diff --git a/build/getShortName.ts b/build/getConfigFileName.ts similarity index 74% rename from build/getShortName.ts rename to build/getConfigFileName.ts index b46205f0..d61cd416 100644 --- a/build/getShortName.ts +++ b/build/getConfigFileName.ts @@ -2,7 +2,7 @@ * Get the configuration file variable name * @param env */ -export const getShortName = (env: any) => { +export const getConfigFileName = (env: Record) => { return `__PRODUCTION__${env.VITE_GLOB_APP_SHORT_NAME || '__APP'}__CONF__` .toUpperCase() .replace(/\s/g, ''); diff --git a/build/script/buildConf.ts b/build/script/buildConf.ts index 3c044df8..a44a1d8e 100644 --- a/build/script/buildConf.ts +++ b/build/script/buildConf.ts @@ -5,8 +5,8 @@ import { GLOB_CONFIG_FILE_NAME, OUTPUT_DIR } from '../constant'; import fs, { writeFileSync } from 'fs-extra'; import chalk from 'chalk'; -import { getCwdPath, getEnvConfig } from '../utils'; -import { getShortName } from '../getShortName'; +import { getRootPath, getEnvConfig } from '../utils'; +import { getConfigFileName } from '../getConfigFileName'; import pkg from '../../package.json'; @@ -27,8 +27,8 @@ function createConfig( writable: false, }); `.replace(/\s/g, ''); - fs.mkdirp(getCwdPath(OUTPUT_DIR)); - writeFileSync(getCwdPath(`${OUTPUT_DIR}/${configFileName}`), configStr); + fs.mkdirp(getRootPath(OUTPUT_DIR)); + writeFileSync(getRootPath(`${OUTPUT_DIR}/${configFileName}`), configStr); console.log(chalk.cyan(`✨ [${pkg.name}]`) + ` - configuration file is build successfully:`); console.log(chalk.gray(OUTPUT_DIR + '/' + chalk.green(configFileName)) + '\n'); @@ -39,6 +39,6 @@ function createConfig( export function runBuildConfig() { const config = getEnvConfig(); - const configFileName = getShortName(config); + const configFileName = getConfigFileName(config); createConfig({ config, configName: configFileName }); } diff --git a/build/script/postBuild.ts b/build/script/postBuild.ts index 0f809a86..094bb067 100644 --- a/build/script/postBuild.ts +++ b/build/script/postBuild.ts @@ -14,6 +14,7 @@ export const runBuild = async () => { if (!argvList.includes('no-conf')) { await runBuildConfig(); } + console.log(`✨ ${chalk.cyan(`[${pkg.name}]`)}` + ' - build successfully!'); } catch (error) { console.log(chalk.red('vite build error:\n' + error)); diff --git a/build/tsconfig.json b/build/tsconfig.json index 5f9bb94a..1ffedd0e 100644 --- a/build/tsconfig.json +++ b/build/tsconfig.json @@ -5,7 +5,6 @@ "moduleResolution": "node", "strict": true, "forceConsistentCasingInFileNames": true, - "jsx": "react", "baseUrl": ".", "esModuleInterop": true, "noUnusedLocals": true, diff --git a/build/typeing.d.ts b/build/typeing.d.ts index 0421b721..3f221c7c 100644 --- a/build/typeing.d.ts +++ b/build/typeing.d.ts @@ -2,3 +2,5 @@ declare module '*.json' { const src: any; export default src; } + +declare type Recordable = Record; diff --git a/build/utils.ts b/build/utils.ts index 0236ea6b..d5e95e3c 100644 --- a/build/utils.ts +++ b/build/utils.ts @@ -2,12 +2,6 @@ import fs from 'fs'; import path from 'path'; import dotenv from 'dotenv'; -export const isFunction = (arg: unknown): arg is (...args: any[]) => any => - typeof arg === 'function'; - -export const isRegExp = (arg: unknown): arg is RegExp => - Object.prototype.toString.call(arg) === '[object RegExp]'; - export function isDevFn(mode: string): boolean { return mode === 'development'; } @@ -34,18 +28,18 @@ export interface ViteEnv { VITE_USE_CDN: boolean; VITE_DROP_CONSOLE: boolean; VITE_BUILD_COMPRESS: 'gzip' | 'brotli' | 'none'; - VITE_DYNAMIC_IMPORT: boolean; VITE_LEGACY: boolean; VITE_USE_IMAGEMIN: boolean; } // Read all environment variable configuration files to process.env -export function wrapperEnv(envConf: any): ViteEnv { +export function wrapperEnv(envConf: Recordable): ViteEnv { const ret: any = {}; for (const envName of Object.keys(envConf)) { let realName = envConf[envName].replace(/\\n/g, '\n'); realName = realName === 'true' ? true : realName === 'false' ? false : realName; + if (envName === 'VITE_PORT') { realName = Number(realName); } @@ -70,10 +64,10 @@ export function getEnvConfig(match = 'VITE_GLOB_', confFiles = ['.env', '.env.pr confFiles.forEach((item) => { try { const env = dotenv.parse(fs.readFileSync(path.resolve(process.cwd(), item))); - envConfig = { ...envConfig, ...env }; } catch (error) {} }); + Object.keys(envConfig).forEach((key) => { const reg = new RegExp(`^(${match})`); if (!reg.test(key)) { @@ -87,6 +81,6 @@ export function getEnvConfig(match = 'VITE_GLOB_', confFiles = ['.env', '.env.pr * Get user root directory * @param dir file path */ -export function getCwdPath(...dir: string[]) { +export function getRootPath(...dir: string[]) { return path.resolve(process.cwd(), ...dir); } diff --git a/build/vite/plugin/index.ts b/build/vite/plugin/index.ts index f1e5a146..6260453f 100644 --- a/build/vite/plugin/index.ts +++ b/build/vite/plugin/index.ts @@ -1,4 +1,5 @@ import type { Plugin } from 'vite'; +import type { ViteEnv } from '../../utils'; import vue from '@vitejs/plugin-vue'; import vueJsx from '@vitejs/plugin-vue-jsx'; @@ -6,7 +7,6 @@ import legacy from '@vitejs/plugin-legacy'; import PurgeIcons from 'vite-plugin-purge-icons'; -import { ViteEnv } from '../../utils'; import { configHtmlPlugin } from './html'; import { configPwaConfig } from './pwa'; import { configMockPlugin } from './mock'; diff --git a/build/vite/plugin/pwa.ts b/build/vite/plugin/pwa.ts index f2730178..3d62faa2 100644 --- a/build/vite/plugin/pwa.ts +++ b/build/vite/plugin/pwa.ts @@ -2,11 +2,10 @@ * Zero-config PWA for Vite * https://github.com/antfu/vite-plugin-pwa */ +import type { ViteEnv } from '../../utils'; import { VitePWA } from 'vite-plugin-pwa'; -import { ViteEnv } from '../../utils'; - export function configPwaConfig(env: ViteEnv) { const { VITE_USE_PWA, VITE_GLOB_APP_TITLE, VITE_GLOB_APP_SHORT_NAME } = env; diff --git a/build/vite/plugin/windicss.ts b/build/vite/plugin/windicss.ts index 0ba949e5..c972c9cc 100644 --- a/build/vite/plugin/windicss.ts +++ b/build/vite/plugin/windicss.ts @@ -1,7 +1,7 @@ -import windiCSS from 'vite-plugin-windicss'; - import type { Plugin } from 'vite'; +import windiCSS from 'vite-plugin-windicss'; + export function configWindiCssPlugin(): Plugin[] { return windiCSS({ safelist: 'no-select', diff --git a/mock/_createProductionServer.ts b/mock/_createProductionServer.ts index a44310b9..6ac92ffa 100644 --- a/mock/_createProductionServer.ts +++ b/mock/_createProductionServer.ts @@ -1,5 +1,6 @@ import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer'; +// @ts-ignore const modules = import.meta.globEager('./**/*.ts'); const mockModules: any[] = []; diff --git a/mock/_util.ts b/mock/_util.ts index 912c5448..c59be9d8 100644 --- a/mock/_util.ts +++ b/mock/_util.ts @@ -18,13 +18,11 @@ export function resultPageSuccess( const pageData = pagination(page, pageSize, list); return { - code: 0, - result: { + ...resultSuccess({ items: pageData, total: list.length, - }, + }), message, - type: 'success', }; } diff --git a/package.json b/package.json index 5960a6d6..d62eb2a8 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "vben-admin", "version": "2.0.1", "scripts": { + "bootstrap": "yarn install", "serve": "vite", "dev": "vite", "build": "vite build && esno ./build/script/postBuild.ts", @@ -9,9 +10,9 @@ "report": "cross-env REPORT=true npm run build ", "preview": "npm run build && vite preview", "preview:dist": "vite preview", - "log": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0", + "log": "conventional-changelog -p angular -i CHANGELOG.md -s", "clean:cache": "rimraf node_modules/.cache/ && rimraf node_modules/.vite", - "clean:lib": "npx rimraf node_modules", + "clean:lib": "rimraf node_modules", "lint:eslint": "eslint \"{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/", @@ -39,8 +40,8 @@ "qrcode": "^1.4.4", "sortablejs": "^1.13.0", "vditor": "^3.8.1", - "vue": "^3.0.6", - "vue-i18n": "9.0.0-rc.7", + "vue": "3.0.5", + "vue-i18n": "9.0.0-rc.8", "vue-router": "^4.0.4", "vue-types": "^3.0.2", "vuex": "^4.0.0", @@ -50,7 +51,7 @@ "devDependencies": { "@commitlint/cli": "^12.0.0", "@commitlint/config-conventional": "^12.0.0", - "@iconify/json": "^1.1.307", + "@iconify/json": "^1.1.308", "@ls-lint/ls-lint": "^1.9.2", "@purge-icons/generated": "^0.7.0", "@types/fs-extra": "^9.0.7", @@ -68,7 +69,7 @@ "@vitejs/plugin-legacy": "^1.3.1", "@vitejs/plugin-vue": "^1.1.4", "@vitejs/plugin-vue-jsx": "^1.1.2", - "@vue/compiler-sfc": "^3.0.6", + "@vue/compiler-sfc": "3.0.5", "autoprefixer": "^10.2.4", "commitizen": "^4.2.3", "conventional-changelog-cli": "^2.1.1", diff --git a/src/components/Tinymce/src/Editor.vue b/src/components/Tinymce/src/Editor.vue index e44d7200..ee46ed50 100644 --- a/src/components/Tinymce/src/Editor.vue +++ b/src/components/Tinymce/src/Editor.vue @@ -26,7 +26,7 @@ import plugins from './plugins'; import { getTinymce } from './getTinymce'; import { useScript } from '/@/hooks/web/useScript'; - import { snowUuid } from '/@/utils/uuid'; + import { shortUuid } from '/@/utils/uuid'; import { bindHandlers } from './helper'; import lineHeight from './lineHeight'; import { onMountedOrActivated } from '/@/hooks/core/onMountedOrActivated'; @@ -45,7 +45,7 @@ emits: ['change', 'update:modelValue'], setup(props, { emit, attrs }) { const editorRef = ref(null); - const tinymceId = ref(snowUuid('tiny-vue')); + const tinymceId = ref(shortUuid('tiny-vue')); const elRef = ref>(null); const { prefixCls } = useDesign('tinymce-container'); @@ -104,7 +104,7 @@ } ); onMountedOrActivated(() => { - tinymceId.value = snowUuid('tiny-vue'); + tinymceId.value = shortUuid('tiny-vue'); nextTick(() => { init(); }); diff --git a/src/hooks/setting/index.ts b/src/hooks/setting/index.ts index 464838da..cb2b0c29 100644 --- a/src/hooks/setting/index.ts +++ b/src/hooks/setting/index.ts @@ -1,33 +1,33 @@ import type { ProjectConfig, GlobConfig, GlobEnvConfig } from '/@/types/config'; +import { getConfigFileName } from '../../../build/getConfigFileName'; + import getProjectSetting from '/@/settings/projectSetting'; -import { getShortName } from '../../../build/getShortName'; import { warn } from '/@/utils/log'; import { getGlobEnvConfig, isDevMode } from '/@/utils/env'; -const reg = /[a-zA-Z\_]*/; - -const ENV_NAME = getShortName(import.meta.env); -const ENV = ((isDevMode() - ? getGlobEnvConfig() - : window[ENV_NAME as any]) as unknown) as GlobEnvConfig; - -const { - VITE_GLOB_APP_TITLE, - VITE_GLOB_API_URL, - VITE_GLOB_APP_SHORT_NAME, - VITE_GLOB_API_URL_PREFIX, - VITE_GLOB_UPLOAD_URL, -} = ENV; - -if (!reg.test(VITE_GLOB_APP_SHORT_NAME)) { - warn( - `VITE_GLOB_APP_SHORT_NAME Variables can only be characters/underscores, please modify in the environment variables and re-running.` - ); -} - export const useGlobSetting = (): Readonly => { + const ENV_NAME = getConfigFileName(import.meta.env); + + const ENV = ((isDevMode() + ? getGlobEnvConfig() + : window[ENV_NAME as any]) as unknown) as GlobEnvConfig; + + const { + VITE_GLOB_APP_TITLE, + VITE_GLOB_API_URL, + VITE_GLOB_APP_SHORT_NAME, + VITE_GLOB_API_URL_PREFIX, + VITE_GLOB_UPLOAD_URL, + } = ENV; + + if (!/[a-zA-Z\_]*/.test(VITE_GLOB_APP_SHORT_NAME)) { + warn( + `VITE_GLOB_APP_SHORT_NAME Variables can only be characters/underscores, please modify in the environment variables and re-running.` + ); + } + // Take global configuration const glob: Readonly = { title: VITE_GLOB_APP_TITLE, diff --git a/src/hooks/web/useApexCharts.ts b/src/hooks/web/useApexCharts.ts index 34fb20e7..cbee7b7c 100644 --- a/src/hooks/web/useApexCharts.ts +++ b/src/hooks/web/useApexCharts.ts @@ -2,8 +2,6 @@ import { useTimeoutFn } from '/@/hooks/core/useTimeout'; import { tryOnUnmounted } from '/@/utils/helper/vueHelper'; import { unref, Ref, nextTick } from 'vue'; -import ApexCharts from 'apexcharts'; - interface CallBackFn { (instance: Nullable): void; } @@ -13,21 +11,22 @@ export function useApexCharts(elRef: Ref) { function setOptions(options: any, callback?: CallBackFn) { nextTick(() => { - useTimeoutFn(() => { + useTimeoutFn(async () => { const el = unref(elRef); if (!el || !unref(el)) return; + const ApexCharts = await (await import('apexcharts')).default; chartInstance = new ApexCharts(el, options); chartInstance && chartInstance.render(); - // setOptions增加callback方法,返回chartInstance,以便于对图表进行再操作,例如调用updateOptions方法更新图表 + // The callback method is added to setOptions to return the chartInstance to facilitate the re-operation of the chart, such as calling the updateOptions method to update the chart callback && callback(chartInstance); }, 30); }); } - // 新增调用ApexCharts的updateOptions方法更新图表 + // Call the updateOptions method of ApexCharts to update the chart function updateOptions( chartInstance: Nullable, options: any, diff --git a/src/hooks/web/useLockPage.ts b/src/hooks/web/useLockPage.ts index 335e0a28..9c2e211e 100644 --- a/src/hooks/web/useLockPage.ts +++ b/src/hooks/web/useLockPage.ts @@ -65,9 +65,3 @@ export function useLockPage() { } }); } - -export const getIsLock = computed(() => { - const { getLockInfo } = lockStore; - const { isLock } = getLockInfo; - return isLock; -}); diff --git a/src/hooks/web/usePermission.ts b/src/hooks/web/usePermission.ts index c35409be..35b1d716 100644 --- a/src/hooks/web/usePermission.ts +++ b/src/hooks/web/usePermission.ts @@ -40,7 +40,7 @@ export function usePermission() { resetRouter(); const routes = await permissionStore.buildRoutesAction(id); routes.forEach((route) => { - router.addRoute(route as RouteRecordRaw); + router.addRoute((route as unknown) as RouteRecordRaw); }); permissionStore.commitLastBuildMenuTimeState(); const { closeAll } = useTabs(); diff --git a/src/hooks/web/useSortable.ts b/src/hooks/web/useSortable.ts index 9cb1f7a0..4c66b6af 100644 --- a/src/hooks/web/useSortable.ts +++ b/src/hooks/web/useSortable.ts @@ -1,11 +1,13 @@ -import Sortable from 'sortablejs'; import { nextTick, unref } from 'vue'; import type { Ref } from 'vue'; +import type { Options } from 'sortablejs'; -export function useSortable(el: HTMLElement | Ref, options?: Sortable.Options) { +export function useSortable(el: HTMLElement | Ref, options?: Options) { function initSortable() { - nextTick(() => { + nextTick(async () => { if (!el) return; + + const Sortable = (await import('sortablejs')).default; Sortable.create(unref(el), { animation: 500, delay: 400, diff --git a/src/layouts/default/tabs/useMultipleTabs.ts b/src/layouts/default/tabs/useMultipleTabs.ts index a15b217e..2305268f 100644 --- a/src/layouts/default/tabs/useMultipleTabs.ts +++ b/src/layouts/default/tabs/useMultipleTabs.ts @@ -43,7 +43,7 @@ export function initAffixTabs(): string[] { addAffixTabs(); isAddAffix = true; } - return affixList.value.map((item) => item.meta?.title).filter(Boolean); + return affixList.value.map((item) => item.meta?.title).filter(Boolean) as string[]; } export function useTabsDrag(affixTextList: string[]) { diff --git a/src/logics/initAppConfig.ts b/src/logics/initAppConfig.ts index 1b51e927..c49b1a12 100644 --- a/src/logics/initAppConfig.ts +++ b/src/logics/initAppConfig.ts @@ -7,7 +7,7 @@ import type { ProjectConfig } from '/@/types/config'; import { PROJ_CFG_KEY } from '/@/enums/cacheEnum'; import projectSetting from '/@/settings/projectSetting'; -import { getLocal } from '/@/utils/helper/persistent'; +import { getLocal } from '/@/utils/cache/persistent'; import { updateHeaderBgColor, updateSidebarBgColor } from '/@/logics/theme/updateBackground'; import { updateColorWeak } from '/@/logics/theme/updateColorWeak'; import { updateGrayMode } from '/@/logics/theme/updateGrayMode'; diff --git a/src/router/helper/menuHelper.ts b/src/router/helper/menuHelper.ts index 81520188..da48abcd 100644 --- a/src/router/helper/menuHelper.ts +++ b/src/router/helper/menuHelper.ts @@ -46,12 +46,6 @@ export function transformRouteToMenu(routeModList: AppRouteModule[]) { const cloneRouteModList = cloneDeep(routeModList); const routeList: AppRouteRecordRaw[] = []; - // cloneRouteModList = filter(cloneRouteModList, (node) => { - // if (Reflect.has(node?.meta ?? {}, 'hideMenu')) { - // return !node?.meta.hideMenu; - // } - // return true; - // }); cloneRouteModList.forEach((item) => { if (item.meta?.single) { const realItem = item?.children?.[0]; diff --git a/src/router/index.ts b/src/router/index.ts index db95b62e..2c5f1507 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -3,9 +3,8 @@ import type { App } from 'vue'; import { createRouter, createWebHashHistory } from 'vue-router'; -import { createGuard } from './guard/'; - -import { basicRoutes } from './routes/'; +import { createGuard } from './guard'; +import { basicRoutes } from './routes'; import { REDIRECT_NAME } from './constant'; // app router @@ -33,8 +32,4 @@ export function setupRouter(app: App) { createGuard(router); } -// router.onError((error) => { -// console.error(error); -// }); - export default router; diff --git a/src/store/modules/app.ts b/src/store/modules/app.ts index a184dc6a..a311695a 100644 --- a/src/store/modules/app.ts +++ b/src/store/modules/app.ts @@ -6,7 +6,7 @@ import store from '/@/store'; import { PROJ_CFG_KEY } from '/@/enums/cacheEnum'; import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper'; -import { setLocal, getLocal, clearSession, clearLocal } from '/@/utils/helper/persistent'; +import { setLocal, getLocal, clearSession, clearLocal } from '/@/utils/cache/persistent'; import { deepMerge } from '/@/utils'; import { resetRouter } from '/@/router'; diff --git a/src/store/modules/lock.ts b/src/store/modules/lock.ts index c88d1bbe..74c37ec3 100644 --- a/src/store/modules/lock.ts +++ b/src/store/modules/lock.ts @@ -4,7 +4,7 @@ import store from '/@/store'; import { LOCK_INFO_KEY } from '/@/enums/cacheEnum'; import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper'; -import { setLocal, getLocal, removeLocal } from '/@/utils/helper/persistent'; +import { setLocal, getLocal, removeLocal } from '/@/utils/cache/persistent'; import { userStore } from './user'; diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts index 5b5e13f6..579f8392 100644 --- a/src/store/modules/user.ts +++ b/src/store/modules/user.ts @@ -18,7 +18,7 @@ import router from '/@/router'; import { loginApi, getUserInfoById } from '/@/api/sys/user'; -import { setLocal, getLocal, getSession, setSession } from '/@/utils/helper/persistent'; +import { setLocal, getLocal, getSession, setSession } from '/@/utils/cache/persistent'; import { useProjectSetting } from '/@/hooks/setting'; import { useI18n } from '/@/hooks/web/useI18n'; import { ErrorMessageMode } from '/@/utils/http/axios/types'; @@ -37,7 +37,6 @@ function getCache(key: string) { function setCache(USER_INFO_KEY: string, info: any) { if (!info) return; - // const fn = permissionCacheType === CacheTypeEnum.LOCAL ? setLocal : setSession; setLocal(USER_INFO_KEY, info, true); // TODO setSession(USER_INFO_KEY, info, true); diff --git a/src/types/config.d.ts b/src/types/config.d.ts index ea9fc2ed..e0f43946 100644 --- a/src/types/config.d.ts +++ b/src/types/config.d.ts @@ -6,9 +6,10 @@ import { RouterTransitionEnum, SettingButtonPositionEnum, } from '/@/enums/appEnum'; + import { CacheTypeEnum } from '/@/enums/cacheEnum'; import type { LocaleType } from '/@/locales/types'; -import { ThemeMode } from '../../build/config/lessModifyVars'; +import { ThemeMode } from '../../build/config/themeConfig'; export interface MenuSetting { bgColor: string; @@ -32,16 +33,10 @@ export interface MenuSetting { } export interface MultiTabsSetting { - // 是否显示 show: boolean; - // 开启快速操作 showQuick: boolean; canDrag: boolean; - - // 显示刷新按钮 showRedo: boolean; - - // 显示折叠按钮 showFold: boolean; } @@ -50,16 +45,14 @@ export interface HeaderSetting { fixed: boolean; show: boolean; theme: ThemeEnum; - - // 显示全屏按钮 + // Turn on full screen showFullScreen: boolean; - // 开启全屏功能 + // Whether to show the lock screen useLockPage: boolean; - // 显示文档按钮 + // Show document button showDoc: boolean; - // 显示消息中心按钮 + // Show message center button showNotice: boolean; - showSearch: boolean; } @@ -76,96 +69,90 @@ export interface LocaleSetting { export interface TransitionSetting { // Whether to open the page switching animation enable: boolean; - // Route basic switching animation basicTransition: RouterTransitionEnum; - // Whether to open page switching loading openPageLoading: boolean; - // Whether to open the top progress bar openNProgress: boolean; } export interface ProjectConfig { + // Multilingual configuration locale: LocaleSetting; - + // Storage location of permission related information permissionCacheType: CacheTypeEnum; - - // 是否显示配置按钮 + // Whether to show the configuration button showSettingButton: boolean; + // Configure where the button is displayed settingButtonPosition: SettingButtonPositionEnum; - // 权限模式 + // Permission mode permissionMode: PermissionModeEnum; - // 网站灰色模式,用于可能悼念的日期开启 + // Website gray mode, open for possible mourning dates grayMode: boolean; - // 是否开启色弱模式 + // Whether to turn on the color weak mode colorWeak: boolean; - // 主题色 + // Theme color themeColor: string; + themeMode: ThemeMode; - // 全屏显示主界面,不显示菜单,及顶部 + // The main interface is displayed in full screen, the menu is not displayed, and the top fullContent: boolean; - // 区域宽度 + // content width contentMode: ContentEnum; - // 是否显示logo + // Whether to display the logo showLogo: boolean; + // Whether to show the global footer showFooter: boolean; - headerSetting: HeaderSetting; - // 菜单类型 // menuType: MenuTypeEnum; + headerSetting: HeaderSetting; + // menuSetting menuSetting: MenuSetting; - - // 多标签页设置 + // Multi-tab settings multiTabsSetting: MultiTabsSetting; - + // Animation configuration transitionSetting: TransitionSetting; - - // pageLayout是否开启keep-alive + // pageLayout whether to enable keep-alive openKeepAlive: boolean; - - // - // 锁屏时间 + // Lock screen time lockTime: number; - // 显示面包屑 + // Show breadcrumbs showBreadCrumb: boolean; - // 显示面包屑图标 + // Show breadcrumb icon showBreadCrumbIcon: boolean; - // 使用error-handler-plugin + // Use error-handler-plugin useErrorHandle: boolean; - // 是否开启回到顶部 + // Whether to open back to top useOpenBackTop: boolean; - // 是否可以嵌入iframe页面 + // Is it possible to embed iframe pages canEmbedIFramePage: boolean; - // 切换界面的时候是否删除未关闭的message及notify + // Whether to delete unclosed messages and notify when switching the interface closeMessageOnSwitch: boolean; - // 切换界面的时候是否取消已经发送但是未响应的http请求。 + // Whether to cancel the http request that has been sent but not responded when switching the interface. removeAllHttpPending: boolean; } export interface GlobConfig { - // 网站标题 + // Site title title: string; - // 项目路径 + // Service interface url apiUrl: string; + // Upload url uploadUrl?: string; + // Service interface url prefix urlPrefix?: string; + // Project abbreviation shortName: string; } export interface GlobEnvConfig { - // 网站标题 + // Site title VITE_GLOB_APP_TITLE: string; - // 项目路径 + // Service interface url VITE_GLOB_API_URL: string; + // Service interface url prefix VITE_GLOB_API_URL_PREFIX?: string; + // Project abbreviation VITE_GLOB_APP_SHORT_NAME: string; + // Upload url VITE_GLOB_UPLOAD_URL?: string; } - -interface GlobWrap { - globSetting: Readonly; -} - -interface ProjectSettingWrap { - projectSetting: Readonly; -} diff --git a/src/utils/helper/persistent.ts b/src/utils/cache/persistent.ts similarity index 100% rename from src/utils/helper/persistent.ts rename to src/utils/cache/persistent.ts diff --git a/src/utils/domUtils.ts b/src/utils/domUtils.ts index 2e98d758..80a77a57 100644 --- a/src/utils/domUtils.ts +++ b/src/utils/domUtils.ts @@ -16,9 +16,9 @@ export function getBoundingClientRect(element: Element): DOMRect | number { return element.getBoundingClientRect(); } -const trim = function (string: string) { +function trim(string: string) { return (string || '').replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g, ''); -}; +} /* istanbul ignore next */ export function hasClass(el: Element, cls: string) { diff --git a/src/utils/env.ts b/src/utils/env.ts index ffeff00a..b7a00068 100644 --- a/src/utils/env.ts +++ b/src/utils/env.ts @@ -1,5 +1,8 @@ import type { GlobEnvConfig } from '/@/types/config'; +import { useGlobSetting } from '/@/hooks/setting'; +import pkg from '../../package.json'; + /** * Get the global configuration (the configuration will be extracted independently when packaging) */ @@ -8,6 +11,12 @@ export function getGlobEnvConfig(): GlobEnvConfig { return (env as unknown) as GlobEnvConfig; } +// Generate cache key according to version +export function getStorageShortName() { + const globSetting = useGlobSetting(); + return `${globSetting.shortName}__${getEnv()}${`__${pkg.version}`}__`.toUpperCase(); +} + /** * @description: Development model */ diff --git a/src/utils/index.ts b/src/utils/index.ts index af210fa0..b9fb89df 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -4,6 +4,7 @@ import { isObject } from '/@/utils/is'; export const clamp = (n: number, min: number, max: number) => Math.min(max, Math.max(min, n)); export const noop = () => {}; export const now = () => Date.now(); + /** * @description: Set ui mount node */ diff --git a/src/utils/uuid.ts b/src/utils/uuid.ts index e08a4586..9678327d 100644 --- a/src/utils/uuid.ts +++ b/src/utils/uuid.ts @@ -20,7 +20,7 @@ export function buildUUID(): string { } let unique = 0; -export function snowUuid(prefix = ''): string { +export function shortUuid(prefix = ''): string { const time = Date.now(); const random = Math.floor(Math.random() * 1000000000); unique++; diff --git a/src/views/sys/lock/index.vue b/src/views/sys/lock/index.vue index 56ff7fd5..20519a10 100644 --- a/src/views/sys/lock/index.vue +++ b/src/views/sys/lock/index.vue @@ -4,13 +4,20 @@