Commit 09e61f7ef342db5c0a85c977338ab711524bc673

Authored by xingyu
1 parent 12ac097b

refactor: sms

yudao-ui-admin-vue3/src/api/system/sms/smsChannel/index.ts
1 1 import request from '@/config/axios'
2   -import type { SmsChannelVO } from './types'
  2 +export type SmsChannelVO = {
  3 + id: number
  4 + status: number
  5 + signature: string
  6 + remark: string
  7 + apiKey: string
  8 + apiSecret: string
  9 + callbackUrl: string
  10 + createTime: string
  11 +}
  12 +
  13 +export interface SmsChannelPageReqVO extends PageParam {
  14 + signature?: string
  15 + code?: string
  16 + status?: number
  17 +}
3 18  
4 19 // 查询短信渠道列表
5   -export const getSmsChannelPageApi = (params) => {
  20 +export const getSmsChannelPageApi = (params: SmsChannelPageReqVO) => {
6 21 return request.get({ url: '/system/sms-channel/page', params })
7 22 }
8 23  
... ...
yudao-ui-admin-vue3/src/api/system/sms/smsChannel/types.ts deleted
1   -export type SmsChannelVO = {
2   - id: number
3   - status: number
4   - signature: string
5   - remark: string
6   - apiKey: string
7   - apiSecret: string
8   - callbackUrl: string
9   - createTime: string
10   -}
yudao-ui-admin-vue3/src/api/system/sms/smsLog/index.ts
1 1 import request from '@/config/axios'
  2 +export type SmsLogVO = {
  3 + id: number
  4 + idchannelId: number
  5 + templateId: number
  6 + mobile: string
  7 + userId: number
  8 + userType: number
  9 + sendStatus: number
  10 + receiveStatus: number
  11 + templateType: number
  12 + templateContent: string
  13 + templateParams: Map<string, object>
  14 + apiTemplateId: string
  15 + sendTime: string
  16 + createTime: string
  17 +}
  18 +
  19 +export interface SmsLogPageReqVO extends PageParam {
  20 + signature?: string
  21 + code?: string
  22 + status?: number
  23 +}
  24 +export interface SmsLogExportReqVO {
  25 + code?: string
  26 + name?: string
  27 + status?: number
  28 +}
2 29  
3 30 // 查询短信日志列表
4   -export const getSmsLogPageApi = (params) => {
  31 +export const getSmsLogPageApi = (params: SmsLogPageReqVO) => {
5 32 return request.get({ url: '/system/sms-log/page', params })
6 33 }
7 34  
8 35 // 导出短信日志
9   -export const exportSmsLogApi = (params) => {
  36 +export const exportSmsLogApi = (params: SmsLogExportReqVO) => {
10 37 return request.download({ url: '/system/sms-log/export', params })
11 38 }
... ...
yudao-ui-admin-vue3/src/api/system/sms/smsLog/types.ts deleted
1   -export type SmsLogVO = {
2   - id: number
3   - idchannelId: number
4   - templateId: number
5   - mobile: string
6   - sendStatus: number
7   - receiveStatus: number
8   - createTime: string
9   -}
yudao-ui-admin-vue3/src/api/system/sms/smsTemplate/index.ts
1 1 import request from '@/config/axios'
2   -import type { SmsTemplateVO } from './types'
  2 +export type SmsTemplateVO = {
  3 + id: number
  4 + type: number
  5 + status: number
  6 + code: string
  7 + name: string
  8 + content: string
  9 + remark: string
  10 + apiTemplateId: string
  11 + channelId: number
  12 + channelCode: string
  13 + createTime: string
  14 +}
  15 +
  16 +export type SmsSendVO = {
  17 + mobile: string
  18 + templateCode: string
  19 + templateParams: string
  20 +}
3 21  
4 22 // 查询短信模板列表
5 23 export const getSmsTemplatePageApi = (params) => {
... ...
yudao-ui-admin-vue3/src/api/system/sms/smsTemplate/types.ts deleted
1   -export type SmsTemplateVO = {
2   - id: number
3   - type: number
4   - status: number
5   - code: string
6   - name: string
7   - content: string
8   - remark: string
9   - apiTemplateId: string
10   - channelId: number
11   - channelCode: string
12   - createTime: string
13   -}
14   -
15   -export type SmsSendVO = {
16   - mobile: string
17   - templateCode: string
18   - templateParams: string
19   -}
yudao-ui-admin-vue3/src/views/system/sms/smsChannel/index.vue
1 1 <template>
2   - <!-- 搜索工作区 -->
3 2 <ContentWrap>
4   - <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
5   - </ContentWrap>
6   - <ContentWrap>
7   - <!-- 操作工具栏 -->
8   - <div class="mb-10px">
9   - <XButton
10   - type="primary"
11   - preIcon="ep:zoom-in"
12   - :title="t('action.add')"
13   - v-hasPermi="['system:sms-channel:create']"
14   - @click="handleCreate()"
15   - />
16   - </div>
17 3 <!-- 列表 -->
18   - <Table
19   - :columns="allSchemas.tableColumns"
20   - :selection="false"
21   - :data="tableObject.tableList"
22   - :loading="tableObject.loading"
23   - :pagination="{
24   - total: tableObject.total
25   - }"
26   - v-model:pageSize="tableObject.pageSize"
27   - v-model:currentPage="tableObject.currentPage"
28   - @register="register"
29   - >
30   - <template #code="{ row }">
31   - <DictTag :type="DICT_TYPE.SYSTEM_SMS_CHANNEL_CODE" :value="row.code" />
32   - </template>
33   - <template #status="{ row }">
34   - <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
35   - </template>
36   - <template #createTime="{ row }">
37   - <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
  4 + <vxe-grid ref="xGrid" v-bind="gridOptions" class="xtable-scrollbar">
  5 + <!-- 操作:新增 -->
  6 + <template #toolbar_buttons>
  7 + <XButton
  8 + type="primary"
  9 + preIcon="ep:zoom-in"
  10 + :title="t('action.add')"
  11 + v-hasPermi="['system:sms-channel:create']"
  12 + @click="handleCreate()"
  13 + />
38 14 </template>
39   - <template #action="{ row }">
  15 + <template #actionbtns_default="{ row }">
40 16 <!-- 操作:修改 -->
41 17 <XTextButton
42 18 preIcon="ep:edit"
... ... @@ -49,20 +25,20 @@
49 25 preIcon="ep:view"
50 26 :title="t('action.detail')"
51 27 v-hasPermi="['system:sms-channel:update']"
52   - @click="handleDetail(row)"
  28 + @click="handleDetail(row.id)"
53 29 />
54 30 <!-- 操作:删除 -->
55 31 <XTextButton
56 32 preIcon="ep:delete"
57 33 :title="t('action.del')"
58 34 v-hasPermi="['system:sms-channel:delete']"
59   - @click="delList(row.id, false)"
  35 + @click="handleDelete(row.id)"
60 36 />
61 37 </template>
62   - </Table>
  38 + </vxe-grid>
63 39 </ContentWrap>
64 40  
65   - <XModal v-model="dialogVisible" :title="dialogTitle">
  41 + <XModal id="smsChannel" v-model="dialogVisible" :title="dialogTitle">
66 42 <!-- 对话框(添加 / 修改) -->
67 43 <Form
68 44 v-if="['create', 'update'].includes(actionType)"
... ... @@ -74,7 +50,7 @@
74 50 <Descriptions
75 51 v-if="actionType === 'detail'"
76 52 :schema="allSchemas.detailSchema"
77   - :data="detailRef"
  53 + :data="detailData"
78 54 />
79 55 <!-- 操作按钮 -->
80 56 <template #footer>
... ... @@ -83,41 +59,45 @@
83 59 v-if="['create', 'update'].includes(actionType)"
84 60 type="primary"
85 61 :title="t('action.save')"
86   - :loading="loading"
  62 + :loading="actionLoading"
87 63 @click="submitForm()"
88 64 />
89 65 <!-- 按钮:关闭 -->
90   - <XButton :loading="loading" :title="t('dialog.close')" @click="dialogVisible = false" />
  66 + <XButton :loading="actionLoading" :title="t('dialog.close')" @click="dialogVisible = false" />
91 67 </template>
92 68 </XModal>
93 69 </template>
94 70  
95 71 <script setup lang="ts">
  72 +// 全局相关的 import
96 73 import { ref, unref } from 'vue'
97   -import dayjs from 'dayjs'
98   -import { ElMessage } from 'element-plus'
99   -import { DICT_TYPE } from '@/utils/dict'
100   -import { useTable } from '@/hooks/web/useTable'
101 74 import { useI18n } from '@/hooks/web/useI18n'
  75 +import { useMessage } from '@/hooks/web/useMessage'
  76 +import { useVxeGrid } from '@/hooks/web/useVxeGrid'
  77 +import { VxeGridInstance } from 'vxe-table'
102 78 import { FormExpose } from '@/components/Form'
103   -import type { SmsChannelVO } from '@/api/system/sms/smsChannel/types'
104   -import { rules, allSchemas } from './sms.channel.data'
  79 +// 业务相关的 import
105 80 import * as SmsChannelApi from '@/api/system/sms/smsChannel'
  81 +import { rules, allSchemas } from './sms.channel.data'
  82 +
106 83 const { t } = useI18n() // 国际化
  84 +const message = useMessage() // 消息弹窗
107 85  
108   -// ========== 列表相关 ==========
109   -const { register, tableObject, methods } = useTable<SmsChannelVO>({
  86 +// 列表相关的变量
  87 +const xGrid = ref<VxeGridInstance>() // 列表 Grid Ref
  88 +const { gridOptions, reloadList, delList } = useVxeGrid<SmsChannelApi.SmsChannelVO>({
  89 + allSchemas: allSchemas,
110 90 getListApi: SmsChannelApi.getSmsChannelPageApi,
111 91 delListApi: SmsChannelApi.deleteSmsChannelApi
112 92 })
113   -const { getList, setSearchParams, delList } = methods
114 93  
115   -// ========== CRUD 相关 ==========
116   -const loading = ref(false) // 遮罩层
117   -const actionType = ref('') // 操作按钮的类型
  94 +// 弹窗相关的变量
118 95 const dialogVisible = ref(false) // 是否显示弹出层
119 96 const dialogTitle = ref('edit') // 弹出层标题
  97 +const actionType = ref('') // 操作按钮的类型
  98 +const actionLoading = ref(false) // 按钮 Loading
120 99 const formRef = ref<FormExpose>() // 表单 Ref
  100 +const detailData = ref() // 详情 Ref
121 101  
122 102 // 设置标题
123 103 const setDialogTile = (type: string) => {
... ... @@ -139,43 +119,42 @@ const handleUpdate = async (rowId: number) =&gt; {
139 119 unref(formRef)?.setValues(res)
140 120 }
141 121  
  122 +// 详情操作
  123 +const handleDetail = async (rowId: number) => {
  124 + setDialogTile('detail')
  125 + const res = await SmsChannelApi.getSmsChannelApi(rowId)
  126 + detailData.value = res
  127 +}
  128 +
  129 +// 删除操作
  130 +const handleDelete = async (rowId: number) => {
  131 + await delList(xGrid, rowId)
  132 +}
  133 +
142 134 // 提交按钮
143 135 const submitForm = async () => {
144 136 const elForm = unref(formRef)?.getElFormRef()
145 137 if (!elForm) return
146 138 elForm.validate(async (valid) => {
147 139 if (valid) {
148   - loading.value = true
  140 + actionLoading.value = true
149 141 // 提交请求
150 142 try {
151   - const data = unref(formRef)?.formModel as SmsChannelVO
  143 + const data = unref(formRef)?.formModel as SmsChannelApi.SmsChannelVO
152 144 if (actionType.value === 'create') {
153 145 await SmsChannelApi.createSmsChannelApi(data)
154   - ElMessage.success(t('common.createSuccess'))
  146 + message.success(t('common.createSuccess'))
155 147 } else {
156 148 await SmsChannelApi.updateSmsChannelApi(data)
157   - ElMessage.success(t('common.updateSuccess'))
  149 + message.success(t('common.updateSuccess'))
158 150 }
159   - // 操作成功,重新加载列表
160 151 dialogVisible.value = false
161   - await getList()
162 152 } finally {
163   - loading.value = false
  153 + actionLoading.value = false
  154 + // 刷新列表
  155 + reloadList(xGrid)
164 156 }
165 157 }
166 158 })
167 159 }
168   -
169   -// ========== 详情相关 ==========
170   -const detailRef = ref() // 详情 Ref
171   -
172   -// 详情操作
173   -const handleDetail = async (row: SmsChannelVO) => {
174   - // 设置数据
175   - detailRef.value = row
176   - setDialogTile('detail')
177   -}
178   -
179   -// ========== 初始化 ==========
180   -getList()
181 160 </script>
... ...
yudao-ui-admin-vue3/src/views/system/sms/smsChannel/sms.channel.data.ts
1 1 import { reactive } from 'vue'
2 2 import { useI18n } from '@/hooks/web/useI18n'
3 3 import { required } from '@/utils/formRules'
4   -import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
5 4 import { DICT_TYPE } from '@/utils/dict'
  5 +import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas'
6 6 const { t } = useI18n() // 国际化
7 7  
8 8 // 表单校验
... ... @@ -14,79 +14,46 @@ export const rules = reactive({
14 14 })
15 15  
16 16 // CrudSchema
17   -const crudSchemas = reactive<CrudSchema[]>([
18   - {
19   - label: t('common.index'),
20   - field: 'id',
21   - type: 'index',
22   - form: {
23   - show: false
  17 +const crudSchemas = reactive<VxeCrudSchema>({
  18 + primaryKey: 'id',
  19 + primaryType: 'seq',
  20 + action: true,
  21 + columns: [
  22 + {
  23 + title: '短信签名',
  24 + field: 'signature',
  25 + isSearch: true
24 26 },
25   - detail: {
26   - show: false
27   - }
28   - },
29   - {
30   - label: '短信签名',
31   - field: 'signature',
32   - search: {
33   - show: true
34   - }
35   - },
36   - {
37   - label: '渠道编码',
38   - field: 'code',
39   - dictType: DICT_TYPE.SYSTEM_SMS_CHANNEL_CODE,
40   - search: {
41   - show: true
42   - }
43   - },
44   - {
45   - label: t('common.status'),
46   - field: 'status',
47   - dictType: DICT_TYPE.COMMON_STATUS,
48   - search: {
49   - show: true
50   - }
51   - },
52   - {
53   - label: '短信 API 的账号',
54   - field: 'apiKey'
55   - },
56   - {
57   - label: '短信 API 的密钥',
58   - field: 'apiSecret'
59   - },
60   - {
61   - label: '短信发送回调 URL',
62   - field: 'callbackUrl'
63   - },
64   - {
65   - label: t('common.createTime'),
66   - field: 'createTime',
67   - form: {
68   - show: false
  27 + {
  28 + title: '渠道编码',
  29 + field: 'code',
  30 + dictType: DICT_TYPE.SYSTEM_SMS_CHANNEL_CODE,
  31 + isSearch: true
69 32 },
70   - search: {
71   - show: true,
72   - component: 'DatePicker',
73   - componentProps: {
74   - type: 'daterange',
75   - valueFormat: 'YYYY-MM-DD HH:mm:ss',
76   - defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]
77   - }
78   - }
79   - },
80   - {
81   - label: t('table.action'),
82   - field: 'action',
83   - width: '240px',
84   - form: {
85   - show: false
  33 + {
  34 + title: t('common.status'),
  35 + field: 'status',
  36 + dictType: DICT_TYPE.COMMON_STATUS,
  37 + isSearch: true
86 38 },
87   - detail: {
88   - show: false
  39 + {
  40 + title: '短信 API 的账号',
  41 + field: 'apiKey'
  42 + },
  43 + {
  44 + title: '短信 API 的密钥',
  45 + field: 'apiSecret'
  46 + },
  47 + {
  48 + title: '短信发送回调 URL',
  49 + field: 'callbackUrl'
  50 + },
  51 + {
  52 + title: t('common.createTime'),
  53 + field: 'createTime',
  54 + formatter: 'formatDate',
  55 + isForm: false
89 56 }
90   - }
91   -])
92   -export const { allSchemas } = useCrudSchemas(crudSchemas)
  57 + ]
  58 +})
  59 +export const { allSchemas } = useVxeCrudSchemas(crudSchemas)
... ...
yudao-ui-admin-vue3/src/views/system/sms/smsLog/index.vue
1 1 <template>
2   - <!-- 搜索工作区 -->
3   - <ContentWrap>
4   - <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
5   - </ContentWrap>
6 2 <ContentWrap>
7 3 <!-- 列表 -->
8   - <Table
9   - :columns="allSchemas.tableColumns"
10   - :selection="false"
11   - :data="tableObject.tableList"
12   - :loading="tableObject.loading"
13   - :pagination="{
14   - total: tableObject.total
15   - }"
16   - v-model:pageSize="tableObject.pageSize"
17   - v-model:currentPage="tableObject.currentPage"
18   - @register="register"
19   - >
20   - <template #code="{ row }">
21   - <DictTag :type="DICT_TYPE.SYSTEM_SMS_CHANNEL_CODE" :value="row.code" />
22   - </template>
23   - <template #status="{ row }">
24   - <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
25   - </template>
26   - <template #createTime="{ row }">
27   - <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
28   - </template>
29   - <template #receiveTime="{ row }">
30   - <span>{{ dayjs(row.receiveTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
  4 + <vxe-grid ref="xGrid" v-bind="gridOptions" class="xtable-scrollbar">
  5 + <!-- 操作:导出 -->
  6 + <template #toolbar_buttons>
  7 + <XButton
  8 + type="warning"
  9 + preIcon="ep:download"
  10 + :title="t('action.export')"
  11 + @click="handleExport()"
  12 + />
31 13 </template>
32   - <template #action="{ row }">
  14 + <template #actionbtns_default="{ row }">
33 15 <XTextButton preIcon="ep:view" :title="t('action.detail')" @click="handleDetail(row)" />
34 16 </template>
35   - </Table>
  17 + </vxe-grid>
36 18 </ContentWrap>
37 19  
38   - <XModal v-model="dialogVisible" :title="dialogTitle">
  20 + <XModal id="smsLog" v-model="dialogVisible" :title="dialogTitle">
39 21 <!-- 对话框(详情) -->
40 22 <Descriptions
41 23 v-if="actionType === 'detail'"
... ... @@ -50,33 +32,37 @@
50 32 </template>
51 33  
52 34 <script setup lang="ts">
  35 +// 全局相关的 import
53 36 import { ref } from 'vue'
54   -import dayjs from 'dayjs'
55   -import { DICT_TYPE } from '@/utils/dict'
56   -import { useTable } from '@/hooks/web/useTable'
57 37 import { useI18n } from '@/hooks/web/useI18n'
58   -import type { SmsLogVO } from '@/api/system/sms/smsLog/types'
  38 +import { useVxeGrid } from '@/hooks/web/useVxeGrid'
  39 +import { VxeGridInstance } from 'vxe-table'
59 40 import { allSchemas } from './sms.log.data'
60 41 import * as SmsLoglApi from '@/api/system/sms/smsLog'
61 42 const { t } = useI18n() // 国际化
62 43  
63   -// ========== 列表相关 ==========
64   -const { register, tableObject, methods } = useTable<SmsLogVO>({
65   - getListApi: SmsLoglApi.getSmsLogPageApi
  44 +// 列表相关的变量
  45 +const xGrid = ref<VxeGridInstance>() // 列表 Grid Ref
  46 +const { gridOptions, exportList } = useVxeGrid<SmsLoglApi.SmsLogVO>({
  47 + allSchemas: allSchemas,
  48 + getListApi: SmsLoglApi.getSmsLogPageApi,
  49 + exportListApi: SmsLoglApi.exportSmsLogApi
66 50 })
67   -const { getList, setSearchParams } = methods
68 51  
69   -// ========== CRUD 相关 ==========
70   -const actionType = ref('') // 操作按钮的类型
  52 +// 弹窗相关的变量
71 53 const dialogVisible = ref(false) // 是否显示弹出层
72   -const dialogTitle = ref(t('action.detail')) // 弹出层标题
  54 +const dialogTitle = ref('edit') // 弹出层标题
  55 +const actionType = ref('') // 操作按钮的类型
73 56 // ========== 详情相关 ==========
74 57 const detailRef = ref() // 详情 Ref
75   -const handleDetail = (row: SmsLogVO) => {
  58 +const handleDetail = (row: SmsLoglApi.SmsLogVO) => {
76 59 // 设置数据
77 60 detailRef.value = row
78 61 dialogVisible.value = true
79 62 }
80   -// ========== 初始化 ==========
81   -getList()
  63 +
  64 +// 导出操作
  65 +const handleExport = async () => {
  66 + await exportList(xGrid, '短信日志.xls')
  67 +}
82 68 </script>
... ...
yudao-ui-admin-vue3/src/views/system/sms/smsLog/sms.log.data.ts
1 1 import { reactive } from 'vue'
2 2 import { useI18n } from '@/hooks/web/useI18n'
3   -import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
4 3 import { DICT_TYPE } from '@/utils/dict'
  4 +import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas'
5 5 const { t } = useI18n() // 国际化
6 6  
7 7 // CrudSchema
8   -const crudSchemas = reactive<CrudSchema[]>([
9   - {
10   - label: t('common.index'),
11   - field: 'id',
12   - type: 'index',
13   - form: {
14   - show: false
  8 +const crudSchemas = reactive<VxeCrudSchema>({
  9 + primaryKey: 'id',
  10 + primaryType: 'seq',
  11 + action: true,
  12 + columns: [
  13 + {
  14 + title: '手机号',
  15 + field: 'mobile',
  16 + isSearch: true
15 17 },
16   - detail: {
17   - show: false
18   - }
19   - },
20   - {
21   - label: '手机号',
22   - field: 'mobile',
23   - search: {
24   - show: true
25   - }
26   - },
27   - {
28   - label: '短信内容',
29   - field: 'templateContent'
30   - },
31   - {
32   - label: '短信渠道',
33   - field: 'channelId',
34   - dictType: DICT_TYPE.SYSTEM_SMS_CHANNEL_CODE,
35   - search: {
36   - show: true
37   - }
38   - },
39   - {
40   - label: '发送状态',
41   - field: 'sendStatus',
42   - dictType: DICT_TYPE.SYSTEM_SMS_SEND_STATUS,
43   - search: {
44   - show: true
45   - }
46   - },
47   - {
48   - label: '接收状态',
49   - field: 'receiveTime',
50   - dictType: DICT_TYPE.SYSTEM_SMS_RECEIVE_STATUS,
51   - search: {
52   - show: true
53   - }
54   - },
55   - {
56   - label: '模板编号',
57   - field: 'templateId',
58   - search: {
59   - show: true
60   - }
61   - },
62   - {
63   - label: '短信类型',
64   - field: 'channelId',
65   - dictType: DICT_TYPE.SYSTEM_SMS_TEMPLATE_TYPE,
66   - search: {
67   - show: true
68   - }
69   - },
70   - {
71   - label: '接收时间',
72   - field: 'receiveTime',
73   - form: {
74   - show: false
75   - }
76   - },
77   - {
78   - label: t('common.createTime'),
79   - field: 'createTime',
80   - form: {
81   - show: false
  18 + {
  19 + title: '短信内容',
  20 + field: 'templateContent'
82 21 },
83   - search: {
84   - show: true,
85   - component: 'DatePicker',
86   - componentProps: {
87   - type: 'daterange',
88   - valueFormat: 'YYYY-MM-DD HH:mm:ss',
89   - defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]
90   - }
91   - }
92   - },
93   - {
94   - label: t('table.action'),
95   - field: 'action',
96   - width: '80px',
97   - form: {
98   - show: false
  22 + {
  23 + title: '短信渠道',
  24 + field: 'channelId',
  25 + dictType: DICT_TYPE.SYSTEM_SMS_CHANNEL_CODE,
  26 + isSearch: true
  27 + },
  28 + {
  29 + title: '发送状态',
  30 + field: 'sendStatus',
  31 + dictType: DICT_TYPE.SYSTEM_SMS_SEND_STATUS,
  32 + isSearch: true
  33 + },
  34 + {
  35 + title: '接收状态',
  36 + field: 'receiveStatus',
  37 + dictType: DICT_TYPE.SYSTEM_SMS_RECEIVE_STATUS,
  38 + isSearch: true
99 39 },
100   - detail: {
101   - show: false
  40 + {
  41 + title: '模板编号',
  42 + field: 'templateId',
  43 + isSearch: true
  44 + },
  45 + {
  46 + title: '短信类型',
  47 + field: 'templateType',
  48 + dictType: DICT_TYPE.SYSTEM_SMS_TEMPLATE_TYPE,
  49 + isSearch: true
  50 + },
  51 + {
  52 + title: '接收时间',
  53 + field: 'receiveTime'
  54 + },
  55 + {
  56 + title: t('common.createTime'),
  57 + field: 'createTime',
  58 + formatter: 'formatDate',
  59 + search: {
  60 + show: true,
  61 + itemRender: {
  62 + name: 'XDataTimePicker'
  63 + }
  64 + }
102 65 }
103   - }
104   -])
105   -export const { allSchemas } = useCrudSchemas(crudSchemas)
  66 + ]
  67 +})
  68 +export const { allSchemas } = useVxeCrudSchemas(crudSchemas)
... ...
yudao-ui-admin-vue3/src/views/system/sms/smsTemplate/index.vue
1 1 <template>
2   - <!-- 搜索工作区 -->
3 2 <ContentWrap>
4   - <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
5   - </ContentWrap>
6   - <ContentWrap>
7   - <!-- 操作工具栏 -->
8   - <div class="mb-10px">
9   - <XButton
10   - type="primary"
11   - preIcon="ep:zoom-in"
12   - :title="t('action.add')"
13   - v-hasPermi="['system:sms-channel:create']"
14   - @click="handleCreate()"
15   - />
16   - </div>
17 3 <!-- 列表 -->
18   - <Table
19   - :columns="allSchemas.tableColumns"
20   - :selection="false"
21   - :data="tableObject.tableList"
22   - :loading="tableObject.loading"
23   - :pagination="{
24   - total: tableObject.total
25   - }"
26   - v-model:pageSize="tableObject.pageSize"
27   - v-model:currentPage="tableObject.currentPage"
28   - @register="register"
29   - >
30   - <template #type="{ row }">
31   - <DictTag :type="DICT_TYPE.SYSTEM_SMS_TEMPLATE_TYPE" :value="row.type" />
32   - </template>
33   - <template #status="{ row }">
34   - <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
35   - </template>
36   - <template #createTime="{ row }">
37   - <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
  4 + <vxe-grid ref="xGrid" v-bind="gridOptions" class="xtable-scrollbar">
  5 + <!-- 操作:新增 -->
  6 + <template #toolbar_buttons>
  7 + <XButton
  8 + type="primary"
  9 + preIcon="ep:zoom-in"
  10 + :title="t('action.add')"
  11 + v-hasPermi="['system:sms-channel:create']"
  12 + @click="handleCreate()"
  13 + />
38 14 </template>
39   - <template #action="{ row }">
  15 + <template #actionbtns_default="{ row }">
40 16 <XTextButton
41 17 preIcon="ep:cpu"
42 18 :title="t('action.test')"
... ... @@ -55,20 +31,20 @@
55 31 preIcon="ep:view"
56 32 :title="t('action.detail')"
57 33 v-hasPermi="['system:sms-template:update']"
58   - @click="handleDetail(row)"
  34 + @click="handleDetail(row.id)"
59 35 />
60 36 <!-- 操作:删除 -->
61 37 <XTextButton
62 38 preIcon="ep:delete"
63 39 :title="t('action.del')"
64 40 v-hasPermi="['system:sms-template:delete']"
65   - @click="delList(row.id, false)"
  41 + @click="handleDelete(row.id)"
66 42 />
67 43 </template>
68   - </Table>
  44 + </vxe-grid>
69 45 </ContentWrap>
70 46  
71   - <XModal v-model="dialogVisible" :title="dialogTitle">
  47 + <XModal id="smsTemplate" v-model="dialogVisible" :title="dialogTitle">
72 48 <!-- 对话框(添加 / 修改) -->
73 49 <Form
74 50 v-if="['create', 'update'].includes(actionType)"
... ... @@ -80,7 +56,7 @@
80 56 <Descriptions
81 57 v-if="actionType === 'detail'"
82 58 :schema="allSchemas.detailSchema"
83   - :data="detailRef"
  59 + :data="detailData"
84 60 />
85 61 <!-- 操作按钮 -->
86 62 <template #footer>
... ... @@ -89,14 +65,14 @@
89 65 v-if="['create', 'update'].includes(actionType)"
90 66 type="primary"
91 67 :title="t('action.save')"
92   - :loading="loading"
  68 + :loading="actionLoading"
93 69 @click="submitForm()"
94 70 />
95 71 <!-- 按钮:关闭 -->
96   - <XButton :loading="loading" :title="t('dialog.close')" @click="dialogVisible = false" />
  72 + <XButton :loading="actionLoading" :title="t('dialog.close')" @click="dialogVisible = false" />
97 73 </template>
98 74 </XModal>
99   - <XModal v-model="sendVisible" title="测试">
  75 + <XModal id="sendTest" v-model="sendVisible" title="测试">
100 76 <el-form :model="sendSmsForm" :rules="sendSmsRules" label-width="140px">
101 77 <el-form-item label="模板内容" prop="content">
102 78 <el-input
... ... @@ -123,38 +99,47 @@
123 99 </el-form>
124 100 <!-- 操作按钮 -->
125 101 <template #footer>
126   - <XButton type="primary" :title="t('action.test')" :loading="loading" @click="sendSmsTest()" />
  102 + <XButton
  103 + type="primary"
  104 + :title="t('action.test')"
  105 + :loading="actionLoading"
  106 + @click="sendSmsTest()"
  107 + />
127 108 <XButton :title="t('dialog.close')" @click="dialogVisible = false" />
128 109 </template>
129 110 </XModal>
130 111 </template>
131 112  
132 113 <script setup lang="ts">
  114 +// 全局相关的 import
133 115 import { ref, unref } from 'vue'
134   -import dayjs from 'dayjs'
135   -import { ElMessage, ElForm, ElFormItem, ElInput } from 'element-plus'
136   -import { DICT_TYPE } from '@/utils/dict'
137   -import { useTable } from '@/hooks/web/useTable'
138 116 import { useI18n } from '@/hooks/web/useI18n'
  117 +import { useMessage } from '@/hooks/web/useMessage'
  118 +import { useVxeGrid } from '@/hooks/web/useVxeGrid'
  119 +import { VxeGridInstance } from 'vxe-table'
139 120 import { FormExpose } from '@/components/Form'
140   -import type { SmsTemplateVO } from '@/api/system/sms/smsTemplate/types'
141   -import { rules, allSchemas } from './sms.template.data'
  121 +// 业务相关的 import
142 122 import * as SmsTemplateApi from '@/api/system/sms/smsTemplate'
  123 +import { rules, allSchemas } from './sms.template.data'
  124 +
143 125 const { t } = useI18n() // 国际化
  126 +const message = useMessage() // 消息弹窗
144 127  
145   -// ========== 列表相关 ==========
146   -const { register, tableObject, methods } = useTable<SmsTemplateVO>({
  128 +// 列表相关的变量
  129 +const xGrid = ref<VxeGridInstance>() // 列表 Grid Ref
  130 +const { gridOptions, reloadList, delList } = useVxeGrid<SmsTemplateApi.SmsTemplateVO>({
  131 + allSchemas: allSchemas,
147 132 getListApi: SmsTemplateApi.getSmsTemplatePageApi,
148 133 delListApi: SmsTemplateApi.deleteSmsTemplateApi
149 134 })
150   -const { getList, setSearchParams, delList } = methods
151 135  
152   -// ========== CRUD 相关 ==========
153   -const loading = ref(false) // 遮罩层
154   -const actionType = ref('') // 操作按钮的类型
  136 +// 弹窗相关的变量
155 137 const dialogVisible = ref(false) // 是否显示弹出层
156 138 const dialogTitle = ref('edit') // 弹出层标题
  139 +const actionType = ref('') // 操作按钮的类型
  140 +const actionLoading = ref(false) // 按钮 Loading
157 141 const formRef = ref<FormExpose>() // 表单 Ref
  142 +const detailData = ref() // 详情 Ref
158 143  
159 144 // 设置标题
160 145 const setDialogTile = (type: string) => {
... ... @@ -176,42 +161,46 @@ const handleUpdate = async (rowId: number) =&gt; {
176 161 unref(formRef)?.setValues(res)
177 162 }
178 163  
  164 +// 详情操作
  165 +const handleDetail = async (rowId: number) => {
  166 + setDialogTile('detail')
  167 + // 设置数据
  168 + const res = await SmsTemplateApi.getSmsTemplateApi(rowId)
  169 + detailData.value = res
  170 +}
  171 +
  172 +// 删除操作
  173 +const handleDelete = async (rowId: number) => {
  174 + await delList(xGrid, rowId)
  175 +}
  176 +
179 177 // 提交按钮
180 178 const submitForm = async () => {
181 179 const elForm = unref(formRef)?.getElFormRef()
182 180 if (!elForm) return
183 181 elForm.validate(async (valid) => {
184 182 if (valid) {
185   - loading.value = true
  183 + actionLoading.value = true
186 184 // 提交请求
187 185 try {
188   - const data = unref(formRef)?.formModel as SmsTemplateVO
  186 + const data = unref(formRef)?.formModel as SmsTemplateApi.SmsTemplateVO
189 187 if (actionType.value === 'create') {
190 188 await SmsTemplateApi.createSmsTemplateApi(data)
191   - ElMessage.success(t('common.createSuccess'))
  189 + message.success(t('common.createSuccess'))
192 190 } else {
193 191 await SmsTemplateApi.updateSmsTemplateApi(data)
194   - ElMessage.success(t('common.updateSuccess'))
  192 + message.success(t('common.updateSuccess'))
195 193 }
196   - // 操作成功,重新加载列表
197 194 dialogVisible.value = false
198   - await getList()
199 195 } finally {
200   - loading.value = false
  196 + actionLoading.value = false
  197 + // 刷新列表
  198 + reloadList(xGrid)
201 199 }
202 200 }
203 201 })
204 202 }
205 203  
206   -// ========== 详情相关 ==========
207   -const detailRef = ref() // 详情 Ref
208   -
209   -// 详情操作
210   -const handleDetail = async (row: SmsTemplateVO) => {
211   - // 设置数据
212   - detailRef.value = row
213   - setDialogTile('detail')
214   -}
215 204 // ========== 测试相关 ==========
216 205 const sendSmsForm = ref({
217 206 content: '',
... ... @@ -249,10 +238,7 @@ const sendSmsTest = () =&gt; {
249 238 templateParams: sendSmsForm.value.templateParams
250 239 }
251 240 SmsTemplateApi.sendSmsApi(data)
252   - ElMessage.info('发送成功')
  241 + message.info('发送成功')
253 242 sendVisible.value = false
254 243 }
255   -
256   -// ========== 初始化 ==========
257   -getList()
258 244 </script>
... ...
yudao-ui-admin-vue3/src/views/system/sms/smsTemplate/sms.template.data.ts
1 1 import { reactive } from 'vue'
2 2 import { useI18n } from '@/hooks/web/useI18n'
3 3 import { required } from '@/utils/formRules'
4   -import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
5 4 import { DICT_TYPE } from '@/utils/dict'
  5 +import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas'
6 6 const { t } = useI18n() // 国际化
7 7  
8 8 // 表单校验
... ... @@ -17,86 +17,57 @@ export const rules = reactive({
17 17 })
18 18  
19 19 // CrudSchema
20   -const crudSchemas = reactive<CrudSchema[]>([
21   - {
22   - label: t('common.index'),
23   - field: 'id',
24   - type: 'index',
25   - form: {
26   - show: false
  20 +const crudSchemas = reactive<VxeCrudSchema>({
  21 + primaryKey: 'id',
  22 + primaryType: 'seq',
  23 + action: true,
  24 + columns: [
  25 + {
  26 + label: '模板编码',
  27 + field: 'code',
  28 + isSearch: true
27 29 },
28   - detail: {
29   - show: false
30   - }
31   - },
32   - {
33   - label: '模板编码',
34   - field: 'code',
35   - search: {
36   - show: true
37   - }
38   - },
39   - {
40   - label: '模板名称',
41   - field: 'name',
42   - search: {
43   - show: true
44   - }
45   - },
46   - {
47   - label: '模板内容',
48   - field: 'content'
49   - },
50   - {
51   - label: '短信 API 的模板编号',
52   - field: 'apiTemplateId',
53   - search: {
54   - show: true
55   - }
56   - },
57   - {
58   - label: '短信类型',
59   - field: 'type',
60   - dictType: DICT_TYPE.SYSTEM_SMS_TEMPLATE_TYPE
61   - },
62   - {
63   - label: t('common.status'),
64   - field: 'status',
65   - dictType: DICT_TYPE.COMMON_STATUS
66   - },
67   - {
68   - label: t('form.remark'),
69   - field: 'remark',
70   - table: {
71   - show: false
72   - }
73   - },
74   - {
75   - label: t('common.createTime'),
76   - field: 'createTime',
77   - form: {
78   - show: false
  30 + {
  31 + label: '模板名称',
  32 + field: 'name',
  33 + isSearch: true
79 34 },
80   - search: {
81   - show: true,
82   - component: 'DatePicker',
83   - componentProps: {
84   - type: 'daterange',
85   - valueFormat: 'YYYY-MM-DD HH:mm:ss',
86   - defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]
87   - }
88   - }
89   - },
90   - {
91   - label: t('table.action'),
92   - field: 'action',
93   - width: '320px',
94   - form: {
95   - show: false
  35 + {
  36 + label: '模板内容',
  37 + field: 'content'
96 38 },
97   - detail: {
98   - show: false
  39 + {
  40 + label: '短信 API 的模板编号',
  41 + field: 'apiTemplateId',
  42 + isSearch: true
  43 + },
  44 + {
  45 + label: '短信类型',
  46 + field: 'type',
  47 + dictType: DICT_TYPE.SYSTEM_SMS_TEMPLATE_TYPE
  48 + },
  49 + {
  50 + label: t('common.status'),
  51 + field: 'status',
  52 + dictType: DICT_TYPE.COMMON_STATUS
  53 + },
  54 + {
  55 + label: t('form.remark'),
  56 + field: 'remark',
  57 + isTable: false
  58 + },
  59 + {
  60 + title: t('common.createTime'),
  61 + field: 'createTime',
  62 + formatter: 'formatDate',
  63 + isForm: false,
  64 + search: {
  65 + show: true,
  66 + itemRender: {
  67 + name: 'XDataTimePicker'
  68 + }
  69 + }
99 70 }
100   - }
101   -])
102   -export const { allSchemas } = useCrudSchemas(crudSchemas)
  71 + ]
  72 +})
  73 +export const { allSchemas } = useVxeCrudSchemas(crudSchemas)
... ...