Commit 28ba9a7456d013a7eb6f41a7104af7250d4736f0
1 parent
86a884e3
邮箱模块:vue3 邮件日志的管理
Showing
8 changed files
with
287 additions
and
0 deletions
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/MailLogController.java
| ... | ... | @@ -5,14 +5,19 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 5 | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | 6 | import cn.iocoder.yudao.module.system.controller.admin.mail.vo.log.MailLogPageReqVO; |
| 7 | 7 | import cn.iocoder.yudao.module.system.controller.admin.mail.vo.log.MailLogRespVO; |
| 8 | +import cn.iocoder.yudao.module.system.controller.admin.mail.vo.template.MailTemplateRespVO; | |
| 8 | 9 | import cn.iocoder.yudao.module.system.convert.mail.MailLogConvert; |
| 10 | +import cn.iocoder.yudao.module.system.convert.mail.MailTemplateConvert; | |
| 9 | 11 | import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailLogDO; |
| 12 | +import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO; | |
| 10 | 13 | import cn.iocoder.yudao.module.system.service.mail.MailLogService; |
| 11 | 14 | import io.swagger.annotations.Api; |
| 15 | +import io.swagger.annotations.ApiImplicitParam; | |
| 12 | 16 | import io.swagger.annotations.ApiOperation; |
| 13 | 17 | import org.springframework.security.access.prepost.PreAuthorize; |
| 14 | 18 | import org.springframework.web.bind.annotation.GetMapping; |
| 15 | 19 | import org.springframework.web.bind.annotation.RequestMapping; |
| 20 | +import org.springframework.web.bind.annotation.RequestParam; | |
| 16 | 21 | import org.springframework.web.bind.annotation.RestController; |
| 17 | 22 | |
| 18 | 23 | import javax.annotation.Resource; |
| ... | ... | @@ -37,4 +42,13 @@ public class MailLogController { |
| 37 | 42 | return success(MailLogConvert.INSTANCE.convertPage(pageResult)); |
| 38 | 43 | } |
| 39 | 44 | |
| 45 | + @GetMapping("/get") | |
| 46 | + @ApiOperation("获得邮箱日志") | |
| 47 | + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) | |
| 48 | + @PreAuthorize("@ss.hasPermission('system:mail-log:query')") | |
| 49 | + public CommonResult<MailLogRespVO> getMailTemplate(@RequestParam("id") Long id) { | |
| 50 | + MailLogDO mailLogDO = mailLogService.getMailLog(id); | |
| 51 | + return success(MailLogConvert.INSTANCE.convert(mailLogDO)); | |
| 52 | + } | |
| 53 | + | |
| 40 | 54 | } | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/mail/MailLogConvert.java
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailLogService.java
| ... | ... | @@ -25,6 +25,14 @@ public interface MailLogService { |
| 25 | 25 | PageResult<MailLogDO> getMailLogPage(MailLogPageReqVO pageVO); |
| 26 | 26 | |
| 27 | 27 | /** |
| 28 | + * 获得指定编号的邮件日志 | |
| 29 | + * | |
| 30 | + * @param id 日志编号 | |
| 31 | + * @return 邮件日志 | |
| 32 | + */ | |
| 33 | + MailLogDO getMailLog(Long id); | |
| 34 | + | |
| 35 | + /** | |
| 28 | 36 | * 创建邮件日志 |
| 29 | 37 | * |
| 30 | 38 | * @param userId 用户编码 | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailLogServiceImpl.java
| ... | ... | @@ -36,6 +36,11 @@ public class MailLogServiceImpl implements MailLogService { |
| 36 | 36 | } |
| 37 | 37 | |
| 38 | 38 | @Override |
| 39 | + public MailLogDO getMailLog(Long id) { | |
| 40 | + return mailLogMapper.selectById(id); | |
| 41 | + } | |
| 42 | + | |
| 43 | + @Override | |
| 39 | 44 | public Long createMailLog(Long userId, Integer userType, String toMail, |
| 40 | 45 | MailAccountDO account, MailTemplateDO template, |
| 41 | 46 | String templateContent, Map<String, Object> templateParams, Boolean isSend) { | ... | ... |
yudao-ui-admin-vue3/src/api/system/mail/log/index.ts
0 → 100644
| 1 | +import request from '@/config/axios' | |
| 2 | + | |
| 3 | +export interface MailLogVO { | |
| 4 | + id: number | |
| 5 | + userId: number | |
| 6 | + userType: number | |
| 7 | + toMail: string | |
| 8 | + accountId: number | |
| 9 | + fromMail: string | |
| 10 | + templateId: number | |
| 11 | + templateCode: string | |
| 12 | + templateNickname: string | |
| 13 | + templateTitle: string | |
| 14 | + templateContent: string | |
| 15 | + templateParams: string | |
| 16 | + sendStatus: number | |
| 17 | + sendTime: Date | |
| 18 | + sendMessageId: string | |
| 19 | + sendException: string | |
| 20 | +} | |
| 21 | + | |
| 22 | +export interface MailLogPageReqVO extends PageParam { | |
| 23 | + userId?: number | |
| 24 | + userType?: number | |
| 25 | + toMail?: string | |
| 26 | + accountId?: number | |
| 27 | + templateId?: number | |
| 28 | + sendStatus?: number | |
| 29 | + sendTime?: Date[] | |
| 30 | +} | |
| 31 | + | |
| 32 | +// 查询邮件日志列表 | |
| 33 | +export const getMailLogPageApi = async (params: MailLogPageReqVO) => { | |
| 34 | + return await request.get({ url: '/system/mail-log/page', params }) | |
| 35 | +} | |
| 36 | + | |
| 37 | +// 查询邮件日志详情 | |
| 38 | +export const getMailLogApi = async (id: number) => { | |
| 39 | + return await request.get({ url: '/system/mail-log/get?id=' + id }) | |
| 40 | +} | ... | ... |
yudao-ui-admin-vue3/src/utils/dict.ts
| ... | ... | @@ -90,6 +90,7 @@ export enum DICT_TYPE { |
| 90 | 90 | SYSTEM_SMS_RECEIVE_STATUS = 'system_sms_receive_status', |
| 91 | 91 | SYSTEM_ERROR_CODE_TYPE = 'system_error_code_type', |
| 92 | 92 | SYSTEM_OAUTH2_GRANT_TYPE = 'system_oauth2_grant_type', |
| 93 | + SYSTEM_MAIL_SEND_STATUS = 'system_mail_send_status', | |
| 93 | 94 | |
| 94 | 95 | // ========== INFRA 模块 ========== |
| 95 | 96 | INFRA_BOOLEAN_STRING = 'infra_boolean_string', | ... | ... |
yudao-ui-admin-vue3/src/views/system/mail/log/index.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <ContentWrap> | |
| 3 | + <!-- 列表 --> | |
| 4 | + <XTable @register="registerTable"> | |
| 5 | + <template #accountId_search> | |
| 6 | + <el-select v-model="queryParams.accountId"> | |
| 7 | + <el-option :key="undefined" label="全部" :value="undefined" /> | |
| 8 | + <el-option | |
| 9 | + v-for="item in accountOptions" | |
| 10 | + :key="item.id" | |
| 11 | + :label="item.mail" | |
| 12 | + :value="item.id" | |
| 13 | + /> | |
| 14 | + </el-select> | |
| 15 | + </template> | |
| 16 | + <template #toMail_default="{ row }"> | |
| 17 | + <div>{{ row.toMail }}</div> | |
| 18 | + <div v-if="row.userType && row.userId"> | |
| 19 | + <dict-tag :type="DICT_TYPE.USER_TYPE" :value="row.userType" />{{ '(' + row.userId + ')' }} | |
| 20 | + </div> | |
| 21 | + </template> | |
| 22 | + <template #actionbtns_default="{ row }"> | |
| 23 | + <!-- 操作:详情 --> | |
| 24 | + <XTextButton | |
| 25 | + preIcon="ep:view" | |
| 26 | + :title="t('action.detail')" | |
| 27 | + v-hasPermi="['system:mail-log:query']" | |
| 28 | + @click="handleDetail(row.id)" | |
| 29 | + /> | |
| 30 | + </template> | |
| 31 | + </XTable> | |
| 32 | + </ContentWrap> | |
| 33 | + <!-- 弹窗 --> | |
| 34 | + <XModal id="mailLogModel" :loading="modelLoading" v-model="modelVisible" :title="modelTitle"> | |
| 35 | + <!-- 表单:详情 --> | |
| 36 | + <Descriptions | |
| 37 | + v-if="actionType === 'detail'" | |
| 38 | + :schema="allSchemas.detailSchema" | |
| 39 | + :data="detailData" | |
| 40 | + /> | |
| 41 | + <template #footer> | |
| 42 | + <!-- 按钮:关闭 --> | |
| 43 | + <XButton :loading="actionLoading" :title="t('dialog.close')" @click="modelVisible = false" /> | |
| 44 | + </template> | |
| 45 | + </XModal> | |
| 46 | +</template> | |
| 47 | +<script setup lang="ts" name="MailLog"> | |
| 48 | +// 业务相关的 import | |
| 49 | +import { allSchemas } from './log.data' | |
| 50 | +import * as MailLogApi from '@/api/system/mail/log' | |
| 51 | +import * as MailAccountApi from '@/api/system/mail/account' | |
| 52 | + | |
| 53 | +const { t } = useI18n() // 国际化 | |
| 54 | + | |
| 55 | +// 列表相关的变量 | |
| 56 | +const queryParams = reactive({ | |
| 57 | + accountId: null | |
| 58 | +}) | |
| 59 | +const [registerTable] = useXTable({ | |
| 60 | + allSchemas: allSchemas, | |
| 61 | + params: queryParams, | |
| 62 | + getListApi: MailLogApi.getMailLogPageApi | |
| 63 | +}) | |
| 64 | +const accountOptions = ref([]) // 账号下拉选项 | |
| 65 | + | |
| 66 | +// 弹窗相关的变量 | |
| 67 | +const modelVisible = ref(false) // 是否显示弹出层 | |
| 68 | +const modelTitle = ref('edit') // 弹出层标题 | |
| 69 | +const modelLoading = ref(false) // 弹出层loading | |
| 70 | +const actionType = ref('') // 操作按钮的类型 | |
| 71 | +const actionLoading = ref(false) // 按钮 Loading | |
| 72 | +const detailData = ref() // 详情 Ref | |
| 73 | + | |
| 74 | +// 设置标题 | |
| 75 | +const setDialogTile = (type: string) => { | |
| 76 | + modelLoading.value = true | |
| 77 | + modelTitle.value = t('action.' + type) | |
| 78 | + actionType.value = type | |
| 79 | + modelVisible.value = true | |
| 80 | +} | |
| 81 | + | |
| 82 | +// 详情操作 | |
| 83 | +const handleDetail = async (rowId: number) => { | |
| 84 | + setDialogTile('detail') | |
| 85 | + const res = await MailLogApi.getMailLogApi(rowId) | |
| 86 | + detailData.value = res | |
| 87 | + modelLoading.value = false | |
| 88 | +} | |
| 89 | + | |
| 90 | +// ========== 初始化 ========== | |
| 91 | +onMounted(() => { | |
| 92 | + MailAccountApi.getSimpleMailAccounts().then((data) => { | |
| 93 | + accountOptions.value = data | |
| 94 | + }) | |
| 95 | +}) | |
| 96 | +</script> | ... | ... |
yudao-ui-admin-vue3/src/views/system/mail/log/log.data.ts
0 → 100644
| 1 | +import type { VxeCrudSchema } from '@/hooks/web/useVxeCrudSchemas' | |
| 2 | + | |
| 3 | +// CrudSchema | |
| 4 | +const crudSchemas = reactive<VxeCrudSchema>({ | |
| 5 | + primaryKey: 'id', | |
| 6 | + primaryTitle: '编号', | |
| 7 | + primaryType: 'id', | |
| 8 | + action: true, | |
| 9 | + actionWidth: '70', | |
| 10 | + columns: [ | |
| 11 | + { | |
| 12 | + title: '发送时间', | |
| 13 | + field: 'sendTime', | |
| 14 | + table: { | |
| 15 | + width: 180 | |
| 16 | + }, | |
| 17 | + formatter: 'formatDate', | |
| 18 | + search: { | |
| 19 | + show: true, | |
| 20 | + itemRender: { | |
| 21 | + name: 'XDataTimePicker' | |
| 22 | + } | |
| 23 | + } | |
| 24 | + }, | |
| 25 | + { | |
| 26 | + title: '接收邮箱', | |
| 27 | + field: 'toMail', | |
| 28 | + isSearch: true, | |
| 29 | + table: { | |
| 30 | + width: 180, | |
| 31 | + slots: { | |
| 32 | + default: 'toMail_default' | |
| 33 | + } | |
| 34 | + } | |
| 35 | + }, | |
| 36 | + { | |
| 37 | + title: '用户编号', | |
| 38 | + field: 'userId', | |
| 39 | + isSearch: true, | |
| 40 | + isTable: false | |
| 41 | + }, | |
| 42 | + { | |
| 43 | + title: '用户类型', | |
| 44 | + field: 'userType', | |
| 45 | + dictType: DICT_TYPE.USER_TYPE, | |
| 46 | + dictClass: 'number', | |
| 47 | + isSearch: true, | |
| 48 | + isTable: false | |
| 49 | + }, | |
| 50 | + { | |
| 51 | + title: '邮件标题', | |
| 52 | + field: 'templateTitle' | |
| 53 | + }, | |
| 54 | + { | |
| 55 | + title: '邮件内容', | |
| 56 | + field: 'templateContent', | |
| 57 | + isTable: false | |
| 58 | + }, | |
| 59 | + { | |
| 60 | + title: '邮箱参数', | |
| 61 | + field: 'templateParams', | |
| 62 | + isTable: false | |
| 63 | + }, | |
| 64 | + { | |
| 65 | + title: '发送状态', | |
| 66 | + field: 'sendStatus', | |
| 67 | + dictType: DICT_TYPE.SYSTEM_MAIL_SEND_STATUS, | |
| 68 | + dictClass: 'string', | |
| 69 | + isSearch: true | |
| 70 | + }, | |
| 71 | + { | |
| 72 | + title: '邮箱账号', | |
| 73 | + field: 'accountId', | |
| 74 | + isSearch: true, | |
| 75 | + isTable: false, | |
| 76 | + search: { | |
| 77 | + slots: { | |
| 78 | + default: 'accountId_search' | |
| 79 | + } | |
| 80 | + } | |
| 81 | + }, | |
| 82 | + { | |
| 83 | + title: '发送邮箱地址', | |
| 84 | + field: 'fromMail', | |
| 85 | + table: { | |
| 86 | + title: '邮箱账号' | |
| 87 | + } | |
| 88 | + }, | |
| 89 | + { | |
| 90 | + title: '模板编号', | |
| 91 | + field: 'templateId', | |
| 92 | + isSearch: true | |
| 93 | + }, | |
| 94 | + { | |
| 95 | + title: '模板编码', | |
| 96 | + field: 'templateCode', | |
| 97 | + isTable: false | |
| 98 | + }, | |
| 99 | + { | |
| 100 | + title: '模版发送人名称', | |
| 101 | + field: 'templateNickname', | |
| 102 | + isTable: false | |
| 103 | + }, | |
| 104 | + { | |
| 105 | + title: '发送返回的消息编号', | |
| 106 | + field: 'sendMessageId', | |
| 107 | + isTable: false | |
| 108 | + }, | |
| 109 | + { | |
| 110 | + title: '发送异常', | |
| 111 | + field: 'sendException', | |
| 112 | + isTable: false | |
| 113 | + }, | |
| 114 | + { | |
| 115 | + title: '创建时间', | |
| 116 | + field: 'createTime', | |
| 117 | + isTable: false | |
| 118 | + } | |
| 119 | + ] | |
| 120 | +}) | |
| 121 | +export const { allSchemas } = useVxeCrudSchemas(crudSchemas) | ... | ... |