From 5212ea79b43c832a5136354b549de8f89b6e2156 Mon Sep 17 00:00:00 2001 From: vben Date: Tue, 8 Jun 2021 00:15:34 +0800 Subject: [PATCH 01/56] fix: build error --- package.json | 2 +- src/locales/useLocale.ts | 4 ++-- yarn.lock | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index bb78fd4e..e395a4cb 100644 --- a/package.json +++ b/package.json @@ -111,7 +111,7 @@ "stylelint-order": "^4.1.0", "ts-node": "^10.0.0", "typescript": "4.3.2", - "vite": "2.3.6", + "vite": "2.3.3", "vite-plugin-compression": "^0.2.5", "vite-plugin-html": "^2.0.7", "vite-plugin-imagemin": "^0.3.2", diff --git a/src/locales/useLocale.ts b/src/locales/useLocale.ts index 8c645d2a..19fff076 100644 --- a/src/locales/useLocale.ts +++ b/src/locales/useLocale.ts @@ -3,7 +3,7 @@ */ import type { LocaleType } from '/#/config'; -import { updateLocale } from 'moment'; +import moment from 'moment'; import { i18n } from './setupI18n'; import { useLocaleStoreWithOut } from '/@/store/modules/locale'; @@ -56,7 +56,7 @@ export function useLocale() { const { message, momentLocale, momentLocaleName } = langModule; globalI18n.setLocaleMessage(locale, message); - updateLocale(momentLocaleName, momentLocale); + moment.updateLocale(momentLocaleName, momentLocale); loadLocalePool.push(locale); setI18nLanguage(locale); diff --git a/yarn.lock b/yarn.lock index bd123587..bc5cb871 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10662,12 +10662,12 @@ vite-plugin-windicss@^1.0.1: debug "^4.3.2" windicss "^3.1.0" -vite@2.3.6: - version "2.3.6" - resolved "https://registry.npmjs.org/vite/-/vite-2.3.6.tgz#1f7cfde88a51a802d69000c7bac85d481c2e871c" - integrity sha512-fsEpNKDHgh3Sn66JH06ZnUBnIgUVUtw6ucDhlOj1CEqxIkymU25yv1/kWDPlIjyYHnalr0cN6V+zzUJ+fmWHYw== +vite@2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/vite/-/vite-2.3.3.tgz#7e88a71abd03985c647789938d784cce0ee3b0fd" + integrity sha512-eO1iwRbn3/BfkNVMNJDeANAFCZ5NobYOFPu7IqfY7DcI7I9nFGjJIZid0EViTmLDGwwSUPmRAq3cRBbO3+DsMA== dependencies: - esbuild "^0.12.5" + esbuild "^0.11.23" postcss "^8.2.10" resolve "^1.19.0" rollup "^2.38.5" From 8e4f486fcf835f0b6f2a95676dba268ffdd0566e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=97=A0=E6=9C=A8?= Date: Tue, 8 Jun 2021 01:08:04 +0800 Subject: [PATCH 02/56] feat(table): add updateTableDataRecord method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加updateTableDataRecord以便可以根据指定的rowKey来直接更新行数据而无需reload --- src/components/Table/src/BasicTable.vue | 2 ++ .../Table/src/hooks/useDataSource.ts | 21 +++++++++++++++++++ src/components/Table/src/hooks/useTable.ts | 3 +++ src/components/Table/src/types/table.ts | 1 + 4 files changed, 27 insertions(+) diff --git a/src/components/Table/src/BasicTable.vue b/src/components/Table/src/BasicTable.vue index 546af304..0ee35b22 100644 --- a/src/components/Table/src/BasicTable.vue +++ b/src/components/Table/src/BasicTable.vue @@ -129,6 +129,7 @@ getDataSourceRef, getDataSource, setTableData, + updateTableDataRecord, fetch, getRowKey, reload, @@ -265,6 +266,7 @@ deleteSelectRowByKey, setPagination, setTableData, + updateTableDataRecord, redoHeight, setSelectedRowKeys, setColumns, diff --git a/src/components/Table/src/hooks/useDataSource.ts b/src/components/Table/src/hooks/useDataSource.ts index 1d161abd..6dfd15cf 100644 --- a/src/components/Table/src/hooks/useDataSource.ts +++ b/src/components/Table/src/hooks/useDataSource.ts @@ -149,6 +149,26 @@ export function useDataSource( return dataSourceRef.value[index]; } + function updateTableDataRecord( + rowKey: string | number, + record: Recordable + ): Recordable | undefined { + if (!dataSourceRef.value || dataSourceRef.value.length == 0) return; + const rowKeyName = unref(getRowKey); + if (typeof rowKeyName !== 'string') { + return; + } + const row = dataSourceRef.value.find( + (r) => Reflect.has(r, rowKeyName as string) && r[rowKeyName as string] === rowKey + ); + if (row) { + for (const field in row) { + if (Reflect.has(record, field)) row[field] = record[field]; + } + return row; + } + } + async function fetch(opt?: FetchParams) { const { api, searchInfo, fetchSetting, beforeFetch, afterFetch, useSearchForm, pagination } = unref(propsRef); @@ -255,6 +275,7 @@ export function useDataSource( fetch, reload, updateTableData, + updateTableDataRecord, handleTableChange, }; } diff --git a/src/components/Table/src/hooks/useTable.ts b/src/components/Table/src/hooks/useTable.ts index 740420a5..59f82226 100644 --- a/src/components/Table/src/hooks/useTable.ts +++ b/src/components/Table/src/hooks/useTable.ts @@ -120,6 +120,9 @@ export function useTable(tableProps?: Props): [ updateTableData: (index: number, key: string, value: any) => { return getTableInstance().updateTableData(index, key, value); }, + updateTableDataRecord: (rowKey: string | number, record: Recordable) => { + return getTableInstance().updateTableDataRecord(rowKey, record); + }, getRowSelection: () => { return toRaw(getTableInstance().getRowSelection()); }, diff --git a/src/components/Table/src/types/table.ts b/src/components/Table/src/types/table.ts index 9b5b217a..09ea636d 100644 --- a/src/components/Table/src/types/table.ts +++ b/src/components/Table/src/types/table.ts @@ -94,6 +94,7 @@ export interface TableActionType { deleteSelectRowByKey: (key: string) => void; setPagination: (info: Partial) => void; setTableData: (values: T[]) => void; + updateTableDataRecord: (rowKey: string | number, record: Recordable) => Recordable | void; getColumns: (opt?: GetColumnsParams) => BasicColumn[]; setColumns: (columns: BasicColumn[] | string[]) => void; getDataSource: () => T[]; From 21f7a854fe2455315287d04e895661ff739bce17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=97=A0=E6=9C=A8?= Date: Tue, 8 Jun 2021 01:13:22 +0800 Subject: [PATCH 03/56] fix(demo): account list page validate and save --- src/views/demo/system/account/AccountModal.vue | 4 +++- src/views/demo/system/account/account.data.ts | 2 +- src/views/demo/system/account/index.vue | 14 +++++++++++--- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/views/demo/system/account/AccountModal.vue b/src/views/demo/system/account/AccountModal.vue index 0dbcaa9c..d0c5fb34 100644 --- a/src/views/demo/system/account/AccountModal.vue +++ b/src/views/demo/system/account/AccountModal.vue @@ -16,6 +16,7 @@ emits: ['success', 'register'], setup(_, { emit }) { const isUpdate = ref(true); + const rowId = ref(''); const [registerForm, { setFieldsValue, updateSchema, resetFields, validate }] = useForm({ labelWidth: 100, @@ -32,6 +33,7 @@ isUpdate.value = !!data?.isUpdate; if (unref(isUpdate)) { + rowId.value = data.record.id; setFieldsValue({ ...data.record, }); @@ -59,7 +61,7 @@ // TODO custom api console.log(values); closeModal(); - emit('success'); + emit('success', { isUpdate: unref(isUpdate), values: { ...values, id: rowId.value } }); } finally { setModalProps({ confirmLoading: false }); } diff --git a/src/views/demo/system/account/account.data.ts b/src/views/demo/system/account/account.data.ts index 1a6d3841..9cca907e 100644 --- a/src/views/demo/system/account/account.data.ts +++ b/src/views/demo/system/account/account.data.ts @@ -61,7 +61,7 @@ export const accountFormSchema: FormSchema[] = [ label: '密码', component: 'InputPassword', required: true, - show: false, + ifShow: false, }, { label: '角色', diff --git a/src/views/demo/system/account/index.vue b/src/views/demo/system/account/index.vue index 06864299..158ebd55 100644 --- a/src/views/demo/system/account/index.vue +++ b/src/views/demo/system/account/index.vue @@ -45,9 +45,10 @@ components: { BasicTable, PageWrapper, DeptTree, AccountModal, TableAction }, setup() { const [registerModal, { openModal }] = useModal(); - const [registerTable, { reload }] = useTable({ + const [registerTable, { reload, updateTableDataRecord }] = useTable({ title: '账号列表', api: getAccountList, + rowKey: 'id', columns, formConfig: { labelWidth: 120, @@ -82,8 +83,15 @@ console.log(record); } - function handleSuccess() { - reload(); + function handleSuccess({ isUpdate, values }) { + if (isUpdate) { + // 演示不刷新表格直接更新内部数据。 + // 注意:updateTableDataRecord要求表格的rowKey属性为string并且存在于每一行的record的keys中 + const result = updateTableDataRecord(values.id, values); + console.log(result); + } else { + reload(); + } } function handleSelect(deptId = '') { From 6d5f9aa699c5da8af6bf5841baddc4a8bd603917 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=97=A0=E6=9C=A8?= Date: Tue, 8 Jun 2021 10:55:33 +0800 Subject: [PATCH 04/56] feat(modal): add closeModal for useModal --- src/components/Modal/src/hooks/useModal.ts | 4 ++++ src/components/Modal/src/types.ts | 1 + 2 files changed, 5 insertions(+) diff --git a/src/components/Modal/src/hooks/useModal.ts b/src/components/Modal/src/hooks/useModal.ts index 25384d18..728564f9 100644 --- a/src/components/Modal/src/hooks/useModal.ts +++ b/src/components/Modal/src/hooks/useModal.ts @@ -90,6 +90,10 @@ export function useModal(): UseModalReturnType { dataTransferRef[unref(uidRef)] = toRaw(data); } }, + + closeModal: () => { + getInstance()?.setModalProps({ visible: false }); + }, }; return [register, methods]; } diff --git a/src/components/Modal/src/types.ts b/src/components/Modal/src/types.ts index 55e4f6ef..71aa9ae9 100644 --- a/src/components/Modal/src/types.ts +++ b/src/components/Modal/src/types.ts @@ -13,6 +13,7 @@ export type RegisterFn = (modalMethods: ModalMethods, uuid?: string) => void; export interface ReturnMethods extends ModalMethods { openModal: (props?: boolean, data?: T, openOnSet?: boolean) => void; + closeModal: () => void; getVisible?: ComputedRef; } From f62f378f42644f87b9ef2fe151db937d3aa93175 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leo=20Caan=20=28=E9=99=88=E6=A0=8B=29?= Date: Tue, 8 Jun 2021 14:28:19 +0800 Subject: [PATCH 05/56] chore: add util for install component (#707) --- src/components/CodeEditor/index.ts | 15 +++------------ src/components/FlowChart/index.ts | 8 ++------ src/utils/install.ts | 12 ++++++++++++ 3 files changed, 17 insertions(+), 18 deletions(-) create mode 100644 src/utils/install.ts diff --git a/src/components/CodeEditor/index.ts b/src/components/CodeEditor/index.ts index 89aa8a0e..faefea51 100644 --- a/src/components/CodeEditor/index.ts +++ b/src/components/CodeEditor/index.ts @@ -1,15 +1,6 @@ -import type { App } from 'vue'; +import { install } from '/@/utils/install'; import codeEditor from './src/CodeEditor.vue'; import jsonPreview from './src/json-preview/JsonPreview.vue'; -export const CodeEditor = Object.assign(codeEditor, { - install(app: App) { - app.component(codeEditor.name, codeEditor); - }, -}); - -export const JsonPreview = Object.assign(jsonPreview, { - install(app: App) { - app.component(jsonPreview.name, jsonPreview); - }, -}); +export const CodeEditor = install(codeEditor); +export const JsonPreview = install(jsonPreview); diff --git a/src/components/FlowChart/index.ts b/src/components/FlowChart/index.ts index f4446a70..30688353 100644 --- a/src/components/FlowChart/index.ts +++ b/src/components/FlowChart/index.ts @@ -1,8 +1,4 @@ -import type { App } from 'vue'; +import { install } from '/@/utils/install'; import flowChart from './src/FlowChart.vue'; -export const FlowChart = Object.assign(flowChart, { - install(app: App) { - app.component(flowChart.name, flowChart); - }, -}); +export const FlowChart = install(flowChart); diff --git a/src/utils/install.ts b/src/utils/install.ts new file mode 100644 index 00000000..f2687b26 --- /dev/null +++ b/src/utils/install.ts @@ -0,0 +1,12 @@ +import { App, Plugin } from 'vue'; + +export const install = (component: T, alias?: string) => { + const C = component as any; + C.install = (app: App) => { + app.component(C.name, component); + if (alias) { + app.config.globalProperties[alias] = component; + } + }; + return component as T & Plugin; +}; From 448a4c2809672480f8f635d7cc4661554112598a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=97=A0=E6=9C=A8?= Date: Tue, 8 Jun 2021 11:19:11 +0800 Subject: [PATCH 06/56] feat(table): updateTableDataRecord support functional rowKey --- src/components/Table/src/hooks/useDataSource.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/components/Table/src/hooks/useDataSource.ts b/src/components/Table/src/hooks/useDataSource.ts index 6dfd15cf..d3bfa3db 100644 --- a/src/components/Table/src/hooks/useDataSource.ts +++ b/src/components/Table/src/hooks/useDataSource.ts @@ -155,12 +155,16 @@ export function useDataSource( ): Recordable | undefined { if (!dataSourceRef.value || dataSourceRef.value.length == 0) return; const rowKeyName = unref(getRowKey); - if (typeof rowKeyName !== 'string') { + if (!rowKeyName) { return; } - const row = dataSourceRef.value.find( - (r) => Reflect.has(r, rowKeyName as string) && r[rowKeyName as string] === rowKey - ); + const row = dataSourceRef.value.find((r) => { + if (typeof rowKeyName === 'function') { + return (rowKeyName(r) as string) === rowKey; + } else { + return Reflect.has(r, rowKeyName) && r[rowKeyName] === rowKey; + } + }); if (row) { for (const field in row) { if (Reflect.has(record, field)) row[field] = record[field]; From df8cd860514f32f44847dcf724f0737ed4d8b9e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=97=A0=E6=9C=A8?= Date: Tue, 8 Jun 2021 15:06:04 +0800 Subject: [PATCH 07/56] fix(router): loss `directory` route MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复"目录"路由丢失的问题 fix: #722 --- src/router/helper/routeHelper.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/router/helper/routeHelper.ts b/src/router/helper/routeHelper.ts index 7148626c..e85bf32f 100644 --- a/src/router/helper/routeHelper.ts +++ b/src/router/helper/routeHelper.ts @@ -2,7 +2,7 @@ import type { AppRouteModule, AppRouteRecordRaw } from '/@/router/types'; import type { Router, RouteRecordNormalized } from 'vue-router'; import { getParentLayout, LAYOUT } from '/@/router/constant'; -import { cloneDeep } from 'lodash-es'; +import { cloneDeep, omit } from 'lodash-es'; import { warn } from '/@/utils/log'; import { createRouter, createWebHashHistory } from 'vue-router'; @@ -73,7 +73,7 @@ export function transformObjToRoute(routeList: AppRouteModul } route.children && asyncImportRoute(route.children); }); - return (routeList as unknown) as T[]; + return routeList as unknown as T[]; } /** @@ -95,7 +95,7 @@ export function flatMultiLevelRoutes(routeModules: AppRouteModule[]) { function promoteRouteLevel(routeModule: AppRouteModule) { // Use vue-router to splice menus let router: Router | null = createRouter({ - routes: [(routeModule as unknown) as RouteRecordNormalized], + routes: [routeModule as unknown as RouteRecordNormalized], history: createWebHashHistory(), }); @@ -103,7 +103,7 @@ function promoteRouteLevel(routeModule: AppRouteModule) { addToChildren(routes, routeModule.children || [], routeModule); router = null; - routeModule.children = routeModule.children?.filter((item) => !item.children?.length); + routeModule.children = routeModule.children?.map((item) => omit(item, 'children')); } // Add all sub-routes to the secondary route @@ -120,7 +120,7 @@ function addToChildren( } routeModule.children = routeModule.children || []; if (!routeModule.children.find((item) => item.name === route.name)) { - routeModule.children?.push((route as unknown) as AppRouteModule); + routeModule.children?.push(route as unknown as AppRouteModule); } if (child.children?.length) { addToChildren(routes, child.children, routeModule); From 84d9300e52fa73da575591aa4b71858a7e459c8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=97=A0=E6=9C=A8?= Date: Tue, 8 Jun 2021 16:45:42 +0800 Subject: [PATCH 08/56] fix(demo): `breadcrumb` route invalid redirect --- src/router/menus/modules/demo/feat.ts | 2 +- src/router/routes/modules/demo/feat.ts | 16 +++------------- .../demo/feat/breadcrumb/ChildrenListDetail.vue | 8 +++++--- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/src/router/menus/modules/demo/feat.ts b/src/router/menus/modules/demo/feat.ts index b45ffd9f..23062e59 100644 --- a/src/router/menus/modules/demo/feat.ts +++ b/src/router/menus/modules/demo/feat.ts @@ -112,7 +112,7 @@ const menu: MenuModule = { // }, { path: 'children', - name: t('routes.demo.feat.breadcrumbChildrenDetail'), + name: t('routes.demo.feat.breadcrumbChildren'), }, ], }, diff --git a/src/router/routes/modules/demo/feat.ts b/src/router/routes/modules/demo/feat.ts index 85ec0cea..6a51be42 100644 --- a/src/router/routes/modules/demo/feat.ts +++ b/src/router/routes/modules/demo/feat.ts @@ -86,21 +86,11 @@ const feat: AppRouteModule = { { path: 'children', name: 'BreadcrumbChildrenDemo', - component: getParentLayout('BreadcrumbChildrenDemo'), - redirect: '/feat/breadcrumb/children', + component: () => import('/@/views/demo/feat/breadcrumb/ChildrenList.vue'), meta: { - title: t('routes.demo.feat.breadcrumbFlat'), + title: t('routes.demo.feat.breadcrumbChildren'), }, children: [ - { - path: '', - name: 'BreadcrumbChildren', - component: () => import('/@/views/demo/feat/breadcrumb/ChildrenList.vue'), - meta: { - title: t('routes.demo.feat.breadcrumbChildren'), - // hideBreadcrumb: true, - }, - }, { path: 'childrenDetail', name: 'BreadcrumbChildrenDetailDemo', @@ -108,7 +98,7 @@ const feat: AppRouteModule = { meta: { currentActiveMenu: '/feat/breadcrumb/children', title: t('routes.demo.feat.breadcrumbChildrenDetail'), - hideTab: true, + //hideTab: true, // hideMenu: true, }, }, diff --git a/src/views/demo/feat/breadcrumb/ChildrenListDetail.vue b/src/views/demo/feat/breadcrumb/ChildrenListDetail.vue index f37c3675..4994c44d 100644 --- a/src/views/demo/feat/breadcrumb/ChildrenListDetail.vue +++ b/src/views/demo/feat/breadcrumb/ChildrenListDetail.vue @@ -1,8 +1,10 @@ From 55e9d9fc2953643cec95c74b6ed34b0e68641fb6 Mon Sep 17 00:00:00 2001 From: Vben Date: Wed, 9 Jun 2021 00:22:05 +0800 Subject: [PATCH 09/56] perf: optimize components and add comments --- package.json | 16 +- src/components/Application/index.ts | 19 +- .../Application/src/AppDarkModeToggle.vue | 28 ++- .../Application/src/AppLocalePicker.vue | 37 ++-- src/components/Application/src/AppLogo.vue | 70 ++++---- .../Application/src/AppProvider.vue | 22 ++- .../Application/src/search/AppSearch.vue | 2 +- .../src/search/AppSearchFooter.vue | 15 +- .../src/search/AppSearchKeyItem.vue | 4 +- .../Application/src/search/AppSearchModal.vue | 21 +-- .../Application/src/search/useMenuSearch.ts | 31 +++- .../Application/src/useAppContext.ts | 1 - src/components/Authority/index.ts | 5 +- src/components/Authority/src/Authority.vue | 3 - src/components/Basic/index.ts | 11 +- src/components/Basic/src/BasicArrow.vue | 49 ++--- src/components/Basic/src/BasicHelp.vue | 108 +++++------ src/components/Basic/src/BasicTitle.vue | 37 ++-- src/components/Button/index.ts | 8 +- src/components/Button/src/BasicButton.vue | 12 +- .../Button/src/PopConfirmButton.vue | 2 +- src/components/ClickOutSide/index.ts | 5 +- src/components/CodeEditor/index.ts | 6 +- src/components/CodeEditor/src/CodeEditor.vue | 44 +++-- .../CodeEditor/src/codemirror/CodeMirror.vue | 36 ++-- .../CodeEditor/src/codemirror/codemirror.css | 59 ++---- .../src/json-preview/JsonPreview.vue | 8 +- src/components/Container/index.ts | 14 +- .../Container/src/LazyContainer.vue | 66 ++++--- .../Container/src/ScrollContainer.vue | 9 +- .../src/collapse/CollapseContainer.vue | 64 +++---- .../Container/src/collapse/CollapseHeader.vue | 23 +-- .../Container/src/{types.ts => typing.ts} | 0 src/components/FlowChart/index.ts | 4 +- .../Form/src/components/FormAction.vue | 20 +-- src/utils/index.ts | 13 ++ src/utils/install.ts | 12 -- src/views/sys/login/Login.vue | 3 +- types/module.d.ts | 4 +- yarn.lock | 169 +++++++++--------- 40 files changed, 533 insertions(+), 527 deletions(-) rename src/components/Container/src/{types.ts => typing.ts} (100%) delete mode 100644 src/utils/install.ts diff --git a/package.json b/package.json index e395a4cb..b2c36f42 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "@iconify/iconify": "^2.0.1", "@logicflow/core": "^0.4.11", "@logicflow/extension": "^0.4.12", - "@vueuse/core": "^4.11.2", + "@vueuse/core": "^5.0.1", "@zxcvbn-ts/core": "^0.3.0", "ant-design-vue": "2.1.2", "axios": "^0.21.1", @@ -63,7 +63,7 @@ "devDependencies": { "@commitlint/cli": "^12.1.4", "@commitlint/config-conventional": "^12.1.4", - "@iconify/json": "^1.1.353", + "@iconify/json": "^1.1.354", "@purge-icons/generated": "^0.7.0", "@types/codemirror": "^5.60.0", "@types/crypto-js": "^4.0.1", @@ -71,13 +71,13 @@ "@types/inquirer": "^7.3.1", "@types/lodash-es": "^4.17.4", "@types/mockjs": "^1.0.3", - "@types/node": "^15.12.1", + "@types/node": "^15.12.2", "@types/nprogress": "^0.2.0", "@types/qrcode": "^1.4.0", "@types/qs": "^6.9.6", "@types/sortablejs": "^1.10.6", - "@typescript-eslint/eslint-plugin": "^4.26.0", - "@typescript-eslint/parser": "^4.26.0", + "@typescript-eslint/eslint-plugin": "^4.26.1", + "@typescript-eslint/parser": "^4.26.1", "@vitejs/plugin-legacy": "^1.4.1", "@vitejs/plugin-vue": "^1.2.3", "@vitejs/plugin-vue-jsx": "^1.1.5", @@ -92,7 +92,7 @@ "eslint-define-config": "^1.0.8", "eslint-plugin-prettier": "^3.4.0", "eslint-plugin-vue": "^7.10.0", - "esno": "^0.7.0", + "esno": "^0.7.1", "fs-extra": "^10.0.0", "http-server": "^0.12.3", "husky": "^6.0.0", @@ -121,14 +121,14 @@ "vite-plugin-style-import": "^0.10.1", "vite-plugin-svg-icons": "^0.7.0", "vite-plugin-theme": "^0.8.1", - "vite-plugin-windicss": "^1.0.1", + "vite-plugin-windicss": "^1.0.2", "vue-eslint-parser": "^7.6.0", "vue-tsc": "^0.1.7" }, "resolutions": { "//": "Used to install imagemin dependencies, because imagemin may not be installed in China. If it is abroad, you can delete it", "bin-wrapper": "npm:bin-wrapper-china", - "rollup": "^2.51.0" + "rollup": "^2.51.1" }, "repository": { "type": "git", diff --git a/src/components/Application/index.ts b/src/components/Application/index.ts index c1b8fb8b..d7c51330 100644 --- a/src/components/Application/index.ts +++ b/src/components/Application/index.ts @@ -1,8 +1,15 @@ -import AppLogo from './src/AppLogo.vue'; -import AppProvider from './src/AppProvider.vue'; -import AppSearch from './src/search/AppSearch.vue'; -import AppLocalePicker from './src/AppLocalePicker.vue'; -import AppDarkModeToggle from './src/AppDarkModeToggle.vue'; +import { withInstall } from '/@/utils'; + +import appLogo from './src/AppLogo.vue'; +import appProvider from './src/AppProvider.vue'; +import appSearch from './src/search/AppSearch.vue'; +import appLocalePicker from './src/AppLocalePicker.vue'; +import appDarkModeToggle from './src/AppDarkModeToggle.vue'; export { useAppProviderContext } from './src/useAppContext'; -export { AppLogo, AppProvider, AppSearch, AppLocalePicker, AppDarkModeToggle }; + +export const AppLogo = withInstall(appLogo); +export const AppProvider = withInstall(appProvider); +export const AppSearch = withInstall(appSearch); +export const AppLocalePicker = withInstall(appLocalePicker); +export const AppDarkModeToggle = withInstall(appDarkModeToggle); diff --git a/src/components/Application/src/AppDarkModeToggle.vue b/src/components/Application/src/AppDarkModeToggle.vue index 9363c1ae..bfc7dfb8 100644 --- a/src/components/Application/src/AppDarkModeToggle.vue +++ b/src/components/Application/src/AppDarkModeToggle.vue @@ -1,14 +1,5 @@ diff --git a/src/components/ContextMenu/src/createContextMenu.ts b/src/components/ContextMenu/src/createContextMenu.ts index 5fc3ed45..8f7a1c82 100644 --- a/src/components/ContextMenu/src/createContextMenu.ts +++ b/src/components/ContextMenu/src/createContextMenu.ts @@ -1,6 +1,6 @@ -import contextMenuVue from './ContextMenu'; +import contextMenuVue from './ContextMenu.vue'; import { isClient } from '/@/utils/is'; -import { CreateContextOptions, ContextMenuProps } from './types'; +import { CreateContextOptions, ContextMenuProps } from './typing'; import { createVNode, render } from 'vue'; const menuManager: { @@ -16,7 +16,9 @@ export const createContextMenu = function (options: CreateContextOptions) { event && event?.preventDefault(); - if (!isClient) return; + if (!isClient) { + return; + } return new Promise((resolve) => { const body = document.body; @@ -54,9 +56,9 @@ export const createContextMenu = function (options: CreateContextOptions) { body.removeEventListener('scroll', handleClick); }; - menuManager.resolve = function (...arg: any) { + menuManager.resolve = function (arg) { remove(); - resolve(arg[0]); + resolve(arg); }; remove(); body.appendChild(container); diff --git a/src/components/ContextMenu/src/index.less b/src/components/ContextMenu/src/index.less deleted file mode 100644 index 3d8dec03..00000000 --- a/src/components/ContextMenu/src/index.less +++ /dev/null @@ -1,65 +0,0 @@ -@default-height: 42px !important; - -@small-height: 36px !important; - -@large-height: 36px !important; - -.item-style() { - li { - display: inline-block; - width: 100%; - height: @default-height; - margin: 0 !important; - line-height: @default-height; - - span { - line-height: @default-height; - } - - > div { - margin: 0 !important; - } - - &:not(.ant-menu-item-disabled):hover { - color: @text-color-base; - background-color: @item-hover-bg; - } - } -} - -.context-menu { - position: fixed; - top: 0; - left: 0; - z-index: 200; - display: block; - width: 156px; - margin: 0; - list-style: none; - background-color: @component-background; - border: 1px solid rgba(0, 0, 0, 0.08); - border-radius: 0.25rem; - box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.1), - 0 1px 5px 0 rgba(0, 0, 0, 0.06); - background-clip: padding-box; - user-select: none; - - .item-style(); - - .ant-divider { - margin: 0 0; - } - - &__popup { - .ant-divider { - margin: 0 0; - } - - .item-style(); - } - - .ant-menu-submenu-title, - .ant-menu-item { - padding: 0 !important; - } -} diff --git a/src/components/ContextMenu/src/props.ts b/src/components/ContextMenu/src/props.ts deleted file mode 100644 index 509b424f..00000000 --- a/src/components/ContextMenu/src/props.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type { PropType } from 'vue'; -import type { Axis, ContextMenuItem } from './types'; -import { propTypes } from '/@/utils/propTypes'; -export const contextMenuProps = { - width: propTypes.number.def(156), - customEvent: { - type: Object as PropType, - default: null, - }, - styles: propTypes.style, - showIcon: propTypes.bool.def(true), - axis: { - // The position of the right mouse button click - type: Object as PropType, - default() { - return { x: 0, y: 0 }; - }, - }, - items: { - // The most important list, if not, will not be displayed - type: Array as PropType, - default() { - return []; - }, - }, -}; diff --git a/src/components/ContextMenu/src/types.ts b/src/components/ContextMenu/src/typing.ts similarity index 100% rename from src/components/ContextMenu/src/types.ts rename to src/components/ContextMenu/src/typing.ts diff --git a/src/components/Drawer/src/BasicDrawer.vue b/src/components/Drawer/src/BasicDrawer.vue index 6e451bf1..b88c2ddc 100644 --- a/src/components/Drawer/src/BasicDrawer.vue +++ b/src/components/Drawer/src/BasicDrawer.vue @@ -81,46 +81,40 @@ instance && emit('register', drawerInstance, instance.uid); - const getMergeProps = computed( - (): DrawerProps => { - return deepMerge(toRaw(props), unref(propsRef)); - } - ); + const getMergeProps = computed((): DrawerProps => { + return deepMerge(toRaw(props), unref(propsRef)); + }); - const getProps = computed( - (): DrawerProps => { - const opt = { - placement: 'right', - ...unref(attrs), - ...unref(getMergeProps), - visible: unref(visibleRef), - }; - opt.title = undefined; - const { isDetail, width, wrapClassName, getContainer } = opt; - if (isDetail) { - if (!width) { - opt.width = '100%'; - } - const detailCls = `${prefixCls}__detail`; - opt.wrapClassName = wrapClassName ? `${wrapClassName} ${detailCls}` : detailCls; - - if (!getContainer) { - // TODO type error? - opt.getContainer = `.${prefixVar}-layout-content` as any; - } + const getProps = computed((): DrawerProps => { + const opt = { + placement: 'right', + ...unref(attrs), + ...unref(getMergeProps), + visible: unref(visibleRef), + }; + opt.title = undefined; + const { isDetail, width, wrapClassName, getContainer } = opt; + if (isDetail) { + if (!width) { + opt.width = '100%'; } - return opt as DrawerProps; - } - ); + const detailCls = `${prefixCls}__detail`; + opt.wrapClassName = wrapClassName ? `${wrapClassName} ${detailCls}` : detailCls; - const getBindValues = computed( - (): DrawerProps => { - return { - ...attrs, - ...unref(getProps), - }; + if (!getContainer) { + // TODO type error? + opt.getContainer = `.${prefixVar}-layout-content` as any; + } } - ); + return opt as DrawerProps; + }); + + const getBindValues = computed((): DrawerProps => { + return { + ...attrs, + ...unref(getProps), + }; + }); // Custom implementation of the bottom button, const getFooterHeight = computed(() => { @@ -133,15 +127,13 @@ return `0px`; }); - const getScrollContentStyle = computed( - (): CSSProperties => { - const footerHeight = unref(getFooterHeight); - return { - position: 'relative', - height: `calc(100% - ${footerHeight})`, - }; - } - ); + const getScrollContentStyle = computed((): CSSProperties => { + const footerHeight = unref(getFooterHeight); + return { + position: 'relative', + height: `calc(100% - ${footerHeight})`, + }; + }); const getLoading = computed(() => { return !!unref(getProps)?.loading; diff --git a/src/components/Drawer/src/components/DrawerFooter.vue b/src/components/Drawer/src/components/DrawerFooter.vue index 8688ce96..903aa832 100644 --- a/src/components/Drawer/src/components/DrawerFooter.vue +++ b/src/components/Drawer/src/components/DrawerFooter.vue @@ -43,15 +43,13 @@ setup(props, { emit }) { const { prefixCls } = useDesign('basic-drawer-footer'); - const getStyle = computed( - (): CSSProperties => { - const heightStr = `${props.height}`; - return { - height: heightStr, - lineHeight: heightStr, - }; - } - ); + const getStyle = computed((): CSSProperties => { + const heightStr = `${props.height}`; + return { + height: heightStr, + lineHeight: heightStr, + }; + }); function handleOk() { emit('ok'); diff --git a/src/components/Form/src/components/FormItem.vue b/src/components/Form/src/components/FormItem.vue index b9701e0b..724cfd09 100644 --- a/src/components/Form/src/components/FormItem.vue +++ b/src/components/Form/src/components/FormItem.vue @@ -174,9 +174,7 @@ return Promise.resolve(); } - const getRequired = isFunction(required) - ? required(unref(getValues)) - : required; + const getRequired = isFunction(required) ? required(unref(getValues)) : required; if ((!rules || rules.length === 0) && getRequired) { rules = [{ required: getRequired, validator }]; diff --git a/src/components/Icon/src/SvgIcon.vue b/src/components/Icon/src/SvgIcon.vue index cb5331d0..2afa4de1 100644 --- a/src/components/Icon/src/SvgIcon.vue +++ b/src/components/Icon/src/SvgIcon.vue @@ -36,17 +36,15 @@ const { prefixCls } = useDesign('svg-icon'); const symbolId = computed(() => `#${props.prefix}-${props.name}`); - const getStyle = computed( - (): CSSProperties => { - const { size } = props; - let s = `${size}`; - s = `${s.replace('px', '')}px`; - return { - width: s, - height: s, - }; - } - ); + const getStyle = computed((): CSSProperties => { + const { size } = props; + let s = `${size}`; + s = `${s.replace('px', '')}px`; + return { + width: s, + height: s, + }; + }); return { symbolId, prefixCls, getStyle }; }, }); diff --git a/src/components/Modal/src/BasicModal.vue b/src/components/Modal/src/BasicModal.vue index de2152c8..ab14fde8 100644 --- a/src/components/Modal/src/BasicModal.vue +++ b/src/components/Modal/src/BasicModal.vue @@ -107,14 +107,12 @@ } // Custom title component: get title - const getMergeProps = computed( - (): ModalProps => { - return { - ...props, - ...(unref(propsRef) as any), - }; - } - ); + const getMergeProps = computed((): ModalProps => { + return { + ...props, + ...(unref(propsRef) as any), + }; + }); const { handleFullScreen, getWrapClassName, fullScreenRef } = useFullScreen({ modalWrapperRef, @@ -123,31 +121,27 @@ }); // modal component does not need title and origin buttons - const getProps = computed( - (): ModalProps => { - const opt = { - ...unref(getMergeProps), - visible: unref(visibleRef), - okButtonProps: undefined, - cancelButtonProps: undefined, - title: undefined, - }; - return { - ...opt, - wrapClassName: unref(getWrapClassName), - }; - } - ); + const getProps = computed((): ModalProps => { + const opt = { + ...unref(getMergeProps), + visible: unref(visibleRef), + okButtonProps: undefined, + cancelButtonProps: undefined, + title: undefined, + }; + return { + ...opt, + wrapClassName: unref(getWrapClassName), + }; + }); - const getBindValue = computed( - (): Recordable => { - const attr = { ...attrs, ...unref(getProps) }; - if (unref(fullScreenRef)) { - return omit(attr, 'height'); - } - return attr; + const getBindValue = computed((): Recordable => { + const attr = { ...attrs, ...unref(getProps) }; + if (unref(fullScreenRef)) { + return omit(attr, 'height'); } - ); + return attr; + }); const getWrapperHeight = computed(() => { if (unref(fullScreenRef)) return undefined; diff --git a/src/components/SimpleMenu/src/components/MenuItem.vue b/src/components/SimpleMenu/src/components/MenuItem.vue index 15d5534e..222c7b62 100644 --- a/src/components/SimpleMenu/src/components/MenuItem.vue +++ b/src/components/SimpleMenu/src/components/MenuItem.vue @@ -39,9 +39,8 @@ const active = ref(false); - const { getItemStyle, getParentList, getParentMenu, getParentRootMenu } = useMenuItem( - instance - ); + const { getItemStyle, getParentList, getParentMenu, getParentRootMenu } = + useMenuItem(instance); const { prefixCls } = useDesign('menu'); diff --git a/src/components/SimpleMenu/src/components/SubMenuItem.vue b/src/components/SimpleMenu/src/components/SubMenuItem.vue index 0d24cbd7..0c5dd9a1 100644 --- a/src/components/SimpleMenu/src/components/SubMenuItem.vue +++ b/src/components/SimpleMenu/src/components/SubMenuItem.vue @@ -109,9 +109,8 @@ isChild: false, }); - const { getParentSubMenu, getItemStyle, getParentMenu, getParentList } = useMenuItem( - instance - ); + const { getParentSubMenu, getItemStyle, getParentMenu, getParentList } = + useMenuItem(instance); const { prefixCls } = useDesign('menu'); @@ -148,13 +147,11 @@ const getCollapse = computed(() => rootProps.collapse); const getTheme = computed(() => rootProps.theme); - const getOverlayStyle = computed( - (): CSSProperties => { - return { - minWidth: '200px', - }; - } - ); + const getOverlayStyle = computed((): CSSProperties => { + return { + minWidth: '200px', + }; + }); const getIsOpend = computed(() => { const name = props.name; diff --git a/src/components/SimpleMenu/src/components/useMenu.ts b/src/components/SimpleMenu/src/components/useMenu.ts index beb4c840..8830559d 100644 --- a/src/components/SimpleMenu/src/components/useMenu.ts +++ b/src/components/SimpleMenu/src/components/useMenu.ts @@ -14,26 +14,24 @@ export function useMenuItem(instance: ComponentInternalInstance | null) { return findParentMenu(['SubMenu']); }); - const getItemStyle = computed( - (): CSSProperties => { - let parent = instance?.parent; - if (!parent) return {}; - const indentSize = (unref(getParentRootMenu)?.props.indentSize as number) ?? 20; - let padding = indentSize; + const getItemStyle = computed((): CSSProperties => { + let parent = instance?.parent; + if (!parent) return {}; + const indentSize = (unref(getParentRootMenu)?.props.indentSize as number) ?? 20; + let padding = indentSize; - if (unref(getParentRootMenu)?.props.collapse) { - padding = indentSize; - } else { - while (parent && parent.type.name !== 'Menu') { - if (parent.type.name === 'SubMenu') { - padding += indentSize; - } - parent = parent.parent; + if (unref(getParentRootMenu)?.props.collapse) { + padding = indentSize; + } else { + while (parent && parent.type.name !== 'Menu') { + if (parent.type.name === 'SubMenu') { + padding += indentSize; } + parent = parent.parent; } - return { paddingLeft: padding + 'px' }; } - ); + return { paddingLeft: padding + 'px' }; + }); function findParentMenu(name: string[]) { let parent = instance?.parent; diff --git a/src/directives/clickOutside.ts b/src/directives/clickOutside.ts index 8c1b2dc4..f6f3051a 100644 --- a/src/directives/clickOutside.ts +++ b/src/directives/clickOutside.ts @@ -31,12 +31,14 @@ function createDocumentHandler(el: HTMLElement, binding: DirectiveBinding): Docu excludes = binding.arg; } else { // due to current implementation on binding type is wrong the type casting is necessary here - excludes.push((binding.arg as unknown) as HTMLElement); + excludes.push(binding.arg as unknown as HTMLElement); } return function (mouseup, mousedown) { - const popperRef = (binding.instance as ComponentPublicInstance<{ - popperRef: Nullable; - }>).popperRef; + const popperRef = ( + binding.instance as ComponentPublicInstance<{ + popperRef: Nullable; + }> + ).popperRef; const mouseUpTarget = mouseup.target as Node; const mouseDownTarget = mousedown.target as Node; const isBound = !binding || !binding.instance; diff --git a/src/hooks/web/useI18n.ts b/src/hooks/web/useI18n.ts index 40e11920..2a777b78 100644 --- a/src/hooks/web/useI18n.ts +++ b/src/hooks/web/useI18n.ts @@ -21,9 +21,7 @@ function getKey(namespace: string | undefined, key: string) { return `${namespace}.${key}`; } -export function useI18n( - namespace?: string -): { +export function useI18n(namespace?: string): { t: I18nGlobalTranslation; } { const normalFn = { diff --git a/src/hooks/web/useMessage.tsx b/src/hooks/web/useMessage.tsx index 56074e0e..ecb8fbbd 100644 --- a/src/hooks/web/useMessage.tsx +++ b/src/hooks/web/useMessage.tsx @@ -60,7 +60,7 @@ function createConfirm(options: ModalOptionsEx): ConfirmOptions { icon: getIcon(iconType), ...options, }; - return (Modal.confirm(opt) as unknown) as ConfirmOptions; + return Modal.confirm(opt) as unknown as ConfirmOptions; } const getBaseOptions = () => { diff --git a/src/layouts/default/header/components/Breadcrumb.vue b/src/layouts/default/header/components/Breadcrumb.vue index c135340a..6d5d2255 100644 --- a/src/layouts/default/header/components/Breadcrumb.vue +++ b/src/layouts/default/header/components/Breadcrumb.vue @@ -71,10 +71,10 @@ const breadcrumbList = filterItem(matched); if (currentRoute.value.meta?.currentActiveMenu) { - breadcrumbList.push(({ + breadcrumbList.push({ ...currentRoute.value, name: currentRoute.value.meta?.title || currentRoute.value.name, - } as unknown) as RouteLocationMatched); + } as unknown as RouteLocationMatched); } routes.value = breadcrumbList; }); diff --git a/src/layouts/default/menu/index.vue b/src/layouts/default/menu/index.vue index 9e340906..9dcb2d51 100644 --- a/src/layouts/default/menu/index.vue +++ b/src/layouts/default/menu/index.vue @@ -76,13 +76,11 @@ ); }); - const getWrapperStyle = computed( - (): CSSProperties => { - return { - height: `calc(100% - ${unref(getIsShowLogo) ? '48px' : '0px'})`, - }; - } - ); + const getWrapperStyle = computed((): CSSProperties => { + return { + height: `calc(100% - ${unref(getIsShowLogo) ? '48px' : '0px'})`, + }; + }); const getLogoClass = computed(() => { return [ diff --git a/src/layouts/default/setting/SettingDrawer.tsx b/src/layouts/default/setting/SettingDrawer.tsx index beba91c9..c9828868 100644 --- a/src/layouts/default/setting/SettingDrawer.tsx +++ b/src/layouts/default/setting/SettingDrawer.tsx @@ -58,12 +58,8 @@ export default defineComponent({ getThemeColor, } = useRootSetting(); - const { - getOpenPageLoading, - getBasicTransition, - getEnableTransition, - getOpenNProgress, - } = useTransitionSetting(); + const { getOpenPageLoading, getBasicTransition, getEnableTransition, getOpenNProgress } = + useTransitionSetting(); const { getIsHorizontal, diff --git a/src/layouts/default/sider/LayoutSider.vue b/src/layouts/default/sider/LayoutSider.vue index 1106062d..cfe46ba0 100644 --- a/src/layouts/default/sider/LayoutSider.vue +++ b/src/layouts/default/sider/LayoutSider.vue @@ -89,19 +89,17 @@ ]; }); - const getHiddenDomStyle = computed( - (): CSSProperties => { - const width = `${unref(getRealWidth)}px`; - return { - width: width, - overflow: 'hidden', - flex: `0 0 ${width}`, - maxWidth: width, - minWidth: width, - transition: 'all 0.2s', - }; - } - ); + const getHiddenDomStyle = computed((): CSSProperties => { + const width = `${unref(getRealWidth)}px`; + return { + width: width, + overflow: 'hidden', + flex: `0 0 ${width}`, + maxWidth: width, + minWidth: width, + transition: 'all 0.2s', + }; + }); return { prefixCls, diff --git a/src/layouts/default/sider/MixSider.vue b/src/layouts/default/sider/MixSider.vue index dea9bb79..46f0b62d 100644 --- a/src/layouts/default/sider/MixSider.vue +++ b/src/layouts/default/sider/MixSider.vue @@ -147,14 +147,12 @@ useDragLine(sideRef, dragBarRef, true); - const getMenuStyle = computed( - (): CSSProperties => { - return { - width: unref(openMenu) ? `${unref(getMenuWidth)}px` : 0, - left: `${unref(getMixSideWidth)}px`, - }; - } - ); + const getMenuStyle = computed((): CSSProperties => { + return { + width: unref(openMenu) ? `${unref(getMenuWidth)}px` : 0, + left: `${unref(getMixSideWidth)}px`, + }; + }); const getIsFixed = computed(() => { /* eslint-disable-next-line */ @@ -171,20 +169,16 @@ return unref(getCollapsed) ? SIDE_BAR_MINI_WIDTH : SIDE_BAR_SHOW_TIT_MINI_WIDTH; }); - const getDomStyle = computed( - (): CSSProperties => { - const fixedWidth = unref(getIsFixed) ? unref(getRealWidth) : 0; - const width = `${unref(getMixSideWidth) + fixedWidth}px`; - return getWrapCommonStyle(width); - } - ); + const getDomStyle = computed((): CSSProperties => { + const fixedWidth = unref(getIsFixed) ? unref(getRealWidth) : 0; + const width = `${unref(getMixSideWidth) + fixedWidth}px`; + return getWrapCommonStyle(width); + }); - const getWrapStyle = computed( - (): CSSProperties => { - const width = `${unref(getMixSideWidth)}px`; - return getWrapCommonStyle(width); - } - ); + const getWrapStyle = computed((): CSSProperties => { + const width = `${unref(getMixSideWidth)}px`; + return getWrapCommonStyle(width); + }); const getMenuEvents = computed(() => { return !unref(getMixSideFixed) diff --git a/src/layouts/default/tabs/index.vue b/src/layouts/default/tabs/index.vue index ad302881..fd7a4eba 100644 --- a/src/layouts/default/tabs/index.vue +++ b/src/layouts/default/tabs/index.vue @@ -106,8 +106,7 @@ .getRoutes() .find((item) => item.path === currentActiveMenu); - findParentRoute && - tabStore.addTab((findParentRoute as unknown) as RouteLocationNormalized); + findParentRoute && tabStore.addTab(findParentRoute as unknown as RouteLocationNormalized); } else { tabStore.addTab(unref(route)); } diff --git a/src/layouts/default/tabs/useMultipleTabs.ts b/src/layouts/default/tabs/useMultipleTabs.ts index 60b01a36..35b553b3 100644 --- a/src/layouts/default/tabs/useMultipleTabs.ts +++ b/src/layouts/default/tabs/useMultipleTabs.ts @@ -30,14 +30,14 @@ export function initAffixTabs(): string[] { * @description: Set fixed tabs */ function addAffixTabs(): void { - const affixTabs = filterAffixTabs((router.getRoutes() as unknown) as RouteLocationNormalized[]); + const affixTabs = filterAffixTabs(router.getRoutes() as unknown as RouteLocationNormalized[]); affixList.value = affixTabs; for (const tab of affixTabs) { - tabStore.addTab(({ + tabStore.addTab({ meta: tab.meta, name: tab.name, path: tab.path, - } as unknown) as RouteLocationNormalized); + } as unknown as RouteLocationNormalized); } } diff --git a/src/layouts/default/tabs/useTabDropdown.ts b/src/layouts/default/tabs/useTabDropdown.ts index d1e9f78f..54b0bbba 100644 --- a/src/layouts/default/tabs/useTabDropdown.ts +++ b/src/layouts/default/tabs/useTabDropdown.ts @@ -20,11 +20,9 @@ export function useTabDropdown(tabContentProps: TabContentProps, getIsTabs: Comp const { currentRoute } = useRouter(); const { refreshPage, closeAll, close, closeLeft, closeOther, closeRight } = useTabs(); - const getTargetTab = computed( - (): RouteLocationNormalized => { - return unref(getIsTabs) ? tabContentProps.tabItem : unref(currentRoute); - } - ); + const getTargetTab = computed((): RouteLocationNormalized => { + return unref(getIsTabs) ? tabContentProps.tabItem : unref(currentRoute); + }); /** * @description: drop-down list diff --git a/src/layouts/iframe/useFrameKeepAlive.ts b/src/layouts/iframe/useFrameKeepAlive.ts index 64b089ce..e84c49fe 100644 --- a/src/layouts/iframe/useFrameKeepAlive.ts +++ b/src/layouts/iframe/useFrameKeepAlive.ts @@ -16,8 +16,7 @@ export function useFrameKeepAlive() { const { getShowMultipleTab } = useMultipleTabSetting(); const tabStore = useMultipleTabStore(); const getFramePages = computed(() => { - const ret = - getAllFramePages((toRaw(router.getRoutes()) as unknown) as AppRouteRecordRaw[]) || []; + const ret = getAllFramePages(toRaw(router.getRoutes()) as unknown as AppRouteRecordRaw[]) || []; return ret; }); diff --git a/src/router/guard/permissionGuard.ts b/src/router/guard/permissionGuard.ts index a4fd1994..e9551264 100644 --- a/src/router/guard/permissionGuard.ts +++ b/src/router/guard/permissionGuard.ts @@ -60,7 +60,7 @@ export function createPermissionGuard(router: Router) { const routes = await permissionStore.buildRoutesAction(); routes.forEach((route) => { - router.addRoute((route as unknown) as RouteRecordRaw); + router.addRoute(route as unknown as RouteRecordRaw); }); const redirectPath = (from.query.redirect || to.path) as string; diff --git a/src/utils/cache/memory.ts b/src/utils/cache/memory.ts index b0a89f9c..7e960727 100644 --- a/src/utils/cache/memory.ts +++ b/src/utils/cache/memory.ts @@ -80,7 +80,7 @@ export class Memory { resetCache(cache: { [K in keyof T]: Cache }) { Object.keys(cache).forEach((key) => { - const k = (key as any) as keyof T; + const k = key as any as keyof T; const item = cache[k]; if (item && item.time) { const now = new Date().getTime(); diff --git a/src/utils/env.ts b/src/utils/env.ts index 67f71ebf..7dfa40c0 100644 --- a/src/utils/env.ts +++ b/src/utils/env.ts @@ -17,10 +17,10 @@ export function getStorageShortName() { export function getAppEnvConfig() { const ENV_NAME = getConfigFileName(import.meta.env); - const ENV = ((import.meta.env.DEV + const ENV = (import.meta.env.DEV ? // Get the global configuration (the configuration will be extracted independently when packaging) - ((import.meta.env as unknown) as GlobEnvConfig) - : window[ENV_NAME as any]) as unknown) as GlobEnvConfig; + (import.meta.env as unknown as GlobEnvConfig) + : window[ENV_NAME as any]) as unknown as GlobEnvConfig; const { VITE_GLOB_APP_TITLE, diff --git a/src/utils/is.ts b/src/utils/is.ts index d6202e03..eeff9270 100644 --- a/src/utils/is.ts +++ b/src/utils/is.ts @@ -89,6 +89,7 @@ export const isServer = typeof window === 'undefined'; export const isClient = !isServer; export function isUrl(path: string): boolean { - const reg = /(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/; + const reg = + /(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/; return reg.test(path); } diff --git a/src/views/demo/form/DynamicForm.vue b/src/views/demo/form/DynamicForm.vue index c4f0c0e5..cb7b4352 100644 --- a/src/views/demo/form/DynamicForm.vue +++ b/src/views/demo/form/DynamicForm.vue @@ -181,16 +181,14 @@ export default defineComponent({ components: { BasicForm, CollapseContainer, PageWrapper }, setup() { - const [ - register, - { setProps, updateSchema, appendSchemaByField, removeSchemaByFiled }, - ] = useForm({ - labelWidth: 120, - schemas, - actionColOptions: { - span: 24, - }, - }); + const [register, { setProps, updateSchema, appendSchemaByField, removeSchemaByFiled }] = + useForm({ + labelWidth: 120, + schemas, + actionColOptions: { + span: 24, + }, + }); const [register1] = useForm({ labelWidth: 120, schemas: schemas1, diff --git a/src/views/demo/system/account/DeptTree.vue b/src/views/demo/system/account/DeptTree.vue index d9b71547..a449862d 100644 --- a/src/views/demo/system/account/DeptTree.vue +++ b/src/views/demo/system/account/DeptTree.vue @@ -26,7 +26,7 @@ const treeData = ref([]); async function fetch() { - treeData.value = ((await getDeptList()) as unknown) as TreeItem[]; + treeData.value = (await getDeptList()) as unknown as TreeItem[]; } function handleSelect(keys: string, e) { diff --git a/src/views/demo/system/role/RoleDrawer.vue b/src/views/demo/system/role/RoleDrawer.vue index 7754f2e8..b41019d0 100644 --- a/src/views/demo/system/role/RoleDrawer.vue +++ b/src/views/demo/system/role/RoleDrawer.vue @@ -54,7 +54,7 @@ ...data.record, }); } - treeData.value = ((await getMenuList()) as any) as TreeItem[]; + treeData.value = (await getMenuList()) as any as TreeItem[]; }); const getTitle = computed(() => (!unref(isUpdate) ? '新增角色' : '编辑角色')); diff --git a/src/views/sys/exception/Exception.vue b/src/views/sys/exception/Exception.vue index b5bac267..dab9c576 100644 --- a/src/views/sys/exception/Exception.vue +++ b/src/views/sys/exception/Exception.vue @@ -64,11 +64,9 @@ return Number(routeStatus) || status; }); - const getMapValue = computed( - (): MapValue => { - return unref(statusMapRef).get(unref(getStatus)) as MapValue; - } - ); + const getMapValue = computed((): MapValue => { + return unref(statusMapRef).get(unref(getStatus)) as MapValue; + }); const backLoginI18n = t('sys.exception.backLogin'); const backHomeI18n = t('sys.exception.backHome'); diff --git a/src/views/sys/iframe/index.vue b/src/views/sys/iframe/index.vue index 564491ad..6c1b15c1 100644 --- a/src/views/sys/iframe/index.vue +++ b/src/views/sys/iframe/index.vue @@ -32,13 +32,11 @@ const { prefixCls } = useDesign('iframe-page'); useWindowSizeFn(calcHeight, 150, { immediate: true }); - const getWrapStyle = computed( - (): CSSProperties => { - return { - height: `${unref(heightRef)}px`, - }; - } - ); + const getWrapStyle = computed((): CSSProperties => { + return { + height: `${unref(heightRef)}px`, + }; + }); function calcHeight() { const iframe = unref(frameRef); diff --git a/stylelint.config.js b/stylelint.config.js index 0e63041c..cfa743d7 100644 --- a/stylelint.config.js +++ b/stylelint.config.js @@ -28,7 +28,7 @@ module.exports = { 'font-family-no-missing-generic-family-keyword': null, 'declaration-colon-space-after': 'always-single-line', 'declaration-colon-space-before': 'never', - 'declaration-block-trailing-semicolon': 'always', + // 'declaration-block-trailing-semicolon': 'always', 'rule-empty-line-before': [ 'always', { From 40008bc235b35b2cf097555854d18f369eadf707 Mon Sep 17 00:00:00 2001 From: Vben Date: Thu, 10 Jun 2021 00:32:15 +0800 Subject: [PATCH 15/56] refactor: refactor CountTo component --- CHANGELOG.zh_CN.md | 8 +- package.json | 12 +- .../ContextMenu/src/ContextMenu.vue | 7 +- src/components/CountTo/index.ts | 6 +- src/components/CountTo/src/CountTo.vue | 182 +++++++----------- src/components/CountTo/src/props.ts | 31 --- src/components/Cropper/src/Cropper.vue | 7 +- yarn.lock | 80 ++++---- 8 files changed, 130 insertions(+), 203 deletions(-) delete mode 100644 src/components/CountTo/src/props.ts diff --git a/CHANGELOG.zh_CN.md b/CHANGELOG.zh_CN.md index f4301d8a..ef581e0c 100644 --- a/CHANGELOG.zh_CN.md +++ b/CHANGELOG.zh_CN.md @@ -1,5 +1,11 @@ ## Wip +### ✨ Refactor + +- `CountTo`组件重构 + +### ✨ Features + - `radioButtonGroup` 支持`boolean`值 - `useModalInner` 新增 `redoModalHeight`用于在 Modal 内部重设`Modal`高度 - `useECharts` 新增`getInstance`用于获取`echart`实例 @@ -12,7 +18,7 @@ - `BasicTable`新增`updateTableDataRecord`方法用于更新指定行数据 - `useModal`新增`closeModal`方法用于关闭`Modal` -## Bug Fixes +### 🐛 Bug Fixes - 修复`redoModalHeight`不能减小高度的问题 - 修复 `BasicForm`设置 schemas 数据不生效的问题 diff --git a/package.json b/package.json index b2c36f42..676866ee 100644 --- a/package.json +++ b/package.json @@ -33,16 +33,16 @@ }, "dependencies": { "@iconify/iconify": "^2.0.1", - "@logicflow/core": "^0.4.11", - "@logicflow/extension": "^0.4.12", - "@vueuse/core": "^5.0.1", + "@logicflow/core": "^0.4.13", + "@logicflow/extension": "^0.4.13", + "@vueuse/core": "^5.0.2", "@zxcvbn-ts/core": "^0.3.0", "ant-design-vue": "2.1.2", "axios": "^0.21.1", "codemirror": "^5.61.1", "cropperjs": "^1.5.11", "crypto-js": "^4.0.0", - "echarts": "^5.1.1", + "echarts": "^5.1.2", "lodash-es": "^4.17.21", "mockjs": "^1.1.0", "nprogress": "^0.2.0", @@ -115,13 +115,13 @@ "vite-plugin-compression": "^0.2.5", "vite-plugin-html": "^2.0.7", "vite-plugin-imagemin": "^0.3.2", - "vite-plugin-mock": "^2.7.0", + "vite-plugin-mock": "^2.7.1", "vite-plugin-purge-icons": "^0.7.0", "vite-plugin-pwa": "^0.7.3", "vite-plugin-style-import": "^0.10.1", "vite-plugin-svg-icons": "^0.7.0", "vite-plugin-theme": "^0.8.1", - "vite-plugin-windicss": "^1.0.2", + "vite-plugin-windicss": "^1.0.3", "vue-eslint-parser": "^7.6.0", "vue-tsc": "^0.1.7" }, diff --git a/src/components/ContextMenu/src/ContextMenu.vue b/src/components/ContextMenu/src/ContextMenu.vue index da8ee554..54f6af56 100644 --- a/src/components/ContextMenu/src/ContextMenu.vue +++ b/src/components/ContextMenu/src/ContextMenu.vue @@ -71,7 +71,8 @@ }); onUnmounted(() => { - unref(wrapRef) && document.body.removeChild(el); + const el = unref(wrapRef); + el && document.body.removeChild(el); }); function handleAction(item: ContextMenuItem, e: MouseEvent) { @@ -118,8 +119,10 @@ }); } return () => { + if (!unref(showRef)) { + return null; + } const { items } = props; - if (!unref(showRef)) return null; return ( import('./src/CountTo.vue')); +export const CountTo = withInstall(countTo); diff --git a/src/components/CountTo/src/CountTo.vue b/src/components/CountTo/src/CountTo.vue index 544b3fba..c7c4b2ed 100644 --- a/src/components/CountTo/src/CountTo.vue +++ b/src/components/CountTo/src/CountTo.vue @@ -1,50 +1,56 @@ diff --git a/src/components/CountTo/src/props.ts b/src/components/CountTo/src/props.ts deleted file mode 100644 index 33b35225..00000000 --- a/src/components/CountTo/src/props.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { PropType } from 'vue'; -import { propTypes } from '/@/utils/propTypes'; -export const countToProps = { - startVal: propTypes.number.def(0), - endVal: propTypes.number.def(2020), - duration: propTypes.number.def(1300), - autoplay: propTypes.bool.def(true), - decimals: { - type: Number as PropType, - required: false, - default: 0, - validator(value: number) { - return value >= 0; - }, - }, - color: { - type: String as PropType, - require: false, - }, - decimal: propTypes.string.def('.'), - separator: propTypes.string.def(','), - prefix: propTypes.string.def(''), - suffix: propTypes.string.def(''), - useEasing: propTypes.bool.def(true), - easingFn: { - type: Function as PropType<(t: number, b: number, c: number, d: number) => number>, - default(t: number, b: number, c: number, d: number) { - return (c * (-Math.pow(2, (-10 * t) / d) + 1) * 1024) / 1023 + b; - }, - }, -}; diff --git a/src/components/Cropper/src/Cropper.vue b/src/components/Cropper/src/Cropper.vue index 8e16c3a6..c5b912a7 100644 --- a/src/components/Cropper/src/Cropper.vue +++ b/src/components/Cropper/src/Cropper.vue @@ -20,7 +20,7 @@ type Options = Cropper.Options; - const defaultOptions: Cropper.Options = { + const defaultOptions: Options = { aspectRatio: 16 / 9, zoomable: true, zoomOnTouch: true, @@ -42,6 +42,7 @@ movable: true, rotatable: true, }; + export default defineComponent({ name: 'CropperImage', props: { @@ -108,9 +109,9 @@ let imgInfo = cropper.value.getData(); cropper.value.getCroppedCanvas().toBlob((blob) => { let fileReader: FileReader = new FileReader(); - fileReader.onloadend = (e: any) => { + fileReader.onloadend = (e) => { ctx.emit('cropperedInfo', { - imgBase64: e.target.result, + imgBase64: e.target?.result ?? '', imgInfo, }); }; diff --git a/yarn.lock b/yarn.lock index 59cff62e..186a37ec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1252,21 +1252,21 @@ "@intlify/runtime" "9.1.6" "@intlify/shared" "9.1.6" -"@logicflow/core@^0.4.11": - version "0.4.11" - resolved "https://registry.yarnpkg.com/@logicflow/core/-/core-0.4.11.tgz#3c617e5cddb47e7052d62fee56ba77ab45b1cd25" - integrity sha512-FlErJRyKw+XzyT0/0hha8Dwsiok9Cri2ZS2/SDmqLdUK6I3rD6LpmVabj8LjYH4IWb0fOYSfgGhY4oWQAKqa9g== +"@logicflow/core@^0.4.13": + version "0.4.13" + resolved "https://registry.npmjs.org/@logicflow/core/-/core-0.4.13.tgz#69d1e7a30b5e545ada3a2e980059f3e6f6923f15" + integrity sha512-xOLz8RO6ldAT5H9Q2Ewt9d7z146B54TUom5EXzJ/jx/s1Phy24vP8tAGu6LuoTEitgNHTRQq7WxvH9NqnpxCpg== dependencies: "@types/mousetrap" "^1.6.4" mousetrap "^1.6.5" preact "^10.4.8" -"@logicflow/extension@^0.4.12": - version "0.4.12" - resolved "https://registry.yarnpkg.com/@logicflow/extension/-/extension-0.4.12.tgz#be69e8ebbcffee6bb0f07778f2126ad98f93f64a" - integrity sha512-fD0bXxYIEo1d047A3PXkAVMH6vM5y8AAIfLxnXxdMJGOVLH44iWCO6eNW8bvnoab7aSmhj2MWMgY3op5XVZh1Q== +"@logicflow/extension@^0.4.13": + version "0.4.13" + resolved "https://registry.npmjs.org/@logicflow/extension/-/extension-0.4.13.tgz#b1c87b5458345414cc6c5fb813511e62db4acfa7" + integrity sha512-DAfgO9A5VrJ4oXruTYGgmDGvZAIaT2kLAlTE+luyg4eld6YsgwWXqXazJWCd9ObdAJkLYCf7lU27hZsDNqqbrg== dependencies: - "@logicflow/core" "^0.4.11" + "@logicflow/core" "^0.4.13" ids "^1.0.0" preact "^10.4.8" @@ -2033,25 +2033,25 @@ resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.0.11.tgz#20d22dd0da7d358bb21c17f9bde8628152642c77" integrity sha512-b+zB8A2so8eCE0JsxjL24J7vdGl8rzPQ09hZNhystm+KqSbKcAej1A+Hbva1rCMmTTqA+hFnUSDc5kouEo0JzA== -"@vueuse/core@^5.0.1": - version "5.0.1" - resolved "https://registry.npmjs.org/@vueuse/core/-/core-5.0.1.tgz#94bbb6c71d95b79efbdb24111915775e61723f1b" - integrity sha512-hzcyYNvW1p9ZEwm+oBaWrHgGx6S93pJBiXLZUj2pgCNiJZjaedoePT9xzesi1SBxeKcYxwToaTISLeKdE4VKeg== +"@vueuse/core@^5.0.2": + version "5.0.2" + resolved "https://registry.npmjs.org/@vueuse/core/-/core-5.0.2.tgz#302389f620c0d4b51fdf157012d9b5b522b605e7" + integrity sha512-Sp9+7AL4Cg3Tx6I55WoH7zICGRlp6ZUF9NW3EU8SZTkryHm0afAjFfASMwlfV030JFeh45BdqafDOrenVmM9Cw== dependencies: - "@vueuse/shared" "5.0.1" + "@vueuse/shared" "5.0.2" vue-demi "*" -"@vueuse/shared@5.0.1": - version "5.0.1" - resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-5.0.1.tgz#3b6607ffc9e19b322c39be8a2f6b584d203a7c5e" - integrity sha512-/+kRII9chn45PhFfRuPVbSQApJHhhqXFhPrWjnYKckMfQE9ZOuNMb1bmQnDTqzuNkoS/ENeHBMq0rnV/cfz/3Q== +"@vueuse/shared@5.0.2": + version "5.0.2" + resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-5.0.2.tgz#274c2bf163d25eb7fd2fc51f23088a2b7f060594" + integrity sha512-S1hRRmEdipjTD4DbXgPdw4ZZYebU/nDi75vNP3Ibpa1irW3NUNUKOT/TWnwRHLQvXquUtdvalhI8D9Db+czZJg== dependencies: vue-demi "*" -"@windicss/plugin-utils@1.0.2": - version "1.0.2" - resolved "https://registry.npmjs.org/@windicss/plugin-utils/-/plugin-utils-1.0.2.tgz#c34d6498058d5f4291805027d2ef6e34638a572a" - integrity sha512-W9fZoPNsD3NMVyqzt9eNb1DNp9p4oy7EscCfGVIg1KBxAC8S+AnXtkaR/rad09y+aqzbILKNfzDKdimDR2FA9g== +"@windicss/plugin-utils@1.0.3": + version "1.0.3" + resolved "https://registry.npmjs.org/@windicss/plugin-utils/-/plugin-utils-1.0.3.tgz#04d039ef56b58180079df3f9b3bd8a21a57368d3" + integrity sha512-SBYjmWBO+dOqxJgyyOAETOuMdcugvVgZYQc3rb7KtcTW5u9UkFXtiuGdoq8cWyFpSkn46gmjCb4WNbY3kEIVnQ== dependencies: "@antfu/utils" "^0.1.6" debug "^4.3.2" @@ -4050,13 +4050,13 @@ duplexer3@^0.1.4: resolved "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= -echarts@^5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/echarts/-/echarts-5.1.1.tgz#b186f162f017c555cfd67b12ede6762bdc3ddfda" - integrity sha512-b3nP8M9XwZM2jISuA+fP0EuJv8lcfgWrinel185Npy8bE/UhXTDIPJcqgQOCWdvk0c5CeT6Dsm1xBjmJXAGlxQ== +echarts@^5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/echarts/-/echarts-5.1.2.tgz#aa1ab0cef5b74fa2f7c620261a5f286893d30fd1" + integrity sha512-okUhO4sw22vwZp+rTPNjd/bvTdpug4K4sHNHyrV8NdAncIX9/AarlolFqtJCAYKGFYhUBNjIWu1EznFrSWTFxg== dependencies: tslib "2.0.3" - zrender "5.1.0" + zrender "5.1.1" ecstatic@^3.3.2: version "3.3.2" @@ -10573,10 +10573,10 @@ vite-plugin-imagemin@^0.3.2: imagemin-svgo "^8.0.0" imagemin-webp "^6.0.0" -vite-plugin-mock@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/vite-plugin-mock/-/vite-plugin-mock-2.7.0.tgz#21aec0397e29d013c87d765c56d177728d4288b4" - integrity sha512-hB3MbnQlrmqGOigbPB+UsUQ/ZjTisj75FprJ7IDw8pDYQjWmHC7AtmDOHdzpGYPKEEX1mz7UhGJ93LLarPqJNg== +vite-plugin-mock@^2.7.1: + version "2.7.1" + resolved "https://registry.npmjs.org/vite-plugin-mock/-/vite-plugin-mock-2.7.1.tgz#c7d25277f7b88158cd3927c1abee7c7721ed92d3" + integrity sha512-UnYcb4UZrpe5fHBNFNEJQetnR32+XxrduTYhyDQTtXmaJ9Yy+JuBfIT6Mueyf7MGPe8T6hNgIEYaMLSUD5+nWA== dependencies: "@rollup/plugin-node-resolve" "^11.2.1" "@types/mockjs" "^1.0.3" @@ -10647,12 +10647,12 @@ vite-plugin-theme@^0.8.1: esbuild-plugin-alias "^0.1.2" tinycolor2 "^1.4.2" -vite-plugin-windicss@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/vite-plugin-windicss/-/vite-plugin-windicss-1.0.2.tgz#0d0fd1ff36dc81d348be755e59a8ee471941095c" - integrity sha512-iTmkxm8Yp+ZCFWLOs//9q3d4hYaBVDlkRGLzNBUNvRW9AQFVea57ZPhglMm9xOt1nW/O68n5Rkg4/In8rrEjHQ== +vite-plugin-windicss@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/vite-plugin-windicss/-/vite-plugin-windicss-1.0.3.tgz#bd45cfee13777e7b57c37a257ebcb7e73fee94ab" + integrity sha512-y9pudcMajdI88PTs49qGftlfAvsLUUhK2Eig+xn5sgxPCbAc3Rj5phXJkRzGDqfmEzGwbpF6JwjmiGmZkm8V+g== dependencies: - "@windicss/plugin-utils" "1.0.2" + "@windicss/plugin-utils" "1.0.3" chalk "^4.1.1" debug "^4.3.2" windicss "^3.1.3" @@ -11321,10 +11321,10 @@ yocto-queue@^0.1.0: resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== -zrender@5.1.0: - version "5.1.0" - resolved "https://registry.npmjs.org/zrender/-/zrender-5.1.0.tgz#b6a84c3aa7ccc6642ee0519901ca4c0835c4d85e" - integrity sha512-c+8VRx52ycbmqwHeHLlo/BAfIHBl/JZNLM6cfDQFgzIH05yb+f5J9F/fbRsP+zGc8dW9XHuhdt8/iqukgMZSeg== +zrender@5.1.1: + version "5.1.1" + resolved "https://registry.npmjs.org/zrender/-/zrender-5.1.1.tgz#0515f4f8cc0f4742f02a6b8819550a6d13d64c5c" + integrity sha512-oeWlmUZPQdS9f5hK4pV21tHPqA3wgQ7CkKkw7l0CCBgWlJ/FP+lRgLFtUBW6yam4JX8y9CdHJo1o587VVrbcoQ== dependencies: tslib "2.0.3" From 2c5351f9f45854501c0ed342c44045f1a6b6a142 Mon Sep 17 00:00:00 2001 From: Vben Date: Thu, 10 Jun 2021 00:36:54 +0800 Subject: [PATCH 16/56] chore: release 2.4.2 --- CHANGELOG.en_US.md | 34 ++++++++++++++++++++ CHANGELOG.md | 77 ++++++++++++++++++++++++++++++++++++++++++++++ CHANGELOG.zh_CN.md | 2 +- package.json | 2 +- 4 files changed, 113 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.en_US.md b/CHANGELOG.en_US.md index 8cac9f0d..ae3619a8 100644 --- a/CHANGELOG.en_US.md +++ b/CHANGELOG.en_US.md @@ -1,3 +1,37 @@ +## 2.4.2(2021-06-10) + +### ✨ Refactor + +- `CountTo` component refactoring + +### ✨ Features + +- `radioButtonGroup` supports `boolean` value +- `useModalInner` added `redoModalHeight` to reset the height of `Modal` inside Modal +- `useECharts` added `getInstance` to obtain instances of `echart` +- `TableAction` added `stopButtonPropagation` to prevent the action button click event from bubbling +- `BasicTable` in the row edit mode, you can get or set the value of other editing components in the column +- The `ApiSelect` component will automatically re-fetch the data after the `params` is changed +- `TableImg` component improvement +- `BasicTable` added `columns-change` event to monitor the user to change the sorting, display, and fixed status of columns +- `Tinymce` supports dynamic modification readonly +- `BasicTable` added `updateTableDataRecord` method to update the specified row data +- `useModal` added `closeModal` method to close `Modal` + +### 🐛 Bug Fixes + +- Fix the problem that `redoModalHeight` cannot reduce the height +- Fix the problem that the schema data of `BasicForm` does not take effect +- Fix the problem that multiple tags may cause `KeepAlive` to fail +- Fix the problem that the default `axios` interceptor cannot handle custom code +- Fix the height issue of the lock screen pop-up window +- Fixed the problem that the half-selected state of the `Column Display` checkbox of `BaiscTable` was incorrectly displayed +- Fixed the problem that the preview list of the `BasicUpload` component could not be displayed in some cases +- Fix the problem that the `options` setting of ` RadioButtonGroup``disabled ` does not take effect +- Fix the problem that the button for uploading pictures in the read-only mode of the `Tinymce` component is still available +- Fix the stuttering problem of `BasicForm` under certain circumstances +- Fix the problem that "directory" routing does not work + ## 2.4.1(2021-06-01) ### ✨ Features diff --git a/CHANGELOG.md b/CHANGELOG.md index faa0ad89..e9a8e7b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,80 @@ +## [2.4.2](https://github.com/anncwb/vue-vben-admin/compare/v2.4.0...v2.4.2) (2021-06-09) + +### Bug Fixes + +- fix darkModeSwitch switch failure ([34a8054](https://github.com/anncwb/vue-vben-admin/commit/34a80542de670f0385dffaf5bf64bb9c3f6b90da)) +- **api-select:** loss option data on event callback ([c5f2577](https://github.com/anncwb/vue-vben-admin/commit/c5f2577f515e7ae96b27b509e5dd4b3317fcb7b4)), closes [#733](https://github.com/anncwb/vue-vben-admin/issues/733) +- **avatar:** mock data and Account center style ([2066f66](https://github.com/anncwb/vue-vben-admin/commit/2066f669715491f3e91ac6d0e905cd2b3e80b58d)) +- **axios:** transformRequestHook logic error ([b69dcd7](https://github.com/anncwb/vue-vben-admin/commit/b69dcd79d742fd171302ce0f48c7750d60da217f)) +- **codeMirror:** fix the JsonEditor embedded in the bullet frame causing the style to be disordered ([#668](https://github.com/anncwb/vue-vben-admin/issues/668)) ([e1123a2](https://github.com/anncwb/vue-vben-admin/commit/e1123a2ccb5d5450a5072c19e5508a5dc0f14423)) +- **demo:** `breadcrumb` route invalid redirect ([84d9300](https://github.com/anncwb/vue-vben-admin/commit/84d9300e52fa73da575591aa4b71858a7e459c8c)) +- **demo:** account list page validate and save ([21f7a85](https://github.com/anncwb/vue-vben-admin/commit/21f7a854fe2455315287d04e895661ff739bce17)) +- **demo:** fix basic form page style ([8b6e07b](https://github.com/anncwb/vue-vben-admin/commit/8b6e07b768f110f13b4f2efa6c46e03266667a8c)) +- **demo:** make sure the map https resource is correct ([7b9cd09](https://github.com/anncwb/vue-vben-admin/commit/7b9cd09ad8a50c45b2e661e07953d786d82f367d)) +- **form:** fix form update problem ([bcad95d](https://github.com/anncwb/vue-vben-admin/commit/bcad95d32a08a73f84ecbabab409cd64159f4077)), closes [#720](https://github.com/anncwb/vue-vben-admin/issues/720) +- **form:** radioButtonGroup value support boolean ([9e2aa20](https://github.com/anncwb/vue-vben-admin/commit/9e2aa20daa08d2902cb5d56c1560306947e44939)) +- **form:** radioButtonGroup value support number ([bbddf30](https://github.com/anncwb/vue-vben-admin/commit/bbddf30e96feb1ab048323d93d3b8c1b18857acd)) +- **form:** schemas update problem ([808328d](https://github.com/anncwb/vue-vben-admin/commit/808328dc7e56b1cc07b678d501d9589290173443)), closes [#688](https://github.com/anncwb/vue-vben-admin/issues/688) +- **keep-alive:** tablist cache updating effect ([d62d0ca](https://github.com/anncwb/vue-vben-admin/commit/d62d0ca08cff442c23eb9265851b066a2f24afa8)), closes [#695](https://github.com/anncwb/vue-vben-admin/issues/695) +- **lock:** fix lock modal height ([40e3cb0](https://github.com/anncwb/vue-vben-admin/commit/40e3cb043c90a8343fa44a32acad2cb77de732da)), closes [#701](https://github.com/anncwb/vue-vben-admin/issues/701) +- **login:** login page modal style fixed: [#662](https://github.com/anncwb/vue-vben-admin/issues/662) ([#666](https://github.com/anncwb/vue-vben-admin/issues/666)) ([b218f10](https://github.com/anncwb/vue-vben-admin/commit/b218f10e25a9364c399a5fe42eedb549f57c01ea)) +- **mock:** menu list api loss `type` field ([4185412](https://github.com/anncwb/vue-vben-admin/commit/41854121f3713dbde236afd3a416e9f27bd0c673)) +- **mock:** type error ([7c1ffa3](https://github.com/anncwb/vue-vben-admin/commit/7c1ffa3d23de508a8d1590985806cb7a484b24e5)) +- **router:** loss `directory` route ([df8cd86](https://github.com/anncwb/vue-vben-admin/commit/df8cd860514f32f44847dcf724f0737ed4d8b9e0)), closes [#722](https://github.com/anncwb/vue-vben-admin/issues/722) +- build error ([5212ea7](https://github.com/anncwb/vue-vben-admin/commit/5212ea79b43c832a5136354b549de8f89b6e2156)) +- **axios:** make sure that the parameter is an object before processing, fix [#660](https://github.com/anncwb/vue-vben-admin/issues/660) ([834fa7e](https://github.com/anncwb/vue-vben-admin/commit/834fa7eb9c8aff252e083d38fdab4f6f53b4d43a)) +- **code-editor:** fix CodeEditor style problem, fix [#655](https://github.com/anncwb/vue-vben-admin/issues/655) ([5662804](https://github.com/anncwb/vue-vben-admin/commit/566280422de0537c4e31496eaaa95a9d51fe9458)) +- **codeeditor:** empty value set failed.fixed:[#659](https://github.com/anncwb/vue-vben-admin/issues/659) ([ba2bebb](https://github.com/anncwb/vue-vben-admin/commit/ba2bebb4069085817a90d065ed5877fdb50a8039)) +- **layout:** fix class loss ([d018363](https://github.com/anncwb/vue-vben-admin/commit/d018363ddcd68189a18829a2b2560f3b98da58a6)) +- **layout:** fix style compatibility issues ([905e5b7](https://github.com/anncwb/vue-vben-admin/commit/905e5b714b582548f32feca723012124343686a6)) +- **log:** fix Wrong version number ([#653](https://github.com/anncwb/vue-vben-admin/issues/653)) ([4f0d45f](https://github.com/anncwb/vue-vben-admin/commit/4f0d45f1df48755eadc0b09fa19762ee68f9abd1)) +- **modal:** redoModalHeight not work as expected ([5d554f1](https://github.com/anncwb/vue-vben-admin/commit/5d554f184f7b61774d1a1b2e61451677b38505de)) +- **page:** `basic form` action btns should be in line ([6c4f947](https://github.com/anncwb/vue-vben-admin/commit/6c4f947386c181f45253c94e4ef735d29a253053)) +- **radio-button:** fix RadioButton `disabled` support ([ee384b1](https://github.com/anncwb/vue-vben-admin/commit/ee384b1fa7e387b3680e9d54cbe4a1e2f15ec750)), closes [#710](https://github.com/anncwb/vue-vben-admin/issues/710) +- **table:** wrong indeterminate state ([495b1da](https://github.com/anncwb/vue-vben-admin/commit/495b1da385e9b6428d2b994669d2065722445923)) +- **table:** make sure the table width is correct, fix [#593](https://github.com/anncwb/vue-vben-admin/issues/593) ([d73d43e](https://github.com/anncwb/vue-vben-admin/commit/d73d43ed91f30957cfd202c51552ca40a19cef08)) +- **table:** settings indeterminate state effect ([4fd2051](https://github.com/anncwb/vue-vben-admin/commit/4fd2051bc0403bfc5345ed6a5fc283a372ef7a92)) +- **table:** support change event ([9f4d171](https://github.com/anncwb/vue-vben-admin/commit/9f4d1719caa76de94e6362c16e4df3ac28df253c)), closes [#677](https://github.com/anncwb/vue-vben-admin/issues/677) +- **table:** try to get close to the form stuck ([d81481c](https://github.com/anncwb/vue-vben-admin/commit/d81481c52186145dac130aaa1594f0ba8db4d392)) +- **Tinymce:** Read only status upload button can also be used ([#718](https://github.com/anncwb/vue-vben-admin/issues/718)) ([966571b](https://github.com/anncwb/vue-vben-admin/commit/966571bdcb11c2729ab9ce212bd3e195f7bf3a59)) +- **upload:** ensure preview items valid ([4376928](https://github.com/anncwb/vue-vben-admin/commit/437692869a232ee65c300c65ee473557ae0913c7)) +- ensure that roleList is not empty ([aebad61](https://github.com/anncwb/vue-vben-admin/commit/aebad61b3d3e11aaf720b37e762e53e2e6999d3c)) +- fix node12 version data mock error ([644dbe3](https://github.com/anncwb/vue-vben-admin/commit/644dbe315bb03ea1641a682359873237208a5303)) +- Fix the problem that the `lang` attribute of `HTML` will not be set when it is first loaded ([#682](https://github.com/anncwb/vue-vben-admin/issues/682)) ([eca8907](https://github.com/anncwb/vue-vben-admin/commit/eca8907a11c28d816c3da5a0667f45a38a499012)) +- **table:** useTable support onChange ([9f5085c](https://github.com/anncwb/vue-vben-admin/commit/9f5085c9f9f46b09391156b17091c1771bc13026)) +- **table-action:** fix the split line style is missing,fix [#674](https://github.com/anncwb/vue-vben-admin/issues/674) ([b1cb863](https://github.com/anncwb/vue-vben-admin/commit/b1cb86350253dc5be095466966d9469775f4395d)) +- login failed ([035f55a](https://github.com/anncwb/vue-vben-admin/commit/035f55af9778819d72adc1700d9de56a6569b58f)) +- session timeout login logic error ([#678](https://github.com/anncwb/vue-vben-admin/issues/678)) ([132c7fb](https://github.com/anncwb/vue-vben-admin/commit/132c7fb944df255c4d76a25d6d924439f91f9c54)), closes [#673](https://github.com/anncwb/vue-vben-admin/issues/673) +- **tree:** support defaultExpandAll prop ([3ed2339](https://github.com/anncwb/vue-vben-admin/commit/3ed2339a6d75abbd6ccf723b6eaa762f9921409e)) +- theme switching fails ([7e2ca79](https://github.com/anncwb/vue-vben-admin/commit/7e2ca79ece2f5209cb7ce4b0f5ee15012f9f51de)) + +### Features + +- **api-select:** auto refetch after params changed ([50207ad](https://github.com/anncwb/vue-vben-admin/commit/50207ad702ef3faca1e27c873c89132ab92fae8e)) +- **app-search:** auto focus on show ([1ae6362](https://github.com/anncwb/vue-vben-admin/commit/1ae636296df2cf99e8a777f053c539c50e6ad49a)) +- **demo:** `switch` use in table ([46899aa](https://github.com/anncwb/vue-vben-admin/commit/46899aa3cd6b1616c42ac263a28af75be839f6a0)) +- **echarts:** add getInstance for useECharts ([fb6c76d](https://github.com/anncwb/vue-vben-admin/commit/fb6c76db535bd0c6305d03c0cff876a1f079100b)) +- **modal:** add closeModal for useModal ([6d5f9aa](https://github.com/anncwb/vue-vben-admin/commit/6d5f9aa699c5da8af6bf5841baddc4a8bd603917)) +- **modal:** add redoModalHeight for useModalInner ([f732b56](https://github.com/anncwb/vue-vben-admin/commit/f732b569042f7fe77c85cb295538ddd85561f7e9)) +- **table:** add editable DatePicker & TimePicker ([#654](https://github.com/anncwb/vue-vben-admin/issues/654)) ([93006c7](https://github.com/anncwb/vue-vben-admin/commit/93006c7dc7b5243b26637f444c8057c95935e622)) +- **table:** add updateTableDataRecord method ([8e4f486](https://github.com/anncwb/vue-vben-admin/commit/8e4f486fcf835f0b6f2a95676dba268ffdd0566e)) +- **table:** editable component text align ([8eaf575](https://github.com/anncwb/vue-vben-admin/commit/8eaf57562610a833c8083ae9957f458319d1cc93)) +- **table:** support columns-change event ([125a7d1](https://github.com/anncwb/vue-vben-admin/commit/125a7d14831642c9cbb2e4b3e75953c3b2e2cdef)) +- **table:** support custom update on row editing ([fe2bcfc](https://github.com/anncwb/vue-vben-admin/commit/fe2bcfc6f74159c355f3be153a316869fdb8b644)), closes [#646](https://github.com/anncwb/vue-vben-admin/issues/646) +- **table:** updateTableDataRecord support functional rowKey ([448a4c2](https://github.com/anncwb/vue-vben-admin/commit/448a4c2809672480f8f635d7cc4661554112598a)) +- **table-action:** add stopButtonPropagation prop ([808012b](https://github.com/anncwb/vue-vben-admin/commit/808012b544b8c6f3cf467f42653c2783dbe8be6b)), closes [#699](https://github.com/anncwb/vue-vben-admin/issues/699) +- **table-img:** support simple show mode and more props ([19d8e01](https://github.com/anncwb/vue-vben-admin/commit/19d8e01e11644c66222f137abd05940cbdec0bb6)) +- **tabs:** add setTabTitle method ([#680](https://github.com/anncwb/vue-vben-admin/issues/680)) ([5ddccf6](https://github.com/anncwb/vue-vben-admin/commit/5ddccf6ba28453b9a35355d53d0db65f1a8876bc)) +- **tinymce:** support dark theme and I18n ([83c9cd7](https://github.com/anncwb/vue-vben-admin/commit/83c9cd77421e9c0888a41e2d8dcbca816da67488)) +- **Tinymce:** add dynamics to the read-only state of the rich text editor ([#725](https://github.com/anncwb/vue-vben-admin/issues/725)) ([efce482](https://github.com/anncwb/vue-vben-admin/commit/efce482b3215ddf9ed588f63a218d5f76939e947)) +- **tree:** add defaultExpandLevel prop ([6edca1c](https://github.com/anncwb/vue-vben-admin/commit/6edca1c19c3b0772f9ab82a7b09251a74fff2173)), closes [#672](https://github.com/anncwb/vue-vben-admin/issues/672) + +### Performance Improvements + +- optimize components and add comments ([55e9d9f](https://github.com/anncwb/vue-vben-admin/commit/55e9d9fc2953643cec95c74b6ed34b0e68641fb6)) +- **i18n:** improve circular dependencies ([d677729](https://github.com/anncwb/vue-vben-admin/commit/d677729acbe2c024ab13cf490b205528507c4823)) +- **i18n:** improve warning prompt ([6ef62ba](https://github.com/anncwb/vue-vben-admin/commit/6ef62ba6ea7f5613a1fec982b30fe6b0f478bf59)) + ## [2.4.1](https://github.com/anncwb/vue-vben-admin/compare/v2.4.0...v2.4.1) (2021-06-01) ### Bug Fixes diff --git a/CHANGELOG.zh_CN.md b/CHANGELOG.zh_CN.md index ef581e0c..9a603fcd 100644 --- a/CHANGELOG.zh_CN.md +++ b/CHANGELOG.zh_CN.md @@ -1,4 +1,4 @@ -## Wip +## 2.4.2(2021-06-10) ### ✨ Refactor diff --git a/package.json b/package.json index 676866ee..1bfbde1d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vben-admin", - "version": "2.4.1", + "version": "2.4.2", "author": { "name": "vben", "email": "anncwb@126.com", From b387681c00ac018f5bc6a9251009ddffe37acae6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=97=A0=E6=9C=A8?= Date: Thu, 10 Jun 2021 15:43:28 +0800 Subject: [PATCH 17/56] fix(api): select api type error --- src/api/demo/model/optionsModel.ts | 2 +- src/api/demo/select.ts | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/api/demo/model/optionsModel.ts b/src/api/demo/model/optionsModel.ts index 0702aae4..c65dc7c9 100644 --- a/src/api/demo/model/optionsModel.ts +++ b/src/api/demo/model/optionsModel.ts @@ -8,4 +8,4 @@ export interface DemoOptionsItem { /** * @description: Request list return value */ -export type DemoOptionsGetResultModel = BasicFetchResult; +export type DemoOptionsGetResultModel = BasicFetchResult; diff --git a/src/api/demo/select.ts b/src/api/demo/select.ts index 30030aee..cb04bea2 100644 --- a/src/api/demo/select.ts +++ b/src/api/demo/select.ts @@ -1,6 +1,5 @@ import { defHttp } from '/@/utils/http/axios'; -import { DemoOptionsGetResultModel } from './model/optionsModel'; - +import { DemoOptionsItem } from './model/optionsModel'; enum Api { OPTIONS_LIST = '/select/getDemoOptions', } @@ -8,5 +7,4 @@ enum Api { /** * @description: Get sample options value */ -export const optionsListApi = () => - defHttp.get({ url: Api.OPTIONS_LIST }); +export const optionsListApi = () => defHttp.get({ url: Api.OPTIONS_LIST }); From de12babd314ac831d3cb645f42dbf8a476075623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=97=A0=E6=9C=A8?= Date: Thu, 10 Jun 2021 19:48:43 +0800 Subject: [PATCH 18/56] fix(modal): add v-model support for visible --- src/components/Modal/src/BasicModal.vue | 9 +++++---- src/components/Modal/src/components/ModalClose.vue | 4 ++-- src/components/Modal/src/components/ModalFooter.vue | 8 ++++---- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/components/Modal/src/BasicModal.vue b/src/components/Modal/src/BasicModal.vue index ab14fde8..4acefc80 100644 --- a/src/components/Modal/src/BasicModal.vue +++ b/src/components/Modal/src/BasicModal.vue @@ -81,7 +81,7 @@ components: { Modal, ModalWrapper, ModalClose, ModalFooter, ModalHeader }, inheritAttrs: false, props: basicProps, - emits: ['visible-change', 'height-change', 'cancel', 'ok', 'register'], + emits: ['visible-change', 'height-change', 'cancel', 'ok', 'register', 'update:visible'], setup(props, { emit, attrs }) { const visibleRef = ref(false); const propsRef = ref | null>(null); @@ -157,6 +157,7 @@ () => unref(visibleRef), (v) => { emit('visible-change', v); + emit('update:visible', v); instance && modalMethods.emitVisible?.(v, instance.uid); nextTick(() => { if (props.scrollTop && v && unref(modalWrapperRef)) { @@ -180,7 +181,7 @@ } visibleRef.value = false; - emit('cancel'); + emit('cancel', e); } /** @@ -193,8 +194,8 @@ visibleRef.value = !!props.visible; } - function handleOk() { - emit('ok'); + function handleOk(e: Event) { + emit('ok', e); } function handleHeightChange(height: string) { diff --git a/src/components/Modal/src/components/ModalClose.vue b/src/components/Modal/src/components/ModalClose.vue index 3f636977..cf6cbda8 100644 --- a/src/components/Modal/src/components/ModalClose.vue +++ b/src/components/Modal/src/components/ModalClose.vue @@ -35,8 +35,8 @@ ]; }); - function handleCancel() { - emit('cancel'); + function handleCancel(e: Event) { + emit('cancel', e); } function handleFullScreen(e: Event) { e?.stopPropagation(); diff --git a/src/components/Modal/src/components/ModalFooter.vue b/src/components/Modal/src/components/ModalFooter.vue index 09094813..10ba4cd4 100644 --- a/src/components/Modal/src/components/ModalFooter.vue +++ b/src/components/Modal/src/components/ModalFooter.vue @@ -26,12 +26,12 @@ props: basicProps, emits: ['ok', 'cancel'], setup(_, { emit }) { - function handleOk() { - emit('ok'); + function handleOk(e: Event) { + emit('ok', e); } - function handleCancel() { - emit('cancel'); + function handleCancel(e: Event) { + emit('cancel', e); } return { handleOk, handleCancel }; }, From 8e410fc6401847d8e5545468b5ce6fd7ce9fc5cc Mon Sep 17 00:00:00 2001 From: Vben Date: Thu, 10 Jun 2021 21:46:46 +0800 Subject: [PATCH 19/56] feat: add CropperAvatar component --- CHANGELOG.zh_CN.md | 7 + package.json | 2 +- .../Application/src/search/AppSearchModal.vue | 7 +- .../CountDown/src/CountdownInput.vue | 7 +- src/components/Cropper/index.ts | 9 +- src/components/Cropper/src/AvatarCropper.vue | 15 - src/components/Cropper/src/CopperModal.vue | 258 ++++++++++++++++++ src/components/Cropper/src/Cropper.vue | 148 +++++++--- src/components/Cropper/src/CropperAvatar.vue | 90 ++++++ src/components/Cropper/src/typing.ts | 8 + src/locales/lang/en/component.ts | 6 + src/locales/lang/zh_CN/component.ts | 6 + src/router/menus/modules/demo/comp.ts | 7 +- src/router/menus/modules/demo/feat.ts | 6 - src/views/demo/comp/cropper/index.vue | 76 ++++-- src/views/demo/comp/upload/index.vue | 1 - src/views/demo/feat/copy/index.vue | 3 +- test/server/service/FileService.ts | 2 - yarn.lock | 15 +- 19 files changed, 551 insertions(+), 122 deletions(-) delete mode 100644 src/components/Cropper/src/AvatarCropper.vue create mode 100644 src/components/Cropper/src/CopperModal.vue create mode 100644 src/components/Cropper/src/CropperAvatar.vue create mode 100644 src/components/Cropper/src/typing.ts diff --git a/CHANGELOG.zh_CN.md b/CHANGELOG.zh_CN.md index 9a603fcd..6798f3d6 100644 --- a/CHANGELOG.zh_CN.md +++ b/CHANGELOG.zh_CN.md @@ -1,3 +1,10 @@ +## Wip + +### ✨ Features + +- `Cropper` 头像裁剪新增圆形裁剪功能 +- 新增头像上传组件 + ## 2.4.2(2021-06-10) ### ✨ Refactor diff --git a/package.json b/package.json index 1bfbde1d..ba9db21c 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "@logicflow/extension": "^0.4.13", "@vueuse/core": "^5.0.2", "@zxcvbn-ts/core": "^0.3.0", - "ant-design-vue": "2.1.2", + "ant-design-vue": "2.1.6", "axios": "^0.21.1", "codemirror": "^5.61.1", "cropperjs": "^1.5.11", diff --git a/src/components/Application/src/search/AppSearchModal.vue b/src/components/Application/src/search/AppSearchModal.vue index f4be1017..5a107bda 100644 --- a/src/components/Application/src/search/AppSearchModal.vue +++ b/src/components/Application/src/search/AppSearchModal.vue @@ -4,7 +4,7 @@
- - + {{ t('common.cancelText') }} @@ -59,7 +59,6 @@ diff --git a/src/components/Cropper/src/CopperModal.vue b/src/components/Cropper/src/CopperModal.vue new file mode 100644 index 00000000..3883cd17 --- /dev/null +++ b/src/components/Cropper/src/CopperModal.vue @@ -0,0 +1,258 @@ + + + + diff --git a/src/components/Cropper/src/Cropper.vue b/src/components/Cropper/src/Cropper.vue index c5b912a7..0516c5e0 100644 --- a/src/components/Cropper/src/Cropper.vue +++ b/src/components/Cropper/src/Cropper.vue @@ -1,5 +1,5 @@ + diff --git a/src/components/Upload/src/UploadModal.vue b/src/components/Upload/src/UploadModal.vue index 5e1faba1..e2fa480d 100644 --- a/src/components/Upload/src/UploadModal.vue +++ b/src/components/Upload/src/UploadModal.vue @@ -50,7 +50,7 @@ import { useUploadType } from './useUpload'; import { useMessage } from '/@/hooks/web/useMessage'; // types - import { FileItem, UploadResultStatus } from './types'; + import { FileItem, UploadResultStatus } from './typing'; import { basicProps } from './props'; import { createTableColumns, createActionColumn } from './data'; // utils @@ -58,9 +58,9 @@ import { buildUUID } from '/@/utils/uuid'; import { isFunction } from '/@/utils/is'; import { warn } from '/@/utils/log'; - import FileList from './FileList'; - + import FileList from './FileList.vue'; import { useI18n } from '/@/hooks/web/useI18n'; + export default defineComponent({ components: { BasicModal, Upload, Alert, FileList }, props: { @@ -70,20 +70,20 @@ default: () => [], }, }, - emits: ['change', 'register'], + emits: ['change', 'register', 'delete'], setup(props, { emit }) { - const { t } = useI18n(); - - // 是否正在上传 - const isUploadingRef = ref(false); - const fileListRef = ref([]); const state = reactive<{ fileList: FileItem[] }>({ fileList: [], }); + // 是否正在上传 + const isUploadingRef = ref(false); + const fileListRef = ref([]); + const { accept, helpText, maxNumber, maxSize } = toRefs(props); + + const { t } = useI18n(); const [register, { closeModal }] = useModalInner(); - const { accept, helpText, maxNumber, maxSize } = toRefs(props); const { getAccept, getStringAccept, getHelpText } = useUploadType({ acceptRef: accept, helpTextRef: helpText, @@ -162,10 +162,12 @@ } return false; } + // 删除 function handleRemove(record: FileItem) { const index = fileListRef.value.findIndex((item) => item.uuid === record.uuid); index !== -1 && fileListRef.value.splice(index, 1); + emit('delete', record); } // 预览 diff --git a/src/components/Upload/src/UploadPreviewModal.vue b/src/components/Upload/src/UploadPreviewModal.vue index 9929aff0..dca152ab 100644 --- a/src/components/Upload/src/UploadPreviewModal.vue +++ b/src/components/Upload/src/UploadPreviewModal.vue @@ -12,18 +12,15 @@ + diff --git a/src/components/Preview/src/functional.ts b/src/components/Preview/src/functional.ts index 0f9eba0a..1f4ba671 100644 --- a/src/components/Preview/src/functional.ts +++ b/src/components/Preview/src/functional.ts @@ -1,11 +1,9 @@ -import ImgPreview from './index'; +import type { Options, Props } from './typing'; +import ImgPreview from './Functional.vue'; import { isClient } from '/@/utils/is'; - -import type { Options, Props } from './types'; - import { createVNode, render } from 'vue'; -let instance: any = null; +let instance: ReturnType | null = null; export function createImgPreview(options: Options) { if (!isClient) return; const { imageList, show = true, index = 0 } = options; diff --git a/src/components/Preview/src/index.less b/src/components/Preview/src/index.less deleted file mode 100644 index 0732a24d..00000000 --- a/src/components/Preview/src/index.less +++ /dev/null @@ -1,118 +0,0 @@ -.img-preview { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: @preview-comp-z-index; - background: rgba(0, 0, 0, 0.5); - user-select: none; - - &-content { - display: flex; - width: 100%; - height: 100%; - color: @white; - justify-content: center; - align-items: center; - } - - &-image { - cursor: pointer; - transition: transform 0.3s; - } - - &__close { - position: absolute; - top: -40px; - right: -40px; - width: 80px; - height: 80px; - overflow: hidden; - color: @white; - cursor: pointer; - background-color: rgba(0, 0, 0, 0.5); - border-radius: 50%; - transition: all 0.2s; - - &-icon { - position: absolute; - top: 46px; - left: 16px; - font-size: 16px; - } - - &:hover { - background-color: rgba(0, 0, 0, 0.8); - } - } - - &__index { - position: absolute; - bottom: 5%; - left: 50%; - padding: 0 22px; - font-size: 16px; - background: rgba(109, 109, 109, 0.6); - border-radius: 15px; - transform: translateX(-50%); - } - - &__controller { - position: absolute; - bottom: 10%; - left: 50%; - display: flex; - width: 260px; - height: 44px; - padding: 0 22px; - margin-left: -139px; - background: rgba(109, 109, 109, 0.6); - border-radius: 22px; - justify-content: center; - - &-item { - display: flex; - height: 100%; - padding: 0 9px; - font-size: 24px; - cursor: pointer; - transition: all 0.2s; - - &:hover { - transform: scale(1.2); - } - - img { - width: 1em; - } - } - } - - &__arrow { - position: absolute; - top: 50%; - display: flex; - align-items: center; - justify-content: center; - width: 50px; - height: 50px; - font-size: 28px; - cursor: pointer; - background-color: rgba(0, 0, 0, 0.5); - border-radius: 50%; - transition: all 0.2s; - - &:hover { - background-color: rgba(0, 0, 0, 0.8); - } - - &.left { - left: 50px; - } - - &.right { - right: 50px; - } - } -} diff --git a/src/components/Preview/src/index.tsx b/src/components/Preview/src/index.tsx deleted file mode 100644 index c674aa5c..00000000 --- a/src/components/Preview/src/index.tsx +++ /dev/null @@ -1,305 +0,0 @@ -import './index.less'; - -import { defineComponent, ref, unref, computed, reactive, watchEffect } from 'vue'; - -// @ts-ignore -import { basicProps } from './props'; -// @ts-ignore -import { Props } from './types'; - -import { CloseOutlined, LeftOutlined, RightOutlined } from '@ant-design/icons-vue'; -// import { Spin } from 'ant-design-vue'; - -import resumeSvg from '/@/assets/svg/preview/resume.svg'; -import rotateSvg from '/@/assets/svg/preview/p-rotate.svg'; -import scaleSvg from '/@/assets/svg/preview/scale.svg'; -import unScaleSvg from '/@/assets/svg/preview/unscale.svg'; -import unRotateSvg from '/@/assets/svg/preview/unrotate.svg'; -enum StatueEnum { - LOADING, - DONE, - FAIL, -} -interface ImgState { - currentUrl: string; - imgScale: number; - imgRotate: number; - imgTop: number; - imgLeft: number; - currentIndex: number; - status: StatueEnum; - moveX: number; - moveY: number; - show: boolean; -} - -const prefixCls = 'img-preview'; -export default defineComponent({ - name: 'ImagePreview', - props: basicProps, - setup(props: Props) { - const imgState = reactive({ - currentUrl: '', - imgScale: 1, - imgRotate: 0, - imgTop: 0, - imgLeft: 0, - status: StatueEnum.LOADING, - currentIndex: 0, - moveX: 0, - moveY: 0, - show: props.show, - }); - - const wrapElRef = ref(null); - const imgElRef = ref(null); - - // 初始化 - function init() { - initMouseWheel(); - const { index, imageList } = props; - - if (!imageList || !imageList.length) { - throw new Error('imageList is undefined'); - } - imgState.currentIndex = index; - handleIChangeImage(imageList[index]); - } - - // 重置 - function initState() { - imgState.imgScale = 1; - imgState.imgRotate = 0; - imgState.imgTop = 0; - imgState.imgLeft = 0; - } - - // 初始化鼠标滚轮事件 - function initMouseWheel() { - const wrapEl = unref(wrapElRef); - if (!wrapEl) { - return; - } - (wrapEl as any).onmousewheel = scrollFunc; - // 火狐浏览器没有onmousewheel事件,用DOMMouseScroll代替 - document.body.addEventListener('DOMMouseScroll', scrollFunc); - // 禁止火狐浏览器下拖拽图片的默认事件 - document.ondragstart = function () { - return false; - }; - } - - // 监听鼠标滚轮 - function scrollFunc(e: any) { - e = e || window.event; - e.delta = e.wheelDelta || -e.detail; - - e.preventDefault(); - if (e.delta > 0) { - // 滑轮向上滚动 - scaleFunc(0.015); - } - if (e.delta < 0) { - // 滑轮向下滚动 - scaleFunc(-0.015); - } - } - // 缩放函数 - function scaleFunc(num: number) { - if (imgState.imgScale <= 0.2 && num < 0) return; - imgState.imgScale += num; - } - - // 旋转图片 - function rotateFunc(deg: number) { - imgState.imgRotate += deg; - } - - // 鼠标事件 - function handleMouseUp() { - const imgEl = unref(imgElRef); - if (!imgEl) return; - imgEl.onmousemove = null; - } - - // 更换图片 - function handleIChangeImage(url: string) { - imgState.status = StatueEnum.LOADING; - const img = new Image(); - img.src = url; - img.onload = () => { - imgState.currentUrl = url; - imgState.status = StatueEnum.DONE; - }; - img.onerror = () => { - imgState.status = StatueEnum.FAIL; - }; - } - - // 关闭 - function handleClose(e: MouseEvent) { - e && e.stopPropagation(); - imgState.show = false; - // 移除火狐浏览器下的鼠标滚动事件 - document.body.removeEventListener('DOMMouseScroll', scrollFunc); - // 恢复火狐及Safari浏览器下的图片拖拽 - document.ondragstart = null; - } - - // 图片复原 - function resume() { - initState(); - } - - // 上一页下一页 - function handleChange(direction: 'left' | 'right') { - const { currentIndex } = imgState; - const { imageList } = props; - if (direction === 'left') { - imgState.currentIndex--; - if (currentIndex <= 0) { - imgState.currentIndex = imageList.length - 1; - } - } - if (direction === 'right') { - imgState.currentIndex++; - if (currentIndex >= imageList.length - 1) { - imgState.currentIndex = 0; - } - } - handleIChangeImage(imageList[imgState.currentIndex]); - } - - function handleAddMoveListener(e: MouseEvent) { - e = e || window.event; - imgState.moveX = e.clientX; - imgState.moveY = e.clientY; - const imgEl = unref(imgElRef); - if (imgEl) { - imgEl.onmousemove = moveFunc; - } - } - - function moveFunc(e: MouseEvent) { - e = e || window.event; - e.preventDefault(); - const movementX = e.clientX - imgState.moveX; - const movementY = e.clientY - imgState.moveY; - imgState.imgLeft += movementX; - imgState.imgTop += movementY; - imgState.moveX = e.clientX; - imgState.moveY = e.clientY; - } - - // 获取图片样式 - const getImageStyle = computed(() => { - const { imgScale, imgRotate, imgTop, imgLeft } = imgState; - return { - transform: `scale(${imgScale}) rotate(${imgRotate}deg)`, - marginTop: `${imgTop}px`, - marginLeft: `${imgLeft}px`, - }; - }); - - const getIsMultipleImage = computed(() => { - const { imageList } = props; - return imageList.length > 1; - }); - - watchEffect(() => { - if (props.show) { - init(); - } - if (props.imageList) { - initState(); - } - }); - - const renderClose = () => { - return ( -
- -
- ); - }; - - const renderIndex = () => { - if (!unref(getIsMultipleImage)) { - return null; - } - const { currentIndex } = imgState; - const { imageList } = props; - return ( -
- {currentIndex + 1} / {imageList.length} -
- ); - }; - - const renderController = () => { - return ( -
-
scaleFunc(-0.15)}> - -
-
scaleFunc(0.15)}> - -
-
- -
-
rotateFunc(-90)}> - -
-
rotateFunc(90)}> - -
-
- ); - }; - - const renderArrow = (direction: 'left' | 'right') => { - if (!unref(getIsMultipleImage)) { - return null; - } - return ( -
handleChange(direction)}> - {direction === 'left' ? : } -
- ); - }; - - return () => { - return ( - imgState.show && ( -
-
- {/*}*/} - {/* spinning={true}*/} - {/* class={[*/} - {/* `${prefixCls}-image`,*/} - {/* {*/} - {/* hidden: imgState.status !== StatueEnum.LOADING,*/} - {/* },*/} - {/* ]}*/} - {/*/>*/} - - {renderClose()} - {renderIndex()} - {renderController()} - {renderArrow('left')} - {renderArrow('right')} -
-
- ) - ); - }; - }, -}); diff --git a/src/components/Preview/src/props.ts b/src/components/Preview/src/props.ts deleted file mode 100644 index c6d7c8af..00000000 --- a/src/components/Preview/src/props.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { PropType } from 'vue'; -export const basicProps = { - show: { - type: Boolean as PropType, - default: false, - }, - imageList: { - type: [Array] as PropType, - default: null, - }, - index: { - type: Number as PropType, - default: 0, - }, -}; diff --git a/src/components/Preview/src/types.ts b/src/components/Preview/src/typing.ts similarity index 100% rename from src/components/Preview/src/types.ts rename to src/components/Preview/src/typing.ts diff --git a/src/views/demo/feat/img-preview/index.vue b/src/views/demo/feat/img-preview/index.vue index cadae76a..79a81c32 100644 --- a/src/views/demo/feat/img-preview/index.vue +++ b/src/views/demo/feat/img-preview/index.vue @@ -1,7 +1,7 @@ diff --git a/src/components/Table/src/components/HeaderCell.vue b/src/components/Table/src/components/HeaderCell.vue index 47dbebb1..4c75682f 100644 --- a/src/components/Table/src/components/HeaderCell.vue +++ b/src/components/Table/src/components/HeaderCell.vue @@ -8,12 +8,11 @@ diff --git a/yarn.lock b/yarn.lock index c0ba5b1d..e9fc5ef0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1184,17 +1184,17 @@ dependencies: cross-fetch "^3.0.6" -"@iconify/iconify@^2.0.1": - version "2.0.1" - resolved "https://registry.npmjs.org/@iconify/iconify/-/iconify-2.0.1.tgz#4927812922d50b378699694b5e72e22a1acc9d2f" - integrity sha512-heGCmdiRc58+TQjKPiem8cmNZj7YXDG3TphRVw0UGjsz8/OKgN2ncBPy1kfFIiv5aKhUsij6WVTfOMUS7YgTbA== +"@iconify/iconify@^2.0.2": + version "2.0.2" + resolved "https://registry.npmjs.org/@iconify/iconify/-/iconify-2.0.2.tgz#8e8be6c8f20042ab69324bc6db6fc884be98b418" + integrity sha512-m3MDKXYRRsrVLZFFUkSaTv9/jTk0sLOlIhlmupj2/VhHnZt0i3ACyUD7rx/Vd5bLvtotrHaT5e/ZOLP7uiFmKQ== dependencies: cross-fetch "^3.0.6" -"@iconify/json@^1.1.356": - version "1.1.356" - resolved "https://registry.npmjs.org/@iconify/json/-/json-1.1.356.tgz#248b25843cf91618dff7ef4494a1b331efd1eb82" - integrity sha512-HeG9neoS5oatUTF6zlAAyDNPxbj0NvGDFqzd4wBtqu5mE4/xjhDO+S1obkgqpBrDedgoXDwIFkGx9Mx1HJCnaw== +"@iconify/json@^1.1.357": + version "1.1.357" + resolved "https://registry.npmjs.org/@iconify/json/-/json-1.1.357.tgz#63dd3b358b80a3774e24ce0a136488b819a20dbd" + integrity sha512-X4tXnyCKCAKRopGtvQjp3LmPX3TaUUfi2DwD41SQItBp9PbsZXg9+tYJbWjl0+gFFv7ikdzAp+yGIaXuZT/k5g== "@intlify/core-base@9.1.6": version "9.1.6" @@ -1646,6 +1646,11 @@ "@types/through" "*" rxjs "^6.4.0" +"@types/intro.js@^3.0.1": + version "3.0.1" + resolved "https://registry.npmjs.org/@types/intro.js/-/intro.js-3.0.1.tgz#2a5272d6ceb715676f496fd0060eedc70d98c6fe" + integrity sha512-L4vCKY/4ZFpRgILDHd3oacARWYKYpz3oJfjweoc0ooM+OoM1HEtGRFM0JuNYQNTrgUXe+R4rUyLDYSeSnrmdLw== + "@types/json-schema@^7.0.7": version "7.0.7" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" @@ -2006,10 +2011,10 @@ "@vue/compiler-dom" "3.0.11" "@vue/shared" "3.0.11" -"@vue/devtools-api@^6.0.0-beta.10": - version "6.0.0-beta.10" - resolved "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.0.0-beta.10.tgz#f39da7618cee292e39c7274227c34163e30eb3ca" - integrity sha512-nktQYRnIFrh4DdXiCBjHnsHOMZXDIVcP9qlm/DMfxmjJMtpMGrSZCOKP8j7kDhObNHyqlicwoGLd+a4hf4x9ww== +"@vue/devtools-api@^6.0.0-beta.14": + version "6.0.0-beta.14" + resolved "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.0.0-beta.14.tgz#6ed2d6f8d66a9256c9ad04bfff08309ba87b9723" + integrity sha512-44fPrrN1cqcs6bFkT0C+yxTM6PZXLbR+ESh1U1j8UD22yO04gXvxH62HApMjLbS3WqJO/iCNC+CYT+evPQh2EQ== "@vue/devtools-api@^6.0.0-beta.7": version "6.0.0-beta.11" @@ -5863,6 +5868,11 @@ into-stream@^3.1.0: from2 "^2.1.1" p-is-promise "^1.1.0" +intro.js@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/intro.js/-/intro.js-4.0.0.tgz#6897f0dc6bb9997f73613ae3c7cd26e16b05a5eb" + integrity sha512-IS8+p4rpnWUq2Vd8YRgjR8w9lbyLvT0ptscBqA4iudO68oven39CvxHfxopfwlNUGgmgcyX17DOETof+D90AXA== + is-accessor-descriptor@^0.1.6: version "0.1.6" resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" @@ -8143,10 +8153,10 @@ postcss@^8.3.0: nanoid "^3.1.23" source-map-js "^0.6.2" -postcss@^8.3.4: - version "8.3.4" - resolved "https://registry.npmjs.org/postcss/-/postcss-8.3.4.tgz#41ece1c43f2f7c74dc7d90144047ce052757b822" - integrity sha512-/tZY0PXExXXnNhKv3TOvZAOUYRyuqcCbBm2c17YMDK0PlVII3K7/LKdt3ScHL+hhouddjUWi+1sKDf9xXW+8YA== +postcss@^8.3.5: + version "8.3.5" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.3.5.tgz#982216b113412bc20a86289e91eb994952a5b709" + integrity sha512-NxTuJocUhYGsMiMFHDUkmjSKT3EdH4/WbGF6GCi1NDGk+vbcUTun4fpbOqaPtD8IIsztA2ilZm2DhYCuyN58gA== dependencies: colorette "^1.2.2" nanoid "^3.1.23" @@ -8878,10 +8888,10 @@ rollup-plugin-visualizer@5.5.0: source-map "^0.7.3" yargs "^16.2.0" -rollup@^2.38.5, rollup@^2.43.1, rollup@^2.51.2, rollup@^2.52.0: - version "2.52.0" - resolved "https://registry.npmjs.org/rollup/-/rollup-2.52.0.tgz#9df3de6028fae79569a985942b81110205a5a411" - integrity sha512-lSkBDGsVoXjqaBf7dsHwxBJz+p+hJEP72P+LOitA0yVs+Nzxj76FidkZE2thrmhjwGqLYiJo39opi7mAfaQ/Vg== +rollup@^2.38.5, rollup@^2.43.1, rollup@^2.51.2, rollup@^2.52.1: + version "2.52.1" + resolved "https://registry.npmjs.org/rollup/-/rollup-2.52.1.tgz#dd1cc178d70cf35c48d943fc06fdc32d546e6876" + integrity sha512-/SPqz8UGnp4P1hq6wc9gdTqA2bXQXGx13TtoL03GBm6qGRI6Hm3p4Io7GeiHNLl0BsQAne1JNYY+q/apcY933w== optionalDependencies: fsevents "~2.3.2" @@ -10079,10 +10089,10 @@ typescript-vscode-sh-plugin@^0.6.14: resolved "https://registry.npmjs.org/typescript-vscode-sh-plugin/-/typescript-vscode-sh-plugin-0.6.14.tgz#a81031b502f6346a26ea49ce082438c3e353bb38" integrity sha512-AkNlRBbI6K7gk29O92qthNSvc6jjmNQ6isVXoYxkFwPa8D04tIv2SOPd+sd+mNpso4tNdL2gy7nVtrd5yFqvlA== -typescript@4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.2.tgz#399ab18aac45802d6f2498de5054fcbbe716a805" - integrity sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw== +typescript@4.3.3: + version "4.3.3" + resolved "https://registry.npmjs.org/typescript/-/typescript-4.3.3.tgz#5401db69bd3203daf1851a1a74d199cb3112c11a" + integrity sha512-rUvLW0WtF7PF2b9yenwWUi9Da9euvDRhmH7BLyBG4DCFfOJ850LGNknmRpp8Z8kXNUPObdZQEfKOiHtXuQHHKA== uglify-js@^3.1.4: version "3.13.3" @@ -10859,12 +10869,12 @@ vue-json-pretty@^2.0.2: resolved "https://registry.npmjs.com/vue-json-pretty/-/vue-json-pretty-2.0.2.tgz#cb8f559af15ea3a2ee53b2742672c7791826d6a3" integrity sha512-Vn7SX3XR9cfvGRNoTDNID89GmvVUMb7/fLUX3C3n0Qptga0N7hp7Zwspui1I1XN5pE+PeoVghCSYty+bi8KnjA== -vue-router@^4.0.8: - version "4.0.8" - resolved "https://registry.npmjs.org/vue-router/-/vue-router-4.0.8.tgz#55d4290a3122444edbc91a3cd2492bb1d0cef494" - integrity sha512-42mWSQaH7CCBQDspQTHv63f34VEnZC20g9QNK4WJ/zW8SdIUeT6TQ2i/78fjF/pVBUPLBWrGhvB7uDnaz7O/pA== +vue-router@^4.0.9: + version "4.0.9" + resolved "https://registry.npmjs.org/vue-router/-/vue-router-4.0.9.tgz#248496941b79c4c1010f6ebfcf235cd4267d85da" + integrity sha512-i3IaZJ57YeMbRHQlqKyXdUMr5NzTCcJkn3f8u38TsZjYWtGcd3IX2zRd3389SCOwuRf11mgfHAyngR6FVDE9og== dependencies: - "@vue/devtools-api" "^6.0.0-beta.10" + "@vue/devtools-api" "^6.0.0-beta.14" vue-tsc@^0.1.7: version "0.1.7" From 0acc4ab2dd70a239bd13929edede02b283feb7c2 Mon Sep 17 00:00:00 2001 From: Vben Date: Thu, 17 Jun 2021 21:43:53 +0800 Subject: [PATCH 45/56] perf(locale): reduce the number of multilingual files --- .vscode/settings.json | 2 +- CHANGELOG.zh_CN.md | 4 + package.json | 4 +- src/locales/lang/en/routes/demo.ts | 194 ++++++++++++++++++ src/locales/lang/en/routes/demo/charts.ts | 9 - src/locales/lang/en/routes/demo/comp.ts | 38 ---- src/locales/lang/en/routes/demo/editor.ts | 9 - src/locales/lang/en/routes/demo/excel.ts | 7 - src/locales/lang/en/routes/demo/feat.ts | 29 --- src/locales/lang/en/routes/demo/flow.ts | 4 - src/locales/lang/en/routes/demo/form.ts | 11 - src/locales/lang/en/routes/demo/iframe.ts | 6 - src/locales/lang/en/routes/demo/level.ts | 3 - src/locales/lang/en/routes/demo/page.ts | 30 --- src/locales/lang/en/routes/demo/permission.ts | 13 -- src/locales/lang/en/routes/demo/setup.ts | 3 - src/locales/lang/en/routes/demo/system.ts | 12 -- src/locales/lang/en/routes/demo/table.ts | 20 -- src/locales/lang/zh_CN/routes/demo.ts | 184 +++++++++++++++++ src/locales/lang/zh_CN/routes/demo/charts.ts | 9 - src/locales/lang/zh_CN/routes/demo/comp.ts | 37 ---- src/locales/lang/zh_CN/routes/demo/editor.ts | 9 - src/locales/lang/zh_CN/routes/demo/excel.ts | 7 - src/locales/lang/zh_CN/routes/demo/feat.ts | 29 --- src/locales/lang/zh_CN/routes/demo/flow.ts | 4 - src/locales/lang/zh_CN/routes/demo/form.ts | 11 - src/locales/lang/zh_CN/routes/demo/iframe.ts | 6 - src/locales/lang/zh_CN/routes/demo/level.ts | 3 - src/locales/lang/zh_CN/routes/demo/page.ts | 29 --- .../lang/zh_CN/routes/demo/permission.ts | 13 -- src/locales/lang/zh_CN/routes/demo/setup.ts | 3 - src/locales/lang/zh_CN/routes/demo/system.ts | 12 -- src/locales/lang/zh_CN/routes/demo/table.ts | 20 -- src/views/demo/setup/index.vue | 2 +- yarn.lock | 18 +- 35 files changed, 395 insertions(+), 399 deletions(-) create mode 100644 src/locales/lang/en/routes/demo.ts delete mode 100644 src/locales/lang/en/routes/demo/charts.ts delete mode 100644 src/locales/lang/en/routes/demo/comp.ts delete mode 100644 src/locales/lang/en/routes/demo/editor.ts delete mode 100644 src/locales/lang/en/routes/demo/excel.ts delete mode 100644 src/locales/lang/en/routes/demo/feat.ts delete mode 100644 src/locales/lang/en/routes/demo/flow.ts delete mode 100644 src/locales/lang/en/routes/demo/form.ts delete mode 100644 src/locales/lang/en/routes/demo/iframe.ts delete mode 100644 src/locales/lang/en/routes/demo/level.ts delete mode 100644 src/locales/lang/en/routes/demo/page.ts delete mode 100644 src/locales/lang/en/routes/demo/permission.ts delete mode 100644 src/locales/lang/en/routes/demo/setup.ts delete mode 100644 src/locales/lang/en/routes/demo/system.ts delete mode 100644 src/locales/lang/en/routes/demo/table.ts create mode 100644 src/locales/lang/zh_CN/routes/demo.ts delete mode 100644 src/locales/lang/zh_CN/routes/demo/charts.ts delete mode 100644 src/locales/lang/zh_CN/routes/demo/comp.ts delete mode 100644 src/locales/lang/zh_CN/routes/demo/editor.ts delete mode 100644 src/locales/lang/zh_CN/routes/demo/excel.ts delete mode 100644 src/locales/lang/zh_CN/routes/demo/feat.ts delete mode 100644 src/locales/lang/zh_CN/routes/demo/flow.ts delete mode 100644 src/locales/lang/zh_CN/routes/demo/form.ts delete mode 100644 src/locales/lang/zh_CN/routes/demo/iframe.ts delete mode 100644 src/locales/lang/zh_CN/routes/demo/level.ts delete mode 100644 src/locales/lang/zh_CN/routes/demo/page.ts delete mode 100644 src/locales/lang/zh_CN/routes/demo/permission.ts delete mode 100644 src/locales/lang/zh_CN/routes/demo/setup.ts delete mode 100644 src/locales/lang/zh_CN/routes/demo/system.ts delete mode 100644 src/locales/lang/zh_CN/routes/demo/table.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 83b85b41..a1b2021e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -118,5 +118,5 @@ "i18n-ally.enabledParsers": ["ts"], "i18n-ally.sourceLanguage": "en", "i18n-ally.enabledFrameworks": ["vue", "react"], - "cSpell.words": ["vben", "windi", "browserslist", "esnext"] + "cSpell.words": ["vben", "windi", "browserslist", "esnext", "antv", "tinymce", "qrcode"] } diff --git a/CHANGELOG.zh_CN.md b/CHANGELOG.zh_CN.md index aa128cf5..b471c136 100644 --- a/CHANGELOG.zh_CN.md +++ b/CHANGELOG.zh_CN.md @@ -4,6 +4,10 @@ - 移除`useExpose`,使用组件自身提供的`expose`代替 +### ⚡ Performance Improvements + +- **Locale** 合并多语言文件,减少文件数量 + ### ✨ Features - **CropperImage** `Cropper` 头像裁剪新增圆形裁剪功能 diff --git a/package.json b/package.json index 29eed4f8..9e90a162 100644 --- a/package.json +++ b/package.json @@ -33,8 +33,8 @@ }, "dependencies": { "@iconify/iconify": "^2.0.2", - "@logicflow/core": "^0.4.14", - "@logicflow/extension": "^0.4.14", + "@logicflow/core": "^0.4.15", + "@logicflow/extension": "^0.4.15", "@vueuse/core": "^5.0.3", "@zxcvbn-ts/core": "^0.3.0", "ant-design-vue": "2.1.6", diff --git a/src/locales/lang/en/routes/demo.ts b/src/locales/lang/en/routes/demo.ts new file mode 100644 index 00000000..c90e8577 --- /dev/null +++ b/src/locales/lang/en/routes/demo.ts @@ -0,0 +1,194 @@ +export default { + charts: { + baiduMap: 'Baidu map', + aMap: 'A map', + googleMap: 'Google map', + charts: 'Chart', + map: 'Map', + line: 'Line', + pie: 'Pie', + }, + comp: { + comp: 'Component', + basic: 'Basic', + transition: 'Animation', + countTo: 'Count To', + + scroll: 'Scroll', + scrollBasic: 'Basic', + scrollAction: 'Scroll Function', + virtualScroll: 'Virtual Scroll', + + tree: 'Tree', + + treeBasic: 'Basic', + editTree: 'Searchable/toolbar', + actionTree: 'Function operation', + + modal: 'Modal', + drawer: 'Drawer', + desc: 'Desc', + + lazy: 'Lazy', + lazyBasic: 'Basic', + lazyTransition: 'Animation', + + verify: 'Verify', + verifyDrag: 'Drag ', + verifyRotate: 'Picture Restore', + + qrcode: 'QR code', + strength: 'Password strength', + upload: 'Upload', + + loading: 'Loading', + + time: 'Relative Time', + cropperImage: 'Cropper Image', + }, + editor: { + editor: 'Editor', + jsonEditor: 'Json editor', + markdown: 'Markdown editor', + + tinymce: 'Rich text', + tinymceBasic: 'Basic', + tinymceForm: 'embedded form', + }, + excel: { + excel: 'Excel', + customExport: 'Select export format', + jsonExport: 'JSON data export', + arrayExport: 'Array data export', + importExcel: 'Import', + }, + feat: { + feat: 'Page Function', + icon: 'Icon', + tabs: 'Tabs', + sessionTimeout: 'Session Timeout', + print: 'Print', + contextMenu: 'Context Menu', + download: 'Download', + clickOutSide: 'ClickOutSide', + imgPreview: 'Picture Preview', + copy: 'Clipboard', + msg: 'Message prompt', + watermark: 'Watermark', + ripple: 'Ripple', + fullScreen: 'Full Screen', + errorLog: 'Error Log', + tab: 'Tab with parameters', + tab1: 'Tab with parameter 1', + tab2: 'Tab with parameter 2', + + ws: 'Websocket test', + + breadcrumb: 'Breadcrumbs', + breadcrumbFlat: 'Flat Mode', + breadcrumbFlatDetail: 'Flat mode details', + + breadcrumbChildren: 'Level mode', + breadcrumbChildrenDetail: 'Level mode detail', + }, + flow: { + name: 'Graphics editor', + flowChart: 'FlowChart', + }, + form: { + form: 'Form', + basic: 'Basic', + useForm: 'useForm', + refForm: 'RefForm', + advancedForm: 'Shrinkable', + ruleForm: 'Form validation', + dynamicForm: 'Dynamic', + customerForm: 'Custom', + appendForm: 'Append', + }, + iframe: { + frame: 'External', + antv: 'antVue doc (embedded)', + doc: 'Project doc (embedded)', + docExternal: 'Project doc (external)', + }, + level: { level: 'MultiMenu' }, + page: { + page: 'Page', + + form: 'Form', + formBasic: 'Basic Form', + formStep: 'Step Form', + formHigh: 'Advanced Form', + + desc: 'Details', + descBasic: 'Basic Details', + descHigh: 'Advanced Details', + + result: 'Result', + resultSuccess: 'Success', + resultFail: 'Failed', + + account: 'Personal', + accountCenter: 'Personal Center', + accountSetting: 'Personal Settings', + + exception: 'Exception', + netWorkError: 'Network Error', + notData: 'No data', + + list: 'List page', + listCard: 'Card list', + basic: 'Basic list', + listBasic: 'Basic list', + listSearch: 'Search list', + }, + permission: { + permission: 'Permission', + + front: 'front-end', + frontPage: 'Page', + frontBtn: 'Button', + frontTestA: 'Test page A', + frontTestB: 'Test page B', + + back: 'background', + backPage: 'Page', + backBtn: 'Button', + }, + setup: { + page: 'Intro page', + }, + system: { + moduleName: 'System management', + + account: 'Account management', + + password: 'Change password', + + dept: 'Department management', + + menu: 'Menu management', + role: 'Role management', + }, + table: { + table: 'Table', + + basic: 'Basic', + treeTable: 'Tree', + fetchTable: 'Remote loading', + fixedColumn: 'Fixed column', + customerCell: 'Custom column', + formTable: 'Open search', + useTable: 'UseTable', + refTable: 'RefTable', + multipleHeader: 'MultiLevel header', + mergeHeader: 'Merge cells', + expandTable: 'Expandable table', + fixedHeight: 'Fixed height', + footerTable: 'Footer', + editCellTable: 'Editable cell', + editRowTable: 'Editable row', + authColumn: 'Auth column', + }, +}; diff --git a/src/locales/lang/en/routes/demo/charts.ts b/src/locales/lang/en/routes/demo/charts.ts deleted file mode 100644 index 835b694e..00000000 --- a/src/locales/lang/en/routes/demo/charts.ts +++ /dev/null @@ -1,9 +0,0 @@ -export default { - baiduMap: 'Baidu map', - aMap: 'A map', - googleMap: 'Google map', - charts: 'Chart', - map: 'Map', - line: 'Line', - pie: 'Pie', -}; diff --git a/src/locales/lang/en/routes/demo/comp.ts b/src/locales/lang/en/routes/demo/comp.ts deleted file mode 100644 index c68ea5cd..00000000 --- a/src/locales/lang/en/routes/demo/comp.ts +++ /dev/null @@ -1,38 +0,0 @@ -export default { - comp: 'Component', - basic: 'Basic', - transition: 'Animation', - countTo: 'Count To', - - scroll: 'Scroll', - scrollBasic: 'Basic', - scrollAction: 'Scroll Function', - virtualScroll: 'Virtual Scroll', - - tree: 'Tree', - - treeBasic: 'Basic', - editTree: 'Searchable/toolbar', - actionTree: 'Function operation', - - modal: 'Modal', - drawer: 'Drawer', - desc: 'Desc', - - lazy: 'Lazy', - lazyBasic: 'Basic', - lazyTransition: 'Animation', - - verify: 'Verify', - verifyDrag: 'Drag ', - verifyRotate: 'Picture Restore', - - qrcode: 'QR code', - strength: 'Password strength', - upload: 'Upload', - - loading: 'Loading', - - time: 'Relative Time', - cropperImage: 'Cropper Image', -}; diff --git a/src/locales/lang/en/routes/demo/editor.ts b/src/locales/lang/en/routes/demo/editor.ts deleted file mode 100644 index 5ede507b..00000000 --- a/src/locales/lang/en/routes/demo/editor.ts +++ /dev/null @@ -1,9 +0,0 @@ -export default { - editor: 'Editor', - jsonEditor: 'Json editor', - markdown: 'Markdown editor', - - tinymce: 'Rich text', - tinymceBasic: 'Basic', - tinymceForm: 'embedded form', -}; diff --git a/src/locales/lang/en/routes/demo/excel.ts b/src/locales/lang/en/routes/demo/excel.ts deleted file mode 100644 index 7a84be6b..00000000 --- a/src/locales/lang/en/routes/demo/excel.ts +++ /dev/null @@ -1,7 +0,0 @@ -export default { - excel: 'Excel', - customExport: 'Select export format', - jsonExport: 'JSON data export', - arrayExport: 'Array data export', - importExcel: 'Import', -}; diff --git a/src/locales/lang/en/routes/demo/feat.ts b/src/locales/lang/en/routes/demo/feat.ts deleted file mode 100644 index 63a75c05..00000000 --- a/src/locales/lang/en/routes/demo/feat.ts +++ /dev/null @@ -1,29 +0,0 @@ -export default { - feat: 'Page Function', - icon: 'Icon', - tabs: 'Tabs', - sessionTimeout: 'Session Timeout', - print: 'Print', - contextMenu: 'Context Menu', - download: 'Download', - clickOutSide: 'ClickOutSide', - imgPreview: 'Picture Preview', - copy: 'Clipboard', - msg: 'Message prompt', - watermark: 'Watermark', - ripple: 'Ripple', - fullScreen: 'Full Screen', - errorLog: 'Error Log', - tab: 'Tab with parameters', - tab1: 'Tab with parameter 1', - tab2: 'Tab with parameter 2', - - ws: 'Websocket test', - - breadcrumb: 'Breadcrumbs', - breadcrumbFlat: 'Flat Mode', - breadcrumbFlatDetail: 'Flat mode details', - - breadcrumbChildren: 'Level mode', - breadcrumbChildrenDetail: 'Level mode detail', -}; diff --git a/src/locales/lang/en/routes/demo/flow.ts b/src/locales/lang/en/routes/demo/flow.ts deleted file mode 100644 index e4fbb9c2..00000000 --- a/src/locales/lang/en/routes/demo/flow.ts +++ /dev/null @@ -1,4 +0,0 @@ -export default { - name: 'Graphics editor', - flowChart: 'FlowChart', -}; diff --git a/src/locales/lang/en/routes/demo/form.ts b/src/locales/lang/en/routes/demo/form.ts deleted file mode 100644 index 314a6c2f..00000000 --- a/src/locales/lang/en/routes/demo/form.ts +++ /dev/null @@ -1,11 +0,0 @@ -export default { - form: 'Form', - basic: 'Basic', - useForm: 'useForm', - refForm: 'RefForm', - advancedForm: 'Shrinkable', - ruleForm: 'Form validation', - dynamicForm: 'Dynamic', - customerForm: 'Custom', - appendForm: 'Append', -}; diff --git a/src/locales/lang/en/routes/demo/iframe.ts b/src/locales/lang/en/routes/demo/iframe.ts deleted file mode 100644 index fd47ea9f..00000000 --- a/src/locales/lang/en/routes/demo/iframe.ts +++ /dev/null @@ -1,6 +0,0 @@ -export default { - frame: 'External', - antv: 'antVue doc (embedded)', - doc: 'Project doc (embedded)', - docExternal: 'Project doc (external)', -}; diff --git a/src/locales/lang/en/routes/demo/level.ts b/src/locales/lang/en/routes/demo/level.ts deleted file mode 100644 index 5c3e8bb7..00000000 --- a/src/locales/lang/en/routes/demo/level.ts +++ /dev/null @@ -1,3 +0,0 @@ -export default { - level: 'MultiMenu', -}; diff --git a/src/locales/lang/en/routes/demo/page.ts b/src/locales/lang/en/routes/demo/page.ts deleted file mode 100644 index 18998ef5..00000000 --- a/src/locales/lang/en/routes/demo/page.ts +++ /dev/null @@ -1,30 +0,0 @@ -export default { - page: 'Page', - - form: 'Form', - formBasic: 'Basic Form', - formStep: 'Step Form', - formHigh: 'Advanced Form', - - desc: 'Details', - descBasic: 'Basic Details', - descHigh: 'Advanced Details', - - result: 'Result', - resultSuccess: 'Success', - resultFail: 'Failed', - - account: 'Personal', - accountCenter: 'Personal Center', - accountSetting: 'Personal Settings', - - exception: 'Exception', - netWorkError: 'Network Error', - notData: 'No data', - - list: 'List page', - listCard: 'Card list', - basic: 'Basic list', - listBasic: 'Basic list', - listSearch: 'Search list', -}; diff --git a/src/locales/lang/en/routes/demo/permission.ts b/src/locales/lang/en/routes/demo/permission.ts deleted file mode 100644 index 0a2b3dae..00000000 --- a/src/locales/lang/en/routes/demo/permission.ts +++ /dev/null @@ -1,13 +0,0 @@ -export default { - permission: 'Permission', - - front: 'front-end', - frontPage: 'Page', - frontBtn: 'Button', - frontTestA: 'Test page A', - frontTestB: 'Test page B', - - back: 'background', - backPage: 'Page', - backBtn: 'Button', -}; diff --git a/src/locales/lang/en/routes/demo/setup.ts b/src/locales/lang/en/routes/demo/setup.ts deleted file mode 100644 index ae12c9fa..00000000 --- a/src/locales/lang/en/routes/demo/setup.ts +++ /dev/null @@ -1,3 +0,0 @@ -export default { - page: 'Intro page', -}; diff --git a/src/locales/lang/en/routes/demo/system.ts b/src/locales/lang/en/routes/demo/system.ts deleted file mode 100644 index fba0c78e..00000000 --- a/src/locales/lang/en/routes/demo/system.ts +++ /dev/null @@ -1,12 +0,0 @@ -export default { - moduleName: 'System management', - - account: 'Account management', - - password: 'Change password', - - dept: 'Department management', - - menu: 'Menu management', - role: 'Role management', -}; diff --git a/src/locales/lang/en/routes/demo/table.ts b/src/locales/lang/en/routes/demo/table.ts deleted file mode 100644 index c5a2dcc6..00000000 --- a/src/locales/lang/en/routes/demo/table.ts +++ /dev/null @@ -1,20 +0,0 @@ -export default { - table: 'Table', - - basic: 'Basic', - treeTable: 'Tree', - fetchTable: 'Remote loading', - fixedColumn: 'Fixed column', - customerCell: 'Custom column', - formTable: 'Open search', - useTable: 'UseTable', - refTable: 'RefTable', - multipleHeader: 'MultiLevel header', - mergeHeader: 'Merge cells', - expandTable: 'Expandable table', - fixedHeight: 'Fixed height', - footerTable: 'Footer', - editCellTable: 'Editable cell', - editRowTable: 'Editable row', - authColumn: 'Auth column', -}; diff --git a/src/locales/lang/zh_CN/routes/demo.ts b/src/locales/lang/zh_CN/routes/demo.ts new file mode 100644 index 00000000..65fea4cf --- /dev/null +++ b/src/locales/lang/zh_CN/routes/demo.ts @@ -0,0 +1,184 @@ +export default { + charts: { + baiduMap: '百度地图', + aMap: '高德地图', + googleMap: '谷歌地图', + charts: '图表', + map: '地图', + line: '折线图', + pie: '饼图', + }, + comp: { + comp: '组件', + basic: '基础组件', + transition: '动画组件', + countTo: '数字动画', + + scroll: '滚动组件', + scrollBasic: '基础滚动', + scrollAction: '滚动函数', + virtualScroll: '虚拟滚动', + + tree: 'Tree', + treeBasic: '基础树', + editTree: '可搜索/工具栏', + actionTree: '函数操作示例', + + modal: '弹窗扩展', + drawer: '抽屉扩展', + desc: '详情组件', + + lazy: '懒加载组件', + lazyBasic: '基础示例', + lazyTransition: '动画效果', + + verify: '验证组件', + verifyDrag: '拖拽校验', + verifyRotate: '图片还原', + + qrcode: '二维码组件', + strength: '密码强度组件', + upload: '上传组件', + + loading: 'Loading', + + time: '相对时间', + cropperImage: '图片裁剪', + }, + editor: { + editor: '编辑器', + jsonEditor: 'Json编辑器', + markdown: 'markdown编辑器', + + tinymce: '富文本', + tinymceBasic: '基础使用', + tinymceForm: '嵌入form', + }, + excel: { + excel: 'Excel', + customExport: '选择导出格式', + jsonExport: 'JSON数据导出', + arrayExport: 'Array数据导出', + importExcel: '导入', + }, + feat: { + feat: '功能', + icon: '图标', + sessionTimeout: '登录过期', + tabs: '标签页操作', + print: '打印', + contextMenu: '右键菜单', + download: '文件下载', + clickOutSide: 'ClickOutSide组件', + imgPreview: '图片预览', + copy: '剪切板', + msg: '消息提示', + watermark: '水印', + ripple: '水波纹', + fullScreen: '全屏', + errorLog: '错误日志', + tab: 'Tab带参', + tab1: 'Tab带参1', + tab2: 'Tab带参2', + ws: 'websocket测试', + breadcrumb: '面包屑导航', + breadcrumbFlat: '平级模式', + breadcrumbFlatDetail: '平级详情', + breadcrumbChildren: '层级模式', + breadcrumbChildrenDetail: '层级详情', + }, + flow: { + name: '图形编辑器', + flowChart: '流程图', + }, + form: { + form: 'Form', + basic: '基础表单', + useForm: 'useForm', + refForm: 'RefForm', + advancedForm: '可收缩表单', + ruleForm: '表单验证', + dynamicForm: '动态表单', + customerForm: '自定义组件', + appendForm: '表单增删示例', + }, + iframe: { + frame: '外部页面', + antv: 'antVue文档(内嵌)', + doc: '项目文档(内嵌)', + docExternal: '项目文档(外链)', + }, + level: { level: '多级菜单' }, + page: { + page: '页面', + + form: '表单页', + formBasic: '基础表单', + formStep: '分步表单', + formHigh: '高级表单', + + desc: '详情页', + descBasic: '基础详情页', + descHigh: '高级详情页', + + result: '结果页', + resultSuccess: '成功页', + resultFail: '失败页', + + account: '个人页', + accountCenter: '个人中心', + accountSetting: '个人设置', + + exception: '异常页', + netWorkError: '网络错误', + notData: '无数据', + + list: '列表页', + listCard: '卡片列表', + listBasic: '标准列表', + listSearch: '搜索列表', + }, + permission: { + permission: '权限管理', + + front: '基于前端权限', + frontPage: '页面权限', + frontBtn: '按钮权限', + frontTestA: '权限测试页A', + frontTestB: '权限测试页B', + + back: '基于后台权限', + backPage: '页面权限', + backBtn: '按钮权限', + }, + setup: { + page: '引导页', + }, + system: { + moduleName: '系统管理', + account: '账号管理', + password: '修改密码', + dept: '部门管理', + menu: '菜单管理', + role: '角色管理', + }, + table: { + table: 'Table', + basic: '基础表格', + treeTable: '树形表格', + fetchTable: '远程加载示例', + fixedColumn: '固定列', + customerCell: '自定义列', + formTable: '开启搜索区域', + useTable: 'UseTable', + refTable: 'RefTable', + multipleHeader: '多级表头', + mergeHeader: '合并单元格', + expandTable: '可展开表格', + fixedHeight: '定高/头部自定义', + footerTable: '表尾行合计', + editCellTable: '可编辑单元格', + editRowTable: '可编辑行', + authColumn: '权限列', + }, +}; diff --git a/src/locales/lang/zh_CN/routes/demo/charts.ts b/src/locales/lang/zh_CN/routes/demo/charts.ts deleted file mode 100644 index d22b655c..00000000 --- a/src/locales/lang/zh_CN/routes/demo/charts.ts +++ /dev/null @@ -1,9 +0,0 @@ -export default { - baiduMap: '百度地图', - aMap: '高德地图', - googleMap: '谷歌地图', - charts: '图表', - map: '地图', - line: '折线图', - pie: '饼图', -}; diff --git a/src/locales/lang/zh_CN/routes/demo/comp.ts b/src/locales/lang/zh_CN/routes/demo/comp.ts deleted file mode 100644 index 2bd3614a..00000000 --- a/src/locales/lang/zh_CN/routes/demo/comp.ts +++ /dev/null @@ -1,37 +0,0 @@ -export default { - comp: '组件', - basic: '基础组件', - transition: '动画组件', - countTo: '数字动画', - - scroll: '滚动组件', - scrollBasic: '基础滚动', - scrollAction: '滚动函数', - virtualScroll: '虚拟滚动', - - tree: 'Tree', - treeBasic: '基础树', - editTree: '可搜索/工具栏', - actionTree: '函数操作示例', - - modal: '弹窗扩展', - drawer: '抽屉扩展', - desc: '详情组件', - - lazy: '懒加载组件', - lazyBasic: '基础示例', - lazyTransition: '动画效果', - - verify: '验证组件', - verifyDrag: '拖拽校验', - verifyRotate: '图片还原', - - qrcode: '二维码组件', - strength: '密码强度组件', - upload: '上传组件', - - loading: 'Loading', - - time: '相对时间', - cropperImage: '图片裁剪', -}; diff --git a/src/locales/lang/zh_CN/routes/demo/editor.ts b/src/locales/lang/zh_CN/routes/demo/editor.ts deleted file mode 100644 index 4067b850..00000000 --- a/src/locales/lang/zh_CN/routes/demo/editor.ts +++ /dev/null @@ -1,9 +0,0 @@ -export default { - editor: '编辑器', - jsonEditor: 'Json编辑器', - markdown: 'markdown编辑器', - - tinymce: '富文本', - tinymceBasic: '基础使用', - tinymceForm: '嵌入form', -}; diff --git a/src/locales/lang/zh_CN/routes/demo/excel.ts b/src/locales/lang/zh_CN/routes/demo/excel.ts deleted file mode 100644 index 16c70597..00000000 --- a/src/locales/lang/zh_CN/routes/demo/excel.ts +++ /dev/null @@ -1,7 +0,0 @@ -export default { - excel: 'Excel', - customExport: '选择导出格式', - jsonExport: 'JSON数据导出', - arrayExport: 'Array数据导出', - importExcel: '导入', -}; diff --git a/src/locales/lang/zh_CN/routes/demo/feat.ts b/src/locales/lang/zh_CN/routes/demo/feat.ts deleted file mode 100644 index e30305b0..00000000 --- a/src/locales/lang/zh_CN/routes/demo/feat.ts +++ /dev/null @@ -1,29 +0,0 @@ -export default { - feat: '功能', - icon: '图标', - sessionTimeout: '登录过期', - tabs: '标签页操作', - print: '打印', - contextMenu: '右键菜单', - download: '文件下载', - clickOutSide: 'ClickOutSide组件', - imgPreview: '图片预览', - copy: '剪切板', - msg: '消息提示', - watermark: '水印', - ripple: '水波纹', - fullScreen: '全屏', - errorLog: '错误日志', - tab: 'Tab带参', - tab1: 'Tab带参1', - tab2: 'Tab带参2', - - ws: 'websocket测试', - - breadcrumb: '面包屑导航', - breadcrumbFlat: '平级模式', - breadcrumbFlatDetail: '平级详情', - - breadcrumbChildren: '层级模式', - breadcrumbChildrenDetail: '层级详情', -}; diff --git a/src/locales/lang/zh_CN/routes/demo/flow.ts b/src/locales/lang/zh_CN/routes/demo/flow.ts deleted file mode 100644 index f87c3e12..00000000 --- a/src/locales/lang/zh_CN/routes/demo/flow.ts +++ /dev/null @@ -1,4 +0,0 @@ -export default { - name: '图形编辑器', - flowChart: '流程图', -}; diff --git a/src/locales/lang/zh_CN/routes/demo/form.ts b/src/locales/lang/zh_CN/routes/demo/form.ts deleted file mode 100644 index fef80151..00000000 --- a/src/locales/lang/zh_CN/routes/demo/form.ts +++ /dev/null @@ -1,11 +0,0 @@ -export default { - form: 'Form', - basic: '基础表单', - useForm: 'useForm', - refForm: 'RefForm', - advancedForm: '可收缩表单', - ruleForm: '表单验证', - dynamicForm: '动态表单', - customerForm: '自定义组件', - appendForm: '表单增删示例', -}; diff --git a/src/locales/lang/zh_CN/routes/demo/iframe.ts b/src/locales/lang/zh_CN/routes/demo/iframe.ts deleted file mode 100644 index 1190f97b..00000000 --- a/src/locales/lang/zh_CN/routes/demo/iframe.ts +++ /dev/null @@ -1,6 +0,0 @@ -export default { - frame: '外部页面', - antv: 'antVue文档(内嵌)', - doc: '项目文档(内嵌)', - docExternal: '项目文档(外链)', -}; diff --git a/src/locales/lang/zh_CN/routes/demo/level.ts b/src/locales/lang/zh_CN/routes/demo/level.ts deleted file mode 100644 index 3b45ffa9..00000000 --- a/src/locales/lang/zh_CN/routes/demo/level.ts +++ /dev/null @@ -1,3 +0,0 @@ -export default { - level: '多级菜单', -}; diff --git a/src/locales/lang/zh_CN/routes/demo/page.ts b/src/locales/lang/zh_CN/routes/demo/page.ts deleted file mode 100644 index 062d98d9..00000000 --- a/src/locales/lang/zh_CN/routes/demo/page.ts +++ /dev/null @@ -1,29 +0,0 @@ -export default { - page: '页面', - - form: '表单页', - formBasic: '基础表单', - formStep: '分步表单', - formHigh: '高级表单', - - desc: '详情页', - descBasic: '基础详情页', - descHigh: '高级详情页', - - result: '结果页', - resultSuccess: '成功页', - resultFail: '失败页', - - account: '个人页', - accountCenter: '个人中心', - accountSetting: '个人设置', - - exception: '异常页', - netWorkError: '网络错误', - notData: '无数据', - - list: '列表页', - listCard: '卡片列表', - listBasic: '标准列表', - listSearch: '搜索列表', -}; diff --git a/src/locales/lang/zh_CN/routes/demo/permission.ts b/src/locales/lang/zh_CN/routes/demo/permission.ts deleted file mode 100644 index c03810ea..00000000 --- a/src/locales/lang/zh_CN/routes/demo/permission.ts +++ /dev/null @@ -1,13 +0,0 @@ -export default { - permission: '权限管理', - - front: '基于前端权限', - frontPage: '页面权限', - frontBtn: '按钮权限', - frontTestA: '权限测试页A', - frontTestB: '权限测试页B', - - back: '基于后台权限', - backPage: '页面权限', - backBtn: '按钮权限', -}; diff --git a/src/locales/lang/zh_CN/routes/demo/setup.ts b/src/locales/lang/zh_CN/routes/demo/setup.ts deleted file mode 100644 index 43abfe37..00000000 --- a/src/locales/lang/zh_CN/routes/demo/setup.ts +++ /dev/null @@ -1,3 +0,0 @@ -export default { - page: '引导页', -}; diff --git a/src/locales/lang/zh_CN/routes/demo/system.ts b/src/locales/lang/zh_CN/routes/demo/system.ts deleted file mode 100644 index 16deff58..00000000 --- a/src/locales/lang/zh_CN/routes/demo/system.ts +++ /dev/null @@ -1,12 +0,0 @@ -export default { - moduleName: '系统管理', - - account: '账号管理', - - password: '修改密码', - - dept: '部门管理', - - menu: '菜单管理', - role: '角色管理', -}; diff --git a/src/locales/lang/zh_CN/routes/demo/table.ts b/src/locales/lang/zh_CN/routes/demo/table.ts deleted file mode 100644 index 254b10ed..00000000 --- a/src/locales/lang/zh_CN/routes/demo/table.ts +++ /dev/null @@ -1,20 +0,0 @@ -export default { - table: 'Table', - - basic: '基础表格', - treeTable: '树形表格', - fetchTable: '远程加载示例', - fixedColumn: '固定列', - customerCell: '自定义列', - formTable: '开启搜索区域', - useTable: 'UseTable', - refTable: 'RefTable', - multipleHeader: '多级表头', - mergeHeader: '合并单元格', - expandTable: '可展开表格', - fixedHeight: '定高/头部自定义', - footerTable: '表尾行合计', - editCellTable: '可编辑单元格', - editRowTable: '可编辑行', - authColumn: '权限列', -}; diff --git a/src/views/demo/setup/index.vue b/src/views/demo/setup/index.vue index fad17f35..4ca5fd43 100644 --- a/src/views/demo/setup/index.vue +++ b/src/views/demo/setup/index.vue @@ -1,5 +1,5 @@ diff --git a/yarn.lock b/yarn.lock index e9fc5ef0..a40be941 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1252,21 +1252,21 @@ "@intlify/runtime" "9.1.6" "@intlify/shared" "9.1.6" -"@logicflow/core@^0.4.14": - version "0.4.14" - resolved "https://registry.npmjs.org/@logicflow/core/-/core-0.4.14.tgz#870ea68a5f241171802ed31b93803bddc24838bd" - integrity sha512-gu/q9QzZAzT8meJXDlnAfIrJ4M0i3GIrR0W36t6CFFnrHsjB96ApqGgSblyKLJ1lyTqBx8QeeTJ5WUQdcqat2A== +"@logicflow/core@^0.4.15": + version "0.4.15" + resolved "https://registry.npmjs.org/@logicflow/core/-/core-0.4.15.tgz#0e13d51b64403416eed6a3229b2d232869ca8dd5" + integrity sha512-JtgRL/ZM+FjjibrOkswkuKzeX3XMnozmq/h0YC/HBRpv0ZHynrlCQGqI1SQsD3tDIkaN4wBnHM9DIqIIwf7ZBQ== dependencies: "@types/mousetrap" "^1.6.4" mousetrap "^1.6.5" preact "^10.4.8" -"@logicflow/extension@^0.4.14": - version "0.4.14" - resolved "https://registry.npmjs.org/@logicflow/extension/-/extension-0.4.14.tgz#6c54659304fa41a12d1bdfccd0691803a2bd9fe9" - integrity sha512-3GTQBvbR/DcOszxy0iqUb4SDAYU0VfAP33ewXMkBkLBLnngf88+4jHMPgDh50H//6oBxXPsNbiMxiGdzjJkTjw== +"@logicflow/extension@^0.4.15": + version "0.4.15" + resolved "https://registry.npmjs.org/@logicflow/extension/-/extension-0.4.15.tgz#d68e8824aca89b8966d71ec1a68ce95bebe3169a" + integrity sha512-J6BRp5ZpOY/kyQmT8eCiLM+y+OWKClNDpWmiVSYdp0Rr8fGH1U4A8ITYvcte45nXorHLcg659PdHZaYqZtzJog== dependencies: - "@logicflow/core" "^0.4.14" + "@logicflow/core" "^0.4.15" ids "^1.0.0" preact "^10.4.8" From 154ebc3d96f73bb3ceab99ea0229a3619d585aba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=97=A0=E6=9C=A8?= Date: Thu, 17 Jun 2021 22:38:22 +0800 Subject: [PATCH 46/56] fix(use-message): `content` not support vNode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复封装的`useMessage`部分函数中`content`不支持vNode类型以及`createConfirm`不支持html的问题 --- src/hooks/web/useMessage.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/hooks/web/useMessage.tsx b/src/hooks/web/useMessage.tsx index ecb8fbbd..97f5b2d0 100644 --- a/src/hooks/web/useMessage.tsx +++ b/src/hooks/web/useMessage.tsx @@ -5,6 +5,7 @@ import { InfoCircleFilled, CheckCircleFilled, CloseCircleFilled } from '@ant-des import { ArgsProps, ConfigProps } from 'ant-design-vue/lib/notification'; import { useI18n } from './useI18n'; +import { isString } from '/@/utils/is'; export interface NotifyApi { info(config: ArgsProps): void; @@ -46,7 +47,11 @@ function getIcon(iconType: string) { } function renderContent({ content }: Pick) { - return
${content as string}
`}>
; + if (isString(content)) { + return
${content as string}
`}>
; + } else { + return content; + } } /** @@ -59,6 +64,7 @@ function createConfirm(options: ModalOptionsEx): ConfirmOptions { centered: true, icon: getIcon(iconType), ...options, + content: renderContent(options), }; return Modal.confirm(opt) as unknown as ConfirmOptions; } From f6fe1dd62df231ccbd063db0d32359b48aa5c76b Mon Sep 17 00:00:00 2001 From: Vben Date: Thu, 17 Jun 2021 22:56:21 +0800 Subject: [PATCH 47/56] feat(test): add jest test suite --- .eslintrc.js | 1 + .gitignore | 1 + CHANGELOG.zh_CN.md | 1 + jest.config.mjs | 37 + package.json | 13 +- .../workbench/components/DynamicInfo.vue | 1 + src/views/demo/feat/tabs/index.vue | 4 +- stylelint.config.js | 149 -- tests/__mocks__/fileMock.ts | 1 + tests/__mocks__/styleMock.ts | 1 + tests/__mocks__/workerMock.ts | 5 + {test => tests}/server/README.md | 0 .../server/controller/FileController.ts | 0 .../server/controller/UserController.ts | 0 {test => tests}/server/ecosystem.config.js | 0 {test => tests}/server/index.ts | 0 {test => tests}/server/nodemon.json | 0 {test => tests}/server/package.json | 0 {test => tests}/server/routes.ts | 0 {test => tests}/server/service/FileService.ts | 0 {test => tests}/server/service/UserService.ts | 0 tests/server/static/upload/11.jpg | Bin 0 -> 220309 bytes .../static/upload/5ab46a3cN616bdc41.jpg | Bin 0 -> 117118 bytes .../static/upload/5ac1bf5fN2522b9dc.jpg | Bin 0 -> 414588 bytes tests/server/static/upload/5c9ccca8a27f0.png | Bin 0 -> 2746 bytes tests/server/static/upload/5c9ccca8b27f1.jpg | Bin 0 -> 38736 bytes tests/server/static/upload/5c9ccca8bc1e0.png | Bin 0 -> 2168 bytes {test => tests}/server/tsconfig.json | 0 {test => tests}/server/utils.ts | 0 {test => tests}/server/yarn.lock | 0 tests/test.spec.ts | 16 + tsconfig.json | 3 +- yarn.lock | 1874 ++++++++++++++++- 33 files changed, 1898 insertions(+), 209 deletions(-) create mode 100644 jest.config.mjs create mode 100644 tests/__mocks__/fileMock.ts create mode 100644 tests/__mocks__/styleMock.ts create mode 100644 tests/__mocks__/workerMock.ts rename {test => tests}/server/README.md (100%) rename {test => tests}/server/controller/FileController.ts (100%) rename {test => tests}/server/controller/UserController.ts (100%) rename {test => tests}/server/ecosystem.config.js (100%) rename {test => tests}/server/index.ts (100%) rename {test => tests}/server/nodemon.json (100%) rename {test => tests}/server/package.json (100%) rename {test => tests}/server/routes.ts (100%) rename {test => tests}/server/service/FileService.ts (100%) rename {test => tests}/server/service/UserService.ts (100%) create mode 100644 tests/server/static/upload/11.jpg create mode 100644 tests/server/static/upload/5ab46a3cN616bdc41.jpg create mode 100644 tests/server/static/upload/5ac1bf5fN2522b9dc.jpg create mode 100644 tests/server/static/upload/5c9ccca8a27f0.png create mode 100644 tests/server/static/upload/5c9ccca8b27f1.jpg create mode 100644 tests/server/static/upload/5c9ccca8bc1e0.png rename {test => tests}/server/tsconfig.json (100%) rename {test => tests}/server/utils.ts (100%) rename {test => tests}/server/yarn.lock (100%) create mode 100644 tests/test.spec.ts diff --git a/.eslintrc.js b/.eslintrc.js index 09aff820..d4c9c6cb 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -22,6 +22,7 @@ module.exports = defineConfig({ 'plugin:@typescript-eslint/recommended', 'prettier', 'plugin:prettier/recommended', + 'plugin:jest/recommended', ], rules: { '@typescript-eslint/ban-ts-ignore': 'off', diff --git a/.gitignore b/.gitignore index 600565c9..2f4e6611 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ test/server/static # local env files .env.local .env.*.local +.eslintcache # Log files npm-debug.log* diff --git a/CHANGELOG.zh_CN.md b/CHANGELOG.zh_CN.md index b471c136..61fa4179 100644 --- a/CHANGELOG.zh_CN.md +++ b/CHANGELOG.zh_CN.md @@ -15,6 +15,7 @@ - **Drawer** `useDrawer`新增`closeDrawer`函数 - **Preview** 新增`createImgPreview`图片预览函数 - **Setup** 新增引导页示例 +- **Tests** 添加 jest 测试套件,暂不支持 Vue 组件单测 ### 🐛 Bug Fixes diff --git a/jest.config.mjs b/jest.config.mjs new file mode 100644 index 00000000..53091ac3 --- /dev/null +++ b/jest.config.mjs @@ -0,0 +1,37 @@ +export default { + preset: 'ts-jest', + roots: ['/tests/'], + clearMocks: true, + moduleDirectories: ['node_modules', 'src'], + moduleFileExtensions: ['js', 'ts', 'vue', 'tsx', 'jsx', 'json', 'node'], + modulePaths: ['/src', '/node_modules'], + testMatch: [ + '**/tests/**/*.[jt]s?(x)', + '**/?(*.)+(spec|test).[tj]s?(x)', + '(/__tests__/.*|(\\.|/)(test|spec))\\.(js|ts)$', + ], + testPathIgnorePatterns: [ + '/tests/server/', + '/tests/__mocks__/', + '/node_modules/', + ], + transform: { + '^.+\\.tsx?$': 'ts-jest', + '^.+\\.(vue)$': 'vue-jest', + }, + transformIgnorePatterns: ['/tests/__mocks__/', '/node_modules/'], + // A map from regular expressions to module names that allow to stub out resources with a single module + moduleNameMapper: { + '\\.(vs|fs|vert|frag|glsl|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': + '/tests/__mocks__/fileMock.ts', + '\\.(sass|s?css|less)$': '/tests/__mocks__/styleMock.ts', + '\\?worker$': '/tests/__mocks__/workerMock.ts', + '^/@/(.*)$': '/src/$1', + }, + testEnvironment: 'jsdom', + verbose: true, + collectCoverage: false, + coverageDirectory: 'coverage', + collectCoverageFrom: ['src/**/*.{js,ts,vue}'], + coveragePathIgnorePatterns: ['^.+\\.d\\.ts$'], +}; diff --git a/package.json b/package.json index 9e90a162..e0cacaf2 100644 --- a/package.json +++ b/package.json @@ -19,11 +19,13 @@ "log": "conventional-changelog -p angular -i CHANGELOG.md -s", "clean:cache": "rimraf node_modules/.cache/ && rimraf node_modules/.vite", "clean:lib": "rimraf node_modules", - "lint:eslint": "eslint \"{src,mock}/**/*.{vue,ts,tsx}\" --fix", + "lint:eslint": "eslint --cache --max-warnings 0 \"{src,mock}/**/*.{vue,ts,tsx}\" --fix", "lint:prettier": "prettier --write --loglevel warn \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"", - "lint:stylelint": "stylelint --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/", + "lint:stylelint": "stylelint --cache --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/", "lint:lint-staged": "lint-staged -c ./.husky/lintstagedrc.js", "lint:pretty": "pretty-quick --staged", + "test:unit": "jest", + "test:unit-coverage": "jest --coverage", "test:gzip": "http-server dist --cors --gzip -c-1", "test:br": "http-server dist --cors --brotli -c-1", "reinstall": "rimraf yarn.lock && rimraf package.lock.json && rimraf node_modules && npm run bootstrap", @@ -71,6 +73,7 @@ "@types/fs-extra": "^9.0.11", "@types/inquirer": "^7.3.1", "@types/intro.js": "^3.0.1", + "@types/jest": "^26.0.23", "@types/lodash-es": "^4.17.4", "@types/mockjs": "^1.0.3", "@types/node": "^15.12.2", @@ -84,7 +87,9 @@ "@vitejs/plugin-vue": "^1.2.3", "@vitejs/plugin-vue-jsx": "^1.1.5", "@vue/compiler-sfc": "3.0.11", + "@vue/test-utils": "^2.0.0-rc.6", "autoprefixer": "^10.2.6", + "babel-jest": "^27.0.2", "commitizen": "^4.2.4", "conventional-changelog-cli": "^2.1.1", "cross-env": "^7.0.3", @@ -92,6 +97,7 @@ "eslint": "^7.28.0", "eslint-config-prettier": "^8.3.0", "eslint-define-config": "^1.0.8", + "eslint-plugin-jest": "^24.3.6", "eslint-plugin-prettier": "^3.4.0", "eslint-plugin-vue": "^7.11.1", "esno": "^0.7.3", @@ -100,6 +106,7 @@ "husky": "^6.0.0", "inquirer": "^8.1.1", "is-ci": "^3.0.0", + "jest": "^27.0.4", "less": "^4.1.1", "lint-staged": "^11.0.0", "postcss": "^8.3.5", @@ -111,6 +118,7 @@ "stylelint-config-prettier": "^8.0.2", "stylelint-config-standard": "^22.0.0", "stylelint-order": "^4.1.0", + "ts-jest": "^27.0.3", "ts-node": "^10.0.0", "typescript": "4.3.3", "vite": "2.3.7", @@ -125,6 +133,7 @@ "vite-plugin-theme": "^0.8.1", "vite-plugin-windicss": "^1.0.4", "vue-eslint-parser": "^7.6.0", + "vue-jest": "^5.0.0-alpha.10", "vue-tsc": "^0.1.7" }, "resolutions": { diff --git a/src/views/dashboard/workbench/components/DynamicInfo.vue b/src/views/dashboard/workbench/components/DynamicInfo.vue index 659600e0..20b2acb7 100644 --- a/src/views/dashboard/workbench/components/DynamicInfo.vue +++ b/src/views/dashboard/workbench/components/DynamicInfo.vue @@ -10,6 +10,7 @@ +