Compare commits
793 Commits
45bf6914d0
...
b2c1df19c2
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b2c1df19c2 | ||
![]() |
a78304745c | ||
![]() |
32286efe79 | ||
![]() |
a1123251ae | ||
![]() |
468349658d | ||
![]() |
02c26790d8 | ||
![]() |
c77ff65b88 | ||
![]() |
ef3a8f3aa6 | ||
![]() |
2aad354c3f | ||
![]() |
2dc094c1db | ||
![]() |
9c528d9a8c | ||
![]() |
0472b823e7 | ||
![]() |
f71cf3cfb4 | ||
![]() |
8179ee8196 | ||
![]() |
8b8099ad09 | ||
![]() |
fd30362267 | ||
![]() |
1878f49e8d | ||
![]() |
ca0fe5ebae | ||
![]() |
ba78f8cc0d | ||
![]() |
a614dee5c6 | ||
![]() |
463faba9b9 | ||
![]() |
9dea8369e3 | ||
![]() |
592fb84aa7 | ||
![]() |
3019701856 | ||
![]() |
1ea70dd3ce | ||
![]() |
2a5ad70155 | ||
![]() |
9c8e3404bb | ||
![]() |
385bbb77a9 | ||
![]() |
70f7c06e55 | ||
![]() |
369f48ced5 | ||
![]() |
7f15f0e15a | ||
![]() |
7b48bd44a2 | ||
![]() |
7affcd27b7 | ||
![]() |
7de9f23226 | ||
![]() |
afc35feb8c | ||
![]() |
84d682a4a2 | ||
![]() |
b29c5bd2fa | ||
![]() |
e4c24a511a | ||
![]() |
9955a52059 | ||
![]() |
de22609196 | ||
![]() |
e5de3f4e9d | ||
![]() |
660d5b3d4f | ||
![]() |
d5eac17097 | ||
![]() |
6fe2317681 | ||
![]() |
e9e8a2eaaf | ||
![]() |
5ec984ac7d | ||
![]() |
c98a14e2ac | ||
![]() |
bbc656a26c | ||
![]() |
722acf0ae7 | ||
![]() |
15acd995f9 | ||
![]() |
35b90aa746 | ||
![]() |
de926211ef | ||
![]() |
30e1ea1c6d | ||
![]() |
8fa765f7be | ||
![]() |
7321b4c4ca | ||
![]() |
85608594bc | ||
![]() |
fc8b795bd9 | ||
![]() |
3a7fad80a8 | ||
![]() |
f5d557fe80 | ||
![]() |
8bff98ac72 | ||
![]() |
8fadab9741 | ||
![]() |
fba121f5c3 | ||
![]() |
48e9f2c5c0 | ||
![]() |
d8a395bfd1 | ||
![]() |
597c8370d3 | ||
![]() |
6b2838141a | ||
![]() |
b3edce5a20 | ||
![]() |
53424765f9 | ||
![]() |
b23b123613 | ||
![]() |
3eab423da5 | ||
![]() |
2e627832ae | ||
![]() |
8b5cf9a35f | ||
![]() |
78798f99ea | ||
![]() |
57f288c892 | ||
![]() |
0815fa2978 | ||
![]() |
7feead9afc | ||
![]() |
98728828ad | ||
![]() |
d9218fac24 | ||
![]() |
6d290785ef | ||
![]() |
f6400f3cbe | ||
![]() |
9d7f3101b9 | ||
![]() |
7784709cae | ||
![]() |
b5a4ebe2f6 | ||
![]() |
b814fb5105 | ||
![]() |
e98d43f50d | ||
![]() |
71b9d5d468 | ||
![]() |
e341b45429 | ||
![]() |
b2219cabec | ||
![]() |
abc6e4f454 | ||
![]() |
b1b63ebf7f | ||
![]() |
acc760a20f | ||
![]() |
62e3351bc7 | ||
![]() |
4fe828faa4 | ||
![]() |
21466ca8a1 | ||
![]() |
21234379b3 | ||
![]() |
44bf7e7212 | ||
![]() |
e91d11876f | ||
![]() |
a90f38734f | ||
![]() |
761f97e143 | ||
![]() |
bfcffc50e2 | ||
![]() |
07b8bc65ec | ||
![]() |
f241c187b3 | ||
![]() |
ef535a3f33 | ||
![]() |
a01545bc84 | ||
![]() |
bdaddb4bf6 | ||
![]() |
ace672dd0c | ||
![]() |
0539fa3c1f | ||
![]() |
18f89055e1 | ||
![]() |
7a8620c994 | ||
![]() |
e38d286c11 | ||
![]() |
05e7e93cf1 | ||
![]() |
f2adc5e5fa | ||
![]() |
7be0723c31 | ||
![]() |
eab4345198 | ||
![]() |
e040820dae | ||
![]() |
61b81f4692 | ||
![]() |
aef5a02097 | ||
![]() |
cc38d23d14 | ||
![]() |
74c29dc13e | ||
![]() |
b474a1cffc | ||
![]() |
e3219c434a | ||
![]() |
c28fbdfb27 | ||
![]() |
ef19e97109 | ||
![]() |
bb90dbc35b | ||
![]() |
770861ed33 | ||
![]() |
edf9529a10 | ||
![]() |
a11679dc0d | ||
![]() |
4d6a1ee73b | ||
![]() |
b43158914b | ||
![]() |
66580a05a8 | ||
![]() |
dccfa219d7 | ||
![]() |
b1f0b3c096 | ||
![]() |
b95a49c7d7 | ||
![]() |
2155d9f4b0 | ||
![]() |
fb7bca27eb | ||
![]() |
904ee32b24 | ||
![]() |
4839a5152f | ||
![]() |
c454efd713 | ||
![]() |
e8bbe0ac15 | ||
![]() |
b2a4157285 | ||
![]() |
5682b5f9c2 | ||
![]() |
a4eab94188 | ||
![]() |
8994e3ad3e | ||
![]() |
060f99dee5 | ||
![]() |
aef170f374 | ||
![]() |
bfc6e7b8da | ||
![]() |
5e440a7dc4 | ||
![]() |
3280baff16 | ||
![]() |
bbe94610a2 | ||
![]() |
4c12943e3c | ||
![]() |
25189f3052 | ||
![]() |
11e2695465 | ||
![]() |
0d493f1c74 | ||
![]() |
8d398d2940 | ||
![]() |
801700044c | ||
![]() |
3c2409169b | ||
![]() |
490eecccc5 | ||
![]() |
ecf2337205 | ||
![]() |
9cc8195237 | ||
![]() |
522087e18f | ||
![]() |
b7e96dec38 | ||
![]() |
71528c78ac | ||
![]() |
2fc220f9d3 | ||
![]() |
e0eed9c89a | ||
![]() |
e423d8afcf | ||
![]() |
100f44e197 | ||
![]() |
b39e0ad6db | ||
![]() |
2b1f5f2c70 | ||
![]() |
e521af0eae | ||
![]() |
b600fb34b5 | ||
![]() |
e29beed8bd | ||
![]() |
7772c7c7d6 | ||
![]() |
ed82954643 | ||
![]() |
1c28058141 | ||
![]() |
f5410dfff4 | ||
![]() |
1f93137b80 | ||
![]() |
8a034662c7 | ||
![]() |
7a9ccedadc | ||
![]() |
84888c3c28 | ||
![]() |
cc4186b578 | ||
![]() |
fd01b5a61f | ||
![]() |
00f7ab34ef | ||
![]() |
b61865f45f | ||
![]() |
4075b838fc | ||
![]() |
116a214ce6 | ||
![]() |
484db3c09e | ||
![]() |
150f1d793c | ||
![]() |
334ee0d40d | ||
![]() |
76f4824d2b | ||
![]() |
bf43f8aa3c | ||
![]() |
0874e32597 | ||
![]() |
23f372dad7 | ||
![]() |
5ca894369a | ||
![]() |
786f25bfd4 | ||
![]() |
06a8d871f7 | ||
![]() |
42b6668fd0 | ||
![]() |
6ef9b9a741 | ||
![]() |
98a8e96feb | ||
![]() |
7c1525fd21 | ||
![]() |
eb406fbb26 | ||
![]() |
845b848b60 | ||
![]() |
f3425493ed | ||
![]() |
f203716f31 | ||
![]() |
3b710d9e99 | ||
![]() |
3960c31975 | ||
![]() |
e3b5d7ca54 | ||
![]() |
a06db1a6f9 | ||
![]() |
247bf826d8 | ||
![]() |
6eeb711d2f | ||
![]() |
525be3cef0 | ||
![]() |
a5931a78f6 | ||
![]() |
971b4f60ec | ||
![]() |
51e4c44fd0 | ||
![]() |
a150c8c9a7 | ||
![]() |
9dd7bf8990 | ||
![]() |
24f1e8b4b1 | ||
![]() |
22e8a57b31 | ||
![]() |
ec0e6a167e | ||
![]() |
5f582c09ba | ||
![]() |
2ef0cf5bd5 | ||
![]() |
cdbbca43c4 | ||
![]() |
72ac227ecf | ||
![]() |
e2f18565d1 | ||
![]() |
9836d6d9bd | ||
![]() |
4310e5e049 | ||
![]() |
b19c2805e1 | ||
![]() |
fdfb556c8e | ||
![]() |
9ed3ae3fab | ||
![]() |
9a02598c00 | ||
![]() |
28a81f2e44 | ||
![]() |
6f4891d677 | ||
![]() |
a62a3de23c | ||
![]() |
1d852da351 | ||
![]() |
f0895e9419 | ||
![]() |
1644070e97 | ||
![]() |
4918552492 | ||
![]() |
364dfb969d | ||
![]() |
9726df3966 | ||
![]() |
483af13741 | ||
![]() |
25848ea99e | ||
![]() |
9f13c29cd7 | ||
![]() |
e1860a30fc | ||
![]() |
34b929d352 | ||
![]() |
1606dbd76f | ||
![]() |
3c2d9100b5 | ||
![]() |
2c8873402f | ||
![]() |
e5727893bb | ||
![]() |
335a1e6019 | ||
![]() |
c0ee3182e1 | ||
![]() |
9eb7b433b4 | ||
![]() |
9193f0b84a | ||
![]() |
076fc5deb1 | ||
![]() |
58412035ad | ||
![]() |
964db2dfce | ||
![]() |
d58a75996e | ||
![]() |
f5a5aaa255 | ||
![]() |
1465a27a6e | ||
![]() |
e5e43fe024 | ||
![]() |
6c49b47344 | ||
![]() |
358f11a0a3 | ||
![]() |
6a83ed2aad | ||
![]() |
e07c0b2b3a | ||
![]() |
adadfcf8cb | ||
![]() |
425386f6f4 | ||
![]() |
ba24afce52 | ||
![]() |
93d3371768 | ||
![]() |
3f08ae6ac4 | ||
![]() |
cc6284d3ac | ||
![]() |
142effd4f2 | ||
![]() |
e657a507e3 | ||
![]() |
ebaec24213 | ||
![]() |
7637582437 | ||
![]() |
27d36f7970 | ||
![]() |
762ebd4ede | ||
![]() |
ad991e248a | ||
![]() |
d1b58f0aaa | ||
![]() |
1be1eaf7b4 | ||
![]() |
fbcc967b14 | ||
![]() |
817c65f7e2 | ||
![]() |
b6dcc62f9c | ||
![]() |
abb4f543b9 | ||
![]() |
71f4d36c21 | ||
![]() |
d1be442c6e | ||
![]() |
9ef7fd3844 | ||
![]() |
fec61f9650 | ||
![]() |
c206ab5b4a | ||
![]() |
fe1942c247 | ||
![]() |
1f2add4b6b | ||
![]() |
3b254cc16b | ||
![]() |
3e7c2f26fa | ||
![]() |
4143285ec6 | ||
![]() |
72610ab194 | ||
![]() |
3c713c9258 | ||
![]() |
f95f6e8390 | ||
![]() |
2c9c837c1b | ||
![]() |
7904496df1 | ||
![]() |
15c3d84ca2 | ||
![]() |
e8a641f3a3 | ||
![]() |
e354db74a7 | ||
![]() |
61df97c4b9 | ||
![]() |
75ecc4dd68 | ||
![]() |
c467d95703 | ||
![]() |
3fead37924 | ||
![]() |
c8626b6893 | ||
![]() |
38df345078 | ||
![]() |
212361dc94 | ||
![]() |
f237ee145a | ||
![]() |
291d4b0040 | ||
![]() |
64c56e9dd9 | ||
![]() |
57d87df589 | ||
![]() |
9de3f25f6a | ||
![]() |
d98c2822d5 | ||
![]() |
58e6fdef78 | ||
![]() |
2c9daae153 | ||
![]() |
c2fdbc66b2 | ||
![]() |
57fd309907 | ||
![]() |
7a335b3438 | ||
![]() |
83bbac303e | ||
![]() |
eb1b614eb1 | ||
![]() |
a63543a5c7 | ||
![]() |
3585761b81 | ||
![]() |
34290d8cad | ||
![]() |
f367b49dd6 | ||
![]() |
7df347c1d4 | ||
![]() |
ea106e44be | ||
![]() |
b2e47f3938 | ||
![]() |
b8e0f018f0 | ||
![]() |
4ee46819c1 | ||
![]() |
0c620ef5b4 | ||
![]() |
9b00aaff93 | ||
![]() |
b829867a5b | ||
![]() |
736225fbfe | ||
![]() |
3062c46b49 | ||
![]() |
ed66231d19 | ||
![]() |
3b8ecadc78 | ||
![]() |
322e88d8e1 | ||
![]() |
526ca728e1 | ||
![]() |
26c0cdaef6 | ||
![]() |
e7dc8e94c7 | ||
![]() |
72ca7a1aae | ||
![]() |
907dc4efb4 | ||
![]() |
935a199f71 | ||
![]() |
a19ac2d4ca | ||
![]() |
437bc936fd | ||
![]() |
0b8f48fb61 | ||
![]() |
5d641e5de4 | ||
![]() |
0d196e47e2 | ||
![]() |
012e70c7e4 | ||
![]() |
9243eee3c3 | ||
![]() |
c449fb60a5 | ||
![]() |
4660aa6e95 | ||
![]() |
9968d14c39 | ||
![]() |
e2254651ca | ||
![]() |
7ed5f33e7b | ||
![]() |
175c4a48ce | ||
![]() |
9bcc4d631b | ||
![]() |
861dc9fb16 | ||
![]() |
8633a23d28 | ||
![]() |
d67bd493c1 | ||
![]() |
2d532d636a | ||
![]() |
e2bdae5bf2 | ||
![]() |
2df121072b | ||
![]() |
7016888d5a | ||
![]() |
3c34421bd2 | ||
![]() |
187ae83731 | ||
![]() |
c4c9905a91 | ||
![]() |
219f3a7d6f | ||
![]() |
44837e975c | ||
![]() |
8c6cf5bc43 | ||
![]() |
c21f0d7d77 | ||
![]() |
8b6b624f6c | ||
![]() |
03c736af82 | ||
![]() |
7386e69033 | ||
![]() |
2f60c96fbf | ||
![]() |
45e1c46ce4 | ||
![]() |
d7d3105c5c | ||
![]() |
4aa42f5c20 | ||
![]() |
c089f2497c | ||
![]() |
e18dcbd86b | ||
![]() |
a541d61c0c | ||
![]() |
4b19f55bce | ||
![]() |
b5042d13d2 | ||
![]() |
b444f2b8e2 | ||
![]() |
6b982984ac | ||
![]() |
30f271359a | ||
![]() |
9967a72e24 | ||
![]() |
efeff40f2e | ||
![]() |
2e299b58e2 | ||
![]() |
1d7c3da86b | ||
![]() |
5057976ad2 | ||
![]() |
41f3d37db1 | ||
![]() |
1fbc5afe75 | ||
![]() |
b0541be0b8 | ||
![]() |
d6803783ae | ||
![]() |
945eec5418 | ||
![]() |
73db6deec3 | ||
![]() |
40a75dae31 | ||
![]() |
64fb2899c9 | ||
![]() |
9da3f1f2d7 | ||
![]() |
70120a8f2f | ||
![]() |
6b4d756a9d | ||
![]() |
905426ad45 | ||
![]() |
b4b0eba228 | ||
![]() |
9f73ea2d32 | ||
![]() |
2d804c7ce0 | ||
![]() |
11e8e9d19a | ||
![]() |
3e44c14286 | ||
![]() |
04f1347ddd | ||
![]() |
0442bd638d | ||
![]() |
aeac77b90f | ||
![]() |
b117a6f198 | ||
![]() |
e1b03258e8 | ||
![]() |
c71eb21416 | ||
![]() |
c922ea3b9c | ||
![]() |
d76f2b857d | ||
![]() |
eec050a2dd | ||
![]() |
b0087d1a50 | ||
![]() |
4752b4eb01 | ||
![]() |
2ea1807f34 | ||
![]() |
5dfc25a493 | ||
![]() |
c5b3c121c9 | ||
![]() |
c417c6debe | ||
![]() |
f6727d80b8 | ||
![]() |
ceb6243cd0 | ||
![]() |
cd129aa949 | ||
![]() |
d186c800f0 | ||
![]() |
31f4219f3d | ||
![]() |
ad8565d29a | ||
![]() |
66a31b620b | ||
![]() |
e26f6423aa | ||
![]() |
12461f4106 | ||
![]() |
58422616e2 | ||
![]() |
f6abd4cf59 | ||
![]() |
f50ed6b2c5 | ||
![]() |
3dba22c47c | ||
![]() |
e1289d0abb | ||
![]() |
9ea8b710ff | ||
![]() |
e889348562 | ||
![]() |
02daeead57 | ||
![]() |
4253b2afbb | ||
![]() |
0c39b593ce | ||
![]() |
8761392c85 | ||
![]() |
30cf3a2caa | ||
![]() |
12458177be | ||
![]() |
b6415c21be | ||
![]() |
bc4358f4eb | ||
![]() |
5dcfee4c07 | ||
![]() |
a9cd5684b2 | ||
![]() |
1c0e614d7d | ||
![]() |
00a7a8ce23 | ||
![]() |
ade0b3e29e | ||
![]() |
3a3f873834 | ||
![]() |
1edc953765 | ||
![]() |
1383f5a7eb | ||
![]() |
e4f18452c7 | ||
![]() |
fdf64a6f08 | ||
![]() |
f46a333778 | ||
![]() |
eb364873d2 | ||
![]() |
7666f724df | ||
![]() |
f9b8922bed | ||
![]() |
fb94a4d79c | ||
![]() |
71047fdbfd | ||
![]() |
2cb9b3ea47 | ||
![]() |
3c27c18889 | ||
![]() |
9defb9a669 | ||
![]() |
8833eb205b | ||
![]() |
15129079d4 | ||
![]() |
d1c199d4bf | ||
![]() |
97b4eef342 | ||
![]() |
1dd9983f0f | ||
![]() |
b8eb2dcb40 | ||
![]() |
3b4f171d9f | ||
![]() |
de33d4aaee | ||
![]() |
803d44cac0 | ||
![]() |
cc293536e2 | ||
![]() |
5f6057253f | ||
![]() |
d50c90afd1 | ||
![]() |
6f9851a4e5 | ||
![]() |
e7ff829502 | ||
![]() |
0108df1334 | ||
![]() |
542f73f0e6 | ||
![]() |
5cb40abe18 | ||
![]() |
26cfa7afc4 | ||
![]() |
df1a84d5ae | ||
![]() |
5b991be4c2 | ||
![]() |
34c0d2d277 | ||
![]() |
b2f00c4b71 | ||
![]() |
63ba90cc10 | ||
![]() |
3b18a476b7 | ||
![]() |
15243ab713 | ||
![]() |
b4cc7b3de0 | ||
![]() |
fe3874396d | ||
![]() |
fdf885c261 | ||
![]() |
7b7377fa1b | ||
![]() |
0c56f87e06 | ||
![]() |
b783b8d991 | ||
![]() |
4ea7376dbc | ||
![]() |
5910032908 | ||
![]() |
024783588e | ||
![]() |
acba493c94 | ||
![]() |
7073acb3ef | ||
![]() |
075c02b8c3 | ||
![]() |
31da01bdd1 | ||
![]() |
dfdcee9b95 | ||
![]() |
d3b630076a | ||
![]() |
173c723c7c | ||
![]() |
595a521a3c | ||
![]() |
d08f14d86d | ||
![]() |
b112b793d5 | ||
![]() |
6432d165c7 | ||
![]() |
e5772cb63c | ||
![]() |
bb696b300f | ||
![]() |
14f6a214f2 | ||
![]() |
bbcedd02ba | ||
![]() |
abf2777b2e | ||
![]() |
3922c16601 | ||
![]() |
321f21c498 | ||
![]() |
085ce4cf43 | ||
![]() |
c5daf629d9 | ||
![]() |
20b7819f11 | ||
![]() |
8b36cac09d | ||
![]() |
0e99163f0c | ||
![]() |
772885de35 | ||
![]() |
1d557a24f9 | ||
![]() |
597f2b4461 | ||
![]() |
cc9b67d467 | ||
![]() |
70a3348954 | ||
![]() |
2c95f86963 | ||
![]() |
1272e8fe7d | ||
![]() |
3204aa8461 | ||
![]() |
5d44f9e231 | ||
![]() |
1d5133b695 | ||
![]() |
031d83828a | ||
![]() |
0541af5abb | ||
![]() |
1f71044cff | ||
![]() |
f32a7105c3 | ||
![]() |
b06f6a316b | ||
![]() |
58d7e50de3 | ||
![]() |
c045276a7c | ||
![]() |
6a7ec81168 | ||
![]() |
183e0e9212 | ||
![]() |
c020c1affc | ||
![]() |
9673380f60 | ||
![]() |
9b28d14bc3 | ||
![]() |
01a4dd0b45 | ||
![]() |
e1023bb331 | ||
![]() |
5c701801db | ||
![]() |
9b4692b625 | ||
![]() |
aaec0f7bfe | ||
![]() |
25e2e0e018 | ||
![]() |
5165541780 | ||
![]() |
b3c1b95437 | ||
![]() |
d84fee9319 | ||
![]() |
d034236ce3 | ||
![]() |
9e89ab5bae | ||
![]() |
6e6062e824 | ||
![]() |
35bebf403c | ||
![]() |
0a8c33c3cb | ||
![]() |
8a7de17b58 | ||
![]() |
f65eb2aee5 | ||
![]() |
efb53d4bcb | ||
![]() |
ad2134f07d | ||
![]() |
caa9d0fcdc | ||
![]() |
b829ba4aa0 | ||
![]() |
a232437abc | ||
![]() |
f2372d3243 | ||
![]() |
a8a334b3c3 | ||
![]() |
1e3f18ce22 | ||
![]() |
631f338be2 | ||
![]() |
bf977fe00a | ||
![]() |
5bc7044032 | ||
![]() |
6ad0ed5316 | ||
![]() |
ccb2ecc5ee | ||
![]() |
ec0cb472df | ||
![]() |
cd0a459c2b | ||
![]() |
18fea86a2c | ||
![]() |
66bfff450c | ||
![]() |
ec34c759ec | ||
![]() |
c1c5ea5e9d | ||
![]() |
6fe269efc7 | ||
![]() |
920e079727 | ||
![]() |
a2f13185e1 | ||
![]() |
078bb50130 | ||
![]() |
4854d8df00 | ||
![]() |
ecf062605d | ||
![]() |
b989b07121 | ||
![]() |
bf957f06a0 | ||
![]() |
aed8c89ded | ||
![]() |
4085811d24 | ||
![]() |
fe384a3020 | ||
![]() |
c6f3cd068e | ||
![]() |
99a6b56233 | ||
![]() |
8ed32775cb | ||
![]() |
395db813b5 | ||
![]() |
ab1a7204fa | ||
![]() |
92b2b489a4 | ||
![]() |
956d2ad495 | ||
![]() |
cb6cbc4f40 | ||
![]() |
14538ce399 | ||
![]() |
6c16d023f4 | ||
![]() |
d12d21c46d | ||
![]() |
93fb212e0c | ||
![]() |
b22d0775b7 | ||
![]() |
c85f0a1995 | ||
![]() |
78d120c423 | ||
![]() |
e43149f8e6 | ||
![]() |
1d8664ab1d | ||
![]() |
e7529fbb8f | ||
![]() |
e10f112fa0 | ||
![]() |
e906b8ad0a | ||
![]() |
1690563ef0 | ||
![]() |
9087fad3fe | ||
![]() |
f3195be732 | ||
![]() |
73df6a1b30 | ||
![]() |
b221ff2566 | ||
![]() |
50891e99ac | ||
![]() |
53ac5fb43c | ||
![]() |
7e54fe7921 | ||
![]() |
3637c16d86 | ||
![]() |
b045cb4239 | ||
![]() |
0c791a1efc | ||
![]() |
0082354aba | ||
![]() |
acbdfc4639 | ||
![]() |
f801f4fb11 | ||
![]() |
d532dc6fc0 | ||
![]() |
452972c1e4 | ||
![]() |
ac3ad63894 | ||
![]() |
d69f0992c7 | ||
![]() |
e64f4b83c8 | ||
![]() |
2b1cbaf8a0 | ||
![]() |
6c86aa42fd | ||
![]() |
e79a9cf797 | ||
![]() |
4af9f025b0 | ||
![]() |
2a1d0edd4e | ||
![]() |
75e72bf974 | ||
![]() |
1d33b01c66 | ||
![]() |
73c14596ed | ||
![]() |
5fa3f9a350 | ||
![]() |
64aea65cef | ||
![]() |
a681353fe1 | ||
![]() |
9719d6d75c | ||
![]() |
c13c622eac | ||
![]() |
d160c3a61c | ||
![]() |
81195fd9c8 | ||
![]() |
d0d67b90bc | ||
![]() |
9e3dd2c6e3 | ||
![]() |
5920b10514 | ||
![]() |
617dfe3161 | ||
![]() |
40175c150c | ||
![]() |
d930b15104 | ||
![]() |
cc69786fd1 | ||
![]() |
4cf836055a | ||
![]() |
88b376bbc2 | ||
![]() |
3fb8f1c251 | ||
![]() |
a8f575fe6f | ||
![]() |
14cf3be392 | ||
![]() |
6e3aec7c50 | ||
![]() |
2b7ffdf19c | ||
![]() |
db6e95bb96 | ||
![]() |
7b6078a178 | ||
![]() |
892c84f32a | ||
![]() |
9b6dc3e844 | ||
![]() |
3b4950e0e3 | ||
![]() |
7340997cf5 | ||
![]() |
3b4ac3e525 | ||
![]() |
cab430a428 | ||
![]() |
538c52a3ad | ||
![]() |
25e80590f6 | ||
![]() |
7f68832edd | ||
![]() |
374ee5d1a8 | ||
![]() |
d557602f2d | ||
![]() |
18dd68edd5 | ||
![]() |
13bb23c717 | ||
![]() |
319b37fe98 | ||
![]() |
a8ed066d8d | ||
![]() |
40e3bcb391 | ||
![]() |
aae6bb7505 | ||
![]() |
952a2ba906 | ||
![]() |
3b3fb80231 | ||
![]() |
a46c511f1f | ||
![]() |
ed84745897 | ||
![]() |
44ea10d9c7 | ||
![]() |
41d140af11 | ||
![]() |
0f54604435 | ||
![]() |
d43ae50abc | ||
![]() |
9f038ad181 | ||
![]() |
dbfe263681 | ||
![]() |
6af68085ff | ||
![]() |
490d4ef47e | ||
![]() |
bc48b224eb | ||
![]() |
9cd7f6cabb | ||
![]() |
3267f59603 | ||
![]() |
bc4554baeb | ||
![]() |
e6a3b6360f | ||
![]() |
548550bb42 | ||
![]() |
7c09eb50a7 | ||
![]() |
d6cb1c6634 | ||
![]() |
cbff04778b | ||
![]() |
f6994e5908 | ||
![]() |
06bc04c04c | ||
![]() |
226e0f3494 | ||
![]() |
7757d96f34 | ||
![]() |
a8ad928324 | ||
![]() |
f0df76aa8b | ||
![]() |
0ede92a2e5 | ||
![]() |
21ab064cf7 | ||
![]() |
84212c0a1b | ||
![]() |
6de98250cc | ||
![]() |
997f565add | ||
![]() |
a326e663cd | ||
![]() |
bf4a8543ca | ||
![]() |
9b6cd8b047 | ||
![]() |
46e7d070a2 | ||
![]() |
ec29c057c4 | ||
![]() |
2885d7e31c | ||
![]() |
0e736c889f | ||
![]() |
d192f73ca4 | ||
![]() |
351eedacec | ||
![]() |
67864e67b3 | ||
![]() |
f5a21c9b6f | ||
![]() |
b9dccb325f | ||
![]() |
7cfaeb5531 | ||
![]() |
94f96181f3 | ||
![]() |
5dda9da40d | ||
![]() |
1eda36201a | ||
![]() |
4722a8ef9b | ||
![]() |
0ba7e31e09 | ||
![]() |
61417032b7 | ||
![]() |
a0bcdf0cde | ||
![]() |
b263918426 | ||
![]() |
771f49354a | ||
![]() |
ab12c9cc94 | ||
![]() |
2976130876 | ||
![]() |
2ddd42bbab | ||
![]() |
f2d1522c34 | ||
![]() |
fda317b628 | ||
![]() |
f153da4390 | ||
![]() |
20f64b54d5 | ||
![]() |
4775803427 | ||
![]() |
d2bce3fcbe | ||
![]() |
55e29ce697 | ||
![]() |
802f6240d4 | ||
![]() |
91bb79e29f | ||
![]() |
fb14197b0e | ||
![]() |
e2bc12d186 | ||
![]() |
b88a09dd7f | ||
![]() |
2ede1095a3 | ||
![]() |
c32e3ce2c9 | ||
![]() |
c25842a0e5 | ||
![]() |
e7c777ac50 | ||
![]() |
1a5ed27067 | ||
![]() |
fed8eb76f6 | ||
![]() |
f9298a3f41 | ||
![]() |
155f22b72c | ||
![]() |
dd01200e2a | ||
![]() |
35eafbb065 | ||
![]() |
a05a782ef5 | ||
![]() |
14b4508b91 | ||
![]() |
8111ed9a84 | ||
![]() |
9a070b0074 | ||
![]() |
a79fa2527a | ||
![]() |
c65536ee6f | ||
![]() |
ccbe849103 | ||
![]() |
f0b52d7abb | ||
![]() |
d37e031014 | ||
![]() |
07a9b6e612 | ||
![]() |
f4522d2caa | ||
![]() |
582df2e467 | ||
![]() |
8c866f4596 | ||
![]() |
3b3f26f610 | ||
![]() |
d4ffd28ffb | ||
![]() |
ee59b3be8b | ||
![]() |
97187b246b | ||
![]() |
a7a31b011a | ||
![]() |
1595cb282a | ||
![]() |
8b01bfd2a0 | ||
![]() |
60d064b319 | ||
![]() |
cc0bedffb9 | ||
![]() |
3b93c8ac56 | ||
![]() |
631a831609 | ||
![]() |
327e60d9f3 | ||
![]() |
457b443404 | ||
![]() |
0408b67d6d | ||
![]() |
c7c63c51de | ||
![]() |
d95fab75a7 | ||
![]() |
251d2411f2 | ||
![]() |
5c87f1cb2c | ||
![]() |
d2a44d682d | ||
![]() |
4a5ba86e38 | ||
![]() |
eec0fd43a3 | ||
![]() |
8fec6cc405 | ||
![]() |
6b6c78fa02 | ||
![]() |
d68654327a |
@ -315,6 +315,9 @@
|
||||
"watchThrottled": true,
|
||||
"watchTriggerable": true,
|
||||
"watchWithFilter": true,
|
||||
"whenever": true
|
||||
"whenever": true,
|
||||
"Slot": true,
|
||||
"Slots": true,
|
||||
"createRef": true
|
||||
}
|
||||
}
|
||||
|
19
README.md
19
README.md
@ -2,16 +2,23 @@
|
||||
|
||||
- 本仓库为前端技术栈 [Vue3](https://v3.cn.vuejs.org) + [TS](https://www.typescriptlang.org/) + [Element Plus](https://element-plus.org/zh-CN) + [Vite](https://cn.vitejs.dev) 版本。
|
||||
- 成员项目: 基于 vben5(ant-design-vue) 的前端项目 [ruoyi-plus-vben5](https://gitee.com/dapppp/ruoyi-plus-vben5)
|
||||
- 配套后端代码仓库地址
|
||||
- [RuoYi-Vue-Plus 5.X(注意版本号)](https://gitee.com/dromara/RuoYi-Vue-Plus)
|
||||
- [RuoYi-Cloud-Plus 2.X(注意版本号)](https://gitee.com/dromara/RuoYi-Cloud-Plus)
|
||||
- 成员项目: 基于soybean 的前端项目 [ruoyi-plus-soybean](https://gitee.com/xlsea/ruoyi-plus-soybean)
|
||||
|
||||
## 配套后端代码仓库地址
|
||||
|
||||
| 介绍 | 项目名 | 项目地址 |
|
||||
|------------|:-----------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 🔥 分布式集群框架 | RuoYi-Vue-Plus | - [Gitee](https://gitee.com/dromara/RuoYi-Vue-Plus)<br> - [GitHub](https://github.com/dromara/RuoYi-Vue-Plus)<br> - [GitCode](https://gitcode.com/dromara/RuoYi-Vue-Plus) |
|
||||
| 🔥 微服务框架 | RuoYi-Cloud-Plus | - [Gitee](https://gitee.com/dromara/RuoYi-Cloud-Plus)<br>- [GitHub](https://github.com/dromara/RuoYi-Cloud-Plus)<br> - [GitCode](https://gitcode.com/dromara/RuoYi-Cloud-Plus) |
|
||||
|
||||
## 分支说明
|
||||
|
||||
- ts分支(稳定发布主分支 生产可用)
|
||||
- dev分支(开发分支 开发过程中使用)
|
||||
|
||||
## 前端运行
|
||||
|
||||
```bash
|
||||
# 克隆项目
|
||||
git clone https://gitee.com/JavaLionLi/plus-ui.git
|
||||
|
||||
# 安装依赖
|
||||
npm install --registry=https://registry.npmmirror.com
|
||||
|
||||
|
51
package.json
51
package.json
@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package",
|
||||
"name": "lx-vue-plus",
|
||||
"version": "5.3.1-2.3.0",
|
||||
"name": "ruoyi-vue-plus",
|
||||
"version": "5.4.0-2.4.0",
|
||||
"description": "龙翔管理系统",
|
||||
"author": "LionLi",
|
||||
"license": "MIT",
|
||||
@ -23,31 +23,31 @@
|
||||
"@element-plus/icons-vue": "2.3.1",
|
||||
"@highlightjs/vue-plugin": "2.1.0",
|
||||
"@vueup/vue-quill": "1.2.0",
|
||||
"@vueuse/core": "12.7.0",
|
||||
"@vueuse/core": "13.1.0",
|
||||
"animate.css": "4.1.1",
|
||||
"await-to-js": "3.0.0",
|
||||
"axios": "1.7.8",
|
||||
"axios": "1.8.4",
|
||||
"crypto-js": "4.2.0",
|
||||
"echarts": "5.5.0",
|
||||
"element-plus": "2.8.8",
|
||||
"echarts": "5.6.0",
|
||||
"element-plus": "2.9.8",
|
||||
"file-saver": "2.0.5",
|
||||
"highlight.js": "11.9.0",
|
||||
"image-conversion": "2.1.1",
|
||||
"js-cookie": "3.0.5",
|
||||
"jsencrypt": "3.3.2",
|
||||
"nprogress": "0.2.0",
|
||||
"pinia": "2.2.6",
|
||||
"pinia": "3.0.2",
|
||||
"screenfull": "6.0.2",
|
||||
"vue": "3.5.13",
|
||||
"vue-cropper": "1.1.1",
|
||||
"vue-i18n": "10.0.5",
|
||||
"vue-i18n": "11.1.3",
|
||||
"vue-json-pretty": "2.4.0",
|
||||
"vue-router": "4.4.5",
|
||||
"vue-types": "5.1.3",
|
||||
"vxe-table": "4.5.22"
|
||||
"vue-router": "4.5.0",
|
||||
"vue-types": "6.0.0",
|
||||
"vxe-table": "4.13.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify/json": "2.2.276",
|
||||
"@iconify/json": "^2.2.276",
|
||||
"@types/crypto-js": "4.2.2",
|
||||
"@types/file-saver": "2.0.7",
|
||||
"@types/js-cookie": "3.0.6",
|
||||
@ -56,8 +56,8 @@
|
||||
"@unocss/preset-attributify": "66.0.0",
|
||||
"@unocss/preset-icons": "66.0.0",
|
||||
"@unocss/preset-uno": "66.0.0",
|
||||
"@vitejs/plugin-vue": "5.2.1",
|
||||
"@vue/compiler-sfc": "3.4.23",
|
||||
"@vitejs/plugin-vue": "5.2.3",
|
||||
"@vue/compiler-sfc": "3.5.13",
|
||||
"@vue/eslint-config-prettier": "10.2.0",
|
||||
"@vue/eslint-config-typescript": "14.4.0",
|
||||
"autoprefixer": "10.4.20",
|
||||
@ -66,19 +66,22 @@
|
||||
"eslint-plugin-vue": "9.32.0",
|
||||
"globals": "16.0.0",
|
||||
"prettier": "3.5.2",
|
||||
"sass": "1.84.0",
|
||||
"typescript": "~5.7.3",
|
||||
"sass": "1.87.0",
|
||||
"typescript": "~5.8.3",
|
||||
"unocss": "66.0.0",
|
||||
"unplugin-auto-import": "0.17.5",
|
||||
"unplugin-icons": "0.18.5",
|
||||
"unplugin-vue-components": "28.0.0",
|
||||
"unplugin-auto-import": "19.1.2",
|
||||
"unplugin-icons": "22.1.0",
|
||||
"unplugin-vue-components": "28.5.0",
|
||||
"unplugin-vue-setup-extend-plus": "1.0.1",
|
||||
"vite": "5.4.11",
|
||||
"vite": "6.3.2",
|
||||
"vite-plugin-compression": "0.5.1",
|
||||
"vite-plugin-svg-icons-ng": "^1.2.2",
|
||||
"vite-plugin-vue-devtools": "7.7.1",
|
||||
"vitest": "3.0.5",
|
||||
"vue-tsc": "^2.2.2"
|
||||
"vite-plugin-svg-icons-ng": "^1.4.0",
|
||||
"vite-plugin-vue-devtools": "7.7.5",
|
||||
"vitest": "3.1.2",
|
||||
"vue-tsc": "^2.2.8"
|
||||
},
|
||||
"overrides": {
|
||||
"quill": "2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.18.0",
|
||||
|
@ -24,6 +24,21 @@ export interface ContractInfoVO {
|
||||
*/
|
||||
remark: string;
|
||||
|
||||
/**
|
||||
* 重要性
|
||||
*/
|
||||
manageContractLevel?: string;
|
||||
|
||||
/**
|
||||
* 合同负责人
|
||||
*/
|
||||
contractManagerId?: string;
|
||||
|
||||
/**
|
||||
* 合同负责人
|
||||
*/
|
||||
contractManager?: string;
|
||||
|
||||
}
|
||||
|
||||
export interface ContractInfoForm extends BaseEntity {
|
||||
@ -52,6 +67,21 @@ export interface ContractInfoForm extends BaseEntity {
|
||||
*/
|
||||
remark?: string;
|
||||
|
||||
/**
|
||||
* 重要性
|
||||
*/
|
||||
manageContractLevel?: string;
|
||||
|
||||
/**
|
||||
* 合同负责人id
|
||||
*/
|
||||
contractManagerId?: string;
|
||||
|
||||
/**
|
||||
* 合同负责人
|
||||
*/
|
||||
contractManager?: string;
|
||||
|
||||
}
|
||||
|
||||
export interface ContractInfoQuery extends PageQuery {
|
||||
|
@ -10,7 +10,7 @@ import { CustomerInfoVO, CustomerInfoForm, CustomerInfoQuery } from '@/api/syste
|
||||
|
||||
export const listCustomerInfo = (query?: CustomerInfoQuery): AxiosPromise<CustomerInfoVO[]> => {
|
||||
return request({
|
||||
url: '/system/customerInfo/list',
|
||||
url: '/manage/customerInfo/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
@ -22,7 +22,7 @@ export const listCustomerInfo = (query?: CustomerInfoQuery): AxiosPromise<Custom
|
||||
*/
|
||||
export const getCustomerInfo = (id: string | number): AxiosPromise<CustomerInfoVO> => {
|
||||
return request({
|
||||
url: '/system/customerInfo/' + id,
|
||||
url: '/manage/customerInfo/' + id,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
@ -33,7 +33,7 @@ export const getCustomerInfo = (id: string | number): AxiosPromise<CustomerInfoV
|
||||
*/
|
||||
export const addCustomerInfo = (data: CustomerInfoForm) => {
|
||||
return request({
|
||||
url: '/system/customerInfo',
|
||||
url: '/manage/customerInfo',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
@ -45,7 +45,7 @@ export const addCustomerInfo = (data: CustomerInfoForm) => {
|
||||
*/
|
||||
export const updateCustomerInfo = (data: CustomerInfoForm) => {
|
||||
return request({
|
||||
url: '/system/customerInfo',
|
||||
url: '/manage/customerInfo',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
@ -57,7 +57,7 @@ export const updateCustomerInfo = (data: CustomerInfoForm) => {
|
||||
*/
|
||||
export const delCustomerInfo = (id: string | number | Array<string | number>) => {
|
||||
return request({
|
||||
url: '/system/customerInfo/' + id,
|
||||
url: '/manage/customerInfo/' + id,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
|
240
src/api/operate/employee/index.ts
Normal file
240
src/api/operate/employee/index.ts
Normal file
@ -0,0 +1,240 @@
|
||||
import { DeptTreeVO, DeptVO } from './../dept/types';
|
||||
import { RoleVO } from '@/api/system/role/types';
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { UserForm, UserQuery, UserVO, UserInfoVO } from './types';
|
||||
import { parseStrEmpty } from '@/utils/ruoyi';
|
||||
|
||||
/**
|
||||
* 查询用户列表
|
||||
* @param query
|
||||
*/
|
||||
export const listUser = (query: UserQuery): AxiosPromise<UserVO[]> => {
|
||||
return request({
|
||||
url: '/operate/user/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 通过用户ids查询用户
|
||||
* @param userIds
|
||||
*/
|
||||
export const optionSelect = (userIds: (number | string)[]): AxiosPromise<UserVO[]> => {
|
||||
return request({
|
||||
url: '/operate/user/optionselect?userIds=' + userIds,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取用户详情
|
||||
* @param userId
|
||||
*/
|
||||
export const getUser = (userId?: string | number): AxiosPromise<UserInfoVO> => {
|
||||
return request({
|
||||
url: '/operate/user/' + parseStrEmpty(userId),
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增用户
|
||||
*/
|
||||
export const addUser = (data: UserForm) => {
|
||||
return request({
|
||||
url: '/operate/user',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改用户
|
||||
*/
|
||||
export const updateUser = (data: UserForm) => {
|
||||
return request({
|
||||
url: '/operate/user',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除用户
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
export const delUser = (userId: Array<string | number> | string | number) => {
|
||||
return request({
|
||||
url: '/operate/user/' + userId,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 用户密码重置
|
||||
* @param userId 用户ID
|
||||
* @param password 密码
|
||||
*/
|
||||
export const resetUserPwd = (userId: string | number, password: string) => {
|
||||
const data = {
|
||||
userId,
|
||||
password
|
||||
};
|
||||
return request({
|
||||
url: '/operate/user/resetPwd',
|
||||
method: 'put',
|
||||
headers: {
|
||||
isEncrypt: true,
|
||||
repeatSubmit: false
|
||||
},
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 用户状态修改
|
||||
* @param userId 用户ID
|
||||
* @param status 用户状态
|
||||
*/
|
||||
export const changeUserStatus = (userId: number | string, status: string) => {
|
||||
const data = {
|
||||
userId,
|
||||
status
|
||||
};
|
||||
return request({
|
||||
url: '/operate/user/changeStatus',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询用户个人信息
|
||||
*/
|
||||
export const getUserProfile = (): AxiosPromise<UserInfoVO> => {
|
||||
return request({
|
||||
url: '/operate/user/profile',
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改用户个人信息
|
||||
* @param data 用户信息
|
||||
*/
|
||||
export const updateUserProfile = (data: UserForm) => {
|
||||
return request({
|
||||
url: '/operate/user/profile',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 用户密码重置
|
||||
* @param oldPassword 旧密码
|
||||
* @param newPassword 新密码
|
||||
*/
|
||||
export const updateUserPwd = (oldPassword: string, newPassword: string) => {
|
||||
const data = {
|
||||
oldPassword,
|
||||
newPassword
|
||||
};
|
||||
return request({
|
||||
url: '/operate/user/profile/updatePwd',
|
||||
method: 'put',
|
||||
headers: {
|
||||
isEncrypt: true,
|
||||
repeatSubmit: false
|
||||
},
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 用户头像上传
|
||||
* @param data 头像文件
|
||||
*/
|
||||
export const uploadAvatar = (data: FormData) => {
|
||||
return request({
|
||||
url: '/operate/user/profile/avatar',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询授权角色
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
export const getAuthRole = (userId: string | number): AxiosPromise<{ user: UserVO; roles: RoleVO[] }> => {
|
||||
return request({
|
||||
url: '/operate/user/authRole/' + userId,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 保存授权角色
|
||||
* @param data 用户ID
|
||||
*/
|
||||
export const updateAuthRole = (data: { userId: string; roleIds: string }) => {
|
||||
return request({
|
||||
url: '/operate/user/authRole',
|
||||
method: 'put',
|
||||
params: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询当前部门的所有用户信息
|
||||
* @param deptId
|
||||
*/
|
||||
export const listUserByDeptId = (deptId: string | number): AxiosPromise<UserVO[]> => {
|
||||
return request({
|
||||
url: '/operate/user/list/dept/' + deptId,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询部门下拉树结构
|
||||
*/
|
||||
export const deptTreeSelect = (): AxiosPromise<DeptTreeVO[]> => {
|
||||
return request({
|
||||
url: '/operate/user/deptTree',
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 设置部门主管
|
||||
*/
|
||||
export const setDeptAdmin = (userId: Array<string | number> | string | number) => {
|
||||
return request({
|
||||
url: '/operate/user/setDeptAdmin/' + userId,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
export default {
|
||||
listUser,
|
||||
getUser,
|
||||
optionSelect,
|
||||
addUser,
|
||||
updateUser,
|
||||
delUser,
|
||||
resetUserPwd,
|
||||
changeUserStatus,
|
||||
getUserProfile,
|
||||
updateUserProfile,
|
||||
updateUserPwd,
|
||||
uploadAvatar,
|
||||
getAuthRole,
|
||||
updateAuthRole,
|
||||
deptTreeSelect,
|
||||
listUserByDeptId,
|
||||
setDeptAdmin
|
||||
};
|
90
src/api/operate/employee/types.ts
Normal file
90
src/api/operate/employee/types.ts
Normal file
@ -0,0 +1,90 @@
|
||||
import { RoleVO } from '@/api/system/role/types';
|
||||
import { PostVO } from '@/api/system/post/types';
|
||||
|
||||
/**
|
||||
* 用户信息
|
||||
*/
|
||||
export interface UserInfo {
|
||||
user: UserVO;
|
||||
roles: string[];
|
||||
permissions: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户查询对象类型
|
||||
*/
|
||||
export interface UserQuery extends PageQuery {
|
||||
userName?: string;
|
||||
nickName?: string;
|
||||
phonenumber?: string;
|
||||
status?: string;
|
||||
deptId?: string | number;
|
||||
roleId?: string | number;
|
||||
userIds?: string;
|
||||
employeeName?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户返回对象
|
||||
*/
|
||||
export interface UserVO extends BaseEntity {
|
||||
userId: string | number;
|
||||
tenantId: string;
|
||||
deptId: number;
|
||||
userName: string;
|
||||
nickName: string;
|
||||
userType: string;
|
||||
email: string;
|
||||
phonenumber: string;
|
||||
sex: string;
|
||||
avatar: string;
|
||||
status: string;
|
||||
delFlag: string;
|
||||
loginIp: string;
|
||||
loginDate: string;
|
||||
remark: string;
|
||||
deptName: string;
|
||||
roles: RoleVO[];
|
||||
roleIds: any;
|
||||
postIds: any;
|
||||
roleId: any;
|
||||
admin: boolean;
|
||||
employeeName: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户表单类型
|
||||
*/
|
||||
export interface UserForm {
|
||||
id?: string;
|
||||
userId?: string;
|
||||
deptId?: number;
|
||||
userName: string;
|
||||
employeeName?: string;
|
||||
nickName?: string;
|
||||
password: string;
|
||||
phonenumber?: string;
|
||||
email?: string;
|
||||
sex?: string;
|
||||
status: string;
|
||||
remark?: string;
|
||||
postIds: string[];
|
||||
roleIds: string[];
|
||||
|
||||
}
|
||||
|
||||
export interface UserInfoVO {
|
||||
user: UserVO;
|
||||
roles: RoleVO[];
|
||||
roleIds: string[];
|
||||
posts: PostVO[];
|
||||
postIds: string[];
|
||||
roleGroup: string;
|
||||
postGroup: string;
|
||||
}
|
||||
|
||||
export interface ResetPwdForm {
|
||||
oldPassword: string;
|
||||
newPassword: string;
|
||||
confirmPassword: string;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import {DeptForm, DeptQuery, DeptTreeVO, DeptVO} from './types';
|
||||
import { DeptForm, DeptQuery, DeptTreeVO, DeptVO } from './types';
|
||||
|
||||
// 查询部门列表
|
||||
export const listDept = (query?: DeptQuery) => {
|
||||
|
@ -68,3 +68,11 @@ export const delMenu = (menuId: string | number) => {
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
|
||||
// 级联删除菜单
|
||||
export const cascadeDelMenu = (menuIds: Array<string | number>) => {
|
||||
return request({
|
||||
url: '/system/menu/cascade/' + menuIds,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {DeptTreeVO, DeptVO} from './../dept/types';
|
||||
import { DeptTreeVO, DeptVO } from './../dept/types';
|
||||
import { RoleVO } from '@/api/system/role/types';
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { RoleVO } from '@/api/system/role/types';
|
||||
import { PostVO } from '@/api/system/post/types';
|
||||
import { string } from 'vue-types';
|
||||
|
||||
/**
|
||||
* 用户信息
|
||||
@ -16,6 +15,7 @@ export interface UserInfo {
|
||||
*/
|
||||
export interface UserQuery extends PageQuery {
|
||||
userName?: string;
|
||||
nickName?: string;
|
||||
phonenumber?: string;
|
||||
status?: string;
|
||||
deptId?: string | number;
|
||||
@ -61,6 +61,7 @@ export interface UserForm {
|
||||
deptId?: number;
|
||||
userName: string;
|
||||
employeeName?: string;
|
||||
nickName?: string;
|
||||
password: string;
|
||||
phonenumber?: string;
|
||||
email?: string;
|
||||
|
63
src/api/workflow/express/index.ts
Normal file
63
src/api/workflow/express/index.ts
Normal file
@ -0,0 +1,63 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { ExpressVO, ExpressQuery, ExpressForm } from '@/api/workflow/express/types';
|
||||
|
||||
/**
|
||||
* 查询快递列表
|
||||
* @param query
|
||||
* @returns {*}
|
||||
*/
|
||||
|
||||
export const listExpress = (query?: ExpressQuery): AxiosPromise<ExpressVO[]> => {
|
||||
return request({
|
||||
url: '/workflow/express/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询快递详细
|
||||
* @param id
|
||||
*/
|
||||
export const getExpress = (id: string | number): AxiosPromise<ExpressVO> => {
|
||||
return request({
|
||||
url: '/workflow/express/' + id,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增快递
|
||||
* @param data
|
||||
*/
|
||||
export const addExpress = (data: ExpressForm): AxiosPromise<ExpressVO> => {
|
||||
return request({
|
||||
url: '/workflow/express',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改快递
|
||||
* @param data
|
||||
*/
|
||||
export const updateExpress = (data: ExpressForm): AxiosPromise<ExpressVO> => {
|
||||
return request({
|
||||
url: '/workflow/express',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除快递
|
||||
* @param id
|
||||
*/
|
||||
export const delExpress = (id: string | number | Array<string | number>) => {
|
||||
return request({
|
||||
url: '/workflow/express/' + id,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
30
src/api/workflow/express/types.ts
Normal file
30
src/api/workflow/express/types.ts
Normal file
@ -0,0 +1,30 @@
|
||||
export interface ExpressVO {
|
||||
id: string | number;
|
||||
tripType: string;
|
||||
startDate: string;
|
||||
endDate: string;
|
||||
tripDays: number;
|
||||
budgetType?: string;
|
||||
remark: string;
|
||||
status?: string;
|
||||
}
|
||||
|
||||
export interface ExpressForm extends BaseEntity {
|
||||
id?: string | number;
|
||||
tripType?: string;
|
||||
startDate?: string;
|
||||
endDate?: string;
|
||||
tripDays?: number;
|
||||
tripMoney?: number;
|
||||
reason?: string;
|
||||
budgetType?: string;
|
||||
currentProjects?: string;
|
||||
remark?: string;
|
||||
attachment?: string;
|
||||
status?: string;
|
||||
}
|
||||
|
||||
export interface ExpressQuery extends PageQuery {
|
||||
startExpressDays?: number;
|
||||
endExpressDays?: number;
|
||||
}
|
@ -31,9 +31,9 @@ export const pageByFinish = (query: FlowInstanceQuery): AxiosPromise<FlowInstanc
|
||||
/**
|
||||
* 通过业务id获取历史流程图
|
||||
*/
|
||||
export const flowImage = (businessId: string | number) => {
|
||||
export const flowHisTaskList = (businessId: string | number) => {
|
||||
return request({
|
||||
url: `/workflow/instance/flowImage/${businessId}` + '?t' + Math.random(),
|
||||
url: `/workflow/instance/flowHisTaskList/${businessId}` + '?t' + Math.random(),
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
@ -26,7 +26,7 @@
|
||||
z-index: 1001;
|
||||
overflow: hidden;
|
||||
-webkit-box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35);
|
||||
box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35);
|
||||
box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.1);
|
||||
|
||||
// reset element-ui css
|
||||
.horizontal-collapse-transition {
|
||||
|
@ -44,7 +44,7 @@ const findPathNum = (str, char = '/') => {
|
||||
return str.split(char).length - 1;
|
||||
};
|
||||
const getMatched = (pathList, routeList, matched) => {
|
||||
let data = routeList.find((item) => item.path == pathList[0] || (item.name += '').toLowerCase() == pathList[0]);
|
||||
const data = routeList.find((item) => item.path == pathList[0] || (item.name += '').toLowerCase() == pathList[0]);
|
||||
if (data) {
|
||||
matched.push(data);
|
||||
if (data.children && pathList.length) {
|
||||
|
@ -95,7 +95,7 @@ const options = ref<any>({
|
||||
});
|
||||
|
||||
const styles = computed(() => {
|
||||
let style: any = {};
|
||||
const style: any = {};
|
||||
if (props.minHeight) {
|
||||
style.minHeight = `${props.minHeight}px`;
|
||||
}
|
||||
@ -121,9 +121,9 @@ const handleUploadSuccess = (res: any) => {
|
||||
// 如果上传成功
|
||||
if (res.code === 200) {
|
||||
// 获取富文本实例
|
||||
let quill = toRaw(quillEditorRef.value).getQuill();
|
||||
const quill = toRaw(quillEditorRef.value).getQuill();
|
||||
// 获取光标位置
|
||||
let length = quill.selection.savedRange.index;
|
||||
const length = quill.selection.savedRange.index;
|
||||
// 插入图片,res为服务器返回的图片链接地址
|
||||
quill.insertEmbed(length, 'image', res.data.url);
|
||||
// 调整光标到最后
|
||||
|
@ -176,7 +176,7 @@ const handleUploadSuccess = (res: any, file: UploadFile) => {
|
||||
|
||||
// 删除文件
|
||||
const handleDelete = (index: number) => {
|
||||
let ossId = fileList.value[index].ossId;
|
||||
const ossId = fileList.value[index].ossId;
|
||||
delOss(ossId);
|
||||
fileList.value.splice(index, 1);
|
||||
emit('update:modelValue', listToString(fileList.value));
|
||||
|
@ -27,7 +27,7 @@ const realSrc = computed(() => {
|
||||
if (!props.src) {
|
||||
return;
|
||||
}
|
||||
let real_src = props.src.split(',')[0];
|
||||
const real_src = props.src.split(',')[0];
|
||||
return real_src;
|
||||
});
|
||||
|
||||
@ -35,8 +35,8 @@ const realSrcList = computed(() => {
|
||||
if (!props.src) {
|
||||
return [];
|
||||
}
|
||||
let real_src_list = props.src.split(',');
|
||||
let srcList: string[] = [];
|
||||
const real_src_list = props.src.split(',');
|
||||
const srcList: string[] = [];
|
||||
real_src_list.forEach((item: string) => {
|
||||
if (item.trim() === '') {
|
||||
return;
|
||||
|
@ -189,7 +189,7 @@ const handleUploadSuccess = (res: any, file: UploadFile) => {
|
||||
const handleDelete = (file: UploadFile): boolean => {
|
||||
const findex = fileList.value.map((f) => f.name).indexOf(file.name);
|
||||
if (findex > -1 && uploadList.value.length === number.value) {
|
||||
let ossId = fileList.value[findex].ossId;
|
||||
const ossId = fileList.value[findex].ossId;
|
||||
delOss(ossId);
|
||||
fileList.value.splice(findex, 1);
|
||||
emit('update:modelValue', listToString(fileList.value));
|
||||
@ -225,7 +225,7 @@ const handlePictureCardPreview = (file: any) => {
|
||||
const listToString = (list: any[], separator?: string) => {
|
||||
let strs = '';
|
||||
separator = separator || ',';
|
||||
for (let i in list) {
|
||||
for (const i in list) {
|
||||
if (undefined !== list[i].ossId && list[i].url.indexOf('blob:') !== 0) {
|
||||
strs += list[i].ossId + separator;
|
||||
}
|
||||
|
56
src/components/Process/approvalButton.vue
Normal file
56
src/components/Process/approvalButton.vue
Normal file
@ -0,0 +1,56 @@
|
||||
<template>
|
||||
<div style="display: flex; justify-content: space-between">
|
||||
<div>
|
||||
<el-button v-if="submitButtonShow" :loading="props.buttonLoading" type="info" @click="submitForm('draft')">暂存</el-button>
|
||||
<el-button v-if="submitButtonShow" :loading="props.buttonLoading" type="primary" @click="submitForm('submit')">提 交</el-button>
|
||||
<el-button v-if="approvalButtonShow" :loading="props.buttonLoading" type="primary" @click="approvalVerifyOpen">审批</el-button>
|
||||
<el-button v-if="props.id && props.status !== 'draft'" type="primary" @click="handleApprovalRecord">流程进度</el-button>
|
||||
<slot />
|
||||
</div>
|
||||
<div>
|
||||
<el-button style="float: right" @click="goBack()">返回</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { propTypes } from '@/utils/propTypes';
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const props = defineProps({
|
||||
status: propTypes.string.def(''),
|
||||
pageType: propTypes.string.def(''),
|
||||
buttonLoading: propTypes.bool.def(false),
|
||||
id: propTypes.string.def('') || propTypes.number.def()
|
||||
});
|
||||
const emits = defineEmits(['submitForm', 'approvalVerifyOpen', 'handleApprovalRecord']);
|
||||
//暂存,提交
|
||||
const submitForm = async (type) => {
|
||||
emits('submitForm', type);
|
||||
};
|
||||
//审批
|
||||
const approvalVerifyOpen = async () => {
|
||||
emits('approvalVerifyOpen');
|
||||
};
|
||||
//审批记录
|
||||
const handleApprovalRecord = () => {
|
||||
emits('handleApprovalRecord');
|
||||
};
|
||||
|
||||
//校验提交按钮是否显示
|
||||
const submitButtonShow = computed(() => {
|
||||
return (
|
||||
props.pageType === 'add' ||
|
||||
(props.pageType === 'update' && props.status && (props.status === 'draft' || props.status === 'cancel' || props.status === 'back'))
|
||||
);
|
||||
});
|
||||
|
||||
//校验审批按钮是否显示
|
||||
const approvalButtonShow = computed(() => {
|
||||
return props.pageType === 'approval' && props.status && props.status === 'waiting';
|
||||
});
|
||||
|
||||
//返回
|
||||
const goBack = () => {
|
||||
proxy.$tab.closePage(proxy.$route);
|
||||
proxy.$router.go(-1);
|
||||
};
|
||||
</script>
|
@ -3,21 +3,7 @@
|
||||
<el-dialog v-model="visible" draggable title="审批记录" :width="props.width" :height="props.height" :close-on-click-modal="false">
|
||||
<el-tabs v-model="tabActiveName" class="demo-tabs">
|
||||
<el-tab-pane v-loading="loading" label="流程图" name="image" style="height: 68vh">
|
||||
<div
|
||||
ref="imageWrapperRef"
|
||||
class="image-wrapper"
|
||||
@wheel="handleMouseWheel"
|
||||
@mousedown="handleMouseDown"
|
||||
@mousemove="handleMouseMove"
|
||||
@mouseup="handleMouseUp"
|
||||
@mouseleave="handleMouseLeave"
|
||||
@dblclick="resetTransform"
|
||||
:style="transformStyle"
|
||||
>
|
||||
<el-card class="box-card">
|
||||
<el-image :src="imgUrl" class="scalable-image" />
|
||||
</el-card>
|
||||
</div>
|
||||
<flowChart :ins-id="insId" v-if="insId" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-loading="loading" label="审批信息" name="info">
|
||||
<div>
|
||||
@ -73,10 +59,10 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { flowImage } from '@/api/workflow/instance';
|
||||
import { flowHisTaskList } from '@/api/workflow/instance';
|
||||
import { propTypes } from '@/utils/propTypes';
|
||||
import { listByIds } from '@/api/system/oss';
|
||||
|
||||
import FlowChart from '@/components/Process/flowChart.vue';
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { wf_task_status } = toRefs<any>(proxy?.useDict('wf_task_status'));
|
||||
const props = defineProps({
|
||||
@ -87,7 +73,7 @@ const loading = ref(false);
|
||||
const visible = ref(false);
|
||||
const historyList = ref<Array<any>>([]);
|
||||
const tabActiveName = ref('image');
|
||||
const imgUrl = ref('');
|
||||
const insId = ref(null);
|
||||
|
||||
//初始化查询审批记录
|
||||
const init = async (businessId: string | number) => {
|
||||
@ -95,10 +81,10 @@ const init = async (businessId: string | number) => {
|
||||
loading.value = true;
|
||||
tabActiveName.value = 'image';
|
||||
historyList.value = [];
|
||||
flowImage(businessId).then((resp) => {
|
||||
flowHisTaskList(businessId).then((resp) => {
|
||||
if (resp.data) {
|
||||
historyList.value = resp.data.list;
|
||||
imgUrl.value = 'data:image/gif;base64,' + resp.data.image;
|
||||
insId.value = resp.data.instanceId;
|
||||
if (historyList.value.length > 0) {
|
||||
historyList.value.forEach((item) => {
|
||||
if (item.ext) {
|
||||
@ -124,109 +110,6 @@ const handleDownload = (ossId: string) => {
|
||||
proxy?.$download.oss(ossId);
|
||||
};
|
||||
|
||||
const imageWrapperRef = ref<HTMLElement | null>(null);
|
||||
const scale = ref(1); // 初始缩放比例
|
||||
const maxScale = 3; // 最大缩放比例
|
||||
const minScale = 0.5; // 最小缩放比例
|
||||
|
||||
let isDragging = false;
|
||||
let startX = 0;
|
||||
let startY = 0;
|
||||
let currentTranslateX = 0;
|
||||
let currentTranslateY = 0;
|
||||
|
||||
const handleMouseWheel = (event: WheelEvent) => {
|
||||
event.preventDefault();
|
||||
let newScale = scale.value - event.deltaY / 1000;
|
||||
newScale = Math.max(minScale, Math.min(newScale, maxScale));
|
||||
if (newScale !== scale.value) {
|
||||
scale.value = newScale;
|
||||
resetDragPosition(); // 重置拖拽位置,使图片居中
|
||||
}
|
||||
};
|
||||
|
||||
const handleMouseDown = (event: MouseEvent) => {
|
||||
if (scale.value > 1) {
|
||||
event.preventDefault(); // 阻止默认行为,防止拖拽
|
||||
isDragging = true;
|
||||
startX = event.clientX;
|
||||
startY = event.clientY;
|
||||
}
|
||||
};
|
||||
|
||||
const handleMouseMove = (event: MouseEvent) => {
|
||||
if (!isDragging || !imageWrapperRef.value) return;
|
||||
|
||||
const deltaX = event.clientX - startX;
|
||||
const deltaY = event.clientY - startY;
|
||||
startX = event.clientX;
|
||||
startY = event.clientY;
|
||||
|
||||
currentTranslateX += deltaX;
|
||||
currentTranslateY += deltaY;
|
||||
|
||||
// 边界检测,防止图片被拖出容器
|
||||
const bounds = getBounds();
|
||||
if (currentTranslateX > bounds.maxTranslateX) {
|
||||
currentTranslateX = bounds.maxTranslateX;
|
||||
} else if (currentTranslateX < bounds.minTranslateX) {
|
||||
currentTranslateX = bounds.minTranslateX;
|
||||
}
|
||||
|
||||
if (currentTranslateY > bounds.maxTranslateY) {
|
||||
currentTranslateY = bounds.maxTranslateY;
|
||||
} else if (currentTranslateY < bounds.minTranslateY) {
|
||||
currentTranslateY = bounds.minTranslateY;
|
||||
}
|
||||
|
||||
applyTransform();
|
||||
};
|
||||
|
||||
const handleMouseUp = () => {
|
||||
isDragging = false;
|
||||
};
|
||||
|
||||
const handleMouseLeave = () => {
|
||||
isDragging = false;
|
||||
};
|
||||
|
||||
const resetTransform = () => {
|
||||
scale.value = 1;
|
||||
currentTranslateX = 0;
|
||||
currentTranslateY = 0;
|
||||
applyTransform();
|
||||
};
|
||||
|
||||
const resetDragPosition = () => {
|
||||
currentTranslateX = 0;
|
||||
currentTranslateY = 0;
|
||||
applyTransform();
|
||||
};
|
||||
|
||||
const applyTransform = () => {
|
||||
if (imageWrapperRef.value) {
|
||||
imageWrapperRef.value.style.transform = `translate(${currentTranslateX}px, ${currentTranslateY}px) scale(${scale.value})`;
|
||||
}
|
||||
};
|
||||
|
||||
const getBounds = () => {
|
||||
if (!imageWrapperRef.value) return { minTranslateX: 0, maxTranslateX: 0, minTranslateY: 0, maxTranslateY: 0 };
|
||||
|
||||
const imgRect = imageWrapperRef.value.getBoundingClientRect();
|
||||
const containerRect = imageWrapperRef.value.parentElement?.getBoundingClientRect() ?? imgRect;
|
||||
|
||||
const minTranslateX = (containerRect.width - imgRect.width * scale.value) / 2;
|
||||
const maxTranslateX = -(containerRect.width - imgRect.width * scale.value) / 2;
|
||||
const minTranslateY = (containerRect.height - imgRect.height * scale.value) / 2;
|
||||
const maxTranslateY = -(containerRect.height - imgRect.height * scale.value) / 2;
|
||||
|
||||
return { minTranslateX, maxTranslateX, minTranslateY, maxTranslateY };
|
||||
};
|
||||
|
||||
const transformStyle = computed(() => ({
|
||||
transition: isDragging ? 'none' : 'transform 0.2s ease'
|
||||
}));
|
||||
|
||||
/**
|
||||
* 对外暴露子组件方法
|
||||
*/
|
||||
@ -235,46 +118,10 @@ defineExpose({
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.triangle {
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.triangle::after {
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
top: 8em;
|
||||
right: 215px;
|
||||
border: 15px solid;
|
||||
border-color: transparent #fff transparent transparent;
|
||||
}
|
||||
|
||||
.container {
|
||||
:deep(.el-dialog .el-dialog__body) {
|
||||
max-height: calc(100vh - 170px) !important;
|
||||
min-height: calc(100vh - 170px) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.image-wrapper {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
user-select: none; /* 禁用文本选择 */
|
||||
cursor: grab; /* 设置初始鼠标指针为可拖动 */
|
||||
}
|
||||
|
||||
.image-wrapper:active {
|
||||
cursor: grabbing; /* 当正在拖动时改变鼠标指针 */
|
||||
}
|
||||
|
||||
.scalable-image {
|
||||
object-fit: contain;
|
||||
width: 100%;
|
||||
padding: 15px;
|
||||
}
|
||||
</style>
|
||||
|
40
src/components/Process/flowChart.vue
Normal file
40
src/components/Process/flowChart.vue
Normal file
@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<div>
|
||||
<div style="height: 68vh" class="iframe-wrapper">
|
||||
<iframe :src="iframeUrl" style="width: 100%; height: 100%" frameborder="0" scrolling="no" class="custom-iframe" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { getToken } from '@/utils/auth';
|
||||
|
||||
// Props 定义方式变化
|
||||
const props = defineProps({
|
||||
insId: {
|
||||
type: [String, Number],
|
||||
default: null
|
||||
}
|
||||
});
|
||||
|
||||
const iframeUrl = ref('');
|
||||
const baseUrl = import.meta.env.VITE_APP_BASE_API;
|
||||
|
||||
onMounted(async () => {
|
||||
const url = baseUrl + `/warm-flow-ui/index.html?id=${props.insId}&type=FlowChart`;
|
||||
iframeUrl.value = url + '&Authorization=Bearer ' + getToken() + '&clientid=' + import.meta.env.VITE_APP_CLIENT_ID;
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
.iframe-wrapper {
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.custom-iframe {
|
||||
width: 100%;
|
||||
border: none;
|
||||
background: transparent;
|
||||
}
|
||||
</style>
|
154
src/components/Process/flowChartImg.vue
Normal file
154
src/components/Process/flowChartImg.vue
Normal file
@ -0,0 +1,154 @@
|
||||
<template>
|
||||
<div
|
||||
ref="imageWrapperRef"
|
||||
class="image-wrapper"
|
||||
@wheel="handleMouseWheel"
|
||||
@mousedown="handleMouseDown"
|
||||
@mousemove="handleMouseMove"
|
||||
@mouseup="handleMouseUp"
|
||||
@mouseleave="handleMouseLeave"
|
||||
@dblclick="resetTransform"
|
||||
:style="transformStyle"
|
||||
>
|
||||
<el-card class="box-card">
|
||||
<el-image :src="props.imgUrl" class="scalable-image" />
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// Props 定义方式变化
|
||||
const props = defineProps({
|
||||
imgUrl: {
|
||||
type: String,
|
||||
default: () => ''
|
||||
}
|
||||
});
|
||||
|
||||
const imageWrapperRef = ref<HTMLElement | null>(null);
|
||||
const scale = ref(1); // 初始缩放比例
|
||||
const maxScale = 3; // 最大缩放比例
|
||||
const minScale = 0.5; // 最小缩放比例
|
||||
|
||||
let isDragging = false;
|
||||
let startX = 0;
|
||||
let startY = 0;
|
||||
let currentTranslateX = 0;
|
||||
let currentTranslateY = 0;
|
||||
|
||||
const handleMouseWheel = (event: WheelEvent) => {
|
||||
event.preventDefault();
|
||||
let newScale = scale.value - event.deltaY / 1000;
|
||||
newScale = Math.max(minScale, Math.min(newScale, maxScale));
|
||||
if (newScale !== scale.value) {
|
||||
scale.value = newScale;
|
||||
resetDragPosition(); // 重置拖拽位置,使图片居中
|
||||
}
|
||||
};
|
||||
|
||||
const handleMouseDown = (event: MouseEvent) => {
|
||||
if (scale.value > 1) {
|
||||
event.preventDefault(); // 阻止默认行为,防止拖拽
|
||||
isDragging = true;
|
||||
startX = event.clientX;
|
||||
startY = event.clientY;
|
||||
}
|
||||
};
|
||||
|
||||
const handleMouseMove = (event: MouseEvent) => {
|
||||
if (!isDragging || !imageWrapperRef.value) return;
|
||||
|
||||
const deltaX = event.clientX - startX;
|
||||
const deltaY = event.clientY - startY;
|
||||
startX = event.clientX;
|
||||
startY = event.clientY;
|
||||
|
||||
currentTranslateX += deltaX;
|
||||
currentTranslateY += deltaY;
|
||||
|
||||
// 边界检测,防止图片被拖出容器
|
||||
const bounds = getBounds();
|
||||
if (currentTranslateX > bounds.maxTranslateX) {
|
||||
currentTranslateX = bounds.maxTranslateX;
|
||||
} else if (currentTranslateX < bounds.minTranslateX) {
|
||||
currentTranslateX = bounds.minTranslateX;
|
||||
}
|
||||
|
||||
if (currentTranslateY > bounds.maxTranslateY) {
|
||||
currentTranslateY = bounds.maxTranslateY;
|
||||
} else if (currentTranslateY < bounds.minTranslateY) {
|
||||
currentTranslateY = bounds.minTranslateY;
|
||||
}
|
||||
|
||||
applyTransform();
|
||||
};
|
||||
|
||||
const handleMouseUp = () => {
|
||||
isDragging = false;
|
||||
};
|
||||
|
||||
const handleMouseLeave = () => {
|
||||
isDragging = false;
|
||||
};
|
||||
|
||||
const resetTransform = () => {
|
||||
scale.value = 1;
|
||||
currentTranslateX = 0;
|
||||
currentTranslateY = 0;
|
||||
applyTransform();
|
||||
};
|
||||
|
||||
const resetDragPosition = () => {
|
||||
currentTranslateX = 0;
|
||||
currentTranslateY = 0;
|
||||
applyTransform();
|
||||
};
|
||||
|
||||
const applyTransform = () => {
|
||||
if (imageWrapperRef.value) {
|
||||
imageWrapperRef.value.style.transform = `translate(${currentTranslateX}px, ${currentTranslateY}px) scale(${scale.value})`;
|
||||
}
|
||||
};
|
||||
|
||||
const getBounds = () => {
|
||||
if (!imageWrapperRef.value) return { minTranslateX: 0, maxTranslateX: 0, minTranslateY: 0, maxTranslateY: 0 };
|
||||
|
||||
const imgRect = imageWrapperRef.value.getBoundingClientRect();
|
||||
const containerRect = imageWrapperRef.value.parentElement?.getBoundingClientRect() ?? imgRect;
|
||||
|
||||
const minTranslateX = (containerRect.width - imgRect.width * scale.value) / 2;
|
||||
const maxTranslateX = -(containerRect.width - imgRect.width * scale.value) / 2;
|
||||
const minTranslateY = (containerRect.height - imgRect.height * scale.value) / 2;
|
||||
const maxTranslateY = -(containerRect.height - imgRect.height * scale.value) / 2;
|
||||
|
||||
return { minTranslateX, maxTranslateX, minTranslateY, maxTranslateY };
|
||||
};
|
||||
|
||||
const transformStyle = computed(() => ({
|
||||
transition: isDragging ? 'none' : 'transform 0.2s ease'
|
||||
}));
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.image-wrapper {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
user-select: none; /* 禁用文本选择 */
|
||||
cursor: grab; /* 设置初始鼠标指针为可拖动 */
|
||||
}
|
||||
|
||||
.image-wrapper:active {
|
||||
cursor: grabbing; /* 当正在拖动时改变鼠标指针 */
|
||||
}
|
||||
|
||||
.scalable-image {
|
||||
object-fit: contain;
|
||||
width: 100%;
|
||||
padding: 15px;
|
||||
}
|
||||
</style>
|
@ -8,10 +8,10 @@
|
||||
<el-checkbox value="3" name="type">短信</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="task.flowStatus === 'waiting'" label="附件">
|
||||
<el-form-item label="附件">
|
||||
<fileUpload v-model="form.fileId" :file-type="['png', 'jpg', 'jpeg', 'doc', 'docx', 'xlsx', 'xls', 'ppt', 'txt', 'pdf']" :file-size="20" />
|
||||
</el-form-item>
|
||||
<el-form-item label="抄送" v-if="task.flowStatus === 'waiting' && buttonObj.copy">
|
||||
<el-form-item label="抄送" v-if="buttonObj.copy">
|
||||
<el-button type="primary" icon="Plus" circle @click="openUserSelectCopy" />
|
||||
<el-tag v-for="user in selectCopyUserList" :key="user.userId" closable style="margin: 2px" @close="handleCopyCloseTag(user)">
|
||||
{{ user.employeeName }}
|
||||
|
@ -47,11 +47,11 @@ const routers = computed(() => permissionStore.getTopbarRoutes());
|
||||
|
||||
// 顶部显示菜单
|
||||
const topMenus = computed(() => {
|
||||
let topMenus: RouteRecordRaw[] = [];
|
||||
const topMenus: RouteRecordRaw[] = [];
|
||||
routers.value.map((menu) => {
|
||||
if (menu.hidden !== true) {
|
||||
// 兼容顶部栏一级菜单内部跳转
|
||||
if (menu.path === '/') {
|
||||
if (menu.path === '/' && menu.children) {
|
||||
topMenus.push(menu.children ? menu.children[0] : menu);
|
||||
} else {
|
||||
topMenus.push(menu);
|
||||
@ -63,7 +63,7 @@ const topMenus = computed(() => {
|
||||
|
||||
// 设置子路由
|
||||
const childrenMenus = computed(() => {
|
||||
let childrenMenus: RouteRecordRaw[] = [];
|
||||
const childrenMenus: RouteRecordRaw[] = [];
|
||||
routers.value.map((router) => {
|
||||
router.children?.forEach((item) => {
|
||||
if (item.parentPath === undefined) {
|
||||
@ -118,7 +118,7 @@ const handleSelect = (key: string) => {
|
||||
// 没有子路由路径内部打开
|
||||
const routeMenu = childrenMenus.value.find((item) => item.path === key);
|
||||
if (routeMenu && routeMenu.query) {
|
||||
let query = JSON.parse(routeMenu.query);
|
||||
const query = JSON.parse(routeMenu.query);
|
||||
router.push({ path: key, query: query });
|
||||
} else {
|
||||
router.push({ path: key });
|
||||
@ -132,7 +132,7 @@ const handleSelect = (key: string) => {
|
||||
};
|
||||
|
||||
const activeRoutes = (key: string) => {
|
||||
let routes: RouteRecordRaw[] = [];
|
||||
const routes: RouteRecordRaw[] = [];
|
||||
if (childrenMenus.value && childrenMenus.value.length > 0) {
|
||||
childrenMenus.value.map((item) => {
|
||||
if (key == item.parentPath || (key == 'index' && '' == item.path)) {
|
||||
|
@ -40,16 +40,16 @@ watch(
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
addIframe()
|
||||
})
|
||||
addIframe();
|
||||
});
|
||||
|
||||
watchEffect((route) => {
|
||||
addIframe()
|
||||
})
|
||||
watchEffect(() => {
|
||||
addIframe();
|
||||
});
|
||||
|
||||
function addIframe() {
|
||||
if (route.meta.link) {
|
||||
useTagsViewStore().addIframeView(route)
|
||||
useTagsViewStore().addIframeView(route);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -18,7 +18,7 @@ const tagsViewStore = useTagsViewStore();
|
||||
|
||||
function iframeUrl(url: string | undefined, query: any) {
|
||||
if (Object.keys(query).length > 0) {
|
||||
let params = Object.keys(query)
|
||||
const params = Object.keys(query)
|
||||
.map((key) => key + '=' + query[key])
|
||||
.join('&');
|
||||
return url + '?' + params;
|
||||
|
@ -33,7 +33,7 @@
|
||||
<el-popover placement="bottom" trigger="click" transition="el-zoom-in-top" :width="300" :persistent="false">
|
||||
<template #reference>
|
||||
<el-badge :value="newNotice > 0 ? newNotice : ''" :max="99">
|
||||
<svg-icon icon-class="message" />
|
||||
<div class="right-menu-item hover-effect" style="display: block"><svg-icon icon-class="message" /></div>
|
||||
</el-badge>
|
||||
</template>
|
||||
<template #default>
|
||||
@ -98,7 +98,7 @@ import { dynamicClear, dynamicTenant } from '@/api/system/tenant';
|
||||
import { TenantVO } from '@/api/types';
|
||||
import notice from './notice/index.vue';
|
||||
import router from '@/router';
|
||||
import {ElMessageBoxOptions} from "element-plus/es/components/message-box/src/message-box.type";
|
||||
import { ElMessageBoxOptions } from 'element-plus/es/components/message-box/src/message-box.type';
|
||||
|
||||
const appStore = useAppStore();
|
||||
const userStore = useUserStore();
|
||||
@ -171,6 +171,7 @@ const logout = async () => {
|
||||
redirect: encodeURIComponent(router.currentRoute.value.fullPath || '/')
|
||||
}
|
||||
});
|
||||
proxy?.$tab.closeAllPage();
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -59,6 +59,13 @@
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="drawer-item">
|
||||
<span>显示页签图标</span>
|
||||
<span class="comp-style">
|
||||
<el-switch v-model="settingsStore.tagsIcon" :disabled="!settingsStore.tagsView" class="drawer-switch" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="drawer-item">
|
||||
<span>固定 Header</span>
|
||||
<span class="comp-style">
|
||||
@ -153,6 +160,7 @@ const saveSetting = () => {
|
||||
const settings = useStorage<LayoutSetting>('layout-setting', defaultSettings);
|
||||
settings.value.topNav = storeSettings.value.topNav;
|
||||
settings.value.tagsView = storeSettings.value.tagsView;
|
||||
settings.value.tagsIcon = storeSettings.value.tagsIcon;
|
||||
settings.value.fixedHeader = storeSettings.value.fixedHeader;
|
||||
settings.value.sidebarLogo = storeSettings.value.sidebarLogo;
|
||||
settings.value.dynamicTitle = storeSettings.value.dynamicTitle;
|
||||
|
@ -86,7 +86,7 @@ const resolvePath = (routePath: string, routeQuery?: string): any => {
|
||||
return props.basePath;
|
||||
}
|
||||
if (routeQuery) {
|
||||
let query = JSON.parse(routeQuery);
|
||||
const query = JSON.parse(routeQuery);
|
||||
return { path: getNormalPath(props.basePath + '/' + routePath), query: query };
|
||||
}
|
||||
return getNormalPath(props.basePath + '/' + routePath);
|
||||
|
@ -63,9 +63,9 @@ const loginByCode = async (data: LoginData) => {
|
||||
|
||||
const init = async () => {
|
||||
// 如果域名不相等 则重定向处理
|
||||
let host = window.location.host;
|
||||
const host = window.location.host;
|
||||
if (domain !== host) {
|
||||
let urlFull = new URL(window.location.href);
|
||||
const urlFull = new URL(window.location.href);
|
||||
urlFull.host = domain;
|
||||
window.location.href = urlFull.toString();
|
||||
return;
|
||||
|
@ -5,13 +5,14 @@
|
||||
v-for="tag in visitedViews"
|
||||
:key="tag.path"
|
||||
:data-path="tag.path"
|
||||
:class="isActive(tag) ? 'active' : ''"
|
||||
:class="{ 'active': isActive(tag), 'has-icon': tagsIcon }"
|
||||
:to="{ path: tag.path ? tag.path : '', query: tag.query, fullPath: tag.fullPath ? tag.fullPath : '' }"
|
||||
class="tags-view-item"
|
||||
:style="activeStyle(tag)"
|
||||
@click.middle="!isAffix(tag) ? closeSelectedTag(tag) : ''"
|
||||
@contextmenu.prevent="openMenu(tag, $event)"
|
||||
>
|
||||
<svg-icon v-if="tagsIcon && tag.meta && tag.meta.icon && tag.meta.icon !== '#'" :icon-class="tag.meta.icon"/>
|
||||
{{ tag.title }}
|
||||
<span v-if="!isAffix(tag)" @click.prevent.stop="closeSelectedTag(tag)">
|
||||
<close class="el-icon-close" style="width: 1em; height: 1em; vertical-align: middle" />
|
||||
@ -51,6 +52,7 @@ const router = useRouter();
|
||||
const visitedViews = computed(() => useTagsViewStore().getVisitedViews());
|
||||
const routes = computed(() => usePermissionStore().getRoutes());
|
||||
const theme = computed(() => useSettingsStore().theme);
|
||||
const tagsIcon = computed(() => useSettingsStore().tagsIcon)
|
||||
|
||||
watch(route, () => {
|
||||
addTags();
|
||||
@ -285,6 +287,9 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
}
|
||||
.tags-view-item.active.has-icon::before {
|
||||
content: none !important;
|
||||
}
|
||||
.contextmenu {
|
||||
margin: 0;
|
||||
background: var(--el-bg-color);
|
||||
|
@ -67,7 +67,7 @@ const closeSearch = () => {
|
||||
};
|
||||
// 菜单搜索数据过滤
|
||||
const menuSearch = (queryString: string, cb: (options: any[]) => void) => {
|
||||
let options = state.menuList.filter((item) => {
|
||||
const options = state.menuList.filter((item) => {
|
||||
return item.title.indexOf(queryString) > -1;
|
||||
});
|
||||
cb(options);
|
||||
|
@ -24,10 +24,9 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="layoutBreadcrumbUserNews">
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useNoticeStore } from '@/store/modules/notice';
|
||||
|
||||
const noticeStore = storeToRefs(useNoticeStore());
|
||||
const noticeStore = useNoticeStore();
|
||||
const { readAll } = useNoticeStore();
|
||||
|
||||
// 定义变量内容
|
||||
@ -42,7 +41,7 @@ const newsList = ref([]) as any;
|
||||
*/
|
||||
const getTableData = async () => {
|
||||
state.loading = true;
|
||||
newsList.value = noticeStore.state.value.notices;
|
||||
newsList.value = noticeStore.state.notices;
|
||||
state.loading = false;
|
||||
};
|
||||
|
||||
@ -50,7 +49,7 @@ const getTableData = async () => {
|
||||
const onNewsClick = (item: any) => {
|
||||
newsList.value[item].read = true;
|
||||
//并且写入pinia
|
||||
noticeStore.state.value.notices = newsList.value;
|
||||
noticeStore.state.notices = newsList.value;
|
||||
};
|
||||
|
||||
// 前往通知中心点击
|
||||
|
@ -34,7 +34,7 @@ import i18n from '@/lang/index';
|
||||
// vxeTable
|
||||
import VXETable from 'vxe-table';
|
||||
import 'vxe-table/lib/style.css';
|
||||
VXETable.config({
|
||||
VXETable.setConfig({
|
||||
zIndex: 999999
|
||||
});
|
||||
|
||||
|
@ -14,8 +14,8 @@ NProgress.configure({ showSpinner: false });
|
||||
const whiteList = ['/login', '/register', '/social-callback', '/register*', '/register/*'];
|
||||
|
||||
const isWhiteList = (path: string) => {
|
||||
return whiteList.some(pattern => isPathMatch(pattern, path))
|
||||
}
|
||||
return whiteList.some((pattern) => isPathMatch(pattern, path));
|
||||
};
|
||||
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
NProgress.start();
|
||||
|
@ -93,132 +93,7 @@ export const constantRoutes: RouteRecordRaw[] = [
|
||||
|
||||
// 动态路由,基于用户权限动态去加载
|
||||
export const dynamicRoutes: RouteRecordRaw[] = [
|
||||
{
|
||||
path: '/system/user-auth',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['system:user:edit'],
|
||||
children: [
|
||||
{
|
||||
path: 'role/:userId(\\d+)',
|
||||
component: () => import('@/views/system/user/authRole.vue'),
|
||||
name: 'AuthRole',
|
||||
meta: { title: '分配角色', activeMenu: '/system/user', icon: '', noCache: true }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/system/role-auth',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['system:role:edit'],
|
||||
children: [
|
||||
{
|
||||
path: 'user/:roleId(\\d+)',
|
||||
component: () => import('@/views/system/role/authUser.vue'),
|
||||
name: 'AuthUser',
|
||||
meta: { title: '分配用户', activeMenu: '/system/role', icon: '', noCache: true }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/system/dict-data',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['system:dict:list'],
|
||||
children: [
|
||||
{
|
||||
path: 'index/:dictId(\\d+)',
|
||||
component: () => import('@/views/system/dict/data.vue'),
|
||||
name: 'Data',
|
||||
meta: { title: '字典数据', activeMenu: '/system/dict', icon: '', noCache: true }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/system/oss-config',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['system:ossConfig:list'],
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
component: () => import('@/views/system/oss/config.vue'),
|
||||
name: 'OssConfig',
|
||||
meta: { title: '配置管理', activeMenu: '/system/oss', icon: '', noCache: true }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/tool/gen-edit',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['tool:gen:edit'],
|
||||
children: [
|
||||
{
|
||||
path: 'index/:tableId(\\d+)',
|
||||
component: () => import('@/views/tool/gen/editTable.vue'),
|
||||
name: 'GenEdit',
|
||||
meta: { title: '修改生成配置', activeMenu: '/tool/gen', icon: '', noCache: true }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/workflow/leaveEdit',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['workflow:leave:edit'],
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
component: () => import('@/views/workflow/leave/leaveEdit.vue'),
|
||||
name: 'leaveEdit',
|
||||
meta: { title: '请假申请', activeMenu: '/workflow/leave', noCache: true }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/workflow/tripEdit',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['workflow:businessTrip:edit'],
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
component: () => import('@/views/workflow/businessTrip/tripEdit.vue'),
|
||||
name: 'tripEdit',
|
||||
meta: { title: '出差申请', activeMenu: '/workflow/businessTrip', noCache: true }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/workflow/sealEdit',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['workflow:seal:edit'],
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
component: () => import('@/views/workflow/seal/sealEdit.vue'),
|
||||
name: 'sealEdit',
|
||||
meta: { title: '用章申请', activeMenu: '/workflow/seal', noCache: true }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/workflow/design',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['workflow:leave:edit'],
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
component: () => import('@/views/workflow/processDefinition/design.vue'),
|
||||
name: 'design',
|
||||
meta: { title: '流程设计', activeMenu: '/workflow/processDefinition', noCache: true }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -27,6 +27,11 @@ const setting: DefaultSettings = {
|
||||
*/
|
||||
tagsView: true,
|
||||
|
||||
/**
|
||||
* 显示页签图标
|
||||
*/
|
||||
tagsIcon: false,
|
||||
|
||||
/**
|
||||
* 是否固定头部
|
||||
*/
|
||||
@ -42,14 +47,6 @@ const setting: DefaultSettings = {
|
||||
*/
|
||||
dynamicTitle: false,
|
||||
|
||||
/**
|
||||
* @type {string | array} 'production' | ['production', 'development']
|
||||
* @description Need show err logs component.
|
||||
* The default is only used in the production env
|
||||
* If you want to also use it in dev, you can pass ['production', 'development']
|
||||
*/
|
||||
errorLog: 'production',
|
||||
|
||||
/**
|
||||
* 是否开启动画 开启随机 关闭渐进渐出
|
||||
*/
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { createPinia } from "pinia";
|
||||
import { createPinia } from 'pinia';
|
||||
|
||||
const store = createPinia();
|
||||
|
||||
|
@ -99,14 +99,14 @@ export const usePermissionStore = defineStore('permission', () => {
|
||||
};
|
||||
const filterChildren = (childrenMap: RouteRecordRaw[], lastRouter?: RouteRecordRaw): RouteRecordRaw[] => {
|
||||
let children: RouteRecordRaw[] = [];
|
||||
childrenMap.forEach(el => {
|
||||
childrenMap.forEach((el) => {
|
||||
el.path = lastRouter ? lastRouter.path + '/' + el.path : el.path;
|
||||
if (el.children && el.children.length && el.component?.toString() === 'ParentView') {
|
||||
children = children.concat(filterChildren(el.children, el));
|
||||
} else {
|
||||
children.push(el);
|
||||
}
|
||||
})
|
||||
});
|
||||
return children;
|
||||
};
|
||||
return {
|
||||
|
@ -5,10 +5,10 @@ import { useStorage } from '@vueuse/core';
|
||||
import { ref } from 'vue';
|
||||
|
||||
export const useSettingsStore = defineStore('setting', () => {
|
||||
// @ts-ignore
|
||||
const storageSetting = useStorage<LayoutSetting>('layout-setting', {
|
||||
topNav: defaultSettings.topNav,
|
||||
tagsView: defaultSettings.tagsView,
|
||||
tagsIcon: defaultSettings.tagsIcon,
|
||||
fixedHeader: defaultSettings.fixedHeader,
|
||||
sidebarLogo: defaultSettings.sidebarLogo,
|
||||
dynamicTitle: defaultSettings.dynamicTitle,
|
||||
@ -21,6 +21,7 @@ export const useSettingsStore = defineStore('setting', () => {
|
||||
const showSettings = ref<boolean>(defaultSettings.showSettings);
|
||||
const topNav = ref<boolean>(storageSetting.value.topNav);
|
||||
const tagsView = ref<boolean>(storageSetting.value.tagsView);
|
||||
const tagsIcon = ref<boolean>(storageSetting.value.tagsIcon);
|
||||
const fixedHeader = ref<boolean>(storageSetting.value.fixedHeader);
|
||||
const sidebarLogo = ref<boolean>(storageSetting.value.sidebarLogo);
|
||||
const dynamicTitle = ref<boolean>(storageSetting.value.dynamicTitle);
|
||||
@ -38,6 +39,7 @@ export const useSettingsStore = defineStore('setting', () => {
|
||||
showSettings,
|
||||
topNav,
|
||||
tagsView,
|
||||
tagsIcon,
|
||||
fixedHeader,
|
||||
sidebarLogo,
|
||||
dynamicTitle,
|
||||
|
6
src/types/global.d.ts
vendored
6
src/types/global.d.ts
vendored
@ -98,6 +98,10 @@ declare global {
|
||||
* 是否显示多标签导航
|
||||
*/
|
||||
tagsView: boolean;
|
||||
/**
|
||||
* 显示页签图标
|
||||
*/
|
||||
tagsIcon: boolean;
|
||||
/**
|
||||
* 是否固定头部
|
||||
*/
|
||||
@ -157,8 +161,6 @@ declare global {
|
||||
* false: 明亮模式
|
||||
*/
|
||||
dark: boolean;
|
||||
|
||||
errorLog: string;
|
||||
}
|
||||
}
|
||||
export {};
|
||||
|
@ -191,7 +191,8 @@ export function download(url: string, params: any, fileName: string) {
|
||||
const blob = new Blob([resp]);
|
||||
FileSaver.saveAs(blob, fileName);
|
||||
} else {
|
||||
const resText = await resp.data.text();
|
||||
const blob = new Blob([resp]);
|
||||
const resText = await blob.text();
|
||||
const rspObj = JSON.parse(resText);
|
||||
const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'];
|
||||
ElMessage.error(errMsg);
|
||||
|
@ -178,11 +178,11 @@ export const handleTree = <T>(data: any[], id?: string, parentId?: string, child
|
||||
|
||||
for (const d of data) {
|
||||
const parentId = d[config.parentId];
|
||||
const parentObj = childrenListMap[parentId]
|
||||
const parentObj = childrenListMap[parentId];
|
||||
if (!parentObj) {
|
||||
tree.push(d);
|
||||
} else {
|
||||
parentObj[config.childrenList].push(d)
|
||||
parentObj[config.childrenList].push(d);
|
||||
}
|
||||
}
|
||||
return tree;
|
||||
|
@ -49,7 +49,7 @@
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="demoList" @selection-change="handleSelectionChange">
|
||||
<el-table v-loading="loading" border :data="demoList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column v-if="true" label="主键" align="center" prop="id" />
|
||||
<el-table-column label="部门id" align="center" prop="deptId" />
|
||||
|
@ -33,6 +33,7 @@
|
||||
v-loading="loading"
|
||||
:data="treeList"
|
||||
row-key="id"
|
||||
border
|
||||
:default-expand-all="isExpandAll"
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
>
|
||||
|
@ -22,7 +22,7 @@
|
||||
<script setup lang="ts">
|
||||
import errImage from '@/assets/401_images/401.gif';
|
||||
|
||||
let { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const errGif = ref(errImage + '?' + +new Date());
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
let message = computed(() => {
|
||||
const message = computed(() => {
|
||||
return '找不到网页!';
|
||||
});
|
||||
</script>
|
||||
|
@ -260,10 +260,9 @@ onMounted(() => {
|
||||
background: #ffffff;
|
||||
width: 400px;
|
||||
padding: 25px 25px 5px 25px;
|
||||
|
||||
z-index: 1;
|
||||
.el-input {
|
||||
height: 40px;
|
||||
|
||||
input {
|
||||
height: 40px;
|
||||
}
|
||||
|
@ -4,12 +4,12 @@
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="合同名称" prop="contractName">
|
||||
<el-input v-model="queryParams.contractName" placeholder="请输入合同名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="合同编码" prop="contractCode">
|
||||
<el-input v-model="queryParams.contractCode" placeholder="请输入合同编码" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="合同名称" prop="contractName">
|
||||
<el-input v-model="queryParams.contractName" placeholder="请输入合同名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
@ -40,10 +40,30 @@
|
||||
|
||||
<el-table v-loading="loading" :data="contractInfoList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="" align="center" prop="id" v-if="true" />
|
||||
<el-table-column label="合同名称" align="center" prop="contractName" />
|
||||
<el-table-column label="合同类型" align="center" prop="contractType" />
|
||||
<el-table-column label="合同编码" align="center" prop="contractCode" />
|
||||
<!-- <el-table-column label="" align="center" prop="id" v-if="true" />-->
|
||||
<el-table-column label="合同编码" align="center" prop="contractCode" fixed="left"/>
|
||||
<el-table-column label="合同名称" align="center" prop="contractName" width="300" fixed="left"/>
|
||||
<el-table-column label="合同负责人" align="center" prop="contractManager" />
|
||||
<el-table-column label="重要性" align="center" prop="contractLevel" >
|
||||
<template #default="scope">
|
||||
<dict-tag :options="manage_contract_level" :value="scope.row.contractLevel" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="委托单位" align="center" prop="contractCode" />
|
||||
<el-table-column label="签约日期" align="center" prop="contractCode" />
|
||||
<el-table-column label="合同类型" align="center" prop="contractType" >
|
||||
<template #default="scope">
|
||||
<dict-tag :options="manage_contract_type" :value="scope.row.contractType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="已开票" align="center" prop="contractCode" />
|
||||
<el-table-column label="已收款" align="center" prop="contractCode" />
|
||||
<el-table-column label="未履行" align="center" prop="contractCode" />
|
||||
<el-table-column label="合同额" align="center" prop="contractCode" />
|
||||
<el-table-column label="合同结算额" align="center" prop="contractCode" />
|
||||
<el-table-column label="合同状态" align="center" prop="contractCode" />
|
||||
<el-table-column label="咨询类型" align="center" prop="contractCode" />
|
||||
<el-table-column label="业务类型" align="center" prop="contractCode" />
|
||||
<el-table-column label="备注" align="center" prop="remark" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
@ -61,12 +81,34 @@
|
||||
</el-card>
|
||||
<!-- 添加或修改合同信息对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||
<el-form ref="contractInfoFormRef" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form ref="contractInfoFormRef" :model="form" :rules="rules" label-width="110px">
|
||||
<el-form-item label="合同编码" prop="contractCode">
|
||||
<el-input v-model="form.contractCode" placeholder="请输入合同编码" />
|
||||
</el-form-item>
|
||||
<el-form-item label="合同名称" prop="contractName">
|
||||
<el-input v-model="form.contractName" placeholder="请输入合同名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="合同编码" prop="contractCode">
|
||||
<el-input v-model="form.contractCode" placeholder="请输入合同编码" />
|
||||
<el-form-item label="合同类型" prop="contractType">
|
||||
<el-select v-model="form.contractType" placeholder="请选择">
|
||||
<el-option v-for="dict in manage_contract_type" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="合同重要性" prop="manageContractLevel">
|
||||
<el-select v-model="form.manageContractLevel" placeholder="请选择">
|
||||
<el-option v-for="dict in manage_contract_level" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="合同重要性" prop="manageContractLevel">
|
||||
<el-select v-model="form.manageContractLevel" placeholder="请选择">
|
||||
<el-option v-for="dict in manage_contract_level" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="合同负责人" prop="contractManagerId">
|
||||
<el-button type="primary" icon="Plus" circle @click="openUserSelect" />
|
||||
<el-tag v-for="user in selectUserList" :key="user.userId" closable style="margin: 2px"
|
||||
@close="handleCloseTag(user)">
|
||||
{{ user.employeeName }}
|
||||
</el-tag>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
|
||||
@ -78,6 +120,8 @@
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<UserSelect ref="userSelectRef" :multiple="false" :data="selectUserIds" @confirm-call-back="userSelectCallBack">
|
||||
</UserSelect>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
@ -85,7 +129,8 @@
|
||||
<script setup name="ContractInfo" lang="ts">
|
||||
import { listContractInfo, getContractInfo, delContractInfo, addContractInfo, updateContractInfo } from '@/api/manage/contract';
|
||||
import { ContractInfoVO, ContractInfoQuery, ContractInfoForm } from '@/api/manage/contract/types';
|
||||
|
||||
import UserSelect from '@/components/UserSelect/index.vue';
|
||||
import { UserVO } from '@/api/system/user/types';
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const contractInfoList = ref<ContractInfoVO[]>([]);
|
||||
@ -99,7 +144,12 @@ const total = ref(0);
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const contractInfoFormRef = ref<ElFormInstance>();
|
||||
|
||||
const userFormRef = ref<ElFormInstance>();
|
||||
//user
|
||||
const selectUserList = ref<UserVO[]>([]);
|
||||
//userid
|
||||
const selectUserIds = ref<string>(undefined);
|
||||
const userSelectRef = ref<InstanceType<typeof UserSelect>>();
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
@ -131,7 +181,7 @@ const data = reactive<PageData<ContractInfoForm, ContractInfoQuery>>({
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
const { manage_contract_type,manage_contract_level } = toRefs<any>(proxy?.useDict('manage_contract_type','manage_contract_level'));
|
||||
/** 查询合同信息列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
@ -187,6 +237,32 @@ const handleUpdate = async (row?: ContractInfoVO) => {
|
||||
Object.assign(form.value, res.data);
|
||||
dialog.visible = true;
|
||||
dialog.title = "修改合同信息";
|
||||
console.log(row)
|
||||
const newUser: UserVO = {
|
||||
userId: form.value.contractManagerId,
|
||||
employeeName: form.value.contractManager,
|
||||
tenantId: undefined,
|
||||
deptId: undefined,
|
||||
userName: undefined,
|
||||
nickName: undefined,
|
||||
userType: undefined,
|
||||
email: undefined,
|
||||
phonenumber: undefined,
|
||||
sex: undefined,
|
||||
avatar: undefined,
|
||||
status: undefined,
|
||||
delFlag: undefined,
|
||||
loginIp: undefined,
|
||||
loginDate: undefined,
|
||||
remark: undefined,
|
||||
deptName: undefined,
|
||||
roles: undefined,
|
||||
roleIds: undefined,
|
||||
postIds: undefined,
|
||||
roleId: undefined,
|
||||
admin: undefined
|
||||
};
|
||||
selectUserList.value[0] = newUser;
|
||||
}
|
||||
|
||||
/** 提交按钮 */
|
||||
@ -222,6 +298,46 @@ const handleExport = () => {
|
||||
}, `contractInfo_${new Date().getTime()}.xlsx`)
|
||||
}
|
||||
|
||||
//打开人员
|
||||
const openUserSelect = () => {
|
||||
if (userSelectRef.value) {
|
||||
userSelectRef.value.open();
|
||||
// 确保 UserSelect 的 data 是数组格式(即使单选也传数组)
|
||||
userSelectRef.value.$el.querySelector('input')?.focus(); // 可选:自动聚焦输入框
|
||||
console.log('selectUserList')
|
||||
console.log(selectUserList)
|
||||
if (selectUserList.value.length !== 0) {
|
||||
console.log('selectUserList不为空')
|
||||
selectUserIds.value = selectUserList.value.map((item) => item.userId).join(',');
|
||||
}else{
|
||||
selectUserIds.value = undefined;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
//确认人员
|
||||
const userSelectCallBack = (data: UserVO[]) => {
|
||||
if (data && data.length > 0) {
|
||||
selectUserList.value = data;
|
||||
selectUserIds.value = data[0].userId.toString();
|
||||
// 单选模式下直接取第一个用户的ID
|
||||
form.value.contractManagerId = selectUserIds.value; // 同步到表单(关键!)
|
||||
} else {
|
||||
selectUserList.value = [];
|
||||
selectUserIds.value = '';
|
||||
form.value.contractManagerId = ''; // 清空表单
|
||||
}
|
||||
};
|
||||
//删除人员
|
||||
const handleCloseTag = (user: UserVO) => {
|
||||
const userId = user.userId;
|
||||
// 使用split删除用户
|
||||
const index = selectUserList.value.findIndex((item) => item.userId === userId);
|
||||
selectUserList.value.splice(index, 1);
|
||||
selectUserIds.value = selectUserList.value.map((item) => item.userId).join(',');
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
|
@ -40,18 +40,19 @@
|
||||
|
||||
<el-table v-loading="loading" :data="customerInfoList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="" align="center" prop="id" v-if="true" />
|
||||
<!-- <el-table-column label="" align="center" prop="id" v-if="true" />-->
|
||||
<el-table-column label="客户编码" align="center" prop="customerCode" />
|
||||
<el-table-column label="客户名称" align="center" prop="customerName" />
|
||||
<el-table-column label="客户类型" align="center" prop="customerType" />
|
||||
<el-table-column label="客户编码" align="center" prop="customerCode" />
|
||||
|
||||
<el-table-column label="备注" align="center" prop="remark" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:customerInfo:edit']"></el-button>
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['manage:customerInfo:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:customerInfo:remove']"></el-button>
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['manage:customerInfo:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
@ -63,6 +63,7 @@
|
||||
v-loading="loading"
|
||||
:data="loginInfoList"
|
||||
:default-sort="defaultSort"
|
||||
border
|
||||
@selection-change="handleSelectionChange"
|
||||
@sort-change="handleSortChange"
|
||||
>
|
||||
|
@ -19,6 +19,7 @@
|
||||
<el-card shadow="hover">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="onlineList.slice((queryParams.pageNum - 1) * queryParams.pageSize, queryParams.pageNum * queryParams.pageSize)"
|
||||
style="width: 100%"
|
||||
>
|
||||
|
@ -65,6 +65,7 @@
|
||||
ref="operLogTableRef"
|
||||
v-loading="loading"
|
||||
:data="operlogList"
|
||||
border
|
||||
:default-sort="defaultSort"
|
||||
@selection-change="handleSelectionChange"
|
||||
@sort-change="handleSortChange"
|
||||
|
@ -108,8 +108,8 @@
|
||||
<el-table-column v-if="columns[3].visible" key="sex" label="性别" align="center" prop="sex" :show-overflow-tooltip="true" >
|
||||
<template #default="scope">
|
||||
<dict-tag :options="sys_user_sex" :value="scope.row.sex" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="columns[4].visible" key="deptName" label="部门" align="center" prop="deptName" :show-overflow-tooltip="true" width="180"/>
|
||||
<el-table-column v-if="columns[5].visible" key="phonenumber" label="手机号码" align="center" prop="phonenumber" width="120" />
|
||||
<el-table-column v-if="columns[6].visible" key="employeeHireDate" label="入职时间" align="center" prop="employeeHireDate" width="120" />
|
||||
@ -117,12 +117,12 @@
|
||||
<template #default="scope">
|
||||
<dict-tag :options="opr_yes_no" :value="scope.row.deptAdminFlag" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="columns[8].visible" key="employeeStatus" label="用工状态" align="center" prop="employeeStatus" width="100">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="opr_employee_status" :value="scope.row.employeeStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="columns[9].visible" key="status" label="状态" align="center">
|
||||
<template #default="scope">
|
||||
<el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch>
|
||||
|
@ -203,7 +203,6 @@ onMounted(() => {
|
||||
line-height: 0;
|
||||
color: #7483a3;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.register-form {
|
||||
|
@ -45,7 +45,7 @@
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="clientList" @selection-change="handleSelectionChange">
|
||||
<el-table v-loading="loading" :data="clientList" border @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column v-if="true" label="id" align="center" prop="id" />
|
||||
<el-table-column label="客户端id" align="center" prop="clientId" />
|
||||
@ -300,7 +300,7 @@ const handleExport = () => {
|
||||
|
||||
/** 状态修改 */
|
||||
const handleStatusChange = async (row: ClientVO) => {
|
||||
let text = row.status === '0' ? '启用' : '停用';
|
||||
const text = row.status === '0' ? '启用' : '停用';
|
||||
try {
|
||||
await proxy?.$modal.confirm('确认要"' + text + '"吗?');
|
||||
await changeStatus(row.clientId, row.status);
|
||||
|
@ -60,7 +60,7 @@
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="configList" @selection-change="handleSelectionChange">
|
||||
<el-table v-loading="loading" border :data="configList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column v-if="false" label="参数主键" align="center" prop="configId" />
|
||||
<el-table-column label="参数名称" align="center" prop="configName" :show-overflow-tooltip="true" />
|
||||
|
@ -42,6 +42,7 @@
|
||||
v-loading="loading"
|
||||
:data="deptList"
|
||||
row-key="deptId"
|
||||
border
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
:default-expand-all="isExpandAll"
|
||||
>
|
||||
|
@ -44,7 +44,7 @@
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
|
||||
<el-table v-loading="loading" border :data="dataList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column v-if="false" label="字典编码" align="center" prop="dictCode" />
|
||||
<el-table-column label="字典标签" align="center" prop="dictLabel">
|
||||
|
@ -53,7 +53,7 @@
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="typeList" @selection-change="handleSelectionChange">
|
||||
<el-table v-loading="loading" border :data="typeList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column v-if="false" label="字典编号" align="center" prop="dictId" />
|
||||
<el-table-column label="字典名称" align="center" prop="dictName" :show-overflow-tooltip="true" />
|
||||
|
@ -30,6 +30,9 @@
|
||||
<el-col :span="1.5">
|
||||
<el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">展开/折叠</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" @click="handleCascadeDelete" :loading="deleteLoading">级联删除</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:show-search="showSearch" @query-table="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
@ -39,6 +42,7 @@
|
||||
v-loading="loading"
|
||||
:data="menuList"
|
||||
row-key="menuId"
|
||||
border
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
:default-expand-all="isExpandAll"
|
||||
>
|
||||
@ -129,8 +133,8 @@
|
||||
</span>
|
||||
</template>
|
||||
<el-radio-group v-model="form.isFrame">
|
||||
<el-radio label="0">是</el-radio>
|
||||
<el-radio label="1">否</el-radio>
|
||||
<el-radio value="0">是</el-radio>
|
||||
<el-radio value="1">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -207,8 +211,8 @@
|
||||
</span>
|
||||
</template>
|
||||
<el-radio-group v-model="form.isCache">
|
||||
<el-radio label="0">缓存</el-radio>
|
||||
<el-radio label="1">不缓存</el-radio>
|
||||
<el-radio value="0">缓存</el-radio>
|
||||
<el-radio value="1">不缓存</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -225,7 +229,7 @@
|
||||
</span>
|
||||
</template>
|
||||
<el-radio-group v-model="form.visible">
|
||||
<el-radio v-for="dict in sys_show_hide" :key="dict.value" :label="dict.value">{{ dict.label }} </el-radio>
|
||||
<el-radio v-for="dict in sys_show_hide" :key="dict.value" :value="dict.value">{{ dict.label }} </el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -242,7 +246,7 @@
|
||||
</span>
|
||||
</template>
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.value">
|
||||
<el-radio v-for="dict in sys_normal_disable" :key="dict.value" :value="dict.value">
|
||||
{{ dict.label }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
@ -257,11 +261,31 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="deleteDialog.visible" :title="deleteDialog.title" destroy-on-close append-to-bod width="750px">
|
||||
<el-tree
|
||||
ref="menuTreeRef"
|
||||
class="tree-border"
|
||||
:data="menuOptions"
|
||||
show-checkbox
|
||||
node-key="menuId"
|
||||
:check-strictly="false"
|
||||
empty-text="加载中,请稍候"
|
||||
:default-expanded-keys="[0]"
|
||||
:props="{ value: 'menuId', label: 'menuName', children: 'children' } as any"
|
||||
/>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitDeleteForm" :loading="deleteLoading">确 定</el-button>
|
||||
<el-button @click="cancelCascade">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="Menu" lang="ts">
|
||||
import { addMenu, delMenu, getMenu, listMenu, updateMenu } from '@/api/system/menu';
|
||||
import { addMenu, cascadeDelMenu, delMenu, getMenu, listMenu, updateMenu } from '@/api/system/menu';
|
||||
import { MenuForm, MenuQuery, MenuVO } from '@/api/system/menu/types';
|
||||
import { MenuTypeEnum } from '@/enums/MenuTypeEnum';
|
||||
|
||||
@ -404,7 +428,50 @@ const handleDelete = async (row: MenuVO) => {
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
};
|
||||
|
||||
const deleteLoading = ref<boolean>(false);
|
||||
const menuTreeRef = ref<ElTreeInstance>();
|
||||
|
||||
const deleteDialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: '级联删除菜单'
|
||||
});
|
||||
|
||||
/** 级联删除按钮操作 */
|
||||
const handleCascadeDelete = () => {
|
||||
menuTreeRef.value?.setCheckedKeys([]);
|
||||
getTreeselect();
|
||||
deleteDialog.visible = true;
|
||||
};
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancelCascade = () => {
|
||||
menuTreeRef.value?.setCheckedKeys([]);
|
||||
deleteDialog.visible = false;
|
||||
};
|
||||
|
||||
/** 删除提交按钮 */
|
||||
const submitDeleteForm = async () => {
|
||||
const menuIds = menuTreeRef.value?.getCheckedKeys();
|
||||
if (menuIds.length < 0) {
|
||||
proxy?.$modal.msgWarning('请选择要删除的菜单');
|
||||
return;
|
||||
}
|
||||
|
||||
deleteLoading.value = true;
|
||||
await cascadeDelMenu(menuIds).finally(() => (deleteLoading.value = false));
|
||||
await getList();
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
deleteDialog.visible = false;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.tree-border {
|
||||
height: 300px;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
|
@ -44,7 +44,7 @@
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="noticeList" @selection-change="handleSelectionChange">
|
||||
<el-table v-loading="loading" border :data="noticeList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column v-if="false" label="序号" align="center" prop="noticeId" width="100" />
|
||||
<el-table-column label="公告标题" align="center" prop="noticeTitle" :show-overflow-tooltip="true" />
|
||||
|
@ -87,10 +87,18 @@
|
||||
<el-input v-model="form.configKey" placeholder="请输入配置key" />
|
||||
</el-form-item>
|
||||
<el-form-item label="访问站点" prop="endpoint">
|
||||
<el-input v-model="form.endpoint" placeholder="请输入访问站点" />
|
||||
<el-input v-model="form.endpoint" placeholder="请输入访问站点">
|
||||
<template #prefix>
|
||||
<span style="color: #999">{{ protocol }}</span>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="自定义域名" prop="domain">
|
||||
<el-input v-model="form.domain" placeholder="请输入自定义域名" />
|
||||
<el-input v-model="form.domain" placeholder="请输入自定义域名">
|
||||
<template #prefix>
|
||||
<span style="color: #999">{{ protocol }}</span>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="accessKey" prop="accessKey">
|
||||
<el-input v-model="form.accessKey" placeholder="请输入accessKey" />
|
||||
@ -239,6 +247,8 @@ const data = reactive<PageData<OssConfigForm, OssConfigQuery>>({
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
const protocol = computed(() => (form.value.isHttps === 'Y' ? 'https://' : 'http://'));
|
||||
|
||||
/** 查询对象存储配置列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
@ -306,7 +316,7 @@ const submitForm = () => {
|
||||
};
|
||||
/** 状态修改 */
|
||||
const handleStatusChange = async (row: OssConfigVO) => {
|
||||
let text = row.status === '0' ? '启用' : '停用';
|
||||
const text = row.status === '0' ? '启用' : '停用';
|
||||
try {
|
||||
await proxy?.$modal.confirm('确认要"' + text + '""' + row.configKey + '"配置吗?');
|
||||
await changeOssConfigStatus(row.ossConfigId, row.status, row.configKey);
|
||||
|
@ -70,6 +70,7 @@
|
||||
v-if="showTable"
|
||||
v-loading="loading"
|
||||
:data="ossList"
|
||||
border
|
||||
:header-cell-class-name="handleHeaderClass"
|
||||
@selection-change="handleSelectionChange"
|
||||
@header-click="handleHeaderCLick"
|
||||
@ -255,9 +256,9 @@ const handleHeaderCLick = (column: any) => {
|
||||
handleOrderChange(column.property, column.multiOrder);
|
||||
};
|
||||
const handleOrderChange = (prop: string, order: string) => {
|
||||
let orderByArr = queryParams.value.orderByColumn ? queryParams.value.orderByColumn.split(',') : [];
|
||||
let isAscArr = queryParams.value.isAsc ? queryParams.value.isAsc.split(',') : [];
|
||||
let propIndex = orderByArr.indexOf(prop);
|
||||
const orderByArr = queryParams.value.orderByColumn ? queryParams.value.orderByColumn.split(',') : [];
|
||||
const isAscArr = queryParams.value.isAsc ? queryParams.value.isAsc.split(',') : [];
|
||||
const propIndex = orderByArr.indexOf(prop);
|
||||
if (propIndex !== -1) {
|
||||
if (order) {
|
||||
//排序里已存在 只修改排序
|
||||
@ -306,7 +307,7 @@ const handleDownload = (row: OssVO) => {
|
||||
};
|
||||
/** 预览开关按钮 */
|
||||
const handlePreviewListResource = async (preview: boolean) => {
|
||||
let text = preview ? '启用' : '停用';
|
||||
const text = preview ? '启用' : '停用';
|
||||
try {
|
||||
await proxy?.$modal.confirm('确认要"' + text + '""预览列表图片"配置吗?');
|
||||
await proxy?.updateConfigByKey('sys.oss.previewListResource', preview);
|
||||
|
@ -84,7 +84,7 @@
|
||||
<right-toolbar v-model:show-search="showSearch" @query-table="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
<el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange">
|
||||
<el-table v-loading="loading" border :data="postList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column v-if="false" label="岗位编号" align="center" prop="postId" />
|
||||
<el-table-column label="岗位编码" align="center" prop="postCode" />
|
||||
|
@ -33,7 +33,7 @@
|
||||
<right-toolbar v-model:show-search="showSearch" :search="true" @query-table="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
<el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
|
||||
<el-table v-loading="loading" border :data="userList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="用户账号" prop="userName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="用户姓名" prop="nickName" :show-overflow-tooltip="true" />
|
||||
|
@ -55,7 +55,7 @@
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table ref="roleTableRef" v-loading="loading" :data="roleList" @selection-change="handleSelectionChange">
|
||||
<el-table ref="roleTableRef" border v-loading="loading" :data="roleList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column v-if="false" label="角色编号" prop="roleId" width="120" />
|
||||
<el-table-column label="角色名称" prop="roleName" :show-overflow-tooltip="true" width="150" />
|
||||
@ -323,7 +323,7 @@ const handleSelectionChange = (selection: RoleVO[]) => {
|
||||
|
||||
/** 角色状态修改 */
|
||||
const handleStatusChange = async (row: RoleVO) => {
|
||||
let text = row.status === '0' ? '启用' : '停用';
|
||||
const text = row.status === '0' ? '启用' : '停用';
|
||||
try {
|
||||
await proxy?.$modal.confirm('确认要"' + text + '""' + row.roleName + '"角色吗?');
|
||||
await changeRoleStatus(row.roleId, row.status);
|
||||
@ -346,11 +346,11 @@ const getMenuTreeselect = async () => {
|
||||
/** 所有部门节点数据 */
|
||||
const getDeptAllCheckedKeys = (): any => {
|
||||
// 目前被选中的部门节点
|
||||
let checkedKeys = deptRef.value?.getCheckedKeys();
|
||||
const checkedKeys = deptRef.value?.getCheckedKeys();
|
||||
// 半选中的部门节点
|
||||
let halfCheckedKeys = deptRef.value?.getHalfCheckedKeys();
|
||||
const halfCheckedKeys = deptRef.value?.getHalfCheckedKeys();
|
||||
if (halfCheckedKeys) {
|
||||
checkedKeys?.unshift.apply(checkedKeys, halfCheckedKeys);
|
||||
checkedKeys?.unshift(...halfCheckedKeys);
|
||||
}
|
||||
return checkedKeys;
|
||||
};
|
||||
@ -404,14 +404,14 @@ const getRoleDeptTreeSelect = async (roleId: string | number) => {
|
||||
/** 树权限(展开/折叠)*/
|
||||
const handleCheckedTreeExpand = (value: boolean, type: string) => {
|
||||
if (type == 'menu') {
|
||||
let treeList = menuOptions.value;
|
||||
const treeList = menuOptions.value;
|
||||
for (let i = 0; i < treeList.length; i++) {
|
||||
if (menuRef.value) {
|
||||
menuRef.value.store.nodesMap[treeList[i].id].expanded = value;
|
||||
}
|
||||
}
|
||||
} else if (type == 'dept') {
|
||||
let treeList = deptOptions.value;
|
||||
const treeList = deptOptions.value;
|
||||
for (let i = 0; i < treeList.length; i++) {
|
||||
if (deptRef.value) {
|
||||
deptRef.value.store.nodesMap[treeList[i].id].expanded = value;
|
||||
@ -438,11 +438,11 @@ const handleCheckedTreeConnect = (value: any, type: string) => {
|
||||
/** 所有菜单节点数据 */
|
||||
const getMenuAllCheckedKeys = (): any => {
|
||||
// 目前被选中的菜单节点
|
||||
let checkedKeys = menuRef.value?.getCheckedKeys();
|
||||
const checkedKeys = menuRef.value?.getCheckedKeys();
|
||||
// 半选中的菜单节点
|
||||
let halfCheckedKeys = menuRef.value?.getHalfCheckedKeys();
|
||||
const halfCheckedKeys = menuRef.value?.getHalfCheckedKeys();
|
||||
if (halfCheckedKeys) {
|
||||
checkedKeys?.unshift.apply(checkedKeys, halfCheckedKeys);
|
||||
checkedKeys?.unshift(...halfCheckedKeys);
|
||||
}
|
||||
return checkedKeys;
|
||||
};
|
||||
|
@ -14,10 +14,10 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-row>
|
||||
<el-table ref="tableRef" :data="userList" height="260px" @row-click="clickRow" @selection-change="handleSelectionChange">
|
||||
<el-table ref="tableRef" border :data="userList" height="260px" @row-click="clickRow" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55"></el-table-column>
|
||||
<el-table-column label="用户账号" prop="userName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="用户姓名" prop="nickName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="用户名称" prop="userName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="用户昵称" prop="nickName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="邮箱" prop="email" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="手机" prop="phonenumber" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="状态" align="center" prop="status">
|
||||
|
@ -51,7 +51,7 @@
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="tenantList" @selection-change="handleSelectionChange">
|
||||
<el-table v-loading="loading" border :data="tenantList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column v-if="false" label="id" align="center" prop="id" />
|
||||
<el-table-column label="租户编号" align="center" prop="tenantId" />
|
||||
@ -245,7 +245,7 @@ const getList = async () => {
|
||||
|
||||
// 租户套餐状态修改
|
||||
const handleStatusChange = async (row: TenantVO) => {
|
||||
let text = row.status === '0' ? '启用' : '停用';
|
||||
const text = row.status === '0' ? '启用' : '停用';
|
||||
try {
|
||||
await proxy?.$modal.confirm('确认要"' + text + '""' + row.companyName + '"租户吗?');
|
||||
await changeTenantStatus(row.id, row.tenantId, row.status);
|
||||
@ -361,7 +361,7 @@ const handleExport = () => {
|
||||
/**同步租户字典*/
|
||||
const handleSyncTenantDict = async () => {
|
||||
await proxy?.$modal.confirm('确认要同步所有租户字典吗?');
|
||||
let res = await syncTenantDict();
|
||||
const res = await syncTenantDict();
|
||||
proxy?.$modal.msgSuccess(res.msg);
|
||||
};
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="tenantPackageList" @selection-change="handleSelectionChange">
|
||||
<el-table v-loading="loading" border :data="tenantPackageList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column v-if="false" label="租户套餐id" align="center" prop="packageId" />
|
||||
<el-table-column label="套餐名称" align="center" prop="packageName" />
|
||||
@ -167,11 +167,11 @@ const getMenuTreeselect = async () => {
|
||||
// 所有菜单节点数据
|
||||
const getMenuAllCheckedKeys = (): any => {
|
||||
// 目前被选中的菜单节点
|
||||
let checkedKeys = menuTreeRef.value?.getCheckedKeys();
|
||||
const checkedKeys = menuTreeRef.value?.getCheckedKeys();
|
||||
// 半选中的菜单节点
|
||||
let halfCheckedKeys = menuTreeRef.value?.getHalfCheckedKeys();
|
||||
const halfCheckedKeys = menuTreeRef.value?.getHalfCheckedKeys();
|
||||
if (halfCheckedKeys) {
|
||||
checkedKeys?.unshift.apply(checkedKeys, halfCheckedKeys);
|
||||
checkedKeys?.unshift(...halfCheckedKeys);
|
||||
}
|
||||
return checkedKeys;
|
||||
};
|
||||
@ -194,7 +194,7 @@ const getList = async () => {
|
||||
|
||||
// 租户套餐状态修改
|
||||
const handleStatusChange = async (row: TenantPkgVO) => {
|
||||
let text = row.status === '0' ? '启用' : '停用';
|
||||
const text = row.status === '0' ? '启用' : '停用';
|
||||
const [err] = await to(proxy?.$modal.confirm('确认要"' + text + '""' + row.packageName + '"套餐吗?') as Promise<any>);
|
||||
if (err) {
|
||||
row.status = row.status === '0' ? '1' : '0';
|
||||
@ -241,7 +241,7 @@ const handleSelectionChange = (selection: TenantPkgVO[]) => {
|
||||
// 树权限(展开/折叠)
|
||||
const handleCheckedTreeExpand = (value: CheckboxValueType, type: string) => {
|
||||
if (type == 'menu') {
|
||||
let treeList = menuOptions.value;
|
||||
const treeList = menuOptions.value;
|
||||
for (let i = 0; i < treeList.length; i++) {
|
||||
if (menuTreeRef.value) {
|
||||
menuTreeRef.value.store.nodesMap[treeList[i].id].expanded = value as boolean;
|
||||
|
@ -7,6 +7,8 @@
|
||||
<el-col :span="2.5">
|
||||
<el-form-item label="员工姓名" prop="employeeName">
|
||||
<el-input v-model="form.employeeName" disabled />
|
||||
<el-form-item label="用户昵称" prop="nickName">
|
||||
<el-input v-model="form.nickName" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="2.5">
|
||||
@ -23,6 +25,7 @@
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
v-loading="loading"
|
||||
border
|
||||
:row-key="getRowKey"
|
||||
:data="roles.slice((pageNum - 1) * pageSize, pageNum * pageSize)"
|
||||
@row-click="clickRow"
|
||||
@ -33,7 +36,7 @@
|
||||
<span>{{ (pageNum - 1) * pageSize + scope.$index + 1 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column type="selection" :reserve-selection="true" width="55"></el-table-column>
|
||||
<el-table-column type="selection" :reserve-selection="true" :selectable="checkSelectable" width="55"></el-table-column>
|
||||
<el-table-column label="角色编号" align="center" prop="roleId" />
|
||||
<el-table-column label="角色名称" align="center" prop="roleName" />
|
||||
<el-table-column label="权限字符" align="center" prop="roleKey" />
|
||||
@ -72,6 +75,7 @@ const roleIds = ref<Array<string | number>>([]);
|
||||
const roles = ref<RoleVO[]>([]);
|
||||
const form = ref<Partial<UserForm>>({
|
||||
employeeName: undefined,
|
||||
nickName: undefined,
|
||||
userName: '',
|
||||
userId: undefined
|
||||
});
|
||||
@ -80,8 +84,10 @@ const tableRef = ref<ElTableInstance>();
|
||||
|
||||
/** 单击选中行数据 */
|
||||
const clickRow = (row: RoleVO) => {
|
||||
row.flag = !row.flag;
|
||||
tableRef.value?.toggleRowSelection(row, row.flag);
|
||||
if (checkSelectable(row)) {
|
||||
row.flag = !row.flag;
|
||||
tableRef.value?.toggleRowSelection(row, row.flag);
|
||||
}
|
||||
};
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: RoleVO[]) => {
|
||||
@ -91,6 +97,10 @@ const handleSelectionChange = (selection: RoleVO[]) => {
|
||||
const getRowKey = (row: RoleVO): string => {
|
||||
return String(row.roleId);
|
||||
};
|
||||
/** 检查角色状态 */
|
||||
const checkSelectable = (row: RoleVO): boolean => {
|
||||
return row.status === '0';
|
||||
};
|
||||
/** 关闭按钮 */
|
||||
const close = () => {
|
||||
const obj: RouteLocationNormalized = {
|
||||
|
@ -27,6 +27,9 @@
|
||||
<el-form-item label="用户名称" prop="userName">
|
||||
<el-input v-model="queryParams.userName" placeholder="请输入用户名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="用户昵称" prop="nickName">
|
||||
<el-input v-model="queryParams.nickName" placeholder="请输入用户昵称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号码" prop="phonenumber">
|
||||
<el-input v-model="queryParams.phonenumber" placeholder="请输入手机号码" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
@ -92,11 +95,11 @@
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
|
||||
<el-table v-loading="loading" border :data="userList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="50" align="center" />
|
||||
<el-table-column v-if="columns[0].visible" key="userId" label="用户编号" align="center" prop="userId" />
|
||||
<el-table-column v-if="columns[1].visible" key="userName" label="用户账号" align="center" prop="userName" :show-overflow-tooltip="true" />
|
||||
<el-table-column v-if="columns[2].visible" key="nickName" label="用户姓名" align="center" prop="nickName" :show-overflow-tooltip="true" />
|
||||
<el-table-column v-if="columns[1].visible" key="userName" label="用户名称" align="center" prop="userName" :show-overflow-tooltip="true" />
|
||||
<el-table-column v-if="columns[2].visible" key="nickName" label="用户昵称" align="center" prop="nickName" :show-overflow-tooltip="true" />
|
||||
<el-table-column v-if="columns[3].visible" key="deptName" label="部门" align="center" prop="deptName" :show-overflow-tooltip="true" />
|
||||
<el-table-column v-if="columns[4].visible" key="phonenumber" label="手机号码" align="center" prop="phonenumber" width="120" />
|
||||
<el-table-column v-if="columns[5].visible" key="status" label="状态" align="center">
|
||||
@ -147,8 +150,8 @@
|
||||
<el-form ref="userFormRef" :model="form" :rules="rules" label-width="80px">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="用户姓名" prop="nickName">
|
||||
<el-input v-model="form.nickName" placeholder="请输入用户姓名" maxlength="30" />
|
||||
<el-form-item label="用户昵称" prop="nickName">
|
||||
<el-input v-model="form.nickName" placeholder="请输入用户昵称" maxlength="30" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
@ -334,7 +337,7 @@ const upload = reactive<ImportOption>({
|
||||
const columns = ref<FieldOption[]>([
|
||||
{ key: 0, label: `用户编号`, visible: false, children: [] },
|
||||
{ key: 1, label: `用户名称`, visible: true, children: [] },
|
||||
{ key: 2, label: `用户姓名`, visible: true, children: [] },
|
||||
{ key: 2, label: `用户昵称`, visible: true, children: [] },
|
||||
{ key: 3, label: `部门`, visible: true, children: [] },
|
||||
{ key: 4, label: `手机号码`, visible: true, children: [] },
|
||||
{ key: 5, label: `状态`, visible: true, children: [] },
|
||||
@ -498,7 +501,7 @@ const handleDelete = async (row?: UserVO) => {
|
||||
|
||||
/** 用户状态修改 */
|
||||
const handleStatusChange = async (row: UserVO) => {
|
||||
let text = row.status === '0' ? '启用' : '停用';
|
||||
const text = row.status === '0' ? '启用' : '停用';
|
||||
try {
|
||||
await proxy?.$modal.confirm('确认要"' + text + '""' + row.userName + '"用户吗?');
|
||||
await api.changeUserStatus(row.userId, row.status);
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-table :data="devices" style="width: 100%; height: 100%; font-size: 14px">
|
||||
<el-table :data="devices" border style="width: 100%; height: 100%; font-size: 14px">
|
||||
<el-table-column label="设备类型" align="center">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="sys_device_type" :value="scope.row.deviceType" />
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-table :data="auths" style="width: 100%; height: 100%; font-size: 14px">
|
||||
<el-table :data="auths" border style="width: 100%; height: 100%; font-size: 14px">
|
||||
<el-table-column label="序号" width="50" type="index" />
|
||||
<el-table-column label="绑定账号平台" width="140" align="center" prop="source" show-overflow-tooltip />
|
||||
<el-table-column label="头像" width="120" align="center" prop="avatar">
|
||||
|
@ -134,7 +134,7 @@ const beforeUpload = (file: UploadRawFile): any => {
|
||||
/** 上传图片 */
|
||||
const uploadImg = async () => {
|
||||
cropper.value.getCropBlob(async (data: any) => {
|
||||
let formData = new FormData();
|
||||
const formData = new FormData();
|
||||
formData.append('avatarfile', data, options.fileName);
|
||||
const res = await uploadAvatar(formData);
|
||||
open.value = false;
|
||||
|
@ -33,7 +33,7 @@ const userForm = computed(() => props.user);
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const userRef = ref<ElFormInstance>();
|
||||
const rule: ElFormRules = {
|
||||
nickName: [{ required: true, message: '用户姓名不能为空', trigger: 'blur' }],
|
||||
nickName: [{ required: true, message: '用户昵称不能为空', trigger: 'blur' }],
|
||||
email: [
|
||||
{ required: true, message: '邮箱地址不能为空', trigger: 'blur' },
|
||||
{
|
||||
|
@ -5,7 +5,7 @@
|
||||
<basic-info-form ref="basicInfo" :info="info" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="字段信息" name="columnInfo">
|
||||
<el-table ref="dragTable" :data="columns" row-key="columnId" :max-height="tableHeight">
|
||||
<el-table ref="dragTable" border :data="columns" row-key="columnId" :max-height="tableHeight">
|
||||
<el-table-column label="序号" type="index" min-width="5%" />
|
||||
<el-table-column label="字段列名" prop="columnName" min-width="10%" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="字段描述" min-width="10%">
|
||||
|
@ -19,7 +19,7 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-row>
|
||||
<el-table ref="tableRef" :data="dbTableList" height="260px" @row-click="clickRow" @selection-change="handleSelectionChange">
|
||||
<el-table ref="tableRef" border :data="dbTableList" height="260px" @row-click="clickRow" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55"></el-table-column>
|
||||
<el-table-column prop="tableName" label="表名称" :show-overflow-tooltip="true"></el-table-column>
|
||||
<el-table-column prop="tableComment" label="表描述" :show-overflow-tooltip="true"></el-table-column>
|
||||
|
@ -56,7 +56,7 @@
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="tableList" @selection-change="handleSelectionChange">
|
||||
<el-table v-loading="loading" border :data="tableList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" align="center" width="55"></el-table-column>
|
||||
<el-table-column label="序号" type="index" width="50" align="center">
|
||||
<template #default="scope">
|
||||
@ -113,8 +113,8 @@
|
||||
</template>
|
||||
|
||||
<script setup name="Gen" lang="ts">
|
||||
import {delTable, genCode, getDataNames, listTable, previewTable, synchDb} from '@/api/tool/gen';
|
||||
import {TableQuery, TableVO} from '@/api/tool/gen/types';
|
||||
import { delTable, genCode, getDataNames, listTable, previewTable, synchDb } from '@/api/tool/gen';
|
||||
import { TableQuery, TableVO } from '@/api/tool/gen/types';
|
||||
import router from '@/router';
|
||||
import ImportTable from './importTable.vue';
|
||||
|
||||
|
@ -3,13 +3,13 @@
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="search">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="出差天数" prop="startBusinessTripDays">
|
||||
<!-- <el-form-item label="出差天数" prop="startBusinessTripDays">
|
||||
<el-input v-model="queryParams.startBusinessTripDays" placeholder="请输入出差天数" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="endBusinessTripDays"> 至 </el-form-item>
|
||||
<el-form-item prop="endBusinessTripDays">
|
||||
</el-form-item> -->
|
||||
<!-- <el-form-item prop="endBusinessTripDays"> 至 </el-form-item> -->
|
||||
<!-- <el-form-item prop="endBusinessTripDays">
|
||||
<el-input v-model="queryParams.endBusinessTripDays" placeholder="请输入出差天数" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-form-item> -->
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
|
@ -15,9 +15,9 @@
|
||||
</el-card>
|
||||
<el-card shadow="never" style="height: 78vh; overflow-y: auto">
|
||||
<el-form ref="businessTripFormRef" v-loading="loading" :disabled="routeParams.type === 'view'" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="业务类别" prop="tripType">
|
||||
<el-select v-model="form.tripType" placeholder="请选择业务类别" style="width: 100%">
|
||||
<el-option v-for="item in business_type" :key="item.value" :label="item.label" :value="item.value" />
|
||||
<el-form-item label="邮寄性质" prop="tripType">
|
||||
<el-select v-model="form.tripType" placeholder="请选择邮寄性质" style="width: 100%">
|
||||
<el-option v-for="item in opr_oa_exp_type" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="预算事项" prop="budgetType">
|
||||
@ -90,7 +90,7 @@ const loading = ref(true);
|
||||
const businessTripTime = ref<Array<string>>([]);
|
||||
//路由参数
|
||||
const routeParams = ref<Record<string, any>>({});
|
||||
const { business_type,opr_oa_trip_budget_type } = toRefs<any>(proxy?.useDict('business_type','opr_oa_trip_budget_type'));
|
||||
const { opr_oa_exp_type } = toRefs<any>(proxy?.useDict('opr_oa_exp_type'));
|
||||
// const options = [
|
||||
// {
|
||||
// value: '1',
|
||||
|
@ -31,10 +31,11 @@
|
||||
v-loading="loading"
|
||||
:data="categoryList"
|
||||
row-key="categoryId"
|
||||
border
|
||||
:default-expand-all="isExpandAll"
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
>
|
||||
<el-table-column label="分类名称" prop="categoryName" width="260"/>
|
||||
<el-table-column label="分类名称" prop="categoryName" width="260" />
|
||||
<el-table-column label="显示顺序" align="center" prop="orderNum" width="200" />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180" />
|
||||
<el-table-column label="操作" fixed="right" align="center" class-name="small-padding fixed-width">
|
||||
@ -77,7 +78,7 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
@ -88,17 +89,16 @@
|
||||
</template>
|
||||
|
||||
<script setup name="Category" lang="ts">
|
||||
import { listCategory, getCategory, delCategory, addCategory, updateCategory } from "@/api/workflow/category";
|
||||
import { listCategory, getCategory, delCategory, addCategory, updateCategory } from '@/api/workflow/category';
|
||||
import { CategoryVO, CategoryQuery, CategoryForm } from '@/api/workflow/category/types';
|
||||
|
||||
type CategoryOption = {
|
||||
categoryId: number;
|
||||
categoryName: string;
|
||||
children?: CategoryOption[];
|
||||
}
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;;
|
||||
};
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const categoryList = ref<CategoryVO[]>([]);
|
||||
const categoryOptions = ref<CategoryOption[]>([]);
|
||||
@ -109,32 +109,29 @@ const loading = ref(false);
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const categoryFormRef = ref<ElFormInstance>();
|
||||
const categoryTableRef = ref<ElTableInstance>()
|
||||
const categoryTableRef = ref<ElTableInstance>();
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
|
||||
const initFormData: CategoryForm = {
|
||||
categoryId: undefined,
|
||||
categoryName: "",
|
||||
categoryName: '',
|
||||
parentId: undefined,
|
||||
orderNum: 0,
|
||||
}
|
||||
orderNum: 0
|
||||
};
|
||||
|
||||
const data = reactive<PageData<CategoryForm, CategoryQuery>>({
|
||||
form: {...initFormData},
|
||||
form: { ...initFormData },
|
||||
queryParams: {
|
||||
categoryName: undefined,
|
||||
categoryName: undefined
|
||||
},
|
||||
rules: {
|
||||
categoryId: [
|
||||
{ required: true, message: "流程分类ID不能为空", trigger: "blur" }
|
||||
],
|
||||
parentId: [{ required: true, message: "请选择上级分类", trigger: "change" }],
|
||||
categoryName: [{ required: true, message: "请输入分类名称", trigger: "blur" }]
|
||||
categoryId: [{ required: true, message: '流程分类ID不能为空', trigger: 'blur' }],
|
||||
parentId: [{ required: true, message: '请选择上级分类', trigger: 'change' }],
|
||||
categoryName: [{ required: true, message: '请输入分类名称', trigger: 'blur' }]
|
||||
}
|
||||
});
|
||||
|
||||
@ -144,19 +141,19 @@ const { queryParams, form, rules } = toRefs(data);
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listCategory(queryParams.value);
|
||||
const data = proxy?.handleTree<CategoryVO>(res.data, "categoryId", "parentId");
|
||||
const data = proxy?.handleTree<CategoryVO>(res.data, 'categoryId', 'parentId');
|
||||
if (data) {
|
||||
categoryList.value = data;
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** 查询流程分类下拉树结构 */
|
||||
const getTreeselect = async () => {
|
||||
const res = await listCategory();
|
||||
categoryOptions.value = [];
|
||||
// 处理树形数据
|
||||
const data = proxy?.handleTree<CategoryOption>(res.data, "categoryId", "parentId");
|
||||
const data = proxy?.handleTree<CategoryOption>(res.data, 'categoryId', 'parentId');
|
||||
if (data) {
|
||||
categoryOptions.value = data; // 将处理后的树形数据赋值
|
||||
}
|
||||
@ -166,24 +163,24 @@ const getTreeselect = async () => {
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 表单重置
|
||||
const reset = () => {
|
||||
form.value = {...initFormData}
|
||||
form.value = { ...initFormData };
|
||||
categoryFormRef.value?.resetFields();
|
||||
}
|
||||
};
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
getList();
|
||||
}
|
||||
};
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
handleQuery();
|
||||
}
|
||||
};
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = (row?: CategoryVO) => {
|
||||
@ -195,22 +192,22 @@ const handleAdd = (row?: CategoryVO) => {
|
||||
form.value.parentId = undefined;
|
||||
}
|
||||
dialog.visible = true;
|
||||
dialog.title = "添加流程分类";
|
||||
}
|
||||
dialog.title = '添加流程分类';
|
||||
};
|
||||
|
||||
/** 展开/折叠操作 */
|
||||
const handleToggleExpandAll = () => {
|
||||
isExpandAll.value = !isExpandAll.value;
|
||||
toggleExpandAll(categoryList.value, isExpandAll.value)
|
||||
}
|
||||
toggleExpandAll(categoryList.value, isExpandAll.value);
|
||||
};
|
||||
|
||||
/** 展开/折叠操作 */
|
||||
const toggleExpandAll = (data: CategoryVO[], status: boolean) => {
|
||||
data.forEach((item) => {
|
||||
categoryTableRef.value?.toggleRowExpansion(item, status)
|
||||
if (item.children && item.children.length > 0) toggleExpandAll(item.children, status)
|
||||
})
|
||||
}
|
||||
categoryTableRef.value?.toggleRowExpansion(item, status);
|
||||
if (item.children && item.children.length > 0) toggleExpandAll(item.children, status);
|
||||
});
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row: CategoryVO) => {
|
||||
@ -222,8 +219,8 @@ const handleUpdate = async (row: CategoryVO) => {
|
||||
const res = await getCategory(row.categoryId);
|
||||
Object.assign(form.value, res.data);
|
||||
dialog.visible = true;
|
||||
dialog.title = "修改流程分类";
|
||||
}
|
||||
dialog.title = '修改流程分类';
|
||||
};
|
||||
|
||||
/** 提交按钮 */
|
||||
const submitForm = () => {
|
||||
@ -231,25 +228,25 @@ const submitForm = () => {
|
||||
if (valid) {
|
||||
buttonLoading.value = true;
|
||||
if (form.value.categoryId) {
|
||||
await updateCategory(form.value).finally(() => buttonLoading.value = false);
|
||||
await updateCategory(form.value).finally(() => (buttonLoading.value = false));
|
||||
} else {
|
||||
await addCategory(form.value).finally(() => buttonLoading.value = false);
|
||||
await addCategory(form.value).finally(() => (buttonLoading.value = false));
|
||||
}
|
||||
proxy?.$modal.msgSuccess("操作成功");
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
dialog.visible = false;
|
||||
getList();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row: CategoryVO) => {
|
||||
await proxy?.$modal.confirm('是否确认删除"' + row.categoryName + '"的分类?');
|
||||
loading.value = true;
|
||||
await delCategory(row.categoryId).finally(() => loading.value = false);
|
||||
await delCategory(row.categoryId).finally(() => (loading.value = false));
|
||||
await getList();
|
||||
proxy?.$modal.msgSuccess("删除成功");
|
||||
}
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
|
331
src/views/workflow/express/expressEdit.vue
Normal file
331
src/views/workflow/express/expressEdit.vue
Normal file
@ -0,0 +1,331 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<el-card shadow="never">
|
||||
<div style="display: flex; justify-content: space-between">
|
||||
<div>
|
||||
<el-button v-if="submitButtonShow" :loading="buttonLoading" type="info" @click="submitForm('draft')">暂存</el-button>
|
||||
<el-button v-if="submitButtonShow" :loading="buttonLoading" type="primary" @click="submitForm('submit')">提 交</el-button>
|
||||
<el-button v-if="approvalButtonShow" :loading="buttonLoading" type="primary" @click="approvalVerifyOpen">审批</el-button>
|
||||
<el-button v-if="form && form.id && form.status !== 'draft'" type="primary" @click="handleApprovalRecord">流程进度</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<el-button style="float: right" @click="goBack()">返回</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card shadow="never" style="height: 78vh; overflow-y: auto">
|
||||
<el-form ref="businessTripFormRef" v-loading="loading" :disabled="routeParams.type === 'view'" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="业务类别" prop="tripType">
|
||||
<el-select v-model="form.tripType" placeholder="请选择业务类别" style="width: 100%">
|
||||
<el-option v-for="item in business_type" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="预算事项" prop="budgetType">
|
||||
<el-select v-model="form.budgetType" placeholder="请选择预算事项" style="width: 100%">
|
||||
<el-option v-for="item in opr_oa_trip_budget_type" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="出差时间">
|
||||
<el-date-picker
|
||||
v-model="businessTripTime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
type="daterange"
|
||||
range-separator="To"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
:default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
|
||||
@change="changeBusinessTripTime()"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="出差天数" prop="tripDays">
|
||||
<el-input v-model="form.tripDays" disabled type="number" placeholder="请输入出差天数" />
|
||||
</el-form-item>
|
||||
<el-form-item label="差旅金额" prop="tripMoney">
|
||||
<el-input v-model="form.tripMoney" type="number" placeholder="请输入差旅金额" style="width: 200px;"/>元
|
||||
</el-form-item>
|
||||
<el-form-item label="在办项目" prop="currentProjects">
|
||||
<el-input v-model="form.currentProjects" type="textarea" :rows="3" placeholder="请输入在办项目" />
|
||||
</el-form-item>
|
||||
<el-form-item label="出差原因" prop="resaon">
|
||||
<el-input v-model="form.reason" type="textarea" :rows="3" placeholder="请输入出差原因" />
|
||||
</el-form-item>
|
||||
<el-form-item label="附件" prop="attachment">
|
||||
<imageUpload v-model="form.attachment" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" :rows="3" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<!-- 提交组件 -->
|
||||
<submitVerify ref="submitVerifyRef" :task-variables="taskVariables" @submit-callback="submitCallback" />
|
||||
<!-- 审批记录 -->
|
||||
<approvalRecord ref="approvalRecordRef" />
|
||||
<el-dialog v-model="dialogVisible.visible" :title="dialogVisible.title" :before-close="handleClose" width="500">
|
||||
<el-select v-model="flowCode" placeholder="Select" style="width: 240px">
|
||||
<el-option v-for="item in flowCodeOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" @click="submitFlow()"> 确认 </el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="Trip" lang="ts">
|
||||
import { addBusinessTrip, getBusinessTrip, updateBusinessTrip } from '@/api/workflow/businessTrip';
|
||||
import { BusinessTripForm, BusinessTripQuery, BusinessTripVO } from '@/api/workflow/businessTrip/types';
|
||||
import { startWorkFlow } from '@/api/workflow/task';
|
||||
import SubmitVerify from '@/components/Process/submitVerify.vue';
|
||||
import ApprovalRecord from '@/components/Process/approvalRecord.vue';
|
||||
import { AxiosResponse } from 'axios';
|
||||
import { StartProcessBo } from '@/api/workflow/workflowCommon/types';
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const buttonLoading = ref(false);
|
||||
const loading = ref(true);
|
||||
const businessTripTime = ref<Array<string>>([]);
|
||||
//路由参数
|
||||
const routeParams = ref<Record<string, any>>({});
|
||||
const { business_type,opr_oa_trip_budget_type } = toRefs<any>(proxy?.useDict('business_type','opr_oa_trip_budget_type'));
|
||||
// const options = [
|
||||
// {
|
||||
// value: '1',
|
||||
// label: '事假'
|
||||
// },
|
||||
// {
|
||||
// value: '2',
|
||||
// label: '调休'
|
||||
// },
|
||||
// {
|
||||
// value: '3',
|
||||
// label: '病假'
|
||||
// },
|
||||
// {
|
||||
// value: '4',
|
||||
// label: '婚假'
|
||||
// }
|
||||
// ];
|
||||
const flowCodeOptions = [
|
||||
{
|
||||
value: 'trip1',
|
||||
label: '出差申请-普通'
|
||||
}
|
||||
// ,
|
||||
// {
|
||||
// value: 'leave2',
|
||||
// label: '请假申请-排他网关'
|
||||
// },
|
||||
// {
|
||||
// value: 'leave3',
|
||||
// label: '请假申请-并行网关'
|
||||
// },
|
||||
// {
|
||||
// value: 'leave4',
|
||||
// label: '请假申请-会签'
|
||||
// },
|
||||
// {
|
||||
// value: 'leave5',
|
||||
// label: '请假申请-并行会签网关'
|
||||
// },
|
||||
// {
|
||||
// value: 'leave6',
|
||||
// label: '请假申请-排他并行会签'
|
||||
// }
|
||||
];
|
||||
|
||||
const flowCode = ref<string>('');
|
||||
|
||||
const dialogVisible = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: '流程定义'
|
||||
});
|
||||
//提交组件
|
||||
const submitVerifyRef = ref<InstanceType<typeof SubmitVerify>>();
|
||||
//审批记录组件
|
||||
const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>();
|
||||
|
||||
const businessTripFormRef = ref<ElFormInstance>();
|
||||
|
||||
const submitFormData = ref<StartProcessBo>({
|
||||
businessId: '',
|
||||
flowCode: '',
|
||||
variables: {}
|
||||
});
|
||||
const taskVariables = ref<Record<string, any>>({});
|
||||
|
||||
const initFormData: BusinessTripForm = {
|
||||
id: undefined,
|
||||
tripType: undefined,
|
||||
startDate: undefined,
|
||||
endDate: undefined,
|
||||
tripDays: undefined,
|
||||
remark: undefined,
|
||||
status: undefined
|
||||
};
|
||||
const data = reactive<PageData<BusinessTripForm, BusinessTripQuery>>({
|
||||
form: { ...initFormData },
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
startBusinessTripDays: undefined,
|
||||
endBusinessTripDays: undefined
|
||||
},
|
||||
rules: {
|
||||
id: [{ required: true, message: '主键不能为空', trigger: 'blur' }],
|
||||
tripType: [{ required: true, message: '业务类别不能为空', trigger: 'blur' }],
|
||||
tripTime: [{ required: true, message: '出差时间不能为空', trigger: 'blur' }],
|
||||
tripDays: [{ required: true, message: '出差天数不能为空', trigger: 'blur' }]
|
||||
}
|
||||
});
|
||||
|
||||
const handleClose = () => {
|
||||
dialogVisible.visible = false;
|
||||
flowCode.value = '';
|
||||
buttonLoading.value = false;
|
||||
};
|
||||
const { form, rules } = toRefs(data);
|
||||
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = { ...initFormData };
|
||||
businessTripTime.value = [];
|
||||
businessTripFormRef.value?.resetFields();
|
||||
};
|
||||
|
||||
const changeBusinessTripTime = () => {
|
||||
const startDate = new Date(businessTripTime.value[0]).getTime();
|
||||
const endDate = new Date(businessTripTime.value[1]).getTime();
|
||||
const diffInMilliseconds = endDate - startDate;
|
||||
form.value.tripDays = Math.floor(diffInMilliseconds / (1000 * 60 * 60 * 24)) + 1;
|
||||
};
|
||||
/** 获取详情 */
|
||||
const getInfo = () => {
|
||||
loading.value = true;
|
||||
buttonLoading.value = false;
|
||||
nextTick(async () => {
|
||||
const res = await getBusinessTrip(routeParams.value.id);
|
||||
Object.assign(form.value, res.data);
|
||||
businessTripTime.value = [];
|
||||
businessTripTime.value.push(form.value.startDate);
|
||||
businessTripTime.value.push(form.value.endDate);
|
||||
loading.value = false;
|
||||
buttonLoading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
/** 提交按钮 */
|
||||
const submitForm = (status: string) => {
|
||||
if (businessTripTime.value.length === 0) {
|
||||
proxy?.$modal.msgError('出差时间不能为空');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
businessTripFormRef.value?.validate(async (valid: boolean) => {
|
||||
form.value.startDate = businessTripTime.value[0];
|
||||
form.value.endDate = businessTripTime.value[1];
|
||||
if (valid) {
|
||||
buttonLoading.value = true;
|
||||
let res: AxiosResponse<BusinessTripVO>;
|
||||
if (form.value.id) {
|
||||
res = await updateBusinessTrip(form.value);
|
||||
} else {
|
||||
res = await addBusinessTrip(form.value);
|
||||
}
|
||||
form.value = res.data;
|
||||
if (status === 'draft') {
|
||||
buttonLoading.value = false;
|
||||
proxy?.$modal.msgSuccess('暂存成功');
|
||||
proxy.$tab.closePage(proxy.$route);
|
||||
proxy.$router.go(-1);
|
||||
} else {
|
||||
if ((form.value.status === 'draft' && (flowCode.value === '' || flowCode.value === null)) || routeParams.value.type === 'add') {
|
||||
flowCode.value = flowCodeOptions[0].value;
|
||||
dialogVisible.visible = true;
|
||||
return;
|
||||
}
|
||||
//说明启动过先随意穿个参数
|
||||
if (flowCode.value === '' || flowCode.value === null) {
|
||||
flowCode.value = 'xx';
|
||||
}
|
||||
await handleStartWorkFlow(res.data);
|
||||
}
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
buttonLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const submitFlow = async () => {
|
||||
handleStartWorkFlow(form.value);
|
||||
dialogVisible.visible = false;
|
||||
};
|
||||
//提交申请
|
||||
const handleStartWorkFlow = async (data: BusinessTripForm) => {
|
||||
try {
|
||||
submitFormData.value.flowCode = flowCode.value;
|
||||
submitFormData.value.businessId = data.id;
|
||||
//流程变量
|
||||
taskVariables.value = {
|
||||
businessTripDays: data.tripDays,
|
||||
userList: ['1', '3', '4']
|
||||
};
|
||||
submitFormData.value.variables = taskVariables.value;
|
||||
const resp = await startWorkFlow(submitFormData.value);
|
||||
if (submitVerifyRef.value) {
|
||||
buttonLoading.value = false;
|
||||
submitVerifyRef.value.openDialog(resp.data.taskId);
|
||||
}
|
||||
} finally {
|
||||
buttonLoading.value = false;
|
||||
}
|
||||
};
|
||||
//审批记录
|
||||
const handleApprovalRecord = () => {
|
||||
approvalRecordRef.value.init(form.value.id);
|
||||
};
|
||||
//提交回调
|
||||
const submitCallback = async () => {
|
||||
await proxy.$tab.closePage(proxy.$route);
|
||||
proxy.$router.go(-1);
|
||||
};
|
||||
|
||||
//返回
|
||||
const goBack = () => {
|
||||
proxy.$tab.closePage(proxy.$route);
|
||||
proxy.$router.go(-1);
|
||||
};
|
||||
//审批
|
||||
const approvalVerifyOpen = async () => {
|
||||
submitVerifyRef.value.openDialog(routeParams.value.taskId);
|
||||
};
|
||||
//校验提交按钮是否显示
|
||||
const submitButtonShow = computed(() => {
|
||||
return (
|
||||
routeParams.value.type === 'add' ||
|
||||
(routeParams.value.type === 'update' &&
|
||||
form.value.status &&
|
||||
(form.value.status === 'draft' || form.value.status === 'cancel' || form.value.status === 'back'))
|
||||
);
|
||||
});
|
||||
|
||||
//校验审批按钮是否显示
|
||||
const approvalButtonShow = computed(() => {
|
||||
return routeParams.value.type === 'approval' && form.value.status && form.value.status === 'waiting';
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
nextTick(async () => {
|
||||
routeParams.value = proxy.$route.query;
|
||||
reset();
|
||||
loading.value = false;
|
||||
if (routeParams.value.type === 'update' || routeParams.value.type === 'view' || routeParams.value.type === 'approval') {
|
||||
getInfo();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
238
src/views/workflow/express/index.vue
Normal file
238
src/views/workflow/express/index.vue
Normal file
@ -0,0 +1,238 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="search">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<!-- <el-form-item label="出差天数" prop="startBusinessTripDays">
|
||||
<el-input v-model="queryParams.startBusinessTripDays" placeholder="请输入出差天数" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item> -->
|
||||
<!-- <el-form-item prop="endBusinessTripDays"> 至 </el-form-item> -->
|
||||
<!-- <el-form-item prop="endBusinessTripDays">
|
||||
<el-input v-model="queryParams.endBusinessTripDays" placeholder="请输入出差天数" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item> -->
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['workflow:business:add']" type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['workflow:business:export']" type="warning" plain icon="Download" @click="handleExport">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:show-search="showSearch" @query-table="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" border :data="tripList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column v-if="false" label="主键" align="center" prop="id" />
|
||||
<el-table-column label="业务类别" align="center">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="business_type" :value="scope.row.tripType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="开始时间" align="center" prop="startDate">
|
||||
<template #default="scope">
|
||||
<span>{{ proxy.parseTime(scope.row.startDate, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="结束时间" align="center" prop="endDate">
|
||||
<template #default="scope">
|
||||
<span>{{ proxy.parseTime(scope.row.endDate, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="出差天数" align="center" prop="tripDays" />
|
||||
<el-table-column label="出差原因" align="center" prop="reason" />
|
||||
<el-table-column label="备注" align="center" prop="remark" />
|
||||
<el-table-column align="center" label="流程状态" min-width="70">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="wf_business_status" :value="scope.row.status"></dict-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="162">
|
||||
<template #default="scope">
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5" v-if="scope.row.status === 'draft' || scope.row.status === 'cancel' || scope.row.status === 'back'">
|
||||
<el-button v-hasPermi="['workflow:business:edit']" size="small" type="primary" icon="Edit" @click="handleUpdate(scope.row)"
|
||||
>修改</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5" v-if="scope.row.status === 'draft' || scope.row.status === 'cancel' || scope.row.status === 'back'">
|
||||
<el-button v-hasPermi="['workflow:business:remove']" size="small" type="primary" icon="Delete" @click="handleDelete(scope.row)"
|
||||
>删除</el-button
|
||||
>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" size="small" icon="View" @click="handleView(scope.row)">查看</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5" v-if="scope.row.status === 'waiting'">
|
||||
<el-button size="small" type="primary" icon="Notification" @click="handleCancelProcessApply(scope.row.id)">撤销</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" :total="total" @pagination="getList" />
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="express" lang="ts">
|
||||
import { delBusinessTrip, listBusinessTrip } from '@/api/workflow/businessTrip';
|
||||
import { cancelProcessApply } from '@/api/workflow/instance';
|
||||
import { BusinessTripForm, BusinessTripQuery, BusinessTripVO } from '@/api/workflow/businessTrip/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { wf_business_status } = toRefs<any>(proxy?.useDict('wf_business_status'));
|
||||
const tripList = ref<BusinessTripVO[]>([]);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<string | number>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const { business_type } = toRefs<any>(proxy?.useDict('business_type'));
|
||||
// const options = [
|
||||
// {
|
||||
// value: '1',
|
||||
// label: '事假'
|
||||
// },
|
||||
// {
|
||||
// value: '2',
|
||||
// label: '调休'
|
||||
// },
|
||||
// {
|
||||
// value: '3',
|
||||
// label: '病假'
|
||||
// },
|
||||
// {
|
||||
// value: '4',
|
||||
// label: '婚假'
|
||||
// }
|
||||
// ];
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
|
||||
const data = reactive<PageData<BusinessTripForm, BusinessTripQuery>>({
|
||||
form: {},
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
startBusinessTripDays: undefined,
|
||||
endBusinessTripDays: undefined
|
||||
},
|
||||
rules: {}
|
||||
});
|
||||
|
||||
const { queryParams } = toRefs(data);
|
||||
|
||||
/** 查询出差列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listBusinessTrip(queryParams.value);
|
||||
tripList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: BusinessTripVO[]) => {
|
||||
ids.value = selection.map((item) => item.id);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
};
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
proxy.$tab.closePage(proxy.$route);
|
||||
proxy.$router.push({
|
||||
path: `/workflow/tripEdit/index`,
|
||||
query: {
|
||||
type: 'add'
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = (row?: BusinessTripVO) => {
|
||||
proxy.$tab.closePage(proxy.$route);
|
||||
proxy.$router.push({
|
||||
path: `/workflow/tripEdit/index`,
|
||||
query: {
|
||||
id: row.id,
|
||||
type: 'update'
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/** 查看按钮操作 */
|
||||
const handleView = (row?: BusinessTripVO) => {
|
||||
proxy.$tab.closePage(proxy.$route);
|
||||
proxy.$router.push({
|
||||
path: `/workflow/tripEdit/index`,
|
||||
query: {
|
||||
id: row.id,
|
||||
type: 'view'
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: BusinessTripVO) => {
|
||||
const _ids = row?.id || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除出差编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
|
||||
await delBusinessTrip(_ids);
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
await getList();
|
||||
};
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download(
|
||||
'workflow/businessTrip/export',
|
||||
{
|
||||
...queryParams.value
|
||||
},
|
||||
`businessTrip_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
};
|
||||
|
||||
/** 撤销按钮操作 */
|
||||
const handleCancelProcessApply = async (id: string) => {
|
||||
await proxy?.$modal.confirm('是否确认撤销当前单据?');
|
||||
loading.value = true;
|
||||
let data = {
|
||||
businessId: id,
|
||||
message: '申请人撤销流程!'
|
||||
};
|
||||
await cancelProcessApply(data).finally(() => (loading.value = false));
|
||||
await getList();
|
||||
proxy?.$modal.msgSuccess('撤销成功');
|
||||
};
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
</script>
|
@ -34,10 +34,10 @@
|
||||
<el-table v-loading="loading" border :data="leaveList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column v-if="false" label="主键" align="center" prop="id" />
|
||||
<el-table-column label="请假类型" align="center" prop="leaveType">
|
||||
<el-table-column label="请假类型" align="center">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="opr_oa_leave_type" :value="scope.row.leaveType" />
|
||||
</template>
|
||||
<dict-tag :options="opr_oa_leave_type" :value="scope.row.leaveType"></dict-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="开始时间" align="center" prop="startDate">
|
||||
<template #default="scope">
|
||||
@ -50,10 +50,7 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="请假天数" align="center" prop="leaveDays" />
|
||||
<el-table-column label="请假原因" align="center" prop="reason" />
|
||||
<el-table-column label="在办项目" align="center" prop="currentProjects" />
|
||||
<!-- <el-table-column label="附件" align="center" prop="attachment" /> -->
|
||||
<el-table-column label="备注" align="center" prop="remark" />
|
||||
<el-table-column label="请假原因" align="center" prop="remark" />
|
||||
<el-table-column align="center" label="流程状态" min-width="70">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="wf_business_status" :value="scope.row.status"></dict-tag>
|
||||
@ -96,7 +93,7 @@ import { cancelProcessApply } from '@/api/workflow/instance';
|
||||
import { LeaveForm, LeaveQuery, LeaveVO } from '@/api/workflow/leave/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { wf_business_status } = toRefs<any>(proxy?.useDict('wf_business_status'));
|
||||
const { wf_business_status,opr_oa_leave_type } = toRefs<any>(proxy?.useDict('wf_business_status','opr_oa_leave_type'));
|
||||
const leaveList = ref<LeaveVO[]>([]);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
@ -104,27 +101,27 @@ const ids = ref<Array<string | number>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
// const options = [
|
||||
// {
|
||||
// value: '1',
|
||||
// label: '事假'
|
||||
// },
|
||||
// {
|
||||
// value: '2',
|
||||
// label: '调休'
|
||||
// },
|
||||
// {
|
||||
// value: '3',
|
||||
// label: '病假'
|
||||
// },
|
||||
// {
|
||||
// value: '4',
|
||||
// label: '婚假'
|
||||
// }
|
||||
// ];
|
||||
const options = [
|
||||
{
|
||||
value: '1',
|
||||
label: '事假'
|
||||
},
|
||||
{
|
||||
value: '2',
|
||||
label: '调休'
|
||||
},
|
||||
{
|
||||
value: '3',
|
||||
label: '病假'
|
||||
},
|
||||
{
|
||||
value: '4',
|
||||
label: '婚假'
|
||||
}
|
||||
];
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const { opr_oa_leave_type } = toRefs<any>(proxy?.useDict('opr_oa_leave_type'));
|
||||
|
||||
const data = reactive<PageData<LeaveForm, LeaveQuery>>({
|
||||
form: {},
|
||||
queryParams: {
|
||||
@ -225,7 +222,7 @@ const handleExport = () => {
|
||||
const handleCancelProcessApply = async (id: string) => {
|
||||
await proxy?.$modal.confirm('是否确认撤销当前单据?');
|
||||
loading.value = true;
|
||||
let data = {
|
||||
const data = {
|
||||
businessId: id,
|
||||
message: '申请人撤销流程!'
|
||||
};
|
||||
|
@ -1,17 +1,15 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<el-card shadow="never">
|
||||
<div style="display: flex; justify-content: space-between">
|
||||
<div>
|
||||
<el-button v-if="submitButtonShow" :loading="buttonLoading" type="info" @click="submitForm('draft')">暂存</el-button>
|
||||
<el-button v-if="submitButtonShow" :loading="buttonLoading" type="primary" @click="submitForm('submit')">提 交</el-button>
|
||||
<el-button v-if="approvalButtonShow" :loading="buttonLoading" type="primary" @click="approvalVerifyOpen">审批</el-button>
|
||||
<el-button v-if="form && form.id && form.status !== 'draft'" type="primary" @click="handleApprovalRecord">流程进度</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<el-button style="float: right" @click="goBack()">返回</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<approvalButton
|
||||
@submitForm="submitForm"
|
||||
@approvalVerifyOpen="approvalVerifyOpen"
|
||||
@handleApprovalRecord="handleApprovalRecord"
|
||||
:buttonLoading="buttonLoading"
|
||||
:id="form.id"
|
||||
:status="form.status"
|
||||
:pageType="routeParams.type"
|
||||
/>
|
||||
</el-card>
|
||||
<el-card shadow="never" style="height: 78vh; overflow-y: auto">
|
||||
<el-form ref="leaveFormRef" v-loading="loading" :disabled="routeParams.type === 'view'" :model="form" :rules="rules" label-width="80px">
|
||||
@ -73,6 +71,7 @@ import { LeaveForm, LeaveQuery, LeaveVO } from '@/api/workflow/leave/types';
|
||||
import { startWorkFlow } from '@/api/workflow/task';
|
||||
import SubmitVerify from '@/components/Process/submitVerify.vue';
|
||||
import ApprovalRecord from '@/components/Process/approvalRecord.vue';
|
||||
import ApprovalButton from '@/components/Process/approvalButton.vue';
|
||||
import { AxiosResponse } from 'axios';
|
||||
import { StartProcessBo } from '@/api/workflow/workflowCommon/types';
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
@ -82,7 +81,7 @@ const loading = ref(true);
|
||||
const leaveTime = ref<Array<string>>([]);
|
||||
//路由参数
|
||||
const routeParams = ref<Record<string, any>>({});
|
||||
const { opr_oa_leave_type } = toRefs<any>(proxy?.useDict('opr_oa_leave_type'));
|
||||
const { opr_oa_leave_type } = toRefs<any>(proxy?.useDict('opr_oa_leave_type'));
|
||||
// const options = [
|
||||
// {
|
||||
// value: '1',
|
||||
@ -139,6 +138,8 @@ const dialogVisible = reactive<DialogOption>({
|
||||
const submitVerifyRef = ref<InstanceType<typeof SubmitVerify>>();
|
||||
//审批记录组件
|
||||
const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>();
|
||||
//按钮组件
|
||||
const approvalButtonRef = ref<InstanceType<typeof ApprovalButton>>();
|
||||
|
||||
const leaveFormRef = ref<ElFormInstance>();
|
||||
|
||||
@ -223,9 +224,9 @@ const submitForm = (status: string) => {
|
||||
buttonLoading.value = true;
|
||||
let res: AxiosResponse<LeaveVO>;
|
||||
if (form.value.id) {
|
||||
res = await updateLeave(form.value);
|
||||
res = await updateLeave(form.value).finally(() => (buttonLoading.value = false));
|
||||
} else {
|
||||
res = await addLeave(form.value);
|
||||
res = await addLeave(form.value).finally(() => (buttonLoading.value = false));
|
||||
}
|
||||
form.value = res.data;
|
||||
if (status === 'draft') {
|
||||
@ -263,7 +264,9 @@ const handleStartWorkFlow = async (data: LeaveForm) => {
|
||||
submitFormData.value.businessId = data.id;
|
||||
//流程变量
|
||||
taskVariables.value = {
|
||||
// leave2/6 使用的流程变量
|
||||
leaveDays: data.leaveDays,
|
||||
// leave4/5 使用的流程变量
|
||||
userList: ['1', '3', '4']
|
||||
};
|
||||
submitFormData.value.variables = taskVariables.value;
|
||||
@ -285,30 +288,10 @@ const submitCallback = async () => {
|
||||
await proxy.$tab.closePage(proxy.$route);
|
||||
proxy.$router.go(-1);
|
||||
};
|
||||
|
||||
//返回
|
||||
const goBack = () => {
|
||||
proxy.$tab.closePage(proxy.$route);
|
||||
proxy.$router.go(-1);
|
||||
};
|
||||
//审批
|
||||
const approvalVerifyOpen = async () => {
|
||||
submitVerifyRef.value.openDialog(routeParams.value.taskId);
|
||||
};
|
||||
//校验提交按钮是否显示
|
||||
const submitButtonShow = computed(() => {
|
||||
return (
|
||||
routeParams.value.type === 'add' ||
|
||||
(routeParams.value.type === 'update' &&
|
||||
form.value.status &&
|
||||
(form.value.status === 'draft' || form.value.status === 'cancel' || form.value.status === 'back'))
|
||||
);
|
||||
});
|
||||
|
||||
//校验审批按钮是否显示
|
||||
const approvalButtonShow = computed(() => {
|
||||
return routeParams.value.type === 'approval' && form.value.status && form.value.status === 'waiting';
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
nextTick(async () => {
|
||||
|
@ -4,7 +4,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="WarmFlow">
|
||||
<script setup name="WarmFlow" lang="ts">
|
||||
const { proxy } = getCurrentInstance();
|
||||
import { onMounted } from 'vue';
|
||||
import { getToken } from '@/utils/auth';
|
||||
@ -24,12 +24,12 @@ const iframeLoaded = () => {
|
||||
};
|
||||
};
|
||||
const open = async (definitionId, disabled) => {
|
||||
let url = baseUrl + `/warm-flow-ui/index.html?id=${definitionId}&disabled=${disabled}`;
|
||||
const url = baseUrl + `/warm-flow-ui/index.html?id=${definitionId}&disabled=${disabled}`;
|
||||
iframeUrl.value = url + '&Authorization=Bearer ' + getToken() + '&clientid=' + import.meta.env.VITE_APP_CLIENT_ID;
|
||||
};
|
||||
/** 关闭按钮 */
|
||||
function close() {
|
||||
const obj = { path: '/workflow/processDefinition', query: {activeName: proxy.$route.query.activeName}};
|
||||
const obj = { path: '/workflow/processDefinition', query: { activeName: proxy.$route.query.activeName } };
|
||||
proxy.$tab.closeOpenPage(obj);
|
||||
}
|
||||
|
||||
|
@ -197,7 +197,7 @@ import { categoryTree } from '@/api/workflow/category';
|
||||
import { CategoryTreeVO } from '@/api/workflow/category/types';
|
||||
import { FlowDefinitionQuery, FlowDefinitionVo, FlowDefinitionForm } from '@/api/workflow/definition/types';
|
||||
import { UploadRequestOptions, TabsPaneContext } from 'element-plus';
|
||||
import { ElMessageBoxOptions } from "element-plus/es/components/message-box/src/message-box.type";
|
||||
import { ElMessageBoxOptions } from 'element-plus/es/components/message-box/src/message-box.type';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
@ -326,7 +326,7 @@ const handleSelectionChange = (selection: any) => {
|
||||
};
|
||||
//分页
|
||||
const getPageList = async () => {
|
||||
let query = proxy.$route.query;
|
||||
const query = proxy.$route.query;
|
||||
if (query.activeName) {
|
||||
activeName.value = query.activeName;
|
||||
}
|
||||
@ -411,7 +411,7 @@ const handlerBeforeUpload = () => {
|
||||
};
|
||||
//部署文件
|
||||
const handlerImportDefinition = (data: UploadRequestOptions): XMLHttpRequest => {
|
||||
let formData = new FormData();
|
||||
const formData = new FormData();
|
||||
uploadDialogLoading.value = true;
|
||||
formData.append('file', data.file);
|
||||
formData.append('category', selectCategory.value);
|
||||
@ -466,6 +466,9 @@ const reset = () => {
|
||||
*/
|
||||
const handleAdd = async () => {
|
||||
reset();
|
||||
if (queryParams.value.category != '') {
|
||||
form.value.category = queryParams.value.category;
|
||||
}
|
||||
modelDialog.visible = true;
|
||||
modelDialog.title = '新增流程';
|
||||
};
|
||||
|
@ -352,7 +352,7 @@ const handleInvalid = async (row: FlowInstanceVO) => {
|
||||
await proxy?.$modal.confirm('是否确认作废?');
|
||||
loading.value = true;
|
||||
if ('running' === tab.value) {
|
||||
let param = {
|
||||
const param = {
|
||||
id: row.id,
|
||||
comment: deleteReason.value
|
||||
};
|
||||
@ -381,7 +381,7 @@ const handleInstanceVariable = async (row: FlowInstanceVO) => {
|
||||
variableLoading.value = true;
|
||||
variableVisible.value = true;
|
||||
processDefinitionName.value = row.flowName;
|
||||
let data = await instanceVariable(row.id);
|
||||
const data = await instanceVariable(row.id);
|
||||
variables.value = data.data.variable;
|
||||
variableLoading.value = false;
|
||||
};
|
||||
|
@ -227,7 +227,8 @@ const handleView = (row) => {
|
||||
taskId: row.id,
|
||||
type: 'view',
|
||||
formCustom: row.formCustom,
|
||||
formPath: row.formPath
|
||||
formPath: row.formPath,
|
||||
instanceId: row.instanceId
|
||||
});
|
||||
workflowCommon.routerJump(routerJumpVo, proxy);
|
||||
};
|
||||
|
@ -222,7 +222,7 @@ const handleCancelProcessApply = async (businessId: string) => {
|
||||
await proxy?.$modal.confirm('是否确认撤销当前单据?');
|
||||
loading.value = true;
|
||||
if ('running' === tab.value) {
|
||||
let data = {
|
||||
const data = {
|
||||
businessId: businessId,
|
||||
message: '申请人撤销流程!'
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user