feat: send sms
							parent
							
								
									3548ba004c
								
							
						
					
					
						commit
						2b8e4c6de5
					
				|  | @ -18,7 +18,9 @@ export interface SmsTemplateVO { | ||||||
| export interface SendSmsReqVO { | export interface SendSmsReqVO { | ||||||
|   mobile: string |   mobile: string | ||||||
|   templateCode: string |   templateCode: string | ||||||
|   templateParams: Map<String, Object> |   templateParams: { | ||||||
|  |     [key: string]: any | ||||||
|  |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export interface SmsTemplatePageReqVO { | export interface SmsTemplatePageReqVO { | ||||||
|  | @ -66,6 +68,21 @@ export function deleteSmsTemplate(id: number) { | ||||||
|   return defHttp.delete({ url: '/system/sms-template/delete?id=' + id }) |   return defHttp.delete({ url: '/system/sms-template/delete?id=' + id }) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // 邮件模板
 | ||||||
|  | export type SmsTemplate = { | ||||||
|  |   name: string // 标题
 | ||||||
|  |   code: string // 编码
 | ||||||
|  |   accountId: number | ||||||
|  |   nickname: string // 发送人
 | ||||||
|  |   title: string // 标题
 | ||||||
|  |   content: string // 内容
 | ||||||
|  |   status: number //
 | ||||||
|  |   remark?: any // 备注
 | ||||||
|  |   id: number | ||||||
|  |   params: string[] // 模板里的参数
 | ||||||
|  |   createTime: number | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // 发送短信
 | // 发送短信
 | ||||||
| export function sendSms(data: SendSmsReqVO) { | export function sendSms(data: SendSmsReqVO) { | ||||||
|   return defHttp.post({ url: '/system/sms-template/send-sms', data }) |   return defHttp.post({ url: '/system/sms-template/send-sms', data }) | ||||||
|  |  | ||||||
|  | @ -21,7 +21,6 @@ const templateCode = ref<string>('') | ||||||
| 
 | 
 | ||||||
| const [register, { setFieldsValue, getFieldsValue, validateFields, resetFields, clearValidate, setProps }] = useForm({ | const [register, { setFieldsValue, getFieldsValue, validateFields, resetFields, clearValidate, setProps }] = useForm({ | ||||||
|   labelWidth: 100, |   labelWidth: 100, | ||||||
|   // schemas: reactiveSchemas, 这里用动态绑定会有问题 |  | ||||||
|   baseColProps: { |   baseColProps: { | ||||||
|     span: 24 |     span: 24 | ||||||
|   }, |   }, | ||||||
|  |  | ||||||
|  | @ -58,7 +58,7 @@ defineOptions({ name: 'SystemMailTemplate' }) | ||||||
| const { t } = useI18n() | const { t } = useI18n() | ||||||
| const { createMessage } = useMessage() | const { createMessage } = useMessage() | ||||||
| const [registerTemplateModal, { openModal }] = useModal() | const [registerTemplateModal, { openModal }] = useModal() | ||||||
| const [registerSendModal, { openModal: openSenModal }] = useModal() | const [registerSendModal, { openModal: openSendModal }] = useModal() | ||||||
| const [registerTable, { reload }] = useTable({ | const [registerTable, { reload }] = useTable({ | ||||||
|   title: '邮件模板列表', |   title: '邮件模板列表', | ||||||
|   api: getMailTemplatePage, |   api: getMailTemplatePage, | ||||||
|  | @ -80,7 +80,7 @@ function handleCreate() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function handleSend(record: Recordable) { | function handleSend(record: Recordable) { | ||||||
|   openSenModal(true, record) |   openSendModal(true, record) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function handleEdit(record: Recordable) { | function handleEdit(record: Recordable) { | ||||||
|  |  | ||||||
|  | @ -22,7 +22,6 @@ export const infoSchema: DescItem[] = [ | ||||||
|     field: 'userType', |     field: 'userType', | ||||||
|     label: '用户类型', |     label: '用户类型', | ||||||
|     render: (value) => { |     render: (value) => { | ||||||
|       console.log(value) |  | ||||||
|       return useRender.renderDict(value, DICT_TYPE.USER_TYPE) |       return useRender.renderDict(value, DICT_TYPE.USER_TYPE) | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|  |  | ||||||
|  | @ -129,7 +129,6 @@ export const infoSchema: DescItem[] = [ | ||||||
|     field: 'userType', |     field: 'userType', | ||||||
|     label: '用户类型', |     label: '用户类型', | ||||||
|     render: (value) => { |     render: (value) => { | ||||||
|       console.log(value) |  | ||||||
|       return useRender.renderDict(value, DICT_TYPE.USER_TYPE) |       return useRender.renderDict(value, DICT_TYPE.USER_TYPE) | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|  |  | ||||||
|  | @ -20,7 +20,6 @@ const templateCode = ref<string>('') | ||||||
| 
 | 
 | ||||||
| const [register, { setFieldsValue, getFieldsValue, validateFields, resetFields, clearValidate, setProps }] = useForm({ | const [register, { setFieldsValue, getFieldsValue, validateFields, resetFields, clearValidate, setProps }] = useForm({ | ||||||
|   labelWidth: 100, |   labelWidth: 100, | ||||||
|   // schemas: reactiveSchemas, 这里用动态绑定会有问题 |  | ||||||
|   baseColProps: { |   baseColProps: { | ||||||
|     span: 24 |     span: 24 | ||||||
|   }, |   }, | ||||||
|  |  | ||||||
|  | @ -0,0 +1,88 @@ | ||||||
|  | <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 { SmsTemplateVO, sendSms } from '@/api/system/sms/smsTemplate' | ||||||
|  | import { useMessage } from '@/hooks/web/useMessage' | ||||||
|  | import { baseSendSchemas } from './smsTemplate.data' | ||||||
|  | 
 | ||||||
|  | defineOptions({ name: 'SendSmsModal' }) | ||||||
|  | 
 | ||||||
|  | const { createMessage } = useMessage() | ||||||
|  | let reactiveSchemas: FormSchema[] = reactive([]) | ||||||
|  | const templateCode = ref<string>('') | ||||||
|  | 
 | ||||||
|  | const [register, { setFieldsValue, getFieldsValue, validateFields, resetFields, clearValidate, setProps }] = useForm({ | ||||||
|  |   labelWidth: 100, | ||||||
|  |   baseColProps: { | ||||||
|  |     span: 24 | ||||||
|  |   }, | ||||||
|  |   showSubmitButton: false, | ||||||
|  |   showResetButton: false | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | const [innerRegister, { changeLoading, closeModal }] = useModalInner((data: SmsTemplateVO) => { | ||||||
|  |   resetForm() | ||||||
|  |   data.params.forEach((item) => { | ||||||
|  |     const dySchema: FormSchema = { | ||||||
|  |       // 这里加上前缀 防止content/mobile和字段重名 | ||||||
|  |       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 = { | ||||||
|  |       mobile: fields.mobile, | ||||||
|  |       templateCode: templateCode.value, | ||||||
|  |       templateParams: {} | ||||||
|  |     } | ||||||
|  |     Object.keys(fields).forEach((key) => { | ||||||
|  |       if (key === 'content' || key === 'mobile') { | ||||||
|  |         return | ||||||
|  |       } | ||||||
|  |       // 去掉 - 后的key | ||||||
|  |       const realKey = key.split('-')[1] | ||||||
|  |       data.templateParams[realKey] = fields[key] | ||||||
|  |     }) | ||||||
|  |     await sendSms(data) | ||||||
|  |     createMessage.success(`发送短信到[${fields.mobile}]成功`) | ||||||
|  |     closeModal() | ||||||
|  |   } finally { | ||||||
|  |     setProps({ disabled: false }) | ||||||
|  |     changeLoading(false) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const resetForm = () => { | ||||||
|  |   // 这里需要每次清空动态表单 | ||||||
|  |   reactiveSchemas.splice(0, reactiveSchemas.length) | ||||||
|  |   reactiveSchemas.push(...baseSendSchemas) | ||||||
|  |   // 清除上一次的表单校验和参数 | ||||||
|  |   resetFields() | ||||||
|  |   clearValidate() | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <style scoped></style> | ||||||
|  | @ -37,6 +37,7 @@ | ||||||
|       </template> |       </template> | ||||||
|     </BasicTable> |     </BasicTable> | ||||||
|     <SmsTemplateModal @register="registerModal" @success="reload()" /> |     <SmsTemplateModal @register="registerModal" @success="reload()" /> | ||||||
|  |     <SendSmsModal @register="registerSendModal" /> | ||||||
|   </div> |   </div> | ||||||
| </template> | </template> | ||||||
| <script lang="ts" setup> | <script lang="ts" setup> | ||||||
|  | @ -45,6 +46,7 @@ import { SmsTemplateExportReqVO, deleteSmsTemplate, exportSmsTemplate, getSmsTem | ||||||
| import { useModal } from '@/components/Modal' | import { useModal } from '@/components/Modal' | ||||||
| import { IconEnum } from '@/enums/appEnum' | import { IconEnum } from '@/enums/appEnum' | ||||||
| import SmsTemplateModal from './SmsTemplateModal.vue' | import SmsTemplateModal from './SmsTemplateModal.vue' | ||||||
|  | import SendSmsModal from './SendSmsModal.vue' | ||||||
| import { columns, searchFormSchema } from './smsTemplate.data' | import { columns, searchFormSchema } from './smsTemplate.data' | ||||||
| import { useI18n } from '@/hooks/web/useI18n' | import { useI18n } from '@/hooks/web/useI18n' | ||||||
| import { useMessage } from '@/hooks/web/useMessage' | import { useMessage } from '@/hooks/web/useMessage' | ||||||
|  | @ -54,6 +56,7 @@ defineOptions({ name: 'SystemSmsTemplate' }) | ||||||
| const { t } = useI18n() | const { t } = useI18n() | ||||||
| const { createConfirm, createMessage } = useMessage() | const { createConfirm, createMessage } = useMessage() | ||||||
| const [registerModal, { openModal }] = useModal() | const [registerModal, { openModal }] = useModal() | ||||||
|  | const [registerSendModal, { openModal: openSendModal }] = useModal() | ||||||
| const [registerTable, { getForm, reload }] = useTable({ | const [registerTable, { getForm, reload }] = useTable({ | ||||||
|   title: '短信模版列表', |   title: '短信模版列表', | ||||||
|   api: getSmsTemplatePage, |   api: getSmsTemplatePage, | ||||||
|  | @ -75,7 +78,7 @@ function handleCreate() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function handleSendSms(record: Recordable) { | function handleSendSms(record: Recordable) { | ||||||
|   console.info(record) |   openSendModal(true, record) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function handleEdit(record: Recordable) { | function handleEdit(record: Recordable) { | ||||||
|  |  | ||||||
|  | @ -168,3 +168,28 @@ export const formSchema: FormSchema[] = [ | ||||||
|     component: 'InputTextArea' |     component: 'InputTextArea' | ||||||
|   } |   } | ||||||
| ] | ] | ||||||
|  | 
 | ||||||
|  | // 发送短信
 | ||||||
|  | export const baseSendSchemas: FormSchema[] = [ | ||||||
|  |   { | ||||||
|  |     field: 'content', | ||||||
|  |     component: 'Editor', | ||||||
|  |     label: '模板内容 ', | ||||||
|  |     required: false, | ||||||
|  |     defaultValue: '', | ||||||
|  |     componentProps: { | ||||||
|  |       options: { | ||||||
|  |         readonly: true | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     field: 'mobile', | ||||||
|  |     label: '手机号 ', | ||||||
|  |     component: 'Input', | ||||||
|  |     componentProps: { | ||||||
|  |       placeholder: '请输入手机号' | ||||||
|  |     }, | ||||||
|  |     required: true | ||||||
|  |   } | ||||||
|  | ] | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 xingyu
						xingyu