From 7e62f9a5ef99e6b4d865a738e296737020839c1f Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 30 May 2026 22:06:02 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20IoT=20=E5=91=8A?= =?UTF-8?q?=E8=AD=A6=E6=A8=A1=E6=9D=BF=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 后端 mail/sms/notify 模板 simple-list 仅返回启用模板精简字段 - 前端补充 mail/sms/notify 模板 simple-list API 封装 - vue3 与 vben antd/ele 在各自 system 模块封装模板选择组件 - IoT 告警配置按接收类型动态选择短信、邮件、站内信模板 - 补充前端 IotAlertReceiveTypeEnum,替换表单内裸常量 --- .../src/api/iot/alert/config/index.ts | 3 + .../src/api/system/mail/template/index.ts | 14 ++++ .../src/api/system/notify/template/index.ts | 14 ++++ .../src/api/system/sms/template/index.ts | 14 ++++ .../src/views/iot/alert/config/data.ts | 69 ++++++++++++++- .../system/mail/template/components/index.ts | 1 + .../mail/template/components/select.vue | 82 ++++++++++++++++++ .../notify/template/components/index.ts | 1 + .../notify/template/components/select.vue | 82 ++++++++++++++++++ .../system/sms/template/components/index.ts | 1 + .../system/sms/template/components/select.vue | 82 ++++++++++++++++++ .../web-ele/src/api/iot/alert/config/index.ts | 3 + .../src/api/system/mail/template/index.ts | 14 ++++ .../src/api/system/notify/template/index.ts | 14 ++++ .../src/api/system/sms/template/index.ts | 14 ++++ .../src/views/iot/alert/config/data.ts | 69 ++++++++++++++- .../system/mail/template/components/index.ts | 1 + .../mail/template/components/select.vue | 84 +++++++++++++++++++ .../notify/template/components/index.ts | 1 + .../notify/template/components/select.vue | 84 +++++++++++++++++++ .../system/sms/template/components/index.ts | 1 + .../system/sms/template/components/select.vue | 84 +++++++++++++++++++ packages/constants/src/biz-iot-enum.ts | 8 ++ 23 files changed, 738 insertions(+), 2 deletions(-) create mode 100644 apps/web-antd/src/views/system/mail/template/components/index.ts create mode 100644 apps/web-antd/src/views/system/mail/template/components/select.vue create mode 100644 apps/web-antd/src/views/system/notify/template/components/index.ts create mode 100644 apps/web-antd/src/views/system/notify/template/components/select.vue create mode 100644 apps/web-antd/src/views/system/sms/template/components/index.ts create mode 100644 apps/web-antd/src/views/system/sms/template/components/select.vue create mode 100644 apps/web-ele/src/views/system/mail/template/components/index.ts create mode 100644 apps/web-ele/src/views/system/mail/template/components/select.vue create mode 100644 apps/web-ele/src/views/system/notify/template/components/index.ts create mode 100644 apps/web-ele/src/views/system/notify/template/components/select.vue create mode 100644 apps/web-ele/src/views/system/sms/template/components/index.ts create mode 100644 apps/web-ele/src/views/system/sms/template/components/select.vue diff --git a/apps/web-antd/src/api/iot/alert/config/index.ts b/apps/web-antd/src/api/iot/alert/config/index.ts index d419a5563..a1d3bdfcc 100644 --- a/apps/web-antd/src/api/iot/alert/config/index.ts +++ b/apps/web-antd/src/api/iot/alert/config/index.ts @@ -14,6 +14,9 @@ export namespace AlertConfigApi { receiveUserIds?: number[]; receiveUserNames?: string[]; receiveTypes?: number[]; + smsTemplateCode?: string; + mailTemplateCode?: string; + notifyTemplateCode?: string; createTime?: Date; } } diff --git a/apps/web-antd/src/api/system/mail/template/index.ts b/apps/web-antd/src/api/system/mail/template/index.ts index 57f722cf5..fffd5d62b 100644 --- a/apps/web-antd/src/api/system/mail/template/index.ts +++ b/apps/web-antd/src/api/system/mail/template/index.ts @@ -17,6 +17,13 @@ export namespace SystemMailTemplateApi { createTime: Date; } + /** 邮件模版精简信息 */ + export interface MailTemplateSimple { + id: number; + name: string; + code: string; + } + /** 邮件发送信息 */ export interface MailSendReqVO { toMails: string[]; @@ -35,6 +42,13 @@ export function getMailTemplatePage(params: PageParam) { ); } +/** 查询邮件模版精简列表 */ +export function getSimpleMailTemplateList() { + return requestClient.get( + '/system/mail-template/simple-list', + ); +} + /** 查询邮件模版详情 */ export function getMailTemplate(id: number) { return requestClient.get( diff --git a/apps/web-antd/src/api/system/notify/template/index.ts b/apps/web-antd/src/api/system/notify/template/index.ts index dd19f4b8f..92c7d7bcc 100644 --- a/apps/web-antd/src/api/system/notify/template/index.ts +++ b/apps/web-antd/src/api/system/notify/template/index.ts @@ -16,6 +16,13 @@ export namespace SystemNotifyTemplateApi { remark: string; } + /** 站内信模板精简信息 */ + export interface NotifyTemplateSimple { + id: number; + name: string; + code: string; + } + /** 发送站内信请求 */ export interface NotifySendReqVO { userId: number; @@ -33,6 +40,13 @@ export function getNotifyTemplatePage(params: PageParam) { ); } +/** 查询站内信模板精简列表 */ +export function getSimpleNotifyTemplateList() { + return requestClient.get( + '/system/notify-template/simple-list', + ); +} + /** 查询站内信模板详情 */ export function getNotifyTemplate(id: number) { return requestClient.get( diff --git a/apps/web-antd/src/api/system/sms/template/index.ts b/apps/web-antd/src/api/system/sms/template/index.ts index eccfb911e..5cfc5ca9b 100644 --- a/apps/web-antd/src/api/system/sms/template/index.ts +++ b/apps/web-antd/src/api/system/sms/template/index.ts @@ -19,6 +19,13 @@ export namespace SystemSmsTemplateApi { createTime?: Date; } + /** 短信模板精简信息 */ + export interface SmsTemplateSimple { + id: number; + name: string; + code: string; + } + /** 发送短信请求 */ export interface SmsSendReqVO { mobile: string; @@ -35,6 +42,13 @@ export function getSmsTemplatePage(params: PageParam) { ); } +/** 查询短信模板精简列表 */ +export function getSimpleSmsTemplateList() { + return requestClient.get( + '/system/sms-template/simple-list', + ); +} + /** 查询短信模板详情 */ export function getSmsTemplate(id: number) { return requestClient.get( diff --git a/apps/web-antd/src/views/iot/alert/config/data.ts b/apps/web-antd/src/views/iot/alert/config/data.ts index 063de59b8..86dab96cc 100644 --- a/apps/web-antd/src/views/iot/alert/config/data.ts +++ b/apps/web-antd/src/views/iot/alert/config/data.ts @@ -2,12 +2,25 @@ import type { VbenFormSchema } from '#/adapter/form'; import type { VxeTableGridOptions } from '#/adapter/vxe-table'; import type { AlertConfigApi } from '#/api/iot/alert/config'; -import { CommonStatusEnum, DICT_TYPE } from '@vben/constants'; +import { markRaw } from 'vue'; + +import { + CommonStatusEnum, + DICT_TYPE, + IotAlertReceiveTypeEnum, +} from '@vben/constants'; import { getDictOptions } from '@vben/hooks'; import { getSimpleRuleSceneList } from '#/api/iot/rule/scene'; import { getSimpleUserList } from '#/api/system/user'; import { getRangePickerDefaultProps } from '#/utils'; +import { MailTemplateSelect } from '#/views/system/mail/template/components'; +import { NotifyTemplateSelect } from '#/views/system/notify/template/components'; +import { SmsTemplateSelect } from '#/views/system/sms/template/components'; + +function hasReceiveType(values: Partial>, type: number) { + return Array.isArray(values.receiveTypes) && values.receiveTypes.includes(type); +} /** 新增/修改告警配置的表单 */ export function useFormSchema(): VbenFormSchema[] { @@ -100,6 +113,60 @@ export function useFormSchema(): VbenFormSchema[] { defaultValue: [], rules: 'required', }, + { + fieldName: 'smsTemplateCode', + label: '短信模板', + component: markRaw(SmsTemplateSelect), + dependencies: { + triggerFields: ['receiveTypes'], + show: (values) => hasReceiveType(values, IotAlertReceiveTypeEnum.SMS), + trigger: async (values, formApi) => { + if ( + !hasReceiveType(values, IotAlertReceiveTypeEnum.SMS) && + values.smsTemplateCode + ) { + await formApi.setFieldValue('smsTemplateCode', undefined); + } + }, + }, + rules: 'selectRequired', + }, + { + fieldName: 'mailTemplateCode', + label: '邮件模板', + component: markRaw(MailTemplateSelect), + dependencies: { + triggerFields: ['receiveTypes'], + show: (values) => hasReceiveType(values, IotAlertReceiveTypeEnum.MAIL), + trigger: async (values, formApi) => { + if ( + !hasReceiveType(values, IotAlertReceiveTypeEnum.MAIL) && + values.mailTemplateCode + ) { + await formApi.setFieldValue('mailTemplateCode', undefined); + } + }, + }, + rules: 'selectRequired', + }, + { + fieldName: 'notifyTemplateCode', + label: '站内信模板', + component: markRaw(NotifyTemplateSelect), + dependencies: { + triggerFields: ['receiveTypes'], + show: (values) => hasReceiveType(values, IotAlertReceiveTypeEnum.NOTIFY), + trigger: async (values, formApi) => { + if ( + !hasReceiveType(values, IotAlertReceiveTypeEnum.NOTIFY) && + values.notifyTemplateCode + ) { + await formApi.setFieldValue('notifyTemplateCode', undefined); + } + }, + }, + rules: 'selectRequired', + }, ]; } diff --git a/apps/web-antd/src/views/system/mail/template/components/index.ts b/apps/web-antd/src/views/system/mail/template/components/index.ts new file mode 100644 index 000000000..4acfb35e7 --- /dev/null +++ b/apps/web-antd/src/views/system/mail/template/components/index.ts @@ -0,0 +1 @@ +export { default as MailTemplateSelect } from './select.vue'; diff --git a/apps/web-antd/src/views/system/mail/template/components/select.vue b/apps/web-antd/src/views/system/mail/template/components/select.vue new file mode 100644 index 000000000..2bdab7dcc --- /dev/null +++ b/apps/web-antd/src/views/system/mail/template/components/select.vue @@ -0,0 +1,82 @@ + + + diff --git a/apps/web-antd/src/views/system/notify/template/components/index.ts b/apps/web-antd/src/views/system/notify/template/components/index.ts new file mode 100644 index 000000000..42715dfa6 --- /dev/null +++ b/apps/web-antd/src/views/system/notify/template/components/index.ts @@ -0,0 +1 @@ +export { default as NotifyTemplateSelect } from './select.vue'; diff --git a/apps/web-antd/src/views/system/notify/template/components/select.vue b/apps/web-antd/src/views/system/notify/template/components/select.vue new file mode 100644 index 000000000..7dbe59290 --- /dev/null +++ b/apps/web-antd/src/views/system/notify/template/components/select.vue @@ -0,0 +1,82 @@ + + + diff --git a/apps/web-antd/src/views/system/sms/template/components/index.ts b/apps/web-antd/src/views/system/sms/template/components/index.ts new file mode 100644 index 000000000..0b1f9ad98 --- /dev/null +++ b/apps/web-antd/src/views/system/sms/template/components/index.ts @@ -0,0 +1 @@ +export { default as SmsTemplateSelect } from './select.vue'; diff --git a/apps/web-antd/src/views/system/sms/template/components/select.vue b/apps/web-antd/src/views/system/sms/template/components/select.vue new file mode 100644 index 000000000..188536173 --- /dev/null +++ b/apps/web-antd/src/views/system/sms/template/components/select.vue @@ -0,0 +1,82 @@ + + + diff --git a/apps/web-ele/src/api/iot/alert/config/index.ts b/apps/web-ele/src/api/iot/alert/config/index.ts index d419a5563..a1d3bdfcc 100644 --- a/apps/web-ele/src/api/iot/alert/config/index.ts +++ b/apps/web-ele/src/api/iot/alert/config/index.ts @@ -14,6 +14,9 @@ export namespace AlertConfigApi { receiveUserIds?: number[]; receiveUserNames?: string[]; receiveTypes?: number[]; + smsTemplateCode?: string; + mailTemplateCode?: string; + notifyTemplateCode?: string; createTime?: Date; } } diff --git a/apps/web-ele/src/api/system/mail/template/index.ts b/apps/web-ele/src/api/system/mail/template/index.ts index 57f722cf5..fffd5d62b 100644 --- a/apps/web-ele/src/api/system/mail/template/index.ts +++ b/apps/web-ele/src/api/system/mail/template/index.ts @@ -17,6 +17,13 @@ export namespace SystemMailTemplateApi { createTime: Date; } + /** 邮件模版精简信息 */ + export interface MailTemplateSimple { + id: number; + name: string; + code: string; + } + /** 邮件发送信息 */ export interface MailSendReqVO { toMails: string[]; @@ -35,6 +42,13 @@ export function getMailTemplatePage(params: PageParam) { ); } +/** 查询邮件模版精简列表 */ +export function getSimpleMailTemplateList() { + return requestClient.get( + '/system/mail-template/simple-list', + ); +} + /** 查询邮件模版详情 */ export function getMailTemplate(id: number) { return requestClient.get( diff --git a/apps/web-ele/src/api/system/notify/template/index.ts b/apps/web-ele/src/api/system/notify/template/index.ts index dd19f4b8f..92c7d7bcc 100644 --- a/apps/web-ele/src/api/system/notify/template/index.ts +++ b/apps/web-ele/src/api/system/notify/template/index.ts @@ -16,6 +16,13 @@ export namespace SystemNotifyTemplateApi { remark: string; } + /** 站内信模板精简信息 */ + export interface NotifyTemplateSimple { + id: number; + name: string; + code: string; + } + /** 发送站内信请求 */ export interface NotifySendReqVO { userId: number; @@ -33,6 +40,13 @@ export function getNotifyTemplatePage(params: PageParam) { ); } +/** 查询站内信模板精简列表 */ +export function getSimpleNotifyTemplateList() { + return requestClient.get( + '/system/notify-template/simple-list', + ); +} + /** 查询站内信模板详情 */ export function getNotifyTemplate(id: number) { return requestClient.get( diff --git a/apps/web-ele/src/api/system/sms/template/index.ts b/apps/web-ele/src/api/system/sms/template/index.ts index eccfb911e..5cfc5ca9b 100644 --- a/apps/web-ele/src/api/system/sms/template/index.ts +++ b/apps/web-ele/src/api/system/sms/template/index.ts @@ -19,6 +19,13 @@ export namespace SystemSmsTemplateApi { createTime?: Date; } + /** 短信模板精简信息 */ + export interface SmsTemplateSimple { + id: number; + name: string; + code: string; + } + /** 发送短信请求 */ export interface SmsSendReqVO { mobile: string; @@ -35,6 +42,13 @@ export function getSmsTemplatePage(params: PageParam) { ); } +/** 查询短信模板精简列表 */ +export function getSimpleSmsTemplateList() { + return requestClient.get( + '/system/sms-template/simple-list', + ); +} + /** 查询短信模板详情 */ export function getSmsTemplate(id: number) { return requestClient.get( diff --git a/apps/web-ele/src/views/iot/alert/config/data.ts b/apps/web-ele/src/views/iot/alert/config/data.ts index 7508f4471..ec8a5a576 100644 --- a/apps/web-ele/src/views/iot/alert/config/data.ts +++ b/apps/web-ele/src/views/iot/alert/config/data.ts @@ -2,12 +2,25 @@ import type { VbenFormSchema } from '#/adapter/form'; import type { VxeTableGridOptions } from '#/adapter/vxe-table'; import type { AlertConfigApi } from '#/api/iot/alert/config'; -import { CommonStatusEnum, DICT_TYPE } from '@vben/constants'; +import { markRaw } from 'vue'; + +import { + CommonStatusEnum, + DICT_TYPE, + IotAlertReceiveTypeEnum, +} from '@vben/constants'; import { getDictOptions } from '@vben/hooks'; import { getSimpleRuleSceneList } from '#/api/iot/rule/scene'; import { getSimpleUserList } from '#/api/system/user'; import { getRangePickerDefaultProps } from '#/utils'; +import { MailTemplateSelect } from '#/views/system/mail/template/components'; +import { NotifyTemplateSelect } from '#/views/system/notify/template/components'; +import { SmsTemplateSelect } from '#/views/system/sms/template/components'; + +function hasReceiveType(values: Partial>, type: number) { + return Array.isArray(values.receiveTypes) && values.receiveTypes.includes(type); +} /** 新增/修改告警配置的表单 */ export function useFormSchema(): VbenFormSchema[] { @@ -98,6 +111,60 @@ export function useFormSchema(): VbenFormSchema[] { defaultValue: [], rules: 'required', }, + { + fieldName: 'smsTemplateCode', + label: '短信模板', + component: markRaw(SmsTemplateSelect), + dependencies: { + triggerFields: ['receiveTypes'], + show: (values) => hasReceiveType(values, IotAlertReceiveTypeEnum.SMS), + trigger: async (values, formApi) => { + if ( + !hasReceiveType(values, IotAlertReceiveTypeEnum.SMS) && + values.smsTemplateCode + ) { + formApi.setFieldValue('smsTemplateCode', undefined); + } + }, + }, + rules: 'selectRequired', + }, + { + fieldName: 'mailTemplateCode', + label: '邮件模板', + component: markRaw(MailTemplateSelect), + dependencies: { + triggerFields: ['receiveTypes'], + show: (values) => hasReceiveType(values, IotAlertReceiveTypeEnum.MAIL), + trigger: async (values, formApi) => { + if ( + !hasReceiveType(values, IotAlertReceiveTypeEnum.MAIL) && + values.mailTemplateCode + ) { + formApi.setFieldValue('mailTemplateCode', undefined); + } + }, + }, + rules: 'selectRequired', + }, + { + fieldName: 'notifyTemplateCode', + label: '站内信模板', + component: markRaw(NotifyTemplateSelect), + dependencies: { + triggerFields: ['receiveTypes'], + show: (values) => hasReceiveType(values, IotAlertReceiveTypeEnum.NOTIFY), + trigger: async (values, formApi) => { + if ( + !hasReceiveType(values, IotAlertReceiveTypeEnum.NOTIFY) && + values.notifyTemplateCode + ) { + formApi.setFieldValue('notifyTemplateCode', undefined); + } + }, + }, + rules: 'selectRequired', + }, ]; } diff --git a/apps/web-ele/src/views/system/mail/template/components/index.ts b/apps/web-ele/src/views/system/mail/template/components/index.ts new file mode 100644 index 000000000..4acfb35e7 --- /dev/null +++ b/apps/web-ele/src/views/system/mail/template/components/index.ts @@ -0,0 +1 @@ +export { default as MailTemplateSelect } from './select.vue'; diff --git a/apps/web-ele/src/views/system/mail/template/components/select.vue b/apps/web-ele/src/views/system/mail/template/components/select.vue new file mode 100644 index 000000000..d99a29f2e --- /dev/null +++ b/apps/web-ele/src/views/system/mail/template/components/select.vue @@ -0,0 +1,84 @@ + + + diff --git a/apps/web-ele/src/views/system/notify/template/components/index.ts b/apps/web-ele/src/views/system/notify/template/components/index.ts new file mode 100644 index 000000000..42715dfa6 --- /dev/null +++ b/apps/web-ele/src/views/system/notify/template/components/index.ts @@ -0,0 +1 @@ +export { default as NotifyTemplateSelect } from './select.vue'; diff --git a/apps/web-ele/src/views/system/notify/template/components/select.vue b/apps/web-ele/src/views/system/notify/template/components/select.vue new file mode 100644 index 000000000..22bd8aa89 --- /dev/null +++ b/apps/web-ele/src/views/system/notify/template/components/select.vue @@ -0,0 +1,84 @@ + + + diff --git a/apps/web-ele/src/views/system/sms/template/components/index.ts b/apps/web-ele/src/views/system/sms/template/components/index.ts new file mode 100644 index 000000000..0b1f9ad98 --- /dev/null +++ b/apps/web-ele/src/views/system/sms/template/components/index.ts @@ -0,0 +1 @@ +export { default as SmsTemplateSelect } from './select.vue'; diff --git a/apps/web-ele/src/views/system/sms/template/components/select.vue b/apps/web-ele/src/views/system/sms/template/components/select.vue new file mode 100644 index 000000000..23a8e5fb9 --- /dev/null +++ b/apps/web-ele/src/views/system/sms/template/components/select.vue @@ -0,0 +1,84 @@ + + + diff --git a/packages/constants/src/biz-iot-enum.ts b/packages/constants/src/biz-iot-enum.ts index 5275bc9da..b7ca4b895 100644 --- a/packages/constants/src/biz-iot-enum.ts +++ b/packages/constants/src/biz-iot-enum.ts @@ -85,6 +85,14 @@ export const CodecTypeEnum = { ALINK: 'Alink', // 阿里云 Alink 协议 } as const; +// ========== IOT - 告警模块 ========== +/** IoT 告警接收方式枚举,与后端 IotAlertReceiveTypeEnum 保持一致 */ +export const IotAlertReceiveTypeEnum = { + SMS: 1, // 短信 + MAIL: 2, // 邮箱 + NOTIFY: 3, // 站内信 +} as const; + // ========== IOT - 物模型 ========== /** IoT 产品物模型类型枚举类 */ export const IoTThingModelTypeEnum = {