Commit cb0da2db6a2fcd32a3a331e1b680061e5a83925a

Authored by YunaiV
1 parent 1943e71e

站内信模块:vue3 模版

yudao-ui-admin-vue3/src/api/system/mail/template/index.ts
... ... @@ -21,7 +21,7 @@ export interface MailTemplatePageReqVO extends PageParam {
21 21 createTime?: Date[]
22 22 }
23 23  
24   -export interface MailSmsReqVO {
  24 +export interface MailSendReqVO {
25 25 mail: string
26 26 templateCode: string
27 27 templateParams: Map<String, Object>
... ... @@ -53,6 +53,6 @@ export const deleteMailTemplateApi = async (id: number) =&gt; {
53 53 }
54 54  
55 55 // 发送邮件
56   -export const sendMailApi = (data: MailSmsReqVO) => {
  56 +export const sendMailApi = (data: MailSendReqVO) => {
57 57 return request.post({ url: '/system/mail-template/send-mail', data })
58 58 }
... ...
yudao-ui-admin-vue3/src/api/system/notify/template/index.ts 0 → 100644
  1 +import request from '@/config/axios'
  2 +
  3 +export interface NotifyTemplateVO {
  4 + id: number
  5 + name: string
  6 + code: string
  7 + content: string
  8 + type: number
  9 + params: string
  10 + status: number
  11 + remark: string
  12 +}
  13 +
  14 +export interface NotifyTemplatePageReqVO extends PageParam {
  15 + name?: string
  16 + code?: string
  17 + status?: number
  18 + createTime?: Date[]
  19 +}
  20 +
  21 +export interface NotifySendReqVO {
  22 + userId: number
  23 + templateCode: string
  24 + templateParams: Map<String, Object>
  25 +}
  26 +
  27 +// 查询站内信模板列表
  28 +export const getNotifyTemplatePageApi = async (params: NotifyTemplatePageReqVO) => {
  29 + return await request.get({ url: '/system/notify-template/page', params })
  30 +}
  31 +
  32 +// 查询站内信模板详情
  33 +export const getNotifyTemplateApi = async (id: number) => {
  34 + return await request.get({ url: '/system/notify-template/get?id=' + id })
  35 +}
  36 +
  37 +// 新增站内信模板
  38 +export const createNotifyTemplateApi = async (data: NotifyTemplateVO) => {
  39 + return await request.post({ url: '/system/notify-template/create', data })
  40 +}
  41 +
  42 +// 修改站内信模板
  43 +export const updateNotifyTemplateApi = async (data: NotifyTemplateVO) => {
  44 + return await request.put({ url: '/system/notify-template/update', data })
  45 +}
  46 +
  47 +// 删除站内信模板
  48 +export const deleteNotifyTemplateApi = async (id: number) => {
  49 + return await request.delete({ url: '/system/notify-template/delete?id=' + id })
  50 +}
  51 +
  52 +// 发送站内信
  53 +export const sendNotifyApi = (data: NotifySendReqVO) => {
  54 + return request.post({ url: '/system/notify-template/send-notify', data })
  55 +}
... ...
yudao-ui-admin-vue3/src/utils/dict.ts
... ... @@ -91,6 +91,7 @@ export enum DICT_TYPE {
91 91 SYSTEM_ERROR_CODE_TYPE = 'system_error_code_type',
92 92 SYSTEM_OAUTH2_GRANT_TYPE = 'system_oauth2_grant_type',
93 93 SYSTEM_MAIL_SEND_STATUS = 'system_mail_send_status',
  94 + SYSTEM_NOTIFY_TEMPLATE_TYPE = 'system_notify_template_type',
94 95  
95 96 // ========== INFRA 模块 ==========
96 97 INFRA_BOOLEAN_STRING = 'infra_boolean_string',
... ...
yudao-ui-admin-vue3/src/views/system/mail/template/index.vue
... ... @@ -252,7 +252,7 @@ const handleSendMail = (row: any) =&gt; {
252 252 }
253 253  
254 254 const sendTest = async () => {
255   - const data: MailTemplateApi.MailSmsReqVO = {
  255 + const data: MailTemplateApi.MailSendReqVO = {
256 256 mail: sendForm.value.mail,
257 257 templateCode: sendForm.value.templateCode,
258 258 templateParams: sendForm.value.templateParams as unknown as Map<string, Object>
... ...
yudao-ui-admin-vue3/src/views/system/notify/template/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:notify-template:create']"
  12 + @click="handleCreate()"
  13 + />
  14 + </template>
  15 + <template #actionbtns_default="{ row }">
  16 + <!-- 操作:测试站内信 -->
  17 + <XTextButton
  18 + preIcon="ep:cpu"
  19 + :title="t('action.test')"
  20 + v-hasPermi="['system:notify-template:send-notify']"
  21 + @click="handleSendNotify(row)"
  22 + />
  23 + <!-- 操作:修改 -->
  24 + <XTextButton
  25 + preIcon="ep:edit"
  26 + :title="t('action.edit')"
  27 + v-hasPermi="['system:notify-template:update']"
  28 + @click="handleUpdate(row.id)"
  29 + />
  30 + <!-- 操作:详情 -->
  31 + <XTextButton
  32 + preIcon="ep:view"
  33 + :title="t('action.detail')"
  34 + v-hasPermi="['system:notify-template:query']"
  35 + @click="handleDetail(row.id)"
  36 + />
  37 + <!-- 操作:删除 -->
  38 + <XTextButton
  39 + preIcon="ep:delete"
  40 + :title="t('action.del')"
  41 + v-hasPermi="['system:notify-template:delete']"
  42 + @click="deleteData(row.id)"
  43 + />
  44 + </template>
  45 + </XTable>
  46 + </ContentWrap>
  47 +
  48 + <!-- 添加/修改的弹窗 -->
  49 + <XModal id="templateModel" :loading="modelLoading" v-model="modelVisible" :title="modelTitle">
  50 + <!-- 表单:添加/修改 -->
  51 + <Form
  52 + ref="formRef"
  53 + v-if="['create', 'update'].includes(actionType)"
  54 + :schema="allSchemas.formSchema"
  55 + :rules="rules"
  56 + />
  57 + <!-- 表单:详情 -->
  58 + <Descriptions
  59 + v-if="actionType === 'detail'"
  60 + :schema="allSchemas.detailSchema"
  61 + :data="detailData"
  62 + />
  63 + <template #footer>
  64 + <!-- 按钮:保存 -->
  65 + <XButton
  66 + v-if="['create', 'update'].includes(actionType)"
  67 + type="primary"
  68 + :title="t('action.save')"
  69 + :loading="actionLoading"
  70 + @click="submitForm()"
  71 + />
  72 + <!-- 按钮:关闭 -->
  73 + <XButton :loading="actionLoading" :title="t('dialog.close')" @click="modelVisible = false" />
  74 + </template>
  75 + </XModal>
  76 +
  77 + <!-- 测试站内信的弹窗 -->
  78 + <XModal id="sendTest" v-model="sendVisible" title="测试">
  79 + <el-form :model="sendForm" :rules="sendRules" label-width="200px" label-position="top">
  80 + <el-form-item label="模板内容" prop="content">
  81 + <el-input type="textarea" v-model="sendForm.content" readonly />
  82 + </el-form-item>
  83 + <el-form-item label="接收人" prop="userId">
  84 + <el-select v-model="sendForm.userId" placeholder="请选择接收人">
  85 + <el-option
  86 + v-for="item in userOption"
  87 + :key="item.id"
  88 + :label="item.nickname"
  89 + :value="item.id"
  90 + />
  91 + </el-select>
  92 + </el-form-item>
  93 + <el-form-item
  94 + v-for="param in sendForm.params"
  95 + :key="param"
  96 + :label="'参数 {' + param + '}'"
  97 + :prop="'templateParams.' + param"
  98 + >
  99 + <el-input
  100 + v-model="sendForm.templateParams[param]"
  101 + :placeholder="'请输入 ' + param + ' 参数'"
  102 + />
  103 + </el-form-item>
  104 + </el-form>
  105 + <!-- 操作按钮 -->
  106 + <template #footer>
  107 + <XButton
  108 + type="primary"
  109 + :title="t('action.test')"
  110 + :loading="actionLoading"
  111 + @click="sendTest()"
  112 + />
  113 + <XButton :title="t('dialog.close')" @click="sendVisible = false" />
  114 + </template>
  115 + </XModal>
  116 +</template>
  117 +<script setup lang="ts" name="NotifyTemplate">
  118 +import { FormExpose } from '@/components/Form'
  119 +// 业务相关的 import
  120 +import { rules, allSchemas } from './template.data'
  121 +import * as NotifyTemplateApi from '@/api/system/notify/template'
  122 +import { getListSimpleUsersApi, UserVO } from '@/api/system/user'
  123 +
  124 +const { t } = useI18n() // 国际化
  125 +const message = useMessage() // 消息弹窗
  126 +
  127 +// 列表相关的变量
  128 +const [registerTable, { reload, deleteData }] = useXTable({
  129 + allSchemas: allSchemas,
  130 + getListApi: NotifyTemplateApi.getNotifyTemplatePageApi,
  131 + deleteApi: NotifyTemplateApi.deleteNotifyTemplateApi
  132 +})
  133 +
  134 +// 弹窗相关的变量
  135 +const modelVisible = ref(false) // 是否显示弹出层
  136 +const modelTitle = ref('edit') // 弹出层标题
  137 +const modelLoading = ref(false) // 弹出层loading
  138 +const actionType = ref('') // 操作按钮的类型
  139 +const actionLoading = ref(false) // 按钮 Loading
  140 +const formRef = ref<FormExpose>() // 表单 Ref
  141 +const detailData = ref() // 详情 Ref
  142 +
  143 +// 设置标题
  144 +const setDialogTile = (type: string) => {
  145 + modelLoading.value = true
  146 + modelTitle.value = t('action.' + type)
  147 + actionType.value = type
  148 + modelVisible.value = true
  149 +}
  150 +
  151 +// 新增操作
  152 +const handleCreate = () => {
  153 + setDialogTile('create')
  154 + modelLoading.value = false
  155 +}
  156 +
  157 +// 修改操作
  158 +const handleUpdate = async (rowId: number) => {
  159 + setDialogTile('update')
  160 + // 设置数据
  161 + const res = await NotifyTemplateApi.getNotifyTemplateApi(rowId)
  162 + unref(formRef)?.setValues(res)
  163 + modelLoading.value = false
  164 +}
  165 +
  166 +// 详情操作
  167 +const handleDetail = async (rowId: number) => {
  168 + setDialogTile('detail')
  169 + const res = await NotifyTemplateApi.getNotifyTemplateApi(rowId)
  170 + detailData.value = res
  171 + modelLoading.value = false
  172 +}
  173 +
  174 +// 提交按钮
  175 +const submitForm = async () => {
  176 + const elForm = unref(formRef)?.getElFormRef()
  177 + if (!elForm) return
  178 + elForm.validate(async (valid) => {
  179 + if (valid) {
  180 + actionLoading.value = true
  181 + // 提交请求
  182 + try {
  183 + const data = unref(formRef)?.formModel as NotifyTemplateApi.NotifyTemplateVO
  184 + if (actionType.value === 'create') {
  185 + await NotifyTemplateApi.createNotifyTemplateApi(data)
  186 + message.success(t('common.createSuccess'))
  187 + } else {
  188 + await NotifyTemplateApi.updateNotifyTemplateApi(data)
  189 + message.success(t('common.updateSuccess'))
  190 + }
  191 + modelVisible.value = false
  192 + } finally {
  193 + actionLoading.value = false
  194 + // 刷新列表
  195 + await reload()
  196 + }
  197 + }
  198 + })
  199 +}
  200 +
  201 +// ========== 测试相关 ==========
  202 +const sendForm = ref({
  203 + content: '',
  204 + params: {},
  205 + userId: undefined,
  206 + templateCode: '',
  207 + templateParams: {}
  208 +})
  209 +const sendRules = ref({
  210 + userId: [{ required: true, message: '用户编号不能为空', trigger: 'blur' }],
  211 + templateCode: [{ required: true, message: '模版编号不能为空', trigger: 'blur' }],
  212 + templateParams: {}
  213 +})
  214 +const sendVisible = ref(false)
  215 +const userOption = ref<UserVO[]>([])
  216 +
  217 +const handleSendNotify = (row: any) => {
  218 + sendForm.value.content = row.content
  219 + sendForm.value.params = row.params
  220 + sendForm.value.templateCode = row.code
  221 + sendForm.value.templateParams = row.params.reduce(function (obj, item) {
  222 + obj[item] = undefined
  223 + return obj
  224 + }, {})
  225 + sendRules.value.templateParams = row.params.reduce(function (obj, item) {
  226 + obj[item] = { required: true, message: '参数 ' + item + ' 不能为空', trigger: 'change' }
  227 + return obj
  228 + }, {})
  229 + sendVisible.value = true
  230 +}
  231 +
  232 +const sendTest = async () => {
  233 + const data: NotifyTemplateApi.NotifySendReqVO = {
  234 + userId: sendForm.value.userId,
  235 + templateCode: sendForm.value.templateCode,
  236 + templateParams: sendForm.value.templateParams as unknown as Map<string, Object>
  237 + }
  238 + const res = await NotifyTemplateApi.sendNotifyApi(data)
  239 + if (res) {
  240 + message.success('提交发送成功!发送结果,见发送日志编号:' + res)
  241 + }
  242 + sendVisible.value = false
  243 +}
  244 +
  245 +// ========== 初始化 ==========
  246 +onMounted(() => {
  247 + getListSimpleUsersApi().then((data) => {
  248 + userOption.value = data
  249 + })
  250 +})
  251 +</script>
... ...
yudao-ui-admin-vue3/src/views/system/notify/template/template.data.ts 0 → 100644
  1 +import type { VxeCrudSchema } from '@/hooks/web/useVxeCrudSchemas'
  2 +
  3 +// 表单校验
  4 +export const rules = reactive({
  5 + name: [required],
  6 + code: [required],
  7 + content: [required],
  8 + type: [required],
  9 + status: [required]
  10 +})
  11 +
  12 +// CrudSchema
  13 +const crudSchemas = reactive<VxeCrudSchema>({
  14 + primaryKey: 'id',
  15 + primaryTitle: '编号',
  16 + primaryType: null,
  17 + action: true,
  18 + actionWidth: '260', // 3个按钮默认200,如有删减对应增减即可
  19 + columns: [
  20 + {
  21 + title: '模版编码',
  22 + field: 'code',
  23 + isSearch: true
  24 + },
  25 + {
  26 + title: '模板名称',
  27 + field: 'name',
  28 + isSearch: true
  29 + },
  30 + {
  31 + title: '发件人名称',
  32 + field: 'nickname'
  33 + },
  34 + {
  35 + title: '类型',
  36 + field: 'type',
  37 + dictType: DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE,
  38 + dictClass: 'number'
  39 + },
  40 + {
  41 + title: '模版内容',
  42 + field: 'content',
  43 + table: {
  44 + width: 300
  45 + },
  46 + form: {
  47 + component: 'Input',
  48 + componentProps: {
  49 + type: 'textarea',
  50 + rows: 4
  51 + },
  52 + colProps: {
  53 + span: 24
  54 + }
  55 + }
  56 + },
  57 + {
  58 + title: '状态',
  59 + field: 'status',
  60 + dictType: DICT_TYPE.COMMON_STATUS,
  61 + dictClass: 'number',
  62 + isSearch: true
  63 + },
  64 + {
  65 + title: '备注',
  66 + field: 'remark'
  67 + },
  68 + {
  69 + title: '创建时间',
  70 + field: 'createTime',
  71 + isForm: false,
  72 + formatter: 'formatDate',
  73 + search: {
  74 + show: true,
  75 + itemRender: {
  76 + name: 'XDataTimePicker'
  77 + }
  78 + },
  79 + table: {
  80 + width: 180
  81 + }
  82 + }
  83 + ]
  84 +})
  85 +export const { allSchemas } = useVxeCrudSchemas(crudSchemas)
... ...