mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-25 16:16:20 +08:00
Compare commits
501 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d7783baad4 | ||
![]() |
2af93c9f53 | ||
![]() |
ef5285385f | ||
![]() |
ba5b8f8506 | ||
![]() |
08a1f7b682 | ||
![]() |
06018add79 | ||
![]() |
29ef0d3915 | ||
![]() |
17f5b1b210 | ||
![]() |
338d077ab3 | ||
![]() |
641d0b38ba | ||
![]() |
fa4bfc4d50 | ||
![]() |
7ae2ec03a7 | ||
![]() |
2f655c2127 | ||
![]() |
1da97c3ff8 | ||
![]() |
69a6e9023e | ||
![]() |
504cf725f1 | ||
![]() |
3623ea7f7b | ||
![]() |
49c4dc646a | ||
![]() |
0ffd777e54 | ||
![]() |
f5cd3ad593 | ||
![]() |
4e8ac0ec4c | ||
![]() |
d53a5b22cc | ||
![]() |
9c027fdcf5 | ||
![]() |
d9b9e53d33 | ||
![]() |
d500c0b61c | ||
![]() |
65e5e71f5e | ||
![]() |
82bf0094c7 | ||
![]() |
4a1277493b | ||
![]() |
895dabfa46 | ||
![]() |
44b1877eae | ||
![]() |
c58c1929c1 | ||
![]() |
87541da27c | ||
![]() |
302e2125ba | ||
![]() |
36274025d6 | ||
![]() |
04d4c5cd66 | ||
![]() |
83455a07a0 | ||
![]() |
64b9696eee | ||
![]() |
a5565bf9cf | ||
![]() |
e9c6dd83b1 | ||
![]() |
a00725be57 | ||
![]() |
162a0d0252 | ||
![]() |
96ac362fa6 | ||
![]() |
e8a86ec8b9 | ||
![]() |
9784cdc840 | ||
![]() |
13b031eef9 | ||
![]() |
c9966b1f13 | ||
![]() |
6054fa2ffa | ||
![]() |
212e78fa76 | ||
![]() |
890ff8f338 | ||
![]() |
ade6d4c22d | ||
![]() |
0bbc2ef4ba | ||
![]() |
de5f9e3047 | ||
![]() |
38d58ab47a | ||
![]() |
6528dc45df | ||
![]() |
b28a46edcb | ||
![]() |
b5c87cf6ab | ||
![]() |
c7ab4a5298 | ||
![]() |
573fd53b4e | ||
![]() |
ea863f2d2d | ||
![]() |
954f04f1c8 | ||
![]() |
05030ee984 | ||
![]() |
09f795e00e | ||
![]() |
c1809cd6c5 | ||
![]() |
7c52f083db | ||
![]() |
9882e8df86 | ||
![]() |
264f34e49d | ||
![]() |
54f8584443 | ||
![]() |
c33ee66473 | ||
![]() |
0434e718ed | ||
![]() |
3d733de399 | ||
![]() |
02b3a2fce8 | ||
![]() |
e26a4ee9cb | ||
![]() |
c7631fed68 | ||
![]() |
a4cc1d5316 | ||
![]() |
c827ffb8e6 | ||
![]() |
d42acb477c | ||
![]() |
bc5e5fa015 | ||
![]() |
32061f468c | ||
![]() |
9372f1d159 | ||
![]() |
7ec9344be8 | ||
![]() |
89830ec7e6 | ||
![]() |
eae68bb029 | ||
![]() |
ca3ddd19f7 | ||
![]() |
aef90aa2a0 | ||
![]() |
ab55cbf99b | ||
![]() |
1a7ae0e810 | ||
![]() |
b7944690d1 | ||
![]() |
76ffd8fdf1 | ||
![]() |
246d1be89e | ||
![]() |
b233973974 | ||
![]() |
0cb379e5ab | ||
![]() |
b6bcf8d36d | ||
![]() |
5ec4446443 | ||
![]() |
236ddf3471 | ||
![]() |
e6a73840ab | ||
![]() |
6f4bdae5c2 | ||
![]() |
62c124ef45 | ||
![]() |
43aa743032 | ||
![]() |
778ebe1f44 | ||
![]() |
a1e862bde7 | ||
![]() |
e6a7e4c4fc | ||
![]() |
b750fc9e51 | ||
![]() |
54af5bb42d | ||
![]() |
e6797043c5 | ||
![]() |
2c121edd3d | ||
![]() |
f3fbb57dc9 | ||
![]() |
a121b32252 | ||
![]() |
0c1235e75a | ||
![]() |
974c1fad7f | ||
![]() |
e23e3383dd | ||
![]() |
69c36021fa | ||
![]() |
abae7f3295 | ||
![]() |
83f16da2d3 | ||
![]() |
0589458b2d | ||
![]() |
49fdb6c986 | ||
![]() |
50276cb602 | ||
![]() |
8f175fca21 | ||
![]() |
6978517a3a | ||
![]() |
c2c9f4f556 | ||
![]() |
a20bac1682 | ||
![]() |
f2a0f73028 | ||
![]() |
f9fc369637 | ||
![]() |
445ea238fb | ||
![]() |
e6c7b5f928 | ||
![]() |
d709dd67b5 | ||
![]() |
7ffe1726b9 | ||
![]() |
f0ca8d5a03 | ||
![]() |
626c54504e | ||
![]() |
6fbb57621e | ||
![]() |
d88f455cd3 | ||
![]() |
98e2e4c89a | ||
![]() |
78234e2ef0 | ||
![]() |
2f921cfb88 | ||
![]() |
816553bfcd | ||
![]() |
00b8d169cb | ||
![]() |
dcbe5510d4 | ||
![]() |
3de22b44b1 | ||
![]() |
1e34d3e9e4 | ||
![]() |
182b4fc437 | ||
![]() |
b92c6c40fa | ||
![]() |
fc002d3db3 | ||
![]() |
141f3bdbd0 | ||
![]() |
cc97f06354 | ||
![]() |
a7b2f14b90 | ||
![]() |
b57d9fc60d | ||
![]() |
1b763fceee | ||
![]() |
7fa2578e6d | ||
![]() |
75f5b7ac4d | ||
![]() |
d6d1120d00 | ||
![]() |
9e055ad273 | ||
![]() |
2db4cfbd33 | ||
![]() |
6bb79180fc | ||
![]() |
65122ea1a5 | ||
![]() |
86ecb2729e | ||
![]() |
7ba83e71bf | ||
![]() |
b008c44246 | ||
![]() |
2bc8981b4f | ||
![]() |
089a98953e | ||
![]() |
404a4720b0 | ||
![]() |
d502e1d493 | ||
![]() |
af6e73b83f | ||
![]() |
e23f29464b | ||
![]() |
595b1ce680 | ||
![]() |
23b684977c | ||
![]() |
1296590e3a | ||
![]() |
ccf4027533 | ||
![]() |
fdde6f06b2 | ||
![]() |
2828ed304a | ||
![]() |
fec67b4d53 | ||
![]() |
d3600daf5c | ||
![]() |
f4df2d5a4b | ||
![]() |
57e6e4f004 | ||
![]() |
0a1a5ffedc | ||
![]() |
20698c052c | ||
![]() |
bca5154a9d | ||
![]() |
6b6b790f87 | ||
![]() |
1ca3f7c2c0 | ||
![]() |
e656b5d8dc | ||
![]() |
943f50051c | ||
![]() |
7207a0b840 | ||
![]() |
05bc4acb9b | ||
![]() |
cd71e60dd1 | ||
![]() |
dde3652b7d | ||
![]() |
522e892d79 | ||
![]() |
f6147fa449 | ||
![]() |
2376e8f67d | ||
![]() |
beee35173b | ||
![]() |
b0e8154f9f | ||
![]() |
be935eb44e | ||
![]() |
8b516b75b8 | ||
![]() |
97b76ea6bc | ||
![]() |
342328ce5f | ||
![]() |
0f13758554 | ||
![]() |
3efe662c91 | ||
![]() |
895352ad22 | ||
![]() |
064922dd4c | ||
![]() |
3a5f406260 | ||
![]() |
4d2fb0cb6f | ||
![]() |
3f65baf503 | ||
![]() |
42e9de50a2 | ||
![]() |
8a000705d1 | ||
![]() |
c8744a057e | ||
![]() |
7191ebc122 | ||
![]() |
4305f58d20 | ||
![]() |
f62043b1fc | ||
![]() |
0cfaa40bd0 | ||
![]() |
617b01338c | ||
![]() |
f58ef6777c | ||
![]() |
c715d35ad5 | ||
![]() |
83fb63faa6 | ||
![]() |
d8ab800b8a | ||
![]() |
eed50db873 | ||
![]() |
c59983345e | ||
![]() |
2cd5a40322 | ||
![]() |
82671d0750 | ||
![]() |
a9530877c0 | ||
![]() |
d7472b8a2e | ||
![]() |
6c0b857d7d | ||
![]() |
bab28af986 | ||
![]() |
cb13986a17 | ||
![]() |
11e689c86c | ||
![]() |
9fad2ab631 | ||
![]() |
003a951bef | ||
![]() |
35751068c5 | ||
![]() |
cb907165ec | ||
![]() |
72ef3df57f | ||
![]() |
3b2760ca3a | ||
![]() |
100f3cf26c | ||
![]() |
2bbc2d2811 | ||
![]() |
89323186b5 | ||
![]() |
6d047fb53f | ||
![]() |
2991bb1670 | ||
![]() |
bfb7cd32f2 | ||
![]() |
538fa168fe | ||
![]() |
83426b5c96 | ||
![]() |
191e809b6d | ||
![]() |
b976933766 | ||
![]() |
90b45b3a51 | ||
![]() |
748b99b18f | ||
![]() |
caf1783525 | ||
![]() |
2142506ce5 | ||
![]() |
71c3fea88a | ||
![]() |
8ef39def79 | ||
![]() |
c373ffd3bf | ||
![]() |
f91d777e4f | ||
![]() |
11cbe66937 | ||
![]() |
ea51c492c2 | ||
![]() |
dccc8f625d | ||
![]() |
031d613b18 | ||
![]() |
b6f8379e93 | ||
![]() |
ec646c57b8 | ||
![]() |
509541d11e | ||
![]() |
da1f177284 | ||
![]() |
6b919cd2fc | ||
![]() |
9c8e848684 | ||
![]() |
4de756aa2d | ||
![]() |
beed7f2e11 | ||
![]() |
2e632e4d4d | ||
![]() |
59145ade25 | ||
![]() |
bf060376e6 | ||
![]() |
bb3d5b8ae8 | ||
![]() |
3689bd1cb1 | ||
![]() |
50eac7f353 | ||
![]() |
e497721e9b | ||
![]() |
ee8ec9eacf | ||
![]() |
295f7eef1a | ||
![]() |
ed267d9c01 | ||
![]() |
5b9759710b | ||
![]() |
726bb73b58 | ||
![]() |
8f900871ac | ||
![]() |
06a6c947a9 | ||
![]() |
97f16271b1 | ||
![]() |
054a476d25 | ||
![]() |
ae61fa1186 | ||
![]() |
405ef9e2b3 | ||
![]() |
4755017bcc | ||
![]() |
18211f6d14 | ||
![]() |
52aba6c106 | ||
![]() |
41451f4fa3 | ||
![]() |
83fc4ae391 | ||
![]() |
6f0a44f528 | ||
![]() |
92875cbecc | ||
![]() |
e7fbd74228 | ||
![]() |
87224715c3 | ||
![]() |
00bf5d5bbf | ||
![]() |
b776ac4cd8 | ||
![]() |
e4bcf8c899 | ||
![]() |
a0b2a9e949 | ||
![]() |
7b87d6d29e | ||
![]() |
3d0b88708e | ||
![]() |
c42ba1cc1b | ||
![]() |
2ec5f6322d | ||
![]() |
83aa1da3de | ||
![]() |
6f7d840128 | ||
![]() |
2152b3f779 | ||
![]() |
882270d5ba | ||
![]() |
b103c64954 | ||
![]() |
0f2c2eabd6 | ||
![]() |
bbc2ede1aa | ||
![]() |
c24e0efd1d | ||
![]() |
0cf79d4ce2 | ||
![]() |
8df2590aae | ||
![]() |
40aac6544c | ||
![]() |
1a5bedd1cb | ||
![]() |
b3a6ef63bb | ||
![]() |
a0e43abeab | ||
![]() |
18222ab0b6 | ||
![]() |
0bb76a86d2 | ||
![]() |
d30fd1d546 | ||
![]() |
8f6153fd2a | ||
![]() |
a0d4b10a1f | ||
![]() |
d4f2641b9a | ||
![]() |
094a33c0c2 | ||
![]() |
95ca2c3ae6 | ||
![]() |
8e9d4f0a57 | ||
![]() |
5aac032acc | ||
![]() |
f5f7952515 | ||
![]() |
cdac147bc8 | ||
![]() |
4b46be4a79 | ||
![]() |
f87e078402 | ||
![]() |
4d02205839 | ||
![]() |
e161c1449a | ||
![]() |
5a388be15e | ||
![]() |
30b3ee5c89 | ||
![]() |
b43d3069e1 | ||
![]() |
a768b7d519 | ||
![]() |
c5a13dc92f | ||
![]() |
6dd2818247 | ||
![]() |
ae58ada82e | ||
![]() |
8b13f62995 | ||
![]() |
025cf98f4b | ||
![]() |
6e33c26893 | ||
![]() |
d9fd16f4de | ||
![]() |
a73187ccf4 | ||
![]() |
aa03c87383 | ||
![]() |
f5ce480f0f | ||
![]() |
f0550f2043 | ||
![]() |
f8698c4c3d | ||
![]() |
71c43945a5 | ||
![]() |
0b9dd918d9 | ||
![]() |
8289332214 | ||
![]() |
ae09d3cfd6 | ||
![]() |
6e1e1de0e2 | ||
![]() |
cea297ce88 | ||
![]() |
e456f54ded | ||
![]() |
e25af8dd8c | ||
![]() |
49d40d685d | ||
![]() |
e53fefb310 | ||
![]() |
9c6b271097 | ||
![]() |
ec33820bf9 | ||
![]() |
a5a11fb846 | ||
![]() |
694dead311 | ||
![]() |
d84f6ef562 | ||
![]() |
ba5809669d | ||
![]() |
a712a8e5a0 | ||
![]() |
1e95706f8b | ||
![]() |
986430513b | ||
![]() |
1519f47f7d | ||
![]() |
f3f2f548e6 | ||
![]() |
18f55833e2 | ||
![]() |
033d8828a9 | ||
![]() |
a3b9ff04f9 | ||
![]() |
c315aa9801 | ||
![]() |
b5bdb53555 | ||
![]() |
690d887680 | ||
![]() |
64b812802f | ||
![]() |
c0c3116193 | ||
![]() |
10d6cc9b60 | ||
![]() |
a63a10c047 | ||
![]() |
b46a505582 | ||
![]() |
d46c6daa13 | ||
![]() |
9f6d61d02c | ||
![]() |
edffc12bb7 | ||
![]() |
b78f06898f | ||
![]() |
a7ee3367e5 | ||
![]() |
b3b2ca0738 | ||
![]() |
fa5803f8c7 | ||
![]() |
aa6168fe20 | ||
![]() |
855a410557 | ||
![]() |
b1559e2cad | ||
![]() |
c5d24e07f0 | ||
![]() |
1cf2a81f2a | ||
![]() |
3569eda012 | ||
![]() |
2abe24b8e0 | ||
![]() |
5665fd62a9 | ||
![]() |
eb2665059e | ||
![]() |
be6f89b4bf | ||
![]() |
b7554fdb74 | ||
![]() |
47348747a3 | ||
![]() |
3b62afe110 | ||
![]() |
dbdd811705 | ||
![]() |
a6b65b58a1 | ||
![]() |
a730afb67c | ||
![]() |
f70cb62ecd | ||
![]() |
556575f501 | ||
![]() |
e4778757ad | ||
![]() |
b43fe7adbc | ||
![]() |
4aaddef06f | ||
![]() |
ce6b25d03b | ||
![]() |
74a2f6209f | ||
![]() |
99ddc3598a | ||
![]() |
d3fd22dbbd | ||
![]() |
bf2f6390ad | ||
![]() |
bd024cc521 | ||
![]() |
4ac08e5ae5 | ||
![]() |
b0c2ca5393 | ||
![]() |
1ac8c56c6b | ||
![]() |
f4149c2f1d | ||
![]() |
3ed49c3f8f | ||
![]() |
356f132610 | ||
![]() |
1c668f21bf | ||
![]() |
a244dcd261 | ||
![]() |
aaf2fde3cf | ||
![]() |
607a24632a | ||
![]() |
89d7a19f3f | ||
![]() |
a9017da294 | ||
![]() |
1c1ce4b0e3 | ||
![]() |
e31525a803 | ||
![]() |
7b26c5994c | ||
![]() |
248f9d5e81 | ||
![]() |
a2a78f40da | ||
![]() |
2c74e790cb | ||
![]() |
b660f96220 | ||
![]() |
5dd3babc4e | ||
![]() |
5425dc241f | ||
![]() |
44f2b1c644 | ||
![]() |
573d395b69 | ||
![]() |
df1fceb291 | ||
![]() |
9650122736 | ||
![]() |
c99ef68b7b | ||
![]() |
a95ba47b74 | ||
![]() |
3fd193eb8b | ||
![]() |
6fbc552ed1 | ||
![]() |
247665513a | ||
![]() |
351e1e55c2 | ||
![]() |
8a27f5f277 | ||
![]() |
befb508f7a | ||
![]() |
e6c820792a | ||
![]() |
30ccbfa695 | ||
![]() |
7e12259ec4 | ||
![]() |
244eeb18aa | ||
![]() |
1108d78a06 | ||
![]() |
ebe2047ae0 | ||
![]() |
c7f4e6a459 | ||
![]() |
833b31129b | ||
![]() |
86d5752ed7 | ||
![]() |
9babbc43fc | ||
![]() |
a2451be5bc | ||
![]() |
eea414e04b | ||
![]() |
0bd98b3c27 | ||
![]() |
a065de4fbc | ||
![]() |
fa5ecb090f | ||
![]() |
4f9c711012 | ||
![]() |
12924fb3fa | ||
![]() |
16b4b6d57c | ||
![]() |
c28224f3f8 | ||
![]() |
3b0b8d0baa | ||
![]() |
b30270a3fb | ||
![]() |
cb64e5d24c | ||
![]() |
a4e70b9efe | ||
![]() |
4e3e721650 | ||
![]() |
c6e135195a | ||
![]() |
1262e13067 | ||
![]() |
c659c14c5a | ||
![]() |
5ad5c8cdc7 | ||
![]() |
27cb958c2e | ||
![]() |
155ad45848 | ||
![]() |
7535db377f | ||
![]() |
a0fdceeae7 | ||
![]() |
c6e5c0f5f1 | ||
![]() |
ca997c15ca | ||
![]() |
4c381596a9 | ||
![]() |
7bcdb46148 | ||
![]() |
d33ccd042f | ||
![]() |
08f479f3e1 | ||
![]() |
c054d73fe6 | ||
![]() |
1f287145f4 | ||
![]() |
9c43c74131 | ||
![]() |
c516d39225 | ||
![]() |
a1283c1322 | ||
![]() |
cc88e1a66c | ||
![]() |
6aa3f934d0 | ||
![]() |
7ca007ecd5 | ||
![]() |
361a189f6a | ||
![]() |
19fd49e22d | ||
![]() |
1e8fab3fe5 | ||
![]() |
7e0456cc6c | ||
![]() |
c118e83a2b | ||
![]() |
31d44ad372 | ||
![]() |
f810a0892d | ||
![]() |
5de89b5ec5 | ||
![]() |
0347c83620 | ||
![]() |
eb0fdb2cfc | ||
![]() |
e154d1366c | ||
![]() |
34237ef033 | ||
![]() |
b13c4a81fc | ||
![]() |
c46b04d548 | ||
![]() |
afacf68825 | ||
![]() |
60a3b6a9f9 | ||
![]() |
b97d588392 | ||
![]() |
6e716c5607 |
@@ -51,7 +51,7 @@ module.exports = {
|
||||
],
|
||||
},
|
||||
prompt: {
|
||||
/** @use `yarn commit :f` */
|
||||
/** @use `pnpm commit :f` */
|
||||
alias: {
|
||||
f: 'docs: fix typos',
|
||||
r: 'docs: update README',
|
3
.dockerignore
Normal file
3
.dockerignore
Normal file
@@ -0,0 +1,3 @@
|
||||
node_modules/
|
||||
dist/
|
||||
.vscode/
|
@@ -11,13 +11,13 @@ VITE_BUILD_COMPRESS = 'none'
|
||||
|
||||
|
||||
# Basic interface address SPA
|
||||
VITE_GLOB_API_URL=/basic-api
|
||||
VITE_GLOB_API_URL = /basic-api
|
||||
|
||||
# File upload address, optional
|
||||
# It can be forwarded by nginx or write the actual address directly
|
||||
VITE_GLOB_UPLOAD_URL=/upload
|
||||
VITE_GLOB_UPLOAD_URL = /upload
|
||||
|
||||
# Interface prefix
|
||||
VITE_GLOB_API_URL_PREFIX=
|
||||
VITE_GLOB_API_URL_PREFIX =
|
||||
|
||||
VITE_ENABLE_ANALYZE = true
|
||||
|
@@ -5,10 +5,10 @@ VITE_USE_MOCK = true
|
||||
VITE_PUBLIC_PATH = /
|
||||
|
||||
# Basic interface address SPA
|
||||
VITE_GLOB_API_URL=/basic-api
|
||||
VITE_GLOB_API_URL = /basic-api
|
||||
|
||||
# File upload address, optional
|
||||
VITE_GLOB_UPLOAD_URL=/upload
|
||||
VITE_GLOB_UPLOAD_URL = /upload
|
||||
|
||||
# Interface prefix
|
||||
VITE_GLOB_API_URL_PREFIX=
|
||||
VITE_GLOB_API_URL_PREFIX =
|
||||
|
22
.env.docker
Normal file
22
.env.docker
Normal file
@@ -0,0 +1,22 @@
|
||||
# Whether to open mock
|
||||
VITE_USE_MOCK = false
|
||||
|
||||
# public path
|
||||
VITE_PUBLIC_PATH = /
|
||||
|
||||
# timeout(seconds)
|
||||
VITE_TIMEOUT = 15
|
||||
# Delete console
|
||||
VITE_DROP_CONSOLE = true
|
||||
|
||||
# Whether to enable gzip or brotli compression
|
||||
# Optional: gzip | brotli | none
|
||||
# If you need multiple forms, you can use `,` to separate
|
||||
VITE_BUILD_COMPRESS = 'none'
|
||||
VITE_GLOB_API_URL = "__vg_base_url"
|
||||
|
||||
# File upload address, optional
|
||||
# It can be forwarded by nginx or write the actual address directly
|
||||
VITE_GLOB_UPLOAD_URL = /files/upload
|
||||
# Interface prefix
|
||||
VITE_GLOB_API_URL_PREFIX =
|
@@ -11,11 +11,11 @@ VITE_BUILD_COMPRESS = 'none'
|
||||
|
||||
|
||||
# Basic interface address SPA
|
||||
VITE_GLOB_API_URL=/basic-api
|
||||
VITE_GLOB_API_URL = /basic-api
|
||||
|
||||
# File upload address, optional
|
||||
# It can be forwarded by nginx or write the actual address directly
|
||||
VITE_GLOB_UPLOAD_URL=/upload
|
||||
VITE_GLOB_UPLOAD_URL = /upload
|
||||
|
||||
# Interface prefix
|
||||
VITE_GLOB_API_URL_PREFIX=
|
||||
VITE_GLOB_API_URL_PREFIX =
|
||||
|
@@ -1,4 +1,4 @@
|
||||
NODE_ENV=production
|
||||
NODE_ENV = production
|
||||
# Whether to open mock
|
||||
VITE_USE_MOCK = true
|
||||
|
||||
@@ -11,11 +11,11 @@ VITE_PUBLIC_PATH = /
|
||||
VITE_BUILD_COMPRESS = 'none'
|
||||
|
||||
# Basic interface address SPA
|
||||
VITE_GLOB_API_URL=/basic-api
|
||||
VITE_GLOB_API_URL = /basic-api
|
||||
|
||||
# File upload address, optional
|
||||
# It can be forwarded by nginx or write the actual address directly
|
||||
VITE_GLOB_UPLOAD_URL=/upload
|
||||
VITE_GLOB_UPLOAD_URL = /upload
|
||||
|
||||
# Interface prefix
|
||||
VITE_GLOB_API_URL_PREFIX=
|
||||
VITE_GLOB_API_URL_PREFIX =
|
||||
|
@@ -13,3 +13,4 @@ dist
|
||||
.local
|
||||
/bin
|
||||
Dockerfile
|
||||
package.json
|
||||
|
@@ -1,4 +1,7 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: ['@vben'],
|
||||
rules: {
|
||||
'no-undef': 'off',
|
||||
},
|
||||
};
|
2
.github/ISSUE_TEMPLATE/1-bug.md
vendored
2
.github/ISSUE_TEMPLATE/1-bug.md
vendored
@@ -36,4 +36,4 @@ Please describe the steps of the problem in detail to ensure that we can restore
|
||||
|
||||
- Operating System:
|
||||
- Node version:
|
||||
- Package manager (npm/yarn/pnpm) and version:
|
||||
- pnpm version:
|
||||
|
2
.github/ISSUE_TEMPLATE/3-bug-cn.md
vendored
2
.github/ISSUE_TEMPLATE/3-bug-cn.md
vendored
@@ -25,4 +25,4 @@ assignees: ''
|
||||
|
||||
- 操作系统:
|
||||
- Node 版本:
|
||||
- 包管理器 (npm/yarn/pnpm) 及其版本:
|
||||
- pnpm 版本:
|
||||
|
38
.github/workflows/deploy.yml
vendored
38
.github/workflows/deploy.yml
vendored
@@ -60,6 +60,8 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# - uses: NullVoxPopuli/action-setup-pnpm@v2
|
||||
|
||||
- name: Sed Config Base
|
||||
shell: bash
|
||||
run: |
|
||||
@@ -67,22 +69,28 @@ jobs:
|
||||
sed -i "s#VITE_DROP_CONSOLE\s*=.*#VITE_DROP_CONSOLE = true#g" ./.env.production
|
||||
cat ./.env.production
|
||||
|
||||
- name: use Node.js 16
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: 9
|
||||
run_install: false
|
||||
|
||||
- name: use Node.js 20
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '16.x'
|
||||
node-version: '20.x'
|
||||
|
||||
- name: Get yarn cache directory path
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-
|
||||
# - name: Get yarn cache directory path
|
||||
# id: yarn-cache-dir-path
|
||||
# run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
|
||||
#
|
||||
# - name: Cache dependencies
|
||||
# uses: actions/cache@v3
|
||||
# with:
|
||||
# path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
# key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||
# restore-keys: |
|
||||
# ${{ runner.os }}-yarn-
|
||||
|
||||
- name: Set SSH Environment
|
||||
env:
|
||||
@@ -100,8 +108,8 @@ jobs:
|
||||
env:
|
||||
NODE_OPTIONS: '--max_old_space_size=4096'
|
||||
run: |
|
||||
yarn install
|
||||
yarn run build
|
||||
pnpm install --no-frozen-lockfile
|
||||
pnpm build
|
||||
touch dist/.nojekyll
|
||||
cp dist/index.html dist/404.html
|
||||
|
||||
|
39
.github/workflows/linter.yml
vendored
Normal file
39
.github/workflows/linter.yml
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
|
||||
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs
|
||||
|
||||
name: Node.js CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, thin]
|
||||
pull_request:
|
||||
branches: [main, thin]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [18.x, 20.x]
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Install pnpm
|
||||
run: npm install -g pnpm
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Run type:check
|
||||
run: pnpm run type:check
|
||||
|
||||
- name: Build
|
||||
run: pnpm build
|
22
.github/workflows/release-tag.yml
vendored
Normal file
22
.github/workflows/release-tag.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
name: Create Release Tag
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Create Release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Create Release for Tag
|
||||
id: release_tag
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
generateReleaseNotes: 'true'
|
||||
body: |
|
||||
> Please refer to [CHANGELOG.md](https://github.com/anncwb/vue-vben-admin/blob/main/CHANGELOG.md) for details.
|
24
.github/workflows/release.yml
vendored
24
.github/workflows/release.yml
vendored
@@ -1,24 +0,0 @@
|
||||
name: Create Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v*
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Create Release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@master
|
||||
|
||||
- name: Create Release for Tag
|
||||
id: release_tag
|
||||
uses: yyx990803/release-tag@master
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.OPER_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
body: |
|
||||
Please refer to [CHANGELOG.md](https://github.com/anncwb/vue-vben-admin/blob/main/CHANGELOG.md) for details.
|
18
.github/workflows/stale.yml
vendored
Normal file
18
.github/workflows/stale.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
name: 'Close stale issues'
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '30 1 * * *'
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v3
|
||||
with:
|
||||
repo-token: ${{ secrets.OPER_TOKEN }}
|
||||
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days'
|
||||
stale-pr-message: 'This PR is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days'
|
||||
exempt-issue-labels: 'bug,enhancement'
|
||||
days-before-stale: 60
|
||||
days-before-close: 7
|
1
.npmrc
1
.npmrc
@@ -5,3 +5,4 @@ public-hoist-pattern[]=lint-staged
|
||||
public-hoist-pattern[]=*stylelint*
|
||||
public-hoist-pattern[]=@commitlint/cli
|
||||
public-hoist-pattern[]=@vben/eslint-config
|
||||
package-manager-strict=false
|
||||
|
@@ -8,3 +8,5 @@ node_modules
|
||||
|
||||
public
|
||||
.npmrc
|
||||
|
||||
*-lock.yaml
|
||||
|
3
.vscode/extensions.json
vendored
3
.vscode/extensions.json
vendored
@@ -7,7 +7,8 @@
|
||||
"mrmlnc.vscode-less",
|
||||
"lokalise.i18n-ally",
|
||||
"antfu.iconify",
|
||||
"antfu.unocss",
|
||||
"mikestead.dotenv",
|
||||
"heybourn.headwind"
|
||||
"warmthsea.vscode-custom-code-color"
|
||||
]
|
||||
}
|
||||
|
76
.vscode/settings.json
vendored
76
.vscode/settings.json
vendored
@@ -57,7 +57,7 @@
|
||||
"stylelint.enable": true,
|
||||
"stylelint.validate": ["css", "less", "postcss", "scss", "vue", "sass"],
|
||||
"path-intellisense.mappings": {
|
||||
"/@/": "${workspaceRoot}/src"
|
||||
"@/": "${workspaceRoot}/src"
|
||||
},
|
||||
"[javascriptreact]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
@@ -84,57 +84,58 @@
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true,
|
||||
"source.fixAll.stylelint": true
|
||||
"source.fixAll.eslint": "explicit",
|
||||
"source.fixAll.stylelint": "explicit"
|
||||
},
|
||||
"[vue]": {
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true,
|
||||
"source.fixAll.stylelint": true
|
||||
}
|
||||
"source.fixAll.eslint": "explicit",
|
||||
"source.fixAll.stylelint": "explicit"
|
||||
},
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"i18n-ally.localesPaths": ["src/locales/lang"],
|
||||
"i18n-ally.keystyle": "nested",
|
||||
"i18n-ally.sortKeys": true,
|
||||
"i18n-ally.namespace": true,
|
||||
"i18n-ally.pathMatcher": "{locale}/{namespaces}.{ext}",
|
||||
"i18n-ally.enabledParsers": ["ts"],
|
||||
"i18n-ally.enabledParsers": ["json", "ts", "js"],
|
||||
"i18n-ally.sourceLanguage": "en",
|
||||
"i18n-ally.displayLanguage": "zh-CN",
|
||||
"i18n-ally.enabledFrameworks": ["vue", "react"],
|
||||
"cSpell.words": [
|
||||
"vben",
|
||||
"browserslist",
|
||||
"tailwindcss",
|
||||
"esnext",
|
||||
"antd",
|
||||
"antv",
|
||||
"tinymce",
|
||||
"brotli",
|
||||
"browserslist",
|
||||
"codemirror",
|
||||
"commitlint",
|
||||
"cropperjs",
|
||||
"echarts",
|
||||
"esnext",
|
||||
"esno",
|
||||
"iconify",
|
||||
"INTLIFY",
|
||||
"lintstagedrc",
|
||||
"logicflow",
|
||||
"mockjs",
|
||||
"nprogress",
|
||||
"pinia",
|
||||
"pnpm",
|
||||
"qrcode",
|
||||
"sider",
|
||||
"pinia",
|
||||
"sider",
|
||||
"nprogress",
|
||||
"INTLIFY",
|
||||
"stylelint",
|
||||
"esno",
|
||||
"vitejs",
|
||||
"sortablejs",
|
||||
"mockjs",
|
||||
"codemirror",
|
||||
"iconify",
|
||||
"commitlint",
|
||||
"vditor",
|
||||
"echarts",
|
||||
"cropperjs",
|
||||
"logicflow",
|
||||
"vueuse",
|
||||
"zxcvbn",
|
||||
"lintstagedrc",
|
||||
"brotli",
|
||||
"stylelint",
|
||||
"tailwindcss",
|
||||
"sider",
|
||||
"pnpm",
|
||||
"antd"
|
||||
"tinymce",
|
||||
"unocss",
|
||||
"unref",
|
||||
"vben",
|
||||
"vditor",
|
||||
"Vite",
|
||||
"vitejs",
|
||||
"vueuse",
|
||||
"zxcvbn"
|
||||
],
|
||||
"vetur.format.scriptInitialIndent": true,
|
||||
"vetur.format.styleInitialIndent": true,
|
||||
@@ -166,7 +167,10 @@
|
||||
"*.env": "$(capture).env.*",
|
||||
"CHANGELOG.md": "CHANGELOG*",
|
||||
"package.json": "pnpm-lock.yaml,pnpm-workspace.yaml,LICENSE,.gitattributes,.gitignore,.gitpod.yml,CNAME,README*,.npmrc,.browserslistrc",
|
||||
".eslintrc.js": ".eslintignore,.prettierignore,.stylelintignore,.commitlintrc.js,.prettierrc.js,.stylelintrc.js"
|
||||
".eslintrc.cjs": ".eslintignore,.prettierignore,.stylelintignore,.commitlintrc.*,.prettierrc.*,.stylelintrc.*"
|
||||
},
|
||||
"terminal.integrated.scrollback": 10000
|
||||
"terminal.integrated.scrollback": 10000,
|
||||
"nuxt.isNuxtApp": false,
|
||||
"vscodeCustomCodeColor.highlightValue": "v-auth",
|
||||
"vscodeCustomCodeColor.highlightValueColor": "#6366f1"
|
||||
}
|
||||
|
@@ -308,7 +308,7 @@
|
||||
- Fix the height issue of the lock screen pop-up window
|
||||
- Fixed the problem that the half-selected state of the `Column Display` checkbox of `BaiscTable` was incorrectly displayed
|
||||
- Fixed the problem that the preview list of the `BasicUpload` component could not be displayed in some cases
|
||||
- Fix the problem that the `options` setting of ` RadioButtonGroup``disabled ` does not take effect
|
||||
- Fix the problem that the `options` setting of `RadioButtonGroup``disabled` does not take effect
|
||||
- Fix the problem that the button for uploading pictures in the read-only mode of the `Tinymce` component is still available
|
||||
- Fix the stuttering problem of `BasicForm` under certain circumstances
|
||||
- Fix the problem that "directory" routing does not work
|
||||
|
277
CHANGELOG.md
277
CHANGELOG.md
@@ -1,3 +1,280 @@
|
||||
## [2.11.4](https://github.com/vbenjs/vue-vben-admin/compare/v2.11.3...v2.11.4) (2024-05-06)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **BasicForm:** 修复 SetFieldsValue 设置值时,会将 Number 类型的值转为 string ([#3802](https://github.com/vbenjs/vue-vben-admin/issues/3802)) ([08a1f7b](https://github.com/vbenjs/vue-vben-admin/commit/08a1f7b682114bdf758ea9dcd4b84daea0d5f196))
|
||||
- **breadcrumb:** if hideChildrenInmenu is true & hidden dropdown-menu ([#3807](https://github.com/vbenjs/vue-vben-admin/issues/3807)) ([2af93c9](https://github.com/vbenjs/vue-vben-admin/commit/2af93c9f5307ffdbb29653303177b2c8631e789a))
|
||||
- **docker:** update node version of dockerfile ([#3788](https://github.com/vbenjs/vue-vben-admin/issues/3788)) ([338d077](https://github.com/vbenjs/vue-vben-admin/commit/338d077ab3669ef116e7406c586fe2cb59952022))
|
||||
- **imgupload:** resultField causing with error display && setField uncertain ([#3798](https://github.com/vbenjs/vue-vben-admin/issues/3798)) ([06018ad](https://github.com/vbenjs/vue-vben-admin/commit/06018add798a6c23ebbfa91a3f4d625c2a57e458))
|
||||
|
||||
### Features
|
||||
|
||||
- **upload->previewColumns:** Adapt functions && chore upload demo ([#3799](https://github.com/vbenjs/vue-vben-admin/issues/3799)) ([29ef0d3](https://github.com/vbenjs/vue-vben-admin/commit/29ef0d39157957146015e1b914c26d2b6d1bf25e))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
- **util:** remove handleInputNumberValue ([#3806](https://github.com/vbenjs/vue-vben-admin/issues/3806)) ([ba5b8f8](https://github.com/vbenjs/vue-vben-admin/commit/ba5b8f8506bb9d052ce2705653f255f0401963e8))
|
||||
|
||||
## [2.11.3](https://github.com/vbenjs/vue-vben-admin/compare/v2.11.2...v2.11.3) (2024-04-24)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **deps:** lock vue version to 3.4.23 ([#3785](https://github.com/vbenjs/vue-vben-admin/issues/3785)) ([2f655c2](https://github.com/vbenjs/vue-vben-admin/commit/2f655c2127753c0cde1cb29834314e961ce0930e)), closes [#3783](https://github.com/vbenjs/vue-vben-admin/issues/3783)
|
||||
- **upload:** disabled prop not effect to upload in the form ([#3780](https://github.com/vbenjs/vue-vben-admin/issues/3780)) ([69a6e90](https://github.com/vbenjs/vue-vben-admin/commit/69a6e9023ef80a5504178d0887119f8e7bbd5113))
|
||||
|
||||
### Features
|
||||
|
||||
- **BasicForm->Components:** add beforeFetch & afterFetch to apicomp && perf the code ([#3786](https://github.com/vbenjs/vue-vben-admin/issues/3786)) ([7ae2ec0](https://github.com/vbenjs/vue-vben-admin/commit/7ae2ec03a773c2223feabbd1e341e90f012f8b7e))
|
||||
- **demo:** use Tour component replace dirverjs ([#3777](https://github.com/vbenjs/vue-vben-admin/issues/3777)) ([49c4dc6](https://github.com/vbenjs/vue-vben-admin/commit/49c4dc646a9d123527577f02ee0d92865da9988e))
|
||||
|
||||
## [2.11.2](https://github.com/vbenjs/vue-vben-admin/compare/v2.11.1...v2.11.2) (2024-04-23)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **BasicForm:** solve the error about setFieldValue array ([#3775](https://github.com/vbenjs/vue-vben-admin/issues/3775)) ([f5cd3ad](https://github.com/vbenjs/vue-vben-admin/commit/f5cd3ad593ded10a9702cf342d788c4b1540944a))
|
||||
- **ci:** use for package-manager-strict ([d53a5b2](https://github.com/vbenjs/vue-vben-admin/commit/d53a5b22ccadc28f99fc5e9751e3177d349ba8b9))
|
||||
|
||||
## [2.11.1](https://github.com/vbenjs/vue-vben-admin/compare/v2.11.0...v2.11.1) (2024-04-20)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- the form not working when setFieldsValue through form-groups and add a demo with form groups ([#3765](https://github.com/vbenjs/vue-vben-admin/issues/3765)) ([65e5e71](https://github.com/vbenjs/vue-vben-admin/commit/65e5e71f5ee44eac221721de2c8c1d03e622e34a))
|
||||
|
||||
# [2.11.0](https://github.com/vbenjs/vue-vben-admin/compare/2.10.1...2.11.0) (2024-04-20)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- (demo->page>form>high) expose getDataSource close [#3529](https://github.com/vbenjs/vue-vben-admin/issues/3529) ([#3530](https://github.com/vbenjs/vue-vben-admin/issues/3530)) ([0c1235e](https://github.com/vbenjs/vue-vben-admin/commit/0c1235e75aa6a855d774435ef08d3ffae19d1272))
|
||||
- [#2744](https://github.com/vbenjs/vue-vben-admin/issues/2744)tabs选项卡渲染问题,以及完善路由中affix=true时处理逻辑。 ([#3127](https://github.com/vbenjs/vue-vben-admin/issues/3127)) ([b43d306](https://github.com/vbenjs/vue-vben-admin/commit/b43d3069e1ec731e339ed28c17325620f1fe9a6e))
|
||||
- [#3077](https://github.com/vbenjs/vue-vben-admin/issues/3077) 最新代码 ApiTransfer编辑后无法正常显示数据 ([#3083](https://github.com/vbenjs/vue-vben-admin/issues/3083)) ([c0c3116](https://github.com/vbenjs/vue-vben-admin/commit/c0c31161939027f64fa44a57084acafa0c6c2a8b))
|
||||
- [#3144](https://github.com/vbenjs/vue-vben-admin/issues/3144) Drawer的footer样式错位问题 ([#3148](https://github.com/vbenjs/vue-vben-admin/issues/3148)) ([8e9d4f0](https://github.com/vbenjs/vue-vben-admin/commit/8e9d4f0a5758bf414b2885f02563a3b24f5cf6f1))
|
||||
- 1.修正ImageUpload直接使用时无法正常回传value 2.修正ImageUpload无法正常初始化第一次传值 ([#3704](https://github.com/vbenjs/vue-vben-admin/issues/3704)) ([b5c87cf](https://github.com/vbenjs/vue-vben-admin/commit/b5c87cf6abc46ccd9b9bb8795b235b738e8bb376))
|
||||
- 菜单搜索功能修复 ([#3688](https://github.com/vbenjs/vue-vben-admin/issues/3688)) ([c1809cd](https://github.com/vbenjs/vue-vben-admin/commit/c1809cd6c59228d7932f24a2b1f8e4933654238d))
|
||||
- 当TableAction的actions属性中的ActionItem传递了color属性时,PopConfirm的指示箭头颜色异常问题 ([#3597](https://github.com/vbenjs/vue-vben-admin/issues/3597)) ([e6a7384](https://github.com/vbenjs/vue-vben-admin/commit/e6a73840ab7c7cbd5a5a534bd248f5ed5df11e5c))
|
||||
- 多选框必填选中校验异常,close [#3097](https://github.com/vbenjs/vue-vben-admin/issues/3097) ([#3103](https://github.com/vbenjs/vue-vben-admin/issues/3103)) ([18f5583](https://github.com/vbenjs/vue-vben-admin/commit/18f55833e282206c1ca650a7c62654d45e819759))
|
||||
- 解决 'Cannot find module uncss' 的问题 ([#3334](https://github.com/vbenjs/vue-vben-admin/issues/3334)) ([3a5f406](https://github.com/vbenjs/vue-vben-admin/commit/3a5f4062602f8394523a82cd807a27580e96a42a))
|
||||
- 解决table复选框点击无法勾选状态问题 ([#3370](https://github.com/vbenjs/vue-vben-admin/issues/3370)) ([dde3652](https://github.com/vbenjs/vue-vben-admin/commit/dde3652b7d8b68b7f8ac669bd96a55c7b9b1b1fa))
|
||||
- 设置 baseurl 后不生效的问题 ([#3318](https://github.com/vbenjs/vue-vben-admin/issues/3318)) ([4305f58](https://github.com/vbenjs/vue-vben-admin/commit/4305f58d201382c71f41fcd2625bc45ae09a2ae0))
|
||||
- 使用suffix时,label没有垂直居中 ([#3384](https://github.com/vbenjs/vue-vben-admin/issues/3384)) ([6b6b790](https://github.com/vbenjs/vue-vben-admin/commit/6b6b790f87edab31cb8e0dff730a1490903a3048))
|
||||
- 修复表单按钮的类型定义外部无法修改重置或者提交按钮的文字的问题 ([141f3bd](https://github.com/vbenjs/vue-vben-admin/commit/141f3bdbd06f4d32e3d0e871072f876c29a8d68b))
|
||||
- 修复表单设计的右侧属性配置面板中部分表单错乱的问题 ([#3300](https://github.com/vbenjs/vue-vben-admin/issues/3300)). close [#3268](https://github.com/vbenjs/vue-vben-admin/issues/3268) ([cb13986](https://github.com/vbenjs/vue-vben-admin/commit/cb13986a170815c5a21c86033057a8a56d608388))
|
||||
- 修复菜单在MIX_SIDEBAR模式下title显示为name的问题 ([#3682](https://github.com/vbenjs/vue-vben-admin/issues/3682)) ([264f34e](https://github.com/vbenjs/vue-vben-admin/commit/264f34e49d413783d6d23715ebd9ab721b03d01c))
|
||||
- 修复黑暗模式下一些样式问题 ([#3201](https://github.com/vbenjs/vue-vben-admin/issues/3201)) ([054a476](https://github.com/vbenjs/vue-vben-admin/commit/054a476d25b2d8322b238a6da6028051bcfdab84))
|
||||
- 修复确认弹出框样式错乱的问题 ([#3742](https://github.com/vbenjs/vue-vben-admin/issues/3742)) ([a00725b](https://github.com/vbenjs/vue-vben-admin/commit/a00725be571e90fa5d807ec2bc1e23b160c824ff))
|
||||
- 修复设置抽屉弹框滚动条样式异常 ([#3193](https://github.com/vbenjs/vue-vben-admin/issues/3193)) ([4755017](https://github.com/vbenjs/vue-vben-admin/commit/4755017bcc2dc0aee2f98b46d929a060a5b1bb62))
|
||||
- 修复BasicForm使用componentProps函数返回valueFormat时DatePicker无法正确格式化的问题 ([#3357](https://github.com/vbenjs/vue-vben-admin/issues/3357)) ([beee351](https://github.com/vbenjs/vue-vben-admin/commit/beee35173b84dfb4c27bcd403df689e102379303))
|
||||
- 修复index.html加载文字偏移的问题 ([#3306](https://github.com/vbenjs/vue-vben-admin/issues/3306)) ([c715d35](https://github.com/vbenjs/vue-vben-admin/commit/c715d35ad5754dd78135073ddbea86e43e17be91))
|
||||
- 修复Modal.confirm的返回类型问题,需要有destroy,update的方法 ([#3161](https://github.com/vbenjs/vue-vben-admin/issues/3161)) ([a0e43ab](https://github.com/vbenjs/vue-vben-admin/commit/a0e43abeab2930097209a0cf6c21f3de687435ca))
|
||||
- 修复notice样式绑定路径错误 ([#3218](https://github.com/vbenjs/vue-vben-admin/issues/3218)) ([ee8ec9e](https://github.com/vbenjs/vue-vben-admin/commit/ee8ec9eacfbfe1c5dc3a842da126dbaf5d54b126))
|
||||
- 修复rule validator类型默认为string,导致 radio 等组件在 setFormValues 时,如果值不是string类型,提示校验错误 ([a63a10c](https://github.com/vbenjs/vue-vben-admin/commit/a63a10c047cda32d92f35780163772fb20a6fe7a))
|
||||
- 英文版本时提示中的单词没有分开 ([eb26650](https://github.com/vbenjs/vue-vben-admin/commit/eb2665059eb5fdcb8299032dc1a49c73f1675156))
|
||||
- **ApiCascader:** apiParamKey not working ([c42ba1c](https://github.com/vbenjs/vue-vben-admin/commit/c42ba1cc1b2fba7179701cb1f918443523a9fc70))
|
||||
- **ApiCascader:** wrong api reload ([#3536](https://github.com/vbenjs/vue-vben-admin/issues/3536)) resolve [#3534](https://github.com/vbenjs/vue-vben-admin/issues/3534) ([83f16da](https://github.com/vbenjs/vue-vben-admin/commit/83f16da2d35716f94f1837ab9bee41c5878ab3b0))
|
||||
- **ApiSelect:** 移除watchEffect引发的重复请求 ([#3107](https://github.com/vbenjs/vue-vben-admin/issues/3107)) ([1519f47](https://github.com/vbenjs/vue-vben-admin/commit/1519f47f7d7785a93be51ce9da0f9ef2e78705c9))
|
||||
- **ApiSelect:** 修复监听不到params的变动 ([ccf4027](https://github.com/vbenjs/vue-vben-admin/commit/ccf4027533d2adabd21bade025ca7bc7d34d75f6))
|
||||
- **ApiSelect:** ApiSelect的isFirstLoaded赋值逻辑,只有当加载报错时才能恢复未初次加载状态 ([#3671](https://github.com/vbenjs/vue-vben-admin/issues/3671)) ([3d733de](https://github.com/vbenjs/vue-vben-admin/commit/3d733de3995a667782fa3219a0e0b171327c5b6f))
|
||||
- **ApiSelect:** BasicForm emit ield-value-change twice ([0f2c2ea](https://github.com/vbenjs/vue-vben-admin/commit/0f2c2eabd671af457febbb16fa3996c845bae145))
|
||||
- **ApiSelect:** Incorrect value type definition. close [#3168](https://github.com/vbenjs/vue-vben-admin/issues/3168) ([0cf79d4](https://github.com/vbenjs/vue-vben-admin/commit/0cf79d4ce2786e71444d4d9483ed77a99f57169c))
|
||||
- **ApiSelect:** type warning ([8f6153f](https://github.com/vbenjs/vue-vben-admin/commit/8f6153fd2a73b9537e7f9ba0f2326388745bc232))
|
||||
- ApiTransfer 不支持disabled ([#3149](https://github.com/vbenjs/vue-vben-admin/issues/3149)) ([95ca2c3](https://github.com/vbenjs/vue-vben-admin/commit/95ca2c3ae6085d97f24546e24117ee2518f33e2d))
|
||||
- **ApiTree:** 多触发一次onchange ([882270d](https://github.com/vbenjs/vue-vben-admin/commit/882270d5baff92eb8f51ccb80758c68ef8babe51))
|
||||
- **ApiTree:** Modify Trigger Selection Event Name ([094a33c](https://github.com/vbenjs/vue-vben-admin/commit/094a33c0c2511816079c935eb83e60ad93c9289c))
|
||||
- async validator ([#3194](https://github.com/vbenjs/vue-vben-admin/issues/3194)) ([405ef9e](https://github.com/vbenjs/vue-vben-admin/commit/405ef9e2b3e61bd6195b58996504b9cb3939ef6f))
|
||||
- **BackTop:** repair BackTup comp ([#3581](https://github.com/vbenjs/vue-vben-admin/issues/3581)) ([6f4bdae](https://github.com/vbenjs/vue-vben-admin/commit/6f4bdae5c2a5455cb924e1903612f9fe96cf4481))
|
||||
- basemodal 无法透传 attributes 至 Modal.tsx ([#3637](https://github.com/vbenjs/vue-vben-admin/issues/3637)) ([89830ec](https://github.com/vbenjs/vue-vben-admin/commit/89830ec7e69a7cab55e6ccf90b74377bcbadf44c))
|
||||
- **BasicDrawer:** remove toRaw props ([#3399](https://github.com/vbenjs/vue-vben-admin/issues/3399)) ([57e6e4f](https://github.com/vbenjs/vue-vben-admin/commit/57e6e4f00435637c545c58de3cd84c102003032a))
|
||||
- **BasicForm->ApiRadioGroup:** when options click, duplicate requests. resolve [#3387](https://github.com/vbenjs/vue-vben-admin/issues/3387) ([fdde6f0](https://github.com/vbenjs/vue-vben-admin/commit/fdde6f06b2d388bbdcc7f0de2b5419593cd686c3))
|
||||
- **BasicForm->FormItem:** model should update before event call ([#3573](https://github.com/vbenjs/vue-vben-admin/issues/3573)). resolve [#3570](https://github.com/vbenjs/vue-vben-admin/issues/3570) ([43aa743](https://github.com/vbenjs/vue-vben-admin/commit/43aa7430324a7f390c31ea9e8a2f1e00fad8a1d0))
|
||||
- **BasicForm:** 修复 useComponentRegister 方法无法添加自定义的组件,添加时爆类型错误的问题 ([#3483](https://github.com/vbenjs/vue-vben-admin/issues/3483)) ([98e2e4c](https://github.com/vbenjs/vue-vben-admin/commit/98e2e4c89a859e67c911134652d4b005be51e2d1))
|
||||
- **BasicForm:** script setup defineExpose ([#3316](https://github.com/vbenjs/vue-vben-admin/issues/3316)) ([f58ef67](https://github.com/vbenjs/vue-vben-admin/commit/f58ef6777c4dd8ac905919637410ea5373eb770b))
|
||||
- **BasicForm:** type instantiation is excessively deep and possibly infinite. ([#3128](https://github.com/vbenjs/vue-vben-admin/issues/3128)) ([5a388be](https://github.com/vbenjs/vue-vben-admin/commit/5a388be15e44d86c87d76dc8829a5286ac1818e0))
|
||||
- **BasicForm:** useForm 中 scheme 选项 slot 与 component冲突 ([#3133](https://github.com/vbenjs/vue-vben-admin/issues/3133)) ([0bb76a8](https://github.com/vbenjs/vue-vben-admin/commit/0bb76a86d25cbd1de1c672f5cc5e63d0ae478b68))
|
||||
- **BasicForm:** validate Form tip height ([#3286](https://github.com/vbenjs/vue-vben-admin/issues/3286)). close [#3281](https://github.com/vbenjs/vue-vben-admin/issues/3281) ([100f3cf](https://github.com/vbenjs/vue-vben-admin/commit/100f3cf26c2b124bf94f3bb4913dd3d6d15aed3e))
|
||||
- **BasicModal:** 修复BasicModal添加wrapClassName样式异常问题 ([#3726](https://github.com/vbenjs/vue-vben-admin/issues/3726)) ([13b031e](https://github.com/vbenjs/vue-vben-admin/commit/13b031eef9b8d4e8333c9397ff26e4875bf9816a))
|
||||
- **BasicTable->rowKey&scroll:** declear and usage about rowKey and scroll ([#3541](https://github.com/vbenjs/vue-vben-admin/issues/3541)) ([e23e338](https://github.com/vbenjs/vue-vben-admin/commit/e23e3383dd73b20a479977d29bab999c51334a1a))
|
||||
- **BasicTable->useColumns:** handle deep colunm hidden ([#3561](https://github.com/vbenjs/vue-vben-admin/issues/3561)) resolve [#3559](https://github.com/vbenjs/vue-vben-admin/issues/3559) ([54af5bb](https://github.com/vbenjs/vue-vben-admin/commit/54af5bb42ddd04a56a7da3becf325dd9cfbccc48))
|
||||
- **BasicTable:** 滑动表格内容合计行不跟随滑动bug ([#3438](https://github.com/vbenjs/vue-vben-admin/issues/3438)) resolve [#2166](https://github.com/vbenjs/vue-vben-admin/issues/2166) ([7ba83e7](https://github.com/vbenjs/vue-vben-admin/commit/7ba83e71bf718b6c896eac892f3b66cd266747af))
|
||||
- **BasicTable:** 修复BasicTable数据为空时,重置后高度不能自适应问题 ([#3724](https://github.com/vbenjs/vue-vben-admin/issues/3724)) ([6054fa2](https://github.com/vbenjs/vue-vben-admin/commit/6054fa2ffac7ff0206a4e0138da16a548d2d25a2))
|
||||
- **BasicTable:** avoid select when edit cell ([#3484](https://github.com/vbenjs/vue-vben-admin/issues/3484)) ([2f921cf](https://github.com/vbenjs/vue-vben-admin/commit/2f921cfb88b969fb8bd361c46ddf2f41a9e363b0))
|
||||
- **BasicTable:** BasicTable resize wrong in modal ([#3549](https://github.com/vbenjs/vue-vben-admin/issues/3549)) ([a121b32](https://github.com/vbenjs/vue-vben-admin/commit/a121b32252cf4b0570c937a1ab86d8b924b229ce))
|
||||
- **BasicTable:** column setting about action fixed and default not cache ([#3441](https://github.com/vbenjs/vue-vben-admin/issues/3441)) ([86ecb27](https://github.com/vbenjs/vue-vben-admin/commit/86ecb2729ef15bb0bb3fc7347a84ffa83487eec8))
|
||||
- **BasicTable:** ColumnSetting about selectedRowKeys override ([#3446](https://github.com/vbenjs/vue-vben-admin/issues/3446)) ([65122ea](https://github.com/vbenjs/vue-vben-admin/commit/65122ea1a52e2f06463dc15f7ee06aba4e29d104))
|
||||
- **BasicTable:** ColumnSetting mistake when use setColumns ([#3408](https://github.com/vbenjs/vue-vben-admin/issues/3408)) ([fec67b4](https://github.com/vbenjs/vue-vben-admin/commit/fec67b4d53ce82d156f4683f2c436f31dd3b4f7a))
|
||||
- **BasicTable:** getSelectRows return duplicate records ([#3545](https://github.com/vbenjs/vue-vben-admin/issues/3545)) ([974c1fa](https://github.com/vbenjs/vue-vben-admin/commit/974c1fad7fb2767429eeb50680cbae8e17b80f1f))
|
||||
- **BasicTable:** headerCell slot title not exist ([8df2590](https://github.com/vbenjs/vue-vben-admin/commit/8df2590aae8d646880e8c064e6b4ba48cb54086d))
|
||||
- **BasicTable:** index still show when set showIndexColumn false ([#3455](https://github.com/vbenjs/vue-vben-admin/issues/3455)) ([75f5b7a](https://github.com/vbenjs/vue-vben-admin/commit/75f5b7ac4dda840ce0098ed528e0b161d99d9b09))
|
||||
- **BasicTable:** keep rowSelection onChange call outside ([#3461](https://github.com/vbenjs/vue-vben-admin/issues/3461)). resolve [#3453](https://github.com/vbenjs/vue-vben-admin/issues/3453) ([a7b2f14](https://github.com/vbenjs/vue-vben-admin/commit/a7b2f14b900771186ee126cf60e8841ecc0cb8c1))
|
||||
- **BasicTable:** pagination exceeds page height. close [#3185](https://github.com/vbenjs/vue-vben-admin/issues/3185) ([41451f4](https://github.com/vbenjs/vue-vben-admin/commit/41451f4fa3495be1d1ea4088cad77322dcde57de))
|
||||
- **BasicTable:** ref table ([#3327](https://github.com/vbenjs/vue-vben-admin/issues/3327)) ([c8744a0](https://github.com/vbenjs/vue-vben-admin/commit/c8744a057e0da407ab929c91b46e638d196d82cc))
|
||||
- **BasicTable:** selection wrong by click input when cross pages ([#3540](https://github.com/vbenjs/vue-vben-admin/issues/3540)). resolve [#3539](https://github.com/vbenjs/vue-vben-admin/issues/3539) ([69c3602](https://github.com/vbenjs/vue-vben-admin/commit/69c36021fa5558097c4fc7b9f63e29816e478cb9))
|
||||
- **BasicTable:** showIndexColumn/showRowSelection cache should by route name ([#3489](https://github.com/vbenjs/vue-vben-admin/issues/3489)) ([d88f455](https://github.com/vbenjs/vue-vben-admin/commit/d88f455cd3530cd7cc7450e8f0fe7744ca0cb313))
|
||||
- **BasicTable:** table表格宽度自适应,隐藏的列导致宽度增加 ([#3388](https://github.com/vbenjs/vue-vben-admin/issues/3388)) ([bca5154](https://github.com/vbenjs/vue-vben-admin/commit/bca5154a9d3d020a70cd332ac19c853ea94405e2))
|
||||
- **BasicTree:** not inherit slot and not show icon slot. close [#1902](https://github.com/vbenjs/vue-vben-admin/issues/1902) ([a0b2a9e](https://github.com/vbenjs/vue-vben-admin/commit/a0b2a9e949dbf1e149da8be757f78fa6b1cebec0))
|
||||
- breadcrumb is displayed despite the menu being hidden ([#3733](https://github.com/vbenjs/vue-vben-admin/issues/3733)) ([e8a86ec](https://github.com/vbenjs/vue-vben-admin/commit/e8a86ec8b996387c9c2d167344eb1e7a010d94fb)), closes [#3690](https://github.com/vbenjs/vue-vben-admin/issues/3690)
|
||||
- **breadcrumb:** 修复面包屑跳转外链时,导致当前页面404问题 ([#3337](https://github.com/vbenjs/vue-vben-admin/issues/3337)). close [#3336](https://github.com/vbenjs/vue-vben-admin/issues/3336) ([895352a](https://github.com/vbenjs/vue-vben-admin/commit/895352ad221f91bdb57fdfd0396925fb7901c2df))
|
||||
- breakpoint ([#3242](https://github.com/vbenjs/vue-vben-admin/issues/3242)) ([b6f8379](https://github.com/vbenjs/vue-vben-admin/commit/b6f8379e936df3743c5b9514e88a02148b08a5d1))
|
||||
- bug RangePicker with componentProps valueFormat ('YYYY-MM-DD') does not return the formatted value when using form validate() method [#3690](https://github.com/vbenjs/vue-vben-admin/issues/3690) ([#3691](https://github.com/vbenjs/vue-vben-admin/issues/3691)) ([09f795e](https://github.com/vbenjs/vue-vben-admin/commit/09f795e00ed8d56d6b1e028fc40974d3292eed5f))
|
||||
- change salesProductPie.vue's data name to '成交占比'. ([#3524](https://github.com/vbenjs/vue-vben-admin/issues/3524)) ([0589458](https://github.com/vbenjs/vue-vben-admin/commit/0589458b2d120b5c6ee0ab10cd8b2d3f13318911))
|
||||
- checkedKeys use unref bug ([#3198](https://github.com/vbenjs/vue-vben-admin/issues/3198)) ([ae61fa1](https://github.com/vbenjs/vue-vben-admin/commit/ae61fa11865b2d7b0337b1fd2edcb20bf559a71f))
|
||||
- **ci:** update node version for linter ([a5565bf](https://github.com/vbenjs/vue-vben-admin/commit/a5565bf9cf361e38057d8ca34fe2542ea1c39873))
|
||||
- **ci:** update use pnpm version for deploy ([83455a0](https://github.com/vbenjs/vue-vben-admin/commit/83455a07a0821142864b4668d89a51057d74330b))
|
||||
- column setting index column sort ([#3463](https://github.com/vbenjs/vue-vben-admin/issues/3463)) ([fc002d3](https://github.com/vbenjs/vue-vben-admin/commit/fc002d3db327a432259eb02e2a72b9b81381eb6e))
|
||||
- **component->markdown:** 浏览器媒体获取兼容 ([#3470](https://github.com/vbenjs/vue-vben-admin/issues/3470)) ([f0ca8d5](https://github.com/vbenjs/vue-vben-admin/commit/f0ca8d5a03e994c9948b055dc5f69dad40d96922))
|
||||
- **component:** insertNextAt is not a function ([#3656](https://github.com/vbenjs/vue-vben-admin/issues/3656)) ([#3657](https://github.com/vbenjs/vue-vben-admin/issues/3657)) ([c827ffb](https://github.com/vbenjs/vue-vben-admin/commit/c827ffb8e680df13dae0c75b19634b6474aa5897))
|
||||
- **component:** resolve the defaultValue error in setting the date type ([#3652](https://github.com/vbenjs/vue-vben-admin/issues/3652)) ([d42acb4](https://github.com/vbenjs/vue-vben-admin/commit/d42acb477c577c0f855403bff371e0780e630cdc)), closes [#3651](https://github.com/vbenjs/vue-vben-admin/issues/3651)
|
||||
- **component:** resolve the error when clicking on a row when clickRowToExpand is true ([#3714](https://github.com/vbenjs/vue-vben-admin/issues/3714)) ([38d58ab](https://github.com/vbenjs/vue-vben-admin/commit/38d58ab47af3611cebade960dbcbd60f165f3a72))
|
||||
- **component:** resolve the issue of "vxe-table" export function not being able to be used ([#3646](https://github.com/vbenjs/vue-vben-admin/issues/3646)) ([bc5e5fa](https://github.com/vbenjs/vue-vben-admin/commit/bc5e5fa015f8c5f1d69f3f8572a1957d83cfe44e)), closes [#3614](https://github.com/vbenjs/vue-vben-admin/issues/3614)
|
||||
- **component:** resovle fullscreen content issues with "fixedHeight" and "contentFullHeight" combined ([#3721](https://github.com/vbenjs/vue-vben-admin/issues/3721)) ([212e78f](https://github.com/vbenjs/vue-vben-admin/commit/212e78fa76132b4239e81d3432f7f3c15d7e5254))
|
||||
- **components->Upload:** 修复文件上传过程中删除文件终止上传时,上传状态未改变不能关闭Modal的bug ([#3761](https://github.com/vbenjs/vue-vben-admin/issues/3761)) ([04d4c5c](https://github.com/vbenjs/vue-vben-admin/commit/04d4c5cd665f52cb287b5059b301e71aed75b3df))
|
||||
- **config:** vite:html warning ([#3518](https://github.com/vbenjs/vue-vben-admin/issues/3518)) ([6978517](https://github.com/vbenjs/vue-vben-admin/commit/6978517a3a0b522a466fc248d0ed4384cdcfecb7))
|
||||
- content fixed mode with blank page ([#3523](https://github.com/vbenjs/vue-vben-admin/issues/3523)) ([49fdb6c](https://github.com/vbenjs/vue-vben-admin/commit/49fdb6c986f36e45fc9f9e206af371f8eb3581f6))
|
||||
- contextmenu location not right when body with scroll ([#3516](https://github.com/vbenjs/vue-vben-admin/issues/3516)) ([c2c9f4f](https://github.com/vbenjs/vue-vben-admin/commit/c2c9f4f556d65eb768a5202a398dc9684c08d577))
|
||||
- Correct spelling error in comments ([#3678](https://github.com/vbenjs/vue-vben-admin/issues/3678)) ([54f8584](https://github.com/vbenjs/vue-vben-admin/commit/54f85844436d95ce290a2f3b5db5b7c4fd14cc0d))
|
||||
- **CropperAvatar:** wrong type about the prop size ([#3635](https://github.com/vbenjs/vue-vben-admin/issues/3635)) ([aef90aa](https://github.com/vbenjs/vue-vben-admin/commit/aef90aa2a0b43c3fc72596d9aecf408a594cb6fd))
|
||||
- **CropperModal:** beforeUpload should return false ([#3601](https://github.com/vbenjs/vue-vben-admin/issues/3601)) ([b6bcf8d](https://github.com/vbenjs/vue-vben-admin/commit/b6bcf8d36dc348af7b51782e43c09c5e1cfeed68))
|
||||
- **customExport:** Failure to export ([#3137](https://github.com/vbenjs/vue-vben-admin/issues/3137)) ([4d02205](https://github.com/vbenjs/vue-vben-admin/commit/4d02205839aad840bbb247b26b7e1dcdbc8b3a67))
|
||||
- **dark:** fix --text-color light color not work ([#3228](https://github.com/vbenjs/vue-vben-admin/issues/3228)) ([2e632e4](https://github.com/vbenjs/vue-vben-admin/commit/2e632e4d4d8af4b8766396b340f9996832310853))
|
||||
- **DatePicker:** date show is wrong and setup script defineExpose ([#3324](https://github.com/vbenjs/vue-vben-admin/issues/3324)) ([f62043b](https://github.com/vbenjs/vue-vben-admin/commit/f62043b1fca82234e04aa04629ba4bbcc624b0ee))
|
||||
- **DatePicker:** zh-CN is not work in DatePicker ([#3273](https://github.com/vbenjs/vue-vben-admin/issues/3273)) ([6d047fb](https://github.com/vbenjs/vue-vben-admin/commit/6d047fb53fb113a4c6fc5c46c5b4195e50744eb0))
|
||||
- defaultValue类型为number时的bug ([#3288](https://github.com/vbenjs/vue-vben-admin/issues/3288)) ([3b2760c](https://github.com/vbenjs/vue-vben-admin/commit/3b2760ca3ae5b51989ea7e97713f629a567fe53a))
|
||||
- **demo->customerForm:** FormItem下有多个受控组件控制台显示错误提示的bug ([#3238](https://github.com/vbenjs/vue-vben-admin/issues/3238)) ([ec646c5](https://github.com/vbenjs/vue-vben-admin/commit/ec646c57b8c2d365f5ce298c496e1efaad8456b7))
|
||||
- **demo:** 修复引导页文件名问题 ([#3352](https://github.com/vbenjs/vue-vben-admin/issues/3352)) ([be935eb](https://github.com/vbenjs/vue-vben-admin/commit/be935eb44e363665b99288f78f03cb3053274200))
|
||||
- **demo:** 修复form demo的远程搜索不会触发的bug ([#3770](https://github.com/vbenjs/vue-vben-admin/issues/3770)) ([44b1877](https://github.com/vbenjs/vue-vben-admin/commit/44b1877eaedca1716aa40b8d819d5fe7cbd26ba0))
|
||||
- **demo:** account page table without dept ([#3164](https://github.com/vbenjs/vue-vben-admin/issues/3164)) ([40aac65](https://github.com/vbenjs/vue-vben-admin/commit/40aac6544cb9b22e2362f2a2d99c0a9cc2f7fb57))
|
||||
- **demo:** useForm中DatePicker,RangePicker 日期控件位置不对 ([ae58ada](https://github.com/vbenjs/vue-vben-admin/commit/ae58ada82e2f62cea8e89a18c9f2ab18d6dba52a))
|
||||
- **dept:** no parentDept can edit parentDept ([#3255](https://github.com/vbenjs/vue-vben-admin/issues/3255)) ([2142506](https://github.com/vbenjs/vue-vben-admin/commit/2142506ce5225dbe19118fcedb2cb48612c58fa7))
|
||||
- Docker 打包逻辑改进,彻底解决缓存问题 ([#3473](https://github.com/vbenjs/vue-vben-admin/issues/3473)) ([dcbe551](https://github.com/vbenjs/vue-vben-admin/commit/dcbe5510d42c3dc5e93b68704a5fa24c88d4de69))
|
||||
- EditableCell about checked/unChecked Value, getDisable, rowKey missing for updating ([#3418](https://github.com/vbenjs/vue-vben-admin/issues/3418)). resolve [#3419](https://github.com/vbenjs/vue-vben-admin/issues/3419) ([404a472](https://github.com/vbenjs/vue-vben-admin/commit/404a4720b016abb6da93cb0b03271ebea6cca976))
|
||||
- **EditCellTable:** 表格编辑行在使用Switch,checkedValue为数字时无法切换开关.close [#2560](https://github.com/vbenjs/vue-vben-admin/issues/2560) ([71c4394](https://github.com/vbenjs/vue-vben-admin/commit/71c43945a5e95fda6daddbb90af51f6d149547f5))
|
||||
- **Editor:** ts类型错误 ([8b13f62](https://github.com/vbenjs/vue-vben-admin/commit/8b13f62995cb7f080eabf2e22d530959d4b79e0b))
|
||||
- Failed to resolve component EllipsisText ([#3330](https://github.com/vbenjs/vue-vben-admin/issues/3330)) ([42e9de5](https://github.com/vbenjs/vue-vben-admin/commit/42e9de50a2bb150556a0eb8098acb2d2d3662c3c))
|
||||
- FormItem won't render when a component is not provided ([9e055ad](https://github.com/vbenjs/vue-vben-admin/commit/9e055ad2734819c2778c0db1990e69b67c95022f))
|
||||
- **FormItem:** use getPopupContainer default value ([#3215](https://github.com/vbenjs/vue-vben-admin/issues/3215)) ([ed267d9](https://github.com/vbenjs/vue-vben-admin/commit/ed267d9c016e50b4d9a7886209bad2432a88ad9b))
|
||||
- **FormTable:** Invert select bug ([#3412](https://github.com/vbenjs/vue-vben-admin/issues/3412)) ([595b1ce](https://github.com/vbenjs/vue-vben-admin/commit/595b1ce680d8b315589d98036a70333055123b18))
|
||||
- **full-screen:** dom fullscreen status text ([#3130](https://github.com/vbenjs/vue-vben-admin/issues/3130)) ([e161c14](https://github.com/vbenjs/vue-vben-admin/commit/e161c1449ac3d097cd6eab9441b25de25d3aa27e))
|
||||
- fullscreen-modal width wrong ([#3321](https://github.com/vbenjs/vue-vben-admin/issues/3321)) ([617b013](https://github.com/vbenjs/vue-vben-admin/commit/617b01338cf4a8d88da529dae7da878b52b30c3b))
|
||||
- handleFormValues 不再将所有空字符串转换为undefined ([#3496](https://github.com/vbenjs/vue-vben-admin/issues/3496)) ([6fbb576](https://github.com/vbenjs/vue-vben-admin/commit/6fbb57621e6ff79f93830969ab388549cbec5d32))
|
||||
- **koa->upload:** fix the error that occurs when uploading files in the `test server` of Koa. ([#3698](https://github.com/vbenjs/vue-vben-admin/issues/3698)) ([954f04f](https://github.com/vbenjs/vue-vben-admin/commit/954f04f1c8e941e45c2bd4ab55df331ba13cb89c))
|
||||
- **layout->menu:** can`t hover when menu is colappsed ([#3499](https://github.com/vbenjs/vue-vben-admin/issues/3499)) resolve [#3492](https://github.com/vbenjs/vue-vben-admin/issues/3492) ([7ffe172](https://github.com/vbenjs/vue-vben-admin/commit/7ffe1726b9ac0ac1f90c20b53996636f31af5c31))
|
||||
- **layout->user-dropdown:** resolve warning "Invalid prop name: key is a reserved property" ([#3640](https://github.com/vbenjs/vue-vben-admin/issues/3640)) ([eae68bb](https://github.com/vbenjs/vue-vben-admin/commit/eae68bb029864d5f1af4e0c6b57038d0c96e4faf)), closes [#3639](https://github.com/vbenjs/vue-vben-admin/issues/3639)
|
||||
- **layout:** 修复切换导航栏模式,分割菜单的状态不同步,导致页面内容区域存在被遮挡的问题 ([#3519](https://github.com/vbenjs/vue-vben-admin/issues/3519)) ([50276cb](https://github.com/vbenjs/vue-vben-admin/commit/50276cb60275d15c2d370c5a1be2705067c7b275))
|
||||
- **LayoutSidre:** resolve the breakpoint conflict. resolve [#3605](https://github.com/vbenjs/vue-vben-admin/issues/3605) ([1a7ae0e](https://github.com/vbenjs/vue-vben-admin/commit/1a7ae0e81071876fe6a5cf2ef00bb61cbca70736))
|
||||
- **LockModal:** Cannot unlock ([#3143](https://github.com/vbenjs/vue-vben-admin/issues/3143)) ([cdac147](https://github.com/vbenjs/vue-vben-admin/commit/cdac147bc8d09fba6ac14ff1ed31ab4d5b5cb28b))
|
||||
- **Login:** avoid infinite loop when query redirect to next route redirect ([#3630](https://github.com/vbenjs/vue-vben-admin/issues/3630)). resolve [#3620](https://github.com/vbenjs/vue-vben-admin/issues/3620) [#3627](https://github.com/vbenjs/vue-vben-admin/issues/3627) ([ab55cbf](https://github.com/vbenjs/vue-vben-admin/commit/ab55cbf99bd9891f10546176e203eb4ea8cafaa4))
|
||||
- **Menu:** tab标签切换选中状态焦点重复. fix [#1681](https://github.com/vbenjs/vue-vben-admin/issues/1681) ([2ec5f63](https://github.com/vbenjs/vue-vben-admin/commit/2ec5f6322d036ea5d6968c16961d2c253e1cef06))
|
||||
- **menu:** top menu and breadcrumb show wrong ([#3703](https://github.com/vbenjs/vue-vben-admin/issues/3703)) ([573fd53](https://github.com/vbenjs/vue-vben-admin/commit/573fd53b4e287524ffa6ec205b68812b657dde71))
|
||||
- modal open logic missing ([#3462](https://github.com/vbenjs/vue-vben-admin/issues/3462)) ([cc97f06](https://github.com/vbenjs/vue-vben-admin/commit/cc97f0635438c102b97102a1e0a9d5550961d6fa))
|
||||
- **Modal:** 修复BasicModal跟原生Modal样式冲突问题 ([#3720](https://github.com/vbenjs/vue-vben-admin/issues/3720)) ([ade6d4c](https://github.com/vbenjs/vue-vben-admin/commit/ade6d4c22dd62aa666fe934a747e2a3764feb7cd))
|
||||
- modalElIterator可能为空,导致报错 ([#3738](https://github.com/vbenjs/vue-vben-admin/issues/3738)) ([162a0d0](https://github.com/vbenjs/vue-vben-admin/commit/162a0d025252ff954f081d126c381e5fefd06e83))
|
||||
- navigator.clipboard 兼容问题 [#3372](https://github.com/vbenjs/vue-vben-admin/issues/3372) ([#3403](https://github.com/vbenjs/vue-vben-admin/issues/3403)) ([d3600da](https://github.com/vbenjs/vue-vben-admin/commit/d3600daf5c55cc884f4a0311ee7335bdad529a1a))
|
||||
- **PageWrapper:** 修复headerSticky样式 ([#3569](https://github.com/vbenjs/vue-vben-admin/issues/3569)) ([778ebe1](https://github.com/vbenjs/vue-vben-admin/commit/778ebe1f44bc4929f34fad41b5fec13e9270b517))
|
||||
- **PopConfirmButton:** avoid type lint error ([#3600](https://github.com/vbenjs/vue-vben-admin/issues/3600)) ([5ec4446](https://github.com/vbenjs/vue-vben-admin/commit/5ec444644384c6a1b8d559e0e21dfa814e5af635))
|
||||
- remove duplicate code ([#3674](https://github.com/vbenjs/vue-vben-admin/issues/3674)) ([c33ee66](https://github.com/vbenjs/vue-vben-admin/commit/c33ee66473159a0322b7c4489538dd5309587e45))
|
||||
- repair login about redirect query ([#3592](https://github.com/vbenjs/vue-vben-admin/issues/3592)) ([236ddf3](https://github.com/vbenjs/vue-vben-admin/commit/236ddf3471a7851ff6541f5709e9cbb6105b58f7))
|
||||
- resolve conflicts between eslint and prettier and bump prettier-plugin-packagejson version to 2.4.6([#3328](https://github.com/vbenjs/vue-vben-admin/issues/3328)) ([8a00070](https://github.com/vbenjs/vue-vben-admin/commit/8a000705d1c89194647a11d01a620c1a893d2643))
|
||||
- **router:** resolve menu loading failure when permission is in "role mode" ([#3660](https://github.com/vbenjs/vue-vben-admin/issues/3660)) ([c7631fe](https://github.com/vbenjs/vue-vben-admin/commit/c7631fed681da0dd51583cf3ecba60ebfd76ec4d)), closes [#3655](https://github.com/vbenjs/vue-vben-admin/issues/3655)
|
||||
- **router:** resolve the next function being called twice ([#3643](https://github.com/vbenjs/vue-vben-admin/issues/3643)) ([7ec9344](https://github.com/vbenjs/vue-vben-admin/commit/7ec9344be8e80899749f41d173c1a11db267354e)), closes [#3642](https://github.com/vbenjs/vue-vben-admin/issues/3642)
|
||||
- **router:** the issue of blank page navigation during repair of non-LAYOUT first-level route component ([#3764](https://github.com/vbenjs/vue-vben-admin/issues/3764)) ([c58c192](https://github.com/vbenjs/vue-vben-admin/commit/c58c1929c1e8a41c15ff2f4f4398eba0fd375b69))
|
||||
- scroll back to top when tab switch ([#3498](https://github.com/vbenjs/vue-vben-admin/issues/3498)). resolve [#3490](https://github.com/vbenjs/vue-vben-admin/issues/3490) ([d709dd6](https://github.com/vbenjs/vue-vben-admin/commit/d709dd67b50a2e2b88cbcce48f19085ce528f971))
|
||||
- scrollbar is obscured ([#3331](https://github.com/vbenjs/vue-vben-admin/issues/3331)) ([3f65baf](https://github.com/vbenjs/vue-vben-admin/commit/3f65baf503bee677bde70535525ae514d0585d69))
|
||||
- ScrollContainer的一个问题 [#3046](https://github.com/vbenjs/vue-vben-admin/issues/3046) ([#3119](https://github.com/vbenjs/vue-vben-admin/issues/3119)) ([aa03c87](https://github.com/vbenjs/vue-vben-admin/commit/aa03c87383c703ddce7759bd7ba114709f2f5241))
|
||||
- **ScrollContainer:** enable x scroll ([#3564](https://github.com/vbenjs/vue-vben-admin/issues/3564)) ([a1e862b](https://github.com/vbenjs/vue-vben-admin/commit/a1e862bde7a29420fd1de6083c5bde02bef8e9fd))
|
||||
- **SimpleMenuTag:** SimpleMenuTag的引用都改为动态组件引用,以消除打包警告.close [#3121](https://github.com/vbenjs/vue-vben-admin/issues/3121) ([6e33c26](https://github.com/vbenjs/vue-vben-admin/commit/6e33c268930ad2a99311f0f2b6eb4b90f3cf61ce))
|
||||
- **StrengthMeter:** change事件应随handleChange一起抛出。close [#3118](https://github.com/vbenjs/vue-vben-admin/issues/3118) ([f5ce480](https://github.com/vbenjs/vue-vben-admin/commit/f5ce480f0fb2f97de57e26a01945b715938f6e18))
|
||||
- **style:** 修复黑暗模式下弹框、demo目录下、按钮样式问题 ([#3208](https://github.com/vbenjs/vue-vben-admin/issues/3208)) ([06a6c94](https://github.com/vbenjs/vue-vben-admin/commit/06a6c947a980530be6654f05357bc3c721c1140b))
|
||||
- tabel取消编辑单元格后会回到初始值. close [#2739](https://github.com/vbenjs/vue-vben-admin/issues/2739) ([#3108](https://github.com/vbenjs/vue-vben-admin/issues/3108)) ([9864305](https://github.com/vbenjs/vue-vben-admin/commit/986430513bc2da9a2ad88d40c026b0373bf22d07))
|
||||
- table height calc when fullcontent and footer visible change ([#3392](https://github.com/vbenjs/vue-vben-admin/issues/3392)) ([20698c0](https://github.com/vbenjs/vue-vben-admin/commit/20698c052c2b696587ac77ba7c85d74abc974ed5))
|
||||
- table index column width is not enough in english ([#3342](https://github.com/vbenjs/vue-vben-admin/issues/3342)) ([0f13758](https://github.com/vbenjs/vue-vben-admin/commit/0f137585542ee2cf3b542a4ca4d94e76aadfb3d0))
|
||||
- TableAction设置icon显示iconify关键字 ([#3608](https://github.com/vbenjs/vue-vben-admin/issues/3608)) ([b233973](https://github.com/vbenjs/vue-vben-admin/commit/b2339739746740eaaf4adee3ef16757f3b05ec86))
|
||||
- **test-server:** test-server can not lanuch ([#3554](https://github.com/vbenjs/vue-vben-admin/issues/3554)) ([e679704](https://github.com/vbenjs/vue-vben-admin/commit/e6797043c53abb8280ff9c86e32663450a650076))
|
||||
- **tree:** remove expandedKeys prop default value ([#3184](https://github.com/vbenjs/vue-vben-admin/issues/3184)) ([92875cb](https://github.com/vbenjs/vue-vben-admin/commit/92875cbeccf6213bcad9acd4e322cdee59e35266))
|
||||
- turbo run lint ([#3332](https://github.com/vbenjs/vue-vben-admin/issues/3332)) ([064922d](https://github.com/vbenjs/vue-vben-admin/commit/064922dd4c3ae674a463e4b9453a4ca8bf2a52a0)), closes [#3277](https://github.com/vbenjs/vue-vben-admin/issues/3277)
|
||||
- **type:** type:check error ([#3309](https://github.com/vbenjs/vue-vben-admin/issues/3309)) ([2cd5a40](https://github.com/vbenjs/vue-vben-admin/commit/2cd5a40322e9b7946e789d7c5023fda0e712af4d))
|
||||
- typo in locale ([#3659](https://github.com/vbenjs/vue-vben-admin/issues/3659)) ([a4cc1d5](https://github.com/vbenjs/vue-vben-admin/commit/a4cc1d53169bc26e01862ca4ff88e28d5329ab8f))
|
||||
- typo substract -> subtract ([#3551](https://github.com/vbenjs/vue-vben-admin/issues/3551)) ([f3fbb57](https://github.com/vbenjs/vue-vben-admin/commit/f3fbb57dc944a11a06be2eff376d77f9cef29813))
|
||||
- **typo:** fileservice class name ([#3625](https://github.com/vbenjs/vue-vben-admin/issues/3625)) ([b794469](https://github.com/vbenjs/vue-vben-admin/commit/b7944690d118377a32e694fa30081b1e43c71719))
|
||||
- Update TableAction.vue ([#3619](https://github.com/vbenjs/vue-vben-admin/issues/3619)) ([76ffd8f](https://github.com/vbenjs/vue-vben-admin/commit/76ffd8fdf1ecc37a30f33c901ff199ba21f88ad4))
|
||||
- **Upload:** The file name is too long bug ([#3182](https://github.com/vbenjs/vue-vben-admin/issues/3182)) ([e7fbd74](https://github.com/vbenjs/vue-vben-admin/commit/e7fbd742287928112b318bf966e57c74f6a8ee72))
|
||||
- **useFormEvent:** 修复表单项存在defaultValue时,updateSchema方法会将setFieldsValue设置的值覆盖问题 ([#3287](https://github.com/vbenjs/vue-vben-admin/issues/3287)) ([72ef3df](https://github.com/vbenjs/vue-vben-admin/commit/72ef3df57fe978c0b8e185f0d632a59e128a390f))
|
||||
- **useFormEvents:** 修复setFieldsValue 方法设置完值后,函数 componentProps丢失formActionType 的bug ([#3301](https://github.com/vbenjs/vue-vben-admin/issues/3301)) ([82671d0](https://github.com/vbenjs/vue-vben-admin/commit/82671d07502adbaa06decbe0caa51ca2ba2e5149))
|
||||
- **util:** resolve executing retry even when HTTP status code is 401 ([#3756](https://github.com/vbenjs/vue-vben-admin/issues/3756)) ([3627402](https://github.com/vbenjs/vue-vben-admin/commit/36274025d6a19de978bcaaae3f0ddb42f31ecd2f))
|
||||
- validateFields await missing ([#3254](https://github.com/vbenjs/vue-vben-admin/issues/3254)) ([71c3fea](https://github.com/vbenjs/vue-vben-admin/commit/71c3fea88afa9209f080458bbd7429b1d37baa2c))
|
||||
- **VFormDesign:** findIndex === -1 ([#3305](https://github.com/vbenjs/vue-vben-admin/issues/3305)) ([d7472b8](https://github.com/vbenjs/vue-vben-admin/commit/d7472b8a2e480299888ffeac6ac95466b27afa0f))
|
||||
- **vxe-table:** theme dark is not work ([#3239](https://github.com/vbenjs/vue-vben-admin/issues/3239)) ([031d613](https://github.com/vbenjs/vue-vben-admin/commit/031d613b18125c877ebaa4a3241c3b4bf9c7624a))
|
||||
- watch open logic lost after build ([#3421](https://github.com/vbenjs/vue-vben-admin/issues/3421)) ([089a989](https://github.com/vbenjs/vue-vben-admin/commit/089a98953e01d6b7cb0003f33d321035e19311c5))
|
||||
|
||||
### Features
|
||||
|
||||
- 解决Form updateSchema后执行setProps导致schemaRef被重置的问题 ([#3354](https://github.com/vbenjs/vue-vben-admin/issues/3354)) ([b0e8154](https://github.com/vbenjs/vue-vben-admin/commit/b0e8154f9f23db71dba7302395cc7d3db4b4a339))
|
||||
- 新增表单只读功能 ([#3335](https://github.com/vbenjs/vue-vben-admin/issues/3335)) ([342328c](https://github.com/vbenjs/vue-vben-admin/commit/342328ce5f06b33dabdbd4a3bdd2c846f011eb03))
|
||||
- 修复 vxetable 实例中缺少的 getRefMaps 和 getComputeMaps 方法 ([#3361](https://github.com/vbenjs/vue-vben-admin/issues/3361)) ([2376e8f](https://github.com/vbenjs/vue-vben-admin/commit/2376e8f67d154fe902452c6c1af19248402602b7))
|
||||
- 增加文本省略组件 ([#3180](https://github.com/vbenjs/vue-vben-admin/issues/3180)) ([8722471](https://github.com/vbenjs/vue-vben-admin/commit/87224715c3983227866f148d858276c1234f77e0))
|
||||
- 支持设置多重水印,增加清除所有水印方法. close [#2610](https://github.com/vbenjs/vue-vben-admin/issues/2610) ([#3084](https://github.com/vbenjs/vue-vben-admin/issues/3084)) ([64b8128](https://github.com/vbenjs/vue-vben-admin/commit/64b812802f5ca053c8f0ae9c9f159cbfedb32d5d))
|
||||
- add pinia persist plugin ([#3173](https://github.com/vbenjs/vue-vben-admin/issues/3173)) ([2152b3f](https://github.com/vbenjs/vue-vben-admin/commit/2152b3f779b47f70e4442ff4c850db10048733d3))
|
||||
- **ApiTree:** 完善ApiTree组件的重置回显功能. close [#2307](https://github.com/vbenjs/vue-vben-admin/issues/2307) ([a0d4b10](https://github.com/vbenjs/vue-vben-admin/commit/a0d4b10a1f0f858925ce7fff3f9b686308fd3ada))
|
||||
- **BasicButton:** BasicButton组件支持icon插槽. close [#1377](https://github.com/vbenjs/vue-vben-admin/issues/1377) ([5aac032](https://github.com/vbenjs/vue-vben-admin/commit/5aac032acc294e087e45d5787cbae843d5a86f28))
|
||||
- **BasicForm:** 新增监听表单收缩方法传值进行判断 ([#3745](https://github.com/vbenjs/vue-vben-admin/issues/3745)) ([e9c6dd8](https://github.com/vbenjs/vue-vben-admin/commit/e9c6dd83b1b21bd46fbb7b16f159733761b49fd2))
|
||||
- **BasicForm:** Improve ts types for BasicForm ([#3426](https://github.com/vbenjs/vue-vben-admin/issues/3426)) ([6bb7918](https://github.com/vbenjs/vue-vben-admin/commit/6bb79180fc798b1a0b1a6c22f7c13ddb3a45a3b5))
|
||||
- **BasicTable:** 新增表格搜索获取参数的方法 ([#3715](https://github.com/vbenjs/vue-vben-admin/issues/3715)) ([de5f9e3](https://github.com/vbenjs/vue-vben-admin/commit/de5f9e304791ce131a589683282b42f77d10238c))
|
||||
- **BasicTable:** table enable accordion expand ([#3533](https://github.com/vbenjs/vue-vben-admin/issues/3533)). resolve [#3525](https://github.com/vbenjs/vue-vben-admin/issues/3525) ([abae7f3](https://github.com/vbenjs/vue-vben-admin/commit/abae7f3295846f10b69c591739bbec22d176b6fe))
|
||||
- **BasicTree:** BasicTree组件暴露treeData数据 ([caf1783](https://github.com/vbenjs/vue-vben-admin/commit/caf178352537650f603aca441386b377f7cf8821))
|
||||
- ColumnSetting and SizeSetting persist ([#3398](https://github.com/vbenjs/vue-vben-admin/issues/3398)) ([f4df2d5](https://github.com/vbenjs/vue-vben-admin/commit/f4df2d5a4bd23f346af10580e5ab7de64933bb4c))
|
||||
- **components->Upload:** 修正图片上传组件允许自定义上传格式限制 ([#3755](https://github.com/vbenjs/vue-vben-admin/issues/3755)) ([302e212](https://github.com/vbenjs/vue-vben-admin/commit/302e2125ba1c7e63e7db47ef6e1ee256da9f81d4))
|
||||
- **demo->BasicTable:** add TableSelectionBar and enable checkbox rowSelection demo ([#3477](https://github.com/vbenjs/vue-vben-admin/issues/3477)) ([816553b](https://github.com/vbenjs/vue-vben-admin/commit/816553bfcd5a88988c6e7b93cc3378f4a5b17fee))
|
||||
- **demo->useRequest:** 更新错误重试示例 ([#3456](https://github.com/vbenjs/vue-vben-admin/issues/3456)) ([7fa2578](https://github.com/vbenjs/vue-vben-admin/commit/7fa2578e6d578e7ab44793fcb2b41189a7ba9af3))
|
||||
- **demo->useRequest:** 更新useRequest 依赖 Effect 函数案例 ([#3460](https://github.com/vbenjs/vue-vben-admin/issues/3460)) ([b57d9fc](https://github.com/vbenjs/vue-vben-admin/commit/b57d9fc60dd113607cd381dff1f88c47671fc434))
|
||||
- **demo:** hooks useRequest 异步数据管理 ([#3447](https://github.com/vbenjs/vue-vben-admin/issues/3447)) ([d6d1120](https://github.com/vbenjs/vue-vben-admin/commit/d6d1120d00a24b7a97bd37f6a0786c1265fa870d))
|
||||
- **deps:** update vite version to 5.x ([#3508](https://github.com/vbenjs/vue-vben-admin/issues/3508)) ([e6c7b5f](https://github.com/vbenjs/vue-vben-admin/commit/e6c7b5f9282adbdd9429495d5918c1eafbffde7d))
|
||||
- fix ellipsis bug ([#3644](https://github.com/vbenjs/vue-vben-admin/issues/3644)) ([9372f1d](https://github.com/vbenjs/vue-vben-admin/commit/9372f1d159bb3236810e469defe6986b924d2264))
|
||||
- **Form:** 新增Transfer、CropperAvatar、BasicTitle 组件至Form中,并添加至演示页面 ([#3362](https://github.com/vbenjs/vue-vben-admin/issues/3362)) ([f6147fa](https://github.com/vbenjs/vue-vben-admin/commit/f6147fa44985d149692b5c6053a49b76d24767cc))
|
||||
- **Form:** 在Form将BasicTitle识做为Divider一样的处理 ([#3371](https://github.com/vbenjs/vue-vben-admin/issues/3371)) ([cd71e60](https://github.com/vbenjs/vue-vben-admin/commit/cd71e60dd16e87706deb2d06310bc507c55d6a99))
|
||||
- Form增加ImageUpload组件 ([#3172](https://github.com/vbenjs/vue-vben-admin/issues/3172)) ([b776ac4](https://github.com/vbenjs/vue-vben-admin/commit/b776ac4cd8a4895804b554949f39c82c03382006))
|
||||
- **hooks:** useWatermark添加水印防篡改功能([#3395](https://github.com/vbenjs/vue-vben-admin/issues/3395)) ([#3397](https://github.com/vbenjs/vue-vben-admin/issues/3397)) ([0a1a5ff](https://github.com/vbenjs/vue-vben-admin/commit/0a1a5ffedc58190529617c9267c6510dc7e17ca9))
|
||||
- **IconPicker:** IconPicker could allowClear and readonly for form ([#3414](https://github.com/vbenjs/vue-vben-admin/issues/3414)) ([e23f294](https://github.com/vbenjs/vue-vben-admin/commit/e23f29464bd609d6bc7228a5940032d693b006aa))
|
||||
- iframe expose postmessage function ([#3368](https://github.com/vbenjs/vue-vben-admin/issues/3368)) ([05bc4ac](https://github.com/vbenjs/vue-vben-admin/commit/05bc4acb9b2107bfad8200c0f1942a76367d7a00))
|
||||
- **input:** add auto-trimming for vxe-table input components ([#3684](https://github.com/vbenjs/vue-vben-admin/issues/3684)) ([9882e8d](https://github.com/vbenjs/vue-vben-admin/commit/9882e8df86cc68373cf0f1fa4f4aa04a9773825e))
|
||||
- **layout->tabs:** support insert new tab after current tab ([#3471](https://github.com/vbenjs/vue-vben-admin/issues/3471)) ([1e34d3e](https://github.com/vbenjs/vue-vben-admin/commit/1e34d3e9e4c79a62a16c6209639f5394dea61148))
|
||||
- **layout:** move setting button to tabs when fold ([#3264](https://github.com/vbenjs/vue-vben-admin/issues/3264)) ([83426b5](https://github.com/vbenjs/vue-vben-admin/commit/83426b5c96a88c3a6aa399eb6100ea5fb494fd0e))
|
||||
- **Menu:** Add custom images to menu ([#3158](https://github.com/vbenjs/vue-vben-admin/issues/3158)) ([b3a6ef6](https://github.com/vbenjs/vue-vben-admin/commit/b3a6ef63bb500d8103bde17d588b3c0c4c77efd6))
|
||||
- **menu:** Restore side bar settings and added menu mouse move in mode light style ([#3295](https://github.com/vbenjs/vue-vben-admin/issues/3295)) ([003a951](https://github.com/vbenjs/vue-vben-admin/commit/003a951befb9ef2878a35fbe3054252d0bc8e77e))
|
||||
- **MultipleTab:** add tabs auto collapse interaction in fold mode and setting ([#3256](https://github.com/vbenjs/vue-vben-admin/issues/3256)) ([191e809](https://github.com/vbenjs/vue-vben-admin/commit/191e809b6d696d6e0b72c67ba1c7e89c721f2642))
|
||||
- pinia persist plugin custom serializer ([#3244](https://github.com/vbenjs/vue-vben-admin/issues/3244)) ([ea51c49](https://github.com/vbenjs/vue-vben-admin/commit/ea51c492c2ba56aa6693217e24f60dc143f124f1))
|
||||
- RefForm页面新增只读功能按钮 ([#3346](https://github.com/vbenjs/vue-vben-admin/issues/3346)) ([97b76ea](https://github.com/vbenjs/vue-vben-admin/commit/97b76ea6bc902d00c87c5cbd1cb2d67aa9a88347))
|
||||
- **search:** adjust the menu search function to recognize lowercase input ([#3736](https://github.com/vbenjs/vue-vben-admin/issues/3736)) ([96ac362](https://github.com/vbenjs/vue-vben-admin/commit/96ac362fa6a89af256cf8a84e4b667c195c6ea2e))
|
||||
- **Table-> CustomerCell:** helpMessage支持传递 tsx 和 h函数的数据 ([c373ffd](https://github.com/vbenjs/vue-vben-admin/commit/c373ffd3bfb7db454e0501b2f7b138ed1a9ec657))
|
||||
- table搜索表单值发生改变可以触发reload ([#3378](https://github.com/vbenjs/vue-vben-admin/issues/3378)) ([1ca3f7c](https://github.com/vbenjs/vue-vben-admin/commit/1ca3f7c2c0c0c00e8395e26c59796c875d34e12c))
|
||||
- **treeTable:** add function collapseRows and demo ([#3375](https://github.com/vbenjs/vue-vben-admin/issues/3375)) ([e656b5d](https://github.com/vbenjs/vue-vben-admin/commit/e656b5d8dcde38deeedc73d713d2367e54d2893b))
|
||||
- **type->api:** resultField推断api的返回值应该包含recordbale类型 ([#3699](https://github.com/vbenjs/vue-vben-admin/issues/3699)) ([c7ab4a5](https://github.com/vbenjs/vue-vben-admin/commit/c7ab4a52989256ccae996191cc249d9cbb36e6d6))
|
||||
- **Upload:** file list add drag func ([#3227](https://github.com/vbenjs/vue-vben-admin/issues/3227)). resolve [#3179](https://github.com/vbenjs/vue-vben-admin/issues/3179) ([beed7f2](https://github.com/vbenjs/vue-vben-admin/commit/beed7f2e1172531fe691384a50c8b0457f3a80d8))
|
||||
- **VirtualScroll:** 虚拟滚动增加滚动到顶部, 底部, 指定项方法 ([#3687](https://github.com/vbenjs/vue-vben-admin/issues/3687)) ([7c52f08](https://github.com/vbenjs/vue-vben-admin/commit/7c52f083db30f7e68c3e10a88cbc47d41cf9de20))
|
||||
- vxeTable searchInfo demo ([#3223](https://github.com/vbenjs/vue-vben-admin/issues/3223)) close [#3011](https://github.com/vbenjs/vue-vben-admin/issues/3011) ([59145ad](https://github.com/vbenjs/vue-vben-admin/commit/59145ade255ee752a7c8d8995634ec172a7f60c8))
|
||||
- **vxetable:** 新增 clearEdit 方法 ([#3369](https://github.com/vbenjs/vue-vben-admin/issues/3369)) ([522e892](https://github.com/vbenjs/vue-vben-admin/commit/522e892d7947807f7d500a2bace23880729df204))
|
||||
- **watermark:** support custom style ([#3634](https://github.com/vbenjs/vue-vben-admin/issues/3634)) ([ca3ddd1](https://github.com/vbenjs/vue-vben-admin/commit/ca3ddd19f7811cbf32fd87b6c1cfd6681c08fc69))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
- 解决ts文件通过alias引入vue文件后, vscode调转不到正确vue文件路径 ([#3099](https://github.com/vbenjs/vue-vben-admin/issues/3099)) ([033d882](https://github.com/vbenjs/vue-vben-admin/commit/033d8828a9545770e98909291dcb6fd8db90ee41))
|
||||
- 优化水印在控制台可以hide的问题 ([#3732](https://github.com/vbenjs/vue-vben-admin/issues/3732)) ([9784cdc](https://github.com/vbenjs/vue-vben-admin/commit/9784cdc840336d5c2bb006fa3ababfa7fa4056af))
|
||||
- **BasicTree:** 获取treeData改写成函数 ([748b99b](https://github.com/vbenjs/vue-vben-admin/commit/748b99b18f5fc4e313add38ad457f0a5f064db70))
|
||||
- **BasicTree:** 外部获取treeData不必通过treeDataRef.value ([#3353](https://github.com/vbenjs/vue-vben-admin/issues/3353)) ([943f500](https://github.com/vbenjs/vue-vben-admin/commit/943f50051ca80b6646ed44a2117b7c9ef632ed6d))
|
||||
- **breakpointEnum:** 修改enum与breakpoint.less内一致 ([#3276](https://github.com/vbenjs/vue-vben-admin/issues/3276)) ([8932318](https://github.com/vbenjs/vue-vben-admin/commit/89323186b56b06b148664ae7483c490cf7eadefa))
|
||||
- **component:** formItem: label支持函数渲染 ([#3504](https://github.com/vbenjs/vue-vben-admin/issues/3504)) ([e6a7e4c](https://github.com/vbenjs/vue-vben-admin/commit/e6a7e4c4fcdc5ad94f55c4f19000d6767773691e))
|
||||
- **ConfigProvider:** 配置antdv主题色, 使其与modifyVars配置一致 ([#3219](https://github.com/vbenjs/vue-vben-admin/issues/3219)) ([bb3d5b8](https://github.com/vbenjs/vue-vben-admin/commit/bb3d5b8ae8e8ae0e91acb3022f51572daf3210c6))
|
||||
- **darkMode:** 深色模式颜色定义以及切换方式优化 ([#3436](https://github.com/vbenjs/vue-vben-admin/issues/3436)) ([b008c44](https://github.com/vbenjs/vue-vben-admin/commit/b008c44246bec32def74c6ae1dd3522bf8c1ca2e))
|
||||
- **darkMode:** 优化深色模式颜色切换相关方法; 增加根据主题更新自定义颜色方法和示例 ([#3216](https://github.com/vbenjs/vue-vben-admin/issues/3216)) ([e497721](https://github.com/vbenjs/vue-vben-admin/commit/e497721e9b3d03de07a61808012d0d6e04fd9663))
|
||||
- **IconPicker:** input trigger popover by click ([#3278](https://github.com/vbenjs/vue-vben-admin/issues/3278)) ([2bbc2d2](https://github.com/vbenjs/vue-vben-admin/commit/2bbc2d28119c7f7cadbf5411b9ea886fb8965de0))
|
||||
- **ImageUpload:** 根据官方示例设置图片回显格式 ([#3252](https://github.com/vbenjs/vue-vben-admin/issues/3252)) ([2991bb1](https://github.com/vbenjs/vue-vben-admin/commit/2991bb1670d44633d1f571374553d027e0dad8a2))
|
||||
- Modify i18 file format to JSON ([#3171](https://github.com/vbenjs/vue-vben-admin/issues/3171)) ([c24e0ef](https://github.com/vbenjs/vue-vben-admin/commit/c24e0efd1d2c7148a3df9c8b12a2a500910a3590))
|
||||
- **useForm:** If the args of the setFieldsValue is empty, it will not be executed. close [#3209](https://github.com/vbenjs/vue-vben-admin/issues/3209) ([8f90087](https://github.com/vbenjs/vue-vben-admin/commit/8f900871ace30895d9fee84c4eb9018c0ad0450e))
|
||||
|
||||
### Reverts
|
||||
|
||||
- Revert "chore(deps): update ant-design-vue version to 4.1.0. resolve #3495" ([f9fc369](https://github.com/vbenjs/vue-vben-admin/commit/f9fc369637d1588aa5eebf5fee1f3526de14e0cb)), closes [#3495](https://github.com/vbenjs/vue-vben-admin/issues/3495)
|
||||
- Revert "feat: table搜索表单值发生改变可以触发reload (#3378)" (#3407) ([2828ed3](https://github.com/vbenjs/vue-vben-admin/commit/2828ed304a778bb16b52223607428dac926d73bf)), closes [#3378](https://github.com/vbenjs/vue-vben-admin/issues/3378) [#3407](https://github.com/vbenjs/vue-vben-admin/issues/3407)
|
||||
- Revert "chore: update `unplugin-config` (#3116)" (#3117) ([f0550f2](https://github.com/vbenjs/vue-vben-admin/commit/f0550f20438a4c11f51fcf3e4a4286692bcf7d9f)), closes [#3116](https://github.com/vbenjs/vue-vben-admin/issues/3116) [#3117](https://github.com/vbenjs/vue-vben-admin/issues/3117)
|
||||
- Revert "chore: Update Dependencies" ([ae09d3c](https://github.com/vbenjs/vue-vben-admin/commit/ae09d3cfd6b11689620565b57b506826626d09e9))
|
||||
- Revert "refactor: use `unplugin-config` (#3106)" ([694dead](https://github.com/vbenjs/vue-vben-admin/commit/694dead3115a535782b7dd3a3c2dc4eaa9f32d76)), closes [#3106](https://github.com/vbenjs/vue-vben-admin/issues/3106)
|
||||
|
||||
## [2.8.0](https://github.com/anncwb/vue-vben-admin/compare/v2.7.2...v2.8.0) (2021-11-03)
|
||||
|
||||
### Bug Fixes
|
||||
|
25
Dockerfile
Normal file
25
Dockerfile
Normal file
@@ -0,0 +1,25 @@
|
||||
# node 构建
|
||||
FROM node:18-alpine as build-stage
|
||||
# 署名
|
||||
MAINTAINER Adoin 'adoin@qq.com'
|
||||
WORKDIR /app
|
||||
COPY . ./
|
||||
# 设置 node 阿里镜像
|
||||
RUN npm config set registry https://registry.npmmirror.com
|
||||
# 设置--max-old-space-size
|
||||
ENV NODE_OPTIONS=--max-old-space-size=16384
|
||||
# 设置阿里镜像、pnpm、依赖、编译
|
||||
RUN npm install pnpm -g && \
|
||||
pnpm install --frozen-lockfile && \
|
||||
pnpm build:docker
|
||||
# node部分结束
|
||||
RUN echo "🎉 编 🎉 译 🎉 成 🎉 功 🎉"
|
||||
# nginx 部署
|
||||
FROM nginx:1.23.3-alpine as production-stage
|
||||
COPY --from=build-stage /app/dist /usr/share/nginx/html/dist
|
||||
COPY --from=build-stage /app/nginx.conf /etc/nginx/nginx.conf
|
||||
EXPOSE 80
|
||||
## 将/usr/share/nginx/html/dist/assets/index.js 和/usr/share/nginx/html/dist/_app.config.js中的"$vg_base_url"替换为环境变量中的VG_BASE_URL,$vg_sub_domain 替换成VG_SUB_DOMAIN,$vg_default_user替换成VG_DEFAULT_USER,$vg_default_password替换成VG_DEFAULT_PASSWORD 而后启动nginx
|
||||
CMD sed -i "s|__vg_base_url|$VG_BASE_URL|g" /usr/share/nginx/html/dist/assets/entry/index-*.js /usr/share/nginx/html/dist/_app.config.js && \
|
||||
nginx -g 'daemon off;'
|
||||
RUN echo "🎉 架 🎉 设 🎉 成 🎉 功 🎉"
|
67
README.md
67
README.md
@@ -9,24 +9,24 @@
|
||||
|
||||
## Introduction
|
||||
|
||||
Vue Vben Admin is a free and open source middle and back-end template. Using the latest `vue3`, `vite2`, `TypeScript` and other mainstream technology development, the out-of-the-box middle and back-end front-end solutions can also be used for learning reference.
|
||||
Vue Vben Admin is a free and open source middle platform/back-end template. Using the latest `vue3`, `vite4`, `TypeScript` and other mainstream technology, Vben is the out-of-the-box front-end solution for both production and learning purpose.
|
||||
|
||||
## Feature
|
||||
## Features
|
||||
|
||||
- **State of The Art Development**:Use front-end front-end technology development such as Vue3/vite2
|
||||
- **State-of-art Techinical Stack**:Using the latest and popular front-end technology such as Vue3/vite2
|
||||
- **TypeScript**: Application-level JavaScript language
|
||||
- **Theming**: Configurable themes
|
||||
- **International**:Built-in complete internationalization program
|
||||
- **Mock Server** Built-in mock data scheme
|
||||
- **Authority** Built-in complete dynamic routing permission generation scheme.
|
||||
- **Component** Multiple commonly used components are encapsulated twice
|
||||
- **International**:Built-in i18n support
|
||||
- **Response Mock**: Built-in response mock ability
|
||||
- **Authority**: Built-in permission system based on dynamic routes.
|
||||
- **Component**: Extracted and encapsulated components for various scenarios.
|
||||
|
||||
## Preview
|
||||
|
||||
- [vue-vben-admin](https://vben.vvbin.cn/) - Full version Chinese site
|
||||
- [vue-vben-admin-gh-pages](https://anncwb.github.io/vue-vben-admin/) - Full version of the github site
|
||||
- [vben-admin-thin-next](https://vben.vvbin.cn/thin/next/) - Simplified Chinese site
|
||||
- [vben-admin-thin-gh-pages](https://anncwb.github.io/vben-admin-thin-next/) -Simplified github site
|
||||
- [vue-vben-admin](https://vben.vvbin.cn/) - Full version (Chinese)
|
||||
- [vue-vben-admin-gh-pages](https://anncwb.github.io/vue-vben-admin/) - Full version (github hosted)
|
||||
- [vben-admin-thin-next](https://vben.vvbin.cn/thin/next/) - Simplified Version (Chinese)
|
||||
- [vben-admin-thin-gh-pages](https://anncwb.github.io/vben-admin-thin-next/) -Simplified Version (github hosted)
|
||||
|
||||
Test account: vben/123456
|
||||
|
||||
@@ -54,7 +54,7 @@ Open the project in Gitpod (free online dev environment for GitHub) and start co
|
||||
- [TypeScript](https://www.typescriptlang.org/) - Familiar with the basic syntax of `TypeScript`
|
||||
- [Es6+](http://es6.ruanyifeng.com/) - Familiar with es6 basic syntax
|
||||
- [Vue-Router-Next](https://next.router.vuejs.org/) - Familiar with the basic use of vue-router
|
||||
- [Ant-Design-Vue](https://2x.antdv.com/docs/vue/introduce-cn/) - ui basic use
|
||||
- [Ant-Design-Vue](https://antdv.com/docs/vue/introduce-cn/) - ui basic use
|
||||
- [Mock.js](https://github.com/nuysoft/Mock) - mockjs basic syntax
|
||||
|
||||
## Install and use
|
||||
@@ -65,7 +65,7 @@ Open the project in Gitpod (free online dev environment for GitHub) and start co
|
||||
git clone https://github.com/anncwb/vue-vben-admin.git
|
||||
```
|
||||
|
||||
- Installation dependencies
|
||||
- Install dependencies
|
||||
|
||||
```bash
|
||||
cd vue-vben-admin
|
||||
@@ -86,6 +86,24 @@ pnpm serve
|
||||
pnpm build
|
||||
```
|
||||
|
||||
- docker
|
||||
|
||||
### The dockerFile is located in the project root directory and supports differential deployment
|
||||
|
||||
#### build image
|
||||
|
||||
```bash
|
||||
docker build -t vue-vben-admin .
|
||||
```
|
||||
|
||||
#### Use environment variables to achieve differentiated container deployment. Specify service endpoint by assigning `VG_BASE_URL`. In the following example, `http://localhost:3333` is used as the back-end service address and the container is mapped to port `6666`:
|
||||
|
||||
```bash
|
||||
docker run --name vue-vben-admin -d -p 6666:80 -e VG_BASE_URL=http://localhost:3333 vue-vben-admin
|
||||
```
|
||||
|
||||
Then you can navigate to `http://localhost:6666`
|
||||
|
||||
## Change Log
|
||||
|
||||
[CHANGELOG](./CHANGELOG.zh_CN.md)
|
||||
@@ -97,7 +115,7 @@ pnpm build
|
||||
|
||||
## How to contribute
|
||||
|
||||
You are very welcome to join Or submit a Pull Request。
|
||||
You are very welcome to join or submit a Pull Request。
|
||||
|
||||
**Pull Request:**
|
||||
|
||||
@@ -113,7 +131,7 @@ You are very welcome to join - Used for local and development environment data mock
|
||||
- [vite-plugin-html](https://github.com/anncwb/vite-plugin-html) - Used for html template conversion and compression
|
||||
@@ -138,7 +156,7 @@ If these plugins are helpful to you, you can give a star support
|
||||
|
||||
The `Chrome 80+` browser is recommended for local development
|
||||
|
||||
Support modern browsers, not IE
|
||||
Support modern browsers, doesn't include IE
|
||||
|
||||
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt=" Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt=" Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
|
||||
| :-: | :-: | :-: | :-: | :-: |
|
||||
@@ -146,20 +164,15 @@ Support modern browsers, not IE
|
||||
|
||||
## Maintainer
|
||||
|
||||
[@Vben](https://github.com/anncwb)
|
||||
[@Vben](https://github.com/anncwb) [@Jinmao](https://github.com/jinmao88)
|
||||
|
||||
## Donate
|
||||
## Thanks
|
||||
|
||||
If you think this project is helpful to you, you can help the author buy a cup of coffee to show your support!
|
||||
<img src="https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.png" alt="JetBrains Logo (Main) logo." height="120">
|
||||
|
||||

|
||||
## Star History Chart
|
||||
|
||||
<a style="display: block;width: 100px;height: 50px;line-height: 50px; color: #fff;text-align: center; background: #408aed;border-radius: 4px;" href="https://www.paypal.com/paypalme/cvvben">Paypal Me</a>
|
||||
|
||||
## Discord
|
||||
|
||||
- [github discussions](https://github.com/anncwb/vue-vben-admin/discussions)
|
||||
- [Discord](https://discord.gg/8GuAdwDhj6)
|
||||
[](https://star-history.com/#vbenjs/vue-vben-admin&Date)
|
||||
|
||||
## License
|
||||
|
||||
|
@@ -9,11 +9,11 @@
|
||||
|
||||
## 简介
|
||||
|
||||
Vue Vben Admin 是一个免费开源的中后台模版。使用了最新的`vue3`,`vite2`,`TypeScript`等主流技术开发,开箱即用的中后台前端解决方案,也可用于学习参考。
|
||||
Vue Vben Admin 是一个免费开源的中后台模版。使用了最新的`vue3`,`vite5`,`TypeScript`等主流技术开发,开箱即用的中后台前端解决方案,也可用于学习参考。
|
||||
|
||||
## 特性
|
||||
|
||||
- **最新技术栈**:使用 Vue3/vite2 等前端前沿技术开发
|
||||
- **最新技术栈**:使用 Vue3/vite5 等前端前沿技术开发
|
||||
- **TypeScript**: 应用程序级 JavaScript 的语言
|
||||
- **主题**:可配置的主题
|
||||
- **国际化**:内置完善的国际化方案
|
||||
@@ -54,7 +54,7 @@ Vue Vben Admin 是一个免费开源的中后台模版。使用了最新的`vue3
|
||||
- [TypeScript](https://www.typescriptlang.org/) - 熟悉`TypeScript`基本语法
|
||||
- [Es6+](http://es6.ruanyifeng.com/) - 熟悉 es6 基本语法
|
||||
- [Vue-Router-Next](https://next.router.vuejs.org/) - 熟悉 vue-router 基本使用
|
||||
- [Ant-Design-Vue](https://2x.antdv.com/docs/vue/introduce-cn/) - ui 基本使用
|
||||
- [Ant-Design-Vue](https://antdv.com/docs/vue/introduce-cn/) - ui 基本使用
|
||||
- [Mock.js](https://github.com/nuysoft/Mock) - mockjs 基本语法
|
||||
|
||||
## 安装使用
|
||||
@@ -86,6 +86,24 @@ pnpm serve
|
||||
pnpm build
|
||||
```
|
||||
|
||||
- docker
|
||||
|
||||
### dockerFile 位于项目根目录下 并且支持差异化部署
|
||||
|
||||
#### 构建镜像
|
||||
|
||||
```bash
|
||||
docker build -t vue-vben-admin .
|
||||
```
|
||||
|
||||
#### 动态使用环境变量实现容器差异化部署,通过不同的 VG_BASE_URL 环境变量,指向不同的后端服务地址,下面例子使用 http://localhost:3333 作为后端服务地址,并且将容器映射到 6666 端口
|
||||
|
||||
```bash
|
||||
docker run --name vue-vben-admin -d -p 6666:80 -e VG_BASE_URL=http://localhost:3333 vue-vben-admin
|
||||
```
|
||||
|
||||
而后可以打开 http://localhost:6666 访问
|
||||
|
||||
## 更新日志
|
||||
|
||||
[CHANGELOG](./CHANGELOG.zh_CN.md)
|
||||
@@ -151,15 +169,11 @@ pnpm build
|
||||
|
||||
## 维护者
|
||||
|
||||
[@Vben](https://github.com/anncwb)
|
||||
[@Vben](https://github.com/anncwb) [@Jinmao](https://github.com/jinmao88)
|
||||
|
||||
## 捐赠
|
||||
## 感谢
|
||||
|
||||
如果你觉得这个项目对你有帮助,你可以帮作者买一杯咖啡表示支持!
|
||||
|
||||

|
||||
|
||||
<a style="display: block;width: 100px;height: 50px;line-height: 50px; color: #fff;text-align: center; background: #408aed;border-radius: 4px;" href="https://www.paypal.com/paypalme/cvvben">Paypal Me</a>
|
||||
<img src="https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.png" alt="JetBrains Logo (Main) logo." height='120'>
|
||||
|
||||
## 交流
|
||||
|
||||
@@ -167,6 +181,10 @@ pnpm build
|
||||
|
||||
- QQ 群 `569291866`
|
||||
|
||||
## Star 历史
|
||||
|
||||
[](https://star-history.com/#vbenjs/vue-vben-admin&Date)
|
||||
|
||||
## License
|
||||
|
||||
[MIT © Vben-2020](./LICENSE)
|
||||
|
@@ -4,16 +4,16 @@
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"compile": "rimraf ./dist && tsup ./index.ts --dts --format cjs,esm ",
|
||||
"prod": "npx pm2 start ecosystem.config.js --env production",
|
||||
"restart": "pm2 restart ecosystem.config.js --env production",
|
||||
"prod": "npx pm2 start ecosystem.config.cjs --env production",
|
||||
"restart": "pm2 restart ecosystem.config.cjs --env production",
|
||||
"start": "nodemon",
|
||||
"stop": "npx pm2 stop ecosystem.config.js"
|
||||
"stop": "npx pm2 stop ecosystem.config.cjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"fs-extra": "^11.1.1",
|
||||
"koa": "^2.14.1",
|
||||
"koa": "^2.14.2",
|
||||
"koa-body": "^6.0.1",
|
||||
"koa-bodyparser": "^4.4.0",
|
||||
"koa-bodyparser": "^4.4.1",
|
||||
"koa-route": "^3.2.0",
|
||||
"koa-router": "^12.0.0",
|
||||
"koa-static": "^5.0.0",
|
||||
@@ -24,13 +24,13 @@
|
||||
"@types/koa": "^2.13.6",
|
||||
"@types/koa-bodyparser": "^5.0.2",
|
||||
"@types/koa-router": "^7.4.4",
|
||||
"@types/node": "^18.15.11",
|
||||
"@types/node": "^20.4.0",
|
||||
"nodemon": "^2.0.22",
|
||||
"pm2": "^5.3.0",
|
||||
"rimraf": "^4.4.1",
|
||||
"rimraf": "^5.0.1",
|
||||
"ts-node": "^10.9.1",
|
||||
"tsconfig-paths": "^4.2.0",
|
||||
"tsup": "^6.7.0",
|
||||
"typescript": "^5.0.3"
|
||||
"tsup": "^7.1.0",
|
||||
"typescript": "^5.1.6"
|
||||
}
|
||||
}
|
||||
|
@@ -5,13 +5,13 @@ const uploadUrl = 'http://localhost:3300/static/upload';
|
||||
const filePath = path.join(__dirname, '../static/upload/');
|
||||
|
||||
fs.ensureDir(filePath);
|
||||
export default class UserService {
|
||||
export default class FileService {
|
||||
async upload(ctx, files, isMultiple) {
|
||||
let fileReader, fileResource, writeStream;
|
||||
|
||||
const fileFunc = function (file) {
|
||||
fileReader = fs.createReadStream(file.path);
|
||||
fileResource = filePath + `/${file.name}`;
|
||||
fileReader = fs.createReadStream(file.filepath);
|
||||
fileResource = filePath + `/${file.originalFilename}`;
|
||||
console.log(fileResource);
|
||||
|
||||
writeStream = fs.createWriteStream(fileResource);
|
||||
@@ -22,7 +22,7 @@ export default class UserService {
|
||||
if (flag) {
|
||||
let url = '';
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
url += uploadUrl + `/${files[i].name},`;
|
||||
url += uploadUrl + `/${files[i].originalFilename},`;
|
||||
}
|
||||
url = url.replace(/,$/gi, '');
|
||||
ctx.body = {
|
||||
@@ -32,7 +32,7 @@ export default class UserService {
|
||||
};
|
||||
} else {
|
||||
ctx.body = {
|
||||
url: uploadUrl + `/${files.name}`,
|
||||
url: uploadUrl + `/${files.originalFilename}`,
|
||||
code: 0,
|
||||
message: 'upload Success!',
|
||||
};
|
||||
|
21
index.html
21
index.html
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" id="htmlRoot">
|
||||
<!doctype html>
|
||||
<html lang="zh" id="htmlRoot">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
@@ -14,6 +14,11 @@
|
||||
<body>
|
||||
<div id="app">
|
||||
<style>
|
||||
html {
|
||||
/* same as ant-design-vue/dist/reset.css setting, avoid the title line-height changed */
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
html[data-theme='dark'] .app-loading {
|
||||
background-color: #2c344a;
|
||||
}
|
||||
@@ -120,18 +125,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes ant-rotate {
|
||||
to {
|
||||
transform: rotate(405deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes ant-spin-move {
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes ant-spin-move {
|
||||
to {
|
||||
opacity: 1;
|
||||
|
9
internal/eslint-config/.eslintignore
Normal file
9
internal/eslint-config/.eslintignore
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
*.sh
|
||||
node_modules
|
||||
*.md
|
||||
*.woff
|
||||
*.ttf
|
||||
.turbo
|
||||
dist
|
||||
package.json
|
@@ -12,6 +12,7 @@
|
||||
"directory": "internal/eslint-config"
|
||||
},
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -36,14 +37,14 @@
|
||||
"stub": "pnpm unbuild --stub"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^5.57.1",
|
||||
"@typescript-eslint/parser": "^5.57.1",
|
||||
"eslint": "^8.37.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-simple-import-sort": "^10.0.0",
|
||||
"eslint-plugin-vue": "^9.10.0",
|
||||
"vue-eslint-parser": "^9.1.1"
|
||||
"@typescript-eslint/eslint-plugin": "^7.0.1",
|
||||
"@typescript-eslint/parser": "^7.0.1",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"eslint-plugin-simple-import-sort": "^12.0.0",
|
||||
"eslint-plugin-vue": "^9.21.1",
|
||||
"vue-eslint-parser": "^9.4.2"
|
||||
}
|
||||
}
|
||||
|
9
internal/stylelint-config/.eslintignore
Normal file
9
internal/stylelint-config/.eslintignore
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
*.sh
|
||||
node_modules
|
||||
*.md
|
||||
*.woff
|
||||
*.ttf
|
||||
.turbo
|
||||
dist
|
||||
package.json
|
@@ -12,6 +12,7 @@
|
||||
"directory": "internal/stylelint-config"
|
||||
},
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -31,19 +32,18 @@
|
||||
"stub": "pnpm unbuild --stub"
|
||||
},
|
||||
"devDependencies": {
|
||||
"postcss": "^8.4.21",
|
||||
"postcss-html": "^1.5.0",
|
||||
"postcss": "^8.4.38",
|
||||
"postcss-html": "^1.6.0",
|
||||
"postcss-less": "^6.0.0",
|
||||
"postcss-scss": "^4.0.6",
|
||||
"prettier": "^2.8.7",
|
||||
"stylelint": "^15.4.0",
|
||||
"stylelint-config-property-sort-order-smacss": "^9.1.0",
|
||||
"stylelint-config-recommended": "^11.0.0",
|
||||
"stylelint-config-recommended-scss": "^9.0.1",
|
||||
"stylelint-config-recommended-vue": "^1.4.0",
|
||||
"stylelint-config-standard": "^32.0.0",
|
||||
"stylelint-config-standard-scss": "^7.0.1",
|
||||
"stylelint-order": "^6.0.3",
|
||||
"stylelint-prettier": "^3.0.0"
|
||||
"postcss-scss": "^4.0.9",
|
||||
"prettier": "^3.2.5",
|
||||
"stylelint": "^16.4.0",
|
||||
"stylelint-config-property-sort-order-smacss": "^10.0.0",
|
||||
"stylelint-config-recommended-scss": "^14.0.0",
|
||||
"stylelint-config-recommended-vue": "^1.5.0",
|
||||
"stylelint-config-standard": "^36.0.0",
|
||||
"stylelint-config-standard-scss": "^13.1.0",
|
||||
"stylelint-order": "^6.0.4",
|
||||
"stylelint-prettier": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
@@ -22,6 +22,8 @@ export default {
|
||||
},
|
||||
],
|
||||
rules: {
|
||||
'prettier/prettier': true,
|
||||
'media-feature-range-notation': null,
|
||||
'selector-not-notation': null,
|
||||
'import-notation': null,
|
||||
'function-no-unknown': null,
|
||||
@@ -57,7 +59,6 @@ export default {
|
||||
},
|
||||
],
|
||||
'no-empty-source': null,
|
||||
'string-quotes': null,
|
||||
'named-grid-areas-no-invalid': null,
|
||||
'no-descending-specificity': null,
|
||||
'font-family-no-missing-generic-family-keyword': null,
|
||||
|
@@ -4,7 +4,7 @@
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"moduleResolution": "bundler",
|
||||
"strict": true,
|
||||
"declaration": true,
|
||||
"noImplicitOverride": true,
|
||||
|
@@ -12,15 +12,15 @@
|
||||
"directory": "internal/ts-config"
|
||||
},
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"files": [
|
||||
"base.json",
|
||||
"node.json",
|
||||
"vue.json",
|
||||
"vue-app.json",
|
||||
"node-server.json"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/node": "^18.15.11",
|
||||
"unplugin-vue-define-options": "^1.3.3",
|
||||
"vite": "^4.3.0-beta.2"
|
||||
"@types/node": "^20.12.7",
|
||||
"vite": "^5.2.10"
|
||||
}
|
||||
}
|
||||
|
@@ -6,6 +6,5 @@
|
||||
"jsx": "preserve",
|
||||
"lib": ["ESNext", "DOM"],
|
||||
"noImplicitAny": false
|
||||
|
||||
}
|
||||
}
|
||||
|
9
internal/vite-config/.eslintignore
Normal file
9
internal/vite-config/.eslintignore
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
*.sh
|
||||
node_modules
|
||||
*.md
|
||||
*.woff
|
||||
*.ttf
|
||||
.turbo
|
||||
dist
|
||||
package.json
|
@@ -12,6 +12,7 @@
|
||||
"directory": "internal/vite-config"
|
||||
},
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -31,29 +32,28 @@
|
||||
"stub": "pnpm unbuild --stub"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/colors": "^7.0.0",
|
||||
"vite": "^4.3.0-beta.2"
|
||||
"@ant-design/colors": "^7.0.2",
|
||||
"vite": "^5.2.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "^11.0.1",
|
||||
"@vitejs/plugin-vue": "^4.1.0",
|
||||
"@vitejs/plugin-vue-jsx": "^3.0.1",
|
||||
"ant-design-vue": "^3.2.17",
|
||||
"dayjs": "^1.11.7",
|
||||
"dotenv": "^16.0.3",
|
||||
"fs-extra": "^11.1.1",
|
||||
"less": "^4.1.3",
|
||||
"@types/fs-extra": "^11.0.4",
|
||||
"@vitejs/plugin-vue": "^5.0.4",
|
||||
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
||||
"ant-design-vue": "^4.2.1",
|
||||
"dayjs": "^1.11.10",
|
||||
"dotenv": "^16.4.5",
|
||||
"fs-extra": "^11.2.0",
|
||||
"less": "^4.2.0",
|
||||
"picocolors": "^1.0.0",
|
||||
"pkg-types": "^1.0.2",
|
||||
"rollup-plugin-visualizer": "^5.9.0",
|
||||
"sass": "^1.60.0",
|
||||
"unocss": "^0.50.6",
|
||||
"unplugin-vue-define-options": "^1.3.3",
|
||||
"pkg-types": "^1.1.0",
|
||||
"rollup-plugin-visualizer": "^5.12.0",
|
||||
"sass": "^1.75.0",
|
||||
"unocss": "0.59.4",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-dts": "^2.2.0",
|
||||
"vite-plugin-html": "^3.2.0",
|
||||
"vite-plugin-dts": "^3.9.0",
|
||||
"vite-plugin-html": "^3.2.2",
|
||||
"vite-plugin-mock": "^2.9.6",
|
||||
"vite-plugin-purge-icons": "^0.9.2",
|
||||
"vite-plugin-purge-icons": "^0.10.0",
|
||||
"vite-plugin-svg-icons": "^2.0.1"
|
||||
}
|
||||
}
|
||||
|
@@ -21,7 +21,10 @@ function defineApplicationConfig(defineOptions: DefineOptions = {}) {
|
||||
return defineConfig(async ({ command, mode }) => {
|
||||
const root = process.cwd();
|
||||
const isBuild = command === 'build';
|
||||
const { VITE_USE_MOCK, VITE_BUILD_COMPRESS, VITE_ENABLE_ANALYZE } = loadEnv(mode, root);
|
||||
const { VITE_PUBLIC_PATH, VITE_USE_MOCK, VITE_BUILD_COMPRESS, VITE_ENABLE_ANALYZE } = loadEnv(
|
||||
mode,
|
||||
root,
|
||||
);
|
||||
|
||||
const defineData = await createDefineData(root);
|
||||
const plugins = await createPlugins({
|
||||
@@ -33,24 +36,15 @@ function defineApplicationConfig(defineOptions: DefineOptions = {}) {
|
||||
});
|
||||
|
||||
const pathResolve = (pathname: string) => resolve(root, '.', pathname);
|
||||
|
||||
const timestamp = new Date().getTime();
|
||||
const applicationConfig: UserConfig = {
|
||||
base: VITE_PUBLIC_PATH,
|
||||
resolve: {
|
||||
alias: [
|
||||
{
|
||||
find: 'vue-i18n',
|
||||
replacement: 'vue-i18n/dist/vue-i18n.cjs.js',
|
||||
},
|
||||
// /@/xxxx => src/xxxx
|
||||
{
|
||||
find: /\/@\//,
|
||||
replacement: pathResolve('src') + '/',
|
||||
},
|
||||
// /#/xxxx => types/xxxx
|
||||
{
|
||||
find: /\/#\//,
|
||||
replacement: pathResolve('types') + '/',
|
||||
},
|
||||
// @/xxxx => src/xxxx
|
||||
{
|
||||
find: /@\//,
|
||||
@@ -69,6 +63,8 @@ function defineApplicationConfig(defineOptions: DefineOptions = {}) {
|
||||
cssTarget: 'chrome80',
|
||||
rollupOptions: {
|
||||
output: {
|
||||
// 入口文件名
|
||||
entryFileNames: `assets/entry/[name]-[hash]-${timestamp}.js`,
|
||||
manualChunks: {
|
||||
vue: ['vue', 'pinia', 'vue-router'],
|
||||
antd: ['ant-design-vue', '@ant-design/icons-vue'],
|
||||
@@ -87,7 +83,7 @@ function defineApplicationConfig(defineOptions: DefineOptions = {}) {
|
||||
plugins,
|
||||
};
|
||||
|
||||
const mergedConfig = mergeConfig(commonConfig, applicationConfig);
|
||||
const mergedConfig = mergeConfig(commonConfig(mode), applicationConfig);
|
||||
|
||||
return mergeConfig(mergedConfig, overrides);
|
||||
});
|
||||
|
@@ -1,13 +1,12 @@
|
||||
import { presetTypography, presetUno } from 'unocss';
|
||||
import UnoCSS from 'unocss/vite';
|
||||
import { type UserConfig } from 'vite';
|
||||
|
||||
const commonConfig: UserConfig = {
|
||||
const commonConfig: (mode: string) => UserConfig = (mode) => ({
|
||||
server: {
|
||||
host: true,
|
||||
},
|
||||
esbuild: {
|
||||
drop: ['console', 'debugger'],
|
||||
drop: mode === 'production' ? ['console', 'debugger'] : [],
|
||||
},
|
||||
build: {
|
||||
reportCompressedSize: false,
|
||||
@@ -17,11 +16,7 @@ const commonConfig: UserConfig = {
|
||||
maxParallelFileOps: 3,
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
UnoCSS({
|
||||
presets: [presetUno(), presetTypography()],
|
||||
}),
|
||||
],
|
||||
};
|
||||
plugins: [UnoCSS()],
|
||||
});
|
||||
|
||||
export { commonConfig };
|
||||
|
@@ -14,7 +14,7 @@ interface DefineOptions {
|
||||
function definePackageConfig(defineOptions: DefineOptions = {}) {
|
||||
const { overrides = {} } = defineOptions;
|
||||
const root = process.cwd();
|
||||
return defineConfig(async () => {
|
||||
return defineConfig(async ({ mode }) => {
|
||||
const { dependencies = {}, peerDependencies = {} } = await readPackageJSON(root);
|
||||
const packageConfig: UserConfig = {
|
||||
build: {
|
||||
@@ -33,7 +33,7 @@ function definePackageConfig(defineOptions: DefineOptions = {}) {
|
||||
}),
|
||||
],
|
||||
};
|
||||
const mergedConfig = mergeConfig(commonConfig, packageConfig);
|
||||
const mergedConfig = mergeConfig(commonConfig(mode), packageConfig);
|
||||
|
||||
return mergeConfig(mergedConfig, overrides);
|
||||
});
|
||||
|
@@ -27,8 +27,8 @@ async function createAppConfigPlugin({
|
||||
return {
|
||||
name: PLUGIN_NAME,
|
||||
async configResolved(_config) {
|
||||
let appTitle = _config?.env?.VITE_GLOB_APP_TITLE ?? '';
|
||||
appTitle = appTitle.replace(/\s/g, '_');
|
||||
const appTitle = _config?.env?.VITE_GLOB_APP_TITLE ?? '';
|
||||
// appTitle = appTitle.replace(/\s/g, '_').replace(/-/g, '_');
|
||||
publicPath = _config.base;
|
||||
source = await getConfigSource(appTitle);
|
||||
},
|
||||
@@ -37,7 +37,7 @@ async function createAppConfigPlugin({
|
||||
|
||||
const appConfigSrc = `${
|
||||
publicPath || '/'
|
||||
}${GLOBAL_CONFIG_FILE_NAME}?v=${version}-${createContentHash(source)}}`;
|
||||
}${GLOBAL_CONFIG_FILE_NAME}?v=${version}-${createContentHash(source)}`;
|
||||
|
||||
return {
|
||||
html,
|
||||
@@ -74,7 +74,15 @@ async function createAppConfigPlugin({
|
||||
* @param env
|
||||
*/
|
||||
const getVariableName = (title: string) => {
|
||||
return `__PRODUCTION__${title || '__APP'}__CONF__`.toUpperCase().replace(/\s/g, '');
|
||||
function strToHex(str: string) {
|
||||
const result: string[] = [];
|
||||
for (let i = 0; i < str.length; ++i) {
|
||||
const hex = str.charCodeAt(i).toString(16);
|
||||
result.push(('000' + hex).slice(-4));
|
||||
}
|
||||
return result.join('').toUpperCase();
|
||||
}
|
||||
return `__PRODUCTION__${strToHex(title) || '__APP'}__CONF__`.toUpperCase().replace(/\s/g, '');
|
||||
};
|
||||
|
||||
async function getConfigSource(appTitle: string) {
|
||||
|
@@ -1,7 +1,5 @@
|
||||
import vue from '@vitejs/plugin-vue';
|
||||
import vueJsx from '@vitejs/plugin-vue-jsx';
|
||||
// @ts-ignore: type unless
|
||||
import DefineOptions from 'unplugin-vue-define-options/vite';
|
||||
import { type PluginOption } from 'vite';
|
||||
import purgeIcons from 'vite-plugin-purge-icons';
|
||||
|
||||
@@ -21,7 +19,7 @@ interface Options {
|
||||
}
|
||||
|
||||
async function createPlugins({ isBuild, root, enableMock, compress, enableAnalyze }: Options) {
|
||||
const vitePlugins: (PluginOption | PluginOption[])[] = [vue(), vueJsx(), DefineOptions()];
|
||||
const vitePlugins: (PluginOption | PluginOption[])[] = [vue(), vueJsx()];
|
||||
|
||||
const appConfigPlugin = await createAppConfigPlugin({ root, isBuild });
|
||||
vitePlugins.push(appConfigPlugin);
|
||||
|
@@ -22,7 +22,12 @@ function getConfFiles() {
|
||||
* @param match prefix
|
||||
* @param confFiles ext
|
||||
*/
|
||||
export async function getEnvConfig(match = 'VITE_GLOB_', confFiles = getConfFiles()) {
|
||||
export async function getEnvConfig(
|
||||
match = 'VITE_GLOB_',
|
||||
confFiles = getConfFiles(),
|
||||
): Promise<{
|
||||
[key: string]: string;
|
||||
}> {
|
||||
let envConfig = {};
|
||||
|
||||
for (const confFile of confFiles) {
|
||||
|
@@ -4,5 +4,13 @@ function createContentHash(content: string, hashLSize = 12) {
|
||||
const hash = createHash('sha256').update(content);
|
||||
return hash.digest('hex').slice(0, hashLSize);
|
||||
}
|
||||
function strToHex(str: string) {
|
||||
const result: string[] = [];
|
||||
for (let i = 0; i < str.length; ++i) {
|
||||
const hex = str.charCodeAt(i).toString(16);
|
||||
result.push(('000' + hex).slice(-4));
|
||||
}
|
||||
return result.join('').toUpperCase();
|
||||
}
|
||||
|
||||
export { createContentHash };
|
||||
export { createContentHash, strToHex };
|
||||
|
@@ -2,8 +2,11 @@ import { resolve } from 'node:path';
|
||||
|
||||
import { generate } from '@ant-design/colors';
|
||||
// @ts-ignore: typo
|
||||
import { getThemeVariables } from 'ant-design-vue/dist/theme';
|
||||
/* import { getThemeVariables } from 'ant-design-vue/dist/theme'; */
|
||||
import { theme } from 'ant-design-vue/lib';
|
||||
import convertLegacyToken from 'ant-design-vue/lib/theme/convertLegacyToken';
|
||||
|
||||
const { defaultAlgorithm, defaultSeed } = theme;
|
||||
const primaryColor = '#0960bd';
|
||||
|
||||
function generateAntColors(color: string, theme: 'default' | 'dark' = 'default') {
|
||||
@@ -18,18 +21,18 @@ function generateAntColors(color: string, theme: 'default' | 'dark' = 'default')
|
||||
export function generateModifyVars() {
|
||||
const palettes = generateAntColors(primaryColor);
|
||||
const primary = palettes[5];
|
||||
|
||||
const primaryColorObj: Record<string, string> = {};
|
||||
|
||||
for (let index = 0; index < 10; index++) {
|
||||
primaryColorObj[`primary-${index + 1}`] = palettes[index];
|
||||
}
|
||||
|
||||
const modifyVars = getThemeVariables();
|
||||
// const modifyVars = getThemeVariables();
|
||||
const mapToken = defaultAlgorithm(defaultSeed);
|
||||
const v3Token = convertLegacyToken(mapToken);
|
||||
return {
|
||||
...modifyVars,
|
||||
...v3Token,
|
||||
// reference: Avoid repeated references
|
||||
hack: `${modifyVars.hack} @import (reference) "${resolve('src/design/config.less')}";`,
|
||||
hack: `true; @import (reference) "${resolve('src/design/config.less')}";`,
|
||||
'primary-color': primary,
|
||||
...primaryColorObj,
|
||||
'info-color': primary,
|
||||
@@ -40,6 +43,5 @@ export function generateModifyVars() {
|
||||
'font-size-base': '14px', // Main font size
|
||||
'border-radius-base': '2px', // Component/float fillet
|
||||
'link-color': primary, // Link color
|
||||
'app-content-background': '#fafafa', // Link color
|
||||
};
|
||||
}
|
||||
|
@@ -16,14 +16,14 @@ import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer';
|
||||
// return pre;
|
||||
// }, [] as any[]);
|
||||
|
||||
const modules = import.meta.globEager('./**/*.ts');
|
||||
const modules = import.meta.glob('./**/*.ts', { eager: true });
|
||||
|
||||
const mockModules: any[] = [];
|
||||
Object.keys(modules).forEach((key) => {
|
||||
if (key.includes('/_')) {
|
||||
return;
|
||||
}
|
||||
mockModules.push(...modules[key].default);
|
||||
mockModules.push(...(modules as Recordable)[key].default);
|
||||
});
|
||||
|
||||
/**
|
||||
|
@@ -1,5 +1,5 @@
|
||||
// Interface data format used to return a unified format
|
||||
import { ResultEnum } from '/@/enums/httpEnum';
|
||||
import { ResultEnum } from '@/enums/httpEnum';
|
||||
|
||||
export function resultSuccess<T = Recordable>(result: T, { message = 'ok' } = {}) {
|
||||
return {
|
||||
|
@@ -12,6 +12,7 @@ const accountList = (() => {
|
||||
role: '@first',
|
||||
createTime: '@datetime',
|
||||
remark: '@cword(10,20)',
|
||||
'dept|0-2': 1,
|
||||
'status|1': ['0', '1'],
|
||||
});
|
||||
}
|
||||
|
@@ -267,4 +267,4 @@ export default [
|
||||
return resultSuccess(menu);
|
||||
},
|
||||
},
|
||||
] as MockMethod[];
|
||||
] as unknown as MockMethod[];
|
||||
|
39
nginx.conf
Normal file
39
nginx.conf
Normal file
@@ -0,0 +1,39 @@
|
||||
#user nobody;
|
||||
worker_processes 1;
|
||||
|
||||
#error_log logs/error.log;
|
||||
#error_log logs/error.log notice;
|
||||
#error_log logs/error.log info;
|
||||
|
||||
#pid logs/nginx.pid;
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
|
||||
http {
|
||||
include mime.types;
|
||||
default_type application/octet-stream;
|
||||
server {
|
||||
listen 80;
|
||||
location / {
|
||||
root /usr/share/nginx/html/dist;
|
||||
try_files $uri $uri/ /index.html;
|
||||
index index.html;
|
||||
# Enable CORS
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
|
||||
if ($request_method = 'OPTIONS') {
|
||||
add_header 'Access-Control-Max-Age' 1728000;
|
||||
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||
add_header 'Content-Length' 0;
|
||||
return 204;
|
||||
}
|
||||
# docker 改造之后不再需要
|
||||
# if ($request_filename ~* ^.*?.(html|htm|js)$) {
|
||||
# add_header Cache-Control no-cache;
|
||||
# }
|
||||
}
|
||||
}
|
||||
}
|
143
package.json
143
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vben-admin",
|
||||
"version": "2.10.0",
|
||||
"version": "2.11.4",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": {
|
||||
"url": "https://github.com/vbenjs/vue-vben-admin/issues"
|
||||
@@ -15,12 +15,14 @@
|
||||
"email": "anncwb@126.com",
|
||||
"url": "https://github.com/anncwb"
|
||||
},
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"bootstrap": "pnpm install",
|
||||
"build": "cross-env NODE_ENV=production pnpm vite build",
|
||||
"build:analyze": "pnpm vite build --mode analyze",
|
||||
"build:no-cache": "pnpm clean:cache && npm run build",
|
||||
"build:test": "pnpm vite build --mode test",
|
||||
"build": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=8192 pnpm vite build",
|
||||
"build:analyze": "cross-env NODE_OPTIONS=--max-old-space-size=8192 pnpm vite build --mode analyze",
|
||||
"build:docker": "vite build --mode docker",
|
||||
"build:no-cache": "pnpm store prune && npm run build",
|
||||
"build:test": "cross-env NODE_OPTIONS=--max-old-space-size=8192 pnpm vite build --mode test",
|
||||
"commit": "czg",
|
||||
"dev": "pnpm vite",
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
@@ -28,7 +30,8 @@
|
||||
"lint": "turbo run lint",
|
||||
"lint:eslint": "eslint --cache --max-warnings 0 \"{src,mock}/**/*.{vue,ts,tsx}\" --fix",
|
||||
"lint:prettier": "prettier --write .",
|
||||
"lint:stylelint": "stylelint \"**/*.{vue,css,less.scss}\" --fix --cache --cache-location node_modules/.cache/stylelint/",
|
||||
"lint:stylelint": "stylelint \"**/*.{vue,css,less,scss}\" --fix --cache --cache-location node_modules/.cache/stylelint/",
|
||||
"log": "conventional-changelog -p angular -i CHANGELOG.md -s",
|
||||
"prepare": "husky install",
|
||||
"preview": "npm run build && vite preview",
|
||||
"reinstall": "rimraf pnpm-lock.yaml && rimraf package.lock.json && rimraf node_modules && npm run bootstrap",
|
||||
@@ -66,89 +69,89 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons-vue": "^6.1.0",
|
||||
"@iconify/iconify": "^3.1.0",
|
||||
"@logicflow/core": "^1.2.1",
|
||||
"@logicflow/extension": "^1.2.1",
|
||||
"@ant-design/icons-vue": "^7.0.1",
|
||||
"@iconify/iconify": "^3.1.1",
|
||||
"@logicflow/core": "^1.2.26",
|
||||
"@logicflow/extension": "^1.2.26",
|
||||
"@vben/hooks": "workspace:*",
|
||||
"@vue/shared": "^3.2.47",
|
||||
"@vueuse/core": "^9.13.0",
|
||||
"@vueuse/shared": "^9.13.0",
|
||||
"@zxcvbn-ts/core": "^2.2.1",
|
||||
"ant-design-vue": "^3.2.17",
|
||||
"axios": "^1.3.5",
|
||||
"codemirror": "^5.65.12",
|
||||
"cropperjs": "^1.5.13",
|
||||
"crypto-js": "^4.1.1",
|
||||
"dayjs": "^1.11.7",
|
||||
"echarts": "^5.4.2",
|
||||
"exceljs": "^4.3.0",
|
||||
"intro.js": "^7.0.1",
|
||||
"@vue/shared": "^3.4.25",
|
||||
"@vueuse/core": "^10.9.0",
|
||||
"@zxcvbn-ts/core": "^3.0.4",
|
||||
"ant-design-vue": "^4.2.1",
|
||||
"axios": "^1.6.8",
|
||||
"codemirror": "^5.65.16",
|
||||
"cropperjs": "^1.6.2",
|
||||
"crypto-js": "^4.2.0",
|
||||
"dayjs": "^1.11.10",
|
||||
"echarts": "^5.5.0",
|
||||
"exceljs": "^4.4.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"mockjs": "^1.1.0",
|
||||
"nprogress": "^0.2.0",
|
||||
"path-to-regexp": "^6.2.1",
|
||||
"pinia": "2.0.33",
|
||||
"path-to-regexp": "^6.2.2",
|
||||
"pinia": "2.1.7",
|
||||
"pinia-plugin-persistedstate": "^3.2.1",
|
||||
"print-js": "^1.6.0",
|
||||
"qrcode": "^1.5.1",
|
||||
"qs": "^6.11.1",
|
||||
"qrcode": "^1.5.3",
|
||||
"qs": "^6.12.1",
|
||||
"resize-observer-polyfill": "^1.5.1",
|
||||
"showdown": "^2.1.0",
|
||||
"sortablejs": "^1.15.0",
|
||||
"tinymce": "^5.10.7",
|
||||
"vditor": "^3.9.1",
|
||||
"vue": "^3.2.47",
|
||||
"vue-i18n": "^9.2.2",
|
||||
"vue-json-pretty": "^2.2.4",
|
||||
"vue-router": "^4.1.6",
|
||||
"vue-types": "^5.0.2",
|
||||
"sortablejs": "^1.15.2",
|
||||
"tinymce": "^5.10.9",
|
||||
"unocss": "^0.59.4",
|
||||
"vditor": "^3.10.4",
|
||||
"vue": "^3.4.25",
|
||||
"vue-i18n": "^9.13.1",
|
||||
"vue-json-pretty": "^2.4.0",
|
||||
"vue-router": "^4.3.2",
|
||||
"vue-types": "^5.1.1",
|
||||
"vuedraggable": "^4.1.0",
|
||||
"vxe-table": "^4.3.11",
|
||||
"vxe-table-plugin-export-xlsx": "^3.0.4",
|
||||
"xe-utils": "^3.5.7",
|
||||
"vxe-table": "^4.6.3",
|
||||
"vxe-table-plugin-export-xlsx": "^4.0.1",
|
||||
"xe-utils": "^3.5.25",
|
||||
"xlsx": "^0.18.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^17.5.1",
|
||||
"@commitlint/config-conventional": "^17.4.4",
|
||||
"@iconify/json": "^2.2.46",
|
||||
"@purge-icons/generated": "^0.9.0",
|
||||
"@types/codemirror": "^5.60.7",
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
"@types/intro.js": "^5.1.1",
|
||||
"@types/lodash-es": "^4.17.7",
|
||||
"@types/mockjs": "^1.0.7",
|
||||
"@types/nprogress": "^0.2.0",
|
||||
"@types/qrcode": "^1.5.0",
|
||||
"@types/qs": "^6.9.7",
|
||||
"@types/showdown": "^2.0.0",
|
||||
"@types/sortablejs": "^1.15.1",
|
||||
"@commitlint/cli": "^19.3.0",
|
||||
"@commitlint/config-conventional": "^19.2.2",
|
||||
"@iconify/json": "^2.2.203",
|
||||
"@purge-icons/generated": "^0.10.0",
|
||||
"@types/codemirror": "^5.60.15",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/mockjs": "^1.0.10",
|
||||
"@types/nprogress": "^0.2.3",
|
||||
"@types/qrcode": "^1.5.5",
|
||||
"@types/qs": "^6.9.15",
|
||||
"@types/showdown": "^2.0.6",
|
||||
"@types/sortablejs": "^1.15.8",
|
||||
"@vben/eslint-config": "workspace:*",
|
||||
"@vben/stylelint-config": "workspace:*",
|
||||
"@vben/ts-config": "workspace:*",
|
||||
"@vben/types": "workspace:*",
|
||||
"@vben/vite-config": "workspace:*",
|
||||
"@vue/compiler-sfc": "^3.2.47",
|
||||
"@vue/test-utils": "^2.3.2",
|
||||
"@vue/compiler-sfc": "^3.4.25",
|
||||
"@vue/test-utils": "^2.4.5",
|
||||
"conventional-changelog-cli": "^4.1.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"cz-git": "^1.6.1",
|
||||
"czg": "^1.6.1",
|
||||
"husky": "^8.0.3",
|
||||
"lint-staged": "13.2.0",
|
||||
"prettier": "^2.8.7",
|
||||
"prettier-plugin-packagejson": "^2.4.3",
|
||||
"rimraf": "^4.4.1",
|
||||
"turbo": "^1.8.8",
|
||||
"typescript": "^5.0.3",
|
||||
"unbuild": "^1.2.0",
|
||||
"unplugin-vue-define-options": "^1.3.3",
|
||||
"vite": "^4.3.0-beta.2",
|
||||
"cz-git": "^1.9.1",
|
||||
"czg": "^1.9.1",
|
||||
"husky": "^9.0.11",
|
||||
"lint-staged": "15.2.2",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier-plugin-packagejson": "^2.5.0",
|
||||
"rimraf": "^5.0.5",
|
||||
"turbo": "^1.13.2",
|
||||
"typescript": "^5.4.5",
|
||||
"unbuild": "^2.0.0",
|
||||
"vite": "^5.2.10",
|
||||
"vite-plugin-mock": "^2.9.6",
|
||||
"vue-tsc": "^1.2.0"
|
||||
"vite-plugin-vue-inspector": "^5.0.1",
|
||||
"vue-tsc": "^2.0.14"
|
||||
},
|
||||
"packageManager": "pnpm@8.1.0",
|
||||
"packageManager": "pnpm@9.0.4",
|
||||
"engines": {
|
||||
"node": ">=16.15.1",
|
||||
"pnpm": ">=8.1.0"
|
||||
"node": ">=18.12.0",
|
||||
"pnpm": ">=9.0.2"
|
||||
}
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"default": "./src/index.ts"
|
||||
@@ -29,8 +30,9 @@
|
||||
"lint": "pnpm eslint ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@vueuse/core": "^9.13.0",
|
||||
"vue": "^3.2.47"
|
||||
"@vueuse/core": "^10.9.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"vue": "^3.4.25"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vben/types": "workspace:*"
|
||||
|
@@ -1,6 +1,7 @@
|
||||
export * from './onMountedOrActivated';
|
||||
export * from './useAttrs';
|
||||
export * from './useRefs';
|
||||
export * from './useRequest';
|
||||
export * from './useScrollTo';
|
||||
export * from './useWindowSizeFn';
|
||||
export { useTimeoutFn } from '@vueuse/core';
|
||||
|
@@ -1,18 +1,18 @@
|
||||
import type { Ref } from 'vue';
|
||||
import type { ComponentPublicInstance, Ref } from 'vue';
|
||||
import { onBeforeUpdate, shallowRef } from 'vue';
|
||||
|
||||
function useRefs(): {
|
||||
refs: Ref<HTMLElement[]>;
|
||||
setRefs: (index: number) => (el: HTMLElement) => void;
|
||||
function useRefs<T = HTMLElement>(): {
|
||||
refs: Ref<T[]>;
|
||||
setRefs: (index: number) => (el: Element | ComponentPublicInstance | null) => void;
|
||||
} {
|
||||
const refs = shallowRef([]) as Ref<HTMLElement[]>;
|
||||
const refs = shallowRef([]) as Ref<T[]>;
|
||||
|
||||
onBeforeUpdate(() => {
|
||||
refs.value = [];
|
||||
});
|
||||
|
||||
const setRefs = (index: number) => (el: HTMLElement) => {
|
||||
refs.value[index] = el;
|
||||
const setRefs = (index: number) => (el: Element | ComponentPublicInstance | null) => {
|
||||
refs.value[index] = el as T;
|
||||
};
|
||||
|
||||
return {
|
||||
|
147
packages/hooks/src/useRequest/Fetch.ts
Normal file
147
packages/hooks/src/useRequest/Fetch.ts
Normal file
@@ -0,0 +1,147 @@
|
||||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||
import { reactive } from 'vue';
|
||||
|
||||
import type { FetchState, PluginReturn, Service, Subscribe, UseRequestOptions } from './types';
|
||||
import { isFunction } from './utils/isFunction';
|
||||
|
||||
export default class Fetch<TData, TParams extends any[]> {
|
||||
pluginImpls: PluginReturn<TData, TParams>[] = [];
|
||||
|
||||
count: number = 0;
|
||||
|
||||
state: FetchState<TData, TParams> = reactive({
|
||||
loading: false,
|
||||
params: undefined,
|
||||
data: undefined,
|
||||
error: undefined,
|
||||
});
|
||||
|
||||
constructor(
|
||||
public serviceRef: Service<TData, TParams>,
|
||||
public options: UseRequestOptions<TData, TParams>,
|
||||
public subscribe: Subscribe,
|
||||
public initState: Partial<FetchState<TData, TParams>> = {},
|
||||
) {
|
||||
this.setState({ loading: !options.manual, ...initState });
|
||||
}
|
||||
|
||||
setState(s: Partial<FetchState<TData, TParams>> = {}) {
|
||||
Object.assign(this.state, s);
|
||||
this.subscribe();
|
||||
}
|
||||
|
||||
runPluginHandler(event: keyof PluginReturn<TData, TParams>, ...rest: any[]) {
|
||||
// @ts-ignore
|
||||
const r = this.pluginImpls.map((i) => i[event]?.(...rest)).filter(Boolean);
|
||||
return Object.assign({}, ...r);
|
||||
}
|
||||
|
||||
async runAsync(...params: TParams): Promise<TData> {
|
||||
this.count += 1;
|
||||
const currentCount = this.count;
|
||||
|
||||
const {
|
||||
stopNow = false,
|
||||
returnNow = false,
|
||||
...state
|
||||
} = this.runPluginHandler('onBefore', params);
|
||||
|
||||
// stop request
|
||||
if (stopNow) {
|
||||
return new Promise(() => {});
|
||||
}
|
||||
|
||||
this.setState({
|
||||
loading: true,
|
||||
params,
|
||||
...state,
|
||||
});
|
||||
|
||||
// return now
|
||||
if (returnNow) {
|
||||
return Promise.resolve(state.data);
|
||||
}
|
||||
|
||||
this.options.onBefore?.(params);
|
||||
|
||||
try {
|
||||
// replace service
|
||||
let { servicePromise } = this.runPluginHandler('onRequest', this.serviceRef, params);
|
||||
|
||||
if (!servicePromise) {
|
||||
servicePromise = this.serviceRef(...params);
|
||||
}
|
||||
|
||||
const res = await servicePromise;
|
||||
|
||||
if (currentCount !== this.count) {
|
||||
// prevent run.then when request is canceled
|
||||
return new Promise(() => {});
|
||||
}
|
||||
|
||||
// const formattedResult = this.options.formatResultRef.current ? this.options.formatResultRef.current(res) : res;
|
||||
|
||||
this.setState({ data: res, error: undefined, loading: false });
|
||||
|
||||
this.options.onSuccess?.(res, params);
|
||||
this.runPluginHandler('onSuccess', res, params);
|
||||
|
||||
this.options.onFinally?.(params, res, undefined);
|
||||
|
||||
if (currentCount === this.count) {
|
||||
this.runPluginHandler('onFinally', params, res, undefined);
|
||||
}
|
||||
|
||||
return res;
|
||||
} catch (error) {
|
||||
if (currentCount !== this.count) {
|
||||
// prevent run.then when request is canceled
|
||||
return new Promise(() => {});
|
||||
}
|
||||
|
||||
this.setState({ error, loading: false });
|
||||
|
||||
this.options.onError?.(error, params);
|
||||
this.runPluginHandler('onError', error, params);
|
||||
|
||||
this.options.onFinally?.(params, undefined, error);
|
||||
|
||||
if (currentCount === this.count) {
|
||||
this.runPluginHandler('onFinally', params, undefined, error);
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
run(...params: TParams) {
|
||||
this.runAsync(...params).catch((error) => {
|
||||
if (!this.options.onError) {
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
cancel() {
|
||||
this.count += 1;
|
||||
this.setState({ loading: false });
|
||||
|
||||
this.runPluginHandler('onCancel');
|
||||
}
|
||||
|
||||
refresh() {
|
||||
// @ts-ignore
|
||||
this.run(...(this.state.params || []));
|
||||
}
|
||||
|
||||
refreshAsync() {
|
||||
// @ts-ignore
|
||||
return this.runAsync(...(this.state.params || []));
|
||||
}
|
||||
|
||||
mutate(data?: TData | ((oldData?: TData) => TData | undefined)) {
|
||||
const targetData = isFunction(data) ? data(this.state.data) : data;
|
||||
this.runPluginHandler('onMutate', targetData);
|
||||
this.setState({ data: targetData });
|
||||
}
|
||||
}
|
30
packages/hooks/src/useRequest/index.ts
Normal file
30
packages/hooks/src/useRequest/index.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import useAutoRunPlugin from './plugins/useAutoRunPlugin';
|
||||
import useCachePlugin from './plugins/useCachePlugin';
|
||||
import useDebouncePlugin from './plugins/useDebouncePlugin';
|
||||
import useLoadingDelayPlugin from './plugins/useLoadingDelayPlugin';
|
||||
import usePollingPlugin from './plugins/usePollingPlugin';
|
||||
import useRefreshOnWindowFocusPlugin from './plugins/useRefreshOnWindowFocusPlugin';
|
||||
import useRetryPlugin from './plugins/useRetryPlugin';
|
||||
import useThrottlePlugin from './plugins/useThrottlePlugin';
|
||||
import type { Service, UseRequestOptions, UseRequestPlugin } from './types';
|
||||
import { useRequestImplement } from './useRequestImplement';
|
||||
|
||||
export { clearCache } from './utils/cache';
|
||||
|
||||
export function useRequest<TData, TParams extends any[]>(
|
||||
service: Service<TData, TParams>,
|
||||
options?: UseRequestOptions<TData, TParams>,
|
||||
plugins?: UseRequestPlugin<TData, TParams>[],
|
||||
) {
|
||||
return useRequestImplement<TData, TParams>(service, options, [
|
||||
...(plugins || []),
|
||||
useDebouncePlugin,
|
||||
useLoadingDelayPlugin,
|
||||
usePollingPlugin,
|
||||
useRefreshOnWindowFocusPlugin,
|
||||
useThrottlePlugin,
|
||||
useAutoRunPlugin,
|
||||
useCachePlugin,
|
||||
useRetryPlugin,
|
||||
] as UseRequestPlugin<TData, TParams>[]);
|
||||
}
|
52
packages/hooks/src/useRequest/plugins/useAutoRunPlugin.ts
Normal file
52
packages/hooks/src/useRequest/plugins/useAutoRunPlugin.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { ref, unref, watch } from 'vue';
|
||||
|
||||
import type { UseRequestPlugin } from '../types';
|
||||
|
||||
// support refreshDeps & ready
|
||||
const useAutoRunPlugin: UseRequestPlugin<any, any[]> = (
|
||||
fetchInstance,
|
||||
{ manual, ready = true, defaultParams = [], refreshDeps = [], refreshDepsAction },
|
||||
) => {
|
||||
const hasAutoRun = ref(false);
|
||||
|
||||
watch(
|
||||
() => unref(ready),
|
||||
(readyVal) => {
|
||||
if (!unref(manual) && readyVal) {
|
||||
hasAutoRun.value = true;
|
||||
fetchInstance.run(...defaultParams);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
if (refreshDeps.length) {
|
||||
watch(refreshDeps, () => {
|
||||
if (hasAutoRun.value) {
|
||||
return;
|
||||
}
|
||||
if (!manual) {
|
||||
if (refreshDepsAction) {
|
||||
refreshDepsAction();
|
||||
} else {
|
||||
fetchInstance.refresh();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
onBefore: () => {
|
||||
if (!unref(ready)) {
|
||||
return { stopNow: true };
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
useAutoRunPlugin.onInit = ({ ready = true, manual }) => {
|
||||
return {
|
||||
loading: !unref(manual) && unref(ready),
|
||||
};
|
||||
};
|
||||
|
||||
export default useAutoRunPlugin;
|
127
packages/hooks/src/useRequest/plugins/useCachePlugin.ts
Normal file
127
packages/hooks/src/useRequest/plugins/useCachePlugin.ts
Normal file
@@ -0,0 +1,127 @@
|
||||
import { onUnmounted, ref, watchEffect } from 'vue';
|
||||
|
||||
import type { UseRequestPlugin } from '../types';
|
||||
import type { CachedData } from '../utils/cache';
|
||||
import { getCache, setCache } from '../utils/cache';
|
||||
import { getCachePromise, setCachePromise } from '../utils/cachePromise';
|
||||
import { subscribe, trigger } from '../utils/cacheSubscribe';
|
||||
|
||||
const useCachePlugin: UseRequestPlugin<any, any[]> = (
|
||||
fetchInstance,
|
||||
{
|
||||
cacheKey,
|
||||
cacheTime = 5 * 60 * 1000,
|
||||
staleTime = 0,
|
||||
setCache: customSetCache,
|
||||
getCache: customGetCache,
|
||||
},
|
||||
) => {
|
||||
const unSubscribeRef = ref<() => void>();
|
||||
const currentPromiseRef = ref<Promise<any>>();
|
||||
|
||||
const _setCache = (key: string, cachedData: CachedData) => {
|
||||
customSetCache ? customSetCache(cachedData) : setCache(key, cacheTime, cachedData);
|
||||
trigger(key, cachedData.data);
|
||||
};
|
||||
|
||||
const _getCache = (key: string, params: any[] = []) => {
|
||||
return customGetCache ? customGetCache(params) : getCache(key);
|
||||
};
|
||||
|
||||
watchEffect(() => {
|
||||
if (!cacheKey) return;
|
||||
|
||||
// get data from cache when init
|
||||
const cacheData = _getCache(cacheKey);
|
||||
if (cacheData && Object.hasOwnProperty.call(cacheData, 'data')) {
|
||||
fetchInstance.state.data = cacheData.data;
|
||||
fetchInstance.state.params = cacheData.params;
|
||||
|
||||
if (staleTime === -1 || new Date().getTime() - cacheData.time <= staleTime) {
|
||||
fetchInstance.state.loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
// subscribe same cachekey update, trigger update
|
||||
unSubscribeRef.value = subscribe(cacheKey, (data) => {
|
||||
fetchInstance.setState({ data });
|
||||
});
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
unSubscribeRef.value?.();
|
||||
});
|
||||
|
||||
if (!cacheKey) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return {
|
||||
onBefore: (params) => {
|
||||
const cacheData = _getCache(cacheKey, params);
|
||||
|
||||
if (!cacheData || !Object.hasOwnProperty.call(cacheData, 'data')) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// If the data is fresh, stop request
|
||||
if (staleTime === -1 || new Date().getTime() - cacheData.time <= staleTime) {
|
||||
return {
|
||||
loading: false,
|
||||
data: cacheData?.data,
|
||||
error: undefined,
|
||||
returnNow: true,
|
||||
};
|
||||
} else {
|
||||
// If the data is stale, return data, and request continue
|
||||
return { data: cacheData?.data, error: undefined };
|
||||
}
|
||||
},
|
||||
onRequest: (service, args) => {
|
||||
let servicePromise = getCachePromise(cacheKey);
|
||||
|
||||
// If has servicePromise, and is not trigger by self, then use it
|
||||
if (servicePromise && servicePromise !== currentPromiseRef.value) {
|
||||
return { servicePromise };
|
||||
}
|
||||
|
||||
servicePromise = service(...args);
|
||||
currentPromiseRef.value = servicePromise;
|
||||
setCachePromise(cacheKey, servicePromise);
|
||||
|
||||
return { servicePromise };
|
||||
},
|
||||
onSuccess: (data, params) => {
|
||||
if (cacheKey) {
|
||||
// cancel subscribe, avoid trgger self
|
||||
unSubscribeRef.value?.();
|
||||
|
||||
_setCache(cacheKey, { data, params, time: new Date().getTime() });
|
||||
|
||||
// resubscribe
|
||||
unSubscribeRef.value = subscribe(cacheKey, (d) => {
|
||||
fetchInstance.setState({ data: d });
|
||||
});
|
||||
}
|
||||
},
|
||||
onMutate: (data) => {
|
||||
if (cacheKey) {
|
||||
// cancel subscribe, avoid trigger self
|
||||
unSubscribeRef.value?.();
|
||||
|
||||
_setCache(cacheKey, {
|
||||
data,
|
||||
params: fetchInstance.state.params,
|
||||
time: new Date().getTime(),
|
||||
});
|
||||
|
||||
// resubscribe
|
||||
unSubscribeRef.value = subscribe(cacheKey, (d) => {
|
||||
fetchInstance.setState({ data: d });
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export default useCachePlugin;
|
71
packages/hooks/src/useRequest/plugins/useDebouncePlugin.ts
Normal file
71
packages/hooks/src/useRequest/plugins/useDebouncePlugin.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import type { DebouncedFunc, DebounceSettings } from 'lodash-es';
|
||||
import { debounce } from 'lodash-es';
|
||||
import { computed, ref, watchEffect } from 'vue';
|
||||
|
||||
import type { UseRequestPlugin } from '../types';
|
||||
|
||||
const useDebouncePlugin: UseRequestPlugin<any, any[]> = (
|
||||
fetchInstance,
|
||||
{ debounceWait, debounceLeading, debounceTrailing, debounceMaxWait },
|
||||
) => {
|
||||
const debouncedRef = ref<DebouncedFunc<any>>();
|
||||
|
||||
const options = computed(() => {
|
||||
const ret: DebounceSettings = {};
|
||||
|
||||
if (debounceLeading !== undefined) {
|
||||
ret.leading = debounceLeading;
|
||||
}
|
||||
if (debounceTrailing !== undefined) {
|
||||
ret.trailing = debounceTrailing;
|
||||
}
|
||||
if (debounceMaxWait !== undefined) {
|
||||
ret.maxWait = debounceMaxWait;
|
||||
}
|
||||
|
||||
return ret;
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
if (debounceWait) {
|
||||
const _originRunAsync = fetchInstance.runAsync.bind(fetchInstance);
|
||||
|
||||
debouncedRef.value = debounce(
|
||||
(callback) => {
|
||||
callback();
|
||||
},
|
||||
debounceWait,
|
||||
options.value,
|
||||
);
|
||||
|
||||
// debounce runAsync should be promise
|
||||
// https://github.com/lodash/lodash/issues/4400#issuecomment-834800398
|
||||
fetchInstance.runAsync = (...args) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
debouncedRef.value?.(() => {
|
||||
_originRunAsync(...args)
|
||||
.then(resolve)
|
||||
.catch(reject);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return () => {
|
||||
debouncedRef.value?.cancel();
|
||||
fetchInstance.runAsync = _originRunAsync;
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
if (!debounceWait) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return {
|
||||
onCancel: () => {
|
||||
debouncedRef.value?.cancel();
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export default useDebouncePlugin;
|
@@ -0,0 +1,45 @@
|
||||
import { ref, unref } from 'vue';
|
||||
|
||||
import type { UseRequestPlugin, UseRequestTimeout } from '../types';
|
||||
|
||||
const useLoadingDelayPlugin: UseRequestPlugin<any, any[]> = (
|
||||
fetchInstance,
|
||||
{ loadingDelay, ready },
|
||||
) => {
|
||||
const timerRef = ref<UseRequestTimeout>();
|
||||
|
||||
if (!loadingDelay) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const cancelTimeout = () => {
|
||||
if (timerRef.value) {
|
||||
clearTimeout(timerRef.value);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
onBefore: () => {
|
||||
cancelTimeout();
|
||||
|
||||
// Two cases:
|
||||
// 1. ready === undefined
|
||||
// 2. ready === true
|
||||
if (unref(ready) !== false) {
|
||||
timerRef.value = setTimeout(() => {
|
||||
fetchInstance.setState({ loading: true });
|
||||
}, loadingDelay);
|
||||
}
|
||||
|
||||
return { loading: false };
|
||||
},
|
||||
onFinally: () => {
|
||||
cancelTimeout();
|
||||
},
|
||||
onCancel: () => {
|
||||
cancelTimeout();
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export default useLoadingDelayPlugin;
|
71
packages/hooks/src/useRequest/plugins/usePollingPlugin.ts
Normal file
71
packages/hooks/src/useRequest/plugins/usePollingPlugin.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import { ref, watch } from 'vue';
|
||||
|
||||
import type { UseRequestPlugin, UseRequestTimeout } from '../types';
|
||||
import { isDocumentVisible } from '../utils/isDocumentVisible';
|
||||
import subscribeReVisible from '../utils/subscribeReVisible';
|
||||
|
||||
const usePollingPlugin: UseRequestPlugin<any, any[]> = (
|
||||
fetchInstance,
|
||||
{ pollingInterval, pollingWhenHidden = true, pollingErrorRetryCount = -1 },
|
||||
) => {
|
||||
const timerRef = ref<UseRequestTimeout>();
|
||||
const unsubscribeRef = ref<() => void>();
|
||||
const countRef = ref<number>(0);
|
||||
|
||||
const stopPolling = () => {
|
||||
if (timerRef.value) {
|
||||
clearTimeout(timerRef.value);
|
||||
}
|
||||
unsubscribeRef.value?.();
|
||||
};
|
||||
|
||||
watch(
|
||||
() => pollingInterval,
|
||||
() => {
|
||||
if (!pollingInterval) {
|
||||
stopPolling();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
if (!pollingInterval) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return {
|
||||
onBefore: () => {
|
||||
stopPolling();
|
||||
},
|
||||
onError: () => {
|
||||
countRef.value += 1;
|
||||
},
|
||||
onSuccess: () => {
|
||||
countRef.value = 0;
|
||||
},
|
||||
onFinally: () => {
|
||||
if (
|
||||
pollingErrorRetryCount === -1 ||
|
||||
// When an error occurs, the request is not repeated after pollingErrorRetryCount retries
|
||||
(pollingErrorRetryCount !== -1 && countRef.value <= pollingErrorRetryCount)
|
||||
) {
|
||||
timerRef.value = setTimeout(() => {
|
||||
// if pollingWhenHidden = false && document is hidden, then stop polling and subscribe revisible
|
||||
if (!pollingWhenHidden && !isDocumentVisible()) {
|
||||
unsubscribeRef.value = subscribeReVisible(() => {
|
||||
fetchInstance.refresh();
|
||||
});
|
||||
} else {
|
||||
fetchInstance.refresh();
|
||||
}
|
||||
}, pollingInterval);
|
||||
} else {
|
||||
countRef.value = 0;
|
||||
}
|
||||
},
|
||||
onCancel: () => {
|
||||
stopPolling();
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export default usePollingPlugin;
|
@@ -0,0 +1,37 @@
|
||||
import { onUnmounted, ref, watchEffect } from 'vue';
|
||||
|
||||
import type { UseRequestPlugin } from '../types';
|
||||
import { limit } from '../utils/limit';
|
||||
import subscribeFocus from '../utils/subscribeFocus';
|
||||
|
||||
const useRefreshOnWindowFocusPlugin: UseRequestPlugin<any, any[]> = (
|
||||
fetchInstance,
|
||||
{ refreshOnWindowFocus, focusTimespan = 5000 },
|
||||
) => {
|
||||
const unsubscribeRef = ref<() => void>();
|
||||
|
||||
const stopSubscribe = () => {
|
||||
unsubscribeRef.value?.();
|
||||
};
|
||||
|
||||
watchEffect(() => {
|
||||
if (refreshOnWindowFocus) {
|
||||
const limitRefresh = limit(fetchInstance.refresh.bind(fetchInstance), focusTimespan);
|
||||
unsubscribeRef.value = subscribeFocus(() => {
|
||||
limitRefresh();
|
||||
});
|
||||
}
|
||||
|
||||
return () => {
|
||||
stopSubscribe();
|
||||
};
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
stopSubscribe();
|
||||
});
|
||||
|
||||
return {};
|
||||
};
|
||||
|
||||
export default useRefreshOnWindowFocusPlugin;
|
54
packages/hooks/src/useRequest/plugins/useRetryPlugin.ts
Normal file
54
packages/hooks/src/useRequest/plugins/useRetryPlugin.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { ref } from 'vue';
|
||||
|
||||
import type { UseRequestPlugin, UseRequestTimeout } from '../types';
|
||||
|
||||
const useRetryPlugin: UseRequestPlugin<any, any[]> = (
|
||||
fetchInstance,
|
||||
{ retryInterval, retryCount },
|
||||
) => {
|
||||
const timerRef = ref<UseRequestTimeout>();
|
||||
const countRef = ref(0);
|
||||
|
||||
const triggerByRetry = ref(false);
|
||||
|
||||
if (!retryCount) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return {
|
||||
onBefore: () => {
|
||||
if (!triggerByRetry.value) {
|
||||
countRef.value = 0;
|
||||
}
|
||||
triggerByRetry.value = false;
|
||||
|
||||
if (timerRef.value) {
|
||||
clearTimeout(timerRef.value);
|
||||
}
|
||||
},
|
||||
onSuccess: () => {
|
||||
countRef.value = 0;
|
||||
},
|
||||
onError: () => {
|
||||
countRef.value += 1;
|
||||
if (retryCount === -1 || countRef.value <= retryCount) {
|
||||
// Exponential backoff
|
||||
const timeout = retryInterval ?? Math.min(1000 * 2 ** countRef.value, 30000);
|
||||
timerRef.value = setTimeout(() => {
|
||||
triggerByRetry.value = true;
|
||||
fetchInstance.refresh();
|
||||
}, timeout);
|
||||
} else {
|
||||
countRef.value = 0;
|
||||
}
|
||||
},
|
||||
onCancel: () => {
|
||||
countRef.value = 0;
|
||||
if (timerRef.value) {
|
||||
clearTimeout(timerRef.value);
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export default useRetryPlugin;
|
63
packages/hooks/src/useRequest/plugins/useThrottlePlugin.ts
Normal file
63
packages/hooks/src/useRequest/plugins/useThrottlePlugin.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import type { DebouncedFunc, ThrottleSettings } from 'lodash-es';
|
||||
import { throttle } from 'lodash-es';
|
||||
import { ref, watchEffect } from 'vue';
|
||||
|
||||
import type { UseRequestPlugin } from '../types';
|
||||
|
||||
const useThrottlePlugin: UseRequestPlugin<any, any[]> = (
|
||||
fetchInstance,
|
||||
{ throttleWait, throttleLeading, throttleTrailing },
|
||||
) => {
|
||||
const throttledRef = ref<DebouncedFunc<any>>();
|
||||
|
||||
const options: ThrottleSettings = {};
|
||||
if (throttleLeading !== undefined) {
|
||||
options.leading = throttleLeading;
|
||||
}
|
||||
if (throttleTrailing !== undefined) {
|
||||
options.trailing = throttleTrailing;
|
||||
}
|
||||
|
||||
watchEffect(() => {
|
||||
if (throttleWait) {
|
||||
const _originRunAsync = fetchInstance.runAsync.bind(fetchInstance);
|
||||
|
||||
throttledRef.value = throttle(
|
||||
(callback) => {
|
||||
callback();
|
||||
},
|
||||
throttleWait,
|
||||
options,
|
||||
);
|
||||
|
||||
// throttle runAsync should be promise
|
||||
// https://github.com/lodash/lodash/issues/4400#issuecomment-834800398
|
||||
fetchInstance.runAsync = (...args) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
throttledRef.value?.(() => {
|
||||
_originRunAsync(...args)
|
||||
.then(resolve)
|
||||
.catch(reject);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return () => {
|
||||
fetchInstance.runAsync = _originRunAsync;
|
||||
throttledRef.value?.cancel();
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
if (!throttleWait) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return {
|
||||
onCancel: () => {
|
||||
throttledRef.value?.cancel();
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export default useThrottlePlugin;
|
124
packages/hooks/src/useRequest/types.ts
Normal file
124
packages/hooks/src/useRequest/types.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
import type { MaybeRef, Ref, WatchSource } from 'vue';
|
||||
|
||||
import type Fetch from './Fetch';
|
||||
import type { CachedData } from './utils/cache';
|
||||
|
||||
export type Service<TData, TParams extends any[]> = (...args: TParams) => Promise<TData>;
|
||||
export type Subscribe = () => void;
|
||||
|
||||
// for Fetch
|
||||
export interface FetchState<TData, TParams extends any[]> {
|
||||
loading: boolean;
|
||||
params?: TParams;
|
||||
data?: TData;
|
||||
error?: Error;
|
||||
}
|
||||
|
||||
export interface PluginReturn<TData, TParams extends any[]> {
|
||||
onBefore?: (params: TParams) =>
|
||||
| ({
|
||||
stopNow?: boolean;
|
||||
returnNow?: boolean;
|
||||
} & Partial<FetchState<TData, TParams>>)
|
||||
| void;
|
||||
|
||||
onRequest?: (
|
||||
service: Service<TData, TParams>,
|
||||
params: TParams,
|
||||
) => {
|
||||
servicePromise?: Promise<TData>;
|
||||
};
|
||||
|
||||
onSuccess?: (data: TData, params: TParams) => void;
|
||||
onError?: (e: Error, params: TParams) => void;
|
||||
onFinally?: (params: TParams, data?: TData, e?: Error) => void;
|
||||
onCancel?: () => void;
|
||||
onMutate?: (data: TData) => void;
|
||||
}
|
||||
|
||||
// for useRequestImplement
|
||||
export interface UseRequestOptions<TData, TParams extends any[]> {
|
||||
manual?: MaybeRef<boolean>;
|
||||
|
||||
onBefore?: (params: TParams) => void;
|
||||
onSuccess?: (data: TData, params: TParams) => void;
|
||||
onError?: (e: Error, params: TParams) => void;
|
||||
// formatResult?: (res: any) => TData;
|
||||
onFinally?: (params: TParams, data?: TData, e?: Error) => void;
|
||||
|
||||
defaultParams?: TParams;
|
||||
|
||||
// refreshDeps
|
||||
refreshDeps?: WatchSource<any>[];
|
||||
refreshDepsAction?: () => void;
|
||||
|
||||
// loading delay
|
||||
loadingDelay?: number;
|
||||
|
||||
// polling
|
||||
pollingInterval?: number;
|
||||
pollingWhenHidden?: boolean;
|
||||
pollingErrorRetryCount?: number;
|
||||
|
||||
// refresh on window focus
|
||||
refreshOnWindowFocus?: boolean;
|
||||
focusTimespan?: number;
|
||||
|
||||
// debounce
|
||||
debounceWait?: number;
|
||||
debounceLeading?: boolean;
|
||||
debounceTrailing?: boolean;
|
||||
debounceMaxWait?: number;
|
||||
|
||||
// throttle
|
||||
throttleWait?: number;
|
||||
throttleLeading?: boolean;
|
||||
throttleTrailing?: boolean;
|
||||
|
||||
// cache
|
||||
cacheKey?: string;
|
||||
cacheTime?: number;
|
||||
staleTime?: number;
|
||||
setCache?: (data: CachedData<TData, TParams>) => void;
|
||||
getCache?: (params: TParams) => CachedData<TData, TParams> | undefined;
|
||||
|
||||
// retry
|
||||
retryCount?: number;
|
||||
retryInterval?: number;
|
||||
|
||||
// ready
|
||||
ready?: MaybeRef<boolean>;
|
||||
|
||||
// [key: string]: any;
|
||||
}
|
||||
|
||||
export interface UseRequestPlugin<TData, TParams extends any[]> {
|
||||
// eslint-disable-next-line prettier/prettier
|
||||
(
|
||||
fetchInstance: Fetch<TData, TParams>,
|
||||
options: UseRequestOptions<TData, TParams>,
|
||||
): PluginReturn<TData, TParams>;
|
||||
onInit?: (options: UseRequestOptions<TData, TParams>) => Partial<FetchState<TData, TParams>>;
|
||||
}
|
||||
|
||||
// for index
|
||||
// export type OptionsWithoutFormat<TData, TParams extends any[]> = Omit<Options<TData, TParams>, 'formatResult'>;
|
||||
|
||||
// export interface OptionsWithFormat<TData, TParams extends any[], TFormated, TTFormated extends TFormated = any> extends Omit<Options<TTFormated, TParams>, 'formatResult'> {
|
||||
// formatResult: (res: TData) => TFormated;
|
||||
// };
|
||||
|
||||
export interface UseRequestResult<TData, TParams extends any[]> {
|
||||
loading: Ref<boolean>;
|
||||
data: Ref<TData>;
|
||||
error: Ref<Error>;
|
||||
params: Ref<TParams | []>;
|
||||
cancel: Fetch<TData, TParams>['cancel'];
|
||||
refresh: Fetch<TData, TParams>['refresh'];
|
||||
refreshAsync: Fetch<TData, TParams>['refreshAsync'];
|
||||
run: Fetch<TData, TParams>['run'];
|
||||
runAsync: Fetch<TData, TParams>['runAsync'];
|
||||
mutate: Fetch<TData, TParams>['mutate'];
|
||||
}
|
||||
|
||||
export type UseRequestTimeout = ReturnType<typeof setTimeout>;
|
49
packages/hooks/src/useRequest/useRequestImplement.ts
Normal file
49
packages/hooks/src/useRequest/useRequestImplement.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||
import { onMounted, onUnmounted, toRefs } from 'vue';
|
||||
|
||||
import Fetch from './Fetch';
|
||||
import type { Service, UseRequestOptions, UseRequestPlugin, UseRequestResult } from './types';
|
||||
|
||||
export function useRequestImplement<TData, TParams extends any[]>(
|
||||
service: Service<TData, TParams>,
|
||||
options: UseRequestOptions<TData, TParams> = {},
|
||||
plugins: UseRequestPlugin<TData, TParams>[] = [],
|
||||
) {
|
||||
const { manual = false, ...rest } = options;
|
||||
const fetchOptions = { manual, ...rest };
|
||||
|
||||
const initState = plugins.map((p) => p?.onInit?.(fetchOptions)).filter(Boolean);
|
||||
|
||||
const fetchInstance = new Fetch<TData, TParams>(
|
||||
service,
|
||||
fetchOptions,
|
||||
() => {},
|
||||
Object.assign({}, ...initState),
|
||||
);
|
||||
|
||||
fetchInstance.options = fetchOptions;
|
||||
// run all plugins hooks
|
||||
fetchInstance.pluginImpls = plugins.map((p) => p(fetchInstance, fetchOptions));
|
||||
|
||||
onMounted(() => {
|
||||
if (!manual) {
|
||||
const params = fetchInstance.state.params || options.defaultParams || [];
|
||||
// @ts-ignore
|
||||
fetchInstance.run(...params);
|
||||
}
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
fetchInstance.cancel();
|
||||
});
|
||||
|
||||
return {
|
||||
...toRefs(fetchInstance.state),
|
||||
cancel: fetchInstance.cancel.bind(fetchInstance),
|
||||
mutate: fetchInstance.mutate.bind(fetchInstance),
|
||||
refresh: fetchInstance.refresh.bind(fetchInstance),
|
||||
refreshAsync: fetchInstance.refreshAsync.bind(fetchInstance),
|
||||
run: fetchInstance.run.bind(fetchInstance),
|
||||
runAsync: fetchInstance.runAsync.bind(fetchInstance),
|
||||
} as UseRequestResult<TData, TParams>;
|
||||
}
|
48
packages/hooks/src/useRequest/utils/cache.ts
Normal file
48
packages/hooks/src/useRequest/utils/cache.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
type Timer = ReturnType<typeof setTimeout>;
|
||||
type CachedKey = string | number;
|
||||
|
||||
export interface CachedData<TData = any, TParams = any> {
|
||||
data: TData;
|
||||
params: TParams;
|
||||
time: number;
|
||||
}
|
||||
|
||||
interface RecordData extends CachedData {
|
||||
timer: Timer | undefined;
|
||||
}
|
||||
|
||||
const cache = new Map<CachedKey, RecordData>();
|
||||
|
||||
export const setCache = (key: CachedKey, cacheTime: number, cachedData: CachedData) => {
|
||||
const currentCache = cache.get(key);
|
||||
if (currentCache?.timer) {
|
||||
clearTimeout(currentCache.timer);
|
||||
}
|
||||
|
||||
let timer: Timer | undefined = undefined;
|
||||
|
||||
if (cacheTime > -1) {
|
||||
// if cache out, clear it
|
||||
timer = setTimeout(() => {
|
||||
cache.delete(key);
|
||||
}, cacheTime);
|
||||
}
|
||||
|
||||
cache.set(key, {
|
||||
...cachedData,
|
||||
timer,
|
||||
});
|
||||
};
|
||||
|
||||
export const getCache = (key: CachedKey) => {
|
||||
return cache.get(key);
|
||||
};
|
||||
|
||||
export const clearCache = (key?: string | string[]) => {
|
||||
if (key) {
|
||||
const cacheKeys = Array.isArray(key) ? key : [key];
|
||||
cacheKeys.forEach((cacheKey) => cache.delete(cacheKey));
|
||||
} else {
|
||||
cache.clear();
|
||||
}
|
||||
};
|
23
packages/hooks/src/useRequest/utils/cachePromise.ts
Normal file
23
packages/hooks/src/useRequest/utils/cachePromise.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
type CachedKey = string | number;
|
||||
|
||||
const cachePromise = new Map<CachedKey, Promise<any>>();
|
||||
|
||||
export const getCachePromise = (cacheKey: CachedKey) => {
|
||||
return cachePromise.get(cacheKey);
|
||||
};
|
||||
|
||||
export const setCachePromise = (cacheKey: CachedKey, promise: Promise<any>) => {
|
||||
// Should cache the same promise, cannot be promise.finally
|
||||
// Because the promise.finally will change the reference of the promise
|
||||
cachePromise.set(cacheKey, promise);
|
||||
|
||||
// no use promise.finally for compatibility
|
||||
promise
|
||||
.then((res) => {
|
||||
cachePromise.delete(cacheKey);
|
||||
return res;
|
||||
})
|
||||
.catch(() => {
|
||||
cachePromise.delete(cacheKey);
|
||||
});
|
||||
};
|
22
packages/hooks/src/useRequest/utils/cacheSubscribe.ts
Normal file
22
packages/hooks/src/useRequest/utils/cacheSubscribe.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
type Listener = (data: any) => void;
|
||||
|
||||
const listeners: Record<string, Listener[]> = {};
|
||||
|
||||
export const trigger = (key: string, data: any) => {
|
||||
if (listeners[key]) {
|
||||
listeners[key].forEach((item) => item(data));
|
||||
}
|
||||
};
|
||||
|
||||
export const subscribe = (key: string, listener: Listener) => {
|
||||
if (!listeners[key]) {
|
||||
listeners[key] = [];
|
||||
}
|
||||
|
||||
listeners[key].push(listener);
|
||||
|
||||
return function unsubscribe() {
|
||||
const index = listeners[key].indexOf(listener);
|
||||
listeners[key].splice(index, 1);
|
||||
};
|
||||
};
|
5
packages/hooks/src/useRequest/utils/isBrowser.ts
Normal file
5
packages/hooks/src/useRequest/utils/isBrowser.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export const isBrowser = !!(
|
||||
typeof window !== 'undefined' &&
|
||||
window.document &&
|
||||
window.document.createElement
|
||||
);
|
8
packages/hooks/src/useRequest/utils/isDocumentVisible.ts
Normal file
8
packages/hooks/src/useRequest/utils/isDocumentVisible.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { isBrowser } from './isBrowser';
|
||||
|
||||
export function isDocumentVisible(): boolean {
|
||||
if (isBrowser) {
|
||||
return document.visibilityState !== 'hidden';
|
||||
}
|
||||
return true;
|
||||
}
|
2
packages/hooks/src/useRequest/utils/isFunction.ts
Normal file
2
packages/hooks/src/useRequest/utils/isFunction.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export const isFunction = (value: unknown): value is (...args: any) => any =>
|
||||
typeof value === 'function';
|
8
packages/hooks/src/useRequest/utils/isOnline.ts
Normal file
8
packages/hooks/src/useRequest/utils/isOnline.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { isBrowser } from './isBrowser';
|
||||
|
||||
export function isOnline(): boolean {
|
||||
if (isBrowser && typeof navigator.onLine !== 'undefined') {
|
||||
return navigator.onLine;
|
||||
}
|
||||
return true;
|
||||
}
|
12
packages/hooks/src/useRequest/utils/limit.ts
Normal file
12
packages/hooks/src/useRequest/utils/limit.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
export function limit(fn: any, timespan: number) {
|
||||
let pending = false;
|
||||
|
||||
return (...args: any[]) => {
|
||||
if (pending) return;
|
||||
pending = true;
|
||||
fn(...args);
|
||||
setTimeout(() => {
|
||||
pending = false;
|
||||
}, timespan);
|
||||
};
|
||||
}
|
30
packages/hooks/src/useRequest/utils/subscribeFocus.ts
Normal file
30
packages/hooks/src/useRequest/utils/subscribeFocus.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { isBrowser } from './isBrowser';
|
||||
import { isDocumentVisible } from './isDocumentVisible';
|
||||
import { isOnline } from './isOnline';
|
||||
|
||||
type Listener = () => void;
|
||||
|
||||
const listeners: Listener[] = [];
|
||||
|
||||
if (isBrowser) {
|
||||
const revalidate = () => {
|
||||
if (!isDocumentVisible() || !isOnline()) return;
|
||||
for (let i = 0; i < listeners.length; i++) {
|
||||
const listener = listeners[i];
|
||||
listener();
|
||||
}
|
||||
};
|
||||
window.addEventListener('visibilitychange', revalidate, false);
|
||||
window.addEventListener('focus', revalidate, false);
|
||||
}
|
||||
|
||||
export default function subscribe(listener: Listener) {
|
||||
listeners.push(listener);
|
||||
|
||||
return function unsubscribe() {
|
||||
const index = listeners.indexOf(listener);
|
||||
if (index > -1) {
|
||||
listeners.splice(index, 1);
|
||||
}
|
||||
};
|
||||
}
|
25
packages/hooks/src/useRequest/utils/subscribeReVisible.ts
Normal file
25
packages/hooks/src/useRequest/utils/subscribeReVisible.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { isBrowser } from './isBrowser';
|
||||
import { isDocumentVisible } from './isDocumentVisible';
|
||||
|
||||
type Listener = () => void;
|
||||
|
||||
const listeners: Listener[] = [];
|
||||
|
||||
if (isBrowser) {
|
||||
const revalidate = () => {
|
||||
if (!isDocumentVisible()) return;
|
||||
for (let i = 0; i < listeners.length; i++) {
|
||||
const listener = listeners[i];
|
||||
listener();
|
||||
}
|
||||
};
|
||||
window.addEventListener('visibilitychange', revalidate, false);
|
||||
}
|
||||
|
||||
export default function subscribe(listener: Listener) {
|
||||
listeners.push(listener);
|
||||
return function unsubscribe() {
|
||||
const index = listeners.indexOf(listener);
|
||||
listeners.splice(index, 1);
|
||||
};
|
||||
}
|
@@ -12,6 +12,7 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"default": "./src/index.ts"
|
||||
|
@@ -26,7 +26,7 @@ type NonNullable<T> = T extends null | undefined ? never : T;
|
||||
/**
|
||||
* 字符串类型对象
|
||||
*/
|
||||
type Recordable<T> = Record<string, T>;
|
||||
type Recordable<T = any> = Record<string, T>;
|
||||
|
||||
/**
|
||||
* 字符串类型对象(只读)
|
||||
|
18658
pnpm-lock.yaml
generated
18658
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
23
src/App.vue
23
src/App.vue
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<ConfigProvider :locale="getAntdLocale">
|
||||
<ConfigProvider :locale="getAntdLocale" :theme="themeConfig">
|
||||
<AppProvider>
|
||||
<RouterView />
|
||||
</AppProvider>
|
||||
@@ -7,15 +7,34 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ConfigProvider } from 'ant-design-vue';
|
||||
import { AppProvider } from '@/components/Application';
|
||||
import { useTitle } from '@/hooks/web/useTitle';
|
||||
import { useLocale } from '@/locales/useLocale';
|
||||
import { ConfigProvider } from 'ant-design-vue';
|
||||
|
||||
import { useDarkModeTheme } from '@/hooks/setting/useDarkModeTheme';
|
||||
import 'dayjs/locale/zh-cn';
|
||||
import { computed } from 'vue';
|
||||
|
||||
// support Multi-language
|
||||
const { getAntdLocale } = useLocale();
|
||||
|
||||
const { isDark, darkTheme } = useDarkModeTheme();
|
||||
|
||||
const themeConfig = computed(() =>
|
||||
Object.assign(
|
||||
{
|
||||
token: {
|
||||
colorPrimary: '#0960bd',
|
||||
colorSuccess: '#55D187',
|
||||
colorWarning: '#EFBD47',
|
||||
colorError: '#ED6F6F',
|
||||
colorInfo: '#0960bd',
|
||||
},
|
||||
},
|
||||
isDark.value ? darkTheme : {},
|
||||
),
|
||||
);
|
||||
// Listening to page changes and dynamically changing site titles
|
||||
useTitle();
|
||||
</script>
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { defHttp } from '@/utils/http/axios';
|
||||
import { GetAccountInfoModel } from './model/accountModel';
|
||||
|
||||
enum Api {
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { AreaModel, AreaParams } from '/@/api/demo/model/areaModel';
|
||||
import { defHttp } from '@/utils/http/axios';
|
||||
import { AreaModel, AreaParams } from '@/api/demo/model/areaModel';
|
||||
|
||||
enum Api {
|
||||
AREA_RECORD = '/cascader/getAreaRecord',
|
||||
}
|
||||
|
||||
export const areaRecord = (data: AreaParams) =>
|
||||
defHttp.post<AreaModel>({ url: Api.AREA_RECORD, data });
|
||||
defHttp.post<AreaModel[]>({ url: Api.AREA_RECORD, data });
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { defHttp } from '@/utils/http/axios';
|
||||
|
||||
enum Api {
|
||||
// The address does not exist
|
||||
|
@@ -1,8 +1,8 @@
|
||||
import { BasicFetchResult } from '/@/api/model/baseModel';
|
||||
import { BasicFetchResult } from '@/api/model/baseModel';
|
||||
|
||||
export interface DemoOptionsItem {
|
||||
label: string;
|
||||
value: string;
|
||||
name: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
export interface selectParams {
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import { BasicPageParams, BasicFetchResult } from '/@/api/model/baseModel';
|
||||
import { BasicPageParams, BasicFetchResult } from '@/api/model/baseModel';
|
||||
|
||||
export type AccountParams = BasicPageParams & {
|
||||
account?: string;
|
||||
nickname?: string;
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
export type RoleParams = {
|
||||
|
@@ -1,8 +1,8 @@
|
||||
import { BasicPageParams, BasicFetchResult } from '/@/api/model/baseModel';
|
||||
import { BasicPageParams, BasicFetchResult } from '@/api/model/baseModel';
|
||||
/**
|
||||
* @description: Request list interface parameters
|
||||
*/
|
||||
export type DemoParams = BasicPageParams;
|
||||
export type DemoParams = Partial<BasicPageParams>;
|
||||
|
||||
export interface DemoListItem {
|
||||
id: string;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { defHttp } from '@/utils/http/axios';
|
||||
import { DemoOptionsItem, selectParams } from './model/optionsModel';
|
||||
|
||||
enum Api {
|
||||
|
@@ -10,7 +10,7 @@ import {
|
||||
RolePageListGetResultModel,
|
||||
RoleListGetResultModel,
|
||||
} from './model/systemModel';
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { defHttp } from '@/utils/http/axios';
|
||||
|
||||
enum Api {
|
||||
AccountList = '/system/getAccountList',
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { defHttp } from '@/utils/http/axios';
|
||||
import { DemoParams, DemoListGetResultModel } from './model/tableModel';
|
||||
|
||||
enum Api {
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { defHttp } from '@/utils/http/axios';
|
||||
|
||||
enum Api {
|
||||
TREE_OPTIONS_LIST = '/tree/getDemoOptions',
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { defHttp } from '@/utils/http/axios';
|
||||
import { getMenuListResultModel } from './model/menuModel';
|
||||
|
||||
enum Api {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user