瀏覽代碼

项目升级

hongrunxia 1 年之前
父節點
當前提交
3bff589e4c
共有 100 個文件被更改,包括 1397 次插入2070 次删除
  1. 0 36
      .env.test
  2. 1 0
      .gitignore
  3. 14 0
      LICENSE
  4. 1 1
      build/script/buildConf.ts
  5. 0 21
      build/vite/optimizer.ts
  6. 4 0
      build/vite/plugin/compress.ts
  7. 0 25
      build/vite/plugin/hmr.ts
  8. 2 2
      build/vite/plugin/html.ts
  9. 1 0
      build/vite/plugin/imagemin.ts
  10. 19 22
      build/vite/plugin/index.ts
  11. 0 33
      build/vite/plugin/pwa.ts
  12. 1 0
      build/vite/plugin/styleImport.ts
  13. 0 16
      docs/切换到vue3前端路由.md
  14. 16 4
      index.html
  15. 1 1
      mock/demo/select-demo.ts
  16. 1 1
      mock/demo/tree-demo.ts
  17. 114 243
      package.json
  18. 665 1473
      pnpm-lock.yaml
  19. 二進制
      public/favicon.ico
  20. 二進制
      public/resource/img/pwa-192x192.png
  21. 二進制
      public/resource/img/pwa-512x512.png
  22. 6 0
      src/App.vue
  23. 1 0
      src/api/sys/model/userModel.ts
  24. 19 3
      src/api/sys/user.ts
  25. 0 0
      src/assets/icons/lock.svg
  26. 二進制
      src/assets/images/department.png
  27. 二進制
      src/assets/images/drag_cover.png
  28. 二進制
      src/assets/images/home-container/device/ccq.png
  29. 二進制
      src/assets/images/home-container/device/cf.png
  30. 二進制
      src/assets/images/home-container/device/fc.png
  31. 二進制
      src/assets/images/home-container/device/fm.png
  32. 二進制
      src/assets/images/home-container/device/js.png
  33. 二進制
      src/assets/images/home-container/device/penfen.png
  34. 二進制
      src/assets/images/home-container/device/penlin.png
  35. 二進制
      src/assets/images/home-container/device/pw.png
  36. 二進制
      src/assets/images/home-container/device/wasibeng.png
  37. 二進制
      src/assets/images/home-container/device/yafeng.png
  38. 二進制
      src/assets/images/home-container/device/zhudan.png
  39. 二進制
      src/assets/images/home-container/device/zhujiang.png
  40. 二進制
      src/assets/images/home-container/device/zhushan.png
  41. 二進制
      src/assets/images/home-container/dialog.png
  42. 二進制
      src/assets/images/home-container/dialog1.png
  43. 二進制
      src/assets/images/home-container/header-nav.png
  44. 二進制
      src/assets/images/home-container/home-bg.png
  45. 14 0
      src/assets/images/home-container/internet-bad.svg
  46. 二進制
      src/assets/images/home-container/item-value.png
  47. 二進制
      src/assets/images/home-container/line-val.png
  48. 二進制
      src/assets/images/home-container/pie.png
  49. 二進制
      src/assets/images/home-container/three-dialog.png
  50. 二進制
      src/assets/images/home-container/three-nav.png
  51. 二進制
      src/assets/images/home-container/tobig.png
  52. 7 0
      src/assets/images/home-container/toggle.svg
  53. 二進制
      src/assets/images/home-container/warn-icon.png
  54. 二進制
      src/assets/images/home-container/warn-icon1.png
  55. 二進制
      src/assets/images/home-container/warn-icon2.png
  56. 二進制
      src/assets/images/home-container/warn-icon3.png
  57. 二進制
      src/assets/images/home-container/warn1.png
  58. 二進制
      src/assets/images/home-container/warn7.png
  59. 二進制
      src/assets/images/home-container/warn8.png
  60. 二進制
      src/assets/images/home-container/wind-door.gif
  61. 二進制
      src/assets/images/home-container/wind-window.gif
  62. 二進制
      src/assets/images/home-container/work-bd.png
  63. 二進制
      src/assets/images/home-container/左下菜单按钮.png
  64. 二進制
      src/assets/images/home-container/背景图.png - 快捷方式.lnk
  65. 二進制
      src/assets/images/home-container/视频上方数据框.png
  66. 22 0
      src/assets/images/home-container/运行风机图标.svg
  67. 二進制
      src/assets/images/people.png
  68. 二進制
      src/assets/images/process_no_form.png
  69. 二進制
      src/assets/images/setting.png
  70. 二進制
      src/assets/images/template_cover.jpg
  71. 二進制
      src/assets/images/wallet.png
  72. 二進制
      src/assets/svg/fileType/image.png
  73. 2 1
      src/components/Application/src/AppLogo.vue
  74. 1 1
      src/components/CodeEditor/src/CodeEditor.vue
  75. 1 1
      src/components/CountDown/src/CountdownInput.vue
  76. 11 4
      src/components/Dropdown/src/Dropdown.vue
  77. 38 9
      src/components/Form/src/BasicForm.vue
  78. 9 1
      src/components/Form/src/componentMap.ts
  79. 42 3
      src/components/Form/src/components/ApiSelect.vue
  80. 6 1
      src/components/Form/src/components/FormAction.vue
  81. 42 9
      src/components/Form/src/components/FormItem.vue
  82. 23 18
      src/components/Form/src/hooks/useForm.ts
  83. 3 3
      src/components/Form/src/hooks/useFormEvents.ts
  84. 1 1
      src/components/Form/src/jeecg/components/JAreaLinkage.vue
  85. 4 3
      src/components/Form/src/jeecg/components/JCategorySelect.vue
  86. 28 12
      src/components/Form/src/jeecg/components/JCodeEditor.vue
  87. 35 20
      src/components/Form/src/jeecg/components/JDictSelectTag.vue
  88. 1 1
      src/components/Form/src/jeecg/components/JEllipsis.vue
  89. 8 6
      src/components/Form/src/jeecg/components/JImageUpload.vue
  90. 7 2
      src/components/Form/src/jeecg/components/JInput.vue
  91. 11 3
      src/components/Form/src/jeecg/components/JPopup.vue
  92. 54 56
      src/components/Form/src/jeecg/components/JRangeDate.vue
  93. 53 0
      src/components/Form/src/jeecg/components/JRangeTime.vue
  94. 12 2
      src/components/Form/src/jeecg/components/JSearchSelect.vue
  95. 14 2
      src/components/Form/src/jeecg/components/JSelectDept.vue
  96. 6 2
      src/components/Form/src/jeecg/components/JSelectPosition.vue
  97. 1 1
      src/components/Form/src/jeecg/components/JTreeDict.vue
  98. 23 11
      src/components/Form/src/jeecg/components/JTreeSelect.vue
  99. 44 13
      src/components/Form/src/jeecg/components/JUpload/JUpload.vue
  100. 8 3
      src/components/Form/src/jeecg/components/modal/DeptSelectModal.vue

+ 0 - 36
.env.test

@@ -1,36 +0,0 @@
-# 是否启用mock
-VITE_USE_MOCK = true
-
-# 发布路径
-VITE_PUBLIC_PATH = /
-
-# 控制台不输出
-VITE_DROP_CONSOLE = true
-
-# 是否启用gzip或brotli压缩
-# 选项值: gzip | brotli | none
-# 如果需要多个可以使用“,”分隔
-VITE_BUILD_COMPRESS = 'gzip'
-
-# 使用压缩时是否删除原始文件,默认为false
-VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
-
-#后台接口父地址(必填)
-VITE_GLOB_API_URL=/jeecgboot
-
-#后台接口全路径地址(必填)
-VITE_GLOB_DOMAIN_URL=http://localhost:8080/jeecg-boot
-
-# 接口父路径前缀
-VITE_GLOB_API_URL_PREFIX=
-
-# 是否启用图像压缩
-VITE_USE_IMAGEMIN= true
-
-# 使用pwa
-VITE_USE_PWA = false
-
-# 是否兼容旧浏览器
-VITE_LEGACY = false
-
-VITE_GLOB_IS_SIMULATE=true

+ 1 - 0
.gitignore

@@ -29,6 +29,7 @@ pnpm-debug.log*
 *.sln
 *.sw?
 /os_del.cmd
+os_del.cmd
 /.vscode/
 /.history/
 /svn clear.bat

+ 14 - 0
LICENSE

@@ -19,3 +19,17 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
+
+
+
+  开源协议补充
+    JeecgBoot 是由 北京国炬信息技术有限公司 发行的软件。 总部位于北京,地址:中国·北京·朝阳区科荟前街1号院奥林佳泰大厦。邮箱:jeecgos@163.com
+    本软件受适用的国家软件著作权法(包括国际条约)和双重保护许可。
+  
+   1.允许基于本平台软件开展业务系统开发。
+   2.JeecgBoot底层依赖的非开源功能:online lib依赖、仪表盘lib依赖等,统一采用LGPL开源协议(不二次改造、不拆分出jeecgboot之外使用,就不产生侵权)
+   3.不得基于该平台软件的基础,修改包装成一个与JeecgBoot平台软件功能类似的产品进行发布、销售,或与JeecgBoot参与同类软件产品市场的竞争。
+	 违反此条款属于侵权行为,须赔偿侵权经济损失,同时立即停止著作权侵权行为。
+	 
+   总结:在遵循Apache开源协议和开源协议补充条款下,允许商用使用,不会造成侵权行为!
+	 解释权归:http://www.jeecg.com

+ 1 - 1
build/script/buildConf.ts

@@ -1,5 +1,5 @@
 /**
- * Generate additional configuration files when used for packaging. The file can be configured with some global variables, so that it can be changed directly externally without repackaging
+ * 生成外部配置文件,用于生产发布后配置,无需重新打包
  */
 import { GLOB_CONFIG_FILE_NAME, OUTPUT_DIR } from '../constant';
 import fs, { writeFileSync } from 'fs-extra';

+ 0 - 21
build/vite/optimizer.ts

@@ -1,21 +0,0 @@
-// TODO
-import type { GetManualChunk } from 'rollup';
-
-//
-const vendorLibs: { match: string[]; output: string }[] = [
-  // {
-  //   match: ['xlsx'],
-  //   output: 'xlsx',
-  // },
-];
-
-// @ts-ignore
-export const configManualChunk: GetManualChunk = (id: string) => {
-  if (/[\\/]node_modules[\\/]/.test(id)) {
-    const matchItem = vendorLibs.find((item) => {
-      const reg = new RegExp(`[\\/]node_modules[\\/]_?(${item.match.join('|')})(.*)`, 'ig');
-      return reg.test(id);
-    });
-    return matchItem ? matchItem.output : null;
-  }
-};

+ 4 - 0
build/vite/plugin/compress.ts

@@ -13,6 +13,10 @@ export function configCompressPlugin(compress: 'gzip' | 'brotli' | 'none', delet
   if (compressList.includes('gzip')) {
     plugins.push(
       compressPlugin({
+        verbose: true,
+        disable: false,
+        threshold: 10240,
+        algorithm: 'gzip',
         ext: '.gz',
         deleteOriginFile,
       })

+ 0 - 25
build/vite/plugin/hmr.ts

@@ -1,25 +0,0 @@
-import type { Plugin } from 'vite';
-
-/**
- * TODO
- * Temporarily solve the Vite circular dependency problem, and wait for a better solution to fix it later. I don't know what problems this writing will bring.
- * @returns
- */
-
-export function configHmrPlugin(): Plugin {
-  return {
-    name: 'singleHMR',
-    handleHotUpdate({ modules, file }) {
-      if (file.match(/xml$/)) return [];
-
-      modules.forEach((m) => {
-        if (!m.url.match(/\.(css|less)/)) {
-          m.importedModules = new Set();
-          m.importers = new Set();
-        }
-      });
-
-      return modules;
-    },
-  };
-}

+ 2 - 2
build/vite/plugin/html.ts

@@ -19,11 +19,11 @@ export function configHtmlPlugin(env: ViteEnv, isBuild: boolean) {
   const htmlPlugin: PluginOption[] = createHtmlPlugin({
     minify: isBuild,
     inject: {
-      // Inject data into ejs template
+      // 修改模板html的标题
       data: {
         title: VITE_GLOB_APP_TITLE,
       },
-      // Embed the generated app.config.js file
+      // 将app.config.js文件注入到模板html中
       tags: isBuild
         ? [
             {

+ 1 - 0
build/vite/plugin/imagemin.ts

@@ -1,3 +1,4 @@
+// 【图片压缩插件】
 // Image resource files used to compress the output of the production environment
 // https://github.com/anncwb/vite-plugin-imagemin
 import viteImagemin from 'vite-plugin-imagemin';

+ 19 - 22
build/vite/plugin/index.ts

@@ -1,27 +1,28 @@
 import { PluginOption } from 'vite';
 import vue from '@vitejs/plugin-vue';
 import vueJsx from '@vitejs/plugin-vue-jsx';
-import legacy from '@vitejs/plugin-legacy';
 import purgeIcons from 'vite-plugin-purge-icons';
-import windiCSS from 'vite-plugin-windicss';
+import UnoCSS from 'unocss/vite';
+import { presetTypography, presetUno } from 'unocss';
+
 import VitePluginCertificate from 'vite-plugin-mkcert';
-import vueSetupExtend from 'vite-plugin-vue-setup-extend';
+//[issues/555]开发环境,vscode断点调试,文件或行数对不上
+import vueSetupExtend from 'vite-plugin-vue-setup-extend-plus';
 import { configHtmlPlugin } from './html';
-import { configPwaConfig } from './pwa';
 import { configMockPlugin } from './mock';
 import { configCompressPlugin } from './compress';
 import { configStyleImportPlugin } from './styleImport';
 import { configVisualizerConfig } from './visualizer';
 import { configThemePlugin } from './theme';
-import { configImageminPlugin } from './imagemin';
 import { configSvgIconsPlugin } from './svgSprite';
-import OptimizationPersist from 'vite-plugin-optimize-persist';
-import PkgConfig from 'vite-plugin-package-config';
+// //预编译加载插件(不支持vite3作废)
+// import OptimizationPersist from 'vite-plugin-optimize-persist';
 import { resolve } from 'path';
 import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
+import topLevelAwait from 'vite-plugin-top-level-await';
 
 export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
-  const { VITE_USE_IMAGEMIN, VITE_USE_MOCK, VITE_LEGACY, VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE } = viteEnv;
+  const { VITE_USE_MOCK, VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE } = viteEnv;
 
   const vitePlugins: (PluginOption | PluginOption[])[] = [
     // have to
@@ -43,13 +44,15 @@ export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
       svgoOptions: false,
       customDomId: '__webtopo__svgpreview__icons__dom__',
     }),
+    topLevelAwait({
+      // The export name of top-level await promise for each chunk module
+      promiseExportName: '__tla',
+      // The function to generate import names of top-level await promise in each chunk module
+      promiseImportName: i => `__tla_${i}`
+    })
   ];
 
-  // vite-plugin-windicss
-  vitePlugins.push(windiCSS());
-
-  // @vitejs/plugin-legacy
-  VITE_LEGACY && isBuild && vitePlugins.push(legacy());
+  vitePlugins.push(UnoCSS({ presets: [presetUno(), presetTypography()] }));
 
   // vite-plugin-html
   vitePlugins.push(configHtmlPlugin(viteEnv, isBuild));
@@ -74,18 +77,12 @@ export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
 
   // The following plugins only work in the production environment
   if (isBuild) {
-    // vite-plugin-imagemin
-    VITE_USE_IMAGEMIN && vitePlugins.push(configImageminPlugin());
-
     // rollup-plugin-gzip
     vitePlugins.push(configCompressPlugin(VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE));
-
-    // vite-plugin-pwa
-    vitePlugins.push(configPwaConfig(viteEnv));
   }
 
-  //vite-plugin-theme【解决vite首次打开界面加载慢问题】
-  vitePlugins.push(PkgConfig());
-  vitePlugins.push(OptimizationPersist());
+  // //vite-plugin-theme【预编译加载插件,解决vite首次打开界面加载慢问题】
+  // vitePlugins.push(PkgConfig());
+  // vitePlugins.push(OptimizationPersist());
   return vitePlugins;
 }

+ 0 - 33
build/vite/plugin/pwa.ts

@@ -1,33 +0,0 @@
-/**
- * Zero-config PWA for Vite
- * https://github.com/antfu/vite-plugin-pwa
- */
-import { VitePWA } from 'vite-plugin-pwa';
-
-export function configPwaConfig(env: ViteEnv) {
-  const { VITE_USE_PWA, VITE_GLOB_APP_TITLE, VITE_GLOB_APP_SHORT_NAME } = env;
-
-  if (VITE_USE_PWA) {
-    // vite-plugin-pwa
-    const pwaPlugin = VitePWA({
-      manifest: {
-        name: VITE_GLOB_APP_TITLE,
-        short_name: VITE_GLOB_APP_SHORT_NAME,
-        icons: [
-          {
-            src: './resource/img/pwa-192x192.png',
-            sizes: '192x192',
-            type: 'image/png',
-          },
-          {
-            src: './resource/img/pwa-512x512.png',
-            sizes: '512x512',
-            type: 'image/png',
-          },
-        ],
-      },
-    });
-    return pwaPlugin;
-  }
-  return [];
-}

+ 1 - 0
build/vite/plugin/styleImport.ts

@@ -1,4 +1,5 @@
 /**
+ * 【样式按需加载插件 ——主要处理antd的样式】
  *  Introduces component library styles on demand.
  * https://github.com/anncwb/vite-plugin-style-import
  */

+ 0 - 16
docs/切换到vue3前端路由.md

@@ -1,16 +0,0 @@
-## 切换到 Vue3菜单路由
-
-- 第一步:执行SQL脚本
-```
-alter table sys_permission rename as sys_permission_v2;
-alter table sys_permission_v3 rename as sys_permission;
-```
-
-> 这个 sql 脚本做了什么?
-> - 1、把表名 sys_permission 备份改为 sys_permission_v2
-> - 2、把 sys_permission_v3 改为 sys_permission
-> 说明:因为 vue3 和 vue2 的菜单配置不一样,所以通过切换表来实现 vue3 和 vue2 的切换。
-
-- 第二步:登录进系统
-
-> 从 jeecgboot3.3.0 版本默认 vue3 和 vue2 的权限都已经分配好, 不需要再手工授权。

+ 16 - 4
index.html

@@ -16,7 +16,7 @@
     <script src="/js/adapter.min.js"></script>
     <script type="text/javascript" src="http://182.92.126.35:9050/web-apps/apps/api/documents/api.js"></script>
   </head>
-  <body style="background-color: #09172C">
+  <body>
     <script>
       (() => {
         var htmlRoot = document.getElementById('htmlRoot');
@@ -27,8 +27,9 @@
         }
       })();
     </script>
+    
     <div id="app">
-      <style>
+      <style lang="less">
         html[data-theme='dark'] .app-loading {
           background-color: #2c344a;
         }
@@ -36,6 +37,9 @@
         html[data-theme='dark'] .app-loading .app-loading-title {
           color: rgba(255, 255, 255, 0.85);
         }
+        body{
+          background-color: var(--vent-base-color)
+        }
         .app-loading {
           display: flex;
           width: 100%;
@@ -47,7 +51,7 @@
           background-image: url('./src/assets/images/vent/loading-bg.png');
           background-size: cover;
           background-repeat: no-repeat;
-          background-color: #09172C;
+          background-color: var(--vent-base-color);
         }
 
         .app-loading .app-loading-wrap {
@@ -319,6 +323,14 @@
     </div>
     
     <script type="module" src="/src/main.ts"></script>
-    <!-- <script type="module" src="/src/utils/threejs/main.worker.ts"></script> -->
+    <script>
+      var _hmt = _hmt || [];
+      (function() {
+        var hm = document.createElement("script");
+        hm.src = "https://hm.baidu.com/hm.js?0febd9e3cacb3f627ddac64d52caac39";
+        var s = document.getElementsByTagName("script")[0];
+        s.parentNode.insertBefore(hm, s);
+      })();
+    </script>
   </body>
 </html>

+ 1 - 1
mock/demo/select-demo.ts

@@ -21,7 +21,7 @@ export default [
     method: 'get',
     response: ({ query }) => {
       const { keyword,count} = query;
-      console.log(keyword);
+      console.log("查询条件:", keyword);
       return resultSuccess(demoList(keyword,count));
     },
   },

+ 1 - 1
mock/demo/tree-demo.ts

@@ -31,7 +31,7 @@ export default [
     method: 'get',
     response: ({ query }) => {
       const { keyword } = query;
-      console.log(keyword);
+      console.log("查询条件:", keyword);
       return resultSuccess(demoTreeList(keyword));
     },
   },

+ 114 - 243
package.json

@@ -1,68 +1,56 @@
 {
   "name": "jeecgboot-vue3",
-  "version": "3.4.4",
+  "version": "3.6.0",
   "author": {
     "name": "jeecg",
     "email": "jeecgos@163.com",
     "url": "https://github.com/jeecgboot/jeecgboot-vue3"
   },
   "scripts": {
-    "bootstrap": "pnpm install",
-    "serve": "npm run dev",
-    "dev": "vite",
+    "pinstall": "pnpm install",
     "clean:cache": "rimraf node_modules/.cache/ && rimraf node_modules/.vite",
-    "clean:lib": "rimraf node_modules",
+    "dev": "vite",
     "build": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=8192 vite build && esno ./build/script/postBuild.ts",
-    "build:test": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build --mode test && esno ./build/script/postBuild.ts",
-    "build:no-cache": "pnpm clean:cache && npm run build",
-    "report": "cross-env REPORT=true npm run build",
-    "type:check": "vue-tsc --noEmit --skipLibCheck",
+    "build:report": "pnpm clean:cache && cross-env REPORT=true npm run build",
     "preview": "npm run build && vite preview",
-    "preview:dist": "vite preview",
-    "log": "conventional-changelog -p angular -i CHANGELOG.md -s",
-    "lint:eslint": "eslint --cache --max-warnings 0  \"{src,mock}/**/*.{vue,ts,tsx}\" --fix",
-    "lint:prettier": "prettier --write  \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"",
-    "lint:stylelint": "stylelint --cache --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/",
-    "lint:lint-staged": "lint-staged -c ./.husky/lintstagedrc.js",
-    "lint:pretty": "pretty-quick --staged",
-    "test:unit": "jest",
-    "test:unit-coverage": "jest --coverage",
-    "test:gzip": "http-server dist --cors --gzip -c-1",
-    "test:br": "http-server dist --cors --brotli -c-1",
-    "reinstall": "rimraf pnpm-lock.yaml && yarn.lock && rimraf package.lock.json && rimraf node_modules && npm run bootstrap",
-    "prepare": "husky install",
-    "gen:icon": "esno ./build/generate/icon/index.ts"
+    "reinstall": "rimraf pnpm-lock.yaml && rimraf yarn.lock && rimraf package.lock.json && rimraf node_modules && npm run install",
+    "clean:lib": "rimraf node_modules",
+    "gen:icon": "esno ./build/generate/icon/index.ts",
+    "batch:prettier": "prettier --write  \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"",
+    "upgrade:log": "conventional-changelog -p angular -i CHANGELOG.md -s",
+    "husky:install": "husky install"
   },
   "dependencies": {
-    "@ant-design/colors": "^6.0.0",
+    "@ant-design/colors": "^7.0.0",
     "@ant-design/icons-vue": "^6.1.0",
-    "@iconify/iconify": "^2.2.1",
-    "@jeecg/online": "3.4.4-RC",
+    "@iconify/iconify": "^3.1.1",
+    "@jeecg/online": "3.5.3-vite4",
     "@kjgl77/datav-vue3": "^1.4.2",
     "@liveqing/liveplayer-v3": "^3.1.9",
-    "@logicflow/core": "^1.1.13",
-    "@logicflow/extension": "^1.1.13",
-    "@vue/runtime-core": "^3.2.33",
-    "@vue/shared": "^3.2.33",
-    "@vueuse/core": "^8.3.0",
-    "@vueuse/shared": "^8.3.0",
-    "@zxcvbn-ts/core": "^2.0.1",
-    "ant-design-vue": "^3.2.19",
-    "axios": "^0.26.1",
+    "@logicflow/core": "^1.2.12",
+    "@logicflow/extension": "^1.2.13",
+    "@qiaoqiaoyun/drag-free": "^1.1.4",
+    "@vue/runtime-core": "^3.3.4",
+    "@vue/shared": "^3.3.4",
+    "@vueuse/core": "^10.4.1",
+    "@vueuse/shared": "^10.4.1",
+    "@zxcvbn-ts/core": "^3.0.3",
+    "ant-design-vue": "^3.2.20",
+    "axios": "^1.5.0",
     "china-area-data": "^5.0.1",
-    "clipboard": "^2.0.8",
+    "clipboard": "^2.0.11",
     "codemirror": "^5.65.3",
-    "cron-parser": "^3.5.0",
-    "cropperjs": "^1.5.12",
+    "cron-parser": "^4.9.0",
+    "cropperjs": "^1.5.13",
     "crypto-js": "^4.1.1",
-    "dayjs": "^1.11.1",
+    "dayjs": "^1.11.9",
     "dexie": "^3.2.2",
-    "dom-align": "^1.12.2",
-    "echarts": "^5.3.2",
-    "emoji-mart-vue-fast": "^11.1.1",
+    "dom-align": "^1.12.4",
+    "echarts": "^5.4.3",
+    "emoji-mart-vue-fast": "^15.0.0",
     "enquire.js": "^2.1.6",
     "gsap": "^3.11.3",
-    "intro.js": "^5.1.0",
+    "intro.js": "^7.2.0",
     "lodash-es": "^4.17.21",
     "lodash.get": "^4.4.2",
     "md5": "^2.3.0",
@@ -70,127 +58,118 @@
     "mockjs": "^1.1.0",
     "moment": "^2.29.4",
     "nprogress": "^0.2.0",
-    "path-to-regexp": "^6.2.0",
-    "pinia": "2.0.12",
+    "path-to-regexp": "^6.2.1",
+    "pinia": "2.1.6",
     "plyr": "^3.7.8",
     "print-js": "^1.6.0",
     "qiankun": "^2.8.4",
-    "qrcode": "^1.5.0",
+    "qrcode": "^1.5.3",
     "qrcodejs2": "0.0.2",
-    "qs": "^6.10.3",
+    "qs": "^6.11.2",
     "resize-observer-polyfill": "^1.5.1",
     "showdown": "^2.1.0",
     "sortablejs": "^1.15.0",
     "three": "^0.155.0",
     "tinymce": "^5.10.3",
-    "vditor": "^3.8.13",
-    "vite-plugin-theme": "^0.8.6",
-    "vue": "^3.2.33",
-    "vue-cropper": "^0.5.6",
+    "vditor": "^3.9.5",
+    "vue": "^3.3.4",
+    "vue-cropper": "^0.6.2",
     "vue-cropperjs": "^5.0.0",
-    "vue-i18n": "^9.1.9",
+    "vue-i18n": "9.2.2",
     "vue-infinite-scroll": "^2.0.2",
-    "vue-json-pretty": "^2.0.6",
-    "vue-print-nb-jeecg": "^1.0.10",
-    "vue-router": "^4.0.14",
-    "vue-tree-list": "^1.5.0",
-    "vue-types": "^4.1.1",
+    "vue-json-pretty": "^2.2.4",
+    "vue-print-nb-jeecg": "^1.0.12",
+    "vue-router": "^4.2.4",
+    "vue-types": "^5.1.1",
     "vuedraggable": "^4.1.0",
-    "vxe-table": "4.1.0",
-    "vxe-table-plugin-antd": "3.0.5",
-    "xe-utils": "^3.3.1",
-    "xss": "^1.0.13"
+    "vxe-table": "4.5.12",
+    "vxe-table-plugin-antd": "3.1.0",
+    "xe-utils": "3.5.13",
+    "xss": "^1.0.14"
   },
   "devDependencies": {
-    "@commitlint/cli": "^16.2.3",
-    "@commitlint/config-conventional": "^16.2.1",
-    "@iconify/json": "^2.1.30",
-    "@purge-icons/generated": "^0.8.1",
+    "@commitlint/cli": "^17.7.1",
+    "@commitlint/config-conventional": "^17.7.0",
+    "@iconify/json": "^2.2.107",
+    "@purge-icons/generated": "^0.9.0",
     "@rys-fe/vite-plugin-theme": "^0.8.6",
-    "@types/codemirror": "^5.60.5",
+    "@types/codemirror": "^5.60.9",
     "@types/crypto-js": "^4.1.1",
-    "@types/fs-extra": "^9.0.13",
-    "@types/inquirer": "^8.2.1",
-    "@types/intro.js": "^3.0.2",
-    "@types/jest": "^27.0.2",
-    "@types/lodash-es": "^4.17.6",
-    "@types/mockjs": "^1.0.6",
-    "@types/node": "^17.0.25",
+    "@types/fs-extra": "^11.0.1",
+    "@types/inquirer": "^9.0.3",
+    "@types/intro.js": "^5.1.1",
+    "@types/jest": "^29.5.4",
+    "@types/lodash-es": "^4.17.8",
+    "@types/mockjs": "^1.0.7",
+    "@types/node": "^20.5.6",
     "@types/nprogress": "^0.2.0",
-    "@types/qrcode": "^1.4.2",
+    "@types/qrcode": "^1.5.1",
     "@types/qs": "^6.9.7",
-    "@types/showdown": "^1.9.4",
-    "@types/sortablejs": "^1.10.7",
+    "@types/showdown": "^2.0.1",
+    "@types/sortablejs": "^1.15.1",
     "@types/three": "^0.155.0",
-    "@typescript-eslint/eslint-plugin": "^5.20.0",
-    "@typescript-eslint/parser": "^5.20.0",
+    "@typescript-eslint/eslint-plugin": "^6.4.1",
+    "@typescript-eslint/parser": "^6.5.0",
     "@vitejs/plugin-legacy": "^2.0.0",
-    "@vitejs/plugin-vue": "^3.0.1",
-    "@vitejs/plugin-vue-jsx": "^1.3.10",
-    "@vue/compiler-sfc": "^3.2.33",
-    "@vue/test-utils": "^2.0.0-rc.21",
-    "autoprefixer": "^10.4.4",
-    "commitizen": "^4.2.4",
-    "conventional-changelog-cli": "^2.2.2",
+    "@vitejs/plugin-vue": "^4.3.3",
+    "@vitejs/plugin-vue-jsx": "^3.0.2",
+    "@vue/compiler-sfc": "^3.3.4",
+    "@vue/test-utils": "^2.4.1",
+    "autoprefixer": "^10.4.15",
+    "commitizen": "^4.3.0",
+    "conventional-changelog-cli": "^3.0.0",
     "cross-env": "^7.0.3",
-    "cz-git": "^1.3.9",
-    "czg": "^1.3.9",
+    "cz-git": "^1.7.1",
+    "czg": "^1.7.1",
     "dat.gui": "^0.7.9",
-    "dotenv": "^16.0.0",
-    "eslint": "^8.13.0",
-    "eslint-config-prettier": "^8.5.0",
-    "eslint-define-config": "^1.1.1",
-    "eslint-plugin-jest": "^25.2.2",
-    "eslint-plugin-prettier": "^4.0.0",
-    "eslint-plugin-vue": "^8.6.0",
-    "esno": "^0.14.1",
-    "fs-extra": "^10.1.0",
-    "http-server": "^14.0.0",
-    "husky": "^7.0.4",
-    "inquirer": "^8.2.2",
-    "is-ci": "^3.0.0",
-    "jest": "^27.3.1",
-    "less": "^4.1.2",
-    "lint-staged": "12.3.7",
+    "dotenv": "^16.3.1",
+    "eslint": "^8.47.0",
+    "eslint-config-prettier": "^9.0.0",
+    "eslint-define-config": "^1.23.0",
+    "eslint-plugin-jest": "^27.2.3",
+    "eslint-plugin-prettier": "^5.0.0",
+    "eslint-plugin-vue": "^9.17.0",
+    "esno": "^0.17.0",
+    "fs-extra": "^11.1.1",
+    "http-server": "^14.1.1",
+    "husky": "^8.0.3",
+    "inquirer": "^9.2.10",
+    "is-ci": "^3.0.1",
+    "jest": "^29.6.4",
+    "less": "^4.2.0",
+    "lint-staged": "14.0.1",
     "npm-run-all": "^4.1.5",
     "picocolors": "^1.0.0",
-    "postcss": "^8.4.12",
-    "postcss-html": "^1.4.1",
+    "postcss": "^8.4.28",
+    "postcss-html": "^1.5.0",
     "postcss-less": "^6.0.0",
-    "prettier": "^2.6.2",
-    "pretty-quick": "^3.1.1",
-    "rimraf": "^3.0.2",
-    "rollup": "^2.70.2",
-    "rollup-plugin-visualizer": "^5.6.0",
-    "stylelint": "^14.7.1",
-    "stylelint-config-prettier": "^9.0.3",
-    "stylelint-config-recommended": "^7.0.0",
-    "stylelint-config-recommended-vue": "^1.4.0",
-    "stylelint-config-standard": "^25.0.0",
-    "stylelint-order": "^5.0.0",
-    "ts-jest": "^27.0.7",
-    "ts-node": "^10.7.0",
-    "typescript": "^4.6.3",
-    "vite": "^3.0.2",
+    "prettier": "^3.0.2",
+    "pretty-quick": "^3.1.3",
+    "rimraf": "^5.0.1",
+    "rollup": "^3.28.1",
+    "rollup-plugin-visualizer": "^5.9.2",
+    "stylelint": "^15.10.3",
+    "stylelint-config-prettier": "^9.0.5",
+    "stylelint-config-recommended": "^13.0.0",
+    "stylelint-config-recommended-vue": "^1.5.0",
+    "stylelint-config-standard": "^34.0.0",
+    "stylelint-order": "^6.0.3",
+    "ts-jest": "^29.1.1",
+    "ts-node": "^10.9.1",
+    "typescript": "^4.9.5",
+    "unocss": "^0.55.3",
+    "vite": "^4.4.9",
     "vite-plugin-compression": "^0.5.1",
     "vite-plugin-html": "^3.2.0",
-    "vite-plugin-imagemin": "^0.6.1",
-    "vite-plugin-mkcert": "^1.10.1",
+    "vite-plugin-mkcert": "^1.16.0",
     "vite-plugin-mock": "^2.9.6",
-    "vite-plugin-optimize-persist": "^0.1.2",
-    "vite-plugin-package-config": "^0.1.1",
-    "vite-plugin-purge-icons": "^0.8.2",
-    "vite-plugin-pwa": "^0.12.3",
+    "vite-plugin-purge-icons": "^0.9.2",
     "vite-plugin-style-import": "^2.0.0",
     "vite-plugin-svg-icons": "^2.0.1",
-    "vite-plugin-vue-setup-extend": "^0.4.0",
-    "vite-plugin-windicss": "^1.8.7",
-    "vue-eslint-parser": "^8.3.0",
-    "vue-tsc": "^0.33.9"
-  },
-  "resolutions": {
-    "bin-wrapper": "npm:bin-wrapper-china",
-    "rollup": "^2.72.0"
+    "vite-plugin-top-level-await": "^1.3.1",
+    "vite-plugin-vue-setup-extend-plus": "^0.1.0",
+    "vue-eslint-parser": "^9.3.1",
+    "vue-tsc": "^1.8.8"
   },
   "repository": {
     "type": "git",
@@ -207,119 +186,11 @@
   "vite": {
     "optimizeDeps": {
       "include": [
-        "@ant-design/colors",
-        "@liveqing/liveplayer-v3",
-        "@ant-design/icons-vue",
-        "@jeecg/online",
-        "@vueuse/core",
-        "@vueuse/shared",
-        "@zxcvbn-ts/core",
-        "ant-design-vue",
-        "axios",
-        "china-area-data",
-        "clipboard",
-        "codemirror",
-        "codemirror/addon/fold/brace-fold.js",
-        "codemirror/addon/fold/comment-fold.js",
-        "codemirror/addon/fold/foldcode.js",
-        "codemirror/addon/fold/foldgutter.js",
-        "codemirror/addon/fold/indent-fold.js",
-        "codemirror/addon/hint/anyword-hint.js",
-        "codemirror/addon/hint/show-hint.js",
-        "codemirror/addon/selection/active-line.js",
-        "codemirror/mode/clike/clike.js",
-        "codemirror/mode/css/css.js",
-        "codemirror/mode/javascript/javascript.js",
-        "codemirror/mode/markdown/markdown.js",
-        "codemirror/mode/python/python.js",
-        "codemirror/mode/r/r.js",
-        "codemirror/mode/shell/shell.js",
-        "codemirror/mode/sql/sql.js",
-        "codemirror/mode/swift/swift.js",
-        "codemirror/mode/vue/vue.js",
-        "codemirror/mode/xml/xml.js",
-        "cron-parser",
-        "cropperjs",
-        "crypto-js/aes",
-        "crypto-js/enc-base64",
-        "crypto-js/enc-utf8",
-        "crypto-js/md5",
-        "crypto-js/mode-ecb",
-        "crypto-js/pad-pkcs7",
-        "dom-align",
-        "echarts",
-        "lodash-es",
-        "echarts/charts",
-        "echarts/components",
-        "echarts/core",
-        "echarts/renderers",
-        "gsap",
-        "intro.js",
-        "lodash-es",
-        "md5",
-        "moment",
-        "nprogress",
-        "path-to-regexp",
-        "pinia",
-        "print-js",
-        "qrcode",
-        "qs",
-        "resize-observer-polyfill",
-        "showdown",
-        "sortablejs",
-        "three",
         "three/examples/jsm/postprocessing/EffectComposer.js",
         "three/examples/jsm/postprocessing/OutputPass.js",
         "three/examples/jsm/postprocessing/RenderPass.js",
         "three/examples/jsm/postprocessing/ShaderPass.js",
-        "three/examples/jsm/postprocessing/UnrealBloomPass.js",
-        "tinymce/icons/default/icons",
-        "tinymce/plugins/advlist",
-        "tinymce/plugins/anchor",
-        "tinymce/plugins/autolink",
-        "tinymce/plugins/autosave",
-        "tinymce/plugins/code",
-        "tinymce/plugins/codesample",
-        "tinymce/plugins/contextmenu",
-        "tinymce/plugins/directionality",
-        "tinymce/plugins/fullscreen",
-        "tinymce/plugins/hr",
-        "tinymce/plugins/image",
-        "tinymce/plugins/insertdatetime",
-        "tinymce/plugins/link",
-        "tinymce/plugins/lists",
-        "tinymce/plugins/media",
-        "tinymce/plugins/nonbreaking",
-        "tinymce/plugins/noneditable",
-        "tinymce/plugins/pagebreak",
-        "tinymce/plugins/paste",
-        "tinymce/plugins/preview",
-        "tinymce/plugins/print",
-        "tinymce/plugins/save",
-        "tinymce/plugins/searchreplace",
-        "tinymce/plugins/spellchecker",
-        "tinymce/plugins/tabfocus",
-        "tinymce/plugins/table",
-        "tinymce/plugins/template",
-        "tinymce/plugins/textcolor",
-        "tinymce/plugins/textpattern",
-        "tinymce/plugins/visualblocks",
-        "tinymce/plugins/visualchars",
-        "tinymce/plugins/wordcount",
-        "tinymce/themes/silver",
-        "tinymce/tinymce",
-        "vditor",
-        "vite-plugin-theme/es/client",
-        "vite-plugin-theme/es/colorUtils",
-        "vue",
-        "vue-i18n",
-        "vue-print-nb-jeecg/src/printarea",
-        "vue-router",
-        "vue-types",
-        "vxe-table",
-        "vxe-table-plugin-antd",
-        "xe-utils",
-        "xss"
+        "three/examples/jsm/postprocessing/UnrealBloomPass.js"
       ]
     }
   }

文件差異過大導致無法顯示
+ 665 - 1473
pnpm-lock.yaml


二進制
public/favicon.ico


二進制
public/resource/img/pwa-192x192.png


二進制
public/resource/img/pwa-512x512.png


+ 6 - 0
src/App.vue

@@ -50,6 +50,12 @@
     gl && gl.getExtension('WEBGL_lose_context').loseContext()
   })
 </script>
+
+<style lang="less">
+// update-begin--author:liaozhiyang---date:20230803---for:【QQYUN-5839】windi会影响到html2canvas绘制的图片样式
+img{display:inline-block;}
+// update-end--author:liaozhiyang---date:20230803---for:【QQYUN-5839】windi会影响到html2canvas绘制的图片样式
+</style>
 <style lang="less" scoped>
   #app {
     overflow: hidden;

+ 1 - 0
src/api/sys/model/userModel.ts

@@ -23,6 +23,7 @@ export interface LoginResultModel {
   userId: string | number;
   token: string;
   role: RoleInfo;
+  userInfo?: any
 }
 
 /**

+ 19 - 3
src/api/sys/user.ts

@@ -78,14 +78,24 @@ export function phoneLoginApi(params: LoginParams, mode: ErrorMessageMode = 'mod
  * @description: getUserInfo
  */
 export function getUserInfo() {
-  return defHttp.get<GetUserInfoModel>({ url: Api.GetUserInfo }, { errorMessageMode: 'none' }).catch((e) => {
+  return defHttp.get<GetUserInfoModel>({ url: Api.GetUserInfo }, {}).catch((e) => {
     // update-begin--author:zyf---date:20220425---for:【VUEN-76】捕获接口超时异常,跳转到登录界面
     if (e && (e.message.includes('timeout') || e.message.includes('401'))) {
       //接口不通时跳转到登录界面
       const userStore = useUserStoreWithOut();
       userStore.setToken('');
       setAuthCache(TOKEN_KEY, null);
-      router.push(PageEnum.BASE_LOGIN);
+
+      // update-begin-author:sunjianlei date:20230306 for: 修复登录成功后,没有正确重定向的问题
+      router.push({
+        path: PageEnum.BASE_LOGIN,
+        query: {
+          // 传入当前的路由,登录成功后跳转到当前路由
+          redirect: router.currentRoute.value.fullPath,
+        }
+      });
+      // update-end-author:sunjianlei date:20230306 for: 修复登录成功后,没有正确重定向的问题
+
     }
     // update-end--author:zyf---date:20220425---for:【VUEN-76】捕获接口超时异常,跳转到登录界面
   });
@@ -146,9 +156,15 @@ export const passwordChange = (params) => defHttp.get({ url: Api.passwordChange,
  * @description: 第三方登录
  */
 export function thirdLogin(params, mode: ErrorMessageMode = 'modal') {
+  //==========begin 第三方登录/auth2登录需要传递租户id===========
+  let tenantId = "0";
+  if(!params.tenantId){
+    tenantId = params.tenantId;
+  }
+  //==========end 第三方登录/auth2登录需要传递租户id===========
   return defHttp.get<LoginResultModel>(
     {
-      url: `${Api.thirdLogin}/${params.token}/${params.thirdType}`,
+      url: `${Api.thirdLogin}/${params.token}/${params.thirdType}/${tenantId}`,
     },
     {
       errorMessageMode: mode,

文件差異過大導致無法顯示
+ 0 - 0
src/assets/icons/lock.svg


二進制
src/assets/images/department.png


二進制
src/assets/images/drag_cover.png


二進制
src/assets/images/home-container/device/ccq.png


二進制
src/assets/images/home-container/device/cf.png


二進制
src/assets/images/home-container/device/fc.png


二進制
src/assets/images/home-container/device/fm.png


二進制
src/assets/images/home-container/device/js.png


二進制
src/assets/images/home-container/device/penfen.png


二進制
src/assets/images/home-container/device/penlin.png


二進制
src/assets/images/home-container/device/pw.png


二進制
src/assets/images/home-container/device/wasibeng.png


二進制
src/assets/images/home-container/device/yafeng.png


二進制
src/assets/images/home-container/device/zhudan.png


二進制
src/assets/images/home-container/device/zhujiang.png


二進制
src/assets/images/home-container/device/zhushan.png


二進制
src/assets/images/home-container/dialog.png


二進制
src/assets/images/home-container/dialog1.png


二進制
src/assets/images/home-container/header-nav.png


二進制
src/assets/images/home-container/home-bg.png


+ 14 - 0
src/assets/images/home-container/internet-bad.svg

@@ -0,0 +1,14 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="18.669" height="18.669" viewBox="0 0 18.669 18.669">
+  <defs>
+    <linearGradient id="linear-gradient" x1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox">
+      <stop offset="0" stop-color="#36c7ff"/>
+      <stop offset="1" stop-color="#c2eeff"/>
+    </linearGradient>
+  </defs>
+  <g id="组_14251" data-name="组 14251" transform="translate(-0.025 0.443)">
+    <g id="组_14269" data-name="组 14269" transform="translate(-3.195 -0.664)">
+      <path id="椭圆_2488" data-name="椭圆 2488" d="M8.835-.5A9.335,9.335,0,1,1-.5,8.835,9.345,9.345,0,0,1,8.835-.5Zm0,17.669A8.335,8.335,0,1,0,.5,8.835,8.344,8.344,0,0,0,8.835,17.169Z" transform="translate(3.721 0.72)" fill="url(#linear-gradient)"/>
+      <path id="路径_55148" data-name="路径 55148" d="M4.164,6.387,2.106,8.447a1.489,1.489,0,0,1-2.1,0l-.023-.023a1.489,1.489,0,0,1,0-2.1L2.043,4.266a1.489,1.489,0,0,1,2.1,0l.023.023a1.487,1.487,0,0,1,0,2.1ZM8.746,1.8,6.688,3.864a1.489,1.489,0,0,1-2.1,0l-.023-.023a1.489,1.489,0,0,1,0-2.1L6.624-.317a1.489,1.489,0,0,1,2.1,0l.023.023a1.487,1.487,0,0,1,0,2.1ZM3.764,3.165,3.773.92,2.862.61Zm-.6.15L1.208,2.564l.451.9Zm1.8,1.362.305,2.259.6-.766Zm.3.15,1.8,1.043-.451-.9ZM3.012,2.714,2.261,1.662l-.15.752Z" transform="translate(8.191 5.491)" stroke="rgba(0,0,0,0)" stroke-width="1" fill="url(#linear-gradient)"/>
+    </g>
+  </g>
+</svg>

二進制
src/assets/images/home-container/item-value.png


二進制
src/assets/images/home-container/line-val.png


二進制
src/assets/images/home-container/pie.png


二進制
src/assets/images/home-container/three-dialog.png


二進制
src/assets/images/home-container/three-nav.png


二進制
src/assets/images/home-container/tobig.png


文件差異過大導致無法顯示
+ 7 - 0
src/assets/images/home-container/toggle.svg


二進制
src/assets/images/home-container/warn-icon.png


二進制
src/assets/images/home-container/warn-icon1.png


二進制
src/assets/images/home-container/warn-icon2.png


二進制
src/assets/images/home-container/warn-icon3.png


二進制
src/assets/images/home-container/warn1.png


二進制
src/assets/images/home-container/warn7.png


二進制
src/assets/images/home-container/warn8.png


二進制
src/assets/images/home-container/wind-door.gif


二進制
src/assets/images/home-container/wind-window.gif


二進制
src/assets/images/home-container/work-bd.png


二進制
src/assets/images/home-container/左下菜单按钮.png


二進制
src/assets/images/home-container/背景图.png - 快捷方式.lnk


二進制
src/assets/images/home-container/视频上方数据框.png


+ 22 - 0
src/assets/images/home-container/运行风机图标.svg

@@ -0,0 +1,22 @@
+<svg id="组_14254" data-name="组 14254" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="18.195" height="18.195" viewBox="0 0 18.195 18.195">
+  <defs>
+    <linearGradient id="linear-gradient" x1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox">
+      <stop offset="0" stop-color="#36c7ff"/>
+      <stop offset="1" stop-color="#c2eeff"/>
+    </linearGradient>
+  </defs>
+  <g id="组_12385" data-name="组 12385">
+    <g id="组_9332" data-name="组 9332">
+      <g id="图层_2" data-name="图层 2">
+        <g id="图层_1" data-name="图层 1">
+          <g id="组_12446" data-name="组 12446">
+            <g id="组_12442" data-name="组 12442">
+              <path id="路径_55231" data-name="路径 55231" d="M9.1,18.2a9.1,9.1,0,1,1,9.1-9.1,9.124,9.124,0,0,1-9.1,9.1ZM9.1.91A8.188,8.188,0,1,0,17.285,9.1,8.154,8.154,0,0,0,9.1.91Z" fill="url(#linear-gradient)"/>
+              <path id="路径_55232" data-name="路径 55232" d="M334.929,244.545s-7.506-4.208-7.619-4.208c-.682-.227-.91.341-.91.8h0s0,8.3.114,8.3c.227.569.8.569,1.251.341h0s6.937-3.98,7.051-4.094c.341-.227.682-.682.114-1.137Z" transform="translate(-320.6 -236.016)" fill="url(#linear-gradient)"/>
+            </g>
+          </g>
+        </g>
+      </g>
+    </g>
+  </g>
+</svg>

二進制
src/assets/images/people.png


二進制
src/assets/images/process_no_form.png


二進制
src/assets/images/setting.png


二進制
src/assets/images/template_cover.jpg


二進制
src/assets/images/wallet.png


二進制
src/assets/svg/fileType/image.png


+ 2 - 1
src/components/Application/src/AppLogo.vue

@@ -50,7 +50,8 @@
   ]);
 
   function goHome() {
-    go(userStore.getUserInfo.homePath || PageEnum.BASE_HOME);
+    const glob = useGlobSetting();
+    go(glob.homePath || PageEnum.BASE_HOME);
   }
 </script>
 <style lang="less" scoped>

+ 1 - 1
src/components/CodeEditor/src/CodeEditor.vue

@@ -15,7 +15,7 @@
   import { computed } from 'vue';
   import CodeMirrorEditor from './codemirror/CodeMirror.vue';
   import { isString } from '/@/utils/is';
-
+  
   const props = defineProps({
     value: { type: [Object, String] as PropType<Record<string, any> | string> },
     mode: { type: String, default: MODE.JSON },

+ 1 - 1
src/components/CountDown/src/CountdownInput.vue

@@ -12,7 +12,7 @@
   import { defineComponent, PropType } from 'vue';
   import CountButton from './CountButton.vue';
   import { useDesign } from '/@/hooks/web/useDesign';
-  import { useRuleFormItem } from '/@/hooks/component/useFormItem';
+  import { useRuleFormItem } from '/@/hooks/component/useFormItemSingle';
 
   const props = {
     value: { type: String },

+ 11 - 4
src/components/Dropdown/src/Dropdown.vue

@@ -10,19 +10,26 @@
             v-bind="getAttr(item.event)"
             @click="handleClickMenu(item)"
             :disabled="item.disabled"
-            :class="[{ 'is-pop-confirm': item.popConfirm }, (item.class ?? [])]"
+            :class="[{ 'is-pop-confirm': item.popConfirm }, item.class ?? []]"
           >
             <a-popconfirm v-if="popconfirm && item.popConfirm" v-bind="getPopConfirmAttrs(item.popConfirm)">
               <template #icon v-if="item.popConfirm.icon">
-                <Icon :icon="item.popConfirm.icon" />
+                <Icon v-if="item.iconColor" :icon="item.popConfirm.icon" :color="item.iconColor" />
+                <Icon v-else :icon="item.popConfirm.icon" />
               </template>
               <div class="dropdown-event-area">
-                <Icon :icon="item.icon" v-if="item.icon" />
+                <Icon :icon="item.icon" v-if="item.icon && item.iconColor" :color="item.iconColor" />
+                <Icon :icon="item.icon" v-else-if="item.icon" />
                 <span class="ml-1">{{ item.text }}</span>
               </div>
             </a-popconfirm>
+            <!--  设置动态插槽   -->
+            <template v-else-if="item.slot">
+              <slot :name="item.slot" :label="item.text"></slot>
+            </template>
             <template v-else>
-              <Icon :icon="item.icon" v-if="item.icon" />
+              <Icon :icon="item.icon" v-if="item.icon && item.iconColor" :color="item.iconColor" />
+              <Icon :icon="item.icon" v-else-if="item.icon" />
               <span class="ml-1">{{ item.text }}</span>
             </template>
           </a-menu-item>

+ 38 - 9
src/components/Form/src/BasicForm.vue

@@ -53,8 +53,11 @@
   import { useModalContext } from '/@/components/Modal';
 
   import { basicProps } from './props';
+  import componentSetting from '/@/settings/componentSetting';
+
   import { useDesign } from '/@/hooks/web/useDesign';
   import dayjs from 'dayjs';
+  import { useDebounceFn } from '@vueuse/core';
 
   export default defineComponent({
     name: 'BasicForm',
@@ -89,6 +92,16 @@
           mergeProps.labelCol = undefined;
         }
         //update-end-author:sunjianlei date:20220923 for: 如果用户设置了labelWidth,则使labelCol失效,解决labelWidth设置无效的问题
+        // update-begin--author:liaozhiyang---date:20231017---for:【QQYUN-6566】BasicForm支持一行显示(inline)
+        if (mergeProps.layout === 'inline') {
+          if (mergeProps.labelCol === componentSetting.form.labelCol) {
+            mergeProps.labelCol = undefined;
+          }
+          if (mergeProps.wrapperCol === componentSetting.form.wrapperCol) {
+            mergeProps.wrapperCol = undefined;
+          }
+        }
+        // update-end--author:liaozhiyang---date:20231017---for:【QQYUN-6566】BasicForm支持一行显示(inline)
         return mergeProps;
       });
 
@@ -118,12 +131,20 @@
           const { defaultValue, component, componentProps } = schema;
           // handle date type
           if (defaultValue && dateItemType.includes(component)) {
-            const { valueFormat } = componentProps;
+            //update-begin---author:wangshuai ---date:20230410  for:【issues/435】代码生成的日期控件赋默认值报错------------
+            let valueFormat:string = "";
+            if(componentProps){
+              valueFormat = componentProps?.valueFormat;
+            }
+            if(!valueFormat){
+              console.warn("未配置valueFormat,可能导致格式化错误!");
+            }
+            //update-end---author:wangshuai ---date:20230410  for:【issues/435】代码生成的日期控件赋默认值报错------------
             if (!Array.isArray(defaultValue)) {
               //update-begin---author:wangshuai ---date:20221124  for:[issues/215]列表页查询框(日期选择框)设置初始时间,一进入页面时,后台报日期转换类型错误的------------
-              if (valueFormat) {
+              if(valueFormat){
                 schema.defaultValue = dateUtil(defaultValue).format(valueFormat);
-              } else {
+              }else{
                 schema.defaultValue = dateUtil(defaultValue);
               }
               //update-end---author:wangshuai ---date:20221124  for:[issues/215]列表页查询框(日期选择框)设置初始时间,一进入页面时,后台报日期转换类型错误的------------
@@ -131,9 +152,9 @@
               const def: dayjs.Dayjs[] = [];
               defaultValue.forEach((item) => {
                 //update-begin---author:wangshuai ---date:20221124  for:[issues/215]列表页查询框(日期选择框)设置初始时间,一进入页面时,后台报日期转换类型错误的------------
-                if (valueFormat) {
+                if(valueFormat){
                   def.push(dateUtil(item).format(valueFormat));
-                } else {
+                }else{
                   def.push(dateUtil(item));
                 }
                 //update-end---author:wangshuai ---date:20221124  for:[issues/215]列表页查询框(日期选择框)设置初始时间,一进入页面时,后台报日期转换类型错误的------------
@@ -241,13 +262,21 @@
         propsRef.value = deepMerge(unref(propsRef) || {}, formProps);
       }
 
+      //update-begin-author:taoyan date:2022-11-28 for: QQYUN-3121 【优化】表单视图问题#scott测试 8、此功能未实现
+      const onFormSubmitWhenChange = useDebounceFn(handleSubmit, 300);
       function setFormModel(key: string, value: any) {
         formModel[key] = value;
-        const { validateTrigger } = unref(getBindValue);
-        if (!validateTrigger || validateTrigger === 'change') {
-          validateFields([key]).catch((_) => {});
+        // update-begin--author:liaozhiyang---date:20230922---for:【issues/752】表单校验dynamicRules 无法 使用失去焦点后校验 trigger: 'blur'
+        // const { validateTrigger } = unref(getBindValue);
+        // if (!validateTrigger || validateTrigger === 'change') {
+        //   validateFields([key]).catch((_) => {});
+        // }
+        // update-end--author:liaozhiyang---date:20230922---for:【issues/752】表单校验dynamicRules 无法 使用失去焦点后校验 trigger: 'blur'
+        if(props.autoSearch === true){
+          onFormSubmitWhenChange();
         }
       }
+      //update-end-author:taoyan date:2022-11-28 for: QQYUN-3121 【优化】表单视图问题#scott测试 8、此功能未实现
 
       function handleEnterPress(e: KeyboardEvent) {
         const { autoSubmitOnEnter } = unref(getProps);
@@ -370,6 +399,6 @@
   :deep(.@{ventSpace}-select-dropdown) {
     left: 0px !important;
     top: 34px !important;
-    background: transparent !important;
+    background: #ffffff !important;
   }
 </style>

+ 9 - 1
src/components/Form/src/componentMap.ts

@@ -61,7 +61,10 @@ 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 JRangeDate from './jeecg/components/JRangeDate.vue';
+import UserSelect from './jeecg/components/userSelect/index.vue';
+import JRangeDate from './jeecg/components/JRangeDate.vue'
+import JRangeTime from './jeecg/components/JRangeTime.vue'
+import RoleSelectInput from './jeecg/components/roleSelect/RoleSelectInput.vue';
 
 const componentMap = new Map<ComponentType, Component>();
 
@@ -131,7 +134,12 @@ componentMap.set('JUpload', JUpload);
 componentMap.set('JSearchSelect', JSearchSelect);
 componentMap.set('JAddInput', JAddInput);
 componentMap.set('JRangeNumber', JRangeNumber);
+componentMap.set('UserSelect', UserSelect);
 componentMap.set('RangeDate', JRangeDate);
+componentMap.set('RangeTime', JRangeTime);
+componentMap.set('RoleSelect', RoleSelectInput);
+
+
 
 export function add(compName: ComponentType, component: Component) {
   componentMap.set(compName, component);

+ 42 - 3
src/components/Form/src/components/ApiSelect.vue

@@ -1,5 +1,5 @@
 <template>
-  <Select @dropdownVisibleChange="handleFetch" v-bind="$attrs" @change="handleChange" :options="getOptions" v-model:value="state">
+  <Select @dropdownVisibleChange="handleFetch" v-bind="attrs_" @change="handleChange" :options="getOptions" v-model:value="state">
     <template #[item]="data" v-for="item in Object.keys($slots)">
       <slot :name="item" v-bind="data || {}"></slot>
     </template>
@@ -63,7 +63,30 @@
 
       // Embedded in the form, just use the hook binding to perform form verification
       const [state, setState] = useRuleFormItem(props, 'value', 'change', emitData);
-
+      // update-begin--author:liaozhiyang---date:20230830---for:【QQYUN-6308】解决警告
+      let vModalValue: any;
+      const attrs_ = computed(() => {
+        let obj: any = unref(attrs) || {};
+        if (obj && obj['onUpdate:value']) {
+          vModalValue = obj['onUpdate:value'];
+          delete obj['onUpdate:value'];
+        }
+        // update-begin--author:liaozhiyang---date:20231017---for:【issues/5467】ApiSelect修复覆盖了用户传递的方法
+        if (obj['filterOption'] === undefined) {
+          // update-begin--author:liaozhiyang---date:20230904---for:【issues/5305】无法按照预期进行搜索
+          obj['filterOption'] = (inputValue, option) => {
+            if (typeof option['label'] === 'string') {
+              return option['label'].toLowerCase().indexOf(inputValue.toLowerCase()) != -1;
+            } else {
+              return true;
+            }
+          };
+          // update-end--author:liaozhiyang---date:20230904---for:【issues/5305】无法按照预期进行搜索
+        }
+        // update-end--author:liaozhiyang---date:20231017---for:【issues/5467】ApiSelect修复覆盖了用户传递的方法
+        return obj;
+      });
+      // update-begin--author:liaozhiyang---date:20230830---for:【QQYUN-6308】解决警告
       const getOptions = computed(() => {
         const { labelField, valueField, numberToString } = props;
         return unref(options).reduce((prev, next: Recordable) => {
@@ -90,6 +113,10 @@
         },
         { deep: true }
       );
+     //监听数值修改,查询数据
+      watchEffect(() => {
+        props.value && handleFetch();
+      });
 
       async function fetch() {
         const api = props.api;
@@ -114,6 +141,17 @@
           //--@updateBy-begin----author:liusq---date:20210914------for:判断选择模式,multiple多选情况下的value值空的情况下需要设置为数组------
           unref(attrs).mode == 'multiple' && !Array.isArray(unref(state)) && setState([]);
           //--@updateBy-end----author:liusq---date:20210914------for:判断选择模式,multiple多选情况下的value值空的情况下需要设置为数组------
+
+          //update-begin---author:wangshuai ---date:20230505  for:初始化value值,如果是多选字符串的情况下显示不出来------------
+          initValue();
+          //update-end---author:wangshuai ---date:20230505  for:初始化value值,如果是多选字符串的情况下显示不出来------------
+        }
+      }
+
+      function initValue() {
+        let value = props.value;
+        if (value && typeof value === 'string' && value != 'null' && value != 'undefined') {
+          state.value = value.split(',');
         }
       }
 
@@ -129,10 +167,11 @@
       }
 
       function handleChange(_, ...args) {
+        vModalValue && vModalValue(_);
         emitData.value = args;
       }
 
-      return { state, attrs, getOptions, loading, t, handleFetch, handleChange };
+      return { state, attrs_, attrs, getOptions, loading, t, handleFetch, handleChange };
     },
   });
 </script>

+ 6 - 1
src/components/Form/src/components/FormAction.vue

@@ -65,6 +65,7 @@
       actionSpan: propTypes.number.def(6),
       isAdvanced: propTypes.bool,
       hideAdvanceBtn: propTypes.bool,
+      layout: propTypes.oneOf(['horizontal', 'vertical', 'inline']).def('horizontal'),
     },
     emits: ['toggle-advanced'],
     setup(props, { emit }) {
@@ -76,10 +77,14 @@
         const advancedSpanObj = showAdvancedButton ? { span: actionSpan < 6 ? 24 : actionSpan } : {};
         const actionColOpt: Partial<ColEx> = {
           style: { textAlign: 'right' },
-          span: showAdvancedButton ? 6 : 4,
           ...advancedSpanObj,
           ...actionColOptions,
         };
+        // update-begin--author:liaozhiyang---date:20231017---for:【QQYUN-6566】BasicForm支持一行显示(inline)
+        if (props.layout !== 'inline') {
+          actionColOpt['span'] = showAdvancedButton ? 6 : 4;
+        }
+        // update-end--author:liaozhiyang---date:20231017---for:【QQYUN-6566】BasicForm支持一行显示(inline)
         return actionColOpt;
       });
 

+ 42 - 9
src/components/Form/src/components/FormItem.vue

@@ -1,4 +1,5 @@
 <script lang="tsx">
+  import { NamePath, ValidateOptions } from 'ant-design-vue/lib/form/interface';
   import type { PropType, Ref } from 'vue';
   import type { FormActionType, FormProps } from '../types/form';
   import type { FormSchema } from '../types/form';
@@ -14,6 +15,7 @@
   import { upperFirst, cloneDeep } from 'lodash-es';
   import { useItemLabelWidth } from '../hooks/useLabelWidth';
   import { useI18n } from '/@/hooks/web/useI18n';
+  import { useAppInject } from '/@/hooks/web/useAppInject';
 
   export default defineComponent({
     name: 'BasicFormItem',
@@ -39,6 +41,10 @@
         type: Function as PropType<(key: string, value: any) => void>,
         default: null,
       },
+      validateFields: {
+        type: Function as PropType<(nameList?: NamePath[] | undefined, options?: ValidateOptions) => Promise<any>>,
+        default: null,
+      },
       tableAction: {
         type: Object as PropType<TableActionType>,
       },
@@ -78,10 +84,9 @@
           componentProps = componentProps({ schema, tableAction, formModel, formActionType }) ?? {};
         }
         if (schema.component === 'Divider') {
-          componentProps = Object.assign({ type: 'horizontal' }, componentProps, {
-            orientation: 'left',
-            plain: true,
-          });
+          //update-begin---author:wangshuai---date:2023-09-22---for:【QQYUN-6603】分割线标题位置显示不正确---
+          componentProps = Object.assign({ type: 'horizontal',orientation:'left', plain: true, }, componentProps);
+          //update-end---author:wangshuai---date:2023-09-22---for:【QQYUN-6603】分割线标题位置显示不正确---
         }
         return componentProps as Recordable;
       });
@@ -201,12 +206,17 @@
       }
 
       function renderComponent() {
-        const { renderComponentContent, component, field, changeEvent = 'change', valueField } = props.schema;
+        const { renderComponentContent, component, field, changeEvent = 'change', valueField, componentProps } = props.schema;
 
         const isCheck = component && ['Switch', 'Checkbox'].includes(component);
-
+        // update-begin--author:liaozhiyang---date:20231013---for:【QQYUN-6679】input去空格
+        let isTrim = false;
+        if (component === 'Input' && componentProps && componentProps.trim) {
+          isTrim = true;
+        }
+        // update-end--author:liaozhiyang---date:20231013---for:【QQYUN-6679】input去空格
         const eventKey = `on${upperFirst(changeEvent)}`;
-
+        // update-begin--author:liaozhiyang---date:20230922---for:【issues/752】表单校验dynamicRules 无法 使用失去焦点后校验 trigger: 'blur'
         const on = {
           [eventKey]: (...args: Nullable<Recordable>[]) => {
             const [e] = args;
@@ -214,10 +224,26 @@
               propsData[eventKey](...args);
             }
             const target = e ? e.target : null;
-            const value = target ? (isCheck ? target.checked : target.value) : e;
+            // update-begin--author:liaozhiyang---date:20231013---for:【QQYUN-6679】input去空格
+            let value;
+            if (target) {
+              if (isCheck) {
+                value = target.checked;
+              } else {
+                value = isTrim ? target.value.trim() : target.value;
+              }
+            } else {
+              value = e;
+            }
+            // update-end--author:liaozhiyang---date:20231013---for:【QQYUN-6679】input去空格
             props.setFormModel(field, value);
+            //props.validateFields([field], { triggerName: 'change' }).catch((_) => {});
           },
+          // onBlur: () => {
+          //   props.validateFields([field], { triggerName: 'blur' }).catch((_) => {});
+          // },
         };
+        // update-end--author:liaozhiyang---date:20230922---for:【issues/752】表单校验dynamicRules 无法 使用失去焦点后校验 trigger: 'blur'
         const Comp = componentMap.get(component) as ReturnType<typeof defineComponent>;
 
         const { autoSetPlaceHolder, size } = props.formProps;
@@ -341,7 +367,14 @@
         }
 
         const { baseColProps = {} } = props.formProps;
-        const realColProps = { ...baseColProps, ...colProps };
+        // update-begin--author:liaozhiyang---date:20230803---for:【issues-641】调整表格搜索表单的span配置无效 
+        const { getIsMobile } = useAppInject();
+        let realColProps;
+        if (colProps['span'] && !unref(getIsMobile)) {
+          ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].forEach((name) => delete baseColProps[name]);
+        }
+        realColProps = { ...baseColProps, ...colProps };
+        // update-end--author:liaozhiyang---date:20230803---for:【issues-641】调整表格搜索表单的span配置无效 
         const { isIfShow, isShow } = getShow();
         const values = unref(getValues);
 

+ 23 - 18
src/components/Form/src/hooks/useForm.ts

@@ -1,16 +1,16 @@
 import type { FormProps, FormActionType, UseFormReturnType, FormSchema } from '../types/form';
-import type { NamePath } from 'ant-design-vue/lib/form/interface';
+import type { NamePath, ValidateOptions } from 'ant-design-vue/lib/form/interface';
 import type { DynamicProps } from '/#/utils';
 import { handleRangeValue } from '../utils/formUtils';
 import { ref, onUnmounted, unref, nextTick, watch } from 'vue';
 import { isProdMode } from '/@/utils/env';
 import { error } from '/@/utils/log';
 import { getDynamicProps, getValueType } from '/@/utils';
-import { add } from '/@/components/Form/src/componentMap';
+import { add } from "/@/components/Form/src/componentMap";
 //集成online专用控件
-import { OnlineSelectCascade, LinkTableCard, LinkTableSelect } from '@jeecg/online';
+import { OnlineSelectCascade, LinkTableCard, LinkTableSelect } from  '@jeecg/online';
 
-export declare type ValidateFields = (nameList?: NamePath[]) => Promise<Recordable>;
+export declare type ValidateFields = (nameList?: NamePath[], options?: ValidateOptions) => Promise<Recordable>;
 
 type Props = Partial<DynamicProps<FormProps>>;
 
@@ -19,10 +19,10 @@ export function useForm(props?: Props): UseFormReturnType {
   const loadedRef = ref<Nullable<boolean>>(false);
 
   //集成online专用控件
-  add('OnlineSelectCascade', OnlineSelectCascade);
-  add('LinkTableCard', LinkTableCard);
-  add('LinkTableSelect', LinkTableSelect);
-
+  add("OnlineSelectCascade", OnlineSelectCascade)
+  add("LinkTableCard", LinkTableCard)
+  add("LinkTableSelect", LinkTableSelect)
+  
   async function getForm() {
     const form = unref(formRef);
     if (!form) {
@@ -93,11 +93,16 @@ export function useForm(props?: Props): UseFormReturnType {
     // TODO promisify
     getFieldsValue: <T>() => {
       //update-begin-author:taoyan date:2022-7-5 for: VUEN-1341【流程】编码方式 流程节点编辑表单时,填写数据报错 包括用户组件、部门组件、省市区
-      const values = unref(formRef)?.getFieldsValue() as T;
-      if (values) {
-        Object.keys(values).map((key) => {
+      let values = unref(formRef)?.getFieldsValue() as T;
+      if(values){
+        Object.keys(values).map(key=>{
           if (values[key] instanceof Array) {
-            values[key] = values[key].join(',');
+            // update-begin-author:sunjianlei date:20221205 for: 【issues/4330】判断如果是对象数组,则不拼接
+            let isObject = typeof (values[key][0] || '') === 'object';
+            if (!isObject) {
+              values[key] = values[key].join(',');
+            }
+            // update-end-author:sunjianlei date:20221205 for: 【issues/4330】判断如果是对象数组,则不拼接
           }
         });
       }
@@ -128,11 +133,11 @@ export function useForm(props?: Props): UseFormReturnType {
      */
     validate: async (nameList?: NamePath[]): Promise<Recordable> => {
       const form = await getForm();
-      const getProps = props || form.getProps;
-      const values = form.validate(nameList).then((values) => {
-        for (const key in values) {
+      let getProps = props || form.getProps;
+      let values = form.validate(nameList).then((values) => {
+        for (let key in values) {
           if (values[key] instanceof Array) {
-            const valueType = getValueType(getProps, key);
+            let valueType = getValueType(getProps, key);
             if (valueType === 'string') {
               values[key] = values[key].join(',');
             }
@@ -144,9 +149,9 @@ export function useForm(props?: Props): UseFormReturnType {
       });
       return values;
     },
-    validateFields: async (nameList?: NamePath[]): Promise<Recordable> => {
+    validateFields: async (nameList?: NamePath[], options?: ValidateOptions): Promise<Recordable> => {
       const form = await getForm();
-      return form.validateFields(nameList);
+      return form.validateFields(nameList, options);
     },
   };
 

+ 3 - 3
src/components/Form/src/hooks/useFormEvents.ts

@@ -1,6 +1,6 @@
 import type { ComputedRef, Ref } from 'vue';
 import type { FormProps, FormSchema, FormActionType } from '../types/form';
-import type { NamePath } from 'ant-design-vue/lib/form/interface';
+import type { NamePath, ValidateOptions } from 'ant-design-vue/lib/form/interface';
 import { unref, toRaw } from 'vue';
 import { isArray, isFunction, isObject, isString } from '/@/utils/is';
 import { deepMerge, getValueType } from '/@/utils';
@@ -207,8 +207,8 @@ export function useFormEvents({
     });
   }
 
-  async function validateFields(nameList?: NamePath[] | undefined) {
-    return unref(formElRef)?.validateFields(nameList);
+  async function validateFields(nameList?: NamePath[] | undefined, options?: ValidateOptions) {
+    return unref(formElRef)?.validateFields(nameList, options);
   }
 
   async function validate(nameList?: NamePath[] | undefined) {

+ 1 - 1
src/components/Form/src/jeecg/components/JAreaLinkage.vue

@@ -15,7 +15,7 @@
     },
     inheritAttrs: false,
     props: {
-      value: propTypes.oneOfType([propTypes.object, propTypes.array]),
+      value: propTypes.oneOfType([propTypes.object, propTypes.array, propTypes.string]),
       //是否显示区县
       showArea: propTypes.bool.def(true),
       //是否是全部

+ 4 - 3
src/components/Form/src/jeecg/components/JCategorySelect.vue

@@ -71,13 +71,12 @@
         required: false,
       },
     },
-    emits: ['options-change', 'change'],
+    emits: ['options-change', 'change', 'update:value'],
     setup(props, { emit, refs }) {
       console.info(props);
       const emitData = ref<any[]>([]);
       const treeData = ref<any[]>([]);
       const treeValue = ref();
-      treeValue.value = '';
       const attrs = useAttrs();
       const [state] = useRuleFormItem(props, 'value', 'change', emitData);
       watch(
@@ -122,7 +121,7 @@
           if(props.multiple){
             treeValue.value = [];
           }else{
-            treeValue.value = '';
+            treeValue.value = { value: null, label: null };
           }
         } else {
           loadDictItem({ ids: props.value }).then((res) => {
@@ -153,6 +152,7 @@
           obj[props.back] = label;
         }
         emit('change', value, obj);
+        emit("update:value",value)
       }
 
       function asyncLoadTreeData(treeNode) {
@@ -205,6 +205,7 @@
         if (!value) {
           emit('change', '');
           treeValue.value = '';
+          emit("update:value",'')
         } else if (Array.isArray(value)) {
           let labels = [];
           let values = value.map((item) => {

+ 28 - 12
src/components/Form/src/jeecg/components/JCodeEditor.vue

@@ -1,5 +1,5 @@
 <template>
-  <div v-bind="boxBindProps">
+  <div ref="containerRef" v-bind="boxBindProps">
     <!-- 全屏按钮 -->
     <a-icon v-if="fullScreen" class="full-screen-icon" :type="fullScreenIcon" @click="onToggleFullScreen" />
     <textarea ref="textarea" v-bind="getBindValue"></textarea>
@@ -45,12 +45,14 @@
   import { useAttrs } from '/@/hooks/core/useAttrs';
   import { useDesign } from '/@/hooks/web/useDesign';
   import { isJsonObjectString } from '/@/utils/is.ts';
+  // 代码提示
+  import { useCodeHinting } from '../hooks/useCodeHinting';
 
   export default defineComponent({
     name: 'JCodeEditor',
-    components: {},
     // 不将 attrs 的属性绑定到 html 标签上
     inheritAttrs: false,
+    components: {},
     props: {
       value: propTypes.string.def(''),
       height: propTypes.string.def('auto'),
@@ -61,9 +63,12 @@
       zIndex: propTypes.any.def(999),
       theme: propTypes.string.def('idea'),
       language: propTypes.string.def(''),
+      // 代码提示
+      keywords: propTypes.array.def([]),
     },
     emits: ['change', 'update:value'],
     setup(props, { emit }) {
+      const containerRef = ref(null);
       const { prefixCls } = useDesign('code-editer');
       const CodeMirror = window.CodeMirror || _CodeMirror;
       const emitData = ref<object>();
@@ -121,6 +126,10 @@
         }
         return _props;
       });
+      // update-begin--author:liaozhiyang---date:20230904---for:【QQYUN-5955】online js增强,加入代码提示
+      const { codeHintingMount, codeHintingRegistry } = useCodeHinting(CodeMirror, props.keywords, props.language);
+      codeHintingRegistry();
+      // update-end--author:liaozhiyang---date:20230904---for:【QQYUN-5955】online js增强,加入代码提示
       /**
        * 监听组件值
        */
@@ -171,6 +180,9 @@
         coder.on('change', onChange);
         // 初始化成功时赋值一次
         setValue(innerValue, false);
+        // update-begin--author:liaozhiyang---date:20230904---for:【QQYUN-5955】online js增强,加入代码提示
+        codeHintingMount(coder);
+        // update-end--author:liaozhiyang---date:20230904---for:【QQYUN-5955】online js增强,加入代码提示
       }
 
       // 切换全屏状态
@@ -188,16 +200,13 @@
         }
       );
       //update-end-author:taoyan date:2022-5-9 for: codeEditor禁用功能
-
+      
       // 支持动态设置语言
-      watch(
-        () => props.language,
-        (val) => {
-          if (val && coder) {
-            coder.setOption('mode', val);
-          }
+      watch(()=>props.language, (val)=>{
+        if(val && coder){
+          coder.setOption('mode', val);
         }
-      );
+      });
 
       const getBindValue = Object.assign({}, unref(props), unref(attrs));
 
@@ -208,7 +217,8 @@
         }
       }
       //update-end-author:taoyan date:2022-10-18 for: VUEN-2480【严重bug】online vue3测试的问题 8、online js增强样式问题
-      
+
+
       return {
         state,
         textarea,
@@ -218,7 +228,8 @@
         isFullScreen,
         fullScreenIcon,
         onToggleFullScreen,
-        refresh
+        refresh,
+        containerRef,
       };
     },
   });
@@ -298,4 +309,9 @@
       border: 1px solid #ddd;
     }
   }
+  .CodeMirror-hints.idea {
+    z-index: 1001;
+    max-width: 600px;
+    max-height: 300px;
+  }
 </style>

+ 35 - 20
src/components/Form/src/jeecg/components/JDictSelectTag.vue

@@ -35,6 +35,7 @@
       v-model:value="state"
       :filterOption="handleFilterOption"
       :getPopupContainer="getPopupContainer"
+      :style="style"
       @change="handleChange"
     >
       <a-select-option v-if="showChooseOption" :value="null">请选择…</a-select-option>
@@ -60,8 +61,8 @@
 
   export default defineComponent({
     name: 'JDictSelectTag',
-    components: { LoadingOutlined },
     inheritAttrs: false,
+    components: { LoadingOutlined },
     props: {
       value: propTypes.oneOfType([propTypes.string, propTypes.number, propTypes.array]),
       dictCode: propTypes.string,
@@ -80,8 +81,9 @@
         default: [],
         required: false,
       },
+      style: propTypes.any,
     },
-    emits: ['options-change', 'change'],
+    emits: ['options-change', 'change','update:value'],
     setup(props, { emit, refs }) {
       const dictOptions = ref<any[]>([]);
       const attrs = useAttrs();
@@ -146,39 +148,52 @@
 
       function handleChange(e) {
         const { mode } = unref<Recordable>(getBindValue);
+        let changeValue:any;
         // 兼容多选模式
+        
+        //update-begin---author:wangshuai ---date:20230216  for:[QQYUN-4290]公文发文:选择机关代字报错,是因为值改变触发了change事件三次,导致数据发生改变------------
+        //采用一个值,不然的话state值变换触发多个change
         if (mode === 'multiple') {
-          state.value = e?.target?.value ?? e;
+          changeValue = e?.target?.value ?? e;
+          // 过滤掉空值
+          if (changeValue == null || changeValue === '') {
+            changeValue = [];
+          }
+          if (Array.isArray(changeValue)) {
+            changeValue = changeValue.filter((item) => item != null && item !== '');
+          }
         } else {
-          state.value = [e?.target?.value ?? e];
-        }
-        // 过滤掉空值
-        if (state.value == null || state.value === '') {
-          state.value = [];
+          changeValue = e?.target?.value ?? e;
         }
-        if (Array.isArray(state.value)) {
-          state.value = state.value.filter((item) => item != null && item !== '');
-        }
-        //update-begin---author:wangshuai ---date:20221123  for:单选模式要改成字符串------------
-        if (mode !== 'multiple' && state.value && state.value.length > 0) {
-          state.value = state.value[0];
-        }
-        //update-end---author:wangshuai ---date:20221123  for:单选模式要改成字符串--------------
+        state.value = changeValue;
+
+        //update-begin---author:wangshuai ---date:20230403  for:【issues/4507】JDictSelectTag组件使用时,浏览器给出警告提示:Expected Function, got Array------------
+        emit('update:value',changeValue)
+        //update-end---author:wangshuai ---date:20230403  for:【issues/4507】JDictSelectTag组件使用时,浏览器给出警告提示:Expected Function, got Array述------------
+        //update-end---author:wangshuai ---date:20230216  for:[QQYUN-4290]公文发文:选择机关代字报错,是因为值改变触发了change事件三次,导致数据发生改变------------
+        
         // nextTick(() => formItemContext.onFieldChange());
       }
 
       /** 单选radio的值变化事件 */
       function handleChangeRadio(e) {
         state.value = e?.target?.value ?? e;
+        //update-begin---author:wangshuai ---date:20230504  for:【issues/506】JDictSelectTag 组件 type="radio" 没有返回值------------
+        emit('update:value',e?.target?.value ?? e)
+        //update-end---author:wangshuai ---date:20230504  for:【issues/506】JDictSelectTag 组件 type="radio" 没有返回值------------
       }
 
       /** 用于搜索下拉框中的内容 */
       function handleFilterOption(input, option) {
-        // 在 label 中搜索
-        let labelIf = option.children()[0]?.children.toLowerCase().indexOf(input.toLowerCase()) >= 0;
-        if (labelIf) {
-          return true;
+        // update-begin--author:liaozhiyang---date:20230914---for:【QQYUN-6514】 配置的时候,Y轴不能输入多个字段了,控制台报错
+        if (typeof option.children === 'function') {
+          // 在 label 中搜索
+          let labelIf = option.children()[0]?.children.toLowerCase().indexOf(input.toLowerCase()) >= 0;
+          if (labelIf) {
+            return true;
+          }
         }
+        // update-end--author:liaozhiyang---date:20230914---for:【QQYUN-6514】 配置的时候,Y轴不能输入多个字段了,控制台报错
         // 在 value 中搜索
         return (option.value || '').toString().toLowerCase().indexOf(input.toLowerCase()) >= 0;
       }

+ 1 - 1
src/components/Form/src/jeecg/components/JEllipsis.vue

@@ -11,7 +11,7 @@
   import { propTypes } from '/@/utils/propTypes';
 
   const props = defineProps({
-    value: propTypes.oneOfType([propTypes.string, propTypes.array]),
+    value: propTypes.oneOfType([propTypes.string, propTypes.number, propTypes.array]),
     length: propTypes.number.def(25),
   });
   //显示的文本

+ 8 - 6
src/components/Form/src/jeecg/components/JImageUpload.vue

@@ -2,6 +2,7 @@
   <div class="clearfix">
     <a-upload
       :listType="listType"
+      accept="image/*"
       :multiple="multiple"
       :action="uploadUrl"
       :headers="headers"
@@ -36,7 +37,7 @@
   import { propTypes } from '/@/utils/propTypes';
   import { useAttrs } from '/@/hooks/core/useAttrs';
   import { useMessage } from '/@/hooks/web/useMessage';
-  import { getFileAccessHttpUrl, getRandom } from '/@/utils/common/compUtils';
+  import { getFileAccessHttpUrl, getHeaders, getRandom } from '/@/utils/common/compUtils';
   import { uploadUrl } from '/@/api/common/api';
   import { getToken } from '/@/utils/auth';
 
@@ -93,9 +94,7 @@
         return path.substring(path.lastIndexOf('/') + 1);
       };
       //token
-      const headers = ref<object>({
-        'X-Access-Token': getToken(),
-      });
+      const headers = getHeaders();
       //上传状态
       const loading = ref<boolean>(false);
       //是否是初始化加载
@@ -123,13 +122,16 @@
       watch(
         () => props.value,
         (val, prevCount) => {
-          if (val instanceof Array) {
+         //update-begin---author:liusq ---date:20230601  for:【issues/556】JImageUpload组件value赋初始值没显示图片------------
+            if (val && val instanceof Array) {
             val = val.join(',');
           }
           if (initTag.value == true) {
             initFileList(val);
           }
-        }
+        },
+        { immediate: true }
+        //update-end---author:liusq ---date:20230601  for:【issues/556】JImageUpload组件value赋初始值没显示图片------------
       );
 
       /**

+ 7 - 2
src/components/Form/src/jeecg/components/JInput.vue

@@ -3,10 +3,11 @@
 </template>
 
 <script lang="ts">
-  import { defineComponent, PropType, ref, watchEffect, unref, watch } from 'vue';
+  import { defineComponent, PropType, ref, watchEffect, unref, watch, computed } from 'vue';
   import { useAttrs } from '/@/hooks/core/useAttrs';
   import { propTypes } from '/@/utils/propTypes';
   import { JInputTypeEnum } from '/@/enums/jeecgEnum.ts';
+  import { omit } from 'lodash-es';
 
   export default defineComponent({
     name: 'JInput',
@@ -22,8 +23,12 @@
       const attrs = useAttrs();
       //表单值
       const showText = ref('');
+      // update-begin--author:liaozhiyang---date:20231026---for:【issues/803】JIput updateSchema不生效
       //绑定属性
-      const getBindValue = Object.assign({}, unref(props), unref(attrs));
+      const getBindValue = computed(() => {
+        return omit(Object.assign({}, unref(props), unref(attrs)), ['value']);
+      });
+      // update-end--author:liaozhiyang---date:20231026---for:【issues/803】JIput updateSchema不生效
       //监听类型变化
       watch(
         () => props.type,

+ 11 - 3
src/components/Form/src/jeecg/components/JPopup.vue

@@ -57,7 +57,7 @@
         default: () => [],
       },
     },
-    emits: ['update:value', 'register'],
+    emits: ['update:value', 'register', 'popUpChange', 'focus'],
     setup(props, { emit, refs }) {
       const { createMessage } = useMessage();
       const attrs = useAttrs();
@@ -67,9 +67,11 @@
       //注册model
       const [regModal, { openModal }] = useModal();
       //表单值
-      let { groupId, code, fieldConfig } = props;
+      let {code, fieldConfig } = props;
+      // update-begin--author:liaozhiyang---date:20230811---for:【issues/675】子表字段Popup弹框数据不更新
       //唯一分组groupId
-      const uniqGroupId = computed(() => (groupId ? `${groupId}_${code}_${fieldConfig[0]['source']}_${fieldConfig[0]['target']}` : ''));
+      const uniqGroupId = computed(() => (props.groupId ? `${props.groupId}_${code}_${fieldConfig[0]['source']}_${fieldConfig[0]['target']}` : ''));
+      // update-begin--author:liaozhiyang---date:20230811---for:【issues/675】子表字段Popup弹框数据不更新
       /**
        * 判断popup配置项是否正确
        */
@@ -94,6 +96,7 @@
        * 打开pop弹出框
        */
       function handleOpen() {
+        emit('focus');
         !props.disabled && openModal(true);
       }
 
@@ -121,6 +124,11 @@
         props.formElRef && props.formElRef.setFieldsValue(values);
         //传入赋值方法方式赋值
         props.setFieldsValue && props.setFieldsValue(values);
+        // update-begin--author:liaozhiyang---date:20230831---for:【issues/5288】popup弹框,无法将选择的数据填充到自身
+        // update-begin--author:liaozhiyang---date:20230811---for:【issues/5213】JPopup抛出change事件
+        emit('popUpChange', values);
+        // update-end--author:liaozhiyang---date:20230811---for:【issues/5213】JPopup抛出change事件
+        // update-begin--author:liaozhiyang---date:20230831---for:【issues/5288】popup弹框,无法将选择的数据填充到自身
       }
 
       return {

+ 54 - 56
src/components/Form/src/jeecg/components/JRangeDate.vue

@@ -1,67 +1,65 @@
 <template>
-  <a-range-picker v-model:value="rangeValue" @change="handleChange" :show-time="datetime" :placeholder="placeholder" :valueFormat="valueFormat" />
+    <a-range-picker v-model:value="rangeValue" @change="handleChange" :show-time="datetime" :placeholder="placeholder" :valueFormat="valueFormat"/>
 </template>
 
 <script>
-  import { defineComponent, ref, watch, computed } from 'vue';
-  import { propTypes } from '/@/utils/propTypes';
-  import { Form } from 'ant-design-vue';
+    import { defineComponent, ref, watch, computed } from 'vue';
+    import { propTypes } from '/@/utils/propTypes';
+    import { Form } from 'ant-design-vue';
 
-  const placeholder = ['最小值', '最大值'];
-  /**
-   * 用于范围查询
-   */
-  export default defineComponent({
-    name: 'JRangeDate',
-    props: {
-      value: propTypes.string.def(''),
-      datetime: propTypes.bool.def(false),
-      placeholder: propTypes.string.def(''),
-    },
-    emits: ['change', 'update:value'],
-    setup(props, { emit }) {
-      const rangeValue = ref([]);
-      const formItemContext = Form.useInjectFormItemContext();
-
-      watch(
-        () => props.value,
-        (val) => {
-          if (val) {
-            rangeValue.value = val.split(',');
-          } else {
-            rangeValue.value = [];
-          }
+    const placeholder = ['开始日期', '结束日期']
+    /**
+     * 用于范围查询
+     */
+    export default defineComponent({
+        name: "JRangeDate",
+        props:{
+            value: propTypes.string.def(''),
+            datetime: propTypes.bool.def(false),
+            placeholder: propTypes.string.def(''),
         },
-        { immediate: true }
-      );
+        emits:['change', 'update:value'],
+        setup(props, {emit}){
+            const rangeValue = ref([])
+            const formItemContext = Form.useInjectFormItemContext();
 
-      const valueFormat = computed(() => {
-        if (props.datetime === true) {
-          return 'YYYY-MM-DD HH:mm:ss';
-        } else {
-          return 'YYYY-MM-DD';
-        }
-      });
+            watch(()=>props.value, (val)=>{
+                if(val){
+                    rangeValue.value = val.split(',')
+                }else{
+                    rangeValue.value = []
+                }
+            }, {immediate: true});
 
-      function handleChange(arr) {
-        let str = '';
-        if (arr && arr.length > 0) {
-          if (arr[1] && arr[0]) {
-            str = arr.join(',');
-          }
+            const valueFormat = computed(()=>{
+                if(props.datetime === true){
+                    return 'YYYY-MM-DD HH:mm:ss'
+                }else{
+                    return 'YYYY-MM-DD'
+                }
+            });
+
+            function handleChange(arr){
+                let str = ''
+                if(arr && arr.length>0){
+                    if(arr[1] && arr[0]){
+                        str = arr.join(',')
+                    }
+                }
+                emit('change', str);
+                emit('update:value', str);
+                formItemContext.onFieldChange();
+            }
+            return {
+                rangeValue,
+                placeholder,
+                valueFormat,
+                handleChange
+            }
         }
-        emit('change', str);
-        emit('update:value', str);
-        formItemContext.onFieldChange();
-      }
-      return {
-        rangeValue,
-        placeholder,
-        valueFormat,
-        handleChange,
-      };
-    },
-  });
+    });
 </script>
 
-<style scoped></style>
+<style scoped>
+
+</style>

+ 53 - 0
src/components/Form/src/jeecg/components/JRangeTime.vue

@@ -0,0 +1,53 @@
+<template>
+    <a-time-range-picker v-model:value="rangeValue" @change="handleChange" :placeholder="placeholder" :valueFormat="format" :format="format"/>
+</template>
+
+<script>
+    import { defineComponent, ref, watch } from 'vue';
+    import { propTypes } from '/@/utils/propTypes';
+    import { Form } from 'ant-design-vue';
+
+    const placeholder = ['开始时间', '结束时间']
+    /**
+     * 用于时间-time组件的范围查询
+     */
+    export default defineComponent({
+        name: "JRangeTime",
+        props:{
+            value: propTypes.string.def(''),
+            format: propTypes.string.def('HH:mm:ss'),
+            placeholder: propTypes.string.def(''),
+        },
+        emits:['change', 'update:value'],
+        setup(props, {emit}){
+            const rangeValue = ref([])
+            const formItemContext = Form.useInjectFormItemContext();
+
+            watch(()=>props.value, (val)=>{
+                if(val){
+                    rangeValue.value = val.split(',')
+                }else{
+                    rangeValue.value = []
+                }
+            }, {immediate: true});
+
+
+            function handleChange(arr){
+                let str = ''
+                if(arr && arr.length>0){
+                    if(arr[1] && arr[0]){
+                        str = arr.join(',')
+                    }
+                }
+                emit('change', str);
+                emit('update:value', str);
+                formItemContext.onFieldChange();
+            }
+            return {
+                rangeValue,
+                placeholder,
+                handleChange
+            }
+        }
+    });
+</script>

+ 12 - 2
src/components/Form/src/jeecg/components/JSearchSelect.vue

@@ -29,6 +29,7 @@
     :placeholder="placeholder"
     :filterOption="filterOption"
     :notFoundContent="loading ? undefined : null"
+    :dropdownAlign="{overflow: {adjustY: adjustY }}"
     @change="handleChange"
   >
     <template #notFoundContent>
@@ -64,6 +65,10 @@
         type: Function,
         default: (node) => node.parentNode,
       },
+      //默认开启Y轴溢出位置调整,因此在可视空间不足时下拉框位置会自动上移,导致Select的输入框被遮挡。需要注意的是,默认情况是是可视空间,而不是所拥有的空间
+      //update-begin-author:liusq date:2023-04-04 for:[issue/286]下拉搜索框遮挡问题
+      adjustY:propTypes.bool.def(true),
+      //update-end-author:liusq date:2023-04-04 for:[issue/286]下拉搜索框遮挡问题
       //是否在有值后立即触发change
       immediateChange: propTypes.bool.def(false),
       //update-begin-author:taoyan date:2022-8-15 for: VUEN-1971 【online 专项测试】关联记录和他表字段 1
@@ -111,7 +116,7 @@
       watch(
         () => props.dictOptions,
         (val) => {
-          if (val && val.length > 0) {
+          if (val && val.length >= 0) {
             options.value = [...val];
           }
         },
@@ -293,7 +298,12 @@
         // 如果设定了排序信息,需要写入排序信息,在关键词后加 [orderby:create_time,desc]
         if(props.params && props.params.column && props.params.order){
           let temp = text||''
-          return temp+'[orderby:'+props.params.column+','+props.params.order+']'
+          
+          //update-begin-author:taoyan date:2023-5-22 for: /issues/4905 表单生成器字段配置时,选择关联字段,在进行高级配置时,无法加载数据库列表,提示 Sgin签名校验错误! #4905
+          temp = temp+'[orderby:'+props.params.column+','+props.params.order+']'
+          return encodeURI(temp);
+          //update-end-author:taoyan date:2023-5-22 for: /issues/4905 表单生成器字段配置时,选择关联字段,在进行高级配置时,无法加载数据库列表,提示 Sgin签名校验错误! #4905
+          
         }else{
           return text;
         }

+ 14 - 2
src/components/Form/src/jeecg/components/JSelectDept.vue

@@ -1,8 +1,8 @@
 <!--部门选择组件-->
 <template>
   <div>
-    <JSelectBiz @handleOpen="handleOpen" :loading="loadingEcho" v-bind="attrs" />
-    <DeptSelectModal @register="regModal" @getSelectResult="setValue" v-bind="getBindValue" />
+    <JSelectBiz @handleOpen="handleOpen" :loading="loadingEcho" v-bind="attrs" @change="handleChange"/>
+    <DeptSelectModal @register="regModal" @getSelectResult="setValue" v-bind="getBindValue" :multiple="multiple" />
   </div>
 </template>
 <script lang="ts">
@@ -119,6 +119,17 @@
         emit('update:value', values.join(','));
       }
       const getBindValue = Object.assign({}, unref(props), unref(attrs));
+
+      //update-begin---author:wangshuai ---date:20230406  for:【issues/397】在表单中使用v-model:value绑定JSelectDept组件时无法清除已选择的数据------------
+      /**
+       * 值改变事件更新value值
+       * @param values
+       */
+      function handleChange(values) {
+        emit('update:value', values);
+      }
+      //update-end---author:wangshuai ---date:20230406  for:【issues/397】在表单中使用v-model:value绑定JSelectDept组件时无法清除已选择的数据------------
+      
       return {
         state,
         attrs,
@@ -130,6 +141,7 @@
         regModal,
         setValue,
         handleOpen,
+        handleChange
       };
     },
   });

+ 6 - 2
src/components/Form/src/jeecg/components/JSelectPosition.vue

@@ -30,14 +30,14 @@
       },
       rowKey: {
         type: String,
-        default: 'code',
+        default: 'id',
       },
       params: {
         type: Object,
         default: () => {},
       },
     },
-    emits: ['options-change', 'change'],
+    emits: ['options-change', 'change', 'update:value'],
     setup(props, { emit, refs }) {
       const emitData = ref<any[]>();
       //注册model
@@ -108,6 +108,10 @@
         //emitData.value = values.join(",");
         state.value = values;
         selectValues.value = values;
+        //update-begin-author:liusq date:20230517 for:选择职务组件v-model方式绑定值不生效
+        emit('update:value', values.join(','));
+        //update-begin-author:liusq date:20230517 for:选择职务组件v-model方式绑定值不生效
+
       }
 
       const getBindValue = Object.assign({}, unref(props), unref(attrs));

+ 1 - 1
src/components/Form/src/jeecg/components/JTreeDict.vue

@@ -55,7 +55,7 @@
 
   async function loadViewInfo() {
     if (!props.value || props.value == '0') {
-      treeValue.value = null;
+      treeValue.value = { value: null, label: null };
     } else {
       let params = { field: props.field, val: props.value };
       let result = await defHttp.get({ url: Api.view, params });

+ 23 - 11
src/components/Form/src/jeecg/components/JTreeSelect.vue

@@ -13,7 +13,9 @@
     v-bind="attrs"
     @change="onChange"
     @search="onSearch"
-  />
+    :tree-checkable="treeCheckAble"
+  >
+  </a-tree-select>
 </template>
 <script lang="ts" setup>
   /*
@@ -49,8 +51,12 @@
     reload: propTypes.number.def(1),
     //update-begin-author:taoyan date:2022-11-8 for: issues/4173 Online JTreeSelect控件changeOptions方法未生效
     url: propTypes.string.def(''),
-    params: propTypes.object.def({})
+    params: propTypes.object.def({}),
     //update-end-author:taoyan date:2022-11-8 for: issues/4173 Online JTreeSelect控件changeOptions方法未生效
+    //update-begin---author:wangshuai date: 20230202 for: 新增是否有复选框
+    //默认没有选择框
+    treeCheckAble: propTypes.bool.def(false),
+    //update-end---author:wangshuai date: 20230202 for: 新增是否有复选框
   });
   const attrs = useAttrs();
   const emit = defineEmits(['change', 'update:value']);
@@ -100,10 +106,10 @@
    */
   async function loadItemByCode() {
     if (!props.value || props.value == '0') {
-      if (props.multiple) {
+      if(props.multiple){
         treeValue.value = [];
-      } else {
-        treeValue.value = null;
+      }else{
+        treeValue.value = { label: null, value: null };
       }
     } else {
       //update-begin-author:taoyan date:2022-11-8 for: issues/4173 Online JTreeSelect控件changeOptions方法未生效
@@ -113,12 +119,18 @@
         let params = { key: props.value };
         let result = await defHttp.get({ url: `${Api.view}${props.dict}`, params }, { isTransformResponse: false });
         if (result.success) {
-          let values = props.value.split(',');
-          treeValue.value = result.result.map((item, index) => ({
-            key: values[index],
-            value: values[index],
-            label: item,
-          }));
+          //update-start-author:liaozhiyang date:2023-7-17 for:【issues/5141】使用JtreeSelect 组件 控制台报错
+          if(props.multiple){
+            let values = props.value.split(',');
+            treeValue.value = result.result.map((item, index) => ({
+              key: values[index],
+              value: values[index],
+              label: item,
+            }));
+          }else{
+            treeValue.value = { key: props.value, value: props.value, label: result.result[0] };
+          }
+          //update-end-author:liaozhiyang date:2023-7-17 for:【issues/5141】使用JtreeSelect 组件 控制台报错
           onLoadTriggleChange(result.result[0]);
         }
       }

+ 44 - 13
src/components/Form/src/jeecg/components/JUpload/JUpload.vue

@@ -17,7 +17,7 @@
           <div class="ant-upload-text">{{ text }}</div>
         </div>
       </template>
-      <a-button v-else-if="buttonVisible" :disabled="isMaxCount || disabled">
+      <a-button v-else-if="buttonVisible" :disabled="buttonDisabled">
         <Icon icon="ant-design:upload-outlined" />
         <span>{{ text }}</span>
       </a-button>
@@ -26,7 +26,7 @@
 </template>
 
 <script lang="ts" setup>
-  import { ref, reactive, computed, watch, nextTick, createApp } from 'vue';
+  import { ref, reactive, computed, watch, nextTick, createApp,unref } from 'vue';
   import { Icon } from '/@/components/Icon';
   import { getToken } from '/@/utils/auth';
   import { uploadUrl } from '/@/api/common/api';
@@ -36,9 +36,8 @@
   import { useAttrs } from '/@/hooks/core/useAttrs';
   import { useDesign } from '/@/hooks/web/useDesign';
   import { UploadTypeEnum } from './upload.data';
-  import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
+  import { getFileAccessHttpUrl, getHeaders } from '/@/utils/common/compUtils';
   import UploadItemActions from './components/UploadItemActions.vue';
-  import { antPrefixCls } from '/@/settings/designSetting'
 
   const { createMessage, createConfirm } = useMessage();
   const { prefixCls } = useDesign('j-upload');
@@ -68,11 +67,11 @@
     removeConfirm: propTypes.bool.def(false),
     beforeUpload: propTypes.func,
     disabled: propTypes.bool.def(false),
+    // 替换前一个文件,用于超出最大数量依然允许上传
+    replaceLastOne: propTypes.bool.def(false),
   });
 
-  const headers = reactive({
-    'X-Access-Token': getToken(),
-  });
+  const headers = getHeaders();
   const fileList = ref<any[]>([]);
   const uploadGoOn = ref<boolean>(true);
   // refs
@@ -81,9 +80,26 @@
   const isMaxCount = computed(() => props.maxCount > 0 && fileList.value.length >= props.maxCount);
   // 当前是否是上传图片模式
   const isImageMode = computed(() => props.fileType === UploadTypeEnum.image);
+  // 上传按钮是否禁用
+  const buttonDisabled = computed(()=>{
+    if(props.disabled === true){
+      return true;
+    }
+    if(isMaxCount.value === true){
+      if(props.replaceLastOne === true){
+        return false
+      }else{
+        return true;
+      }
+    }
+    return false
+  });
   // 合并 props 和 attrs
   const bindProps = computed(() => {
-    const bind: any = Object.assign({}, props, attrs);
+    //update-begin-author:liusq date:20220411 for: [issue/455]上传组件传入accept限制上传文件类型无效
+    const bind: any = Object.assign({}, props, unref(attrs));
+    //update-end-author:liusq date:20220411 for: [issue/455]上传组件传入accept限制上传文件类型无效
+
     bind.name = 'file';
     bind.listType = isImageMode.value ? 'picture-card' : 'text';
     bind.class = [bind.class, { 'upload-disabled': props.disabled }];
@@ -110,7 +126,13 @@
           parseArrayValue(val);
         }
       } else {
-        parsePathsValue(val);
+        //update-begin---author:liusq ---date:20230914  for:[issues/5327]Upload组件returnUrl为false时上传的字段值返回了一个'[object Object]' ------------
+        if (props.returnUrl) {
+          parsePathsValue(val);
+        } else {
+          val && parseArrayValue(JSON.parse(val));
+        }
+        //update-end---author:liusq ---date:20230914  for:[issues/5327]Upload组件returnUrl为false时上传的字段值返回了一个'[object Object]' ------------
       }
     },
     { immediate: true }
@@ -118,7 +140,7 @@
 
   watch(fileList, () => nextTick(() => addActionsListener()), { immediate: true });
 
-  const antUploadItemCls = `${antPrefixCls}-upload-list-item`;
+  const antUploadItemCls = 'ant-upload-list-item';
 
   // Listener
   function addActionsListener() {
@@ -264,15 +286,22 @@
       }
     }
     if (info.file.status === 'done') {
+      let successFileList = [];
       if (info.file.response.success) {
-        fileListTemp = fileListTemp.map((file) => {
+        successFileList = fileListTemp.map((file) => {
           if (file.response) {
             let reUrl = file.response.message;
             file.url = getFileAccessHttpUrl(reUrl);
           }
           return file;
         });
+      }else{
+        successFileList = fileListTemp.filter(item=>{
+          return item.uid!=info.file.uid;
+        });
+        createMessage.error(`${info.file.name} 上传失败.`);
       }
+      fileListTemp = successFileList;
     } else if (info.file.status === 'error') {
       createMessage.error(`${info.file.name} 上传失败.`);
     }
@@ -292,11 +321,13 @@
               fileSize: item.size,
             };
             newFileList.push(fileJson);
-          } else {
+          }else{
             return;
           }
         }
-        emitValue(newFileList);
+        //update-begin---author:liusq ---date:20230914  for:[issues/5327]Upload组件returnUrl为false时上传的字段值返回了一个'[object Object]' ------------
+        emitValue(JSON.stringify(newFileList));
+        //update-end---author:liusq ---date:20230914  for:[issues/5327]Upload组件returnUrl为false时上传的字段值返回了一个'[object Object]' ------------
       }
     }
   }

+ 8 - 3
src/components/Form/src/jeecg/components/modal/DeptSelectModal.vue

@@ -11,6 +11,7 @@
         @check="onCheck"
         :fieldNames="fieldNames"
         :checkedKeys="checkedKeys"
+        :multiple="multiple"
         :checkStrictly="getCheckStrictly"
       />
       <!--树操作部分-->
@@ -39,6 +40,7 @@
   import { BasicTree, TreeActionType } from '/@/components/Tree';
   import { useTreeBiz } from '/@/components/Form/src/jeecg/hooks/useTreeBiz';
   import {propTypes} from "/@/utils/propTypes";
+  import { omit } from 'lodash-es';
 
   export default defineComponent({
     name: 'DeptSelectModal',
@@ -64,12 +66,15 @@
       
       //update-begin-author:taoyan date:2022-10-28 for: 部门选择警告类型不匹配
       let propValue = props.value === ''?[]:props.value;
-      const getBindValue = Object.assign({}, unref(props), unref(attrs), {value: propValue});
-      //update-end-author:taoyan date:2022-10-28 for: 部门选择警告类型不匹配
+      //update-begin-author:liusq date:2023-05-26 for:  [issues/538]JSelectDept组件受 dynamicDisabled 影响
+      let temp = Object.assign({}, unref(props), unref(attrs), {value: propValue},{disabled: false});
+      const getBindValue = omit(temp, 'multiple');
+      //update-end-author:liusq date:2023-05-26 for:  [issues/538]JSelectDept组件受 dynamicDisabled 影响
+     //update-end-author:taoyan date:2022-10-28 for: 部门选择警告类型不匹配
       
       const queryUrl = getQueryUrl();
       const [{ visibleChange, checkedKeys, getCheckStrictly, getSelectTreeData, onCheck, onLoadData, treeData, checkALL, expandAll, onSelect }] =
-        useTreeBiz(treeRef, queryUrl, getBindValue);
+        useTreeBiz(treeRef, queryUrl, getBindValue, props);
       const searchInfo = ref(props.params);
       const tree = ref([]);
       //替换treeNode中key字段为treeData中对应的字段

部分文件因文件數量過多而無法顯示