Commit 356a8ec94d869a06c8ff3660c3f41a142289bb29

Authored by 芋道源码
Committed by Gitee
2 parents 3fbb0b4c 583549ed

!295 fix: vue3 bugs

Merge pull request !295 from xingyu/feature/vue3
yudao-ui-admin-vue3/package.json
... ... @@ -31,7 +31,7 @@
31 31 "@wangeditor/editor-for-vue": "^5.1.10",
32 32 "@zxcvbn-ts/core": "^2.1.0",
33 33 "animate.css": "^4.1.1",
34   - "axios": "^1.1.3",
  34 + "axios": "^0.27.2",
35 35 "crypto-js": "^4.1.1",
36 36 "dayjs": "^1.11.6",
37 37 "echarts": "^5.4.0",
... ...
yudao-ui-admin-vue3/pnpm-lock.yaml
... ... @@ -23,7 +23,7 @@ specifiers:
23 23 '@zxcvbn-ts/core': ^2.1.0
24 24 animate.css: ^4.1.1
25 25 autoprefixer: ^10.4.13
26   - axios: ^1.1.3
  26 + axios: ^0.27.2
27 27 crypto-js: ^4.1.1
28 28 dayjs: ^1.11.6
29 29 echarts: ^5.4.0
... ... @@ -87,7 +87,7 @@ dependencies:
87 87 '@wangeditor/editor-for-vue': 5.1.12_95363b7c2c964a937bf2a01c911df30e
88 88 '@zxcvbn-ts/core': 2.1.0
89 89 animate.css: 4.1.1
90   - axios: 1.1.3
  90 + axios: 0.27.2
91 91 crypto-js: 4.1.1
92 92 dayjs: 1.11.6
93 93 echarts: 5.4.0
... ... @@ -2175,12 +2175,11 @@ packages:
2175 2175 - debug
2176 2176 dev: true
2177 2177  
2178   - /axios/1.1.3:
2179   - resolution: {integrity: sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA==}
  2178 + /axios/0.27.2:
  2179 + resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==}
2180 2180 dependencies:
2181 2181 follow-redirects: 1.15.2
2182 2182 form-data: 4.0.0
2183   - proxy-from-env: 1.1.0
2184 2183 transitivePeerDependencies:
2185 2184 - debug
2186 2185 dev: false
... ... @@ -5790,10 +5789,6 @@ packages:
5790 5789 engines: {node: '>=6'}
5791 5790 dev: false
5792 5791  
5793   - /proxy-from-env/1.1.0:
5794   - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
5795   - dev: false
5796   -
5797 5792 /prr/1.0.1:
5798 5793 resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==}
5799 5794 dev: true
... ...
yudao-ui-admin-vue3/src/config/axios/service.ts
... ... @@ -5,7 +5,7 @@ import axios, {
5 5 AxiosResponse,
6 6 AxiosError
7 7 } from 'axios'
8   -import { ElMessage, ElMessageBox, ElNotification } from 'element-plus'
  8 +import { useMessage } from '@/hooks/web/useMessage'
9 9 import qs from 'qs'
10 10 import { config } from '@/config/axios/config'
11 11 import { getAccessToken, getRefreshToken, getTenantId, removeToken, setToken } from '@/utils/auth'
... ... @@ -17,6 +17,7 @@ import { useCache } from '@/hooks/web/useCache'
17 17 const tenantEnable = import.meta.env.VITE_APP_TENANT_ENABLE
18 18 const { result_code, base_url, request_timeout } = config
19 19  
  20 +const message = useMessage()
20 21 // 需要忽略的提示。忽略后,自动 Promise.reject('error')
21 22 const ignoreMsgs = [
22 23 '无效的刷新令牌', // 刷新令牌被删除时,不用提示
... ... @@ -46,9 +47,9 @@ service.interceptors.request.use(
46 47 ;(config as Recordable).headers.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token
47 48 }
48 49 // 设置租户
49   - if (tenantEnable) {
  50 + if (tenantEnable && tenantEnable === 'true') {
50 51 const tenantId = getTenantId()
51   - if (tenantId) service.defaults.headers.common['tenant-id'] = tenantId
  52 + if (tenantId) (config as Recordable).headers.common['tenant-id'] = tenantId
52 53 }
53 54 const params = config.params || {}
54 55 const data = config.data || false
... ... @@ -129,7 +130,6 @@ service.interceptors.response.use(
129 130 // 2.1 刷新成功,则回放队列的请求 + 当前请求
130 131 setToken((await refreshTokenRes).data.data)
131 132 config.headers!.Authorization = 'Bearer ' + getAccessToken()
132   - service.defaults.headers.Authorization = 'Bearer ' + getAccessToken()
133 133 requestList.forEach((cb: any) => {
134 134 cb()
135 135 })
... ... @@ -157,10 +157,10 @@ service.interceptors.response.use(
157 157 })
158 158 }
159 159 } else if (code === 500) {
160   - ElMessage.error(t('sys.api.errMsg500'))
  160 + message.error(t('sys.api.errMsg500'))
161 161 return Promise.reject(new Error(msg))
162 162 } else if (code === 901) {
163   - ElMessage.error(
  163 + message.error(
164 164 '<div>' +
165 165 t('sys.api.errMsg901') +
166 166 '</div>' +
... ... @@ -175,9 +175,7 @@ service.interceptors.response.use(
175 175 // hard coding:忽略这个提示,直接登出
176 176 console.log(msg)
177 177 } else {
178   - ElNotification.error({
179   - title: msg
180   - })
  178 + message.notifyError(msg)
181 179 }
182 180 return Promise.reject('error')
183 181 } else {
... ... @@ -186,16 +184,16 @@ service.interceptors.response.use(
186 184 },
187 185 (error: AxiosError) => {
188 186 console.log('err' + error) // for debug
189   - let { message } = error
  187 + let { message: msg } = error
190 188 const { t } = useI18n()
191   - if (message === 'Network Error') {
192   - message = t('sys.api.errorMessage')
193   - } else if (message.includes('timeout')) {
194   - message = t('sys.api.apiTimeoutMessage')
195   - } else if (message.includes('Request failed with status code')) {
196   - message = t('sys.api.apiRequestFailed') + message.substr(message.length - 3)
  189 + if (msg === 'Network Error') {
  190 + msg = t('sys.api.errorMessage')
  191 + } else if (msg.includes('timeout')) {
  192 + msg = t('sys.api.apiTimeoutMessage')
  193 + } else if (msg.includes('Request failed with status code')) {
  194 + msg = t('sys.api.apiRequestFailed') + msg.substr(msg.length - 3)
197 195 }
198   - ElMessage.error(message)
  196 + message.error(msg)
199 197 return Promise.reject(error)
200 198 }
201 199 )
... ... @@ -207,11 +205,8 @@ const handleAuthorized = () =&gt; {
207 205 const { t } = useI18n()
208 206 if (!isRelogin.show) {
209 207 isRelogin.show = true
210   - ElMessageBox.confirm(t('sys.api.timeoutMessage'), t('common.confirmTitle'), {
211   - confirmButtonText: t('login.relogin'),
212   - cancelButtonText: t('common.cancel'),
213   - type: 'warning'
214   - })
  208 + message
  209 + .confirm(t('sys.api.timeoutMessage'))
215 210 .then(() => {
216 211 const { wsCache } = useCache()
217 212 resetRouter() // 重置静态路由表
... ...
yudao-ui-admin-vue3/src/hooks/web/useCache.ts
... ... @@ -4,9 +4,9 @@
4 4  
5 5 import WebStorageCache from 'web-storage-cache'
6 6  
7   -type CacheType = 'sessionStorage' | 'localStorage'
  7 +type CacheType = 'localStorage' | 'sessionStorage'
8 8  
9   -export const useCache = (type: CacheType = 'sessionStorage') => {
  9 +export const useCache = (type: CacheType = 'localStorage') => {
10 10 const wsCache: WebStorageCache = new WebStorageCache({
11 11 storage: type
12 12 })
... ...
yudao-ui-admin-vue3/src/hooks/web/useVxeCrudSchemas.ts
... ... @@ -121,10 +121,10 @@ const filterSearchSchema = (crudSchema: VxeCrudSchema[]): VxeFormItemProps[] =&gt;
121 121 props: { placeholder: t('common.selectText') }
122 122 }
123 123 }
124   -
125 124 const searchSchemaItem = {
126 125 // 默认为 input
127   - span: 6,
  126 + span: 8,
  127 + folding: searchSchema.length > 2,
128 128 itemRender: itemRender,
129 129 ...schemaItem.search,
130 130 field: schemaItem.field,
... ... @@ -140,7 +140,7 @@ const filterSearchSchema = (crudSchema: VxeCrudSchema[]): VxeFormItemProps[] =&gt;
140 140 const buttons: VxeFormItemProps = {
141 141 span: 24,
142 142 align: 'center',
143   - collapseNode: true,
  143 + collapseNode: searchSchema.length > 3,
144 144 itemRender: {
145 145 name: '$buttons',
146 146 children: [
... ...
yudao-ui-admin-vue3/src/hooks/web/useVxeGrid.ts
1 1 import { computed, reactive } from 'vue'
2   -import { VxeGridProps } from 'vxe-table'
  2 +import { SizeType, VxeGridProps } from 'vxe-table'
3 3 import { useAppStore } from '@/store/modules/app'
4 4 import { VxeAllSchemas } from './useVxeCrudSchemas'
5 5 import { useI18n } from '@/hooks/web/useI18n'
... ... @@ -18,20 +18,27 @@ interface UseVxeGridConfig&lt;T = any&gt; {
18 18 const appStore = useAppStore()
19 19  
20 20 const currentSize = computed(() => {
21   - if (appStore.getCurrentSize === 'small') {
22   - return 'small'
23   - } else if (appStore.getCurrentSize === 'large') {
24   - return 'mini'
25   - } else {
26   - return 'medium'
  21 + let resSize: SizeType = 'small'
  22 + const appsize = appStore.getCurrentSize
  23 + switch (appsize) {
  24 + case 'large':
  25 + resSize = 'medium'
  26 + break
  27 + case 'default':
  28 + resSize = 'small'
  29 + break
  30 + case 'small':
  31 + resSize = 'mini'
  32 + break
27 33 }
  34 + return resSize
28 35 })
29 36  
30 37 export const useVxeGrid = <T = any>(config?: UseVxeGridConfig<T>) => {
31 38 const gridOptions = reactive<VxeGridProps>({
32 39 loading: true,
33   - size: currentSize.value,
34   - height: 800,
  40 + size: currentSize as any,
  41 + height: 700,
35 42 rowConfig: {
36 43 isCurrent: true, // 当鼠标点击行时,是否要高亮当前行
37 44 isHover: true // 当鼠标移到行时,是否要高亮当前行
... ... @@ -90,9 +97,11 @@ export const useVxeGrid = &lt;T = any&gt;(config?: UseVxeGridConfig&lt;T&gt;) =&gt; {
90 97 }
91 98 })
92 99 const delList = (ids: string | number | string[] | number[]) => {
93   - message.delConfirm().then(() => {
94   - config?.delListApi && config?.delListApi(ids)
95   - message.success(t('common.delSuccess'))
  100 + return new Promise(async () => {
  101 + message.delConfirm().then(() => {
  102 + config?.delListApi && config?.delListApi(ids)
  103 + message.success(t('common.delSuccess'))
  104 + })
96 105 })
97 106 }
98 107 return {
... ...
yudao-ui-admin-vue3/src/plugins/vxeTable/index.ts
... ... @@ -7,7 +7,6 @@ import enUS from &#39;vxe-table/lib/locale/lang/en-US&#39;
7 7 import {
8 8 // 全局对象
9 9 VXETable,
10   -
11 10 // 表格功能
12 11 Filter,
13 12 Edit,
... ... @@ -15,7 +14,6 @@ import {
15 14 Export,
16 15 Keyboard,
17 16 Validator,
18   -
19 17 // 可选组件
20 18 Icon,
21 19 Column,
... ... @@ -42,7 +40,6 @@ import {
42 40 Modal,
43 41 List,
44 42 Pulldown,
45   -
46 43 // 表格
47 44 Table
48 45 } from 'vxe-table'
... ...
yudao-ui-admin-vue3/src/views/system/dict/index.vue
  1 +<template>
  2 + <div class="flex">
  3 + <el-card class="w-1/2 dict" :gutter="12" shadow="always">
  4 + <template #header>
  5 + <div class="card-header">
  6 + <span>字典分类</span>
  7 + </div>
  8 + </template>
  9 + <Search
  10 + :schema="DictTypeSchemas.allSchemas.searchSchema"
  11 + @search="setTypeSearchParams"
  12 + @reset="setTypeSearchParams"
  13 + />
  14 + <!-- 操作工具栏 -->
  15 + <div class="mb-10px">
  16 + <XButton
  17 + type="primary"
  18 + preIcon="ep:zoom-in"
  19 + :title="t('action.add')"
  20 + v-hasPermi="['system:dict:create']"
  21 + @click="handleTypeCreate()"
  22 + />
  23 + </div>
  24 + <!-- 列表 -->
  25 + <Table
  26 + @row-click="onClickType"
  27 + :columns="DictTypeSchemas.allSchemas.tableColumns"
  28 + :selection="false"
  29 + :data="typeTableObject.tableList"
  30 + :loading="typeTableObject.loading"
  31 + :pagination="{
  32 + total: typeTableObject.total
  33 + }"
  34 + :highlight-current-row="true"
  35 + v-model:pageSize="typeTableObject.pageSize"
  36 + v-model:currentPage="typeTableObject.currentPage"
  37 + @register="typeRegister"
  38 + >
  39 + <template #status="{ row }">
  40 + <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
  41 + </template>
  42 + <template #action="{ row }">
  43 + <XTextButton
  44 + preIcon="ep:edit"
  45 + :title="t('action.edit')"
  46 + v-hasPermi="['system:dict:update']"
  47 + @click="handleTypeUpdate(row)"
  48 + />
  49 + <XTextButton
  50 + preIcon="ep:delete"
  51 + :title="t('action.del')"
  52 + v-hasPermi="['system:dict:delete']"
  53 + @click="delTypeList(row.id, false)"
  54 + />
  55 + </template>
  56 + </Table>
  57 + </el-card>
  58 + <el-card class="w-1/2 dict" style="margin-left: 10px" :gutter="12" shadow="hover">
  59 + <template #header>
  60 + <div class="card-header">
  61 + <span>字典数据</span>
  62 + </div>
  63 + </template>
  64 + <!-- 列表 -->
  65 + <div v-if="!tableTypeSelect">
  66 + <span>请从左侧选择</span>
  67 + </div>
  68 + <div v-if="tableTypeSelect">
  69 + <Search
  70 + :schema="DictDataSchemas.allSchemas.searchSchema"
  71 + @search="setDataSearchParams"
  72 + @reset="setDataSearchParams"
  73 + />
  74 + <!-- 操作工具栏 -->
  75 + <div class="mb-10px">
  76 + <XButton
  77 + type="primary"
  78 + preIcon="ep:zoom-in"
  79 + :title="t('action.add')"
  80 + v-hasPermi="['system:dict:create']"
  81 + @click="handleDataCreate()"
  82 + />
  83 + </div>
  84 + <Table
  85 + :columns="DictDataSchemas.allSchemas.tableColumns"
  86 + :selection="false"
  87 + :data="dataTableObject.tableList"
  88 + :loading="dataTableObject.loading"
  89 + :pagination="{
  90 + total: dataTableObject.total
  91 + }"
  92 + v-model:pageSize="dataTableObject.pageSize"
  93 + v-model:currentPage="dataTableObject.currentPage"
  94 + @register="dataRegister"
  95 + >
  96 + <template #status="{ row }">
  97 + <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
  98 + </template>
  99 + <template #action="{ row }">
  100 + <XTextButton
  101 + v-hasPermi="['system:dict:update']"
  102 + preIcon="ep:edit"
  103 + :title="t('action.edit')"
  104 + @click="handleDataUpdate(row)"
  105 + />
  106 + <XTextButton
  107 + v-hasPermi="['system:dict:delete']"
  108 + preIcon="ep:delete"
  109 + :title="t('action.del')"
  110 + @click="delDataList(row.id, false)"
  111 + />
  112 + </template>
  113 + </Table>
  114 + </div>
  115 + </el-card>
  116 + <XModal id="dictModel" v-model="dialogVisible" :title="dialogTitle">
  117 + <template #default>
  118 + <Form
  119 + v-if="['typeCreate', 'typeUpdate'].includes(actionType)"
  120 + :schema="DictTypeSchemas.allSchemas.formSchema"
  121 + :rules="DictTypeSchemas.dictTypeRules"
  122 + ref="typeFormRef"
  123 + />
  124 + <Form
  125 + v-if="['dataCreate', 'dataUpdate'].includes(actionType)"
  126 + :schema="DictDataSchemas.allSchemas.formSchema"
  127 + :rules="DictDataSchemas.dictDataRules"
  128 + ref="dataFormRef"
  129 + />
  130 + </template>
  131 + <!-- 操作按钮 -->
  132 + <template #footer>
  133 + <XButton
  134 + v-if="['typeCreate', 'typeUpdate'].includes(actionType)"
  135 + type="primary"
  136 + :title="t('action.save')"
  137 + :loading="actionLoading"
  138 + @click="submitTypeForm"
  139 + />
  140 + <XButton
  141 + v-if="['dataCreate', 'dataUpdate'].includes(actionType)"
  142 + type="primary"
  143 + :title="t('action.save')"
  144 + :loading="actionLoading"
  145 + @click="submitDataForm"
  146 + />
  147 + <XButton :title="t('dialog.close')" @click="dialogVisible = false" />
  148 + </template>
  149 + </XModal>
  150 + </div>
  151 +</template>
1 152 <script setup lang="ts">
2 153 import { ref, unref, onMounted } from 'vue'
3 154 import { DICT_TYPE } from '@/utils/dict'
... ... @@ -148,155 +299,3 @@ onMounted(async () =&gt; {
148 299 typeTableObject.tableList[0] && onClickType(typeTableObject.tableList[0])
149 300 })
150 301 </script>
151   -
152   -<template>
153   - <div class="flex">
154   - <el-card class="w-1/2 dict" :gutter="12" shadow="always">
155   - <template #header>
156   - <div class="card-header">
157   - <span>字典分类</span>
158   - </div>
159   - </template>
160   - <Search
161   - :schema="DictTypeSchemas.allSchemas.searchSchema"
162   - @search="setTypeSearchParams"
163   - @reset="setTypeSearchParams"
164   - />
165   - <!-- 操作工具栏 -->
166   - <div class="mb-10px">
167   - <el-button type="primary" v-hasPermi="['system:dict:create']" @click="handleTypeCreate">
168   - <Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }}
169   - </el-button>
170   - </div>
171   - <!-- 列表 -->
172   - <Table
173   - @row-click="onClickType"
174   - :columns="DictTypeSchemas.allSchemas.tableColumns"
175   - :selection="false"
176   - :data="typeTableObject.tableList"
177   - :loading="typeTableObject.loading"
178   - :pagination="{
179   - total: typeTableObject.total
180   - }"
181   - :highlight-current-row="true"
182   - v-model:pageSize="typeTableObject.pageSize"
183   - v-model:currentPage="typeTableObject.currentPage"
184   - @register="typeRegister"
185   - >
186   - <template #status="{ row }">
187   - <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
188   - </template>
189   - <template #action="{ row }">
190   - <el-button
191   - link
192   - type="primary"
193   - v-hasPermi="['system:dict:update']"
194   - @click="handleTypeUpdate(row)"
195   - >
196   - <Icon icon="ep:edit" class="mr-1px" /> {{ t('action.edit') }}
197   - </el-button>
198   - <el-button
199   - link
200   - type="primary"
201   - v-hasPermi="['system:dict:delete']"
202   - @click="delTypeList(row.id, false)"
203   - >
204   - <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }}
205   - </el-button>
206   - </template>
207   - </Table>
208   - </el-card>
209   - <el-card class="w-1/2 dict" style="margin-left: 10px" :gutter="12" shadow="hover">
210   - <template #header>
211   - <div class="card-header">
212   - <span>字典数据</span>
213   - </div>
214   - </template>
215   - <!-- 列表 -->
216   - <div v-if="!tableTypeSelect">
217   - <span>请从左侧选择</span>
218   - </div>
219   - <div v-if="tableTypeSelect">
220   - <Search
221   - :schema="DictDataSchemas.allSchemas.searchSchema"
222   - @search="setDataSearchParams"
223   - @reset="setDataSearchParams"
224   - />
225   - <!-- 操作工具栏 -->
226   - <div class="mb-10px">
227   - <el-button type="primary" v-hasPermi="['system:dict:create']" @click="handleDataCreate">
228   - <Icon icon="ep:zoom-in" class="mr-1px" /> {{ t('action.add') }}
229   - </el-button>
230   - </div>
231   - <Table
232   - :columns="DictDataSchemas.allSchemas.tableColumns"
233   - :selection="false"
234   - :data="dataTableObject.tableList"
235   - :loading="dataTableObject.loading"
236   - :pagination="{
237   - total: dataTableObject.total
238   - }"
239   - v-model:pageSize="dataTableObject.pageSize"
240   - v-model:currentPage="dataTableObject.currentPage"
241   - @register="dataRegister"
242   - >
243   - <template #status="{ row }">
244   - <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
245   - </template>
246   - <template #action="{ row }">
247   - <el-button
248   - link
249   - type="primary"
250   - v-hasPermi="['system:dict:update']"
251   - @click="handleDataUpdate(row)"
252   - >
253   - <Icon icon="ep:edit" class="mr-1px" /> {{ t('action.edit') }}
254   - </el-button>
255   - <el-button
256   - link
257   - type="primary"
258   - v-hasPermi="['system:dict:delete']"
259   - @click="delDataList(row.id, false)"
260   - >
261   - <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }}
262   - </el-button>
263   - </template>
264   - </Table>
265   - </div>
266   - </el-card>
267   - <Dialog v-model="dialogVisible" :title="dialogTitle">
268   - <Form
269   - v-if="['typeCreate', 'typeUpdate'].includes(actionType)"
270   - :schema="DictTypeSchemas.allSchemas.formSchema"
271   - :rules="DictTypeSchemas.dictTypeRules"
272   - ref="typeFormRef"
273   - />
274   - <Form
275   - v-if="['dataCreate', 'dataUpdate'].includes(actionType)"
276   - :schema="DictDataSchemas.allSchemas.formSchema"
277   - :rules="DictDataSchemas.dictDataRules"
278   - ref="dataFormRef"
279   - />
280   - <!-- 操作按钮 -->
281   - <template #footer>
282   - <el-button
283   - v-if="['typeCreate', 'typeUpdate'].includes(actionType)"
284   - type="primary"
285   - :loading="actionLoading"
286   - @click="submitTypeForm"
287   - >
288   - {{ t('action.save') }}
289   - </el-button>
290   - <el-button
291   - v-if="['dataCreate', 'dataUpdate'].includes(actionType)"
292   - type="primary"
293   - :loading="actionLoading"
294   - @click="submitDataForm"
295   - >
296   - {{ t('action.save') }}
297   - </el-button>
298   - <el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button>
299   - </template>
300   - </Dialog>
301   - </div>
302   -</template>
... ...
yudao-ui-admin-vue3/src/views/system/post/index.vue
... ... @@ -60,9 +60,9 @@
60 60 <template #footer>
61 61 <XButton
62 62 v-if="['create', 'update'].includes(actionType)"
63   - :loading="actionLoading"
64   - :title="t('action.save')"
65 63 type="primary"
  64 + :title="t('action.save')"
  65 + :loading="actionLoading"
66 66 @click="submitForm"
67 67 />
68 68 <XButton :loading="actionLoading" :title="t('dialog.close')" @click="dialogVisible = false" />
... ... @@ -79,35 +79,31 @@ import { rules, allSchemas } from &#39;./post.data&#39;
79 79 import { useI18n } from '@/hooks/web/useI18n'
80 80 import { useMessage } from '@/hooks/web/useMessage'
81 81 import { useVxeGrid } from '@/hooks/web/useVxeGrid'
82   -import { VxeFormEvents, VxeGridInstance } from 'vxe-table'
  82 +import { VxeGridInstance } from 'vxe-table'
83 83 import { FormExpose } from '@/components/Form'
84 84  
85 85 const { t } = useI18n() // 国际化
86 86 const message = useMessage() // 消息弹窗
87   -const xGrid = ref<VxeGridInstance>()
88   -const formRef = ref<FormExpose>() // 表单 Ref
89 87 const dialogVisible = ref(false) // 是否显示弹出层
90 88 const dialogTitle = ref('edit') // 弹出层标题
91 89 const actionType = ref('') // 操作按钮的类型
92 90 const actionLoading = ref(false) // 按钮Loading
  91 +const xGrid = ref<VxeGridInstance>() // grid Ref
  92 +const formRef = ref<FormExpose>() // 表单 Ref
  93 +const detailRef = ref() // 详情 Ref
93 94  
94 95 const { gridOptions } = useVxeGrid<PostVO>({
95 96 allSchemas: allSchemas,
96 97 getListApi: PostApi.getPostPageApi
97 98 })
  99 +
98 100 // 设置标题
99 101 const setDialogTile = (type: string) => {
100 102 dialogTitle.value = t('action.' + type)
101 103 actionType.value = type
102 104 dialogVisible.value = true
103 105 }
104   -// ========== 详情相关 ==========
105   -const detailRef = ref() // 详情 Ref
106   -// 详情操作
107   -const handleDetail = (row: PostVO) => {
108   - setDialogTile('detail')
109   - detailRef.value = row
110   -}
  106 +
111 107 // 新增操作
112 108 const handleCreate = () => {
113 109 setDialogTile('create')
... ... @@ -115,6 +111,12 @@ const handleCreate = () =&gt; {
115 111 unref(formRef)?.getElFormRef()?.resetFields()
116 112 }
117 113  
  114 +// 详情操作
  115 +const handleDetail = (row: PostVO) => {
  116 + setDialogTile('detail')
  117 + detailRef.value = row
  118 +}
  119 +
118 120 // 修改操作
119 121 const handleUpdate = async (rowId: number) => {
120 122 setDialogTile('update')
... ... @@ -122,6 +124,7 @@ const handleUpdate = async (rowId: number) =&gt; {
122 124 const res = await PostApi.getPostApi(rowId)
123 125 unref(formRef)?.setValues(res)
124 126 }
  127 +
125 128 // 删除操作
126 129 const handleDelete = async (rowId: number) => {
127 130 message
... ... @@ -134,8 +137,9 @@ const handleDelete = async (rowId: number) =&gt; {
134 137 xGrid.value?.commitProxy('query')
135 138 })
136 139 }
  140 +
137 141 // 提交按钮
138   -const submitForm: VxeFormEvents.Submit = async () => {
  142 +const submitForm = async () => {
139 143 const elForm = unref(formRef)?.getElFormRef()
140 144 if (!elForm) return
141 145 elForm.validate(async (valid) => {
... ... @@ -151,7 +155,6 @@ const submitForm: VxeFormEvents.Submit = async () =&gt; {
151 155 await PostApi.updatePostApi(data)
152 156 message.success(t('common.updateSuccess'))
153 157 }
154   - // 操作成功,重新加载列表
155 158 dialogVisible.value = false
156 159 } finally {
157 160 actionLoading.value = false
... ...
yudao-ui-admin-vue3/src/views/system/post/post.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 { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas'
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,7 +17,7 @@ const crudSchemas = reactive&lt;VxeCrudSchema[]&gt;([
17 17 {
18 18 title: t('common.index'),
19 19 field: 'id',
20   - type: 'index',
  20 + type: 'seq',
21 21 form: {
22 22 show: false
23 23 },
... ...