From b55cfd9bab062b3f14ce39335e013d448a24b974 Mon Sep 17 00:00:00 2001 From: lynn Date: Mon, 7 Jul 2025 18:33:59 +0800 Subject: [PATCH 1/3] finish email api --- src/api/email/index.js | 58 ++++ src/views/email/index.vue | 543 +++++++++++++++++++--------------- src/views/library/index.vue | 563 ++++++++++++++++++++++++++++-------- 3 files changed, 804 insertions(+), 360 deletions(-) create mode 100644 src/api/email/index.js diff --git a/src/api/email/index.js b/src/api/email/index.js new file mode 100644 index 0000000..4aeea94 --- /dev/null +++ b/src/api/email/index.js @@ -0,0 +1,58 @@ +import request from '@/utils/request' +import { getToken } from '@/utils/auth' + +// 获取邮件模板列表 +export function getEmailTemplateList(params) { + return request({ + url: '/api/admin/email-template/index', + method: 'get', + params + }) +} + +// 保存邮件模版(新增/编辑) +export function saveEmailTemplate(data) { + return request({ + url: '/api/admin/email-template/save', + method: 'post', + data + }) +} + +// 删除邮件模版 +export function deleteEmailTemplate(id) { + return request({ + url: '/api/admin/email-template/destroy', + method: 'get', + params: { + id, + token: getToken() + } + }) +} + +export function uploadEmailRecord(data) { + return request({ + url: '/api/admin/email-record/excel-show', + method: 'post', + data + }) +} + +// 保存邮件记录 +export function saveEmailRecord(data) { + return request({ + url: '/api/admin/email-record/save', + method: 'post', + data + }) +} + +// 获取邮件记录列表 +export function getEmailRecordList(params) { + return request({ + url: '/api/admin/email-record/index', + method: 'get', + params + }) +} \ No newline at end of file diff --git a/src/views/email/index.vue b/src/views/email/index.vue index 7d2916e..ab76209 100644 --- a/src/views/email/index.vue +++ b/src/views/email/index.vue @@ -51,9 +51,9 @@
{{ template.name }}
- {{ template.createTime }} + {{ template.createTime || template.updatedTime }} 使用{{ template.useCount }}次 - {{ template.variables.length }}个变量 + {{ template.variables ? template.variables.length : 0 }}个变量
@@ -82,7 +82,7 @@
可用变量: - {{ '{' + '{' + variable + '}' + '}' }} + {{ '{' + variable + '}' }}
@@ -130,18 +130,28 @@
-
- 全选用户 +
收件人列表
+
+ +
暂无收件人数据
+
请先上传Excel文件
+ style="width: 100%" + :max-height="400"> - - - - + +
@@ -179,14 +189,18 @@
- - - - - + + + @@ -227,11 +241,15 @@
收件人预览(前3条)
- - - - - + + +
还有 {{ selectedRecipients.length - 3 }} 位收件人未显示 @@ -243,7 +261,7 @@ @@ -274,9 +292,17 @@
邮件内容预览
@@ -351,9 +377,9 @@
- + @@ -372,20 +398,18 @@ v-for="variable in availableVariables" :key="variable" class="variable-tag clickable" - @click="insertVariable(`{{${variable}}}`)"> - {{ '{' + '{' + variable + '}' + '}' }} + @click="insertVariable(`{${variable}}`)"> + {{ '{' + variable + '}' }}
- - + :height="300" + :toolbar="'undo redo | bold italic underline strikethrough | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist | outdent indent | removeformat | fullscreen'" + :plugins="'lists fullscreen textcolor colorpicker'" + />
@@ -397,7 +421,7 @@ @@ -406,6 +430,11 @@ @@ -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 From c9c60f03bd2d5416658051e85162b1a3a3b8210e Mon Sep 17 00:00:00 2001 From: lynn Date: Tue, 8 Jul 2025 17:09:31 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E9=82=AE=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/email/index.js | 10 ++++++ src/views/email/index.vue | 69 ++++++++++++++++++++++++++++++++++----- 2 files changed, 70 insertions(+), 9 deletions(-) diff --git a/src/api/email/index.js b/src/api/email/index.js index 4aeea94..76c63c8 100644 --- a/src/api/email/index.js +++ b/src/api/email/index.js @@ -55,4 +55,14 @@ export function getEmailRecordList(params) { method: 'get', params }) +} + + +// 发送邮件 +export function sendEmail(data) { + return request({ + url: '/api/admin/email-record/send-example', + method: 'post', + data + }) } \ No newline at end of file diff --git a/src/views/email/index.vue b/src/views/email/index.vue index 9f4226a..b49a19a 100644 --- a/src/views/email/index.vue +++ b/src/views/email/index.vue @@ -281,10 +281,19 @@ - - - 先发送测试邮件到我的邮箱 - + + + + + + + + + 发送测试邮件 + @@ -623,9 +632,8 @@