From 87be4af655d4a8a0be01591527323110a05bec4b Mon Sep 17 00:00:00 2001 From: zhengkunwang <31820853+zhengkunwang223@users.noreply.github.com> Date: Tue, 2 Jul 2024 14:38:04 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=88=A0=E9=99=A4=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=97=A0=E7=94=A8=E4=BB=A3=E7=A0=81=20(#5637)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/package.json | 14 ++--- frontend/src/App.vue | 2 +- .../src/components/license-import/index.vue | 2 +- frontend/src/config/service-loading.ts | 35 ----------- frontend/src/directives/index.ts | 13 ---- frontend/src/directives/modules/debounce.ts | 31 ---------- frontend/src/directives/modules/draggable.ts | 49 --------------- .../src/directives/modules/drawer-drag.ts | 60 ------------------- frontend/src/directives/modules/longpress.ts | 49 --------------- frontend/src/directives/modules/throttle.ts | 41 ------------- .../src/directives/modules/water-marker.ts | 36 ----------- frontend/src/enums/http-enum.ts | 24 -------- frontend/src/{hooks => global}/use-theme.ts | 0 frontend/src/hooks/interface/index.ts | 3 - frontend/src/hooks/use-delete-data.ts | 53 ---------------- frontend/src/hooks/use-logo.ts | 20 ------- frontend/src/shims-vue.d.ts | 2 - frontend/src/utils/xpack.ts | 2 +- frontend/src/views/setting/panel/index.vue | 2 +- frontend/vite.config.ts | 16 ++++- 20 files changed, 25 insertions(+), 429 deletions(-) delete mode 100644 frontend/src/config/service-loading.ts delete mode 100644 frontend/src/directives/modules/debounce.ts delete mode 100644 frontend/src/directives/modules/draggable.ts delete mode 100644 frontend/src/directives/modules/drawer-drag.ts delete mode 100644 frontend/src/directives/modules/longpress.ts delete mode 100644 frontend/src/directives/modules/throttle.ts delete mode 100644 frontend/src/directives/modules/water-marker.ts rename frontend/src/{hooks => global}/use-theme.ts (100%) delete mode 100644 frontend/src/hooks/interface/index.ts delete mode 100644 frontend/src/hooks/use-delete-data.ts delete mode 100644 frontend/src/hooks/use-logo.ts delete mode 100644 frontend/src/shims-vue.d.ts diff --git a/frontend/package.json b/frontend/package.json index 4a8e29af6..ba98f1c9a 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,5 +1,5 @@ { - "name": "1Panel-Frontend", + "name": "1panel-frontend", "private": true, "version": "1.10", "description": "1Panel 前端", @@ -56,16 +56,16 @@ "vue-router": "^4.3.3" }, "devDependencies": { - "@types/node": "^20.14.2", - "@typescript-eslint/eslint-plugin": "^5.22.0", + "@types/node": "^20.14.8", + "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.22.0", "@vitejs/plugin-vue": "^5.0.5", "@vitejs/plugin-vue-jsx": "^4.0.0", "autoprefixer": "^10.4.7", "commitizen": "^4.2.4", - "eslint": "^8.43.0", - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-prettier": "^4.0.0", + "eslint": "^8.57.0", + "eslint-config-prettier": "^8.10.0", + "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-vue": "^8.7.1", "lint-staged": "^12.4.2", "postcss": "^8.4.31", @@ -79,7 +79,7 @@ "typescript": "^4.5.4", "unplugin-auto-import": "^0.16.4", "unplugin-vue-components": "^0.25.0", - "vite": "^5.2.13", + "vite": "^5.3.1", "vite-plugin-compression": "^0.5.1", "vite-plugin-eslint": "^1.8.1", "vite-plugin-html": "^3.2.2", diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 8cd639de1..85784cd93 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -9,7 +9,7 @@ import { reactive, computed, ref, nextTick, provide } from 'vue'; import { GlobalStore } from '@/store'; import zhCn from 'element-plus/es/locale/lang/zh-cn'; import en from 'element-plus/es/locale/lang/en'; -import { useTheme } from '@/hooks/use-theme'; +import { useTheme } from '@/global/use-theme'; useTheme(); const globalStore = GlobalStore(); diff --git a/frontend/src/components/license-import/index.vue b/frontend/src/components/license-import/index.vue index bd6212e40..11d572632 100644 --- a/frontend/src/components/license-import/index.vue +++ b/frontend/src/components/license-import/index.vue @@ -47,7 +47,7 @@ import { MsgSuccess } from '@/utils/message'; import { UploadFileData } from '@/api/modules/setting'; import { GlobalStore } from '@/store'; import { UploadFile, UploadFiles, UploadInstance, UploadProps, UploadRawFile, genFileId } from 'element-plus'; -import { useTheme } from '@/hooks/use-theme'; +import { useTheme } from '@/global/use-theme'; import { getXpackSetting } from '@/utils/xpack'; const globalStore = GlobalStore(); diff --git a/frontend/src/config/service-loading.ts b/frontend/src/config/service-loading.ts deleted file mode 100644 index d339b4903..000000000 --- a/frontend/src/config/service-loading.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { ElLoading } from 'element-plus'; - -/* 全局请求 loading(服务方式调用) */ -let loadingInstance: ReturnType; - -const startLoading = () => { - loadingInstance = ElLoading.service({ - fullscreen: true, - lock: true, - text: 'Loading', - background: 'rgba(0, 0, 0, 0.7)', - }); -}; -const endLoading = () => { - loadingInstance.close(); -}; - -// 那么 showFullScreenLoading() tryHideFullScreenLoading() 要做的事就是将同一时刻的请求合并。 -// 声明一个变量 needLoadingRequestCount,每次调用showFullScreenLoading方法 needLoadingRequestCount + 1。 -// 调用tryHideFullScreenLoading()方法,needLoadingRequestCount - 1。needLoadingRequestCount为 0 时,结束 loading。 -let needLoadingRequestCount = 0; -export const showFullScreenLoading = () => { - if (needLoadingRequestCount === 0) { - startLoading(); - } - needLoadingRequestCount++; -}; - -export const tryHideFullScreenLoading = () => { - if (needLoadingRequestCount <= 0) return; - needLoadingRequestCount--; - if (needLoadingRequestCount === 0) { - endLoading(); - } -}; diff --git a/frontend/src/directives/index.ts b/frontend/src/directives/index.ts index 24bd09bd7..513094935 100644 --- a/frontend/src/directives/index.ts +++ b/frontend/src/directives/index.ts @@ -1,21 +1,8 @@ import { App } from 'vue'; import copy from './modules/copy'; -import waterMarker from './modules/water-marker'; -import draggable from './modules/draggable'; -import debounce from './modules/debounce'; -import throttle from './modules/throttle'; -import longpress from './modules/longpress'; -import drawerDrag from './modules/drawer-drag'; const directivesList: any = { - // Custom directives copy, - waterMarker, - draggable, - debounce, - throttle, - longpress, - drawerDrag, }; const directives = { diff --git a/frontend/src/directives/modules/debounce.ts b/frontend/src/directives/modules/debounce.ts deleted file mode 100644 index a9f81ac4c..000000000 --- a/frontend/src/directives/modules/debounce.ts +++ /dev/null @@ -1,31 +0,0 @@ -/** - * v-debounce - * 按钮防抖指令,可自行扩展至input - * 接收参数:function类型 - */ -import type { Directive, DirectiveBinding } from 'vue'; -interface ElType extends HTMLElement { - __handleClick__: () => any; -} -const debounce: Directive = { - mounted(el: ElType, binding: DirectiveBinding) { - if (typeof binding.value !== 'function') { - throw 'callback must be a function'; - } - let timer: NodeJS.Timeout | null = null; - el.__handleClick__ = function () { - if (timer) { - clearInterval(timer); - } - timer = setTimeout(() => { - binding.value(); - }, 500); - }; - el.addEventListener('click', el.__handleClick__); - }, - beforeUnmount(el: ElType) { - el.removeEventListener('click', el.__handleClick__); - }, -}; - -export default debounce; diff --git a/frontend/src/directives/modules/draggable.ts b/frontend/src/directives/modules/draggable.ts deleted file mode 100644 index 2514e9859..000000000 --- a/frontend/src/directives/modules/draggable.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - 需求:实现一个拖拽指令,可在父元素区域任意拖拽元素。 - - 思路: - 1、设置需要拖拽的元素为absolute,其父元素为relative。 - 2、鼠标按下(onmousedown)时记录目标元素当前的 left 和 top 值。 - 3、鼠标移动(onmousemove)时计算每次移动的横向距离和纵向距离的变化值,并改变元素的 left 和 top 值 - 4、鼠标松开(onmouseup)时完成一次拖拽 - - 使用:在 Dom 上加上 v-draggable 即可 -
-*/ -import type { Directive } from 'vue'; -interface ElType extends HTMLElement { - parentNode: any; -} -const draggable: Directive = { - mounted: function (el: ElType) { - el.style.cursor = 'move'; - el.style.position = 'absolute'; - el.onmousedown = function (e) { - let disX = e.pageX - el.offsetLeft; - let disY = e.pageY - el.offsetTop; - document.onmousemove = function (e) { - let x = e.pageX - disX; - let y = e.pageY - disY; - let maxX = el.parentNode.offsetWidth - el.offsetWidth; - let maxY = el.parentNode.offsetHeight - el.offsetHeight; - if (x < 0) { - x = 0; - } else if (x > maxX) { - x = maxX; - } - - if (y < 0) { - y = 0; - } else if (y > maxY) { - y = maxY; - } - el.style.left = x + 'px'; - el.style.top = y + 'px'; - }; - document.onmouseup = function () { - document.onmousemove = document.onmouseup = null; - }; - }; - }, -}; -export default draggable; diff --git a/frontend/src/directives/modules/drawer-drag.ts b/frontend/src/directives/modules/drawer-drag.ts deleted file mode 100644 index b93110855..000000000 --- a/frontend/src/directives/modules/drawer-drag.ts +++ /dev/null @@ -1,60 +0,0 @@ -/* - 需求:实现一个drawer可拖拽指令。 - 使用:在 Dom 上加上 v-draggable 即可 - -*/ -import type { Directive } from 'vue'; -interface ElType extends HTMLElement { - parentNode: any; -} -const drawerDrag: Directive = { - mounted: function (el: ElType) { - const minWidth = 400; - const maxWidth = document.body.clientWidth; - const dragDom = el.querySelector('.el-drawer'); - (dragDom as HTMLElement).style.overflow = 'auto'; - - const resizeElL = document.createElement('div'); - dragDom.appendChild(resizeElL); - resizeElL.style.cursor = 'w-resize'; - resizeElL.style.position = 'absolute'; - resizeElL.style.height = '100%'; - resizeElL.style.width = '10px'; - resizeElL.style.left = '0px'; - resizeElL.style.top = '0px'; - - resizeElL.onmousedown = (e) => { - const elW = dragDom.clientWidth; - const EloffsetLeft = (dragDom as HTMLElement).offsetLeft; - const clientX = e.clientX; - document.onmousemove = function (e) { - e.preventDefault(); - // 左侧鼠标拖拽位置 - if (clientX > EloffsetLeft && clientX < EloffsetLeft + 10) { - // 往左拖拽 - if (clientX > e.clientX) { - if (dragDom.clientWidth < maxWidth) { - (dragDom as HTMLElement).style.width = elW + (clientX - e.clientX) + 'px'; - } else { - (dragDom as HTMLElement).style.width = maxWidth + 'px'; - } - } - // 往右拖拽 - if (clientX < e.clientX) { - if (dragDom.clientWidth > minWidth) { - (dragDom as HTMLElement).style.width = elW - (e.clientX - clientX) + 'px'; - } else { - (dragDom as HTMLElement).style.width = minWidth + 'px'; - } - } - } - }; - // 拉伸结束 - document.onmouseup = function () { - document.onmousemove = null; - document.onmouseup = null; - }; - }; - }, -}; -export default drawerDrag; diff --git a/frontend/src/directives/modules/longpress.ts b/frontend/src/directives/modules/longpress.ts deleted file mode 100644 index 5edf1a1d4..000000000 --- a/frontend/src/directives/modules/longpress.ts +++ /dev/null @@ -1,49 +0,0 @@ -/** - * v-longpress - * 长按指令,长按时触发事件 - */ -import type { Directive, DirectiveBinding } from 'vue'; - -const directive: Directive = { - mounted(el: HTMLElement, binding: DirectiveBinding) { - if (typeof binding.value !== 'function') { - throw 'callback must be a function'; - } - // 定义变量 - let pressTimer: any = null; - // 创建计时器( 2秒后执行函数 ) - const start = (e: any) => { - if (e.button) { - if (e.type === 'click' && e.button !== 0) { - return; - } - } - if (pressTimer === null) { - pressTimer = setTimeout(() => { - handler(e); - }, 1000); - } - }; - // 取消计时器 - const cancel = () => { - if (pressTimer !== null) { - clearTimeout(pressTimer); - pressTimer = null; - } - }; - // 运行函数 - const handler = (e: MouseEvent | TouchEvent) => { - binding.value(e); - }; - // 添加事件监听器 - el.addEventListener('mousedown', start); - el.addEventListener('touchstart', start); - // 取消计时器 - el.addEventListener('click', cancel); - el.addEventListener('mouseout', cancel); - el.addEventListener('touchend', cancel); - el.addEventListener('touchcancel', cancel); - }, -}; - -export default directive; diff --git a/frontend/src/directives/modules/throttle.ts b/frontend/src/directives/modules/throttle.ts deleted file mode 100644 index 07fdc9446..000000000 --- a/frontend/src/directives/modules/throttle.ts +++ /dev/null @@ -1,41 +0,0 @@ -/* - 需求:防止按钮在短时间内被多次点击,使用节流函数限制规定时间内只能点击一次。 - - 思路: - 1、第一次点击,立即调用方法并禁用按钮,等延迟结束再次激活按钮 - 2、将需要触发的方法绑定在指令上 - - 使用:给 Dom 加上 v-throttle 及回调函数即可 - -*/ -import type { Directive, DirectiveBinding } from 'vue'; -interface ElType extends HTMLElement { - __handleClick__: () => any; - disabled: boolean; -} -const throttle: Directive = { - mounted(el: ElType, binding: DirectiveBinding) { - if (typeof binding.value !== 'function') { - throw 'callback must be a function'; - } - let timer: NodeJS.Timeout | null = null; - el.__handleClick__ = function () { - if (timer) { - clearTimeout(timer); - } - if (!el.disabled) { - el.disabled = true; - binding.value(); - timer = setTimeout(() => { - el.disabled = false; - }, 1000); - } - }; - el.addEventListener('click', el.__handleClick__); - }, - beforeUnmount(el: ElType) { - el.removeEventListener('click', el.__handleClick__); - }, -}; - -export default throttle; diff --git a/frontend/src/directives/modules/water-marker.ts b/frontend/src/directives/modules/water-marker.ts deleted file mode 100644 index 598d52bde..000000000 --- a/frontend/src/directives/modules/water-marker.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - 需求:给整个页面添加背景水印。 - - 思路: - 1、使用 canvas 特性生成 base64 格式的图片文件,设置其字体大小,颜色等。 - 2、将其设置为背景图片,从而实现页面或组件水印效果 - - 使用:设置水印文案,颜色,字体大小即可 -
-*/ - -import type { Directive, DirectiveBinding } from 'vue'; -const addWaterMarker: Directive = (str: string, parentNode: any, font: any, textColor: string) => { - // 水印文字,父元素,字体,文字颜色 - let can: HTMLCanvasElement = document.createElement('canvas'); - parentNode.appendChild(can); - can.width = 200; - can.height = 150; - can.style.display = 'none'; - let cans = can.getContext('2d') as CanvasRenderingContext2D; - cans.rotate((-20 * Math.PI) / 180); - cans.font = font || '16px Microsoft JhengHei'; - cans.fillStyle = textColor || 'rgba(180, 180, 180, 0.3)'; - cans.textAlign = 'left'; - cans.textBaseline = 'Middle' as CanvasTextBaseline; - cans.fillText(str, can.width / 10, can.height / 2); - parentNode.style.backgroundImage = 'url(' + can.toDataURL('image/png') + ')'; -}; - -const waterMarker = { - mounted(el: DirectiveBinding, binding: DirectiveBinding) { - addWaterMarker(binding.value.text, el, binding.value.font, binding.value.textColor); - }, -}; - -export default waterMarker; diff --git a/frontend/src/enums/http-enum.ts b/frontend/src/enums/http-enum.ts index 289877779..2ef10bab1 100644 --- a/frontend/src/enums/http-enum.ts +++ b/frontend/src/enums/http-enum.ts @@ -24,27 +24,3 @@ export enum TimeoutEnum { T_1H = 3600000, T_1D = 86400000, } -/** - * @description:请求方法 - */ -export enum RequestEnum { - GET = 'GET', - POST = 'POST', - PATCH = 'PATCH', - PUT = 'PUT', - DELETE = 'DELETE', -} - -/** - * @description:常用的contentTyp类型 - */ -export enum ContentTypeEnum { - // json - JSON = 'application/json;charset=UTF-8', - // text - TEXT = 'text/plain;charset=UTF-8', - // form-data 一般配合qs - FORM_URLENCODED = 'application/x-www-form-urlencoded;charset=UTF-8', - // form-data 上传 - FORM_DATA = 'multipart/form-data;charset=UTF-8', -} diff --git a/frontend/src/hooks/use-theme.ts b/frontend/src/global/use-theme.ts similarity index 100% rename from frontend/src/hooks/use-theme.ts rename to frontend/src/global/use-theme.ts diff --git a/frontend/src/hooks/interface/index.ts b/frontend/src/hooks/interface/index.ts deleted file mode 100644 index 96c7910fa..000000000 --- a/frontend/src/hooks/interface/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export namespace HandleData { - export type MessageType = '' | 'success' | 'warning' | 'info' | 'error'; -} diff --git a/frontend/src/hooks/use-delete-data.ts b/frontend/src/hooks/use-delete-data.ts deleted file mode 100644 index 69f80c892..000000000 --- a/frontend/src/hooks/use-delete-data.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { ElMessageBox } from 'element-plus'; -import { HandleData } from './interface'; -import i18n from '@/lang'; -import { MsgSuccess } from '@/utils/message'; - -/** - * @description 删除操作使用 - * @param {Function} api 操作数据接口的api方法(必传) - * @param {Object} params 携带的操作数据参数 {id,params}(必传) - * @param {String} message 提示信息(必传) - * @param {String} confirmType icon类型(不必传,默认为 warning) - * @return Promise - */ -export const useDeleteData =

( - api: (params: P) => Promise, - params: Parameters[0], - message: string, - confirmType: HandleData.MessageType = 'error', -) => { - return new Promise((resolve, reject) => { - ElMessageBox.confirm(i18n.global.t(`${message}`), i18n.global.t('commons.msg.deleteTitle'), { - confirmButtonText: i18n.global.t('commons.button.confirm'), - cancelButtonText: i18n.global.t('commons.button.cancel'), - closeOnClickModal: false, - closeOnPressEscape: false, - showClose: false, - type: confirmType, - draggable: true, - beforeClose: async (action, instance, done) => { - if (action === 'confirm') { - instance.confirmButtonLoading = true; - instance.cancelButtonLoading = true; - - await api(params) - .then((res) => { - done(); - if (!res) return reject(false); - resolve(true); - MsgSuccess(i18n.global.t('commons.msg.operationSuccess')); - }) - .finally(() => { - instance.confirmButtonLoading = false; - instance.cancelButtonLoading = false; - }); - } else { - done(); - } - }, - }) - .then(() => {}) - .catch(() => {}); - }); -}; diff --git a/frontend/src/hooks/use-logo.ts b/frontend/src/hooks/use-logo.ts deleted file mode 100644 index 575280375..000000000 --- a/frontend/src/hooks/use-logo.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { GlobalStore } from '@/store'; -import { getXpackSetting } from '@/utils/xpack'; - -export const useLogo = async () => { - const globalStore = GlobalStore(); - const res = await getXpackSetting(); - if (res) { - localStorage.setItem('1p-favicon', res.data.logo); - globalStore.themeConfig.title = res.data.title; - globalStore.themeConfig.logo = res.data.logo; - globalStore.themeConfig.logoWithText = res.data.logoWithText; - globalStore.themeConfig.favicon = res.data.favicon; - } - - const link = (document.querySelector("link[rel*='icon']") || document.createElement('link')) as HTMLLinkElement; - link.type = 'image/x-icon'; - link.rel = 'shortcut icon'; - link.href = globalStore.themeConfig.favicon ? '/api/v1/images/favicon' : '/public/favicon.png'; - document.getElementsByTagName('head')[0].appendChild(link); -}; diff --git a/frontend/src/shims-vue.d.ts b/frontend/src/shims-vue.d.ts deleted file mode 100644 index c876f9a46..000000000 --- a/frontend/src/shims-vue.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -declare module '@kangc/v-md-editor/lib/preview'; -declare module '@kangc/v-md-editor/lib/theme/github.js'; diff --git a/frontend/src/utils/xpack.ts b/frontend/src/utils/xpack.ts index 4205a8c64..9ad6d7ceb 100644 --- a/frontend/src/utils/xpack.ts +++ b/frontend/src/utils/xpack.ts @@ -1,5 +1,5 @@ import { getLicenseStatus, getSettingInfo } from '@/api/modules/setting'; -import { useTheme } from '@/hooks/use-theme'; +import { useTheme } from '@/global/use-theme'; import { GlobalStore } from '@/store'; const globalStore = GlobalStore(); const { switchTheme } = useTheme(); diff --git a/frontend/src/views/setting/panel/index.vue b/frontend/src/views/setting/panel/index.vue index 8553f286f..316d10d0d 100644 --- a/frontend/src/views/setting/panel/index.vue +++ b/frontend/src/views/setting/panel/index.vue @@ -173,7 +173,7 @@ import { ElForm } from 'element-plus'; import { getSettingInfo, updateSetting, getSystemAvailable } from '@/api/modules/setting'; import { GlobalStore } from '@/store'; import { useI18n } from 'vue-i18n'; -import { useTheme } from '@/hooks/use-theme'; +import { useTheme } from '@/global/use-theme'; import { MsgSuccess } from '@/utils/message'; import Password from '@/views/setting/panel/password/index.vue'; import UserName from '@/views/setting/panel/username/index.vue'; diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 10a1dbd0a..bc6b92224 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -1,5 +1,3 @@ -import { defineConfig, loadEnv, ConfigEnv, UserConfig } from 'vite'; -import vue from '@vitejs/plugin-vue'; import { resolve } from 'path'; import { wrapperEnv } from './src/utils/get-env'; import { visualizer } from 'rollup-plugin-visualizer'; @@ -8,6 +6,10 @@ import VueSetupExtend from 'vite-plugin-vue-setup-extend'; import eslintPlugin from 'vite-plugin-eslint'; import vueJsx from '@vitejs/plugin-vue-jsx'; import DefineOptions from 'unplugin-vue-define-options/vite'; +import { defineConfig, loadEnv, ConfigEnv, UserConfig } from 'vite'; +import vue from '@vitejs/plugin-vue'; +import pkg from './package.json'; +import dayjs from 'dayjs'; import AutoImport from 'unplugin-auto-import/vite'; import Components from 'unplugin-vue-components/vite'; @@ -16,6 +18,12 @@ import svgLoader from 'vite-svg-loader'; const prefix = `monaco-editor/esm/vs`; +const { dependencies, devDependencies, name, version } = pkg; +const __APP_INFO__ = { + pkg: { dependencies, devDependencies, name, version }, + lastBuildTime: dayjs().format('YYYY-MM-DD HH:mm:ss'), +}; + export default defineConfig(({ mode }: ConfigEnv): UserConfig => { const env = loadEnv(mode, process.cwd()); const viteEnv = wrapperEnv(env); @@ -28,6 +36,9 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => { xpack: resolve(__dirname, './src/xpack'), }, }, + define: { + __APP_INFO__: JSON.stringify(__APP_INFO__), + }, css: { preprocessorOptions: { scss: { @@ -65,6 +76,7 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => { ext: '.gz', }), AutoImport({ + imports: ['vue', 'vue-router'], resolvers: [ ElementPlusResolver({ importStyle: 'sass',