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,7 +31,7 @@
31 "@wangeditor/editor-for-vue": "^5.1.10", 31 "@wangeditor/editor-for-vue": "^5.1.10",
32 "@zxcvbn-ts/core": "^2.1.0", 32 "@zxcvbn-ts/core": "^2.1.0",
33 "animate.css": "^4.1.1", 33 "animate.css": "^4.1.1",
34 - "axios": "^1.1.3", 34 + "axios": "^0.27.2",
35 "crypto-js": "^4.1.1", 35 "crypto-js": "^4.1.1",
36 "dayjs": "^1.11.6", 36 "dayjs": "^1.11.6",
37 "echarts": "^5.4.0", 37 "echarts": "^5.4.0",
yudao-ui-admin-vue3/pnpm-lock.yaml
@@ -23,7 +23,7 @@ specifiers: @@ -23,7 +23,7 @@ specifiers:
23 '@zxcvbn-ts/core': ^2.1.0 23 '@zxcvbn-ts/core': ^2.1.0
24 animate.css: ^4.1.1 24 animate.css: ^4.1.1
25 autoprefixer: ^10.4.13 25 autoprefixer: ^10.4.13
26 - axios: ^1.1.3 26 + axios: ^0.27.2
27 crypto-js: ^4.1.1 27 crypto-js: ^4.1.1
28 dayjs: ^1.11.6 28 dayjs: ^1.11.6
29 echarts: ^5.4.0 29 echarts: ^5.4.0
@@ -87,7 +87,7 @@ dependencies: @@ -87,7 +87,7 @@ dependencies:
87 '@wangeditor/editor-for-vue': 5.1.12_95363b7c2c964a937bf2a01c911df30e 87 '@wangeditor/editor-for-vue': 5.1.12_95363b7c2c964a937bf2a01c911df30e
88 '@zxcvbn-ts/core': 2.1.0 88 '@zxcvbn-ts/core': 2.1.0
89 animate.css: 4.1.1 89 animate.css: 4.1.1
90 - axios: 1.1.3 90 + axios: 0.27.2
91 crypto-js: 4.1.1 91 crypto-js: 4.1.1
92 dayjs: 1.11.6 92 dayjs: 1.11.6
93 echarts: 5.4.0 93 echarts: 5.4.0
@@ -2175,12 +2175,11 @@ packages: @@ -2175,12 +2175,11 @@ packages:
2175 - debug 2175 - debug
2176 dev: true 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 dependencies: 2180 dependencies:
2181 follow-redirects: 1.15.2 2181 follow-redirects: 1.15.2
2182 form-data: 4.0.0 2182 form-data: 4.0.0
2183 - proxy-from-env: 1.1.0  
2184 transitivePeerDependencies: 2183 transitivePeerDependencies:
2185 - debug 2184 - debug
2186 dev: false 2185 dev: false
@@ -5790,10 +5789,6 @@ packages: @@ -5790,10 +5789,6 @@ packages:
5790 engines: {node: '>=6'} 5789 engines: {node: '>=6'}
5791 dev: false 5790 dev: false
5792 5791
5793 - /proxy-from-env/1.1.0:  
5794 - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}  
5795 - dev: false  
5796 -  
5797 /prr/1.0.1: 5792 /prr/1.0.1:
5798 resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} 5793 resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==}
5799 dev: true 5794 dev: true
yudao-ui-admin-vue3/src/config/axios/service.ts
@@ -5,7 +5,7 @@ import axios, { @@ -5,7 +5,7 @@ import axios, {
5 AxiosResponse, 5 AxiosResponse,
6 AxiosError 6 AxiosError
7 } from 'axios' 7 } from 'axios'
8 -import { ElMessage, ElMessageBox, ElNotification } from 'element-plus' 8 +import { useMessage } from '@/hooks/web/useMessage'
9 import qs from 'qs' 9 import qs from 'qs'
10 import { config } from '@/config/axios/config' 10 import { config } from '@/config/axios/config'
11 import { getAccessToken, getRefreshToken, getTenantId, removeToken, setToken } from '@/utils/auth' 11 import { getAccessToken, getRefreshToken, getTenantId, removeToken, setToken } from '@/utils/auth'
@@ -17,6 +17,7 @@ import { useCache } from '@/hooks/web/useCache' @@ -17,6 +17,7 @@ import { useCache } from '@/hooks/web/useCache'
17 const tenantEnable = import.meta.env.VITE_APP_TENANT_ENABLE 17 const tenantEnable = import.meta.env.VITE_APP_TENANT_ENABLE
18 const { result_code, base_url, request_timeout } = config 18 const { result_code, base_url, request_timeout } = config
19 19
  20 +const message = useMessage()
20 // 需要忽略的提示。忽略后,自动 Promise.reject('error') 21 // 需要忽略的提示。忽略后,自动 Promise.reject('error')
21 const ignoreMsgs = [ 22 const ignoreMsgs = [
22 '无效的刷新令牌', // 刷新令牌被删除时,不用提示 23 '无效的刷新令牌', // 刷新令牌被删除时,不用提示
@@ -46,9 +47,9 @@ service.interceptors.request.use( @@ -46,9 +47,9 @@ service.interceptors.request.use(
46 ;(config as Recordable).headers.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token 47 ;(config as Recordable).headers.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token
47 } 48 }
48 // 设置租户 49 // 设置租户
49 - if (tenantEnable) { 50 + if (tenantEnable && tenantEnable === 'true') {
50 const tenantId = getTenantId() 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 const params = config.params || {} 54 const params = config.params || {}
54 const data = config.data || false 55 const data = config.data || false
@@ -129,7 +130,6 @@ service.interceptors.response.use( @@ -129,7 +130,6 @@ service.interceptors.response.use(
129 // 2.1 刷新成功,则回放队列的请求 + 当前请求 130 // 2.1 刷新成功,则回放队列的请求 + 当前请求
130 setToken((await refreshTokenRes).data.data) 131 setToken((await refreshTokenRes).data.data)
131 config.headers!.Authorization = 'Bearer ' + getAccessToken() 132 config.headers!.Authorization = 'Bearer ' + getAccessToken()
132 - service.defaults.headers.Authorization = 'Bearer ' + getAccessToken()  
133 requestList.forEach((cb: any) => { 133 requestList.forEach((cb: any) => {
134 cb() 134 cb()
135 }) 135 })
@@ -157,10 +157,10 @@ service.interceptors.response.use( @@ -157,10 +157,10 @@ service.interceptors.response.use(
157 }) 157 })
158 } 158 }
159 } else if (code === 500) { 159 } else if (code === 500) {
160 - ElMessage.error(t('sys.api.errMsg500')) 160 + message.error(t('sys.api.errMsg500'))
161 return Promise.reject(new Error(msg)) 161 return Promise.reject(new Error(msg))
162 } else if (code === 901) { 162 } else if (code === 901) {
163 - ElMessage.error( 163 + message.error(
164 '<div>' + 164 '<div>' +
165 t('sys.api.errMsg901') + 165 t('sys.api.errMsg901') +
166 '</div>' + 166 '</div>' +
@@ -175,9 +175,7 @@ service.interceptors.response.use( @@ -175,9 +175,7 @@ service.interceptors.response.use(
175 // hard coding:忽略这个提示,直接登出 175 // hard coding:忽略这个提示,直接登出
176 console.log(msg) 176 console.log(msg)
177 } else { 177 } else {
178 - ElNotification.error({  
179 - title: msg  
180 - }) 178 + message.notifyError(msg)
181 } 179 }
182 return Promise.reject('error') 180 return Promise.reject('error')
183 } else { 181 } else {
@@ -186,16 +184,16 @@ service.interceptors.response.use( @@ -186,16 +184,16 @@ service.interceptors.response.use(
186 }, 184 },
187 (error: AxiosError) => { 185 (error: AxiosError) => {
188 console.log('err' + error) // for debug 186 console.log('err' + error) // for debug
189 - let { message } = error 187 + let { message: msg } = error
190 const { t } = useI18n() 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 return Promise.reject(error) 197 return Promise.reject(error)
200 } 198 }
201 ) 199 )
@@ -207,11 +205,8 @@ const handleAuthorized = () =&gt; { @@ -207,11 +205,8 @@ const handleAuthorized = () =&gt; {
207 const { t } = useI18n() 205 const { t } = useI18n()
208 if (!isRelogin.show) { 206 if (!isRelogin.show) {
209 isRelogin.show = true 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 .then(() => { 210 .then(() => {
216 const { wsCache } = useCache() 211 const { wsCache } = useCache()
217 resetRouter() // 重置静态路由表 212 resetRouter() // 重置静态路由表
yudao-ui-admin-vue3/src/hooks/web/useCache.ts
@@ -4,9 +4,9 @@ @@ -4,9 +4,9 @@
4 4
5 import WebStorageCache from 'web-storage-cache' 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 const wsCache: WebStorageCache = new WebStorageCache({ 10 const wsCache: WebStorageCache = new WebStorageCache({
11 storage: type 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,10 +121,10 @@ const filterSearchSchema = (crudSchema: VxeCrudSchema[]): VxeFormItemProps[] =&gt;
121 props: { placeholder: t('common.selectText') } 121 props: { placeholder: t('common.selectText') }
122 } 122 }
123 } 123 }
124 -  
125 const searchSchemaItem = { 124 const searchSchemaItem = {
126 // 默认为 input 125 // 默认为 input
127 - span: 6, 126 + span: 8,
  127 + folding: searchSchema.length > 2,
128 itemRender: itemRender, 128 itemRender: itemRender,
129 ...schemaItem.search, 129 ...schemaItem.search,
130 field: schemaItem.field, 130 field: schemaItem.field,
@@ -140,7 +140,7 @@ const filterSearchSchema = (crudSchema: VxeCrudSchema[]): VxeFormItemProps[] =&gt; @@ -140,7 +140,7 @@ const filterSearchSchema = (crudSchema: VxeCrudSchema[]): VxeFormItemProps[] =&gt;
140 const buttons: VxeFormItemProps = { 140 const buttons: VxeFormItemProps = {
141 span: 24, 141 span: 24,
142 align: 'center', 142 align: 'center',
143 - collapseNode: true, 143 + collapseNode: searchSchema.length > 3,
144 itemRender: { 144 itemRender: {
145 name: '$buttons', 145 name: '$buttons',
146 children: [ 146 children: [
yudao-ui-admin-vue3/src/hooks/web/useVxeGrid.ts
1 import { computed, reactive } from 'vue' 1 import { computed, reactive } from 'vue'
2 -import { VxeGridProps } from 'vxe-table' 2 +import { SizeType, VxeGridProps } from 'vxe-table'
3 import { useAppStore } from '@/store/modules/app' 3 import { useAppStore } from '@/store/modules/app'
4 import { VxeAllSchemas } from './useVxeCrudSchemas' 4 import { VxeAllSchemas } from './useVxeCrudSchemas'
5 import { useI18n } from '@/hooks/web/useI18n' 5 import { useI18n } from '@/hooks/web/useI18n'
@@ -18,20 +18,27 @@ interface UseVxeGridConfig&lt;T = any&gt; { @@ -18,20 +18,27 @@ interface UseVxeGridConfig&lt;T = any&gt; {
18 const appStore = useAppStore() 18 const appStore = useAppStore()
19 19
20 const currentSize = computed(() => { 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 export const useVxeGrid = <T = any>(config?: UseVxeGridConfig<T>) => { 37 export const useVxeGrid = <T = any>(config?: UseVxeGridConfig<T>) => {
31 const gridOptions = reactive<VxeGridProps>({ 38 const gridOptions = reactive<VxeGridProps>({
32 loading: true, 39 loading: true,
33 - size: currentSize.value,  
34 - height: 800, 40 + size: currentSize as any,
  41 + height: 700,
35 rowConfig: { 42 rowConfig: {
36 isCurrent: true, // 当鼠标点击行时,是否要高亮当前行 43 isCurrent: true, // 当鼠标点击行时,是否要高亮当前行
37 isHover: true // 当鼠标移到行时,是否要高亮当前行 44 isHover: true // 当鼠标移到行时,是否要高亮当前行
@@ -90,9 +97,11 @@ export const useVxeGrid = &lt;T = any&gt;(config?: UseVxeGridConfig&lt;T&gt;) =&gt; { @@ -90,9 +97,11 @@ export const useVxeGrid = &lt;T = any&gt;(config?: UseVxeGridConfig&lt;T&gt;) =&gt; {
90 } 97 }
91 }) 98 })
92 const delList = (ids: string | number | string[] | number[]) => { 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 return { 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 +7,6 @@ import enUS from &#39;vxe-table/lib/locale/lang/en-US&#39;
7 import { 7 import {
8 // 全局对象 8 // 全局对象
9 VXETable, 9 VXETable,
10 -  
11 // 表格功能 10 // 表格功能
12 Filter, 11 Filter,
13 Edit, 12 Edit,
@@ -15,7 +14,6 @@ import { @@ -15,7 +14,6 @@ import {
15 Export, 14 Export,
16 Keyboard, 15 Keyboard,
17 Validator, 16 Validator,
18 -  
19 // 可选组件 17 // 可选组件
20 Icon, 18 Icon,
21 Column, 19 Column,
@@ -42,7 +40,6 @@ import { @@ -42,7 +40,6 @@ import {
42 Modal, 40 Modal,
43 List, 41 List,
44 Pulldown, 42 Pulldown,
45 -  
46 // 表格 43 // 表格
47 Table 44 Table
48 } from 'vxe-table' 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 <script setup lang="ts"> 152 <script setup lang="ts">
2 import { ref, unref, onMounted } from 'vue' 153 import { ref, unref, onMounted } from 'vue'
3 import { DICT_TYPE } from '@/utils/dict' 154 import { DICT_TYPE } from '@/utils/dict'
@@ -148,155 +299,3 @@ onMounted(async () =&gt; { @@ -148,155 +299,3 @@ onMounted(async () =&gt; {
148 typeTableObject.tableList[0] && onClickType(typeTableObject.tableList[0]) 299 typeTableObject.tableList[0] && onClickType(typeTableObject.tableList[0])
149 }) 300 })
150 </script> 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,9 +60,9 @@
60 <template #footer> 60 <template #footer>
61 <XButton 61 <XButton
62 v-if="['create', 'update'].includes(actionType)" 62 v-if="['create', 'update'].includes(actionType)"
63 - :loading="actionLoading"  
64 - :title="t('action.save')"  
65 type="primary" 63 type="primary"
  64 + :title="t('action.save')"
  65 + :loading="actionLoading"
66 @click="submitForm" 66 @click="submitForm"
67 /> 67 />
68 <XButton :loading="actionLoading" :title="t('dialog.close')" @click="dialogVisible = false" /> 68 <XButton :loading="actionLoading" :title="t('dialog.close')" @click="dialogVisible = false" />
@@ -79,35 +79,31 @@ import { rules, allSchemas } from &#39;./post.data&#39; @@ -79,35 +79,31 @@ import { rules, allSchemas } from &#39;./post.data&#39;
79 import { useI18n } from '@/hooks/web/useI18n' 79 import { useI18n } from '@/hooks/web/useI18n'
80 import { useMessage } from '@/hooks/web/useMessage' 80 import { useMessage } from '@/hooks/web/useMessage'
81 import { useVxeGrid } from '@/hooks/web/useVxeGrid' 81 import { useVxeGrid } from '@/hooks/web/useVxeGrid'
82 -import { VxeFormEvents, VxeGridInstance } from 'vxe-table' 82 +import { VxeGridInstance } from 'vxe-table'
83 import { FormExpose } from '@/components/Form' 83 import { FormExpose } from '@/components/Form'
84 84
85 const { t } = useI18n() // 国际化 85 const { t } = useI18n() // 国际化
86 const message = useMessage() // 消息弹窗 86 const message = useMessage() // 消息弹窗
87 -const xGrid = ref<VxeGridInstance>()  
88 -const formRef = ref<FormExpose>() // 表单 Ref  
89 const dialogVisible = ref(false) // 是否显示弹出层 87 const dialogVisible = ref(false) // 是否显示弹出层
90 const dialogTitle = ref('edit') // 弹出层标题 88 const dialogTitle = ref('edit') // 弹出层标题
91 const actionType = ref('') // 操作按钮的类型 89 const actionType = ref('') // 操作按钮的类型
92 const actionLoading = ref(false) // 按钮Loading 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 const { gridOptions } = useVxeGrid<PostVO>({ 95 const { gridOptions } = useVxeGrid<PostVO>({
95 allSchemas: allSchemas, 96 allSchemas: allSchemas,
96 getListApi: PostApi.getPostPageApi 97 getListApi: PostApi.getPostPageApi
97 }) 98 })
  99 +
98 // 设置标题 100 // 设置标题
99 const setDialogTile = (type: string) => { 101 const setDialogTile = (type: string) => {
100 dialogTitle.value = t('action.' + type) 102 dialogTitle.value = t('action.' + type)
101 actionType.value = type 103 actionType.value = type
102 dialogVisible.value = true 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 const handleCreate = () => { 108 const handleCreate = () => {
113 setDialogTile('create') 109 setDialogTile('create')
@@ -115,6 +111,12 @@ const handleCreate = () =&gt; { @@ -115,6 +111,12 @@ const handleCreate = () =&gt; {
115 unref(formRef)?.getElFormRef()?.resetFields() 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 const handleUpdate = async (rowId: number) => { 121 const handleUpdate = async (rowId: number) => {
120 setDialogTile('update') 122 setDialogTile('update')
@@ -122,6 +124,7 @@ const handleUpdate = async (rowId: number) =&gt; { @@ -122,6 +124,7 @@ const handleUpdate = async (rowId: number) =&gt; {
122 const res = await PostApi.getPostApi(rowId) 124 const res = await PostApi.getPostApi(rowId)
123 unref(formRef)?.setValues(res) 125 unref(formRef)?.setValues(res)
124 } 126 }
  127 +
125 // 删除操作 128 // 删除操作
126 const handleDelete = async (rowId: number) => { 129 const handleDelete = async (rowId: number) => {
127 message 130 message
@@ -134,8 +137,9 @@ const handleDelete = async (rowId: number) =&gt; { @@ -134,8 +137,9 @@ const handleDelete = async (rowId: number) =&gt; {
134 xGrid.value?.commitProxy('query') 137 xGrid.value?.commitProxy('query')
135 }) 138 })
136 } 139 }
  140 +
137 // 提交按钮 141 // 提交按钮
138 -const submitForm: VxeFormEvents.Submit = async () => { 142 +const submitForm = async () => {
139 const elForm = unref(formRef)?.getElFormRef() 143 const elForm = unref(formRef)?.getElFormRef()
140 if (!elForm) return 144 if (!elForm) return
141 elForm.validate(async (valid) => { 145 elForm.validate(async (valid) => {
@@ -151,7 +155,6 @@ const submitForm: VxeFormEvents.Submit = async () =&gt; { @@ -151,7 +155,6 @@ const submitForm: VxeFormEvents.Submit = async () =&gt; {
151 await PostApi.updatePostApi(data) 155 await PostApi.updatePostApi(data)
152 message.success(t('common.updateSuccess')) 156 message.success(t('common.updateSuccess'))
153 } 157 }
154 - // 操作成功,重新加载列表  
155 dialogVisible.value = false 158 dialogVisible.value = false
156 } finally { 159 } finally {
157 actionLoading.value = false 160 actionLoading.value = false
yudao-ui-admin-vue3/src/views/system/post/post.data.ts
1 import { reactive } from 'vue' 1 import { reactive } from 'vue'
2 import { useI18n } from '@/hooks/web/useI18n' 2 import { useI18n } from '@/hooks/web/useI18n'
3 import { required } from '@/utils/formRules' 3 import { required } from '@/utils/formRules'
4 -import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas'  
5 import { DICT_TYPE } from '@/utils/dict' 4 import { DICT_TYPE } from '@/utils/dict'
  5 +import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas'
6 const { t } = useI18n() // 国际化 6 const { t } = useI18n() // 国际化
7 7
8 // 表单校验 8 // 表单校验
@@ -17,7 +17,7 @@ const crudSchemas = reactive&lt;VxeCrudSchema[]&gt;([ @@ -17,7 +17,7 @@ const crudSchemas = reactive&lt;VxeCrudSchema[]&gt;([
17 { 17 {
18 title: t('common.index'), 18 title: t('common.index'),
19 field: 'id', 19 field: 'id',
20 - type: 'index', 20 + type: 'seq',
21 form: { 21 form: {
22 show: false 22 show: false
23 }, 23 },