Compare commits
1343 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2563f122fc | ||
|
|
8739811b04 | ||
|
|
5973d43b9d | ||
|
|
d113f5c553 | ||
|
|
5c7b109be6 | ||
|
|
97e611c072 | ||
|
|
68dfae9a62 | ||
|
|
bb8e9a0d3d | ||
|
|
f4fd1c1acd | ||
|
|
21abd26b1f | ||
|
|
a55c8356c8 | ||
|
|
b025ab804e | ||
|
|
700c709afd | ||
|
|
8d0788e09b | ||
|
|
55a431ddd5 | ||
|
|
b72c792ade | ||
|
|
1f872254cc | ||
|
|
99e7f6ed47 | ||
|
|
06e02998aa | ||
|
|
1395f2ad24 | ||
|
|
67e8c86b5b | ||
|
|
9fcd325df9 | ||
|
|
f21ce6e252 | ||
|
|
da95f17885 | ||
|
|
0f9593d5ed | ||
|
|
088a2bb308 | ||
|
|
d29ad9c99b | ||
|
|
d87e0c5f6b | ||
|
|
5e74e356e0 | ||
|
|
cba624f480 | ||
|
|
ba964ff478 | ||
|
|
45338c9d70 | ||
|
|
6b6dc2c4f3 | ||
|
|
8fd353a766 | ||
|
|
3cb60139d5 | ||
|
|
7d9bf776db | ||
|
|
0c814ec956 | ||
|
|
322e357398 | ||
|
|
cc4a94da40 | ||
|
|
36648f065b | ||
|
|
9893494cf1 | ||
|
|
906cda0385 | ||
|
|
92dd179525 | ||
|
|
fefb748864 | ||
|
|
0b644a1722 | ||
|
|
2a2c3f8174 | ||
|
|
88fc1b0b2a | ||
|
|
b45910a35f | ||
|
|
758f09a291 | ||
|
|
fce063642d | ||
|
|
c832350dd3 | ||
|
|
5169d4ac43 | ||
|
|
d80ead4d94 | ||
|
|
62700162d5 | ||
|
|
a568131b7c | ||
|
|
27ca53068b | ||
|
|
1d946a9616 | ||
|
|
f31669cba6 | ||
|
|
005006adf7 | ||
|
|
2f097ace49 | ||
|
|
654839b247 | ||
|
|
8ed67847dd | ||
|
|
47974dddab | ||
|
|
76cc10c6af | ||
|
|
ae08a568bd | ||
|
|
2bb3a71460 | ||
|
|
ce03b13718 | ||
|
|
0ad79157d3 | ||
|
|
bdae07e585 | ||
|
|
7fa6c2d84c | ||
|
|
59bd1b8c78 | ||
|
|
18eb79054f | ||
|
|
b5047a7a7a | ||
|
|
45b83d0fe4 | ||
|
|
a804120fa2 | ||
|
|
ebbf42cb76 | ||
|
|
1e7e78a841 | ||
|
|
350e79895d | ||
|
|
2bee689198 | ||
|
|
de333c2d34 | ||
|
|
0c7ecbe039 | ||
|
|
7a1ae5d5da | ||
|
|
2bbec5b9e5 | ||
|
|
b4d67859da | ||
|
|
15c229fa62 | ||
|
|
3278726a25 | ||
|
|
5df1ab6993 | ||
|
|
870bacdd8c | ||
|
|
bbe336d902 | ||
|
|
1bd50cee45 | ||
|
|
b639bc36eb | ||
|
|
89711af0e6 | ||
|
|
3ec3f11d5b | ||
|
|
5fcc26a866 | ||
|
|
8484936e3d | ||
|
|
1b275cf592 | ||
|
|
4c232284f8 | ||
|
|
326ccea1b4 | ||
|
|
8410179885 | ||
|
|
4777eb2dd6 | ||
|
|
867b03ebfc | ||
|
|
a6063874c7 | ||
|
|
037fd0caa0 | ||
|
|
ea897b154b | ||
|
|
54c72239d4 | ||
|
|
1bad9a14db | ||
|
|
50ebc7d6df | ||
|
|
ff38cf52b4 | ||
|
|
2fdab71d14 | ||
|
|
b51148f520 | ||
|
|
87db9dbb12 | ||
|
|
fb979ea514 | ||
|
|
8d18f05085 | ||
|
|
dfb790e713 | ||
|
|
62d55e2b92 | ||
|
|
f4a50cd854 | ||
|
|
47a2c40ffd | ||
|
|
fddb82e680 | ||
|
|
2d80a795a7 | ||
|
|
ffdae4a332 | ||
|
|
3ca9aad9be | ||
|
|
085674dfa7 | ||
|
|
9540a1b98b | ||
|
|
b9d48fab05 | ||
|
|
6552767823 | ||
|
|
f42f5903d3 | ||
|
|
0c94b67ad9 | ||
|
|
3b665f6d8c | ||
|
|
420e8a84e5 | ||
|
|
05b14ada18 | ||
|
|
aed9d86ada | ||
|
|
6933fb79ec | ||
|
|
4be36d61c7 | ||
|
|
d4cd6e0936 | ||
|
|
c0b00999c5 | ||
|
|
1accdf5826 | ||
|
|
1ae7ab3036 | ||
|
|
36878e6f7f | ||
|
|
09b735e82a | ||
|
|
24f829033f | ||
|
|
a72ff640cc | ||
|
|
68a791a439 | ||
|
|
c0ca9672a1 | ||
|
|
6ee49ce9ac | ||
|
|
c83d715234 | ||
|
|
4bcaf14bad | ||
|
|
e91d783e22 | ||
|
|
4bb3d33f89 | ||
|
|
12291ad4d5 | ||
|
|
829d3e65e7 | ||
|
|
3be9aa5c14 | ||
|
|
6c9a3820e8 | ||
|
|
d172a1c9b8 | ||
|
|
59c98d1289 | ||
|
|
b7235f5644 | ||
|
|
9dc4829f1f | ||
|
|
843134c82a | ||
|
|
7e87214b6d | ||
|
|
192a9ca53f | ||
|
|
1df821aa0c | ||
|
|
3e3644f4a4 | ||
|
|
b1f62d599b | ||
|
|
4e0ee8e899 | ||
|
|
7804d4eba6 | ||
|
|
1fa3a91979 | ||
|
|
29d5ba98ff | ||
|
|
c25c16adf3 | ||
|
|
de9bf1902a | ||
|
|
f2ec4530ed | ||
|
|
7bbcab7679 | ||
|
|
f646022926 | ||
|
|
f6037dc18b | ||
|
|
29acc7f0ee | ||
|
|
5ef5adf9be | ||
|
|
9647e7614b | ||
|
|
fb7c0c9ca2 | ||
|
|
0002a39fc4 | ||
|
|
e67ea56651 | ||
|
|
4cd96980ba | ||
|
|
d648855533 | ||
|
|
9bed373ec1 | ||
|
|
c355194aba | ||
|
|
15fa1a5e52 | ||
|
|
ecf11ae2d2 | ||
|
|
fb2a9e7a9f | ||
|
|
106e059d1a | ||
|
|
f6ddcf4f99 | ||
|
|
a4659ed1a2 | ||
|
|
c90559981e | ||
|
|
b299507df9 | ||
|
|
cf92d9d939 | ||
|
|
6b61b86585 | ||
|
|
ae896ff42c | ||
|
|
709d114986 | ||
|
|
cc86430ea4 | ||
|
|
295aaf1a01 | ||
|
|
548335b658 | ||
|
|
df35a26f9e | ||
|
|
c277cf1121 | ||
|
|
297bdd95dd | ||
|
|
e13ca6281d | ||
|
|
235362d5b0 | ||
|
|
fc5fb3832d | ||
|
|
bd9a5f75b0 | ||
|
|
99de0d4722 | ||
|
|
726d563e1a | ||
|
|
7ce1ea8fa4 | ||
|
|
2e5be29a43 | ||
|
|
ac77acd888 | ||
|
|
f4b17254ec | ||
|
|
28a857249a | ||
|
|
22f7b1a343 | ||
|
|
ec948b5496 | ||
|
|
1b2e980fb6 | ||
|
|
8a60e23214 | ||
|
|
ff55a0fade | ||
|
|
c1447b4376 | ||
|
|
734825ba9b | ||
|
|
0da6ef99af | ||
|
|
832fda813b | ||
|
|
615ee91511 | ||
|
|
e7350899bf | ||
|
|
ad0522335e | ||
|
|
38da0d9f3a | ||
|
|
020b413e20 | ||
|
|
1750f04d0b | ||
|
|
14d53fa48d | ||
|
|
aa4bc81da4 | ||
|
|
fe4e0ce75c | ||
|
|
052c6e153d | ||
|
|
60479b44b1 | ||
|
|
8e0d9148b1 | ||
|
|
fc471a17a0 | ||
|
|
b6a2dbc23a | ||
|
|
b854f40cc7 | ||
|
|
a2cd9aebe8 | ||
|
|
2e8d257140 | ||
|
|
379fed15b3 | ||
|
|
afa3290f11 | ||
|
|
5593ebe574 | ||
|
|
b18999900d | ||
|
|
03ccdf2d43 | ||
|
|
40dc2b5d2f | ||
|
|
50960ed899 | ||
|
|
ede1de664a | ||
|
|
6884a89fe5 | ||
|
|
676410a108 | ||
|
|
b37e12b7a7 | ||
|
|
8a0f5ff120 | ||
|
|
c5fecda212 | ||
|
|
e5d98d022e | ||
|
|
799184fd21 | ||
|
|
756cb28daa | ||
|
|
5f6eb6a26d | ||
|
|
4efbec5741 | ||
|
|
86dbc0d86e | ||
|
|
c32d011851 | ||
|
|
311ca35afc | ||
|
|
1a3fae6501 | ||
|
|
3432530de7 | ||
|
|
af85493863 | ||
|
|
ae85f0d612 | ||
|
|
16c4a78e29 | ||
|
|
8fb87aa64d | ||
|
|
c5d675b6d2 | ||
|
|
f4d06b2d7b | ||
|
|
bb610a7cd8 | ||
|
|
bb864e72b3 | ||
|
|
c6c4797d87 | ||
|
|
25fed42395 | ||
|
|
66c4676493 | ||
|
|
f8747b5d5d | ||
|
|
0eb58d4b8a | ||
|
|
7b30ea343f | ||
|
|
7db8484a7c | ||
|
|
78b058009b | ||
|
|
05abad3905 | ||
|
|
ad178b1806 | ||
|
|
075c20ae41 | ||
|
|
56420bd4d0 | ||
|
|
a18fc729c0 | ||
|
|
099941a54e | ||
|
|
3867d51d92 | ||
|
|
f1be18b7e3 | ||
|
|
ef46380f9e | ||
|
|
d711273cf0 | ||
|
|
5e7cf2d679 | ||
|
|
11319ba21f | ||
|
|
9c51523352 | ||
|
|
b4a706820e | ||
|
|
376a3223dc | ||
|
|
a85ec69549 | ||
|
|
ebf4d6d3eb | ||
|
|
2ccd8265b9 | ||
|
|
fb1671d062 | ||
|
|
95e37df2ec | ||
|
|
cfde72f1ab | ||
|
|
efc778acbc | ||
|
|
37384ebadd | ||
|
|
9a7aee7e97 | ||
|
|
1a56534d28 | ||
|
|
79e7e5f087 | ||
|
|
aea03cf975 | ||
|
|
8ef6f944dc | ||
|
|
e18d243961 | ||
|
|
765b633cea | ||
|
|
9c402a3878 | ||
|
|
86426b087a | ||
|
|
c5aaa2f3e2 | ||
|
|
cc59bb6094 | ||
|
|
5662da1210 | ||
|
|
863725d3ba | ||
|
|
b1acfbdd4b | ||
|
|
001f9c3f30 | ||
|
|
8d4df4b66e | ||
|
|
604447508a | ||
|
|
6f30949620 | ||
|
|
10e8e82fe4 | ||
|
|
5227e0ae13 | ||
|
|
cf193f4eab | ||
|
|
708ae53fe2 | ||
|
|
aed57177dd | ||
|
|
e916a03ff8 | ||
|
|
859d60c0bf | ||
|
|
1eeaf38638 | ||
|
|
ca09bbe3fc | ||
|
|
57b42bdc66 | ||
|
|
88c31d157e | ||
|
|
c738274423 | ||
|
|
1c62ee6efe | ||
|
|
4fcb24607d | ||
|
|
52ce1e795c | ||
|
|
39c4593d9e | ||
|
|
6ae288cf01 | ||
|
|
bab54570fe | ||
|
|
2551c76d97 | ||
|
|
e3a5583802 | ||
|
|
b03adc1b1f | ||
|
|
6e9d725f6d | ||
|
|
92559ca9e7 | ||
|
|
3bfa99f578 | ||
|
|
30b85163b7 | ||
|
|
ef528a2952 | ||
|
|
907e9d35a7 | ||
|
|
d003e5da70 | ||
|
|
19530988ce | ||
|
|
4e9baebcf5 | ||
|
|
3a1cbfe8bb | ||
|
|
c16b37c8bc | ||
|
|
0c6703f04d | ||
|
|
3471caf00a | ||
|
|
ad28e70a07 | ||
|
|
47315963f1 | ||
|
|
fb8fa9e787 | ||
|
|
223fa7ca05 | ||
|
|
b568c242e3 | ||
|
|
e4283e1c53 | ||
|
|
25f9cc1095 | ||
|
|
85729e3761 | ||
|
|
fa0a0cb1d8 | ||
|
|
e7ee256b80 | ||
|
|
36190438f0 | ||
|
|
ce629a1fb6 | ||
|
|
f989d1ef4e | ||
|
|
99455dee58 | ||
|
|
c7bd7223bc | ||
|
|
8166f90f0f | ||
|
|
8b2587daa7 | ||
|
|
82e047c797 | ||
|
|
3cefb40ccb | ||
|
|
8bba4a1e48 | ||
|
|
a12f317aa8 | ||
|
|
1d133af38d | ||
|
|
9cab354cbb | ||
|
|
c0385414ca | ||
|
|
4f7846dc4e | ||
|
|
01beac9265 | ||
|
|
77ad146e24 | ||
|
|
6c1c47de1d | ||
|
|
b3cac070df | ||
|
|
daf1b20f67 | ||
|
|
2316fb8d11 | ||
|
|
43159335f8 | ||
|
|
0e56c2038d | ||
|
|
0840740e2c | ||
|
|
e2404f0f3b | ||
|
|
5e9a258cc8 | ||
|
|
8cfc420085 | ||
|
|
83593bd015 | ||
|
|
c1cdf97edb | ||
|
|
eca8370c70 | ||
|
|
54502b331f | ||
|
|
0ec5955ea0 | ||
|
|
b70a9bf0c0 | ||
|
|
fb20cb32da | ||
|
|
a314373e64 | ||
|
|
4976b87c4e | ||
|
|
3b9e54375a | ||
|
|
8b15cfb0b1 | ||
|
|
ff02cce191 | ||
|
|
83beb81a3b | ||
|
|
de89249d3e | ||
|
|
77732e766a | ||
|
|
21c91cfcf1 | ||
|
|
ebaf5e34d8 | ||
|
|
94e389ab23 | ||
|
|
7ba94c7fe1 | ||
|
|
c47394a162 | ||
|
|
bf8afdc0f4 | ||
|
|
3df17ed33f | ||
|
|
dc6d3b3743 | ||
|
|
6e626f6e11 | ||
|
|
d20da31f2c | ||
|
|
2182cd012a | ||
|
|
71c629cb06 | ||
|
|
185d675abf | ||
|
|
6221b59b21 | ||
|
|
07f320ca2f | ||
|
|
9908b83b18 | ||
|
|
9ce1c966eb | ||
|
|
c81eff58d3 | ||
|
|
92b61a203f | ||
|
|
b1f9c0adf2 | ||
|
|
c5d75a3570 | ||
|
|
42c64920b1 | ||
|
|
77e7d095a7 | ||
|
|
560199944d | ||
|
|
21ae217369 | ||
|
|
4565297fe6 | ||
|
|
118e68b8ac | ||
|
|
a03f908e96 | ||
|
|
0b6dcf17d1 | ||
|
|
5136f8b3dd | ||
|
|
286295393d | ||
|
|
195ea35798 | ||
|
|
053279f60d | ||
|
|
9bfb7e8b69 | ||
|
|
c82f8a6de3 | ||
|
|
749147cfad | ||
|
|
4429227665 | ||
|
|
3ec0e9d997 | ||
|
|
904046f02c | ||
|
|
5a29215b80 | ||
|
|
508a00d103 | ||
|
|
5385d10bc8 | ||
|
|
08b4a04791 | ||
|
|
218cee2aef | ||
|
|
63b22f4c86 | ||
|
|
709a3f71fd | ||
|
|
f7589e42ab | ||
|
|
0e7008862e | ||
|
|
7e88ee930b | ||
|
|
e935f2a3e3 | ||
|
|
9d442a2aa1 | ||
|
|
eed6ba43d9 | ||
|
|
b2c286f0f5 | ||
|
|
2aae5a4bff | ||
|
|
c88c1865e7 | ||
|
|
7152e339e5 | ||
|
|
46143beb83 | ||
|
|
2c66eaae2b | ||
|
|
b8c74ac84c | ||
|
|
cb210916eb | ||
|
|
f968f3d20d | ||
|
|
4ef2496221 | ||
|
|
b2b56178a2 | ||
|
|
525838468c | ||
|
|
ef92bcfe3a | ||
|
|
ed72c2ffc2 | ||
|
|
9f94c2013a | ||
|
|
8666254ffe | ||
|
|
e13fc57ae7 | ||
|
|
c6cf90fb4e | ||
|
|
fff086a3a1 | ||
|
|
b7a2a5af6d | ||
|
|
1786dfeee2 | ||
|
|
2c32088f4c | ||
|
|
71f61461ce | ||
|
|
54be87efea | ||
|
|
76fc55fdd0 | ||
|
|
5d5a845523 | ||
|
|
4f915a32b6 | ||
|
|
78df54d153 | ||
|
|
24554a0768 | ||
|
|
ffe03fd785 | ||
|
|
4b635735ae | ||
|
|
79c1e2c5bb | ||
|
|
cf9f9fb7dd | ||
|
|
2bcefc1306 | ||
|
|
39547b542c | ||
|
|
8c9246faa4 | ||
|
|
74b180f6d3 | ||
|
|
ac26690e78 | ||
|
|
d642e00844 | ||
|
|
7bbb657379 | ||
|
|
00a56473f1 | ||
|
|
e138275c0a | ||
|
|
9e7a1b3ee3 | ||
|
|
c5e06ad1f2 | ||
|
|
128ad892d1 | ||
|
|
552b4c605d | ||
|
|
8b33dbe8d7 | ||
|
|
8a43335b75 | ||
|
|
a4d17102f1 | ||
|
|
d02d0adb39 | ||
|
|
c86cecf4f0 | ||
|
|
7bc5d67efc | ||
|
|
d058d7d6e8 | ||
|
|
914fa0a324 | ||
|
|
4389911436 | ||
|
|
841d48e2a7 | ||
|
|
b6c16e7048 | ||
|
|
9fce33ca18 | ||
|
|
6a653198c3 | ||
|
|
2c8e34008f | ||
|
|
6feb650f06 | ||
|
|
873764b59e | ||
|
|
36ef331b94 | ||
|
|
308619fbdd | ||
|
|
6dec218e81 | ||
|
|
f9717eb7ac | ||
|
|
cb10bd97a0 | ||
|
|
430894eb69 | ||
|
|
34cb3b4a29 | ||
|
|
b89f81e5d6 | ||
|
|
604bdcaf77 | ||
|
|
a46cd8ee97 | ||
|
|
7e14569479 | ||
|
|
3c296ea011 | ||
|
|
8529641145 | ||
|
|
b133502062 | ||
|
|
5470253626 | ||
|
|
6b697f9ecd | ||
|
|
44558d9072 | ||
|
|
8dbd5429f0 | ||
|
|
3c83179579 | ||
|
|
bf70527c58 | ||
|
|
26a539662e | ||
|
|
48f2bd82a1 | ||
|
|
73c2654cc5 | ||
|
|
49dfd644a2 | ||
|
|
09ce16dc95 | ||
|
|
5b58d1de5e | ||
|
|
775b339c17 | ||
|
|
1ef8dd26cf | ||
|
|
b36be16f38 | ||
|
|
1c765f37cf | ||
|
|
724922dddc | ||
|
|
9dece4dd2c | ||
|
|
4a628acd37 | ||
|
|
5c3501f08d | ||
|
|
ad09b38ed5 | ||
|
|
c60a54b8f9 | ||
|
|
056386e8e9 | ||
|
|
8ad79b8728 | ||
|
|
a78374910f | ||
|
|
4318e8d0da | ||
|
|
4ace1a9cca | ||
|
|
7ded1c564e | ||
|
|
28d68bdca6 | ||
|
|
9181befdf9 | ||
|
|
87b3cbe344 | ||
|
|
8b0ca5ba7e | ||
|
|
b30be8efb2 | ||
|
|
2213f0d0ce | ||
|
|
0883a967b6 | ||
|
|
c8e8685586 | ||
|
|
73ce45aff9 | ||
|
|
e954cf4d92 | ||
|
|
d1a974f6b0 | ||
|
|
39f7f1ed38 | ||
|
|
5380cf9ba9 | ||
|
|
6e9ca81b58 | ||
|
|
531ed5b2dd | ||
|
|
ebc79da0fc | ||
|
|
1cbafbce25 | ||
|
|
816d842a57 | ||
|
|
e5c25895a0 | ||
|
|
1abc7a5a52 | ||
|
|
170244cc9c | ||
|
|
3498de4529 | ||
|
|
16b0d457fc | ||
|
|
87b6ddbaa6 | ||
|
|
2f6e50cc1c | ||
|
|
aa196918bf | ||
|
|
5958353383 | ||
|
|
f37f633f51 | ||
|
|
8c286610ba | ||
|
|
d2540733dc | ||
|
|
ab56bdfcad | ||
|
|
803eae5c7d | ||
|
|
6b3892e17d | ||
|
|
500afcc33f | ||
|
|
64c61d5365 | ||
|
|
bf58711c88 | ||
|
|
48b3e3246c | ||
|
|
8f629db5ab | ||
|
|
1ca94d289a | ||
|
|
3159c325e3 | ||
|
|
b51040c73e | ||
|
|
f4ddeaa5c5 | ||
|
|
8599708af3 | ||
|
|
72fb11d3d3 | ||
|
|
7d0b3c6908 | ||
|
|
f7a9bff2ba | ||
|
|
4fd419fcfe | ||
|
|
f72c28d770 | ||
|
|
7c775f7692 | ||
|
|
ac0404adaa | ||
|
|
40ccbf3edb | ||
|
|
2aa7b67b7a | ||
|
|
4700bc995a | ||
|
|
7052fa7420 | ||
|
|
08c62e5c9c | ||
|
|
32b29f45e7 | ||
|
|
49d023cef0 | ||
|
|
674c2352ef | ||
|
|
96156508b5 | ||
|
|
802f13e6e5 | ||
|
|
5d24dda4c1 | ||
|
|
2207d11c7c | ||
|
|
495096c779 | ||
|
|
9375ba9e31 | ||
|
|
42a24d854b | ||
|
|
cc31b6232f | ||
|
|
092873592d | ||
|
|
70757e8adf | ||
|
|
b1fb019b01 | ||
|
|
ed4f78bf6a | ||
|
|
826ba41866 | ||
|
|
4886b53847 | ||
|
|
56d6401cda | ||
|
|
36794613cd | ||
|
|
cfd2529caf | ||
|
|
f0628c5995 | ||
|
|
4780ae5b18 | ||
|
|
5a93abb946 | ||
|
|
d371fd0146 | ||
|
|
c850a27cca | ||
|
|
a97ed0c3f6 | ||
|
|
3c65de9912 | ||
|
|
c6e1cc060a | ||
|
|
9df377677b | ||
|
|
69caf86c7e | ||
|
|
c86d863f1d | ||
|
|
c130597e95 | ||
|
|
5d16a7a80e | ||
|
|
bad9f9109c | ||
|
|
7e33598b8e | ||
|
|
83f145767e | ||
|
|
8ea3843d61 | ||
|
|
29cc6002cd | ||
|
|
db33b34f18 | ||
|
|
73acb0bc09 | ||
|
|
94ab061cc8 | ||
|
|
4f243afb63 | ||
|
|
efd3ed26df | ||
|
|
e7d1664673 | ||
|
|
7b7310ed75 | ||
|
|
c8649caf1a | ||
|
|
aaa2deef85 | ||
|
|
b0ed6635e5 | ||
|
|
0dc3124bba | ||
|
|
1135c1fbc3 | ||
|
|
779f6e4fa1 | ||
|
|
f4bf4dc060 | ||
|
|
84d3dd247d | ||
|
|
61c44af5a0 | ||
|
|
e8b7a85140 | ||
|
|
aa4dbc1bbd | ||
|
|
3881370b6e | ||
|
|
0fa93d545e | ||
|
|
a92c213b64 | ||
|
|
fcc9a9f8c5 | ||
|
|
0ffd0f0c29 | ||
|
|
3afad96b8f | ||
|
|
d9e1a4a491 | ||
|
|
2e4246e63b | ||
|
|
235d582ae2 | ||
|
|
c34e2ad6ad | ||
|
|
78b8a002e9 | ||
|
|
29091739d4 | ||
|
|
aa05ee1165 | ||
|
|
2446c28b20 | ||
|
|
8378182730 | ||
|
|
d84250ab88 | ||
|
|
5218388eff | ||
|
|
984bc4b635 | ||
|
|
acc9a0b88a | ||
|
|
a31c7a5ad0 | ||
|
|
f0882793e4 | ||
|
|
053e5ce062 | ||
|
|
34ef7e555a | ||
|
|
34165127f0 | ||
|
|
4d347df505 | ||
|
|
830154371a | ||
|
|
69c2c4c5c2 | ||
|
|
a5d067943d | ||
|
|
1e190e3a88 | ||
|
|
b042bd6052 | ||
|
|
3861881996 | ||
|
|
405bb4a216 | ||
|
|
c382f015f4 | ||
|
|
c083a58f30 | ||
|
|
a78d637468 | ||
|
|
0cb32caa3e | ||
|
|
8095aa0d8e | ||
|
|
60117f51b3 | ||
|
|
b51a5e6deb | ||
|
|
b9869053c2 | ||
|
|
f1753babbe | ||
|
|
05f8defe56 | ||
|
|
af115c45cc | ||
|
|
532fc8b2dd | ||
|
|
fa8aa633bf | ||
|
|
dca8ee512f | ||
|
|
50c3fd6af8 | ||
|
|
bb93be2fb1 | ||
|
|
17a4131bf1 | ||
|
|
eb9c999a16 | ||
|
|
a70c741990 | ||
|
|
6007dc57d5 | ||
|
|
7dfdb4f685 | ||
|
|
0cc27f4e60 | ||
|
|
163f9f26c2 | ||
|
|
68ba97e590 | ||
|
|
d36c2bdc3d | ||
|
|
72c64f017f | ||
|
|
0f28a7f16c | ||
|
|
581a1f75e1 | ||
|
|
a727001daf | ||
|
|
2f9754b2a5 | ||
|
|
a11452a430 | ||
|
|
7d90846960 | ||
|
|
23e456d265 | ||
|
|
cddd94b9e5 | ||
|
|
685ec5f679 | ||
|
|
0933f1942e | ||
|
|
2792df38c0 | ||
|
|
62d8d121c6 | ||
|
|
b99db4c673 | ||
|
|
3639804d1b | ||
|
|
f6ff0b8a12 | ||
|
|
a345586b25 | ||
|
|
3d0ba486df | ||
|
|
4651d74b7b | ||
|
|
55aa57d812 | ||
|
|
36c4584970 | ||
|
|
96b6565272 | ||
|
|
8b22b73f3d | ||
|
|
ba91d7c26d | ||
|
|
fd847944b7 | ||
|
|
4ea142ea08 | ||
|
|
2aceffc112 | ||
|
|
ed59b389a5 | ||
|
|
2b433cf1e8 | ||
|
|
41ea3b7a88 | ||
|
|
f5a452c124 | ||
|
|
9ce3a5e916 | ||
|
|
248c4031c0 | ||
|
|
8715066f7c | ||
|
|
5dc5cce96b | ||
|
|
f58500c4e3 | ||
|
|
2041eca723 | ||
|
|
db6e47fa04 | ||
|
|
116c168ed7 | ||
|
|
8ff6c0414a | ||
|
|
aaf1c172de | ||
|
|
f7c310b126 | ||
|
|
ab0db38eb2 | ||
|
|
283f4d6afa | ||
|
|
db51df89f7 | ||
|
|
b77b4c0ef8 | ||
|
|
dd67687d3a | ||
|
|
61f5dde015 | ||
|
|
0355dcddde | ||
|
|
1d6a61d5d9 | ||
|
|
bf393181b8 | ||
|
|
79ff1cecb4 | ||
|
|
0d21c87816 | ||
|
|
c281b0a867 | ||
|
|
bd322709f3 | ||
|
|
bc4f9527d0 | ||
|
|
0b5e7c40b0 | ||
|
|
8d5f4db494 | ||
|
|
4ecb41e9a2 | ||
|
|
dba167738b | ||
|
|
c1853fd4e0 | ||
|
|
75ef173c64 | ||
|
|
752c1086a0 | ||
|
|
6c5994202b | ||
|
|
00e229e7f4 | ||
|
|
4674cfae37 | ||
|
|
eeadfc1db9 | ||
|
|
34788d800e | ||
|
|
954cd1cda9 | ||
|
|
f3ef286aa7 | ||
|
|
7874931b1f | ||
|
|
c3b3e7bb61 | ||
|
|
12839eee8d | ||
|
|
601a2e8d33 | ||
|
|
a3fe3a3743 | ||
|
|
86fa39d7af | ||
|
|
a785718715 | ||
|
|
d4eb17e573 | ||
|
|
994b700892 | ||
|
|
317bf1cd47 | ||
|
|
8327639c23 | ||
|
|
c1830df1a2 | ||
|
|
590ceaf641 | ||
|
|
c7b739e546 | ||
|
|
42db858d61 | ||
|
|
85349a197f | ||
|
|
8ef3510c4b | ||
|
|
8d6fa2f19f | ||
|
|
af975b9f46 | ||
|
|
3de928ee14 | ||
|
|
0a5563e5e2 | ||
|
|
f4b7068cd6 | ||
|
|
2cb6f04465 | ||
|
|
037a307ed1 | ||
|
|
cd81a6afb1 | ||
|
|
f930d73a6a | ||
|
|
23bae9efd5 | ||
|
|
2880c21a26 | ||
|
|
274ac3f155 | ||
|
|
c85d488de4 | ||
|
|
92d58ea7e5 | ||
|
|
9a3d202524 | ||
|
|
ba71eaeaaf | ||
|
|
273fdf2e84 | ||
|
|
59cfa0efb0 | ||
|
|
14d720beed | ||
|
|
2dcfacd431 | ||
|
|
71690cfd8f | ||
|
|
d2c2da25b4 | ||
|
|
c3c29af8c7 | ||
|
|
e5f9f81ef7 | ||
|
|
0c0c903529 | ||
|
|
115fa87ff2 | ||
|
|
bb40364aed | ||
|
|
0e921de6c3 | ||
|
|
58eeed4bbd | ||
|
|
21289f5a92 | ||
|
|
0aec486291 | ||
|
|
5c34245ba4 | ||
|
|
3d0a202cbe | ||
|
|
66143deb0d | ||
|
|
2111020f62 | ||
|
|
160658cfb6 | ||
|
|
8a7f9b2487 | ||
|
|
85061ed2f8 | ||
|
|
3405cf68bb | ||
|
|
ebacb58049 | ||
|
|
8873f575db | ||
|
|
994ef217ac | ||
|
|
1bda042bc9 | ||
|
|
e97dbe1c90 | ||
|
|
f19071542a | ||
|
|
50836e0aa3 | ||
|
|
1b4c05f70b | ||
|
|
32dffe96ed | ||
|
|
e2df32d906 | ||
|
|
9eab3b261e | ||
|
|
1e40e2d557 | ||
|
|
256ada983b | ||
|
|
cd0c90ace8 | ||
|
|
913b96af5a | ||
|
|
a3f5212bbc | ||
|
|
9d7a06e867 | ||
|
|
48f3c38fbd | ||
|
|
706bab7eff | ||
|
|
b6fa3175c6 | ||
|
|
3cd57a6915 | ||
|
|
d433ff02cb | ||
|
|
68d2c25ff5 | ||
|
|
9ccf51dd5c | ||
|
|
727d240715 | ||
|
|
1f4448ba08 | ||
|
|
6064c168bf | ||
|
|
479470832d | ||
|
|
71fa00c267 | ||
|
|
c1331e8ccf | ||
|
|
8a2ec77c84 | ||
|
|
b197cda548 | ||
|
|
c83eddd62e | ||
|
|
46168a037d | ||
|
|
cbb2365ae8 | ||
|
|
ec3093246a | ||
|
|
670ba74044 | ||
|
|
84e0803558 | ||
|
|
1691f8244f | ||
|
|
24f4a36082 | ||
|
|
7cf7123dd2 | ||
|
|
37064141c2 | ||
|
|
5bd66b9ec6 | ||
|
|
9e34b44165 | ||
|
|
8d9a64d84b | ||
|
|
92aafe3031 | ||
|
|
81f4f4a742 | ||
|
|
9b14cd633e | ||
|
|
118aaaf6fb | ||
|
|
0635dd38a2 | ||
|
|
1d648bbad7 | ||
|
|
5dfcc2482c | ||
|
|
7ff51b5e53 | ||
|
|
c4168c9a2b | ||
|
|
7312b3ec3f | ||
|
|
c09e25974f | ||
|
|
744567e8de | ||
|
|
4156d51d78 | ||
|
|
0faae31b2e | ||
|
|
79a719e7ff | ||
|
|
0d09920314 | ||
|
|
d641123987 | ||
|
|
ce871a804c | ||
|
|
36fd58a446 | ||
|
|
9e0a681e01 | ||
|
|
df408e640a | ||
|
|
f365231ee7 | ||
|
|
2e8d124560 | ||
|
|
1e8279c849 | ||
|
|
48668fd2d4 | ||
|
|
ee5539fb0f | ||
|
|
97d88abf80 | ||
|
|
9a33db76e9 | ||
|
|
65aa9d0a9f | ||
|
|
baaeef0978 | ||
|
|
e27070e089 | ||
|
|
2ea2723aed | ||
|
|
5188bba5b1 | ||
|
|
33bb16a0d3 | ||
|
|
87f6b81e37 | ||
|
|
3b4f0b8c9d | ||
|
|
3b540b1aac | ||
|
|
378ac39315 | ||
|
|
2dac958227 | ||
|
|
c879cb2af0 | ||
|
|
32336decc6 | ||
|
|
7cd64553ab | ||
|
|
6e737a3fa7 | ||
|
|
25b403cde9 | ||
|
|
535a36c378 | ||
|
|
7b30bc42d7 | ||
|
|
403ae0a963 | ||
|
|
800b91d406 | ||
|
|
bf92b0804e | ||
|
|
7e8ff778f9 | ||
|
|
31f438edfa | ||
|
|
a7ed6454af | ||
|
|
12ea0c2b84 | ||
|
|
44086e8bf4 | ||
|
|
b740a6f906 | ||
|
|
7376d4d890 | ||
|
|
f9d09365ea | ||
|
|
81297db7a8 | ||
|
|
b5ca94ab98 | ||
|
|
a220339fd6 | ||
|
|
0994b6659a | ||
|
|
c4037a346d | ||
|
|
45a6e76d4a | ||
|
|
aee67ec317 | ||
|
|
51610546c4 | ||
|
|
e8e7d27c0d | ||
|
|
166e889b6f | ||
|
|
db95647cd8 | ||
|
|
db13814156 | ||
|
|
5cf3956bc8 | ||
|
|
329e6df722 | ||
|
|
8023852b3c | ||
|
|
228935034d | ||
|
|
acff55dc65 | ||
|
|
61a9110c51 | ||
|
|
3a3e14e0a7 | ||
|
|
6ba767419e | ||
|
|
925365018b | ||
|
|
5960df31bd | ||
|
|
21f9fd92e2 | ||
|
|
9765310136 | ||
|
|
51cde2dd0d | ||
|
|
3311568e50 | ||
|
|
e5918b041a | ||
|
|
f46330ecf0 | ||
|
|
846e80f1fa | ||
|
|
631519d7c7 | ||
|
|
bbeb31e8a3 | ||
|
|
52bcf07e25 | ||
|
|
4d725221a5 | ||
|
|
c8a0619141 | ||
|
|
e1d7b1801d | ||
|
|
15456ae377 | ||
|
|
1c3d711298 | ||
|
|
1bee69cefb | ||
|
|
cf740d9605 | ||
|
|
d2aca24d06 | ||
|
|
6e042c4b78 | ||
|
|
1afd1704ab | ||
|
|
d5f81fe5d8 | ||
|
|
fada0a735f | ||
|
|
35de0c031d | ||
|
|
2e5eefc079 | ||
|
|
1fa264b0bf | ||
|
|
d2a0940858 | ||
|
|
4ff8eb6494 | ||
|
|
8ca87cdb2a | ||
|
|
f45b115355 | ||
|
|
7490211340 | ||
|
|
76d028277a | ||
|
|
0a0066fe5c | ||
|
|
4f7e38db3b | ||
|
|
54dcd2d8be | ||
|
|
6c1d7cce8d | ||
|
|
06b090cdf6 | ||
|
|
3653b4e7cb | ||
|
|
c6c890da63 | ||
|
|
75e7bc2d9c | ||
|
|
649f983990 | ||
|
|
193628913a | ||
|
|
cb304d7d53 | ||
|
|
4bb7bd4603 | ||
|
|
1e408eb8ae | ||
|
|
d762d18c7b | ||
|
|
3622c7bb53 | ||
|
|
1b9b2d9c95 | ||
|
|
0d5c60ed8c | ||
|
|
ab2bcb515f | ||
|
|
b3e6eb72eb | ||
|
|
9742aaf0bc | ||
|
|
bc1942c492 | ||
|
|
44facf549a | ||
|
|
09dd9861fd | ||
|
|
8d3b5cf91d | ||
|
|
5a90567e98 | ||
|
|
246ba9057f | ||
|
|
9eecc603db | ||
|
|
1fe4078115 | ||
|
|
ef73a6fe94 | ||
|
|
edef393535 | ||
|
|
97e6fc79ea | ||
|
|
0b82ae7569 | ||
|
|
3cb0e52ca0 | ||
|
|
fd1d32d431 | ||
|
|
8c169489eb | ||
|
|
6ecb6b8055 | ||
|
|
515cd3ebbd | ||
|
|
6c6b89f512 | ||
|
|
1ac5dcfe25 | ||
|
|
ccd5decbf7 | ||
|
|
9a12a29127 | ||
|
|
8d96a3c106 | ||
|
|
41bfd17cd0 | ||
|
|
5614414185 | ||
|
|
7ac4010910 | ||
|
|
ffc5af6d39 | ||
|
|
c64f00fe9e | ||
|
|
d3a49f3f3e | ||
|
|
06c6abe250 | ||
|
|
f54739e337 | ||
|
|
cdc673da06 | ||
|
|
0bd99df26a | ||
|
|
0dcee2f2e2 | ||
|
|
f7f836f5fd | ||
|
|
16d1576c10 | ||
|
|
0d1dbd0350 | ||
|
|
18ea8a4366 | ||
|
|
b9aa720bea | ||
|
|
28473979ec | ||
|
|
dbe5a21f4d | ||
|
|
31d9859f10 | ||
|
|
7cbd2b698c | ||
|
|
6fa3fa7822 | ||
|
|
e80316d43d | ||
|
|
9979b6fd67 | ||
|
|
a36a4cd244 | ||
|
|
f99e2673a6 | ||
|
|
47da7d3b16 | ||
|
|
4f2f6e8d20 | ||
|
|
4da164dcba | ||
|
|
1aab8aa8c8 | ||
|
|
8a2a946bc1 | ||
|
|
038de5ed53 | ||
|
|
0bac362c95 | ||
|
|
04599148fc | ||
|
|
b61faef093 | ||
|
|
642536f83e | ||
|
|
7ebb5e21d2 | ||
|
|
0c18a0f6db | ||
|
|
93768e4014 | ||
|
|
3674b63db4 | ||
|
|
9e8f369da4 | ||
|
|
04cc8b991c | ||
|
|
0342f1d17a | ||
|
|
82838a5ebb | ||
|
|
20042786aa | ||
|
|
2037b57a5d | ||
|
|
2932c7f35d | ||
|
|
53cc6f46d1 | ||
|
|
a5e2ae9a4d | ||
|
|
95beebc5c7 | ||
|
|
f7b8713be1 | ||
|
|
c33d10734f | ||
|
|
edde94af69 | ||
|
|
fbf2b6a6fa | ||
|
|
b84f1b595e | ||
|
|
e4bc52a219 | ||
|
|
dc55e0983a | ||
|
|
f3914b63b3 | ||
|
|
1ad729ca0e | ||
|
|
8c864c207a | ||
|
|
aaadc90b09 | ||
|
|
ea8c86e2e2 | ||
|
|
575e7b3297 | ||
|
|
49b1252a1f | ||
|
|
b0021a759f | ||
|
|
70506767ef | ||
|
|
48002d6143 | ||
|
|
43349a51d1 | ||
|
|
a6052bcd9d | ||
|
|
3d418fa9e1 | ||
|
|
9feff82451 | ||
|
|
647ed90eac | ||
|
|
30b968b3e5 | ||
|
|
c8edf9c1bd | ||
|
|
a2c6a1d46d | ||
|
|
6d5428317f | ||
|
|
b829d2cd05 | ||
|
|
7f46528086 | ||
|
|
71e4c49c3e | ||
|
|
84cfb26512 | ||
|
|
07445e42e3 | ||
|
|
201348202a | ||
|
|
01d2ecda39 | ||
|
|
34967921a5 | ||
|
|
692f7b6dbf | ||
|
|
8dc3923a4f | ||
|
|
b5b74e8b3b | ||
|
|
a7ee9a6444 | ||
|
|
5ac39d0e93 | ||
|
|
e6d8d87c31 | ||
|
|
bed539d16f | ||
|
|
abaefc59a6 | ||
|
|
8d60a40688 | ||
|
|
589b7fc7c5 | ||
|
|
7caa2fd40d | ||
|
|
b59da2c101 | ||
|
|
72ad898a6c | ||
|
|
db919a57f3 | ||
|
|
f33efac045 | ||
|
|
334a27a12b | ||
|
|
08fcbe9acf | ||
|
|
14a8695cc9 | ||
|
|
9e4449257e | ||
|
|
826454e164 | ||
|
|
4c11e448f1 | ||
|
|
cfc5c94f5a | ||
|
|
e6588af790 | ||
|
|
9b81a70808 | ||
|
|
fb50143ec2 | ||
|
|
736c5ecd2c | ||
|
|
e88c75d0b7 | ||
|
|
a849d8906a | ||
|
|
2d2448ebba | ||
|
|
9b0a089e29 | ||
|
|
682bd13b6e | ||
|
|
71ab63e047 | ||
|
|
2e27a2fb85 | ||
|
|
02bf570f08 | ||
|
|
e52ac06fb3 | ||
|
|
c1a741466c | ||
|
|
81ab58e009 | ||
|
|
a42a7515dc | ||
|
|
2dabff65ed | ||
|
|
71d8fbd5fe | ||
|
|
7763abd591 | ||
|
|
6bbba6bd35 | ||
|
|
c7ce4e72c6 | ||
|
|
9e365c27b5 | ||
|
|
4557b1d5c1 | ||
|
|
e9163e4247 | ||
|
|
328bceec2c | ||
|
|
82bb5577b2 | ||
|
|
3e505a8a4e | ||
|
|
cc80242896 | ||
|
|
e521e723d5 | ||
|
|
9213aed8e0 | ||
|
|
d104baf426 | ||
|
|
b89fb8b2ba | ||
|
|
bb8ea94850 | ||
|
|
783c6df0a4 | ||
|
|
06a6b77d2e | ||
|
|
924de43227 | ||
|
|
0597531c72 | ||
|
|
07e75f71cc | ||
|
|
c9d42755ef | ||
|
|
9e45c45688 | ||
|
|
75fd42e152 | ||
|
|
97bc68ad26 | ||
|
|
05a25bd80f | ||
|
|
ffde03bc21 | ||
|
|
0d42bce536 | ||
|
|
bf2eb82728 | ||
|
|
a62530d7b8 | ||
|
|
3e1fa0b937 | ||
|
|
604a918fd1 | ||
|
|
1f02b45600 | ||
|
|
ebb048f1a7 | ||
|
|
c58d70524d | ||
|
|
86fed0db41 | ||
|
|
7cbca93d3d | ||
|
|
c1f846a633 | ||
|
|
7a43087ae0 | ||
|
|
f281f8e65a | ||
|
|
4d26bf08b2 | ||
|
|
146854b098 | ||
|
|
5cfbfdf67c | ||
|
|
00a64c4d2a | ||
|
|
ba7e711a88 | ||
|
|
10dcf4473c | ||
|
|
4c217b85e9 | ||
|
|
c75bd5208b | ||
|
|
1fe7c050a4 | ||
|
|
c6874acb1b | ||
|
|
ffeef640da | ||
|
|
1f054b796d | ||
|
|
35881e30e0 | ||
|
|
a8e55d230a | ||
|
|
083576ab3f | ||
|
|
0387ac510a | ||
|
|
726ae1f856 | ||
|
|
483d8c3aef | ||
|
|
db42d19f44 | ||
|
|
d822c3c809 | ||
|
|
94719d58cd | ||
|
|
307153801d | ||
|
|
a771189939 | ||
|
|
98c65eab46 | ||
|
|
21a37db1da | ||
|
|
4008816c66 | ||
|
|
925e84528c | ||
|
|
8d6ee03d88 | ||
|
|
8cec0e6ab8 | ||
|
|
ad17d8b743 | ||
|
|
2792d24e98 | ||
|
|
ff92fd8d76 | ||
|
|
93ba1c134f | ||
|
|
dc08d545a2 | ||
|
|
ca3cf71c6d | ||
|
|
96beccad82 | ||
|
|
f63c21b17a | ||
|
|
6b27278e6e | ||
|
|
cd0cd14f77 | ||
|
|
94a9404b39 | ||
|
|
2385bbd912 | ||
|
|
327d911f80 | ||
|
|
83f0f01233 | ||
|
|
877ccc059e | ||
|
|
9313d5a886 | ||
|
|
5fb6986a18 | ||
|
|
eb4a5e4fdc | ||
|
|
59e1aedbf3 | ||
|
|
87980277bf | ||
|
|
30fbe6ca83 | ||
|
|
31d28627f1 | ||
|
|
df9ea021b3 | ||
|
|
a198fc0161 | ||
|
|
64bfe1cdc2 | ||
|
|
6a716fa531 | ||
|
|
05b4f67bd3 | ||
|
|
9130485631 | ||
|
|
ae329419a6 | ||
|
|
66462b9085 | ||
|
|
80d070bb67 | ||
|
|
916dd1a398 | ||
|
|
502c77fb6e | ||
|
|
2f8946f372 | ||
|
|
abc58298a3 | ||
|
|
4809c3839b | ||
|
|
7fbcdafa9b | ||
|
|
b2180ecaf7 | ||
|
|
6351bdb633 | ||
|
|
75bff1edc4 | ||
|
|
f512caa81d | ||
|
|
c3178eb7d0 | ||
|
|
562679b366 | ||
|
|
eee0258061 | ||
|
|
0a248d89d5 | ||
|
|
5062cad2b0 | ||
|
|
07f41f5cb6 | ||
|
|
133febe7a7 | ||
|
|
e74c6d9eda | ||
|
|
0499a9c237 | ||
|
|
fbb24fd07f | ||
|
|
0b62cba3b9 | ||
|
|
0fd4645514 | ||
|
|
0e277a8e6d | ||
|
|
d7da00582a | ||
|
|
953320526e | ||
|
|
726b11eb82 | ||
|
|
ca8d518fae | ||
|
|
3e3c101a1e | ||
|
|
c6417cf197 | ||
|
|
4c0aec2f42 | ||
|
|
7331fcbb17 | ||
|
|
f5faad982c | ||
|
|
48c0dcb69b | ||
|
|
0504592f7d | ||
|
|
9ff4197ec4 | ||
|
|
c835616ad2 | ||
|
|
e5449213c2 | ||
|
|
872a5d1982 | ||
|
|
1246810c01 | ||
|
|
fc393ecd64 | ||
|
|
9b9295ea94 | ||
|
|
c403fce786 | ||
|
|
31349634f6 | ||
|
|
cc1afed902 | ||
|
|
3a76ba2c1f | ||
|
|
da330b80c8 | ||
|
|
1028b8189e | ||
|
|
6988ad8bf0 | ||
|
|
e318fe5be0 | ||
|
|
4166a1ca58 | ||
|
|
35ea8adf7d | ||
|
|
be2280907e | ||
|
|
6100f1e39a | ||
|
|
5368f3c323 | ||
|
|
be1a05e566 | ||
|
|
0a02195ca6 | ||
|
|
6887b6c624 | ||
|
|
f7167912e7 | ||
|
|
14feac43fe | ||
|
|
c9e58f3586 | ||
|
|
e8809bbeb8 | ||
|
|
d8b9d81f70 | ||
|
|
4340b1a5b7 | ||
|
|
950b8a097c | ||
|
|
72ed363ac3 | ||
|
|
e493f26442 | ||
|
|
f973cadd80 | ||
|
|
5143f2b83f | ||
|
|
b728e340a0 | ||
|
|
18bfa0edef | ||
|
|
9fbc61f742 |
8
.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
*/.vscode/
|
||||||
|
/.idea/
|
||||||
|
*/dist/
|
||||||
|
.DS_Store
|
||||||
|
node_modules/
|
||||||
|
yarn.lock
|
||||||
|
package-lock.json
|
||||||
|
!seller/yarn.lock
|
||||||
17
.idea/codeStyles/Project.xml
generated
@@ -1,17 +0,0 @@
|
|||||||
<component name="ProjectCodeStyleConfiguration">
|
|
||||||
<code_scheme name="Project" version="173">
|
|
||||||
<option name="OTHER_INDENT_OPTIONS">
|
|
||||||
<value>
|
|
||||||
<option name="INDENT_SIZE" value="2" />
|
|
||||||
<option name="TAB_SIZE" value="2" />
|
|
||||||
</value>
|
|
||||||
</option>
|
|
||||||
<codeStyleSettings language="JavaScript">
|
|
||||||
<indentOptions>
|
|
||||||
<option name="INDENT_SIZE" value="2" />
|
|
||||||
<option name="CONTINUATION_INDENT_SIZE" value="0" />
|
|
||||||
<option name="TAB_SIZE" value="2" />
|
|
||||||
</indentOptions>
|
|
||||||
</codeStyleSettings>
|
|
||||||
</code_scheme>
|
|
||||||
</component>
|
|
||||||
5
.idea/codeStyles/codeStyleConfig.xml
generated
@@ -1,5 +0,0 @@
|
|||||||
<component name="ProjectCodeStyleConfiguration">
|
|
||||||
<state>
|
|
||||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
|
||||||
</state>
|
|
||||||
</component>
|
|
||||||
6
.idea/inspectionProfiles/Project_Default.xml
generated
@@ -1,6 +0,0 @@
|
|||||||
<component name="InspectionProjectProfileManager">
|
|
||||||
<profile version="1.0">
|
|
||||||
<option name="myName" value="Project Default" />
|
|
||||||
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
|
||||||
</profile>
|
|
||||||
</component>
|
|
||||||
12
.idea/lili-shop-ui.iml
generated
@@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="WEB_MODULE" version="4">
|
|
||||||
<component name="NewModuleRootManager">
|
|
||||||
<content url="file://$MODULE_DIR$">
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
|
||||||
</content>
|
|
||||||
<orderEntry type="inheritedJdk" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
||||||
6
.idea/misc.xml
generated
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="JavaScriptSettings">
|
|
||||||
<option name="languageLevel" value="ES6" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
8
.idea/modules.xml
generated
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/.idea/lili-shop-ui.iml" filepath="$PROJECT_DIR$/.idea/lili-shop-ui.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
6
.idea/vcs.xml
generated
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
380
.idea/workspace.xml
generated
@@ -1,380 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="BranchesTreeState">
|
|
||||||
<expand>
|
|
||||||
<path>
|
|
||||||
<item name="ROOT" type="e8cecc67:BranchNodeDescriptor" />
|
|
||||||
<item name="LOCAL_ROOT" type="e8cecc67:BranchNodeDescriptor" />
|
|
||||||
</path>
|
|
||||||
<path>
|
|
||||||
<item name="ROOT" type="e8cecc67:BranchNodeDescriptor" />
|
|
||||||
<item name="REMOTE_ROOT" type="e8cecc67:BranchNodeDescriptor" />
|
|
||||||
</path>
|
|
||||||
<path>
|
|
||||||
<item name="ROOT" type="e8cecc67:BranchNodeDescriptor" />
|
|
||||||
<item name="REMOTE_ROOT" type="e8cecc67:BranchNodeDescriptor" />
|
|
||||||
<item name="GROUP_NODE:origin" type="e8cecc67:BranchNodeDescriptor" />
|
|
||||||
</path>
|
|
||||||
</expand>
|
|
||||||
<select />
|
|
||||||
</component>
|
|
||||||
<component name="ChangeListManager">
|
|
||||||
<list default="true" id="7e964aa0-753b-43f7-854a-2942a3e76fe4" name="默认更改列表" comment="店铺设置">
|
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
|
||||||
<<<<<<< HEAD
|
|
||||||
<change beforePath="$PROJECT_DIR$/buyer/src/pages/home/orderCenter/AddAddress.vue" beforeDir="false" afterPath="$PROJECT_DIR$/buyer/src/pages/home/orderCenter/AddAddress.vue" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/manager/src/config/index.js" beforeDir="false" afterPath="$PROJECT_DIR$/manager/src/config/index.js" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/seller/src/config/index.js" beforeDir="false" afterPath="$PROJECT_DIR$/seller/src/config/index.js" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/seller/src/views/statistics/goods/goodsStatistics.vue" beforeDir="false" afterPath="$PROJECT_DIR$/seller/src/views/statistics/goods/goodsStatistics.vue" afterDir="false" />
|
|
||||||
=======
|
|
||||||
<change beforePath="$PROJECT_DIR$/manager/src/views/goods-unit/index.vue" beforeDir="false" afterPath="$PROJECT_DIR$/manager/src/views/goods-unit/index.vue" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/manager/src/views/sensitiveWords/index.vue" beforeDir="false" afterPath="$PROJECT_DIR$/manager/src/views/sensitiveWords/index.vue" afterDir="false" />
|
|
||||||
>>>>>>> new-lmr
|
|
||||||
</list>
|
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
|
||||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
|
||||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
|
||||||
</component>
|
|
||||||
<component name="FileTemplateManagerImpl">
|
|
||||||
<option name="RECENT_TEMPLATES">
|
|
||||||
<list>
|
|
||||||
<option value="Vue File" />
|
|
||||||
<option value="Vue Single File Component" />
|
|
||||||
<option value="JavaScript File" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
<component name="Git.Settings">
|
|
||||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
|
||||||
</component>
|
|
||||||
<component name="ProjectId" id="1gGPnr0TWcTGoYhLT7QHFe5MrX4" />
|
|
||||||
<component name="ProjectLevelVcsManager">
|
|
||||||
<ConfirmationsSetting value="2" id="Add" />
|
|
||||||
</component>
|
|
||||||
<component name="ProjectViewState">
|
|
||||||
<option name="hideEmptyMiddlePackages" value="true" />
|
|
||||||
<option name="showLibraryContents" value="true" />
|
|
||||||
</component>
|
|
||||||
<component name="PropertiesComponent">
|
|
||||||
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
|
|
||||||
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
|
|
||||||
<property name="SHARE_PROJECT_CONFIGURATION_FILES" value="true" />
|
|
||||||
<property name="WebServerToolWindowFactoryState" value="false" />
|
|
||||||
<<<<<<< HEAD
|
|
||||||
<property name="last_opened_file_path" value="$PROJECT_DIR$/manager/src/api" />
|
|
||||||
=======
|
|
||||||
<property name="last_opened_file_path" value="$PROJECT_DIR$/manager/src/views/sys/setting-manage" />
|
|
||||||
>>>>>>> new-lmr
|
|
||||||
<property name="node.js.detected.package.eslint" value="true" />
|
|
||||||
<property name="node.js.detected.package.tslint" value="true" />
|
|
||||||
<property name="node.js.path.for.package.eslint" value="project" />
|
|
||||||
<property name="node.js.path.for.package.tslint" value="project" />
|
|
||||||
<property name="node.js.selected.package.eslint" value="(autodetect)" />
|
|
||||||
<property name="node.js.selected.package.tslint" value="(autodetect)" />
|
|
||||||
<property name="nodejs_package_manager_path" value="npm" />
|
|
||||||
<property name="settings.editor.selected.configurable" value="preferences.sourceCode.XML" />
|
|
||||||
<property name="ts.external.directory.path" value="$APPLICATION_HOME_DIR$/plugins/JavaScriptLanguage/jsLanguageServicesImpl/external" />
|
|
||||||
</component>
|
|
||||||
<component name="RecentsManager">
|
|
||||||
<key name="CopyFile.RECENT_KEYS">
|
|
||||||
<<<<<<< HEAD
|
|
||||||
<recent name="$PROJECT_DIR$/manager/src/api" />
|
|
||||||
<recent name="$PROJECT_DIR$/manager/src/views/my-components" />
|
|
||||||
=======
|
|
||||||
<recent name="$PROJECT_DIR$/manager/src/views/sys/setting-manage" />
|
|
||||||
>>>>>>> new-lmr
|
|
||||||
<recent name="$PROJECT_DIR$/buyer/src/components/verify" />
|
|
||||||
<recent name="$PROJECT_DIR$/buyer/src/components/change" />
|
|
||||||
</key>
|
|
||||||
<key name="MoveFile.RECENT_KEYS">
|
|
||||||
<recent name="$PROJECT_DIR$/buyer/src/components/change" />
|
|
||||||
<recent name="$PROJECT_DIR$/buyer/src/pages/home/memberCenter" />
|
|
||||||
<recent name="$PROJECT_DIR$/buyer/src/pages/home/orderCenter" />
|
|
||||||
<recent name="$PROJECT_DIR$/buyer/src/pages/home" />
|
|
||||||
<recent name="$PROJECT_DIR$/buyer/src/components/home/order" />
|
|
||||||
</key>
|
|
||||||
</component>
|
|
||||||
<component name="RunManager">
|
|
||||||
<configuration name="Home.vue" type="JavascriptDebugType" temporary="true" nameIsGenerated="true" uri="http://localhost:63342/lili-shop-ui/buyer/src/page/user/Home.vue" useBuiltInWebServerPort="true">
|
|
||||||
<method v="2" />
|
|
||||||
</configuration>
|
|
||||||
<recent_temporary>
|
|
||||||
<list>
|
|
||||||
<item itemvalue="JavaScript Debug.Home.vue" />
|
|
||||||
</list>
|
|
||||||
</recent_temporary>
|
|
||||||
</component>
|
|
||||||
<component name="SvnConfiguration">
|
|
||||||
<configuration />
|
|
||||||
</component>
|
|
||||||
<component name="TaskManager">
|
|
||||||
<task active="true" id="Default" summary="Default task">
|
|
||||||
<changelist id="7e964aa0-753b-43f7-854a-2942a3e76fe4" name="默认更改列表" comment="" />
|
|
||||||
<created>1597738125477</created>
|
|
||||||
<option name="number" value="Default" />
|
|
||||||
<option name="presentableId" value="Default" />
|
|
||||||
<updated>1597738125477</updated>
|
|
||||||
<workItem from="1597738127938" duration="6268000" />
|
|
||||||
<workItem from="1597825716012" duration="3768000" />
|
|
||||||
<workItem from="1597830090678" duration="7632000" />
|
|
||||||
<workItem from="1597972262326" duration="865000" />
|
|
||||||
<workItem from="1597974893526" duration="112000" />
|
|
||||||
<workItem from="1597975021121" duration="17000" />
|
|
||||||
<workItem from="1597975216701" duration="17254000" />
|
|
||||||
<workItem from="1598184961388" duration="14000" />
|
|
||||||
<workItem from="1598233017859" duration="10307000" />
|
|
||||||
<workItem from="1598259954059" duration="2720000" />
|
|
||||||
<workItem from="1598318520176" duration="726000" />
|
|
||||||
<workItem from="1598319433942" duration="106000" />
|
|
||||||
<workItem from="1598319554477" duration="13265000" />
|
|
||||||
<workItem from="1598406300597" duration="6030000" />
|
|
||||||
<workItem from="1598422866858" duration="7787000" />
|
|
||||||
<workItem from="1598491104901" duration="37245000" />
|
|
||||||
<workItem from="1606876680167" duration="61000" />
|
|
||||||
<workItem from="1611131536390" duration="5616000" />
|
|
||||||
<workItem from="1611537245379" duration="828000" />
|
|
||||||
<workItem from="1611538362285" duration="350000" />
|
|
||||||
<workItem from="1611560515629" duration="834000" />
|
|
||||||
<workItem from="1611650051294" duration="3000" />
|
|
||||||
<workItem from="1611818003333" duration="239000" />
|
|
||||||
<workItem from="1613989205923" duration="7005000" />
|
|
||||||
<workItem from="1614076082765" duration="8973000" />
|
|
||||||
<workItem from="1614142479169" duration="2129000" />
|
|
||||||
<workItem from="1614162982178" duration="8343000" />
|
|
||||||
<workItem from="1614228135182" duration="3456000" />
|
|
||||||
<workItem from="1614248866969" duration="8023000" />
|
|
||||||
<workItem from="1614313313338" duration="83000" />
|
|
||||||
<workItem from="1614313447954" duration="211000" />
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00001" summary="管理端页面优化">
|
|
||||||
<created>1613996019944</created>
|
|
||||||
<option name="number" value="00001" />
|
|
||||||
<option name="presentableId" value="LOCAL-00001" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1613996019944</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00002" summary="修复修改商家地址报错问题">
|
|
||||||
<created>1613996389449</created>
|
|
||||||
<option name="number" value="00002" />
|
|
||||||
<option name="presentableId" value="LOCAL-00002" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1613996389449</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00003" summary="去掉id">
|
|
||||||
<created>1614076370139</created>
|
|
||||||
<option name="number" value="00003" />
|
|
||||||
<option name="presentableId" value="LOCAL-00003" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1614076370139</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00004" summary="选择物流规则不能选择物流模板">
|
|
||||||
<created>1614080544415</created>
|
|
||||||
<option name="number" value="00004" />
|
|
||||||
<option name="presentableId" value="LOCAL-00004" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1614080544415</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00005" summary="修改查询条件样式">
|
|
||||||
<created>1614143298555</created>
|
|
||||||
<option name="number" value="00005" />
|
|
||||||
<option name="presentableId" value="LOCAL-00005" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1614143298555</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00006" summary="修改样式">
|
|
||||||
<created>1614143902874</created>
|
|
||||||
<option name="number" value="00006" />
|
|
||||||
<option name="presentableId" value="LOCAL-00006" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1614143902874</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00007" summary="修改更新时间为NAN">
|
|
||||||
<created>1614144541858</created>
|
|
||||||
<option name="number" value="00007" />
|
|
||||||
<option name="presentableId" value="LOCAL-00007" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1614144541858</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00008" summary="修复app版本无法添加和修改">
|
|
||||||
<created>1614230386509</created>
|
|
||||||
<option name="number" value="00008" />
|
|
||||||
<option name="presentableId" value="LOCAL-00008" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1614230386509</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00009" summary="去掉打印">
|
|
||||||
<created>1614230407722</created>
|
|
||||||
<option name="number" value="00009" />
|
|
||||||
<option name="presentableId" value="LOCAL-00009" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1614230407722</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00010" summary="去掉多选">
|
|
||||||
<created>1614230544808</created>
|
|
||||||
<option name="number" value="00010" />
|
|
||||||
<option name="presentableId" value="LOCAL-00010" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1614230544808</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00011" summary="修改消息标题宽度">
|
|
||||||
<created>1614230627881</created>
|
|
||||||
<option name="number" value="00011" />
|
|
||||||
<option name="presentableId" value="LOCAL-00011" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1614230627881</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00012" summary="店铺相关js提交">
|
|
||||||
<created>1614231645143</created>
|
|
||||||
<option name="number" value="00012" />
|
|
||||||
<option name="presentableId" value="LOCAL-00012" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1614231645143</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00013" summary="店铺修改">
|
|
||||||
<created>1614231785359</created>
|
|
||||||
<option name="number" value="00013" />
|
|
||||||
<option name="presentableId" value="LOCAL-00013" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1614231785359</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00014" summary="优化页面">
|
|
||||||
<created>1614249105672</created>
|
|
||||||
<option name="number" value="00014" />
|
|
||||||
<option name="presentableId" value="LOCAL-00014" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1614249105672</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00015" summary="页面优化">
|
|
||||||
<created>1614258980903</created>
|
|
||||||
<option name="number" value="00015" />
|
|
||||||
<option name="presentableId" value="LOCAL-00015" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1614258980903</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00016" summary="页面优化">
|
|
||||||
<created>1614259068248</created>
|
|
||||||
<option name="number" value="00016" />
|
|
||||||
<option name="presentableId" value="LOCAL-00016" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1614259068248</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00017" summary="页面优化">
|
|
||||||
<created>1614313690732</created>
|
|
||||||
<option name="number" value="00017" />
|
|
||||||
<option name="presentableId" value="LOCAL-00017" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1614313690732</updated>
|
|
||||||
</task>
|
|
||||||
<option name="localTasksCounter" value="18" />
|
|
||||||
<servers />
|
|
||||||
</component>
|
|
||||||
<component name="TypeScriptGeneratedFilesManager">
|
|
||||||
<option name="version" value="1" />
|
|
||||||
</component>
|
|
||||||
<component name="Vcs.Log.History.Properties">
|
|
||||||
<option name="COLUMN_ID_ORDER">
|
|
||||||
<list>
|
|
||||||
<option value="Default.Root" />
|
|
||||||
<option value="Default.Author" />
|
|
||||||
<option value="Default.Date" />
|
|
||||||
<option value="Default.Subject" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
<component name="Vcs.Log.Tabs.Properties">
|
|
||||||
<option name="TAB_STATES">
|
|
||||||
<map>
|
|
||||||
<entry key="1">
|
|
||||||
<value>
|
|
||||||
<State>
|
|
||||||
<option name="SHOW_ONLY_AFFECTED_CHANGES" value="true" />
|
|
||||||
<option name="FILTERS">
|
|
||||||
<map>
|
|
||||||
<entry key="branch">
|
|
||||||
<value>
|
|
||||||
<list>
|
|
||||||
<option value="HEAD" />
|
|
||||||
</list>
|
|
||||||
</value>
|
|
||||||
</entry>
|
|
||||||
<entry key="structure">
|
|
||||||
<value>
|
|
||||||
<list>
|
|
||||||
<option value="dir:/Users/liushuai/Documents/workspace/lili-shop-ui/seller/src/router" />
|
|
||||||
</list>
|
|
||||||
</value>
|
|
||||||
</entry>
|
|
||||||
</map>
|
|
||||||
</option>
|
|
||||||
</State>
|
|
||||||
</value>
|
|
||||||
</entry>
|
|
||||||
<entry key="MAIN">
|
|
||||||
<value>
|
|
||||||
<State>
|
|
||||||
<option name="COLUMN_ORDER" />
|
|
||||||
</State>
|
|
||||||
</value>
|
|
||||||
</entry>
|
|
||||||
</map>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
<component name="VcsManagerConfiguration">
|
|
||||||
<MESSAGE value="店铺设置" />
|
|
||||||
<MESSAGE value="文件排序问题处理" />
|
|
||||||
<MESSAGE value="管理端页面优化" />
|
|
||||||
<MESSAGE value="修复修改商家地址报错问题" />
|
|
||||||
<MESSAGE value="去掉id" />
|
|
||||||
<MESSAGE value="选择物流规则不能选择物流模板" />
|
|
||||||
<MESSAGE value="修改查询条件样式" />
|
|
||||||
<MESSAGE value="修改样式" />
|
|
||||||
<MESSAGE value="修改更新时间为NAN" />
|
|
||||||
<MESSAGE value="修复app版本无法添加和修改" />
|
|
||||||
<MESSAGE value="去掉打印" />
|
|
||||||
<MESSAGE value="去掉多选" />
|
|
||||||
<MESSAGE value="修改消息标题宽度" />
|
|
||||||
<MESSAGE value="店铺相关js提交" />
|
|
||||||
<MESSAGE value="店铺修改" />
|
|
||||||
<MESSAGE value="优化页面" />
|
|
||||||
<MESSAGE value="页面优化" />
|
|
||||||
<option name="LAST_COMMIT_MESSAGE" value="页面优化" />
|
|
||||||
</component>
|
|
||||||
<component name="WindowStateProjectService">
|
|
||||||
<state x="2074" y="292" key="CommitChangelistDialog2" timestamp="1614313690605">
|
|
||||||
<screen x="0" y="23" width="3440" height="1333" />
|
|
||||||
</state>
|
|
||||||
<state x="2074" y="292" key="CommitChangelistDialog2/0.23.3440.1333@0.23.3440.1333" timestamp="1614313690605" />
|
|
||||||
<state x="1660" y="123" width="1572" height="1133" key="DiffContextDialog" timestamp="1614231764977">
|
|
||||||
<screen x="0" y="23" width="3440" height="1333" />
|
|
||||||
</state>
|
|
||||||
<state x="1660" y="123" width="1572" height="1133" key="DiffContextDialog/0.23.3440.1333@0.23.3440.1333" timestamp="1614231764977" />
|
|
||||||
<state x="2046" y="418" key="Vcs.Push.Dialog.v2" timestamp="1614313692405">
|
|
||||||
<screen x="0" y="23" width="3440" height="1333" />
|
|
||||||
</state>
|
|
||||||
<state x="2046" y="418" key="Vcs.Push.Dialog.v2/0.23.3440.1333@0.23.3440.1333" timestamp="1614313692405" />
|
|
||||||
<state x="2055" y="414" width="782" height="550" key="find.popup" timestamp="1614256597933">
|
|
||||||
<screen x="0" y="23" width="3440" height="1333" />
|
|
||||||
</state>
|
|
||||||
<state x="2055" y="414" width="782" height="550" key="find.popup/0.23.3440.1333@0.23.3440.1333" timestamp="1614256597933" />
|
|
||||||
<state x="2111" y="325" key="run.anything.popup" timestamp="1613991372498">
|
|
||||||
<screen x="0" y="23" width="3440" height="1333" />
|
|
||||||
</state>
|
|
||||||
<state x="2111" y="325" key="run.anything.popup/0.23.3440.1333@0.23.3440.1333" timestamp="1613991372498" />
|
|
||||||
<state x="2111" y="327" width="670" height="676" key="search.everywhere.popup" timestamp="1614254687317">
|
|
||||||
<screen x="0" y="23" width="3440" height="1333" />
|
|
||||||
</state>
|
|
||||||
<state x="2111" y="327" width="670" height="676" key="search.everywhere.popup/0.23.3440.1333@0.23.3440.1333" timestamp="1614254687317" />
|
|
||||||
</component>
|
|
||||||
<component name="XDebuggerManager">
|
|
||||||
<breakpoint-manager>
|
|
||||||
<breakpoints>
|
|
||||||
<line-breakpoint enabled="true" type="javascript">
|
|
||||||
<url>file://$PROJECT_DIR$/manager/src/views/sys/monitor/monitor.vue</url>
|
|
||||||
<line>5</line>
|
|
||||||
<option name="timeStamp" value="2" />
|
|
||||||
</line-breakpoint>
|
|
||||||
</breakpoints>
|
|
||||||
</breakpoint-manager>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
695
LICENSE
@@ -1,674 +1,21 @@
|
|||||||
GNU GENERAL PUBLIC LICENSE
|
MIT License
|
||||||
Version 3, 29 June 2007
|
|
||||||
|
Copyright (c) 2020-2026 Beijing Hongye Huicheng Technology Co., Ltd. (北京宏业汇成科技有限公司)
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this license document, but changing it is not allowed.
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
Preamble
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
The GNU General Public License is a free, copyleft license for
|
furnished to do so, subject to the following conditions:
|
||||||
software and other kinds of works.
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
The licenses for most software and other practical works are designed
|
copies or substantial portions of the Software.
|
||||||
to take away your freedom to share and change the works. By contrast,
|
|
||||||
the GNU General Public License is intended to guarantee your freedom to
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
share and change all versions of a program--to make sure it remains free
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
software for all its users. We, the Free Software Foundation, use the
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
GNU General Public License for most of our software; it applies also to
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
any other work released this way by its authors. You can apply it to
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
your programs, too.
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
When we speak of free software, we are referring to freedom, not
|
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
|
||||||
have the freedom to distribute copies of free software (and charge for
|
|
||||||
them if you wish), that you receive source code or can get it if you
|
|
||||||
want it, that you can change the software or use pieces of it in new
|
|
||||||
free programs, and that you know you can do these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to prevent others from denying you
|
|
||||||
these rights or asking you to surrender the rights. Therefore, you have
|
|
||||||
certain responsibilities if you distribute copies of the software, or if
|
|
||||||
you modify it: responsibilities to respect the freedom of others.
|
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether
|
|
||||||
gratis or for a fee, you must pass on to the recipients the same
|
|
||||||
freedoms that you received. You must make sure that they, too, receive
|
|
||||||
or can get the source code. And you must show them these terms so they
|
|
||||||
know their rights.
|
|
||||||
|
|
||||||
Developers that use the GNU GPL protect your rights with two steps:
|
|
||||||
(1) assert copyright on the software, and (2) offer you this License
|
|
||||||
giving you legal permission to copy, distribute and/or modify it.
|
|
||||||
|
|
||||||
For the developers' and authors' protection, the GPL clearly explains
|
|
||||||
that there is no warranty for this free software. For both users' and
|
|
||||||
authors' sake, the GPL requires that modified versions be marked as
|
|
||||||
changed, so that their problems will not be attributed erroneously to
|
|
||||||
authors of previous versions.
|
|
||||||
|
|
||||||
Some devices are designed to deny users access to install or run
|
|
||||||
modified versions of the software inside them, although the manufacturer
|
|
||||||
can do so. This is fundamentally incompatible with the aim of
|
|
||||||
protecting users' freedom to change the software. The systematic
|
|
||||||
pattern of such abuse occurs in the area of products for individuals to
|
|
||||||
use, which is precisely where it is most unacceptable. Therefore, we
|
|
||||||
have designed this version of the GPL to prohibit the practice for those
|
|
||||||
products. If such problems arise substantially in other domains, we
|
|
||||||
stand ready to extend this provision to those domains in future versions
|
|
||||||
of the GPL, as needed to protect the freedom of users.
|
|
||||||
|
|
||||||
Finally, every program is threatened constantly by software patents.
|
|
||||||
States should not allow patents to restrict development and use of
|
|
||||||
software on general-purpose computers, but in those that do, we wish to
|
|
||||||
avoid the special danger that patents applied to a free program could
|
|
||||||
make it effectively proprietary. To prevent this, the GPL assures that
|
|
||||||
patents cannot be used to render the program non-free.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
0. Definitions.
|
|
||||||
|
|
||||||
"This License" refers to version 3 of the GNU General Public License.
|
|
||||||
|
|
||||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
|
||||||
works, such as semiconductor masks.
|
|
||||||
|
|
||||||
"The Program" refers to any copyrightable work licensed under this
|
|
||||||
License. Each licensee is addressed as "you". "Licensees" and
|
|
||||||
"recipients" may be individuals or organizations.
|
|
||||||
|
|
||||||
To "modify" a work means to copy from or adapt all or part of the work
|
|
||||||
in a fashion requiring copyright permission, other than the making of an
|
|
||||||
exact copy. The resulting work is called a "modified version" of the
|
|
||||||
earlier work or a work "based on" the earlier work.
|
|
||||||
|
|
||||||
A "covered work" means either the unmodified Program or a work based
|
|
||||||
on the Program.
|
|
||||||
|
|
||||||
To "propagate" a work means to do anything with it that, without
|
|
||||||
permission, would make you directly or secondarily liable for
|
|
||||||
infringement under applicable copyright law, except executing it on a
|
|
||||||
computer or modifying a private copy. Propagation includes copying,
|
|
||||||
distribution (with or without modification), making available to the
|
|
||||||
public, and in some countries other activities as well.
|
|
||||||
|
|
||||||
To "convey" a work means any kind of propagation that enables other
|
|
||||||
parties to make or receive copies. Mere interaction with a user through
|
|
||||||
a computer network, with no transfer of a copy, is not conveying.
|
|
||||||
|
|
||||||
An interactive user interface displays "Appropriate Legal Notices"
|
|
||||||
to the extent that it includes a convenient and prominently visible
|
|
||||||
feature that (1) displays an appropriate copyright notice, and (2)
|
|
||||||
tells the user that there is no warranty for the work (except to the
|
|
||||||
extent that warranties are provided), that licensees may convey the
|
|
||||||
work under this License, and how to view a copy of this License. If
|
|
||||||
the interface presents a list of user commands or options, such as a
|
|
||||||
menu, a prominent item in the list meets this criterion.
|
|
||||||
|
|
||||||
1. Source Code.
|
|
||||||
|
|
||||||
The "source code" for a work means the preferred form of the work
|
|
||||||
for making modifications to it. "Object code" means any non-source
|
|
||||||
form of a work.
|
|
||||||
|
|
||||||
A "Standard Interface" means an interface that either is an official
|
|
||||||
standard defined by a recognized standards body, or, in the case of
|
|
||||||
interfaces specified for a particular programming language, one that
|
|
||||||
is widely used among developers working in that language.
|
|
||||||
|
|
||||||
The "System Libraries" of an executable work include anything, other
|
|
||||||
than the work as a whole, that (a) is included in the normal form of
|
|
||||||
packaging a Major Component, but which is not part of that Major
|
|
||||||
Component, and (b) serves only to enable use of the work with that
|
|
||||||
Major Component, or to implement a Standard Interface for which an
|
|
||||||
implementation is available to the public in source code form. A
|
|
||||||
"Major Component", in this context, means a major essential component
|
|
||||||
(kernel, window system, and so on) of the specific operating system
|
|
||||||
(if any) on which the executable work runs, or a compiler used to
|
|
||||||
produce the work, or an object code interpreter used to run it.
|
|
||||||
|
|
||||||
The "Corresponding Source" for a work in object code form means all
|
|
||||||
the source code needed to generate, install, and (for an executable
|
|
||||||
work) run the object code and to modify the work, including scripts to
|
|
||||||
control those activities. However, it does not include the work's
|
|
||||||
System Libraries, or general-purpose tools or generally available free
|
|
||||||
programs which are used unmodified in performing those activities but
|
|
||||||
which are not part of the work. For example, Corresponding Source
|
|
||||||
includes interface definition files associated with source files for
|
|
||||||
the work, and the source code for shared libraries and dynamically
|
|
||||||
linked subprograms that the work is specifically designed to require,
|
|
||||||
such as by intimate data communication or control flow between those
|
|
||||||
subprograms and other parts of the work.
|
|
||||||
|
|
||||||
The Corresponding Source need not include anything that users
|
|
||||||
can regenerate automatically from other parts of the Corresponding
|
|
||||||
Source.
|
|
||||||
|
|
||||||
The Corresponding Source for a work in source code form is that
|
|
||||||
same work.
|
|
||||||
|
|
||||||
2. Basic Permissions.
|
|
||||||
|
|
||||||
All rights granted under this License are granted for the term of
|
|
||||||
copyright on the Program, and are irrevocable provided the stated
|
|
||||||
conditions are met. This License explicitly affirms your unlimited
|
|
||||||
permission to run the unmodified Program. The output from running a
|
|
||||||
covered work is covered by this License only if the output, given its
|
|
||||||
content, constitutes a covered work. This License acknowledges your
|
|
||||||
rights of fair use or other equivalent, as provided by copyright law.
|
|
||||||
|
|
||||||
You may make, run and propagate covered works that you do not
|
|
||||||
convey, without conditions so long as your license otherwise remains
|
|
||||||
in force. You may convey covered works to others for the sole purpose
|
|
||||||
of having them make modifications exclusively for you, or provide you
|
|
||||||
with facilities for running those works, provided that you comply with
|
|
||||||
the terms of this License in conveying all material for which you do
|
|
||||||
not control copyright. Those thus making or running the covered works
|
|
||||||
for you must do so exclusively on your behalf, under your direction
|
|
||||||
and control, on terms that prohibit them from making any copies of
|
|
||||||
your copyrighted material outside their relationship with you.
|
|
||||||
|
|
||||||
Conveying under any other circumstances is permitted solely under
|
|
||||||
the conditions stated below. Sublicensing is not allowed; section 10
|
|
||||||
makes it unnecessary.
|
|
||||||
|
|
||||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
|
||||||
|
|
||||||
No covered work shall be deemed part of an effective technological
|
|
||||||
measure under any applicable law fulfilling obligations under article
|
|
||||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
|
||||||
similar laws prohibiting or restricting circumvention of such
|
|
||||||
measures.
|
|
||||||
|
|
||||||
When you convey a covered work, you waive any legal power to forbid
|
|
||||||
circumvention of technological measures to the extent such circumvention
|
|
||||||
is effected by exercising rights under this License with respect to
|
|
||||||
the covered work, and you disclaim any intention to limit operation or
|
|
||||||
modification of the work as a means of enforcing, against the work's
|
|
||||||
users, your or third parties' legal rights to forbid circumvention of
|
|
||||||
technological measures.
|
|
||||||
|
|
||||||
4. Conveying Verbatim Copies.
|
|
||||||
|
|
||||||
You may convey verbatim copies of the Program's source code as you
|
|
||||||
receive it, in any medium, provided that you conspicuously and
|
|
||||||
appropriately publish on each copy an appropriate copyright notice;
|
|
||||||
keep intact all notices stating that this License and any
|
|
||||||
non-permissive terms added in accord with section 7 apply to the code;
|
|
||||||
keep intact all notices of the absence of any warranty; and give all
|
|
||||||
recipients a copy of this License along with the Program.
|
|
||||||
|
|
||||||
You may charge any price or no price for each copy that you convey,
|
|
||||||
and you may offer support or warranty protection for a fee.
|
|
||||||
|
|
||||||
5. Conveying Modified Source Versions.
|
|
||||||
|
|
||||||
You may convey a work based on the Program, or the modifications to
|
|
||||||
produce it from the Program, in the form of source code under the
|
|
||||||
terms of section 4, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) The work must carry prominent notices stating that you modified
|
|
||||||
it, and giving a relevant date.
|
|
||||||
|
|
||||||
b) The work must carry prominent notices stating that it is
|
|
||||||
released under this License and any conditions added under section
|
|
||||||
7. This requirement modifies the requirement in section 4 to
|
|
||||||
"keep intact all notices".
|
|
||||||
|
|
||||||
c) You must license the entire work, as a whole, under this
|
|
||||||
License to anyone who comes into possession of a copy. This
|
|
||||||
License will therefore apply, along with any applicable section 7
|
|
||||||
additional terms, to the whole of the work, and all its parts,
|
|
||||||
regardless of how they are packaged. This License gives no
|
|
||||||
permission to license the work in any other way, but it does not
|
|
||||||
invalidate such permission if you have separately received it.
|
|
||||||
|
|
||||||
d) If the work has interactive user interfaces, each must display
|
|
||||||
Appropriate Legal Notices; however, if the Program has interactive
|
|
||||||
interfaces that do not display Appropriate Legal Notices, your
|
|
||||||
work need not make them do so.
|
|
||||||
|
|
||||||
A compilation of a covered work with other separate and independent
|
|
||||||
works, which are not by their nature extensions of the covered work,
|
|
||||||
and which are not combined with it such as to form a larger program,
|
|
||||||
in or on a volume of a storage or distribution medium, is called an
|
|
||||||
"aggregate" if the compilation and its resulting copyright are not
|
|
||||||
used to limit the access or legal rights of the compilation's users
|
|
||||||
beyond what the individual works permit. Inclusion of a covered work
|
|
||||||
in an aggregate does not cause this License to apply to the other
|
|
||||||
parts of the aggregate.
|
|
||||||
|
|
||||||
6. Conveying Non-Source Forms.
|
|
||||||
|
|
||||||
You may convey a covered work in object code form under the terms
|
|
||||||
of sections 4 and 5, provided that you also convey the
|
|
||||||
machine-readable Corresponding Source under the terms of this License,
|
|
||||||
in one of these ways:
|
|
||||||
|
|
||||||
a) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by the
|
|
||||||
Corresponding Source fixed on a durable physical medium
|
|
||||||
customarily used for software interchange.
|
|
||||||
|
|
||||||
b) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by a
|
|
||||||
written offer, valid for at least three years and valid for as
|
|
||||||
long as you offer spare parts or customer support for that product
|
|
||||||
model, to give anyone who possesses the object code either (1) a
|
|
||||||
copy of the Corresponding Source for all the software in the
|
|
||||||
product that is covered by this License, on a durable physical
|
|
||||||
medium customarily used for software interchange, for a price no
|
|
||||||
more than your reasonable cost of physically performing this
|
|
||||||
conveying of source, or (2) access to copy the
|
|
||||||
Corresponding Source from a network server at no charge.
|
|
||||||
|
|
||||||
c) Convey individual copies of the object code with a copy of the
|
|
||||||
written offer to provide the Corresponding Source. This
|
|
||||||
alternative is allowed only occasionally and noncommercially, and
|
|
||||||
only if you received the object code with such an offer, in accord
|
|
||||||
with subsection 6b.
|
|
||||||
|
|
||||||
d) Convey the object code by offering access from a designated
|
|
||||||
place (gratis or for a charge), and offer equivalent access to the
|
|
||||||
Corresponding Source in the same way through the same place at no
|
|
||||||
further charge. You need not require recipients to copy the
|
|
||||||
Corresponding Source along with the object code. If the place to
|
|
||||||
copy the object code is a network server, the Corresponding Source
|
|
||||||
may be on a different server (operated by you or a third party)
|
|
||||||
that supports equivalent copying facilities, provided you maintain
|
|
||||||
clear directions next to the object code saying where to find the
|
|
||||||
Corresponding Source. Regardless of what server hosts the
|
|
||||||
Corresponding Source, you remain obligated to ensure that it is
|
|
||||||
available for as long as needed to satisfy these requirements.
|
|
||||||
|
|
||||||
e) Convey the object code using peer-to-peer transmission, provided
|
|
||||||
you inform other peers where the object code and Corresponding
|
|
||||||
Source of the work are being offered to the general public at no
|
|
||||||
charge under subsection 6d.
|
|
||||||
|
|
||||||
A separable portion of the object code, whose source code is excluded
|
|
||||||
from the Corresponding Source as a System Library, need not be
|
|
||||||
included in conveying the object code work.
|
|
||||||
|
|
||||||
A "User Product" is either (1) a "consumer product", which means any
|
|
||||||
tangible personal property which is normally used for personal, family,
|
|
||||||
or household purposes, or (2) anything designed or sold for incorporation
|
|
||||||
into a dwelling. In determining whether a product is a consumer product,
|
|
||||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
|
||||||
product received by a particular user, "normally used" refers to a
|
|
||||||
typical or common use of that class of product, regardless of the status
|
|
||||||
of the particular user or of the way in which the particular user
|
|
||||||
actually uses, or expects or is expected to use, the product. A product
|
|
||||||
is a consumer product regardless of whether the product has substantial
|
|
||||||
commercial, industrial or non-consumer uses, unless such uses represent
|
|
||||||
the only significant mode of use of the product.
|
|
||||||
|
|
||||||
"Installation Information" for a User Product means any methods,
|
|
||||||
procedures, authorization keys, or other information required to install
|
|
||||||
and execute modified versions of a covered work in that User Product from
|
|
||||||
a modified version of its Corresponding Source. The information must
|
|
||||||
suffice to ensure that the continued functioning of the modified object
|
|
||||||
code is in no case prevented or interfered with solely because
|
|
||||||
modification has been made.
|
|
||||||
|
|
||||||
If you convey an object code work under this section in, or with, or
|
|
||||||
specifically for use in, a User Product, and the conveying occurs as
|
|
||||||
part of a transaction in which the right of possession and use of the
|
|
||||||
User Product is transferred to the recipient in perpetuity or for a
|
|
||||||
fixed term (regardless of how the transaction is characterized), the
|
|
||||||
Corresponding Source conveyed under this section must be accompanied
|
|
||||||
by the Installation Information. But this requirement does not apply
|
|
||||||
if neither you nor any third party retains the ability to install
|
|
||||||
modified object code on the User Product (for example, the work has
|
|
||||||
been installed in ROM).
|
|
||||||
|
|
||||||
The requirement to provide Installation Information does not include a
|
|
||||||
requirement to continue to provide support service, warranty, or updates
|
|
||||||
for a work that has been modified or installed by the recipient, or for
|
|
||||||
the User Product in which it has been modified or installed. Access to a
|
|
||||||
network may be denied when the modification itself materially and
|
|
||||||
adversely affects the operation of the network or violates the rules and
|
|
||||||
protocols for communication across the network.
|
|
||||||
|
|
||||||
Corresponding Source conveyed, and Installation Information provided,
|
|
||||||
in accord with this section must be in a format that is publicly
|
|
||||||
documented (and with an implementation available to the public in
|
|
||||||
source code form), and must require no special password or key for
|
|
||||||
unpacking, reading or copying.
|
|
||||||
|
|
||||||
7. Additional Terms.
|
|
||||||
|
|
||||||
"Additional permissions" are terms that supplement the terms of this
|
|
||||||
License by making exceptions from one or more of its conditions.
|
|
||||||
Additional permissions that are applicable to the entire Program shall
|
|
||||||
be treated as though they were included in this License, to the extent
|
|
||||||
that they are valid under applicable law. If additional permissions
|
|
||||||
apply only to part of the Program, that part may be used separately
|
|
||||||
under those permissions, but the entire Program remains governed by
|
|
||||||
this License without regard to the additional permissions.
|
|
||||||
|
|
||||||
When you convey a copy of a covered work, you may at your option
|
|
||||||
remove any additional permissions from that copy, or from any part of
|
|
||||||
it. (Additional permissions may be written to require their own
|
|
||||||
removal in certain cases when you modify the work.) You may place
|
|
||||||
additional permissions on material, added by you to a covered work,
|
|
||||||
for which you have or can give appropriate copyright permission.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, for material you
|
|
||||||
add to a covered work, you may (if authorized by the copyright holders of
|
|
||||||
that material) supplement the terms of this License with terms:
|
|
||||||
|
|
||||||
a) Disclaiming warranty or limiting liability differently from the
|
|
||||||
terms of sections 15 and 16 of this License; or
|
|
||||||
|
|
||||||
b) Requiring preservation of specified reasonable legal notices or
|
|
||||||
author attributions in that material or in the Appropriate Legal
|
|
||||||
Notices displayed by works containing it; or
|
|
||||||
|
|
||||||
c) Prohibiting misrepresentation of the origin of that material, or
|
|
||||||
requiring that modified versions of such material be marked in
|
|
||||||
reasonable ways as different from the original version; or
|
|
||||||
|
|
||||||
d) Limiting the use for publicity purposes of names of licensors or
|
|
||||||
authors of the material; or
|
|
||||||
|
|
||||||
e) Declining to grant rights under trademark law for use of some
|
|
||||||
trade names, trademarks, or service marks; or
|
|
||||||
|
|
||||||
f) Requiring indemnification of licensors and authors of that
|
|
||||||
material by anyone who conveys the material (or modified versions of
|
|
||||||
it) with contractual assumptions of liability to the recipient, for
|
|
||||||
any liability that these contractual assumptions directly impose on
|
|
||||||
those licensors and authors.
|
|
||||||
|
|
||||||
All other non-permissive additional terms are considered "further
|
|
||||||
restrictions" within the meaning of section 10. If the Program as you
|
|
||||||
received it, or any part of it, contains a notice stating that it is
|
|
||||||
governed by this License along with a term that is a further
|
|
||||||
restriction, you may remove that term. If a license document contains
|
|
||||||
a further restriction but permits relicensing or conveying under this
|
|
||||||
License, you may add to a covered work material governed by the terms
|
|
||||||
of that license document, provided that the further restriction does
|
|
||||||
not survive such relicensing or conveying.
|
|
||||||
|
|
||||||
If you add terms to a covered work in accord with this section, you
|
|
||||||
must place, in the relevant source files, a statement of the
|
|
||||||
additional terms that apply to those files, or a notice indicating
|
|
||||||
where to find the applicable terms.
|
|
||||||
|
|
||||||
Additional terms, permissive or non-permissive, may be stated in the
|
|
||||||
form of a separately written license, or stated as exceptions;
|
|
||||||
the above requirements apply either way.
|
|
||||||
|
|
||||||
8. Termination.
|
|
||||||
|
|
||||||
You may not propagate or modify a covered work except as expressly
|
|
||||||
provided under this License. Any attempt otherwise to propagate or
|
|
||||||
modify it is void, and will automatically terminate your rights under
|
|
||||||
this License (including any patent licenses granted under the third
|
|
||||||
paragraph of section 11).
|
|
||||||
|
|
||||||
However, if you cease all violation of this License, then your
|
|
||||||
license from a particular copyright holder is reinstated (a)
|
|
||||||
provisionally, unless and until the copyright holder explicitly and
|
|
||||||
finally terminates your license, and (b) permanently, if the copyright
|
|
||||||
holder fails to notify you of the violation by some reasonable means
|
|
||||||
prior to 60 days after the cessation.
|
|
||||||
|
|
||||||
Moreover, your license from a particular copyright holder is
|
|
||||||
reinstated permanently if the copyright holder notifies you of the
|
|
||||||
violation by some reasonable means, this is the first time you have
|
|
||||||
received notice of violation of this License (for any work) from that
|
|
||||||
copyright holder, and you cure the violation prior to 30 days after
|
|
||||||
your receipt of the notice.
|
|
||||||
|
|
||||||
Termination of your rights under this section does not terminate the
|
|
||||||
licenses of parties who have received copies or rights from you under
|
|
||||||
this License. If your rights have been terminated and not permanently
|
|
||||||
reinstated, you do not qualify to receive new licenses for the same
|
|
||||||
material under section 10.
|
|
||||||
|
|
||||||
9. Acceptance Not Required for Having Copies.
|
|
||||||
|
|
||||||
You are not required to accept this License in order to receive or
|
|
||||||
run a copy of the Program. Ancillary propagation of a covered work
|
|
||||||
occurring solely as a consequence of using peer-to-peer transmission
|
|
||||||
to receive a copy likewise does not require acceptance. However,
|
|
||||||
nothing other than this License grants you permission to propagate or
|
|
||||||
modify any covered work. These actions infringe copyright if you do
|
|
||||||
not accept this License. Therefore, by modifying or propagating a
|
|
||||||
covered work, you indicate your acceptance of this License to do so.
|
|
||||||
|
|
||||||
10. Automatic Licensing of Downstream Recipients.
|
|
||||||
|
|
||||||
Each time you convey a covered work, the recipient automatically
|
|
||||||
receives a license from the original licensors, to run, modify and
|
|
||||||
propagate that work, subject to this License. You are not responsible
|
|
||||||
for enforcing compliance by third parties with this License.
|
|
||||||
|
|
||||||
An "entity transaction" is a transaction transferring control of an
|
|
||||||
organization, or substantially all assets of one, or subdividing an
|
|
||||||
organization, or merging organizations. If propagation of a covered
|
|
||||||
work results from an entity transaction, each party to that
|
|
||||||
transaction who receives a copy of the work also receives whatever
|
|
||||||
licenses to the work the party's predecessor in interest had or could
|
|
||||||
give under the previous paragraph, plus a right to possession of the
|
|
||||||
Corresponding Source of the work from the predecessor in interest, if
|
|
||||||
the predecessor has it or can get it with reasonable efforts.
|
|
||||||
|
|
||||||
You may not impose any further restrictions on the exercise of the
|
|
||||||
rights granted or affirmed under this License. For example, you may
|
|
||||||
not impose a license fee, royalty, or other charge for exercise of
|
|
||||||
rights granted under this License, and you may not initiate litigation
|
|
||||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
|
||||||
any patent claim is infringed by making, using, selling, offering for
|
|
||||||
sale, or importing the Program or any portion of it.
|
|
||||||
|
|
||||||
11. Patents.
|
|
||||||
|
|
||||||
A "contributor" is a copyright holder who authorizes use under this
|
|
||||||
License of the Program or a work on which the Program is based. The
|
|
||||||
work thus licensed is called the contributor's "contributor version".
|
|
||||||
|
|
||||||
A contributor's "essential patent claims" are all patent claims
|
|
||||||
owned or controlled by the contributor, whether already acquired or
|
|
||||||
hereafter acquired, that would be infringed by some manner, permitted
|
|
||||||
by this License, of making, using, or selling its contributor version,
|
|
||||||
but do not include claims that would be infringed only as a
|
|
||||||
consequence of further modification of the contributor version. For
|
|
||||||
purposes of this definition, "control" includes the right to grant
|
|
||||||
patent sublicenses in a manner consistent with the requirements of
|
|
||||||
this License.
|
|
||||||
|
|
||||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
|
||||||
patent license under the contributor's essential patent claims, to
|
|
||||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
|
||||||
propagate the contents of its contributor version.
|
|
||||||
|
|
||||||
In the following three paragraphs, a "patent license" is any express
|
|
||||||
agreement or commitment, however denominated, not to enforce a patent
|
|
||||||
(such as an express permission to practice a patent or covenant not to
|
|
||||||
sue for patent infringement). To "grant" such a patent license to a
|
|
||||||
party means to make such an agreement or commitment not to enforce a
|
|
||||||
patent against the party.
|
|
||||||
|
|
||||||
If you convey a covered work, knowingly relying on a patent license,
|
|
||||||
and the Corresponding Source of the work is not available for anyone
|
|
||||||
to copy, free of charge and under the terms of this License, through a
|
|
||||||
publicly available network server or other readily accessible means,
|
|
||||||
then you must either (1) cause the Corresponding Source to be so
|
|
||||||
available, or (2) arrange to deprive yourself of the benefit of the
|
|
||||||
patent license for this particular work, or (3) arrange, in a manner
|
|
||||||
consistent with the requirements of this License, to extend the patent
|
|
||||||
license to downstream recipients. "Knowingly relying" means you have
|
|
||||||
actual knowledge that, but for the patent license, your conveying the
|
|
||||||
covered work in a country, or your recipient's use of the covered work
|
|
||||||
in a country, would infringe one or more identifiable patents in that
|
|
||||||
country that you have reason to believe are valid.
|
|
||||||
|
|
||||||
If, pursuant to or in connection with a single transaction or
|
|
||||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
|
||||||
covered work, and grant a patent license to some of the parties
|
|
||||||
receiving the covered work authorizing them to use, propagate, modify
|
|
||||||
or convey a specific copy of the covered work, then the patent license
|
|
||||||
you grant is automatically extended to all recipients of the covered
|
|
||||||
work and works based on it.
|
|
||||||
|
|
||||||
A patent license is "discriminatory" if it does not include within
|
|
||||||
the scope of its coverage, prohibits the exercise of, or is
|
|
||||||
conditioned on the non-exercise of one or more of the rights that are
|
|
||||||
specifically granted under this License. You may not convey a covered
|
|
||||||
work if you are a party to an arrangement with a third party that is
|
|
||||||
in the business of distributing software, under which you make payment
|
|
||||||
to the third party based on the extent of your activity of conveying
|
|
||||||
the work, and under which the third party grants, to any of the
|
|
||||||
parties who would receive the covered work from you, a discriminatory
|
|
||||||
patent license (a) in connection with copies of the covered work
|
|
||||||
conveyed by you (or copies made from those copies), or (b) primarily
|
|
||||||
for and in connection with specific products or compilations that
|
|
||||||
contain the covered work, unless you entered into that arrangement,
|
|
||||||
or that patent license was granted, prior to 28 March 2007.
|
|
||||||
|
|
||||||
Nothing in this License shall be construed as excluding or limiting
|
|
||||||
any implied license or other defenses to infringement that may
|
|
||||||
otherwise be available to you under applicable patent law.
|
|
||||||
|
|
||||||
12. No Surrender of Others' Freedom.
|
|
||||||
|
|
||||||
If conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot convey a
|
|
||||||
covered work so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you may
|
|
||||||
not convey it at all. For example, if you agree to terms that obligate you
|
|
||||||
to collect a royalty for further conveying from those to whom you convey
|
|
||||||
the Program, the only way you could satisfy both those terms and this
|
|
||||||
License would be to refrain entirely from conveying the Program.
|
|
||||||
|
|
||||||
13. Use with the GNU Affero General Public License.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, you have
|
|
||||||
permission to link or combine any covered work with a work licensed
|
|
||||||
under version 3 of the GNU Affero General Public License into a single
|
|
||||||
combined work, and to convey the resulting work. The terms of this
|
|
||||||
License will continue to apply to the part which is the covered work,
|
|
||||||
but the special requirements of the GNU Affero General Public License,
|
|
||||||
section 13, concerning interaction through a network will apply to the
|
|
||||||
combination as such.
|
|
||||||
|
|
||||||
14. Revised Versions of this License.
|
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions of
|
|
||||||
the GNU General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the
|
|
||||||
Program specifies that a certain numbered version of the GNU General
|
|
||||||
Public License "or any later version" applies to it, you have the
|
|
||||||
option of following the terms and conditions either of that numbered
|
|
||||||
version or of any later version published by the Free Software
|
|
||||||
Foundation. If the Program does not specify a version number of the
|
|
||||||
GNU General Public License, you may choose any version ever published
|
|
||||||
by the Free Software Foundation.
|
|
||||||
|
|
||||||
If the Program specifies that a proxy can decide which future
|
|
||||||
versions of the GNU General Public License can be used, that proxy's
|
|
||||||
public statement of acceptance of a version permanently authorizes you
|
|
||||||
to choose that version for the Program.
|
|
||||||
|
|
||||||
Later license versions may give you additional or different
|
|
||||||
permissions. However, no additional obligations are imposed on any
|
|
||||||
author or copyright holder as a result of your choosing to follow a
|
|
||||||
later version.
|
|
||||||
|
|
||||||
15. Disclaimer of Warranty.
|
|
||||||
|
|
||||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
|
||||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
|
||||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
|
||||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
|
||||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
|
||||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
16. Limitation of Liability.
|
|
||||||
|
|
||||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
|
||||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
|
||||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
|
||||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
|
||||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
|
||||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
|
||||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
|
||||||
SUCH DAMAGES.
|
|
||||||
|
|
||||||
17. Interpretation of Sections 15 and 16.
|
|
||||||
|
|
||||||
If the disclaimer of warranty and limitation of liability provided
|
|
||||||
above cannot be given local legal effect according to their terms,
|
|
||||||
reviewing courts shall apply local law that most closely approximates
|
|
||||||
an absolute waiver of all civil liability in connection with the
|
|
||||||
Program, unless a warranty or assumption of liability accompanies a
|
|
||||||
copy of the Program in return for a fee.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
state the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program does terminal interaction, make it output a short
|
|
||||||
notice like this when it starts in an interactive mode:
|
|
||||||
|
|
||||||
<program> Copyright (C) <year> <name of author>
|
|
||||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
|
||||||
parts of the General Public License. Of course, your program's commands
|
|
||||||
might be different; for a GUI interface, you would use an "about box".
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or school,
|
|
||||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
|
||||||
For more information on this, and how to apply and follow the GNU GPL, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The GNU General Public License does not permit incorporating your program
|
|
||||||
into proprietary programs. If your program is a subroutine library, you
|
|
||||||
may consider it more useful to permit linking proprietary applications with
|
|
||||||
the library. If this is what you want to do, use the GNU Lesser General
|
|
||||||
Public License instead of this License. But first, please read
|
|
||||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
|
||||||
|
|||||||
201
MIGRATION-VUE3.md
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
# Lilishop UI — Vue 3 迁移与上线前检查清单
|
||||||
|
|
||||||
|
四个子项目(buyer / seller / manager / im)已完成 **Vue 3 + Element Plus** 迁移,并完成依赖小版本对齐。本文档供上线前统一回归使用。
|
||||||
|
|
||||||
|
## 技术栈(四端一致)
|
||||||
|
|
||||||
|
| 类别 | 包 | 版本(package.json) |
|
||||||
|
|------|-----|---------------------|
|
||||||
|
| 框架 | vue | ^3.5.35 |
|
||||||
|
| 编译 | @vue/compiler-sfc | ^3.5.35 |
|
||||||
|
| 路由 | vue-router | ^4.6.4 |
|
||||||
|
| 状态 | pinia | ^4.0.3(四端已全部从 vuex 迁移完成) |
|
||||||
|
| 组件写法 | `<script setup>` | 四端 597 个组件已全部完成 Options API → 组合式 API 迁移;各端 eslint 已启用 `vue/component-api-style: ['warn', ['script-setup']]` 防止回退 |
|
||||||
|
| UI | element-plus | ^2.14.1 |
|
||||||
|
| 图标 | @element-plus/icons-vue | ^2.3.2 |
|
||||||
|
| 请求 | axios | ^1.7.9 |
|
||||||
|
| 兼容 | core-js | ^3.49.0 |
|
||||||
|
| 构建 | @vue/cli-service | ^5.0.9 |
|
||||||
|
|
||||||
|
> 使用 `^` 范围,实际安装版本以各目录 `yarn.lock` 为准。
|
||||||
|
> 要求 **Node >= 16**,包管理统一 **yarn**。
|
||||||
|
|
||||||
|
## 本地启动
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 买家端
|
||||||
|
cd buyer && yarn install && yarn dev # 端口 10000
|
||||||
|
|
||||||
|
# 商家端
|
||||||
|
cd seller && yarn install && yarn dev # 端口 10002
|
||||||
|
|
||||||
|
# 管理端
|
||||||
|
cd manager && yarn install && yarn dev # 端口 10003
|
||||||
|
|
||||||
|
# IM 客服
|
||||||
|
cd im && yarn install && yarn dev # 端口 8000
|
||||||
|
```
|
||||||
|
|
||||||
|
生产构建(上线前必跑):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd buyer && yarn build
|
||||||
|
cd seller && yarn build
|
||||||
|
cd manager && yarn build
|
||||||
|
cd im && yarn build
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、通用检查(四端都要过)
|
||||||
|
|
||||||
|
### 1. 认证与请求(axios 1.x 重点)
|
||||||
|
|
||||||
|
各端请求封装位置:
|
||||||
|
|
||||||
|
| 端 | 文件 |
|
||||||
|
|----|------|
|
||||||
|
| buyer | `buyer/src/plugins/request.js` |
|
||||||
|
| seller | `seller/src/libs/axios.js` |
|
||||||
|
| manager | `manager/src/libs/axios.js` |
|
||||||
|
| im | `im/src/utils/request.js` |
|
||||||
|
|
||||||
|
- [ ] **登录**:账号密码登录成功,token 写入正常
|
||||||
|
- [ ] **登出**:清除 token,跳转登录页
|
||||||
|
- [ ] **401**:token 过期后跳转登录 / 刷新 token(buyer/manager/seller 有刷新逻辑)
|
||||||
|
- [ ] **403**:无权限时提示文案正确、不白屏
|
||||||
|
- [ ] **400 / 5xx**:接口报错能弹出 `Message` / `ElMessage` / `Notification`
|
||||||
|
- [ ] **网络超时**:断网或超时后有错误提示,页面不卡死
|
||||||
|
- [ ] **GET 带参**:列表筛选、分页参数序列化正常
|
||||||
|
- [ ] **POST JSON**:`Content-Type: application/json` 请求体正确
|
||||||
|
- [ ] **POST 表单**:`application/x-www-form-urlencoded` 提交正常(im 等)
|
||||||
|
|
||||||
|
### 2. Element Plus UI(2.6 → 2.14 重点)
|
||||||
|
|
||||||
|
- [ ] **表格** `el-table`:列展示、排序、空数据、加载态
|
||||||
|
- [ ] **分页** `el-pagination`:翻页、每页条数切换
|
||||||
|
- [ ] **表单** `el-form`:必填校验、错误提示位置
|
||||||
|
- [ ] **弹窗** `el-dialog` / `ElMessageBox`:打开、确认、取消、关闭
|
||||||
|
- [ ] **下拉** `el-select` / `el-dropdown`:选项、点击外部关闭
|
||||||
|
- [ ] **消息** `ElMessage` / `$Message` 兼容层:success / error / warning
|
||||||
|
- [ ] **加载** `ElLoading` / `v-loading`:请求期间遮罩正常消失
|
||||||
|
- [ ] **日期** `el-date-picker`:选择、清空、范围选择
|
||||||
|
- [ ] **上传** `el-upload`:选文件、进度、成功 / 失败回调
|
||||||
|
|
||||||
|
### 3. 路由与页面
|
||||||
|
|
||||||
|
- [ ] 浏览器 **刷新** 当前路由不 404(history 模式 + 服务端配置)
|
||||||
|
- [ ] **动态路由** 加载正常(seller / manager 菜单权限路由)
|
||||||
|
- [ ] 浏览器 **前进 / 后退** 正常
|
||||||
|
- [ ] 各端 **404 页** 可回到首页
|
||||||
|
|
||||||
|
### 4. 构建与部署
|
||||||
|
|
||||||
|
- [ ] 四端 `yarn build` 无 error(warning 可记录,不阻断)
|
||||||
|
- [ ] 生产环境 API 地址配置正确(`config` / 环境变量)
|
||||||
|
- [ ] 静态资源 `publicPath` 与 Nginx / CDN 路径一致
|
||||||
|
- [ ] gzip 压缩包(如有)可正常访问
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、分端专项检查
|
||||||
|
|
||||||
|
### Buyer 买家端(10000)
|
||||||
|
|
||||||
|
详见 [buyer/MIGRATION-VUE3.md](./buyer/MIGRATION-VUE3.md)
|
||||||
|
|
||||||
|
- [ ] 首页装修模块渲染(轮播、商品列表、秒杀区等)
|
||||||
|
- [ ] 商品详情:规格选择、加购、收藏、`el-image` 预览
|
||||||
|
- [ ] 购物车 → 结算 → 支付流程
|
||||||
|
- [ ] 用户中心:订单列表、地址、优惠券、售后
|
||||||
|
- [ ] 登录 / 注册 / 忘记密码
|
||||||
|
- [ ] 店铺入驻、商户页
|
||||||
|
- [ ] 地图(高德 `@amap/amap-jsapi-loader`)定位与选点
|
||||||
|
- [ ] 侧边栏 `el-menu`、头部 `el-dropdown`、动态图标 `iconMap.js`
|
||||||
|
|
||||||
|
### Seller 商家端(10002)
|
||||||
|
|
||||||
|
详见 [seller/MIGRATION-VUE3.md](./seller/MIGRATION-VUE3.md)
|
||||||
|
|
||||||
|
- [ ] 商家登录、店铺信息
|
||||||
|
- [ ] 商品发布三步流程(`goodsOperation` 步骤条)
|
||||||
|
- [ ] 订单管理:发货、退款、详情
|
||||||
|
- [ ] 促销 / 分销 / 统计图表(`@antv/g2`)
|
||||||
|
- [ ] 页面装修(wap / modelList,从 manager 同步部分)
|
||||||
|
- [ ] 图片懒加载 `vue-lazyload`
|
||||||
|
- [ ] Excel 导出 `vue-json-excel`
|
||||||
|
|
||||||
|
### Manager 管理端(10003)
|
||||||
|
|
||||||
|
详见 [manager/MIGRATION-VUE3.md](./manager/MIGRATION-VUE3.md)
|
||||||
|
|
||||||
|
- [ ] 管理员登录、权限菜单、动态路由
|
||||||
|
- [ ] 系统设置(`sys/setting-manage` 各 Tab)
|
||||||
|
- [ ] 菜单 / 部门管理
|
||||||
|
- [ ] 页面装修(PC + H5)
|
||||||
|
- [ ] 文章管理
|
||||||
|
- [ ] 商品 / 订单 / 会员 / 促销等核心列表 CRUD
|
||||||
|
- [ ] 富文本 TinyMCE 编辑、图片上传
|
||||||
|
- [ ] 多语言 `vue-i18n` 切换(如有启用)
|
||||||
|
|
||||||
|
### IM 客服端(8000)
|
||||||
|
|
||||||
|
详见 [im/MIGRATION-VUE3.md](./im/MIGRATION-VUE3.md)
|
||||||
|
|
||||||
|
- [ ] 带 token 参数进入会话页
|
||||||
|
- [ ] 对话列表加载、切换会话、未读数
|
||||||
|
- [ ] 发送文字、表情、图片消息
|
||||||
|
- [ ] 商品 / 订单卡片链接跳转(`linkToGoods` / `linkToOrders`)
|
||||||
|
- [ ] 右键菜单(复制、撤回、删除等)
|
||||||
|
- [ ] WebSocket 连接 / 断线重连 / 新消息通知
|
||||||
|
- [ ] 最近浏览、订单列表侧栏(商家场景)
|
||||||
|
- [ ] 用户名片弹层 `$user()`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、已知可忽略项
|
||||||
|
|
||||||
|
| 项 | 说明 |
|
||||||
|
|----|------|
|
||||||
|
| `vue-awesome-swiper` peer warning | 历史依赖,Vue 3 下仍有 peer 告警,功能正常可暂忽略 |
|
||||||
|
| im 内 `<i class="el-icon-*">` | Element Plus 无字体图标,部分旧图标可能不显示,不影响核心功能 |
|
||||||
|
| `vue-prism-editor@2.0.0-alpha.2` | im 代码块编辑器刻意锁定 alpha 版 |
|
||||||
|
| 打包体积 warning | chunk-vendors 偏大,属 Element Plus 全量引入,可后续做按需优化 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、问题记录模板
|
||||||
|
|
||||||
|
上线测试时建议按端记录:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
### [端名] 问题标题
|
||||||
|
- 页面/路由:
|
||||||
|
- 操作步骤:
|
||||||
|
- 预期:
|
||||||
|
- 实际:
|
||||||
|
- 控制台报错:
|
||||||
|
- 优先级:P0 / P1 / P2
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、子项目文档索引
|
||||||
|
|
||||||
|
| 端 | 迁移说明 |
|
||||||
|
|----|----------|
|
||||||
|
| buyer | [buyer/MIGRATION-VUE3.md](./buyer/MIGRATION-VUE3.md) |
|
||||||
|
| seller | [seller/MIGRATION-VUE3.md](./seller/MIGRATION-VUE3.md) |
|
||||||
|
| manager | [manager/MIGRATION-VUE3.md](./manager/MIGRATION-VUE3.md) |
|
||||||
|
| im | [im/MIGRATION-VUE3.md](./im/MIGRATION-VUE3.md) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、建议上线顺序
|
||||||
|
|
||||||
|
1. **manager**(后台配置源头)
|
||||||
|
2. **seller**(商家经营)
|
||||||
|
3. **buyer**(C 端流量最大)
|
||||||
|
4. **im**(客服,依赖前后端 WebSocket)
|
||||||
|
|
||||||
|
每上一端,至少完成本文 **第一节通用检查** + 对应 **第二节分端检查** 后再切下一端。
|
||||||
144
README.en.md
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
<div align="center">
|
||||||
|
<img src="./manager/src/assets/logo.png" width="180" alt="Lilishop Logo" />
|
||||||
|
<h1>Lilishop(PickMall) - Web Frontend (Vue 3)</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<a href="https://github.com/lilishop/lilishop"><img src="https://img.shields.io/github/stars/lilishop/lilishop.svg?style=social&logo=github" alt="GitHub Stars" /></a>
|
||||||
|
<a href="https://gitee.com/beijing_hongye_huicheng/lilishop"><img src="https://gitee.com/beijing_hongye_huicheng/lilishop/badge/star.svg?theme=dark" alt="Gitee Stars" /></a>
|
||||||
|
<a href="./LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License" /></a>
|
||||||
|
<a href="https://vuejs.org/"><img src="https://img.shields.io/badge/Vue-3.5-brightgreen.svg" alt="Vue 3" /></a>
|
||||||
|
<a href="https://element-plus.org/"><img src="https://img.shields.io/badge/Element%20Plus-2.x-409EFF.svg" alt="Element Plus" /></a>
|
||||||
|
<a href="https://pinia.vuejs.org/"><img src="https://img.shields.io/badge/Pinia-4.x-yellow.svg" alt="Pinia" /></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<a href="https://pickmall.cn">🏠 Official Website</a> ·
|
||||||
|
<a href="https://bdwx2tfwwt.feishu.cn/wiki/space/7675179368632617952?ccm_open_type=lark_wiki_spaceLink&open_tab_from=wiki_home">📖 Product Documentation</a> ·
|
||||||
|
<a href="#2-online-demo">💻 Online Demo</a> ·
|
||||||
|
<a href="https://github.com/lilishop/lilishop">💻 GitHub</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<a href="./README.md">简体中文</a> | <b>English</b>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
> ⭐ **If you like this project, please click `Star` in the top-right corner to support us! Your Star is our greatest motivation for continuous open-source iteration!**
|
||||||
|
|
||||||
|
**LILISHOP** is an open-source e-commerce system built with Spring Boot, Vue 3, and uni-app. It supports B2B2C multi-vendor marketplaces, WeChat Mini Programs, H5, Android/iOS Apps, live-streaming e-commerce, affiliate distribution, and flash sales.
|
||||||
|
|
||||||
|
### ✨ Why Choose Lilishop
|
||||||
|
- 🟢 **True MIT License**: Free for commercial use and private secondary development without licensing concerns.
|
||||||
|
- 🚀 **Modern Vue 3 Stack**: Built on `Vue 3.5 + Pinia 4 + Vue Router 4 + Element Plus`, leaving legacy Vue 2 templates behind.
|
||||||
|
- 🧩 **4-in-1 Production Suite**: Covers **PC Buyer Mall (`buyer`)**, **Seller Portal (`seller`)**, **Platform Admin Panel (`manager`)**, and **IM Customer Service Web (`im`)**, complete with drag-and-drop visual storefront decoration and rich analytics.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Overview
|
||||||
|
|
||||||
|
This repository (`lilishop-ui`) is the **Web Frontend Suite** of Lilishop, containing four standalone **Vue 3** web applications: **PC Buyer Mall, Seller Panel, Platform Admin Panel, and IM Customer Service Web**.
|
||||||
|
|
||||||
|
- **Official Website**: <https://pickmall.cn>
|
||||||
|
- **Documentation**: [Product Documentation](https://bdwx2tfwwt.feishu.cn/wiki/space/7675179368632617952?ccm_open_type=lark_wiki_spaceLink&open_tab_from=wiki_home)
|
||||||
|
- **Gitee Repository**: <https://gitee.com/beijing_hongye_huicheng>
|
||||||
|
- **GitHub Main Repository**: <https://github.com/lilishop/lilishop>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Online Demo
|
||||||
|
|
||||||
|
> **Note**: The verification code for the demo environment is `111111`.
|
||||||
|
|
||||||
|
| Portal | URL | Demo Credentials |
|
||||||
|
| :--- | :--- | :--- |
|
||||||
|
| **Platform Admin Panel (`manager`)** | <https://admin-b2b2c.pickmall.cn> | `admin` / `123456` |
|
||||||
|
| **Seller / Store Panel (`seller`)** | <https://store-b2b2c.pickmall.cn> | `13011111111` / `111111` |
|
||||||
|
| **PC Buyer Mall (`buyer`)** | <https://pc-b2b2c.pickmall.cn> | SMS code: `111111` |
|
||||||
|
| **Mobile H5 (`uni-app`)** | <https://m-b2b2c.pickmall.cn> | SMS code: `111111` |
|
||||||
|
|
||||||
|
| WeChat Mini Program | Mobile H5 ([Visit Directly](https://m-b2b2c.pickmall.cn)) |
|
||||||
|
| :---: | :---: |
|
||||||
|
| <img src="https://static.pickmall.cn/images/h5-qrcode.png" width="180" alt="WeChat Mini Program QR Code" /> | <img src="https://lilishop-wechat.oss-cn-beijing.aliyuncs.com/h5-qrcode.png" width="180" alt="Mobile H5 QR Code" /> |
|
||||||
|
| Scan with WeChat | Scan or visit <https://m-b2b2c.pickmall.cn> |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Core Features & Tech Stack
|
||||||
|
|
||||||
|
### Core Features
|
||||||
|
- **Four-Portal Synergy**: Includes Platform Admin, Seller Panel, PC Buyer Mall, and IM Web Workbench with clear role boundaries.
|
||||||
|
- **Drag-and-Drop Visual Decoration**: Built-in visual floor editor (`vuedraggable`) for customizing both PC and mobile storefronts.
|
||||||
|
- **Multi-Vendor B2B2C Operations**: Merchant onboarding, product auditing, split-order fulfillment, promotions, and financial settlement ledgers.
|
||||||
|
- **Rich Business Analytics**: Powered by `@antv/g2` for sales overview, YoY/MoM product reports, member analytics, and distribution metrics.
|
||||||
|
- **IM Customer Service**: Integrated with Tencent Cloud IM / WebSocket customer service for real-time communication.
|
||||||
|
|
||||||
|
### Web Tech Stack
|
||||||
|
| Category | Technology | Description |
|
||||||
|
| :--- | :--- | :--- |
|
||||||
|
| Core Framework | `Vue 3.5` + `Vue Router 4` | Modern reactive frontend framework |
|
||||||
|
| State Management | `Pinia 4` | Official Vue 3 state management library |
|
||||||
|
| UI Library | `Element Plus 2.x` | Enterprise desktop UI component library |
|
||||||
|
| HTTP Client | `Axios 1.x` | Unified request/response interceptors & auth handling |
|
||||||
|
| Data Visualization | `@antv/g2` | Interactive charts and business analytics |
|
||||||
|
| Visual Decoration | `vuedraggable 4` | Drag-and-drop page floor builder |
|
||||||
|
| Messaging & IM | `@tencentcloud/chat` / `sockjs-client` | Real-time customer service messaging |
|
||||||
|
| Video Player | `dplayer` + `hls.js` | Product video and live streaming playback |
|
||||||
|
| Build & Styling | `Vue CLI 5` + `Webpack 5` + `Sass / Less` | Modular build pipeline and theme customization |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Directory Structure
|
||||||
|
|
||||||
|
```text
|
||||||
|
lilishop-ui
|
||||||
|
├── buyer/ # [PC Buyer Mall]
|
||||||
|
│ ├── public/ # Static assets & global config (config.js)
|
||||||
|
│ └── src/
|
||||||
|
│ ├── api/ # Buyer API modules (goods, cart, order, member, promotion)
|
||||||
|
│ ├── components/ # Shared components (floor renderer, navbar, goods card)
|
||||||
|
│ ├── pages/ # PC Mall pages (Home, Product Detail, Checkout, User Center)
|
||||||
|
│ ├── router/ # Route definitions & guards
|
||||||
|
│ ├── stores/ # Pinia stores
|
||||||
|
│ └── utils/ # Request interceptors & helpers
|
||||||
|
├── seller/ # [Seller / Store Management Portal]
|
||||||
|
│ ├── public/ # Static assets & global config
|
||||||
|
│ └── src/
|
||||||
|
│ ├── api/ # Seller API modules
|
||||||
|
│ ├── components/ # Seller shared & decoration components
|
||||||
|
│ ├── views/ # Seller views (goods, orders, after-sales, promotions, store settings)
|
||||||
|
│ ├── router/ # Dynamic permission routes
|
||||||
|
│ └── stores/ # Pinia stores
|
||||||
|
├── manager/ # [Platform Admin Portal]
|
||||||
|
│ ├── public/ # Static assets & global config
|
||||||
|
│ └── src/
|
||||||
|
│ ├── api/ # Admin API modules
|
||||||
|
│ ├── components/ # Admin components, rich-text editor, visual floor builder
|
||||||
|
│ ├── views/ # Admin views (member, goods, order, seller, marketing, finance, stats, system)
|
||||||
|
│ ├── router/ # Menu & permission routes
|
||||||
|
│ └── stores/ # Pinia stores
|
||||||
|
├── im/ # [IM Customer Service Web Client]
|
||||||
|
│ └── src/
|
||||||
|
│ ├── api/ # Chat session & message APIs
|
||||||
|
│ ├── components/ # Chat window, message list, product/order cards
|
||||||
|
│ ├── im-server/ # WebSocket / IM connection manager
|
||||||
|
│ └── views/ # Customer service workbench
|
||||||
|
├── build.sh # Unified build script
|
||||||
|
└── docker-build.sh # Docker image build script
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Related Repositories
|
||||||
|
|
||||||
|
| Repository | Description | Links |
|
||||||
|
| :--- | :--- | :--- |
|
||||||
|
| **`lilishop`** | Backend Services (Spring Boot 4 / Java 21) | [Gitee](https://gitee.com/beijing_hongye_huicheng/lilishop) · [GitHub](https://github.com/lilishop/lilishop) |
|
||||||
|
| **`lilishop-ui`** | PC Mall / Seller / Admin / IM Web Frontend | [Gitee](https://gitee.com/beijing_hongye_huicheng/lilishop-ui) |
|
||||||
|
| **`lilishop-uniapp`** | Mobile Buyer Client (H5 / Mini Program / App) | [Gitee](https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp) |
|
||||||
|
| **`docker`** | Docker Compose, Images & SQL Init Scripts | [Gitee](https://gitee.com/beijing_hongye_huicheng/docker) · [MySQL Scripts](https://gitee.com/beijing_hongye_huicheng/docker/tree/master/init/mysql) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. License
|
||||||
|
|
||||||
|
Lilishop is licensed under the [MIT](./LICENSE) License. Copyright © 2020-2026 **Beijing Hongye Huicheng Technology Co., Ltd.**
|
||||||
426
README.md
@@ -1,277 +1,181 @@
|
|||||||
## Lilishop B2B2C商城系统
|
<div align="center">
|
||||||
|
<img src="./manager/src/assets/logo.png" width="180" alt="Lilishop Logo" />
|
||||||
##### 官方公众号 & 开源不易,如有帮助请点Star
|
<h1>Lilishop(PickMall) 开源商城系统 - Web 前端 (Vue 3)</h1>
|
||||||

|
|
||||||
|
<p>
|
||||||
[](https://gitee.com/beijing_hongye_huicheng/lilishop/stargazers)
|
<a href="https://github.com/lilishop/lilishop"><img src="https://img.shields.io/github/stars/lilishop/lilishop.svg?style=social&logo=github" alt="GitHub Stars" /></a>
|
||||||
|
<a href="https://gitee.com/beijing_hongye_huicheng/lilishop"><img src="https://gitee.com/beijing_hongye_huicheng/lilishop/badge/star.svg?theme=dark" alt="Gitee Stars" /></a>
|
||||||
|
<a href="./LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License" /></a>
|
||||||
### 介绍
|
<a href="https://vuejs.org/"><img src="https://img.shields.io/badge/Vue-3.5-brightgreen.svg" alt="Vue 3" /></a>
|
||||||
**官网**:https://pickmall.cn
|
<a href="https://element-plus.org/"><img src="https://img.shields.io/badge/Element%20Plus-2.x-409EFF.svg" alt="Element Plus" /></a>
|
||||||
|
<a href="https://pinia.vuejs.org/"><img src="https://img.shields.io/badge/Pinia-4.x-yellow.svg" alt="Pinia" /></a>
|
||||||
Lilishop 是一款Java开发,基于SpringBoot研发的B2B2C多用户商城,前端使用 Vue、uniapp开发 **系统全端全部代码开源**
|
</p>
|
||||||
|
|
||||||
产品前后端分离、支持分布式部署。
|
<p>
|
||||||
|
<a href="https://pickmall.cn">🏠 官方网站</a> ·
|
||||||
商城展示端包含 PC、H5、微信小程序、APP。
|
<a href="https://bdwx2tfwwt.feishu.cn/wiki/space/7675179368632617952?ccm_open_type=lark_wiki_spaceLink&open_tab_from=wiki_home">📖 产品文档</a> ·
|
||||||
|
<a href="#2-在线演示">💻 在线演示</a> ·
|
||||||
商城包含 会员模块、**第三方登录模块**、**第三方支付模块**、**楼层装修模块**、订单模块、分销模块、文章模块、系统设置模块、流量分析模块
|
<a href="#7-社区与支持">💬 微信交流群</a>
|
||||||
|
</p>
|
||||||
系统包含各种中间件、搜索引擎、多级缓存、分布式事务、分布式任务调度等,支持Docker,支持k8s。是一款高性能,支持高并发等商城系统。
|
|
||||||
|
<p>
|
||||||
开箱即用,简单配置即可部署一套属于您的系统。
|
<b>简体中文</b> | <a href="./README.en.md">English</a>
|
||||||
|
</p>
|
||||||
### 文档
|
</div>
|
||||||
|
|
||||||
**产品文档**(需求、架构、使用、部署、开发):https://docs.pickmall.cn
|
> ⭐ **如果觉得项目不错,请点击右上角 `Star` 收藏支持!您的 Star 是我们持续开源迭代的最大动力!**
|
||||||
|
|
||||||
|
**LILISHOP** 是基于 Spring Boot / Vue 3 / uni-app 开发的开源商城系统,支持 B2B2C 多商户商城、微信小程序商城、H5 商城、APP 商城、直播电商、分销返佣、秒杀活动。
|
||||||
### 项目链接(gitee)
|
|
||||||
|
### ✨ 为什么选择 Lilishop
|
||||||
**Java后台**:https://gitee.com/beijing_hongye_huicheng/lilishop.git
|
- 🟢 **真 MIT 协议**:支持免费商用与私有化闭源二开,无版权后顾之忧。
|
||||||
|
- 🚀 **Vue 3 全新栈**:全面基于 `Vue 3.5 + Pinia 4 + Vue Router 4 + Element Plus` 构建,告别老旧 Vue 2 架构。
|
||||||
**Vue后台前端**: https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git
|
- 🧩 **四端合一生产级闭环**:完整覆盖 **PC 买家端 (`buyer`)**、**商家端 (`seller`)**、**平台运营管理端 (`manager`)** 与 **在线客服端 (`im`)**,支持拖拽式可视化楼层装修与多维数据统计报表。
|
||||||
|
|
||||||
**Uni-app**:https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp.git
|
---
|
||||||
|
|
||||||
**docker一键部署**:https://gitee.com/beijing_hongye_huicheng/docker.git
|
## 1. 项目简介
|
||||||
|
|
||||||
### 项目链接(github)
|
**Lilishop** 是一款功能完善的 B2B2C 多商户商城系统,采用前后端分离架构,全端代码开源。
|
||||||
|
后端基于 **Spring Boot 4**(Java 21)构建,具备高内聚、低耦合的特性,支持分布式部署;前端覆盖 PC、管理后台、H5、小程序和 APP,基于 **Vue 3** 和 **uni-app** 开发。
|
||||||
**Java后台**:https://github.com/hongyehuicheng/lilishop.git
|
|
||||||
|
本仓库(`lilishop-ui`)为 **Web 前端源码仓库**,包含 **PC 商城端、商家后台、平台管理后台、IM 在线客服** 四个独立子工程。
|
||||||
**Vue后台前端**: https://github.com/hongyehuicheng/lilishop-ui.git
|
|
||||||
|
- **官方网站**: <https://pickmall.cn>
|
||||||
**Uni-app**:https://github.com/hongyehuicheng/lilishop-uniapp.git
|
- **官方文档**: [产品文档](https://bdwx2tfwwt.feishu.cn/wiki/space/7675179368632617952?ccm_open_type=lark_wiki_spaceLink&open_tab_from=wiki_home)
|
||||||
|
- **Gitee 仓库**: <https://gitee.com/beijing_hongye_huicheng>
|
||||||
**docker一键部署**:https://github.com/hongyehuicheng/docker.git
|
- **GitHub 主仓库**: <https://github.com/lilishop/lilishop>
|
||||||
|
|
||||||
### 演示地址
|
---
|
||||||
|
|
||||||
**运营后台**:https://admin-b2b2c.pickmall.cn 账号:admin/123456
|
## 2. 在线演示
|
||||||
|
|
||||||
**店铺后台**:https://store-b2b2c.pickmall.cn 账号:13011111111/111111
|
> **注意**: 演示站手机验证码统一为 `111111`。演示环境部署于 `master` 分支。
|
||||||
|
|
||||||
**用户前台**:https://pc-b2b2c.pickmall.cn
|
| 演示站点 | 访问地址 | 演示账号 |
|
||||||
|
| :--- | :--- | :--- |
|
||||||
**移动端**:https://m-b2b2c.pickmall.cn
|
| **平台运营管理端 (`manager`)** | <https://admin-b2b2c.pickmall.cn> | 账号:`admin` / 密码:`123456` |
|
||||||
|
| **商家店铺管理端 (`seller`)** | <https://store-b2b2c.pickmall.cn> | 账号:`13011111111` / 密码:`111111` |
|
||||||

|
| **商城 PC 买家端 (`buyer`)** | <https://pc-b2b2c.pickmall.cn> | 可使用手机号验证码 `111111` 登录 |
|
||||||
|
| **移动端 H5 (`uni-app`)** | <https://m-b2b2c.pickmall.cn> | 可使用手机号验证码 `111111` 登录 |
|
||||||
### 3行命令搭建本地环境
|
|
||||||
|
| 微信小程序 | 移动端 H5([点击直接访问](https://m-b2b2c.pickmall.cn)) |
|
||||||
温馨提示:由于服务较多,如果笔记本环境启动内存没有32g可能无法启动成功(macbookpro 2020 16g内存启动无法成功),台式机在16g内存、AMD 3700x 的ubuntu系统成功运行。
|
| :---: | :---: |
|
||||||
|
| <img src="https://static.pickmall.cn/images/h5-qrcode.png" width="180" alt="微信小程序体验码" /> | <img src="https://lilishop-wechat.oss-cn-beijing.aliyuncs.com/h5-qrcode.png" width="180" alt="移动端 H5 体验二维码" /> |
|
||||||
##### 下载docker脚本
|
| 微信扫码体验小程序 | 手机扫码或访问 <https://m-b2b2c.pickmall.cn> |
|
||||||
`git clone https://gitee.com/beijing_hongye_huicheng/docker.git `
|
|
||||||
##### 部署基础环境
|
---
|
||||||
`docker-compose up -d`
|
|
||||||
|
## 3. 核心特性与技术栈
|
||||||
##### 部署应用
|
|
||||||
`docker-compose -f docker-compose-application.yml up -d`
|
### 核心特性
|
||||||
|
- **四端协同**: 涵盖平台管理端、商家管理端、PC 买家商城端、IM 客服端,角色边界清晰,开箱即用。
|
||||||
|
- **可视化拖拽装修**: 管理端与商家端内置可视化楼层编辑器(基于 `vuedraggable`),可同步配置 PC 端与移动端首页/专题页。
|
||||||
|
- **多商户入驻与结算**: 完整的商家入驻审核、商品审核、拆单发货、促销报名、财务对账与结算台账体系。
|
||||||
PS:单独部署的话,数据库文件访问这里:https://gitee.com/beijing_hongye_huicheng/docker/tree/master/init/mysql
|
- **多维经营分析**: 集成 `@antv/g2` 图表引擎,提供营业概况、商品同比环比、会员分析、营销与分销数据统计。
|
||||||
|
- **即时通讯客服**: 集成腾讯云 IM / WebSocket 在线客服系统,支持买家、商家与平台实时沟通。
|
||||||
##### 各个地址
|
|
||||||
|
### Web 前端技术栈
|
||||||
| API | 地址 |
|
| 类别 | 技术选型 | 说明 |
|
||||||
| -------------- | --------------- |
|
| :--- | :--- | :--- |
|
||||||
| 买家API | http://127.0.0.1:8888 |
|
| 核心框架 | `Vue 3.5` + `Vue Router 4` | 基于 Composition API 的现代响应式前端框架 |
|
||||||
| 商家API | http://127.0.0.1:8889 |
|
| 状态管理 | `Pinia 4` | 轻量、类型友好的 Vue 3 官方状态管理库 |
|
||||||
| 管理端API | http://127.0.0.1:8887 |
|
| UI 组件库 | `Element Plus 2.x` | 企业级中后台与桌面端 UI 组件库 |
|
||||||
| 通用API | http://127.0.0.1:8890 |
|
| 网络请求 | `Axios 1.x` | 统一请求/响应拦截、Token 刷新与异常提示 |
|
||||||
|
| 数据可视化 | `@antv/g2` | 运营端与商家端数据统计图表渲染 |
|
||||||
| 前端演示 | 地址 |
|
| 可视化拖拽 | `vuedraggable 4` | 商城首页及专题楼层可视化拖拽装修 |
|
||||||
| -------------- | --------------- |
|
| 即时通讯 | `@tencentcloud/chat` / `sockjs-client` | 在线客服消息收发与实时通知 |
|
||||||
| PC | http://127.0.0.1:10000 |
|
| 音视频播放 | `dplayer` + `hls.js` | 商品视频与直播流播放支持 |
|
||||||
| WAP | http://127.0.0.1:10001 |
|
| 构建与样式 | `Vue CLI 5` + `Webpack 5` + `Sass / Less` | 模块化工程构建与全局主题样式定制 |
|
||||||
| 商家 | http://127.0.0.1:10002 |
|
|
||||||
| 管理端 | http://127.0.0.1:10003 |
|
---
|
||||||
|
|
||||||
|
## 4. 目录结构
|
||||||
|
|
||||||
|
```text
|
||||||
|
lilishop-ui
|
||||||
### 功能列表
|
├── buyer/ # 【PC 买家商城端】源码工程
|
||||||
|
│ ├── public/ # 静态资源与全局配置文件 (config.js)
|
||||||
|
│ └── src/
|
||||||
|
│ ├── api/ # 买家端接口定义(商品、购物车、订单、会员、促销等)
|
||||||
#### 平台功能
|
│ ├── components/ # 公共业务组件(楼层渲染、导航栏、商品卡片等)
|
||||||
|
│ ├── pages/ # PC 商城各业务页面(首页、商品详情、结算、个人中心等)
|
||||||

|
│ ├── router/ # 路由配置与守卫
|
||||||
|
│ ├── stores/ # Pinia 状态管理
|
||||||
|
│ └── utils/ # 请求封装与通用工具函数
|
||||||
|
├── seller/ # 【商家店铺管理端】源码工程
|
||||||
#### 商家端功能
|
│ ├── public/ # 静态资源与全局配置
|
||||||
|
│ └── src/
|
||||||

|
│ ├── api/ # 商家端接口定义
|
||||||
|
│ ├── components/ # 商家端公共组件与装修组件
|
||||||
|
│ ├── views/ # 商家端业务视图(商品管理、订单发货、售后、促销、店铺设置、统计等)
|
||||||
|
│ ├── router/ # 动态权限路由
|
||||||
|
│ └── stores/ # Pinia 状态管理
|
||||||
|
├── manager/ # 【平台运营管理端】源码工程
|
||||||
### 功能展示
|
│ ├── public/ # 静态资源与全局配置
|
||||||
|
│ └── src/
|
||||||
|
│ ├── api/ # 运营端接口定义
|
||||||
|
│ ├── components/ # 平台公共组件、富文本、可视化楼层装修编辑器
|
||||||
#### 移动端
|
│ ├── views/ # 运营端业务视图(会员、商品、订单、商家、营销、分销、财务、统计、系统设置)
|
||||||
|
│ ├── router/ # 菜单与权限路由
|
||||||
<img src="https://pickmall.cn/assets/imgs/other/app.gif" alt="管理端功能展示" style="zoom:50%;" />
|
│ └── stores/ # Pinia 状态管理
|
||||||
|
├── im/ # 【IM 在线客服 Web 端】源码工程
|
||||||
<img src="https://pickmall.cn/assets/imgs/other/app.gif" alt="移动端功能展示" style="zoom:50%;" />
|
│ └── src/
|
||||||
|
│ ├── api/ # 客服会话与消息接口
|
||||||
|
│ ├── components/ # 聊天窗口、消息列表、商品/订单卡片组件
|
||||||
|
│ ├── im-server/ # WebSocket / IM 连接服务管理
|
||||||
#### 管理端
|
│ └── views/ # 客服工作台页面
|
||||||
|
├── build.sh # 多端统一构建脚本
|
||||||

|
└── docker-build.sh # Docker 镜像构建脚本
|
||||||
|
|
||||||
|
|
||||||
### 技术选型
|
|
||||||
|
|
||||||
#### 架构图
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
##### Java后台
|
|
||||||
|
|
||||||
| 说明 | 框架 | 说明 | |
|
|
||||||
| -------------- | --------------- | -------------- | ------------- |
|
|
||||||
| 基础框架 | Spring Boot | MVC框架 | Spring MVC |
|
|
||||||
| 持久框架 | Mybatis-Plus | 程序构建 | Maven |
|
|
||||||
| 关系型数据库 | MySQL | 消息中间件AMQP | RocketMQ |
|
|
||||||
| 缓存 | Redis +MongoDB | 搜索引擎 | Elasticsearch |
|
|
||||||
| 安全框架 | Spring Security | 数据库连接池 | Druid |
|
|
||||||
| 数据库分库分表 | sharding | 定时任务 | xxl-job |
|
|
||||||
| 负载均衡 | Nginx | 静态资源 | 阿里云OSS |
|
|
||||||
| 短信 | 阿里云短信 | 认证 | JWT |
|
|
||||||
| 日志处理 | Log4j | 接口规范 | RESTful |
|
|
||||||
|
|
||||||
##### 前端-运营后台、店铺后台
|
|
||||||
|
|
||||||
| 说明 | 框架 | 说明 | 框架 |
|
|
||||||
| ---------- | ---------- | ---------- | ------- |
|
|
||||||
| 构建工具 | webpack | JS版本 | ES6 |
|
|
||||||
| 基础JS框架 | Vue.js | 视频播放器 | Dplayer |
|
|
||||||
| 路由管理 | Vue Router | 状态管理 | Vuex |
|
|
||||||
| 基础UI库 | iView | UI界面基于 | iView |
|
|
||||||
| 网络请求 | axios | | |
|
|
||||||
|
|
||||||
##### 前端-移动端
|
|
||||||
|
|
||||||
| 说明 | 架构 | 说明 | 架构 |
|
|
||||||
| --------- | ------- | -------- | ------- |
|
|
||||||
| 基础UI库 | uViewui | 基础框架 | uni-app |
|
|
||||||
| CSS预处理 | scss | 地图引擎 | amap |
|
|
||||||
|
|
||||||
### 升级计划
|
|
||||||
|
|
||||||
#### 计划每个月发布一个版本,具体时间可能有出入
|
|
||||||
|
|
||||||
时间:2021年6月15日
|
|
||||||
|
|
||||||
```
|
|
||||||
新增功能:
|
|
||||||
1.微信小程序直播
|
|
||||||
2.优惠券活动
|
|
||||||
3.新人赠券
|
|
||||||
4.准确发券
|
|
||||||
5.用户等级
|
|
||||||
6.数据导出
|
|
||||||
7.订单批量
|
|
||||||
8.APP版本升级检测
|
|
||||||
9.积分商城
|
|
||||||
|
|
||||||
功能优化:
|
|
||||||
1.优惠券有效期增加类型:设置领取后*内有效。
|
|
||||||
2.秒杀活动设置为每天开启,需设置秒杀活动开启时间。
|
|
||||||
3.店铺配送模板,配送地区如果选择省份则下方的市级地址不展示。
|
|
||||||
4.店铺配送模板支持,店铺包邮。
|
|
||||||
5.普通商品设置去除卖家承担运费。
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
时间:2021年7月15日
|
---
|
||||||
|
|
||||||
```
|
## 5. 配套源码仓库
|
||||||
新增功能:
|
|
||||||
1.会员权益
|
|
||||||
2.支持用户升级会员
|
|
||||||
3.供求单
|
|
||||||
4.IM:腾讯云智服
|
|
||||||
5.服务商品
|
|
||||||
6.店铺支持订单核销
|
|
||||||
7.店铺自提点
|
|
||||||
功能优化:
|
|
||||||
1.用户分享商城、关注店铺、邀请新用户可获取积分、经验值。
|
|
||||||
```
|
|
||||||
|
|
||||||
时间:2021年8月16日
|
本仓库专注于 **PC / 商家端 / 运营端 / IM Web**(`lilishop-ui`)。完整系统由以下四个核心仓库组成:
|
||||||
|
|
||||||
```
|
| 仓库名称 | 职责说明 | 仓库地址 |
|
||||||
新增功能:
|
| :--- | :--- | :--- |
|
||||||
1.微淘功能
|
| **`lilishop`** | 后端服务源码(Spring Boot 4 / Java 21) | [Gitee](https://gitee.com/beijing_hongye_huicheng/lilishop) · [GitHub](https://github.com/lilishop/lilishop) |
|
||||||
2.店铺移动端
|
| **`lilishop-ui`** | PC 商城 / 商家端 / 运营管理端 / IM Web 前端 | [Gitee](https://gitee.com/beijing_hongye_huicheng/lilishop-ui) |
|
||||||
3.店铺发货单
|
| **`lilishop-uniapp`** | 买家端 H5 / 微信小程序 / Android & iOS APP | [Gitee](https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp) |
|
||||||
```
|
| **`docker`** | 容器化部署编排、镜像与数据库脚本 | [Gitee](https://gitee.com/beijing_hongye_huicheng/docker) · [MySQL 脚本](https://gitee.com/beijing_hongye_huicheng/docker/tree/master/init/mysql) |
|
||||||
|
|
||||||
时间:2021年9月15日
|
---
|
||||||
|
|
||||||
```
|
## 6. 开源与授权
|
||||||
新增功能:
|
|
||||||
增加供应商功能
|
|
||||||
```
|
|
||||||
|
|
||||||
### 版本升级
|
本项目遵循 [MIT](./LICENSE) 开源协议,版权归 **北京宏业汇成科技有限公司** 所有。允许个人及企业免费用于学习、研究、修改和商业用途(需保留原始版权和许可声明)。
|
||||||
|
|
||||||
```
|
---
|
||||||
后续会持续版本升级,修复bug,完善功能,覆盖更多业务场景 o2o/b2b/s2b2b2c/跨境电商
|
|
||||||
|
|
||||||
后续会考虑推出微服务/中台等 企业级版本
|
## 7. 社区与支持
|
||||||
```
|
|
||||||
|
|
||||||
### 技术亮点
|
我们欢迎任何形式的交流与贡献。在提问前,请先查阅 [产品文档](https://bdwx2tfwwt.feishu.cn/wiki/space/7675179368632617952?ccm_open_type=lark_wiki_spaceLink&open_tab_from=wiki_home),并参考 [《提问的智慧》](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/master/README-zh_CN.md) 以便高效沟通。
|
||||||
|
|
||||||
|
- **[在线客服](https://work.weixin.qq.com/kfid/kfc4d8dc24a73c15f44)**
|
||||||
|
- **微信交流群**:
|
||||||
|
<img src="https://lilishop-wechat.oss-cn-beijing.aliyuncs.com/wechat.jpg" width="200" alt="微信群" />
|
||||||
|
|
||||||
1.后端框架基于Springboot,构建基于maven,持久层使用MyBatisPlus。使用elasticsearch、redis、mongodb、rocketmq 等各种中间健。都是主流架构,轻松应对各种环境。
|
---
|
||||||
|
|
||||||
2.支持集群、分布式,支持docker 轻松部署,解决各种复杂场景!
|
## 8. 升级计划
|
||||||
|
|
||||||
3.代码模块清晰,主要分为三端api(买家、卖家、管理),各端API互相隔离,自己鉴权,自己操作业务。
|
### ✅ 已完成特性
|
||||||
|
| 功能模块 | 功能模块 |
|
||||||
4.使用阿里开源的RocketMQ,基于mq解决各种并发场景,解决事务一致性,解决搞并发延迟场景问题。
|
| :--- | :--- |
|
||||||
|
| ✅ 商品定时上下架 | ✅ 商品分组 / 会员分组 |
|
||||||
5.项目使用多级缓存,应用不同场景,redis缓存业务数据、mongodb缓存关系型多对多关系问题、nginx缓存高频访问低频修改的页面。
|
| ✅ 商品虚拟销量 | ✅ 专用发票(发票上传) |
|
||||||
|
| ✅ 置顶评论 | ✅ 客户等级体系 |
|
||||||
6.支持各种联合登陆,支持各种客户端的支付问题,灵活配置灵活开启。
|
| ✅ 购物卡 | ✅ 腾讯云-云直播 |
|
||||||
|
| ✅ 卡密商品 | ✅ 二级分销 |
|
||||||
7.内置完善的楼层装修机制,各种拖拉拽,维护跳转页面或外网,即便是一个什么都不懂的运营也可以轻松掌握。
|
| ✅ 定时任务管理 | ✅ 预约服务商品 |
|
||||||
|
| ✅ 主题色管理 | ✅ 商家发货改造(整单/拆单/无需配送) |
|
||||||
8.内置阿里短信接口,可以在线申请短信模版。内置阿里oss系统,可以对文件执行各种操作。oss商家端资源相互隔离。
|
| ✅ 多维统计(营业/商品/会员/积分/储值/营销/分销) | ✅ 经营报表(店铺业绩/商品同比环比/订单明细/销售汇总) |
|
||||||
|
|
||||||
10.强大的统计报表,统计效果,可以实现各个场景,包含在线人数,历史在线人数,活跃人数等信息。
|
|
||||||
|
|
||||||
11.标准Api接口、提供swagger文档,快速二开。
|
|
||||||
|
|
||||||
12.分布式调度任务中心,解决分布式定时任务多次执行问题。
|
|
||||||
|
|
||||||
13.代码注释完善,快速上手。
|
|
||||||
|
|
||||||
14.非移动端采用IView框架,各种自定义插件、选择器实现。移动端采用uniapp,一次编写,全端使用
|
|
||||||
|
|
||||||
15.已经对接好各种第三方插件,支持各种复杂等联合登陆,联合支付等场景。
|
|
||||||
|
|
||||||
|
|
||||||
### 开源须知
|
|
||||||
1.仅允许用于个人学习研究使用.
|
|
||||||
|
|
||||||
2.禁止将本开源的代码和资源进行任何形式任何名义的出售.
|
|
||||||
|
|
||||||
3.限制商用,如果需要商业使用请联系我们。QQ3409056806.
|
|
||||||
|
|
||||||
### 交流群
|
|
||||||
|
|
||||||
**QQ群**:961316482
|
|
||||||
|
|
||||||
|
### 🔜 近期规划中
|
||||||
|
- 🔜 店铺结算汇总 & 结算台账
|
||||||
|
- 🔜 支付方式汇总 & 钱包流水 & 财务汇总
|
||||||
|
- 🔜 微信小店对接
|
||||||
|
- 🔜 抖店对接
|
||||||
|
|||||||
19
build.sh
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#代码目录
|
||||||
|
code_path=$PWD
|
||||||
|
|
||||||
|
git pull
|
||||||
|
|
||||||
|
cd ${code_path}/manager
|
||||||
|
rm -rf ./dist
|
||||||
|
yarn install
|
||||||
|
yarn build
|
||||||
|
|
||||||
|
cd ${code_path}/seller
|
||||||
|
rm -rf ./dist
|
||||||
|
yarn install
|
||||||
|
yarn build
|
||||||
|
|
||||||
|
cd ${code_path}/buyer
|
||||||
|
rm -rf ./dist
|
||||||
|
yarn install
|
||||||
|
yarn build
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"presets": [
|
|
||||||
["env", {
|
|
||||||
"modules": false,
|
|
||||||
"targets": {
|
|
||||||
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
|
|
||||||
}
|
|
||||||
}],
|
|
||||||
"stage-2"
|
|
||||||
],
|
|
||||||
"plugins": ["transform-vue-jsx", "transform-runtime"]
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
/build/
|
|
||||||
/config/
|
|
||||||
/dist/
|
|
||||||
/*.js
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
// https://eslint.org/docs/user-guide/configuring
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
root: true,
|
|
||||||
parserOptions: {
|
|
||||||
parser: 'babel-eslint'
|
|
||||||
},
|
|
||||||
env: {
|
|
||||||
browser: true,
|
|
||||||
},
|
|
||||||
extends: [
|
|
||||||
// https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
|
|
||||||
// consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
|
|
||||||
'plugin:vue/essential',
|
|
||||||
// https://github.com/standard/standard/blob/master/docs/RULES-en.md
|
|
||||||
'standard'
|
|
||||||
],
|
|
||||||
// required to lint *.vue files
|
|
||||||
plugins: [
|
|
||||||
'vue'
|
|
||||||
],
|
|
||||||
// add your custom rules here
|
|
||||||
rules: {
|
|
||||||
"semi": [0, "never"],
|
|
||||||
// allow async-await
|
|
||||||
'generator-star-spacing': 'off',
|
|
||||||
// allow debugger during development
|
|
||||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
|
||||||
"vue/no-parsing-error": [2, {
|
|
||||||
"x-invalid-end-tag": false
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
1
buyer/.gitignore
vendored
@@ -12,4 +12,3 @@ yarn-error.log*
|
|||||||
*.ntvs*
|
*.ntvs*
|
||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
package-lock.json
|
|
||||||
|
|||||||
1
buyer/.npmrc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
engine-strict=false
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
// https://github.com/michael-ciniawsky/postcss-load-config
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
"plugins": {
|
|
||||||
"postcss-import": {},
|
|
||||||
"postcss-url": {},
|
|
||||||
// to target browsers: use "browserslist" field in package.json
|
|
||||||
"autoprefixer": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
1
buyer/.yarnrc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
--ignore-engines true
|
||||||
@@ -1,8 +1,13 @@
|
|||||||
FROM nginx:alpine
|
FROM node:10.19.0 as build-stage
|
||||||
|
WORKDIR /app
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm install
|
||||||
|
COPY . .
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
RUN mkdir -p /app/
|
# production stage
|
||||||
COPY ./dist /app/
|
FROM nginx:stable-alpine as production-stage
|
||||||
|
COPY --from=build-stage /app/dist /usr/share/nginx/html
|
||||||
COPY ./nginx.conf /etc/nginx/nginx.conf
|
COPY ./nginx.conf /etc/nginx/nginx.conf
|
||||||
|
|
||||||
|
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
CMD ["nginx", "-g", "daemon off;"]k
|
||||||
|
|||||||
55
buyer/MIGRATION-VUE3.md
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
# Buyer 买家端 Vue 3 迁移说明
|
||||||
|
|
||||||
|
## 技术栈
|
||||||
|
|
||||||
|
- Vue 3 + Vue Router 4 + Pinia(vuex 已移除,见下文"组合式 API 迁移")
|
||||||
|
- Element Plus(替代 view-design / iView)
|
||||||
|
- 保留 `$Message` / `$Modal` / `$Notice` 兼容层(`src/utils/message.js`)
|
||||||
|
|
||||||
|
## 启动
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd buyer
|
||||||
|
yarn install
|
||||||
|
yarn dev # 默认端口 10000
|
||||||
|
yarn build
|
||||||
|
```
|
||||||
|
|
||||||
|
## 迁移要点
|
||||||
|
|
||||||
|
1. **入口** `src/main.js` 使用 `createApp`,全局过滤器改为 `$filters`
|
||||||
|
2. **路由** `src/router/index.js` 使用 `createRouter` + 动态 `import()`
|
||||||
|
3. **请求** `src/plugins/request.js` 使用 Element Plus `ElLoading`
|
||||||
|
4. **iView 组件已全部替换**:轮播 `el-carousel`、下拉 `el-dropdown`、侧栏 `el-menu`、头像 `el-avatar` 等
|
||||||
|
5. **图标映射** `src/utils/iconMap.js` — 动态图标(如侧边栏菜单)通过 `resolveIcon()` 使用
|
||||||
|
6. **自定义字体图标** `icomoon` 保留为 `<i class="icomoon icon-*">`(购物车步骤条、钱包等)
|
||||||
|
7. **首页装修** `indexDecorate/modelList` 保留买家端展示逻辑(非 manager 编辑版)
|
||||||
|
8. **特殊替换**
|
||||||
|
- `vue-piczoom` → `el-image` 预览
|
||||||
|
- `mv-count-down` → 内置倒计时
|
||||||
|
- 秒杀轮播 → 横向滚动列表
|
||||||
|
|
||||||
|
## 组合式 API 迁移(2026-10 完成)
|
||||||
|
|
||||||
|
全部 95 个 `.vue` 组件已从 Options API 转换为 `<script setup>`,同时完成 vuex → pinia:
|
||||||
|
|
||||||
|
- **状态管理**:`src/stores/app.js`(`useAppStore`:navList / cartNum / unreadMsg / logoImg / siteName / hotWordsList / category + 对应 setXxx actions)。原 `src/vuex/` 已删除,package.json 不再依赖 vuex。
|
||||||
|
- **路由守卫**:`beforeRouteEnter` 无组合式等价物,5 个页面(`GoodsList` / `GoodsDetail` / `PointGoodsDetail` / `Cart` / `ShoppingCart`)保留普通 `<script>` 块存放 `export default { name, beforeRouteEnter }`——这是官方支持的合并写法,统计 Options API 残留时需排除。
|
||||||
|
- **defineExpose**:以下组件的方法/状态被父组件通过模板 ref 调用,已显式暴露:`verify`(init / close)、`multiple-map`(open)、`addressManage`(show / hide)、`invoiceModal`(invoiceAvailable)。新增此类父子调用时必须加 `defineExpose`。
|
||||||
|
- **模板 ref 与响应式变量同名会互相覆盖**:同名时模板 ref 统一改名 `xxxRef`(如 `formRef` / `verifyRef`)。
|
||||||
|
- **mixin 已消除**:原 `components/mixes/talkIm.vue` 的 IM 客服逻辑已内联进 `Merchant.vue` 和 `goodsDetail/StoreSide.vue`,文件已删除。
|
||||||
|
- **全局属性照旧**:模板中的 `$filters.*` / `linkTo` / `connectCs` / `$inputMaxLength` 是 `main.js` 注册的全局属性,`<script setup>` 下模板可直接使用;script 内使用 `$filters` 函数需从 `@/plugins/filters.js` 具名导入,`this.Cookies` 等同 `storage`(`@/plugins/storage`)。
|
||||||
|
- **其余三端(seller / manager / im)仍为 Options API + vuex**,迁移时参照本端模式。
|
||||||
|
|
||||||
|
## 批量脚本
|
||||||
|
|
||||||
|
- `scripts/migrate-iview-to-element.js` — iView → Element 模板替换
|
||||||
|
- `scripts/fix-filters.js` — Vue 2 过滤器语法修复
|
||||||
|
- `scripts/replace-page.js` — `<Page>` → `el-pagination`
|
||||||
|
- `scripts/replace-icon.js` — 静态 `<Icon type>` → `el-icon`
|
||||||
|
- `scripts/fix-el-icon-click.js` — 修复 `@click` 绑定
|
||||||
|
- `scripts/fix-broken-tags.js` — 闭合标签修复
|
||||||
|
|
||||||
|
## 上线前检查
|
||||||
|
|
||||||
|
四端统一清单(认证、axios、Element Plus、分端专项):[../MIGRATION-VUE3.md](../MIGRATION-VUE3.md)
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
### 全局css src/assets/styles
|
|
||||||
|
|
||||||
### 工具类 src/plugins
|
|
||||||
|
|
||||||
### 顶部广告页 src/components/advertising
|
|
||||||
|
|
||||||
### 全部商品分类 components/nav
|
|
||||||
|
|
||||||
### 底部导航栏 components/footer
|
|
||||||
|
|
||||||
### 发票模态框 components/invoiceModal
|
|
||||||
|
|
||||||
### 商品详情 pages/GoodsDetail.vue
|
|
||||||
|
|
||||||
#### 商品详情组件 components/goodsDetail
|
|
||||||
|
|
||||||
### 全部商品分类 pages/AllCategories.vue
|
|
||||||
|
|
||||||
### 意见反馈 pages/Feedback.vue
|
|
||||||
|
|
||||||
### 卡片的封装 components/card
|
|
||||||
|
|
||||||
### 购物车 pages/Cart.vue
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
5
buyer/babel.config.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
module.exports = {
|
||||||
|
presets: [
|
||||||
|
'@vue/cli-plugin-babel/preset'
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
require('./check-versions')()
|
|
||||||
|
|
||||||
process.env.NODE_ENV = 'production'
|
|
||||||
|
|
||||||
const ora = require('ora')
|
|
||||||
const rm = require('rimraf')
|
|
||||||
const path = require('path')
|
|
||||||
const chalk = require('chalk')
|
|
||||||
const webpack = require('webpack')
|
|
||||||
const config = require('../config')
|
|
||||||
const webpackConfig = require('./webpack.prod.conf')
|
|
||||||
|
|
||||||
const spinner = ora('building for production...')
|
|
||||||
spinner.start()
|
|
||||||
|
|
||||||
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
|
|
||||||
if (err) throw err
|
|
||||||
webpack(webpackConfig, (err, stats) => {
|
|
||||||
spinner.stop()
|
|
||||||
if (err) throw err
|
|
||||||
process.stdout.write(stats.toString({
|
|
||||||
colors: true,
|
|
||||||
modules: false,
|
|
||||||
children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
|
|
||||||
chunks: false,
|
|
||||||
chunkModules: false
|
|
||||||
}) + '\n\n')
|
|
||||||
|
|
||||||
if (stats.hasErrors()) {
|
|
||||||
console.log(chalk.red(' Build failed with errors.\n'))
|
|
||||||
process.exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(chalk.cyan(' Build complete.\n'))
|
|
||||||
console.log(chalk.yellow(
|
|
||||||
' Tip: built files are meant to be served over an HTTP server.\n' +
|
|
||||||
' Opening index.html over file:// won\'t work.\n'
|
|
||||||
))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
const chalk = require('chalk')
|
|
||||||
const semver = require('semver')
|
|
||||||
const packageConfig = require('../package.json')
|
|
||||||
const shell = require('shelljs')
|
|
||||||
|
|
||||||
function exec (cmd) {
|
|
||||||
return require('child_process').execSync(cmd).toString().trim()
|
|
||||||
}
|
|
||||||
|
|
||||||
const versionRequirements = [
|
|
||||||
{
|
|
||||||
name: 'node',
|
|
||||||
currentVersion: semver.clean(process.version),
|
|
||||||
versionRequirement: packageConfig.engines.node
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
if (shell.which('npm')) {
|
|
||||||
versionRequirements.push({
|
|
||||||
name: 'npm',
|
|
||||||
currentVersion: exec('npm --version'),
|
|
||||||
versionRequirement: packageConfig.engines.npm
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = function () {
|
|
||||||
const warnings = []
|
|
||||||
|
|
||||||
for (let i = 0; i < versionRequirements.length; i++) {
|
|
||||||
const mod = versionRequirements[i]
|
|
||||||
|
|
||||||
if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
|
|
||||||
warnings.push(mod.name + ': ' +
|
|
||||||
chalk.red(mod.currentVersion) + ' should be ' +
|
|
||||||
chalk.green(mod.versionRequirement)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (warnings.length) {
|
|
||||||
console.log('')
|
|
||||||
console.log(chalk.yellow('To use this template, you must update following to modules:'))
|
|
||||||
console.log()
|
|
||||||
|
|
||||||
for (let i = 0; i < warnings.length; i++) {
|
|
||||||
const warning = warnings[i]
|
|
||||||
console.log(' ' + warning)
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log()
|
|
||||||
process.exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
const path = require('path')
|
|
||||||
const config = require('../config')
|
|
||||||
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
|
||||||
const packageConfig = require('../package.json')
|
|
||||||
|
|
||||||
exports.assetsPath = function (_path) {
|
|
||||||
const assetsSubDirectory = process.env.NODE_ENV === 'production'
|
|
||||||
? config.build.assetsSubDirectory
|
|
||||||
: config.dev.assetsSubDirectory
|
|
||||||
|
|
||||||
return path.posix.join(assetsSubDirectory, _path)
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.cssLoaders = function (options) {
|
|
||||||
options = options || {}
|
|
||||||
|
|
||||||
const cssLoader = {
|
|
||||||
loader: 'css-loader',
|
|
||||||
options: {
|
|
||||||
sourceMap: options.sourceMap
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const postcssLoader = {
|
|
||||||
loader: 'postcss-loader',
|
|
||||||
options: {
|
|
||||||
sourceMap: options.sourceMap
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate loader string to be used with extract text plugin
|
|
||||||
function generateLoaders (loader, loaderOptions) {
|
|
||||||
const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
|
|
||||||
|
|
||||||
if (loader) {
|
|
||||||
loaders.push({
|
|
||||||
loader: loader + '-loader',
|
|
||||||
options: Object.assign({}, loaderOptions, {
|
|
||||||
sourceMap: options.sourceMap
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract CSS when that option is specified
|
|
||||||
// (which is the case during production build)
|
|
||||||
if (options.extract) {
|
|
||||||
return ExtractTextPlugin.extract({
|
|
||||||
use: loaders,
|
|
||||||
fallback: 'vue-style-loader',
|
|
||||||
publicPath: '../../'
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
return ['vue-style-loader'].concat(loaders)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
|
|
||||||
return {
|
|
||||||
css: generateLoaders(),
|
|
||||||
postcss: generateLoaders(),
|
|
||||||
less: generateLoaders('less' , { javascriptEnabled : true }),
|
|
||||||
sass: generateLoaders('sass', { indentedSyntax: true }),
|
|
||||||
scss: generateLoaders('sass').concat(
|
|
||||||
{
|
|
||||||
loader: 'sass-resources-loader',
|
|
||||||
options: {
|
|
||||||
//你自己的scss全局文件的路径
|
|
||||||
resources: path.resolve(__dirname, '../src/assets/styles/global.scss')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
),
|
|
||||||
stylus: generateLoaders('stylus'),
|
|
||||||
styl: generateLoaders('stylus')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate loaders for standalone style files (outside of .vue)
|
|
||||||
exports.styleLoaders = function (options) {
|
|
||||||
const output = []
|
|
||||||
const loaders = exports.cssLoaders(options)
|
|
||||||
|
|
||||||
for (const extension in loaders) {
|
|
||||||
const loader = loaders[extension]
|
|
||||||
output.push({
|
|
||||||
test: new RegExp('\\.' + extension + '$'),
|
|
||||||
use: loader
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return output
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.createNotifierCallback = () => {
|
|
||||||
const notifier = require('node-notifier')
|
|
||||||
|
|
||||||
return (severity, errors) => {
|
|
||||||
if (severity !== 'error') return
|
|
||||||
|
|
||||||
const error = errors[0]
|
|
||||||
const filename = error.file && error.file.split('!').pop()
|
|
||||||
|
|
||||||
notifier.notify({
|
|
||||||
title: packageConfig.name,
|
|
||||||
message: severity + ': ' + error.name,
|
|
||||||
subtitle: filename || '',
|
|
||||||
icon: path.join(__dirname, 'logo.png')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
const utils = require('./utils')
|
|
||||||
const config = require('../config')
|
|
||||||
const isProduction = process.env.NODE_ENV === 'production'
|
|
||||||
const sourceMapEnabled = isProduction
|
|
||||||
? config.build.productionSourceMap
|
|
||||||
: config.dev.cssSourceMap
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
loaders: utils.cssLoaders({
|
|
||||||
sourceMap: sourceMapEnabled,
|
|
||||||
extract: isProduction
|
|
||||||
}),
|
|
||||||
cssSourceMap: sourceMapEnabled,
|
|
||||||
cacheBusting: config.dev.cacheBusting,
|
|
||||||
transformToRequire: {
|
|
||||||
video: ['src', 'poster'],
|
|
||||||
source: 'src',
|
|
||||||
img: 'src',
|
|
||||||
image: 'xlink:href'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
const path = require('path')
|
|
||||||
const utils = require('./utils')
|
|
||||||
const config = require('../config')
|
|
||||||
const vueLoaderConfig = require('./vue-loader.conf')
|
|
||||||
|
|
||||||
function resolve (dir) {
|
|
||||||
return path.join(__dirname, '..', dir)
|
|
||||||
}
|
|
||||||
|
|
||||||
const createLintingRule = () => ({
|
|
||||||
test: /\.(js|vue)$/,
|
|
||||||
loader: 'eslint-loader',
|
|
||||||
enforce: 'pre',
|
|
||||||
include: [resolve('src'), resolve('test')],
|
|
||||||
options: {
|
|
||||||
formatter: require('eslint-friendly-formatter'),
|
|
||||||
emitWarning: !config.dev.showEslintErrorsInOverlay
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
context: path.resolve(__dirname, '../'),
|
|
||||||
entry: {
|
|
||||||
app: './src/main.js'
|
|
||||||
},
|
|
||||||
output: {
|
|
||||||
path: config.build.assetsRoot,
|
|
||||||
filename: '[name].js',
|
|
||||||
publicPath: process.env.NODE_ENV === 'production'
|
|
||||||
? config.build.assetsPublicPath
|
|
||||||
: config.dev.assetsPublicPath
|
|
||||||
},
|
|
||||||
resolve: {
|
|
||||||
extensions: ['.js', '.vue', '.json'],
|
|
||||||
alias: {
|
|
||||||
'vue$': 'vue/dist/vue.esm.js',
|
|
||||||
'@': resolve('src'),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
module: {
|
|
||||||
rules: [
|
|
||||||
// ...(config.dev.useEslint ? [createLintingRule()] : []),
|
|
||||||
{
|
|
||||||
test: /\.vue$/,
|
|
||||||
loader: 'vue-loader',
|
|
||||||
options: vueLoaderConfig
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.scss$/,
|
|
||||||
loaders: ['style', 'css', 'sass']
|
|
||||||
},
|
|
||||||
// {
|
|
||||||
|
|
||||||
// test: /\.less$/,
|
|
||||||
|
|
||||||
// loader: "style-loader!css-loader!less-loader",
|
|
||||||
|
|
||||||
// },
|
|
||||||
{
|
|
||||||
test: /\.js$/,
|
|
||||||
loader: 'babel-loader',
|
|
||||||
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
|
|
||||||
loader: 'url-loader',
|
|
||||||
options: {
|
|
||||||
limit: 10000,
|
|
||||||
name: utils.assetsPath('img/[name].[hash:7].[ext]')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
|
|
||||||
loader: 'url-loader',
|
|
||||||
options: {
|
|
||||||
limit: 10000,
|
|
||||||
name: utils.assetsPath('media/[name].[hash:7].[ext]')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
|
||||||
loader: 'url-loader',
|
|
||||||
options: {
|
|
||||||
limit: 10000,
|
|
||||||
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.(cur)(\?.*)?$/,
|
|
||||||
loader: 'url-loader',
|
|
||||||
options: {
|
|
||||||
limit: 10000,
|
|
||||||
name: utils.assetsPath('cur/[name].[hash:7].[ext]')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
node: {
|
|
||||||
// prevent webpack from injecting useless setImmediate polyfill because Vue
|
|
||||||
// source contains it (although only uses it if it's native).
|
|
||||||
setImmediate: false,
|
|
||||||
// prevent webpack from injecting mocks to Node native modules
|
|
||||||
// that does not make sense for the client
|
|
||||||
dgram: 'empty',
|
|
||||||
fs: 'empty',
|
|
||||||
net: 'empty',
|
|
||||||
tls: 'empty',
|
|
||||||
child_process: 'empty'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
const utils = require('./utils')
|
|
||||||
const webpack = require('webpack')
|
|
||||||
const config = require('../config')
|
|
||||||
const merge = require('webpack-merge')
|
|
||||||
const path = require('path')
|
|
||||||
const baseWebpackConfig = require('./webpack.base.conf')
|
|
||||||
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
|
||||||
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
|
||||||
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
|
|
||||||
const portfinder = require('portfinder')
|
|
||||||
|
|
||||||
const HOST = process.env.HOST
|
|
||||||
const PORT = process.env.PORT && Number(process.env.PORT)
|
|
||||||
|
|
||||||
const devWebpackConfig = merge(baseWebpackConfig, {
|
|
||||||
module: {
|
|
||||||
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
|
|
||||||
},
|
|
||||||
// cheap-module-eval-source-map is faster for development
|
|
||||||
devtool: config.dev.devtool,
|
|
||||||
|
|
||||||
// these devServer options should be customized in /config/index.js
|
|
||||||
devServer: {
|
|
||||||
clientLogLevel: 'warning',
|
|
||||||
historyApiFallback: {
|
|
||||||
rewrites: [
|
|
||||||
{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
hot: true,
|
|
||||||
contentBase: false, // since we use CopyWebpackPlugin.
|
|
||||||
compress: true,
|
|
||||||
host: HOST || config.dev.host,
|
|
||||||
port: PORT || config.dev.port,
|
|
||||||
open: config.dev.autoOpenBrowser,
|
|
||||||
overlay: config.dev.errorOverlay
|
|
||||||
? { warnings: false, errors: true }
|
|
||||||
: false,
|
|
||||||
publicPath: config.dev.assetsPublicPath,
|
|
||||||
proxy: config.dev.proxyTable,
|
|
||||||
quiet: true, // necessary for FriendlyErrorsPlugin
|
|
||||||
watchOptions: {
|
|
||||||
poll: config.dev.poll,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
plugins: [
|
|
||||||
new webpack.DefinePlugin({
|
|
||||||
'process.env': require('../config/dev.env')
|
|
||||||
}),
|
|
||||||
new webpack.HotModuleReplacementPlugin(),
|
|
||||||
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
|
|
||||||
new webpack.NoEmitOnErrorsPlugin(),
|
|
||||||
// https://github.com/ampedandwired/html-webpack-plugin
|
|
||||||
new HtmlWebpackPlugin({
|
|
||||||
filename: 'index.html',
|
|
||||||
template: 'index.html',
|
|
||||||
inject: true
|
|
||||||
}),
|
|
||||||
// copy custom static assets
|
|
||||||
new CopyWebpackPlugin([
|
|
||||||
{
|
|
||||||
from: path.resolve(__dirname, '../static'),
|
|
||||||
to: config.dev.assetsSubDirectory,
|
|
||||||
ignore: ['.*']
|
|
||||||
}
|
|
||||||
])
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
module.exports = new Promise((resolve, reject) => {
|
|
||||||
portfinder.basePort = process.env.PORT || config.dev.port
|
|
||||||
portfinder.getPort((err, port) => {
|
|
||||||
if (err) {
|
|
||||||
reject(err)
|
|
||||||
} else {
|
|
||||||
// publish the new Port, necessary for e2e tests
|
|
||||||
process.env.PORT = port
|
|
||||||
// add port to devServer config
|
|
||||||
devWebpackConfig.devServer.port = port
|
|
||||||
|
|
||||||
// Add FriendlyErrorsPlugin
|
|
||||||
devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
|
|
||||||
compilationSuccessInfo: {
|
|
||||||
messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
|
|
||||||
},
|
|
||||||
onErrors: config.dev.notifyOnErrors
|
|
||||||
? utils.createNotifierCallback()
|
|
||||||
: undefined
|
|
||||||
}))
|
|
||||||
|
|
||||||
resolve(devWebpackConfig)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,145 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
const path = require('path')
|
|
||||||
const utils = require('./utils')
|
|
||||||
const webpack = require('webpack')
|
|
||||||
const config = require('../config')
|
|
||||||
const merge = require('webpack-merge')
|
|
||||||
const baseWebpackConfig = require('./webpack.base.conf')
|
|
||||||
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
|
||||||
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
|
||||||
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
|
||||||
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
|
|
||||||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
|
|
||||||
|
|
||||||
const env = require('../config/prod.env')
|
|
||||||
|
|
||||||
const webpackConfig = merge(baseWebpackConfig, {
|
|
||||||
module: {
|
|
||||||
rules: utils.styleLoaders({
|
|
||||||
sourceMap: config.build.productionSourceMap,
|
|
||||||
extract: false,
|
|
||||||
usePostCSS: true
|
|
||||||
})
|
|
||||||
},
|
|
||||||
devtool: config.build.productionSourceMap ? config.build.devtool : false,
|
|
||||||
output: {
|
|
||||||
path: config.build.assetsRoot,
|
|
||||||
filename: utils.assetsPath('js/[name].[chunkhash].js'),
|
|
||||||
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
|
|
||||||
},
|
|
||||||
plugins: [
|
|
||||||
// http://vuejs.github.io/vue-loader/en/workflow/production.html
|
|
||||||
new webpack.DefinePlugin({
|
|
||||||
'process.env': env
|
|
||||||
}),
|
|
||||||
new UglifyJsPlugin({
|
|
||||||
uglifyOptions: {
|
|
||||||
compress: {
|
|
||||||
warnings: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
sourceMap: config.build.productionSourceMap,
|
|
||||||
parallel: true
|
|
||||||
}),
|
|
||||||
// extract css into its own file
|
|
||||||
new ExtractTextPlugin({
|
|
||||||
filename: utils.assetsPath('css/[name].[contenthash].css'),
|
|
||||||
// Setting the following option to `false` will not extract CSS from codesplit chunks.
|
|
||||||
// Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
|
|
||||||
// It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
|
|
||||||
// increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
|
|
||||||
allChunks: true,
|
|
||||||
}),
|
|
||||||
// Compress extracted CSS. We are using this plugin so that possible
|
|
||||||
// duplicated CSS from different components can be deduped.
|
|
||||||
new OptimizeCSSPlugin({
|
|
||||||
cssProcessorOptions: config.build.productionSourceMap
|
|
||||||
? { safe: true, map: { inline: false } }
|
|
||||||
: { safe: true }
|
|
||||||
}),
|
|
||||||
// generate dist index.html with correct asset hash for caching.
|
|
||||||
// you can customize output by editing /index.html
|
|
||||||
// see https://github.com/ampedandwired/html-webpack-plugin
|
|
||||||
new HtmlWebpackPlugin({
|
|
||||||
filename: config.build.index,
|
|
||||||
template: 'index.html',
|
|
||||||
inject: true,
|
|
||||||
minify: {
|
|
||||||
removeComments: true,
|
|
||||||
collapseWhitespace: true,
|
|
||||||
removeAttributeQuotes: true
|
|
||||||
// more options:
|
|
||||||
// https://github.com/kangax/html-minifier#options-quick-reference
|
|
||||||
},
|
|
||||||
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
|
|
||||||
chunksSortMode: 'dependency'
|
|
||||||
}),
|
|
||||||
// keep module.id stable when vendor modules does not change
|
|
||||||
new webpack.HashedModuleIdsPlugin(),
|
|
||||||
// enable scope hoisting
|
|
||||||
new webpack.optimize.ModuleConcatenationPlugin(),
|
|
||||||
// split vendor js into its own file
|
|
||||||
new webpack.optimize.CommonsChunkPlugin({
|
|
||||||
name: 'vendor',
|
|
||||||
minChunks (module) {
|
|
||||||
// any required modules inside node_modules are extracted to vendor
|
|
||||||
return (
|
|
||||||
module.resource &&
|
|
||||||
/\.js$/.test(module.resource) &&
|
|
||||||
module.resource.indexOf(
|
|
||||||
path.join(__dirname, '../node_modules')
|
|
||||||
) === 0
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
// extract webpack runtime and module manifest to its own file in order to
|
|
||||||
// prevent vendor hash from being updated whenever app bundle is updated
|
|
||||||
new webpack.optimize.CommonsChunkPlugin({
|
|
||||||
name: 'manifest',
|
|
||||||
minChunks: Infinity
|
|
||||||
}),
|
|
||||||
// This instance extracts shared chunks from code splitted chunks and bundles them
|
|
||||||
// in a separate chunk, similar to the vendor chunk
|
|
||||||
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
|
|
||||||
new webpack.optimize.CommonsChunkPlugin({
|
|
||||||
name: 'app',
|
|
||||||
async: 'vendor-async',
|
|
||||||
children: true,
|
|
||||||
minChunks: 3
|
|
||||||
}),
|
|
||||||
|
|
||||||
// copy custom static assets
|
|
||||||
new CopyWebpackPlugin([
|
|
||||||
{
|
|
||||||
from: path.resolve(__dirname, '../static'),
|
|
||||||
to: config.build.assetsSubDirectory,
|
|
||||||
ignore: ['.*']
|
|
||||||
}
|
|
||||||
])
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
if (config.build.productionGzip) {
|
|
||||||
const CompressionWebpackPlugin = require('compression-webpack-plugin')
|
|
||||||
|
|
||||||
webpackConfig.plugins.push(
|
|
||||||
new CompressionWebpackPlugin({
|
|
||||||
asset: '[path].gz[query]',
|
|
||||||
algorithm: 'gzip',
|
|
||||||
test: new RegExp(
|
|
||||||
'\\.(' +
|
|
||||||
config.build.productionGzipExtensions.join('|') +
|
|
||||||
')$'
|
|
||||||
),
|
|
||||||
threshold: 10240,
|
|
||||||
minRatio: 0.8
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.build.bundleAnalyzerReport) {
|
|
||||||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
|
|
||||||
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = webpackConfig
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
const merge = require('webpack-merge')
|
|
||||||
const prodEnv = require('./prod.env')
|
|
||||||
|
|
||||||
module.exports = merge(prodEnv, {
|
|
||||||
NODE_ENV: '"development"',
|
|
||||||
BASE_URL:''
|
|
||||||
})
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
// Template version: 1.3.1
|
|
||||||
// see http://vuejs-templates.github.io/webpack for documentation.
|
|
||||||
|
|
||||||
const path = require('path')
|
|
||||||
// const api = 'http://www.baidu.com'
|
|
||||||
module.exports = {
|
|
||||||
dev: {
|
|
||||||
|
|
||||||
// Paths
|
|
||||||
assetsSubDirectory: 'static',
|
|
||||||
assetsPublicPath: '/',
|
|
||||||
proxyTable: {
|
|
||||||
// '/api': {
|
|
||||||
// target:api,
|
|
||||||
// changeOrigin:true,
|
|
||||||
// pathRewrite:{
|
|
||||||
// '^/api':''
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
},
|
|
||||||
|
|
||||||
// Various Dev Server settings
|
|
||||||
host: '0.0.0.0', // can be overwritten by process.env.HOST
|
|
||||||
port: 10000, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
|
|
||||||
autoOpenBrowser: false,
|
|
||||||
errorOverlay: true,
|
|
||||||
notifyOnErrors: true,
|
|
||||||
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
|
|
||||||
|
|
||||||
// Use Eslint Loader?
|
|
||||||
// If true, your code will be linted during bundling and
|
|
||||||
// linting errors and warnings will be shown in the console.
|
|
||||||
useEslint: false,
|
|
||||||
// If true, eslint errors and warnings will also be shown in the error overlay
|
|
||||||
// in the browser.
|
|
||||||
showEslintErrorsInOverlay: false,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Source Maps
|
|
||||||
*/
|
|
||||||
|
|
||||||
// https://webpack.js.org/configuration/devtool/#development
|
|
||||||
devtool: 'cheap-module-eval-source-map',
|
|
||||||
|
|
||||||
// If you have problems debugging vue-files in devtools,
|
|
||||||
// set this to false - it *may* help
|
|
||||||
// https://vue-loader.vuejs.org/en/options.html#cachebusting
|
|
||||||
cacheBusting: true,
|
|
||||||
|
|
||||||
cssSourceMap: true
|
|
||||||
},
|
|
||||||
|
|
||||||
build: {
|
|
||||||
// Template for index.html
|
|
||||||
index: path.resolve(__dirname, '../dist/index.html'),
|
|
||||||
|
|
||||||
// Paths
|
|
||||||
assetsRoot: path.resolve(__dirname, '../dist'),
|
|
||||||
assetsSubDirectory: 'static',
|
|
||||||
assetsPublicPath: '/',
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Source Maps
|
|
||||||
*/
|
|
||||||
|
|
||||||
productionSourceMap: true,
|
|
||||||
// https://webpack.js.org/configuration/devtool/#production
|
|
||||||
devtool: '#source-map',
|
|
||||||
|
|
||||||
// Gzip off by default as many popular static hosts such as
|
|
||||||
// Surge or Netlify already gzip all static assets for you.
|
|
||||||
// Before setting to `true`, make sure to:
|
|
||||||
// npm install --save-dev compression-webpack-plugin
|
|
||||||
productionGzip: false,
|
|
||||||
productionGzipExtensions: ['js', 'css'],
|
|
||||||
|
|
||||||
// Run the build command with an extra argument to
|
|
||||||
// View the bundle analyzer report after build finishes:
|
|
||||||
// `npm run build --report`
|
|
||||||
// Set to `true` or `false` to always turn it on or off
|
|
||||||
bundleAnalyzerReport: process.env.npm_config_report
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
module.exports = {
|
|
||||||
NODE_ENV: '"production"',
|
|
||||||
BASE_URL:'http://www.baidu.com'
|
|
||||||
}
|
|
||||||
@@ -1 +1 @@
|
|||||||
docker build -t registry.cn-beijing.aliyuncs.com/lili-images/buyer-ui-1.0.1:0.0.4 .
|
docker build -t registry.cn-beijing.aliyuncs.com/lili-images/buyer-ui:4.2.4.1 .
|
||||||
|
|||||||
36
buyer/eslint.config.js
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
const globals = require('globals')
|
||||||
|
const pluginVue = require('eslint-plugin-vue')
|
||||||
|
|
||||||
|
module.exports = [
|
||||||
|
{
|
||||||
|
ignores: [
|
||||||
|
'dist/**',
|
||||||
|
'node_modules/**',
|
||||||
|
'build/**',
|
||||||
|
'config/**',
|
||||||
|
'src/scripts/**', // 一次性迁移脚本,不参与 lint
|
||||||
|
],
|
||||||
|
},
|
||||||
|
...pluginVue.configs['flat/essential'],
|
||||||
|
{
|
||||||
|
files: ['src/**/*.{js,vue}'],
|
||||||
|
languageOptions: {
|
||||||
|
ecmaVersion: 'latest',
|
||||||
|
sourceType: 'module',
|
||||||
|
globals: {
|
||||||
|
...globals.browser,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'no-console': ['warn', { allow: ['warn', 'error'] }],
|
||||||
|
'no-empty': ['error', { allowEmptyCatch: false }],
|
||||||
|
'vue/no-parsing-error': ['error', { 'x-invalid-end-tag': false }],
|
||||||
|
// 页面组件通过路由按文件路径引用,组件名不参与解析,存量单词组件名不再强制多词
|
||||||
|
'vue/multi-word-component-names': 'off',
|
||||||
|
// 存量代码大量使用与 HTML 保留名同名的组件(element-plus 图标 Search/View/Camera/Link 及全局注册的 empty/drawer 等),重命名成本高,暂不启用
|
||||||
|
'vue/no-reserved-component-names': 'off',
|
||||||
|
// 全端已完成 Options API → <script setup> 迁移,防止新代码回退(路由守卫的普通 script 块等有意保留的除外,故用 warn)
|
||||||
|
'vue/component-api-style': ['warn', ['script-setup']],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
|
||||||
<link rel="icon" href="./static/logo.ico" type="image/x-icon">
|
|
||||||
<script src="https://yzf.qq.com/xv/web/static/chat_sdk/yzf_chat.min.js"></script>
|
|
||||||
<title>LILI</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="app"></div>
|
|
||||||
<!-- built files will be auto injected -->
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
@@ -1,51 +1,46 @@
|
|||||||
#这个文件给docker用的
|
#这个文件给docker用的
|
||||||
#user nobody;
|
#user nobody;
|
||||||
worker_processes 1;
|
worker_processes 1;
|
||||||
|
|
||||||
#error_log logs/error.log;
|
#error_log logs/error.log;
|
||||||
#error_log logs/error.log notice;
|
#error_log logs/error.log notice;
|
||||||
#error_log logs/error.log info;
|
#error_log logs/error.log info;
|
||||||
|
|
||||||
#pid logs/nginx.pid;
|
#pid logs/nginx.pid;
|
||||||
|
|
||||||
|
|
||||||
events {
|
events {
|
||||||
worker_connections 1024;
|
worker_connections 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
http {
|
http {
|
||||||
include mime.types;
|
include mime.types;
|
||||||
default_type application/octet-stream;
|
default_type application/octet-stream;
|
||||||
|
|
||||||
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||||
# '$status $body_bytes_sent "$http_referer" '
|
# '$status $body_bytes_sent "$http_referer" '
|
||||||
# '"$http_user_agent" "$http_x_forwarded_for"';
|
# '"$http_user_agent" "$http_x_forwarded_for"';
|
||||||
|
|
||||||
#access_log logs/access.log main;
|
#access_log logs/access.log main;
|
||||||
|
sendfile on;
|
||||||
sendfile on;
|
|
||||||
#tcp_nopush on;
|
#tcp_nopush on;
|
||||||
|
|
||||||
#keepalive_timeout 0;
|
#keepalive_timeout 0;
|
||||||
keepalive_timeout 65;
|
keepalive_timeout 65;
|
||||||
client_max_body_size 10m;
|
client_max_body_size 10m;
|
||||||
gzip on;
|
gzip on;
|
||||||
gzip_min_length 5k;
|
gzip_min_length 5k;
|
||||||
gzip_buffers 4 16k;
|
gzip_buffers 4 16k;
|
||||||
gzip_http_version 1.0;
|
gzip_http_version 1.0;
|
||||||
gzip_comp_level 4;
|
gzip_comp_level 4;
|
||||||
gzip_types text/plain application/x-javascript application/javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
|
gzip_types text/plain application/x-javascript application/javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
|
||||||
gzip_vary on;
|
gzip_vary on;
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen 10000;
|
listen 10000;
|
||||||
server_name localhost;
|
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
root /app;
|
root /app;
|
||||||
try_files $uri $uri/ /index.html $uri/ =404;
|
try_files $uri $uri/ /index.html $uri/ =404;
|
||||||
index index.html index.htm;
|
index index.html index.htm;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,91 +1,56 @@
|
|||||||
{
|
{
|
||||||
"name": "lilishop-vue",
|
"name": "lilishop",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
|
"serve": "vue-cli-service serve",
|
||||||
"start": "npm run dev",
|
"build": "vue-cli-service build",
|
||||||
"lint": "eslint --ext .js,.vue src",
|
"dev": "vue-cli-service serve",
|
||||||
"build": "node build/build.js"
|
"lint": "eslint src",
|
||||||
|
"lint:fix": "eslint src --fix"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@amap/amap-jsapi-loader": "0.0.7",
|
"@amap/amap-jsapi-loader": "0.0.7",
|
||||||
"axios": "^0.19.2",
|
"@element-plus/icons-vue": "^2.3.2",
|
||||||
|
"axios": "^1.7.9",
|
||||||
|
"core-js": "^3.49.0",
|
||||||
|
"dplayer": "^1.27.1",
|
||||||
|
"element-plus": "^2.14.1",
|
||||||
"js-cookie": "^2.2.1",
|
"js-cookie": "^2.2.1",
|
||||||
"less": "^3.12.2",
|
"nprogress": "^0.2.0",
|
||||||
"less-loader": "^5.0.0",
|
"pinia": "^4.0.3",
|
||||||
"mv-count-down": "^0.1.15",
|
|
||||||
"psl": "^1.8.0",
|
"psl": "^1.8.0",
|
||||||
"qs": "^6.9.4",
|
"qs": "^6.9.4",
|
||||||
"swiper": "^5.2.0",
|
"sass": "^1.63.6",
|
||||||
|
"sass-loader": "^10.4.1",
|
||||||
"uuid": "^8.3.2",
|
"uuid": "^8.3.2",
|
||||||
"v-distpicker": "^1.0.17",
|
"vue": "^3.5.35",
|
||||||
"view-design": "^4.3.2",
|
"vue-qr": "^5.0.3",
|
||||||
"vue": "^2.5.2",
|
"vue-router": "^4.6.4"
|
||||||
"vue-awesome": "^4.0.2",
|
|
||||||
"vue-awesome-swiper": "^4.1.1",
|
|
||||||
"vue-piczoom": "^1.0.6",
|
|
||||||
"vue-qr": "^2.3.0",
|
|
||||||
"vue-router": "^3.0.1",
|
|
||||||
"vuex": "^3.0.1"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"autoprefixer": "^7.1.2",
|
"@vue/cli-plugin-babel": "^5.0.9",
|
||||||
"babel-core": "^6.22.1",
|
"@vue/cli-service": "^5.0.9",
|
||||||
"babel-eslint": "^8.2.1",
|
"@vue/compiler-sfc": "^3.5.35",
|
||||||
"babel-helper-vue-jsx-merge-props": "^2.0.3",
|
"compression-webpack-plugin": "^10.0.0",
|
||||||
"babel-loader": "^7.1.1",
|
"eslint": "^9.39.4",
|
||||||
"babel-plugin-syntax-jsx": "^6.18.0",
|
"eslint-plugin-vue": "^10.11.1",
|
||||||
"babel-plugin-transform-runtime": "^6.22.0",
|
"globals": "^17.13.0",
|
||||||
"babel-plugin-transform-vue-jsx": "^3.5.0",
|
"less": "^4.2.0",
|
||||||
"babel-preset-env": "^1.3.2",
|
"less-loader": "^11.1.4",
|
||||||
"babel-preset-stage-2": "^6.22.0",
|
"vue-eslint-parser": "^10.4.1",
|
||||||
"chalk": "^2.0.1",
|
"webpack": "^5.95.0"
|
||||||
"copy-webpack-plugin": "^4.0.1",
|
|
||||||
"css-loader": "^0.28.0",
|
|
||||||
"eslint": "^4.15.0",
|
|
||||||
"eslint-config-standard": "^10.2.1",
|
|
||||||
"eslint-friendly-formatter": "^3.0.0",
|
|
||||||
"eslint-loader": "^1.7.1",
|
|
||||||
"eslint-plugin-import": "^2.7.0",
|
|
||||||
"eslint-plugin-node": "^5.2.0",
|
|
||||||
"eslint-plugin-promise": "^3.4.0",
|
|
||||||
"eslint-plugin-standard": "^3.0.1",
|
|
||||||
"eslint-plugin-vue": "^4.0.0",
|
|
||||||
"extract-text-webpack-plugin": "^3.0.0",
|
|
||||||
"file-loader": "^1.1.4",
|
|
||||||
"friendly-errors-webpack-plugin": "^1.6.1",
|
|
||||||
"html-webpack-plugin": "^2.30.1",
|
|
||||||
"node-notifier": "^5.1.2",
|
|
||||||
"node-sass": "^4.14.1",
|
|
||||||
"optimize-css-assets-webpack-plugin": "^3.2.0",
|
|
||||||
"ora": "^1.2.0",
|
|
||||||
"portfinder": "^1.0.13",
|
|
||||||
"postcss-import": "^11.0.0",
|
|
||||||
"postcss-loader": "^2.0.8",
|
|
||||||
"postcss-url": "^7.2.1",
|
|
||||||
"rimraf": "^2.6.0",
|
|
||||||
"sass-loader": "^7.3.1",
|
|
||||||
"sass-resources-loader": "^2.0.3",
|
|
||||||
"semver": "^5.3.0",
|
|
||||||
"shelljs": "^0.7.6",
|
|
||||||
"uglifyjs-webpack-plugin": "^1.1.1",
|
|
||||||
"url-loader": "^0.5.8",
|
|
||||||
"vue-loader": "^13.3.0",
|
|
||||||
"vue-style-loader": "^3.0.1",
|
|
||||||
"vue-template-compiler": "^2.5.2",
|
|
||||||
"webpack": "^3.6.0",
|
|
||||||
"webpack-bundle-analyzer": "^2.9.0",
|
|
||||||
"webpack-dev-server": "^2.9.1",
|
|
||||||
"webpack-merge": "^4.1.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 6.0.0",
|
|
||||||
"npm": ">= 3.0.0"
|
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"> 1%",
|
"> 1%",
|
||||||
"last 2 versions",
|
"last 2 versions",
|
||||||
"not ie <= 8"
|
"not dead"
|
||||||
]
|
],
|
||||||
|
"resolutions": {
|
||||||
|
"minimatch": "^3.1.2",
|
||||||
|
"@achrinza/node-ipc": "9.2.2"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
8672
buyer/pnpm-lock.yaml
generated
Normal file
11
buyer/public/config.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
var BASE = {
|
||||||
|
/**
|
||||||
|
* @description api请求基础路径
|
||||||
|
*/
|
||||||
|
API_DEV: {
|
||||||
|
buyer: "https://buyer-api.pickmall.cn",
|
||||||
|
},
|
||||||
|
API_PROD: {
|
||||||
|
buyer: "https://buyer-api.pickmall.cn",
|
||||||
|
},
|
||||||
|
};
|
||||||
18
buyer/public/index.html
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name='description' content='在线购物平台'>
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
|
<link rel="icon" href="<%= BASE_URL %>logo.ico">
|
||||||
|
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script src="<%= BASE_URL %>config.js"></script>
|
||||||
|
<noscript>
|
||||||
|
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||||
|
</noscript>
|
||||||
|
<div id="app"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
BIN
buyer/public/logo.ico
Normal file
|
After Width: | Height: | Size: 19 KiB |
54
buyer/scripts/fix-broken-tags.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
const ROOT = path.join(__dirname, "..");
|
||||||
|
|
||||||
|
function walkDir(dir, files = []) {
|
||||||
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||||
|
const full = path.join(dir, entry.name);
|
||||||
|
if (entry.isDirectory()) walkDir(full, files);
|
||||||
|
else if (entry.name.endsWith(".vue")) files.push(full);
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fix(content) {
|
||||||
|
let c = content;
|
||||||
|
c = c.replace(/<\/Button>/g, "</el-button>");
|
||||||
|
c = c.replace(/<\/Button\b/g, "</el-button");
|
||||||
|
c = c.replace(/<\/Input>/g, "</el-input>");
|
||||||
|
c = c.replace(/<\/Input\b/g, "</el-input");
|
||||||
|
c = c.replace(/<\/Option>/g, "</el-option>");
|
||||||
|
c = c.replace(/<\/Option\b/g, "</el-option");
|
||||||
|
c = c.replace(/<\/Checkbox>/g, "</el-checkbox>");
|
||||||
|
c = c.replace(/<\/Checkbox\b/g, "</el-checkbox");
|
||||||
|
c = c.replace(/<\/Select>/g, "</el-select>");
|
||||||
|
c = c.replace(/<\/Select\b/g, "</el-select");
|
||||||
|
c = c.replace(/<\/Form>/g, "</el-form>");
|
||||||
|
c = c.replace(/<\/Modal>/g, "</el-dialog>");
|
||||||
|
c = c.replace(/@click\.native/g, "@click");
|
||||||
|
c = c.replace(/@on-search/g, "@keyup.enter");
|
||||||
|
c = c.replace(/\bsearch\b(?=\s+enter-button)/g, "");
|
||||||
|
c = c.replace(/\benter-button\b/g, "");
|
||||||
|
c = c.replace(/<BreadcrumbItem/g, "<el-breadcrumb-item");
|
||||||
|
c = c.replace(/<\/BreadcrumbItem>/g, "</el-breadcrumb-item>");
|
||||||
|
c = c.replace(/<Breadcrumb/g, "<el-breadcrumb");
|
||||||
|
c = c.replace(/<\/Breadcrumb>/g, "</el-breadcrumb>");
|
||||||
|
c = c.replace(/type="error"/g, 'type="danger"');
|
||||||
|
c = c.replace(/<i-col/g, "<div");
|
||||||
|
c = c.replace(/<\/i-col>/g, "</div>");
|
||||||
|
c = c.replace(/\{\{([^}|]+)\s*\|\s*secrecyMobile\s*\}\}/g, "{{ $filters.secrecyMobile($1) }}");
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
let count = 0;
|
||||||
|
for (const file of walkDir(path.join(ROOT, "src"))) {
|
||||||
|
const original = fs.readFileSync(file, "utf8");
|
||||||
|
const fixed = fix(original);
|
||||||
|
if (fixed !== original) {
|
||||||
|
fs.writeFileSync(file, fixed);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`Fixed tags in ${count} files`);
|
||||||
52
buyer/scripts/fix-dialog-slots.js
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
const ROOT = path.join(__dirname, "..");
|
||||||
|
|
||||||
|
function walkDir(dir, files = []) {
|
||||||
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||||
|
const full = path.join(dir, entry.name);
|
||||||
|
if (entry.isDirectory()) walkDir(full, files);
|
||||||
|
else if (entry.name.endsWith(".vue")) files.push(full);
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fix(content) {
|
||||||
|
let c = content;
|
||||||
|
|
||||||
|
c = c.replace(/<p #header>/g, "<template #header><p>");
|
||||||
|
c = c.replace(
|
||||||
|
/(<template #header><p>[\s\S]*?<\/p>)(\s*<div)/g,
|
||||||
|
"$1</template>$2"
|
||||||
|
);
|
||||||
|
|
||||||
|
c = c.replace(
|
||||||
|
/<template #footer><div([^>]*)>([\s\S]*?)<\/div><\/template><\/el-dialog>/g,
|
||||||
|
"<template #footer><div$1>$2</div></template>\n </el-dialog>"
|
||||||
|
);
|
||||||
|
|
||||||
|
c = c.replace(
|
||||||
|
/<template #default\s*>([\s\S]*?)<\/template\s*>/g,
|
||||||
|
(match, inner) => {
|
||||||
|
if (match.includes("el-alert")) {
|
||||||
|
return `<template #title>${inner}</template>`;
|
||||||
|
}
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
let count = 0;
|
||||||
|
for (const file of walkDir(path.join(ROOT, "src"))) {
|
||||||
|
const original = fs.readFileSync(file, "utf8");
|
||||||
|
const fixed = fix(original);
|
||||||
|
if (fixed !== original) {
|
||||||
|
fs.writeFileSync(file, fixed);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`Fixed dialog slots in ${count} files`);
|
||||||
26
buyer/scripts/fix-duplicate-size.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
const ROOT = path.join(__dirname, "..", "src");
|
||||||
|
|
||||||
|
function walk(dir, files = []) {
|
||||||
|
for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||||
|
const f = path.join(dir, e.name);
|
||||||
|
if (e.isDirectory()) walk(f, files);
|
||||||
|
else if (e.name.endsWith(".vue")) files.push(f);
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
let n = 0;
|
||||||
|
for (const file of walk(ROOT)) {
|
||||||
|
let c = fs.readFileSync(file, "utf8");
|
||||||
|
const next = c.replace(/:size="(\d+)"\s+:size="\1"/g, ':size="$1"');
|
||||||
|
if (next !== c) {
|
||||||
|
fs.writeFileSync(file, next);
|
||||||
|
n++;
|
||||||
|
console.log(path.relative(ROOT, file));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`Fixed duplicate :size in ${n} files`);
|
||||||
28
buyer/scripts/fix-el-icon-click.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
const ROOT = path.join(__dirname, "..", "src");
|
||||||
|
|
||||||
|
function walk(dir, files = []) {
|
||||||
|
for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||||
|
const f = path.join(dir, e.name);
|
||||||
|
if (e.isDirectory()) walk(f, files);
|
||||||
|
else if (e.name.endsWith(".vue")) files.push(f);
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
let n = 0;
|
||||||
|
for (const file of walk(ROOT)) {
|
||||||
|
let c = fs.readFileSync(file, "utf8");
|
||||||
|
const next = c
|
||||||
|
.replace(/<el-icon([^>]*?):click=/g, "<el-icon$1@click=")
|
||||||
|
.replace(/:class="refresh"/g, 'class="refresh"')
|
||||||
|
.replace(/:size="20" @click="show = false" :size="20"/g, ':size="20" @click="show = false"');
|
||||||
|
if (next !== c) {
|
||||||
|
fs.writeFileSync(file, next);
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`Fixed el-icon click in ${n} files`);
|
||||||
77
buyer/scripts/fix-filters.js
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
const ROOT = path.join(__dirname, "..");
|
||||||
|
|
||||||
|
function walkDir(dir, files = []) {
|
||||||
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||||
|
const full = path.join(dir, entry.name);
|
||||||
|
if (entry.isDirectory()) walkDir(full, files);
|
||||||
|
else if (entry.name.endsWith(".vue")) files.push(full);
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fixFilters(content) {
|
||||||
|
let c = content;
|
||||||
|
|
||||||
|
// Fix broken: {{ expr {{ $filters.unitPrice(args) }}
|
||||||
|
c = c.replace(
|
||||||
|
/\{\{\s*([^}{]+?)\s*\{\{\s*\$filters\.unitPrice\(([^)]*)\)\s*\}\}/g,
|
||||||
|
"{{ $filters.unitPrice($1, $2) }}"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Fix: {{ expr | unitPrice }} or {{ expr | unitPrice('¥') }}
|
||||||
|
c = c.replace(
|
||||||
|
/\{\{\s*([^}|]+?)\s*\|\s*unitPrice(?:\(([^)]*)\))?\s*\}\}/g,
|
||||||
|
(_, expr, args) => {
|
||||||
|
const e = expr.trim();
|
||||||
|
return args !== undefined
|
||||||
|
? `{{ $filters.unitPrice(${e}, ${args}) }}`
|
||||||
|
: `{{ $filters.unitPrice(${e}) }}`;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Fix inline without braces: expr | unitPrice("¥")
|
||||||
|
c = c.replace(
|
||||||
|
/(?<!\{\{)\s*([a-zA-Z0-9_.?()[\]'"\s]+?)\s*\|\s*unitPrice\(([^)]*)\)/g,
|
||||||
|
(match, expr, args) => {
|
||||||
|
if (match.includes("{{")) return match;
|
||||||
|
return `{{ $filters.unitPrice(${expr.trim()}, ${args}) }}`;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Fix inline without args: expr | unitPrice
|
||||||
|
c = c.replace(
|
||||||
|
/(?<!\{\{)\s*([a-zA-Z0-9_.?()[\]'"\s]+?)\s*\|\s*unitPrice(?!\()/g,
|
||||||
|
(match, expr) => {
|
||||||
|
if (match.includes("{{") || match.includes("$filters")) return match;
|
||||||
|
return `{{ $filters.unitPrice(${expr.trim()}) }}`;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Fix unixToDate filter
|
||||||
|
c = c.replace(
|
||||||
|
/\{\{\s*([^}|]+?)\s*\|\s*unixToDate(?:\(([^)]*)\))?\s*\}\}/g,
|
||||||
|
(_, expr, args) => {
|
||||||
|
const e = expr.trim();
|
||||||
|
return args !== undefined
|
||||||
|
? `{{ $filters.unixToDate(${e}, ${args}) }}`
|
||||||
|
: `{{ $filters.unixToDate(${e}) }}`;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
let count = 0;
|
||||||
|
for (const file of walkDir(path.join(ROOT, "src"))) {
|
||||||
|
const original = fs.readFileSync(file, "utf8");
|
||||||
|
const fixed = fixFilters(original);
|
||||||
|
if (fixed !== original) {
|
||||||
|
fs.writeFileSync(file, fixed);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`Fixed filters in ${count} files`);
|
||||||
55
buyer/scripts/fix-runtime-compat.js
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
const ROOT = path.join(__dirname, "..");
|
||||||
|
|
||||||
|
function walkDir(dir, files = []) {
|
||||||
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||||
|
const full = path.join(dir, entry.name);
|
||||||
|
if (entry.isDirectory()) walkDir(full, files);
|
||||||
|
else if (entry.name.endsWith(".vue")) files.push(full);
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fix(content) {
|
||||||
|
let c = content;
|
||||||
|
|
||||||
|
c = c.replace(/<el-pagination\b/g, "<Page");
|
||||||
|
c = c.replace(/<\/el-pagination>/g, "</Page>");
|
||||||
|
|
||||||
|
c = c.replace(
|
||||||
|
/<Icon([^>]*)\s+#prepend\s*>\s*<\/Icon>/g,
|
||||||
|
"<template #prepend><Icon$1></Icon></template>"
|
||||||
|
);
|
||||||
|
c = c.replace(
|
||||||
|
/<Icon([^>]*)\s+#prepend\s*>\s*<\/Icon>/g,
|
||||||
|
"<template #prepend><Icon$1></Icon></template>"
|
||||||
|
);
|
||||||
|
c = c.replace(
|
||||||
|
/<template #prepend><Icon([^>]*)\s*\/>/g,
|
||||||
|
"<template #prepend><Icon$1></Icon></template>"
|
||||||
|
);
|
||||||
|
|
||||||
|
c = c.replace(/@keyup\.enter\.native/g, "@keyup.enter");
|
||||||
|
c = c.replace(/slot="append"/g, "#append");
|
||||||
|
c = c.replace(/(<div[^>]*)\s+#append/g, "<template #append>$1");
|
||||||
|
|
||||||
|
c = c.replace(/(<el-button[^>]*)\slong/g, '$1 style="width:100%"');
|
||||||
|
c = c.replace(/@on-select/g, "@select");
|
||||||
|
c = c.replace(/@on-click/g, "@click");
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
let count = 0;
|
||||||
|
for (const file of walkDir(path.join(ROOT, "src"))) {
|
||||||
|
const original = fs.readFileSync(file, "utf8");
|
||||||
|
const fixed = fix(original);
|
||||||
|
if (fixed !== original) {
|
||||||
|
fs.writeFileSync(file, fixed);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`Runtime compat fixes in ${count} files`);
|
||||||
54
buyer/scripts/fix-slots.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
const ROOT = path.join(__dirname, "..");
|
||||||
|
|
||||||
|
function walkDir(dir, files = []) {
|
||||||
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||||
|
const full = path.join(dir, entry.name);
|
||||||
|
if (entry.isDirectory()) walkDir(full, files);
|
||||||
|
else if (entry.name.endsWith(".vue")) files.push(full);
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fix(content) {
|
||||||
|
let c = content;
|
||||||
|
|
||||||
|
c = c.replace(
|
||||||
|
/<template #default="(\{[^"]+\})" #([a-zA-Z0-9_-]+)>/g,
|
||||||
|
'<template #$2="$1">'
|
||||||
|
);
|
||||||
|
|
||||||
|
c = c.replace(
|
||||||
|
/<div([^>]*) #footer([^>]*)>/g,
|
||||||
|
'<template #footer><div$1$2>'
|
||||||
|
);
|
||||||
|
c = c.replace(/<\/div>\s*(?=<\/el-dialog>)/g, "</div></template>");
|
||||||
|
|
||||||
|
c = c.replace(/<span #append>/g, "<template #append><span>");
|
||||||
|
c = c.replace(/<\/span><\/el-input/g, "</span></template></el-input");
|
||||||
|
c = c.replace(/><span #append>/g, "><template #append><span>");
|
||||||
|
|
||||||
|
c = c.replace(/<el-button #append/g, "<template #append><el-button");
|
||||||
|
c = c.replace(
|
||||||
|
/<\/el-button>(\s*<\/el-input>)/g,
|
||||||
|
"</el-button></template>$1"
|
||||||
|
);
|
||||||
|
|
||||||
|
c = c.replace(/<template #desc\b/g, "<template #default");
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
let count = 0;
|
||||||
|
for (const file of walkDir(path.join(ROOT, "src"))) {
|
||||||
|
const original = fs.readFileSync(file, "utf8");
|
||||||
|
const fixed = fix(original);
|
||||||
|
if (fixed !== original) {
|
||||||
|
fs.writeFileSync(file, fixed);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`Fixed slots in ${count} files`);
|
||||||
46
buyer/scripts/fix-span-tags.js
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
const ROOT = path.join(__dirname, "..");
|
||||||
|
|
||||||
|
function walkDir(dir, files = []) {
|
||||||
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||||
|
const full = path.join(dir, entry.name);
|
||||||
|
if (entry.isDirectory()) walkDir(full, files);
|
||||||
|
else if (entry.name.endsWith(".vue")) files.push(full);
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fix(content) {
|
||||||
|
let c = content;
|
||||||
|
c = c.replace(/<\/span\s*\n\s*>/g, "</span>");
|
||||||
|
c = c.replace(/<\/span\s+>/g, "</span>");
|
||||||
|
c = c.replace(/<i-input/g, "<el-input");
|
||||||
|
c = c.replace(/<\/i-input>/g, "</el-input>");
|
||||||
|
c = c.replace(
|
||||||
|
/<Icon([^>]*)\s+#prepend\s*\/>/g,
|
||||||
|
"<template #prepend><Icon$1 /></template>"
|
||||||
|
);
|
||||||
|
c = c.replace(
|
||||||
|
/<template #append><el-button([^>]*)>([\s\S]*?)<\/el-button>\s*<\/i-input>/g,
|
||||||
|
"<template #append><el-button$1>$2</el-button></template></el-input>"
|
||||||
|
);
|
||||||
|
c = c.replace(
|
||||||
|
/<template #append><el-button([^>]*)>([\s\S]*?)<\/el-button>\s*<\/el-input>/g,
|
||||||
|
"<template #append><el-button$1>$2</el-button></template></el-input>"
|
||||||
|
);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
let count = 0;
|
||||||
|
for (const file of walkDir(path.join(ROOT, "src"))) {
|
||||||
|
const original = fs.readFileSync(file, "utf8");
|
||||||
|
const fixed = fix(original);
|
||||||
|
if (fixed !== original) {
|
||||||
|
fs.writeFileSync(file, fixed);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`Fixed span/input tags in ${count} files`);
|
||||||
55
buyer/scripts/fix-stray-templates.js
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
const ROOT = path.join(__dirname, "..");
|
||||||
|
|
||||||
|
function walkDir(dir, files = []) {
|
||||||
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||||
|
const full = path.join(dir, entry.name);
|
||||||
|
if (entry.isDirectory()) walkDir(full, files);
|
||||||
|
else if (entry.name.endsWith(".vue")) files.push(full);
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fix(content) {
|
||||||
|
let c = content;
|
||||||
|
|
||||||
|
c = c.replace(
|
||||||
|
/(<div[^>]*)\s+#content>/g,
|
||||||
|
"<template #content><div$1>"
|
||||||
|
);
|
||||||
|
c = c.replace(
|
||||||
|
/(<\/el-tooltip>)/g,
|
||||||
|
(match, _m, offset, str) => {
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
c = c.replace(
|
||||||
|
/(<div style="white-space:[^"]*"[^>]*>[\s\S]*?<\/div>)(\s*<\/el-tooltip>)/g,
|
||||||
|
"$1</template>$2"
|
||||||
|
);
|
||||||
|
|
||||||
|
c = c.replace(/<\/div><\/template><\/el-dialog>/g, (m, offset, str) => {
|
||||||
|
const before = str.slice(Math.max(0, offset - 200), offset);
|
||||||
|
if (before.includes("#footer")) return m;
|
||||||
|
return "</div></el-dialog>";
|
||||||
|
});
|
||||||
|
|
||||||
|
c = c.replace(/<i(\s[^>]*)\/>/g, "<i$1></i>");
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
let count = 0;
|
||||||
|
for (const file of walkDir(path.join(ROOT, "src"))) {
|
||||||
|
const original = fs.readFileSync(file, "utf8");
|
||||||
|
const fixed = fix(original);
|
||||||
|
if (fixed !== original) {
|
||||||
|
fs.writeFileSync(file, fixed);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`Fixed stray templates in ${count} files`);
|
||||||
227
buyer/scripts/migrate-iview-to-element.js
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* Migrate buyer Vue files from iView to Element Plus.
|
||||||
|
* Usage: node scripts/migrate-iview-to-element.js
|
||||||
|
*/
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
const BUYER_ROOT = path.join(__dirname, "..");
|
||||||
|
const MANAGER_ROOT = path.join(__dirname, "../../manager");
|
||||||
|
|
||||||
|
const MODEL_LIST = [
|
||||||
|
["Carousel.vue", "carousel.vue"],
|
||||||
|
["Carousel1.vue", "carousel1.vue"],
|
||||||
|
["Carousel2.vue", "carousel2.vue"],
|
||||||
|
["FirstPageAdvert.vue", "firstPageAdvert.vue"],
|
||||||
|
["NewGoodsSort.vue", "newGoodsSort.vue"],
|
||||||
|
["NotEnough.vue", "notEnough.vue"],
|
||||||
|
["Recommend.vue", "recommend.vue"],
|
||||||
|
["Seckill.vue", "seckill.vue"],
|
||||||
|
["forYour.vue", "forYour.vue"],
|
||||||
|
["goodsAndType.vue", "goodsAndType.vue"],
|
||||||
|
["mixModel.vue", "mixModel.vue"],
|
||||||
|
["oneRowThreeColumns.vue", "oneRowThreeColumns.vue"],
|
||||||
|
["onlyGoodsModel.vue", "onlyGoodsModel.vue"],
|
||||||
|
["mixs/mix-brand.vue", "mixs/mix-brand.vue"],
|
||||||
|
["mixs/mix-goods.vue", "mixs/mix-goods.vue"],
|
||||||
|
];
|
||||||
|
|
||||||
|
const DECORATE_COPY_MAP = [
|
||||||
|
[
|
||||||
|
"src/components/indexDecorate/ModelForm.vue",
|
||||||
|
"src/views/page-decoration/modelForm.vue",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"src/components/indexDecorate/ModelFormItem.vue",
|
||||||
|
"src/views/page-decoration/modelFormItem.vue",
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
MODEL_LIST.forEach(([buyerName, managerName]) => {
|
||||||
|
DECORATE_COPY_MAP.push([
|
||||||
|
`src/components/indexDecorate/modelList/${buyerName}`,
|
||||||
|
`src/views/page-decoration/modelList/${managerName}`,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
const TARGET_DIRS = ["src/pages", "src/components"];
|
||||||
|
|
||||||
|
function adaptBuyerContent(content) {
|
||||||
|
return content
|
||||||
|
.replace(/@\/views\/page-decoration\//g, "@/components/indexDecorate/")
|
||||||
|
.replace(/admin-setting/g, "buyer-setting")
|
||||||
|
.replace(/adminPCPageCache/g, "buyerPCPageCache")
|
||||||
|
.replace(/getStore\('adminPCPageCache'\)/g, "getStore('buyerPCPageCache')")
|
||||||
|
.replace(/setStore\('adminPCPageCache'/g, "setStore('buyerPCPageCache'");
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyScriptTransforms(content) {
|
||||||
|
let c = content;
|
||||||
|
c = c.replace(/\$options\.filters\./g, "$filters.");
|
||||||
|
c = c.replace(/\|\s*unitPrice\(/g, "{{ $filters.unitPrice(");
|
||||||
|
c = c.replace(/\|\s*unixToDate\(/g, "{{ $filters.unixToDate(");
|
||||||
|
c = c.replace(/\bbeforeDestroy\b/g, "beforeUnmount");
|
||||||
|
c = c.replace(/this\.\$set\(([^,]+),\s*([^,]+),\s*([^)]+)\)/g, "$1[$2] = $3");
|
||||||
|
c = c.replace(/::v-deep/g, ":deep");
|
||||||
|
c = c.replace(/\/deep\//g, ":deep");
|
||||||
|
c = c.replace(/@on-change/g, "@change");
|
||||||
|
c = c.replace(/@on-click/g, "@click");
|
||||||
|
c = c.replace(/@on-ok/g, "@ok");
|
||||||
|
c = c.replace(/@on-cancel/g, "@cancel");
|
||||||
|
c = c.replace(/@on-clear/g, "@clear");
|
||||||
|
c = c.replace(/@on-open-change/g, "@visible-change");
|
||||||
|
c = c.replace(/@on-page-size-change/g, "@size-change");
|
||||||
|
c = c.replace(/@on-select/g, "@select");
|
||||||
|
c = c.replace(/@keydown\.enter\.native/g, "@keyup.enter");
|
||||||
|
c = c.replace(/slot-scope="([^"]+)"/g, '#default="$1"');
|
||||||
|
c = c.replace(/slot="([^"]+)"/g, '#$1');
|
||||||
|
c = c.replace(/from ['"]view-design['"]/g, 'from "@/utils/message"');
|
||||||
|
c = c.replace(/import\s*\{([^}]*)\}\s*from\s*['"]view-design['"]/g, 'import {$1} from "@/utils/message"');
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyTemplateTransforms(content) {
|
||||||
|
let c = content;
|
||||||
|
const replacements = [
|
||||||
|
[/<\/?Card>/g, (m) => m.replace("Card", "el-card")],
|
||||||
|
[/<Form-item/g, "<el-form-item"],
|
||||||
|
[/<\/Form-item>/g, "</el-form-item>"],
|
||||||
|
[/<FormItem/g, "<el-form-item"],
|
||||||
|
[/<\/FormItem>/g, "</el-form-item>"],
|
||||||
|
[/<Form(\s|>)/g, "<el-form$1"],
|
||||||
|
[/<\/Form>/g, "</el-form>"],
|
||||||
|
[/<InputNumber/g, "<el-input-number"],
|
||||||
|
[/<\/InputNumber>/g, "</el-input-number>"],
|
||||||
|
[/<Input(\s|>)/g, "<el-input$1"],
|
||||||
|
[/<\/Input>/g, "</el-input>"],
|
||||||
|
[/<Button(\s|>)/g, "<el-button$1"],
|
||||||
|
[/<\/Button>/g, "</el-button>"],
|
||||||
|
[/<Select(\s|>)/g, "<el-select$1"],
|
||||||
|
[/<\/Select>/g, "</el-select>"],
|
||||||
|
[/<Option(\s)/g, "<el-option "],
|
||||||
|
[/<\/Option>/g, "</el-option>"],
|
||||||
|
[/<DatePicker/g, "<el-date-picker"],
|
||||||
|
[/<\/DatePicker>/g, "</el-date-picker>"],
|
||||||
|
[/<TimePicker/g, "<el-time-picker"],
|
||||||
|
[/<\/TimePicker>/g, "</el-time-picker>"],
|
||||||
|
[/<Modal/g, "<el-dialog"],
|
||||||
|
[/<\/Modal>/g, "</el-dialog>"],
|
||||||
|
[/<Page(\s)/g, "<el-pagination "],
|
||||||
|
[/<\/Page>/g, "</el-pagination>"],
|
||||||
|
[/<Tabs(\s|>)/g, "<el-tabs$1"],
|
||||||
|
[/<\/Tabs>/g, "</el-tabs>"],
|
||||||
|
[/<TabPane/g, "<el-tab-pane"],
|
||||||
|
[/<\/TabPane>/g, "</el-tab-pane>"],
|
||||||
|
[/<Row(\s|>)/g, "<div$1"],
|
||||||
|
[/<\/Row>/g, "</div>"],
|
||||||
|
[/<Col(\s|>)/g, "<div$1"],
|
||||||
|
[/<\/Col>/g, "</div>"],
|
||||||
|
[/<Tag(\s|>)/g, "<el-tag$1"],
|
||||||
|
[/<\/Tag>/g, "</el-tag>"],
|
||||||
|
[/<Switch(\s|>)/g, "<el-switch$1"],
|
||||||
|
[/<\/Switch>/g, "</el-switch>"],
|
||||||
|
[/<RadioGroup/g, "<el-radio-group"],
|
||||||
|
[/<\/RadioGroup>/g, "</el-radio-group>"],
|
||||||
|
[/<Radio(\s)/g, "<el-radio "],
|
||||||
|
[/<\/Radio>/g, "</el-radio>"],
|
||||||
|
[/<CheckboxGroup/g, "<el-checkbox-group"],
|
||||||
|
[/<\/CheckboxGroup>/g, "</el-checkbox-group>"],
|
||||||
|
[/<Checkbox/g, "<el-checkbox"],
|
||||||
|
[/<\/Checkbox>/g, "</el-checkbox>"],
|
||||||
|
[/<Poptip/g, "<el-popover"],
|
||||||
|
[/<\/Poptip>/g, "</el-popover>"],
|
||||||
|
[/<Tooltip/g, "<el-tooltip"],
|
||||||
|
[/<\/Tooltip>/g, "</el-tooltip>"],
|
||||||
|
[/<Drawer/g, "<el-drawer"],
|
||||||
|
[/<\/Drawer>/g, "</el-drawer>"],
|
||||||
|
[/<Alert/g, "<el-alert"],
|
||||||
|
[/<\/Alert>/g, "</el-alert>"],
|
||||||
|
[/<Badge/g, "<el-badge"],
|
||||||
|
[/<\/Badge>/g, "</el-badge>"],
|
||||||
|
[/<Divider/g, "<el-divider"],
|
||||||
|
[/<\/Divider>/g, "</el-divider>"],
|
||||||
|
[/<Rate/g, "<el-rate"],
|
||||||
|
[/<\/Rate>/g, "</el-rate>"],
|
||||||
|
[/<Steps/g, "<el-steps"],
|
||||||
|
[/<\/Steps>/g, "</el-steps>"],
|
||||||
|
[/<Step(\s)/g, "<el-step "],
|
||||||
|
[/<\/Step>/g, "</el-step>"],
|
||||||
|
[/<Upload/g, "<el-upload"],
|
||||||
|
[/<\/Upload>/g, "</el-upload>"],
|
||||||
|
[/<Cascader/g, "<el-cascader"],
|
||||||
|
[/<\/Cascader>/g, "</el-cascader>"],
|
||||||
|
[/<Affix/g, "<el-affix"],
|
||||||
|
[/<\/Affix>/g, "</el-affix>"],
|
||||||
|
[/<Spin/g, "<el-skeleton"],
|
||||||
|
[/<\/Spin>/g, "</el-skeleton>"],
|
||||||
|
[/:label-width="(\d+)"/g, 'label-width="$1px"'],
|
||||||
|
[/:mask-closable="false"/g, ':close-on-click-modal="false"'],
|
||||||
|
[/:width="(\d+)"/g, 'width="$1"'],
|
||||||
|
[/type="primary"/g, 'type="primary"'],
|
||||||
|
];
|
||||||
|
for (const [pattern, replacement] of replacements) {
|
||||||
|
c = c.replace(pattern, replacement);
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
function walkDir(dir, files = []) {
|
||||||
|
if (!fs.existsSync(dir)) return files;
|
||||||
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||||
|
const full = path.join(dir, entry.name);
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
walkDir(full, files);
|
||||||
|
} else if (entry.name.endsWith(".vue")) {
|
||||||
|
files.push(full);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
const copied = [];
|
||||||
|
const transformed = [];
|
||||||
|
const skipped = [];
|
||||||
|
|
||||||
|
for (const [buyerRel, managerRel] of DECORATE_COPY_MAP) {
|
||||||
|
const managerPath = path.join(MANAGER_ROOT, managerRel);
|
||||||
|
const buyerPath = path.join(BUYER_ROOT, buyerRel);
|
||||||
|
if (!fs.existsSync(managerPath)) {
|
||||||
|
skipped.push({ file: buyerRel, reason: "manager counterpart missing" });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let content = fs.readFileSync(managerPath, "utf8");
|
||||||
|
content = adaptBuyerContent(content);
|
||||||
|
fs.mkdirSync(path.dirname(buyerPath), { recursive: true });
|
||||||
|
fs.writeFileSync(buyerPath, content);
|
||||||
|
copied.push(buyerRel);
|
||||||
|
}
|
||||||
|
|
||||||
|
const copiedSet = new Set(copied);
|
||||||
|
for (const dir of TARGET_DIRS) {
|
||||||
|
const absDir = path.join(BUYER_ROOT, dir);
|
||||||
|
for (const filePath of walkDir(absDir)) {
|
||||||
|
const rel = path.relative(BUYER_ROOT, filePath).replace(/\\/g, "/");
|
||||||
|
if (copiedSet.has(rel)) continue;
|
||||||
|
|
||||||
|
let content = fs.readFileSync(filePath, "utf8");
|
||||||
|
const hasIView =
|
||||||
|
/<(Card|Form|Form-item|FormItem|Table|Button|Modal|Page|Tabs|TabPane|Input|Select|Option|DatePicker|Row|Poptip|Drawer|Upload|Checkbox|Radio|Switch|Tag|Alert|Rate|Steps|Step|Spin|Affix|TimePicker|Cascader|Divider|Badge|InputNumber)\b/.test(
|
||||||
|
content
|
||||||
|
);
|
||||||
|
if (!hasIView) {
|
||||||
|
skipped.push({ file: rel, reason: "no iView components" });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
content = applyTemplateTransforms(content);
|
||||||
|
content = applyScriptTransforms(content);
|
||||||
|
fs.writeFileSync(filePath, content);
|
||||||
|
transformed.push(rel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("=== Buyer Migration Summary ===");
|
||||||
|
console.log(`Copied from manager: ${copied.length}`);
|
||||||
|
console.log(`Script-transformed: ${transformed.length}`);
|
||||||
|
console.log(`Skipped: ${skipped.length}`);
|
||||||
149
buyer/scripts/replace-icon.js
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* 将静态 <Icon type="..." /> 替换为 <el-icon><Xxx /></el-icon>
|
||||||
|
* 动态 :type / custom 属性保留,由人工或 resolveIcon 处理。
|
||||||
|
*/
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
const ROOT = path.join(__dirname, "..", "src");
|
||||||
|
|
||||||
|
const TYPE_TO_COMPONENT = {
|
||||||
|
"md-checkmark": "Check",
|
||||||
|
"md-close": "Close",
|
||||||
|
"md-trash": "Delete",
|
||||||
|
"md-add": "Plus",
|
||||||
|
"md-arrow-dropdown": "ArrowDown",
|
||||||
|
"md-arrow-dropup": "ArrowUp",
|
||||||
|
"md-person": "User",
|
||||||
|
"md-lock": "Lock",
|
||||||
|
"md-phone-portrait": "Iphone",
|
||||||
|
"md-key": "Key",
|
||||||
|
"md-link": "Link",
|
||||||
|
"md-refresh": "Refresh",
|
||||||
|
"md-qr-scanner": "Iphone",
|
||||||
|
"ios-arrow-down": "ArrowDown",
|
||||||
|
"ios-arrow-up": "ArrowUp",
|
||||||
|
"ios-arrow-forward": "ArrowRight",
|
||||||
|
"ios-arrow-back": "ArrowLeft",
|
||||||
|
"ios-arrow-round-down": "ArrowDown",
|
||||||
|
"ios-arrow-round-forward": "ArrowRight",
|
||||||
|
"ios-cart-outline": "ShoppingCart",
|
||||||
|
"ios-camera": "Camera",
|
||||||
|
"ios-eye-outline": "View",
|
||||||
|
"ios-trash-outline": "Delete",
|
||||||
|
"ios-alert-outline": "Warning",
|
||||||
|
"ios-help-circle-outline": "Help",
|
||||||
|
"ios-add-circle-outline": "Plus",
|
||||||
|
"ios-information-circle": "InfoFilled",
|
||||||
|
"ios-search": "Search",
|
||||||
|
"ios-text-outline": "Document",
|
||||||
|
"ios-alarm-outline": "AlarmClock",
|
||||||
|
"ios-heart": "StarFilled",
|
||||||
|
"md-close-circle": "CircleClose",
|
||||||
|
edit: "Edit",
|
||||||
|
"trash-a": "Delete",
|
||||||
|
location: "Location",
|
||||||
|
};
|
||||||
|
|
||||||
|
function walkDir(dir, files = []) {
|
||||||
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||||
|
const full = path.join(dir, entry.name);
|
||||||
|
if (entry.isDirectory() && entry.name !== "compat") walkDir(full, files);
|
||||||
|
else if (entry.name.endsWith(".vue")) files.push(full);
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseAttrs(attrStr) {
|
||||||
|
const attrs = {};
|
||||||
|
const re = /(?::([\w-]+)|@([\w-]+)|([\w-]+))=(?:"([^"]*)"|'([^']*)')|(?::([\w-]+)|@([\w-]+)|([\w-]+))(?=\s|\/|>)/g;
|
||||||
|
let m;
|
||||||
|
while ((m = re.exec(attrStr)) !== null) {
|
||||||
|
const name = m[1] || m[2] || m[3] || m[6] || m[7] || m[8];
|
||||||
|
const value = m[4] ?? m[5] ?? true;
|
||||||
|
attrs[name] = value;
|
||||||
|
}
|
||||||
|
return attrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
function attrsToString(attrs, exclude = []) {
|
||||||
|
return Object.entries(attrs)
|
||||||
|
.filter(([k]) => !exclude.includes(k))
|
||||||
|
.map(([k, v]) => {
|
||||||
|
if (v === true) return k;
|
||||||
|
if (k.startsWith("@")) return `${k}="${v}"`;
|
||||||
|
return `:${k}="${v}"`;
|
||||||
|
})
|
||||||
|
.join(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
function transform(content, filePath) {
|
||||||
|
if (filePath.includes("/compat/")) return content;
|
||||||
|
let c = content;
|
||||||
|
const used = new Set();
|
||||||
|
|
||||||
|
c = c.replace(/<Icon\b([^>]*?)\/>/g, (match, attrStr) => {
|
||||||
|
if (/\bcustom=/.test(attrStr) || /:type=/.test(attrStr)) return match;
|
||||||
|
const attrs = parseAttrs(attrStr);
|
||||||
|
const type = attrs.type;
|
||||||
|
if (!type || !TYPE_TO_COMPONENT[type]) return match;
|
||||||
|
const comp = TYPE_TO_COMPONENT[type];
|
||||||
|
used.add(comp);
|
||||||
|
const rest = attrsToString(attrs, ["type"]);
|
||||||
|
const size = attrs.size ? ` :size="${attrs.size}"` : "";
|
||||||
|
const open = rest ? `<el-icon ${rest}${size}>` : `<el-icon${size}>`;
|
||||||
|
return `${open}<${comp} /></el-icon>`;
|
||||||
|
});
|
||||||
|
|
||||||
|
c = c.replace(/<Icon\b([^>]*?)><\/Icon>/g, (match, attrStr) => {
|
||||||
|
if (/\bcustom=/.test(attrStr) || /:type=/.test(attrStr)) return match;
|
||||||
|
const attrs = parseAttrs(attrStr);
|
||||||
|
const type = attrs.type;
|
||||||
|
if (!type || !TYPE_TO_COMPONENT[type]) return match;
|
||||||
|
const comp = TYPE_TO_COMPONENT[type];
|
||||||
|
used.add(comp);
|
||||||
|
const rest = attrsToString(attrs, ["type"]);
|
||||||
|
const size = attrs.size ? ` :size="${attrs.size}"` : "";
|
||||||
|
const open = rest ? `<el-icon ${rest}${size}>` : `<el-icon${size}>`;
|
||||||
|
return `${open}<${comp} /></el-icon>`;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (used.size && !c.includes("@element-plus/icons-vue")) {
|
||||||
|
const imports = [...used].sort().join(", ");
|
||||||
|
c = c.replace(
|
||||||
|
/(<script[^>]*>\s*\n)/,
|
||||||
|
`$1import { ${imports} } from '@element-plus/icons-vue';\n`
|
||||||
|
);
|
||||||
|
c = c.replace(/export default \{/, (m) => {
|
||||||
|
if (/components:\s*\{/.test(c)) {
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
return `${m}\n components: { ${imports} },`;
|
||||||
|
});
|
||||||
|
if (/components:\s*\{/.test(c) && !c.includes(`${[...used][0]},`)) {
|
||||||
|
c = c.replace(/components:\s*\{([^}]*)\}/, (m, inner) => {
|
||||||
|
const existing = inner.trim();
|
||||||
|
const add = [...used].filter((n) => !inner.includes(n)).join(", ");
|
||||||
|
if (!add) return m;
|
||||||
|
const merged = existing ? `${existing}, ${add}` : add;
|
||||||
|
return `components: { ${merged} }`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
let count = 0;
|
||||||
|
for (const file of walkDir(ROOT)) {
|
||||||
|
const original = fs.readFileSync(file, "utf8");
|
||||||
|
if (!/<Icon\b/.test(original)) continue;
|
||||||
|
const fixed = transform(original, file);
|
||||||
|
if (fixed !== original) {
|
||||||
|
fs.writeFileSync(file, fixed);
|
||||||
|
count++;
|
||||||
|
console.log(path.relative(ROOT, file));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`Icon replacements in ${count} files`);
|
||||||
63
buyer/scripts/replace-page.js
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* 将全局 <Page> 封装替换为原生 el-pagination
|
||||||
|
*/
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
const ROOT = path.join(__dirname, "..", "src");
|
||||||
|
|
||||||
|
function walkDir(dir, files = []) {
|
||||||
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||||
|
const full = path.join(dir, entry.name);
|
||||||
|
if (entry.isDirectory()) walkDir(full, files);
|
||||||
|
else if (entry.name.endsWith(".vue")) files.push(full);
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
function transformPage(content) {
|
||||||
|
return content.replace(
|
||||||
|
/<Page\b([^>]*?)(\/>|>(\s*)<\/Page>)/gs,
|
||||||
|
(match, attrs, close) => {
|
||||||
|
let a = attrs;
|
||||||
|
const hasTotal = /\bshow-total\b/.test(a);
|
||||||
|
const hasSizer = /\bshow-sizer\b/.test(a);
|
||||||
|
const hasElevator = /\bshow-elevator\b/.test(a);
|
||||||
|
|
||||||
|
a = a.replace(/\s+show-total\b/g, "");
|
||||||
|
a = a.replace(/\s+show-sizer\b/g, "");
|
||||||
|
a = a.replace(/\s+show-elevator\b/g, "");
|
||||||
|
a = a.replace(/:current=/g, ":current-page=");
|
||||||
|
a = a.replace(/:page-size-opts=/g, ":page-sizes=");
|
||||||
|
a = a.replace(/@change=/g, "@current-change=");
|
||||||
|
a = a.replace(/\ssize="small"/g, " small");
|
||||||
|
|
||||||
|
const layoutParts = [];
|
||||||
|
if (hasTotal) layoutParts.push("total");
|
||||||
|
if (hasSizer) layoutParts.push("sizes");
|
||||||
|
layoutParts.push("prev", "pager", "next");
|
||||||
|
if (hasElevator) layoutParts.push("jumper");
|
||||||
|
|
||||||
|
const layoutAttr = ` layout="${layoutParts.join(", ")}"`;
|
||||||
|
|
||||||
|
if (close.startsWith("/>")) {
|
||||||
|
return `<el-pagination${a}${layoutAttr} />`;
|
||||||
|
}
|
||||||
|
return `<el-pagination${a}${layoutAttr}></el-pagination>`;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let count = 0;
|
||||||
|
for (const file of walkDir(ROOT)) {
|
||||||
|
const original = fs.readFileSync(file, "utf8");
|
||||||
|
if (!/<Page\b/.test(original)) continue;
|
||||||
|
const fixed = transformPage(original);
|
||||||
|
if (fixed !== original) {
|
||||||
|
fs.writeFileSync(file, fixed);
|
||||||
|
count++;
|
||||||
|
console.log(path.relative(ROOT, file));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`Page → el-pagination in ${count} files`);
|
||||||
@@ -1,37 +1,84 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<router-view/>
|
<router-view />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
import {v4 as uuidv4} from 'uuid';
|
import { onMounted } from "vue";
|
||||||
import storage from '@/plugins/storage';
|
import { useRoute } from "vue-router";
|
||||||
import {getLogo} from '@/api/common.js';
|
import storage from "@/plugins/storage";
|
||||||
export default {
|
import { getBaseSite, getThemeSetting } from "@/api/common.js";
|
||||||
name: 'App',
|
import { fetchAndApplyTheme } from "@/utils/theme";
|
||||||
mounted () {
|
import { useAppStore } from "@/stores/app";
|
||||||
let uuid = storage.getItem('uuid');
|
|
||||||
if (!uuid) {
|
defineOptions({ name: "App" });
|
||||||
uuid = uuidv4();
|
|
||||||
storage.setItem('uuid', uuid);
|
const route = useRoute();
|
||||||
}
|
const appStore = useAppStore();
|
||||||
if (!this.Cookies.getItem('logo')) {
|
|
||||||
setTimeout(() => {
|
function applySiteInfo(data) {
|
||||||
getLogo().then(res => {
|
const expirationTime = new Date().setHours(new Date().getHours() + 1);
|
||||||
if (res.success) {
|
storage.setItem("sitelogo_expiration_time", expirationTime);
|
||||||
let logoObj = JSON.parse(res.result.settingValue)
|
storage.setItem("siteName", data.siteName);
|
||||||
this.Cookies.setItem('logo', logoObj.buyerSideLogo)
|
storage.setItem("logoImg", data.buyerSideLogo);
|
||||||
}
|
storage.setItem("siteIcon", data.buyerSideIcon);
|
||||||
})
|
appStore.setSiteName(data.siteName);
|
||||||
}, 1000)
|
appStore.setLogoImg(data.buyerSideLogo);
|
||||||
}
|
if (route.meta.title === undefined) {
|
||||||
|
window.document.title = data.siteName;
|
||||||
}
|
}
|
||||||
};
|
let link =
|
||||||
|
document.querySelector("link[rel*='icon']") ||
|
||||||
|
document.createElement("link");
|
||||||
|
link.type = "image/x-icon";
|
||||||
|
link.href = data.buyerSideIcon;
|
||||||
|
link.rel = "shortcut icon";
|
||||||
|
document.getElementsByTagName("head")[0].appendChild(link);
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
const expirationTime = storage.getItem("sitelogo_expiration_time");
|
||||||
|
const cacheValid =
|
||||||
|
expirationTime && new Date() <= new Date(Number(expirationTime));
|
||||||
|
if (cacheValid) {
|
||||||
|
applySiteInfo({
|
||||||
|
siteName: storage.getItem("siteName"),
|
||||||
|
buyerSideLogo: storage.getItem("logoImg"),
|
||||||
|
buyerSideIcon: storage.getItem("siteIcon"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
getSite();
|
||||||
|
getTheme();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSite() {
|
||||||
|
getBaseSite().then((res) => {
|
||||||
|
if (res.success && res.result.settingValue) {
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(res.result.settingValue);
|
||||||
|
applySiteInfo(data);
|
||||||
|
} catch {
|
||||||
|
// 站点配置解析失败时使用缓存
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).catch((err) => {
|
||||||
|
console.warn('获取站点配置失败', err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTheme() {
|
||||||
|
fetchAndApplyTheme(getThemeSetting).catch((err) => {
|
||||||
|
console.warn('获取主题配置失败', err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
init();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
#app{
|
#app {
|
||||||
min-height: 100%;
|
|
||||||
@include background_color($light_background_color);
|
@include background_color($light_background_color);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import request, {Method} from '@/plugins/request.js'
|
|||||||
// 获取密码状态
|
// 获取密码状态
|
||||||
export function getPwdStatus (params) {
|
export function getPwdStatus (params) {
|
||||||
return request({
|
return request({
|
||||||
url: '/buyer/members/wallet/check',
|
url: '/buyer/passport/member/wallet/check',
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
params
|
params
|
||||||
@@ -21,7 +21,7 @@ export function getPwdStatus (params) {
|
|||||||
// 设置密码
|
// 设置密码
|
||||||
export function setPwd (params) {
|
export function setPwd (params) {
|
||||||
return request({
|
return request({
|
||||||
url: '/buyer/members/wallet/set-password',
|
url: '/buyer/passport/member/wallet/set-password',
|
||||||
method: Method.POST,
|
method: Method.POST,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
data: params
|
data: params
|
||||||
@@ -31,7 +31,7 @@ export function setPwd (params) {
|
|||||||
// 设置支付密码
|
// 设置支付密码
|
||||||
export function setUpdatePwdOrdinary (params) {
|
export function setUpdatePwdOrdinary (params) {
|
||||||
return request({
|
return request({
|
||||||
url: '/buyer/members/wallet/update-password/ordinary',
|
url: '/buyer/passport/member/wallet/update-password/ordinary',
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
data: params
|
data: params
|
||||||
@@ -41,19 +41,31 @@ export function setUpdatePwdOrdinary (params) {
|
|||||||
// 修改会员资料
|
// 修改会员资料
|
||||||
export function editMemberInfo (params) {
|
export function editMemberInfo (params) {
|
||||||
return request({
|
return request({
|
||||||
url: '/buyer/members/editOwn',
|
url: '/buyer/passport/member/editOwn',
|
||||||
method: Method.PUT,
|
method: Method.PUT,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
data: params
|
data: params,
|
||||||
|
loading: false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 修改密码
|
// 修改密码
|
||||||
export function editPwd (params) {
|
export function editPwd (params) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/members/modifyPass`,
|
url: `/buyer/passport/member/modifyPass`,
|
||||||
method: Method.PUT,
|
method: Method.PUT,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
data: params
|
data: params,
|
||||||
|
loading: false,
|
||||||
|
skipMessage: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取密码状态
|
||||||
|
export function logout () {
|
||||||
|
return request({
|
||||||
|
url: '/buyer/passport/member/logout',
|
||||||
|
method: Method.POST,
|
||||||
|
needToken: true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import request, {
|
import request, {
|
||||||
Method, commonUrl
|
Method, buyerUrl
|
||||||
} from '@/plugins/request.js';
|
} from '@/plugins/request.js';
|
||||||
|
|
||||||
// 会员收货地址列表
|
// 会员收货地址列表
|
||||||
export function memberAddress () {
|
export function memberAddress () {
|
||||||
return request({
|
return request({
|
||||||
url: '/buyer/memberAddress',
|
url: '/buyer/member/address',
|
||||||
needToken: true,
|
needToken: true,
|
||||||
method: Method.GET
|
method: Method.GET
|
||||||
});
|
});
|
||||||
@@ -14,36 +14,39 @@ export function memberAddress () {
|
|||||||
// 添加收货地址
|
// 添加收货地址
|
||||||
export function newMemberAddress (params) {
|
export function newMemberAddress (params) {
|
||||||
return request({
|
return request({
|
||||||
url: '/buyer/memberAddress',
|
url: '/buyer/member/address',
|
||||||
needToken: true,
|
needToken: true,
|
||||||
method: Method.POST,
|
method: Method.POST,
|
||||||
data: params
|
data: params,
|
||||||
|
loading: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 编辑收货地址
|
// 编辑收货地址
|
||||||
export function editMemberAddress (params) {
|
export function editMemberAddress (params) {
|
||||||
return request({
|
return request({
|
||||||
url: '/buyer/memberAddress',
|
url: '/buyer/member/address',
|
||||||
needToken: true,
|
needToken: true,
|
||||||
method: Method.PUT,
|
method: Method.PUT,
|
||||||
params
|
params,
|
||||||
|
loading: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除收货地址
|
// 删除收货地址
|
||||||
export function delMemberAddress (id) {
|
export function delMemberAddress (id) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/memberAddress/delById/${id}`,
|
url: `/buyer/member/address/delById/${id}`,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
method: Method.DELETE
|
method: Method.DELETE,
|
||||||
|
loading: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据id获取会员地址详情
|
// 根据id获取会员地址详情
|
||||||
export function getAddrDetail (id) {
|
export function getAddrDetail (id) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/memberAddress/get/${id}`,
|
url: `/buyer/member/address/get/${id}`,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
method: Method.GET
|
method: Method.GET
|
||||||
});
|
});
|
||||||
@@ -52,7 +55,7 @@ export function getAddrDetail (id) {
|
|||||||
// 传给后台citycode 获取城市街道等id
|
// 传给后台citycode 获取城市街道等id
|
||||||
export function handleRegion (params) {
|
export function handleRegion (params) {
|
||||||
return request({
|
return request({
|
||||||
url: `${commonUrl}/common/region/region`,
|
url: `${buyerUrl}/buyer/common/region/region`,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
params
|
params
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ export function cartGoodsAll () {
|
|||||||
return request({
|
return request({
|
||||||
url: '/buyer/trade/carts/all',
|
url: '/buyer/trade/carts/all',
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: true
|
needToken: true,
|
||||||
|
loading: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +65,7 @@ export function addCartGoods (params) {
|
|||||||
/**
|
/**
|
||||||
* 创建交易
|
* 创建交易
|
||||||
* @param client 客户端:H5/移动端 PC/PC端,WECHAT_MP/小程序端,APP/移动应用端
|
* @param client 客户端:H5/移动端 PC/PC端,WECHAT_MP/小程序端,APP/移动应用端
|
||||||
* @param way 购物车购买:CART/立即购买:BUY_NOW / 积分购买:POINT
|
* @param way 购物车:CART / 立即购买:BUY_NOW / 积分:POINTS / 拼团:PINTUAN / 砍价:KANJIA
|
||||||
* @param remark 备注 非必填
|
* @param remark 备注 非必填
|
||||||
*/
|
*/
|
||||||
export function createTrade (data) {
|
export function createTrade (data) {
|
||||||
@@ -80,7 +81,7 @@ export function createTrade (data) {
|
|||||||
/**
|
/**
|
||||||
* 选择优惠券
|
* 选择优惠券
|
||||||
* @param memberCouponId 优惠券id
|
* @param memberCouponId 优惠券id
|
||||||
* @param way 购物车购买:CART/立即购买:BUY_NOW/ 积分购买:POINT
|
* @param way 购物车:CART / 立即购买:BUY_NOW / 积分:POINTS
|
||||||
* @param used 使用true 弃用 false
|
* @param used 使用true 弃用 false
|
||||||
*/
|
*/
|
||||||
export function selectCoupon (params) {
|
export function selectCoupon (params) {
|
||||||
@@ -92,6 +93,21 @@ export function selectCoupon (params) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 选择礼品卡
|
||||||
|
* @param way 购物车:CART / 立即购买:BUY_NOW / 拼团:PINTUAN / 积分:POINTS / 砍价:KANJIA
|
||||||
|
* @param credentialId 礼品卡凭证 id;used=false 且不传则清空全部
|
||||||
|
* @param used 使用 true / 弃用 false
|
||||||
|
*/
|
||||||
|
export function selectGiftCard (params) {
|
||||||
|
return request({
|
||||||
|
url: '/buyer/trade/carts/select/giftCard',
|
||||||
|
method: Method.GET,
|
||||||
|
needToken: true,
|
||||||
|
params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 可用优惠券数量
|
* 可用优惠券数量
|
||||||
*/
|
*/
|
||||||
@@ -212,3 +228,52 @@ export function receiptSelect (params) {
|
|||||||
params
|
params
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取全部配送方式
|
||||||
|
*/
|
||||||
|
export function shippingMethodList(params) {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/trade/carts/shippingMethodList`,
|
||||||
|
method: Method.GET,
|
||||||
|
needToken: true,
|
||||||
|
params: params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取全部配送方式
|
||||||
|
*/
|
||||||
|
export function storeAddressList(params) {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/store/address/shippingMethodList`,
|
||||||
|
method: Method.GET,
|
||||||
|
needToken: true,
|
||||||
|
params: params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置自提地址ID
|
||||||
|
* @param addressId
|
||||||
|
*/
|
||||||
|
export function setStoreAddressId(storeAddressId,way) {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/trade/carts/storeAddress?storeAddressId=${storeAddressId}&way=${way}`,
|
||||||
|
method: Method.GET,
|
||||||
|
needToken: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提交配送方式
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export function setShipMethod(params) {
|
||||||
|
return request({
|
||||||
|
url: "/buyer/trade/carts/shippingMethod",
|
||||||
|
method: Method.PUT,
|
||||||
|
needToken: true,
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import request, {Method, commonUrl} from '@/plugins/request.js';
|
import request, {Method, buyerUrl} from '@/plugins/request.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取拼图验证
|
* 获取拼图验证
|
||||||
*/
|
*/
|
||||||
export function getVerifyImg (verificationEnums) {
|
export function getVerifyImg (verificationEnums) {
|
||||||
return request({
|
return request({
|
||||||
url: `${commonUrl}/common/slider/${verificationEnums}`,
|
url: `${buyerUrl}/buyer/common/slider/${verificationEnums}`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: false
|
needToken: false
|
||||||
});
|
});
|
||||||
@@ -15,7 +15,7 @@ export function getVerifyImg (verificationEnums) {
|
|||||||
*/
|
*/
|
||||||
export function postVerifyImg (params) {
|
export function postVerifyImg (params) {
|
||||||
return request({
|
return request({
|
||||||
url: `${commonUrl}/common/slider/${params.verificationEnums}`,
|
url: `${buyerUrl}/buyer/common/slider/${params.verificationEnums}`,
|
||||||
method: Method.POST,
|
method: Method.POST,
|
||||||
needToken: false,
|
needToken: false,
|
||||||
params
|
params
|
||||||
@@ -26,28 +26,20 @@ export function postVerifyImg (params) {
|
|||||||
*/
|
*/
|
||||||
export function sendSms (params) {
|
export function sendSms (params) {
|
||||||
return request({
|
return request({
|
||||||
url: `${commonUrl}/common/sms/${params.verificationEnums}/${params.mobile}`,
|
url: `${buyerUrl}/buyer/common/sms/${params.verificationEnums}/${params.mobile}`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: false,
|
needToken: false,
|
||||||
params
|
params
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* 发送短信验证码
|
|
||||||
*/
|
|
||||||
export function getLogo () {
|
|
||||||
return request({
|
|
||||||
url: `${commonUrl}/common/logo`,
|
|
||||||
method: Method.GET,
|
|
||||||
needToken: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// 地区数据,用于三级联动
|
// 地区数据,用于三级联动
|
||||||
export function getRegion (id) {
|
export function getRegion (id) {
|
||||||
return request({
|
return request({
|
||||||
url: `${commonUrl}/common/region/item/${id}`,
|
url: `${buyerUrl}/buyer/common/region/item/${id}`,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
method: Method.GET
|
method: Method.GET,
|
||||||
|
loading: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +49,7 @@ export function getRegion (id) {
|
|||||||
*/
|
*/
|
||||||
export function articleList (params) {
|
export function articleList (params) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/article`,
|
url: `/buyer/other/article`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
params
|
params
|
||||||
});
|
});
|
||||||
@@ -69,7 +61,7 @@ export function articleList (params) {
|
|||||||
*/
|
*/
|
||||||
export function articleCateList () {
|
export function articleCateList () {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/article/articleCategory/list`,
|
url: `/buyer/other/article/articleCategory/list`,
|
||||||
method: Method.GET
|
method: Method.GET
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -77,7 +69,37 @@ export function articleCateList () {
|
|||||||
// 通过id获取文章
|
// 通过id获取文章
|
||||||
export function articleDetail (id) {
|
export function articleDetail (id) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/article/get/${id}`,
|
url: `/buyer/other/article/get/${id}`,
|
||||||
method: Method.GET
|
method: Method.GET
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 获取IM接口前缀
|
||||||
|
export function getIMDetail () {
|
||||||
|
return request({
|
||||||
|
url: `${buyerUrl}/buyer/common/IM`,
|
||||||
|
method: Method.GET
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//获取图片logo
|
||||||
|
export function getBaseSite(){
|
||||||
|
return request ({
|
||||||
|
url:`${buyerUrl}/buyer/common/site`,
|
||||||
|
method: Method.GET,
|
||||||
|
needToken: false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取主题色配置
|
||||||
|
export function getThemeSetting() {
|
||||||
|
return request({
|
||||||
|
url: `${buyerUrl}/buyer/common/site/theme`,
|
||||||
|
method: Method.GET,
|
||||||
|
needToken: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,9 +5,10 @@ import request, {
|
|||||||
// 商品列表
|
// 商品列表
|
||||||
export function goodsList (params) {
|
export function goodsList (params) {
|
||||||
return request({
|
return request({
|
||||||
url: '/buyer/goods/es',
|
url: '/buyer/goods/goods/search',
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: false,
|
needToken: false,
|
||||||
|
optionalToken: true,
|
||||||
params
|
params
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -15,9 +16,10 @@ export function goodsList (params) {
|
|||||||
// 商品分类 筛选条件 品牌, 尺寸等
|
// 商品分类 筛选条件 品牌, 尺寸等
|
||||||
export function filterList (params) {
|
export function filterList (params) {
|
||||||
return request({
|
return request({
|
||||||
url: '/buyer/goods/es/related',
|
url: '/buyer/goods/goods/search/related',
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: false,
|
needToken: false,
|
||||||
|
optionalToken: true,
|
||||||
params
|
params
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -25,18 +27,19 @@ export function filterList (params) {
|
|||||||
// id获取商品详情
|
// id获取商品详情
|
||||||
export function goodsDetail (goodsId) {
|
export function goodsDetail (goodsId) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/goods/get/${goodsId}`,
|
url: `/buyer/goods/goods/get/${goodsId}`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: false
|
needToken: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// id获取商品Sku详情
|
// id获取商品Sku详情(支持未登录浏览,登录后可选携带 token)
|
||||||
export function goodsSkuDetail (params) {
|
export function goodsSkuDetail (params) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/goods/sku/${params.goodsId}/${params.skuId}`,
|
url: `/buyer/goods/goods/sku/${params.goodsId}/${params.skuId}`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: true,
|
needToken: false,
|
||||||
|
optionalToken: true,
|
||||||
params
|
params
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -44,7 +47,7 @@ export function goodsSkuDetail (params) {
|
|||||||
// 获取所有商品分类
|
// 获取所有商品分类
|
||||||
export function getCategory (parentId) {
|
export function getCategory (parentId) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/category/get/${parentId}`,
|
url: `/buyer/goods/category/get/${parentId}`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: false
|
needToken: false
|
||||||
});
|
});
|
||||||
@@ -60,12 +63,12 @@ export function pintuanMembers (pintuanId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Number} start 搜索起始下标
|
* 获取搜索热词
|
||||||
* @param {Number} end 搜索结束下标
|
* @param {Number} count 获取搜索热词数量
|
||||||
*/
|
*/
|
||||||
export function hotWords (params) {
|
export function hotWords (params) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/goods/hot-words`,
|
url: `/buyer/goods/goods/hot-words`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: false,
|
needToken: false,
|
||||||
params
|
params
|
||||||
|
|||||||
@@ -1,13 +1,44 @@
|
|||||||
import request, {Method} from '@/plugins/request.js'
|
import request, { Method } from "@/plugins/request.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取首页专题数据
|
||||||
|
*/
|
||||||
|
export function getTopicData(id) {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/other/pageData/get/${id}`,
|
||||||
|
method: Method.GET,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 获取首页楼层装修数据
|
// 获取首页楼层装修数据
|
||||||
export function indexData (params) {
|
export function indexData(params) {
|
||||||
return request({
|
return request({
|
||||||
url: '/buyer/pageData/getIndex',
|
url: "/buyer/other/pageData/getIndex",
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: false,
|
needToken: false,
|
||||||
params
|
params,
|
||||||
})
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取自动发券
|
||||||
|
export function getAutoCoup(){
|
||||||
|
return request({
|
||||||
|
url: "/buyer/promotion/coupon/activity",
|
||||||
|
method: Method.GET,
|
||||||
|
needToken: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取店铺楼层数据
|
||||||
|
*/
|
||||||
|
export function getFloorStoreData(params) {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/other/pageData?pageClientType=PC`,
|
||||||
|
method: "get",
|
||||||
|
params,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -15,21 +46,36 @@ export function indexData (params) {
|
|||||||
* @param pageClientType 客户端类型,可用值:PC,H5,WECHAT_MP,APP
|
* @param pageClientType 客户端类型,可用值:PC,H5,WECHAT_MP,APP
|
||||||
* @param pageType 页面类型,可用值:INDEX,STORE,SPECIAL
|
* @param pageType 页面类型,可用值:INDEX,STORE,SPECIAL
|
||||||
*/
|
*/
|
||||||
export function pageData (params) {
|
export function pageData(params) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/pageData`,
|
url: `/buyer/other/pageData`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: false,
|
needToken: false,
|
||||||
params
|
params,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 刷新token
|
* 刷新token
|
||||||
*/
|
*/
|
||||||
export function handleRefreshToken (token) {
|
export function handleRefreshToken(token) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/members/refresh/${token}`,
|
url: `/buyer/passport/member/refresh/${token}`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: false
|
needToken: false,
|
||||||
})
|
// 刷新令牌请求自身不再进入 401/403 刷新分支,避免拦截器递归死锁;失败也不弹全局错误提示
|
||||||
|
skipAuthHandler: true,
|
||||||
|
skipMessage: true,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * 获取店铺楼层数据
|
||||||
|
// */
|
||||||
|
// export function getFloorStoreData(params) {
|
||||||
|
// return request({
|
||||||
|
// url: `/buyer/other/pageData?pageClientType=PC`,
|
||||||
|
// method: "get",
|
||||||
|
// params,
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import request, {Method, buyerUrl} from '@/plugins/request.js';
|
|||||||
*/
|
*/
|
||||||
export function regist (params) {
|
export function regist (params) {
|
||||||
return request({
|
return request({
|
||||||
url: '/buyer/members/register',
|
url: '/buyer/passport/member/register',
|
||||||
method: Method.POST,
|
method: Method.POST,
|
||||||
needToken: false,
|
needToken: false,
|
||||||
data: params
|
data: params
|
||||||
@@ -18,7 +18,7 @@ export function regist (params) {
|
|||||||
*/
|
*/
|
||||||
export function login (params) {
|
export function login (params) {
|
||||||
return request({
|
return request({
|
||||||
url: '/buyer/members/userLogin',
|
url: '/buyer/passport/member/userLogin',
|
||||||
method: Method.POST,
|
method: Method.POST,
|
||||||
needToken: false,
|
needToken: false,
|
||||||
data: params,
|
data: params,
|
||||||
@@ -31,7 +31,7 @@ export function login (params) {
|
|||||||
*/
|
*/
|
||||||
export function smsLogin (params) {
|
export function smsLogin (params) {
|
||||||
return request({
|
return request({
|
||||||
url: '/buyer/members/smsLogin',
|
url: '/buyer/passport/member/smsLogin',
|
||||||
method: Method.POST,
|
method: Method.POST,
|
||||||
needToken: false,
|
needToken: false,
|
||||||
data: params,
|
data: params,
|
||||||
@@ -44,7 +44,7 @@ export function smsLogin (params) {
|
|||||||
*/
|
*/
|
||||||
export function getMemberMsg (params) {
|
export function getMemberMsg (params) {
|
||||||
return request({
|
return request({
|
||||||
url: '/buyer/members',
|
url: '/buyer/passport/member',
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
params
|
params
|
||||||
@@ -55,7 +55,7 @@ export function getMemberMsg (params) {
|
|||||||
* 第三方登录 支付宝,微博,qq,微信
|
* 第三方登录 支付宝,微博,qq,微信
|
||||||
*/
|
*/
|
||||||
export function webLogin (type) {
|
export function webLogin (type) {
|
||||||
window.open(`${buyerUrl}/buyer/connect/login/web/${type}`, 'blank');
|
window.open(`${buyerUrl}/buyer/passport/connect/connect/login/web/${type}`, 'blank');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -63,18 +63,44 @@ export function webLogin (type) {
|
|||||||
*/
|
*/
|
||||||
export function loginCallback (uuid) {
|
export function loginCallback (uuid) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/connect/result?state=${uuid}`,
|
url: `/buyer/passport/connect/connect/result?state=${uuid}`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: false
|
needToken: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getThirdAccountBindList () {
|
||||||
|
return request({
|
||||||
|
url: '/buyer/passport/connect/bind/list',
|
||||||
|
method: Method.GET,
|
||||||
|
needToken: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function bindThirdAccount (data) {
|
||||||
|
return request({
|
||||||
|
url: '/buyer/passport/connect/bind',
|
||||||
|
method: Method.POST,
|
||||||
|
needToken: true,
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function unbindThirdAccount (data) {
|
||||||
|
return request({
|
||||||
|
url: '/buyer/passport/connect/bind/unbind',
|
||||||
|
method: Method.POST,
|
||||||
|
needToken: true,
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 忘记密码 验证手机验证码
|
* 忘记密码 验证手机验证码
|
||||||
*/
|
*/
|
||||||
export function validateCode (params) {
|
export function validateCode (params) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/members/resetByMobile`,
|
url: `/buyer/passport/member/resetByMobile`,
|
||||||
method: Method.POST,
|
method: Method.POST,
|
||||||
needToken: false,
|
needToken: false,
|
||||||
params
|
params
|
||||||
@@ -86,9 +112,40 @@ export function validateCode (params) {
|
|||||||
*/
|
*/
|
||||||
export function resetPassword (params) {
|
export function resetPassword (params) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/members/resetPassword`,
|
url: `/buyer/passport/member/resetPassword`,
|
||||||
method: Method.POST,
|
method: Method.POST,
|
||||||
needToken: false,
|
needToken: false,
|
||||||
params
|
params
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getSCLoginCode(params) {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/passport/member/pc_session`,
|
||||||
|
method: Method.POST,
|
||||||
|
needToken: false,
|
||||||
|
loading: false,
|
||||||
|
params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
export function sCLogin(token,params) {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/passport/member/session_login/`+token,
|
||||||
|
method: Method.POST,
|
||||||
|
needToken: false,
|
||||||
|
loading: false,
|
||||||
|
skipMessage: true,
|
||||||
|
// 长轮询后端最长挂起 20s,需大于该值,避免 axios 10s 默认超时把二维码请求掐断
|
||||||
|
timeout: 25000,
|
||||||
|
params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getWechatH5QrCode (params) {
|
||||||
|
return request({
|
||||||
|
url: '/buyer/other/wechat/h5/qrcode',
|
||||||
|
method: Method.GET,
|
||||||
|
needToken: true,
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import request, {Method} from '@/plugins/request.js';
|
|||||||
// 查询账户余额
|
// 查询账户余额
|
||||||
export function getMembersWallet () {
|
export function getMembersWallet () {
|
||||||
return request({
|
return request({
|
||||||
url: '/buyer/members/wallet',
|
url: '/buyer/wallet/wallet',
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: true
|
needToken: true
|
||||||
});
|
});
|
||||||
@@ -22,7 +22,7 @@ export function getDepositLog (params) {
|
|||||||
// 查询充值记录
|
// 查询充值记录
|
||||||
export function getRecharge (params) {
|
export function getRecharge (params) {
|
||||||
return request({
|
return request({
|
||||||
url: '/buyer/member/recharge',
|
url: '/buyer/wallet/recharge',
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
params
|
params
|
||||||
@@ -52,14 +52,14 @@ export function recharge (params) {
|
|||||||
// 提现
|
// 提现
|
||||||
export function withdrawalApply (params) {
|
export function withdrawalApply (params) {
|
||||||
return request({
|
return request({
|
||||||
url: '/buyer/members/wallet/withdrawal',
|
url: '/buyer/wallet/wallet/withdrawal',
|
||||||
method: Method.POST,
|
method: Method.POST,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
data: params
|
data: params
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 收藏商品、店铺
|
// 收藏商品
|
||||||
export function collectGoods (type, id) {
|
export function collectGoods (type, id) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/member/collection/add/${type}/${id}`,
|
url: `/buyer/member/collection/add/${type}/${id}`,
|
||||||
@@ -68,7 +68,16 @@ export function collectGoods (type, id) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 取消 收藏商品、店铺
|
// 收藏店铺
|
||||||
|
export function collectStore (type, id) {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/member/storeCollection/add/${type}/${id}`,
|
||||||
|
method: Method.POST,
|
||||||
|
needToken: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消 收藏商品
|
||||||
export function cancelCollect (type, id) {
|
export function cancelCollect (type, id) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/member/collection/delete/${type}/${id}`,
|
url: `/buyer/member/collection/delete/${type}/${id}`,
|
||||||
@@ -77,16 +86,38 @@ export function cancelCollect (type, id) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查看是否收藏
|
// 取消 收藏店铺
|
||||||
export function isCollection (type, goodsId) {
|
export function cancelStoreCollect (type, id) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/member/collection/isCollection/${type}/${goodsId}`,
|
url: `/buyer/member/storeCollection/delete/${type}/${id}`,
|
||||||
method: Method.GET,
|
method: Method.DELETE,
|
||||||
needToken: true
|
needToken: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 会员收藏列表
|
// 查看是否收藏商品(后台查询,token 失效时静默失败,不弹全局登录框)
|
||||||
|
export function isCollection (type, goodsId) {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/member/collection/isCollection/${type}/${goodsId}`,
|
||||||
|
method: Method.GET,
|
||||||
|
needToken: true,
|
||||||
|
skipAuthHandler: true,
|
||||||
|
skipMessage: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查看是否收藏店铺(后台查询,token 失效时静默失败,不弹全局登录框)
|
||||||
|
export function isStoreCollection (type, goodsId) {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/member/storeCollection/isCollection/${type}/${goodsId}`,
|
||||||
|
method: Method.GET,
|
||||||
|
needToken: true,
|
||||||
|
skipAuthHandler: true,
|
||||||
|
skipMessage: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 会员收藏商品列表
|
||||||
export function collectList (params) {
|
export function collectList (params) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/member/collection/${params.type}`,
|
url: `/buyer/member/collection/${params.type}`,
|
||||||
@@ -96,39 +127,53 @@ export function collectList (params) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 单个商品评价
|
// 会员收藏店铺列表
|
||||||
export function goodsComment (params) {
|
export function storeCollectList (params) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/memberEvaluation/${params.goodsId}/goodsEvaluation`,
|
url: `/buyer/member/storeCollection/${params.type}`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: false,
|
needToken: true,
|
||||||
params
|
params
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 商品各评价类别数量
|
// 单个商品评价(需登录;token 失效时静默失败,不弹全局登录框)
|
||||||
|
export function goodsComment (params) {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/member/evaluation/${params.goodsId}/goodsEvaluation`,
|
||||||
|
method: Method.GET,
|
||||||
|
needToken: true,
|
||||||
|
skipAuthHandler: true,
|
||||||
|
skipMessage: true,
|
||||||
|
params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 商品各评价类别数量(需登录;token 失效时静默失败,不弹全局登录框)
|
||||||
export function goodsCommentNum (goodsId) {
|
export function goodsCommentNum (goodsId) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/memberEvaluation/${goodsId}/evaluationNumber`,
|
url: `/buyer/member/evaluation/${goodsId}/evaluationNumber`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: false
|
needToken: true,
|
||||||
|
skipAuthHandler: true,
|
||||||
|
skipMessage: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加会员评价
|
// 添加会员评价
|
||||||
export function addEvaluation (params) {
|
export function addEvaluation (params) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/memberEvaluation`,
|
url: `/buyer/member/evaluation`,
|
||||||
method: Method.POST,
|
method: Method.POST,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
params
|
data: params
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 会员评价详情
|
// 会员评价详情
|
||||||
export function evaluationDetail (id) {
|
export function evaluationDetail (id) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/memberEvaluation/get/${id}`,
|
url: `/buyer/member/evaluation/get/${id}`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: true
|
needToken: true
|
||||||
});
|
});
|
||||||
@@ -143,6 +188,15 @@ export function receiptList () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 发票详情
|
||||||
|
export function receiptDetail (id) {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/trade/receipt/${id}`,
|
||||||
|
method: Method.GET,
|
||||||
|
needToken: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 保存发票信息
|
// 保存发票信息
|
||||||
export function saveReceipt (params) {
|
export function saveReceipt (params) {
|
||||||
return request({
|
return request({
|
||||||
@@ -159,6 +213,7 @@ export function couponList (params) {
|
|||||||
url: `/buyer/promotion/coupon`,
|
url: `/buyer/promotion/coupon`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
|
loading: false,
|
||||||
params
|
params
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -195,7 +250,7 @@ export function receiveCoupon (couponId) {
|
|||||||
// 获取申请售后列表
|
// 获取申请售后列表
|
||||||
export function afterSaleList (params) {
|
export function afterSaleList (params) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/afterSale/page`,
|
url: `/buyer/order/afterSale/page`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
params
|
params
|
||||||
@@ -205,7 +260,7 @@ export function afterSaleList (params) {
|
|||||||
// 获取申请售后页面信息
|
// 获取申请售后页面信息
|
||||||
export function afterSaleInfo (sn) {
|
export function afterSaleInfo (sn) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/afterSale/applyAfterSaleInfo/${sn}`,
|
url: `/buyer/order/afterSale/applyAfterSaleInfo/${sn}`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: true
|
needToken: true
|
||||||
});
|
});
|
||||||
@@ -214,7 +269,7 @@ export function afterSaleInfo (sn) {
|
|||||||
// 获取申请售后、投诉原因
|
// 获取申请售后、投诉原因
|
||||||
export function afterSaleReason (serviceType) {
|
export function afterSaleReason (serviceType) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/afterSale/get/afterSaleReason/${serviceType}`,
|
url: `/buyer/order/afterSale/get/afterSaleReason/${serviceType}`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: true
|
needToken: true
|
||||||
});
|
});
|
||||||
@@ -222,7 +277,7 @@ export function afterSaleReason (serviceType) {
|
|||||||
// 获取申请售后详情
|
// 获取申请售后详情
|
||||||
export function afterSaleDetail (sn) {
|
export function afterSaleDetail (sn) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/afterSale/get/${sn}`,
|
url: `/buyer/order/afterSale/get/${sn}`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: true
|
needToken: true
|
||||||
});
|
});
|
||||||
@@ -230,7 +285,7 @@ export function afterSaleDetail (sn) {
|
|||||||
// 售后日志
|
// 售后日志
|
||||||
export function afterSaleLog (sn) {
|
export function afterSaleLog (sn) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/afterSale/get/getAfterSaleLog/${sn}`,
|
url: `/buyer/order/afterSale/get/getAfterSaleLog/${sn}`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: true
|
needToken: true
|
||||||
});
|
});
|
||||||
@@ -239,7 +294,7 @@ export function afterSaleLog (sn) {
|
|||||||
// 申请售后
|
// 申请售后
|
||||||
export function applyAfterSale (params) {
|
export function applyAfterSale (params) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/afterSale/save/${params.orderItemSn}`,
|
url: `/buyer/order/afterSale/save/${params.orderItemSn}`,
|
||||||
method: Method.POST,
|
method: Method.POST,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
params
|
params
|
||||||
@@ -249,16 +304,17 @@ export function applyAfterSale (params) {
|
|||||||
// 取消售后申请
|
// 取消售后申请
|
||||||
export function cancelAfterSale (afterSaleSn) {
|
export function cancelAfterSale (afterSaleSn) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/afterSale/cancel/${afterSaleSn}`,
|
url: `/buyer/order/afterSale/cancel/${afterSaleSn}`,
|
||||||
method: Method.POST,
|
method: Method.POST,
|
||||||
needToken: true
|
needToken: true,
|
||||||
|
loading: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 投诉商品
|
// 投诉商品
|
||||||
export function handleComplain (data) {
|
export function handleComplain (data) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/complain`,
|
url: `/buyer/order/complain`,
|
||||||
method: Method.POST,
|
method: Method.POST,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
data
|
data
|
||||||
@@ -267,7 +323,7 @@ export function handleComplain (data) {
|
|||||||
// 分页获取我的投诉列表
|
// 分页获取我的投诉列表
|
||||||
export function complainList (params) {
|
export function complainList (params) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/complain`,
|
url: `/buyer/order/complain`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
params
|
params
|
||||||
@@ -279,7 +335,7 @@ export function complainList (params) {
|
|||||||
*/
|
*/
|
||||||
export function getComplainDetail (id) {
|
export function getComplainDetail (id) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/complain/${id}`,
|
url: `/buyer/order/complain/${id}`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: true
|
needToken: true
|
||||||
});
|
});
|
||||||
@@ -290,97 +346,12 @@ export function getComplainDetail (id) {
|
|||||||
*/
|
*/
|
||||||
export function clearComplain (id) {
|
export function clearComplain (id) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/complain/status/${id}`,
|
url: `/buyer/order/complain/status/${id}`,
|
||||||
method: Method.PUT,
|
method: Method.PUT,
|
||||||
needToken: true
|
needToken: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取当前会员分销信息
|
|
||||||
*/
|
|
||||||
export function distribution () {
|
|
||||||
return request({
|
|
||||||
url: `/buyer/distribution`,
|
|
||||||
method: Method.GET,
|
|
||||||
needToken: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 申请成为分销商
|
|
||||||
* @param idNumber 身份证号
|
|
||||||
* @param name 名字
|
|
||||||
*/
|
|
||||||
export function applyDistribution (params) {
|
|
||||||
return request({
|
|
||||||
url: `/buyer/distribution`,
|
|
||||||
method: Method.POST,
|
|
||||||
needToken: true,
|
|
||||||
params
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取分销商订单列表
|
|
||||||
*/
|
|
||||||
export function getDistOrderList (params) {
|
|
||||||
return request({
|
|
||||||
url: `/buyer/distribution/distributionOrder`,
|
|
||||||
method: Method.GET,
|
|
||||||
needToken: true,
|
|
||||||
params
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取分销商商品列表
|
|
||||||
*/
|
|
||||||
export function getDistGoodsList (params) {
|
|
||||||
return request({
|
|
||||||
url: `/buyer/distributionGoods`,
|
|
||||||
method: Method.GET,
|
|
||||||
needToken: true,
|
|
||||||
params
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 选择分销商品
|
|
||||||
* @param distributionGoodsId 分销商品id
|
|
||||||
*/
|
|
||||||
export function selectDistGoods (distributionGoodsId) {
|
|
||||||
return request({
|
|
||||||
url: `/buyer/distributionGoods/checked/${distributionGoodsId}`,
|
|
||||||
method: Method.GET,
|
|
||||||
needToken: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 分销商提现历史
|
|
||||||
*/
|
|
||||||
export function distCashHistory (params) {
|
|
||||||
return request({
|
|
||||||
url: `/buyer/distribution/cash`,
|
|
||||||
method: Method.GET,
|
|
||||||
needToken: true,
|
|
||||||
params
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 分销商提现
|
|
||||||
*/
|
|
||||||
export function distCash (params) {
|
|
||||||
return request({
|
|
||||||
url: `/buyer/distribution/cash`,
|
|
||||||
method: Method.POST,
|
|
||||||
needToken: true,
|
|
||||||
params
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 我的足迹
|
* 我的足迹
|
||||||
* @param {Number} pageNumber 页码
|
* @param {Number} pageNumber 页码
|
||||||
@@ -388,7 +359,7 @@ export function distCash (params) {
|
|||||||
*/
|
*/
|
||||||
export function tracksList (params) {
|
export function tracksList (params) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/footprint`,
|
url: `/buyer/member/footprint`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
params
|
params
|
||||||
@@ -400,7 +371,7 @@ export function tracksList (params) {
|
|||||||
*/
|
*/
|
||||||
export function clearTracks () {
|
export function clearTracks () {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/footprint`,
|
url: `/buyer/member/footprint`,
|
||||||
method: Method.DELETE,
|
method: Method.DELETE,
|
||||||
needToken: true
|
needToken: true
|
||||||
});
|
});
|
||||||
@@ -412,7 +383,7 @@ export function clearTracks () {
|
|||||||
*/
|
*/
|
||||||
export function clearTracksById (ids) {
|
export function clearTracksById (ids) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/footprint/delByIds/${ids}`,
|
url: `/buyer/member/footprint/delByIds/${ids}`,
|
||||||
method: Method.DELETE,
|
method: Method.DELETE,
|
||||||
needToken: true
|
needToken: true
|
||||||
});
|
});
|
||||||
@@ -441,13 +412,38 @@ export function memberPointHistory (params) {
|
|||||||
params
|
params
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function memberGradeCurrent (params) {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/member/memberGrade/current`,
|
||||||
|
method: Method.GET,
|
||||||
|
needToken: true,
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function memberGradeRules () {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/member/memberGrade/rules`,
|
||||||
|
method: Method.GET,
|
||||||
|
needToken: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function memberGradeList () {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/member/memberGrade/list`,
|
||||||
|
method: Method.GET,
|
||||||
|
needToken: true
|
||||||
|
})
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 分页获取会员站内信
|
* 分页获取会员站内信
|
||||||
* @param {Object} params 请求参数,包括pageNumber、pageSize、status
|
* @param {Object} params 请求参数,包括pageNumber、pageSize、status
|
||||||
*/
|
*/
|
||||||
export function memberMsgList (params) {
|
export function memberMsgList (params) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/member/message`,
|
url: `/buyer/message/member`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
params
|
params
|
||||||
@@ -457,9 +453,19 @@ export function memberMsgList (params) {
|
|||||||
* 设置消息为已读
|
* 设置消息为已读
|
||||||
* @param {String} messageId 消息id
|
* @param {String} messageId 消息id
|
||||||
*/
|
*/
|
||||||
export function readMemberMsg (id) {
|
|
||||||
|
export function getMemberMessage (id) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/member/message/${id}`,
|
url: `/buyer/message/member/${id}`,
|
||||||
|
method: Method.GET,
|
||||||
|
needToken: true,
|
||||||
|
skipMessage: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function readMemberMsg (id) {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/message/member/${id}`,
|
||||||
method: Method.PUT,
|
method: Method.PUT,
|
||||||
needToken: true
|
needToken: true
|
||||||
});
|
});
|
||||||
@@ -468,10 +474,22 @@ export function memberMsgList (params) {
|
|||||||
* 删除会员消息
|
* 删除会员消息
|
||||||
* @param {String} messageId 消息id
|
* @param {String} messageId 消息id
|
||||||
*/
|
*/
|
||||||
export function delMemberMsg (id) {
|
export function delMemberMsg (id) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/member/message/${id}`,
|
url: `/buyer/message/member/${id}`,
|
||||||
method: Method.DELETE,
|
method: Method.DELETE,
|
||||||
needToken: true
|
needToken: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定分销
|
||||||
|
* @param distributionId 商品分销ID
|
||||||
|
*/
|
||||||
|
export function getGoodsDistribution (distributionId) {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/distribution/distribution/bindingDistribution/${distributionId}`,
|
||||||
|
method: Method.GET,
|
||||||
|
needToken: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import request, {
|
|||||||
// 查询会员订单列表
|
// 查询会员订单列表
|
||||||
export function getOrderList (params) {
|
export function getOrderList (params) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/orders`,
|
url: `/buyer/order/order`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
params
|
params
|
||||||
@@ -18,7 +18,7 @@ export function getOrderList (params) {
|
|||||||
*/
|
*/
|
||||||
export function orderDetail (orderSn) {
|
export function orderDetail (orderSn) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/orders/${orderSn}`,
|
url: `/buyer/order/order/${orderSn}`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: true
|
needToken: true
|
||||||
});
|
});
|
||||||
@@ -31,7 +31,7 @@ export function orderDetail (orderSn) {
|
|||||||
*/
|
*/
|
||||||
export function cancelOrder (params) {
|
export function cancelOrder (params) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/orders/${params.orderSn}/cancel`,
|
url: `/buyer/order/order/${params.orderSn}/cancel`,
|
||||||
method: Method.POST,
|
method: Method.POST,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
params
|
params
|
||||||
@@ -44,7 +44,7 @@ export function cancelOrder (params) {
|
|||||||
*/
|
*/
|
||||||
export function delOrder (orderSn) {
|
export function delOrder (orderSn) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/orders/${orderSn}`,
|
url: `/buyer/order/order/${orderSn}`,
|
||||||
method: Method.DELETE,
|
method: Method.DELETE,
|
||||||
needToken: true
|
needToken: true
|
||||||
});
|
});
|
||||||
@@ -56,7 +56,7 @@ export function delOrder (orderSn) {
|
|||||||
*/
|
*/
|
||||||
export function sureReceived (orderSn) {
|
export function sureReceived (orderSn) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/orders/${orderSn}/receiving`,
|
url: `/buyer/order/order/${orderSn}/receiving`,
|
||||||
method: Method.POST,
|
method: Method.POST,
|
||||||
needToken: true
|
needToken: true
|
||||||
});
|
});
|
||||||
@@ -68,7 +68,7 @@ export function sureReceived (orderSn) {
|
|||||||
*/
|
*/
|
||||||
export function getTraces (orderSn) {
|
export function getTraces (orderSn) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/orders/getTraces/${orderSn}`,
|
url: `/buyer/order/order/getTraces/${orderSn}`,
|
||||||
method: Method.POST,
|
method: Method.POST,
|
||||||
needToken: true
|
needToken: true
|
||||||
});
|
});
|
||||||
@@ -80,7 +80,7 @@ export function getTraces (orderSn) {
|
|||||||
*/
|
*/
|
||||||
export function evolutionList (params) {
|
export function evolutionList (params) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/memberEvaluation`,
|
url: `/buyer/member/evaluation`,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
params
|
params
|
||||||
@@ -90,9 +90,46 @@ export function evolutionList (params) {
|
|||||||
// 添加交易投诉对话
|
// 添加交易投诉对话
|
||||||
export function communication (params) {
|
export function communication (params) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/complain/communication`,
|
url: `/buyer/order/complain/communication`,
|
||||||
method: Method.POST,
|
method: Method.POST,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
params
|
params
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 退换货服务 提交物流
|
||||||
|
export function afterSaleDelivery (params) {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/order/afterSale/delivery/${params.afterSaleSn}`,
|
||||||
|
method: Method.POST,
|
||||||
|
needToken: true,
|
||||||
|
params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 获取退货可选物流公司
|
||||||
|
export function getLogisticsCompany () {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/other/logistics`,
|
||||||
|
method: Method.GET,
|
||||||
|
needToken: true,
|
||||||
|
params: { pageNumber: 1, pageSize: 200, disabled: 'OPEN' }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//查询包裹列表
|
||||||
|
export const getPackage = (sn) => {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/order/order/getPackage/${sn}`,
|
||||||
|
method: Method.GET,
|
||||||
|
needToken: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//查询物流
|
||||||
|
export const getTracesList = (sn, params) => {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/order/order/getTracesList/${sn}`,
|
||||||
|
method: Method.GET,
|
||||||
|
needToken: true,
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import request, {
|
|||||||
*/
|
*/
|
||||||
export function tradeDetail (params) {
|
export function tradeDetail (params) {
|
||||||
return request({
|
return request({
|
||||||
url: '/buyer/cashier/tradeDetail',
|
url: '/buyer/payment/cashier/tradeDetail',
|
||||||
needToken: true,
|
needToken: true,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
params
|
params
|
||||||
@@ -24,9 +24,24 @@ export function tradeDetail (params) {
|
|||||||
* @param payClient 调起方式 可用值:APP,NATIVE,JSAPI,H5
|
* @param payClient 调起方式 可用值:APP,NATIVE,JSAPI,H5
|
||||||
* @param sn 订单编号
|
* @param sn 订单编号
|
||||||
*/
|
*/
|
||||||
export function pay (params) {
|
export function pay (params, config = {}) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/cashier/pay/${params.paymentMethod}/${params.paymentClient}`,
|
url: `/buyer/payment/cashier/pay/${params.paymentMethod}/${params.paymentClient}`,
|
||||||
|
needToken: true,
|
||||||
|
method: Method.GET,
|
||||||
|
params,
|
||||||
|
skipMessage: !!config.skipMessage,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付结果查询
|
||||||
|
* @param orderType 交易类型,可用值:TRADE,ORDER,RECHARGE
|
||||||
|
* @param sn 订单编号
|
||||||
|
*/
|
||||||
|
export function payCallback (params) {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/payment/cashier/result`,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
params
|
params
|
||||||
@@ -38,9 +53,9 @@ export function pay (params) {
|
|||||||
* @param orderType 交易类型,可用值:TRADE,ORDER,RECHARGE
|
* @param orderType 交易类型,可用值:TRADE,ORDER,RECHARGE
|
||||||
* @param sn 订单编号
|
* @param sn 订单编号
|
||||||
*/
|
*/
|
||||||
export function payCallback (params) {
|
export function withdrawalSettingVO (params) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/cashier/result`,
|
url: `/buyer/wallet/wallet/withdrawalSettingVO`,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
params
|
params
|
||||||
|
|||||||
@@ -46,3 +46,61 @@ export function pointGoods (params) {
|
|||||||
params
|
params
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 获取积分商品详情
|
||||||
|
*/
|
||||||
|
export function pointGoodsDetail (id) {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/promotion/pointsGoods/${id}`,
|
||||||
|
method: Method.GET,
|
||||||
|
needToken: true,
|
||||||
|
id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询当前客户礼品卡
|
||||||
|
*/
|
||||||
|
export function getGiftCardCashMemberCardPage (params) {
|
||||||
|
return request({
|
||||||
|
url: '/buyer/promotion/giftCardCash/memberCard',
|
||||||
|
method: Method.GET,
|
||||||
|
needToken: true,
|
||||||
|
params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定礼品卡(卡号 + 兑换码/卡密)
|
||||||
|
*/
|
||||||
|
export function bindGiftCardCashMemberCard (data) {
|
||||||
|
return request({
|
||||||
|
url: '/buyer/promotion/giftCardCash/memberCard/bind',
|
||||||
|
method: Method.POST,
|
||||||
|
needToken: true,
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 激活礼品卡
|
||||||
|
*/
|
||||||
|
export function activateGiftCardCashMemberCard (memberCardId) {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/promotion/giftCardCash/memberCard/${memberCardId}/activate`,
|
||||||
|
method: Method.POST,
|
||||||
|
needToken: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下单页可用礼品卡列表
|
||||||
|
*/
|
||||||
|
export function getAvailableGiftCardCashMemberCards () {
|
||||||
|
return request({
|
||||||
|
url: '/buyer/promotion/giftCardCash/memberCard/available',
|
||||||
|
method: Method.GET,
|
||||||
|
needToken: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,8 +5,9 @@ import request, {
|
|||||||
// 店铺分页列表
|
// 店铺分页列表
|
||||||
export function shopList (params) {
|
export function shopList (params) {
|
||||||
return request({
|
return request({
|
||||||
url: '/buyer/store',
|
url: '/buyer/store/store',
|
||||||
needToken: true,
|
needToken: false,
|
||||||
|
optionalToken: true,
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
params
|
params
|
||||||
})
|
})
|
||||||
@@ -15,7 +16,7 @@ export function shopList (params) {
|
|||||||
// 申请店铺第一步-填写企业信息
|
// 申请店铺第一步-填写企业信息
|
||||||
export function applyFirst (params) {
|
export function applyFirst (params) {
|
||||||
return request({
|
return request({
|
||||||
url: '/buyer/store/apply/first',
|
url: '/buyer/store/store/apply/first',
|
||||||
needToken: true,
|
needToken: true,
|
||||||
method: Method.PUT,
|
method: Method.PUT,
|
||||||
params
|
params
|
||||||
@@ -25,7 +26,7 @@ export function applyFirst (params) {
|
|||||||
// 申请店铺第一步-填写企业信息
|
// 申请店铺第一步-填写企业信息
|
||||||
export function applySecond (params) {
|
export function applySecond (params) {
|
||||||
return request({
|
return request({
|
||||||
url: '/buyer/store/apply/second',
|
url: '/buyer/store/store/apply/second',
|
||||||
needToken: true,
|
needToken: true,
|
||||||
method: Method.PUT,
|
method: Method.PUT,
|
||||||
params
|
params
|
||||||
@@ -35,25 +36,45 @@ export function applySecond (params) {
|
|||||||
// 申请店铺第一步-填写企业信息
|
// 申请店铺第一步-填写企业信息
|
||||||
export function applyThird (params) {
|
export function applyThird (params) {
|
||||||
return request({
|
return request({
|
||||||
url: '/buyer/store/apply/third',
|
url: '/buyer/store/store/apply/third',
|
||||||
needToken: true,
|
needToken: true,
|
||||||
method: Method.PUT,
|
method: Method.PUT,
|
||||||
params
|
params
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 店铺信息(含评分)
|
||||||
|
export function getStoreById (id) {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/store/store/store/${id}`,
|
||||||
|
needToken: false,
|
||||||
|
method: Method.GET
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 店铺详情
|
// 店铺详情
|
||||||
|
// 获取店铺工商/营业执照信息
|
||||||
|
export function getLicencePhoto (id) {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/store/store/get/licencePhoto/${id}`,
|
||||||
|
needToken: false,
|
||||||
|
optionalToken: true,
|
||||||
|
method: Method.GET
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export function getDetailById (id) {
|
export function getDetailById (id) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/store/get/detail/${id}`,
|
url: `/buyer/store/store/get/detail/${id}`,
|
||||||
needToken: true,
|
needToken: false,
|
||||||
|
optionalToken: true,
|
||||||
method: Method.GET
|
method: Method.GET
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 店铺分类
|
// 店铺分类
|
||||||
export function getCateById (id) {
|
export function getCateById (id) {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/store/label/get/${id}`,
|
url: `/buyer/store/store/label/get/${id}`,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
method: Method.GET
|
method: Method.GET
|
||||||
})
|
})
|
||||||
@@ -61,7 +82,7 @@ export function getCateById (id) {
|
|||||||
// 店铺入驻协议
|
// 店铺入驻协议
|
||||||
export function agreement () {
|
export function agreement () {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/article/type/STORE_REGISTER`,
|
url: `/buyer/other/article/type/STORE_REGISTER`,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
method: Method.GET
|
method: Method.GET
|
||||||
})
|
})
|
||||||
@@ -70,8 +91,21 @@ export function agreement () {
|
|||||||
// 获取当前登录会员的店铺信息
|
// 获取当前登录会员的店铺信息
|
||||||
export function applyStatus () {
|
export function applyStatus () {
|
||||||
return request({
|
return request({
|
||||||
url: `/buyer/store/apply`,
|
url: `/buyer/store/store/apply`,
|
||||||
needToken: true,
|
needToken: true,
|
||||||
method: Method.GET
|
method: Method.GET,
|
||||||
|
loading: false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取自提点信息
|
||||||
|
* @param storeId
|
||||||
|
*/
|
||||||
|
export function getStoreAddress(storeId,params) {
|
||||||
|
return request({
|
||||||
|
url: `/buyer/store/address/page/${storeId}`,
|
||||||
|
method: Method.GET,
|
||||||
|
params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
BIN
buyer/src/assets/iconfont/back.png
Normal file
|
After Width: | Height: | Size: 682 B |
BIN
buyer/src/assets/iconfont/carts.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
buyer/src/assets/iconfont/collage.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
buyer/src/assets/iconfont/consumer.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
buyer/src/assets/iconfont/feedback.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
29
buyer/src/assets/iconfont/iconMap.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import back from "./back.png";
|
||||||
|
import carts from "./carts.png";
|
||||||
|
import collage from "./collage.png";
|
||||||
|
import feedback from "./feedback.png";
|
||||||
|
import notice from "./notice.png";
|
||||||
|
import notification from "./notification.png";
|
||||||
|
import shop from "./shop.png";
|
||||||
|
import story from "./story.png";
|
||||||
|
import support from "./support.png";
|
||||||
|
import user from "./user.png";
|
||||||
|
|
||||||
|
const iconMap = {
|
||||||
|
back,
|
||||||
|
carts,
|
||||||
|
collage,
|
||||||
|
feedback,
|
||||||
|
notice,
|
||||||
|
notification,
|
||||||
|
shop,
|
||||||
|
story,
|
||||||
|
support,
|
||||||
|
user,
|
||||||
|
};
|
||||||
|
|
||||||
|
export function getIconUrl(name) {
|
||||||
|
return iconMap[name] || "";
|
||||||
|
}
|
||||||
|
|
||||||
|
export default iconMap;
|
||||||
BIN
buyer/src/assets/iconfont/notice.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
buyer/src/assets/iconfont/notification.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
1
buyer/src/assets/iconfont/play.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?><svg width="24" height="24" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M24 44C35.0457 44 44 35.0457 44 24C44 12.9543 35.0457 4 24 4C12.9543 4 4 12.9543 4 24C4 35.0457 12.9543 44 24 44Z" fill="none" stroke="#333" stroke-width="4" stroke-linejoin="round"/><path d="M20 24V17.0718L26 20.5359L32 24L26 27.4641L20 30.9282V24Z" fill="none" stroke="#333" stroke-width="4" stroke-linejoin="round"/></svg>
|
||||||
|
After Width: | Height: | Size: 468 B |
BIN
buyer/src/assets/iconfont/shop.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
buyer/src/assets/iconfont/story.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
buyer/src/assets/iconfont/support.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
buyer/src/assets/iconfont/user.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 126 KiB |
BIN
buyer/src/assets/images/decorate.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
buyer/src/assets/images/default.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 131 KiB |
BIN
buyer/src/assets/images/jinghui.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 302 KiB |
BIN
buyer/src/assets/images/logo2.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
BIN
buyer/src/assets/images/zhizhao.jpg
Normal file
|
After Width: | Height: | Size: 374 KiB |
@@ -1,92 +1,91 @@
|
|||||||
|
|
||||||
|
// coupon
|
||||||
.coupon-list {
|
.coupon-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
.coupon-item {
|
.coupon-item {
|
||||||
width: 380px;
|
width: 380px;
|
||||||
height: 145px;
|
height: 145px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
position: relative;
|
position: relative;
|
||||||
border: 1px solid #eee;
|
|
||||||
.c-left {
|
|
||||||
width: 100%;
|
|
||||||
padding: 20px;
|
|
||||||
>div, > p {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
>div {
|
|
||||||
.price{
|
|
||||||
color: $theme_color;
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
.describe{
|
|
||||||
background-color: #fff4ec;
|
|
||||||
color: $theme_color;
|
|
||||||
padding: 0 5px;
|
|
||||||
margin-left: 10px;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p:nth-of-type(1){
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
p:nth-of-type(2){
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
b{
|
|
||||||
position: absolute;
|
|
||||||
z-index: 2;
|
|
||||||
top: 0;
|
|
||||||
right: 50px;
|
|
||||||
display: block;
|
|
||||||
width: 3px;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
.c-right {
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 52px;
|
|
||||||
height: 100%;
|
|
||||||
background-color: $theme_color;
|
|
||||||
color: #fff;
|
|
||||||
font-size: 16px;
|
|
||||||
padding: 20px;
|
|
||||||
&:hover{
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i{
|
|
||||||
position: absolute;
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
right: 42px;
|
|
||||||
border: 1px solid #eee;
|
border: 1px solid #eee;
|
||||||
background-color: #fff;
|
.c-left {
|
||||||
border-radius: 20px;
|
width: 100%;
|
||||||
&:after{
|
padding: 20px;
|
||||||
content: '';
|
> div,
|
||||||
position: absolute;
|
> p {
|
||||||
width: 25px;
|
margin-bottom: 10px;
|
||||||
height: 20px;
|
}
|
||||||
left: -2px;
|
> div {
|
||||||
background-color: #fff;
|
.price {
|
||||||
|
color: $theme_color;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
.describe {
|
||||||
|
background-color: #fff4ec;
|
||||||
|
color: $theme_color;
|
||||||
|
padding: 0 5px;
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p:nth-of-type(1) {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
p:nth-of-type(2) {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
b {
|
||||||
i.circle-top{
|
position: absolute;
|
||||||
top: -10px;
|
z-index: 2;
|
||||||
&::after{
|
top: 0;
|
||||||
top: -11px;
|
right: 50px;
|
||||||
|
display: block;
|
||||||
|
width: 3px;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
}
|
.c-right {
|
||||||
i.circle-bottom{
|
position: absolute;
|
||||||
bottom: -10px;
|
right: 0;
|
||||||
&::after{
|
top: 0;
|
||||||
bottom: -11px;
|
width: 52px;
|
||||||
|
height: 100%;
|
||||||
|
background-color: $theme_color;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 16px;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
i {
|
||||||
|
position: absolute;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
right: 42px;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20px;
|
||||||
|
&:after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
width: 25px;
|
||||||
|
height: 20px;
|
||||||
|
left: -2px;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i.circle-top {
|
||||||
|
top: -10px;
|
||||||
|
&::after {
|
||||||
|
top: -11px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i.circle-bottom {
|
||||||
|
bottom: -10px;
|
||||||
|
&::after {
|
||||||
|
bottom: -11px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
40
buyer/src/assets/styles/element.scss
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
:root {
|
||||||
|
--el-color-primary: var(--theme-color, #ff3c2a);
|
||||||
|
--el-color-danger: var(--theme-color, #ff3c2a);
|
||||||
|
--el-font-size-base: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-table--border {
|
||||||
|
.el-table__cell {
|
||||||
|
border-right: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-text {
|
||||||
|
color: var(--theme-color, #ff3c2a);
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.85;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.op-split {
|
||||||
|
margin: 0 8px;
|
||||||
|
color: #dcdfe6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 次要强调按钮,使用高亮主题色(如「立即购买」) */
|
||||||
|
.confirm-receipt-btn {
|
||||||
|
background-color: var(--theme-light, #ff6b35) !important;
|
||||||
|
border-color: var(--theme-light, #ff6b35) !important;
|
||||||
|
color: #fff !important;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
background-color: color-mix(in srgb, var(--theme-light, #ff6b35) 88%, black) !important;
|
||||||
|
border-color: color-mix(in srgb, var(--theme-light, #ff6b35) 88%, black) !important;
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
25
buyer/src/assets/styles/global-layout.scss
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
// 全局布局工具类(非 scoped,避免子组件继承 class 时宽度失效)
|
||||||
|
.width_1200_auto {
|
||||||
|
width: 1200px;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 首页主体:分类导航 + 楼层装修共用同一 1200px 容器,保证列对齐
|
||||||
|
.index-main {
|
||||||
|
width: 1200px;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 与 CateNav 商品分类栏、Carousel 左占位一致的列宽
|
||||||
|
$index-main-width: 1200px;
|
||||||
|
$index-side-col-width: 263.2px;
|
||||||
|
$index-col-gap: 10px;
|
||||||
|
// 1200 - 263.2*2 - 10*2 = 653.6px
|
||||||
|
$index-center-col-width: $index-main-width - ($index-side-col-width * 2) - ($index-col-gap * 2);
|
||||||
@@ -1,18 +1,121 @@
|
|||||||
/*
|
|
||||||
* @Author: LMR
|
|
||||||
* @Date: 2020-08-11 10:12:34
|
|
||||||
* @Last Modified by: LMR
|
|
||||||
* @Last Modified time: 2020-08-18 16:00:10
|
|
||||||
*/
|
|
||||||
|
|
||||||
//引入主题色
|
//引入主题色
|
||||||
@import "./theme.scss";
|
|
||||||
|
|
||||||
.global_color{
|
|
||||||
color: $theme_color;
|
// 明亮主题颜色
|
||||||
|
$primary_color: #2d8cf0;
|
||||||
|
$primary_light_color: #0f1011;
|
||||||
|
$primary_dark_color: #2b85e4;
|
||||||
|
$success_color: #19be6b;
|
||||||
|
$warning_color: #ff9900;
|
||||||
|
$error_color: #ed3f14;
|
||||||
|
$handle-btn-color: #438cde;
|
||||||
|
|
||||||
|
$theme_color: var(--theme-color, #ff3c2a);
|
||||||
|
|
||||||
|
$border_color: #dddee1;
|
||||||
|
$title_color: #8c8c8c;
|
||||||
|
$light_title_color: #1c2438;
|
||||||
|
$light_content_color: #495060;
|
||||||
|
$light_sub_color: #80848f;
|
||||||
|
$light_background_color: #F5F5F7;
|
||||||
|
$light_white_background_color: #fff;
|
||||||
|
// 暗黑主题颜色
|
||||||
|
$dark_background_color: #141414;
|
||||||
|
$dark_sub_background_color: #1d1d1d; //稍微浅一点的
|
||||||
|
$dark_content_color: #d5d5d5;
|
||||||
|
|
||||||
|
|
||||||
|
.wes-2 {
|
||||||
|
/* 适用于webkit内核和移动端 */
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
line-clamp: 2;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.global_background_color{
|
/***** 封装一些方法可用于 黑暗主题 ,明亮主题 *****/
|
||||||
background-color: $theme_color;
|
|
||||||
|
// 背景颜色
|
||||||
|
@mixin background_color($color) {
|
||||||
|
/*通过该函数设置字体颜色,后期方便统一管理;*/
|
||||||
|
background-color: $color;
|
||||||
|
transition: 0.35s;
|
||||||
|
[data-theme="dark"] & {
|
||||||
|
background-color: $dark_background_color;
|
||||||
|
}
|
||||||
|
[data-theme="light"] & {
|
||||||
|
background-color: $light_background_color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 辅助背景颜色
|
||||||
|
@mixin sub_background_color($color) {
|
||||||
|
/*通过该函数设置字体颜色,后期方便统一管理;*/
|
||||||
|
background-color: $color;
|
||||||
|
transition: 0.35s;
|
||||||
|
[data-theme="dark"] & {
|
||||||
|
background-color: $dark_sub_background_color;
|
||||||
|
}
|
||||||
|
[data-theme="light"] & {
|
||||||
|
background-color: $light_background_color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin white_background_color() {
|
||||||
|
/*通过该函数设置字体颜色,后期方便统一管理;*/
|
||||||
|
background-color: $light_white_background_color;
|
||||||
|
transition: 0.35s;
|
||||||
|
[data-theme="dark"] & {
|
||||||
|
background-color: $dark_sub_background_color;
|
||||||
|
}
|
||||||
|
[data-theme="light"] & {
|
||||||
|
background-color: $light_white_background_color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 正文颜色
|
||||||
|
@mixin content_color($color) {
|
||||||
|
/*通过该函数设置字体颜色,后期方便统一管理;*/
|
||||||
|
color: $color;
|
||||||
|
[data-theme="dark"] & {
|
||||||
|
color: $dark_content_color;
|
||||||
|
}
|
||||||
|
[data-theme="light"] & {
|
||||||
|
color: $light_content_color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 辅助颜色
|
||||||
|
@mixin sub_color($color) {
|
||||||
|
/*通过该函数设置字体颜色,后期方便统一管理;*/
|
||||||
|
color: $color;
|
||||||
|
[data-theme="dark"] & {
|
||||||
|
color: $dark_content_color;
|
||||||
|
}
|
||||||
|
[data-theme="light"] & {
|
||||||
|
color: $light_sub_color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 标题颜色
|
||||||
|
@mixin title_color($color) {
|
||||||
|
/*通过该函数设置字体颜色,后期方便统一管理;*/
|
||||||
|
color: $color;
|
||||||
|
[data-theme="dark"] & {
|
||||||
|
color: $dark_content_color;
|
||||||
|
}
|
||||||
|
[data-theme="light"] & {
|
||||||
|
color: $light_title_color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 全局变量
|
||||||
|
.global_color {
|
||||||
|
color: $theme_color;
|
||||||
|
}
|
||||||
|
.global_background_color {
|
||||||
|
background-color: $theme_color;
|
||||||
}
|
}
|
||||||
.global_text_left {
|
.global_text_left {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
@@ -26,44 +129,109 @@
|
|||||||
.global_float_right {
|
.global_float_right {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
.clearfix::after{
|
.clearfix::after {
|
||||||
content: '';
|
content: "";
|
||||||
display: block;
|
display: block;
|
||||||
clear: both;
|
clear: both;
|
||||||
}
|
}
|
||||||
.width_1200{width: 1200px;}
|
.width_1200 {
|
||||||
.width_800{width: 800px;}
|
width: 1200px;
|
||||||
.width_400{width: 400px;}
|
}
|
||||||
.width_300{width: 300px;}
|
.width_800 {
|
||||||
.width_200{width: 200px;}
|
width: 800px;
|
||||||
.width_100{width: 100px;}
|
}
|
||||||
|
.width_400 {
|
||||||
|
width: 400px;
|
||||||
|
}
|
||||||
|
.width_300 {
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
.width_200 {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
.width_100 {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
.fontsize_12{font-size: 12px;}
|
.fontsize_12 {
|
||||||
.fontsize_14{font-size: 14px;}
|
font-size: 12px;
|
||||||
.fontsize_16{font-size: 16px;}
|
}
|
||||||
.fontsize_18{font-size: 18px;}
|
.fontsize_14 {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.fontsize_16 {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
.fontsize_18 {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
.mb_20{margin-bottom: 20px;}
|
.mb_20 {
|
||||||
.mt_20{margin-top: 20px;}
|
margin-bottom: 20px;
|
||||||
.ml_20{margin-left: 20px;}
|
}
|
||||||
.mr_20{margin-right: 20px;}
|
.mt_20 {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.ml_20 {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
.mr_20 {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
.mb_10{margin-bottom: 10px;}
|
.mb_24 {
|
||||||
.mt_10{margin-top: 10px;}
|
margin-bottom: 24px;
|
||||||
.ml_10{margin-left: 10px;}
|
}
|
||||||
.mr_10{margin-right: 10px;}
|
.mt_24 {
|
||||||
|
margin-top: 24px;
|
||||||
|
}
|
||||||
|
.ml_24 {
|
||||||
|
margin-left: 24px;
|
||||||
|
}
|
||||||
|
.mr_24 {
|
||||||
|
margin-right: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
.pb_20{padding-bottom: 20px;}
|
.mb_10 {
|
||||||
.pt_20{padding-top: 20px;}
|
margin-bottom: 10px;
|
||||||
.pl_20{padding-left: 20px;}
|
}
|
||||||
.pr_20{padding-right: 20px;}
|
.mt_10 {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.ml_10 {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
.mr_10 {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.pb_10{padding-bottom: 10px;}
|
.pb_20 {
|
||||||
.pt_10{padding-top: 10px;}
|
padding-bottom: 20px;
|
||||||
.pl_10{padding-left: 10px;}
|
}
|
||||||
.pr_10{padding-right: 10px;}
|
.pt_20 {
|
||||||
|
padding-top: 20px;
|
||||||
|
}
|
||||||
|
.pl_20 {
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
.pr_20 {
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
.color999{
|
.pb_10 {
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
.pt_10 {
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
.pl_10 {
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
.pr_10 {
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color999 {
|
||||||
color: #999;
|
color: #999;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,55 +239,151 @@ html,
|
|||||||
body {
|
body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif;
|
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial,
|
||||||
|
sans-serif;
|
||||||
// overflow: hidden;
|
// overflow: hidden;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
li{
|
li {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
}
|
}
|
||||||
.hover-color:hover{
|
.hover-color:hover {
|
||||||
color: $theme_color!important;
|
color: $theme_color !important;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.hover-pointer{
|
.hover-pointer {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.center{
|
.center {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
.relative{
|
.relative {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
.ellipsis{
|
.ellipsis {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow:ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.promotion-decorate{
|
.promotion-decorate {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 25px;
|
font-size: 25px;
|
||||||
position: relative;
|
position: relative;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
margin: 30px auto 30px;
|
margin: 30px auto 30px;
|
||||||
&::before,&::after{
|
&::before,
|
||||||
content: '';
|
&::after {
|
||||||
display: inline-block;
|
content: "";
|
||||||
width: 25px;
|
display: inline-block;
|
||||||
height: 20px;
|
width: 25px;
|
||||||
background-size: 50px 20px;
|
height: 20px;
|
||||||
background-repeat: no-repeat;
|
background-size: 50px 20px;
|
||||||
background-position: 0 0;
|
background-repeat: no-repeat;
|
||||||
position: absolute;
|
background-position: 0 0;
|
||||||
top: 10px;
|
position: absolute;
|
||||||
left: -3px;
|
top: 10px;
|
||||||
|
left: -3px;
|
||||||
}
|
}
|
||||||
&::after{
|
&::after {
|
||||||
background-position: -24px 0;
|
background-position: -24px 0;
|
||||||
right: -3px;
|
right: -3px;
|
||||||
left: auto;
|
left: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.flex{
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.flex-a-c{
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.flex-j-sb{
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.flex-j-c{
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.width_1200_auto {
|
||||||
|
width: 1200px;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// goodsList
|
||||||
|
|
||||||
|
.text-danger {
|
||||||
|
color: $theme_color;
|
||||||
|
}
|
||||||
|
.seckill-price{
|
||||||
|
margin-right: 5px;
|
||||||
|
font-size: 25px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.goods-list {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
column-gap: 10px;
|
||||||
|
}
|
||||||
|
.goods-show-info {
|
||||||
|
width: calc(20% - 8px);
|
||||||
|
padding: 6px;
|
||||||
|
margin: 10px 0;
|
||||||
|
position: relative;
|
||||||
|
border: 1px solid #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: #fff;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.goods-show-img img {
|
||||||
|
width: 100%;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
.goods-show-info:hover {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
box-shadow: 0px 0px 15px #ccc;
|
||||||
|
}
|
||||||
|
.goods-show-price {
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
.goods-show-detail {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 21px;
|
||||||
|
margin: 6px 0px;
|
||||||
|
}
|
||||||
|
.goods-show-num {
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
.goods-show-num {
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
color: #009688;
|
||||||
|
}
|
||||||
|
.goods-show-num span {
|
||||||
|
color: #005aa0;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.goods-show-seller {
|
||||||
|
font-size: 14px;
|
||||||
|
color: $theme_color;
|
||||||
|
}
|
||||||
|
.goods-page {
|
||||||
|
margin: 10px 0;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
|
||||||
|
:deep(.el-pagination) {
|
||||||
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,18 +9,24 @@
|
|||||||
.goods-list {
|
.goods-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
width: 1200px;
|
width: 100%;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
column-gap: 10px;
|
||||||
}
|
}
|
||||||
.goods-show-info {
|
.goods-show-info {
|
||||||
width: 235px;
|
width: calc(20% - 8px);
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
margin: 10px 0px;
|
margin: 10px 0;
|
||||||
margin-left: 5px;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
border: 1px solid #fff;
|
border: 1px solid #fff;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.goods-show-img img {
|
||||||
|
width: 100%;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
.goods-show-info:hover {
|
.goods-show-info:hover {
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
@@ -30,16 +36,28 @@
|
|||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
}
|
}
|
||||||
.goods-show-detail {
|
.goods-show-detail {
|
||||||
font-size: 12px;
|
height: 42px;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 21px;
|
||||||
margin: 6px 0px;
|
margin: 6px 0px;
|
||||||
|
overflow:hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
display:-webkit-box;
|
||||||
|
-webkit-line-clamp:2;
|
||||||
|
line-clamp: 2;
|
||||||
|
-webkit-box-orient:vertical;
|
||||||
|
color:#808080;
|
||||||
|
}
|
||||||
|
.goods-show-detail :hover{
|
||||||
|
color:#E23A3A;
|
||||||
}
|
}
|
||||||
.goods-show-num {
|
.goods-show-num {
|
||||||
font-size: 12px;
|
font-size: 14px;
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
color: #666;
|
color: #666;
|
||||||
}
|
}
|
||||||
.goods-show-num {
|
.goods-show-num {
|
||||||
font-size: 12px;
|
font-size: 14px;
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
color: #009688;
|
color: #009688;
|
||||||
}
|
}
|
||||||
@@ -48,11 +66,16 @@
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
.goods-show-seller {
|
.goods-show-seller {
|
||||||
font-size: 12px;
|
font-size: 14px;
|
||||||
color: $theme_color;
|
color: $theme_color;
|
||||||
}
|
}
|
||||||
.goods-page {
|
.goods-page {
|
||||||
margin:10px auto ;
|
margin: 10px 0;
|
||||||
text-align: right;
|
width: 100%;
|
||||||
width: 1200px;
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
|
||||||
|
:deep(.el-pagination) {
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,84 +1,15 @@
|
|||||||
@import '~view-design/src/styles/index.less';
|
// Element Plus 主题变量(原 view-design less 已移除)
|
||||||
|
@primary-color: #ff5c58;
|
||||||
|
@info-color: #fa6419;
|
||||||
|
@success-color: #68cabe;
|
||||||
|
@error-color: #ff3c2a;
|
||||||
|
@table-thead-bg: #f8f8f9;
|
||||||
|
@table-td-stripe-bg: #f8f8f9;
|
||||||
|
@table-td-hover-bg: #ededed;
|
||||||
|
@table-td-highlight-bg: #ededed;
|
||||||
|
@font-size-base: 12px;
|
||||||
|
|
||||||
@primary-color: #ed3f14;
|
.el-drawer,
|
||||||
|
.drawer {
|
||||||
|
z-index: 2600 !important;
|
||||||
@table-thead-bg : #f8f8f9;
|
}
|
||||||
@table-td-stripe-bg : #f8f8f9;
|
|
||||||
@table-td-hover-bg : #ededed;
|
|
||||||
@table-td-highlight-bg : #ededed;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
//.colorPaletteMixin() {
|
|
||||||
// @functions: ~`(function() {
|
|
||||||
// var hueStep = 2;
|
|
||||||
// var saturationStep = 0.16;
|
|
||||||
// var saturationStep2 = 0.05;
|
|
||||||
// var brightnessStep1 = 0.05;
|
|
||||||
// var brightnessStep2 = 0.15;
|
|
||||||
// var lightColorCount = 5;
|
|
||||||
// var darkColorCount = 4;
|
|
||||||
//
|
|
||||||
// var getHue = function(hsv, i, isLight) {
|
|
||||||
// var hue;
|
|
||||||
// if (hsv.h >= 60 && hsv.h <= 240) {
|
|
||||||
// hue = isLight ? hsv.h - hueStep * i : hsv.h + hueStep * i;
|
|
||||||
// } else {
|
|
||||||
// hue = isLight ? hsv.h + hueStep * i : hsv.h - hueStep * i;
|
|
||||||
// }
|
|
||||||
// if (hue < 0) {
|
|
||||||
// hue += 360;
|
|
||||||
// } else if (hue >= 360) {
|
|
||||||
// hue -= 360;
|
|
||||||
// }
|
|
||||||
// return Math.round(hue);
|
|
||||||
// };
|
|
||||||
// var getSaturation = function(hsv, i, isLight) {
|
|
||||||
// var saturation;
|
|
||||||
// if (isLight) {
|
|
||||||
// saturation = hsv.s - saturationStep * i;
|
|
||||||
// } else if (i === darkColorCount) {
|
|
||||||
// saturation = hsv.s + saturationStep;
|
|
||||||
// } else {
|
|
||||||
// saturation = hsv.s + saturationStep2 * i;
|
|
||||||
// }
|
|
||||||
// if (saturation > 1) {
|
|
||||||
// saturation = 1;
|
|
||||||
// }
|
|
||||||
// if (isLight && i === lightColorCount && saturation > 0.1) {
|
|
||||||
// saturation = 0.1;
|
|
||||||
// }
|
|
||||||
// if (saturation < 0.06) {
|
|
||||||
// saturation = 0.06;
|
|
||||||
// }
|
|
||||||
// return Number(saturation.toFixed(2));
|
|
||||||
// };
|
|
||||||
// var getValue = function(hsv, i, isLight) {
|
|
||||||
// var value;
|
|
||||||
// if (isLight) {
|
|
||||||
// value = hsv.v + brightnessStep1 * i;
|
|
||||||
// }else{
|
|
||||||
// value = hsv.v - brightnessStep2 * i
|
|
||||||
// }
|
|
||||||
// if (value > 1) {
|
|
||||||
// value = 1;
|
|
||||||
// }
|
|
||||||
// return Number(value.toFixed(2))
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// this.colorPalette = function(color, index) {
|
|
||||||
// var isLight = index <= 6;
|
|
||||||
// var hsv = tinycolor(color).toHsv();
|
|
||||||
// var i = isLight ? lightColorCount + 1 - index : index - lightColorCount - 1;
|
|
||||||
// return tinycolor({
|
|
||||||
// h: getHue(hsv, i, isLight),
|
|
||||||
// s: getSaturation(hsv, i, isLight),
|
|
||||||
// v: getValue(hsv, i, isLight),
|
|
||||||
// }).toHexString();
|
|
||||||
// };
|
|
||||||
//})()`;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//.colorPaletteMixin();
|
|
||||||
|
|||||||
@@ -1,114 +0,0 @@
|
|||||||
/*
|
|
||||||
* @Author: LMR
|
|
||||||
* @Date: 2020-08-14 11:04:12
|
|
||||||
* @Last Modified by: LMR
|
|
||||||
* @Last Modified time: 2020-08-18 14:21:41
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
// 主题颜色
|
|
||||||
|
|
||||||
// 明亮主题颜色
|
|
||||||
$primary_color: #2d8cf0;
|
|
||||||
$primary_light_color: #0f1011;
|
|
||||||
$primary_dark_color: #2b85e4;
|
|
||||||
$success_color: #19be6b;
|
|
||||||
$warning_color: #ff9900;
|
|
||||||
$error_color: #ed3f14;
|
|
||||||
$handle-btn-color: #438cde;
|
|
||||||
|
|
||||||
$theme_color: #ed3f14;
|
|
||||||
|
|
||||||
$border_color: #dddee1;
|
|
||||||
$title_color: #8c8c8c;
|
|
||||||
$light_title_color: #1c2438;
|
|
||||||
$light_content_color: #495060;
|
|
||||||
$light_sub_color: #80848f;
|
|
||||||
$light_background_color: #f8f8f9;
|
|
||||||
$light_white_background_color :#fff;
|
|
||||||
// 暗黑主题颜色
|
|
||||||
$dark_background_color: #141414;
|
|
||||||
$dark_sub_background_color: #1d1d1d; //稍微浅一点的
|
|
||||||
$dark_content_color: #d5d5d5;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***** 封装一些方法可用于 黑暗主题 ,明亮主题 *****/
|
|
||||||
|
|
||||||
|
|
||||||
// 背景颜色
|
|
||||||
@mixin background_color($color) {
|
|
||||||
/*通过该函数设置字体颜色,后期方便统一管理;*/
|
|
||||||
background-color: $color;
|
|
||||||
transition: 0.35s;
|
|
||||||
[data-theme="dark"] & {
|
|
||||||
background-color: $dark_background_color;
|
|
||||||
}
|
|
||||||
[data-theme="light"] & {
|
|
||||||
background-color: $light_background_color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 辅助背景颜色
|
|
||||||
@mixin sub_background_color($color) {
|
|
||||||
/*通过该函数设置字体颜色,后期方便统一管理;*/
|
|
||||||
background-color: $color;
|
|
||||||
transition: 0.35s;
|
|
||||||
[data-theme="dark"] & {
|
|
||||||
background-color: $dark_sub_background_color;
|
|
||||||
}
|
|
||||||
[data-theme="light"] & {
|
|
||||||
background-color: $light_background_color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@mixin white_background_color() {
|
|
||||||
/*通过该函数设置字体颜色,后期方便统一管理;*/
|
|
||||||
background-color: $light_white_background_color;
|
|
||||||
transition: 0.35s;
|
|
||||||
[data-theme="dark"] & {
|
|
||||||
background-color: $dark_sub_background_color;
|
|
||||||
}
|
|
||||||
[data-theme="light"] & {
|
|
||||||
background-color: $light_white_background_color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 正文颜色
|
|
||||||
@mixin content_color($color) {
|
|
||||||
/*通过该函数设置字体颜色,后期方便统一管理;*/
|
|
||||||
color: $color;
|
|
||||||
[data-theme="dark"] & {
|
|
||||||
color: $dark_content_color;
|
|
||||||
}
|
|
||||||
[data-theme="light"] & {
|
|
||||||
color: $light_content_color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 辅助颜色
|
|
||||||
@mixin sub_color($color) {
|
|
||||||
/*通过该函数设置字体颜色,后期方便统一管理;*/
|
|
||||||
color: $color;
|
|
||||||
[data-theme="dark"] & {
|
|
||||||
color: $dark_content_color;
|
|
||||||
}
|
|
||||||
[data-theme="light"] & {
|
|
||||||
color: $light_sub_color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 标题颜色
|
|
||||||
@mixin title_color($color) {
|
|
||||||
/*通过该函数设置字体颜色,后期方便统一管理;*/
|
|
||||||
color: $color;
|
|
||||||
[data-theme="dark"] & {
|
|
||||||
color: $dark_content_color;
|
|
||||||
}
|
|
||||||
[data-theme="light"] & {
|
|
||||||
color: $light_title_color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,149 +1,496 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="navbar" ref="rootRef" :class="{'small-search-box': useClass == 'fixed-show'}">
|
||||||
<div class="container">
|
<template v-if="useClass == 'fixed-show'">
|
||||||
<img
|
<div class="search search-embedded">
|
||||||
:src="logoImg"
|
<el-input
|
||||||
v-if="showLogo"
|
v-model="searchData"
|
||||||
class="logo-img"
|
size="large"
|
||||||
alt=""
|
class="search-input"
|
||||||
@click="$router.push('/')"
|
:placeholder="placeholderText"
|
||||||
/>
|
@focus="openPanel"
|
||||||
<i-input
|
@input="queueSuggest"
|
||||||
v-model="searchData"
|
@keyup.enter="search"
|
||||||
size="large"
|
/>
|
||||||
class="search"
|
<div class="search-btn" @click="search">
|
||||||
placeholder="输入你想查找的商品"
|
<el-icon :size="21"><SearchIcon /></el-icon>
|
||||||
@keyup.enter.native="search"
|
|
||||||
>
|
|
||||||
<Button v-if="!store" slot="append" @click="search">搜索</Button>
|
|
||||||
</i-input>
|
|
||||||
<div v-if="store" class="btn-div">
|
|
||||||
<Button class="store-search" type="warning" @click="searchStore">搜本店</Button>
|
|
||||||
<Button class="store-search" type="primary" @click="search">搜全站</Button>
|
|
||||||
</div>
|
|
||||||
<template v-if="showTag">
|
|
||||||
<div style="height:12px" v-if="promotionTags.length === 0"></div>
|
|
||||||
<div v-else>
|
|
||||||
<Tag
|
|
||||||
v-for="(item, index) in promotionTags"
|
|
||||||
:key="index"
|
|
||||||
>
|
|
||||||
<span class="hover-color" @click="selectTags(item)">{{ item }}</span>
|
|
||||||
</Tag>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
<div v-if="showPanel" class="suggest-panel" @mousedown.prevent>
|
||||||
</div>
|
<SearchSuggest
|
||||||
|
:keyword="trimmedKeyword"
|
||||||
|
:history="history"
|
||||||
|
:hot-words="promotionTags"
|
||||||
|
:suggestions="suggestions"
|
||||||
|
:suggesting="suggesting"
|
||||||
|
@pick="selectTags"
|
||||||
|
@clear="clearHistory"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<div class="container width_1200_auto flex flex-a-c">
|
||||||
|
<img
|
||||||
|
:src="logoImg"
|
||||||
|
v-if="showLogo"
|
||||||
|
class="logo-img"
|
||||||
|
alt=""
|
||||||
|
@click="$router.push('/')"
|
||||||
|
/>
|
||||||
|
<div class="search-box">
|
||||||
|
<!-- 搜索类型切换:商品 / 店铺(店铺内搜索时不展示) -->
|
||||||
|
<div v-if="showTypeSwitch" class="search-type">
|
||||||
|
<span
|
||||||
|
v-for="item in searchTypes"
|
||||||
|
:key="item.value"
|
||||||
|
class="search-type-item"
|
||||||
|
:class="{ active: searchType === item.value }"
|
||||||
|
@click="switchType(item.value)"
|
||||||
|
>{{ item.label }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="search">
|
||||||
|
<el-input
|
||||||
|
v-model="searchData"
|
||||||
|
size="large"
|
||||||
|
class="search-input"
|
||||||
|
:placeholder="placeholderText"
|
||||||
|
@focus="openPanel"
|
||||||
|
@input="queueSuggest"
|
||||||
|
@keyup.enter="search"
|
||||||
|
/>
|
||||||
|
<div class="search-btn" @click="search">
|
||||||
|
<el-icon :size="21"><SearchIcon /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div v-if="showPanel" class="suggest-panel" @mousedown.prevent>
|
||||||
|
<SearchSuggest
|
||||||
|
:keyword="trimmedKeyword"
|
||||||
|
:history="history"
|
||||||
|
:hot-words="promotionTags"
|
||||||
|
:suggestions="suggestions"
|
||||||
|
:suggesting="suggesting"
|
||||||
|
@pick="selectTags"
|
||||||
|
@clear="clearHistory"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<template v-if="showTag">
|
||||||
|
<div v-if="promotionTags.length === 0"></div>
|
||||||
|
<div v-else class="history-list flex">
|
||||||
|
<div
|
||||||
|
v-for="(item, index) in promotionTags"
|
||||||
|
:key="index"
|
||||||
|
class="mr_10"
|
||||||
|
>
|
||||||
|
<span class="history-item" @click="selectTags(item)">{{ item }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
import {getLogo} from '@/api/common.js'
|
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
|
||||||
import {hotWords} from '@/api/goods.js'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
export default {
|
import storage from '@/plugins/storage.js'
|
||||||
name: 'search',
|
import { goodsList, hotWords } from '@/api/goods.js'
|
||||||
props: {
|
import { Search as SearchIcon } from '@element-plus/icons-vue'
|
||||||
showTag: { // 是否展示搜索栏下方热门搜索
|
import SearchSuggest from '@/components/SearchSuggest.vue'
|
||||||
type: Boolean,
|
import { useAppStore } from '@/stores/app'
|
||||||
default: true
|
|
||||||
},
|
|
||||||
showLogo: { // 是否展示左侧logo
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
store: { // 是否为店铺页面
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
searchData: '', // 搜索内容
|
|
||||||
logoImg: '', // pc端展示logo
|
|
||||||
promotionTags: [] // 热门搜索列表
|
|
||||||
};
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
selectTags (item) { // 选择热门标签
|
|
||||||
this.searchData = item;
|
|
||||||
this.search();
|
|
||||||
},
|
|
||||||
search () { // 全平台搜索商品
|
|
||||||
this.$router.push({
|
|
||||||
path: '/goodsList',
|
|
||||||
query: { keyword: this.searchData }
|
|
||||||
});
|
|
||||||
},
|
|
||||||
searchStore () { // 店铺搜索商品
|
|
||||||
this.$emit('search', this.searchData)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted () {
|
|
||||||
if (!this.Cookies.getItem('logo')) {
|
|
||||||
getLogo().then(res => {
|
|
||||||
if (res.success) {
|
|
||||||
let logoObj = JSON.parse(res.result.settingValue)
|
|
||||||
this.Cookies.setItem('logo', logoObj.buyerSideLogo)
|
|
||||||
this.logoImg = logoObj.buyerSideLogo
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.logoImg = this.Cookies.getItem('logo')
|
|
||||||
}
|
|
||||||
this.searchData = this.$route.query.keyword
|
|
||||||
hotWords({start: 1, end: 5}).then(res => {
|
|
||||||
if (res.success) this.promotionTags = res.result
|
|
||||||
})
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
defineOptions({ name: 'search' })
|
||||||
.container {
|
|
||||||
margin: 30px auto;
|
const props = defineProps({
|
||||||
width: 460px;
|
showTag: {
|
||||||
position: relative;
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
showLogo: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
storeId: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
hover: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
useClass: {
|
||||||
|
type: null,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['search'])
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const router = useRouter()
|
||||||
|
const appStore = useAppStore()
|
||||||
|
|
||||||
|
const HISTORY_KEY = 'buyerSearchHistory'
|
||||||
|
const HISTORY_LIMIT = 10
|
||||||
|
|
||||||
|
function readHistory() {
|
||||||
|
try {
|
||||||
|
const raw = localStorage.getItem(HISTORY_KEY)
|
||||||
|
const list = raw ? JSON.parse(raw) : []
|
||||||
|
return Array.isArray(list) ? list.filter((item) => typeof item === 'string' && item.trim()) : []
|
||||||
|
} catch {
|
||||||
|
return []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parseHotWords(raw) {
|
||||||
|
if (!raw) return []
|
||||||
|
if (Array.isArray(raw)) return raw.filter(Boolean)
|
||||||
|
if (typeof raw !== 'string') return []
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(raw)
|
||||||
|
if (Array.isArray(parsed)) return parsed.filter(Boolean)
|
||||||
|
} catch {
|
||||||
|
// 旧数据可能是逗号拼接
|
||||||
|
}
|
||||||
|
return raw.split(',').map((item) => item.trim()).filter(Boolean)
|
||||||
|
}
|
||||||
|
|
||||||
|
const rootRef = ref(null)
|
||||||
|
const searchData = ref('')
|
||||||
|
const history = ref([])
|
||||||
|
const panelVisible = ref(false)
|
||||||
|
const suggestions = ref([])
|
||||||
|
const suggesting = ref(false)
|
||||||
|
let suggestTimer = null
|
||||||
|
let suggestSeq = 0
|
||||||
|
|
||||||
|
const logoImg = computed(() => appStore.logoImg)
|
||||||
|
|
||||||
|
const trimmedKeyword = computed(() => {
|
||||||
|
return (searchData.value || '').trim()
|
||||||
|
})
|
||||||
|
|
||||||
|
const promotionTags = computed(() => {
|
||||||
|
return parseHotWords(appStore.hotWordsList)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 搜索类型:goods 商品 / store 店铺
|
||||||
|
const searchTypes = [
|
||||||
|
{ label: '商品', value: 'goods' },
|
||||||
|
{ label: '店铺', value: 'store' },
|
||||||
|
]
|
||||||
|
const searchType = ref(route.path === '/storeList' ? 'store' : 'goods')
|
||||||
|
// 店铺内搜索(传了 storeId)只能搜本店商品,不展示切换
|
||||||
|
const showTypeSwitch = computed(() => !props.storeId && props.useClass !== 'fixed-show')
|
||||||
|
const isStoreMode = computed(() => searchType.value === 'store' && !props.storeId)
|
||||||
|
const placeholderText = computed(() => (isStoreMode.value ? '输入你想查找的店铺' : '输入你想查找的商品'))
|
||||||
|
|
||||||
|
function switchType(type) {
|
||||||
|
if (searchType.value === type) return
|
||||||
|
searchType.value = type
|
||||||
|
suggestions.value = []
|
||||||
|
suggesting.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const showPanel = computed(() => {
|
||||||
|
// 店铺搜索暂无联想/历史,不展示下拉面板
|
||||||
|
if (isStoreMode.value) return false
|
||||||
|
if (!panelVisible.value) return false
|
||||||
|
if (trimmedKeyword.value) return true
|
||||||
|
return history.value.length > 0 || promotionTags.value.length > 0
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => route.query.keyword,
|
||||||
|
(value) => {
|
||||||
|
searchData.value = value || ''
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
function selectTags(item) {
|
||||||
|
// 热词/历史均为商品关键词,点击时按商品搜索
|
||||||
|
searchType.value = 'goods'
|
||||||
|
searchData.value = item
|
||||||
|
search()
|
||||||
|
}
|
||||||
|
|
||||||
|
function remember(keyword) {
|
||||||
|
const next = [keyword, ...history.value.filter((item) => item !== keyword)].slice(0, HISTORY_LIMIT)
|
||||||
|
history.value = next
|
||||||
|
localStorage.setItem(HISTORY_KEY, JSON.stringify(next))
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearHistory() {
|
||||||
|
history.value = []
|
||||||
|
localStorage.removeItem(HISTORY_KEY)
|
||||||
|
}
|
||||||
|
|
||||||
|
function openPanel() {
|
||||||
|
panelVisible.value = true
|
||||||
|
if (trimmedKeyword.value) queueSuggest()
|
||||||
|
}
|
||||||
|
|
||||||
|
function closePanel() {
|
||||||
|
panelVisible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDocumentClick(event) {
|
||||||
|
if (rootRef.value && !rootRef.value.contains(event.target)) closePanel()
|
||||||
|
}
|
||||||
|
|
||||||
|
function queueSuggest() {
|
||||||
|
if (isStoreMode.value) return
|
||||||
|
panelVisible.value = true
|
||||||
|
clearTimeout(suggestTimer)
|
||||||
|
const keyword = trimmedKeyword.value
|
||||||
|
if (!keyword) {
|
||||||
|
suggestions.value = []
|
||||||
|
suggesting.value = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
suggesting.value = true
|
||||||
|
suggestTimer = setTimeout(() => fetchSuggest(keyword), 300)
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchSuggest(keyword) {
|
||||||
|
const seq = ++suggestSeq
|
||||||
|
const params = { keyword, pageNumber: 1, pageSize: 8 }
|
||||||
|
if (props.storeId) params.storeId = props.storeId
|
||||||
|
goodsList(params).then((res) => {
|
||||||
|
if (seq !== suggestSeq || keyword !== trimmedKeyword.value) return
|
||||||
|
const records = res && res.success ? (res.result.records || []) : []
|
||||||
|
const seen = new Set()
|
||||||
|
const names = []
|
||||||
|
promotionTags.value.forEach((word) => {
|
||||||
|
if (word && String(word).toLowerCase().includes(keyword.toLowerCase()) && !seen.has(word)) {
|
||||||
|
seen.add(word)
|
||||||
|
names.push(word)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
records.forEach((item) => {
|
||||||
|
const name = item && item.goodsName
|
||||||
|
if (name && !seen.has(name)) {
|
||||||
|
seen.add(name)
|
||||||
|
names.push(name)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
suggestions.value = names.slice(0, 8)
|
||||||
|
}).catch(() => {
|
||||||
|
if (seq === suggestSeq) suggestions.value = []
|
||||||
|
}).finally(() => {
|
||||||
|
if (seq === suggestSeq) suggesting.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function search() {
|
||||||
|
const keyword = trimmedKeyword.value
|
||||||
|
searchData.value = keyword
|
||||||
|
closePanel()
|
||||||
|
if (isStoreMode.value) {
|
||||||
|
if (route.path === '/storeList') {
|
||||||
|
emit('search', keyword)
|
||||||
|
} else {
|
||||||
|
router.push({ path: '/storeList', query: keyword ? { keyword } : {} })
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (keyword) remember(keyword)
|
||||||
|
const url = route.path
|
||||||
|
if (url == '/goodsList') {
|
||||||
|
emit('search', keyword)
|
||||||
|
} else {
|
||||||
|
const pushData = {
|
||||||
|
path: '/goodsList',
|
||||||
|
query: keyword ? { keyword } : {},
|
||||||
|
}
|
||||||
|
if (props.storeId) pushData.query.storeId = props.storeId
|
||||||
|
|
||||||
|
router.push(pushData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function searchStore() {
|
||||||
|
emit('search', trimmedKeyword.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyHotWords(result) {
|
||||||
|
const list = parseHotWords(result)
|
||||||
|
appStore.setHotWords(list)
|
||||||
|
storage.setItem('hotWordsList', JSON.stringify(list))
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadHotWords() {
|
||||||
|
hotWords({ count: 5 }).then((res) => {
|
||||||
|
if (res.success && res.result) applyHotWords(res.result)
|
||||||
|
}).catch(() => {
|
||||||
|
// 热词为可选数据,失败时沿用缓存或默认热词
|
||||||
|
})
|
||||||
|
storage.setItem('hotWordsReloadTime', new Date().getTime())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化(原 created 钩子逻辑)
|
||||||
|
searchData.value = route.query.keyword || ''
|
||||||
|
history.value = readHistory()
|
||||||
|
|
||||||
|
if (!props.hover) {
|
||||||
|
const reloadTime = storage.getItem('hotWordsReloadTime')
|
||||||
|
const time = new Date().getTime() - 5 * 60 * 1000
|
||||||
|
if (!reloadTime || time > reloadTime) loadHotWords()
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
document.addEventListener('click', onDocumentClick)
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
clearTimeout(suggestTimer)
|
||||||
|
document.removeEventListener('click', onDocumentClick)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.navbar {
|
||||||
|
height: 113px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar.small-search-box {
|
||||||
|
height: 60px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-embedded {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.search {
|
.search {
|
||||||
|
$btn-gap: 4px;
|
||||||
|
$btn-width: 60px;
|
||||||
|
$input-height: 37.8px;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
width: 778.4px;
|
||||||
|
height: $input-height;
|
||||||
margin: 10px 0px 5px 0;
|
margin: 10px 0px 5px 0;
|
||||||
/deep/ .ivu-input.ivu-input-large {
|
|
||||||
border: 2px solid $theme_color;
|
.search-input {
|
||||||
font-size: 12px;
|
width: 100%;
|
||||||
height: 34px;
|
|
||||||
&:focus {
|
:deep(.el-input__wrapper) {
|
||||||
|
border: 2px solid #409EFF;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding-left: 26px;
|
||||||
|
padding-right: calc(#{$btn-gap * 2} + #{$btn-width});
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: normal;
|
||||||
|
height: $input-height;
|
||||||
|
color: #999;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/deep/ .ivu-input-group-append {
|
|
||||||
border: 1px solid $theme_color;
|
.search-btn {
|
||||||
border-left: none;
|
position: absolute;
|
||||||
height: 30px;
|
right: $btn-gap;
|
||||||
background-color: $theme_color;
|
top: $btn-gap;
|
||||||
|
bottom: $btn-gap;
|
||||||
|
width: $btn-width;
|
||||||
|
border-radius: 0 3px 3px 0;
|
||||||
|
cursor: pointer;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 1;
|
||||||
|
background-color: #409EFF;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
button {
|
transition: background 0.2s;
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 600;
|
&:hover {
|
||||||
line-height: 1;
|
background-color: #66b1ff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.logo-img {
|
|
||||||
position: absolute;
|
.search-embedded.search {
|
||||||
left: -360px;
|
width: 100%;
|
||||||
top: -9px;
|
|
||||||
width: 150px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
}
|
||||||
.store-search{
|
|
||||||
padding: 0 9px;
|
.search-box{
|
||||||
border-radius: 0;
|
margin-left: 28px;
|
||||||
&:nth-child(2){
|
}
|
||||||
margin-left: -5px;
|
|
||||||
|
.search-type {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
gap: 4px;
|
||||||
|
height: 22px;
|
||||||
|
padding-left: 18px;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-type-item {
|
||||||
|
padding: 2px 10px;
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
|
color: #666;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 18px;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: $theme_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: #fff;
|
||||||
|
background: $theme_color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.btn-div{
|
|
||||||
position: relative;
|
.search-type + .search {
|
||||||
height: 0px;
|
margin-top: 0;
|
||||||
top: -38px;
|
|
||||||
left: 336px;
|
|
||||||
}
|
}
|
||||||
|
.logo-img {
|
||||||
|
max-width: 150px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-list {
|
||||||
|
margin-left: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-item {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 16px;
|
||||||
|
letter-spacing: 0px;
|
||||||
|
margin-right: 17px;
|
||||||
|
color: #666666;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.suggest-panel {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: calc(100% + 8px);
|
||||||
|
z-index: 30;
|
||||||
|
padding: 8px 0;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||