Commit 0ef05fba7cc4a39354ecbfdf07a061b8227622d2

Authored by xingyu
2 parents e314a63e 8c4bc638

Merge remote-tracking branch 'origin/dev' into feature/springdoc

# Conflicts:
#	yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/captcha/CaptchaController.java
yudao-dependencies/pom.xml
... ... @@ -41,7 +41,7 @@
41 41 <!-- Bpm 工作流相关 -->
42 42 <flowable.version>6.8.0</flowable.version>
43 43 <!-- 工具类相关 -->
44   - <captcha-plus.version>1.0.0</captcha-plus.version>
  44 + <captcha-plus.version>1.0.1</captcha-plus.version>
45 45 <jsoup.version>1.15.3</jsoup.version>
46 46 <lombok.version>1.18.24</lombok.version>
47 47 <mapstruct.version>1.5.3.Final</mapstruct.version>
... ...
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/cn/iocoder/yudao/framework/captcha/config/YudaoCaptchaConfiguration.java
... ... @@ -3,7 +3,7 @@ package cn.iocoder.yudao.framework.captcha.config;
3 3 import cn.hutool.core.util.ClassUtil;
4 4 import cn.iocoder.yudao.framework.captcha.core.enums.CaptchaRedisKeyConstants;
5 5 import cn.iocoder.yudao.framework.captcha.core.service.RedisCaptchaServiceImpl;
6   -import com.anji.captcha.service.CaptchaCacheService;
  6 +import com.xingyuv.captcha.service.CaptchaCacheService;
7 7 import org.springframework.boot.autoconfigure.AutoConfiguration;
8 8 import org.springframework.context.annotation.Bean;
9 9 import org.springframework.data.redis.core.StringRedisTemplate;
... ...
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/cn/iocoder/yudao/framework/captcha/core/enums/CaptchaRedisKeyConstants.java
1 1 package cn.iocoder.yudao.framework.captcha.core.enums;
2 2  
3 3 import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
4   -import com.anji.captcha.model.vo.PointVO;
  4 +import com.xingyuv.captcha.model.vo.PointVO;
5 5  
6 6 import java.time.Duration;
7 7  
... ...
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/cn/iocoder/yudao/framework/captcha/core/service/RedisCaptchaServiceImpl.java
1 1 package cn.iocoder.yudao.framework.captcha.core.service;
2 2  
3   -import com.anji.captcha.service.CaptchaCacheService;
  3 +import com.xingyuv.captcha.service.CaptchaCacheService;
4 4 import lombok.AllArgsConstructor;
5 5 import lombok.NoArgsConstructor;
6 6 import org.springframework.data.redis.core.StringRedisTemplate;
... ...
yudao-framework/yudao-spring-boot-starter-captcha/src/main/resources/META-INF/services/com.anji.captcha.service.CaptchaCacheService renamed to yudao-framework/yudao-spring-boot-starter-captcha/src/main/resources/META-INF/services/com.xingyuv.captcha.service.CaptchaCacheService
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java
... ... @@ -22,9 +22,9 @@ import cn.iocoder.yudao.module.system.service.member.MemberService;
22 22 import cn.iocoder.yudao.module.system.service.oauth2.OAuth2TokenService;
23 23 import cn.iocoder.yudao.module.system.service.social.SocialUserService;
24 24 import cn.iocoder.yudao.module.system.service.user.AdminUserService;
25   -import com.anji.captcha.model.common.ResponseModel;
26   -import com.anji.captcha.model.vo.CaptchaVO;
27   -import com.anji.captcha.service.CaptchaService;
  25 +import com.xingyuv.captcha.model.common.ResponseModel;
  26 +import com.xingyuv.captcha.model.vo.CaptchaVO;
  27 +import com.xingyuv.captcha.service.CaptchaService;
28 28 import com.google.common.annotations.VisibleForTesting;
29 29 import lombok.extern.slf4j.Slf4j;
30 30 import org.springframework.beans.factory.annotation.Value;
... ...
yudao-ui-admin-vue3/package.json
1 1 {
2 2 "name": "yudao-ui-admin-vue3",
3   - "version": "1.6.6-snapshot.1921",
  3 + "version": "1.6.6-snapshot.1922",
4 4 "description": "基于vue3、vite4、element-plus、typesScript",
5 5 "author": "xingyu",
6 6 "private": false,
... ... @@ -66,8 +66,8 @@
66 66 "@types/nprogress": "^0.2.0",
67 67 "@types/qrcode": "^1.5.0",
68 68 "@types/qs": "^6.9.7",
69   - "@typescript-eslint/eslint-plugin": "^5.48.1",
70   - "@typescript-eslint/parser": "^5.48.1",
  69 + "@typescript-eslint/eslint-plugin": "^5.48.2",
  70 + "@typescript-eslint/parser": "^5.48.2",
71 71 "@vitejs/plugin-legacy": "^3.0.1",
72 72 "@vitejs/plugin-vue": "^4.0.0",
73 73 "@vitejs/plugin-vue-jsx": "^3.0.0",
... ... @@ -83,7 +83,7 @@
83 83 "postcss-html": "^1.5.0",
84 84 "postcss-scss": "^4.0.6",
85 85 "prettier": "^2.8.3",
86   - "rimraf": "^4.0.7",
  86 + "rimraf": "^4.1.0",
87 87 "rollup": "^3.10.0",
88 88 "sass": "^1.57.1",
89 89 "stylelint": "^14.16.1",
... ...
yudao-ui-admin-vue3/pnpm-lock.yaml
... ... @@ -13,8 +13,8 @@ specifiers:
13 13 '@types/nprogress': ^0.2.0
14 14 '@types/qrcode': ^1.5.0
15 15 '@types/qs': ^6.9.7
16   - '@typescript-eslint/eslint-plugin': ^5.48.1
17   - '@typescript-eslint/parser': ^5.48.1
  16 + '@typescript-eslint/eslint-plugin': ^5.48.2
  17 + '@typescript-eslint/parser': ^5.48.2
18 18 '@vitejs/plugin-legacy': ^3.0.1
19 19 '@vitejs/plugin-vue': ^4.0.0
20 20 '@vitejs/plugin-vue-jsx': ^3.0.0
... ... @@ -50,7 +50,7 @@ specifiers:
50 50 prettier: ^2.8.3
51 51 qrcode: ^1.5.1
52 52 qs: ^6.11.0
53   - rimraf: ^4.0.7
  53 + rimraf: ^4.1.0
54 54 rollup: ^3.10.0
55 55 sass: ^1.57.1
56 56 stylelint: ^14.16.1
... ... @@ -125,8 +125,8 @@ devDependencies:
125 125 '@types/nprogress': 0.2.0
126 126 '@types/qrcode': 1.5.0
127 127 '@types/qs': 6.9.7
128   - '@typescript-eslint/eslint-plugin': 5.48.1_oomjohfipuyaxs2zyomcx4f5by
129   - '@typescript-eslint/parser': 5.48.1_7uibuqfxkfaozanbtbziikiqje
  128 + '@typescript-eslint/eslint-plugin': 5.48.2_caon6io6stgpr7lz2rtbhekxqy
  129 + '@typescript-eslint/parser': 5.48.2_7uibuqfxkfaozanbtbziikiqje
130 130 '@vitejs/plugin-legacy': 3.0.1_terser@5.16.1+vite@4.0.4
131 131 '@vitejs/plugin-vue': 4.0.0_vite@4.0.4+vue@3.2.45
132 132 '@vitejs/plugin-vue-jsx': 3.0.0_vite@4.0.4+vue@3.2.45
... ... @@ -142,7 +142,7 @@ devDependencies:
142 142 postcss-html: 1.5.0
143 143 postcss-scss: 4.0.6_postcss@8.4.21
144 144 prettier: 2.8.3
145   - rimraf: 4.0.7
  145 + rimraf: 4.1.0
146 146 rollup: 3.10.0
147 147 sass: 1.57.1
148 148 stylelint: 14.16.1
... ... @@ -1279,8 +1279,8 @@ packages:
1279 1279 resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==}
1280 1280 dev: false
1281 1281  
1282   - /@typescript-eslint/eslint-plugin/5.48.1_oomjohfipuyaxs2zyomcx4f5by:
1283   - resolution: {integrity: sha512-9nY5K1Rp2ppmpb9s9S2aBiF3xo5uExCehMDmYmmFqqyxgenbHJ3qbarcLt4ITgaD6r/2ypdlcFRdcuVPnks+fQ==}
  1282 + /@typescript-eslint/eslint-plugin/5.48.2_caon6io6stgpr7lz2rtbhekxqy:
  1283 + resolution: {integrity: sha512-sR0Gja9Ky1teIq4qJOl0nC+Tk64/uYdX+mi+5iB//MH8gwyx8e3SOyhEzeLZEFEEfCaLf8KJq+Bd/6je1t+CAg==}
1284 1284 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
1285 1285 peerDependencies:
1286 1286 '@typescript-eslint/parser': ^5.0.0
... ... @@ -1290,10 +1290,10 @@ packages:
1290 1290 typescript:
1291 1291 optional: true
1292 1292 dependencies:
1293   - '@typescript-eslint/parser': 5.48.1_7uibuqfxkfaozanbtbziikiqje
1294   - '@typescript-eslint/scope-manager': 5.48.1
1295   - '@typescript-eslint/type-utils': 5.48.1_7uibuqfxkfaozanbtbziikiqje
1296   - '@typescript-eslint/utils': 5.48.1_7uibuqfxkfaozanbtbziikiqje
  1293 + '@typescript-eslint/parser': 5.48.2_7uibuqfxkfaozanbtbziikiqje
  1294 + '@typescript-eslint/scope-manager': 5.48.2
  1295 + '@typescript-eslint/type-utils': 5.48.2_7uibuqfxkfaozanbtbziikiqje
  1296 + '@typescript-eslint/utils': 5.48.2_7uibuqfxkfaozanbtbziikiqje
1297 1297 debug: 4.3.4
1298 1298 eslint: 8.32.0
1299 1299 ignore: 5.2.1
... ... @@ -1306,8 +1306,8 @@ packages:
1306 1306 - supports-color
1307 1307 dev: true
1308 1308  
1309   - /@typescript-eslint/parser/5.48.1_7uibuqfxkfaozanbtbziikiqje:
1310   - resolution: {integrity: sha512-4yg+FJR/V1M9Xoq56SF9Iygqm+r5LMXvheo6DQ7/yUWynQ4YfCRnsKuRgqH4EQ5Ya76rVwlEpw4Xu+TgWQUcdA==}
  1309 + /@typescript-eslint/parser/5.48.2_7uibuqfxkfaozanbtbziikiqje:
  1310 + resolution: {integrity: sha512-38zMsKsG2sIuM5Oi/olurGwYJXzmtdsHhn5mI/pQogP+BjYVkK5iRazCQ8RGS0V+YLk282uWElN70zAAUmaYHw==}
1311 1311 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
1312 1312 peerDependencies:
1313 1313 eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
... ... @@ -1316,9 +1316,9 @@ packages:
1316 1316 typescript:
1317 1317 optional: true
1318 1318 dependencies:
1319   - '@typescript-eslint/scope-manager': 5.48.1
1320   - '@typescript-eslint/types': 5.48.1
1321   - '@typescript-eslint/typescript-estree': 5.48.1_typescript@4.9.4
  1319 + '@typescript-eslint/scope-manager': 5.48.2
  1320 + '@typescript-eslint/types': 5.48.2
  1321 + '@typescript-eslint/typescript-estree': 5.48.2_typescript@4.9.4
1322 1322 debug: 4.3.4
1323 1323 eslint: 8.32.0
1324 1324 typescript: 4.9.4
... ... @@ -1326,16 +1326,16 @@ packages:
1326 1326 - supports-color
1327 1327 dev: true
1328 1328  
1329   - /@typescript-eslint/scope-manager/5.48.1:
1330   - resolution: {integrity: sha512-S035ueRrbxRMKvSTv9vJKIWgr86BD8s3RqoRZmsSh/s8HhIs90g6UlK8ZabUSjUZQkhVxt7nmZ63VJ9dcZhtDQ==}
  1329 + /@typescript-eslint/scope-manager/5.48.2:
  1330 + resolution: {integrity: sha512-zEUFfonQid5KRDKoI3O+uP1GnrFd4tIHlvs+sTJXiWuypUWMuDaottkJuR612wQfOkjYbsaskSIURV9xo4f+Fw==}
1331 1331 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
1332 1332 dependencies:
1333   - '@typescript-eslint/types': 5.48.1
1334   - '@typescript-eslint/visitor-keys': 5.48.1
  1333 + '@typescript-eslint/types': 5.48.2
  1334 + '@typescript-eslint/visitor-keys': 5.48.2
1335 1335 dev: true
1336 1336  
1337   - /@typescript-eslint/type-utils/5.48.1_7uibuqfxkfaozanbtbziikiqje:
1338   - resolution: {integrity: sha512-Hyr8HU8Alcuva1ppmqSYtM/Gp0q4JOp1F+/JH5D1IZm/bUBrV0edoewQZiEc1r6I8L4JL21broddxK8HAcZiqQ==}
  1337 + /@typescript-eslint/type-utils/5.48.2_7uibuqfxkfaozanbtbziikiqje:
  1338 + resolution: {integrity: sha512-QVWx7J5sPMRiOMJp5dYshPxABRoZV1xbRirqSk8yuIIsu0nvMTZesKErEA3Oix1k+uvsk8Cs8TGJ6kQ0ndAcew==}
1339 1339 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
1340 1340 peerDependencies:
1341 1341 eslint: '*'
... ... @@ -1344,8 +1344,8 @@ packages:
1344 1344 typescript:
1345 1345 optional: true
1346 1346 dependencies:
1347   - '@typescript-eslint/typescript-estree': 5.48.1_typescript@4.9.4
1348   - '@typescript-eslint/utils': 5.48.1_7uibuqfxkfaozanbtbziikiqje
  1347 + '@typescript-eslint/typescript-estree': 5.48.2_typescript@4.9.4
  1348 + '@typescript-eslint/utils': 5.48.2_7uibuqfxkfaozanbtbziikiqje
1349 1349 debug: 4.3.4
1350 1350 eslint: 8.32.0
1351 1351 tsutils: 3.21.0_typescript@4.9.4
... ... @@ -1354,13 +1354,13 @@ packages:
1354 1354 - supports-color
1355 1355 dev: true
1356 1356  
1357   - /@typescript-eslint/types/5.48.1:
1358   - resolution: {integrity: sha512-xHyDLU6MSuEEdIlzrrAerCGS3T7AA/L8Hggd0RCYBi0w3JMvGYxlLlXHeg50JI9Tfg5MrtsfuNxbS/3zF1/ATg==}
  1357 + /@typescript-eslint/types/5.48.2:
  1358 + resolution: {integrity: sha512-hE7dA77xxu7ByBc6KCzikgfRyBCTst6dZQpwaTy25iMYOnbNljDT4hjhrGEJJ0QoMjrfqrx+j1l1B9/LtKeuqA==}
1359 1359 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
1360 1360 dev: true
1361 1361  
1362   - /@typescript-eslint/typescript-estree/5.48.1_typescript@4.9.4:
1363   - resolution: {integrity: sha512-Hut+Osk5FYr+sgFh8J/FHjqX6HFcDzTlWLrFqGoK5kVUN3VBHF/QzZmAsIXCQ8T/W9nQNBTqalxi1P3LSqWnRA==}
  1362 + /@typescript-eslint/typescript-estree/5.48.2_typescript@4.9.4:
  1363 + resolution: {integrity: sha512-bibvD3z6ilnoVxUBFEgkO0k0aFvUc4Cttt0dAreEr+nrAHhWzkO83PEVVuieK3DqcgL6VAK5dkzK8XUVja5Zcg==}
1364 1364 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
1365 1365 peerDependencies:
1366 1366 typescript: '*'
... ... @@ -1368,8 +1368,8 @@ packages:
1368 1368 typescript:
1369 1369 optional: true
1370 1370 dependencies:
1371   - '@typescript-eslint/types': 5.48.1
1372   - '@typescript-eslint/visitor-keys': 5.48.1
  1371 + '@typescript-eslint/types': 5.48.2
  1372 + '@typescript-eslint/visitor-keys': 5.48.2
1373 1373 debug: 4.3.4
1374 1374 globby: 11.1.0
1375 1375 is-glob: 4.0.3
... ... @@ -1380,17 +1380,17 @@ packages:
1380 1380 - supports-color
1381 1381 dev: true
1382 1382  
1383   - /@typescript-eslint/utils/5.48.1_7uibuqfxkfaozanbtbziikiqje:
1384   - resolution: {integrity: sha512-SmQuSrCGUOdmGMwivW14Z0Lj8dxG1mOFZ7soeJ0TQZEJcs3n5Ndgkg0A4bcMFzBELqLJ6GTHnEU+iIoaD6hFGA==}
  1383 + /@typescript-eslint/utils/5.48.2_7uibuqfxkfaozanbtbziikiqje:
  1384 + resolution: {integrity: sha512-2h18c0d7jgkw6tdKTlNaM7wyopbLRBiit8oAxoP89YnuBOzCZ8g8aBCaCqq7h208qUTroL7Whgzam7UY3HVLow==}
1385 1385 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
1386 1386 peerDependencies:
1387 1387 eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
1388 1388 dependencies:
1389 1389 '@types/json-schema': 7.0.11
1390 1390 '@types/semver': 7.3.13
1391   - '@typescript-eslint/scope-manager': 5.48.1
1392   - '@typescript-eslint/types': 5.48.1
1393   - '@typescript-eslint/typescript-estree': 5.48.1_typescript@4.9.4
  1391 + '@typescript-eslint/scope-manager': 5.48.2
  1392 + '@typescript-eslint/types': 5.48.2
  1393 + '@typescript-eslint/typescript-estree': 5.48.2_typescript@4.9.4
1394 1394 eslint: 8.32.0
1395 1395 eslint-scope: 5.1.1
1396 1396 eslint-utils: 3.0.0_eslint@8.32.0
... ... @@ -1400,11 +1400,11 @@ packages:
1400 1400 - typescript
1401 1401 dev: true
1402 1402  
1403   - /@typescript-eslint/visitor-keys/5.48.1:
1404   - resolution: {integrity: sha512-Ns0XBwmfuX7ZknznfXozgnydyR8F6ev/KEGePP4i74uL3ArsKbEhJ7raeKr1JSa997DBDwol/4a0Y+At82c9dA==}
  1403 + /@typescript-eslint/visitor-keys/5.48.2:
  1404 + resolution: {integrity: sha512-z9njZLSkwmjFWUelGEwEbdf4NwKvfHxvGC0OcGN1Hp/XNDIcJ7D5DpPNPv6x6/mFvc1tQHsaWmpD/a4gOvvCJQ==}
1405 1405 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
1406 1406 dependencies:
1407   - '@typescript-eslint/types': 5.48.1
  1407 + '@typescript-eslint/types': 5.48.2
1408 1408 eslint-visitor-keys: 3.3.0
1409 1409 dev: true
1410 1410  
... ... @@ -5192,8 +5192,8 @@ packages:
5192 5192 glob: 7.2.3
5193 5193 dev: true
5194 5194  
5195   - /rimraf/4.0.7:
5196   - resolution: {integrity: sha512-CUEDDrZvc0swDgVdXGiv3FcYYQMpJxjvSGt85Amj6yU+MCVWurrLCeLiJDdJPHCzNJnwuebBEdcO//eP11Xa7w==}
  5195 + /rimraf/4.1.0:
  5196 + resolution: {integrity: sha512-ZJdkUR5/dRrRJHdcSKJLrpRn6tVjl9ALxd4yrTCxFsMpjQNzwHF6GLqMsuEzEYIXxHlFPDSk21Vr8VPuFBEz0g==}
5197 5197 engines: {node: '>=14'}
5198 5198 hasBin: true
5199 5199 dev: true
... ...
yudao-ui-admin-vue3/src/components/DictTag/src/DictTag.vue
1   -<script setup lang="ts">
2   -import { onMounted, onUpdated, PropType, ref } from 'vue'
3   -import { getDictOptions, DictDataType } from '@/utils/dict'
  1 +<script lang="tsx">
  2 +import { defineComponent, PropType, ref } from 'vue'
  3 +import { isHexColor } from '@/utils/color'
4 4 import { ElTag } from 'element-plus'
5   -const props = defineProps({
6   - type: {
7   - type: String as PropType<string>,
8   - required: true
  5 +import { DictDataType, getDictOptions } from '@/utils/dict'
  6 +
  7 +export default defineComponent({
  8 + name: 'DictTag',
  9 + props: {
  10 + type: {
  11 + type: String as PropType<string>,
  12 + required: true
  13 + },
  14 + value: {
  15 + type: [String, Number, Boolean] as PropType<string | number | boolean>,
  16 + required: true
  17 + }
9 18 },
10   - value: {
11   - type: [String, Number, Boolean] as PropType<string | number | boolean>,
12   - required: true
13   - }
14   -})
15   -const dictData = ref<DictDataType>()
16   -const getDictObj = (dictType: string, value: string) => {
17   - const dictOptions = getDictOptions(dictType)
18   - dictOptions.forEach((dict: DictDataType) => {
19   - if (dict.value === value) {
20   - if (dict.colorType + '' === 'primary' || dict.colorType + '' === 'default') {
21   - dict.colorType = ''
  19 + setup(props) {
  20 + const dictData = ref<DictDataType>()
  21 + const getDictObj = (dictType: string, value: string) => {
  22 + const dictOptions = getDictOptions(dictType)
  23 + dictOptions.forEach((dict: DictDataType) => {
  24 + if (dict.value === value) {
  25 + if (dict.colorType + '' === 'primary' || dict.colorType + '' === 'default') {
  26 + dict.colorType = ''
  27 + }
  28 + dictData.value = dict
  29 + }
  30 + })
  31 + }
  32 + const rederDictTag = () => {
  33 + if (!props.type) {
  34 + return null
22 35 }
23   - dictData.value = dict
  36 + getDictObj(props.type, props.value.toString())
  37 + return (
  38 + <ElTag
  39 + type={dictData.value?.colorType}
  40 + color={
  41 + dictData.value?.cssClass && isHexColor(dictData.value?.cssClass)
  42 + ? dictData.value?.cssClass
  43 + : ''
  44 + }
  45 + >
  46 + {dictData.value?.label}
  47 + </ElTag>
  48 + )
24 49 }
25   - })
26   -}
27   -
28   -onMounted(() => {
29   - return getDictObj(props.type, props.value?.toString())
30   -})
31   -
32   -onUpdated(() => {
33   - getDictObj(props.type, props.value?.toString())
  50 + return () => rederDictTag()
  51 + }
34 52 })
35 53 </script>
36   -<template>
37   - <ElTag
38   - :disable-transitions="true"
39   - :key="dictData?.value + ''"
40   - :type="dictData?.colorType"
41   - :color="dictData?.cssClass"
42   - >
43   - {{ dictData?.label }}
44   - </ElTag>
45   -</template>
... ...
yudao-ui-admin-vue3/src/components/XTable/src/XTable.vue
... ... @@ -205,7 +205,7 @@ const getPageConfig = (options: XTableProps) =&gt; {
205 205 if (isBoolean(pagination)) {
206 206 options.pagerConfig = {
207 207 border: false, // 带边框
208   - background: true, // 带背景颜色
  208 + background: false, // 带背景颜色
209 209 perfect: false, // 配套的样式
210 210 pageSize: 10, // 每页大小
211 211 pagerCount: 7, // 显示页码按钮的数量
... ... @@ -229,19 +229,19 @@ const getPageConfig = (options: XTableProps) =&gt; {
229 229 if (pagination != false) {
230 230 options.pagerConfig = {
231 231 border: false, // 带边框
232   - background: true, // 带背景颜色
  232 + background: false, // 带背景颜色
233 233 perfect: false, // 配套的样式
234 234 pageSize: 10, // 每页大小
235 235 pagerCount: 7, // 显示页码按钮的数量
236 236 autoHidden: false, // 当只有一页时自动隐藏
237 237 pageSizes: [5, 10, 20, 30, 50, 100], // 每页大小选项列表
238 238 layouts: [
  239 + 'Sizes',
239 240 'PrevJump',
240 241 'PrevPage',
241   - 'JumpNumber',
  242 + 'Number',
242 243 'NextPage',
243 244 'NextJump',
244   - 'Sizes',
245 245 'FullJump',
246 246 'Total'
247 247 ]
... ... @@ -276,7 +276,7 @@ const reload = () =&gt; {
276 276 }
277 277  
278 278 // 删除
279   -const deleteData = async (ids: string | number) => {
  279 +const deleteData = async (id: string | number) => {
280 280 const g = unref(xGrid)
281 281 if (!g) {
282 282 return
... ... @@ -288,7 +288,7 @@ const deleteData = async (ids: string | number) =&gt; {
288 288 }
289 289 return new Promise(async () => {
290 290 message.delConfirm().then(async () => {
291   - await (options?.deleteApi && options?.deleteApi(ids))
  291 + await (options?.deleteApi && options?.deleteApi(id))
292 292 message.success(t('common.delSuccess'))
293 293 // 刷新列表
294 294 reload()
... ... @@ -296,6 +296,49 @@ const deleteData = async (ids: string | number) =&gt; {
296 296 })
297 297 }
298 298  
  299 +// 批量删除
  300 +const deleteBatch = async () => {
  301 + const g = unref(xGrid)
  302 + if (!g) {
  303 + return
  304 + }
  305 + const rows = g.getCheckboxRecords() || g.getRadioRecord()
  306 + let ids: any[] = []
  307 + if (rows.length == 0) {
  308 + message.error('请选择数据')
  309 + return
  310 + } else {
  311 + rows.forEach((row) => {
  312 + ids.push(row.id)
  313 + })
  314 + }
  315 + const options = innerProps.value || props.options
  316 + if (options.deleteListApi) {
  317 + return new Promise(async () => {
  318 + message.delConfirm().then(async () => {
  319 + await (options?.deleteListApi && options?.deleteListApi(ids))
  320 + message.success(t('common.delSuccess'))
  321 + // 刷新列表
  322 + reload()
  323 + })
  324 + })
  325 + } else if (options.deleteApi) {
  326 + return new Promise(async () => {
  327 + message.delConfirm().then(async () => {
  328 + ids.forEach(async (id) => {
  329 + await (options?.deleteApi && options?.deleteApi(id))
  330 + })
  331 + message.success(t('common.delSuccess'))
  332 + // 刷新列表
  333 + reload()
  334 + })
  335 + })
  336 + } else {
  337 + console.error('未传入delListApi')
  338 + return
  339 + }
  340 +}
  341 +
299 342 // 导出
300 343 const exportList = async (fileName?: string) => {
301 344 const g = unref(xGrid)
... ... @@ -324,12 +367,48 @@ const getSearchData = () =&gt; {
324 367 return queryParams
325 368 }
326 369  
  370 +// 获取当前列
  371 +const getCurrentColumn = () => {
  372 + const g = unref(xGrid)
  373 + if (!g) {
  374 + return
  375 + }
  376 + return g.getCurrentColumn()
  377 +}
  378 +
  379 +// 获取当前选中列,redio
  380 +const getRadioRecord = () => {
  381 + const g = unref(xGrid)
  382 + if (!g) {
  383 + return
  384 + }
  385 + return g.getRadioRecord(false)
  386 +}
  387 +
  388 +// 获取当前选中列,checkbox
  389 +const getCheckboxRecords = () => {
  390 + const g = unref(xGrid)
  391 + if (!g) {
  392 + return
  393 + }
  394 + return g.getCheckboxRecords(false)
  395 +}
327 396 const setProps = (prop: Partial<XTableProps>) => {
328 397 innerProps.value = { ...unref(innerProps), ...prop }
329 398 }
330 399  
331 400 defineExpose({ reload, Ref: xGrid, getSearchData, deleteData, exportList })
332   -emit('register', { reload, getSearchData, setProps, deleteData, exportList })
  401 +emit('register', {
  402 + reload,
  403 + getSearchData,
  404 + setProps,
  405 + deleteData,
  406 + deleteBatch,
  407 + exportList,
  408 + getCurrentColumn,
  409 + getRadioRecord,
  410 + getCheckboxRecords
  411 +})
333 412 </script>
334 413 <style lang="scss">
335 414 @import './style/index.scss';
... ...
yudao-ui-admin-vue3/src/components/XTable/src/type.ts
... ... @@ -10,6 +10,7 @@ export type XTableProps&lt;D = any&gt; = VxeGridProps&lt;D&gt; &amp; {
10 10 getListApi?: Function // 获取列表接口
11 11 getAllListApi?: Function // 获取全部数据接口 用于 vxe 导出
12 12 deleteApi?: Function // 删除接口
  13 + deleteListApi?: Function // 批量删除接口
13 14 exportListApi?: Function // 导出接口
14 15 exportName?: string // 导出文件夹名称
15 16 params?: any // 其他查询参数
... ...
yudao-ui-admin-vue3/src/hooks/web/useVxeCrudSchemas.ts
... ... @@ -18,6 +18,7 @@ export type VxeCrudSchema = {
18 18 primaryKey?: string // 主键ID
19 19 primaryTitle?: string // 主键标题 默认为序号
20 20 primaryType?: VxeColumnPropTypes.Type | 'id' // 还支持 "id" | "seq" | "radio" | "checkbox" | "expand" | "html" | null
  21 + firstColumn?: VxeColumnPropTypes.Type // 第一列显示类型
21 22 action?: boolean // 是否开启表格内右侧操作栏插槽
22 23 actionTitle?: string // 操作栏标题 默认为操作
23 24 actionWidth?: string // 操作栏插槽宽度,一般2个字带图标 text 类型按钮 50-70
... ... @@ -184,6 +185,14 @@ const filterSearchSchema = (crudSchema: VxeCrudSchema): VxeFormItemProps[] =&gt; {
184 185 const filterTableSchema = (crudSchema: VxeCrudSchema): VxeGridPropTypes.Columns => {
185 186 const { t } = useI18n()
186 187 const tableSchema: VxeGridPropTypes.Columns = []
  188 + // 第一列
  189 + if (crudSchema.firstColumn) {
  190 + const tableSchemaItem = {
  191 + type: crudSchema.firstColumn,
  192 + width: '50px'
  193 + }
  194 + tableSchema.push(tableSchemaItem)
  195 + }
187 196 // 主键ID
188 197 if (crudSchema.primaryKey && crudSchema.primaryType) {
189 198 const primaryTitle = crudSchema.primaryTitle ? crudSchema.primaryTitle : t('common.index')
... ...
yudao-ui-admin-vue3/src/hooks/web/useXTable.ts
... ... @@ -2,10 +2,14 @@ import { ref, unref } from &#39;vue&#39;
2 2 import { XTableProps } from '@/components/XTable/src/type'
3 3  
4 4 export interface tableMethod {
5   - reload: () => void
  5 + reload: () => void // 刷新表格
6 6 setProps: (props: XTableProps) => void
7   - deleteData: (ids: string | number) => void
8   - exportList: (fileName?: string) => void
  7 + deleteData: (id: string | number) => void // 删除数据
  8 + deleteBatch: () => void // 批量删除
  9 + exportList: (fileName?: string) => void // 导出列表
  10 + getCurrentColumn: () => void // 获取当前列
  11 + getRadioRecord: () => void // 获取当前选中列,redio
  12 + getCheckboxRecords: () => void //获取当前选中列, checkbox
9 13 }
10 14  
11 15 export const useXTable = (props: XTableProps): [Function, tableMethod] => {
... ... @@ -25,8 +29,12 @@ export const useXTable = (props: XTableProps): [Function, tableMethod] =&gt; {
25 29 const methods: tableMethod = {
26 30 reload: () => getInstance().reload(),
27 31 setProps: (props) => getInstance().setProps(props),
28   - deleteData: (ids: string | number) => getInstance().deleteData(ids),
29   - exportList: (fileName?: string) => getInstance().exportList(fileName)
  32 + deleteData: (id: string | number) => getInstance().deleteData(id),
  33 + deleteBatch: () => getInstance().deleteBatch(),
  34 + exportList: (fileName?: string) => getInstance().exportList(fileName),
  35 + getCurrentColumn: () => getInstance().getCheckboxRecords(),
  36 + getRadioRecord: () => getInstance().getRadioRecord(),
  37 + getCheckboxRecords: () => getInstance().getCheckboxRecords()
30 38 }
31 39 return [register, methods]
32 40 }
... ...
yudao-ui-admin-vue3/src/plugins/vxeTable/index.ts
... ... @@ -76,26 +76,26 @@ VXETable.setup({
76 76 },
77 77 pagerConfig: {
78 78 border: false,
79   - background: true,
  79 + background: false,
80 80 autoHidden: true,
81 81 perfect: true,
82 82 pageSize: 10,
83 83 pagerCount: 7,
84 84 pageSizes: [5, 10, 15, 20, 50, 100, 200, 500],
85 85 layouts: [
  86 + 'Sizes',
86 87 'PrevJump',
87 88 'PrevPage',
88   - 'Jump',
89   - 'PageCount',
  89 + 'Number',
90 90 'NextPage',
91 91 'NextJump',
92   - 'Sizes',
  92 + 'FullJump',
93 93 'Total'
94 94 ]
95 95 }
96 96 },
97 97 pager: {
98   - background: true,
  98 + background: false,
99 99 autoHidden: false,
100 100 perfect: true,
101 101 pageSize: 10,
... ...
yudao-ui-admin-vue3/src/store/modules/dict.ts
... ... @@ -66,6 +66,12 @@ export const useDictStore = defineStore(&#39;dict&#39;, {
66 66 wsCache.set(CACHE_KEY.DICT_CACHE, dictDataMap, { exp: 60 }) // 60 秒 过期
67 67 }
68 68 },
  69 + getDictByType(type: string) {
  70 + if (!this.isSetDict) {
  71 + this.setDictMap()
  72 + }
  73 + return this.dictMap[type]
  74 + },
69 75 async resetDict() {
70 76 wsCache.delete(CACHE_KEY.DICT_CACHE)
71 77 const res = await listSimpleDictDataApi()
... ...
yudao-ui-admin-vue3/src/utils/dict.ts
... ... @@ -21,7 +21,7 @@ export interface DictDataType {
21 21 }
22 22  
23 23 export const getDictOptions = (dictType: string) => {
24   - return dictStore.getDictMap[dictType]
  24 + return dictStore.getDictByType(dictType)
25 25 }
26 26  
27 27 export const getIntDictOptions = (dictType: string) => {
... ...
yudao-ui-admin-vue3/src/views/system/post/index.vue
... ... @@ -9,7 +9,7 @@
9 9 preIcon="ep:zoom-in"
10 10 :title="t('action.add')"
11 11 v-hasPermi="['system:post:create']"
12   - @click="handleCreate()"
  12 + @click="openModel('create')"
13 13 />
14 14 <!-- 操作:导出 -->
15 15 <XButton
... ... @@ -24,21 +24,18 @@
24 24 <!-- 操作:修改 -->
25 25 <XTextButton
26 26 preIcon="ep:edit"
27   - :title="t('action.edit')"
28 27 v-hasPermi="['system:post:update']"
29   - @click="handleUpdate(row.id)"
  28 + @click="openModel('update', row.id)"
30 29 />
31 30 <!-- 操作:详情 -->
32 31 <XTextButton
33 32 preIcon="ep:view"
34   - :title="t('action.detail')"
35 33 v-hasPermi="['system:post:query']"
36   - @click="handleDetail(row.id)"
  34 + @click="openModel('detail', row.id)"
37 35 />
38 36 <!-- 操作:删除 -->
39 37 <XTextButton
40 38 preIcon="ep:delete"
41   - :title="t('action.del')"
42 39 v-hasPermi="['system:post:delete']"
43 40 @click="deleteData(row.id)"
44 41 />
... ... @@ -103,34 +100,20 @@ const actionLoading = ref(false) // 按钮 Loading
103 100 const formRef = ref<FormExpose>() // 表单 Ref
104 101 const detailData = ref() // 详情 Ref
105 102  
106   -// 设置标题
107   -const setDialogTile = (type: string) => {
  103 +const openModel = async (type: string, rowId?: number) => {
108 104 modelLoading.value = true
109 105 modelTitle.value = t('action.' + type)
110 106 actionType.value = type
111 107 modelVisible.value = true
112   -}
113   -
114   -// 新增操作
115   -const handleCreate = () => {
116   - setDialogTile('create')
117   - modelLoading.value = false
118   -}
119   -
120   -// 修改操作
121   -const handleUpdate = async (rowId: number) => {
122   - setDialogTile('update')
123 108 // 设置数据
124   - const res = await PostApi.getPostApi(rowId)
125   - unref(formRef)?.setValues(res)
126   - modelLoading.value = false
127   -}
128   -
129   -// 详情操作
130   -const handleDetail = async (rowId: number) => {
131   - setDialogTile('detail')
132   - const res = await PostApi.getPostApi(rowId)
133   - detailData.value = res
  109 + if (rowId) {
  110 + const res = await PostApi.getPostApi(rowId)
  111 + if (type === 'update') {
  112 + unref(formRef)?.setValues(res)
  113 + } else if (type === 'detail') {
  114 + detailData.value = res
  115 + }
  116 + }
134 117 modelLoading.value = false
135 118 }
136 119  
... ... @@ -155,7 +138,7 @@ const submitForm = async () =&gt; {
155 138 } finally {
156 139 actionLoading.value = false
157 140 // 刷新列表
158   - await reload()
  141 + reload()
159 142 }
160 143 }
161 144 })
... ...