mirror of
https://gitee.com/dromara/RuoYi-Cloud-Plus.git
synced 2025-12-25 23:26:20 +08:00
Compare commits
738 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
778ee424e6 | ||
|
|
3b82076b62 | ||
|
|
43e522e35c | ||
|
|
b4e1bf2592 | ||
|
|
577bb456a4 | ||
|
|
df130b0455 | ||
|
|
d145e3e432 | ||
|
|
8923333d3f | ||
|
|
b1a7de3bb1 | ||
|
|
a87450ec2c | ||
|
|
672444d9d9 | ||
|
|
c6b4014eab | ||
|
|
1be37bae6b | ||
|
|
93f9249410 | ||
|
|
3ca290b7d7 | ||
|
|
6f3bc78ebc | ||
|
|
bc86e7e1f0 | ||
|
|
ec7d850445 | ||
|
|
c09fa60433 | ||
|
|
972b1248af | ||
|
|
7185bb64e4 | ||
|
|
16e683283e | ||
|
|
5a62c58fe3 | ||
|
|
a24870cc05 | ||
|
|
d68e9e27de | ||
|
|
e8f4828528 | ||
|
|
2add71a01c | ||
|
|
7f009f4b09 | ||
|
|
2787571820 | ||
|
|
7361519474 | ||
|
|
30195a02f7 | ||
|
|
f9e8b751d6 | ||
|
|
fdbffa2b61 | ||
|
|
2c58beca79 | ||
|
|
f72182e589 | ||
|
|
bab2b19604 | ||
|
|
79a8e473ce | ||
|
|
9061bdd4cc | ||
|
|
ad10e576bd | ||
|
|
ee735ed10a | ||
|
|
513d6cece3 | ||
|
|
c315c41270 | ||
|
|
9db0e10f3d | ||
|
|
927658cc40 | ||
|
|
63db3e5468 | ||
|
|
9d7f870ef0 | ||
|
|
b08d2d11db | ||
|
|
d6849ae328 | ||
|
|
85f4478d2f | ||
|
|
23672c120a | ||
|
|
3be17bc145 | ||
|
|
d9e5f86efa | ||
|
|
4bd3467595 | ||
|
|
8cf324b936 | ||
|
|
0e4a01bdf4 | ||
|
|
2ef0ca8d58 | ||
|
|
49a0d38373 | ||
|
|
df372fb659 | ||
|
|
604856f7c2 | ||
|
|
ddfa8a2601 | ||
|
|
36cc2ea1e2 | ||
|
|
2043c1c158 | ||
|
|
478d6ebe33 | ||
|
|
829c19e806 | ||
|
|
c62425e2ea | ||
|
|
f5bf38f16f | ||
|
|
f58137c60c | ||
|
|
4a870fa135 | ||
|
|
0ef3439750 | ||
|
|
e840387fab | ||
|
|
0ddb6dee67 | ||
|
|
2e3fe5804e | ||
|
|
65dad95e3b | ||
|
|
965fe349f6 | ||
|
|
411c551f90 | ||
|
|
f0931258a1 | ||
|
|
3df354dbd4 | ||
|
|
7e54246af2 | ||
|
|
d568797ba4 | ||
|
|
00a1eeb088 | ||
|
|
6bfa87a7e6 | ||
|
|
299b56af4f | ||
|
|
5e2692bc43 | ||
|
|
a4ac09efd9 | ||
|
|
17bca63e37 | ||
|
|
37fe228d5e | ||
|
|
7a36e85b8c | ||
|
|
15d938448b | ||
|
|
b4e645ef66 | ||
|
|
422760dde7 | ||
|
|
a7207e11f7 | ||
|
|
81255a921e | ||
|
|
4be304217e | ||
|
|
743467c021 | ||
|
|
0055e01dc1 | ||
|
|
362894a7ec | ||
|
|
5927171aea | ||
|
|
ae6c0a7e64 | ||
|
|
9533adea09 | ||
|
|
bccbed47eb | ||
|
|
63f1deddc3 | ||
|
|
c87601ce39 | ||
|
|
4c71784c0e | ||
|
|
905cf33897 | ||
|
|
5ecb06f2d9 | ||
|
|
a5a86a5c15 | ||
|
|
49b1d65af7 | ||
|
|
50bcac1c73 | ||
|
|
057e3540a9 | ||
|
|
26961919e1 | ||
|
|
789273d0d9 | ||
|
|
35e38d5766 | ||
|
|
0fff64da20 | ||
|
|
0082a60970 | ||
|
|
92c13c23c9 | ||
|
|
cb83f9d9de | ||
|
|
cce5f53b7a | ||
|
|
8512b66746 | ||
|
|
43efa94af9 | ||
|
|
7fe1d90641 | ||
|
|
3b2854adb8 | ||
|
|
0d994c97b9 | ||
|
|
61a4b96831 | ||
|
|
52daba0b36 | ||
|
|
c2c778c0c3 | ||
|
|
8c315c0c4d | ||
|
|
9439ec88ab | ||
|
|
1dc9bfe304 | ||
|
|
0122a09c27 | ||
|
|
6551134460 | ||
|
|
f6ddae57c4 | ||
|
|
7316d05874 | ||
|
|
0766ef65c7 | ||
|
|
66dea77421 | ||
|
|
6dcb3153c2 | ||
|
|
de6fffc6fe | ||
|
|
328f5dcdac | ||
|
|
4266517ead | ||
|
|
2db80ae6da | ||
|
|
971f0070f7 | ||
|
|
7c341548c4 | ||
|
|
85160be7f7 | ||
|
|
d41e373f8b | ||
|
|
fc6d45d8c9 | ||
|
|
bf0130dea6 | ||
|
|
fbe9cf506b | ||
|
|
3151741d87 | ||
|
|
1ebb552d7f | ||
|
|
426a6c484e | ||
|
|
0c5173c388 | ||
|
|
4ae432713b | ||
|
|
d425383d38 | ||
|
|
c710b6365e | ||
|
|
415fb76139 | ||
|
|
ee68904d59 | ||
|
|
50fd75bfdd | ||
|
|
29af0a1423 | ||
|
|
b3e7bef603 | ||
|
|
943d8b0f6f | ||
|
|
0ed79627b6 | ||
|
|
643fead8f4 | ||
|
|
e67399c2c7 | ||
|
|
e878adb6e8 | ||
|
|
d1d5336762 | ||
|
|
1b07733a12 | ||
|
|
89549569d5 | ||
|
|
f0056b0ce1 | ||
|
|
c593ed5839 | ||
|
|
4b51157bc3 | ||
|
|
d32ba1f92f | ||
|
|
0daa00e24b | ||
|
|
14091133c4 | ||
|
|
3cc8b1767e | ||
|
|
f6500b46f2 | ||
|
|
8352f25fd9 | ||
|
|
543be7a809 | ||
|
|
e015970f79 | ||
|
|
b41ed6fd92 | ||
|
|
c8408ae750 | ||
|
|
0f8ae82257 | ||
|
|
a0519521a5 | ||
|
|
986082eef3 | ||
|
|
633252f730 | ||
|
|
716ea1deff | ||
|
|
0eeb2a144b | ||
|
|
a8de8886ec | ||
|
|
78c6580e28 | ||
|
|
087f5d5058 | ||
|
|
9dc682ff03 | ||
|
|
4a637756bb | ||
|
|
3f1e97da2b | ||
|
|
2bb9ec9899 | ||
|
|
5c6ff3fe54 | ||
|
|
64b7bd5b6c | ||
|
|
4557bc30b6 | ||
|
|
c73d3cdf89 | ||
|
|
ba780cb444 | ||
|
|
a2392acad6 | ||
|
|
44a5eb2ec9 | ||
|
|
0f0fb92ff6 | ||
|
|
36298c79f0 | ||
|
|
f8152410e3 | ||
|
|
d5e4a069d4 | ||
|
|
d68ff10e6f | ||
|
|
3cb0567b3b | ||
|
|
35937624b2 | ||
|
|
1bc23099aa | ||
|
|
36e18aa71e | ||
|
|
30653c6d0f | ||
|
|
f5729d040d | ||
|
|
7ab62a89be | ||
|
|
e3b449e91e | ||
|
|
4f42258f99 | ||
|
|
e0f68ef605 | ||
|
|
2c93bdc5dd | ||
|
|
5f3597bffb | ||
|
|
3b06e02394 | ||
|
|
946fb57116 | ||
|
|
9599f41f7e | ||
|
|
d07b047dcc | ||
|
|
967cc6e4f7 | ||
|
|
bb51b61072 | ||
|
|
7373a58dfb | ||
|
|
a899fefc13 | ||
|
|
792a4b7e37 | ||
|
|
ccacb64c47 | ||
|
|
304fa68276 | ||
|
|
33bd7c11a1 | ||
|
|
df8fa77e63 | ||
|
|
5d2156cb5e | ||
|
|
4244567d2e | ||
|
|
29a78eba27 | ||
|
|
b54bece04d | ||
|
|
38feed5469 | ||
|
|
066d48f7b3 | ||
|
|
999203665a | ||
|
|
28daad748d | ||
|
|
1a6460bcc3 | ||
|
|
d48bbab086 | ||
|
|
beb7c55757 | ||
|
|
7141e855bb | ||
|
|
b77152357f | ||
|
|
a4d21e06c0 | ||
|
|
77a245c13b | ||
|
|
edac6074fb | ||
|
|
2656fcc956 | ||
|
|
7488b091bc | ||
|
|
483107955e | ||
|
|
8dc266055c | ||
|
|
09c484f496 | ||
|
|
348e8eb5fe | ||
|
|
753b456b4e | ||
|
|
f852949c22 | ||
|
|
e668e524b2 | ||
|
|
8a2e970c54 | ||
|
|
39079e53aa | ||
|
|
c690a30221 | ||
|
|
e93a2662a7 | ||
|
|
54f04c3cdf | ||
|
|
0b8b47d857 | ||
|
|
c846fad872 | ||
|
|
df7f282e41 | ||
|
|
06b145cb83 | ||
|
|
8ed00aed21 | ||
|
|
c519815fd4 | ||
|
|
cd3a831213 | ||
|
|
3b58e0952a | ||
|
|
61ea1b3354 | ||
|
|
c39a816689 | ||
|
|
4ad0969f0a | ||
|
|
c64410d0ae | ||
|
|
d37a00497d | ||
|
|
1ab8750cd5 | ||
|
|
77dcf4b0d4 | ||
|
|
af04bc74ed | ||
|
|
ee7450c0e8 | ||
|
|
6e7ecc96cb | ||
|
|
72001f721e | ||
|
|
d830a7d5cf | ||
|
|
f50d7e85c0 | ||
|
|
0aabd18e1c | ||
|
|
249d7bdcde | ||
|
|
1c126dc5d3 | ||
|
|
84f0bc1832 | ||
|
|
d2f43e7f95 | ||
|
|
4263ccef62 | ||
|
|
cf64f2139f | ||
|
|
17c94cdc1a | ||
|
|
679c83e837 | ||
|
|
a9f10e4fa4 | ||
|
|
a6ab750508 | ||
|
|
1efe1ac78a | ||
|
|
cb545862f4 | ||
|
|
d26147fb61 | ||
|
|
f26ef3515a | ||
|
|
ef013bd653 | ||
|
|
751e86298f | ||
|
|
6738d68fa4 | ||
|
|
d97146de98 | ||
|
|
ca7c0c94f3 | ||
|
|
6d319b13ad | ||
|
|
1321a1ec38 | ||
|
|
6d7fb33ae0 | ||
|
|
faa9be7e4e | ||
|
|
36ab89d582 | ||
|
|
66bda00007 | ||
|
|
f0ec0811fd | ||
|
|
a28f05c145 | ||
|
|
6d7e8e3822 | ||
|
|
3f0d0ad82b | ||
|
|
b7835ec5bd | ||
|
|
cb4e9a2006 | ||
|
|
6fb975fe6b | ||
|
|
1842103a18 | ||
|
|
66e1767979 | ||
|
|
b87d59aec3 | ||
|
|
7cfd8b4d46 | ||
|
|
16a366b23c | ||
|
|
81abbb204f | ||
|
|
4b19b384d3 | ||
|
|
a37597ee7d | ||
|
|
44342e32cb | ||
|
|
67be46bbb1 | ||
|
|
3bb020c8a9 | ||
|
|
9c9710fa4d | ||
|
|
bdc5791a21 | ||
|
|
acb254c867 | ||
|
|
47a45ab1fc | ||
|
|
be0b27a8bc | ||
|
|
92afe12288 | ||
|
|
90b508eaf3 | ||
|
|
f34a92c6a4 | ||
|
|
7ecb5f3826 | ||
|
|
f15e8f1ffa | ||
|
|
01bf26d39f | ||
|
|
bc99124cbd | ||
|
|
85567dde0c | ||
|
|
fd285c9c38 | ||
|
|
dd77741f75 | ||
|
|
47ed39879d | ||
|
|
3727d04744 | ||
|
|
281d0d336a | ||
|
|
88bec4aaea | ||
|
|
1917d7234d | ||
|
|
845a0e57de | ||
|
|
48fb1d92f3 | ||
|
|
09c03bfc76 | ||
|
|
488a5631f4 | ||
|
|
5217bd6a1f | ||
|
|
edd372f4e4 | ||
|
|
bb11ea218d | ||
|
|
92908f435f | ||
|
|
baa93b5337 | ||
|
|
21d00dfcc9 | ||
|
|
287d5cd5dc | ||
|
|
f77994ba6c | ||
|
|
6c10bc8860 | ||
|
|
01b137a08e | ||
|
|
0364cae19a | ||
|
|
e83e0548d0 | ||
|
|
ec7aa9035a | ||
|
|
1edc373b2b | ||
|
|
2a413d13df | ||
|
|
74df9e2bc0 | ||
|
|
c65f3e2f2c | ||
|
|
8b17bd5d5d | ||
|
|
21521e4d80 | ||
|
|
bf6f18d7b8 | ||
|
|
55e97d7edb | ||
|
|
3b5559e562 | ||
|
|
9f936349e1 | ||
|
|
520ac26b88 | ||
|
|
dc0b36ac38 | ||
|
|
ca85b8c223 | ||
|
|
e2063ca3c7 | ||
|
|
d7c3a7fd67 | ||
|
|
81817ef631 | ||
|
|
0e79b6a744 | ||
|
|
ccd25a5d46 | ||
|
|
2674a0cda2 | ||
|
|
2cc792fe32 | ||
|
|
c3aa5c3aed | ||
|
|
fcf71dee33 | ||
|
|
ea429e79a9 | ||
|
|
72bc3b6227 | ||
|
|
baf0d3ed50 | ||
|
|
b8d634a933 | ||
|
|
38fca0c0e5 | ||
|
|
98d3f66470 | ||
|
|
99210f3511 | ||
|
|
b7562259a9 | ||
|
|
6628ead2ea | ||
|
|
5f91db4cbe | ||
|
|
52295bdc20 | ||
|
|
acb701ad59 | ||
|
|
ad30965ef1 | ||
|
|
dbc72dea3c | ||
|
|
a8da093a89 | ||
|
|
d879f1c763 | ||
|
|
9e1fb0e482 | ||
|
|
e7f553fe91 | ||
|
|
fcfa6dc976 | ||
|
|
465a9a25e9 | ||
|
|
1a5e01cd96 | ||
|
|
b849b00398 | ||
|
|
ac0dbde532 | ||
|
|
1102573da3 | ||
|
|
43f24051fe | ||
|
|
0264b5f7e9 | ||
|
|
6012dbdfa8 | ||
|
|
7c056c5090 | ||
|
|
eec5940703 | ||
|
|
09fb5bb2da | ||
|
|
33e7faa1d1 | ||
|
|
39e6ac9ed4 | ||
|
|
c6b5bb0652 | ||
|
|
32f59ba2ee | ||
|
|
3b28b04775 | ||
|
|
850dd7164b | ||
|
|
00356eaa05 | ||
|
|
35b8c6d8e3 | ||
|
|
d45ba32876 | ||
|
|
6d15b20942 | ||
|
|
0d3d558ebe | ||
|
|
13fc51849d | ||
|
|
9cadcffd7f | ||
|
|
e7b05184a7 | ||
|
|
3f7673f16b | ||
|
|
0b020f5f99 | ||
|
|
d808ab48cf | ||
|
|
058a5a107f | ||
|
|
7b47d01ce7 | ||
|
|
7d2bc6f031 | ||
|
|
b7fbff5c95 | ||
|
|
fd867eeebb | ||
|
|
743bd22d79 | ||
|
|
822f1837e8 | ||
|
|
87aef971b8 | ||
|
|
c5e2ed541a | ||
|
|
817a31ab31 | ||
|
|
bf1c5d6611 | ||
|
|
b45646f48b | ||
|
|
4badc08432 | ||
|
|
6dc7519bdb | ||
|
|
d2fb7da4aa | ||
|
|
1766247d2f | ||
|
|
c611dff7f2 | ||
|
|
2b623c005a | ||
|
|
f80b29536b | ||
|
|
820c56cfed | ||
|
|
430ae3a2a4 | ||
|
|
2fd1e36239 | ||
|
|
c197606cb5 | ||
|
|
c6e72e16dd | ||
|
|
298874b388 | ||
|
|
b7633e5d83 | ||
|
|
84a1540c19 | ||
|
|
9981d6ad58 | ||
|
|
df5433be75 | ||
|
|
5a17fb4a68 | ||
|
|
04bcc0890c | ||
|
|
3e4727db17 | ||
|
|
ed7d11b740 | ||
|
|
aa7c79885a | ||
|
|
2b3897c302 | ||
|
|
ddb4495571 | ||
|
|
44365e09dc | ||
|
|
b09dea38f5 | ||
|
|
56a6e97ef6 | ||
|
|
b0480823f6 | ||
|
|
ab61943cc5 | ||
|
|
08ace3680d | ||
|
|
e6729143c3 | ||
|
|
cf8bf6a8b5 | ||
|
|
339cc28249 | ||
|
|
0e28aa7509 | ||
|
|
8879fc6f1b | ||
|
|
2a231ec72c | ||
|
|
eb96432a2f | ||
|
|
da32c32259 | ||
|
|
820fbe19fc | ||
|
|
4aeff18535 | ||
|
|
31e1055abd | ||
|
|
dfc91efff2 | ||
|
|
1bbfa0c520 | ||
|
|
58294e0f39 | ||
|
|
3396a590f6 | ||
|
|
381e0f0ea1 | ||
|
|
1a984330a6 | ||
|
|
8aefe455be | ||
|
|
d7b4c5611b | ||
|
|
af4eb55c27 | ||
|
|
3374176e2e | ||
|
|
dc54382af7 | ||
|
|
1c1e097dc6 | ||
|
|
4756403172 | ||
|
|
f050d8cc7f | ||
|
|
3d7bdb6bed | ||
|
|
e98d6649cf | ||
|
|
d6e26fccd8 | ||
|
|
efa6e475ff | ||
|
|
7ff1b41e19 | ||
|
|
2e86b8c61c | ||
|
|
f1f6e04a67 | ||
|
|
79775a0ac4 | ||
|
|
681132674b | ||
|
|
09ed003ea4 | ||
|
|
0dc0e64caa | ||
|
|
e67aa57cb3 | ||
|
|
4c5ab7bcaf | ||
|
|
95d8619c94 | ||
|
|
838a6cba5d | ||
|
|
c870697c84 | ||
|
|
988d8e77e8 | ||
|
|
33214e4d6b | ||
|
|
ba477a944b | ||
|
|
35f141b001 | ||
|
|
74b8c44e6e | ||
|
|
8a33c79509 | ||
|
|
7592019690 | ||
|
|
13d8ab4f58 | ||
|
|
52734c48d0 | ||
|
|
c930074184 | ||
|
|
81f2f67551 | ||
|
|
d621024300 | ||
|
|
bdd3188287 | ||
|
|
c7a51847bd | ||
|
|
ab56ec5fb7 | ||
|
|
ef4b4285da | ||
|
|
0f197c1934 | ||
|
|
20614184ec | ||
|
|
3bdb837196 | ||
|
|
82b9a69231 | ||
|
|
828d75674d | ||
|
|
b10c237a0c | ||
|
|
a8434c68b6 | ||
|
|
e129035b56 | ||
|
|
fbfb0f7195 | ||
|
|
53b38e8ee4 | ||
|
|
c8f49c680f | ||
|
|
6fde504ed9 | ||
|
|
49af8b6055 | ||
|
|
4f379e01d3 | ||
|
|
30ab053db4 | ||
|
|
72d3e3caa8 | ||
|
|
08e407b7f4 | ||
|
|
1be1b57bde | ||
|
|
719f8e19fb | ||
|
|
a4084a4580 | ||
|
|
fe5cee274a | ||
|
|
a4b19e4879 | ||
|
|
6ecb8447b6 | ||
|
|
6c26d9b529 | ||
|
|
454be09d05 | ||
|
|
8101136d58 | ||
|
|
4f1fd8f630 | ||
|
|
29e4da27fb | ||
|
|
59c30fc24b | ||
|
|
7138e02aa1 | ||
|
|
64781098f6 | ||
|
|
c48ae42bcd | ||
|
|
322b1415e4 | ||
|
|
8309faae02 | ||
|
|
dd110b0688 | ||
|
|
7784de5a5f | ||
|
|
c2285c7a23 | ||
|
|
7875e6c88c | ||
|
|
6388b9aa50 | ||
|
|
3423576116 | ||
|
|
ec1ba9d28d | ||
|
|
fdbfc34fd8 | ||
|
|
76c58d1c63 | ||
|
|
9b76933766 | ||
|
|
7e8b0b3fad | ||
|
|
2797a9c751 | ||
|
|
26b93ed48c | ||
|
|
d67c6994c4 | ||
|
|
d5a91261a5 | ||
|
|
d812c74535 | ||
|
|
5414260082 | ||
|
|
df3eedf79f | ||
|
|
02ace774a6 | ||
|
|
9c55e4efc8 | ||
|
|
c506997810 | ||
|
|
91a36299ac | ||
|
|
b32096ef35 | ||
|
|
ddaefa3f60 | ||
|
|
96245cf82d | ||
|
|
5aa96c5b02 | ||
|
|
d0143f98fb | ||
|
|
7d89a81853 | ||
|
|
4ce2fb53a8 | ||
|
|
3b433089e3 | ||
|
|
8939df7cd3 | ||
|
|
c56877c785 | ||
|
|
f890ad4246 | ||
|
|
1b34b99a75 | ||
|
|
8c47026554 | ||
|
|
f9fc9d2c90 | ||
|
|
bbc67e403f | ||
|
|
6fe4a35b03 | ||
|
|
32facf7ebc | ||
|
|
f90c02bbb8 | ||
|
|
88601bd0af | ||
|
|
1152429d9a | ||
|
|
540fe6c22e | ||
|
|
a676916da2 | ||
|
|
e330350960 | ||
|
|
9806c39e52 | ||
|
|
be87ac9421 | ||
|
|
591db0bdd2 | ||
|
|
4e84b0d65e | ||
|
|
7b20563f2b | ||
|
|
bcfddb431d | ||
|
|
5cdd7999d2 | ||
|
|
52559f1aad | ||
|
|
a2f9090cc7 | ||
|
|
87feefe5f8 | ||
|
|
08bb39d3d1 | ||
|
|
76cf3137c5 | ||
|
|
8d6c4bb575 | ||
|
|
85b57ca98c | ||
|
|
d4bee21d90 | ||
|
|
1fa0aa8e27 | ||
|
|
652e9ee200 | ||
|
|
edcdc7990b | ||
|
|
ddcdbaf098 | ||
|
|
a300e885f1 | ||
|
|
8fb2952a59 | ||
|
|
7a5e2ea6c3 | ||
|
|
2ebac37d4e | ||
|
|
449e306433 | ||
|
|
b3cb99118a | ||
|
|
a6bc63761d | ||
|
|
5f3ce86836 | ||
|
|
c7eb77d730 | ||
|
|
81f1200710 | ||
|
|
7cff7894da | ||
|
|
ff5157ee99 | ||
|
|
8bae36c0d8 | ||
|
|
0c824088f3 | ||
|
|
ab828a2579 | ||
|
|
1eaf28e985 | ||
|
|
4675399919 | ||
|
|
263cf7725e | ||
|
|
b95dc22403 | ||
|
|
54471dfab0 | ||
|
|
a8de81aba7 | ||
|
|
5d29847714 | ||
|
|
5ad44bedcc | ||
|
|
7f6388e655 | ||
|
|
ae20a4b8cf | ||
|
|
b09bf523c3 | ||
|
|
c0fda663ac | ||
|
|
d9be6fbf7f | ||
|
|
3444a8d5f6 | ||
|
|
2812948bb6 | ||
|
|
612fed0428 | ||
|
|
dabf8e91b7 | ||
|
|
9a59aded6c | ||
|
|
87b062e8da | ||
|
|
eb5f93325b | ||
|
|
15c06c7ebe | ||
|
|
60edc820a8 | ||
|
|
f87f473aeb | ||
|
|
aaa23a0d6e | ||
|
|
5f3a2ebcaa | ||
|
|
36d5d612ed | ||
|
|
0892121cf7 | ||
|
|
04bc7a3f20 | ||
|
|
081c258943 | ||
|
|
26b2e616ab | ||
|
|
96364f0d3b | ||
|
|
31c1c69431 | ||
|
|
daae5a8ba9 | ||
|
|
f4aef0eda8 | ||
|
|
c8cb74c52a | ||
|
|
1096c17523 | ||
|
|
87031a0995 | ||
|
|
9018dcb377 | ||
|
|
503a0efc31 | ||
|
|
f64b17b548 | ||
|
|
74b897dfd7 | ||
|
|
d622d717b8 | ||
|
|
12b4aefa2f | ||
|
|
0d8a713d69 | ||
|
|
9cf3310f1e | ||
|
|
097dbdcdee | ||
|
|
be936ddf6b | ||
|
|
a639753fe9 | ||
|
|
c32bcfd8ad | ||
|
|
4959712df0 | ||
|
|
791b73f1a5 | ||
|
|
0e7c7e8033 | ||
|
|
0db17bac6c | ||
|
|
e00b300017 | ||
|
|
15c8b4cbfd | ||
|
|
1529894830 | ||
|
|
d2b640162f | ||
|
|
48b172e6c9 | ||
|
|
048e1e3f85 | ||
|
|
f6cf5ab6ca | ||
|
|
77bf53800d | ||
|
|
e6a765cd34 | ||
|
|
21bc893410 | ||
|
|
9b19b09eb2 | ||
|
|
0ee13b8814 | ||
|
|
fb0d67d7df | ||
|
|
28dff1831f | ||
|
|
4be95fd878 | ||
|
|
528850b28f | ||
|
|
32fa5d1e8f | ||
|
|
30a7db3624 | ||
|
|
992647fd14 | ||
|
|
f3526100a8 | ||
|
|
d5e5875325 | ||
|
|
a1741dd839 | ||
|
|
cd0df97ed4 | ||
|
|
998ba53519 | ||
|
|
1a52581e4e | ||
|
|
2a6e63917f | ||
|
|
fddfb4389d | ||
|
|
67f19b350a | ||
|
|
2f52b340f2 | ||
|
|
25843a67ca | ||
|
|
e53d49bf0a | ||
|
|
cfdfd870bb | ||
|
|
2318b48b26 | ||
|
|
9ad8bff4ff | ||
|
|
9cd7640125 | ||
|
|
d5ef554e5e | ||
|
|
3542bb92aa | ||
|
|
05ad9bc907 | ||
|
|
a35b32ef4d | ||
|
|
f497b33e88 | ||
|
|
0ebfcf1edd | ||
|
|
79bec85e27 | ||
|
|
1673395ad8 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -37,6 +37,7 @@ nbdist/
|
||||
######################################################################
|
||||
# Others
|
||||
*.log
|
||||
*.log.gz
|
||||
*.xml.versionsBackup
|
||||
*.swp
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="ruoyi-auth" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-auth:2.2.1" />
|
||||
<option name="imageTag" value="ruoyi/ruoyi-auth:2.5.2" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-auth/Dockerfile" />
|
||||
</settings>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="ruoyi-gateway" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-gateway:2.2.1" />
|
||||
<option name="imageTag" value="ruoyi/ruoyi-gateway:2.5.2" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-gateway/Dockerfile" />
|
||||
</settings>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="ruoyi-gen" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-gen:2.2.1" />
|
||||
<option name="imageTag" value="ruoyi/ruoyi-gen:2.5.2" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-modules/ruoyi-gen/Dockerfile" />
|
||||
</settings>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="ruoyi-job" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-job:2.2.1" />
|
||||
<option name="imageTag" value="ruoyi/ruoyi-job:2.5.2" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-modules/ruoyi-job/Dockerfile" />
|
||||
</settings>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="ruoyi-monitor" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-monitor:2.2.1" />
|
||||
<option name="imageTag" value="ruoyi/ruoyi-monitor:2.5.2" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-visual/ruoyi-monitor/Dockerfile" />
|
||||
</settings>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="ruoyi-nacos" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-nacos:2.2.1" />
|
||||
<option name="imageTag" value="ruoyi/ruoyi-nacos:2.5.2" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-visual/ruoyi-nacos/Dockerfile" />
|
||||
</settings>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="ruoyi-resource" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-resource:2.2.1" />
|
||||
<option name="imageTag" value="ruoyi/ruoyi-resource:2.5.2" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-modules/ruoyi-resource/Dockerfile" />
|
||||
</settings>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="ruoyi-seata-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-seata-server:2.2.1" />
|
||||
<option name="imageTag" value="ruoyi/ruoyi-seata-server:2.5.2" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-visual/ruoyi-seata-server/Dockerfile" />
|
||||
</settings>
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="ruoyi-sentinel-dashboard" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-sentinel-dashboard:2.2.1" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-visual/ruoyi-sentinel-dashboard/Dockerfile" />
|
||||
</settings>
|
||||
</deployment>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="ruoyi-snailjob-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-snailjob-server:2.2.1" />
|
||||
<option name="imageTag" value="ruoyi/ruoyi-snailjob-server:2.5.2" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-visual/ruoyi-snailjob-server/Dockerfile" />
|
||||
</settings>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="ruoyi-system" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-system:2.2.1" />
|
||||
<option name="imageTag" value="ruoyi/ruoyi-system:2.5.2" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-modules/ruoyi-system/Dockerfile" />
|
||||
</settings>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="ruoyi-workflow" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-workflow:2.2.1" />
|
||||
<option name="imageTag" value="ruoyi/ruoyi-workflow:2.5.2" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-modules/ruoyi-workflow/Dockerfile" />
|
||||
</settings>
|
||||
|
||||
31
README.md
31
README.md
@ -6,24 +6,28 @@
|
||||
|
||||
[](https://gitee.com/dromara/RuoYi-Cloud-Plus)
|
||||
[](https://github.com/dromara/RuoYi-Cloud-Plus)
|
||||
[](https://gitee.com/dromara/RuoYi-Cloud-Plus/blob/master/LICENSE)
|
||||
[](https://gitcode.com/dromara/RuoYi-Cloud-Plus)
|
||||
[](https://gitee.com/dromara/RuoYi-Cloud-Plus/blob/2.X/LICENSE)
|
||||
[](https://www.jetbrains.com/?from=RuoYi-Cloud-Plus)
|
||||
<br>
|
||||
[](https://gitee.com/dromara/RuoYi-Cloud-Plus)
|
||||
[]()
|
||||
[](https://gitee.com/dromara/RuoYi-Cloud-Plus)
|
||||
[]()
|
||||
[]()
|
||||
[]()
|
||||
|
||||
> RuoYi-Cloud-Plus `微服务通用权限管理系统` 重写 RuoYi-Cloud 全方位升级(不兼容原框架)
|
||||
> Dromara RuoYi-Cloud-Plus `微服务通用权限管理系统` 重写 RuoYi-Cloud 全方位升级(不兼容原框架)
|
||||
|
||||
> 项目代码、文档 均开源免费可商用 遵循开源协议在项目中保留开源协议文件即可<br>
|
||||
活到老写到老 为兴趣而开源 为学习而开源 为让大家真正可以学到技术而开源
|
||||
|
||||
> 系统演示: [传送门](https://plus-doc.dromara.org/#/common/demo_system)
|
||||
|
||||
> 前端项目地址: [plus-ui](https://gitee.com/JavaLionLi/plus-ui)
|
||||
> 官方前端项目地址: [gitee](https://gitee.com/JavaLionLi/plus-ui) - [github](https://github.com/JavaLionLi/plus-ui) - [gitcode](https://gitcode.com/dromara/plus-ui)<br>
|
||||
> 成员前端项目地址: 基于vben5 [ruoyi-plus-vben5](https://gitee.com/dapppp/ruoyi-plus-vben5)<br>
|
||||
> 成员前端项目地址: 基于soybean [ruoyi-plus-soybean](https://gitee.com/xlsea/ruoyi-plus-soybean)<br>
|
||||
> 成员项目地址: 删除多租户与工作流 [RuoYi-Vue-Plus-Single](https://gitee.com/ColorDreams/RuoYi-Vue-Plus-Single)<br>
|
||||
|
||||
> 文档地址: [plus-doc](https://plus-doc.dromara.org)
|
||||
> 文档地址: [plus-doc](https://plus-doc.dromara.org) 国内加速: [plus-doc.top](https://plus-doc.top)
|
||||
|
||||
## 赞助商
|
||||
|
||||
@ -31,7 +35,13 @@ MaxKey 业界领先单点登录产品 - https://gitee.com/dromara/MaxKey <br>
|
||||
CCFlow 驰聘低代码-流程-表单 - https://gitee.com/opencc/RuoYi-JFlow <br>
|
||||
数舵科技 软件定制开发APP小程序等 - http://www.shuduokeji.com/ <br>
|
||||
引迈信息 软件开发平台 - https://www.jnpfsoft.com/index.html?from=plus-doc <br>
|
||||
[如何成为赞助商 加群联系作者详谈](https://plus-doc.dromara.org/#/common/add_group)
|
||||
<font color="red">**启山商城系统 多租户商城源码可免费商用可二次开发 - https://www.73app.cn/** </font><br>
|
||||
Mall4J 高质量Java商城系统 - https://www.mall4j.com/cn/?statId=11 <br>
|
||||
aizuda flowlong 工作流 - https://gitee.com/aizuda/flowlong <br>
|
||||
Ruoyi-Plus-Uniapp - https://ruoyi.plus <br>
|
||||
Topiam IAM/IDaaS身份管理平台 - https://www.topiam.cn/ <br>
|
||||
|
||||
[如何成为赞助商 加群联系作者详谈 每日PV2500-3000 IP1700-2500](https://plus-doc.dromara.org/#/common/add_group)
|
||||
|
||||
# 本框架与RuoYi的功能差异
|
||||
|
||||
@ -81,7 +91,7 @@ CCFlow 驰聘低代码-流程-表单 - https://gitee.com/opencc/RuoYi-JFlow <br>
|
||||
| 邮件 | 采用 mail-api 通用协议支持大部分邮件厂商 | 不支持 |
|
||||
| 接口文档 | 采用 SpringDoc、javadoc 无注解零入侵基于java注释<br/>只需把注释写好 无需再写一大堆的文档注解了 | 采用 Springfox 已停止维护 需要编写大量的注解来支持文档生成 |
|
||||
| 校验框架 | 采用 Validation 支持注解与工具类校验 注解支持国际化 | 仅支持注解 且注解不支持国际化 |
|
||||
| Excel框架 | 采用 Alibaba EasyExcel 基于插件化<br/>框架对其增加了很多功能 例如 自动合并相同内容 自动排列布局 字典翻译等 | 基于 POI 手写实现 功能有限 复杂 扩展性差 |
|
||||
| Excel框架 | 采用 FastExcel(原Alibaba EasyExcel) 基于插件化<br/>框架对其增加了很多功能 例如 自动合并相同内容 自动排列布局 字典翻译等 | 基于 POI 手写实现 功能有限 复杂 扩展性差 |
|
||||
| 工作流支持 | 支持各种复杂审批 转办 委派 加减签 会签 或签 票签 等功能 | 无 |
|
||||
| 工具类框架 | 采用 Hutool、Lombok 上百种工具覆盖90%的使用需求 基于注解自动生成 get set 等简化框架大量代码 | 手写工具稳定性差易出问题 工具数量有限 代码臃肿需自己手写 get set 等 |
|
||||
| 服务监控框架 | 采用 SpringBoot-Admin 基于SpringBoot官方 actuator 探针机制<br/>实时监控服务状态 框架还为其扩展了在线日志查看监控 | 无 |
|
||||
@ -118,7 +128,6 @@ CCFlow 驰聘低代码-流程-表单 - https://gitee.com/opencc/RuoYi-JFlow <br>
|
||||
| 系统接口 | 根据业务代码自动生成相关的api接口文档 | 支持 | 支持 |
|
||||
| 服务监控 | 监视集群系统CPU、内存、磁盘、堆栈、在线日志、Spring相关配置等 | 支持 | 仅支持单机CPU、内存、磁盘监控 |
|
||||
| 缓存监控 | 对系统的缓存信息查询,命令统计等。 | 支持 | 支持 |
|
||||
| 在线构建器 | 拖动表单元素生成相应的HTML代码。 | 支持 | 支持 |
|
||||
| 使用案例 | 系统的一些功能案例 | 支持 | 不支持 |
|
||||
|
||||
## 参考文档
|
||||
@ -175,8 +184,8 @@ CCFlow 驰聘低代码-流程-表单 - https://gitee.com/opencc/RuoYi-JFlow <br>
|
||||
|  |  |
|
||||
|  |  |
|
||||
|  |  |
|
||||
|  |  |
|
||||
|  |  |
|
||||
|  |  |
|
||||
|  |  |
|
||||
|  |  |
|
||||
|
||||
|
||||
|
||||
BIN
bpmn/模型.zip
BIN
bpmn/模型.zip
Binary file not shown.
@ -1,100 +0,0 @@
|
||||
# 安全配置
|
||||
security:
|
||||
# 防止XSS攻击
|
||||
xss:
|
||||
enabled: true
|
||||
excludeUrls:
|
||||
- /system/notice
|
||||
- /workflow/model/save
|
||||
- /workflow/model/editModelXml
|
||||
# 不校验白名单
|
||||
ignore:
|
||||
whites:
|
||||
- /auth/code
|
||||
- /auth/logout
|
||||
- /auth/login
|
||||
- /auth/binding/*
|
||||
- /auth/social/callback
|
||||
- /auth/register
|
||||
- /auth/tenant/list
|
||||
- /resource/sms/code
|
||||
- /resource/sse/close
|
||||
- /*/v3/api-docs
|
||||
- /*/error
|
||||
- /csrf
|
||||
|
||||
spring:
|
||||
cloud:
|
||||
# 网关配置
|
||||
gateway:
|
||||
# 打印请求日志(自定义)
|
||||
requestLog: true
|
||||
discovery:
|
||||
locator:
|
||||
lowerCaseServiceId: true
|
||||
enabled: true
|
||||
routes:
|
||||
# 认证中心
|
||||
- id: ruoyi-auth
|
||||
uri: lb://ruoyi-auth
|
||||
predicates:
|
||||
- Path=/auth/**
|
||||
filters:
|
||||
- StripPrefix=1
|
||||
# 代码生成
|
||||
- id: ruoyi-gen
|
||||
uri: lb://ruoyi-gen
|
||||
predicates:
|
||||
- Path=/tool/**
|
||||
filters:
|
||||
- StripPrefix=1
|
||||
# 系统模块
|
||||
- id: ruoyi-system
|
||||
uri: lb://ruoyi-system
|
||||
predicates:
|
||||
- Path=/system/**,/monitor/**
|
||||
filters:
|
||||
- StripPrefix=1
|
||||
# 资源服务
|
||||
- id: ruoyi-resource
|
||||
uri: lb://ruoyi-resource
|
||||
predicates:
|
||||
- Path=/resource/**
|
||||
filters:
|
||||
- StripPrefix=1
|
||||
# workflow服务
|
||||
- id: ruoyi-workflow
|
||||
uri: lb://ruoyi-workflow
|
||||
predicates:
|
||||
- Path=/workflow/**
|
||||
# 演示服务
|
||||
- id: ruoyi-demo
|
||||
uri: lb://ruoyi-demo
|
||||
predicates:
|
||||
- Path=/demo/**
|
||||
filters:
|
||||
- StripPrefix=1
|
||||
# MQ演示服务
|
||||
- id: ruoyi-test-mq
|
||||
uri: lb://ruoyi-test-mq
|
||||
predicates:
|
||||
- Path=/test-mq/**
|
||||
filters:
|
||||
- StripPrefix=1
|
||||
|
||||
# sentinel 配置
|
||||
sentinel:
|
||||
filter:
|
||||
enabled: false
|
||||
# nacos配置持久化
|
||||
datasource:
|
||||
ds1:
|
||||
nacos:
|
||||
server-addr: ${spring.cloud.nacos.server-addr}
|
||||
dataId: sentinel-${spring.application.name}.json
|
||||
groupId: ${spring.cloud.nacos.config.group}
|
||||
username: ${spring.cloud.nacos.username}
|
||||
password: ${spring.cloud.nacos.password}
|
||||
namespace: ${spring.profiles.active}
|
||||
data-type: json
|
||||
rule-type: gw-flow
|
||||
@ -1,27 +0,0 @@
|
||||
spring:
|
||||
mvc:
|
||||
pathmatch:
|
||||
# 修复 sentinel 控制台未适配 springboot 2.6 新路由方式
|
||||
matching-strategy: ANT_PATH_MATCHER
|
||||
|
||||
server:
|
||||
servlet:
|
||||
encoding:
|
||||
force: true
|
||||
charset: UTF-8
|
||||
enabled: true
|
||||
session:
|
||||
cookie:
|
||||
name: sentinel_dashboard_cookie
|
||||
|
||||
logging:
|
||||
level:
|
||||
org.springframework.web: INFO
|
||||
|
||||
auth:
|
||||
enabled: true
|
||||
filter:
|
||||
exclude-urls: /,/auth/login,/auth/logout,/registry/machine,/version,/actuator,/actuator/**
|
||||
exclude-url-suffixes: htm,html,js,css,map,ico,ttf,woff,png
|
||||
username: sentinel
|
||||
password: sentinel
|
||||
@ -1,26 +0,0 @@
|
||||
[
|
||||
{
|
||||
"resource": "ruoyi-auth",
|
||||
"count": 500,
|
||||
"grade": 1,
|
||||
"limitApp": "default",
|
||||
"strategy": 0,
|
||||
"controlBehavior": 0
|
||||
},
|
||||
{
|
||||
"resource": "ruoyi-system",
|
||||
"count": 1000,
|
||||
"grade": 1,
|
||||
"limitApp": "default",
|
||||
"strategy": 0,
|
||||
"controlBehavior": 0
|
||||
},
|
||||
{
|
||||
"resource": "ruoyi-resource",
|
||||
"count": 500,
|
||||
"grade": 1,
|
||||
"limitApp": "default",
|
||||
"strategy": 0,
|
||||
"controlBehavior": 0
|
||||
}
|
||||
]
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
163
pom.xml
163
pom.xml
@ -10,63 +10,60 @@
|
||||
|
||||
<name>RuoYi-Cloud-Plus</name>
|
||||
<url>https://gitee.com/dromara/RuoYi-Cloud-Plus</url>
|
||||
<description>RuoYi-Cloud-Plus微服务系统</description>
|
||||
<description>Dromara RuoYi-Cloud-Plus微服务系统</description>
|
||||
|
||||
<properties>
|
||||
<revision>2.2.1</revision>
|
||||
<revision>2.5.2</revision>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>17</java.version>
|
||||
<spring-boot.version>3.2.9</spring-boot.version>
|
||||
<spring-cloud.version>2023.0.3</spring-cloud.version>
|
||||
<spring-boot-admin.version>3.2.3</spring-boot-admin.version>
|
||||
<spring-boot.version>3.5.9</spring-boot.version>
|
||||
<spring-cloud.version>2025.0.1</spring-cloud.version>
|
||||
<spring-boot-admin.version>3.5.5</spring-boot-admin.version>
|
||||
<mybatis.version>3.5.16</mybatis.version>
|
||||
<mybatis-plus.version>3.5.7</mybatis-plus.version>
|
||||
<mybatis-plus.version>3.5.14</mybatis-plus.version>
|
||||
<p6spy.version>3.9.1</p6spy.version>
|
||||
<dynamic-ds.version>4.3.1</dynamic-ds.version>
|
||||
<velocity.version>2.3</velocity.version>
|
||||
<swagger.core.version>2.2.22</swagger.core.version>
|
||||
<springdoc.version>2.6.0</springdoc.version>
|
||||
<swagger.core.version>2.2.38</swagger.core.version>
|
||||
<springdoc.version>2.8.14</springdoc.version>
|
||||
<therapi-javadoc.version>0.15.0</therapi-javadoc.version>
|
||||
<easyexcel.version>4.0.2</easyexcel.version>
|
||||
<hutool.version>5.8.31</hutool.version>
|
||||
<redisson.version>3.34.1</redisson.version>
|
||||
<fastexcel.version>1.3.0</fastexcel.version>
|
||||
<hutool.version>5.8.40</hutool.version>
|
||||
<redisson.version>3.52.0</redisson.version>
|
||||
<lock4j.version>2.2.7</lock4j.version>
|
||||
<snailjob.version>1.1.2</snailjob.version>
|
||||
<satoken.version>1.38.0</satoken.version>
|
||||
<lombok.version>1.18.34</lombok.version>
|
||||
<snailjob.version>1.9.0</snailjob.version>
|
||||
<satoken.version>1.44.0</satoken.version>
|
||||
<lombok.version>1.18.40</lombok.version>
|
||||
<logstash.version>7.4</logstash.version>
|
||||
<easy-es.version>2.0.0</easy-es.version>
|
||||
<elasticsearch.version>7.14.0</elasticsearch.version>
|
||||
<skywalking-toolkit.version>9.2.0</skywalking-toolkit.version>
|
||||
<bouncycastle.version>1.76</bouncycastle.version>
|
||||
<mapstruct-plus.version>1.4.4</mapstruct-plus.version>
|
||||
<easy-es.version>3.0.1</easy-es.version>
|
||||
<elasticsearch-client.version>7.17.28</elasticsearch-client.version>
|
||||
<skywalking-toolkit.version>9.3.0</skywalking-toolkit.version>
|
||||
<bouncycastle.version>1.80</bouncycastle.version>
|
||||
<mapstruct-plus.version>1.5.0</mapstruct-plus.version>
|
||||
<mapstruct-plus.lombok.version>0.2.0</mapstruct-plus.lombok.version>
|
||||
<justauth.version>1.16.6</justauth.version>
|
||||
<justauth.version>1.16.7</justauth.version>
|
||||
<!-- 离线IP地址定位库 -->
|
||||
<ip2region.version>2.7.0</ip2region.version>
|
||||
<undertow.version>2.3.15.Final</undertow.version>
|
||||
<ip2region.version>3.3.1</ip2region.version>
|
||||
<!-- 临时修复 fastjson 漏洞 -->
|
||||
<fastjson.version>1.2.83</fastjson.version>
|
||||
|
||||
<!-- OSS 配置 -->
|
||||
<aws.sdk.version>2.25.15</aws.sdk.version>
|
||||
<aws.crt.version>0.29.13</aws.crt.version>
|
||||
<okhttp.version>4.10.0</okhttp.version>
|
||||
|
||||
<aws.sdk.version>2.28.22</aws.sdk.version>
|
||||
<!-- SMS 配置 -->
|
||||
<sms4j.version>3.3.2</sms4j.version>
|
||||
<sms4j.version>3.3.4</sms4j.version>
|
||||
<!-- 面向运行时的D-ORM依赖 -->
|
||||
<anyline.version>8.7.2-20240808</anyline.version>
|
||||
<anyline.version>8.7.3-20251210</anyline.version>
|
||||
<!-- 工作流配置 -->
|
||||
<flowable.version>7.0.1</flowable.version>
|
||||
<warm-flow.version>1.8.4</warm-flow.version>
|
||||
<!-- mq配置 -->
|
||||
<rocketmq.version>2.3.0</rocketmq.version>
|
||||
<rocketmq.version>2.3.4</rocketmq.version>
|
||||
|
||||
<!-- 插件版本 -->
|
||||
<maven-compiler-plugin.verison>3.11.0</maven-compiler-plugin.verison>
|
||||
<maven-surefire-plugin.version>3.1.2</maven-surefire-plugin.version>
|
||||
<maven-compiler-plugin.version>3.14.0</maven-compiler-plugin.version>
|
||||
<maven-surefire-plugin.version>3.5.3</maven-surefire-plugin.version>
|
||||
<flatten-maven-plugin.version>1.3.0</flatten-maven-plugin.version>
|
||||
<!-- 打包默认跳过测试 -->
|
||||
<skipTests>true</skipTests>
|
||||
</properties>
|
||||
|
||||
<profiles>
|
||||
@ -141,13 +138,6 @@
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- JustAuth 的依赖配置-->
|
||||
<dependency>
|
||||
<groupId>me.zhyd.oauth</groupId>
|
||||
<artifactId>JustAuth</artifactId>
|
||||
<version>${justauth.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- common 的依赖配置-->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
@ -166,14 +156,6 @@
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.flowable</groupId>
|
||||
<artifactId>flowable-bom</artifactId>
|
||||
<version>${flowable.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-core</artifactId>
|
||||
@ -198,6 +180,12 @@
|
||||
<version>${mybatis-plus.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-jsqlparser</artifactId>
|
||||
<version>${mybatis-plus.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-annotation</artifactId>
|
||||
@ -235,9 +223,9 @@
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>easyexcel</artifactId>
|
||||
<version>${easyexcel.version}</version>
|
||||
<groupId>cn.idev.excel</groupId>
|
||||
<artifactId>fastexcel</artifactId>
|
||||
<version>${fastexcel.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 代码生成使用模板 -->
|
||||
@ -291,15 +279,17 @@
|
||||
<artifactId>easy-es-boot-starter</artifactId>
|
||||
<version>${easy-es.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.elasticsearch</groupId>
|
||||
<artifactId>elasticsearch</artifactId>
|
||||
<version>${elasticsearch.version}</version>
|
||||
<groupId>co.elastic.clients</groupId>
|
||||
<artifactId>elasticsearch-java</artifactId>
|
||||
<version>${elasticsearch-client.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.elasticsearch.client</groupId>
|
||||
<artifactId>elasticsearch-rest-high-level-client</artifactId>
|
||||
<version>${elasticsearch.version}</version>
|
||||
<artifactId>elasticsearch-rest-client</artifactId>
|
||||
<version>${elasticsearch-client.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- skywalking 整合 logback -->
|
||||
@ -314,30 +304,24 @@
|
||||
<version>${skywalking-toolkit.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>${okhttp.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- AWS SDK for Java 2.x -->
|
||||
<dependency>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>s3</artifactId>
|
||||
<version>${aws.sdk.version}</version>
|
||||
</dependency>
|
||||
<!-- 使用AWS基于 CRT 的 S3 客户端 -->
|
||||
<dependency>
|
||||
<groupId>software.amazon.awssdk.crt</groupId>
|
||||
<artifactId>aws-crt</artifactId>
|
||||
<version>${aws.crt.version}</version>
|
||||
</dependency>
|
||||
<!-- 基于 AWS CRT 的 S3 客户端的性能增强的 S3 传输管理器 -->
|
||||
<dependency>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>s3-transfer-manager</artifactId>
|
||||
<version>${aws.sdk.version}</version>
|
||||
</dependency>
|
||||
<!-- 将基于 Netty 的 HTTP 客户端从类路径中移除 -->
|
||||
<dependency>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>netty-nio-client</artifactId>
|
||||
<version>${aws.sdk.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!--短信sms4j-->
|
||||
<dependency>
|
||||
@ -346,6 +330,13 @@
|
||||
<version>${sms4j.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- JustAuth 的依赖配置-->
|
||||
<dependency>
|
||||
<groupId>me.zhyd.oauth</groupId>
|
||||
<artifactId>JustAuth</artifactId>
|
||||
<version>${justauth.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 离线IP地址定位库 ip2region -->
|
||||
<dependency>
|
||||
<groupId>org.lionsoul</groupId>
|
||||
@ -353,28 +344,6 @@
|
||||
<version>${ip2region.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.undertow</groupId>
|
||||
<artifactId>undertow-core</artifactId>
|
||||
<version>${undertow.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.undertow</groupId>
|
||||
<artifactId>undertow-servlet</artifactId>
|
||||
<version>${undertow.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.undertow</groupId>
|
||||
<artifactId>undertow-websockets-jsr</artifactId>
|
||||
<version>${undertow.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<artifactId>commons-compress</artifactId>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<version>1.26.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
@ -401,6 +370,18 @@
|
||||
<version>${rocketmq.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Warm-Flow国产工作流引擎, 在线文档:http://warm-flow.cn/ -->
|
||||
<dependency>
|
||||
<groupId>org.dromara.warm</groupId>
|
||||
<artifactId>warm-flow-mybatis-plus-sb3-starter</artifactId>
|
||||
<version>${warm-flow.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dromara.warm</groupId>
|
||||
<artifactId>warm-flow-plugin-ui-sb-web</artifactId>
|
||||
<version>${warm-flow.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
@ -424,7 +405,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.verison}</version>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
</description>
|
||||
|
||||
<properties>
|
||||
<revision>2.2.1</revision>
|
||||
<revision>2.5.2</revision>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package org.dromara.resource.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 消息服务
|
||||
*
|
||||
@ -13,7 +15,7 @@ public interface RemoteMessageService {
|
||||
* @param sessionKey session主键 一般为用户id
|
||||
* @param message 消息文本
|
||||
*/
|
||||
void publishMessage(Long sessionKey, String message);
|
||||
void publishMessage(List<Long> sessionKey, String message);
|
||||
|
||||
/**
|
||||
* 发布订阅的消息(群发)
|
||||
|
||||
@ -3,6 +3,8 @@ package org.dromara.resource.api;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 消息服务
|
||||
*
|
||||
@ -21,11 +23,11 @@ public class RemoteMessageServiceStub implements RemoteMessageService {
|
||||
* @param message 消息文本
|
||||
*/
|
||||
@Override
|
||||
public void publishMessage(Long sessionKey, String message) {
|
||||
public void publishMessage(List<Long> sessionKey, String message) {
|
||||
try {
|
||||
remoteMessageService.publishMessage(sessionKey, message);
|
||||
} catch (Exception e) {
|
||||
log.warn("websocket 功能未开启或服务未找到");
|
||||
log.warn("推送功能未开启或服务未找到");
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,7 +41,7 @@ public class RemoteMessageServiceStub implements RemoteMessageService {
|
||||
try {
|
||||
remoteMessageService.publishAll(message);
|
||||
} catch (Exception e) {
|
||||
log.warn("websocket 功能未开启或服务未找到");
|
||||
log.warn("推送功能未开启或服务未找到");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,4 +41,9 @@ public class RemoteFile implements Serializable {
|
||||
*/
|
||||
private String fileSuffix;
|
||||
|
||||
/**
|
||||
* 扩展字段
|
||||
*/
|
||||
private String ext1;
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,11 @@
|
||||
package org.dromara.system.api;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.lang.Dict;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 配置服务
|
||||
*
|
||||
@ -14,4 +20,88 @@ public interface RemoteConfigService {
|
||||
*/
|
||||
boolean selectRegisterEnabled(String tenantId);
|
||||
|
||||
/**
|
||||
* 根据参数 key 获取参数值
|
||||
*
|
||||
* @param configKey 参数 key
|
||||
* @return 参数值
|
||||
*/
|
||||
String getConfigValue(String configKey);
|
||||
|
||||
/**
|
||||
* 根据参数 key 获取布尔值
|
||||
*
|
||||
* @param configKey 参数 key
|
||||
* @return Boolean 值
|
||||
*/
|
||||
default Boolean getConfigBool(String configKey) {
|
||||
return Convert.toBool(getConfigValue(configKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据参数 key 获取整数值
|
||||
*
|
||||
* @param configKey 参数 key
|
||||
* @return Integer 值
|
||||
*/
|
||||
default Integer getConfigInt(String configKey) {
|
||||
return Convert.toInt(getConfigValue(configKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据参数 key 获取长整型值
|
||||
*
|
||||
* @param configKey 参数 key
|
||||
* @return Long 值
|
||||
*/
|
||||
default Long getConfigLong(String configKey) {
|
||||
return Convert.toLong(getConfigValue(configKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据参数 key 获取 BigDecimal 值
|
||||
*
|
||||
* @param configKey 参数 key
|
||||
* @return BigDecimal 值
|
||||
*/
|
||||
default BigDecimal getConfigDecimal(String configKey) {
|
||||
return Convert.toBigDecimal(getConfigValue(configKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据参数 key 获取 Map 类型的配置
|
||||
*
|
||||
* @param configKey 参数 key
|
||||
* @return Dict 对象,如果配置为空或无法解析,返回空 Dict
|
||||
*/
|
||||
Dict getConfigMap(String configKey);
|
||||
|
||||
/**
|
||||
* 根据参数 key 获取 Map 类型的配置列表
|
||||
*
|
||||
* @param configKey 参数 key
|
||||
* @return Dict 列表,如果配置为空或无法解析,返回空列表
|
||||
*/
|
||||
List<Dict> getConfigArrayMap(String configKey);
|
||||
|
||||
/**
|
||||
* 根据参数 key 获取指定类型的配置对象
|
||||
*
|
||||
* @param configKey 参数 key
|
||||
* @param clazz 目标对象类型
|
||||
* @param <T> 目标对象泛型
|
||||
* @return 对象实例,如果配置为空或无法解析,返回 null
|
||||
*/
|
||||
<T> T getConfigObject(String configKey, Class<T> clazz);
|
||||
|
||||
/**
|
||||
* 根据参数 key 获取指定类型的配置列表
|
||||
*
|
||||
* @param configKey 参数 key
|
||||
* @param clazz 目标元素类型
|
||||
* @param <T> 元素类型泛型
|
||||
* @return 指定类型列表,如果配置为空或无法解析,返回空列表
|
||||
*/
|
||||
<T> List<T> getConfigArray(String configKey, Class<T> clazz);
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,10 @@
|
||||
package org.dromara.system.api;
|
||||
|
||||
import org.dromara.system.api.domain.vo.RemoteDeptVo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 部门服务
|
||||
*
|
||||
@ -15,4 +20,27 @@ public interface RemoteDeptService {
|
||||
*/
|
||||
String selectDeptNameByIds(String deptIds);
|
||||
|
||||
/**
|
||||
* 根据部门ID查询部门负责人
|
||||
*
|
||||
* @param deptId 部门ID,用于指定需要查询的部门
|
||||
* @return 返回该部门的负责人ID
|
||||
*/
|
||||
Long selectDeptLeaderById(Long deptId);
|
||||
|
||||
/**
|
||||
* 查询部门
|
||||
*
|
||||
* @return 部门列表
|
||||
*/
|
||||
List<RemoteDeptVo> selectDeptsByList();
|
||||
|
||||
/**
|
||||
* 根据部门 ID 列表查询部门名称映射关系
|
||||
*
|
||||
* @param deptIds 部门 ID 列表
|
||||
* @return Map,其中 key 为部门 ID,value 为对应的部门名称
|
||||
*/
|
||||
Map<Long, String> selectDeptNamesByIds(List<Long> deptIds);
|
||||
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package org.dromara.system.api;
|
||||
|
||||
import org.dromara.system.api.domain.vo.RemoteDictDataVo;
|
||||
import org.dromara.system.api.domain.vo.RemoteDictTypeVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -11,6 +12,14 @@ import java.util.List;
|
||||
*/
|
||||
public interface RemoteDictService {
|
||||
|
||||
/**
|
||||
* 根据字典类型查询信息
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @return 字典类型
|
||||
*/
|
||||
RemoteDictTypeVo selectDictTypeByType(String dictType);
|
||||
|
||||
/**
|
||||
* 根据字典类型查询字典数据
|
||||
*
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
package org.dromara.system.api;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 用户权限处理
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface RemotePermissionService {
|
||||
|
||||
/**
|
||||
* 获取角色数据权限
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @return 角色权限信息
|
||||
*/
|
||||
Set<String> getRolePermission(Long userId);
|
||||
|
||||
/**
|
||||
* 获取菜单数据权限
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @return 菜单权限信息
|
||||
*/
|
||||
Set<String> getMenuPermission(Long userId);
|
||||
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
package org.dromara.system.api;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 岗位服务
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface RemotePostService {
|
||||
|
||||
/**
|
||||
* 根据岗位 ID 列表查询岗位名称映射关系
|
||||
*
|
||||
* @param postIds 岗位 ID 列表
|
||||
* @return Map,其中 key 为岗位 ID,value 为对应的岗位名称
|
||||
*/
|
||||
Map<Long, String> selectPostNamesByIds(List<Long> postIds);
|
||||
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
package org.dromara.system.api;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 角色服务
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface RemoteRoleService {
|
||||
|
||||
/**
|
||||
* 根据角色 ID 列表查询角色名称映射关系
|
||||
*
|
||||
* @param roleIds 角色 ID 列表
|
||||
* @return Map,其中 key 为角色 ID,value 为对应的角色名称
|
||||
*/
|
||||
Map<Long, String> selectRoleNamesByIds(List<Long> roleIds);
|
||||
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
package org.dromara.system.api;
|
||||
|
||||
import org.dromara.system.api.domain.bo.RemoteTaskAssigneeBo;
|
||||
import org.dromara.system.api.domain.vo.RemoteTaskAssigneeVo;
|
||||
|
||||
/**
|
||||
* 工作流设计器获取任务执行人
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface RemoteTaskAssigneeService {
|
||||
|
||||
/**
|
||||
* 查询角色并返回任务指派的列表,支持分页
|
||||
*
|
||||
* @param taskQuery 查询条件
|
||||
* @return 办理人
|
||||
*/
|
||||
RemoteTaskAssigneeVo selectRolesByTaskAssigneeList(RemoteTaskAssigneeBo taskQuery);
|
||||
|
||||
/**
|
||||
* 查询岗位并返回任务指派的列表,支持分页
|
||||
*
|
||||
* @param taskQuery 查询条件
|
||||
* @return 办理人
|
||||
*/
|
||||
RemoteTaskAssigneeVo selectPostsByTaskAssigneeList(RemoteTaskAssigneeBo taskQuery);
|
||||
|
||||
/**
|
||||
* 查询部门并返回任务指派的列表,支持分页
|
||||
*
|
||||
* @param taskQuery 查询条件
|
||||
* @return 办理人
|
||||
*/
|
||||
RemoteTaskAssigneeVo selectDeptsByTaskAssigneeList(RemoteTaskAssigneeBo taskQuery);
|
||||
|
||||
/**
|
||||
* 查询用户并返回任务指派的列表,支持分页
|
||||
*
|
||||
* @param taskQuery 查询条件
|
||||
* @return 办理人
|
||||
*/
|
||||
RemoteTaskAssigneeVo selectUsersByTaskAssigneeList(RemoteTaskAssigneeBo taskQuery);
|
||||
|
||||
}
|
||||
@ -8,6 +8,7 @@ import org.dromara.system.api.model.LoginUser;
|
||||
import org.dromara.system.api.model.XcxLoginUser;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 用户服务
|
||||
@ -131,4 +132,37 @@ public interface RemoteUserService {
|
||||
* @return 用户ids
|
||||
*/
|
||||
List<Long> selectUserIdsByRoleIds(List<Long> roleIds);
|
||||
|
||||
/**
|
||||
* 通过角色ID查询用户
|
||||
*
|
||||
* @param roleIds 角色ids
|
||||
* @return 用户
|
||||
*/
|
||||
List<RemoteUserVo> selectUsersByRoleIds(List<Long> roleIds);
|
||||
|
||||
/**
|
||||
* 通过部门ID查询用户
|
||||
*
|
||||
* @param deptIds 部门ids
|
||||
* @return 用户
|
||||
*/
|
||||
List<RemoteUserVo> selectUsersByDeptIds(List<Long> deptIds);
|
||||
|
||||
/**
|
||||
* 通过岗位ID查询用户
|
||||
*
|
||||
* @param postIds 岗位ids
|
||||
* @return 用户
|
||||
*/
|
||||
List<RemoteUserVo> selectUsersByPostIds(List<Long> postIds);
|
||||
|
||||
/**
|
||||
* 根据用户 ID 列表查询用户名称映射关系
|
||||
*
|
||||
* @param userIds 用户 ID 列表
|
||||
* @return Map,其中 key 为用户 ID,value 为对应的用户名称
|
||||
*/
|
||||
Map<Long, String> selectUserNamesByIds(List<Long> userIds);
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,56 @@
|
||||
package org.dromara.system.api.domain.bo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 任务受让人
|
||||
*
|
||||
* @author AprilWind
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class RemoteTaskAssigneeBo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 权限编码
|
||||
*/
|
||||
private String handlerCode;
|
||||
|
||||
/**
|
||||
* 权限名称
|
||||
*/
|
||||
private String handlerName;
|
||||
|
||||
/**
|
||||
* 权限分组
|
||||
*/
|
||||
private String groupId;
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
private String beginTime;
|
||||
|
||||
/**
|
||||
* 结束时间
|
||||
*/
|
||||
private String endTime;
|
||||
|
||||
/**
|
||||
* 当前页
|
||||
*/
|
||||
private Integer pageNum = 1;
|
||||
|
||||
/**
|
||||
* 每页显示条数
|
||||
*/
|
||||
private Integer pageSize = 10;
|
||||
|
||||
}
|
||||
@ -3,7 +3,7 @@ package org.dromara.system.api.domain.bo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.dromara.common.core.constant.UserConstants;
|
||||
import org.dromara.common.core.constant.SystemConstants;
|
||||
import org.dromara.common.core.xss.Xss;
|
||||
|
||||
import jakarta.validation.constraints.Email;
|
||||
@ -118,7 +118,7 @@ public class RemoteUserBo implements Serializable {
|
||||
}
|
||||
|
||||
public boolean isSuperAdmin() {
|
||||
return UserConstants.SUPER_ADMIN_ID.equals(this.userId);
|
||||
return SystemConstants.SUPER_ADMIN_ID.equals(this.userId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,37 @@
|
||||
package org.dromara.system.api.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 部门
|
||||
*
|
||||
* @author AprilWind
|
||||
*/
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class RemoteDeptVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 部门ID
|
||||
*/
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 父部门ID
|
||||
*/
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 部门名称
|
||||
*/
|
||||
private String deptName;
|
||||
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
package org.dromara.system.api.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
/**
|
||||
* 字典类型视图对象 sys_dict_type
|
||||
*
|
||||
* @author Michelle.Chung
|
||||
*/
|
||||
@Data
|
||||
public class RemoteDictTypeVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 字典主键
|
||||
*/
|
||||
private Long dictId;
|
||||
|
||||
/**
|
||||
* 字典名称
|
||||
*/
|
||||
private String dictName;
|
||||
|
||||
/**
|
||||
* 字典类型
|
||||
*/
|
||||
private String dictType;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
@ -0,0 +1,104 @@
|
||||
package org.dromara.system.api.domain.vo;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 任务受让人
|
||||
*
|
||||
* @author AprilWind
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class RemoteTaskAssigneeVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 总大小
|
||||
*/
|
||||
private Long total = 0L;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private List<TaskHandler> list;
|
||||
|
||||
public RemoteTaskAssigneeVo(Long total, List<TaskHandler> list) {
|
||||
this.total = total;
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将源列表转换为 TaskHandler 列表
|
||||
*
|
||||
* @param <T> 通用类型
|
||||
* @param sourceList 待转换的源列表
|
||||
* @param storageId 提取 storageId 的函数
|
||||
* @param handlerCode 提取 handlerCode 的函数
|
||||
* @param handlerName 提取 handlerName 的函数
|
||||
* @param groupName 提取 groupName 的函数
|
||||
* @param createTimeMapper 提取 createTime 的函数
|
||||
* @return 转换后的 TaskHandler 列表
|
||||
*/
|
||||
public static <T> List<TaskHandler> convertToHandlerList(
|
||||
List<T> sourceList,
|
||||
Function<T, String> storageId,
|
||||
Function<T, String> handlerCode,
|
||||
Function<T, String> handlerName,
|
||||
Function<T, String> groupName,
|
||||
Function<T, Date> createTimeMapper) {
|
||||
return sourceList.stream()
|
||||
.map(item -> new TaskHandler(
|
||||
storageId.apply(item),
|
||||
handlerCode.apply(item),
|
||||
handlerName.apply(item),
|
||||
groupName.apply(item),
|
||||
createTimeMapper.apply(item)
|
||||
)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class TaskHandler implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
private String storageId;
|
||||
|
||||
/**
|
||||
* 权限编码
|
||||
*/
|
||||
private String handlerCode;
|
||||
|
||||
/**
|
||||
* 权限名称
|
||||
*/
|
||||
private String handlerName;
|
||||
|
||||
/**
|
||||
* 权限分组
|
||||
*/
|
||||
private String groupName;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
}
|
||||
|
||||
}
|
||||
@ -115,6 +115,11 @@ public class LoginUser implements Serializable {
|
||||
*/
|
||||
private List<RoleDTO> roles;
|
||||
|
||||
/**
|
||||
* 岗位对象
|
||||
*/
|
||||
private List<PostDTO> posts;
|
||||
|
||||
/**
|
||||
* 数据权限 当前角色ID
|
||||
*/
|
||||
|
||||
@ -0,0 +1,46 @@
|
||||
package org.dromara.system.api.model;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 岗位
|
||||
*
|
||||
* @author AprilWind
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class PostDTO implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 岗位ID
|
||||
*/
|
||||
private Long postId;
|
||||
|
||||
/**
|
||||
* 部门id
|
||||
*/
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 岗位编码
|
||||
*/
|
||||
private String postCode;
|
||||
|
||||
/**
|
||||
* 岗位名称
|
||||
*/
|
||||
private String postName;
|
||||
|
||||
/**
|
||||
* 岗位类别编码
|
||||
*/
|
||||
private String postCategory;
|
||||
|
||||
}
|
||||
@ -35,7 +35,7 @@ public class RoleDTO implements Serializable {
|
||||
private String roleKey;
|
||||
|
||||
/**
|
||||
* 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限)
|
||||
* 数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限 5:仅本人数据权限 6:部门及以下或本人数据权限)
|
||||
*/
|
||||
private String dataScope;
|
||||
|
||||
|
||||
@ -22,9 +22,12 @@
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 非必需模块 如果需要跟工作流同步数据 则需要在对应服务内引入bus模块 如果只是调用工作流api则不需要 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-bus</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@ -0,0 +1,106 @@
|
||||
package org.dromara.workflow.api;
|
||||
|
||||
import org.dromara.workflow.api.domain.RemoteCompleteTask;
|
||||
import org.dromara.workflow.api.domain.RemoteStartProcess;
|
||||
import org.dromara.workflow.api.domain.RemoteStartProcessReturn;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 通用 工作流服务
|
||||
*
|
||||
* @Author ZETA
|
||||
* @Date 2024/6/3
|
||||
*/
|
||||
public interface RemoteWorkflowService {
|
||||
|
||||
/**
|
||||
* 运行中的实例 删除程实例,删除历史记录,删除业务与流程关联信息
|
||||
*
|
||||
* @param businessIds 业务id
|
||||
* @return 结果
|
||||
*/
|
||||
boolean deleteInstance(List<String> businessIds);
|
||||
|
||||
/**
|
||||
* 获取当前流程状态
|
||||
*
|
||||
* @param taskId 任务id
|
||||
* @return 状态
|
||||
*/
|
||||
String getBusinessStatusByTaskId(Long taskId);
|
||||
|
||||
/**
|
||||
* 获取当前流程状态
|
||||
*
|
||||
* @param businessId 业务id
|
||||
* @return 状态
|
||||
*/
|
||||
String getBusinessStatus(String businessId);
|
||||
|
||||
/**
|
||||
* 设置流程变量
|
||||
*
|
||||
* @param instanceId 流程实例id
|
||||
* @param variable 流程变量
|
||||
*/
|
||||
void setVariable(Long instanceId, Map<String, Object> variable);
|
||||
|
||||
/**
|
||||
* 获取流程变量
|
||||
*
|
||||
* @param instanceId 流程实例id
|
||||
*/
|
||||
Map<String, Object> instanceVariable(Long instanceId);
|
||||
|
||||
/**
|
||||
* 按照业务id查询流程实例id
|
||||
*
|
||||
* @param businessId 业务id
|
||||
* @return 结果
|
||||
*/
|
||||
Long getInstanceIdByBusinessId(String businessId);
|
||||
|
||||
/**
|
||||
* 新增租户流程定义
|
||||
*
|
||||
* @param tenantId 租户id
|
||||
*/
|
||||
void syncDef(String tenantId);
|
||||
|
||||
/**
|
||||
* 启动流程
|
||||
*
|
||||
* @param startProcess 参数
|
||||
* @return 结果
|
||||
*/
|
||||
RemoteStartProcessReturn startWorkFlow(RemoteStartProcess startProcess);
|
||||
|
||||
/**
|
||||
* 办理任务
|
||||
*
|
||||
* @param completeTask 参数
|
||||
* @return 结果
|
||||
*/
|
||||
boolean completeTask(RemoteCompleteTask completeTask);
|
||||
|
||||
|
||||
/**
|
||||
* 办理任务
|
||||
*
|
||||
* @param taskId 任务ID
|
||||
* @param message 办理意见
|
||||
* @return 结果
|
||||
*/
|
||||
boolean completeTask(Long taskId, String message);
|
||||
|
||||
/**
|
||||
* 启动流程并办理第一个任务
|
||||
*
|
||||
* @param startProcess 参数
|
||||
* @return 结果
|
||||
*/
|
||||
boolean startCompleteTask(RemoteStartProcess startProcess);
|
||||
|
||||
}
|
||||
@ -0,0 +1,83 @@
|
||||
package org.dromara.workflow.api;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.workflow.api.domain.RemoteCompleteTask;
|
||||
import org.dromara.workflow.api.domain.RemoteStartProcess;
|
||||
import org.dromara.workflow.api.domain.RemoteStartProcessReturn;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 工作流服务(降级处理)
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Slf4j
|
||||
public class RemoteWorkflowServiceMock implements RemoteWorkflowService {
|
||||
|
||||
@Override
|
||||
public boolean deleteInstance(List<String> businessIds) {
|
||||
log.warn("服务调用异常 -> 降级处理");
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBusinessStatusByTaskId(Long taskId) {
|
||||
log.warn("服务调用异常 -> 降级处理");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBusinessStatus(String businessId) {
|
||||
log.warn("服务调用异常 -> 降级处理");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVariable(Long instanceId, Map<String, Object> variable) {
|
||||
log.warn("服务调用异常 -> 降级处理");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> instanceVariable(Long instanceId) {
|
||||
log.warn("服务调用异常 -> 降级处理");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getInstanceIdByBusinessId(String businessId) {
|
||||
log.warn("服务调用异常 -> 降级处理");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syncDef(String tenantId) {
|
||||
log.warn("服务调用异常 -> 降级处理");
|
||||
}
|
||||
|
||||
@Override
|
||||
public RemoteStartProcessReturn startWorkFlow(RemoteStartProcess startProcess) {
|
||||
log.warn("服务调用异常 -> 降级处理");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean completeTask(RemoteCompleteTask completeTask) {
|
||||
log.warn("服务调用异常 -> 降级处理");
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean completeTask(Long taskId, String message) {
|
||||
log.warn("服务调用异常 -> 降级处理");
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startCompleteTask(RemoteStartProcess startProcess) {
|
||||
log.warn("服务调用异常 -> 降级处理");
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,76 @@
|
||||
package org.dromara.workflow.api.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 办理任务请求对象
|
||||
*
|
||||
* @author may
|
||||
*/
|
||||
@Data
|
||||
public class RemoteCompleteTask implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 任务id
|
||||
*/
|
||||
private Long taskId;
|
||||
|
||||
/**
|
||||
* 附件id
|
||||
*/
|
||||
private String fileId;
|
||||
|
||||
/**
|
||||
* 抄送人员
|
||||
*/
|
||||
private List<RemoteFlowCopy> flowCopyList;
|
||||
|
||||
/**
|
||||
* 消息类型
|
||||
*/
|
||||
private List<String> messageType;
|
||||
|
||||
/**
|
||||
* 办理意见
|
||||
*/
|
||||
private String message;
|
||||
|
||||
/**
|
||||
* 消息通知
|
||||
*/
|
||||
private String notice;
|
||||
|
||||
/**
|
||||
* 办理人(可不填 用于覆盖当前节点办理人)
|
||||
*/
|
||||
private String handler;
|
||||
|
||||
/**
|
||||
* 流程变量
|
||||
*/
|
||||
private Map<String, Object> variables;
|
||||
|
||||
/**
|
||||
* 扩展变量(此处为逗号分隔的ossId)
|
||||
*/
|
||||
private String ext;
|
||||
|
||||
public Map<String, Object> getVariables() {
|
||||
if (variables == null) {
|
||||
return new HashMap<>(16);
|
||||
}
|
||||
variables.entrySet().removeIf(entry -> Objects.isNull(entry.getValue()));
|
||||
return variables;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,28 +1,30 @@
|
||||
package org.dromara.workflow.domain.vo;
|
||||
package org.dromara.workflow.api.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* 流程变量
|
||||
* 抄送
|
||||
*
|
||||
* @author may
|
||||
*/
|
||||
@Data
|
||||
public class VariableVo implements Serializable {
|
||||
public class RemoteFlowCopy implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 变量key
|
||||
* 用户id
|
||||
*/
|
||||
private String key;
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 变量值
|
||||
* 用户名称
|
||||
*/
|
||||
private String value;
|
||||
private String userName;
|
||||
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
package org.dromara.workflow.api.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 流程实例业务扩展对象
|
||||
*
|
||||
* @author may
|
||||
* @date 2025-08-05
|
||||
*/
|
||||
@Data
|
||||
public class RemoteFlowInstanceBizExt implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 流程实例ID
|
||||
*/
|
||||
private Long instanceId;
|
||||
|
||||
/**
|
||||
* 业务ID
|
||||
*/
|
||||
private String businessId;
|
||||
|
||||
/**
|
||||
* 业务编码
|
||||
*/
|
||||
private String businessCode;
|
||||
|
||||
/**
|
||||
* 业务标题
|
||||
*/
|
||||
private String businessTitle;
|
||||
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
package org.dromara.workflow.api.domain;
|
||||
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 启动流程对象
|
||||
*
|
||||
* @author may
|
||||
*/
|
||||
@Data
|
||||
public class RemoteStartProcess implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 业务唯一值id
|
||||
*/
|
||||
private String businessId;
|
||||
|
||||
/**
|
||||
* 流程定义编码
|
||||
*/
|
||||
private String flowCode;
|
||||
|
||||
/**
|
||||
* 办理人(可不填 用于覆盖当前节点办理人)
|
||||
*/
|
||||
private String handler;
|
||||
|
||||
/**
|
||||
* 流程变量,前端会提交一个元素{'entity': {业务详情数据对象}}
|
||||
*/
|
||||
private Map<String, Object> variables;
|
||||
|
||||
/**
|
||||
* 流程业务扩展信息
|
||||
*/
|
||||
private RemoteFlowInstanceBizExt bizExt;
|
||||
|
||||
public Map<String, Object> getVariables() {
|
||||
if (variables == null) {
|
||||
return new HashMap<>(16);
|
||||
}
|
||||
variables.entrySet().removeIf(entry -> Objects.isNull(entry.getValue()));
|
||||
return variables;
|
||||
}
|
||||
|
||||
public RemoteFlowInstanceBizExt getBizExt() {
|
||||
if (ObjectUtil.isNull(bizExt)) {
|
||||
bizExt = new RemoteFlowInstanceBizExt();
|
||||
}
|
||||
return bizExt;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package org.dromara.workflow.api.domain;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 启动流程返回对象
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Data
|
||||
public class RemoteStartProcessReturn implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 流程实例id
|
||||
*/
|
||||
private Long processInstanceId;
|
||||
|
||||
/**
|
||||
* 任务id
|
||||
*/
|
||||
private Long taskId;
|
||||
|
||||
}
|
||||
@ -1,78 +0,0 @@
|
||||
package org.dromara.workflow.api.domain;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 通用 工作流服务
|
||||
*
|
||||
* @Author ZETA
|
||||
* @Date 2024/6/3
|
||||
*/
|
||||
public interface RemoteWorkflowService {
|
||||
|
||||
/**
|
||||
* 运行中的实例 删除程实例,删除历史记录,删除业务与流程关联信息
|
||||
*
|
||||
* @param businessKeys 业务id
|
||||
* @return 结果
|
||||
*/
|
||||
boolean deleteRunAndHisInstance(List<String> businessKeys);
|
||||
|
||||
/**
|
||||
* 获取当前流程状态
|
||||
*
|
||||
* @param taskId 任务id
|
||||
*/
|
||||
String getBusinessStatusByTaskId(String taskId);
|
||||
|
||||
/**
|
||||
* 获取当前流程状态
|
||||
*
|
||||
* @param businessKey 业务id
|
||||
*/
|
||||
String getBusinessStatus(String businessKey);
|
||||
|
||||
/**
|
||||
* 设置流程变量(全局变量)
|
||||
*
|
||||
* @param taskId 任务id
|
||||
* @param variableName 变量名称
|
||||
* @param value 变量值
|
||||
*/
|
||||
void setVariable(String taskId, String variableName, Object value);
|
||||
|
||||
/**
|
||||
* 设置流程变量(全局变量)
|
||||
*
|
||||
* @param taskId 任务id
|
||||
* @param variables 流程变量
|
||||
*/
|
||||
void setVariables(String taskId, Map<String, Object> variables);
|
||||
|
||||
/**
|
||||
* 设置流程变量(本地变量,非全局变量)
|
||||
*
|
||||
* @param taskId 任务id
|
||||
* @param variableName 变量名称
|
||||
* @param value 变量值
|
||||
*/
|
||||
void setVariableLocal(String taskId, String variableName, Object value);
|
||||
|
||||
/**
|
||||
* 设置流程变量(本地变量,非全局变量)
|
||||
*
|
||||
* @param taskId 任务id
|
||||
* @param variables 流程变量
|
||||
*/
|
||||
void setVariablesLocal(String taskId, Map<String, Object> variables);
|
||||
|
||||
/**
|
||||
* 按照业务id查询流程实例id
|
||||
*
|
||||
* @param businessKey 业务id
|
||||
* @return 结果
|
||||
*/
|
||||
String getInstanceIdByBusinessKey(String businessKey);
|
||||
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package org.dromara.workflow.api.domain.event;
|
||||
package org.dromara.workflow.api.event;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@ -8,38 +8,34 @@ import org.springframework.cloud.bus.event.RemoteApplicationEvent;
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 流程办理监听
|
||||
* 删除流程监听
|
||||
*
|
||||
* @author may
|
||||
* @author AprilWind
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class ProcessTaskEvent extends RemoteApplicationEvent {
|
||||
public class ProcessDeleteEvent extends RemoteApplicationEvent {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 流程定义key
|
||||
* 租户ID
|
||||
*/
|
||||
private String key;
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 审批节点key
|
||||
* 流程定义编码
|
||||
*/
|
||||
private String taskDefinitionKey;
|
||||
|
||||
/**
|
||||
* 任务id
|
||||
*/
|
||||
private String taskId;
|
||||
private String flowCode;
|
||||
|
||||
/**
|
||||
* 业务id
|
||||
*/
|
||||
private String businessKey;
|
||||
private String businessId;
|
||||
|
||||
public ProcessTaskEvent() {
|
||||
public ProcessDeleteEvent() {
|
||||
super(new Object(), SpringUtils.getApplicationName(), DEFAULT_DESTINATION_FACTORY.getDestination(null));
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package org.dromara.workflow.api.domain.event;
|
||||
package org.dromara.workflow.api.event;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@ -6,6 +6,7 @@ import org.dromara.common.core.utils.SpringUtils;
|
||||
import org.springframework.cloud.bus.event.RemoteApplicationEvent;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 总体流程监听
|
||||
@ -20,24 +21,54 @@ public class ProcessEvent extends RemoteApplicationEvent {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 流程定义key
|
||||
* 租户ID
|
||||
*/
|
||||
private String key;
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 流程定义编码
|
||||
*/
|
||||
private String flowCode;
|
||||
|
||||
/**
|
||||
* 实例id
|
||||
*/
|
||||
private Long instanceId;
|
||||
|
||||
/**
|
||||
* 业务id
|
||||
*/
|
||||
private String businessKey;
|
||||
private String businessId;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
* 节点类型(0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关)
|
||||
*/
|
||||
private Integer nodeType;
|
||||
|
||||
/**
|
||||
* 流程节点编码
|
||||
*/
|
||||
private String nodeCode;
|
||||
|
||||
/**
|
||||
* 流程节点名称
|
||||
*/
|
||||
private String nodeName;
|
||||
|
||||
/**
|
||||
* 流程状态
|
||||
*/
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 办理参数
|
||||
*/
|
||||
private Map<String, Object> params;
|
||||
|
||||
/**
|
||||
* 当为true时为申请人节点办理
|
||||
*/
|
||||
private boolean submit;
|
||||
private Boolean submit;
|
||||
|
||||
public ProcessEvent() {
|
||||
super(new Object(), SpringUtils.getApplicationName(), DEFAULT_DESTINATION_FACTORY.getDestination(null));
|
||||
@ -0,0 +1,76 @@
|
||||
package org.dromara.workflow.api.event;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.core.utils.SpringUtils;
|
||||
import org.springframework.cloud.bus.event.RemoteApplicationEvent;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 流程任务监听
|
||||
*
|
||||
* @author may
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class ProcessTaskEvent extends RemoteApplicationEvent {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 租户ID
|
||||
*/
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 流程定义编码
|
||||
*/
|
||||
private String flowCode;
|
||||
|
||||
/**
|
||||
* 节点类型(0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关)
|
||||
*/
|
||||
private Integer nodeType;
|
||||
|
||||
/**
|
||||
* 流程节点编码
|
||||
*/
|
||||
private String nodeCode;
|
||||
|
||||
/**
|
||||
* 流程节点名称
|
||||
*/
|
||||
private String nodeName;
|
||||
|
||||
/**
|
||||
* 任务id
|
||||
*/
|
||||
private Long taskId;
|
||||
|
||||
/**
|
||||
* 实例id
|
||||
*/
|
||||
private Long instanceId;
|
||||
|
||||
/**
|
||||
* 业务id
|
||||
*/
|
||||
private String businessId;
|
||||
|
||||
/**
|
||||
* 流程状态
|
||||
*/
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 办理参数
|
||||
*/
|
||||
private Map<String, Object> params;
|
||||
|
||||
public ProcessTaskEvent() {
|
||||
super(new Object(), SpringUtils.getApplicationName(), DEFAULT_DESTINATION_FACTORY.getDestination(null));
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
# 贝尔实验室 Spring 官方推荐镜像 JDK下载地址 https://bell-sw.com/pages/downloads/
|
||||
FROM bellsoft/liberica-openjdk-debian:17.0.11-cds
|
||||
#FROM bellsoft/liberica-openjdk-debian:21.0.3-cds
|
||||
FROM bellsoft/liberica-openjdk-rocky:17.0.16-cds
|
||||
#FROM bellsoft/liberica-openjdk-rocky:21.0.8-cds
|
||||
#FROM findepi/graalvm:java17-native
|
||||
|
||||
LABEL maintainer="Lion Li"
|
||||
@ -17,6 +17,8 @@ EXPOSE ${SERVER_PORT}
|
||||
|
||||
ADD ./target/ruoyi-auth.jar ./app.jar
|
||||
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
|
||||
ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -Dserver.port=${SERVER_PORT} \
|
||||
#-Dskywalking.agent.service_name=ruoyi-auth \
|
||||
#-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar \
|
||||
|
||||
@ -26,11 +26,6 @@
|
||||
<artifactId>hutool-captcha</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-sentinel</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- RuoYi Common Security-->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
@ -81,6 +76,12 @@
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-tenant</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-service-impl</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-api-resource</artifactId>
|
||||
|
||||
@ -1,88 +0,0 @@
|
||||
package org.dromara.auth.captcha;
|
||||
|
||||
import cn.hutool.captcha.generator.CodeGenerator;
|
||||
import cn.hutool.core.math.Calculator;
|
||||
import cn.hutool.core.util.CharUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 无符号计算生成器
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public class UnsignedMathGenerator implements CodeGenerator {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = -5514819971774091076L;
|
||||
|
||||
private static final String OPERATORS = "+-*";
|
||||
|
||||
/**
|
||||
* 参与计算数字最大长度
|
||||
*/
|
||||
private final int numberLength;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*/
|
||||
public UnsignedMathGenerator() {
|
||||
this(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param numberLength 参与计算最大数字位数
|
||||
*/
|
||||
public UnsignedMathGenerator(int numberLength) {
|
||||
this.numberLength = numberLength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generate() {
|
||||
final int limit = getLimit();
|
||||
int a = RandomUtil.randomInt(limit);
|
||||
int b = RandomUtil.randomInt(limit);
|
||||
String max = Integer.toString(Math.max(a,b));
|
||||
String min = Integer.toString(Math.min(a,b));
|
||||
max = StringUtils.rightPad(max, this.numberLength, CharUtil.SPACE);
|
||||
min = StringUtils.rightPad(min, this.numberLength, CharUtil.SPACE);
|
||||
|
||||
return max + RandomUtil.randomChar(OPERATORS) + min + '=';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verify(String code, String userInputCode) {
|
||||
int result;
|
||||
try {
|
||||
result = Integer.parseInt(userInputCode);
|
||||
} catch (NumberFormatException e) {
|
||||
// 用户输入非数字
|
||||
return false;
|
||||
}
|
||||
|
||||
final int calculateResult = (int) Calculator.conversion(code);
|
||||
return result == calculateResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取验证码长度
|
||||
*
|
||||
* @return 验证码长度
|
||||
*/
|
||||
public int getLength() {
|
||||
return this.numberLength * 2 + 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据长度获取参与计算数字最大值
|
||||
*
|
||||
* @return 最大值
|
||||
*/
|
||||
private int getLimit() {
|
||||
return Integer.parseInt("1" + StringUtils.repeat('0', this.numberLength));
|
||||
}
|
||||
}
|
||||
@ -42,7 +42,6 @@ public class CaptchaController {
|
||||
/**
|
||||
* 生成验证码
|
||||
*/
|
||||
@RateLimiter(time = 60, count = 10, limitType = LimitType.IP)
|
||||
@GetMapping("/code")
|
||||
public R<CaptchaVo> getCode() {
|
||||
CaptchaVo captchaVo = new CaptchaVo();
|
||||
@ -51,28 +50,41 @@ public class CaptchaController {
|
||||
captchaVo.setCaptchaEnabled(false);
|
||||
return R.ok(captchaVo);
|
||||
}
|
||||
return R.ok(SpringUtils.getAopProxy(this).getCodeImpl());
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成验证码
|
||||
* 独立方法避免验证码关闭之后仍然走限流
|
||||
*/
|
||||
@RateLimiter(time = 60, count = 10, limitType = LimitType.IP)
|
||||
public CaptchaVo getCodeImpl() {
|
||||
// 保存验证码信息
|
||||
String uuid = IdUtil.simpleUUID();
|
||||
String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + uuid;
|
||||
// 生成验证码
|
||||
CaptchaType captchaType = captchaProperties.getType();
|
||||
boolean isMath = CaptchaType.MATH == captchaType;
|
||||
Integer length = isMath ? captchaProperties.getNumberLength() : captchaProperties.getCharLength();
|
||||
CodeGenerator codeGenerator = ReflectUtils.newInstance(captchaType.getClazz(), length);
|
||||
CodeGenerator codeGenerator;
|
||||
if (CaptchaType.MATH == captchaType) {
|
||||
codeGenerator = ReflectUtils.newInstance(captchaType.getClazz(), captchaProperties.getNumberLength(), false);
|
||||
} else {
|
||||
codeGenerator = ReflectUtils.newInstance(captchaType.getClazz(), captchaProperties.getCharLength());
|
||||
}
|
||||
AbstractCaptcha captcha = SpringUtils.getBean(captchaProperties.getCategory().getClazz());
|
||||
captcha.setGenerator(codeGenerator);
|
||||
captcha.createCode();
|
||||
// 如果是数学验证码,使用SpEL表达式处理验证码结果
|
||||
String code = captcha.getCode();
|
||||
if (isMath) {
|
||||
if (CaptchaType.MATH == captchaType) {
|
||||
ExpressionParser parser = new SpelExpressionParser();
|
||||
Expression exp = parser.parseExpression(StringUtils.remove(code, "="));
|
||||
code = exp.getValue(String.class);
|
||||
}
|
||||
RedisUtils.setCacheObject(verifyKey, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
|
||||
CaptchaVo captchaVo = new CaptchaVo();
|
||||
captchaVo.setUuid(uuid);
|
||||
captchaVo.setImg(captcha.getImageBase64());
|
||||
return R.ok(captchaVo);
|
||||
return captchaVo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -19,12 +19,14 @@ import org.dromara.auth.form.RegisterBody;
|
||||
import org.dromara.auth.form.SocialLoginBody;
|
||||
import org.dromara.auth.service.IAuthStrategy;
|
||||
import org.dromara.auth.service.SysLoginService;
|
||||
import org.dromara.common.core.constant.UserConstants;
|
||||
import org.dromara.common.core.constant.SystemConstants;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.domain.model.LoginBody;
|
||||
import org.dromara.common.core.utils.*;
|
||||
import org.dromara.common.encrypt.annotation.ApiEncrypt;
|
||||
import org.dromara.common.json.utils.JsonUtils;
|
||||
import org.dromara.common.ratelimiter.annotation.RateLimiter;
|
||||
import org.dromara.common.ratelimiter.enums.LimitType;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.dromara.common.social.config.properties.SocialLoginConfigProperties;
|
||||
import org.dromara.common.social.config.properties.SocialProperties;
|
||||
@ -41,6 +43,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -92,7 +95,7 @@ public class TokenController {
|
||||
if (ObjectUtil.isNull(clientVo) || !StringUtils.contains(clientVo.getGrantType(), grantType)) {
|
||||
log.info("客户端id: {} 认证类型:{} 异常!.", clientId, grantType);
|
||||
return R.fail(MessageUtils.message("auth.grant.type.error"));
|
||||
} else if (!UserConstants.NORMAL.equals(clientVo.getStatus())) {
|
||||
} else if (!SystemConstants.NORMAL.equals(clientVo.getStatus())) {
|
||||
return R.fail(MessageUtils.message("auth.grant.type.blocked"));
|
||||
}
|
||||
// 校验租户
|
||||
@ -102,8 +105,8 @@ public class TokenController {
|
||||
|
||||
Long userId = LoginHelper.getUserId();
|
||||
scheduledExecutorService.schedule(() -> {
|
||||
remoteMessageService.publishMessage(userId, "欢迎登录RuoYi-Cloud-Plus微服务管理系统");
|
||||
}, 3, TimeUnit.SECONDS);
|
||||
remoteMessageService.publishMessage(List.of(userId), DateUtils.getTodayHour(new Date()) + "好,欢迎登录 RuoYi-Cloud-Plus 后台管理系统");
|
||||
}, 5, TimeUnit.SECONDS);
|
||||
return R.ok(loginVo);
|
||||
}
|
||||
|
||||
@ -190,6 +193,7 @@ public class TokenController {
|
||||
*
|
||||
* @return 租户列表
|
||||
*/
|
||||
@RateLimiter(time = 60, count = 20, limitType = LimitType.IP)
|
||||
@GetMapping("/tenant/list")
|
||||
public R<LoginTenantVo> tenantList(HttpServletRequest request) throws Exception {
|
||||
// 返回对象
|
||||
@ -223,7 +227,7 @@ public class TokenController {
|
||||
}
|
||||
// 根据域名进行筛选
|
||||
List<TenantListVo> list = StreamUtils.filter(voList, vo ->
|
||||
StringUtils.equals(vo.getDomain(), host));
|
||||
StringUtils.equalsIgnoreCase(vo.getDomain(), host));
|
||||
result.setVoList(CollUtil.isNotEmpty(list) ? list : voList);
|
||||
return R.ok(result);
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
package org.dromara.auth.enums;
|
||||
|
||||
import cn.hutool.captcha.generator.CodeGenerator;
|
||||
import cn.hutool.captcha.generator.MathGenerator;
|
||||
import cn.hutool.captcha.generator.RandomGenerator;
|
||||
import org.dromara.auth.captcha.UnsignedMathGenerator;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@ -18,7 +18,7 @@ public enum CaptchaType {
|
||||
/**
|
||||
* 数字
|
||||
*/
|
||||
MATH(UnsignedMathGenerator.class),
|
||||
MATH(MathGenerator.class),
|
||||
|
||||
/**
|
||||
* 字符
|
||||
|
||||
@ -6,8 +6,6 @@ import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.core.domain.model.LoginBody;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import static org.dromara.common.core.constant.UserConstants.*;
|
||||
|
||||
/**
|
||||
* 密码登录对象
|
||||
*
|
||||
@ -21,14 +19,15 @@ public class PasswordLoginBody extends LoginBody {
|
||||
* 用户名
|
||||
*/
|
||||
@NotBlank(message = "{user.username.not.blank}")
|
||||
@Length(min = USERNAME_MIN_LENGTH, max = USERNAME_MAX_LENGTH, message = "{user.username.length.valid}")
|
||||
@Length(min = 2, max = 30, message = "{user.username.length.valid}")
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 用户密码
|
||||
*/
|
||||
@NotBlank(message = "{user.password.not.blank}")
|
||||
@Length(min = PASSWORD_MIN_LENGTH, max = PASSWORD_MAX_LENGTH, message = "{user.password.length.valid}")
|
||||
@Length(min = 5, max = 30, message = "{user.password.length.valid}")
|
||||
// @Pattern(regexp = RegexConstants.PASSWORD, message = "{user.password.format.valid}")
|
||||
private String password;
|
||||
|
||||
}
|
||||
|
||||
@ -6,8 +6,6 @@ import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.core.domain.model.LoginBody;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import static org.dromara.common.core.constant.UserConstants.*;
|
||||
|
||||
/**
|
||||
* 用户注册对象
|
||||
*
|
||||
@ -21,14 +19,15 @@ public class RegisterBody extends LoginBody {
|
||||
* 用户名
|
||||
*/
|
||||
@NotBlank(message = "{user.username.not.blank}")
|
||||
@Length(min = USERNAME_MIN_LENGTH, max = USERNAME_MAX_LENGTH, message = "{user.username.length.valid}")
|
||||
@Length(min = 2, max = 30, message = "{user.username.length.valid}")
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 用户密码
|
||||
*/
|
||||
@NotBlank(message = "{user.password.not.blank}")
|
||||
@Length(min = PASSWORD_MIN_LENGTH, max = PASSWORD_MAX_LENGTH, message = "{user.password.length.valid}")
|
||||
@Length(min = 5, max = 30, message = "{user.password.length.valid}")
|
||||
// @Pattern(regexp = RegexConstants.PASSWORD, message = "{user.password.format.valid}")
|
||||
private String password;
|
||||
|
||||
/**
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
package org.dromara.auth.listener;
|
||||
|
||||
import cn.dev33.satoken.config.SaTokenConfig;
|
||||
import cn.dev33.satoken.listener.SaTokenListener;
|
||||
import cn.dev33.satoken.stp.SaLoginModel;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.http.useragent.UserAgent;
|
||||
import cn.hutool.http.useragent.UserAgentUtil;
|
||||
@ -37,7 +36,6 @@ import java.time.Duration;
|
||||
@Slf4j
|
||||
public class UserActionListener implements SaTokenListener {
|
||||
|
||||
private final SaTokenConfig tokenConfig;
|
||||
@DubboReference
|
||||
private RemoteUserService remoteUserService;
|
||||
@DubboReference
|
||||
@ -47,7 +45,7 @@ public class UserActionListener implements SaTokenListener {
|
||||
* 每次登录时触发
|
||||
*/
|
||||
@Override
|
||||
public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) {
|
||||
public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginParameter loginParameter) {
|
||||
UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent"));
|
||||
String ip = ServletUtils.getClientIP();
|
||||
SysUserOnline userOnline = new SysUserOnline();
|
||||
@ -57,17 +55,17 @@ public class UserActionListener implements SaTokenListener {
|
||||
userOnline.setOs(userAgent.getOs().getName());
|
||||
userOnline.setLoginTime(System.currentTimeMillis());
|
||||
userOnline.setTokenId(tokenValue);
|
||||
String username = (String) loginModel.getExtra(LoginHelper.USER_NAME_KEY);
|
||||
String tenantId = (String) loginModel.getExtra(LoginHelper.TENANT_KEY);
|
||||
String username = (String) loginParameter.getExtra(LoginHelper.USER_NAME_KEY);
|
||||
String tenantId = (String) loginParameter.getExtra(LoginHelper.TENANT_KEY);
|
||||
userOnline.setUserName(username);
|
||||
userOnline.setClientKey((String) loginModel.getExtra(LoginHelper.CLIENT_KEY));
|
||||
userOnline.setDeviceType(loginModel.getDevice());
|
||||
userOnline.setDeptName((String) loginModel.getExtra(LoginHelper.DEPT_NAME_KEY));
|
||||
userOnline.setClientKey((String) loginParameter.getExtra(LoginHelper.CLIENT_KEY));
|
||||
userOnline.setDeviceType(loginParameter.getDeviceType());
|
||||
userOnline.setDeptName((String) loginParameter.getExtra(LoginHelper.DEPT_NAME_KEY));
|
||||
TenantHelper.dynamic(tenantId, () -> {
|
||||
if (tokenConfig.getTimeout() == -1) {
|
||||
if (loginParameter.getTimeout() == -1) {
|
||||
RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, userOnline);
|
||||
} else {
|
||||
RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, userOnline, Duration.ofSeconds(tokenConfig.getTimeout()));
|
||||
RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, userOnline, Duration.ofSeconds(loginParameter.getTimeout()));
|
||||
}
|
||||
});
|
||||
// 记录登录日志
|
||||
@ -78,7 +76,7 @@ public class UserActionListener implements SaTokenListener {
|
||||
logininforEvent.setMessage(MessageUtils.message("user.login.success"));
|
||||
SpringUtils.context().publishEvent(logininforEvent);
|
||||
// 更新登录信息
|
||||
remoteUserService.recordLoginInfo((Long) loginModel.getExtra(LoginHelper.USER_KEY), ip);
|
||||
remoteUserService.recordLoginInfo((Long) loginParameter.getExtra(LoginHelper.USER_KEY), ip);
|
||||
log.info("user doLogin, useId:{}, token:{}", loginId, tokenValue);
|
||||
}
|
||||
|
||||
@ -164,7 +162,7 @@ public class UserActionListener implements SaTokenListener {
|
||||
* 每次Token续期时触发
|
||||
*/
|
||||
@Override
|
||||
public void doRenewTimeout(String tokenValue, Object loginId, long timeout) {
|
||||
public void doRenewTimeout(String loginType, Object loginId, String tokenValue, long timeout) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package org.dromara.auth.service;
|
||||
|
||||
import cn.dev33.satoken.exception.NotLoginException;
|
||||
import cn.dev33.satoken.secure.BCrypt;
|
||||
import cn.hutool.crypto.digest.BCrypt;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
@ -14,12 +14,8 @@ import org.apache.dubbo.config.annotation.DubboReference;
|
||||
import org.dromara.auth.form.RegisterBody;
|
||||
import org.dromara.auth.properties.CaptchaProperties;
|
||||
import org.dromara.auth.properties.UserPasswordProperties;
|
||||
import org.dromara.common.core.constant.CacheConstants;
|
||||
import org.dromara.common.core.constant.Constants;
|
||||
import org.dromara.common.core.constant.GlobalConstants;
|
||||
import org.dromara.common.core.constant.TenantConstants;
|
||||
import org.dromara.common.core.constant.*;
|
||||
import org.dromara.common.core.enums.LoginType;
|
||||
import org.dromara.common.core.enums.TenantStatus;
|
||||
import org.dromara.common.core.enums.UserType;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.exception.user.CaptchaException;
|
||||
@ -175,11 +171,11 @@ public class SysLoginService {
|
||||
String captcha = RedisUtils.getCacheObject(verifyKey);
|
||||
RedisUtils.deleteObject(verifyKey);
|
||||
if (captcha == null) {
|
||||
recordLogininfor(tenantId, username, Constants.REGISTER, MessageUtils.message("user.jcaptcha.expire"));
|
||||
recordLogininfor(tenantId, username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
|
||||
throw new CaptchaExpireException();
|
||||
}
|
||||
if (!code.equalsIgnoreCase(captcha)) {
|
||||
recordLogininfor(tenantId, username, Constants.REGISTER, MessageUtils.message("user.jcaptcha.error"));
|
||||
if (!StringUtils.equalsIgnoreCase(code, captcha)) {
|
||||
recordLogininfor(tenantId, username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"));
|
||||
throw new CaptchaException();
|
||||
}
|
||||
}
|
||||
@ -247,17 +243,17 @@ public class SysLoginService {
|
||||
if (!TenantHelper.isEnable()) {
|
||||
return;
|
||||
}
|
||||
if (TenantConstants.DEFAULT_TENANT_ID.equals(tenantId)) {
|
||||
return;
|
||||
}
|
||||
if (StringUtils.isBlank(tenantId)) {
|
||||
throw new TenantException("tenant.number.not.blank");
|
||||
}
|
||||
if (TenantConstants.DEFAULT_TENANT_ID.equals(tenantId)) {
|
||||
return;
|
||||
}
|
||||
RemoteTenantVo tenant = remoteTenantService.queryByTenantId(tenantId);
|
||||
if (ObjectUtil.isNull(tenant)) {
|
||||
log.info("登录租户:{} 不存在.", tenantId);
|
||||
throw new TenantException("tenant.not.exists");
|
||||
} else if (TenantStatus.DISABLE.getCode().equals(tenant.getStatus())) {
|
||||
} else if (SystemConstants.DISABLE.equals(tenant.getStatus())) {
|
||||
log.info("登录租户:{} 已被停用.", tenantId);
|
||||
throw new TenantException("tenant.blocked");
|
||||
} else if (ObjectUtil.isNotNull(tenant.getExpireTime())
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package org.dromara.auth.service.impl;
|
||||
|
||||
import cn.dev33.satoken.stp.SaLoginModel;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
@ -54,8 +54,8 @@ public class EmailAuthStrategy implements IAuthStrategy {
|
||||
});
|
||||
loginUser.setClientKey(client.getClientKey());
|
||||
loginUser.setDeviceType(client.getDeviceType());
|
||||
SaLoginModel model = new SaLoginModel();
|
||||
model.setDevice(client.getDeviceType());
|
||||
SaLoginParameter model = new SaLoginParameter();
|
||||
model.setDeviceType(client.getDeviceType());
|
||||
// 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置
|
||||
// 例如: 后台用户30分钟过期 app用户1天过期
|
||||
model.setTimeout(client.getTimeout());
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
package org.dromara.auth.service.impl;
|
||||
|
||||
import cn.dev33.satoken.secure.BCrypt;
|
||||
import cn.dev33.satoken.stp.SaLoginModel;
|
||||
import cn.hutool.crypto.digest.BCrypt;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
@ -66,8 +66,8 @@ public class PasswordAuthStrategy implements IAuthStrategy {
|
||||
});
|
||||
loginUser.setClientKey(client.getClientKey());
|
||||
loginUser.setDeviceType(client.getDeviceType());
|
||||
SaLoginModel model = new SaLoginModel();
|
||||
model.setDevice(client.getDeviceType());
|
||||
SaLoginParameter model = new SaLoginParameter();
|
||||
model.setDeviceType(client.getDeviceType());
|
||||
// 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置
|
||||
// 例如: 后台用户30分钟过期 app用户1天过期
|
||||
model.setTimeout(client.getTimeout());
|
||||
@ -98,7 +98,7 @@ public class PasswordAuthStrategy implements IAuthStrategy {
|
||||
loginService.recordLogininfor(tenantId, username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
|
||||
throw new CaptchaExpireException();
|
||||
}
|
||||
if (!code.equalsIgnoreCase(captcha)) {
|
||||
if (!StringUtils.equalsIgnoreCase(code, captcha)) {
|
||||
loginService.recordLogininfor(tenantId, username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"));
|
||||
throw new CaptchaException();
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package org.dromara.auth.service.impl;
|
||||
|
||||
import cn.dev33.satoken.stp.SaLoginModel;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
@ -54,8 +54,8 @@ public class SmsAuthStrategy implements IAuthStrategy {
|
||||
});
|
||||
loginUser.setClientKey(client.getClientKey());
|
||||
loginUser.setDeviceType(client.getDeviceType());
|
||||
SaLoginModel model = new SaLoginModel();
|
||||
model.setDevice(client.getDeviceType());
|
||||
SaLoginParameter model = new SaLoginParameter();
|
||||
model.setDeviceType(client.getDeviceType());
|
||||
// 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置
|
||||
// 例如: 后台用户30分钟过期 app用户1天过期
|
||||
model.setTimeout(client.getTimeout());
|
||||
|
||||
@ -1,11 +1,8 @@
|
||||
package org.dromara.auth.service.impl;
|
||||
|
||||
import cn.dev33.satoken.stp.SaLoginModel;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.http.Method;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.zhyd.oauth.model.AuthResponse;
|
||||
@ -66,15 +63,6 @@ public class SocialAuthStrategy implements IAuthStrategy {
|
||||
throw new ServiceException(response.getMsg());
|
||||
}
|
||||
AuthUser authUserData = response.getData();
|
||||
if ("GITEE".equals(authUserData.getSource())) {
|
||||
// 如用户使用 gitee 登录顺手 star 给作者一点支持 拒绝白嫖
|
||||
HttpUtil.createRequest(Method.PUT, "https://gitee.com/api/v5/user/starred/dromara/RuoYi-Vue-Plus")
|
||||
.formStr(MapUtil.of("access_token", authUserData.getToken().getAccessToken()))
|
||||
.executeAsync();
|
||||
HttpUtil.createRequest(Method.PUT, "https://gitee.com/api/v5/user/starred/dromara/RuoYi-Cloud-Plus")
|
||||
.formStr(MapUtil.of("access_token", authUserData.getToken().getAccessToken()))
|
||||
.executeAsync();
|
||||
}
|
||||
|
||||
List<RemoteSocialVo> list = remoteSocialService.selectByAuthId(authUserData.getSource() + authUserData.getUuid());
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
@ -94,8 +82,8 @@ public class SocialAuthStrategy implements IAuthStrategy {
|
||||
LoginUser loginUser = remoteUserService.getUserInfo(socialVo.getUserId(), socialVo.getTenantId());
|
||||
loginUser.setClientKey(client.getClientKey());
|
||||
loginUser.setDeviceType(client.getDeviceType());
|
||||
SaLoginModel model = new SaLoginModel();
|
||||
model.setDevice(client.getDeviceType());
|
||||
SaLoginParameter model = new SaLoginParameter();
|
||||
model.setDeviceType(client.getDeviceType());
|
||||
// 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置
|
||||
// 例如: 后台用户30分钟过期 app用户1天过期
|
||||
model.setTimeout(client.getTimeout());
|
||||
|
||||
@ -1,14 +1,22 @@
|
||||
package org.dromara.auth.service.impl;
|
||||
|
||||
import cn.dev33.satoken.stp.SaLoginModel;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.zhyd.oauth.config.AuthConfig;
|
||||
import me.zhyd.oauth.model.AuthCallback;
|
||||
import me.zhyd.oauth.model.AuthResponse;
|
||||
import me.zhyd.oauth.model.AuthToken;
|
||||
import me.zhyd.oauth.model.AuthUser;
|
||||
import me.zhyd.oauth.request.AuthRequest;
|
||||
import me.zhyd.oauth.request.AuthWechatMiniProgramRequest;
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
import org.dromara.auth.domain.vo.LoginVo;
|
||||
import org.dromara.auth.form.XcxLoginBody;
|
||||
import org.dromara.auth.service.IAuthStrategy;
|
||||
import org.dromara.auth.service.SysLoginService;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.ValidatorUtils;
|
||||
import org.dromara.common.json.utils.JsonUtils;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
@ -41,15 +49,29 @@ public class XcxAuthStrategy implements IAuthStrategy {
|
||||
// 多个小程序识别使用
|
||||
String appid = loginBody.getAppid();
|
||||
|
||||
// todo 以下自行实现
|
||||
// 校验 appid + appsrcret + xcxCode 调用登录凭证校验接口 获取 session_key 与 openid
|
||||
String openid = "";
|
||||
AuthRequest authRequest = new AuthWechatMiniProgramRequest(AuthConfig.builder()
|
||||
.clientId(appid).clientSecret("自行填写密钥 可根据不同appid填入不同密钥")
|
||||
.ignoreCheckRedirectUri(true).ignoreCheckState(true).build());
|
||||
AuthCallback authCallback = new AuthCallback();
|
||||
authCallback.setCode(xcxCode);
|
||||
AuthResponse<AuthUser> resp = authRequest.login(authCallback);
|
||||
String openid, unionId;
|
||||
if (resp.ok()) {
|
||||
AuthToken token = resp.getData().getToken();
|
||||
openid = token.getOpenId();
|
||||
// 微信小程序只有关联到微信开放平台下之后才能获取到 unionId,因此unionId不一定能返回。
|
||||
unionId = token.getUnionId();
|
||||
} else {
|
||||
throw new ServiceException(resp.getMsg());
|
||||
}
|
||||
// todo getUserInfoByOpenid 方法内部查询逻辑需要自行根据业务实现
|
||||
XcxLoginUser loginUser = remoteUserService.getUserInfoByOpenid(openid);
|
||||
loginUser.setClientKey(client.getClientKey());
|
||||
loginUser.setDeviceType(client.getDeviceType());
|
||||
|
||||
SaLoginModel model = new SaLoginModel();
|
||||
model.setDevice(client.getDeviceType());
|
||||
SaLoginParameter model = new SaLoginParameter();
|
||||
model.setDeviceType(client.getDeviceType());
|
||||
// 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置
|
||||
// 例如: 后台用户30分钟过期 app用户1天过期
|
||||
model.setTimeout(client.getTimeout());
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<property name="log.path" value="logs/${project.artifactId}"/>
|
||||
<!-- 日志输出格式 -->
|
||||
<property name="console.log.pattern"
|
||||
value="%red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}%n) - %msg%n"/>
|
||||
value="%cyan(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}%n) - %msg%n"/>
|
||||
|
||||
<!-- 控制台输出 -->
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
<module>ruoyi-common-bom</module>
|
||||
<module>ruoyi-common-alibaba-bom</module>
|
||||
<module>ruoyi-common-log</module>
|
||||
<module>ruoyi-common-dict</module>
|
||||
<module>ruoyi-common-service-impl</module>
|
||||
<module>ruoyi-common-excel</module>
|
||||
<module>ruoyi-common-core</module>
|
||||
<module>ruoyi-common-redis</module>
|
||||
@ -32,7 +32,6 @@
|
||||
<module>ruoyi-common-sms</module>
|
||||
<module>ruoyi-common-logstash</module>
|
||||
<module>ruoyi-common-elasticsearch</module>
|
||||
<module>ruoyi-common-sentinel</module>
|
||||
<module>ruoyi-common-skylog</module>
|
||||
<module>ruoyi-common-prometheus</module>
|
||||
<module>ruoyi-common-translation</module>
|
||||
|
||||
@ -14,13 +14,12 @@
|
||||
</description>
|
||||
|
||||
<properties>
|
||||
<revision>2.2.1</revision>
|
||||
<spring-cloud-alibaba.version>2023.0.1.2</spring-cloud-alibaba.version>
|
||||
<sentinel.version>1.8.8</sentinel.version>
|
||||
<seata.version>1.7.1</seata.version>
|
||||
<nacos.client.version>2.3.3</nacos.client.version>
|
||||
<dubbo.version>3.2.14</dubbo.version>
|
||||
<spring.context.support.version>1.0.11</spring.context.support.version>
|
||||
<revision>2.5.2</revision>
|
||||
<spring-cloud-alibaba.version>2025.0.0.0</spring-cloud-alibaba.version>
|
||||
<seata.version>2.5.0</seata.version>
|
||||
<nacos.client.version>2.5.1</nacos.client.version>
|
||||
<dubbo.version>3.3.6</dubbo.version>
|
||||
<dubbo-extensions.version>3.3.1</dubbo-extensions.version>
|
||||
</properties>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
@ -35,117 +34,31 @@
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-client</artifactId>
|
||||
<version>${nacos.client.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-log4j2-adapter</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-logback-adapter-12</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>logback-adapter</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-core</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-parameter-flow-control</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-datasource-extension</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-datasource-apollo</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-datasource-zookeeper</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-datasource-nacos</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-datasource-redis</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-datasource-consul</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-web-servlet</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-transport-simple-http</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-annotation-aspectj</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-reactor-adapter</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-cluster-server-default</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-cluster-client-default</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-spring-webflux-adapter</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-api-gateway-adapter-common</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-spring-webmvc-v6x-adapter</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-dubbo-adapter</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-apache-dubbo-adapter</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-apache-dubbo3-adapter</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.seata</groupId>
|
||||
<groupId>org.apache.seata</groupId>
|
||||
<artifactId>seata-spring-boot-starter</artifactId>
|
||||
<version>${seata.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.seata</groupId>
|
||||
<artifactId>seata-all</artifactId>
|
||||
<version>${seata.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Apache Dubbo 配置 -->
|
||||
<dependency>
|
||||
@ -167,15 +80,9 @@
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<groupId>org.apache.dubbo.extensions</groupId>
|
||||
<artifactId>dubbo-metadata-report-redis</artifactId>
|
||||
<version>${dubbo.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.spring</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
<version>${spring.context.support.version}</version>
|
||||
<version>${dubbo-extensions.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
</description>
|
||||
|
||||
<properties>
|
||||
<revision>2.2.1</revision>
|
||||
<revision>2.5.2</revision>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
@ -54,10 +54,10 @@
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 字典 -->
|
||||
<!-- 通用service实现模块 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-dict</artifactId>
|
||||
<artifactId>ruoyi-common-service-impl</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
@ -166,13 +166,6 @@
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 限流模块 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-sentinel</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- skywalking日志收集模块 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
|
||||
@ -1,52 +0,0 @@
|
||||
package org.dromara.common.core.config;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.SpringUtils;
|
||||
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.core.task.VirtualThreadTaskExecutor;
|
||||
import org.springframework.scheduling.annotation.AsyncConfigurer;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* 异步配置
|
||||
* <p>
|
||||
* 如果未使用虚拟线程则生效
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@AutoConfiguration
|
||||
public class AsyncConfig implements AsyncConfigurer {
|
||||
|
||||
/**
|
||||
* 自定义 @Async 注解使用系统线程池
|
||||
*/
|
||||
@Override
|
||||
public Executor getAsyncExecutor() {
|
||||
if(SpringUtils.isVirtual()) {
|
||||
return new VirtualThreadTaskExecutor("async-");
|
||||
}
|
||||
return SpringUtils.getBean("scheduledExecutorService");
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步执行异常处理
|
||||
*/
|
||||
@Override
|
||||
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
|
||||
return (throwable, method, objects) -> {
|
||||
throwable.printStackTrace();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Exception message - ").append(throwable.getMessage())
|
||||
.append(", Method name - ").append(method.getName());
|
||||
if (ArrayUtil.isNotEmpty(objects)) {
|
||||
sb.append(", Parameter value - ").append(Arrays.toString(objects));
|
||||
}
|
||||
throw new ServiceException(sb.toString());
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@ -3,13 +3,12 @@ package org.dromara.common.core.config;
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
|
||||
import org.dromara.common.core.utils.Threads;
|
||||
import org.dromara.common.core.utils.SpringUtils;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.task.VirtualThreadTaskExecutor;
|
||||
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
/**
|
||||
* 线程池配置
|
||||
@ -32,13 +31,20 @@ public class ThreadPoolConfig {
|
||||
*/
|
||||
@Bean(name = "scheduledExecutorService")
|
||||
protected ScheduledExecutorService scheduledExecutorService() {
|
||||
// daemon 必须为 true
|
||||
BasicThreadFactory.Builder builder = new BasicThreadFactory.Builder().daemon(true);
|
||||
if (SpringUtils.isVirtual()) {
|
||||
builder.namingPattern("virtual-schedule-pool-%d").wrappedFactory(new VirtualThreadTaskExecutor().getVirtualThreadFactory());
|
||||
} else {
|
||||
builder.namingPattern("schedule-pool-%d");
|
||||
}
|
||||
ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(core,
|
||||
new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build(),
|
||||
builder.build(),
|
||||
new ThreadPoolExecutor.CallerRunsPolicy()) {
|
||||
@Override
|
||||
protected void afterExecute(Runnable r, Throwable t) {
|
||||
super.afterExecute(r, t);
|
||||
Threads.printException(r, t);
|
||||
printException(r, t);
|
||||
}
|
||||
};
|
||||
this.scheduledExecutorService = scheduledThreadPoolExecutor;
|
||||
@ -47,15 +53,57 @@ public class ThreadPoolConfig {
|
||||
|
||||
/**
|
||||
* 销毁事件
|
||||
* 停止线程池
|
||||
* 先使用shutdown, 停止接收新任务并尝试完成所有已存在任务.
|
||||
* 如果超时, 则调用shutdownNow, 取消在workQueue中Pending的任务,并中断所有阻塞函数.
|
||||
* 如果仍然超時,則強制退出.
|
||||
* 另对在shutdown时线程本身被调用中断做了处理.
|
||||
*/
|
||||
@PreDestroy
|
||||
public void destroy() {
|
||||
try {
|
||||
log.info("====关闭后台任务任务线程池====");
|
||||
Threads.shutdownAndAwaitTermination(scheduledExecutorService);
|
||||
ScheduledExecutorService pool = scheduledExecutorService;
|
||||
if (pool != null && !pool.isShutdown()) {
|
||||
pool.shutdown();
|
||||
try {
|
||||
if (!pool.awaitTermination(120, TimeUnit.SECONDS)) {
|
||||
pool.shutdownNow();
|
||||
if (!pool.awaitTermination(120, TimeUnit.SECONDS)) {
|
||||
log.info("Pool did not terminate");
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException ie) {
|
||||
pool.shutdownNow();
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印线程异常信息
|
||||
*/
|
||||
public static void printException(Runnable r, Throwable t) {
|
||||
if (t == null && r instanceof Future<?>) {
|
||||
try {
|
||||
Future<?> future = (Future<?>) r;
|
||||
if (future.isDone()) {
|
||||
future.get();
|
||||
}
|
||||
} catch (CancellationException ce) {
|
||||
t = ce;
|
||||
} catch (ExecutionException ee) {
|
||||
t = ee.getCause();
|
||||
} catch (InterruptedException ie) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
if (t != null) {
|
||||
log.error(t.getMessage(), t);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package org.dromara.common.core.config;
|
||||
import jakarta.validation.Validator;
|
||||
import org.hibernate.validator.HibernateValidator;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||
@ -14,11 +15,11 @@ import java.util.Properties;
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@AutoConfiguration(before = ValidationAutoConfiguration.class)
|
||||
public class ValidatorConfig {
|
||||
|
||||
/**
|
||||
* 配置校验框架 快速返回模式
|
||||
* 配置校验框架 快速失败模式
|
||||
*/
|
||||
@Bean
|
||||
public Validator validator(MessageSource messageSource) {
|
||||
@ -28,7 +29,7 @@ public class ValidatorConfig {
|
||||
// 设置使用 HibernateValidator 校验器
|
||||
factoryBean.setProviderClass(HibernateValidator.class);
|
||||
Properties properties = new Properties();
|
||||
// 设置 快速异常返回
|
||||
// 设置快速失败模式(fail-fast),即校验过程中一旦遇到失败,立即停止并返回错误
|
||||
properties.setProperty("hibernate.validator.fail_fast", "true");
|
||||
factoryBean.setValidationProperties(properties);
|
||||
// 加载配置
|
||||
|
||||
@ -3,13 +3,14 @@ package org.dromara.common.core.constant;
|
||||
/**
|
||||
* 缓存组名称常量
|
||||
* <p>
|
||||
* key 格式为 cacheNames#ttl#maxIdleTime#maxSize
|
||||
* key 格式为 cacheNames#ttl#maxIdleTime#maxSize#local
|
||||
* <p>
|
||||
* ttl 过期时间 如果设置为0则不过期 默认为0
|
||||
* maxIdleTime 最大空闲时间 根据LRU算法清理空闲数据 如果设置为0则不检测 默认为0
|
||||
* maxSize 组最大长度 根据LRU算法清理溢出数据 如果设置为0则无限长 默认为0
|
||||
* local 默认开启本地缓存为1 关闭本地缓存为0
|
||||
* <p>
|
||||
* 例子: test#60s、test#0#60s、test#0#1m#1000、test#1h#0#500
|
||||
* 例子: test#60s、test#0#60s、test#0#1m#1000、test#1h#0#500、test#1h#0#500#0
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@ -30,6 +31,11 @@ public interface CacheNames {
|
||||
*/
|
||||
String SYS_DICT = "sys_dict";
|
||||
|
||||
/**
|
||||
* 数据字典类型
|
||||
*/
|
||||
String SYS_DICT_TYPE = "sys_dict_type";
|
||||
|
||||
/**
|
||||
* 租户
|
||||
*/
|
||||
@ -60,6 +66,16 @@ public interface CacheNames {
|
||||
*/
|
||||
String SYS_OSS = "sys_oss#30d";
|
||||
|
||||
/**
|
||||
* 角色自定义权限
|
||||
*/
|
||||
String SYS_ROLE_CUSTOM = "sys_role_custom#30d";
|
||||
|
||||
/**
|
||||
* 部门及以下权限
|
||||
*/
|
||||
String SYS_DEPT_AND_CHILD = "sys_dept_and_child#30d";
|
||||
|
||||
/**
|
||||
* OSS配置
|
||||
*/
|
||||
|
||||
@ -67,15 +67,15 @@ public interface Constants {
|
||||
*/
|
||||
Integer CAPTCHA_EXPIRATION = 2;
|
||||
|
||||
/**
|
||||
* 令牌
|
||||
*/
|
||||
String TOKEN = "token";
|
||||
|
||||
/**
|
||||
* 顶级部门id
|
||||
*/
|
||||
Long TOP_PARENT_ID = 0L;
|
||||
|
||||
/**
|
||||
* 加密头
|
||||
*/
|
||||
String ENCRYPT_HEADER = "ENC_";
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -17,9 +17,14 @@ public interface RegexConstants extends RegexPool {
|
||||
String DICTIONARY_TYPE = "^[a-z][a-z0-9_]*$";
|
||||
|
||||
/**
|
||||
* 权限标识必须符合 tool:build:list 格式,或者空字符串
|
||||
* 权限标识必须符合以下格式:
|
||||
* 1. 标准格式:xxx:yyy:zzz
|
||||
* - 第一部分(xxx):只能包含字母、数字和下划线(_),不能使用 `*`
|
||||
* - 第二部分(yyy):可以包含字母、数字、下划线(_)和 `*`
|
||||
* - 第三部分(zzz):可以包含字母、数字、下划线(_)和 `*`
|
||||
* 2. 允许空字符串(""),表示没有权限标识
|
||||
*/
|
||||
String PERMISSION_STRING = "^(|^[a-zA-Z0-9_]+:[a-zA-Z0-9_]+:[a-zA-Z0-9_]+)$";
|
||||
String PERMISSION_STRING = "^$|^[a-zA-Z0-9_]+:[a-zA-Z0-9_*]+:[a-zA-Z0-9_*]+$";
|
||||
|
||||
/**
|
||||
* 身份证号码(后6位)
|
||||
|
||||
@ -0,0 +1,80 @@
|
||||
package org.dromara.common.core.constant;
|
||||
|
||||
/**
|
||||
* 用户常量信息
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface SystemConstants {
|
||||
|
||||
/**
|
||||
* 正常状态
|
||||
*/
|
||||
String NORMAL = "0";
|
||||
|
||||
/**
|
||||
* 异常状态
|
||||
*/
|
||||
String DISABLE = "1";
|
||||
|
||||
/**
|
||||
* 是否为系统默认(是)
|
||||
*/
|
||||
String YES = "Y";
|
||||
|
||||
/**
|
||||
* 是否菜单外链(是)
|
||||
*/
|
||||
String YES_FRAME = "0";
|
||||
|
||||
/**
|
||||
* 是否菜单外链(否)
|
||||
*/
|
||||
String NO_FRAME = "1";
|
||||
|
||||
/**
|
||||
* 菜单类型(目录)
|
||||
*/
|
||||
String TYPE_DIR = "M";
|
||||
|
||||
/**
|
||||
* 菜单类型(菜单)
|
||||
*/
|
||||
String TYPE_MENU = "C";
|
||||
|
||||
/**
|
||||
* 菜单类型(按钮)
|
||||
*/
|
||||
String TYPE_BUTTON = "F";
|
||||
|
||||
/**
|
||||
* Layout组件标识
|
||||
*/
|
||||
String LAYOUT = "Layout";
|
||||
|
||||
/**
|
||||
* ParentView组件标识
|
||||
*/
|
||||
String PARENT_VIEW = "ParentView";
|
||||
|
||||
/**
|
||||
* InnerLink组件标识
|
||||
*/
|
||||
String INNER_LINK = "InnerLink";
|
||||
|
||||
/**
|
||||
* 超级管理员ID
|
||||
*/
|
||||
Long SUPER_ADMIN_ID = 1L;
|
||||
|
||||
/**
|
||||
* 根部门祖级列表
|
||||
*/
|
||||
String ROOT_DEPT_ANCESTORS = "0";
|
||||
|
||||
/**
|
||||
* 排除敏感属性字段
|
||||
*/
|
||||
String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" };
|
||||
|
||||
}
|
||||
@ -7,16 +7,6 @@ package org.dromara.common.core.constant;
|
||||
*/
|
||||
public interface TenantConstants {
|
||||
|
||||
/**
|
||||
* 租户正常状态
|
||||
*/
|
||||
String NORMAL = "0";
|
||||
|
||||
/**
|
||||
* 租户封禁状态
|
||||
*/
|
||||
String DISABLE = "1";
|
||||
|
||||
/**
|
||||
* 超级管理员ID
|
||||
*/
|
||||
|
||||
@ -1,152 +0,0 @@
|
||||
package org.dromara.common.core.constant;
|
||||
|
||||
/**
|
||||
* 用户常量信息
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public interface UserConstants {
|
||||
|
||||
/**
|
||||
* 平台内系统用户的唯一标志
|
||||
*/
|
||||
String SYS_USER = "SYS_USER";
|
||||
|
||||
/**
|
||||
* 正常状态
|
||||
*/
|
||||
String NORMAL = "0";
|
||||
|
||||
/**
|
||||
* 异常状态
|
||||
*/
|
||||
String EXCEPTION = "1";
|
||||
|
||||
/**
|
||||
* 用户正常状态
|
||||
*/
|
||||
String USER_NORMAL = "0";
|
||||
|
||||
/**
|
||||
* 用户封禁状态
|
||||
*/
|
||||
String USER_DISABLE = "1";
|
||||
|
||||
/**
|
||||
* 角色正常状态
|
||||
*/
|
||||
String ROLE_NORMAL = "0";
|
||||
|
||||
/**
|
||||
* 角色封禁状态
|
||||
*/
|
||||
String ROLE_DISABLE = "1";
|
||||
|
||||
/**
|
||||
* 部门正常状态
|
||||
*/
|
||||
String DEPT_NORMAL = "0";
|
||||
|
||||
/**
|
||||
* 部门停用状态
|
||||
*/
|
||||
String DEPT_DISABLE = "1";
|
||||
|
||||
/**
|
||||
* 岗位正常状态
|
||||
*/
|
||||
String POST_NORMAL = "0";
|
||||
|
||||
/**
|
||||
* 岗位停用状态
|
||||
*/
|
||||
String POST_DISABLE = "1";
|
||||
|
||||
/**
|
||||
* 字典正常状态
|
||||
*/
|
||||
String DICT_NORMAL = "0";
|
||||
|
||||
/**
|
||||
* 通用存在标志
|
||||
*/
|
||||
String DEL_FLAG_NORMAL = "0";
|
||||
|
||||
/**
|
||||
* 通用删除标志
|
||||
*/
|
||||
String DEL_FLAG_REMOVED = "2";
|
||||
|
||||
/**
|
||||
* 是否为系统默认(是)
|
||||
*/
|
||||
String YES = "Y";
|
||||
|
||||
/**
|
||||
* 是否菜单外链(是)
|
||||
*/
|
||||
String YES_FRAME = "0";
|
||||
|
||||
/**
|
||||
* 是否菜单外链(否)
|
||||
*/
|
||||
String NO_FRAME = "1";
|
||||
|
||||
/**
|
||||
* 菜单正常状态
|
||||
*/
|
||||
String MENU_NORMAL = "0";
|
||||
|
||||
/**
|
||||
* 菜单停用状态
|
||||
*/
|
||||
String MENU_DISABLE = "1";
|
||||
|
||||
/**
|
||||
* 菜单类型(目录)
|
||||
*/
|
||||
String TYPE_DIR = "M";
|
||||
|
||||
/**
|
||||
* 菜单类型(菜单)
|
||||
*/
|
||||
String TYPE_MENU = "C";
|
||||
|
||||
/**
|
||||
* 菜单类型(按钮)
|
||||
*/
|
||||
String TYPE_BUTTON = "F";
|
||||
|
||||
/**
|
||||
* Layout组件标识
|
||||
*/
|
||||
String LAYOUT = "Layout";
|
||||
|
||||
/**
|
||||
* ParentView组件标识
|
||||
*/
|
||||
String PARENT_VIEW = "ParentView";
|
||||
|
||||
/**
|
||||
* InnerLink组件标识
|
||||
*/
|
||||
String INNER_LINK = "InnerLink";
|
||||
|
||||
/**
|
||||
* 用户名长度限制
|
||||
*/
|
||||
int USERNAME_MIN_LENGTH = 2;
|
||||
int USERNAME_MAX_LENGTH = 20;
|
||||
|
||||
/**
|
||||
* 密码长度限制
|
||||
*/
|
||||
int PASSWORD_MIN_LENGTH = 5;
|
||||
int PASSWORD_MAX_LENGTH = 20;
|
||||
|
||||
/**
|
||||
* 超级管理员ID
|
||||
*/
|
||||
Long SUPER_ADMIN_ID = 1L;
|
||||
|
||||
}
|
||||
@ -7,6 +7,10 @@ import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 业务状态枚举
|
||||
@ -16,30 +20,37 @@ import java.util.Arrays;
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum BusinessStatusEnum {
|
||||
|
||||
/**
|
||||
* 已撤销
|
||||
*/
|
||||
CANCEL("cancel", "已撤销"),
|
||||
|
||||
/**
|
||||
* 草稿
|
||||
*/
|
||||
DRAFT("draft", "草稿"),
|
||||
|
||||
/**
|
||||
* 待审核
|
||||
*/
|
||||
WAITING("waiting", "待审核"),
|
||||
|
||||
/**
|
||||
* 已完成
|
||||
*/
|
||||
FINISH("finish", "已完成"),
|
||||
|
||||
/**
|
||||
* 已作废
|
||||
*/
|
||||
INVALID("invalid", "已作废"),
|
||||
|
||||
/**
|
||||
* 已退回
|
||||
*/
|
||||
BACK("back", "已退回"),
|
||||
|
||||
/**
|
||||
* 已终止
|
||||
*/
|
||||
@ -55,20 +66,72 @@ public enum BusinessStatusEnum {
|
||||
*/
|
||||
private final String desc;
|
||||
|
||||
private static final Map<String, BusinessStatusEnum> STATUS_MAP = Arrays.stream(BusinessStatusEnum.values())
|
||||
.collect(Collectors.toConcurrentMap(BusinessStatusEnum::getStatus, Function.identity()));
|
||||
|
||||
/**
|
||||
* 获取业务状态
|
||||
* 根据状态获取对应的 BusinessStatusEnum 枚举
|
||||
*
|
||||
* @param status 状态
|
||||
* @param status 业务状态码
|
||||
* @return 对应的 BusinessStatusEnum 枚举,如果找不到则返回 null
|
||||
*/
|
||||
public static BusinessStatusEnum getByStatus(String status) {
|
||||
// 使用 STATUS_MAP 获取对应的枚举,若找不到则返回 null
|
||||
return STATUS_MAP.get(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据状态获取对应的业务状态描述信息
|
||||
*
|
||||
* @param status 业务状态码
|
||||
* @return 返回业务状态描述,若状态码为空或未找到对应的枚举,返回空字符串
|
||||
*/
|
||||
public static String findByStatus(String status) {
|
||||
if (StringUtils.isBlank(status)) {
|
||||
return StrUtil.EMPTY;
|
||||
}
|
||||
return Arrays.stream(BusinessStatusEnum.values())
|
||||
.filter(statusEnum -> statusEnum.getStatus().equals(status))
|
||||
.findFirst()
|
||||
.map(BusinessStatusEnum::getDesc)
|
||||
.orElse(StrUtil.EMPTY);
|
||||
BusinessStatusEnum statusEnum = STATUS_MAP.get(status);
|
||||
return (statusEnum != null) ? statusEnum.getDesc() : StrUtil.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为指定的状态之一:草稿、已撤销或已退回
|
||||
*
|
||||
* @param status 要检查的状态
|
||||
* @return 如果状态为草稿、已撤销或已退回之一,则返回 true;否则返回 false
|
||||
*/
|
||||
public static boolean isDraftOrCancelOrBack(String status) {
|
||||
return DRAFT.status.equals(status) || CANCEL.status.equals(status) || BACK.status.equals(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为撤销,退回,作废,终止
|
||||
*
|
||||
* @param status status
|
||||
* @return 结果
|
||||
*/
|
||||
public static boolean initialState(String status) {
|
||||
return CANCEL.status.equals(status) || BACK.status.equals(status) || INVALID.status.equals(status) || TERMINATION.status.equals(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取运行中的实例状态列表
|
||||
*
|
||||
* @return 包含运行中实例状态的不可变列表
|
||||
* (包含 DRAFT、WAITING、BACK 和 CANCEL 状态)
|
||||
*/
|
||||
public static List<String> runningStatus() {
|
||||
return Arrays.asList(DRAFT.status, WAITING.status, BACK.status, CANCEL.status);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取结束实例的状态列表
|
||||
*
|
||||
* @return 包含结束实例状态的不可变列表
|
||||
* (包含 FINISH、INVALID 和 TERMINATION 状态)
|
||||
*/
|
||||
public static List<String> finishStatus() {
|
||||
return Arrays.asList(FINISH.status, INVALID.status, TERMINATION.status);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -148,5 +211,5 @@ public enum BusinessStatusEnum {
|
||||
throw new ServiceException("流程状态为空!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -5,7 +5,6 @@ import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 设备类型
|
||||
* 针对一套 用户体系
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@ -26,7 +25,15 @@ public enum DeviceType {
|
||||
/**
|
||||
* 小程序端
|
||||
*/
|
||||
XCX("xcx");
|
||||
XCX("xcx"),
|
||||
|
||||
/**
|
||||
* 第三方社交登录平台
|
||||
*/
|
||||
SOCIAL("social");
|
||||
|
||||
/**
|
||||
* 设备标识
|
||||
*/
|
||||
private final String device;
|
||||
}
|
||||
|
||||
@ -0,0 +1,146 @@
|
||||
package org.dromara.common.core.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
|
||||
/*
|
||||
* 日期格式
|
||||
* "yyyy":4位数的年份,例如:2023年表示为"2023"。
|
||||
* "yy":2位数的年份,例如:2023年表示为"23"。
|
||||
* "MM":2位数的月份,取值范围为01到12,例如:7月表示为"07"。
|
||||
* "M":不带前导零的月份,取值范围为1到12,例如:7月表示为"7"。
|
||||
* "dd":2位数的日期,取值范围为01到31,例如:22日表示为"22"。
|
||||
* "d":不带前导零的日期,取值范围为1到31,例如:22日表示为"22"。
|
||||
* "EEEE":星期的全名,例如:星期三表示为"Wednesday"。
|
||||
* "E":星期的缩写,例如:星期三表示为"Wed"。
|
||||
* "DDD" 或 "D":一年中的第几天,取值范围为001到366,例如:第200天表示为"200"。
|
||||
* 时间格式
|
||||
* "HH":24小时制的小时数,取值范围为00到23,例如:下午5点表示为"17"。
|
||||
* "hh":12小时制的小时数,取值范围为01到12,例如:下午5点表示为"05"。
|
||||
* "mm":分钟数,取值范围为00到59,例如:30分钟表示为"30"。
|
||||
* "ss":秒数,取值范围为00到59,例如:45秒表示为"45"。
|
||||
* "SSS":毫秒数,取值范围为000到999,例如:123毫秒表示为"123"。
|
||||
*/
|
||||
|
||||
/**
|
||||
* 日期格式与时间格式枚举
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum FormatsType {
|
||||
|
||||
/**
|
||||
* 例如:2023年表示为"23"
|
||||
*/
|
||||
YY("yy"),
|
||||
|
||||
/**
|
||||
* 例如:2023年表示为"2023"
|
||||
*/
|
||||
YYYY("yyyy"),
|
||||
|
||||
/**
|
||||
* 例例如,2023年7月可以表示为 "2023-07"
|
||||
*/
|
||||
YYYY_MM("yyyy-MM"),
|
||||
|
||||
/**
|
||||
* 例如,日期 "2023年7月22日" 可以表示为 "2023-07-22"
|
||||
*/
|
||||
YYYY_MM_DD("yyyy-MM-dd"),
|
||||
|
||||
/**
|
||||
* 例如,当前时间如果是 "2023年7月22日下午3点30分",则可以表示为 "2023-07-22 15:30"
|
||||
*/
|
||||
YYYY_MM_DD_HH_MM("yyyy-MM-dd HH:mm"),
|
||||
|
||||
/**
|
||||
* 例如,当前时间如果是 "2023年7月22日下午3点30分45秒",则可以表示为 "2023-07-22 15:30:45"
|
||||
*/
|
||||
YYYY_MM_DD_HH_MM_SS("yyyy-MM-dd HH:mm:ss"),
|
||||
|
||||
/**
|
||||
* 例如:下午3点30分45秒,表示为 "15:30:45"
|
||||
*/
|
||||
HH_MM_SS("HH:mm:ss"),
|
||||
|
||||
/**
|
||||
* 例例如,2023年7月可以表示为 "2023/07"
|
||||
*/
|
||||
YYYY_MM_SLASH("yyyy/MM"),
|
||||
|
||||
/**
|
||||
* 例如,日期 "2023年7月22日" 可以表示为 "2023/07/22"
|
||||
*/
|
||||
YYYY_MM_DD_SLASH("yyyy/MM/dd"),
|
||||
|
||||
/**
|
||||
* 例如,当前时间如果是 "2023年7月22日下午3点30分45秒",则可以表示为 "2023/07/22 15:30:45"
|
||||
*/
|
||||
YYYY_MM_DD_HH_MM_SLASH("yyyy/MM/dd HH:mm"),
|
||||
|
||||
/**
|
||||
* 例如,当前时间如果是 "2023年7月22日下午3点30分45秒",则可以表示为 "2023/07/22 15:30:45"
|
||||
*/
|
||||
YYYY_MM_DD_HH_MM_SS_SLASH("yyyy/MM/dd HH:mm:ss"),
|
||||
|
||||
/**
|
||||
* 例例如,2023年7月可以表示为 "2023.07"
|
||||
*/
|
||||
YYYY_MM_DOT("yyyy.MM"),
|
||||
|
||||
/**
|
||||
* 例如,日期 "2023年7月22日" 可以表示为 "2023.07.22"
|
||||
*/
|
||||
YYYY_MM_DD_DOT("yyyy.MM.dd"),
|
||||
|
||||
/**
|
||||
* 例如,当前时间如果是 "2023年7月22日下午3点30分",则可以表示为 "2023.07.22 15:30"
|
||||
*/
|
||||
YYYY_MM_DD_HH_MM_DOT("yyyy.MM.dd HH:mm"),
|
||||
|
||||
/**
|
||||
* 例如,当前时间如果是 "2023年7月22日下午3点30分45秒",则可以表示为 "2023.07.22 15:30:45"
|
||||
*/
|
||||
YYYY_MM_DD_HH_MM_SS_DOT("yyyy.MM.dd HH:mm:ss"),
|
||||
|
||||
/**
|
||||
* 例如,2023年7月可以表示为 "202307"
|
||||
*/
|
||||
YYYYMM("yyyyMM"),
|
||||
|
||||
/**
|
||||
* 例如,2023年7月22日可以表示为 "20230722"
|
||||
*/
|
||||
YYYYMMDD("yyyyMMdd"),
|
||||
|
||||
/**
|
||||
* 例如,2023年7月22日下午3点可以表示为 "2023072215"
|
||||
*/
|
||||
YYYYMMDDHH("yyyyMMddHH"),
|
||||
|
||||
/**
|
||||
* 例如,2023年7月22日下午3点30分可以表示为 "202307221530"
|
||||
*/
|
||||
YYYYMMDDHHMM("yyyyMMddHHmm"),
|
||||
|
||||
/**
|
||||
* 例如,2023年7月22日下午3点30分45秒可以表示为 "20230722153045"
|
||||
*/
|
||||
YYYYMMDDHHMMSS("yyyyMMddHHmmss");
|
||||
|
||||
/**
|
||||
* 时间格式
|
||||
*/
|
||||
private final String timeFormat;
|
||||
|
||||
public static FormatsType getFormatsType(String str) {
|
||||
for (FormatsType value : values()) {
|
||||
if (StringUtils.contains(str, value.getTimeFormat())) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("'FormatsType' not found By " + str);
|
||||
}
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
package org.dromara.common.core.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 用户状态
|
||||
*
|
||||
* @author LionLi
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum TenantStatus {
|
||||
/**
|
||||
* 正常
|
||||
*/
|
||||
OK("0", "正常"),
|
||||
/**
|
||||
* 停用
|
||||
*/
|
||||
DISABLE("1", "停用"),
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
DELETED("2", "删除");
|
||||
|
||||
private final String code;
|
||||
private final String info;
|
||||
|
||||
}
|
||||
@ -1,12 +1,11 @@
|
||||
package org.dromara.common.core.enums;
|
||||
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 设备类型
|
||||
* 针对多套 用户体系
|
||||
* 用户类型
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@ -15,15 +14,18 @@ import lombok.Getter;
|
||||
public enum UserType {
|
||||
|
||||
/**
|
||||
* pc端
|
||||
* 后台系统用户
|
||||
*/
|
||||
SYS_USER("sys_user"),
|
||||
|
||||
/**
|
||||
* app端
|
||||
* 移动客户端用户
|
||||
*/
|
||||
APP_USER("app_user");
|
||||
|
||||
/**
|
||||
* 用户类型标识(用于 token、权限识别等)
|
||||
*/
|
||||
private final String userType;
|
||||
|
||||
public static UserType getUserType(String str) {
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package org.dromara.common.core.exception;
|
||||
|
||||
import cn.hutool.core.text.StrFormatter;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@ -8,7 +9,7 @@ import lombok.NoArgsConstructor;
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 业务异常
|
||||
* 业务异常(支持占位符 {} )
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@ -45,8 +46,8 @@ public final class ServiceException extends RuntimeException {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getDetailMessage() {
|
||||
return detailMessage;
|
||||
public ServiceException(String message, Object... args) {
|
||||
this.message = StrFormatter.format(message, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -54,10 +55,6 @@ public final class ServiceException extends RuntimeException {
|
||||
return message;
|
||||
}
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public ServiceException setMessage(String message) {
|
||||
this.message = message;
|
||||
return this;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user