diff --git a/src/api/email/index.js b/src/api/email/index.js new file mode 100644 index 0000000..76c63c8 --- /dev/null +++ b/src/api/email/index.js @@ -0,0 +1,68 @@ +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 + }) +} + + +// 发送邮件 +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 7d2916e..b49a19a 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 @@ @@ -263,10 +281,19 @@ - - - 先发送测试邮件到我的邮箱 - + + + + + + + + + 发送测试邮件 + @@ -274,9 +301,17 @@
邮件内容预览
@@ -314,30 +349,43 @@

发送记录

- - - - - - +
+ + + + + + + + 刷新记录 + +
- - - - - + + + + + + + + + - + @@ -347,13 +395,26 @@ + + +
+ + +
- + @@ -372,20 +433,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,29 +456,208 @@ + + + +
+ +
+

+ + 基本信息 +

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

+ + 发送统计 +

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

+ + 邮件内容预览 +

+ +
+ + +
+

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

+ + + + + + + + + + + + + +
+
+ + +
+ + + +
+ + + {{ value }} + + +
+
@@ -960,6 +1329,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; @@ -1096,6 +1481,14 @@ export default { margin-bottom: 20px; } +.recipient-table .el-table { + overflow-x: auto; +} + +.recipient-table .el-table__body-wrapper { + overflow-x: auto; +} + .table-header { background: #409EFF; color: white; @@ -1153,6 +1546,14 @@ export default { margin-top: 15px; } +.selected-preview .el-table { + overflow-x: auto; +} + +.selected-preview .el-table__body-wrapper { + overflow-x: auto; +} + .empty-selection { text-align: center; color: #6c757d; @@ -1178,6 +1579,14 @@ export default { box-shadow: 0 2px 8px rgba(0,0,0,0.1); } +.preview-table .el-table { + overflow-x: auto; +} + +.preview-table .el-table__body-wrapper { + overflow-x: auto; +} + .more-info { text-align: center; color: #6c757d; @@ -1245,6 +1654,7 @@ export default { max-height: 400px; overflow-y: auto; line-height: 1.6; + white-space: pre-wrap; } .variable-tags { @@ -1268,6 +1678,8 @@ export default { color: #66b1ff; } + + /* 响应式设计 */ @media (max-width: 768px) { .email-container { @@ -1288,6 +1700,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; @@ -2522,4 +2949,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 diff --git a/src/views/library/index.vue b/src/views/library/index.vue index 013cee5..db243e6 100644 --- a/src/views/library/index.vue +++ b/src/views/library/index.vue @@ -14,19 +14,19 @@
-
1,247
+
{{ chartData.total || 0 }}
总图书数量
-
856
+
{{ chartData.borrowable || 0 }}
可借阅
-
391
+
{{ chartData.borrowed || 0 }}
已借出
-
23
+
{{ chartData.maintaining || 0 }}
维护中
@@ -35,21 +35,42 @@
- + - - - - - + + + - - - - + + + + + @@ -74,42 +95,74 @@ - + @@ -130,9 +183,9 @@ >
- + - + @@ -217,73 +270,147 @@ + + + + +
+ +
+
+ + 基本信息 +
+ + +
+ + {{ currentBook.title || '未设置' }} +
+
+ +
+ + {{ currentBook.author || '未知' }} +
+
+
+ + +
+ + {{ currentBook.isbn || '未设置' }} +
+
+ +
+ + {{ currentBook.publisher || '未设置' }} +
+
+
+ + +
+ + {{ currentBook.publish_year || '未设置' }} +
+
+ +
+ + {{ currentBook.category || '未分类' }} +
+
+
+ + +
+ + {{ getStatusText(currentBook.status) }} +
+
+
+
+ +
{{ currentBook.description || '暂无简介' }}
+
+
+ + +
+
+ + 图书封面 +
+
+ 图书封面 +
+ +
暂无封面
+
+
+
+ + +
+
+ + 其他信息 +
+ + +
+ + {{ formatDateTime(currentBook.created_at) }} +
+
+ +
+ + {{ formatDateTime(currentBook.updated_at) }} +
+
+
+
+ + {{ currentBook.id }} +
+
+
+