From a092f4fc694a6ee735a9c9273482cd05dad0be22 Mon Sep 17 00:00:00 2001 From: JEECG <445654970@qq.com> Date: Tue, 28 Apr 2026 15:39:31 +0800 Subject: [PATCH] =?UTF-8?q?v3.9.2=20=E5=89=8D=E7=AB=AF=E6=8C=89=E9=9C=80?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E6=A0=B8=E5=BF=83=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jeecgboot-vue3/build/vite/plugin/index.ts | 54 ++- jeecgboot-vue3/package.json | 18 +- jeecgboot-vue3/pnpm-lock.yaml | 345 +++++++++++++++++- jeecgboot-vue3/src/components/Form/index.ts | 61 ++-- .../src/components/Form/src/componentMap.ts | 248 ++++--------- .../src/components/Icon/src/Icon.vue | 41 ++- .../src/components/jeecg/JVxeTable/index.ts | 19 +- .../jeecg/JVxeTable/useVxeTableRegister.ts | 12 + .../src/components/registerGlobComp.ts | 132 ++----- .../src/router/helper/routeHelper.ts | 12 +- jeecgboot-vue3/src/utils/dynamicPages.ts | 10 + jeecgboot-vue3/src/utils/index.ts | 174 ++++++++- .../src/utils/monorepo/registerPackages.ts | 18 +- jeecgboot-vue3/vite.config.ts | 48 ++- 14 files changed, 813 insertions(+), 379 deletions(-) create mode 100644 jeecgboot-vue3/src/components/jeecg/JVxeTable/useVxeTableRegister.ts create mode 100644 jeecgboot-vue3/src/utils/dynamicPages.ts diff --git a/jeecgboot-vue3/build/vite/plugin/index.ts b/jeecgboot-vue3/build/vite/plugin/index.ts index 183bfbced..29aea4a39 100644 --- a/jeecgboot-vue3/build/vite/plugin/index.ts +++ b/jeecgboot-vue3/build/vite/plugin/index.ts @@ -2,8 +2,11 @@ import { PluginOption } from 'vite'; import vue from '@vitejs/plugin-vue'; import vueJsx from '@vitejs/plugin-vue-jsx'; import purgeIcons from 'vite-plugin-purge-icons'; +// unplugin-icons 为 ESM-only,用动态 import 避免 CJS 配置加载时 require 报错 import UnoCSS from 'unocss/vite'; import { presetTypography, presetUno } from 'unocss'; +import Components from 'unplugin-vue-components/vite'; +import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers'; // 本地调试https配置方法 import VitePluginCertificate from 'vite-plugin-mkcert'; @@ -29,9 +32,23 @@ import { configPwaPlugin } from './pwa'; * @param isBuild * @param isQiankunMicro 是否【JEECG作为乾坤子应用】 */ -export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean, isQiankunMicro: boolean) { +export async function createVitePlugins( + viteEnv: ViteEnv, + isBuild: boolean, + isQiankunMicro: boolean, +) { const { VITE_USE_MOCK, VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE } = viteEnv; + // update-begin--author:liaozhiyang---date:20260306---for:【QQYUN-14833】unplugin-icons 使用esm + // 动态 import ESM-only,避免 CJS 配置链 require 报 ERR_REQUIRE_ESM (解决node 20启动报错) + const [ + { default: Icons }, + { default: IconsResolver }, + ] = await Promise.all([ + import('unplugin-icons/vite'), + import('unplugin-icons/resolver'), + ]); + // update-end--author:liaozhiyang---date:20260306---for:【QQYUN-14833】unplugin-icons 使用esm const vitePlugins: (PluginOption | PluginOption[])[] = [ // have to vue(), @@ -46,6 +63,26 @@ export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean, isQiankunM ]; vitePlugins.push(UnoCSS({ presets: [presetUno(), presetTypography()] })); + // update-begin--author:liaozhiyang---date:20260302---for:【QQYUN-14806】antd采用unplugin-vue-components实现按需加载 + // unplugin-vue-components: ant-design-vue 组件自动按需导入 + vitePlugins.push( + Components({ + resolvers: [ + AntDesignVueResolver({ + importStyle: false, + // 排除antd的Button组件,让项目中的a-button指向BasicButton组件 + // 低版本是AButton,高版本是Button + exclude: ['AButton', 'Button'], + }), + IconsResolver({ + prefix: 'iconify', + }), + ], + dirs: [], + dts: false, + }) + ); + // update-end--author:liaozhiyang---date:20260302---for:【QQYUN-14806】antd采用unplugin-vue-components实现按需加载 // vite-plugin-html vitePlugins.push(configHtmlPlugin(viteEnv, isBuild, isQiankunMicro)); @@ -56,8 +93,21 @@ export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean, isQiankunM // vite-plugin-mock VITE_USE_MOCK && vitePlugins.push(configMockPlugin(isBuild)); - // vite-plugin-purge-icons + // update-begin--author:liaozhiyang---date:20260304---for:【QQYUN-14802】新增unplugin-icons插件,及icon支持online和local两种模式 + if (viteEnv.VITE_GLOB_ICONIFY_USE_TYPE === 'local') { + vitePlugins.push(purgeIcons()); + } + vitePlugins.push( + Icons({ + compiler: 'vue3', + // 自动安装图标集 + autoInstall: false, + scale: 1, + defaultClass: 'app-iconify anticon', + }) + ); vitePlugins.push(purgeIcons()); + // update-end--author:liaozhiyang---date:20260304---for:【QQYUN-14802】新增unplugin-icons插件,及icon支持online和local两种模式 // rollup-plugin-visualizer vitePlugins.push(configVisualizerConfig()); diff --git a/jeecgboot-vue3/package.json b/jeecgboot-vue3/package.json index 6bf53916a..9a85c637a 100644 --- a/jeecgboot-vue3/package.json +++ b/jeecgboot-vue3/package.json @@ -23,11 +23,10 @@ "husky:install": "husky install" }, "dependencies": { - "@jeecg/online": "3.9.1-RC", - "@jeecg/aiflow":"3.9.1-beta", - "@logicflow/core": "^2.0.10", - "@logicflow/extension": "^2.0.14", - "@logicflow/vue-node-registry": "^1.0.12", + "@jeecg/aiflow":"3.9.2-beta", + "@logicflow/core": "^2.1.2", + "@logicflow/extension": "^2.1.4", + "@logicflow/vue-node-registry": "^1.1.3", "@iconify/iconify": "^3.1.1", "@ant-design/colors": "^7.2.1", "@ant-design/icons-vue": "^7.0.1", @@ -37,7 +36,6 @@ "@zxcvbn-ts/core": "^3.0.4", "ant-design-vue": "^4.2.6", "axios": "^1.12.2", - "china-area-data": "^5.0.1", "@vant/area-data": "^1.5.2", "clipboard": "^2.0.11", "codemirror": "^5.65.20", @@ -85,13 +83,18 @@ "vxe-pc-ui": "4.6.12", "vxe-table-plugin-antd": "4.0.8", "xe-utils": "3.5.26", - "xss": "^1.0.15" + "xss": "^1.0.15", + "vue-grid-layout-v3": "^3.1.2", + "lunar-javascript": "^1.7.5", + "perfect-scrollbar": "^1.5.6", + "vue-color": "^3.3.3" }, "devDependencies": { "@commitlint/cli": "^18.6.1", "@commitlint/config-conventional": "^18.6.3", "@iconify/json": "^2.2.394", "@purge-icons/generated": "^0.10.0", + "unplugin-icons": "^0.22.0", "@types/codemirror": "^5.60.16", "@types/crypto-js": "^4.2.2", "@types/fs-extra": "^11.0.4", @@ -154,6 +157,7 @@ "ts-jest": "^29.4.4", "ts-node": "^10.9.2", "typescript": "^5.9.3", + "unplugin-vue-components": "~0.24.1", "vite": "^6.3.6", "vite-plugin-compression": "^0.5.1", "vite-plugin-html": "^3.2.2", diff --git a/jeecgboot-vue3/pnpm-lock.yaml b/jeecgboot-vue3/pnpm-lock.yaml index 0a7ccb8c8..5f224bdb8 100644 --- a/jeecgboot-vue3/pnpm-lock.yaml +++ b/jeecgboot-vue3/pnpm-lock.yaml @@ -20,17 +20,14 @@ importers: '@jeecg/aiflow': specifier: 3.9.1-beta version: 3.9.1-beta - '@jeecg/online': - specifier: 3.9.1-beta - version: 3.9.1-beta '@logicflow/core': - specifier: ^2.0.10 + specifier: ^2.1.2 version: 2.1.9 '@logicflow/extension': - specifier: ^2.0.14 + specifier: ^2.1.4 version: 2.1.11(@logicflow/core@2.1.9)(@logicflow/vue-node-registry@1.1.10(@logicflow/core@2.1.9)(vue@3.5.27(typescript@5.9.3))) '@logicflow/vue-node-registry': - specifier: ^1.0.12 + specifier: ^1.1.3 version: 1.1.10(@logicflow/core@2.1.9)(vue@3.5.27(typescript@5.9.3)) '@tinymce/tinymce-vue': specifier: 4.0.7 @@ -56,9 +53,6 @@ importers: axios: specifier: ^1.12.2 version: 1.13.2(debug@4.4.3) - china-area-data: - specifier: ^5.0.1 - version: 5.0.1 clipboard: specifier: ^2.0.11 version: 2.0.11 @@ -104,6 +98,9 @@ importers: lodash.get: specifier: ^4.4.2 version: 4.4.2 + lunar-javascript: + specifier: ^1.7.5 + version: 1.7.7 markdown-it: specifier: ^14.1.0 version: 14.1.0 @@ -122,6 +119,9 @@ importers: path-to-regexp: specifier: ^6.3.0 version: 6.3.0 + perfect-scrollbar: + specifier: ^1.5.6 + version: 1.5.6 pinia: specifier: 2.1.7 version: 2.1.7(typescript@5.9.3)(vue@3.5.27(typescript@5.9.3)) @@ -158,12 +158,18 @@ importers: vue: specifier: ^3.5.22 version: 3.5.27(typescript@5.9.3) + vue-color: + specifier: ^3.3.3 + version: 3.3.3(vue@3.5.27(typescript@5.9.3)) vue-cropper: specifier: ^0.6.5 version: 0.6.5 vue-cropperjs: specifier: ^5.0.0 version: 5.0.0(vue@3.5.27(typescript@5.9.3)) + vue-grid-layout-v3: + specifier: ^3.1.2 + version: 3.1.2(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27)(typescript@5.9.3) vue-i18n: specifier: ^9.14.5 version: 9.14.5(vue@3.5.27(typescript@5.9.3)) @@ -408,6 +414,12 @@ importers: unocss: specifier: ^0.58.9 version: 0.58.9(postcss@8.5.6)(rollup@4.52.5)(vite@6.4.1(@types/node@20.19.30)(jiti@2.6.1)(less@4.5.1)(terser@5.46.0)(tsx@4.21.0)) + unplugin-icons: + specifier: ^0.22.0 + version: 0.22.0(@vue/compiler-sfc@3.5.27)(vue-template-compiler@2.7.16) + unplugin-vue-components: + specifier: ~0.24.1 + version: 0.24.1(@babel/parser@7.28.6)(rollup@4.52.5)(vue@3.5.27(typescript@5.9.3)) vite: specifier: ^6.3.6 version: 6.4.1(@types/node@20.19.30)(jiti@2.6.1)(less@4.5.1)(terser@5.46.0)(tsx@4.21.0) @@ -478,6 +490,9 @@ packages: peerDependencies: vue: '>=3.0.3' + '@antfu/install-pkg@0.5.0': + resolution: {integrity: sha512-dKnk2xlAyC7rvTkpkHmu+Qy/2Zc3Vm/l8PtNyIOGDBtXPY3kThfU4ORNEp3V7SXw5XSOb+tOJaUYpfquPzL/Tg==} + '@antfu/install-pkg@1.1.0': resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} @@ -1613,6 +1628,51 @@ packages: resolution: {integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==} engines: {node: '>=18'} + '@interactjs/actions@1.10.27': + resolution: {integrity: sha512-FCRg5KwB+stkPcAMx/Cn0fgGP6p4LyMX9S/Upcn/W+hpYme31bPi54PCqmOebzz6myTthN6zFf9jMyLOqtI/gg==} + peerDependencies: + '@interactjs/core': 1.10.27 + '@interactjs/utils': 1.10.27 + + '@interactjs/auto-scroll@1.10.27': + resolution: {integrity: sha512-zPg5TnVsZv+9Hnt4qnbxLvBMf+rIWHkoJVoSETEbLNaj90C8hIyr0pVwukSUySSgDhCgQ7np0f3pg4INLq9beQ==} + peerDependencies: + '@interactjs/utils': 1.10.27 + + '@interactjs/auto-start@1.10.27': + resolution: {integrity: sha512-ECLBO/nxmaF1knncJKIE5F7la3KKRgEkn0Cu2JTPOYj9xy/LpfYElo3wkRHsodgOqF651nR70GK2/IzPR2lO9A==} + peerDependencies: + '@interactjs/core': 1.10.27 + '@interactjs/utils': 1.10.27 + + '@interactjs/core@1.10.27': + resolution: {integrity: sha512-SliUr/3ZbLAdED8LokzYzWHWMdCB5Cq+UnpXuRy+BIod1j97m4IUFf/D1iIKUBBjBcucgXbz28z96WnenVCB7Q==} + peerDependencies: + '@interactjs/utils': 1.10.27 + + '@interactjs/dev-tools@1.10.27': + resolution: {integrity: sha512-YolmBwRaKH1gWbvyLeV3m5QSwtD38lOZnCBA87PCAlcd9PQAC2gb03fEPeEyD336bE20oLB8f0WZt4Wre+afiw==} + peerDependencies: + '@interactjs/modifiers': 1.10.27 + '@interactjs/utils': 1.10.27 + + '@interactjs/interact@1.10.27': + resolution: {integrity: sha512-XdH3A2UUzjEFGGJgFuJlhiz99tE8jB8xNh/DmnoMuL6uOQPxNA+sWRnzEVjG0+zY2P3/dbhEpi4Cn3FLPzydwA==} + + '@interactjs/modifiers@1.10.27': + resolution: {integrity: sha512-ei/qfoQ+9/8k6WzNzdNqHI6cWkIV576N4Ap16r5CoqOWwhA6Xzj3OMHf1g0t1O4eSq2HdJsVJn3eLNfw9HsbeQ==} + peerDependencies: + '@interactjs/core': 1.10.27 + '@interactjs/utils': 1.10.27 + + '@interactjs/snappers@1.10.27': + resolution: {integrity: sha512-HZLZ0XSi6HI08OmTv/HKG6AltQoaKAALLQ+KDW92utj3XSgw7oren0KsWUKPhaPg3Av7R1jFQd08s+uafqIlLw==} + peerDependencies: + '@interactjs/utils': 1.10.27 + + '@interactjs/utils@1.10.27': + resolution: {integrity: sha512-+qfLOio2OxQqg1cXSnRaCl+N8MQDQLDS9w+aOGxH8YLAhIMyt7Asxx/46//sT8orgsi16pmlBPtngPHT9s8zKw==} + '@intlify/core-base@9.14.5': resolution: {integrity: sha512-5ah5FqZG4pOoHjkvs8mjtv+gPKYU0zCISaYNjBNNqYiaITxW8ZtVih3GS/oTOqN8d9/mDLyrjD46GBApNxmlsA==} engines: {node: '>= 16'} @@ -1648,9 +1708,6 @@ packages: '@jeecg/aiflow@3.9.1-beta': resolution: {integrity: sha512-RwYobjK95Kb23rXIPOuL7+MgSTry8QxHs6l88vJRliZSY55aACHqy6YyyDybugSEsbGuckFAfaSOGlb6kN1/iQ==} - '@jeecg/online@3.9.1-beta': - resolution: {integrity: sha512-PecK5QCazXpmCjdG0Y2Oa2+10M3hxCvfxy7gP1WDNDqDguN2Zl30rEN1ziOaqiv7on5/wp1XyLYOFid9n3egLA==} - '@jest/console@29.7.0': resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1886,56 +1943,67 @@ packages: resolution: {integrity: sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.52.5': resolution: {integrity: sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.52.5': resolution: {integrity: sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.52.5': resolution: {integrity: sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.52.5': resolution: {integrity: sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==} cpu: [loong64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-ppc64-gnu@4.52.5': resolution: {integrity: sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-gnu@4.52.5': resolution: {integrity: sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.52.5': resolution: {integrity: sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==} cpu: [riscv64] os: [linux] + libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.52.5': resolution: {integrity: sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.52.5': resolution: {integrity: sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.52.5': resolution: {integrity: sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-openharmony-arm64@4.52.5': resolution: {integrity: sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==} @@ -2659,6 +2727,9 @@ packages: resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==} engines: {node: '>= 0.8'} + batch-processor@1.0.0: + resolution: {integrity: sha512-xoLQD8gmmR32MeuBHgH0Tzd5PuSZx71ZsbhVxOCRbgktZEPe4SQy7s9Z50uPp0F/f7iw2XmkHN2xkgbMfckMDA==} + big.js@5.2.2: resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} @@ -2799,9 +2870,6 @@ packages: resolution: {integrity: sha512-IkxPpb5rS/d1IiLbHMgfPuS0FgiWTtFIm/Nj+2woXDLTZ7fOT2eqzgYbdMlLweqlHbsZjxEChoVK+7iph7jyQg==} engines: {node: '>=20.18.1'} - china-area-data@5.0.1: - resolution: {integrity: sha512-BQDPpiv5Nn+018ekcJK2oSD9PAD+E1bvXB0wgabc//dFVS/KvRqCgg0QOEUt3vBkx9XzB5a9BmkJCEZDBxVjVw==} - chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -3452,6 +3520,9 @@ packages: electron-to-chromium@1.5.267: resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} + element-resize-detector@1.2.4: + resolution: {integrity: sha512-Fl5Ftk6WwXE0wqCgNoseKWndjzZlDCwuPTcoVZfCP9R3EHQF8qUtr3YUPNETegRBOKqQKPW3n4kiIWngGi8tKg==} + emittery@0.13.1: resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} engines: {node: '>=12'} @@ -4968,6 +5039,14 @@ packages: resolution: {integrity: sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==} engines: {node: '>=4.0.0'} + local-pkg@0.4.3: + resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} + engines: {node: '>=14'} + + local-pkg@0.5.1: + resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==} + engines: {node: '>=14'} + local-pkg@1.1.2: resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==} engines: {node: '>=14'} @@ -5072,6 +5151,9 @@ packages: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} + lunar-javascript@1.7.7: + resolution: {integrity: sha512-u/KYiwPIBo/0bT+WWfU7qO1d+aqeB90Tuy4ErXenr2Gam0QcWeezUvtiOIyXR7HbVnW2I1DKfU0NBvzMZhbVQw==} + luxon@3.7.2: resolution: {integrity: sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==} engines: {node: '>=12'} @@ -5119,6 +5201,9 @@ packages: resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} hasBin: true + material-colors@1.2.6: + resolution: {integrity: sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg==} + math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -5226,6 +5311,10 @@ packages: resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} engines: {node: '>=10'} + minimatch@7.4.9: + resolution: {integrity: sha512-Brg/fp/iAVDOQoHxkuN5bEYhyQlZhxddI78yWsCbeEwTHXQjlNLtiJDUsp1GIptVqMI7/gkJMz4vVAc01mpoBw==} + engines: {node: '>=10'} + minimatch@9.0.1: resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==} engines: {node: '>=16 || 14 >=14.17'} @@ -5252,6 +5341,9 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + mixin-deep@1.3.2: resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==} engines: {node: '>=0.10.0'} @@ -5501,6 +5593,9 @@ packages: package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + package-manager-detector@0.2.11: + resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} + package-manager-detector@1.6.0: resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} @@ -5612,6 +5707,9 @@ packages: perfect-debounce@1.0.0: resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + perfect-scrollbar@1.5.6: + resolution: {integrity: sha512-rixgxw3SxyJbCaSpo1n35A/fwI1r2rdwMKOTCg/AcG+xOEyZcE8UHVjpZMFCVImzsFoCZeJTT+M/rdEIQYO2nw==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -6811,6 +6909,50 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} + unplugin-icons@0.22.0: + resolution: {integrity: sha512-CP+iZq5U7doOifer5bcM0jQ9t3Is7EGybIYt3myVxceI8Zuk8EZEpe1NPtJvh7iqMs1VdbK0L41t9+um9VuuLw==} + peerDependencies: + '@svgr/core': '>=7.0.0' + '@svgx/core': ^1.0.1 + '@vue/compiler-sfc': ^3.0.2 || ^2.7.0 + svelte: ^3.0.0 || ^4.0.0 || ^5.0.0 + vue-template-compiler: ^2.6.12 + vue-template-es2015-compiler: ^1.9.0 + peerDependenciesMeta: + '@svgr/core': + optional: true + '@svgx/core': + optional: true + '@vue/compiler-sfc': + optional: true + svelte: + optional: true + vue-template-compiler: + optional: true + vue-template-es2015-compiler: + optional: true + + unplugin-vue-components@0.24.1: + resolution: {integrity: sha512-T3A8HkZoIE1Cja95xNqolwza0yD5IVlgZZ1PVAGvVCx8xthmjsv38xWRCtHtwl+rvZyL9uif42SRkDGw9aCfMA==} + engines: {node: '>=14'} + peerDependencies: + '@babel/parser': ^7.15.8 + '@nuxt/kit': ^3.2.2 + vue: 2 || 3 + peerDependenciesMeta: + '@babel/parser': + optional: true + '@nuxt/kit': + optional: true + + unplugin@1.16.1: + resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==} + engines: {node: '>=14.0.0'} + + unplugin@2.3.11: + resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} + engines: {node: '>=18.12.0'} + unset-value@1.0.0: resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==} engines: {node: '>=0.10.0'} @@ -6976,6 +7118,11 @@ packages: yaml: optional: true + vue-color@3.3.3: + resolution: {integrity: sha512-FW/9JXFbCHfFEGv6SFUuK/SE+K61pHoL7lxJMQXcU+Zt7s36Ui1/tMDc3vzGXPrxxRBB+NSzFt+71nEaUJ29dQ==} + peerDependencies: + vue: '>=2.7.0 <4.0.0' + vue-component-type-helpers@2.2.12: resolution: {integrity: sha512-YbGqHZ5/eW4SnkPNR44mKVc6ZKQoRs/Rux1sxC6rdwXb4qpbOSYfDr9DsTHolOTGmIKgM9j141mZbBeg05R1pw==} @@ -7004,6 +7151,9 @@ packages: peerDependencies: eslint: '>=6.0.0' + vue-grid-layout-v3@3.1.2: + resolution: {integrity: sha512-4VB6pel2OklFNnFSUVg4wXwx/fKuKKvnhleLyscwk5ay7aEFk+HghcVKbComg+EgMvjuPzZ7hgIES3FlxuVK6w==} + vue-i18n@9.14.5: resolution: {integrity: sha512-0jQ9Em3ymWngyiIkj0+c/k7WgaPO+TNzjKSNq9BvBQaKJECqn9cd9fL4tkDhB5G1QBskGl9YxxbDAhgbFtpe2g==} engines: {node: '>= 16'} @@ -7085,6 +7235,9 @@ packages: webidl-conversions@4.0.2: resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + whatwg-encoding@2.0.0: resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} engines: {node: '>=12'} @@ -7312,6 +7465,11 @@ snapshots: '@ant-design/icons-svg': 4.4.2 vue: 3.5.27(typescript@5.9.3) + '@antfu/install-pkg@0.5.0': + dependencies: + package-manager-detector: 0.2.11 + tinyexec: 0.3.2 + '@antfu/install-pkg@1.1.0': dependencies: package-manager-detector: 1.6.0 @@ -8519,6 +8677,61 @@ snapshots: '@inquirer/figures@1.0.15': {} + '@interactjs/actions@1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27)': + dependencies: + '@interactjs/core': 1.10.27(@interactjs/utils@1.10.27) + '@interactjs/utils': 1.10.27 + optionalDependencies: + '@interactjs/interact': 1.10.27 + + '@interactjs/auto-scroll@1.10.27(@interactjs/utils@1.10.27)': + dependencies: + '@interactjs/utils': 1.10.27 + optionalDependencies: + '@interactjs/interact': 1.10.27 + + '@interactjs/auto-start@1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27)': + dependencies: + '@interactjs/core': 1.10.27(@interactjs/utils@1.10.27) + '@interactjs/utils': 1.10.27 + optionalDependencies: + '@interactjs/interact': 1.10.27 + + '@interactjs/core@1.10.27(@interactjs/utils@1.10.27)': + dependencies: + '@interactjs/utils': 1.10.27 + + '@interactjs/dev-tools@1.10.27(@interactjs/modifiers@1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27)(typescript@5.9.3)': + dependencies: + '@interactjs/modifiers': 1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27) + '@interactjs/utils': 1.10.27 + optionalDependencies: + '@interactjs/interact': 1.10.27 + vue: 3.5.27(typescript@5.9.3) + transitivePeerDependencies: + - typescript + + '@interactjs/interact@1.10.27': + dependencies: + '@interactjs/core': 1.10.27(@interactjs/utils@1.10.27) + '@interactjs/utils': 1.10.27 + + '@interactjs/modifiers@1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27)': + dependencies: + '@interactjs/core': 1.10.27(@interactjs/utils@1.10.27) + '@interactjs/snappers': 1.10.27(@interactjs/utils@1.10.27) + '@interactjs/utils': 1.10.27 + optionalDependencies: + '@interactjs/interact': 1.10.27 + + '@interactjs/snappers@1.10.27(@interactjs/utils@1.10.27)': + dependencies: + '@interactjs/utils': 1.10.27 + optionalDependencies: + '@interactjs/interact': 1.10.27 + + '@interactjs/utils@1.10.27': {} + '@intlify/core-base@9.14.5': dependencies: '@intlify/message-compiler': 9.14.5 @@ -8558,8 +8771,6 @@ snapshots: '@jeecg/aiflow@3.9.1-beta': {} - '@jeecg/online@3.9.1-beta': {} - '@jest/console@29.7.0': dependencies: '@jest/types': 29.6.3 @@ -9878,6 +10089,8 @@ snapshots: dependencies: safe-buffer: 5.1.2 + batch-processor@1.0.0: {} + big.js@5.2.2: {} big.js@6.2.2: {} @@ -10060,8 +10273,6 @@ snapshots: undici: 7.18.2 whatwg-mimetype: 4.0.0 - china-area-data@5.0.1: {} - chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -10707,6 +10918,10 @@ snapshots: electron-to-chromium@1.5.267: {} + element-resize-detector@1.2.4: + dependencies: + batch-processor: 1.0.0 + emittery@0.13.1: {} emoji-mart-vue-fast@15.0.5(vue@3.5.27(typescript@5.9.3)): @@ -12549,6 +12764,13 @@ snapshots: emojis-list: 3.0.0 json5: 1.0.2 + local-pkg@0.4.3: {} + + local-pkg@0.5.1: + dependencies: + mlly: 1.8.0 + pkg-types: 1.3.1 + local-pkg@1.1.2: dependencies: mlly: 1.8.0 @@ -12638,6 +12860,8 @@ snapshots: dependencies: yallist: 4.0.0 + lunar-javascript@1.7.7: {} + luxon@3.7.2: {} magic-string@0.25.9: @@ -12685,6 +12909,8 @@ snapshots: punycode.js: 2.3.1 uc.micro: 2.1.0 + material-colors@1.2.6: {} + math-intrinsics@1.1.0: {} mathml-tag-names@2.1.3: {} @@ -12791,6 +13017,10 @@ snapshots: dependencies: brace-expansion: 2.0.2 + minimatch@7.4.9: + dependencies: + brace-expansion: 2.0.2 + minimatch@9.0.1: dependencies: brace-expansion: 2.0.2 @@ -12815,6 +13045,8 @@ snapshots: minipass@7.1.2: {} + mitt@3.0.1: {} + mixin-deep@1.3.2: dependencies: for-in: 1.0.2 @@ -13085,6 +13317,10 @@ snapshots: package-json-from-dist@1.0.1: {} + package-manager-detector@0.2.11: + dependencies: + quansync: 0.2.11 + package-manager-detector@1.6.0: {} param-case@3.0.4: @@ -13184,6 +13420,8 @@ snapshots: perfect-debounce@1.0.0: {} + perfect-scrollbar@1.5.6: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -14469,6 +14707,52 @@ snapshots: unpipe@1.0.0: {} + unplugin-icons@0.22.0(@vue/compiler-sfc@3.5.27)(vue-template-compiler@2.7.16): + dependencies: + '@antfu/install-pkg': 0.5.0 + '@antfu/utils': 0.7.10 + '@iconify/utils': 2.3.0 + debug: 4.4.3 + kolorist: 1.8.0 + local-pkg: 0.5.1 + unplugin: 2.3.11 + optionalDependencies: + '@vue/compiler-sfc': 3.5.27 + vue-template-compiler: 2.7.16 + transitivePeerDependencies: + - supports-color + + unplugin-vue-components@0.24.1(@babel/parser@7.28.6)(rollup@4.52.5)(vue@3.5.27(typescript@5.9.3)): + dependencies: + '@antfu/utils': 0.7.10 + '@rollup/pluginutils': 5.3.0(rollup@4.52.5) + chokidar: 3.6.0 + debug: 4.4.3 + fast-glob: 3.3.3 + local-pkg: 0.4.3 + magic-string: 0.30.21 + minimatch: 7.4.9 + resolve: 1.22.11 + unplugin: 1.16.1 + vue: 3.5.27(typescript@5.9.3) + optionalDependencies: + '@babel/parser': 7.28.6 + transitivePeerDependencies: + - rollup + - supports-color + + unplugin@1.16.1: + dependencies: + acorn: 8.15.0 + webpack-virtual-modules: 0.6.2 + + unplugin@2.3.11: + dependencies: + '@jridgewell/remapping': 2.3.5 + acorn: 8.15.0 + picomatch: 4.0.3 + webpack-virtual-modules: 0.6.2 + unset-value@1.0.0: dependencies: has-value: 0.3.1 @@ -14645,6 +14929,12 @@ snapshots: terser: 5.46.0 tsx: 4.21.0 + vue-color@3.3.3(vue@3.5.27(typescript@5.9.3)): + dependencies: + material-colors: 1.2.6 + tinycolor2: 1.6.0 + vue: 3.5.27(typescript@5.9.3) + vue-component-type-helpers@2.2.12: {} vue-cropper@0.6.5: {} @@ -14671,6 +14961,21 @@ snapshots: transitivePeerDependencies: - supports-color + vue-grid-layout-v3@3.1.2(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27)(typescript@5.9.3): + dependencies: + '@interactjs/actions': 1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27) + '@interactjs/auto-scroll': 1.10.27(@interactjs/utils@1.10.27) + '@interactjs/auto-start': 1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27) + '@interactjs/dev-tools': 1.10.27(@interactjs/modifiers@1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27)(typescript@5.9.3) + '@interactjs/interact': 1.10.27 + '@interactjs/modifiers': 1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27) + element-resize-detector: 1.2.4 + mitt: 3.0.1 + transitivePeerDependencies: + - '@interactjs/core' + - '@interactjs/utils' + - typescript + vue-i18n@9.14.5(vue@3.5.27(typescript@5.9.3)): dependencies: '@intlify/core-base': 9.14.5 @@ -14759,6 +15064,8 @@ snapshots: webidl-conversions@4.0.2: {} + webpack-virtual-modules@0.6.2: {} + whatwg-encoding@2.0.0: dependencies: iconv-lite: 0.6.3 diff --git a/jeecgboot-vue3/src/components/Form/index.ts b/jeecgboot-vue3/src/components/Form/index.ts index c89160175..486016d28 100644 --- a/jeecgboot-vue3/src/components/Form/index.ts +++ b/jeecgboot-vue3/src/components/Form/index.ts @@ -1,38 +1,43 @@ import BasicForm from './src/BasicForm.vue'; - +import { defineAsyncComponent } from 'vue'; export * from './src/types/form'; export * from './src/types/formItem'; export { useComponentRegister } from './src/hooks/useComponentRegister'; export { useForm } from './src/hooks/useForm'; -export { default as ApiSelect } from './src/components/ApiSelect.vue'; -export { default as RadioButtonGroup } from './src/components/RadioButtonGroup.vue'; -export { default as ApiTreeSelect } from './src/components/ApiTreeSelect.vue'; -export { default as ApiRadioGroup } from './src/components/ApiRadioGroup.vue'; +export const ApiSelect = defineAsyncComponent(() => import('./src/components/ApiSelect.vue')); +export const RadioButtonGroup = defineAsyncComponent(() => import('./src/components/RadioButtonGroup.vue')); +export const ApiTreeSelect = defineAsyncComponent(() => import('./src/components/ApiTreeSelect.vue')); +export const ApiRadioGroup = defineAsyncComponent(() => import('./src/components/ApiRadioGroup.vue')); //Jeecg自定义组件 -export { default as JAreaLinkage } from './src/jeecg/components/JAreaLinkage.vue'; -export { default as JSelectUser } from './src/jeecg/components/JSelectUser.vue'; -export { default as JSelectDept } from './src/jeecg/components/JSelectDept.vue'; -export { default as JSelectDepartPost } from './src/jeecg/components/JSelectDepartPost.vue'; -export { default as JSelectUserByDeptPost } from './src/jeecg/components/JSelectUserByDeptPost.vue'; -export { default as JCodeEditor } from './src/jeecg/components/JCodeEditor.vue'; -export { default as JCategorySelect } from './src/jeecg/components/JCategorySelect.vue'; -export { default as JSelectMultiple } from './src/jeecg/components/JSelectMultiple.vue'; -export { default as JPopup } from './src/jeecg/components/JPopup.vue'; -export { default as JAreaSelect } from './src/jeecg/components/JAreaSelect.vue'; -export { JEasyCron, JEasyCronInner, JEasyCronModal } from '/@/components/Form/src/jeecg/components/JEasyCron'; -export { default as JCheckbox } from './src/jeecg/components/JCheckbox.vue'; -export { default as JInput } from './src/jeecg/components/JInput.vue'; -export { default as JEllipsis } from './src/jeecg/components/JEllipsis.vue'; -export { default as JDictSelectTag } from './src/jeecg/components/JDictSelectTag.vue'; -export { default as JTreeSelect } from './src/jeecg/components/JTreeSelect.vue'; -export { default as JSearchSelect } from './src/jeecg/components/JSearchSelect.vue'; -export { default as JSelectUserByDept } from './src/jeecg/components/JSelectUserByDept.vue'; -export { default as JSelectUserByDepartment } from './src/jeecg/components/JSelectUserByDepartment.vue'; -export { default as JEditor } from './src/jeecg/components/JEditor.vue'; -export { default as JImageUpload } from './src/jeecg/components/JImageUpload.vue'; +export const JAreaLinkage = defineAsyncComponent(() => import('./src/jeecg/components/JAreaLinkage.vue')); +export const JSelectUser = defineAsyncComponent(() => import('./src/jeecg/components/JSelectUser.vue')); +export const JSelectDept = defineAsyncComponent(() => import('./src/jeecg/components/JSelectDept.vue')); +export const JSelectDepartPost = defineAsyncComponent(() => import('./src/jeecg/components/JSelectDepartPost.vue')); +export const JSelectUserByDeptPost = defineAsyncComponent(() => import('./src/jeecg/components/JSelectUserByDeptPost.vue')); +export const JCodeEditor = defineAsyncComponent(() => import('./src/jeecg/components/JCodeEditor.vue')); +export const JCategorySelect = defineAsyncComponent(() => import('./src/jeecg/components/JCategorySelect.vue')); +export const JSelectMultiple = defineAsyncComponent(() => import('./src/jeecg/components/JSelectMultiple.vue')); +export const JPopup = defineAsyncComponent(() => import('./src/jeecg/components/JPopup.vue')); +export const JAreaSelect = defineAsyncComponent(() => import('./src/jeecg/components/JAreaSelect.vue')); +export const JEasyCron = defineAsyncComponent(() => import('./src/jeecg/components/JEasyCron/EasyCronInput.vue')); +export const JEasyCronInner = defineAsyncComponent(() => import('./src/jeecg/components/JEasyCron/EasyCronInner.vue')); +export const JEasyCronModal = defineAsyncComponent(() => import('./src/jeecg/components/JEasyCron/EasyCronModal.vue')); +export const JCheckbox = defineAsyncComponent(() => import('./src/jeecg/components/JCheckbox.vue')); +export const JInput = defineAsyncComponent(() => import('./src/jeecg/components/JInput.vue')); +export const JEllipsis = defineAsyncComponent(() => import('./src/jeecg/components/JEllipsis.vue')); +export const JDictSelectTag = defineAsyncComponent(() => import('./src/jeecg/components/JDictSelectTag.vue')); +export const JTreeSelect = defineAsyncComponent(() => import('./src/jeecg/components/JTreeSelect.vue')); +export const JSearchSelect = defineAsyncComponent(() => import('./src/jeecg/components/JSearchSelect.vue')); +export const JSelectUserByDept = defineAsyncComponent(() => import('./src/jeecg/components/JSelectUserByDept.vue')); +export const JSelectUserByDepartment = defineAsyncComponent(() => import('./src/jeecg/components/JSelectUserByDepartment.vue')); +// update-begin--author:liaozhiyang---date:20260227---for:【QQYUN-14751】tinymce富文本、JEasyCron、JLinkTableCard异步加载 +export const JEditor = defineAsyncComponent(() => import('./src/jeecg/components/JEditor.vue')); +// update-end--author:liaozhiyang---date:20260227---for:【QQYUN-14751】tinymce富文本、JEasyCron、JLinkTableCard异步加载 +export const JImageUpload = defineAsyncComponent(() => import('./src/jeecg/components/JImageUpload.vue')); // Jeecg自定义校验 -export { JCronValidator } from '/@/components/Form/src/jeecg/components/JEasyCron'; - +// update-begin--author:liaozhiyang---date:20260303---for:【QQYUN-14815】JCronValidator从Form中注释,防止首页加载,改为业务中直接导入 +// export { default as JCronValidator } from '/@/components/Form/src/jeecg/components/JEasyCron/validator'; +// update-end--author:liaozhiyang---date:20260303---for:【QQYUN-14815】JCronValidator从Form中注释,防止首页加载,改为业务中直接导入 export { BasicForm }; diff --git a/jeecgboot-vue3/src/components/Form/src/componentMap.ts b/jeecgboot-vue3/src/components/Form/src/componentMap.ts index 58f8e4a35..e579762a2 100644 --- a/jeecgboot-vue3/src/components/Form/src/componentMap.ts +++ b/jeecgboot-vue3/src/components/Form/src/componentMap.ts @@ -1,10 +1,5 @@ /** - * 目前实现了异步加载的组件清单 : - * JAreaLinkage - * JEditor - * JMarkdownEditor - * JCodeEditor - * JEasyCron + * 目前实现了异步加载的组件清单(antd 组件已改为 createAsyncComponent 异步加载) */ import type { Component } from 'vue'; import type { ComponentType } from './types/index'; @@ -12,182 +7,93 @@ import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; /** * Component list, register here to setting it in the form */ -import { - Input, - Select, - Radio, - Checkbox, - AutoComplete, - Cascader, - DatePicker, - InputNumber, - Switch, - TimePicker, - TreeSelect, - Slider, - Rate, - Divider, -} from 'ant-design-vue'; -import ApiRadioGroup from './components/ApiRadioGroup.vue'; -import RadioButtonGroup from './components/RadioButtonGroup.vue'; -import ApiSelect from './components/ApiSelect.vue'; -import ApiTreeSelect from './components/ApiTreeSelect.vue'; -import { BasicUpload } from '/@/components/Upload'; -import { StrengthMeter } from '/@/components/StrengthMeter'; -import { IconPicker } from '/@/components/Icon'; -import { CountdownInput } from '/@/components/CountDown'; -//自定义组件 -// import JAreaLinkage from './jeecg/components/JAreaLinkage.vue'; -import JSelectUser from './jeecg/components/JSelectUser.vue'; -import JSelectPosition from './jeecg/components/JSelectPosition.vue'; -import JSelectRole from './jeecg/components/JSelectRole.vue'; -import JImageUpload from './jeecg/components/JImageUpload.vue'; -import JDictSelectTag from './jeecg/components/JDictSelectTag.vue'; -import JSelectDept from './jeecg/components/JSelectDept.vue'; -import JSelectDepartPost from './jeecg/components/JSelectDepartPost.vue'; -import JAreaSelect from './jeecg/components/JAreaSelect.vue'; -import JEditor from './jeecg/components/JEditor.vue'; -// import JMarkdownEditor from './jeecg/components/JMarkdownEditor.vue'; -import JSelectInput from './jeecg/components/JSelectInput.vue'; -// import JCodeEditor from './jeecg/components/JCodeEditor.vue'; -import JCategorySelect from './jeecg/components/JCategorySelect.vue'; -import JSelectMultiple from './jeecg/components/JSelectMultiple.vue'; -import JPopup from './jeecg/components/JPopup.vue'; -// 代码逻辑说明: 【QQYUN-7961】popupDict字典 -import JPopupDict from './jeecg/components/JPopupDict.vue'; -import JSwitch from './jeecg/components/JSwitch.vue'; -import JTreeDict from './jeecg/components/JTreeDict.vue'; -import JInputPop from './jeecg/components/JInputPop.vue'; -// import { JEasyCron } from './jeecg/components/JEasyCron'; -import JCheckbox from './jeecg/components/JCheckbox.vue'; -import JInput from './jeecg/components/JInput.vue'; -import JTreeSelect from './jeecg/components/JTreeSelect.vue'; -import JEllipsis from './jeecg/components/JEllipsis.vue'; -import JSelectUserByDept from './jeecg/components/JSelectUserByDept.vue'; -import JSelectUserByDepartment from './jeecg/components/JSelectUserByDepartment.vue'; -import JLinkTableCard from './jeecg/components/JLinkTableCard/JLinkTableCard.vue'; - -import JUpload from './jeecg/components/JUpload/JUpload.vue'; -import JSearchSelect from './jeecg/components/JSearchSelect.vue'; -import JAddInput from './jeecg/components/JAddInput.vue'; -import { Time } from '/@/components/Time'; -import JRangeNumber from './jeecg/components/JRangeNumber.vue'; -import UserSelect from './jeecg/components/userSelect/index.vue'; -import JRangeDate from './jeecg/components/JRangeDate.vue' -import JRangeTime from './jeecg/components/JRangeTime.vue' -import JInputSelect from './jeecg/components/JInputSelect.vue' -import RoleSelectInput from './jeecg/components/roleSelect/RoleSelectInput.vue'; -import JSelectUserByDeptPost from './jeecg/components/JSelectUserByDeptPost.vue'; -import JDatePickerMultiple from './jeecg/components/JDatePickerMultiple.vue'; -import {DatePickerInFilter, CascaderPcaInFilter} from "@/components/InFilter"; const componentMap = new Map(); -componentMap.set('Time', Time); -componentMap.set('Input', Input); -componentMap.set('InputGroup', Input.Group); -componentMap.set('InputPassword', Input.Password); -componentMap.set('InputSearch', Input.Search); -componentMap.set('InputTextArea', Input.TextArea); -componentMap.set('InputNumber', InputNumber); -componentMap.set('AutoComplete', AutoComplete); +componentMap.set('Time', createAsyncComponent(() => import('/@/components/Time/src/Time.vue'))); +componentMap.set('Input', createAsyncComponent(() => import('ant-design-vue/es/input'))); +componentMap.set('InputGroup', createAsyncComponent(() => import('ant-design-vue/es/input/Group'))); +componentMap.set('InputPassword', createAsyncComponent(() => import('ant-design-vue/es/input/Password'))); +componentMap.set('InputSearch', createAsyncComponent(() => import('ant-design-vue/es/input/Search'))); +componentMap.set('InputTextArea', createAsyncComponent(() => import('ant-design-vue/es/input/TextArea'))); +componentMap.set('InputNumber', createAsyncComponent(() => import('ant-design-vue/es/input-number'))); +componentMap.set('AutoComplete', createAsyncComponent(() => import('ant-design-vue/es/auto-complete'))); -componentMap.set('Select', Select); -componentMap.set('ApiSelect', ApiSelect); -componentMap.set('TreeSelect', TreeSelect); -componentMap.set('ApiTreeSelect', ApiTreeSelect); -componentMap.set('ApiRadioGroup', ApiRadioGroup); -componentMap.set('Switch', Switch); -componentMap.set('RadioButtonGroup', RadioButtonGroup); -componentMap.set('RadioGroup', Radio.Group); -componentMap.set('Checkbox', Checkbox); -componentMap.set('CheckboxGroup', Checkbox.Group); -componentMap.set('Cascader', Cascader); -componentMap.set('Slider', Slider); -componentMap.set('Rate', Rate); +componentMap.set('Select', createAsyncComponent(() => import('ant-design-vue/es/select'))); +componentMap.set('ApiSelect', createAsyncComponent(() => import('./components/ApiSelect.vue'))); +componentMap.set('JTabsSelectUser', createAsyncComponent(() => import('@/components/jeecg/JTabsSelectUser/index.vue'))); +componentMap.set('TreeSelect', createAsyncComponent(() => import('ant-design-vue/es/tree-select'))); +componentMap.set('ApiTreeSelect', createAsyncComponent(() => import('./components/ApiTreeSelect.vue'))); +componentMap.set('ApiRadioGroup', createAsyncComponent(() => import('./components/ApiRadioGroup.vue'))); +componentMap.set('Switch', createAsyncComponent(() => import('ant-design-vue/es/switch'))); +componentMap.set('RadioButtonGroup', createAsyncComponent(() => import('./components/RadioButtonGroup.vue'))); +componentMap.set('RadioGroup', createAsyncComponent(() => import('ant-design-vue/es/radio/Group'))); +componentMap.set('Checkbox', createAsyncComponent(() => import('ant-design-vue/es/checkbox'))); +componentMap.set('CheckboxGroup', createAsyncComponent(() => import('ant-design-vue/es/checkbox/Group'))); +componentMap.set('Cascader', createAsyncComponent(() => import('ant-design-vue/es/cascader'))); +componentMap.set('Slider', createAsyncComponent(() => import('ant-design-vue/es/slider'))); +componentMap.set('Rate', createAsyncComponent(() => import('ant-design-vue/es/rate'))); -componentMap.set('DatePicker', DatePicker); -componentMap.set('MonthPicker', DatePicker.MonthPicker); -componentMap.set('RangePicker', DatePicker.RangePicker); -componentMap.set('WeekPicker', DatePicker.WeekPicker); -componentMap.set('TimePicker', TimePicker); -componentMap.set('DatePickerInFilter', DatePickerInFilter); -componentMap.set('JDatePickerMultiple', JDatePickerMultiple); -componentMap.set('StrengthMeter', StrengthMeter); -componentMap.set('IconPicker', IconPicker); -componentMap.set('InputCountDown', CountdownInput); +componentMap.set('DatePicker', createAsyncComponent(() => import('ant-design-vue/es/date-picker'))); +componentMap.set('MonthPicker', createAsyncComponent(() => import('ant-design-vue/es/date-picker').then((m) => m.default.MonthPicker))); +componentMap.set('RangePicker', createAsyncComponent(() => import('ant-design-vue/es/date-picker').then((m) => m.default.RangePicker))); +componentMap.set('WeekPicker', createAsyncComponent(() => import('ant-design-vue/es/date-picker').then((m) => m.default.WeekPicker))); +componentMap.set('TimePicker', createAsyncComponent(() => import('ant-design-vue/es/time-picker'))); +componentMap.set('DatePickerInFilter', createAsyncComponent(() => import('@/components/InFilter/DatePickerInFilter.vue'))); +componentMap.set('JDatePickerMultiple', createAsyncComponent(() => import('./jeecg/components/JDatePickerMultiple.vue'))); +componentMap.set('StrengthMeter', createAsyncComponent(() => import('/@/components/StrengthMeter/src/StrengthMeter.vue'))); +componentMap.set('IconPicker', createAsyncComponent(() => import('/@/components/Icon/src/IconPicker.vue'))); +componentMap.set('InputCountDown', createAsyncComponent(() => import('/@/components/CountDown/src/CountdownInput.vue'))); -componentMap.set('Upload', BasicUpload); -componentMap.set('Divider', Divider); +componentMap.set('Upload', createAsyncComponent(() => import('/@/components/Upload/src/BasicUpload.vue'))); +componentMap.set('Divider', createAsyncComponent(() => import('ant-design-vue/es/divider'))); //注册自定义组件 -componentMap.set( - 'JAreaLinkage', - createAsyncComponent(() => import('./jeecg/components/JAreaLinkage.vue')) -); -componentMap.set('JSelectPosition', JSelectPosition); -componentMap.set('JSelectUser', JSelectUser); -componentMap.set('JSelectRole', JSelectRole); -componentMap.set('JImageUpload', JImageUpload); -componentMap.set('JDictSelectTag', JDictSelectTag); -componentMap.set('JSelectDept', JSelectDept); -componentMap.set('JAreaSelect', JAreaSelect); -componentMap.set('JLinkTableCard', JLinkTableCard); -// componentMap.set( -// 'JEditor', -// createAsyncComponent(() => import('./jeecg/components/JEditor.vue')) -// ); -componentMap.set('JEditor', JEditor); -componentMap.set( - 'JMarkdownEditor', - createAsyncComponent(() => import('./jeecg/components/JMarkdownEditor.vue')) -); -componentMap.set('JSelectInput', JSelectInput); -componentMap.set( - 'JCodeEditor', - createAsyncComponent(() => import('./jeecg/components/JCodeEditor.vue')) -); -componentMap.set('JCategorySelect', JCategorySelect); -componentMap.set('JSelectMultiple', JSelectMultiple); -componentMap.set('JPopup', JPopup); +componentMap.set('JAreaLinkage', createAsyncComponent(() => import('./jeecg/components/JAreaLinkage.vue'))); +componentMap.set('JSelectPosition', createAsyncComponent(() => import('./jeecg/components/JSelectPosition.vue'))); +componentMap.set('JSelectUser', createAsyncComponent(() => import('./jeecg/components/JSelectUser.vue'))); +componentMap.set('JSelectRole', createAsyncComponent(() => import('./jeecg/components/JSelectRole.vue'))); +componentMap.set('JImageUpload', createAsyncComponent(() => import('./jeecg/components/JImageUpload.vue'))); +componentMap.set('JDictSelectTag', createAsyncComponent(() => import('./jeecg/components/JDictSelectTag.vue'))); +componentMap.set('JSelectDept', createAsyncComponent(() => import('./jeecg/components/JSelectDept.vue'))); +componentMap.set('JAreaSelect', createAsyncComponent(() => import('./jeecg/components/JAreaSelect.vue'))); +// update-begin--author:liaozhiyang---date:20260227---for:【QQYUN-14751】tinymce富文本、JEasyCron、JLinkTableCard异步加载 +componentMap.set('JLinkTableCard', createAsyncComponent(() => import('./jeecg/components/JLinkTableCard/JLinkTableCard.vue'), { loading: true })); +componentMap.set('JEditor', createAsyncComponent(() => import('./jeecg/components/JEditor.vue'))); +// update-end--author:liaozhiyang---date:20260227---for:【QQYUN-14751】tinymce富文本、JEasyCron、JLinkTableCard异步加载 +componentMap.set('JMarkdownEditor', createAsyncComponent(() => import('./jeecg/components/JMarkdownEditor.vue'))); +componentMap.set('JSelectInput', createAsyncComponent(() => import('./jeecg/components/JSelectInput.vue'))); +componentMap.set('JCodeEditor', createAsyncComponent(() => import('./jeecg/components/JCodeEditor.vue'))); +componentMap.set('JCategorySelect', createAsyncComponent(() => import('./jeecg/components/JCategorySelect.vue'))); +componentMap.set('JSelectMultiple', createAsyncComponent(() => import('./jeecg/components/JSelectMultiple.vue'))); +componentMap.set('JSelectSingle', createAsyncComponent(() => import('./jeecg/components/JSelectSingle.vue'))); +componentMap.set('JPopup', createAsyncComponent(() => import('./jeecg/components/JPopup.vue'))); // 代码逻辑说明: 【QQYUN-7961】popupDict字典 -componentMap.set('JPopupDict', JPopupDict); -componentMap.set('JSwitch', JSwitch); -componentMap.set('JTreeDict', JTreeDict); -componentMap.set('JInputPop', JInputPop); -componentMap.set( - 'JEasyCron', - createAsyncComponent(() => import('./jeecg/components/JEasyCron/EasyCronInput.vue')) -); -componentMap.set('JCheckbox', JCheckbox); -componentMap.set('JInput', JInput); -componentMap.set('JTreeSelect', JTreeSelect); -componentMap.set('JEllipsis', JEllipsis); -componentMap.set('JSelectUserByDept', JSelectUserByDept); -componentMap.set('JSelectUserByDepartment', JSelectUserByDepartment); -componentMap.set('JUpload', JUpload); -componentMap.set('JSearchSelect', JSearchSelect); -componentMap.set('JAddInput', JAddInput); -componentMap.set('JRangeNumber', JRangeNumber); -componentMap.set('CascaderPcaInFilter', CascaderPcaInFilter); -componentMap.set('UserSelect', UserSelect); -componentMap.set('RangeDate', JRangeDate); -componentMap.set('RangeTime', JRangeTime); -componentMap.set('RoleSelect', RoleSelectInput); -componentMap.set('JInputSelect', JInputSelect); -componentMap.set('JSelectDepartPost', JSelectDepartPost); -componentMap.set('JSelectUserByDeptPost', JSelectUserByDeptPost); +componentMap.set('JPopupDict', createAsyncComponent(() => import('./jeecg/components/JPopupDict.vue'))); +componentMap.set('JSwitch', createAsyncComponent(() => import('./jeecg/components/JSwitch.vue'))); +componentMap.set('JTreeDict', createAsyncComponent(() => import('./jeecg/components/JTreeDict.vue'))); +componentMap.set('JInputPop', createAsyncComponent(() => import('./jeecg/components/JInputPop.vue'))); +componentMap.set('JEasyCron', createAsyncComponent(() => import('./jeecg/components/JEasyCron/EasyCronInput.vue'))); +componentMap.set('JCheckbox', createAsyncComponent(() => import('./jeecg/components/JCheckbox.vue'))); +componentMap.set('JInput', createAsyncComponent(() => import('./jeecg/components/JInput.vue'))); +componentMap.set('JTreeSelect', createAsyncComponent(() => import('./jeecg/components/JTreeSelect.vue'))); +componentMap.set('JEllipsis', createAsyncComponent(() => import('./jeecg/components/JEllipsis.vue'))); +componentMap.set('JSelectUserByDept', createAsyncComponent(() => import('./jeecg/components/JSelectUserByDept.vue'))); +componentMap.set('JSelectUserByDepartment', createAsyncComponent(() => import('./jeecg/components/JSelectUserByDepartment.vue'))); +componentMap.set('JUpload', createAsyncComponent(() => import('./jeecg/components/JUpload/JUpload.vue'))); +componentMap.set('JSearchSelect', createAsyncComponent(() => import('./jeecg/components/JSearchSelect.vue'))); +componentMap.set('JAddInput', createAsyncComponent(() => import('./jeecg/components/JAddInput.vue'))); +componentMap.set('JRangeNumber', createAsyncComponent(() => import('./jeecg/components/JRangeNumber.vue'))); +componentMap.set('CascaderPcaInFilter', createAsyncComponent(() => import('@/components/InFilter/CascaderPcaInFilter.vue'))); +componentMap.set('UserSelect', createAsyncComponent(() => import('./jeecg/components/userSelect/index.vue'))); +componentMap.set('RangeDate', createAsyncComponent(() => import('./jeecg/components/JRangeDate.vue'))); +componentMap.set('RangeTime', createAsyncComponent(() => import('./jeecg/components/JRangeTime.vue'))); +componentMap.set('RoleSelect', createAsyncComponent(() => import('./jeecg/components/roleSelect/RoleSelectInput.vue'))); +componentMap.set('JInputSelect', createAsyncComponent(() => import('./jeecg/components/JInputSelect.vue'))); +componentMap.set('JSelectDepartPost', createAsyncComponent(() => import('./jeecg/components/JSelectDepartPost.vue'))); +componentMap.set('JSelectUserByDeptPost', createAsyncComponent(() => import('./jeecg/components/JSelectUserByDeptPost.vue'))); -componentMap.set('OnlineSelectCascade', createAsyncComponent(() => { - return import('@jeecg/online').then(mod => mod.OnlineSelectCascade); -})); -componentMap.set('LinkTableCard', createAsyncComponent(() => { - return import('@jeecg/online').then(mod => mod.LinkTableCard); -})); -componentMap.set('LinkTableSelect', createAsyncComponent(() => { - return import('@jeecg/online').then(mod => mod.LinkTableSelect); -})); export function add(compName: ComponentType, component: Component) { componentMap.set(compName, component); diff --git a/jeecgboot-vue3/src/components/Icon/src/Icon.vue b/jeecgboot-vue3/src/components/Icon/src/Icon.vue index d6b13499f..075c57adc 100644 --- a/jeecgboot-vue3/src/components/Icon/src/Icon.vue +++ b/jeecgboot-vue3/src/components/Icon/src/Icon.vue @@ -6,10 +6,8 @@ import type { PropType } from 'vue'; import { defineComponent, ref, watch, onMounted, nextTick, unref, computed, CSSProperties } from 'vue'; import SvgIcon from './SvgIcon.vue'; - import Iconify from '@purge-icons/generated'; import { isString } from '/@/utils/is'; import { propTypes } from '/@/utils/propTypes'; - const SVG_END_WITH_FLAG = '|svg'; export default defineComponent({ name: 'Icon', @@ -43,18 +41,35 @@ await nextTick(); const icon = unref(getIconRef); if (!icon) return; - - const svg = Iconify.renderSVG(icon, {}); - if (svg) { - el.textContent = ''; - el.appendChild(svg); - } else { - const span = document.createElement('span'); - span.className = 'iconify'; - span.dataset.icon = icon; - el.textContent = ''; - el.appendChild(span); + // update-begin--author:liaozhiyang---date:20260304---for:【QQYUN-14802】新增unplugin-icons插件,及icon支持online和local两种模式 + try { + let svg: SVGElement | null = null; + if (import.meta.env.VITE_GLOB_ICONIFY_USE_TYPE === 'local') { + // 使用本地 purge-icons 图标(离线,图标已打包进产物) + const iconifyModule = await import('@purge-icons/generated'); + const Iconify = iconifyModule.default; + svg = Iconify.renderSVG(icon, {}); + } else { + // 使用 @iconify/iconify 在线按需加载 + const iconifyModule = await import('@iconify/iconify'); + const Iconify = iconifyModule.default; + svg = Iconify.renderSVG(icon, {}); + } + if (svg) { + el.textContent = ''; + el.appendChild(svg); + } else { + // 如果图标不存在,显示占位符 + const span = document.createElement('span'); + span.className = 'iconify'; + span.dataset.icon = icon; + el.textContent = ''; + el.appendChild(span); + } + } catch (err) { + console.error('Failed to render icon:', icon, err); } + // update-end--author:liaozhiyang---date:20260304---for:【QQYUN-14802】新增unplugin-icons插件,及icon支持online和local两种模式 }; const getWrapStyle = computed((): CSSProperties => { diff --git a/jeecgboot-vue3/src/components/jeecg/JVxeTable/index.ts b/jeecgboot-vue3/src/components/jeecg/JVxeTable/index.ts index 6ce9d1f2d..2d8ce0aba 100644 --- a/jeecgboot-vue3/src/components/jeecg/JVxeTable/index.ts +++ b/jeecgboot-vue3/src/components/jeecg/JVxeTable/index.ts @@ -1,4 +1,21 @@ -export { default as JVxeTable } from './src/JVxeTable'; +import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; +// update-begin--author:liaozhiyang---date:20260318---for:【QQYUN-14948】需要兼容vxetable引入到了页面也不报错 +// 兼容页面直接引入:通过异步组件包装,确保 vxe-table 注册后再渲染,避免页面卡死 +export const JVxeTable = createAsyncComponent( + async () => { + const app = window['JAppRootInstance']; + if (app && !app._context.components['VxeTable']) { + const { registerJVxeTable } = await import('./src/install'); + await registerJVxeTable(app); + const { registerJVxeCustom } = await import('/@/components/JVxeCustom'); + await registerJVxeCustom(); + } + const m = await import('./src/JVxeTable'); + return m.default; + }, + { loading: true } +); +// update-end--author:liaozhiyang---date:20260318---for:【QQYUN-14948】需要兼容vxetable引入到了页面也不报错 export { registerJVxeTable } from './src/install'; export { deleteComponent } from './src/componentMap'; export { registerComponent, registerAsyncComponent, registerASyncComponentReal } from './src/utils/registerUtils'; diff --git a/jeecgboot-vue3/src/components/jeecg/JVxeTable/useVxeTableRegister.ts b/jeecgboot-vue3/src/components/jeecg/JVxeTable/useVxeTableRegister.ts new file mode 100644 index 000000000..9d2fcb505 --- /dev/null +++ b/jeecgboot-vue3/src/components/jeecg/JVxeTable/useVxeTableRegister.ts @@ -0,0 +1,12 @@ +// 给使用原生vxe-table的页面注册vxe-table组件 +export const useVxeTableRegister = async () => { + const app = window['JAppRootInstance']; + if (app._context.components.VxeTable) { + // 已全局注册 + } else { + const { registerJVxeTable } = await import('/@/components/jeecg/JVxeTable'); + await registerJVxeTable(app); + const { registerJVxeCustom } = await import('/@/components/JVxeCustom'); + await registerJVxeCustom(); + } +} diff --git a/jeecgboot-vue3/src/components/registerGlobComp.ts b/jeecgboot-vue3/src/components/registerGlobComp.ts index bd40cdc1a..b6c4696b9 100644 --- a/jeecgboot-vue3/src/components/registerGlobComp.ts +++ b/jeecgboot-vue3/src/components/registerGlobComp.ts @@ -2,128 +2,38 @@ import type { App } from 'vue'; import { Icon } from './Icon'; import AIcon from '/@/components/jeecg/AIcon.vue'; //Tinymce富文本 - import Editor from '/@/components/Tinymce/src/Editor.vue' +// import Editor from '/@/components/Tinymce/src/Editor.vue' import { Button, JUploadButton } from './Button'; +import { Space } from 'ant-design-vue'; -// 按需注册antd的组件 -import { - // Need - Button as AntButton, - Select, - Alert, - Checkbox, - DatePicker, - TimePicker, - Calendar, - Radio, - Switch, - Card, - List, - Tabs, - Descriptions, - Tree, - Table, - Divider, - Modal, - Drawer, - TreeSelect, - Dropdown, - Tag, - Tooltip, - Badge, - Popover, - Upload, - Transfer, - Steps, - PageHeader, - Result, - Empty, - Avatar, - Menu, - Breadcrumb, - Form, - Input, - Row, - Col, - Spin, - Space, - Layout, - Collapse, - Slider, - InputNumber, - Carousel, - Popconfirm, - Skeleton, - Cascader, - Rate, - Progress -} from 'ant-design-vue'; -const compList = [AntButton.Group, Icon, AIcon, JUploadButton]; +// ant-design-vue 组件通过 unplugin-vue-components + AntDesignVueResolver 自动按需导入,无需手动注册 +const compList = [Icon, AIcon, JUploadButton]; +//注册online模块的全局组件 +import { registerOnlineComp } from '/@/views/super/online/cgform/auto/comp/index'; +import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; export function registerGlobComp(app: App) { compList.forEach((comp) => { app.component(comp.name || comp.displayName, comp); }); + // Space.Compact 是子组件,AntDesignVueResolver 无法自动解析,需手动注册 + app.component('ASpaceCompact', Space.Compact); //仪表盘依赖Tinymce,需要提前加载(没办法按需加载了) - app.component(Editor.name, Editor); + // app.component(Editor.name, Editor); // 代码逻辑说明: Tinymce异步加载 - // app.component( - // 'Tinymce', - // createAsyncComponent(() => import('./Tinymce/src/Editor.vue'), { - // loading: true, - // }) - // ); - app.use(Select) - .use(Alert) + // update-begin--author:liaozhiyang---date:20260227---for:【QQYUN-14751】tinymce富文本、JEasyCron、JLinkTableCard异步加载 + app.component( + 'Tinymce', + createAsyncComponent(() => import('./Tinymce/src/Editor.vue'), { + loading: true, + }) + ); + // update-end--author:liaozhiyang---date:20260227---for:【QQYUN-14751】tinymce富文本、JEasyCron、JLinkTableCard异步加载 + app + .use(registerOnlineComp) .use(Button) - .use(Breadcrumb) - .use(Checkbox) - .use(DatePicker) - .use(TimePicker) - .use(Calendar) - .use(Radio) - .use(Switch) - .use(Card) - .use(List) - .use(Descriptions) - .use(Tree) - .use(TreeSelect) - .use(Table) - .use(Divider) - .use(Modal) - .use(Drawer) - .use(Dropdown) - .use(Tag) - .use(Tooltip) - .use(Badge) - .use(Popover) - .use(Upload) - .use(Transfer) - .use(Steps) - .use(PageHeader) - .use(Result) - .use(Empty) - .use(Avatar) - .use(Menu) - .use(Tabs) - .use(Form) - .use(Input) - .use(Row) - .use(Col) - .use(Spin) - .use(Space) - .use(Layout) - .use(Collapse) - .use(Slider) - .use(InputNumber) - .use(Carousel) - .use(Popconfirm) - .use(Skeleton) - .use(Cascader) - .use(Rate) - .use(Progress); - console.log("---初始化---, 全局注册Antd、仪表盘、流程设计器、online、流程等组件--------------") + console.log("---初始化---, 全局注册Antd、仪表盘、流程设计器、online、流程等组件--------------") } diff --git a/jeecgboot-vue3/src/router/helper/routeHelper.ts b/jeecgboot-vue3/src/router/helper/routeHelper.ts index 402334b89..b90701155 100644 --- a/jeecgboot-vue3/src/router/helper/routeHelper.ts +++ b/jeecgboot-vue3/src/router/helper/routeHelper.ts @@ -10,6 +10,7 @@ import { URL_HASH_TAB, _eval } from '/@/utils'; //引入online lib路由 import { packageViews } from '/@/utils/monorepo/dynamicRouter'; import { loadPackageComponent } from '/@/utils/monorepo/registerPackages'; +import { dynamicPages } from '/@/utils/dynamicPages'; import {useI18n} from "/@/hooks/web/useI18n"; export type LayoutMapKey = 'LAYOUT'; @@ -28,7 +29,9 @@ let dynamicViewsModules: Record Promise>; // Dynamic introduction function asyncImportRoute(routes: AppRouteRecordRaw[] | undefined) { if (!dynamicViewsModules) { - dynamicViewsModules = import.meta.glob('../../views/**/*.{vue,tsx}'); + // update-begin--author:liaozhiyang---date:20260302---for:【QQYUN-14799】动态引入页面会生成两份及引入components下的组件文件 + dynamicViewsModules = dynamicPages as Record Promise>; + // update-end--author:liaozhiyang---date:20260302---for:【QQYUN-14799】动态引入页面会生成两份及引入components下的组件文件 //合并online lib路由 dynamicViewsModules = Object.assign({}, dynamicViewsModules, packageViews); } @@ -105,7 +108,10 @@ function asyncImportRoute(routes: AppRouteRecordRaw[] | undefined) { function dynamicImport(dynamicViewsModules: Record Promise>, component: string) { const keys = Object.keys(dynamicViewsModules); const matchKeys = keys.filter((key) => { - const k = key.replace('../../views', ''); + // update-begin--author:liaozhiyang---date:20260302---for:【QQYUN-14799】动态引入页面会生成两份及引入components下的组件文件 + // 兼容两种前缀:dynamicPages 的 ../views 与 packageViews 的 ../../views + const k = key.replace(/^(\.\.\/)+views/, ''); + // update-end--author:liaozhiyang---date:20260302---for:【QQYUN-14799】动态引入页面会生成两份及引入components下的组件文件 const startFlag = component.startsWith('/'); const endFlag = component.endsWith('.vue') || component.endsWith('.tsx'); const startIndex = startFlag ? 0 : 1; @@ -122,7 +128,7 @@ function dynamicImport(dynamicViewsModules: Record Promise { return loadPackageComponent(component).then((factory) => (factory ? factory() : Promise.reject(`组件 ${component} 未找到`))); }; diff --git a/jeecgboot-vue3/src/utils/dynamicPages.ts b/jeecgboot-vue3/src/utils/dynamicPages.ts new file mode 100644 index 000000000..88e71d277 --- /dev/null +++ b/jeecgboot-vue3/src/utils/dynamicPages.ts @@ -0,0 +1,10 @@ +// 获取所有动态页面(views目录下的所有vue文件和tsx文件) +const allFiles = import.meta.glob( + [ + '../views/**/*.{vue,tsx}',// 获取所有vue和tsx文件 + // 排除特定文件夹 + '!../views/system/approvalrole/compoments/**', + ] +); +// 合并所有动态页面 +export const dynamicPages = { ...allFiles }; diff --git a/jeecgboot-vue3/src/utils/index.ts b/jeecgboot-vue3/src/utils/index.ts index ca012f53b..9d99bf9e3 100644 --- a/jeecgboot-vue3/src/utils/index.ts +++ b/jeecgboot-vue3/src/utils/index.ts @@ -4,6 +4,7 @@ import type { FormSchema, FormActionType } from "@/components/Form"; import { unref } from 'vue'; import { isObject, isFunction, isString } from '/@/utils/is'; +import { dynamicPages } from './dynamicPages'; import Big from 'big.js'; import dayjs from "dayjs"; // 代码逻辑说明: 【VUEN-656】配置外部网址打不开,原因是带了#号,需要替换一下 @@ -348,7 +349,6 @@ export function numToUpper(value) { } // 代码逻辑说明: 解决老的vue2动态导入文件语法 vite不支持的问题 -const allModules = import.meta.glob('../views/**/*.vue'); export function importViewsFile(path): Promise { if (path.startsWith('/')) { path = path.substring(1); @@ -361,10 +361,10 @@ export function importViewsFile(path): Promise { } return new Promise((resolve, reject) => { let flag = true; - for (const path in allModules) { + for (const path in dynamicPages) { if (path == page) { flag = false; - allModules[path]().then((mod) => { + dynamicPages[path]().then((mod) => { console.log(path, mod); resolve(mod); }); @@ -669,3 +669,171 @@ export const split = (str) => { } return str; }; +/** + * 处理word文档中的o:p标签 + * @param html + */ +export const removeSpecialTags = (html: string): string => { + if (!html) return ''; + try { + const BORDER = '1px solid #8c8c8c'; + + // =================================================================== + // 第一步:移除 Office 垃圾标签(纯字符串) + // =================================================================== + // o:p 标签(转义和普通形式) + html = html.replace(/<o:p[^&]*?>.*?<\/o:p>/gis, ''); + html = html.replace(/<o:p[^&]*?\/?>/gis, ''); + html = html.replace(/<\/o:p>/gis, ''); + html = html.replace(/]*>.*?<\/o:p>/gis, ''); + html = html.replace(/]*\/?>/gis, ''); + html = html.replace(/<\/o:p>/gis, ''); + + // style 标签(转义和普通形式) + html = html.replace(/<style[^&]*?>.*?<\/style>/gis, ''); + html = html.replace(/<style[^&]*?\/?>/gis, ''); + html = html.replace(/<\/style>/gis, ''); + html = html.replace(/]*>.*?<\/style>/gis, ''); + + // 条件注释和 Office 命名空间标签 + html = html.replace(//gis, ''); + html = html.replace(/<\/?w:[^>]*>/gis, ''); + html = html.replace(/<\/?xml[^>]*>/gis, ''); + html = html.replace(/<\/?v:[^>]*>/gis, ''); + + // =================================================================== + // 第二步:DOM 清理(仅清理空段落,完全不动表格行结构) + // ★ 关键:放在边框处理之前,防止 DOM 序列化丢失 !important + // =================================================================== + try { + const DOMParserCtor: any = + typeof DOMParser !== 'undefined' ? DOMParser : (globalThis as any).DOMParser; + if (DOMParserCtor) { + const parser = new DOMParserCtor() as DOMParser; + const doc = parser.parseFromString(html, 'text/html') as Document; + + // 仅清理单元格内的空

标签 + const cells = doc.querySelectorAll('td,th'); + for (let ci = 0; ci < cells.length; ci++) { + const cell = cells[ci] as HTMLElement; + if (!cell) continue; + const ps = cell.querySelectorAll('p'); + for (let pi = ps.length - 1; pi >= 0; pi--) { + const p = ps[pi] as HTMLParagraphElement; + if (!p) continue; + const content = (p.innerHTML || '').replace(/ |\u00A0/g, '').trim(); + if (content === '') { + p.remove(); + } else { + const frag = doc.createDocumentFragment(); + while (p.firstChild) frag.appendChild(p.firstChild); + if (p.parentNode) p.parentNode.replaceChild(frag, p); + } + } + } + + html = doc.body.innerHTML; + } + } catch (_) { + // DOM 不可用,跳过段落清理(不影响边框修复) + } + + // =================================================================== + // 第三步:注入全局表格样式 `; + + if (/]*>/i.test(html)) { + html = html.replace(/(]*>)/i, `$1${globalCSS}`); + } else if (/]*>/i.test(html)) { + html = html.replace(/(]*>)/i, `$1${globalCSS}`); + } else { + html = globalCSS + html; + } + + // =================================================================== + // 第四步:纯字符串处理内联样式(核心边框修复) + // ★ 最后执行!确保输出 HTML 中的 !important 不会被任何后续处理丢失 + // + // 策略:按分号拆分 style 值,逐条判断属性名, + // 过滤掉所有 border* 和 mso-* 声明, + // 然后追加统一的边框声明(含 !important) + // =================================================================== + + /** + * 从 CSS style 字符串中移除所有 border* 和 mso-* 声明, + * 保留其余布局相关属性(width, height, padding, text-align 等) + */ + function stripBorderAndMso(styleStr: string): string { + return styleStr + .split(';') + .filter(function (decl) { + const trimmed = decl.trim(); + if (!trimmed) return false; + const colonIdx = trimmed.indexOf(':'); + if (colonIdx === -1) return true; // 保留无效声明(安全起见) + const prop = trimmed.substring(0, colonIdx).trim().toLowerCase(); + // 移除所有 border 开头和 mso- 开头的属性 + if (prop.startsWith('border') || prop.startsWith('mso-')) return false; + return true; + }) + .join(';'); + } + + // 4a. 移除 上的 border="0" HTML 属性 + html = html.replace(/(]*?)\sborder\s*=\s*['"]?0['"]?/gi, '$1'); + + // 4b. 处理
标签的内联样式 + html = html.replace(/]*)>/gi, function (fullMatch, attrs) { + try { + const sm = attrs.match(/\sstyle\s*=\s*(["'])([\s\S]*?)\1/i); + if (sm) { + const q = sm[1]; + const cleaned = stripBorderAndMso(sm[2]); + const newStyle = cleaned + + ';border-collapse:collapse!important' + + ';border-spacing:0!important' + + ';width:100%!important'; + return ''; + } + return ''; + } catch (_) { return fullMatch; } + }); + + // 4c. 处理
/ 标签的内联样式 + const cellBorderCSS = + `border-top:${BORDER}!important;` + + `border-right:${BORDER}!important;` + + `border-bottom:${BORDER}!important;` + + `border-left:${BORDER}!important;` + + 'padding:6px 8px!important;' + + 'vertical-align:middle!important;' + + 'box-sizing:border-box!important'; + + html = html.replace(/<(td|th)(\s[^>]*)>/gi, function (fullMatch, tag, attrs) { + try { + const sm = attrs.match(/\sstyle\s*=\s*(["'])([\s\S]*?)\1/i); + if (sm) { + const q = sm[1]; + const cleaned = stripBorderAndMso(sm[2]); + const newStyle = (cleaned ? cleaned + ';' : '') + cellBorderCSS; + return '<' + tag + attrs.replace(sm[0], ` style=${q}${newStyle}${q}`) + '>'; + } + return '<' + tag + attrs + ` style="${cellBorderCSS}">`; + } catch (_) { return fullMatch; } + }); + + return html; + } catch (_) { + return html; + } +}; + + diff --git a/jeecgboot-vue3/src/utils/monorepo/registerPackages.ts b/jeecgboot-vue3/src/utils/monorepo/registerPackages.ts index 68ec73235..4223c7e9e 100644 --- a/jeecgboot-vue3/src/utils/monorepo/registerPackages.ts +++ b/jeecgboot-vue3/src/utils/monorepo/registerPackages.ts @@ -1,11 +1,9 @@ import type { App } from 'vue'; import { warn } from '/@/utils/log'; import { registerDynamicRouter } from '/@/utils/monorepo/dynamicRouter'; -import { createAsyncComponent } from "@/utils/factory/createAsyncComponent"; // 懒加载模块配置(按需加载,访问相关路由时才加载对应包) const lazyPackages = [ - { name: '@jeecg/online', importer: () => import('@jeecg/online') }, { name: '@jeecg/aiflow', importer: () => import('@jeecg/aiflow') }, ]; @@ -19,14 +17,14 @@ const installOptions = { export function registerPackages(app: App) { // 仅保存 app 实例,不立即加载模块 appInstance = app; - app.component( - 'SuperQuery', - createAsyncComponent(() => import('@jeecg/online').then(mod => mod.SuperQuery)) - ); - app.component( - 'JOnlineSearchSelect', - createAsyncComponent(() => import('@jeecg/online').then(mod => mod.JOnlineSearchSelect)) - ); + // app.component( + // 'SuperQuery', + // createAsyncComponent(() => import('@jeecg/online').then(mod => mod.SuperQuery)) + // ); + // app.component( + // 'JOnlineSearchSelect', + // createAsyncComponent(() => import('@jeecg/online').then(mod => mod.JOnlineSearchSelect)) + // ); } /** 已加载的包缓存 */ diff --git a/jeecgboot-vue3/vite.config.ts b/jeecgboot-vue3/vite.config.ts index 07009431d..0e3932abe 100644 --- a/jeecgboot-vue3/vite.config.ts +++ b/jeecgboot-vue3/vite.config.ts @@ -19,7 +19,7 @@ const __APP_INFO__ = { lastBuildTime: dayjs().format('YYYY-MM-DD HH:mm:ss'), }; -export default ({ command, mode }: ConfigEnv): UserConfig => { +export default async ({ command, mode }: ConfigEnv): Promise => { const root = process.cwd(); const env = loadEnv(mode, root); @@ -86,6 +86,17 @@ export default ({ command, mode }: ConfigEnv): UserConfig => { proxy: createProxy(VITE_PROXY), // 合并 server 配置 ...serverOptions, + // update-begin--author:liaozhiyang---date:20260306---for:【QQYUN-14801】vite启动的时候,预构建一些入口页面,访问时快一些 + // 启动时预构建 + warmup: { + clientFiles: [ + './src/main.ts', + './src/App.vue', + './src/views/system/loginmini/MiniLogin.vue', + 'src/layouts/default/index.vue' + ], + }, + // update-end--author:liaozhiyang---date:20260306---for:【QQYUN-14801】vite启动的时候,预构建一些入口页面,访问时快一些 }, build: { minify: 'esbuild', @@ -94,7 +105,7 @@ export default ({ command, mode }: ConfigEnv): UserConfig => { outDir: OUTPUT_DIR, rollupOptions: { // 关闭除屑优化,防止删除重要代码,导致打包后功能出现异常 - treeshake: false, + // treeshake: false, output: { chunkFileNames: 'js/[name]-[hash].js', // 引入文件名的名称 entryFileNames: 'js/[name]-[hash].js', // 包的入口文件名称 @@ -102,10 +113,7 @@ export default ({ command, mode }: ConfigEnv): UserConfig => { manualChunks: { // vue vue-router合并打包 'vue-vendor': ['vue', 'vue-router'], - 'antd-vue-vendor': ['ant-design-vue','@ant-design/icons-vue','@ant-design/colors'], - 'vxe-table-vendor': ['vxe-table','vxe-table-plugin-antd','xe-utils'], 'emoji-mart-vue-fast': ['emoji-mart-vue-fast'], - 'china-area-data-vendor': ['china-area-data'] }, }, }, @@ -134,19 +142,37 @@ export default ({ command, mode }: ConfigEnv): UserConfig => { }, // The vite plugin used by the project. The quantity is large, so it is separately extracted and managed - // 预加载构建配置(首屏性能) - plugins: createVitePlugins(viteEnv, isBuild, isQiankunMicro), + plugins: await createVitePlugins(viteEnv, isBuild, isQiankunMicro), + optimizeDeps: { esbuildOptions: { target: 'es2020', }, + // @iconify/iconify: The dependency is dynamically and virtually loaded by @purge-icons/generated, so it needs to be specified explicitly + include: [ + // 强制预构建clipboard,解决Vite6对CommonJS模块的严格检查 + 'clipboard', + '@vue/shared', + '@iconify/iconify', + 'ant-design-vue/es/locale/zh_CN', + 'ant-design-vue/es/locale/en_US', + // update-begin--author:scott---date:20260427---for: 集成 @jeecg/aiflow(预编译 lib 在 node_modules)时, + // Vite 默认不扫描 node_modules 里已打包的 mjs,导致 ant-design-vue/es/vc-picker/generate/dayjs.js + // 引入的 dayjs 插件子路径(UMD/CJS)未被预打包,运行时报 "does not provide an export named 'default'"。 + // 显式列出 vc-picker 用到的全部 dayjs 插件,强制 esbuild 预打包成 ESM。 + 'dayjs/plugin/advancedFormat', + 'dayjs/plugin/customParseFormat', + 'dayjs/plugin/weekday', + 'dayjs/plugin/localeData', + 'dayjs/plugin/weekOfYear', + 'dayjs/plugin/weekYear', + 'dayjs/plugin/quarterOfYear', + // update-end--author:scott---date:20260427---for: 集成 @jeecg/aiflow 时 dayjs 插件 default 导出报错 + ], exclude: [ - //升级vite4后,需要排除online依赖 - '@jeecg/online', + //升级vite4后,需要排除online和aiflow依赖 '@jeecg/aiflow', ], - // 强制预构建clipboard,解决Vite6对CommonJS模块的严格检查 - include: ['clipboard'] }, }; };