Commit 32986ca284e3e34774c64586a1978b0dc60b0f65

Authored by YunaiV
2 parents f390f1b1 7cabf0ea

Merge remote-tracking branch 'origin/feature/vue3' into feature/vue3

Showing 51 changed files with 1174 additions and 1234 deletions
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/handler/GlobalExceptionHandler.java
... ... @@ -168,12 +168,6 @@ public class GlobalExceptionHandler {
168 168 */
169 169 @ExceptionHandler(NoHandlerFoundException.class)
170 170 public CommonResult<?> noHandlerFoundExceptionHandler(HttpServletRequest req, NoHandlerFoundException ex) {
171   - // 情况一:部分功能未开启
172   - if (req.getRequestURI().contains("/bpm/")) {
173   - return CommonResult.error(NOT_IMPLEMENTED.getCode(), "[工作流模块 yudao-module-bpm - 已禁用][参考 https://doc.iocoder.cn/bpm/ 开启]");
174   - }
175   -
176   - // 情况二:正常情况下的 404
177 171 log.warn("[noHandlerFoundExceptionHandler]", ex);
178 172 return CommonResult.error(NOT_FOUND.getCode(), String.format("请求地址不存在:%s", ex.getRequestURL()));
179 173 }
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/data.ts.vm
... ... @@ -21,71 +21,78 @@ const crudSchemas = reactive&lt;VxeCrudSchema&gt;({
21 21 action: true,
22 22 actionWidth: '200', // 3个按钮默认200,如有删减对应增减即可
23 23 columns: [
24   -#foreach($column in $columns)
25   - #if ($column.listOperation || $column.listOperationResult || $column.createOperation || $column.updateOperation)
26   - #set ($dictType = $column.dictType)
27   - #if(!$column.primaryKey)
28   - {
29   - title: '${column.columnComment}',
30   - field: '${column.javaField}',
31   - #if ("" != $dictType)## 有数据字典
32   - dictType: DICT_TYPE.$dictType.toUpperCase(),
33   - #end
34   - #if (!$column.createOperation && !$column.updateOperation)
35   - isForm: false
36   - #elseif(!("" != $column.dictType))
37   - #if ($column.htmlType == "datetime")## 时间框
38   - form: {
39   - show: true,
40   - component: 'DatePicker',
41   - componentProps: {
42   - type: 'datetime',
43   - valueFormat: 'YYYY-MM-DD HH:mm:ss'
44   - }
45   - }
46   - #elseif($column.htmlType == "editor")## 文本编辑器
47   - form: {
48   - show: true,
49   - component: 'Editor',
50   - colProps: {
51   - span: 24
  24 + #foreach($column in $columns)
  25 + #if ($column.listOperation || $column.listOperationResult || $column.createOperation || $column.updateOperation)
  26 + #set ($dictType = $column.dictType)
  27 + #if(!$column.primaryKey)
  28 + {
  29 + title: '${column.columnComment}',
  30 + field: '${column.javaField}',
  31 + #if ("" != $dictType)## 有数据字典
  32 + dictType: DICT_TYPE.$dictType.toUpperCase(),
  33 + #if (${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer")
  34 + dictData: 'number',
  35 + #else
  36 + dictData: 'string',
  37 + #end
  38 + #end
  39 + #if (!$column.createOperation && !$column.updateOperation)
  40 + isForm: false,
  41 + #elseif(!("" != $column.dictType))
  42 + #if ($column.htmlType == "datetime")## 时间框
  43 + form: {
  44 + component: 'DatePicker',
  45 + componentProps: {
  46 + type: 'datetime',
  47 + valueFormat: 'YYYY-MM-DD HH:mm:ss'
  48 + }
52 49 },
53   - componentProps: {
54   - valueHtml: ''
55   - }
56   - }
57   - #elseif($column.htmlType == "textarea")## 文本框
58   - form: {
59   - show: true,
60   - component: 'Input',
61   - componentProps: {
62   - type: 'textarea',
63   - rows: 4
  50 + #elseif($column.htmlType == "editor")## 文本编辑器
  51 + form: {
  52 + component: 'Editor',
  53 + colProps: {
  54 + span: 24
  55 + },
  56 + componentProps: {
  57 + valueHtml: ''
  58 + }
64 59 },
65   - colProps: {
66   - span: 24
67   - }
68   - }
69   - #end
70   - #end
71   - #if ($column.listOperationResult)
72   - #if($column.htmlType == "input")
73   - isSearch: true
74   - #elseif("" != $dictType)
75   - isSearch: true
76   - #elseif($column.htmlType == "datetime")
77   - search: {
78   - show: true,
79   - itemRender: {
80   - name: 'XDataTimePicker'
81   - }
82   - }
83   - #end
84   - #end
  60 + #elseif($column.htmlType == "textarea")## 文本框
  61 + form: {
  62 + component: 'Input',
  63 + componentProps: {
  64 + type: 'textarea',
  65 + rows: 4
  66 + },
  67 + colProps: {
  68 + span: 24
  69 + }
  70 + },
  71 + #elseif(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer")## 数字类型
  72 + form: {
  73 + component: 'InputNumber',
  74 + value: 0
  75 + },
  76 + #end
  77 + #end
  78 + #if ($column.listOperationResult)
  79 + #if($column.htmlType == "input")
  80 + isSearch: true,
  81 + #elseif("" != $dictType)
  82 + isSearch: true,
  83 + #elseif($column.htmlType == "datetime")
  84 + search: {
  85 + show: true,
  86 + itemRender: {
  87 + name: 'XDataTimePicker'
  88 + }
  89 + },
  90 + #end
  91 + #end
  92 + #end
  93 + },
85 94 #end
86   - },
87 95 #end
88   -#end
89 96 ]
90 97 })
91 98 export const { allSchemas } = useVxeCrudSchemas(crudSchemas)
92 99 \ No newline at end of file
... ...
yudao-server/src/main/java/cn/iocoder/yudao/server/controller/DefaultController.java 0 → 100644
  1 +package cn.iocoder.yudao.server.controller;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import org.springframework.web.bind.annotation.RequestMapping;
  5 +import org.springframework.web.bind.annotation.RestController;
  6 +
  7 +import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.NOT_IMPLEMENTED;
  8 +
  9 +/**
  10 + * 默认 Controller,解决部分 module 未开启时的 404 提示。
  11 + * 例如说,/bpm/** 路径,工作流
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@RestController
  16 +public class DefaultController {
  17 +
  18 + @RequestMapping("/admin-api/bpm/**")
  19 + public CommonResult<Boolean> bpm404() {
  20 + return CommonResult.error(NOT_IMPLEMENTED.getCode(),
  21 + "[工作流模块 yudao-module-bpm - 已禁用][参考 https://doc.iocoder.cn/bpm/ 开启]");
  22 + }
  23 +
  24 +}
... ...
yudao-server/src/main/resources/application.yaml
... ... @@ -17,8 +17,8 @@ spring:
17 17 mvc:
18 18 pathmatch:
19 19 matching-strategy: ANT_PATH_MATCHER # 解决 SpringFox 与 SpringBoot 2.6.x 不兼容的问题,参见 SpringFoxHandlerProviderBeanPostProcessor 类
20   - throw-exception-if-no-handler-found: true # 404 错误时抛出异常,方便统一处理
21   - static-path-pattern: /static/** # 静态资源路径; 注意:如果不配置,则 throw-exception-if-no-handler-found 不生效!!!
  20 +# throw-exception-if-no-handler-found: true # 404 错误时抛出异常,方便统一处理
  21 +# static-path-pattern: /static/** # 静态资源路径; 注意:如果不配置,则 throw-exception-if-no-handler-found 不生效!!! TODO 芋艿:不能配置,会导致 swagger 不生效
22 22  
23 23 # Jackson 配置项
24 24 jackson:
... ...
yudao-ui-admin-vue3/package.json
1 1 {
2 2 "name": "ruoyi-vue-pro-vue3",
3   - "version": "1.6.4.1841",
  3 + "version": "1.6.4.1851",
4 4 "description": "基于vue3、vite3、element-plus、typesScript",
5 5 "author": "xingyu",
6 6 "private": false,
... ... @@ -43,7 +43,7 @@
43 43 "lodash-es": "^4.17.21",
44 44 "mitt": "^3.0.0",
45 45 "nprogress": "^0.2.0",
46   - "pinia": "^2.0.23",
  46 + "pinia": "^2.0.24",
47 47 "qrcode": "^1.5.1",
48 48 "qs": "^6.11.0",
49 49 "url": "^0.11.0",
... ... @@ -59,7 +59,7 @@
59 59 "devDependencies": {
60 60 "@commitlint/cli": "^17.2.0",
61 61 "@commitlint/config-conventional": "^17.2.0",
62   - "@iconify/json": "^2.1.138",
  62 + "@iconify/json": "^2.1.139",
63 63 "@intlify/vite-plugin-vue-i18n": "^6.0.3",
64 64 "@purge-icons/generated": "^0.9.0",
65 65 "@types/intro.js": "^5.1.0",
... ... @@ -95,7 +95,7 @@
95 95 "stylelint-order": "^5.0.0",
96 96 "typescript": "4.8.4",
97 97 "unplugin-vue-macros": "^0.16.3",
98   - "vite": "3.2.3",
  98 + "vite": "3.2.4",
99 99 "vite-plugin-compression": "^0.5.1",
100 100 "vite-plugin-eslint": "^1.8.1",
101 101 "vite-plugin-html": "^3.2.0",
... ...
yudao-ui-admin-vue3/pnpm-lock.yaml
... ... @@ -4,7 +4,7 @@ specifiers:
4 4 '@commitlint/cli': ^17.2.0
5 5 '@commitlint/config-conventional': ^17.2.0
6 6 '@iconify/iconify': ^3.0.0
7   - '@iconify/json': ^2.1.138
  7 + '@iconify/json': ^2.1.139
8 8 '@intlify/vite-plugin-vue-i18n': ^6.0.3
9 9 '@purge-icons/generated': ^0.9.0
10 10 '@types/intro.js': ^5.1.0
... ... @@ -42,7 +42,7 @@ specifiers:
42 42 lodash-es: ^4.17.21
43 43 mitt: ^3.0.0
44 44 nprogress: ^0.2.0
45   - pinia: ^2.0.23
  45 + pinia: ^2.0.24
46 46 plop: ^3.1.1
47 47 postcss: ^8.4.19
48 48 postcss-html: ^1.5.0
... ... @@ -61,7 +61,7 @@ specifiers:
61 61 typescript: 4.8.4
62 62 unplugin-vue-macros: ^0.16.3
63 63 url: ^0.11.0
64   - vite: 3.2.3
  64 + vite: 3.2.4
65 65 vite-plugin-compression: ^0.5.1
66 66 vite-plugin-eslint: ^1.8.1
67 67 vite-plugin-html: ^3.2.0
... ... @@ -99,7 +99,7 @@ dependencies:
99 99 lodash-es: 4.17.21
100 100 mitt: 3.0.0
101 101 nprogress: 0.2.0
102   - pinia: 2.0.23_zwu2zepfy3m6u2gunxlolp35gi
  102 + pinia: 2.0.24_zwu2zepfy3m6u2gunxlolp35gi
103 103 qrcode: 1.5.1
104 104 qs: 6.11.0
105 105 url: 0.11.0
... ... @@ -115,8 +115,8 @@ dependencies:
115 115 devDependencies:
116 116 '@commitlint/cli': 17.2.0
117 117 '@commitlint/config-conventional': 17.2.0
118   - '@iconify/json': 2.1.138
119   - '@intlify/vite-plugin-vue-i18n': 6.0.3_vite@3.2.3+vue-i18n@9.2.2
  118 + '@iconify/json': 2.1.139
  119 + '@intlify/vite-plugin-vue-i18n': 6.0.3_vite@3.2.4+vue-i18n@9.2.2
120 120 '@purge-icons/generated': 0.9.0
121 121 '@types/intro.js': 5.1.0
122 122 '@types/lodash-es': 4.17.6
... ... @@ -126,8 +126,8 @@ devDependencies:
126 126 '@types/qs': 6.9.7
127 127 '@typescript-eslint/eslint-plugin': 5.43.0_yy4vf4gcvxiubmg7fqa55dqe2i
128 128 '@typescript-eslint/parser': 5.43.0_rmayb2veg2btbq6mbmnyivgasy
129   - '@vitejs/plugin-vue': 3.2.0_vite@3.2.3+vue@3.2.45
130   - '@vitejs/plugin-vue-jsx': 2.1.1_vite@3.2.3+vue@3.2.45
  129 + '@vitejs/plugin-vue': 3.2.0_vite@3.2.4+vue@3.2.45
  130 + '@vitejs/plugin-vue-jsx': 2.1.1_vite@3.2.4+vue@3.2.45
131 131 autoprefixer: 10.4.13_postcss@8.4.19
132 132 eslint: 8.27.0
133 133 eslint-config-prettier: 8.5.0_eslint@8.27.0
... ... @@ -150,15 +150,15 @@ devDependencies:
150 150 stylelint-config-standard: 29.0.0_stylelint@14.15.0
151 151 stylelint-order: 5.0.0_stylelint@14.15.0
152 152 typescript: 4.8.4
153   - unplugin-vue-macros: 0.16.3_mghlipbkxnxld5kp6aysmuv2fa
154   - vite: 3.2.3_mp5lu76ee5qtwstsyca37sdhqi
155   - vite-plugin-compression: 0.5.1_vite@3.2.3
156   - vite-plugin-eslint: 1.8.1_eslint@8.27.0+vite@3.2.3
157   - vite-plugin-html: 3.2.0_vite@3.2.3
158   - vite-plugin-purge-icons: 0.9.1_vite@3.2.3
159   - vite-plugin-style-import: 2.0.0_vite@3.2.3
160   - vite-plugin-svg-icons: 2.0.1_vite@3.2.3
161   - vite-plugin-windicss: 1.8.8_vite@3.2.3
  153 + unplugin-vue-macros: 0.16.3_drqowttw7xgwfzqyhu6wuedde4
  154 + vite: 3.2.4_mp5lu76ee5qtwstsyca37sdhqi
  155 + vite-plugin-compression: 0.5.1_vite@3.2.4
  156 + vite-plugin-eslint: 1.8.1_eslint@8.27.0+vite@3.2.4
  157 + vite-plugin-html: 3.2.0_vite@3.2.4
  158 + vite-plugin-purge-icons: 0.9.1_vite@3.2.4
  159 + vite-plugin-style-import: 2.0.0_vite@3.2.4
  160 + vite-plugin-svg-icons: 2.0.1_vite@3.2.4
  161 + vite-plugin-windicss: 1.8.8_vite@3.2.4
162 162 vue-tsc: 1.0.9_typescript@4.8.4
163 163 windicss: 3.5.6
164 164  
... ... @@ -574,11 +574,11 @@ packages:
574 574 '@types/node': 14.18.31
575 575 chalk: 4.1.2
576 576 cosmiconfig: 7.0.1
577   - cosmiconfig-typescript-loader: 4.1.1_gpl3msxjb2n3qdkii2jvdrcxxe
  577 + cosmiconfig-typescript-loader: 4.1.1_kjtesrzmdzjxgbmvhf7rq2qmfi
578 578 lodash: 4.17.21
579 579 resolve-from: 5.0.0
580   - ts-node: 10.9.1_fk6arlf3j7tudlucddpzvj2plq
581   - typescript: 4.8.4
  580 + ts-node: 10.9.1_zdwmxzc3s32eishk7hircltqdy
  581 + typescript: 4.9.3
582 582 transitivePeerDependencies:
583 583 - '@swc/core'
584 584 - '@swc/wasm'
... ... @@ -760,8 +760,8 @@ packages:
760 760 dependencies:
761 761 '@iconify/types': 2.0.0
762 762  
763   - /@iconify/json/2.1.138:
764   - resolution: {integrity: sha512-migiXo9NKjkc3ob3qRzjdfecyFo39eziD9IY+LbNooQwyU8CS+WoeNtoI34Sf2+3DrV69H0kxeLf3bFQ+nKvew==}
  763 + /@iconify/json/2.1.139:
  764 + resolution: {integrity: sha512-H/DQ/yVgdUk4x4hU696fy0mZOkvLQaR6REQU/okFLgaiIFOS+EWw6GV5JDSKbbkh0YVaxUrAUaqB8XTSFVrFeA==}
765 765 dependencies:
766 766 '@iconify/types': 2.0.0
767 767 pathe: 0.3.9
... ... @@ -829,7 +829,7 @@ packages:
829 829 engines: {node: '>= 14'}
830 830 dev: true
831 831  
832   - /@intlify/vite-plugin-vue-i18n/6.0.3_vite@3.2.3+vue-i18n@9.2.2:
  832 + /@intlify/vite-plugin-vue-i18n/6.0.3_vite@3.2.4+vue-i18n@9.2.2:
833 833 resolution: {integrity: sha512-6SgNzPAOCR90wvt368lKzi7f/5ZEWJn22UCGvhFsP3XvKqlF3cVzojahgQ6o+LTdCkExeM6wPgd+haFf28E9VQ==}
834 834 engines: {node: '>= 14.6'}
835 835 peerDependencies:
... ... @@ -850,7 +850,7 @@ packages:
850 850 debug: 4.3.4
851 851 fast-glob: 3.2.12
852 852 source-map: 0.6.1
853   - vite: 3.2.3_mp5lu76ee5qtwstsyca37sdhqi
  853 + vite: 3.2.4_mp5lu76ee5qtwstsyca37sdhqi
854 854 vue-i18n: 9.2.2_vue@3.2.45
855 855 transitivePeerDependencies:
856 856 - supports-color
... ... @@ -1263,7 +1263,7 @@ packages:
1263 1263 nanoid: 3.3.4
1264 1264 dev: false
1265 1265  
1266   - /@vitejs/plugin-vue-jsx/2.1.1_vite@3.2.3+vue@3.2.45:
  1266 + /@vitejs/plugin-vue-jsx/2.1.1_vite@3.2.4+vue@3.2.45:
1267 1267 resolution: {integrity: sha512-JgDhxstQlwnHBvZ1BSnU5mbmyQ14/t5JhREc6YH5kWyu2QdAAOsLF6xgHoIWarj8tddaiwFrNzLbWJPudpXKYA==}
1268 1268 engines: {node: ^14.18.0 || >=16.0.0}
1269 1269 peerDependencies:
... ... @@ -1273,20 +1273,20 @@ packages:
1273 1273 '@babel/core': 7.19.6
1274 1274 '@babel/plugin-transform-typescript': 7.20.2_@babel+core@7.19.6
1275 1275 '@vue/babel-plugin-jsx': 1.1.1_@babel+core@7.19.6
1276   - vite: 3.2.3_mp5lu76ee5qtwstsyca37sdhqi
  1276 + vite: 3.2.4_mp5lu76ee5qtwstsyca37sdhqi
1277 1277 vue: 3.2.45
1278 1278 transitivePeerDependencies:
1279 1279 - supports-color
1280 1280 dev: true
1281 1281  
1282   - /@vitejs/plugin-vue/3.2.0_vite@3.2.3+vue@3.2.45:
  1282 + /@vitejs/plugin-vue/3.2.0_vite@3.2.4+vue@3.2.45:
1283 1283 resolution: {integrity: sha512-E0tnaL4fr+qkdCNxJ+Xd0yM31UwMkQje76fsDVBBUCoGOUPexu2VDUYHL8P4CwV+zMvWw6nlRw19OnRKmYAJpw==}
1284 1284 engines: {node: ^14.18.0 || >=16.0.0}
1285 1285 peerDependencies:
1286 1286 vite: ^3.0.0
1287 1287 vue: ^3.2.25
1288 1288 dependencies:
1289   - vite: 3.2.3_mp5lu76ee5qtwstsyca37sdhqi
  1289 + vite: 3.2.4_mp5lu76ee5qtwstsyca37sdhqi
1290 1290 vue: 3.2.45
1291 1291 dev: true
1292 1292  
... ... @@ -1418,16 +1418,16 @@ packages:
1418 1418 unplugin: 0.10.2
1419 1419 dev: true
1420 1420  
1421   - /@vue-macros/named-template/0.0.5_poefzxy2vtculed3kqru6isufm:
  1421 + /@vue-macros/named-template/0.0.5_ygspmtsr7jejaf6wke2f4dns5a:
1422 1422 resolution: {integrity: sha512-bZRUljNyvOOqeE9dyqXvKPQCLUCcPt1EkThmXqSbxagV29ohyviF8+CCs/8OdmNygLTBIChjP8DexQ3nUIFzUg==}
1423 1423 engines: {node: '>=14.19.0'}
1424 1424 dependencies:
1425 1425 '@rollup/pluginutils': 4.2.1
1426   - '@vitejs/plugin-vue': 3.2.0_vite@3.2.3+vue@3.2.45
  1426 + '@vitejs/plugin-vue': 3.2.0_vite@3.2.4+vue@3.2.45
1427 1427 '@vue-macros/common': 0.13.3
1428 1428 '@vue/compiler-dom': 3.2.45
1429 1429 unplugin: 0.10.2
1430   - unplugin-combine: 0.2.8_rollup@3.3.0+vite@3.2.3
  1430 + unplugin-combine: 0.2.8_rollup@3.3.0+vite@3.2.4
1431 1431 transitivePeerDependencies:
1432 1432 - esbuild
1433 1433 - rollup
... ... @@ -1436,14 +1436,14 @@ packages:
1436 1436 - webpack
1437 1437 dev: true
1438 1438  
1439   - /@vue-macros/setup-component/0.12.7_rollup@3.3.0+vite@3.2.3:
  1439 + /@vue-macros/setup-component/0.12.7_rollup@3.3.0+vite@3.2.4:
1440 1440 resolution: {integrity: sha512-L0WkJgw0QDwZh4tOjjKIDR0DMIybiOunsaxVqkJjicTb2YaiRUSLq4Wadl8Ttrsd0IEfI51CSlg7Sx0/dKLrlQ==}
1441 1441 engines: {node: '>=14.19.0'}
1442 1442 dependencies:
1443 1443 '@rollup/pluginutils': 4.2.1
1444 1444 '@vue-macros/common': 0.13.3
1445 1445 unplugin: 0.10.2
1446   - unplugin-combine: 0.2.8_rollup@3.3.0+vite@3.2.3
  1446 + unplugin-combine: 0.2.8_rollup@3.3.0+vite@3.2.4
1447 1447 transitivePeerDependencies:
1448 1448 - esbuild
1449 1449 - rollup
... ... @@ -1565,10 +1565,6 @@ packages:
1565 1565 /@vue/devtools-api/6.4.3:
1566 1566 resolution: {integrity: sha512-9WCRwdROJvWcHAdyrR7SZMM/qUvllDZnpndHXokThkUsjnJ2xe4/pvsH9FZrxFe22L+JmDKczL79HjLJ7DK9rg==}
1567 1567  
1568   - /@vue/devtools-api/6.4.4:
1569   - resolution: {integrity: sha512-Ku31WzpOV/8cruFaXaEZKF81WkNnvCSlBY4eOGtz5WMSdJvX1v1WWlSMGZeqUwPtQ27ZZz7B62erEMq8JDjcXw==}
1570   - dev: false
1571   -
1572 1568 /@vue/devtools-api/6.4.5:
1573 1569 resolution: {integrity: sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ==}
1574 1570 dev: false
... ... @@ -2615,7 +2611,7 @@ packages:
2615 2611 vary: 1.1.2
2616 2612 dev: true
2617 2613  
2618   - /cosmiconfig-typescript-loader/4.1.1_gpl3msxjb2n3qdkii2jvdrcxxe:
  2614 + /cosmiconfig-typescript-loader/4.1.1_kjtesrzmdzjxgbmvhf7rq2qmfi:
2619 2615 resolution: {integrity: sha512-9DHpa379Gp0o0Zefii35fcmuuin6q92FnLDffzdZ0l9tVd3nEobG3O+MZ06+kuBvFTSVScvNb/oHA13Nd4iipg==}
2620 2616 engines: {node: '>=12', npm: '>=6'}
2621 2617 peerDependencies:
... ... @@ -2626,8 +2622,8 @@ packages:
2626 2622 dependencies:
2627 2623 '@types/node': 14.18.31
2628 2624 cosmiconfig: 7.0.1
2629   - ts-node: 10.9.1_fk6arlf3j7tudlucddpzvj2plq
2630   - typescript: 4.8.4
  2625 + ts-node: 10.9.1_zdwmxzc3s32eishk7hircltqdy
  2626 + typescript: 4.9.3
2631 2627 dev: true
2632 2628  
2633 2629 /cosmiconfig/7.0.1:
... ... @@ -5564,8 +5560,8 @@ packages:
5564 5560 dev: true
5565 5561 optional: true
5566 5562  
5567   - /pinia/2.0.23_zwu2zepfy3m6u2gunxlolp35gi:
5568   - resolution: {integrity: sha512-N15hFf4o5STrxpNrib1IEb1GOArvPYf1zPvQVRGOO1G1d74Ak0J0lVyalX/SmrzdT4Q0nlEFjbURsmBmIGUR5Q==}
  5563 + /pinia/2.0.24_zwu2zepfy3m6u2gunxlolp35gi:
  5564 + resolution: {integrity: sha512-DDLd4Iphyc+6PYYYbx7jkb6WP9gecgu9bz9huyB5rb7CdJI3DhzYiZI+/Ih8MLewRrP9DSpslF/BgSNrJtZU7A==}
5569 5565 peerDependencies:
5570 5566 '@vue/composition-api': ^1.4.0
5571 5567 typescript: '>=4.4.4'
... ... @@ -5576,7 +5572,7 @@ packages:
5576 5572 typescript:
5577 5573 optional: true
5578 5574 dependencies:
5579   - '@vue/devtools-api': 6.4.4
  5575 + '@vue/devtools-api': 6.4.5
5580 5576 typescript: 4.8.4
5581 5577 vue: 3.2.45
5582 5578 vue-demi: 0.13.11_vue@3.2.45
... ... @@ -6673,7 +6669,7 @@ packages:
6673 6669 engines: {node: '>=8'}
6674 6670 dev: true
6675 6671  
6676   - /ts-node/10.9.1_fk6arlf3j7tudlucddpzvj2plq:
  6672 + /ts-node/10.9.1_zdwmxzc3s32eishk7hircltqdy:
6677 6673 resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
6678 6674 hasBin: true
6679 6675 peerDependencies:
... ... @@ -6699,7 +6695,7 @@ packages:
6699 6695 create-require: 1.1.1
6700 6696 diff: 4.0.2
6701 6697 make-error: 1.3.6
6702   - typescript: 4.8.4
  6698 + typescript: 4.9.3
6703 6699 v8-compile-cache-lib: 3.0.1
6704 6700 yn: 3.1.1
6705 6701 dev: true
... ... @@ -6771,6 +6767,12 @@ packages:
6771 6767 engines: {node: '>=4.2.0'}
6772 6768 hasBin: true
6773 6769  
  6770 + /typescript/4.9.3:
  6771 + resolution: {integrity: sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==}
  6772 + engines: {node: '>=4.2.0'}
  6773 + hasBin: true
  6774 + dev: true
  6775 +
6774 6776 /uglify-js/3.17.3:
6775 6777 resolution: {integrity: sha512-JmMFDME3iufZnBpyKL+uS78LRiC+mK55zWfM5f/pWBJfpOttXAqYfdDGRukYhJuyRinvPVAtUhvy7rlDybNtFg==}
6776 6778 engines: {node: '>=0.8.0'}
... ... @@ -6799,7 +6801,7 @@ packages:
6799 6801 engines: {node: '>= 10.0.0'}
6800 6802 dev: true
6801 6803  
6802   - /unplugin-combine/0.2.8_rollup@3.3.0+vite@3.2.3:
  6804 + /unplugin-combine/0.2.8_rollup@3.3.0+vite@3.2.4:
6803 6805 resolution: {integrity: sha512-Z38AC/TEjXbVyZ5HjVqo+lADj0/dcfwWC0Z4y0LNhybJzJQwmcMxm+ZsqHY3faauj4YigmlRMdptR5JEW9RuLg==}
6804 6806 engines: {node: '>=14.19.0'}
6805 6807 peerDependencies:
... ... @@ -6820,7 +6822,7 @@ packages:
6820 6822 '@antfu/utils': 0.6.0
6821 6823 rollup: 3.3.0
6822 6824 unplugin: 0.10.2
6823   - vite: 3.2.3_mp5lu76ee5qtwstsyca37sdhqi
  6825 + vite: 3.2.4_mp5lu76ee5qtwstsyca37sdhqi
6824 6826 dev: true
6825 6827  
6826 6828 /unplugin-vue-define-options/0.12.7:
... ... @@ -6833,7 +6835,7 @@ packages:
6833 6835 unplugin: 0.10.2
6834 6836 dev: true
6835 6837  
6836   - /unplugin-vue-macros/0.16.3_mghlipbkxnxld5kp6aysmuv2fa:
  6838 + /unplugin-vue-macros/0.16.3_drqowttw7xgwfzqyhu6wuedde4:
6837 6839 resolution: {integrity: sha512-ADdDS5EjHRZ2esEHSNBw7CS7QLWpqvNJIW0H5EqKgSvtQ+2Hnb8IeRVT0f4mR+wyQvl/ZrlpTs1GvZdsh8eSlw==}
6838 6840 engines: {node: '>=14.19.0'}
6839 6841 peerDependencies:
... ... @@ -6846,12 +6848,12 @@ packages:
6846 6848 '@vue-macros/define-render': 0.13.8_vue@3.2.45
6847 6849 '@vue-macros/define-slots': 0.0.5_vue@3.2.45
6848 6850 '@vue-macros/hoist-static': 0.12.7
6849   - '@vue-macros/named-template': 0.0.5_poefzxy2vtculed3kqru6isufm
6850   - '@vue-macros/setup-component': 0.12.7_rollup@3.3.0+vite@3.2.3
  6851 + '@vue-macros/named-template': 0.0.5_ygspmtsr7jejaf6wke2f4dns5a
  6852 + '@vue-macros/setup-component': 0.12.7_rollup@3.3.0+vite@3.2.4
6851 6853 '@vue-macros/setup-sfc': 0.12.7
6852 6854 '@vue-macros/short-emits': 0.12.8
6853 6855 local-pkg: 0.4.2
6854   - unplugin-combine: 0.2.8_rollup@3.3.0+vite@3.2.3
  6856 + unplugin-combine: 0.2.8_rollup@3.3.0+vite@3.2.4
6855 6857 unplugin-vue-define-options: 0.12.7
6856 6858 vue: 3.2.45
6857 6859 transitivePeerDependencies:
... ... @@ -6954,7 +6956,7 @@ packages:
6954 6956 engines: {node: '>= 0.8'}
6955 6957 dev: true
6956 6958  
6957   - /vite-plugin-compression/0.5.1_vite@3.2.3:
  6959 + /vite-plugin-compression/0.5.1_vite@3.2.4:
6958 6960 resolution: {integrity: sha512-5QJKBDc+gNYVqL/skgFAP81Yuzo9R+EAf19d+EtsMF/i8kFUpNi3J/H01QD3Oo8zBQn+NzoCIFkpPLynoOzaJg==}
6959 6961 peerDependencies:
6960 6962 vite: '>=2.0.0'
... ... @@ -6962,12 +6964,12 @@ packages:
6962 6964 chalk: 4.1.2
6963 6965 debug: 4.3.4
6964 6966 fs-extra: 10.1.0
6965   - vite: 3.2.3_mp5lu76ee5qtwstsyca37sdhqi
  6967 + vite: 3.2.4_mp5lu76ee5qtwstsyca37sdhqi
6966 6968 transitivePeerDependencies:
6967 6969 - supports-color
6968 6970 dev: true
6969 6971  
6970   - /vite-plugin-eslint/1.8.1_eslint@8.27.0+vite@3.2.3:
  6972 + /vite-plugin-eslint/1.8.1_eslint@8.27.0+vite@3.2.4:
6971 6973 resolution: {integrity: sha512-PqdMf3Y2fLO9FsNPmMX+//2BF5SF8nEWspZdgl4kSt7UvHDRHVVfHvxsD7ULYzZrJDGRxR81Nq7TOFgwMnUang==}
6972 6974 peerDependencies:
6973 6975 eslint: '>=7'
... ... @@ -6977,10 +6979,10 @@ packages:
6977 6979 '@types/eslint': 8.4.6
6978 6980 eslint: 8.27.0
6979 6981 rollup: 2.79.1
6980   - vite: 3.2.3_mp5lu76ee5qtwstsyca37sdhqi
  6982 + vite: 3.2.4_mp5lu76ee5qtwstsyca37sdhqi
6981 6983 dev: true
6982 6984  
6983   - /vite-plugin-html/3.2.0_vite@3.2.3:
  6985 + /vite-plugin-html/3.2.0_vite@3.2.4:
6984 6986 resolution: {integrity: sha512-2VLCeDiHmV/BqqNn5h2V+4280KRgQzCFN47cst3WiNK848klESPQnzuC3okH5XHtgwHH/6s1Ho/YV6yIO0pgoQ==}
6985 6987 peerDependencies:
6986 6988 vite: '>=2.0.0'
... ... @@ -6997,10 +6999,10 @@ packages:
6997 6999 html-minifier-terser: 6.1.0
6998 7000 node-html-parser: 5.4.2
6999 7001 pathe: 0.2.0
7000   - vite: 3.2.3_mp5lu76ee5qtwstsyca37sdhqi
  7002 + vite: 3.2.4_mp5lu76ee5qtwstsyca37sdhqi
7001 7003 dev: true
7002 7004  
7003   - /vite-plugin-purge-icons/0.9.1_vite@3.2.3:
  7005 + /vite-plugin-purge-icons/0.9.1_vite@3.2.4:
7004 7006 resolution: {integrity: sha512-oS0Y9Iq6vGnTDVRzB8xJNhA/gGlyR0lfCICU6+9FRKdrO5PnT34fRjvd8YWEsegCrk91+w3GVZc0HJDj/dPp5Q==}
7005 7007 engines: {node: '>= 12'}
7006 7008 peerDependencies:
... ... @@ -7009,13 +7011,13 @@ packages:
7009 7011 '@purge-icons/core': 0.9.1
7010 7012 '@purge-icons/generated': 0.9.0
7011 7013 rollup-plugin-purge-icons: 0.9.1
7012   - vite: 3.2.3_mp5lu76ee5qtwstsyca37sdhqi
  7014 + vite: 3.2.4_mp5lu76ee5qtwstsyca37sdhqi
7013 7015 transitivePeerDependencies:
7014 7016 - encoding
7015 7017 - supports-color
7016 7018 dev: true
7017 7019  
7018   - /vite-plugin-style-import/2.0.0_vite@3.2.3:
  7020 + /vite-plugin-style-import/2.0.0_vite@3.2.4:
7019 7021 resolution: {integrity: sha512-qtoHQae5dSUQPo/rYz/8p190VU5y19rtBaeV7ryLa/AYAU/e9CG89NrN/3+k7MR8mJy/GPIu91iJ3zk9foUOSA==}
7020 7022 peerDependencies:
7021 7023 vite: '>=2.0.0'
... ... @@ -7027,10 +7029,10 @@ packages:
7027 7029 fs-extra: 10.1.0
7028 7030 magic-string: 0.25.9
7029 7031 pathe: 0.2.0
7030   - vite: 3.2.3_mp5lu76ee5qtwstsyca37sdhqi
  7032 + vite: 3.2.4_mp5lu76ee5qtwstsyca37sdhqi
7031 7033 dev: true
7032 7034  
7033   - /vite-plugin-svg-icons/2.0.1_vite@3.2.3:
  7035 + /vite-plugin-svg-icons/2.0.1_vite@3.2.4:
7034 7036 resolution: {integrity: sha512-6ktD+DhV6Rz3VtedYvBKKVA2eXF+sAQVaKkKLDSqGUfnhqXl3bj5PPkVTl3VexfTuZy66PmINi8Q6eFnVfRUmA==}
7035 7037 peerDependencies:
7036 7038 vite: '>=2.0.0'
... ... @@ -7043,12 +7045,12 @@ packages:
7043 7045 pathe: 0.2.0
7044 7046 svg-baker: 1.7.0
7045 7047 svgo: 2.8.0
7046   - vite: 3.2.3_mp5lu76ee5qtwstsyca37sdhqi
  7048 + vite: 3.2.4_mp5lu76ee5qtwstsyca37sdhqi
7047 7049 transitivePeerDependencies:
7048 7050 - supports-color
7049 7051 dev: true
7050 7052  
7051   - /vite-plugin-windicss/1.8.8_vite@3.2.3:
  7053 + /vite-plugin-windicss/1.8.8_vite@3.2.4:
7052 7054 resolution: {integrity: sha512-iyu+ZX0NmhNEUaLPv7xtC+EFRBpWMmw0nhd9a9upayfuNG/thwslKiQKmRB7U/dG0k/2oWLvPDvN/B9i7oRgSA==}
7053 7055 peerDependencies:
7054 7056 vite: ^2.0.1 || ^3.0.0
... ... @@ -7056,14 +7058,14 @@ packages:
7056 7058 '@windicss/plugin-utils': 1.8.8
7057 7059 debug: 4.3.4
7058 7060 kolorist: 1.6.0
7059   - vite: 3.2.3_mp5lu76ee5qtwstsyca37sdhqi
  7061 + vite: 3.2.4_mp5lu76ee5qtwstsyca37sdhqi
7060 7062 windicss: 3.5.6
7061 7063 transitivePeerDependencies:
7062 7064 - supports-color
7063 7065 dev: true
7064 7066  
7065   - /vite/3.2.3_mp5lu76ee5qtwstsyca37sdhqi:
7066   - resolution: {integrity: sha512-h8jl1TZ76eGs3o2dIBSsvXDLb1m/Ec1iej8ZMdz+PsaFUsftZeWe2CZOI3qogEsMNaywc17gu0q6cQDzh/weCQ==}
  7067 + /vite/3.2.4_mp5lu76ee5qtwstsyca37sdhqi:
  7068 + resolution: {integrity: sha512-Z2X6SRAffOUYTa+sLy3NQ7nlHFU100xwanq1WDwqaiFiCe+25zdxP1TfCS5ojPV2oDDcXudHIoPnI1Z/66B7Yw==}
7067 7069 engines: {node: ^14.18.0 || >=16.0.0}
7068 7070 hasBin: true
7069 7071 peerDependencies:
... ...
yudao-ui-admin-vue3/src/api/login/index.ts
... ... @@ -62,3 +62,12 @@ export const socialAuthRedirectApi = (type: string, redirectUri: string) =&gt; {
62 62 url: '/system/auth/social-auth-redirect?type=' + type + '&redirectUri=' + redirectUri
63 63 })
64 64 }
  65 +// 获取验证图片 以及token
  66 +export const getCodeApi = (data) => {
  67 + return request.postOriginal({ url: 'system/captcha/get', data })
  68 +}
  69 +
  70 +// 滑动或者点选验证
  71 +export const reqCheckApi = (data) => {
  72 + return request.postOriginal({ url: 'system/captcha/check', data })
  73 +}
... ...
yudao-ui-admin-vue3/src/api/system/dept/index.ts
1 1 import request from '@/config/axios'
2   -import type { DeptVO, DeptListReqVO } from './types'
  2 +export type DeptVO = {
  3 + id: number
  4 + name: string
  5 + parentId: number
  6 + status: number
  7 + sort: number
  8 + leaderUserId: number
  9 + phone: string
  10 + email: string
  11 +}
  12 +
  13 +export interface DeptPageReqVO {
  14 + name?: string
  15 + status?: number
  16 +}
3 17  
4 18 // 查询部门(精简)列表
5   -export const listSimpleDeptApi = () => {
6   - return request.get({ url: '/system/dept/list-all-simple' })
  19 +export const listSimpleDeptApi = async () => {
  20 + return await request.get({ url: '/system/dept/list-all-simple' })
7 21 }
8 22  
9 23 // 查询部门列表
10   -export const getDeptPageApi = (params: DeptListReqVO) => {
11   - return request.get({ url: '/system/dept/list', params })
  24 +export const getDeptPageApi = async (params: DeptPageReqVO) => {
  25 + return await request.get({ url: '/system/dept/list', params })
12 26 }
13 27  
14 28 // 查询部门详情
15   -export const getDeptApi = (id: number) => {
16   - return request.get({ url: '/system/dept/get?id=' + id })
  29 +export const getDeptApi = async (id: number) => {
  30 + return await request.get({ url: '/system/dept/get?id=' + id })
17 31 }
18 32  
19 33 // 新增部门
20   -export const createDeptApi = (data: DeptVO) => {
21   - return request.post({ url: '/system/dept/create', data: data })
  34 +export const createDeptApi = async (data: DeptVO) => {
  35 + return await request.post({ url: '/system/dept/create', data: data })
22 36 }
23 37  
24 38 // 修改部门
25   -export const updateDeptApi = (params: DeptVO) => {
26   - return request.put({ url: '/system/dept/update', data: params })
  39 +export const updateDeptApi = async (params: DeptVO) => {
  40 + return await request.put({ url: '/system/dept/update', data: params })
27 41 }
28 42  
29 43 // 删除部门
30   -export const deleteDeptApi = (id: number) => {
31   - return request.delete({ url: '/system/dept/delete?id=' + id })
  44 +export const deleteDeptApi = async (id: number) => {
  45 + return await request.delete({ url: '/system/dept/delete?id=' + id })
32 46 }
... ...
yudao-ui-admin-vue3/src/components/Crontab/src/Crontab.vue
1   -<!--
2   - * @Descripttion: cron规则生成器
3   - * @version: 1.0
4   - * @Author: sakuya
5   - * @Date: 2021年12月29日15:23:54
6   - * @LastEditors:
7   - * @LastEditTime:
8   --->
9 1 <script setup lang="ts">
10 2 import {
11 3 ElInput,
... ... @@ -520,7 +512,12 @@ const submit = () =&gt; {
520 512 <template>
521 513 <el-input v-model="defaultValue" v-bind="$attrs">
522 514 <template #append>
523   - <el-dropdown split-button trigger="click" @command="handleShortcuts">
  515 + <el-dropdown
  516 + split-button
  517 + type="text"
  518 + @command="handleShortcuts"
  519 + style="width: 35px; margin-left: 5px; margin-right: 2px"
  520 + >
524 521 生成器
525 522 <template #dropdown>
526 523 <el-dropdown-menu>
... ...
yudao-ui-admin-vue3/src/components/Form/src/Form.vue
... ... @@ -226,11 +226,7 @@ export default defineComponent({
226 226 vModel={formModel.value[item.field]}
227 227 {...(autoSetPlaceholder && setTextPlaceholder(item))}
228 228 {...setComponentProps(item)}
229   - style={
230   - item?.component === 'Input'
231   - ? { width: '189.5px', ...item.componentProps?.style }
232   - : { ...item.componentProps?.style }
233   - }
  229 + style={item.componentProps?.style}
234 230 {...(notRenderOptions.includes(item?.component as string) &&
235 231 item?.componentProps?.options
236 232 ? { options: item?.componentProps?.options || [] }
... ... @@ -258,8 +254,8 @@ export default defineComponent({
258 254 return renderRadioOptions(item)
259 255 case 'Checkbox':
260 256 case 'CheckboxButton':
261   - const { renderChcekboxOptions } = useRenderCheckbox()
262   - return renderChcekboxOptions(item)
  257 + const { renderCheckboxOptions } = useRenderCheckbox()
  258 + return renderCheckboxOptions(item)
263 259 default:
264 260 break
265 261 }
... ...
yudao-ui-admin-vue3/src/components/Form/src/components/useRenderCheckbox.tsx
... ... @@ -3,7 +3,7 @@ import { ElCheckbox, ElCheckboxButton } from &#39;element-plus&#39;
3 3 import { defineComponent } from 'vue'
4 4  
5 5 export const useRenderCheckbox = () => {
6   - const renderChcekboxOptions = (item: FormSchema) => {
  6 + const renderCheckboxOptions = (item: FormSchema) => {
7 7 // 如果有别名,就取别名
8 8 const labelAlias = item?.componentProps?.optionsAlias?.labelField
9 9 const valueAlias = item?.componentProps?.optionsAlias?.valueField
... ... @@ -13,14 +13,14 @@ export const useRenderCheckbox = () =&gt; {
13 13 return item?.componentProps?.options?.map((option) => {
14 14 const { ...other } = option
15 15 return (
16   - <Com label={option[labelAlias || 'value']} {...other}>
17   - {option[valueAlias || 'label']}
  16 + <Com {...other} label={option[valueAlias || 'value']}>
  17 + {option[labelAlias || 'label']}
18 18 </Com>
19 19 )
20 20 })
21 21 }
22 22  
23 23 return {
24   - renderChcekboxOptions
  24 + renderCheckboxOptions
25 25 }
26 26 }
... ...
yudao-ui-admin-vue3/src/components/Form/src/components/useRenderRadio.tsx
... ... @@ -13,8 +13,8 @@ export const useRenderRadio = () =&gt; {
13 13 return item?.componentProps?.options?.map((option) => {
14 14 const { ...other } = option
15 15 return (
16   - <Com label={option[labelAlias || 'value']} {...other}>
17   - {option[valueAlias || 'label']}
  16 + <Com {...other} label={option[valueAlias || 'value']}>
  17 + {option[labelAlias || 'label']}
18 18 </Com>
19 19 )
20 20 })
... ...
yudao-ui-admin-vue3/src/components/Form/src/components/useRenderSelect.tsx
... ... @@ -36,9 +36,9 @@ export const useRenderSelect = (slots: Slots) =&gt; {
36 36  
37 37 return (
38 38 <ElOption
  39 + {...other}
39 40 label={labelAlias ? option[labelAlias] : label}
40 41 value={valueAlias ? option[valueAlias] : value}
41   - {...other}
42 42 >
43 43 {{
44 44 default: () =>
... ...
yudao-ui-admin-vue3/src/components/Verifition/src/Verify.vue
... ... @@ -2,7 +2,7 @@
2 2 <div :class="mode == 'pop' ? 'mask' : ''" v-show="showBox">
3 3 <div
4 4 :class="mode == 'pop' ? 'verifybox' : ''"
5   - :style="{ 'max-width': parseInt(imgSize.width) + 30 + 'px' }"
  5 + :style="{ 'max-width': parseInt(imgSize.width) + 20 + 'px' }"
6 6 >
7 7 <div class="verifybox-top" v-if="mode == 'pop'">
8 8 {{ t('captcha.verification') }}
... ... @@ -10,7 +10,7 @@
10 10 <i class="iconfont icon-close"></i>
11 11 </span>
12 12 </div>
13   - <div class="verifybox-bottom" :style="{ padding: mode == 'pop' ? '15px' : '0' }">
  13 + <div class="verifybox-bottom" :style="{ padding: mode == 'pop' ? '10px' : '0' }">
14 14 <!-- 验证码容器 -->
15 15 <component
16 16 v-if="componentType"
... ... @@ -153,12 +153,13 @@ export default {
153 153 box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
154 154 left: 50%;
155 155 top: 50%;
  156 + border-radius: 5px;
156 157 transform: translate(-50%, -50%);
157 158 }
158 159 .verifybox-top {
159 160 padding: 0 15px;
160   - height: 50px;
161   - line-height: 50px;
  161 + height: 40px;
  162 + line-height: 40px;
162 163 text-align: left;
163 164 font-size: 16px;
164 165 color: #45494c;
... ... @@ -166,7 +167,7 @@ export default {
166 167 box-sizing: border-box;
167 168 }
168 169 .verifybox-bottom {
169   - padding: 15px;
  170 + padding: 10px;
170 171 box-sizing: border-box;
171 172 }
172 173 .verifybox-close {
... ... @@ -262,6 +263,7 @@ export default {
262 263 color: #ffffff;
263 264 border: none;
264 265 margin-top: 10px;
  266 + border-radius: 8px;
265 267 }
266 268  
267 269 /*滑动验证码*/
... ... @@ -273,6 +275,7 @@ export default {
273 275 -moz-box-sizing: content-box;
274 276 box-sizing: content-box;
275 277 border: 1px solid #ddd;
  278 + border-radius: 8px;
276 279 }
277 280  
278 281 .verify-bar-area .verify-move-block {
... ... @@ -285,6 +288,7 @@ export default {
285 288 -moz-box-sizing: content-box;
286 289 box-sizing: content-box;
287 290 box-shadow: 0 0 2px #888888;
  291 + border-radius: 8px;
288 292 }
289 293  
290 294 .verify-bar-area .verify-move-block:hover {
... ... @@ -302,6 +306,7 @@ export default {
302 306 -moz-box-sizing: content-box;
303 307 box-sizing: content-box;
304 308 border: 1px solid #ddd;
  309 + border-radius: 8px;
305 310 }
306 311  
307 312 .verify-img-panel {
... ...
yudao-ui-admin-vue3/src/components/Verifition/src/Verify/VerifyPoints.vue
... ... @@ -64,7 +64,7 @@
64 64 * */
65 65 import { resetSize } from './../utils/util'
66 66 import { aesEncrypt } from './../utils/ase'
67   -import { reqGet, reqCheck } from './../api/index'
  67 +import { getCodeApi, reqCheckApi } from '@/api/login'
68 68 import { onMounted, reactive, ref, nextTick, toRefs, getCurrentInstance } from 'vue'
69 69 import { useI18n } from '@/hooks/web/useI18n'
70 70 export default {
... ... @@ -172,7 +172,7 @@ export default {
172 172 : JSON.stringify(checkPosArr),
173 173 token: backToken.value
174 174 }
175   - reqCheck(data).then((res) => {
  175 + reqCheckApi(data).then((res) => {
176 176 if (res.repCode == '0000') {
177 177 barAreaColor.value = '#4cae4c'
178 178 barAreaBorderColor.value = '#5cb85c'
... ... @@ -230,7 +230,7 @@ export default {
230 230 let data = {
231 231 captchaType: captchaType.value
232 232 }
233   - reqGet(data).then((res) => {
  233 + getCodeApi(data).then((res) => {
234 234 if (res.repCode == '0000') {
235 235 pointBackImgBase.value = res.repData.originalImageBase64
236 236 backToken.value = res.repData.token
... ...
yudao-ui-admin-vue3/src/components/Verifition/src/Verify/VerifySlide.vue
... ... @@ -78,7 +78,7 @@
78 78 * */
79 79 import { aesEncrypt } from './../utils/ase'
80 80 import { resetSize } from './../utils/util'
81   -import { reqGet, reqCheck } from './../api/index'
  81 +import { getCodeApi, reqCheckApi } from '@/api/login'
82 82 import { useI18n } from '@/hooks/web/useI18n'
83 83 import {
84 84 computed,
... ... @@ -137,7 +137,7 @@ export default {
137 137 default() {
138 138 return {
139 139 width: '310px',
140   - height: '40px'
  140 + height: '30px'
141 141 }
142 142 }
143 143 }
... ... @@ -302,7 +302,7 @@ export default {
302 302 : JSON.stringify({ x: moveLeftDistance, y: 5.0 }),
303 303 token: backToken.value
304 304 }
305   - reqCheck(data).then((res) => {
  305 + reqCheckApi(data).then((res) => {
306 306 if (res.repCode == '0000') {
307 307 moveBlockBackgroundColor.value = '#5cb85c'
308 308 leftBarBorderColor.value = '#5cb85c'
... ... @@ -379,7 +379,7 @@ export default {
379 379 let data = {
380 380 captchaType: captchaType.value
381 381 }
382   - reqGet(data).then((res) => {
  382 + getCodeApi(data).then((res) => {
383 383 if (res.repCode == '0000') {
384 384 backImgBase.value = res.repData.originalImageBase64
385 385 blockBackImgBase.value = res.repData.jigsawImageBase64
... ...
yudao-ui-admin-vue3/src/components/Verifition/src/api/index.ts deleted
1   -/**
2   - * 此处可直接引用自己项目封装好的 axios 配合后端联调
3   - */
4   -
5   -import request from './../utils/axios' //组件内部封装的axios
6   -// import request from "@/api/axios.js" //调用项目封装的axios
7   -
8   -//获取验证图片 以及token
9   -export function reqGet(data) {
10   - return request({
11   - // url: '/captcha/get',
12   - url: '/admin-api/system/captcha/get', // 使用项目自定义的 /admin-api/ 前缀
13   - method: 'post',
14   - data
15   - })
16   -}
17   -
18   -//滑动或者点选验证
19   -export function reqCheck(data) {
20   - return request({
21   - // url: '/captcha/check',
22   - url: '/admin-api/system/captcha/check', // 使用项目自定义的 /admin-api/ 前缀
23   - method: 'post',
24   - data
25   - })
26   -}
yudao-ui-admin-vue3/src/components/Verifition/src/utils/axios.ts deleted
1   -import axios from 'axios'
2   -
3   -axios.defaults.baseURL = import.meta.env.VITE_BASE_URL
4   -
5   -const service = axios.create({
6   - timeout: 40000,
7   - headers: {
8   - 'X-Requested-With': 'XMLHttpRequest',
9   - 'Content-Type': 'application/json; charset=UTF-8'
10   - }
11   -})
12   -service.interceptors.request.use(
13   - (config) => {
14   - return config
15   - },
16   - (error) => {
17   - Promise.reject(error)
18   - }
19   -)
20   -
21   -// response interceptor
22   -service.interceptors.response.use((response) => {
23   - const res = response.data
24   - return res
25   -})
26   -export default service
yudao-ui-admin-vue3/src/config/axios/index.ts
... ... @@ -26,6 +26,10 @@ export default {
26 26 const res = await request({ method: 'POST', ...option })
27 27 return res.data as unknown as T
28 28 },
  29 + postOriginal: async (option: any) => {
  30 + const res = await request({ method: 'POST', ...option })
  31 + return res
  32 + },
29 33 delete: async <T = any>(option: any) => {
30 34 const res = await request({ method: 'DELETE', ...option })
31 35 return res.data as unknown as T
... ...
yudao-ui-admin-vue3/src/config/axios/service.ts
... ... @@ -206,6 +206,7 @@ service.interceptors.response.use(
206 206 )
207 207  
208 208 const refreshToken = async () => {
  209 + axios.defaults.headers.common['tenant-id'] = getTenantId()
209 210 return await axios.post(base_url + '/system/auth/refresh-token?refreshToken=' + getRefreshToken())
210 211 }
211 212 const handleAuthorized = () => {
... ...
yudao-ui-admin-vue3/src/hooks/web/useCrudSchemas.ts
... ... @@ -7,10 +7,14 @@ import { DescriptionsSchema } from &#39;@/types/descriptions&#39;
7 7 import { ComponentOptions } from '@/types/components'
8 8  
9 9 export type CrudSchema = Omit<TableColumn, 'children'> & {
10   - search?: CrudSearchParams
11   - table?: CrudTableParams
12   - form?: CrudFormParams
13   - detail?: CrudDescriptionsParams
  10 + isSearch?: boolean // 是否在查询显示
  11 + search?: CrudSearchParams // 查询的详细配置
  12 + isTable?: boolean // 是否在列表显示
  13 + table?: CrudTableParams // 列表的详细配置
  14 + isForm?: boolean // 是否在表单显示
  15 + form?: CrudFormParams // 表单的详细配置
  16 + isDetail?: boolean // 是否在详情显示
  17 + detail?: CrudDescriptionsParams // 详情的详细配置
14 18 children?: CrudSchema[]
15 19 dictType?: string // 字典类型
16 20 dictData?: 'string' | 'number' | 'boolean' // 字典数据类型 string | number | boolean
... ... @@ -80,7 +84,7 @@ const filterSearchSchema = (crudSchema: CrudSchema[]): FormSchema[] =&gt; {
80 84  
81 85 eachTree(crudSchema, (schemaItem: CrudSchema) => {
82 86 // 判断是否显示
83   - if (schemaItem?.search?.show) {
  87 + if (schemaItem?.isSearch || schemaItem.search?.show) {
84 88 let component = schemaItem?.search?.component || 'Input'
85 89 const options: ComponentOptions[] = []
86 90 let comonentProps = {}
... ... @@ -93,7 +97,7 @@ const filterSearchSchema = (crudSchema: CrudSchema[]): FormSchema[] =&gt; {
93 97 comonentProps = {
94 98 options: options
95 99 }
96   - if (!schemaItem.search.component) component = 'Select'
  100 + if (!schemaItem.search?.component) component = 'Select'
97 101 }
98 102 const searchSchemaItem = {
99 103 // 默认为 input
... ... @@ -116,7 +120,7 @@ const filterSearchSchema = (crudSchema: CrudSchema[]): FormSchema[] =&gt; {
116 120 const filterTableSchema = (crudSchema: CrudSchema[]): TableColumn[] => {
117 121 const tableColumns = treeMap<CrudSchema>(crudSchema, {
118 122 conversion: (schema: CrudSchema) => {
119   - if (schema?.table?.show !== false) {
  123 + if (schema?.isTable !== false || schema?.table?.show !== false) {
120 124 return {
121 125 ...schema.table,
122 126 ...schema
... ... @@ -140,11 +144,19 @@ const filterFormSchema = (crudSchema: CrudSchema[]): FormSchema[] =&gt; {
140 144  
141 145 eachTree(crudSchema, (schemaItem: CrudSchema) => {
142 146 // 判断是否显示
143   - if (schemaItem?.form?.show !== false) {
  147 + if (schemaItem?.isForm !== false || schemaItem?.form?.show == true) {
144 148 let component = schemaItem?.form?.component || 'Input'
145   - const options: ComponentOptions[] = []
  149 + let defaultValue: any = ''
  150 + if (schemaItem.form?.value) {
  151 + defaultValue = schemaItem.form?.value
  152 + } else {
  153 + if (component === 'InputNumber') {
  154 + defaultValue = 0
  155 + }
  156 + }
146 157 let comonentProps = {}
147 158 if (schemaItem.dictType) {
  159 + const options: ComponentOptions[] = []
148 160 if (schemaItem.dictData && schemaItem.dictData === 'number') {
149 161 getIntDictOptions(schemaItem.dictType).forEach((dict) => {
150 162 options.push(dict)
... ... @@ -167,6 +179,7 @@ const filterFormSchema = (crudSchema: CrudSchema[]): FormSchema[] =&gt; {
167 179 // 默认为 input
168 180 component: component,
169 181 componentProps: comonentProps,
  182 + value: defaultValue,
170 183 ...schemaItem.form,
171 184 field: schemaItem.field,
172 185 label: schemaItem.form?.label || schemaItem.label
... ... @@ -188,7 +201,7 @@ const filterDescriptionsSchema = (crudSchema: CrudSchema[]): DescriptionsSchema[
188 201  
189 202 eachTree(crudSchema, (schemaItem: CrudSchema) => {
190 203 // 判断是否显示
191   - if (schemaItem?.detail?.show !== false) {
  204 + if (schemaItem?.isDetail !== false || schemaItem.detail?.show !== false) {
192 205 const descriptionsSchemaItem = {
193 206 ...schemaItem.detail,
194 207 field: schemaItem.field,
... ...
yudao-ui-admin-vue3/src/hooks/web/useVxeCrudSchemas.ts
... ... @@ -181,7 +181,7 @@ const filterTableSchema = (crudSchema: VxeCrudSchema): VxeGridPropTypes.Columns
181 181 }
182 182 eachTree(crudSchema.columns, (schemaItem: VxeCrudColumns) => {
183 183 // 判断是否显示
184   - if (schemaItem?.isTable !== false) {
  184 + if (schemaItem?.isTable !== false && schemaItem?.table?.show !== false) {
185 185 const tableSchemaItem = {
186 186 ...schemaItem.table,
187 187 field: schemaItem.field,
... ... @@ -227,9 +227,17 @@ const filterFormSchema = (crudSchema: VxeCrudSchema): FormSchema[] =&gt; {
227 227 if (schemaItem?.isForm !== false || schemaItem?.form?.show == true) {
228 228 // 默认为 input
229 229 let component = schemaItem?.form?.component || 'Input'
230   - const options: ComponentOptions[] = []
  230 + let defaultValue: any = ''
  231 + if (schemaItem.form?.value) {
  232 + defaultValue = schemaItem.form?.value
  233 + } else {
  234 + if (component === 'InputNumber') {
  235 + defaultValue = 0
  236 + }
  237 + }
231 238 let comonentProps = {}
232 239 if (schemaItem.dictType) {
  240 + const options: ComponentOptions[] = []
233 241 if (schemaItem.dictData && schemaItem.dictData === 'number') {
234 242 getIntDictOptions(schemaItem.dictType).forEach((dict) => {
235 243 options.push(dict)
... ... @@ -249,11 +257,12 @@ const filterFormSchema = (crudSchema: VxeCrudSchema): FormSchema[] =&gt; {
249 257 if (!(schemaItem.form && schemaItem.form.component)) component = 'Select'
250 258 }
251 259 const formSchemaItem = {
  260 + component: component,
  261 + componentProps: comonentProps,
  262 + value: defaultValue,
252 263 ...schemaItem.form,
253 264 field: schemaItem.field,
254   - label: schemaItem.form?.label || schemaItem.title,
255   - component: component,
256   - componentProps: comonentProps
  265 + label: schemaItem.form?.label || schemaItem.title
257 266 }
258 267  
259 268 formSchema.push(formSchemaItem)
... ... @@ -269,7 +278,7 @@ const filterDescriptionsSchema = (crudSchema: VxeCrudSchema): DescriptionsSchema
269 278  
270 279 eachTree(crudSchema.columns, (schemaItem: VxeCrudColumns) => {
271 280 // 判断是否显示
272   - if (schemaItem?.isDetail !== false) {
  281 + if (schemaItem?.isDetail !== false || schemaItem.detail?.show !== false) {
273 282 const descriptionsSchemaItem = {
274 283 ...schemaItem.detail,
275 284 field: schemaItem.field,
... ...
yudao-ui-admin-vue3/src/router/index.ts
... ... @@ -14,7 +14,7 @@ import { isRelogin } from &#39;@/config/axios/service&#39;
14 14 import { getInfoApi } from '@/api/login'
15 15 import { useCache } from '@/hooks/web/useCache'
16 16  
17   -const { wsCache } = useCache()
  17 +const { wsCache } = useCache('sessionStorage')
18 18  
19 19 const { start, done } = useNProgress()
20 20  
... ...
yudao-ui-admin-vue3/src/views/Error/403.vue
  1 +<template>
  2 + <Error type="403" @error-click="errorClick" />
  3 +</template>
1 4 <script setup lang="ts">
2 5 import { Error } from '@/components/Error'
3 6 import { useRouter } from 'vue-router'
... ... @@ -8,7 +11,3 @@ const errorClick = () =&gt; {
8 11 push('/')
9 12 }
10 13 </script>
11   -
12   -<template>
13   - <Error type="403" @error-click="errorClick" />
14   -</template>
... ...
yudao-ui-admin-vue3/src/views/Error/404.vue
  1 +<template>
  2 + <Error @error-click="errorClick" />
  3 +</template>
  4 +
1 5 <script setup lang="ts">
2 6 import { Error } from '@/components/Error'
3 7 import { useRouter } from 'vue-router'
... ... @@ -8,7 +12,3 @@ const errorClick = () =&gt; {
8 12 push('/')
9 13 }
10 14 </script>
11   -
12   -<template>
13   - <Error @error-click="errorClick" />
14   -</template>
... ...
yudao-ui-admin-vue3/src/views/Error/500.vue
  1 +<template>
  2 + <Error type="500" @error-click="errorClick" />
  3 +</template>
  4 +
1 5 <script setup lang="ts">
2 6 import { Error } from '@/components/Error'
3 7 import { useRouter } from 'vue-router'
... ... @@ -8,7 +12,3 @@ const errorClick = () =&gt; {
8 12 push('/')
9 13 }
10 14 </script>
11   -
12   -<template>
13   - <Error type="500" @error-click="errorClick" />
14   -</template>
... ...
yudao-ui-admin-vue3/src/views/Home/Index.vue
  1 +<template>
  2 + <div>
  3 + <el-card shadow="never">
  4 + <el-skeleton :loading="loading" animated>
  5 + <el-row :gutter="20" justify="space-between">
  6 + <el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
  7 + <div class="flex items-center">
  8 + <img :src="avatar" alt="" class="w-70px h-70px rounded-[50%] mr-20px" />
  9 + <div>
  10 + <div class="text-20px text-700">
  11 + {{ t('workplace.welcome') }} {{ username }} {{ t('workplace.happyDay') }}
  12 + </div>
  13 + <div class="mt-10px text-14px text-gray-500">
  14 + {{ t('workplace.toady') }},20℃ - 32℃!
  15 + </div>
  16 + </div>
  17 + </div>
  18 + </el-col>
  19 + <el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
  20 + <div class="flex h-70px items-center justify-end <sm:mt-10px">
  21 + <div class="px-8px text-right">
  22 + <div class="text-14px text-gray-400 mb-20px">{{ t('workplace.project') }}</div>
  23 + <CountTo
  24 + class="text-20px"
  25 + :start-val="0"
  26 + :end-val="totalSate.project"
  27 + :duration="2600"
  28 + />
  29 + </div>
  30 + <el-divider direction="vertical" />
  31 + <div class="px-8px text-right">
  32 + <div class="text-14px text-gray-400 mb-20px">{{ t('workplace.toDo') }}</div>
  33 + <CountTo
  34 + class="text-20px"
  35 + :start-val="0"
  36 + :end-val="totalSate.todo"
  37 + :duration="2600"
  38 + />
  39 + </div>
  40 + <el-divider direction="vertical" border-style="dashed" />
  41 + <div class="px-8px text-right">
  42 + <div class="text-14px text-gray-400 mb-20px">{{ t('workplace.access') }}</div>
  43 + <CountTo
  44 + class="text-20px"
  45 + :start-val="0"
  46 + :end-val="totalSate.access"
  47 + :duration="2600"
  48 + />
  49 + </div>
  50 + </div>
  51 + </el-col>
  52 + </el-row>
  53 + </el-skeleton>
  54 + </el-card>
  55 + </div>
  56 +
  57 + <el-row class="mt-5px" :gutter="20" justify="space-between">
  58 + <el-col :xl="16" :lg="16" :md="24" :sm="24" :xs="24" class="mb-10px">
  59 + <el-card shadow="never">
  60 + <template #header>
  61 + <div class="flex justify-between h-3">
  62 + <span>{{ t('workplace.project') }}</span>
  63 + <el-link type="primary" :underline="false">{{ t('workplace.more') }}</el-link>
  64 + </div>
  65 + </template>
  66 + <el-skeleton :loading="loading" animated>
  67 + <el-row>
  68 + <el-col
  69 + v-for="(item, index) in projects"
  70 + :key="`card-${index}`"
  71 + :xl="8"
  72 + :lg="8"
  73 + :md="8"
  74 + :sm="24"
  75 + :xs="24"
  76 + >
  77 + <el-card shadow="hover">
  78 + <div class="flex items-center">
  79 + <Icon :icon="item.icon" :size="25" class="mr-10px" />
  80 + <span class="text-16px">{{ item.name }}</span>
  81 + </div>
  82 + <div class="mt-15px text-14px text-gray-400">{{ t(item.message) }}</div>
  83 + <div class="mt-20px text-12px text-gray-400 flex justify-between">
  84 + <span>{{ item.personal }}</span>
  85 + <span>{{ formatTime(item.time, 'yyyy-MM-dd') }}</span>
  86 + </div>
  87 + </el-card>
  88 + </el-col>
  89 + </el-row>
  90 + </el-skeleton>
  91 + </el-card>
  92 +
  93 + <el-card shadow="never" class="mt-5px">
  94 + <el-skeleton :loading="loading" animated>
  95 + <el-row :gutter="20" justify="space-between">
  96 + <el-col :xl="10" :lg="10" :md="24" :sm="24" :xs="24">
  97 + <el-card shadow="hover" class="mb-10px">
  98 + <el-skeleton :loading="loading" animated>
  99 + <Echart :options="pieOptionsData" :height="280" />
  100 + </el-skeleton>
  101 + </el-card>
  102 + </el-col>
  103 + <el-col :xl="14" :lg="14" :md="24" :sm="24" :xs="24">
  104 + <el-card shadow="hover" class="mb-10px">
  105 + <el-skeleton :loading="loading" animated>
  106 + <Echart :options="barOptionsData" :height="280" />
  107 + </el-skeleton>
  108 + </el-card>
  109 + </el-col>
  110 + </el-row>
  111 + </el-skeleton>
  112 + </el-card>
  113 + </el-col>
  114 + <el-col :xl="8" :lg="8" :md="24" :sm="24" :xs="24" class="mb-10px">
  115 + <el-card shadow="never">
  116 + <template #header>
  117 + <div class="flex justify-between h-3">
  118 + <span>{{ t('workplace.shortcutOperation') }}</span>
  119 + </div>
  120 + </template>
  121 + <el-skeleton :loading="loading" animated>
  122 + <el-row>
  123 + <el-col v-for="item in shortcut" :key="`team-${item.name}`" :span="8" class="mb-10px">
  124 + <div class="flex items-center">
  125 + <Icon :icon="item.icon" class="mr-10px" />
  126 + <el-link type="default" :underline="false" :href="item.url">
  127 + {{ item.name }}
  128 + </el-link>
  129 + </div>
  130 + </el-col>
  131 + </el-row>
  132 + </el-skeleton>
  133 + </el-card>
  134 + <el-card shadow="never" class="mt-10px">
  135 + <template #header>
  136 + <div class="flex justify-between h-3">
  137 + <span>{{ t('workplace.notice') }}</span>
  138 + <el-link type="primary" :underline="false">{{ t('workplace.more') }}</el-link>
  139 + </div>
  140 + </template>
  141 + <el-skeleton :loading="loading" animated>
  142 + <div v-for="(item, index) in notice" :key="`dynamics-${index}`">
  143 + <div class="flex items-center">
  144 + <img :src="avatar" alt="" class="w-35px h-35px rounded-[50%] mr-20px" />
  145 + <div>
  146 + <div class="text-14px">
  147 + <Highlight :keys="item.keys.map((v) => t(v))">
  148 + {{ item.type }} : {{ item.title }}
  149 + </Highlight>
  150 + </div>
  151 + <div class="mt-15px text-12px text-gray-400">
  152 + {{ formatTime(item.date, 'yyyy-MM-dd') }}
  153 + </div>
  154 + </div>
  155 + </div>
  156 + <el-divider />
  157 + </div>
  158 + </el-skeleton>
  159 + </el-card>
  160 + </el-col>
  161 + </el-row>
  162 +</template>
1 163 <script setup lang="ts">
2 164 import { ElRow, ElCol, ElSkeleton, ElCard, ElDivider, ElLink } from 'element-plus'
3 165 import { useI18n } from '@/hooks/web/useI18n'
... ... @@ -6,12 +168,11 @@ import { CountTo } from &#39;@/components/CountTo&#39;
6 168 import { formatTime } from '@/utils'
7 169 import { Echart } from '@/components/Echart'
8 170 import { EChartsOption } from 'echarts'
9   -import { radarOption } from './echarts-data'
10 171 import { Highlight } from '@/components/Highlight'
11 172 import type { WorkplaceTotal, Project, Notice, Shortcut } from './types'
12 173 import { set } from 'lodash-es'
13 174 import { useCache } from '@/hooks/web/useCache'
14   -import { pieOptions, barOptions, lineOptions } from './echarts-data'
  175 +import { pieOptions, barOptions } from './echarts-data'
15 176  
16 177 const { t } = useI18n()
17 178 const { wsCache } = useCache()
... ... @@ -156,44 +317,6 @@ const getShortcut = async () =&gt; {
156 317 shortcut = Object.assign(shortcut, data)
157 318 }
158 319  
159   -// 获取指数
160   -let radarOptionData = reactive<EChartsOption>(radarOption) as EChartsOption
161   -
162   -const getRadar = async () => {
163   - const data = [
164   - { name: 'workplace.quote', max: 65, personal: 42, team: 50 },
165   - { name: 'workplace.contribution', max: 160, personal: 30, team: 140 },
166   - { name: 'workplace.hot', max: 300, personal: 20, team: 28 },
167   - { name: 'workplace.yield', max: 130, personal: 35, team: 35 },
168   - { name: 'workplace.follow', max: 100, personal: 80, team: 90 }
169   - ]
170   - set(
171   - radarOptionData,
172   - 'radar.indicator',
173   - data.map((v) => {
174   - return {
175   - name: t(v.name),
176   - max: v.max
177   - }
178   - })
179   - )
180   - set(radarOptionData, 'series', [
181   - {
182   - name: '指数',
183   - type: 'radar',
184   - data: [
185   - {
186   - value: data.map((v) => v.personal),
187   - name: t('workplace.personal')
188   - },
189   - {
190   - value: data.map((v) => v.team),
191   - name: t('workplace.team')
192   - }
193   - ]
194   - }
195   - ])
196   -}
197 320 // 用户来源
198 321 const getUserAccessSource = async () => {
199 322 const data = [
... ... @@ -242,239 +365,17 @@ const getWeeklyUserActivity = async () =&gt; {
242 365 ])
243 366 }
244 367  
245   -const lineOptionsData = reactive<EChartsOption>(lineOptions) as EChartsOption
246   -
247   -// 每月销售总额
248   -const getMonthlySales = async () => {
249   - const data = [
250   - { estimate: 100, actual: 120, name: 'analysis.january' },
251   - { estimate: 120, actual: 82, name: 'analysis.february' },
252   - { estimate: 161, actual: 91, name: 'analysis.march' },
253   - { estimate: 134, actual: 154, name: 'analysis.april' },
254   - { estimate: 105, actual: 162, name: 'analysis.may' },
255   - { estimate: 160, actual: 140, name: 'analysis.june' },
256   - { estimate: 165, actual: 145, name: 'analysis.july' },
257   - { estimate: 114, actual: 250, name: 'analysis.august' },
258   - { estimate: 163, actual: 134, name: 'analysis.september' },
259   - { estimate: 185, actual: 56, name: 'analysis.october' },
260   - { estimate: 118, actual: 99, name: 'analysis.november' },
261   - { estimate: 123, actual: 123, name: 'analysis.december' }
262   - ]
263   - set(
264   - lineOptionsData,
265   - 'xAxis.data',
266   - data.map((v) => t(v.name))
267   - )
268   - set(lineOptionsData, 'series', [
269   - {
270   - name: t('analysis.estimate'),
271   - smooth: true,
272   - type: 'line',
273   - data: data.map((v) => v.estimate),
274   - animationDuration: 2800,
275   - animationEasing: 'cubicInOut'
276   - },
277   - {
278   - name: t('analysis.actual'),
279   - smooth: true,
280   - type: 'line',
281   - itemStyle: {},
282   - data: data.map((v) => v.actual),
283   - animationDuration: 2800,
284   - animationEasing: 'quadraticOut'
285   - }
286   - ])
287   -}
288   -
289 368 const getAllApi = async () => {
290 369 await Promise.all([
291 370 getCount(),
292 371 getProject(),
293 372 getNotice(),
294 373 getShortcut(),
295   - getRadar(),
296 374 getUserAccessSource(),
297   - getWeeklyUserActivity(),
298   - getMonthlySales()
  375 + getWeeklyUserActivity()
299 376 ])
300 377 loading.value = false
301 378 }
302 379  
303 380 getAllApi()
304 381 </script>
305   -
306   -<template>
307   - <div>
308   - <el-card shadow="never">
309   - <el-skeleton :loading="loading" animated>
310   - <el-row :gutter="20" justify="space-between">
311   - <el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
312   - <div class="flex items-center">
313   - <img :src="avatar" alt="" class="w-70px h-70px rounded-[50%] mr-20px" />
314   - <div>
315   - <div class="text-20px text-700">
316   - {{ t('workplace.welcome') }} {{ username }} {{ t('workplace.happyDay') }}
317   - </div>
318   - <div class="mt-10px text-14px text-gray-500">
319   - {{ t('workplace.toady') }},20℃ - 32℃!
320   - </div>
321   - </div>
322   - </div>
323   - </el-col>
324   - <el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
325   - <div class="flex h-70px items-center justify-end <sm:mt-10px">
326   - <div class="px-8px text-right">
327   - <div class="text-14px text-gray-400 mb-20px">{{ t('workplace.project') }}</div>
328   - <CountTo
329   - class="text-20px"
330   - :start-val="0"
331   - :end-val="totalSate.project"
332   - :duration="2600"
333   - />
334   - </div>
335   - <el-divider direction="vertical" />
336   - <div class="px-8px text-right">
337   - <div class="text-14px text-gray-400 mb-20px">{{ t('workplace.toDo') }}</div>
338   - <CountTo
339   - class="text-20px"
340   - :start-val="0"
341   - :end-val="totalSate.todo"
342   - :duration="2600"
343   - />
344   - </div>
345   - <el-divider direction="vertical" border-style="dashed" />
346   - <div class="px-8px text-right">
347   - <div class="text-14px text-gray-400 mb-20px">{{ t('workplace.access') }}</div>
348   - <CountTo
349   - class="text-20px"
350   - :start-val="0"
351   - :end-val="totalSate.access"
352   - :duration="2600"
353   - />
354   - </div>
355   - </div>
356   - </el-col>
357   - </el-row>
358   - </el-skeleton>
359   - </el-card>
360   - </div>
361   -
362   - <el-row class="mt-10px" :gutter="20" justify="space-between">
363   - <el-col :xl="16" :lg="16" :md="24" :sm="24" :xs="24" class="mb-20px">
364   - <el-card shadow="never">
365   - <template #header>
366   - <div class="flex justify-between">
367   - <span>{{ t('workplace.project') }}</span>
368   - <el-link type="primary" :underline="false">{{ t('workplace.more') }}</el-link>
369   - </div>
370   - </template>
371   - <el-skeleton :loading="loading" animated>
372   - <el-row>
373   - <el-col
374   - v-for="(item, index) in projects"
375   - :key="`card-${index}`"
376   - :xl="8"
377   - :lg="8"
378   - :md="12"
379   - :sm="24"
380   - :xs="24"
381   - >
382   - <el-card shadow="hover">
383   - <div class="flex items-center">
384   - <Icon :icon="item.icon" :size="25" class="mr-10px" />
385   - <span class="text-16px">{{ item.name }}</span>
386   - </div>
387   - <div class="mt-15px text-14px text-gray-400">{{ t(item.message) }}</div>
388   - <div class="mt-20px text-12px text-gray-400 flex justify-between">
389   - <span>{{ item.personal }}</span>
390   - <span>{{ formatTime(item.time, 'yyyy-MM-dd') }}</span>
391   - </div>
392   - </el-card>
393   - </el-col>
394   - </el-row>
395   - </el-skeleton>
396   - </el-card>
397   -
398   - <el-card shadow="never" class="mt-10px">
399   - <el-skeleton :loading="loading" animated>
400   - <el-row :gutter="20" justify="space-between">
401   - <el-col :xl="10" :lg="10" :md="24" :sm="24" :xs="24">
402   - <el-card shadow="hover" class="mb-20px">
403   - <el-skeleton :loading="loading" animated>
404   - <Echart :options="pieOptionsData" :height="300" />
405   - </el-skeleton>
406   - </el-card>
407   - </el-col>
408   - <el-col :xl="14" :lg="14" :md="24" :sm="24" :xs="24">
409   - <el-card shadow="hover" class="mb-20px">
410   - <el-skeleton :loading="loading" animated>
411   - <Echart :options="barOptionsData" :height="300" />
412   - </el-skeleton>
413   - </el-card>
414   - </el-col>
415   - <el-col :span="24">
416   - <el-card shadow="hover" class="mb-20px">
417   - <el-skeleton :loading="loading" animated :rows="4">
418   - <Echart :options="lineOptionsData" :height="350" />
419   - </el-skeleton>
420   - </el-card>
421   - </el-col>
422   - </el-row>
423   - </el-skeleton>
424   - </el-card>
425   - </el-col>
426   - <el-col :xl="8" :lg="8" :md="24" :sm="24" :xs="24" class="mb-20px">
427   - <el-card shadow="never">
428   - <template #header>
429   - <span>{{ t('workplace.shortcutOperation') }}</span>
430   - </template>
431   - <el-skeleton :loading="loading" animated>
432   - <el-row>
433   - <el-col v-for="item in shortcut" :key="`team-${item.name}`" :span="8" class="mb-20px">
434   - <div class="flex items-center">
435   - <Icon :icon="item.icon" class="mr-10px" />
436   - <el-link type="default" :underline="false" :href="item.url">
437   - {{ item.name }}
438   - </el-link>
439   - </div>
440   - </el-col>
441   - </el-row>
442   - </el-skeleton>
443   - </el-card>
444   - <el-card shadow="never" class="mt-10px">
445   - <template #header>
446   - <div class="flex justify-between">
447   - <span>{{ t('workplace.notice') }}</span>
448   - <el-link type="primary" :underline="false">{{ t('workplace.more') }}</el-link>
449   - </div>
450   - </template>
451   - <el-skeleton :loading="loading" animated>
452   - <div v-for="(item, index) in notice" :key="`dynamics-${index}`">
453   - <div class="flex items-center">
454   - <img :src="avatar" alt="" class="w-35px h-35px rounded-[50%] mr-20px" />
455   - <div>
456   - <div class="text-14px">
457   - <Highlight :keys="item.keys.map((v) => t(v))">
458   - {{ item.type }} : {{ item.title }}
459   - </Highlight>
460   - </div>
461   - <div class="mt-15px text-12px text-gray-400">
462   - {{ formatTime(item.date, 'yyyy-MM-dd') }}
463   - </div>
464   - </div>
465   - </div>
466   - <el-divider />
467   - </div>
468   - </el-skeleton>
469   - </el-card>
470   - <el-card shadow="never" class="mt-10px">
471   - <template #header>
472   - <span>{{ t('workplace.index') }}</span>
473   - </template>
474   - <el-skeleton :loading="loading" animated>
475   - <Echart :options="radarOptionData" :height="400" />
476   - </el-skeleton>
477   - </el-card>
478   - </el-col>
479   - </el-row>
480   -</template>
... ...
yudao-ui-admin-vue3/src/views/Home/Index2.vue
1   -<script setup lang="ts">
2   -import { ref, reactive } from 'vue'
3   -import { set } from 'lodash-es'
4   -import { EChartsOption } from 'echarts'
5   -import { Echart } from '@/components/Echart'
6   -import { useI18n } from '@/hooks/web/useI18n'
7   -import { CountTo } from '@/components/CountTo'
8   -import type { AnalysisTotalTypes } from './types'
9   -import { useDesign } from '@/hooks/web/useDesign'
10   -import { ElRow, ElCol, ElCard, ElSkeleton } from 'element-plus'
11   -import { pieOptions, barOptions, lineOptions } from './echarts-data'
12   -
13   -const { t } = useI18n()
14   -const loading = ref(true)
15   -const { getPrefixCls } = useDesign()
16   -const prefixCls = getPrefixCls('panel')
17   -const pieOptionsData = reactive<EChartsOption>(pieOptions) as EChartsOption
18   -
19   -let totalState = reactive<AnalysisTotalTypes>({
20   - users: 0,
21   - messages: 0,
22   - moneys: 0,
23   - shoppings: 0
24   -})
25   -
26   -const getCount = async () => {
27   - const data = {
28   - users: 102400,
29   - messages: 81212,
30   - moneys: 9280,
31   - shoppings: 13600
32   - }
33   - totalState = Object.assign(totalState, data)
34   -}
35   -
36   -// 用户来源
37   -const getUserAccessSource = async () => {
38   - const data = [
39   - { value: 335, name: 'analysis.directAccess' },
40   - { value: 310, name: 'analysis.mailMarketing' },
41   - { value: 234, name: 'analysis.allianceAdvertising' },
42   - { value: 135, name: 'analysis.videoAdvertising' },
43   - { value: 1548, name: 'analysis.searchEngines' }
44   - ]
45   - set(
46   - pieOptionsData,
47   - 'legend.data',
48   - data.map((v) => t(v.name))
49   - )
50   - set(pieOptionsData, 'series.data', data)
51   -}
52   -const barOptionsData = reactive<EChartsOption>(barOptions) as EChartsOption
53   -
54   -// 周活跃量
55   -const getWeeklyUserActivity = async () => {
56   - const data = [
57   - { value: 13253, name: 'analysis.monday' },
58   - { value: 34235, name: 'analysis.tuesday' },
59   - { value: 26321, name: 'analysis.wednesday' },
60   - { value: 12340, name: 'analysis.thursday' },
61   - { value: 24643, name: 'analysis.friday' },
62   - { value: 1322, name: 'analysis.saturday' },
63   - { value: 1324, name: 'analysis.sunday' }
64   - ]
65   - set(
66   - barOptionsData,
67   - 'xAxis.data',
68   - data.map((v) => t(v.name))
69   - )
70   - set(barOptionsData, 'series', [
71   - {
72   - name: t('analysis.activeQuantity'),
73   - data: data.map((v) => v.value),
74   - type: 'bar'
75   - }
76   - ])
77   -}
78   -
79   -const lineOptionsData = reactive<EChartsOption>(lineOptions) as EChartsOption
80   -
81   -// 每月销售总额
82   -const getMonthlySales = async () => {
83   - const data = [
84   - { estimate: 100, actual: 120, name: 'analysis.january' },
85   - { estimate: 120, actual: 82, name: 'analysis.february' },
86   - { estimate: 161, actual: 91, name: 'analysis.march' },
87   - { estimate: 134, actual: 154, name: 'analysis.april' },
88   - { estimate: 105, actual: 162, name: 'analysis.may' },
89   - { estimate: 160, actual: 140, name: 'analysis.june' },
90   - { estimate: 165, actual: 145, name: 'analysis.july' },
91   - { estimate: 114, actual: 250, name: 'analysis.august' },
92   - { estimate: 163, actual: 134, name: 'analysis.september' },
93   - { estimate: 185, actual: 56, name: 'analysis.october' },
94   - { estimate: 118, actual: 99, name: 'analysis.november' },
95   - { estimate: 123, actual: 123, name: 'analysis.december' }
96   - ]
97   - set(
98   - lineOptionsData,
99   - 'xAxis.data',
100   - data.map((v) => t(v.name))
101   - )
102   - set(lineOptionsData, 'series', [
103   - {
104   - name: t('analysis.estimate'),
105   - smooth: true,
106   - type: 'line',
107   - data: data.map((v) => v.estimate),
108   - animationDuration: 2800,
109   - animationEasing: 'cubicInOut'
110   - },
111   - {
112   - name: t('analysis.actual'),
113   - smooth: true,
114   - type: 'line',
115   - itemStyle: {},
116   - data: data.map((v) => v.actual),
117   - animationDuration: 2800,
118   - animationEasing: 'quadraticOut'
119   - }
120   - ])
121   -}
122   -
123   -const getAllApi = async () => {
124   - await Promise.all([getCount(), getUserAccessSource(), getWeeklyUserActivity(), getMonthlySales()])
125   - loading.value = false
126   -}
127   -
128   -getAllApi()
129   -</script>
130   -
131 1 <template>
132 2 <el-row :gutter="20" justify="space-between" :class="prefixCls">
133 3 <el-col :xl="6" :lg="6" :md="12" :sm="12" :xs="24">
... ... @@ -270,6 +140,136 @@ getAllApi()
270 140 </el-col>
271 141 </el-row>
272 142 </template>
  143 +<script setup lang="ts">
  144 +import { ref, reactive } from 'vue'
  145 +import { set } from 'lodash-es'
  146 +import { EChartsOption } from 'echarts'
  147 +import { Echart } from '@/components/Echart'
  148 +import { useI18n } from '@/hooks/web/useI18n'
  149 +import { CountTo } from '@/components/CountTo'
  150 +import type { AnalysisTotalTypes } from './types'
  151 +import { useDesign } from '@/hooks/web/useDesign'
  152 +import { ElRow, ElCol, ElCard, ElSkeleton } from 'element-plus'
  153 +import { pieOptions, barOptions, lineOptions } from './echarts-data'
  154 +
  155 +const { t } = useI18n()
  156 +const loading = ref(true)
  157 +const { getPrefixCls } = useDesign()
  158 +const prefixCls = getPrefixCls('panel')
  159 +const pieOptionsData = reactive<EChartsOption>(pieOptions) as EChartsOption
  160 +
  161 +let totalState = reactive<AnalysisTotalTypes>({
  162 + users: 0,
  163 + messages: 0,
  164 + moneys: 0,
  165 + shoppings: 0
  166 +})
  167 +
  168 +const getCount = async () => {
  169 + const data = {
  170 + users: 102400,
  171 + messages: 81212,
  172 + moneys: 9280,
  173 + shoppings: 13600
  174 + }
  175 + totalState = Object.assign(totalState, data)
  176 +}
  177 +
  178 +// 用户来源
  179 +const getUserAccessSource = async () => {
  180 + const data = [
  181 + { value: 335, name: 'analysis.directAccess' },
  182 + { value: 310, name: 'analysis.mailMarketing' },
  183 + { value: 234, name: 'analysis.allianceAdvertising' },
  184 + { value: 135, name: 'analysis.videoAdvertising' },
  185 + { value: 1548, name: 'analysis.searchEngines' }
  186 + ]
  187 + set(
  188 + pieOptionsData,
  189 + 'legend.data',
  190 + data.map((v) => t(v.name))
  191 + )
  192 + set(pieOptionsData, 'series.data', data)
  193 +}
  194 +const barOptionsData = reactive<EChartsOption>(barOptions) as EChartsOption
  195 +
  196 +// 周活跃量
  197 +const getWeeklyUserActivity = async () => {
  198 + const data = [
  199 + { value: 13253, name: 'analysis.monday' },
  200 + { value: 34235, name: 'analysis.tuesday' },
  201 + { value: 26321, name: 'analysis.wednesday' },
  202 + { value: 12340, name: 'analysis.thursday' },
  203 + { value: 24643, name: 'analysis.friday' },
  204 + { value: 1322, name: 'analysis.saturday' },
  205 + { value: 1324, name: 'analysis.sunday' }
  206 + ]
  207 + set(
  208 + barOptionsData,
  209 + 'xAxis.data',
  210 + data.map((v) => t(v.name))
  211 + )
  212 + set(barOptionsData, 'series', [
  213 + {
  214 + name: t('analysis.activeQuantity'),
  215 + data: data.map((v) => v.value),
  216 + type: 'bar'
  217 + }
  218 + ])
  219 +}
  220 +
  221 +const lineOptionsData = reactive<EChartsOption>(lineOptions) as EChartsOption
  222 +
  223 +// 每月销售总额
  224 +const getMonthlySales = async () => {
  225 + const data = [
  226 + { estimate: 100, actual: 120, name: 'analysis.january' },
  227 + { estimate: 120, actual: 82, name: 'analysis.february' },
  228 + { estimate: 161, actual: 91, name: 'analysis.march' },
  229 + { estimate: 134, actual: 154, name: 'analysis.april' },
  230 + { estimate: 105, actual: 162, name: 'analysis.may' },
  231 + { estimate: 160, actual: 140, name: 'analysis.june' },
  232 + { estimate: 165, actual: 145, name: 'analysis.july' },
  233 + { estimate: 114, actual: 250, name: 'analysis.august' },
  234 + { estimate: 163, actual: 134, name: 'analysis.september' },
  235 + { estimate: 185, actual: 56, name: 'analysis.october' },
  236 + { estimate: 118, actual: 99, name: 'analysis.november' },
  237 + { estimate: 123, actual: 123, name: 'analysis.december' }
  238 + ]
  239 + set(
  240 + lineOptionsData,
  241 + 'xAxis.data',
  242 + data.map((v) => t(v.name))
  243 + )
  244 + set(lineOptionsData, 'series', [
  245 + {
  246 + name: t('analysis.estimate'),
  247 + smooth: true,
  248 + type: 'line',
  249 + data: data.map((v) => v.estimate),
  250 + animationDuration: 2800,
  251 + animationEasing: 'cubicInOut'
  252 + },
  253 + {
  254 + name: t('analysis.actual'),
  255 + smooth: true,
  256 + type: 'line',
  257 + itemStyle: {},
  258 + data: data.map((v) => v.actual),
  259 + animationDuration: 2800,
  260 + animationEasing: 'quadraticOut'
  261 + }
  262 + ])
  263 +}
  264 +
  265 +const getAllApi = async () => {
  266 + await Promise.all([getCount(), getUserAccessSource(), getWeeklyUserActivity(), getMonthlySales()])
  267 + loading.value = false
  268 +}
  269 +
  270 +getAllApi()
  271 +</script>
  272 +
273 273 <style lang="less" scoped>
274 274 @prefix-cls: ~'@{namespace}-panel';
275 275  
... ...
yudao-ui-admin-vue3/src/views/Login/Login.vue
1   -<script setup lang="ts">
2   -import { LoginForm, MobileForm, RegisterForm, QrCodeForm } from './components'
3   -import { ThemeSwitch } from '@/components/ThemeSwitch'
4   -import { LocaleDropdown } from '@/components/LocaleDropdown'
5   -import { useI18n } from '@/hooks/web/useI18n'
6   -import { underlineToHump } from '@/utils'
7   -import { useAppStore } from '@/store/modules/app'
8   -import { useDesign } from '@/hooks/web/useDesign'
9   -
10   -const { t } = useI18n()
11   -
12   -const { getPrefixCls } = useDesign()
13   -
14   -const prefixCls = getPrefixCls('login')
15   -
16   -const appStore = useAppStore()
17   -</script>
18   -
19 1 <template>
20 2 <div
21 3 :class="prefixCls"
... ... @@ -76,6 +58,23 @@ const appStore = useAppStore()
76 58 </div>
77 59 </div>
78 60 </template>
  61 +<script setup lang="ts">
  62 +import { LoginForm, MobileForm, RegisterForm, QrCodeForm } from './components'
  63 +import { ThemeSwitch } from '@/components/ThemeSwitch'
  64 +import { LocaleDropdown } from '@/components/LocaleDropdown'
  65 +import { useI18n } from '@/hooks/web/useI18n'
  66 +import { underlineToHump } from '@/utils'
  67 +import { useAppStore } from '@/store/modules/app'
  68 +import { useDesign } from '@/hooks/web/useDesign'
  69 +
  70 +const { t } = useI18n()
  71 +
  72 +const { getPrefixCls } = useDesign()
  73 +
  74 +const prefixCls = getPrefixCls('login')
  75 +
  76 +const appStore = useAppStore()
  77 +</script>
79 78  
80 79 <style lang="less" scoped>
81 80 @prefix-cls: ~'@{namespace}-login';
... ...
yudao-ui-admin-vue3/src/views/Login/components/LoginForm.vue
  1 +<template>
  2 + <el-form
  3 + :model="loginData.loginForm"
  4 + :rules="LoginRules"
  5 + label-position="top"
  6 + class="login-form"
  7 + label-width="120px"
  8 + size="large"
  9 + v-show="getShow"
  10 + ref="formLogin"
  11 + >
  12 + <el-row style="maring-left: -10px; maring-right: -10px">
  13 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  14 + <el-form-item>
  15 + <LoginFormTitle style="width: 100%" />
  16 + </el-form-item>
  17 + </el-col>
  18 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  19 + <el-form-item prop="tenantName">
  20 + <el-input
  21 + type="text"
  22 + v-model="loginData.loginForm.tenantName"
  23 + :placeholder="t('login.tenantNamePlaceholder')"
  24 + :prefix-icon="iconHouse"
  25 + />
  26 + </el-form-item>
  27 + </el-col>
  28 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  29 + <el-form-item prop="username">
  30 + <el-input
  31 + v-model="loginData.loginForm.username"
  32 + :placeholder="t('login.usernamePlaceholder')"
  33 + :prefix-icon="iconAvatar"
  34 + />
  35 + </el-form-item>
  36 + </el-col>
  37 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  38 + <el-form-item prop="password">
  39 + <el-input
  40 + v-model="loginData.loginForm.password"
  41 + type="password"
  42 + :placeholder="t('login.passwordPlaceholder')"
  43 + show-password
  44 + @keyup.enter="getCode()"
  45 + :prefix-icon="iconLock"
  46 + />
  47 + </el-form-item>
  48 + </el-col>
  49 + <el-col
  50 + :span="24"
  51 + style="padding-left: 10px; padding-right: 10px; margin-top: -20px; margin-bottom: -20px"
  52 + >
  53 + <el-form-item>
  54 + <el-row justify="space-between" style="width: 100%">
  55 + <el-col :span="6">
  56 + <el-checkbox v-model="loginData.loginForm.rememberMe">
  57 + {{ t('login.remember') }}
  58 + </el-checkbox>
  59 + </el-col>
  60 + <el-col :span="12" :offset="6">
  61 + <el-link type="primary" style="float: right">{{ t('login.forgetPassword') }}</el-link>
  62 + </el-col>
  63 + </el-row>
  64 + </el-form-item>
  65 + </el-col>
  66 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  67 + <el-form-item>
  68 + <el-button :loading="loginLoading" type="primary" class="w-[100%]" @click="getCode()">
  69 + {{ t('login.login') }}
  70 + </el-button>
  71 + </el-form-item>
  72 + </el-col>
  73 + <Verify
  74 + ref="verify"
  75 + mode="pop"
  76 + :captchaType="captchaType"
  77 + :imgSize="{ width: '400px', height: '200px' }"
  78 + @success="handleLogin"
  79 + />
  80 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  81 + <el-form-item>
  82 + <el-row justify="space-between" style="width: 100%" :gutter="5">
  83 + <el-col :span="8">
  84 + <el-button class="w-[100%]" @click="setLoginState(LoginStateEnum.MOBILE)">
  85 + {{ t('login.btnMobile') }}
  86 + </el-button>
  87 + </el-col>
  88 + <el-col :span="8">
  89 + <el-button class="w-[100%]" @click="setLoginState(LoginStateEnum.QR_CODE)">
  90 + {{ t('login.btnQRCode') }}
  91 + </el-button>
  92 + </el-col>
  93 + <el-col :span="8">
  94 + <el-button class="w-[100%]" @click="setLoginState(LoginStateEnum.REGISTER)">
  95 + {{ t('login.btnRegister') }}
  96 + </el-button>
  97 + </el-col>
  98 + </el-row>
  99 + </el-form-item>
  100 + </el-col>
  101 + <el-divider content-position="center">{{ t('login.otherLogin') }}</el-divider>
  102 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  103 + <el-form-item>
  104 + <div class="flex justify-between w-[100%]">
  105 + <Icon
  106 + icon="ant-design:github-filled"
  107 + :size="iconSize"
  108 + class="cursor-pointer anticon"
  109 + :color="iconColor"
  110 + @click="doSocialLogin('github')"
  111 + />
  112 + <Icon
  113 + icon="ant-design:wechat-filled"
  114 + :size="iconSize"
  115 + class="cursor-pointer anticon"
  116 + :color="iconColor"
  117 + @click="doSocialLogin('wechat')"
  118 + />
  119 + <Icon
  120 + icon="ant-design:alipay-circle-filled"
  121 + :size="iconSize"
  122 + :color="iconColor"
  123 + class="cursor-pointer anticon"
  124 + @click="doSocialLogin('alipay')"
  125 + />
  126 + <Icon
  127 + icon="ant-design:dingtalk-circle-filled"
  128 + :size="iconSize"
  129 + :color="iconColor"
  130 + class="cursor-pointer anticon"
  131 + @click="doSocialLogin('dingtalk')"
  132 + />
  133 + </div>
  134 + </el-form-item>
  135 + </el-col>
  136 + </el-row>
  137 + </el-form>
  138 +</template>
1 139 <script setup lang="ts">
2 140 import { useIcon } from '@/hooks/web/useIcon'
3 141 import LoginFormTitle from './LoginFormTitle.vue'
... ... @@ -153,144 +291,7 @@ onMounted(() =&gt; {
153 291 getCookie()
154 292 })
155 293 </script>
156   -<template>
157   - <el-form
158   - :model="loginData.loginForm"
159   - :rules="LoginRules"
160   - label-position="top"
161   - class="login-form"
162   - label-width="120px"
163   - size="large"
164   - v-show="getShow"
165   - ref="formLogin"
166   - >
167   - <el-row style="maring-left: -10px; maring-right: -10px">
168   - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
169   - <el-form-item>
170   - <LoginFormTitle style="width: 100%" />
171   - </el-form-item>
172   - </el-col>
173   - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
174   - <el-form-item prop="tenantName">
175   - <el-input
176   - type="text"
177   - v-model="loginData.loginForm.tenantName"
178   - :placeholder="t('login.tenantNamePlaceholder')"
179   - :prefix-icon="iconHouse"
180   - />
181   - </el-form-item>
182   - </el-col>
183   - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
184   - <el-form-item prop="username">
185   - <el-input
186   - v-model="loginData.loginForm.username"
187   - :placeholder="t('login.usernamePlaceholder')"
188   - :prefix-icon="iconAvatar"
189   - />
190   - </el-form-item>
191   - </el-col>
192   - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
193   - <el-form-item prop="password">
194   - <el-input
195   - v-model="loginData.loginForm.password"
196   - type="password"
197   - :placeholder="t('login.passwordPlaceholder')"
198   - show-password
199   - @keyup.enter="getCode()"
200   - :prefix-icon="iconLock"
201   - />
202   - </el-form-item>
203   - </el-col>
204   - <el-col
205   - :span="24"
206   - style="padding-left: 10px; padding-right: 10px; margin-top: -20px; margin-bottom: -20px"
207   - >
208   - <el-form-item>
209   - <el-row justify="space-between" style="width: 100%">
210   - <el-col :span="6">
211   - <el-checkbox v-model="loginData.loginForm.rememberMe">
212   - {{ t('login.remember') }}
213   - </el-checkbox>
214   - </el-col>
215   - <el-col :span="12" :offset="6">
216   - <el-link type="primary" style="float: right">{{ t('login.forgetPassword') }}</el-link>
217   - </el-col>
218   - </el-row>
219   - </el-form-item>
220   - </el-col>
221   - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
222   - <el-form-item>
223   - <el-button :loading="loginLoading" type="primary" class="w-[100%]" @click="getCode()">
224   - {{ t('login.login') }}
225   - </el-button>
226   - </el-form-item>
227   - </el-col>
228   - <Verify
229   - ref="verify"
230   - mode="pop"
231   - :captchaType="captchaType"
232   - :imgSize="{ width: '400px', height: '200px' }"
233   - @success="handleLogin"
234   - />
235   - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
236   - <el-form-item>
237   - <el-row justify="space-between" style="width: 100%" :gutter="5">
238   - <el-col :span="8">
239   - <el-button class="w-[100%]" @click="setLoginState(LoginStateEnum.MOBILE)">
240   - {{ t('login.btnMobile') }}
241   - </el-button>
242   - </el-col>
243   - <el-col :span="8">
244   - <el-button class="w-[100%]" @click="setLoginState(LoginStateEnum.QR_CODE)">
245   - {{ t('login.btnQRCode') }}
246   - </el-button>
247   - </el-col>
248   - <el-col :span="8">
249   - <el-button class="w-[100%]" @click="setLoginState(LoginStateEnum.REGISTER)">
250   - {{ t('login.btnRegister') }}
251   - </el-button>
252   - </el-col>
253   - </el-row>
254   - </el-form-item>
255   - </el-col>
256   - <el-divider content-position="center">{{ t('login.otherLogin') }}</el-divider>
257   - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
258   - <el-form-item>
259   - <div class="flex justify-between w-[100%]">
260   - <Icon
261   - icon="ant-design:github-filled"
262   - :size="iconSize"
263   - class="cursor-pointer anticon"
264   - :color="iconColor"
265   - @click="doSocialLogin('github')"
266   - />
267   - <Icon
268   - icon="ant-design:wechat-filled"
269   - :size="iconSize"
270   - class="cursor-pointer anticon"
271   - :color="iconColor"
272   - @click="doSocialLogin('wechat')"
273   - />
274   - <Icon
275   - icon="ant-design:alipay-circle-filled"
276   - :size="iconSize"
277   - :color="iconColor"
278   - class="cursor-pointer anticon"
279   - @click="doSocialLogin('alipay')"
280   - />
281   - <Icon
282   - icon="ant-design:dingtalk-circle-filled"
283   - :size="iconSize"
284   - :color="iconColor"
285   - class="cursor-pointer anticon"
286   - @click="doSocialLogin('dingtalk')"
287   - />
288   - </div>
289   - </el-form-item>
290   - </el-col>
291   - </el-row>
292   - </el-form>
293   -</template>
  294 +
294 295 <style lang="less" scoped>
295 296 :deep(.anticon) {
296 297 &:hover {
... ...
yudao-ui-admin-vue3/src/views/Login/components/LoginFormTitle.vue
  1 +<template>
  2 + <h2 class="mb-3 text-2xl font-bold text-center xl:text-3xl enter-x xl:text-center">
  3 + {{ getFormTitle }}
  4 + </h2>
  5 +</template>
1 6 <script setup lang="ts">
2 7 import { computed, unref } from 'vue'
3 8 import { useI18n } from '@/hooks/web/useI18n'
... ... @@ -18,8 +23,3 @@ const getFormTitle = computed(() =&gt; {
18 23 return titleObj[unref(getLoginState)]
19 24 })
20 25 </script>
21   -<template>
22   - <h2 class="mb-3 text-2xl font-bold text-center xl:text-3xl enter-x xl:text-center">
23   - {{ getFormTitle }}
24   - </h2>
25   -</template>
... ...
yudao-ui-admin-vue3/src/views/Login/components/MobileForm.vue
  1 +<template>
  2 + <el-form
  3 + :model="loginData.loginForm"
  4 + :rules="rules"
  5 + label-position="top"
  6 + class="login-form"
  7 + label-width="120px"
  8 + size="large"
  9 + v-show="getShow"
  10 + ref="formSmsLogin"
  11 + >
  12 + <el-row style="margin-left: -10px; margin-right: -10px">
  13 + <!-- 租户名 -->
  14 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  15 + <el-form-item>
  16 + <LoginFormTitle style="width: 100%" />
  17 + </el-form-item>
  18 + </el-col>
  19 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  20 + <el-form-item prop="tenantName">
  21 + <el-input
  22 + type="text"
  23 + v-model="loginData.loginForm.tenantName"
  24 + :placeholder="t('login.tenantNamePlaceholder')"
  25 + :prefix-icon="iconHouse"
  26 + />
  27 + </el-form-item>
  28 + </el-col>
  29 + <!-- 手机号 -->
  30 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  31 + <el-form-item prop="mobileNumber">
  32 + <el-input
  33 + v-model="loginData.loginForm.mobileNumber"
  34 + :placeholder="t('login.mobileNumberPlaceholder')"
  35 + :prefix-icon="iconCellphone"
  36 + />
  37 + </el-form-item>
  38 + </el-col>
  39 + <!-- 验证码 -->
  40 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  41 + <el-form-item prop="code">
  42 + <el-row justify="space-between" style="width: 100%" :gutter="5">
  43 + <el-col :span="24">
  44 + <el-input
  45 + v-model="loginData.loginForm.code"
  46 + :placeholder="t('login.codePlaceholder')"
  47 + :prefix-icon="iconCircleCheck"
  48 + >
  49 + <!-- <el-button class="w-[100%]"> -->
  50 + <template #append>
  51 + <span
  52 + v-if="mobileCodeTimer <= 0"
  53 + @click="getSmsCode"
  54 + class="getMobileCode"
  55 + style="cursor: pointer"
  56 + >
  57 + {{ t('login.getSmsCode') }}
  58 + </span>
  59 + <span v-if="mobileCodeTimer > 0" class="getMobileCode" style="cursor: pointer">
  60 + {{ mobileCodeTimer }}秒后可重新获取
  61 + </span>
  62 + </template>
  63 + </el-input>
  64 + <!-- </el-button> -->
  65 + </el-col>
  66 + </el-row>
  67 + </el-form-item>
  68 + </el-col>
  69 + <!-- 登录按钮 / 返回按钮 -->
  70 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  71 + <el-form-item>
  72 + <el-button :loading="loginLoading" type="primary" class="w-[100%]" @click="signIn">
  73 + {{ t('login.login') }}
  74 + </el-button>
  75 + </el-form-item>
  76 + </el-col>
  77 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  78 + <el-form-item>
  79 + <el-button :loading="loginLoading" class="w-[100%]" @click="handleBackLogin">
  80 + {{ t('login.backLogin') }}
  81 + </el-button>
  82 + </el-form-item>
  83 + </el-col>
  84 + </el-row>
  85 + </el-form>
  86 +</template>
1 87 <script setup lang="ts">
2 88 import { useIcon } from '@/hooks/web/useIcon'
3 89 import { reactive, ref, unref, watch, computed } from 'vue'
... ... @@ -111,92 +197,7 @@ const signIn = async () =&gt; {
111 197 })
112 198 }
113 199 </script>
114   -<template>
115   - <el-form
116   - :model="loginData.loginForm"
117   - :rules="rules"
118   - label-position="top"
119   - class="login-form"
120   - label-width="120px"
121   - size="large"
122   - v-show="getShow"
123   - ref="formSmsLogin"
124   - >
125   - <el-row style="margin-left: -10px; margin-right: -10px">
126   - <!-- 租户名 -->
127   - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
128   - <el-form-item>
129   - <LoginFormTitle style="width: 100%" />
130   - </el-form-item>
131   - </el-col>
132   - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
133   - <el-form-item prop="tenantName">
134   - <el-input
135   - type="text"
136   - v-model="loginData.loginForm.tenantName"
137   - :placeholder="t('login.tenantNamePlaceholder')"
138   - :prefix-icon="iconHouse"
139   - />
140   - </el-form-item>
141   - </el-col>
142   - <!-- 手机号 -->
143   - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
144   - <el-form-item prop="mobileNumber">
145   - <el-input
146   - v-model="loginData.loginForm.mobileNumber"
147   - :placeholder="t('login.mobileNumberPlaceholder')"
148   - :prefix-icon="iconCellphone"
149   - />
150   - </el-form-item>
151   - </el-col>
152   - <!-- 验证码 -->
153   - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
154   - <el-form-item prop="code">
155   - <el-row justify="space-between" style="width: 100%" :gutter="5">
156   - <el-col :span="24">
157   - <el-input
158   - v-model="loginData.loginForm.code"
159   - :placeholder="t('login.codePlaceholder')"
160   - :prefix-icon="iconCircleCheck"
161   - >
162   - <!-- <el-button class="w-[100%]"> -->
163   - <template #append>
164   - <span
165   - v-if="mobileCodeTimer <= 0"
166   - @click="getSmsCode"
167   - class="getMobileCode"
168   - style="cursor: pointer"
169   - >
170   - {{ t('login.getSmsCode') }}
171   - </span>
172   - <span v-if="mobileCodeTimer > 0" class="getMobileCode" style="cursor: pointer">
173   - {{ mobileCodeTimer }}秒后可重新获取
174   - </span>
175   - </template>
176   - </el-input>
177   - <!-- </el-button> -->
178   - </el-col>
179   - </el-row>
180   - </el-form-item>
181   - </el-col>
182   - <!-- 登录按钮 / 返回按钮 -->
183   - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
184   - <el-form-item>
185   - <el-button :loading="loginLoading" type="primary" class="w-[100%]" @click="signIn">
186   - {{ t('login.login') }}
187   - </el-button>
188   - </el-form-item>
189   - </el-col>
190   - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
191   - <el-form-item>
192   - <el-button :loading="loginLoading" class="w-[100%]" @click="handleBackLogin">
193   - {{ t('login.backLogin') }}
194   - </el-button>
195   - </el-form-item>
196   - </el-col>
197   - </el-row>
198   - </el-form>
199   -</template>
  200 +
200 201 <style lang="less" scoped>
201 202 :deep(.anticon) {
202 203 &:hover {
... ...
yudao-ui-admin-vue3/src/views/Login/components/QrCodeForm.vue
1   -<script setup lang="ts">
2   -import { computed, unref } from 'vue'
3   -import { ElRow, ElCol, ElCard, ElDivider } from 'element-plus'
4   -import { useI18n } from '@/hooks/web/useI18n'
5   -import { useLoginState, LoginStateEnum } from './useLogin'
6   -import LoginFormTitle from './LoginFormTitle.vue'
7   -import { Qrcode } from '@/components/Qrcode'
8   -import logoImg from '@/assets/imgs/logo.png'
9   -
10   -const { t } = useI18n()
11   -const { handleBackLogin, getLoginState } = useLoginState()
12   -const getShow = computed(() => unref(getLoginState) === LoginStateEnum.QR_CODE)
13   -</script>
14   -
15 1 <template>
16 2 <el-row v-show="getShow" style="maring-left: -10px; maring-right: -10px">
17 3 <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
... ... @@ -32,3 +18,16 @@ const getShow = computed(() =&gt; unref(getLoginState) === LoginStateEnum.QR_CODE)
32 18 </el-col>
33 19 </el-row>
34 20 </template>
  21 +<script setup lang="ts">
  22 +import { computed, unref } from 'vue'
  23 +import { ElRow, ElCol, ElCard, ElDivider } from 'element-plus'
  24 +import { useI18n } from '@/hooks/web/useI18n'
  25 +import { useLoginState, LoginStateEnum } from './useLogin'
  26 +import LoginFormTitle from './LoginFormTitle.vue'
  27 +import { Qrcode } from '@/components/Qrcode'
  28 +import logoImg from '@/assets/imgs/logo.png'
  29 +
  30 +const { t } = useI18n()
  31 +const { handleBackLogin, getLoginState } = useLoginState()
  32 +const getShow = computed(() => unref(getLoginState) === LoginStateEnum.QR_CODE)
  33 +</script>
... ...
yudao-ui-admin-vue3/src/views/Login/components/RegisterForm.vue
  1 +<template>
  2 + <Form
  3 + :schema="schema"
  4 + :rules="rules"
  5 + label-position="top"
  6 + hide-required-asterisk
  7 + size="large"
  8 + v-show="getShow"
  9 + class="dark:(border-1 border-[var(--el-border-color)] border-solid)"
  10 + @register="register"
  11 + >
  12 + <template #title>
  13 + <LoginFormTitle style="width: 100%" />
  14 + </template>
  15 +
  16 + <template #code="form">
  17 + <div class="w-[100%] flex">
  18 + <el-input v-model="form['code']" :placeholder="t('login.codePlaceholder')" />
  19 + </div>
  20 + </template>
  21 +
  22 + <template #register>
  23 + <div class="w-[100%]">
  24 + <el-button type="primary" class="w-[100%]" :loading="loading" @click="loginRegister">
  25 + {{ t('login.register') }}
  26 + </el-button>
  27 + </div>
  28 + <div class="w-[100%] mt-15px">
  29 + <el-button class="w-[100%]" @click="handleBackLogin">
  30 + {{ t('login.hasUser') }}
  31 + </el-button>
  32 + </div>
  33 + </template>
  34 + </Form>
  35 +</template>
  36 +
1 37 <script setup lang="ts">
2 38 import { Form } from '@/components/Form'
3 39 import { computed, reactive, ref, unref } from 'vue'
... ... @@ -104,39 +140,3 @@ const loginRegister = async () =&gt; {
104 140 })
105 141 }
106 142 </script>
107   -
108   -<template>
109   - <Form
110   - :schema="schema"
111   - :rules="rules"
112   - label-position="top"
113   - hide-required-asterisk
114   - size="large"
115   - v-show="getShow"
116   - class="dark:(border-1 border-[var(--el-border-color)] border-solid)"
117   - @register="register"
118   - >
119   - <template #title>
120   - <LoginFormTitle style="width: 100%" />
121   - </template>
122   -
123   - <template #code="form">
124   - <div class="w-[100%] flex">
125   - <el-input v-model="form['code']" :placeholder="t('login.codePlaceholder')" />
126   - </div>
127   - </template>
128   -
129   - <template #register>
130   - <div class="w-[100%]">
131   - <el-button type="primary" class="w-[100%]" :loading="loading" @click="loginRegister">
132   - {{ t('login.register') }}
133   - </el-button>
134   - </div>
135   - <div class="w-[100%] mt-15px">
136   - <el-button class="w-[100%]" @click="handleBackLogin">
137   - {{ t('login.hasUser') }}
138   - </el-button>
139   - </div>
140   - </template>
141   - </Form>
142   -</template>
... ...
yudao-ui-admin-vue3/src/views/Profile/components/BasicInfo.vue
... ... @@ -62,7 +62,8 @@ const schema = reactive&lt;FormSchema[]&gt;([
62 62 {
63 63 field: 'sex',
64 64 label: t('profile.user.sex'),
65   - component: 'InputNumber'
  65 + component: 'InputNumber',
  66 + value: 0
66 67 }
67 68 ])
68 69 const sexVlue = ref<number>()
... ...
yudao-ui-admin-vue3/src/views/infra/codegen/codegen.data.ts
... ... @@ -17,40 +17,28 @@ const crudSchemas = reactive&lt;CrudSchema[]&gt;([
17 17 label: t('common.index'),
18 18 field: 'id',
19 19 type: 'index',
20   - form: {
21   - show: false
22   - },
23   - detail: {
24   - show: false
25   - }
  20 + isForm: false,
  21 + isDetail: false
26 22 },
27 23 {
28 24 label: '表名称',
29 25 field: 'tableName',
30   - search: {
31   - show: true
32   - }
  26 + isSearch: true
33 27 },
34 28 {
35 29 label: '表描述',
36 30 field: 'tableComment',
37   - search: {
38   - show: true
39   - }
  31 + isSearch: true
40 32 },
41 33 {
42 34 label: '实体',
43 35 field: 'className',
44   - search: {
45   - show: true
46   - }
  36 + isSearch: true
47 37 },
48 38 {
49 39 label: t('common.createTime'),
50 40 field: 'createTime',
51   - form: {
52   - show: false
53   - },
  41 + isForm: false,
54 42 search: {
55 43 show: true,
56 44 component: 'DatePicker',
... ... @@ -64,20 +52,14 @@ const crudSchemas = reactive&lt;CrudSchema[]&gt;([
64 52 {
65 53 label: t('common.updateTime'),
66 54 field: 'updateTime',
67   - form: {
68   - show: false
69   - }
  55 + isForm: false
70 56 },
71 57 {
72 58 label: t('table.action'),
73 59 field: 'action',
74   - width: '500px',
75   - form: {
76   - show: false
77   - },
78   - detail: {
79   - show: false
80   - }
  60 + width: '350px',
  61 + isForm: false,
  62 + isDetail: false
81 63 }
82 64 ])
83 65 export const { allSchemas } = useCrudSchemas(crudSchemas)
... ...
yudao-ui-admin-vue3/src/views/infra/codegen/components/ImportTable.vue
... ... @@ -33,7 +33,7 @@
33 33 :data="dbTableList"
34 34 v-loading="dbLoading"
35 35 :checkbox-config="{ highlight: true, range: true }"
36   - height="350px"
  36 + height="260px"
37 37 class="xtable-scrollbar"
38 38 >
39 39 <vxe-column type="checkbox" width="60" />
... ...
yudao-ui-admin-vue3/src/views/system/dept/dept.data.ts
... ... @@ -49,8 +49,7 @@ export const modelSchema = reactive&lt;FormSchema[]&gt;([
49 49 {
50 50 label: '显示排序',
51 51 field: 'sort',
52   - component: 'InputNumber',
53   - value: 0
  52 + component: 'Input'
54 53 },
55 54 {
56 55 label: '状态',
... ...
yudao-ui-admin-vue3/src/views/system/dept/index.vue
1 1 <template>
2   - <div class="flex">
3   - <el-card class="w-1/3 dept" :gutter="12" shadow="always">
4   - <template #header>
5   - <div class="card-header">
6   - <span>部门列表</span>
7   - <XButton
8   - type="primary"
9   - preIcon="ep:zoom-in"
10   - title="新增根节点"
11   - v-hasPermi="['system:dept:create']"
12   - @click="handleCreate"
  2 + <ContentWrap>
  3 + <!-- 搜索工作栏 -->
  4 + <el-form :model="queryParams" ref="queryForm" :inline="true">
  5 + <el-form-item label="部门名称" prop="name">
  6 + <el-input v-model="queryParams.name" placeholder="请输入部门名称" />
  7 + </el-form-item>
  8 + <el-form-item label="状态" prop="status">
  9 + <el-select v-model="queryParams.status" placeholder="请选择部门状态">
  10 + <el-option
  11 + v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
  12 + :key="dict.value"
  13 + :label="dict.label"
  14 + :value="dict.value"
13 15 />
14   - </div>
  16 + </el-select>
  17 + </el-form-item>
  18 + <el-form-item>
  19 + <!-- 操作:搜索 -->
  20 + <XButton
  21 + type="primary"
  22 + preIcon="ep:search"
  23 + :title="t('common.query')"
  24 + @click="handleQuery()"
  25 + />
  26 + <!-- 操作:重置 -->
  27 + <XButton preIcon="ep:refresh-right" :title="t('common.reset')" @click="resetQuery()" />
  28 + </el-form-item>
  29 + </el-form>
  30 + <vxe-toolbar>
  31 + <template #buttons>
  32 + <!-- 操作:新增 -->
  33 + <XButton
  34 + type="primary"
  35 + preIcon="ep:zoom-in"
  36 + :title="t('action.add')"
  37 + v-hasPermi="['system:dept:create']"
  38 + @click="handleCreate()"
  39 + />
  40 + <XButton title="展开所有" @click="xTable?.setAllTreeExpand(true)" />
  41 + <XButton title="关闭所有" @click="xTable?.clearTreeExpand()" />
15 42 </template>
16   - <div class="custom-tree-container">
17   - <!-- <p>部门列表</p> -->
18   - <!-- 操作工具栏 -->
19   - <el-input v-model="filterText" placeholder="搜索部门" />
20   - <el-tree
21   - ref="treeRef"
  43 + </vxe-toolbar>
  44 + <!-- 列表 -->
  45 + <vxe-table
  46 + show-overflow
  47 + keep-source
  48 + ref="xTable"
  49 + :loading="tableLoading"
  50 + :row-config="{ keyField: 'id' }"
  51 + :column-config="{ resizable: true }"
  52 + :tree-config="{ transform: true, rowField: 'id', parentField: 'parentId' }"
  53 + :print-config="{}"
  54 + :export-config="{}"
  55 + :data="tableData"
  56 + class="xtable"
  57 + >
  58 + <vxe-column title="部门名称" field="name" width="200" tree-node />
  59 + <vxe-column title="负责人" field="leaderUserId" :formatter="userNicknameFormat" />
  60 + <vxe-column title="排序" field="sort" />
  61 + <vxe-column title="状态" field="status">
  62 + <template #default="{ row }">
  63 + <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
  64 + </template>
  65 + </vxe-column>
  66 + <vxe-column title="创建时间" field="createTime" formatter="formatDate" />
  67 + <vxe-column title="操作" width="200">
  68 + <template #default="{ row }">
  69 + <!-- 操作:修改 -->
  70 + <XTextButton
  71 + preIcon="ep:edit"
  72 + :title="t('action.edit')"
  73 + v-hasPermi="['system:dept:update']"
  74 + @click="handleUpdate(row.id)"
  75 + />
  76 + <!-- 操作:删除 -->
  77 + <XTextButton
  78 + preIcon="ep:delete"
  79 + :title="t('action.del')"
  80 + v-hasPermi="['system:dept:delete']"
  81 + @click="handleDelete(row.id)"
  82 + />
  83 + </template>
  84 + </vxe-column>
  85 + </vxe-table>
  86 + </ContentWrap>
  87 + <!-- 添加或修改菜单对话框 -->
  88 + <XModal id="deptModel" v-model="dialogVisible" :title="dialogTitle">
  89 + <!-- 对话框(添加 / 修改) -->
  90 + <!-- 操作工具栏 -->
  91 + <Form ref="formRef" :schema="modelSchema" :rules="rules">
  92 + <template #parentId>
  93 + <el-tree-select
22 94 node-key="id"
23   - :data="deptOptions"
  95 + v-model="deptParentId"
24 96 :props="defaultProps"
25   - :highlight-current="true"
26   - default-expand-all
27   - :filter-node-method="filterNode"
28   - :expand-on-click-node="false"
29   - >
30   - <template #default="{ node, data }">
31   - <span class="custom-tree-node">
32   - <span>{{ node.label }}</span>
33   - <span>
34   - <XTextButton
35   - preIcon="ep:zoom-in"
36   - :title="t('action.add')"
37   - v-hasPermi="['system:dept:create']"
38   - @click="handleCreate(data)"
39   - />
40   - <XTextButton
41   - preIcon="ep:edit"
42   - :title="t('action.edit')"
43   - v-hasPermi="['system:dept:update']"
44   - @click="handleUpdate(data)"
45   - />
46   - <XTextButton
47   - preIcon="ep:delete"
48   - :title="t('action.del')"
49   - v-hasPermi="['system:dept:delete']"
50   - @click="handleDelete(data)"
51   - />
52   - </span>
53   - </span>
54   - </template>
55   - </el-tree>
56   - </div>
57   - </el-card>
58   - <el-card class="w-2/3 dept" style="margin-left: 10px" :gutter="12" shadow="hover">
59   - <template #header>
60   - <div class="card-header">
61   - <span>{{ formTitle }}</span>
62   - </div>
63   - </template>
64   - <div v-if="!showForm">
65   - <span><p>请从左侧选择部门</p></span>
66   - </div>
67   - <div v-if="showForm">
68   - <!-- 操作工具栏 -->
69   - <Form ref="formRef" :schema="modelSchema" :rules="rules">
70   - <template #parentId>
71   - <el-tree-select
72   - node-key="id"
73   - v-model="deptParentId"
74   - :props="defaultProps"
75   - :data="deptOptions"
76   - check-strictly
77   - />
78   - </template>
79   - <template #leaderUserId>
80   - <el-select v-model="leaderUserId">
81   - <el-option
82   - v-for="item in userOption"
83   - :key="parseInt(item.id)"
84   - :label="item.nickname"
85   - :value="parseInt(item.id)"
86   - />
87   - </el-select>
88   - </template>
89   - </Form>
90   - <!-- 按钮:保存 -->
91   - <XButton
92   - type="primary"
93   - :title="t('action.save')"
94   - v-hasPermi="['system:dept:update']"
95   - :loading="loading"
96   - @click="submitForm()"
  97 + :data="deptOptions"
  98 + :default-expanded-keys="[100]"
  99 + check-strictly
97 100 />
98   - <!-- 按钮:关闭 -->
99   - <XButton :loading="loading" :title="t('dialog.close')" @click="showForm = false" />
100   - </div>
101   - </el-card>
102   - </div>
  101 + </template>
  102 + <template #leaderUserId>
  103 + <el-select v-model="leaderUserId">
  104 + <el-option
  105 + v-for="item in userOption"
  106 + :key="parseInt(item.id)"
  107 + :label="item.nickname"
  108 + :value="parseInt(item.id)"
  109 + />
  110 + </el-select>
  111 + </template>
  112 + </Form>
  113 + <template #footer>
  114 + <!-- 按钮:保存 -->
  115 + <XButton
  116 + v-if="['create', 'update'].includes(actionType)"
  117 + type="primary"
  118 + :loading="actionLoading"
  119 + @click="submitForm()"
  120 + :title="t('action.save')"
  121 + />
  122 + <!-- 按钮:关闭 -->
  123 + <XButton :loading="actionLoading" @click="dialogVisible = false" :title="t('dialog.close')" />
  124 + </template>
  125 + </XModal>
103 126 </template>
104 127 <script setup lang="ts">
  128 +import { nextTick, onMounted, reactive, ref, unref } from 'vue'
105 129 import { useI18n } from '@/hooks/web/useI18n'
106   -import { ElInput, ElCard, ElTree, ElTreeSelect, ElSelect, ElOption } from 'element-plus'
107   -import { handleTree } from '@/utils/tree'
108   -import { onMounted, ref, unref, watch } from 'vue'
109   -import * as DeptApi from '@/api/system/dept'
110   -import { Form, FormExpose } from '@/components/Form'
111   -import { modelSchema, rules } from './dept.data'
112   -import { DeptVO } from '@/api/system/dept/types'
113 130 import { useMessage } from '@/hooks/web/useMessage'
  131 +import { ElForm, ElFormItem, ElInput, ElSelect, ElTreeSelect, ElOption } from 'element-plus'
  132 +import { VxeColumn, VxeTable, VxeTableInstance, VxeToolbar } from 'vxe-table'
  133 +import { modelSchema } from './dept.data'
  134 +import * as DeptApi from '@/api/system/dept'
114 135 import { getListSimpleUsersApi } from '@/api/system/user'
115   -const message = useMessage()
  136 +import { required } from '@/utils/formRules.js'
  137 +import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
  138 +import { handleTree } from '@/utils/tree'
  139 +import { FormExpose } from '@/components/Form'
116 140  
  141 +const { t } = useI18n() // 国际化
  142 +const message = useMessage() // 消息弹窗
  143 +// 列表相关的变量
  144 +const xTable = ref<VxeTableInstance>()
  145 +const tableLoading = ref(false)
  146 +const tableData = ref()
  147 +// 弹窗相关的变量
  148 +const dialogVisible = ref(false) // 是否显示弹出层
  149 +const dialogTitle = ref('edit') // 弹出层标题
  150 +const actionType = ref('') // 操作按钮的类型
  151 +const actionLoading = ref(false) // 遮罩层
  152 +const deptParentId = ref(0) // 上级ID
  153 +const leaderUserId = ref()
  154 +const formRef = ref<FormExpose>() // 表单 Ref
  155 +const deptOptions = ref() // 树形结构
  156 +const userOption = ref()
  157 +// 新增和修改的表单校验
  158 +const rules = reactive({
  159 + name: [required],
  160 + sort: [required],
  161 + path: [required],
  162 + status: [required]
  163 +})
  164 +
  165 +// 下拉框[上级]的配置项目
117 166 const defaultProps = {
  167 + checkStrictly: true,
118 168 children: 'children',
119 169 label: 'name',
120 170 value: 'id'
121 171 }
122   -const { t } = useI18n() // 国际化
123   -const loading = ref(false) // 遮罩层
124   -const dialogVisible = ref(false) // 是否显示弹出层
125   -const showForm = ref(false) // 显示form表单
126   -const formTitle = ref('部门信息') // 显示form标题
127   -const deptParentId = ref(0) // 上级ID
128   -// 创建form表单
129   -const formRef = ref<FormExpose>()
130   -
131   -// ========== 创建部门树结构 ==========
132   -const filterText = ref('')
133   -const deptOptions = ref() // 树形结构
134   -const treeRef = ref<InstanceType<typeof ElTree>>()
  172 +// 获取下拉框[上级]的数据
135 173 const getTree = async () => {
136 174 const res = await DeptApi.listSimpleDeptApi()
137 175 deptOptions.value = handleTree(res)
  176 + console.info(deptOptions.value)
138 177 }
139   -const filterNode = (value: string, data: Tree) => {
140   - if (!value) return true
141   - return data.name.includes(value)
142   -}
143   -watch(filterText, (val) => {
144   - treeRef.value!.filter(val)
145   -})
146   -// 用户列表
147   -const userOption = ref()
148   -const leaderUserId = ref()
149 178 const getUserList = async () => {
150 179 const res = await getListSimpleUsersApi()
151 180 userOption.value = res
152 181 }
153   -// 新增
154   -const handleCreate = (data: { id: number }) => {
155   - // 重置表单
156   - deptParentId.value = data.id
157   - formTitle.value = '新增部门'
158   - showForm.value = true
  182 +// ========== 查询 ==========
  183 +const queryParams = reactive<DeptApi.DeptPageReqVO>({
  184 + name: undefined,
  185 + status: undefined
  186 +})
  187 +// 执行查询
  188 +const getList = async () => {
  189 + tableLoading.value = true
  190 + const res = await DeptApi.getDeptPageApi(queryParams)
  191 + tableData.value = res
  192 + tableLoading.value = false
  193 +}
  194 +
  195 +// 查询操作
  196 +const handleQuery = async () => {
  197 + await getList()
  198 +}
  199 +
  200 +// 重置操作
  201 +const resetQuery = async () => {
  202 + queryParams.name = undefined
  203 + queryParams.status = undefined
  204 + await getList()
  205 +}
  206 +
  207 +// ========== 新增/修改 ==========
  208 +
  209 +// 设置标题
  210 +const setDialogTile = (type: string) => {
  211 + dialogTitle.value = t('action.' + type)
  212 + actionType.value = type
  213 + dialogVisible.value = true
  214 +}
  215 +
  216 +// 新增操作
  217 +const handleCreate = async () => {
  218 + deptParentId.value = 0
  219 + leaderUserId.value = null
  220 + setDialogTile('create')
159 221 }
160   -// 编辑
161   -const handleUpdate = async (data: { id: number }) => {
162   - const res = await DeptApi.getDeptApi(data.id)
163   - formTitle.value = '修改- ' + res?.name
164   - deptParentId.value = res.parentId
  222 +
  223 +// 修改操作
  224 +const handleUpdate = async (rowId: number) => {
  225 + setDialogTile('update')
  226 + // 设置数据
  227 + const res = await DeptApi.getDeptApi(rowId)
  228 + console.info(res)
  229 + deptParentId.value = res.deptParentId
165 230 leaderUserId.value = res.leaderUserId
  231 + await nextTick()
166 232 unref(formRef)?.setValues(res)
167   - showForm.value = true
168   -}
169   -// 删除
170   -const handleDelete = async (data: { id: number }) => {
171   - message
172   - .confirm(t('common.delDataMessage'), t('common.confirmTitle'))
173   - .then(async () => {
174   - await DeptApi.deleteDeptApi(data.id)
175   - message.success(t('common.delSuccess'))
176   - })
177   - .catch(() => {})
178   - await getTree()
179 233 }
180   -// 提交按钮
  234 +
  235 +// 提交新增/修改的表单
181 236 const submitForm = async () => {
182 237 const elForm = unref(formRef)?.getElFormRef()
183 238 if (!elForm) return
184 239 elForm.validate(async (valid) => {
185 240 if (valid) {
186   - loading.value = true
  241 + actionLoading.value = true
187 242 // 提交请求
188 243 try {
189   - const data = unref(formRef)?.formModel as DeptVO
  244 + const data = unref(formRef)?.formModel as DeptApi.DeptVO
190 245 data.parentId = deptParentId.value
191 246 data.leaderUserId = leaderUserId.value
192   - if (formTitle.value.startsWith('新增')) {
  247 + if (dialogTitle.value.startsWith('新增')) {
193 248 await DeptApi.createDeptApi(data)
194   - } else if (formTitle.value.startsWith('修改')) {
  249 + } else if (dialogTitle.value.startsWith('修改')) {
195 250 await DeptApi.updateDeptApi(data)
196 251 }
197 252 // 操作成功,重新加载列表
198 253 dialogVisible.value = false
199 254 } finally {
200   - loading.value = false
  255 + actionLoading.value = false
201 256 }
202 257 }
203 258 })
204 259 }
  260 +
  261 +// 删除操作
  262 +const handleDelete = async (rowId: number) => {
  263 + message.delConfirm().then(async () => {
  264 + await DeptApi.deleteDeptApi(rowId)
  265 + message.success(t('common.delSuccess'))
  266 + await getList()
  267 + })
  268 +}
  269 +
  270 +const userNicknameFormat = (row) => {
  271 + if (!row && !row.row && !row.row.leaderUserId) {
  272 + return '未设置'
  273 + }
  274 + for (const user of userOption.value) {
  275 + if (row.row.leaderUserId === user.id) {
  276 + return user.nickname
  277 + }
  278 + }
  279 + return '未知【' + row.row.leaderUserId + '】'
  280 +}
  281 +
  282 +// ========== 初始化 ==========
205 283 onMounted(async () => {
206 284 await getTree()
207 285 await getUserList()
  286 + await getList()
208 287 })
209 288 </script>
210   -
211   -<style scoped>
212   -.dept {
213   - height: 600px;
214   - max-height: 1800px;
215   -}
216   -.card-header {
217   - display: flex;
218   - justify-content: space-between;
219   - align-items: center;
220   -}
221   -.custom-tree-node {
222   - flex: 1;
223   - display: flex;
224   - align-items: center;
225   - justify-content: space-between;
226   - font-size: 14px;
227   - padding-right: 8px;
228   -}
229   -</style>
... ...
yudao-ui-admin-vue3/src/views/system/dict/index.vue
... ... @@ -119,7 +119,14 @@
119 119 :schema="DictTypeSchemas.allSchemas.formSchema"
120 120 :rules="DictTypeSchemas.dictTypeRules"
121 121 ref="typeFormRef"
122   - />
  122 + >
  123 + <template #type>
  124 + <template v-if="dictTypeValue">
  125 + <el-tag>{{ dictTypeValue }}</el-tag>
  126 + </template>
  127 + <template v-else><el-input v-model="dictTypeValue" /> </template>
  128 + </template>
  129 + </Form>
123 130 <Form
124 131 v-if="['dataCreate', 'dataUpdate'].includes(actionType)"
125 132 :schema="DictDataSchemas.allSchemas.formSchema"
... ... @@ -152,6 +159,7 @@ import { ref, unref, onMounted } from &#39;vue&#39;
152 159 import { DICT_TYPE } from '@/utils/dict'
153 160 import { useI18n } from '@/hooks/web/useI18n'
154 161 import { FormExpose } from '@/components/Form'
  162 +import { ElInput, ElTag } from 'element-plus'
155 163 import * as DictTypeSchemas from './dict.type'
156 164 import * as DictDataSchemas from './dict.data'
157 165 import { useTable } from '@/hooks/web/useTable'
... ... @@ -174,15 +182,17 @@ const {
174 182 setSearchParams: setTypeSearchParams,
175 183 delList: delTypeList
176 184 } = typeMethods
177   -
  185 +const dictTypeValue = ref('')
178 186 // 字典分类修改操作
179 187 const handleTypeCreate = () => {
  188 + dictTypeValue.value = ''
180 189 setDialogTile('typeCreate')
181 190 }
182 191 const handleTypeUpdate = async (row: DictTypeVO) => {
183 192 setDialogTile('typeUpdate')
184 193 // 设置数据
185 194 const res = await DictTypeApi.getDictTypeApi(row.id)
  195 + dictTypeValue.value = res.type
186 196 unref(typeFormRef)?.setValues(res)
187 197 }
188 198  
... ... @@ -229,6 +239,7 @@ const actionLoading = ref(false) // 遮罩层
229 239 const typeFormRef = ref<FormExpose>() // 分类表单 Ref
230 240 const dataFormRef = ref<FormExpose>() // 数据表单 Ref
231 241 const actionType = ref('') // 操作按钮的类型
  242 +
232 243 // 设置标题
233 244 const setDialogTile = (type: string) => {
234 245 dialogTitle.value = t('action.' + type)
... ... @@ -246,6 +257,7 @@ const submitTypeForm = async () =&gt; {
246 257 try {
247 258 const data = unref(typeFormRef)?.formModel as DictTypeVO
248 259 if (actionType.value === 'typeCreate') {
  260 + data.type = dictTypeValue.value
249 261 await DictTypeApi.createDictTypeApi(data)
250 262 ElMessage.success(t('common.createSuccess'))
251 263 } else if (actionType.value === 'typeUpdate') {
... ...
yudao-ui-admin-vue3/src/views/system/tenant/tenant.data.ts
... ... @@ -82,8 +82,7 @@ const crudSchemas = reactive&lt;CrudSchema[]&gt;([
82 82 label: '账号额度',
83 83 field: 'accountCount',
84 84 form: {
85   - component: 'InputNumber',
86   - value: 0
  85 + component: 'InputNumber'
87 86 }
88 87 },
89 88 {
... ...
yudao-ui-admin-vue3/src/views/system/user/user.data.ts
... ... @@ -74,6 +74,7 @@ const crudSchemas = reactive&lt;VxeCrudSchema&gt;({
74 74 {
75 75 title: '最后登录时间',
76 76 field: 'loginDate',
  77 + formatter: 'formatDate',
77 78 isForm: false
78 79 },
79 80 {
... ...
yudao-ui-admin-vue3/vite.config.ts
... ... @@ -13,7 +13,7 @@ import { createHtmlPlugin } from &#39;vite-plugin-html&#39;
13 13 import viteCompression from 'vite-plugin-compression'
14 14 import VueMarcos from 'unplugin-vue-macros/vite'
15 15  
16   -// 当前执行node命令时文件夹的地址(工作目录)
  16 +// 当前执行node命令时文件夹的地址(工作目录)
17 17 const root = process.cwd()
18 18  
19 19 // 路径查找
... ... @@ -144,6 +144,8 @@ export default ({ command, mode }: ConfigEnv): UserConfig =&gt; {
144 144 'vue-router',
145 145 'vue-types',
146 146 'vue-i18n',
  147 + 'vxe-table',
  148 + 'xe-utils',
147 149 'element-plus/es',
148 150 'element-plus/es/locale/lang/zh-cn',
149 151 'element-plus/es/locale/lang/en',
... ...
yudao-ui-admin/src/api/login.js
... ... @@ -126,5 +126,23 @@ export function authorize(responseType, clientId, redirectUri, state,
126 126 })
127 127 }
128 128  
  129 +// 获取验证图片 以及token
  130 +export function reqGet(data) {
  131 + return request({
  132 + url: 'system/captcha/get',
  133 + method: 'post',
  134 + data
  135 + })
  136 +}
  137 +
  138 +// 滑动或者点选验证
  139 +export function reqCheck(data) {
  140 + return request({
  141 + url: '/system/captcha/check',
  142 + method: 'post',
  143 + data
  144 + })
  145 +}
  146 +
129 147 export class socialBindLogin {
130 148 }
... ...
yudao-ui-admin/src/components/RightToolbar/index.vue
... ... @@ -92,13 +92,13 @@ export default {
92 92 };
93 93 </script>
94 94 <style lang="scss" scoped>
95   -::v-deep .el-transfer__button {
  95 +:deep(.el-transfer__button) {
96 96 border-radius: 50%;
97 97 padding: 12px;
98 98 display: block;
99 99 margin-left: 0px;
100 100 }
101   -::v-deep .el-transfer__button:first-child {
  101 +:deep(.el-transfer__button:first-child) {
102 102 margin-bottom: 10px;
103 103 }
104 104 </style>
... ...
yudao-ui-admin/src/components/Verifition/Verify/VerifyPoints.vue
... ... @@ -60,7 +60,7 @@
60 60 * */
61 61 import { resetSize } from './../utils/util'
62 62 import { aesEncrypt } from '@/utils/ase'
63   -import { reqGet, reqCheck } from './../api/index'
  63 +import { reqGet, reqCheck } from '@/api/login'
64 64  
65 65 export default {
66 66 name: 'VerifyPoints',
... ...
yudao-ui-admin/src/components/Verifition/Verify/VerifySlide.vue
... ... @@ -64,7 +64,7 @@
64 64 * */
65 65 import { aesEncrypt } from '@/utils/ase'
66 66 import { resetSize } from './../utils/util'
67   -import { reqGet, reqCheck } from './../api/index'
  67 +import { reqGet, reqCheck } from '@/api/login'
68 68  
69 69 // "captchaType":"blockPuzzle",
70 70 export default {
... ...
yudao-ui-admin/src/components/Verifition/api/index.js deleted
1   -/**
2   - * 此处可直接引用自己项目封装好的 axios 配合后端联调
3   - */
4   -
5   -import request from './../utils/axios' // 组件内部封装的axios
6   -// import request from "@/api/axios.js" //调用项目封装的axios
7   -
8   -// 获取验证图片 以及token
9   -export function reqGet(data) {
10   - return request({
11   - // url: '/captcha/get',
12   - url: '/admin-api/system/captcha/get', // 使用项目自定义的 /admin-api/ 前缀
13   - method: 'post',
14   - data
15   - })
16   -}
17   -
18   -// 滑动或者点选验证
19   -export function reqCheck(data) {
20   - return request({
21   - // url: '/captcha/check',
22   - url: '/admin-api/system/captcha/check', // 使用项目自定义的 /admin-api/ 前缀
23   - method: 'post',
24   - data
25   - })
26   -}
27   -
yudao-ui-admin/src/components/Verifition/utils/axios.js deleted
1   -import axios from 'axios'
2   -
3   -axios.defaults.baseURL = process.env.VUE_APP_BASE_API
4   -
5   -const service = axios.create({
6   - timeout: 40000,
7   - headers: {
8   - 'X-Requested-With': 'XMLHttpRequest',
9   - 'Content-Type': 'application/json; charset=UTF-8'
10   - },
11   -})
12   -service.interceptors.request.use(
13   - config => {
14   - return config
15   - },
16   - error => {
17   - Promise.reject(error)
18   - }
19   -)
20   -
21   -// response interceptor
22   -service.interceptors.response.use(
23   - response => {
24   - return response.data
25   - },
26   - error => {
27   - }
28   -)
29   -export default service
yudao-ui-admin/src/views/mall/trade/order/detail.vue
... ... @@ -244,7 +244,7 @@ export default {
244 244 </script>
245 245  
246 246 <style lang="scss" scoped>
247   - ::v-deep .el-descriptions{
  247 + :deep(.el-descriptions){
248 248 &:not(:nth-child(1)) {
249 249 margin-top: 20px;
250 250 }
... ...
yudao-ui-admin/src/views/mall/trade/order/index.vue
... ... @@ -332,7 +332,7 @@
332 332 </script>
333 333  
334 334 <style lang="scss" scoped>
335   - ::v-deep .order-table{
  335 + :deep(.order-table){
336 336 margin-top: 20px;
337 337 border-bottom: none;
338 338 &::before{
... ...