diff --git a/src/api/system/sms/smsTemplate/index.ts b/src/api/system/sms/smsTemplate/index.ts index 55a61762..35cb489d 100644 --- a/src/api/system/sms/smsTemplate/index.ts +++ b/src/api/system/sms/smsTemplate/index.ts @@ -3,7 +3,7 @@ import request from '@/config/axios' export interface SmsTemplateVO { id: number | null type: number | null - status: number | null + status: number code: string name: string content: string @@ -21,60 +21,40 @@ export interface SendSmsReqVO { templateParams: Map<String, Object> } -export interface SmsTemplatePageReqVO extends PageParam { - type?: number | null - status?: number | null - code?: string - content?: string - apiTemplateId?: string - channelId?: number | null - createTime?: Date[] -} - -export interface SmsTemplateExportReqVO { - type?: number - status?: number - code?: string - content?: string - apiTemplateId?: string - channelId?: number - createTime?: Date[] -} - // 查询短信模板列表 -export const getSmsTemplatePageApi = (params: SmsTemplatePageReqVO) => { +export const getSmsTemplatePage = (params: PageParam) => { return request.get({ url: '/system/sms-template/page', params }) } // 查询短信模板详情 -export const getSmsTemplateApi = (id: number) => { +export const getSmsTemplate = (id: number) => { return request.get({ url: '/system/sms-template/get?id=' + id }) } // 新增短信模板 -export const createSmsTemplateApi = (data: SmsTemplateVO) => { +export const createSmsTemplate = (data: SmsTemplateVO) => { return request.post({ url: '/system/sms-template/create', data }) } // 修改短信模板 -export const updateSmsTemplateApi = (data: SmsTemplateVO) => { +export const updateSmsTemplate = (data: SmsTemplateVO) => { return request.put({ url: '/system/sms-template/update', data }) } // 删除短信模板 -export const deleteSmsTemplateApi = (id: number) => { +export const deleteSmsTemplate = (id: number) => { return request.delete({ url: '/system/sms-template/delete?id=' + id }) } -// 发送短信 -export const sendSmsApi = (data: SendSmsReqVO) => { - return request.post({ url: '/system/sms-template/send-sms', data }) -} - // 导出短信模板 -export const exportPostApi = (params: SmsTemplateExportReqVO) => { +export const exportSmsTemplate = (params) => { return request.download({ url: '/system/sms-template/export-excel', params }) } + +// 发送短信 +export const sendSms = (data: SendSmsReqVO) => { + return request.post({ url: '/system/sms-template/send-sms', data }) +} diff --git a/src/views/system/sms/log/index.vue b/src/views/system/sms/log/index.vue index a0acdfaa..ec8a4659 100644 --- a/src/views/system/sms/log/index.vue +++ b/src/views/system/sms/log/index.vue @@ -102,7 +102,7 @@ plain @click="handleExport" :loading="exportLoading" - v-hasPermi="['infra:config:export']" + v-hasPermi="['system:sms-log:export']" > <Icon icon="ep:download" class="mr-5px" /> 导出 </el-button> diff --git a/src/views/system/sms/template/SmsTemplateForm.vue b/src/views/system/sms/template/SmsTemplateForm.vue new file mode 100644 index 00000000..e6bdce6c --- /dev/null +++ b/src/views/system/sms/template/SmsTemplateForm.vue @@ -0,0 +1,160 @@ +<template> + <Dialog :title="modelTitle" v-model="modelVisible"> + <el-form + ref="formRef" + :model="formData" + :rules="formRules" + label-width="140px" + v-loading="formLoading" + > + <el-form-item label="短信渠道编号" prop="channelId"> + <el-select v-model="formData.channelId" placeholder="请选择短信渠道编号"> + <el-option + v-for="channel in channelList" + :key="channel.id" + :value="channel.id" + :label=" + channel.signature + + `【 ${getDictLabel(DICT_TYPE.SYSTEM_SMS_CHANNEL_CODE, channel.code)}】` + " + /> + </el-select> + </el-form-item> + <el-form-item label="短信类型" prop="type"> + <el-select v-model="formData.type" placeholder="请选择短信类型"> + <el-option + v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_SMS_TEMPLATE_TYPE)" + :key="dict.value" + :label="dict.label" + :value="dict.value" + /> + </el-select> + </el-form-item> + <el-form-item label="模板编号" prop="code"> + <el-input v-model="formData.code" placeholder="请输入模板编号" /> + </el-form-item> + <el-form-item label="模板名称" prop="name"> + <el-input v-model="formData.name" placeholder="请输入模板名称" /> + </el-form-item> + <el-form-item label="模板内容" prop="content"> + <el-input type="textarea" v-model="formData.content" placeholder="请输入模板内容" /> + </el-form-item> + <el-form-item label="开启状态" prop="status"> + <el-radio-group v-model="formData.status"> + <el-radio + v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)" + :key="dict.value" + :label="parseInt(dict.value)" + > + {{ dict.label }} + </el-radio> + </el-radio-group> + </el-form-item> + <el-form-item label="短信 API 模板编号" prop="apiTemplateId"> + <el-input v-model="formData.apiTemplateId" placeholder="请输入短信 API 的模板编号" /> + </el-form-item> + <el-form-item label="备注" prop="remark"> + <el-input v-model="formData.remark" placeholder="请输入备注" /> + </el-form-item> + </el-form> + <template #footer> + <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button> + <el-button @click="modelVisible = false">取 消</el-button> + </template> + </Dialog> +</template> +<script setup lang="ts"> +import { DICT_TYPE, getIntDictOptions, getDictLabel } from '@/utils/dict' +import * as SmsTemplateApi from '@/api/system/sms/smsTemplate' +import * as SmsChannelApi from '@/api/system/sms/smsChannel' +import { CommonStatusEnum } from '@/utils/constants' +const { t } = useI18n() // 国际化 +const message = useMessage() // 消息弹窗 + +const modelVisible = ref(false) // 弹窗的是否展示 +const modelTitle = ref('') // 弹窗的标题 +const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用 +const formType = ref('') // 表单的类型 +const formData = ref<SmsTemplateApi.SmsTemplateVO>({ + id: null, + type: null, + status: CommonStatusEnum.ENABLE, + code: '', + name: '', + content: '', + remark: '', + apiTemplateId: '', + channelId: null +}) +const formRules = reactive({ + type: [{ required: true, message: '短信类型不能为空', trigger: 'change' }], + status: [{ required: true, message: '开启状态不能为空', trigger: 'blur' }], + code: [{ required: true, message: '模板编码不能为空', trigger: 'blur' }], + name: [{ required: true, message: '模板名称不能为空', trigger: 'blur' }], + content: [{ required: true, message: '模板内容不能为空', trigger: 'blur' }], + apiTemplateId: [{ required: true, message: '短信 API 的模板编号不能为空', trigger: 'blur' }], + channelId: [{ required: true, message: '短信渠道编号不能为空', trigger: 'change' }] +}) +const formRef = ref() // 表单 Ref +const channelList = ref([]) // 短信渠道列表 + +const open = async (type: string, id?: number) => { + modelVisible.value = true + modelTitle.value = t('action.' + type) + formType.value = type + resetForm() + // 修改时,设置数据 + if (id) { + formLoading.value = true + try { + formData.value = await SmsTemplateApi.getSmsTemplate(id) + } finally { + formLoading.value = false + } + } + // 加载渠道列表 + channelList.value = await SmsChannelApi.getSimpleSmsChannelList() +} +defineExpose({ open }) // 提供 open 方法,用于打开弹窗 + +/** 提交表单 */ +const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调 +const submitForm = async () => { + // 校验表单 + if (!formRef) return + const valid = await formRef.value.validate() + if (!valid) return + formLoading.value = true + try { + const data = formData.value as SmsTemplateApi.SmsTemplateVO + if (formType.value === 'create') { + await SmsTemplateApi.createSmsTemplate(data) + message.success(t('common.createSuccess')) + } else { + await SmsTemplateApi.updateSmsTemplate(data) + message.success(t('common.updateSuccess')) + } + modelVisible.value = false + // 发送操作成功的事件 + emit('success') + } finally { + formLoading.value = false + } +} + +/** 重置表单 */ +const resetForm = () => { + formData.value = { + id: null, + type: null, + status: CommonStatusEnum.ENABLE, + code: '', + name: '', + content: '', + remark: '', + apiTemplateId: '', + channelId: null + } + formRef.value?.resetFields() +} +</script> diff --git a/src/views/system/sms/template/SmsTemplateSendForm.vue b/src/views/system/sms/template/SmsTemplateSendForm.vue new file mode 100644 index 00000000..f2ecbe9f --- /dev/null +++ b/src/views/system/sms/template/SmsTemplateSendForm.vue @@ -0,0 +1,117 @@ +<template> + <Dialog title="测试" v-model="modelVisible"> + <el-form + ref="formRef" + :model="formData" + :rules="formRules" + label-width="140px" + v-loading="formLoading" + > + <el-form-item label="模板内容" prop="content"> + <el-input + v-model="formData.content" + type="textarea" + placeholder="请输入模板内容" + readonly + /> + </el-form-item> + <el-form-item label="手机号" prop="mobile"> + <el-input v-model="formData.mobile" placeholder="请输入手机号" /> + </el-form-item> + <el-form-item + v-for="param in formData.params" + :key="param" + :label="'参数 {' + param + '}'" + :prop="'templateParams.' + param" + > + <el-input + v-model="formData.templateParams[param]" + :placeholder="'请输入 ' + param + ' 参数'" + /> + </el-form-item> + </el-form> + <template #footer> + <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button> + <el-button @click="modelVisible = false">取 消</el-button> + </template> + </Dialog> +</template> +<script setup lang="ts"> +import * as SmsTemplateApi from '@/api/system/sms/smsTemplate' +const message = useMessage() // 消息弹窗 + +const modelVisible = ref(false) // 弹窗的是否展示 +const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用 + +// 发送短信表单相关 +const formData = ref({ + content: '', + params: {}, + mobile: '', + templateCode: '', + templateParams: new Map() +}) +const formRules = reactive({ + mobile: [{ required: true, message: '手机不能为空', trigger: 'blur' }], + templateCode: [{ required: true, message: '模版编码不能为空', trigger: 'blur' }], + templateParams: {} +}) +const formRef = ref() // 表单 Ref + +const open = async (id: number) => { + modelVisible.value = true + resetForm() + // 设置数据 + formLoading.value = true + try { + const data = await SmsTemplateApi.getSmsTemplate(id) + // 设置动态表单 + formData.value.content = data.content + formData.value.params = data.params + formData.value.templateCode = data.code + formData.value.templateParams = data.params.reduce((obj, item) => { + obj[item] = '' // 给每个动态属性赋值,避免无法读取 + return obj + }, {}) + formRules.templateParams = data.params.reduce((obj, item) => { + obj[item] = { required: true, message: '参数 ' + item + ' 不能为空', trigger: 'blur' } + return obj + }, {}) + } finally { + formLoading.value = false + } +} +defineExpose({ open }) // 提供 open 方法,用于打开弹窗 + +/** 提交表单 */ +const submitForm = async () => { + // 校验表单 + if (!formRef) return + const valid = await formRef.value.validate() + if (!valid) return + // 提交请求 + formLoading.value = true + try { + const data = formData.value as SmsTemplateApi.SendSmsReqVO + const logId = await SmsTemplateApi.sendSms(data) + if (logId) { + message.success('提交发送成功!发送结果,见发送日志编号:' + logId) + } + modelVisible.value = false + } finally { + formLoading.value = false + } +} + +/** 重置表单 */ +const resetForm = () => { + formData.value = { + content: '', + params: {}, + mobile: '', + templateCode: '', + templateParams: new Map() + } + formRef.value?.resetFields() +} +</script> diff --git a/src/views/system/sms/template/form.vue b/src/views/system/sms/template/form.vue deleted file mode 100644 index 4c9825f9..00000000 --- a/src/views/system/sms/template/form.vue +++ /dev/null @@ -1,267 +0,0 @@ -<template> - <Dialog :title="modelTitle" v-model="modelVisible"> - <!-- 修改/新增 --> - <el-form - v-if="['template.addTitle', 'template.updtaeTitle'].includes(formType)" - ref="formRef" - :model="formData" - :rules="formRules" - label-width="140px" - > - <el-form-item label="短信渠道编号" prop="channelId"> - <el-select v-model="formData.channelId" placeholder="请选择短信渠道编号"> - <el-option - v-for="channel in channelOptions" - :key="channel.id" - :value="channel.id" - :label=" - channel.signature + optionLabel(DICT_TYPE.SYSTEM_SMS_CHANNEL_CODE, channel.code) - " - /> - </el-select> - </el-form-item> - <el-form-item label="短信类型" prop="type"> - <el-select v-model="formData.type" placeholder="请选择短信类型"> - <el-option - v-for="dict in getDictOptions(DICT_TYPE.SYSTEM_SMS_TEMPLATE_TYPE)" - :key="dict.value" - :label="dict.label" - :value="parseInt(dict.value)" - /> - </el-select> - </el-form-item> - <el-form-item label="模板编号" prop="code"> - <el-input v-model="formData.code" placeholder="请输入模板编号" /> - </el-form-item> - <el-form-item label="模板名称" prop="name"> - <el-input v-model="formData.name" placeholder="请输入模板名称" /> - </el-form-item> - <el-form-item label="模板内容" prop="content"> - <el-input type="textarea" v-model="formData.content" placeholder="请输入模板内容" /> - </el-form-item> - <el-form-item label="开启状态" prop="status"> - <el-radio-group v-model="formData.status"> - <el-radio - v-for="dict in getDictOptions(DICT_TYPE.COMMON_STATUS)" - :key="dict.value" - :label="parseInt(dict.value)" - >{{ dict.label }}</el-radio - > - </el-radio-group> - </el-form-item> - <el-form-item label="短信 API 模板编号" prop="apiTemplateId"> - <el-input v-model="formData.apiTemplateId" placeholder="请输入短信 API 的模板编号" /> - </el-form-item> - <el-form-item label="备注" prop="remark"> - <el-input v-model="formData.remark" placeholder="请输入备注" /> - </el-form-item> - </el-form> - <!-- 短信测试 --> - <el-form - v-if="formType === 'template.sendSms'" - ref="sendSmsFormRef" - :model="sendSmsForm" - :rules="sendSmsRules" - > - <el-form-item label="模板内容" prop="content"> - <el-input - v-model="sendSmsForm.content" - type="textarea" - placeholder="请输入模板内容" - readonly - /> - </el-form-item> - <el-form-item label="手机号" prop="mobile"> - <el-input v-model="sendSmsForm.mobile" placeholder="请输入手机号" /> - </el-form-item> - <el-form-item - v-for="param in sendSmsForm.params" - :key="param" - :label="'参数 {' + param + '}'" - :prop="'templateParams.' + param" - > - <el-input - v-model="sendSmsForm.templateParams[param]" - :placeholder="'请输入 ' + param + ' 参数'" - /> - </el-form-item> - </el-form> - <template #footer> - <div class="dialog-footer"> - <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button> - <el-button @click="modelVisible = false">取 消</el-button> - </div> - </template> - </Dialog> -</template> -<script setup lang="ts" name="SmsTemplateFrom"> -import { DICT_TYPE, getDictOptions, getDictLabel } from '@/utils/dict' -import * as templateApi from '@/api/system/sms/smsTemplate' -import * as SmsChannelApi from '@/api/system/sms/smsChannel' -const { t } = useI18n() // 国际化 -const message = useMessage() // 消息弹窗 - -defineProps({ - channelOptions: { - type: Array as PropType<SmsChannelApi.SmsChannelListVO[]>, - define: () => {} - } -}) - -const modelVisible = ref(false) // 弹窗的是否展示 -const modelTitle = ref('') // 弹窗的标题 -const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用 -const formType = ref('') // 表单的类型 -const formData = ref<templateApi.SmsTemplateVO>({ - id: null, - type: null, - status: null, - code: '', - name: '', - content: '', - remark: '', - apiTemplateId: '', - channelId: null -}) -const formRules = reactive({ - type: [{ required: true, message: '短信类型不能为空', trigger: 'change' }], - status: [{ required: true, message: '开启状态不能为空', trigger: 'blur' }], - code: [{ required: true, message: '模板编码不能为空', trigger: 'blur' }], - name: [{ required: true, message: '模板名称不能为空', trigger: 'blur' }], - content: [{ required: true, message: '模板内容不能为空', trigger: 'blur' }], - apiTemplateId: [{ required: true, message: '短信 API 的模板编号不能为空', trigger: 'blur' }], - channelId: [{ required: true, message: '短信渠道编号不能为空', trigger: 'change' }] -}) - -const formRef = ref() // 表单 Ref -const optionLabel = computed( - () => (type: string, code: string) => `【${getDictLabel(type, code)}】` -) -// 发送短信表单相关 -const sendSmsForm = ref({ - content: '', - params: {}, - mobile: '', - templateCode: '', - templateParams: {} -}) -const sendSmsRules = reactive({ - mobile: [{ required: true, message: '手机不能为空', trigger: 'blur' }], - templateCode: [{ required: true, message: '模版编码不能为空', trigger: 'blur' }], - templateParams: {} -}) -const sendSmsFormRef = ref() -/** 打开弹窗 */ -interface openModalOption { - type: string - // 编辑传id - id?: '' - // 短信测试传row - row?: any -} -const openModal = async (option: openModalOption) => { - modelVisible.value = true - modelTitle.value = t('dialog.sms.' + option.type) - formType.value = option.type - resetForm() - resetSendSms() - // 短信测试 - if (option.row) { - sendSmsForm.value.content = option.row.content - sendSmsForm.value.params = option.row.params - sendSmsForm.value.templateCode = option.row.code - sendSmsForm.value.templateParams = option.row.params.reduce(function (obj, item) { - obj[item] = undefined - return obj - }, {}) - sendSmsRules.templateParams = option.row.params.reduce(function (obj, item) { - obj[item] = { required: true, message: '参数 ' + item + ' 不能为空', trigger: 'change' } - return obj - }, {}) - } - - // 修改时,设置数据 - if (option.id) { - formLoading.value = true - try { - formData.value = await templateApi.getSmsTemplateApi(option.id) - } finally { - formLoading.value = false - } - } -} -defineExpose({ openModal }) // 提供 openModal 方法,用于打开弹窗 - -const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调 -/** 提交表单 */ -const submitForm = async () => { - formLoading.value = true - // 提交请求 - if (['template.addTitle', 'template.updtaeTitle'].includes(formType.value)) { - // 校验表单 - if (!formRef) return - const valid = await formRef.value.validate() - if (!valid) return - try { - const data = formData.value as templateApi.SmsTemplateVO - if (formType.value === 'template.addTitle') { - await templateApi.createSmsTemplateApi(data) - message.success(t('common.createSuccess')) - } else { - await templateApi.updateSmsTemplateApi(data) - message.success(t('common.updateSuccess')) - } - modelVisible.value = false - // 发送操作成功的事件 - emit('success') - } finally { - formLoading.value = false - } - } - if (formType.value === 'template.sendSms') { - sendSmsTest() - } -} - -/** 重置表单 */ -const resetForm = () => { - formData.value = { - id: null, - type: null, - status: null, - code: '', - name: '', - content: '', - remark: '', - apiTemplateId: '', - channelId: null - } - formRef.value?.resetFields() -} -/** 重置发送短信的表单 */ -const resetSendSms = () => { - // 根据 row 重置表单 - sendSmsForm.value = { - content: '', - params: {}, - mobile: '', - templateCode: '', - templateParams: {} - } - sendSmsFormRef.value?.resetFields() -} -/** 发送短信 */ -const sendSmsTest = async () => { - const data: templateApi.SendSmsReqVO = { - mobile: sendSmsForm.value.mobile, - templateCode: sendSmsForm.value.templateCode, - templateParams: sendSmsForm.value.templateParams as unknown as Map<string, Object> - } - const res = await templateApi.sendSmsApi(data) - if (res) { - message.success('提交发送成功!发送结果,见发送日志编号:' + res) - } - formLoading.value = false - modelVisible.value = false -} -</script> diff --git a/src/views/system/sms/template/index.vue b/src/views/system/sms/template/index.vue index ffdd4240..85d84e88 100644 --- a/src/views/system/sms/template/index.vue +++ b/src/views/system/sms/template/index.vue @@ -1,17 +1,22 @@ <template> - <content-wrap> + <ContentWrap> <!-- 搜索工作栏 --> <el-form + class="-mb-15px" :model="queryParams" - ref="queryForm" + ref="queryFormRef" :inline="true" - v-show="showSearch" label-width="150px" > <el-form-item label="短信类型" prop="type"> - <el-select v-model="queryParams.type" placeholder="请选择短信类型" clearable> + <el-select + v-model="queryParams.type" + placeholder="请选择短信类型" + clearable + class="!w-240px" + > <el-option - v-for="dict in getDictOptions(DICT_TYPE.SYSTEM_SMS_TEMPLATE_TYPE)" + v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_SMS_TEMPLATE_TYPE)" :key="dict.value" :label="dict.label" :value="dict.value" @@ -19,9 +24,14 @@ </el-select> </el-form-item> <el-form-item label="开启状态" prop="status"> - <el-select v-model="queryParams.status" placeholder="请选择开启状态" clearable> + <el-select + v-model="queryParams.status" + placeholder="请选择开启状态" + clearable + class="!w-240px" + > <el-option - v-for="dict in getDictOptions(DICT_TYPE.COMMON_STATUS)" + v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)" :key="dict.value" :label="dict.label" :value="dict.value" @@ -34,6 +44,7 @@ placeholder="请输入模板编码" clearable @keyup.enter="handleQuery" + class="!w-240px" /> </el-form-item> <el-form-item label="短信 API 的模板编号" prop="apiTemplateId"> @@ -42,16 +53,23 @@ placeholder="请输入短信 API 的模板编号" clearable @keyup.enter="handleQuery" + class="!w-240px" /> </el-form-item> <el-form-item label="短信渠道" prop="channelId"> - <el-select v-model="queryParams.channelId" placeholder="请选择短信渠道" clearable> + <el-select + v-model="queryParams.channelId" + placeholder="请选择短信渠道" + clearable + class="!w-240px" + > <el-option - v-for="channel in channelOptions" + v-for="channel in channelList" :key="channel.id" :value="channel.id" :label=" - channel.signature + optionLabel(DICT_TYPE.SYSTEM_SMS_CHANNEL_CODE, channel.code) + channel.signature + + `【 ${getDictLabel(DICT_TYPE.SYSTEM_SMS_CHANNEL_CODE, channel.code)}】` " /> </el-select> @@ -64,47 +82,36 @@ value-format="YYYY-MM-DD HH:mm:ss" start-placeholder="开始日期" end-placeholder="结束日期" + class="!w-240px" /> </el-form-item> <el-form-item> - <el-button type="primary" @click="handleQuery" - ><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button - > + <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button> <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button> + <el-button + type="primary" + plain + @click="openForm('create')" + v-hasPermi="['system:sms-template:create']" + > + <Icon icon="ep:plus" class="mr-5px" />新增 + </el-button> + <el-button + type="success" + plain + @click="handleExport" + :loading="exportLoading" + v-hasPermi="['system:sms-template:export']" + > + <Icon icon="ep:download" class="mr-5px" /> 导出 + </el-button> </el-form-item> </el-form> - <!-- 操作工具栏 --> - <el-row class="mb-10px"> - <el-col :span="12"> - <el-row :gutter="10"> - <el-col :span="1.5"> - <el-button - type="primary" - plain - @click="handleAdd('template.addTitle')" - v-hasPermi="['system:sms-template:create']" - ><Icon icon="ep:plus" class="mr-5px" />新增</el-button - > - </el-col> - <el-col :span="1.5"> - <el-button - type="success" - plain - @click="handleExport" - :loading="exportLoading" - v-hasPermi="['system:sms-template:export']" - > - <Icon icon="ep:download" class="mr-5px" /> 导出 - </el-button> - </el-col> - </el-row> - </el-col> - <el-col :span="12"> - <right-toolbar v-model:showSearch="showSearch" @query-table="getList" /> - </el-col> - </el-row> - <!-- 列表 --> - <el-table v-loading="loading" :data="templateList" align="center"> + </ContentWrap> + + <!-- 列表 --> + <ContentWrap> + <el-table v-loading="loading" :data="list" align="center"> <el-table-column label="模板编码" align="center" @@ -146,7 +153,9 @@ /> <el-table-column label="短信渠道" align="center" width="120"> <template #default="scope"> - <div>{{ formatChannelSignature(scope.row.channelId) }}</div> + <div> + {{ channelList.find((channel) => channel.id === scope.row.channelId)?.signature }} + </div> <dict-tag :type="DICT_TYPE.SYSTEM_SMS_CHANNEL_CODE" :value="scope.row.channelCode" /> </template> </el-table-column> @@ -168,24 +177,27 @@ <el-button link type="primary" - @click="handleSendSms('template.sendSms', scope.row)" - v-hasPermi="['system:sms-template:send-sms']" - ><Icon icon="ep:share" class="mr-3px" />测试</el-button - > - <el-button - link - type="primary" - @click="handleUpdate('template.updtaeTitle', scope.row)" + @click="openForm('update', scope.row.id)" v-hasPermi="['system:sms-template:update']" - ><Icon icon="ep:edit" class="mr-3px" />修改</el-button > + 修改 + </el-button> <el-button link type="primary" - @click="handleDelete(scope.row)" - v-hasPermi="['system:sms-template:delete']" - ><Icon icon="ep:delete" class="mr-3px" />删除</el-button + @click="openSendForm(scope.row.id)" + v-hasPermi="['system:sms-template:send-sms']" > + 测试 + </el-button> + <el-button + link + type="danger" + @click="handleDelete(scope.row.id)" + v-hasPermi="['system:sms-template:delete']" + > + 删除 + </el-button> </template> </el-table-column> </el-table> @@ -196,33 +208,29 @@ v-model:limit="queryParams.pageSize" @pagination="getList" /> - </content-wrap> + </ContentWrap> <!-- 表单弹窗:添加/修改 --> - <SmsTemplateFrom ref="modalRef" :channelOptions="channelOptions" @success="getList" /> + <SmsTemplateForm ref="formRef" @success="getList" /> + <!-- 表单弹窗:测试发送 --> + <SmsTemplateSendForm ref="sendFormRef" /> </template> <script setup lang="ts" name="SmsTemplate"> -import { DICT_TYPE, getDictOptions, getDictLabel } from '@/utils/dict' +import { DICT_TYPE, getIntDictOptions, getDictLabel } from '@/utils/dict' import { dateFormatter } from '@/utils/formatTime' -import * as templateApi from '@/api/system/sms/smsTemplate' +import * as SmsTemplateApi from '@/api/system/sms/smsTemplate' import * as SmsChannelApi from '@/api/system/sms/smsChannel' import download from '@/utils/download' -import SmsTemplateFrom from './form.vue' +import SmsTemplateForm from './SmsTemplateForm.vue' +import SmsTemplateSendForm from './SmsTemplateSendForm.vue' const message = useMessage() // 消息弹窗 -// const { t } = useI18n() // 国际化 +const { t } = useI18n() // 国际化 -// 弹出层ref -const modalRef = ref() -// 遮罩层 -const loading = ref(true) -// 导出遮罩层 -// const exportLoading = ref(false) -// 显示搜索条件 -const showSearch = ref(true) -// 表单ref -const queryForm = ref() -// 查询参数 -const queryParams = ref<templateApi.SmsTemplatePageReqVO>({ +const loading = ref(false) // 列表的加载中 +const total = ref(0) // 列表的总页数 +const list = ref([]) // 列表的数据 +const queryFormRef = ref() // 搜索的表单 +const queryParams = reactive({ pageNo: 1, pageSize: 10, type: null, @@ -233,108 +241,77 @@ const queryParams = ref<templateApi.SmsTemplatePageReqVO>({ channelId: null, createTime: [] }) -// 总条数 -const total = ref(0) -// 短信模板列表 -const templateList = ref([]) +const exportLoading = ref(false) // 导出的加载中 +const channelList = ref([]) // 短信渠道列表 + /** 查询列表 */ -const getList = () => { +const getList = async () => { loading.value = true - // 执行查询 - templateApi.getSmsTemplatePageApi(queryParams.value).then((response) => { - templateList.value = response.list - total.value = response.total + try { + const data = await SmsTemplateApi.getSmsTemplatePage(queryParams) + list.value = data.list + total.value = data.total + } finally { loading.value = false - }) -} -/** 搜索按钮操作 */ -const handleQuery = () => { - queryParams.value.pageNo = 1 - getList() -} -/** 重置按钮操作 */ -const resetQuery = () => { - resetForm() - handleQuery() -} -/** 重置搜索表单 */ -const resetForm = () => { - queryParams.value = { - pageNo: 1, - pageSize: 10, - type: null, - status: null, - code: '', - content: '', - apiTemplateId: '', - channelId: null, - createTime: [] } - queryForm.value?.resetFields() -} -// 短信渠道 -const channelOptions = ref<SmsChannelApi.SmsChannelListVO[]>([]) -onMounted(() => { - SmsChannelApi.getSimpleSmsChannelList().then((res) => { - channelOptions.value = res - }) -}) -const optionLabel = computed( - () => (type: string, code: string) => `【${getDictLabel(type, code)}】` -) -/** 格式化短信渠道 */ -const formatChannelSignature = (channelId: number) => { - channelOptions.value.forEach((item) => { - if (item.id === channelId) { - return item.signature - } - }) - return '找不到签名:' + channelId -} -/** 新增按钮操作 */ -const handleAdd = (type: string) => { - modalRef.value.openModal({ type }) -} -/** 修改按钮操作 */ -// const handleUpdate = (row) => {} -const exportLoading = ref(false) -/** 导出按钮操作 */ -const handleExport = () => { - // 处理查询参数 - let params = { ...queryParams.value } as templateApi.SmsTemplateExportReqVO - // 执行导出 - message - .confirm('是否确认导出所有短信模板数据项?', '警告') - .then(() => { - exportLoading.value = true - return templateApi.exportPostApi(params) - }) - .then((response) => { - download.excel(response, '短信模板.xls') - exportLoading.value = false - }) - .catch(() => {}) -} -/** 发送短信按钮 */ -const handleSendSms = (type, row: any) => { - modalRef.value.openModal({ type, row }) -} -const handleUpdate = (type: string, { id }: { id: number }) => { - modalRef.value.openModal({ type, id }) -} -/** 删除按钮操作 */ -const handleDelete = ({ id }: { id: number }) => { - message - .confirm('是否确认删除短信模板编号为"' + id + '"的数据项?') - .then(function () { - return templateApi.deleteSmsTemplateApi(id) - }) - .then(() => { - getList() - message.success('删除成功') - }) - .catch(() => {}) } -getList() +/** 搜索按钮操作 */ +const handleQuery = () => { + queryParams.pageNo = 1 + getList() +} + +/** 重置按钮操作 */ +const resetQuery = () => { + queryFormRef.value.resetFields() + handleQuery() +} + +/** 添加/修改操作 */ +const formRef = ref() +const openForm = (type: string, id?: number) => { + formRef.value.open(type, id) +} + +/** 发送短信按钮 */ +const sendFormRef = ref() +const openSendForm = (id: number) => { + sendFormRef.value.open(id) +} + +/** 删除按钮操作 */ +const handleDelete = async (id: number) => { + try { + // 删除的二次确认 + await message.delConfirm() + // 发起删除 + await SmsTemplateApi.deleteSmsTemplate(id) + message.success(t('common.delSuccess')) + // 刷新列表 + await getList() + } catch {} +} + +/** 导出按钮操作 */ +const handleExport = async () => { + try { + // 导出的二次确认 + await message.exportConfirm() + // 发起导出 + exportLoading.value = true + const data = await SmsTemplateApi.exportSmsTemplate(queryParams) + download.excel(data, '短信模板.xls') + } catch { + } finally { + exportLoading.value = false + } +} + +/** 初始化 **/ +onMounted(async () => { + await getList() + // 加载渠道列表 + channelList.value = await SmsChannelApi.getSimpleSmsChannelList() +}) </script>