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,14 +5,19 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||
| 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | import cn.iocoder.yudao.module.system.controller.admin.mail.vo.log.MailLogPageReqVO; | 6 | import cn.iocoder.yudao.module.system.controller.admin.mail.vo.log.MailLogPageReqVO; |
| 7 | import cn.iocoder.yudao.module.system.controller.admin.mail.vo.log.MailLogRespVO; | 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 | import cn.iocoder.yudao.module.system.convert.mail.MailLogConvert; | 9 | import cn.iocoder.yudao.module.system.convert.mail.MailLogConvert; |
| 10 | +import cn.iocoder.yudao.module.system.convert.mail.MailTemplateConvert; | ||
| 9 | import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailLogDO; | 11 | import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailLogDO; |
| 12 | +import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO; | ||
| 10 | import cn.iocoder.yudao.module.system.service.mail.MailLogService; | 13 | import cn.iocoder.yudao.module.system.service.mail.MailLogService; |
| 11 | import io.swagger.annotations.Api; | 14 | import io.swagger.annotations.Api; |
| 15 | +import io.swagger.annotations.ApiImplicitParam; | ||
| 12 | import io.swagger.annotations.ApiOperation; | 16 | import io.swagger.annotations.ApiOperation; |
| 13 | import org.springframework.security.access.prepost.PreAuthorize; | 17 | import org.springframework.security.access.prepost.PreAuthorize; |
| 14 | import org.springframework.web.bind.annotation.GetMapping; | 18 | import org.springframework.web.bind.annotation.GetMapping; |
| 15 | import org.springframework.web.bind.annotation.RequestMapping; | 19 | import org.springframework.web.bind.annotation.RequestMapping; |
| 20 | +import org.springframework.web.bind.annotation.RequestParam; | ||
| 16 | import org.springframework.web.bind.annotation.RestController; | 21 | import org.springframework.web.bind.annotation.RestController; |
| 17 | 22 | ||
| 18 | import javax.annotation.Resource; | 23 | import javax.annotation.Resource; |
| @@ -37,4 +42,13 @@ public class MailLogController { | @@ -37,4 +42,13 @@ public class MailLogController { | ||
| 37 | return success(MailLogConvert.INSTANCE.convertPage(pageResult)); | 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
| @@ -13,4 +13,6 @@ public interface MailLogConvert { | @@ -13,4 +13,6 @@ public interface MailLogConvert { | ||
| 13 | 13 | ||
| 14 | PageResult<MailLogRespVO> convertPage(PageResult<MailLogDO> pageResult); | 14 | PageResult<MailLogRespVO> convertPage(PageResult<MailLogDO> pageResult); |
| 15 | 15 | ||
| 16 | + MailLogRespVO convert(MailLogDO bean); | ||
| 17 | + | ||
| 16 | } | 18 | } |
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,6 +25,14 @@ public interface MailLogService { | ||
| 25 | PageResult<MailLogDO> getMailLogPage(MailLogPageReqVO pageVO); | 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 | * @param userId 用户编码 | 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,6 +36,11 @@ public class MailLogServiceImpl implements MailLogService { | ||
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | @Override | 38 | @Override |
| 39 | + public MailLogDO getMailLog(Long id) { | ||
| 40 | + return mailLogMapper.selectById(id); | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + @Override | ||
| 39 | public Long createMailLog(Long userId, Integer userType, String toMail, | 44 | public Long createMailLog(Long userId, Integer userType, String toMail, |
| 40 | MailAccountDO account, MailTemplateDO template, | 45 | MailAccountDO account, MailTemplateDO template, |
| 41 | String templateContent, Map<String, Object> templateParams, Boolean isSend) { | 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,6 +90,7 @@ export enum DICT_TYPE { | ||
| 90 | SYSTEM_SMS_RECEIVE_STATUS = 'system_sms_receive_status', | 90 | SYSTEM_SMS_RECEIVE_STATUS = 'system_sms_receive_status', |
| 91 | SYSTEM_ERROR_CODE_TYPE = 'system_error_code_type', | 91 | SYSTEM_ERROR_CODE_TYPE = 'system_error_code_type', |
| 92 | SYSTEM_OAUTH2_GRANT_TYPE = 'system_oauth2_grant_type', | 92 | SYSTEM_OAUTH2_GRANT_TYPE = 'system_oauth2_grant_type', |
| 93 | + SYSTEM_MAIL_SEND_STATUS = 'system_mail_send_status', | ||
| 93 | 94 | ||
| 94 | // ========== INFRA 模块 ========== | 95 | // ========== INFRA 模块 ========== |
| 95 | INFRA_BOOLEAN_STRING = 'infra_boolean_string', | 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) |