From 22f45ff184a6eb0896c93481e4123493e163b0eb Mon Sep 17 00:00:00 2001 From: lynn Date: Tue, 8 Jul 2025 15:03:07 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8F=91=E9=80=81=E8=AE=B0?= =?UTF-8?q?=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/email/index.vue | 551 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 522 insertions(+), 29 deletions(-) diff --git a/src/views/email/index.vue b/src/views/email/index.vue index ab76209..9f4226a 100644 --- a/src/views/email/index.vue +++ b/src/views/email/index.vue @@ -340,30 +340,43 @@

发送记录

- - - - - - +
+ + + + + + + + 刷新记录 + +
- - - - - + + + + + + + + + - + @@ -373,6 +386,19 @@ + + +
+ + +
@@ -426,6 +452,172 @@ + + + +
+ +
+

+ + 基本信息 +

+ + +
+ + {{ detailRecord.subject }} +
+
+ +
+ + {{ detailRecord.templateName }} +
+
+ +
+ + + {{ detailRecord.statusText }} + +
+
+ +
+ + {{ detailRecord.createdTime }} +
+
+ +
+ + {{ detailRecord.sendTime }} +
+
+
+
+ + +
+

+ + 发送统计 +

+ + +
+
+ +
+
+
{{ detailRecord.totalRecipients }}
+
总收件人
+
+
+
+ +
+
+ +
+
+
{{ detailRecord.successCount }}
+
发送成功
+
+
+
+ +
+
+ +
+
+
{{ detailRecord.failCount }}
+
发送失败
+
+
+
+
+
+ + +
+

+ + 邮件内容预览 +

+ +
+ + +
+

+ + 收件人详情 ({{ detailRecord.recipients.length }}人) +

+ + + + + + + + + + + + + +
+
+ + +
+ + + +
+ + + {{ value }} + + +
+
@@ -441,11 +633,18 @@ export default { return { activeTab: 'templates', showTemplateModal: false, + showDetailModal: false, showSendProgress: false, sendProgress: 0, selectAll: false, selectedTemplateId: null, historyFilter: '', + detailRecord: null, + showVarDataModal: false, + currentVarData: null, + refreshing: false, + currentPage: 1, + pageSize: 20, // 表单数据 templateForm: { @@ -490,6 +689,10 @@ export default { if (val === 'history') { this.loadSendHistory() } + }, + historyFilter() { + // 当过滤条件改变时,重置到第一页 + this.currentPage = 1 } }, computed: { @@ -534,7 +737,13 @@ export default { filteredHistory() { if (!this.historyFilter) return this.sendHistory - return this.sendHistory.filter(record => record.status === this.historyFilter) + return this.sendHistory.filter(record => record.status.toString() === this.historyFilter) + }, + + paginatedHistory() { + const start = (this.currentPage - 1) * this.pageSize + const end = start + this.pageSize + return this.filteredHistory.slice(start, end) } }, @@ -881,7 +1090,19 @@ export default { .then(res => { this.$message.success('邮件发送请求已提交!') this.showSendProgress = false - // 可选:刷新历史、重置表单等 + // 自动跳转到发送记录页面 + this.activeTab = 'history' + // 刷新发送记录数据 + this.loadSendHistory() + // 重置发送表单 + this.sendForm = { + subject: '', + sendMode: 'now', + scheduleTime: null, + testSend: false + } + // 清空选择的收件人 + this.selectedRecipients = [] }) .catch(err => { this.$message.error('邮件发送失败') @@ -891,8 +1112,21 @@ export default { // 发送记录相关方法 toggleHistoryDetail(record) { - // 这里可以展开显示详细的发送记录 - console.log('查看记录详情:', record) + // 设置详情数据并显示模态框 + this.detailRecord = { + subject: record.subject, + templateName: record.email_template ? record.email_template.title : '未知模板', + templateContent: record.email_template ? record.email_template.content : '', + totalRecipients: record.email_record_users_count, + successCount: record.success_count, + failCount: record.fail_count, + status: record.status, + statusText: this.getStatusText(record.status), + sendTime: record.send_time || record.created_at, + createdTime: record.created_at, + recipients: record.email_record_users || [] + } + this.showDetailModal = true }, // 工具方法 @@ -947,31 +1181,63 @@ export default { getStatusType(status) { const statusMap = { - pending: 'warning', - sending: 'primary', - sent: 'success', - failed: 'danger' + 0: 'warning', // 待发送 + 1: 'success', // 已发送 + 2: 'danger' // 发送失败 } return statusMap[status] || 'info' }, getStatusText(status) { const statusMap = { - pending: '等待发送', - sending: '发送中', - sent: '发送成功', - failed: '发送失败' + 0: '待发送', + 1: '已发送', + 2: '发送失败' } return statusMap[status] || '未知状态' }, loadSendHistory() { getEmailRecordList().then(res => { + // 根据API返回的数据结构,data字段包含记录数组 this.sendHistory = res.data || [] }).catch(error => { + console.error('获取发送记录失败:', error) this.$message.error('获取发送记录失败') }) - } + }, + + // 刷新发送记录 + refreshSendHistory() { + this.refreshing = true + getEmailRecordList().then(res => { + this.sendHistory = res.data || [] + this.$message.success('发送记录已刷新') + }).catch(error => { + console.error('刷新发送记录失败:', error) + this.$message.error('刷新发送记录失败') + }).finally(() => { + this.refreshing = false + }) + }, + + // 分页相关方法 + handleSizeChange(newSize) { + this.pageSize = newSize + this.currentPage = 1 // 重置到第一页 + }, + + handleCurrentChange(newPage) { + this.currentPage = newPage + }, + + // 显示变量数据 + showVarData(varData) { + this.currentVarData = varData + this.showVarDataModal = true + }, + + } } @@ -1014,6 +1280,22 @@ export default { margin-bottom: 20px; } +.header-actions { + display: flex; + align-items: center; + gap: 12px; +} + +.pagination-container { + display: flex; + justify-content: center; + margin-top: 20px; + padding: 20px 0; + background: white; + border-radius: 8px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); +} + .tab-footer, .tab-navigation { display: flex; justify-content: flex-end; @@ -1367,6 +1649,21 @@ export default { text-align: center; } + .header-actions { + flex-direction: column; + gap: 10px; + width: 100%; + } + + .header-actions .el-select { + width: 100%; + } + + .pagination-container { + margin-top: 15px; + padding: 15px 0; + } + .tab-navigation { flex-direction: column; gap: 10px; @@ -2601,4 +2898,200 @@ export default { margin-bottom: 0; font-size: 14px; } + +/* 发送记录详情模态框样式 */ +:deep(.detail-modal) { + .el-dialog__body { + padding: 0; + } +} + +.detail-content { + padding: 20px; + max-height: 60vh; + overflow-y: auto; +} + +.detail-section { + background: white; + border-radius: 12px; + padding: 24px; + margin-bottom: 20px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + border: 1px solid #e9ecef; +} + +.section-title { + font-size: 18px; + font-weight: 600; + color: #2c3e50; + margin: 0 0 20px 0; + display: flex; + align-items: center; + gap: 8px; + padding-bottom: 12px; + border-bottom: 2px solid #f0f0f0; +} + +.section-title i { + color: #409EFF; + font-size: 20px; +} + +.info-item { + margin-bottom: 16px; + display: flex; + align-items: center; +} + +.info-item label { + font-weight: 600; + color: #606266; + min-width: 100px; + margin-right: 12px; +} + +.info-value { + color: #2c3e50; + font-weight: 500; +} + +/* 统计卡片样式 */ +.stat-card { + display: flex; + align-items: center; + padding: 20px; + background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%); + border-radius: 12px; + border: 1px solid #e9ecef; + transition: all 0.3s ease; +} + +.stat-card:hover { + transform: translateY(-2px); + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1); +} + +.stat-icon { + width: 60px; + height: 60px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + margin-right: 16px; + font-size: 24px; + color: white; +} + +.stat-icon.total { + background: linear-gradient(135deg, #409EFF 0%, #36a3f7 100%); +} + +.stat-icon.success { + background: linear-gradient(135deg, #67C23A 0%, #85ce61 100%); +} + +.stat-icon.fail { + background: linear-gradient(135deg, #F56C6C 0%, #f78989 100%); +} + +.stat-content { + flex: 1; +} + +.stat-number { + font-size: 28px; + font-weight: 700; + color: #2c3e50; + line-height: 1; + margin-bottom: 4px; +} + +.stat-label { + font-size: 14px; + color: #606266; + font-weight: 500; +} + +/* 邮件内容预览样式 */ +.email-content-preview { + background: #f8f9fa; + border: 1px solid #e9ecef; + border-radius: 8px; + overflow: hidden; +} + +.preview-header { + background: #e9ecef; + padding: 12px 16px; + border-bottom: 1px solid #dee2e6; + font-weight: 500; + color: #495057; +} + +.preview-body { + padding: 16px; + max-height: 200px; + overflow-y: auto; + line-height: 1.6; + color: #2c3e50; +} + +.preview-body :deep(p) { + margin: 8px 0; +} + +.preview-body :deep(strong) { + font-weight: 600; +} + +/* 收件人表格样式 */ +.fail-reason { + color: #F56C6C; + font-size: 12px; + background: #fef0f0; + padding: 2px 6px; + border-radius: 4px; +} + +/* 变量数据弹窗样式 */ +.var-data-content { + padding: 20px 0; +} + +:deep(.el-descriptions__label) { + font-weight: 600; + color: #606266; +} + +:deep(.el-descriptions__content) { + color: #2c3e50; +} + +/* 响应式设计 */ +@media (max-width: 768px) { + .detail-content { + padding: 16px; + } + + .detail-section { + padding: 16px; + } + + .stat-card { + padding: 16px; + margin-bottom: 16px; + } + + .stat-icon { + width: 50px; + height: 50px; + font-size: 20px; + } + + .stat-number { + font-size: 24px; + } +} \ No newline at end of file