mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-31 10:37:41 +08:00 
			
		
		
		
	站内信模块:vue3 模版
This commit is contained in:
		| @ -21,7 +21,7 @@ export interface MailTemplatePageReqVO extends PageParam { | |||||||
|   createTime?: Date[] |   createTime?: Date[] | ||||||
| } | } | ||||||
|  |  | ||||||
| export interface MailSmsReqVO { | export interface MailSendReqVO { | ||||||
|   mail: string |   mail: string | ||||||
|   templateCode: string |   templateCode: string | ||||||
|   templateParams: Map<String, Object> |   templateParams: Map<String, Object> | ||||||
| @ -53,6 +53,6 @@ export const deleteMailTemplateApi = async (id: number) => { | |||||||
| } | } | ||||||
|  |  | ||||||
| // 发送邮件 | // 发送邮件 | ||||||
| export const sendMailApi = (data: MailSmsReqVO) => { | export const sendMailApi = (data: MailSendReqVO) => { | ||||||
|   return request.post({ url: '/system/mail-template/send-mail', data }) |   return request.post({ url: '/system/mail-template/send-mail', data }) | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										55
									
								
								yudao-ui-admin-vue3/src/api/system/notify/template/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								yudao-ui-admin-vue3/src/api/system/notify/template/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,55 @@ | |||||||
|  | import request from '@/config/axios' | ||||||
|  |  | ||||||
|  | export interface NotifyTemplateVO { | ||||||
|  |   id: number | ||||||
|  |   name: string | ||||||
|  |   code: string | ||||||
|  |   content: string | ||||||
|  |   type: number | ||||||
|  |   params: string | ||||||
|  |   status: number | ||||||
|  |   remark: string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export interface NotifyTemplatePageReqVO extends PageParam { | ||||||
|  |   name?: string | ||||||
|  |   code?: string | ||||||
|  |   status?: number | ||||||
|  |   createTime?: Date[] | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export interface NotifySendReqVO { | ||||||
|  |   userId: number | ||||||
|  |   templateCode: string | ||||||
|  |   templateParams: Map<String, Object> | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 查询站内信模板列表 | ||||||
|  | export const getNotifyTemplatePageApi = async (params: NotifyTemplatePageReqVO) => { | ||||||
|  |   return await request.get({ url: '/system/notify-template/page', params }) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 查询站内信模板详情 | ||||||
|  | export const getNotifyTemplateApi = async (id: number) => { | ||||||
|  |   return await request.get({ url: '/system/notify-template/get?id=' + id }) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 新增站内信模板 | ||||||
|  | export const createNotifyTemplateApi = async (data: NotifyTemplateVO) => { | ||||||
|  |   return await request.post({ url: '/system/notify-template/create', data }) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 修改站内信模板 | ||||||
|  | export const updateNotifyTemplateApi = async (data: NotifyTemplateVO) => { | ||||||
|  |   return await request.put({ url: '/system/notify-template/update', data }) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 删除站内信模板 | ||||||
|  | export const deleteNotifyTemplateApi = async (id: number) => { | ||||||
|  |   return await request.delete({ url: '/system/notify-template/delete?id=' + id }) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 发送站内信 | ||||||
|  | export const sendNotifyApi = (data: NotifySendReqVO) => { | ||||||
|  |   return request.post({ url: '/system/notify-template/send-notify', data }) | ||||||
|  | } | ||||||
| @ -91,6 +91,7 @@ export enum DICT_TYPE { | |||||||
|   SYSTEM_ERROR_CODE_TYPE = 'system_error_code_type', |   SYSTEM_ERROR_CODE_TYPE = 'system_error_code_type', | ||||||
|   SYSTEM_OAUTH2_GRANT_TYPE = 'system_oauth2_grant_type', |   SYSTEM_OAUTH2_GRANT_TYPE = 'system_oauth2_grant_type', | ||||||
|   SYSTEM_MAIL_SEND_STATUS = 'system_mail_send_status', |   SYSTEM_MAIL_SEND_STATUS = 'system_mail_send_status', | ||||||
|  |   SYSTEM_NOTIFY_TEMPLATE_TYPE = 'system_notify_template_type', | ||||||
|  |  | ||||||
|   // ========== INFRA 模块 ========== |   // ========== INFRA 模块 ========== | ||||||
|   INFRA_BOOLEAN_STRING = 'infra_boolean_string', |   INFRA_BOOLEAN_STRING = 'infra_boolean_string', | ||||||
|  | |||||||
| @ -252,7 +252,7 @@ const handleSendMail = (row: any) => { | |||||||
| } | } | ||||||
|  |  | ||||||
| const sendTest = async () => { | const sendTest = async () => { | ||||||
|   const data: MailTemplateApi.MailSmsReqVO = { |   const data: MailTemplateApi.MailSendReqVO = { | ||||||
|     mail: sendForm.value.mail, |     mail: sendForm.value.mail, | ||||||
|     templateCode: sendForm.value.templateCode, |     templateCode: sendForm.value.templateCode, | ||||||
|     templateParams: sendForm.value.templateParams as unknown as Map<string, Object> |     templateParams: sendForm.value.templateParams as unknown as Map<string, Object> | ||||||
|  | |||||||
							
								
								
									
										251
									
								
								yudao-ui-admin-vue3/src/views/system/notify/template/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										251
									
								
								yudao-ui-admin-vue3/src/views/system/notify/template/index.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,251 @@ | |||||||
|  | <template> | ||||||
|  |   <ContentWrap> | ||||||
|  |     <!-- 列表 --> | ||||||
|  |     <XTable @register="registerTable"> | ||||||
|  |       <template #toolbar_buttons> | ||||||
|  |         <!-- 操作:新增 --> | ||||||
|  |         <XButton | ||||||
|  |           type="primary" | ||||||
|  |           preIcon="ep:zoom-in" | ||||||
|  |           :title="t('action.add')" | ||||||
|  |           v-hasPermi="['system:notify-template:create']" | ||||||
|  |           @click="handleCreate()" | ||||||
|  |         /> | ||||||
|  |       </template> | ||||||
|  |       <template #actionbtns_default="{ row }"> | ||||||
|  |         <!-- 操作:测试站内信 --> | ||||||
|  |         <XTextButton | ||||||
|  |           preIcon="ep:cpu" | ||||||
|  |           :title="t('action.test')" | ||||||
|  |           v-hasPermi="['system:notify-template:send-notify']" | ||||||
|  |           @click="handleSendNotify(row)" | ||||||
|  |         /> | ||||||
|  |         <!-- 操作:修改 --> | ||||||
|  |         <XTextButton | ||||||
|  |           preIcon="ep:edit" | ||||||
|  |           :title="t('action.edit')" | ||||||
|  |           v-hasPermi="['system:notify-template:update']" | ||||||
|  |           @click="handleUpdate(row.id)" | ||||||
|  |         /> | ||||||
|  |         <!-- 操作:详情 --> | ||||||
|  |         <XTextButton | ||||||
|  |           preIcon="ep:view" | ||||||
|  |           :title="t('action.detail')" | ||||||
|  |           v-hasPermi="['system:notify-template:query']" | ||||||
|  |           @click="handleDetail(row.id)" | ||||||
|  |         /> | ||||||
|  |         <!-- 操作:删除 --> | ||||||
|  |         <XTextButton | ||||||
|  |           preIcon="ep:delete" | ||||||
|  |           :title="t('action.del')" | ||||||
|  |           v-hasPermi="['system:notify-template:delete']" | ||||||
|  |           @click="deleteData(row.id)" | ||||||
|  |         /> | ||||||
|  |       </template> | ||||||
|  |     </XTable> | ||||||
|  |   </ContentWrap> | ||||||
|  |  | ||||||
|  |   <!-- 添加/修改的弹窗 --> | ||||||
|  |   <XModal id="templateModel" :loading="modelLoading" v-model="modelVisible" :title="modelTitle"> | ||||||
|  |     <!-- 表单:添加/修改 --> | ||||||
|  |     <Form | ||||||
|  |       ref="formRef" | ||||||
|  |       v-if="['create', 'update'].includes(actionType)" | ||||||
|  |       :schema="allSchemas.formSchema" | ||||||
|  |       :rules="rules" | ||||||
|  |     /> | ||||||
|  |     <!-- 表单:详情 --> | ||||||
|  |     <Descriptions | ||||||
|  |       v-if="actionType === 'detail'" | ||||||
|  |       :schema="allSchemas.detailSchema" | ||||||
|  |       :data="detailData" | ||||||
|  |     /> | ||||||
|  |     <template #footer> | ||||||
|  |       <!-- 按钮:保存 --> | ||||||
|  |       <XButton | ||||||
|  |         v-if="['create', 'update'].includes(actionType)" | ||||||
|  |         type="primary" | ||||||
|  |         :title="t('action.save')" | ||||||
|  |         :loading="actionLoading" | ||||||
|  |         @click="submitForm()" | ||||||
|  |       /> | ||||||
|  |       <!-- 按钮:关闭 --> | ||||||
|  |       <XButton :loading="actionLoading" :title="t('dialog.close')" @click="modelVisible = false" /> | ||||||
|  |     </template> | ||||||
|  |   </XModal> | ||||||
|  |  | ||||||
|  |   <!-- 测试站内信的弹窗 --> | ||||||
|  |   <XModal id="sendTest" v-model="sendVisible" title="测试"> | ||||||
|  |     <el-form :model="sendForm" :rules="sendRules" label-width="200px" label-position="top"> | ||||||
|  |       <el-form-item label="模板内容" prop="content"> | ||||||
|  |         <el-input type="textarea" v-model="sendForm.content" readonly /> | ||||||
|  |       </el-form-item> | ||||||
|  |       <el-form-item label="接收人" prop="userId"> | ||||||
|  |         <el-select v-model="sendForm.userId" placeholder="请选择接收人"> | ||||||
|  |           <el-option | ||||||
|  |             v-for="item in userOption" | ||||||
|  |             :key="item.id" | ||||||
|  |             :label="item.nickname" | ||||||
|  |             :value="item.id" | ||||||
|  |           /> | ||||||
|  |         </el-select> | ||||||
|  |       </el-form-item> | ||||||
|  |       <el-form-item | ||||||
|  |         v-for="param in sendForm.params" | ||||||
|  |         :key="param" | ||||||
|  |         :label="'参数 {' + param + '}'" | ||||||
|  |         :prop="'templateParams.' + param" | ||||||
|  |       > | ||||||
|  |         <el-input | ||||||
|  |           v-model="sendForm.templateParams[param]" | ||||||
|  |           :placeholder="'请输入 ' + param + ' 参数'" | ||||||
|  |         /> | ||||||
|  |       </el-form-item> | ||||||
|  |     </el-form> | ||||||
|  |     <!-- 操作按钮 --> | ||||||
|  |     <template #footer> | ||||||
|  |       <XButton | ||||||
|  |         type="primary" | ||||||
|  |         :title="t('action.test')" | ||||||
|  |         :loading="actionLoading" | ||||||
|  |         @click="sendTest()" | ||||||
|  |       /> | ||||||
|  |       <XButton :title="t('dialog.close')" @click="sendVisible = false" /> | ||||||
|  |     </template> | ||||||
|  |   </XModal> | ||||||
|  | </template> | ||||||
|  | <script setup lang="ts" name="NotifyTemplate"> | ||||||
|  | import { FormExpose } from '@/components/Form' | ||||||
|  | // 业务相关的 import | ||||||
|  | import { rules, allSchemas } from './template.data' | ||||||
|  | import * as NotifyTemplateApi from '@/api/system/notify/template' | ||||||
|  | import { getListSimpleUsersApi, UserVO } from '@/api/system/user' | ||||||
|  |  | ||||||
|  | const { t } = useI18n() // 国际化 | ||||||
|  | const message = useMessage() // 消息弹窗 | ||||||
|  |  | ||||||
|  | // 列表相关的变量 | ||||||
|  | const [registerTable, { reload, deleteData }] = useXTable({ | ||||||
|  |   allSchemas: allSchemas, | ||||||
|  |   getListApi: NotifyTemplateApi.getNotifyTemplatePageApi, | ||||||
|  |   deleteApi: NotifyTemplateApi.deleteNotifyTemplateApi | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | // 弹窗相关的变量 | ||||||
|  | const modelVisible = ref(false) // 是否显示弹出层 | ||||||
|  | const modelTitle = ref('edit') // 弹出层标题 | ||||||
|  | const modelLoading = ref(false) // 弹出层loading | ||||||
|  | const actionType = ref('') // 操作按钮的类型 | ||||||
|  | const actionLoading = ref(false) // 按钮 Loading | ||||||
|  | const formRef = ref<FormExpose>() // 表单 Ref | ||||||
|  | const detailData = ref() // 详情 Ref | ||||||
|  |  | ||||||
|  | // 设置标题 | ||||||
|  | const setDialogTile = (type: string) => { | ||||||
|  |   modelLoading.value = true | ||||||
|  |   modelTitle.value = t('action.' + type) | ||||||
|  |   actionType.value = type | ||||||
|  |   modelVisible.value = true | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 新增操作 | ||||||
|  | const handleCreate = () => { | ||||||
|  |   setDialogTile('create') | ||||||
|  |   modelLoading.value = false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 修改操作 | ||||||
|  | const handleUpdate = async (rowId: number) => { | ||||||
|  |   setDialogTile('update') | ||||||
|  |   // 设置数据 | ||||||
|  |   const res = await NotifyTemplateApi.getNotifyTemplateApi(rowId) | ||||||
|  |   unref(formRef)?.setValues(res) | ||||||
|  |   modelLoading.value = false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 详情操作 | ||||||
|  | const handleDetail = async (rowId: number) => { | ||||||
|  |   setDialogTile('detail') | ||||||
|  |   const res = await NotifyTemplateApi.getNotifyTemplateApi(rowId) | ||||||
|  |   detailData.value = res | ||||||
|  |   modelLoading.value = false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 提交按钮 | ||||||
|  | const submitForm = async () => { | ||||||
|  |   const elForm = unref(formRef)?.getElFormRef() | ||||||
|  |   if (!elForm) return | ||||||
|  |   elForm.validate(async (valid) => { | ||||||
|  |     if (valid) { | ||||||
|  |       actionLoading.value = true | ||||||
|  |       // 提交请求 | ||||||
|  |       try { | ||||||
|  |         const data = unref(formRef)?.formModel as NotifyTemplateApi.NotifyTemplateVO | ||||||
|  |         if (actionType.value === 'create') { | ||||||
|  |           await NotifyTemplateApi.createNotifyTemplateApi(data) | ||||||
|  |           message.success(t('common.createSuccess')) | ||||||
|  |         } else { | ||||||
|  |           await NotifyTemplateApi.updateNotifyTemplateApi(data) | ||||||
|  |           message.success(t('common.updateSuccess')) | ||||||
|  |         } | ||||||
|  |         modelVisible.value = false | ||||||
|  |       } finally { | ||||||
|  |         actionLoading.value = false | ||||||
|  |         // 刷新列表 | ||||||
|  |         await reload() | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ========== 测试相关 ========== | ||||||
|  | const sendForm = ref({ | ||||||
|  |   content: '', | ||||||
|  |   params: {}, | ||||||
|  |   userId: undefined, | ||||||
|  |   templateCode: '', | ||||||
|  |   templateParams: {} | ||||||
|  | }) | ||||||
|  | const sendRules = ref({ | ||||||
|  |   userId: [{ required: true, message: '用户编号不能为空', trigger: 'blur' }], | ||||||
|  |   templateCode: [{ required: true, message: '模版编号不能为空', trigger: 'blur' }], | ||||||
|  |   templateParams: {} | ||||||
|  | }) | ||||||
|  | const sendVisible = ref(false) | ||||||
|  | const userOption = ref<UserVO[]>([]) | ||||||
|  |  | ||||||
|  | const handleSendNotify = (row: any) => { | ||||||
|  |   sendForm.value.content = row.content | ||||||
|  |   sendForm.value.params = row.params | ||||||
|  |   sendForm.value.templateCode = row.code | ||||||
|  |   sendForm.value.templateParams = row.params.reduce(function (obj, item) { | ||||||
|  |     obj[item] = undefined | ||||||
|  |     return obj | ||||||
|  |   }, {}) | ||||||
|  |   sendRules.value.templateParams = row.params.reduce(function (obj, item) { | ||||||
|  |     obj[item] = { required: true, message: '参数 ' + item + ' 不能为空', trigger: 'change' } | ||||||
|  |     return obj | ||||||
|  |   }, {}) | ||||||
|  |   sendVisible.value = true | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const sendTest = async () => { | ||||||
|  |   const data: NotifyTemplateApi.NotifySendReqVO = { | ||||||
|  |     userId: sendForm.value.userId, | ||||||
|  |     templateCode: sendForm.value.templateCode, | ||||||
|  |     templateParams: sendForm.value.templateParams as unknown as Map<string, Object> | ||||||
|  |   } | ||||||
|  |   const res = await NotifyTemplateApi.sendNotifyApi(data) | ||||||
|  |   if (res) { | ||||||
|  |     message.success('提交发送成功!发送结果,见发送日志编号:' + res) | ||||||
|  |   } | ||||||
|  |   sendVisible.value = false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ========== 初始化 ========== | ||||||
|  | onMounted(() => { | ||||||
|  |   getListSimpleUsersApi().then((data) => { | ||||||
|  |     userOption.value = data | ||||||
|  |   }) | ||||||
|  | }) | ||||||
|  | </script> | ||||||
| @ -0,0 +1,85 @@ | |||||||
|  | import type { VxeCrudSchema } from '@/hooks/web/useVxeCrudSchemas' | ||||||
|  |  | ||||||
|  | // 表单校验 | ||||||
|  | export const rules = reactive({ | ||||||
|  |   name: [required], | ||||||
|  |   code: [required], | ||||||
|  |   content: [required], | ||||||
|  |   type: [required], | ||||||
|  |   status: [required] | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | // CrudSchema | ||||||
|  | const crudSchemas = reactive<VxeCrudSchema>({ | ||||||
|  |   primaryKey: 'id', | ||||||
|  |   primaryTitle: '编号', | ||||||
|  |   primaryType: null, | ||||||
|  |   action: true, | ||||||
|  |   actionWidth: '260', // 3个按钮默认200,如有删减对应增减即可 | ||||||
|  |   columns: [ | ||||||
|  |     { | ||||||
|  |       title: '模版编码', | ||||||
|  |       field: 'code', | ||||||
|  |       isSearch: true | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       title: '模板名称', | ||||||
|  |       field: 'name', | ||||||
|  |       isSearch: true | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       title: '发件人名称', | ||||||
|  |       field: 'nickname' | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       title: '类型', | ||||||
|  |       field: 'type', | ||||||
|  |       dictType: DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE, | ||||||
|  |       dictClass: 'number' | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       title: '模版内容', | ||||||
|  |       field: 'content', | ||||||
|  |       table: { | ||||||
|  |         width: 300 | ||||||
|  |       }, | ||||||
|  |       form: { | ||||||
|  |         component: 'Input', | ||||||
|  |         componentProps: { | ||||||
|  |           type: 'textarea', | ||||||
|  |           rows: 4 | ||||||
|  |         }, | ||||||
|  |         colProps: { | ||||||
|  |           span: 24 | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       title: '状态', | ||||||
|  |       field: 'status', | ||||||
|  |       dictType: DICT_TYPE.COMMON_STATUS, | ||||||
|  |       dictClass: 'number', | ||||||
|  |       isSearch: true | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       title: '备注', | ||||||
|  |       field: 'remark' | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       title: '创建时间', | ||||||
|  |       field: 'createTime', | ||||||
|  |       isForm: false, | ||||||
|  |       formatter: 'formatDate', | ||||||
|  |       search: { | ||||||
|  |         show: true, | ||||||
|  |         itemRender: { | ||||||
|  |           name: 'XDataTimePicker' | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       table: { | ||||||
|  |         width: 180 | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   ] | ||||||
|  | }) | ||||||
|  | export const { allSchemas } = useVxeCrudSchemas(crudSchemas) | ||||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV