From 725cc4e41b2879862a3c2d3cca3490197d4a62a3 Mon Sep 17 00:00:00 2001 From: xingyu4j Date: Sat, 12 Nov 2022 15:52:43 +0800 Subject: [PATCH] perf: vxe --- .../src/config/axios/service.ts | 44 +-- .../src/hooks/web/useVxeCrudSchemas.ts | 63 ++++- .../src/plugins/vxeTable/index.ts | 5 + .../src/plugins/vxeTable/renderer/dict.tsx | 12 + .../src/plugins/vxeTable/renderer/index.tsx | 1 + .../views/system/errorCode/errorCode.data.ts | 107 +++----- .../src/views/system/errorCode/index.vue | 258 +++++++++--------- .../src/views/system/post/index.vue | 2 +- .../src/views/system/post/post.data.ts | 111 +++----- 9 files changed, 304 insertions(+), 299 deletions(-) create mode 100644 yudao-ui-admin-vue3/src/plugins/vxeTable/renderer/dict.tsx create mode 100644 yudao-ui-admin-vue3/src/plugins/vxeTable/renderer/index.tsx diff --git a/yudao-ui-admin-vue3/src/config/axios/service.ts b/yudao-ui-admin-vue3/src/config/axios/service.ts index cd1235e58..a392702bb 100644 --- a/yudao-ui-admin-vue3/src/config/axios/service.ts +++ b/yudao-ui-admin-vue3/src/config/axios/service.ts @@ -5,7 +5,7 @@ import axios, { AxiosResponse, AxiosError } from 'axios' -import { useMessage } from '@/hooks/web/useMessage' +import { ElMessage, ElMessageBox, ElNotification } from 'element-plus' import qs from 'qs' import { config } from '@/config/axios/config' import { getAccessToken, getRefreshToken, getTenantId, removeToken, setToken } from '@/utils/auth' @@ -17,7 +17,6 @@ import { useCache } from '@/hooks/web/useCache' const tenantEnable = import.meta.env.VITE_APP_TENANT_ENABLE const { result_code, base_url, request_timeout } = config -const message = useMessage() // 需要忽略的提示。忽略后,自动 Promise.reject('error') const ignoreMsgs = [ '无效的刷新令牌', // 刷新令牌被删除时,不用提示 @@ -30,6 +29,8 @@ export const isRelogin = { show: false } let requestList: any[] = [] // 是否正在刷新中 let isRefreshToken = false +// 请求白名单,无须token的接口 +const whiteList: string[] = ['/login', '/refresh-token'] // 创建axios实例 const service: AxiosInstance = axios.create({ @@ -42,14 +43,20 @@ const service: AxiosInstance = axios.create({ service.interceptors.request.use( (config: AxiosRequestConfig) => { // 是否需要设置 token - const isToken = (config!.headers || {}).isToken === false + let isToken = (config!.headers || {}).isToken === false + whiteList.some((v) => { + if (config.url) { + config.url.indexOf(v) > -1 + return (isToken = false) + } + }) if (getAccessToken() && !isToken) { ;(config as Recordable).headers.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token } // 设置租户 if (tenantEnable && tenantEnable === 'true') { const tenantId = getTenantId() - if (tenantId) (config as Recordable).headers.common['tenant-id'] = tenantId + if (tenantId) (config as Recordable).headers['tenant-id'] = tenantId } const params = config.params || {} const data = config.data || false @@ -157,10 +164,10 @@ service.interceptors.response.use( }) } } else if (code === 500) { - message.error(t('sys.api.errMsg500')) + ElMessage.error(t('sys.api.errMsg500')) return Promise.reject(new Error(msg)) } else if (code === 901) { - message.error( + ElMessage.error( '
' + t('sys.api.errMsg901') + '
' + @@ -175,7 +182,7 @@ service.interceptors.response.use( // hard coding:忽略这个提示,直接登出 console.log(msg) } else { - message.notifyError(msg) + ElNotification.error({ title: msg }) } return Promise.reject('error') } else { @@ -184,16 +191,16 @@ service.interceptors.response.use( }, (error: AxiosError) => { console.log('err' + error) // for debug - let { message: msg } = error + let { message } = error const { t } = useI18n() - if (msg === 'Network Error') { - msg = t('sys.api.errorMessage') - } else if (msg.includes('timeout')) { - msg = t('sys.api.apiTimeoutMessage') - } else if (msg.includes('Request failed with status code')) { - msg = t('sys.api.apiRequestFailed') + msg.substr(msg.length - 3) + if (message === 'Network Error') { + message = t('sys.api.errorMessage') + } else if (message.includes('timeout')) { + message = t('sys.api.apiTimeoutMessage') + } else if (message.includes('Request failed with status code')) { + message = t('sys.api.apiRequestFailed') + message.substr(message.length - 3) } - message.error(msg) + ElMessage.error(message) return Promise.reject(error) } ) @@ -205,8 +212,11 @@ const handleAuthorized = () => { const { t } = useI18n() if (!isRelogin.show) { isRelogin.show = true - message - .confirm(t('sys.api.timeoutMessage')) + ElMessageBox.confirm(t('sys.api.timeoutMessage'), t('common.confirmTitle'), { + confirmButtonText: t('login.relogin'), + cancelButtonText: t('common.cancel'), + type: 'warning' + }) .then(() => { const { wsCache } = useCache() resetRouter() // 重置静态路由表 diff --git a/yudao-ui-admin-vue3/src/hooks/web/useVxeCrudSchemas.ts b/yudao-ui-admin-vue3/src/hooks/web/useVxeCrudSchemas.ts index 4eafbcbdb..4ba77f32f 100644 --- a/yudao-ui-admin-vue3/src/hooks/web/useVxeCrudSchemas.ts +++ b/yudao-ui-admin-vue3/src/hooks/web/useVxeCrudSchemas.ts @@ -14,7 +14,15 @@ import { VxeTableColumn } from '@/types/table' import { FormSchema } from '@/types/form' import { ComponentOptions } from '@/types/components' -export type VxeCrudSchema = Omit & { +export type VxeCrudSchema = { + // 主键ID + primaryKey?: string + primaryType?: VxeColumnPropTypes.Type + // 是否开启操作栏插槽 + action?: boolean + columns: VxeCrudColumns[] +} +type VxeCrudColumns = Omit & { field: string title?: string formatter?: VxeColumnPropTypes.Formatter @@ -23,7 +31,7 @@ export type VxeCrudSchema = Omit & { form?: CrudFormParams detail?: CrudDescriptionsParams print?: CrudPrintParams - children?: VxeCrudSchema[] + children?: VxeCrudColumns[] dictType?: string } type CrudSearchParams = { @@ -61,7 +69,7 @@ export type VxeAllSchemas = { // 过滤所有结构 export const useVxeCrudSchemas = ( - crudSchema: VxeCrudSchema[] + crudSchema: VxeCrudSchema ): { allSchemas: VxeAllSchemas } => { @@ -95,10 +103,10 @@ export const useVxeCrudSchemas = ( } // 过滤 Search 结构 -const filterSearchSchema = (crudSchema: VxeCrudSchema[]): VxeFormItemProps[] => { +const filterSearchSchema = (crudSchema: VxeCrudSchema): VxeFormItemProps[] => { const searchSchema: VxeFormItemProps[] = [] const { t } = useI18n() - eachTree(crudSchema, (schemaItem: VxeCrudSchema) => { + eachTree(crudSchema.columns, (schemaItem: VxeCrudColumns) => { // 判断是否显示 if (schemaItem?.search?.show) { let itemRenderName = schemaItem?.search?.itemRender?.name || '$input' @@ -154,9 +162,20 @@ const filterSearchSchema = (crudSchema: VxeCrudSchema[]): VxeFormItemProps[] => } // 过滤 table 结构 -const filterTableSchema = (crudSchema: VxeCrudSchema[]): VxeGridPropTypes.Columns => { +const filterTableSchema = (crudSchema: VxeCrudSchema): VxeGridPropTypes.Columns => { + const { t } = useI18n() const tableSchema: VxeGridPropTypes.Columns = [] - eachTree(crudSchema, (schemaItem: VxeCrudSchema) => { + // 主键ID + if (crudSchema.primaryKey) { + const tableSchemaItem = { + title: t('common.index'), + field: crudSchema.primaryKey, + type: crudSchema.primaryType ? crudSchema.primaryType : 'seq', + width: '50px' + } + tableSchema.push(tableSchemaItem) + } + eachTree(crudSchema.columns, (schemaItem: VxeCrudColumns) => { // 判断是否显示 if (schemaItem?.table?.show !== false) { const tableSchemaItem = { @@ -167,6 +186,12 @@ const filterTableSchema = (crudSchema: VxeCrudSchema[]): VxeGridPropTypes.Column if (schemaItem?.formatter) { tableSchemaItem.formatter = schemaItem.formatter } + if (schemaItem?.dictType) { + tableSchemaItem.cellRender = { + name: 'XDict', + content: schemaItem.dictType + } + } // 删除不必要的字段 delete tableSchemaItem.show @@ -174,14 +199,26 @@ const filterTableSchema = (crudSchema: VxeCrudSchema[]): VxeGridPropTypes.Column tableSchema.push(tableSchemaItem) } }) + // 操作栏插槽 + if (crudSchema.action && crudSchema.action == true) { + const tableSchemaItem = { + title: t('table.action'), + field: 'actionbtns', + width: '240px', + slots: { + default: 'actionbtns_default' + } + } + tableSchema.push(tableSchemaItem) + } return tableSchema } // 过滤 form 结构 -const filterFormSchema = (crudSchema: VxeCrudSchema[]): FormSchema[] => { +const filterFormSchema = (crudSchema: VxeCrudSchema): FormSchema[] => { const formSchema: FormSchema[] = [] - eachTree(crudSchema, (schemaItem: VxeCrudSchema) => { + eachTree(crudSchema.columns, (schemaItem: VxeCrudColumns) => { // 判断是否显示 if (schemaItem?.form?.show !== false) { let component = schemaItem?.form?.component || 'Input' @@ -216,10 +253,10 @@ const filterFormSchema = (crudSchema: VxeCrudSchema[]): FormSchema[] => { } // 过滤 descriptions 结构 -const filterDescriptionsSchema = (crudSchema: VxeCrudSchema[]): DescriptionsSchema[] => { +const filterDescriptionsSchema = (crudSchema: VxeCrudSchema): DescriptionsSchema[] => { const descriptionsSchema: DescriptionsSchema[] = [] - eachTree(crudSchema, (schemaItem: VxeCrudSchema) => { + eachTree(crudSchema.columns, (schemaItem: VxeCrudColumns) => { // 判断是否显示 if (schemaItem?.detail?.show !== false) { const descriptionsSchemaItem = { @@ -239,10 +276,10 @@ const filterDescriptionsSchema = (crudSchema: VxeCrudSchema[]): DescriptionsSche } // 过滤 打印 结构 -const filterPrintSchema = (crudSchema: VxeCrudSchema[]): any[] => { +const filterPrintSchema = (crudSchema: VxeCrudSchema): any[] => { const printSchema: any[] = [] - eachTree(crudSchema, (schemaItem: VxeCrudSchema) => { + eachTree(crudSchema.columns, (schemaItem: VxeCrudColumns) => { // 判断是否显示 if (schemaItem?.print?.show !== false) { const printSchemaItem = { diff --git a/yudao-ui-admin-vue3/src/plugins/vxeTable/index.ts b/yudao-ui-admin-vue3/src/plugins/vxeTable/index.ts index 1da528f70..3873cfa78 100644 --- a/yudao-ui-admin-vue3/src/plugins/vxeTable/index.ts +++ b/yudao-ui-admin-vue3/src/plugins/vxeTable/index.ts @@ -1,6 +1,7 @@ import { App, unref } from 'vue' import 'xe-utils' import XEUtils from 'xe-utils' +import './renderer' import { i18n } from '@/plugins/vueI18n' import zhCN from 'vxe-table/es/locale/lang/zh-CN' import enUS from 'vxe-table/lib/locale/lang/en-US' @@ -138,6 +139,10 @@ VXETable.formats.mixin({ formatDate({ cellValue }, format) { return XEUtils.toDateString(cellValue, format || 'yyyy-MM-dd HH:mm:ss') }, + // 格式字典 + formatDict() { + return 'cellValue 123' + }, // 四舍五入金额,每隔3位逗号分隔,默认2位数 formatAmount({ cellValue }, digits = 2) { return XEUtils.commafy(Number(cellValue), { digits }) diff --git a/yudao-ui-admin-vue3/src/plugins/vxeTable/renderer/dict.tsx b/yudao-ui-admin-vue3/src/plugins/vxeTable/renderer/dict.tsx new file mode 100644 index 000000000..b0c301ece --- /dev/null +++ b/yudao-ui-admin-vue3/src/plugins/vxeTable/renderer/dict.tsx @@ -0,0 +1,12 @@ +import { DictTag } from '@/components/DictTag' +import { VXETable } from 'vxe-table' + +// 创建一个简单的超链接渲染 +VXETable.renderer.add('XDict', { + // 默认显示模板 + renderDefault(renderOpts, params) { + const { row, column } = params + const { content } = renderOpts + return + } +}) diff --git a/yudao-ui-admin-vue3/src/plugins/vxeTable/renderer/index.tsx b/yudao-ui-admin-vue3/src/plugins/vxeTable/renderer/index.tsx new file mode 100644 index 000000000..3b5b5f8a3 --- /dev/null +++ b/yudao-ui-admin-vue3/src/plugins/vxeTable/renderer/index.tsx @@ -0,0 +1 @@ +import './dict' diff --git a/yudao-ui-admin-vue3/src/views/system/errorCode/errorCode.data.ts b/yudao-ui-admin-vue3/src/views/system/errorCode/errorCode.data.ts index 6228b3ccb..f70438a25 100644 --- a/yudao-ui-admin-vue3/src/views/system/errorCode/errorCode.data.ts +++ b/yudao-ui-admin-vue3/src/views/system/errorCode/errorCode.data.ts @@ -2,9 +2,8 @@ import { reactive } from 'vue' import { required } from '@/utils/formRules' import { useI18n } from '@/hooks/web/useI18n' import { DICT_TYPE } from '@/utils/dict' -import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas' -// 国际化 -const { t } = useI18n() +import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas' +const { t } = useI18n() // 国际化 // 表单校验 export const rules = reactive({ applicationName: [required], @@ -12,71 +11,45 @@ export const rules = reactive({ message: [required] }) // 新增 + 修改 -const crudSchemas = reactive([ - { - label: t('common.index'), - field: 'id', - type: 'index', - form: { - show: false +const crudSchemas = reactive({ + primaryKey: 'id', + primaryType: 'seq', + action: true, + columns: [ + { + title: '错误码类型', + field: 'type', + dictType: DICT_TYPE.SYSTEM_ERROR_CODE_TYPE, + search: { + show: true + } }, - detail: { - show: false - } - }, - { - label: '错误码类型', - field: 'type', - component: 'InputNumber', - dictType: DICT_TYPE.SYSTEM_ERROR_CODE_TYPE, - search: { - show: true - } - }, - { - label: '应用名', - field: 'applicationName', - search: { - show: true - } - }, - { - label: '错误码编码', - field: 'code', - search: { - show: true - } - }, - { - label: '错误码错误提示', - field: 'message' - }, - { - label: t('common.createTime'), - field: 'createTime', - form: { - show: false + { + title: '应用名', + field: 'applicationName', + search: { + show: true + } }, - search: { - show: true, - component: 'DatePicker', - componentProps: { - type: 'daterange', - valueFormat: 'YYYY-MM-DD HH:mm:ss', - defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)] + { + title: '错误码编码', + field: 'code', + search: { + show: true + } + }, + { + title: '错误码错误提示', + field: 'message' + }, + { + title: t('common.createTime'), + field: 'createTime', + formatter: 'formatDate', + form: { + show: false } } - }, - { - field: 'action', - width: '240px', - label: t('table.action'), - form: { - show: false - }, - detail: { - show: false - } - } -]) -export const { allSchemas } = useCrudSchemas(crudSchemas) + ] +}) +export const { allSchemas } = useVxeCrudSchemas(crudSchemas) diff --git a/yudao-ui-admin-vue3/src/views/system/errorCode/index.vue b/yudao-ui-admin-vue3/src/views/system/errorCode/index.vue index a0fb96c32..6df7499cf 100644 --- a/yudao-ui-admin-vue3/src/views/system/errorCode/index.vue +++ b/yudao-ui-admin-vue3/src/views/system/errorCode/index.vue @@ -1,30 +1,114 @@ + + - - diff --git a/yudao-ui-admin-vue3/src/views/system/post/index.vue b/yudao-ui-admin-vue3/src/views/system/post/index.vue index 8a768611c..7e25329bf 100644 --- a/yudao-ui-admin-vue3/src/views/system/post/index.vue +++ b/yudao-ui-admin-vue3/src/views/system/post/index.vue @@ -13,7 +13,7 @@ -