Commit 4cbf7398e850deb88e8aa40cf90c8e5c3906ad9f
1 parent
2c55d294
邮箱模块:vue3 邮箱账号的管理
Showing
5 changed files
with
259 additions
and
1 deletions
README.md
| @@ -91,6 +91,7 @@ | @@ -91,6 +91,7 @@ | ||
| 91 | | 🚀 | 租户套餐 | 配置租户套餐,自定每个租户的菜单、操作、按钮的权限 | | 91 | | 🚀 | 租户套餐 | 配置租户套餐,自定每个租户的菜单、操作、按钮的权限 | |
| 92 | | | 字典管理 | 对系统中经常使用的一些较为固定的数据进行维护 | | 92 | | | 字典管理 | 对系统中经常使用的一些较为固定的数据进行维护 | |
| 93 | | 🚀 | 短信管理 | 短信渠道、短息模板、短信日志,对接阿里云、腾讯云等主流短信平台 | | 93 | | 🚀 | 短信管理 | 短信渠道、短息模板、短信日志,对接阿里云、腾讯云等主流短信平台 | |
| 94 | +| 🚀 | 邮件管理 | 邮箱账号、邮件模版、邮件发送日志,支持所有邮件平台 | | ||
| 94 | | 🚀 | 操作日志 | 系统正常操作日志记录和查询,集成 Swagger 生成日志内容 | | 95 | | 🚀 | 操作日志 | 系统正常操作日志记录和查询,集成 Swagger 生成日志内容 | |
| 95 | | ⭐️ | 登录日志 | 系统登录日志记录查询,包含登录异常 | | 96 | | ⭐️ | 登录日志 | 系统登录日志记录查询,包含登录异常 | |
| 96 | | 🚀 | 错误码管理 | 系统所有错误码的管理,可在线修改错误提示,无需重启服务 | | 97 | | 🚀 | 错误码管理 | 系统所有错误码的管理,可在线修改错误提示,无需重启服务 | |
yudao-ui-admin-vue3/src/api/system/mail/account/index.ts
0 → 100644
| 1 | +import request from '@/config/axios' | ||
| 2 | + | ||
| 3 | +export interface MailAccountVO { | ||
| 4 | + id: number | ||
| 5 | + mail: string | ||
| 6 | + username: string | ||
| 7 | + password: string | ||
| 8 | + host: string | ||
| 9 | + port: number | ||
| 10 | + sslEnable: boolean | ||
| 11 | +} | ||
| 12 | + | ||
| 13 | +export interface MailAccountPageReqVO extends PageParam { | ||
| 14 | + mail?: string | ||
| 15 | + username?: string | ||
| 16 | +} | ||
| 17 | + | ||
| 18 | +// 查询邮箱账号列表 | ||
| 19 | +export const getMailAccountPageApi = async (params: MailAccountPageReqVO) => { | ||
| 20 | + return await request.get({ url: '/system/mail-account/page', params }) | ||
| 21 | +} | ||
| 22 | + | ||
| 23 | +// 查询邮箱账号详情 | ||
| 24 | +export const getMailAccountApi = async (id: number) => { | ||
| 25 | + return await request.get({ url: '/system/mail-account/get?id=' + id }) | ||
| 26 | +} | ||
| 27 | + | ||
| 28 | +// 新增邮箱账号 | ||
| 29 | +export const createMailAccountApi = async (data: MailAccountVO) => { | ||
| 30 | + return await request.post({ url: '/system/mail-account/create', data }) | ||
| 31 | +} | ||
| 32 | + | ||
| 33 | +// 修改邮箱账号 | ||
| 34 | +export const updateMailAccountApi = async (data: MailAccountVO) => { | ||
| 35 | + return await request.put({ url: '/system/mail-account/update', data }) | ||
| 36 | +} | ||
| 37 | + | ||
| 38 | +// 删除邮箱账号 | ||
| 39 | +export const deleteMailAccountApi = async (id: number) => { | ||
| 40 | + return await request.delete({ url: '/system/mail-account/delete?id=' + id }) | ||
| 41 | +} |
yudao-ui-admin-vue3/src/views/system/mail/account/account.template.data.ts
0 → 100644
| 1 | +import type { VxeCrudSchema } from '@/hooks/web/useVxeCrudSchemas' | ||
| 2 | + | ||
| 3 | +// 表单校验 | ||
| 4 | +export const rules = reactive({ | ||
| 5 | + mail: [required], | ||
| 6 | + username: [required], | ||
| 7 | + password: [required], | ||
| 8 | + host: [required], | ||
| 9 | + port: [required], | ||
| 10 | + sslEnable: [required] | ||
| 11 | +}) | ||
| 12 | + | ||
| 13 | +// CrudSchema | ||
| 14 | +const crudSchemas = reactive<VxeCrudSchema>({ | ||
| 15 | + primaryKey: 'id', // 默认的主键 ID | ||
| 16 | + primaryTitle: '编号', | ||
| 17 | + primaryType: 'id', | ||
| 18 | + action: true, | ||
| 19 | + actionWidth: '200', // 3 个按钮默认 200,如有删减对应增减即可 | ||
| 20 | + columns: [ | ||
| 21 | + { | ||
| 22 | + title: '邮箱', | ||
| 23 | + field: 'mail', | ||
| 24 | + isSearch: true | ||
| 25 | + }, | ||
| 26 | + { | ||
| 27 | + title: '用户名', | ||
| 28 | + field: 'username', | ||
| 29 | + isSearch: true | ||
| 30 | + }, | ||
| 31 | + { | ||
| 32 | + title: '密码', | ||
| 33 | + field: 'password', | ||
| 34 | + isTable: false | ||
| 35 | + }, | ||
| 36 | + { | ||
| 37 | + title: 'SMTP 服务器域名', | ||
| 38 | + field: 'host' | ||
| 39 | + }, | ||
| 40 | + { | ||
| 41 | + title: 'SMTP 服务器端口', | ||
| 42 | + field: 'port', | ||
| 43 | + form: { | ||
| 44 | + component: 'InputNumber', | ||
| 45 | + value: 465 | ||
| 46 | + } | ||
| 47 | + }, | ||
| 48 | + { | ||
| 49 | + title: '是否开启 SSL', | ||
| 50 | + field: 'sslEnable', | ||
| 51 | + dictType: DICT_TYPE.INFRA_BOOLEAN_STRING, | ||
| 52 | + dictClass: 'boolean' | ||
| 53 | + }, | ||
| 54 | + { | ||
| 55 | + title: '创建时间', | ||
| 56 | + field: 'createTime', | ||
| 57 | + isForm: false, | ||
| 58 | + formatter: 'formatDate', | ||
| 59 | + table: { | ||
| 60 | + width: 180 | ||
| 61 | + } | ||
| 62 | + } | ||
| 63 | + ] | ||
| 64 | +}) | ||
| 65 | +export const { allSchemas } = useVxeCrudSchemas(crudSchemas) |
yudao-ui-admin-vue3/src/views/system/mail/account/index.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <ContentWrap> | ||
| 3 | + <!-- 列表 --> | ||
| 4 | + <XTable @register="registerTable"> | ||
| 5 | + <template #toolbar_buttons> | ||
| 6 | + <!-- 操作:新增 --> | ||
| 7 | + <XButton | ||
| 8 | + type="primary" | ||
| 9 | + preIcon="ep:zoom-in" | ||
| 10 | + :title="t('action.add')" | ||
| 11 | + v-hasPermi="['system:mail-account:create']" | ||
| 12 | + @click="handleCreate()" | ||
| 13 | + /> | ||
| 14 | + </template> | ||
| 15 | + <template #actionbtns_default="{ row }"> | ||
| 16 | + <!-- 操作:修改 --> | ||
| 17 | + <XTextButton | ||
| 18 | + preIcon="ep:edit" | ||
| 19 | + :title="t('action.edit')" | ||
| 20 | + v-hasPermi="['system:mail-account:update']" | ||
| 21 | + @click="handleUpdate(row.id)" | ||
| 22 | + /> | ||
| 23 | + <!-- 操作:详情 --> | ||
| 24 | + <XTextButton | ||
| 25 | + preIcon="ep:view" | ||
| 26 | + :title="t('action.detail')" | ||
| 27 | + v-hasPermi="['system:mail-account:query']" | ||
| 28 | + @click="handleDetail(row.id)" | ||
| 29 | + /> | ||
| 30 | + <!-- 操作:删除 --> | ||
| 31 | + <XTextButton | ||
| 32 | + preIcon="ep:delete" | ||
| 33 | + :title="t('action.del')" | ||
| 34 | + v-hasPermi="['system:mail-account:delete']" | ||
| 35 | + @click="deleteData(row.id)" | ||
| 36 | + /> | ||
| 37 | + </template> | ||
| 38 | + </XTable> | ||
| 39 | + </ContentWrap> | ||
| 40 | + <!-- 弹窗 --> | ||
| 41 | + <XModal id="mailAccountModel" :loading="modelLoading" v-model="modelVisible" :title="modelTitle"> | ||
| 42 | + <!-- 表单:添加/修改 --> | ||
| 43 | + <Form | ||
| 44 | + ref="formRef" | ||
| 45 | + v-if="['create', 'update'].includes(actionType)" | ||
| 46 | + :schema="allSchemas.formSchema" | ||
| 47 | + :rules="rules" | ||
| 48 | + /> | ||
| 49 | + <!-- 表单:详情 --> | ||
| 50 | + <Descriptions | ||
| 51 | + v-if="actionType === 'detail'" | ||
| 52 | + :schema="allSchemas.detailSchema" | ||
| 53 | + :data="detailData" | ||
| 54 | + /> | ||
| 55 | + <template #footer> | ||
| 56 | + <!-- 按钮:保存 --> | ||
| 57 | + <XButton | ||
| 58 | + v-if="['create', 'update'].includes(actionType)" | ||
| 59 | + type="primary" | ||
| 60 | + :title="t('action.save')" | ||
| 61 | + :loading="actionLoading" | ||
| 62 | + @click="submitForm()" | ||
| 63 | + /> | ||
| 64 | + <!-- 按钮:关闭 --> | ||
| 65 | + <XButton :loading="actionLoading" :title="t('dialog.close')" @click="modelVisible = false" /> | ||
| 66 | + </template> | ||
| 67 | + </XModal> | ||
| 68 | +</template> | ||
| 69 | +<script setup lang="ts" name="MailAccount"> | ||
| 70 | +import { FormExpose } from '@/components/Form' | ||
| 71 | +// 业务相关的 import | ||
| 72 | +import { rules, allSchemas } from './account.template.data' | ||
| 73 | +import * as MailAccountApi from '@/api/system/mail/account' | ||
| 74 | + | ||
| 75 | +const { t } = useI18n() // 国际化 | ||
| 76 | +const message = useMessage() // 消息弹窗 | ||
| 77 | + | ||
| 78 | +// 列表相关的变量 | ||
| 79 | +const [registerTable, { reload, deleteData }] = useXTable({ | ||
| 80 | + allSchemas: allSchemas, | ||
| 81 | + getListApi: MailAccountApi.getMailAccountPageApi, | ||
| 82 | + deleteApi: MailAccountApi.deleteMailAccountApi | ||
| 83 | +}) | ||
| 84 | + | ||
| 85 | +// 弹窗相关的变量 | ||
| 86 | +const modelVisible = ref(false) // 是否显示弹出层 | ||
| 87 | +const modelTitle = ref('edit') // 弹出层标题 | ||
| 88 | +const modelLoading = ref(false) // 弹出层loading | ||
| 89 | +const actionType = ref('') // 操作按钮的类型 | ||
| 90 | +const actionLoading = ref(false) // 按钮 Loading | ||
| 91 | +const formRef = ref<FormExpose>() // 表单 Ref | ||
| 92 | +const detailData = ref() // 详情 Ref | ||
| 93 | + | ||
| 94 | +// 设置标题 | ||
| 95 | +const setDialogTile = (type: string) => { | ||
| 96 | + modelLoading.value = true | ||
| 97 | + modelTitle.value = t('action.' + type) | ||
| 98 | + actionType.value = type | ||
| 99 | + modelVisible.value = true | ||
| 100 | +} | ||
| 101 | + | ||
| 102 | +// 新增操作 | ||
| 103 | +const handleCreate = () => { | ||
| 104 | + setDialogTile('create') | ||
| 105 | + modelLoading.value = false | ||
| 106 | +} | ||
| 107 | + | ||
| 108 | +// 修改操作 | ||
| 109 | +const handleUpdate = async (rowId: number) => { | ||
| 110 | + setDialogTile('update') | ||
| 111 | + // 设置数据 | ||
| 112 | + const res = await MailAccountApi.getMailAccountApi(rowId) | ||
| 113 | + unref(formRef)?.setValues(res) | ||
| 114 | + modelLoading.value = false | ||
| 115 | +} | ||
| 116 | + | ||
| 117 | +// 详情操作 | ||
| 118 | +const handleDetail = async (rowId: number) => { | ||
| 119 | + setDialogTile('detail') | ||
| 120 | + const res = await MailAccountApi.getMailAccountApi(rowId) | ||
| 121 | + detailData.value = res | ||
| 122 | + modelLoading.value = false | ||
| 123 | +} | ||
| 124 | + | ||
| 125 | +// 提交按钮 | ||
| 126 | +const submitForm = async () => { | ||
| 127 | + const elForm = unref(formRef)?.getElFormRef() | ||
| 128 | + if (!elForm) return | ||
| 129 | + elForm.validate(async (valid) => { | ||
| 130 | + if (valid) { | ||
| 131 | + actionLoading.value = true | ||
| 132 | + // 提交请求 | ||
| 133 | + try { | ||
| 134 | + const data = unref(formRef)?.formModel as MailAccountApi.MailAccountVO | ||
| 135 | + if (actionType.value === 'create') { | ||
| 136 | + await MailAccountApi.createMailAccountApi(data) | ||
| 137 | + message.success(t('common.createSuccess')) | ||
| 138 | + } else { | ||
| 139 | + await MailAccountApi.updateMailAccountApi(data) | ||
| 140 | + message.success(t('common.updateSuccess')) | ||
| 141 | + } | ||
| 142 | + modelVisible.value = false | ||
| 143 | + } finally { | ||
| 144 | + actionLoading.value = false | ||
| 145 | + // 刷新列表 | ||
| 146 | + await reload() | ||
| 147 | + } | ||
| 148 | + } | ||
| 149 | + }) | ||
| 150 | +} | ||
| 151 | +</script> |
yudao-ui-admin/src/views/system/mail/account/index.vue
| @@ -27,7 +27,7 @@ | @@ -27,7 +27,7 @@ | ||
| 27 | 27 | ||
| 28 | <!-- 列表 --> | 28 | <!-- 列表 --> |
| 29 | <el-table v-loading="loading" :data="list"> | 29 | <el-table v-loading="loading" :data="list"> |
| 30 | - <el-table-column label="主键" align="center" prop="id" /> | 30 | + <el-table-column label="编号" align="center" prop="id" /> |
| 31 | <el-table-column label="邮箱" align="center" prop="mail" /> | 31 | <el-table-column label="邮箱" align="center" prop="mail" /> |
| 32 | <el-table-column label="用户名" align="center" prop="username" /> | 32 | <el-table-column label="用户名" align="center" prop="username" /> |
| 33 | <el-table-column label="SMTP 服务器域名" align="center" prop="host" /> | 33 | <el-table-column label="SMTP 服务器域名" align="center" prop="host" /> |