Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c144439e5b | ||
|
|
42f5223941 | ||
|
|
1b2c7ceb90 | ||
|
|
8855b77770 | ||
|
|
f3b28f43f1 | ||
|
|
732b1741c1 | ||
|
|
1e161d2e64 | ||
|
|
59281a7126 | ||
|
|
51cffa4e03 | ||
|
|
e985b2507a | ||
|
|
aa37021a68 | ||
|
|
c56eeccaef | ||
|
|
d8851721b8 | ||
|
|
472da9274e | ||
|
|
6f724d9d52 | ||
|
|
6791de9d7c | ||
|
|
241e27137c | ||
|
|
eeda821b74 | ||
|
|
3ba5cb460c | ||
|
|
a8c1fd4473 | ||
|
|
e50cd2231c | ||
|
|
40c2cb72ff | ||
|
|
6cf3de0166 | ||
|
|
2f4599f664 | ||
|
|
7c7fbba2a3 | ||
|
|
36157a8f24 | ||
|
|
a82862be47 | ||
|
|
f86bd0df0b | ||
|
|
53841a598f | ||
|
|
ab11818ce2 | ||
|
|
5a0bcfe6b5 | ||
|
|
ecfe1b6145 | ||
|
|
1df1850ef9 | ||
|
|
ea97abc0af | ||
|
|
0ae9acdfd6 | ||
|
|
25484a941b | ||
|
|
169e3600d9 | ||
|
|
b5aa9d24ac | ||
|
|
413721bdfd | ||
|
|
a6461da0f8 | ||
|
|
6e6754e44a | ||
|
|
e891a4bfd2 | ||
|
|
5e386336b9 | ||
|
|
f87b37eaac | ||
|
|
c083a0c986 | ||
|
|
9685fbf822 | ||
|
|
746aeaff35 | ||
|
|
21c28c3665 | ||
|
|
9f0f5b0e6c | ||
|
|
0ab7f2342c | ||
|
|
a389392c8e | ||
|
|
5d31881f48 | ||
|
|
3e826776f4 | ||
|
|
4c5c6ff5c3 | ||
|
|
d76df547ae | ||
|
|
bfb9e2e77f | ||
|
|
fe2ac97f9d | ||
|
|
4bd020857f | ||
|
|
a9c924a421 | ||
|
|
b09ff417c3 | ||
|
|
6b397104fc | ||
|
|
9e2958f7d0 | ||
|
|
dc8f5cf977 | ||
|
|
9459a7296f | ||
|
|
8c52c6867f | ||
|
|
46985c6e1b | ||
|
|
7697054918 | ||
|
|
acb00ba866 | ||
|
|
cff65aa901 | ||
|
|
a6de16a02d | ||
|
|
0b6af855ac | ||
|
|
5785d741bb | ||
|
|
e52049876e | ||
|
|
7474c6b83b | ||
|
|
1f19b567c2 | ||
|
|
2efd0d69d9 | ||
|
|
ee46a31a81 | ||
|
|
4835316fca | ||
|
|
9bdafb0f6f | ||
|
|
740de45a82 | ||
|
|
7917bca9fd | ||
|
|
2835c9d111 | ||
|
|
f7477c3264 | ||
|
|
9c2b13f2d0 | ||
|
|
e8315e2864 | ||
|
|
c2f51b3c12 | ||
|
|
c00e6988a5 | ||
|
|
8ea43f30af | ||
|
|
abdaf2e0ca | ||
|
|
eb6f3a3e49 | ||
|
|
175d6ba0cb | ||
|
|
f0c797deac | ||
|
|
6e077ac7d9 | ||
|
|
557bc29d24 | ||
|
|
5063db47f3 | ||
|
|
8e4d91f43e | ||
|
|
97b1ac6ad3 | ||
|
|
be33226178 | ||
|
|
1a95687f61 | ||
|
|
f2f9391328 | ||
|
|
2de62667dc | ||
|
|
c79f027d62 | ||
|
|
4754685d84 | ||
|
|
1597891244 | ||
|
|
b108b07a96 | ||
|
|
7ee8cb89a8 | ||
|
|
c665fad8bc | ||
|
|
019bd9533e | ||
|
|
8ff9443f28 | ||
|
|
e591aa8867 | ||
|
|
9da5beb879 | ||
|
|
e3a39b7732 | ||
|
|
e0e287c88b | ||
|
|
d0ae37da4e | ||
|
|
d017ab55db | ||
|
|
e0bc260fc1 | ||
|
|
70c3a09f76 | ||
|
|
f93919b750 | ||
|
|
3c7526de2f | ||
|
|
886f3391aa | ||
|
|
22e9eb2add | ||
|
|
6dc5f5dcb5 | ||
|
|
455c192a9a | ||
|
|
9f8f790ec9 | ||
|
|
7c391a315e | ||
|
|
9d8e06a54b | ||
|
|
929b67b9ab | ||
|
|
690243dc4f | ||
|
|
a4dd4773ca | ||
|
|
6eb013b2a6 | ||
|
|
6dee7415cb | ||
|
|
513ea33f3f | ||
|
|
41f8f0cc9a | ||
|
|
6041a6eb31 | ||
|
|
ad0d4803e2 | ||
|
|
e587d68fef | ||
|
|
8e5a4d09d2 | ||
|
|
101c704a8f | ||
|
|
154dd6c40b | ||
|
|
d228df5210 | ||
|
|
5cdc15387c | ||
|
|
64e2ddfa18 | ||
|
|
90c71804e2 | ||
|
|
f125df7dd2 | ||
|
|
22199c64fd | ||
|
|
4ffaa2dc6e | ||
|
|
7b4b5ebbd1 | ||
|
|
16aef13573 | ||
|
|
bcc75bdd14 | ||
|
|
4423c5f84a | ||
|
|
4b0d3ec29c | ||
|
|
97a68ce4ba | ||
|
|
068b32d0d4 | ||
|
|
00a19cfc78 | ||
|
|
1d4339fac8 | ||
|
|
295a43d516 | ||
|
|
41b8407841 | ||
|
|
f1e161279c | ||
|
|
8f7a75bf3b | ||
|
|
29a0c691a0 | ||
|
|
47f1f13ca2 | ||
|
|
24e1374993 | ||
|
|
3a9f8db3fa | ||
|
|
397c09a195 | ||
|
|
738289bc06 | ||
|
|
f8b0cd53e5 | ||
|
|
7895d184e8 | ||
|
|
fc5df39b1a | ||
|
|
a07f61a9ed | ||
|
|
2cc9652d4b | ||
|
|
a283dc8cba | ||
|
|
b5d99e2c75 | ||
|
|
39f183bb3e | ||
|
|
2d1b31a841 | ||
|
|
4d2c038972 | ||
|
|
138d535e87 | ||
|
|
522e358eaf | ||
|
|
056684e291 | ||
|
|
12bd71e70b | ||
|
|
158708c1b1 | ||
|
|
6cd6429102 | ||
|
|
7b8e4ea238 | ||
|
|
c34bfc18bc | ||
|
|
caa31a67fe | ||
|
|
5f2e23f4da | ||
|
|
6304a8e9b6 | ||
|
|
3783582b33 | ||
|
|
ba2cdcc310 | ||
|
|
c119e910d0 | ||
|
|
2fe28af05d | ||
|
|
756addd423 | ||
|
|
eefabf34a5 | ||
|
|
0924f50266 | ||
|
|
67769c299e | ||
|
|
6ac0ee5844 | ||
|
|
da0a780163 | ||
|
|
046e6ce5a7 | ||
|
|
2719541462 | ||
|
|
0db0b66051 | ||
|
|
735837f0f9 | ||
|
|
2bca7bb44a | ||
|
|
d03fdecc26 | ||
|
|
e451f483c5 | ||
|
|
5eb415437d | ||
|
|
2c8125e218 | ||
|
|
3b49f7dec9 | ||
|
|
18c7693ed6 | ||
|
|
5e7afae972 | ||
|
|
b9e1529623 | ||
|
|
649c24ed51 | ||
|
|
fdee8d8628 | ||
|
|
33a4100ed4 | ||
|
|
52a8c46a0a | ||
|
|
8f32dce2d6 | ||
|
|
81d2a38363 | ||
|
|
4ba5dad22e | ||
|
|
91b1ecd3bb | ||
|
|
8b0778ca0c | ||
|
|
e4b57bd8c0 | ||
|
|
1c23298d19 | ||
|
|
2aa2b4609f | ||
|
|
7d29c6319f | ||
|
|
df34f65df8 | ||
|
|
e342e91f79 | ||
|
|
066607ab08 | ||
|
|
d052356ff0 | ||
|
|
1e6762ea69 | ||
|
|
0fae9a4ba4 | ||
|
|
5814826fa8 | ||
|
|
32d0093488 | ||
|
|
6dd6f9c2a5 | ||
|
|
8df5991940 | ||
|
|
8b5740d05c | ||
|
|
92314ee945 | ||
|
|
0fbd98291e | ||
|
|
31cef4f3bc | ||
|
|
8a97a33a29 | ||
|
|
cd69659c93 | ||
|
|
1c3be2b92a | ||
|
|
078407fa10 | ||
|
|
1e39af84d3 | ||
|
|
6f5cc3248f | ||
|
|
d3f3044655 | ||
|
|
70abc5fc17 | ||
|
|
ce3380fa3f | ||
|
|
40d7f5786d | ||
|
|
34fe09e2db | ||
|
|
55da358336 | ||
|
|
65f0b2f8ab | ||
|
|
13272c2293 | ||
|
|
21fc3fd7e6 | ||
|
|
71de0c3ecf | ||
|
|
c3cf479f6f | ||
|
|
77062cb391 | ||
|
|
1bb6a23ff8 | ||
|
|
fec7af453f | ||
|
|
2df0aa20ff | ||
|
|
98e9ba49ae | ||
|
|
5121d5694d | ||
|
|
bf87c46d0f | ||
|
|
c52a7e5012 | ||
|
|
12f52b288b | ||
|
|
3202378b04 | ||
|
|
a097560f81 | ||
|
|
e504be7d42 | ||
|
|
812e5b5865 | ||
|
|
8465f8fada | ||
|
|
7044bcee60 | ||
|
|
0284893b4a | ||
|
|
a57840c804 | ||
|
|
9b290ae3ce | ||
|
|
c9b12c8b39 | ||
|
|
67430a83fb | ||
|
|
c1109e90c4 | ||
|
|
a43bca5785 | ||
|
|
137b33e7cf | ||
|
|
458242a27b | ||
|
|
cf200b2618 | ||
|
|
c1924d566f | ||
|
|
b4139676f3 | ||
|
|
92f4160fe1 | ||
|
|
c1a2228022 | ||
|
|
71a2fddb1b | ||
|
|
8bdf60c886 | ||
|
|
38360eef12 | ||
|
|
d599134de6 | ||
|
|
dca54d0760 | ||
|
|
bd4ac52a2d | ||
|
|
17225ef3df | ||
|
|
d477b35f83 | ||
|
|
a6f325b14d | ||
|
|
57ab876886 | ||
|
|
8a8ae557f7 | ||
|
|
c7ecb0a69f | ||
|
|
a401d8ede4 | ||
|
|
de073e82bc | ||
|
|
dfa9cd5a3c | ||
|
|
3859a48825 | ||
|
|
0a4a9e0e55 | ||
|
|
30052b05f5 | ||
|
|
520fc784bc | ||
|
|
cd9cefa2c8 | ||
|
|
ffc09e8e35 | ||
|
|
aa6610e36c | ||
|
|
43b7dff0d0 | ||
|
|
dcdce4120d | ||
|
|
410c3bc9a7 | ||
|
|
d6e89db05c | ||
|
|
1f34aa8dee | ||
|
|
5116b94873 | ||
|
|
5267fe459f | ||
|
|
498244020d | ||
|
|
0f8522e306 | ||
|
|
f47e8f3a25 | ||
|
|
d818e338e3 | ||
|
|
fb2ea334b9 | ||
|
|
ac13524515 | ||
|
|
c7bd9f7138 | ||
|
|
4bc79c382b | ||
|
|
3a9197dfdf | ||
|
|
a31bafbb4a | ||
|
|
708e12b6ce | ||
|
|
91ea4b7936 | ||
|
|
2db1f726c3 | ||
|
|
57820cb3e1 | ||
|
|
10e432243e | ||
|
|
a033706fb4 | ||
|
|
ea02192b64 | ||
|
|
1d01955b8b | ||
|
|
13706de227 | ||
|
|
b056db55b2 | ||
|
|
842fe09e8b | ||
|
|
5ef5ee6e14 | ||
|
|
d10a3af3d1 | ||
|
|
6a9f5cc10f | ||
|
|
dcf1ad6b38 | ||
|
|
ca9a389ae8 | ||
|
|
2aefcd9070 | ||
|
|
dad97e2f17 | ||
|
|
22e425208c | ||
|
|
77e8827f8b | ||
|
|
6b06f320b9 | ||
|
|
33f3bc0567 | ||
|
|
4342c3ee05 | ||
|
|
c828517c55 | ||
|
|
2ff9904f63 | ||
|
|
fe21db3704 | ||
|
|
abcecc92c5 | ||
|
|
9dc268efb4 | ||
|
|
c49e8bd3f9 | ||
|
|
a4a4dcdfc2 | ||
|
|
9ec660817c | ||
|
|
b293f15779 | ||
|
|
c6b6d2f404 | ||
|
|
a69dc3a187 | ||
|
|
753a32aecc | ||
|
|
019104f460 | ||
|
|
4b2785bd41 | ||
|
|
7b1b9084c7 | ||
|
|
4105636741 | ||
|
|
d136128650 | ||
|
|
1d9532ca5a | ||
|
|
b94235adf3 | ||
|
|
619491b4d0 | ||
|
|
dd4c4817e4 | ||
|
|
926eb70fe5 | ||
|
|
dc0e947334 | ||
|
|
28f768f3b2 | ||
|
|
145eabbf42 | ||
|
|
2d245d1fe7 | ||
|
|
86c33e1f68 | ||
|
|
2d16816f3f | ||
|
|
27d24cd02d | ||
|
|
40512afb49 | ||
|
|
53d1cb8fff | ||
|
|
6d641177b8 | ||
|
|
9394a7cd60 | ||
|
|
f84c10cdea | ||
|
|
79c3ba090f | ||
|
|
4b2800f723 | ||
|
|
887936ccf0 | ||
|
|
81a710c02d | ||
|
|
4a2eddbd3b | ||
|
|
3f6e3c4168 | ||
|
|
f36b01575f | ||
|
|
95bb19dc0b | ||
|
|
fd907ddf3b | ||
|
|
d9f4336717 | ||
|
|
a132f07d04 | ||
|
|
1f8e419f78 | ||
|
|
4204c31442 | ||
|
|
cf4ed96f28 | ||
|
|
db98b376ff | ||
|
|
7a6c69495d | ||
|
|
989e30810a | ||
|
|
0e3ebbd2b8 | ||
|
|
26b025aca0 | ||
|
|
74e04279c2 | ||
|
|
6aaf611291 | ||
|
|
96593dac52 | ||
|
|
da45ee034c | ||
|
|
4872f18dc6 | ||
|
|
a45c8e6d2d | ||
|
|
360cce10c7 | ||
|
|
93a0789e34 | ||
|
|
63a0e5dc3d | ||
|
|
4680a7dcfd | ||
|
|
b69a784e86 | ||
|
|
4a2a7b760a | ||
|
|
0db57da901 | ||
|
|
8f231bc296 | ||
|
|
859f25fee3 | ||
|
|
fe33517ef0 | ||
|
|
f7217a5c83 | ||
|
|
1a8c04d763 | ||
|
|
8dafe26b2b | ||
|
|
f069f809c2 | ||
|
|
8a225e66b7 | ||
|
|
f086b9c32b | ||
|
|
fc0de84d78 | ||
|
|
c697824b09 | ||
|
|
456f3d210a | ||
|
|
4d25dda7fd | ||
|
|
370851ac37 | ||
|
|
fbed29100f | ||
|
|
870a1c44e8 | ||
|
|
d8fb70628d | ||
|
|
48e78c38c8 | ||
|
|
0974ece199 | ||
|
|
9d0e77b624 | ||
|
|
8d116599b1 | ||
|
|
e1502d15a2 | ||
|
|
823530bbc9 | ||
|
|
7577fc45c4 | ||
|
|
cb6e716ce2 | ||
|
|
b1e3337cb4 | ||
|
|
f545dcc63d | ||
|
|
09d1dbedf9 | ||
|
|
65e1c7385f | ||
|
|
1a0ff0215d | ||
|
|
0e2000550a | ||
|
|
4fcc33ec60 | ||
|
|
b2dd170884 | ||
|
|
5a3ae2ab7a | ||
|
|
f07c74d83c | ||
|
|
1bd853bb32 | ||
|
|
6f47069df8 | ||
|
|
5ccca7ffa7 | ||
|
|
cb34733318 | ||
|
|
ed54cfe519 | ||
|
|
7bb482a829 | ||
|
|
2e207ddef9 | ||
|
|
90656ddb51 | ||
|
|
9c6b5eb600 | ||
|
|
25dff95fed | ||
|
|
d5f1e50495 | ||
|
|
85c0da5aec | ||
|
|
daddf79683 | ||
|
|
e6d83c1bd0 | ||
|
|
3c34602483 | ||
|
|
ef56489d46 | ||
|
|
d12c4dc258 | ||
|
|
9faad6424e | ||
|
|
fb19dd2476 | ||
|
|
e5ec820127 | ||
|
|
3e55015d77 | ||
|
|
e5de6a5cbd | ||
|
|
beaf533a14 | ||
|
|
307743b7d0 | ||
|
|
4aea2eaed5 | ||
|
|
b5c4da073a | ||
|
|
3dc02f7282 | ||
|
|
7d60b5a619 | ||
|
|
a2091df2df | ||
|
|
2205526a79 | ||
|
|
fd6fd9e520 | ||
|
|
15ed1cf5c2 | ||
|
|
d7e0b771ef | ||
|
|
52f804e204 | ||
|
|
7ba29c97aa | ||
|
|
4f941df55c | ||
|
|
4870231b61 | ||
|
|
40fe63a3fb | ||
|
|
03356576b3 | ||
|
|
10c95406d8 | ||
|
|
757f10cbe6 | ||
|
|
19789fabf5 | ||
|
|
c486dfd87a | ||
|
|
c4fda86747 | ||
|
|
f750e3b41b | ||
|
|
428f976034 | ||
|
|
8362665f2b | ||
|
|
18880c71db | ||
|
|
a2b378b131 | ||
|
|
dcc1a3e9d5 | ||
|
|
9329978f6d | ||
|
|
9aa7706722 | ||
|
|
a9623e3001 | ||
|
|
8547b28d63 | ||
|
|
7151695103 | ||
|
|
fb68dc2bfa | ||
|
|
0ceba5a441 | ||
|
|
5502911333 | ||
|
|
632dea08c0 | ||
|
|
8c0380506c | ||
|
|
395c9c3dca | ||
|
|
24270f4e9d | ||
|
|
8cb59315da | ||
|
|
15bd591c1b | ||
|
|
7414a044a6 | ||
|
|
612fa4ab92 | ||
|
|
324217a8bb | ||
|
|
b67ed77030 | ||
|
|
a13e8b77c9 | ||
|
|
0112e7203e | ||
|
|
beb7f60bc5 | ||
|
|
c4f7aa760b | ||
|
|
af1bec2a8c | ||
|
|
c3b210d2b5 | ||
|
|
2434911064 | ||
|
|
35c1551fad | ||
|
|
898593696c | ||
|
|
a06a50967e | ||
|
|
e1ccf52389 | ||
|
|
ce0f6edba6 | ||
|
|
927196c5d1 | ||
|
|
1911ed9934 | ||
|
|
075cf0c160 | ||
|
|
dd4dbb0a5c | ||
|
|
ca3e47f673 | ||
|
|
b99700455c | ||
|
|
216d8c00b2 | ||
|
|
c832af77e8 | ||
|
|
8f748edd96 | ||
|
|
295976407b | ||
|
|
69dc5c1a23 | ||
|
|
de5cda9ef4 | ||
|
|
c32e03b002 | ||
|
|
f1ffd6e6b8 | ||
|
|
535921b0d0 | ||
|
|
fd9d6e5818 | ||
|
|
6cd826d56d | ||
|
|
c820b5a574 | ||
|
|
24e1e2f26c | ||
|
|
be2ca75ef0 | ||
|
|
21621fd2d2 | ||
|
|
5bf1de5481 | ||
|
|
7ff082a930 | ||
|
|
3eeb55749d | ||
|
|
f2f39c3a91 | ||
|
|
a02712ca95 | ||
|
|
d81ca6e8e3 | ||
|
|
e9510f50f8 | ||
|
|
299fec7bdd | ||
|
|
f996d00e92 | ||
|
|
dd841c2c06 | ||
|
|
a08684089d | ||
|
|
d407bc3c41 | ||
|
|
8150b9b139 | ||
|
|
f5c093b3d8 | ||
|
|
814f9ba9c6 | ||
|
|
f11df67441 | ||
|
|
0f420bf39b | ||
|
|
31150eaa76 | ||
|
|
800ebf174f | ||
|
|
484826a5ad | ||
|
|
e75f954495 | ||
|
|
10cb91ad59 | ||
|
|
25b23881b0 | ||
|
|
e294520cf9 | ||
|
|
287421df7a | ||
|
|
45fc9957af | ||
|
|
9e695c0e69 | ||
|
|
70efcadc72 | ||
|
|
8b35ee53a8 | ||
|
|
5968fc5fbf | ||
|
|
64168a9f39 | ||
|
|
38e2063f1f | ||
|
|
ca6b61f553 | ||
|
|
c45a5228e1 | ||
|
|
8c28b8d2d9 | ||
|
|
4bddfbf95d | ||
|
|
f61f0fa2e8 | ||
|
|
5fad001468 | ||
|
|
8283c5d5ec | ||
|
|
5cdfed5741 | ||
|
|
de7a9a484c | ||
|
|
98a95e6e88 | ||
|
|
6586ba43a8 | ||
|
|
323e6197b1 | ||
|
|
1d07068806 | ||
|
|
ce5d8d3780 | ||
|
|
eb79ee1b77 | ||
|
|
d22a2933b6 | ||
|
|
273ae198a6 | ||
|
|
a4d19cc085 | ||
|
|
1c9d40fc54 | ||
|
|
edc50b6f00 | ||
|
|
b47c8f0ba0 | ||
|
|
eb9a9257de | ||
|
|
65f1863327 | ||
|
|
d3dc508171 | ||
|
|
dea9ef8cd1 | ||
|
|
30605fba76 | ||
|
|
5dc11f844d | ||
|
|
eecfb90ab6 | ||
|
|
43ad93cd20 | ||
|
|
ffdd3325dd | ||
|
|
fc5e37dd21 | ||
|
|
231bdd1dd0 | ||
|
|
b9c2d311ba | ||
|
|
ab7064037b | ||
|
|
8bbfaf2aeb | ||
|
|
b931fbc500 | ||
|
|
687c96bb0e | ||
|
|
e2754b3ede | ||
|
|
0791a8aedb | ||
|
|
7108cde060 | ||
|
|
e01883d58b | ||
|
|
a9e52b4e98 | ||
|
|
254d1e0322 | ||
|
|
3d56931268 | ||
|
|
eb7e9397f5 | ||
|
|
996fe3329c | ||
|
|
9d9f7ad7f7 | ||
|
|
92ee6d639d | ||
|
|
8b3c294e5c | ||
|
|
6b31a32a2d | ||
|
|
ab9ce936a3 | ||
|
|
0ce9ececc6 | ||
|
|
2dae231afc | ||
|
|
db75640167 | ||
|
|
13b630b9ce | ||
|
|
df90c46a5b | ||
|
|
aadf1373fc | ||
|
|
4130b2fec5 | ||
|
|
3b445d031f | ||
|
|
61fb71c010 | ||
|
|
3f57039f4d | ||
|
|
bd88d29340 | ||
|
|
16c919ce02 | ||
|
|
6afcfdd50c | ||
|
|
bcfb98cb37 | ||
|
|
d3f38c690e | ||
|
|
2dc738a6e7 | ||
|
|
4925273c0b | ||
|
|
8c2ecbd7aa | ||
|
|
c40ca1333d | ||
|
|
cc1d2b194d | ||
|
|
521ae46cba | ||
|
|
879870ee26 | ||
|
|
9475ded922 | ||
|
|
0e9fde1f8a | ||
|
|
bcb4fc3034 | ||
|
|
e7c9ca0c5b | ||
|
|
aaa5e146f1 | ||
|
|
f45c255073 | ||
|
|
3a1224a2ec | ||
|
|
5a21c0e8ca | ||
|
|
1a4c717584 | ||
|
|
c49641d988 | ||
|
|
2937f3c174 | ||
|
|
82bf084920 | ||
|
|
14192991d9 | ||
|
|
24e69ecf36 | ||
|
|
372e2215f0 | ||
|
|
fd13eb7f8f | ||
|
|
5376eb4051 | ||
|
|
a7c37fa295 | ||
|
|
38c485b2bc | ||
|
|
ab110f915c | ||
|
|
5f970864a1 | ||
|
|
b2bdcdcf9c | ||
|
|
7c73b800fa | ||
|
|
5ba69ba707 | ||
|
|
de9ec95099 | ||
|
|
f7d31d5c99 | ||
|
|
53cef8b475 | ||
|
|
fb08357e8f | ||
|
|
485e3fa466 | ||
|
|
270f41428f | ||
|
|
1c60204350 | ||
|
|
b5eb9e73a7 | ||
|
|
6edd64f13b | ||
|
|
a6e1e5ffe3 | ||
|
|
1d047d8cb2 | ||
|
|
e1cf0e4456 | ||
|
|
3b9d115c59 | ||
|
|
8d4c9e9c16 | ||
|
|
ed36d2bfb4 | ||
|
|
d5d783af25 | ||
|
|
1fe40b61a0 | ||
|
|
86880b48f7 | ||
|
|
e54fdc8d3f | ||
|
|
07adf4c68b | ||
|
|
7cb68da5b0 | ||
|
|
c015b2e881 | ||
|
|
251a98df5c | ||
|
|
a4a376b18d | ||
|
|
677767fd83 | ||
|
|
8c5aaa8801 | ||
|
|
3a5c93fa84 | ||
|
|
2c11228f55 | ||
|
|
33b0b5ceb3 | ||
|
|
538ad86b03 | ||
|
|
fae712b9d4 | ||
|
|
6ad29c6a39 | ||
|
|
64a691a3c7 | ||
|
|
88356c7b2a | ||
|
|
ea1e51a655 | ||
|
|
58fc91b810 | ||
|
|
5ee0a7b946 | ||
|
|
d5a7ae1865 | ||
|
|
cab9553235 | ||
|
|
632bcb9944 | ||
|
|
e8d06c314e | ||
|
|
94cdb2ed29 | ||
|
|
b768632b0c | ||
|
|
0e7dbbb04d | ||
|
|
142b0f7203 | ||
|
|
03433278be | ||
|
|
f42c6d8375 | ||
|
|
afe28d83c9 | ||
|
|
5ac92cf362 | ||
|
|
4f24141689 | ||
|
|
e1fc9039b2 | ||
|
|
6cf69f04ab | ||
|
|
672db903f3 | ||
|
|
22af2dc2d9 | ||
|
|
e8193a0aa0 | ||
|
|
9a2dcf2004 | ||
|
|
0d8d043250 | ||
|
|
ee895d0752 | ||
|
|
676ed6bd44 | ||
|
|
931417928f | ||
|
|
2589fbe560 | ||
|
|
12548b0af2 | ||
|
|
cfc0003388 | ||
|
|
4b2ff9f614 | ||
|
|
11b7cf32ca | ||
|
|
32d2eb11f0 | ||
|
|
556cac8138 | ||
|
|
f79c29d168 | ||
|
|
4f839136c7 | ||
|
|
253d707131 | ||
|
|
627b822f15 | ||
|
|
cf28e42a26 | ||
|
|
4c4d13cdd0 |
No files matched your search
@@ -8,8 +8,6 @@ VITE_BASE_URL='http://api-dashboard.yudao.iocoder.cn'
|
|||||||
|
|
||||||
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务
|
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务
|
||||||
VITE_UPLOAD_TYPE=server
|
VITE_UPLOAD_TYPE=server
|
||||||
# 上传路径
|
|
||||||
VITE_UPLOAD_URL='http://api-dashboard.yudao.iocoder.cn/admin-api/infra/file/upload'
|
|
||||||
|
|
||||||
# 接口地址
|
# 接口地址
|
||||||
VITE_API_URL=/admin-api
|
VITE_API_URL=/admin-api
|
||||||
@@ -34,3 +32,6 @@ VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
|
|||||||
|
|
||||||
# 验证码的开关
|
# 验证码的开关
|
||||||
VITE_APP_CAPTCHA_ENABLE=true
|
VITE_APP_CAPTCHA_ENABLE=true
|
||||||
|
|
||||||
|
# GoView域名
|
||||||
|
VITE_GOVIEW_URL='http://127.0.0.1:3000'
|
||||||
@@ -8,8 +8,6 @@ VITE_BASE_URL='http://localhost:48080'
|
|||||||
|
|
||||||
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持 S3 服务
|
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持 S3 服务
|
||||||
VITE_UPLOAD_TYPE=server
|
VITE_UPLOAD_TYPE=server
|
||||||
# 上传路径
|
|
||||||
VITE_UPLOAD_URL='http://localhost:48080/admin-api/infra/file/upload'
|
|
||||||
|
|
||||||
# 接口地址
|
# 接口地址
|
||||||
VITE_API_URL=/admin-api
|
VITE_API_URL=/admin-api
|
||||||
@@ -31,3 +29,6 @@ VITE_MALL_H5_DOMAIN='http://localhost:3000'
|
|||||||
|
|
||||||
# 验证码的开关
|
# 验证码的开关
|
||||||
VITE_APP_CAPTCHA_ENABLE=false
|
VITE_APP_CAPTCHA_ENABLE=false
|
||||||
|
|
||||||
|
# GoView域名
|
||||||
|
VITE_GOVIEW_URL='http://127.0.0.1:3000'
|
||||||
@@ -8,8 +8,6 @@ VITE_BASE_URL='http://localhost:48080'
|
|||||||
|
|
||||||
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务
|
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务
|
||||||
VITE_UPLOAD_TYPE=server
|
VITE_UPLOAD_TYPE=server
|
||||||
# 上传路径
|
|
||||||
VITE_UPLOAD_URL='http://localhost:48080/admin-api/infra/file/upload'
|
|
||||||
|
|
||||||
# 接口地址
|
# 接口地址
|
||||||
VITE_API_URL=/admin-api
|
VITE_API_URL=/admin-api
|
||||||
@@ -31,3 +29,6 @@ VITE_OUT_DIR=dist-prod
|
|||||||
|
|
||||||
# 商城H5会员端域名
|
# 商城H5会员端域名
|
||||||
VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
|
VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
|
||||||
|
|
||||||
|
# GoView域名
|
||||||
|
VITE_GOVIEW_URL='http://127.0.0.1:3000'
|
||||||
@@ -8,8 +8,6 @@ VITE_BASE_URL='http://api-dashboard.yudao.iocoder.cn'
|
|||||||
|
|
||||||
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务
|
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务
|
||||||
VITE_UPLOAD_TYPE=server
|
VITE_UPLOAD_TYPE=server
|
||||||
# 上传路径
|
|
||||||
VITE_UPLOAD_URL='http://api-dashboard.yudao.iocoder.cn/admin-api/infra/file/upload'
|
|
||||||
|
|
||||||
# 接口地址
|
# 接口地址
|
||||||
VITE_API_URL=/admin-api
|
VITE_API_URL=/admin-api
|
||||||
@@ -31,3 +29,6 @@ VITE_OUT_DIR=dist-stage
|
|||||||
|
|
||||||
# 商城H5会员端域名
|
# 商城H5会员端域名
|
||||||
VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
|
VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
|
||||||
|
|
||||||
|
# GoView域名
|
||||||
|
VITE_GOVIEW_URL='http://127.0.0.1:3000'
|
||||||
@@ -8,8 +8,6 @@ VITE_BASE_URL='http://localhost:48080'
|
|||||||
|
|
||||||
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务
|
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务
|
||||||
VITE_UPLOAD_TYPE=server
|
VITE_UPLOAD_TYPE=server
|
||||||
# 上传路径
|
|
||||||
VITE_UPLOAD_URL='http://localhost:48080/admin-api/infra/file/upload'
|
|
||||||
|
|
||||||
# 接口地址
|
# 接口地址
|
||||||
VITE_API_URL=/admin-api
|
VITE_API_URL=/admin-api
|
||||||
@@ -31,3 +29,6 @@ VITE_OUT_DIR=dist-test
|
|||||||
|
|
||||||
# 商城H5会员端域名
|
# 商城H5会员端域名
|
||||||
VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
|
VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
|
||||||
|
|
||||||
|
# GoView域名
|
||||||
|
VITE_GOVIEW_URL='http://127.0.0.1:3000'
|
||||||
|
After Width: | Height: | Size: 177 KiB |
|
After Width: | Height: | Size: 127 KiB |
@@ -83,10 +83,11 @@
|
|||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
},
|
},
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
"source.fixAll.eslint": "explicit"
|
"source.fixAll.eslint": "explicit",
|
||||||
|
"source.fixAll.stylelint": "explicit"
|
||||||
},
|
},
|
||||||
"[vue]": {
|
"[vue]": {
|
||||||
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
},
|
},
|
||||||
"i18n-ally.localesPaths": ["src/locales"],
|
"i18n-ally.localesPaths": ["src/locales"],
|
||||||
"i18n-ally.keystyle": "nested",
|
"i18n-ally.keystyle": "nested",
|
||||||
|
|||||||
@@ -69,11 +69,11 @@
|
|||||||
|
|
||||||
支持 Spring Boot、Spring Cloud 两种架构:
|
支持 Spring Boot、Spring Cloud 两种架构:
|
||||||
|
|
||||||
① Spring Boot 单体架构:<https://github.com/YunaiV/ruoyi-vue-pro>
|
① Spring Boot 单体架构:<https://doc.iocoder.cn>
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
② Spring Cloud 微服务架构:<https://github.com/YunaiV/yudao-cloud>
|
② Spring Cloud 微服务架构:<https://cloud.iocoder.cn>
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -120,18 +120,22 @@
|
|||||||
|
|
||||||
### 工作流程
|
### 工作流程
|
||||||
|
|
||||||
| | 功能 | 描述 |
|
| | 功能 | 描述 |
|
||||||
|-----|-------|----------------------------------------|
|
|----|-------|-----------------------------------------|
|
||||||
| 🚀 | 流程模型 | 配置工作流的流程模型,支持文件导入与在线设计流程图,提供 7 种任务分配规则 |
|
| 🚀 | 流程模型 | 配置工作流的流程模型,支持 BPMN 和仿钉钉/飞书设计器 |
|
||||||
| 🚀 | 流程表单 | 拖动表单元素生成相应的工作流表单,覆盖 Element UI 所有的表单组件 |
|
| 🚀 | 流程表单 | 拖动表单元素生成相应的工作流表单,覆盖 Element UI 所有的表单组件 |
|
||||||
| 🚀 | 用户分组 | 自定义用户分组,可用于工作流的审批分组 |
|
| 🚀 | 用户分组 | 自定义用户分组,可用于工作流的审批分组 |
|
||||||
| 🚀 | 我的流程 | 查看我发起的工作流程,支持新建、取消流程等操作,高亮流程图、审批时间线 |
|
| 🚀 | 我的流程 | 查看我发起的工作流程,支持新建、取消流程等操作,高亮流程图、审批时间线 |
|
||||||
| 🚀 | 待办任务 | 查看自己【未】审批的工作任务,支持通过、不通过、转发、委派、退回等操作 |
|
| 🚀 | 待办任务 | 查看自己【未】审批的工作任务,支持通过、不通过、转派、委派、退回、加减签等操作 |
|
||||||
| 🚀 | 已办任务 | 查看自己【已】审批的工作任务,未来会支持回退操作 |
|
| 🚀 | 已办任务 | 查看自己【已】审批的工作任务,支持流程预测,展示未来审批人信息 |
|
||||||
| 🚀 | OA 请假 | 作为业务自定义接入工作流的使用示例,只需创建请求对应的工作流程,即可进行审批 |
|
| 🚀 | OA 请假 | 作为业务自定义接入工作流的使用示例,只需创建请求对应的工作流程,即可进行审批 |
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
| BPMN 设计器 | 钉钉/飞书设计器 |
|
||||||
|
|------------------------------|--------------------------------|
|
||||||
|
|  |  |
|
||||||
|
|
||||||
### 支付系统
|
### 支付系统
|
||||||
|
|
||||||
| | 功能 | 描述 |
|
| | 功能 | 描述 |
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "yudao-ui-admin-vue3",
|
"name": "yudao-ui-admin-vue3",
|
||||||
"version": "2.2.0-snapshot",
|
"version": "2.4.0-snapshot",
|
||||||
"description": "基于vue3、vite4、element-plus、typesScript",
|
"description": "基于vue3、vite4、element-plus、typesScript",
|
||||||
"author": "xingyu",
|
"author": "xingyu",
|
||||||
"private": false,
|
"private": false,
|
||||||
@@ -9,11 +9,11 @@
|
|||||||
"dev": "vite --mode env.local",
|
"dev": "vite --mode env.local",
|
||||||
"dev-server": "vite --mode dev",
|
"dev-server": "vite --mode dev",
|
||||||
"ts:check": "vue-tsc --noEmit",
|
"ts:check": "vue-tsc --noEmit",
|
||||||
"build:local": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build",
|
"build:local": "node --max_old_space_size=4096 ./node_modules/vite/bin/vite.js build",
|
||||||
"build:dev": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode dev",
|
"build:dev": "node --max_old_space_size=4096 ./node_modules/vite/bin/vite.js build --mode dev",
|
||||||
"build:test": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode test",
|
"build:test": "node --max_old_space_size=4096 ./node_modules/vite/bin/vite.js build --mode test",
|
||||||
"build:stage": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode stage",
|
"build:stage": "node --max_old_space_size=4096 ./node_modules/vite/bin/vite.js build --mode stage",
|
||||||
"build:prod": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode prod",
|
"build:prod": "node --max_old_space_size=4096 ./node_modules/vite/bin/vite.js build --mode prod",
|
||||||
"serve:dev": "vite preview --mode dev",
|
"serve:dev": "vite preview --mode dev",
|
||||||
"serve:prod": "vite preview --mode prod",
|
"serve:prod": "vite preview --mode prod",
|
||||||
"preview": "pnpm build:local && vite preview",
|
"preview": "pnpm build:local && vite preview",
|
||||||
@@ -26,8 +26,8 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@element-plus/icons-vue": "^2.1.0",
|
"@element-plus/icons-vue": "^2.1.0",
|
||||||
"@form-create/designer": "^3.1.3",
|
"@form-create/designer": "^3.2.6",
|
||||||
"@form-create/element-ui": "^3.1.24",
|
"@form-create/element-ui": "^3.2.11",
|
||||||
"@iconify/iconify": "^3.1.1",
|
"@iconify/iconify": "^3.1.1",
|
||||||
"@microsoft/fetch-event-source": "^2.0.1",
|
"@microsoft/fetch-event-source": "^2.0.1",
|
||||||
"@videojs-player/vue": "^1.0.0",
|
"@videojs-player/vue": "^1.0.0",
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
"driver.js": "^1.3.1",
|
"driver.js": "^1.3.1",
|
||||||
"echarts": "^5.5.0",
|
"echarts": "^5.5.0",
|
||||||
"echarts-wordcloud": "^2.1.0",
|
"echarts-wordcloud": "^2.1.0",
|
||||||
"element-plus": "2.7.0",
|
"element-plus": "2.8.4",
|
||||||
"fast-xml-parser": "^4.3.2",
|
"fast-xml-parser": "^4.3.2",
|
||||||
"highlight.js": "^11.9.0",
|
"highlight.js": "^11.9.0",
|
||||||
"jsencrypt": "^3.3.2",
|
"jsencrypt": "^3.3.2",
|
||||||
@@ -64,13 +64,14 @@
|
|||||||
"pinia-plugin-persistedstate": "^3.2.1",
|
"pinia-plugin-persistedstate": "^3.2.1",
|
||||||
"qrcode": "^1.5.3",
|
"qrcode": "^1.5.3",
|
||||||
"qs": "^6.12.0",
|
"qs": "^6.12.0",
|
||||||
|
"sortablejs": "^1.15.3",
|
||||||
"steady-xml": "^0.1.0",
|
"steady-xml": "^0.1.0",
|
||||||
"url": "^0.11.3",
|
"url": "^0.11.3",
|
||||||
"video.js": "^7.21.5",
|
"video.js": "^7.21.5",
|
||||||
"vue": "3.4.21",
|
"vue": "3.5.12",
|
||||||
"vue-dompurify-html": "^4.1.4",
|
"vue-dompurify-html": "^4.1.4",
|
||||||
"vue-i18n": "9.10.2",
|
"vue-i18n": "9.10.2",
|
||||||
"vue-router": "^4.3.0",
|
"vue-router": "4.4.5",
|
||||||
"vue-types": "^5.1.1",
|
"vue-types": "^5.1.1",
|
||||||
"vuedraggable": "^4.1.0",
|
"vuedraggable": "^4.1.0",
|
||||||
"web-storage-cache": "^1.1.1",
|
"web-storage-cache": "^1.1.1",
|
||||||
@@ -95,8 +96,8 @@
|
|||||||
"@vitejs/plugin-vue": "^5.0.4",
|
"@vitejs/plugin-vue": "^5.0.4",
|
||||||
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
||||||
"autoprefixer": "^10.4.17",
|
"autoprefixer": "^10.4.17",
|
||||||
"bpmn-js": "8.9.0",
|
"bpmn-js": "^17.9.2",
|
||||||
"bpmn-js-properties-panel": "0.46.0",
|
"bpmn-js-properties-panel": "5.23.0",
|
||||||
"consola": "^3.2.3",
|
"consola": "^3.2.3",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^9.1.0",
|
||||||
@@ -130,7 +131,7 @@
|
|||||||
"vite-plugin-progress": "^0.0.7",
|
"vite-plugin-progress": "^0.0.7",
|
||||||
"vite-plugin-purge-icons": "^0.10.0",
|
"vite-plugin-purge-icons": "^0.10.0",
|
||||||
"vite-plugin-svg-icons": "^2.0.1",
|
"vite-plugin-svg-icons": "^2.0.1",
|
||||||
"vite-plugin-top-level-await": "^1.3.1",
|
"vite-plugin-top-level-await": "^1.4.4",
|
||||||
"vue-eslint-parser": "^9.3.2",
|
"vue-eslint-parser": "^9.3.2",
|
||||||
"vue-tsc": "^1.8.27"
|
"vue-tsc": "^1.8.27"
|
||||||
},
|
},
|
||||||
@@ -143,6 +144,7 @@
|
|||||||
"url": "https://gitee.com/yudaocode/yudao-ui-admin-vue3/issues"
|
"url": "https://gitee.com/yudaocode/yudao-ui-admin-vue3/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://gitee.com/yudaocode/yudao-ui-admin-vue3",
|
"homepage": "https://gitee.com/yudaocode/yudao-ui-admin-vue3",
|
||||||
|
"web-types": "./web-types.json",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 16.0.0",
|
"node": ">= 16.0.0",
|
||||||
"pnpm": ">=8.6.0"
|
"pnpm": ">=8.6.0"
|
||||||
|
|||||||
@@ -54,8 +54,4 @@ body {
|
|||||||
.#{$prefix-cls}-grey-mode {
|
.#{$prefix-cls}-grey-mode {
|
||||||
filter: grayscale(100%);
|
filter: grayscale(100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.scrollbar__view {
|
|
||||||
height: 99%!important;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
@@ -1,7 +1,20 @@
|
|||||||
import { getAccessToken } from '@/utils/auth'
|
import { getAccessToken } from '@/utils/auth'
|
||||||
import { fetchEventSource } from '@microsoft/fetch-event-source'
|
import { fetchEventSource } from '@microsoft/fetch-event-source'
|
||||||
import { config } from '@/config/axios/config'
|
import { config } from '@/config/axios/config'
|
||||||
|
import request from '@/config/axios' // AI 思维导图 VO
|
||||||
|
|
||||||
|
// AI 思维导图 VO
|
||||||
|
export interface MindMapVO {
|
||||||
|
id: number // 编号
|
||||||
|
userId: number // 用户编号
|
||||||
|
prompt: string // 生成内容提示
|
||||||
|
generatedContent: string // 生成的思维导图内容
|
||||||
|
platform: string // 平台
|
||||||
|
model: string // 模型
|
||||||
|
errorMessage: string // 错误信息
|
||||||
|
}
|
||||||
|
|
||||||
|
// AI 思维导图生成 VO
|
||||||
export interface AiMindMapGenerateReqVO {
|
export interface AiMindMapGenerateReqVO {
|
||||||
prompt: string
|
prompt: string
|
||||||
}
|
}
|
||||||
@@ -34,5 +47,14 @@ export const AiMindMapApi = {
|
|||||||
onclose: onClose,
|
onclose: onClose,
|
||||||
signal: ctrl.signal
|
signal: ctrl.signal
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询思维导图分页
|
||||||
|
getMindMapPage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/ai/mind-map/page`, params })
|
||||||
|
},
|
||||||
|
// 删除思维导图
|
||||||
|
deleteMindMap: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/ai/mind-map/delete?id=` + id })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
import request from '@/config/axios'
|
|
||||||
|
|
||||||
export const getActivityList = async (params) => {
|
|
||||||
return await request.get({
|
|
||||||
url: '/bpm/activity/list',
|
|
||||||
params
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -36,6 +36,16 @@ export const CategoryApi = {
|
|||||||
return await request.put({ url: `/bpm/category/update`, data })
|
return await request.put({ url: `/bpm/category/update`, data })
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 批量修改流程分类的排序
|
||||||
|
updateCategorySortBatch: async (ids: number[]) => {
|
||||||
|
return await request.put({
|
||||||
|
url: `/bpm/category/update-sort-batch`,
|
||||||
|
params: {
|
||||||
|
ids: ids.join(',')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
// 删除流程分类
|
// 删除流程分类
|
||||||
deleteCategory: async (id: number) => {
|
deleteCategory: async (id: number) => {
|
||||||
return await request.delete({ url: `/bpm/category/delete?id=` + id })
|
return await request.delete({ url: `/bpm/category/delete?id=` + id })
|
||||||
|
|||||||
@@ -26,11 +26,11 @@ export type ModelVO = {
|
|||||||
bpmnXml: string
|
bpmnXml: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getModelPage = async (params) => {
|
export const getModelList = async (name: string | undefined) => {
|
||||||
return await request.get({ url: '/bpm/model/page', params })
|
return await request.get({ url: '/bpm/model/list', params: { name } })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getModel = async (id: number) => {
|
export const getModel = async (id: string) => {
|
||||||
return await request.get({ url: '/bpm/model/get?id=' + id })
|
return await request.get({ url: '/bpm/model/get?id=' + id })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,6 +38,20 @@ export const updateModel = async (data: ModelVO) => {
|
|||||||
return await request.put({ url: '/bpm/model/update', data: data })
|
return await request.put({ url: '/bpm/model/update', data: data })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 批量修改流程分类的排序
|
||||||
|
export const updateModelSortBatch = async (ids: number[]) => {
|
||||||
|
return await request.put({
|
||||||
|
url: `/bpm/model/update-sort-batch`,
|
||||||
|
params: {
|
||||||
|
ids: ids.join(',')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const updateModelBpmn = async (data: ModelVO) => {
|
||||||
|
return await request.put({ url: '/bpm/model/update-bpmn', data: data })
|
||||||
|
}
|
||||||
|
|
||||||
// 任务状态修改
|
// 任务状态修改
|
||||||
export const updateModelState = async (id: number, state: number) => {
|
export const updateModelState = async (id: number, state: number) => {
|
||||||
const data = {
|
const data = {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import request from '@/config/axios'
|
import request from '@/config/axios'
|
||||||
import { ProcessDefinitionVO } from '@/api/bpm/model'
|
import { ProcessDefinitionVO } from '@/api/bpm/model'
|
||||||
|
import { NodeType, CandidateStrategy } from '@/components/SimpleProcessDesignerV2/src/consts'
|
||||||
export type Task = {
|
export type Task = {
|
||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
@@ -22,6 +22,35 @@ export type ProcessInstanceVO = {
|
|||||||
processDefinition?: ProcessDefinitionVO
|
processDefinition?: ProcessDefinitionVO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 用户信息
|
||||||
|
export type User = {
|
||||||
|
id: number
|
||||||
|
nickname: string
|
||||||
|
avatar: string
|
||||||
|
}
|
||||||
|
|
||||||
|
// 审批任务信息
|
||||||
|
export type ApprovalTaskInfo = {
|
||||||
|
id: number
|
||||||
|
ownerUser: User
|
||||||
|
assigneeUser: User
|
||||||
|
status: number
|
||||||
|
reason: string
|
||||||
|
}
|
||||||
|
|
||||||
|
// 审批节点信息
|
||||||
|
export type ApprovalNodeInfo = {
|
||||||
|
id: number
|
||||||
|
name: string
|
||||||
|
nodeType: NodeType
|
||||||
|
candidateStrategy?: CandidateStrategy
|
||||||
|
status: number
|
||||||
|
startTime?: Date
|
||||||
|
endTime?: Date
|
||||||
|
candidateUsers?: User[]
|
||||||
|
tasks: ApprovalTaskInfo[]
|
||||||
|
}
|
||||||
|
|
||||||
export const getProcessInstanceMyPage = async (params: any) => {
|
export const getProcessInstanceMyPage = async (params: any) => {
|
||||||
return await request.get({ url: '/bpm/process-instance/my-page', params })
|
return await request.get({ url: '/bpm/process-instance/my-page', params })
|
||||||
}
|
}
|
||||||
@@ -57,3 +86,18 @@ export const getProcessInstance = async (id: string) => {
|
|||||||
export const getProcessInstanceCopyPage = async (params: any) => {
|
export const getProcessInstanceCopyPage = async (params: any) => {
|
||||||
return await request.get({ url: '/bpm/process-instance/copy/page', params })
|
return await request.get({ url: '/bpm/process-instance/copy/page', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取审批详情
|
||||||
|
export const getApprovalDetail = async (params: any) => {
|
||||||
|
return await request.get({ url: 'bpm/process-instance/get-approval-detail' , params })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取表单字段权限
|
||||||
|
export const getFormFieldsPermission = async (params: any) => {
|
||||||
|
return await request.get({ url: '/bpm/process-instance/get-form-fields-permission', params })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取流程实例的 BPMN 模型视图
|
||||||
|
export const getProcessInstanceBpmnModelView = async (id: string) => {
|
||||||
|
return await request.get({ url: '/bpm/process-instance/get-bpmn-model-view?id=' + id })
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
|
||||||
|
export const updateBpmSimpleModel = async (data) => {
|
||||||
|
return await request.post({
|
||||||
|
url: '/bpm/model/simple/update',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getBpmSimpleModel = async (id) => {
|
||||||
|
return await request.get({
|
||||||
|
url: '/bpm/model/simple/get?id=' + id
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,7 +1,44 @@
|
|||||||
import request from '@/config/axios'
|
import request from '@/config/axios'
|
||||||
|
|
||||||
export type TaskVO = {
|
/**
|
||||||
id: number
|
* 任务状态枚举
|
||||||
|
*/
|
||||||
|
export enum TaskStatusEnum {
|
||||||
|
/**
|
||||||
|
* 未开始
|
||||||
|
*/
|
||||||
|
NOT_START = -1,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 待审批
|
||||||
|
*/
|
||||||
|
WAIT = 0,
|
||||||
|
/**
|
||||||
|
* 审批中
|
||||||
|
*/
|
||||||
|
RUNNING = 1,
|
||||||
|
/**
|
||||||
|
* 审批通过
|
||||||
|
*/
|
||||||
|
APPROVE = 2,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 审批不通过
|
||||||
|
*/
|
||||||
|
REJECT = 3,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已取消
|
||||||
|
*/
|
||||||
|
CANCEL = 4,
|
||||||
|
/**
|
||||||
|
* 已退回
|
||||||
|
*/
|
||||||
|
RETURN = 5,
|
||||||
|
/**
|
||||||
|
* 审批通过中
|
||||||
|
*/
|
||||||
|
APPROVING = 7
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getTaskTodoPage = async (params: any) => {
|
export const getTaskTodoPage = async (params: any) => {
|
||||||
@@ -30,12 +67,12 @@ export const getTaskListByProcessInstanceId = async (processInstanceId: string)
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取所有可回退的节点
|
// 获取所有可退回的节点
|
||||||
export const getTaskListByReturn = async (id: string) => {
|
export const getTaskListByReturn = async (id: string) => {
|
||||||
return await request.get({ url: '/bpm/task/list-by-return', params: { id } })
|
return await request.get({ url: '/bpm/task/list-by-return', params: { id } })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 回退
|
// 退回
|
||||||
export const returnTask = async (data: any) => {
|
export const returnTask = async (data: any) => {
|
||||||
return await request.put({ url: '/bpm/task/return', data })
|
return await request.put({ url: '/bpm/task/return', data })
|
||||||
}
|
}
|
||||||
@@ -60,6 +97,16 @@ export const signDeleteTask = async (data: any) => {
|
|||||||
return await request.delete({ url: '/bpm/task/delete-sign', data })
|
return await request.delete({ url: '/bpm/task/delete-sign', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 抄送
|
||||||
|
export const copyTask = async (data: any) => {
|
||||||
|
return await request.put({ url: '/bpm/task/copy', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取我的待办任务
|
||||||
|
export const myTodoTask = async (processInstanceId: string) => {
|
||||||
|
return await request.get({ url: '/bpm/task/my-todo?processInstanceId=' + processInstanceId })
|
||||||
|
}
|
||||||
|
|
||||||
// 获取减签任务列表
|
// 获取减签任务列表
|
||||||
export const getChildrenTaskList = async (id: string) => {
|
export const getChildrenTaskList = async (id: string) => {
|
||||||
return await request.get({ url: '/bpm/task/list-by-parent-task-id?parentTaskId=' + id })
|
return await request.get({ url: '/bpm/task/list-by-parent-task-id?parentTaskId=' + id })
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
// IoT 设备 VO
|
||||||
|
export interface DeviceVO {
|
||||||
|
id: number // 设备 ID,主键,自增
|
||||||
|
deviceKey: string // 设备唯一标识符
|
||||||
|
deviceName: string // 设备名称
|
||||||
|
productId: number // 产品编号
|
||||||
|
productKey: string // 产品标识
|
||||||
|
deviceType: number // 设备类型
|
||||||
|
nickname: string // 设备备注名称
|
||||||
|
gatewayId: number // 网关设备 ID
|
||||||
|
status: number // 设备状态
|
||||||
|
statusLastUpdateTime: Date // 设备状态最后更新时间
|
||||||
|
lastOnlineTime: Date // 最后上线时间
|
||||||
|
lastOfflineTime: Date // 最后离线时间
|
||||||
|
activeTime: Date // 设备激活时间
|
||||||
|
createTime: Date // 创建时间
|
||||||
|
ip: string // 设备的 IP 地址
|
||||||
|
firmwareVersion: string // 设备的固件版本
|
||||||
|
deviceSecret: string // 设备密钥,用于设备认证,需安全存储
|
||||||
|
mqttClientId: string // MQTT 客户端 ID
|
||||||
|
mqttUsername: string // MQTT 用户名
|
||||||
|
mqttPassword: string // MQTT 密码
|
||||||
|
authType: string // 认证类型
|
||||||
|
latitude: number // 设备位置的纬度
|
||||||
|
longitude: number // 设备位置的经度
|
||||||
|
areaId: number // 地区编码
|
||||||
|
address: string // 设备详细地址
|
||||||
|
serialNumber: string // 设备序列号
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DeviceUpdateStatusVO {
|
||||||
|
id: number // 设备 ID,主键,自增
|
||||||
|
status: number // 设备状态
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设备 API
|
||||||
|
export const DeviceApi = {
|
||||||
|
// 查询设备分页
|
||||||
|
getDevicePage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/iot/device/page`, params })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询设备详情
|
||||||
|
getDevice: async (id: number) => {
|
||||||
|
return await request.get({ url: `/iot/device/get?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 新增设备
|
||||||
|
createDevice: async (data: DeviceVO) => {
|
||||||
|
return await request.post({ url: `/iot/device/create`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 修改设备
|
||||||
|
updateDevice: async (data: DeviceVO) => {
|
||||||
|
return await request.put({ url: `/iot/device/update`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 修改设备状态
|
||||||
|
updateDeviceStatus: async (data: DeviceUpdateStatusVO) => {
|
||||||
|
return await request.put({ url: `/iot/device/update-status`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除设备
|
||||||
|
deleteDevice: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/iot/device/delete?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取设备数量
|
||||||
|
getDeviceCount: async (productId: number) => {
|
||||||
|
return await request.get({ url: `/iot/device/count?productId=` + productId })
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
// IoT 产品 VO
|
||||||
|
export interface ProductVO {
|
||||||
|
id: number // 产品编号
|
||||||
|
name: string // 产品名称
|
||||||
|
productKey: string // 产品标识
|
||||||
|
protocolId: number // 协议编号
|
||||||
|
categoryId: number // 产品所属品类标识符
|
||||||
|
description: string // 产品描述
|
||||||
|
validateType: number // 数据校验级别
|
||||||
|
status: number // 产品状态
|
||||||
|
deviceType: number // 设备类型
|
||||||
|
netType: number // 联网方式
|
||||||
|
protocolType: number // 接入网关协议
|
||||||
|
dataFormat: number // 数据格式
|
||||||
|
deviceCount: number // 设备数量
|
||||||
|
createTime: Date // 创建时间
|
||||||
|
}
|
||||||
|
|
||||||
|
// IoT 产品 API
|
||||||
|
export const ProductApi = {
|
||||||
|
// 查询产品分页
|
||||||
|
getProductPage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/iot/product/page`, params })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询产品详情
|
||||||
|
getProduct: async (id: number) => {
|
||||||
|
return await request.get({ url: `/iot/product/get?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 新增产品
|
||||||
|
createProduct: async (data: ProductVO) => {
|
||||||
|
return await request.post({ url: `/iot/product/create`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 修改产品
|
||||||
|
updateProduct: async (data: ProductVO) => {
|
||||||
|
return await request.put({ url: `/iot/product/update`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除产品
|
||||||
|
deleteProduct: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/iot/product/delete?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 导出产品 Excel
|
||||||
|
exportProduct: async (params) => {
|
||||||
|
return await request.download({ url: `/iot/product/export-excel`, params })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 更新产品状态
|
||||||
|
updateProductStatus: async (id: number, status: number) => {
|
||||||
|
return await request.put({ url: `/iot/product/update-status?id=` + id + `&status=` + status })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询产品(精简)列表
|
||||||
|
getSimpleProductList() {
|
||||||
|
return request.get({ url: '/iot/product/list-all-simple' })
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
// IoT 产品物模型 VO
|
||||||
|
export interface ThinkModelFunctionVO {
|
||||||
|
id: number // 物模型功能编号
|
||||||
|
identifier: string // 功能标识
|
||||||
|
name: string // 功能名称
|
||||||
|
description: string // 功能描述
|
||||||
|
productId: number // 产品编号
|
||||||
|
productKey: string // 产品标识
|
||||||
|
type: number // 功能类型
|
||||||
|
property: string // 属性
|
||||||
|
event: string // 事件
|
||||||
|
service: string // 服务
|
||||||
|
}
|
||||||
|
|
||||||
|
// IoT 产品物模型 API
|
||||||
|
export const ThinkModelFunctionApi = {
|
||||||
|
// 查询产品物模型分页
|
||||||
|
getThinkModelFunctionPage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/iot/think-model-function/page`, params })
|
||||||
|
},
|
||||||
|
// 获得产品物模型
|
||||||
|
getThinkModelFunctionListByProductId: async (params: any) => {
|
||||||
|
return await request.get({
|
||||||
|
url: `/iot/think-model-function/list-by-product-id`,
|
||||||
|
params
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询产品物模型详情
|
||||||
|
getThinkModelFunction: async (id: number) => {
|
||||||
|
return await request.get({ url: `/iot/think-model-function/get?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 新增产品物模型
|
||||||
|
createThinkModelFunction: async (data: ThinkModelFunctionVO) => {
|
||||||
|
return await request.post({ url: `/iot/think-model-function/create`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 修改产品物模型
|
||||||
|
updateThinkModelFunction: async (data: ThinkModelFunctionVO) => {
|
||||||
|
return await request.put({ url: `/iot/think-model-function/update`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除产品物模型
|
||||||
|
deleteThinkModelFunction: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/iot/think-model-function/delete?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 导出产品物模型 Excel
|
||||||
|
exportThinkModelFunction: async (params) => {
|
||||||
|
return await request.download({ url: `/iot/think-model-function/export-excel`, params })
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import request from '@/config/axios'
|
import request from '@/config/axios'
|
||||||
import { getRefreshToken } from '@/utils/auth'
|
import { getRefreshToken } from '@/utils/auth'
|
||||||
import type { UserLoginVO } from './types'
|
import type { RegisterVO, UserLoginVO } from './types'
|
||||||
|
|
||||||
export interface SmsCodeVO {
|
export interface SmsCodeVO {
|
||||||
mobile: string
|
mobile: string
|
||||||
@@ -17,6 +17,11 @@ export const login = (data: UserLoginVO) => {
|
|||||||
return request.post({ url: '/system/auth/login', data })
|
return request.post({ url: '/system/auth/login', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 注册
|
||||||
|
export const register = (data: RegisterVO) => {
|
||||||
|
return request.post({ url: '/system/auth/register', data })
|
||||||
|
}
|
||||||
|
|
||||||
// 刷新访问令牌
|
// 刷新访问令牌
|
||||||
export const refreshToken = () => {
|
export const refreshToken = () => {
|
||||||
return request.post({ url: '/system/auth/refresh-token?refreshToken=' + getRefreshToken() })
|
return request.post({ url: '/system/auth/refresh-token?refreshToken=' + getRefreshToken() })
|
||||||
@@ -72,6 +77,7 @@ export const socialAuthRedirect = (type: number, redirectUri: string) => {
|
|||||||
}
|
}
|
||||||
// 获取验证图片以及 token
|
// 获取验证图片以及 token
|
||||||
export const getCode = (data) => {
|
export const getCode = (data) => {
|
||||||
|
debugger
|
||||||
return request.postOriginal({ url: 'system/captcha/get', data })
|
return request.postOriginal({ url: 'system/captcha/get', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export const authorize = (
|
|||||||
return request.post({
|
return request.post({
|
||||||
url: '/system/oauth2/authorize',
|
url: '/system/oauth2/authorize',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-type': 'application/x-www-form-urlencoded'
|
'Content-Type': 'application/x-www-form-urlencoded'
|
||||||
},
|
},
|
||||||
params: {
|
params: {
|
||||||
response_type: responseType,
|
response_type: responseType,
|
||||||
|
|||||||
@@ -29,3 +29,10 @@ export type UserVO = {
|
|||||||
loginIp: string
|
loginIp: string
|
||||||
loginDate: string
|
loginDate: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type RegisterVO = {
|
||||||
|
tenantName: string
|
||||||
|
username: string
|
||||||
|
password: string
|
||||||
|
captchaVerification: string
|
||||||
|
}
|
||||||
@@ -24,20 +24,6 @@ export interface PropertyValueVO {
|
|||||||
remark?: string
|
remark?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 商品属性值的明细
|
|
||||||
*/
|
|
||||||
export interface PropertyValueDetailVO {
|
|
||||||
/** 属性项的编号 */
|
|
||||||
propertyId: number // 属性的编号
|
|
||||||
/** 属性的名称 */
|
|
||||||
propertyName: string
|
|
||||||
/** 属性值的编号 */
|
|
||||||
valueId: number
|
|
||||||
/** 属性值的名称 */
|
|
||||||
valueName: string
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------ 属性项 -------------------
|
// ------------------------ 属性项 -------------------
|
||||||
|
|
||||||
// 创建属性项
|
// 创建属性项
|
||||||
@@ -65,6 +51,11 @@ export const getPropertyPage = (params: PageParam) => {
|
|||||||
return request.get({ url: '/product/property/page', params })
|
return request.get({ url: '/product/property/page', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获得属性项精简列表
|
||||||
|
export const getPropertySimpleList = (): Promise<PropertyVO[]> => {
|
||||||
|
return request.get({ url: '/product/property/simple-list' })
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------ 属性值 -------------------
|
// ------------------------ 属性值 -------------------
|
||||||
|
|
||||||
// 获得属性值分页
|
// 获得属性值分页
|
||||||
@@ -91,3 +82,8 @@ export const updatePropertyValue = (data: PropertyValueVO) => {
|
|||||||
export const deletePropertyValue = (id: number) => {
|
export const deletePropertyValue = (id: number) => {
|
||||||
return request.delete({ url: `/product/property/value/delete?id=${id}` })
|
return request.delete({ url: `/product/property/value/delete?id=${id}` })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获得属性值精简列表
|
||||||
|
export const getPropertyValueSimpleList = (propertyId: number): Promise<PropertyValueVO[]> => {
|
||||||
|
return request.get({ url: '/product/property/value/simple-list', params: { propertyId } })
|
||||||
|
}
|
||||||
@@ -50,6 +50,8 @@ export interface Spu {
|
|||||||
giveIntegral?: number // 赠送积分
|
giveIntegral?: number // 赠送积分
|
||||||
virtualSalesCount?: number // 虚拟销量
|
virtualSalesCount?: number // 虚拟销量
|
||||||
price?: number // 商品价格
|
price?: number // 商品价格
|
||||||
|
combinationPrice?: number // 商品拼团价格
|
||||||
|
seckillPrice?: number // 商品秒杀价格
|
||||||
salesCount?: number // 商品销量
|
salesCount?: number // 商品销量
|
||||||
marketPrice?: number // 市场价
|
marketPrice?: number // 市场价
|
||||||
costPrice?: number // 成本价
|
costPrice?: number // 成本价
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ export interface CombinationActivityVO {
|
|||||||
virtualGroup?: number
|
virtualGroup?: number
|
||||||
status?: number
|
status?: number
|
||||||
limitDuration?: number
|
limitDuration?: number
|
||||||
|
combinationPrice?: number
|
||||||
products: CombinationProductVO[]
|
products: CombinationProductVO[]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +37,7 @@ export interface SpuExtension extends Spu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 查询拼团活动列表
|
// 查询拼团活动列表
|
||||||
export const getCombinationActivityPage = async (params) => {
|
export const getCombinationActivityPage = async (params: any) => {
|
||||||
return await request.get({ url: '/promotion/combination-activity/page', params })
|
return await request.get({ url: '/promotion/combination-activity/page', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,6 +46,11 @@ export const getCombinationActivity = async (id: number) => {
|
|||||||
return await request.get({ url: '/promotion/combination-activity/get?id=' + id })
|
return await request.get({ url: '/promotion/combination-activity/get?id=' + id })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获得拼团活动列表,基于活动编号数组
|
||||||
|
export const getCombinationActivityListByIds = (ids: number[]) => {
|
||||||
|
return request.get({ url: `/promotion/combination-activity/list-by-ids?ids=${ids}` })
|
||||||
|
}
|
||||||
|
|
||||||
// 新增拼团活动
|
// 新增拼团活动
|
||||||
export const createCombinationActivity = async (data: CombinationActivityVO) => {
|
export const createCombinationActivity = async (data: CombinationActivityVO) => {
|
||||||
return await request.post({ url: '/promotion/combination-activity/create', data })
|
return await request.post({ url: '/promotion/combination-activity/create', data })
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ export function getCouponTemplatePage(params: PageParam) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获得优惠劵模板分页
|
// 获得优惠劵模板分页
|
||||||
export function getCouponTemplateList(ids: number[]) {
|
export function getCouponTemplateList(ids: number[]): Promise<CouponTemplateVO[]> {
|
||||||
return request.get({
|
return request.get({
|
||||||
url: `/promotion/coupon-template/list?ids=${ids}`
|
url: `/promotion/coupon-template/list?ids=${ids}`
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ export const KeFuConversationApi = {
|
|||||||
getConversationList: async () => {
|
getConversationList: async () => {
|
||||||
return await request.get({ url: '/promotion/kefu-conversation/list' })
|
return await request.get({ url: '/promotion/kefu-conversation/list' })
|
||||||
},
|
},
|
||||||
|
// 获得客服会话
|
||||||
|
getConversation: async (id: number) => {
|
||||||
|
return await request.get({ url: `/promotion/kefu-conversation/get?id=` + id })
|
||||||
|
},
|
||||||
// 客服会话置顶
|
// 客服会话置顶
|
||||||
updateConversationPinned: async (data: any) => {
|
updateConversationPinned: async (data: any) => {
|
||||||
return await request.put({
|
return await request.put({
|
||||||
@@ -30,6 +34,6 @@ export const KeFuConversationApi = {
|
|||||||
},
|
},
|
||||||
// 删除客服会话
|
// 删除客服会话
|
||||||
deleteConversation: async (id: number) => {
|
deleteConversation: async (id: number) => {
|
||||||
return await request.get({ url: '/promotion/kefu-conversation/delete?id' + id })
|
return await request.delete({ url: `/promotion/kefu-conversation/delete?id=${id}` })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -29,8 +29,8 @@ export const KeFuMessageApi = {
|
|||||||
url: '/promotion/kefu-message/update-read-status?conversationId=' + conversationId
|
url: '/promotion/kefu-message/update-read-status?conversationId=' + conversationId
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 获得消息分页数据
|
// 获得消息列表(流式加载)
|
||||||
getKeFuMessagePage: async (params: any) => {
|
getKeFuMessageList: async (params: any) => {
|
||||||
return await request.get({ url: '/promotion/kefu-message/page', params })
|
return await request.get({ url: '/promotion/kefu-message/list', params })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
import request from '@/config/axios'
|
||||||
|
import { Sku, Spu } from '@/api/mall/product/spu' // 积分商城活动 VO
|
||||||
|
|
||||||
|
// 积分商城活动 VO
|
||||||
|
export interface PointActivityVO {
|
||||||
|
id: number // 积分商城活动编号
|
||||||
|
spuId: number // 积分商城活动商品
|
||||||
|
status: number // 活动状态
|
||||||
|
stock: number // 积分商城活动库存
|
||||||
|
totalStock: number // 积分商城活动总库存
|
||||||
|
remark?: string // 备注
|
||||||
|
sort: number // 排序
|
||||||
|
createTime: string // 创建时间
|
||||||
|
products: PointProductVO[] // 积分商城商品
|
||||||
|
|
||||||
|
// ========== 商品字段 ==========
|
||||||
|
spuName: string // 商品名称
|
||||||
|
picUrl: string // 商品主图
|
||||||
|
marketPrice: number // 商品市场价,单位:分
|
||||||
|
|
||||||
|
//======================= 显示所需兑换积分最少的 sku 信息 =======================
|
||||||
|
point: number // 兑换积分
|
||||||
|
price: number // 兑换金额,单位:分
|
||||||
|
}
|
||||||
|
|
||||||
|
// 秒杀活动所需属性
|
||||||
|
export interface PointProductVO {
|
||||||
|
id?: number // 积分商城商品编号
|
||||||
|
activityId?: number // 积分商城活动 id
|
||||||
|
spuId?: number // 商品 SPU 编号
|
||||||
|
skuId: number // 商品 SKU 编号
|
||||||
|
count: number // 可兑换数量
|
||||||
|
point: number // 兑换积分
|
||||||
|
price: number // 兑换金额,单位:分
|
||||||
|
stock: number // 积分商城商品库存
|
||||||
|
activityStatus?: number // 积分商城商品状态
|
||||||
|
}
|
||||||
|
|
||||||
|
// 扩展 Sku 配置
|
||||||
|
export type SkuExtension = Sku & {
|
||||||
|
productConfig: PointProductVO
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SpuExtension extends Spu {
|
||||||
|
skus: SkuExtension[] // 重写类型
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SpuExtension0 extends Spu {
|
||||||
|
pointStock: number // 积分商城活动库存
|
||||||
|
pointTotalStock: number // 积分商城活动总库存
|
||||||
|
point: number // 兑换积分
|
||||||
|
pointPrice: number // 兑换金额,单位:分
|
||||||
|
}
|
||||||
|
|
||||||
|
// 积分商城活动 API
|
||||||
|
export const PointActivityApi = {
|
||||||
|
// 查询积分商城活动分页
|
||||||
|
getPointActivityPage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/promotion/point-activity/page`, params })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询积分商城活动详情
|
||||||
|
getPointActivity: async (id: number) => {
|
||||||
|
return await request.get({ url: `/promotion/point-activity/get?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询积分商城活动列表,基于活动编号数组
|
||||||
|
getPointActivityListByIds: async (ids: number[]) => {
|
||||||
|
return request.get({ url: `/promotion/point-activity/list-by-ids?ids=${ids}` })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 新增积分商城活动
|
||||||
|
createPointActivity: async (data: PointActivityVO) => {
|
||||||
|
return await request.post({ url: `/promotion/point-activity/create`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 修改积分商城活动
|
||||||
|
updatePointActivity: async (data: PointActivityVO) => {
|
||||||
|
return await request.put({ url: `/promotion/point-activity/update`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除积分商城活动
|
||||||
|
deletePointActivity: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/promotion/point-activity/delete?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 关闭秒杀活动
|
||||||
|
closePointActivity: async (id: number) => {
|
||||||
|
return await request.put({ url: '/promotion/point-activity/close?id=' + id })
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,34 +1,39 @@
|
|||||||
import request from '@/config/axios'
|
import request from '@/config/axios'
|
||||||
|
|
||||||
export interface DiscountActivityVO {
|
export interface RewardActivityVO {
|
||||||
id?: number
|
id?: number
|
||||||
name?: string
|
name?: string
|
||||||
startTime?: Date
|
startTime?: Date
|
||||||
endTime?: Date
|
endTime?: Date
|
||||||
|
startAndEndTime?: Date[] // 只前端使用
|
||||||
remark?: string
|
remark?: string
|
||||||
conditionType?: number
|
conditionType?: number
|
||||||
productScope?: number
|
productScope?: number
|
||||||
|
rules: RewardRule[]
|
||||||
|
// 如下仅用于表单,不提交
|
||||||
|
productScopeValues?: number[] // 商品范围:值为品类编号列表、商品编号列表
|
||||||
|
productCategoryIds?: number[]
|
||||||
productSpuIds?: number[]
|
productSpuIds?: number[]
|
||||||
rules?: DiscountProductVO[]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 优惠规则
|
// 优惠规则
|
||||||
export interface DiscountProductVO {
|
export interface RewardRule {
|
||||||
limit: number
|
limit?: number
|
||||||
discountPrice: number
|
discountPrice?: number
|
||||||
freeDelivery: boolean
|
freeDelivery?: boolean
|
||||||
point: number
|
point: number
|
||||||
couponIds: number[]
|
giveCouponTemplateCounts?: {
|
||||||
couponCounts: number[]
|
[key: number]: number
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增满减送活动
|
// 新增满减送活动
|
||||||
export const createRewardActivity = async (data: DiscountActivityVO) => {
|
export const createRewardActivity = async (data: RewardActivityVO) => {
|
||||||
return await request.post({ url: '/promotion/reward-activity/create', data })
|
return await request.post({ url: '/promotion/reward-activity/create', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新满减送活动
|
// 更新满减送活动
|
||||||
export const updateRewardActivity = async (data: DiscountActivityVO) => {
|
export const updateRewardActivity = async (data: RewardActivityVO) => {
|
||||||
return await request.put({ url: '/promotion/reward-activity/update', data })
|
return await request.put({ url: '/promotion/reward-activity/update', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +47,12 @@ export const getReward = async (id: number) => {
|
|||||||
return await request.get({ url: '/promotion/reward-activity/get?id=' + id })
|
return await request.get({ url: '/promotion/reward-activity/get?id=' + id })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除限时折扣活动
|
// 删除满减送活动
|
||||||
export const deleteRewardActivity = async (id: number) => {
|
export const deleteRewardActivity = async (id: number) => {
|
||||||
return await request.delete({ url: '/promotion/reward-activity/delete?id=' + id })
|
return await request.delete({ url: '/promotion/reward-activity/delete?id=' + id })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 关闭满减送活动
|
||||||
|
export const closeRewardActivity = async (id: number) => {
|
||||||
|
return await request.put({ url: '/promotion/reward-activity/close?id=' + id })
|
||||||
|
}
|
||||||
@@ -18,12 +18,14 @@ export interface SeckillActivityVO {
|
|||||||
singleLimitCount?: number
|
singleLimitCount?: number
|
||||||
stock?: number
|
stock?: number
|
||||||
totalStock?: number
|
totalStock?: number
|
||||||
|
seckillPrice?: number
|
||||||
products?: SeckillProductVO[]
|
products?: SeckillProductVO[]
|
||||||
}
|
}
|
||||||
|
|
||||||
// 秒杀活动所需属性
|
// 秒杀活动所需属性
|
||||||
export interface SeckillProductVO {
|
export interface SeckillProductVO {
|
||||||
skuId: number
|
skuId: number
|
||||||
|
spuId: number
|
||||||
seckillPrice: number
|
seckillPrice: number
|
||||||
stock: number
|
stock: number
|
||||||
}
|
}
|
||||||
@@ -42,6 +44,11 @@ export const getSeckillActivityPage = async (params) => {
|
|||||||
return await request.get({ url: '/promotion/seckill-activity/page', params })
|
return await request.get({ url: '/promotion/seckill-activity/page', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 查询秒杀活动列表,基于活动编号数组
|
||||||
|
export const getSeckillActivityListByIds = (ids: number[]) => {
|
||||||
|
return request.get({ url: `/promotion/seckill-activity/list-by-ids?ids=${ids}` })
|
||||||
|
}
|
||||||
|
|
||||||
// 查询秒杀活动详情
|
// 查询秒杀活动详情
|
||||||
export const getSeckillActivity = async (id: number) => {
|
export const getSeckillActivity = async (id: number) => {
|
||||||
return await request.get({ url: '/promotion/seckill-activity/get?id=' + id })
|
return await request.get({ url: '/promotion/seckill-activity/get?id=' + id })
|
||||||
|
|||||||
@@ -13,6 +13,11 @@ export interface BrokerageUserVO {
|
|||||||
avatar: string
|
avatar: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 创建分销用户
|
||||||
|
export const createBrokerageUser = (data: any) => {
|
||||||
|
return request.post({ url: '/trade/brokerage-user/create', data })
|
||||||
|
}
|
||||||
|
|
||||||
// 查询分销用户列表
|
// 查询分销用户列表
|
||||||
export const getBrokerageUserPage = async (params: any) => {
|
export const getBrokerageUserPage = async (params: any) => {
|
||||||
return await request.get({ url: `/trade/brokerage-user/page`, params })
|
return await request.get({ url: `/trade/brokerage-user/page`, params })
|
||||||
|
|||||||
@@ -13,10 +13,11 @@ export interface DeliveryPickUpStoreVO {
|
|||||||
latitude: number
|
latitude: number
|
||||||
longitude: number
|
longitude: number
|
||||||
status: number
|
status: number
|
||||||
|
verifyUserIds: number[] // 绑定用户编号组数
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询自提门店列表
|
// 查询自提门店列表
|
||||||
export const getDeliveryPickUpStorePage = async (params) => {
|
export const getDeliveryPickUpStorePage = async (params: any) => {
|
||||||
return await request.get({ url: '/trade/delivery/pick-up-store/page', params })
|
return await request.get({ url: '/trade/delivery/pick-up-store/page', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,8 +27,8 @@ export const getDeliveryPickUpStore = async (id: number) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 查询自提门店精简列表
|
// 查询自提门店精简列表
|
||||||
export const getListAllSimple = async (): Promise<DeliveryPickUpStoreVO[]> => {
|
export const getSimpleDeliveryPickUpStoreList = async (): Promise<DeliveryPickUpStoreVO[]> => {
|
||||||
return await request.get({ url: '/trade/delivery/pick-up-store/list-all-simple' })
|
return await request.get({ url: '/trade/delivery/pick-up-store/simple-list' })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增自提门店
|
// 新增自提门店
|
||||||
@@ -44,3 +45,8 @@ export const updateDeliveryPickUpStore = async (data: DeliveryPickUpStoreVO) =>
|
|||||||
export const deleteDeliveryPickUpStore = async (id: number) => {
|
export const deleteDeliveryPickUpStore = async (id: number) => {
|
||||||
return await request.delete({ url: '/trade/delivery/pick-up-store/delete?id=' + id })
|
return await request.delete({ url: '/trade/delivery/pick-up-store/delete?id=' + id })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 绑定自提店员
|
||||||
|
export const bindStoreStaffId = async (data: any) => {
|
||||||
|
return await request.post({ url: '/trade/delivery/pick-up-store/bind', data })
|
||||||
|
}
|
||||||
@@ -46,8 +46,3 @@ export const updateUserLevel = async (data: any) => {
|
|||||||
export const updateUserPoint = async (data: any) => {
|
export const updateUserPoint = async (data: any) => {
|
||||||
return await request.put({ url: `/member/user/update-point`, data })
|
return await request.put({ url: `/member/user/update-point`, data })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 修改会员用户余额
|
|
||||||
export const updateUserBalance = async (data: any) => {
|
|
||||||
return await request.put({ url: `/member/user/update-balance`, data })
|
|
||||||
}
|
|
||||||
@@ -2,11 +2,13 @@ import request from '@/config/axios'
|
|||||||
|
|
||||||
export interface AppVO {
|
export interface AppVO {
|
||||||
id: number
|
id: number
|
||||||
|
appKey: string
|
||||||
name: string
|
name: string
|
||||||
status: number
|
status: number
|
||||||
remark: string
|
remark: string
|
||||||
payNotifyUrl: string
|
payNotifyUrl: string
|
||||||
refundNotifyUrl: string
|
refundNotifyUrl: string
|
||||||
|
transferNotifyUrl: string
|
||||||
merchantId: number
|
merchantId: number
|
||||||
merchantName: string
|
merchantName: string
|
||||||
createTime: Date
|
createTime: Date
|
||||||
@@ -18,6 +20,7 @@ export interface AppPageReqVO extends PageParam {
|
|||||||
remark?: string
|
remark?: string
|
||||||
payNotifyUrl?: string
|
payNotifyUrl?: string
|
||||||
refundNotifyUrl?: string
|
refundNotifyUrl?: string
|
||||||
|
transferNotifyUrl?: string
|
||||||
merchantName?: string
|
merchantName?: string
|
||||||
createTime?: Date[]
|
createTime?: Date[]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,8 +84,14 @@ export const getOrderPage = async (params: OrderPageReqVO) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 查询详情支付订单
|
// 查询详情支付订单
|
||||||
export const getOrder = async (id: number) => {
|
export const getOrder = async (id: number, sync?: boolean) => {
|
||||||
return await request.get({ url: '/pay/order/get?id=' + id })
|
return await request.get({
|
||||||
|
url: '/pay/order/get',
|
||||||
|
params: {
|
||||||
|
id,
|
||||||
|
sync
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获得支付订单的明细
|
// 获得支付订单的明细
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import request from '@/config/axios'
|
|||||||
export interface PayWalletUserReqVO {
|
export interface PayWalletUserReqVO {
|
||||||
userId: number
|
userId: number
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 钱包 VO */
|
/** 钱包 VO */
|
||||||
export interface WalletVO {
|
export interface WalletVO {
|
||||||
id: number
|
id: number
|
||||||
@@ -20,7 +21,12 @@ export const getWallet = async (params: PayWalletUserReqVO) => {
|
|||||||
return await request.get<WalletVO>({ url: `/pay/wallet/get`, params })
|
return await request.get<WalletVO>({ url: `/pay/wallet/get`, params })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询会员钱包列表
|
/** 查询会员钱包列表 */
|
||||||
export const getWalletPage = async (params) => {
|
export const getWalletPage = async (params: any) => {
|
||||||
return await request.get({ url: `/pay/wallet/page`, params })
|
return await request.get({ url: `/pay/wallet/page`, params })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 修改会员钱包余额 */
|
||||||
|
export const updateWalletBalance = async (data: any) => {
|
||||||
|
return await request.put({ url: `/pay/wallet/update-balance`, data })
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<svg t="1731390087280" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4297" width="200" height="200"><path d="M639.9 541.7c76.4-44.2 127.9-126.8 127.9-221.5C767.7 179 653.2 64.5 512 64.5S256.3 179 256.3 320.2c0 89.6 46.1 168.4 115.8 214.1C193.5 593 64.5 761.2 64.5 959.5h63.9c0-211.5 172.1-383.6 383.6-383.6 44.9 0 87.8 8.1 127.9 22.4v-56.6zM320.2 320.2c0-105.8 86-191.8 191.8-191.8s191.8 86 191.8 191.8S617.7 512 512 512s-191.8-86-191.8-191.8zM831.6 767.7V639.9h-63.9v127.8H639.9v63.9h127.8v127.9h63.9V831.6h127.9v-63.9z" fill="#5f6266" p-id="4298"></path></svg>
|
||||||
|
After Width: | Height: | Size: 608 B |
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1724316565416" class="icon" viewBox="0 0 1300 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1339" xmlns:xlink="http://www.w3.org/1999/xlink" width="253.90625" height="200"><path d="M784.058182 99.258182l10.938182 18.385454-21.294546-2.56-14.196363 16.058182-4.072728-21.061818-19.781818-8.494545 18.734546-10.472728 2.094545-21.294545 15.709091 14.545454 20.945454-4.654545-9.076363 19.549091zM1067.287273 642.443636l-18.501818 10.821819 2.56-21.294546-16.058182-14.196364 21.061818-4.072727 8.494545-19.665454 10.472728 18.734545 21.294545 1.978182-14.661818 15.709091 4.770909 20.945454-19.432727-8.96z" fill="#13C463" p-id="1340"></path><path d="M1067.287273 642.443636l-18.501818 10.821819 2.56-21.294546-16.058182-14.196364 21.061818-4.072727 8.494545-19.665454 10.472728 18.734545 21.294545 1.978182-14.661818 15.709091 4.770909 20.945454-19.432727-8.96zM571.927273 100.072727l-17.454546-12.567272 20.596364-6.167273 6.516364-20.48 12.218181 17.570909 21.410909-0.116364-12.916363 17.105455 6.749091 20.363636-20.247273-6.981818-17.338182 12.683636 0.465455-21.410909zM991.418182 784.407273l-21.178182 3.490909 10.123636-18.967273-9.774545-18.967273 21.061818 3.723637 15.127273-15.243637 2.909091 21.294546 19.2 9.658182-19.316364 9.309091-3.258182 21.178181-14.894545-15.476363zM427.985455 156.741818L407.272727 151.505455l16.872728-13.265455-1.396364-21.410909 17.803636 11.985454 20.014546-7.912727-5.934546 20.596364 13.730909 16.523636-21.410909 0.814546-11.52 18.152727-7.447272-20.247273zM854.225455 896.465455l-20.712728-5.352728 16.872728-13.265454-1.396364-21.294546 17.803636 11.869091 20.014546-7.912727-5.934546 20.712727 13.730909 16.523637-21.527272 0.814545-11.403637 18.036364-7.447272-20.130909zM562.501818 923.694545l10.821818 18.385455-21.294545-2.56-14.196364 16.058182-4.072727-21.061818-19.665455-8.494546 18.734546-10.356363 1.978182-21.41091 15.709091 14.661819 20.945454-4.770909-8.96 19.54909zM242.734545 420.770909l-18.385454 10.938182 2.56-21.294546-16.058182-14.196363 21.061818-4.189091 8.494546-19.665455 10.356363 18.734546 21.410909 2.094545-14.545454 15.709091 4.654545 20.945455-19.549091-9.076364z" fill="#13C463" p-id="1341"></path><path d="M242.734545 420.770909l-18.385454 10.938182 2.56-21.294546-16.058182-14.196363 21.061818-4.189091 8.494546-19.665455 10.356363 18.734546 21.410909 2.094545-14.545454 15.709091 4.654545 20.945455-19.549091-9.076364zM700.858182 943.941818l-17.454546-12.450909 20.48-6.283636 6.516364-20.48 12.334545 17.687272 21.41091-0.116363-12.916364 17.105454 6.632727 20.363637-20.247273-7.098182-17.221818 12.683636 0.465455-21.410909zM303.592727 278.807273l-21.178182 3.490909 10.123637-18.967273-9.890909-18.967273 21.178182 3.723637 15.010909-15.243637 2.909091 21.294546 19.2 9.541818-19.316364 9.425455-3.258182 21.178181-14.778182-15.476363z" fill="#13C463" p-id="1342"></path><path d="M407.272727 90.647273a486.632727 486.632727 0 0 1 504.552728 11.636363l25.018181-14.429091A512 512 0 0 0 139.636364 546.909091l25.018181-14.429091A486.981818 486.981818 0 0 1 407.272727 90.647273zM893.323636 933.352727a486.749091 486.749091 0 0 1-504.669091-11.636363l-24.901818 14.429091A512 512 0 0 0 1161.192727 477.090909l-24.901818 13.963636a486.981818 486.981818 0 0 1-242.967273 442.298182z" fill="#13C463" p-id="1343"></path><path d="M814.545455 795.927273a327.447273 327.447273 0 0 1-258.21091 29.556363l-29.78909 17.105455A353.163636 353.163636 0 0 0 998.865455 570.181818l-29.789091 17.105455A326.865455 326.865455 0 0 1 814.545455 795.927273zM486.865455 228.072727A327.447273 327.447273 0 0 1 744.727273 198.516364l29.789091-17.105455A353.163636 353.163636 0 0 0 302.545455 453.818182l29.78909-17.105455A326.865455 326.865455 0 0 1 486.865455 228.072727zM1288.378182 374.690909a53.294545 53.294545 0 0 1-14.429091 11.636364L229.469091 989.090909a53.876364 53.876364 0 0 1-73.425455-19.665454L7.214545 710.632727a53.527273 53.527273 0 0 1 19.781819-73.309091L1071.476364 34.909091a53.876364 53.876364 0 0 1 73.425454 19.665454l148.829091 258.327273a53.061818 53.061818 0 0 1 5.352727 40.727273 55.272727 55.272727 0 0 1-10.705454 21.061818zM32.232727 665.716364A28.043636 28.043636 0 0 0 29.323636 698.181818l148.829091 257.978182a28.392727 28.392727 0 0 0 38.516364 10.356364l1044.48-601.949091a28.16 28.16 0 0 0 10.356364-38.516364L1122.676364 67.84a28.276364 28.276364 0 0 0-38.4-10.356364L39.68 659.432727a27.810909 27.810909 0 0 0-7.447273 6.283637z" fill="#13C463" p-id="1344"></path><path d="M356.770909 569.250909l22.341818 38.749091-15.476363 8.727273L349.090909 592.64l-153.483636 88.785455 14.778182 25.483636-15.476364 8.96-23.272727-39.912727L256 627.2c-6.283636-4.887273-11.636364-8.843636-16.174545-11.636364L256 602.647273c3.956364 3.141818 9.774545 8.261818 17.338182 15.127272z m-17.338182 199.447273l-49.221818 28.392727 7.563636 13.149091-15.47Line truncated
|
||||||
|
After Width: | Height: | Size: 10 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg t="1729561718271" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8640" width="200" height="200"><path d="M908.5952 920.4224H164.7616a31.0784 31.0784 0 0 1-30.976-30.976c0-17.0496 13.9264-30.976 30.976-30.976h743.8336c17.0496 0 31.0272 13.9264 31.0272 30.976a31.0784 31.0784 0 0 1-31.0272 30.976z m0-123.9552H164.7616a31.0784 31.0784 0 0 1-30.976-30.976v-154.9824c0-51.1488 41.8304-92.9792 92.9792-92.9792h198.3488c-6.1952-37.1712-24.7808-72.8064-51.1488-103.8336a216.576 216.576 0 0 1-54.2208-144.128c0-58.88 23.2448-114.688 66.6112-156.4672C429.7728 71.168 485.5296 51.0976 545.9968 52.6848c111.5648 4.608 206.08 100.6592 207.616 212.2752 1.536 55.808-20.1216 110.0288-57.344 151.8592-26.3168 27.904-41.8304 61.952-48.0256 100.7104h198.3488c51.2 0 93.0304 41.8304 93.0304 92.9792v154.9824a31.0784 31.0784 0 0 1-31.0272 30.976z m-712.8064-61.952H877.568v-124.0064a31.0784 31.0784 0 0 0-31.0272-30.976h-232.448a31.0784 31.0784 0 0 1-30.976-31.0272c0-65.024 23.2448-127.0784 66.6624-173.568 27.8528-29.3888 41.8304-68.1472 41.8304-108.4416-1.536-80.5888-68.1984-148.7872-148.7872-151.8592a150.528 150.528 0 0 0-113.152 43.3664 153.6 153.6 0 0 0-48.0256 111.616c0 37.1712 13.9776 74.3424 38.7584 102.2464 44.9536 51.1488 69.7344 113.152 69.7344 176.64a31.0784 31.0784 0 0 1-30.976 31.0272h-232.448a31.0784 31.0784 0 0 0-30.976 30.976v123.9552z" fill="#fff" p-id="8641"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg t="1729178183592" class="icon" viewBox="0 0 1300 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4332" width="200" height="200"><path d="M784.074702 99.196443l10.927871 18.473304-21.302843-2.56935-14.180213 16.066571-4.130475-21.042655-19.676671-8.521137 18.733492-10.440019 2.016452-21.335366 15.708814 14.603017 20.945085-4.683373-9.041512 19.449008zM1067.22363 642.402668l-18.440781 10.92787 2.56935-21.302842-16.099094-14.180213 21.042655-4.130475 8.521137-19.676671 10.440019 18.733492 21.367889 2.016452-14.603017 15.708814 4.683373 20.945085-19.481531-9.041512z" fill="#8a8a8a" p-id="4333"></path><path d="M1067.22363 642.402668l-18.440781 10.92787 2.56935-21.302842-16.099094-14.180213 21.042655-4.130475 8.521137-19.676671 10.440019 18.733492 21.367889 2.016452-14.603017 15.708814 4.683373 20.945085-19.481531-9.041512zM571.924408 100.009528l-17.400031-12.488994 20.52228-6.211974 6.504685-20.457234 12.261331 17.595172 21.432936-0.09757-12.944323 17.074798 6.732349 20.359663-20.262093-7.02506-17.269938 12.716659 0.422804-21.46546zM991.444053 784.43246l-21.172749 3.480006 10.114785-18.928632-9.822074-19.026203 21.107702 3.772717 15.090868-15.253486 2.927109 21.237796 19.156296 9.626933-19.318914 9.366746-3.219819 21.205273-14.863204-15.48115zM428.008258 156.795426l-20.749945-5.333841 16.879657-13.237034-1.365983-21.400413 17.822836 11.936097 19.936859-7.870669-5.88674 20.619851 13.692361 16.521899-21.432936 0.813086-11.513292 18.083024-7.382817-20.132zM854.260251 896.475655l-20.749945-5.333841 16.879657-13.237034-1.365983-21.400413 17.822836 11.96862 19.936859-7.903192-5.854217 20.619851 13.659838 16.554423-21.432936 0.780562-11.513292 18.115547-7.382817-20.164523zM562.460092 923.665237l10.895347 18.440782-21.302843-2.569351-14.180212 16.099095-4.130475-21.042655-19.676672-8.521137 18.733493-10.440019 2.016452-21.36789 15.708814 14.603018 20.945085-4.683373-9.008989 19.48153zM242.787359 420.788058l-18.473305 10.895347 2.569351-21.302843-16.066572-14.180213 21.042656-4.130474 8.521137-19.676672 10.440019 18.733492 21.335366 2.016453-14.603018 15.708813 4.683374 20.945085-19.449008-9.008988z" fill="#8a8a8a" p-id="4334"></path><path d="M242.787359 420.788058l-18.473305 10.895347 2.569351-21.302843-16.066572-14.180213 21.042656-4.130474 8.521137-19.676672 10.440019 18.733492 21.335366 2.016453-14.603018 15.708813 4.683374 20.945085-19.449008-9.008988zM700.814737 943.959854l-17.400032-12.521518 20.522281-6.211974 6.504685-20.42471 12.26133 17.595172 21.432937-0.130094-12.944323 17.107321 6.732349 20.359663-20.262093-7.025059-17.269938 12.684135 0.422804-21.432936zM303.541115 278.823313l-21.140226 3.480006 10.114785-18.928633-9.854597-19.058726 21.107702 3.772717 15.090868-15.220962 2.927109 21.237796 19.156296 9.626933-19.28639 9.366746-3.252342 21.172749-14.863205-15.448626z" fill="#8a8a8a" p-id="4335"></path><path d="M407.648595 90.642782a486.713038 486.713038 0 0 1 504.568397 11.578339l25.010513-14.407877A512.081309 512.081309 0 0 0 139.850723 547.401747l24.977989-14.407877a486.778085 486.778085 0 0 1 242.819883-442.351088zM893.28836 933.422265a486.810608 486.810608 0 0 1-504.568398-11.610863l-25.010513 14.407877a512.081309 512.081309 0 0 0 797.5394-459.621026l-24.97799 14.505447a486.843132 486.843132 0 0 1-242.982499 442.318565z" fill="#8a8a8a" p-id="4336"></path><path d="M814.061299 795.880705a326.665269 326.665269 0 0 1-258.170939 29.563792l-29.791456 17.172368a353.236906 353.236906 0 0 0 472.793013-272.448721l-29.693886 17.172367a326.762839 326.762839 0 0 1-155.136732 208.540194zM486.875655 228.119295a326.795363 326.795363 0 0 1 258.170939-29.563792l29.791456-17.172368a353.236906 353.236906 0 0 0-472.793013 272.448721l29.82398-17.172367a326.762839 326.762839 0 0 1 155.006638-208.540194zM1288.350389 374.73489a53.923837 53.923837 0 0 1-14.34283 12.001143L229.420232 988.712085A53.793743 53.793743 0 0 1 156.112434 968.937843l-148.924757-258.235985a53.76122 53.76122 0 0 1 19.741718-73.437891L1071.516722 35.352962A53.826266 53.826266 0 0 1 1144.82452 55.062157l148.827187 258.268508a53.793743 53.793743 0 0 1-5.398888 61.404225zM32.19819 665.754486a28.360426 28.360426 0 0 0-5.626553 10.73273 28.067715 28.067715 0 0 0 2.699444 21.432936L178.195839 956.188661a28.165285 28.165285 0 0 0 38.442687 10.342449l1044.587328-601.976052a28.132762 28.132762 0 0 0 10.440019-38.442687l-148.924758-258.268509a28.197808 28.197808 0 0 0-38.442687-10.342449L39.711101 659.444942a28.230332 28.230332 0 0 0-7.512911 6.309544z" fill="#8a8a8a" p-id="4337"></path><path d="M498.941845 597.390249l-138.322121 79.877529 38.637827 66.933207q8.000762 13.854979 21.595554 5.98431l114.254788-65.957504a21.172749 21.172749 0 0 0 9.952167-11.123011q2.634397-9.757027-16.91218-47.321582l18.440781-4.130474q20.489757 43.22363 18.148071 56.167953a36.166047 36.166047 0 0 1-16.261712 19.514054l-123.068636 71.031158q-25.17313 14.603017-40.394092-11.77348L317.103383 639.020232l16.066571-9.269176 18.570875 32.133143 122.027886-70.47826-33.596697-Line truncated
|
||||||
|
After Width: | Height: | Size: 7.4 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg t="1729585232424" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1602" width="200" height="200"><path d="M925.5 898.9H804.9c-19 0-34.5-15.4-34.5-34.4V761.3c0-19 15.4-34.4 34.5-34.4h34.5V572.2c0-19-15.4-34.4-34.5-34.4H529.2V727h34.5c19 0 34.5 15.4 34.5 34.4v103.2c0 19-15.4 34.4-34.5 34.4H443.1c-19 0-34.5-15.4-34.5-34.4V761.3c0-19 15.4-34.4 34.5-34.4h34.5V537.8H219.1c-19 0-34.5 15.4-34.5 34.4V727h34.5c19 0 34.5 15.4 34.5 34.4v103.2c0 19-15.4 34.4-34.5 34.4H98.5c-19 0-34.5-15.4-34.5-34.4V761.3c0-19 15.4-34.4 34.5-34.4H133V555c0-38 30.9-68.8 68.9-68.8h275.7V297.1h-34.5c-19 0-34.5-15.4-34.5-34.4V159.5c0-19 15.4-34.4 34.5-34.4h120.6c19 0 34.5 15.4 34.5 34.4v103.2c0 19-15.4 34.4-34.5 34.4h-34.5v189.2h292.9c38.1 0 68.9 30.8 68.9 68.8v172h34.5c19 0 34.5 15.4 34.5 34.4v103.2c0 18.8-15.4 34.2-34.5 34.2z m0 0" p-id="1603" fill="#fff"></path></svg>
|
||||||
|
After Width: | Height: | Size: 897 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg t="1729649333541" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1644" width="200" height="200"><path d="M647.888 893.84L491.904 571.52l393.888-393.888-237.904 716.208zM872.32 123.232L459.872 535.68 134.96 380.88 872.32 123.232z m90.72-68.32a23.968 23.968 0 0 0-24.784-5.568L64.08 354.816a23.984 23.984 0 0 0-2.4 44.32l381.392 181.728 187.36 387.088a24.048 24.048 0 0 0 23.152 13.504 24.032 24.032 0 0 0 21.232-16.4L968.96 79.552c2.88-8.672 0.592-18.24-5.92-24.64z" fill="#fff" p-id="1645"></path></svg>
|
||||||
|
After Width: | Height: | Size: 553 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg t="1730189225011" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2651" id="mx_n_1730189225011" width="200" height="200"><path d="M793.889347 200.380242c27.648573 20.615681 42.196018 32.710677 63.781037 56.119312 25.313864 27.453234 43.242957 48.52047 64.502857 86.507991 44.537416 79.580127 53.527718 136.949077 53.517684 212.063821 0 64.933675-15.452562 130.459388-40.138263 187.311893-22.076044 50.841799-61.545336 104.359483-101.886297 138.933914-45.506755 39.001681-81.214423 60.462941-137.605337 81.826531-55.699867 21.102023-114.070267 28.641326-181.379458 27.791064-68.274516-0.862973-129.364283-11.040029-180.533878-31.80489-46.159002-18.731189-98.338744-46.827973-141.596418-87.541551-43.946046-41.361142-70.369064-75.958317-93.88139-127.198155-26.157437-57.004361-40.094111-129.065922-39.680686-191.781288 0-36.980719 4.033895-70.902234 12.252873-105.241856 8.532726-35.651474 20.069131-69.572989 38.13135-102.35257 18.856956-34.221214 36.754607-62.067803 58.869452-88.973149 23.248751-28.285434 39.2104-46.417894 64.295476-63.475987 18.297696-12.442861 36.879036-9.295353 47.199252-2.306612 4.403836 2.982273 8.919391 6.577992 12.933218 12.933217 9.572307 15.156208-0.334486 29.769212-6.69038 38.465836-7.148625 9.781026-23.130343 26.023643-38.738775 43.218205-38.192895 42.075603-55.133918 65.965228-74.986303 106.965794-30.772668 63.552249-37.495827 115.718611-38.131349 166.573791-0.668971 53.517684 9.995096 99.647251 27.427813 140.483919 33.916163 80.572211 94.807915 144.44289 175.270414 178.615938 41.108271 17.845472 113.812713 37.319888 181.960793 38.13135 56.193568 0.668971 125.919751-11.321666 166.574459-28.096784 45.935566-18.954626 97.223569-56.862539 127.10383-94.324918 23.013273-28.852721 52.179742-70.910931 64.413884-105.694749 14.863868-42.260239 24.806784-87.661297 24.559934-132.458943 0-54.414105-11.53373-108.417461-36.918505-156.856317-20.16747-38.483228-46.480777-74.607665-84.66899-108.048189-13.377414-11.714352-23.822728-20.067124-38.808348-31.619586-10.191774-7.857065-36.059546-25.027545-28.923632-47.326356 4.970455-15.53217 18.303717-25.294464 31.887843-27.205046 19.456354-2.736092 28.565733 2.427027 43.705885 12.041479l6.179955 4.322891zM510.755379 531.65738c-8.696624-0.668971-10.034566-0.446204-20.738102-6.689711-11.031333-6.434832-17.839451-21.183637-16.514219-35.175166V92.220334c0-18.178619 0.386665-22.815926 8.988295-31.685813 5.351768-5.519011 10.963097-11.381873 26.08987-11.539751 16.055305-0.167243 21.407073 3.846584 27.929542 9.700081 9.70677 8.711341 10.703537 17.56049 10.377078 33.525483v397.5715c-0.509756 15.273947 0.326458 22.967114-11.380535 33.502739-3.884046 3.495374-8.027653 7.693167-20.96087 8.362138l-3.791059 0.000669z m4.453341 0.573308" p-id="2652" fill="#ffffff"></path></svg>
|
||||||
|
After Width: | Height: | Size: 2.7 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg t="1729585239190" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1755" width="200" height="200"><path d="M901.489435 536.822664v-0.931601l-1.001722-198.240726c-0.100172-19.162936-9.21584-37.474409-25.043042-50.246361-14.024104-11.349507-32.265456-17.60025-51.348255-17.610268l-618.062295-0.18031c-19.142902 0-37.424323 6.280795-51.478478 17.690405-15.827203 12.842072-24.902802 31.2437-24.892785 50.486775v196.798247A114.987635 114.987635 0 1 0 195.295664 536.922836V338.782282c1.15198-1.252152 4.808264-3.596181 10.768509-3.596181l276.725622 0.090155v199.753326a114.987635 114.987635 0 1 0 65.612772 1.412428V335.326342l275.693849 0.080138c6.01033 0 9.626546 2.344029 10.768508 3.596181l1.001722 195.70637a114.987635 114.987635 0 1 0 65.592737 2.113633zM214.979496 645.910158a56.437001 56.437001 0 1 1-56.437001-56.437001 56.507122 56.507122 0 0 1 56.437001 56.437001z m354.689623 0a56.437001 56.437001 0 1 1-56.437001-56.437001 56.507122 56.507122 0 0 1 56.437001 56.437001z m295.507904 56.437001a56.437001 56.437001 0 1 1 56.437001-56.437001 56.507122 56.507122 0 0 1-56.457035 56.437001z" p-id="1756" fill='#fff'></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1724316570161" class="icon" viewBox="0 0 1185 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1505" xmlns:xlink="http://www.w3.org/1999/xlink" width="231.4453125" height="200"><path d="M414.276535 230.004913l-2.443086-31.647244 26.446614 17.351559 29.437984-11.852598-8.143622 30.31685 20.423559 24.221229-31.623055 1.475527-16.722646 26.801386-11.239811-29.760504-30.663559-7.522772zM581.664252 176.902047l13.884472-28.542992 14.206993 28.220473 31.42148 4.321763-22.350614 22.092599 5.684409 31.123149-28.180157-14.513385-27.897953 14.819779 5.28126-31.066709-22.76989-21.689448zM896.507969 672.735748l17.754708 26.398236-31.494047-2.064126-19.560819 24.705008-7.95011-30.502299-29.575055-11.02211 26.744945-16.771024 1.104629-31.526299 24.414741 20.197795 30.268472-8.619338zM777.030551 801.961323l2.112504 31.647244-26.446614-17.682142-29.413795 11.546205 8.466141-30.308787-20.092976-24.221229 31.606929-1.153008 17.045166-26.793323 10.86085 29.704063 30.647433 7.837229zM609.312252 853.451591l-14.198929 28.518803-14.110236-28.542992-31.405355-4.636221 22.673134-22.084535-5.36189-31.12315 27.833449 14.835906 28.188221-14.803654-5.28126 31.066709 22.76989 22.060346zM298.435528 354.828094l-17.448315-26.390173 31.485984 2.394709 19.875275-24.753386 7.611465 30.865134 29.583118 11.288189-27.011024 16.779087-1.419086 31.526299-24.084158-20.504189-30.518425 8.280693zM962.56 91.53915a43.636913 43.636913 0 0 1 59.375874 15.601889l138.627024 236.753638c12.175118 20.447748 5.12 47.208819-15.609953 59.375874L229.13411 938.185575a43.636913 43.636913 0 0 1-59.375874-15.60189L31.12315 685.773606a43.636913 43.636913 0 0 1 15.601889-59.319433z m25.672567 24.108346a13.594205 13.594205 0 0 0-10.441575 1.548095L61.625449 652.054173a13.586142 13.586142 0 0 0-4.853921 18.83515l138.643149 236.793953a13.586142 13.586142 0 0 0 18.843213 4.837795l915.818834-534.915024a13.957039 13.957039 0 0 0 5.160315-18.778708l-138.602834-236.78589a13.594205 13.594205 0 0 0-8.401638-6.393953z" fill="#F5222D" p-id="1506"></path><path d="M395.981606 172.338394c123.670173-72.349228 271.11811-69.462677 388.394331-5.12l29.623433-17.335433a414.574866 414.574866 0 0 0-112.107842-47.071748 429.991307 429.991307 0 0 0-162.009701-10.498016 412.792945 412.792945 0 0 0-158.80063 54.707401 417.856504 417.856504 0 0 0-125.363402 111.922394A426.282331 426.282331 0 0 0 185.206929 405.004094a417.348535 417.348535 0 0 0-13.529701 120.977134l29.623433-17.335433c1.386835-133.958551 70.688252-263.958173 194.672882-336.307401z m397.666772 679.484472c-123.670173 72.365354-271.110047 69.462677-388.394331 5.128063l-29.623433 17.335433a414.679685 414.679685 0 0 0 112.075591 47.087874 429.991307 429.991307 0 0 0 162.009701 10.498016 412.744567 412.744567 0 0 0 158.808692-54.707402 423.145827 423.145827 0 0 0 209.105638-378.976756l-29.623433 17.335434c-1.072378 133.974677-70.712441 263.95011-194.350362 336.307401h-0.008063z" fill="#F5222D" p-id="1507"></path><path d="M478.377323 313.110173a226.271748 226.271748 0 0 1 109.979212-31.219905l45.668788-26.761071c-58.634079-9.13537-118.316346 2.314079-170.612914 32.735748a258.693039 258.693039 0 0 0-111.91433 132.71685l45.67685-26.761071a230.359685 230.359685 0 0 1 81.097575-80.589606l0.104819-0.120945z m232.568945 397.674835a226.328189 226.328189 0 0 1-109.979213 31.227968l-45.668787 26.753008c58.634079 9.13537 118.316346-2.314079 170.612913-32.735748a258.709165 258.709165 0 0 0 111.914331-132.71685l-45.676851 26.761071a225.215496 225.215496 0 0 1-81.097574 80.597669l-0.104819 0.112882zM188.57726 706.938961l-10.062614-17.424126 109.938897-63.471874 9.578835 16.585574 17.093543-9.869102-18.770645-32.509984-63.689575 36.767244c-4.047622-3.918614-7.804976-7.337323-11.272063-10.24l-16.859717 13.747401c3.249386 2.144756 6.595528 4.458835 9.869103 7.038993l-62.173733 35.896441 19.254426 33.348535 17.093543-9.869102zM317.44 781.142677l-19.060913-33.017953 32.679307-18.867401 4.741039 8.216189 17.093543-9.869103-48.474708-83.959937-49.772851 28.736504-7.933984-13.747401-17.432189 10.062614 7.933984 13.747402-49.264882 28.446236 48.764977 84.459842 17.093543-9.869102-5.031307-8.708032 32.171339-18.585196 19.060913 33.017952 17.432189-10.062614z m-12.505701-97.126803l-32.679307 18.867402-8.321008-14.41663 32.679307-18.867402 8.321008 14.41663z m-50.111496 28.930016l-32.171338 18.577134-8.321008-14.41663 32.171338-18.577134 8.321008 14.41663z m16.932284 29.325102l-32.171339 18.577134-8.127496-14.077984 32.171339-18.577134 8.127496 14.077984z m50.111496-28.930016l-32.679307 18.867402-8.127496-14.077984 32.679307-18.867402 8.127496 14.077984z m95.828661 7.684032c11.062425-6.38589 13.368441-15.537386 6.692284-27.099717l-25.05978-43.411149c3.55578-4.289512 7.014803-8.740283 10.48189-13.199118l-9.482079-16.424315c-3.467087 4.458835-6.92611 8.917669-10.48189 13.199118l-17.803086-30.832882 14.755275-8.Line truncated
|
||||||
|
After Width: | Height: | Size: 11 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1724304256588" class="icon" viewBox="0 0 1300 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1272" xmlns:xlink="http://www.w3.org/1999/xlink" width="253.90625" height="200"><path d="M784.058182 99.258182l10.938182 18.385454-21.294546-2.56-14.196363 16.058182-4.072728-21.061818-19.781818-8.494545 18.734546-10.472728 2.094545-21.294545 15.709091 14.545454 20.945454-4.654545-9.076363 19.549091zM1067.287273 642.443636l-18.501818 10.821819 2.56-21.294546-16.058182-14.196364 21.061818-4.072727 8.494545-19.665454 10.472728 18.734545 21.294545 1.978182-14.661818 15.709091 4.770909 20.945454-19.432727-8.96z" fill="#2196F3" p-id="1273"></path><path d="M1067.287273 642.443636l-18.501818 10.821819 2.56-21.294546-16.058182-14.196364 21.061818-4.072727 8.494545-19.665454 10.472728 18.734545 21.294545 1.978182-14.661818 15.709091 4.770909 20.945454-19.432727-8.96zM571.927273 100.072727l-17.454546-12.567272 20.596364-6.167273 6.516364-20.48 12.218181 17.570909 21.410909-0.116364-12.916363 17.105455 6.749091 20.363636-20.247273-6.981818-17.338182 12.683636 0.465455-21.410909zM991.418182 784.407273l-21.178182 3.490909 10.123636-18.967273-9.774545-18.967273 21.061818 3.723637 15.127273-15.243637 2.909091 21.294546 19.2 9.658182-19.316364 9.309091-3.258182 21.178181-14.894545-15.476363zM427.985455 156.741818L407.272727 151.505455l16.872728-13.265455-1.396364-21.410909 17.803636 11.985454 20.014546-7.912727-5.934546 20.596364 13.730909 16.523636-21.410909 0.814546-11.52 18.152727-7.447272-20.247273zM854.225455 896.465455l-20.712728-5.352728 16.872728-13.265454-1.396364-21.294546 17.803636 11.869091 20.014546-7.912727-5.934546 20.712727 13.730909 16.523637-21.527272 0.814545-11.403637 18.036364-7.447272-20.130909zM562.501818 923.694545l10.821818 18.385455-21.294545-2.56-14.196364 16.058182-4.072727-21.061818-19.665455-8.494546 18.734546-10.356363 1.978182-21.41091 15.709091 14.661819 20.945454-4.770909-8.96 19.54909zM242.734545 420.770909l-18.385454 10.938182 2.56-21.294546-16.058182-14.196363 21.061818-4.189091 8.494546-19.665455 10.356363 18.734546 21.410909 2.094545-14.545454 15.709091 4.654545 20.945455-19.549091-9.076364z" fill="#2196F3" p-id="1274"></path><path d="M242.734545 420.770909l-18.385454 10.938182 2.56-21.294546-16.058182-14.196363 21.061818-4.189091 8.494546-19.665455 10.356363 18.734546 21.410909 2.094545-14.545454 15.709091 4.654545 20.945455-19.549091-9.076364zM700.858182 943.941818l-17.454546-12.450909 20.48-6.283636 6.516364-20.48 12.334545 17.687272 21.41091-0.116363-12.916364 17.105454 6.632727 20.363637-20.247273-7.098182-17.221818 12.683636 0.465455-21.410909zM303.592727 278.807273l-21.178182 3.490909 10.123637-18.967273-9.890909-18.967273 21.178182 3.723637 15.010909-15.243637 2.909091 21.294546 19.2 9.541818-19.316364 9.425455-3.258182 21.178181-14.778182-15.476363z" fill="#2196F3" p-id="1275"></path><path d="M407.272727 90.647273a486.632727 486.632727 0 0 1 504.552728 11.636363l25.018181-14.429091A512 512 0 0 0 139.636364 546.909091l25.018181-14.429091A486.981818 486.981818 0 0 1 407.272727 90.647273zM893.323636 933.352727a486.749091 486.749091 0 0 1-504.669091-11.636363l-24.901818 14.429091A512 512 0 0 0 1161.192727 477.090909l-24.901818 13.963636a486.981818 486.981818 0 0 1-242.967273 442.298182z" fill="#2196F3" p-id="1276"></path><path d="M814.545455 795.927273a327.447273 327.447273 0 0 1-258.21091 29.556363l-29.78909 17.105455A353.163636 353.163636 0 0 0 998.865455 570.181818l-29.789091 17.105455A326.865455 326.865455 0 0 1 814.545455 795.927273zM486.865455 228.072727A327.447273 327.447273 0 0 1 744.727273 198.516364l29.789091-17.105455A353.163636 353.163636 0 0 0 302.545455 453.818182l29.78909-17.105455A326.865455 326.865455 0 0 1 486.865455 228.072727zM1288.378182 374.690909a53.294545 53.294545 0 0 1-14.429091 11.636364L229.469091 989.090909a53.876364 53.876364 0 0 1-73.425455-19.665454L7.214545 710.632727a53.527273 53.527273 0 0 1 19.781819-73.309091L1071.476364 34.909091a53.876364 53.876364 0 0 1 73.425454 19.665454l148.829091 258.327273a53.061818 53.061818 0 0 1 5.352727 40.727273 55.272727 55.272727 0 0 1-10.705454 21.061818zM32.232727 665.716364A28.043636 28.043636 0 0 0 29.323636 698.181818l148.829091 257.978182a28.392727 28.392727 0 0 0 38.516364 10.356364l1044.48-601.949091a28.16 28.16 0 0 0 10.356364-38.516364L1122.676364 67.84a28.276364 28.276364 0 0 0-38.4-10.356364L39.68 659.432727a27.810909 27.810909 0 0 0-7.447273 6.283637z" fill="#2196F3" p-id="1277"></path><path d="M477.090909 500.945455l22.109091 38.283636-15.36 8.843636-13.963636-24.436363-151.272728 87.621818 14.545455 25.134545-15.243636 8.843637-23.272728-39.330909L377.949091 558.545455c-6.050909-4.887273-11.636364-8.843636-15.825455-11.636364l14.894546-12.450909c3.956364 3.141818 9.658182 8.145455 17.105454 14.894545zM459.869091 698.181818l-48.407273 28.043637 7.44727Line truncated
|
||||||
|
After Width: | Height: | Size: 7.4 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg width="22" height="22" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path fill="#FAFAFA" d="M0 0h22v22H0z"/><circle fill="#919BAE" cx="1" cy="1" r="1"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 192 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg t="1729561814171" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1359" width="200" height="200"><path d="M674.496 603.456c120.256 0 218.176 90.752 221.44 203.84l0.064 5.888v125.888c0 11.52-9.92 20.928-22.144 20.928h-44.352a21.568 21.568 0 0 1-22.144-20.928v-125.888c0-67.712-56.512-123.264-128-125.76l-4.928-0.064H349.568c-71.488 0-130.176 53.504-132.864 121.152l-0.064 4.672v125.888c0 11.52-9.92 20.928-22.144 20.928h-44.352A21.568 21.568 0 0 1 128 939.072v-125.888c0-113.92 95.872-206.528 215.36-209.664l6.208-0.064h324.928zM497.216 128c122.368 0 221.568 93.888 221.568 209.728s-99.2 209.792-221.568 209.792c-122.304 0-221.44-93.952-221.44-209.728C275.712 221.952 374.848 128 497.152 128z m0 83.904c-73.408 0-132.864 56.32-132.864 125.888 0 69.504 59.52 125.824 132.864 125.824 73.408 0 132.928-56.32 132.928-125.824 0-69.504-59.52-125.888-132.928-125.888z" fill="#fff" p-id="1360"></path></svg>
|
||||||
|
After Width: | Height: | Size: 947 B |
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1724297262365" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1396" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M707.91 103c16.28 0 29.522 13.007 29.897 29.195l0.009 0.706v111.878a29.96 29.96 0 0 1-0.898 7.3l171.177-0.001c16.28 0 29.522 13.007 29.897 29.195l0.008 0.706v637.12c0 16.278-13.01 29.518-29.2 29.893l-0.705 0.008H270.884c-16.28 0-29.522-13.007-29.897-29.195l-0.008-0.706V787.274c0-16.514 13.389-29.9 29.905-29.9 16.28 0 29.522 13.007 29.897 29.194l0.008 0.706v101.924h577.4V311.88h-577.4v88.787c0 16.278-13.009 29.518-29.2 29.893l-0.705 0.008c-16.28 0-29.522-13.008-29.897-29.195l-0.008-0.706V281.979c0-16.278 13.009-29.518 29.2-29.893l0.705-0.008h408.019a29.916 29.916 0 0 1-0.89-6.593l-0.008-0.706v-81.978H132.808v407.113h385.787L408.223 456.982c-11.36-11.624-11.329-30.143-0.066-41.729l0.554-0.555c11.625-11.358 30.147-11.327 41.734-0.066l0.555 0.554 161.028 164.762c11.244 11.504 11.344 29.793 0.362 41.42l-0.55 0.565-161.027 161.849c-11.648 11.707-30.583 11.757-42.292 0.11-11.524-11.461-11.754-29.979-0.657-41.723l0.546-0.563 111.319-111.89H102.905c-16.28 0-29.522-13.007-29.897-29.195l-0.008-0.705V132.9c0-16.278 13.01-29.518 29.2-29.893l0.705-0.008H707.91z" p-id="1397"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -5,6 +5,7 @@ export interface AppLinkGroup {
|
|||||||
// 链接列表
|
// 链接列表
|
||||||
links: AppLink[]
|
links: AppLink[]
|
||||||
}
|
}
|
||||||
|
|
||||||
// APP 链接
|
// APP 链接
|
||||||
export interface AppLink {
|
export interface AppLink {
|
||||||
// 链接名称
|
// 链接名称
|
||||||
@@ -21,6 +22,8 @@ export const enum APP_LINK_TYPE_ENUM {
|
|||||||
ACTIVITY_COMBINATION,
|
ACTIVITY_COMBINATION,
|
||||||
// 秒杀活动
|
// 秒杀活动
|
||||||
ACTIVITY_SECKILL,
|
ACTIVITY_SECKILL,
|
||||||
|
// 积分商城活动
|
||||||
|
ACTIVITY_POINT,
|
||||||
// 文章详情
|
// 文章详情
|
||||||
ARTICLE_DETAIL,
|
ARTICLE_DETAIL,
|
||||||
// 优惠券详情
|
// 优惠券详情
|
||||||
@@ -130,6 +133,11 @@ export const APP_LINK_GROUP_LIST = [
|
|||||||
path: '/pages/activity/seckill/list',
|
path: '/pages/activity/seckill/list',
|
||||||
type: APP_LINK_TYPE_ENUM.ACTIVITY_SECKILL
|
type: APP_LINK_TYPE_ENUM.ACTIVITY_SECKILL
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: '积分商城活动',
|
||||||
|
path: '/pages/activity/point/list',
|
||||||
|
type: APP_LINK_TYPE_ENUM.ACTIVITY_POINT
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: '签到中心',
|
name: '签到中心',
|
||||||
path: '/pages/app/sign'
|
path: '/pages/app/sign'
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const prefixCls = getPrefixCls('content-wrap')
|
|||||||
defineProps({
|
defineProps({
|
||||||
title: propTypes.string.def(''),
|
title: propTypes.string.def(''),
|
||||||
message: propTypes.string.def(''),
|
message: propTypes.string.def(''),
|
||||||
bodyStyle: propTypes.object.def({ padding: '20px' })
|
bodyStyle: propTypes.object.def({ padding: '10px' })
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -548,10 +548,10 @@ const inputChange = () => {
|
|||||||
<el-form>
|
<el-form>
|
||||||
<el-form-item label="类型">
|
<el-form-item label="类型">
|
||||||
<el-radio-group v-model="cronValue.second.type">
|
<el-radio-group v-model="cronValue.second.type">
|
||||||
<el-radio-button label="0">任意值</el-radio-button>
|
<el-radio-button value="0">任意值</el-radio-button>
|
||||||
<el-radio-button label="1">范围</el-radio-button>
|
<el-radio-button value="1">范围</el-radio-button>
|
||||||
<el-radio-button label="2">间隔</el-radio-button>
|
<el-radio-button value="2">间隔</el-radio-button>
|
||||||
<el-radio-button label="3">指定</el-radio-button>
|
<el-radio-button value="3">指定</el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="cronValue.second.type == '1'" label="范围">
|
<el-form-item v-if="cronValue.second.type == '1'" label="范围">
|
||||||
@@ -607,10 +607,10 @@ const inputChange = () => {
|
|||||||
<el-form>
|
<el-form>
|
||||||
<el-form-item label="类型">
|
<el-form-item label="类型">
|
||||||
<el-radio-group v-model="cronValue.minute.type">
|
<el-radio-group v-model="cronValue.minute.type">
|
||||||
<el-radio-button label="0">任意值</el-radio-button>
|
<el-radio-button value="0">任意值</el-radio-button>
|
||||||
<el-radio-button label="1">范围</el-radio-button>
|
<el-radio-button value="1">范围</el-radio-button>
|
||||||
<el-radio-button label="2">间隔</el-radio-button>
|
<el-radio-button value="2">间隔</el-radio-button>
|
||||||
<el-radio-button label="3">指定</el-radio-button>
|
<el-radio-button value="3">指定</el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="cronValue.minute.type == '1'" label="范围">
|
<el-form-item v-if="cronValue.minute.type == '1'" label="范围">
|
||||||
@@ -666,10 +666,10 @@ const inputChange = () => {
|
|||||||
<el-form>
|
<el-form>
|
||||||
<el-form-item label="类型">
|
<el-form-item label="类型">
|
||||||
<el-radio-group v-model="cronValue.hour.type">
|
<el-radio-group v-model="cronValue.hour.type">
|
||||||
<el-radio-button label="0">任意值</el-radio-button>
|
<el-radio-button value="0">任意值</el-radio-button>
|
||||||
<el-radio-button label="1">范围</el-radio-button>
|
<el-radio-button value="1">范围</el-radio-button>
|
||||||
<el-radio-button label="2">间隔</el-radio-button>
|
<el-radio-button value="2">间隔</el-radio-button>
|
||||||
<el-radio-button label="3">指定</el-radio-button>
|
<el-radio-button value="3">指定</el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="cronValue.hour.type == '1'" label="范围">
|
<el-form-item v-if="cronValue.hour.type == '1'" label="范围">
|
||||||
@@ -725,12 +725,12 @@ const inputChange = () => {
|
|||||||
<el-form>
|
<el-form>
|
||||||
<el-form-item label="类型">
|
<el-form-item label="类型">
|
||||||
<el-radio-group v-model="cronValue.day.type">
|
<el-radio-group v-model="cronValue.day.type">
|
||||||
<el-radio-button label="0">任意值</el-radio-button>
|
<el-radio-button value="0">任意值</el-radio-button>
|
||||||
<el-radio-button label="1">范围</el-radio-button>
|
<el-radio-button value="1">范围</el-radio-button>
|
||||||
<el-radio-button label="2">间隔</el-radio-button>
|
<el-radio-button value="2">间隔</el-radio-button>
|
||||||
<el-radio-button label="3">指定</el-radio-button>
|
<el-radio-button value="3">指定</el-radio-button>
|
||||||
<el-radio-button label="4">本月最后一天</el-radio-button>
|
<el-radio-button value="4">本月最后一天</el-radio-button>
|
||||||
<el-radio-button label="5">不指定</el-radio-button>
|
<el-radio-button value="5">不指定</el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="cronValue.day.type == '1'" label="范围">
|
<el-form-item v-if="cronValue.day.type == '1'" label="范围">
|
||||||
@@ -786,10 +786,10 @@ const inputChange = () => {
|
|||||||
<el-form>
|
<el-form>
|
||||||
<el-form-item label="类型">
|
<el-form-item label="类型">
|
||||||
<el-radio-group v-model="cronValue.month.type">
|
<el-radio-group v-model="cronValue.month.type">
|
||||||
<el-radio-button label="0">任意值</el-radio-button>
|
<el-radio-button value="0">任意值</el-radio-button>
|
||||||
<el-radio-button label="1">范围</el-radio-button>
|
<el-radio-button value="1">范围</el-radio-button>
|
||||||
<el-radio-button label="2">间隔</el-radio-button>
|
<el-radio-button value="2">间隔</el-radio-button>
|
||||||
<el-radio-button label="3">指定</el-radio-button>
|
<el-radio-button value="3">指定</el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="cronValue.month.type == '1'" label="范围">
|
<el-form-item v-if="cronValue.month.type == '1'" label="范围">
|
||||||
@@ -846,12 +846,12 @@ const inputChange = () => {
|
|||||||
<el-form>
|
<el-form>
|
||||||
<el-form-item label="类型">
|
<el-form-item label="类型">
|
||||||
<el-radio-group v-model="cronValue.week.type">
|
<el-radio-group v-model="cronValue.week.type">
|
||||||
<el-radio-button label="0">任意值</el-radio-button>
|
<el-radio-button value="0">任意值</el-radio-button>
|
||||||
<el-radio-button label="1">范围</el-radio-button>
|
<el-radio-button value="1">范围</el-radio-button>
|
||||||
<el-radio-button label="2">间隔</el-radio-button>
|
<el-radio-button value="2">间隔</el-radio-button>
|
||||||
<el-radio-button label="3">指定</el-radio-button>
|
<el-radio-button value="3">指定</el-radio-button>
|
||||||
<el-radio-button label="4">本月最后一周</el-radio-button>
|
<el-radio-button value="4">本月最后一周</el-radio-button>
|
||||||
<el-radio-button label="5">不指定</el-radio-button>
|
<el-radio-button value="5">不指定</el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="cronValue.week.type == '1'" label="范围">
|
<el-form-item v-if="cronValue.week.type == '1'" label="范围">
|
||||||
@@ -925,11 +925,11 @@ const inputChange = () => {
|
|||||||
<el-form>
|
<el-form>
|
||||||
<el-form-item label="类型">
|
<el-form-item label="类型">
|
||||||
<el-radio-group v-model="cronValue.year.type">
|
<el-radio-group v-model="cronValue.year.type">
|
||||||
<el-radio-button label="-1">忽略</el-radio-button>
|
<el-radio-button value="-1">忽略</el-radio-button>
|
||||||
<el-radio-button label="0">任意值</el-radio-button>
|
<el-radio-button value="0">任意值</el-radio-button>
|
||||||
<el-radio-button label="1">范围</el-radio-button>
|
<el-radio-button value="1">范围</el-radio-button>
|
||||||
<el-radio-button label="2">间隔</el-radio-button>
|
<el-radio-button value="2">间隔</el-radio-button>
|
||||||
<el-radio-button label="3">指定</el-radio-button>
|
<el-radio-button value="3">指定</el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="cronValue.year.type == '1'" label="范围">
|
<el-form-item v-if="cronValue.year.type == '1'" label="范围">
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
<script lang="tsx">
|
<script lang="tsx">
|
||||||
import { defineComponent, PropType, ref } from 'vue'
|
import { computed, defineComponent, PropType } from 'vue'
|
||||||
import { isHexColor } from '@/utils/color'
|
import { isHexColor } from '@/utils/color'
|
||||||
import { ElTag } from 'element-plus'
|
import { ElTag } from 'element-plus'
|
||||||
import { DictDataType, getDictOptions } from '@/utils/dict'
|
import { DictDataType, getDictOptions } from '@/utils/dict'
|
||||||
|
import { isArray, isBoolean, isNumber, isString } from '@/utils/is'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'DictTag',
|
name: 'DictTag',
|
||||||
@@ -12,49 +13,78 @@ export default defineComponent({
|
|||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
value: {
|
value: {
|
||||||
type: [String, Number, Boolean] as PropType<string | number | boolean>,
|
type: [String, Number, Boolean, Array],
|
||||||
required: true
|
required: true
|
||||||
|
},
|
||||||
|
// 字符串分隔符 只有当 props.value 传入值为字符串时有效
|
||||||
|
separator: {
|
||||||
|
type: String as PropType<string>,
|
||||||
|
default: ','
|
||||||
|
},
|
||||||
|
// 每个 tag 之间的间隔,默认为 5px,参考的 el-row 的 gutter
|
||||||
|
gutter: {
|
||||||
|
type: String as PropType<string>,
|
||||||
|
default: '5px'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const dictData = ref<DictDataType>()
|
const valueArr: any = computed(() => {
|
||||||
const getDictObj = (dictType: string, value: string) => {
|
// 1. 是 Number 类型和 Boolean 类型的情况
|
||||||
const dictOptions = getDictOptions(dictType)
|
if (isNumber(props.value) || isBoolean(props.value)) {
|
||||||
dictOptions.forEach((dict: DictDataType) => {
|
return [String(props.value)]
|
||||||
if (dict.value === value) {
|
}
|
||||||
if (dict.colorType + '' === 'default') {
|
// 2. 是字符串(进一步判断是否有包含分隔符号 -> props.sepSymbol )
|
||||||
dict.colorType = 'info'
|
else if (isString(props.value)) {
|
||||||
}
|
return props.value.split(props.separator)
|
||||||
dictData.value = dict
|
}
|
||||||
}
|
// 3. 数组
|
||||||
})
|
else if (isArray(props.value)) {
|
||||||
}
|
return props.value.map(String)
|
||||||
const rederDictTag = () => {
|
}
|
||||||
|
return []
|
||||||
|
})
|
||||||
|
const renderDictTag = () => {
|
||||||
if (!props.type) {
|
if (!props.type) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
// 解决自定义字典标签值为零时标签不渲染的问题
|
// 解决自定义字典标签值为零时标签不渲染的问题
|
||||||
if (props.value === undefined || props.value === null) {
|
if (props.value === undefined || props.value === null || props.value === '') {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
getDictObj(props.type, props.value.toString())
|
const dictOptions = getDictOptions(props.type)
|
||||||
// 添加标签的文字颜色为白色,解决自定义背景颜色时标签文字看不清的问题
|
|
||||||
return (
|
return (
|
||||||
<ElTag
|
<div
|
||||||
style={dictData.value?.cssClass ? 'color: #fff' : ''}
|
class="dict-tag"
|
||||||
type={dictData.value?.colorType}
|
style={{
|
||||||
color={
|
display: 'inline-flex',
|
||||||
dictData.value?.cssClass && isHexColor(dictData.value?.cssClass)
|
gap: props.gutter,
|
||||||
? dictData.value?.cssClass
|
justifyContent: 'center',
|
||||||
: ''
|
alignItems: 'center'
|
||||||
}
|
}}
|
||||||
disableTransitions={true}
|
|
||||||
>
|
>
|
||||||
{dictData.value?.label}
|
{dictOptions.map((dict: DictDataType) => {
|
||||||
</ElTag>
|
if (valueArr.value.includes(dict.value)) {
|
||||||
|
if (dict.colorType + '' === 'primary' || dict.colorType + '' === 'default') {
|
||||||
|
dict.colorType = ''
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
// 添加标签的文字颜色为白色,解决自定义背景颜色时标签文字看不清的问题
|
||||||
|
<ElTag
|
||||||
|
style={dict?.cssClass ? 'color: #fff' : ''}
|
||||||
|
type={dict?.colorType || null}
|
||||||
|
color={dict?.cssClass && isHexColor(dict?.cssClass) ? dict?.cssClass : ''}
|
||||||
|
disableTransitions={true}
|
||||||
|
>
|
||||||
|
{dict?.label}
|
||||||
|
</ElTag>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return () => rederDictTag()
|
return () => renderDictTag()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
@@ -165,6 +165,7 @@ $toolbar-position: -55px;
|
|||||||
width: 80px;
|
width: 80px;
|
||||||
height: 25px;
|
height: 25px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
color: #6a6a6a;
|
||||||
line-height: 25px;
|
line-height: 25px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
|||||||
@@ -11,8 +11,8 @@
|
|||||||
<el-form :model="formData" label-width="80px">
|
<el-form :model="formData" label-width="80px">
|
||||||
<el-form-item label="组件背景" prop="bgType">
|
<el-form-item label="组件背景" prop="bgType">
|
||||||
<el-radio-group v-model="formData.bgType">
|
<el-radio-group v-model="formData.bgType">
|
||||||
<el-radio label="color">纯色</el-radio>
|
<el-radio value="color">纯色</el-radio>
|
||||||
<el-radio label="img">图片</el-radio>
|
<el-radio value="img">图片</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="选择颜色" prop="bgColor" v-if="formData.bgType === 'color'">
|
<el-form-item label="选择颜色" prop="bgColor" v-if="formData.bgType === 'color'">
|
||||||
|
|||||||
@@ -5,12 +5,12 @@
|
|||||||
<el-form-item label="样式" prop="type">
|
<el-form-item label="样式" prop="type">
|
||||||
<el-radio-group v-model="formData.type">
|
<el-radio-group v-model="formData.type">
|
||||||
<el-tooltip class="item" content="默认" placement="bottom">
|
<el-tooltip class="item" content="默认" placement="bottom">
|
||||||
<el-radio-button label="default">
|
<el-radio-button value="default">
|
||||||
<Icon icon="system-uicons:carousel" />
|
<Icon icon="system-uicons:carousel" />
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip class="item" content="卡片" placement="bottom">
|
<el-tooltip class="item" content="卡片" placement="bottom">
|
||||||
<el-radio-button label="card">
|
<el-radio-button value="card">
|
||||||
<Icon icon="ic:round-view-carousel" />
|
<Icon icon="ic:round-view-carousel" />
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
@@ -18,8 +18,8 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="指示器" prop="indicator">
|
<el-form-item label="指示器" prop="indicator">
|
||||||
<el-radio-group v-model="formData.indicator">
|
<el-radio-group v-model="formData.indicator">
|
||||||
<el-radio label="dot">小圆点</el-radio>
|
<el-radio value="dot">小圆点</el-radio>
|
||||||
<el-radio label="number">数字</el-radio>
|
<el-radio value="number">数字</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="是否轮播" prop="autoplay">
|
<el-form-item label="是否轮播" prop="autoplay">
|
||||||
@@ -43,8 +43,8 @@
|
|||||||
<template #default="{ element }">
|
<template #default="{ element }">
|
||||||
<el-form-item label="类型" prop="type" class="m-b-8px!" label-width="40px">
|
<el-form-item label="类型" prop="type" class="m-b-8px!" label-width="40px">
|
||||||
<el-radio-group v-model="element.type">
|
<el-radio-group v-model="element.type">
|
||||||
<el-radio label="img">图片</el-radio>
|
<el-radio value="img">图片</el-radio>
|
||||||
<el-radio label="video">视频</el-radio>
|
<el-radio value="video">视频</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
|
|||||||
@@ -26,17 +26,17 @@
|
|||||||
<el-form-item label="列数" prop="type">
|
<el-form-item label="列数" prop="type">
|
||||||
<el-radio-group v-model="formData.columns">
|
<el-radio-group v-model="formData.columns">
|
||||||
<el-tooltip class="item" content="一列" placement="bottom">
|
<el-tooltip class="item" content="一列" placement="bottom">
|
||||||
<el-radio-button :label="1">
|
<el-radio-button :value="1">
|
||||||
<Icon icon="fluent:text-column-one-24-filled" />
|
<Icon icon="fluent:text-column-one-24-filled" />
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip class="item" content="二列" placement="bottom">
|
<el-tooltip class="item" content="二列" placement="bottom">
|
||||||
<el-radio-button :label="2">
|
<el-radio-button :value="2">
|
||||||
<Icon icon="fluent:text-column-two-24-filled" />
|
<Icon icon="fluent:text-column-two-24-filled" />
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip class="item" content="三列" placement="bottom">
|
<el-tooltip class="item" content="三列" placement="bottom">
|
||||||
<el-radio-button :label="3">
|
<el-radio-button :value="3">
|
||||||
<Icon icon="fluent:text-column-three-24-filled" />
|
<Icon icon="fluent:text-column-three-24-filled" />
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
:key="index"
|
:key="index"
|
||||||
:content="item.text"
|
:content="item.text"
|
||||||
>
|
>
|
||||||
<el-radio-button :label="item.type">
|
<el-radio-button :value="item.type">
|
||||||
<Icon :icon="item.icon" />
|
<Icon :icon="item.icon" />
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
@@ -24,12 +24,12 @@
|
|||||||
<el-form-item label="左右边距" prop="paddingType">
|
<el-form-item label="左右边距" prop="paddingType">
|
||||||
<el-radio-group v-model="formData!.paddingType">
|
<el-radio-group v-model="formData!.paddingType">
|
||||||
<el-tooltip content="无边距" placement="top">
|
<el-tooltip content="无边距" placement="top">
|
||||||
<el-radio-button label="none">
|
<el-radio-button value="none">
|
||||||
<Icon icon="tabler:box-padding" />
|
<Icon icon="tabler:box-padding" />
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip content="左右留边" placement="top">
|
<el-tooltip content="左右留边" placement="top">
|
||||||
<el-radio-button label="horizontal">
|
<el-radio-button value="horizontal">
|
||||||
<Icon icon="vaadin:padding" />
|
<Icon icon="vaadin:padding" />
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ defineOptions({ name: 'FloatingActionButton' })
|
|||||||
defineProps<{ property: FloatingActionButtonProperty }>()
|
defineProps<{ property: FloatingActionButtonProperty }>()
|
||||||
|
|
||||||
// 是否展开
|
// 是否展开
|
||||||
const expanded = ref(true)
|
const expanded = ref(false)
|
||||||
// 处理展开/折叠
|
// 处理展开/折叠
|
||||||
const handleToggleFab = () => {
|
const handleToggleFab = () => {
|
||||||
expanded.value = !expanded.value
|
expanded.value = !expanded.value
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
<el-card header="按钮配置" class="property-group" shadow="never">
|
<el-card header="按钮配置" class="property-group" shadow="never">
|
||||||
<el-form-item label="展开方向" prop="direction">
|
<el-form-item label="展开方向" prop="direction">
|
||||||
<el-radio-group v-model="formData.direction">
|
<el-radio-group v-model="formData.direction">
|
||||||
<el-radio label="vertical">垂直</el-radio>
|
<el-radio value="vertical">垂直</el-radio>
|
||||||
<el-radio label="horizontal">水平</el-radio>
|
<el-radio value="horizontal">水平</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="显示文字" prop="showText">
|
<el-form-item label="显示文字" prop="showText">
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
<el-form label-width="80px" :model="formData" class="m-t-8px">
|
<el-form label-width="80px" :model="formData" class="m-t-8px">
|
||||||
<el-form-item label="每行数量" prop="column">
|
<el-form-item label="每行数量" prop="column">
|
||||||
<el-radio-group v-model="formData.column">
|
<el-radio-group v-model="formData.column">
|
||||||
<el-radio :label="3">3个</el-radio>
|
<el-radio :value="3">3个</el-radio>
|
||||||
<el-radio :label="4">4个</el-radio>
|
<el-radio :value="4">4个</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
|||||||
@@ -4,21 +4,21 @@
|
|||||||
<el-form label-width="80px" :model="formData" class="m-t-8px">
|
<el-form label-width="80px" :model="formData" class="m-t-8px">
|
||||||
<el-form-item label="布局" prop="layout">
|
<el-form-item label="布局" prop="layout">
|
||||||
<el-radio-group v-model="formData.layout">
|
<el-radio-group v-model="formData.layout">
|
||||||
<el-radio label="iconText">图标+文字</el-radio>
|
<el-radio value="iconText">图标+文字</el-radio>
|
||||||
<el-radio label="icon">仅图标</el-radio>
|
<el-radio value="icon">仅图标</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="行数" prop="row">
|
<el-form-item label="行数" prop="row">
|
||||||
<el-radio-group v-model="formData.row">
|
<el-radio-group v-model="formData.row">
|
||||||
<el-radio :label="1">1行</el-radio>
|
<el-radio :value="1">1行</el-radio>
|
||||||
<el-radio :label="2">2行</el-radio>
|
<el-radio :value="2">2行</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="列数" prop="column">
|
<el-form-item label="列数" prop="column">
|
||||||
<el-radio-group v-model="formData.column">
|
<el-radio-group v-model="formData.column">
|
||||||
<el-radio :label="3">3列</el-radio>
|
<el-radio :value="3">3列</el-radio>
|
||||||
<el-radio :label="4">4列</el-radio>
|
<el-radio :value="4">4列</el-radio>
|
||||||
<el-radio :label="5">5列</el-radio>
|
<el-radio :value="5">5列</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
|||||||
@@ -2,56 +2,59 @@
|
|||||||
<div class="h-40px flex items-center justify-center">
|
<div class="h-40px flex items-center justify-center">
|
||||||
<MagicCubeEditor
|
<MagicCubeEditor
|
||||||
v-model="cellList"
|
v-model="cellList"
|
||||||
class="m-b-16px"
|
|
||||||
:rows="1"
|
|
||||||
:cols="cellCount"
|
:cols="cellCount"
|
||||||
:cube-size="38"
|
:cube-size="38"
|
||||||
|
:rows="1"
|
||||||
|
class="m-b-16px"
|
||||||
@hot-area-selected="handleHotAreaSelected"
|
@hot-area-selected="handleHotAreaSelected"
|
||||||
/>
|
/>
|
||||||
<img src="@/assets/imgs/diy/app-nav-bar-mp.png" alt="" class="h-30px w-76px" v-if="isMp" />
|
<img v-if="isMp" alt="" class="h-30px w-76px" src="@/assets/imgs/diy/app-nav-bar-mp.png" />
|
||||||
</div>
|
</div>
|
||||||
<template v-for="(cell, cellIndex) in cellList" :key="cellIndex">
|
<template v-for="(cell, cellIndex) in cellList" :key="cellIndex">
|
||||||
<template v-if="selectedHotAreaIndex === cellIndex">
|
<template v-if="selectedHotAreaIndex === cellIndex">
|
||||||
<el-form-item label="类型" :prop="`cell[${cellIndex}].type`">
|
<el-form-item :prop="`cell[${cellIndex}].type`" label="类型">
|
||||||
<el-radio-group v-model="cell.type">
|
<el-radio-group v-model="cell.type">
|
||||||
<el-radio label="text">文字</el-radio>
|
<el-radio value="text">文字</el-radio>
|
||||||
<el-radio label="image">图片</el-radio>
|
<el-radio value="image">图片</el-radio>
|
||||||
<el-radio label="search">搜索框</el-radio>
|
<el-radio value="search">搜索框</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 1. 文字 -->
|
<!-- 1. 文字 -->
|
||||||
<template v-if="cell.type === 'text'">
|
<template v-if="cell.type === 'text'">
|
||||||
<el-form-item label="内容" :prop="`cell[${cellIndex}].text`">
|
<el-form-item :prop="`cell[${cellIndex}].text`" label="内容">
|
||||||
<el-input v-model="cell!.text" maxlength="10" show-word-limit />
|
<el-input v-model="cell!.text" maxlength="10" show-word-limit />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="颜色" :prop="`cell[${cellIndex}].text`">
|
<el-form-item :prop="`cell[${cellIndex}].text`" label="颜色">
|
||||||
<ColorInput v-model="cell!.textColor" />
|
<ColorInput v-model="cell!.textColor" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item :prop="`cell[${cellIndex}].url`" label="链接">
|
||||||
|
<AppLinkInput v-model="cell.url" />
|
||||||
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
<!-- 2. 图片 -->
|
<!-- 2. 图片 -->
|
||||||
<template v-else-if="cell.type === 'image'">
|
<template v-else-if="cell.type === 'image'">
|
||||||
<el-form-item label="图片" :prop="`cell[${cellIndex}].imgUrl`">
|
<el-form-item :prop="`cell[${cellIndex}].imgUrl`" label="图片">
|
||||||
<UploadImg v-model="cell.imgUrl" :limit="1" height="56px" width="56px">
|
<UploadImg v-model="cell.imgUrl" :limit="1" height="56px" width="56px">
|
||||||
<template #tip>建议尺寸 56*56</template>
|
<template #tip>建议尺寸 56*56</template>
|
||||||
</UploadImg>
|
</UploadImg>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="链接" :prop="`cell[${cellIndex}].url`">
|
<el-form-item :prop="`cell[${cellIndex}].url`" label="链接">
|
||||||
<AppLinkInput v-model="cell.url" />
|
<AppLinkInput v-model="cell.url" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
<!-- 3. 搜索框 -->
|
<!-- 3. 搜索框 -->
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<el-form-item label="提示文字" :prop="`cell[${cellIndex}].placeholder`">
|
<el-form-item :prop="`cell[${cellIndex}].placeholder`" label="提示文字">
|
||||||
<el-input v-model="cell.placeholder" maxlength="10" show-word-limit />
|
<el-input v-model="cell.placeholder" maxlength="10" show-word-limit />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="圆角" :prop="`cell[${cellIndex}].borderRadius`">
|
<el-form-item :prop="`cell[${cellIndex}].borderRadius`" label="圆角">
|
||||||
<el-slider
|
<el-slider
|
||||||
v-model="cell.borderRadius"
|
v-model="cell.borderRadius"
|
||||||
:max="100"
|
:max="100"
|
||||||
:min="0"
|
:min="0"
|
||||||
show-input
|
|
||||||
input-size="small"
|
|
||||||
:show-input-controls="false"
|
:show-input-controls="false"
|
||||||
|
input-size="small"
|
||||||
|
show-input
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
@@ -59,7 +62,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script lang="ts" setup>
|
||||||
import { NavigationBarCellProperty } from '../config'
|
import { NavigationBarCellProperty } from '../config'
|
||||||
import { usePropertyForm } from '@/components/DiyEditor/util'
|
import { usePropertyForm } from '@/components/DiyEditor/util'
|
||||||
// 导航栏属性面板
|
// 导航栏属性面板
|
||||||
@@ -87,4 +90,4 @@ const handleHotAreaSelected = (cellValue: NavigationBarCellProperty, index: numb
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss"></style>
|
<style lang="scss" scoped></style>
|
||||||
@@ -2,27 +2,27 @@
|
|||||||
<el-form label-width="80px" :model="formData" :rules="rules">
|
<el-form label-width="80px" :model="formData" :rules="rules">
|
||||||
<el-form-item label="样式" prop="styleType">
|
<el-form-item label="样式" prop="styleType">
|
||||||
<el-radio-group v-model="formData!.styleType">
|
<el-radio-group v-model="formData!.styleType">
|
||||||
<el-radio label="normal">标准</el-radio>
|
<el-radio value="normal">标准</el-radio>
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
content="沉侵式头部仅支持微信小程序、APP,建议页面第一个组件为图片展示类组件"
|
content="沉侵式头部仅支持微信小程序、APP,建议页面第一个组件为图片展示类组件"
|
||||||
placement="top"
|
placement="top"
|
||||||
>
|
>
|
||||||
<el-radio label="inner">沉浸式</el-radio>
|
<el-radio value="inner">沉浸式</el-radio>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="常驻显示" prop="alwaysShow" v-if="formData.styleType === 'inner'">
|
<el-form-item label="常驻显示" prop="alwaysShow" v-if="formData.styleType === 'inner'">
|
||||||
<el-radio-group v-model="formData!.alwaysShow">
|
<el-radio-group v-model="formData!.alwaysShow">
|
||||||
<el-radio :label="false">关闭</el-radio>
|
<el-radio :value="false">关闭</el-radio>
|
||||||
<el-tooltip content="常驻显示关闭后,头部小组件将在页面滑动时淡入" placement="top">
|
<el-tooltip content="常驻显示关闭后,头部小组件将在页面滑动时淡入" placement="top">
|
||||||
<el-radio :label="true">开启</el-radio>
|
<el-radio :value="true">开启</el-radio>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="背景类型" prop="bgType">
|
<el-form-item label="背景类型" prop="bgType">
|
||||||
<el-radio-group v-model="formData.bgType">
|
<el-radio-group v-model="formData.bgType">
|
||||||
<el-radio label="color">纯色</el-radio>
|
<el-radio value="color">纯色</el-radio>
|
||||||
<el-radio label="img">图片</el-radio>
|
<el-radio value="img">图片</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="背景颜色" prop="bgColor" v-if="formData.bgType === 'color'">
|
<el-form-item label="背景颜色" prop="bgColor" v-if="formData.bgType === 'color'">
|
||||||
|
|||||||
@@ -11,10 +11,10 @@
|
|||||||
<el-form-item label="显示次数" :prop="`list[${index}].showType`">
|
<el-form-item label="显示次数" :prop="`list[${index}].showType`">
|
||||||
<el-radio-group v-model="element.showType">
|
<el-radio-group v-model="element.showType">
|
||||||
<el-tooltip content="只显示一次,下次打开时不显示" placement="bottom">
|
<el-tooltip content="只显示一次,下次打开时不显示" placement="bottom">
|
||||||
<el-radio label="once">一次</el-radio>
|
<el-radio value="once">一次</el-radio>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip content="每次打开时都会显示" placement="bottom">
|
<el-tooltip content="每次打开时都会显示" placement="bottom">
|
||||||
<el-radio label="always">不限</el-radio>
|
<el-radio value="always">不限</el-radio>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|||||||
@@ -67,15 +67,15 @@
|
|||||||
class="text-16px"
|
class="text-16px"
|
||||||
:style="{ color: property.fields.price.color }"
|
:style="{ color: property.fields.price.color }"
|
||||||
>
|
>
|
||||||
¥{{ spu.price }}
|
¥{{ fenToYuan(spu.price as any) }}
|
||||||
</span>
|
</span>
|
||||||
<!-- 市场价 -->
|
<!-- 市场价 -->
|
||||||
<span
|
<span
|
||||||
v-if="property.fields.marketPrice.show && spu.marketPrice"
|
v-if="property.fields.marketPrice.show && spu.marketPrice"
|
||||||
class="ml-4px text-10px line-through"
|
class="ml-4px text-10px line-through"
|
||||||
:style="{ color: property.fields.marketPrice.color }"
|
:style="{ color: property.fields.marketPrice.color }"
|
||||||
>¥{{ spu.marketPrice }}</span
|
>¥{{ fenToYuan(spu.marketPrice) }}
|
||||||
>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-12px">
|
<div class="text-12px">
|
||||||
<!-- 销量 -->
|
<!-- 销量 -->
|
||||||
@@ -117,6 +117,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ProductCardProperty } from './config'
|
import { ProductCardProperty } from './config'
|
||||||
import * as ProductSpuApi from '@/api/mall/product/spu'
|
import * as ProductSpuApi from '@/api/mall/product/spu'
|
||||||
|
import { fenToYuan } from '../../../../../utils'
|
||||||
|
|
||||||
/** 商品卡片 */
|
/** 商品卡片 */
|
||||||
defineOptions({ name: 'ProductCard' })
|
defineOptions({ name: 'ProductCard' })
|
||||||
|
|||||||
@@ -8,17 +8,17 @@
|
|||||||
<el-form-item label="布局" prop="type">
|
<el-form-item label="布局" prop="type">
|
||||||
<el-radio-group v-model="formData.layoutType">
|
<el-radio-group v-model="formData.layoutType">
|
||||||
<el-tooltip class="item" content="单列大图" placement="bottom">
|
<el-tooltip class="item" content="单列大图" placement="bottom">
|
||||||
<el-radio-button label="oneColBigImg">
|
<el-radio-button value="oneColBigImg">
|
||||||
<Icon icon="fluent:text-column-one-24-filled" />
|
<Icon icon="fluent:text-column-one-24-filled" />
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip class="item" content="单列小图" placement="bottom">
|
<el-tooltip class="item" content="单列小图" placement="bottom">
|
||||||
<el-radio-button label="oneColSmallImg">
|
<el-radio-button value="oneColSmallImg">
|
||||||
<Icon icon="fluent:text-column-two-left-24-filled" />
|
<Icon icon="fluent:text-column-two-left-24-filled" />
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip class="item" content="双列" placement="bottom">
|
<el-tooltip class="item" content="双列" placement="bottom">
|
||||||
<el-radio-button label="twoCol">
|
<el-radio-button value="twoCol">
|
||||||
<Icon icon="fluent:text-column-two-24-filled" />
|
<Icon icon="fluent:text-column-two-24-filled" />
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
@@ -74,8 +74,8 @@
|
|||||||
<el-card header="按钮" class="property-group" shadow="never">
|
<el-card header="按钮" class="property-group" shadow="never">
|
||||||
<el-form-item label="按钮类型" prop="btnBuy.type">
|
<el-form-item label="按钮类型" prop="btnBuy.type">
|
||||||
<el-radio-group v-model="formData.btnBuy.type">
|
<el-radio-group v-model="formData.btnBuy.type">
|
||||||
<el-radio-button label="text">文字</el-radio-button>
|
<el-radio-button value="text">文字</el-radio-button>
|
||||||
<el-radio-button label="img">图片</el-radio-button>
|
<el-radio-button value="img">图片</el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<template v-if="formData.btnBuy.type === 'text'">
|
<template v-if="formData.btnBuy.type === 'text'">
|
||||||
|
|||||||
@@ -54,7 +54,7 @@
|
|||||||
class="text-12px"
|
class="text-12px"
|
||||||
:style="{ color: property.fields.price.color }"
|
:style="{ color: property.fields.price.color }"
|
||||||
>
|
>
|
||||||
¥{{ spu.price }}
|
¥{{ fenToYuan(spu.price) }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -65,6 +65,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ProductListProperty } from './config'
|
import { ProductListProperty } from './config'
|
||||||
import * as ProductSpuApi from '@/api/mall/product/spu'
|
import * as ProductSpuApi from '@/api/mall/product/spu'
|
||||||
|
import { fenToYuan } from '@/utils'
|
||||||
|
|
||||||
/** 商品栏 */
|
/** 商品栏 */
|
||||||
defineOptions({ name: 'ProductList' })
|
defineOptions({ name: 'ProductList' })
|
||||||
|
|||||||
@@ -8,17 +8,17 @@
|
|||||||
<el-form-item label="布局" prop="type">
|
<el-form-item label="布局" prop="type">
|
||||||
<el-radio-group v-model="formData.layoutType">
|
<el-radio-group v-model="formData.layoutType">
|
||||||
<el-tooltip class="item" content="双列" placement="bottom">
|
<el-tooltip class="item" content="双列" placement="bottom">
|
||||||
<el-radio-button label="twoCol">
|
<el-radio-button value="twoCol">
|
||||||
<Icon icon="fluent:text-column-two-24-filled" />
|
<Icon icon="fluent:text-column-two-24-filled" />
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip class="item" content="三列" placement="bottom">
|
<el-tooltip class="item" content="三列" placement="bottom">
|
||||||
<el-radio-button label="threeCol">
|
<el-radio-button value="threeCol">
|
||||||
<Icon icon="fluent:text-column-three-24-filled" />
|
<Icon icon="fluent:text-column-three-24-filled" />
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip class="item" content="水平滑动" placement="bottom">
|
<el-tooltip class="item" content="水平滑动" placement="bottom">
|
||||||
<el-radio-button label="horizSwiper">
|
<el-radio-button value="horizSwiper">
|
||||||
<Icon icon="system-uicons:carousel" />
|
<Icon icon="system-uicons:carousel" />
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|||||||
@@ -3,13 +3,21 @@ import { ComponentStyle, DiyComponent } from '@/components/DiyEditor/util'
|
|||||||
/** 拼团属性 */
|
/** 拼团属性 */
|
||||||
export interface PromotionCombinationProperty {
|
export interface PromotionCombinationProperty {
|
||||||
// 布局类型:单列 | 三列
|
// 布局类型:单列 | 三列
|
||||||
layoutType: 'oneCol' | 'threeCol'
|
layoutType: 'oneColBigImg' | 'oneColSmallImg' | 'twoCol'
|
||||||
// 商品字段
|
// 商品字段
|
||||||
fields: {
|
fields: {
|
||||||
// 商品名称
|
// 商品名称
|
||||||
name: PromotionCombinationFieldProperty
|
name: PromotionCombinationFieldProperty
|
||||||
|
// 商品简介
|
||||||
|
introduction: PromotionCombinationFieldProperty
|
||||||
// 商品价格
|
// 商品价格
|
||||||
price: PromotionCombinationFieldProperty
|
price: PromotionCombinationFieldProperty
|
||||||
|
// 市场价
|
||||||
|
marketPrice: PromotionCombinationFieldProperty
|
||||||
|
// 商品销量
|
||||||
|
salesCount: PromotionCombinationFieldProperty
|
||||||
|
// 商品库存
|
||||||
|
stock: PromotionCombinationFieldProperty
|
||||||
}
|
}
|
||||||
// 角标
|
// 角标
|
||||||
badge: {
|
badge: {
|
||||||
@@ -18,6 +26,19 @@ export interface PromotionCombinationProperty {
|
|||||||
// 角标图片
|
// 角标图片
|
||||||
imgUrl: string
|
imgUrl: string
|
||||||
}
|
}
|
||||||
|
// 按钮
|
||||||
|
btnBuy: {
|
||||||
|
// 类型:文字 | 图片
|
||||||
|
type: 'text' | 'img'
|
||||||
|
// 文字
|
||||||
|
text: string
|
||||||
|
// 文字按钮:背景渐变起始颜色
|
||||||
|
bgBeginColor: string
|
||||||
|
// 文字按钮:背景渐变结束颜色
|
||||||
|
bgEndColor: string
|
||||||
|
// 图片按钮:图片地址
|
||||||
|
imgUrl: string
|
||||||
|
}
|
||||||
// 上圆角
|
// 上圆角
|
||||||
borderRadiusTop: number
|
borderRadiusTop: number
|
||||||
// 下圆角
|
// 下圆角
|
||||||
@@ -25,7 +46,7 @@ export interface PromotionCombinationProperty {
|
|||||||
// 间距
|
// 间距
|
||||||
space: number
|
space: number
|
||||||
// 拼团活动编号
|
// 拼团活动编号
|
||||||
activityId: number
|
activityIds: number[]
|
||||||
// 组件样式
|
// 组件样式
|
||||||
style: ComponentStyle
|
style: ComponentStyle
|
||||||
}
|
}
|
||||||
@@ -44,12 +65,23 @@ export const component = {
|
|||||||
name: '拼团',
|
name: '拼团',
|
||||||
icon: 'mdi:account-group',
|
icon: 'mdi:account-group',
|
||||||
property: {
|
property: {
|
||||||
layoutType: 'oneCol',
|
layoutType: 'oneColBigImg',
|
||||||
fields: {
|
fields: {
|
||||||
name: { show: true, color: '#000' },
|
name: { show: true, color: '#000' },
|
||||||
price: { show: true, color: '#ff3000' }
|
introduction: { show: true, color: '#999' },
|
||||||
|
price: { show: true, color: '#ff3000' },
|
||||||
|
marketPrice: { show: true, color: '#c4c4c4' },
|
||||||
|
salesCount: { show: true, color: '#c4c4c4' },
|
||||||
|
stock: { show: false, color: '#c4c4c4' }
|
||||||
},
|
},
|
||||||
badge: { show: false, imgUrl: '' },
|
badge: { show: false, imgUrl: '' },
|
||||||
|
btnBuy: {
|
||||||
|
type: 'text',
|
||||||
|
text: '去拼团',
|
||||||
|
bgBeginColor: '#FF6000',
|
||||||
|
bgEndColor: '#FE832A',
|
||||||
|
imgUrl: ''
|
||||||
|
},
|
||||||
borderRadiusTop: 8,
|
borderRadiusTop: 8,
|
||||||
borderRadiusBottom: 8,
|
borderRadiusBottom: 8,
|
||||||
space: 8,
|
space: 8,
|
||||||
|
|||||||
@@ -1,125 +1,201 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-scrollbar class="z-1 min-h-30px" wrap-class="w-full" ref="containerRef">
|
<div :class="`box-content min-h-30px w-full flex flex-row flex-wrap`" ref="containerRef">
|
||||||
<!-- 商品网格 -->
|
|
||||||
<div
|
<div
|
||||||
class="grid overflow-x-auto"
|
class="relative box-content flex flex-row flex-wrap overflow-hidden bg-white"
|
||||||
:style="{
|
:style="{
|
||||||
gridGap: `${property.space}px`,
|
...calculateSpace(index),
|
||||||
gridTemplateColumns,
|
...calculateWidth(),
|
||||||
width: scrollbarWidth
|
borderTopLeftRadius: `${property.borderRadiusTop}px`,
|
||||||
|
borderTopRightRadius: `${property.borderRadiusTop}px`,
|
||||||
|
borderBottomLeftRadius: `${property.borderRadiusBottom}px`,
|
||||||
|
borderBottomRightRadius: `${property.borderRadiusBottom}px`
|
||||||
}"
|
}"
|
||||||
|
v-for="(spu, index) in spuList"
|
||||||
|
:key="index"
|
||||||
>
|
>
|
||||||
<!-- 商品 -->
|
<!-- 角标 -->
|
||||||
|
<div v-if="property.badge.show" class="absolute left-0 top-0 z-1 items-center justify-center">
|
||||||
|
<el-image fit="cover" :src="property.badge.imgUrl" class="h-26px w-38px" />
|
||||||
|
</div>
|
||||||
|
<!-- 商品封面图 -->
|
||||||
<div
|
<div
|
||||||
class="relative box-content flex flex-row flex-wrap overflow-hidden bg-white"
|
:class="[
|
||||||
:style="{
|
'h-140px',
|
||||||
borderTopLeftRadius: `${property.borderRadiusTop}px`,
|
{
|
||||||
borderTopRightRadius: `${property.borderRadiusTop}px`,
|
'w-full': property.layoutType !== 'oneColSmallImg',
|
||||||
borderBottomLeftRadius: `${property.borderRadiusBottom}px`,
|
'w-140px': property.layoutType === 'oneColSmallImg'
|
||||||
borderBottomRightRadius: `${property.borderRadiusBottom}px`
|
}
|
||||||
}"
|
]"
|
||||||
v-for="(spu, index) in spuList"
|
|
||||||
:key="index"
|
|
||||||
>
|
>
|
||||||
<!-- 角标 -->
|
<el-image fit="cover" class="h-full w-full" :src="spu.picUrl" />
|
||||||
<div
|
</div>
|
||||||
v-if="property.badge.show"
|
<div
|
||||||
class="absolute left-0 top-0 z-1 items-center justify-center"
|
:class="[
|
||||||
>
|
' flex flex-col gap-8px p-8px box-border',
|
||||||
<el-image fit="cover" :src="property.badge.imgUrl" class="h-26px w-38px" />
|
{
|
||||||
</div>
|
'w-full': property.layoutType !== 'oneColSmallImg',
|
||||||
<!-- 商品封面图 -->
|
'w-[calc(100%-140px-16px)]': property.layoutType === 'oneColSmallImg'
|
||||||
<el-image fit="cover" :src="spu.picUrl" :style="{ width: imageSize, height: imageSize }" />
|
}
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<!-- 商品名称 -->
|
||||||
<div
|
<div
|
||||||
|
v-if="property.fields.name.show"
|
||||||
:class="[
|
:class="[
|
||||||
'flex flex-col gap-8px p-8px box-border',
|
'text-14px ',
|
||||||
{
|
{
|
||||||
'w-[calc(100%-64px)]': columns === 2,
|
truncate: property.layoutType !== 'oneColSmallImg',
|
||||||
'w-full': columns === 3
|
'overflow-ellipsis line-clamp-2': property.layoutType === 'oneColSmallImg'
|
||||||
}
|
}
|
||||||
]"
|
]"
|
||||||
|
:style="{ color: property.fields.name.color }"
|
||||||
>
|
>
|
||||||
<!-- 商品名称 -->
|
{{ spu.name }}
|
||||||
<div
|
</div>
|
||||||
v-if="property.fields.name.show"
|
<!-- 商品简介 -->
|
||||||
class="truncate text-12px"
|
<div
|
||||||
:style="{ color: property.fields.name.color }"
|
v-if="property.fields.introduction.show"
|
||||||
|
class="truncate text-12px"
|
||||||
|
:style="{ color: property.fields.introduction.color }"
|
||||||
|
>
|
||||||
|
{{ spu.introduction }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<!-- 价格 -->
|
||||||
|
<span
|
||||||
|
v-if="property.fields.price.show"
|
||||||
|
class="text-16px"
|
||||||
|
:style="{ color: property.fields.price.color }"
|
||||||
>
|
>
|
||||||
{{ spu.name }}
|
¥{{ fenToYuan(spu.price || Infinity) }}
|
||||||
</div>
|
</span>
|
||||||
<div>
|
<!-- 市场价 -->
|
||||||
<!-- 商品价格 -->
|
<span
|
||||||
<span
|
v-if="property.fields.marketPrice.show && spu.marketPrice"
|
||||||
v-if="property.fields.price.show"
|
class="ml-4px text-10px line-through"
|
||||||
class="text-12px"
|
:style="{ color: property.fields.marketPrice.color }"
|
||||||
:style="{ color: property.fields.price.color }"
|
>¥{{ fenToYuan(spu.marketPrice) }}</span
|
||||||
>
|
>
|
||||||
¥{{ spu.price }}
|
</div>
|
||||||
</span>
|
<div class="text-12px">
|
||||||
</div>
|
<!-- 销量 -->
|
||||||
|
<span
|
||||||
|
v-if="property.fields.salesCount.show"
|
||||||
|
:style="{ color: property.fields.salesCount.color }"
|
||||||
|
>
|
||||||
|
已售{{ (spu.salesCount || 0) + (spu.virtualSalesCount || 0) }}件
|
||||||
|
</span>
|
||||||
|
<!-- 库存 -->
|
||||||
|
<span v-if="property.fields.stock.show" :style="{ color: property.fields.stock.color }">
|
||||||
|
库存{{ spu.stock || 0 }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 购买按钮 -->
|
||||||
|
<div class="absolute bottom-8px right-8px">
|
||||||
|
<!-- 文字按钮 -->
|
||||||
|
<span
|
||||||
|
v-if="property.btnBuy.type === 'text'"
|
||||||
|
class="rounded-full p-x-12px p-y-4px text-12px text-white"
|
||||||
|
:style="{
|
||||||
|
background: `linear-gradient(to right, ${property.btnBuy.bgBeginColor}, ${property.btnBuy.bgEndColor}`
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ property.btnBuy.text }}
|
||||||
|
</span>
|
||||||
|
<!-- 图片按钮 -->
|
||||||
|
<el-image
|
||||||
|
v-else
|
||||||
|
class="h-28px w-28px rounded-full"
|
||||||
|
fit="cover"
|
||||||
|
:src="property.btnBuy.imgUrl"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-scrollbar>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { PromotionCombinationProperty } from './config'
|
import { PromotionCombinationProperty } from './config'
|
||||||
import * as ProductSpuApi from '@/api/mall/product/spu'
|
import * as ProductSpuApi from '@/api/mall/product/spu'
|
||||||
import * as CombinationActivityApi from '@/api/mall/promotion/combination/combinationActivity'
|
import * as CombinationActivityApi from '@/api/mall/promotion/combination/combinationActivity'
|
||||||
|
import { fenToYuan } from '@/utils'
|
||||||
|
|
||||||
/** 拼团 */
|
/** 拼团卡片 */
|
||||||
defineOptions({ name: 'PromotionCombination' })
|
defineOptions({ name: 'PromotionCombination' })
|
||||||
// 定义属性
|
// 定义属性
|
||||||
const props = defineProps<{ property: PromotionCombinationProperty }>()
|
const props = defineProps<{ property: PromotionCombinationProperty }>()
|
||||||
// 商品列表
|
// 商品列表
|
||||||
const spuList = ref<ProductSpuApi.Spu[]>([])
|
const spuList = ref<ProductSpuApi.Spu[]>([])
|
||||||
|
const spuIdList = ref<number[]>([])
|
||||||
|
const combinationActivityList = ref<CombinationActivityApi.CombinationActivityVO[]>([])
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.property.activityId,
|
() => props.property.activityIds,
|
||||||
async () => {
|
async () => {
|
||||||
if (!props.property.activityId) return
|
try {
|
||||||
const activity = await CombinationActivityApi.getCombinationActivity(props.property.activityId)
|
// 新添加的拼团组件,是没有活动ID的
|
||||||
if (!activity?.spuId) return
|
const activityIds = props.property.activityIds
|
||||||
spuList.value = [await ProductSpuApi.getSpu(activity.spuId)]
|
// 检查活动ID的有效性
|
||||||
|
if (Array.isArray(activityIds) && activityIds.length > 0) {
|
||||||
|
// 获取拼团活动详情列表
|
||||||
|
combinationActivityList.value =
|
||||||
|
await CombinationActivityApi.getCombinationActivityListByIds(activityIds)
|
||||||
|
|
||||||
|
// 获取拼团活动的 SPU 详情列表
|
||||||
|
spuList.value = []
|
||||||
|
spuIdList.value = combinationActivityList.value
|
||||||
|
.map((activity) => activity.spuId)
|
||||||
|
.filter((spuId): spuId is number => typeof spuId === 'number')
|
||||||
|
if (spuIdList.value.length > 0) {
|
||||||
|
spuList.value = await ProductSpuApi.getSpuDetailList(spuIdList.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新 SPU 的最低价格
|
||||||
|
combinationActivityList.value.forEach((activity) => {
|
||||||
|
// 匹配spuId
|
||||||
|
const spu = spuList.value.find((spu) => spu.id === activity.spuId)
|
||||||
|
if (spu) {
|
||||||
|
// 赋值活动价格,哪个最便宜就赋值哪个
|
||||||
|
spu.price = Math.min(activity.combinationPrice || Infinity, spu.price || Infinity)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取拼团活动细节或 SPU 细节时出错:', error)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
immediate: true,
|
immediate: true,
|
||||||
deep: true
|
deep: true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
// 手机宽度
|
|
||||||
const phoneWidth = ref(375)
|
/**
|
||||||
|
* 计算商品的间距
|
||||||
|
* @param index 商品索引
|
||||||
|
*/
|
||||||
|
const calculateSpace = (index: number) => {
|
||||||
|
// 商品的列数
|
||||||
|
const columns = props.property.layoutType === 'twoCol' ? 2 : 1
|
||||||
|
// 第一列没有左边距
|
||||||
|
const marginLeft = index % columns === 0 ? '0' : props.property.space + 'px'
|
||||||
|
// 第一行没有上边距
|
||||||
|
const marginTop = index < columns ? '0' : props.property.space + 'px'
|
||||||
|
|
||||||
|
return { marginLeft, marginTop }
|
||||||
|
}
|
||||||
|
|
||||||
// 容器
|
// 容器
|
||||||
const containerRef = ref()
|
const containerRef = ref()
|
||||||
// 商品的列数
|
// 计算商品的宽度
|
||||||
const columns = ref(2)
|
const calculateWidth = () => {
|
||||||
// 滚动条宽度
|
let width = '100%'
|
||||||
const scrollbarWidth = ref('100%')
|
// 双列时每列的宽度为:(总宽度 - 间距)/ 2
|
||||||
// 商品图大小
|
if (props.property.layoutType === 'twoCol') {
|
||||||
const imageSize = ref('0')
|
width = `${(containerRef.value.offsetWidth - props.property.space) / 2}px`
|
||||||
// 商品网络列数
|
}
|
||||||
const gridTemplateColumns = ref('')
|
return { width }
|
||||||
// 计算布局参数
|
}
|
||||||
watch(
|
|
||||||
() => [props.property, phoneWidth, spuList.value.length],
|
|
||||||
() => {
|
|
||||||
// 计算列数
|
|
||||||
columns.value = props.property.layoutType === 'oneCol' ? 1 : 3
|
|
||||||
// 每列的宽度为:(总宽度 - 间距 * (列数 - 1))/ 列数
|
|
||||||
const productWidth =
|
|
||||||
(phoneWidth.value - props.property.space * (columns.value - 1)) / columns.value
|
|
||||||
// 商品图布局:2列时,左右布局 3列时,上下布局
|
|
||||||
imageSize.value = columns.value === 2 ? '64px' : `${productWidth}px`
|
|
||||||
// 指定列数
|
|
||||||
gridTemplateColumns.value = `repeat(${columns.value}, auto)`
|
|
||||||
// 不滚动
|
|
||||||
scrollbarWidth.value = '100%'
|
|
||||||
},
|
|
||||||
{ immediate: true, deep: true }
|
|
||||||
)
|
|
||||||
onMounted(() => {
|
|
||||||
// 提取手机宽度
|
|
||||||
phoneWidth.value = containerRef.value?.wrapRef?.offsetWidth || 375
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss"></style>
|
<style scoped lang="scss"></style>
|
||||||
@@ -2,30 +2,31 @@
|
|||||||
<ComponentContainerProperty v-model="formData.style">
|
<ComponentContainerProperty v-model="formData.style">
|
||||||
<el-form label-width="80px" :model="formData">
|
<el-form label-width="80px" :model="formData">
|
||||||
<el-card header="拼团活动" class="property-group" shadow="never">
|
<el-card header="拼团活动" class="property-group" shadow="never">
|
||||||
<el-form-item label="拼团活动" prop="activityId">
|
<CombinationShowcase v-model="formData.activityIds" />
|
||||||
<el-select v-model="formData.activityId">
|
|
||||||
<el-option
|
|
||||||
v-for="activity in activityList"
|
|
||||||
:key="activity.id"
|
|
||||||
:label="activity.name"
|
|
||||||
:value="activity.id"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card header="商品样式" class="property-group" shadow="never">
|
<el-card header="商品样式" class="property-group" shadow="never">
|
||||||
<el-form-item label="布局" prop="type">
|
<el-form-item label="布局" prop="type">
|
||||||
<el-radio-group v-model="formData.layoutType">
|
<el-radio-group v-model="formData.layoutType">
|
||||||
<el-tooltip class="item" content="单列" placement="bottom">
|
<el-tooltip class="item" content="单列大图" placement="bottom">
|
||||||
<el-radio-button label="oneCol">
|
<el-radio-button value="oneColBigImg">
|
||||||
<Icon icon="fluent:text-column-one-24-filled" />
|
<Icon icon="fluent:text-column-one-24-filled" />
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip class="item" content="三列" placement="bottom">
|
<el-tooltip class="item" content="单列小图" placement="bottom">
|
||||||
<el-radio-button label="threeCol">
|
<el-radio-button value="oneColSmallImg">
|
||||||
<Icon icon="fluent:text-column-three-24-filled" />
|
<Icon icon="fluent:text-column-two-left-24-filled" />
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
<el-tooltip class="item" content="双列" placement="bottom">
|
||||||
|
<el-radio-button value="twoCol">
|
||||||
|
<Icon icon="fluent:text-column-two-24-filled" />
|
||||||
|
</el-radio-button>
|
||||||
|
</el-tooltip>
|
||||||
|
<!--<el-tooltip class="item" content="三列" placement="bottom">
|
||||||
|
<el-radio-button value="threeCol">
|
||||||
|
<Icon icon="fluent:text-column-three-24-filled" />
|
||||||
|
</el-radio-button>
|
||||||
|
</el-tooltip>-->
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="商品名称" prop="fields.name.show">
|
<el-form-item label="商品名称" prop="fields.name.show">
|
||||||
@@ -34,12 +35,36 @@
|
|||||||
<el-checkbox v-model="formData.fields.name.show" />
|
<el-checkbox v-model="formData.fields.name.show" />
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="商品简介" prop="fields.introduction.show">
|
||||||
|
<div class="flex gap-8px">
|
||||||
|
<ColorInput v-model="formData.fields.introduction.color" />
|
||||||
|
<el-checkbox v-model="formData.fields.introduction.show" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="商品价格" prop="fields.price.show">
|
<el-form-item label="商品价格" prop="fields.price.show">
|
||||||
<div class="flex gap-8px">
|
<div class="flex gap-8px">
|
||||||
<ColorInput v-model="formData.fields.price.color" />
|
<ColorInput v-model="formData.fields.price.color" />
|
||||||
<el-checkbox v-model="formData.fields.price.show" />
|
<el-checkbox v-model="formData.fields.price.show" />
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="市场价" prop="fields.marketPrice.show">
|
||||||
|
<div class="flex gap-8px">
|
||||||
|
<ColorInput v-model="formData.fields.marketPrice.color" />
|
||||||
|
<el-checkbox v-model="formData.fields.marketPrice.show" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="商品销量" prop="fields.salesCount.show">
|
||||||
|
<div class="flex gap-8px">
|
||||||
|
<ColorInput v-model="formData.fields.salesCount.color" />
|
||||||
|
<el-checkbox v-model="formData.fields.salesCount.show" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="商品库存" prop="fields.stock.show">
|
||||||
|
<div class="flex gap-8px">
|
||||||
|
<ColorInput v-model="formData.fields.stock.color" />
|
||||||
|
<el-checkbox v-model="formData.fields.stock.show" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card header="角标" class="property-group" shadow="never">
|
<el-card header="角标" class="property-group" shadow="never">
|
||||||
<el-form-item label="角标" prop="badge.show">
|
<el-form-item label="角标" prop="badge.show">
|
||||||
@@ -47,10 +72,36 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="角标" prop="badge.imgUrl" v-if="formData.badge.show">
|
<el-form-item label="角标" prop="badge.imgUrl" v-if="formData.badge.show">
|
||||||
<UploadImg v-model="formData.badge.imgUrl" height="44px" width="72px">
|
<UploadImg v-model="formData.badge.imgUrl" height="44px" width="72px">
|
||||||
<template #tip> 建议尺寸:36 * 22 </template>
|
<template #tip> 建议尺寸:36 * 22</template>
|
||||||
</UploadImg>
|
</UploadImg>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
<el-card header="按钮" class="property-group" shadow="never">
|
||||||
|
<el-form-item label="按钮类型" prop="btnBuy.type">
|
||||||
|
<el-radio-group v-model="formData.btnBuy.type">
|
||||||
|
<el-radio-button value="text">文字</el-radio-button>
|
||||||
|
<el-radio-button value="img">图片</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<template v-if="formData.btnBuy.type === 'text'">
|
||||||
|
<el-form-item label="按钮文字" prop="btnBuy.text">
|
||||||
|
<el-input v-model="formData.btnBuy.text" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="左侧背景" prop="btnBuy.bgBeginColor">
|
||||||
|
<ColorInput v-model="formData.btnBuy.bgBeginColor" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="右侧背景" prop="btnBuy.bgEndColor">
|
||||||
|
<ColorInput v-model="formData.btnBuy.bgEndColor" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<el-form-item label="图片" prop="btnBuy.imgUrl">
|
||||||
|
<UploadImg v-model="formData.btnBuy.imgUrl" height="56px" width="56px">
|
||||||
|
<template #tip> 建议尺寸:56 * 56</template>
|
||||||
|
</UploadImg>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-card>
|
||||||
<el-card header="商品样式" class="property-group" shadow="never">
|
<el-card header="商品样式" class="property-group" shadow="never">
|
||||||
<el-form-item label="上圆角" prop="borderRadiusTop">
|
<el-form-item label="上圆角" prop="borderRadiusTop">
|
||||||
<el-slider
|
<el-slider
|
||||||
@@ -92,6 +143,7 @@ import { PromotionCombinationProperty } from './config'
|
|||||||
import { usePropertyForm } from '@/components/DiyEditor/util'
|
import { usePropertyForm } from '@/components/DiyEditor/util'
|
||||||
import * as CombinationActivityApi from '@/api/mall/promotion/combination/combinationActivity'
|
import * as CombinationActivityApi from '@/api/mall/promotion/combination/combinationActivity'
|
||||||
import { CommonStatusEnum } from '@/utils/constants'
|
import { CommonStatusEnum } from '@/utils/constants'
|
||||||
|
import CombinationShowcase from '@/views/mall/promotion/combination/components/CombinationShowcase.vue'
|
||||||
|
|
||||||
// 拼团属性面板
|
// 拼团属性面板
|
||||||
defineOptions({ name: 'PromotionCombinationProperty' })
|
defineOptions({ name: 'PromotionCombinationProperty' })
|
||||||
@@ -100,7 +152,7 @@ const props = defineProps<{ modelValue: PromotionCombinationProperty }>()
|
|||||||
const emit = defineEmits(['update:modelValue'])
|
const emit = defineEmits(['update:modelValue'])
|
||||||
const { formData } = usePropertyForm(props.modelValue, emit)
|
const { formData } = usePropertyForm(props.modelValue, emit)
|
||||||
// 活动列表
|
// 活动列表
|
||||||
const activityList = ref<CombinationActivityApi.CombinationActivityVO>([])
|
const activityList = ref<CombinationActivityApi.CombinationActivityVO[]>([])
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
const { list } = await CombinationActivityApi.getCombinationActivityPage({
|
const { list } = await CombinationActivityApi.getCombinationActivityPage({
|
||||||
status: CommonStatusEnum.ENABLE
|
status: CommonStatusEnum.ENABLE
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
import {ComponentStyle, DiyComponent} from '@/components/DiyEditor/util'
|
||||||
|
|
||||||
|
/** 积分商城属性 */
|
||||||
|
export interface PromotionPointProperty {
|
||||||
|
// 布局类型:单列 | 三列
|
||||||
|
layoutType: 'oneColBigImg' | 'oneColSmallImg' | 'twoCol'
|
||||||
|
// 商品字段
|
||||||
|
fields: {
|
||||||
|
// 商品名称
|
||||||
|
name: PromotionPointFieldProperty
|
||||||
|
// 商品简介
|
||||||
|
introduction: PromotionPointFieldProperty
|
||||||
|
// 商品价格
|
||||||
|
price: PromotionPointFieldProperty
|
||||||
|
// 市场价
|
||||||
|
marketPrice: PromotionPointFieldProperty
|
||||||
|
// 商品销量
|
||||||
|
salesCount: PromotionPointFieldProperty
|
||||||
|
// 商品库存
|
||||||
|
stock: PromotionPointFieldProperty
|
||||||
|
}
|
||||||
|
// 角标
|
||||||
|
badge: {
|
||||||
|
// 是否显示
|
||||||
|
show: boolean
|
||||||
|
// 角标图片
|
||||||
|
imgUrl: string
|
||||||
|
}
|
||||||
|
// 按钮
|
||||||
|
btnBuy: {
|
||||||
|
// 类型:文字 | 图片
|
||||||
|
type: 'text' | 'img'
|
||||||
|
// 文字
|
||||||
|
text: string
|
||||||
|
// 文字按钮:背景渐变起始颜色
|
||||||
|
bgBeginColor: string
|
||||||
|
// 文字按钮:背景渐变结束颜色
|
||||||
|
bgEndColor: string
|
||||||
|
// 图片按钮:图片地址
|
||||||
|
imgUrl: string
|
||||||
|
}
|
||||||
|
// 上圆角
|
||||||
|
borderRadiusTop: number
|
||||||
|
// 下圆角
|
||||||
|
borderRadiusBottom: number
|
||||||
|
// 间距
|
||||||
|
space: number
|
||||||
|
// 秒杀活动编号
|
||||||
|
activityIds: number[]
|
||||||
|
// 组件样式
|
||||||
|
style: ComponentStyle
|
||||||
|
}
|
||||||
|
|
||||||
|
// 商品字段
|
||||||
|
export interface PromotionPointFieldProperty {
|
||||||
|
// 是否显示
|
||||||
|
show: boolean
|
||||||
|
// 颜色
|
||||||
|
color: string
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定义组件
|
||||||
|
export const component = {
|
||||||
|
id: 'PromotionPoint',
|
||||||
|
name: '积分商城',
|
||||||
|
icon: 'ep:present',
|
||||||
|
property: {
|
||||||
|
layoutType: 'oneColBigImg',
|
||||||
|
fields: {
|
||||||
|
name: { show: true, color: '#000' },
|
||||||
|
introduction: { show: true, color: '#999' },
|
||||||
|
price: { show: true, color: '#ff3000' },
|
||||||
|
marketPrice: { show: true, color: '#c4c4c4' },
|
||||||
|
salesCount: { show: true, color: '#c4c4c4' },
|
||||||
|
stock: { show: false, color: '#c4c4c4' }
|
||||||
|
},
|
||||||
|
badge: { show: false, imgUrl: '' },
|
||||||
|
btnBuy: {
|
||||||
|
type: 'text',
|
||||||
|
text: '立即兑换',
|
||||||
|
bgBeginColor: '#FF6000',
|
||||||
|
bgEndColor: '#FE832A',
|
||||||
|
imgUrl: ''
|
||||||
|
},
|
||||||
|
borderRadiusTop: 8,
|
||||||
|
borderRadiusBottom: 8,
|
||||||
|
space: 8,
|
||||||
|
style: {
|
||||||
|
bgType: 'color',
|
||||||
|
bgColor: '',
|
||||||
|
marginLeft: 8,
|
||||||
|
marginRight: 8,
|
||||||
|
marginBottom: 8
|
||||||
|
} as ComponentStyle
|
||||||
|
}
|
||||||
|
} as DiyComponent<PromotionPointProperty>
|
||||||
@@ -0,0 +1,202 @@
|
|||||||
|
<template>
|
||||||
|
<div ref="containerRef" :class="`box-content min-h-30px w-full flex flex-row flex-wrap`">
|
||||||
|
<div
|
||||||
|
v-for="(spu, index) in spuList"
|
||||||
|
:key="index"
|
||||||
|
:style="{
|
||||||
|
...calculateSpace(index),
|
||||||
|
...calculateWidth(),
|
||||||
|
borderTopLeftRadius: `${property.borderRadiusTop}px`,
|
||||||
|
borderTopRightRadius: `${property.borderRadiusTop}px`,
|
||||||
|
borderBottomLeftRadius: `${property.borderRadiusBottom}px`,
|
||||||
|
borderBottomRightRadius: `${property.borderRadiusBottom}px`
|
||||||
|
}"
|
||||||
|
class="relative box-content flex flex-row flex-wrap overflow-hidden bg-white"
|
||||||
|
>
|
||||||
|
<!-- 角标 -->
|
||||||
|
<div v-if="property.badge.show" class="absolute left-0 top-0 z-1 items-center justify-center">
|
||||||
|
<el-image :src="property.badge.imgUrl" class="h-26px w-38px" fit="cover" />
|
||||||
|
</div>
|
||||||
|
<!-- 商品封面图 -->
|
||||||
|
<div
|
||||||
|
:class="[
|
||||||
|
'h-140px',
|
||||||
|
{
|
||||||
|
'w-full': property.layoutType !== 'oneColSmallImg',
|
||||||
|
'w-140px': property.layoutType === 'oneColSmallImg'
|
||||||
|
}
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<el-image :src="spu.picUrl" class="h-full w-full" fit="cover" />
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
:class="[
|
||||||
|
' flex flex-col gap-8px p-8px box-border',
|
||||||
|
{
|
||||||
|
'w-full': property.layoutType !== 'oneColSmallImg',
|
||||||
|
'w-[calc(100%-140px-16px)]': property.layoutType === 'oneColSmallImg'
|
||||||
|
}
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<!-- 商品名称 -->
|
||||||
|
<div
|
||||||
|
v-if="property.fields.name.show"
|
||||||
|
:class="[
|
||||||
|
'text-14px ',
|
||||||
|
{
|
||||||
|
truncate: property.layoutType !== 'oneColSmallImg',
|
||||||
|
'overflow-ellipsis line-clamp-2': property.layoutType === 'oneColSmallImg'
|
||||||
|
}
|
||||||
|
]"
|
||||||
|
:style="{ color: property.fields.name.color }"
|
||||||
|
>
|
||||||
|
{{ spu.name }}
|
||||||
|
</div>
|
||||||
|
<!-- 商品简介 -->
|
||||||
|
<div
|
||||||
|
v-if="property.fields.introduction.show"
|
||||||
|
:style="{ color: property.fields.introduction.color }"
|
||||||
|
class="truncate text-12px"
|
||||||
|
>
|
||||||
|
{{ spu.introduction }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<!-- 积分 -->
|
||||||
|
<span
|
||||||
|
v-if="property.fields.price.show"
|
||||||
|
:style="{ color: property.fields.price.color }"
|
||||||
|
class="text-16px"
|
||||||
|
>
|
||||||
|
{{ spu.point }}积分
|
||||||
|
{{ !spu.pointPrice || spu.pointPrice === 0 ? '' : `+${fenToYuan(spu.pointPrice)}元` }}
|
||||||
|
</span>
|
||||||
|
<!-- 市场价 -->
|
||||||
|
<span
|
||||||
|
v-if="property.fields.marketPrice.show && spu.marketPrice"
|
||||||
|
:style="{ color: property.fields.marketPrice.color }"
|
||||||
|
class="ml-4px text-10px line-through"
|
||||||
|
>
|
||||||
|
¥{{ fenToYuan(spu.marketPrice) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="text-12px">
|
||||||
|
<!-- 销量 -->
|
||||||
|
<span
|
||||||
|
v-if="property.fields.salesCount.show"
|
||||||
|
:style="{ color: property.fields.salesCount.color }"
|
||||||
|
>
|
||||||
|
已兑{{ (spu.pointTotalStock || 0) - (spu.pointStock || 0) }}件
|
||||||
|
</span>
|
||||||
|
<!-- 库存 -->
|
||||||
|
<span v-if="property.fields.stock.show" :style="{ color: property.fields.stock.color }">
|
||||||
|
库存{{ spu.pointTotalStock || 0 }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 购买按钮 -->
|
||||||
|
<div class="absolute bottom-8px right-8px">
|
||||||
|
<!-- 文字按钮 -->
|
||||||
|
<span
|
||||||
|
v-if="property.btnBuy.type === 'text'"
|
||||||
|
:style="{
|
||||||
|
background: `linear-gradient(to right, ${property.btnBuy.bgBeginColor}, ${property.btnBuy.bgEndColor}`
|
||||||
|
}"
|
||||||
|
class="rounded-full p-x-12px p-y-4px text-12px text-white"
|
||||||
|
>
|
||||||
|
{{ property.btnBuy.text }}
|
||||||
|
</span>
|
||||||
|
<!-- 图片按钮 -->
|
||||||
|
<el-image
|
||||||
|
v-else
|
||||||
|
:src="property.btnBuy.imgUrl"
|
||||||
|
class="h-28px w-28px rounded-full"
|
||||||
|
fit="cover"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { PromotionPointProperty } from './config'
|
||||||
|
import * as ProductSpuApi from '@/api/mall/product/spu'
|
||||||
|
import { PointActivityApi, PointActivityVO, SpuExtension0 } from '@/api/mall/promotion/point'
|
||||||
|
import { fenToYuan } from '@/utils'
|
||||||
|
|
||||||
|
/** 积分商城卡片 */
|
||||||
|
defineOptions({ name: 'PromotionPoint' })
|
||||||
|
// 定义属性
|
||||||
|
const props = defineProps<{ property: PromotionPointProperty }>()
|
||||||
|
// 商品列表
|
||||||
|
const spuList = ref<SpuExtension0[]>([])
|
||||||
|
const spuIdList = ref<number[]>([])
|
||||||
|
const pointActivityList = ref<PointActivityVO[]>([])
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.property.activityIds,
|
||||||
|
async () => {
|
||||||
|
try {
|
||||||
|
// 新添加的积分商城组件,是没有活动ID的
|
||||||
|
const activityIds = props.property.activityIds
|
||||||
|
// 检查活动ID的有效性
|
||||||
|
if (Array.isArray(activityIds) && activityIds.length > 0) {
|
||||||
|
// 获取积分商城活动详情列表
|
||||||
|
pointActivityList.value = await PointActivityApi.getPointActivityListByIds(activityIds)
|
||||||
|
|
||||||
|
// 获取积分商城活动的 SPU 详情列表
|
||||||
|
spuList.value = []
|
||||||
|
spuIdList.value = pointActivityList.value.map((activity) => activity.spuId)
|
||||||
|
if (spuIdList.value.length > 0) {
|
||||||
|
spuList.value = await ProductSpuApi.getSpuDetailList(spuIdList.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新 SPU 的最低兑换积分和所需兑换金额
|
||||||
|
pointActivityList.value.forEach((activity) => {
|
||||||
|
// 匹配spuId
|
||||||
|
const spu = spuList.value.find((spu) => spu.id === activity.spuId)
|
||||||
|
if (spu) {
|
||||||
|
spu.pointStock = activity.stock
|
||||||
|
spu.pointTotalStock = activity.totalStock
|
||||||
|
spu.point = activity.point
|
||||||
|
spu.pointPrice = activity.price
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取积分商城活动细节或 SPU 细节时出错:', error)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
immediate: true,
|
||||||
|
deep: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算商品的间距
|
||||||
|
* @param index 商品索引
|
||||||
|
*/
|
||||||
|
const calculateSpace = (index: number) => {
|
||||||
|
// 商品的列数
|
||||||
|
const columns = props.property.layoutType === 'twoCol' ? 2 : 1
|
||||||
|
// 第一列没有左边距
|
||||||
|
const marginLeft = index % columns === 0 ? '0' : props.property.space + 'px'
|
||||||
|
// 第一行没有上边距
|
||||||
|
const marginTop = index < columns ? '0' : props.property.space + 'px'
|
||||||
|
|
||||||
|
return { marginLeft, marginTop }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 容器
|
||||||
|
const containerRef = ref()
|
||||||
|
// 计算商品的宽度
|
||||||
|
const calculateWidth = () => {
|
||||||
|
let width = '100%'
|
||||||
|
// 双列时每列的宽度为:(总宽度 - 间距)/ 2
|
||||||
|
if (props.property.layoutType === 'twoCol') {
|
||||||
|
width = `${(containerRef.value.offsetWidth - props.property.space) / 2}px`
|
||||||
|
}
|
||||||
|
return { width }
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
<template>
|
||||||
|
<ComponentContainerProperty v-model="formData.style">
|
||||||
|
<el-form :model="formData" label-width="80px">
|
||||||
|
<el-card class="property-group" header="积分商城活动" shadow="never">
|
||||||
|
<PointShowcase v-model="formData.activityIds" />
|
||||||
|
</el-card>
|
||||||
|
<el-card class="property-group" header="商品样式" shadow="never">
|
||||||
|
<el-form-item label="布局" prop="type">
|
||||||
|
<el-radio-group v-model="formData.layoutType">
|
||||||
|
<el-tooltip class="item" content="单列大图" placement="bottom">
|
||||||
|
<el-radio-button value="oneColBigImg">
|
||||||
|
<Icon icon="fluent:text-column-one-24-filled" />
|
||||||
|
</el-radio-button>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip class="item" content="单列小图" placement="bottom">
|
||||||
|
<el-radio-button value="oneColSmallImg">
|
||||||
|
<Icon icon="fluent:text-column-two-left-24-filled" />
|
||||||
|
</el-radio-button>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip class="item" content="双列" placement="bottom">
|
||||||
|
<el-radio-button value="twoCol">
|
||||||
|
<Icon icon="fluent:text-column-two-24-filled" />
|
||||||
|
</el-radio-button>
|
||||||
|
</el-tooltip>
|
||||||
|
<!--<el-tooltip class="item" content="三列" placement="bottom">
|
||||||
|
<el-radio-button value="threeCol">
|
||||||
|
<Icon icon="fluent:text-column-three-24-filled" />
|
||||||
|
</el-radio-button>
|
||||||
|
</el-tooltip>-->
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="商品名称" prop="fields.name.show">
|
||||||
|
<div class="flex gap-8px">
|
||||||
|
<ColorInput v-model="formData.fields.name.color" />
|
||||||
|
<el-checkbox v-model="formData.fields.name.show" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="商品简介" prop="fields.introduction.show">
|
||||||
|
<div class="flex gap-8px">
|
||||||
|
<ColorInput v-model="formData.fields.introduction.color" />
|
||||||
|
<el-checkbox v-model="formData.fields.introduction.show" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="商品价格" prop="fields.price.show">
|
||||||
|
<div class="flex gap-8px">
|
||||||
|
<ColorInput v-model="formData.fields.price.color" />
|
||||||
|
<el-checkbox v-model="formData.fields.price.show" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="市场价" prop="fields.marketPrice.show">
|
||||||
|
<div class="flex gap-8px">
|
||||||
|
<ColorInput v-model="formData.fields.marketPrice.color" />
|
||||||
|
<el-checkbox v-model="formData.fields.marketPrice.show" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="商品销量" prop="fields.salesCount.show">
|
||||||
|
<div class="flex gap-8px">
|
||||||
|
<ColorInput v-model="formData.fields.salesCount.color" />
|
||||||
|
<el-checkbox v-model="formData.fields.salesCount.show" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="商品库存" prop="fields.stock.show">
|
||||||
|
<div class="flex gap-8px">
|
||||||
|
<ColorInput v-model="formData.fields.stock.color" />
|
||||||
|
<el-checkbox v-model="formData.fields.stock.show" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-card>
|
||||||
|
<el-card class="property-group" header="角标" shadow="never">
|
||||||
|
<el-form-item label="角标" prop="badge.show">
|
||||||
|
<el-switch v-model="formData.badge.show" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="formData.badge.show" label="角标" prop="badge.imgUrl">
|
||||||
|
<UploadImg v-model="formData.badge.imgUrl" height="44px" width="72px">
|
||||||
|
<template #tip> 建议尺寸:36 * 22</template>
|
||||||
|
</UploadImg>
|
||||||
|
</el-form-item>
|
||||||
|
</el-card>
|
||||||
|
<el-card class="property-group" header="按钮" shadow="never">
|
||||||
|
<el-form-item label="按钮类型" prop="btnBuy.type">
|
||||||
|
<el-radio-group v-model="formData.btnBuy.type">
|
||||||
|
<el-radio-button value="text">文字</el-radio-button>
|
||||||
|
<el-radio-button value="img">图片</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<template v-if="formData.btnBuy.type === 'text'">
|
||||||
|
<el-form-item label="按钮文字" prop="btnBuy.text">
|
||||||
|
<el-input v-model="formData.btnBuy.text" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="左侧背景" prop="btnBuy.bgBeginColor">
|
||||||
|
<ColorInput v-model="formData.btnBuy.bgBeginColor" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="右侧背景" prop="btnBuy.bgEndColor">
|
||||||
|
<ColorInput v-model="formData.btnBuy.bgEndColor" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<el-form-item label="图片" prop="btnBuy.imgUrl">
|
||||||
|
<UploadImg v-model="formData.btnBuy.imgUrl" height="56px" width="56px">
|
||||||
|
<template #tip> 建议尺寸:56 * 56</template>
|
||||||
|
</UploadImg>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-card>
|
||||||
|
<el-card class="property-group" header="商品样式" shadow="never">
|
||||||
|
<el-form-item label="上圆角" prop="borderRadiusTop">
|
||||||
|
<el-slider
|
||||||
|
v-model="formData.borderRadiusTop"
|
||||||
|
:max="100"
|
||||||
|
:min="0"
|
||||||
|
:show-input-controls="false"
|
||||||
|
input-size="small"
|
||||||
|
show-input
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="下圆角" prop="borderRadiusBottom">
|
||||||
|
<el-slider
|
||||||
|
v-model="formData.borderRadiusBottom"
|
||||||
|
:max="100"
|
||||||
|
:min="0"
|
||||||
|
:show-input-controls="false"
|
||||||
|
input-size="small"
|
||||||
|
show-input
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="间隔" prop="space">
|
||||||
|
<el-slider
|
||||||
|
v-model="formData.space"
|
||||||
|
:max="100"
|
||||||
|
:min="0"
|
||||||
|
:show-input-controls="false"
|
||||||
|
input-size="small"
|
||||||
|
show-input
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-card>
|
||||||
|
</el-form>
|
||||||
|
</ComponentContainerProperty>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { PromotionPointProperty } from './config'
|
||||||
|
import { usePropertyForm } from '@/components/DiyEditor/util'
|
||||||
|
import PointShowcase from '@/views/mall/promotion/point/components/PointShowcase.vue'
|
||||||
|
|
||||||
|
// 秒杀属性面板
|
||||||
|
defineOptions({ name: 'PromotionPointProperty' })
|
||||||
|
|
||||||
|
const props = defineProps<{ modelValue: PromotionPointProperty }>()
|
||||||
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
const { formData } = usePropertyForm(props.modelValue, emit)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
@@ -3,13 +3,21 @@ import { ComponentStyle, DiyComponent } from '@/components/DiyEditor/util'
|
|||||||
/** 秒杀属性 */
|
/** 秒杀属性 */
|
||||||
export interface PromotionSeckillProperty {
|
export interface PromotionSeckillProperty {
|
||||||
// 布局类型:单列 | 三列
|
// 布局类型:单列 | 三列
|
||||||
layoutType: 'oneCol' | 'threeCol'
|
layoutType: 'oneColBigImg' | 'oneColSmallImg' | 'twoCol'
|
||||||
// 商品字段
|
// 商品字段
|
||||||
fields: {
|
fields: {
|
||||||
// 商品名称
|
// 商品名称
|
||||||
name: PromotionSeckillFieldProperty
|
name: PromotionSeckillFieldProperty
|
||||||
|
// 商品简介
|
||||||
|
introduction: PromotionSeckillFieldProperty
|
||||||
// 商品价格
|
// 商品价格
|
||||||
price: PromotionSeckillFieldProperty
|
price: PromotionSeckillFieldProperty
|
||||||
|
// 市场价
|
||||||
|
marketPrice: PromotionSeckillFieldProperty
|
||||||
|
// 商品销量
|
||||||
|
salesCount: PromotionSeckillFieldProperty
|
||||||
|
// 商品库存
|
||||||
|
stock: PromotionSeckillFieldProperty
|
||||||
}
|
}
|
||||||
// 角标
|
// 角标
|
||||||
badge: {
|
badge: {
|
||||||
@@ -18,6 +26,19 @@ export interface PromotionSeckillProperty {
|
|||||||
// 角标图片
|
// 角标图片
|
||||||
imgUrl: string
|
imgUrl: string
|
||||||
}
|
}
|
||||||
|
// 按钮
|
||||||
|
btnBuy: {
|
||||||
|
// 类型:文字 | 图片
|
||||||
|
type: 'text' | 'img'
|
||||||
|
// 文字
|
||||||
|
text: string
|
||||||
|
// 文字按钮:背景渐变起始颜色
|
||||||
|
bgBeginColor: string
|
||||||
|
// 文字按钮:背景渐变结束颜色
|
||||||
|
bgEndColor: string
|
||||||
|
// 图片按钮:图片地址
|
||||||
|
imgUrl: string
|
||||||
|
}
|
||||||
// 上圆角
|
// 上圆角
|
||||||
borderRadiusTop: number
|
borderRadiusTop: number
|
||||||
// 下圆角
|
// 下圆角
|
||||||
@@ -25,10 +46,11 @@ export interface PromotionSeckillProperty {
|
|||||||
// 间距
|
// 间距
|
||||||
space: number
|
space: number
|
||||||
// 秒杀活动编号
|
// 秒杀活动编号
|
||||||
activityId: number
|
activityIds: number[]
|
||||||
// 组件样式
|
// 组件样式
|
||||||
style: ComponentStyle
|
style: ComponentStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
// 商品字段
|
// 商品字段
|
||||||
export interface PromotionSeckillFieldProperty {
|
export interface PromotionSeckillFieldProperty {
|
||||||
// 是否显示
|
// 是否显示
|
||||||
@@ -43,13 +65,23 @@ export const component = {
|
|||||||
name: '秒杀',
|
name: '秒杀',
|
||||||
icon: 'mdi:calendar-time',
|
icon: 'mdi:calendar-time',
|
||||||
property: {
|
property: {
|
||||||
activityId: undefined,
|
layoutType: 'oneColBigImg',
|
||||||
layoutType: 'oneCol',
|
|
||||||
fields: {
|
fields: {
|
||||||
name: { show: true, color: '#000' },
|
name: { show: true, color: '#000' },
|
||||||
price: { show: true, color: '#ff3000' }
|
introduction: { show: true, color: '#999' },
|
||||||
|
price: { show: true, color: '#ff3000' },
|
||||||
|
marketPrice: { show: true, color: '#c4c4c4' },
|
||||||
|
salesCount: { show: true, color: '#c4c4c4' },
|
||||||
|
stock: { show: false, color: '#c4c4c4' }
|
||||||
},
|
},
|
||||||
badge: { show: false, imgUrl: '' },
|
badge: { show: false, imgUrl: '' },
|
||||||
|
btnBuy: {
|
||||||
|
type: 'text',
|
||||||
|
text: '立即秒杀',
|
||||||
|
bgBeginColor: '#FF6000',
|
||||||
|
bgEndColor: '#FE832A',
|
||||||
|
imgUrl: ''
|
||||||
|
},
|
||||||
borderRadiusTop: 8,
|
borderRadiusTop: 8,
|
||||||
borderRadiusBottom: 8,
|
borderRadiusBottom: 8,
|
||||||
space: 8,
|
space: 8,
|
||||||
|
|||||||
@@ -1,125 +1,201 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-scrollbar class="z-1 min-h-30px" wrap-class="w-full" ref="containerRef">
|
<div :class="`box-content min-h-30px w-full flex flex-row flex-wrap`" ref="containerRef">
|
||||||
<!-- 商品网格 -->
|
|
||||||
<div
|
<div
|
||||||
class="grid overflow-x-auto"
|
class="relative box-content flex flex-row flex-wrap overflow-hidden bg-white"
|
||||||
:style="{
|
:style="{
|
||||||
gridGap: `${property.space}px`,
|
...calculateSpace(index),
|
||||||
gridTemplateColumns,
|
...calculateWidth(),
|
||||||
width: scrollbarWidth
|
borderTopLeftRadius: `${property.borderRadiusTop}px`,
|
||||||
|
borderTopRightRadius: `${property.borderRadiusTop}px`,
|
||||||
|
borderBottomLeftRadius: `${property.borderRadiusBottom}px`,
|
||||||
|
borderBottomRightRadius: `${property.borderRadiusBottom}px`
|
||||||
}"
|
}"
|
||||||
|
v-for="(spu, index) in spuList"
|
||||||
|
:key="index"
|
||||||
>
|
>
|
||||||
<!-- 商品 -->
|
<!-- 角标 -->
|
||||||
|
<div v-if="property.badge.show" class="absolute left-0 top-0 z-1 items-center justify-center">
|
||||||
|
<el-image fit="cover" :src="property.badge.imgUrl" class="h-26px w-38px" />
|
||||||
|
</div>
|
||||||
|
<!-- 商品封面图 -->
|
||||||
<div
|
<div
|
||||||
class="relative box-content flex flex-row flex-wrap overflow-hidden bg-white"
|
:class="[
|
||||||
:style="{
|
'h-140px',
|
||||||
borderTopLeftRadius: `${property.borderRadiusTop}px`,
|
{
|
||||||
borderTopRightRadius: `${property.borderRadiusTop}px`,
|
'w-full': property.layoutType !== 'oneColSmallImg',
|
||||||
borderBottomLeftRadius: `${property.borderRadiusBottom}px`,
|
'w-140px': property.layoutType === 'oneColSmallImg'
|
||||||
borderBottomRightRadius: `${property.borderRadiusBottom}px`
|
}
|
||||||
}"
|
]"
|
||||||
v-for="(spu, index) in spuList"
|
|
||||||
:key="index"
|
|
||||||
>
|
>
|
||||||
<!-- 角标 -->
|
<el-image fit="cover" class="h-full w-full" :src="spu.picUrl" />
|
||||||
<div
|
</div>
|
||||||
v-if="property.badge.show"
|
<div
|
||||||
class="absolute left-0 top-0 z-1 items-center justify-center"
|
:class="[
|
||||||
>
|
' flex flex-col gap-8px p-8px box-border',
|
||||||
<el-image fit="cover" :src="property.badge.imgUrl" class="h-26px w-38px" />
|
{
|
||||||
</div>
|
'w-full': property.layoutType !== 'oneColSmallImg',
|
||||||
<!-- 商品封面图 -->
|
'w-[calc(100%-140px-16px)]': property.layoutType === 'oneColSmallImg'
|
||||||
<el-image fit="cover" :src="spu.picUrl" :style="{ width: imageSize, height: imageSize }" />
|
}
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<!-- 商品名称 -->
|
||||||
<div
|
<div
|
||||||
|
v-if="property.fields.name.show"
|
||||||
:class="[
|
:class="[
|
||||||
'flex flex-col gap-8px p-8px box-border',
|
'text-14px ',
|
||||||
{
|
{
|
||||||
'w-[calc(100%-64px)]': columns === 2,
|
truncate: property.layoutType !== 'oneColSmallImg',
|
||||||
'w-full': columns === 3
|
'overflow-ellipsis line-clamp-2': property.layoutType === 'oneColSmallImg'
|
||||||
}
|
}
|
||||||
]"
|
]"
|
||||||
|
:style="{ color: property.fields.name.color }"
|
||||||
>
|
>
|
||||||
<!-- 商品名称 -->
|
{{ spu.name }}
|
||||||
<div
|
</div>
|
||||||
v-if="property.fields.name.show"
|
<!-- 商品简介 -->
|
||||||
class="truncate text-12px"
|
<div
|
||||||
:style="{ color: property.fields.name.color }"
|
v-if="property.fields.introduction.show"
|
||||||
|
class="truncate text-12px"
|
||||||
|
:style="{ color: property.fields.introduction.color }"
|
||||||
|
>
|
||||||
|
{{ spu.introduction }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<!-- 价格 -->
|
||||||
|
<span
|
||||||
|
v-if="property.fields.price.show"
|
||||||
|
class="text-16px"
|
||||||
|
:style="{ color: property.fields.price.color }"
|
||||||
>
|
>
|
||||||
{{ spu.name }}
|
¥{{ fenToYuan(spu.price || Infinity) }}
|
||||||
</div>
|
</span>
|
||||||
<div>
|
<!-- 市场价 -->
|
||||||
<!-- 商品价格 -->
|
<span
|
||||||
<span
|
v-if="property.fields.marketPrice.show && spu.marketPrice"
|
||||||
v-if="property.fields.price.show"
|
class="ml-4px text-10px line-through"
|
||||||
class="text-12px"
|
:style="{ color: property.fields.marketPrice.color }"
|
||||||
:style="{ color: property.fields.price.color }"
|
>¥{{ fenToYuan(spu.marketPrice) }}</span
|
||||||
>
|
>
|
||||||
¥{{ spu.price }}
|
</div>
|
||||||
</span>
|
<div class="text-12px">
|
||||||
</div>
|
<!-- 销量 -->
|
||||||
|
<span
|
||||||
|
v-if="property.fields.salesCount.show"
|
||||||
|
:style="{ color: property.fields.salesCount.color }"
|
||||||
|
>
|
||||||
|
已售{{ (spu.salesCount || 0) + (spu.virtualSalesCount || 0) }}件
|
||||||
|
</span>
|
||||||
|
<!-- 库存 -->
|
||||||
|
<span v-if="property.fields.stock.show" :style="{ color: property.fields.stock.color }">
|
||||||
|
库存{{ spu.stock || 0 }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 购买按钮 -->
|
||||||
|
<div class="absolute bottom-8px right-8px">
|
||||||
|
<!-- 文字按钮 -->
|
||||||
|
<span
|
||||||
|
v-if="property.btnBuy.type === 'text'"
|
||||||
|
class="rounded-full p-x-12px p-y-4px text-12px text-white"
|
||||||
|
:style="{
|
||||||
|
background: `linear-gradient(to right, ${property.btnBuy.bgBeginColor}, ${property.btnBuy.bgEndColor}`
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ property.btnBuy.text }}
|
||||||
|
</span>
|
||||||
|
<!-- 图片按钮 -->
|
||||||
|
<el-image
|
||||||
|
v-else
|
||||||
|
class="h-28px w-28px rounded-full"
|
||||||
|
fit="cover"
|
||||||
|
:src="property.btnBuy.imgUrl"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-scrollbar>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { PromotionSeckillProperty } from './config'
|
import { PromotionSeckillProperty } from './config'
|
||||||
import * as ProductSpuApi from '@/api/mall/product/spu'
|
import * as ProductSpuApi from '@/api/mall/product/spu'
|
||||||
import * as SeckillActivityApi from '@/api/mall/promotion/seckill/seckillActivity'
|
import * as SeckillActivityApi from '@/api/mall/promotion/seckill/seckillActivity'
|
||||||
|
import { fenToYuan } from '@/utils'
|
||||||
|
|
||||||
/** 秒杀 */
|
/** 秒杀卡片 */
|
||||||
defineOptions({ name: 'PromotionSeckill' })
|
defineOptions({ name: 'PromotionSeckill' })
|
||||||
// 定义属性
|
// 定义属性
|
||||||
const props = defineProps<{ property: PromotionSeckillProperty }>()
|
const props = defineProps<{ property: PromotionSeckillProperty }>()
|
||||||
// 商品列表
|
// 商品列表
|
||||||
const spuList = ref<ProductSpuApi.Spu[]>([])
|
const spuList = ref<ProductSpuApi.Spu[]>([])
|
||||||
|
const spuIdList = ref<number[]>([])
|
||||||
|
const seckillActivityList = ref<SeckillActivityApi.SeckillActivityVO[]>([])
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.property.activityId,
|
() => props.property.activityIds,
|
||||||
async () => {
|
async () => {
|
||||||
if (!props.property.activityId) return
|
try {
|
||||||
const activity = await SeckillActivityApi.getSeckillActivity(props.property.activityId)
|
// 新添加的秒杀组件,是没有活动ID的
|
||||||
if (!activity?.spuId) return
|
const activityIds = props.property.activityIds
|
||||||
spuList.value = [await ProductSpuApi.getSpu(activity.spuId)]
|
// 检查活动ID的有效性
|
||||||
|
if (Array.isArray(activityIds) && activityIds.length > 0) {
|
||||||
|
// 获取秒杀活动详情列表
|
||||||
|
seckillActivityList.value =
|
||||||
|
await SeckillActivityApi.getSeckillActivityListByIds(activityIds)
|
||||||
|
|
||||||
|
// 获取秒杀活动的 SPU 详情列表
|
||||||
|
spuList.value = []
|
||||||
|
spuIdList.value = seckillActivityList.value
|
||||||
|
.map((activity) => activity.spuId)
|
||||||
|
.filter((spuId): spuId is number => typeof spuId === 'number')
|
||||||
|
if (spuIdList.value.length > 0) {
|
||||||
|
spuList.value = await ProductSpuApi.getSpuDetailList(spuIdList.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新 SPU 的最低价格
|
||||||
|
seckillActivityList.value.forEach((activity) => {
|
||||||
|
// 匹配spuId
|
||||||
|
const spu = spuList.value.find((spu) => spu.id === activity.spuId)
|
||||||
|
if (spu) {
|
||||||
|
// 赋值活动价格,哪个最便宜就赋值哪个
|
||||||
|
spu.price = Math.min(activity.seckillPrice || Infinity, spu.price || Infinity)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取秒杀活动细节或 SPU 细节时出错:', error)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
immediate: true,
|
immediate: true,
|
||||||
deep: true
|
deep: true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
// 手机宽度
|
|
||||||
const phoneWidth = ref(375)
|
/**
|
||||||
|
* 计算商品的间距
|
||||||
|
* @param index 商品索引
|
||||||
|
*/
|
||||||
|
const calculateSpace = (index: number) => {
|
||||||
|
// 商品的列数
|
||||||
|
const columns = props.property.layoutType === 'twoCol' ? 2 : 1
|
||||||
|
// 第一列没有左边距
|
||||||
|
const marginLeft = index % columns === 0 ? '0' : props.property.space + 'px'
|
||||||
|
// 第一行没有上边距
|
||||||
|
const marginTop = index < columns ? '0' : props.property.space + 'px'
|
||||||
|
|
||||||
|
return { marginLeft, marginTop }
|
||||||
|
}
|
||||||
|
|
||||||
// 容器
|
// 容器
|
||||||
const containerRef = ref()
|
const containerRef = ref()
|
||||||
// 商品的列数
|
// 计算商品的宽度
|
||||||
const columns = ref(2)
|
const calculateWidth = () => {
|
||||||
// 滚动条宽度
|
let width = '100%'
|
||||||
const scrollbarWidth = ref('100%')
|
// 双列时每列的宽度为:(总宽度 - 间距)/ 2
|
||||||
// 商品图大小
|
if (props.property.layoutType === 'twoCol') {
|
||||||
const imageSize = ref('0')
|
width = `${(containerRef.value.offsetWidth - props.property.space) / 2}px`
|
||||||
// 商品网络列数
|
}
|
||||||
const gridTemplateColumns = ref('')
|
return { width }
|
||||||
// 计算布局参数
|
}
|
||||||
watch(
|
|
||||||
() => [props.property, phoneWidth, spuList.value.length],
|
|
||||||
() => {
|
|
||||||
// 计算列数
|
|
||||||
columns.value = props.property.layoutType === 'oneCol' ? 1 : 3
|
|
||||||
// 每列的宽度为:(总宽度 - 间距 * (列数 - 1))/ 列数
|
|
||||||
const productWidth =
|
|
||||||
(phoneWidth.value - props.property.space * (columns.value - 1)) / columns.value
|
|
||||||
// 商品图布局:2列时,左右布局 3列时,上下布局
|
|
||||||
imageSize.value = columns.value === 2 ? '64px' : `${productWidth}px`
|
|
||||||
// 指定列数
|
|
||||||
gridTemplateColumns.value = `repeat(${columns.value}, auto)`
|
|
||||||
// 不滚动
|
|
||||||
scrollbarWidth.value = '100%'
|
|
||||||
},
|
|
||||||
{ immediate: true, deep: true }
|
|
||||||
)
|
|
||||||
onMounted(() => {
|
|
||||||
// 提取手机宽度
|
|
||||||
phoneWidth.value = containerRef.value?.wrapRef?.offsetWidth || 375
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss"></style>
|
<style scoped lang="scss"></style>
|
||||||
@@ -2,30 +2,31 @@
|
|||||||
<ComponentContainerProperty v-model="formData.style">
|
<ComponentContainerProperty v-model="formData.style">
|
||||||
<el-form label-width="80px" :model="formData">
|
<el-form label-width="80px" :model="formData">
|
||||||
<el-card header="秒杀活动" class="property-group" shadow="never">
|
<el-card header="秒杀活动" class="property-group" shadow="never">
|
||||||
<el-form-item label="秒杀活动" prop="activityId">
|
<SeckillShowcase v-model="formData.activityIds" />
|
||||||
<el-select v-model="formData.activityId">
|
|
||||||
<el-option
|
|
||||||
v-for="activity in activityList"
|
|
||||||
:key="activity.id"
|
|
||||||
:label="activity.name"
|
|
||||||
:value="activity.id"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card header="商品样式" class="property-group" shadow="never">
|
<el-card header="商品样式" class="property-group" shadow="never">
|
||||||
<el-form-item label="布局" prop="type">
|
<el-form-item label="布局" prop="type">
|
||||||
<el-radio-group v-model="formData.layoutType">
|
<el-radio-group v-model="formData.layoutType">
|
||||||
<el-tooltip class="item" content="单列" placement="bottom">
|
<el-tooltip class="item" content="单列大图" placement="bottom">
|
||||||
<el-radio-button label="oneCol">
|
<el-radio-button value="oneColBigImg">
|
||||||
<Icon icon="fluent:text-column-one-24-filled" />
|
<Icon icon="fluent:text-column-one-24-filled" />
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip class="item" content="三列" placement="bottom">
|
<el-tooltip class="item" content="单列小图" placement="bottom">
|
||||||
<el-radio-button label="threeCol">
|
<el-radio-button value="oneColSmallImg">
|
||||||
<Icon icon="fluent:text-column-three-24-filled" />
|
<Icon icon="fluent:text-column-two-left-24-filled" />
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
<el-tooltip class="item" content="双列" placement="bottom">
|
||||||
|
<el-radio-button value="twoCol">
|
||||||
|
<Icon icon="fluent:text-column-two-24-filled" />
|
||||||
|
</el-radio-button>
|
||||||
|
</el-tooltip>
|
||||||
|
<!--<el-tooltip class="item" content="三列" placement="bottom">
|
||||||
|
<el-radio-button value="threeCol">
|
||||||
|
<Icon icon="fluent:text-column-three-24-filled" />
|
||||||
|
</el-radio-button>
|
||||||
|
</el-tooltip>-->
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="商品名称" prop="fields.name.show">
|
<el-form-item label="商品名称" prop="fields.name.show">
|
||||||
@@ -34,12 +35,36 @@
|
|||||||
<el-checkbox v-model="formData.fields.name.show" />
|
<el-checkbox v-model="formData.fields.name.show" />
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="商品简介" prop="fields.introduction.show">
|
||||||
|
<div class="flex gap-8px">
|
||||||
|
<ColorInput v-model="formData.fields.introduction.color" />
|
||||||
|
<el-checkbox v-model="formData.fields.introduction.show" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="商品价格" prop="fields.price.show">
|
<el-form-item label="商品价格" prop="fields.price.show">
|
||||||
<div class="flex gap-8px">
|
<div class="flex gap-8px">
|
||||||
<ColorInput v-model="formData.fields.price.color" />
|
<ColorInput v-model="formData.fields.price.color" />
|
||||||
<el-checkbox v-model="formData.fields.price.show" />
|
<el-checkbox v-model="formData.fields.price.show" />
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="市场价" prop="fields.marketPrice.show">
|
||||||
|
<div class="flex gap-8px">
|
||||||
|
<ColorInput v-model="formData.fields.marketPrice.color" />
|
||||||
|
<el-checkbox v-model="formData.fields.marketPrice.show" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="商品销量" prop="fields.salesCount.show">
|
||||||
|
<div class="flex gap-8px">
|
||||||
|
<ColorInput v-model="formData.fields.salesCount.color" />
|
||||||
|
<el-checkbox v-model="formData.fields.salesCount.show" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="商品库存" prop="fields.stock.show">
|
||||||
|
<div class="flex gap-8px">
|
||||||
|
<ColorInput v-model="formData.fields.stock.color" />
|
||||||
|
<el-checkbox v-model="formData.fields.stock.show" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card header="角标" class="property-group" shadow="never">
|
<el-card header="角标" class="property-group" shadow="never">
|
||||||
<el-form-item label="角标" prop="badge.show">
|
<el-form-item label="角标" prop="badge.show">
|
||||||
@@ -47,10 +72,36 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="角标" prop="badge.imgUrl" v-if="formData.badge.show">
|
<el-form-item label="角标" prop="badge.imgUrl" v-if="formData.badge.show">
|
||||||
<UploadImg v-model="formData.badge.imgUrl" height="44px" width="72px">
|
<UploadImg v-model="formData.badge.imgUrl" height="44px" width="72px">
|
||||||
<template #tip> 建议尺寸:36 * 22 </template>
|
<template #tip> 建议尺寸:36 * 22</template>
|
||||||
</UploadImg>
|
</UploadImg>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
<el-card header="按钮" class="property-group" shadow="never">
|
||||||
|
<el-form-item label="按钮类型" prop="btnBuy.type">
|
||||||
|
<el-radio-group v-model="formData.btnBuy.type">
|
||||||
|
<el-radio-button value="text">文字</el-radio-button>
|
||||||
|
<el-radio-button value="img">图片</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<template v-if="formData.btnBuy.type === 'text'">
|
||||||
|
<el-form-item label="按钮文字" prop="btnBuy.text">
|
||||||
|
<el-input v-model="formData.btnBuy.text" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="左侧背景" prop="btnBuy.bgBeginColor">
|
||||||
|
<ColorInput v-model="formData.btnBuy.bgBeginColor" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="右侧背景" prop="btnBuy.bgEndColor">
|
||||||
|
<ColorInput v-model="formData.btnBuy.bgEndColor" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<el-form-item label="图片" prop="btnBuy.imgUrl">
|
||||||
|
<UploadImg v-model="formData.btnBuy.imgUrl" height="56px" width="56px">
|
||||||
|
<template #tip> 建议尺寸:56 * 56</template>
|
||||||
|
</UploadImg>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-card>
|
||||||
<el-card header="商品样式" class="property-group" shadow="never">
|
<el-card header="商品样式" class="property-group" shadow="never">
|
||||||
<el-form-item label="上圆角" prop="borderRadiusTop">
|
<el-form-item label="上圆角" prop="borderRadiusTop">
|
||||||
<el-slider
|
<el-slider
|
||||||
@@ -92,6 +143,7 @@ import { PromotionSeckillProperty } from './config'
|
|||||||
import { usePropertyForm } from '@/components/DiyEditor/util'
|
import { usePropertyForm } from '@/components/DiyEditor/util'
|
||||||
import * as SeckillActivityApi from '@/api/mall/promotion/seckill/seckillActivity'
|
import * as SeckillActivityApi from '@/api/mall/promotion/seckill/seckillActivity'
|
||||||
import { CommonStatusEnum } from '@/utils/constants'
|
import { CommonStatusEnum } from '@/utils/constants'
|
||||||
|
import SeckillShowcase from '@/views/mall/promotion/seckill/components/SeckillShowcase.vue'
|
||||||
|
|
||||||
// 秒杀属性面板
|
// 秒杀属性面板
|
||||||
defineOptions({ name: 'PromotionSeckillProperty' })
|
defineOptions({ name: 'PromotionSeckillProperty' })
|
||||||
@@ -100,7 +152,7 @@ const props = defineProps<{ modelValue: PromotionSeckillProperty }>()
|
|||||||
const emit = defineEmits(['update:modelValue'])
|
const emit = defineEmits(['update:modelValue'])
|
||||||
const { formData } = usePropertyForm(props.modelValue, emit)
|
const { formData } = usePropertyForm(props.modelValue, emit)
|
||||||
// 活动列表
|
// 活动列表
|
||||||
const activityList = ref<SeckillActivityApi.SeckillActivityVO>([])
|
const activityList = ref<SeckillActivityApi.SeckillActivityVO[]>([])
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
const { list } = await SeckillActivityApi.getSeckillActivityPage({
|
const { list } = await SeckillActivityApi.getSeckillActivityPage({
|
||||||
status: CommonStatusEnum.ENABLE
|
status: CommonStatusEnum.ENABLE
|
||||||
|
|||||||
@@ -13,12 +13,12 @@
|
|||||||
<el-form-item label="框体样式">
|
<el-form-item label="框体样式">
|
||||||
<el-radio-group v-model="formData!.borderRadius">
|
<el-radio-group v-model="formData!.borderRadius">
|
||||||
<el-tooltip content="方形" placement="top">
|
<el-tooltip content="方形" placement="top">
|
||||||
<el-radio-button :label="0">
|
<el-radio-button :value="0">
|
||||||
<Icon icon="tabler:input-search" />
|
<Icon icon="tabler:input-search" />
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip content="圆形" placement="top">
|
<el-tooltip content="圆形" placement="top">
|
||||||
<el-radio-button :label="10">
|
<el-radio-button :value="10">
|
||||||
<Icon icon="iconoir:input-search" />
|
<Icon icon="iconoir:input-search" />
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
@@ -30,12 +30,12 @@
|
|||||||
<el-form-item label="文本位置" prop="placeholderPosition">
|
<el-form-item label="文本位置" prop="placeholderPosition">
|
||||||
<el-radio-group v-model="formData!.placeholderPosition">
|
<el-radio-group v-model="formData!.placeholderPosition">
|
||||||
<el-tooltip content="居左" placement="top">
|
<el-tooltip content="居左" placement="top">
|
||||||
<el-radio-button label="left">
|
<el-radio-button value="left">
|
||||||
<Icon icon="ant-design:align-left-outlined" />
|
<Icon icon="ant-design:align-left-outlined" />
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip content="居中" placement="top">
|
<el-tooltip content="居中" placement="top">
|
||||||
<el-radio-button label="center">
|
<el-radio-button value="center">
|
||||||
<Icon icon="ant-design:align-center-outlined" />
|
<Icon icon="ant-design:align-center-outlined" />
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|||||||
@@ -27,8 +27,8 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="导航背景">
|
<el-form-item label="导航背景">
|
||||||
<el-radio-group v-model="formData!.style.bgType">
|
<el-radio-group v-model="formData!.style.bgType">
|
||||||
<el-radio-button label="color">纯色</el-radio-button>
|
<el-radio-button value="color">纯色</el-radio-button>
|
||||||
<el-radio-button label="img">图片</el-radio-button>
|
<el-radio-button value="img">图片</el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="选择颜色" v-if="formData!.style.bgType === 'color'">
|
<el-form-item label="选择颜色" v-if="formData!.style.bgType === 'color'">
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { TabBarProperty, THEME_LIST } from './config'
|
import { TabBarProperty, component, THEME_LIST } from './config'
|
||||||
import { usePropertyForm } from '@/components/DiyEditor/util'
|
import { usePropertyForm } from '@/components/DiyEditor/util'
|
||||||
// 底部导航栏
|
// 底部导航栏
|
||||||
defineOptions({ name: 'TabBarProperty' })
|
defineOptions({ name: 'TabBarProperty' })
|
||||||
@@ -88,6 +88,9 @@ const props = defineProps<{ modelValue: TabBarProperty }>()
|
|||||||
const emit = defineEmits(['update:modelValue'])
|
const emit = defineEmits(['update:modelValue'])
|
||||||
const { formData } = usePropertyForm(props.modelValue, emit)
|
const { formData } = usePropertyForm(props.modelValue, emit)
|
||||||
|
|
||||||
|
// 将数据库的值更新到右侧属性栏
|
||||||
|
component.property.items = formData.value.items
|
||||||
|
|
||||||
// 要的主题
|
// 要的主题
|
||||||
const handleThemeChange = () => {
|
const handleThemeChange = () => {
|
||||||
const theme = THEME_LIST.find((theme) => theme.id === formData.value.theme)
|
const theme = THEME_LIST.find((theme) => theme.id === formData.value.theme)
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import { ComponentStyle, DiyComponent } from '@/components/DiyEditor/util'
|
import {ComponentStyle, DiyComponent} from '@/components/DiyEditor/util'
|
||||||
|
|
||||||
/** 标题栏属性 */
|
/** 标题栏属性 */
|
||||||
export interface TitleBarProperty {
|
export interface TitleBarProperty {
|
||||||
// 背景图
|
|
||||||
bgImgUrl: string
|
|
||||||
// 偏移
|
// 偏移
|
||||||
marginLeft: number
|
marginLeft: number
|
||||||
// 显示位置
|
// 显示位置
|
||||||
|
|||||||
@@ -1,21 +1,30 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="title-bar">
|
<div
|
||||||
<el-image v-if="property.bgImgUrl" :src="property.bgImgUrl" fit="cover" class="w-full" />
|
:style="{
|
||||||
<div class="absolute left-0 top-0 w-full">
|
background:
|
||||||
|
property.style.bgType === 'color' ? property.style.bgColor : `url(${property.style.bgImg})`,
|
||||||
|
backgroundSize: '100% 100%',
|
||||||
|
backgroundRepeat: 'no-repeat'
|
||||||
|
}"
|
||||||
|
class="title-bar"
|
||||||
|
>
|
||||||
|
<!-- 内容 -->
|
||||||
|
<div>
|
||||||
<!-- 标题 -->
|
<!-- 标题 -->
|
||||||
<div
|
<div
|
||||||
|
v-if="property.title"
|
||||||
:style="{
|
:style="{
|
||||||
fontSize: `${property.titleSize}px`,
|
fontSize: `${property.titleSize}px`,
|
||||||
fontWeight: property.titleWeight,
|
fontWeight: property.titleWeight,
|
||||||
color: property.titleColor,
|
color: property.titleColor,
|
||||||
textAlign: property.textAlign
|
textAlign: property.textAlign
|
||||||
}"
|
}"
|
||||||
v-if="property.title"
|
|
||||||
>
|
>
|
||||||
{{ property.title }}
|
{{ property.title }}
|
||||||
</div>
|
</div>
|
||||||
<!-- 副标题 -->
|
<!-- 副标题 -->
|
||||||
<div
|
<div
|
||||||
|
v-if="property.description"
|
||||||
:style="{
|
:style="{
|
||||||
fontSize: `${property.descriptionSize}px`,
|
fontSize: `${property.descriptionSize}px`,
|
||||||
fontWeight: property.descriptionWeight,
|
fontWeight: property.descriptionWeight,
|
||||||
@@ -23,25 +32,24 @@
|
|||||||
textAlign: property.textAlign
|
textAlign: property.textAlign
|
||||||
}"
|
}"
|
||||||
class="m-t-8px"
|
class="m-t-8px"
|
||||||
v-if="property.description"
|
|
||||||
>
|
>
|
||||||
{{ property.description }}
|
{{ property.description }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 更多 -->
|
<!-- 更多 -->
|
||||||
<div
|
<div
|
||||||
class="more"
|
|
||||||
v-show="property.more.show"
|
v-show="property.more.show"
|
||||||
:style="{
|
:style="{
|
||||||
color: property.descriptionColor
|
color: property.descriptionColor
|
||||||
}"
|
}"
|
||||||
|
class="more"
|
||||||
>
|
>
|
||||||
<span v-if="property.more.type !== 'icon'"> {{ property.more.text }} </span>
|
<span v-if="property.more.type !== 'icon'"> {{ property.more.text }} </span>
|
||||||
<Icon icon="ep:arrow-right" v-if="property.more.type !== 'text'" />
|
<Icon v-if="property.more.type !== 'text'" icon="ep:arrow-right" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script lang="ts" setup>
|
||||||
import { TitleBarProperty } from './config'
|
import { TitleBarProperty } from './config'
|
||||||
|
|
||||||
/** 标题栏 */
|
/** 标题栏 */
|
||||||
@@ -49,7 +57,7 @@ defineOptions({ name: 'TitleBar' })
|
|||||||
|
|
||||||
defineProps<{ property: TitleBarProperty }>()
|
defineProps<{ property: TitleBarProperty }>()
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="scss">
|
<style lang="scss" scoped>
|
||||||
.title-bar {
|
.title-bar {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
@@ -1,86 +1,81 @@
|
|||||||
<template>
|
<template>
|
||||||
<ComponentContainerProperty v-model="formData.style">
|
<ComponentContainerProperty v-model="formData.style">
|
||||||
<el-form label-width="85px" :model="formData" :rules="rules">
|
<el-form :model="formData" :rules="rules" label-width="85px">
|
||||||
<el-card header="风格" class="property-group" shadow="never">
|
<el-card class="property-group" header="风格" shadow="never">
|
||||||
<el-form-item label="背景图片" prop="bgImgUrl">
|
|
||||||
<UploadImg v-model="formData.bgImgUrl" width="100%" height="40px">
|
|
||||||
<template #tip>建议尺寸 750*80</template>
|
|
||||||
</UploadImg>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="标题位置" prop="textAlign">
|
<el-form-item label="标题位置" prop="textAlign">
|
||||||
<el-radio-group v-model="formData!.textAlign">
|
<el-radio-group v-model="formData!.textAlign">
|
||||||
<el-tooltip content="居左" placement="top">
|
<el-tooltip content="居左" placement="top">
|
||||||
<el-radio-button label="left">
|
<el-radio-button value="left">
|
||||||
<Icon icon="ant-design:align-left-outlined" />
|
<Icon icon="ant-design:align-left-outlined" />
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip content="居中" placement="top">
|
<el-tooltip content="居中" placement="top">
|
||||||
<el-radio-button label="center">
|
<el-radio-button value="center">
|
||||||
<Icon icon="ant-design:align-center-outlined" />
|
<Icon icon="ant-design:align-center-outlined" />
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card header="主标题" class="property-group" shadow="never">
|
<el-card class="property-group" header="主标题" shadow="never">
|
||||||
<el-form-item label="文字" prop="title" label-width="40px">
|
<el-form-item label="文字" label-width="40px" prop="title">
|
||||||
<InputWithColor
|
<InputWithColor
|
||||||
v-model="formData.title"
|
v-model="formData.title"
|
||||||
v-model:color="formData.titleColor"
|
v-model:color="formData.titleColor"
|
||||||
show-word-limit
|
|
||||||
maxlength="20"
|
maxlength="20"
|
||||||
|
show-word-limit
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="大小" prop="titleSize" label-width="40px">
|
<el-form-item label="大小" label-width="40px" prop="titleSize">
|
||||||
<el-slider
|
<el-slider
|
||||||
v-model="formData.titleSize"
|
v-model="formData.titleSize"
|
||||||
:max="60"
|
:max="60"
|
||||||
:min="10"
|
:min="10"
|
||||||
show-input
|
|
||||||
input-size="small"
|
input-size="small"
|
||||||
|
show-input
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="粗细" prop="titleWeight" label-width="40px">
|
<el-form-item label="粗细" label-width="40px" prop="titleWeight">
|
||||||
<el-slider
|
<el-slider
|
||||||
v-model="formData.titleWeight"
|
v-model="formData.titleWeight"
|
||||||
:min="100"
|
|
||||||
:max="900"
|
:max="900"
|
||||||
|
:min="100"
|
||||||
:step="100"
|
:step="100"
|
||||||
show-input
|
|
||||||
input-size="small"
|
input-size="small"
|
||||||
|
show-input
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card header="副标题" class="property-group" shadow="never">
|
<el-card class="property-group" header="副标题" shadow="never">
|
||||||
<el-form-item label="文字" prop="description" label-width="40px">
|
<el-form-item label="文字" label-width="40px" prop="description">
|
||||||
<InputWithColor
|
<InputWithColor
|
||||||
v-model="formData.description"
|
v-model="formData.description"
|
||||||
v-model:color="formData.descriptionColor"
|
v-model:color="formData.descriptionColor"
|
||||||
show-word-limit
|
|
||||||
maxlength="50"
|
maxlength="50"
|
||||||
|
show-word-limit
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="大小" prop="descriptionSize" label-width="40px">
|
<el-form-item label="大小" label-width="40px" prop="descriptionSize">
|
||||||
<el-slider
|
<el-slider
|
||||||
v-model="formData.descriptionSize"
|
v-model="formData.descriptionSize"
|
||||||
:max="60"
|
:max="60"
|
||||||
:min="10"
|
:min="10"
|
||||||
show-input
|
|
||||||
input-size="small"
|
input-size="small"
|
||||||
|
show-input
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="粗细" prop="descriptionWeight" label-width="40px">
|
<el-form-item label="粗细" label-width="40px" prop="descriptionWeight">
|
||||||
<el-slider
|
<el-slider
|
||||||
v-model="formData.descriptionWeight"
|
v-model="formData.descriptionWeight"
|
||||||
:min="100"
|
|
||||||
:max="900"
|
:max="900"
|
||||||
|
:min="100"
|
||||||
:step="100"
|
:step="100"
|
||||||
show-input
|
|
||||||
input-size="small"
|
input-size="small"
|
||||||
|
show-input
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card header="查看更多" class="property-group" shadow="never">
|
<el-card class="property-group" header="查看更多" shadow="never">
|
||||||
<el-form-item label="是否显示" prop="more.show">
|
<el-form-item label="是否显示" prop="more.show">
|
||||||
<el-checkbox v-model="formData.more.show" />
|
<el-checkbox v-model="formData.more.show" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -88,12 +83,12 @@
|
|||||||
<template v-if="formData.more.show">
|
<template v-if="formData.more.show">
|
||||||
<el-form-item label="样式" prop="more.type">
|
<el-form-item label="样式" prop="more.type">
|
||||||
<el-radio-group v-model="formData.more.type">
|
<el-radio-group v-model="formData.more.type">
|
||||||
<el-radio label="text">文字</el-radio>
|
<el-radio value="text">文字</el-radio>
|
||||||
<el-radio label="icon">图标</el-radio>
|
<el-radio value="icon">图标</el-radio>
|
||||||
<el-radio label="all">文字+图标</el-radio>
|
<el-radio value="all">文字+图标</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="更多文字" prop="more.text" v-show="formData.more.type !== 'icon'">
|
<el-form-item v-show="formData.more.type !== 'icon'" label="更多文字" prop="more.text">
|
||||||
<el-input v-model="formData.more.text" />
|
<el-input v-model="formData.more.text" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="跳转链接" prop="more.url">
|
<el-form-item label="跳转链接" prop="more.url">
|
||||||
@@ -104,7 +99,7 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
</ComponentContainerProperty>
|
</ComponentContainerProperty>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script lang="ts" setup>
|
||||||
import { TitleBarProperty } from './config'
|
import { TitleBarProperty } from './config'
|
||||||
import { usePropertyForm } from '@/components/DiyEditor/util'
|
import { usePropertyForm } from '@/components/DiyEditor/util'
|
||||||
// 导航栏属性面板
|
// 导航栏属性面板
|
||||||
@@ -118,4 +113,4 @@ const { formData } = usePropertyForm(props.modelValue, emit)
|
|||||||
const rules = {}
|
const rules = {}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss"></style>
|
<style lang="scss" scoped></style>
|
||||||
@@ -12,17 +12,17 @@
|
|||||||
<el-button-group class="header-right">
|
<el-button-group class="header-right">
|
||||||
<el-tooltip content="重置">
|
<el-tooltip content="重置">
|
||||||
<el-button @click="handleReset">
|
<el-button @click="handleReset">
|
||||||
<Icon icon="system-uicons:reset-alt" :size="24" />
|
<Icon :size="24" icon="system-uicons:reset-alt" />
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip content="预览" v-if="previewUrl">
|
<el-tooltip v-if="previewUrl" content="预览">
|
||||||
<el-button @click="handlePreview">
|
<el-button @click="handlePreview">
|
||||||
<Icon icon="ep:view" :size="24" />
|
<Icon :size="24" icon="ep:view" />
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip content="保存">
|
<el-tooltip content="保存">
|
||||||
<el-button @click="handleSave">
|
<el-button @click="handleSave">
|
||||||
<Icon icon="ep:check" :size="24" />
|
<Icon :size="24" icon="ep:check" />
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-button-group>
|
</el-button-group>
|
||||||
@@ -31,21 +31,21 @@
|
|||||||
<!-- 中心区域 -->
|
<!-- 中心区域 -->
|
||||||
<el-container class="editor-container">
|
<el-container class="editor-container">
|
||||||
<!-- 左侧:组件库(ComponentLibrary) -->
|
<!-- 左侧:组件库(ComponentLibrary) -->
|
||||||
<ComponentLibrary ref="componentLibrary" :list="libs" v-if="libs && libs.length > 0" />
|
<ComponentLibrary v-if="libs && libs.length > 0" ref="componentLibrary" :list="libs" />
|
||||||
<!-- 中心:设计区域(ComponentContainer) -->
|
<!-- 中心:设计区域(ComponentContainer) -->
|
||||||
<div class="editor-center page-prop-area" @click="handlePageSelected">
|
<div class="editor-center page-prop-area" @click="handlePageSelected">
|
||||||
<!-- 手机顶部 -->
|
<!-- 手机顶部 -->
|
||||||
<div class="editor-design-top">
|
<div class="editor-design-top">
|
||||||
<!-- 手机顶部状态栏 -->
|
<!-- 手机顶部状态栏 -->
|
||||||
<img src="@/assets/imgs/diy/statusBar.png" alt="" class="status-bar" />
|
<img alt="" class="status-bar" src="@/assets/imgs/diy/statusBar.png" />
|
||||||
<!-- 手机顶部导航栏 -->
|
<!-- 手机顶部导航栏 -->
|
||||||
<ComponentContainer
|
<ComponentContainer
|
||||||
v-if="showNavigationBar"
|
v-if="showNavigationBar"
|
||||||
|
:active="selectedComponent?.id === navigationBarComponent.id"
|
||||||
:component="navigationBarComponent"
|
:component="navigationBarComponent"
|
||||||
:show-toolbar="false"
|
:show-toolbar="false"
|
||||||
:active="selectedComponent?.id === navigationBarComponent.id"
|
|
||||||
@click="handleNavigationBarSelected"
|
|
||||||
class="cursor-pointer!"
|
class="cursor-pointer!"
|
||||||
|
@click="handleNavigationBarSelected"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<!-- 绝对定位的组件:例如 弹窗、浮动按钮等 -->
|
<!-- 绝对定位的组件:例如 弹窗、浮动按钮等 -->
|
||||||
@@ -55,43 +55,43 @@
|
|||||||
@click="handleComponentSelected(component, index)"
|
@click="handleComponentSelected(component, index)"
|
||||||
>
|
>
|
||||||
<component
|
<component
|
||||||
v-if="component.position === 'fixed' && selectedComponent?.uid === component.uid"
|
|
||||||
:is="component.id"
|
:is="component.id"
|
||||||
|
v-if="component.position === 'fixed' && selectedComponent?.uid === component.uid"
|
||||||
:property="component.property"
|
:property="component.property"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<!-- 手机页面编辑区域 -->
|
<!-- 手机页面编辑区域 -->
|
||||||
<el-scrollbar
|
<el-scrollbar
|
||||||
height="100%"
|
|
||||||
wrap-class="editor-design-center page-prop-area"
|
|
||||||
view-class="phone-container"
|
|
||||||
:view-style="{
|
:view-style="{
|
||||||
backgroundColor: pageConfigComponent.property.backgroundColor,
|
backgroundColor: pageConfigComponent.property.backgroundColor,
|
||||||
backgroundImage: `url(${pageConfigComponent.property.backgroundImage})`
|
backgroundImage: `url(${pageConfigComponent.property.backgroundImage})`
|
||||||
}"
|
}"
|
||||||
|
height="100%"
|
||||||
|
view-class="phone-container"
|
||||||
|
wrap-class="editor-design-center page-prop-area"
|
||||||
>
|
>
|
||||||
<draggable
|
<draggable
|
||||||
class="page-prop-area drag-area"
|
|
||||||
v-model="pageComponents"
|
v-model="pageComponents"
|
||||||
item-key="index"
|
|
||||||
:animation="200"
|
:animation="200"
|
||||||
|
:force-fallback="true"
|
||||||
|
class="page-prop-area drag-area"
|
||||||
filter=".component-toolbar"
|
filter=".component-toolbar"
|
||||||
ghost-class="draggable-ghost"
|
ghost-class="draggable-ghost"
|
||||||
:force-fallback="true"
|
|
||||||
group="component"
|
group="component"
|
||||||
|
item-key="index"
|
||||||
@change="handleComponentChange"
|
@change="handleComponentChange"
|
||||||
>
|
>
|
||||||
<template #item="{ element, index }">
|
<template #item="{ element, index }">
|
||||||
<ComponentContainer
|
<ComponentContainer
|
||||||
v-if="!element.position || element.position === 'center'"
|
v-if="!element.position || element.position === 'center'"
|
||||||
:component="element"
|
|
||||||
:active="selectedComponentIndex === index"
|
:active="selectedComponentIndex === index"
|
||||||
:can-move-up="index > 0"
|
|
||||||
:can-move-down="index < pageComponents.length - 1"
|
:can-move-down="index < pageComponents.length - 1"
|
||||||
@move="(direction) => handleMoveComponent(index, direction)"
|
:can-move-up="index > 0"
|
||||||
|
:component="element"
|
||||||
|
@click="handleComponentSelected(element, index)"
|
||||||
@copy="handleCopyComponent(index)"
|
@copy="handleCopyComponent(index)"
|
||||||
@delete="handleDeleteComponent(index)"
|
@delete="handleDeleteComponent(index)"
|
||||||
@click="handleComponentSelected(element, index)"
|
@move="(direction) => handleMoveComponent(index, direction)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</draggable>
|
</draggable>
|
||||||
@@ -99,9 +99,9 @@
|
|||||||
<!-- 手机底部导航 -->
|
<!-- 手机底部导航 -->
|
||||||
<div v-if="showTabBar" :class="['editor-design-bottom', 'component', 'cursor-pointer!']">
|
<div v-if="showTabBar" :class="['editor-design-bottom', 'component', 'cursor-pointer!']">
|
||||||
<ComponentContainer
|
<ComponentContainer
|
||||||
|
:active="selectedComponent?.id === tabBarComponent.id"
|
||||||
:component="tabBarComponent"
|
:component="tabBarComponent"
|
||||||
:show-toolbar="false"
|
:show-toolbar="false"
|
||||||
:active="selectedComponent?.id === tabBarComponent.id"
|
|
||||||
@click="handleTabBarSelected"
|
@click="handleTabBarSelected"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -109,9 +109,9 @@
|
|||||||
<div class="fixed-component-action-group">
|
<div class="fixed-component-action-group">
|
||||||
<el-tag
|
<el-tag
|
||||||
v-if="showPageConfig"
|
v-if="showPageConfig"
|
||||||
size="large"
|
|
||||||
:effect="selectedComponent?.uid === pageConfigComponent.uid ? 'dark' : 'plain'"
|
:effect="selectedComponent?.uid === pageConfigComponent.uid ? 'dark' : 'plain'"
|
||||||
:type="selectedComponent?.uid === pageConfigComponent.uid ? '' : 'info'"
|
:type="selectedComponent?.uid === pageConfigComponent.uid ? '' : 'info'"
|
||||||
|
size="large"
|
||||||
@click="handleComponentSelected(pageConfigComponent)"
|
@click="handleComponentSelected(pageConfigComponent)"
|
||||||
>
|
>
|
||||||
<Icon :icon="pageConfigComponent.icon" :size="12" />
|
<Icon :icon="pageConfigComponent.icon" :size="12" />
|
||||||
@@ -120,10 +120,10 @@
|
|||||||
<template v-for="(component, index) in pageComponents" :key="index">
|
<template v-for="(component, index) in pageComponents" :key="index">
|
||||||
<el-tag
|
<el-tag
|
||||||
v-if="component.position === 'fixed'"
|
v-if="component.position === 'fixed'"
|
||||||
size="large"
|
|
||||||
closable
|
|
||||||
:effect="selectedComponent?.uid === component.uid ? 'dark' : 'plain'"
|
:effect="selectedComponent?.uid === component.uid ? 'dark' : 'plain'"
|
||||||
:type="selectedComponent?.uid === component.uid ? '' : 'info'"
|
:type="selectedComponent?.uid === component.uid ? '' : 'info'"
|
||||||
|
closable
|
||||||
|
size="large"
|
||||||
@click="handleComponentSelected(component)"
|
@click="handleComponentSelected(component)"
|
||||||
@close="handleDeleteComponent(index)"
|
@close="handleDeleteComponent(index)"
|
||||||
>
|
>
|
||||||
@@ -134,11 +134,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 右侧:属性面板(ComponentContainerProperty) -->
|
<!-- 右侧:属性面板(ComponentContainerProperty) -->
|
||||||
<el-aside class="editor-right" width="350px" v-if="selectedComponent?.property">
|
<el-aside v-if="selectedComponent?.property" class="editor-right" width="350px">
|
||||||
<el-card
|
<el-card
|
||||||
shadow="never"
|
|
||||||
body-class="h-[calc(100%-var(--el-card-padding)-var(--el-card-padding))]"
|
body-class="h-[calc(100%-var(--el-card-padding)-var(--el-card-padding))]"
|
||||||
class="h-full"
|
class="h-full"
|
||||||
|
shadow="never"
|
||||||
>
|
>
|
||||||
<!-- 组件名称 -->
|
<!-- 组件名称 -->
|
||||||
<template #header>
|
<template #header>
|
||||||
@@ -152,8 +152,8 @@
|
|||||||
view-class="p-[var(--el-card-padding)] p-b-[calc(var(--el-card-padding)+var(--el-card-padding))] property"
|
view-class="p-[var(--el-card-padding)] p-b-[calc(var(--el-card-padding)+var(--el-card-padding))] property"
|
||||||
>
|
>
|
||||||
<component
|
<component
|
||||||
:key="selectedComponent?.uid || selectedComponent?.id"
|
|
||||||
:is="selectedComponent?.id + 'Property'"
|
:is="selectedComponent?.id + 'Property'"
|
||||||
|
:key="selectedComponent?.uid || selectedComponent?.id"
|
||||||
v-model="selectedComponent.property"
|
v-model="selectedComponent.property"
|
||||||
/>
|
/>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
@@ -166,8 +166,8 @@
|
|||||||
<Dialog v-model="previewDialogVisible" title="预览" width="700">
|
<Dialog v-model="previewDialogVisible" title="预览" width="700">
|
||||||
<div class="flex justify-around">
|
<div class="flex justify-around">
|
||||||
<IFrame
|
<IFrame
|
||||||
class="w-375px border-4px border-rounded-8px border-solid p-2px h-667px!"
|
|
||||||
:src="previewUrl"
|
:src="previewUrl"
|
||||||
|
class="w-375px border-4px border-rounded-8px border-solid p-2px h-667px!"
|
||||||
/>
|
/>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<el-text>手机扫码预览</el-text>
|
<el-text>手机扫码预览</el-text>
|
||||||
@@ -179,6 +179,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
// 注册所有的组件
|
// 注册所有的组件
|
||||||
import { components } from './components/mobile/index'
|
import { components } from './components/mobile/index'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { ...components }
|
components: { ...components }
|
||||||
}
|
}
|
||||||
@@ -257,6 +258,11 @@ watch(
|
|||||||
|
|
||||||
// 保存
|
// 保存
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
|
// 发送保存通知
|
||||||
|
emits('save')
|
||||||
|
}
|
||||||
|
// 监听配置修改
|
||||||
|
const pageConfigChange = () => {
|
||||||
const pageConfig = {
|
const pageConfig = {
|
||||||
page: pageConfigComponent.value.property,
|
page: pageConfigComponent.value.property,
|
||||||
navigationBar: navigationBarComponent.value.property,
|
navigationBar: navigationBarComponent.value.property,
|
||||||
@@ -272,10 +278,19 @@ const handleSave = () => {
|
|||||||
// 发送数据更新通知
|
// 发送数据更新通知
|
||||||
const modelValue = isString(props.modelValue) ? JSON.stringify(pageConfig) : pageConfig
|
const modelValue = isString(props.modelValue) ? JSON.stringify(pageConfig) : pageConfig
|
||||||
emits('update:modelValue', modelValue)
|
emits('update:modelValue', modelValue)
|
||||||
// 发送保存通知
|
|
||||||
emits('save', pageConfig)
|
|
||||||
}
|
}
|
||||||
|
watch(
|
||||||
|
() => [
|
||||||
|
pageConfigComponent.value.property,
|
||||||
|
navigationBarComponent.value.property,
|
||||||
|
tabBarComponent.value.property,
|
||||||
|
pageComponents.value
|
||||||
|
],
|
||||||
|
() => {
|
||||||
|
pageConfigChange()
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
)
|
||||||
// 处理页面选中:显示属性表单
|
// 处理页面选中:显示属性表单
|
||||||
const handlePageSelected = (event: any) => {
|
const handlePageSelected = (event: any) => {
|
||||||
if (!props.showPageConfig) return
|
if (!props.showPageConfig) return
|
||||||
@@ -547,6 +562,7 @@ $toolbar-height: 42px;
|
|||||||
:deep(.el-tag) {
|
:deep(.el-tag) {
|
||||||
box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.1);
|
box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.1);
|
||||||
border: none;
|
border: none;
|
||||||
|
|
||||||
.el-tag__content {
|
.el-tag__content {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -13,9 +13,9 @@
|
|||||||
class="mb-4px flex flex-col gap-4px border border-gray-2 border-rounded rounded border-solid p-8px"
|
class="mb-4px flex flex-col gap-4px border border-gray-2 border-rounded rounded border-solid p-8px"
|
||||||
>
|
>
|
||||||
<!-- 操作按钮区 -->
|
<!-- 操作按钮区 -->
|
||||||
<div class="m--8px m-b-4px flex flex-row items-center justify-between bg-gray-1 p-8px">
|
<div class="m--8px m-b-4px flex flex-row items-center justify-between p-8px" style="background-color: var(--app-content-bg-color);">
|
||||||
<el-tooltip content="拖动排序">
|
<el-tooltip content="拖动排序">
|
||||||
<Icon icon="ic:round-drag-indicator" class="drag-icon cursor-move" />
|
<Icon icon="ic:round-drag-indicator" class="drag-icon cursor-move" style="color: #8a909c;" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip content="删除">
|
<el-tooltip content="删除">
|
||||||
<Icon
|
<Icon
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ import { propTypes } from '@/utils/propTypes'
|
|||||||
import { isNumber } from '@/utils/is'
|
import { isNumber } from '@/utils/is'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { useLocaleStore } from '@/store/modules/locale'
|
import { useLocaleStore } from '@/store/modules/locale'
|
||||||
import { getAccessToken, getTenantId } from '@/utils/auth'
|
import { getRefreshToken, getTenantId } from '@/utils/auth'
|
||||||
|
import { getUploadUrl } from '@/components/UploadFile/src/useUpload'
|
||||||
|
|
||||||
defineOptions({ name: 'Editor' })
|
defineOptions({ name: 'Editor' })
|
||||||
|
|
||||||
@@ -88,7 +89,7 @@ const editorConfig = computed((): IEditorConfig => {
|
|||||||
scroll: true,
|
scroll: true,
|
||||||
MENU_CONF: {
|
MENU_CONF: {
|
||||||
['uploadImage']: {
|
['uploadImage']: {
|
||||||
server: import.meta.env.VITE_UPLOAD_URL,
|
server: getUploadUrl(),
|
||||||
// 单个文件的最大体积限制,默认为 2M
|
// 单个文件的最大体积限制,默认为 2M
|
||||||
maxFileSize: 5 * 1024 * 1024,
|
maxFileSize: 5 * 1024 * 1024,
|
||||||
// 最多可上传几个文件,默认为 100
|
// 最多可上传几个文件,默认为 100
|
||||||
@@ -99,7 +100,7 @@ const editorConfig = computed((): IEditorConfig => {
|
|||||||
// 自定义增加 http header
|
// 自定义增加 http header
|
||||||
headers: {
|
headers: {
|
||||||
Accept: '*',
|
Accept: '*',
|
||||||
Authorization: 'Bearer ' + getAccessToken(),
|
Authorization: 'Bearer ' + getRefreshToken(), // 使用 getRefreshToken() 方法,而不使用 getAccessToken() 方法的原因:Editor 无法方便的刷新访问令牌
|
||||||
'tenant-id': getTenantId()
|
'tenant-id': getTenantId()
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -136,7 +137,7 @@ const editorConfig = computed((): IEditorConfig => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
['uploadVideo']: {
|
['uploadVideo']: {
|
||||||
server: import.meta.env.VITE_UPLOAD_URL,
|
server: getUploadUrl(),
|
||||||
// 单个文件的最大体积限制,默认为 10M
|
// 单个文件的最大体积限制,默认为 10M
|
||||||
maxFileSize: 10 * 1024 * 1024,
|
maxFileSize: 10 * 1024 * 1024,
|
||||||
// 最多可上传几个文件,默认为 100
|
// 最多可上传几个文件,默认为 100
|
||||||
@@ -147,7 +148,7 @@ const editorConfig = computed((): IEditorConfig => {
|
|||||||
// 自定义增加 http header
|
// 自定义增加 http header
|
||||||
headers: {
|
headers: {
|
||||||
Accept: '*',
|
Accept: '*',
|
||||||
Authorization: 'Bearer ' + getAccessToken(),
|
Authorization: 'Bearer ' + getRefreshToken(), // 使用 getRefreshToken() 方法,而不使用 getAccessToken() 方法的原因:Editor 无法方便的刷新访问令牌
|
||||||
'tenant-id': getTenantId()
|
'tenant-id': getTenantId()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -185,7 +185,6 @@ export const useApiSelect = (option: ApiSelectProps) => {
|
|||||||
</el-select>
|
</el-select>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
debugger
|
|
||||||
return (
|
return (
|
||||||
<el-select
|
<el-select
|
||||||
class="w-1/1"
|
class="w-1/1"
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export const useDictSelectRule = () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'select',
|
type: 'select',
|
||||||
field: 'dictValueType',
|
field: 'valueType',
|
||||||
title: '字典值类型',
|
title: '字典值类型',
|
||||||
value: 'str',
|
value: 'str',
|
||||||
options: [
|
options: [
|
||||||
|
|||||||
@@ -16,3 +16,46 @@ export const localeProps = (t, prefix, rules) => {
|
|||||||
return rule
|
return rule
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析表单组件的 field, title 等字段(递归,如果组件包含子组件)
|
||||||
|
*
|
||||||
|
* @param rule 组件的生成规则 https://www.form-create.com/v3/guide/rule
|
||||||
|
* @param fields 解析后表单组件字段
|
||||||
|
* @param parentTitle 如果是子表单,子表单的标题,默认为空
|
||||||
|
*/
|
||||||
|
export const parseFormFields = (
|
||||||
|
rule: Record<string, any>,
|
||||||
|
fields: Array<Record<string, any>> = [],
|
||||||
|
parentTitle: string = ''
|
||||||
|
) => {
|
||||||
|
const { type, field, $required, title: tempTitle, children } = rule
|
||||||
|
if (field && tempTitle) {
|
||||||
|
let title = tempTitle
|
||||||
|
if (parentTitle) {
|
||||||
|
title = `${parentTitle}.${tempTitle}`
|
||||||
|
}
|
||||||
|
let required = false
|
||||||
|
if ($required) {
|
||||||
|
required = true
|
||||||
|
}
|
||||||
|
fields.push({
|
||||||
|
field,
|
||||||
|
title,
|
||||||
|
type,
|
||||||
|
required
|
||||||
|
})
|
||||||
|
// TODO 子表单 需要处理子表单字段
|
||||||
|
// if (type === 'group' && rule.props?.rule && Array.isArray(rule.props.rule)) {
|
||||||
|
// // 解析子表单的字段
|
||||||
|
// rule.props.rule.forEach((item) => {
|
||||||
|
// parseFields(item, fieldsPermission, title)
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
if (children && Array.isArray(children)) {
|
||||||
|
children.forEach((rule) => {
|
||||||
|
parseFormFields(rule, fields)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,26 +7,41 @@ const props = defineProps({
|
|||||||
src: propTypes.string.def('')
|
src: propTypes.string.def('')
|
||||||
})
|
})
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const height = ref('')
|
|
||||||
const frameRef = ref<HTMLElement | null>(null)
|
const frameRef = ref<HTMLElement | null>(null)
|
||||||
const init = () => {
|
const init = () => {
|
||||||
height.value = document.documentElement.clientHeight - 94.5 + 'px'
|
nextTick(() => {
|
||||||
loading.value = false
|
loading.value = true
|
||||||
|
if (!frameRef.value) return
|
||||||
|
frameRef.value.onload = () => {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
setTimeout(() => {
|
init()
|
||||||
init()
|
|
||||||
}, 300)
|
|
||||||
})
|
})
|
||||||
|
watch(
|
||||||
|
() => props.src,
|
||||||
|
() => {
|
||||||
|
init()
|
||||||
|
}
|
||||||
|
)
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div v-loading="loading" :style="'height:' + height">
|
<div
|
||||||
|
v-loading="loading"
|
||||||
|
class="w-full h-[calc(100vh-var(--top-tool-height)-var(--tags-view-height)-var(--app-content-padding)-var(--app-content-padding)-2px)]"
|
||||||
|
>
|
||||||
<iframe
|
<iframe
|
||||||
ref="frameRef"
|
ref="frameRef"
|
||||||
:src="props.src"
|
:src="props.src"
|
||||||
frameborder="no"
|
frameborder="0"
|
||||||
scrolling="auto"
|
scrolling="auto"
|
||||||
style="width: 100%; height: 100%"
|
height="100%"
|
||||||
|
width="100%"
|
||||||
|
allowfullscreen="true"
|
||||||
|
webkitallowfullscreen="true"
|
||||||
|
mozallowfullscreen="true"
|
||||||
></iframe>
|
></iframe>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -11,6 +11,10 @@ const props = defineProps({
|
|||||||
modelValue: {
|
modelValue: {
|
||||||
require: false,
|
require: false,
|
||||||
type: String
|
type: String
|
||||||
|
},
|
||||||
|
clearable: {
|
||||||
|
require: false,
|
||||||
|
type: Boolean
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const emit = defineEmits<{ (e: 'update:modelValue', v: string) }>()
|
const emit = defineEmits<{ (e: 'update:modelValue', v: string) }>()
|
||||||
@@ -92,6 +96,12 @@ function onCurrentChange(page) {
|
|||||||
currentPage.value = page
|
currentPage.value = page
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clearIcon() {
|
||||||
|
icon.value = ''
|
||||||
|
emit('update:modelValue', '')
|
||||||
|
visible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => {
|
() => {
|
||||||
return props.modelValue
|
return props.modelValue
|
||||||
@@ -115,14 +125,14 @@ watch(
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="selector">
|
<div class="selector">
|
||||||
<ElInput v-model="inputValue" @click="visible = !visible">
|
<ElInput v-model="inputValue" @click="visible = !visible" :clearable="props.clearable" @clear="clearIcon">
|
||||||
<template #append>
|
<template #append>
|
||||||
<ElPopover
|
<ElPopover
|
||||||
:popper-options="{
|
:popper-options="{
|
||||||
placement: 'auto'
|
placement: 'auto'
|
||||||
}"
|
}"
|
||||||
:visible="visible"
|
:visible="visible"
|
||||||
:width="350"
|
:width="355"
|
||||||
popper-class="pure-popper"
|
popper-class="pure-popper"
|
||||||
trigger="click"
|
trigger="click"
|
||||||
>
|
>
|
||||||
@@ -147,7 +157,7 @@ watch(
|
|||||||
>
|
>
|
||||||
<ElDivider border-style="dashed" class="tab-divider" />
|
<ElDivider border-style="dashed" class="tab-divider" />
|
||||||
<ElScrollbar height="220px">
|
<ElScrollbar height="220px">
|
||||||
<ul class="ml-2 flex flex-wrap px-2">
|
<ul class="ml-2 flex flex-wrap">
|
||||||
<li
|
<li
|
||||||
v-for="(item, key) in pageList"
|
v-for="(item, key) in pageList"
|
||||||
:key="key"
|
:key="key"
|
||||||
@@ -171,7 +181,7 @@ watch(
|
|||||||
background
|
background
|
||||||
class="h-10 flex items-center justify-center"
|
class="h-10 flex items-center justify-center"
|
||||||
layout="prev, pager, next"
|
layout="prev, pager, next"
|
||||||
small
|
size="small"
|
||||||
@current-change="onCurrentChange"
|
@current-change="onCurrentChange"
|
||||||
/>
|
/>
|
||||||
</ElPopover>
|
</ElPopover>
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
<div v-else class="custom-hover" @click.stop="showTopSearch = !showTopSearch">
|
<div v-else class="custom-hover" @click.stop="showTopSearch = !showTopSearch">
|
||||||
<Icon icon="ep:search" />
|
<Icon icon="ep:search" />
|
||||||
<el-select
|
<el-select
|
||||||
|
@click.stop
|
||||||
filterable
|
filterable
|
||||||
:reserve-keyword="false"
|
:reserve-keyword="false"
|
||||||
remote
|
remote
|
||||||
@@ -98,6 +99,8 @@ onUnmounted(() => {
|
|||||||
// 监听 ctrl + k
|
// 监听 ctrl + k
|
||||||
function listenKey(event) {
|
function listenKey(event) {
|
||||||
if ((event.ctrlKey || event.metaKey) && event.key === 'k') {
|
if ((event.ctrlKey || event.metaKey) && event.key === 'k') {
|
||||||
|
// 阻止触发浏览器默认事件
|
||||||
|
event.preventDefault()
|
||||||
showSearch.value = !showSearch.value
|
showSearch.value = !showSearch.value
|
||||||
// 这里可以执行相应的操作(例如打开搜索框等)
|
// 这里可以执行相应的操作(例如打开搜索框等)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-row items-center gap-2">
|
<div class="flex flex-row items-center gap-2">
|
||||||
<el-radio-group v-model="shortcutDays" @change="handleShortcutDaysChange">
|
<el-radio-group v-model="shortcutDays" @change="handleShortcutDaysChange">
|
||||||
<el-radio-button :label="1">昨天</el-radio-button>
|
<el-radio-button :value="1">昨天</el-radio-button>
|
||||||
<el-radio-button :label="7">最近7天</el-radio-button>
|
<el-radio-button :value="7">最近7天</el-radio-button>
|
||||||
<el-radio-button :label="30">最近30天</el-radio-button>
|
<el-radio-button :value="30">最近30天</el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="times"
|
v-model="times"
|
||||||
|
|||||||
@@ -1,237 +0,0 @@
|
|||||||
/* stylelint-disable order/properties-order */
|
|
||||||
<template>
|
|
||||||
<div class="add-node-btn-box">
|
|
||||||
<div class="add-node-btn">
|
|
||||||
<el-popover placement="right-start" v-model="visible" width="auto">
|
|
||||||
<div class="add-node-popover-body">
|
|
||||||
<a class="add-node-popover-item approver" @click="addType(1)">
|
|
||||||
<div class="item-wrapper">
|
|
||||||
<span class="iconfont"></span>
|
|
||||||
</div>
|
|
||||||
<p>审批人</p>
|
|
||||||
</a>
|
|
||||||
<a class="add-node-popover-item notifier" @click="addType(2)">
|
|
||||||
<div class="item-wrapper">
|
|
||||||
<span class="iconfont"></span>
|
|
||||||
</div>
|
|
||||||
<p>抄送人</p>
|
|
||||||
</a>
|
|
||||||
<a class="add-node-popover-item condition" @click="addType(4)">
|
|
||||||
<div class="item-wrapper">
|
|
||||||
<span class="iconfont"></span>
|
|
||||||
</div>
|
|
||||||
<p>条件分支</p>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<template #reference>
|
|
||||||
<button class="btn" type="button">
|
|
||||||
<span class="iconfont"></span>
|
|
||||||
</button>
|
|
||||||
</template>
|
|
||||||
</el-popover>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script setup>
|
|
||||||
import { ref } from 'vue'
|
|
||||||
let props = defineProps({
|
|
||||||
childNodeP: {
|
|
||||||
type: Object,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
let emits = defineEmits(['update:childNodeP'])
|
|
||||||
let visible = ref(false)
|
|
||||||
const addType = (type) => {
|
|
||||||
visible.value = false
|
|
||||||
if (type != 4) {
|
|
||||||
var data
|
|
||||||
if (type == 1) {
|
|
||||||
data = {
|
|
||||||
nodeName: '审核人',
|
|
||||||
error: true,
|
|
||||||
type: 1,
|
|
||||||
settype: 1,
|
|
||||||
selectMode: 0,
|
|
||||||
selectRange: 0,
|
|
||||||
directorLevel: 1,
|
|
||||||
examineMode: 1,
|
|
||||||
noHanderAction: 1,
|
|
||||||
examineEndDirectorLevel: 0,
|
|
||||||
childNode: props.childNodeP,
|
|
||||||
nodeUserList: []
|
|
||||||
}
|
|
||||||
} else if (type == 2) {
|
|
||||||
data = {
|
|
||||||
nodeName: '抄送人',
|
|
||||||
type: 2,
|
|
||||||
ccSelfSelectFlag: 1,
|
|
||||||
childNode: props.childNodeP,
|
|
||||||
nodeUserList: []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
emits('update:childNodeP', data)
|
|
||||||
} else {
|
|
||||||
emits('update:childNodeP', {
|
|
||||||
nodeName: '路由',
|
|
||||||
type: 4,
|
|
||||||
childNode: null,
|
|
||||||
conditionNodes: [
|
|
||||||
{
|
|
||||||
nodeName: '条件1',
|
|
||||||
error: true,
|
|
||||||
type: 3,
|
|
||||||
priorityLevel: 1,
|
|
||||||
conditionList: [],
|
|
||||||
nodeUserList: [],
|
|
||||||
childNode: props.childNodeP
|
|
||||||
},
|
|
||||||
{
|
|
||||||
nodeName: '条件2',
|
|
||||||
type: 3,
|
|
||||||
priorityLevel: 2,
|
|
||||||
conditionList: [],
|
|
||||||
nodeUserList: [],
|
|
||||||
childNode: null
|
|
||||||
}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.add-node-btn-box {
|
|
||||||
width: 240px;
|
|
||||||
display: inline-flex;
|
|
||||||
-ms-flex-negative: 0;
|
|
||||||
flex-shrink: 0;
|
|
||||||
-webkit-box-flex: 1;
|
|
||||||
-ms-flex-positive: 1;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&:before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
z-index: -1;
|
|
||||||
margin: auto;
|
|
||||||
width: 2px;
|
|
||||||
height: 100%;
|
|
||||||
background-color: #cacaca;
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-node-btn {
|
|
||||||
user-select: none;
|
|
||||||
width: 240px;
|
|
||||||
padding: 20px 0 32px;
|
|
||||||
display: flex;
|
|
||||||
-webkit-box-pack: center;
|
|
||||||
justify-content: center;
|
|
||||||
flex-shrink: 0;
|
|
||||||
-webkit-box-flex: 1;
|
|
||||||
flex-grow: 1;
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
outline: none;
|
|
||||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
background: #3296fa;
|
|
||||||
border-radius: 50%;
|
|
||||||
position: relative;
|
|
||||||
border: none;
|
|
||||||
line-height: 30px;
|
|
||||||
-webkit-transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
|
||||||
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
|
||||||
|
|
||||||
.iconfont {
|
|
||||||
color: #fff;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
transform: scale(1.3);
|
|
||||||
box-shadow: 0 13px 27px 0 rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
transform: none;
|
|
||||||
background: #1e83e9;
|
|
||||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-node-popover-body {
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
.add-node-popover-item {
|
|
||||||
margin-right: 10px;
|
|
||||||
cursor: pointer;
|
|
||||||
text-align: center;
|
|
||||||
flex: 1;
|
|
||||||
color: #191f25 !important;
|
|
||||||
|
|
||||||
.item-wrapper {
|
|
||||||
user-select: none;
|
|
||||||
display: inline-block;
|
|
||||||
width: 80px;
|
|
||||||
height: 80px;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
background: #fff;
|
|
||||||
border: 1px solid #e2e2e2;
|
|
||||||
border-radius: 50%;
|
|
||||||
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
|
||||||
|
|
||||||
.iconfont {
|
|
||||||
font-size: 35px;
|
|
||||||
line-height: 80px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.approver {
|
|
||||||
.item-wrapper {
|
|
||||||
color: #ff943e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.notifier {
|
|
||||||
.item-wrapper {
|
|
||||||
color: #3296fa;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.condition {
|
|
||||||
.item-wrapper {
|
|
||||||
color: #15bc83;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
.item-wrapper {
|
|
||||||
background: #3296fa;
|
|
||||||
box-shadow: 0 10px 20px 0 rgba(50, 150, 250, 0.4);
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconfont {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
.item-wrapper {
|
|
||||||
box-shadow: none;
|
|
||||||
background: #eaeaea;
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconfont {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,297 +0,0 @@
|
|||||||
<!-- eslint-disable vue/no-mutating-props -->
|
|
||||||
<!--
|
|
||||||
* @Date: 2022-09-21 14:41:53
|
|
||||||
* @LastEditors: StavinLi 495727881@qq.com
|
|
||||||
* @LastEditTime: 2023-05-24 15:20:24
|
|
||||||
* @FilePath: /Workflow-Vue3/src/components/nodeWrap.vue
|
|
||||||
-->
|
|
||||||
<template>
|
|
||||||
<div class="node-wrap" v-if="nodeConfig.type < 3">
|
|
||||||
<div class="node-wrap-box" :class="(nodeConfig.type == 0 ? 'start-node ' : '') +(isTried && nodeConfig.error ? 'active error' : '')">
|
|
||||||
<div class="title" :style="`background: rgb(${bgColors[nodeConfig.type]});`">
|
|
||||||
<span v-if="nodeConfig.type == 0">{{ nodeConfig.nodeName }}</span>
|
|
||||||
<template v-else>
|
|
||||||
<span class="iconfont">{{nodeConfig.type == 1?'':''}}</span>
|
|
||||||
<input
|
|
||||||
v-if="isInput"
|
|
||||||
type="text"
|
|
||||||
class="ant-input editable-title-input"
|
|
||||||
@blur="blurEvent()"
|
|
||||||
@focus="$event.currentTarget.select()"
|
|
||||||
v-focus
|
|
||||||
v-model="nodeConfig.nodeName"
|
|
||||||
:placeholder="defaultText"
|
|
||||||
/>
|
|
||||||
<span v-else class="editable-title" @click="clickEvent()">{{ nodeConfig.nodeName }}</span>
|
|
||||||
<i class="anticon anticon-close close" @click="delNode"></i>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
<div class="content" @click="setPerson">
|
|
||||||
<div class="text">
|
|
||||||
<span class="placeholder" v-if="!showText">请选择{{defaultText}}</span>
|
|
||||||
{{showText}}
|
|
||||||
</div>
|
|
||||||
<i class="anticon anticon-right arrow"></i>
|
|
||||||
</div>
|
|
||||||
<div class="error_tip" v-if="isTried && nodeConfig.error">
|
|
||||||
<i class="anticon anticon-exclamation-circle"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<addNode v-model:childNodeP="nodeConfig.childNode" />
|
|
||||||
</div>
|
|
||||||
<div class="branch-wrap" v-if="nodeConfig.type == 4">
|
|
||||||
<div class="branch-box-wrap">
|
|
||||||
<div class="branch-box">
|
|
||||||
<button class="add-branch" @click="addTerm">添加条件</button>
|
|
||||||
<div class="col-box" v-for="(item, index) in nodeConfig.conditionNodes" :key="index">
|
|
||||||
<div class="condition-node">
|
|
||||||
<div class="condition-node-box">
|
|
||||||
<div class="auto-judge" :class="isTried && item.error ? 'error active' : ''">
|
|
||||||
<div class="sort-left" v-if="index != 0" @click="arrTransfer(index, -1)"><</div>
|
|
||||||
<div class="title-wrapper">
|
|
||||||
<input
|
|
||||||
v-if="isInputList[index]"
|
|
||||||
type="text"
|
|
||||||
class="ant-input editable-title-input"
|
|
||||||
@blur="blurEvent(index)"
|
|
||||||
@focus="$event.currentTarget.select()"
|
|
||||||
v-model="item.nodeName"
|
|
||||||
/>
|
|
||||||
<span v-else class="editable-title" @click="clickEvent(index)">{{ item.nodeName }}</span>
|
|
||||||
<span class="priority-title" @click="setPerson(item.priorityLevel)">优先级{{ item.priorityLevel }}</span>
|
|
||||||
<i class="anticon anticon-close close" @click="delTerm(index)"></i>
|
|
||||||
</div>
|
|
||||||
<div class="sort-right" v-if="index != nodeConfig.conditionNodes.length - 1" @click="arrTransfer(index)">></div>
|
|
||||||
<div class="content" @click="setPerson(item.priorityLevel)">{{ conditionStr(nodeConfig, index) }}</div>
|
|
||||||
<div class="error_tip" v-if="isTried && item.error">
|
|
||||||
<i class="anticon anticon-exclamation-circle"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<addNode v-model:childNodeP="item.childNode" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<nodeWrap v-if="item.childNode" v-model:nodeConfig="item.childNode" />
|
|
||||||
<template v-if="index == 0">
|
|
||||||
<div class="top-left-cover-line"></div>
|
|
||||||
<div class="bottom-left-cover-line"></div>
|
|
||||||
</template>
|
|
||||||
<template v-if="index == nodeConfig.conditionNodes.length - 1">
|
|
||||||
<div class="top-right-cover-line"></div>
|
|
||||||
<div class="bottom-right-cover-line"></div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<addNode v-model:childNodeP="nodeConfig.childNode" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<nodeWrap v-if="nodeConfig.childNode" v-model:nodeConfig="nodeConfig.childNode" />
|
|
||||||
</template>
|
|
||||||
<script setup>
|
|
||||||
import addNode from './addNode.vue'
|
|
||||||
import { onMounted, ref, watch, getCurrentInstance, computed } from 'vue'
|
|
||||||
import {
|
|
||||||
arrToStr,
|
|
||||||
conditionStr,
|
|
||||||
setApproverStr,
|
|
||||||
copyerStr,
|
|
||||||
bgColors,
|
|
||||||
placeholderList
|
|
||||||
} from './util'
|
|
||||||
import { useWorkFlowStoreWithOut } from '@/store/modules/simpleWorkflow'
|
|
||||||
let _uid = getCurrentInstance().uid
|
|
||||||
|
|
||||||
let props = defineProps({
|
|
||||||
nodeConfig: {
|
|
||||||
type: Object,
|
|
||||||
default: () => ({})
|
|
||||||
},
|
|
||||||
flowPermission: {
|
|
||||||
type: Object,
|
|
||||||
// eslint-disable-next-line vue/require-valid-default-prop
|
|
||||||
default: () => []
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
let defaultText = computed(() => {
|
|
||||||
return placeholderList[props.nodeConfig.type]
|
|
||||||
})
|
|
||||||
let showText = computed(() => {
|
|
||||||
if (props.nodeConfig.type == 0) return arrToStr(props.flowPermission) || '所有人'
|
|
||||||
if (props.nodeConfig.type == 1) return setApproverStr(props.nodeConfig)
|
|
||||||
return copyerStr(props.nodeConfig)
|
|
||||||
})
|
|
||||||
|
|
||||||
let isInputList = ref([])
|
|
||||||
let isInput = ref(false)
|
|
||||||
const resetConditionNodesErr = () => {
|
|
||||||
for (var i = 0; i < props.nodeConfig.conditionNodes.length; i++) {
|
|
||||||
// eslint-disable-next-line vue/no-mutating-props
|
|
||||||
props.nodeConfig.conditionNodes[i].error =
|
|
||||||
conditionStr(props.nodeConfig, i) == '请设置条件' &&
|
|
||||||
i != props.nodeConfig.conditionNodes.length - 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onMounted(() => {
|
|
||||||
if (props.nodeConfig.type == 1) {
|
|
||||||
// eslint-disable-next-line vue/no-mutating-props
|
|
||||||
props.nodeConfig.error = !setApproverStr(props.nodeConfig)
|
|
||||||
} else if (props.nodeConfig.type == 2) {
|
|
||||||
// eslint-disable-next-line vue/no-mutating-props
|
|
||||||
props.nodeConfig.error = !copyerStr(props.nodeConfig)
|
|
||||||
} else if (props.nodeConfig.type == 4) {
|
|
||||||
resetConditionNodesErr()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
let emits = defineEmits(['update:flowPermission', 'update:nodeConfig'])
|
|
||||||
let store = useWorkFlowStoreWithOut()
|
|
||||||
let {
|
|
||||||
setPromoter,
|
|
||||||
setApprover,
|
|
||||||
setCopyer,
|
|
||||||
setCondition,
|
|
||||||
setFlowPermission,
|
|
||||||
setApproverConfig,
|
|
||||||
setCopyerConfig,
|
|
||||||
setConditionsConfig
|
|
||||||
} = store
|
|
||||||
let isTried = computed(() => store.isTried)
|
|
||||||
let flowPermission1 = computed(() => store.flowPermission1)
|
|
||||||
let approverConfig1 = computed(() => store.approverConfig1)
|
|
||||||
let copyerConfig1 = computed(() => store.copyerConfig1)
|
|
||||||
let conditionsConfig1 = computed(() => store.conditionsConfig1)
|
|
||||||
watch(flowPermission1, (flow) => {
|
|
||||||
if (flow.flag && flow.id === _uid) {
|
|
||||||
emits('update:flowPermission', flow.value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
watch(approverConfig1, (approver) => {
|
|
||||||
if (approver.flag && approver.id === _uid) {
|
|
||||||
emits('update:nodeConfig', approver.value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
watch(copyerConfig1, (copyer) => {
|
|
||||||
if (copyer.flag && copyer.id === _uid) {
|
|
||||||
emits('update:nodeConfig', copyer.value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
watch(conditionsConfig1, (condition) => {
|
|
||||||
if (condition.flag && condition.id === _uid) {
|
|
||||||
emits('update:nodeConfig', condition.value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const clickEvent = (index) => {
|
|
||||||
if (index || index === 0) {
|
|
||||||
isInputList.value[index] = true
|
|
||||||
} else {
|
|
||||||
isInput.value = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const blurEvent = (index) => {
|
|
||||||
if (index || index === 0) {
|
|
||||||
isInputList.value[index] = false
|
|
||||||
// eslint-disable-next-line vue/no-mutating-props
|
|
||||||
props.nodeConfig.conditionNodes[index].nodeName =
|
|
||||||
props.nodeConfig.conditionNodes[index].nodeName || '条件'
|
|
||||||
} else {
|
|
||||||
isInput.value = false
|
|
||||||
// eslint-disable-next-line vue/no-mutating-props
|
|
||||||
props.nodeConfig.nodeName = props.nodeConfig.nodeName || defaultText
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const delNode = () => {
|
|
||||||
emits('update:nodeConfig', props.nodeConfig.childNode)
|
|
||||||
}
|
|
||||||
const addTerm = () => {
|
|
||||||
let len = props.nodeConfig.conditionNodes.length + 1
|
|
||||||
// eslint-disable-next-line vue/no-mutating-props
|
|
||||||
props.nodeConfig.conditionNodes.push({
|
|
||||||
nodeName: '条件' + len,
|
|
||||||
type: 3,
|
|
||||||
priorityLevel: len,
|
|
||||||
conditionList: [],
|
|
||||||
nodeUserList: [],
|
|
||||||
childNode: null
|
|
||||||
})
|
|
||||||
resetConditionNodesErr()
|
|
||||||
emits('update:nodeConfig', props.nodeConfig)
|
|
||||||
}
|
|
||||||
const delTerm = (index) => {
|
|
||||||
// eslint-disable-next-line vue/no-mutating-props
|
|
||||||
props.nodeConfig.conditionNodes.splice(index, 1)
|
|
||||||
props.nodeConfig.conditionNodes.map((item, index) => {
|
|
||||||
item.priorityLevel = index + 1
|
|
||||||
item.nodeName = `条件${index + 1}`
|
|
||||||
})
|
|
||||||
resetConditionNodesErr()
|
|
||||||
emits('update:nodeConfig', props.nodeConfig)
|
|
||||||
if (props.nodeConfig.conditionNodes.length == 1) {
|
|
||||||
if (props.nodeConfig.childNode) {
|
|
||||||
if (props.nodeConfig.conditionNodes[0].childNode) {
|
|
||||||
reData(props.nodeConfig.conditionNodes[0].childNode, props.nodeConfig.childNode)
|
|
||||||
} else {
|
|
||||||
// eslint-disable-next-line vue/no-mutating-props
|
|
||||||
props.nodeConfig.conditionNodes[0].childNode = props.nodeConfig.childNode
|
|
||||||
}
|
|
||||||
}
|
|
||||||
emits('update:nodeConfig', props.nodeConfig.conditionNodes[0].childNode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const reData = (data, addData) => {
|
|
||||||
if (!data.childNode) {
|
|
||||||
data.childNode = addData
|
|
||||||
} else {
|
|
||||||
reData(data.childNode, addData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const setPerson = (priorityLevel) => {
|
|
||||||
var { type } = props.nodeConfig
|
|
||||||
if (type == 0) {
|
|
||||||
setPromoter(true)
|
|
||||||
setFlowPermission({
|
|
||||||
value: props.flowPermission,
|
|
||||||
flag: false,
|
|
||||||
id: _uid
|
|
||||||
})
|
|
||||||
} else if (type == 1) {
|
|
||||||
setApprover(true)
|
|
||||||
setApproverConfig({
|
|
||||||
value: {
|
|
||||||
...JSON.parse(JSON.stringify(props.nodeConfig)),
|
|
||||||
...{ settype: props.nodeConfig.settype ? props.nodeConfig.settype : 1 }
|
|
||||||
},
|
|
||||||
flag: false,
|
|
||||||
id: _uid
|
|
||||||
})
|
|
||||||
} else if (type == 2) {
|
|
||||||
setCopyer(true)
|
|
||||||
setCopyerConfig({
|
|
||||||
value: JSON.parse(JSON.stringify(props.nodeConfig)),
|
|
||||||
flag: false,
|
|
||||||
id: _uid
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
setCondition(true)
|
|
||||||
setConditionsConfig({
|
|
||||||
value: JSON.parse(JSON.stringify(props.nodeConfig)),
|
|
||||||
priorityLevel,
|
|
||||||
flag: false,
|
|
||||||
id: _uid
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const arrTransfer = (index, type = 1) => {
|
|
||||||
//向左-1,向右1
|
|
||||||
// eslint-disable-next-line vue/no-mutating-props
|
|
||||||
props.nodeConfig.conditionNodes[index] = props.nodeConfig.conditionNodes.splice(
|
|
||||||
index + type,
|
|
||||||
1,
|
|
||||||
props.nodeConfig.conditionNodes[index]
|
|
||||||
)[0]
|
|
||||||
props.nodeConfig.conditionNodes.map((item, index) => {
|
|
||||||
item.priorityLevel = index + 1
|
|
||||||
})
|
|
||||||
resetConditionNodesErr()
|
|
||||||
emits('update:nodeConfig', props.nodeConfig)
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,165 +0,0 @@
|
|||||||
/**
|
|
||||||
* todo
|
|
||||||
*/
|
|
||||||
export const arrToStr = (arr?: [{ name: string }]) => {
|
|
||||||
if (arr) {
|
|
||||||
return arr
|
|
||||||
.map((item) => {
|
|
||||||
return item.name
|
|
||||||
})
|
|
||||||
.toString()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const setApproverStr = (nodeConfig: any) => {
|
|
||||||
if (nodeConfig.settype == 1) {
|
|
||||||
if (nodeConfig.nodeUserList.length == 1) {
|
|
||||||
return nodeConfig.nodeUserList[0].name
|
|
||||||
} else if (nodeConfig.nodeUserList.length > 1) {
|
|
||||||
if (nodeConfig.examineMode == 1) {
|
|
||||||
return arrToStr(nodeConfig.nodeUserList)
|
|
||||||
} else if (nodeConfig.examineMode == 2) {
|
|
||||||
return nodeConfig.nodeUserList.length + '人会签'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (nodeConfig.settype == 2) {
|
|
||||||
const level =
|
|
||||||
nodeConfig.directorLevel == 1 ? '直接主管' : '第' + nodeConfig.directorLevel + '级主管'
|
|
||||||
if (nodeConfig.examineMode == 1) {
|
|
||||||
return level
|
|
||||||
} else if (nodeConfig.examineMode == 2) {
|
|
||||||
return level + '会签'
|
|
||||||
}
|
|
||||||
} else if (nodeConfig.settype == 4) {
|
|
||||||
if (nodeConfig.selectRange == 1) {
|
|
||||||
return '发起人自选'
|
|
||||||
} else {
|
|
||||||
if (nodeConfig.nodeUserList.length > 0) {
|
|
||||||
if (nodeConfig.selectRange == 2) {
|
|
||||||
return '发起人自选'
|
|
||||||
} else {
|
|
||||||
return '发起人从' + nodeConfig.nodeUserList[0].name + '中自选'
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (nodeConfig.settype == 5) {
|
|
||||||
return '发起人自己'
|
|
||||||
} else if (nodeConfig.settype == 7) {
|
|
||||||
return '从直接主管到通讯录中级别最高的第' + nodeConfig.examineEndDirectorLevel + '个层级主管'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const copyerStr = (nodeConfig: any) => {
|
|
||||||
if (nodeConfig.nodeUserList.length != 0) {
|
|
||||||
return arrToStr(nodeConfig.nodeUserList)
|
|
||||||
} else {
|
|
||||||
if (nodeConfig.ccSelfSelectFlag == 1) {
|
|
||||||
return '发起人自选'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export const conditionStr = (nodeConfig, index) => {
|
|
||||||
const { conditionList, nodeUserList } = nodeConfig.conditionNodes[index]
|
|
||||||
if (conditionList.length == 0) {
|
|
||||||
return index == nodeConfig.conditionNodes.length - 1 &&
|
|
||||||
nodeConfig.conditionNodes[0].conditionList.length != 0
|
|
||||||
? '其他条件进入此流程'
|
|
||||||
: '请设置条件'
|
|
||||||
} else {
|
|
||||||
let str = ''
|
|
||||||
for (let i = 0; i < conditionList.length; i++) {
|
|
||||||
const {
|
|
||||||
columnId,
|
|
||||||
columnType,
|
|
||||||
showType,
|
|
||||||
showName,
|
|
||||||
optType,
|
|
||||||
zdy1,
|
|
||||||
opt1,
|
|
||||||
zdy2,
|
|
||||||
opt2,
|
|
||||||
fixedDownBoxValue
|
|
||||||
} = conditionList[i]
|
|
||||||
if (columnId == 0) {
|
|
||||||
if (nodeUserList.length != 0) {
|
|
||||||
str += '发起人属于:'
|
|
||||||
str +=
|
|
||||||
nodeUserList
|
|
||||||
.map((item) => {
|
|
||||||
return item.name
|
|
||||||
})
|
|
||||||
.join('或') + ' 并且 '
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (columnType == 'String' && showType == '3') {
|
|
||||||
if (zdy1) {
|
|
||||||
str += showName + '属于:' + dealStr(zdy1, JSON.parse(fixedDownBoxValue)) + ' 并且 '
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (columnType == 'Double') {
|
|
||||||
if (optType != 6 && zdy1) {
|
|
||||||
const optTypeStr = ['', '<', '>', '≤', '=', '≥'][optType]
|
|
||||||
str += `${showName} ${optTypeStr} ${zdy1} 并且 `
|
|
||||||
} else if (optType == 6 && zdy1 && zdy2) {
|
|
||||||
str += `${zdy1} ${opt1} ${showName} ${opt2} ${zdy2} 并且 `
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return str ? str.substring(0, str.length - 4) : '请设置条件'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const dealStr = (str: string, obj) => {
|
|
||||||
const arr = []
|
|
||||||
const list = str.split(',')
|
|
||||||
for (const elem in obj) {
|
|
||||||
list.map((item) => {
|
|
||||||
if (item == elem) {
|
|
||||||
arr.push(obj[elem].value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return arr.join('或')
|
|
||||||
}
|
|
||||||
|
|
||||||
export const removeEle = (arr, elem, key = 'id') => {
|
|
||||||
let includesIndex
|
|
||||||
arr.map((item, index) => {
|
|
||||||
if (item[key] == elem[key]) {
|
|
||||||
includesIndex = index
|
|
||||||
}
|
|
||||||
})
|
|
||||||
arr.splice(includesIndex, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const bgColors = ['87, 106, 149', '255, 148, 62', '50, 150, 250']
|
|
||||||
export const placeholderList = ['发起人', '审核人', '抄送人']
|
|
||||||
export const setTypes = [
|
|
||||||
{ value: 1, label: '指定成员' },
|
|
||||||
{ value: 2, label: '主管' },
|
|
||||||
{ value: 4, label: '发起人自选' },
|
|
||||||
{ value: 5, label: '发起人自己' },
|
|
||||||
{ value: 7, label: '连续多级主管' }
|
|
||||||
]
|
|
||||||
|
|
||||||
export const selectModes = [
|
|
||||||
{ value: 1, label: '选一个人' },
|
|
||||||
{ value: 2, label: '选多个人' }
|
|
||||||
]
|
|
||||||
|
|
||||||
export const selectRanges = [
|
|
||||||
{ value: 1, label: '全公司' },
|
|
||||||
{ value: 2, label: '指定成员' },
|
|
||||||
{ value: 3, label: '指定角色' }
|
|
||||||
]
|
|
||||||
|
|
||||||
export const optTypes = [
|
|
||||||
{ value: '1', label: '小于' },
|
|
||||||
{ value: '2', label: '大于' },
|
|
||||||
{ value: '3', label: '小于等于' },
|
|
||||||
{ value: '4', label: '等于' },
|
|
||||||
{ value: '5', label: '大于等于' },
|
|
||||||
{ value: '6', label: '介于两个数之间' }
|
|
||||||
]
|
|
||||||