diff --git a/src/api/system/notify/template.ts b/src/api/system/notify/template.ts index ebf8a9e..f595415 100644 --- a/src/api/system/notify/template.ts +++ b/src/api/system/notify/template.ts @@ -34,3 +34,30 @@ export function listSimplePosts() { export function exportNotifyTemplateExcel(params) { return defHttp.download({ url: '/system/notify-template/export-excel', params }, '导出站内信模板.xls') } + +export type SendNotifyParam = { + userId: number + templateCode: string + templateParams: { + [key: string]: string + } +} + +export type NotifyTemplate = { + name: string + code: string + type: number + nickname: string + content: string + status: number + remark?: any + id: number + params: string[] + createTime: number + key: string +} + +// 发送 +export function sendNotify(data: SendNotifyParam) { + return defHttp.post({ url: '/system/notify-template/send-notify', data }) +} diff --git a/src/locales/lang/zh-CN/action.ts b/src/locales/lang/zh-CN/action.ts index eaa422e..270cf12 100644 --- a/src/locales/lang/zh-CN/action.ts +++ b/src/locales/lang/zh-CN/action.ts @@ -9,5 +9,6 @@ export default { export: '导出', import: '导入', sync: '同步', - cancel: '取消' + cancel: '取消', + send: '发送' } diff --git a/src/views/infra/codegen/components/ImportTableModal.vue b/src/views/infra/codegen/components/ImportTableModal.vue index 0452071..92ffcd2 100644 --- a/src/views/infra/codegen/components/ImportTableModal.vue +++ b/src/views/infra/codegen/components/ImportTableModal.vue @@ -24,7 +24,8 @@ const [registerTable, { getSelectRowKeys, getForm }] = useTable({ useSearchForm: true, pagination: false, showTableSetting: false, - showIndexColumn: false + showIndexColumn: false, + immediate: false }) const [registerModal, { setModalProps, closeModal }] = useModalInner(async () => { diff --git a/src/views/system/notify/template/SendNotifyModal.vue b/src/views/system/notify/template/SendNotifyModal.vue new file mode 100644 index 0000000..fc86a15 --- /dev/null +++ b/src/views/system/notify/template/SendNotifyModal.vue @@ -0,0 +1,89 @@ +<template> + <BasicModal v-bind="$attrs" title="发送站内信" @register="innerRegister" @ok="submit"> + <BasicForm @register="register" :schemas="reactiveSchemas" /> + </BasicModal> +</template> + +<script setup lang="ts"> +import { BasicModal, useModalInner } from '@/components/Modal' +import { BasicForm, FormSchema, useForm } from '@/components/Form' +import { reactive, ref } from 'vue' +import { useMessage } from '@/hooks/web/useMessage' +import { sendNotify, SendNotifyParam, NotifyTemplate } from '@/api/system/notify/template' +import { baseSendSchemas } from './template.data' + +defineOptions({ name: 'SendNotifyModal' }) + +const { createMessage } = useMessage() +let reactiveSchemas: FormSchema[] = reactive([]) +const templateCode = ref<string>('') + +const [register, { setFieldsValue, getFieldsValue, validateFields, resetFields, clearValidate, setProps }] = useForm({ + labelWidth: 100, + // schemas: reactiveSchemas, 这里用动态绑定会有问题 + baseColProps: { + span: 24 + }, + showSubmitButton: false, + showResetButton: false +}) + +const [innerRegister, { changeLoading, closeModal }] = useModalInner((data: NotifyTemplate) => { + resetForm() + data.params.forEach((item) => { + const dySchema: FormSchema = { + // 这里加上前缀 防止和content/userId字段重名 + field: `key-${item}`, + label: `参数{${item}} `, + component: 'Input', + componentProps: { + placeholder: `输入{${item}}` + }, + required: true + } + reactiveSchemas.push(dySchema) + }) + const { content, code } = data + setFieldsValue({ content }) + templateCode.value = code +}) + +const submit = async () => { + try { + setProps({ disabled: true }) + changeLoading(true) + await validateFields() + const fields = getFieldsValue() + const data: SendNotifyParam = { + userId: fields.userId, + templateCode: templateCode.value, + templateParams: {} + } + Object.keys(fields).forEach((key) => { + if (key === 'content' || key === 'userId') { + return + } + // 去掉 - 后的key + const realKey = key.split('-')[1] + data.templateParams[realKey] = fields[key] + }) + await sendNotify(data) + createMessage.success(`发送站内信成功`) + closeModal() + } finally { + setProps({ disabled: false }) + changeLoading(false) + } +} + +const resetForm = () => { + // 这里需要每次清空动态表单 + reactiveSchemas.splice(0, reactiveSchemas.length) + reactiveSchemas.push(...baseSendSchemas) + // 清除上一次的表单校验和参数 + resetFields() + clearValidate() +} +</script> + +<style scoped></style> diff --git a/src/views/system/notify/template/index.vue b/src/views/system/notify/template/index.vue index c4b76e1..d9a24da 100644 --- a/src/views/system/notify/template/index.vue +++ b/src/views/system/notify/template/index.vue @@ -10,6 +10,12 @@ <template v-if="column.key === 'action'"> <TableAction :actions="[ + { + icon: IconEnum.UPLOAD, + label: t('action.send'), + auth: 'system:notify-template:update', + onClick: handleSend.bind(null, record) + }, { icon: IconEnum.EDIT, label: t('action.edit'), @@ -33,6 +39,7 @@ </template> </BasicTable> <TemplateModal @register="registerModal" @success="reload()" /> + <SendNotifyModal @register="registerSendModal" /> </div> </template> <script lang="ts" setup> @@ -44,12 +51,14 @@ import { IconEnum } from '@/enums/appEnum' import { BasicTable, useTable, TableAction } from '@/components/Table' import { deleteNotifyTemplate, getNotifyTemplatePage } from '@/api/system/notify/template' import { columns, searchFormSchema } from './template.data' +import SendNotifyModal from './SendNotifyModal.vue' defineOptions({ name: 'SystemMessageTemplate' }) const { t } = useI18n() const { createMessage } = useMessage() const [registerModal, { openModal }] = useModal() +const [registerSendModal, { openModal: openSendModal }] = useModal() const [registerTable, { reload }] = useTable({ title: '站内信模板列表', @@ -60,7 +69,7 @@ const [registerTable, { reload }] = useTable({ showTableSetting: true, showIndexColumn: false, actionColumn: { - width: 140, + width: 200, title: t('common.action'), dataIndex: 'action', fixed: 'right' @@ -75,6 +84,11 @@ function handleEdit(record: Recordable) { openModal(true, { record, isUpdate: true }) } +function handleSend(record: Recordable) { + console.log(JSON.stringify(record, [...Object.keys(record)], 2)) + openSendModal(true, record) +} + async function handleDelete(record: Recordable) { await deleteNotifyTemplate(record.id) createMessage.success(t('common.delSuccessText')) diff --git a/src/views/system/notify/template/template.data.ts b/src/views/system/notify/template/template.data.ts index 75a1e23..8ebb776 100644 --- a/src/views/system/notify/template/template.data.ts +++ b/src/views/system/notify/template/template.data.ts @@ -1,5 +1,6 @@ import { BasicColumn, FormSchema, useRender } from '@/components/Table' import { DICT_TYPE, getDictOptions } from '@/utils/dict' +import { getListSimpleUsers } from '@/api/system/user/index' export const columns: BasicColumn[] = [ { @@ -125,6 +126,7 @@ export const formSchema: FormSchema[] = [ { label: '开启状态', field: 'status', + required: true, component: 'RadioGroup', componentProps: { options: getDictOptions(DICT_TYPE.COMMON_STATUS) @@ -136,3 +138,27 @@ export const formSchema: FormSchema[] = [ component: 'InputTextArea' } ] + +// 发送站内信 +export const baseSendSchemas: FormSchema[] = [ + { + field: 'content', + component: 'InputTextArea', + label: '模板内容 ', + required: false, + componentProps: { + disabled: true + } + }, + { + field: 'userId', + component: 'ApiSelect', + label: '接收人 ', + required: true, + componentProps: { + api: getListSimpleUsers, + labelField: 'nickname', + valueField: 'id' + } + } +]