Compare commits
1175 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e987ac99e | ||
|
|
99a073484b | ||
|
|
831a860ce2 | ||
|
|
610a7feeca | ||
|
|
6275b14570 | ||
|
|
b2bf89996f | ||
|
|
7b8be18bd6 | ||
|
|
14b55e118c | ||
|
|
fe59f8bca7 | ||
|
|
ede900560d | ||
|
|
376a5b89c2 | ||
|
|
cd3b091649 | ||
|
|
1df7d0b2c3 | ||
|
|
485e2ff3d7 | ||
|
|
898aca526d | ||
|
|
129a386f42 | ||
|
|
bbb9f2d906 | ||
|
|
1bc8826aac | ||
|
|
586490c31a | ||
|
|
a2a142e546 | ||
|
|
e138e49e27 | ||
|
|
9212f14ffd | ||
|
|
27379c8f3f | ||
|
|
331dd51255 | ||
|
|
29bb629928 | ||
|
|
a5652f24f3 | ||
|
|
299db632be | ||
|
|
dc8e726b26 | ||
|
|
4398b0dde6 | ||
|
|
404379287f | ||
|
|
1a5a0a798a | ||
|
|
2793c61436 | ||
|
|
bfd18f1e3c | ||
|
|
271889cb78 | ||
|
|
62722e26b9 | ||
|
|
ff8e97bb97 | ||
|
|
4a2213c856 | ||
|
|
4eb0810099 | ||
|
|
63fe824223 | ||
|
|
7ee376827b | ||
|
|
9ffc6dd32d | ||
|
|
80230993c6 | ||
|
|
7b4f62ad1c | ||
|
|
3555582349 | ||
|
|
1e220ea385 | ||
|
|
a5d516f340 | ||
|
|
690763db2c | ||
|
|
a7c6200601 | ||
|
|
396ab56265 | ||
|
|
4f0b158c7d | ||
|
|
c7fa7bce3d | ||
|
|
10736d0638 | ||
|
|
7a13c37ead | ||
|
|
782c970228 | ||
|
|
6eb1da80c8 | ||
|
|
c612b569e0 | ||
|
|
9dafa1729d | ||
|
|
e245405325 | ||
|
|
1e0194d4bb | ||
|
|
7881a34fec | ||
|
|
1e206d4af6 | ||
|
|
049a5ffc9f | ||
|
|
51390bf6ca | ||
|
|
c9f905b396 | ||
|
|
58f36787f5 | ||
|
|
e750422cee | ||
|
|
66516f7a47 | ||
|
|
8152b8daea | ||
|
|
6245d4fb61 | ||
|
|
fce2753666 | ||
|
|
d9ee8386a3 | ||
|
|
c41e99f7e0 | ||
|
|
74b18e1d4f | ||
|
|
3e064cf976 | ||
|
|
d082a3a70b | ||
|
|
0f6f54635e | ||
|
|
a84ad79665 | ||
|
|
a3ea6de99d | ||
|
|
4c37716fb1 | ||
|
|
a68affad2a | ||
|
|
4a0d0ee3df | ||
|
|
b30d35b72b | ||
|
|
7190d106ab | ||
|
|
174aacd231 | ||
|
|
f51c075891 | ||
|
|
4ed660ffe8 | ||
|
|
c3609b59b2 | ||
|
|
14fa03b586 | ||
|
|
8818dc957c | ||
|
|
123c0971da | ||
|
|
fec30ce3e7 | ||
|
|
0349b56a6f | ||
|
|
4266a5b0b9 | ||
|
|
c25bdc27f7 | ||
|
|
75ad109b81 | ||
|
|
035497d3ec | ||
|
|
23473d2648 | ||
|
|
80f26a9459 | ||
|
|
57da276469 | ||
|
|
b05b144bd9 | ||
|
|
eee17ff269 | ||
|
|
f8ee2f5508 | ||
|
|
001cf56863 | ||
|
|
4ae09764cb | ||
|
|
4759a2d6b5 | ||
|
|
7e2ac57300 | ||
|
|
c845eabe69 | ||
|
|
7efcd3a614 | ||
|
|
947a2a7ce4 | ||
|
|
26c613faad | ||
|
|
4df39d1d2b | ||
|
|
0a51e4bf7c | ||
|
|
50fceedd10 | ||
|
|
fde4807f95 | ||
|
|
30ef1b3588 | ||
|
|
b7a86c9003 | ||
|
|
b47fba8d37 | ||
|
|
4a655509ed | ||
|
|
7d3537dbc0 | ||
|
|
c21e5ab383 | ||
|
|
4430003475 | ||
|
|
0e59a39006 | ||
|
|
e92ee33ee0 | ||
|
|
c25f161f99 | ||
|
|
886785acc2 | ||
|
|
11d389a871 | ||
|
|
af603074d5 | ||
|
|
ef78df0887 | ||
|
|
88dc9adaad | ||
|
|
5e92c69f64 | ||
|
|
04c761ba5f | ||
|
|
f324fe4ce4 | ||
|
|
5e15d68b9f | ||
|
|
9f61711154 | ||
|
|
6e8b14ab3b | ||
|
|
2d3f85dbea | ||
|
|
cf59208d7a | ||
|
|
fecfd2ffe4 | ||
|
|
2bf71c9fec | ||
|
|
0fcdc4b32c | ||
|
|
3671e373ce | ||
|
|
5fd9ff5093 | ||
|
|
32e4c45ef1 | ||
|
|
847bd705bb | ||
|
|
a7df6a480a | ||
|
|
5aa919b200 | ||
|
|
c79c8c77ca | ||
|
|
f9c4f9fa50 | ||
|
|
c1b2f097c2 | ||
|
|
08e71bd933 | ||
|
|
2ca1dc93c2 | ||
|
|
46e8de37f8 | ||
|
|
7c92f47be5 | ||
|
|
24262f3812 | ||
|
|
7fbd055c47 | ||
|
|
25dce9601d | ||
|
|
46e420a892 | ||
|
|
12d6688b6f | ||
|
|
12c1f633cc | ||
|
|
b94de1d201 | ||
|
|
59cc2d4ffd | ||
|
|
1facd77f78 | ||
|
|
902a245674 | ||
|
|
2fd881f172 | ||
|
|
fb3027b34d | ||
|
|
0145f18912 | ||
|
|
c4068f4dfc | ||
|
|
b002522cf0 | ||
|
|
d55fe9f988 | ||
|
|
a0a859cf77 | ||
|
|
7e251151c6 | ||
|
|
802366f44c | ||
|
|
647ed0a861 | ||
|
|
7c968cb91c | ||
|
|
1677bbbee3 | ||
|
|
fd69d4dda0 | ||
|
|
26f5087072 | ||
|
|
97a48e5267 | ||
|
|
38b2a5363b | ||
|
|
9aafc7da9a | ||
|
|
c0388be7c5 | ||
|
|
7284949cd7 | ||
|
|
d083ca165e | ||
|
|
b020d4bf11 | ||
|
|
ce62b2d01a | ||
|
|
ddfdd6c5c2 | ||
|
|
dc0f14021d | ||
|
|
faf6d4ff91 | ||
|
|
688c17613c | ||
|
|
19229449d4 | ||
|
|
467d9b1456 | ||
|
|
3f34e06eae | ||
|
|
ae1ee4d1cb | ||
|
|
572a14d171 | ||
|
|
cf3d09b39a | ||
|
|
41f36bd16c | ||
|
|
3af00e3aad | ||
|
|
a920e1fe80 | ||
|
|
7a1fb943de | ||
|
|
27655b80a5 | ||
|
|
1690888782 | ||
|
|
2ef51857b5 | ||
|
|
e7460cabc5 | ||
|
|
f588a2be99 | ||
|
|
3ab96bce79 | ||
|
|
49e72ab6bf | ||
|
|
da91dbf2d7 | ||
|
|
24974efe5f | ||
|
|
a25a63b316 | ||
|
|
335d981dee | ||
|
|
5e493288f0 | ||
|
|
60277b42d4 | ||
|
|
39e0999481 | ||
|
|
a5d4a1c5d1 | ||
|
|
754749ff4d | ||
|
|
295d790dab | ||
|
|
c20d156e19 | ||
|
|
a7315eeb12 | ||
|
|
8a0d844adb | ||
|
|
2574622760 | ||
|
|
cc5eb45624 | ||
|
|
9aac434f1a | ||
|
|
9ad4d52352 | ||
|
|
2131a724a6 | ||
|
|
3fa0cbdfe7 | ||
|
|
0584eeb643 | ||
|
|
c89c320ee9 | ||
|
|
2ee949830a | ||
|
|
1697a85de6 | ||
|
|
85868a322e | ||
|
|
a85684bb96 | ||
|
|
43b6c24919 | ||
|
|
c5863204c8 | ||
|
|
349d760a50 | ||
|
|
8374e410f4 | ||
|
|
3aec25bbdd | ||
|
|
92b6d309e4 | ||
|
|
aa0eee9812 | ||
|
|
89e48b0979 | ||
|
|
585eb0e0de | ||
|
|
58fba95c0f | ||
|
|
c650ae418d | ||
|
|
0ed3d3afa7 | ||
|
|
1df97c4106 | ||
|
|
99300a8715 | ||
|
|
5a54d537b5 | ||
|
|
20fbd266f4 | ||
|
|
a1abcff2d5 | ||
|
|
052c1362e0 | ||
|
|
30a41b59f4 | ||
|
|
7ae08dea69 | ||
|
|
457bfbf6d0 | ||
|
|
21ab3d159e | ||
|
|
749de1b0e9 | ||
|
|
5418ace2fc | ||
|
|
e54e865ce5 | ||
|
|
97cc8cce0d | ||
|
|
ee02691601 | ||
|
|
466ca12c91 | ||
|
|
b336512a5b | ||
|
|
cfcab79a6d | ||
|
|
2cc0e81445 | ||
|
|
408efdb631 | ||
|
|
df481cd2b5 | ||
|
|
f2f7928068 | ||
|
|
cb0f8c2001 | ||
|
|
829b00d3c8 | ||
|
|
5bbcda5b5f | ||
|
|
1b213dc31f | ||
|
|
bfe94e735a | ||
|
|
8993e48ae9 | ||
|
|
fda538ce92 | ||
|
|
e09d175fa8 | ||
|
|
e1e735ff46 | ||
|
|
179f3f1146 | ||
|
|
940af4b622 | ||
|
|
dedef13719 | ||
|
|
f2178a7548 | ||
|
|
537fa7b7ea | ||
|
|
e4c5cfba61 | ||
|
|
5b79b92566 | ||
|
|
c2c9f99c68 | ||
|
|
a062f6a173 | ||
|
|
c07499770b | ||
|
|
833209bfbf | ||
|
|
ba519bd463 | ||
|
|
4aa9b19c99 | ||
|
|
e72e5ad83f | ||
|
|
dc2ef79fc0 | ||
|
|
afea334ca0 | ||
|
|
c246a94365 | ||
|
|
7c87c541f2 | ||
|
|
587c0aa864 | ||
|
|
d8c596515e | ||
|
|
55d1b84059 | ||
|
|
6814b2ae6b | ||
|
|
686aead9f2 | ||
|
|
20098751ee | ||
|
|
443fb80d6b | ||
|
|
ef43ac99c5 | ||
|
|
7ac449e71e | ||
|
|
44d93ec198 | ||
|
|
294a0df50f | ||
|
|
621c9fbeb2 | ||
|
|
288304c536 | ||
|
|
dbdf8f862c | ||
|
|
4b5df9f680 | ||
|
|
b98ded125a | ||
|
|
62933c7ef6 | ||
|
|
b5363033d6 | ||
|
|
d0e511ff98 | ||
|
|
84016134f2 | ||
|
|
b23f597060 | ||
|
|
2c64ff131b | ||
|
|
b9bed1d6d8 | ||
|
|
e1b1795be2 | ||
|
|
96c499f108 | ||
|
|
dcff70b43b | ||
|
|
7f9c0e8812 | ||
|
|
4f41f766fe | ||
|
|
29248dae3b | ||
|
|
e3a135f337 | ||
|
|
5cafeb9a50 | ||
|
|
14ef7cb40a | ||
|
|
446aed8515 | ||
|
|
1a972a5b09 | ||
|
|
e827c53ebc | ||
|
|
ae84589963 | ||
|
|
81c11062f2 | ||
|
|
704fb336e6 | ||
|
|
7267473617 | ||
|
|
d11f13a0fd | ||
|
|
2a2bd56df4 | ||
|
|
78aa612a50 | ||
|
|
c6275b162f | ||
|
|
fe4073597e | ||
|
|
d5f8ab6909 | ||
|
|
29a15b55cd | ||
|
|
9da435d0af | ||
|
|
2e6aac79ff | ||
|
|
d1d8bbaeb6 | ||
|
|
f6c974f73e | ||
|
|
9aeaedb2d6 | ||
|
|
6b505c474e | ||
|
|
4977dd6e72 | ||
|
|
611b90e4c4 | ||
|
|
f251aab7f2 | ||
|
|
61a39bc973 | ||
|
|
25c5cfc39f | ||
|
|
e3be541ccd | ||
|
|
e3c09bed8d | ||
|
|
837e14ab0e | ||
|
|
0fb3d05d3e | ||
|
|
bf5fb8aea5 | ||
|
|
83ee99c1d1 | ||
|
|
2d8d668f4e | ||
|
|
170456ef76 | ||
|
|
1bf6ed058e | ||
|
|
2bc920719c | ||
|
|
3481d09177 | ||
|
|
d1438e11bf | ||
|
|
2981e57b9a | ||
|
|
c321ae5886 | ||
|
|
fb10cbb7d2 | ||
|
|
8559ccc4f3 | ||
|
|
2b81130e0a | ||
|
|
ae8a75a975 | ||
|
|
14d5bf3d78 | ||
|
|
3f9ab86fae | ||
|
|
d861e9b2ce | ||
|
|
4024f62a6c | ||
|
|
c844176703 | ||
|
|
17ae45e74c | ||
|
|
5e3c72b843 | ||
|
|
4c5e825990 | ||
|
|
c24f179edc | ||
|
|
df4a4e333c | ||
|
|
f505323837 | ||
|
|
b6f4138048 | ||
|
|
c4dd7832f8 | ||
|
|
5697f49bf1 | ||
|
|
06b9d035b1 | ||
|
|
dfb91baa09 | ||
|
|
e216a3b5ae | ||
|
|
0ad4efa6a6 | ||
|
|
9a725ed9c2 | ||
|
|
9dc7291c29 | ||
|
|
270eef92ef | ||
|
|
e58964633c | ||
|
|
b65e808972 | ||
|
|
13d2b1b883 | ||
|
|
37c188ffa7 | ||
|
|
db199feb00 | ||
|
|
ced8c4996e | ||
|
|
e65f6c9209 | ||
|
|
7279c48a10 | ||
|
|
14f3c29c04 | ||
|
|
f1eddbb839 | ||
|
|
5b155d0d9c | ||
|
|
1216c2d748 | ||
|
|
8600f85a8f | ||
|
|
29acc9232f | ||
|
|
fbc4f96976 | ||
|
|
7ebac81dba | ||
|
|
6e3b989a13 | ||
|
|
7c1c1b0045 | ||
|
|
0343b77b1e | ||
|
|
06a0332878 | ||
|
|
18ebaa41c4 | ||
|
|
910e83ea4b | ||
|
|
b2c03d6956 | ||
|
|
433b980c52 | ||
|
|
a500b2631b | ||
|
|
56879c4d64 | ||
|
|
5c825f44df | ||
|
|
e80007e3ea | ||
|
|
309bbfdb62 | ||
|
|
20bc619947 | ||
|
|
9b3cad6488 | ||
|
|
853814df00 | ||
|
|
a0b0e31d5c | ||
|
|
360d8a5220 | ||
|
|
5772bdcd1e | ||
|
|
c43039abca | ||
|
|
1cd87fb87c | ||
|
|
a75ed0f33c | ||
|
|
14f7fc7828 | ||
|
|
89417e6f6d | ||
|
|
f442644bdd | ||
|
|
f8c86c25d4 | ||
|
|
32baa0a091 | ||
|
|
fb607a3c41 | ||
|
|
4057f8105e | ||
|
|
9b84048fe9 | ||
|
|
ed410ebb7f | ||
|
|
610b767814 | ||
|
|
c4d46326ad | ||
|
|
493e9ccc64 | ||
|
|
bac4c55835 | ||
|
|
bf35e6a26d | ||
|
|
c9d95b5edd | ||
|
|
bf68f22bac | ||
|
|
5de1be8b54 | ||
|
|
a33fa55f8c | ||
|
|
f9ff953e0a | ||
|
|
6235597ba6 | ||
|
|
5a7e7a0ab7 | ||
|
|
625b5a5cbd | ||
|
|
74c5171972 | ||
|
|
1ff8565566 | ||
|
|
807e2a69f1 | ||
|
|
95b34af3b7 | ||
|
|
37afeaaa04 | ||
|
|
60f61435bb | ||
|
|
2ed0f94f2f | ||
|
|
cc8c1a5a30 | ||
|
|
1f7a272aff | ||
|
|
a3a86a3d16 | ||
|
|
5a3ecfad93 | ||
|
|
bbc8763e76 | ||
|
|
2464e1d803 | ||
|
|
7ef72424bb | ||
|
|
4344e06558 | ||
|
|
f56ce72034 | ||
|
|
ae5dd3abde | ||
|
|
22a05e2cef | ||
|
|
deb0e60a06 | ||
|
|
03a32aa3d6 | ||
|
|
41acd31fec | ||
|
|
7e7f5ef5fa | ||
|
|
a06620e34b | ||
|
|
952f06f73d | ||
|
|
3838cf2ebf | ||
|
|
e3cc92bde9 | ||
|
|
0eafe25fa2 | ||
|
|
bbf2849a19 | ||
|
|
4ff352b5c1 | ||
|
|
fcc08de485 | ||
|
|
d9f6f165f9 | ||
|
|
a7d1ef9e70 | ||
|
|
d6021c6f28 | ||
|
|
cf9c58799c | ||
|
|
8ad648c194 | ||
|
|
1a6d1959c4 | ||
|
|
7a9b7c5a35 | ||
|
|
32a4b83fa9 | ||
|
|
79097e11df | ||
|
|
8b1ddf6b89 | ||
|
|
c4ac98380a | ||
|
|
e613558f25 | ||
|
|
ca15bf10bb | ||
|
|
4138eed6a2 | ||
|
|
03d53ddc49 | ||
|
|
bf5d742af0 | ||
|
|
3e0d1a4e31 | ||
|
|
a90b4af799 | ||
|
|
027d546151 | ||
|
|
1218e2077c | ||
|
|
8c981d71b0 | ||
|
|
5ce7436e1d | ||
|
|
f6a1edea5b | ||
|
|
126b8679fe | ||
|
|
007fdd7342 | ||
|
|
78bb668fad | ||
|
|
ccdc532142 | ||
|
|
a3e80c306c | ||
|
|
ccc536b83f | ||
|
|
af19dddc5a | ||
|
|
c3f387e5b5 | ||
|
|
7f2a3c5133 | ||
|
|
59d8c30d91 | ||
|
|
45e167dd5b | ||
|
|
742ee01346 | ||
|
|
18b17e846b | ||
|
|
7d82d5ad34 | ||
|
|
b4be7c3ad7 | ||
|
|
4a41424c73 | ||
|
|
c659732c5d | ||
|
|
6ce886212f | ||
|
|
edb3e78650 | ||
|
|
3359662363 | ||
|
|
b586a93722 | ||
|
|
31c746f639 | ||
|
|
f7d1abc91b | ||
|
|
18af6c92f3 | ||
|
|
2b9045b8f4 | ||
|
|
8a4bf159f8 | ||
|
|
b186b7f551 | ||
|
|
5a38f81a4a | ||
|
|
2c81655f97 | ||
|
|
615acd6363 | ||
|
|
539afbd153 | ||
|
|
e2b67fd1cb | ||
|
|
24b2247a1f | ||
|
|
a561368cf4 | ||
|
|
3de4615719 | ||
|
|
8434c19887 | ||
|
|
ef5a6161d3 | ||
|
|
aea7a0eb1e | ||
|
|
29cd7f3952 | ||
|
|
1a954ad675 | ||
|
|
6d66d1ec35 | ||
|
|
eda0d50636 | ||
|
|
37cf01e182 | ||
|
|
01797b9932 | ||
|
|
fd6fdd3960 | ||
|
|
4f2c857bbf | ||
|
|
786ac3f365 | ||
|
|
d3966a8e29 | ||
|
|
d70431691b | ||
|
|
0e9c2fffb5 | ||
|
|
2c9bfdac17 | ||
|
|
4c8a182300 | ||
|
|
9a2fbeacb8 | ||
|
|
608b0b0c41 | ||
|
|
ef6bccc543 | ||
|
|
f6bef97830 | ||
|
|
5feafb676e | ||
|
|
84de6377eb | ||
|
|
a2396a4876 | ||
|
|
cce7839324 | ||
|
|
d1d592c633 | ||
|
|
6a6a6e43d6 | ||
|
|
5efd085da5 | ||
|
|
8c5f5cf858 | ||
|
|
e3747c81f5 | ||
|
|
269b7fa710 | ||
|
|
c4ce270e1a | ||
|
|
b6ffa0f01f | ||
|
|
8f6a6bf47d | ||
|
|
55189e1693 | ||
|
|
04acffa985 | ||
|
|
e456ee1be9 | ||
|
|
1d78471933 | ||
|
|
85ab238067 | ||
|
|
c798070d12 | ||
|
|
e9de98e123 | ||
|
|
33ac4db9ba | ||
|
|
a3f06b2e7f | ||
|
|
83bcc38735 | ||
|
|
da778f7b85 | ||
|
|
d26bd44af7 | ||
|
|
55383ff5fc | ||
|
|
d9ad96249b | ||
|
|
6a41d536fa | ||
|
|
598e78bba7 | ||
|
|
ff1dfebd86 | ||
|
|
e3c422c5a3 | ||
|
|
0210024dc4 | ||
|
|
68e9c5571c | ||
|
|
fa9215fe5b | ||
|
|
0332b25ea0 | ||
|
|
5f343c493b | ||
|
|
9b3beb0dc0 | ||
|
|
ccac6319a1 | ||
|
|
f71a758cc0 | ||
|
|
637f6ee7ac | ||
|
|
54aeccc534 | ||
|
|
7eea91324d | ||
|
|
a2313e4b19 | ||
|
|
d5b94fdbd2 | ||
|
|
d48952079b | ||
|
|
fd77a3703c | ||
|
|
5fee02bfcd | ||
|
|
25671ad532 | ||
|
|
35d3330f9d | ||
|
|
947750c5c9 | ||
|
|
1765620899 | ||
|
|
a48e9d13ab | ||
|
|
d2e6dd6bf3 | ||
|
|
382ef05884 | ||
|
|
4a7f691525 | ||
|
|
92f0cca62d | ||
|
|
fd7057525e | ||
|
|
bd59cc18a7 | ||
|
|
49d0903a2d | ||
|
|
829e1d76c2 | ||
|
|
95a7766507 | ||
|
|
68626a8cfd | ||
|
|
17dba6007b | ||
|
|
1f3164832d | ||
|
|
e5082bbfe7 | ||
|
|
2d1aa60e1c | ||
|
|
2840dec1b7 | ||
|
|
4f5c1a8f2b | ||
|
|
3e41f86386 | ||
|
|
af30593ce4 | ||
|
|
165da4d980 | ||
|
|
5c678d1117 | ||
|
|
4d313aea76 | ||
|
|
d9059263ee | ||
|
|
c7d87be485 | ||
|
|
ed28a26a6b | ||
|
|
d3a71dc6fb | ||
|
|
6555557534 | ||
|
|
f1dc696967 | ||
|
|
5f96b68e5e | ||
|
|
e150bf5f59 | ||
|
|
ee27ffdeef | ||
|
|
cf22855307 | ||
|
|
5ad8dc6ee0 | ||
|
|
9f80450e0c | ||
|
|
bccb99e580 | ||
|
|
5927b8b05d | ||
|
|
1ad60d560f | ||
|
|
fd336262f7 | ||
|
|
682e8d2947 | ||
|
|
ab078d7fd9 | ||
|
|
a216e42922 | ||
|
|
edff9daa62 | ||
|
|
a907462a0a | ||
|
|
92e28b4176 | ||
|
|
f881f7c7b6 | ||
|
|
05b9b6733d | ||
|
|
760269db13 | ||
|
|
2eb6455122 | ||
|
|
e1cdb85d3f | ||
|
|
7b4649b430 | ||
|
|
309d47cb5b | ||
|
|
12ab1035ee | ||
|
|
f177221c7e | ||
|
|
edbbbf770c | ||
|
|
7c4e82b623 | ||
|
|
cfadba7ad3 | ||
|
|
0c72be5d8e | ||
|
|
10dc638f1a | ||
|
|
14681aec1e | ||
|
|
f3d1635c6c | ||
|
|
d9a16fa54b | ||
|
|
5c7a5522d4 | ||
|
|
c2cf1ce0ef | ||
|
|
92f4a59e17 | ||
|
|
a96784dbfb | ||
|
|
d69c31b773 | ||
|
|
caf63a3869 | ||
|
|
9e07b0b957 | ||
|
|
0bb42973ba | ||
|
|
3f8bf89836 | ||
|
|
a4b7beb735 | ||
|
|
6d1eb9d47f | ||
|
|
5a668e63cc | ||
|
|
01812799c4 | ||
|
|
ef6ce5d5e2 | ||
|
|
59cbdd8d4d | ||
|
|
df8452f7de | ||
|
|
680a7df34d | ||
|
|
5dd82a44df | ||
|
|
b4dfec99a2 | ||
|
|
4a4e4a69a9 | ||
|
|
a3258e9d1a | ||
|
|
72c29abdd4 | ||
|
|
6c171a107c | ||
|
|
4f89bc32d1 | ||
|
|
3de8b4ca4d | ||
|
|
633aef8f10 | ||
|
|
145deb5c70 | ||
|
|
aad5603c68 | ||
|
|
7dd5223dea | ||
|
|
e6e3afcca7 | ||
|
|
e1aa2ec029 | ||
|
|
bc3463501f | ||
|
|
f0d887bc0c | ||
|
|
28978f0143 | ||
|
|
1afb76de67 | ||
|
|
78010354bc | ||
|
|
360aed8743 | ||
|
|
b87260f34f | ||
|
|
ac19d53c8c | ||
|
|
edeca69ca9 | ||
|
|
a283490d08 | ||
|
|
3f0dbdcfed | ||
|
|
8836690b1a | ||
|
|
09277b1842 | ||
|
|
26ece732ff | ||
|
|
fb72d68235 | ||
|
|
513e176bf6 | ||
|
|
ffb12a0e6b | ||
|
|
c086f337a4 | ||
|
|
1483691937 | ||
|
|
42bbc6767c | ||
|
|
a5aa853f06 | ||
|
|
a06d1b6d5e | ||
|
|
a35c28b20f | ||
|
|
d9ed65840f | ||
|
|
15cba26b7b | ||
|
|
1097cbb60e | ||
|
|
72c4b6c06a | ||
|
|
b4b8eaecb0 | ||
|
|
83190dc848 | ||
|
|
97b59580ab | ||
|
|
609a74e559 | ||
|
|
2f68e749c7 | ||
|
|
069c104d09 | ||
|
|
57812bf484 | ||
|
|
d12e4edd08 | ||
|
|
088934adbd | ||
|
|
3405090597 | ||
|
|
8fcd186ed3 | ||
|
|
0f561dc394 | ||
|
|
c8c7dbf38e | ||
|
|
b06343c8bf | ||
|
|
2d0f12a9ff | ||
|
|
70db40b68d | ||
|
|
4aa8787fd8 | ||
|
|
8e71f3de18 | ||
|
|
b03f5ae055 | ||
|
|
871eb1f74f | ||
|
|
2502b821d4 | ||
|
|
eab8fa7311 | ||
|
|
65340be4da | ||
|
|
e4b5efd4eb | ||
|
|
ad02997ff7 | ||
|
|
66abf4c711 | ||
|
|
fd11b0cd83 | ||
|
|
0788bd8e79 | ||
|
|
e247aa69ba | ||
|
|
afeb65d616 | ||
|
|
bf210c0cdd | ||
|
|
5783cef8aa | ||
|
|
c092e2cd85 | ||
|
|
b9c15efec4 | ||
|
|
8eb3ef3488 | ||
|
|
b424457fff | ||
|
|
19b681ea97 | ||
|
|
2e2cd0686c | ||
|
|
28b097cfca | ||
|
|
ff125d53aa | ||
|
|
b04870c607 | ||
|
|
f2192d4825 | ||
|
|
22c70edcc4 | ||
|
|
97f4e1bc19 | ||
|
|
d4ffefce8a | ||
|
|
34ea3761f3 | ||
|
|
842b5e59bb | ||
|
|
126af8f857 | ||
|
|
ec97835313 | ||
|
|
6d54e23321 | ||
|
|
b25c14cb88 | ||
|
|
04d3483b06 | ||
|
|
4dd1ee8ecb | ||
|
|
a5c6193e29 | ||
|
|
7db1975e96 | ||
|
|
c3b062cfbf | ||
|
|
abf763e454 | ||
|
|
5088d49c0c | ||
|
|
a3849bb5b7 | ||
|
|
9793d1b274 | ||
|
|
f265cd4053 | ||
|
|
f917c96aa3 | ||
|
|
487c34e6a9 | ||
|
|
9e65eded68 | ||
|
|
cbff4eb618 | ||
|
|
9da28c7363 | ||
|
|
158adc8499 | ||
|
|
52db66616e | ||
|
|
ecc068f976 | ||
|
|
8bdf988a14 | ||
|
|
ace910eb62 | ||
|
|
047c24c151 | ||
|
|
c2740e87d9 | ||
|
|
750ad8fb9a | ||
|
|
e501c1beaf | ||
|
|
8d814257b2 | ||
|
|
118f93fb5a | ||
|
|
b2ac231af3 | ||
|
|
969f597557 | ||
|
|
f63794c9e1 | ||
|
|
bccf4b8d4f | ||
|
|
7808360d1c | ||
|
|
d296acfb94 | ||
|
|
d8f1e361d7 | ||
|
|
3a7d19e8a3 | ||
|
|
6d9a96d0ec | ||
|
|
f218f16781 | ||
|
|
833bc63cad | ||
|
|
5a0842eba7 | ||
|
|
908693fde5 | ||
|
|
9b86d634c5 | ||
|
|
a5a30c5148 | ||
|
|
26751d21f4 | ||
|
|
f0b9ea7385 | ||
|
|
aafa040327 | ||
|
|
869b4f2c35 | ||
|
|
fe57e8a76e | ||
|
|
2001383f0f | ||
|
|
a4d0874eda | ||
|
|
e68239c6ea | ||
|
|
d89375a7ce | ||
|
|
32988d0cee | ||
|
|
01c475ea95 | ||
|
|
b62b23562e | ||
|
|
5fd1522f17 | ||
|
|
9b7613f436 | ||
|
|
84a3e4b384 | ||
|
|
8113852ecc | ||
|
|
cbf15f6c49 | ||
|
|
cd48c4b81c | ||
|
|
6488daac1e | ||
|
|
5cd44c6526 | ||
|
|
4eb0730605 | ||
|
|
b4cb45389b | ||
|
|
0f2789b728 | ||
|
|
98ddab4f7b | ||
|
|
5199cfe947 | ||
|
|
3c97be837d | ||
|
|
70f07549f6 | ||
|
|
641e05cfd7 | ||
|
|
5d62f14378 | ||
|
|
f920a30389 | ||
|
|
c7e52925c1 | ||
|
|
0c140fa4c1 | ||
|
|
eaaa634e5a | ||
|
|
68478588b5 | ||
|
|
d3c943925c | ||
|
|
3cb9790d43 | ||
|
|
5bdfa981cd | ||
|
|
dc8f708cc2 | ||
|
|
8805d78dee | ||
|
|
aab7167e35 | ||
|
|
80392c74d5 | ||
|
|
b12c1b12c6 | ||
|
|
8180769021 | ||
|
|
2c0776d388 | ||
|
|
7fd07db556 | ||
|
|
01d9af671d | ||
|
|
bdb7c8a3f3 | ||
|
|
d37e8e8b4f | ||
|
|
7ff1c39297 | ||
|
|
9401aed189 | ||
|
|
a3f55fc57c | ||
|
|
c7d1488296 | ||
|
|
d5efb69678 | ||
|
|
4ba80a99a5 | ||
|
|
02822598c2 | ||
|
|
3fa1ed6222 | ||
|
|
1256ff79cd | ||
|
|
5d9108c646 | ||
|
|
396e46636a | ||
|
|
8573e20206 | ||
|
|
9b220dbc68 | ||
|
|
28fbbe1a45 | ||
|
|
cbc81f3c74 | ||
|
|
2887294071 | ||
|
|
ff16d1db79 | ||
|
|
d0938be8ab | ||
|
|
f101b715cf | ||
|
|
bbff9d2e4f | ||
|
|
f82b71332e | ||
|
|
4cda519218 | ||
|
|
24b826e688 | ||
|
|
9290236ae8 | ||
|
|
a2b6c89935 | ||
|
|
c2dae8e2bb | ||
|
|
cb6fa7fa74 | ||
|
|
cd156feba9 | ||
|
|
97f9e44e8a | ||
|
|
f6f8141ccf | ||
|
|
6ab1165cff | ||
|
|
433d79254d | ||
|
|
829af27f30 | ||
|
|
925ef2ffc4 | ||
|
|
5f0cf841ed | ||
|
|
85da153440 | ||
|
|
e114e56ab2 | ||
|
|
e7627e5904 | ||
|
|
1be5319436 | ||
|
|
b8de5a8a49 | ||
|
|
2de901a9c9 | ||
|
|
801850f1f7 | ||
|
|
1ddd2d7362 | ||
|
|
1aaeab99cc | ||
|
|
32cecd0e98 | ||
|
|
4d3d0fac2a | ||
|
|
c74bf0da82 | ||
|
|
bb2e4a6721 | ||
|
|
e1875b17da | ||
|
|
93a7689a94 | ||
|
|
380554ac2b | ||
|
|
90b6fcf597 | ||
|
|
f836b738f0 | ||
|
|
3156af3448 | ||
|
|
3681e9f7fa | ||
|
|
8abb7ffd13 | ||
|
|
bfc99196a8 | ||
|
|
6b9eb80be9 | ||
|
|
35bd646600 | ||
|
|
f4d4c04659 | ||
|
|
2322394a84 | ||
|
|
235ccab488 | ||
|
|
3933523142 | ||
|
|
d0d2d6c2df | ||
|
|
03dc9b724c | ||
|
|
da24bd128d | ||
|
|
652bbf42c8 | ||
|
|
f171cfc468 | ||
|
|
fd36e21197 | ||
|
|
f037b4434c | ||
|
|
c9a3febe47 | ||
|
|
c3b653a90a | ||
|
|
d954f37d4d | ||
|
|
c3e899d65a | ||
|
|
cf72ac3c8b | ||
|
|
49ac45a94a | ||
|
|
40fd3e6d2c | ||
|
|
0bc79ac9ba | ||
|
|
fdd6b879fb | ||
|
|
2b7720be38 | ||
|
|
bb373ef391 | ||
|
|
7b69b96a8a | ||
|
|
0e0a5db339 | ||
|
|
aa3dc4e6f1 | ||
|
|
dcf0cddf48 | ||
|
|
1e2fc44cf0 | ||
|
|
85b4b9a1a9 | ||
|
|
e1cd990c76 | ||
|
|
4a986546eb | ||
|
|
57da75ee0d | ||
|
|
bad35a0e0c | ||
|
|
34e21b209d | ||
|
|
233a0a9364 | ||
|
|
ebc4f888a8 | ||
|
|
916736b0fb | ||
|
|
be3ade4a69 | ||
|
|
d1f4cf9e75 | ||
|
|
54958becc1 | ||
|
|
5979dfb148 | ||
|
|
662b306ad7 | ||
|
|
1637a4215a | ||
|
|
d61decc182 | ||
|
|
b0576d0d55 | ||
|
|
8808a71f7c | ||
|
|
62b7ee89d7 | ||
|
|
9762d78148 | ||
|
|
3206ae2f92 | ||
|
|
744b8074e1 | ||
|
|
76ca18d261 | ||
|
|
cf37c22103 | ||
|
|
2984ac1ef0 | ||
|
|
4186800548 | ||
|
|
9e7de82c9c | ||
|
|
e1852e32c4 | ||
|
|
686416521a | ||
|
|
dc1829de5a | ||
|
|
2b018c4132 | ||
|
|
0315b531c8 | ||
|
|
c4b70f47d2 | ||
|
|
8ab2af4f1c | ||
|
|
ca819b108c | ||
|
|
3a1edc1237 | ||
|
|
bba63d28a5 | ||
|
|
0d679e9871 | ||
|
|
7584a2e689 | ||
|
|
f08be13855 | ||
|
|
673ba2f11b | ||
|
|
9ddfe8e284 | ||
|
|
cc1071a22a | ||
|
|
7c2d897f66 | ||
|
|
bcb1e07ff5 | ||
|
|
7f11756c97 | ||
|
|
72c61ec556 | ||
|
|
2cf7a0157e | ||
|
|
dd18d0e64d | ||
|
|
fbad28f76d | ||
|
|
1f080493be | ||
|
|
b23e804e29 | ||
|
|
46a31d79a5 | ||
|
|
658b005f61 | ||
|
|
b485bb7bec | ||
|
|
baed9d8c4b | ||
|
|
9d177646c7 | ||
|
|
d515dcc656 | ||
|
|
d583243da8 | ||
|
|
cb5eb09bba | ||
|
|
48035f22b6 | ||
|
|
5088f29456 | ||
|
|
53fcb9f57f | ||
|
|
3e44f00a25 | ||
|
|
278574a897 | ||
|
|
4fa27150dc | ||
|
|
bbefa6eeea | ||
|
|
123d90503d | ||
|
|
73ce8a77c3 | ||
|
|
c7199a3bc7 | ||
|
|
965293fc14 | ||
|
|
cba8a36aae | ||
|
|
b7e25130ce | ||
|
|
f1db21b302 | ||
|
|
5ef69f5f5d | ||
|
|
38312fc43b | ||
|
|
75fae9aa2d | ||
|
|
5199ed7df4 | ||
|
|
55dddcbb75 | ||
|
|
a7032ae943 | ||
|
|
4692e711aa | ||
|
|
64c0bc05ed | ||
|
|
bbcb8ec37c | ||
|
|
396f81cd58 | ||
|
|
ec81fb7947 | ||
|
|
fad889355b | ||
|
|
1601813062 | ||
|
|
8ad7ed8aaf | ||
|
|
55275eb390 | ||
|
|
b8e3c39c54 | ||
|
|
602afa385f | ||
|
|
100c2ca978 | ||
|
|
55a43504b6 | ||
|
|
b4eafb711f | ||
|
|
4bb5e12d2d | ||
|
|
d16d67dfc6 | ||
|
|
8e23dd4b1e | ||
|
|
506a9a8764 | ||
|
|
e211997a61 | ||
|
|
2ae5f3a793 | ||
|
|
0460b48bbf | ||
|
|
2b0bf4f7fe | ||
|
|
b8cb5ddff9 | ||
|
|
6b57bb3078 | ||
|
|
410377a578 | ||
|
|
520e91ff9d | ||
|
|
8631c0acc4 | ||
|
|
0e03ea65c5 | ||
|
|
8cf944ce80 | ||
|
|
2ea9a04503 | ||
|
|
f24f927a68 | ||
|
|
244e8c8473 | ||
|
|
382f59f545 | ||
|
|
51a9c62beb | ||
|
|
b9c49f75a5 | ||
|
|
777bdc6d93 | ||
|
|
4fc2e9c5df | ||
|
|
c160d89f17 | ||
|
|
e96431dbe0 | ||
|
|
b8f18712a9 | ||
|
|
bd1ae5558c | ||
|
|
bbf527d419 | ||
|
|
7e32707c8b | ||
|
|
dd8d91d021 | ||
|
|
2c57b36537 | ||
|
|
9861f7a774 | ||
|
|
9b8fc7e1dc | ||
|
|
16458454bd | ||
|
|
fe53668185 | ||
|
|
9c3be6bcc7 | ||
|
|
c30588b9ea | ||
|
|
b6837feb2c | ||
|
|
379d826b44 | ||
|
|
a6034b3535 | ||
|
|
871e88d1e5 | ||
|
|
66ba2b5e82 | ||
|
|
3426100635 | ||
|
|
d20d77c8ec | ||
|
|
150ec0701c | ||
|
|
29946b79d9 | ||
|
|
a765af69ee | ||
|
|
768d187ba6 | ||
|
|
5a76c726c4 | ||
|
|
5dd72f7b2d | ||
|
|
64f8ebd43f | ||
|
|
ac20216437 | ||
|
|
adf90f21e0 | ||
|
|
5f59b7bdd9 | ||
|
|
a9e9d30308 | ||
|
|
a41052cd9c | ||
|
|
10d66dda21 | ||
|
|
7580a79422 | ||
|
|
d9f8d2f4bb | ||
|
|
00553e32e8 | ||
|
|
5a95250bcd | ||
|
|
793669a976 | ||
|
|
dab6ba84d2 | ||
|
|
a3d169d2f0 | ||
|
|
d25ee35268 | ||
|
|
c887a0a14a | ||
|
|
1132be64dc | ||
|
|
67f4bddc4c | ||
|
|
50759aec9f | ||
|
|
e05f313c1a | ||
|
|
74e4ca6479 | ||
|
|
d2c6d02b82 | ||
|
|
3c05d41246 | ||
|
|
8c7806bf3d | ||
|
|
cc9ac79e45 | ||
|
|
4737c354e4 | ||
|
|
1c1784943e | ||
|
|
47c2cd12fe | ||
|
|
25461b7f8f | ||
|
|
2dbd9d542b | ||
|
|
61252f4527 | ||
|
|
4c05c1a7b2 | ||
|
|
f78f323db2 | ||
|
|
3f9d251990 | ||
|
|
f5f93381ab | ||
|
|
1d56ce77f7 | ||
|
|
1482ff8cee | ||
|
|
54438022ff | ||
|
|
0ff054afed | ||
|
|
cbe94c7916 | ||
|
|
3fa46c9afd | ||
|
|
fac92a6c7a | ||
|
|
bd361fa881 | ||
|
|
eb950f11bf | ||
|
|
accb629e14 | ||
|
|
5f791290ca | ||
|
|
fb9992e616 | ||
|
|
6f848954d1 | ||
|
|
0b36b4b81f | ||
|
|
49ad561d54 | ||
|
|
1133684e3b | ||
|
|
8f746dcfea | ||
|
|
602f088dba | ||
|
|
208104c751 | ||
|
|
d84c7679b7 | ||
|
|
1932dbf8a8 | ||
|
|
2ab79d949a | ||
|
|
cc96feb587 | ||
|
|
60baba6bde | ||
|
|
078327e8d5 | ||
|
|
f2f7e511a3 | ||
|
|
2d86b6a928 | ||
|
|
82a4e58c08 | ||
|
|
be58e21519 | ||
|
|
c9263befb3 | ||
|
|
1affa3afbb | ||
|
|
32506c47d4 | ||
|
|
6aa221391a | ||
|
|
81d8f3e421 | ||
|
|
49c149c531 | ||
|
|
9b62c93016 | ||
|
|
20936ca4c8 | ||
|
|
845c83bb09 | ||
|
|
52b0778d59 | ||
|
|
20fcc857d5 | ||
|
|
d807f7f51c | ||
|
|
045d54844f | ||
|
|
99532b7aec |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
jx-callback
|
jx-callback
|
||||||
*.tmp
|
*.tmp
|
||||||
|
swagger/
|
||||||
debug
|
debug
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*.log
|
*.log
|
||||||
@@ -15,4 +16,3 @@ param_parser.go
|
|||||||
*.exe~
|
*.exe~
|
||||||
.vscode
|
.vscode
|
||||||
.idea
|
.idea
|
||||||
./swagger
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
package app_version
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
)
|
|
||||||
|
|
||||||
// AddApplicationVersion 添加app版本控制
|
|
||||||
func AddApplicationVersion(userName, appId, version string) error {
|
|
||||||
config := &model.NewConfig{
|
|
||||||
Type: model.ConfigTypeApplication,
|
|
||||||
Key: appId,
|
|
||||||
Value: version,
|
|
||||||
}
|
|
||||||
dao.WrapAddIDCULDEntity(config, userName)
|
|
||||||
return dao.CreateEntity(dao.GetDB(), config)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateApplicationVersion 修改app版本
|
|
||||||
func UpdateApplicationVersion(appId, version string) error {
|
|
||||||
sql := ` UPDATE new_config c SET c.value = ? WHERE c.key = ? AND c.deleted_at = ? `
|
|
||||||
param := []interface{}{version, appId, utils.DefaultTimeValue}
|
|
||||||
|
|
||||||
_, err := dao.ExecuteSQL(dao.GetDB(), sql, param...)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetApplicationVersion 查询小程序版本控制
|
|
||||||
func GetApplicationVersion(appId string) ([]*model.NewConfig, error) {
|
|
||||||
return dao.QueryConfigs(dao.GetDB(), appId, model.ConfigTypeApplication, "")
|
|
||||||
}
|
|
||||||
@@ -3,15 +3,16 @@ package auth2
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/dao"
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
"git.rosy.net.cn/jx-callback/globals/api"
|
||||||
"github.com/dchest/captcha"
|
"github.com/dchest/captcha"
|
||||||
)
|
)
|
||||||
@@ -32,18 +33,15 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
AuthTypeNone = ""
|
AuthTypeNone = ""
|
||||||
AuthTypePassword = "localpass"
|
AuthTypePassword = "localpass"
|
||||||
AuthTypeEmail = "email"
|
AuthTypeEmail = "email"
|
||||||
AuthTypeMobile = "mobile"
|
AuthTypeMobile = "mobile"
|
||||||
AuthTypeWXApp = "weixinapp" //微信小程序(商家版)
|
|
||||||
AuthTypeWXAppCaishi = "weixinappcs" //微信小程序(用户)
|
|
||||||
AuthTypeWXMini = "weixinmini" //微信小程序
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DefTokenDuration = 7 * 24 * 2 * time.Hour // 正式TOKEN,7天有效期
|
DefTokenDuration = 7 * 24 * time.Hour // 正式TOKEN,7天有效期
|
||||||
TmpTokenDuration = 30 * time.Minute // 临时TOKEN,30分钟有效期
|
TmpTokenDuration = 30 * time.Minute // 临时TOKEN,30分钟有效期
|
||||||
MinCaptchaLen = 4
|
MinCaptchaLen = 4
|
||||||
MaxCaptchaWidth = 400
|
MaxCaptchaWidth = 400
|
||||||
MaxCaptchaHeight = 400
|
MaxCaptchaHeight = 400
|
||||||
@@ -64,7 +62,6 @@ const (
|
|||||||
UpdateUserTypeAdd = 1
|
UpdateUserTypeAdd = 1
|
||||||
UpdateUserTypeDelete = 2
|
UpdateUserTypeDelete = 2
|
||||||
UpdateUserTypeUpdate = 3
|
UpdateUserTypeUpdate = 3
|
||||||
WeCartAppID = "wx4b5930c13f8b1170"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type IUserProvider interface {
|
type IUserProvider interface {
|
||||||
@@ -162,7 +159,6 @@ func getFixedTokenName(token string) *AuthInfo {
|
|||||||
|
|
||||||
func createAuthInfo(user IUser, authBindInfo *AuthBindEx) (authInfo *AuthInfo) {
|
func createAuthInfo(user IUser, authBindInfo *AuthBindEx) (authInfo *AuthInfo) {
|
||||||
token, tokenType := createToken(user, authBindInfo)
|
token, tokenType := createToken(user, authBindInfo)
|
||||||
//user为空 tokenType=2
|
|
||||||
expireDuration := DefTokenDuration
|
expireDuration := DefTokenDuration
|
||||||
authInfo = &AuthInfo{
|
authInfo = &AuthInfo{
|
||||||
AuthBindInfo: authBindInfo,
|
AuthBindInfo: authBindInfo,
|
||||||
@@ -173,9 +169,11 @@ func createAuthInfo(user IUser, authBindInfo *AuthBindEx) (authInfo *AuthInfo) {
|
|||||||
}
|
}
|
||||||
if user != nil {
|
if user != nil {
|
||||||
authInfo.UpdateByIUser(user)
|
authInfo.UpdateByIUser(user)
|
||||||
|
globals.SugarLogger.Debugf("createAuthInfo id:%s, id2:%s, mobile:%s, authInfo:%s", authInfo.GetID(), authInfo.GetID2(), authInfo.GetMobile(), utils.Format4Output(authInfo, true))
|
||||||
} else {
|
} else {
|
||||||
expireDuration = TmpTokenDuration
|
expireDuration = TmpTokenDuration
|
||||||
authInfo.ExpiresAt = time.Now().Add(expireDuration).Unix()
|
authInfo.ExpiresAt = time.Now().Add(expireDuration).Unix()
|
||||||
|
globals.SugarLogger.Debugf("createAuthInfo authInfo:%s", utils.Format4Output(authInfo, true))
|
||||||
}
|
}
|
||||||
SetUserInfo(token, authInfo, expireDuration)
|
SetUserInfo(token, authInfo, expireDuration)
|
||||||
return authInfo
|
return authInfo
|
||||||
@@ -215,9 +213,6 @@ func SendVerifyCode(authToken, captchaID, captchaValue, authID string) (verfifyC
|
|||||||
if handler := authers[authType]; handler == nil {
|
if handler := authers[authType]; handler == nil {
|
||||||
err = ErrIllegalAuthType
|
err = ErrIllegalAuthType
|
||||||
} else {
|
} else {
|
||||||
//if user, _ := dao.GetUserByID(dao.GetDB(), "mobile", authID); user != nil {
|
|
||||||
// return "", authInfo, fmt.Errorf("该用户已存在,请勿重复注册!")
|
|
||||||
//}
|
|
||||||
verfifyCode, err = handler.SendVerifyCode(authID)
|
verfifyCode, err = handler.SendVerifyCode(authID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -248,8 +243,7 @@ func LoginInternal(ctx *Context, authType, authID, authIDType, authSecret string
|
|||||||
}
|
}
|
||||||
realAuthID = user.GetID()
|
realAuthID = user.GetID()
|
||||||
}
|
}
|
||||||
authBindEx, err = handler.VerifySecret(realAuthID, authSecret)
|
if authBindEx, err = handler.VerifySecret(realAuthID, authSecret); err == nil {
|
||||||
if err == nil {
|
|
||||||
if authBindEx == nil { // mobile, email会返回nil(表示不会新建AuthBind实体)
|
if authBindEx == nil { // mobile, email会返回nil(表示不会新建AuthBind实体)
|
||||||
user = userProvider.GetUser(authID, authIDType)
|
user = userProvider.GetUser(authID, authIDType)
|
||||||
authBindEx = &AuthBindEx{
|
authBindEx = &AuthBindEx{
|
||||||
@@ -263,18 +257,15 @@ func LoginInternal(ctx *Context, authType, authID, authIDType, authSecret string
|
|||||||
// 返回authBind中UserID为空表示只是认证,但本地没有记录,这种情况会返回临时TOKEN
|
// 返回authBind中UserID为空表示只是认证,但本地没有记录,这种情况会返回临时TOKEN
|
||||||
if authBindEx.UserHint != nil && authBindEx.UserID == "" {
|
if authBindEx.UserHint != nil && authBindEx.UserID == "" {
|
||||||
// 利用得到受信任的信息查找用户
|
// 利用得到受信任的信息查找用户
|
||||||
if authBindEx.UserHint.Mobile != "" {
|
// if authBindEx.UserHint.Mobile != "" {
|
||||||
user = userProvider.GetUser(authBindEx.UserHint.Mobile, UserIDMobile)
|
// user = userProvider.GetUser(authBindEx.UserHint.Mobile, UserIDMobile)
|
||||||
}
|
// }
|
||||||
if user == nil && authBindEx.UserHint.Email != "" {
|
// if user == nil && authBindEx.UserHint.Email != "" {
|
||||||
user = userProvider.GetUser(authBindEx.UserHint.Email, UserIDEmail)
|
// user = userProvider.GetUser(authBindEx.UserHint.Email, UserIDEmail)
|
||||||
}
|
// }
|
||||||
if user != nil {
|
// if user != nil {
|
||||||
authBindEx.UserID = user.GetID()
|
// authBindEx.UserID = user.GetID()
|
||||||
}
|
// }
|
||||||
if user2 := userProvider.GetUser(authBindEx.UserHint.Email, UserIDMobile); user2 != nil {
|
|
||||||
user = user2
|
|
||||||
}
|
|
||||||
} else if authBindEx.UserID != "" {
|
} else if authBindEx.UserID != "" {
|
||||||
user = userProvider.GetUser(authBindEx.UserID, UserIDID)
|
user = userProvider.GetUser(authBindEx.UserID, UserIDID)
|
||||||
}
|
}
|
||||||
@@ -284,12 +275,11 @@ func LoginInternal(ctx *Context, authType, authID, authIDType, authSecret string
|
|||||||
userProvider.UpdateLastLogin(user.GetID(), authType, ctx.GetRealRemoteIP())
|
userProvider.UpdateLastLogin(user.GetID(), authType, ctx.GetRealRemoteIP())
|
||||||
}
|
}
|
||||||
//如果是小程序
|
//如果是小程序
|
||||||
if authType == AuthTypeWXMini { // || authType == AuthTypeWXApp 此处AuthTypeWXApp没用上
|
if authType == "weixinmini" || authType == "weixinapp" {
|
||||||
appID := strings.Split(authSecret, ",")[0]
|
appID := strings.Split(authSecret, ",")[0]
|
||||||
// 菜市商家 // // // 京西商城
|
if appID == "wxa4a76d7b4c88604e" || appID == "wx2d6949f724b2541d" || appID == "wx18111a41fd17f24f" { //菜市或者果园
|
||||||
if appID == model.JXC4BusinessAppId || appID == "wx2d6949f724b2541d" || appID == "wx18111a41fd17f24f" || appID == model.JXC4AppId { //菜市或者果园
|
if user != nil {
|
||||||
if authInfo.AuthBindInfo.UserID != "" {
|
binds, err := dao.GetUserBindAuthInfo(dao.GetDB(), user.GetID(), 0, nil, "", "", "wx2bb99eb5d2c9b82c")
|
||||||
binds, err := dao.GetUserBindAuthInfo(dao.GetDB(), authInfo.AuthBindInfo.UserID, 0, nil, "", "", []string{"wx2bb99eb5d2c9b82c", "wx4b5930c13f8b1170"})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return authInfo, err
|
return authInfo, err
|
||||||
}
|
}
|
||||||
@@ -298,29 +288,9 @@ func LoginInternal(ctx *Context, authType, authID, authIDType, authSecret string
|
|||||||
} else {
|
} else {
|
||||||
authInfo.IsExistOpenID = true
|
authInfo.IsExistOpenID = true
|
||||||
}
|
}
|
||||||
if WeCartAppID == appID {
|
|
||||||
authInfo.AppID = WeCartAppID
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//微信APP端登录
|
|
||||||
if authType == AuthTypeWXApp || authType == AuthTypeWXAppCaishi {
|
|
||||||
appID := strings.Split(authSecret, ",")[0]
|
|
||||||
if appID == model.JXC4ClientAppID && authInfo.AuthBindInfo.UserID != "" {
|
|
||||||
binds, err := dao.GetUserBindAuthInfo(dao.GetDB(), authInfo.AuthBindInfo.UserID, 0, nil, "", "", []string{model.JXC4ClientAppID})
|
|
||||||
if err != nil {
|
|
||||||
return authInfo, err
|
|
||||||
}
|
|
||||||
if len(binds) == 0 {
|
|
||||||
authInfo.IsExistOpenID = false
|
|
||||||
} else {
|
|
||||||
authInfo.IsExistOpenID = true
|
|
||||||
}
|
|
||||||
authInfo.AppID = model.JXC4ClientAppID
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err = ErrIllegalAuthType
|
err = ErrIllegalAuthType
|
||||||
@@ -335,59 +305,6 @@ func Login(ctx *Context, authType, authID, authIDType, authSecret string) (authI
|
|||||||
return LoginInternal(ctx, authType, authID, authIDType, authSecret)
|
return LoginInternal(ctx, authType, authID, authIDType, authSecret)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TikTokDecryptInfo 抖音用户信息解密
|
|
||||||
type TikTokDecryptInfo struct {
|
|
||||||
CountryCode string `json:"countryCode"`
|
|
||||||
PhoneNumber string `json:"phoneNumber"`
|
|
||||||
PurePhoneNumber string `json:"purePhoneNumber"`
|
|
||||||
Watermark *struct {
|
|
||||||
AppID string `json:"appid"`
|
|
||||||
Timestamp int64 `json:"timestamp"`
|
|
||||||
} `json:"watermark"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// KuaiShouInfo 抖音用户信息解密
|
|
||||||
type KuaiShouInfo struct {
|
|
||||||
CountryCode string `json:"countryCode"`
|
|
||||||
PhoneNumber string `json:"phoneNumber"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func DecryptUserMsg(sessionKey, iv, msg, loginType string) (string, error) {
|
|
||||||
decodeMsg, err := base64.StdEncoding.DecodeString(msg)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
decodeIv, err := base64.StdEncoding.DecodeString(iv)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
decodeSessionKey, err := base64.StdEncoding.DecodeString(sessionKey)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
userInfo, err := utils.AESCBC16Decrypt(decodeSessionKey, decodeIv, decodeMsg)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
switch loginType {
|
|
||||||
case "tiktokmini":
|
|
||||||
result := &TikTokDecryptInfo{}
|
|
||||||
if err := json.Unmarshal(userInfo, result); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return result.PhoneNumber, nil
|
|
||||||
case "kuaishoumini":
|
|
||||||
result := &KuaiShouInfo{}
|
|
||||||
if err := json.Unmarshal(userInfo, result); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return result.PhoneNumber, nil
|
|
||||||
}
|
|
||||||
return "", ErrIllegalAuthType
|
|
||||||
}
|
|
||||||
|
|
||||||
// 通过临时TOKEN绑定新创建的用户
|
// 通过临时TOKEN绑定新创建的用户
|
||||||
func BindUser(inauthInfo *AuthInfo, user IUser) (outauthInfo *AuthInfo, err error) {
|
func BindUser(inauthInfo *AuthInfo, user IUser) (outauthInfo *AuthInfo, err error) {
|
||||||
if err = AddAuthBind(user, inauthInfo); err == nil {
|
if err = AddAuthBind(user, inauthInfo); err == nil {
|
||||||
@@ -399,6 +316,7 @@ func BindUser(inauthInfo *AuthInfo, user IUser) (outauthInfo *AuthInfo, err erro
|
|||||||
|
|
||||||
// 添加新绑定
|
// 添加新绑定
|
||||||
func AddAuthBind(user IUser, newAuthInfo *AuthInfo) (err error) {
|
func AddAuthBind(user IUser, newAuthInfo *AuthInfo) (err error) {
|
||||||
|
globals.SugarLogger.Debugf("AddAuthBind user:%s, newAuthInfo:%s", utils.Format4Output(user, true), utils.Format4Output(newAuthInfo, true))
|
||||||
if user == nil || newAuthInfo == nil {
|
if user == nil || newAuthInfo == nil {
|
||||||
return ErrInternalErrror
|
return ErrInternalErrror
|
||||||
}
|
}
|
||||||
@@ -422,22 +340,8 @@ func AddAuthBind(user IUser, newAuthInfo *AuthInfo) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddAuthBindWithMobile(authInfo *AuthInfo, mobile string) (err error) {
|
|
||||||
if handler := authers[authInfo.AuthBindInfo.Type]; handler != nil {
|
|
||||||
user, err := dao.GetUserByID(dao.GetDB(), "mobile", mobile)
|
|
||||||
if err != nil {
|
|
||||||
return errors.New("此接口有执行顺序,请先调用注册登录接口:【第一步:Login,第二步:TiktokDecrypt】")
|
|
||||||
}
|
|
||||||
authInfo.AuthBindInfo.UserID = user.UserID
|
|
||||||
//handler.UnbindAuth(user.GetID(), newAuthInfo.GetAuthType(), newAuthInfo.GetAuthTypeID(), user.GetName())
|
|
||||||
err = handler.AddAuthBind(authInfo.AuthBindInfo, user.GetName())
|
|
||||||
} else {
|
|
||||||
err = ErrIllegalAuthType
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func UnbindAuth(userID, authType, authTypeID, userName string) (err error) {
|
func UnbindAuth(userID, authType, authTypeID, userName string) (err error) {
|
||||||
|
globals.SugarLogger.Debugf("UnbindAuth userID:%s, authType:%s, authTypeID:%s, userName:%s", userID, authType, authTypeID, userName)
|
||||||
if handler := authers[authType]; handler != nil {
|
if handler := authers[authType]; handler != nil {
|
||||||
err = handler.UnbindAuth(userID, authType, authTypeID, userName)
|
err = handler.UnbindAuth(userID, authType, authTypeID, userName)
|
||||||
} else {
|
} else {
|
||||||
@@ -447,6 +351,7 @@ func UnbindAuth(userID, authType, authTypeID, userName string) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Logout(authInfo *AuthInfo) (err error) {
|
func Logout(authInfo *AuthInfo) (err error) {
|
||||||
|
globals.SugarLogger.Debugf("Logout authInfo:%s", utils.Format4Output(authInfo, true))
|
||||||
if handler := authers[authInfo.AuthBindInfo.Type]; handler != nil {
|
if handler := authers[authInfo.AuthBindInfo.Type]; handler != nil {
|
||||||
err = handler.Logout(authInfo)
|
err = handler.Logout(authInfo)
|
||||||
}
|
}
|
||||||
@@ -488,6 +393,8 @@ func ClearUserToken(userID string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////
|
||||||
|
|
||||||
func createToken(user IUser, authBindInfo *AuthBindEx) (token string, tokenType int) {
|
func createToken(user IUser, authBindInfo *AuthBindEx) (token string, tokenType int) {
|
||||||
userID := TokenUserEmpty
|
userID := TokenUserEmpty
|
||||||
userName := authBindInfo.AuthID
|
userName := authBindInfo.AuthID
|
||||||
@@ -556,7 +463,7 @@ func DisableUser(userID, operatorUserName string) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GetUserBindAuthInfo(userID string) (authList []*model.AuthBind, err error) {
|
func GetUserBindAuthInfo(userID string) (authList []*model.AuthBind, err error) {
|
||||||
return dao.GetUserBindAuthInfo(dao.GetDB(), userID, model.AuthBindTypeAuth, nil, "", "", nil)
|
return dao.GetUserBindAuthInfo(dao.GetDB(), userID, model.AuthBindTypeAuth, nil, "", "", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeletedTokenInfoWithoutParam(authInfo *AuthInfo) (err error) {
|
func DeletedTokenInfoWithoutParam(authInfo *AuthInfo) (err error) {
|
||||||
@@ -569,3 +476,16 @@ func DeletedTokenInfoWithoutParam(authInfo *AuthInfo) (err error) {
|
|||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CheckWeixinminiAuthBind(userID string) (err error) {
|
||||||
|
var (
|
||||||
|
db = dao.GetDB()
|
||||||
|
)
|
||||||
|
authBinds, err := dao.GetUserBindAuthInfo(db, userID, model.AuthBindTypeAuth, []string{"weixinmini", "weixinapp"}, "", "", "")
|
||||||
|
if len(authBinds) == 0 {
|
||||||
|
return fmt.Errorf("请绑定微信认证方式!")
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Context struct {
|
type Context struct {
|
||||||
@@ -20,6 +21,7 @@ func NewContext(w http.ResponseWriter, r *http.Request) (ctx *Context) {
|
|||||||
r: r,
|
r: r,
|
||||||
accessUUID: utils.GetUUID(),
|
accessUUID: utils.GetUUID(),
|
||||||
}
|
}
|
||||||
|
globals.SugarLogger.Debugf("NewContext ip:%s", ctx.GetRealRemoteIP())
|
||||||
return ctx
|
return ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,6 +40,7 @@ func (ctx *Context) GetTrackInfo() string {
|
|||||||
func (ctx *Context) GetRealRemoteIP() (ip string) {
|
func (ctx *Context) GetRealRemoteIP() (ip string) {
|
||||||
r := ctx.r
|
r := ctx.r
|
||||||
if r != nil {
|
if r != nil {
|
||||||
|
// globals.SugarLogger.Debugf("GetRealRemoteIP header:%s", utils.Format4Output(r.Header, false))
|
||||||
ip = r.Header.Get("X-Forwarded-For")
|
ip = r.Header.Get("X-Forwarded-For")
|
||||||
if ip == "" {
|
if ip == "" {
|
||||||
ip = r.Header.Get("X-real-ip")
|
ip = r.Header.Get("X-real-ip")
|
||||||
|
|||||||
@@ -74,7 +74,6 @@ type AuthInfo struct {
|
|||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
TokenType int `json:"tokenType"` // TOKEN类型,
|
TokenType int `json:"tokenType"` // TOKEN类型,
|
||||||
IsExistOpenID bool `json:"isExistOpenID"`
|
IsExistOpenID bool `json:"isExistOpenID"`
|
||||||
AppID string `json:"appId"` // appId
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AuthInfo) GetAuthID() string {
|
func (a *AuthInfo) GetAuthID() string {
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
package alipay
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/alipayapi"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/auth2"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/auth2/authprovider"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
AuthType = "alipaycode"
|
|
||||||
|
|
||||||
AuthKey = "GHp3ojlVYRRu2XID4FX2ew=="
|
|
||||||
)
|
|
||||||
|
|
||||||
type Auther struct {
|
|
||||||
authprovider.DefAuther
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
AutherObj *Auther
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
AutherObj = new(Auther)
|
|
||||||
auth2.RegisterAuther(AuthType, AutherObj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Auther) VerifySecret(dummy, code string) (authBindEx *auth2.AuthBindEx, err error) {
|
|
||||||
tokenInfo, err := api.AliPayAPI.SystemAuthToken(alipayapi.GrantTypeCode, code, "")
|
|
||||||
if err == nil {
|
|
||||||
//userInfo, err2 := api.AliPayAPI.UserInfoShare(tokenInfo.AccessToken)
|
|
||||||
//if err = err2; err == nil {
|
|
||||||
if authBindEx, err = a.UnionFindAuthBind(AuthType, api.AliPayAPI.GetAppID(), nil, tokenInfo.UserID, tokenInfo.AlipayUserID, tokenInfo); err == nil {
|
|
||||||
authBindEx.AuthSecret = tokenInfo.AccessToken
|
|
||||||
authBindEx.AuthSecret2 = tokenInfo.RefreshToken
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return authBindEx, err
|
|
||||||
}
|
|
||||||
@@ -9,8 +9,9 @@ import (
|
|||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
"git.rosy.net.cn/jx-callback/business/auth2"
|
"git.rosy.net.cn/jx-callback/business/auth2"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/dao"
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
"git.rosy.net.cn/jx-callback/globals/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -35,6 +36,7 @@ func (a *DefAuther) AddAuthBind(authBindEx *auth2.AuthBindEx, userName string) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *DefAuther) UnbindAuth(userID, authType, authTypeID, userName string) (err error) {
|
func (a *DefAuther) UnbindAuth(userID, authType, authTypeID, userName string) (err error) {
|
||||||
|
globals.SugarLogger.Debugf("DefAuther.UnbindAuth userID:%s, authType:%s, GetAuthTypeID:%s, userName:%s", userID, authType, authTypeID, userName)
|
||||||
condition := map[string]interface{}{
|
condition := map[string]interface{}{
|
||||||
"UserID": userID,
|
"UserID": userID,
|
||||||
"Type": authType,
|
"Type": authType,
|
||||||
@@ -62,6 +64,8 @@ func (a *DefAuther) GetUserType() (userType int8) {
|
|||||||
|
|
||||||
// 此函数用于联合(通过unionID)查找用户
|
// 此函数用于联合(通过unionID)查找用户
|
||||||
func (a *DefAuther) UnionFindAuthBind(curAuthType, curAuthTypeID string, unionAuthTypeList []string, openID, unionID string, authDetail interface{}) (authBindEx *auth2.AuthBindEx, err error) {
|
func (a *DefAuther) UnionFindAuthBind(curAuthType, curAuthTypeID string, unionAuthTypeList []string, openID, unionID string, authDetail interface{}) (authBindEx *auth2.AuthBindEx, err error) {
|
||||||
|
globals.SugarLogger.Debugf("UnionFindAuthBind curAuthType:%s, curAuthTypeID:%s, unionAuthTypeList:%v, openID:%s, unionID:%s, authDetail:%s",
|
||||||
|
curAuthType, curAuthTypeID, unionAuthTypeList, openID, unionID, utils.Format4Output(authDetail, true))
|
||||||
db := dao.GetDB()
|
db := dao.GetDB()
|
||||||
var authBind *model.AuthBind
|
var authBind *model.AuthBind
|
||||||
if authBind, err = dao.GetAuthBind(db, model.AuthBindTypeAuth, curAuthType, openID); err == nil { // 直接找到了
|
if authBind, err = dao.GetAuthBind(db, model.AuthBindTypeAuth, curAuthType, openID); err == nil { // 直接找到了
|
||||||
@@ -76,9 +80,9 @@ func (a *DefAuther) UnionFindAuthBind(curAuthType, curAuthTypeID string, unionAu
|
|||||||
dao.UpdateEntity(db, authBind, "TypeID")
|
dao.UpdateEntity(db, authBind, "TypeID")
|
||||||
}
|
}
|
||||||
} else if dao.IsNoRowsError(err) { // 直接找不到,尝试unionID
|
} else if dao.IsNoRowsError(err) { // 直接找不到,尝试unionID
|
||||||
if unionID != "" || openID != "" { // 且有unionID
|
if unionID != "" { // 且有unionID
|
||||||
var authBindList []*model.AuthBind
|
var authBindList []*model.AuthBind
|
||||||
if authBindList, err = dao.GetUserBindAuthInfo(db, "", model.AuthBindTypeAuth, unionAuthTypeList, openID, unionID, nil); err == nil && len(authBindList) > 0 { // 通过unionID找到至少一个认证方式
|
if authBindList, err = dao.GetUserBindAuthInfo(db, "", model.AuthBindTypeAuth, unionAuthTypeList, "", unionID, ""); err == nil && len(authBindList) > 0 { // 通过unionID找到至少一个认证方式
|
||||||
authBind = authBindList[0]
|
authBind = authBindList[0]
|
||||||
authBind.Type = curAuthType
|
authBind.Type = curAuthType
|
||||||
authBind.TypeID = curAuthTypeID
|
authBind.TypeID = curAuthTypeID
|
||||||
@@ -98,8 +102,7 @@ func (a *DefAuther) UnionFindAuthBind(curAuthType, curAuthTypeID string, unionAu
|
|||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err == nil && authBindEx == nil {
|
if err == nil && authBindEx == nil { //如果没有报错,且没有找到一个认证方式,创建无用户(UserID为空)的认证方式
|
||||||
//如果没有报错,且没有找到一个认证方式,创建无用户(UserID为空)的认证方式
|
|
||||||
authBindEx = &auth2.AuthBindEx{
|
authBindEx = &auth2.AuthBindEx{
|
||||||
AuthBind: model.AuthBind{
|
AuthBind: model.AuthBind{
|
||||||
Type: curAuthType,
|
Type: curAuthType,
|
||||||
@@ -139,6 +142,7 @@ func (a *DefAuther) GenerateVerifyCode(keyID string) (verifyCode string) {
|
|||||||
if verifyCode == "" {
|
if verifyCode == "" {
|
||||||
verifyCode = fmt.Sprintf("%06d", rand.Intn(1000000))
|
verifyCode = fmt.Sprintf("%06d", rand.Intn(1000000))
|
||||||
}
|
}
|
||||||
|
globals.SugarLogger.Debugf("GenerateVerifyCode keyID:%s verifyCode:%s", keyID, verifyCode)
|
||||||
return verifyCode
|
return verifyCode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
package dingding
|
|
||||||
|
|
||||||
const (
|
|
||||||
AuthTypeStaff = "ddstaff" // 钉钉企业登录
|
|
||||||
AuthTypeQRCode = "ddqrcode"
|
|
||||||
)
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
package dingding
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/auth2"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/auth2/authprovider"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
|
||||||
)
|
|
||||||
|
|
||||||
type QRCodeAuther struct {
|
|
||||||
authprovider.DefAuther
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
AutherObjQRCode *QRCodeAuther
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
AutherObjQRCode = new(QRCodeAuther)
|
|
||||||
auth2.RegisterAuther(AuthTypeQRCode, AutherObjQRCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *QRCodeAuther) VerifySecret(dummy, code string) (*auth2.AuthBindEx, error) {
|
|
||||||
userQRInfo, err := api.DingDingQRCodeAPI.GetUserInfoByCode(code)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
tmp_userID, err := api.DingDingAPI.GetByUnionID(userQRInfo.UnionID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
userInfo, err := api.DingDingAPI.GetUser(tmp_userID.UserID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
authBindEx, err := a.UnionFindAuthBind(AuthTypeQRCode, api.DingDingQRCodeAPI.GetAppID(), []string{AuthTypeStaff, AuthTypeQRCode}, userQRInfo.OpenID, userQRInfo.UnionID, userQRInfo)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
authBindEx.UserHint = &auth2.UserBasic{
|
|
||||||
UserID2: tmp_userID.UserID,
|
|
||||||
Mobile: utils.Interface2String(userInfo["mobile"]),
|
|
||||||
Email: utils.Interface2String(userInfo["email"]),
|
|
||||||
Name: utils.Interface2String(userInfo["name"]),
|
|
||||||
}
|
|
||||||
|
|
||||||
return authBindEx, err
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
package dingding
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/auth2"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/auth2/authprovider"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
|
||||||
)
|
|
||||||
|
|
||||||
type StaffAuther struct {
|
|
||||||
authprovider.DefAuther
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
AutherObjStaff *StaffAuther
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
AutherObjStaff = new(StaffAuther)
|
|
||||||
auth2.RegisterAuther(AuthTypeStaff, AutherObjStaff)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *StaffAuther) VerifySecret(dummy, code string) (authBindEx *auth2.AuthBindEx, err error) {
|
|
||||||
userID, err := api.DingDingAPI.GetUserID(code)
|
|
||||||
if err == nil {
|
|
||||||
userDetail, err2 := api.DingDingAPI.GetUserDetail(userID.UserID)
|
|
||||||
if err = err2; err == nil {
|
|
||||||
if authBindEx, err = a.UnionFindAuthBind(AuthTypeStaff, api.DingDingQRCodeAPI.GetAppID(), []string{AuthTypeStaff, AuthTypeQRCode}, userID.UserID, utils.Interface2String(userDetail["unionid"]), userDetail); err == nil {
|
|
||||||
authBindEx.UserHint = &auth2.UserBasic{
|
|
||||||
UserID2: userID.UserID,
|
|
||||||
Mobile: utils.Interface2String(userDetail["mobile"]),
|
|
||||||
Email: utils.Interface2String(userDetail["email"]),
|
|
||||||
Name: utils.Interface2String(userDetail["name"]),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return authBindEx, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *StaffAuther) GetUserType() (userType int8) {
|
|
||||||
return model.UserTypeOperator
|
|
||||||
}
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
package douyin
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/tiktok"
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/weixinapi"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/auth2"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/auth2/authprovider"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/auth2/authprovider/weixin"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
AuthTypeTiktokMini = "tiktokmini" // 抖音小程序
|
|
||||||
)
|
|
||||||
|
|
||||||
type TiktokMiniAuther struct {
|
|
||||||
authprovider.DefAuther
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
AutherObjMini *TiktokMiniAuther
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
AutherObjMini = new(TiktokMiniAuther)
|
|
||||||
auth2.RegisterAuther(AuthTypeTiktokMini, AutherObjMini)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *TiktokMiniAuther) VerifySecret(dummy, code string) (authBindEx *auth2.AuthBindEx, err error) {
|
|
||||||
//appID, realCode := splitCode(code)
|
|
||||||
//sessionInfo, err := getTikTokApp(appID).GetTiktokOauth(realCode)
|
|
||||||
sessionInfo, err := api.TiktokApi.GetTiktokOauth(code)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
sessionKey := sessionInfo.Data.SessionKey
|
|
||||||
if authBindEx, err = a.UnionFindAuthBind(AuthTypeTiktokMini, api.TiktokApi.GetAppID(), []string{AuthTypeTiktokMini}, sessionInfo.Data.OpenId, sessionInfo.Data.Unionid, sessionInfo); err == nil {
|
|
||||||
authBindEx.UserData = sessionKey
|
|
||||||
}
|
|
||||||
return authBindEx, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 特殊接口
|
|
||||||
func (a *TiktokMiniAuther) DecryptData(authInfo *auth2.AuthInfo, jsCode, encryptedData, iv string) (decryptedDataBase64 string, err error) {
|
|
||||||
var sessionKey string
|
|
||||||
appID, jsCode := weixin.SplitJsCode(jsCode)
|
|
||||||
if jsCode != "" {
|
|
||||||
sessionInfo, err := getWxApp(appID).SNSCode2Session(jsCode)
|
|
||||||
if err == nil {
|
|
||||||
// if authBindEx, err := a.UnionFindAuthBind(AuthTypeMini, getWxApp(appID).GetAppID(), []string{AuthTypeMini}, sessionInfo.OpenID, "", nil); err == nil {
|
|
||||||
// if authBindEx.UserID != authInfo.GetID() {
|
|
||||||
// return "", fmt.Errorf("jsCode与token不匹配")
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// return "", err
|
|
||||||
// }
|
|
||||||
sessionKey = sessionInfo.SessionKey
|
|
||||||
} else {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if authInfo.AuthBindInfo.Type != AuthTypeTiktokMini {
|
|
||||||
// return "", ErrAuthTypeShouldBeMini
|
|
||||||
}
|
|
||||||
sessionKey = authInfo.AuthBindInfo.UserData.(string)
|
|
||||||
}
|
|
||||||
decryptedData, err := weixinapi.SNSDecodeMiniProgramData(encryptedData, sessionKey, iv)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return string(decryptedData), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *TiktokMiniAuther) GetUserType() (userType int8) {
|
|
||||||
return model.UserTypeStoreBoss
|
|
||||||
}
|
|
||||||
|
|
||||||
func getWxApp(appID string) (miniApi *weixinapi.API) {
|
|
||||||
miniApi = api.WeixinMiniAPI
|
|
||||||
if len(appID) > 0 && appID == api.WeixinMiniAppID2 {
|
|
||||||
miniApi = api.WeixinMiniAPI2
|
|
||||||
}
|
|
||||||
if len(appID) > 0 && appID == api.WeixinMiniAppIDsc {
|
|
||||||
miniApi = api.WeixinMiniAPIsc
|
|
||||||
}
|
|
||||||
return miniApi
|
|
||||||
}
|
|
||||||
|
|
||||||
func getTikTokApp(appID string) (TikTokMini *tiktok.API) {
|
|
||||||
TikTokMini = api.TiktokApi
|
|
||||||
if len(appID) > 0 && appID == api.TiktokJXDJApiID {
|
|
||||||
TikTokMini = api.TiktokJXDJApi
|
|
||||||
}
|
|
||||||
return TikTokMini
|
|
||||||
}
|
|
||||||
func splitCode(code string) (appID, realCode string) {
|
|
||||||
str := strings.Split(code, "&")
|
|
||||||
if len(str) == 2 {
|
|
||||||
appID = str[1]
|
|
||||||
realCode = str[0]
|
|
||||||
} else {
|
|
||||||
globals.SugarLogger.Warnf("splitCode abnormal code:%s", code)
|
|
||||||
}
|
|
||||||
return appID, realCode
|
|
||||||
}
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
package kuaishou
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.rosy.net.cn/jx-callback/business/auth2"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/auth2/authprovider"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
AuthTypeKuaiShouMini = "kuaishoumini" // 快手小程序
|
|
||||||
)
|
|
||||||
|
|
||||||
type KuaiShouMiniAuther struct {
|
|
||||||
authprovider.DefAuther
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
AutherObjMini *KuaiShouMiniAuther
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
AutherObjMini = new(KuaiShouMiniAuther)
|
|
||||||
auth2.RegisterAuther(AuthTypeKuaiShouMini, AutherObjMini)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *KuaiShouMiniAuther) VerifySecret(dummy, code string) (authBindEx *auth2.AuthBindEx, err error) {
|
|
||||||
//appID, realCode := splitCode(code)
|
|
||||||
//sessionInfo, err := getTikTokApp(appID).GetTiktokOauth(realCode)
|
|
||||||
sessionInfo, openId, err := api.KuaiShouApi.AuthLoginKuaiShou(code)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if authBindEx, err = a.UnionFindAuthBind(AuthTypeKuaiShouMini, api.KuaiShouApi.GetAppID(), []string{AuthTypeKuaiShouMini}, openId, "", sessionInfo); err == nil {
|
|
||||||
authBindEx.UserData = sessionInfo
|
|
||||||
}
|
|
||||||
return authBindEx, err
|
|
||||||
}
|
|
||||||
|
|
||||||
//func (a *KuaiShouMiniAuther) DecryptData(authInfo *auth2.AuthInfo, jsCode, encryptedData, iv string) (decryptedDataBase64 string, err error) {
|
|
||||||
// var sessionKey string
|
|
||||||
// appID, jsCode := weixin.SplitJsCode(jsCode)
|
|
||||||
// if jsCode != "" {
|
|
||||||
// sessionInfo, err := getWxApp(appID).SNSCode2Session(jsCode)
|
|
||||||
// if err == nil {
|
|
||||||
// // if authBindEx, err := a.UnionFindAuthBind(AuthTypeMini, getWxApp(appID).GetAppID(), []string{AuthTypeMini}, sessionInfo.OpenID, "", nil); err == nil {
|
|
||||||
// // if authBindEx.UserID != authInfo.GetID() {
|
|
||||||
// // return "", fmt.Errorf("jsCode与token不匹配")
|
|
||||||
// // }
|
|
||||||
// // } else {
|
|
||||||
// // return "", err
|
|
||||||
// // }
|
|
||||||
// sessionKey = sessionInfo.SessionKey
|
|
||||||
// } else {
|
|
||||||
// return "", err
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// if authInfo.AuthBindInfo.Type != AuthTypeKuaiShouMini {
|
|
||||||
// // return "", ErrAuthTypeShouldBeMini
|
|
||||||
// }
|
|
||||||
// sessionKey = authInfo.AuthBindInfo.UserData.(string)
|
|
||||||
// }
|
|
||||||
// decryptedData, err := weixinapi.SNSDecodeMiniProgramData(encryptedData, sessionKey, iv)
|
|
||||||
// if err != nil {
|
|
||||||
// return "", err
|
|
||||||
// }
|
|
||||||
// return string(decryptedData), nil
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//func (a *KuaiShouMiniAuther) GetUserType() (userType int8) {
|
|
||||||
// return model.UserTypeStoreBoss
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//func getWxApp(appID string) (miniApi *weixinapi.API) {
|
|
||||||
// miniApi = api.WeixinMiniAPI
|
|
||||||
// if len(appID) > 0 && appID == api.WeixinMiniAppID2 {
|
|
||||||
// miniApi = api.WeixinMiniAPI2
|
|
||||||
// }
|
|
||||||
// if len(appID) > 0 && appID == api.WeixinMiniAppIDsc {
|
|
||||||
// miniApi = api.WeixinMiniAPIsc
|
|
||||||
// }
|
|
||||||
// return miniApi
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//func getTikTokApp(appID string) (TikTokMini *tiktok.API) {
|
|
||||||
// TikTokMini = api.TiktokApi
|
|
||||||
// if len(appID) > 0 && appID == api.TiktokJXDJApiID {
|
|
||||||
// TikTokMini = api.TiktokJXDJApi
|
|
||||||
// }
|
|
||||||
// return TikTokMini
|
|
||||||
//}
|
|
||||||
//func splitCode(code string) (appID, realCode string) {
|
|
||||||
// str := strings.Split(code, "&")
|
|
||||||
// if len(str) == 2 {
|
|
||||||
// appID = str[1]
|
|
||||||
// realCode = str[0]
|
|
||||||
// } else {
|
|
||||||
// globals.SugarLogger.Warnf("splitCode abnormal code:%s", code)
|
|
||||||
// }
|
|
||||||
// return appID, realCode
|
|
||||||
//}
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
package mobile
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/auth2"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/auth2/authprovider"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
aliyunsmsclient "github.com/KenmyZhang/aliyun-communicate"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
AuthType = auth2.AuthTypeMobile
|
|
||||||
TestVerifyCode = "123456"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
warningMap = map[string]int{
|
|
||||||
"isv.AMOUNT_NOT_ENOUGH": 1,
|
|
||||||
"isv.ACCOUNT_ABNORMAL": 1,
|
|
||||||
"isv.OUT_OF_SERVICE": 1,
|
|
||||||
"isv.DAY_LIMIT_CONTROL": 1,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrVerifyCodeIsWrong = errors.New("验证码错")
|
|
||||||
)
|
|
||||||
|
|
||||||
type Auther struct {
|
|
||||||
authprovider.DefAuther
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
AutherObj *Auther
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
AutherObj = new(Auther)
|
|
||||||
auth2.RegisterAuther(AuthType, AutherObj)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 特殊接口
|
|
||||||
func (a *Auther) SendVerifyCode(mobileNumber string) (verifyCode string, err error) {
|
|
||||||
verifyCode = a.GenerateVerifyCode(mobileNumber)
|
|
||||||
smsClient := aliyunsmsclient.New("http://dysmsapi.aliyuncs.com/")
|
|
||||||
response, err := smsClient.Execute(globals.AliKey, globals.AliSecret, mobileNumber, globals.SMSSignName, globals.SMSMobileVerifyTemplate, string(utils.MustMarshal(map[string]interface{}{
|
|
||||||
"code": verifyCode,
|
|
||||||
})))
|
|
||||||
a.SaveVerifyCode(mobileNumber, verifyCode)
|
|
||||||
if err == nil && response.Code == aliyunsmsclient.ResponseCodeOk {
|
|
||||||
// a.SaveVerifyCode(mobileNumber, verifyCode)
|
|
||||||
} else {
|
|
||||||
if err == nil {
|
|
||||||
if warningMap[response.Code] == 1 {
|
|
||||||
globals.SugarLogger.Warnf("SendVerifyCode mobileNumber:%s failed with response:%s", mobileNumber, utils.Format4Output(response, false))
|
|
||||||
} else {
|
|
||||||
globals.SugarLogger.Infof("SendVerifyCode mobileNumber:%s failed with response:%s", mobileNumber, utils.Format4Output(response, false))
|
|
||||||
}
|
|
||||||
err = fmt.Errorf("发送短信出错:%s", response.Message)
|
|
||||||
} else {
|
|
||||||
globals.SugarLogger.Warnf("SendVerifyCode mobileNumber:%s failed with error:%v", mobileNumber, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return verifyCode, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Auther) VerifySecret(mobileNumber, code string) (authBindEx *auth2.AuthBindEx, err error) {
|
|
||||||
err = ErrVerifyCodeIsWrong
|
|
||||||
if (code == auth2.InternalAuthSecret ||
|
|
||||||
auth2.TestMobileMap[mobileNumber] == 1 && code == TestVerifyCode) ||
|
|
||||||
a.VerifyCode(mobileNumber, code) {
|
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 此函数为空
|
|
||||||
func (a *Auther) AddAuthBind(authBindEx *auth2.AuthBindEx, userName string) (err error) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 此函数为空
|
|
||||||
func (a *Auther) UnbindAuth(userID, authType, authTypeID, userName string) (err error) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
package password
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/sha1"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/auth2"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/auth2/authprovider"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
AuthType = auth2.AuthTypePassword
|
|
||||||
)
|
|
||||||
|
|
||||||
type Auther struct {
|
|
||||||
authprovider.DefAuther
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
AutherObj *Auther
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrUserAndPassNotMatch = errors.New("用户名密码不匹配")
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
AutherObj = new(Auther)
|
|
||||||
auth2.RegisterAuther(AuthType, AutherObj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Auther) VerifySecret(userID, passMD5 string) (authBindEx *auth2.AuthBindEx, err error) {
|
|
||||||
var authBind *model.AuthBind
|
|
||||||
if authBind, err = dao.GetAuthBind(dao.GetDB(), model.AuthBindTypeAuth, AuthType, userID); err == nil {
|
|
||||||
if err = a.checkPassword(authBind, passMD5); err == nil {
|
|
||||||
authBindEx = &auth2.AuthBindEx{
|
|
||||||
AuthBind: *authBind,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if dao.IsNoRowsError(err) {
|
|
||||||
err = auth2.ErrUserAuthTypeNotExist
|
|
||||||
}
|
|
||||||
return authBindEx, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 特殊接口
|
|
||||||
func (a *Auther) ChangePassword(userID, userName, oldPassMD5, newPassMD5 string) (err error) {
|
|
||||||
var authBind *model.AuthBind
|
|
||||||
db := dao.GetDB()
|
|
||||||
salt := utils.GetUUID()
|
|
||||||
encryptPwd := a.encryptPassword(newPassMD5, salt)
|
|
||||||
if authBind, err = dao.GetAuthBind(db, model.AuthBindTypeAuth, AuthType, userID); err == nil {
|
|
||||||
if err = a.checkPassword(authBind, oldPassMD5); err == nil || authBind.AuthSecret == "" { // 如果原密码为空,不判断原密码,代表重置密码
|
|
||||||
_, err = dao.UpdateEntityLogically(db, authBind, map[string]interface{}{
|
|
||||||
"AuthSecret": encryptPwd,
|
|
||||||
"AuthSecret2": salt,
|
|
||||||
}, userName, nil)
|
|
||||||
}
|
|
||||||
} else if dao.IsNoRowsError(err) {
|
|
||||||
err = a.AddAuthBind(&auth2.AuthBindEx{
|
|
||||||
AuthBind: model.AuthBind{
|
|
||||||
UserID: userID,
|
|
||||||
Type: AuthType,
|
|
||||||
AuthID: userID,
|
|
||||||
AuthSecret: encryptPwd,
|
|
||||||
AuthSecret2: salt,
|
|
||||||
},
|
|
||||||
}, userName)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Auther) encryptPassword(password, salt string) string {
|
|
||||||
return fmt.Sprintf("%x", sha1.Sum([]byte(password+salt)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Auther) checkPassword(authBind *model.AuthBind, passMD5 string) (err error) {
|
|
||||||
if authBind.AuthSecret != a.encryptPassword(passMD5, authBind.AuthSecret2) {
|
|
||||||
return ErrUserAndPassNotMatch
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
package weixin
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/weixinapi"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/auth2"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/auth2/authprovider"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
AuthTypeWeixin = "wxqrcode" // 微信扫码
|
|
||||||
AuthTypeMP = "weixinsns" // 公众号
|
|
||||||
AuthTypeWXNative = "wxnative" // 微信APP
|
|
||||||
AuthTypeWxApp = "weixinapp" //app微信登录(商家版)
|
|
||||||
AuthTypeWxAppCaishi = "weixinappcs" //app微信登录(用户版)
|
|
||||||
)
|
|
||||||
|
|
||||||
type Auther struct {
|
|
||||||
authprovider.DefAuther
|
|
||||||
authType string
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
AutherObjWX *Auther
|
|
||||||
AutherObjMP *Auther
|
|
||||||
AutherObjNative *Auther
|
|
||||||
AutherObjApp *Auther
|
|
||||||
AutherObjCaiShiApp *Auther
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrStateIsWrong = errors.New("登录state非法")
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
AutherObjWX = &Auther{
|
|
||||||
authType: AuthTypeWeixin,
|
|
||||||
}
|
|
||||||
auth2.RegisterAuther(AuthTypeWeixin, AutherObjWX)
|
|
||||||
|
|
||||||
AutherObjMP = &Auther{
|
|
||||||
authType: AuthTypeMP,
|
|
||||||
}
|
|
||||||
auth2.RegisterAuther(AuthTypeMP, AutherObjMP)
|
|
||||||
|
|
||||||
AutherObjNative = &Auther{
|
|
||||||
authType: AuthTypeWXNative,
|
|
||||||
}
|
|
||||||
auth2.RegisterAuther(AuthTypeWXNative, AutherObjNative)
|
|
||||||
|
|
||||||
AutherObjApp = &Auther{
|
|
||||||
authType: AuthTypeWxApp,
|
|
||||||
}
|
|
||||||
auth2.RegisterAuther(AuthTypeWxApp, AutherObjApp)
|
|
||||||
|
|
||||||
AutherObjCaiShiApp = &Auther{
|
|
||||||
authType: AuthTypeWxAppCaishi,
|
|
||||||
}
|
|
||||||
auth2.RegisterAuther(AuthTypeWxAppCaishi, AutherObjCaiShiApp)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Auther) VerifySecret(id, secret string) (authBindEx *auth2.AuthBindEx, err error) {
|
|
||||||
var openID, accessToken string
|
|
||||||
_, jsCode := SplitJsCode(secret)
|
|
||||||
if a.authType != AuthTypeWXNative {
|
|
||||||
state := id
|
|
||||||
code := jsCode
|
|
||||||
if state == "" {
|
|
||||||
//temp := a.getAPI()
|
|
||||||
//fmt.Printf("secret=%s,appid=%s", temp.GetSecret(), temp.GetAppID())
|
|
||||||
token, err2 := a.getAPI().SNSRetrieveToken(code)
|
|
||||||
if err = err2; err == nil {
|
|
||||||
openID = token.OpenID
|
|
||||||
accessToken = token.AccessToken
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = ErrStateIsWrong
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
openID = id
|
|
||||||
accessToken = secret
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
wxUserinfo, err2 := a.getAPI().SNSGetUserInfo(accessToken, openID)
|
|
||||||
if err = err2; err == nil {
|
|
||||||
if authBindEx, err = a.UnionFindAuthBind(a.authType, a.getAPI().GetAppID(), []string{AuthTypeWeixin, AuthTypeMP, AuthTypeMini, AuthTypeWXNative, AuthTypeWxApp, AuthTypeWxAppCaishi}, wxUserinfo.OpenID, wxUserinfo.UnionID, wxUserinfo); err == nil {
|
|
||||||
authBindEx.UserHint = &auth2.UserBasic{
|
|
||||||
Name: wxUserinfo.NickName,
|
|
||||||
Avatar: wxUserinfo.HeadImgURL,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return authBindEx, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Auther) getAPI() *weixinapi.API {
|
|
||||||
if a.authType == AuthTypeWeixin {
|
|
||||||
return api.WeixinPageAPI
|
|
||||||
}
|
|
||||||
if a.authType == AuthTypeWxApp {
|
|
||||||
return api.WeixinApp
|
|
||||||
}
|
|
||||||
if a.authType == AuthTypeWxAppCaishi {
|
|
||||||
return api.WeixinApp2
|
|
||||||
}
|
|
||||||
return api.WeixinAPI
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Auther) GetUserType() (userType int8) {
|
|
||||||
return model.UserTypeStoreBoss
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetAPI(appID string) *weixinapi.API {
|
|
||||||
miniApi := api.WeixinMiniAPI
|
|
||||||
if len(appID) > 0 && appID == api.WeixinMiniAppID2 {
|
|
||||||
miniApi = api.WeixinMiniAPI2
|
|
||||||
}
|
|
||||||
if len(appID) > 0 && appID == api.WeixinMiniAppIDsc {
|
|
||||||
miniApi = api.WeixinMiniAPIsc
|
|
||||||
}
|
|
||||||
return miniApi
|
|
||||||
}
|
|
||||||
@@ -1,139 +0,0 @@
|
|||||||
package weixin
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/weixinapi"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/auth2"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/auth2/authprovider"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
AuthTypeMini = "weixinmini" // 小程序
|
|
||||||
)
|
|
||||||
|
|
||||||
type MiniAuther struct {
|
|
||||||
authprovider.DefAuther
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrAuthTypeShouldBeMini = errors.New("当前操作要求是小程序登录方式")
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
AutherObjMini *MiniAuther
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
AutherObjMini = new(MiniAuther)
|
|
||||||
auth2.RegisterAuther(AuthTypeMini, AutherObjMini)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *MiniAuther) VerifySecret(dummy, jsCode string) (authBindEx *auth2.AuthBindEx, err error) {
|
|
||||||
appID, jsCode := SplitJsCode(jsCode)
|
|
||||||
sessionInfo, err := getWxApp(appID).SNSCode2Session(jsCode)
|
|
||||||
if err == nil {
|
|
||||||
sessionKey := sessionInfo.SessionKey
|
|
||||||
sessionInfo.SessionKey = ""
|
|
||||||
if authBindEx, err = a.UnionFindAuthBind(AuthTypeMini, getWxApp(appID).GetAppID(), []string{AuthTypeWeixin, AuthTypeMP, AuthTypeMini, AuthTypeWXNative}, sessionInfo.OpenID, sessionInfo.UnionID, sessionInfo); err == nil {
|
|
||||||
authBindEx.UserData = sessionKey
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return authBindEx, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 特殊接口
|
|
||||||
func (a *MiniAuther) DecryptData(authInfo *auth2.AuthInfo, jsCode, encryptedData, iv string) (decryptedDataBase64 string, err error) {
|
|
||||||
var sessionKey string
|
|
||||||
appID, jsCode := SplitJsCode(jsCode)
|
|
||||||
if jsCode != "" {
|
|
||||||
sessionInfo, err := getWxApp(appID).SNSCode2Session(jsCode)
|
|
||||||
if err == nil {
|
|
||||||
// if authBindEx, err := a.UnionFindAuthBind(AuthTypeMini, getWxApp(appID).GetAppID(), []string{AuthTypeMini}, sessionInfo.OpenID, "", nil); err == nil {
|
|
||||||
// if authBindEx.UserID != authInfo.GetID() {
|
|
||||||
// return "", fmt.Errorf("jsCode与token不匹配")
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// return "", err
|
|
||||||
// }
|
|
||||||
sessionKey = sessionInfo.SessionKey
|
|
||||||
} else {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if authInfo.AuthBindInfo.Type != AuthTypeMini {
|
|
||||||
// return "", ErrAuthTypeShouldBeMini
|
|
||||||
}
|
|
||||||
sessionKey = authInfo.AuthBindInfo.UserData.(string)
|
|
||||||
}
|
|
||||||
// decryptedData, err := ProxySNSDecodeMiniProgramData(encryptedData, sessionKey, iv)
|
|
||||||
decryptedData, err := weixinapi.SNSDecodeMiniProgramData(encryptedData, sessionKey, iv)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
// authInfo.AuthBindInfo.UserData = sessionKey
|
|
||||||
return string(decryptedData), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *MiniAuther) GetUserType() (userType int8) {
|
|
||||||
return model.UserTypeStoreBoss
|
|
||||||
}
|
|
||||||
|
|
||||||
func getWxApp(appID string) (miniApi *weixinapi.API) {
|
|
||||||
miniApi = api.WeixinMiniAPI
|
|
||||||
if len(appID) > 0 && appID == api.WeixinMiniAppID2 {
|
|
||||||
miniApi = api.WeixinMiniAPI2
|
|
||||||
}
|
|
||||||
if len(appID) > 0 && appID == api.WeixinMiniAppIDsc {
|
|
||||||
miniApi = api.WeixinMiniAPIsc
|
|
||||||
}
|
|
||||||
//if len(appID) > 0 && appID == api.WeixinMiniPrintAppId {
|
|
||||||
// miniApi = api.WeixinMiniAPIPrint
|
|
||||||
//}
|
|
||||||
return miniApi
|
|
||||||
}
|
|
||||||
|
|
||||||
func SplitJsCode(jsCode string) (appID, realJsCode string) {
|
|
||||||
list := strings.Split(jsCode, ",")
|
|
||||||
if len(list) == 2 {
|
|
||||||
appID = list[0]
|
|
||||||
realJsCode = list[1]
|
|
||||||
} else if len(list) == 1 {
|
|
||||||
realJsCode = jsCode
|
|
||||||
} else {
|
|
||||||
globals.SugarLogger.Warnf("SplitJsCode abnormal jsCode:%s", jsCode)
|
|
||||||
}
|
|
||||||
return appID, realJsCode
|
|
||||||
}
|
|
||||||
|
|
||||||
func ComposeJsCode(appID, jsCode string) (composedCode string) {
|
|
||||||
composedCode = strings.Join([]string{
|
|
||||||
appID,
|
|
||||||
jsCode,
|
|
||||||
}, ",")
|
|
||||||
return composedCode
|
|
||||||
}
|
|
||||||
|
|
||||||
// func ProxySNSCode2Session(jsCode string) (sessionInfo *weixinapi.SessionInfo, err error) {
|
|
||||||
// miniApi := api.WeixinMiniAPI
|
|
||||||
// list := strings.Split(jsCode, ",")
|
|
||||||
// if len(list) >= 2 && len(list[0]) == len("wx4b5930c13f8b1170") {
|
|
||||||
// if list[0] == api.WeixinMiniAppID2 {
|
|
||||||
// miniApi = api.WeixinMiniAPI2
|
|
||||||
// }
|
|
||||||
// miniApi = getWxApp(list[0])
|
|
||||||
// jsCode = strings.Join(list[1:], ",")
|
|
||||||
// }
|
|
||||||
// sessionInfo, err = miniApi.SNSCode2Session(jsCode)
|
|
||||||
// return sessionInfo, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func ProxySNSDecodeMiniProgramData(encryptedData, sessionKey, iv string) (decryptedData []byte, err error) {
|
|
||||||
// globals.SugarLogger.Debugf("ProxySNSDecodeMiniProgramData, encryptedData:%s, sessionKey:%s, iv:%s", encryptedData, sessionKey, iv)
|
|
||||||
// decryptedData, err = api.WeixinMiniAPI.SNSDecodeMiniProgramData(encryptedData, sessionKey, iv)
|
|
||||||
// return decryptedData, err
|
|
||||||
// }
|
|
||||||
@@ -6,8 +6,8 @@ import (
|
|||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
"git.rosy.net.cn/jx-callback/business/authz"
|
"git.rosy.net.cn/jx-callback/business/authz"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/dao"
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetRoleDescription(name string, storeID int) (description string) {
|
func GetRoleDescription(name string, storeID int) (description string) {
|
||||||
|
|||||||
@@ -1,169 +0,0 @@
|
|||||||
package casbinauth
|
|
||||||
|
|
||||||
import (
|
|
||||||
jxmodel "git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"github.com/astaxie/beego/client/orm"
|
|
||||||
"github.com/casbin/casbin/model"
|
|
||||||
"github.com/casbin/casbin/persist"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Adapter struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
// finalizer is the destructor for Adapter.
|
|
||||||
func finalizer(a *Adapter) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewAdapter() *Adapter {
|
|
||||||
return &Adapter{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadPolicyLine(line jxmodel.CasbinRule, model model.Model) {
|
|
||||||
lineText := line.PType
|
|
||||||
if line.V0 != "" {
|
|
||||||
lineText += ", " + line.V0
|
|
||||||
}
|
|
||||||
if line.V1 != "" {
|
|
||||||
lineText += ", " + line.V1
|
|
||||||
}
|
|
||||||
if line.V2 != "" {
|
|
||||||
lineText += ", " + line.V2
|
|
||||||
}
|
|
||||||
if line.V3 != "" {
|
|
||||||
lineText += ", " + line.V3
|
|
||||||
}
|
|
||||||
if line.V4 != "" {
|
|
||||||
lineText += ", " + line.V4
|
|
||||||
}
|
|
||||||
if line.V5 != "" {
|
|
||||||
lineText += ", " + line.V5
|
|
||||||
}
|
|
||||||
|
|
||||||
persist.LoadPolicyLine(lineText, model)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Adapter) LoadPolicy(model model.Model) error {
|
|
||||||
var lines []jxmodel.CasbinRule
|
|
||||||
o := orm.NewOrm()
|
|
||||||
_, err := o.QueryTable("casbin_rule").Limit(-1).All(&lines)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, line := range lines {
|
|
||||||
loadPolicyLine(line, model)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func savePolicyLine(ptype string, rule []string) jxmodel.CasbinRule {
|
|
||||||
line := jxmodel.CasbinRule{}
|
|
||||||
|
|
||||||
line.PType = ptype
|
|
||||||
if len(rule) > 0 {
|
|
||||||
line.V0 = rule[0]
|
|
||||||
}
|
|
||||||
if len(rule) > 1 {
|
|
||||||
line.V1 = rule[1]
|
|
||||||
}
|
|
||||||
if len(rule) > 2 {
|
|
||||||
line.V2 = rule[2]
|
|
||||||
}
|
|
||||||
if len(rule) > 3 {
|
|
||||||
line.V3 = rule[3]
|
|
||||||
}
|
|
||||||
if len(rule) > 4 {
|
|
||||||
line.V4 = rule[4]
|
|
||||||
}
|
|
||||||
if len(rule) > 5 {
|
|
||||||
line.V5 = rule[5]
|
|
||||||
}
|
|
||||||
|
|
||||||
return line
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Adapter) clearAll(o orm.Ormer) (err error) {
|
|
||||||
_, err = o.Raw(`
|
|
||||||
DELETE t1
|
|
||||||
FROM casbin_rule t1
|
|
||||||
`).Exec()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// SavePolicy saves policy to database.
|
|
||||||
func (a *Adapter) SavePolicy(model model.Model) error {
|
|
||||||
o := orm.NewOrm()
|
|
||||||
|
|
||||||
a.clearAll(o)
|
|
||||||
var lines []jxmodel.CasbinRule
|
|
||||||
|
|
||||||
for ptype, ast := range model["p"] {
|
|
||||||
for _, rule := range ast.Policy {
|
|
||||||
line := savePolicyLine(ptype, rule)
|
|
||||||
lines = append(lines, line)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for ptype, ast := range model["g"] {
|
|
||||||
for _, rule := range ast.Policy {
|
|
||||||
line := savePolicyLine(ptype, rule)
|
|
||||||
lines = append(lines, line)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := o.InsertMulti(len(lines), lines)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddPolicy adds a policy rule to the storage.
|
|
||||||
func (a *Adapter) AddPolicy(sec string, ptype string, rule []string) error {
|
|
||||||
o := orm.NewOrm()
|
|
||||||
line := savePolicyLine(ptype, rule)
|
|
||||||
_, err := o.Insert(&line)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemovePolicy removes a policy rule from the storage.
|
|
||||||
func (a *Adapter) RemovePolicy(sec string, ptype string, rule []string) error {
|
|
||||||
o := orm.NewOrm()
|
|
||||||
line := savePolicyLine(ptype, rule)
|
|
||||||
_, err := o.Delete(&line, "p_type", "v0", "v1", "v2", "v3", "v4", "v5")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveFilteredPolicy removes policy rules that match the filter from the storage.
|
|
||||||
func (a *Adapter) RemoveFilteredPolicy(sec string, ptype string, fieldIndex int, fieldValues ...string) error {
|
|
||||||
line := jxmodel.CasbinRule{}
|
|
||||||
|
|
||||||
line.PType = ptype
|
|
||||||
filter := []string{}
|
|
||||||
filter = append(filter, "p_type")
|
|
||||||
if fieldIndex <= 0 && 0 < fieldIndex+len(fieldValues) {
|
|
||||||
line.V0 = fieldValues[0-fieldIndex]
|
|
||||||
filter = append(filter, "v0")
|
|
||||||
}
|
|
||||||
if fieldIndex <= 1 && 1 < fieldIndex+len(fieldValues) {
|
|
||||||
line.V1 = fieldValues[1-fieldIndex]
|
|
||||||
filter = append(filter, "v1")
|
|
||||||
}
|
|
||||||
if fieldIndex <= 2 && 2 < fieldIndex+len(fieldValues) {
|
|
||||||
line.V2 = fieldValues[2-fieldIndex]
|
|
||||||
filter = append(filter, "v2")
|
|
||||||
}
|
|
||||||
if fieldIndex <= 3 && 3 < fieldIndex+len(fieldValues) {
|
|
||||||
line.V3 = fieldValues[3-fieldIndex]
|
|
||||||
filter = append(filter, "v3")
|
|
||||||
}
|
|
||||||
if fieldIndex <= 4 && 4 < fieldIndex+len(fieldValues) {
|
|
||||||
line.V4 = fieldValues[4-fieldIndex]
|
|
||||||
filter = append(filter, "v4")
|
|
||||||
}
|
|
||||||
if fieldIndex <= 5 && 5 < fieldIndex+len(fieldValues) {
|
|
||||||
line.V5 = fieldValues[5-fieldIndex]
|
|
||||||
filter = append(filter, "v5")
|
|
||||||
}
|
|
||||||
|
|
||||||
o := orm.NewOrm()
|
|
||||||
_, err := o.Delete(&line, filter...)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
package casbinauth
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.rosy.net.cn/jx-callback/business/authz"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/authz/autils"
|
|
||||||
"github.com/casbin/casbin"
|
|
||||||
"github.com/casbin/casbin/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type CasbinAuthz struct {
|
|
||||||
enforcer *casbin.SyncedEnforcer
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(modelFile string) (authObj authz.IAuthz, err error) {
|
|
||||||
obj := &CasbinAuthz{}
|
|
||||||
obj.enforcer, err = casbin.NewSyncedEnforcer(modelFile, NewAdapter())
|
|
||||||
return obj, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *CasbinAuthz) AddRole4User(userID string, r *authz.RoleInfo) (err error) {
|
|
||||||
_, err = c.enforcer.AddRoleForUser(userID, r.GetFullName())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *CasbinAuthz) DeleteRole4User(userID string, r *authz.RoleInfo) (err error) {
|
|
||||||
_, err = c.enforcer.DeleteRoleForUser(userID, r.GetFullName())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *CasbinAuthz) GetUserRoleList(userID string) (roleList []*authz.RoleInfo, err error) {
|
|
||||||
roleNameList, err := c.enforcer.GetRolesForUser(userID)
|
|
||||||
if err == nil && len(roleNameList) > 0 {
|
|
||||||
roleList = autils.FullRoleName2RoleList(roleNameList)
|
|
||||||
}
|
|
||||||
return roleList, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *CasbinAuthz) GetRoleUserList(r *authz.RoleInfo) (userIDList []string, err error) {
|
|
||||||
// globals.SugarLogger.Debug(roleFullName)
|
|
||||||
userIDList, err = c.enforcer.GetUsersForRole(r.GetFullName())
|
|
||||||
if err == errors.ERR_NAME_NOT_FOUND {
|
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
return userIDList, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// func (c *CasbinAuthz) GetAllRoleList() (roleList []*authz.RoleInfo) {
|
|
||||||
// return authz.FullRoleName2RoleList(c.enforcer.GetAllRoles())
|
|
||||||
// }
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,266 +0,0 @@
|
|||||||
package bidding
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/ali_logistics_query"
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/dingdingapi"
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/tonglianpayapi"
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/weixinapi"
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/ddmsg"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func LoadingLogistics(paramLogistic []*model.UpdateMaterialLogistic) []error {
|
|
||||||
var param []*model.UpdateMaterialLogistic
|
|
||||||
if len(paramLogistic) == 0 || paramLogistic == nil {
|
|
||||||
param = GetLogisticOrder()
|
|
||||||
} else {
|
|
||||||
param = paramLogistic
|
|
||||||
}
|
|
||||||
|
|
||||||
var db = dao.GetDB()
|
|
||||||
var errList = make([]error, 0, 0)
|
|
||||||
|
|
||||||
for _, v := range param {
|
|
||||||
// 更新订单状态
|
|
||||||
goodsOrder, err := partner.CurOrderManager.LoadOrder(v.OrderId, model.VendorIDJX)
|
|
||||||
if err != nil {
|
|
||||||
errList = append(errList, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if time.Since(goodsOrder.CreatedAt) >= 3*24*time.Hour {
|
|
||||||
goodsOrder.Status = model.OrderStatusFinished
|
|
||||||
goodsOrder.VendorStatus = utils.Int2Str(model.WaybillStatusDelivered)
|
|
||||||
goodsOrder.StatusTime = time.Now()
|
|
||||||
goodsOrder.OrderFinishedAt = time.Now()
|
|
||||||
if _, err := dao.UpdateEntity(db, goodsOrder, "Status", "VendorStatus", "StatusTime", "OrderFinishedAt"); err != nil {
|
|
||||||
errList = append(errList, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
payList, _ := dao.GetOrderPayList(db, goodsOrder.VendorOrderID, goodsOrder.VendorID)
|
|
||||||
for _, pl := range payList {
|
|
||||||
if pl.OriginalData != "" {
|
|
||||||
originalData := &tonglianpayapi.CallBackResult{}
|
|
||||||
json.Unmarshal([]byte(pl.OriginalData), originalData)
|
|
||||||
|
|
||||||
if err = api.WeixinMiniAPI2.SNSDeliveryGoodsOrder(&weixinapi.DeliveryOrder{
|
|
||||||
TransactionId: originalData.ChnlTrxID,
|
|
||||||
ReceivedTime: time.Now().Unix(),
|
|
||||||
}); err != nil {
|
|
||||||
ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "2452A93EEB9111EC9B06525400E86DC0", "微信物料送达推送", fmt.Sprintf("物料商城下单,送达错误:%s,请注意查看,err:%s", goodsOrder.VendorOrderID, err.Error()))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
|
|
||||||
// GetLogisticsInfo 免费物流查询资源不可用,暂时不管
|
|
||||||
//for _, logistics := range param {
|
|
||||||
// // 获取当前订单物流状态
|
|
||||||
// statusList, err := orderman.FixedOrderManager.GetLogisticsOrderStatusList(logistics.OrderId, logistics.LogisticId, 9)
|
|
||||||
// if err != nil {
|
|
||||||
// errList = append(errList, err)
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // 获取当前订单三方配送物流
|
|
||||||
// logisticsList, err := api.LogisticsApi.GetLogisticsInfo(logistics.LogisticId)
|
|
||||||
// if err != nil {
|
|
||||||
// errList = append(errList, err)
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // 新订单,本地暂无物流信息,全部更新远端物流信息到本地
|
|
||||||
// if len(logisticsList.Info[0].LogisticsTraceDetailList) == model.NO {
|
|
||||||
// errList = append(errList, errors.New("运单号[%s]:已经过期/新订单暂无物流推送信息"))
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// var orderStatus = make([]*model.OrderStatus, 0, 0)
|
|
||||||
// goodsOrderStatus := 0
|
|
||||||
// for _, v := range logisticsList.Info[0].LogisticsTraceDetailList {
|
|
||||||
// orderStatusToLocal := &model.OrderStatus{
|
|
||||||
// VendorOrderID: logisticsList.Info[0].MailNo,
|
|
||||||
// VendorID: model.VendorIDTotalWl,
|
|
||||||
// OrderType: model.OrderTypeWaybill,
|
|
||||||
// RefVendorOrderID: logistics.OrderId,
|
|
||||||
// RefVendorID: model.VendorIDJX,
|
|
||||||
// VendorStatus: v.SubLogisticsStatus,
|
|
||||||
// StatusTime: time.Time{},
|
|
||||||
// DuplicatedCount: 0,
|
|
||||||
// Remark: v.Desc,
|
|
||||||
// ModelTimeInfo: model.ModelTimeInfo{CreatedAt: time.Now(), UpdatedAt: time.Now()},
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// switch v.SubLogisticsStatus {
|
|
||||||
// case ali_logistics_query.LogisticsStatusRECEVIE:
|
|
||||||
// orderStatusToLocal.Status = model.WaybillStatusNew // 新订单
|
|
||||||
// goodsOrderStatus = model.OrderStatusNew // 新订单
|
|
||||||
// case ali_logistics_query.LogisticsStatusWAIT_ACCEPT:
|
|
||||||
// orderStatusToLocal.Status = model.WaybillStatusAccepted // 分配骑手
|
|
||||||
// goodsOrderStatus = model.OrderStatusAccepted // 拣货完成等待骑手
|
|
||||||
// case ali_logistics_query.LogisticsStatusACCEPT:
|
|
||||||
// orderStatusToLocal.Status = model.WaybillStatusCourierArrived // 兼容骑手取货状态
|
|
||||||
// goodsOrderStatus = model.OrderStatusFinishedPickup
|
|
||||||
// case ali_logistics_query.LogisticsStatusTRANSPORT, ali_logistics_query.LogisticsStatusSEND_ON, ali_logistics_query.LogisticsStatusARRIVE_CITY, ali_logistics_query.LogisticsStatusDELIVERING:
|
|
||||||
// orderStatusToLocal.Status = model.WaybillStatusDelivering // 配送中
|
|
||||||
// goodsOrderStatus = model.OrderStatusDelivering
|
|
||||||
// case ali_logistics_query.LogisticsStatusAGENT_SIGN, ali_logistics_query.LogisticsStatusSIGN, ali_logistics_query.LogisticsStatusSTA_SIGN:
|
|
||||||
// orderStatusToLocal.Status = model.WaybillStatusDelivered // 配送结束
|
|
||||||
// goodsOrderStatus = model.OrderStatusFinished
|
|
||||||
// default: // 剩余状态全部为异常状态,除非新加状态
|
|
||||||
// orderStatusToLocal.Status = model.WaybillStatusUnknown // 异常配送
|
|
||||||
// goodsOrderStatus = model.OrderStatusDeliverFailed // 投递失败
|
|
||||||
// }
|
|
||||||
// orderStatusToLocal.StatusTime = utils.Timestamp2Time(v.Time)
|
|
||||||
// orderStatus = append(orderStatus, orderStatusToLocal)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if len(statusList) == 0 || statusList == nil { // 本地订单状态为空不存在
|
|
||||||
// for _, v := range orderStatus {
|
|
||||||
// if err := dao.CreateEntity(db, v); err != nil {
|
|
||||||
// errList = append(errList, err)
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// for _, v := range orderStatus {
|
|
||||||
// if statusList[len(statusList)-1].StatusTime.Unix() > v.StatusTime.Unix() && checkOrderStatus(statusList[len(statusList)-1].VendorStatus) {
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// if err := dao.CreateEntity(db, v); err != nil {
|
|
||||||
// errList = append(errList, err)
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // 获取当前订单运单状态
|
|
||||||
// wayBill, err := dao.GetWaybills(db, logistics.OrderId, nil)
|
|
||||||
// if err != nil {
|
|
||||||
// errList = append(errList, err)
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// status := orderStatus[len(orderStatus)-1].Status
|
|
||||||
// vendorStatus := orderStatus[len(orderStatus)-1].VendorStatus
|
|
||||||
// statusTime := orderStatus[len(orderStatus)-1].StatusTime
|
|
||||||
// if len(wayBill) == 0 || wayBill == nil {
|
|
||||||
// wayBillObj := &model.Waybill{
|
|
||||||
// VendorWaybillID: logistics.LogisticId,
|
|
||||||
// WaybillVendorID: model.VendorIDTotalWl,
|
|
||||||
// VendorOrderID: logistics.OrderId,
|
|
||||||
// OrderVendorID: model.VendorIDJX,
|
|
||||||
// CourierName: logisticsList.Info[0].Courier,
|
|
||||||
// CourierMobile: logisticsList.Info[0].CourierPhone,
|
|
||||||
// Status: status,
|
|
||||||
// VendorStatus: vendorStatus,
|
|
||||||
// ActualFee: logistics.LogisticFee,
|
|
||||||
// DesiredFee: logistics.LogisticFee,
|
|
||||||
// DeliveryFlag: model.OrderDeliveryFlagMaskScheduleDisabled,
|
|
||||||
// WaybillCreatedAt: time.Now(),
|
|
||||||
// StatusTime: statusTime,
|
|
||||||
// ModelTimeInfo: model.ModelTimeInfo{CreatedAt: time.Now(), UpdatedAt: time.Now()},
|
|
||||||
// WaybillFinishedAt: time.Now(),
|
|
||||||
// }
|
|
||||||
// if err := dao.CreateEntity(db, wayBillObj); err != nil {
|
|
||||||
// errList = append(errList, err)
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// wayBill[0].UpdatedAt = time.Now()
|
|
||||||
// wayBill[0].Status = status
|
|
||||||
// wayBill[0].VendorStatus = vendorStatus
|
|
||||||
// wayBill[0].StatusTime = statusTime
|
|
||||||
// wayBill[0].WaybillFinishedAt = time.Now()
|
|
||||||
// if _, err := dao.UpdateEntity(db, wayBill[0], "Status", "UpdatedAt", "VendorStatus", "StatusTime"); err != nil {
|
|
||||||
// errList = append(errList, err)
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // 更新订单状态
|
|
||||||
// goodsOrder, err := partner.CurOrderManager.LoadOrder(logistics.OrderId, model.VendorIDJX)
|
|
||||||
// if err != nil {
|
|
||||||
// errList = append(errList, err)
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// goodsOrder.Status = goodsOrderStatus
|
|
||||||
// goodsOrder.VendorStatus = vendorStatus
|
|
||||||
// goodsOrder.StatusTime = statusTime
|
|
||||||
// if orderStatus[len(orderStatus)-1].Status >= model.OrderStatusEndBegin {
|
|
||||||
// goodsOrder.OrderFinishedAt = time.Now()
|
|
||||||
// }
|
|
||||||
// if _, err := dao.UpdateEntity(db, goodsOrder, "Status", "VendorStatus", "StatusTime", "OrderFinishedAt"); err != nil {
|
|
||||||
// errList = append(errList, err)
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//return errList
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkOrderStatus(orderStatus string) bool {
|
|
||||||
switch orderStatus {
|
|
||||||
case ali_logistics_query.LogisticsStatusRECEVIE:
|
|
||||||
return true
|
|
||||||
case ali_logistics_query.LogisticsStatusWAIT_ACCEPT:
|
|
||||||
return true
|
|
||||||
case ali_logistics_query.LogisticsStatusACCEPT:
|
|
||||||
return true
|
|
||||||
case ali_logistics_query.LogisticsStatusTRANSPORT, ali_logistics_query.LogisticsStatusSEND_ON, ali_logistics_query.LogisticsStatusARRIVE_CITY, ali_logistics_query.LogisticsStatusDELIVERING:
|
|
||||||
return true
|
|
||||||
case ali_logistics_query.LogisticsStatusAGENT_SIGN, ali_logistics_query.LogisticsStatusSIGN, ali_logistics_query.LogisticsStatusSTA_SIGN:
|
|
||||||
return true
|
|
||||||
case ali_logistics_query.LogisticsStatusSTA_INBOUND, ali_logistics_query.LogisticsStatusRETURN_SIGN, ali_logistics_query.LogisticsStatusFAILED, ali_logistics_query.LogisticsStatusREFUSE_SIGN, ali_logistics_query.LogisticsStatusDELIVER_ABNORMAL:
|
|
||||||
return true
|
|
||||||
case ali_logistics_query.LogisticsStatusRETENTION, ali_logistics_query.LogisticsStatusISSUE, ali_logistics_query.LogisticsStatusRETURN, ali_logistics_query.LogisticsStatusDAMAGE, ali_logistics_query.LogisticsStatusCANCEL_ORDER:
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetLogisticOrder 查询未完成的物料订单,更新物流信息
|
|
||||||
func GetLogisticOrder() []*model.UpdateMaterialLogistic {
|
|
||||||
var (
|
|
||||||
timeNow = time.Now()
|
|
||||||
startTime = timeNow.AddDate(0, -1, 0)
|
|
||||||
endTime = timeNow
|
|
||||||
goodsList = make([]*model.GoodsOrder, 0, 0)
|
|
||||||
)
|
|
||||||
|
|
||||||
sql := ` SELECT * FROM goods_order g WHERE g.order_created_at >= ? AND g.order_created_at < ? AND g.store_id = ? AND order_type = ? AND g.status < ? ` // 一个月内状态未完成的订单
|
|
||||||
sqlParam := []interface{}{
|
|
||||||
startTime, endTime, "666666", 1, model.OrderStatusEndBegin,
|
|
||||||
}
|
|
||||||
if err := dao.GetRows(dao.GetDB(), &goodsList, sql, sqlParam...); err != nil {
|
|
||||||
globals.SugarLogger.Debugf("loading jx material order err :%s", err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(goodsList) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
logisticsList := make([]*model.UpdateMaterialLogistic, 0, len(goodsList))
|
|
||||||
for _, v := range goodsList {
|
|
||||||
logistics := &model.UpdateMaterialLogistic{
|
|
||||||
OrderId: v.VendorOrderID,
|
|
||||||
LogisticId: v.VendorWaybillID,
|
|
||||||
LogisticFee: v.BaseFreightMoney,
|
|
||||||
}
|
|
||||||
logisticsList = append(logisticsList, logistics)
|
|
||||||
}
|
|
||||||
return logisticsList
|
|
||||||
}
|
|
||||||
@@ -1,230 +0,0 @@
|
|||||||
package bidding
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
|
||||||
"sort"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetStatisticsList 京西数据查询
|
|
||||||
func GetStatisticsList(start, end time.Time, storeIds []int, offset, pageSize int) (*model.PagedInfo, error) {
|
|
||||||
return dao.GetStatistics(dao.GetDB(), start, end, storeIds, offset, pageSize)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetMTInfo 更新美团门店信息
|
|
||||||
func GetMTInfo() []error {
|
|
||||||
var db = dao.GetDB()
|
|
||||||
var errList = make([]error, 0, 0)
|
|
||||||
// 获取当前一月有效订单的门店信息
|
|
||||||
effectiveStores, err := dao.StoreInformationStatistics(db)
|
|
||||||
if err != nil {
|
|
||||||
return append(errList, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var mtApi *mtwmapi.API
|
|
||||||
for _, v := range effectiveStores {
|
|
||||||
if v.VendorOrgCode == globals.Mtwm2Code {
|
|
||||||
mtApi = api.Mtwm2API
|
|
||||||
mtApi.SetToken(v.MtwmToken)
|
|
||||||
} else {
|
|
||||||
mtApi = api.MtwmAPI
|
|
||||||
}
|
|
||||||
|
|
||||||
statistics := &model.ActivityStation{
|
|
||||||
StoreID: v.JxStoreID,
|
|
||||||
VendorID: model.VendorIDMTWM,
|
|
||||||
VendorStoreID: v.VendorStoreID,
|
|
||||||
BrandID: v.VendorOrgCode,
|
|
||||||
//Activity1: 0,
|
|
||||||
//Activity2: 0,
|
|
||||||
//Activity: 0,
|
|
||||||
//StoreSkuNum: 0,
|
|
||||||
//StoreRating: 0,
|
|
||||||
//DeliveryFee: "",
|
|
||||||
//DeliveryFee2: "",
|
|
||||||
PromotionFee: "暂无法获取",
|
|
||||||
//BusinessHours: "",
|
|
||||||
}
|
|
||||||
dao.WrapAddIDCULEntity(statistics, "system")
|
|
||||||
down, up := getActivityCount(mtApi, v.VendorStoreID)
|
|
||||||
statistics.Activity1 = int64(down)
|
|
||||||
statistics.Activity2 = int64(up)
|
|
||||||
statistics.Activity = int64(down + up)
|
|
||||||
score, err := mtApi.CommentScore(v.VendorStoreID)
|
|
||||||
if err != nil {
|
|
||||||
errList = append(errList, fmt.Errorf("%s获取评分错误:%s", v.VendorStoreID, err.Error()))
|
|
||||||
}
|
|
||||||
if score != nil {
|
|
||||||
statistics.StoreRating = score.AvgPoiScore
|
|
||||||
} else {
|
|
||||||
statistics.StoreRating = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取门店营业时长
|
|
||||||
detail, _ := mtApi.PoiMGet([]string{v.VendorStoreID})
|
|
||||||
if detail != nil {
|
|
||||||
statistics.BusinessHours, err = getStoreShippingTime(detail[0].ShippingTime)
|
|
||||||
if err != nil {
|
|
||||||
errList = append(errList, fmt.Errorf("%s获取营业时长错误:%s", v.VendorStoreID, err.Error()))
|
|
||||||
statistics.BusinessHours = err.Error()
|
|
||||||
}
|
|
||||||
statistics.DeliveryFee2 = utils.Float64ToStr(detail[0].ShippingFee)
|
|
||||||
}
|
|
||||||
// 获取门店起送价
|
|
||||||
result, err := mtApi.ShippingList(v.VendorStoreID)
|
|
||||||
if err != nil {
|
|
||||||
errList = append(errList, fmt.Errorf("%s获取起送价错误:%s", v.VendorStoreID, err.Error()))
|
|
||||||
statistics.DeliveryFee = err.Error()
|
|
||||||
}
|
|
||||||
shippingList := make([]ShippingList, 0, 0)
|
|
||||||
for _, v2 := range result {
|
|
||||||
shippingList = append(shippingList, ShippingList{
|
|
||||||
TimeRange: utils.Interface2String(v2["time_range"]),
|
|
||||||
MinPrice: utils.MustInterface2Float64(v2["min_price"]),
|
|
||||||
ShippingFee: utils.MustInterface2Float64(v2["shipping_fee"]),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
statistics.DeliveryFee = utils.Format4Output(shippingList, false)
|
|
||||||
if len(result) == 0 {
|
|
||||||
statistics.DeliveryFee = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
dao.CreateEntity(db, statistics)
|
|
||||||
}
|
|
||||||
|
|
||||||
return errList
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取门店折扣活动商品数量
|
|
||||||
func getActivityCount(api *mtwmapi.API, vendorStoreId string) (int, int) {
|
|
||||||
threefoldDown := 0 // 0-3 折活动数量
|
|
||||||
threefoldUp := 0 // 3.01-9 折活动
|
|
||||||
// 获取美团活动
|
|
||||||
directList, _ := api.RetailDiscountList(vendorStoreId, mtwmapi.RetailActTypeDirectDown) // 折扣活动
|
|
||||||
for _, v := range directList {
|
|
||||||
if v.ActPrice/v.OriginalPrice >= 3.01 {
|
|
||||||
threefoldUp++
|
|
||||||
} else {
|
|
||||||
threefoldDown++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
secKillList, _ := api.RetailDiscountList(vendorStoreId, mtwmapi.RetailActTypeSecKill) // 爆品活动
|
|
||||||
if secKillList != nil {
|
|
||||||
threefoldDown = threefoldDown + len(secKillList)
|
|
||||||
}
|
|
||||||
|
|
||||||
return threefoldDown, threefoldUp
|
|
||||||
}
|
|
||||||
|
|
||||||
func getStoreShippingTime(storeTime string) (string, error) {
|
|
||||||
time2 := strings.Split(storeTime, ";")
|
|
||||||
aa := int(time.Now().Weekday())
|
|
||||||
if aa == 0 {
|
|
||||||
aa = 7
|
|
||||||
}
|
|
||||||
if len(time2) == 1 {
|
|
||||||
aa = 1
|
|
||||||
}
|
|
||||||
intervals, err := parseIntervals(time2[aa-1])
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("解析错误: %v\n", err)
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
merged := mergeIntervals(intervals)
|
|
||||||
|
|
||||||
totalMinutes := 0
|
|
||||||
for _, iv := range merged {
|
|
||||||
totalMinutes += iv.end - iv.start
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%.2f", float64(totalMinutes)/float64(60)), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// timeToMinutes 将 "HH:MM" 转为当天第几分钟(0 ~ 1439)
|
|
||||||
func timeToMinutes(t string) (int, error) {
|
|
||||||
parts := strings.Split(t, ":")
|
|
||||||
if len(parts) != 2 {
|
|
||||||
return 0, fmt.Errorf("invalid time format: %s", t)
|
|
||||||
}
|
|
||||||
h, err := strconv.Atoi(parts[0])
|
|
||||||
if err != nil || h < 0 || h > 23 {
|
|
||||||
return 0, fmt.Errorf("invalid hour in %s", t)
|
|
||||||
}
|
|
||||||
m, err := strconv.Atoi(parts[1])
|
|
||||||
if err != nil || m < 0 || m > 59 {
|
|
||||||
return 0, fmt.Errorf("invalid minute in %s", t)
|
|
||||||
}
|
|
||||||
return h*60 + m, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseIntervals 解析 "00:00-01:00,01:05-23:59" → []interval
|
|
||||||
type interval struct {
|
|
||||||
start, end int // minutes since 00:00
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseIntervals(s string) ([]interval, error) {
|
|
||||||
var intervals []interval
|
|
||||||
for _, seg := range strings.Split(s, ",") {
|
|
||||||
seg = strings.TrimSpace(seg)
|
|
||||||
if seg == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
parts := strings.Split(seg, "-")
|
|
||||||
if len(parts) != 2 {
|
|
||||||
return nil, fmt.Errorf("invalid interval format: %s", seg)
|
|
||||||
}
|
|
||||||
startMins, err := timeToMinutes(strings.TrimSpace(parts[0]))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
endMins, err := timeToMinutes(strings.TrimSpace(parts[1]))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if startMins > endMins {
|
|
||||||
return nil, fmt.Errorf("start after end in interval: %s", seg)
|
|
||||||
}
|
|
||||||
intervals = append(intervals, interval{start: startMins, end: endMins})
|
|
||||||
}
|
|
||||||
return intervals, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// mergeIntervals 合并重叠/相邻区间(如 [0,60], [65,1439] → 保留两个;若 [0,60], [60,120] → 可合并为 [0,120])
|
|
||||||
func mergeIntervals(ints []interval) []interval {
|
|
||||||
if len(ints) == 0 {
|
|
||||||
return ints
|
|
||||||
}
|
|
||||||
// 排序
|
|
||||||
sort.Slice(ints, func(i, j int) bool {
|
|
||||||
return ints[i].start < ints[j].start
|
|
||||||
})
|
|
||||||
|
|
||||||
merged := make([]interval, 0, len(ints))
|
|
||||||
curr := ints[0]
|
|
||||||
for i := 1; i < len(ints); i++ {
|
|
||||||
if ints[i].start <= curr.end { // 重叠或紧邻(如 end=60, next.start=60 → 合并)
|
|
||||||
if ints[i].end > curr.end {
|
|
||||||
curr.end = ints[i].end
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
merged = append(merged, curr)
|
|
||||||
curr = ints[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
merged = append(merged, curr)
|
|
||||||
return merged
|
|
||||||
}
|
|
||||||
|
|
||||||
type ShippingList struct {
|
|
||||||
TimeRange string `json:"time_range"` // 配送生效时间范围
|
|
||||||
MinPrice float64 `json:"min_price"` // 最小起送价
|
|
||||||
ShippingFee float64 `json:"shipping_fee"` // 配送费
|
|
||||||
}
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
package cs
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/weimobapi"
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/authz/autils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxstore/cms"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
minCSOrderPayment = 0 // 供货订单的最小金额(单位为元)
|
|
||||||
maxUnitPrice = 3000 // 为防止误填单价,限制单价最高(单位为分)
|
|
||||||
)
|
|
||||||
|
|
||||||
func OnCallbackMsg(msg *weimobapi.CallbackMsg) (response *weimobapi.CallbackResponse) {
|
|
||||||
orderID := utils.Int64ToStr(msg.OrderNo)
|
|
||||||
jxutils.CallMsgHandler(func() {
|
|
||||||
response = onOrderMsg(msg)
|
|
||||||
}, jxutils.ComposeUniversalOrderID(orderID, model.VendorIDWSC))
|
|
||||||
return response
|
|
||||||
}
|
|
||||||
|
|
||||||
func onOrderMsg(msg *weimobapi.CallbackMsg) (response *weimobapi.CallbackResponse) {
|
|
||||||
if msg.Event == weimobapi.MsgEventOrderStatusChange {
|
|
||||||
if utils.ForceInterface2Int64(msg.MsgBody["orderStatus"]) == weimobapi.MsgOrderStatusFinished {
|
|
||||||
if orderDetail, err := api.WeimobAPI.QueryOrderDetail2(msg.OrderNo, false); err == nil {
|
|
||||||
if orderDetail.OrderStatus == weimobapi.OrderStatusFinished && orderDetail.PaymentAmount >= minCSOrderPayment {
|
|
||||||
changeStoreSkusByOrder(orderDetail)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
response = weimobapi.Err2CallbackResponse(err, "")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return response
|
|
||||||
}
|
|
||||||
|
|
||||||
func changeStoreSkusByOrder(order *weimobapi.OrderDetail) {
|
|
||||||
receiverMobile := order.DeliveryDetail.LogisticsDeliveryDetail.ReceiverMobile
|
|
||||||
ctx := jxcontext.NewWithUserName(nil, utils.LimitStringLen(utils.Int64ToStr(order.OrderNo), 32), nil, nil)
|
|
||||||
if storeList, err := GetStoreList4Mobile(dao.GetDB(), []string{receiverMobile}); err == nil {
|
|
||||||
if len(storeList) >= 1 {
|
|
||||||
var skuBindInfos []*cms.StoreSkuBindInfo
|
|
||||||
storeID := storeList[0].ID
|
|
||||||
for _, v := range order.ItemList {
|
|
||||||
nameID := int(utils.Str2Int64WithDefault(v.SkuCode, 0))
|
|
||||||
unitPrice := v.CostPrice
|
|
||||||
if nameID > 0 && (unitPrice > 0 && unitPrice < maxUnitPrice) {
|
|
||||||
skuBindInfos = append(skuBindInfos, &cms.StoreSkuBindInfo{
|
|
||||||
StoreID: storeID,
|
|
||||||
NameID: nameID,
|
|
||||||
UnitPrice: int(jxutils.StandardPrice2Int(unitPrice)),
|
|
||||||
IsFocus: 1,
|
|
||||||
IsSale: 1,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
globals.SugarLogger.Infof("[运营],微商城订单:%d,商品:%s没有设置正确的SkuName编码或单价,当前商家编码:%s,市场价:%s", order.OrderNo, v.SkuNum, v.SkuCode, jxutils.IntPrice2StandardString(jxutils.StandardPrice2Int(unitPrice)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(skuBindInfos) > 0 {
|
|
||||||
var nameIDs []int
|
|
||||||
for _, v := range skuBindInfos {
|
|
||||||
nameIDs = append(nameIDs, v.NameID)
|
|
||||||
}
|
|
||||||
if skuNamesInfo, err := cms.GetSkuNames(ctx, "", false, false, map[string]interface{}{
|
|
||||||
"nameIDs": string(utils.MustMarshal(nameIDs)),
|
|
||||||
}, 0, 0); err == nil {
|
|
||||||
for _, skuName := range skuNamesInfo.SkuNames {
|
|
||||||
if skuName.Status != model.SkuStatusNormal {
|
|
||||||
cms.UpdateSkuName(ctx, skuName.ID, map[string]interface{}{
|
|
||||||
"status": model.SkuStatusNormal,
|
|
||||||
}, false)
|
|
||||||
}
|
|
||||||
for _, sku := range skuName.Skus {
|
|
||||||
if sku.Status != model.SkuStatusNormal {
|
|
||||||
cms.UpdateSku(ctx, sku.ID, map[string]interface{}{
|
|
||||||
"status": model.SkuStatusNormal,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cms.UpdateStoreSkus(ctx, 0, storeID, skuBindInfos, true, true)
|
|
||||||
} else {
|
|
||||||
globals.SugarLogger.Debugf("changeStoreSkusByOrder orderID:%d, storeID:%d is empty", order.OrderNo, storeID)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
globals.SugarLogger.Infof("[运营],微商城订单:%d,手机:%s找不到唯一一个本地门店%d", order.OrderNo, receiverMobile, len(storeList))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
globals.SugarLogger.Warnf("changeStoreSkusByOrder orderNo:%d, receiverMobile:%s failed with err:%v", order.OrderNo, receiverMobile, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetStoreList4Mobile(db *dao.DaoDB, mobileList []string) (storeList []*model.Store, err error) {
|
|
||||||
sql := `
|
|
||||||
SELECT t1.*
|
|
||||||
FROM store t1
|
|
||||||
WHERE t1.deleted_at = ? /*AND t1.change_price_type = ?*/`
|
|
||||||
sqlParams := []interface{}{
|
|
||||||
utils.DefaultTimeValue,
|
|
||||||
// model.StoreChangePriceTypeBossDisabled,
|
|
||||||
}
|
|
||||||
if len(mobileList) > 0 {
|
|
||||||
questionMarks := dao.GenQuestionMarks(len(mobileList))
|
|
||||||
sql += " AND (t1.tel1 IN (" + questionMarks + ") OR t1.tel2 IN (" + questionMarks + `)
|
|
||||||
OR (SELECT
|
|
||||||
COUNT(*)
|
|
||||||
FROM casbin_rule t2
|
|
||||||
JOIN user t3 ON t3.user_id = t2.v0 AND t3.mobile IN (` + questionMarks + `)
|
|
||||||
WHERE t2.v1 = CONCAT(?, t1.id)
|
|
||||||
) > 0)
|
|
||||||
`
|
|
||||||
sqlParams = append(sqlParams, mobileList, mobileList, mobileList, autils.NewStoreBossRole(-1).GetFullName())
|
|
||||||
}
|
|
||||||
err = dao.GetRows(db, &storeList, sql, sqlParams...)
|
|
||||||
return storeList, err
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
package cs
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api2"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/testinit"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
testinit.Init()
|
|
||||||
api2.Init()
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetStoreList4Mobile(t *testing.T) {
|
|
||||||
storeList, err := GetStoreList4Mobile(dao.GetDB(), []string{"18180948107"})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
t.Log(utils.Format4Output(storeList, false))
|
|
||||||
t.Log(len(storeList))
|
|
||||||
}
|
|
||||||
32
business/dao/common.go
Normal file
32
business/dao/common.go
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package dao
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetDataResource(db *DaoDB, hashCode, fullURL string) (dataRes *model.DataResource, err error) {
|
||||||
|
sql := `
|
||||||
|
SELECT t1.*
|
||||||
|
FROM data_resource t1
|
||||||
|
WHERE 0 = 1`
|
||||||
|
sqlParams := []interface{}{}
|
||||||
|
if hashCode != "" {
|
||||||
|
sql += " OR t1.hash_code = ?"
|
||||||
|
sqlParams = append(sqlParams, hashCode)
|
||||||
|
}
|
||||||
|
if fullURL != "" {
|
||||||
|
sql += " OR t1.main_url = ? OR t1.qiniu_url = ? OR t1.ebai_url = ? OR t1.mtwm_url = ?"
|
||||||
|
sqlParams = append(sqlParams, fullURL, fullURL, fullURL, fullURL)
|
||||||
|
}
|
||||||
|
err = GetRow(db, &dataRes, sql, sqlParams...)
|
||||||
|
return dataRes, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetNeedUploadDataResource(db *DaoDB) (dataResList []*model.DataResource, err error) {
|
||||||
|
sql := `
|
||||||
|
SELECT t1.*
|
||||||
|
FROM data_resource t1
|
||||||
|
WHERE t1.use_type <> 0 AND (t1.ebai_url = '' OR t1.mtwm_url = '')`
|
||||||
|
err = GetRows(db, &dataResList, sql)
|
||||||
|
return dataResList, err
|
||||||
|
}
|
||||||
@@ -79,6 +79,7 @@ func Begin(db *DaoDB) (txDB orm.TxOrmer, err error) {
|
|||||||
func (db *DaoDB) startWatchTransaction() {
|
func (db *DaoDB) startWatchTransaction() {
|
||||||
db.beginTransactionStack = debug.Stack()
|
db.beginTransactionStack = debug.Stack()
|
||||||
db.transactionWatchTimer = utils.AfterFuncWithRecover(transactionWarningSeconds*time.Second, func() {
|
db.transactionWatchTimer = utils.AfterFuncWithRecover(transactionWarningSeconds*time.Second, func() {
|
||||||
|
globals.SugarLogger.Warnf("Begin Transaction too long, %s", string(db.beginTransactionStack))
|
||||||
db.transactionWatchTimer = nil
|
db.transactionWatchTimer = nil
|
||||||
db.beginTransactionStack = nil
|
db.beginTransactionStack = nil
|
||||||
})
|
})
|
||||||
@@ -96,7 +97,7 @@ func Commit(db *DaoDB, txDB orm.TxOrmer) (err error) {
|
|||||||
if db.transactionLevel == 1 {
|
if db.transactionLevel == 1 {
|
||||||
db.stopWatchTransaction()
|
db.stopWatchTransaction()
|
||||||
err = txDB.Commit()
|
err = txDB.Commit()
|
||||||
// err = db.Db.Commit()
|
//err = db.Db.Commit()
|
||||||
db.transactionLevel = 0
|
db.transactionLevel = 0
|
||||||
} else if db.transactionLevel > 1 {
|
} else if db.transactionLevel > 1 {
|
||||||
db.transactionLevel--
|
db.transactionLevel--
|
||||||
@@ -108,7 +109,7 @@ func Rollback(db *DaoDB, txDB orm.TxOrmer) (err error) {
|
|||||||
if db.transactionLevel > 0 {
|
if db.transactionLevel > 0 {
|
||||||
db.stopWatchTransaction()
|
db.stopWatchTransaction()
|
||||||
err = txDB.Rollback()
|
err = txDB.Rollback()
|
||||||
// err = db.Db.Rollback()
|
//err = db.Db.Rollback()
|
||||||
}
|
}
|
||||||
db.transactionLevel = 0
|
db.transactionLevel = 0
|
||||||
return err
|
return err
|
||||||
@@ -142,17 +143,22 @@ func GetRowTx(txDB orm.TxOrmer, inPtr interface{}, sql string, values ...interfa
|
|||||||
if txDB == nil {
|
if txDB == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
typeInfo := reflect.TypeOf(inPtr)
|
if !useGetRowsWhenGetRow { // beego QueryRow有bug,嵌入的struct不能正常绑定
|
||||||
if typeInfo.Kind() != reflect.Ptr {
|
err = txDB.Raw(sql, values).QueryRow(inPtr)
|
||||||
return errors.New("inPtr must be ptr")
|
//err = db.Db.Raw(sql, values).QueryRow(inPtr)
|
||||||
}
|
} else {
|
||||||
slice := reflect.New(reflect.SliceOf(typeInfo.Elem()))
|
typeInfo := reflect.TypeOf(inPtr)
|
||||||
if err = GetRowsTx(txDB, slice.Interface(), sql, values...); err == nil {
|
if typeInfo.Kind() != reflect.Ptr {
|
||||||
slice = slice.Elem()
|
return errors.New("inPtr must be ptr")
|
||||||
if slice.Len() > 0 {
|
}
|
||||||
reflect.ValueOf(inPtr).Elem().Set(slice.Index(0))
|
slice := reflect.New(reflect.SliceOf(typeInfo.Elem()))
|
||||||
} else {
|
if err = GetRowsTx(txDB, slice.Interface(), sql, values...); err == nil {
|
||||||
return orm.ErrNoRows
|
slice = slice.Elem()
|
||||||
|
if slice.Len() > 0 {
|
||||||
|
reflect.ValueOf(inPtr).Elem().Set(slice.Index(0))
|
||||||
|
} else {
|
||||||
|
return orm.ErrNoRows
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
@@ -171,7 +177,7 @@ func GetRowsTx(txDB orm.TxOrmer, inPtr interface{}, sql string, values ...interf
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, err = txDB.Raw(sql, values).QueryRows(inPtr)
|
_, err = txDB.Raw(sql, values).QueryRows(inPtr)
|
||||||
// _, err = db.Db.Raw(sql, values).QueryRows(inPtr)
|
//_, err = db.Db.Raw(sql, values).QueryRows(inPtr)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,6 +202,16 @@ func UpdateEntity(db *DaoDB, item interface{}, cols ...string) (num int64, err e
|
|||||||
return num, err
|
return num, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CreateEntity(db *DaoDB, item interface{}) (err error) {
|
||||||
|
if db == nil {
|
||||||
|
db = GetDB()
|
||||||
|
}
|
||||||
|
if _, err = db.Db.Insert(item); err != nil && !IsDuplicateError(err) {
|
||||||
|
globals.SugarLogger.Errorf("CreateEntity %s failed with error:%v", reflect.TypeOf(item).Name(), err)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func UpdateEntityTx(txDB orm.TxOrmer, item interface{}, cols ...string) (num int64, err error) {
|
func UpdateEntityTx(txDB orm.TxOrmer, item interface{}, cols ...string) (num int64, err error) {
|
||||||
if txDB == nil {
|
if txDB == nil {
|
||||||
return
|
return
|
||||||
@@ -207,16 +223,6 @@ func UpdateEntityTx(txDB orm.TxOrmer, item interface{}, cols ...string) (num int
|
|||||||
return num, err
|
return num, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateEntity(db *DaoDB, item interface{}) (err error) {
|
|
||||||
if db == nil {
|
|
||||||
db = GetDB()
|
|
||||||
}
|
|
||||||
if _, err = db.Db.Insert(item); err != nil && !IsDuplicateError(err) {
|
|
||||||
globals.SugarLogger.Errorf("CreateEntity %s failed with error:%v", reflect.TypeOf(item).Name(), err)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateEntityTx(txDB orm.TxOrmer, item interface{}) (err error) {
|
func CreateEntityTx(txDB orm.TxOrmer, item interface{}) (err error) {
|
||||||
if txDB == nil {
|
if txDB == nil {
|
||||||
return
|
return
|
||||||
@@ -257,6 +263,18 @@ func DeleteEntity(db *DaoDB, item interface{}, cols ...string) (num int64, err e
|
|||||||
return num, err
|
return num, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DeleteEntityTx(txDB orm.TxOrmer, item interface{}, cols ...string) (num int64, err error) {
|
||||||
|
if txDB == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = utils.CallFuncLogError(func() error {
|
||||||
|
num, err = txDB.Delete(item, cols...)
|
||||||
|
//num, err = db.Db.Delete(item, cols...)
|
||||||
|
return err
|
||||||
|
}, reflect.TypeOf(item).Name())
|
||||||
|
return num, err
|
||||||
|
}
|
||||||
|
|
||||||
func ExecuteSQL(db *DaoDB, sql string, params ...interface{}) (num int64, err error) {
|
func ExecuteSQL(db *DaoDB, sql string, params ...interface{}) (num int64, err error) {
|
||||||
if db == nil {
|
if db == nil {
|
||||||
db = GetDB()
|
db = GetDB()
|
||||||
@@ -274,16 +292,13 @@ func ExecuteSQL(db *DaoDB, sql string, params ...interface{}) (num int64, err er
|
|||||||
// 此函数要求db在事务中,否则可能导致取得到的是另一个连接的数据
|
// 此函数要求db在事务中,否则可能导致取得到的是另一个连接的数据
|
||||||
func GetLastTotalRowCount(db *DaoDB) int {
|
func GetLastTotalRowCount(db *DaoDB) int {
|
||||||
countInfo := &struct{ Ct int }{}
|
countInfo := &struct{ Ct int }{}
|
||||||
// if err := txDB.Raw("SELECT FOUND_ROWS() ct", nil).QueryRow(countInfo); err == nil {
|
|
||||||
// return countInfo.Ct
|
|
||||||
// }
|
|
||||||
if err := GetRow(db, countInfo, "SELECT FOUND_ROWS() ct"); err == nil {
|
if err := GetRow(db, countInfo, "SELECT FOUND_ROWS() ct"); err == nil {
|
||||||
return countInfo.Ct
|
return countInfo.Ct
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetLastTotalRowCount2(db *DaoDB, txDB orm.TxOrmer) int {
|
func GetLastTotalRowCountTx(txDB orm.TxOrmer) int {
|
||||||
countInfo := &struct{ Ct int }{}
|
countInfo := &struct{ Ct int }{}
|
||||||
if err := GetRowTx(txDB, countInfo, "SELECT FOUND_ROWS() ct"); err == nil {
|
if err := GetRowTx(txDB, countInfo, "SELECT FOUND_ROWS() ct"); err == nil {
|
||||||
return countInfo.Ct
|
return countInfo.Ct
|
||||||
@@ -22,11 +22,12 @@ func GetAuthBind(db *DaoDB, bindType int, authType, authID string) (authBind *mo
|
|||||||
authType,
|
authType,
|
||||||
authID,
|
authID,
|
||||||
}
|
}
|
||||||
|
// globals.SugarLogger.Debugf("GetAuthBind sql:%s, sqlParams:%s", sql, utils.Format4Output(sqlParams, false))
|
||||||
err = GetRow(db, &authBind, sql, sqlParams...)
|
err = GetRow(db, &authBind, sql, sqlParams...)
|
||||||
return authBind, err
|
return authBind, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetUserBindAuthInfo(db *DaoDB, userID string, bindType int, typeList []string, authID, authID2 string, typeIDs []string) (authList []*model.AuthBind, err error) {
|
func GetUserBindAuthInfo(db *DaoDB, userID string, bindType int, typeList []string, authID, authID2, typeID string) (authList []*model.AuthBind, err error) {
|
||||||
sql := `
|
sql := `
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM auth_bind t1
|
FROM auth_bind t1
|
||||||
@@ -43,7 +44,6 @@ func GetUserBindAuthInfo(db *DaoDB, userID string, bindType int, typeList []stri
|
|||||||
sql += " AND t1.bind_type = ?"
|
sql += " AND t1.bind_type = ?"
|
||||||
sqlParams = append(sqlParams, bindType)
|
sqlParams = append(sqlParams, bindType)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(typeList) > 0 {
|
if len(typeList) > 0 {
|
||||||
sql += " AND t1.type IN (" + GenQuestionMarks(len(typeList)) + ")"
|
sql += " AND t1.type IN (" + GenQuestionMarks(len(typeList)) + ")"
|
||||||
sqlParams = append(sqlParams, typeList)
|
sqlParams = append(sqlParams, typeList)
|
||||||
@@ -56,9 +56,9 @@ func GetUserBindAuthInfo(db *DaoDB, userID string, bindType int, typeList []stri
|
|||||||
sql += " AND t1.auth_id2 = ?"
|
sql += " AND t1.auth_id2 = ?"
|
||||||
sqlParams = append(sqlParams, authID2)
|
sqlParams = append(sqlParams, authID2)
|
||||||
}
|
}
|
||||||
if len(typeIDs) > 0 {
|
if typeID != "" {
|
||||||
sql += " AND t1.type_id IN (" + GenQuestionMarks(len(typeIDs)) + ")"
|
sql += " AND t1.type_id = ?"
|
||||||
sqlParams = append(sqlParams, typeIDs)
|
sqlParams = append(sqlParams, typeID)
|
||||||
}
|
}
|
||||||
sql += " ORDER BY t1.type"
|
sql += " ORDER BY t1.type"
|
||||||
err = GetRows(db, &authList, sql, sqlParams...)
|
err = GetRows(db, &authList, sql, sqlParams...)
|
||||||
@@ -54,11 +54,6 @@ func UpdateEntityByKV(db *DaoDB, item interface{}, kvs map[string]interface{}, c
|
|||||||
qs = qs.Filter(k, v)
|
qs = qs.Filter(k, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for k, v := range kvs {
|
|
||||||
if k == "jdCategoryID" && (v == "" || v == nil) {
|
|
||||||
delete(kvs, k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
num, err = qs.Update(kvs)
|
num, err = qs.Update(kvs)
|
||||||
if err != nil && !IsDuplicateError(err) {
|
if err != nil && !IsDuplicateError(err) {
|
||||||
globals.SugarLogger.Errorf("UpdateEntityByKV %s failed with error:%v", reflect.TypeOf(item).Name(), err)
|
globals.SugarLogger.Errorf("UpdateEntityByKV %s failed with error:%v", reflect.TypeOf(item).Name(), err)
|
||||||
@@ -136,6 +131,7 @@ func UpdateEntityLogicallyAndUpdateSyncStatus(db *DaoDB, item interface{}, kvs m
|
|||||||
valueRows := reflect.New(reflect.SliceOf(typeInfo))
|
valueRows := reflect.New(reflect.SliceOf(typeInfo))
|
||||||
rows := valueRows.Interface()
|
rows := valueRows.Interface()
|
||||||
if err = GetEntitiesByKV(db, rows, conditions, false); err == nil {
|
if err = GetEntitiesByKV(db, rows, conditions, false); err == nil {
|
||||||
|
// globals.SugarLogger.Debug(utils.Format4Output(rows, false))
|
||||||
valueRows = reflect.Indirect(valueRows)
|
valueRows = reflect.Indirect(valueRows)
|
||||||
for i := 0; i < valueRows.Len(); i++ {
|
for i := 0; i < valueRows.Len(); i++ {
|
||||||
value := reflect.Indirect(valueRows.Index(i))
|
value := reflect.Indirect(valueRows.Index(i))
|
||||||
91
business/dao/dao_print.go
Normal file
91
business/dao/dao_print.go
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
package dao
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
|
)
|
||||||
|
|
||||||
|
// QueryUserPrinter 查询用户打印机
|
||||||
|
func QueryUserPrinter(userId, printNo string) (*model.Printer, error) {
|
||||||
|
sql := `
|
||||||
|
SELECT *
|
||||||
|
FROM printer
|
||||||
|
WHERE 1 = 1 AND deleted_at = ?
|
||||||
|
`
|
||||||
|
sqlParams := []interface{}{
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
}
|
||||||
|
|
||||||
|
if printNo != "" {
|
||||||
|
sql += " AND print_no = ?"
|
||||||
|
sqlParams = append(sqlParams, printNo)
|
||||||
|
}
|
||||||
|
if userId != "" {
|
||||||
|
sql += " AND user_id = ?"
|
||||||
|
sqlParams = append(sqlParams, userId)
|
||||||
|
}
|
||||||
|
var printer = &model.Printer{}
|
||||||
|
err := GetRow(GetDB(), &printer, sql, sqlParams)
|
||||||
|
return printer, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPrinters(db *DaoDB, appID int, printNo string, status, statusNeq int) (printers []*model.Printer, err error) {
|
||||||
|
sql := `
|
||||||
|
SELECT *
|
||||||
|
FROM printer
|
||||||
|
WHERE 1 = 1 AND deleted_at = ?
|
||||||
|
`
|
||||||
|
sqlParams := []interface{}{
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
}
|
||||||
|
if appID != 0 {
|
||||||
|
sql += " AND app_id = ?"
|
||||||
|
sqlParams = append(sqlParams, appID)
|
||||||
|
}
|
||||||
|
if printNo != "" {
|
||||||
|
sql += " AND print_no = ?"
|
||||||
|
sqlParams = append(sqlParams, printNo)
|
||||||
|
}
|
||||||
|
if status != 0 {
|
||||||
|
sql += " AND status = ?"
|
||||||
|
sqlParams = append(sqlParams, status)
|
||||||
|
}
|
||||||
|
if statusNeq != 0 {
|
||||||
|
sql += " AND status <> ?"
|
||||||
|
sqlParams = append(sqlParams, statusNeq)
|
||||||
|
}
|
||||||
|
err = GetRows(db, &printers, sql, sqlParams)
|
||||||
|
|
||||||
|
globals.SugarLogger.Debugf("======printers==== %s", utils.Format4Output(printers, false))
|
||||||
|
return printers, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPrintMsgs(db *DaoDB, printNo, msgID string, status, statusNeq int) (printMsgs []*model.PrintMsg, err error) {
|
||||||
|
sql := `
|
||||||
|
SELECT *
|
||||||
|
FROM print_msg
|
||||||
|
WHERE 1 = 1 AND deleted_at = ?
|
||||||
|
`
|
||||||
|
sqlParams := []interface{}{
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
}
|
||||||
|
if status != model.PrintMsgAll {
|
||||||
|
sql += " AND status = ?"
|
||||||
|
sqlParams = append(sqlParams, status)
|
||||||
|
}
|
||||||
|
if statusNeq != model.PrintMsgAll {
|
||||||
|
sql += " AND status <> ?"
|
||||||
|
sqlParams = append(sqlParams, statusNeq)
|
||||||
|
}
|
||||||
|
if printNo != "" {
|
||||||
|
sql += " AND print_no = ?"
|
||||||
|
sqlParams = append(sqlParams, printNo)
|
||||||
|
}
|
||||||
|
if msgID != "" {
|
||||||
|
sql += " AND msg_id = ?"
|
||||||
|
sqlParams = append(sqlParams, msgID)
|
||||||
|
}
|
||||||
|
err = GetRows(db, &printMsgs, sql, sqlParams)
|
||||||
|
return printMsgs, err
|
||||||
|
}
|
||||||
25
business/dao/dao_print_setting.go
Normal file
25
business/dao/dao_print_setting.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package dao
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetPrintSetting(printNo string) (*model.PrintSettingObj, error) {
|
||||||
|
sql := ` SELECT * FROM print_setting WHERE print_no = ? and deleted_at = ? `
|
||||||
|
sqlParams := []interface{}{
|
||||||
|
printNo,
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
}
|
||||||
|
|
||||||
|
var printSetting *model.PrintSetting
|
||||||
|
if err := GetRow(GetDB(), &printSetting, sql, sqlParams...); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if printSetting == nil {
|
||||||
|
return nil, errors.New("数据查询异常")
|
||||||
|
}
|
||||||
|
|
||||||
|
return model.UnMarshalString2Json(printSetting)
|
||||||
|
}
|
||||||
34
business/dao/dao_print_temp.go
Normal file
34
business/dao/dao_print_temp.go
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package dao
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SelectUserDefaultTemp 查询用户默认模板
|
||||||
|
func SelectUserDefaultTemp(userId string, tempType string) (*model.SystemTemp, bool, error) {
|
||||||
|
var result *model.SystemTemp
|
||||||
|
if err := GetRow(GetDB(), &result, `SELECT * FROM system_temp WHERE user_id = ? AND temp_type = ? AND is_use = ? AND deleted_at = ? ORDER BY created_at desc `, []interface{}{userId, tempType, 1, utils.DefaultTimeValue}...); err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
return result, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// QuerySystemTemp 查询系统模板
|
||||||
|
func QuerySystemTemp() (*model.SystemTemp, error) {
|
||||||
|
var result []*model.SystemTemp
|
||||||
|
if err := GetRows(GetDB(), &result, `SELECT * FROM system_temp WHERE user_id = ? AND temp_type = ? AND is_use = ? AND deleted_at = ? ORDER BY created_at desc `, []interface{}{"system_user", "user_store", 1, utils.DefaultTimeValue}...); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(result) > 0 {
|
||||||
|
return result[0], nil
|
||||||
|
}
|
||||||
|
return nil, errors.New("模板获取异常")
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddTemp 添加模板数据
|
||||||
|
func AddTemp(param *model.SystemTemp) error {
|
||||||
|
return CreateEntity(GetDB(), param)
|
||||||
|
}
|
||||||
19
business/dao/dao_user_test.go
Normal file
19
business/dao/dao_user_test.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package dao
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetUsers(t *testing.T) {
|
||||||
|
aa := "{\"title\":\"<center><b>京西菜市</b></center><br><center>手机买菜上京西</center><br><center>极速到家送惊喜</center><br>--------------------------------<br>\",\"divider\":\"--------------------------------<br>\",\"payOrderTime\":\"<left>下单时间:%s</left>\",\"trySendTime\":\"<left>预计送达时间:%s</left>\",\"consigneeName\":\"<left>客户名称:%s</left>\",\"consigneeMobile\":\"<left>客户电话:%s</left>\",\"consigneeAddress\":\"<left>客户地址:%s</left>\",\"buyerComment\":\"<left>客户备注:%s</left>\",\"qrcOrder\":\"<qrl>%s</qrl>\",\"goodsListDetail\":\"商品列表:<br>品名 数量 单价 小计<br>--------------------------------<br>\",\"skuName\":\"<b>%s</b><br>\",\"skuNumber\":\"<b>x%s</b>\",\"skuPrice\":\"<b>¥%s</b>\",\"skuAllPrice\":\"<b>¥%s</b>\",\"skuUpc\":\"upc码: %s<br>\",\"allSkuTypeCount\":\"<br><br><b>共 %s 种\",\"allSkuCount\":\" %s 件商品</b><br>\",\"storeName\":\"<center><b>商品质量问题请联系:</b></center><br><center><b>%s:\",\"storeTel\":\"%s</b></center><br><br>更多信息请关注官方微信:\",\"officialName\":\"<b>%s</b><br><br><br>--------------------------------<br>--------------------------------<br><br>\"}"
|
||||||
|
|
||||||
|
conte := make(map[string]string, 0)
|
||||||
|
|
||||||
|
if err := json.Unmarshal([]byte(aa), &conte); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Log(utils.Format4Output(conte, false))
|
||||||
|
}
|
||||||
@@ -111,7 +111,7 @@ func GetOperateEvents(db *DaoDB, name string, apiFunctions []string, operateType
|
|||||||
txDB, _ := Begin(db)
|
txDB, _ := Begin(db)
|
||||||
defer Commit(db, txDB)
|
defer Commit(db, txDB)
|
||||||
if err = GetRowsTx(txDB, &operateEventExt, sql, sqlParams...); err == nil {
|
if err = GetRowsTx(txDB, &operateEventExt, sql, sqlParams...); err == nil {
|
||||||
totalCount = GetLastTotalRowCount2(db, txDB)
|
totalCount = GetLastTotalRowCountTx(txDB)
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
accessUUidList []string
|
accessUUidList []string
|
||||||
@@ -142,31 +142,131 @@ func GetOperateEvents(db *DaoDB, name string, apiFunctions []string, operateType
|
|||||||
return operateEventExt, totalCount, err
|
return operateEventExt, totalCount, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetImMessageRecord(db *DaoDB, vendorOrderID, userID string, storeID, vendorID int) (msg []*model.ImMessageRecord, err error) {
|
type GetMessageGroupsResult struct {
|
||||||
|
model.MessageGroup
|
||||||
|
Avatar string `json:"avatar"`
|
||||||
|
LastMessageType int `json:"lastMessageType"`
|
||||||
|
LastContent string `json:"lastContent"`
|
||||||
|
LastTime time.Time `json:"lastTime"`
|
||||||
|
LastUserName string `json:"lastUserName"`
|
||||||
|
UserName string `json:"userName"`
|
||||||
|
UnReadMessageCount int `json:"unReadMessageCount"`
|
||||||
|
MessageGroupMembers []*GetMessageGroupsMemberResult `json:"messageGroupMembers"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetMessageGroupsMemberResult struct {
|
||||||
|
model.User
|
||||||
|
model.MessageGroupMember
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMessageGroups(db *DaoDB, userID string, groupID, groupType int, isMember bool, userID2 string) (messageGroupsResult []*GetMessageGroupsResult, err error) {
|
||||||
sql := `
|
sql := `
|
||||||
SELECT *
|
SELECT a.*, b.name user_name, b.avatar
|
||||||
FROM im_message_record
|
FROM message_group a
|
||||||
WHERE deleted_at = ?
|
LEFT JOIN user b ON b.user_id = a.user_id
|
||||||
|
WHERE a.deleted_at = ?
|
||||||
`
|
`
|
||||||
sqlParams := []interface{}{
|
sqlParams := []interface{}{utils.DefaultTimeValue}
|
||||||
utils.DefaultTimeValue,
|
|
||||||
}
|
|
||||||
if vendorOrderID != "" {
|
|
||||||
sql += " AND vendor_order_id = ?"
|
|
||||||
sqlParams = append(sqlParams, vendorOrderID)
|
|
||||||
}
|
|
||||||
if userID != "" {
|
if userID != "" {
|
||||||
sql += " AND user_id = ?"
|
sql += " AND a.user_id = ?"
|
||||||
sqlParams = append(sqlParams, userID)
|
sqlParams = append(sqlParams, userID)
|
||||||
}
|
}
|
||||||
if storeID != 0 {
|
if groupType != 0 {
|
||||||
sql += " AND store_id = ?"
|
sql += " AND a.type = ?"
|
||||||
sqlParams = append(sqlParams, storeID)
|
sqlParams = append(sqlParams, groupType)
|
||||||
}
|
}
|
||||||
if vendorID >= 0 {
|
if groupID != 0 {
|
||||||
sql += " AND vendor_id = ?"
|
sql += " AND a.group_id LIKE ?"
|
||||||
sqlParams = append(sqlParams, vendorID)
|
sqlParams = append(sqlParams, utils.Int2Str(groupID)+"%")
|
||||||
}
|
}
|
||||||
err = GetRows(db, &msg, sql, sqlParams)
|
if err = GetRows(db, &messageGroupsResult, sql, sqlParams); err == nil {
|
||||||
return msg, err
|
if isMember {
|
||||||
|
for _, v := range messageGroupsResult {
|
||||||
|
var messageGroupMembers []*GetMessageGroupsMemberResult
|
||||||
|
sql2 := `
|
||||||
|
SELECT a.*, b.*
|
||||||
|
FROM message_group_member a
|
||||||
|
LEFT JOIN user b ON b.user_id = a.member_user_id
|
||||||
|
WHERE a.group_id = ?
|
||||||
|
AND a.deleted_at = ?
|
||||||
|
`
|
||||||
|
sqlParams2 := []interface{}{v.GroupID, utils.DefaultTimeValue}
|
||||||
|
if userID2 != "" {
|
||||||
|
sql2 += ` AND member_user_id = ?`
|
||||||
|
sqlParams2 = append(sqlParams2, userID2)
|
||||||
|
}
|
||||||
|
if err = GetRows(db, &messageGroupMembers, sql2, sqlParams2); err == nil {
|
||||||
|
v.MessageGroupMembers = messageGroupMembers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return messageGroupsResult, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMessageGroupMembers(db *DaoDB, groupID, groupType int, memberUserID string) (messageGroupMembers []*model.MessageGroupMember, err error) {
|
||||||
|
sqlParams := []interface{}{}
|
||||||
|
sql := `
|
||||||
|
SELECT a.*
|
||||||
|
FROM message_group_member a
|
||||||
|
`
|
||||||
|
if groupType != 0 {
|
||||||
|
sql += ` JOIN message_group b ON b.group_id = a.group_id AND b.type = ? AND b.deleted_at = ?`
|
||||||
|
sqlParams = append(sqlParams, groupType, utils.DefaultTimeValue)
|
||||||
|
}
|
||||||
|
sql += `
|
||||||
|
WHERE a.deleted_at = ?
|
||||||
|
`
|
||||||
|
sqlParams = append(sqlParams, utils.DefaultTimeValue)
|
||||||
|
if groupID != 0 {
|
||||||
|
sql += " AND a.group_id = ?"
|
||||||
|
sqlParams = append(sqlParams, groupID)
|
||||||
|
}
|
||||||
|
if memberUserID != "" {
|
||||||
|
sql += " AND a.member_user_id = ?"
|
||||||
|
sqlParams = append(sqlParams, memberUserID)
|
||||||
|
}
|
||||||
|
err = GetRows(db, &messageGroupMembers, sql, sqlParams)
|
||||||
|
return messageGroupMembers, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//得到某个用户所在所有群组
|
||||||
|
func GetUserMessageGroups(db *DaoDB, userID string) (messageGroup []*model.MessageGroup, err error) {
|
||||||
|
sql := `
|
||||||
|
SELECT group_id
|
||||||
|
FROM message_group
|
||||||
|
WHERE deleted_at = ? AND user_id = ?
|
||||||
|
UNION
|
||||||
|
SELECT group_id
|
||||||
|
FROM message_group_member
|
||||||
|
WHERE deleted_at = ? AND member_user_id = ?
|
||||||
|
`
|
||||||
|
sqlParams := []interface{}{
|
||||||
|
utils.DefaultTimeValue, userID,
|
||||||
|
utils.DefaultTimeValue, userID,
|
||||||
|
}
|
||||||
|
err = GetRows(db, &messageGroup, sql, sqlParams)
|
||||||
|
messageGroup = append(messageGroup, &model.MessageGroup{
|
||||||
|
GroupID: model.SysGroupID,
|
||||||
|
})
|
||||||
|
return messageGroup, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMessageGroupRead(db *DaoDB, userID string, groupID int) (messageGroupReads []*model.MessageGroupRead, err error) {
|
||||||
|
sql := `
|
||||||
|
SELECT *
|
||||||
|
FROM message_group_read a
|
||||||
|
WHERE 1 = 1
|
||||||
|
`
|
||||||
|
sqlParams := []interface{}{}
|
||||||
|
if userID != "" {
|
||||||
|
sql += ` AND a.user_id = ?`
|
||||||
|
sqlParams = append(sqlParams, userID)
|
||||||
|
}
|
||||||
|
if groupID != 0 {
|
||||||
|
sql += ` AND a.group_id = ?`
|
||||||
|
sqlParams = append(sqlParams, groupID)
|
||||||
|
}
|
||||||
|
err = GetRows(db, &messageGroupReads, sql, sqlParams...)
|
||||||
|
return messageGroupReads, err
|
||||||
}
|
}
|
||||||
@@ -2,8 +2,8 @@ package dao
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils/errlist"
|
"git.rosy.net.cn/baseapi/utils/errlist"
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
@@ -34,7 +34,6 @@ func QueryConfigs(db *DaoDB, key, configType, keyword string) (configList []*mod
|
|||||||
|
|
||||||
err = GetRows(db, &configList, sql, sqlParams...)
|
err = GetRows(db, &configList, sql, sqlParams...)
|
||||||
if err == nil && len(configList) == 0 && key != "" {
|
if err == nil && len(configList) == 0 && key != "" {
|
||||||
fmt.Println("条件:key:,type:,keyword:不能找到配置", key, configType, keyword)
|
|
||||||
err = fmt.Errorf("条件:key:%s,type:%s,keyword:%s不能找到配置", key, configType, keyword)
|
err = fmt.Errorf("条件:key:%s,type:%s,keyword:%s不能找到配置", key, configType, keyword)
|
||||||
}
|
}
|
||||||
return configList, err
|
return configList, err
|
||||||
@@ -60,10 +59,3 @@ func GetSysConfigAsInt64(db *DaoDB, key string) (value int64, err error) {
|
|||||||
}
|
}
|
||||||
return value, err
|
return value, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 修改配置
|
|
||||||
func UpdateOperatorConfig(param string, types, key string) error {
|
|
||||||
sql := `UPDATE new_config c SET c.value = ?,c.updated_at = ? WHERE c.type = ? AND c.key = ?`
|
|
||||||
_, err := ExecuteSQL(GetDB(), sql, []interface{}{param, time.Now(), types, key})
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
65
business/dao/place.go
Normal file
65
business/dao/place.go
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
package dao
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
"github.com/astaxie/beego/client/orm"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
EnableCondAll = 0
|
||||||
|
EnableCondEnalbed = 1
|
||||||
|
EnableCondDisabled = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetPlaceByCode(db *DaoDB, code int) (place *model.Place, err error) {
|
||||||
|
if db == nil {
|
||||||
|
db = GetDB()
|
||||||
|
}
|
||||||
|
place = &model.Place{
|
||||||
|
Code: code,
|
||||||
|
}
|
||||||
|
err = GetEntity(db, place, "Code")
|
||||||
|
return place, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPlacesByCond(db *DaoDB, enableCond int) (placeList []*model.Place, err error) {
|
||||||
|
if db == nil {
|
||||||
|
db = GetDB()
|
||||||
|
}
|
||||||
|
sql := `
|
||||||
|
SELECT *
|
||||||
|
FROM place
|
||||||
|
WHERE level = 2
|
||||||
|
`
|
||||||
|
if enableCond == EnableCondEnalbed {
|
||||||
|
sql += " AND enabled = 1"
|
||||||
|
} else if enableCond == EnableCondDisabled {
|
||||||
|
sql += " AND enabled = 0"
|
||||||
|
}
|
||||||
|
sql += " ORDER BY code"
|
||||||
|
err = GetRows(db, &placeList, sql)
|
||||||
|
return placeList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPlaceByName(db *DaoDB, name string, level int, parentCode int) (place *model.Place, err error) {
|
||||||
|
if db == nil {
|
||||||
|
db = GetDB()
|
||||||
|
}
|
||||||
|
cols := []string{
|
||||||
|
"Name",
|
||||||
|
"Level",
|
||||||
|
}
|
||||||
|
place = &model.Place{
|
||||||
|
Name: name,
|
||||||
|
Level: int8(level),
|
||||||
|
}
|
||||||
|
if parentCode != 0 {
|
||||||
|
cols = append(cols, "ParentCode")
|
||||||
|
place.ParentCode = parentCode
|
||||||
|
|
||||||
|
}
|
||||||
|
if err = GetEntity(db, place, cols...); err == orm.ErrNoRows {
|
||||||
|
err = db.Db.Raw("SELECT * FROM place WHERE parent_code = ? AND level = ? AND name LIKE ?", parentCode, level, "%"+name+"%").QueryRow(place)
|
||||||
|
}
|
||||||
|
return place, err
|
||||||
|
}
|
||||||
19
business/dao/print_activation.go
Normal file
19
business/dao/print_activation.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package dao
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CheckHeard(printNo string) (bool, error) {
|
||||||
|
var data *model.PrintActivation
|
||||||
|
err := GetRow(GetDB(), &data, `SELECT * FROM print_activation WHERE print_no = ?`, []interface{}{printNo}...)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if data == nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
42
business/dao/print_bind_store.go
Normal file
42
business/dao/print_bind_store.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package dao
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// QueryPrintBindStore 查询绑定门店
|
||||||
|
func QueryPrintBindStore(printNo string) ([]*model.PrintBindStore, error) {
|
||||||
|
var data []*model.PrintBindStore
|
||||||
|
if err := GetRows(GetDB(), &data, `SELECT * FROM print_bind_store WHERE print_no = ?`, []interface{}{printNo}...); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// BindStoreList 绑定门店信息
|
||||||
|
func BindStoreList(req *model.AddPrinterParam, userId string) error {
|
||||||
|
param := &model.PrintBindStore{
|
||||||
|
CreatedAt: time.Now(),
|
||||||
|
UpdatedAt: time.Now(),
|
||||||
|
StoreID: req.StoreId,
|
||||||
|
StoreName: req.Name,
|
||||||
|
StoreVendor: 9, // 绑定平台,全平台
|
||||||
|
PrintNo: req.PrintNo,
|
||||||
|
StoreStatus: 1, // 门店开启
|
||||||
|
BindStatus: 1, // 绑定状态
|
||||||
|
}
|
||||||
|
if userId != "" {
|
||||||
|
param.UserId = userId
|
||||||
|
} else {
|
||||||
|
param.UserId = "system"
|
||||||
|
}
|
||||||
|
return CreateEntity(GetDB(), param)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteStoreList 删除绑定门店
|
||||||
|
func DeleteStoreList(printNo string, storeId string) error {
|
||||||
|
sql := ` DELETE FROM print_bind_store WHERE print_no = ? AND store_id = ? `
|
||||||
|
_, err := ExecuteSQL(GetDB(), sql, []interface{}{printNo, storeId}...)
|
||||||
|
return err
|
||||||
|
}
|
||||||
539
business/dao/print_temp_utils.go
Normal file
539
business/dao/print_temp_utils.go
Normal file
@@ -0,0 +1,539 @@
|
|||||||
|
package dao
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
"git.rosy.net.cn/jx-print/globals"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var SystemTempObj map[string]*model.SystemTemp
|
||||||
|
|
||||||
|
func Init() {
|
||||||
|
SystemTempObj = make(map[string]*model.SystemTemp, 0)
|
||||||
|
sysTempList, err := QuerySystemTemp()
|
||||||
|
if err != nil {
|
||||||
|
globals.SugarLogger.Debug("query system temp err :", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
SystemTempObj[sysTempList.TempSize] = sysTempList
|
||||||
|
|
||||||
|
//now := time.Now()
|
||||||
|
//param := &model.SystemTemp{
|
||||||
|
// CreatedAt: &now,
|
||||||
|
// UpdatedAt: &now,
|
||||||
|
// LastOperator: "system",
|
||||||
|
// DeletedAt: &utils.DefaultTimeValue,
|
||||||
|
// TempName: "",
|
||||||
|
// TempRank: model.SystemTempKey,
|
||||||
|
// Temp: "",
|
||||||
|
// UserId: "system_user",
|
||||||
|
// TempType: model.TempTypeMerchant,
|
||||||
|
// TempSize: model.SystemTempSizeBig,
|
||||||
|
// PrintSn: "system",
|
||||||
|
// IsUse: 1,
|
||||||
|
//}
|
||||||
|
|
||||||
|
// 初始化大字体模板
|
||||||
|
//if _, v := temp[model.SystemTempSizeBig]; !v {
|
||||||
|
// param.TempName = "system" + model.SystemTempSizeBig
|
||||||
|
// param.Temp = model.SystemTempValue
|
||||||
|
// if err := AddTemp(param); err != nil {
|
||||||
|
// globals.SugarLogger.Debug("init system temp err :", err)
|
||||||
|
// }
|
||||||
|
// SystemTempObj[model.SystemTempSizeBig] = param
|
||||||
|
//}
|
||||||
|
|
||||||
|
// 初始化中字体模板
|
||||||
|
//if _, v := temp[model.SystemTempSizeMedium]; !v {
|
||||||
|
// param.TempName = "system" + model.SystemTempSizeMedium
|
||||||
|
// medium := strings.Replace(model.SystemTempValue, "<b>", "<hb>", -1)
|
||||||
|
// medium2 := strings.Replace(medium, "</b>", "</hb>", -1)
|
||||||
|
// param.Temp = medium2
|
||||||
|
// param.TempSize = model.SystemTempSizeMedium
|
||||||
|
// param.IsUse = 2
|
||||||
|
// if err := AddTemp(param); err != nil {
|
||||||
|
// globals.SugarLogger.Debug("init system temp err :", err)
|
||||||
|
// }
|
||||||
|
// SystemTempObj[model.SystemTempSizeMedium] = param
|
||||||
|
//}
|
||||||
|
|
||||||
|
// 初始化小字体模板
|
||||||
|
//if _, v := temp[model.SystemTempSizeSmall]; !v {
|
||||||
|
// param.TempName = "system" + model.SystemTempSizeSmall
|
||||||
|
// medium := strings.Replace(model.SystemTempValue, "<b>", " ", -1)
|
||||||
|
// medium2 := strings.Replace(medium, "</b>", " ", -1)
|
||||||
|
// param.Temp = medium2
|
||||||
|
// param.TempSize = model.SystemTempSizeSmall
|
||||||
|
// param.IsUse = 2
|
||||||
|
// if err := AddTemp(param); err != nil {
|
||||||
|
// globals.SugarLogger.Debug("init system temp err :", err)
|
||||||
|
// }
|
||||||
|
// SystemTempObj[model.SystemTempSizeSmall] = param
|
||||||
|
//}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakePrintMsgOnTemp 将打印数据渲染到模板当中
|
||||||
|
func MakePrintMsgOnTemp(param map[string]string, userId string) (string, error) {
|
||||||
|
// 查询用户默认模板,不存在则使用系统默认模板
|
||||||
|
userTemp := &model.SystemTemp{}
|
||||||
|
userTemp, isHave, err := SelectUserDefaultTemp(userId, model.TempTypeMerchantUser)
|
||||||
|
if err != nil || !isHave {
|
||||||
|
userTemp, err = QuerySystemTemp()
|
||||||
|
}
|
||||||
|
if userTemp == nil || !isHave || err != nil {
|
||||||
|
if userTemp.TempType != "" {
|
||||||
|
userTemp = SystemTempObj[userTemp.TempSize]
|
||||||
|
} else {
|
||||||
|
userTemp = SystemTempObj[model.SystemTempSizeBig]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 需要打印数据
|
||||||
|
printMsg := ""
|
||||||
|
printValue := make([]interface{}, 0, 0)
|
||||||
|
userTempMap := make(map[string]string, 0)
|
||||||
|
if err := json.Unmarshal([]byte(userTemp.Temp), &userTempMap); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range strings.Split(userTemp.TempRank, ",") {
|
||||||
|
switch v {
|
||||||
|
case "skuName", "skuNumber", "skuPrice", "skuAllPrice", "allSkuTypeCount", "allSkuCount", "skuUpc", "userPayMoney":
|
||||||
|
continue
|
||||||
|
case "goodsListDetail":
|
||||||
|
printMsg += userTempMap[v]
|
||||||
|
skuList := make([]*model.SkuListPrintOrder, 0, 0)
|
||||||
|
if err := json.Unmarshal([]byte(param["skuList"]), &skuList); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
for i := 0; i < len(skuList); i++ {
|
||||||
|
printMsg += userTempMap["skuName"]
|
||||||
|
printMsg += userTempMap["skuNumber"]
|
||||||
|
printMsg += userTempMap["skuPrice"]
|
||||||
|
printMsg += userTempMap["skuAllPrice"]
|
||||||
|
printValue = append(printValue, skuList[i].SkuName, skuList[i].SkuCount, skuList[i].SalePrice, skuList[i].TotalCountPrice)
|
||||||
|
if skuList[i].Upc != "" {
|
||||||
|
printMsg += userTempMap["skuUpc"]
|
||||||
|
printValue = append(printValue, skuList[i].Upc)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
printMsg += userTempMap["allSkuTypeCount"]
|
||||||
|
printValue = append(printValue, param["allSkuTypeCount"])
|
||||||
|
printMsg += userTempMap["allSkuCount"]
|
||||||
|
printValue = append(printValue, param["allSkuCount"])
|
||||||
|
printMsg += userTempMap["userPayMoney"]
|
||||||
|
printValue = append(printValue, param["userPayMoney"])
|
||||||
|
case "businessType":
|
||||||
|
if param[v] == "2" { // 是预订单
|
||||||
|
printMsg += userTempMap[v]
|
||||||
|
printValue = append(printValue, param[v])
|
||||||
|
}
|
||||||
|
case "divider":
|
||||||
|
printMsg += userTempMap[v]
|
||||||
|
case "title":
|
||||||
|
printMsg += userTempMap[v]
|
||||||
|
case "qrcOrder": // 老版打印机展示不要
|
||||||
|
//printMsg += userTempMap[v]
|
||||||
|
//printValue = append(printValue, param[v])
|
||||||
|
printMsg += `<b>%s #%s</b>`
|
||||||
|
printValue = append(printValue, param["vendorName"], param["vendorOrderNo"])
|
||||||
|
default:
|
||||||
|
printMsg += userTempMap[v]
|
||||||
|
printValue = append(printValue, param[v])
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return strings.Replace(fmt.Sprintf(strings.Replace(printMsg, "\n", "", -1), printValue...), "\\n", "\r\n", -1), nil
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakePrintMsgOnTempVoice 制作平台语音
|
||||||
|
func MakePrintMsgOnTempVoice(param map[string]string, setting *model.PrintSettingObj, userId string) (string, error) {
|
||||||
|
// 打订单
|
||||||
|
if param[model.OrderStatusPrint] != "" {
|
||||||
|
// 订单提示设置
|
||||||
|
printMsg, err := PrinterOrderVoice(param, setting, userId)
|
||||||
|
if err != nil {
|
||||||
|
globals.SugarLogger.Debug("err Unmarshal userTemp.printMsg", err)
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return printMsg, nil
|
||||||
|
}
|
||||||
|
// 打运单
|
||||||
|
if param[model.WayBillStatusPrint] != "" {
|
||||||
|
switch param[model.WayBillStatusPrint] {
|
||||||
|
case utils.Int2Str(model.WaybillStatusCourierAssigned): // 分配骑手
|
||||||
|
return PrintWayBillOrderStatus(param, setting), nil
|
||||||
|
case utils.Int2Str(model.WaybillStatusDeliverReminder): // 催单
|
||||||
|
printVoiceMsg := ``
|
||||||
|
printVoiceValue := make([]interface{}, 0, 0)
|
||||||
|
//printVoiceMsg, printVoiceValue = SyntheticSpeech(printVoiceMsg, printVoiceValue, param)
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, model.ReminderOrderVoice)
|
||||||
|
return strings.Replace(fmt.Sprintf(strings.Replace(printVoiceMsg, "\n", "", -1), printVoiceValue...), "\\n", "\r\n", -1), nil
|
||||||
|
case utils.Int2Str(model.WaybillStatusDelivered): // 送达
|
||||||
|
printVoiceMsg := ``
|
||||||
|
printVoiceValue := make([]interface{}, 0, 0)
|
||||||
|
//printVoiceMsg, printVoiceValue = SyntheticSpeech(printVoiceMsg, printVoiceValue, param)
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, model.FinialsOrderVoice)
|
||||||
|
return strings.Replace(fmt.Sprintf(strings.Replace(printVoiceMsg, "\n", "", -1), printVoiceValue...), "\\n", "\r\n", -1), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 门店状态
|
||||||
|
if param[model.StoreStatusPrint] != "" {
|
||||||
|
return PrintStoreStatus(param, setting), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 进店咨询
|
||||||
|
if param[model.EnterTheStorePrint] != "" && setting.VoiceSetting.ConsultingPrint == model.SettingOpen {
|
||||||
|
return `<sound>19</sound>`, nil
|
||||||
|
}
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrinterOrderVoice 打印机订单提示设置
|
||||||
|
func PrinterOrderVoice(param map[string]string, setting *model.PrintSettingObj, userId string) (string, error) {
|
||||||
|
var (
|
||||||
|
printVoiceMsg string //语音信息
|
||||||
|
printVoiceValue = make([]interface{}, 0, 0)
|
||||||
|
textMsg string // 文本信息
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
// 订单状态
|
||||||
|
switch param[model.OrderStatusPrint] {
|
||||||
|
// 新订单(待接单)
|
||||||
|
case utils.Int2Str(model.OrderStatusNew): // utils.Int2Str(model.OrderStatusFinishedPickup), utils.Int2Str(model.OrderStatusAccepted)
|
||||||
|
//if param[model.OrderStatusPrint] != utils.Int2Str(model.OrderStatusNew) && param[model.VendorIDPrint] == utils.Int64ToStr(model.VendorIDMTWM) {
|
||||||
|
// return "", err
|
||||||
|
//}
|
||||||
|
//if param[model.OrderStatusPrint] == utils.Int2Str(model.OrderStatusFinishedPickup) && param[model.VendorIDPrint] == utils.Int64ToStr(model.VendorIDEBAI) {
|
||||||
|
// return "", err
|
||||||
|
//}
|
||||||
|
// 称谓设置/平台语音设置
|
||||||
|
if setting.CallNameSetting == 64 || setting.CallNameSetting == 65 || setting.CallNameSetting == 66 {
|
||||||
|
// 老板
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, setting.CallNameSetting)
|
||||||
|
}
|
||||||
|
// 订单设置
|
||||||
|
if setting.PrintSetting.WaitOrderPrint == model.SettingOpen { // 打印订单
|
||||||
|
textMsg, err = MakePrintMsgOnTemp(param, userId)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if setting.VoiceSetting.WaitOrderVoice == model.SettingOpen { // 订单通知
|
||||||
|
printVoiceMsg += `<sound>%d</sound>` // 你来新订单了
|
||||||
|
printVoiceValue = append(printVoiceValue, model.NewOrderVoice)
|
||||||
|
}
|
||||||
|
// 申请取消
|
||||||
|
case utils.Int2Str(model.ApplyOrderCancel):
|
||||||
|
// 称谓设置/平台语音设置
|
||||||
|
if setting.CallNameSetting == 64 || setting.CallNameSetting == 65 || setting.CallNameSetting == 66 {
|
||||||
|
// 老板
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, setting.CallNameSetting)
|
||||||
|
}
|
||||||
|
// 订单设置
|
||||||
|
if setting.PrintSetting.ApplyUserCancelOrder == model.SettingOpen { // 申请取消打印
|
||||||
|
rejection := ``
|
||||||
|
rejectionValue := make([]interface{}, 0, 0)
|
||||||
|
rejection += `<center><b>客户申请取消订单:</b></center><br>`
|
||||||
|
rejection += `<center><b>订单号: %s</b></center><br>`
|
||||||
|
rejection += `<center><b>订单来源: %s # %s</b></center><br>`
|
||||||
|
rejection += `<center><b>取消时间: %s</b></center><br>`
|
||||||
|
rejectionValue = append(rejectionValue, param[model.OrderNoPrint], param[model.VendorNamePrint], param[model.VendorOrderNoPrint], utils.Time2DateStr(time.Now()))
|
||||||
|
textMsg = strings.Replace(fmt.Sprintf(strings.Replace(rejection, "\n", "", -1), rejectionValue...), "\\n", "\r\n", -1)
|
||||||
|
}
|
||||||
|
if setting.VoiceSetting.ApplyUserOrderCancelVoice == model.SettingOpen { // 申请取消语音
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, model.ApplyCancelVoice)
|
||||||
|
//printVoiceMsg, printVoiceValue = SyntheticSpeech(printVoiceMsg, printVoiceValue, param)
|
||||||
|
}
|
||||||
|
// 申请退货
|
||||||
|
case utils.Int2Str(model.ApplyOrderRefundGoods):
|
||||||
|
// 称谓设置/平台语音设置
|
||||||
|
if setting.CallNameSetting == 64 || setting.CallNameSetting == 65 || setting.CallNameSetting == 66 {
|
||||||
|
// 老板
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, setting.CallNameSetting)
|
||||||
|
}
|
||||||
|
rejection := ``
|
||||||
|
rejectionValue := make([]interface{}, 0, 0)
|
||||||
|
rejection += `<center><b>客户申请退货:</b></center><br>`
|
||||||
|
rejection += `<center><b>订单号: %s</b></center><br>`
|
||||||
|
rejection += `<center><b>订单来源: %s # %s</b></center><br>`
|
||||||
|
rejection += `<center><b>原因: %s</b></center><br>`
|
||||||
|
rejectionValue = append(rejectionValue, param[model.OrderNoPrint], param[model.VendorNamePrint], param[model.VendorOrderNoPrint], param[model.RejectionReasonPrint])
|
||||||
|
textMsg = strings.Replace(fmt.Sprintf(strings.Replace(rejection, "\n", "", -1), rejectionValue...), "\\n", "\r\n", -1)
|
||||||
|
|
||||||
|
if setting.VoiceSetting.ApplyRefundGoodsVoice == model.SettingOpen { // 申请退货语音
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, model.ApplyReturnGoodsVoice)
|
||||||
|
// printVoiceMsg, printVoiceValue = SyntheticSpeech(printVoiceMsg, printVoiceValue, param)
|
||||||
|
}
|
||||||
|
// 申请退款
|
||||||
|
case utils.Int2Str(model.ApplyOrderRefund):
|
||||||
|
// 称谓设置/平台语音设置
|
||||||
|
if setting.CallNameSetting == 64 || setting.CallNameSetting == 65 || setting.CallNameSetting == 66 {
|
||||||
|
// 老板
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, setting.CallNameSetting)
|
||||||
|
}
|
||||||
|
// 订单设置
|
||||||
|
if setting.PrintSetting.ApplyUserRefund == model.SettingOpen { // 取消退款订单
|
||||||
|
textMsg, err = MakePrintMsgOnTemp(param, userId)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if setting.VoiceSetting.ApplyRefundOrderVoice == model.SettingOpen {
|
||||||
|
//printVoiceMsg, printVoiceValue = SyntheticSpeech(printVoiceMsg, printVoiceValue, param)
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, model.ApplyRefundVoice)
|
||||||
|
}
|
||||||
|
// 取消打印
|
||||||
|
|
||||||
|
case utils.Int2Str(model.OrderStatusRejection): // 拒收
|
||||||
|
// 称谓设置/平台语音设置
|
||||||
|
if setting.CallNameSetting == 64 || setting.CallNameSetting == 65 || setting.CallNameSetting == 66 {
|
||||||
|
// 老板
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, setting.CallNameSetting)
|
||||||
|
}
|
||||||
|
//if setting.VoiceSetting.CustomerRejectionVoice == model.SettingOpen && setting.SystemVoice == model.SettingOpen {
|
||||||
|
// // 暂无语音打印
|
||||||
|
//}
|
||||||
|
// 拒收暂无语音设置,使用文本提示
|
||||||
|
if setting.PrintSetting.CustomerRejectionPrint == model.SettingOpen { // 客户拒收打印
|
||||||
|
rejection := ``
|
||||||
|
rejectionValue := make([]interface{}, 0, 0)
|
||||||
|
rejection += `<center><b>客户拒收信息:</b></center><br>`
|
||||||
|
rejection += `<center><b>订单号: %s</b></center><br>`
|
||||||
|
rejection += `<center><b>订单来源: %s # %s</b></center><br>`
|
||||||
|
rejection += `<center><b>拒收原因: %s</b></center><br>`
|
||||||
|
rejectionValue = append(rejectionValue, param[model.OrderNoPrint], param[model.VendorNamePrint], param[model.VendorOrderNoPrint], param[model.RejectionReasonPrint])
|
||||||
|
textMsg = strings.Replace(fmt.Sprintf(strings.Replace(rejection, "\n", "", -1), rejectionValue...), "\\n", "\r\n", -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
case utils.Int2Str(model.OrderStatusCustomerService): // 客服退款
|
||||||
|
// 称谓设置/平台语音设置
|
||||||
|
if setting.CallNameSetting == 64 || setting.CallNameSetting == 65 || setting.CallNameSetting == 66 {
|
||||||
|
// 老板
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, setting.CallNameSetting)
|
||||||
|
}
|
||||||
|
if setting.VoiceSetting.CusterRefundVoice == model.SettingOpen {
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, model.BusinessResponsibilityVoice)
|
||||||
|
}
|
||||||
|
if setting.PrintSetting.CusterRefundPrint == model.SettingOpen {
|
||||||
|
rejection := ``
|
||||||
|
rejectionValue := make([]interface{}, 0, 0)
|
||||||
|
rejection += `<center><b>客服退款详情:</b></center><br>`
|
||||||
|
rejection += `<center><b>订单号: %s</b></center><br>`
|
||||||
|
rejection += `<center><b>订单来源: %s # %s</b></center><br>`
|
||||||
|
rejection += `<center><b>退款原因: %s</b></center><br>`
|
||||||
|
rejection += `<center><b>退款时间: %s</b></center><br>`
|
||||||
|
rejectionValue = append(rejectionValue, param[model.OrderNoPrint], param[model.VendorNamePrint], param[model.VendorOrderNoPrint], param[model.CustcareRefundReasonPrint], utils.Time2DateStr(time.Now()))
|
||||||
|
textMsg = strings.Replace(fmt.Sprintf(strings.Replace(rejection, "\n", "", -1), rejectionValue...), "\\n", "\r\n", -1)
|
||||||
|
}
|
||||||
|
case utils.Int2Str(model.OrderStatusCanceled), utils.Int2Str(model.CancelOrderSuccess): // 取消订单成功
|
||||||
|
// 称谓设置/平台语音设置
|
||||||
|
if setting.CallNameSetting == 64 || setting.CallNameSetting == 65 || setting.CallNameSetting == 66 {
|
||||||
|
// 老板
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, setting.CallNameSetting)
|
||||||
|
if setting.VoiceSetting.RefundGoodsVoice == model.SettingOpen {
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, model.CancelOrderVoice)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if setting.PrintSetting.CusterRefundPrint == model.SettingOpen {
|
||||||
|
rejection := ``
|
||||||
|
rejectionValue := make([]interface{}, 0, 0)
|
||||||
|
rejection += `<center><b>订单取消成功:</b></center><br>`
|
||||||
|
rejection += `<center><b>订单号: %s</b></center><br>`
|
||||||
|
rejection += `<center><b>订单来源: %s # %s</b></center><br>`
|
||||||
|
rejection += `<center><b>取消原因: %s</b></center><br>`
|
||||||
|
rejection += `<center><b>取消成功时间: %s</b></center><br>`
|
||||||
|
rejectionValue = append(rejectionValue, param[model.OrderNoPrint], param[model.VendorNamePrint], param[model.VendorOrderNoPrint], param[model.CustcareRefundReasonPrint], utils.Time2DateStr(time.Now()))
|
||||||
|
textMsg = strings.Replace(fmt.Sprintf(strings.Replace(rejection, "\n", "", -1), rejectionValue...), "\\n", "\r\n", -1)
|
||||||
|
}
|
||||||
|
case utils.Int2Str(model.BusinessCancelOrder): // 商家取消打印
|
||||||
|
// 称谓设置/平台语音设置
|
||||||
|
if setting.CallNameSetting == 64 || setting.CallNameSetting == 65 || setting.CallNameSetting == 66 {
|
||||||
|
// 老板
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, setting.CallNameSetting)
|
||||||
|
}
|
||||||
|
if setting.PrintSetting.BusinessOrderCancel == model.SettingOpen {
|
||||||
|
rejection := ``
|
||||||
|
rejectionValue := make([]interface{}, 0, 0)
|
||||||
|
rejection += `<center><b>商家侧取消订单:</b></center><br>`
|
||||||
|
rejection += `<center><b>订单号: %s</b></center><br>`
|
||||||
|
rejection += `<center><b>订单来源: %s # %s</b></center><br>`
|
||||||
|
rejection += `<center><b>取消原因: %s</b></center><br>`
|
||||||
|
rejection += `<center><b>取消成功时间: %s</b></center><br>`
|
||||||
|
rejectionValue = append(rejectionValue, param[model.OrderNoPrint], param[model.VendorNamePrint], param[model.VendorOrderNoPrint], param[model.CustcareRefundReasonPrint], utils.Time2DateStr(time.Now()))
|
||||||
|
textMsg = strings.Replace(fmt.Sprintf(strings.Replace(rejection, "\n", "", -1), rejectionValue...), "\\n", "\r\n", -1)
|
||||||
|
}
|
||||||
|
case utils.Int2Str(model.OrderRefundMoneySuccess): // 订单退款成功打印
|
||||||
|
// 称谓设置/平台语音设置
|
||||||
|
if setting.CallNameSetting == 64 || setting.CallNameSetting == 65 || setting.CallNameSetting == 66 {
|
||||||
|
// 老板
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, setting.CallNameSetting)
|
||||||
|
}
|
||||||
|
if setting.PrintSetting.OrderCancelSuccess == model.SettingOpen {
|
||||||
|
rejection := ``
|
||||||
|
rejectionValue := make([]interface{}, 0, 0)
|
||||||
|
rejection += `<center><b>退款成功:</b></center><br>`
|
||||||
|
rejection += `<center><b>订单号: %s</b></center><br>`
|
||||||
|
rejection += `<center><b>订单来源: %s # %s</b></center><br>`
|
||||||
|
rejectionValue = append(rejectionValue, param[model.OrderNoPrint], param[model.VendorNamePrint], param[model.VendorOrderNoPrint])
|
||||||
|
textMsg = strings.Replace(fmt.Sprintf(strings.Replace(rejection, "\n", "", -1), rejectionValue...), "\\n", "\r\n", -1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
voice := strings.Replace(fmt.Sprintf(strings.Replace(printVoiceMsg, "\n", "", -1), printVoiceValue...), "\\n", "\r\n", -1)
|
||||||
|
return voice + textMsg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrintWayBillOrderStatus 打印运单类通知消息
|
||||||
|
func PrintWayBillOrderStatus(param map[string]string, setting *model.PrintSettingObj) string {
|
||||||
|
var (
|
||||||
|
printVoiceMsg string //语音信息
|
||||||
|
printVoiceValue = make([]interface{}, 0, 0)
|
||||||
|
textMsg string // 文本信息
|
||||||
|
textMsgValue = make([]interface{}, 0, 0) // 文本信息
|
||||||
|
)
|
||||||
|
|
||||||
|
switch param[model.WayBillStatusPrint] {
|
||||||
|
case utils.Int2Str(model.WaybillStatusAccepted), utils.Int2Str(model.WaybillStatusCourierAssigned): // 分配骑手
|
||||||
|
if setting.PrintSetting.RiderTakeOrder == model.SettingOpen { // 打印订单
|
||||||
|
textMsg += `<center><b>接单骑手信息:</b></center><br>`
|
||||||
|
textMsg += `<center><b>骑手姓名: %s</b></center><br>`
|
||||||
|
textMsg += `<center><b>骑手电话: %s</b></center><br>`
|
||||||
|
textMsg += `<center><b>接单时间: %s</b></center><br>`
|
||||||
|
textMsg += `<center><b>订单来源: %s</b></center><br>`
|
||||||
|
textMsg += `<center><b>单号: #%s</b></center><br>`
|
||||||
|
textMsgValue = append(textMsgValue, param[model.RiderNamePrint], param[model.RiderPhonePrint], utils.Time2DateStr(time.Now()), param[model.VendorNamePrint], param[model.VendorOrderNoPrint])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if setting.VoiceSetting.RiderTakeOrderVoice == model.SettingOpen { // 骑手接单语音通知
|
||||||
|
printVoiceMsg += `<sound>%d</sound><sound>%d</sound>` // 骑手已经接单了
|
||||||
|
printVoiceValue = append(printVoiceValue, model.RiderGetOrderVoice)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := strings.Replace(fmt.Sprintf(strings.Replace(textMsg, "\n", "", -1), textMsgValue...), "\\n", "\r\n", -1)
|
||||||
|
voice := strings.Replace(fmt.Sprintf(strings.Replace(printVoiceMsg, "\n", "", -1), printVoiceValue...), "\\n", "\r\n", -1)
|
||||||
|
return voice + msg
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrintStoreStatus 打印门店状态
|
||||||
|
func PrintStoreStatus(param map[string]string, setting *model.PrintSettingObj) string {
|
||||||
|
var (
|
||||||
|
printVoiceMsg string //语音信息
|
||||||
|
printVoiceValue = make([]interface{}, 0, 0)
|
||||||
|
textMsg string // 文本信息
|
||||||
|
textMsgValue = make([]interface{}, 0, 0)
|
||||||
|
)
|
||||||
|
|
||||||
|
switch utils.Str2Int(param[model.StoreStatusPrint]) {
|
||||||
|
case -9: // 丢失授权
|
||||||
|
var voice string
|
||||||
|
if setting.VoiceSetting.LoseAuthorization == model.SettingOpen {
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, model.LoseTokenVoice)
|
||||||
|
voice = strings.Replace(fmt.Sprintf(strings.Replace(printVoiceMsg, "\n", "", -1), printVoiceValue...), "\\n", "\r\n", -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
textMsg += `<left><b>门店丢失授权通知</b></left><br>`
|
||||||
|
textMsg += `<left><b>门店:%s</b></left><br>`
|
||||||
|
textMsg += `<left><b>平台:%s</b></left><br>`
|
||||||
|
textMsg += `<left><b>下线时间:%s</b></left><br>`
|
||||||
|
textMsg += `<left><b>授权丢失,将无法继续打压订单!!!!</b></left><br>`
|
||||||
|
textMsgValue = append(textMsgValue, param[model.StoreNamePrint], param[model.VendorNamePrint], utils.Time2DateStr(time.Now()))
|
||||||
|
msg := strings.Replace(fmt.Sprintf(strings.Replace(textMsg, "\n", "", -1), textMsgValue...), "\\n", "\r\n", -1)
|
||||||
|
return voice + msg
|
||||||
|
default:
|
||||||
|
// 离线打印文本开启
|
||||||
|
textMsg += `<center><b>门店下线通知</b></center><br>`
|
||||||
|
textMsg += `<center><b>门店:%s</b></center><br>`
|
||||||
|
textMsg += `<center><b>平台:%s</b></center><br>`
|
||||||
|
textMsg += `<center><b>下线时间:%s</b></center><br>`
|
||||||
|
textMsgValue = append(textMsgValue, param[model.StoreNamePrint], param[model.VendorNamePrint], utils.Time2DateStr(time.Now()))
|
||||||
|
// 离线打印语音开启
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, model.StoreOfflineVoice)
|
||||||
|
voice := strings.Replace(fmt.Sprintf(strings.Replace(printVoiceMsg, "\n", "", -1), printVoiceValue...), "\\n", "\r\n", -1)
|
||||||
|
msg := strings.Replace(fmt.Sprintf(strings.Replace(textMsg, "\n", "", -1), textMsgValue...), "\\n", "\r\n", -1)
|
||||||
|
|
||||||
|
return voice + msg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SyntheticSpeech 合成语音 (美团xxx号订单)
|
||||||
|
func SyntheticSpeech(printVoiceMsg string, printVoiceValue []interface{}, param map[string]string) (string, []interface{}) {
|
||||||
|
printVoiceMsg += `<sound>%d</sound>` // 美团
|
||||||
|
switch param[model.VendorIDPrint] {
|
||||||
|
case utils.Int2Str(model.VendorIDJD): // 京东
|
||||||
|
printVoiceValue = append(printVoiceValue, model.JdVoice)
|
||||||
|
case utils.Int2Str(model.VendorIDMTWM): // 美团
|
||||||
|
printVoiceValue = append(printVoiceValue, model.MtVoice)
|
||||||
|
case utils.Int2Str(model.VendorIDELM): // 饿了么
|
||||||
|
printVoiceValue = append(printVoiceValue, model.ElmVoice)
|
||||||
|
case utils.Int2Str(model.VendorIDEBAI): // 饿百
|
||||||
|
printVoiceValue = append(printVoiceValue, model.ElmVoice)
|
||||||
|
case utils.Int2Str(model.VendorIDJDShop): // 京东商城
|
||||||
|
printVoiceValue = append(printVoiceValue, model.JdToHose)
|
||||||
|
case utils.Int2Str(model.VendorIDTT): // 抖音
|
||||||
|
// 暂无
|
||||||
|
}
|
||||||
|
if param[model.VendorOrderNoPrint] != "" {
|
||||||
|
switch len(param[model.VendorOrderNoPrint]) {
|
||||||
|
case 1:
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, model.NumberVoiceMap[param[model.VendorOrderNoPrint]])
|
||||||
|
case 2:
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, model.NumberVoiceMap[param[model.VendorOrderNoPrint][:1]+"0"])
|
||||||
|
if param[model.VendorOrderNoPrint][1:] != "0" {
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, model.NumberVoiceMap[param[model.VendorOrderNoPrint][1:]])
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, model.NumberVoiceMap[param[model.VendorOrderNoPrint][0:1]+"00"])
|
||||||
|
if param[model.VendorOrderNoPrint][1:2] == "0" && param[model.VendorOrderNoPrint][2:] == "0" {
|
||||||
|
|
||||||
|
} else if param[model.VendorOrderNoPrint][1:2] == "0" && param[model.VendorOrderNoPrint][2:] != "0" {
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, model.NumberVoiceMap[param[model.VendorOrderNoPrint][1:2]])
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, model.NumberVoiceMap[param[model.VendorOrderNoPrint][2:]])
|
||||||
|
} else if param[model.VendorOrderNoPrint][1:2] != "0" && param[model.VendorOrderNoPrint][2:] == "0" {
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, model.NumberVoiceMap[param[model.VendorOrderNoPrint][1:2]+"0"])
|
||||||
|
} else if param[model.VendorOrderNoPrint][1:2] != "0" && param[model.VendorOrderNoPrint][2:] != "0" {
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, model.NumberVoiceMap[param[model.VendorOrderNoPrint][1:2]+"0"])
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, model.NumberVoiceMap[param[model.VendorOrderNoPrint][2:]])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printVoiceMsg += `<sound>%d</sound>`
|
||||||
|
printVoiceValue = append(printVoiceValue, model.OrderNoVoice)
|
||||||
|
return printVoiceMsg, printVoiceValue
|
||||||
|
}
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
package enterprise
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/ebaiapi"
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestOOO(t *testing.T) {
|
|
||||||
product := map[string]interface{}{
|
|
||||||
"apply_quantity": 1,
|
|
||||||
"apply_refund_time": 1711447475000,
|
|
||||||
"apply_refund_user_amount": 143,
|
|
||||||
"commodity_type": 2,
|
|
||||||
"custom_sku_id": "25381",
|
|
||||||
"custom_sku_spec_id": "",
|
|
||||||
"discount_detail": map[string]interface{}{
|
|
||||||
"agent_discount_amount": 0,
|
|
||||||
"discount_total_amount": 577,
|
|
||||||
"merchant_discount_amount": 563,
|
|
||||||
"platform_discount_amount": 14,
|
|
||||||
"total_price": 720,
|
|
||||||
"user_discount_amount": 0,
|
|
||||||
},
|
|
||||||
"free_gift": false,
|
|
||||||
"fund_calculate_type": 0,
|
|
||||||
"gift_related_sub_biz_order_id_list": nil,
|
|
||||||
"is_combine": false,
|
|
||||||
"last_refund_status": 0,
|
|
||||||
"platform_sku_id": 16319366072214214,
|
|
||||||
"refund_order_id": 2403269635888396215,
|
|
||||||
"refund_quantity": 1,
|
|
||||||
"refund_status": 50,
|
|
||||||
"refund_user_amount": 143,
|
|
||||||
"refund_weight": 350,
|
|
||||||
"sku_name": "【尽享好价】西红柿 番茄约300~350g/组",
|
|
||||||
"sku_spec_id": "null",
|
|
||||||
"sub_biz_order_id": "4006435770425226215",
|
|
||||||
"upc": "upc-25381",
|
|
||||||
"virtual_type": "0",
|
|
||||||
}
|
|
||||||
skuList := aa(product)
|
|
||||||
globals.SugarLogger.Debugf("=====skulist := %s", utils.Format4Output(skuList, false))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func aa(product map[string]interface{}) (skuList []*model.OrderSku) {
|
|
||||||
skuList = make([]*model.OrderSku, 0, 0)
|
|
||||||
if product["virtual_type"] == ebaiapi.OrderVirtualType {
|
|
||||||
skuName := product["sku_name"].(string)
|
|
||||||
_, _, _, specUnit, _, specQuality := jxutils.SplitSkuName(skuName)
|
|
||||||
number := int(utils.MustInterface2Int64(product["apply_quantity"]))
|
|
||||||
sku := &model.OrderSku{
|
|
||||||
VendorOrderID: "1",
|
|
||||||
VendorID: model.VendorIDEBAI,
|
|
||||||
Count: number,
|
|
||||||
SkuID: int(utils.Str2Int64WithDefault(utils.Interface2String(product[ebaiapi.KeyCustomSkuID]), 0)),
|
|
||||||
VendorSkuID: utils.Int2Str(product["platform_sku_id"].(int)),
|
|
||||||
SkuName: skuName,
|
|
||||||
Weight: int(utils.Interface2Int64WithDefault(product["refund_weight"], 0)) / number, // 退单这里的total_weight有BUG,这里的total_weight还是没有退单时的值
|
|
||||||
VendorPrice: utils.MustInterface2Int64(product["refund_user_amount"]),
|
|
||||||
}
|
|
||||||
//sku.SalePrice, _, sku.StoreSubName = getSkuSalePrice(product)
|
|
||||||
sku.SalePrice = utils.Interface2Int64WithDefault(product["discount_detail"].(map[string]interface{})["total_price"], 0)
|
|
||||||
if sku.Weight == 0 {
|
|
||||||
sku.Weight = jxutils.FormatSkuWeight(specQuality, specUnit) // 订单信息里没有重量,只有名字里尝试找
|
|
||||||
}
|
|
||||||
skuList = append(skuList, sku)
|
|
||||||
}
|
|
||||||
return skuList
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
package enterprise
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/enterprise_wechat"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/legacymodel"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
var EnterpriseSuite = new(enterprise_wechat.SuiteTicketInfo)
|
|
||||||
|
|
||||||
// 初始化加载全局变量
|
|
||||||
func Init() {
|
|
||||||
var config []*legacymodel.Config
|
|
||||||
sql := `SELECT * FROM config WHERE thirdparty = ? `
|
|
||||||
if err := dao.GetRows(dao.GetDB(), &config, sql, []interface{}{"enterprise"}...); err != nil {
|
|
||||||
globals.SugarLogger.Debug("enterprice init config err = ", err)
|
|
||||||
}
|
|
||||||
if len(config) >= model.YES {
|
|
||||||
EnterpriseSuite.SuiteId = config[0].RefreshToken
|
|
||||||
EnterpriseSuite.SuiteTicket = config[0].Token
|
|
||||||
EnterpriseSuite.InfoType = ""
|
|
||||||
time, _ := strconv.ParseInt(config[0].Date, 10, 64)
|
|
||||||
EnterpriseSuite.TimeStamp = time
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func UpdateEnterpriseSuite(data *enterprise_wechat.SuiteTicketInfo) error {
|
|
||||||
if data.SuiteTicket != "" && data.TimeStamp > 0 {
|
|
||||||
EnterpriseSuite = data
|
|
||||||
}
|
|
||||||
// 修改数据库
|
|
||||||
db := dao.GetDB()
|
|
||||||
config := &legacymodel.Config{
|
|
||||||
Thirdparty: "enterprise",
|
|
||||||
Token: data.SuiteTicket,
|
|
||||||
Date: string(data.TimeStamp),
|
|
||||||
LastOperator: model.AdminName,
|
|
||||||
RefreshToken: data.SuiteId,
|
|
||||||
}
|
|
||||||
return dao.CreateOrUpdate(db, config)
|
|
||||||
}
|
|
||||||
@@ -1,484 +0,0 @@
|
|||||||
package enterprise
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/ebaiapi"
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/jdapi"
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
|
|
||||||
|
|
||||||
//"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
|
|
||||||
tao "git.rosy.net.cn/baseapi/platformapi/tao_vegetable"
|
|
||||||
domain585 "git.rosy.net.cn/baseapi/platformapi/tao_vegetable/sdk/ability585/domain"
|
|
||||||
request585 "git.rosy.net.cn/baseapi/platformapi/tao_vegetable/sdk/ability585/request"
|
|
||||||
product_listV2_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/product_listV2/request"
|
|
||||||
product_listV2_response "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/product_listV2/response"
|
|
||||||
sku_syncStock_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/sku_syncStock/request"
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/tiktok_shop/tiktok_api"
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxstore/cms"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api/apimanager"
|
|
||||||
beego "github.com/astaxie/beego/server/web"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 该函数主要用于对比京西平台商品和各个平台门店商品的差异
|
|
||||||
// 对比上下架状态以及商品价格差异,相同的不做修改,不同的以京西系统商品为主
|
|
||||||
func CompareJxVendorSku(jxStoreId int, vendorIds []int) (string, error) {
|
|
||||||
var (
|
|
||||||
db = dao.GetDB()
|
|
||||||
errListToStr = new(strings.Builder)
|
|
||||||
)
|
|
||||||
skuList, err := dao.GetStoresSkusInfo(db, []int{jxStoreId}, nil)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 门店商品列表平
|
|
||||||
skuMap := make(map[string]*model.StoreSkuBind, 0)
|
|
||||||
skuIdList := make([]string, 0, len(skuList))
|
|
||||||
for _, v := range skuList {
|
|
||||||
localSkuId := utils.Int2Str(v.SkuID)
|
|
||||||
skuMap[localSkuId] = v
|
|
||||||
skuIdList = append(skuIdList, localSkuId)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 有效的三方平台
|
|
||||||
storeMap, err := dao.GetStoresMapList(db, vendorIds, []int{jxStoreId}, []int{model.StoreStatusOpened, model.StoreStatusClosed, model.StoreStatusHaveRest}, model.StoreStatusDisabled, 1, "", "", "")
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, sm := range storeMap {
|
|
||||||
switch sm.VendorID {
|
|
||||||
case model.VendorIDJD:
|
|
||||||
if errs := JdSyncSkuPriceAndStatus(db, sm, skuMap); err != nil {
|
|
||||||
errListToStr.WriteString(errs.Error())
|
|
||||||
globals.SugarLogger.Debugf("京东同步商品异常信息: %v", errs)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
case model.VendorIDMTWM:
|
|
||||||
if errs := MtWmSyncSkuPriceAndStatus(db, sm, skuMap); errs != nil {
|
|
||||||
errListToStr.WriteString(errs.Error())
|
|
||||||
globals.SugarLogger.Debugf("美团同步商品异常信息: %v", errs)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
case model.VendorIDEBAI:
|
|
||||||
if errs := EBaiSyncSkuPriceAndStatus(db, sm, skuMap); errs != nil {
|
|
||||||
errListToStr.WriteString(errs.Error())
|
|
||||||
globals.SugarLogger.Debugf("饿百同步商品异常信息: %v", errs)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
case model.VendorIDDD:
|
|
||||||
if errs := TiktokSyncSkuPriceAndStatus(db, sm, skuMap); errs != nil {
|
|
||||||
errListToStr.WriteString(errs.Error())
|
|
||||||
globals.SugarLogger.Debugf("抖音同步商品异常信息: %v", errs)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
case model.VendorIDTaoVegetable:
|
|
||||||
if errs := TaoSyncSkuPriceAndStatus(db, sm, skuMap, skuIdList); errs != nil {
|
|
||||||
errListToStr.WriteString(errs.Error())
|
|
||||||
globals.SugarLogger.Debugf("淘宝同步商品异常信息: %v", errs)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
default:
|
|
||||||
return errListToStr.String(), fmt.Errorf("无法识别的平台id")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
// MtWmSyncSkuPriceAndStatus 校验美团平台和京西系统商品差异
|
|
||||||
func MtWmSyncSkuPriceAndStatus(db *dao.DaoDB, sm *model.StoreMap, skuMap map[string]*model.StoreSkuBind) (err error) {
|
|
||||||
var (
|
|
||||||
mtApi = apimanager.CurAPIManager.GetAPI(sm.VendorID, sm.VendorOrgCode).(*mtwmapi.API)
|
|
||||||
i = model.NO
|
|
||||||
foodListData = make([]*mtwmapi.AppFood, 0, 0)
|
|
||||||
errs = make([]string, 0, 0)
|
|
||||||
vendorStatus = 0
|
|
||||||
)
|
|
||||||
|
|
||||||
if len(skuMap) == 0 || sm.IsSync != model.YES {
|
|
||||||
return fmt.Errorf("门店未打开同步或者未关注商品")
|
|
||||||
}
|
|
||||||
|
|
||||||
if sm.VendorOrgCode == globals.Mtwm2Code {
|
|
||||||
mtApi = mtwmapi.New(beego.AppConfig.DefaultString("mtwmAppID2", ""), beego.AppConfig.DefaultString("mtwmSecret2", ""), beego.AppConfig.DefaultString("mtwmCallbackURL2", ""), "")
|
|
||||||
mtApi.SetToken(sm.MtwmToken)
|
|
||||||
} else {
|
|
||||||
mtApi = partner.CurAPIManager.GetAPI(model.VendorIDMTWM, sm.VendorOrgCode).(*mtwmapi.API)
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
foodList, err := mtApi.RetailListAll(sm.VendorStoreID, i)
|
|
||||||
if err != nil {
|
|
||||||
globals.SugarLogger.Debugf("美团商品价格和上下架状态获取平台商品异常 :%v", err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
foodListData = append(foodListData, foodList...)
|
|
||||||
if len(foodList) < 100 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, vsl := range foodListData {
|
|
||||||
if sku, ok := skuMap[vsl.AppFoodCode]; ok {
|
|
||||||
// 同步商品价格
|
|
||||||
if utils.Float64TwoInt(vsl.Price*float64(100)) != sku.MtwmPrice {
|
|
||||||
_, err = cms.CurVendorSync.SyncStoresSkus2(jxcontext.AdminCtx, nil, 0, db, []int{sm.VendorID}, []int{sku.StoreID}, false, []int{sku.SkuID}, []int{27379}, model.SyncFlagPriceMask, true, true)
|
|
||||||
if err != nil {
|
|
||||||
errs = append(errs, fmt.Sprintf("skuCode:%d,修改美团价格错误:%v", sku.SkuID, err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 同步商品上下架状态
|
|
||||||
// SPU(可能包含多个SKU)上下架状态,字段取值范围:0-全部sku上架,1-全部sku下架。以下功能灰度中:若同时传递sku_is_sold_out,则优先根据sku_is_sold_out传参判断单个sku的上下架状态。
|
|
||||||
// 本地sku.Status 0-不可售, 1-可售
|
|
||||||
if vsl.IsSoldOut == sku.Status {
|
|
||||||
if sku.Status == model.SkuStatusNormal {
|
|
||||||
vendorStatus = mtwmapi.SellStatusOnline
|
|
||||||
} else {
|
|
||||||
vendorStatus = mtwmapi.SellStatusOffline
|
|
||||||
}
|
|
||||||
|
|
||||||
param := []*mtwmapi.BareStoreFoodInfo{
|
|
||||||
&mtwmapi.BareStoreFoodInfo{
|
|
||||||
AppFoodCode: utils.Int64ToStr(sku.MtwmID),
|
|
||||||
Skus: nil,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
foodErrList, err := mtApi.RetailSellStatus(jxcontext.AdminCtx.GetTrackInfo(), sm.VendorStoreID, param, vendorStatus)
|
|
||||||
if err != nil {
|
|
||||||
errs = append(errs, fmt.Sprintf("skuCode:%d,修改美团可售状态错误%v", sku.SkuID, err))
|
|
||||||
}
|
|
||||||
for _, fel := range foodErrList {
|
|
||||||
errs = append(errs, fmt.Sprintf("skuCode:%s,修改美团可售状态错误:%s", fel.AppFoodCode, fel.ErrorMsg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
param := []*mtwmapi.BareStoreFoodInfo{
|
|
||||||
&mtwmapi.BareStoreFoodInfo{
|
|
||||||
AppFoodCode: vsl.AppFoodCode,
|
|
||||||
Skus: nil,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
foodErrList, err := mtApi.RetailSellStatus(jxcontext.AdminCtx.GetTrackInfo(), sm.VendorStoreID, param, mtwmapi.SellStatusOffline)
|
|
||||||
if err != nil {
|
|
||||||
errs = append(errs, fmt.Sprintf("skuCode:%d,修改美团可售状态错误%v", vsl.AppFoodCode, err))
|
|
||||||
}
|
|
||||||
for _, fel := range foodErrList {
|
|
||||||
errs = append(errs, fmt.Sprintf("skuCode:%s,修改美团可售状态错误:%s", fel.AppFoodCode, fel.ErrorMsg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(errs) == model.NO {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Errorf("%s", strings.Join(errs, ","))
|
|
||||||
}
|
|
||||||
|
|
||||||
// EBaiSyncSkuPriceAndStatus 校验饿了么平台和京西系统商品差异
|
|
||||||
func EBaiSyncSkuPriceAndStatus(db *dao.DaoDB, sm *model.StoreMap, skuMap map[string]*model.StoreSkuBind) (err error) {
|
|
||||||
var (
|
|
||||||
ebaiApi = apimanager.CurAPIManager.GetAPI(sm.VendorID, sm.VendorOrgCode).(*ebaiapi.API)
|
|
||||||
//skuIdOffset = 0
|
|
||||||
foodListData = make([]*ebaiapi.SkuInfo, 0, 0)
|
|
||||||
errs = make([]string, 0, 0)
|
|
||||||
)
|
|
||||||
|
|
||||||
if len(skuMap) == 0 || sm.IsSync != model.YES {
|
|
||||||
return fmt.Errorf("门店未打开同步或者未关注商品")
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
page := 1
|
|
||||||
param := &ebaiapi.SkuListParams{
|
|
||||||
Page: page,
|
|
||||||
PageSize: 100,
|
|
||||||
//SkuIdOffset: skuIdOffset,
|
|
||||||
}
|
|
||||||
foodList, err := ebaiApi.SkuList(utils.Int2Str(sm.StoreID), param)
|
|
||||||
if err != nil {
|
|
||||||
globals.SugarLogger.Debugf("饿了么商品价格和上下架状态获取平台商品异常 :%v", err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
foodListData = append(foodListData, foodList.List...)
|
|
||||||
if len(foodList.List) < 100 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
//skuIdOffset = foodList.SkuIdOffset
|
|
||||||
page += 1
|
|
||||||
}
|
|
||||||
globals.SugarLogger.Debugf("======len foodListData:= %d", len(foodListData))
|
|
||||||
globals.SugarLogger.Debugf("======len skuMap:= %d", len(skuMap))
|
|
||||||
for _, vsl := range foodListData {
|
|
||||||
if sku, ok := skuMap[vsl.CustomSkuId]; ok {
|
|
||||||
// 同步商品价格
|
|
||||||
if vsl.SalePrice != sku.EbaiPrice {
|
|
||||||
_, err = cms.CurVendorSync.SyncStoresSkus2(jxcontext.AdminCtx, nil, 0, db, []int{sm.VendorID}, []int{sku.StoreID}, false, []int{sku.SkuID}, []int{27379}, model.SyncFlagPriceMask, true, true)
|
|
||||||
}
|
|
||||||
// 同步商品上下架状态
|
|
||||||
// 1为上架,0为下架
|
|
||||||
// 本地sku.Status 0-不可售, 1-可售
|
|
||||||
if vsl.Status != utils.Int2Str(sku.Status) {
|
|
||||||
// 平台上架本地下架,将平台商品下架
|
|
||||||
if sku.Status == model.StoreSkuBindStatusNormal {
|
|
||||||
ebailResult, err := ebaiApi.SkuOnline(jxcontext.AdminCtx.GetTrackInfo(), utils.Int2Str(sm.StoreID), []int64{sku.EbaiID}, nil, nil)
|
|
||||||
if err != nil {
|
|
||||||
errs = append(errs, fmt.Sprintf("skuCode:%d,修改饿百可售状态错误%v", sku.SkuID, err))
|
|
||||||
}
|
|
||||||
for _, fel := range ebailResult.FailedList {
|
|
||||||
errs = append(errs, fmt.Sprintf("skuCode:%d,修改饿百可售状态错误:%s", fel.SkuID, fel.ErrorMsg))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = ebaiApi.SkuOfflineOne(jxcontext.AdminCtx.GetTrackInfo(), utils.Int2Str(sm.StoreID), sku.EbaiID, "", "")
|
|
||||||
if err != nil {
|
|
||||||
errs = append(errs, fmt.Sprintf("skuCode:%d,修改饿百不可售状态错误%v", sku.SkuID, err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_, err = ebaiApi.SkuDelete(jxcontext.AdminCtx.GetTrackInfo(), utils.Int2Str(sm.StoreID), nil, []string{vsl.CustomSkuId})
|
|
||||||
|
|
||||||
//err = ebaiApi.SkuOfflineOne(jxcontext.AdminCtx.GetTrackInfo(), utils.Int2Str(sm.StoreID), utils.Str2Int64(vsl.CustomSkuId), "", "")
|
|
||||||
if err != nil {
|
|
||||||
errs = append(errs, fmt.Sprintf("skuCode:%d,修改饿百不可售状态错误%v", sku.SkuID, err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(errs) == model.NO {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Errorf("%s", strings.Join(errs, ","))
|
|
||||||
}
|
|
||||||
|
|
||||||
// TaoSyncSkuPriceAndStatus 校验淘宝平台和京西系统商品差异
|
|
||||||
func TaoSyncSkuPriceAndStatus(db *dao.DaoDB, sm *model.StoreMap, skuMap map[string]*model.StoreSkuBind, skuIdList []string) (err error) {
|
|
||||||
var (
|
|
||||||
taoApi = apimanager.CurAPIManager.GetAPI(sm.VendorID, sm.VendorOrgCode).(*tao.API)
|
|
||||||
length = len(skuIdList) / 100
|
|
||||||
foodListData = make([]domain585.AlibabaWdkSkuQuerySkuDo, 0, 0)
|
|
||||||
onlineStatus int64 = 0
|
|
||||||
)
|
|
||||||
if len(skuMap) == 0 || sm.IsSync != model.YES {
|
|
||||||
return fmt.Errorf("门店未打开同步或者未关注商品")
|
|
||||||
}
|
|
||||||
if len(skuIdList)%100 != 0 {
|
|
||||||
length += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取平台商品列表
|
|
||||||
for i := 0; i < length; i++ {
|
|
||||||
skuCods := skuIdList[i*100 : (i+1)*100]
|
|
||||||
foodList, _ := taoApi.QueryStoreSKu(&request585.AlibabaWdkSkuQueryRequest{Param: &domain585.AlibabaWdkSkuQuerySkuQueryDo{
|
|
||||||
OuCode: utils.String2Pointer(sm.VendorStoreID),
|
|
||||||
SkuCodes: &skuCods,
|
|
||||||
}})
|
|
||||||
for _, fl := range *foodList {
|
|
||||||
if *fl.Success {
|
|
||||||
foodListData = append(foodListData, *fl.Model)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 比较商品差异
|
|
||||||
errs := make([]string, 0, 0)
|
|
||||||
for _, vsl := range foodListData {
|
|
||||||
if sku, ok := skuMap[*vsl.SkuCode]; ok {
|
|
||||||
// 同步商品价格
|
|
||||||
if utils.Float64TwoInt(utils.Str2Float64(*vsl.SalePrice)*float64(100)) != sku.TaoPrice {
|
|
||||||
_, err = cms.CurVendorSync.SyncStoresSkus2(jxcontext.AdminCtx, nil, 0, db, []int{sm.VendorID}, []int{sku.StoreID}, false, []int{sku.SkuID}, []int{27379}, model.SyncFlagPriceMask, true, true)
|
|
||||||
if err != nil {
|
|
||||||
errs = append(errs, fmt.Sprintf("淘宝对比商品价格异常skuid:%d,错误%v", sku.SkuID, err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 同步商品上下架状态
|
|
||||||
// 是否线上可售 是 0:否 1:是。
|
|
||||||
// 本地sku.Status 0-不可售, 1-可售
|
|
||||||
if int(*vsl.OnlineSaleFlag) != sku.Status {
|
|
||||||
// 平台上架本地下架,将平台商品下架
|
|
||||||
param := &request585.AlibabaWdkSkuUpdateRequest{}
|
|
||||||
updateSkuList := make([]domain585.AlibabaWdkSkuUpdateSkuDo, 0, 0)
|
|
||||||
if sku.Status == model.SkuStatusNormal {
|
|
||||||
onlineStatus = tao.CreateOnlineSaleFlag
|
|
||||||
} else {
|
|
||||||
onlineStatus = tao.CreateOfflineSaleFlag
|
|
||||||
}
|
|
||||||
updateSkuList = append(updateSkuList, domain585.AlibabaWdkSkuUpdateSkuDo{
|
|
||||||
OuCode: utils.String2Pointer(utils.Int64ToStr(sku.TaoID)),
|
|
||||||
SkuCode: utils.String2Pointer(utils.Int2Str(sku.SkuID)),
|
|
||||||
OnlineSaleFlag: utils.Int64ToPointer(onlineStatus),
|
|
||||||
SubTitle: utils.String2Pointer("小时达"),
|
|
||||||
AllowAppSale: utils.Int64ToPointer(onlineStatus),
|
|
||||||
//CleanSkuMemberPrice: utils.Int64ToPointer(model.YES),
|
|
||||||
})
|
|
||||||
param.ParamList = &updateSkuList
|
|
||||||
|
|
||||||
result, err := taoApi.UpdateStoreSku(param)
|
|
||||||
if err != nil {
|
|
||||||
errs = append(errs, fmt.Sprintf("skuCode:%d,修改饿百可售状态错误%v", sku.SkuID, err))
|
|
||||||
}
|
|
||||||
for _, fel := range *result {
|
|
||||||
if fel.ErrMsg != "" {
|
|
||||||
errs = append(errs, fmt.Sprintf("skuCode:%s,修改饿百可售状态错误:%s", fel.SkuID, fel.ErrMsg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//_, err = cms.CurVendorSync.SyncStoresSkus2(jxcontext.AdminCtx, nil, 0, db, []int{sm.VendorID}, []int{sku.StoreID}, false, []int{sku.SkuID}, []int{27379}, 56, true, true)
|
|
||||||
//if err != nil {
|
|
||||||
// errs = append(errs, fmt.Sprintf("%v", err))
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 平台上架本地下架,将平台商品下架
|
|
||||||
param := &request585.AlibabaWdkSkuUpdateRequest{}
|
|
||||||
updateSkuList := make([]domain585.AlibabaWdkSkuUpdateSkuDo, 0, 0)
|
|
||||||
onlineStatus = tao.CreateOfflineSaleFlag
|
|
||||||
updateSkuList = append(updateSkuList, domain585.AlibabaWdkSkuUpdateSkuDo{
|
|
||||||
OuCode: vsl.OuCode,
|
|
||||||
SkuCode: vsl.SkuCode,
|
|
||||||
OnlineSaleFlag: utils.Int64ToPointer(onlineStatus),
|
|
||||||
SubTitle: utils.String2Pointer("小时达"),
|
|
||||||
AllowAppSale: utils.Int64ToPointer(onlineStatus),
|
|
||||||
//CleanSkuMemberPrice: utils.Int64ToPointer(model.YES),
|
|
||||||
})
|
|
||||||
param.ParamList = &updateSkuList
|
|
||||||
result, err := taoApi.UpdateStoreSku(param)
|
|
||||||
if err != nil {
|
|
||||||
errs = append(errs, fmt.Sprintf("skuCode:%d,修改饿百可售状态错误%v", sku.SkuID, err))
|
|
||||||
}
|
|
||||||
for _, fel := range *result {
|
|
||||||
if fel.ErrMsg != "" {
|
|
||||||
errs = append(errs, fmt.Sprintf("skuCode:%s,修改饿百可售状态错误:%s", fel.SkuID, fel.ErrMsg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(errs) == model.NO {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Errorf("%s", strings.Join(errs, ","))
|
|
||||||
}
|
|
||||||
|
|
||||||
// TiktokSyncSkuPriceAndStatus 校验抖音平台和京西系统商品差异
|
|
||||||
func TiktokSyncSkuPriceAndStatus(db *dao.DaoDB, sm *model.StoreMap, skuMap map[string]*model.StoreSkuBind) (err error) {
|
|
||||||
var (
|
|
||||||
tiktokApi = apimanager.CurAPIManager.GetAPI(sm.VendorID, sm.VendorOrgCode).(*tiktok_api.API)
|
|
||||||
page = 0
|
|
||||||
foodListData = make([]product_listV2_response.DataItem, 0, 0)
|
|
||||||
errs = make([]string, 0, 0)
|
|
||||||
)
|
|
||||||
if len(skuMap) == 0 || sm.IsSync != model.YES {
|
|
||||||
return fmt.Errorf("门店未打开同步或者未关注商品")
|
|
||||||
}
|
|
||||||
for {
|
|
||||||
param := &product_listV2_request.ProductListV2Param{
|
|
||||||
Page: int64(page),
|
|
||||||
Size: 100,
|
|
||||||
StoreId: utils.Str2Int64(sm.VendorStoreID),
|
|
||||||
}
|
|
||||||
foodList, err := tiktokApi.GetSkuDetailList(param)
|
|
||||||
if err != nil {
|
|
||||||
globals.SugarLogger.Debugf("抖音商品价格和上下架状态获取平台商品异常 :%v", err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
foodListData = append(foodListData, foodList.Data...)
|
|
||||||
if len(foodList.Data) < 100 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
page += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, vsl := range foodListData {
|
|
||||||
if sku, ok := skuMap[vsl.OuterProductId]; ok {
|
|
||||||
// 同步商品价格
|
|
||||||
if vsl.DiscountPrice != int64(sku.DdPrice) {
|
|
||||||
_, err = cms.CurVendorSync.SyncStoresSkus2(jxcontext.AdminCtx, nil, 0, db, []int{sm.VendorID}, []int{sku.StoreID}, false, []int{sku.SkuID}, []int{27379}, model.SyncFlagPriceMask, true, true)
|
|
||||||
if err != nil {
|
|
||||||
errs = append(errs, fmt.Sprintf("抖音对比商品价格异常skuid:%d,错误%v", sku.SkuID, err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 同步商品上下架状态
|
|
||||||
// 0-在线 1-下线
|
|
||||||
// 本地sku.Status 0-不可售,1-可售
|
|
||||||
if vsl.Status == int64(sku.Status) {
|
|
||||||
if sku.Status == model.SkuStatusNormal {
|
|
||||||
param := &sku_syncStock_request.SkuSyncStockParam{
|
|
||||||
ProductId: sku.DdID,
|
|
||||||
Incremental: false,
|
|
||||||
StockNum: 99999,
|
|
||||||
OutSkuId: int64(sku.SkuID),
|
|
||||||
}
|
|
||||||
if err = tiktokApi.UpdateSkuStock(param); err != nil {
|
|
||||||
errs = append(errs, fmt.Sprintf("抖音对比商品上架异常skuid:%d,错误%v", sku.SkuID, err))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
param := &sku_syncStock_request.SkuSyncStockParam{
|
|
||||||
ProductId: sku.DdID,
|
|
||||||
Incremental: false,
|
|
||||||
StockNum: 0,
|
|
||||||
OutSkuId: int64(sku.SkuID),
|
|
||||||
}
|
|
||||||
if err = tiktokApi.UpdateSkuStock(param); err != nil {
|
|
||||||
errs = append(errs, fmt.Sprintf("抖音对比商品下架异常skuid:%d,错误%v", sku.SkuID, err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
param := &sku_syncStock_request.SkuSyncStockParam{
|
|
||||||
ProductId: sku.DdID,
|
|
||||||
Incremental: false,
|
|
||||||
StockNum: 0,
|
|
||||||
OutSkuId: int64(sku.SkuID),
|
|
||||||
}
|
|
||||||
if err = tiktokApi.UpdateSkuStock(param); err != nil {
|
|
||||||
errs = append(errs, fmt.Sprintf("抖音对比商品下架异常skuid:%d,错误%v", sku.SkuID, err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(errs) == model.NO {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Errorf("%s", strings.Join(errs, ","))
|
|
||||||
}
|
|
||||||
|
|
||||||
// JdSyncSkuPriceAndStatus 校验京东平台和京西系统商品差异
|
|
||||||
func JdSyncSkuPriceAndStatus(db *dao.DaoDB, sm *model.StoreMap, skuMap map[string]*model.StoreSkuBind) (err error) {
|
|
||||||
var (
|
|
||||||
jdsApi = apimanager.CurAPIManager.GetAPI(sm.VendorID, sm.VendorOrgCode).(*jdapi.API)
|
|
||||||
)
|
|
||||||
skuVendibilityList := make([]*jdapi.StockVendibility, 0, 0)
|
|
||||||
for _, v := range skuMap {
|
|
||||||
skuVendibilityList = append(skuVendibilityList, &jdapi.StockVendibility{
|
|
||||||
OutSkuId: utils.Int2Str(v.SkuID),
|
|
||||||
DoSale: v.Status == model.SkuStatusNormal,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
count := len(skuVendibilityList) / 50
|
|
||||||
if len(skuVendibilityList)%50 != 0 {
|
|
||||||
count += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 1; i <= count; i++ {
|
|
||||||
if i == count {
|
|
||||||
jdsApi.BatchUpdateVendibility(jxcontext.AdminCtx.GetTrackInfo(), "", sm.VendorStoreID, skuVendibilityList[(i-1)*50:], jxcontext.AdminCtx.GetUserName())
|
|
||||||
} else {
|
|
||||||
jdsApi.BatchUpdateVendibility(jxcontext.AdminCtx.GetTrackInfo(), "", sm.VendorStoreID, skuVendibilityList[(i-1)*50:i*50], jxcontext.AdminCtx.GetUserName())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Errorf("京东运行结束")
|
|
||||||
}
|
|
||||||
@@ -1,182 +0,0 @@
|
|||||||
package enterprise_session
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
enterprise "git.rosy.net.cn/baseapi/platformapi/enterprise_wechat"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/auth2"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/authz"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/authz/autils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxstore/cms"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type CreateSession struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建老板的业务群
|
|
||||||
func (c *CreateSession) CreateBossToStaffAndCreateSession(token string, storeId int) (map[string]interface{}, error) {
|
|
||||||
// 获取老本的电话和门店信息
|
|
||||||
authInfo, err := auth2.GetTokenInfo(token)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
store, err := dao.GetStoreDetail2(dao.GetDB(), storeId, "", 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if store.Tel1 != authInfo.Mobile || store.Tel1 == "" {
|
|
||||||
return nil, errors.New("不是门店老板,不创建群聊")
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检测用户是否存在
|
|
||||||
if _, err := CheckUserExist(store); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取创建群聊所需基础人员id
|
|
||||||
enterpriseIdList, err := CheckBoosGroupChat(store)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
result := make(map[string]interface{}, 0)
|
|
||||||
result["enterpriseIdList"] = enterpriseIdList
|
|
||||||
result["chatName"] = "京西菜市" + store.Name + "群"
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检测用户是否存在
|
|
||||||
func CheckUserExist(store *dao.StoreDetail2) (string, error) {
|
|
||||||
enterpriseUserId, err := api.EnterpriseChatHeadApi.GetUserIdByMobile(store.Tel1)
|
|
||||||
if strings.Contains(fmt.Sprintf("%v", err), "user no exist") || strings.Contains(fmt.Sprintf("%v", err), "46004") {
|
|
||||||
boss := &enterprise.CreateBoos2JXStaffReq{
|
|
||||||
Userid: store.Tel1 + "_" + strconv.Itoa(store.ID),
|
|
||||||
Name: store.LicenceOwnerName,
|
|
||||||
Alias: "",
|
|
||||||
Mobile: store.Tel1,
|
|
||||||
Department: nil, // 四川省
|
|
||||||
Order: nil,
|
|
||||||
Gender: "1",
|
|
||||||
Email: "",
|
|
||||||
IsLeaderInDept: nil,
|
|
||||||
Enable: 0,
|
|
||||||
AvatarMediaid: "",
|
|
||||||
Telephone: "",
|
|
||||||
Address: store.Address,
|
|
||||||
Extattr: enterprise.Extattr{},
|
|
||||||
MainDepartment: 0,
|
|
||||||
ToInvite: true,
|
|
||||||
ExternalPosition: "",
|
|
||||||
ExternalProfile: enterprise.ExternalProfile{},
|
|
||||||
}
|
|
||||||
if boss.Name == "" {
|
|
||||||
boss.Name = store.Name + "(老板名称不存在)"
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询本门店所属省code
|
|
||||||
parentCityName := ""
|
|
||||||
if store.CityCode == 0 {
|
|
||||||
return "", errors.New("门店位置不能为空")
|
|
||||||
}
|
|
||||||
parentCityName, err = GetCityCode(store.CityCode)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
// 查询企业微信所有省份部门分类
|
|
||||||
departmentList, err := api.EnterpriseChatHeadApi.GetAllDepartmentList()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
for _, v := range departmentList {
|
|
||||||
if !strings.Contains(v.Name, parentCityName[:6]) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
boss.Department = []int{v.ID}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建老板为京西员工,并存放在对应的省份里面
|
|
||||||
if err := api.EnterpriseChatHeadApi.CreateBoss2JxStaff(boss); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
enterpriseUserId = boss.Userid
|
|
||||||
}
|
|
||||||
|
|
||||||
return enterpriseUserId, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetCityCode(cityCode int) (string, error) {
|
|
||||||
for i := 0; i < 4; i++ {
|
|
||||||
place, err := dao.GetPlaceByCode(dao.GetDB(), cityCode)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if place.Level == model.YES && place.ParentCode == 0 {
|
|
||||||
return place.Name, nil
|
|
||||||
}
|
|
||||||
cityCode = place.ParentCode
|
|
||||||
}
|
|
||||||
return "", errors.New("未查询到目标城市")
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取当前门店企业内部人员信息
|
|
||||||
func CheckBoosGroupChat(store *dao.StoreDetail2) ([]string, error) {
|
|
||||||
// 获取门店角色
|
|
||||||
roleNames := []string{"StoreBoss"}
|
|
||||||
storeIDs := []int{store.ID}
|
|
||||||
var roleList []*authz.RoleInfo
|
|
||||||
for _, roleName := range roleNames {
|
|
||||||
if roleName == authz.StoreRoleBoss {
|
|
||||||
for _, storeID := range storeIDs {
|
|
||||||
roleList = append(roleList, autils.NewRole(roleName, storeID))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
roleList = append(roleList, autils.NewRole(roleName, 0))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
retVal, err := cms.GetRolesUserList(nil, roleList)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取角色系统userId
|
|
||||||
systemUserId := make([]string, 0, 0)
|
|
||||||
for _, v := range retVal {
|
|
||||||
if len(v) == 0 {
|
|
||||||
return nil, errors.New("门店负责人为空,数据异常.联系管理员")
|
|
||||||
}
|
|
||||||
systemUserId = append(systemUserId, v...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 根据userId获取系统用户电话号码
|
|
||||||
userList, _, err := dao.GetUsers(dao.GetDB(), 0, "", systemUserId, nil, nil, 0, 50)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
enterpriseList := make([]string, 0, 0)
|
|
||||||
// 获取用户企业微信用户id
|
|
||||||
for _, v := range userList {
|
|
||||||
enterpriseId, err := api.EnterpriseChatHeadApi.GetUserIdByMobile(*v.Mobile)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
enterpriseList = append(enterpriseList, enterpriseId)
|
|
||||||
}
|
|
||||||
return enterpriseList, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取企业微信token
|
|
||||||
func GetEnterpriseTokenInfo() (string, string) {
|
|
||||||
api.EnterpriseChatMin.CheckAccessTokenExpiresIn()
|
|
||||||
api.EnterpriseChatHeadApi.CheckAccessTokenExpiresIn()
|
|
||||||
return api.EnterpriseChatMin.ReturnToken(), api.EnterpriseChatHeadApi.ReturnToken()
|
|
||||||
// 企业微信api
|
|
||||||
//return api.EnterpriseChatHeadApi.ReturnToken()
|
|
||||||
}
|
|
||||||
@@ -1,188 +0,0 @@
|
|||||||
package auto_delivery
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/rand"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/tao_vegetable"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler/defsch"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
|
||||||
"math/big"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
)
|
|
||||||
|
|
||||||
var riderListInfo = make(map[string][]map[string]string, 0)
|
|
||||||
|
|
||||||
func Init() {
|
|
||||||
if len(riderListInfo) != 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
db := dao.GetDB()
|
|
||||||
// 骑手列表
|
|
||||||
configRiderList, err := dao.QueryConfigs(db, "riderList", "Sys", "")
|
|
||||||
if err != nil {
|
|
||||||
globals.SugarLogger.Errorf("抖音自动刷单获取骑手列表错误:%v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
list := make(map[string][]map[string]string, 0)
|
|
||||||
if len(configRiderList[0].Value) > 0 {
|
|
||||||
if err := json.Unmarshal([]byte(configRiderList[0].Value), &list); err != nil {
|
|
||||||
globals.SugarLogger.Errorf("抖音自动刷单获取骑手列表错误:%v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取刷单地址
|
|
||||||
addressList, err := dao.QueryConfigs(db, "refundAddress", "Sys", "")
|
|
||||||
if err != nil {
|
|
||||||
globals.SugarLogger.Errorf("抖音自动刷单获取刷单地址列表错误:%v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range strings.Split(addressList[0].Value, ",") {
|
|
||||||
if _, ok := list[v]; ok && len(list[v]) >= 200 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
riderList, err := dao.GetAddressRiderInfo(db, v)
|
|
||||||
if err != nil {
|
|
||||||
globals.SugarLogger.Errorf("初始化各省份骑手信息错误:[%v]", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
addressRiderList := make([]map[string]string, 0)
|
|
||||||
for i := 0; i < len(riderList); i++ {
|
|
||||||
if len(riderList[i].CourierMobile) == 11 {
|
|
||||||
riderMap := make(map[string]string, 1)
|
|
||||||
riderMap[riderList[i].CourierName] = riderList[i].CourierMobile
|
|
||||||
addressRiderList = append(addressRiderList, riderMap)
|
|
||||||
}
|
|
||||||
if len(addressRiderList) >= 200 {
|
|
||||||
list[v] = addressRiderList
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
listStr, err := json.Marshal(list)
|
|
||||||
if err != nil {
|
|
||||||
globals.SugarLogger.Errorf("Marshal 骑手信息错误:[%v]", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := dao.UpdateOperatorConfig(string(listStr), "Sys", "riderList"); err != nil {
|
|
||||||
globals.SugarLogger.Errorf("UpdateOperatorConfig 骑手配置信息错误:[%v]", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
riderListInfo = list
|
|
||||||
}
|
|
||||||
|
|
||||||
// AutoSettingFakeDelivery 抖音自动设置骑手, 推送假订单
|
|
||||||
func AutoSettingFakeDelivery() {
|
|
||||||
db := dao.GetDB()
|
|
||||||
|
|
||||||
// 查询需要刷单的门店
|
|
||||||
configList, err := dao.QueryConfigs(db, "storeIdList", "Sys", "")
|
|
||||||
if err != nil {
|
|
||||||
globals.SugarLogger.Errorf("抖音自动刷单获取刷单门店列表错误:%v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if len(configList) != model.YES {
|
|
||||||
globals.SugarLogger.Errorf("newConfig 刷单门店设置异常")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取刷单门店订单
|
|
||||||
storeList := strings.Split(configList[0].Value, ",")
|
|
||||||
for _, v := range storeList {
|
|
||||||
if !strings.Contains(v, "-") {
|
|
||||||
globals.SugarLogger.Errorf("newConfig 刷单门店配置异常")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
storeIdAndVendorId := strings.Split(v, "-")
|
|
||||||
if len(storeIdAndVendorId) == model.NO {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
orderList, err := dao.GetOrderListByStoreList(db, []int64{utils.Str2Int64(storeIdAndVendorId[0])}, utils.Str2Int(storeIdAndVendorId[1]))
|
|
||||||
if err != nil {
|
|
||||||
globals.SugarLogger.Errorf("获取门店刷单记录错误")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if len(orderList) == model.NO {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1.根据订单客户地址获取骑手列表
|
|
||||||
riderKey := ""
|
|
||||||
storeDetail, _ := dao.GetStoreDetail(db, utils.Str2Int(storeIdAndVendorId[0]), 0, "")
|
|
||||||
if strings.Contains(storeDetail.Address, "重庆") || strings.Contains(storeDetail.Address, "上海") || strings.Contains(storeDetail.Address, "北京") || strings.Contains(storeDetail.Address, "天津") {
|
|
||||||
riderKey = strings.Split(storeDetail.Address, "市")[0]
|
|
||||||
} else if strings.Contains(storeDetail.Address, "省") {
|
|
||||||
riderKey = strings.Split(storeDetail.Address, "省")[0]
|
|
||||||
} else {
|
|
||||||
place, err := dao.GetParentCodeByCode(db, storeDetail.CityCode)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if strings.Contains(place.Name, "省") {
|
|
||||||
riderKey = strings.Split(place.Name, "省")[0]
|
|
||||||
} else {
|
|
||||||
riderKey = strings.Split(place.Name, "市")[0]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, order := range orderList {
|
|
||||||
if len(riderListInfo[riderKey]) == model.NO {
|
|
||||||
// 骑手列表
|
|
||||||
configRiderList, err := dao.QueryConfigs(db, "riderList", "Sys", "")
|
|
||||||
if err != nil {
|
|
||||||
globals.SugarLogger.Errorf("抖音自动刷单获取骑手列表错误:%v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := json.Unmarshal([]byte(configRiderList[0].Value), &riderListInfo); err != nil {
|
|
||||||
globals.SugarLogger.Errorf("抖音自动刷单获取骑手列表错误:%v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
randNumber, _ := rand.Int(rand.Reader, big.NewInt(int64(len(riderListInfo[riderKey]))))
|
|
||||||
randTime := randNumber.Int64()
|
|
||||||
if randTime < 0 {
|
|
||||||
randTime = 1
|
|
||||||
}
|
|
||||||
if randTime >= int64(len(riderListInfo[riderKey])) {
|
|
||||||
randTime = int64(len(riderListInfo[riderKey])) - 1
|
|
||||||
}
|
|
||||||
if (order.PhoneAscription == "" || strings.Split(order.PhoneAscription, "-")[0] != model.PhoneAscriptionAddressYes) && order.VendorID == model.VendorIDDD {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// 自动拣货
|
|
||||||
if order.Status < model.OrderStatusFinishedPickup { // 未拣货
|
|
||||||
handler := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID)
|
|
||||||
flag := model.IsOrderDeliveryByStore(order) || model.IsOrderDeliveryBySelf(order)
|
|
||||||
if err := handler.PickupGoods(order, flag, jxcontext.AdminCtx.GetUserName()); err != nil {
|
|
||||||
partner.CurOrderManager.OnOrderMsg(order, tao_vegetable.OrderStatusPickedUp, fmt.Sprintf("自动拣货错误:[%v]", err))
|
|
||||||
break
|
|
||||||
}
|
|
||||||
partner.CurOrderManager.OnOrderMsg(order, tao_vegetable.OrderStatusPickedUp, "fake自动拣货,已拣货")
|
|
||||||
}
|
|
||||||
//自动发单
|
|
||||||
if len(riderListInfo[riderKey]) == 0 {
|
|
||||||
globals.SugarLogger.Errorf("riderListInfo[riderKey][randTime] :%s,%s,%d", riderListInfo[riderKey][randTime], riderKey, randTime)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
for riderName, riderPhone := range riderListInfo[riderKey][randTime] {
|
|
||||||
if err := defsch.FixedScheduler.SelfDeliveringAndUpdateStatus(jxcontext.AdminCtx, order.VendorOrderID, order.VendorID, jxcontext.AdminCtx.GetUserName(), riderName, riderPhone); err != nil {
|
|
||||||
partner.CurOrderManager.OnOrderMsg(order, tao_vegetable.OrderStatusPickedUp, fmt.Sprintf("自动发货错误:[%v]", err))
|
|
||||||
break
|
|
||||||
}
|
|
||||||
partner.CurOrderManager.OnOrderMsg(order, tao_vegetable.OrderStatusCallRider, "自动发货,出库")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
package orderman
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/netprinter"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/weixinmsg"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner/purchase/jd"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (c *OrderManager) OnNewFakeJdOrder(vendorOrderID string) (err error) {
|
|
||||||
utils.CallFuncAsync(func() {
|
|
||||||
orderInfo, err := api.FakeJdAPI.FakeQuerySingleOrderRaw(vendorOrderID)
|
|
||||||
if err == nil {
|
|
||||||
order := jd.Map2Order(orderInfo)
|
|
||||||
jxutils.RefreshOrderSkuRelated(order)
|
|
||||||
err = c.notifyNewFakeJdOrder(order)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
globals.SugarLogger.Warnf("OnNewFakeJdOrder failed with err:%v", err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *OrderManager) notifyNewFakeJdOrder(order *model.GoodsOrder) (err error) {
|
|
||||||
db := dao.GetDB()
|
|
||||||
storeDetail, err := dao.GetStoreDetailByVendorStoreID(db, order.VendorStoreID, model.VendorIDJD, "")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
realStoreID := storeDetail.ID
|
|
||||||
if storeDetail.LinkStoreID != 0 {
|
|
||||||
realStoreID = storeDetail.LinkStoreID
|
|
||||||
}
|
|
||||||
notifyWxNewFakeJdOrder(order, realStoreID)
|
|
||||||
netprinter.PrintOrderByOrder4Store(jxcontext.AdminCtx, order, realStoreID, "", nil)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func notifyWxNewFakeJdOrder(order *model.GoodsOrder, storeID int) (err error) {
|
|
||||||
sb := new(strings.Builder)
|
|
||||||
sb.WriteString("老板,你有新订单了\n")
|
|
||||||
sb.WriteString(fmt.Sprintf("订单号:%s\n", order.VendorOrderID))
|
|
||||||
sb.WriteString("送达时间:")
|
|
||||||
if order.BusinessType == model.BusinessTypeDingshida {
|
|
||||||
sb.WriteString(utils.Time2Str(order.ExpectedDeliveredTime))
|
|
||||||
} else {
|
|
||||||
sb.WriteString("立即达")
|
|
||||||
}
|
|
||||||
sb.WriteString("\n")
|
|
||||||
sb.WriteString(fmt.Sprintf("买家:%s\n", order.ConsigneeName))
|
|
||||||
sb.WriteString(fmt.Sprintf("电话:%s\n", order.ConsigneeMobile))
|
|
||||||
sb.WriteString(fmt.Sprintf("收货地址:%s\n", order.ConsigneeAddress))
|
|
||||||
sb.WriteString("商品详情:\n")
|
|
||||||
for _, sku := range order.Skus {
|
|
||||||
sb.WriteString(fmt.Sprintf("\t%s*%d\n", sku.SkuName, sku.Count))
|
|
||||||
}
|
|
||||||
title := fmt.Sprintf("你有到家菜市新订单%d", order.OrderSeq)
|
|
||||||
content := sb.String()
|
|
||||||
_, err = weixinmsg.SendStoreMessage(jxcontext.AdminCtx, title, content, []int{storeID}, nil, "", model.MessageTypeStore, true, true)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
package orderman
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestOnNewFakeJdOrder(t *testing.T) {
|
|
||||||
err := FixedOrderManager.OnNewFakeJdOrder("2002984074001021")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
time.Sleep(3 * time.Second)
|
|
||||||
}
|
|
||||||
@@ -1,252 +0,0 @@
|
|||||||
package orderman
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
TotalRate = 200 // 总费率(千分之200)= 第三方平台费+京西品牌费+京西服务费,现阶段都是合计200‰
|
|
||||||
MaxFreightMoneyFromJxByShop = 7 // 商家自送实际转美团/达达后由商家承担的运费金额上限
|
|
||||||
)
|
|
||||||
|
|
||||||
// 处理正向订单结账信息
|
|
||||||
func (c *OrderManager) SaveOrderFinancialInfo(order *model.OrderFinancial, operation string) (err error) {
|
|
||||||
db := dao.GetDB()
|
|
||||||
txDB, _ := dao.Begin(db)
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil || err != nil {
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
if r != nil {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
if operation == partner.UpdatedPeration {
|
|
||||||
// db := orm.NewOrm()
|
|
||||||
err = utils.CallFuncLogError(func() error {
|
|
||||||
_, err = dao.ExecuteSQL(db, "DELETE FROM order_financial WHERE vendor_order_id = ? AND vendor_id = ?", order.VendorOrderID, order.VendorID)
|
|
||||||
return err
|
|
||||||
}, "SaveOrderFinancialInfo delete order_financial, orderID:%s", order.VendorOrderID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = utils.CallFuncLogError(func() error {
|
|
||||||
_, err = dao.ExecuteSQL(db, "DELETE FROM order_sku_financial WHERE vendor_order_id = ? AND vendor_id = ? AND is_afs_order = 0", order.VendorOrderID, order.VendorID)
|
|
||||||
return err
|
|
||||||
}, "SaveOrderFinancialInfo delete order_sku_financial, orderID:%s", order.VendorOrderID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = utils.CallFuncLogError(func() error {
|
|
||||||
_, err = dao.ExecuteSQL(db, "DELETE FROM order_discount_financial WHERE vendor_order_id = ? AND vendor_id = ?", order.VendorOrderID, order.VendorID)
|
|
||||||
return err
|
|
||||||
}, "SaveOrderFinancialInfo delete order_discount_financial, orderID:%s", order.VendorOrderID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, activity := range order.Discounts {
|
|
||||||
if err = dao.CreateEntity(db, activity); err != nil {
|
|
||||||
if !dao.IsDuplicateError(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
order.ShopMoneyByCal = order.SalePriceMoney - order.TotalDiscountMoney - order.PointsDeductionMoney + order.PmFreightDiscountMoney - order.DistanceFreightMoney - order.FreightTipsMoney - order.DonationMoney + order.SelfDeliveryDiscountMoney + order.PmSubsidyMoney + order.SkuBoxMoney + order.BoxMoney - order.PmMoney
|
|
||||||
order.JxPmMoney = utils.Float64TwoInt64(float64(order.ShopMoney+order.PmMoney)*TotalRate/1000) - order.PmMoney // 京西平台费 = 总金额*20%-第三方平台费
|
|
||||||
if order.JxPmMoney < 0 { // 如果算出京西平台费为负数,则置0
|
|
||||||
order.JxPmMoney = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
order.JxShopMoney = order.ShopMoney - order.JxPmMoney + order.JxSubsidyMoney - order.JxFreightMoneyByShop
|
|
||||||
// 订单结算金额拆分计算,拆分到单条sku
|
|
||||||
// 先获取订单主体优惠金额
|
|
||||||
platOrderGoodsDiscountMoney := order.PmSubsidyMoney - order.PmSkuSubsidyMoney + order.SelfDeliveryDiscountMoney
|
|
||||||
// 结算平台扣除项汇总---平台佣金,商家设置运费减免,远距离费,小费,公益捐款、、、、
|
|
||||||
deductionsByPm := order.FreightDiscountMoney + order.DistanceFreightMoney + order.FreightTipsMoney + order.DonationMoney + order.PmMoney
|
|
||||||
// 结算京西扣除项汇总---京西佣金,京西配送运费
|
|
||||||
deductionsByJx := order.JxPmMoney + order.JxFreightMoneyByShop
|
|
||||||
for _, sku := range order.Skus[1:] {
|
|
||||||
// 用户支付菜品金额,用户为这一条sku支付的菜品金额
|
|
||||||
sku.UserMoney = utils.Float64TwoInt64(float64(order.SalePriceMoney-order.DiscountMoney-order.PointsDeductionMoney+order.BoxMoney+order.SkuBoxMoney) * float64(sku.SalePrice*int64(sku.Count)+sku.SkuBoxMoney) / float64(order.SalePriceMoney+order.SkuBoxMoney)) // 林峰确认,比如49-2满减,算餐盒费满49元,不算餐盒费不足49元,是可以参加满减活动的,那么餐盒费也应该和商品金额一起进行折算
|
|
||||||
order.Skus[0].UserMoney += sku.UserMoney
|
|
||||||
// 计算平台订单主体补贴拆分到单条sku的金额 + sku.PmSubsidyMoneyForSku
|
|
||||||
sku.PmSubsidyMoney = sku.PmSkuSubsidyMoney + utils.Float64TwoInt64(float64(platOrderGoodsDiscountMoney*sku.SalePrice*int64(sku.Count)+sku.SkuBoxMoney)/float64(order.SalePriceMoney+order.SkuBoxMoney))
|
|
||||||
order.Skus[0].PmSubsidyMoney += sku.PmSubsidyMoney
|
|
||||||
// 计算京西满减补贴拆分到单条sku的金额 + sku.JxSubsidyMoneyForSku
|
|
||||||
sku.JxSubsidyMoney = sku.JxSkuSubsidyMoney + utils.Float64TwoInt64(float64(order.JxSubsidyMoney-order.PmSkuSubsidyMoney)*float64(sku.SalePrice*int64(sku.Count)+sku.SkuBoxMoney)/float64(order.SalePriceMoney+order.SkuBoxMoney))
|
|
||||||
order.Skus[0].JxSubsidyMoney += sku.JxSubsidyMoney
|
|
||||||
// 计算单条sku需要承担的平台扣费金额
|
|
||||||
sku.PmDeductionsMoney = utils.Float64TwoInt64(float64(deductionsByPm) * (float64(sku.UserMoney + sku.PmSubsidyMoney)) / (float64(order.SalePriceMoney + order.BoxMoney + order.SkuBoxMoney - order.DiscountMoney - order.PointsDeductionMoney + order.PmSubsidyMoney)))
|
|
||||||
order.Skus[0].PmDeductionsMoney += sku.PmDeductionsMoney
|
|
||||||
// 计算单条sku平台应该结算给京西的金额
|
|
||||||
sku.ShopMoneyByCal = sku.UserMoney + sku.PmSubsidyMoney - sku.PmDeductionsMoney
|
|
||||||
order.Skus[0].ShopMoneyByCal += sku.ShopMoneyByCal
|
|
||||||
// j计算单条sku需要承担的京西扣费金额
|
|
||||||
sku.JxDeductionsMoney = utils.Float64TwoInt64(float64(deductionsByJx*sku.ShopMoneyByCal) / float64(order.ShopMoney))
|
|
||||||
order.Skus[0].JxDeductionsMoney += sku.JxDeductionsMoney
|
|
||||||
// 计算单条sku京西应该结算给商家的金额
|
|
||||||
sku.JxShopMoney = sku.ShopMoneyByCal + sku.JxSubsidyMoney - sku.JxDeductionsMoney
|
|
||||||
order.Skus[0].JxShopMoney += sku.JxShopMoney
|
|
||||||
if sku.SkuID >= math.MaxInt32 {
|
|
||||||
sku.SkuID = sku.JxSkuID
|
|
||||||
}
|
|
||||||
if err = dao.CreateEntity(db, sku); err != nil {
|
|
||||||
if !dao.IsDuplicateError(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(order.Skus) > 0 {
|
|
||||||
sku := order.Skus[0]
|
|
||||||
if sku.SkuID > math.MaxInt32 {
|
|
||||||
sku.SkuID = sku.JxSkuID
|
|
||||||
}
|
|
||||||
sku.UserMoney = order.SalePriceMoney - order.DiscountMoney - sku.UserMoney
|
|
||||||
sku.PmSubsidyMoney = platOrderGoodsDiscountMoney + order.SelfDeliveryDiscountMoney - sku.PmSubsidyMoney
|
|
||||||
sku.JxSubsidyMoney = order.JxSubsidyMoney - sku.JxSubsidyMoney
|
|
||||||
sku.PmDeductionsMoney = deductionsByPm - sku.PmDeductionsMoney
|
|
||||||
sku.ShopMoneyByCal = order.ShopMoney - sku.ShopMoneyByCal
|
|
||||||
sku.JxDeductionsMoney = deductionsByJx - sku.JxDeductionsMoney
|
|
||||||
sku.JxShopMoney = order.JxShopMoney - sku.JxShopMoney
|
|
||||||
if err = dao.CreateEntity(db, sku); err != nil {
|
|
||||||
if !dao.IsDuplicateError(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
globals.SugarLogger.Warnf("On SaveOrderSkuFinancialInfo order.VendorOrderID:%s err: order have no sku", order.VendorOrderID)
|
|
||||||
}
|
|
||||||
// 加上京西对单条sku的补贴,再存数据库
|
|
||||||
order.JxSubsidyMoney += order.JxSkuSubsidyMoney
|
|
||||||
if err = dao.CreateEntity(db, order); err != nil {
|
|
||||||
if !dao.IsDuplicateError(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
dao.Commit(db, txDB)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理售后订单结账信息
|
|
||||||
func (c *OrderManager) SaveAfsOrderFinancialInfo(afsOrder *model.AfsOrder) (err error) {
|
|
||||||
db := dao.GetDB()
|
|
||||||
txDB, _ := dao.Begin(db)
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil || err != nil {
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
if r != nil {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
// 平台结算扣除汇总--平台补贴,售后产生运费,平台收包装费,同城运费、、、
|
|
||||||
deductionsByPm := afsOrder.PmSubsidyMoney + afsOrder.AfsFreightMoney + afsOrder.BoxMoney + afsOrder.TongchengFreightMoney
|
|
||||||
afsOrder.RefundMoneyByCal = afsOrder.SkuUserMoney + afsOrder.FreightUserMoney + deductionsByPm - afsOrder.PmRefundMoney
|
|
||||||
// order.TotalMoney += order.SkuJxMoney // 退款单京西补贴部分先不作计算
|
|
||||||
if err = dao.CreateEntity(db, afsOrder); err != nil {
|
|
||||||
if !dao.IsDuplicateError(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 京西结算扣除汇总,先不作计算,计算单条sku最终扣款金额(+该条sku承担的平台结算扣除金额)
|
|
||||||
for _, orderSku := range afsOrder.Skus[1:] {
|
|
||||||
orderSku.RefundMoneyByCal = orderSku.PmSkuSubsidyMoney +
|
|
||||||
utils.Float64TwoInt64(float64(afsOrder.RefundMoneyByCal-afsOrder.PmSkuSubsidyMoney)*float64(orderSku.UserMoney+orderSku.PmSubsidyMoney-orderSku.PmSkuSubsidyMoney)/float64(afsOrder.SkuUserMoney+afsOrder.PmSubsidyMoney-afsOrder.PmSkuSubsidyMoney))
|
|
||||||
afsOrder.Skus[0].RefundMoneyByCal += orderSku.RefundMoneyByCal
|
|
||||||
if err = dao.CreateEntity(db, orderSku); err != nil {
|
|
||||||
if !dao.IsDuplicateError(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(afsOrder.Skus) > 0 {
|
|
||||||
orderSku := afsOrder.Skus[0]
|
|
||||||
orderSku.RefundMoneyByCal = afsOrder.RefundMoneyByCal - orderSku.RefundMoneyByCal
|
|
||||||
if err = dao.CreateEntity(db, orderSku); err != nil {
|
|
||||||
if !dao.IsDuplicateError(err) {
|
|
||||||
globals.SugarLogger.Warnf("On SaveAfsOrderFinancialInfo afsOrder.AfsOrderID:%s err: SaveAfsOrderSku is err", afsOrder.AfsOrderID)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
globals.SugarLogger.Warnf("On SaveAfsOrderFinancialInfo afsOrder.AfsOrderID:%s err: afsOrder have no sku", afsOrder.AfsOrderID)
|
|
||||||
}
|
|
||||||
dao.Commit(db, txDB)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 转自送实际使用美团/达达配送,调用此方法
|
|
||||||
func (c *OrderManager) UpdataOrderFinancialInfo(orderFinancial *model.OrderFinancial, wayBill *model.Waybill) (err error) {
|
|
||||||
// 通过本地数据库去取是否转美团/达达,并计算运费,写在上级调用函数里面传递过来
|
|
||||||
//wayBill, err2 := partner.CurOrderManager.LoadWaybill(orderFinancial.VendorOrderID, orderFinancial.VendorID)
|
|
||||||
//if err = err2; err == nil {
|
|
||||||
// orderFinancial.JxFreightMoney = wayBill.DesiredFee
|
|
||||||
//}
|
|
||||||
db := dao.GetDB()
|
|
||||||
txDB, _ := dao.Begin(db)
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil || err != nil {
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
if r != nil {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
orderFinancial.JxFreightMoney = wayBill.DesiredFee
|
|
||||||
if (orderFinancial.JxFreightMoney - orderFinancial.SelfDeliveryDiscountMoney) > MaxFreightMoneyFromJxByShop {
|
|
||||||
orderFinancial.JxFreightMoneyByShop = orderFinancial.SelfDeliveryDiscountMoney + MaxFreightMoneyFromJxByShop
|
|
||||||
} else if (orderFinancial.JxFreightMoney - orderFinancial.SelfDeliveryDiscountMoney) < 0 {
|
|
||||||
orderFinancial.JxFreightMoneyByShop = orderFinancial.SelfDeliveryDiscountMoney
|
|
||||||
} else {
|
|
||||||
orderFinancial.JxFreightMoneyByShop = orderFinancial.JxFreightMoney
|
|
||||||
}
|
|
||||||
orderFinancial.JxShopMoney -= orderFinancial.JxFreightMoneyByShop
|
|
||||||
// orderFinancial.JxFreightMoneyByShop 的改变直接影响到单条sku的京西结算金额的改变
|
|
||||||
jxDecMoney := orderFinancial.JxFreightMoneyByShop
|
|
||||||
for _, sku := range orderFinancial.Skus[1:] {
|
|
||||||
// 重新计算单条sku京西应该结算的金额
|
|
||||||
skuJxDecMoney := utils.Float64TwoInt64(float64(jxDecMoney*sku.SalePrice*int64(sku.Count)+sku.SkuBoxMoney) / float64(orderFinancial.SalePriceMoney+orderFinancial.SkuBoxMoney))
|
|
||||||
sku.JxDeductionsMoney += skuJxDecMoney
|
|
||||||
sku.JxShopMoney -= skuJxDecMoney
|
|
||||||
jxDecMoney -= skuJxDecMoney
|
|
||||||
if _, err = dao.UpdateEntity(db, sku); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(orderFinancial.Skus) > 0 {
|
|
||||||
sku := orderFinancial.Skus[0]
|
|
||||||
sku.JxDeductionsMoney += jxDecMoney
|
|
||||||
sku.JxShopMoney -= jxDecMoney
|
|
||||||
if _, err = dao.UpdateEntity(db, sku); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err = dao.CreateEntity(db, orderFinancial); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
dao.Commit(db, txDB)
|
|
||||||
// orderFinancial 和 OrderSkuFinancial 数据计算完毕,准备进行更新
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,447 +0,0 @@
|
|||||||
package orderman
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
"github.com/astaxie/beego/client/orm"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (c *OrderManager) LoadAfsOrder(vendorAfsOrderID string, vendorID int) (afsOrder *model.AfsOrder, err error) {
|
|
||||||
return c.loadAfsOrder(dao.GetDB(), vendorAfsOrderID, vendorID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *OrderManager) loadAfsOrder(db *dao.DaoDB, vendorAfsOrderID string, vendorID int) (afsOrder *model.AfsOrder, err error) {
|
|
||||||
afsOrder = &model.AfsOrder{
|
|
||||||
AfsOrderID: vendorAfsOrderID,
|
|
||||||
VendorID: vendorID,
|
|
||||||
}
|
|
||||||
if err = dao.GetEntity(db, afsOrder, "AfsOrderID", "VendorID"); err != nil {
|
|
||||||
afsOrder = nil
|
|
||||||
}
|
|
||||||
return afsOrder, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *OrderManager) OnAfsOrderAdjust(afsOrder *model.AfsOrder, orderStatus *model.OrderStatus) (err error) {
|
|
||||||
return c.onAfsOrderNew(afsOrder, orderStatus, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *OrderManager) OnAfsOrderNew(afsOrder *model.AfsOrder, orderStatus *model.OrderStatus) (err error) {
|
|
||||||
return c.onAfsOrderNew(afsOrder, orderStatus, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *OrderManager) onAfsOrderNew(afsOrder *model.AfsOrder, orderStatus *model.OrderStatus, isAdjust bool) (err error) {
|
|
||||||
db := dao.GetDB()
|
|
||||||
c.setAfsOrderID(db, orderStatus)
|
|
||||||
if afsOrder.AfsOrderID == "" {
|
|
||||||
afsOrder.AfsOrderID = orderStatus.VendorOrderID
|
|
||||||
}
|
|
||||||
if afsOrder.VendorStatus == "" {
|
|
||||||
afsOrder.VendorStatus = orderStatus.VendorStatus
|
|
||||||
}
|
|
||||||
if afsOrder.Status == model.OrderStatusUnknown {
|
|
||||||
afsOrder.Status = orderStatus.Status
|
|
||||||
}
|
|
||||||
if order, _ := c.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID); order != nil {
|
|
||||||
if order.ConsigneeMobile2 == "" {
|
|
||||||
if handler := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID); handler != nil {
|
|
||||||
if order2, _ := handler.GetOrder(order.VendorOrgCode, order.VendorOrderID, order.VendorStoreID); order2 != nil && order.ConsigneeMobile != order2.ConsigneeMobile {
|
|
||||||
order.ConsigneeMobile = order2.ConsigneeMobile
|
|
||||||
c.UpdateOrderFields(order, []string{"ConsigneeMobile"})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
txDB, _ := dao.Begin(db)
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil || err != nil {
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
isDuplicated, err := addOrderOrWaybillStatus(orderStatus, db)
|
|
||||||
if err != nil || (isDuplicated && orderStatus.VendorID != model.VendorIDJX) {
|
|
||||||
if err == nil {
|
|
||||||
dao.Commit(db, txDB)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
existAfsOrder, err := c.loadAfsOrder(db, afsOrder.AfsOrderID, afsOrder.VendorID)
|
|
||||||
if err != nil {
|
|
||||||
if !dao.IsNoRowsError(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if existAfsOrder != nil {
|
|
||||||
if existAfsOrder.Status < model.AfsOrderStatusFinished {
|
|
||||||
// todo 可能导致状态回绕
|
|
||||||
existAfsOrder.Status = afsOrder.Status
|
|
||||||
existAfsOrder.VendorStatus = afsOrder.VendorStatus
|
|
||||||
if _, err = dao.UpdateEntity(db, existAfsOrder, "Status", "VendorStatus", "AfsFinishedAt"); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
afsOrder = existAfsOrder
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// 全退都要先全删除再建
|
|
||||||
if afsOrder.RefundType == model.AfsTypeFullRefund {
|
|
||||||
isAdjust = true
|
|
||||||
}
|
|
||||||
if err = c.SaveAfsOrder(db, afsOrder, isAdjust); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dao.Commit(db, txDB)
|
|
||||||
scheduler.CurrentScheduler.OnAfsOrderNew(afsOrder, false)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *OrderManager) SaveAfsOrder(db *dao.DaoDB, afsOrder *model.AfsOrder, isDeleteFirst bool) (err error) {
|
|
||||||
if db == nil {
|
|
||||||
db = dao.GetDB()
|
|
||||||
}
|
|
||||||
if err = c.updateAfsOrderOtherInfo(db, afsOrder); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
txDB, _ := dao.Begin(db)
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil || err != nil {
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
if r != nil {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
if isDeleteFirst {
|
|
||||||
err = utils.CallFuncLogError(func() error {
|
|
||||||
_, err = dao.DeleteEntity(db, afsOrder, "VendorOrderID", "VendorID")
|
|
||||||
return err
|
|
||||||
}, "SaveAfsOrder delete AfsOrder, afsOrderID:%s", afsOrder.AfsOrderID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = utils.CallFuncLogError(func() error {
|
|
||||||
_, err = dao.DeleteEntity(db, &model.OrderSkuFinancial{
|
|
||||||
VendorOrderID: afsOrder.VendorOrderID,
|
|
||||||
VendorID: afsOrder.VendorID,
|
|
||||||
IsAfsOrder: 1,
|
|
||||||
}, "VendorOrderID", "VendorID", "IsAfsOrder")
|
|
||||||
return err
|
|
||||||
}, "SaveAfsOrder delete OrderSkuFinancial, afsOrderID:%s", afsOrder.AfsOrderID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 平台结算扣除汇总--平台补贴,售后产生运费,平台收包装费,同城运费、、、
|
|
||||||
deductionsByPm := afsOrder.PmSubsidyMoney + afsOrder.AfsFreightMoney + afsOrder.BoxMoney + afsOrder.TongchengFreightMoney
|
|
||||||
afsOrder.RefundMoneyByCal = afsOrder.SkuUserMoney + afsOrder.FreightUserMoney + deductionsByPm - afsOrder.PmRefundMoney
|
|
||||||
// order.TotalMoney += order.SkuJxMoney // 退款单京西补贴部分先不作计算
|
|
||||||
if err = dao.CreateEntity(db, afsOrder); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 京西结算扣除汇总,先不作计算,计算单条sku最终扣款金额(+该条sku承担的平台结算扣除金额)
|
|
||||||
for _, orderSku := range afsOrder.Skus[1:] {
|
|
||||||
orderSku.RefundMoneyByCal = orderSku.PmSkuSubsidyMoney +
|
|
||||||
utils.Float64TwoInt64(float64(afsOrder.RefundMoneyByCal-afsOrder.PmSkuSubsidyMoney)*float64(orderSku.UserMoney+orderSku.PmSubsidyMoney-orderSku.PmSkuSubsidyMoney)/float64(afsOrder.SkuUserMoney+afsOrder.PmSubsidyMoney-afsOrder.PmSkuSubsidyMoney))
|
|
||||||
afsOrder.Skus[0].RefundMoneyByCal += orderSku.RefundMoneyByCal
|
|
||||||
if err = dao.CreateEntity(db, orderSku); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(afsOrder.Skus) > 0 {
|
|
||||||
orderSku := afsOrder.Skus[0]
|
|
||||||
orderSku.RefundMoneyByCal = afsOrder.RefundMoneyByCal - orderSku.RefundMoneyByCal
|
|
||||||
if err = dao.CreateEntity(db, orderSku); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
globals.SugarLogger.Warnf("On SaveAfsOrder afsOrder.AfsOrderID:%s err: afsOrder have no sku", afsOrder.AfsOrderID)
|
|
||||||
}
|
|
||||||
dao.Commit(db, txDB)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *OrderManager) OnAfsOrderStatusChanged(orderStatus *model.OrderStatus) (err error) {
|
|
||||||
db := dao.GetDB()
|
|
||||||
c.setAfsOrderID(db, orderStatus)
|
|
||||||
txDB, _ := dao.Begin(db)
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
isDuplicated, afsOrder, err := c.addAfsOrderStatus(db, orderStatus)
|
|
||||||
if err != nil || isDuplicated {
|
|
||||||
if err == nil {
|
|
||||||
dao.Commit(db, txDB)
|
|
||||||
} else {
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
dao.Commit(db, txDB)
|
|
||||||
scheduler.CurrentScheduler.OnAfsOrderStatusChanged(afsOrder, orderStatus, false)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *OrderManager) addAfsOrderStatus(db *dao.DaoDB, orderStatus *model.OrderStatus) (isDuplicated bool, order *model.AfsOrder, err error) {
|
|
||||||
if db == nil {
|
|
||||||
db = dao.GetDB()
|
|
||||||
}
|
|
||||||
isDuplicated, err = addOrderOrWaybillStatus(orderStatus, db)
|
|
||||||
//if err == nil && !isDuplicated && (orderStatus.Status != model.OrderStatusUnknown && orderStatus.Status != model.OrderStatusMsg) {
|
|
||||||
if err == nil && (orderStatus.Status != model.OrderStatusUnknown && orderStatus.Status != model.OrderStatusMsg) {
|
|
||||||
order = &model.AfsOrder{
|
|
||||||
AfsOrderID: orderStatus.VendorOrderID,
|
|
||||||
VendorID: orderStatus.VendorID,
|
|
||||||
}
|
|
||||||
if err = db.Db.ReadForUpdate(order, "AfsOrderID", "VendorID"); err == nil {
|
|
||||||
if orderStatus.Status > model.OrderStatusUnknown { // todo 要求status不能回绕
|
|
||||||
order.VendorStatus = orderStatus.VendorStatus
|
|
||||||
order.Status = orderStatus.Status
|
|
||||||
updateFields := []string{
|
|
||||||
"VendorStatus",
|
|
||||||
"Status",
|
|
||||||
}
|
|
||||||
if orderStatus.VendorID == model.VendorIDDD {
|
|
||||||
order.Flag = 0
|
|
||||||
if strings.Contains(orderStatus.VendorStatus, "cancel_refund_afsOrder") {
|
|
||||||
order.Flag = 3
|
|
||||||
}
|
|
||||||
updateFields = append(updateFields, "Flag")
|
|
||||||
}
|
|
||||||
if model.IsAfsOrderFinalStatus(orderStatus.Status) || orderStatus.Status == model.AfsOrderStatusNew {
|
|
||||||
order.AfsFinishedAt = orderStatus.StatusTime
|
|
||||||
if utils.IsTimeZero(order.AfsFinishedAt) {
|
|
||||||
order.AfsFinishedAt = time.Now()
|
|
||||||
}
|
|
||||||
updateFields = append(updateFields, "AfsFinishedAt")
|
|
||||||
if handler := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID); handler != nil {
|
|
||||||
if orderAfsInfo, err := handler.GetOrderAfsInfo(nil, order.VendorOrderID, order.AfsOrderID); err == nil && orderAfsInfo.AfsTotalShopMoney != 0 {
|
|
||||||
order.AfsTotalShopMoney = orderAfsInfo.AfsTotalShopMoney
|
|
||||||
updateFields = append(updateFields, "AfsTotalShopMoney")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_, err = dao.UpdateEntity(db, order, updateFields...)
|
|
||||||
//utils.CallFuncLogError(func() error {
|
|
||||||
// _, err = dao.UpdateEntity(db, order, updateFields...)
|
|
||||||
// return err
|
|
||||||
//}, "addAfsOrderStatus update orderID:%s, status:%v", order.VendorOrderID, orderStatus)
|
|
||||||
} else {
|
|
||||||
isDuplicated = true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 这是发现有部分订单已经完成,但是没有完成时间影响到导出结果错误
|
|
||||||
if model.IsAfsOrderFinalStatus(orderStatus.Status) || orderStatus.Status == model.AfsOrderStatusNew && order.VendorID == model.VendorIDMTWM {
|
|
||||||
if afsOrderObj, _ := partner.CurOrderManager.LoadAfsOrder(orderStatus.VendorOrderID, orderStatus.VendorID); afsOrderObj != nil {
|
|
||||||
afsOrderObj.AfsFinishedAt = time.Now()
|
|
||||||
afsOrderObj.Status = orderStatus.Status
|
|
||||||
dao.UpdateEntity(db, afsOrderObj, "AfsFinishedAt", "Status")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if dao.IsNoRowsError(err) { // todo 消息错序
|
|
||||||
err = nil
|
|
||||||
} else {
|
|
||||||
globals.SugarLogger.Warnf("addAfsOrderStatus orderID:%s read failed with error:%v", order.VendorOrderID, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return isDuplicated, order, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *OrderManager) updateAfsOrderSkuOtherInfo(db *dao.DaoDB, order *model.AfsOrder) (err error) {
|
|
||||||
jxStoreID := jxutils.GetSaleStoreIDFromAfsOrder(order)
|
|
||||||
opNumStr := "2"
|
|
||||||
if jxStoreID == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
orderSkus := order.Skus
|
|
||||||
var vendorSkuIDs []string
|
|
||||||
skuIDMap := make(map[int]int)
|
|
||||||
for _, v := range orderSkus {
|
|
||||||
if v.VendorSkuID != "" {
|
|
||||||
vendorSkuIDs = append(vendorSkuIDs, v.VendorSkuID)
|
|
||||||
}
|
|
||||||
|
|
||||||
if skuID := jxutils.GetSkuIDFromOrderSkuFinancial(v); skuID > 0 {
|
|
||||||
skuIDMap[skuID] = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(vendorSkuIDs) > 0 {
|
|
||||||
var vendorStoreID string
|
|
||||||
if order.VendorID == model.VendorIDJDShop {
|
|
||||||
vendorStoreID = model.JdShopMainVendorStoreID
|
|
||||||
} else {
|
|
||||||
vendorStoreID = order.VendorStoreID
|
|
||||||
}
|
|
||||||
l, err := dao.GetStoreSkuPriceAndWeight(db, vendorStoreID, order.VendorID, vendorSkuIDs)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
skumapper := storeSkuPriceAndWeight2Map(l)
|
|
||||||
|
|
||||||
var actStoreSkuMap *jxutils.ActStoreSkuMap
|
|
||||||
if len(skuIDMap) > 0 {
|
|
||||||
if order2, err2 := c.LoadOrder(order.VendorOrderID, order.VendorID); err2 == nil {
|
|
||||||
actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, 0, []int{order.VendorID}, model.ActTypeAll, []int{jxStoreID}, jxutils.IntMap2List(skuIDMap), order2.OrderCreatedAt, order2.OrderCreatedAt)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
actStoreSkuMap = jxutils.NewActStoreSkuMap(actStoreSkuList, false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, v := range orderSkus {
|
|
||||||
v.AfsOrderID = order.AfsOrderID
|
|
||||||
v.VendorID = order.VendorID
|
|
||||||
v.VendorOrderID = order.VendorOrderID
|
|
||||||
v.IsAfsOrder = 1
|
|
||||||
v.VendorStoreID = order.VendorStoreID
|
|
||||||
v.StoreID = order.StoreID
|
|
||||||
v.JxStoreID = jxStoreID
|
|
||||||
|
|
||||||
intVendorSkuID := utils.Str2Int64WithDefault(v.VendorSkuID, 0)
|
|
||||||
if intVendorSkuID != 0 && v.VendorSkuID != "-70000" { // todo hard code
|
|
||||||
skuBindInfo := skumapper[v.VendorSkuID]
|
|
||||||
if skuBindInfo == nil {
|
|
||||||
globals.SugarLogger.Infof("updateAfsOrderSkuOtherInfo [运营%s]%s订单sku找不到门店价格(或商品映射),orderID:%s, StoreID:%d, VendorSkuID:%s, sku:%v", opNumStr, model.VendorChineseNames[order.VendorID], order.VendorOrderID, jxStoreID, v.VendorSkuID, v)
|
|
||||||
} else {
|
|
||||||
v.JxSkuID = skuBindInfo.SkuID
|
|
||||||
v.ShopPrice = int64(skuBindInfo.Price)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if actStoreSkuMap != nil {
|
|
||||||
if skuID := jxutils.GetSkuIDFromOrderSkuFinancial(v); skuID > 0 && v.StoreSubName != "" {
|
|
||||||
if actStoreSku := actStoreSkuMap.GetActStoreSku(jxStoreID, skuID, order.VendorID); actStoreSku != nil {
|
|
||||||
v.StoreSubID = actStoreSku.ActID
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *OrderManager) updateAfsOrderOtherInfo(db *dao.DaoDB, afsOrder *model.AfsOrder) (err error) {
|
|
||||||
if afsOrder.VendorStoreID != "" {
|
|
||||||
if storeDetail, err := dao.GetStoreDetailByVendorStoreID(db, afsOrder.VendorStoreID, 0, ""); err == nil {
|
|
||||||
afsOrder.JxStoreID = storeDetail.Store.ID
|
|
||||||
}
|
|
||||||
}
|
|
||||||
order, err2 := c.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID)
|
|
||||||
if afsOrder.StoreID == 0 && afsOrder.JxStoreID == 0 {
|
|
||||||
if err2 == nil {
|
|
||||||
afsOrder.JxStoreID = order.JxStoreID
|
|
||||||
if afsOrder.StoreID == 0 {
|
|
||||||
afsOrder.StoreID = order.StoreID
|
|
||||||
}
|
|
||||||
if afsOrder.VendorStoreID == "" {
|
|
||||||
afsOrder.VendorStoreID = order.VendorStoreID
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
if handler := partner.GetPurchaseOrderHandlerFromVendorID(afsOrder.VendorID); handler != nil {
|
|
||||||
if orderAfsInfo, err := handler.GetOrderAfsInfo(nil, afsOrder.VendorOrderID, afsOrder.AfsOrderID); err == nil && orderAfsInfo.AfsTotalShopMoney != 0 {
|
|
||||||
afsOrder.AfsTotalShopMoney = orderAfsInfo.AfsTotalShopMoney
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err = c.updateAfsOrderSkuOtherInfo(db, afsOrder); err == nil {
|
|
||||||
jxutils.RefreshAfsOrderSkuRelated(afsOrder)
|
|
||||||
if afsOrder.RefundType == model.AfsTypeFullRefund && afsOrder.VendorID == model.VendorIDJX && order.DeliveryType != model.OrderDeliveryTypeSelfTake {
|
|
||||||
afsOrder.SkuUserMoney = order.ActualPayPrice
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *OrderManager) UpdateAfsOrderFields(afsOrder *model.AfsOrder, fieldList []string) (err error) {
|
|
||||||
db := orm.NewOrm()
|
|
||||||
utils.CallFuncLogError(func() error {
|
|
||||||
_, err = db.Update(afsOrder, fieldList...)
|
|
||||||
return err
|
|
||||||
}, "UpdateAfsOrderFields orderID:%s failed with error:%v", afsOrder.VendorOrderID, err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *OrderManager) setAfsOrderID(db *dao.DaoDB, orderStatus *model.OrderStatus) {
|
|
||||||
if dao.IsVendorThingIDEmpty(orderStatus.VendorOrderID) {
|
|
||||||
index := 1
|
|
||||||
if afsOrderList, err2 := dao.GetAfsOrders(db, orderStatus.RefVendorID, orderStatus.RefVendorOrderID, ""); err2 == nil {
|
|
||||||
if len(afsOrderList) > 0 {
|
|
||||||
list := strings.Split(afsOrderList[0].AfsOrderID, "-")
|
|
||||||
if len(list) > 1 {
|
|
||||||
index = int(utils.Str2Int64WithDefault(list[1], 0))
|
|
||||||
//if afsOrderList[0].Status >= model.AfsOrderStatusFinished {
|
|
||||||
index++
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
globals.SugarLogger.Warnf("setAfsOrderID err2:%v", err2)
|
|
||||||
}
|
|
||||||
orderStatus.VendorOrderID = composeAfsOrderID(orderStatus.RefVendorOrderID, index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func composeAfsOrderID(vendorOrderID string, index int) (afsOrderID string) {
|
|
||||||
return strings.Join([]string{
|
|
||||||
vendorOrderID,
|
|
||||||
utils.Int2Str(index),
|
|
||||||
}, "-")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *OrderManager) CreateAfsOrderFromOrder(vendorOrderID string, vendorID int) (afsOrder *model.AfsOrder, err error) {
|
|
||||||
order, err := c.LoadOrder(vendorOrderID, vendorID)
|
|
||||||
if err == nil {
|
|
||||||
afsOrder = &model.AfsOrder{
|
|
||||||
VendorID: vendorID,
|
|
||||||
VendorOrderID: vendorOrderID,
|
|
||||||
JxStoreID: order.JxStoreID,
|
|
||||||
VendorStoreID: order.VendorStoreID,
|
|
||||||
StoreID: order.StoreID,
|
|
||||||
VendorOrgCode: order.VendorOrgCode,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, sku := range order.Skus {
|
|
||||||
orderSkuFinancial := &model.OrderSkuFinancial{
|
|
||||||
VendorID: sku.VendorID,
|
|
||||||
VendorOrderID: sku.VendorOrderID,
|
|
||||||
VendorSubOrderID: sku.VendorSubOrderID,
|
|
||||||
// OrderFinancialID: sku.VendorOrderID,
|
|
||||||
// ConfirmTime: afsOrder.AfsCreateAt,
|
|
||||||
VendorStoreID: afsOrder.VendorStoreID,
|
|
||||||
StoreID: afsOrder.StoreID,
|
|
||||||
JxStoreID: afsOrder.JxStoreID,
|
|
||||||
VendorSkuID: sku.VendorSkuID,
|
|
||||||
SkuID: sku.SkuID,
|
|
||||||
PromotionType: sku.PromotionType,
|
|
||||||
Name: sku.SkuName,
|
|
||||||
ShopPrice: sku.ShopPrice,
|
|
||||||
SalePrice: sku.SalePrice,
|
|
||||||
Count: sku.Count,
|
|
||||||
// UserMoney: sku.UserMoney,
|
|
||||||
// PmSubsidyMoney: sku.PmSubsidyMoney,
|
|
||||||
IsAfsOrder: 1,
|
|
||||||
}
|
|
||||||
afsOrder.Skus = append(afsOrder.Skus, orderSkuFinancial)
|
|
||||||
}
|
|
||||||
return afsOrder, nil
|
|
||||||
}
|
|
||||||
@@ -1,223 +0,0 @@
|
|||||||
package orderman
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxstore/cms"
|
|
||||||
"math/rand"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/weixinmsg"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/legacymodel"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
)
|
|
||||||
|
|
||||||
type tReplyConfig struct {
|
|
||||||
DelayGapBegin int `json:"delayGapBegin"`
|
|
||||||
DelayGapEnd int `json:"delayGapEnd"`
|
|
||||||
Comments []string `json:"comments"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
//replyConfig = map[int]*tReplyConfig{
|
|
||||||
// 1: &tReplyConfig{
|
|
||||||
// delayGapBegin: COMMENTS_SCORE_ONE_ORTWO_BEGIN_DELAY_TIME,
|
|
||||||
// delayGapEnd: COMMENTS_SCORE_ONE_ORTWO_END_DELAY_TIME,
|
|
||||||
// comments: []string{
|
|
||||||
// "非常抱歉让您没有得到十分满意的购物体验,我们会及时与您联系进行确认并解决问题!",
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// 3: &tReplyConfig{
|
|
||||||
// delayGapBegin: COMMENTS_SCORE_THREE_BEGIN_DELAY_TIME,
|
|
||||||
// delayGapEnd: COMMENTS_SCORE_THREE_END_DELAY_TIME,
|
|
||||||
// comments: []string{
|
|
||||||
// "感谢您对我们的肯定,祝您生活愉快!欢迎再次光临,谢谢!",
|
|
||||||
// fmt.Sprintf("感谢您对%s的关照,我们会更加精益求精。", globals.StoreName),
|
|
||||||
// "感谢您的光临,您的支持是我们前进的动力!",
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// 4: &tReplyConfig{
|
|
||||||
// delayGapBegin: COMMENTS_SCORE_FOUR_ORFIVE_BEGIN_DELAY_TIME,
|
|
||||||
// delayGapEnd: COMMENTS_SCORE_FOUR_ORFIVE_END_DELAY_TIME,
|
|
||||||
// comments: []string{
|
|
||||||
// "感谢您的信赖!我们会不断提升菜品质量以及优质的服务,期待与您的再次相遇!",
|
|
||||||
// "感谢您的支持,愿您天天好心情!",
|
|
||||||
// "感谢您的认可!您的支持是我们前进的动力。",
|
|
||||||
// "感谢您的肯定与支持!我们会坚持把最好的服务带给您,期待和您的再次相遇!",
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
//}
|
|
||||||
)
|
|
||||||
|
|
||||||
func (c *OrderManager) OnOrderComments(orderCommentList []*model.OrderComment) (err error) {
|
|
||||||
db := dao.GetDB()
|
|
||||||
for _, orderComment := range orderCommentList {
|
|
||||||
comment2 := &legacymodel.JxBadComments{
|
|
||||||
OrderId: orderComment.VendorOrderID,
|
|
||||||
}
|
|
||||||
err = dao.GetEntity(db, comment2, "OrderId")
|
|
||||||
if err == nil || dao.IsNoRowsError(err) {
|
|
||||||
isNewComment := false
|
|
||||||
if dao.IsNoRowsError(err) {
|
|
||||||
err = nil
|
|
||||||
isNewComment = true
|
|
||||||
if orderComment.IsReplied == 0 && time.Now().Sub(orderComment.CommentCreatedAt) < time.Duration(orderComment.ModifyDuration)*time.Hour {
|
|
||||||
if storeDetail, err2 := dao.GetStoreDetail(db, orderComment.StoreID, orderComment.VendorID, ""); err2 == nil {
|
|
||||||
if storeDetail.AutoReplyType == model.AutoReplyAll || orderComment.Score > cms.JX_BAD_COMMENTS_MAX_LEVEL && storeDetail.AutoReplyType == model.AutoReplyGoodComment {
|
|
||||||
c.replyOrderComment(storeDetail.VendorOrgCode, orderComment)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if isNewComment /*&& orderComment.Score <= JX_BAD_COMMENTS_MAX_LEVEL*/ || !isNewComment && orderComment.Score > cms.JX_BAD_COMMENTS_MAX_LEVEL { // 如果是直接非差评,或补评仍然是差评,忽略
|
|
||||||
if isNewComment {
|
|
||||||
comment2.Createtime = utils.Time2Str(orderComment.CommentCreatedAt)
|
|
||||||
comment2.Score = int(orderComment.Score)
|
|
||||||
comment2.Scorecontent = orderComment.Content
|
|
||||||
comment2.Vendertags = orderComment.TagList
|
|
||||||
comment2.Msg = orderComment.OriginalMsg
|
|
||||||
|
|
||||||
comment2.Status = cms.COMMENT_NOT_RESOLVED
|
|
||||||
comment2.OrderFlag = utils.Int2Str(orderComment.VendorID)
|
|
||||||
comment2.Maxmodifytime = int(orderComment.ModifyDuration)
|
|
||||||
comment2.VendorOrderId = orderComment.VendorOrderID2
|
|
||||||
|
|
||||||
var order *model.GoodsOrder
|
|
||||||
if orderComment.VendorID == model.VendorIDMTWM && orderComment.VendorOrderID2 != "" {
|
|
||||||
order, _ = partner.CurOrderManager.LoadOrder(orderComment.VendorOrderID2, orderComment.VendorID)
|
|
||||||
} else {
|
|
||||||
order, _ = partner.CurOrderManager.LoadOrder(orderComment.VendorOrderID, orderComment.VendorID)
|
|
||||||
}
|
|
||||||
|
|
||||||
if order != nil {
|
|
||||||
orderComment.StoreID = jxutils.GetSaleStoreIDFromOrder(order)
|
|
||||||
if order.ConsigneeMobile2 != "" {
|
|
||||||
orderComment.ConsigneeMobile = order.ConsigneeMobile2
|
|
||||||
} else {
|
|
||||||
if handler := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID); handler != nil {
|
|
||||||
if order2, _ := handler.GetOrder(order.VendorOrgCode, order.VendorOrderID, order.VendorStoreID); order2 != nil && order.ConsigneeMobile != order2.ConsigneeMobile {
|
|
||||||
order.ConsigneeMobile = order2.ConsigneeMobile
|
|
||||||
partner.CurOrderManager.UpdateOrderFields(order, []string{"ConsigneeMobile"})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
orderComment.ConsigneeMobile = order.ConsigneeMobile
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if storeDetail, err := dao.GetStoreDetailByVendorStoreID(db, orderComment.VendorStoreID, orderComment.VendorID, ""); err == nil {
|
|
||||||
orderComment.StoreID = storeDetail.ID
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if orderComment.StoreID > 0 {
|
|
||||||
comment2.Jxstoreid = utils.Int2Str(orderComment.StoreID)
|
|
||||||
}
|
|
||||||
comment2.Userphone = orderComment.ConsigneeMobile
|
|
||||||
if comment2.Jxstoreid != "" && orderComment.Score <= cms.JX_MIDDLE_COMMENTS_MAX_LEVEL && time.Now().Sub(orderComment.CommentCreatedAt) < cms.MAX_REAPLY_TIME && order != nil {
|
|
||||||
comment2.LastPushTime = utils.Time2Str(time.Now())
|
|
||||||
comment2.PushNo = 1
|
|
||||||
weixinmsg.PushJDBadCommentToWeiXin(comment2, orderComment.Score <= cms.JX_BAD_COMMENTS_MAX_LEVEL, order)
|
|
||||||
}
|
|
||||||
} else { // 修改评价,高于JX_BAD_COMMENTS_MAX_LEVEL
|
|
||||||
//if orderComment.CommentCreatedAt.Sub(str2Time(comment2.Createtime)) == 0 ||
|
|
||||||
// orderComment.CommentCreatedAt.Sub(str2Time(comment2.Updatetime)) == 0 {
|
|
||||||
// comment2 = nil // 重复
|
|
||||||
//} else {
|
|
||||||
comment2.Updatetime = utils.Time2Str(orderComment.CommentCreatedAt)
|
|
||||||
comment2.UpdatedMsg = orderComment.OriginalMsg
|
|
||||||
comment2.UpdatedScore = int(orderComment.Score)
|
|
||||||
comment2.UpdatedScorecontent = orderComment.Content
|
|
||||||
comment2.UpdatedVendertags = orderComment.TagList
|
|
||||||
comment2.Status = cms.COMMENT_RESOLVED
|
|
||||||
comment2.VendorOrderId = orderComment.VendorOrderID2
|
|
||||||
if comment2.Jxstoreid != "" && orderComment.Score <= cms.JX_MIDDLE_COMMENTS_MAX_LEVEL && time.Now().Sub(orderComment.CommentCreatedAt) < cms.MAX_REAPLY_TIME {
|
|
||||||
comment2.LastPushTime = utils.Time2Str(time.Now())
|
|
||||||
comment2.PushNo++
|
|
||||||
|
|
||||||
comment3 := *comment2
|
|
||||||
comment3.Createtime = comment2.Updatetime
|
|
||||||
comment3.Score = comment2.UpdatedScore
|
|
||||||
comment3.Scorecontent = comment2.UpdatedScorecontent
|
|
||||||
comment3.Vendertags = comment2.UpdatedVendertags
|
|
||||||
|
|
||||||
var order *model.GoodsOrder
|
|
||||||
if orderComment.VendorID == model.VendorIDMTWM && orderComment.VendorOrderID2 != "" {
|
|
||||||
order, _ = partner.CurOrderManager.LoadOrder(orderComment.VendorOrderID2, orderComment.VendorID)
|
|
||||||
} else {
|
|
||||||
order, _ = partner.CurOrderManager.LoadOrder(orderComment.VendorOrderID, orderComment.VendorID)
|
|
||||||
}
|
|
||||||
weixinmsg.PushJDBadCommentToWeiXin(&comment3, orderComment.Score <= cms.JX_BAD_COMMENTS_MAX_LEVEL, order)
|
|
||||||
}
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err == nil {
|
|
||||||
if comment2.OrderFlag == "1" {
|
|
||||||
}
|
|
||||||
if isNewComment {
|
|
||||||
err = dao.CreateEntity(db, comment2)
|
|
||||||
} else if comment2 != nil {
|
|
||||||
_, err = dao.UpdateEntity(db, comment2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if orderComment.VendorOrderID2 != "" {
|
|
||||||
comment2.VendorOrderId = orderComment.VendorOrderID2
|
|
||||||
_, err = dao.UpdateEntity(db, comment2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
comment2.VendorOrderId = orderComment.VendorOrderID2
|
|
||||||
_, err = dao.UpdateEntity(db, comment2, "VendorOrderId")
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *OrderManager) replyOrderComment(vendorOrgCode string, orderComment *model.OrderComment) (err error) {
|
|
||||||
score := int(orderComment.Score)
|
|
||||||
if score <= 2 {
|
|
||||||
score = 1
|
|
||||||
} else if score >= 5 {
|
|
||||||
score = 4
|
|
||||||
}
|
|
||||||
var config *tReplyConfig
|
|
||||||
if configs, err := dao.QueryConfigs(dao.GetDB(), utils.Int2Str(score), model.ConfigTypeReply, ""); err == nil {
|
|
||||||
json.Unmarshal([]byte(configs[0].Value), &config)
|
|
||||||
}
|
|
||||||
if config == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
//config := replyConfig[score]
|
|
||||||
delaySeconds := config.DelayGapBegin + rand.Intn(config.DelayGapEnd-config.DelayGapBegin)
|
|
||||||
content := config.Comments[rand.Intn(len(config.Comments))]
|
|
||||||
utils.AfterFuncWithRecover(time.Duration(delaySeconds)*time.Second, func() {
|
|
||||||
if handler := partner.GetPurchaseOrderHandlerFromVendorID(orderComment.VendorID); handler != nil {
|
|
||||||
if err = handler.ReplyOrderComment(jxcontext.AdminCtx, vendorOrgCode, orderComment, content); err != nil {
|
|
||||||
globals.SugarLogger.Debugf("replyOrderComment orderID:%s, error:%v", orderComment.VendorOrderID, err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
globals.SugarLogger.Warnf("replyOrderComment can not find handler orderID:%s", orderComment.VendorOrderID)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// todo 这里直接延时,可以导致服务器重启时漏掉回复,但如果用管理任务,又会导致大量评价任务存在与任务列表中
|
|
||||||
// task := tasksch.NewParallelTask(fmt.Sprintf("回复订单:%s评价", orderComment.VendorOrderID), nil, jxcontext.AdminCtx,
|
|
||||||
// func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
|
||||||
// return retVal, err
|
|
||||||
// }, []int{0})
|
|
||||||
// tasksch.HandleTask(task, nil, true).Run()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func str2Time(timeStr string) time.Time {
|
|
||||||
if timeStr == "" {
|
|
||||||
return utils.DefaultTimeValue
|
|
||||||
}
|
|
||||||
return utils.Str2Time(timeStr)
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
package orderman
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSaveJdsOrders(t *testing.T) {
|
|
||||||
type args struct {
|
|
||||||
ctx *jxcontext.Context
|
|
||||||
orderCreatedStart time.Time
|
|
||||||
orderCreatedEnd time.Time
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
// TODO: Add test cases.
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
if err := SaveJdsOrders(tt.args.ctx, tt.args.orderCreatedStart, tt.args.orderCreatedEnd); (err != nil) != tt.wantErr {
|
|
||||||
t.Errorf("SaveJdsOrders() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,177 +0,0 @@
|
|||||||
package orderman
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"sort"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
pendingOrderGapMax = 2 * 24 * time.Hour // 每次重启机子时,要检查几天内的订单状态
|
|
||||||
maxTimeHandlePendingOrder = 2 * time.Second //处理pending order的最长时间
|
|
||||||
maxSleepGapHandlePendingOrder = 5 * time.Millisecond // 每个pending order的最长时间间隙
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrCanNotFindOrder = errors.New("找不到相应订单")
|
|
||||||
ErrCanNotFindWaybill = errors.New("找不到相应运单")
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
FixedOrderManager *OrderManager
|
|
||||||
)
|
|
||||||
|
|
||||||
// 所有公共接口调用前,要求在order里或status中设置合适的Status
|
|
||||||
type OrderManager struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewOrderManager() *OrderManager {
|
|
||||||
return &OrderManager{}
|
|
||||||
}
|
|
||||||
|
|
||||||
type IStatusTimer interface {
|
|
||||||
GetStatusTime() time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
type StatusTimerSlice []IStatusTimer
|
|
||||||
|
|
||||||
func (s StatusTimerSlice) Len() int {
|
|
||||||
return len(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s StatusTimerSlice) Less(i, j int) bool {
|
|
||||||
return s[i].GetStatusTime().Sub(s[j].GetStatusTime()) < 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s StatusTimerSlice) Swap(i, j int) {
|
|
||||||
tmp := s[i]
|
|
||||||
s[i] = s[j]
|
|
||||||
s[j] = tmp
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
FixedOrderManager = NewOrderManager()
|
|
||||||
partner.InitOrderManager(FixedOrderManager)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 美团回调错误信息
|
|
||||||
func addOrderOrWaybillStatus(status *model.OrderStatus, db *dao.DaoDB) (isDuplicated bool, err error) {
|
|
||||||
if status.OrderType == model.OrderTypeOrder {
|
|
||||||
globals.SugarLogger.Debugf("addOrderStatus order:%v", status)
|
|
||||||
} else if status.OrderType == model.OrderTypeWaybill {
|
|
||||||
globals.SugarLogger.Debugf("addOrderStatus waybill:%v", status)
|
|
||||||
} else {
|
|
||||||
globals.SugarLogger.Debugf("addOrderStatus afsOrder:%v", status)
|
|
||||||
}
|
|
||||||
txDB, _ := dao.Begin(db)
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil || err != nil {
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
if r != nil {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
status.ID = 0
|
|
||||||
status.Remark = utils.LimitUTF8StringLen(status.Remark, 255)
|
|
||||||
created, _, err := db.Db.ReadOrCreate(status, "VendorOrderID", "VendorID", "OrderType", "Status", "VendorStatus", "StatusTime")
|
|
||||||
if err == nil {
|
|
||||||
if !created {
|
|
||||||
isDuplicated = true
|
|
||||||
status.DuplicatedCount++
|
|
||||||
utils.CallFuncLogError(func() error {
|
|
||||||
_, err = db.Db.Update(status, "DuplicatedCount")
|
|
||||||
return err
|
|
||||||
}, "addOrderOrWaybillStatus update DuplicatedCount, status:%v", status)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
// todo 这里居然会有主键重复错误,逻辑上是不应该的
|
|
||||||
globals.SugarLogger.Warnf("addOrderOrWaybillStatus status:%v, access db error:%v", status, err)
|
|
||||||
} else {
|
|
||||||
dao.Commit(db, txDB)
|
|
||||||
}
|
|
||||||
return isDuplicated, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *OrderManager) GetStatusDuplicatedCount(status *model.OrderStatus) (duplicatedCount int) {
|
|
||||||
if status == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
db := dao.GetDB()
|
|
||||||
if err := dao.GetEntity(db, status, "VendorOrderID", "VendorID", "OrderType", "VendorStatus", "StatusTime"); err == nil {
|
|
||||||
return status.DuplicatedCount
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo 最好还是改成全事件回放算了
|
|
||||||
func LoadPendingOrders() {
|
|
||||||
orders, err := dao.LoadPendingOrders(dao.GetDB(), time.Now().Add(-pendingOrderGapMax), model.OrderStatusEndBegin)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ordersCount := len(orders)
|
|
||||||
if ordersCount > 0 {
|
|
||||||
bills := FixedOrderManager.LoadPendingWaybills()
|
|
||||||
var sortOrders StatusTimerSlice
|
|
||||||
orderMap := make(map[string]*model.GoodsOrder)
|
|
||||||
for _, order := range orders {
|
|
||||||
if order.Status > model.OrderStatusNew {
|
|
||||||
status := model.Order2Status(order)
|
|
||||||
sortOrders = append(sortOrders, status)
|
|
||||||
}
|
|
||||||
// order.Status = model.OrderStatusNew // 就是要以实际order状态来调用scheduler.OnOrderNew
|
|
||||||
order.StatusTime = order.OrderCreatedAt
|
|
||||||
sortOrders = append(sortOrders, order)
|
|
||||||
orderMap[jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID)] = order
|
|
||||||
}
|
|
||||||
for _, bill := range bills {
|
|
||||||
if bill.Status > model.WaybillStatusNew {
|
|
||||||
bill2 := *bill
|
|
||||||
sortOrders = append(sortOrders, &bill2)
|
|
||||||
}
|
|
||||||
bill.Status = model.WaybillStatusNew
|
|
||||||
bill.StatusTime = bill.WaybillCreatedAt
|
|
||||||
sortOrders = append(sortOrders, bill)
|
|
||||||
}
|
|
||||||
sort.Sort(sortOrders)
|
|
||||||
sleepGap := maxTimeHandlePendingOrder / time.Duration(ordersCount)
|
|
||||||
if sleepGap > maxSleepGapHandlePendingOrder {
|
|
||||||
sleepGap = maxSleepGapHandlePendingOrder
|
|
||||||
}
|
|
||||||
lastTime := time.Now()
|
|
||||||
for _, item := range sortOrders {
|
|
||||||
if order, ok := item.(*model.GoodsOrder); ok {
|
|
||||||
jxutils.CallMsgHandlerAsync(func() {
|
|
||||||
scheduler.CurrentScheduler.OnOrderNew(order, true, true)
|
|
||||||
}, jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID))
|
|
||||||
} else if status, ok := item.(*model.OrderStatus); ok {
|
|
||||||
jxutils.CallMsgHandlerAsync(func() {
|
|
||||||
order := orderMap[jxutils.ComposeUniversalOrderID(status.VendorOrderID, status.VendorID)]
|
|
||||||
scheduler.CurrentScheduler.OnOrderStatusChanged(order, status, true)
|
|
||||||
}, jxutils.ComposeUniversalOrderID(status.RefVendorOrderID, status.RefVendorID))
|
|
||||||
} else {
|
|
||||||
bill := item.(*model.Waybill)
|
|
||||||
jxutils.CallMsgHandlerAsync(func() {
|
|
||||||
scheduler.CurrentScheduler.OnWaybillStatusChanged(bill, true)
|
|
||||||
}, jxutils.ComposeUniversalOrderID(bill.VendorOrderID, bill.OrderVendorID))
|
|
||||||
}
|
|
||||||
curTime := time.Now()
|
|
||||||
timeout := sleepGap - curTime.Sub(lastTime)
|
|
||||||
if timeout > 0 {
|
|
||||||
time.Sleep(timeout)
|
|
||||||
}
|
|
||||||
lastTime = curTime
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,17 +0,0 @@
|
|||||||
package orderman
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api2"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/testinit"
|
|
||||||
|
|
||||||
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/ebai"
|
|
||||||
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/elm"
|
|
||||||
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/jd"
|
|
||||||
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/mtwm"
|
|
||||||
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/weimob/wsc"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
testinit.Init()
|
|
||||||
api2.Init()
|
|
||||||
}
|
|
||||||
@@ -1,289 +0,0 @@
|
|||||||
package orderman
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/dadaapi"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
"github.com/astaxie/beego/client/orm"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
waybillOrderStatusMap = map[int]int{
|
|
||||||
model.WaybillStatusApplyFailedGetGoods: model.OrderStatusApplyFailedGetGoods,
|
|
||||||
model.WaybillStatusAgreeFailedGetGoods: model.OrderStatusAgreeFailedGetGoods,
|
|
||||||
model.WaybillStatusRefuseFailedGetGoods: model.OrderStatusRefuseFailedGetGoods,
|
|
||||||
model.WaybillStatusDeliverFailed: model.OrderStatusDeliverFailed,
|
|
||||||
}
|
|
||||||
complaintReasonsMap = map[int]string{
|
|
||||||
1: "骑手态度恶劣",
|
|
||||||
2: "骑手接单后未取货",
|
|
||||||
3: "骑手取货太慢",
|
|
||||||
4: "骑手送货太慢",
|
|
||||||
5: "货品未送达",
|
|
||||||
6: "货品有损坏",
|
|
||||||
7: "骑手违规收取顾客其他费用",
|
|
||||||
69: "骑手恶意取消订单",
|
|
||||||
71: "骑手提前点击取货/送达",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func (w *OrderManager) LoadPendingWaybills() []*model.Waybill {
|
|
||||||
db := orm.NewOrm()
|
|
||||||
var bills []*model.Waybill
|
|
||||||
tillTime := time.Now().Add(-pendingOrderGapMax)
|
|
||||||
_, err := db.Raw(`
|
|
||||||
SELECT t1.*
|
|
||||||
FROM waybill t1
|
|
||||||
JOIN goods_order t2 ON t2.vendor_order_id = t1.vendor_order_id
|
|
||||||
AND t2.vendor_id = t1.order_vendor_id
|
|
||||||
AND t2.order_created_at >= ?
|
|
||||||
AND t2.status < ?
|
|
||||||
WHERE t1.waybill_created_at >= ?
|
|
||||||
AND t1.status < ?
|
|
||||||
`, tillTime, model.OrderStatusEndBegin, tillTime, model.WaybillStatusEndBegin).QueryRows(&bills)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return bills
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *OrderManager) OnWaybillNew(bill2 *model.Waybill, db *dao.DaoDB) (isDuplicated bool, err error) {
|
|
||||||
isDuplicated, err = addOrderOrWaybillStatus(model.Waybill2Status(bill2), db)
|
|
||||||
if err == nil && !isDuplicated {
|
|
||||||
bill2.ID = 0
|
|
||||||
bill2.WaybillCreatedAt = bill2.StatusTime
|
|
||||||
bill2.WaybillFinishedAt = utils.DefaultTimeValue
|
|
||||||
billCopied := *bill2
|
|
||||||
bill := &billCopied
|
|
||||||
created, _, err2 := db.Db.ReadOrCreate(bill, "VendorWaybillID", "WaybillVendorID")
|
|
||||||
if err = err2; err == nil {
|
|
||||||
if !created {
|
|
||||||
bill.DuplicatedCount++
|
|
||||||
if bill2.VendorOrderID == bill2.VendorWaybillID { // 购物平台(比如京东)重新建的运单,单号始终是与订单相同的
|
|
||||||
bill2.ID = bill.ID
|
|
||||||
bill2.CreatedAt = bill.CreatedAt
|
|
||||||
bill2.DuplicatedCount = bill.DuplicatedCount
|
|
||||||
err = utils.CallFuncLogError(func() error {
|
|
||||||
_, err = db.Db.Update(bill2) //更新所有字段
|
|
||||||
return err
|
|
||||||
}, "onWaybillNew Update1")
|
|
||||||
} else {
|
|
||||||
isDuplicated = true
|
|
||||||
err = utils.CallFuncLogError(func() error {
|
|
||||||
_, err = db.Db.Update(bill, "DuplicatedCount")
|
|
||||||
return err
|
|
||||||
}, "onWaybillNew Update2")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*bill2 = *bill
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
globals.SugarLogger.Warnf("onWaybillNew create bill:%v, error:%v", bill2, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return isDuplicated, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *OrderManager) OnWaybillStatusChanged(bill *model.Waybill) (err error) {
|
|
||||||
var isDuplicated bool
|
|
||||||
if bill.ActualFee == 0 {
|
|
||||||
bill.ActualFee = bill.DesiredFee + bill.TipFee
|
|
||||||
}
|
|
||||||
bill.CourierMobile = jxutils.FormalizeMobile(bill.CourierMobile)
|
|
||||||
db := dao.GetDB()
|
|
||||||
txDB, _ := dao.Begin(db)
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
duplicatedCount := 0
|
|
||||||
if bill.Status == model.WaybillStatusNew {
|
|
||||||
isDuplicated, err = w.OnWaybillNew(bill, db)
|
|
||||||
if isDuplicated {
|
|
||||||
duplicatedCount = 1
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
existingBill, err2 := w.LoadWaybill(bill.VendorWaybillID, bill.WaybillVendorID)
|
|
||||||
// todo
|
|
||||||
if err2 == nil {
|
|
||||||
bill.DeliveryFlag = existingBill.DeliveryFlag
|
|
||||||
}
|
|
||||||
if bill.Status == model.WaybillStatusAccepted { // 处理美团配送丢失新运单消息的情况
|
|
||||||
if err2 != nil {
|
|
||||||
if dao.IsNoRowsError(err2) || err2 == ErrCanNotFindWaybill {
|
|
||||||
existingBill = bill
|
|
||||||
billCopy := *bill
|
|
||||||
billCopy.Status = model.WaybillStatusNew
|
|
||||||
if isDuplicated, err = w.OnWaybillNew(&billCopy, db); err != nil {
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
dao.Commit(db, txDB)
|
|
||||||
// 进运单调度器OnWaybillStatusChanged之前要确保事务是提交了的,否则会导致死锁
|
|
||||||
// 加载数据到当前系统调度器当中
|
|
||||||
scheduler.CurrentScheduler.OnWaybillStatusChanged(&billCopy, false)
|
|
||||||
dao.Begin(db)
|
|
||||||
} else {
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
return err2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 运单消息错序,之前已经结束了,直接返回
|
|
||||||
if existingBill.Status >= model.WaybillStatusEndBegin {
|
|
||||||
dao.Commit(db, txDB)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
addParams := orm.Params{}
|
|
||||||
if bill.Status >= model.WaybillStatusAccepted {
|
|
||||||
//if bill.Status == model.WaybillStatusAccepted {等于10的时候没有运费
|
|
||||||
if bill.DesiredFee > 0 {
|
|
||||||
addParams["desired_fee"] = bill.DesiredFee
|
|
||||||
}
|
|
||||||
if bill.ActualFee > 0 {
|
|
||||||
addParams["actual_fee"] = bill.ActualFee
|
|
||||||
}
|
|
||||||
//}
|
|
||||||
//单独增加顺丰派送取消运单修改配送费逻辑
|
|
||||||
if (bill.WaybillVendorID == model.VendorIDSFPS || bill.WaybillVendorID == model.VendorIDMTWM) && bill.Status == model.WaybillStatusCanceled {
|
|
||||||
addParams["desired_fee"] = bill.DesiredFee
|
|
||||||
addParams["actual_fee"] = bill.ActualFee
|
|
||||||
}
|
|
||||||
if bill.CourierMobile != "" {
|
|
||||||
addParams["courier_name"] = bill.CourierName
|
|
||||||
addParams["courier_mobile"] = bill.CourierMobile
|
|
||||||
}
|
|
||||||
if bill.Status >= model.WaybillStatusEndBegin {
|
|
||||||
addParams["waybill_finished_at"] = bill.StatusTime
|
|
||||||
}
|
|
||||||
}
|
|
||||||
duplicatedCount, err = w.addWaybillStatus(bill, db, addParams)
|
|
||||||
if err != nil {
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
dao.Commit(db, txDB)
|
|
||||||
if duplicatedCount == 0 {
|
|
||||||
scheduler.CurrentScheduler.OnWaybillStatusChanged(bill, false)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
}
|
|
||||||
if bill.VendorOrderID == bill.VendorWaybillID {
|
|
||||||
if status, ok := waybillOrderStatusMap[bill.Status]; ok {
|
|
||||||
fakeOrderStatus := &model.OrderStatus{
|
|
||||||
VendorOrderID: bill.VendorOrderID,
|
|
||||||
VendorID: bill.OrderVendorID,
|
|
||||||
OrderType: model.OrderTypeOrder,
|
|
||||||
RefVendorOrderID: bill.VendorOrderID,
|
|
||||||
RefVendorID: bill.OrderVendorID,
|
|
||||||
Status: status,
|
|
||||||
VendorStatus: bill.VendorStatus,
|
|
||||||
StatusTime: bill.StatusTime,
|
|
||||||
Remark: bill.Remark + ",订单运费:" + fmt.Sprintf("%d", bill.DesiredFee),
|
|
||||||
}
|
|
||||||
w.OnOrderStatusChanged(bill.VendorOrgCode, fakeOrderStatus)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *OrderManager) addWaybillStatus(bill *model.Waybill, db *dao.DaoDB, addParams orm.Params) (duplicatedCount int, err error) {
|
|
||||||
waybillStatus := model.Waybill2Status(bill)
|
|
||||||
isDuplicated, err := addOrderOrWaybillStatus(waybillStatus, db)
|
|
||||||
if err == nil && !isDuplicated {
|
|
||||||
if waybillStatus.Status > model.WaybillStatusUnknown { // todo 这里应该和addOrderStatus一样的改法,状态不能回绕
|
|
||||||
params := utils.MergeMaps(orm.Params{
|
|
||||||
"status": bill.Status,
|
|
||||||
"vendor_status": bill.VendorStatus,
|
|
||||||
"status_time": bill.StatusTime,
|
|
||||||
}, addParams)
|
|
||||||
utils.CallFuncLogError(func() error {
|
|
||||||
_, err = db.Db.QueryTable("waybill").Filter("vendor_waybill_id", bill.VendorWaybillID).Filter("waybill_vendor_id", bill.WaybillVendorID).Filter("status__lte", bill.Status).Update(params)
|
|
||||||
return err
|
|
||||||
}, "addWaybillStatus update waybill status, bill:%v", bill)
|
|
||||||
} else {
|
|
||||||
duplicatedCount = -1
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
duplicatedCount = 1
|
|
||||||
}
|
|
||||||
return duplicatedCount, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *OrderManager) LoadWaybill(vendorWaybillID string, waybillVendorID int) (bill *model.Waybill, err error) {
|
|
||||||
db := orm.NewOrm()
|
|
||||||
bill = &model.Waybill{
|
|
||||||
VendorWaybillID: vendorWaybillID,
|
|
||||||
WaybillVendorID: waybillVendorID,
|
|
||||||
}
|
|
||||||
if err = db.Read(bill, "VendorWaybillID", "WaybillVendorID"); err != nil {
|
|
||||||
bill = nil
|
|
||||||
if err == orm.ErrNoRows {
|
|
||||||
err = ErrCanNotFindWaybill
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bill, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetComplaintReasons() (complaintReasonList []*dadaapi.ComplaintReason) {
|
|
||||||
for k, v := range complaintReasonsMap {
|
|
||||||
complaintReason := &dadaapi.ComplaintReason{
|
|
||||||
ID: k,
|
|
||||||
Reason: v,
|
|
||||||
}
|
|
||||||
complaintReasonList = append(complaintReasonList, complaintReason)
|
|
||||||
}
|
|
||||||
return complaintReasonList
|
|
||||||
}
|
|
||||||
|
|
||||||
func ComplaintRider(ctx *jxcontext.Context, vendorOrderID string, waybillVendorID string, complaintID int, waybillID string) (err error) {
|
|
||||||
wayBillList, err := dao.GetComplaintList(dao.GetDB(), vendorOrderID, waybillID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if len(wayBillList) != model.YES {
|
|
||||||
return fmt.Errorf("订单所属运单不存在,或运单为分配骑手,无法投诉")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err == nil && len(wayBillList) > 0 {
|
|
||||||
switch wayBillList[0].WaybillVendorID {
|
|
||||||
case model.VendorIDFengNiao, model.VendorIDDada, model.VendorIDMTPS, model.VendorIDUUPT, model.VendorIDSFPS:
|
|
||||||
tripartiteDelivery := partner.GetDeliveryPlatformFromVendorID(wayBillList[0].WaybillVendorID)
|
|
||||||
if tripartiteDelivery != nil {
|
|
||||||
err = tripartiteDelivery.Handler.ComplaintRider(wayBillList[0], complaintID, complaintReasonsMap[complaintID])
|
|
||||||
} else {
|
|
||||||
err = fmt.Errorf("投诉三方配送获取运单失败")
|
|
||||||
}
|
|
||||||
case model.VendorIDMTWM, model.VendorIDDD, model.VendorIDJD, model.VendorIDEBAI, model.VendorIDTaoVegetable:
|
|
||||||
platformDelivery := partner.GetPurchaseOrderHandlerFromVendorID(wayBillList[0].WaybillVendorID)
|
|
||||||
if platformDelivery != nil {
|
|
||||||
err = platformDelivery.ComplaintRider(wayBillList[0].VendorOrderID, complaintID, complaintReasonsMap[complaintID])
|
|
||||||
} else {
|
|
||||||
err = fmt.Errorf("投诉平台配送获取运单失败")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetComplaintList 获取投诉列表
|
|
||||||
func GetComplaintList(orderId string) ([]*model.Waybill, error) {
|
|
||||||
return dao.GetComplaintList(dao.GetDB(), orderId, "")
|
|
||||||
}
|
|
||||||
@@ -1,281 +0,0 @@
|
|||||||
package basesch
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
tiktokShop "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/tiktok_api"
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxstore/cms"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
ctx *jxcontext.Context
|
|
||||||
)
|
|
||||||
var (
|
|
||||||
FixedBaseScheduler *BaseScheduler
|
|
||||||
)
|
|
||||||
|
|
||||||
type BaseScheduler struct {
|
|
||||||
IsReallyCallPlatformAPI bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) {
|
|
||||||
if /*order.LockStatus == model.OrderStatusUnknown && */ order.Status == model.OrderStatusNew || order.Status == model.OrderStatusWaitAccepted {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = utils.CallFuncLogErrorWithInfo(func() error {
|
|
||||||
return partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).AcceptOrRefuseOrder(order, isAcceptIt, userName)
|
|
||||||
}, "AcceptOrRefuseOrder orderID:%s, isAcceptIt:%t", order.VendorOrderID, isAcceptIt)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return scheduler.ErrOrderStatusAlreadySatisfyCurOperation
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) {
|
|
||||||
if /*order.LockStatus == model.OrderStatusUnknown && */ order.Status == model.OrderStatusAccepted {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
handler := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID)
|
|
||||||
err = utils.CallFuncLogErrorWithInfo(func() (err error) {
|
|
||||||
if err = handler.PickupGoods(order, isSelfDelivery, userName); err != nil {
|
|
||||||
if status, err2 := handler.GetOrderStatus(order.VendorOrgCode, order.VendorOrderID); err2 == nil && status >= model.OrderStatusFinished {
|
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}, "PickupGoods orderID:%s", order.VendorOrderID)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if order.LockStatus != model.OrderStatusUnknown || order.Status < model.OrderStatusAccepted {
|
|
||||||
err = scheduler.ErrOrderStatusIsNotSuitable4CurOperation
|
|
||||||
} else {
|
|
||||||
err = scheduler.ErrOrderStatusAlreadySatisfyCurOperation
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) {
|
|
||||||
if /*order.LockStatus == model.OrderStatusUnknown && */ order.Status >= model.OrderStatusFinishedPickup && order.Status <= model.OrderStatusDelivering {
|
|
||||||
if order.DeliveryFlag&model.OrderDeliveryFlagMaskPurcahseDisabled == 0 && c.IsReallyCallPlatformAPI {
|
|
||||||
err = utils.CallFuncLogErrorWithInfo(func() error {
|
|
||||||
return partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).Swtich2SelfDeliver(order, userName)
|
|
||||||
}, "Swtich2SelfDeliver orderID:%s", order.VendorOrderID)
|
|
||||||
}
|
|
||||||
if err == nil { // 因为有些平台转自送后,不会再发送订单在配送中消息过来,所以成功后就强制设置状态为配送中
|
|
||||||
order.Status = model.OrderStatusDelivering
|
|
||||||
order.DeliveryFlag |= model.OrderDeliveryFlagMaskPurcahseDisabled
|
|
||||||
err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if order.LockStatus != model.OrderStatusUnknown || order.Status < model.OrderStatusFinishedPickup || order.VendorID == order.WaybillVendorID {
|
|
||||||
err = scheduler.ErrOrderStatusIsNotSuitable4CurOperation
|
|
||||||
} else {
|
|
||||||
err = scheduler.ErrOrderStatusAlreadySatisfyCurOperation
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) {
|
|
||||||
if /*order.LockStatus == model.OrderStatusUnknown && */ order.Status == model.OrderStatusDelivering {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = utils.CallFuncLogError(func() error {
|
|
||||||
return partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).Swtich2SelfDelivered(order, userName)
|
|
||||||
}, "Swtich2SelfDelivered orderID:%s", order.VendorOrderID)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if order.LockStatus != model.OrderStatusUnknown || order.Status < model.OrderStatusDelivering {
|
|
||||||
err = scheduler.ErrOrderStatusIsNotSuitable4CurOperation
|
|
||||||
} else {
|
|
||||||
err = scheduler.ErrOrderStatusAlreadySatisfyCurOperation
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) {
|
|
||||||
if order.Status == model.OrderStatusFinishedPickup {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = utils.CallFuncLogError(func() error {
|
|
||||||
// 下面这个写法暂存,可能会有问题
|
|
||||||
if order.VendorID == model.VendorIDMTWM {
|
|
||||||
// 转自送同时取消平台订单(美团才做这个操作)
|
|
||||||
if _, err := partner.GetPurchasePlatformFromVendorID(order.VendorID).GetCancelDeliveryReason(order); err != nil {
|
|
||||||
partner.CurOrderManager.OnOrderMsg(order, "订单转自送取消美团平台发单获取理由失败", err.Error())
|
|
||||||
}
|
|
||||||
// 取消美团外卖配送,转自送
|
|
||||||
if err = partner.GetPurchasePlatformFromVendorID(order.VendorID).CancelLogisticsByWmOrderId(order, "101512", "已选择其他配送方式", order.VendorStoreID, order.VendorOrderID); err != nil {
|
|
||||||
partner.CurOrderManager.OnOrderMsg(order, "取消美团外卖,转用三方配送", err.Error())
|
|
||||||
}
|
|
||||||
// 查询订单状态,
|
|
||||||
orderStatus, _ := partner.GetPurchasePlatformFromVendorID(order.VendorID).OrderLogisticsStatus(order.VendorOrderID)
|
|
||||||
status := 0
|
|
||||||
if orderStatus != nil {
|
|
||||||
status = orderStatus.LogisticsStatus
|
|
||||||
}
|
|
||||||
if status == 100 { // 美团取消配送单
|
|
||||||
partner.CurOrderManager.OnOrderMsg(order, "美团外卖转自送成功.", "")
|
|
||||||
return nil
|
|
||||||
} else if strings.Contains(err.Error(), "包裹不存在") || strings.Contains(err.Error(), "运单不存在") || strings.Contains(err.Error(), "1071") || strings.Contains(err.Error(), "1014") || strings.Contains(err.Error(), "invalid character 'o' looking for beginning of value") {
|
|
||||||
partner.CurOrderManager.OnOrderMsg(order, "美团外卖转自送可能成功,异常:", err.Error())
|
|
||||||
err = nil
|
|
||||||
return nil
|
|
||||||
} else if strings.Contains(err.Error(), "商家没有接入众包配送,无法进行众包配送相关操作") {
|
|
||||||
partner.CurOrderManager.OnOrderMsg(order, "商家无配送设置,转配送成功", err.Error())
|
|
||||||
err = nil
|
|
||||||
} else if strings.Contains(err.Error(), "无需重复取消") {
|
|
||||||
partner.CurOrderManager.OnOrderMsg(order, "商家无配送设置,转配送成功", err.Error())
|
|
||||||
err = nil
|
|
||||||
} else {
|
|
||||||
bill, _ := partner.CurOrderManager.LoadWaybill(order.VendorWaybillID, order.WaybillVendorID)
|
|
||||||
err = c.CancelWaybill(bill, partner.CancelWaybillReasonOther, userName+":5"+partner.CancelWaybillReasonStrActive)
|
|
||||||
partner.CurOrderManager.OnOrderMsg(order, "美团外卖运单无法取消,", err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else if order.VendorID == model.VendorIDDD { //抖音配送
|
|
||||||
localBill, _ := partner.CurOrderManager.LoadWaybill(order.VendorWaybillID, order.WaybillVendorID)
|
|
||||||
// 获取抖音配送状态
|
|
||||||
tiktokWayBillStatus, err2 := partner.GetPurchasePlatformFromVendorID(order.VendorID).OrderLogisticsStatus(order.VendorOrderID)
|
|
||||||
if tiktokWayBillStatus != nil && tiktokWayBillStatus.LogisticsStatus >= tiktokShop.ShipmentStatusReceived && tiktokWayBillStatus.LogisticsStatus != tiktokShop.ShipmentStatusCanceled {
|
|
||||||
//取消抖音配送转自送
|
|
||||||
err = c.CancelWaybill(localBill, partner.CancelWaybillReasonDYPSCancel, partner.CancelWaybillReasonStrDYPSCancel+"抖音骑手已经接单,无法取消6")
|
|
||||||
partner.CurOrderManager.OnOrderMsg(order, "取消抖音配送,转用门店自配送/三方配送", "抖音骑手已经接单,无法取消")
|
|
||||||
return err
|
|
||||||
} else if tiktokWayBillStatus != nil && tiktokWayBillStatus.LogisticsStatus == -1 { // 先转自送,自送不成功取消平台配送.
|
|
||||||
if err := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).SelfDeliverDelivering(order, userName); err != nil {
|
|
||||||
partner.CurOrderManager.OnOrderMsg(order, "抖音转自送,平台无运力", "tiktokWayBillStatus = -1")
|
|
||||||
}
|
|
||||||
} else if (err2 != nil && strings.Contains(err2.Error(), "当前状态获取不到运力信息")) || (tiktokWayBillStatus != nil && tiktokWayBillStatus.LogisticsStatus == tiktokShop.ShipmentStatusCanceled) {
|
|
||||||
partner.GetPurchasePlatformFromVendorID(order.VendorID).SelfDeliverDelivering(order, "")
|
|
||||||
} else if err = partner.GetPurchasePlatformFromVendorID(order.VendorID).CancelLogisticsByWmOrderId(order, "", "", order.VendorStoreID, order.VendorOrderID); err != nil {
|
|
||||||
partner.CurOrderManager.OnOrderMsg(order, "取消抖音配送异常:", err.Error())
|
|
||||||
if err = c.CancelWaybill(localBill, partner.CancelWaybillReasonDYPSCancel, partner.CancelWaybillReasonStrDYPSCancel+"7"); err != nil {
|
|
||||||
partner.CurOrderManager.OnOrderMsg(order, "取消抖音平台运单错误,无法转自送", err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
partner.GetPurchasePlatformFromVendorID(order.VendorID).SelfDeliverDelivering(order, "")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if err := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).SelfDeliverDelivering(order, userName); err != nil && (err != scheduler.ErrOrderStatusAlreadySatisfyCurOperation) {
|
|
||||||
partner.CurOrderManager.OnOrderMsg(order, "SelfDeliverDelivering 调用[SelfDeliverDelivering]转自送", err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}, "SelfDeliverDelivering orderID:%s", order.VendorOrderID)
|
|
||||||
if err == nil { // 因为有些平台设置配送中后,不会发送订单在配送中消息过来,所以成功后就强制设置状态为配送中
|
|
||||||
order.Status = model.OrderStatusDelivering
|
|
||||||
err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if order.LockStatus != model.OrderStatusUnknown || order.Status < model.OrderStatusFinishedPickup {
|
|
||||||
err = scheduler.ErrOrderStatusIsNotSuitable4CurOperation
|
|
||||||
} else {
|
|
||||||
err = scheduler.ErrOrderStatusAlreadySatisfyCurOperation
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) {
|
|
||||||
if order.Status >= model.OrderStatusFinishedPickup && order.Status <= model.OrderStatusDelivering {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = utils.CallFuncLogError(func() error {
|
|
||||||
if err = partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).SelfDeliverDelivered(order, userName); err == nil {
|
|
||||||
bill, _ := partner.CurOrderManager.LoadWaybill(order.VendorWaybillID, order.WaybillVendorID)
|
|
||||||
if bill != nil && bill.WaybillVendorID != model.VendorJXFakeWL && bill.WaybillVendorID != model.VendorIDUnknown {
|
|
||||||
c.CancelWaybill(bill, partner.CancelWaybillReasonOther, userName+":"+partner.CancelWaybillReasonStrActive+"8")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}, "SelfDeliverDelivered orderID:%s", order.VendorOrderID)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if order.LockStatus != model.OrderStatusUnknown || order.Status < model.OrderStatusDelivering {
|
|
||||||
err = scheduler.ErrOrderStatusIsNotSuitable4CurOperation
|
|
||||||
} else {
|
|
||||||
err = scheduler.ErrOrderStatusAlreadySatisfyCurOperation
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) CreateWaybill(platformVendorID int, order *model.GoodsOrder, maxDeliveryFee int64) (bill *model.Waybill, err error) {
|
|
||||||
if !model.IsOrderSolid(order) { // 如果订单是不完整的
|
|
||||||
return nil, scheduler.ErrOrderIsNotSolid
|
|
||||||
}
|
|
||||||
|
|
||||||
storeDetail, _ := dao.GetStoreDetail(dao.GetDB(), jxutils.GetSaleStoreIDFromOrder(order), order.VendorID, order.VendorOrgCode)
|
|
||||||
var balance int
|
|
||||||
|
|
||||||
// 门店发单,如果是京西门店,直接使用京西余额,非京西门店使用门店余额,余额不足使用品牌余额!
|
|
||||||
if order.CreateDeliveryType == model.YES {
|
|
||||||
storeAcct, err := cms.GetStoreAcctBalance(ctx, jxutils.GetSaleStoreIDFromOrder(order)) // 获取门店余额
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
balance = storeAcct.AccountBalance
|
|
||||||
} else {
|
|
||||||
balance, _ = partner.CurStoreAcctManager.GetBrandBalance(storeDetail.BrandID)
|
|
||||||
}
|
|
||||||
|
|
||||||
handlerInfo := partner.GetDeliveryPlatformFromVendorID(platformVendorID)
|
|
||||||
if handlerInfo != nil && handlerInfo.Use4CreateWaybill {
|
|
||||||
if _, ok := model.DeliveryBrandMarkMap[platformVendorID]; ok && storeDetail.BrandIsOpen != 0 && balance >= model.BrandBalanceLimit {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
// 如果门店是美团服务商且订单为美团订单
|
|
||||||
if storeDetail.IsService == model.YES && order.VendorID == model.VendorIDMTWM {
|
|
||||||
err = fmt.Errorf("京西ID:[%d],平台id[%s],平台[美团]:错误:[%s]", storeDetail.Store.ID, storeDetail.VendorStoreID, "此门店美团平台为服务商模式,不支持本系统提供的三方配送![仅美团,其余平台订单正常使用.]")
|
|
||||||
} else {
|
|
||||||
if order.VendorID == model.VendorIDEBAI && strings.Contains(order.ConsigneeAddress, EBaiOrderAddressHide) {
|
|
||||||
return nil, fmt.Errorf("由于饿了么用户数据隐私保护,发三方配送前请先将订单转为自配送,获取详情地址")
|
|
||||||
}
|
|
||||||
// 生成三方运单
|
|
||||||
bill, err = handlerInfo.Handler.CreateWaybill(order, maxDeliveryFee)
|
|
||||||
if err != nil {
|
|
||||||
globals.SugarLogger.Infof("CreateWaybill failed orderID:%s vendorID:%d with error:%v", order.VendorOrderID, platformVendorID, err)
|
|
||||||
} else {
|
|
||||||
order.DeliveryFlag |= model.WaybillVendorID2Mask(platformVendorID)
|
|
||||||
err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = fmt.Errorf("创建运单是门店余额不足十元,无法创建运单")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = scheduler.ErrDeliverProviderWrong
|
|
||||||
}
|
|
||||||
return bill, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) CancelWaybill(bill *model.Waybill, cancelReasonID int, cancelReason string) (err error) {
|
|
||||||
// 部分快递平台在取消成功后有时会不发运单取消消息过来(比如达达,904200512000442),为避免二次取消报错,添加状态判断
|
|
||||||
if c.IsReallyCallPlatformAPI && bill.OrderVendorID != bill.WaybillVendorID && bill.Status != model.WaybillStatusCanceled {
|
|
||||||
if handlerInfo := partner.GetDeliveryPlatformFromVendorID(bill.WaybillVendorID); handlerInfo != nil {
|
|
||||||
if err = utils.CallFuncLogErrorWithInfo(func() error {
|
|
||||||
if err := handlerInfo.Handler.CancelWaybill(bill, cancelReasonID, cancelReason+"9"); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}, "CancelWaybill bill:%v", bill); err == nil {
|
|
||||||
bill.Status = model.WaybillStatusCanceled
|
|
||||||
bill.DeliveryFlag |= model.WaybillDeliveryFlagMaskActiveCancel
|
|
||||||
_, err = dao.UpdateEntity(nil, bill, "Status", "DeliveryFlag")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
@@ -1,577 +0,0 @@
|
|||||||
package basesch
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/jdshopapi"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/dingdingapi"
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/baseapi/utils/errlist"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxstore/cms"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/ddmsg"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
autoSelfTakeCode = "135246"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
EBaiOrderAddressHide = "[隐私保护]顾客地址已隐藏"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (c *BaseScheduler) CreateWaybillOnProviders(ctx *jxcontext.Context, order *model.GoodsOrder, courierVendorIDs, excludeCourierVendorIDs []int, maxDeliveryFee int64, createOnlyOne bool) (bills []*model.Waybill, err error) {
|
|
||||||
storeCourierList, err := dao.GetStoreCourierList2(dao.GetDB(), []int{jxutils.GetSaleStoreIDFromOrder(order)}, courierVendorIDs, model.StoreStatusOpened, []int{model.StoreAuditStatusOnline, model.StoreAuditStatusUpdated})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
courierVendorIDMap := jxutils.IntList2Map(courierVendorIDs)
|
|
||||||
excludeCourierVendorIDMap := jxutils.IntList2Map(excludeCourierVendorIDs)
|
|
||||||
errList := errlist.New()
|
|
||||||
|
|
||||||
store, _ := dao.GetStoreDetail(dao.GetDB(), order.JxStoreID, order.VendorID, order.VendorOrgCode)
|
|
||||||
for _, storeCourier := range storeCourierList {
|
|
||||||
switch storeCourier.Status {
|
|
||||||
case model.YES:
|
|
||||||
if (courierVendorIDs == nil || courierVendorIDMap[storeCourier.VendorID] == 1) &&
|
|
||||||
(excludeCourierVendorIDs == nil || excludeCourierVendorIDMap[storeCourier.VendorID] == 0) {
|
|
||||||
if handler := partner.GetDeliveryPlatformFromVendorID(storeCourier.VendorID); handler != nil && handler.Use4CreateWaybill {
|
|
||||||
courierVendorID := storeCourier.VendorID
|
|
||||||
// 创建运单
|
|
||||||
bill, err2 := c.CreateWaybill(courierVendorID, order, maxDeliveryFee)
|
|
||||||
if err = err2; err == nil {
|
|
||||||
// 其实这个bill没啥用,运单的创建是通过回调产生的
|
|
||||||
bill.DesiredFee += int64(model.WayBillDeliveryMarkUp + store.FreightMarkup)
|
|
||||||
if bill.WaybillVendorID == model.VendorIDFengNiao {
|
|
||||||
bill.DesiredFee += model.WayBillDeliveryMarkUp
|
|
||||||
}
|
|
||||||
bill.DesiredFee += int64(store.FreightMarkup)
|
|
||||||
bills = append(bills, bill)
|
|
||||||
if createOnlyOne {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
errList.AddErr(fmt.Errorf("平台:%s,%s", jxutils.GetVendorName(courierVendorID), err.Error()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case model.NO:
|
|
||||||
errList.AddErr(fmt.Errorf("平台:%s,发单配送被关闭,打开后发单", jxutils.GetVendorName(storeCourier.VendorID)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(bills) > 0 {
|
|
||||||
err = errList.GetErrListAsOne()
|
|
||||||
if err != nil {
|
|
||||||
partner.CurOrderManager.OnOrderMsg(order, "创建三方运单部分失败", err.Error())
|
|
||||||
}
|
|
||||||
err = nil
|
|
||||||
} else if errList.GetErrListAsOne() == nil {
|
|
||||||
err = fmt.Errorf("orderID:%s过订单发三方配送亏损超6元/当前订单配送方式不是门店自送/没有绑定有效的三方配送门店", order.VendorOrderID)
|
|
||||||
} else {
|
|
||||||
err = fmt.Errorf("orderID:%s所有运单失败:%s", order.VendorOrderID, errList.GetErrListAsOne().Error())
|
|
||||||
}
|
|
||||||
return bills, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) SelfDeliveredAndUpdateStatus(ctx *jxcontext.Context, vendorOrderID string, vendorID int, userName string) (err error) {
|
|
||||||
jxutils.CallMsgHandler(func() {
|
|
||||||
err = func() (err error) {
|
|
||||||
order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, vendorID)
|
|
||||||
if err == nil {
|
|
||||||
if model.IsOrderDeliveryByStore(order) {
|
|
||||||
err = c.SelfDeliverDelivered(order, userName)
|
|
||||||
} else if model.IsOrderDeliveryByPlatform(order) {
|
|
||||||
err = c.Swtich2SelfDelivered(order, userName)
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
order.Status = model.OrderStatusFinished // todo 是否需要强制设置完成状态?
|
|
||||||
if err = dao.SetOrderFlag(dao.GetDB(), ctx.GetUserName(), order.VendorOrderID, order.VendorID, model.OrderFlagMaskSetDelivered); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
order.OrderFinishedAt = time.Now()
|
|
||||||
dao.UpdateEntity(dao.GetDB(), order, "Status", "OrderFinishedAt")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}()
|
|
||||||
}, jxutils.ComposeUniversalOrderID(vendorOrderID, vendorID))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) PickupGoodsAndUpdateStatus(ctx *jxcontext.Context, vendorOrderID string, vendorID int, userName string) (err error) {
|
|
||||||
jxutils.CallMsgHandler(func() {
|
|
||||||
err = func() (err error) {
|
|
||||||
order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, vendorID)
|
|
||||||
if err == nil {
|
|
||||||
flag := model.IsOrderDeliveryByStore(order) || model.IsOrderDeliveryBySelf(order)
|
|
||||||
err = c.PickupGoods(order, flag, userName)
|
|
||||||
if err == nil {
|
|
||||||
partner.CurOrderManager.OnOrderMsg(order, fmt.Sprintf("订单手动拣货成功[%s]", ctx.GetUserName()), "")
|
|
||||||
order.Status = model.OrderStatusFinishedPickup
|
|
||||||
if err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 京西商城的自提订单,在拣货完成时自动设置为完成订单
|
|
||||||
if model.IsOrderDeliveryBySelf(order) && order.VendorID == model.VendorIDJX {
|
|
||||||
order.Status = model.OrderStatusFinished
|
|
||||||
order.VendorStatus = utils.Int64ToStr(model.OrderStatusFinished)
|
|
||||||
order.Flag = 128
|
|
||||||
order.OrderFinishedAt = time.Now()
|
|
||||||
dao.UpdateEntity(dao.GetDB(), order, "Status", "VendorStatus", "Flag", "OrderFinishedAt")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}()
|
|
||||||
}, jxutils.ComposeUniversalOrderID(vendorOrderID, vendorID))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).AdjustOrder(ctx, order, removedSkuList, reason)
|
|
||||||
if err == nil {
|
|
||||||
var skuIDs []string
|
|
||||||
for _, v := range removedSkuList {
|
|
||||||
skuIDs = append(skuIDs, utils.Int2Str(v.SkuID))
|
|
||||||
}
|
|
||||||
noticeMsg := fmt.Sprintf("商品skuID列表:%v,订单号(点击进入详情):%v", strings.Join(skuIDs, ","), globals.BackstageHost+"/#/ordermanager/"+order.VendorOrderID)
|
|
||||||
user, err := dao.GetUserByID(dao.GetDB(), "mobile", "18982250714")
|
|
||||||
if user != nil && err == nil {
|
|
||||||
ddmsg.SendUserMessage(dingdingapi.MsgTyeText, user.UserID, "调整单调整商品", noticeMsg)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
if globals.IsAddEvent {
|
|
||||||
err = cms.AddEventDetail(dao.GetDB(), ctx, model.OperateUpdate, order.StoreID, model.ThingTypeOrder, order.StoreID, order.VendorOrderID, order.StoreName)
|
|
||||||
}
|
|
||||||
err = partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).CancelOrder(ctx, order, reason+","+ctx.GetUserName())
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) AcceptOrRefuseFailedGetOrder(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool, reason string) (err error) {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).AcceptOrRefuseFailedGetOrder(ctx, order, isAcceptIt)
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
flag := model.OrderFlagAgreeFailedGetGoods
|
|
||||||
if !isAcceptIt {
|
|
||||||
flag = model.OrderFlagRefuseFailedGetGoods
|
|
||||||
}
|
|
||||||
dao.SetOrderFlag(dao.GetDB(), ctx.GetUserName(), order.VendorOrderID, order.VendorID, flag)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) CallPMCourier(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).CallCourier(ctx, order)
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
dao.SetOrderFlag(dao.GetDB(), ctx.GetUserName(), order.VendorOrderID, order.VendorID, model.OrderFlagMaskCallPMCourier)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) ConfirmReceiveGoods(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).ConfirmReceiveGoods(ctx, order)
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
dao.SetOrderFlag(dao.GetDB(), ctx.GetUserName(), order.VendorOrderID, order.VendorID, model.OrderFlagMaskFailedDeliver)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool, reason string) (err error) {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).AgreeOrRefuseCancel(ctx, order, isAcceptIt, reason)
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
flag := model.OrderFlagAgreeUserApplyCancel
|
|
||||||
if !isAcceptIt {
|
|
||||||
flag = model.OrderFlagRefuseUserApplyCancel
|
|
||||||
}
|
|
||||||
dao.SetOrderFlag(dao.GetDB(), ctx.GetUserName(), order.VendorOrderID, order.VendorID, flag)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) CancelWaybillByID(ctx *jxcontext.Context, vendorWaybillID string, waybillVendorID int, cancelReasonID int, cancelReason string) (err error) {
|
|
||||||
bill, err := partner.CurOrderManager.LoadWaybill(vendorWaybillID, waybillVendorID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
order, _ := partner.CurOrderManager.LoadOrder(bill.VendorOrderID, bill.OrderVendorID)
|
|
||||||
|
|
||||||
if bill.OrderVendorID != bill.WaybillVendorID { // 取消三方配送
|
|
||||||
if err = c.CancelWaybill(bill, cancelReasonID, cancelReason); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else { // 取消平台配送转自送
|
|
||||||
if err = c.Swtich2SelfDeliver(order, ctx.GetUserName()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
partner.CurOrderManager.OnOrderMsg(order, utils.Int64ToStr(model.WaybillStatusCancel), "商户发起运单取消10")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) AgreeOrRefuseRefund(ctx *jxcontext.Context, afsOrderID string, vendorID, approveType int, reason string) (err error) {
|
|
||||||
skus := make([]*model.OrderFinancialSkuExt, 0, 0)
|
|
||||||
afsOrder, err := partner.CurOrderManager.LoadAfsOrder(afsOrderID, vendorID)
|
|
||||||
if err == nil {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = partner.GetPurchaseOrderHandlerFromVendorID(vendorID).AgreeOrRefuseRefund(ctx, afsOrder, approveType, reason)
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
flag := model.AfsOrderFlagAgreeUserRefund
|
|
||||||
if approveType == partner.AfsApproveTypeRefused {
|
|
||||||
flag = model.AfsOrderFlagRefuseUserRefund
|
|
||||||
afsOrder.RefuseReason = reason
|
|
||||||
partner.CurOrderManager.UpdateAfsOrderFields(afsOrder, []string{"RefuseReason"})
|
|
||||||
} else {
|
|
||||||
if order, _ := partner.CurOrderManager.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID); order != nil {
|
|
||||||
var (
|
|
||||||
db = dao.GetDB()
|
|
||||||
)
|
|
||||||
waybills, _ := dao.GetWaybills(db, order.VendorOrderID, nil)
|
|
||||||
//美团的订单如果是同意全部退款,要取消所有三方运单并停止调度
|
|
||||||
if order.VendorID == model.VendorIDMTWM || order.VendorID == model.VendorIDJX || order.VendorID == model.VendorIDEBAI {
|
|
||||||
var (
|
|
||||||
afsCount, orderCount int
|
|
||||||
)
|
|
||||||
skus, _ = dao.GetAfsOrderSkuInfo(db, order.VendorOrderID, afsOrderID, order.VendorID, false)
|
|
||||||
for _, v := range skus {
|
|
||||||
afsCount += v.Count
|
|
||||||
}
|
|
||||||
for _, v := range order.Skus {
|
|
||||||
orderCount += v.Count
|
|
||||||
}
|
|
||||||
//如果售后退款的商品数等于订单商品数,我就当是全部退款了
|
|
||||||
if afsCount == orderCount && order.VendorID == model.VendorIDMTWM {
|
|
||||||
order.DeliveryFlag |= model.OrderDeliveryFlagMaskScheduleDisabled
|
|
||||||
partner.CurOrderManager.UpdateOrderFields(order, []string{"DeliveryFlag"})
|
|
||||||
for _, v := range waybills {
|
|
||||||
c.CancelWaybill(v, partner.CancelWaybillReasonOther, ctx.GetUserName()+":11"+partner.CancelWaybillReasonStrActive)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if afsCount == orderCount && order.VendorID == model.VendorIDJX {
|
|
||||||
order.DeliveryFlag |= model.OrderDeliveryFlagMaskScheduleDisabled
|
|
||||||
order.Status = model.OrderStatusCanceled
|
|
||||||
order.VendorStatus = utils.Int2Str(model.OrderStatusCanceled)
|
|
||||||
partner.CurOrderManager.UpdateOrderFields(order, []string{"DeliveryFlag", "Status", "VendorStatus"})
|
|
||||||
}
|
|
||||||
if afsCount == orderCount && order.VendorID == model.VendorIDEBAI {
|
|
||||||
order.DeliveryFlag |= model.OrderDeliveryFlagMaskScheduleDisabled
|
|
||||||
order.Status = model.OrderStatusCanceled
|
|
||||||
order.VendorStatus = "10" // 饿百取消订单
|
|
||||||
partner.CurOrderManager.UpdateOrderFields(order, []string{"DeliveryFlag", "Status", "VendorStatus"})
|
|
||||||
for _, v := range waybills {
|
|
||||||
c.CancelWaybill(v, partner.CancelWaybillReasonOther, ctx.GetUserName()+":12"+partner.CancelWaybillReasonStrActive)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if order.EarningType == model.EarningTypePoints {
|
|
||||||
var (
|
|
||||||
skuMap = make(map[int]*model.OrderSku)
|
|
||||||
diff int64
|
|
||||||
)
|
|
||||||
for _, sku := range order.Skus {
|
|
||||||
skuMap[sku.SkuID] = sku
|
|
||||||
}
|
|
||||||
//京东商城和京西要重新算totalshopmoney等
|
|
||||||
if order.VendorID == model.VendorIDJDShop || order.VendorID == model.VendorIDJX {
|
|
||||||
skus, _ := dao.GetAfsOrderSkuInfo(db, order.VendorOrderID, afsOrderID, order.VendorID, false)
|
|
||||||
for _, v := range skus {
|
|
||||||
if skuMap[v.SkuID] != nil {
|
|
||||||
diff += skuMap[v.SkuID].SalePrice * int64(v.Count)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
order.TotalShopMoney = utils.Float64TwoInt64(float64(float64(order.TotalShopMoney)/jdshopapi.JdsPayPercentage-float64(diff)) * jdshopapi.JdsPayPercentage)
|
|
||||||
if len(waybills) > 0 {
|
|
||||||
jxutils.RefreshOrderEarningPrice3(order, order.OrderPayPercentage, waybills[0])
|
|
||||||
} else {
|
|
||||||
jxutils.RefreshOrderEarningPrice2(order, order.OrderPayPercentage)
|
|
||||||
}
|
|
||||||
dao.UpdateEntity(db, order, "TotalShopMoney", "NewEarningPrice")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dao.SetAfsOrderFlag(dao.GetDB(), ctx.GetUserName(), afsOrderID, vendorID, flag)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//if approveType != partner.AfsApproveTypeRefused && err == nil {
|
|
||||||
// storeDetail, err := partner.CurOrderManager.LoadStoreDetail(afsOrder.StoreID, afsOrder.VendorID)
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// if storeDetail.IsPrintRefundOrder == model.YES { // 打印退款订单
|
|
||||||
// order2, _ := partner.CurOrderManager.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID)
|
|
||||||
// order2.Status = model.AfsOrderStatusFinished
|
|
||||||
// _, err = netprinter.PrintRefundOrCancelOrder(jxcontext.AdminCtx, model.NO, order2, afsOrder.StoreID)
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) ConfirmReceivedReturnGoods(ctx *jxcontext.Context, afsOrderID string, vendorID int) (err error) {
|
|
||||||
afsOrder, err := partner.CurOrderManager.LoadAfsOrder(afsOrderID, vendorID)
|
|
||||||
if err == nil {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = partner.GetPurchaseOrderHandlerFromVendorID(vendorID).ConfirmReceivedReturnGoods(ctx, afsOrder)
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
dao.SetAfsOrderFlag(dao.GetDB(), ctx.GetUserName(), afsOrderID, vendorID, model.AfsOrderFlagMaskReturnGoods)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) PartRefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, refundSkuList []*model.OrderSku, reason string) (err error) {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).PartRefundOrder(ctx, order, refundSkuList, reason)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) RefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).RefundOrder(ctx, order, reason)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) ConfirmSelfTake(ctx *jxcontext.Context, vendorOrderID string, vendorID int, selfTakeCode string) (err error) {
|
|
||||||
order, err2 := partner.CurOrderManager.LoadOrder(vendorOrderID, vendorID)
|
|
||||||
if err = err2; err == nil {
|
|
||||||
err = c.confirmSelfTake(ctx, order, selfTakeCode)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) SetOrderWaybillTip(ctx *jxcontext.Context, vendorOrderID string, vendorID int, tipFee int64, isPay int) (errCode string, err error) {
|
|
||||||
order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, vendorID)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
errCode, err = c.CheckStoreBalanceWithTip(ctx, order, tipFee, isPay)
|
|
||||||
if err != nil {
|
|
||||||
return errCode, err
|
|
||||||
}
|
|
||||||
err = c.SetOrderWaybillTipByOrder(ctx, order, tipFee)
|
|
||||||
return errCode, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) CheckStoreBalanceWithTip(ctx *jxcontext.Context, order *model.GoodsOrder, tipFee int64, isPay int) (errCode string, err error) {
|
|
||||||
var (
|
|
||||||
db = dao.GetDB()
|
|
||||||
)
|
|
||||||
roundTipFee := tipFee / 100 * 100
|
|
||||||
if roundTipFee != tipFee {
|
|
||||||
return model.ErrCodeOnePayTipFeeMore, fmt.Errorf("小费必须是1元的整数倍")
|
|
||||||
}
|
|
||||||
//if order.WaybillTipMoney >= tipFee {
|
|
||||||
// return model.ErrCodeOnePayTipFeeMore, fmt.Errorf("本次小费金额不能小于已经支付的小费")
|
|
||||||
//}
|
|
||||||
if order.CreateDeliveryType == model.YES {
|
|
||||||
//加小费只判断余额
|
|
||||||
storeAcct, err := cms.GetStoreAcctBalance(ctx, jxutils.GetSaleStoreIDFromOrder(order))
|
|
||||||
if err != nil {
|
|
||||||
return errCode, fmt.Errorf("获取账户余额失败!")
|
|
||||||
}
|
|
||||||
if tipFee > int64(storeAcct.AccountBalance) {
|
|
||||||
return model.ErrCodeAccountBalanceNotEnough, fmt.Errorf("门店账户余额不足,不能加小费!")
|
|
||||||
}
|
|
||||||
if tipFee > 1000 {
|
|
||||||
return model.ErrCodeAccountBalanceNotEnough, fmt.Errorf("小费单次加价金额大于十元")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 品牌发单
|
|
||||||
storeDetail, err := dao.GetStoreDetail(db, order.JxStoreID, order.VendorID, order.VendorOrgCode)
|
|
||||||
if err != nil || storeDetail == nil {
|
|
||||||
return model.ErrCodeAccountBalanceNotEnough, fmt.Errorf("根据订单获取门店详情错误:%v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
brandAcct, err := dao.GetBrandBalance(db, storeDetail.BrandID)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if tipFee > int64(brandAcct) {
|
|
||||||
return model.ErrCodeAccountBalanceNotEnough, fmt.Errorf("品牌账户余额不足,不能加小费!")
|
|
||||||
}
|
|
||||||
if tipFee > 1000 {
|
|
||||||
return model.ErrCodeOnePayTipFeeMore, fmt.Errorf("小费单次加价金额大于十元")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 是否确认支付
|
|
||||||
if isPay != model.YES {
|
|
||||||
return model.ErrCodeIsPaySure, fmt.Errorf("此订单已经支付小费[%d]元,本次增加小费[%d]元,总支出小费[%d]元", order.WaybillTipMoney/100, tipFee/100, (order.WaybillTipMoney+tipFee)/100)
|
|
||||||
}
|
|
||||||
|
|
||||||
return errCode, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func isWaybillCanAddTip(waybill *model.Waybill) (isCan bool) {
|
|
||||||
isCan = waybill.Status >= model.WaybillStatusNew && waybill.Status < model.WaybillStatusAccepted && partner.GetWaybillTipUpdater(waybill.WaybillVendorID) != nil
|
|
||||||
return isCan
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) SetOrderWaybillTipByOrder(ctx *jxcontext.Context, order *model.GoodsOrder, tipFee int64) (err error) {
|
|
||||||
db := dao.GetDB()
|
|
||||||
thisTimeTipFee := tipFee - order.WaybillTipMoney
|
|
||||||
storeDetail, _ := dao.GetStoreDetail(db, jxutils.GetSaleStoreIDFromOrder(order), order.VendorID, "")
|
|
||||||
flag := false
|
|
||||||
// 如果平台支持设置配送小费,必须要成功设置
|
|
||||||
if handler := partner.GetWaybillTipUpdater(order.VendorID); handler != nil {
|
|
||||||
if err = handler.UpdateWaybillTip(ctx, order.VendorOrgCode, order.VendorStoreID, order.VendorOrderID, "", "", utils.Int2Str(storeDetail.CityCode), thisTimeTipFee); err != nil {
|
|
||||||
globals.SugarLogger.Debugf("订单id[%s],平台id[%d],427,err :[%v]", order.VendorOrderID, order.VendorID, err)
|
|
||||||
} else {
|
|
||||||
//加小费成功扣钱
|
|
||||||
if order.CreateDeliveryType == model.YES {
|
|
||||||
if err = partner.CurStoreAcctManager.InsertStoreAcctExpendAndUpdateStoreAcctBalance(ctx, jxutils.GetSaleStoreIDFromOrder(order), int(thisTimeTipFee), partner.StoreAcctTypeExpendCreateWaybillTip, order.VendorOrderID, "", 0); err == nil {
|
|
||||||
flag = true
|
|
||||||
}
|
|
||||||
} else if order.CreateDeliveryType == model.NO {
|
|
||||||
if err = partner.CurStoreAcctManager.InsertBrandBill(ctx, storeDetail.BrandID, int(thisTimeTipFee), model.BrandBillTypeExpend, model.BrandBillFeeTypeTipFee, order.VendorOrderID, ""); err == nil {
|
|
||||||
flag = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} //有可能进else,没加得起平台小费,就要到下面扣账户
|
|
||||||
|
|
||||||
order.WaybillTipMoney = tipFee
|
|
||||||
partner.CurOrderManager.UpdateOrderFields(order, []string{"WaybillTipMoney"})
|
|
||||||
|
|
||||||
waybills, err := dao.GetWayBillByOrderID(db, 0, order.VendorID, 0, order.VendorOrderID)
|
|
||||||
if err == nil {
|
|
||||||
var waybills2 []*model.Waybill
|
|
||||||
for _, v := range waybills {
|
|
||||||
// 必须是三方配送
|
|
||||||
if !model.IsWaybillPlatformOwn(v) && isWaybillCanAddTip(v) {
|
|
||||||
waybills2 = append(waybills2, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(waybills2) > 0 {
|
|
||||||
task := tasksch.NewParallelTask("SetOrderWaybillTipByOrder", nil, ctx,
|
|
||||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
|
||||||
waybill := batchItemList[0].(*model.Waybill)
|
|
||||||
handler := partner.GetWaybillTipUpdater(waybill.WaybillVendorID)
|
|
||||||
if waybill.WaybillVendorID == model.VendorIDDada {
|
|
||||||
err = handler.UpdateWaybillTip(ctx, waybill.VendorOrgCode, storeDetail.VendorStoreID, waybill.VendorOrderID, waybill.VendorWaybillID, waybill.VendorWaybillID2, utils.Int2Str(storeDetail.CityCode), tipFee)
|
|
||||||
globals.SugarLogger.Debugf("订单id[%s],平台id[%d],462,err :[%v]", order.VendorOrderID, order.VendorID, err)
|
|
||||||
} else {
|
|
||||||
err = handler.UpdateWaybillTip(ctx, waybill.VendorOrgCode, storeDetail.VendorStoreID, waybill.VendorOrderID, waybill.VendorWaybillID, waybill.VendorWaybillID2, utils.Int2Str(storeDetail.CityCode), thisTimeTipFee)
|
|
||||||
globals.SugarLogger.Debugf("订单id[%s],平台id[%d],465,err :[%v]", order.VendorOrderID, order.VendorID, err)
|
|
||||||
}
|
|
||||||
return nil, err
|
|
||||||
}, waybills2)
|
|
||||||
tasksch.HandleTask(task, nil, false).Run()
|
|
||||||
_, err = task.GetResult(0)
|
|
||||||
if err == nil {
|
|
||||||
//加起了至少只扣一次钱
|
|
||||||
if !flag {
|
|
||||||
//加小费成功扣钱
|
|
||||||
if order.CreateDeliveryType == model.YES {
|
|
||||||
partner.CurStoreAcctManager.InsertStoreAcctExpendAndUpdateStoreAcctBalance(ctx, jxutils.GetSaleStoreIDFromOrder(order), int(thisTimeTipFee), partner.StoreAcctTypeExpendCreateWaybillTip, order.VendorOrderID, "", 0)
|
|
||||||
} else if order.CreateDeliveryType == model.NO {
|
|
||||||
partner.CurStoreAcctManager.InsertBrandBill(ctx, storeDetail.BrandID, int(thisTimeTipFee), model.BrandBillTypeExpend, model.BrandBillFeeTypeTipFee, order.VendorOrderID, "")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) confirmSelfTake(ctx *jxcontext.Context, order *model.GoodsOrder, selfTakeCode string) (err error) {
|
|
||||||
vendorID := order.VendorID
|
|
||||||
// if vendorID == model.VendorIDJD || vendorID == model.VendorIDJX {
|
|
||||||
if vendorID != model.VendorIDJX {
|
|
||||||
handler := partner.GetPurchaseOrderHandlerFromVendorID(vendorID)
|
|
||||||
if selfTakeCode == autoSelfTakeCode {
|
|
||||||
if selfTakeCode, err = handler.GetSelfTakeCode(ctx, order); err != nil {
|
|
||||||
return fmt.Errorf("获取订单:%s自提货码失败,原始错误:%s", order.VendorOrderID, err.Error())
|
|
||||||
}
|
|
||||||
if selfTakeCode == "" {
|
|
||||||
return fmt.Errorf("订单:%s 自动提货失败,请手动输入自提码", order.VendorOrderID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = handler.ConfirmSelfTake(ctx, order, selfTakeCode)
|
|
||||||
} else {
|
|
||||||
if selfTakeCode != order.ConsigneeMobile && selfTakeCode != order.VendorOrderID[len(order.VendorOrderID)-4:] {
|
|
||||||
return fmt.Errorf("京西平台自提单,自提码为订单后四位或完整的下单电话")
|
|
||||||
}
|
|
||||||
orderStatus := &model.OrderStatus{
|
|
||||||
VendorOrderID: order.VendorOrderID,
|
|
||||||
VendorID: model.VendorIDJX,
|
|
||||||
OrderType: model.OrderTypeOrder,
|
|
||||||
RefVendorOrderID: order.VendorOrderID,
|
|
||||||
RefVendorID: model.VendorIDJX,
|
|
||||||
VendorStatus: utils.Int2Str(model.OrderStatusFinished),
|
|
||||||
Status: model.OrderStatusFinished,
|
|
||||||
StatusTime: time.Now(),
|
|
||||||
Remark: "自提完成",
|
|
||||||
}
|
|
||||||
jxutils.CallMsgHandlerAsync(func() {
|
|
||||||
err = partner.CurOrderManager.OnOrderStatusChanged("", orderStatus)
|
|
||||||
}, jxutils.ComposeUniversalOrderID(order.VendorOrderID, model.VendorIDJX))
|
|
||||||
}
|
|
||||||
// } else {
|
|
||||||
// err = fmt.Errorf("自提核销不支持%s平台订单", model.VendorChineseNames[order.VendorID])
|
|
||||||
// }
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) ConfirmSelfTakeOrders(ctx *jxcontext.Context, vendorIDs []int, orderCreatedAfter, orderCreatedBefore time.Time, isAsync, isContinueWhenError bool) (hint string, err error) {
|
|
||||||
orderList, err := dao.GetPendingFakeOrders(dao.GetDB(), vendorIDs, orderCreatedAfter, orderCreatedBefore)
|
|
||||||
if err == nil {
|
|
||||||
if len(orderList) > 0 {
|
|
||||||
task := tasksch.NewParallelTask(fmt.Sprintf("自动完成内部自提单%v,%s", vendorIDs, utils.Time2Str(orderCreatedAfter)), tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
|
|
||||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
|
||||||
order := batchItemList[0].(*model.GoodsOrder)
|
|
||||||
if order.Status == model.OrderStatusAccepted {
|
|
||||||
if handler := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID); handler != nil {
|
|
||||||
err = handler.AcceptOrRefuseOrder(order, true, ctx.GetUserName())
|
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
if err = c.confirmSelfTake(ctx, order, autoSelfTakeCode); err == nil {
|
|
||||||
retVal = []int{1}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return retVal, err
|
|
||||||
}, orderList)
|
|
||||||
tasksch.HandleTask(task, nil, true).Run()
|
|
||||||
if isAsync {
|
|
||||||
hint = task.GetID()
|
|
||||||
} else {
|
|
||||||
resultList, err2 := task.GetResult(0)
|
|
||||||
if err = err2; err == nil {
|
|
||||||
hint = utils.Int2Str(len(resultList))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hint, err
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,90 +0,0 @@
|
|||||||
package defsch
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/netprinter"
|
|
||||||
push "git.rosy.net.cn/jx-callback/business/jxutils/unipush"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/weixinmsg"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/msghub"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
autoRejectSkuMap = map[int]int{
|
|
||||||
33996: 1,
|
|
||||||
33995: 1,
|
|
||||||
33994: 1,
|
|
||||||
33991: 1,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s *DefScheduler) OnAfsOrderNew(order *model.AfsOrder, isPending bool) (err error) {
|
|
||||||
if order.Status == model.AfsOrderStatusWait4Approve {
|
|
||||||
if !isPending {
|
|
||||||
if isAutoRejectAfsOrder(order) {
|
|
||||||
if handler := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID); handler != nil {
|
|
||||||
if err := handler.AgreeOrRefuseRefund(jxcontext.AdminCtx, order, partner.AfsApproveTypeRefused, "抱歉,蟹券不接受退货或换货"); err != nil {
|
|
||||||
globals.SugarLogger.Debugf("OnAfsOrderNew, orderID:%s, afsOrderID:%s failed with err:%v", order.VendorOrderID, order.AfsOrderID, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if order != nil && order.VendorID == model.VendorIDTaoVegetable {
|
|
||||||
result, _ := dao.GetAfsOrders(dao.GetDB(), model.VendorIDTaoVegetable, order.VendorOrderID, "")
|
|
||||||
if len(result) <= model.YES {
|
|
||||||
msghub.OnNewWait4ApproveAfsOrder(order)
|
|
||||||
weixinmsg.NotifyAfsOrderStatus(order)
|
|
||||||
push.NotifyAfsOrder(order)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
msghub.OnNewWait4ApproveAfsOrder(order)
|
|
||||||
weixinmsg.NotifyAfsOrderStatus(order)
|
|
||||||
push.NotifyAfsOrder(order)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
storeDetail, err := partner.CurOrderManager.LoadStoreDetail(order.JxStoreID, order.VendorID)
|
|
||||||
if err == nil {
|
|
||||||
if storeDetail.IsPrintRefundOrder == model.YES { // 打印退款订单
|
|
||||||
order2, _ := partner.CurOrderManager.LoadOrder(order.VendorOrderID, order.VendorID)
|
|
||||||
_, err = netprinter.PrintRefundOrCancelOrder(jxcontext.AdminCtx, model.NO, order2, order2.JxStoreID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//if order.Status == model.AfsOrderStatusWait4Approve || order.Status == model.AfsOrderStatusFinished || order.Status == model.AfsOrderStatusNew {
|
|
||||||
// // 京西云打印机打印数据-如果门店使用京西打印机才使用如下代码块
|
|
||||||
// store, err := dao.GetStoreDetail(dao.GetDB(), order.JxStoreID, order.VendorID, order.VendorOrgCode)
|
|
||||||
// if err == nil && store.PrinterVendorID == model.VendorIDJxprint && store.IsPrintCancelOrder == model.YES {
|
|
||||||
// orderObj, _ := partner.CurOrderManager.LoadOrder(order.VendorOrderID, order.VendorID)
|
|
||||||
// if orderObj != nil {
|
|
||||||
// netprinter.PrintOrderByOrder(jxcontext.AdminCtx, orderObj, model.PrintAfsOrder, order)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *DefScheduler) OnAfsOrderStatusChanged(order *model.AfsOrder, status *model.OrderStatus, isPending bool) (err error) {
|
|
||||||
if status.Status == model.AfsOrderStatusWait4ReceiveGoods {
|
|
||||||
if !isPending {
|
|
||||||
msghub.OnKeyAfsOrderStatusChanged(order)
|
|
||||||
weixinmsg.NotifyAfsOrderStatus(order)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func isAutoRejectAfsOrder(order *model.AfsOrder) (isReject bool) {
|
|
||||||
for _, v := range order.Skus {
|
|
||||||
if autoRejectSkuMap[jxutils.GetSkuIDFromOrderSkuFinancial(v)] == 1 {
|
|
||||||
isReject = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return isReject
|
|
||||||
}
|
|
||||||
@@ -1,591 +0,0 @@
|
|||||||
package defsch
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxstore/cms"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
|
||||||
beego "github.com/astaxie/beego/server/web"
|
|
||||||
"math"
|
|
||||||
"math/rand"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s *DefScheduler) loadSavedOrderByID(vendorOrderID string, vendorID int, isForceLoad bool) *WatchOrderInfo {
|
|
||||||
return s.loadSavedOrderFromMap(&model.OrderStatus{
|
|
||||||
RefVendorOrderID: vendorOrderID,
|
|
||||||
RefVendorID: vendorID,
|
|
||||||
}, isForceLoad)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *DefScheduler) SelfDeliveringAndUpdateStatus(ctx *jxcontext.Context, vendorOrderID string, vendorID int, userName, courierName, courierMobile string) (err error) {
|
|
||||||
var order *model.GoodsOrder
|
|
||||||
jxutils.CallMsgHandler(func() {
|
|
||||||
err = func() (err error) {
|
|
||||||
savedOrderInfo := s.loadSavedOrderByID(vendorOrderID, vendorID, true)
|
|
||||||
if savedOrderInfo != nil {
|
|
||||||
order = savedOrderInfo.order
|
|
||||||
if err = s.isPossibleSwitch2SelfDelivery(order); err == nil { // 是否能转自送
|
|
||||||
err = s.cancelOtherWaybillsCheckOrderDeliveryFlag(savedOrderInfo, nil, partner.CancelWaybillReasonOther, ctx.GetUserName()+"17"+partner.CancelWaybillReasonStrActive)
|
|
||||||
if err == nil {
|
|
||||||
if model.IsOrderDeliveryByStore(order) {
|
|
||||||
if order.Status < model.OrderStatusDelivering {
|
|
||||||
storeDetail, err2 := dao.GetStoreDetail(dao.GetDB(), order.StoreID, order.VendorID, "")
|
|
||||||
phone := userName
|
|
||||||
if err = err2; err == nil {
|
|
||||||
phone = storeDetail.Tel1
|
|
||||||
}
|
|
||||||
err = s.SelfDeliverDelivering(order, phone) // 取消平台自配送
|
|
||||||
s.CancelAll3rdWaybills(ctx, vendorOrderID, vendorID, true) // 取消三方平台配送以及调度
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if order.Status < model.OrderStatusDelivering {
|
|
||||||
err = s.Swtich2SelfDeliver(order, userName)
|
|
||||||
} else if order.VendorID == order.WaybillVendorID { // 状态为配送中,且是购物平台运单,不能转自送了
|
|
||||||
err = scheduler.ErrOrderStatusIsNotSuitable4CurOperation
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
order.Status = model.OrderStatusDelivering
|
|
||||||
order.DeliveryFlag |= model.OrderDeliveryFlagMaskScheduleDisabled | model.OrderDeliveryFlagMaskPurcahseDisabled
|
|
||||||
if err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order); err == nil {
|
|
||||||
s.stopTimer(savedOrderInfo)
|
|
||||||
//return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
order = &model.GoodsOrder{
|
|
||||||
VendorOrderID: vendorOrderID,
|
|
||||||
VendorID: vendorID,
|
|
||||||
}
|
|
||||||
err = scheduler.ErrCanNotFindOrder
|
|
||||||
}
|
|
||||||
vendorStatus := fmt.Sprintf("%s转商户自送成功", ctx.GetUserName())
|
|
||||||
remark := ""
|
|
||||||
if err != nil {
|
|
||||||
vendorStatus = fmt.Sprintf("%s转商户自送失败", ctx.GetUserName())
|
|
||||||
remark = err.Error()
|
|
||||||
partner.CurOrderManager.OnOrderMsg(order, vendorStatus, remark)
|
|
||||||
return err
|
|
||||||
} else {
|
|
||||||
partner.CurOrderManager.OnOrderMsg(order, vendorStatus, remark)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 上面是真的转自送,支持美团,饿百,京东,如果时抖店,抖店暂时全部是自送的!但是有骑手信息时,就是一个白嫖单子!
|
|
||||||
if courierName != "" && courierMobile != "" && err == nil {
|
|
||||||
timeNow := time.Now()
|
|
||||||
rand.Seed(timeNow.UnixNano())
|
|
||||||
randNumber := rand.Int63n(640)
|
|
||||||
if randNumber < 60 {
|
|
||||||
randNumber += 60
|
|
||||||
}
|
|
||||||
randTime := time.Duration(randNumber) * time.Second
|
|
||||||
bill := &model.Waybill{
|
|
||||||
VendorWaybillID: order.VendorOrderID,
|
|
||||||
VendorWaybillID2: "",
|
|
||||||
WaybillVendorID: model.VendorJXFakeWL,
|
|
||||||
VendorOrderID: order.VendorOrderID,
|
|
||||||
OrderVendorID: order.VendorID,
|
|
||||||
CourierName: courierName,
|
|
||||||
CourierMobile: courierMobile,
|
|
||||||
Status: model.OrderStatusNew,
|
|
||||||
VendorStatus: utils.Int2Str(model.OrderStatusNew),
|
|
||||||
ActualFee: 0,
|
|
||||||
DesiredFee: 0,
|
|
||||||
TipFee: 0,
|
|
||||||
DuplicatedCount: 0,
|
|
||||||
DeliveryFlag: 0,
|
|
||||||
WaybillCreatedAt: timeNow,
|
|
||||||
WaybillFinishedAt: utils.DefaultTimeValue,
|
|
||||||
StatusTime: timeNow.Add(randTime), // 下一状态时间
|
|
||||||
OriginalData: "",
|
|
||||||
Remark: "自定义物流单(全平台刷单)",
|
|
||||||
VendorOrgCode: order.VendorOrgCode,
|
|
||||||
}
|
|
||||||
err = dao.CreateEntity(dao.GetDB(), bill)
|
|
||||||
//if order.VendorID == model.VendorIDTaoVegetable {
|
|
||||||
// order.VendorWaybillID = order.VendorOrderID
|
|
||||||
// order.WaybillVendorID = model.VendorJXFakeWL
|
|
||||||
// dao.UpdateEntity(dao.GetDB(), order, "VendorWaybillID", "WaybillVendorID")
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}()
|
|
||||||
}, jxutils.ComposeUniversalOrderID(vendorOrderID, vendorID))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *DefScheduler) canOrderCreateWaybillNormally(order *model.GoodsOrder, savedOrderInfo *WatchOrderInfo) (err error) {
|
|
||||||
if !(order.LockStatus != model.OrderStatusLocked && order.Status >= model.OrderStatusFinishedPickup && order.Status < model.OrderStatusEndBegin) {
|
|
||||||
err = fmt.Errorf("当前订单%s没有处于拣货完成且没有结束没有锁定的订单才能进行召唤配送操作", order.VendorOrderID)
|
|
||||||
} else if model.IsOrderHaveWaybill(order) {
|
|
||||||
err = fmt.Errorf("当前订单%s已经有了有效的承运人%s了", order.VendorOrderID, jxutils.GetVendorName(order.WaybillVendorID))
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *DefScheduler) isPossibleSwitch2SelfDelivery(order *model.GoodsOrder) (err error) {
|
|
||||||
//TODO 刷单用,之后不刷单了删除
|
|
||||||
//if order.VendorID == model.VendorIDDD {
|
|
||||||
// return nil
|
|
||||||
//}
|
|
||||||
|
|
||||||
if model.IsOrderDeliveryByPlatform(order) {
|
|
||||||
if order.Status < model.OrderStatusFinishedPickup {
|
|
||||||
err = fmt.Errorf("拣货完成后才能转自配送")
|
|
||||||
} else if order.Status == model.OrderStatusFinishedPickup {
|
|
||||||
if time.Now().Sub(order.StatusTime) < minMinute2Schedule3rdCarrier*time.Minute {
|
|
||||||
err = fmt.Errorf("非自配送门店转3方配送至少要求拣货完成后%d分钟才能操作", minMinute2Schedule3rdCarrier)
|
|
||||||
}
|
|
||||||
} else if order.Status >= model.OrderStatusDelivering && order.Status < model.OrderStatusEndBegin {
|
|
||||||
if model.IsOrderHaveOwnWaybill(order) {
|
|
||||||
err = fmt.Errorf("%s物流已在配送中,不能转自配送", jxutils.GetVendorName(order.VendorID))
|
|
||||||
}
|
|
||||||
} else if order.Status >= model.OrderStatusEndBegin {
|
|
||||||
err = fmt.Errorf("订单%s已经结束,请刷新状态", order.VendorOrderID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建订单
|
|
||||||
func (s *DefScheduler) CreateWaybillOnProviders4SavedOrder(ctx *jxcontext.Context, savedOrderInfo *WatchOrderInfo, courierVendorIDs, excludeCourierVendorIDs []int, forceCreate bool, maxDeliveryFee int64) (bills []*model.Waybill, err error) {
|
|
||||||
order := savedOrderInfo.order
|
|
||||||
// 查看订单状态是否处于可配送状态
|
|
||||||
if !forceCreate {
|
|
||||||
err = s.canOrderCreateWaybillNormally(order, nil)
|
|
||||||
}
|
|
||||||
// 检查订单是否在配送状态
|
|
||||||
waybills, err := dao.GetWaybills(dao.GetDB(), order.VendorOrderID, nil)
|
|
||||||
for _, v := range waybills {
|
|
||||||
if v.Status >= model.OrderStatusDelivering && v.Status != model.OrderStatusCanceled && v.Status != model.OrderStatusFinished {
|
|
||||||
err = fmt.Errorf("订单已经在配送中,无法创建运单,有疑问请联系管理员")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
if forceCreate {
|
|
||||||
maxDeliveryFee = math.MaxInt64
|
|
||||||
}
|
|
||||||
// 生成美团订单(三方订单)
|
|
||||||
if bills, err = s.CreateWaybillOnProviders(ctx, order, courierVendorIDs, excludeCourierVendorIDs, maxDeliveryFee, forceCreate); err == nil {
|
|
||||||
if forceCreate {
|
|
||||||
order.DeliveryFlag |= model.OrderDeliveryFlagMaskScheduleDisabled
|
|
||||||
err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order)
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
if forceCreate {
|
|
||||||
s.stopTimer(savedOrderInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取门店品牌余额
|
|
||||||
storeAcct, err := cms.GetStoreAcctBalance(ctx, jxutils.GetSaleStoreIDFromOrder(order)) // 获取门店余额
|
|
||||||
|
|
||||||
// 门店详细信息
|
|
||||||
storeList, err := dao.GetStoreDetail(dao.GetDB(), jxutils.GetSaleStoreIDFromOrder(order), savedOrderInfo.order.VendorID, order.VendorOrgCode)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
deliveryFeeMap, _ := s.QueryOrderWaybillFeeInfoEx(ctx, order.VendorOrderID, order.VendorID)
|
|
||||||
// 不管是门店发单还是品牌发单都要扣钱,门店发单扣门店,品牌发单扣品牌
|
|
||||||
if order.CreateDeliveryType == model.YES {
|
|
||||||
// 获取平台配送费
|
|
||||||
isEqual, isZero, _ := partner.CurStoreAcctManager.CheckStoreAcctExpendExist(order.VendorOrderID) // 当前订单的支出记录
|
|
||||||
expend, lastFee, _ := partner.CurStoreAcctManager.GetStoreAcctExpendLastCreateWayBillFee(order.VendorOrderID) // 最后一个运单支出记录
|
|
||||||
// 收最贵的一个订单配送费(配送费发送变化,收取最贵的价格)
|
|
||||||
if !isZero && !isEqual { // 满足此条件是,门店发单已经存在此订单的发单记录,且支出记录大于退还记录
|
|
||||||
var newPrice int64
|
|
||||||
if len(courierVendorIDs) == 1 {
|
|
||||||
courierVendorID := courierVendorIDs[0]
|
|
||||||
if _, ok := deliveryFeeMap[courierVendorID]; ok {
|
|
||||||
newPrice = deliveryFeeMap[courierVendorID].DeliveryFee
|
|
||||||
}
|
|
||||||
} else if len(courierVendorIDs) == 0 {
|
|
||||||
var maxFee int64
|
|
||||||
for _, v := range deliveryFeeMap {
|
|
||||||
if v.DeliveryFee > maxFee {
|
|
||||||
maxFee = v.DeliveryFee
|
|
||||||
}
|
|
||||||
}
|
|
||||||
newPrice = maxFee
|
|
||||||
}
|
|
||||||
// 门店支出运费,门店发单
|
|
||||||
if order.CreateDeliveryType == model.YES {
|
|
||||||
if storeAcct.AccountBalance > int(newPrice) {
|
|
||||||
if int(newPrice) > lastFee {
|
|
||||||
// 门店支出费用
|
|
||||||
partner.CurStoreAcctManager.InsertStoreAcctExpendAndUpdateStoreAcctBalance(ctx, jxutils.GetSaleStoreIDFromOrder(order), int(newPrice)-lastFee, partner.StoreAcctTypeExpendCreateWaybill2ndMore, order.VendorOrderID, "", expend.ID) //int(newPrice)-lastFee
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else { // 新订单的发单记录,门店发单扣门店,品牌发单扣品牌
|
|
||||||
if len(courierVendorIDs) == 1 {
|
|
||||||
courierVendorID := courierVendorIDs[0]
|
|
||||||
if _, ok := deliveryFeeMap[courierVendorID]; ok {
|
|
||||||
if order.CreateDeliveryType == model.YES {
|
|
||||||
err = partner.CurStoreAcctManager.InsertStoreAcctExpendAndUpdateStoreAcctBalance(ctx, jxutils.GetSaleStoreIDFromOrder(order), int(deliveryFeeMap[courierVendorID].DeliveryFee), partner.StoreAcctTypeExpendCreateWaybillEx, order.VendorOrderID, "", 0) //int(newPrice)-lastFee
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if len(courierVendorIDs) == 0 {
|
|
||||||
var maxFee int64
|
|
||||||
for _, v := range deliveryFeeMap {
|
|
||||||
if v.DeliveryFee > maxFee {
|
|
||||||
maxFee = v.DeliveryFee
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = partner.CurStoreAcctManager.InsertStoreAcctExpendAndUpdateStoreAcctBalance(ctx, jxutils.GetSaleStoreIDFromOrder(order), int(maxFee), partner.StoreAcctTypeExpendCreateWaybillEx, order.VendorOrderID, "", 0) //int(maxFee)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 看看此订单有无发单记录,小费记录
|
|
||||||
// 品牌发单
|
|
||||||
if len(courierVendorIDs) == 1 {
|
|
||||||
courierVendorID := courierVendorIDs[0]
|
|
||||||
if _, ok := deliveryFeeMap[courierVendorID]; ok {
|
|
||||||
err = partner.CurStoreAcctManager.InsertBrandBill(jxcontext.AdminCtx, storeList.BrandID, int(deliveryFeeMap[courierVendorID].DeliveryFee), model.BrandBillTypeExpend, model.BrandBillFeeTypeDelivery, order.VendorOrderID, order.VendorWaybillID)
|
|
||||||
}
|
|
||||||
} else if len(courierVendorIDs) == 0 {
|
|
||||||
var maxFee int64
|
|
||||||
for _, v := range deliveryFeeMap {
|
|
||||||
if v.DeliveryFee > maxFee {
|
|
||||||
maxFee = v.DeliveryFee
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = partner.CurStoreAcctManager.InsertBrandBill(jxcontext.AdminCtx, storeList.BrandID, int(maxFee), model.BrandBillTypeExpend, model.BrandBillFeeTypeDelivery, order.VendorOrderID, order.VendorWaybillID)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return bills, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
globals.SugarLogger.Debugf("CreateWaybillOnProviders4SavedOrder orderID:%s failed with error:%v", order.VendorOrderID, err)
|
|
||||||
}
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建三方运单
|
|
||||||
func (s *DefScheduler) CreateWaybillOnProvidersEx(ctx *jxcontext.Context, vendorOrderID string, vendorID int, courierVendorIDs []int, forceCreate bool, maxDeliveryFee int64) (bills []*model.Waybill, errCode string, err error) {
|
|
||||||
savedOrderInfo := s.loadSavedOrderByID(vendorOrderID, vendorID, true)
|
|
||||||
if savedOrderInfo != nil {
|
|
||||||
order := savedOrderInfo.order
|
|
||||||
//1表示为门店发单,需要验证门店账户余额情况
|
|
||||||
if errCode, err = s.CheckStoreBalance(ctx, order, courierVendorIDs); err != nil {
|
|
||||||
return nil, errCode, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
excludeCourierVendorIDs := make([]int, 0, 0)
|
|
||||||
allDelivery := map[int]int{model.VendorIDFengNiao: 1, model.VendorIDDada: 1, model.VendorIDMTPS: 1, model.VendorIDUUPT: 1, model.VendorIDSFPS: 1}
|
|
||||||
for _, v := range courierVendorIDs {
|
|
||||||
if allDelivery[v] == model.YES {
|
|
||||||
delete(allDelivery, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for k, _ := range allDelivery {
|
|
||||||
excludeCourierVendorIDs = append(excludeCourierVendorIDs, k)
|
|
||||||
}
|
|
||||||
|
|
||||||
billFunc := func() {
|
|
||||||
bills, err = func() (bills []*model.Waybill, err error) {
|
|
||||||
if vendorID == model.VendorIDELM {
|
|
||||||
return nil, fmt.Errorf("不要直接使用饿了么订单号,请使用相应的饿百订单号")
|
|
||||||
}
|
|
||||||
// 创建可调度对象,并且存储
|
|
||||||
savedOrderInfo := s.loadSavedOrderByID(vendorOrderID, vendorID, true)
|
|
||||||
if savedOrderInfo != nil {
|
|
||||||
savedOrderInfo.order.SendOrderType = 1 // 设置为手动创建订单
|
|
||||||
order := savedOrderInfo.order
|
|
||||||
if order.DeliveryType == model.OrderDeliveryTypeSelfTake {
|
|
||||||
return nil, fmt.Errorf("订单:%s是自提单", vendorOrderID)
|
|
||||||
}
|
|
||||||
if !forceCreate {
|
|
||||||
err = s.isPossibleSwitch2SelfDelivery(order)
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
if savedOrderInfo.order.VendorID == model.VendorIDEBAI {
|
|
||||||
courierVendorIDs = []int{model.VendorIDMTPS, model.VendorIDDada}
|
|
||||||
}
|
|
||||||
order := savedOrderInfo.order
|
|
||||||
order.DeliveryFlag = 0
|
|
||||||
err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order)
|
|
||||||
// 创建订单
|
|
||||||
if bills, err = s.CreateWaybillOnProviders4SavedOrder(ctx, savedOrderInfo, courierVendorIDs, excludeCourierVendorIDs, forceCreate, maxDeliveryFee); err == nil && len(bills) > 0 {
|
|
||||||
partner.CurOrderManager.OnOrderMsg(order, "手动创建运单成功", fmt.Sprintf("%s创建%s平台运单,强发:%t,最高限价:%d", ctx.GetUserName(), model.VendorChineseNames[bills[0].WaybillVendorID], forceCreate, maxDeliveryFee))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = scheduler.ErrCanNotFindOrder
|
|
||||||
}
|
|
||||||
return bills, err
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
jxutils.CallMsgHandler(billFunc, jxutils.ComposeUniversalOrderID(vendorOrderID, vendorID))
|
|
||||||
return bills, errCode, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *DefScheduler) CheckStoreBalance(ctx *jxcontext.Context, order *model.GoodsOrder, courierVendorIDs []int) (errCode string, err error) {
|
|
||||||
var (
|
|
||||||
db = dao.GetDB()
|
|
||||||
)
|
|
||||||
deliveryFeeMap, _ := s.QueryOrderWaybillFeeInfoEx(ctx, order.VendorOrderID, order.VendorID)
|
|
||||||
if err != nil {
|
|
||||||
return errCode, fmt.Errorf("获取订单配送费错误[%v]!", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
switch order.CreateDeliveryType {
|
|
||||||
case model.NO: // 品牌发单
|
|
||||||
storeDetail, err := dao.GetStoreDetail(db, jxutils.GetSaleStoreIDFromOrder(order), order.VendorID, "")
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
brandAcct, err := dao.GetBrandBalance(db, storeDetail.BrandID)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(courierVendorIDs) == 1 {
|
|
||||||
courierVendorID := courierVendorIDs[0]
|
|
||||||
if _, ok := deliveryFeeMap[courierVendorID]; ok {
|
|
||||||
if deliveryFeeMap[courierVendorID].DeliveryFee > int64(brandAcct) {
|
|
||||||
return model.ErrCodeAccountBalanceNotEnough, fmt.Errorf("品牌账户余额小于[%v]元,不能发配送!", jxutils.IntPrice2Standard(deliveryFeeMap[courierVendorID].DeliveryFee))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if len(courierVendorIDs) == 0 {
|
|
||||||
var maxFee int64
|
|
||||||
for _, v := range deliveryFeeMap {
|
|
||||||
if v.DeliveryFee > maxFee {
|
|
||||||
v.DeliveryFee = maxFee
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if maxFee > int64(brandAcct) {
|
|
||||||
return model.ErrCodeAccountBalanceNotEnough, fmt.Errorf("品牌账户余额小于[%v]元,不能发配送!", jxutils.IntPrice2Standard(maxFee))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case model.YES: // 门店发单
|
|
||||||
//暂时这么认为,len courierVendorIDs 为1表示是老板或者运营从小程序上点的立即发单,因为小程序上是点哪个发哪个
|
|
||||||
//京西后台则是点一下发3个,len courierVendorIDs 是0
|
|
||||||
//如果是小程序上点哪个扣哪个平台的钱
|
|
||||||
//如果是后台,则选最高的那个扣
|
|
||||||
storeAcct, err := cms.GetStoreAcctBalance(ctx, jxutils.GetSaleStoreIDFromOrder(order)) // 获取门店余额
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
//1、先判断是不是第一次发:查询库里是否有这个订单的运费支出记录,再查询是否有相同金额并且类型为回退的收入记录(取消运单退回)
|
|
||||||
//前者有,后者无, 表示已经发过了,暂未取消,若这这次的发单金额小于上次的金额则不进行判断也不多扣钱,若大于则扣除‘这次金额-上次金额’的钱,余额不足问题也根据这个判断
|
|
||||||
//前者有,后者有,表示发过并且取消过了,是多次发,直接扣
|
|
||||||
//前者无,表示就是第一次发,直接扣
|
|
||||||
//2、小程序里这次金额用发单平台的金额,后台里这次金额用所有平台最高费用
|
|
||||||
isEqual, isZero, err := partner.CurStoreAcctManager.CheckStoreAcctExpendExist(order.VendorOrderID)
|
|
||||||
//表示前者有,后者无
|
|
||||||
if !isZero && !isEqual { // 当前订单支出费用大于,退还费用
|
|
||||||
var newPrice int64
|
|
||||||
if len(courierVendorIDs) == 1 {
|
|
||||||
courierVendorID := courierVendorIDs[0]
|
|
||||||
if _, ok := deliveryFeeMap[courierVendorID]; ok {
|
|
||||||
newPrice = deliveryFeeMap[courierVendorID].DeliveryFee
|
|
||||||
}
|
|
||||||
} else if len(courierVendorIDs) == 0 {
|
|
||||||
var maxFee int64
|
|
||||||
for _, v := range deliveryFeeMap {
|
|
||||||
if v.DeliveryFee > maxFee {
|
|
||||||
v.DeliveryFee = maxFee
|
|
||||||
}
|
|
||||||
}
|
|
||||||
newPrice = maxFee
|
|
||||||
}
|
|
||||||
_, lastFee, _ := partner.CurStoreAcctManager.GetStoreAcctExpendLastCreateWayBillFee(order.VendorOrderID)
|
|
||||||
// 如果门店属于京西菜市,京西果园则只能扣门店的金额
|
|
||||||
if int(newPrice) > lastFee {
|
|
||||||
if storeAcct.AccountBalance < int(newPrice)-lastFee /*&& result < int(newPrice)-lastFee*/ {
|
|
||||||
return model.ErrCodeAccountBalanceNotEnough, fmt.Errorf("门店账户余额小于[%v]元,不能发配送!", jxutils.IntPrice2Standard(newPrice-int64(lastFee)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if len(courierVendorIDs) == 1 {
|
|
||||||
courierVendorID := courierVendorIDs[0]
|
|
||||||
if _, ok := deliveryFeeMap[courierVendorID]; ok {
|
|
||||||
if deliveryFeeMap[courierVendorID].DeliveryFee > int64(storeAcct.AccountBalance) {
|
|
||||||
return model.ErrCodeAccountBalanceNotEnough, fmt.Errorf("门店账户余额小于[%v]元,不能发配送!", jxutils.IntPrice2Standard(deliveryFeeMap[courierVendorID].DeliveryFee))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if len(courierVendorIDs) == 0 {
|
|
||||||
var maxFee int64
|
|
||||||
for _, v := range deliveryFeeMap {
|
|
||||||
if v.DeliveryFee > maxFee {
|
|
||||||
v.DeliveryFee = maxFee
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if maxFee > int64(storeAcct.AccountBalance) {
|
|
||||||
return model.ErrCodeAccountBalanceNotEnough, fmt.Errorf("门店账户余额小于[%v]元,不能发配送!", jxutils.IntPrice2Standard(maxFee))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return "", fmt.Errorf("不存在的订单发单类型,检查配置")
|
|
||||||
}
|
|
||||||
|
|
||||||
return errCode, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo 这个函数可以和SelfDeliveringAndUpdateStatus合并
|
|
||||||
func (s *DefScheduler) CancelAll3rdWaybills(ctx *jxcontext.Context, vendorOrderID string, vendorID int, isStopSchedule bool) (err error) {
|
|
||||||
jxutils.CallMsgHandler(func() {
|
|
||||||
err = func() (err error) {
|
|
||||||
// 取消三方运单,取消各平台单号信息,间隔一段时间后定时任务重新调度
|
|
||||||
savedOrderInfo := s.loadSavedOrderByID(vendorOrderID, vendorID, true)
|
|
||||||
if savedOrderInfo != nil {
|
|
||||||
if len(savedOrderInfo.waybills) == model.NO {
|
|
||||||
wayBills, err := dao.GetWayBillByOrderID(dao.GetDB(), 0, vendorID, 0, vendorOrderID)
|
|
||||||
if err == nil {
|
|
||||||
for _, wb := range wayBills {
|
|
||||||
if wb.Status < model.WaybillStatusDelivered {
|
|
||||||
err = s.CancelWaybill(wb, partner.CancelWaybillReasonOther, ctx.GetUserName()+":18"+partner.CancelWaybillReasonStrActive)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = s.cancelOtherWaybills(savedOrderInfo, nil, partner.CancelWaybillReasonOther, ctx.GetUserName()+":18"+partner.CancelWaybillReasonStrActive)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = scheduler.ErrCanNotFindOrder
|
|
||||||
}
|
|
||||||
// 停止调度,同事停止订单调度,不在通知第三方
|
|
||||||
if err == nil && isStopSchedule {
|
|
||||||
order := savedOrderInfo.order
|
|
||||||
order.DeliveryFlag |= model.OrderDeliveryFlagMaskScheduleDisabled
|
|
||||||
if err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order); err == nil {
|
|
||||||
s.stopTimer(savedOrderInfo)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}()
|
|
||||||
}, jxutils.ComposeUniversalOrderID(vendorOrderID, vendorID))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询三方运单费用
|
|
||||||
func (s *DefScheduler) QueryOrderWaybillFeeInfoEx(ctx *jxcontext.Context, vendorOrderID string, vendorID int) (deliveryFeeMap map[int]*partner.WaybillFeeInfo, err error) {
|
|
||||||
jxutils.CallMsgHandler(func() {
|
|
||||||
deliveryFeeMap, err = func() (deliveryFeeMap map[int]*partner.WaybillFeeInfo, err error) {
|
|
||||||
db := dao.GetDB()
|
|
||||||
order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, vendorID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if order.DeliveryType == model.OrderDeliveryTypeSelfTake {
|
|
||||||
return nil, fmt.Errorf("订单:%s是自提单", vendorOrderID)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取用户送货地址
|
|
||||||
storeCourierList, err := dao.GetStoreCourierList(db, []int{jxutils.GetSaleStoreIDFromOrder(order)}, nil, model.StoreStatusAll, model.StoreAuditStatusOnline)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 隐私地址获取(美团)
|
|
||||||
if vendorID == model.VendorIDMTWM && (strings.Contains(order.ConsigneeAddress, "地址已隐藏") || strings.Contains(order.ConsigneeAddress, "(***)")) {
|
|
||||||
var apiObj *mtwmapi.API
|
|
||||||
switch order.VendorOrgCode {
|
|
||||||
case beego.AppConfig.DefaultString("mtwmAppID2", ""): // 5873
|
|
||||||
store, _ := dao.GetStoreDetail(dao.GetDB(), order.JxStoreID, order.VendorID, order.VendorOrgCode)
|
|
||||||
apiObj = api.Mtwm2API
|
|
||||||
apiObj.SetToken(store.MtwmToken)
|
|
||||||
default: // 589 4123
|
|
||||||
apiObj = api.MtwmAPI
|
|
||||||
}
|
|
||||||
address, err := apiObj.GetOrderAddress(utils.Str2Int64(order.VendorOrderID), 3)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
addressList := strings.Split(order.ConsigneeAddress, "@#")
|
|
||||||
order.ConsigneeAddress = address + "@#" + addressList[1]
|
|
||||||
dao.UpdateEntity(db, order, "ConsigneeAddress")
|
|
||||||
}
|
|
||||||
// 美团配送订单兑现
|
|
||||||
waybillList, err := partner.CurOrderManager.GetOrderWaybillInfo(ctx, vendorOrderID, vendorID, true, false)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
waybillMap := make(map[int]*model.Waybill)
|
|
||||||
for _, bill := range waybillList {
|
|
||||||
waybillMap[bill.WaybillVendorID] = &bill.Waybill
|
|
||||||
}
|
|
||||||
deliveryFeeMap = make(map[int]*partner.WaybillFeeInfo)
|
|
||||||
var timeoutSecond int
|
|
||||||
if savedOrderInfo := s.loadSavedOrderByID(vendorOrderID, vendorID, false); savedOrderInfo != nil {
|
|
||||||
timeoutSecond = savedOrderInfo.GetCreateWaybillTimeout()
|
|
||||||
}
|
|
||||||
|
|
||||||
store, _ := dao.GetStoreDetail(db, order.JxStoreID, order.VendorID, order.VendorOrgCode)
|
|
||||||
for _, storeCourier := range storeCourierList {
|
|
||||||
var feeInfo *partner.WaybillFeeInfo
|
|
||||||
if waybillMap[storeCourier.VendorID] != nil {
|
|
||||||
feeInfo = &partner.WaybillFeeInfo{
|
|
||||||
Waybill: waybillMap[storeCourier.VendorID],
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if storeCourier.Status != model.StoreStatusOpened {
|
|
||||||
feeInfo = &partner.WaybillFeeInfo{
|
|
||||||
ErrCode: partner.WaybillFeeErrCodeCourierNotOpen,
|
|
||||||
ErrStr: fmt.Sprintf("暂未开通,联系运营"),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if handler := partner.GetDeliveryPlatformFromVendorID(storeCourier.VendorID); handler != nil {
|
|
||||||
if handler.Use4CreateWaybill {
|
|
||||||
// 获取订单配送费用
|
|
||||||
feeInfo, err = handler.Handler.GetWaybillFee(order)
|
|
||||||
if err != nil {
|
|
||||||
feeInfo = &partner.WaybillFeeInfo{
|
|
||||||
ErrCode: partner.WaybillFeeErrCodeCourierOthers,
|
|
||||||
ErrStr: err.Error(),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
feeInfo.DeliveryFee += model.WayBillDeliveryMarkUp // 加收两毛
|
|
||||||
if storeCourier.VendorID == model.VendorIDFengNiao {
|
|
||||||
feeInfo.DeliveryFee += model.WayBillDeliveryMarkUp // 蜂鸟加
|
|
||||||
}
|
|
||||||
feeInfo.DeliveryFee += int64(store.FreightMarkup)
|
|
||||||
feeInfo.TimeoutSecond = timeoutSecond
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
feeInfo = &partner.WaybillFeeInfo{
|
|
||||||
ErrCode: partner.WaybillFeeErrCodeCourierForbidden,
|
|
||||||
ErrStr: fmt.Sprintf("内部错误,%d不能用于创建运单", storeCourier.VendorID),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
feeInfo = &partner.WaybillFeeInfo{
|
|
||||||
ErrCode: partner.WaybillFeeErrCodeCourierNotSupported,
|
|
||||||
ErrStr: fmt.Sprintf("内部错误,%d不被支持", storeCourier.VendorID),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
deliveryFeeMap[storeCourier.VendorID] = feeInfo
|
|
||||||
}
|
|
||||||
err = nil
|
|
||||||
return deliveryFeeMap, err
|
|
||||||
}()
|
|
||||||
}, jxutils.ComposeUniversalOrderID(vendorOrderID, vendorID))
|
|
||||||
return deliveryFeeMap, err
|
|
||||||
}
|
|
||||||
@@ -1,280 +0,0 @@
|
|||||||
package jcq
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/md5"
|
|
||||||
"encoding/hex"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"git.rosy.net.cn/baseapi"
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/jcqapi"
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/jdshopapi"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner/purchase/jdshop"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
accessKey = "C0EB36912C652079DB111A922ACA406B" //京东第三方的AK
|
|
||||||
secretKey = "86B6330051ECC88391E2630D34C2CA13" //京东第三方的SK
|
|
||||||
consumerGroupID = "open_message_573819178445" //消费组ID
|
|
||||||
popOrderCreatTopic = "open_message_pop_order_create_E1D746D42474D5F1F1A10CECE75D99F6" //pop订单创建主题名称
|
|
||||||
popOrderChangeTopic = "open_message_pop_order_change_E1D746D42474D5F1F1A10CECE75D99F6" //pop订单修改主题名称
|
|
||||||
popOrderOutTopic = "open_message_pop_order_out_E1D746D42474D5F1F1A10CECE75D99F6" //pop订单出库主题名称
|
|
||||||
OrderOutTopic = "open_message_order_order_out_E1D746D42474D5F1F1A10CECE75D99F6" //订单出库主题名称
|
|
||||||
OrderCancelTopic = "open_message_order_order_cancel_E1D746D42474D5F1F1A10CECE75D99F6" //订单取消主题名称
|
|
||||||
OrderPayTopic = "open_message_order_order_pay_E1D746D42474D5F1F1A10CECE75D99F6" //订单支付主题名称
|
|
||||||
OrderCreatTopic = "open_message_order_order_create_E1D746D42474D5F1F1A10CECE75D99F6" //订单创建主题
|
|
||||||
DefaultSubscribeSize = 32 //默认拉取数量
|
|
||||||
popOrderCreatType = "popCreat" //存储到数据库pop订单创建类型
|
|
||||||
popOrderOutType = "popOut" //存储到数据库pop订单出库类型
|
|
||||||
popOrderChangeType = "popChange" //存储到数据库pop订单修改类型
|
|
||||||
OrderCreatType = "orderCreat" //订单创建类型
|
|
||||||
OrderPayType = "orderPay" //订单支付类型
|
|
||||||
OrderOutType = "orderOut" //订单出库主题
|
|
||||||
OrderCancelType = "orderCancel" //订单取消类型
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
TopicList = []string{
|
|
||||||
popOrderCreatTopic, popOrderChangeTopic, popOrderOutTopic, OrderCreatTopic, OrderPayTopic, OrderOutTopic, OrderCancelTopic,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
type JcqMessage struct { //model
|
|
||||||
ID int64 `orm:"column(id)" `
|
|
||||||
MessageID string `orm:"column(message_id)" `
|
|
||||||
MessageBody string `orm:"column(message_body)"`
|
|
||||||
BusinessID string `orm:"column(business_id)"`
|
|
||||||
PropertyRetryTimes string `orm:"column(property_retry_times)"`
|
|
||||||
Status string `orm:"column(status)"` //表示业务逻辑状态 n 表示业务为处理 y 表示已处理
|
|
||||||
MessageType string `orm:"column(message_type)" //消息类型 对应上面的枚举`
|
|
||||||
}
|
|
||||||
|
|
||||||
type JqcTask struct {
|
|
||||||
TopicId string
|
|
||||||
Wg *sync.WaitGroup
|
|
||||||
}
|
|
||||||
|
|
||||||
type PopCreatObject struct { //序列化属性首字母必须大写 否则会出现赋值问题 切记! 也可以考虑使用simplejson就需要这么多的struct
|
|
||||||
OrderCreateTime string `json:"orderCreateTime"`
|
|
||||||
OrderId int64 `json:"orderId"`
|
|
||||||
OrderPaymentType int `json:"orderPaymentType"`
|
|
||||||
OrderStatus string `json:"orderStatus"`
|
|
||||||
OrderType int `json:"orderType"`
|
|
||||||
VenderId int64 `json:"venderId"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type PopChangeObject struct { //Pop修改
|
|
||||||
ErpOrderStatus int `json:"erpOrderStatus"`
|
|
||||||
Modified int `json:"modified"`
|
|
||||||
OrderCreateTime int `json:"orderCreateTime"`
|
|
||||||
OrderId int64 `json:"orderId"`
|
|
||||||
OrderPaymentType int `json:"orderPaymentType"`
|
|
||||||
OrderType int `json:"orderType"`
|
|
||||||
VenderId int `json:"venderId"`
|
|
||||||
Yn int `json:"yn"`
|
|
||||||
}
|
|
||||||
type PopCreatOrderMessage struct { //pop订单创建结构体
|
|
||||||
PopCreatObj PopCreatObject `json:"object"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type CreatOrderMessage struct {
|
|
||||||
OrderCreatObj PopCreatObject `json:"object"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type PayOrderMessage struct {
|
|
||||||
OrderPayObject OrderPayObject `json:"object"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type OrderPayObject struct {
|
|
||||||
OrderId int64 `json:"orderId"`
|
|
||||||
OrderPaymentTime int `json:"orderPaymentTime"`
|
|
||||||
OrderPaymentType int `json:"orderPaymentType"`
|
|
||||||
OrderType int `json:"orderType"`
|
|
||||||
VenderId int `json:"venderId"`
|
|
||||||
OrderStatus int `json:"orderStatus"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *JqcTask) Do() {
|
|
||||||
handleTopic(t.TopicId)
|
|
||||||
t.Wg.Done()
|
|
||||||
}
|
|
||||||
|
|
||||||
var jcqApi *jcqapi.API
|
|
||||||
|
|
||||||
// JCQSchedule creat by Hang
|
|
||||||
// 用于jcq队列返回数据处理 以及业务逻辑 由于在consumeInfo2加了ack 所以不会存在重复拉取的可能性
|
|
||||||
// 使用ants 同时启动topic数量的携程 进行handle
|
|
||||||
func JCQSchedule() {
|
|
||||||
jcqApi = jcqapi.New(accessKey, secretKey)
|
|
||||||
currentTopic := OrderPayTopic
|
|
||||||
handleTopic(currentTopic)
|
|
||||||
|
|
||||||
/* p, _ := ants.NewPoolWithFunc(10, func(data interface{}) {
|
|
||||||
task := data.(*JqcTask)
|
|
||||||
task.Do()
|
|
||||||
})
|
|
||||||
defer p.Release()
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
wg.Add(len(TopicList))
|
|
||||||
tasks := make([]*JqcTask, 0, len(TopicList))
|
|
||||||
for i := 0; i < len(TopicList); i++ {
|
|
||||||
task := &JqcTask{
|
|
||||||
TopicId: TopicList[i],
|
|
||||||
Wg: &wg,
|
|
||||||
}
|
|
||||||
tasks = append(tasks, task)
|
|
||||||
p.Invoke(task)
|
|
||||||
}
|
|
||||||
wg.Wait()*/
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//处理topic 针对不同的topic进行存库操作
|
|
||||||
func handleTopic(topicId string) {
|
|
||||||
consumeResults, err := jcqApi.ConsumeInfo2(topicId, consumerGroupID, DefaultSubscribeSize)
|
|
||||||
if err == nil {
|
|
||||||
if len(consumeResults) != 0 {
|
|
||||||
entityList := make([]JcqMessage, 0)
|
|
||||||
//构建实体
|
|
||||||
for _, result := range consumeResults {
|
|
||||||
if topicId == popOrderCreatTopic {
|
|
||||||
var r PopCreatOrderMessage
|
|
||||||
//js, _ := simplejson.NewJson([]byte(result.MessageBody))
|
|
||||||
json.Unmarshal([]byte(result.MessageBody), &r)
|
|
||||||
fmt.Println(r)
|
|
||||||
}
|
|
||||||
jcq := JcqMessage{
|
|
||||||
MessageID: result.MessageID,
|
|
||||||
MessageBody: result.MessageBody,
|
|
||||||
BusinessID: result.Properties.BUSINESSID,
|
|
||||||
PropertyRetryTimes: result.Properties.PROPERTYRETRYTIMES,
|
|
||||||
Status: "n", //默认给定初始值 未做处理
|
|
||||||
MessageType: transType(topicId),
|
|
||||||
}
|
|
||||||
entityList = append(entityList, jcq)
|
|
||||||
}
|
|
||||||
db := dao.GetDB()
|
|
||||||
if err = dao.CreateMultiEntities(db, entityList); err != nil {
|
|
||||||
baseapi.SugarLogger.Warnf("saveMessage orderID:%s, save jqs_message failed with error:%v", entityList, err)
|
|
||||||
} else { //存库成功进行调用API操作
|
|
||||||
//定义菜市api
|
|
||||||
jdmcshopapi := jdshopapi.New("37d36b62c0d14bd4b872f948b335c95czinj", "E1D746D42474D5F1F1A10CECE75D99F6", "efa7e1d1a22640fa990e6cf164b28608")
|
|
||||||
//定义果园api
|
|
||||||
jdgyshopapi := jdshopapi.New("f9c5ce9a5ce24218936924f7c4864cc9owe1", "E1D746D42474D5F1F1A10CECE75D99F6", "efa7e1d1a22640fa990e6cf164b28608")
|
|
||||||
for _, result := range consumeResults {
|
|
||||||
//处理订单支付,订单取消和pop订单出库的topic
|
|
||||||
if topicId == OrderPayTopic || topicId == OrderCancelTopic || topicId == popOrderOutTopic {
|
|
||||||
var r PayOrderMessage
|
|
||||||
//js, _ := simplejson.NewJson([]byte(result.MessageBody))
|
|
||||||
json.Unmarshal([]byte(result.MessageBody), &r)
|
|
||||||
orderResult, err := jdmcshopapi.GetOrderById(r.OrderPayObject.OrderId, true)
|
|
||||||
isGy := false
|
|
||||||
if orderResult == nil && err == nil {
|
|
||||||
isGy = true
|
|
||||||
orderResult, err = jdgyshopapi.GetOrderById(r.OrderPayObject.OrderId, true) //查询不到之后说明不是这个账号的 使用果园再查一遍
|
|
||||||
}
|
|
||||||
if err == nil { //确定返回结果
|
|
||||||
// TO DO 处理数据转换为原先回调的结果
|
|
||||||
if orderResult == nil {
|
|
||||||
baseapi.SugarLogger.Debug("未查询到订单ID", r.OrderPayObject.OrderId)
|
|
||||||
} else {
|
|
||||||
callBackResult := TransFormOrderResultToCallBackResult(orderResult, topicId, isGy)
|
|
||||||
jdshop.OnCallbackMsg(callBackResult) //进行处理
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
baseapi.SugarLogger.Debug("handle Topic the end")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 用于转换类型
|
|
||||||
func transType(topic string) string {
|
|
||||||
switch topic {
|
|
||||||
case popOrderCreatTopic:
|
|
||||||
return popOrderCreatType
|
|
||||||
case popOrderChangeTopic:
|
|
||||||
return popOrderChangeType
|
|
||||||
case popOrderOutTopic:
|
|
||||||
return popOrderOutType
|
|
||||||
case OrderCreatTopic:
|
|
||||||
return OrderCreatType
|
|
||||||
case OrderPayTopic:
|
|
||||||
return OrderPayType
|
|
||||||
case OrderOutTopic:
|
|
||||||
return OrderOutType
|
|
||||||
case OrderCancelTopic:
|
|
||||||
return OrderCancelType
|
|
||||||
default:
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// TransFormOrderResultToCallBackResult 转换数据类型 使其可以进入原先回调方法
|
|
||||||
func TransFormOrderResultToCallBackResult(getOrderResult *jdshopapi.GetEnOrderResult, topicId string, isGy bool) *jdshopapi.CallBackResult {
|
|
||||||
return &jdshopapi.CallBackResult{
|
|
||||||
OrderStateRemark: getOrderResult.OrderStateRemark,
|
|
||||||
OrderRemark: getOrderResult.OrderRemark,
|
|
||||||
OrderSellerPrice: getOrderResult.OrderSellerPrice,
|
|
||||||
OrderState: getOrderResult.OrderState,
|
|
||||||
OrderType: getOrderResult.OrderType,
|
|
||||||
OrderPayment: getOrderResult.OrderPayment,
|
|
||||||
PayType: getOrderResult.PayType,
|
|
||||||
StoreID: getOrderResult.StoreID,
|
|
||||||
OrderTotalPrice: getOrderResult.OrderTotalPrice,
|
|
||||||
OrderExt: getOrderResult.OrderExt,
|
|
||||||
StoreOrder: getOrderResult.StoreOrder,
|
|
||||||
OrderStartTime: getOrderResult.OrderStartTime,
|
|
||||||
OrderID: getOrderResult.OrderID,
|
|
||||||
OrderSource: getOrderResult.OrderSource,
|
|
||||||
FreightPrice: getOrderResult.FreightPrice,
|
|
||||||
MsgType: TransMsgType(topicId),
|
|
||||||
Pin:/*splitPin(getOrderResult.Pin),*/ "jd_temp",
|
|
||||||
IDSopShipmenttype: getOrderResult.IDSopShipmenttype,
|
|
||||||
ScDT: getOrderResult.ScDT,
|
|
||||||
SellerDiscount: getOrderResult.SellerDiscount,
|
|
||||||
ConsigneeInfo: getOrderResult.ConsigneeInfo,
|
|
||||||
ItemInfoList: getOrderResult.ItemInfoList,
|
|
||||||
VendorOrgCode: getVendorOrgCode(isGy),
|
|
||||||
MenDianID: getOrderResult.MenDianID,
|
|
||||||
BalanceUsed: getOrderResult.BalanceUsed}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TransMsgType 目前业务处理函数仅对一下三种topic做了业务处理
|
|
||||||
func TransMsgType(topicId string) string {
|
|
||||||
switch topicId {
|
|
||||||
case OrderPayTopic:
|
|
||||||
return jcqapi.TopicOrderPay
|
|
||||||
case OrderCancelTopic:
|
|
||||||
return jcqapi.TopicOrderCancel
|
|
||||||
case popOrderOutTopic:
|
|
||||||
return jcqapi.TopicOrderOut
|
|
||||||
default:
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//由于返回的pin长度过长 进行md5操作 压缩长度
|
|
||||||
func splitPin(pin string) string {
|
|
||||||
h := md5.New()
|
|
||||||
h.Write([]byte(pin))
|
|
||||||
s := hex.EncodeToString(h.Sum(nil))
|
|
||||||
return s
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// 根据标识判断加密标识
|
|
||||||
func getVendorOrgCode(isGy bool) string {
|
|
||||||
if isGy {
|
|
||||||
return "2"
|
|
||||||
} else {
|
|
||||||
return "1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
package jdslogin
|
|
||||||
|
|
||||||
// RefreshQRCode Creat By 2022/04/18
|
|
||||||
// RefreshQRCode Author By Hang xu
|
|
||||||
// RefreshQRCode 用于爬取京东的二维码链接 并持久化进入数据库中
|
|
||||||
//func RefreshQRCode() (retval string, err error) {
|
|
||||||
// baseapi.SugarLogger.Debug("BEGIN JD SHOP QRCODE SPIDER---------------------------------------------------")
|
|
||||||
// const (
|
|
||||||
// seleniumPath = `/usr/bin/chromedriver`
|
|
||||||
// port = 9515
|
|
||||||
// )
|
|
||||||
// opts := []selenium.ServiceOption{}
|
|
||||||
//
|
|
||||||
// selenium.SetDebug(true)
|
|
||||||
//
|
|
||||||
// service, err := selenium.NewChromeDriverService(seleniumPath, port, opts...)
|
|
||||||
// if nil != err {
|
|
||||||
// fmt.Println("start a chromedriver service falid", err.Error())
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// ////server关闭之后,chrome窗口也会关闭
|
|
||||||
// defer service.Stop()
|
|
||||||
// //链接本地的浏览器 chrome
|
|
||||||
// caps := selenium.Capabilities{
|
|
||||||
// //"browserName": "/Applications/Google Chrome Dev.app/Contents/MacOS/Google Chrome Dev",
|
|
||||||
// "browserName": "/opt/google/chrome",
|
|
||||||
// }
|
|
||||||
// //禁止图片加载,加快渲染速度
|
|
||||||
// imagCaps := map[string]interface{}{
|
|
||||||
// "profile.managed_default_content_settings.images": 2,
|
|
||||||
// }
|
|
||||||
// chromeCaps := chrome.Capabilities{
|
|
||||||
// Prefs: imagCaps,
|
|
||||||
// Path: "/opt/google/chrome",
|
|
||||||
// Args: []string{
|
|
||||||
// //静默执行请求
|
|
||||||
// "--headless", // 设置Chrome无头模式,在linux下运行,需要设置这个参数,否则会报错
|
|
||||||
// "--no-sandbox",
|
|
||||||
// "--user-agent=Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36", // 模拟user-agent,防反爬
|
|
||||||
// "--Host=porder.shop.jd.com",
|
|
||||||
// "--Connection=keep-alive",
|
|
||||||
// },
|
|
||||||
// }
|
|
||||||
// //以上是设置浏览器参数
|
|
||||||
// caps.AddChrome(chromeCaps)
|
|
||||||
//
|
|
||||||
// url := "https://porder.shop.jd.com/order/orderlist/allOrders"
|
|
||||||
// w_b1, err := selenium.NewRemote(caps, fmt.Sprintf("http://localhost:%d/wd/hub", port))
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println("connect to the webDriver faild", err.Error())
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// err = w_b1.Get(url)
|
|
||||||
// pageSource, err := w_b1.PageSource()
|
|
||||||
// baseapi.SugarLogger.Debug("pageSource", pageSource)
|
|
||||||
// qr, err := w_b1.FindElement("id", "js-login-qrcode")
|
|
||||||
// qrStr, err := qr.GetAttribute("src")
|
|
||||||
// baseapi.SugarLogger.Debug("qrStr:", qrStr) //当前qrcode sample:https://passport.shop.jd.com/login/json/qrcode_show.action?_timeStr=165026591404449b823cc58684d948d0e0ca8351adf64
|
|
||||||
// // 进行存库操作
|
|
||||||
// // save to database 存入 new_config表中
|
|
||||||
// db := dao.GetDB()
|
|
||||||
// txDB, _ := dao.Begin(db)
|
|
||||||
// defer func() {
|
|
||||||
// if r := recover(); r != nil {
|
|
||||||
// dao.Rollback(db, txDB)
|
|
||||||
// panic(r)
|
|
||||||
// }
|
|
||||||
// }()
|
|
||||||
// configList, err := dao.QueryConfigs(db, "jdsQRcode", "Cookie", "")
|
|
||||||
// if err != nil {
|
|
||||||
// dao.Rollback(db, txDB)
|
|
||||||
// return "", err
|
|
||||||
// }
|
|
||||||
// if _, err = dao.UpdateEntityLogically(db, configList[0], map[string]interface{}{
|
|
||||||
// "Value": qrStr,
|
|
||||||
// }, "", nil); err != nil {
|
|
||||||
// dao.Rollback(db, txDB)
|
|
||||||
// return "", err
|
|
||||||
// }
|
|
||||||
// baseapi.SugarLogger.Debug("THE JD SHOP QRCODE SPIDER THE END---------------------------------------------")
|
|
||||||
// return "", nil
|
|
||||||
//}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
package scheduler
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
StoreDeliveryTypeCrowdSourcing = 0 //缺省,平台众包配送,可转自送
|
|
||||||
StoreDeliveryTypeByPlatform = 1 //平台专送
|
|
||||||
StoreDeliveryTypeByStore = 2 //完全门店自送,这个表示的意思是平台的门店属性(就是购物平台不负责配送),而不是真正是否是老板自己送
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
TimerStatusTypeUnknown = -1
|
|
||||||
TimerStatusTypeOrder = 0
|
|
||||||
TimerStatusTypeWaybill = 1
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
CurrentScheduler IScheduler
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrOrderStatusIsNotSuitable4CurOperation = errors.New("订单锁定或状态不适合当前操作")
|
|
||||||
ErrOrderStatusAlreadySatisfyCurOperation = errors.New("订单当前状态已满足当前操作")
|
|
||||||
ErrOrderStatusShippedCurOperation = errors.New("订单已发货,不允许再次执行发货")
|
|
||||||
ErrOrderStatusAlreadySatisfyCurOperationELM = errors.New("无需切自配送")
|
|
||||||
ErrOrderStatusAlreadySatisfyCurOperationMTWM = errors.New("非专送、快送、混合送订单不允许调用此接口 level:0, code:1047")
|
|
||||||
|
|
||||||
ErrCanNotCreateAtLeastOneWaybill = errors.New("一个运单都不能创建")
|
|
||||||
ErrCanNotFindOrder = errors.New("不能找到订单(一般是由于事件错序)")
|
|
||||||
ErrCanNotFindWaybill = errors.New("不能找到运单(一般是由于事件错序)")
|
|
||||||
ErrOrderIsNotSolid = errors.New("订单是临时订单,不完整,不能用于创建运单")
|
|
||||||
ErrDeliverProviderWrong = errors.New("快递商不存在或不能用于创建运单")
|
|
||||||
)
|
|
||||||
|
|
||||||
type IScheduler interface {
|
|
||||||
// 以下是订单
|
|
||||||
OnOrderNew(order *model.GoodsOrder, isPending bool, isAuto bool) (err error)
|
|
||||||
OnOrderStatusChanged(order *model.GoodsOrder, status *model.OrderStatus, isPending bool) (err error)
|
|
||||||
|
|
||||||
// 以下是运单
|
|
||||||
OnWaybillStatusChanged(bill *model.Waybill, isPending bool) (err error)
|
|
||||||
|
|
||||||
// 以下是售后单
|
|
||||||
OnAfsOrderNew(order *model.AfsOrder, isPending bool) (err error)
|
|
||||||
OnAfsOrderStatusChanged(order *model.AfsOrder, status *model.OrderStatus, isPending bool) (err error)
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,206 +0,0 @@
|
|||||||
package act
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/testinit"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
|
|
||||||
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/ebai"
|
|
||||||
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/jd"
|
|
||||||
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/mtwm"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
testinit.Init()
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInitDb(t *testing.T) {
|
|
||||||
dao.ExecuteSQL(dao.GetDB(), `
|
|
||||||
DROP TABLE IF EXISTS act, act_map, act_order_rule, act_store_sku, act_store_sku_map;
|
|
||||||
`)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCreateActOnAlpha(t *testing.T) {
|
|
||||||
actStoreSkuList := []*ActStoreSkuParam{
|
|
||||||
&ActStoreSkuParam{
|
|
||||||
ActStoreSku: model.ActStoreSku{
|
|
||||||
StoreID: 2,
|
|
||||||
SkuID: 2142,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&ActStoreSkuParam{
|
|
||||||
ActStoreSku: model.ActStoreSku{
|
|
||||||
StoreID: 2,
|
|
||||||
SkuID: 1162,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&ActStoreSkuParam{
|
|
||||||
ActStoreSku: model.ActStoreSku{
|
|
||||||
StoreID: 2,
|
|
||||||
SkuID: 1167,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&ActStoreSkuParam{
|
|
||||||
ActStoreSku: model.ActStoreSku{
|
|
||||||
StoreID: 2,
|
|
||||||
SkuID: 1172,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
t.Log(utils.Format4Output(actStoreSkuList, true))
|
|
||||||
// actID, err := CreateAct(jxcontext.AdminCtx, &model.Act{
|
|
||||||
// Name: "测试活动",
|
|
||||||
// PricePercentage: 80,
|
|
||||||
// Type: model.ActSkuDirectDown,
|
|
||||||
// }, []int{model.VendorIDJD, model.VendorIDMTWM, model.VendorIDEBAI}, nil, actStoreSkuList, false)
|
|
||||||
// if err != nil {
|
|
||||||
// t.Fatal(err)
|
|
||||||
// }
|
|
||||||
// globals.SugarLogger.Debug(actID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCreateActOnDev(t *testing.T) {
|
|
||||||
//actStoreSkuList := []*ActStoreSkuParam{
|
|
||||||
// &ActStoreSkuParam{
|
|
||||||
// ActStoreSku: model.ActStoreSku{
|
|
||||||
// StoreID: 100884,
|
|
||||||
// SkuID: 22716,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// &ActStoreSkuParam{
|
|
||||||
// ActStoreSku: model.ActStoreSku{
|
|
||||||
// StoreID: 100884,
|
|
||||||
// SkuID: 22717,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// &ActStoreSkuParam{
|
|
||||||
// ActStoreSku: model.ActStoreSku{
|
|
||||||
// StoreID: 100920,
|
|
||||||
// SkuID: 22714,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// &ActStoreSkuParam{
|
|
||||||
// ActStoreSku: model.ActStoreSku{
|
|
||||||
// StoreID: 100920,
|
|
||||||
// SkuID: 22715,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// // &ActStoreSkuParam{
|
|
||||||
// // ActStoreSku: model.ActStoreSku{
|
|
||||||
// // StoreID: 100119,
|
|
||||||
// // SkuID: 26595,
|
|
||||||
// // },
|
|
||||||
// // },
|
|
||||||
//}
|
|
||||||
// t.Log(utils.Format4Output(actStoreSkuList, true))
|
|
||||||
//actID, err := CreateAct(jxcontext.AdminCtx, &model.Act{
|
|
||||||
// Name: "测试活动",
|
|
||||||
// PricePercentage: 80,
|
|
||||||
// Type: model.ActSkuDirectDown,
|
|
||||||
// BeginAt: time.Now().Add(-24 * time.Hour),
|
|
||||||
// EndAt: time.Now().Add(10 * 24 * time.Hour),
|
|
||||||
//}, []int{model.VendorIDJD, model.VendorIDMTWM /*, model.VendorIDEBAI*/}, nil, actStoreSkuList, false)
|
|
||||||
//if err != nil {
|
|
||||||
// t.Fatal(err)
|
|
||||||
//}
|
|
||||||
//globals.SugarLogger.Debug(actID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCancelAct(t *testing.T) {
|
|
||||||
err := CancelAct(jxcontext.AdminCtx, 1)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDeleteActStoreBind(t *testing.T) {
|
|
||||||
_, err := DeleteActStoreSkuBind(jxcontext.AdminCtx, dao.GetDB(), 1, []*ActStoreSkuParam{
|
|
||||||
// &ActStoreSkuParam{
|
|
||||||
// ActStoreSku: model.ActStoreSku{
|
|
||||||
// StoreID: 100119,
|
|
||||||
// SkuID: 30828,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// &ActStoreSkuParam{
|
|
||||||
// ActStoreSku: model.ActStoreSku{
|
|
||||||
// StoreID: 100119,
|
|
||||||
// SkuID: 30827,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
&ActStoreSkuParam{
|
|
||||||
ActStoreSku: model.ActStoreSku{
|
|
||||||
StoreID: 100884,
|
|
||||||
SkuID: 22716,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&ActStoreSkuParam{
|
|
||||||
ActStoreSku: model.ActStoreSku{
|
|
||||||
StoreID: 100884,
|
|
||||||
SkuID: 22717,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAddActStoreBind(t *testing.T) {
|
|
||||||
err := AddActStoreSkuBind(jxcontext.AdminCtx, dao.GetDB(), 1, []*ActStoreSkuParam{
|
|
||||||
// &ActStoreSkuParam{
|
|
||||||
// ActStoreSku: model.ActStoreSku{
|
|
||||||
// StoreID: 100119,
|
|
||||||
// SkuID: 30828,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// &ActStoreSkuParam{
|
|
||||||
// ActStoreSku: model.ActStoreSku{
|
|
||||||
// StoreID: 100119,
|
|
||||||
// SkuID: 30827,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
&ActStoreSkuParam{
|
|
||||||
ActStoreSku: model.ActStoreSku{
|
|
||||||
StoreID: 100884,
|
|
||||||
SkuID: 22716,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&ActStoreSkuParam{
|
|
||||||
ActStoreSku: model.ActStoreSku{
|
|
||||||
StoreID: 100884,
|
|
||||||
SkuID: 22717,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSyncAct(t *testing.T) {
|
|
||||||
_, err := SyncAct(jxcontext.AdminCtx, nil, 1, nil, false)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestForceUpdateVendorPrice(t *testing.T) {
|
|
||||||
//hint, err := ForceUpdateVendorPrice(jxcontext.AdminCtx, model.VendorIDJD, model.ActSkuDirectDown, []*ActStoreSkuParam{
|
|
||||||
// &ActStoreSkuParam{
|
|
||||||
// ActStoreSku: model.ActStoreSku{
|
|
||||||
// StoreID: 100118,
|
|
||||||
// SkuID: 22509,
|
|
||||||
// ActPrice: 9900,
|
|
||||||
// },
|
|
||||||
// VendorPrice: 19900,
|
|
||||||
// },
|
|
||||||
//}, false)
|
|
||||||
//if err != nil {
|
|
||||||
// t.Fatal(err)
|
|
||||||
//}
|
|
||||||
//t.Log(hint)
|
|
||||||
}
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
package cms
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.rosy.net.cn/jx-callback/business/auth2"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/auth2/authprovider/weixin"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/authz/autils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/legacymodel"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// todo 是否需要将Store.MarketManPhone与OperatorPhone成角色?
|
|
||||||
|
|
||||||
func TransferLegacyWeixins(mobile string) (err error) {
|
|
||||||
if !globals.EnableWXAuth2 || globals.DisableWXAuth1 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
remark4Transfer := "transfer"
|
|
||||||
// DELETE t1
|
|
||||||
// FROM auth_bind t1
|
|
||||||
// WHERE t1.remark = 'transfer';
|
|
||||||
|
|
||||||
// DELETE t1
|
|
||||||
// FROM user t1
|
|
||||||
// WHERE t1.remark = 'transfer';
|
|
||||||
|
|
||||||
// TRUNCATE TABLE casbin_rule;
|
|
||||||
|
|
||||||
sql := `
|
|
||||||
SELECT t1.*
|
|
||||||
FROM weixins t1
|
|
||||||
LEFT JOIN user t2 ON t2.mobile = t1.tel
|
|
||||||
LEFT JOIN auth_bind t3 ON t3.auth_id = t1.openid AND t3.type = 'weixinsns'
|
|
||||||
LEFT JOIN auth_bind t4 ON t4.auth_id = t1.openid_mini AND t4.type = 'weixinmini'
|
|
||||||
WHERE`
|
|
||||||
sqlParams := []interface{}{}
|
|
||||||
if mobile != "" {
|
|
||||||
remark4Transfer = "transfer2"
|
|
||||||
sql += " t1.tel = ?"
|
|
||||||
sqlParams = append(sqlParams, mobile)
|
|
||||||
} else {
|
|
||||||
sql += " t2.id IS NULL OR (t1.openid <> '' AND t3.id IS NULL) OR (t1.openid_mini <> '' AND t4.id IS NULL)"
|
|
||||||
}
|
|
||||||
sql += " ORDER BY t1.parentid;"
|
|
||||||
var weixinList []*legacymodel.WeiXins
|
|
||||||
db := dao.GetDB()
|
|
||||||
err = dao.GetRows(db, &weixinList, sql, sqlParams...)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
parentMap := make(map[int]*legacymodel.WeiXins)
|
|
||||||
for _, v := range weixinList {
|
|
||||||
if v.ParentID == -1 {
|
|
||||||
parentMap[v.ID] = v
|
|
||||||
} else {
|
|
||||||
if parentMap[v.ParentID] != nil {
|
|
||||||
v.JxStoreID = parentMap[v.ParentID].JxStoreID
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if v.Tel != "" {
|
|
||||||
user := &model.User{
|
|
||||||
UserID2: v.Tel,
|
|
||||||
Name: v.NickName,
|
|
||||||
Mobile: &v.Tel,
|
|
||||||
Type: model.UserTypeStoreBoss,
|
|
||||||
Remark: remark4Transfer,
|
|
||||||
}
|
|
||||||
if user.Name == "" {
|
|
||||||
user.Name = user.GetMobile()
|
|
||||||
}
|
|
||||||
userList, _, err2 := dao.GetUsers(db, 0, "", nil, nil, []string{v.Tel}, 0, -1)
|
|
||||||
if err = err2; err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if len(userList) == 0 {
|
|
||||||
err = CreateUser(user, v.LastOperator)
|
|
||||||
} else {
|
|
||||||
user = userList[0]
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if v.OpenID != "" {
|
|
||||||
auth2.AddAuthBind(user, &auth2.AuthInfo{
|
|
||||||
AuthBindInfo: &auth2.AuthBindEx{
|
|
||||||
AuthBind: model.AuthBind{
|
|
||||||
Type: weixin.AuthTypeMP,
|
|
||||||
AuthID: v.OpenID,
|
|
||||||
AuthID2: v.OpenIDUnion,
|
|
||||||
Remark: remark4Transfer,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if v.OpenIDMini != "" {
|
|
||||||
auth2.AddAuthBind(user, &auth2.AuthInfo{
|
|
||||||
AuthBindInfo: &auth2.AuthBindEx{
|
|
||||||
AuthBind: model.AuthBind{
|
|
||||||
Type: weixin.AuthTypeMini,
|
|
||||||
AuthID: v.OpenIDMini,
|
|
||||||
AuthID2: v.OpenIDUnion,
|
|
||||||
Remark: remark4Transfer,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if v.JxStoreID > 0 { // 运营就不加到门店老板组里了
|
|
||||||
if user.Type&model.UserTypeOperator == 0 {
|
|
||||||
api2.RoleMan.AddRole4User(user.GetID(), autils.NewStoreBossRole(v.JxStoreID))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if mobile != "" {
|
|
||||||
rList, err2 := api2.RoleMan.GetUserRoleList(user.GetID())
|
|
||||||
if err = err2; err == nil {
|
|
||||||
for _, role := range rList {
|
|
||||||
if role.StoreID > 0 {
|
|
||||||
api2.RoleMan.DeleteRole4User(user.GetID(), autils.NewStoreBossRole(role.StoreID))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package cms
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api2"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/jx-callback/business/authz/autils"
|
|
||||||
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/ebai"
|
|
||||||
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/elm"
|
|
||||||
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/jd"
|
|
||||||
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/mtwm"
|
|
||||||
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/weimob/wsc"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestTransferLegacyWeixins(t *testing.T) {
|
|
||||||
err := TransferLegacyWeixins("")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCasbin(t *testing.T) {
|
|
||||||
userList, err := api2.RoleMan.GetRoleUserList(autils.NewStoreBossRole(100324))
|
|
||||||
t.Log(utils.Format4Output(userList, false))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRefreshTiktokShopToken(t *testing.T) {
|
|
||||||
RefreshTiktokShopToken(nil)
|
|
||||||
}
|
|
||||||
@@ -2,35 +2,17 @@ package cms
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.rosy.net.cn/baseapi/platformapi/tencent_map"
|
"git.rosy.net.cn/baseapi/platformapi/mtunionapi"
|
||||||
"math"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/autonavi"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner/purchase/ebai"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils/errlist"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api2"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/dingdingapi"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/jx-callback/business/auth2/authprovider/mobile"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/authz/autils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/ddmsg"
|
"git.rosy.net.cn/jx-callback/business/dao"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -46,64 +28,8 @@ type SysConfigLimit struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
serviceInfo map[string]interface{}
|
serviceInfo map[string]interface{}
|
||||||
allowUpdatePlaceFieldsMap = map[string]bool{
|
|
||||||
"name": true,
|
|
||||||
"enabled": true,
|
|
||||||
"mtpsPrice": true,
|
|
||||||
}
|
|
||||||
|
|
||||||
regexpMsgContentOpID = regexp.MustCompile(`"openid":"(.*?)"`)
|
regexpMsgContentOpID = regexp.MustCompile(`"openid":"(.*?)"`)
|
||||||
|
|
||||||
receiveMsgUsersMap = map[string][]string{
|
|
||||||
SendMsgTypeOpenStoreRequest: []string{
|
|
||||||
"石锋",
|
|
||||||
// "x",
|
|
||||||
// "周扬",
|
|
||||||
},
|
|
||||||
SendMsgTypeSuggestRequest: []string{
|
|
||||||
"石锋",
|
|
||||||
// "x",
|
|
||||||
// "周扬",
|
|
||||||
// "苏尹岚",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
needConfirmRequestMap = map[string]int{
|
|
||||||
SendMsgTypeOpenStoreRequest: 1,
|
|
||||||
}
|
|
||||||
|
|
||||||
SysConfigLimitMap = map[string]*SysConfigLimit{
|
|
||||||
model.ConfigSysEbaiBoxFee: &SysConfigLimit{
|
|
||||||
ValueType: reflect.Int,
|
|
||||||
MinValue: 0,
|
|
||||||
MaxValue: 500,
|
|
||||||
AfterChanged: func() (err error) {
|
|
||||||
_, err = dao.SetStoreMapSyncStatus(dao.GetDB(), []int{model.VendorIDEBAI}, nil, model.SyncFlagModifiedMask)
|
|
||||||
return err
|
|
||||||
},
|
|
||||||
},
|
|
||||||
model.ConfigSysMtwmBoxFee: &SysConfigLimit{
|
|
||||||
ValueType: reflect.Int,
|
|
||||||
MinValue: 0,
|
|
||||||
MaxValue: 500,
|
|
||||||
AfterChanged: func() (err error) {
|
|
||||||
_, err = dao.SetStoreMapSyncStatus(dao.GetDB(), []int{model.VendorIDMTWM}, nil, model.SyncFlagModifiedMask)
|
|
||||||
return err
|
|
||||||
},
|
|
||||||
},
|
|
||||||
model.ConfigSysMtwmSkuBoxFee: &SysConfigLimit{
|
|
||||||
ValueType: reflect.Int,
|
|
||||||
MinValue: 0,
|
|
||||||
MaxValue: 50,
|
|
||||||
AfterChanged: func() (err error) {
|
|
||||||
_, err = dao.SetStoreSkuSyncStatus(dao.GetDB(), model.VendorIDMTWM, nil, nil, model.SyncFlagModifiedMask)
|
|
||||||
return err
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
AutonaviKeyList = []string{autonavi.AMAPCyclingPlanKey1, autonavi.AMAPCyclingPlanKey2, autonavi.AMAPCyclingPlanKey3, autonavi.AMAPCyclingPlanKey4, autonavi.AMAPCyclingPlanKey5}
|
|
||||||
AutonaviKeyIndex = 0
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitServiceInfo(version string, buildTime time.Time, gitCommit string) {
|
func InitServiceInfo(version string, buildTime time.Time, gitCommit string) {
|
||||||
@@ -117,49 +43,41 @@ func InitServiceInfo(version string, buildTime time.Time, gitCommit string) {
|
|||||||
"buildTime": buildTimeStr,
|
"buildTime": buildTimeStr,
|
||||||
"gitCommit": gitCommit,
|
"gitCommit": gitCommit,
|
||||||
"metaData": map[string]interface{}{
|
"metaData": map[string]interface{}{
|
||||||
"skuNamePrefix": model.SkuNamePrefixNames,
|
"vendorTypeName": model.VendorTypeName,
|
||||||
"skuNameUnit": model.UnitNames,
|
"vendorName": model.VendorChineseNames,
|
||||||
"skuSpecUnit": model.SpecUnitNames,
|
//"vendorImg": model.VendorImg,
|
||||||
"skuStatus": model.SkuStatusName,
|
//"vendorColors": model.VendorColors,
|
||||||
"storeDeliveryRangeType": model.DeliveryRangeTypeName,
|
|
||||||
"storeDeliveryType": model.DeliveryTypeName,
|
|
||||||
"storeStatus": model.StoreStatusName,
|
|
||||||
"categoryType": model.CategoryTypeName,
|
|
||||||
"vendorTypeName": model.VendorTypeName,
|
|
||||||
"vendorName": model.VendorChineseNames,
|
|
||||||
"orderStatus": model.OrderStatusName,
|
"orderStatus": model.OrderStatusName,
|
||||||
"waybillStatus": model.WaybillStatusName,
|
"waybillStatus": model.WaybillStatusName,
|
||||||
"orderTypeName": model.OrderTypeName,
|
"orderTypeName": model.OrderTypeName,
|
||||||
"taskStatusName": tasksch.TaskStatusName,
|
"taskStatusName": tasksch.TaskStatusName,
|
||||||
"opRequestTypeName": model.RequestTypeName,
|
|
||||||
"opRequestStatusName": model.RequestStatusName,
|
|
||||||
"storeMsgSendStatusName": model.StoreMsgSendStatusName,
|
"storeMsgSendStatusName": model.StoreMsgSendStatusName,
|
||||||
"shopChineseNames": model.ShopChineseNames,
|
|
||||||
"printerVendorInfo": model.PrinterVendorInfo,
|
"printerVendorInfo": model.PrinterVendorInfo,
|
||||||
"printerStatusName": partner.PrinterStatusName,
|
|
||||||
"purchaseVendorInfo": model.PurchaseVendorInfo,
|
"purchaseVendorInfo": model.PurchaseVendorInfo,
|
||||||
"afsReasonTypeName": model.AfsReasonTypeName,
|
"afsReasonTypeName": model.AfsReasonTypeName,
|
||||||
"afsAppealTypeName": model.AfsAppealTypeName,
|
"afsAppealTypeName": model.AfsAppealTypeName,
|
||||||
"actTypeName": model.ActTypeName,
|
|
||||||
"actStatusName": model.ActStatusName,
|
|
||||||
"actCreateTypeName": model.ActCreateTypeName,
|
|
||||||
"storeAuditStatusName": model.StoreAuditStatusName,
|
|
||||||
"configTypeName": model.ConfigTypeName,
|
"configTypeName": model.ConfigTypeName,
|
||||||
"autoSaleAt": AutoSaleAtStr,
|
|
||||||
"userTypeName": model.UserTypeName,
|
"userTypeName": model.UserTypeName,
|
||||||
"storePriceTypeName": model.StorePriceTypeName,
|
|
||||||
"payStatusName": model.PayStatusName,
|
|
||||||
"refundStatusName": model.RefundStatusName,
|
|
||||||
"autoReplyTypeName": model.AutoReplyTypeName,
|
|
||||||
"complaintReasons": model.ComplaintReasons,
|
"complaintReasons": model.ComplaintReasons,
|
||||||
"supplementType": model.SupplementTypeName,
|
"supplementType": model.SupplementTypeName,
|
||||||
"operateType": model.OperateTypeName,
|
"operateType": model.OperateTypeName,
|
||||||
"thingType": model.ThingTypeName,
|
|
||||||
"apiFunctionName": model.ApiFunctionName,
|
"apiFunctionName": model.ApiFunctionName,
|
||||||
"vendorStatus": model.VendorStatus,
|
"vendorStatus": model.VendorStatus,
|
||||||
"couponsStatus": model.CouponStatusName,
|
"unionActTypeNames": map[int]map[int]interface{}{
|
||||||
"ebaiSupplierID": ebai.EbaiSupplierIDMap,
|
model.VendorIDMTWM: map[int]interface{}{
|
||||||
"ebaiSupplierInfo": ebai.EbaiSupplierInfo,
|
mtunionapi.ActTypeQB: "券包推广",
|
||||||
|
},
|
||||||
|
//model.VendorIDTB: map[int]interface{}{
|
||||||
|
// tbunionapi.TbElmActTypeBDH: "本地化",
|
||||||
|
//},
|
||||||
|
//model.VendorIDPDD: map[int]interface{}{
|
||||||
|
// 1: "进行中的活动",
|
||||||
|
//},
|
||||||
|
model.VendorIDJDShop: map[int]interface{}{
|
||||||
|
2: "进行中",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"unionOrderStatusName": model.UnionOrderStatusName,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -196,217 +114,20 @@ func GetPlaces(ctx *jxcontext.Context, keyword string, includeDisabled bool, par
|
|||||||
sqlParams = append(sqlParams, params["level"])
|
sqlParams = append(sqlParams, params["level"])
|
||||||
}
|
}
|
||||||
sql += " ORDER BY t1.level, t1.name"
|
sql += " ORDER BY t1.level, t1.name"
|
||||||
|
// globals.SugarLogger.Debug(sql)
|
||||||
places := []*model.Place{}
|
places := []*model.Place{}
|
||||||
return places, dao.GetRows(nil, &places, sql, sqlParams...)
|
return places, dao.GetRows(nil, &places, sql, sqlParams)
|
||||||
}
|
|
||||||
|
|
||||||
func UpdatePlaces(ctx *jxcontext.Context, places []map[string]interface{}, userName string) (num int64, err error) {
|
|
||||||
if len(places) == 0 {
|
|
||||||
return 0, ErrMissingInput
|
|
||||||
}
|
|
||||||
updateFields := []string{}
|
|
||||||
for k := range places[0] {
|
|
||||||
if allowUpdatePlaceFieldsMap[k] {
|
|
||||||
updateFields = append(updateFields, k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, place := range places {
|
|
||||||
if place["code"] == nil {
|
|
||||||
return 0, ErrMissingInput
|
|
||||||
}
|
|
||||||
placeid := &model.Place{}
|
|
||||||
valid := dao.NormalMakeMapByFieldList(place, updateFields, userName)
|
|
||||||
if num, err = dao.UpdateEntityLogically(nil, placeid, valid, userName, utils.Params2Map("Code", place["code"])); err != nil {
|
|
||||||
return num, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return num, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func UpdatePlace(ctx *jxcontext.Context, placeCode int, payload map[string]interface{}, userName string) (num int64, err error) {
|
|
||||||
payload["code"] = placeCode
|
|
||||||
return UpdatePlaces(ctx, []map[string]interface{}{payload}, userName)
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetCoordinateDistrictCode(ctx *jxcontext.Context, lng, lat float64) (code int, err error) {
|
|
||||||
return api.TencentMapAPI.GetCoordinateDistrictCode(lng, lat), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetCoordinateCityInfo(ctx *jxcontext.Context, lng, lat float64) (name string, err error) {
|
|
||||||
name, _ = api.TencentMapAPI.GetCoordinateCityInfo(lng, lat)
|
|
||||||
return name, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func SendMsg2Somebody(ctx *jxcontext.Context, mobileNum, verifyCode, msgType, msgContent string) (err error) {
|
func SendMsg2Somebody(ctx *jxcontext.Context, mobileNum, verifyCode, msgType, msgContent string) (err error) {
|
||||||
if needConfirmRequestMap[msgType] == 1 {
|
|
||||||
if _, err = mobile.AutherObj.VerifySecret(mobileNum, verifyCode); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
db := dao.GetDB()
|
|
||||||
//获取门店信息
|
|
||||||
var (
|
|
||||||
stores []*model.Store
|
|
||||||
authBinds []*model.AuthBind
|
|
||||||
order *model.GoodsOrder
|
|
||||||
storeName string
|
|
||||||
storeID int
|
|
||||||
vendorOrderID string
|
|
||||||
)
|
|
||||||
if mobileNum != "" {
|
|
||||||
sql := `
|
|
||||||
SELECT * FROM store WHERE (tel1 = ? OR tel2 = ?) AND deleted_at = ?
|
|
||||||
`
|
|
||||||
sqlParams := []interface{}{mobileNum, mobileNum, utils.DefaultTimeValue}
|
|
||||||
err = dao.GetRows(db, &stores, sql, sqlParams)
|
|
||||||
if len(stores) > 0 {
|
|
||||||
storeName = stores[0].Name
|
|
||||||
storeID = stores[0].ID
|
|
||||||
}
|
|
||||||
if storeID == 0 {
|
|
||||||
results := regexpMsgContentOpID.FindStringSubmatch(msgContent)
|
|
||||||
if len(results) > 0 {
|
|
||||||
sql3 := `
|
|
||||||
SELECT * FROM auth_bind WHERE auth_id = ? OR auth_id2 = ?
|
|
||||||
`
|
|
||||||
sqlParams3 := []interface{}{results[1], results[1]}
|
|
||||||
err = dao.GetRows(db, &authBinds, sql3, sqlParams3)
|
|
||||||
if len(authBinds) > 0 {
|
|
||||||
user, _ := dao.GetUserByID(db, "user_id", authBinds[0].UserID)
|
|
||||||
mobileNum = *user.Mobile
|
|
||||||
sqlParams4 := []interface{}{mobileNum, mobileNum, utils.DefaultTimeValue}
|
|
||||||
err = dao.GetRows(db, &stores, sql, sqlParams4)
|
|
||||||
if len(stores) > 0 {
|
|
||||||
storeName = stores[0].Name
|
|
||||||
storeID = stores[0].ID
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
results := regexpMsgContentOpID.FindStringSubmatch(msgContent)
|
|
||||||
if len(results) > 0 {
|
|
||||||
sql3 := `
|
|
||||||
SELECT * FROM auth_bind WHERE auth_id = ? OR auth_id2 = ?
|
|
||||||
`
|
|
||||||
sqlParams3 := []interface{}{results[1], results[1]}
|
|
||||||
err = dao.GetRows(db, &authBinds, sql3, sqlParams3)
|
|
||||||
if len(authBinds) > 0 {
|
|
||||||
user, _ := dao.GetUserByID(db, "user_id", authBinds[0].UserID)
|
|
||||||
mobileNum = *user.Mobile
|
|
||||||
sql4 := `
|
|
||||||
SELECT * FROM store WHERE (tel1 = ? OR tel2 = ?) AND deleted_at = ?
|
|
||||||
`
|
|
||||||
sqlParams4 := []interface{}{mobileNum, mobileNum, utils.DefaultTimeValue}
|
|
||||||
err = dao.GetRows(db, &stores, sql4, sqlParams4)
|
|
||||||
if len(stores) > 0 {
|
|
||||||
storeName = stores[0].Name
|
|
||||||
storeID = stores[0].ID
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sql2 := `
|
|
||||||
SELECT *
|
|
||||||
FROM goods_order
|
|
||||||
WHERE IF(store_id <> '', store_id, jx_store_id) = ?
|
|
||||||
ORDER BY order_created_at DESC
|
|
||||||
LIMIT 1
|
|
||||||
`
|
|
||||||
sqlParams2 := []interface{}{storeID}
|
|
||||||
err = dao.GetRow(db, &order, sql2, sqlParams2)
|
|
||||||
if order != nil {
|
|
||||||
vendorOrderID = order.VendorOrderID
|
|
||||||
}
|
|
||||||
if storeID == 0 {
|
|
||||||
vendorOrderID = ""
|
|
||||||
}
|
|
||||||
msgContent = msgContent + " 门店名称:" + storeName + " 门店ID:" + utils.Int2Str(storeID) + " 最新订单号:" + vendorOrderID
|
|
||||||
for _, v := range receiveMsgUsersMap[msgType] {
|
|
||||||
user, err2 := dao.GetUserByID(db, "name", v)
|
|
||||||
if err2 == nil {
|
|
||||||
ddmsg.SendUserMessage(dingdingapi.MsgTyeText, user.GetID(), msgType, msgContent)
|
|
||||||
} else if err == nil {
|
|
||||||
err = err2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkSysConfig(key, value string) (err error) {
|
|
||||||
if limit := SysConfigLimitMap[key]; limit != nil {
|
|
||||||
if limit.ValueType == reflect.Int {
|
|
||||||
int64Value, err2 := strconv.ParseInt(value, 10, 64)
|
|
||||||
if err = err2; err == nil {
|
|
||||||
if int64Value < limit.MinValue || int64Value > limit.MaxValue {
|
|
||||||
err = fmt.Errorf("配置%s,值%s超范围[%d,%d]", key, value, limit.MinValue, limit.MaxValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func onSysConfigChanged(key, value string) (err error) {
|
|
||||||
if limit := SysConfigLimitMap[key]; limit != nil && limit.AfterChanged != nil {
|
|
||||||
err = limit.AfterChanged()
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkConfig(opFlag int, configType, key, value string) (err error) {
|
|
||||||
switch configType {
|
|
||||||
case model.ConfigTypePricePack:
|
|
||||||
if value != "" {
|
|
||||||
pricePack := dao.PricePercentagePack2Obj(value)
|
|
||||||
if pricePack == nil {
|
|
||||||
err = fmt.Errorf("配置:%s不合法", value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case model.ConfigTypeFreightPack:
|
|
||||||
if value != "" {
|
|
||||||
freightPack := dao.FreightDeductionPack2Obj(value)
|
|
||||||
if freightPack == nil {
|
|
||||||
err = fmt.Errorf("配置:%s不合法", value)
|
|
||||||
} else {
|
|
||||||
var lastStage *model.FreightDeductionItem
|
|
||||||
for _, v := range freightPack.FreightDeductionList {
|
|
||||||
if lastStage != nil && lastStage.DeductFreight > v.DeductFreight {
|
|
||||||
err = fmt.Errorf("免运设置不合理:门槛:%s,免运金额:%s,门槛:%s,免运金额:%s",
|
|
||||||
jxutils.IntPrice2StandardString(int64(lastStage.BeginPrice)), jxutils.IntPrice2StandardString(int64(lastStage.DeductFreight)),
|
|
||||||
jxutils.IntPrice2StandardString(int64(v.BeginPrice)), jxutils.IntPrice2StandardString(int64(v.DeductFreight)))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
lastStage = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case model.ConfigTypeBank:
|
|
||||||
if value != "" {
|
|
||||||
if model.BankName[key] == "" {
|
|
||||||
err = fmt.Errorf("此银行代码:%s不支持,请联系开发", value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case model.ConfigTypeRole:
|
|
||||||
case model.ConfigTypeSys:
|
|
||||||
if opFlag&( /*model.SyncFlagNewMask|*/ model.SyncFlagDeletedMask) != 0 {
|
|
||||||
err = fmt.Errorf("系统参数只支持修改或添加,不支持删除")
|
|
||||||
} else {
|
|
||||||
err = checkSysConfig(key, value)
|
|
||||||
}
|
|
||||||
case model.ConfigTypeJxStore:
|
|
||||||
case model.ConfigTypeCookie:
|
|
||||||
case model.ConfigTypeDiscountCard:
|
|
||||||
default:
|
|
||||||
err = fmt.Errorf("当前只支持配置:%s, 传入的配置类型:%s", utils.Format4Output(model.ConfigTypeName, true), configType)
|
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddConfig(ctx *jxcontext.Context, key, configType, value string) (err error) {
|
func AddConfig(ctx *jxcontext.Context, key, configType, value string) (err error) {
|
||||||
if err = checkConfig(model.SyncFlagNewMask, configType, key, value); err != nil {
|
// if err = checkConfig(model.SyncFlagNewMask, configType, key, value); err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
|
|
||||||
db := dao.GetDB()
|
db := dao.GetDB()
|
||||||
conf := &model.NewConfig{
|
conf := &model.NewConfig{
|
||||||
@@ -417,75 +138,7 @@ func AddConfig(ctx *jxcontext.Context, key, configType, value string) (err error
|
|||||||
dao.WrapAddIDCULDEntity(conf, ctx.GetUserName())
|
dao.WrapAddIDCULDEntity(conf, ctx.GetUserName())
|
||||||
err = dao.CreateEntity(db, conf)
|
err = dao.CreateEntity(db, conf)
|
||||||
if configType == model.ConfigTypeSys && err == nil {
|
if configType == model.ConfigTypeSys && err == nil {
|
||||||
err = onSysConfigChanged(key, value)
|
// err = onSysConfigChanged(key, value)
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func DeleteConfig(ctx *jxcontext.Context, key, configType string) (err error) {
|
|
||||||
if err = checkConfig(model.SyncFlagDeletedMask, configType, key, ""); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
db := dao.GetDB()
|
|
||||||
switch configType {
|
|
||||||
case model.ConfigTypePricePack:
|
|
||||||
storeMapList, err2 := dao.GetStoresMapList(db, nil, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, key, "", "")
|
|
||||||
if err = err2; err == nil {
|
|
||||||
var storeInfo []string
|
|
||||||
for _, v := range storeMapList {
|
|
||||||
storeInfo = append(storeInfo, fmt.Sprintf("门店:%d, 平台:%s", v.StoreID, model.VendorChineseNames[v.VendorID]))
|
|
||||||
}
|
|
||||||
if len(storeInfo) > 0 {
|
|
||||||
err = fmt.Errorf("还有门店在使用价格包:%s,门店信息:%s", key, strings.Join(storeInfo, ","))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case model.ConfigTypeFreightPack:
|
|
||||||
storeMapList, err2 := dao.GetStoresMapList(db, nil, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, "", "", "")
|
|
||||||
if err = err2; err == nil {
|
|
||||||
var storeInfo []string
|
|
||||||
for _, v := range storeMapList {
|
|
||||||
if v.FreightDeductionPack == key {
|
|
||||||
storeInfo = append(storeInfo, fmt.Sprintf("门店:%d, 平台:%s", v.StoreID, model.VendorChineseNames[v.VendorID]))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(storeInfo) > 0 {
|
|
||||||
err = fmt.Errorf("还有门店在使用价格包:%s,门店信息:%s", key, strings.Join(storeInfo, ","))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case model.ConfigTypeBank:
|
|
||||||
//todo
|
|
||||||
return fmt.Errorf("暂不支持删除银行")
|
|
||||||
case model.ConfigTypeRole:
|
|
||||||
errList := errlist.New()
|
|
||||||
userIDs, err2 := api2.RoleMan.GetRoleUserList(autils.NewRole(key, 0))
|
|
||||||
if err = err2; err == nil && len(userIDs) > 0 {
|
|
||||||
userList, totalCount, err2 := dao.GetUsers(dao.GetDB(), 0, "", userIDs, nil, nil, 0, -1)
|
|
||||||
if err = err2; err == nil && totalCount > 0 {
|
|
||||||
// todo
|
|
||||||
// err = fmt.Errorf("还有人员在使用角色:%s,人员信息:%s", key, utils.MustMarshal(utils.Struct2Map(userList, "compact")))
|
|
||||||
err = fmt.Errorf("还有人员在使用角色:%s,人员信息:%s", key, utils.Format4Output(userList, false))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
errList.AddErr(err)
|
|
||||||
storeList, err2 := dao.GetStoreList(db, nil, nil, nil, nil, nil, key)
|
|
||||||
if err = err2; err == nil && len(storeList) > 0 {
|
|
||||||
storeIDs := make([]int, len(storeList))
|
|
||||||
for k, v := range storeList {
|
|
||||||
storeIDs[k] = v.ID
|
|
||||||
}
|
|
||||||
err = fmt.Errorf("还有门店在使用角色:%s,门店信息:%s", key, utils.MustMarshal(storeIDs))
|
|
||||||
}
|
|
||||||
errList.AddErr(err)
|
|
||||||
err = errList.GetErrListAsOne()
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
_, err = dao.DeleteEntityLogically(db, &model.NewConfig{}, nil, ctx.GetUserName(), map[string]interface{}{
|
|
||||||
"Key": key,
|
|
||||||
"Type": configType,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if configType == model.ConfigTypeSys && err == nil {
|
|
||||||
err = onSysConfigChanged(key, "")
|
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -494,9 +147,6 @@ func UpdateConfig(ctx *jxcontext.Context, key, configType, value string) (hint s
|
|||||||
if key == "" {
|
if key == "" {
|
||||||
return "", fmt.Errorf("修改配置必须给定key")
|
return "", fmt.Errorf("修改配置必须给定key")
|
||||||
}
|
}
|
||||||
if err = checkConfig(model.SyncFlagModifiedMask, configType, key, value); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
hint = "1"
|
hint = "1"
|
||||||
|
|
||||||
db := dao.GetDB()
|
db := dao.GetDB()
|
||||||
@@ -520,54 +170,12 @@ func UpdateConfig(ctx *jxcontext.Context, key, configType, value string) (hint s
|
|||||||
}
|
}
|
||||||
switch configType {
|
switch configType {
|
||||||
case model.ConfigTypePricePack:
|
case model.ConfigTypePricePack:
|
||||||
storeMapList, err := dao.GetStoresMapList(db, nil, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, key, "", "")
|
|
||||||
if err != nil {
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
dao.Commit(db, txDB)
|
|
||||||
vendorStoreMap := make(map[int][]int)
|
|
||||||
for _, v := range storeMapList {
|
|
||||||
vendorStoreMap[v.VendorID] = append(vendorStoreMap[v.VendorID], v.StoreID)
|
|
||||||
}
|
|
||||||
for vendorID, storeIDs := range vendorStoreMap {
|
|
||||||
if vendorID != model.VendorIDJX {
|
|
||||||
dao.SetStoreSkuSyncStatus(db, vendorID, storeIDs, nil, model.SyncFlagPriceMask)
|
|
||||||
} else {
|
|
||||||
hint, err = ReCalculateJxPrice(db, ctx, storeIDs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case model.ConfigTypeFreightPack:
|
|
||||||
dao.Commit(db, txDB)
|
|
||||||
storeMapList, err := dao.GetStoresMapList(db, nil, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, "", "", "")
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
for _, v := range storeMapList {
|
|
||||||
var storeMapList2 []*model.StoreMap
|
|
||||||
if v.FreightDeductionPack == key {
|
|
||||||
storeMapList2 = append(storeMapList2, v)
|
|
||||||
}
|
|
||||||
if len(storeMapList2) > 0 {
|
|
||||||
task := tasksch.NewParallelTask("同步门店配送免运", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx,
|
|
||||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
|
||||||
storeMap := batchItemList[0].(*model.StoreMap)
|
|
||||||
_, err = CurVendorSync.SyncStore(ctx, db, storeMap.VendorID, storeMap.StoreID, false, ctx.GetUserName())
|
|
||||||
return retVal, err
|
|
||||||
}, storeMapList2)
|
|
||||||
tasksch.HandleTask(task, nil, true).Run()
|
|
||||||
if len(storeMapList2) < 5 {
|
|
||||||
_, err = task.GetResult(0)
|
|
||||||
} else {
|
|
||||||
hint = task.GetID()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
dao.Commit(db, txDB)
|
dao.Commit(db, txDB)
|
||||||
}
|
}
|
||||||
if configType == model.ConfigTypeSys && err == nil {
|
if configType == model.ConfigTypeSys && err == nil {
|
||||||
err = onSysConfigChanged(key, value)
|
// err = onSysConfigChanged(key, value)
|
||||||
}
|
}
|
||||||
return hint, err
|
return hint, err
|
||||||
}
|
}
|
||||||
@@ -575,198 +183,3 @@ func UpdateConfig(ctx *jxcontext.Context, key, configType, value string) (hint s
|
|||||||
func QueryConfigs(key, configType, keyword string) (configList []*model.NewConfig, err error) {
|
func QueryConfigs(key, configType, keyword string) (configList []*model.NewConfig, err error) {
|
||||||
return dao.QueryConfigs(dao.GetDB(), key, configType, keyword)
|
return dao.QueryConfigs(dao.GetDB(), key, configType, keyword)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetCityBankBranches(ctx *jxcontext.Context, cityCode int, bankCode string) (info map[int]map[string][]string, err error) {
|
|
||||||
list, err := dao.GetCityBankBranches(dao.GetDB(), cityCode, bankCode)
|
|
||||||
if err == nil && len(list) > 0 {
|
|
||||||
info = make(map[int]map[string][]string)
|
|
||||||
for _, v := range list {
|
|
||||||
if info[v.CityCode] == nil {
|
|
||||||
info[v.CityCode] = make(map[string][]string)
|
|
||||||
}
|
|
||||||
info[v.CityCode][v.PayeeBankCode] = append(info[v.CityCode][v.PayeeBankCode], v.PayeeBankBranchName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return info, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSToURidingDistance 获取商家与用户间步行距离
|
|
||||||
func GetSToURidingDistance(sLng, sLat, uLng, uLat float64, orderId string) (stepInfo interface{}, err error) {
|
|
||||||
coordList, err := api.TencentMapAPI.TencentCoordinateChange(&tencent_map.TencentCoordinateChangeReq{
|
|
||||||
Locations: fmt.Sprintf("%.6f,%.6f;%.6f,%.6f", sLat, sLng, uLat, uLng),
|
|
||||||
Type: tencent_map.CoordinateChangeTypeBaidu,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err == nil && len(coordList) == 2 {
|
|
||||||
param := &tencent_map.TencentCyclingPlanningReq{
|
|
||||||
From: fmt.Sprintf("%s,%s", coordList[0].Lat, coordList[0].Lng),
|
|
||||||
To: fmt.Sprintf("%s,%s", coordList[1].Lat, coordList[1].Lng),
|
|
||||||
}
|
|
||||||
if stepInfo, err = api.TencentMapAPI.WalkingDistance(param); err == nil {
|
|
||||||
return stepInfo, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSToURidingDistance2 获取商家与用户间步行距离
|
|
||||||
func GetSToURidingDistance2(sLng, sLat, uLng, uLat float64, orderId string, vendors []int64) (wayBill *model.Waybill, err error) {
|
|
||||||
var (
|
|
||||||
db = dao.GetDB()
|
|
||||||
vendorMaps = map[int]int{model.VendorIDDada: 1, model.VendorIDFengNiao: 1, model.VendorIDMTPS: 1, model.VendorIDUUPT: 1, model.VendorIDSFPS: 1}
|
|
||||||
)
|
|
||||||
|
|
||||||
for {
|
|
||||||
// 骑手坐标
|
|
||||||
waybills, err := dao.GetWaybills(db, orderId, vendors)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(waybills) == model.NO {
|
|
||||||
return nil, fmt.Errorf("请先创建运单,或者转自配送")
|
|
||||||
}
|
|
||||||
for _, v := range waybills {
|
|
||||||
// 获取骑行路线图
|
|
||||||
if v.OriginalData == "" && v.WaybillVendorID == model.VendorJXFakeWL {
|
|
||||||
originalData, distance, durationTime, err2 := GetCyclingLine(sLng, sLat, uLng, uLat)
|
|
||||||
if err2 == nil && len(originalData) != model.NO {
|
|
||||||
v.OriginalData = strings.Join(originalData, ";")
|
|
||||||
v.Distance = distance
|
|
||||||
v.DurationTime = durationTime + 500
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if vendorMaps[v.WaybillVendorID] == model.YES {
|
|
||||||
// 如果是三方配送,更新骑手信息
|
|
||||||
if handler := partner.GetDeliveryPlatformFromVendorID(v.WaybillVendorID); handler != nil {
|
|
||||||
riderInfo, _ := handler.Handler.GetRiderInfo(v.VendorOrderID, v.ID+1000000, v.VendorWaybillID)
|
|
||||||
if riderInfo != nil {
|
|
||||||
if len(riderInfo.Longitude) < len("104.065861") || riderInfo.Longitude != "" {
|
|
||||||
riderInfo.Longitude += "0"
|
|
||||||
}
|
|
||||||
if len(riderInfo.Latitude) < len("27.934441") || riderInfo.Latitude != "" {
|
|
||||||
riderInfo.Latitude += "0"
|
|
||||||
}
|
|
||||||
v.CourierCoordinate = fmt.Sprintf("%s,%s", riderInfo.Longitude, riderInfo.Latitude)
|
|
||||||
if (v.CourierName == "" || v.CourierMobile == "") && riderInfo.CourierName != "" {
|
|
||||||
v.CourierName = riderInfo.CourierName
|
|
||||||
v.CourierMobile = riderInfo.CourierPhone
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 如果是平台配送,获取骑手信息
|
|
||||||
if handler := partner.GetPurchaseOrderHandlerFromVendorID(v.WaybillVendorID); handler != nil {
|
|
||||||
riderInfo, _ := handler.OrderLogisticsStatus(v.VendorOrderID)
|
|
||||||
if riderInfo != nil {
|
|
||||||
if len(riderInfo.Longitude) < len("104.065861") || riderInfo.Longitude != "" {
|
|
||||||
riderInfo.Longitude += "0"
|
|
||||||
}
|
|
||||||
if len(riderInfo.Latitude) < len("27.934441") || riderInfo.Latitude != "" {
|
|
||||||
riderInfo.Latitude += "0"
|
|
||||||
}
|
|
||||||
v.CourierCoordinate = fmt.Sprintf("%s,%s", riderInfo.Longitude, riderInfo.Latitude)
|
|
||||||
if (v.CourierName == "" || v.CourierMobile == "") && riderInfo.CourierName != "" {
|
|
||||||
v.CourierName = riderInfo.CourierName
|
|
||||||
v.CourierMobile = riderInfo.CourierPhone
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 当这个运单为假物流/门店真实自送/获取运单骑手信息为空的时候使用假的骑手信息
|
|
||||||
if (v.WaybillVendorID == model.VendorJXFakeWL || v.WaybillVendorID == model.VendorIDUnknown || v.CourierCoordinate == "") && v.OriginalData != "" {
|
|
||||||
riderLine := strings.Split(v.OriginalData, ";") // 路线坐标点
|
|
||||||
|
|
||||||
courierDistance := float64(time.Now().Unix()-v.WaybillCreatedAt.Unix()) * (float64(v.Distance) / float64(v.DurationTime)) // 当前骑手骑行距离
|
|
||||||
if courierDistance >= float64(v.Distance) {
|
|
||||||
courierDistance = float64(v.Distance)
|
|
||||||
}
|
|
||||||
nowCourierDrop := int64(math.Ceil((courierDistance / float64(v.Distance)) * float64(len(riderLine)))) // 当前骑手骑行距离,占中的骑行距离百分比.
|
|
||||||
if nowCourierDrop >= int64(len(riderLine)) {
|
|
||||||
v.CourierCoordinate = riderLine[nowCourierDrop-1]
|
|
||||||
}
|
|
||||||
if nowCourierDrop <= 0 {
|
|
||||||
v.CourierCoordinate = riderLine[0]
|
|
||||||
}
|
|
||||||
if v.Status >= model.WaybillStatusDelivered {
|
|
||||||
v.CourierCoordinate = riderLine[len(riderLine)-1]
|
|
||||||
}
|
|
||||||
if v.Status == model.WaybillStatusCourierArrived {
|
|
||||||
order, _ := partner.CurOrderManager.LoadOrder(orderId, v.OrderVendorID)
|
|
||||||
storeDetail, err := dao.GetStoreDetail2(dao.GetDB(), order.JxStoreID, order.VendorStoreID, order.VendorID)
|
|
||||||
if err == nil && storeDetail != nil {
|
|
||||||
v.CourierCoordinate = fmt.Sprintf("%s,%s", utils.Float64ToStr(jxutils.IntCoordinate2Standard(storeDetail.Lng)), utils.Float64ToStr(jxutils.IntCoordinate2Standard(storeDetail.Lat)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if v.CourierCoordinate == "" {
|
|
||||||
v.CourierCoordinate = riderLine[nowCourierDrop]
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (v.WaybillVendorID == model.VendorJXFakeWL || v.WaybillVendorID == model.VendorIDUnknown || v.CourierCoordinate == "") && v.OriginalData == "" {
|
|
||||||
lng := utils.Str2Float64(fmt.Sprintf("%0.6f", (sLng-uLng)/float64(300)))
|
|
||||||
lat := utils.Str2Float64(fmt.Sprintf("%0.6f", (sLat-uLat)/float64(300)))
|
|
||||||
originalData := make([]string, 0, 0)
|
|
||||||
originalData = append(originalData, fmt.Sprintf("%.6f,%.6f", sLng, sLat))
|
|
||||||
var nLng float64
|
|
||||||
var nLat float64
|
|
||||||
for i := 1; i <= 300; i++ {
|
|
||||||
if sLng > uLng {
|
|
||||||
nLng = sLng - (lng * float64(i))
|
|
||||||
} else {
|
|
||||||
nLng = sLng + (lng * float64(i))
|
|
||||||
}
|
|
||||||
if sLat > uLat {
|
|
||||||
nLat = sLat - (lat * float64(i))
|
|
||||||
} else {
|
|
||||||
nLat = sLat + (lat * float64(i))
|
|
||||||
}
|
|
||||||
fakeCourier := fmt.Sprintf("%.6f,%.6f", nLng, nLat)
|
|
||||||
originalData = append(originalData, fakeCourier)
|
|
||||||
}
|
|
||||||
originalData = append(originalData, fmt.Sprintf("%.6f,%.6f", uLng, uLat))
|
|
||||||
|
|
||||||
v.Distance = 5001 // 距离,固定
|
|
||||||
v.DurationTime = 600 // 固定骑行时间
|
|
||||||
v.OriginalData = strings.Join(originalData, ";")
|
|
||||||
v.CourierCoordinate = originalData[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
dao.UpdateEntity(db, v, "OriginalData", "CourierCoordinate", "Distance", "DurationTime")
|
|
||||||
if v.CourierName == "" || v.CourierMobile == "" {
|
|
||||||
v.CourierName = "暂无骑手"
|
|
||||||
v.CourierMobile = "暂无电话"
|
|
||||||
}
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetCyclingLine 获取骑行路线
|
|
||||||
func GetCyclingLine(sLng, sLat, uLng, uLat float64) (polyLineList []string, distance, duration int64, err error) {
|
|
||||||
// 百度
|
|
||||||
/* var coords []*baidunavi.Coordinate
|
|
||||||
coords = append(coords, &baidunavi.Coordinate{
|
|
||||||
Lng: sLng,
|
|
||||||
Lat: sLat,
|
|
||||||
}, &baidunavi.Coordinate{
|
|
||||||
Lat: uLat,
|
|
||||||
Lng: uLng,
|
|
||||||
})*/
|
|
||||||
|
|
||||||
// 高德坐标转换成百度坐标
|
|
||||||
/*coords, err := api.TencentMapAPI.TencentCoordinateChange(&tencent_map.TencentCoordinateChangeReq{
|
|
||||||
Locations: fmt.Sprintf("%.6f,%.6f;%.6f,%.6f", sLat, sLng, uLat, uLng),
|
|
||||||
Type: tencent_map.CoordinateChangeTypeBaidu,
|
|
||||||
})
|
|
||||||
if err != nil || len(coords) <= model.NO {
|
|
||||||
return nil, 0, 0, err
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
distance, duration, polyLineList, err = api.TencentMapAPI.TencentCyclingPlanning(&tencent_map.TencentCyclingPlanningReq{
|
|
||||||
From: fmt.Sprintf("%.6f,%.6f", sLat, sLng),
|
|
||||||
To: fmt.Sprintf("%.6f,%.6f", uLat, uLng),
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
package cms
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api2"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/testinit"
|
|
||||||
|
|
||||||
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/ebai"
|
|
||||||
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/elm"
|
|
||||||
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/jd"
|
|
||||||
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/mtwm"
|
|
||||||
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/weimob/wsc"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
testinit.Init()
|
|
||||||
api2.Init()
|
|
||||||
}
|
|
||||||
11
business/jxstore/cms/conn_test.go
Normal file
11
business/jxstore/cms/conn_test.go
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package cms
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestConn(t *testing.T) {
|
||||||
|
err := DelPrinterSeq(1000, "120220915001012")
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
@@ -4,10 +4,10 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/dao"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type MessageStatusExt struct {
|
type MessageStatusExt struct {
|
||||||
@@ -68,16 +68,17 @@ func GetStoreMessages(ctx *jxcontext.Context, msgIDs, storeIDs, types []int, fro
|
|||||||
txDB, _ := dao.Begin(db)
|
txDB, _ := dao.Begin(db)
|
||||||
defer dao.Commit(db, txDB)
|
defer dao.Commit(db, txDB)
|
||||||
var msgList []*model.Message
|
var msgList []*model.Message
|
||||||
|
// globals.SugarLogger.Debug(sql)
|
||||||
if err = dao.GetRowsTx(txDB, &msgList, sql, sqlParams...); err == nil {
|
if err = dao.GetRowsTx(txDB, &msgList, sql, sqlParams...); err == nil {
|
||||||
pagedInfo = &model.PagedInfo{
|
pagedInfo = &model.PagedInfo{
|
||||||
TotalCount: dao.GetLastTotalRowCount2(db, txDB),
|
TotalCount: dao.GetLastTotalRowCountTx(txDB),
|
||||||
Data: msgList,
|
Data: msgList,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pagedInfo, err
|
return pagedInfo, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetStoreMessageStatuses(ctx *jxcontext.Context, msgIDs, storeIDs, confirmStatuss []int, fromReadCount, toReadCount int, fromTime, toTime time.Time, keyword string, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) {
|
func GetStoreMessageStatuses(ctx *jxcontext.Context, msgIDs, storeIDs []int, fromReadCount, toReadCount int, fromTime, toTime time.Time, keyword string, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) {
|
||||||
sql := `
|
sql := `
|
||||||
SELECT SQL_CALC_FOUND_ROWS
|
SELECT SQL_CALC_FOUND_ROWS
|
||||||
t1.*,
|
t1.*,
|
||||||
@@ -91,10 +92,6 @@ func GetStoreMessageStatuses(ctx *jxcontext.Context, msgIDs, storeIDs, confirmSt
|
|||||||
sql += " AND t1.store_id IN (" + dao.GenQuestionMarks(len(storeIDs)) + ")"
|
sql += " AND t1.store_id IN (" + dao.GenQuestionMarks(len(storeIDs)) + ")"
|
||||||
sqlParams = append(sqlParams, storeIDs)
|
sqlParams = append(sqlParams, storeIDs)
|
||||||
}
|
}
|
||||||
if len(confirmStatuss) > 0 {
|
|
||||||
sql += " AND t1.confirm_status IN (" + dao.GenQuestionMarks(len(confirmStatuss)) + ")"
|
|
||||||
sqlParams = append(sqlParams, confirmStatuss)
|
|
||||||
}
|
|
||||||
if len(msgIDs) > 0 {
|
if len(msgIDs) > 0 {
|
||||||
sql += " AND t1.message_id IN (" + dao.GenQuestionMarks(len(msgIDs)) + ")"
|
sql += " AND t1.message_id IN (" + dao.GenQuestionMarks(len(msgIDs)) + ")"
|
||||||
sqlParams = append(sqlParams, msgIDs)
|
sqlParams = append(sqlParams, msgIDs)
|
||||||
@@ -126,9 +123,11 @@ func GetStoreMessageStatuses(ctx *jxcontext.Context, msgIDs, storeIDs, confirmSt
|
|||||||
txDB, _ := dao.Begin(db)
|
txDB, _ := dao.Begin(db)
|
||||||
defer dao.Commit(db, txDB)
|
defer dao.Commit(db, txDB)
|
||||||
var msgStatusList []*MessageStatusExt
|
var msgStatusList []*MessageStatusExt
|
||||||
|
// globals.SugarLogger.Debug(sql)
|
||||||
|
// globals.SugarLogger.Debug(utils.Format4Output(sqlParams, false))
|
||||||
if err = dao.GetRowsTx(txDB, &msgStatusList, sql, sqlParams...); err == nil {
|
if err = dao.GetRowsTx(txDB, &msgStatusList, sql, sqlParams...); err == nil {
|
||||||
pagedInfo = &model.PagedInfo{
|
pagedInfo = &model.PagedInfo{
|
||||||
TotalCount: dao.GetLastTotalRowCount2(db, txDB),
|
TotalCount: dao.GetLastTotalRowCountTx(txDB),
|
||||||
Data: msgStatusList,
|
Data: msgStatusList,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
package cms
|
|
||||||
@@ -1,292 +0,0 @@
|
|||||||
package cms
|
|
||||||
//
|
|
||||||
//import (
|
|
||||||
// "encoding/json"
|
|
||||||
// "errors"
|
|
||||||
// "fmt"
|
|
||||||
// "git.rosy.net.cn/baseapi/utils"
|
|
||||||
// "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
// "git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
|
||||||
// "git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
// "git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
// "git.rosy.net.cn/jx-callback/business/partner/purchase/jx/localjx"
|
|
||||||
// "github.com/360EntSecGroup-Skylar/excelize"
|
|
||||||
// "io"
|
|
||||||
// "mime/multipart"
|
|
||||||
// "strings"
|
|
||||||
//)
|
|
||||||
//
|
|
||||||
//// 根据excel新增待拣货订单
|
|
||||||
//func CreateOrderByExcel(ctx *jxcontext.Context, files []*multipart.FileHeader) (hint string, err error) {
|
|
||||||
// if len(files) == 0 {
|
|
||||||
// return "", errors.New("没有文件上传!")
|
|
||||||
// }
|
|
||||||
// fileHeader := files[0]
|
|
||||||
// file, err := fileHeader.Open()
|
|
||||||
// hint, err = RefreshJxPriceByExcelBin(ctx, file, true, true)
|
|
||||||
// file.Close()
|
|
||||||
// return hint, err
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//type CreateOrderByExcelStore struct {
|
|
||||||
// BuyerComment int // 备注
|
|
||||||
// StoreID int // 门店id
|
|
||||||
// Skus int // 商品列表
|
|
||||||
// ExpectedDeliveredTimestamp int // 预期送达时间
|
|
||||||
// TotalPrice int // 总价格
|
|
||||||
// FreightPrice int // 运费
|
|
||||||
// OrderPrice int // 订单价格
|
|
||||||
// ActualPayPrice int // 顾客实际支付
|
|
||||||
// OrderID int // 订单id
|
|
||||||
// StoreName int // 门店名称
|
|
||||||
// Weight int // 重量
|
|
||||||
// FromStoreID int // 物料ID
|
|
||||||
// EarningType int // 结算方式(1为报价,2为扣点),0无
|
|
||||||
// OrderType int // 订单类型
|
|
||||||
// IsBuyNowPrice int // 守价的值只有0和1
|
|
||||||
// IsPriceDefend int
|
|
||||||
// OrderID2 int
|
|
||||||
// UserID int // 用户id
|
|
||||||
// AddressID int // 收货地址id
|
|
||||||
// CreateType int // "创建类型, 0:预创建, 1:创建"
|
|
||||||
// IsDeliverySelf int // 自提
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//// 赋值excel表字段排序
|
|
||||||
//func SortExcelTable() *CreateOrderByExcelStore {
|
|
||||||
// return &CreateOrderByExcelStore{
|
|
||||||
// StoreID: 1,
|
|
||||||
// StoreName: 2,
|
|
||||||
// UserID: 3,
|
|
||||||
// AddressID: 4,
|
|
||||||
// Skus: 5,
|
|
||||||
// Weight: 6,
|
|
||||||
// TotalPrice: 7,
|
|
||||||
// FreightPrice: 8,
|
|
||||||
// OrderPrice: 9,
|
|
||||||
// ActualPayPrice: 10,
|
|
||||||
// ExpectedDeliveredTimestamp: 11,
|
|
||||||
// OrderType: 12,
|
|
||||||
// FromStoreID: 13,
|
|
||||||
// EarningType: 14,
|
|
||||||
// BuyerComment: 15,
|
|
||||||
//
|
|
||||||
// CreateType: 16,
|
|
||||||
// IsDeliverySelf: 17,
|
|
||||||
// IsPriceDefend: 18,
|
|
||||||
// IsBuyNowPrice: 19,
|
|
||||||
// OrderID: 20,
|
|
||||||
// OrderID2: 21,
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//// 订单结构体
|
|
||||||
//type ExcelOrderStruct struct {
|
|
||||||
// BuyerComment string `json:"buyerComment"` // 备注
|
|
||||||
// StoreID int `json:"storeID"`
|
|
||||||
// Skus []*JxSkuInfo `json:"skus"`
|
|
||||||
// ExpectedDeliveredTimestamp int64 `json:"expectedDeliveredTimestamp"` // 预期送达时间
|
|
||||||
// TotalPrice int64 `json:"totalPrice"` // 单位为分 订单总价
|
|
||||||
// FreightPrice int64 `json:"freightPrice"` // 单位为分 订单配送费
|
|
||||||
// OrderPrice int64 `json:"orderPrice"` // 单位为分 订单商品价格
|
|
||||||
// ActualPayPrice int64 `json:"actualPayPrice"` // 单位为分 顾客实际支付
|
|
||||||
// OrderID int64 `json:"orderID"`
|
|
||||||
// StoreName string `json:"storeName"`
|
|
||||||
// Weight int `json:"weight"`
|
|
||||||
// FromStoreID int `json:"fromStoreID"` //
|
|
||||||
// EarningType int `json:"earningType"`
|
|
||||||
// OrderType int `json:"orderType"`
|
|
||||||
// IsBuyNowPrice int `json:"isBuyNowPrice"`
|
|
||||||
// IsPriceDefend int `json:"isPriceDefend"`
|
|
||||||
// OrderID2 string `json:"-"` // 订单id2
|
|
||||||
// UserID string `json:"userID"` // 用户id
|
|
||||||
// AddressId int64 `json:"address_id"` // 地址id
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//// 商品列表
|
|
||||||
//type JxSkuInfo struct {
|
|
||||||
// SkuID int `json:"skuID"`
|
|
||||||
// Count int `json:"count"`
|
|
||||||
// Price int64 `json:"price,omitempty"` // 原价
|
|
||||||
// SalePrice int64 `json:"salePrice,omitempty"` // 售卖价
|
|
||||||
// Name string `json:"name"`
|
|
||||||
// Weight int `json:"weight"`
|
|
||||||
// GroupSign bool `json:"groupSign"`
|
|
||||||
// DefendPrice int64 `json:"defendPrice"` //守价
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//// 解析excel到订单结构体当中
|
|
||||||
//func GetCellIntoOrder(rowNum int, row []string, sheetParam *CreateOrderByExcelStore, order *ExcelOrderStruct, nameMap map[string]string) (errMsg string) {
|
|
||||||
// address := make(map[string]int64, 0)
|
|
||||||
// for k, cell := range row {
|
|
||||||
// switch k {
|
|
||||||
// case sheetParam.StoreID:
|
|
||||||
// order.StoreID = utils.Str2Int(cell)
|
|
||||||
// case sheetParam.StoreName:
|
|
||||||
// order.StoreName = cell
|
|
||||||
// case sheetParam.UserID:
|
|
||||||
// order.UserID = cell
|
|
||||||
// case sheetParam.AddressID:
|
|
||||||
// order.AddressId = utils.Str2Int64(cell)
|
|
||||||
// case sheetParam.Skus:
|
|
||||||
// shop := make([]*JxSkuInfo, 0, 0)
|
|
||||||
// if err := json.Unmarshal([]byte(cell), shop); err != nil {
|
|
||||||
// return fmt.Sprintf("解析excel文档用户商品列表错,检查数据格式是否正确")
|
|
||||||
// }
|
|
||||||
// order.Skus = shop
|
|
||||||
// case sheetParam.Weight:
|
|
||||||
// order.Weight = utils.Str2Int(cell)
|
|
||||||
// case sheetParam.TotalPrice:
|
|
||||||
// order.TotalPrice = utils.Str2Int64(cell)
|
|
||||||
// case sheetParam.FreightPrice:
|
|
||||||
// order.FreightPrice = utils.Str2Int64(cell)
|
|
||||||
// case sheetParam.OrderPrice:
|
|
||||||
// order.OrderPrice = utils.Str2Int64(cell)
|
|
||||||
// case sheetParam.ActualPayPrice:
|
|
||||||
// order.ActualPayPrice = utils.Str2Int64(cell)
|
|
||||||
// case :
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if k == sheetParam.SkuNameIDCol {
|
|
||||||
// cellReplace := strings.ReplaceAll(cell, ",", ",")
|
|
||||||
// if cellReplace != "" {
|
|
||||||
// if cellReplace[len(cellReplace)-1:len(cellReplace)] == "," {
|
|
||||||
// cellReplace = cellReplace[0 : len(cellReplace)-1]
|
|
||||||
// }
|
|
||||||
// nameIDs := strings.Split(cellReplace, ",")
|
|
||||||
// for _, v := range nameIDs {
|
|
||||||
// if nameMap[v] != "" {
|
|
||||||
// return fmt.Sprintf(" Excel中含有重复的nameID![%v]列,[%v]行,nameID [%v]\n", k+1, rowNum+1, v)
|
|
||||||
// } else {
|
|
||||||
// nameMap[v] = v
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// storeSkuNamePrice.NameIDGroup = cellReplace
|
|
||||||
// }
|
|
||||||
// if k == sheetParam.SkuPriceCol {
|
|
||||||
// if IsChineseChar(cell) {
|
|
||||||
// return fmt.Sprintf("Excel格式排版发生了变化!在[%v]列,[%v]行附近可能增加或减少了一列", k+1, rowNum+1)
|
|
||||||
// }
|
|
||||||
// storeSkuNamePrice.Price = int(utils.Float64TwoInt64(utils.Str2Float64(cell) * 100))
|
|
||||||
// }
|
|
||||||
// if k == sheetParam.SkuUnitCol {
|
|
||||||
// storeSkuNamePrice.Unit = cell
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return errMsg
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//func AnalysisExcelOrder(ctx *jxcontext.Context, reader io.Reader, isAsync, isContinueWhenError bool) {
|
|
||||||
// excelSort := SortExcelTable()
|
|
||||||
// taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
|
||||||
// switch step {
|
|
||||||
// case 0:
|
|
||||||
// xlsx, err := excelize.OpenReader(reader)
|
|
||||||
// if err != nil {
|
|
||||||
// return "", err
|
|
||||||
// }
|
|
||||||
// rows, _ := xlsx.GetRows(xlsx.GetSheetName(1))
|
|
||||||
// for rowNum, row := range rows {
|
|
||||||
// if rowNum < model.YES { // 第一行跳过
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// storeSkuNamePrice := &localjx.JxOrderInfo{}
|
|
||||||
// errMsg += GetCellIntoStruct(rowNum, row, excelSort, storeSkuNamePrice, nameMap)
|
|
||||||
// storeSkuNamePriceList = append(storeSkuNamePriceList, storeSkuNamePrice)
|
|
||||||
// }
|
|
||||||
// if errMsg != "" {
|
|
||||||
// return "", errors.New(errMsg)
|
|
||||||
// } else {
|
|
||||||
// isErr = true
|
|
||||||
// }
|
|
||||||
// case 1:
|
|
||||||
// db := dao.GetDB()
|
|
||||||
// storeSkuNamePriceListOrg, _ := dao.GetStoreSkuNamePrice(db)
|
|
||||||
// CreateOrUpdateStoreSkuNamePriceByExcel(db, ctx, storeSkuNamePriceList, storeSkuNamePriceListOrg)
|
|
||||||
// storeSkuNamePriceListNew, _ := dao.GetStoreSkuNamePrice(db)
|
|
||||||
// storeSkuNamePriceMapNew := StoreSkuNamePriceList2Map(ctx, storeSkuNamePriceListNew)
|
|
||||||
// for _, v := range storeSkuNamePriceList {
|
|
||||||
// if storeSkuNamePriceMapNew[v.OutSkuID] != nil {
|
|
||||||
// storeSkuNamePriceListUpdate = append(storeSkuNamePriceListUpdate, storeSkuNamePriceMapNew[v.OutSkuID])
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
|
||||||
// storeSkuNamePrice := batchItemList[0].(*model.StoreSkuNamePrice)
|
|
||||||
// var skuBindInfos []*StoreSkuBindInfo
|
|
||||||
// nameIDGroup := strings.Split(storeSkuNamePrice.NameIDGroup, ",")
|
|
||||||
// for _, v := range nameIDGroup {
|
|
||||||
// if v != "" {
|
|
||||||
// nameID := int(utils.Str2Int64(v))
|
|
||||||
// for _, vv := range storeIDs {
|
|
||||||
// skuList, err2 := dao.GetStoreSkusByNameIDs(db, []int{vv}, nameID)
|
|
||||||
// err = err2
|
|
||||||
// if len(skuList) > 0 {
|
|
||||||
// unitPrice := 0
|
|
||||||
// if skuList[0].Unit == model.UnitNames[0] {
|
|
||||||
// if storeSkuNamePrice.Unit == "KG" {
|
|
||||||
// unitPrice = storeSkuNamePrice.Price / 2
|
|
||||||
// } else {
|
|
||||||
// unitPrice = storeSkuNamePrice.Price
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// unitPrice = storeSkuNamePrice.Price
|
|
||||||
// }
|
|
||||||
// storeSkuBindInfo := &StoreSkuBindInfo{
|
|
||||||
// NameID: nameID,
|
|
||||||
// UnitPrice: unitPrice,
|
|
||||||
// }
|
|
||||||
// skuBindInfos = append(skuBindInfos, storeSkuBindInfo)
|
|
||||||
// outSuccess := DataSuccess{
|
|
||||||
// NameID: nameID,
|
|
||||||
// Name: skuList[0].Name,
|
|
||||||
// Unit: storeSkuNamePrice.Unit,
|
|
||||||
// OrgPrice: utils.Str2Float64(utils.Int64ToStr(skuList[0].UnitPrice)) / 100,
|
|
||||||
// NowPrice: utils.Str2Float64(utils.Int64ToStr(int64(unitPrice))) / 100,
|
|
||||||
// MixPrice: utils.Str2Float64(utils.Int64ToStr(int64(unitPrice)-skuList[0].UnitPrice)) / 100,
|
|
||||||
// }
|
|
||||||
// dataLock.AppendDataSuccess(outSuccess)
|
|
||||||
// } else {
|
|
||||||
// //京西xx门店没有关注该商品
|
|
||||||
// outFailed := DataFailed{
|
|
||||||
// NameID: nameID,
|
|
||||||
// Name: storeSkuNamePrice.Name,
|
|
||||||
// Comment: fmt.Sprintf("京西[%v]门店没有关注该商品,商品nameID[%v],Excel上商品名[%v]", vv, nameID, storeSkuNamePrice.Name),
|
|
||||||
// }
|
|
||||||
// dataLock.AppendDataFailed(outFailed)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// //nameID为空,还未填写nameID
|
|
||||||
// outFailed := DataFailed{
|
|
||||||
// NameID: 0,
|
|
||||||
// Name: storeSkuNamePrice.Name,
|
|
||||||
// Comment: fmt.Sprintf("商品nameID为空!,还未填写商品nameID,Excel上商品名[%v]", storeSkuNamePrice.Name),
|
|
||||||
// }
|
|
||||||
// dataLock.AppendDataFailed(outFailed)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// retVal = skuBindInfos
|
|
||||||
// return retVal, err
|
|
||||||
// }
|
|
||||||
// taskParallel := tasksch.NewParallelTask("刷新京西价", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, taskFunc, storeSkuNamePriceListUpdate)
|
|
||||||
// tasksch.HandleTask(taskParallel, task, true).Run()
|
|
||||||
// skuBindInfosInter, err = taskParallel.GetResult(0)
|
|
||||||
// case 2:
|
|
||||||
// //更新京西价
|
|
||||||
// for _, v := range skuBindInfosInter {
|
|
||||||
// skuBindInfoList = append(skuBindInfoList, v.(*StoreSkuBindInfo))
|
|
||||||
// }
|
|
||||||
// if isErr {
|
|
||||||
// UpdateStoresSkus(ctx, 0, storeIDs, skuBindInfoList, false, false, isAsync, isContinueWhenError)
|
|
||||||
// }
|
|
||||||
// case 3:
|
|
||||||
// //写Excel
|
|
||||||
// WriteToExcelJx(task, dataLock.dataSuccessList, dataLock.dataFailedList)
|
|
||||||
// }
|
|
||||||
// return result, err
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
467
business/jxstore/cms/print.go
Normal file
467
business/jxstore/cms/print.go
Normal file
@@ -0,0 +1,467 @@
|
|||||||
|
package cms
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/dao"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
"net"
|
||||||
|
"regexp"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
sounda = "sounda" //提示音a
|
||||||
|
soundb = "soundb" //提示音b
|
||||||
|
soundc = "soundc" //提示音c
|
||||||
|
soundd = "soundd" //提示音d
|
||||||
|
sounde = "sounde" //报警音e
|
||||||
|
soundf = "soundf" //报警音f
|
||||||
|
soundg = "soundg" //报警音g
|
||||||
|
)
|
||||||
|
|
||||||
|
type PrintInfo struct {
|
||||||
|
PrintNo string
|
||||||
|
AppID int
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
regexpMobile = regexp.MustCompile("^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\\d{8}$")
|
||||||
|
soundMap = map[string]string{
|
||||||
|
"sounda": "sounda",
|
||||||
|
"soundb": "soundb",
|
||||||
|
"soundc": "soundc",
|
||||||
|
"soundd": "soundd",
|
||||||
|
"sounde": "sounde",
|
||||||
|
"soundf": "soundf",
|
||||||
|
"soundg": "soundg",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func AddPrinter(appID int, printers []*model.AddPrinterParam) (err error) {
|
||||||
|
var (
|
||||||
|
db = dao.GetDB()
|
||||||
|
errs []error
|
||||||
|
)
|
||||||
|
if len(printers) > 50 {
|
||||||
|
return fmt.Errorf("一次最多只能绑定50台!")
|
||||||
|
}
|
||||||
|
for _, v := range printers {
|
||||||
|
if printers2, _ := dao.GetPrinters(db, appID, v.PrintNo, 0, 0); len(printers2) > 0 {
|
||||||
|
// 代表打印机已经在小程序注册了,查询打印机授权门店
|
||||||
|
bindStoreList, err := dao.QueryPrintBindStore(v.PrintNo)
|
||||||
|
if err != nil {
|
||||||
|
errs = append(errs, fmt.Errorf("QueryPrintBindStore err : %v ", err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if len(bindStoreList) >= 5 {
|
||||||
|
errs = append(errs, fmt.Errorf("当前打印机绑定门店数据超过五个,无法继续绑定"))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
have := false
|
||||||
|
userId := ""
|
||||||
|
for _, bsl := range bindStoreList {
|
||||||
|
if bsl.StoreID == v.StoreId {
|
||||||
|
have = true
|
||||||
|
userId = bsl.UserId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !have {
|
||||||
|
if err := dao.BindStoreList(printers[0], userId); err != nil {
|
||||||
|
errs = append(errs, fmt.Errorf("BindStoreList err : %v ", err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
//验证
|
||||||
|
if err = checkPrinterInfo(v.PrintNo, v.Name, "", "", 0); err != nil {
|
||||||
|
errs = append(errs, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// 检查心跳
|
||||||
|
exits, err := dao.CheckHeard(v.PrintNo)
|
||||||
|
if err != nil {
|
||||||
|
errs = append(errs, fmt.Errorf("CheckHeard err : %v ", err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !exits {
|
||||||
|
errs = append(errs, fmt.Errorf("打印机未激活,请激活后在绑定"))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
printer := &model.Printer{
|
||||||
|
AppID: appID,
|
||||||
|
PrintNo: v.PrintNo,
|
||||||
|
Name: v.Name,
|
||||||
|
IccID: "",
|
||||||
|
Status: model.PrinterStatusOffline,
|
||||||
|
Sound: "sounda",
|
||||||
|
PrintKey: v.SIM,
|
||||||
|
IsOnline: 0,
|
||||||
|
Volume: 1,
|
||||||
|
FlowFlag: 0,
|
||||||
|
OfflineCount: 0,
|
||||||
|
UserId: "system_user",
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建打印机
|
||||||
|
if err := InitPrint(printer, v); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(errs) > 0 {
|
||||||
|
err = jxutils.BuildErr(errs)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func InitPrint(printer *model.Printer, printParam *model.AddPrinterParam) error {
|
||||||
|
txDb, _ := dao.Begin(dao.GetDB())
|
||||||
|
// 创建打印机
|
||||||
|
dao.WrapAddIDCULDEntity(printer, "")
|
||||||
|
if err := dao.CreateEntityTx(txDb, printer); err != nil {
|
||||||
|
txDb.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 赋予打印机默认配置
|
||||||
|
day := time.Now()
|
||||||
|
param, err := MarshalJson2String(&model.PrintSetting{
|
||||||
|
CreatedAt: day,
|
||||||
|
UpdatedAt: day,
|
||||||
|
DeletedAt: utils.DefaultTimeValue,
|
||||||
|
PrintNo: printer.PrintNo,
|
||||||
|
CallNameSetting: 64, // 老板
|
||||||
|
BusinessOffLineVoice: 1, // 离线开关
|
||||||
|
BalanceNotEnoughVoice: 1, // 余额不足
|
||||||
|
EveryDayGreetVoice: 1, // 问好
|
||||||
|
BusinessPrintNum: 1, // 商户侧打印次数
|
||||||
|
CustomerPrintNum: 1, // 用户侧打印次数
|
||||||
|
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := dao.CreateEntityTx(txDb, param); err != nil {
|
||||||
|
txDb.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化打印机账户
|
||||||
|
if err := dao.CreateEntityTx(txDb, &model.PrintBill{
|
||||||
|
CreatedAt: time.Now(),
|
||||||
|
UpdatedAt: time.Now(),
|
||||||
|
PrintNo: param.PrintNo,
|
||||||
|
PrintBalance: 20000,
|
||||||
|
UserId: "system",
|
||||||
|
}); err != nil {
|
||||||
|
txDb.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化绑定信息
|
||||||
|
if err := dao.BindStoreList(printParam, ""); err != nil {
|
||||||
|
txDb.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer txDb.Commit()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJson2String 工具类
|
||||||
|
func MarshalJson2String(param *model.PrintSetting) (*model.PrintSetting, error) {
|
||||||
|
// 语音设置
|
||||||
|
voiceSetting := &model.VoiceSettingDetail{
|
||||||
|
WaitOrderVoice: model.SettingOpen,
|
||||||
|
RiderTakeOrderVoice: model.SettingOpen,
|
||||||
|
ApplyUserOrderCancelVoice: model.SettingOpen,
|
||||||
|
ApplyRefundOrderVoice: model.SettingOpen,
|
||||||
|
ApplyRefundGoodsVoice: model.SettingOpen,
|
||||||
|
RefundGoodsVoice: model.SettingOpen,
|
||||||
|
ConfirmGoodsVoice: model.SettingOpen,
|
||||||
|
SuccessGoodsVoice: model.SettingOpen,
|
||||||
|
ConsultingPrint: model.SettingOpen,
|
||||||
|
ReminderVoice: model.SettingOpen,
|
||||||
|
CustomerRejectionVoice: model.SettingOpen,
|
||||||
|
CusterRefundVoice: model.SettingOpen,
|
||||||
|
LoseAuthorization: model.SettingOpen,
|
||||||
|
}
|
||||||
|
customerVoiceSettingByte, err := json.Marshal(voiceSetting)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
param.VoiceSetting = string(customerVoiceSettingByte)
|
||||||
|
|
||||||
|
// 打印设置
|
||||||
|
printSetting := &model.PrintSettingDetail{
|
||||||
|
UserOrderCancel: model.SettingOpen,
|
||||||
|
RefundOrder: model.SettingOpen,
|
||||||
|
BusinessOrderCancel: model.SettingOpen,
|
||||||
|
RiderTakeOrder: model.SettingOpen,
|
||||||
|
CusterRefundPrint: model.SettingOpen,
|
||||||
|
WaitOrderPrint: model.SettingOpen,
|
||||||
|
ApplyUserCancelOrder: model.SettingOpen,
|
||||||
|
ApplyUserRefund: model.SettingOpen,
|
||||||
|
OrderCancelSuccess: model.SettingOpen,
|
||||||
|
}
|
||||||
|
pickingSettingByte, err := json.Marshal(printSetting)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
param.PrintSetting = string(pickingSettingByte)
|
||||||
|
return param, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkPrinterInfo(printNo, name, sound, sim string, volume int) (err error) {
|
||||||
|
if printNo != "" {
|
||||||
|
|
||||||
|
}
|
||||||
|
if sim != "" {
|
||||||
|
//if regexpMobile.FindString(sim) == "" {
|
||||||
|
return fmt.Errorf("暂不支持修改sim卡号码!print_no : %v ", printNo)
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
if volume != 0 {
|
||||||
|
if volume <= 0 || volume > 5 {
|
||||||
|
return fmt.Errorf("请输入正确的音量1-5!print_no : %v ", printNo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if sound != "" {
|
||||||
|
if soundMap[sound] == "" {
|
||||||
|
return fmt.Errorf("请输入正确的提示音!print_no : %v ", printNo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if name != "" {
|
||||||
|
if len(name) > 255 {
|
||||||
|
return fmt.Errorf("打印机备注不能超过255个字符!print_no : %v ", printNo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func DelPrinter(appID int, printNos []string, storeId string) (err error) {
|
||||||
|
var (
|
||||||
|
db = dao.GetDB()
|
||||||
|
errs []error
|
||||||
|
)
|
||||||
|
for _, v := range printNos {
|
||||||
|
if printers, _ := dao.GetPrinters(db, appID, v, 0, 0); len(printers) == 0 {
|
||||||
|
errs = append(errs, fmt.Errorf("该应用下未找到该打印机!print_no : %v ", v))
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
if err := dao.DeleteStoreList(printers[0].PrintNo, storeId); err != nil {
|
||||||
|
errs = append(errs, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(errs) > 0 {
|
||||||
|
err = jxutils.BuildErr(errs)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdatePrinter(appID int, printNo string, name, sim, sound *string, volume *int) (err error) {
|
||||||
|
var (
|
||||||
|
db = dao.GetDB()
|
||||||
|
fields []string
|
||||||
|
)
|
||||||
|
//看有没有
|
||||||
|
if printers, _ := dao.GetPrinters(db, appID, printNo, 0, 0); len(printers) == 0 {
|
||||||
|
return fmt.Errorf("该应用下未找到该打印机!print_no : %v", printNo)
|
||||||
|
} else {
|
||||||
|
if name != nil {
|
||||||
|
if *name != "" {
|
||||||
|
if len(*name) > 20 {
|
||||||
|
return fmt.Errorf("打印机备注不能超过20个字符!print_no : %v ", printNo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if printers[0].Name != *name {
|
||||||
|
printers[0].Name = *name
|
||||||
|
fields = append(fields, "name")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if sim != nil {
|
||||||
|
if *sim != "" {
|
||||||
|
//if regexpMobile.FindString(*sim) == "" {
|
||||||
|
return fmt.Errorf("暂不支持修改sim卡号码!print_no : %v ", printNo)
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
//if printers[0].SIM != *sim {
|
||||||
|
// printers[0].SIM = *sim
|
||||||
|
// fields = append(fields, "sim")
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
if sound != nil {
|
||||||
|
if *sound != "" {
|
||||||
|
if soundMap[*sound] == "" {
|
||||||
|
return fmt.Errorf("请输入正确的提示音!print_no : %v ", printNo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if printers[0].Sound != *sound {
|
||||||
|
printers[0].Sound = *sound
|
||||||
|
fields = append(fields, "sound")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if volume != nil {
|
||||||
|
if *volume <= 0 || *volume > 5 {
|
||||||
|
return fmt.Errorf("请输入正确的音量 1-5!print_no : %v ", printNo)
|
||||||
|
}
|
||||||
|
if printers[0].Volume != *volume {
|
||||||
|
printers[0].Volume = *volume
|
||||||
|
fields = append(fields, "volume")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, err = dao.UpdateEntity(db, printers[0], fields...); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func DelPrinterSeq(appID int, printNo string) (err error) {
|
||||||
|
var (
|
||||||
|
db = dao.GetDB()
|
||||||
|
)
|
||||||
|
//看有没有
|
||||||
|
if printers, _ := dao.GetPrinters(db, appID, printNo, 0, 0); len(printers) == 0 {
|
||||||
|
return fmt.Errorf("该应用下未找到该打印机!print_no : %v", printNo)
|
||||||
|
} else {
|
||||||
|
printMsgs, _ := dao.GetPrintMsgs(db, printNo, "", model.PrintMsgAll, model.PrintMsgSuccess)
|
||||||
|
for _, v := range printMsgs {
|
||||||
|
v.DeletedAt = time.Now()
|
||||||
|
if _, err = dao.UpdateEntity(db, v, "DeletedAt"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 简历连接
|
||||||
|
conn, err := net.Dial("tcp", "www.jxcs.net:8000")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
clearPrint := fmt.Sprintf(`{"print_no_clear":%s}`, printNo)
|
||||||
|
// 发送数据
|
||||||
|
if _, err := conn.Write([]byte(clearPrint)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// 等待数据
|
||||||
|
buf := make([]byte, 1024)
|
||||||
|
n, err := conn.Read(buf)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if string(buf[:n]) != "ok" {
|
||||||
|
return errors.New("缓存清理失败")
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func DoPrintMsg(appID int, msgID, printNo, content string, orderNo string) (err error) {
|
||||||
|
var (
|
||||||
|
db = dao.GetDB()
|
||||||
|
)
|
||||||
|
//打印机必须绑定在该应用下才能打印
|
||||||
|
if printers, _ := dao.GetPrinters(db, appID, printNo, 0, 0); len(printers) == 0 {
|
||||||
|
return fmt.Errorf("未在该应用下获取到此打印机!print_no %v", printNo)
|
||||||
|
}
|
||||||
|
printMsg := &model.PrintMsg{
|
||||||
|
PrintNo: printNo,
|
||||||
|
Content: content,
|
||||||
|
OrderNo: orderNo,
|
||||||
|
MsgID: msgID,
|
||||||
|
}
|
||||||
|
dao.WrapAddIDCULDEntity(printMsg, "")
|
||||||
|
if err = dao.CreateEntity(db, printMsg); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetPrintMsgResult struct {
|
||||||
|
MsgID string `json:"msg_id"` //消息ID
|
||||||
|
PrintNo string `json:"print_no"` //打印机编号
|
||||||
|
OrderNo string `json:"order_no"` //订单序号
|
||||||
|
Content string `json:"content"` //订单内容
|
||||||
|
Status int `json:"status"` //打印状态
|
||||||
|
Comment string `json:"comment"` //失败原因
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPrintMsg(appID int, msgID string) (printMsg *GetPrintMsgResult, err error) {
|
||||||
|
var (
|
||||||
|
db = dao.GetDB()
|
||||||
|
)
|
||||||
|
if printMsgs, _ := dao.GetPrintMsgs(db, "", msgID, model.PrintMsgAll, model.PrintMsgAll); len(printMsgs) > 0 {
|
||||||
|
result := printMsgs[0]
|
||||||
|
printMsg = &GetPrintMsgResult{
|
||||||
|
MsgID: result.MsgID,
|
||||||
|
PrintNo: result.PrintNo,
|
||||||
|
OrderNo: result.OrderNo,
|
||||||
|
Content: result.Content,
|
||||||
|
Status: result.Status,
|
||||||
|
Comment: result.Comment,
|
||||||
|
}
|
||||||
|
return printMsg, err
|
||||||
|
} else {
|
||||||
|
return printMsg, fmt.Errorf("未找到该消息!msg_id :%v", msgID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPrinterStatus(appID int, printNo string) (status int, err error) {
|
||||||
|
var (
|
||||||
|
db = dao.GetDB()
|
||||||
|
)
|
||||||
|
//看有没有
|
||||||
|
if printers, _ := dao.GetPrinters(db, appID, printNo, 0, 0); len(printers) == 0 {
|
||||||
|
return status, fmt.Errorf("该应用下未找到该打印机!print_no : %v", printNo)
|
||||||
|
} else {
|
||||||
|
return printers[0].Status + printers[0].IsOnline, nil // 当两个值都唯一时->在线正常
|
||||||
|
server := "print.jxcs.net:8000"
|
||||||
|
tcpAddr, err := net.ResolveTCPAddr("tcp4", server)
|
||||||
|
if err != nil {
|
||||||
|
//os.Exit(1)
|
||||||
|
return status, err
|
||||||
|
}
|
||||||
|
conn, err := net.DialTCP("tcp", nil, tcpAddr)
|
||||||
|
if err != nil {
|
||||||
|
return status, err
|
||||||
|
}
|
||||||
|
status = connHandler(conn, &PrintInfo{
|
||||||
|
PrintNo: printNo,
|
||||||
|
AppID: appID,
|
||||||
|
})
|
||||||
|
return status, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func connHandler(c net.Conn, printInfo *PrintInfo) (status int) {
|
||||||
|
defer c.Close()
|
||||||
|
//缓冲
|
||||||
|
buf := make([]byte, 1024)
|
||||||
|
data, _ := json.Marshal(printInfo)
|
||||||
|
//写入数据
|
||||||
|
c.Write(data)
|
||||||
|
//服务器端返回的数据写入buf
|
||||||
|
n, _ := c.Read(buf)
|
||||||
|
status = utils.Str2Int(string(buf[:n]))
|
||||||
|
//服务器端回传的信息
|
||||||
|
fmt.Println("server response:", string(buf[:n]))
|
||||||
|
return status
|
||||||
|
}
|
||||||
|
|
||||||
|
//#region 打印机拼装模板
|
||||||
|
|
||||||
|
// QueryPrinterSetting 查询用户设置
|
||||||
|
func QueryPrinterSetting() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//#endregion 打印机
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,216 +0,0 @@
|
|||||||
package cms
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/smsmsg"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
|
||||||
)
|
|
||||||
|
|
||||||
type StoreAcctManager struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
FixedStoreAcctManager *StoreAcctManager
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
FixedStoreAcctManager = &StoreAcctManager{}
|
|
||||||
partner.InitStoreAcctManager(FixedStoreAcctManager)
|
|
||||||
}
|
|
||||||
|
|
||||||
func InsertStoreAcctIncome(ctx *jxcontext.Context, storeID, price, acctType int, vendorOrderID, vendorWaybillId string, expendID int) (err error) {
|
|
||||||
var (
|
|
||||||
userID, userName string
|
|
||||||
goodsVendorOrderID string
|
|
||||||
db = dao.GetDB()
|
|
||||||
)
|
|
||||||
if ctx != nil {
|
|
||||||
userID = ctx.GetUserID()
|
|
||||||
userName = ctx.GetUserName()
|
|
||||||
goodsVendorOrderID = vendorOrderID
|
|
||||||
} else {
|
|
||||||
storeOrder := &model.StoreAcctOrder{
|
|
||||||
VendorOrderID: vendorOrderID,
|
|
||||||
}
|
|
||||||
if err = dao.GetEntity(db, storeOrder, "VendorOrderID"); err == nil && storeOrder.ID != 0 {
|
|
||||||
userID = storeOrder.UserID
|
|
||||||
userName = storeOrder.LastOperator
|
|
||||||
goodsVendorOrderID = storeOrder.GoodsVendorOrderID
|
|
||||||
}
|
|
||||||
}
|
|
||||||
storeAcctIncome := &model.StoreAcctIncome{
|
|
||||||
StoreID: storeID,
|
|
||||||
IncomePrice: price,
|
|
||||||
Type: acctType,
|
|
||||||
UserID: userID,
|
|
||||||
VendorOrderID: goodsVendorOrderID,
|
|
||||||
VendorWaybillID: vendorWaybillId,
|
|
||||||
}
|
|
||||||
dao.WrapAddIDCULEntity(storeAcctIncome, userName)
|
|
||||||
if expendID != 0 {
|
|
||||||
storeAcctIncome.ExpID = expendID
|
|
||||||
}
|
|
||||||
err = dao.CreateEntity(db, storeAcctIncome)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func InsertStoreAcctExpend(ctx *jxcontext.Context, storeID, price, acctType int, vendorOrderID, vendorWaybillId string, expendID int) (err error) {
|
|
||||||
var (
|
|
||||||
userID, userName string
|
|
||||||
db = dao.GetDB()
|
|
||||||
)
|
|
||||||
if ctx != nil {
|
|
||||||
userID = ctx.GetUserID()
|
|
||||||
userName = ctx.GetUserName()
|
|
||||||
} else {
|
|
||||||
storeOrder := &model.StoreAcctOrder{
|
|
||||||
VendorOrderID: vendorOrderID,
|
|
||||||
}
|
|
||||||
if err = dao.GetEntity(db, storeOrder, "VendorOrderID"); err == nil && storeOrder.ID != 0 {
|
|
||||||
userID = storeOrder.UserID
|
|
||||||
userName = storeOrder.LastOperator
|
|
||||||
}
|
|
||||||
}
|
|
||||||
storeAcctExpend := &model.StoreAcctExpend{
|
|
||||||
StoreID: storeID,
|
|
||||||
ExpendPrice: price,
|
|
||||||
Type: acctType,
|
|
||||||
UserID: userID,
|
|
||||||
VendorOrderID: vendorOrderID,
|
|
||||||
VendorWaybillID: vendorWaybillId,
|
|
||||||
}
|
|
||||||
dao.WrapAddIDCULEntity(storeAcctExpend, userName)
|
|
||||||
if expendID != 0 {
|
|
||||||
storeAcctExpend.ExpID = expendID
|
|
||||||
}
|
|
||||||
err = dao.CreateEntity(db, storeAcctExpend)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *StoreAcctManager) UpdateStoreAcctBalance(ctx *jxcontext.Context, storeID, price int, isIncome bool) (err error) {
|
|
||||||
var (
|
|
||||||
db = dao.GetDB()
|
|
||||||
)
|
|
||||||
if ctx == nil {
|
|
||||||
ctx = jxcontext.AdminCtx
|
|
||||||
}
|
|
||||||
storeAcct := &model.StoreAcct{
|
|
||||||
StoreID: storeID,
|
|
||||||
}
|
|
||||||
txDB, _ := dao.Begin(db)
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil || err != nil {
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
if r != nil {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
if err = dao.GetEntity(db, storeAcct, "StoreID"); err != nil && dao.IsNoRowsError(err) {
|
|
||||||
//新增门店账单
|
|
||||||
dao.WrapAddIDCULEntity(storeAcct, ctx.GetUserName())
|
|
||||||
if err = dao.CreateEntityTx(txDB, storeAcct); err != nil {
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if isIncome {
|
|
||||||
storeAcct.AccountBalance += price
|
|
||||||
} else {
|
|
||||||
storeAcct.AccountBalance -= price
|
|
||||||
}
|
|
||||||
if _, err = dao.UpdateEntityTx(txDB, storeAcct, "AccountBalance"); err != nil {
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dao.Commit(db, txDB)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 门店到账(老版本,修改门店的交易记录)
|
|
||||||
func (s *StoreAcctManager) InsertStoreAcctExpendAndUpdateStoreAcctBalance(ctx *jxcontext.Context, storeID, price, acctType int, vendorOrderID, vendorWaybillID string, expendID int) (err error) {
|
|
||||||
utils.CallFuncAsync(func() {
|
|
||||||
if err = InsertStoreAcctExpend(ctx, storeID, price, acctType, vendorOrderID, vendorWaybillID, expendID); err == nil {
|
|
||||||
s.UpdateStoreAcctBalance(ctx, storeID, price, false)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *StoreAcctManager) InsertStoreAcctIncomeAndUpdateStoreAcctBalance(ctx *jxcontext.Context, storeID, price, acctType int, vendorOrderID, vendorWaybillID string, expendID int) (err error) {
|
|
||||||
utils.CallFuncAsync(func() {
|
|
||||||
if err = InsertStoreAcctIncome(ctx, storeID, price, acctType, vendorOrderID, vendorWaybillID, expendID); err == nil {
|
|
||||||
s.UpdateStoreAcctBalance(ctx, storeID, price, true)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查当前订单的状态以及支出收入比
|
|
||||||
func (s *StoreAcctManager) CheckStoreAcctExpendExist(vendorOrderID string) (isEqual, isZero bool, err error) {
|
|
||||||
var (
|
|
||||||
expends, incomes int
|
|
||||||
db = dao.GetDB()
|
|
||||||
)
|
|
||||||
// 当前订单的支出金额(临时运费+真实运费)[小费] partner.StoreAcctTypeExpendCreateWaybillDeductFee 违约金不参与计算,本来就要扣除
|
|
||||||
expends, err = dao.GetStoreAcctExpendTotal(db, 0, []int{partner.StoreAcctTypeExpendCreateWaybillEx, partner.StoreAcctTypeExpendCreateWaybillTip, partner.StoreAcctTypeExpendCreateWaybill2ndMore, partner.StoreAcctTypeRealFeeExpend}, vendorOrderID, utils.ZeroTimeValue, utils.ZeroTimeValue)
|
|
||||||
// 当前订单的退费金额()
|
|
||||||
incomes, err = dao.GetStoreAcctIncomeTotal(db, 0, []int{partner.StoreAcctTypeRealFeeIncome, partner.StoreAcctTypeIncomeCancelTemp, partner.StoreAcctTypeIncomeCancelReal}, vendorOrderID, utils.ZeroTimeValue, utils.ZeroTimeValue)
|
|
||||||
if expends != incomes {
|
|
||||||
if expends > incomes {
|
|
||||||
return false, false, err
|
|
||||||
} else {
|
|
||||||
globals.SugarLogger.Debugf("CheckStoreAcctExpendExist 收入大于支出! orderID:[%v]", vendorOrderID)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if expends == 0 && incomes == 0 {
|
|
||||||
return true, true, err
|
|
||||||
} else {
|
|
||||||
return true, false, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false, false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *StoreAcctManager) GetStoreAcctExpendLastCreateWayBillFee(vendorOrderID string) (expend *dao.GetStoreAcctExpendLastCreateWayBillFeeResult, lastFee int, err error) {
|
|
||||||
return dao.GetStoreAcctExpendLastCreateWayBillFee(dao.GetDB(), vendorOrderID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *StoreAcctManager) GetBrandBalance(brandID int) (balance int, err error) {
|
|
||||||
return dao.GetBrandBalance(dao.GetDB(), brandID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *StoreAcctManager) InsertBrandBill(ctx *jxcontext.Context, brandID, price, billType, feeType int, vendorOrderID string, wayVendorOrderId string) (err error) {
|
|
||||||
utils.CallFuncAsync(func() {
|
|
||||||
var (
|
|
||||||
db = dao.GetDB()
|
|
||||||
)
|
|
||||||
if price == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
brandBill := &model.BrandBill{
|
|
||||||
BrandID: brandID,
|
|
||||||
Price: price,
|
|
||||||
BillType: billType,
|
|
||||||
FeeType: feeType,
|
|
||||||
VendorOrderID: vendorOrderID,
|
|
||||||
OrderID: wayVendorOrderId,
|
|
||||||
}
|
|
||||||
dao.WrapAddIDCULEntity(brandBill, ctx.GetUserName())
|
|
||||||
//扣除后,如果余额小于10元要发消息通知 ,每天通知一次
|
|
||||||
if err = dao.CreateEntity(db, brandBill); err == nil {
|
|
||||||
if mark := api.Cacher.Get("brandID" + utils.Int2Str(brandID)); mark == nil {
|
|
||||||
if balance, _ := s.GetBrandBalance(brandID); balance < model.BrandBalanceLimit {
|
|
||||||
smsmsg.NotifyBrandBalance(brandID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
package cms
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 更新门店负责人信息
|
|
||||||
func UpdateStoreOperatorConfig() {
|
|
||||||
db := dao.GetDB()
|
|
||||||
store, err := dao.GetStoreList(db, nil, nil, []int{-1, 0, 1}, nil, nil, "")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
userData := make(map[string][][]interface{}, 0)
|
|
||||||
jx := make(map[string]string, 0)
|
|
||||||
jd := make(map[string]string, 0)
|
|
||||||
mt := make(map[string]string, 0)
|
|
||||||
eb := make(map[string]string, 0)
|
|
||||||
for _, v := range store {
|
|
||||||
storeDetail, err := dao.GetStoreDetail(dao.GetDB(), v.ID, 0, "")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if storeDetail.MarketManPhone != "" { // 平台负责人jx
|
|
||||||
jx[storeDetail.MarketManName] = storeDetail.MarketManPhone
|
|
||||||
}
|
|
||||||
if storeDetail.OperatorPhone != "" { // 京东负责人电话
|
|
||||||
jd[storeDetail.OperatorName] = storeDetail.OperatorPhone
|
|
||||||
}
|
|
||||||
if storeDetail.OperatorPhone2 != "" { // 美团负责人电话
|
|
||||||
mt[storeDetail.OperatorName2] = storeDetail.OperatorPhone2
|
|
||||||
}
|
|
||||||
if storeDetail.OperatorPhone3 != "" { // 饿了么负责人电话
|
|
||||||
eb[storeDetail.OperatorName3] = storeDetail.OperatorPhone3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
userData["jx"] = Map2Slice(jx)
|
|
||||||
userData["jd"] = Map2Slice(jd)
|
|
||||||
userData["mt"] = Map2Slice(mt)
|
|
||||||
userData["eb"] = Map2Slice(eb)
|
|
||||||
// 写入配置
|
|
||||||
byteData, err := json.Marshal(userData)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := dao.UpdateOperatorConfig(string(byteData), "Sys", "FZR"); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func Map2Slice(param map[string]string) [][]interface{} {
|
|
||||||
if len(param) <= 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
result := make([][]interface{}, 0, 0)
|
|
||||||
for k, v := range param {
|
|
||||||
phone, _ := strconv.Atoi(v)
|
|
||||||
result = append(result, []interface{}{k, phone})
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,163 +0,0 @@
|
|||||||
package cms
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
func TestGetStoresVendorSnapshot(t *testing.T) {
|
|
||||||
result, err := GetStoresVendorSnapshot(jxcontext.AdminCtx, nil, []int{model.VendorIDEBAI}, nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
t.Log(utils.Format4Output(result, false))
|
|
||||||
t.Log(len(result))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSendAlarmVendorSnapshot(t *testing.T) {
|
|
||||||
db := dao.GetDB()
|
|
||||||
prevSnapshotList, _ := dao.GetVendorStoreSnapshot(db, utils.Str2Time("2019-09-19 11:00:00"))
|
|
||||||
curSnapshotList, _ := dao.GetVendorStoreSnapshot(db, utils.Str2Time("2019-09-19 15:00:00"))
|
|
||||||
err := SendAlarmVendorSnapshot(jxcontext.AdminCtx, nil, prevSnapshotList, curSnapshotList)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUpdateVendorStoreStatusBySnapshot(t *testing.T) {
|
|
||||||
db := dao.GetDB()
|
|
||||||
curSnapshotList, _ := dao.GetVendorStoreSnapshot(db, utils.Str2Time("2019-07-30 08:00:00"))
|
|
||||||
updateVendorStoreStatusBySnapshot(db, curSnapshotList)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
func TestGetBrands(t *testing.T) {
|
|
||||||
var test bool = false
|
|
||||||
if test {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
func TestAbs(t *testing.T) {
|
|
||||||
got := 1
|
|
||||||
if got != 1 {
|
|
||||||
t.Errorf("Abs(-1) = %d; want 1", got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetBrands1(t *testing.T) {
|
|
||||||
type args struct {
|
|
||||||
ctx *jxcontext.Context
|
|
||||||
name string
|
|
||||||
brandID int
|
|
||||||
isManage bool
|
|
||||||
}
|
|
||||||
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
wantGetBrandsResult []*GetBrandsResult
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
// TODO: Add test cases.
|
|
||||||
|
|
||||||
}
|
|
||||||
var test bool = false
|
|
||||||
if test {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
gotGetBrandsResult, err := GetBrands(tt.args.ctx, tt.args.name, tt.args.brandID, tt.args.isManage)
|
|
||||||
if (err != nil) != tt.wantErr {
|
|
||||||
t.Errorf("GetBrands() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(gotGetBrandsResult, tt.wantGetBrandsResult) {
|
|
||||||
t.Errorf("GetBrands() gotGetBrandsResult = %v, want %v", gotGetBrandsResult, tt.wantGetBrandsResult)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestQueryPageStores2(t *testing.T) {
|
|
||||||
type args struct {
|
|
||||||
db *dao.DaoDB
|
|
||||||
pageSize int
|
|
||||||
offset int
|
|
||||||
keyword string
|
|
||||||
vendorStoreID string
|
|
||||||
brandName string
|
|
||||||
vendorID int
|
|
||||||
cityCode int
|
|
||||||
districtCode int
|
|
||||||
tel string
|
|
||||||
minShopScore float32
|
|
||||||
minRecentOrderNum int
|
|
||||||
minSkuCount int
|
|
||||||
lng1 float64
|
|
||||||
lat1 float64
|
|
||||||
lng2 float64
|
|
||||||
lat2 float64
|
|
||||||
cat string
|
|
||||||
}
|
|
||||||
dbt := dao.GetDB()
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
wantPagedInfo *model.PagedInfo
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
// TODO: Add test cases.
|
|
||||||
{
|
|
||||||
"测试1",
|
|
||||||
args{
|
|
||||||
dbt,
|
|
||||||
15,
|
|
||||||
0,
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
"", //缺
|
|
||||||
-1,
|
|
||||||
510000,
|
|
||||||
0, //缺
|
|
||||||
"",
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
104.066301,
|
|
||||||
30.572961,
|
|
||||||
104.066301,
|
|
||||||
30.572961,
|
|
||||||
"",
|
|
||||||
},
|
|
||||||
nil,
|
|
||||||
true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
gotPagedInfo, err := QueryPageStores2(tt.args.db, tt.args.pageSize, tt.args.offset, tt.args.keyword, tt.args.vendorStoreID, tt.args.brandName, tt.args.vendorID, tt.args.cityCode, tt.args.districtCode, tt.args.tel, tt.args.minShopScore, tt.args.minRecentOrderNum, tt.args.minSkuCount, tt.args.lng1, tt.args.lat1, tt.args.lng2, tt.args.lat2, tt.args.cat)
|
|
||||||
if (err != nil) != tt.wantErr {
|
|
||||||
t.Errorf("QueryPageStores2() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(gotPagedInfo, tt.wantPagedInfo) {
|
|
||||||
t.Errorf("QueryPageStores2() gotPagedInfo = %v, want %v", gotPagedInfo, tt.wantPagedInfo)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUpdate(t *testing.T) {
|
|
||||||
UpdateStoreOperatorConfig()
|
|
||||||
}
|
|
||||||
func TestUpdateStorePoiStatus(t *testing.T) {
|
|
||||||
var ctx *jxcontext.Context
|
|
||||||
err := UpdateStorePoiStatus(ctx)
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
@@ -1,135 +0,0 @@
|
|||||||
package cms
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/netprinter"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
|
||||||
)
|
|
||||||
|
|
||||||
type StoreManager struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
FixedStoreManager *StoreManager
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
FixedStoreManager = &StoreManager{}
|
|
||||||
partner.InitStoreManager(FixedStoreManager)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *StoreManager) OnStoreStatusChanged(vendorStoreID string, vendorID int, storeStatus int) (err error) {
|
|
||||||
db := dao.GetDB()
|
|
||||||
storeDetail, err := dao.GetStoreDetailByVendorStoreID(db, vendorStoreID, vendorID, "")
|
|
||||||
if err == nil {
|
|
||||||
if storeDetail.IsSync == model.NO || storeDetail.Status == model.StoreStatusDisabled || storeDetail.Status == model.StoreStatusHaveRest {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var storeKV, storeMapKV map[string]interface{}
|
|
||||||
if storeStatus == model.StoreStatusOpened {
|
|
||||||
if storeDetail.Status != model.StoreStatusOpened {
|
|
||||||
storeKV = map[string]interface{}{
|
|
||||||
"Status": model.StoreStatusOpened,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if storeDetail.VendorStatus != model.StoreStatusOpened {
|
|
||||||
storeMapKV = map[string]interface{}{
|
|
||||||
"Status": model.StoreStatusOpened,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if storeDetail.Status == model.StoreStatusOpened {
|
|
||||||
if storeDetail.VendorStatus != storeStatus {
|
|
||||||
storeMapKV = map[string]interface{}{
|
|
||||||
"Status": storeStatus,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if storeDetail.Status <= storeStatus {
|
|
||||||
if storeDetail.VendorStatus != storeStatus {
|
|
||||||
storeMapKV = map[string]interface{}{
|
|
||||||
"Status": storeStatus,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err == nil && (storeKV != nil || storeMapKV != nil) {
|
|
||||||
txDB, _ := dao.Begin(db)
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil || err != nil {
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
if r != nil {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
if storeKV != nil {
|
|
||||||
store := &model.Store{}
|
|
||||||
store.ID = storeDetail.Store.ID
|
|
||||||
if err = utils.CallFuncLogError(func() error {
|
|
||||||
_, err = dao.UpdateEntityLogically(db, store, storeKV, model.AdminName, nil)
|
|
||||||
return err
|
|
||||||
}, "OnStoreStatusChanged Update Store venvendorStoreID:%s", vendorStoreID); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if storeMapKV != nil {
|
|
||||||
if err = utils.CallFuncLogError(func() error {
|
|
||||||
_, err = dao.UpdateEntityLogically(db, &model.StoreMap{}, storeMapKV, model.AdminName, map[string]interface{}{
|
|
||||||
model.FieldStoreID: storeDetail.Store.ID,
|
|
||||||
model.FieldVendorID: vendorID,
|
|
||||||
model.FieldDeletedAt: utils.DefaultTimeValue,
|
|
||||||
})
|
|
||||||
return err
|
|
||||||
}, "OnStoreStatusChanged Update StoreMap venvendorStoreID:%s", vendorStoreID); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if storeStatus != model.StoreStatusOpened {
|
|
||||||
// 因为storeStatus != model.StoreStatusOpened不会修改京西门店的状态,所以直接用storeDetail.Status是合适的
|
|
||||||
if err = utils.CallFuncLogError(func() error {
|
|
||||||
return dao.FormalizeStoreStatus(db, storeDetail.Store.ID, storeDetail.Status)
|
|
||||||
}, "OnStoreStatusChanged FormalizeStoreStatus venvendorStoreID:%s", vendorStoreID); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dao.Commit(db, txDB)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 打印门第离线消息
|
|
||||||
if storeStatus < model.StoreStatusOpened && storeDetail.PrinterVendorID == model.VendorIDJxprint {
|
|
||||||
netprinter.PrintStoreStatus(jxcontext.AdminCtx, storeDetail, vendorID, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *StoreManager) OnCourierStoreStatusChanged(ctx *jxcontext.Context, vendorStoreID string, vendorID int, auditStatus int, message string) (err error) {
|
|
||||||
if vendorStoreID != "" {
|
|
||||||
db := dao.GetDB()
|
|
||||||
_, err2 := dao.GetStoreDetail2(db, 0, vendorStoreID, vendorID)
|
|
||||||
if err = err2; err == nil {
|
|
||||||
status := model.StoreStatusOpened
|
|
||||||
if auditStatus != model.StoreAuditStatusOnline && auditStatus != model.StoreAuditStatusUpdated {
|
|
||||||
status = model.StoreStatusDisabled
|
|
||||||
}
|
|
||||||
comment := ""
|
|
||||||
if auditStatus == model.StoreAuditStatusRejected {
|
|
||||||
comment = message
|
|
||||||
}
|
|
||||||
_, err = dao.UpdateEntityLogically(db, &model.StoreCourierMap{}, map[string]interface{}{
|
|
||||||
model.FieldStatus: status,
|
|
||||||
"AuditStatus": auditStatus,
|
|
||||||
"Comment": comment,
|
|
||||||
}, ctx.GetUserName(), map[string]interface{}{
|
|
||||||
model.FieldVendorStoreID: vendorStoreID,
|
|
||||||
model.FieldVendorID: vendorID,
|
|
||||||
})
|
|
||||||
} else if dao.IsNoRowsError(err) {
|
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,742 +0,0 @@
|
|||||||
package cms
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner/purchase/tiktok_store"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/baseapi/utils/errlist"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner/putils"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
)
|
|
||||||
|
|
||||||
type MultiStoreVendorInfo struct {
|
|
||||||
VendorID int
|
|
||||||
OrgCode string
|
|
||||||
}
|
|
||||||
|
|
||||||
func CombineVendorIDAndOrgCode(vendorID int, orgCode string) string {
|
|
||||||
return fmt.Sprintf("%d-%s", vendorID, orgCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getMultiStoreVendorInfoList() (list []*MultiStoreVendorInfo) {
|
|
||||||
vendorIDs := partner.GetMultiStoreVendorIDs()
|
|
||||||
for _, vendorID := range vendorIDs {
|
|
||||||
orgCodeList := partner.CurAPIManager.GetAppOrgCodeList(vendorID)
|
|
||||||
for _, v := range orgCodeList {
|
|
||||||
list = append(list, &MultiStoreVendorInfo{
|
|
||||||
VendorID: vendorID,
|
|
||||||
OrgCode: v,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
|
|
||||||
func syncCategories(ctx *jxcontext.Context, db *dao.DaoDB, parentTask tasksch.ITask, catList []*dao.SkuStoreCatInfo, isAsync bool) (hint string, err error) {
|
|
||||||
if len(catList) > 0 {
|
|
||||||
// todo 按vendorID orgCode合并操作
|
|
||||||
task := tasksch.NewParallelTask(fmt.Sprintf("同步分类2:%d", len(catList)), tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx,
|
|
||||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
|
||||||
catVendorInfo := batchItemList[0].(*dao.SkuStoreCatInfo)
|
|
||||||
if catVendorInfo.Level != 1 && catVendorInfo.ParentVendorCatID == "" {
|
|
||||||
return nil, fmt.Errorf("%d的父目录%d没有同步", catVendorInfo.ID, catVendorInfo.ParentID)
|
|
||||||
}
|
|
||||||
if catVendorInfo.MapID == 0 {
|
|
||||||
return nil, fmt.Errorf("分类:%d的数据异常", catVendorInfo.ID)
|
|
||||||
}
|
|
||||||
//表示是不用京西分类,要用平台分类
|
|
||||||
if catVendorInfo.IsJxCat == model.YES {
|
|
||||||
if catVendorInfo.VendorCategoryID != 0 {
|
|
||||||
catVendorInfo.Seq = catVendorInfo.VendorCategorySeq
|
|
||||||
catVendorInfo.Name = catVendorInfo.VendorCategoryName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if multiStoresHandler, ok := partner.GetPurchasePlatformFromVendorID(catVendorInfo.VendorID).(partner.IMultipleStoresHandler); ok {
|
|
||||||
if model.IsSyncStatusDelete(catVendorInfo.CatSyncStatus) { //删除
|
|
||||||
if !dao.IsVendorThingIDEmpty(catVendorInfo.VendorCatID) &&
|
|
||||||
model.IsSyncStatusNeedDelete(catVendorInfo.CatSyncStatus) {
|
|
||||||
err = multiStoresHandler.DeleteCategory2(ctx, catVendorInfo.VendorOrgCode, catVendorInfo.VendorCatID)
|
|
||||||
}
|
|
||||||
} else if model.IsSyncStatusNew(catVendorInfo.CatSyncStatus) { // 新增
|
|
||||||
err = multiStoresHandler.CreateCategory2(ctx, catVendorInfo)
|
|
||||||
} else if model.IsSyncStatusUpdate(catVendorInfo.CatSyncStatus) { // 修改
|
|
||||||
err = multiStoresHandler.UpdateCategory2(ctx, catVendorInfo)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if catVendorInfo.VendorID != model.VendorIDDD {
|
|
||||||
err = fmt.Errorf("平台:%d不合法", catVendorInfo.VendorID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err = OnThingSync(ctx, dao.GetDB(), SkuCategoryVendor2ThingMap(catVendorInfo), err); err == nil {
|
|
||||||
retVal = []int{1}
|
|
||||||
}
|
|
||||||
return retVal, err
|
|
||||||
}, catList)
|
|
||||||
tasksch.HandleTask(task, parentTask, len(catList) == 0 || len(catList) > 10).Run()
|
|
||||||
if isAsync {
|
|
||||||
hint = task.GetID()
|
|
||||||
} else {
|
|
||||||
resultList, err2 := task.GetResult(0)
|
|
||||||
if err = err2; err == nil {
|
|
||||||
hint = utils.Int2Str(len(resultList))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hint, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func SyncCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorIDs []int, appOrgCodes []string, catIDs []int, isAsync bool) (hint string, err error) {
|
|
||||||
db := dao.GetDB()
|
|
||||||
catList, err := dao.GetSkuCategoryWithVendor(db, vendorIDs, appOrgCodes, -1, catIDs, true)
|
|
||||||
if err == nil && len(catList) > 0 {
|
|
||||||
//TODO 同一平台不同账号会有影响needSyncParentIDs,暂不处理
|
|
||||||
var needSyncParentIDs []int
|
|
||||||
for _, cat := range catList {
|
|
||||||
if cat.Level == 2 && cat.ParentVendorCatID == "" && cat.IsExdSpec == model.NO {
|
|
||||||
needSyncParentIDs = append(needSyncParentIDs, cat.ParentID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(needSyncParentIDs) > 0 {
|
|
||||||
task := tasksch.NewSeqTask(fmt.Sprintf("同步分类1:%v", catIDs), ctx,
|
|
||||||
func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
|
||||||
switch step {
|
|
||||||
case 0:
|
|
||||||
catList2, err := dao.GetSkuCategoryWithVendor(db, vendorIDs, appOrgCodes, -1, needSyncParentIDs, true)
|
|
||||||
if err == nil {
|
|
||||||
_, err = syncCategories(ctx, db, task, catList2, false)
|
|
||||||
}
|
|
||||||
case 1:
|
|
||||||
catList2, err := dao.GetSkuCategoryWithVendor(db, vendorIDs, appOrgCodes, -1, catIDs, true)
|
|
||||||
if err == nil {
|
|
||||||
_, err = syncCategories(ctx, db, task, catList2, false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result, err
|
|
||||||
}, 2)
|
|
||||||
tasksch.HandleTask(task, parentTask, len(catIDs) == 0 || len(catIDs) > 10).Run()
|
|
||||||
if isAsync {
|
|
||||||
hint = task.GetID()
|
|
||||||
} else {
|
|
||||||
resultList, err2 := task.GetResult(0)
|
|
||||||
if err = err2; err == nil {
|
|
||||||
hint = utils.Int2Str(len(resultList))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
hint, err = syncCategories(ctx, db, parentTask, catList, false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hint, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func SyncSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorIDs []int, appOrgCodes []string, nameIDs, skuIDs []int, isAsync bool) (hint string, err error) {
|
|
||||||
db := dao.GetDB()
|
|
||||||
skuList, err := dao.GetSkusWithVendor(db, vendorIDs, appOrgCodes, nameIDs, skuIDs, true)
|
|
||||||
|
|
||||||
cc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
|
||||||
skuVendorInfo := batchItemList[0].(*dao.StoreSkuSyncInfo)
|
|
||||||
var failedList []*partner.StoreSkuInfoWithErr
|
|
||||||
// if skuVendorInfo.VendorCatID == "" {
|
|
||||||
// return nil, fmt.Errorf("商品:%d的商家分类没有同步", skuVendorInfo.SkuID)
|
|
||||||
// }
|
|
||||||
if skuVendorInfo.BindID == 0 {
|
|
||||||
return nil, fmt.Errorf("商品:%d的数据异常", skuVendorInfo.SkuID)
|
|
||||||
}
|
|
||||||
if skuVendorInfo.ExdSkuID != "" {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
//todo 暂时注释
|
|
||||||
if !model.IsSyncStatusNew(skuVendorInfo.SkuSyncStatus) && skuVendorInfo.VendorSkuID == "" {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if skuVendorInfo.SkuVendorMapCatID != "" {
|
|
||||||
skuVendorInfo.VendorVendorCatID = utils.Str2Int64(skuVendorInfo.SkuVendorMapCatID)
|
|
||||||
}
|
|
||||||
skuVendorInfo.SkuName = jxutils.ComposeSkuNameSync(skuVendorInfo.Prefix, skuVendorInfo.Name, skuVendorInfo.Comment, skuVendorInfo.Unit, skuVendorInfo.SpecQuality, skuVendorInfo.SpecUnit, 0, skuVendorInfo.ExPrefix, skuVendorInfo.ExPrefixBegin, skuVendorInfo.ExPrefixEnd, true)
|
|
||||||
skuVendorInfo.SkuNameOrigin = jxutils.ComposeSkuNameOriginal(skuVendorInfo.Prefix, skuVendorInfo.Name, skuVendorInfo.Comment, skuVendorInfo.Unit, skuVendorInfo.SpecQuality, skuVendorInfo.SpecUnit, 0)
|
|
||||||
if skuVendorInfo.ImgWatermark != "" {
|
|
||||||
downLoad, _ := uploadImgStandard(skuVendorInfo.ImgWatermark)
|
|
||||||
skuVendorInfo.ImgMix = jxutils.MixWatermarkImg(downLoad, skuVendorInfo.Img, skuVendorInfo.ExPrefixBegin, skuVendorInfo.ExPrefixEnd)
|
|
||||||
}
|
|
||||||
skuVendorInfo.MergedStatus = jxutils.MergeSkuStatus(skuVendorInfo.Status, skuVendorInfo.NameStatus)
|
|
||||||
if multiStoresHandler, ok := partner.GetPurchasePlatformFromVendorID(skuVendorInfo.VendorID).(partner.IMultipleStoresHandler); ok {
|
|
||||||
if model.IsSyncStatusDelete(skuVendorInfo.SkuSyncStatus) { //删除
|
|
||||||
if !dao.IsVendorThingIDEmpty(skuVendorInfo.VendorSkuID) &&
|
|
||||||
model.IsSyncStatusNeedDelete(skuVendorInfo.SkuSyncStatus) {
|
|
||||||
err = multiStoresHandler.DeleteSku2(ctx, skuVendorInfo.VendorOrgCode, storeSkuSyncInfo2Bare(skuVendorInfo))
|
|
||||||
if err != nil {
|
|
||||||
failedList = putils.GetErrMsg2FailedSingleList(skuVendorInfo, err, 0, model.VendorChineseNames[skuVendorInfo.VendorID], "删除商品")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if model.IsSyncStatusNew(skuVendorInfo.SkuSyncStatus) { // 新增
|
|
||||||
err = multiStoresHandler.CreateSku2(ctx, skuVendorInfo)
|
|
||||||
if err != nil {
|
|
||||||
failedList = putils.GetErrMsg2FailedSingleList(skuVendorInfo, err, 0, model.VendorChineseNames[skuVendorInfo.VendorID], "新增商品")
|
|
||||||
}
|
|
||||||
} else if model.IsSyncStatusUpdate(skuVendorInfo.SkuSyncStatus) { // 修改
|
|
||||||
err = multiStoresHandler.UpdateSku2(ctx, skuVendorInfo)
|
|
||||||
if err != nil {
|
|
||||||
failedList = putils.GetErrMsg2FailedSingleList(skuVendorInfo, err, 0, model.VendorChineseNames[skuVendorInfo.VendorID], "修改商品")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if skuVendorInfo.VendorID != model.VendorIDDD {
|
|
||||||
err = fmt.Errorf("平台:%d不合法", skuVendorInfo.VendorID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(failedList) > 0 {
|
|
||||||
task.AddFailedList(failedList)
|
|
||||||
} else {
|
|
||||||
dao.SetStoreSkuSyncStatus(dao.GetDB(), model.VendorIDJD, []int{skuVendorInfo.StoreID}, []int{skuVendorInfo.SkuID}, model.ThingTypeSyncSuccess)
|
|
||||||
}
|
|
||||||
if err = OnThingSync(ctx, dao.GetDB(), SkuVendor2ThingMap(skuVendorInfo), err); err == nil {
|
|
||||||
retVal = []int{1}
|
|
||||||
}
|
|
||||||
return retVal, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err == nil && len(skuList) > 0 {
|
|
||||||
task := tasksch.NewParallelTask(
|
|
||||||
fmt.Sprintf("同步商品:%v,%v", nameIDs, skuIDs),
|
|
||||||
tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, cc, skuList)
|
|
||||||
if isAsync {
|
|
||||||
buildSetFinishHook(task, ctx)
|
|
||||||
}
|
|
||||||
tasksch.HandleTask(task, parentTask, len(skuList) == 0 || len(skuList) > 10).Run()
|
|
||||||
if isAsync {
|
|
||||||
hint = task.GetID()
|
|
||||||
} else {
|
|
||||||
resultList, err2 := task.GetResult(0)
|
|
||||||
if len(task.GetFailedList()) > 0 {
|
|
||||||
err2 = buildErrMsg(task)
|
|
||||||
err2 = makeSyncError(err2)
|
|
||||||
}
|
|
||||||
if err = err2; err == nil {
|
|
||||||
hint = utils.Int2Str(len(resultList))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hint, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func SyncReorderCategories(ctx *jxcontext.Context, parentCatID int, isAsync bool) (hint string, err error) {
|
|
||||||
db := dao.GetDB()
|
|
||||||
hint, err = CurVendorSync.LoopMultiStoresVendors(ctx, db, fmt.Sprintf("分类重排序:%d", parentCatID), isAsync, false,
|
|
||||||
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
|
||||||
vendorInfo := batchItemList[0].(*MultiStoreVendorInfo)
|
|
||||||
multiStoresHandler := CurVendorSync.GetMultiStoreHandler(vendorInfo.VendorID)
|
|
||||||
vendorOrgCode, err := dao.GetVendorOrgCode(db, vendorInfo.VendorID, vendorInfo.OrgCode, "")
|
|
||||||
if multiStoresHandler != nil {
|
|
||||||
var vendorCatIDList []string
|
|
||||||
var parentVendorCatID string
|
|
||||||
//如果用平台分类就走else,用京西分类就还是原来的if
|
|
||||||
if vendorOrgCode[0].IsJxCat == model.NO {
|
|
||||||
catList, err2 := dao.GetSkuCategoryWithVendor(db, []int{vendorInfo.VendorID}, []string{vendorInfo.OrgCode}, parentCatID, nil, false)
|
|
||||||
if err = err2; err == nil {
|
|
||||||
for _, v := range catList {
|
|
||||||
if v.VendorCatID != "" {
|
|
||||||
vendorCatIDList = append(vendorCatIDList, v.VendorCatID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parentVendorCatID = catList[0].ParentVendorCatID
|
|
||||||
} else {
|
|
||||||
vendorCatList, _ := dao.GetVendorCategoryMapExt(db, parentCatID, 0, vendorInfo.VendorID, vendorInfo.OrgCode, 0)
|
|
||||||
for _, v := range vendorCatList {
|
|
||||||
if v.VendorThingID != "" {
|
|
||||||
vendorCatIDList = append(vendorCatIDList, v.VendorThingID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
thingMaps, _ := dao.GetThingMapList(db, model.ThingTypeCategory, []int{vendorInfo.VendorID}, []int{parentCatID}, []string{vendorInfo.OrgCode})
|
|
||||||
parentVendorCatID = thingMaps[0].VendorThingID
|
|
||||||
}
|
|
||||||
if len(vendorCatIDList) > 0 {
|
|
||||||
if err = multiStoresHandler.ReorderCategories2(ctx, vendorInfo.OrgCode, parentVendorCatID, vendorCatIDList); err == nil {
|
|
||||||
retVal = []int{len(vendorCatIDList)}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = fmt.Errorf("非法平台:%d", vendorInfo.VendorID)
|
|
||||||
}
|
|
||||||
return retVal, err
|
|
||||||
})
|
|
||||||
return hint, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func SyncReorderCategories2(ctx *jxcontext.Context, parentCatID, vendorID int, vendorOrgCode string) (err error) {
|
|
||||||
db := dao.GetDB()
|
|
||||||
multiStoresHandler := CurVendorSync.GetMultiStoreHandler(vendorID)
|
|
||||||
if multiStoresHandler != nil {
|
|
||||||
var vendorCatIDList []string
|
|
||||||
var parentVendorCatID string
|
|
||||||
vendorCatList, _ := dao.GetVendorCategoryMapExt(db, parentCatID, 0, vendorID, vendorOrgCode, 0)
|
|
||||||
for _, v := range vendorCatList {
|
|
||||||
if v.VendorThingID != "" {
|
|
||||||
vendorCatIDList = append(vendorCatIDList, v.VendorThingID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
thingMaps, _ := dao.GetThingMapList(db, model.ThingTypeCategory, []int{vendorID}, []int{parentCatID}, []string{vendorOrgCode})
|
|
||||||
if len(thingMaps) > 0 {
|
|
||||||
parentVendorCatID = thingMaps[0].VendorThingID
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(vendorCatIDList) > 0 {
|
|
||||||
err = multiStoresHandler.ReorderCategories2(ctx, vendorOrgCode, parentVendorCatID, vendorCatIDList)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = fmt.Errorf("非法平台:%d", vendorID)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func getThingMap(db *dao.DaoDB, thingMap *model.ThingMap) (err error) {
|
|
||||||
return dao.GetEntity(db, thingMap, "ThingID", "ThingType", "VendorID", "VendorOrgCode", model.FieldDeletedAt)
|
|
||||||
}
|
|
||||||
|
|
||||||
func OnCreateThing(ctx *jxcontext.Context, db *dao.DaoDB, vendorInfoList []*model.VendorOrgCode, thingID int64, thingType, syncFlag int8, vendorFlag bool) (err error) {
|
|
||||||
if thingType == model.ThingTypeSkuName {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if len(vendorInfoList) == 0 {
|
|
||||||
vendorInfoList, err = dao.GetVendorOrgCode(db, model.VendorIDJD, "", model.VendorOrgTypePlatform)
|
|
||||||
}
|
|
||||||
errList := errlist.New()
|
|
||||||
for _, v := range vendorInfoList {
|
|
||||||
thingMap := &model.ThingMap{
|
|
||||||
ThingID: thingID,
|
|
||||||
ThingType: thingType,
|
|
||||||
VendorID: v.VendorID,
|
|
||||||
VendorOrgCode: v.VendorOrgCode,
|
|
||||||
}
|
|
||||||
if thingType == model.ThingTypeCategory && !vendorFlag {
|
|
||||||
if v.IsJxCat == model.YES {
|
|
||||||
syncFlag = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
thingMap.SyncStatus = syncFlag
|
|
||||||
dao.WrapAddIDCULDEntity(thingMap, ctx.GetUserName())
|
|
||||||
if err2 := dao.CreateEntity(db, thingMap); err2 != nil {
|
|
||||||
if dao.IsDuplicateError(err2) {
|
|
||||||
errList.AddErr(onUpdateThing(ctx, db, vendorInfoList, thingID, thingType, syncFlag))
|
|
||||||
} else {
|
|
||||||
errList.AddErr(err2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
updateThingMapEntity(db, thingMap)
|
|
||||||
}
|
|
||||||
err = errList.GetErrListAsOne()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func OnCreateThing2Tiktok(ctx *jxcontext.Context, db *dao.DaoDB, appOrgCode string, vendorThingList []*tiktok_store.TiktokIdAndLocalSkuId, thingType, syncFlag int8, vendorFlag bool) (err error) {
|
|
||||||
if thingType == model.ThingTypeSkuName {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
errList := errlist.New()
|
|
||||||
for _, v := range vendorThingList {
|
|
||||||
thingMap := &model.ThingMap{
|
|
||||||
ThingID: v.LocalSkuId,
|
|
||||||
ThingType: thingType,
|
|
||||||
VendorID: model.VendorIDDD,
|
|
||||||
VendorOrgCode: appOrgCode,
|
|
||||||
VendorThingID: v.MainId,
|
|
||||||
Remark: v.SkuAttrId,
|
|
||||||
}
|
|
||||||
if thingType == model.ThingTypeCategory && !vendorFlag {
|
|
||||||
syncFlag = 0
|
|
||||||
}
|
|
||||||
thingMap.SyncStatus = syncFlag
|
|
||||||
dao.WrapAddIDCULDEntity(thingMap, ctx.GetUserName())
|
|
||||||
if err2 := dao.CreateEntity(db, thingMap); err2 != nil {
|
|
||||||
if err2 := getThingMap(db, thingMap); err2 == nil {
|
|
||||||
thingMap.SyncStatus = 2
|
|
||||||
thingMap.LastOperator = ctx.GetUserName()
|
|
||||||
_, err2 = dao.UpdateEntity(db, thingMap)
|
|
||||||
errList.AddErr(err2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = errList.GetErrListAsOne()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func onUpdateThing(ctx *jxcontext.Context, db *dao.DaoDB, vendorInfoList []*model.VendorOrgCode, thingID int64, thingType int8, syncStatus int8) (err error) {
|
|
||||||
if thingType == model.ThingTypeSkuName {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if len(vendorInfoList) == 0 {
|
|
||||||
vendorInfoList, err = dao.GetVendorOrgCode(db, model.VendorIDJD, "", model.VendorOrgTypePlatform)
|
|
||||||
}
|
|
||||||
errList := errlist.New()
|
|
||||||
for _, v := range vendorInfoList {
|
|
||||||
thingMap := &model.ThingMap{
|
|
||||||
ThingID: thingID,
|
|
||||||
ThingType: thingType,
|
|
||||||
VendorID: v.VendorID,
|
|
||||||
VendorOrgCode: v.VendorOrgCode,
|
|
||||||
}
|
|
||||||
thingMap.DeletedAt = utils.DefaultTimeValue
|
|
||||||
if err2 := getThingMap(db, thingMap); err2 == nil {
|
|
||||||
thingMap.SyncStatus |= syncStatus
|
|
||||||
thingMap.LastOperator = ctx.GetUserName()
|
|
||||||
_, err2 = dao.UpdateEntity(db, thingMap)
|
|
||||||
errList.AddErr(err2)
|
|
||||||
|
|
||||||
updateThingMapEntity(db, thingMap)
|
|
||||||
} else {
|
|
||||||
if dao.IsNoRowsError(err2) {
|
|
||||||
err2 = nil
|
|
||||||
} else {
|
|
||||||
errList.AddErr(err2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = errList.GetErrListAsOne()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func DeleteThingByData(ctx *jxcontext.Context, db *dao.DaoDB, appOrgCode string, startTime time.Time, endTime time.Time) error {
|
|
||||||
sql := ` DELETE FROM thing_map WHERE vendor_org_code = ? AND created_at >= ? AND created_at < ? `
|
|
||||||
_, err := dao.ExecuteSQL(db, sql, []interface{}{appOrgCode, startTime, endTime})
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func OnUpdateThing(ctx *jxcontext.Context, db *dao.DaoDB, vendorInfoList []*model.VendorOrgCode, thingID int64, thingType int8) (err error) {
|
|
||||||
return onUpdateThing(ctx, db, vendorInfoList, thingID, thingType, model.SyncFlagModifiedMask)
|
|
||||||
}
|
|
||||||
|
|
||||||
func OnDeleteThing(ctx *jxcontext.Context, db *dao.DaoDB, vendorInfoList []*MultiStoreVendorInfo, thingID int64, thingType int8) (err error) {
|
|
||||||
if thingType == model.ThingTypeSkuName {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if len(vendorInfoList) == 0 {
|
|
||||||
vendorInfoList = getMultiStoreVendorInfoList()
|
|
||||||
}
|
|
||||||
errList := errlist.New()
|
|
||||||
for _, v := range vendorInfoList {
|
|
||||||
thingMap := &model.ThingMap{
|
|
||||||
ThingID: thingID,
|
|
||||||
ThingType: thingType,
|
|
||||||
VendorID: v.VendorID,
|
|
||||||
VendorOrgCode: v.OrgCode,
|
|
||||||
}
|
|
||||||
thingMap.DeletedAt = utils.DefaultTimeValue
|
|
||||||
if err2 := getThingMap(db, thingMap); err2 == nil {
|
|
||||||
if model.IsSyncStatusNew(thingMap.SyncStatus) {
|
|
||||||
thingMap.SyncStatus = 0
|
|
||||||
thingMap.DeletedAt = time.Now()
|
|
||||||
} else {
|
|
||||||
thingMap.SyncStatus |= model.SyncFlagDeletedMask
|
|
||||||
}
|
|
||||||
thingMap.LastOperator = ctx.GetUserName()
|
|
||||||
_, err2 = dao.UpdateEntity(db, thingMap)
|
|
||||||
errList.AddErr(err2)
|
|
||||||
|
|
||||||
updateThingMapEntity(db, thingMap)
|
|
||||||
} else if !dao.IsNoRowsError(err2) {
|
|
||||||
errList.AddErr(err2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = errList.GetErrListAsOne()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func SkuCategoryVendor2ThingMap(cat *dao.SkuStoreCatInfo) (thingMap *model.ThingMap) {
|
|
||||||
thingMap = &model.ThingMap{
|
|
||||||
ThingID: int64(cat.ID),
|
|
||||||
ThingType: model.ThingTypeCategory,
|
|
||||||
VendorID: cat.VendorID,
|
|
||||||
VendorOrgCode: cat.VendorOrgCode,
|
|
||||||
|
|
||||||
SyncStatus: cat.CatSyncStatus,
|
|
||||||
VendorThingID: cat.VendorCatID,
|
|
||||||
}
|
|
||||||
thingMap.ID = cat.MapID // 一定要赋值
|
|
||||||
return thingMap
|
|
||||||
}
|
|
||||||
|
|
||||||
func SkuVendor2ThingMap(sku *dao.StoreSkuSyncInfo) (thingMap *model.ThingMap) {
|
|
||||||
thingMap = &model.ThingMap{
|
|
||||||
ThingID: int64(sku.SkuID),
|
|
||||||
ThingType: model.ThingTypeSku,
|
|
||||||
VendorID: sku.VendorID,
|
|
||||||
VendorOrgCode: sku.VendorOrgCode,
|
|
||||||
|
|
||||||
SyncStatus: sku.SkuSyncStatus,
|
|
||||||
VendorThingID: sku.VendorSkuID,
|
|
||||||
}
|
|
||||||
thingMap.DeletedAt = utils.DefaultTimeValue
|
|
||||||
thingMap.ID = sku.BindID // 一定要赋值
|
|
||||||
return thingMap
|
|
||||||
}
|
|
||||||
|
|
||||||
func OnThingSync(ctx *jxcontext.Context, db *dao.DaoDB, thingMap *model.ThingMap, syncErr error) (err error) {
|
|
||||||
if syncErr != nil {
|
|
||||||
err = syncErr
|
|
||||||
thingMap.Remark = utils.LimitUTF8StringLen(err.Error(), 255)
|
|
||||||
dao.UpdateEntity(db, thingMap, "Remark")
|
|
||||||
|
|
||||||
if thingMap.VendorOrgCode == globals.JdcsOrgCode {
|
|
||||||
if strings.Contains(err.Error(), "店内分类信息不存在") {
|
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
updateFields := []string{
|
|
||||||
model.FieldSyncStatus,
|
|
||||||
model.FieldUpdatedAt,
|
|
||||||
model.FieldLastOperator,
|
|
||||||
"Remark",
|
|
||||||
}
|
|
||||||
if model.IsSyncStatusDelete(thingMap.SyncStatus) { //删除
|
|
||||||
thingMap.DeletedAt = time.Now()
|
|
||||||
thingMap.VendorThingID = ""
|
|
||||||
updateFields = append(updateFields, "VendorThingID", model.FieldDeletedAt)
|
|
||||||
} else if model.IsSyncStatusNew(thingMap.SyncStatus) { // 新增
|
|
||||||
updateFields = append(updateFields, "VendorThingID")
|
|
||||||
}
|
|
||||||
thingMap.SyncStatus = 0
|
|
||||||
thingMap.LastOperator = ctx.GetUserName()
|
|
||||||
thingMap.UpdatedAt = time.Now()
|
|
||||||
thingMap.Remark = ""
|
|
||||||
_, err = dao.UpdateEntity(db, thingMap, updateFields...)
|
|
||||||
|
|
||||||
updateThingMapEntity(db, thingMap)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateThingMapEntity(db *dao.DaoDB, thingMap *model.ThingMap) {
|
|
||||||
// if thingMap.VendorOrgCode == globals.JdOrgCode {
|
|
||||||
// if thingMap.ThingType == model.ThingTypeCategory {
|
|
||||||
// cat := &model.SkuCategory{
|
|
||||||
// JdID: utils.Str2Int64WithDefault(thingMap.VendorThingID, 0),
|
|
||||||
// JdSyncStatus: thingMap.SyncStatus,
|
|
||||||
// }
|
|
||||||
// cat.ID = int(thingMap.ThingID)
|
|
||||||
// dao.UpdateEntity(db, cat, "JdID", "JdSyncStatus")
|
|
||||||
// } else if thingMap.ThingType == model.ThingTypeSku {
|
|
||||||
// sku := &model.Sku{
|
|
||||||
// JdID: utils.Str2Int64WithDefault(thingMap.VendorThingID, 0),
|
|
||||||
// JdSyncStatus: thingMap.SyncStatus,
|
|
||||||
// }
|
|
||||||
// sku.ID = int(thingMap.ThingID)
|
|
||||||
// dao.UpdateEntity(db, sku, "JdID", "JdSyncStatus")
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
func amendAndPruneVendorStuff(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID, vendorID int, vendorOrgCode string, isAsync, isContinueWhenError bool, opType int, isForceUpdate bool) (hint string, err error) {
|
|
||||||
handler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IMultipleStoresHandler)
|
|
||||||
if handler == nil {
|
|
||||||
return "", fmt.Errorf("平台:%s不支持此操作", model.VendorChineseNames[vendorID])
|
|
||||||
}
|
|
||||||
db := dao.GetDB()
|
|
||||||
vendorOrgCodes, _ := dao.GetVendorOrgCode(db, vendorID, vendorOrgCode, model.VendorOrgTypePlatform)
|
|
||||||
var sku2Delete []*partner.StoreSkuInfo
|
|
||||||
var cat2Delete []*partner.BareCategoryInfo
|
|
||||||
task := tasksch.NewParallelTask(fmt.Sprintf("平台:%s,账号:%s上的商品与商家分类", model.VendorChineseNames[vendorID], vendorOrgCode),
|
|
||||||
tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx,
|
|
||||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
|
||||||
step := batchItemList[0].(int)
|
|
||||||
switch step {
|
|
||||||
case 0:
|
|
||||||
localSkuList, err := dao.GetSkusWithVendor(db, []int{vendorID}, []string{vendorOrgCode}, nil, nil, false)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
localSkuMap := make(map[string]*dao.StoreSkuSyncInfo)
|
|
||||||
for _, v := range localSkuList {
|
|
||||||
if v.VendorSkuID != "" {
|
|
||||||
localSkuMap[v.VendorSkuID] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
remoteSkuList, err2 := handler.GetSkus(ctx, vendorOrgCode, 0, "")
|
|
||||||
if err = err2; err == nil {
|
|
||||||
remoteSkuMap := make(map[string]int)
|
|
||||||
for _, v := range remoteSkuList {
|
|
||||||
if vendorSkuID := v.SkuList[0].VendorSkuID; vendorSkuID != "" {
|
|
||||||
if localSkuMap[vendorSkuID] == nil {
|
|
||||||
sku2Delete = append(sku2Delete, &partner.StoreSkuInfo{
|
|
||||||
SkuID: v.SkuList[0].SkuID,
|
|
||||||
VendorSkuID: vendorSkuID,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
remoteSkuMap[vendorSkuID] = 1
|
|
||||||
}
|
|
||||||
} else if v.VendorNameID != "" {
|
|
||||||
sku2Delete = append(sku2Delete, &partner.StoreSkuInfo{
|
|
||||||
SkuID: v.NameID,
|
|
||||||
VendorSkuID: v.VendorNameID,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
StoreSkuMap := make(map[int]*dao.StoreSkuSyncInfo)
|
|
||||||
if storeID != 0 {
|
|
||||||
skuList2, _ := dao.GetStoreSkuListWithVendor(db, storeID, vendorID, vendorOrgCode)
|
|
||||||
for _, v := range skuList2 {
|
|
||||||
if _, ok := StoreSkuMap[v.ID]; !ok {
|
|
||||||
StoreSkuMap[v.ID] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
getSyncFlag := func(skuID int) int8 {
|
|
||||||
if StoreSkuMap[skuID] != nil {
|
|
||||||
return model.SyncFlagNewMask
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
if opType == AmendPruneOnlyAmend || opType == AmendPruneAll {
|
|
||||||
for _, v := range localSkuList {
|
|
||||||
if v.ExdSkuID == "" {
|
|
||||||
if v.BindID != 0 {
|
|
||||||
if !model.IsSyncStatusDelete(v.SkuSyncStatus) {
|
|
||||||
if remoteSkuMap[v.VendorSkuID] == 0 {
|
|
||||||
if !model.IsSyncStatusNew(v.SkuSyncStatus) {
|
|
||||||
err = OnCreateThing(ctx, db, vendorOrgCodes, int64(v.SkuID), model.ThingTypeSku, getSyncFlag(v.SkuID), false)
|
|
||||||
}
|
|
||||||
} else if isForceUpdate {
|
|
||||||
err = OnUpdateThing(ctx, db, vendorOrgCodes, int64(v.SkuID), model.ThingTypeSku)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//表示根据某门店的门店商品同步京东商品库中,这个门店关注并可售了这个商品,插到thingmap里同步标志是待创建(SyncFlagNewMask)才会创建
|
|
||||||
//若该门店没关注可售,那插到thingmap里的话就该同步标志为0,就不会创建
|
|
||||||
//getSyncFlag
|
|
||||||
err = OnCreateThing(ctx, db, vendorOrgCodes, int64(v.SkuID), model.ThingTypeSku, getSyncFlag(v.SkuID), false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 1:
|
|
||||||
// if (opType == AmendPruneOnlyPrune || opType == AmendPruneAll) && len(sku2Delete) > 0 {
|
|
||||||
// _, err = putils.FreeBatchStoreSkuInfo("删除商品", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) {
|
|
||||||
// if err = handler.DeleteSku2(ctx, vendorOrgCode, batchedStoreSkuList[0]); err == nil {
|
|
||||||
// successCount = 1
|
|
||||||
// }
|
|
||||||
// return nil, successCount, err
|
|
||||||
// }, ctx, task, sku2Delete, 1, isContinueWhenError)
|
|
||||||
// }
|
|
||||||
sku2Delete = nil
|
|
||||||
case 2:
|
|
||||||
localCatList, err := dao.GetSkuCategoryWithVendor(db, []int{vendorID}, []string{vendorOrgCode}, -1, nil, false)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
localCatMap := make(map[string]*dao.SkuStoreCatInfo)
|
|
||||||
for _, v := range localCatList {
|
|
||||||
localCatMap[v.VendorCatID] = v
|
|
||||||
localCatMap[v.Name] = v
|
|
||||||
localCatMap[utils.Int2Str(v.ID)] = v
|
|
||||||
}
|
|
||||||
|
|
||||||
vendorCatMap := make(map[int]*model.VendorCategoryMap)
|
|
||||||
if vendorOrgCodes[0].IsJxCat == model.YES {
|
|
||||||
vendorCats, _ := dao.GetVendorCategoryMap(db, -1, 0, vendorID, vendorOrgCode, 0)
|
|
||||||
for _, v := range vendorCats {
|
|
||||||
if _, ok := vendorCatMap[v.CategoryID]; !ok {
|
|
||||||
vendorCatMap[v.CategoryID] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
getSyncFlagCat := func(categoryID int) int8 {
|
|
||||||
if vendorCatMap[categoryID] != nil || vendorOrgCodes[0].IsJxCat == model.NO {
|
|
||||||
return model.SyncFlagNewMask
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
remoteCatList, err2 := handler.GetAllCategories(ctx, vendorOrgCode)
|
|
||||||
if err = err2; err == nil {
|
|
||||||
remoteCatMap := make(map[string]int)
|
|
||||||
cat2Delete = checkRemoteCatExist(remoteCatMap, localCatMap, remoteCatList)
|
|
||||||
for _, v := range localCatList {
|
|
||||||
if v.IsExdSpec == model.NO {
|
|
||||||
if v.MapID != 0 {
|
|
||||||
if !model.IsSyncStatusDelete(v.CatSyncStatus) {
|
|
||||||
if remoteCatMap[v.VendorCatID] == 0 {
|
|
||||||
if !model.IsSyncStatusNew(v.CatSyncStatus) {
|
|
||||||
err = OnCreateThing(ctx, db, vendorOrgCodes, int64(v.ID), model.ThingTypeCategory, getSyncFlagCat(v.ID), true)
|
|
||||||
}
|
|
||||||
} else if isForceUpdate && !model.IsSyncStatusUpdate(v.CatSyncStatus) {
|
|
||||||
OnUpdateThing(ctx, db, vendorOrgCodes, int64(v.ID), model.ThingTypeCategory)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
OnCreateThing(ctx, db, vendorOrgCodes, int64(v.ID), model.ThingTypeCategory, getSyncFlagCat(v.ID), true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 3:
|
|
||||||
if (opType == AmendPruneOnlyPrune || opType == AmendPruneAll) && len(cat2Delete) > 0 {
|
|
||||||
for i := 0; i < 2; i++ {
|
|
||||||
level := 2 - i
|
|
||||||
var levelCat2Delete []*partner.BareCategoryInfo
|
|
||||||
for _, v := range cat2Delete {
|
|
||||||
if v.Level == level {
|
|
||||||
levelCat2Delete = append(levelCat2Delete, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(levelCat2Delete) > 0 {
|
|
||||||
// task4Delete := tasksch.NewParallelTask(fmt.Sprintf("删除商家分类,level:%d", level), tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
|
|
||||||
// func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
|
||||||
// cat := batchItemList[0].(*partner.BareCategoryInfo)
|
|
||||||
// err = handler.DeleteCategory2(ctx, vendorOrgCode, cat.VendorCatID)
|
|
||||||
// return nil, err
|
|
||||||
// }, levelCat2Delete)
|
|
||||||
// tasksch.HandleTask(task4Delete, task, true).Run()
|
|
||||||
// _, err = task4Delete.GetResult(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cat2Delete = nil
|
|
||||||
}
|
|
||||||
return nil, err
|
|
||||||
}, []int{0, 1, 2, 3})
|
|
||||||
tasksch.HandleTask(task, parentTask, true).Run()
|
|
||||||
if !isAsync {
|
|
||||||
_, err = task.GetResult(0)
|
|
||||||
hint = "1"
|
|
||||||
} else {
|
|
||||||
hint = task.ID
|
|
||||||
}
|
|
||||||
return hint, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func FullSyncVendorStuff(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID, vendorID int, vendorOrgCode string, isAsync, isContinueWhenError bool) (hint string, err error) {
|
|
||||||
multiStoreHandler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IMultipleStoresHandler)
|
|
||||||
if multiStoreHandler == nil {
|
|
||||||
return "", fmt.Errorf("vendorID:%d不是多门店平台", vendorID)
|
|
||||||
}
|
|
||||||
worker := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
|
||||||
step := batchItemList[0].(int)
|
|
||||||
switch step {
|
|
||||||
case 0:
|
|
||||||
_, err = amendAndPruneVendorStuff(ctx, task, storeID, vendorID, vendorOrgCode, false, isContinueWhenError, AmendPruneAll, false)
|
|
||||||
case 1:
|
|
||||||
//_, err = SyncCategories(ctx, task, []int{vendorID}, []string{vendorOrgCode}, nil, false)
|
|
||||||
case 2:
|
|
||||||
_, err = SyncSkus(ctx, task, []int{vendorID}, []string{vendorOrgCode}, nil, nil, false)
|
|
||||||
}
|
|
||||||
return retVal, err
|
|
||||||
}
|
|
||||||
task := tasksch.NewParallelTask("FullSyncStoreSkuNew", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(false), ctx, worker, []int{0, 1, 2})
|
|
||||||
tasksch.HandleTask(task, parentTask, true).Run()
|
|
||||||
if !isAsync {
|
|
||||||
_, err = task.GetResult(0)
|
|
||||||
} else {
|
|
||||||
hint = task.GetID()
|
|
||||||
}
|
|
||||||
return hint, err
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
package cms
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 如果京西门为打开,打开状态为非营业的平台门店
|
|
||||||
func OpenRemoteStoreByJxStatus(ctx *jxcontext.Context, vendorIDs, storeIDs []int, isForce, isAsync, isContinueWhenError bool) (hint string, err error) {
|
|
||||||
db := dao.GetDB()
|
|
||||||
status := model.StoreStatusAll
|
|
||||||
if !isForce {
|
|
||||||
status = model.StoreStatusClosed
|
|
||||||
}
|
|
||||||
storeMapList, err := dao.GetStoresMapList(db, vendorIDs, storeIDs, nil, status, model.StoreIsSyncYes, "", "", "")
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
vendorIDMap := make(map[int]int)
|
|
||||||
if len(vendorIDs) == 0 {
|
|
||||||
for k := range partner.PurchasePlatformHandlers {
|
|
||||||
vendorIDMap[k] = 1
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for _, v := range vendorIDs {
|
|
||||||
vendorIDMap[v] = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
task := tasksch.NewParallelTask("OpenRemoteStoreByJxStatus", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
|
|
||||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
|
||||||
storeMap := batchItemList[0].(*model.StoreMap)
|
|
||||||
if handler, _ := partner.GetPurchasePlatformFromVendorID(storeMap.VendorID).(partner.IStoreHandler); handler != nil {
|
|
||||||
storeDetail, err := dao.GetStoreDetail(db, storeMap.StoreID, storeMap.VendorID, "")
|
|
||||||
if err == nil && storeDetail.Status == model.StoreStatusOpened {
|
|
||||||
if err = handler.UpdateStoreStatus(ctx, storeMap.VendorOrgCode, storeMap.StoreID, storeMap.VendorStoreID, model.StoreStatusOpened); err == nil {
|
|
||||||
storeMap.Status = model.StoreStatusOpened
|
|
||||||
dao.UpdateEntity(db, storeMap, model.FieldStatus)
|
|
||||||
retVal = []int{1}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return retVal, err
|
|
||||||
}, storeMapList)
|
|
||||||
tasksch.HandleTask(task, nil, true).Run()
|
|
||||||
|
|
||||||
if isAsync {
|
|
||||||
hint = task.GetID()
|
|
||||||
} else {
|
|
||||||
resultList, err2 := task.GetResult(0)
|
|
||||||
if err = err2; err == nil {
|
|
||||||
hint = utils.Int2Str(len(resultList))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hint, err
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,328 +0,0 @@
|
|||||||
package cms
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner/putils"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api/apimanager"
|
|
||||||
"github.com/360EntSecGroup-Skylar/excelize"
|
|
||||||
)
|
|
||||||
|
|
||||||
func storeOrSkuMap2List(intStrMap map[int]string) (ids []int) {
|
|
||||||
for k, v := range intStrMap {
|
|
||||||
if v != "" {
|
|
||||||
ids = append(ids, k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ids
|
|
||||||
}
|
|
||||||
|
|
||||||
func getStoreSkus(db *dao.DaoDB, storeID int, skuIDs []int) (skus []*dao.StoreSkuSyncInfo, err error) {
|
|
||||||
sql := `
|
|
||||||
SELECT
|
|
||||||
t1.id bind_id, t1.sku_id, t1.price, t1.unit_price, t1.status store_sku_status,
|
|
||||||
t1.jd_sync_status sku_sync_status, t1.jd_price vendor_price, t1.jd_lock_time lock_time,
|
|
||||||
t1.store_id, t1.deleted_at bind_deleted_at,t1.status_sale_begin,t1.status_sale_end,
|
|
||||||
t2.*,
|
|
||||||
t3.id name_id, t3.prefix, t3.name, t3.unit, t3.upc, t3.status name_status, t3.ex_prefix, t3.ex_prefix_begin, t3.ex_prefix_end
|
|
||||||
FROM store_sku_bind t1
|
|
||||||
LEFT JOIN sku t2 ON t1.sku_id = t2.id AND t2.deleted_at = ?/* AND t2.status = ?*/
|
|
||||||
LEFT JOIN sku_name t3 ON t2.name_id = t3.id AND t3.deleted_at = ?/* AND t3.status = ?*/
|
|
||||||
WHERE 1 = 1
|
|
||||||
AND t1.store_id = ?
|
|
||||||
AND t1.deleted_at = ?
|
|
||||||
AND t1.sku_id IN ( ` + dao.GenQuestionMarks(len(skuIDs)) + `)
|
|
||||||
ORDER BY t1.price`
|
|
||||||
sqlParams := []interface{}{
|
|
||||||
utils.DefaultTimeValue,
|
|
||||||
utils.DefaultTimeValue,
|
|
||||||
storeID,
|
|
||||||
utils.DefaultTimeValue,
|
|
||||||
skuIDs,
|
|
||||||
}
|
|
||||||
if err = dao.GetRows(db, &skus, sql, sqlParams...); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return skus, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func SyncStoreSku4FakeJD(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, inSkuMap map[int]string, isContinueWhenError bool) (err error) {
|
|
||||||
vendorID := model.VendorIDJD
|
|
||||||
db := dao.GetDB()
|
|
||||||
storeDetail, err := dao.GetStoreDetail(db, storeID, vendorID, "")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
storeDetail.VendorOrgCode = apimanager.FakeJdOrgCode
|
|
||||||
skuIDs := storeOrSkuMap2List(inSkuMap)
|
|
||||||
skus, err := getStoreSkus(db, storeID, skuIDs)
|
|
||||||
if err != nil || len(skus) == 0 {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
formalizeStoreSkuList(skus)
|
|
||||||
storeSkuHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IPurchasePlatformStoreSkuHandler)
|
|
||||||
|
|
||||||
var (
|
|
||||||
stockList, onlineList, offlineList, priceList []*partner.StoreSkuInfo
|
|
||||||
)
|
|
||||||
skuMap := make(map[*partner.StoreSkuInfo]*dao.StoreSkuSyncInfo)
|
|
||||||
now := jxutils.OperationTime2HourMinuteFormat(time.Now())
|
|
||||||
var failedList []*partner.StoreSkuInfoWithErr
|
|
||||||
for _, sku := range skus {
|
|
||||||
sku.SkuSyncStatus = model.SyncFlagSaleMask | model.SyncFlagPriceMask | model.SyncFlagStockMask
|
|
||||||
sku.VendorSkuID = inSkuMap[sku.SkuID]
|
|
||||||
sku.SkuID = int(utils.Str2Int64(sku.VendorSkuID)) // skuID与vendorID一样
|
|
||||||
sku.VendorOrgCode = apimanager.FakeJdOrgCode
|
|
||||||
|
|
||||||
sku.VendorPrice = 0
|
|
||||||
sku.MergedStatus = MergeSkuSaleStatusWithStoreOpTime(sku, storeDetail, now)
|
|
||||||
var bareSku *partner.StoreSkuInfo
|
|
||||||
if isStoreSkuSyncNeedDelete(sku) {
|
|
||||||
if !dao.IsVendorThingIDEmpty(sku.VendorSkuID) {
|
|
||||||
bareSku = storeSkuSyncInfo2Bare(sku)
|
|
||||||
stockList = append(stockList, bareSku)
|
|
||||||
} else {
|
|
||||||
// updateItems = append(updateItems, sku2Update(vendorID, sku, model.SyncFlagDeletedMask))
|
|
||||||
}
|
|
||||||
} else if model.IsSyncStatusNew(sku.SkuSyncStatus) {
|
|
||||||
calVendorPrice4StoreSku(sku, storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage))
|
|
||||||
if dao.IsVendorThingIDEmpty(sku.VendorSkuID) {
|
|
||||||
// todo 多平台商品库没有正常创建,直接跳过
|
|
||||||
} else {
|
|
||||||
sku.SkuSyncStatus |= model.SyncFlagSaleMask | model.SyncFlagPriceMask
|
|
||||||
bareSku = storeSkuSyncInfo2Bare(sku)
|
|
||||||
stockList = append(stockList, bareSku)
|
|
||||||
priceList = append(priceList, bareSku)
|
|
||||||
if sku.MergedStatus == model.SkuStatusNormal {
|
|
||||||
onlineList = append(onlineList, bareSku)
|
|
||||||
} else {
|
|
||||||
offlineList = append(offlineList, bareSku)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if dao.IsVendorThingIDEmpty(sku.VendorSkuID) {
|
|
||||||
// err = fmt.Errorf("门店:%d,修改没有创建的商品:%d", storeID, sku.SkuID)
|
|
||||||
err = utils.NewErrorCode(fmt.Sprintf("门店:%d,修改没有创建的商品:%d", storeID, sku.SkuID), "-1", 0)
|
|
||||||
failedList = putils.GetErrMsg2FailedSingleList(nil, err, storeID, model.VendorChineseNames[vendorID], "异常同步错误")
|
|
||||||
if parentTask == nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
parentTask.AddBatchErr(err)
|
|
||||||
parentTask.AddFailedList(failedList)
|
|
||||||
} else {
|
|
||||||
isAdded2Update := false
|
|
||||||
if model.IsSyncStatusPrice(sku.SkuSyncStatus) {
|
|
||||||
bareSku = storeSkuSyncInfo2Bare(calVendorPrice4StoreSku(sku, storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage)))
|
|
||||||
priceList = append(priceList, bareSku)
|
|
||||||
}
|
|
||||||
if !isAdded2Update {
|
|
||||||
if model.IsSyncStatusSale(sku.SkuSyncStatus) {
|
|
||||||
if bareSku == nil {
|
|
||||||
bareSku = storeSkuSyncInfo2Bare(sku)
|
|
||||||
}
|
|
||||||
if sku.MergedStatus == model.SkuStatusNormal {
|
|
||||||
onlineList = append(onlineList, bareSku)
|
|
||||||
stockList = append(stockList, bareSku)
|
|
||||||
} else {
|
|
||||||
offlineList = append(offlineList, bareSku)
|
|
||||||
// 因为京东平台以是否有库存表示是否关注,所以不论是否可售,都要设置库存
|
|
||||||
stockList = append(stockList, bareSku)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if bareSku != nil {
|
|
||||||
skuMap[bareSku] = sku
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bareSku2Sync := func(bareSkuList []*partner.StoreSkuInfo) (skuList []*dao.StoreSkuSyncInfo) {
|
|
||||||
if len(bareSkuList) > 0 {
|
|
||||||
skuList = make([]*dao.StoreSkuSyncInfo, len(bareSkuList))
|
|
||||||
for k, v := range bareSkuList {
|
|
||||||
skuList[k] = skuMap[v]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return skuList
|
|
||||||
}
|
|
||||||
isContinueWhenError2 := true
|
|
||||||
realStoreID := int(utils.Str2Int64(vendorStoreID))
|
|
||||||
task := tasksch.NewParallelTask("SyncStoreSku4FakeJD", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError2), ctx,
|
|
||||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
|
||||||
step := batchItemList[0].(int)
|
|
||||||
switch step {
|
|
||||||
case 0:
|
|
||||||
for k, list := range [][]*partner.StoreSkuInfo{stockList /*, onlineList*/} {
|
|
||||||
if len(list) > 0 {
|
|
||||||
_, err = putils.FreeBatchStoreSkuInfo("更新门店商品库存", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) {
|
|
||||||
var failedList []*partner.StoreSkuInfoWithErr
|
|
||||||
failedList, err = storeSkuHandler.UpdateStoreSkusStock(ctx, storeDetail.VendorOrgCode, realStoreID, vendorStoreID, batchedStoreSkuList)
|
|
||||||
if len(failedList) > 0 {
|
|
||||||
task.AddFailedList(failedList)
|
|
||||||
}
|
|
||||||
successList := putils.UnselectStoreSkuListByVendorSkuIDs(batchedStoreSkuList, GetVendorSkuIDList(failedList))
|
|
||||||
if k == 0 && len(successList) > 0 {
|
|
||||||
updateStoreSku(dao.GetDB(), vendorID, bareSku2Sync(successList), model.SyncFlagStockMask)
|
|
||||||
}
|
|
||||||
return nil, len(successList), err
|
|
||||||
}, ctx, task, list, storeSkuHandler.GetStoreSkusBatchSize(partner.FuncUpdateStoreSkusStock), isContinueWhenError2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 1, 2:
|
|
||||||
statusList := onlineList
|
|
||||||
status := model.SkuStatusNormal
|
|
||||||
name := "可售门店商品"
|
|
||||||
if step == 2 {
|
|
||||||
statusList = offlineList
|
|
||||||
status = model.SkuStatusDontSale
|
|
||||||
name = "不可售门店商品"
|
|
||||||
}
|
|
||||||
if len(statusList) > 0 {
|
|
||||||
_, err = putils.FreeBatchStoreSkuInfo(name, func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) {
|
|
||||||
var failedList []*partner.StoreSkuInfoWithErr
|
|
||||||
failedList, err = storeSkuHandler.UpdateStoreSkusStatus(ctx, storeDetail.VendorOrgCode, realStoreID, vendorStoreID, batchedStoreSkuList, status)
|
|
||||||
if len(failedList) > 0 {
|
|
||||||
task.AddFailedList(failedList)
|
|
||||||
}
|
|
||||||
successList := putils.UnselectStoreSkuListByVendorSkuIDs(batchedStoreSkuList, GetVendorSkuIDList(failedList))
|
|
||||||
if len(successList) > 0 {
|
|
||||||
updateStoreSku(dao.GetDB(), vendorID, bareSku2Sync(successList), model.SyncFlagSaleMask)
|
|
||||||
}
|
|
||||||
return nil, len(successList), err
|
|
||||||
}, ctx, task, statusList, storeSkuHandler.GetStoreSkusBatchSize(partner.FuncUpdateStoreSkusStatus), isContinueWhenError2)
|
|
||||||
}
|
|
||||||
case 3:
|
|
||||||
if len(priceList) > 0 {
|
|
||||||
_, err = putils.FreeBatchStoreSkuInfo("更新门店商品价格2", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) {
|
|
||||||
var failedList []*partner.StoreSkuInfoWithErr
|
|
||||||
failedList, err = storeSkuHandler.UpdateStoreSkusPrice(ctx, storeDetail.VendorOrgCode, realStoreID, vendorStoreID, batchedStoreSkuList)
|
|
||||||
if len(failedList) > 0 {
|
|
||||||
task.AddFailedList(failedList)
|
|
||||||
}
|
|
||||||
successList := putils.UnselectStoreSkuListByVendorSkuIDs(batchedStoreSkuList, GetVendorSkuIDList(failedList))
|
|
||||||
if len(successList) > 0 {
|
|
||||||
updateStoreSku(dao.GetDB(), vendorID, bareSku2Sync(successList), model.SyncFlagPriceMask)
|
|
||||||
}
|
|
||||||
return nil, len(successList), err
|
|
||||||
}, ctx, task, priceList, storeSkuHandler.GetStoreSkusBatchSize(partner.FuncUpdateStoreSkusPrice), isContinueWhenError2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return retVal, err
|
|
||||||
}, []int{0, 1, 2, 3})
|
|
||||||
tasksch.HandleTask(task, parentTask, true).Run()
|
|
||||||
_, err = task.GetResult(0)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func SyncFakeJdStoreSku(ctx *jxcontext.Context, parentTask tasksch.ITask, storeMap, skuMap map[int]string, isAsync, isContinueWhenError bool) (hint string, err error) {
|
|
||||||
storeIDs := storeOrSkuMap2List(storeMap)
|
|
||||||
task := tasksch.NewParallelTask("同步假京东", nil, ctx,
|
|
||||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
|
||||||
storeID := batchItemList[0].(int)
|
|
||||||
err = SyncStoreSku4FakeJD(ctx, task, storeID, storeMap[storeID], skuMap, isContinueWhenError)
|
|
||||||
return retVal, err
|
|
||||||
}, storeIDs)
|
|
||||||
tasksch.HandleTask(task, parentTask, true).Run()
|
|
||||||
if isAsync {
|
|
||||||
hint = task.GetID()
|
|
||||||
} else {
|
|
||||||
_, err = task.GetResult(0)
|
|
||||||
hint = utils.Int2Str(len(storeIDs))
|
|
||||||
}
|
|
||||||
return hint, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func excel2FakeJdThingMap(ctx *jxcontext.Context, reader io.Reader) (thingMapList []*model.FakeJdThingMap, err error) {
|
|
||||||
xlsx, err := excelize.OpenReader(reader)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for sheetIndex := 0; sheetIndex < xlsx.SheetCount; sheetIndex++ {
|
|
||||||
rows, err2 := xlsx.GetRows(xlsx.GetSheetName(sheetIndex + 1))
|
|
||||||
if err2 != nil {
|
|
||||||
return nil, err2
|
|
||||||
}
|
|
||||||
for rowNum, row := range rows {
|
|
||||||
thingMap := &model.FakeJdThingMap{
|
|
||||||
JxID: int(utils.Str2Int64WithDefault(row[0], 0)),
|
|
||||||
JdID: utils.Str2Int64WithDefault(row[1], 0),
|
|
||||||
}
|
|
||||||
if thingMap.JxID == 0 || thingMap.JdID == 0 {
|
|
||||||
if rowNum == 0 {
|
|
||||||
continue
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if sheetIndex == 0 {
|
|
||||||
thingMap.ThingType = model.ThingTypeStore
|
|
||||||
} else {
|
|
||||||
thingMap.ThingType = model.ThingTypeSku
|
|
||||||
}
|
|
||||||
dao.WrapAddIDCULEntity(thingMap, ctx.GetUserName())
|
|
||||||
thingMapList = append(thingMapList, thingMap)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return thingMapList, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func getFakeThingMap(ctx *jxcontext.Context, db *dao.DaoDB) (storeMap, skuMap map[int]string, err error) {
|
|
||||||
var thingMapList []*model.FakeJdThingMap
|
|
||||||
err = dao.GetRows(db, &thingMapList, "SELECT t1.* FROM fake_jd_thing_map t1")
|
|
||||||
if err == nil {
|
|
||||||
storeMap, skuMap = make(map[int]string), make(map[int]string)
|
|
||||||
for _, v := range thingMapList {
|
|
||||||
if v.ThingType == model.ThingTypeStore {
|
|
||||||
storeMap[v.JxID] = utils.Int64ToStr(v.JdID)
|
|
||||||
} else {
|
|
||||||
skuMap[v.JxID] = utils.Int64ToStr(v.JdID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return storeMap, skuMap, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func UploadFakeJdThingMap(ctx *jxcontext.Context, reader io.Reader, isSyncNow, isAsync, isContinueWhenError bool) (hint string, err error) {
|
|
||||||
thingMapList, err := excel2FakeJdThingMap(ctx, reader)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
db := dao.GetDB()
|
|
||||||
txDB, _ := dao.Begin(db)
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
_, err = dao.ExecuteSQL(db, "DELETE t1 FROM fake_jd_thing_map t1")
|
|
||||||
if err != nil {
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
err = dao.CreateMultiEntities(db, thingMapList)
|
|
||||||
if err != nil {
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
dao.Commit(db, txDB)
|
|
||||||
|
|
||||||
if isSyncNow {
|
|
||||||
if storeMap, skuMap, err2 := getFakeThingMap(ctx, db); err2 == nil {
|
|
||||||
hint, err = SyncFakeJdStoreSku(ctx, nil, storeMap, skuMap, isAsync, isContinueWhenError)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
hint = utils.Int2Str(len(thingMapList))
|
|
||||||
}
|
|
||||||
return hint, err
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package cms
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSyncStoreSku4FakeJD(t *testing.T) {
|
|
||||||
skuMap := map[int]string{
|
|
||||||
22509: "2029937911",
|
|
||||||
}
|
|
||||||
err := SyncStoreSku4FakeJD(jxcontext.AdminCtx, nil, 100118, "11943257", skuMap, true)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUploadFakeJdThingMap(t *testing.T) {
|
|
||||||
file, err := os.Open("到家菜市门店与商品映射信息(1).xlsx")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
hint, err := UploadFakeJdThingMap(jxcontext.AdminCtx, file, true, false, true)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
t.Log(hint)
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
package cms
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner/putils"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestFreeBatchStoreSkuInfo(t *testing.T) {
|
|
||||||
var sku2Delete []*partner.StoreSkuInfo
|
|
||||||
for i := 0; i < 123; i++ {
|
|
||||||
sku2Delete = append(sku2Delete, &partner.StoreSkuInfo{
|
|
||||||
SkuID: i + 1,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx := jxcontext.AdminCtx
|
|
||||||
var parentTask tasksch.ITask
|
|
||||||
isContinueWhenError := true
|
|
||||||
handler, _ := partner.GetPurchasePlatformFromVendorID(model.VendorIDEBAI).(partner.ISingleStoreStoreSkuHandler)
|
|
||||||
_, err := putils.FreeBatchStoreSkuInfo("删除门店商品", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) {
|
|
||||||
t.Log(len(batchedStoreSkuList))
|
|
||||||
return nil, 0, err
|
|
||||||
}, ctx, parentTask, sku2Delete, handler.GetStoreSkusBatchSize(partner.FuncDeleteStoreSkus), isContinueWhenError)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetTimeMixByInt(t *testing.T) {
|
|
||||||
const (
|
|
||||||
time1 = 1100
|
|
||||||
time2 = 2300
|
|
||||||
time3 = 1200
|
|
||||||
time4 = 2400
|
|
||||||
)
|
|
||||||
a, b := GetTimeMixByInt(time1, time2, time3, time4)
|
|
||||||
fmt.Println(a, b)
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,207 +0,0 @@
|
|||||||
package cms
|
|
||||||
|
|
||||||
// var (
|
|
||||||
// LoginTypeFieldMap = map[string]string{
|
|
||||||
// mobile.LoginType: "tel",
|
|
||||||
// weixin.LoginType: "openid",
|
|
||||||
// weixin.LoginTypeMiniProgram: "openid_mini",
|
|
||||||
// }
|
|
||||||
// )
|
|
||||||
|
|
||||||
// func GetStoreUsers(ctx *jxcontext.Context, storeID int) (storeUserInfos []*dao.StoreUserInfo, err error) {
|
|
||||||
// sql := `
|
|
||||||
// SELECT t1.id, t1.jxstoreid, t1.openid, t1.tel, t1.nickname, t1.parentid, t3.tel parent_mobile,
|
|
||||||
// CONCAT("[", GROUP_CONCAT(CONCAT('{"id":', t2.id, ',"parentID":', t2.parentid, ',"tel":"', t2.tel, '","nickname":"', IF(t2.nickname IS NULL, "", t2.nickname), '"}')), "]") members_str
|
|
||||||
// FROM weixins t1
|
|
||||||
// LEFT JOIN weixins t2 ON t2.parentid = t1.id
|
|
||||||
// LEFT JOIN weixins t3 ON t1.parentid = t3.id
|
|
||||||
// WHERE t1.parentid = -1 AND t1.jxstoreid = ?
|
|
||||||
// GROUP BY 1,2,3,4,5,6,7;
|
|
||||||
// `
|
|
||||||
// if err = dao.GetRows(nil, &storeUserInfos, sql, storeID); err == nil {
|
|
||||||
// for _, storeUserInfo := range storeUserInfos {
|
|
||||||
// if storeUserInfo.MembersStr != "" {
|
|
||||||
// err = utils.UnmarshalUseNumber([]byte(storeUserInfo.MembersStr), &storeUserInfo.Members)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return storeUserInfos, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func GetUserInfo(ctx *jxcontext.Context, mobile string) (storeUserInfo *dao.StoreUserInfo, err error) {
|
|
||||||
// storeUserInfo, err = dao.GetUserStoreInfo(dao.GetDB(), "tel", mobile)
|
|
||||||
// globals.SugarLogger.Debugf("GetUserInfo:%s, token:%s, mobile:%s, storeUserInfo:%s, err:%v", ctx.GetTrackInfo(), ctx.GetToken(), mobile, utils.Format4Output(storeUserInfo, true), err)
|
|
||||||
// return storeUserInfo, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func GetSelfInfo(ctx *jxcontext.Context) (storeUserInfo *dao.StoreUserInfo, err error) {
|
|
||||||
// loginInfo := ctx.GetLoginInfo()
|
|
||||||
// if loginInfo == nil {
|
|
||||||
// return nil, auth.ErrAPINeedRealLogin
|
|
||||||
// }
|
|
||||||
// fieldName := LoginTypeFieldMap[loginInfo.GetAuthType()]
|
|
||||||
// if fieldName == "" {
|
|
||||||
// return nil, auth.ErrIllegalLoginType
|
|
||||||
// }
|
|
||||||
// storeUserInfo, err = dao.GetUserStoreInfo(dao.GetDB(), fieldName, loginInfo.GetAuthID())
|
|
||||||
// return storeUserInfo, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func GetMyStoreList(ctx *jxcontext.Context) (storeList []*dao.StoreWithCityName, err error) {
|
|
||||||
// mobileNum, _ := ctx.GetMobileAndUserID()
|
|
||||||
// if mobileNum == "" {
|
|
||||||
// return nil, fmt.Errorf("不能得到用户手机号")
|
|
||||||
// }
|
|
||||||
// storeList, err = dao.GetStoreListByMobile(dao.GetDB(), mobileNum)
|
|
||||||
// return storeList, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func UnbindMobile(ctx *jxcontext.Context, mobile string) (num int64, err error) {
|
|
||||||
// db := dao.GetDB()
|
|
||||||
// num, err = dao.UpdateEntityByKV(db, &legacymodel.WeiXins{}, map[string]interface{}{
|
|
||||||
// "JxStoreID": 0,
|
|
||||||
// "ParentID": -1,
|
|
||||||
// }, map[string]interface{}{
|
|
||||||
// "Tel": mobile,
|
|
||||||
// })
|
|
||||||
// if err == nil {
|
|
||||||
// jxutils.HandleUserWXRemark(db, mobile, false)
|
|
||||||
// TransferLegacyWeixins(mobile)
|
|
||||||
// }
|
|
||||||
// return num, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func BindMobile2Store(ctx *jxcontext.Context, mobile string, storeID int) (num int64, err error) {
|
|
||||||
// db := dao.GetDB()
|
|
||||||
// user, err2 := verifyMobileIsBlank(db, mobile)
|
|
||||||
// if err = err2; err == nil || err == orm.ErrNoRows {
|
|
||||||
// user.JxStoreID = storeID
|
|
||||||
// if err == nil {
|
|
||||||
// txDB , _ := dao.Begin(db)
|
|
||||||
// defer func() {
|
|
||||||
// if r := recover(); r != nil {
|
|
||||||
// dao.Rollback(db, txDB)
|
|
||||||
// panic(r)
|
|
||||||
// }
|
|
||||||
// }()
|
|
||||||
// if num, err = dao.UpdateEntity(db, user, "JxStoreID"); err == nil {
|
|
||||||
// err = dao.SetWeiXinsEmpty2Null(db, user)
|
|
||||||
// }
|
|
||||||
// if err != nil {
|
|
||||||
// dao.Rollback(db, txDB)
|
|
||||||
// } else {
|
|
||||||
// dao.Commit(db, txDB)
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// // globals.SugarLogger.Debug(utils.Format4Output(user, false))
|
|
||||||
// dao.WrapAddIDCULEntity(user, ctx.GetUserName())
|
|
||||||
// user.ParentID = -1
|
|
||||||
// if err = dao.CreateWeiXins(db, user); err == nil {
|
|
||||||
// num = 1
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if err == nil {
|
|
||||||
// jxutils.HandleUserWXRemark(db, mobile, false)
|
|
||||||
// TransferLegacyWeixins(mobile)
|
|
||||||
// }
|
|
||||||
// return num, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func AddMobile2Mobile(ctx *jxcontext.Context, parentMobile, mobile string) (num int64, err error) {
|
|
||||||
// db := dao.GetDB()
|
|
||||||
// parentUser := &legacymodel.WeiXins{}
|
|
||||||
// parentUser.Tel = parentMobile
|
|
||||||
// if err = dao.GetEntity(db, parentUser, "Tel"); err == nil {
|
|
||||||
// if parentUser.ParentID == -1 {
|
|
||||||
// if err = verifyMobileHasNoMembers(db, mobile); err == nil {
|
|
||||||
// user, err2 := verifyMobileIsBlank(db, mobile)
|
|
||||||
// if err = err2; err == nil || err == orm.ErrNoRows {
|
|
||||||
// user.ParentID = parentUser.ID
|
|
||||||
// if err == nil {
|
|
||||||
// // todo transaction
|
|
||||||
// if num, err = dao.UpdateEntity(db, user, "ParentID"); err == nil {
|
|
||||||
// err = dao.SetWeiXinsEmpty2Null(db, user)
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// dao.WrapAddIDCULEntity(user, ctx.GetUserName())
|
|
||||||
// if err = dao.CreateWeiXins(db, user); err == nil {
|
|
||||||
// num = 1
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// err = fmt.Errorf("%s本身是成员", parentMobile)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if err == nil {
|
|
||||||
// jxutils.HandleUserWXRemark(db, mobile, false)
|
|
||||||
// TransferLegacyWeixins(mobile)
|
|
||||||
// }
|
|
||||||
// return num, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func ChangeMobile(ctx *jxcontext.Context, curMobile, expectedMobile string) (num int64, err error) {
|
|
||||||
// num, err = dao.UpdateEntityByKV(nil, &legacymodel.WeiXins{}, map[string]interface{}{
|
|
||||||
// "Tel": expectedMobile,
|
|
||||||
// }, map[string]interface{}{
|
|
||||||
// "Tel": curMobile,
|
|
||||||
// })
|
|
||||||
// if err == nil {
|
|
||||||
// TransferLegacyWeixins(curMobile)
|
|
||||||
// TransferLegacyWeixins(expectedMobile)
|
|
||||||
// }
|
|
||||||
// return num, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func verifyMobileIsBlank(db *dao.DaoDB, mobile string) (user *legacymodel.WeiXins, err error) {
|
|
||||||
// if !jxutils.IsStringLikeMobile(mobile) {
|
|
||||||
// return nil, fmt.Errorf("%s看起来不像是一个手机号", mobile)
|
|
||||||
// }
|
|
||||||
// user = &legacymodel.WeiXins{
|
|
||||||
// Tel: mobile,
|
|
||||||
// }
|
|
||||||
// if err = dao.GetEntity(db, user, "Tel"); err == nil {
|
|
||||||
// if user.ParentID != -1 && user.ParentID != 0 {
|
|
||||||
// userParent := &legacymodel.WeiXins{
|
|
||||||
// ID: user.ParentID,
|
|
||||||
// }
|
|
||||||
// if err = dao.GetEntity(db, userParent); err != nil && err != orm.ErrNoRows {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
// if err != orm.ErrNoRows {
|
|
||||||
// err = fmt.Errorf("%s已经是组长:%s,门店:%d的小组成员", mobile, userParent.Tel, userParent.JxStoreID)
|
|
||||||
// } else {
|
|
||||||
// err = nil
|
|
||||||
// }
|
|
||||||
// } else if user.JxStoreID != 0 {
|
|
||||||
// store := &model.Store{}
|
|
||||||
// store.ID = user.JxStoreID
|
|
||||||
// if err = dao.GetEntity(db, store); err == nil {
|
|
||||||
// err = fmt.Errorf("%s本身已经是门店:%d的组长", mobile, user.JxStoreID)
|
|
||||||
// } else if dao.IsNoRowsError(err) {
|
|
||||||
// err = nil
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return user, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func verifyMobileHasNoMembers(db *dao.DaoDB, mobile string) (err error) {
|
|
||||||
// countInfo := &struct{ Ct int }{}
|
|
||||||
// if err = dao.GetRow(db, countInfo, `
|
|
||||||
// SELECT COUNT(*) ct
|
|
||||||
// FROM weixins t1
|
|
||||||
// JOIN weixins t2 ON t1.parentid = t2.id AND t2.tel = ?
|
|
||||||
// `, mobile); err == nil {
|
|
||||||
// if countInfo.Ct > 0 {
|
|
||||||
// user := &legacymodel.WeiXins{
|
|
||||||
// Tel: mobile,
|
|
||||||
// }
|
|
||||||
// dao.GetEntity(db, user, "Tel")
|
|
||||||
// err = fmt.Errorf("%s本身已经是门店:%d组长", mobile, user.JxStoreID)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,23 +0,0 @@
|
|||||||
package cms
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
|
|
||||||
_ "git.rosy.net.cn/jx-callback/globals/api/apimanager"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestTryAddStoreBossRole4User(t *testing.T) {
|
|
||||||
err := TryAddStoreBossRole4User(jxcontext.AdminCtx, &model.User{
|
|
||||||
Type: model.UserTypeStoreBoss,
|
|
||||||
UserID: "24058800CD3711E991B2525400E86DC0",
|
|
||||||
Mobile: utils.String2Pointer("91112345678"),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
package cms
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"gopkg.in/go-playground/validator.v9"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
unitNamesMap map[string]int
|
|
||||||
specUnitNamesMap map[string]int
|
|
||||||
validate = validator.New()
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
unitNamesMap = jxutils.MakeValidationMapFromSlice(model.UnitNames, 1)
|
|
||||||
specUnitNamesMap = jxutils.MakeValidationMapFromSlice(model.SpecUnitNames, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func validateStringInMap(name string, value interface{}, flagMap map[string]int) (err error) {
|
|
||||||
if strValue, ok := value.(string); ok {
|
|
||||||
if flagMap[strValue] == 1 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fmt.Errorf("属性%s类型或取值不合法,要求string", name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ValidateUnit(value interface{}) (err error) {
|
|
||||||
return validateStringInMap("Unit", value, unitNamesMap)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ValidateSpecUnit(value interface{}) (err error) {
|
|
||||||
return validateStringInMap("SpecUnit", value, specUnitNamesMap)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ValidateStruct(value interface{}) (err error) {
|
|
||||||
return validate.Struct(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ValidateVar(value interface{}, tag string) (err error) {
|
|
||||||
return validate.Var(value, tag)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ValidateStructPartial(value interface{}, fields ...string) (err error) {
|
|
||||||
return validate.StructPartial(value, fields...)
|
|
||||||
}
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
package cms
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner/purchase/mtwm"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetMtSkuDetailInfo 获取美团商品信息,暂时只支持美团
|
|
||||||
func GetMtSkuDetailInfo(ctx *jxcontext.Context, vendorOrderID string, vendorSkuName string) (outSkuNameExt *model.SkuNameExt, err error) {
|
|
||||||
orderDetail, err := partner.CurOrderManager.LoadOrder(vendorOrderID, model.VendorIDMTWM)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取订单详情
|
|
||||||
mtApi := mtwm.GetAPI(orderDetail.VendorOrgCode, orderDetail.JxStoreID, orderDetail.VendorStoreID)
|
|
||||||
mtOrderDetail, err := mtApi.OrderGetOrderDetail(utils.Str2Int64(vendorOrderID), false)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var detail []map[string]interface{}
|
|
||||||
if err = utils.UnmarshalUseNumber([]byte(mtOrderDetail["detail"].(string)), &detail); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
mtCode := ""
|
|
||||||
for _, product := range detail {
|
|
||||||
if product["food_name"].(string) == vendorSkuName {
|
|
||||||
if product["app_food_code"].(string) == "" {
|
|
||||||
return nil, fmt.Errorf("[%s] 未获取到商品的美团code,无法创建商品", vendorSkuName)
|
|
||||||
}
|
|
||||||
mtCode = product["app_food_code"].(string)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if mtCode == "" {
|
|
||||||
return nil, fmt.Errorf("[%s] 未获取到商品的美团code,无法创建商品", vendorSkuName)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取美团商品详情
|
|
||||||
mtSkuDetail, err := mtApi.RetailGet(orderDetail.VendorStoreID, mtCode)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
skuName := &model.SkuNameExt{
|
|
||||||
SkuName: model.SkuName{
|
|
||||||
Prefix: "",
|
|
||||||
Name: mtSkuDetail.Name,
|
|
||||||
Upc: utils.String2Pointer(mtSkuDetail.UpcCode),
|
|
||||||
Status: 1,
|
|
||||||
CategoryID: 291, // ?
|
|
||||||
IsGlobal: 1,
|
|
||||||
Unit: mtSkuDetail.Unit,
|
|
||||||
Price: utils.Float64TwoInt(mtSkuDetail.Price * float64(100)),
|
|
||||||
DescImg: mtSkuDetail.PictureContents,
|
|
||||||
JdsStockSwitch: 1,
|
|
||||||
PreparationTime: 0,
|
|
||||||
MtAttribute: "",
|
|
||||||
// 京西创建是传入的属性
|
|
||||||
// [{"attr_id":"1200000088","attr_name":"品牌","valueList":[{"value":"其他"}]},{"attr_id":"1200000135","attr_name":"包装方式","valueList":[{"value_id":"1300000231","value":"袋装"}]}]
|
|
||||||
// 美团获取的属性,不太好转换,暂时不弄
|
|
||||||
// [{"attrId":1200000202,"attrName":"品种","setAttrId":true,"setAttrName":true,"setValueList":true,"valueList":[{"setValue":true,"setValueId":true,"value":"二荆条","valueId":1300015565}],"valueListIterator":[{"$ref":"$[0].valueList[0]"}],"valueListSize":1},{"attrId":1200000135,"attrName":"包装方式","setAttrId":true,"setAttrName":true,"setValueList":true,"valueList":[{"setValue":true,"setValueId":true,"value":"散装","valueId":1300000232}],"valueListIterator":[{"$ref":"$[1].valueList[0]"}],"valueListSize":1}]
|
|
||||||
},
|
|
||||||
Skus: nil,
|
|
||||||
MtwmCategoryID: utils.Int2Str(mtSkuDetail.TagID),
|
|
||||||
}
|
|
||||||
|
|
||||||
skus := make([]*model.SkuWithVendor, 0, 0)
|
|
||||||
for _, mtSks := range mtSkuDetail.SkuList {
|
|
||||||
sku := &model.SkuWithVendor{
|
|
||||||
Sku: &model.Sku{
|
|
||||||
MinOrderCount: utils.Str2Int(mtSks.MinOrderCount),
|
|
||||||
LadderBoxNum: utils.Str2Int(mtSks.LadderBoxNum),
|
|
||||||
LadderBoxPrice: utils.Float64TwoInt(utils.Str2Float64(mtSks.Price) * float64(100)),
|
|
||||||
SpecQuality: float32(utils.Str2Float64(mtSks.Weight)),
|
|
||||||
Weight: utils.Str2Int(mtSks.Weight),
|
|
||||||
SpecUnit: mtSks.Unit,
|
|
||||||
Status: 1,
|
|
||||||
Comment: "",
|
|
||||||
EclpID: "",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
skus = append(skus, sku)
|
|
||||||
}
|
|
||||||
skuName.Skus = skus
|
|
||||||
|
|
||||||
mTImg2Jx(skuName, mtSkuDetail.PictureList)
|
|
||||||
return AddSkuName(ctx, skuName, ctx.GetUserName())
|
|
||||||
}
|
|
||||||
|
|
||||||
func mTImg2Jx(sku *model.SkuNameExt, pictureList []string) {
|
|
||||||
switch len(pictureList) {
|
|
||||||
case 0:
|
|
||||||
return
|
|
||||||
case 1:
|
|
||||||
sku.Img = pictureList[0]
|
|
||||||
case 2:
|
|
||||||
sku.Img = pictureList[0]
|
|
||||||
sku.Img2 = pictureList[1]
|
|
||||||
case 3:
|
|
||||||
sku.Img = pictureList[0]
|
|
||||||
sku.Img2 = pictureList[1]
|
|
||||||
sku.Img3 = pictureList[2]
|
|
||||||
case 4:
|
|
||||||
sku.Img = pictureList[0]
|
|
||||||
sku.Img2 = pictureList[1]
|
|
||||||
sku.Img3 = pictureList[2]
|
|
||||||
sku.Img4 = pictureList[3]
|
|
||||||
case 5:
|
|
||||||
sku.Img = pictureList[0]
|
|
||||||
sku.Img2 = pictureList[1]
|
|
||||||
sku.Img3 = pictureList[2]
|
|
||||||
sku.Img4 = pictureList[3]
|
|
||||||
sku.Img5 = pictureList[4]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,14 +2,14 @@ package common
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.rosy.net.cn/baseapi/platformapi/tencent_map"
|
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/baseapi/platformapi/autonavi"
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/dao"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
"git.rosy.net.cn/jx-callback/globals/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -40,7 +40,6 @@ type Store4User struct {
|
|||||||
|
|
||||||
Distance int `json:"distance"`
|
Distance int `json:"distance"`
|
||||||
WalkDistance int `json:"walkDistance"`
|
WalkDistance int `json:"walkDistance"`
|
||||||
DeliverySelf int `json:"deliverySelf"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Store4UserList []*Store4User
|
type Store4UserList []*Store4User
|
||||||
@@ -68,7 +67,7 @@ func GetNearSupplyGoodsStoreByStoreID(ctx *jxcontext.Context, storeID int) (stor
|
|||||||
stores []*model.Store
|
stores []*model.Store
|
||||||
db = dao.GetDB()
|
db = dao.GetDB()
|
||||||
)
|
)
|
||||||
store2, _ := dao.GetStoreDetail(db, storeID, model.VendorIDJX, "")
|
store2, _ := dao.GetStoreDetail(db, storeID, model.VendorIDJX)
|
||||||
if store2 == nil {
|
if store2 == nil {
|
||||||
return nil, fmt.Errorf("该门店未绑定京西平台!storeID: %v", storeID)
|
return nil, fmt.Errorf("该门店未绑定京西平台!storeID: %v", storeID)
|
||||||
}
|
}
|
||||||
@@ -91,7 +90,7 @@ func GetNearSupplyGoodsStoreByStoreID(ctx *jxcontext.Context, storeID int) (stor
|
|||||||
utils.DefaultTimeValue, utils.DefaultTimeValue,
|
utils.DefaultTimeValue, utils.DefaultTimeValue,
|
||||||
model.VendorIDJX, model.YES, model.StoreStatusOpened,
|
model.VendorIDJX, model.YES, model.StoreStatusOpened,
|
||||||
}
|
}
|
||||||
err = dao.GetRows(db, &stores, sql, sqlParams...)
|
err = dao.GetRows(db, &stores, sql, sqlParams)
|
||||||
if len(stores) > 0 {
|
if len(stores) > 0 {
|
||||||
realDistance := float64(0)
|
realDistance := float64(0)
|
||||||
for _, v := range stores {
|
for _, v := range stores {
|
||||||
@@ -110,7 +109,7 @@ func GetNearSupplyGoodsStoreByStoreID(ctx *jxcontext.Context, storeID int) (stor
|
|||||||
return store, err
|
return store, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetStoreListByLocation(ctx *jxcontext.Context, lng, lat float64, maxRadius int, needWalkDistance, isJds bool, brandID []int) (storeList []*Store4User, err error) {
|
func GetStoreListByLocation(ctx *jxcontext.Context, lng, lat float64, maxRadius int, needWalkDistance, isJds bool) (storeList []*Store4User, err error) {
|
||||||
const (
|
const (
|
||||||
maxStoreCount4User = 5
|
maxStoreCount4User = 5
|
||||||
)
|
)
|
||||||
@@ -124,34 +123,29 @@ func GetStoreListByLocation(ctx *jxcontext.Context, lng, lat float64, maxRadius
|
|||||||
_, lat2 := jxutils.ConvertDistanceToLogLat(lng, lat, float64(maxRadius), 0)
|
_, lat2 := jxutils.ConvertDistanceToLogLat(lng, lat, float64(maxRadius), 0)
|
||||||
lng1 := lng - (lng2 - lng)
|
lng1 := lng - (lng2 - lng)
|
||||||
lat1 := lat - (lat2 - lat)
|
lat1 := lat - (lat2 - lat)
|
||||||
|
// globals.SugarLogger.Debugf("%f,%f,%f,%f\n", lng1, lng2, lat1, lat2)
|
||||||
if !isJds {
|
if !isJds {
|
||||||
sql = `
|
sql = `
|
||||||
SELECT t1.*,
|
SELECT t1.*,
|
||||||
city.name city_name,sm.delivery_self
|
city.name city_name
|
||||||
FROM store t1
|
FROM store t1
|
||||||
JOIN place city ON city.code = t1.city_code
|
JOIN place city ON city.code = t1.city_code
|
||||||
JOIN store_map sm ON sm.store_id = t1.id AND sm.vendor_id = ? AND sm.deleted_at = ? AND sm.status <> ?
|
JOIN store_map sm ON sm.store_id = t1.id AND sm.vendor_id = ? AND sm.deleted_at = ? AND sm.status <> ?
|
||||||
WHERE t1.deleted_at = ? AND t1.status <> ? AND t1.lng > ? AND t1.lng < ? AND t1.lat > ? AND t1.lat < ?
|
WHERE t1.deleted_at = ? AND t1.status <> ? AND t1.lng > ? AND t1.lng < ? AND t1.lat > ? AND t1.lat < ?
|
||||||
AND sm.is_order <> ?
|
AND sm.is_order <> ?
|
||||||
AND t1.id <> ?
|
AND t1.id <> ?
|
||||||
|
ORDER BY t1.id
|
||||||
`
|
`
|
||||||
sqlParams = append(sqlParams,
|
sqlParams = []interface{}{
|
||||||
model.VendorIDJX, utils.DefaultTimeValue, model.StoreStatusDisabled,
|
model.VendorIDJX, utils.DefaultTimeValue, model.StoreStatusDisabled,
|
||||||
utils.DefaultTimeValue, model.StoreStatusDisabled, jxutils.StandardCoordinate2Int(lng1), jxutils.StandardCoordinate2Int(lng2), jxutils.StandardCoordinate2Int(lat1), jxutils.StandardCoordinate2Int(lat2),
|
utils.DefaultTimeValue, model.StoreStatusDisabled, jxutils.StandardCoordinate2Int(lng1), jxutils.StandardCoordinate2Int(lng2), jxutils.StandardCoordinate2Int(lat1), jxutils.StandardCoordinate2Int(lat2),
|
||||||
model.YES,
|
model.YES,
|
||||||
model.MatterStoreID,
|
model.MatterStoreID,
|
||||||
)
|
|
||||||
if len(brandID) != 0 {
|
|
||||||
sql += " AND t1.brand_id IN (" + dao.GenQuestionMarks(len(brandID)) + ")"
|
|
||||||
sqlParams = append(sqlParams, brandID)
|
|
||||||
}
|
}
|
||||||
sql += `
|
|
||||||
ORDER BY t1.id
|
|
||||||
`
|
|
||||||
} else {
|
} else {
|
||||||
sql = `
|
sql = `
|
||||||
SELECT t1.*,
|
SELECT t1.*,
|
||||||
city.name city_name,sm.delivery_self
|
city.name city_name
|
||||||
FROM store t1
|
FROM store t1
|
||||||
JOIN place city ON city.code = t1.city_code
|
JOIN place city ON city.code = t1.city_code
|
||||||
JOIN store_map sm ON sm.store_id = t1.id AND sm.vendor_id = ? AND sm.deleted_at = ? AND sm.status = ?
|
JOIN store_map sm ON sm.store_id = t1.id AND sm.vendor_id = ? AND sm.deleted_at = ? AND sm.status = ?
|
||||||
@@ -185,12 +179,12 @@ func GetStoreListByLocation(ctx *jxcontext.Context, lng, lat float64, maxRadius
|
|||||||
city.name city_name
|
city.name city_name
|
||||||
FROM store t1
|
FROM store t1
|
||||||
JOIN place city ON city.code = t1.city_code
|
JOIN place city ON city.code = t1.city_code
|
||||||
WHERE t1.deleted_at = ? AND t1.id = ?
|
WHERE t1.deleted_at = ? AND t1.status <> ? AND t1.id = ?
|
||||||
`
|
`
|
||||||
sqlParams2 := []interface{}{
|
sqlParams2 := []interface{}{
|
||||||
// model.VendorIDJX, utils.DefaultTimeValue, model.StoreStatusDisabled,
|
// model.VendorIDJX, utils.DefaultTimeValue, model.StoreStatusDisabled,
|
||||||
utils.DefaultTimeValue,
|
utils.DefaultTimeValue,
|
||||||
// model.StoreStatusDisabled,
|
model.StoreStatusDisabled,
|
||||||
// jxutils.StandardCoordinate2Int(0),
|
// jxutils.StandardCoordinate2Int(0),
|
||||||
// jxutils.StandardCoordinate2Int(10000),
|
// jxutils.StandardCoordinate2Int(10000),
|
||||||
// jxutils.StandardCoordinate2Int(0),
|
// jxutils.StandardCoordinate2Int(0),
|
||||||
@@ -206,14 +200,14 @@ func GetStoreListByLocation(ctx *jxcontext.Context, lng, lat float64, maxRadius
|
|||||||
|
|
||||||
// 如果要求以步行距离来算
|
// 如果要求以步行距离来算
|
||||||
if needWalkDistance {
|
if needWalkDistance {
|
||||||
var coordList []*tencent_map.Coordinate
|
var coordList []*autonavi.Coordinate
|
||||||
for _, v := range storeList2 {
|
for _, v := range storeList2 {
|
||||||
coordList = append(coordList, &tencent_map.Coordinate{
|
coordList = append(coordList, &autonavi.Coordinate{
|
||||||
Lng: v.FloatLng,
|
Lng: v.FloatLng,
|
||||||
Lat: v.FloatLat,
|
Lat: v.FloatLat,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if distanceList, err2 := api.TencentMapAPI.BatchWalkingDistance(lng, lat, coordList); err2 == nil {
|
if distanceList, err2 := api.AutonaviAPI.BatchWalkingDistance(lng, lat, coordList); err2 == nil {
|
||||||
for k, v := range storeList2 {
|
for k, v := range storeList2 {
|
||||||
v.WalkDistance = int(distanceList[k])
|
v.WalkDistance = int(distanceList[k])
|
||||||
}
|
}
|
||||||
@@ -230,69 +224,3 @@ func GetStoreListByLocation(ctx *jxcontext.Context, lng, lat float64, maxRadius
|
|||||||
}
|
}
|
||||||
return storeList, err
|
return storeList, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetVendorOrgCode(ctx *jxcontext.Context, vendorID int, vendorOrgCode, vendorType string) (vendorOrgs []*model.VendorOrgCode, err error) {
|
|
||||||
return dao.GetVendorOrgCode(dao.GetDB(), vendorID, vendorOrgCode, vendorType)
|
|
||||||
}
|
|
||||||
|
|
||||||
func UpdateVendorOrgCode(ctx *jxcontext.Context, ID int, payload map[string]interface{}) (err error) {
|
|
||||||
var (
|
|
||||||
db = dao.GetDB()
|
|
||||||
vendorOrgCode = &model.VendorOrgCode{}
|
|
||||||
)
|
|
||||||
vendorOrgCode.ID = ID
|
|
||||||
err = dao.GetEntity(db, vendorOrgCode)
|
|
||||||
valid := dao.StrictMakeMapByStructObject(payload, vendorOrgCode, ctx.GetUserName())
|
|
||||||
if len(valid) > 0 {
|
|
||||||
if valid["key"] != nil {
|
|
||||||
valid["vendorOrgCode"] = valid["key"]
|
|
||||||
delete(valid, "key")
|
|
||||||
}
|
|
||||||
if valid["code"] != nil {
|
|
||||||
valid["vendorID"] = valid["code"]
|
|
||||||
delete(valid, "code")
|
|
||||||
}
|
|
||||||
if valid["name"] != nil {
|
|
||||||
valid["comment"] = valid["name"]
|
|
||||||
delete(valid, "name")
|
|
||||||
}
|
|
||||||
txDB, _ := dao.Begin(db)
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
if _, err = dao.UpdateEntityLogically(db, vendorOrgCode, valid, ctx.GetUserName(), nil); err != nil {
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
dao.Commit(db, txDB)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func AddVendorOrgCode(ctx *jxcontext.Context, vendorOrgCode *model.VendorOrgCode) (err error) {
|
|
||||||
var (
|
|
||||||
db = dao.GetDB()
|
|
||||||
)
|
|
||||||
list, err := dao.GetVendorOrgCode(db, vendorOrgCode.VendorID, vendorOrgCode.VendorOrgCode, model.VendorOrgTypePlatform)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if len(list) > 0 {
|
|
||||||
vendorOrgCode.ID = list[0].ID
|
|
||||||
_, err = dao.UpdateEntity(db, vendorOrgCode, "token", "updated_at", "app_key", "app_secret", "comment", "vendor_org_code")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var userName string
|
|
||||||
if ctx != nil {
|
|
||||||
userName = ctx.GetUserName()
|
|
||||||
} else {
|
|
||||||
userName = "system"
|
|
||||||
}
|
|
||||||
dao.WrapAddIDCULDEntity(vendorOrgCode, userName)
|
|
||||||
dao.CreateEntity(db, vendorOrgCode)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,34 +1,29 @@
|
|||||||
package event
|
package event
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/dao"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
NoUseEventMap = map[string]string{
|
NoUseEventMap = map[string]string{
|
||||||
"CreateQrOrBarCode": "CreateQrOrBarCode",
|
"CreateQrOrBarCode": "CreateQrOrBarCode",
|
||||||
"StatisticsReportForOrders": "StatisticsReportForOrders",
|
"StatisticsReportForOrders": "StatisticsReportForOrders",
|
||||||
|
"UpdateUser": "UpdateUser",
|
||||||
}
|
}
|
||||||
regexpToken = regexp.MustCompile(`,"token":".*"`)
|
regexpToken = regexp.MustCompile(`,"token":".*"`)
|
||||||
)
|
)
|
||||||
|
|
||||||
type CheckCookie struct {
|
const (
|
||||||
VendorID int `json:"vendorID"`
|
sysMessageTitle = ""
|
||||||
VendorOrgCode string `json:"vendorOrgCode"`
|
)
|
||||||
Status string `json:"status"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func AddOperateEvent(ctx *jxcontext.Context, accessUUID, jsonData string, errCode, errMsg string, useTime int, apiFunctionSpec string) (err error) {
|
func AddOperateEvent(ctx *jxcontext.Context, accessUUID, jsonData string, errCode, errMsg string, useTime int, apiFunctionSpec string) (err error) {
|
||||||
var (
|
var (
|
||||||
@@ -48,7 +43,7 @@ func AddOperateEvent(ctx *jxcontext.Context, accessUUID, jsonData string, errCod
|
|||||||
}
|
}
|
||||||
if apiFunction != "" {
|
if apiFunction != "" {
|
||||||
if apiFunction[0:3] == "Get" || NoUseEventMap[apiFunction] != "" {
|
if apiFunction[0:3] == "Get" || NoUseEventMap[apiFunction] != "" {
|
||||||
return errors.New("未知错误")
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if accessUUID != "" {
|
if accessUUID != "" {
|
||||||
@@ -68,7 +63,7 @@ func AddOperateEvent(ctx *jxcontext.Context, accessUUID, jsonData string, errCod
|
|||||||
ErrMsg: errMsg,
|
ErrMsg: errMsg,
|
||||||
UseTime: useTime,
|
UseTime: useTime,
|
||||||
}
|
}
|
||||||
txDB, err := dao.Begin(db)
|
txDB, _ := dao.Begin(db)
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
dao.Rollback(db, txDB)
|
dao.Rollback(db, txDB)
|
||||||
@@ -134,67 +129,3 @@ func GetOperateEvents(ctx *jxcontext.Context, name string, apiFunctions []string
|
|||||||
}
|
}
|
||||||
return pageInfo, err
|
return pageInfo, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetCheckVendorCookie(ctx *jxcontext.Context, vendorIDs []int, isAuto bool) (ccList []*CheckCookie, err error) {
|
|
||||||
var (
|
|
||||||
ebaiOrderID = "1577329467196263592"
|
|
||||||
ebaiErr = "return not json"
|
|
||||||
ebaiErr2 = "系统错误"
|
|
||||||
mtStoreID = "7388603"
|
|
||||||
mtErr = "返回结果格式不正常"
|
|
||||||
jdUpcCode = "6952395700895"
|
|
||||||
jdErr = "请输入用户名"
|
|
||||||
// mtpsErr = "用户未登录"
|
|
||||||
errMsg = ""
|
|
||||||
)
|
|
||||||
for _, v := range vendorIDs {
|
|
||||||
cc := &CheckCookie{}
|
|
||||||
var flag = false
|
|
||||||
switch v {
|
|
||||||
case model.VendorIDEBAI:
|
|
||||||
resultMap, err := api.EbaiAPI.GetStoreOrderInfo(ebaiOrderID)
|
|
||||||
if len(resultMap) < 1 && err != nil {
|
|
||||||
if strings.Contains(err.Error(), ebaiErr) || strings.Contains(err.Error(), ebaiErr2) {
|
|
||||||
errMsg += fmt.Sprintf(" 饿百账号:[%v]的Cookie无效了!", v)
|
|
||||||
flag = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case model.VendorIDMTWM:
|
|
||||||
_, err := api.MtwmAPI.PackagePriceGet(mtStoreID)
|
|
||||||
if err != nil {
|
|
||||||
if strings.Contains(err.Error(), mtErr) {
|
|
||||||
errMsg += fmt.Sprintf(" 美团账号:[%v]的Cookie无效了!", v)
|
|
||||||
flag = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case model.VendorIDJD:
|
|
||||||
result, err := api.JdAPI.GetJdUpcCodeByName("", jdUpcCode, 1, 5)
|
|
||||||
if len(result) < 1 && err != nil {
|
|
||||||
if strings.Contains(err.Error(), jdErr) {
|
|
||||||
errMsg += fmt.Sprintf(" 京东账号:[%v]的Cookie无效了!", v)
|
|
||||||
flag = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case model.VendorIDJDShop:
|
|
||||||
_, err := api.JdShopAPI.OrderDetail("124350112427")
|
|
||||||
if err != nil {
|
|
||||||
if strings.Contains(err.Error(), "登录") {
|
|
||||||
errMsg += fmt.Sprintf("京东商城:[%v]的Cookie无效了!", v)
|
|
||||||
flag = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cc.VendorID = v
|
|
||||||
cc.VendorOrgCode = ""
|
|
||||||
if flag {
|
|
||||||
cc.Status = "无效"
|
|
||||||
} else {
|
|
||||||
cc.Status = "有效"
|
|
||||||
}
|
|
||||||
ccList = append(ccList, cc)
|
|
||||||
}
|
|
||||||
if isAuto && errMsg != "" {
|
|
||||||
globals.SugarLogger.Warnf("GetCheckVendorCookie:[%v]", errMsg)
|
|
||||||
}
|
|
||||||
return ccList, err
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,122 +0,0 @@
|
|||||||
package financial
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"mime/multipart"
|
|
||||||
"path"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/weixinmsg"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/legacymodel"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
|
||||||
"github.com/qiniu/api.v7/storage"
|
|
||||||
)
|
|
||||||
|
|
||||||
type tUploadFileInfo struct {
|
|
||||||
FileHeader *multipart.FileHeader
|
|
||||||
StoreID int
|
|
||||||
}
|
|
||||||
|
|
||||||
func SendFilesToStores(ctx *jxcontext.Context, files []*multipart.FileHeader, title, shopName string, isAsync bool, userName string) (hint string, err error) {
|
|
||||||
if len(files) == 0 {
|
|
||||||
return "", errors.New("没有文件上传!")
|
|
||||||
}
|
|
||||||
|
|
||||||
fileList := make([]*tUploadFileInfo, len(files))
|
|
||||||
for k, fileHeader := range files {
|
|
||||||
fileList[k] = &tUploadFileInfo{
|
|
||||||
FileHeader: fileHeader,
|
|
||||||
}
|
|
||||||
fileNameParts := strings.Split(fileHeader.Filename, "_")
|
|
||||||
if len(fileNameParts) < 3 {
|
|
||||||
return "", fmt.Errorf("文件名:%s不规范,没有包含三个必要的部分", fileHeader.Filename)
|
|
||||||
}
|
|
||||||
fileList[k].StoreID = int(utils.Str2Int64WithDefault(fileNameParts[0], 0))
|
|
||||||
// 果园和菜市账号冲突,果园门店ID调整变大
|
|
||||||
//if fileList[k].StoreID < 100000 || fileList[k].StoreID > 1000000 {
|
|
||||||
// return "", fmt.Errorf("文件名:%s不规范,不以合法的京西门店ID开始", fileHeader.Filename)
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
putPolicy := storage.PutPolicy{
|
|
||||||
Scope: globals.QiniuBucket,
|
|
||||||
Expires: 10 * 60,
|
|
||||||
}
|
|
||||||
upToken := putPolicy.UploadToken(api.QiniuAPI)
|
|
||||||
cfg := &storage.Config{}
|
|
||||||
task := tasksch.NewParallelTask("SendFilesToStores", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx,
|
|
||||||
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
|
||||||
fileInfo := batchItemList[0].(*tUploadFileInfo)
|
|
||||||
fileHeader := fileInfo.FileHeader
|
|
||||||
db := dao.GetDB()
|
|
||||||
storeID, _ := dao.GetRealLinkStoreID(db, fileInfo.StoreID)
|
|
||||||
storeDetail, _ := dao.GetStoreDetail(db, storeID, 0, "")
|
|
||||||
if storeDetail != nil && storeDetail.PushBill == 1 {
|
|
||||||
return retVal, err
|
|
||||||
}
|
|
||||||
file, err := fileHeader.Open()
|
|
||||||
if err == nil {
|
|
||||||
ret := storage.PutRet{}
|
|
||||||
key := "storeBill/" + utils.Int2Str(storeID) + "_" + strings.ToLower(utils.GetUUID()) + path.Ext(fileHeader.Filename)
|
|
||||||
formUploader := storage.NewFormUploader(cfg)
|
|
||||||
for i := 0; i < 3; i++ {
|
|
||||||
if err = formUploader.Put(context.Background(), &ret, upToken, key, file, fileHeader.Size, &storage.PutExtra{}); err == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file.Close()
|
|
||||||
if err == nil {
|
|
||||||
billRec := &legacymodel.StoreBill{
|
|
||||||
Date: time.Now(),
|
|
||||||
Url: strings.Replace(jxutils.ComposeQiniuResURL(ret.Key), "http://", "https://", -1),
|
|
||||||
StoreId: storeID,
|
|
||||||
BillName: fileHeader.Filename,
|
|
||||||
ShopName: shopName,
|
|
||||||
BillTitle: title,
|
|
||||||
}
|
|
||||||
if err = dao.CreateEntity(db, billRec); err == nil {
|
|
||||||
err = weixinmsg.NotifySaleBill(storeID, title, shopName, fmt.Sprintf("%s/billshow/?path=%s", globals.BackstageHost, billRec.Url))
|
|
||||||
if err != nil {
|
|
||||||
globals.SugarLogger.Infof("SendFilesToStores NotifySaleBill file:%s error:%v", fileHeader.Filename, err)
|
|
||||||
}
|
|
||||||
err = nil // 忽略微信发送错误
|
|
||||||
} else {
|
|
||||||
globals.SugarLogger.Warnf("SendFilesToStores CreateEntity file:%s error:%v", fileHeader.Filename, err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
globals.SugarLogger.Warnf("SendFilesToStores file:%s failed with error:%v", fileHeader.Filename, err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
globals.SugarLogger.Warnf("SendFilesToStores open file:%s failed with error:%v", fileHeader.Filename, err)
|
|
||||||
}
|
|
||||||
return retVal, err
|
|
||||||
}, fileList)
|
|
||||||
tasksch.HandleTask(task, nil, true).Run()
|
|
||||||
hint = task.ID
|
|
||||||
if !isAsync {
|
|
||||||
_, err = task.GetResult(0)
|
|
||||||
}
|
|
||||||
return task.ID, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetStoreBills(ctx *jxcontext.Context, storeID int) (bills []*legacymodel.StoreBill, err error) {
|
|
||||||
db := dao.GetDB()
|
|
||||||
if err = dao.GetRows(db, &bills, `
|
|
||||||
SELECT *
|
|
||||||
FROM store_bill
|
|
||||||
WHERE store_id = ?
|
|
||||||
ORDER BY date DESC
|
|
||||||
LIMIT 10
|
|
||||||
`, storeID); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return bills, err
|
|
||||||
}
|
|
||||||
@@ -1,278 +0,0 @@
|
|||||||
package initdata
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/tencent_map"
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TruncateTable(db *dao.DaoDB, tableName string) (err error) {
|
|
||||||
_, err = dao.ExecuteSQL(db, "TRUNCATE TABLE "+tableName)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func insertPlace(ctx *jxcontext.Context, db *dao.DaoDB, parent *tencent_map.District, placeList []*tencent_map.District) (err error) {
|
|
||||||
for _, v := range placeList {
|
|
||||||
if v.Level <= tencent_map.DistrictLevelDistrict {
|
|
||||||
place := &model.Place{
|
|
||||||
Code: int(utils.Str2Int64(v.Adcode)),
|
|
||||||
Name: v.Name,
|
|
||||||
Level: int8(v.Level),
|
|
||||||
TelCode: v.CityCode,
|
|
||||||
Enabled: 1,
|
|
||||||
}
|
|
||||||
if parent != nil {
|
|
||||||
place.ParentCode = int(utils.Str2Int64(parent.Adcode))
|
|
||||||
}
|
|
||||||
dao.WrapAddIDCULEntity(place, ctx.GetUserName())
|
|
||||||
if err = dao.CreateEntity(db, place); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err = insertPlace(ctx, db, v, v.Districts); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func InitPlace(ctx *jxcontext.Context) (err error) {
|
|
||||||
// 这个地方是更新全国的place表,因为两个不兼容且上传时间不会发送改变,暂时不做返回
|
|
||||||
placeList, err2 := api.TencentMapAPI.GetDistricts(tencent_map.DistrictLevelDistrict, "", 0)
|
|
||||||
if err = err2; err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
placeList = placeList[0].Districts
|
|
||||||
db := dao.GetDB()
|
|
||||||
txDB, _ := dao.Begin(db)
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil || err != nil {
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
if r != nil {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
if _, err = dao.ExecuteSQL(db, `
|
|
||||||
DELETE t1
|
|
||||||
FROM place t1
|
|
||||||
WHERE code < 9000000;
|
|
||||||
`); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err = insertPlace(ctx, db, nil, placeList); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
updateSqls := []string{
|
|
||||||
`
|
|
||||||
UPDATE place t1
|
|
||||||
JOIN jde_city t2 ON t1.code = t2.col_tencentAddressCode
|
|
||||||
SET t1.jd_code = t2.col_areaCode;
|
|
||||||
`,
|
|
||||||
`
|
|
||||||
UPDATE place t1
|
|
||||||
JOIN place t2 ON t1.parent_code = t2.code AND t2.jd_code != 0
|
|
||||||
JOIN jde_district t3 ON t1.name = t3.col_areaName AND t2.jd_code = t3.col_cityCode
|
|
||||||
SET t1.jd_code = t3.col_areaCode
|
|
||||||
WHERE t1.level = 3;
|
|
||||||
`,
|
|
||||||
`
|
|
||||||
UPDATE
|
|
||||||
place t1
|
|
||||||
JOIN ebde_places t2 ON t1.name = t2.col_city_name
|
|
||||||
SET t1.ebai_code = t2.col_city_id
|
|
||||||
WHERE t1.level = 1 OR t1.level = 2;
|
|
||||||
`,
|
|
||||||
`
|
|
||||||
UPDATE
|
|
||||||
place t1
|
|
||||||
JOIN place t1p ON t1.parent_code = t1p.code
|
|
||||||
JOIN ebde_places t2 ON t1.name = t2.col_city_name
|
|
||||||
JOIN ebde_places t2p ON t2.col_parent_id = t2p.col_city_id AND t1p.ebai_code = t2p.col_city_id
|
|
||||||
SET t1.ebai_code = t2.col_city_id
|
|
||||||
WHERE t1.level = 3;
|
|
||||||
`,
|
|
||||||
`
|
|
||||||
UPDATE
|
|
||||||
place t1
|
|
||||||
JOIN mtpsdeliveryprice t2 ON t1.code = t2.citycode
|
|
||||||
SET t1.mtps_price = t2.price;
|
|
||||||
`,
|
|
||||||
`
|
|
||||||
UPDATE
|
|
||||||
place t1
|
|
||||||
JOIN mtpsdeliveryprice t2 ON t1.name LIKE CONCAT(t2.cityname, '%')
|
|
||||||
SET t1.mtps_price = t2.price
|
|
||||||
WHERE t1.level = 2 AND t1.mtps_price = 0;
|
|
||||||
`,
|
|
||||||
`
|
|
||||||
UPDATE place t1
|
|
||||||
LEFT JOIN (
|
|
||||||
SELECT DISTINCT city_code
|
|
||||||
FROM store
|
|
||||||
UNION DISTINCT
|
|
||||||
SELECT DISTINCT place_code city_code
|
|
||||||
FROM sku_name_place_bind
|
|
||||||
) t2 ON t1.code = t2.city_code
|
|
||||||
SET t1.enabled = 0
|
|
||||||
WHERE t1.level = 2 AND t2.city_code IS NULL;
|
|
||||||
`,
|
|
||||||
}
|
|
||||||
for _, v := range updateSqls {
|
|
||||||
if _, err = dao.ExecuteSQL(db, v); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dao.Commit(db, txDB)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func InitVendorCategory(ctx *jxcontext.Context, vendorID int, isAsync bool) (hint string, err error) {
|
|
||||||
if handler := partner.GetPurchasePlatformFromVendorID(vendorID); handler != nil {
|
|
||||||
var cats []*model.SkuVendorCategory
|
|
||||||
rootTask := tasksch.NewSeqTask(fmt.Sprintf("创建%s的平台分类", model.VendorChineseNames[vendorID]), ctx,
|
|
||||||
func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
|
||||||
switch step {
|
|
||||||
case 0:
|
|
||||||
cats, err = handler.GetVendorCategories(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
case 1:
|
|
||||||
db := dao.GetDB()
|
|
||||||
txDB, _ := dao.Begin(db)
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil || err != nil {
|
|
||||||
dao.Rollback(db, txDB)
|
|
||||||
if r != nil {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
sql := `
|
|
||||||
DELETE
|
|
||||||
FROM sku_vendor_category
|
|
||||||
WHERE vendor_id = ?
|
|
||||||
`
|
|
||||||
if _, err = dao.ExecuteSQL(db, sql, vendorID); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for _, cat := range cats {
|
|
||||||
dao.WrapAddIDCULEntity(cat, ctx.GetUserName())
|
|
||||||
}
|
|
||||||
if err = dao.CreateMultiEntities(db, cats); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
dao.Commit(db, txDB)
|
|
||||||
}
|
|
||||||
return nil, err
|
|
||||||
}, 2)
|
|
||||||
tasksch.HandleTask(rootTask, nil, true).Run()
|
|
||||||
if !isAsync {
|
|
||||||
if _, err = rootTask.GetResult(0); err == nil {
|
|
||||||
hint = utils.Int2Str(len(cats))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
hint = rootTask.ID
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = fmt.Errorf("找不到平台:%d", vendorID)
|
|
||||||
}
|
|
||||||
return hint, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func UploadImg4Vendors(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (hint string, err error) {
|
|
||||||
// db := dao.GetDB()
|
|
||||||
// rootTask := tasksch.NewSeqTask("合并SkuName图片至DataResource", ctx,
|
|
||||||
// func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
|
||||||
// switch step {
|
|
||||||
// case 0: // 计算SkuName中缺失的hashCode(注意是DescImg不是Img)
|
|
||||||
// var skuNameList []*model.SkuName
|
|
||||||
// if err = dao.GetRows(db, &skuNameList, `
|
|
||||||
// SELECT t1.*
|
|
||||||
// FROM sku_name t1
|
|
||||||
// WHERE t1.desc_img <> '' AND t1.img_hash_code = ''
|
|
||||||
// `); err == nil && len(skuNameList) > 0 {
|
|
||||||
// calcTask := tasksch.NewParallelTask("UploadImg4Vendors calc hashCode",
|
|
||||||
// tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetParallelCount(5), ctx,
|
|
||||||
// func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
|
||||||
// skuName := batchItemList[0].(*model.SkuName)
|
|
||||||
// _, skuName.ImgHashCode, err = jxutils.DownloadFileByURL(skuName.DescImg)
|
|
||||||
// if err == nil {
|
|
||||||
// dao.UpdateEntity(db, skuName, "ImgHashCode")
|
|
||||||
// }
|
|
||||||
// return retVal, err
|
|
||||||
// }, skuNameList)
|
|
||||||
// tasksch.HandleTask(calcTask, task, false).Run()
|
|
||||||
// _, err = calcTask.GetResult(0)
|
|
||||||
// }
|
|
||||||
// case 1: // 从SkuName添加缺失的图片至DataResource
|
|
||||||
// _, err = dao.ExecuteSQL(db, `
|
|
||||||
// INSERT INTO data_resource(created_at, updated_at, last_operator, hash_code,
|
|
||||||
// resource_type, name, main_url, ebai_url, qiniu_url, use_type)
|
|
||||||
// SELECT t1.created_at, t1.created_at, t1.last_operator, t1.img_hash_code,
|
|
||||||
// CASE
|
|
||||||
// WHEN INSTR(t1.desc_img, ".jpg") > 0 OR INSTR(t1.desc_img, ".jpeg") > 0 THEN
|
|
||||||
// 'image/jpeg'
|
|
||||||
// WHEN INSTR(t1.desc_img, ".png") > 0 OR INSTR(t1.desc_img, ".peg") > 0 THEN
|
|
||||||
// 'image/png'
|
|
||||||
// WHEN INSTR(t1.desc_img, ".gif") THEN
|
|
||||||
// 'image/gif'
|
|
||||||
// ELSE
|
|
||||||
// ''
|
|
||||||
// END resource_type,
|
|
||||||
// CONCAT(t1.name, '_desc'), desc_img main_url, t1.desc_img_ebai ebai_url,
|
|
||||||
// IF(INSTR(t1.desc_img, "image.jxc4.com") > 0, t1.desc_img, '') qiniu_url, 2
|
|
||||||
// FROM sku_name t1
|
|
||||||
// JOIN (
|
|
||||||
// SELECT img_hash_code, MAX(id) id, COUNT(*) ct
|
|
||||||
// FROM sku_name
|
|
||||||
// WHERE img_hash_code <> '' AND desc_img <> ''
|
|
||||||
// GROUP BY 1
|
|
||||||
// ) t3 ON t3.id = t1.id
|
|
||||||
// LEFT JOIN data_resource t2 ON (t2.main_url <> '' AND t2.main_url = t1.desc_img)
|
|
||||||
// WHERE t1.desc_img <> '' AND t1.img_hash_code <> '' AND t2.id IS NULL;
|
|
||||||
// `)
|
|
||||||
// case 2: // 统一SkuName中同hashCode,不同图片地址至同一地址
|
|
||||||
// _, err = dao.ExecuteSQL(db, `
|
|
||||||
// UPDATE sku_name t1
|
|
||||||
// JOIN data_resource t2 ON t2.hash_code = t1.img_hash_code AND t2.main_url <> ''
|
|
||||||
// SET t1.desc_img = t2.main_url
|
|
||||||
// WHERE t1.img_hash_code <> '' AND t1.desc_img <> t2.main_url;
|
|
||||||
// `)
|
|
||||||
// case 3: // 上传DataResource中缺失的平台图片
|
|
||||||
// dataResList, err2 := dao.GetNeedUploadDataResource(db)
|
|
||||||
// if err = err2; err == nil && len(dataResList) > 0 {
|
|
||||||
// uploadTask := tasksch.NewParallelTask("批量上传图片至平台",
|
|
||||||
// tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetParallelCount(2), ctx,
|
|
||||||
// func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
|
||||||
// dataRes := batchItemList[0].(*model.DataResource)
|
|
||||||
// _, err = datares.UploadImage2Vendors(ctx, task, dataRes, nil, false)
|
|
||||||
// return nil, err
|
|
||||||
// }, dataResList)
|
|
||||||
// tasksch.HandleTask(uploadTask, task, true).Run()
|
|
||||||
// _, err = uploadTask.GetResult(0)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return result, err
|
|
||||||
// }, 4)
|
|
||||||
// tasksch.HandleTask(rootTask, nil, true).Run()
|
|
||||||
// if !isAsync {
|
|
||||||
// if _, err = rootTask.GetResult(0); err == nil {
|
|
||||||
// hint = "1"
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// hint = rootTask.ID
|
|
||||||
// }
|
|
||||||
return hint, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func getSkuNameKey(prefix, name, comment, specUnit, unit string, specQuality float32) string {
|
|
||||||
return fmt.Sprintf("%s-%s-%f-%s-%s", prefix, name, specQuality, specUnit, unit)
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user