Compare commits
574 Commits
multiple_r
...
master
| Author | SHA1 | Date |
|---|---|---|
|
|
d957a0c2a3 | |
|
|
dd51d48a45 | |
|
|
5a172360bc | |
|
|
28c5d34acf | |
|
|
e66d6b56e9 | |
|
|
232509dc14 | |
|
|
477f252fd1 | |
|
|
4c801f007a | |
|
|
5d5f67ef07 | |
|
|
027e23e538 | |
|
|
f88d3a1673 | |
|
|
5c17e811a9 | |
|
|
ae843ab767 | |
|
|
d2db2a5547 | |
|
|
f1df93ec25 | |
|
|
34d71c1fd0 | |
|
|
bc9d50bf0c | |
|
|
e1e41d98bc | |
|
|
a36d9374dd | |
|
|
174f6b4a82 | |
|
|
aa7b8c7a5d | |
|
|
77008d11da | |
|
|
f66ee72314 | |
|
|
40ba4652be | |
|
|
1485037c82 | |
|
|
cb78526d0e | |
|
|
bc96277f86 | |
|
|
c733349a9e | |
|
|
e7bb47f023 | |
|
|
a805c562c9 | |
|
|
8bbacc653f | |
|
|
e0060c0432 | |
|
|
72748b7113 | |
|
|
fe13c91ab2 | |
|
|
16891e331d | |
|
|
9ebbc056f3 | |
|
|
43e51e7557 | |
|
|
642038eef5 | |
|
|
5489aaa620 | |
|
|
9bb52b5ffb | |
|
|
bba67251af | |
|
|
4388cbb3f6 | |
|
|
e0226437ad | |
|
|
c57c585b37 | |
|
|
eced56a427 | |
|
|
8148a59e83 | |
|
|
c84c39a28f | |
|
|
47f717fcb2 | |
|
|
5c2049c3ea | |
|
|
82ecd1a144 | |
|
|
9acd98d9b5 | |
|
|
9db20efd88 | |
|
|
61dcb7b25c | |
|
|
c8825f1c16 | |
|
|
c3f89a3a4f | |
|
|
e9771921db | |
|
|
9ebbcfacf7 | |
|
|
4783b4b077 | |
|
|
5cc6d5736d | |
|
|
87bcdda6f8 | |
|
|
624921d776 | |
|
|
75ffa0f6ee | |
|
|
1a8283e441 | |
|
|
cb3e5d98a8 | |
|
|
731d340abf | |
|
|
e9ab52cb7e | |
|
|
7878cc61c1 | |
|
|
c55ac047c0 | |
|
|
a64f1728ac | |
|
|
a75d05bc9a | |
|
|
6532c9d460 | |
|
|
3eb0bd846f | |
|
|
7d2b4f7fdb | |
|
|
7a2f71624b | |
|
|
190d2a2bed | |
|
|
f12121c457 | |
|
|
c7953da901 | |
|
|
464fab9fa1 | |
|
|
ef8fc2c492 | |
|
|
9090b61095 | |
|
|
08e5353b4e | |
|
|
a2a009a1e2 | |
|
|
49394a5172 | |
|
|
57d5161b2c | |
|
|
270ad85a10 | |
|
|
65ca7bf9aa | |
|
|
356d2beaa5 | |
|
|
d2260ade7b | |
|
|
9c519ce980 | |
|
|
620af65906 | |
|
|
353e302df9 | |
|
|
0a37c352fb | |
|
|
1a5b094388 | |
|
|
c8811b0e60 | |
|
|
510e696030 | |
|
|
8c859e1866 | |
|
|
91cb050b47 | |
|
|
1fe53780b9 | |
|
|
671a9f225e | |
|
|
ae2f59d183 | |
|
|
d59b15c569 | |
|
|
fa7ff1971f | |
|
|
08c7cb32a9 | |
|
|
f1d55564c3 | |
|
|
3cf9951bb3 | |
|
|
ce8015b836 | |
|
|
9a3245380b | |
|
|
02528c930f | |
|
|
3dc68ceaf8 | |
|
|
ad6473f446 | |
|
|
61e9859181 | |
|
|
3fbd432b9c | |
|
|
7643b5d6d8 | |
|
|
4ef6b6de2c | |
|
|
7a73c9b099 | |
|
|
40f5c1472e | |
|
|
8870875647 | |
|
|
5fe9d79a94 | |
|
|
ee36d363a7 | |
|
|
f9f36c16d9 | |
|
|
7f959107da | |
|
|
47f5c7b039 | |
|
|
704454a759 | |
|
|
a82b513755 | |
|
|
c726bf91d4 | |
|
|
ea0233425e | |
|
|
708d2f12f5 | |
|
|
037b1b5b5e | |
|
|
b2ddfb1502 | |
|
|
bd78980529 | |
|
|
fa616c8de6 | |
|
|
7afe847942 | |
|
|
d3dcb97911 | |
|
|
10835cd1a7 | |
|
|
e2ec85c7ae | |
|
|
7a2a155938 | |
|
|
dfcf26d976 | |
|
|
cedc78e76e | |
|
|
e38126d341 | |
|
|
547fcfc37b | |
|
|
e8af400536 | |
|
|
3524b20075 | |
|
|
affce5e1b4 | |
|
|
f1328d4db8 | |
|
|
75c06e6457 | |
|
|
448b134f11 | |
|
|
5b8fe3cd58 | |
|
|
f68eb53363 | |
|
|
9a722c8da2 | |
|
|
18b6d5325d | |
|
|
8766726189 | |
|
|
dfc1aaca91 | |
|
|
ca4530ce84 | |
|
|
6c500a0349 | |
|
|
d7f8ffa20d | |
|
|
8e09f2aaf6 | |
|
|
36767a00bf | |
|
|
ecd9a76eeb | |
|
|
4f984ab2e7 | |
|
|
1d91eb9976 | |
|
|
c747158393 | |
|
|
cb16333e61 | |
|
|
964d1cb519 | |
|
|
cc032f44c0 | |
|
|
71bb414f23 | |
|
|
ef23b61265 | |
|
|
6dd60354a6 | |
|
|
582d478186 | |
|
|
a14f69f77c | |
|
|
5a4945955d | |
|
|
99be99391f | |
|
|
60952f6b47 | |
|
|
60c02a28ed | |
|
|
05ac0b5acb | |
|
|
087ea91ecf | |
|
|
54a7b65f8f | |
|
|
687f691ff9 | |
|
|
78f43c0c16 | |
|
|
880866b1b6 | |
|
|
c07f80e18f | |
|
|
1abb02f464 | |
|
|
fc38c49162 | |
|
|
c857e551fb | |
|
|
a22d60f23a | |
|
|
806e5e700e | |
|
|
f8a987a0f6 | |
|
|
be3311daee | |
|
|
0ff2a6b703 | |
|
|
dbeace3191 | |
|
|
96cbd47cb0 | |
|
|
bcffad126c | |
|
|
6dbdb33a2b | |
|
|
fecb22b5ad | |
|
|
e661871090 | |
|
|
38c26e399f | |
|
|
e1696d937b | |
|
|
2099610e59 | |
|
|
2e2494c9bb | |
|
|
ed034cb2c7 | |
|
|
d40822487f | |
|
|
3cd9560732 | |
|
|
479e619d39 | |
|
|
bd9883c0d0 | |
|
|
6aec17ed20 | |
|
|
5aea1c4731 | |
|
|
f385aaabf3 | |
|
|
0a86d01406 | |
|
|
ccb7cc34b5 | |
|
|
37722ef2fa | |
|
|
d1ce4b76a2 | |
|
|
95952ea425 | |
|
|
1a2f919f79 | |
|
|
3c958a2923 | |
|
|
ec4fdda392 | |
|
|
73710b0a4c | |
|
|
e6a3d6fc2d | |
|
|
e7e8583806 | |
|
|
259b99c3f0 | |
|
|
9df61f6a85 | |
|
|
21c4d8e7dc | |
|
|
174b6031e9 | |
|
|
37471713b7 | |
|
|
4c8a00d081 | |
|
|
f9080bb812 | |
|
|
cf10288761 | |
|
|
1be8d59c6f | |
|
|
930a9e3de8 | |
|
|
2e7bcaba70 | |
|
|
d6028c3e1e | |
|
|
ff67462b73 | |
|
|
fab703b7af | |
|
|
2655d8ffdb | |
|
|
ab7e7eaca7 | |
|
|
c92ea38c60 | |
|
|
fabfbad8e3 | |
|
|
63f85c996f | |
|
|
45ee79cc6d | |
|
|
977994aeee | |
|
|
a04f2ac07c | |
|
|
c421a6a9b5 | |
|
|
9ce50574d0 | |
|
|
1bf22bad69 | |
|
|
55b1e1a16d | |
|
|
a4aaf529dd | |
|
|
6f4cd2d217 | |
|
|
3ff590511d | |
|
|
c832f2632e | |
|
|
33e278b904 | |
|
|
6a191fe575 | |
|
|
7726728114 | |
|
|
021ab31732 | |
|
|
ccbbbe7ec5 | |
|
|
487c912351 | |
|
|
a22fb81326 | |
|
|
62c0baa1db | |
|
|
7460a01b22 | |
|
|
c99975c300 | |
|
|
9fad62d168 | |
|
|
d132a9f68f | |
|
|
7bbefd0d60 | |
|
|
1fdb099591 | |
|
|
700b261e36 | |
|
|
368f943211 | |
|
|
38b6211531 | |
|
|
b4cb0f6a65 | |
|
|
2c3328b320 | |
|
|
3ef7b08c95 | |
|
|
a1d6f90837 | |
|
|
ed1790a79a | |
|
|
7844f470fa | |
|
|
b572d35b88 | |
|
|
0c6ced5f64 | |
|
|
37b2158fe0 | |
|
|
269c023cfb | |
|
|
2b8747b6f7 | |
|
|
66eabfee3f | |
|
|
2379de2ca8 | |
|
|
365bb601dc | |
|
|
41a79155e8 | |
|
|
dde04d33d7 | |
|
|
ebed7ed88a | |
|
|
6e9f52b0f1 | |
|
|
a44ffd15cd | |
|
|
7440a5d166 | |
|
|
3fd8968a1a | |
|
|
19940c64ae | |
|
|
c471f79d34 | |
|
|
6f357a3bcb | |
|
|
077fe631a3 | |
|
|
6fee96a602 | |
|
|
73bba5dc9d | |
|
|
f04fa50549 | |
|
|
21bfff0400 | |
|
|
0ca42dc14b | |
|
|
435f63560f | |
|
|
7c07a7951c | |
|
|
6920d3d554 | |
|
|
3f726ca439 | |
|
|
1254dd9e79 | |
|
|
44eab29981 | |
|
|
70b31a6a8e | |
|
|
cd0fb4c6ce | |
|
|
f0cd7c5172 | |
|
|
76323f4bbc | |
|
|
0433165ae2 | |
|
|
db05137f27 | |
|
|
31670d8962 | |
|
|
20ce2319e7 | |
|
|
0c015748fc | |
|
|
89a9c13822 | |
|
|
ccc6b3cb99 | |
|
|
41a9c93f62 | |
|
|
35b0b86c60 | |
|
|
bfcbaa9cae | |
|
|
67b4f95237 | |
|
|
ce70f4f954 | |
|
|
152c2c5caa | |
|
|
fb57b9e9f9 | |
|
|
b4617d3135 | |
|
|
ffb560da51 | |
|
|
c58346349c | |
|
|
109cc4ccca | |
|
|
e8fd8d49d2 | |
|
|
68023b8cc0 | |
|
|
2549dcd977 | |
|
|
934afa402a | |
|
|
0975f12e39 | |
|
|
5c54c87ea3 | |
|
|
67f8738c5e | |
|
|
8a8cd9353b | |
|
|
88db2391d2 | |
|
|
4f55e0e9f8 | |
|
|
ec5fcacf64 | |
|
|
d798bf8f26 | |
|
|
a0aefb4850 | |
|
|
e24cbde6f0 | |
|
|
a13ac431dc | |
|
|
ff366f9ec5 | |
|
|
482e2225f1 | |
|
|
94277bce22 | |
|
|
1a18fbb03b | |
|
|
b57f751831 | |
|
|
9d78fcef91 | |
|
|
87e049618e | |
|
|
3e96984d64 | |
|
|
1b712a705d | |
|
|
6357dc58d2 | |
|
|
f09fa1e8b6 | |
|
|
02683fcfeb | |
|
|
014e591916 | |
|
|
aac5ba8b20 | |
|
|
e398ad7e25 | |
|
|
d5c1dda703 | |
|
|
d44591330a | |
|
|
d8b6c15034 | |
|
|
cf7c708f3a | |
|
|
6d72575c0b | |
|
|
3bf3f56587 | |
|
|
228e8d3a70 | |
|
|
96891f811c | |
|
|
a329df620d | |
|
|
bc960bbb2b | |
|
|
739976b1f9 | |
|
|
0fcc7efb8e | |
|
|
660acc64ee | |
|
|
a8452e1f52 | |
|
|
199fc1c619 | |
|
|
0c82e06c91 | |
|
|
d266225943 | |
|
|
7cdbfe8e9d | |
|
|
2f488a71e1 | |
|
|
8c805e710a | |
|
|
cc5f528bf7 | |
|
|
0a4264c9ac | |
|
|
6f2c5f534d | |
|
|
d7053a4d9c | |
|
|
3271cf06f3 | |
|
|
43df3100ed | |
|
|
c6b3fdaf03 | |
|
|
5136738411 | |
|
|
443a61e2ec | |
|
|
e79e530bcd | |
|
|
ddaf344907 | |
|
|
a56511b4f2 | |
|
|
54b214c4b4 | |
|
|
32119e1348 | |
|
|
c97d064aca | |
|
|
d1cac03848 | |
|
|
7e48da6fb3 | |
|
|
e32a57baf7 | |
|
|
cc2abf126a | |
|
|
9a2524bbde | |
|
|
2d1c925e47 | |
|
|
3bd058f650 | |
|
|
7b1ed37c50 | |
|
|
3eb06f5951 | |
|
|
c328e4f4c4 | |
|
|
4fcdc5a1dc | |
|
|
572bfcbc05 | |
|
|
1264052f30 | |
|
|
facc4199f6 | |
|
|
3a5cd3b210 | |
|
|
1dd6bc0065 | |
|
|
8e661f0211 | |
|
|
57a211bbce | |
|
|
37b3d0a716 | |
|
|
1cebda3074 | |
|
|
ee243b5d61 | |
|
|
f3c0419987 | |
|
|
6b6886f3f3 | |
|
|
73f9cd14e6 | |
|
|
1df8410b99 | |
|
|
bc8a43ce2f | |
|
|
134da09966 | |
|
|
8625d959da | |
|
|
b5a09dfd71 | |
|
|
5e0d35a989 | |
|
|
0ee5ababdc | |
|
|
28c6ccd65b | |
|
|
a5ad79dc0e | |
|
|
7733e4f755 | |
|
|
555fd91a56 | |
|
|
a0ab257b18 | |
|
|
294123359f | |
|
|
c64902e206 | |
|
|
f13e74aff7 | |
|
|
8edb26d46f | |
|
|
b6d6dafe8d | |
|
|
68661072ce | |
|
|
7062b7dd52 | |
|
|
2ebe61813d | |
|
|
22f73e9a06 | |
|
|
14d3a48dda | |
|
|
77e7ae8227 | |
|
|
bd6dee6d8c | |
|
|
b95dcce2b4 | |
|
|
81ccbc40bc | |
|
|
bc64e4a10c | |
|
|
062164f90d | |
|
|
227c7f6896 | |
|
|
95c9bfcfcf | |
|
|
44f780f15b | |
|
|
49ca78bdf3 | |
|
|
9cd69109f9 | |
|
|
bb5f136025 | |
|
|
d6bd909075 | |
|
|
9109c692a1 | |
|
|
6d4cf3ed78 | |
|
|
59a662d56a | |
|
|
82f8a40f87 | |
|
|
0de3aa5058 | |
|
|
118107cc15 | |
|
|
638c3bd518 | |
|
|
d1634edfcb | |
|
|
316de8d63e | |
|
|
bd7bc74bdb | |
|
|
043d8cf9f9 | |
|
|
d11dfdc04d | |
|
|
19161fda7f | |
|
|
232eed7361 | |
|
|
f42f56c48e | |
|
|
f7017a21c1 | |
|
|
9a193669b8 | |
|
|
77a45f2c52 | |
|
|
5d99c998fe | |
|
|
a82fa6f21f | |
|
|
ebef42aba7 | |
|
|
d65dedb62d | |
|
|
ce77b24b47 | |
|
|
009c391e44 | |
|
|
0d6a963959 | |
|
|
de669894fc | |
|
|
5b54770a40 | |
|
|
49f52d0845 | |
|
|
8ad615c8b7 | |
|
|
7b0169e4bc | |
|
|
3a829cae26 | |
|
|
d5847db0b9 | |
|
|
84bbf53ea4 | |
|
|
ffcf62c5f3 | |
|
|
8df08d1ff1 | |
|
|
210ade5f47 | |
|
|
05265ac17e | |
|
|
d28e6a1b90 | |
|
|
82a9d1cdbc | |
|
|
842793a74e | |
|
|
36aa346c2a | |
|
|
b57a8383d2 | |
|
|
3ec22e2a8e | |
|
|
cea7d3301a | |
|
|
a3168fdb6d | |
|
|
9f6a22a065 | |
|
|
7d22d8bd86 | |
|
|
b71f6d5570 | |
|
|
27a8302c7f | |
|
|
6fc928fa34 | |
|
|
09a0b0696c | |
|
|
352a4323d0 | |
|
|
32a7dc96ea | |
|
|
eb8a213cc4 | |
|
|
d78b636d6b | |
|
|
ea674336ff | |
|
|
4929fc8d3a | |
|
|
db11b450a3 | |
|
|
7caf7eae18 | |
|
|
f574bfed24 | |
|
|
7d7d7ee584 | |
|
|
f7cca0de02 | |
|
|
8b7ab3c6fe | |
|
|
db206b6577 | |
|
|
12438386bd | |
|
|
08b50407dd | |
|
|
6d431cf991 | |
|
|
f401676e02 | |
|
|
444c532f9a | |
|
|
4a094c256e | |
|
|
92bf1bb533 | |
|
|
ea2d9d683b | |
|
|
74a72688db | |
|
|
d00aaea21c | |
|
|
40e5098a7e | |
|
|
063717b4ca | |
|
|
f9b9653cc6 | |
|
|
daa1555f62 | |
|
|
feb2bee79e | |
|
|
9ad2b8cb3b | |
|
|
c3540575ab | |
|
|
ba8a37c77d | |
|
|
5b1f10fadd | |
|
|
e7cdfe188d | |
|
|
6436dffee0 | |
|
|
f64296dec7 | |
|
|
6013517d26 | |
|
|
dd43a90d15 | |
|
|
a500a5581d | |
|
|
5337178504 | |
|
|
24a5b2d44f | |
|
|
9982b95211 | |
|
|
acf7a47be6 | |
|
|
48986fd44a | |
|
|
ccf9a8bb61 | |
|
|
29588e68d2 | |
|
|
6b064b7fe1 | |
|
|
2aaab088a6 | |
|
|
c25587ffb6 | |
|
|
e5a7c1bb99 | |
|
|
cd21ae9d17 | |
|
|
83754b9d2c | |
|
|
bc24d8d243 | |
|
|
47533e40e0 | |
|
|
132047104b | |
|
|
5976ab5c54 | |
|
|
d12f2f7eae | |
|
|
7528ee8d28 | |
|
|
8034d35fff | |
|
|
af4d4321fe | |
|
|
d9e2a782ac | |
|
|
2e5ff5096c | |
|
|
c1b93ee051 | |
|
|
43aaede0b6 | |
|
|
5bd28dc039 | |
|
|
777178cc45 | |
|
|
0a82851e2c | |
|
|
e2dfdd057e | |
|
|
2077230be3 | |
|
|
67aaad5519 | |
|
|
a72d302696 | |
|
|
fb30737591 | |
|
|
8d3a159405 | |
|
|
ceafb5526c | |
|
|
439fecbff2 | |
|
|
94852f198a | |
|
|
2aca501eaf | |
|
|
103b864df2 |
|
|
@ -33,4 +33,5 @@ build/
|
|||
### VS Code ###
|
||||
.vscode/
|
||||
/logs/
|
||||
/ghy-admin/src/test/
|
||||
/ghy-admin/src/test/
|
||||
ghy-shop/ADDRESS_QUERY_EXAMPLE.md
|
||||
|
|
|
|||
|
|
@ -0,0 +1,214 @@
|
|||
<!-- @author Yifei.Kuang -->
|
||||
# 房间 / 群 / 群员业务需求说明文档
|
||||
|
||||
## 一、项目背景与目标
|
||||
|
||||
- **背景**
|
||||
在现有「师傅 / 商城 / 分销」体系上,引入「房间(圈子)+ 群 + 分销」的新结构,实现多房间、多群、多身份的精细化运营与监管。
|
||||
|
||||
- **目标**
|
||||
- 建立清晰的层级结构:**平台 → 房间 → 群 → 群员/分销**。
|
||||
- 统一分销身份规则,保证订单与佣金归属准确。
|
||||
- 支持群主、房间主、下级分销、运营商等多角色协同。
|
||||
- 为后续房间收费、群收费、群员收费等模式预留空间。
|
||||
|
||||
---
|
||||
|
||||
## 二、核心概念定义
|
||||
|
||||
### 2.1 平台
|
||||
|
||||
- 系统最上层运营主体,负责全局参数(平台扣点、结算规则等)。
|
||||
|
||||
### 2.2 房间(圈子)
|
||||
|
||||
- **定义**:平台下的独立运营空间,一个平台可创建多个房间。
|
||||
- **特点**
|
||||
- 房间名称:限制在 4–6 个字。
|
||||
- 房间标识图片、品牌注解由房间主配置。
|
||||
- 顶部功能栏:默认为「师傅库 / 商城 / 会话厅」,文字可改,总长度有限制但功能不变。
|
||||
- 房间可配置自身的功能权限(是否开放商城、是否允许群选品等)以及扣点、收费策略。
|
||||
- **关系**
|
||||
- 「微社圈」是整体产品名,“切换圈子”即切换不同房间。
|
||||
|
||||
### 2.3 群(分销群)
|
||||
|
||||
- **定义**:隶属于某房间的运营群,每个房间下可以创建多个群。
|
||||
- **建群要求**
|
||||
- 填写城市、区域、主营品类、预期群规模等信息。
|
||||
- 建群申请需由房间主及后台审核(形式类似现有分销申请)。
|
||||
- **职责**
|
||||
- 每个群经营自己的商品与客户。
|
||||
- 群商城中仅群主有选品权限,下级分销不能选品。
|
||||
|
||||
### 2.4 群主
|
||||
|
||||
- 该群的最高级分销者。
|
||||
- 新建群后自动成为本群顶级分销(无上级分销)。
|
||||
- 负责本群的选品、群成员管理、群内规则等。
|
||||
|
||||
### 2.5 群员 / 分销人员
|
||||
|
||||
- 所有群员可根据既有三级分销规则绑定上级关系。
|
||||
- **分销身份规则**
|
||||
- 每个群员在「平台 + 房间 + 群」这一组合下有一个独立分销身份。
|
||||
- 同一微信号在不同房间、不同群中,对系统而言是多个独立身份。
|
||||
- **影响**
|
||||
- 每个身份对应一条独立的分销线。
|
||||
- 订单结算与分账都按所在群对应的分销线进行。
|
||||
|
||||
### 2.6 系统机器人 / 监管号
|
||||
|
||||
- 平台可在任意群中驻入一个“系统机器人”账号:
|
||||
- 拥有类似群主的管理能力及后台监管能力。
|
||||
- 用于监管群运营是否健康、是否违规。
|
||||
|
||||
### 2.7 运营商(按微信号)
|
||||
|
||||
- 以微信号为主体的运营视角。
|
||||
- 同一微信号在多个房间、多个群中有多条分销线,但在运营统计中可统一聚合。
|
||||
|
||||
---
|
||||
|
||||
## 三、分销身份与订单归属规则
|
||||
|
||||
### 3.1 唯一身份线
|
||||
|
||||
- 每条分销身份线由四段组合定义:
|
||||
**平台ID + 房间ID + 群ID + 用户ID**
|
||||
- 每一条组合都被视为“系统中的一个人、一条分销线”。
|
||||
|
||||
### 3.2 多群多房间身份
|
||||
|
||||
- 同一微信号在不同房间/群中创建或加入时:
|
||||
- 系统会为其生成新的分销身份线。
|
||||
- 不同房间、群的身份互不影响。
|
||||
|
||||
### 3.3 分销绑定
|
||||
|
||||
- 在某群中被拉入的新成员:
|
||||
- 按现有三级分销规则建立上下级关系。
|
||||
- 上下级关系限定在本群对应的分销线中。
|
||||
|
||||
### 3.4 订单与分销归属
|
||||
|
||||
- 用户从某个群入口进入商城并下单:
|
||||
- 所有分销与分账都按该群的分销线计算。
|
||||
- 即使服务商在其他群也有身份,本订单仍只归属于当前群对应的身份线。
|
||||
|
||||
---
|
||||
|
||||
## 四、房间与群的前台结构
|
||||
|
||||
### 4.1 房间首页结构
|
||||
|
||||
- 房间头部展示:
|
||||
- 房间头像/标识图;
|
||||
- 品牌名称(4–6 字);
|
||||
- 简短品牌注解。
|
||||
- 顶部功能栏:
|
||||
- 默认入口为:「师傅库 / 商城 / 会话厅」。
|
||||
- 房间主可修改这三个名称(总长度有限制),但功能含义不变。
|
||||
- 顶部入口与底部导航对应,为功能快捷入口。
|
||||
|
||||
### 4.2 师傅库
|
||||
|
||||
- 展示本房间下已入驻的师傅与服务店铺。
|
||||
- 支持按街道、服务品类筛选。
|
||||
- 师傅资料在现有认证信息基础上增加头像和定位信息。
|
||||
- 用户可在师傅详情中:
|
||||
- 直接发起“发布订单”给该师傅;
|
||||
- 或将已有未接订单指派给该师傅。
|
||||
|
||||
### 4.3 商城
|
||||
|
||||
- 房间/群共用一个商城体系:
|
||||
- 房间级定义基础类目与商品池。
|
||||
- 群主在此基础上为本群做选品配置。
|
||||
- 首页默认展示热门服务类目,可左划展示其他商品类目。
|
||||
- 列表支持按价格、评分、销量筛选。
|
||||
- 商品销量按整条上架商品做统一统计。
|
||||
|
||||
### 4.4 会话厅
|
||||
|
||||
- 作为房间的首页使用:
|
||||
- 展示全部群、自建群、已加入群、单聊会话等。
|
||||
- 顶部菜单包含:申请房间、申请建群、搜索群、房间名称设置等入口。
|
||||
- 与群聊页面不同,主要承载群列表与会话入口。
|
||||
|
||||
---
|
||||
|
||||
## 五、订单与发布相关需求(概要)
|
||||
|
||||
### 5.1 师傅端状态汇总
|
||||
|
||||
- 师傅端首页顶部使用黄条展示:
|
||||
- 新订单数量;
|
||||
- 未约订单数量;
|
||||
- 待上门/待发货数量。
|
||||
- 点击不同统计可跳转到对应订单列表。
|
||||
|
||||
### 5.2 发单入口
|
||||
|
||||
- 页面底部设置蓝色「+」按钮作为发布主单入口。
|
||||
- 支持:
|
||||
- 服务类/商品类发单;
|
||||
- 选择到第 4 级类目,可多选;
|
||||
- 将常用配置保存为模板。
|
||||
- 支持代填发布,由专业师傅代填问题内容,客户补充地址、电话后提交。
|
||||
|
||||
### 5.3 保险规则(概念级)
|
||||
|
||||
- 发单时默认勾选“启用保险核查服务费”。
|
||||
- 发单方需选择保险费用由谁承担:
|
||||
- 服务费由发单方支付;
|
||||
- 服务费在订单中扣除。
|
||||
- 到付场景下,已产生的保险费用仍需保留,并可在后续订单中抵扣。
|
||||
|
||||
### 5.4 报价/加价模式(概念级)
|
||||
|
||||
- 在满足一定条件(报价模式或允许商家报价)时,显示“加价/报价”入口。
|
||||
- 支持大厅主单、未约/未排/监控单、已接单主单进行报价。
|
||||
- 客户最多可选择 3 家(特例 4 家)报价,确认后进入支付流程。
|
||||
|
||||
---
|
||||
|
||||
## 六、「我的」与运营统计(概念级)
|
||||
|
||||
- “我的”页面延用现有结构:
|
||||
- 展示分销中心、订单、选品等信息。
|
||||
- 运营统计以微信号为主体:
|
||||
- 汇总展示多房间、多群的运营数据;
|
||||
- 可按房间、群维度下钻查看。
|
||||
|
||||
---
|
||||
|
||||
## 七、商品与服务上架(概念级)
|
||||
|
||||
- 服务上架沿用当前规则。
|
||||
- 商品上架需区分于服务:
|
||||
- 针对库存、规格、展示方式做单独设计;
|
||||
- 与服务上架在前台展示上明显区分。
|
||||
|
||||
---
|
||||
|
||||
## 八、后台与安全监管(概念级)
|
||||
|
||||
- 房间级管理:
|
||||
- 房间创建与审核;
|
||||
- 房间启用/禁用;
|
||||
- 房间收费与扣点配置。
|
||||
- 群级管理:
|
||||
- 建群审核;
|
||||
- 群启用/禁用;
|
||||
- 群主调整;
|
||||
- 系统机器人驻入/移除。
|
||||
- 操作审计:
|
||||
- 记录房间、群创建和重要参数修改,便于运营追溯。
|
||||
|
||||
---
|
||||
|
||||
**文档定位**:业务需求说明(偏产品视角)
|
||||
**用途**:为后续详细设计与开发提供业务背景和规则依据
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,285 @@
|
|||
<!-- @author Yifei.Kuang -->
|
||||
# 房间 / 群 / 分销功能说明文档(开发视角)
|
||||
|
||||
## 一、整体架构
|
||||
|
||||
- 层级结构:
|
||||
- 平台 → 房间(Room)→ 群(Group)→ 群员 / 分销身份(Distributor)
|
||||
- 身份核心:
|
||||
- 每条分销身份由「平台 + 房间 + 群 + 用户」组合唯一确定,用于分销归属和订单结算。
|
||||
|
||||
---
|
||||
|
||||
## 二、房间模块(Room)
|
||||
|
||||
### 2.1 房间功能点
|
||||
|
||||
- 创建房间申请:
|
||||
- 用户提交房间名称、头像、品牌注解等信息。
|
||||
- 后台审核通过后,生成房间,并指定房间主。
|
||||
- 房间信息维护:
|
||||
- 房间主可编辑名称、头像、品牌注解。
|
||||
- 房间顶部功能栏配置:
|
||||
- 默认显示「师傅库 / 商城 / 会话厅」三项。
|
||||
- 房间主可以修改显示文案(总字数受限),功能类型不变。
|
||||
- 房间权限与扣点设置(后台):
|
||||
- 是否开启本房间商城。
|
||||
- 是否允许本房间下的群进行选品。
|
||||
- 房间级扣点与收费策略配置。
|
||||
- 房间切换:
|
||||
- 同一微信可加入多个房间,通过「切换圈子」在不同房间间切换。
|
||||
|
||||
---
|
||||
|
||||
## 三、群模块(Group)
|
||||
|
||||
### 3.1 建群与审核
|
||||
|
||||
- 在某房间内,用户可发起建群申请。
|
||||
- 填写群基础信息(城市、区域、主营类目、群规模等)。
|
||||
- 审核流程:
|
||||
- 房间主初审;
|
||||
- 后台终审;
|
||||
- 通过后创建群,申请人自动成为群主。
|
||||
|
||||
### 3.2 群基本操作
|
||||
|
||||
- 群信息维护:
|
||||
- 群主可编辑群名、介绍、主营描述等。
|
||||
- 群状态控制(后台):
|
||||
- 支持群的启用/禁用;
|
||||
- 禁用后,群内发单、接单、分销等操作关闭或受限。
|
||||
- 群主变更:
|
||||
- 后台可在必要时调整群主(例如违规处理)。
|
||||
|
||||
### 3.3 群监管
|
||||
|
||||
- 支持在任意群中驻入“系统机器人/系统监管号”:
|
||||
- 具备基本群管理与后台数据采集、监控能力。
|
||||
- 用于运营与风险控制。
|
||||
|
||||
---
|
||||
|
||||
## 四、群员 / 分销身份模块
|
||||
|
||||
### 4.1 分销身份规则
|
||||
|
||||
- 每个用户在某「平台 + 房间 + 群」组合下对应一个分销身份。
|
||||
- 同一微信在不同房间/群中拥有多个独立身份:
|
||||
- 每个身份有独立的分销链;
|
||||
- 后台视为多个“人”。
|
||||
|
||||
### 4.2 加入群与分销绑定
|
||||
|
||||
- 成员加入群时:
|
||||
- 若在该群下不存在分销身份,则系统为其创建一条新身份线。
|
||||
- 按既有三级分销规则绑定上级分销。
|
||||
- 上下级分销关系:
|
||||
- 限定在当前群对应的分销线中,不跨群共享。
|
||||
|
||||
### 4.3 角色与权限(概念层)
|
||||
|
||||
- 群主:
|
||||
- 本群最高级分销;
|
||||
- 拥有选品、群配置、成员管理等高权限。
|
||||
- 管理员:
|
||||
- 由群主任命,可拥有部分管理能力(禁言、审核、公告等)。
|
||||
- 普通分销/群员:
|
||||
- 不能在群内进行选品;
|
||||
- 可以拉人建立下级分销关系。
|
||||
|
||||
---
|
||||
|
||||
## 五、会话厅与群聊相关功能
|
||||
|
||||
### 5.1 订单页面导航(左侧)
|
||||
|
||||
- 导航栏包含 4 项:
|
||||
- 资源库;
|
||||
- 商品城;
|
||||
- 会话厅;
|
||||
- 附近圈动态。
|
||||
- 群主可以:
|
||||
- 修改导航名称(总字数有限制);
|
||||
- 单独开放/禁用任一入口;
|
||||
- 与外层房间首页的导航机制保持一致。
|
||||
- 右下角「会话大厅」按钮:
|
||||
- 进入群聊页面(中间页);
|
||||
- 文案可改,群主/平台可控制是否可用。
|
||||
|
||||
### 5.2 资源库(A)
|
||||
|
||||
- 展示服务师傅资料与店铺:
|
||||
- 格式类似现有“师傅圈”,但样式可定制。
|
||||
- 群主可设置仅群内成员可见,或继承房间级展示。
|
||||
- 提供发布入口,支持基于群选品的类目发单。
|
||||
|
||||
### 5.3 商品城(B)
|
||||
|
||||
- 群级商城展示逻辑:
|
||||
- 与整体商城逻辑一致;
|
||||
- 差异在于:群商城的选品由群主独立配置。
|
||||
- 所有人看到的商品、类目等均来源于群主选品结果。
|
||||
- 首页热门类目默认服务类,可左滑出商品类目列表。
|
||||
- 列表筛选按价格、评分、销量进行。
|
||||
- 销量统计按整条商品聚合,不再按规格拆分。
|
||||
|
||||
### 5.4 会话厅(C)
|
||||
|
||||
- 会话厅为“会话/订单流”页面,不是群聊页面。
|
||||
- 默认进入订单页时落在该列:
|
||||
- 支持上拉刷新;
|
||||
- 承载订单、系统相关信息的流式展示。
|
||||
|
||||
### 5.5 附近圈动态(D)
|
||||
|
||||
- 展示商家图文动态的“公共圈子”区域:
|
||||
- 默认名称为“附近圈动态”;
|
||||
- 群主可以改名,但含义不变(商家圈/动态圈)。
|
||||
|
||||
### 5.6 会话大厅图与编辑订单(E)
|
||||
|
||||
- 页面中部展示“会话大厅相关图”:
|
||||
- 使用会话大厅图的一部分放大,作为视觉入口。
|
||||
- 支持进入“编辑订单/发单页”:
|
||||
- 编辑后的订单可发至全群;
|
||||
- 管理员可选择仅发送至单个客户。
|
||||
|
||||
---
|
||||
|
||||
## 六、群聊在线控制与刷新机制
|
||||
|
||||
### 6.1 在线人数限制
|
||||
|
||||
- 当群聊在线人数超过上限(群主/后台可配置):
|
||||
- 群主与管理员不受上线限制,始终在线。
|
||||
- 系统自动将部分成员标记为离线:
|
||||
- 优先踢出近期未发言的成员;
|
||||
- 该过程对成员前端为“默默离线”,不会强制踢出页面。
|
||||
|
||||
### 6.2 重新上线与刷新
|
||||
|
||||
- 被标记为离线的成员:
|
||||
- 在输入框输入内容时,自动重新上线。
|
||||
- 新进群但未发言的成员:
|
||||
- 一段时间后,输入框变为“消息刷新”按钮;
|
||||
- 点击后重新加载消息,并作为新上线行为。
|
||||
- 在已超上线限制的状态下:
|
||||
- 新进入成员默认离线;
|
||||
- 需主动刷新或发言才开始拉取实时消息。
|
||||
|
||||
### 6.3 页面跳转与上线状态
|
||||
|
||||
- 在群聊中点击任何产品、品类跳转其他页面:
|
||||
- 无论是否超限,都视为离线(停止实时连接)。
|
||||
- 从商品/其他页面返回群聊页:
|
||||
- 自动恢复为在线状态。
|
||||
- 在商品页面点击“聊天”:
|
||||
- 跳回群聊,并恢复在线。
|
||||
|
||||
---
|
||||
|
||||
## 七、会话厅顶部类目与选品关系
|
||||
|
||||
### 7.1 顶部类目区
|
||||
|
||||
- 顶部显示:
|
||||
- 「全部」入口;
|
||||
- 若干热门类目。
|
||||
- 热门类目:
|
||||
- 群主从本群的主营/重点品类中选定;
|
||||
- 可对特别重要的类目打红点标记。
|
||||
- 展示方式:
|
||||
- 左右滑动;
|
||||
- 每行最多 8 个类目,最多展示两行。
|
||||
|
||||
### 7.2 选品关系
|
||||
|
||||
- 群主 = 分销顶层:
|
||||
- 群主在本群选品的结果,体现在“全部”和热门类目展示中。
|
||||
- 群员:
|
||||
- 无法直接在群内进行选品;
|
||||
- 仅能浏览、转发商品并参与分销。
|
||||
|
||||
---
|
||||
|
||||
## 八、群内订单与全域订单
|
||||
|
||||
### 8.1 群内订单发起
|
||||
|
||||
- 在群聊页面可以通过以下方式生成群内订单:
|
||||
- 使用专门的“群内订单发单入口”;
|
||||
- 将当前输入框的文字通过快捷键转换为订单(跳转到发单确认页)。
|
||||
- 生成的群内订单:
|
||||
- 在群聊中以订单卡片形式展示;
|
||||
- 提供“接单”按钮。
|
||||
|
||||
### 8.2 与专业版(师傅端)的联动
|
||||
|
||||
- 若群内发单时勾选“保险”等高级字段:
|
||||
- 该订单将按专业版(师傅端)逻辑处理;
|
||||
- 接单、保险、结算等均走专业端流程。
|
||||
- 群主可配置:
|
||||
- 群内订单是否仅允许本群服务人员接单;
|
||||
- 或是否允许进入大厅,被所有专业师傅接单。
|
||||
|
||||
### 8.3 全域订单
|
||||
|
||||
- 群主可将部分群内订单开放到“全域订单池”:
|
||||
- 其他群的服务商也能在“全域订单”中看到这些订单并接单。
|
||||
- 展示限制:
|
||||
- 在群页面或全域订单列表中:
|
||||
- 只有服务商能看到具体金额;
|
||||
- 普通消费者看不到金额。
|
||||
|
||||
### 8.4 订单生命周期(概念)
|
||||
|
||||
- 典型状态流:
|
||||
- 已发单 → 待服务(需要填写上门时间)→ 已提交 → 已付款 → 已完成。
|
||||
- 客户侧操作:
|
||||
- 在“已提交”中查看支付方式并确认;
|
||||
- 确认支付后进入“已付款”。
|
||||
- 服务侧操作:
|
||||
- 服务方确认“已收款,结单”,进入“已完成”。
|
||||
|
||||
### 8.5 纯发单群模式
|
||||
|
||||
- 对于“只发单、不聊天”的群:
|
||||
- 群聊可以不保持实时连接;
|
||||
- 用户仅在手动刷新时看到新订单;
|
||||
- 群形态接近“单纯接单页面”,以降低系统实时成本。
|
||||
|
||||
---
|
||||
|
||||
## 九、「我的」与运营视角
|
||||
|
||||
- “我的”页面沿用现有商城结构:
|
||||
- 包含分销中心、订单、选品等模块。
|
||||
- 统计以微信号为主视角:
|
||||
- 汇总展示该用户在不同房间、群中的运营情况;
|
||||
- 可按房间、群进行明细下钻。
|
||||
|
||||
---
|
||||
|
||||
## 十、后台与审计(功能级)
|
||||
|
||||
- 房间管理:
|
||||
- 房间申请审批;
|
||||
- 房间启用/禁用;
|
||||
- 房间级扣点/收费配置。
|
||||
- 群管理:
|
||||
- 建群申请审核;
|
||||
- 群启用/禁用;
|
||||
- 群主调整;
|
||||
- 系统机器人驻入/移除。
|
||||
- 审计日志:
|
||||
- 创建/修改房间、群;
|
||||
- 修改扣点与重要配置;
|
||||
- 关键权限调整(如群主、管理员变更)等操作均需记录。
|
||||
|
||||
---
|
||||
|
||||
**文档定位**:开发可读的功能说明(不含字段/接口细节)
|
||||
**用途**:指导后续接口设计、表结构设计与前后端实现拆分
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,299 @@
|
|||
# 群成员身份标签与权限管理功能文档
|
||||
|
||||
## 文档说明
|
||||
本文档描述群聊中**群成员身份标签、分类管理、权限控制、消息通知**相关的功能逻辑,不涉及字段/表结构设计,仅面向功能实现。
|
||||
|
||||
---
|
||||
|
||||
## 一、群成员身份标签系统
|
||||
|
||||
### 1.1 身份标签类型
|
||||
系统支持以下身份标签:
|
||||
- **创建者**:群创建者(通常也是群主)
|
||||
- **管理员**:被群主任命的管理员
|
||||
- **服务商家**:提供服务的商家/师傅
|
||||
- **商品商家**:提供商品的商家
|
||||
- **消费者**:普通消费者
|
||||
- **发单人**:经常发单的用户
|
||||
- **接单人**:经常接单的用户
|
||||
- **群成员**:普通群成员
|
||||
- **VIP客户**:VIP客户
|
||||
|
||||
### 1.2 标签分配流程
|
||||
- **入群时自选标签**
|
||||
- 用户加入群时,系统提供两个初始选项:
|
||||
- **非商家**
|
||||
- **商家**
|
||||
- 用户选择一个作为初始身份标识。
|
||||
- **群主/管理员最终确认**
|
||||
- 群主或管理员可以在群成员资料中:
|
||||
- 查看用户自选的标签。
|
||||
- 从系统标签库中选择一个标签,覆盖或确认用户的标签。
|
||||
- 后续可以随时修改成员的标签。
|
||||
- **标签对外展示**
|
||||
- 标签会显示在群成员资料、群成员列表等位置,作为该成员在群内的“对外身份”。
|
||||
|
||||
### 1.3 群成员资料栏位
|
||||
- **群成员资料页包含7个栏位**:
|
||||
- 每个栏位可以放置一个名称/备注。
|
||||
- 这些栏位对所有身份/标签的群员都开放使用。
|
||||
- 用途:方便所有群员查看和识别成员信息。
|
||||
|
||||
---
|
||||
|
||||
## 二、群成员分类/分组系统
|
||||
|
||||
### 2.1 分类概念
|
||||
- **分类定义**
|
||||
- 群内成员可以按照“分类”进行组织,每个分类可以理解为“分组”或“分仓”。
|
||||
- 系统支持创建 **1~7个分类**。
|
||||
- 每个分类可以自定义命名(例如“1类”、“2类”,或自定义别名如“核心商家组”、“普通客户组”等)。
|
||||
- **分类与标签的关系**
|
||||
- 分类与身份标签是**独立的两套体系**:
|
||||
- 一个成员可以拥有一个身份标签(如“服务商家”)。
|
||||
- 同时,该成员可以被放入任意一个分类中(如“1类”)。
|
||||
- 标签不影响分类归属,分类也不影响标签展示。
|
||||
|
||||
### 2.2 分类操作
|
||||
- **成员分类归属**
|
||||
- 任何成员可以被放入任意一个分类中。
|
||||
- 例如:可以将某个“服务商家”放入“1类”,也可以将某个“消费者”放入“1类”。
|
||||
- 成员可以只属于一个分类,也可以不属于任何分类(显示在“未分类”或“全部”中)。
|
||||
- **按分类查看成员**
|
||||
- 群主与管理员可以:
|
||||
- 按分类查看成员列表。
|
||||
- 按标签查看成员列表。
|
||||
- 按“分类+标签”组合筛选查看。
|
||||
- **普通群成员查看**
|
||||
- 普通群成员在群名单中:
|
||||
- 可以按“全部”及“标签身份”查看成员信息。
|
||||
- 不能按分类查看(分类信息对普通成员不展示)。
|
||||
|
||||
### 2.3 分类消息发送
|
||||
- **管理员按分类发消息**
|
||||
- 管理员可以:
|
||||
- 选择向某个分类的所有成员发送消息(其他分类看不到)。
|
||||
- 选择向某个分类中的单个成员发送消息。
|
||||
- 用途:主要用于群管理员进行精细化运营和定向通知。
|
||||
|
||||
---
|
||||
|
||||
## 三、管理员任命与权限体系
|
||||
|
||||
### 3.1 管理员任命
|
||||
- **任命流程**
|
||||
- 群主可以任命任意群成员为管理员。
|
||||
- 任命时可以:
|
||||
- 标注该管理员的“岗位名称”(例如“客服主管”、“运营专员”等)。
|
||||
- 有岗位名称的管理员会在“服务团队消息专列”中显示。
|
||||
- **订单交付权限(独立于管理员)**
|
||||
- 订单交付栏的权限与管理员身份独立:
|
||||
- 群主可以勾选某些成员(不一定是管理员)拥有“订单交付权限”。
|
||||
- 拥有交付权限的人可以在订单交付栏中发布交付信息。
|
||||
|
||||
### 3.2 管理员权限列表
|
||||
群主在任命管理员时,可以勾选该管理员拥有的权限项。管理员在哪个分类中不影响其权限范围。
|
||||
|
||||
#### 权限1:按类发群信息
|
||||
- 管理员可以向指定分类的所有成员发送群消息(其他分类看不到)。
|
||||
|
||||
#### 权限2:禁言与消息可见性控制
|
||||
- **禁言功能(实际为“审核可见”)**
|
||||
- 管理员可以按分类或单个成员设置“禁言”。
|
||||
- 被禁言的成员:
|
||||
- 仍然可以发送消息,但消息默认**仅管理员可见 + 自己可见**。
|
||||
- 管理员可以在后台审核这些消息,勾选后才会展示到群聊页面。
|
||||
- 严格来说这不是传统“禁言”,而是“审核可见”机制。
|
||||
- **消息可见性设置**
|
||||
- 管理员可以:
|
||||
- 按分类设置:该类群员发的消息仅该类成员可见,或仅管理员可见。
|
||||
- 按单个成员设置:该成员发的消息仅管理员可见(在群内形成独立通道,对其他人无感)。
|
||||
- **特殊规则**
|
||||
- 被禁言的成员仍然可以发送商品链接到群(商品链接不受禁言限制)。
|
||||
- 管理员查看消息的规则:
|
||||
- 如果管理员属于某个分类,只能看到该类群员发的信息。
|
||||
- 如果管理员在“全部”分类中,可以看到所有分类群员发的信息。
|
||||
- **管理员@解禁**
|
||||
- 管理员可以@被禁言的成员,临时解禁3小时。
|
||||
|
||||
#### 权限3:禁止接单
|
||||
- 管理员可以按分类或单个成员设置“禁止点击接单键”。
|
||||
- 被禁止的成员无法接取群消息中的订单。
|
||||
|
||||
#### 权限4:禁止发单
|
||||
- 管理员可以按分类或单个成员设置“禁止点击发单键”。
|
||||
- 被禁止的成员无法使用发单功能(包括类目发单)。
|
||||
|
||||
#### 权限5:禁止互加好友
|
||||
- 管理员可以按分类或单个成员设置“禁止互加好友”。
|
||||
- 被禁止的成员:
|
||||
- 别人无法添加他为好友。
|
||||
- 他也无法添加别人为好友。
|
||||
- **特殊规则**
|
||||
- 即使被禁止加好友,双方仍然可以:
|
||||
- 在服务团队聊天中直接对话(通过服务团队入口)。
|
||||
|
||||
#### 权限6:屏蔽群内信息
|
||||
- 管理员可以按分类或单个成员设置“屏蔽群内信息”。
|
||||
- 被屏蔽的成员:
|
||||
- 看不到群内在发的消息。
|
||||
- **但订单仍然可见可接**(屏蔽消息,不屏蔽订单展示)。
|
||||
|
||||
#### 权限7:禁止发圈信息
|
||||
- 管理员可以按分类或单个成员设置“禁止发圈信息”。
|
||||
- 被禁止的成员无法在商家圈/动态圈中发布内容。
|
||||
|
||||
#### 权限8:审核成员入群
|
||||
- 管理员可以审核新成员的入群申请。
|
||||
|
||||
#### 权限9:删除成员与撤回消息
|
||||
- 管理员可以:
|
||||
- 删除群成员(将成员移出群)。
|
||||
- 撤回群成员的消息:
|
||||
- 可以撤回任意成员的一条消息。
|
||||
- 可以彻底删除消息(删除后不可见,不可恢复)。
|
||||
|
||||
#### 权限10:分类分标签发公告
|
||||
- 管理员可以:
|
||||
- 按分类发送公告。
|
||||
- 按标签发送公告。
|
||||
- 按“分类+标签”组合发送公告。
|
||||
|
||||
---
|
||||
|
||||
## 四、群主专属权限
|
||||
|
||||
### 4.1 群名设置
|
||||
- 群主可以修改群名称。
|
||||
|
||||
### 4.2 群转让
|
||||
- 群主可以将群主身份转让给其他成员。
|
||||
|
||||
### 4.3 开通入群申请
|
||||
- 群主可以开启/关闭“入群申请”功能。
|
||||
- 开启后,新成员需要申请才能加入群。
|
||||
|
||||
### 4.4 待接单显示规则(待定)
|
||||
- 群主可以设置“待接单是否仅显示本群的订单”(此功能待定,可能不实现)。
|
||||
|
||||
---
|
||||
|
||||
## 五、群消息通知机制
|
||||
|
||||
### 5.1 消息通知基础规则
|
||||
|
||||
#### 未打开登录页面的通知策略
|
||||
- 用户未打开登录页面(APP未打开)时:
|
||||
- 系统每 **5分钟** 聚合一次新消息,发送一条通知。
|
||||
- 通知内容:显示所有群的新消息汇总(例如“您有X条新消息”)。
|
||||
- 用户打开APP后,不再发送聚合通知。
|
||||
|
||||
#### 群外消息计数
|
||||
- 在群列表页面(群外):
|
||||
- 每个群名旁边显示该群的消息数量角标。
|
||||
- APP端统一使用角标显示。
|
||||
|
||||
### 5.2 群消息免打扰设置
|
||||
|
||||
#### 免打扰选项
|
||||
每个群成员可以为自己设置该群的“免打扰”策略,选项包括:
|
||||
- **仅1小时1条**:1小时内只通知一次。
|
||||
- **仅1天1条**:1天内只通知一次。
|
||||
- **仅3天1条**:3天内只通知一次。
|
||||
- **仅10天1条**:10天内只通知一次。
|
||||
|
||||
#### 免打扰与通知队列的关系
|
||||
- 系统维护多个通知队列:
|
||||
- **5分钟通知队列**:默认队列,每5分钟通知一次。
|
||||
- **1小时通知队列**:设置了“1小时1条”的用户进入此队列。
|
||||
- **1天通知队列**:设置了“1天1条”的用户进入此队列。
|
||||
- **3天通知队列**:设置了“3天1条”的用户进入此队列。
|
||||
- **10天通知队列**:设置了“10天1条”的用户进入此队列。
|
||||
- 用户设置免打扰后:
|
||||
- 从“5分钟队列”中剔除,进入对应的免打扰队列。
|
||||
- 例如:设置“1小时1条”后,每1小时聚合通知一次(而不是每5分钟)。
|
||||
|
||||
#### 通知时间窗口
|
||||
- **5分钟队列与1小时队列**:
|
||||
- 晚上7点后不通知。
|
||||
- 早上8点后才开始通知。
|
||||
- **1天队列、3天队列、10天队列**:
|
||||
- 通知时间点可以设定在12点,或错开时间点(例如1天队列12点,3天队列14点,10天队列16点),以减少大量通知同时推送。
|
||||
|
||||
#### 用户类型与免打扰选择
|
||||
- **经营者(商家/师傅)**:
|
||||
- 更多选择“5分钟通知”或“1小时通知”(需要及时响应)。
|
||||
- **客户(消费者)**:
|
||||
- 更多选择“3天通知”或“10天通知”(降低打扰频率)。
|
||||
|
||||
### 5.3 @通知机制
|
||||
|
||||
#### @通知规则
|
||||
- **无论用户是否设置免打扰**,被@时:
|
||||
- 使用**手机上方消息栏**直接通知(不进入队列等待)。
|
||||
- 通知带有声音提醒(用户可以自定义声音)。
|
||||
- 不等待5分钟/1小时等时间窗口,立即推送。
|
||||
|
||||
#### @通知展示位置
|
||||
- @通知显示在手机顶部通知栏(系统级通知)。
|
||||
|
||||
---
|
||||
|
||||
## 六、消息通知总结
|
||||
|
||||
### 6.1 通知队列体系
|
||||
系统维护以下通知队列:
|
||||
1. **5分钟通知队列**(默认)
|
||||
- 时间窗口:早上8点 ~ 晚上7点。
|
||||
- 每5分钟聚合通知一次。
|
||||
2. **1小时通知队列**
|
||||
- 时间窗口:早上8点 ~ 晚上7点。
|
||||
- 每1小时聚合通知一次。
|
||||
3. **1天通知队列**
|
||||
- 在指定时间点(例如12点)通知一次。
|
||||
4. **3天通知队列**
|
||||
- 在指定时间点(例如14点)通知一次。
|
||||
5. **10天通知队列**
|
||||
- 在指定时间点(例如16点)通知一次。
|
||||
|
||||
### 6.2 特殊通知(不受队列限制)
|
||||
- **@通知**:
|
||||
- 立即推送,使用手机顶部通知栏。
|
||||
- 带声音提醒。
|
||||
- 不受免打扰设置影响。
|
||||
|
||||
### 6.3 通知聚合规则
|
||||
- **未打开APP时**:
|
||||
- 所有群的新消息统一聚合为一条通知(例如“您有X条新消息”)。
|
||||
- 按用户所属队列的时间窗口进行通知。
|
||||
- **打开APP后**:
|
||||
- 不再发送聚合通知。
|
||||
- 用户可以在APP内查看各群的具体消息。
|
||||
|
||||
---
|
||||
|
||||
## 七、功能总结
|
||||
|
||||
### 7.1 身份标签与分类
|
||||
- 9种身份标签,入群时自选,群主/管理员可最终确认和修改。
|
||||
- 支持1~7个分类,分类与标签独立,成员可被放入任意分类。
|
||||
|
||||
### 7.2 管理员权限
|
||||
- 10个权限点,群主可灵活配置每个管理员的权限。
|
||||
- 订单交付权限独立于管理员身份。
|
||||
|
||||
### 7.3 消息通知
|
||||
- 5个通知队列(5分钟/1小时/1天/3天/10天),用户可自由选择。
|
||||
- @通知立即推送,不受免打扰影响。
|
||||
- 时间窗口控制,避免夜间打扰。
|
||||
|
||||
---
|
||||
|
||||
## 八、待定事项
|
||||
- 待接单是否仅显示本群的订单(功能待定)。
|
||||
|
||||
---
|
||||
|
||||
**文档版本**:v1.0
|
||||
**最后更新**:2024年
|
||||
|
||||
|
|
@ -17,6 +17,38 @@
|
|||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.tencentcloudapi.cls</groupId>
|
||||
<artifactId>tencentcloud-cls-logback-appender</artifactId>
|
||||
<version>1.0.3</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 阿里云api-SDK -->
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>dytnsapi20200217</artifactId>
|
||||
<version>2.9.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>tea-openapi</artifactId>
|
||||
<version>0.3.6</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>tea-console</artifactId>
|
||||
<version>0.0.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>tea-util</artifactId>
|
||||
<version>0.2.23</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- SpringBoot集成thymeleaf模板 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
|
@ -111,6 +143,10 @@
|
|||
<artifactId>spring-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.ghy</groupId>
|
||||
<artifactId>ghy-shop</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
|
|
|||
|
|
@ -4,13 +4,18 @@ import org.springframework.boot.SpringApplication;
|
|||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||
import org.springframework.web.filter.CorsFilter;
|
||||
|
||||
/**
|
||||
* 启动程序
|
||||
*
|
||||
* @author clunt
|
||||
*/
|
||||
@EnableScheduling
|
||||
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
|
||||
public class GhyApplication
|
||||
{
|
||||
|
|
@ -34,4 +39,25 @@ public class GhyApplication
|
|||
public RestTemplate restTemplate(){
|
||||
return new RestTemplate();
|
||||
}
|
||||
|
||||
|
||||
private CorsConfiguration corsConfig() {
|
||||
CorsConfiguration corsConfiguration = new CorsConfiguration();
|
||||
// 请求常用的三种配置,*代表允许所有,当时你也可以自定义属性(比如header只能带什么,只能是post方式等等)
|
||||
// corsConfiguration.addAllowedOrigin("*");
|
||||
corsConfiguration.addAllowedHeader("*");
|
||||
corsConfiguration.addAllowedMethod("*");
|
||||
corsConfiguration.setAllowCredentials(true);
|
||||
corsConfiguration.addAllowedOriginPattern("*");
|
||||
corsConfiguration.setMaxAge(3600L);
|
||||
return corsConfiguration;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CorsFilter corsFilter() {
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
source.registerCorsConfiguration("/**", corsConfig());
|
||||
return new CorsFilter(source);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -7,21 +7,27 @@ import com.ghy.common.adapay.model.Event;
|
|||
import com.ghy.common.adapay.model.PayCallback;
|
||||
import com.ghy.common.adapay.model.PaymentDTO;
|
||||
import com.ghy.common.enums.PayStatus;
|
||||
import com.ghy.order.domain.OrderAddSubtract;
|
||||
import com.ghy.order.domain.OrderMaster;
|
||||
import com.ghy.order.mapper.OrderMasterMapper;
|
||||
import com.ghy.order.service.IOrderAddSubtractService;
|
||||
import com.ghy.order.service.OrderMasterService;
|
||||
import com.ghy.payment.domain.FinancialChangeRecord;
|
||||
import com.ghy.payment.domain.FinancialDetail;
|
||||
import com.ghy.payment.domain.FinancialMaster;
|
||||
import com.ghy.payment.domain.PaymentRelation;
|
||||
import com.ghy.payment.mapper.PaymentRelationMapper;
|
||||
import com.ghy.payment.service.CallBackService;
|
||||
import com.ghy.payment.service.FinancialChangeRecordService;
|
||||
import com.ghy.payment.service.FinancialDetailService;
|
||||
import com.ghy.payment.service.FinancialMasterService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
|
|
@ -29,98 +35,160 @@ import java.util.concurrent.CompletableFuture;
|
|||
*
|
||||
* @author HH 2022/5/31
|
||||
*/
|
||||
@Slf4j
|
||||
@Service("payCallbackService")
|
||||
public class PayCallbackService implements CallBackService {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(PayCallbackService.class);
|
||||
@Resource
|
||||
OrderMasterService orderMasterService;
|
||||
|
||||
@Resource
|
||||
FinancialMasterService financialMasterService;
|
||||
|
||||
@Resource
|
||||
PaymentRelationMapper paymentRelationMapper;
|
||||
@Resource
|
||||
FinancialDetailService financialDetailService;
|
||||
|
||||
@Resource
|
||||
IOrderAddSubtractService orderAddSubtractService;
|
||||
@Resource
|
||||
FinancialChangeRecordService financialChangeRecordService;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void onCallback(Event event) {
|
||||
logger.info("支付回调: {}", event);
|
||||
log.info("支付回调: {}", event);
|
||||
String data = event.getData();
|
||||
PayCallback payment = JSON.parseObject(data, PayCallback.class);
|
||||
PaymentDTO dto = financialMasterService.selectPaymentById(payment.getId());
|
||||
// 校验是否是本系统发出去的支付请求
|
||||
if (dto != null) {
|
||||
CompletableFuture.runAsync(() -> {
|
||||
// 异步更新交易记录 避免被回滚
|
||||
PaymentDTO param = new PaymentDTO();
|
||||
param.setId(payment.getId());
|
||||
// 支付ID
|
||||
final String paymentId = dto.getId();
|
||||
// 是否支付成功
|
||||
final boolean succeeded = AdapayStatusEnum.succeeded.code.equals(payment.getStatus());
|
||||
|
||||
// 异步更新交易记录 避免被其它业务异常回滚
|
||||
CompletableFuture.runAsync(() -> {
|
||||
PaymentDTO param = new PaymentDTO();
|
||||
param.setId(payment.getId());
|
||||
param.setStatus(payment.getStatus());
|
||||
if (succeeded) {
|
||||
// 如果支付成功 更新支付渠道、支付时间、手续费
|
||||
param.setPayChannel(payment.getPayChannel());
|
||||
param.setFeeAmt(payment.getFeeAmt());
|
||||
param.setStatus(payment.getStatus());
|
||||
param.setPayTime(LocalDateTime.now());
|
||||
financialMasterService.updatePayment(param);
|
||||
});
|
||||
if (AdapayStatusEnum.succeeded.code.equals(payment.getStatus())) {
|
||||
if (payment.getOrderNo().split("_").length > 2) {
|
||||
// 支付回调中的加价记录ID
|
||||
String fcrIdStr = payment.getOrderNo().split("_")[1];
|
||||
String[] fcrIds = fcrIdStr.split(",");
|
||||
if ("delay".equals(dto.getPayMode())) {
|
||||
// 如果支付成功 且是延迟分账模式 更新可用金额=交易金额
|
||||
param.setAvailableAmt(dto.getPayAmt());
|
||||
}
|
||||
}
|
||||
financialMasterService.updatePayment(param);
|
||||
});
|
||||
|
||||
BigDecimal totalChangeMoney = BigDecimal.ZERO;
|
||||
Long financialMasterId = null;
|
||||
for (String fcrId : fcrIds) {
|
||||
FinancialChangeRecord financialChangeRecord = new FinancialChangeRecord();
|
||||
financialChangeRecord.setId(Long.valueOf(fcrId));
|
||||
financialChangeRecord.setPayStatus(1);
|
||||
// 加价的支付paymentId回填到remark
|
||||
financialChangeRecord.setRemark(payment.getId());
|
||||
financialChangeRecord.setRemark(payment.getId());
|
||||
financialChangeRecord.setPaymentId(payment.getId());
|
||||
financialChangeRecordService.update(financialChangeRecord);
|
||||
if (succeeded) {
|
||||
// 支付成功 查询支付关联的订单
|
||||
List<PaymentRelation> paymentRelations = paymentRelationMapper.selectByPaymentId(paymentId);
|
||||
if (CollectionUtils.isEmpty(paymentRelations)) {
|
||||
log.error("未关联订单的支付回调: {}", data);
|
||||
return;
|
||||
}
|
||||
|
||||
// 修改子订单的payMoney
|
||||
FinancialChangeRecord fc = financialChangeRecordService.selectFinancialChangeRecordById(financialChangeRecord.getId());
|
||||
FinancialDetail financialDetail = financialDetailService.selectByOrderDetailId(fc.getOrderDetailId());
|
||||
FinancialDetail financialDetail2Update = new FinancialDetail();
|
||||
financialDetail2Update.setId(financialDetail.getId());
|
||||
financialDetail2Update.setPayMoney(financialDetail.getPayMoney().add(fc.getChangeMoney()));
|
||||
financialDetail2Update.setPayStatus(PayStatus.PAID.getCode());
|
||||
financialDetailService.updateFinancialDetail(financialDetail2Update);
|
||||
totalChangeMoney = totalChangeMoney.add(fc.getChangeMoney());
|
||||
if (financialMasterId == null) {
|
||||
financialMasterId = financialDetail.getFinancialMasterId();
|
||||
for (PaymentRelation relation : paymentRelations) {
|
||||
Long relationId = relation.getRelationId();
|
||||
if (PaymentRelation.FINANCIAL_MASTER.equals(relation.getRelationIdType())) {
|
||||
FinancialMaster financialMaster = financialMasterService.selectById(relationId);
|
||||
// 更新主订单的支付信息
|
||||
orderMasterService.updatePayStatus(financialMaster.getOrderMasterId(), PayStatus.PAID.getCode());
|
||||
// 更新主财务单的支付信息
|
||||
financialMasterService.updatePay(relationId, paymentId, PayStatus.PAID.getCode());
|
||||
log.info("主财务单[{}]支付成功", relationId);
|
||||
|
||||
// 检查是否为商品订单且有关联的服务订单,需要同步更新服务订单财务主单支付状态
|
||||
try {
|
||||
OrderMaster orderMaster = orderMasterService.selectById(financialMaster.getOrderMasterId());
|
||||
if (orderMaster != null && orderMaster.getOrderType() == 1 && orderMaster.getHasServiceOrder() == 1) {
|
||||
// 查询关联的服务订单
|
||||
OrderMaster serviceOrder = orderMasterService.selectByGoodsOrderMasterId(orderMaster.getId());
|
||||
if (serviceOrder != null) {
|
||||
// 查询服务订单对应的财务主单
|
||||
FinancialMaster serviceFinancialMaster = financialMasterService.selectByOrderMasterId(serviceOrder.getId());
|
||||
if (serviceFinancialMaster != null && !PayStatus.PAID.getCode().equals(serviceFinancialMaster.getPayStatus())) {
|
||||
// 更新服务订单财务主单支付状态
|
||||
financialMasterService.updatePay(serviceFinancialMaster.getId(), paymentId, PayStatus.PAID.getCode());
|
||||
// 更新服务订单支付状态
|
||||
orderMasterService.updatePayStatus(serviceOrder.getId(), PayStatus.PAID.getCode());
|
||||
log.info("商品订单[{}]关联的服务订单[{}]财务主单[{}]支付状态已同步更新为已支付",
|
||||
orderMaster.getId(), serviceOrder.getId(), serviceFinancialMaster.getId());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("同步更新商品订单关联服务订单支付状态时发生异常,商品订单ID: {}, 异常信息: {}",
|
||||
financialMaster.getOrderMasterId(), e.getMessage(), e);
|
||||
}
|
||||
|
||||
} else if (PaymentRelation.FINANCIAL_CHANGE.equals(relation.getRelationIdType())) {
|
||||
|
||||
// 更新加价单的支付信息
|
||||
financialChangeRecordService.updatePay(relationId, paymentId, PayStatus.PAID.getCode());
|
||||
FinancialChangeRecord fc = financialChangeRecordService.selectFinancialChangeRecordById(relationId);
|
||||
// 修改子订单的payMoney
|
||||
FinancialDetail fd = financialDetailService.selectByOrderDetailId(fc.getOrderDetailId());
|
||||
FinancialDetail fd2Update = new FinancialDetail();
|
||||
fd2Update.setId(fd.getId());
|
||||
fd2Update.setPayMoney(fd.getPayMoney());
|
||||
fd2Update.setPayStatus(PayStatus.PAID.getCode());
|
||||
financialDetailService.updateFinancialDetail(fd2Update);
|
||||
// 修改主单的payMoney
|
||||
FinancialMaster financialMaster = financialMasterService.selectById(financialMasterId);
|
||||
FinancialMaster financialMaster = financialMasterService.selectById(fd.getFinancialMasterId());
|
||||
FinancialMaster financialMaster2Update = new FinancialMaster();
|
||||
financialMaster2Update.setId(financialMaster.getId());
|
||||
financialMaster2Update.setPayMoney(financialMaster.getPayMoney().add(totalChangeMoney));
|
||||
financialMaster2Update.setPayMoney(financialMaster.getPayMoney());
|
||||
financialMaster2Update.setPayStatus(PayStatus.PAID.getCode());
|
||||
financialMasterService.updateFinancialMaster(financialMaster2Update);
|
||||
// TODO 拆分对应的分账流水
|
||||
// 更新主订单的支付信息
|
||||
orderMasterService.updatePayStatus(financialMaster.getOrderMasterId(), PayStatus.PAID.getCode());
|
||||
log.info("FinancialChange[{}]支付成功", relationId);
|
||||
|
||||
} else if (PaymentRelation.ORDER_ADD.equals(relation.getRelationIdType())) {
|
||||
// 更新订单追加单的支付信息
|
||||
orderAddSubtractService.updatePay(relationId, paymentId, PayStatus.PAID.getCode());
|
||||
OrderAddSubtract orderAdd = orderAddSubtractService.selectById(relationId);
|
||||
// 修改子订单的payMoney
|
||||
FinancialDetail fd = financialDetailService.selectByOrderDetailId(orderAdd.getOrderDetailId());
|
||||
FinancialDetail fd2Update = new FinancialDetail();
|
||||
fd2Update.setId(fd.getId());
|
||||
fd2Update.setPayMoney(fd.getPayMoney());
|
||||
fd2Update.setPayStatus(PayStatus.PAID.getCode());
|
||||
financialDetailService.updateFinancialDetail(fd2Update);
|
||||
// 修改主单的payMoney
|
||||
FinancialMaster financialMaster = financialMasterService.selectById(fd.getFinancialMasterId());
|
||||
FinancialMaster financialMaster2Update = new FinancialMaster();
|
||||
financialMaster2Update.setId(financialMaster.getId());
|
||||
financialMaster2Update.setPayMoney(financialMaster.getPayMoney());
|
||||
financialMaster2Update.setPayStatus(PayStatus.PAID.getCode());
|
||||
financialMasterService.updateFinancialMaster(financialMaster2Update);
|
||||
log.info("订单追加[{}]支付成功", relationId);
|
||||
|
||||
} else if (PaymentRelation.CONSULT_ADD.equals(relation.getRelationIdType())) {
|
||||
// 更新加价单的支付信息
|
||||
financialChangeRecordService.updatePay(relationId, paymentId, PayStatus.PAID.getCode());
|
||||
} else {
|
||||
log.error("未知的订单类型: relationIdType={}, relationId={}", relation.getRelationIdType(), relationId);
|
||||
}
|
||||
// 更新主财务单状态
|
||||
financialMasterService.paySucceeded(payment.getId(), payment.getPayChannel());
|
||||
} else {
|
||||
logger.warn("支付失败 : {}", data);
|
||||
}
|
||||
} else {
|
||||
logger.warn("系统中不存在这条交易记录: {}", event);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(JSONObject response) {
|
||||
logger.info("发起支付 Response: {}", response.toJSONString());
|
||||
log.info("发起支付 Response: {}", response.toJSONString());
|
||||
// 保存一条支付记录
|
||||
PaymentDTO payment = response.toJavaObject(PaymentDTO.class);
|
||||
String status = payment.getStatus();
|
||||
payment.setStatus(AdapayStatusEnum.pending.code);
|
||||
financialMasterService.insertPayment(payment);
|
||||
|
||||
if (!AdapayStatusEnum.succeeded.code.equals(status)) {
|
||||
logger.warn("发起支付失败 : {}", response.toJSONString());
|
||||
log.warn("发起支付失败 : {}", response.toJSONString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
package com.ghy.callback;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.ghy.common.adapay.model.AdapayStatusEnum;
|
||||
import com.ghy.common.adapay.model.Event;
|
||||
import com.ghy.common.adapay.model.PaymentDTO;
|
||||
import com.ghy.common.utils.MoneyUtil;
|
||||
import com.ghy.payment.domain.PaymentConfirm;
|
||||
import com.ghy.payment.mapper.PaymentConfirmMapper;
|
||||
import com.ghy.payment.mapper.PaymentMapper;
|
||||
import com.ghy.payment.service.CallBackService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Service("paymentConfirmCallbackService")
|
||||
public class PaymentConfirmCallbackService implements CallBackService {
|
||||
|
||||
@Resource
|
||||
private PaymentMapper paymentMapper;
|
||||
@Resource
|
||||
private PaymentConfirmMapper paymentConfirmMapper;
|
||||
|
||||
@Override
|
||||
public void onCallback(Event event) {
|
||||
// 支付确认没有callback
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(JSONObject response) {
|
||||
if (AdapayStatusEnum.succeeded.code.equals(response.getString("status")) ||
|
||||
AdapayStatusEnum.pending.code.equals(response.getString("status"))) {
|
||||
// 支付确认 操作成功
|
||||
PaymentConfirm paymentConfirm = response.toJavaObject(PaymentConfirm.class);
|
||||
// 保存支付确认记录
|
||||
paymentConfirmMapper.insert(paymentConfirm);
|
||||
// 更新支付单信息
|
||||
updatePayment(paymentConfirm);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void updatePayment(PaymentConfirm paymentConfirm) {
|
||||
String paymentId = paymentConfirm.getPaymentId();
|
||||
PaymentDTO payment = paymentMapper.selectById(paymentId);
|
||||
// 支付金额
|
||||
BigDecimal payAmt = new BigDecimal(payment.getPayAmt());
|
||||
// 已确认金额
|
||||
BigDecimal confirmedAmt = new BigDecimal(paymentConfirm.getConfirmedAmt());
|
||||
// 已退款金额
|
||||
BigDecimal refundedAmt = new BigDecimal(paymentConfirm.getRefundedAmt());
|
||||
// 已撤销金额
|
||||
BigDecimal reservedAmt = new BigDecimal(paymentConfirm.getReservedAmt());
|
||||
// 可支配金额 = 支付金额 - 已确认金额 - 已退款金额 - 已撤销金额
|
||||
BigDecimal availableAmt = payAmt.subtract(confirmedAmt).subtract(refundedAmt).subtract(reservedAmt);
|
||||
|
||||
// 更新支付单信息
|
||||
PaymentDTO payment2up = new PaymentDTO();
|
||||
payment2up.setId(paymentId);
|
||||
payment2up.setConfirmedAmt(paymentConfirm.getConfirmedAmt());
|
||||
payment2up.setRefundedAmt(paymentConfirm.getRefundedAmt());
|
||||
payment2up.setReservedAmt(paymentConfirm.getReservedAmt());
|
||||
payment2up.setAvailableAmt(MoneyUtil.toS(availableAmt));
|
||||
paymentMapper.updatePayment(payment2up);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package com.ghy.web.controller;
|
||||
|
||||
|
||||
import com.ghy.common.dto.DataEntityDTO;
|
||||
import com.ghy.common.enums.WxMsgEnum;
|
||||
import com.ghy.common.utils.WechatMsgUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author 但星霖
|
||||
* @Date 2023-09-28 10:42:56
|
||||
* 说明:
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/mesg/test")
|
||||
public class MesgTestController {
|
||||
|
||||
@GetMapping("/{openId}")
|
||||
public void edit(@PathVariable("openId") String openId){
|
||||
try {
|
||||
// 消息组装。
|
||||
Map<String, Object> paramsNew = new HashMap<>();
|
||||
// 订单编号
|
||||
paramsNew.put("character_string1", new DataEntityDTO("12312"));
|
||||
// 名称
|
||||
paramsNew.put("thing2", new DataEntityDTO("订单被拒通知"));
|
||||
// 预约时间
|
||||
paramsNew.put("data8", new DataEntityDTO(com.ghy.common.utils.DateUtils.parseDateToStr("yyyy年MM月dd日 HH:mm", new Date())));
|
||||
// 师傅姓名
|
||||
paramsNew.put("name3", new DataEntityDTO("测试"));
|
||||
// 服务区域
|
||||
paramsNew.put("thing4", new DataEntityDTO("成都市"));
|
||||
// 消息推送
|
||||
WechatMsgUtils.sendWeChatMsg(WechatMsgUtils.getToken(), openId, WxMsgEnum.TEXT, paramsNew);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,576 @@
|
|||
package com.ghy.web.controller;
|
||||
|
||||
import com.ghy.common.core.controller.BaseController;
|
||||
import com.ghy.shop.domain.Shop;
|
||||
import com.ghy.shop.domain.ShopDistanceQuery;
|
||||
import com.ghy.shop.service.ShopService;
|
||||
import com.ghy.common.core.domain.AjaxResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import java.util.List;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import com.ghy.common.utils.LocationUtils;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* 店铺管理接口
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/shop")
|
||||
public class ShopController extends BaseController {
|
||||
@Autowired
|
||||
private ShopService shopService;
|
||||
|
||||
@Autowired
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
@PostMapping("/add")
|
||||
public AjaxResult addShop(@RequestBody Shop shop) {
|
||||
// 如果没有经纬度,尝试通过地址解析获取
|
||||
if ((shop.getLatitude() == null || shop.getLongitude() == null) &&
|
||||
shop.getAddress() != null && !shop.getAddress().trim().isEmpty()) {
|
||||
try {
|
||||
Map<String, Double> coordinates = getCoordinatesByAddress(shop);
|
||||
if (coordinates != null) {
|
||||
shop.setLatitude(coordinates.get("latitude"));
|
||||
shop.setLongitude(coordinates.get("longitude"));
|
||||
logger.info("为店铺[{}]自动获取到坐标: 经度={}, 纬度={}",
|
||||
shop.getShopName(), shop.getLongitude(), shop.getLatitude());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("获取地址经纬度失败: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
int result = shopService.addShop(shop);
|
||||
if (result > 0) {
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("shopId", shop.getShopId());
|
||||
response.put("shopName", shop.getShopName());
|
||||
response.put("latitude", shop.getLatitude());
|
||||
response.put("longitude", shop.getLongitude());
|
||||
response.put("address", shop.getAddress());
|
||||
return AjaxResult.success("店铺创建成功", response);
|
||||
} else {
|
||||
return AjaxResult.error("店铺创建失败");
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
public AjaxResult listShops() {
|
||||
List<Shop> list = shopService.listShops();
|
||||
return AjaxResult.success(list);
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public AjaxResult getShop(@PathVariable Long id) {
|
||||
Shop shop = shopService.getShop(id);
|
||||
return shop != null ? AjaxResult.success(shop) : AjaxResult.error("未找到店铺");
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public AjaxResult updateShop(@RequestBody Shop shop) {
|
||||
// 如果没有经纬度但有地址,尝试通过地址解析获取经纬度
|
||||
if ((shop.getLatitude() == null || shop.getLongitude() == null) &&
|
||||
shop.getAddress() != null && !shop.getAddress().trim().isEmpty()) {
|
||||
try {
|
||||
Map<String, Double> coordinates = getCoordinatesByAddress(shop);
|
||||
if (coordinates != null) {
|
||||
shop.setLatitude(coordinates.get("latitude"));
|
||||
shop.setLongitude(coordinates.get("longitude"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("更新店铺时获取地址经纬度失败: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
return toAjax(shopService.updateShop(shop));
|
||||
}
|
||||
|
||||
@PostMapping("/delete/{id}")
|
||||
public AjaxResult deleteShop(@PathVariable Long id) {
|
||||
return toAjax(shopService.deleteShop(id));
|
||||
}
|
||||
|
||||
@GetMapping("/{id}/location")
|
||||
public AjaxResult getShopLocation(@PathVariable Long id) {
|
||||
Shop shop = shopService.getShop(id);
|
||||
if (shop == null) {
|
||||
return AjaxResult.error("未找到店铺");
|
||||
}
|
||||
Map<String, Object> location = new HashMap<>();
|
||||
location.put("address", shop.getAddress());
|
||||
location.put("latitude", shop.getLatitude());
|
||||
location.put("longitude", shop.getLongitude());
|
||||
location.put("provinceName", shop.getProvinceName());
|
||||
location.put("cityName", shop.getCityName());
|
||||
location.put("countryName", shop.getCountryName());
|
||||
location.put("streetName", shop.getStreetName());
|
||||
return AjaxResult.success(location);
|
||||
}
|
||||
|
||||
// @GetMapping("/getCurrentLocation")
|
||||
// public AjaxResult getCurrentLocation() {
|
||||
// try {
|
||||
// // 直接调用百度地图API获取当前位置信息
|
||||
// String url = "/tool/baidu/getLocation";
|
||||
// return restTemplate.getForObject(url, AjaxResult.class);
|
||||
// } catch (Exception e) {
|
||||
// return AjaxResult.error("获取当前位置失败:" + e.getMessage());
|
||||
// }
|
||||
// }
|
||||
|
||||
@GetMapping("/worker/{workerId}")
|
||||
public AjaxResult getShopsByWorkerId(@PathVariable Long workerId) {
|
||||
List<Shop> shops = shopService.getShopsByWorkerId(workerId);
|
||||
return AjaxResult.success(shops);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 通过地址获取经纬度坐标
|
||||
// */
|
||||
// @PostMapping("/getCoordinates")
|
||||
// public AjaxResult getCoordinatesByAddress(@RequestBody Shop shop) {
|
||||
// try {
|
||||
// Map<String, Double> coordinates = getCoordinatesByAddress(shop);
|
||||
// if (coordinates != null) {
|
||||
// return AjaxResult.success("获取坐标成功", coordinates);
|
||||
// } else {
|
||||
// return AjaxResult.error("无法获取该地址的坐标信息");
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// logger.error("获取坐标失败: {}", e.getMessage(), e);
|
||||
// return AjaxResult.error("获取坐标失败: " + e.getMessage());
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* 通过经纬度逆解析获取地址信息并保存到店铺
|
||||
*/
|
||||
@PostMapping("/saveShopByLocation")
|
||||
public AjaxResult saveShopByLocation(@RequestBody Map<String, Object> params) {
|
||||
try {
|
||||
String location = params.get("location").toString(); // 格式: "经度,纬度"
|
||||
|
||||
// 调用百度地图逆解析API
|
||||
String url = "/tool/baidu/getLocation";
|
||||
Map<String, String> requestBody = new HashMap<>();
|
||||
requestBody.put("location", location);
|
||||
|
||||
// 这里应该调用百度接口获取地址信息
|
||||
// AjaxResult locationResult = restTemplate.postForObject(url, requestBody, AjaxResult.class);
|
||||
|
||||
// 解析经纬度
|
||||
String[] coordinates = location.split(",");
|
||||
if (coordinates.length != 2) {
|
||||
return AjaxResult.error("location格式错误,应为:经度,纬度");
|
||||
}
|
||||
|
||||
Double longitude = Double.parseDouble(coordinates[0]);
|
||||
Double latitude = Double.parseDouble(coordinates[1]);
|
||||
|
||||
// 创建店铺对象
|
||||
Shop shop = new Shop();
|
||||
shop.setLongitude(longitude);
|
||||
shop.setLatitude(latitude);
|
||||
|
||||
// 设置其他信息
|
||||
if (params.containsKey("shopName")) {
|
||||
shop.setShopName(params.get("shopName").toString());
|
||||
}
|
||||
if (params.containsKey("workerId")) {
|
||||
shop.setWorkerId(Long.valueOf(params.get("workerId").toString()));
|
||||
}
|
||||
if (params.containsKey("phone")) {
|
||||
shop.setPhone(params.get("phone").toString());
|
||||
}
|
||||
|
||||
// 保存店铺
|
||||
int result = shopService.addShop(shop);
|
||||
if (result > 0) {
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("shopId", shop.getShopId());
|
||||
response.put("longitude", longitude);
|
||||
response.put("latitude", latitude);
|
||||
response.put("location", location);
|
||||
return AjaxResult.success("店铺创建成功", response);
|
||||
} else {
|
||||
return AjaxResult.error("店铺创建失败");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("通过位置创建店铺失败: {}", e.getMessage(), e);
|
||||
return AjaxResult.error("创建失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 内部方法:通过地址解析获取经纬度
|
||||
*/
|
||||
private Map<String, Double> getCoordinatesByAddress(Shop shop) {
|
||||
try {
|
||||
// 构建完整地址
|
||||
StringBuilder fullAddress = new StringBuilder();
|
||||
if (shop.getProvinceName() != null) fullAddress.append(shop.getProvinceName());
|
||||
if (shop.getCityName() != null) fullAddress.append(shop.getCityName());
|
||||
if (shop.getCountryName() != null) fullAddress.append(shop.getCountryName());
|
||||
if (shop.getStreetName() != null) fullAddress.append(shop.getStreetName());
|
||||
if (shop.getAddress() != null) fullAddress.append(shop.getAddress());
|
||||
|
||||
String address = fullAddress.toString();
|
||||
if (address.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
logger.info("开始解析地址获取坐标: {}", address);
|
||||
|
||||
// TODO: 这里应该调用真实的地图API
|
||||
// 示例:百度地图正向地理编码API
|
||||
// String url = "https://api.map.baidu.com/geocoding/v3/?address=" +
|
||||
// java.net.URLEncoder.encode(address, "UTF-8") +
|
||||
// "&output=json&ak=YOUR_BAIDU_API_KEY";
|
||||
//
|
||||
// String result = restTemplate.getForObject(url, String.class);
|
||||
// JSONObject jsonResult = JSONObject.parseObject(result);
|
||||
//
|
||||
// if ("0".equals(jsonResult.getString("status"))) {
|
||||
// JSONObject location = jsonResult.getJSONObject("result").getJSONObject("location");
|
||||
// Double lng = location.getDouble("lng");
|
||||
// Double lat = location.getDouble("lat");
|
||||
//
|
||||
// Map<String, Double> coordinates = new HashMap<>();
|
||||
// coordinates.put("longitude", lng);
|
||||
// coordinates.put("latitude", lat);
|
||||
// return coordinates;
|
||||
// }
|
||||
|
||||
// 临时返回示例坐标(实际使用时请替换为真实的API调用)
|
||||
Map<String, Double> coordinates = new HashMap<>();
|
||||
coordinates.put("latitude", 39.915 + Math.random() * 0.1); // 示例纬度
|
||||
coordinates.put("longitude", 116.404 + Math.random() * 0.1); // 示例经度
|
||||
|
||||
logger.info("地址解析成功: {} -> 经度={}, 纬度={}",
|
||||
address, coordinates.get("longitude"), coordinates.get("latitude"));
|
||||
|
||||
return coordinates;
|
||||
} catch (Exception e) {
|
||||
logger.error("地址解析失败: {}", e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动设置店铺经纬度
|
||||
*/
|
||||
@PostMapping("/setCoordinates")
|
||||
public AjaxResult setCoordinates(@RequestBody Map<String, Object> params) {
|
||||
try {
|
||||
Long shopId = Long.valueOf(params.get("shopId").toString());
|
||||
Double latitude = Double.valueOf(params.get("latitude").toString());
|
||||
Double longitude = Double.valueOf(params.get("longitude").toString());
|
||||
|
||||
Shop shop = new Shop();
|
||||
shop.setShopId(shopId);
|
||||
shop.setLatitude(latitude);
|
||||
shop.setLongitude(longitude);
|
||||
|
||||
int result = shopService.updateShop(shop);
|
||||
if (result > 0) {
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("shopId", shopId);
|
||||
response.put("latitude", latitude);
|
||||
response.put("longitude", longitude);
|
||||
return AjaxResult.success("坐标设置成功", response);
|
||||
} else {
|
||||
return AjaxResult.error("坐标设置失败");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("设置坐标失败: {}", e.getMessage(), e);
|
||||
return AjaxResult.error("设置坐标失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量查询店铺(包含经纬度信息)
|
||||
*/
|
||||
@PostMapping("/listWithLocation")
|
||||
public AjaxResult listShopsWithLocation(@RequestBody(required = false) Map<String, Object> params) {
|
||||
try {
|
||||
List<Shop> shops = shopService.listShops();
|
||||
|
||||
// 可以根据参数进行筛选
|
||||
if (params != null) {
|
||||
// 按城市筛选
|
||||
if (params.containsKey("cityId")) {
|
||||
Long cityId = Long.valueOf(params.get("cityId").toString());
|
||||
shops = shops.stream()
|
||||
.filter(shop -> shop.getCityId() != null && shop.getCityId().equals(cityId))
|
||||
.collect(java.util.stream.Collectors.toList());
|
||||
}
|
||||
|
||||
// 按师傅筛选
|
||||
if (params.containsKey("workerId")) {
|
||||
Long workerId = Long.valueOf(params.get("workerId").toString());
|
||||
shops = shops.stream()
|
||||
.filter(shop -> shop.getWorkerId() != null && shop.getWorkerId().equals(workerId))
|
||||
.collect(java.util.stream.Collectors.toList());
|
||||
}
|
||||
|
||||
// 只返回有坐标的店铺
|
||||
if (params.containsKey("hasLocation") && Boolean.valueOf(params.get("hasLocation").toString())) {
|
||||
shops = shops.stream()
|
||||
.filter(shop -> shop.getLatitude() != null && shop.getLongitude() != null)
|
||||
.collect(java.util.stream.Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
return AjaxResult.success(shops);
|
||||
} catch (Exception e) {
|
||||
logger.error("查询店铺列表失败: {}", e.getMessage(), e);
|
||||
return AjaxResult.error("查询失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询附近的店铺
|
||||
*/
|
||||
@PostMapping("/nearby")
|
||||
public AjaxResult getNearbyShops(@RequestBody Map<String, Object> params) {
|
||||
try {
|
||||
Double latitude = Double.valueOf(params.get("latitude").toString());
|
||||
Double longitude = Double.valueOf(params.get("longitude").toString());
|
||||
Double radiusKm = params.containsKey("radiusKm") ?
|
||||
Double.valueOf(params.get("radiusKm").toString()) : 5.0; // 默认5公里
|
||||
|
||||
// 验证坐标有效性
|
||||
if (!LocationUtils.isValidCoordinate(latitude, longitude)) {
|
||||
return AjaxResult.error("无效的坐标参数");
|
||||
}
|
||||
|
||||
// 获取所有店铺
|
||||
List<Shop> allShops = shopService.listShops();
|
||||
|
||||
// 筛选出有坐标的店铺并计算距离
|
||||
List<Map<String, Object>> nearbyShops = allShops.stream()
|
||||
.filter(shop -> LocationUtils.isValidCoordinate(shop.getLatitude(), shop.getLongitude()))
|
||||
.map(shop -> {
|
||||
double distance = LocationUtils.getDistanceInKilometers(
|
||||
latitude, longitude, shop.getLatitude(), shop.getLongitude());
|
||||
|
||||
Map<String, Object> shopWithDistance = new HashMap<>();
|
||||
shopWithDistance.put("shop", shop);
|
||||
shopWithDistance.put("distance", distance);
|
||||
shopWithDistance.put("distanceText", LocationUtils.formatDistance(distance * 1000));
|
||||
|
||||
// 计算方向
|
||||
double bearing = LocationUtils.getBearing(latitude, longitude,
|
||||
shop.getLatitude(), shop.getLongitude());
|
||||
shopWithDistance.put("direction", LocationUtils.getDirectionDescription(bearing));
|
||||
shopWithDistance.put("bearing", bearing);
|
||||
|
||||
return shopWithDistance;
|
||||
})
|
||||
.filter(shopMap -> (Double) shopMap.get("distance") <= radiusKm)
|
||||
.sorted(Comparator.comparingDouble(shopMap -> (Double) shopMap.get("distance")))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("centerLatitude", latitude);
|
||||
result.put("centerLongitude", longitude);
|
||||
result.put("radiusKm", radiusKm);
|
||||
result.put("totalCount", nearbyShops.size());
|
||||
result.put("shops", nearbyShops);
|
||||
|
||||
return AjaxResult.success("查询成功", result);
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("查询附近店铺失败: {}", e.getMessage(), e);
|
||||
return AjaxResult.error("查询失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算两个店铺之间的距离
|
||||
*/
|
||||
@PostMapping("/distance")
|
||||
public AjaxResult getShopsDistance(@RequestBody Map<String, Object> params) {
|
||||
try {
|
||||
Long shopId1 = Long.valueOf(params.get("shopId1").toString());
|
||||
Long shopId2 = Long.valueOf(params.get("shopId2").toString());
|
||||
|
||||
Shop shop1 = shopService.getShop(shopId1);
|
||||
Shop shop2 = shopService.getShop(shopId2);
|
||||
|
||||
if (shop1 == null || shop2 == null) {
|
||||
return AjaxResult.error("店铺不存在");
|
||||
}
|
||||
|
||||
if (!LocationUtils.isValidCoordinate(shop1.getLatitude(), shop1.getLongitude()) ||
|
||||
!LocationUtils.isValidCoordinate(shop2.getLatitude(), shop2.getLongitude())) {
|
||||
return AjaxResult.error("店铺坐标信息不完整");
|
||||
}
|
||||
|
||||
double distanceKm = LocationUtils.getDistanceInKilometers(
|
||||
shop1.getLatitude(), shop1.getLongitude(),
|
||||
shop2.getLatitude(), shop2.getLongitude());
|
||||
|
||||
double bearing = LocationUtils.getBearing(
|
||||
shop1.getLatitude(), shop1.getLongitude(),
|
||||
shop2.getLatitude(), shop2.getLongitude());
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("shop1", shop1);
|
||||
result.put("shop2", shop2);
|
||||
result.put("distanceKm", distanceKm);
|
||||
result.put("distanceText", LocationUtils.formatDistance(distanceKm * 1000));
|
||||
result.put("direction", LocationUtils.getDirectionDescription(bearing));
|
||||
result.put("bearing", bearing);
|
||||
|
||||
return AjaxResult.success("计算成功", result);
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("计算店铺距离失败: {}", e.getMessage(), e);
|
||||
return AjaxResult.error("计算失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过店铺ID查询详细信息并计算距离
|
||||
* 最终效果:
|
||||
* 1. 传入的详细地址 → 转换为经纬度
|
||||
* 2. 店铺有经纬度 → 直接使用
|
||||
* 3. 店铺没有经纬度 → 通过详细地址生成经纬度
|
||||
* 4. 最终通过经纬度计算距离 → 放在店铺的距离字段上
|
||||
*
|
||||
* @param query 距离查询请求实体
|
||||
* @return 包含距离信息的完整店铺详情
|
||||
*/
|
||||
@PostMapping("/getShopDetailWithDistance")
|
||||
public AjaxResult getShopDetailWithDistance(@RequestBody ShopDistanceQuery query) {
|
||||
try {
|
||||
// 验证参数
|
||||
if (query.getShopId() == null) {
|
||||
return AjaxResult.error("店铺ID不能为空");
|
||||
}
|
||||
|
||||
// 验证是否有足够的信息来计算距离或获取位置
|
||||
if (!query.hasEnoughInfo()) {
|
||||
return AjaxResult.error("请提供经纬度或地址信息");
|
||||
}
|
||||
|
||||
// 如果提供了经纬度,验证其有效性
|
||||
if (query.hasCoordinateInfo() && !LocationUtils.isValidCoordinate(query.getLatitude(), query.getLongitude())) {
|
||||
return AjaxResult.error("无效的坐标参数");
|
||||
}
|
||||
|
||||
// 验证地址参数(如果提供了地址信息,则验证其完整性)
|
||||
if (query.hasAddressInfo()) {
|
||||
String fullAddress = query.getFullAddress();
|
||||
if (fullAddress.trim().length() < 5) {
|
||||
return AjaxResult.error("地址信息不完整,请提供更详细的地址");
|
||||
}
|
||||
logger.info("使用传入的地址信息: {}", fullAddress);
|
||||
}
|
||||
|
||||
// 调用服务层方法获取店铺详情和距离
|
||||
Shop shop = shopService.getShopWithDistance(query);
|
||||
|
||||
if (shop == null) {
|
||||
return AjaxResult.error("未找到店铺");
|
||||
}
|
||||
|
||||
// 检查距离是否有效
|
||||
if (shop.getDistance() == null || shop.getDistance().equals("无法计算距离")) {
|
||||
if (query.hasCoordinateInfo()) {
|
||||
return AjaxResult.error("无法计算店铺距离,请检查店铺地址信息或提供更详细的地址参数");
|
||||
} else {
|
||||
// 如果没有经纬度,只获取位置信息
|
||||
logger.info("仅获取店铺位置信息,无法计算距离");
|
||||
}
|
||||
}
|
||||
|
||||
// 构建返回结果
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("shopId", shop.getShopId());
|
||||
result.put("shopName", shop.getShopName());
|
||||
result.put("imageUrl", shop.getImageUrl());
|
||||
result.put("workerId", shop.getWorkerId());
|
||||
result.put("provinceId", shop.getProvinceId());
|
||||
result.put("provinceName", shop.getProvinceName());
|
||||
result.put("cityId", shop.getCityId());
|
||||
result.put("cityName", shop.getCityName());
|
||||
result.put("countryId", shop.getCountryId());
|
||||
result.put("countryName", shop.getCountryName());
|
||||
result.put("streetId", shop.getStreetId());
|
||||
result.put("streetName", shop.getStreetName());
|
||||
result.put("address", shop.getAddress());
|
||||
result.put("phone", shop.getPhone());
|
||||
result.put("latitude", shop.getLatitude());
|
||||
result.put("longitude", shop.getLongitude());
|
||||
result.put("distance", shop.getDistance());
|
||||
|
||||
|
||||
return AjaxResult.success("查询成功", result);
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("查询店铺详情失败: {}", e.getMessage(), e);
|
||||
return AjaxResult.error("查询失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 获取店铺覆盖范围内的其他店铺
|
||||
// */
|
||||
// @PostMapping("/coverage")
|
||||
// public AjaxResult getShopsCoverage(@RequestBody Map<String, Object> params) {
|
||||
// try {
|
||||
// Long shopId = Long.valueOf(params.get("shopId").toString());
|
||||
// Double radiusKm = params.containsKey("radiusKm") ?
|
||||
// Double.valueOf(params.get("radiusKm").toString()) : 10.0; // 默认10公里
|
||||
//
|
||||
// Shop centerShop = shopService.getShop(shopId);
|
||||
// if (centerShop == null) {
|
||||
// return AjaxResult.error("店铺不存在");
|
||||
// }
|
||||
//
|
||||
// if (!LocationUtils.isValidCoordinate(centerShop.getLatitude(), centerShop.getLongitude())) {
|
||||
// return AjaxResult.error("中心店铺坐标信息不完整");
|
||||
// }
|
||||
//
|
||||
// // 获取附近的店铺
|
||||
// Map<String, Object> nearbyParams = new HashMap<>();
|
||||
// nearbyParams.put("latitude", centerShop.getLatitude());
|
||||
// nearbyParams.put("longitude", centerShop.getLongitude());
|
||||
// radiusKm);
|
||||
//
|
||||
// AjaxResult nearbyResult = getNearbyShops(nearbyParams);
|
||||
// if (nearbyResult.isSuccess()) {
|
||||
// Map<String, Object> data = (Map<String, Object>) nearbyResult.get("data");
|
||||
// List<Map<String, Object>> shops = (List<Map<String, Object>>) data.get("shops");
|
||||
//
|
||||
// // 排除自己
|
||||
// shops = shops.stream()
|
||||
// .filter(shopMap -> {
|
||||
// Shop shop = (Shop) shopMap.get("shop");
|
||||
// return !shop.getShopId().equals(shopId);
|
||||
// })
|
||||
// .collect(Collectors.toList());
|
||||
//
|
||||
// data.put("centerShop", centerShop);
|
||||
// data.put("shops", shops);
|
||||
// data.put("totalCount", shops.size());
|
||||
//
|
||||
// return AjaxResult.success("查询成功", data);
|
||||
// } else {
|
||||
// return nearbyResult;
|
||||
// }
|
||||
//
|
||||
// } catch (Exception e) {
|
||||
// logger.error("查询店铺覆盖范围失败: {}", e.getMessage(), e);
|
||||
// return AjaxResult.error("查询失败: " + e.getMessage());
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package com.ghy.web.controller.config;
|
||||
|
||||
import com.ghy.common.core.domain.AjaxResult;
|
||||
import com.ghy.system.service.ISysGlobalConfigService;
|
||||
import com.ghy.web.pojo.vo.SysGlobalConfigRequestVO;
|
||||
import com.ghy.web.pojo.vo.SysGlobalConfigResponseVO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* @Author: 但星霖
|
||||
* @Date: 2023-11-09 14:42
|
||||
* @Version: 1.0
|
||||
* @Description: web-系统配置控制层
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/config/globalConfig")
|
||||
@Tag(name = "web-系统配置控制层")
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class SysGlobalConfigController {
|
||||
|
||||
private String prefix = "config/globalConfig";
|
||||
|
||||
@RequiresPermissions("sys:order:audio:config")
|
||||
@GetMapping()
|
||||
public String place() {
|
||||
return prefix + "/edit";
|
||||
}
|
||||
|
||||
private final ISysGlobalConfigService service;
|
||||
|
||||
|
||||
@ResponseBody
|
||||
@Operation(summary = "系统配置查询接口(根据类型查询)", method = "GET")
|
||||
@Parameters({
|
||||
@Parameter(name = "typeId", description = "配置类型Code", required = true, in = ParameterIn.PATH)
|
||||
})
|
||||
@GetMapping(path = "/search/type/{typeId}", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public AjaxResult searchByType(@PathVariable("typeId") Integer typeId) {
|
||||
return AjaxResult.success(SysGlobalConfigResponseVO.toVo(service.loadByConfigType(typeId)));
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@RequiresPermissions("sys:order:audio:config:update")
|
||||
@Operation(summary = "系统配置修改", method = "PUT")
|
||||
@PutMapping(path = "/update", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public AjaxResult update(@RequestBody SysGlobalConfigRequestVO sysConfigRequestVO) {
|
||||
return AjaxResult.success(service.update(SysGlobalConfigRequestVO.toModel(sysConfigRequestVO)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.ghy.web.controller.customer;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.ghy.common.core.controller.BaseController;
|
||||
import com.ghy.common.core.domain.AjaxResult;
|
||||
import com.ghy.common.utils.ExceptionUtil;
|
||||
|
|
@ -12,6 +13,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/customer/address")
|
||||
|
|
@ -100,6 +103,20 @@ public class CustomerAddressController extends BaseController {
|
|||
@ResponseBody
|
||||
AjaxResult insertCustomerAddress(@RequestBody CustomerAddress customerAddress){
|
||||
try {
|
||||
// 判断下当前是否是默认地址
|
||||
if(ObjectUtil.equals(customerAddress.getIsDefault(), 1)){
|
||||
CustomerAddress param = new CustomerAddress();
|
||||
param.setNeedNameFlag(false);
|
||||
param.setCustomerId(customerAddress.getCustomerId());
|
||||
param.setIsDefault(1);
|
||||
List<CustomerAddress> sourceDefaultAddress = customerAddressService.getCustomerAddressList(param);
|
||||
for (CustomerAddress defaultAddress : sourceDefaultAddress) {
|
||||
CustomerAddress defaultParam = new CustomerAddress();
|
||||
defaultParam.setCustomerAddressId(defaultAddress.getCustomerAddressId());
|
||||
defaultParam.setIsDefault(0);
|
||||
customerAddressService.updateCustomerAddress(defaultParam);
|
||||
}
|
||||
}
|
||||
customerAddressService.insertCustomerAddress(customerAddress);
|
||||
return AjaxResult.success("操作成功");
|
||||
}catch (Exception e){
|
||||
|
|
@ -114,7 +131,24 @@ public class CustomerAddressController extends BaseController {
|
|||
@PostMapping("/update")
|
||||
@ResponseBody
|
||||
AjaxResult updateCustomerAddress(@RequestBody CustomerAddress customerAddress){
|
||||
logger.info("地址库的订单修改方法{}",customerAddress);
|
||||
try {
|
||||
// 判断下当前是否是默认地址
|
||||
if(ObjectUtil.equals(customerAddress.getIsDefault(), 1)){
|
||||
CustomerAddress param = new CustomerAddress();
|
||||
param.setNeedNameFlag(false);
|
||||
param.setCustomerId(customerAddress.getCustomerId());
|
||||
param.setIsDefault(1);
|
||||
List<CustomerAddress> sourceDefaultAddress = customerAddressService.getCustomerAddressList(param);
|
||||
for (CustomerAddress defaultAddress : sourceDefaultAddress) {
|
||||
if(!Objects.equals(defaultAddress.getCustomerAddressId(), customerAddress.getCustomerAddressId())){
|
||||
CustomerAddress defaultParam = new CustomerAddress();
|
||||
defaultParam.setCustomerAddressId(defaultAddress.getCustomerAddressId());
|
||||
defaultParam.setIsDefault(0);
|
||||
customerAddressService.updateCustomerAddress(defaultParam);
|
||||
}
|
||||
}
|
||||
}
|
||||
customerAddressService.updateCustomerAddress(customerAddress);
|
||||
return AjaxResult.success("操作成功");
|
||||
}catch (Exception e){
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
|
@ -45,6 +46,8 @@ public class CustomerBankController {
|
|||
@ResponseBody
|
||||
private AjaxResult bindBankCard(@RequestBody @Valid BindBankCardRequest request) throws BaseAdaPayException {
|
||||
Set<Merchant> merchants = AdapayConfig.getMerchants();
|
||||
String phone = request.getPhone();
|
||||
phone = StringUtils.trimAllWhitespace(phone);
|
||||
for (Merchant merchant : merchants) {
|
||||
String memberId = AdapayUtils.getCustomerMemberId(request.getCustomerId(), merchant.getDeptId());
|
||||
|
||||
|
|
@ -60,7 +63,7 @@ public class CustomerBankController {
|
|||
log.info("用户[memberId={}]已存在 跳过实名直接绑卡", memberId);
|
||||
} else {
|
||||
// 先在Adapay创建实名用户
|
||||
Map<String, Object> result1 = adapayService.createMember(merchant.getDeptId(), memberId, request.getPhone(),
|
||||
Map<String, Object> result1 = adapayService.createMember(merchant.getDeptId(), memberId, phone,
|
||||
request.getName(), request.getCertId());
|
||||
if (!AdapayStatusEnum.succeeded.code.equals(result1.get("status"))) {
|
||||
log.error("实名认证失败[{}]", JSON.toJSONString(result1));
|
||||
|
|
@ -70,7 +73,7 @@ public class CustomerBankController {
|
|||
|
||||
// 开始创建结算账户
|
||||
JSONObject result2 = adapayService.createSettleAccount(merchant.getDeptId(), memberId, request.getBankNum(), request.getName(),
|
||||
"2", request.getCertId(), request.getPhone(), null, null, null);
|
||||
"2", request.getCertId(), phone, null, null, null);
|
||||
if (!AdapayStatusEnum.succeeded.code.equals(result2.get("status"))) {
|
||||
if ("account_exists".equals(result2.get("error_code"))) {
|
||||
log.info("用户[memberId={}]结算账户已存在 跳过", memberId);
|
||||
|
|
@ -85,7 +88,7 @@ public class CustomerBankController {
|
|||
customerBank.setName(request.getName());
|
||||
customerBank.setCertId(request.getCertId());
|
||||
customerBank.setBankNum(request.getBankNum());
|
||||
customerBank.setPhone(request.getPhone());
|
||||
customerBank.setPhone(phone);
|
||||
customerBank.setDeptId(merchant.getDeptId());
|
||||
customerBank.setAdapayMemberId(memberId);
|
||||
customerBank.setSettleAccount(1);
|
||||
|
|
|
|||
|
|
@ -4,13 +4,16 @@ import com.ghy.common.adapay.model.AnalyseItemEnum;
|
|||
import com.ghy.common.core.controller.BaseController;
|
||||
import com.ghy.common.core.domain.AjaxResult;
|
||||
import com.ghy.common.core.page.TableDataInfo;
|
||||
import com.ghy.common.enums.FinancialDetailType;
|
||||
import com.ghy.common.enums.PlaceStatus;
|
||||
import com.ghy.common.enums.UserStatus;
|
||||
import com.ghy.common.utils.ExceptionUtil;
|
||||
import com.ghy.customer.domain.Customer;
|
||||
import com.ghy.customer.service.CustomerService;
|
||||
import com.ghy.goods.domain.InsuranceManager;
|
||||
import com.ghy.order.domain.OrderMaster;
|
||||
import com.ghy.order.service.OrderMasterService;
|
||||
import com.ghy.payment.domain.FinancialDetail;
|
||||
import com.ghy.payment.domain.FinancialMaster;
|
||||
import com.ghy.payment.service.FinancialMasterService;
|
||||
import com.ghy.web.pojo.vo.AnalyseItem;
|
||||
|
|
@ -19,6 +22,7 @@ import org.apache.commons.collections.CollectionUtils;
|
|||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
|
|
@ -72,17 +76,19 @@ public class CustomerController extends BaseController {
|
|||
startPage();
|
||||
List<Customer> list = customerService.getCustomerList(customer);
|
||||
for (Customer curCustomer: list) {
|
||||
Long teamNum = 0L;
|
||||
List<Long> customerIds = new ArrayList<Long>(){{
|
||||
add(curCustomer.getCustomerId());
|
||||
}};
|
||||
List<Long> nextLevelCustomerIds = new ArrayList<>();
|
||||
if (customer.getIsDistributor()) {
|
||||
// 分销商需要查询所有下一级分销用户作为统计条件
|
||||
Customer customerQry = new Customer();
|
||||
customerQry.setCustomerPlace(curCustomer.getCustomerId());
|
||||
customerQry.setStatus(Integer.valueOf(UserStatus.OK.getCode()));
|
||||
List<Customer> nextLevelCustomers = customerService.getCustomerList(customerQry);
|
||||
List<Long> nextLevelCustomerIds = nextLevelCustomers.stream().map(Customer::getCustomerId).collect(Collectors.toList());
|
||||
customerIds.addAll(nextLevelCustomerIds);
|
||||
teamNum = teamNum + nextLevelCustomers.stream().filter(x->PlaceStatus.CAN_PLACE.getCode().equals(x.getPlaceStatus())).count();
|
||||
nextLevelCustomerIds = nextLevelCustomers.stream().map(Customer::getCustomerId).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
// 本月第一天
|
||||
|
|
@ -103,30 +109,36 @@ public class CustomerController extends BaseController {
|
|||
.setValue(customerService.countCustomer(customerParams));
|
||||
analyseItems.add(aItem1);
|
||||
// 本月绑定客户数
|
||||
customerParams.setPlaceStatus(null);
|
||||
customerParams.setUpdateTimeStart(firstDayCurMonth.atStartOfDay());
|
||||
AnalyseItem aItem2 = new AnalyseItem()
|
||||
.setType(AnalyseItemEnum.CUSTOMER_NUM_ADDED_CUR_MONTH.getType())
|
||||
.setTitle(AnalyseItemEnum.CUSTOMER_NUM_ADDED_CUR_MONTH.getTitle())
|
||||
.setUnit(AnalyseItemEnum.CUSTOMER_NUM_ADDED_CUR_MONTH.getUnit())
|
||||
.setValue(customerService.countCustomer(customerParams));
|
||||
.setType(AnalyseItemEnum.CUSTOMER_NUM_ADDED_CUR_MONTH.getType())
|
||||
.setTitle(AnalyseItemEnum.CUSTOMER_NUM_ADDED_CUR_MONTH.getTitle())
|
||||
.setUnit(AnalyseItemEnum.CUSTOMER_NUM_ADDED_CUR_MONTH.getUnit())
|
||||
.setValue(customerService.countCustomer(customerParams));
|
||||
analyseItems.add(aItem2);
|
||||
// 团队
|
||||
customerParams.setUpdateTimeStart(null);
|
||||
customerParams.setPlaceStatus(PlaceStatus.CAN_PLACE.getCode());
|
||||
AnalyseItem aItem11 = new AnalyseItem()
|
||||
.setType(AnalyseItemEnum.TEAM_MEMBER_NUM.getType())
|
||||
.setTitle(AnalyseItemEnum.TEAM_MEMBER_NUM.getTitle())
|
||||
.setUnit(AnalyseItemEnum.TEAM_MEMBER_NUM.getUnit())
|
||||
.setValue(aItem1.getValue());
|
||||
.setType(AnalyseItemEnum.TEAM_MEMBER_NUM.getType())
|
||||
.setTitle(AnalyseItemEnum.TEAM_MEMBER_NUM.getTitle())
|
||||
.setUnit(AnalyseItemEnum.TEAM_MEMBER_NUM.getUnit())
|
||||
.setValue(customerService.countCustomer(customerParams));
|
||||
analyseItems.add(aItem11);
|
||||
// 本月绑定客户数
|
||||
customerParams.setUpdateTimeStart(firstDayCurMonth.atStartOfDay());
|
||||
customerParams.setPlaceStatus(PlaceStatus.CAN_PLACE.getCode());
|
||||
AnalyseItem aItem12 = new AnalyseItem()
|
||||
.setType(AnalyseItemEnum.TEAM_MEMBER_ADDED_CUR_MONTH.getType())
|
||||
.setTitle(AnalyseItemEnum.TEAM_MEMBER_ADDED_CUR_MONTH.getTitle())
|
||||
.setUnit(AnalyseItemEnum.TEAM_MEMBER_ADDED_CUR_MONTH.getUnit())
|
||||
.setValue(aItem2.getValue());
|
||||
.setValue(customerService.countCustomer(customerParams));
|
||||
analyseItems.add(aItem12);
|
||||
|
||||
// 本月订单数及本月订单额
|
||||
OrderMaster orderParams1 = new OrderMaster();
|
||||
customerIds.addAll(nextLevelCustomerIds);
|
||||
orderParams1.setCustomerIds(customerIds);
|
||||
orderParams1.setCreateTimeStart(firstDayCurMonth.atStartOfDay());
|
||||
List<OrderMaster> ordersCurMonth1 = orderMasterService.selectOrderMasterList(orderParams1);
|
||||
|
|
@ -208,7 +220,7 @@ public class CustomerController extends BaseController {
|
|||
OrderMaster orderParams4 = new OrderMaster();
|
||||
orderParams4.setCustomerIds(customerIds);
|
||||
orderParams4.setCreateTimeStart(firstDayCurWeek.atStartOfDay());
|
||||
List<OrderMaster> ordersCurWeek = orderMasterService.selectOrderMasterList(orderParams3);
|
||||
List<OrderMaster> ordersCurWeek = orderMasterService.selectOrderMasterList(orderParams4);
|
||||
List<Long> orderIdsCurWeek = ordersCurWeek.stream().map(OrderMaster::getId).collect(Collectors.toList());
|
||||
BigDecimal totalMoneyCurWeek = new BigDecimal(0);
|
||||
if (CollectionUtils.isNotEmpty(orderIdsCurWeek)) {
|
||||
|
|
@ -242,6 +254,25 @@ public class CustomerController extends BaseController {
|
|||
return getDataTable(response);
|
||||
}
|
||||
|
||||
@GetMapping("/changePlace/{customerId}")
|
||||
public String changePlace(@PathVariable("customerId") Long customerId, ModelMap mmap)
|
||||
{
|
||||
|
||||
mmap.put("customerId", customerId);
|
||||
mmap.put("customerPlaces", customerService.getPlaceCustomerList());
|
||||
return prefix + "/changePlace";
|
||||
}
|
||||
|
||||
@PostMapping("/changePlace")
|
||||
@ResponseBody
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public AjaxResult changePlace(Customer customer) {
|
||||
Customer place = customerService.selectByCustomerId(customer.getCustomerPlace());
|
||||
customer.setParentCustomerPlace(place.getCustomerPlace());
|
||||
customerService.updateCustomer(customer);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
@RequiresPermissions("customer:customer:resetPwd")
|
||||
@GetMapping("/resetPwd/{customerId}")
|
||||
public String resetPwd(@PathVariable("customerId") Long customerId, ModelMap mmap)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package com.ghy.web.controller.customer;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.ghy.common.exception.base.BaseException;
|
||||
import com.ghy.customer.domain.Customer;
|
||||
|
|
@ -62,6 +64,22 @@ public class CustomerSelectionController extends BaseController
|
|||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询消费者选品列表
|
||||
*/
|
||||
@PostMapping("/listNoPage")
|
||||
@ResponseBody
|
||||
public AjaxResult listNoPage(@RequestBody CustomerSelection customerSelection)
|
||||
{
|
||||
// 判断是否有上级,有上级则取上级的 -- 没有则就是自身
|
||||
Customer customer = customerService.selectByCustomerId(customerSelection.getCustomerId());
|
||||
if(customer.getPlaceStatus() != 2 && customer.getCustomerPlace() != null){
|
||||
customerSelection.setCustomerId(customer.getCustomerPlace());
|
||||
}
|
||||
List<CustomerSelection> list = customerSelectionService.selectCustomerSelectionList(customerSelection);
|
||||
return AjaxResult.success(list.stream().map(CustomerSelection::getDeptCategoryId).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
/**
|
||||
* App查询消费者选品列表
|
||||
*/
|
||||
|
|
@ -129,18 +147,28 @@ public class CustomerSelectionController extends BaseController
|
|||
}else {
|
||||
workId = workList.get(0).getWorkerId();
|
||||
}
|
||||
// 删除历史的
|
||||
CustomerSelection hisParam = new CustomerSelection();
|
||||
hisParam.setCustomerId(customerSelection.getCustomerId());
|
||||
hisParam.setSelectionType(customerSelection.getSelectionType());
|
||||
List<CustomerSelection> hisList = customerSelectionService.selectCustomerSelectionList(hisParam);
|
||||
if(!CollectionUtils.isEmpty(hisList)){
|
||||
List<String> hisIds = hisList.stream()
|
||||
.filter(customerSelection1 -> Objects.equals(customerSelection1.getType(), customerSelection.getType())).map(CustomerSelection::getId).collect(Collectors.toList());
|
||||
StringBuilder ids = new StringBuilder();
|
||||
hisIds.forEach(model->{
|
||||
ids.append(model.trim()).append(",");
|
||||
});
|
||||
if(!StringUtil.isEmpty(ids)&&ids.length()>0){
|
||||
String idString = ids.substring(0, ids.length()-1);
|
||||
customerSelectionService.deleteCustomerSelectionByIds(idString);
|
||||
}
|
||||
}
|
||||
// 判断是否有历史数据 - 有则删除
|
||||
customerSelection.getDeptCategoryIds().forEach(selection->{
|
||||
customerSelection.setWorkId(workId);
|
||||
customerSelection.setDeptCategoryId(selection);
|
||||
CustomerSelection param = new CustomerSelection();
|
||||
param.setDeptCategoryId(selection);
|
||||
param.setSelectionType(customerSelection.getSelectionType());
|
||||
param.setCustomerId(customerSelection.getCustomerId());
|
||||
List<CustomerSelection> customerSelections = customerSelectionService.selectCustomerSelectionList(param);
|
||||
if(CollectionUtils.isEmpty(customerSelections)){
|
||||
customerSelectionService.insertCustomerSelection(customerSelection);
|
||||
}
|
||||
customerSelectionService.insertCustomerSelection(customerSelection);
|
||||
});
|
||||
return AjaxResult.success("新增成功");
|
||||
}catch (Exception e){
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.ghy.web.controller.goods;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.ghy.common.annotation.Log;
|
||||
import com.ghy.common.constant.UserConstants;
|
||||
import com.ghy.common.core.controller.BaseController;
|
||||
|
|
@ -7,16 +8,24 @@ import com.ghy.common.core.domain.AjaxResult;
|
|||
import com.ghy.common.core.domain.Ztree;
|
||||
import com.ghy.common.enums.BusinessType;
|
||||
import com.ghy.common.utils.ShiroUtils;
|
||||
import com.ghy.common.utils.StringUtils;
|
||||
import com.ghy.goods.domain.CategoryInsuranceRelation;
|
||||
import com.ghy.goods.domain.GoodsCategory;
|
||||
import com.ghy.goods.domain.InsuranceManager;
|
||||
import com.ghy.goods.service.GoodsCategoryService;
|
||||
import com.ghy.goods.service.ICategoryInsuranceRelationService;
|
||||
import com.ghy.goods.service.IInsuranceManagerService;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author HH 2022/3/19
|
||||
|
|
@ -30,6 +39,12 @@ public class GoodsCategoryController extends BaseController {
|
|||
@Resource
|
||||
private GoodsCategoryService goodsCategoryService;
|
||||
|
||||
@Resource
|
||||
private IInsuranceManagerService insuranceManagerService;
|
||||
|
||||
@Resource
|
||||
private ICategoryInsuranceRelationService categoryInsuranceRelationService;
|
||||
|
||||
@RequiresPermissions("goods:category:view")
|
||||
@GetMapping()
|
||||
public String goodsCategory() {
|
||||
|
|
@ -43,6 +58,7 @@ public class GoodsCategoryController extends BaseController {
|
|||
@GetMapping("/add/{parentCategoryId}")
|
||||
public String add(@PathVariable("parentCategoryId") Long parentCategoryId, ModelMap mmap) {
|
||||
mmap.put("goodsCategory", goodsCategoryService.selectById(parentCategoryId));
|
||||
mmap.put("insurances", insuranceManagerService.selectInsuranceManagerList(new InsuranceManager()));
|
||||
return PREFIX + "/add";
|
||||
}
|
||||
|
||||
|
|
@ -50,7 +66,8 @@ public class GoodsCategoryController extends BaseController {
|
|||
* 新增商品类别页面
|
||||
*/
|
||||
@GetMapping("/add")
|
||||
public String add() {
|
||||
public String add(ModelMap mmap) {
|
||||
mmap.put("insurances", insuranceManagerService.selectInsuranceManagerList(new InsuranceManager()));
|
||||
return PREFIX + "/add";
|
||||
}
|
||||
|
||||
|
|
@ -60,7 +77,21 @@ public class GoodsCategoryController extends BaseController {
|
|||
@RequiresPermissions("goods:category:edit")
|
||||
@GetMapping("/edit/{goodsId}")
|
||||
public String edit(@PathVariable("goodsId") Long goodsId, ModelMap mmap) {
|
||||
mmap.put("goodsCategory", goodsCategoryService.selectById(goodsId));
|
||||
GoodsCategory goodsCategory = goodsCategoryService.selectById(goodsId);
|
||||
mmap.put("goodsCategory", goodsCategory);
|
||||
List<InsuranceManager> list = insuranceManagerService.selectInsuranceManagerList(new InsuranceManager());
|
||||
CategoryInsuranceRelation param = new CategoryInsuranceRelation();
|
||||
param.setGoodsCategoryId(goodsCategory.getGoodsCategoryId());
|
||||
List<CategoryInsuranceRelation> relations = categoryInsuranceRelationService.selectCategoryInsuranceRelationList(param);
|
||||
if(CollectionUtil.isNotEmpty(relations)){
|
||||
Map<Long, List<CategoryInsuranceRelation>> map = relations.stream().collect(Collectors.groupingBy(CategoryInsuranceRelation::getInsuranceId));
|
||||
list.forEach(model->{
|
||||
if(map.containsKey(model.getId())){
|
||||
model.setFlag(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
mmap.put("insurances", list);
|
||||
return PREFIX + "/edit";
|
||||
}
|
||||
|
||||
|
|
@ -103,12 +134,10 @@ public class GoodsCategoryController extends BaseController {
|
|||
@Log(title = "商品类别管理", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/edit")
|
||||
@ResponseBody
|
||||
@Transactional
|
||||
public AjaxResult editSave(@Validated GoodsCategory category) {
|
||||
// if (goodsCategoryService.checkGoodsCategoryNameUnique(category)) {
|
||||
// return error("新增商品类别'" + category.getGoodsCategoryName() + "'失败,商品类别名称已存在");
|
||||
// } else if (goodsCategoryService.checkGoodsCategoryCodeUnique(category)) {
|
||||
// return error("新增商品类别'" + category.getGoodsCategoryCode() + "'失败,商品类别编码已存在");
|
||||
// }
|
||||
// 更新保险设置
|
||||
categoryInsuranceRelationService.updateCategoryInsuranceRelation(category.getInsuranceIds(), category.getGoodsCategoryId());
|
||||
category.setUpdateBy(getLoginName());
|
||||
return toAjax(goodsCategoryService.updateGoodsCategory(category));
|
||||
}
|
||||
|
|
@ -152,6 +181,25 @@ public class GoodsCategoryController extends BaseController {
|
|||
return goodsCategoryService.selectCategoryTree(new GoodsCategory());
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择服务类目树
|
||||
*/
|
||||
@GetMapping("/selectServiceCategoryTree")
|
||||
public String selectServiceCategoryTree(ModelMap mmap) {
|
||||
return PREFIX + "/serviceTree";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取服务类目树数据
|
||||
*/
|
||||
@GetMapping("/serviceTreeData")
|
||||
@ResponseBody
|
||||
public List<Ztree> serviceTreeData() {
|
||||
GoodsCategory category = new GoodsCategory();
|
||||
category.setType(1); // 1表示服务类
|
||||
return goodsCategoryService.selectCategoryTree(category);
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品类别表
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -10,8 +10,13 @@ import com.ghy.common.utils.ShiroUtils;
|
|||
import com.ghy.common.utils.StringUtils;
|
||||
import com.ghy.common.utils.bean.BeanUtils;
|
||||
import com.ghy.common.utils.poi.ExcelUtil;
|
||||
import com.ghy.common.utils.LocationUtils;
|
||||
import com.ghy.common.utils.http.HttpUtils;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.ghy.goods.domain.*;
|
||||
import com.ghy.goods.service.*;
|
||||
import com.ghy.shop.domain.Shop;
|
||||
import com.ghy.shop.service.ShopService;
|
||||
import com.ghy.system.domain.SysArea;
|
||||
import com.ghy.system.service.ISysAreaService;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
|
|
@ -26,6 +31,7 @@ import javax.annotation.Resource;
|
|||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import com.ghy.common.utils.BaiduMapUtils;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/goods/goods")
|
||||
|
|
@ -47,6 +53,14 @@ public class GoodsController extends BaseController {
|
|||
private GoodsStandardService goodsStandardService;
|
||||
@Resource
|
||||
private ISysAreaService sysAreaService;
|
||||
@Resource
|
||||
private IInsuranceManagerService insuranceManagerService;
|
||||
@Resource
|
||||
private IDeptCategoryInsuranceRelationService deptCategoryInsuranceRelationService;
|
||||
@Resource
|
||||
private ShopService shopService;
|
||||
@Resource
|
||||
private BaiduMapUtils baiduMapUtils;
|
||||
|
||||
@RequiresPermissions("goods:goods:view")
|
||||
@GetMapping()
|
||||
|
|
@ -160,6 +174,15 @@ public class GoodsController extends BaseController {
|
|||
@PostMapping("/app/list")
|
||||
@ResponseBody
|
||||
public TableDataInfo appList(@RequestBody Goods goods) {
|
||||
Integer type=goods.getType();
|
||||
if (type==null){
|
||||
goods.setType(1);
|
||||
}
|
||||
|
||||
// 获取用户当前位置
|
||||
Double userLatitude = goods.getLatitude();
|
||||
Double userLongitude = goods.getLongitude();
|
||||
|
||||
// 判断类目id是否为第三级,不是的话需要找到所有符合条件的第三级类目id作为新的条件
|
||||
if (goods.getDeptGoodsCategoryId() != null) {
|
||||
logger.info("入参:" + goods.getDeptGoodsCategoryId());
|
||||
|
|
@ -198,9 +221,40 @@ public class GoodsController extends BaseController {
|
|||
}
|
||||
}
|
||||
|
||||
// 通过商品规格名称模糊查询
|
||||
if (StringUtils.isNotEmpty(goods.getGoodsStandard())) {
|
||||
logger.info("通过商品规格查询:{}", goods.getGoodsStandard());
|
||||
List<GoodsStandard> matchedStandards = goodsStandardService.selectByStandardNameLike(goods.getGoodsStandard());
|
||||
if (CollectionUtils.isNotEmpty(matchedStandards)) {
|
||||
// 获取所有符合规格条件的商品ID
|
||||
List<Long> goodsIds = matchedStandards.stream()
|
||||
.map(GoodsStandard::getGoodsId)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
logger.info("通过规格查询到的商品ID列表:{}", goodsIds);
|
||||
|
||||
// 设置商品ID筛选条件,与现有的类目筛选条件组合使用
|
||||
if (goods.getGoodsIds() == null) {
|
||||
goods.setGoodsIds(goodsIds);
|
||||
} else {
|
||||
// 如果已有商品ID筛选条件,取交集
|
||||
goods.getGoodsIds().retainAll(goodsIds);
|
||||
}
|
||||
} else {
|
||||
logger.info("未找到符合规格条件的商品,设置空结果");
|
||||
// 如果没找到符合条件的规格,设置一个不存在的商品ID
|
||||
goods.setGoodsIds(Arrays.asList(-1L));
|
||||
}
|
||||
}
|
||||
|
||||
startPage();
|
||||
|
||||
List<Goods> list = goodsService.selectGoodsList(goods);
|
||||
logger.info("传入的类目id汇总{},传入的goods信息为{},获取到的所有商品{}",goods.getDeptGoodsCategoryIds(),goods,list);
|
||||
|
||||
// 用于缓存店铺信息,避免重复查询
|
||||
Map<Long, Shop> shopCache = new HashMap<>();
|
||||
|
||||
list.forEach(one -> {
|
||||
// 补全商品服务区域
|
||||
List<GoodsArea> goodsAreas = goodsAreaService.selectByGoodsId(one.getGoodsId());
|
||||
|
|
@ -218,9 +272,88 @@ public class GoodsController extends BaseController {
|
|||
one.setParGoodsCategoryId(parGoodsCategory.getGoodsCategoryId());
|
||||
one.setParGoodsCategoryName(parGoodsCategory.getGoodsCategoryName());
|
||||
}
|
||||
logger.debug("验证坐标是否合理: {}", LocationUtils.isValidCoordinate(userLatitude, userLongitude));
|
||||
// 计算距离逻辑
|
||||
if (LocationUtils.isValidCoordinate(userLatitude, userLongitude) && one.getShopId() != null) {
|
||||
try {
|
||||
// 从缓存获取店铺信息,避免重复查询
|
||||
Shop shop = shopCache.computeIfAbsent(one.getShopId(),
|
||||
shopId -> shopService.getShop(shopId));
|
||||
|
||||
if (shop != null && LocationUtils.isValidCoordinate(shop.getLatitude(), shop.getLongitude())) {
|
||||
// 计算距离(米)
|
||||
double distanceInMeters = LocationUtils.getDistanceInMeters(
|
||||
userLatitude, userLongitude,
|
||||
shop.getLatitude(), shop.getLongitude()
|
||||
);
|
||||
|
||||
// 格式化距离并设置到商品对象
|
||||
one.setDistance(LocationUtils.formatDistance(distanceInMeters));
|
||||
|
||||
logger.debug("商品[{}]距离用户: {}", one.getGoodsName(), one.getDistance());
|
||||
} else {
|
||||
// 店铺坐标不完整
|
||||
one.setDistance(null);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("计算商品[{}]距离失败: {}", one.getGoodsName(), e.getMessage());
|
||||
// 计算异常时设为null
|
||||
one.setDistance(null);
|
||||
}
|
||||
} else {
|
||||
// 用户未提供位置或商品无店铺信息
|
||||
one.setDistance(null);
|
||||
}
|
||||
});
|
||||
|
||||
// 如果用户提供了位置信息,按距离排序(距离为null的排在最后)
|
||||
if (LocationUtils.isValidCoordinate(userLatitude, userLongitude)) {
|
||||
list.sort((goods1, goods2) -> {
|
||||
String distance1 = goods1.getDistance();
|
||||
String distance2 = goods2.getDistance();
|
||||
|
||||
// 距离为null的排在最后
|
||||
if (distance1 == null && distance2 == null) return 0;
|
||||
if (distance1 == null) return 1;
|
||||
if (distance2 == null) return -1;
|
||||
|
||||
// 解析距离数值进行比较
|
||||
try {
|
||||
double dist1 = parseDistanceToMeters(distance1);
|
||||
double dist2 = parseDistanceToMeters(distance2);
|
||||
return Double.compare(dist1, dist2);
|
||||
} catch (Exception e) {
|
||||
// 解析失败时保持原顺序
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
logger.info("已按距离排序,用户位置: 纬度={}, 经度={}", userLatitude, userLongitude);
|
||||
}
|
||||
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析距离字符串为米数(用于排序)
|
||||
*/
|
||||
private double parseDistanceToMeters(String distanceText) {
|
||||
if (distanceText == null || distanceText.trim().isEmpty()) {
|
||||
return Double.MAX_VALUE;
|
||||
}
|
||||
|
||||
try {
|
||||
if (distanceText.endsWith("米")) {
|
||||
return Double.parseDouble(distanceText.replace("米", ""));
|
||||
} else if (distanceText.endsWith("公里")) {
|
||||
return Double.parseDouble(distanceText.replace("公里", "")) * 1000;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
logger.warn("无法解析距离字符串: {}", distanceText);
|
||||
}
|
||||
|
||||
return Double.MAX_VALUE;
|
||||
}
|
||||
|
||||
@PostMapping("/hot/list")
|
||||
@ResponseBody
|
||||
|
|
@ -271,11 +404,225 @@ public class GoodsController extends BaseController {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品详情
|
||||
*
|
||||
* @param requestBody 请求参数
|
||||
* @return 商品详情信息
|
||||
*/
|
||||
@PostMapping("/getDetail")
|
||||
@ResponseBody
|
||||
public AjaxResult getDetail(@RequestBody Goods goods) {
|
||||
public AjaxResult getDetail(@RequestBody JSONObject requestBody) {
|
||||
try {
|
||||
Goods result = goodsService.selectById(goods.getGoodsId());
|
||||
// 从请求体中提取参数
|
||||
Long goodsId = requestBody.getLong("goodsId");
|
||||
Double userLatitude = requestBody.getDouble("latitude");
|
||||
Double userLongitude = requestBody.getDouble("longitude");
|
||||
String provinceName = requestBody.getString("provinceName");
|
||||
String cityName = requestBody.getString("cityName");
|
||||
String countryName = requestBody.getString("countryName");
|
||||
String streetName = requestBody.getString("streetName");
|
||||
String address = requestBody.getString("address");
|
||||
|
||||
if (goodsId == null) {
|
||||
return AjaxResult.error("商品ID不能为空");
|
||||
}
|
||||
|
||||
Goods result = goodsService.selectById(goodsId);
|
||||
if (result == null) {
|
||||
return AjaxResult.error("商品不存在");
|
||||
}
|
||||
|
||||
// 如果用户没有提供经纬度,但有详细地址,则通过地址获取经纬度
|
||||
if ((userLatitude == null || userLongitude == null) &&
|
||||
(provinceName != null || cityName != null ||
|
||||
countryName != null || streetName != null ||
|
||||
address != null)) {
|
||||
try {
|
||||
// 使用BaiduMapUtils工具类获取经纬度
|
||||
Map<String, Double> coordinates = baiduMapUtils.getCoordinatesByAddress(
|
||||
provinceName, cityName, countryName, streetName, address
|
||||
);
|
||||
|
||||
if (coordinates != null) {
|
||||
userLongitude = coordinates.get("longitude");
|
||||
userLatitude = coordinates.get("latitude");
|
||||
logger.info("通过地址获取到用户经纬度: 经度={}, 纬度={}", userLongitude, userLatitude);
|
||||
} else {
|
||||
logger.warn("通过地址获取用户经纬度失败");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("调用百度地图API异常: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取商品店铺信息
|
||||
Shop goodsShop = null;
|
||||
if (result.getShopId() != null) {
|
||||
try {
|
||||
goodsShop = shopService.getShop(result.getShopId());
|
||||
} catch (Exception e) {
|
||||
logger.warn("获取商品店铺信息失败: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 获取服务店铺信息
|
||||
Shop serviceShop = null;
|
||||
|
||||
if (result.getDeptGoodsCategoryId() != null) {
|
||||
try {
|
||||
// 1. 通过商品的类目ID获取类目信息
|
||||
DeptGoodsCategory deptGoodsCategory = deptGoodsCategoryService.selectOneByGoodsCategoryId(result.getDeptGoodsCategoryId());
|
||||
Long serviceCategoryId = null;
|
||||
|
||||
if (deptGoodsCategory != null) {
|
||||
// 先检查当前类目是否有服务类目ID
|
||||
if (deptGoodsCategory.getServiceCategoryId() != null) {
|
||||
serviceCategoryId = deptGoodsCategory.getServiceCategoryId();
|
||||
logger.debug("当前类目[{}]的服务类目ID: {}", deptGoodsCategory.getGoodsCategoryName(), serviceCategoryId);
|
||||
} else {
|
||||
// 如果当前类目没有服务类目ID,查找上一级类目
|
||||
logger.debug("当前类目[{}]未配置服务类目ID,查找上一级类目", deptGoodsCategory.getGoodsCategoryName());
|
||||
|
||||
if (deptGoodsCategory.getParentCategoryId() != null) {
|
||||
DeptGoodsCategory parentCategory = deptGoodsCategoryService.selectOneByGoodsCategoryId(deptGoodsCategory.getParentCategoryId());
|
||||
if (parentCategory != null && parentCategory.getServiceCategoryId() != null) {
|
||||
serviceCategoryId = parentCategory.getServiceCategoryId();
|
||||
logger.debug("上一级类目[{}]的服务类目ID: {}", parentCategory.getGoodsCategoryName(), serviceCategoryId);
|
||||
} else {
|
||||
logger.debug("上一级类目[{}]也未配置服务类目ID", parentCategory != null ? parentCategory.getGoodsCategoryName() : "null");
|
||||
}
|
||||
} else {
|
||||
logger.debug("当前类目没有父级类目");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (serviceCategoryId != null) {
|
||||
// 2. 通过服务类目ID查询所有使用该服务类目的商品
|
||||
Goods queryGoods = new Goods();
|
||||
queryGoods.setDeptGoodsCategoryId(serviceCategoryId);
|
||||
queryGoods.setStatus(0); // 只查询上架的商品
|
||||
List<Goods> goodsList = goodsService.selectGoodsList(queryGoods);
|
||||
if (goodsList.size()==0){
|
||||
DeptGoodsCategory deptGoodsCategory1=deptGoodsCategoryService.selectOneByGoodsCategoryId(serviceCategoryId);
|
||||
serviceCategoryId=deptGoodsCategory1.getDeptGoodsCategoryId();
|
||||
// 直接使用新方法获取商品列表
|
||||
goodsList = goodsStandardService.selectGoodsByDeptGoodsCategoryId(serviceCategoryId);
|
||||
// 过滤只保留上架的商品
|
||||
goodsList = goodsList.stream()
|
||||
.filter(goods -> goods.getStatus() != null && goods.getStatus() == 0)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
logger.info("获取到的服务类目id{} 取到的商品列表:{}", serviceCategoryId,goodsList);
|
||||
// 3. 提取所有店铺ID(去重)
|
||||
Set<Long> shopIds = goodsList.stream()
|
||||
.filter(g -> g.getShopId() != null)
|
||||
.map(Goods::getShopId)
|
||||
.collect(Collectors.toSet());
|
||||
logger.info("取到的店铺列表:{}", shopIds);
|
||||
if (!shopIds.isEmpty()) {
|
||||
// 找到最近的店铺
|
||||
Shop nearestShop = null;
|
||||
double minDistance = Double.MAX_VALUE;
|
||||
|
||||
for (Long shopId : shopIds) {
|
||||
Shop shop = shopService.getShop(shopId);
|
||||
if (shop != null && LocationUtils.isValidCoordinate(shop.getLatitude(), shop.getLongitude())) {
|
||||
if (LocationUtils.isValidCoordinate(userLatitude, userLongitude)) {
|
||||
try {
|
||||
double distanceInMeters = LocationUtils.getDistanceInMeters(
|
||||
userLatitude, userLongitude,
|
||||
shop.getLatitude(), shop.getLongitude()
|
||||
);
|
||||
if (distanceInMeters < minDistance) {
|
||||
minDistance = distanceInMeters;
|
||||
nearestShop = shop;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("计算店铺[{}]距离失败: {}", shop.getShopName(), e.getMessage());
|
||||
}
|
||||
} else {
|
||||
// 如果用户没有提供位置,选择第一个有效店铺
|
||||
if (nearestShop == null) {
|
||||
nearestShop = shop;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
serviceShop = nearestShop;
|
||||
} else {
|
||||
logger.debug("服务类目[{}]下没有找到商品", serviceCategoryId);
|
||||
}
|
||||
} else {
|
||||
logger.debug("未找到有效的服务类目ID");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("获取服务店铺信息失败: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 设置商品店铺和服务店铺信息
|
||||
if(result.getType()==1){
|
||||
serviceShop=goodsShop;
|
||||
result.setServiceShop(serviceShop);
|
||||
}else {
|
||||
result.setShop(goodsShop);
|
||||
}
|
||||
// 计算距离逻辑
|
||||
if (LocationUtils.isValidCoordinate(userLatitude, userLongitude)) {
|
||||
// 计算服务店铺距离
|
||||
if (serviceShop != null) {
|
||||
try {
|
||||
if (LocationUtils.isValidCoordinate(serviceShop.getLatitude(), serviceShop.getLongitude())) {
|
||||
// 计算距离(米)
|
||||
double distanceInMeters = LocationUtils.getDistanceInMeters(
|
||||
userLatitude, userLongitude,
|
||||
serviceShop.getLatitude(), serviceShop.getLongitude()
|
||||
);
|
||||
|
||||
// 格式化距离并设置到服务店铺对象
|
||||
serviceShop.setDistance(LocationUtils.formatDistance(distanceInMeters));
|
||||
|
||||
logger.debug("商品[{}]服务店铺距离用户: {}", result.getGoodsName(), serviceShop.getDistance());
|
||||
} else {
|
||||
// 店铺坐标不完整
|
||||
serviceShop.setDistance(null);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("计算商品[{}]服务店铺距离失败: {}", result.getGoodsName(), e.getMessage());
|
||||
// 计算异常时设为null
|
||||
serviceShop.setDistance(null);
|
||||
}
|
||||
}
|
||||
|
||||
// 计算商品店铺距离
|
||||
if (goodsShop != null) {
|
||||
try {
|
||||
if (LocationUtils.isValidCoordinate(goodsShop.getLatitude(), goodsShop.getLongitude())) {
|
||||
// 计算距离(米)
|
||||
double distanceInMeters = LocationUtils.getDistanceInMeters(
|
||||
userLatitude, userLongitude,
|
||||
goodsShop.getLatitude(), goodsShop.getLongitude()
|
||||
);
|
||||
|
||||
// 格式化距离并设置到商品店铺对象
|
||||
goodsShop.setDistance(LocationUtils.formatDistance(distanceInMeters));
|
||||
|
||||
logger.debug("商品[{}]商品店铺距离用户: {}", result.getGoodsName(), goodsShop.getDistance());
|
||||
} else {
|
||||
// 店铺坐标不完整
|
||||
goodsShop.setDistance(null);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("计算商品[{}]商品店铺距离失败: {}", result.getGoodsName(), e.getMessage());
|
||||
// 计算异常时设为null
|
||||
goodsShop.setDistance(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
result.setServiceShop(serviceShop);
|
||||
|
||||
// 补全商品类目及父级类目信息
|
||||
GoodsCategory goodsCategory = goodsCategoryService.selectById(result.getDeptGoodsCategoryId());
|
||||
|
|
@ -322,7 +669,24 @@ public class GoodsController extends BaseController {
|
|||
goodsStandard.setFinalPrice(finalPrice);
|
||||
});
|
||||
result.setGoodsStandardList(goodsStandards);
|
||||
|
||||
// 所有保险信息
|
||||
List<InsuranceManager> insuranceManagers = insuranceManagerService.selectInsuranceManagerList(new InsuranceManager());
|
||||
// 查询本类目保险信息
|
||||
DeptCategoryInsuranceRelation param = new DeptCategoryInsuranceRelation();
|
||||
param.setType("01");
|
||||
param.setDeptCategoryId(goodsStandards.get(0).getDeptGoodsCategoryId());
|
||||
List<DeptCategoryInsuranceRelation> deptCategoryInsuranceRelations = deptCategoryInsuranceRelationService.selectDeptCategoryInsuranceRelationList(param);
|
||||
if(CollectionUtils.isNotEmpty(deptCategoryInsuranceRelations)){
|
||||
Map<Long, List<DeptCategoryInsuranceRelation>> insuranceMap = deptCategoryInsuranceRelations.stream().collect(Collectors.groupingBy(DeptCategoryInsuranceRelation::getInsuranceId));
|
||||
// 目标保险
|
||||
List<InsuranceManager> goal = new ArrayList<>();
|
||||
insuranceManagers.forEach(model->{
|
||||
if(insuranceMap.containsKey(model.getId())){
|
||||
goal.add(model);
|
||||
}
|
||||
});
|
||||
result.setInsuranceManagers(goal);
|
||||
}
|
||||
return AjaxResult.success(result);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
|
@ -331,6 +695,186 @@ public class GoodsController extends BaseController {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据商品ID和用户位置获取服务店铺列表
|
||||
* @return 服务店铺列表,按距离排序
|
||||
*/
|
||||
@PostMapping("/getShopsByGoodsId")
|
||||
@ResponseBody
|
||||
public AjaxResult getShopsByGoodsId(@RequestBody JSONObject requestBody) {
|
||||
try {
|
||||
Long goodsId = requestBody.getLong("goodsId");
|
||||
Double latitude = requestBody.getDouble("latitude");
|
||||
Double longitude = requestBody.getDouble("longitude");
|
||||
String provinceName = requestBody.getString("provinceName");
|
||||
String cityName = requestBody.getString("cityName");
|
||||
String countryName = requestBody.getString("countryName");
|
||||
String streetName = requestBody.getString("streetName");
|
||||
String address = requestBody.getString("address");
|
||||
|
||||
if (goodsId == null) {
|
||||
return AjaxResult.error("商品ID不能为空");
|
||||
}
|
||||
|
||||
// 如果用户没有提供经纬度,但有详细地址,则通过地址获取经纬度
|
||||
if ((latitude == null || longitude == null) &&
|
||||
(provinceName != null || cityName != null || countryName != null ||
|
||||
streetName != null || address != null)) {
|
||||
try {
|
||||
// 使用BaiduMapUtils工具类获取经纬度
|
||||
Map<String, Double> coordinates = baiduMapUtils.getCoordinatesByAddress(
|
||||
provinceName, cityName, countryName, streetName, address
|
||||
);
|
||||
|
||||
if (coordinates != null) {
|
||||
longitude = coordinates.get("longitude");
|
||||
latitude = coordinates.get("latitude");
|
||||
logger.info("通过地址获取到用户经纬度: 经度={}, 纬度={}", longitude, latitude);
|
||||
} else {
|
||||
logger.warn("通过地址获取用户经纬度失败");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("调用百度地图API异常: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取商品信息
|
||||
Goods goods = goodsService.selectById(goodsId);
|
||||
if (goods == null) {
|
||||
return AjaxResult.error("商品不存在");
|
||||
}
|
||||
|
||||
List<Shop> serviceShops = new ArrayList<>();
|
||||
|
||||
// 通过商品的服务类目获取服务店铺
|
||||
if (goods.getDeptGoodsCategoryId() != null) {
|
||||
try {
|
||||
// 1. 通过商品的类目ID获取类目信息
|
||||
DeptGoodsCategory deptGoodsCategory = deptGoodsCategoryService.selectOneByGoodsCategoryId(goods.getDeptGoodsCategoryId());
|
||||
Long serviceCategoryId = null;
|
||||
|
||||
if (deptGoodsCategory != null) {
|
||||
// 先检查当前类目是否有服务类目ID
|
||||
if (deptGoodsCategory.getServiceCategoryId() != null) {
|
||||
serviceCategoryId = deptGoodsCategory.getServiceCategoryId();
|
||||
logger.debug("当前类目[{}]的服务类目ID: {}", deptGoodsCategory.getGoodsCategoryName(), serviceCategoryId);
|
||||
} else {
|
||||
// 如果当前类目没有服务类目ID,查找上一级类目
|
||||
logger.debug("当前类目[{}]未配置服务类目ID,查找上一级类目", deptGoodsCategory.getGoodsCategoryName());
|
||||
|
||||
if (deptGoodsCategory.getParentCategoryId() != null) {
|
||||
DeptGoodsCategory parentCategory = deptGoodsCategoryService.selectOneByGoodsCategoryId(deptGoodsCategory.getParentCategoryId());
|
||||
if (parentCategory != null && parentCategory.getServiceCategoryId() != null) {
|
||||
serviceCategoryId = parentCategory.getServiceCategoryId();
|
||||
logger.debug("上一级类目[{}]的服务类目ID: {}", parentCategory.getGoodsCategoryName(), serviceCategoryId);
|
||||
} else {
|
||||
logger.debug("上一级类目[{}]也未配置服务类目ID", parentCategory != null ? parentCategory.getGoodsCategoryName() : "null");
|
||||
}
|
||||
} else {
|
||||
logger.debug("当前类目没有父级类目");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<Goods> goodsList = new ArrayList<>();
|
||||
if (serviceCategoryId != null) {
|
||||
// 2. 通过服务类目ID查询所有使用该服务类目的商品
|
||||
Goods queryGoods = new Goods();
|
||||
queryGoods.setDeptGoodsCategoryId(serviceCategoryId);
|
||||
queryGoods.setStatus(0); // 只查询上架的商品
|
||||
goodsList = goodsService.selectGoodsList(queryGoods);
|
||||
if (goodsList.size() == 0) {
|
||||
DeptGoodsCategory deptGoodsCategory1 = deptGoodsCategoryService.selectOneByGoodsCategoryId(serviceCategoryId);
|
||||
serviceCategoryId = deptGoodsCategory1.getDeptGoodsCategoryId();
|
||||
// 直接使用新方法获取商品列表
|
||||
goodsList = goodsStandardService.selectGoodsByDeptGoodsCategoryId(serviceCategoryId);
|
||||
// 过滤只保留上架的商品
|
||||
goodsList = goodsList.stream()
|
||||
.filter(g -> g.getStatus() != null && g.getStatus() == 0)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
logger.info("获取到的服务类目id{} 取到的商品列表:{}", serviceCategoryId, goodsList);
|
||||
}
|
||||
|
||||
if (!goodsList.isEmpty()) {
|
||||
logger.debug("通过商品ID[{}]找到{}个相关服务商品", goodsId, goodsList.size());
|
||||
|
||||
// 提取所有店铺ID(去重)
|
||||
Set<Long> shopIds = goodsList.stream()
|
||||
.filter(g -> g.getShopId() != null)
|
||||
.map(Goods::getShopId)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
if (!shopIds.isEmpty()) {
|
||||
// 获取所有店铺信息并计算距离
|
||||
for (Long shopId : shopIds) {
|
||||
Shop shop = shopService.getShop(shopId);
|
||||
if (shop != null) {
|
||||
// 计算距离
|
||||
if (LocationUtils.isValidCoordinate(latitude, longitude) &&
|
||||
LocationUtils.isValidCoordinate(shop.getLatitude(), shop.getLongitude())) {
|
||||
try {
|
||||
double distanceInMeters = LocationUtils.getDistanceInMeters(
|
||||
latitude, longitude,
|
||||
shop.getLatitude(), shop.getLongitude()
|
||||
);
|
||||
shop.setDistance(LocationUtils.formatDistance(distanceInMeters));
|
||||
} catch (Exception e) {
|
||||
logger.warn("计算店铺[{}]距离失败: {}", shop.getShopName(), e.getMessage());
|
||||
shop.setDistance(null);
|
||||
}
|
||||
} else {
|
||||
shop.setDistance(null);
|
||||
}
|
||||
serviceShops.add(shop);
|
||||
}
|
||||
}
|
||||
|
||||
// 按距离排序(有距离的排在前面,然后按距离升序)
|
||||
serviceShops.sort((s1, s2) -> {
|
||||
if (s1.getDistance() == null && s2.getDistance() == null) {
|
||||
return 0;
|
||||
}
|
||||
if (s1.getDistance() == null) {
|
||||
return 1;
|
||||
}
|
||||
if (s2.getDistance() == null) {
|
||||
return -1;
|
||||
}
|
||||
// 提取距离数值进行比较
|
||||
try {
|
||||
double d1 = Double.parseDouble(s1.getDistance().replaceAll("[^0-9.]", ""));
|
||||
double d2 = Double.parseDouble(s2.getDistance().replaceAll("[^0-9.]", ""));
|
||||
return Double.compare(d1, d2);
|
||||
} catch (Exception e) {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
logger.debug("未找到商品ID[{}]的相关服务商品", goodsId);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("获取服务店铺信息失败: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("goodsId", goodsId);
|
||||
result.put("goodsName", goods.getGoodsName());
|
||||
result.put("userLatitude", latitude);
|
||||
result.put("userLongitude", longitude);
|
||||
result.put("serviceShops", serviceShops);
|
||||
result.put("totalCount", serviceShops.size());
|
||||
|
||||
return AjaxResult.success(result);
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("获取服务店铺列表失败: {}", e.getMessage(), e);
|
||||
return AjaxResult.error("获取服务店铺列表失败: " + ExceptionUtil.getExceptionMessage(e));
|
||||
}
|
||||
}
|
||||
|
||||
@Log(title = "商品管理", businessType = BusinessType.EXPORT)
|
||||
@RequiresPermissions("goods:goods:export")
|
||||
@PostMapping("/export")
|
||||
|
|
@ -401,13 +945,26 @@ public class GoodsController extends BaseController {
|
|||
@ResponseBody
|
||||
public AjaxResult editSave(@Validated Goods goods) {
|
||||
goods.setUpdateBy(getLoginName());
|
||||
|
||||
// 处理Long类型字段的空值情况
|
||||
// 当前端传入0或空字符串时,将shopId设置为null以便清空
|
||||
if (goods.getShopId() != null && goods.getShopId().equals(0L)) {
|
||||
goods.setShopId(null);
|
||||
}
|
||||
|
||||
return toAjax(goodsService.updateGoods(goods));
|
||||
}
|
||||
|
||||
@PostMapping("/app/edit")
|
||||
@ResponseBody
|
||||
public AjaxResult appEditSave(@RequestBody @Validated Goods goods) {
|
||||
|
||||
|
||||
// 处理Long类型字段的空值情况
|
||||
// 当前端传入0或空字符串时,将shopId设置为null以便清空
|
||||
if (goods.getShopId() != null && goods.getShopId().equals(0L)) {
|
||||
goods.setShopId(null);
|
||||
}
|
||||
|
||||
goodsService.edit(goods);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
|
@ -467,4 +1024,6 @@ public class GoodsController extends BaseController {
|
|||
return AjaxResult.error(ExceptionUtil.getExceptionMessage(e));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package com.ghy.web.controller.goods;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.ghy.common.annotation.Log;
|
||||
import com.ghy.common.core.controller.BaseController;
|
||||
import com.ghy.common.core.domain.AjaxResult;
|
||||
|
|
@ -10,10 +12,8 @@ import com.ghy.common.enums.ImgType;
|
|||
import com.ghy.common.utils.ExceptionUtil;
|
||||
import com.ghy.common.utils.ShiroUtils;
|
||||
import com.ghy.common.utils.StringUtils;
|
||||
import com.ghy.goods.domain.DeptGoodsCategory;
|
||||
import com.ghy.goods.domain.GoodsImgs;
|
||||
import com.ghy.goods.service.DeptGoodsCategoryService;
|
||||
import com.ghy.goods.service.GoodsImgsService;
|
||||
import com.ghy.goods.domain.*;
|
||||
import com.ghy.goods.service.*;
|
||||
import com.ghy.web.pojo.vo.AppCategoryRequest;
|
||||
import com.ghy.web.pojo.vo.HotCategoryResponse;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
|
|
@ -30,6 +30,7 @@ import java.util.List;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
@Controller
|
||||
@CrossOrigin(origins = "*")
|
||||
@RequestMapping("goods/deptcategory")
|
||||
public class GoodsDeptCategoryController extends BaseController {
|
||||
|
||||
|
|
@ -38,6 +39,18 @@ public class GoodsDeptCategoryController extends BaseController {
|
|||
@Resource
|
||||
DeptGoodsCategoryService deptGoodsCategoryService;
|
||||
|
||||
@Resource
|
||||
private GoodsCategoryService goodsCategoryService;
|
||||
|
||||
@Resource
|
||||
ICategoryInsuranceRelationService categoryInsuranceRelationService;
|
||||
|
||||
@Resource
|
||||
IDeptCategoryInsuranceRelationService deptCategoryInsuranceRelationService;
|
||||
|
||||
@Resource
|
||||
IInsuranceManagerService insuranceManagerService;
|
||||
|
||||
@Autowired
|
||||
private GoodsImgsService goodsImgsService;
|
||||
|
||||
|
|
@ -145,6 +158,57 @@ public class GoodsDeptCategoryController extends BaseController {
|
|||
@GetMapping("/edit/{id}")
|
||||
public String edit(@PathVariable("id") Long id, ModelMap mmap) {
|
||||
DeptGoodsCategory deptGoodsCategory = deptGoodsCategoryService.get(id);
|
||||
CategoryInsuranceRelation relation = new CategoryInsuranceRelation();
|
||||
relation.setGoodsCategoryId(deptGoodsCategory.getGoodsCategoryId());
|
||||
List<CategoryInsuranceRelation> relations = categoryInsuranceRelationService.selectCategoryInsuranceRelationList(relation);
|
||||
// 当第四级没有的时候,往上找三级
|
||||
if(CollectionUtil.isEmpty(relations)){
|
||||
GoodsCategory model = goodsCategoryService.selectById(deptGoodsCategory.getGoodsCategoryId());
|
||||
CategoryInsuranceRelation parentRelation = new CategoryInsuranceRelation();
|
||||
parentRelation.setGoodsCategoryId(model.getParentCategoryId());
|
||||
relations = categoryInsuranceRelationService.selectCategoryInsuranceRelationList(parentRelation);
|
||||
// 当第三级没有的时候,往上找二级
|
||||
if(CollectionUtil.isEmpty(relations)){
|
||||
GoodsCategory parentModel = goodsCategoryService.selectById(model.getParentCategoryId());
|
||||
CategoryInsuranceRelation topRelation = new CategoryInsuranceRelation();
|
||||
topRelation.setGoodsCategoryId(parentModel.getParentCategoryId());
|
||||
relations = categoryInsuranceRelationService.selectCategoryInsuranceRelationList(topRelation);
|
||||
}
|
||||
}
|
||||
// pc保险设置
|
||||
List<InsuranceManager> pcInsuranceList = new ArrayList<>();
|
||||
// 商城保险设置
|
||||
List<InsuranceManager> shopInsuranceList = new ArrayList<>();
|
||||
if(CollectionUtil.isNotEmpty(relations)){
|
||||
List<InsuranceManager> list = insuranceManagerService.selectByIds(relations.stream().map(CategoryInsuranceRelation::getInsuranceId).collect(Collectors.toList()));
|
||||
list.forEach(model->{
|
||||
model.setInsuranceName(model.getCompanyName() + "||" + model.getInsuranceName() + "||" + model.getInsuranceAmount() + "元");
|
||||
// 查看pc勾选状态
|
||||
DeptCategoryInsuranceRelation pcParam = new DeptCategoryInsuranceRelation();
|
||||
pcParam.setType("02");
|
||||
pcParam.setInsuranceId(model.getId());
|
||||
pcParam.setDeptCategoryId(deptGoodsCategory.getDeptGoodsCategoryId());
|
||||
InsuranceManager pcModel = new InsuranceManager();
|
||||
BeanUtil.copyProperties(model, pcModel);
|
||||
if(CollectionUtil.isNotEmpty(deptCategoryInsuranceRelationService.selectDeptCategoryInsuranceRelationList(pcParam))){
|
||||
pcModel.setFlag(true);
|
||||
}
|
||||
pcInsuranceList.add(pcModel);
|
||||
|
||||
DeptCategoryInsuranceRelation shopParam = new DeptCategoryInsuranceRelation();
|
||||
shopParam.setType("01");
|
||||
shopParam.setInsuranceId(model.getId());
|
||||
shopParam.setDeptCategoryId(deptGoodsCategory.getDeptGoodsCategoryId());
|
||||
InsuranceManager shopModel = new InsuranceManager();
|
||||
BeanUtil.copyProperties(model, shopModel);
|
||||
if(CollectionUtil.isNotEmpty(deptCategoryInsuranceRelationService.selectDeptCategoryInsuranceRelationList(shopParam))){
|
||||
shopModel.setFlag(true);
|
||||
}
|
||||
shopInsuranceList.add(shopModel);
|
||||
});
|
||||
}
|
||||
mmap.put("pcInsurances", pcInsuranceList);
|
||||
mmap.put("shopInsurances", shopInsuranceList);
|
||||
mmap.put("deptGoodsCategory", deptGoodsCategory);
|
||||
return PREFIX + "/edit";
|
||||
}
|
||||
|
|
@ -153,6 +217,8 @@ public class GoodsDeptCategoryController extends BaseController {
|
|||
@PostMapping("/edit")
|
||||
@ResponseBody
|
||||
public AjaxResult edit(DeptGoodsCategory category) {
|
||||
// 更新保险设置
|
||||
deptCategoryInsuranceRelationService.updateDeptCategoryInsuranceRelation(category.getPcInsuranceIds(), category.getShopInsuranceIds(), category.getDeptGoodsCategoryId());
|
||||
category.setUpdateBy(getLoginName());
|
||||
deptGoodsCategoryService.edit(category);
|
||||
return AjaxResult.success();
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.ghy.web.controller.goods;
|
|||
import com.ghy.common.core.controller.BaseController;
|
||||
import com.ghy.common.core.domain.AjaxResult;
|
||||
import com.ghy.common.core.page.TableDataInfo;
|
||||
import com.ghy.goods.domain.Goods;
|
||||
import com.ghy.goods.domain.GoodsStandard;
|
||||
import com.ghy.goods.service.GoodsStandardService;
|
||||
import com.ghy.order.domain.OrderTemplate;
|
||||
|
|
@ -64,4 +65,14 @@ public class GoodsStandardController extends BaseController {
|
|||
return toAjax(goodsStandardService.save(goodsStandardList));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据部门商品分类ID获取商品列表
|
||||
*/
|
||||
@ResponseBody
|
||||
@GetMapping("/goods/by-dept-category/{deptGoodsCategoryId}")
|
||||
public AjaxResult getGoodsByDeptCategoryId(@PathVariable("deptGoodsCategoryId") Long deptGoodsCategoryId) {
|
||||
List<Goods> goodsList = goodsStandardService.selectGoodsByDeptGoodsCategoryId(deptGoodsCategoryId);
|
||||
return AjaxResult.success(goodsList);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,135 @@
|
|||
package com.ghy.web.controller.goods;
|
||||
import java.util.List;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import com.ghy.common.annotation.Log;
|
||||
import com.ghy.common.enums.BusinessType;
|
||||
import com.ghy.goods.domain.InsuranceManager;
|
||||
import com.ghy.goods.service.IInsuranceManagerService;
|
||||
import com.ghy.common.core.controller.BaseController;
|
||||
import com.ghy.common.core.domain.AjaxResult;
|
||||
import com.ghy.common.utils.poi.ExcelUtil;
|
||||
import com.ghy.common.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 保险管理Controller
|
||||
*
|
||||
* @author clunt
|
||||
* @date 2024-09-25
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/goods/manager")
|
||||
public class InsuranceManagerController extends BaseController
|
||||
{
|
||||
private String prefix = "goods/manager";
|
||||
|
||||
@Autowired
|
||||
private IInsuranceManagerService insuranceManagerService;
|
||||
|
||||
@RequiresPermissions("goods:manager:view")
|
||||
@GetMapping()
|
||||
public String manager()
|
||||
{
|
||||
return prefix + "/manager";
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询保险管理列表
|
||||
*/
|
||||
@RequiresPermissions("goods:manager:list")
|
||||
@PostMapping("/list")
|
||||
@ResponseBody
|
||||
public TableDataInfo list(InsuranceManager insuranceManager)
|
||||
{
|
||||
startPage();
|
||||
List<InsuranceManager> list = insuranceManagerService.selectInsuranceManagerList(insuranceManager);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* App查询保险管理列表
|
||||
*/
|
||||
@PostMapping("/app/list")
|
||||
@ResponseBody
|
||||
public TableDataInfo appList(@RequestBody InsuranceManager insuranceManager)
|
||||
{
|
||||
startPage();
|
||||
List<InsuranceManager> list = insuranceManagerService.selectInsuranceManagerList(insuranceManager);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 导出保险管理列表
|
||||
*/
|
||||
@RequiresPermissions("goods:manager:export")
|
||||
@Log(title = "保险管理", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
@ResponseBody
|
||||
public AjaxResult export(InsuranceManager insuranceManager)
|
||||
{
|
||||
List<InsuranceManager> list = insuranceManagerService.selectInsuranceManagerList(insuranceManager);
|
||||
ExcelUtil<InsuranceManager> util = new ExcelUtil<InsuranceManager>(InsuranceManager.class);
|
||||
return util.exportExcel(list, "保险管理数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增保险管理
|
||||
*/
|
||||
@GetMapping("/add")
|
||||
public String add()
|
||||
{
|
||||
return prefix + "/add";
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增保存保险管理
|
||||
*/
|
||||
@RequiresPermissions("goods:manager:add")
|
||||
@Log(title = "保险管理", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/add")
|
||||
@ResponseBody
|
||||
public AjaxResult addSave(InsuranceManager insuranceManager)
|
||||
{
|
||||
return toAjax(insuranceManagerService.insertInsuranceManager(insuranceManager));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改保险管理
|
||||
*/
|
||||
@RequiresPermissions("goods:manager:edit")
|
||||
@GetMapping("/edit/{id}")
|
||||
public String edit(@PathVariable("id") Long id, ModelMap mmap)
|
||||
{
|
||||
InsuranceManager insuranceManager = insuranceManagerService.selectInsuranceManagerById(id);
|
||||
mmap.put("insuranceManager", insuranceManager);
|
||||
return prefix + "/edit";
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改保存保险管理
|
||||
*/
|
||||
@RequiresPermissions("goods:manager:edit")
|
||||
@Log(title = "保险管理", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/edit")
|
||||
@ResponseBody
|
||||
public AjaxResult editSave(InsuranceManager insuranceManager)
|
||||
{
|
||||
return toAjax(insuranceManagerService.updateInsuranceManager(insuranceManager));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除保险管理
|
||||
*/
|
||||
@RequiresPermissions("goods:manager:remove")
|
||||
@Log(title = "保险管理", businessType = BusinessType.DELETE)
|
||||
@PostMapping( "/remove")
|
||||
@ResponseBody
|
||||
public AjaxResult remove(String ids)
|
||||
{
|
||||
return toAjax(insuranceManagerService.deleteInsuranceManagerByIds(ids));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
package com.ghy.web.controller.order;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 售后纠纷处理请求
|
||||
*
|
||||
* @author system
|
||||
* @date 2024-12-19
|
||||
*/
|
||||
public class AfterServiceDisputeRequest {
|
||||
|
||||
/**
|
||||
* 售后记录ID
|
||||
*/
|
||||
private String recordId;
|
||||
|
||||
/**
|
||||
* 主单ID
|
||||
*/
|
||||
private Long orderMasterId;
|
||||
|
||||
/**
|
||||
* 子单ID
|
||||
*/
|
||||
private Long orderDetailId;
|
||||
|
||||
/**
|
||||
* 退款金额
|
||||
*/
|
||||
private BigDecimal refundAmount;
|
||||
|
||||
/**
|
||||
* 售后纠纷平台处理原因
|
||||
*/
|
||||
private String platformHandleReason;
|
||||
|
||||
public String getRecordId() {
|
||||
return recordId;
|
||||
}
|
||||
|
||||
public void setRecordId(String recordId) {
|
||||
this.recordId = recordId;
|
||||
}
|
||||
|
||||
public Long getOrderMasterId() {
|
||||
return orderMasterId;
|
||||
}
|
||||
|
||||
public void setOrderMasterId(Long orderMasterId) {
|
||||
this.orderMasterId = orderMasterId;
|
||||
}
|
||||
|
||||
public Long getOrderDetailId() {
|
||||
return orderDetailId;
|
||||
}
|
||||
|
||||
public void setOrderDetailId(Long orderDetailId) {
|
||||
this.orderDetailId = orderDetailId;
|
||||
}
|
||||
|
||||
public BigDecimal getRefundAmount() {
|
||||
return refundAmount;
|
||||
}
|
||||
|
||||
public void setRefundAmount(BigDecimal refundAmount) {
|
||||
this.refundAmount = refundAmount;
|
||||
}
|
||||
|
||||
public String getPlatformHandleReason() {
|
||||
return platformHandleReason;
|
||||
}
|
||||
|
||||
public void setPlatformHandleReason(String platformHandleReason) {
|
||||
this.platformHandleReason = platformHandleReason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AfterServiceDisputeRequest{" +
|
||||
"recordId='" + recordId + '\'' +
|
||||
", orderMasterId=" + orderMasterId +
|
||||
", orderDetailId=" + orderDetailId +
|
||||
", refundAmount=" + refundAmount +
|
||||
", platformHandleReason='" + platformHandleReason + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
@ -108,7 +108,7 @@ public class AfterServiceRecordController extends BaseController {
|
|||
public AjaxResult addSave(@RequestBody AfterServiceRecord afterServiceRecord) {
|
||||
logger.info("新增售后记录:{}", afterServiceRecord);
|
||||
OrderDetail orderDetail = orderDetailService.selectById(afterServiceRecord.getOrderDetailId());
|
||||
if(orderDetail.getDrawCashTime() != null){
|
||||
if (orderDetail.getDrawCashTime() != null) {
|
||||
return AjaxResult.error("已发起分账子单,请联系师傅处理线下售后!");
|
||||
}
|
||||
return toAjax(afterServiceRecordService.insertAfterServiceRecord(afterServiceRecord));
|
||||
|
|
@ -134,11 +134,22 @@ public class AfterServiceRecordController extends BaseController {
|
|||
public AjaxResult editSave(@RequestBody AfterServiceRecord afterServiceRecord) {
|
||||
logger.info("修改售后记录:{}", afterServiceRecord);
|
||||
try {
|
||||
OrderDetail orderDetail = orderDetailService.selectById(afterServiceRecord.getOrderDetailId());
|
||||
if(orderDetail.getDrawCashTime() != null){
|
||||
return AjaxResult.error("已发起分账子单,请联系师傅处理线下售后!");
|
||||
}
|
||||
return toAjax(afterServiceRecordService.updateAfterServiceRecord(afterServiceRecord));
|
||||
return afterServiceRecordService.updateAfterServiceRecord(afterServiceRecord);
|
||||
} catch (Exception exception) {
|
||||
logger.error(ExceptionUtils.getStackTrace(exception));
|
||||
return AjaxResult.error(exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改商品售后记录
|
||||
*/
|
||||
@PostMapping("/editGoods")
|
||||
@ResponseBody
|
||||
public AjaxResult editGoodsSave(@RequestBody AfterServiceRecord afterServiceRecord) {
|
||||
logger.info("修改商品售后记录:{}", afterServiceRecord);
|
||||
try {
|
||||
return afterServiceRecordService.updateGoodsAfterServiceRecord(afterServiceRecord);
|
||||
} catch (Exception exception) {
|
||||
logger.error(ExceptionUtils.getStackTrace(exception));
|
||||
return AjaxResult.error(exception.getMessage());
|
||||
|
|
@ -155,4 +166,34 @@ public class AfterServiceRecordController extends BaseController {
|
|||
public AjaxResult remove(String ids) {
|
||||
return toAjax(afterServiceRecordService.deleteAfterServiceRecordByIds(ids));
|
||||
}
|
||||
|
||||
/**
|
||||
* 师傅重发/补发操作
|
||||
* 师傅端点击重发补发按钮,保存重发/补发方案
|
||||
*/
|
||||
@PostMapping("/workerResendPlan")
|
||||
@ResponseBody
|
||||
public AjaxResult workerResendPlan(@RequestBody AfterServiceRecord afterServiceRecord) {
|
||||
return afterServiceRecordService.workerResendPlan(afterServiceRecord);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退货操作
|
||||
* 客户或师傅端进行退货操作,保存退货信息
|
||||
*/
|
||||
@PostMapping("/returnGoods")
|
||||
@ResponseBody
|
||||
public AjaxResult returnGoods(@RequestBody AfterServiceRecord afterServiceRecord) {
|
||||
return afterServiceRecordService.returnGoods(afterServiceRecord);
|
||||
}
|
||||
|
||||
/**
|
||||
* 师傅确认收货
|
||||
* 师傅确认收到货物后,根据同意处理方式决定是否执行退款
|
||||
*/
|
||||
@PostMapping("/workerConfirmReceive")
|
||||
@ResponseBody
|
||||
public AjaxResult workerConfirmReceive(@RequestBody AfterServiceRecord afterServiceRecord) {
|
||||
return afterServiceRecordService.workerConfirmReceive(afterServiceRecord);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,143 @@
|
|||
package com.ghy.web.controller.order;
|
||||
|
||||
import java.util.List;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import com.ghy.common.annotation.Log;
|
||||
import com.ghy.common.enums.BusinessType;
|
||||
import com.ghy.order.domain.OrderAddRecord;
|
||||
import com.ghy.order.service.IOrderAddRecordService;
|
||||
import com.ghy.common.core.controller.BaseController;
|
||||
import com.ghy.common.core.domain.AjaxResult;
|
||||
import com.ghy.common.utils.poi.ExcelUtil;
|
||||
import com.ghy.common.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 发单加价记录Controller
|
||||
*
|
||||
* @author clunt
|
||||
* @date 2023-11-03
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/add/record")
|
||||
public class OrderAddRecordController extends BaseController
|
||||
{
|
||||
private String prefix = "add/record";
|
||||
|
||||
@Autowired
|
||||
private IOrderAddRecordService orderAddRecordService;
|
||||
|
||||
@RequiresPermissions("worker:record:view")
|
||||
@GetMapping()
|
||||
public String record()
|
||||
{
|
||||
return prefix + "/record";
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询发单加价记录列表
|
||||
*/
|
||||
@RequiresPermissions("worker:record:list")
|
||||
@PostMapping("/list")
|
||||
@ResponseBody
|
||||
public TableDataInfo list(OrderAddRecord orderAddRecord)
|
||||
{
|
||||
startPage();
|
||||
List<OrderAddRecord> list = orderAddRecordService.selectOrderAddRecordList(orderAddRecord);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* App查询发单加价记录列表
|
||||
*/
|
||||
@PostMapping("/app/list")
|
||||
@ResponseBody
|
||||
public TableDataInfo appList(@RequestBody OrderAddRecord orderAddRecord)
|
||||
{
|
||||
startPage();
|
||||
List<OrderAddRecord> list = orderAddRecordService.selectOrderAddRecordList(orderAddRecord);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@PostMapping("/app/add")
|
||||
@ResponseBody
|
||||
public AjaxResult appAddSave(@RequestBody OrderAddRecord orderAddRecord)
|
||||
{
|
||||
return toAjax(orderAddRecordService.insertOrderAddRecord(orderAddRecord));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 导出发单加价记录列表
|
||||
*/
|
||||
@RequiresPermissions("worker:record:export")
|
||||
@Log(title = "发单加价记录", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
@ResponseBody
|
||||
public AjaxResult export(OrderAddRecord orderAddRecord)
|
||||
{
|
||||
List<OrderAddRecord> list = orderAddRecordService.selectOrderAddRecordList(orderAddRecord);
|
||||
ExcelUtil<OrderAddRecord> util = new ExcelUtil<OrderAddRecord>(OrderAddRecord.class);
|
||||
return util.exportExcel(list, "发单加价记录数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增发单加价记录
|
||||
*/
|
||||
@GetMapping("/add")
|
||||
public String add()
|
||||
{
|
||||
return prefix + "/add";
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增保存发单加价记录
|
||||
*/
|
||||
@RequiresPermissions("worker:record:add")
|
||||
@Log(title = "发单加价记录", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/add")
|
||||
@ResponseBody
|
||||
public AjaxResult addSave(OrderAddRecord orderAddRecord)
|
||||
{
|
||||
return toAjax(orderAddRecordService.insertOrderAddRecord(orderAddRecord));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改发单加价记录
|
||||
*/
|
||||
@RequiresPermissions("worker:record:edit")
|
||||
@GetMapping("/edit/{id}")
|
||||
public String edit(@PathVariable("id") Long id, ModelMap mmap)
|
||||
{
|
||||
OrderAddRecord orderAddRecord = orderAddRecordService.selectOrderAddRecordById(id);
|
||||
mmap.put("orderAddRecord", orderAddRecord);
|
||||
return prefix + "/edit";
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改保存发单加价记录
|
||||
*/
|
||||
@RequiresPermissions("worker:record:edit")
|
||||
@Log(title = "发单加价记录", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/edit")
|
||||
@ResponseBody
|
||||
public AjaxResult editSave(OrderAddRecord orderAddRecord)
|
||||
{
|
||||
return toAjax(orderAddRecordService.updateOrderAddRecord(orderAddRecord));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除发单加价记录
|
||||
*/
|
||||
@RequiresPermissions("worker:record:remove")
|
||||
@Log(title = "发单加价记录", businessType = BusinessType.DELETE)
|
||||
@PostMapping( "/remove")
|
||||
@ResponseBody
|
||||
public AjaxResult remove(String ids)
|
||||
{
|
||||
return toAjax(orderAddRecordService.deleteOrderAddRecordByIds(ids));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,157 @@
|
|||
package com.ghy.web.controller.order;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import com.ghy.common.annotation.Log;
|
||||
import com.ghy.common.enums.BusinessType;
|
||||
import com.ghy.order.domain.OrderAttachmentRecord;
|
||||
import com.ghy.order.service.IOrderAttachmentRecordService;
|
||||
import com.ghy.common.core.controller.BaseController;
|
||||
import com.ghy.common.core.domain.AjaxResult;
|
||||
import com.ghy.common.utils.poi.ExcelUtil;
|
||||
import com.ghy.common.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 附件费Controller
|
||||
*
|
||||
* @author clunt
|
||||
* @date 2024-01-02
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/order/attach")
|
||||
public class OrderAttachmentRecordController extends BaseController
|
||||
{
|
||||
private String prefix = "order/attach";
|
||||
|
||||
@Autowired
|
||||
private IOrderAttachmentRecordService orderAttachmentRecordService;
|
||||
|
||||
@RequiresPermissions("attach:record:view")
|
||||
@GetMapping()
|
||||
public String record()
|
||||
{
|
||||
return prefix + "/record";
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询附件费列表
|
||||
*/
|
||||
@RequiresPermissions("attach:record:list")
|
||||
@PostMapping("/list")
|
||||
@ResponseBody
|
||||
public TableDataInfo list(OrderAttachmentRecord orderAttachmentRecord)
|
||||
{
|
||||
startPage();
|
||||
List<OrderAttachmentRecord> list = orderAttachmentRecordService.selectOrderAttachmentRecordList(orderAttachmentRecord);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* App查询附件费列表
|
||||
*/
|
||||
@PostMapping("/app/list")
|
||||
@ResponseBody
|
||||
public TableDataInfo appList(@RequestBody OrderAttachmentRecord orderAttachmentRecord)
|
||||
{
|
||||
startPage();
|
||||
List<OrderAttachmentRecord> list = orderAttachmentRecordService.selectOrderAttachmentRecordList(orderAttachmentRecord);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 导出附件费列表
|
||||
*/
|
||||
@RequiresPermissions("attach:record:export")
|
||||
@Log(title = "附件费", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
@ResponseBody
|
||||
public AjaxResult export(OrderAttachmentRecord orderAttachmentRecord)
|
||||
{
|
||||
List<OrderAttachmentRecord> list = orderAttachmentRecordService.selectOrderAttachmentRecordList(orderAttachmentRecord);
|
||||
ExcelUtil<OrderAttachmentRecord> util = new ExcelUtil<OrderAttachmentRecord>(OrderAttachmentRecord.class);
|
||||
return util.exportExcel(list, "附件费数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增附件费
|
||||
*/
|
||||
@GetMapping("/add")
|
||||
public String add()
|
||||
{
|
||||
return prefix + "/add";
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增保存附件费
|
||||
*/
|
||||
@RequiresPermissions("attach:record:add")
|
||||
@Log(title = "附件费", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/add")
|
||||
@ResponseBody
|
||||
public AjaxResult addSave(OrderAttachmentRecord orderAttachmentRecord)
|
||||
{
|
||||
return toAjax(orderAttachmentRecordService.insertOrderAttachmentRecord(orderAttachmentRecord));
|
||||
}
|
||||
|
||||
@PostMapping("/appAdd")
|
||||
@ResponseBody
|
||||
public AjaxResult appAdd(OrderAttachmentRecord orderAttachmentRecord)
|
||||
{
|
||||
return toAjax(orderAttachmentRecordService.insertOrderAttachmentRecord(orderAttachmentRecord));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改附件费
|
||||
*/
|
||||
@RequiresPermissions("attach:record:edit")
|
||||
@GetMapping("/edit/{id}")
|
||||
public String edit(@PathVariable("id") Long id, ModelMap mmap)
|
||||
{
|
||||
OrderAttachmentRecord orderAttachmentRecord = orderAttachmentRecordService.selectOrderAttachmentRecordById(id);
|
||||
mmap.put("orderAttachmentRecord", orderAttachmentRecord);
|
||||
return prefix + "/edit";
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改保存附件费
|
||||
*/
|
||||
@RequiresPermissions("attach:record:edit")
|
||||
@Log(title = "附件费", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/edit")
|
||||
@ResponseBody
|
||||
public AjaxResult editSave(OrderAttachmentRecord orderAttachmentRecord)
|
||||
{
|
||||
return toAjax(orderAttachmentRecordService.updateOrderAttachmentRecord(orderAttachmentRecord));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除附件费
|
||||
*/
|
||||
@RequiresPermissions("attach:record:remove")
|
||||
@Log(title = "附件费", businessType = BusinessType.DELETE)
|
||||
@PostMapping( "/remove")
|
||||
@ResponseBody
|
||||
public AjaxResult remove(String ids)
|
||||
{
|
||||
return toAjax(orderAttachmentRecordService.deleteOrderAttachmentRecordByIds(ids));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 删除附件费 根据子单id
|
||||
*/
|
||||
@PostMapping( "/deleteByDetailId")
|
||||
@ResponseBody
|
||||
public AjaxResult deleteByDetailId(@RequestParam Long orderDetailId)
|
||||
{
|
||||
return toAjax(orderAttachmentRecordService.deleteOrderAttachmentRecordByOrderDetailId(orderDetailId));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
package com.ghy.web.controller.order;
|
||||
|
||||
import java.util.List;
|
||||
import com.ghy.order.domain.OrderCallRecord;
|
||||
import com.ghy.order.service.IOrderCallRecordService;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import com.ghy.common.annotation.Log;
|
||||
import com.ghy.common.enums.BusinessType;
|
||||
import com.ghy.common.core.controller.BaseController;
|
||||
import com.ghy.common.core.domain.AjaxResult;
|
||||
import com.ghy.common.utils.poi.ExcelUtil;
|
||||
import com.ghy.common.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 订单约单记录Controller
|
||||
*
|
||||
* @author clunt
|
||||
* @date 2023-06-04
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/order/record")
|
||||
public class OrderCallRecordController extends BaseController
|
||||
{
|
||||
private String prefix = "order/record";
|
||||
|
||||
@Autowired
|
||||
private IOrderCallRecordService orderCallRecordService;
|
||||
|
||||
// @RequiresPermissions("worker:record:view")
|
||||
@GetMapping()
|
||||
public String record(Long orderId, ModelMap mmap)
|
||||
{
|
||||
mmap.put("orderId", orderId);
|
||||
return prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询订单约单记录列表
|
||||
*/
|
||||
@RequiresPermissions("worker:record:list")
|
||||
@PostMapping("/list")
|
||||
@ResponseBody
|
||||
public TableDataInfo list(OrderCallRecord orderCallRecord)
|
||||
{
|
||||
startPage();
|
||||
List<OrderCallRecord> list = orderCallRecordService.selectOrderCallRecordList(orderCallRecord);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* App查询订单约单记录列表
|
||||
*/
|
||||
@PostMapping("/app/list")
|
||||
@ResponseBody
|
||||
public TableDataInfo appList(@RequestBody OrderCallRecord orderCallRecord)
|
||||
{
|
||||
startPage();
|
||||
List<OrderCallRecord> list = orderCallRecordService.selectOrderCallRecordList(orderCallRecord);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 导出订单约单记录列表
|
||||
*/
|
||||
@RequiresPermissions("worker:record:export")
|
||||
@Log(title = "订单约单记录", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
@ResponseBody
|
||||
public AjaxResult export(OrderCallRecord orderCallRecord)
|
||||
{
|
||||
List<OrderCallRecord> list = orderCallRecordService.selectOrderCallRecordList(orderCallRecord);
|
||||
ExcelUtil<OrderCallRecord> util = new ExcelUtil<OrderCallRecord>(OrderCallRecord.class);
|
||||
return util.exportExcel(list, "订单约单记录数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增订单约单记录
|
||||
*/
|
||||
@GetMapping("/add")
|
||||
public String add()
|
||||
{
|
||||
return prefix + "/add";
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增保存订单约单记录
|
||||
*/
|
||||
@RequiresPermissions("worker:record:add")
|
||||
@Log(title = "订单约单记录", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/add")
|
||||
@ResponseBody
|
||||
public AjaxResult addSave(OrderCallRecord orderCallRecord)
|
||||
{
|
||||
return toAjax(orderCallRecordService.insertOrderCallRecord(orderCallRecord));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改订单约单记录
|
||||
*/
|
||||
@RequiresPermissions("worker:record:edit")
|
||||
@GetMapping("/edit/{id}")
|
||||
public String edit(@PathVariable("id") Long id, ModelMap mmap)
|
||||
{
|
||||
OrderCallRecord orderCallRecord = orderCallRecordService.selectOrderCallRecordById(id);
|
||||
mmap.put("orderCallRecord", orderCallRecord);
|
||||
return prefix + "/edit";
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改保存订单约单记录
|
||||
*/
|
||||
@RequiresPermissions("worker:record:edit")
|
||||
@Log(title = "订单约单记录", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/edit")
|
||||
@ResponseBody
|
||||
public AjaxResult editSave(OrderCallRecord orderCallRecord)
|
||||
{
|
||||
return toAjax(orderCallRecordService.updateOrderCallRecord(orderCallRecord));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除订单约单记录
|
||||
*/
|
||||
@RequiresPermissions("worker:record:remove")
|
||||
@Log(title = "订单约单记录", businessType = BusinessType.DELETE)
|
||||
@PostMapping( "/remove")
|
||||
@ResponseBody
|
||||
public AjaxResult remove(String ids)
|
||||
{
|
||||
return toAjax(orderCallRecordService.deleteOrderCallRecordByIds(ids));
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,159 @@
|
|||
package com.ghy.web.controller.order;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.ghy.web.pojo.vo.CertNoTwoElementReq;
|
||||
import com.ghy.web.service.AliCloudService;
|
||||
import com.ghy.web.service.InsuranceService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import com.ghy.common.annotation.Log;
|
||||
import com.ghy.common.enums.BusinessType;
|
||||
import com.ghy.order.domain.OrderDetailInsuranceUser;
|
||||
import com.ghy.order.service.IOrderDetailInsuranceUserService;
|
||||
import com.ghy.common.core.controller.BaseController;
|
||||
import com.ghy.common.core.domain.AjaxResult;
|
||||
import com.ghy.common.utils.poi.ExcelUtil;
|
||||
import com.ghy.common.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 订单保险人员Controller
|
||||
*
|
||||
* @author clunt
|
||||
* @date 2024-10-21
|
||||
*/
|
||||
@Slf4j
|
||||
@Controller
|
||||
@RequestMapping("/insurance/user")
|
||||
public class OrderDetailInsuranceUserController extends BaseController
|
||||
{
|
||||
private String prefix = "insurance/user";
|
||||
|
||||
@Autowired
|
||||
private IOrderDetailInsuranceUserService orderDetailInsuranceUserService;
|
||||
|
||||
@Autowired
|
||||
private AliCloudService aliCloudService;
|
||||
|
||||
@Autowired
|
||||
private InsuranceService insuranceService;
|
||||
|
||||
@RequiresPermissions("worker:user:view")
|
||||
@GetMapping()
|
||||
public String user()
|
||||
{
|
||||
return prefix + "/user";
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询订单保险人员列表
|
||||
*/
|
||||
@PostMapping("/list")
|
||||
@ResponseBody
|
||||
public TableDataInfo list(OrderDetailInsuranceUser orderDetailInsuranceUser)
|
||||
{
|
||||
startPage();
|
||||
List<OrderDetailInsuranceUser> list = orderDetailInsuranceUserService.selectOrderDetailInsuranceUserList(orderDetailInsuranceUser);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* App查询订单保险人员列表
|
||||
*/
|
||||
@PostMapping("/app/list")
|
||||
@ResponseBody
|
||||
public TableDataInfo appList(@RequestBody OrderDetailInsuranceUser orderDetailInsuranceUser)
|
||||
{
|
||||
startPage();
|
||||
List<OrderDetailInsuranceUser> list = orderDetailInsuranceUserService.selectOrderDetailInsuranceUserList(orderDetailInsuranceUser);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 导出订单保险人员列表
|
||||
*/
|
||||
@PostMapping("/export")
|
||||
@ResponseBody
|
||||
public AjaxResult export(OrderDetailInsuranceUser orderDetailInsuranceUser)
|
||||
{
|
||||
List<OrderDetailInsuranceUser> list = orderDetailInsuranceUserService.selectOrderDetailInsuranceUserList(orderDetailInsuranceUser);
|
||||
ExcelUtil<OrderDetailInsuranceUser> util = new ExcelUtil<OrderDetailInsuranceUser>(OrderDetailInsuranceUser.class);
|
||||
return util.exportExcel(list, "订单保险人员数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增订单保险人员
|
||||
*/
|
||||
@GetMapping("/add")
|
||||
public String add()
|
||||
{
|
||||
return prefix + "/add";
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增保存订单保险人员
|
||||
*/
|
||||
@PostMapping("/add")
|
||||
@ResponseBody
|
||||
public AjaxResult addSave(@RequestBody OrderDetailInsuranceUser orderDetailInsuranceUser)
|
||||
{
|
||||
// 先校验身份证信息是否ok
|
||||
CertNoTwoElementReq req = new CertNoTwoElementReq();
|
||||
req.setCertName(orderDetailInsuranceUser.getName());
|
||||
req.setCertNo(orderDetailInsuranceUser.getIdCardNum());
|
||||
try {
|
||||
aliCloudService.certNoTwoElementVerification(req);
|
||||
} catch (Exception e) {
|
||||
log.error("身份证二要素校验失败:{}", e.getMessage(), e);
|
||||
return AjaxResult.error("请核对姓名与身份证号!");
|
||||
}
|
||||
// 将保险人员增员到原保险订单上去
|
||||
try {
|
||||
insuranceService.editInsurance(orderDetailInsuranceUser);
|
||||
orderDetailInsuranceUserService.insertOrderDetailInsuranceUser(orderDetailInsuranceUser);
|
||||
return AjaxResult.success("增员完毕,保险已生效。");
|
||||
}catch (Exception e){
|
||||
log.error("保险增员失败:{}", e.getMessage(), e);
|
||||
return AjaxResult.error("保险正生成中,可能需几秒或几分钟,请稍等即可!若超半小时可联系发单方或平台。");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改订单保险人员
|
||||
*/
|
||||
@RequiresPermissions("worker:user:edit")
|
||||
@GetMapping("/edit/{id}")
|
||||
public String edit(@PathVariable("id") Long id, ModelMap mmap)
|
||||
{
|
||||
OrderDetailInsuranceUser orderDetailInsuranceUser = orderDetailInsuranceUserService.selectOrderDetailInsuranceUserById(id);
|
||||
mmap.put("orderDetailInsuranceUser", orderDetailInsuranceUser);
|
||||
return prefix + "/edit";
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改保存订单保险人员
|
||||
*/
|
||||
@RequiresPermissions("worker:user:edit")
|
||||
@Log(title = "订单保险人员", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/edit")
|
||||
@ResponseBody
|
||||
public AjaxResult editSave(OrderDetailInsuranceUser orderDetailInsuranceUser)
|
||||
{
|
||||
return toAjax(orderDetailInsuranceUserService.updateOrderDetailInsuranceUser(orderDetailInsuranceUser));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除订单保险人员
|
||||
*/
|
||||
@PostMapping( "/remove")
|
||||
@ResponseBody
|
||||
public AjaxResult remove(String ids)
|
||||
{
|
||||
return toAjax(orderDetailInsuranceUserService.deleteOrderDetailInsuranceUserByIds(ids));
|
||||
}
|
||||
}
|
||||
|
|
@ -35,14 +35,23 @@ public class OrderGoodsController extends BaseController {
|
|||
@Resource
|
||||
private OrderMasterService orderMasterService;
|
||||
|
||||
@RequiresPermissions("order:goods:view")
|
||||
// @RequiresPermissions("order:goods:view")
|
||||
@GetMapping()
|
||||
public String orderGoods(Long orderId, ModelMap mmap) {
|
||||
OrderMaster orderMaster = orderMasterService.selectById(orderId);
|
||||
mmap.put("orderId", orderId);
|
||||
mmap.put("orderMaster", orderMaster);
|
||||
return prefix;
|
||||
}
|
||||
|
||||
@GetMapping(value = "/master")
|
||||
public String orderMasterGoods(Long orderId, ModelMap mmap) {
|
||||
OrderMaster orderMaster = orderMasterService.selectById(orderId);
|
||||
mmap.put("orderId", orderId);
|
||||
mmap.put("orderMaster", orderMaster);
|
||||
return "order/masterGoods";
|
||||
}
|
||||
|
||||
// @RequiresPermissions("order:goods:list")
|
||||
@PostMapping("/list")
|
||||
@ResponseBody
|
||||
|
|
@ -53,7 +62,7 @@ public class OrderGoodsController extends BaseController {
|
|||
}
|
||||
|
||||
@Log(title = "主订单管理", businessType = BusinessType.EXPORT)
|
||||
@RequiresPermissions("order:goods:export")
|
||||
// @RequiresPermissions("order:goods:export")
|
||||
@PostMapping("/export")
|
||||
@ResponseBody
|
||||
public AjaxResult export(OrderGoods orderGoods) {
|
||||
|
|
@ -62,7 +71,7 @@ public class OrderGoodsController extends BaseController {
|
|||
return util.exportExcel(list, "主订单数据");
|
||||
}
|
||||
|
||||
@RequiresPermissions("order:goods:remove")
|
||||
// @RequiresPermissions("order:goods:remove")
|
||||
@Log(title = "主订单管理", businessType = BusinessType.DELETE)
|
||||
@PostMapping("/remove")
|
||||
@ResponseBody
|
||||
|
|
@ -78,7 +87,7 @@ public class OrderGoodsController extends BaseController {
|
|||
/**
|
||||
* 修改主订单
|
||||
*/
|
||||
@RequiresPermissions("order:goods:edit")
|
||||
// @RequiresPermissions("order:goods:edit")
|
||||
@GetMapping("/edit/{orderGoodsId}")
|
||||
public String edit(@PathVariable("orderGoodsId") Long orderGoodsId, ModelMap mmap) {
|
||||
mmap.put("orderGoods", orderGoodsService.selectById(orderGoodsId));
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,152 @@
|
|||
package com.ghy.web.controller.order;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import com.ghy.common.annotation.Log;
|
||||
import com.ghy.common.enums.BusinessType;
|
||||
import com.ghy.order.domain.OrderOperationRecord;
|
||||
import com.ghy.order.service.IOrderOperationRecordService;
|
||||
import com.ghy.common.core.controller.BaseController;
|
||||
import com.ghy.common.core.domain.AjaxResult;
|
||||
import com.ghy.common.utils.poi.ExcelUtil;
|
||||
import com.ghy.common.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 订单操作记录Controller
|
||||
*
|
||||
* @author clunt
|
||||
* @date 2024-02-17
|
||||
*/
|
||||
@Api
|
||||
@Controller
|
||||
@RequestMapping("/order/operate")
|
||||
public class OrderOperationRecordController extends BaseController
|
||||
{
|
||||
private String prefix = "order/operate";
|
||||
|
||||
@Autowired
|
||||
private IOrderOperationRecordService orderOperationRecordService;
|
||||
|
||||
@RequiresPermissions("order:operate:view")
|
||||
@GetMapping()
|
||||
public String record()
|
||||
{
|
||||
return prefix + "/operate";
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询订单操作记录列表
|
||||
*/
|
||||
@RequiresPermissions("order:operate:list")
|
||||
@PostMapping("/list")
|
||||
@ResponseBody
|
||||
public TableDataInfo list(OrderOperationRecord orderOperationRecord)
|
||||
{
|
||||
startPage();
|
||||
List<OrderOperationRecord> list = orderOperationRecordService.selectOrderOperationRecordList(orderOperationRecord);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* App查询订单操作记录列表
|
||||
*/
|
||||
@ApiOperation("订单操作记录列表")
|
||||
@PostMapping("/app/list")
|
||||
@ResponseBody
|
||||
public TableDataInfo appList(@RequestBody OrderOperationRecord orderOperationRecord)
|
||||
{
|
||||
startPage();
|
||||
List<OrderOperationRecord> list = orderOperationRecordService.selectOrderOperationRecordList(orderOperationRecord);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增保存订单操作记录
|
||||
*/
|
||||
@ApiOperation("新增订单操作记录")
|
||||
@PostMapping("/app/add")
|
||||
@ResponseBody
|
||||
public AjaxResult appAdd(@RequestBody OrderOperationRecord orderOperationRecord)
|
||||
{
|
||||
return toAjax(orderOperationRecordService.insertOrderOperationRecord(orderOperationRecord));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 导出订单操作记录列表
|
||||
*/
|
||||
@RequiresPermissions("order:operate:export")
|
||||
@Log(title = "订单操作记录", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
@ResponseBody
|
||||
public AjaxResult export(OrderOperationRecord orderOperationRecord)
|
||||
{
|
||||
List<OrderOperationRecord> list = orderOperationRecordService.selectOrderOperationRecordList(orderOperationRecord);
|
||||
ExcelUtil<OrderOperationRecord> util = new ExcelUtil<OrderOperationRecord>(OrderOperationRecord.class);
|
||||
return util.exportExcel(list, "订单操作记录数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增订单操作记录
|
||||
*/
|
||||
@GetMapping("/add")
|
||||
public String add()
|
||||
{
|
||||
return prefix + "/add";
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增保存订单操作记录
|
||||
*/
|
||||
@RequiresPermissions("order:operate:add")
|
||||
@Log(title = "订单操作记录", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/add")
|
||||
@ResponseBody
|
||||
public AjaxResult addSave(OrderOperationRecord orderOperationRecord)
|
||||
{
|
||||
return toAjax(orderOperationRecordService.insertOrderOperationRecord(orderOperationRecord));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改订单操作记录
|
||||
*/
|
||||
@RequiresPermissions("order:operate:edit")
|
||||
@GetMapping("/edit/{id}")
|
||||
public String edit(@PathVariable("id") Long id, ModelMap mmap)
|
||||
{
|
||||
OrderOperationRecord orderOperationRecord = orderOperationRecordService.selectOrderOperationRecordById(id);
|
||||
mmap.put("orderOperationRecord", orderOperationRecord);
|
||||
return prefix + "/edit";
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改保存订单操作记录
|
||||
*/
|
||||
@RequiresPermissions("order:operate:edit")
|
||||
@Log(title = "订单操作记录", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/edit")
|
||||
@ResponseBody
|
||||
public AjaxResult editSave(OrderOperationRecord orderOperationRecord)
|
||||
{
|
||||
return toAjax(orderOperationRecordService.updateOrderOperationRecord(orderOperationRecord));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除订单操作记录
|
||||
*/
|
||||
@RequiresPermissions("order:operate:remove")
|
||||
@Log(title = "订单操作记录", businessType = BusinessType.DELETE)
|
||||
@PostMapping( "/remove")
|
||||
@ResponseBody
|
||||
public AjaxResult remove(String ids)
|
||||
{
|
||||
return toAjax(orderOperationRecordService.deleteOrderOperationRecordByIds(ids));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,202 @@
|
|||
package com.ghy.web.controller.order;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.ghy.common.enums.WxMsgEnum;
|
||||
import com.ghy.common.utils.WechatMsgUtils;
|
||||
import com.ghy.customer.domain.Customer;
|
||||
import com.ghy.customer.service.CustomerService;
|
||||
import com.ghy.order.domain.OrderDetail;
|
||||
import com.ghy.order.domain.OrderMaster;
|
||||
import com.ghy.order.service.OrderDetailService;
|
||||
import com.ghy.order.service.OrderMasterService;
|
||||
import com.ghy.worker.domain.Worker;
|
||||
import com.ghy.worker.service.WorkerService;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import com.ghy.common.annotation.Log;
|
||||
import com.ghy.common.enums.BusinessType;
|
||||
import com.ghy.order.domain.OrderWarnRecord;
|
||||
import com.ghy.order.service.IOrderWarnRecordService;
|
||||
import com.ghy.common.core.controller.BaseController;
|
||||
import com.ghy.common.core.domain.AjaxResult;
|
||||
import com.ghy.common.utils.poi.ExcelUtil;
|
||||
import com.ghy.common.core.page.TableDataInfo;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 订单急报记录Controller
|
||||
*
|
||||
* @author clunt
|
||||
* @date 2024-02-18
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/warn/record")
|
||||
public class OrderWarnRecordController extends BaseController
|
||||
{
|
||||
private String prefix = "warn/record";
|
||||
|
||||
@Autowired
|
||||
private IOrderWarnRecordService orderWarnRecordService;
|
||||
|
||||
@Resource
|
||||
private OrderMasterService orderMasterService;
|
||||
|
||||
@Resource
|
||||
private OrderDetailService orderDetailService;
|
||||
|
||||
@Resource
|
||||
private WorkerService workerService;
|
||||
|
||||
@Resource
|
||||
private CustomerService customerService;
|
||||
|
||||
@RequiresPermissions("warn:record:view")
|
||||
@GetMapping()
|
||||
public String record()
|
||||
{
|
||||
return prefix + "/record";
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询订单急报记录列表
|
||||
*/
|
||||
@RequiresPermissions("warn:record:list")
|
||||
@PostMapping("/list")
|
||||
@ResponseBody
|
||||
public TableDataInfo list(OrderWarnRecord orderWarnRecord)
|
||||
{
|
||||
startPage();
|
||||
List<OrderWarnRecord> list = orderWarnRecordService.selectOrderWarnRecordList(orderWarnRecord);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* App查询订单急报记录列表
|
||||
*/
|
||||
@ApiOperation("急报操作记录列表")
|
||||
@PostMapping("/app/list")
|
||||
@ResponseBody
|
||||
public TableDataInfo appList(@RequestBody OrderWarnRecord orderWarnRecord)
|
||||
{
|
||||
startPage();
|
||||
List<OrderWarnRecord> list = orderWarnRecordService.selectOrderWarnRecordList(orderWarnRecord);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@ApiOperation("新增急报记录(约单/催单)")
|
||||
@PostMapping("/app/add")
|
||||
@ResponseBody
|
||||
public AjaxResult appAdd(@RequestBody OrderWarnRecord orderWarnRecord)
|
||||
{
|
||||
Worker worker;
|
||||
Customer customer;
|
||||
if("01".equals(orderWarnRecord.getOrderType())){
|
||||
OrderMaster orderMaster = orderMasterService.selectById(orderWarnRecord.getOrderId());
|
||||
worker = workerService.selectById(orderMaster.getWorkerId());
|
||||
customer = customerService.selectByCustomerId(orderMaster.getCustomerId());
|
||||
}else {
|
||||
OrderDetail orderDetail = orderDetailService.selectById(orderWarnRecord.getOrderId());
|
||||
worker = workerService.selectById(orderDetail.getWorkerId());
|
||||
customer = customerService.selectByCustomerId(orderDetail.getCustomerId());
|
||||
}
|
||||
// 发送急报
|
||||
// 推送公众号通知数据。
|
||||
try {
|
||||
// 消息组装。
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
// 订单编号
|
||||
params.put("thing3", customer.getName());
|
||||
// 名称
|
||||
params.put("thing2", orderWarnRecord.getContent());
|
||||
// 反馈时间
|
||||
params.put("time6", com.ghy.common.utils.DateUtils.parseDateToStr("yyyy年MM月dd日 HH:mm", new Date()));
|
||||
// 消息推送
|
||||
WechatMsgUtils.sendWeChatMsg(WechatMsgUtils.getToken(), worker.getWxOpenId(), WxMsgEnum.WARN_ORDER, params);
|
||||
} catch (Exception e) {
|
||||
// 暂时不做任何操作。
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
return toAjax(orderWarnRecordService.insertOrderWarnRecord(orderWarnRecord));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 导出订单急报记录列表
|
||||
*/
|
||||
@RequiresPermissions("warn:record:export")
|
||||
@Log(title = "订单急报记录", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
@ResponseBody
|
||||
public AjaxResult export(OrderWarnRecord orderWarnRecord)
|
||||
{
|
||||
List<OrderWarnRecord> list = orderWarnRecordService.selectOrderWarnRecordList(orderWarnRecord);
|
||||
ExcelUtil<OrderWarnRecord> util = new ExcelUtil<OrderWarnRecord>(OrderWarnRecord.class);
|
||||
return util.exportExcel(list, "订单急报记录数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增订单急报记录
|
||||
*/
|
||||
@GetMapping("/add")
|
||||
public String add()
|
||||
{
|
||||
return prefix + "/add";
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增保存订单急报记录
|
||||
*/
|
||||
@RequiresPermissions("warn:record:add")
|
||||
@Log(title = "订单急报记录", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/add")
|
||||
@ResponseBody
|
||||
public AjaxResult addSave(OrderWarnRecord orderWarnRecord)
|
||||
{
|
||||
return toAjax(orderWarnRecordService.insertOrderWarnRecord(orderWarnRecord));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改订单急报记录
|
||||
*/
|
||||
@RequiresPermissions("warn:record:edit")
|
||||
@GetMapping("/edit/{id}")
|
||||
public String edit(@PathVariable("id") Long id, ModelMap mmap)
|
||||
{
|
||||
OrderWarnRecord orderWarnRecord = orderWarnRecordService.selectOrderWarnRecordById(id);
|
||||
mmap.put("orderWarnRecord", orderWarnRecord);
|
||||
return prefix + "/edit";
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改保存订单急报记录
|
||||
*/
|
||||
@RequiresPermissions("warn:record:edit")
|
||||
@Log(title = "订单急报记录", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/edit")
|
||||
@ResponseBody
|
||||
public AjaxResult editSave(OrderWarnRecord orderWarnRecord)
|
||||
{
|
||||
return toAjax(orderWarnRecordService.updateOrderWarnRecord(orderWarnRecord));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除订单急报记录
|
||||
*/
|
||||
@RequiresPermissions("warn:record:remove")
|
||||
@Log(title = "订单急报记录", businessType = BusinessType.DELETE)
|
||||
@PostMapping( "/remove")
|
||||
@ResponseBody
|
||||
public AjaxResult remove(String ids)
|
||||
{
|
||||
return toAjax(orderWarnRecordService.deleteOrderWarnRecordByIds(ids));
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,9 @@ import com.huifu.adapay.core.AdapayCore;
|
|||
import com.huifu.adapay.core.util.AdapaySign;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
|
|
@ -72,6 +74,12 @@ public class AdapayCallbackController extends BaseController {
|
|||
return "NG";
|
||||
}
|
||||
|
||||
@GetMapping("/adapay/callback")
|
||||
@ResponseBody
|
||||
public String test() {
|
||||
return "NG";
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验签名
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.ghy.web.controller.pay;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.ghy.common.adapay.model.AdapayStatusEnum;
|
||||
import com.ghy.common.adapay.model.PayParam;
|
||||
|
|
@ -7,15 +8,20 @@ import com.ghy.common.core.controller.BaseController;
|
|||
import com.ghy.common.core.domain.AjaxResult;
|
||||
import com.ghy.common.enums.PayStatus;
|
||||
import com.ghy.common.enums.PayTypeEnum;
|
||||
import com.ghy.common.utils.MoneyUtil;
|
||||
import com.ghy.order.domain.OrderAttachmentRecord;
|
||||
import com.ghy.order.domain.OrderDetail;
|
||||
import com.ghy.order.domain.OrderMaster;
|
||||
import com.ghy.order.service.IOrderAttachmentRecordService;
|
||||
import com.ghy.order.service.OrderDetailService;
|
||||
import com.ghy.order.service.OrderMasterService;
|
||||
import com.ghy.payment.domain.FinancialChangeRecord;
|
||||
import com.ghy.payment.domain.FinancialMaster;
|
||||
import com.ghy.payment.domain.PaymentRelation;
|
||||
import com.ghy.payment.service.AdapayService;
|
||||
import com.ghy.payment.service.FinancialChangeRecordService;
|
||||
import com.ghy.payment.service.FinancialMasterService;
|
||||
import com.ghy.payment.service.IPaymentRelationService;
|
||||
import com.huifu.adapay.core.exception.BaseAdaPayException;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
|
@ -24,7 +30,9 @@ import org.springframework.web.bind.annotation.RestController;
|
|||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Map;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
|
|
@ -40,14 +48,17 @@ public class AlipayController extends BaseController {
|
|||
private AdapayService adapayService;
|
||||
@Resource
|
||||
private OrderMasterService orderMasterService;
|
||||
@Resource
|
||||
private FinancialMasterService financialMasterService;
|
||||
|
||||
@Resource
|
||||
private OrderDetailService orderDetailService;
|
||||
|
||||
@Resource
|
||||
private FinancialMasterService financialMasterService;
|
||||
@Resource
|
||||
private IPaymentRelationService paymentRelationService;
|
||||
@Resource
|
||||
private FinancialChangeRecordService financialChangeRecordService;
|
||||
@Resource
|
||||
private IOrderAttachmentRecordService orderAttachmentRecordService;
|
||||
|
||||
|
||||
/**
|
||||
* 支付宝正扫支付
|
||||
|
|
@ -62,17 +73,104 @@ public class AlipayController extends BaseController {
|
|||
if (om.getPayStatus() == 1 || fm.getPayStatus() == 1) {
|
||||
return AjaxResult.error("订单已支付,不要重复付款!");
|
||||
}
|
||||
Map<String, Object> map;
|
||||
String payMoney = fm.getPayMoney().setScale(2, BigDecimal.ROUND_UNNECESSARY).toString();
|
||||
String payMoney = MoneyUtil.toS(fm.getPayMoney());
|
||||
// TODO 这里需要补充商品标题和商品描述信息
|
||||
PayParam payParam = PayParam.delayPayParam(om.getCode() + "_" + System.currentTimeMillis(), payMoney, "商品标题", "商品描述信息");
|
||||
try {
|
||||
map = adapayService.alipayQrPay(om.getDeptId(), payParam, null, null, null);
|
||||
JSONObject response = adapayService.alipayQrPay(om.getDeptId(), payParam, null, null, null);
|
||||
boolean status = AdapayStatusEnum.succeeded.code.equals(response.getString("status"));
|
||||
if (!status) {
|
||||
logger.error("创建支付失败: {}", response.toJSONString());
|
||||
return AjaxResult.error("网络不佳 请稍后再试");
|
||||
}
|
||||
// 支付二维码创建成功 保存一下paymentId
|
||||
String paymentId = response.getString("id");
|
||||
// 更新财务主单的paymentId
|
||||
FinancialMaster fm2update = new FinancialMaster();
|
||||
fm2update.setId(fm.getId());
|
||||
fm2update.setPaymentId(paymentId);
|
||||
fm2update.setPayType(PayTypeEnum.ALIPAY_QR.getCode());
|
||||
financialMasterService.updateFinancialMaster(fm2update);
|
||||
// 保存支付ID与主财务单ID到关系表
|
||||
PaymentRelation relation = new PaymentRelation(null, fm.getId(), PaymentRelation.FINANCIAL_MASTER, fm.getPayMoney());
|
||||
relation.setPaymentId(paymentId);
|
||||
paymentRelationService.insert(relation);
|
||||
return AjaxResult.success(response);
|
||||
} catch (BaseAdaPayException e) {
|
||||
logger.error("创建支付失败", e);
|
||||
return AjaxResult.error("网络不佳 请稍后再试");
|
||||
}
|
||||
return AjaxResult.success(map);
|
||||
}
|
||||
|
||||
@PostMapping("/addMasterQr")
|
||||
public AjaxResult addMasterQrPay(@RequestBody String orderId) {
|
||||
orderId = orderId.replace("\"", "");
|
||||
String [] orderIds = orderId.split(",");
|
||||
List<String> orderIdList = Arrays.asList(orderIds);
|
||||
ArrayList<PaymentRelation> relations = new ArrayList<>();
|
||||
List<Long> fmList = new ArrayList<>();
|
||||
BigDecimal payMoney = BigDecimal.ZERO;
|
||||
for (String id : orderIdList){
|
||||
// 不知道为啥参数可能会带上双引号 这里去掉再转Long
|
||||
Long orderMasterId = Long.valueOf(id);
|
||||
OrderMaster orderMaster = orderMasterService.selectById(orderMasterId);
|
||||
if (orderMaster == null) {
|
||||
return AjaxResult.error("主订单不存在!");
|
||||
}
|
||||
// 查询主单是否有未支付的付款单
|
||||
FinancialMaster fm = financialMasterService.selectByOrderMasterId(orderMaster.getId());
|
||||
if (fm == null) {
|
||||
return AjaxResult.error("财务单不存在!");
|
||||
}
|
||||
// 主单是否付款 没付款的话一起付
|
||||
boolean fmPaid = Objects.equals(PayStatus.WAIT_PAY.getCode(), fm.getPayStatus());
|
||||
if (fmPaid) {
|
||||
fmList.add(fm.getId());
|
||||
payMoney = payMoney.add(fm.getPayMoney());
|
||||
relations.add(new PaymentRelation(null, fm.getId(), PaymentRelation.FINANCIAL_MASTER, fm.getPayMoney()));
|
||||
}else {
|
||||
return AjaxResult.error("选择了不需要付款的订单!");
|
||||
}
|
||||
|
||||
if (MoneyUtil.lte0(payMoney)) {
|
||||
return AjaxResult.error("不需要支付");
|
||||
}
|
||||
|
||||
}
|
||||
// 以第一单为第三放的付款单号
|
||||
OrderMaster orderMaster = orderMasterService.selectById(Long.valueOf(orderIdList.get(0)));
|
||||
// 付款
|
||||
PayParam payParam = PayParam.delayPayParam(orderMaster.getCode() + "_" + System.currentTimeMillis(),
|
||||
MoneyUtil.toS(payMoney), "订单支付", "叮咚到家服务");
|
||||
|
||||
JSONObject response;
|
||||
try {
|
||||
response = adapayService.alipayQrPay(orderMaster.getDeptId(), payParam, null, null, null);
|
||||
} catch (BaseAdaPayException e) {
|
||||
logger.error("创建支付失败: " + e.getMessage(), e);
|
||||
return AjaxResult.error("网络不佳 请稍后再试");
|
||||
}
|
||||
boolean status = AdapayStatusEnum.succeeded.code.equals(response.getString("status"));
|
||||
if (!status) {
|
||||
logger.error("创建支付失败: {}", response.toJSONString());
|
||||
return AjaxResult.error("网络不佳 请稍后再试");
|
||||
}
|
||||
// 支付二维码创建成功 保存一下paymentId
|
||||
String paymentId = response.getString("id");
|
||||
for (Long id : fmList){
|
||||
FinancialMaster fm2update = new FinancialMaster();
|
||||
fm2update.setId(id);
|
||||
fm2update.setPaymentId(paymentId);
|
||||
fm2update.setPayType(PayTypeEnum.ALIPAY_QR.getCode());
|
||||
financialMasterService.updateFinancialMaster(fm2update);
|
||||
}
|
||||
// 保存支付ID与订单ID到关系表
|
||||
for (PaymentRelation relation : relations) {
|
||||
relation.setPaymentId(paymentId);
|
||||
paymentRelationService.insert(relation);
|
||||
}
|
||||
|
||||
return AjaxResult.success(response);
|
||||
}
|
||||
|
||||
@PostMapping("/addQr")
|
||||
|
|
@ -92,29 +190,41 @@ public class AlipayController extends BaseController {
|
|||
if (fm == null) {
|
||||
return AjaxResult.error("财务单不存在!");
|
||||
}
|
||||
ArrayList<PaymentRelation> relations = new ArrayList<>();
|
||||
// 主单是否付款 没付款的话一起付
|
||||
boolean fmPaid = Objects.equals(PayStatus.WAIT_PAY.getCode(), fm.getPayStatus());
|
||||
if (fmPaid) {
|
||||
if (fmPaid && !"01".equals(orderMaster.getConsultMode())) {
|
||||
payMoney = payMoney.add(fm.getPayMoney());
|
||||
relations.add(new PaymentRelation(null, fm.getId(), PaymentRelation.FINANCIAL_MASTER, fm.getPayMoney()));
|
||||
}
|
||||
// 查询关联的加价单
|
||||
FinancialChangeRecord financialChangeRecord = financialChangeRecordService.selectNotPayRecordByDetailId(orderDetailId);
|
||||
if (financialChangeRecord != null) {
|
||||
payMoney = payMoney.add(financialChangeRecord.getChangeMoney());
|
||||
FinancialChangeRecord fcr = financialChangeRecordService.selectNotPayRecordByDetailId(orderDetailId);
|
||||
if (fcr != null && !"01".equals(orderMaster.getConsultMode())) {
|
||||
payMoney = payMoney.add(fcr.getChangeMoney());
|
||||
relations.add(new PaymentRelation(null, fcr.getId(), PaymentRelation.FINANCIAL_CHANGE, fcr.getChangeMoney()));
|
||||
}else if(fcr != null){
|
||||
payMoney = payMoney.add(fcr.getChangeMoney());
|
||||
relations.add(new PaymentRelation(null, fcr.getId(), PaymentRelation.CONSULT_ADD, fcr.getChangeMoney()));
|
||||
}
|
||||
|
||||
if (BigDecimal.ZERO.compareTo(payMoney) > -1) {
|
||||
OrderAttachmentRecord param = new OrderAttachmentRecord();
|
||||
param.setOrderDetailId(orderDetailId);
|
||||
List<OrderAttachmentRecord> orderAttachmentRecordList = orderAttachmentRecordService.selectOrderAttachmentRecordList(param);
|
||||
if(CollectionUtil.isNotEmpty(orderAttachmentRecordList)){
|
||||
payMoney = payMoney.add(orderAttachmentRecordList.get(0).getAttachMoney());
|
||||
relations.add(new PaymentRelation(null, orderAttachmentRecordList.get(0).getId(), PaymentRelation.ORDER_ATTACHMENT, orderAttachmentRecordList.get(0).getAttachMoney()));
|
||||
}
|
||||
if (MoneyUtil.lte0(payMoney)) {
|
||||
return AjaxResult.error("不需要支付");
|
||||
}
|
||||
|
||||
// 付款
|
||||
PayParam payParam;
|
||||
if (financialChangeRecord == null) {
|
||||
if (fcr == null) {
|
||||
payParam = PayParam.delayPayParam(orderMaster.getCode() + "_" + System.currentTimeMillis(),
|
||||
payMoney.setScale(2, BigDecimal.ROUND_UNNECESSARY).toString(),
|
||||
"订单支付", "叮咚到家服务");
|
||||
} else {
|
||||
payParam = PayParam.delayPayParam(orderMaster.getCode() + "_" + financialChangeRecord.getId() + "_" + System.currentTimeMillis(),
|
||||
payParam = PayParam.delayPayParam(orderMaster.getCode() + "_" + fcr.getId() + "_" + System.currentTimeMillis(),
|
||||
payMoney.setScale(2, BigDecimal.ROUND_UNNECESSARY).toString(),
|
||||
"加价付款", "叮咚到家服务");
|
||||
}
|
||||
|
|
@ -140,12 +250,23 @@ public class AlipayController extends BaseController {
|
|||
fm2update.setPayType(PayTypeEnum.ALIPAY_QR.getCode());
|
||||
financialMasterService.updateFinancialMaster(fm2update);
|
||||
}
|
||||
if (financialChangeRecord != null) {
|
||||
if (fcr != null) {
|
||||
FinancialChangeRecord fcr2update = new FinancialChangeRecord();
|
||||
fcr2update.setId(financialChangeRecord.getId());
|
||||
fcr2update.setId(fcr.getId());
|
||||
fcr2update.setPaymentId(paymentId);
|
||||
financialChangeRecordService.update(fcr2update);
|
||||
}
|
||||
if(CollectionUtil.isNotEmpty(orderAttachmentRecordList)){
|
||||
OrderAttachmentRecord oarUpdate = new OrderAttachmentRecord();
|
||||
oarUpdate.setId(orderAttachmentRecordList.get(0).getId());
|
||||
oarUpdate.setPaymentId(paymentId);
|
||||
orderAttachmentRecordService.updateOrderAttachmentRecord(oarUpdate);
|
||||
}
|
||||
// 保存支付ID与订单ID到关系表
|
||||
for (PaymentRelation relation : relations) {
|
||||
relation.setPaymentId(paymentId);
|
||||
paymentRelationService.insert(relation);
|
||||
}
|
||||
return AjaxResult.success(response);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
package com.ghy.web.controller.pay;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.ghy.common.adapay.model.PayParam;
|
||||
import com.ghy.common.adapay.model.WxpayExpend;
|
||||
import com.ghy.common.config.WxConfig;
|
||||
import com.ghy.common.core.controller.BaseController;
|
||||
import com.ghy.common.core.domain.AjaxResult;
|
||||
import com.ghy.common.enums.PayStatus;
|
||||
import com.ghy.common.json.JSONObject;
|
||||
import com.ghy.common.utils.StringUtils;
|
||||
import com.ghy.order.domain.OrderDetail;
|
||||
import com.ghy.order.domain.OrderMaster;
|
||||
|
|
@ -14,9 +14,11 @@ import com.ghy.order.service.OrderDetailService;
|
|||
import com.ghy.order.service.OrderMasterService;
|
||||
import com.ghy.payment.domain.FinancialChangeRecord;
|
||||
import com.ghy.payment.domain.FinancialMaster;
|
||||
import com.ghy.payment.domain.PaymentRelation;
|
||||
import com.ghy.payment.service.AdapayService;
|
||||
import com.ghy.payment.service.FinancialChangeRecordService;
|
||||
import com.ghy.payment.service.FinancialMasterService;
|
||||
import com.ghy.payment.service.IPaymentRelationService;
|
||||
import com.huifu.adapay.core.exception.BaseAdaPayException;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.util.Assert;
|
||||
|
|
@ -30,7 +32,6 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Controller
|
||||
|
|
@ -47,7 +48,8 @@ public class WxPayController extends BaseController {
|
|||
private FinancialMasterService financialMasterService;
|
||||
@Resource
|
||||
private OrderDetailService orderDetailService;
|
||||
|
||||
@Resource
|
||||
private IPaymentRelationService paymentRelationService;
|
||||
@Resource
|
||||
private FinancialChangeRecordService financialChangeRecordService;
|
||||
|
||||
|
|
@ -56,11 +58,11 @@ public class WxPayController extends BaseController {
|
|||
public AjaxResult drawCash(@RequestBody JSONObject object) {
|
||||
try {
|
||||
Long deptId = object.getLong("deptId");
|
||||
String orderNo = object.getStr("orderNo");
|
||||
String cashType = object.getStr("cashType");
|
||||
String cashAmt = object.getStr("cashAmt");
|
||||
String memberId = object.getStr("memberId");
|
||||
String remark = object.getStr("remark");
|
||||
String orderNo = object.getString("orderNo");
|
||||
String cashType = object.getString("cashType");
|
||||
String cashAmt = object.getString("cashAmt");
|
||||
String memberId = object.getString("memberId");
|
||||
String remark = object.getString("remark");
|
||||
adapayService.drawCash(deptId, orderNo, cashType, cashAmt, memberId, remark, null);
|
||||
return AjaxResult.success("操作成功");
|
||||
} catch (Exception e) {
|
||||
|
|
@ -80,33 +82,60 @@ public class WxPayController extends BaseController {
|
|||
Assert.notNull(orderMaster, "找不到对应的订单");
|
||||
FinancialMaster financialMaster = financialMasterService.selectByOrderMasterId(orderMaster.getId());
|
||||
BigDecimal payMoney = BigDecimal.ZERO;
|
||||
if(PayStatus.WAIT_PAY.getCode().equals(financialMaster.getPayStatus())){
|
||||
ArrayList<PaymentRelation> relations = new ArrayList<>();
|
||||
if (PayStatus.WAIT_PAY.getCode().equals(financialMaster.getPayStatus())) {
|
||||
payMoney = financialMaster.getPayMoney();
|
||||
relations.add(new PaymentRelation(null, financialMaster.getId(), PaymentRelation.FINANCIAL_MASTER, financialMaster.getPayMoney()));
|
||||
}
|
||||
List<Long> idList = orderDetailService.selectByOrderMasterId(orderMaster.getId()).stream().map(OrderDetail::getId).collect(Collectors.toList());
|
||||
List<FinancialChangeRecord> financialChangeRecords = financialChangeRecordService.selectByDetailIds(StringUtils.join(idList, ","));
|
||||
List<Long> financialChangeRecordIds = new ArrayList<>();
|
||||
for (FinancialChangeRecord financialChangeRecord : financialChangeRecords) {
|
||||
if (PayStatus.WAIT_PAY.getCode().equals(financialChangeRecord.getPayStatus())) {
|
||||
payMoney = payMoney.add(financialChangeRecord.getChangeMoney());
|
||||
financialChangeRecordIds.add(financialChangeRecord.getId());
|
||||
for (FinancialChangeRecord fcr : financialChangeRecords) {
|
||||
if (PayStatus.WAIT_PAY.getCode().equals(fcr.getPayStatus())) {
|
||||
payMoney = payMoney.add(fcr.getChangeMoney());
|
||||
financialChangeRecordIds.add(fcr.getId());
|
||||
relations.add(new PaymentRelation(null, fcr.getId(), PaymentRelation.FINANCIAL_CHANGE, fcr.getChangeMoney()));
|
||||
}
|
||||
}
|
||||
//调用adapay微信公众号支付.
|
||||
WxpayExpend expend = new WxpayExpend();
|
||||
expend.setOpenId(openId);
|
||||
Map<String, Object> map;
|
||||
try {
|
||||
// TODO 订单里需要补充支付金额、tittle、简要描述、分账信息、description
|
||||
String changeRecordIdStr = financialChangeRecordIds.size() > 0 ? StringUtils.join(financialChangeRecordIds, ",") + "_" : "";
|
||||
PayParam payParam = PayParam.delayPayParam(orderMaster.getCode() + "_" + changeRecordIdStr + System.currentTimeMillis(),
|
||||
String.valueOf(payMoney), "工圈子居家设备", "工圈子居家设备购买付费");
|
||||
map = adapayService.wxLitePay(orderMaster.getDeptId(), payParam, expend, null, null);
|
||||
JSONObject response = adapayService.wxLitePay(orderMaster.getDeptId(), payParam, expend, null, null);
|
||||
String paymentId = response.getString("id");
|
||||
|
||||
// 更新财务主单的paymentId
|
||||
if (PayStatus.WAIT_PAY.getCode().equals(financialMaster.getPayStatus())) {
|
||||
FinancialMaster fm2update = new FinancialMaster();
|
||||
fm2update.setId(financialMaster.getId());
|
||||
fm2update.setPaymentId(paymentId);
|
||||
financialMasterService.updateFinancialMaster(fm2update);
|
||||
}
|
||||
|
||||
// 更新财务变更记录的paymentId
|
||||
for (FinancialChangeRecord fcr : financialChangeRecords) {
|
||||
if (PayStatus.WAIT_PAY.getCode().equals(fcr.getPayStatus())) {
|
||||
FinancialChangeRecord fcr2update = new FinancialChangeRecord();
|
||||
fcr2update.setId(fcr.getId());
|
||||
fcr2update.setPaymentId(paymentId);
|
||||
financialChangeRecordService.update(fcr2update);
|
||||
}
|
||||
}
|
||||
|
||||
// 保存支付ID与订单ID到关系表
|
||||
for (PaymentRelation relation : relations) {
|
||||
relation.setPaymentId(paymentId);
|
||||
paymentRelationService.insert(relation);
|
||||
}
|
||||
return AjaxResult.success(response);
|
||||
} catch (BaseAdaPayException e) {
|
||||
logger.error("获取微信用户信息失败", e);
|
||||
return AjaxResult.error();
|
||||
}
|
||||
return AjaxResult.success(map);
|
||||
}
|
||||
|
||||
// /**
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import com.ghy.common.enums.BusinessType;
|
|||
import com.ghy.common.utils.ExceptionUtil;
|
||||
import com.ghy.common.utils.poi.ExcelUtil;
|
||||
import com.ghy.payment.domain.FinancialDetail;
|
||||
import com.ghy.payment.request.FinancialAccountBillReq;
|
||||
import com.ghy.payment.response.FinancialAccountBillResp;
|
||||
import com.ghy.payment.service.FinancialDetailService;
|
||||
import com.ghy.web.pojo.vo.FinancialCountRequest;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
|
|
@ -68,6 +70,14 @@ public class FinancialDetailController extends BaseController {
|
|||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@PostMapping("/app/listV2")
|
||||
@ResponseBody
|
||||
public TableDataInfo appListV2(@RequestBody FinancialAccountBillReq financialAccountBillReq) {
|
||||
startPage();
|
||||
List<FinancialAccountBillResp> list = financialDetailService.selectFinancialDetailListV2(financialAccountBillReq);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@Log(title = "财务细单管理", businessType = BusinessType.EXPORT)
|
||||
@RequiresPermissions("financial:detail:export")
|
||||
@PostMapping("/export")
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import com.ghy.common.constant.UserConstants;
|
|||
import com.ghy.common.core.controller.BaseController;
|
||||
import com.ghy.common.core.domain.AjaxResult;
|
||||
import com.ghy.common.enums.BusinessType;
|
||||
import com.ghy.common.json.JSONObject;
|
||||
import com.ghy.common.utils.ExceptionUtil;
|
||||
import com.ghy.system.domain.SysArea;
|
||||
import com.ghy.system.service.ISysAreaService;
|
||||
|
|
@ -15,6 +16,7 @@ import org.springframework.validation.annotation.Validated;
|
|||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
|
@ -45,6 +47,43 @@ public class SysAreaController extends BaseController {
|
|||
|
||||
}
|
||||
|
||||
@PostMapping("/app/all")
|
||||
@ResponseBody
|
||||
public Object appAll(@RequestBody SysArea sysArea)
|
||||
{
|
||||
try {
|
||||
// 第一层 省
|
||||
List<SysArea> provinceAreas = sysAreaService.selectSysAreaList(sysArea);
|
||||
for (SysArea provinceArea : provinceAreas) {
|
||||
logger.info("进行中的省 : " + provinceArea.getAreaName());
|
||||
SysArea param1 = new SysArea();
|
||||
param1.setParentCode(provinceArea.getAreaCode());
|
||||
// 第二层 市
|
||||
List<SysArea> cityAreas = sysAreaService.selectSysAreaList(param1);
|
||||
for (SysArea cityArea : cityAreas){
|
||||
SysArea param2 = new SysArea();
|
||||
param2.setParentCode(cityArea.getAreaCode());
|
||||
// 第三层 区
|
||||
List<SysArea> countryAreas = sysAreaService.selectSysAreaList(param2);
|
||||
for (SysArea countryArea : countryAreas){
|
||||
SysArea param3 = new SysArea();
|
||||
param3.setParentCode(countryArea.getAreaCode());
|
||||
// 第三层 街道
|
||||
List<SysArea> streetAreas = sysAreaService.selectSysAreaList(param3);
|
||||
countryArea.setChild(streetAreas);
|
||||
}
|
||||
cityArea.setChild(countryAreas);
|
||||
}
|
||||
provinceArea.setChild(cityAreas);
|
||||
}
|
||||
return provinceAreas;
|
||||
}catch (Exception e){
|
||||
logger.error(ExceptionUtil.getExceptionMessage(e));
|
||||
return AjaxResult.error(e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@PostMapping("/app/list")
|
||||
@ResponseBody
|
||||
public AjaxResult appList(@RequestBody SysArea sysArea)
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import com.ghy.system.service.ISysDeptService;
|
|||
|
||||
/**
|
||||
* 部门信息
|
||||
*
|
||||
*
|
||||
* @author clunt
|
||||
*/
|
||||
@Controller
|
||||
|
|
@ -45,7 +45,7 @@ public class SysDeptController extends BaseController
|
|||
return prefix + "/dept";
|
||||
}
|
||||
|
||||
@RequiresPermissions("system:dept:list")
|
||||
// @RequiresPermissions("system:dept:list")
|
||||
@PostMapping("/list")
|
||||
@ResponseBody
|
||||
public List<SysDept> list(SysDept dept)
|
||||
|
|
@ -160,7 +160,7 @@ public class SysDeptController extends BaseController
|
|||
|
||||
/**
|
||||
* 选择部门树
|
||||
*
|
||||
*
|
||||
* @param deptId 部门ID
|
||||
* @param excludeId 排除ID
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.ghy.web.controller.system;
|
||||
|
||||
import com.ghy.common.core.domain.dto.SysUserAddDTO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
|
@ -12,9 +13,11 @@ import com.ghy.common.utils.StringUtils;
|
|||
import com.ghy.framework.shiro.service.SysRegisterService;
|
||||
import com.ghy.system.service.ISysConfigService;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* 注册验证
|
||||
*
|
||||
*
|
||||
* @author clunt
|
||||
*/
|
||||
@Controller
|
||||
|
|
@ -34,13 +37,13 @@ public class SysRegisterController extends BaseController
|
|||
|
||||
@PostMapping("/register")
|
||||
@ResponseBody
|
||||
public AjaxResult ajaxRegister(SysUser user)
|
||||
public AjaxResult ajaxRegister(@Valid SysUserAddDTO userAddDTO)
|
||||
{
|
||||
if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser"))))
|
||||
{
|
||||
return error("当前系统没有开启注册功能!");
|
||||
}
|
||||
String msg = registerService.register(user);
|
||||
String msg = registerService.register(userAddDTO);
|
||||
return StringUtils.isEmpty(msg) ? success() : error(msg);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
package com.ghy.web.controller.tool;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.ghy.common.core.domain.AjaxResult;
|
||||
import com.ghy.common.utils.StringUtils;
|
||||
import com.ghy.web.pojo.vo.CertNoTwoElementReq;
|
||||
import com.ghy.web.service.AliCloudService;
|
||||
import com.ghy.worker.domain.Worker;
|
||||
import com.ghy.worker.service.WorkerService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
@Slf4j
|
||||
@Tag(name = "阿里云Api接口")
|
||||
@Controller
|
||||
@RequestMapping("/tool/ali")
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class AliCloudController {
|
||||
|
||||
private final AliCloudService aliCloudService;
|
||||
|
||||
private final WorkerService workerService;
|
||||
|
||||
@Operation(summary = "身份证二要素校验")
|
||||
@PostMapping("/certNoTwoElementVerification")
|
||||
@ResponseBody
|
||||
public AjaxResult certNoTwoElementVerification(@RequestBody CertNoTwoElementReq certNoTwoElementReq){
|
||||
try {
|
||||
Worker worker = workerService.selectById(certNoTwoElementReq.getWorkerId());
|
||||
if(StringUtils.isNotEmpty(worker.getRemark())){
|
||||
return AjaxResult.success("操作成功!");
|
||||
}else {
|
||||
aliCloudService.certNoTwoElementVerification(certNoTwoElementReq);
|
||||
worker.setRemark(JSONUtil.toJsonStr(certNoTwoElementReq));
|
||||
workerService.updateWorker(worker);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("身份证二要素校验失败:{}", e.getMessage(), e);
|
||||
return AjaxResult.success(e.getMessage(), "身份证二要素校验失败!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -17,6 +17,9 @@ import org.springframework.web.bind.annotation.RequestBody;
|
|||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* 百度地图逆解析
|
||||
* @author clunt
|
||||
|
|
@ -38,12 +41,34 @@ public class BaiduController extends BaseController {
|
|||
JSONObject json = new JSONObject();
|
||||
|
||||
String location = jsonObject.getString("location");
|
||||
|
||||
// 解析经纬度
|
||||
String[] coordinates = location.split(",");
|
||||
if (coordinates.length != 2) {
|
||||
return AjaxResult.error("location格式错误,应为:经度,纬度");
|
||||
}
|
||||
|
||||
try {
|
||||
double longitude = Double.parseDouble(coordinates[1]); // 经度
|
||||
double latitude = Double.parseDouble(coordinates[0]); // 纬度
|
||||
|
||||
// 将经纬度添加到返回结果中
|
||||
json.put("longitude", longitude);
|
||||
json.put("latitude", latitude);
|
||||
json.put("coordinates", coordinates);
|
||||
|
||||
logger.info("解析到的坐标 - 经度: {}, 纬度: {}", longitude, latitude);
|
||||
} catch (NumberFormatException e) {
|
||||
return AjaxResult.error("经纬度格式错误");
|
||||
}
|
||||
|
||||
String url = baiduConfig.getUrl().replace("#AK#", baiduConfig.getAk()) + location;
|
||||
String result = HttpUtils.sendGet(url);
|
||||
result = result.replaceAll("\n", "").replaceAll("\t", "");
|
||||
JSONObject resultJson = JSONObject.parseObject(result);
|
||||
if("0".equals(resultJson.getString("status"))){
|
||||
JSONObject addressJson = resultJson.getJSONObject("result").getJSONObject("addressComponent");
|
||||
logger.info("百度地图获取到的地址 :" + addressJson);
|
||||
String provinceName = addressJson.getString("province");
|
||||
logger.info("provinceName :" + provinceName);
|
||||
SysArea provinceArea = iSysAreaService.selectByName(provinceName, null);
|
||||
|
|
@ -53,9 +78,25 @@ public class BaiduController extends BaseController {
|
|||
String countryName = addressJson.getString("district");
|
||||
logger.info("countryName :" + countryName);
|
||||
SysArea countryArea = iSysAreaService.selectByName(countryName, cityArea.getAreaCode());
|
||||
String streetName = addressJson.getString("town");
|
||||
logger.info("streetName :" + streetName);
|
||||
SysArea streetArea = iSysAreaService.selectByName(streetName, countryArea.getAreaCode());
|
||||
|
||||
// 添加地址信息
|
||||
json.put("provinceArea", provinceArea);
|
||||
json.put("cityArea", cityArea);
|
||||
json.put("countryArea", countryArea);
|
||||
json.put("streetArea", streetArea);
|
||||
|
||||
// 添加完整地址
|
||||
String fullAddress = (provinceName != null ? provinceName : "") +
|
||||
(cityName != null ? cityName : "") +
|
||||
(countryName != null ? countryName : "") +
|
||||
(streetName != null ? streetName : "");
|
||||
json.put("fullAddress", fullAddress);
|
||||
|
||||
// 保留原有的location字段用于兼容
|
||||
json.put("location", location);
|
||||
}else {
|
||||
return AjaxResult.error("Api服务异常!");
|
||||
}
|
||||
|
|
@ -67,6 +108,56 @@ public class BaiduController extends BaseController {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 百度地图正向地理编码(地址 -> 经纬度)
|
||||
* 接收JSON:{provinceName, cityName, countryName, streetName, address}
|
||||
*/
|
||||
@PostMapping("/geocode")
|
||||
@ResponseBody
|
||||
public AjaxResult geocode(@RequestBody JSONObject jsonObject) {
|
||||
try {
|
||||
String provinceName = jsonObject.getString("provinceName");
|
||||
String cityName = jsonObject.getString("cityName");
|
||||
String countryName = jsonObject.getString("countryName");
|
||||
String streetName = jsonObject.getString("streetName");
|
||||
String detailAddress = jsonObject.getString("address");
|
||||
|
||||
StringBuilder full = new StringBuilder();
|
||||
if (provinceName != null) { full.append(provinceName); }
|
||||
if (cityName != null) { full.append(cityName); }
|
||||
if (countryName != null) { full.append(countryName); }
|
||||
if (streetName != null) { full.append(streetName); }
|
||||
if (detailAddress != null) { full.append(detailAddress); }
|
||||
|
||||
String address = full.toString();
|
||||
if (address == null || address.trim().isEmpty()) {
|
||||
return AjaxResult.error("地址不能为空");
|
||||
}
|
||||
|
||||
String encoded = URLEncoder.encode(address, StandardCharsets.UTF_8.name());
|
||||
// 使用百度正向地理编码API
|
||||
String url = "https://api.map.baidu.com/geocoding/v3/?output=json&ak="
|
||||
+ baiduConfig.getAk() + "&address=" + encoded;
|
||||
|
||||
String result = HttpUtils.sendGet(url);
|
||||
result = result.replaceAll("\n", "").replaceAll("\t", "");
|
||||
JSONObject resultJson = JSONObject.parseObject(result);
|
||||
if ("0".equals(resultJson.getString("status"))) {
|
||||
JSONObject location = resultJson.getJSONObject("result").getJSONObject("location");
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("longitude", location.getBigDecimal("lng"));
|
||||
data.put("latitude", location.getBigDecimal("lat"));
|
||||
data.put("fullAddress", address);
|
||||
return AjaxResult.success(data);
|
||||
} else {
|
||||
return AjaxResult.error("百度地理编码失败:" + resultJson.getString("msg"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return AjaxResult.error(ExceptionUtil.getExceptionMessage(e));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
String result = " {\"status\":0,\"result\":{\"location\":{\"lng\":113.29950224957551,\"lat\":23.019282373814027},\"formatted_address\":\"广东省广州市番禺区安平路\",\"business\":\"大石\",\"addressComponent\":{\"country\":\"中国\",\"country_code\":0,\"country_code_iso\":\"CHN\",\"country_code_iso2\":\"CN\",\"province\":\"广东省\",\"city\":\"广州市\",\"city_level\":2,\"district\":\"番禺区\",\"town\":\"\",\"town_code\":\"\",\"distance\":\"\",\"direction\":\"\",\"adcode\":\"440113\",\"street\":\"安平路\",\"street_number\":\"\"},\"pois\":[],\"roads\":[],\"poiRegions\":[],\"sematic_description\":\"\",\"cityCode\":257}}\n";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
package com.ghy.web.controller.tool;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.ghy.common.config.WxConfig;
|
||||
import com.ghy.common.core.controller.BaseController;
|
||||
|
|
@ -8,6 +11,7 @@ import com.ghy.common.enums.OrderStatus;
|
|||
import com.ghy.common.exception.ServiceException;
|
||||
import com.ghy.common.utils.ExceptionUtil;
|
||||
import com.ghy.common.utils.StringUtils;
|
||||
import com.ghy.common.utils.WechatMsgUtils;
|
||||
import com.ghy.common.utils.WxUtils;
|
||||
import com.ghy.common.utils.http.HttpUtils;
|
||||
import com.ghy.customer.domain.Customer;
|
||||
|
|
@ -28,7 +32,9 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import java.io.IOException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author clunt
|
||||
|
|
@ -184,9 +190,205 @@ public class WxController extends BaseController {
|
|||
}
|
||||
String data = HttpUtils.sendGet(url, null);
|
||||
JSONObject result = JSONObject.parseObject(data);
|
||||
// 如果是师傅端,需要调用公众号的获取用户列表接口 -- 遍历列表去找到unionId和openid关联并入库
|
||||
// if(!"customer".equals(from)){
|
||||
// String openid = result.getString("openid");
|
||||
// String unionId = result.getString("unionid");
|
||||
// // 查询openid是否入库,已经入库则不管
|
||||
// Worker param = new Worker();
|
||||
// param.setOpenId(openid);
|
||||
// Worker worker = workerService.selectByOpenId(param);
|
||||
// if(worker != null && StringUtils.isEmpty(worker.getWxOpenId())){
|
||||
// // 公众号token
|
||||
// String wxToken = WechatMsgUtils.getToken();
|
||||
// String wxUserOpenidList = HttpUtils.sendGet("https://api.weixin.qq.com/cgi-bin/user/get?access_token="+wxToken+"&next_openid=");
|
||||
// logger.info("公众号获取的用户列表集合:{}", wxUserOpenidList);
|
||||
// JSONObject wxOpenidJson = JSONObject.parseObject(wxUserOpenidList);
|
||||
// JSONObject openIdListJson = wxOpenidJson.getJSONObject("data");
|
||||
// List<String> openidList = openIdListJson.getObject("openid", ArrayList.class);
|
||||
// JSONArray openidJsonArray = new JSONArray();
|
||||
// openidList.forEach(model->{
|
||||
// JSONObject openidJson = new JSONObject();
|
||||
// openidJson.put("openid", model);
|
||||
// openidJson.put("lang", "zh_CN");
|
||||
// openidJsonArray.add(openidJson);
|
||||
// });
|
||||
// JSONObject jsonParam = new JSONObject();
|
||||
// xw jsonParam.put("user_list", openidJsonArray);
|
||||
// String unionUrl = "https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token="+WechatMsgUtils.getToken();;
|
||||
// logger.info("调用获取用户信息,请求url:{}, 请求body:{}", unionUrl, jsonParam.toJSONString());
|
||||
// String getUnionResult = HttpUtil.post(unionUrl, jsonParam.toJSONString());
|
||||
// logger.info("获取公众号union列表:{}", getUnionResult);
|
||||
// JSONObject unionJson = JSONObject.parseObject(getUnionResult);
|
||||
// JSONArray unionJsonArray = unionJson.getJSONArray("user_info_list");
|
||||
// for (int index = 0 ; index<unionJsonArray.size(); index ++){
|
||||
// JSONObject json = unionJsonArray.getJSONObject(index);
|
||||
// if(StringUtils.isEmpty(json.getString("unionid"))||StringUtils.isEmpty(unionId)){
|
||||
// return AjaxResult.success(result);
|
||||
// }
|
||||
// if(json.getString("unionid").equals(unionId)){
|
||||
// Worker updateWorker = new Worker();
|
||||
// updateWorker.setWorkerId(worker.getWorkerId());
|
||||
// updateWorker.setWxOpenId(json.getString("openid"));
|
||||
// logger.info("关联后的worker信息:{}", worker);
|
||||
// workerService.updateWorker(updateWorker);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
return AjaxResult.success(result);
|
||||
}
|
||||
|
||||
@GetMapping("/check")
|
||||
@ResponseBody
|
||||
public AjaxResult check(HttpServletRequest request) {
|
||||
String url;
|
||||
boolean flag = false;
|
||||
String deptId = request.getHeader("deptId");
|
||||
String from = request.getHeader("from");
|
||||
SysDeptConfig sysDeptConfig = sysDeptConfigService.selectByDeptId(Long.parseLong(deptId));
|
||||
String code = request.getHeader("code");
|
||||
if("customer".equals(from)){
|
||||
url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + sysDeptConfig.getWxAppId() + "&secret=" + sysDeptConfig.getWxSecret() + "&js_code=" + code + "&grant_type=authorization_code";
|
||||
}else {
|
||||
url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + sysDeptConfig.getServWxAppId() + "&secret=" + sysDeptConfig.getServWxSecret() + "&js_code=" + code + "&grant_type=authorization_code";
|
||||
}
|
||||
String data = HttpUtils.sendGet(url, null);
|
||||
JSONObject result = JSONObject.parseObject(data);
|
||||
// 如果是师傅端,需要调用公众号的获取用户列表接口 -- 遍历列表去找到unionId和openid关联并入库
|
||||
if(!"customer".equals(from)){
|
||||
String openid = result.getString("openid");
|
||||
String unionId = result.getString("unionid");
|
||||
// 查询openid是否入库,已经入库则不管
|
||||
Worker param = new Worker();
|
||||
param.setOpenId(openid);
|
||||
Worker worker = workerService.selectByOpenId(param);
|
||||
if(worker != null){
|
||||
// 公众号token
|
||||
String wxToken = WechatMsgUtils.getToken();
|
||||
String wxUserOpenidList = HttpUtils.sendGet("https://api.weixin.qq.com/cgi-bin/user/get?access_token="+wxToken+"&next_openid=");
|
||||
logger.info("公众号获取的用户列表集合:{}", wxUserOpenidList);
|
||||
JSONObject wxOpenidJson = JSONObject.parseObject(wxUserOpenidList);
|
||||
JSONObject openIdListJson = wxOpenidJson.getJSONObject("data");
|
||||
List<String> openidList = openIdListJson.getObject("openid", ArrayList.class);
|
||||
List<List<String>> batchList = ListUtil.partition(openidList, 99);
|
||||
for (List<String> childOpenidList : batchList) {
|
||||
JSONArray openidJsonArray = new JSONArray();
|
||||
childOpenidList.forEach(model->{
|
||||
JSONObject openidJson = new JSONObject();
|
||||
openidJson.put("openid", model);
|
||||
openidJson.put("lang", "zh_CN");
|
||||
openidJsonArray.add(openidJson);
|
||||
});
|
||||
JSONObject jsonParam = new JSONObject();
|
||||
jsonParam.put("user_list", openidJsonArray);
|
||||
String unionUrl = "https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token="+WechatMsgUtils.getToken();;
|
||||
logger.info("调用获取用户信息,请求url:{}, 请求body:{}", unionUrl, jsonParam.toJSONString());
|
||||
String getUnionResult = HttpUtil.post(unionUrl, jsonParam.toJSONString());
|
||||
logger.info("获取公众号union列表:{}", getUnionResult);
|
||||
JSONObject unionJson = JSONObject.parseObject(getUnionResult);
|
||||
JSONArray unionJsonArray = unionJson.getJSONArray("user_info_list");
|
||||
for (int index = 0 ; index<unionJsonArray.size(); index ++){
|
||||
JSONObject json = unionJsonArray.getJSONObject(index);
|
||||
if(StringUtils.isNotEmpty(json.getString("unionid") )&& StringUtils.isNotEmpty(unionId)){
|
||||
if(json.getString("unionid").equals(unionId)){
|
||||
Worker updateWorker = new Worker();
|
||||
updateWorker.setWorkerId(worker.getWorkerId());
|
||||
updateWorker.setWxOpenId(json.getString("openid"));
|
||||
logger.info("关联后的worker信息:{}", worker);
|
||||
workerService.updateWorker(updateWorker);
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(flag){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return AjaxResult.success(true);
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/neCheck")
|
||||
@ResponseBody
|
||||
public AjaxResult neCheck(HttpServletRequest request) {
|
||||
try {
|
||||
String url;
|
||||
boolean flag = false;
|
||||
String deptId = request.getHeader("deptId");
|
||||
String from = request.getHeader("from");
|
||||
SysDeptConfig sysDeptConfig = sysDeptConfigService.selectByDeptId(Long.parseLong(deptId));
|
||||
String code = request.getHeader("code");
|
||||
if("customer".equals(from)){
|
||||
url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + sysDeptConfig.getWxAppId() + "&secret=" + sysDeptConfig.getWxSecret() + "&js_code=" + code + "&grant_type=authorization_code";
|
||||
}else {
|
||||
url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + sysDeptConfig.getServWxAppId() + "&secret=" + sysDeptConfig.getServWxSecret() + "&js_code=" + code + "&grant_type=authorization_code";
|
||||
}
|
||||
String data = HttpUtils.sendGet(url, null);
|
||||
JSONObject result = JSONObject.parseObject(data);
|
||||
// 如果是师傅端,需要调用公众号的获取用户列表接口 -- 遍历列表去找到unionId和openid关联并入库
|
||||
if(!"customer".equals(from)){
|
||||
String openid = result.getString("openid");
|
||||
String unionId = result.getString("unionid");
|
||||
// 查询openid是否入库,已经入库则不管
|
||||
Worker param = new Worker();
|
||||
param.setOpenId(openid);
|
||||
Worker worker = workerService.selectByOpenId(param);
|
||||
if(worker != null){
|
||||
// 公众号token
|
||||
String wxToken = WechatMsgUtils.getToken();
|
||||
String wxUserOpenidList = HttpUtils.sendGet("https://api.weixin.qq.com/cgi-bin/user/get?access_token="+wxToken+"&next_openid=");
|
||||
logger.info("公众号获取的用户列表集合:{}", wxUserOpenidList);
|
||||
JSONObject wxOpenidJson = JSONObject.parseObject(wxUserOpenidList);
|
||||
JSONObject openIdListJson = wxOpenidJson.getJSONObject("data");
|
||||
List<String> openidList = openIdListJson.getObject("openid", ArrayList.class);
|
||||
List<List<String>> batchList = ListUtil.partition(openidList, 99);
|
||||
for (List<String> childOpenidList : batchList) {
|
||||
JSONArray openidJsonArray = new JSONArray();
|
||||
childOpenidList.forEach(model->{
|
||||
JSONObject openidJson = new JSONObject();
|
||||
openidJson.put("openid", model);
|
||||
openidJson.put("lang", "zh_CN");
|
||||
openidJsonArray.add(openidJson);
|
||||
});
|
||||
JSONObject jsonParam = new JSONObject();
|
||||
jsonParam.put("user_list", openidJsonArray);
|
||||
String unionUrl = "https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token="+WechatMsgUtils.getToken();;
|
||||
logger.info("调用获取用户信息,请求url:{}, 请求body:{}", unionUrl, jsonParam.toJSONString());
|
||||
String getUnionResult = HttpUtil.post(unionUrl, jsonParam.toJSONString());
|
||||
logger.info("获取公众号union列表:{}", getUnionResult);
|
||||
JSONObject unionJson = JSONObject.parseObject(getUnionResult);
|
||||
JSONArray unionJsonArray = unionJson.getJSONArray("user_info_list");
|
||||
for (int index = 0 ; index<unionJsonArray.size(); index ++){
|
||||
JSONObject json = unionJsonArray.getJSONObject(index);
|
||||
if(StringUtils.isNotEmpty(json.getString("unionid") )&& StringUtils.isNotEmpty(unionId)){
|
||||
if(json.getString("unionid").equals(unionId)){
|
||||
Worker updateWorker = new Worker();
|
||||
updateWorker.setWorkerId(worker.getWorkerId());
|
||||
updateWorker.setWxOpenId(json.getString("openid"));
|
||||
logger.info("关联后的worker信息:{}", worker);
|
||||
workerService.updateWorker(updateWorker);
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(flag){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return AjaxResult.success(flag);
|
||||
}catch (Exception e){
|
||||
return AjaxResult.success(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/openid")
|
||||
@ResponseBody
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
package com.ghy.web.controller.worker;
|
||||
|
||||
import com.ghy.common.core.controller.BaseController;
|
||||
import com.ghy.common.core.domain.AjaxResult;
|
||||
import com.ghy.common.core.page.TableDataInfo;
|
||||
import com.ghy.common.core.text.Convert;
|
||||
import com.ghy.order.domain.OrderGoods;
|
||||
import com.ghy.system.domain.SysArea;
|
||||
import com.ghy.system.service.ISysAreaService;
|
||||
import com.ghy.worker.domain.WorkerArea;
|
||||
|
|
@ -11,6 +14,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
|
|
@ -26,7 +30,7 @@ import java.util.stream.Collectors;
|
|||
@Slf4j
|
||||
@Controller
|
||||
@RequestMapping("worker/area")
|
||||
public class WorkerAreaController {
|
||||
public class WorkerAreaController extends BaseController {
|
||||
|
||||
@Resource
|
||||
private WorkerAreaService workerAreaService;
|
||||
|
|
@ -34,42 +38,154 @@ public class WorkerAreaController {
|
|||
@Autowired
|
||||
private ISysAreaService sysAreaService;
|
||||
|
||||
@PostMapping("/list")
|
||||
@ResponseBody
|
||||
public TableDataInfo list(WorkerArea workerArea) {
|
||||
startPage();
|
||||
List<WorkerArea> list = workerAreaService.getWorkerAreaList(workerArea);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@GetMapping()
|
||||
public String area(Long workerId, ModelMap mmap)
|
||||
{
|
||||
mmap.put("workerId", workerId);
|
||||
return "worker/areaDetail";
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询某个师傅的所有接单地区
|
||||
*
|
||||
* @param workerId 师傅ID
|
||||
* @param serviceType 服务类型:1=服务, 2=商品,不传则查询所有
|
||||
*/
|
||||
@GetMapping("worker")
|
||||
@ResponseBody
|
||||
public AjaxResult getByWorker(Long workerId) {
|
||||
return AjaxResult.success(workerAreaService.getByWorker(workerId));
|
||||
public AjaxResult getByWorker(Long workerId, Integer serviceType) {
|
||||
if (serviceType != null) {
|
||||
// 根据服务类型查询
|
||||
return AjaxResult.success(workerAreaService.getByWorkerIdAndType(workerId, serviceType));
|
||||
} else {
|
||||
// 查询所有区域(保持向后兼容)
|
||||
return AjaxResult.success(workerAreaService.getByWorker(workerId));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询某个师傅的服务区域(类型1)
|
||||
*
|
||||
* @param workerId 师傅ID
|
||||
*/
|
||||
@GetMapping("worker/service")
|
||||
@ResponseBody
|
||||
public AjaxResult getServiceAreasByWorker(Long workerId) {
|
||||
return AjaxResult.success(workerAreaService.getByWorkerIdAndType(workerId, 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询某个师傅的商品区域(类型2)
|
||||
*
|
||||
* @param workerId 师傅ID
|
||||
*/
|
||||
@GetMapping("worker/goods")
|
||||
@ResponseBody
|
||||
public AjaxResult getGoodsAreasByWorker(Long workerId) {
|
||||
return AjaxResult.success(workerAreaService.getByWorkerIdAndType(workerId, 2));
|
||||
}
|
||||
|
||||
@GetMapping("worker/edit")
|
||||
@ResponseBody
|
||||
public AjaxResult getEditWorker(Long workerId){
|
||||
public AjaxResult getEditWorker(Long workerId, Integer type){
|
||||
Map<Long, List<String>> countryMap = new HashMap<>();
|
||||
List<WorkerArea> byWorker = workerAreaService.getByWorker(workerId);
|
||||
for (WorkerArea area : byWorker){
|
||||
List<String> ids;
|
||||
if(countryMap.containsKey(area.getDistrictId())){
|
||||
ids = countryMap.get(area.getDistrictId());
|
||||
}else {
|
||||
ids = new ArrayList<>();
|
||||
}
|
||||
ids.add(String.valueOf(area.getStreetId()));
|
||||
countryMap.put(area.getDistrictId(), ids);
|
||||
|
||||
// 需求1:根据类型查询对应的区域数据
|
||||
List<WorkerArea> byWorker;
|
||||
if (Integer.valueOf(1).equals(type)) {
|
||||
// 服务类型:查询服务区域
|
||||
byWorker = workerAreaService.getByWorkerIdAndType(workerId, 1);
|
||||
} else if (Integer.valueOf(2).equals(type)) {
|
||||
// 商品类型:查询商品区域
|
||||
byWorker = workerAreaService.getByWorkerIdAndType(workerId, 2);
|
||||
} else {
|
||||
// 不传类型:查询所有区域
|
||||
byWorker = workerAreaService.getByWorker(workerId);
|
||||
}
|
||||
|
||||
// 收集只有cityId没有districtId的城市ID集合(用于单独处理)
|
||||
Set<Long> cityOnlyIds = new HashSet<>();
|
||||
// 按districtId分组收集cityIds
|
||||
Map<Long, Set<Long>> districtCityMap = new HashMap<>();
|
||||
|
||||
for (WorkerArea area : byWorker){
|
||||
Long districtId = area.getDistrictId();
|
||||
|
||||
// 如果有districtId,按districtId分组处理
|
||||
if (districtId != null) {
|
||||
List<String> ids;
|
||||
if(countryMap.containsKey(districtId)){
|
||||
ids = countryMap.get(districtId);
|
||||
} else {
|
||||
ids = new ArrayList<>();
|
||||
}
|
||||
|
||||
// 收集该district下的城市ID
|
||||
if (area.getCityId() != null) {
|
||||
districtCityMap.computeIfAbsent(districtId, k -> new HashSet<>()).add(area.getCityId());
|
||||
}
|
||||
|
||||
// 添加街道ID
|
||||
if (area.getStreetId() != null) {
|
||||
ids.add(String.valueOf(area.getStreetId()));
|
||||
}
|
||||
|
||||
countryMap.put(districtId, ids);
|
||||
} else {
|
||||
// 如果只有cityId没有districtId,收集到cityOnlyIds
|
||||
if (area.getCityId() != null) {
|
||||
cityOnlyIds.add(area.getCityId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<WorkerArea> result = new ArrayList<>();
|
||||
|
||||
// 处理有districtId的情况(正常流程)
|
||||
for (Map.Entry<Long, List<String>> longListEntry : countryMap.entrySet()) {
|
||||
WorkerArea model = new WorkerArea();
|
||||
SysArea countryArea = sysAreaService.selectById(longListEntry.getKey());
|
||||
Long districtId = longListEntry.getKey();
|
||||
SysArea countryArea = sysAreaService.selectById(districtId);
|
||||
model.setDistrictArea(countryArea);
|
||||
SysArea cityArea = sysAreaService.selectById(Long.valueOf(countryArea.getParentCode()));
|
||||
model.setCityArea(cityArea);
|
||||
SysArea provinceArea = sysAreaService.selectById(Long.valueOf(cityArea.getParentCode()));
|
||||
model.setProvinceArea(provinceArea);
|
||||
|
||||
// 设置该district下的cityIds
|
||||
Set<Long> districtCityIds = districtCityMap.getOrDefault(districtId, new HashSet<>());
|
||||
List<Long> cityIdList = new ArrayList<>(districtCityIds);
|
||||
model.setCityIds(cityIdList);
|
||||
|
||||
// 设置街道ID列表
|
||||
model.setStreetIds(longListEntry.getValue());
|
||||
|
||||
result.add(model);
|
||||
}
|
||||
|
||||
// 处理只有cityId没有districtId的情况(只返回省市信息)
|
||||
for (Long cityId : cityOnlyIds) {
|
||||
WorkerArea model = new WorkerArea();
|
||||
SysArea cityArea = sysAreaService.selectById(cityId);
|
||||
model.setCityArea(cityArea);
|
||||
// 获取省份信息
|
||||
SysArea provinceArea = sysAreaService.selectById(Long.valueOf(cityArea.getParentCode()));
|
||||
model.setProvinceArea(provinceArea);
|
||||
|
||||
// 只设置城市ID列表
|
||||
List<Long> cityIdList = new ArrayList<>();
|
||||
cityIdList.add(cityId);
|
||||
model.setCityIds(cityIdList);
|
||||
|
||||
// 不设置district和street信息
|
||||
result.add(model);
|
||||
}
|
||||
return AjaxResult.success(result);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import com.huifu.adapay.core.exception.BaseAdaPayException;
|
|||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
|
@ -57,6 +58,8 @@ public class WorkerBankController extends BaseController {
|
|||
return AjaxResult.error("师傅未通过审核,不能绑定银行卡");
|
||||
}
|
||||
Set<Merchant> merchants = AdapayConfig.getMerchants();
|
||||
String phone = request.getPhone();
|
||||
phone = StringUtils.trimAllWhitespace(phone);
|
||||
for (Merchant merchant : merchants) {
|
||||
String memberId = AdapayUtils.getWorkerMemberId(request.getWorkerId(), merchant.getDeptId());
|
||||
|
||||
|
|
@ -66,7 +69,7 @@ public class WorkerBankController extends BaseController {
|
|||
logger.info("用户[memberId={}]已存在 跳过实名直接绑卡", memberId);
|
||||
} else {
|
||||
// 先在Adapay创建实名用户
|
||||
Map<String, Object> result1 = adapayService.createMember(merchant.getDeptId(), memberId, request.getPhone(),
|
||||
Map<String, Object> result1 = adapayService.createMember(merchant.getDeptId(), memberId, phone,
|
||||
request.getName(), request.getCertId());
|
||||
if (!AdapayStatusEnum.succeeded.code.equals(result1.get("status"))) {
|
||||
logger.error("实名认证失败[{}]", JSON.toJSONString(result1));
|
||||
|
|
@ -76,11 +79,11 @@ public class WorkerBankController extends BaseController {
|
|||
|
||||
// 开始创建结算账户
|
||||
JSONObject result2 = adapayService.createSettleAccount(merchant.getDeptId(), memberId, request.getBankNum(), request.getName(),
|
||||
"2", request.getCertId(), request.getPhone(), null, null, null);
|
||||
"2", request.getCertId(), phone, null, null, null);
|
||||
if (!AdapayStatusEnum.succeeded.code.equals(result2.get("status"))) {
|
||||
if ("account_exists".equals(result2.get("error_code"))) {
|
||||
logger.info("用户[memberId={}]结算账户已存在 跳过", memberId);
|
||||
|
||||
continue;
|
||||
} else {
|
||||
logger.error("创建结算账户失败[{}]", JSON.toJSONString(result2));
|
||||
return AjaxResult.error("个人信息与银行卡不匹配或不支持信用卡绑定");
|
||||
|
|
@ -93,7 +96,7 @@ public class WorkerBankController extends BaseController {
|
|||
workerBank.setName(request.getName());
|
||||
workerBank.setCertId(request.getCertId());
|
||||
workerBank.setBankNum(request.getBankNum());
|
||||
workerBank.setPhone(request.getPhone());
|
||||
workerBank.setPhone(phone);
|
||||
workerBank.setDeptId(merchant.getDeptId());
|
||||
workerBank.setAdapayMemberId(memberId);
|
||||
workerBank.setSettleAccount(1);
|
||||
|
|
@ -156,7 +159,10 @@ public class WorkerBankController extends BaseController {
|
|||
@ResponseBody
|
||||
public AjaxResult getByWorkerId(@RequestBody WorkerBindBankCardRequest request) {
|
||||
try {
|
||||
return AjaxResult.success(workerBankService.getByWorkerId(request.getWorkerId()));
|
||||
if(request.getDeptId() == null){
|
||||
request.setDeptId(101L);
|
||||
}
|
||||
return AjaxResult.success(workerBankService.getByWorkerId(request.getWorkerId(), request.getDeptId()));
|
||||
} catch (Exception e) {
|
||||
|
||||
return AjaxResult.error(ExceptionUtil.getExceptionMessage(e));
|
||||
|
|
|
|||
|
|
@ -6,11 +6,8 @@ import com.ghy.common.core.domain.AjaxResult;
|
|||
import com.ghy.common.core.page.TableDataInfo;
|
||||
import com.ghy.common.enums.BusinessType;
|
||||
import com.ghy.common.enums.WorkerCertifyStatus;
|
||||
import com.ghy.common.enums.WorkerStatus;
|
||||
import com.ghy.common.json.JSONObject;
|
||||
import com.ghy.common.utils.ExceptionUtil;
|
||||
import com.ghy.common.utils.ObjectUtils;
|
||||
import com.ghy.common.utils.StringUtils;
|
||||
import com.ghy.common.utils.poi.ExcelUtil;
|
||||
import com.ghy.goods.domain.DeptGoodsCategory;
|
||||
import com.ghy.goods.service.DeptGoodsCategoryService;
|
||||
|
|
@ -30,7 +27,6 @@ import org.springframework.stereotype.Controller;
|
|||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -81,7 +77,13 @@ public class WorkerCertificationController extends BaseController
|
|||
public TableDataInfo list(WorkerCertification workerCertification)
|
||||
{
|
||||
startPage();
|
||||
if(this.getSysUser().getDept().getParentId() != 101){
|
||||
workerCertification.setDeptId(this.getSysUser().getDept().getParentId());
|
||||
}
|
||||
List<WorkerCertification> list = workerCertificationService.selectWorkerCertificationList(workerCertification);
|
||||
list.forEach(worker->{
|
||||
worker.setName(worker.getSurname() + worker.getName());
|
||||
});
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
|
|
@ -160,6 +162,8 @@ public class WorkerCertificationController extends BaseController
|
|||
@ResponseBody
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public AjaxResult appAddCertify(@RequestBody WorkerCertification request) {
|
||||
Worker worker = workerService.selectById(request.getWorkerId());
|
||||
request.setWorkerPhone(worker != null ? worker.getPhone() : null);
|
||||
// 将师傅状态设置为冻结
|
||||
// Worker worker = new Worker();
|
||||
// worker.setWorkerId(request.getWorkerId());
|
||||
|
|
@ -222,7 +226,7 @@ public class WorkerCertificationController extends BaseController
|
|||
for (String id : idArray){
|
||||
WorkerCertification workerCertification = workerCertificationService.selectWorkerCertificationByWorkerCertificationId(id);
|
||||
// 是否绑定了银行卡
|
||||
WorkerBank workerBank = workerBankService.getByWorkerId(workerCertification.getWorkerId());
|
||||
WorkerBank workerBank = workerBankService.getByWorkerId(workerCertification.getWorkerId(), 101L);
|
||||
// 没有绑定了银行卡的用户
|
||||
if(ObjectUtils.isEmpty(workerBank)){
|
||||
return AjaxResult.success("操作成功!");
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import com.ghy.common.enums.WorkerStatus;
|
|||
import com.ghy.common.enums.WorkerType;
|
||||
import com.ghy.common.utils.CacheUtils;
|
||||
import com.ghy.common.utils.ExceptionUtil;
|
||||
import com.ghy.common.utils.StringUtils;
|
||||
import com.ghy.goods.domain.Goods;
|
||||
import com.ghy.goods.domain.GoodsCategory;
|
||||
import com.ghy.goods.service.GoodsCategoryService;
|
||||
|
|
@ -24,6 +25,7 @@ import com.ghy.worker.domain.WorkerArea;
|
|||
import com.ghy.worker.domain.WorkerBank;
|
||||
import com.ghy.worker.domain.WorkerGoodsCategory;
|
||||
import com.ghy.worker.service.*;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.apache.shiro.util.Assert;
|
||||
|
|
@ -81,9 +83,18 @@ public class WorkerController extends BaseController {
|
|||
public AjaxResult login(@RequestBody Worker worker){
|
||||
try {
|
||||
Assert.notNull(worker.getPhone(), "手机号码为空");
|
||||
List<Worker> workerList = workerService.getWorkList(worker);
|
||||
List<Worker> workerList = workerService.getWorkByPhoneAndPwd(worker);
|
||||
if(workerList.size() > 0){
|
||||
return AjaxResult.success(workerList.get(0));
|
||||
Worker loginWorker = workerList.get(0);
|
||||
// 检查师傅状态:0=生效,1=冻结,2=删除
|
||||
if(loginWorker.getStatus() == WorkerStatus.DELETED.getCode()){
|
||||
return AjaxResult.error("账户已被删除,无法登录!");
|
||||
}
|
||||
// 检查登录状态:0=允许登录,1=禁止登录
|
||||
if(loginWorker.getLoginStatus() != null && loginWorker.getLoginStatus() == 1){
|
||||
return AjaxResult.error("账户登录已被禁用,无法登录!");
|
||||
}
|
||||
return AjaxResult.success(loginWorker);
|
||||
}else {
|
||||
return AjaxResult.error("用户名或密码错误!");
|
||||
}
|
||||
|
|
@ -98,11 +109,13 @@ public class WorkerController extends BaseController {
|
|||
@ResponseBody
|
||||
public AjaxResult register(@RequestBody Worker request){
|
||||
try {
|
||||
logger.info("注册师傅信息:{}", request);
|
||||
if (CacheUtils.get(request.getPhone()) == null){
|
||||
return AjaxResult.error("验证码无效!");
|
||||
}
|
||||
// 验证码校验正确
|
||||
if(CacheUtils.get(request.getPhone()).toString().equals(request.getRegisterCode())){
|
||||
logger.info("验证码信息:{}", CacheUtils.get(request.getPhone()));
|
||||
int result = workerService.updateWorker(request);
|
||||
if(result > 0){
|
||||
CacheUtils.remove(request.getPhone());
|
||||
|
|
@ -129,28 +142,108 @@ public class WorkerController extends BaseController {
|
|||
|
||||
try {
|
||||
// 查询满足区域条件的师傅区域记录
|
||||
WorkerArea workerArea = new WorkerArea();
|
||||
workerArea.setDistrictId(workerListRequest.getAreaId());
|
||||
List<WorkerArea> workerAreaList = workerAreaService.getWorkerAreaList(workerArea);
|
||||
List<Long> workerIdsByArea = workerAreaList.stream().map(WorkerArea::getWorkerId).collect(Collectors.toList());
|
||||
// 查询满足技能条件的师傅技能记录
|
||||
WorkerGoodsCategory workerGoodsCategory = new WorkerGoodsCategory();
|
||||
workerGoodsCategory.setGoodsCategoryId(workerListRequest.getGoodsCategoryId());
|
||||
List<WorkerGoodsCategory> workerGoodsCategoryList = workerGoodsCategoryService.getWorkerGoodsCategory(workerGoodsCategory);
|
||||
List<Long> workerIdsByCategory = workerGoodsCategoryList.stream().map(WorkerGoodsCategory::getWorkerId).collect(Collectors.toList());
|
||||
// 两个list中的workerid取交集
|
||||
List<Long> resWorkerIds = new ArrayList<>(CollectionUtils.intersection(workerIdsByArea, workerIdsByCategory));
|
||||
List<Long> workerIdsByArea = new ArrayList<>();
|
||||
if(workerListRequest.getAreaId() != null){
|
||||
WorkerArea workerArea = new WorkerArea();
|
||||
workerArea.setDistrictId(workerListRequest.getAreaId());
|
||||
// 如果有省市区的查询条件,需要构建完整的区域查询条件
|
||||
boolean flag = StringUtils.isNotEmpty(workerListRequest.getDistrictId()) || StringUtils.isNotEmpty(workerListRequest.getProvinceId())
|
||||
|| StringUtils.isNotEmpty(workerListRequest.getCityId()) || StringUtils.isNotEmpty(workerListRequest.getStreetId());
|
||||
if(flag){
|
||||
workerArea.setDistrictId(null);
|
||||
}
|
||||
if(StringUtils.isNotEmpty(workerListRequest.getDistrictId())){
|
||||
workerArea.setDistrictId(Long.valueOf(workerListRequest.getDistrictId()));
|
||||
}
|
||||
if(StringUtils.isNotEmpty(workerListRequest.getProvinceId())) {
|
||||
workerArea.setProvinceId(Long.valueOf(workerListRequest.getProvinceId()));
|
||||
}
|
||||
if(StringUtils.isNotEmpty(workerListRequest.getCityId())) {
|
||||
workerArea.setCityId(Long.valueOf(workerListRequest.getCityId()));
|
||||
}
|
||||
if(StringUtils.isNotEmpty(workerListRequest.getStreetId())) {
|
||||
workerArea.setStreetId(Long.valueOf(workerListRequest.getStreetId()));
|
||||
}
|
||||
List<WorkerArea> workerAreaList = workerAreaService.getWorkerAreaList(workerArea);
|
||||
workerIdsByArea = workerAreaList.stream()
|
||||
.map(WorkerArea::getWorkerId)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
if (CollectionUtils.isEmpty(resWorkerIds)) {
|
||||
// 交集不存在的情况直接返回空list
|
||||
return getDataTable(resList);
|
||||
// 查询满足技能条件的师傅技能记录
|
||||
List<Long> workerIdsByCategory = new ArrayList<>();
|
||||
WorkerGoodsCategory workerGoodsCategory = new WorkerGoodsCategory();
|
||||
if(workerListRequest.getGoodsCategoryId() != null){
|
||||
workerGoodsCategory.setGoodsCategoryId(workerListRequest.getGoodsCategoryId());
|
||||
}
|
||||
// 如果选择了上级类目但未选择最终类目,则查询该类目下所有子类目
|
||||
if(StringUtils.isNotEmpty(workerListRequest.getCategoryLevel1())
|
||||
&& StringUtils.isEmpty(workerListRequest.getCategoryLevel2()) && workerListRequest.getGoodsCategoryId() == null) {
|
||||
// 1. 先查找二级类目
|
||||
GoodsCategory param = new GoodsCategory();
|
||||
param.setParentCategoryId(Long.valueOf(workerListRequest.getCategoryLevel1()));
|
||||
List<GoodsCategory> secondCategories = goodsCategoryService.selectGoodsCategoryList(param);
|
||||
|
||||
// 2. 用二级类目查找三级类目
|
||||
List<String> categoryIds = new ArrayList<>();
|
||||
for (GoodsCategory secondCategory : secondCategories) {
|
||||
param.setParentCategoryId(secondCategory.getGoodsCategoryId());
|
||||
List<GoodsCategory> thirdCategories = goodsCategoryService.selectGoodsCategoryList(param);
|
||||
categoryIds.addAll(thirdCategories.stream()
|
||||
.map(x->x.getGoodsCategoryId().toString())
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
workerGoodsCategory.setCategoryIds(categoryIds);
|
||||
}
|
||||
// 如果选择了二级类目但未选择三级类目
|
||||
else if(StringUtils.isNotEmpty(workerListRequest.getCategoryLevel2())
|
||||
&& workerListRequest.getGoodsCategoryId() == null) {
|
||||
GoodsCategory param = new GoodsCategory();
|
||||
param.setParentCategoryId(Long.valueOf(workerListRequest.getCategoryLevel2()));
|
||||
List<GoodsCategory> subCategories = goodsCategoryService.selectGoodsCategoryList(param);
|
||||
List<String> categoryIds = subCategories.stream()
|
||||
.map(x->x.getGoodsCategoryId().toString())
|
||||
.collect(Collectors.toList());
|
||||
workerGoodsCategory.setCategoryIds(categoryIds);
|
||||
}
|
||||
if(CollectionUtils.isNotEmpty(workerGoodsCategory.getCategoryIds()) || workerGoodsCategory.getGoodsCategoryId() != null){
|
||||
List<WorkerGoodsCategory> workerGoodsCategoryList = workerGoodsCategoryService.getWorkerGoodsCategory(workerGoodsCategory);
|
||||
workerIdsByCategory = workerGoodsCategoryList.stream()
|
||||
.map(WorkerGoodsCategory::getWorkerId)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
// 两个list中的workerid取交集
|
||||
List<Long> resWorkerIds = new ArrayList<>();
|
||||
if(!workerIdsByArea.isEmpty() && !workerIdsByCategory.isEmpty()) {
|
||||
resWorkerIds.addAll(CollectionUtils.intersection(workerIdsByArea, workerIdsByCategory));
|
||||
} else if(!workerIdsByArea.isEmpty()) {
|
||||
resWorkerIds.addAll(workerIdsByArea);
|
||||
} else if(!workerIdsByCategory.isEmpty()) {
|
||||
resWorkerIds.addAll(workerIdsByCategory);
|
||||
}
|
||||
|
||||
if (!resWorkerIds.isEmpty() ||
|
||||
workerListRequest.getAreaId() != null ||
|
||||
workerListRequest.getGoodsCategoryId() != null) {
|
||||
// 有查询条件但无匹配结果时直接返回空列表
|
||||
if(resWorkerIds.isEmpty()) {
|
||||
return getDataTable(resList);
|
||||
}
|
||||
}
|
||||
|
||||
startPage();
|
||||
Worker worker = new Worker();
|
||||
worker.setWorkerIds(CollectionUtils.isNotEmpty(resWorkerIds) ? resWorkerIds : null);
|
||||
worker.setName(workerListRequest.getWorkerName());
|
||||
worker.setKeyWords(workerListRequest.getWorkerName());
|
||||
if(StringUtils.isNotEmpty(workerListRequest.getWorkerPhone())){
|
||||
worker.setPhone(workerListRequest.getWorkerPhone());
|
||||
}
|
||||
if(this.getSysUser().getDept().getParentId() != 101){
|
||||
worker.setDeptId(this.getSysUser().getDept().getParentId());
|
||||
}
|
||||
List<Worker> list = workerService.getWorkList(worker);
|
||||
TableDataInfo dataTable = getDataTable(list);
|
||||
list.forEach(w -> {
|
||||
Goods goods = new Goods();
|
||||
goods.setWorkerId(w.getWorkerId());
|
||||
|
|
@ -161,13 +254,18 @@ public class WorkerController extends BaseController {
|
|||
workerListResponse.setGoodsCategories(workerGoodsCategoryService.getByWorker(w.getWorkerId()));
|
||||
workerListResponse.setSpecialSkills(specialSkillService.getByWorker(w.getWorkerId()));
|
||||
resList.add(workerListResponse);
|
||||
|
||||
});
|
||||
TableDataInfo rspData = new TableDataInfo();
|
||||
rspData.setCode(0);
|
||||
rspData.setRows(resList);
|
||||
rspData.setTotal(dataTable.getTotal());
|
||||
return rspData;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
logger.error(ExceptionUtil.getExceptionMessage(e));
|
||||
return getDataTable(new ArrayList<>());
|
||||
}
|
||||
|
||||
return getDataTable(resList);
|
||||
}
|
||||
|
||||
@PostMapping("/app/list")
|
||||
|
|
@ -238,6 +336,7 @@ public class WorkerController extends BaseController {
|
|||
startPage();
|
||||
// worker.setWorkerIds(CollectionUtils.isNotEmpty(resWorkerIds) ? resWorkerIds : null);
|
||||
worker.setName(workerListRequest.getWorkerName());
|
||||
worker.setStatus(0);
|
||||
List<Worker> list = workerService.getWorkList(worker);
|
||||
list.forEach(w -> {
|
||||
Goods goods = new Goods();
|
||||
|
|
@ -252,7 +351,12 @@ public class WorkerController extends BaseController {
|
|||
setDistrictIds(worker.getDistrictIds());
|
||||
}}));
|
||||
} else {
|
||||
workerListResponse.setWorkerAreas(workerAreaService.getByWorker(w.getWorkerId()));
|
||||
List<WorkerArea> workerAreas = workerAreaService.getByWorker(w.getWorkerId());
|
||||
if(workerAreas.size() > 10){
|
||||
workerListResponse.setWorkerAreas(workerAreas.subList(0,10));
|
||||
}else {
|
||||
workerListResponse.setWorkerAreas(workerAreas);
|
||||
}
|
||||
}
|
||||
workerListResponse.setGoodsCategories(workerGoodsCategoryService.getByWorker(w.getWorkerId()));
|
||||
workerListResponse.setSpecialSkills(specialSkillService.getByWorker(w.getWorkerId()));
|
||||
|
|
@ -317,19 +421,106 @@ public class WorkerController extends BaseController {
|
|||
}
|
||||
}
|
||||
|
||||
@PostMapping("/changeLoginStatus")
|
||||
@ResponseBody
|
||||
public AjaxResult changeLoginStatus(Worker worker){
|
||||
try {
|
||||
workerService.updateWorker(worker);
|
||||
return AjaxResult.success("登录状态修改成功");
|
||||
}catch (Exception e){
|
||||
logger.error(ExceptionUtil.getExceptionMessage(e));
|
||||
return AjaxResult.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/settled")
|
||||
@ResponseBody
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public AjaxResult settled(@RequestBody WorkerSettledRequest request) {
|
||||
// 入驻区域信息持久化
|
||||
workerAreaService.updateWorkerServArea(request.getWorkerId(), request.getWorkerAreas());
|
||||
// 入驻服务品类信息持久化
|
||||
workerGoodsCategoryService.updateWorkerGoodsCategory(request.getWorkerId(), request.getGoodsCategories());
|
||||
// 入驻服务区域信息持久化(类型1)
|
||||
workerAreaService.updateWorkerAreaByType(request.getWorkerId(), request.getWorkerAreas(), 1);
|
||||
|
||||
// 入驻商品区域信息持久化(类型2)
|
||||
workerAreaService.updateWorkerAreaByType(request.getWorkerId(), request.getWorkerGoodsAreas(), 2);
|
||||
|
||||
// 入驻服务类目信息持久化(类型1)
|
||||
if (request.getServiceCategories() != null && !request.getServiceCategories().isEmpty()) {
|
||||
// 使用对象数组方式
|
||||
workerGoodsCategoryService.updateWorkerGoodsCategoryByType(request.getWorkerId(), request.getServiceCategories(), 1);
|
||||
} else if (request.getServiceCategoryIds() != null && !request.getServiceCategoryIds().isEmpty()) {
|
||||
// 使用ID数组方式(兼容旧版本)
|
||||
List<WorkerGoodsCategory> serviceCategories = request.getServiceCategoryIds().stream()
|
||||
.map(id -> {
|
||||
WorkerGoodsCategory category = new WorkerGoodsCategory();
|
||||
category.setGoodsCategoryId(id);
|
||||
return category;
|
||||
}).collect(Collectors.toList());
|
||||
workerGoodsCategoryService.updateWorkerGoodsCategoryByType(request.getWorkerId(), serviceCategories, 1);
|
||||
}
|
||||
|
||||
// 入驻商品类目信息持久化(类型2)
|
||||
if (request.getGoodsCategories() != null && !request.getGoodsCategories().isEmpty()) {
|
||||
// 使用对象数组方式
|
||||
workerGoodsCategoryService.updateWorkerGoodsCategoryByType(request.getWorkerId(), request.getGoodsCategories(), 2);
|
||||
} else if (request.getGoodsCategoryIds() != null && !request.getGoodsCategoryIds().isEmpty()) {
|
||||
// 使用ID数组方式(兼容旧版本)
|
||||
List<WorkerGoodsCategory> goodsCategories = request.getGoodsCategoryIds().stream()
|
||||
.map(id -> {
|
||||
WorkerGoodsCategory category = new WorkerGoodsCategory();
|
||||
category.setGoodsCategoryId(id);
|
||||
return category;
|
||||
}).collect(Collectors.toList());
|
||||
workerGoodsCategoryService.updateWorkerGoodsCategoryByType(request.getWorkerId(), goodsCategories, 2);
|
||||
}
|
||||
|
||||
// 更新师傅入驻类型为服务商
|
||||
Worker worker = new Worker();
|
||||
worker.setWorkerId(request.getWorkerId());
|
||||
worker.setType(WorkerType.SP.getCode());
|
||||
workerService.updateWorker(worker);
|
||||
|
||||
return AjaxResult.success("保存成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过师傅ID获取师傅详情
|
||||
* @param workerId 师傅ID
|
||||
* @return 师傅实体对象
|
||||
*/
|
||||
@GetMapping("/detail/{workerId}")
|
||||
@ResponseBody
|
||||
public AjaxResult getWorkerDetailById(@PathVariable("workerId") Long workerId) {
|
||||
try {
|
||||
// 参数校验
|
||||
if (workerId == null) {
|
||||
return AjaxResult.error("师傅ID不能为空");
|
||||
}
|
||||
|
||||
// 查询师傅基本信息
|
||||
Worker worker = workerService.selectById(workerId);
|
||||
if (worker == null) {
|
||||
return AjaxResult.error("师傅不存在");
|
||||
}
|
||||
|
||||
return AjaxResult.success(worker);
|
||||
} catch (Exception e) {
|
||||
logger.error("获取师傅详情失败: " + ExceptionUtil.getExceptionMessage(e));
|
||||
return AjaxResult.error("获取师傅详情失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除师傅(软删除)
|
||||
*/
|
||||
@RequiresPermissions("worker:worker:remove")
|
||||
@PostMapping("/remove")
|
||||
@ResponseBody
|
||||
public AjaxResult remove(String ids) {
|
||||
try {
|
||||
return toAjax(workerService.deleteWorkerByIds(ids));
|
||||
} catch (Exception e) {
|
||||
logger.error(ExceptionUtil.getExceptionMessage(e));
|
||||
return AjaxResult.error("删除失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
package com.ghy.web.controller.worker;
|
||||
|
||||
import com.ghy.common.constant.Constants;
|
||||
import com.ghy.common.core.controller.BaseController;
|
||||
import com.ghy.common.core.domain.AjaxResult;
|
||||
import com.ghy.common.core.page.TableDataInfo;
|
||||
import com.ghy.common.core.text.Convert;
|
||||
import com.ghy.common.utils.StringUtils;
|
||||
import com.ghy.goods.domain.GoodsCategory;
|
||||
import com.ghy.goods.service.GoodsCategoryService;
|
||||
import com.ghy.worker.domain.WorkerArea;
|
||||
import com.ghy.worker.domain.WorkerGoodsCategory;
|
||||
import com.ghy.worker.request.WorkerGoodsCategorySaveRequest;
|
||||
import com.ghy.worker.service.WorkerGoodsCategoryService;
|
||||
|
|
@ -13,6 +16,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
|
|
@ -28,7 +32,7 @@ import java.util.stream.Collectors;
|
|||
@Slf4j
|
||||
@Controller
|
||||
@RequestMapping("worker/goods/category")
|
||||
public class WorkerGoodsCategoryController {
|
||||
public class WorkerGoodsCategoryController extends BaseController {
|
||||
|
||||
@Resource
|
||||
private WorkerGoodsCategoryService workerGoodsCategoryService;
|
||||
|
|
@ -36,15 +40,51 @@ public class WorkerGoodsCategoryController {
|
|||
@Autowired
|
||||
private GoodsCategoryService goodsCategoryService;
|
||||
|
||||
|
||||
@PostMapping("/list")
|
||||
@ResponseBody
|
||||
public TableDataInfo list(WorkerGoodsCategory workerGoodsCategory) {
|
||||
startPage();
|
||||
List<WorkerGoodsCategory> list = workerGoodsCategoryService.getByWorker(workerGoodsCategory.getWorkerId());
|
||||
for (WorkerGoodsCategory item: list) {
|
||||
List<String> nameList = new ArrayList<String>();
|
||||
// 查询所有父级服务类目,拼接服务名称
|
||||
GoodsCategory goodsCategory = goodsCategoryService.selectById(item.getGoodsCategoryId());
|
||||
while (goodsCategory.getParentCategoryId() != null) {
|
||||
nameList.add(goodsCategory.getGoodsCategoryName());
|
||||
goodsCategory = goodsCategoryService.selectById(goodsCategory.getParentCategoryId());
|
||||
}
|
||||
Collections.reverse(nameList);
|
||||
item.setMergeName(StringUtils.join(nameList, Constants.JOIN_SYMBOL));
|
||||
}
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@GetMapping()
|
||||
public String category(Long workerId, ModelMap mmap)
|
||||
{
|
||||
mmap.put("workerId", workerId);
|
||||
return "worker/categoryDetail";
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询某个师傅的所有服务类目
|
||||
*
|
||||
* @param workerId 师傅ID
|
||||
* @param serviceType 服务类型:1=服务, 2=商品,不传则查询所有
|
||||
*/
|
||||
@GetMapping("worker")
|
||||
@ResponseBody
|
||||
public AjaxResult getByWorker(Long workerId) {
|
||||
List<WorkerGoodsCategory> list = workerGoodsCategoryService.getByWorker(workerId);
|
||||
public AjaxResult getByWorker(Long workerId, Integer serviceType) {
|
||||
List<WorkerGoodsCategory> list;
|
||||
if (serviceType != null) {
|
||||
// 根据服务类型查询
|
||||
list = workerGoodsCategoryService.getByWorkerIdAndType(workerId, serviceType);
|
||||
} else {
|
||||
// 查询所有类目(保持向后兼容)
|
||||
list = workerGoodsCategoryService.getByWorker(workerId);
|
||||
}
|
||||
|
||||
for (WorkerGoodsCategory item: list) {
|
||||
List<String> nameList = new ArrayList<String>();
|
||||
// 查询所有父级服务类目,拼接服务名称
|
||||
|
|
@ -58,14 +98,75 @@ public class WorkerGoodsCategoryController {
|
|||
}
|
||||
return AjaxResult.success(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询某个师傅的服务类目(类型1)
|
||||
*
|
||||
* @param workerId 师傅ID
|
||||
*/
|
||||
@GetMapping("worker/service")
|
||||
@ResponseBody
|
||||
public AjaxResult getServiceCategoriesByWorker(Long workerId) {
|
||||
List<WorkerGoodsCategory> list = workerGoodsCategoryService.getByWorkerIdAndType(workerId, 1);
|
||||
for (WorkerGoodsCategory item: list) {
|
||||
List<String> nameList = new ArrayList<String>();
|
||||
// 查询所有父级服务类目,拼接服务名称
|
||||
GoodsCategory goodsCategory = goodsCategoryService.selectById(item.getGoodsCategoryId());
|
||||
while (goodsCategory.getParentCategoryId() != null) {
|
||||
nameList.add(goodsCategory.getGoodsCategoryName());
|
||||
goodsCategory = goodsCategoryService.selectById(goodsCategory.getParentCategoryId());
|
||||
}
|
||||
Collections.reverse(nameList);
|
||||
item.setMergeName(StringUtils.join(nameList, Constants.JOIN_SYMBOL));
|
||||
}
|
||||
return AjaxResult.success(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询某个师傅的商品类目(类型2)
|
||||
*
|
||||
* @param workerId 师傅ID
|
||||
*/
|
||||
@GetMapping("worker/goods")
|
||||
@ResponseBody
|
||||
public AjaxResult getGoodsCategoriesByWorker(Long workerId) {
|
||||
List<WorkerGoodsCategory> list = workerGoodsCategoryService.getByWorkerIdAndType(workerId, 2);
|
||||
for (WorkerGoodsCategory item: list) {
|
||||
List<String> nameList = new ArrayList<String>();
|
||||
// 查询所有父级服务类目,拼接服务名称
|
||||
GoodsCategory goodsCategory = goodsCategoryService.selectById(item.getGoodsCategoryId());
|
||||
while (goodsCategory.getParentCategoryId() != null) {
|
||||
nameList.add(goodsCategory.getGoodsCategoryName());
|
||||
goodsCategory = goodsCategoryService.selectById(goodsCategory.getParentCategoryId());
|
||||
}
|
||||
Collections.reverse(nameList);
|
||||
item.setMergeName(StringUtils.join(nameList, Constants.JOIN_SYMBOL));
|
||||
}
|
||||
return AjaxResult.success(list);
|
||||
}
|
||||
|
||||
@GetMapping("worker/edit")
|
||||
@ResponseBody
|
||||
public AjaxResult getEditWorker(Long workerId) {
|
||||
public AjaxResult getEditWorker(Long workerId, Integer type) {
|
||||
Map<Long, List<String>> twoMap = new HashMap<>();
|
||||
List<WorkerGoodsCategory> list = workerGoodsCategoryService.getByWorker(workerId);
|
||||
|
||||
// 根据类型查询对应的商品分类数据
|
||||
List<WorkerGoodsCategory> list;
|
||||
if (Integer.valueOf(1).equals(type)) {
|
||||
// 服务类型:查询服务商品分类
|
||||
list = workerGoodsCategoryService.getByWorkerIdAndType(workerId, 1);
|
||||
} else if (Integer.valueOf(2).equals(type)) {
|
||||
// 商品类型:查询商品分类
|
||||
list = workerGoodsCategoryService.getByWorkerIdAndType(workerId, 2);
|
||||
} else {
|
||||
// 不传类型:查询所有商品分类
|
||||
list = workerGoodsCategoryService.getByWorker(workerId);
|
||||
}
|
||||
|
||||
if(CollectionUtils.isEmpty(list)){
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
for (WorkerGoodsCategory item: list) {
|
||||
List<String> ids;
|
||||
GoodsCategory goodsCategory = goodsCategoryService.selectById(item.getGoodsCategoryId());
|
||||
|
|
@ -77,6 +178,7 @@ public class WorkerGoodsCategoryController {
|
|||
ids.add(String.valueOf(goodsCategory.getGoodsCategoryId()));
|
||||
twoMap.put(goodsCategory.getParentCategoryId(), ids);
|
||||
}
|
||||
|
||||
List<WorkerGoodsCategory> result = new ArrayList<>();
|
||||
for (Map.Entry<Long, List<String>> longListEntry : twoMap.entrySet()) {
|
||||
WorkerGoodsCategory model = new WorkerGoodsCategory();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
package com.ghy.web.core.config;
|
||||
|
||||
import com.aliyun.dytnsapi20200217.Client;
|
||||
import com.aliyun.teaopenapi.models.Config;
|
||||
import lombok.Data;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Data
|
||||
@Configuration
|
||||
public class AliApiConfig {
|
||||
|
||||
@Value("${aliyun.accessKey}")
|
||||
private String accessKey;
|
||||
|
||||
@Value("${aliyun.accessSecret}")
|
||||
private String accessSecret;
|
||||
|
||||
@Value("${aliyun.endpoint}")
|
||||
private String endpoint;
|
||||
|
||||
@Value("${aliyun.authCode}")
|
||||
private String authCode;
|
||||
|
||||
@Bean
|
||||
public Client createClient() throws Exception {
|
||||
// 建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378657.html。
|
||||
Config config = new Config()
|
||||
// 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
|
||||
.setAccessKeyId(accessKey)
|
||||
// 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
|
||||
.setAccessKeySecret(accessSecret)
|
||||
.setEndpoint(endpoint);
|
||||
return new Client(config);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -41,7 +41,7 @@ public class SwaggerConfig
|
|||
// 扫描所有有注解的api,用这种方式更灵活
|
||||
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
|
||||
// 扫描指定包中的swagger注解
|
||||
.apis(RequestHandlerSelectors.basePackage("com.ghy.web.controller.tool"))
|
||||
.apis(RequestHandlerSelectors.basePackage("com.ghy.web.controller.order"))
|
||||
// 扫描所有 .apis(RequestHandlerSelectors.any())
|
||||
.paths(PathSelectors.any())
|
||||
.build();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
package com.ghy.web.pojo.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class CertNoTwoElementReq {
|
||||
|
||||
private Long workerId;
|
||||
|
||||
private String certNo;
|
||||
|
||||
private String certName;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.ghy.web.pojo.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class InsuranceOrderEditReq {
|
||||
|
||||
private String requestNo;
|
||||
|
||||
private String channelCode = "NNDD0806QH";
|
||||
|
||||
private String sign;
|
||||
|
||||
private String orderNumber;
|
||||
|
||||
private String workName;
|
||||
|
||||
private String workerID;
|
||||
|
||||
private String shangmenTime;
|
||||
|
||||
private String shangmenNum;
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package com.ghy.web.pojo.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
public class InsuranceOrderReq {
|
||||
|
||||
private String requestNo;
|
||||
|
||||
private String channelCode = "NNDD0806QH";
|
||||
|
||||
private String sign;
|
||||
|
||||
private String orderNumber;
|
||||
|
||||
private String orderProductType = "0002";
|
||||
|
||||
private String orderStatus = "1";
|
||||
|
||||
private String orderStartat;
|
||||
|
||||
private String orderEndat;
|
||||
|
||||
private String customerAddress;
|
||||
|
||||
private String customerPhone;
|
||||
|
||||
private String workName;
|
||||
|
||||
private String workerID;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ import java.math.BigDecimal;
|
|||
|
||||
/**
|
||||
* 改价请求实体
|
||||
*
|
||||
* @author clunt
|
||||
*/
|
||||
@Data
|
||||
|
|
@ -21,4 +22,10 @@ public class OrderChangePriceRequest implements Serializable {
|
|||
private Integer type;
|
||||
|
||||
private String remark;
|
||||
|
||||
private String urls;
|
||||
|
||||
private String fileNames;
|
||||
|
||||
private String reason;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,4 +29,13 @@ public class OrderListRequest {
|
|||
private Integer shelveStatus;
|
||||
|
||||
private Integer allSelfAssigned;
|
||||
|
||||
/**
|
||||
* 是否超时 1=是 0=否
|
||||
*/
|
||||
private Integer timeout;
|
||||
|
||||
private Boolean needImgs = true;
|
||||
|
||||
private Integer orderType;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,10 +2,15 @@ package com.ghy.web.pojo.vo;
|
|||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.ghy.common.annotation.Excel;
|
||||
import com.ghy.goods.domain.Goods;
|
||||
import com.ghy.goods.domain.GoodsArea;
|
||||
import com.ghy.goods.domain.InsuranceManager;
|
||||
import com.ghy.order.domain.AfterServiceRecord;
|
||||
import com.ghy.payment.domain.FinancialChangeRecord;
|
||||
import com.ghy.payment.domain.OrderTimeoutRecord;
|
||||
import com.ghy.shop.domain.Shop;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
|
@ -15,16 +20,29 @@ import java.util.List;
|
|||
@Data
|
||||
public class OrderListResponse {
|
||||
|
||||
// 商品品牌 -- 后台发单才有
|
||||
private String goodsBrand;
|
||||
// 商品规格 -- 后台发单才有
|
||||
private String goodsSpecification;
|
||||
|
||||
private String totalName;
|
||||
|
||||
private String isCall;
|
||||
|
||||
private Long orderMasterId;
|
||||
|
||||
private String orderMasterCode;
|
||||
|
||||
private String originalOrderMasterCode;
|
||||
|
||||
private Long orderDetailId;
|
||||
|
||||
private String orderDetailCode;
|
||||
|
||||
private Long workerId;
|
||||
|
||||
private Long masterWorkerId;
|
||||
|
||||
private String workerName;
|
||||
|
||||
private String workerPhone;
|
||||
|
|
@ -35,6 +53,8 @@ public class OrderListResponse {
|
|||
|
||||
private String masterCompanyName;
|
||||
|
||||
private String masterCompanyPhone;
|
||||
|
||||
private String customerName;
|
||||
|
||||
private String customerPhone;
|
||||
|
|
@ -67,14 +87,23 @@ public class OrderListResponse {
|
|||
|
||||
private Integer orderStatus;
|
||||
|
||||
private String orderStatusName;
|
||||
|
||||
private Integer payStatus;
|
||||
|
||||
/**
|
||||
* 退款支付状态:0=未支付,1=已支付
|
||||
*/
|
||||
private Integer refundPayStatus;
|
||||
|
||||
private Integer payType;
|
||||
|
||||
private BigDecimal totalMoney;
|
||||
|
||||
private BigDecimal payMoney;
|
||||
|
||||
private BigDecimal payAddMoney;
|
||||
|
||||
private BigDecimal finalRecvMoney;
|
||||
|
||||
private BigDecimal changeMoney;
|
||||
|
|
@ -137,4 +166,174 @@ public class OrderListResponse {
|
|||
* 提现到账时间 arrival_time
|
||||
*/
|
||||
private Date arrivalTime;
|
||||
|
||||
/**
|
||||
* 是否超时 1=是 0=否
|
||||
*/
|
||||
private Integer timeout;
|
||||
|
||||
/**
|
||||
* 超时扣款次数
|
||||
*/
|
||||
private Integer timeoutFineTimes;
|
||||
|
||||
/**
|
||||
* 超时时间(用于排序)
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date timeoutTime;
|
||||
|
||||
private Integer afterTimeout;
|
||||
|
||||
private String orderMode;
|
||||
|
||||
/*是否合约订单*/
|
||||
private String consultMode;
|
||||
|
||||
private Goods goods;
|
||||
|
||||
/*是否有保险id*/
|
||||
private Long insuranceId;
|
||||
|
||||
private InsuranceManager insuranceManager;
|
||||
|
||||
private Long cityId;
|
||||
|
||||
/*街道id*/
|
||||
private Long streetId;
|
||||
|
||||
private Long provinceId;
|
||||
|
||||
private String name;
|
||||
private String phone;
|
||||
|
||||
private String provinceName;
|
||||
|
||||
private String cityName;
|
||||
|
||||
private String countryName;
|
||||
|
||||
private String streetName;
|
||||
|
||||
|
||||
private Long countryId;
|
||||
|
||||
/**
|
||||
* 是否为监控但
|
||||
* */
|
||||
private Boolean isMonitoredOrder;
|
||||
|
||||
private BigDecimal addMoney;
|
||||
|
||||
private String addMoneyRemark;
|
||||
|
||||
private BigDecimal paymentMoney;
|
||||
|
||||
/**
|
||||
* 是否已派发服务订单:0=未派发,1=已派发
|
||||
*/
|
||||
private Integer hasServiceOrder;
|
||||
|
||||
/**
|
||||
* 下单图片
|
||||
*/
|
||||
@Excel(name = "下单图片", cellType = Excel.ColumnType.STRING)
|
||||
private String orderImages;
|
||||
|
||||
/**
|
||||
* 是否发货到服务店:0=否,1=是
|
||||
*/
|
||||
@Excel(name = "是否发货到服务店", cellType = Excel.ColumnType.NUMERIC)
|
||||
private Integer isDeliveryToStore;
|
||||
|
||||
/**
|
||||
* 是否已开票:0=是,1=否
|
||||
*/
|
||||
@Excel(name = "是否已开票", cellType = Excel.ColumnType.NUMERIC, readConverterExp = "0=是,1=否")
|
||||
private Integer isInvoiced;
|
||||
|
||||
/**
|
||||
* 是否需要开票:0=不需要,1=需要
|
||||
*/
|
||||
@Excel(name = "是否需要开票", cellType = Excel.ColumnType.NUMERIC, readConverterExp = "0=不需要,1=需要")
|
||||
private Integer isNeedBill;
|
||||
|
||||
/**
|
||||
* 原师傅id(转单前的师傅)
|
||||
*/
|
||||
@Excel(name = "原师傅id", cellType = Excel.ColumnType.NUMERIC)
|
||||
private Long originalWorkerId;
|
||||
|
||||
|
||||
private Long serverGoodsId;
|
||||
|
||||
/**
|
||||
* 服务店铺ID
|
||||
*/
|
||||
private Long serviceShopId;
|
||||
|
||||
private Date confirmStartTime;
|
||||
|
||||
private Integer deliveryType;
|
||||
|
||||
private Long goodsId;
|
||||
|
||||
|
||||
/**
|
||||
* 发货备注
|
||||
*/
|
||||
@Excel(name = "发货备注", cellType = Excel.ColumnType.STRING)
|
||||
private String deliveryRemark;
|
||||
|
||||
/**
|
||||
* 发货图片
|
||||
*/
|
||||
@Excel(name = "发货图片", cellType = Excel.ColumnType.STRING)
|
||||
private String deliveryImages;
|
||||
|
||||
@Excel(name = "交货图片", cellType = Excel.ColumnType.STRING)
|
||||
private String handoverImages;
|
||||
|
||||
@Excel(name = "交货备注", cellType = Excel.ColumnType.STRING)
|
||||
private String handoverRemark;
|
||||
|
||||
/**
|
||||
* 快递单号
|
||||
*/
|
||||
private String trackingNumber;
|
||||
|
||||
|
||||
/**
|
||||
* 分账倒计时结束时间
|
||||
*/
|
||||
@Excel(name = "分账倒计时结束时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date shareAccountCountdownEndTime;
|
||||
|
||||
/**
|
||||
* 分账倒计时时长(小时)
|
||||
*/
|
||||
@Excel(name = "分账倒计时时长(小时)")
|
||||
private Integer shareAccountCountdownDuration;
|
||||
|
||||
private Shop shop;
|
||||
|
||||
private Shop serviceShop;
|
||||
private Long goodsOrderMasterId;
|
||||
|
||||
/**
|
||||
* 是否已撤销服务主单:0=未撤销,1=已撤销
|
||||
*/
|
||||
@Excel(name = "是否已撤销服务主单", cellType = Excel.ColumnType.NUMERIC, readConverterExp = "0=未撤销,1=已撤销")
|
||||
private Integer serviceCancelled;
|
||||
|
||||
/**
|
||||
* 是否显示售后记录:0=不显示,1=显示
|
||||
*/
|
||||
private Integer showAfterServiceRecord = 0;
|
||||
|
||||
@Excel(name = "是否显示在监控单", cellType = Excel.ColumnType.NUMERIC, readConverterExp = "0=不显示,1=显示在监控单")
|
||||
private Integer showInMonitor;
|
||||
|
||||
@Excel(name = "售后状态:0-无售后,1-售后纠纷,2-售后已完成,3-售后已取消")
|
||||
private Integer afterPlatformServiceStatus;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,4 +55,83 @@ public class OrderStandardDetail {
|
|||
private Boolean isOverTime;
|
||||
|
||||
private BigDecimal serverMoney;
|
||||
|
||||
/**
|
||||
* draw_cash_status
|
||||
* 0 未分账
|
||||
* 1 已分账
|
||||
* 2 已到账
|
||||
* -1 提现失败
|
||||
*/
|
||||
private Integer drawCashStatus;
|
||||
|
||||
/**
|
||||
* 发起提现时间 draw_cash_time
|
||||
*/
|
||||
private Date drawCashTime;
|
||||
|
||||
/**
|
||||
* 是否超时 1=是 0=否
|
||||
*/
|
||||
private Integer timeout;
|
||||
|
||||
/**
|
||||
* 超时扣款次数
|
||||
*/
|
||||
private Integer timeoutFineTimes;
|
||||
|
||||
private Integer afterTimeout;
|
||||
|
||||
private BigDecimal addMoney;
|
||||
|
||||
/**
|
||||
* 退单原因
|
||||
*/
|
||||
private String returnReason;
|
||||
|
||||
/**
|
||||
* 退单原因详情
|
||||
*/
|
||||
private String returnReasonDetail;
|
||||
|
||||
/**
|
||||
* 退单图片
|
||||
*/
|
||||
private String returnImages;
|
||||
|
||||
|
||||
/**
|
||||
* 发货类型 - 订单的发货方式
|
||||
*/
|
||||
private Integer deliveryType;
|
||||
|
||||
/**
|
||||
* 发货备注 - 发货相关备注信息
|
||||
*/
|
||||
private String deliveryRemark;
|
||||
|
||||
/**
|
||||
* 发货图片 - 发货凭证图片
|
||||
*/
|
||||
private String deliveryImages;
|
||||
|
||||
/**
|
||||
* 快递单号 - 物流跟踪单号
|
||||
*/
|
||||
private String trackingNumber;
|
||||
|
||||
|
||||
|
||||
private String handoverImages;
|
||||
|
||||
|
||||
private String handoverRemark;
|
||||
|
||||
private String orderImages;
|
||||
//= "售后状态:0-无售后,1-售后纠纷,2-售后已完成,3-售后已取消"
|
||||
private Integer afterPlatformServiceStatus;
|
||||
|
||||
private Integer payStatus;
|
||||
|
||||
private Integer refundPayStatus;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,4 +11,8 @@ import lombok.Data;
|
|||
@Data
|
||||
public class OrderStatisticsRequest {
|
||||
private Long workerId;
|
||||
|
||||
private Long deptId;
|
||||
|
||||
private Integer orderType;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
package com.ghy.web.pojo.vo;
|
||||
|
||||
import com.ghy.system.domain.SysGlobalConfig;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
/**
|
||||
* @Author 但星霖
|
||||
* @Date 2023-03-20 20:37:16
|
||||
* 说明:系统配置返回vo
|
||||
*/
|
||||
@Data
|
||||
@ToString
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
@Schema(description = "系统配置请求返回vo")
|
||||
public class SysGlobalConfigRequestVO {
|
||||
|
||||
@Schema(description = "配置项主键ID")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "配置项名称")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "配置项内容json串")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "排序号")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "描述")
|
||||
private String describe;
|
||||
|
||||
@Schema(description = "配置类型")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "数据内容类型")
|
||||
private Integer dataType;
|
||||
|
||||
@Schema(description = "单位")
|
||||
private String configUnit;
|
||||
|
||||
public static SysGlobalConfig toModel(SysGlobalConfigRequestVO vo){
|
||||
SysGlobalConfig sysConfig = new SysGlobalConfig();
|
||||
BeanUtils.copyProperties(vo, sysConfig);
|
||||
return sysConfig;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
package com.ghy.web.pojo.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.ghy.common.annotation.SysConstants;
|
||||
import com.ghy.common.enums.SysGlobalConfigDataTypeEnum;
|
||||
import com.ghy.common.enums.SysGlobalConfigEnum;
|
||||
import com.ghy.common.utils.ObjectVerifyUtils;
|
||||
import com.ghy.system.domain.SysGlobalConfig;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author 但星霖
|
||||
* @Date 2023-03-20 20:37:16
|
||||
* 说明:系统配置返回vo
|
||||
*/
|
||||
@Data
|
||||
@ToString
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
@Schema(description = "系统配置返回vo")
|
||||
public class SysGlobalConfigResponseVO {
|
||||
|
||||
@Schema(description = "配置项主键ID")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "配置项名称")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "配置项内容json串")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "排序号")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "描述")
|
||||
private String describe;
|
||||
|
||||
@Schema(description = "配置类型")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "配置类型枚举")
|
||||
private SysGlobalConfigEnum typeEnum;
|
||||
|
||||
@Schema(description = "配置类型Desc")
|
||||
private String typeEnumDesc;
|
||||
|
||||
@Schema(description = "数据内容类型")
|
||||
private Integer dataType;
|
||||
|
||||
@Schema(description = "数据内容类型")
|
||||
private SysGlobalConfigDataTypeEnum dataTypeEnum;
|
||||
|
||||
@Schema(description = "数据内容类型")
|
||||
private String dataTypeEnumDesc;
|
||||
|
||||
@Schema(description = "单位")
|
||||
private String configUnit;
|
||||
|
||||
@JsonInclude(value = JsonInclude.Include.NON_NULL)
|
||||
@JsonFormat(pattern = SysConstants.DATE_TIME_FORMAT, locale = "zh", timezone = "GMT+8")
|
||||
@Schema(description = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
@JsonInclude(value = JsonInclude.Include.NON_NULL)
|
||||
@JsonFormat(pattern = SysConstants.DATE_TIME_FORMAT, locale = "zh", timezone = "GMT+8")
|
||||
@Schema(description = "更新时间")
|
||||
private Date updateTime;
|
||||
|
||||
public static SysGlobalConfigResponseVO toVo(SysGlobalConfig model) {
|
||||
if (ObjectVerifyUtils.isNull(model)) {
|
||||
return null;
|
||||
}
|
||||
SysGlobalConfigResponseVO vo = new SysGlobalConfigResponseVO();
|
||||
BeanUtils.copyProperties(model, vo);
|
||||
// 配置类型
|
||||
if (ObjectVerifyUtils.isNotNull(model.getType())) {
|
||||
SysGlobalConfigEnum configEnum = SysGlobalConfigEnum.parse(model.getType());
|
||||
if (ObjectVerifyUtils.isNotNull(configEnum)) {
|
||||
vo.setTypeEnum(configEnum);
|
||||
vo.setTypeEnumDesc(configEnum.desc());
|
||||
}
|
||||
}
|
||||
// 配置类型数据类型
|
||||
if (ObjectVerifyUtils.isNotNull(model.getDataType())) {
|
||||
SysGlobalConfigDataTypeEnum sysConfigDataTypeEnum = SysGlobalConfigDataTypeEnum.parse(model.getDataType());
|
||||
if (ObjectVerifyUtils.isNotNull(sysConfigDataTypeEnum)) {
|
||||
vo.setDataTypeEnum(sysConfigDataTypeEnum);
|
||||
vo.setDataTypeEnumDesc(sysConfigDataTypeEnum.desc());
|
||||
}
|
||||
}
|
||||
// 时间类单独处理
|
||||
vo.setCreateTime(ObjectVerifyUtils.isNotNull(model.getCreateTime()) ? new Date(model.getCreateTime()) : null);
|
||||
vo.setUpdateTime(ObjectVerifyUtils.isNotNull(model.getUpdateTime()) ? new Date(model.getUpdateTime()) : null);
|
||||
return vo;
|
||||
}
|
||||
|
||||
public static List<SysGlobalConfigResponseVO> toVoList(List<SysGlobalConfig> sysConfigList) {
|
||||
List<SysGlobalConfigResponseVO> voList = new ArrayList<>();
|
||||
if (ObjectVerifyUtils.isNotEmpty(sysConfigList)) {
|
||||
sysConfigList.forEach(sysConfig -> voList.add(toVo(sysConfig)));
|
||||
}
|
||||
return voList;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
package com.ghy.web.pojo.vo;
|
||||
|
||||
import com.ghy.common.annotation.Excel;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class SysOrderRequest {
|
||||
|
||||
@Excel(name = "seq")
|
||||
private String seq;
|
||||
|
||||
@Excel(name = "category")
|
||||
private String category;
|
||||
|
||||
@Excel(name = "lastCategory")
|
||||
private String lastCategory;
|
||||
|
||||
@Excel(name = "brand")
|
||||
private String brand;
|
||||
|
||||
@Excel(name = "date")
|
||||
private String date;
|
||||
|
||||
@Excel(name = "time")
|
||||
private String time;
|
||||
|
||||
@Excel(name = "mode")
|
||||
private String mode;
|
||||
|
||||
@Excel(name = "num")
|
||||
private String num;
|
||||
|
||||
@Excel(name = "price")
|
||||
private String price;
|
||||
|
||||
@Excel(name = "name")
|
||||
private String name;
|
||||
|
||||
@Excel(name = "phone")
|
||||
private String phone;
|
||||
|
||||
@Excel(name = "address")
|
||||
private String address;
|
||||
|
||||
@Excel(name = "remark")
|
||||
private String remark;
|
||||
|
||||
@Excel(name = "money")
|
||||
private String money;
|
||||
|
||||
@Excel(name = "award")
|
||||
private String award;
|
||||
|
||||
@Excel(name = "infoMoney")
|
||||
private String infoMoney;
|
||||
|
||||
@Excel(name = "url")
|
||||
private String url;
|
||||
|
||||
@Excel(name = "logistics")
|
||||
private String logistics;
|
||||
|
||||
@Excel(name = "needHll")
|
||||
private String needHll;
|
||||
|
||||
@Excel(name = "bh")
|
||||
private String bh;
|
||||
|
||||
@Excel(name = "floor")
|
||||
private String floor;
|
||||
|
||||
@Excel(name = "floorUp")
|
||||
private String floorUp;
|
||||
|
||||
@Excel(name = "bhry")
|
||||
private String bhry;
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.ghy.web.pojo.vo;
|
||||
|
||||
import com.ghy.common.core.domain.BaseEntity;
|
||||
import com.ghy.worker.domain.Worker;
|
||||
import lombok.Data;
|
||||
|
||||
|
|
@ -10,7 +11,7 @@ import java.util.List;
|
|||
* @date : 2022-06-24 17:38
|
||||
*/
|
||||
@Data
|
||||
public class WorkerListRequest {
|
||||
public class WorkerListRequest extends BaseEntity {
|
||||
private Long areaId;
|
||||
|
||||
private List<Long> areaIds;
|
||||
|
|
@ -19,9 +20,25 @@ public class WorkerListRequest {
|
|||
|
||||
private String workerName;
|
||||
|
||||
private String workerPhone;
|
||||
|
||||
private Long workerId;
|
||||
|
||||
private Long exceptParentAreaId;
|
||||
|
||||
private boolean justShowCurWorkerArea;
|
||||
|
||||
private String keyWords;
|
||||
|
||||
private String provinceId;
|
||||
|
||||
private String cityId;
|
||||
|
||||
private String districtId;
|
||||
|
||||
private String streetId;
|
||||
|
||||
private String categoryLevel1;
|
||||
|
||||
private String categoryLevel2;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,9 +21,21 @@ public class WorkerSettledRequest {
|
|||
// 入驻区域
|
||||
private List<WorkerArea> workerAreas;
|
||||
|
||||
// 服务品类
|
||||
// 入驻商品区域
|
||||
private List<WorkerArea> workerGoodsAreas;
|
||||
|
||||
// 入驻服务类目
|
||||
private List<WorkerGoodsCategory> serviceCategories;
|
||||
|
||||
// 入驻商品类目
|
||||
private List<WorkerGoodsCategory> goodsCategories;
|
||||
|
||||
// 入驻服务类目ID列表(兼容旧版本)
|
||||
private List<Long> serviceCategoryIds;
|
||||
|
||||
// 入驻商品类目ID列表(兼容旧版本)
|
||||
private List<Long> goodsCategoryIds;
|
||||
|
||||
// 特殊技能
|
||||
// private List<WorkerSpecialSkill> specialSkills;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
package com.ghy.web.service;
|
||||
|
||||
import com.ghy.web.pojo.vo.CertNoTwoElementReq;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
/**
|
||||
* <p>阿里云api合集,二次包装在服务内</p>
|
||||
* @author clunt
|
||||
*/
|
||||
public interface AliCloudService {
|
||||
|
||||
void certNoTwoElementVerification(@RequestBody CertNoTwoElementReq certNoTwoElementReq) throws Exception;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.ghy.web.service;
|
||||
|
||||
import com.ghy.order.domain.OrderDetailInsuranceUser;
|
||||
|
||||
public interface InsuranceService {
|
||||
|
||||
void clockInsurance(Long orderDetailId) throws Exception;
|
||||
|
||||
void orderInsurance(String orderCode) throws Exception;
|
||||
|
||||
void editInsurance(OrderDetailInsuranceUser orderDetailInsuranceUser) throws Exception ;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.ghy.web.service.impl;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.aliyun.dytnsapi20200217.Client;
|
||||
import com.aliyun.dytnsapi20200217.models.CertNoTwoElementVerificationRequest;
|
||||
import com.aliyun.dytnsapi20200217.models.CertNoTwoElementVerificationResponse;
|
||||
import com.ghy.web.core.config.AliApiConfig;
|
||||
import com.ghy.web.pojo.vo.CertNoTwoElementReq;
|
||||
import com.ghy.web.service.AliCloudService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class AliCloudServiceImpl implements AliCloudService {
|
||||
|
||||
private final AliApiConfig aliApiConfig;
|
||||
|
||||
|
||||
@Override
|
||||
public void certNoTwoElementVerification(CertNoTwoElementReq certNoTwoElementReq) throws Exception{
|
||||
// 校验是否是历史记录
|
||||
Client client = aliApiConfig.createClient();
|
||||
CertNoTwoElementVerificationRequest request = new CertNoTwoElementVerificationRequest();
|
||||
request.setAuthCode(aliApiConfig.getAuthCode());
|
||||
request.setCertNo(certNoTwoElementReq.getCertNo());
|
||||
request.setCertName(certNoTwoElementReq.getCertName());
|
||||
log.info("调用身份证二要素校验接口,入参:{}", certNoTwoElementReq);
|
||||
CertNoTwoElementVerificationResponse response =client.certNoTwoElementVerification(request);
|
||||
log.info("调用身份证二要素校验接口,响应:{}", JSONUtil.toJsonStr(response.getBody()));
|
||||
Assert.isTrue("OK".equals(response.getBody().getCode()), Exception::new);
|
||||
Assert.isTrue("1".equals(response.getBody().getData().getIsConsistent()), "身份二要素验证失败!");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
package com.ghy.web.service.impl;
|
||||
|
||||
import cn.hutool.core.date.DateField;
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.ghy.common.utils.security.Md5Utils;
|
||||
import com.ghy.customer.domain.CustomerAddress;
|
||||
import com.ghy.customer.service.CustomerAddressService;
|
||||
import com.ghy.order.domain.OrderDetail;
|
||||
import com.ghy.order.domain.OrderDetailInsuranceUser;
|
||||
import com.ghy.order.domain.OrderMaster;
|
||||
import com.ghy.order.service.IOrderDetailInsuranceUserService;
|
||||
import com.ghy.order.service.OrderDetailService;
|
||||
import com.ghy.order.service.OrderMasterService;
|
||||
import com.ghy.web.pojo.vo.CertNoTwoElementReq;
|
||||
import com.ghy.web.pojo.vo.InsuranceOrderEditReq;
|
||||
import com.ghy.web.pojo.vo.InsuranceOrderReq;
|
||||
import com.ghy.web.service.InsuranceService;
|
||||
import com.ghy.worker.domain.Worker;
|
||||
import com.ghy.worker.domain.WorkerCertification;
|
||||
import com.ghy.worker.service.IWorkerCertificationService;
|
||||
import com.ghy.worker.service.WorkerService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class InsuranceServiceImpl implements InsuranceService {
|
||||
|
||||
private final static String Key = "96ndsd26k25jm";
|
||||
|
||||
private final static String baseUrl = "https://pre-hbhp-xianding.hzins.com/api/external/";
|
||||
|
||||
@Autowired
|
||||
private OrderMasterService orderMasterService;
|
||||
|
||||
@Autowired
|
||||
private CustomerAddressService customerAddressService;
|
||||
|
||||
@Autowired
|
||||
private WorkerService workerService;
|
||||
|
||||
@Autowired
|
||||
private OrderDetailService orderDetailService;
|
||||
|
||||
@Autowired
|
||||
private IOrderDetailInsuranceUserService orderDetailInsuranceUserService;
|
||||
|
||||
@Override
|
||||
public void orderInsurance(String orderCode) throws Exception{
|
||||
InsuranceOrderReq req = new InsuranceOrderReq();
|
||||
OrderMaster master = orderMasterService.selectByCode(orderCode);
|
||||
if(master.getInsuranceId() == null){
|
||||
return;
|
||||
}
|
||||
req.setOrderNumber(master.getCode());
|
||||
req.setRequestNo(master.getCode() + System.currentTimeMillis());
|
||||
req.setSign(Md5Utils.hash(req.getRequestNo() + req.getChannelCode() + Key));
|
||||
// 查询客户地址信息
|
||||
CustomerAddress customerAddress = customerAddressService.selectByCustomerAddressId(master.getAddressId());
|
||||
req.setCustomerAddress(customerAddress.getAddress());
|
||||
req.setCustomerPhone(customerAddress.getPhone());
|
||||
// 查师傅信息
|
||||
Worker worker = workerService.selectById(master.getWorkerId());
|
||||
CertNoTwoElementReq certNoTwoElementReq = JSONUtil.toBean(worker.getRemark(), CertNoTwoElementReq.class);
|
||||
req.setWorkerID(certNoTwoElementReq.getCertNo());
|
||||
req.setWorkName(certNoTwoElementReq.getCertName());
|
||||
req.setOrderStartat(DateUtil.format(DateUtil.offset(new Date(), DateField.SECOND, 30), DatePattern.NORM_DATETIME_PATTERN));
|
||||
req.setOrderEndat(DateUtil.format(DateUtil.offset(new Date(), DateField.DAY_OF_YEAR, 30),DatePattern.NORM_DATETIME_PATTERN));
|
||||
log.info("调用保险请求url:{},内容:{}", baseUrl+"/platInterface/order", JSONUtil.toJsonStr(req));
|
||||
String result = HttpUtil.post(baseUrl+"/platInterface/order", JSONUtil.toJsonStr(req));
|
||||
log.info("调用保险返回内容:{}", result);
|
||||
if(!"1".equals(JSONObject.parseObject(result).getString("code")) && !JSONObject.parseObject(result).getString("msg").contains("已存在该工单")){
|
||||
throw new Exception(JSONObject.parseObject(result).getString("msg"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void editInsurance(OrderDetailInsuranceUser orderDetailInsuranceUser) throws Exception {
|
||||
// 查询子单
|
||||
OrderDetail detail = orderDetailService.selectById(orderDetailInsuranceUser.getOrderDetailId());
|
||||
// 查询主单
|
||||
OrderMaster master = orderMasterService.selectById(detail.getOrderMasterId());
|
||||
// 查师傅信息
|
||||
Worker worker = workerService.selectById(master.getWorkerId());
|
||||
CertNoTwoElementReq certNoTwoElementReq = JSONUtil.toBean(worker.getRemark(), CertNoTwoElementReq.class);
|
||||
// 查询主单下的所有子单
|
||||
List<OrderDetail> detailList = orderDetailService.selectByOrderMasterId(detail.getOrderMasterId());
|
||||
StringBuilder workerName = new StringBuilder();
|
||||
StringBuilder workerId = new StringBuilder();
|
||||
// 拼上主单信息
|
||||
workerName.append(certNoTwoElementReq.getCertName());
|
||||
workerId.append(certNoTwoElementReq.getCertNo());
|
||||
detailList.forEach(model->{
|
||||
OrderDetailInsuranceUser param = new OrderDetailInsuranceUser();
|
||||
param.setOrderDetailId(model.getId());
|
||||
List<OrderDetailInsuranceUser> users = orderDetailInsuranceUserService.selectOrderDetailInsuranceUserList(param);
|
||||
if(!CollectionUtils.isEmpty(users)){
|
||||
users.forEach(user->{
|
||||
workerName.append(",").append(user.getName());
|
||||
workerId.append(",").append(user.getIdCardNum());
|
||||
});
|
||||
}
|
||||
});
|
||||
// 再拼上 现在要加入的师傅的信息
|
||||
workerName.append(",").append(orderDetailInsuranceUser.getName());
|
||||
workerId.append(",").append(orderDetailInsuranceUser.getIdCardNum());
|
||||
InsuranceOrderEditReq editReq = new InsuranceOrderEditReq();
|
||||
editReq.setOrderNumber(master.getCode());
|
||||
editReq.setRequestNo(master.getCode() + System.currentTimeMillis());
|
||||
editReq.setSign(Md5Utils.hash(editReq.getRequestNo() + editReq.getChannelCode() + Key));
|
||||
editReq.setOrderNumber(master.getCode());
|
||||
editReq.setWorkName(workerName.toString());
|
||||
editReq.setWorkerID(workerId.toString());
|
||||
log.info("调用保险请求url:{},内容:{}", baseUrl+"/platInterface/updateOrder", JSONUtil.toJsonStr(editReq));
|
||||
String result = HttpUtil.post(baseUrl+"/platInterface/updateOrder", JSONUtil.toJsonStr(editReq));
|
||||
log.info("调用保险返回内容:{}", result);
|
||||
if(!"1".equals(JSONObject.parseObject(result).getString("code"))){
|
||||
throw new Exception(JSONObject.parseObject(result).getString("msg"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clockInsurance(Long orderDetailId) throws Exception {
|
||||
// 查询子单
|
||||
OrderDetail detail = orderDetailService.selectById(orderDetailId);
|
||||
// 查询主单
|
||||
OrderMaster master = orderMasterService.selectById(detail.getOrderMasterId());
|
||||
if(master.getInsuranceId() != null){
|
||||
InsuranceOrderEditReq editReq = new InsuranceOrderEditReq();
|
||||
editReq.setOrderNumber(master.getCode());
|
||||
editReq.setRequestNo(master.getCode() + System.currentTimeMillis());
|
||||
editReq.setSign(Md5Utils.hash(editReq.getRequestNo() + editReq.getChannelCode() + Key));
|
||||
editReq.setOrderNumber(master.getCode());
|
||||
editReq.setShangmenTime(DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN));
|
||||
editReq.setShangmenNum("1");
|
||||
log.info("调用保险请求url:{},内容:{}", baseUrl+"/platInterface/service", JSONUtil.toJsonStr(editReq));
|
||||
String result = HttpUtil.post(baseUrl+"/platInterface/service", JSONUtil.toJsonStr(editReq));
|
||||
log.info("调用保险返回内容:{}", result);
|
||||
if(!"1".equals(JSONObject.parseObject(result).getString("code"))){
|
||||
throw new Exception(JSONObject.parseObject(result).getString("msg"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,10 +3,16 @@ package com.ghy.web.timer;
|
|||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.ghy.common.adapay.model.AdapayStatusEnum;
|
||||
import com.ghy.common.enums.AdapayOrderType;
|
||||
import com.ghy.common.utils.AdapayUtils;
|
||||
import com.ghy.customer.domain.CustomerBank;
|
||||
import com.ghy.customer.service.CustomerBankService;
|
||||
import com.ghy.order.service.OrderDetailService;
|
||||
import com.ghy.payment.domain.DrawCashRecord;
|
||||
import com.ghy.payment.mapper.DrawCashRecordMapper;
|
||||
import com.ghy.payment.service.AdapayService;
|
||||
import com.ghy.worker.domain.WorkerBank;
|
||||
import com.ghy.worker.service.WorkerBankService;
|
||||
import com.huifu.adapay.core.exception.BaseAdaPayException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
|
@ -17,6 +23,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -32,10 +39,82 @@ public class AdapaySyncTimer {
|
|||
@Resource
|
||||
private AdapayService adapayService;
|
||||
@Resource
|
||||
private WorkerBankService workerBankService;
|
||||
@Resource
|
||||
private CustomerBankService customerBankService;
|
||||
@Resource
|
||||
private OrderDetailService orderDetailService;
|
||||
@Resource
|
||||
private DrawCashRecordMapper drawCashRecordMapper;
|
||||
|
||||
/**
|
||||
* 补偿提现定时器
|
||||
* 某些订单分账成功,但是提现失败,需要在这里为它重新发起提现
|
||||
*/
|
||||
@Scheduled(fixedRate = 5 * 60 * 1000L)
|
||||
public void autoDrawCash() {
|
||||
List<WorkerBank> workerBanks = workerBankService.select(new WorkerBank());
|
||||
for (WorkerBank workerBank : workerBanks) {
|
||||
Long deptId = workerBank.getDeptId();
|
||||
String memberId = workerBank.getAdapayMemberId();
|
||||
String settleAccountId = workerBank.getSettleAccountId();
|
||||
if (deptId == null || StringUtils.isBlank(memberId) || StringUtils.isBlank(settleAccountId)) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
JSONObject accountBalance = adapayService.queryAccountBalance(deptId, memberId, settleAccountId, "01");
|
||||
if (AdapayStatusEnum.succeeded.code.equals(accountBalance.getString("status"))) {
|
||||
// 可提现金额
|
||||
String avlBalance = accountBalance.getString("avl_balance");
|
||||
if (BigDecimal.ZERO.compareTo(new BigDecimal(avlBalance)) > -1) {
|
||||
continue;
|
||||
}
|
||||
// 提现
|
||||
log.info("Worker[{},{}]开始提现: avlBalance={}", workerBank.getWorkerId(), workerBank.getName(), avlBalance);
|
||||
String orderNo = AdapayUtils.createOrderNo(AdapayOrderType.DRAW_CASH);
|
||||
JSONObject drawCash = adapayService.drawCash(deptId, orderNo, "T1", avlBalance, memberId, "提现", null);
|
||||
log.info("Worker[{},{}]提现结果: {}", workerBank.getWorkerId(), workerBank.getName(), drawCash.toJSONString());
|
||||
} else {
|
||||
log.error("Worker[{},{}]查询账户余额失败: {}", workerBank.getWorkerId(), workerBank.getName(), accountBalance.toJSONString());
|
||||
}
|
||||
} catch (BaseAdaPayException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
List<CustomerBank> customerBanks = customerBankService.getCustomerBankList(new CustomerBank());
|
||||
for (CustomerBank customer : customerBanks) {
|
||||
Long deptId = customer.getDeptId();
|
||||
String memberId = customer.getAdapayMemberId();
|
||||
String settleAccountId = customer.getSettleAccountId();
|
||||
if (deptId == null || StringUtils.isBlank(memberId) || StringUtils.isBlank(settleAccountId)) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
JSONObject accountBalance = adapayService.queryAccountBalance(deptId, memberId, settleAccountId, "01");
|
||||
if (AdapayStatusEnum.succeeded.code.equals(accountBalance.getString("status"))) {
|
||||
// 可提现金额
|
||||
String avlBalance = accountBalance.getString("avl_balance");
|
||||
if (BigDecimal.ZERO.compareTo(new BigDecimal(avlBalance)) > -1) {
|
||||
continue;
|
||||
}
|
||||
// 提现
|
||||
log.info("Customer[{},{}]开始提现: avlBalance={}", customer.getCustomerId(), customer.getName(), avlBalance);
|
||||
String orderNo = AdapayUtils.createOrderNo(AdapayOrderType.DRAW_CASH);
|
||||
JSONObject drawCash = adapayService.drawCash(deptId, orderNo, "T1", avlBalance, memberId, "提现", null);
|
||||
log.info("Customer[{},{}]提现结果: {}", customer.getCustomerId(), customer.getName(), drawCash.toJSONString());
|
||||
} else {
|
||||
log.error("Customer[{},{}]查询账户余额失败: {}", customer.getCustomerId(), customer.getName(), accountBalance.toJSONString());
|
||||
}
|
||||
} catch (BaseAdaPayException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 定时同步提现状态
|
||||
*/
|
||||
@Scheduled(fixedRate = 5 * 60 * 1000L)
|
||||
public void syncDrawCash() {
|
||||
List<DrawCashRecord> records = drawCashRecordMapper.selectByStatus("pending");
|
||||
|
|
@ -75,7 +154,7 @@ public class AdapaySyncTimer {
|
|||
// 更新提现记录表状态
|
||||
drawCashRecordMapper.updateStatus(record.getId(), "succeeded");
|
||||
// 更新子订单表状态
|
||||
orderDetailService.updateDrawCashStatus(record.getId(), 2, new Date());
|
||||
orderDetailService.updateDrawCashStatus(record.getId(), 2, null, new Date());
|
||||
break;
|
||||
// 提现失败
|
||||
case "F":
|
||||
|
|
@ -83,7 +162,7 @@ public class AdapaySyncTimer {
|
|||
// 更新提现记录表状态
|
||||
drawCashRecordMapper.updateStatus(record.getId(), "failed");
|
||||
// 更新子订单表状态
|
||||
orderDetailService.updateDrawCashStatus(record.getId(), -1, null);
|
||||
orderDetailService.updateDrawCashStatus(record.getId(), -1, null, null);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ shiro:
|
|||
cipherKey:
|
||||
session:
|
||||
# Session超时时间,-1代表永不过期(默认30分钟)
|
||||
expireTime: 30
|
||||
expireTime: 720
|
||||
# 同步session到数据库的周期(默认1分钟)
|
||||
dbSyncPeriod: 1
|
||||
# 相隔多久检查一次session的有效性,默认就是10分钟
|
||||
|
|
@ -45,9 +45,9 @@ spring:
|
|||
druid:
|
||||
# 主库数据源
|
||||
master:
|
||||
url: jdbc:mysql://121.4.113.60:3306/gqz?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||
username: admin
|
||||
password: Clunt@12345
|
||||
url: jdbc:mysql://8.138.169.236:3306/gqz?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
|
||||
username: root
|
||||
password: clunt@12345
|
||||
# 从库数据源
|
||||
slave:
|
||||
# 从数据源开关/默认关闭
|
||||
|
|
@ -58,9 +58,9 @@ spring:
|
|||
# 初始连接数
|
||||
initialSize: 5
|
||||
# 最小连接池数量
|
||||
minIdle: 10
|
||||
minIdle: 5
|
||||
# 最大连接池数量
|
||||
maxActive: 20
|
||||
maxActive: 10
|
||||
# 配置获取连接等待超时的时间
|
||||
maxWait: 60000
|
||||
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ ruoyi:
|
|||
# 版权年份
|
||||
copyrightYear: 2021
|
||||
# 实例演示开关
|
||||
demoEnabled: true
|
||||
demoEnabled: false
|
||||
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
|
||||
profile: /home/ruoyi/uploadPath
|
||||
# 获取ip地址开关
|
||||
|
|
@ -16,7 +16,7 @@ ruoyi:
|
|||
# 开发环境配置
|
||||
server:
|
||||
# 服务器的HTTP端口,默认为80
|
||||
port: 80
|
||||
port: 19001
|
||||
servlet:
|
||||
# 应用的访问路径
|
||||
context-path: /
|
||||
|
|
@ -59,7 +59,7 @@ spring:
|
|||
time-zone: GMT+8
|
||||
date-format: yyyy-MM-dd HH:mm:ss
|
||||
profiles:
|
||||
active: dev
|
||||
active: druid
|
||||
# 文件上传
|
||||
servlet:
|
||||
multipart:
|
||||
|
|
@ -116,12 +116,12 @@ qiniu:
|
|||
accessKey: 'QTNOppkvtufxTxLjt1V7YZwvzV2Rc6WLD5yXLBVY'
|
||||
secretKey: 'V8SM9nkbO-dft4JmG7UaCH6RYxXdqzrvQ0zWO2W3'
|
||||
bucketName: 'gqz'
|
||||
mediaUrl: 'http://gqz.opsoul.com/'
|
||||
mediaUrl: 'https://gqz.opsoul.com/'
|
||||
|
||||
adapay:
|
||||
debug: true
|
||||
prod-mode: true
|
||||
notifyUrl: 'https://www.opsoul.com:8881/adapay/callback'
|
||||
notifyUrl: 'https://gmhl.gmjlb.com/adapay/callback'
|
||||
|
||||
jim:
|
||||
appKey: '110e8830290152d76e2f1d97'
|
||||
|
|
@ -130,7 +130,7 @@ jim:
|
|||
|
||||
# 百度地图应用api
|
||||
baidu:
|
||||
ak: 'ZQTgMW7W0GTuE7Ripb0HDp5TqRaOI6PZ'
|
||||
ak: 'i0sdnIsMmJVik7vJhfqMHA6DmS6d0fMB'
|
||||
url: 'https://api.map.baidu.com/reverse_geocoding/v3/?ak=#AK#&output=json&coordtype=wgs84ll&location='
|
||||
|
||||
sms:
|
||||
|
|
@ -138,3 +138,31 @@ sms:
|
|||
account: '8a216da85f008800015f0eb223620557'
|
||||
appId: '8a216da85f008800015f0eb224db055d'
|
||||
token: '3cef1bc80d814637a236d93004e7ffa5'
|
||||
|
||||
# 阿里云api接口, 这里是身份证二要素的
|
||||
aliyun:
|
||||
accessKey: LTAI5tDmv3T3Ze1Mt9wi5Be6
|
||||
accessSecret: EV4dzWRfKTQaPRjf3tFziMuVBCsThU
|
||||
endpoint: dytnsapi.aliyuncs.com
|
||||
authCode: od2FgE9a9g
|
||||
|
||||
# 物流API配置
|
||||
# logistics:
|
||||
# kdniao:
|
||||
# # 快递鸟 API配置
|
||||
# appId: '1889454' # 快递鸟应用ID,需要到快递鸟官网申请
|
||||
# appKey: 'b2483529-807d-49af-b0e1-1ed218baa4db' # 快递鸟API密钥,需要到快递鸟官网申请
|
||||
# url: 'https://api.kdniao.com/api/dist' # 快递鸟即时查询接口地址
|
||||
# 快递鸟支持两种接口:
|
||||
# 1. 即时查询接口:https://api.kdniao.com/api/dist
|
||||
# 2. 物流跟踪接口:https://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx
|
||||
|
||||
logistics:
|
||||
# 阿里云快递查询API配置
|
||||
aliyun:
|
||||
# 阿里云API网关AppCode,需要在阿里云市场购买快递查询服务后获取
|
||||
appCode: "78064b8aaa294f64ab07a285f129aea6"
|
||||
# API主机地址
|
||||
host: "https://kzexpress.market.alicloudapi.com"
|
||||
# API路径
|
||||
path: "/api-mall/api/express/query"
|
||||
|
|
@ -273,8 +273,7 @@
|
|||
var _defaultRootFlag = item[options.parentCode] == '0' ||
|
||||
item[options.parentCode] == 0 ||
|
||||
item[options.parentCode] == null ||
|
||||
item[options.parentCode] == '' ||
|
||||
$.inArray(item[options.code], parentCodes) > 0 && !rootFlag;
|
||||
item[options.parentCode] == '';
|
||||
if (!item[options.parentCode] || (_root ? (item[options.parentCode] == options.rootIdValue) : _defaultRootFlag)) {
|
||||
rootFlag = true;
|
||||
if (!target.data_list["_root_"]) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,164 @@
|
|||
* {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
html, body {
|
||||
height: 100%;
|
||||
}
|
||||
body {
|
||||
padding: 100px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.cascader-wrap {
|
||||
min-height: 40px;
|
||||
border: 1px solid #dcdfe6;
|
||||
box-sizing: border-box;
|
||||
border-radius: 4px;
|
||||
position: relative;
|
||||
z-index: 100;
|
||||
}
|
||||
.cascader-wrap:after {
|
||||
/*opacity: 1;*/
|
||||
content: "展开";
|
||||
padding: 5px 10px;
|
||||
background-color: #1d85c6;
|
||||
color: #feffff;
|
||||
border-radius: 4px;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
top: 12%;
|
||||
right: 5px;
|
||||
/*border-color: transparent transparent #888 transparent;*/
|
||||
/*border-style: solid;*/
|
||||
/*height: 0;*/
|
||||
/*margin-top: -2px;*/
|
||||
/*position: absolute;*/
|
||||
/*top: 50%;*/
|
||||
/*right: 10px;*/
|
||||
/*width: 0;*/
|
||||
/*border-width: 0 4px 5px 4px;*/
|
||||
/*transform: rotate(180deg);*/
|
||||
transition: all 0.1s;
|
||||
}
|
||||
.cascader-wrap.is-show:after {
|
||||
/*transform: rotate(0deg);*/
|
||||
content: "收起";
|
||||
background-color: #e82d2d;
|
||||
color: #feffff;
|
||||
}
|
||||
.cascader-wrap.is-show .eo-cascader-panel {
|
||||
display: block;
|
||||
display: flex;
|
||||
}
|
||||
.cascader-wrap .eo-clear-btn {
|
||||
display: none;
|
||||
}
|
||||
.cascader-wrap.is-clear .eo-clear-btn {
|
||||
font-style: normal;
|
||||
position: absolute;
|
||||
right: 7px;
|
||||
top: 50%;
|
||||
margin-top: -7px;
|
||||
font-size: 12px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border: 1px solid #c0c4cc;
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
line-height: 9px;
|
||||
color: #c0c4cc;
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
z-index: 9;
|
||||
}
|
||||
.cascader-wrap.is-clear:after {
|
||||
/*opacity: 0;*/
|
||||
}
|
||||
.eo-cascader-panel {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
top: 40px;
|
||||
left: 0;
|
||||
overflow: hidden;
|
||||
display: none;
|
||||
}
|
||||
.eo-cascader-menu {
|
||||
min-width: 200px;
|
||||
box-sizing: border-box;
|
||||
color: #606266;
|
||||
border-right: 1px solid #e4e7ed;
|
||||
position: relative;
|
||||
padding: 6px 0;
|
||||
max-height: 350px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.eo-cascader-menu:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
.eo-cascader-menu li {
|
||||
line-height: 30px;
|
||||
cursor: pointer;
|
||||
padding: 0 15px;
|
||||
position: relative;
|
||||
}
|
||||
.eo-cascader-menu li.has-child:after {
|
||||
content: '>';
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: -2px;
|
||||
transform: scaleY(1.8);
|
||||
font-size: 12px;
|
||||
color: #606266;
|
||||
}
|
||||
.eo-cascader-menu li:hover {
|
||||
background: #f5f7fa;
|
||||
}
|
||||
.eo-cascader-menu li span {
|
||||
margin-left: 6px;
|
||||
}
|
||||
.eo-checked-wrap {
|
||||
padding: 5px;
|
||||
position: relative;
|
||||
width: 90%;
|
||||
}
|
||||
.eo-checked-wrap li {
|
||||
display: flex;
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
line-height: 24px;
|
||||
margin: 2px 0 2px 0px;
|
||||
background: #f0f2f5;
|
||||
padding: 0 10px;
|
||||
height: 24px;
|
||||
border-radius: 4px;
|
||||
box-sizing: border-box;
|
||||
align-items: center;
|
||||
}
|
||||
.eo-checked-wrap li i {
|
||||
font-style: normal;
|
||||
margin-left: 10px;
|
||||
cursor: pointer;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
background: #c0c4cc;
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
line-height: 9px;
|
||||
color: #fff;
|
||||
}
|
||||
.eo-checked-wrap li p {
|
||||
margin: 0;
|
||||
}
|
||||
input[type="checkbox"].is-indeterminate {
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
background-color: #dfedff;
|
||||
-webkit-appearance: none;
|
||||
border: 1px solid #61aaff;
|
||||
border-radius: 2px;
|
||||
outline: none;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,28 @@
|
|||
(function(r){r.fn.qrcode=function(h){var s;function u(a){this.mode=s;this.data=a}function o(a,c){this.typeNumber=a;this.errorCorrectLevel=c;this.modules=null;this.moduleCount=0;this.dataCache=null;this.dataList=[]}function q(a,c){if(void 0==a.length)throw Error(a.length+"/"+c);for(var d=0;d<a.length&&0==a[d];)d++;this.num=Array(a.length-d+c);for(var b=0;b<a.length-d;b++)this.num[b]=a[b+d]}function p(a,c){this.totalCount=a;this.dataCount=c}function t(){this.buffer=[];this.length=0}u.prototype={getLength:function(){return this.data.length},
|
||||
write:function(a){for(var c=0;c<this.data.length;c++)a.put(this.data.charCodeAt(c),8)}};o.prototype={addData:function(a){this.dataList.push(new u(a));this.dataCache=null},isDark:function(a,c){if(0>a||this.moduleCount<=a||0>c||this.moduleCount<=c)throw Error(a+","+c);return this.modules[a][c]},getModuleCount:function(){return this.moduleCount},make:function(){if(1>this.typeNumber){for(var a=1,a=1;40>a;a++){for(var c=p.getRSBlocks(a,this.errorCorrectLevel),d=new t,b=0,e=0;e<c.length;e++)b+=c[e].dataCount;
|
||||
for(e=0;e<this.dataList.length;e++)c=this.dataList[e],d.put(c.mode,4),d.put(c.getLength(),j.getLengthInBits(c.mode,a)),c.write(d);if(d.getLengthInBits()<=8*b)break}this.typeNumber=a}this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17;this.modules=Array(this.moduleCount);for(var d=0;d<this.moduleCount;d++){this.modules[d]=Array(this.moduleCount);for(var b=0;b<this.moduleCount;b++)this.modules[d][b]=null}this.setupPositionProbePattern(0,0);this.setupPositionProbePattern(this.moduleCount-
|
||||
7,0);this.setupPositionProbePattern(0,this.moduleCount-7);this.setupPositionAdjustPattern();this.setupTimingPattern();this.setupTypeInfo(a,c);7<=this.typeNumber&&this.setupTypeNumber(a);null==this.dataCache&&(this.dataCache=o.createData(this.typeNumber,this.errorCorrectLevel,this.dataList));this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,c){for(var d=-1;7>=d;d++)if(!(-1>=a+d||this.moduleCount<=a+d))for(var b=-1;7>=b;b++)-1>=c+b||this.moduleCount<=c+b||(this.modules[a+d][c+b]=
|
||||
0<=d&&6>=d&&(0==b||6==b)||0<=b&&6>=b&&(0==d||6==d)||2<=d&&4>=d&&2<=b&&4>=b?!0:!1)},getBestMaskPattern:function(){for(var a=0,c=0,d=0;8>d;d++){this.makeImpl(!0,d);var b=j.getLostPoint(this);if(0==d||a>b)a=b,c=d}return c},createMovieClip:function(a,c,d){a=a.createEmptyMovieClip(c,d);this.make();for(c=0;c<this.modules.length;c++)for(var d=1*c,b=0;b<this.modules[c].length;b++){var e=1*b;this.modules[c][b]&&(a.beginFill(0,100),a.moveTo(e,d),a.lineTo(e+1,d),a.lineTo(e+1,d+1),a.lineTo(e,d+1),a.endFill())}return a},
|
||||
setupTimingPattern:function(){for(var a=8;a<this.moduleCount-8;a++)null==this.modules[a][6]&&(this.modules[a][6]=0==a%2);for(a=8;a<this.moduleCount-8;a++)null==this.modules[6][a]&&(this.modules[6][a]=0==a%2)},setupPositionAdjustPattern:function(){for(var a=j.getPatternPosition(this.typeNumber),c=0;c<a.length;c++)for(var d=0;d<a.length;d++){var b=a[c],e=a[d];if(null==this.modules[b][e])for(var f=-2;2>=f;f++)for(var i=-2;2>=i;i++)this.modules[b+f][e+i]=-2==f||2==f||-2==i||2==i||0==f&&0==i?!0:!1}},setupTypeNumber:function(a){for(var c=
|
||||
j.getBCHTypeNumber(this.typeNumber),d=0;18>d;d++){var b=!a&&1==(c>>d&1);this.modules[Math.floor(d/3)][d%3+this.moduleCount-8-3]=b}for(d=0;18>d;d++)b=!a&&1==(c>>d&1),this.modules[d%3+this.moduleCount-8-3][Math.floor(d/3)]=b},setupTypeInfo:function(a,c){for(var d=j.getBCHTypeInfo(this.errorCorrectLevel<<3|c),b=0;15>b;b++){var e=!a&&1==(d>>b&1);6>b?this.modules[b][8]=e:8>b?this.modules[b+1][8]=e:this.modules[this.moduleCount-15+b][8]=e}for(b=0;15>b;b++)e=!a&&1==(d>>b&1),8>b?this.modules[8][this.moduleCount-
|
||||
b-1]=e:9>b?this.modules[8][15-b-1+1]=e:this.modules[8][15-b-1]=e;this.modules[this.moduleCount-8][8]=!a},mapData:function(a,c){for(var d=-1,b=this.moduleCount-1,e=7,f=0,i=this.moduleCount-1;0<i;i-=2)for(6==i&&i--;;){for(var g=0;2>g;g++)if(null==this.modules[b][i-g]){var n=!1;f<a.length&&(n=1==(a[f]>>>e&1));j.getMask(c,b,i-g)&&(n=!n);this.modules[b][i-g]=n;e--; -1==e&&(f++,e=7)}b+=d;if(0>b||this.moduleCount<=b){b-=d;d=-d;break}}}};o.PAD0=236;o.PAD1=17;o.createData=function(a,c,d){for(var c=p.getRSBlocks(a,
|
||||
c),b=new t,e=0;e<d.length;e++){var f=d[e];b.put(f.mode,4);b.put(f.getLength(),j.getLengthInBits(f.mode,a));f.write(b)}for(e=a=0;e<c.length;e++)a+=c[e].dataCount;if(b.getLengthInBits()>8*a)throw Error("code length overflow. ("+b.getLengthInBits()+">"+8*a+")");for(b.getLengthInBits()+4<=8*a&&b.put(0,4);0!=b.getLengthInBits()%8;)b.putBit(!1);for(;!(b.getLengthInBits()>=8*a);){b.put(o.PAD0,8);if(b.getLengthInBits()>=8*a)break;b.put(o.PAD1,8)}return o.createBytes(b,c)};o.createBytes=function(a,c){for(var d=
|
||||
0,b=0,e=0,f=Array(c.length),i=Array(c.length),g=0;g<c.length;g++){var n=c[g].dataCount,h=c[g].totalCount-n,b=Math.max(b,n),e=Math.max(e,h);f[g]=Array(n);for(var k=0;k<f[g].length;k++)f[g][k]=255&a.buffer[k+d];d+=n;k=j.getErrorCorrectPolynomial(h);n=(new q(f[g],k.getLength()-1)).mod(k);i[g]=Array(k.getLength()-1);for(k=0;k<i[g].length;k++)h=k+n.getLength()-i[g].length,i[g][k]=0<=h?n.get(h):0}for(k=g=0;k<c.length;k++)g+=c[k].totalCount;d=Array(g);for(k=n=0;k<b;k++)for(g=0;g<c.length;g++)k<f[g].length&&
|
||||
(d[n++]=f[g][k]);for(k=0;k<e;k++)for(g=0;g<c.length;g++)k<i[g].length&&(d[n++]=i[g][k]);return d};s=4;for(var j={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,
|
||||
78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:1335,G18:7973,G15_MASK:21522,getBCHTypeInfo:function(a){for(var c=a<<10;0<=j.getBCHDigit(c)-j.getBCHDigit(j.G15);)c^=j.G15<<j.getBCHDigit(c)-j.getBCHDigit(j.G15);return(a<<10|c)^j.G15_MASK},getBCHTypeNumber:function(a){for(var c=a<<12;0<=j.getBCHDigit(c)-
|
||||
j.getBCHDigit(j.G18);)c^=j.G18<<j.getBCHDigit(c)-j.getBCHDigit(j.G18);return a<<12|c},getBCHDigit:function(a){for(var c=0;0!=a;)c++,a>>>=1;return c},getPatternPosition:function(a){return j.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,c,d){switch(a){case 0:return 0==(c+d)%2;case 1:return 0==c%2;case 2:return 0==d%3;case 3:return 0==(c+d)%3;case 4:return 0==(Math.floor(c/2)+Math.floor(d/3))%2;case 5:return 0==c*d%2+c*d%3;case 6:return 0==(c*d%2+c*d%3)%2;case 7:return 0==(c*d%3+(c+d)%2)%2;default:throw Error("bad maskPattern:"+
|
||||
a);}},getErrorCorrectPolynomial:function(a){for(var c=new q([1],0),d=0;d<a;d++)c=c.multiply(new q([1,l.gexp(d)],0));return c},getLengthInBits:function(a,c){if(1<=c&&10>c)switch(a){case 1:return 10;case 2:return 9;case s:return 8;case 8:return 8;default:throw Error("mode:"+a);}else if(27>c)switch(a){case 1:return 12;case 2:return 11;case s:return 16;case 8:return 10;default:throw Error("mode:"+a);}else if(41>c)switch(a){case 1:return 14;case 2:return 13;case s:return 16;case 8:return 12;default:throw Error("mode:"+
|
||||
a);}else throw Error("type:"+c);},getLostPoint:function(a){for(var c=a.getModuleCount(),d=0,b=0;b<c;b++)for(var e=0;e<c;e++){for(var f=0,i=a.isDark(b,e),g=-1;1>=g;g++)if(!(0>b+g||c<=b+g))for(var h=-1;1>=h;h++)0>e+h||c<=e+h||0==g&&0==h||i==a.isDark(b+g,e+h)&&f++;5<f&&(d+=3+f-5)}for(b=0;b<c-1;b++)for(e=0;e<c-1;e++)if(f=0,a.isDark(b,e)&&f++,a.isDark(b+1,e)&&f++,a.isDark(b,e+1)&&f++,a.isDark(b+1,e+1)&&f++,0==f||4==f)d+=3;for(b=0;b<c;b++)for(e=0;e<c-6;e++)a.isDark(b,e)&&!a.isDark(b,e+1)&&a.isDark(b,e+
|
||||
2)&&a.isDark(b,e+3)&&a.isDark(b,e+4)&&!a.isDark(b,e+5)&&a.isDark(b,e+6)&&(d+=40);for(e=0;e<c;e++)for(b=0;b<c-6;b++)a.isDark(b,e)&&!a.isDark(b+1,e)&&a.isDark(b+2,e)&&a.isDark(b+3,e)&&a.isDark(b+4,e)&&!a.isDark(b+5,e)&&a.isDark(b+6,e)&&(d+=40);for(e=f=0;e<c;e++)for(b=0;b<c;b++)a.isDark(b,e)&&f++;a=Math.abs(100*f/c/c-50)/5;return d+10*a}},l={glog:function(a){if(1>a)throw Error("glog("+a+")");return l.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;256<=a;)a-=255;return l.EXP_TABLE[a]},EXP_TABLE:Array(256),
|
||||
LOG_TABLE:Array(256)},m=0;8>m;m++)l.EXP_TABLE[m]=1<<m;for(m=8;256>m;m++)l.EXP_TABLE[m]=l.EXP_TABLE[m-4]^l.EXP_TABLE[m-5]^l.EXP_TABLE[m-6]^l.EXP_TABLE[m-8];for(m=0;255>m;m++)l.LOG_TABLE[l.EXP_TABLE[m]]=m;q.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var c=Array(this.getLength()+a.getLength()-1),d=0;d<this.getLength();d++)for(var b=0;b<a.getLength();b++)c[d+b]^=l.gexp(l.glog(this.get(d))+l.glog(a.get(b)));return new q(c,0)},mod:function(a){if(0>
|
||||
this.getLength()-a.getLength())return this;for(var c=l.glog(this.get(0))-l.glog(a.get(0)),d=Array(this.getLength()),b=0;b<this.getLength();b++)d[b]=this.get(b);for(b=0;b<a.getLength();b++)d[b]^=l.gexp(l.glog(a.get(b))+c);return(new q(d,0)).mod(a)}};p.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],
|
||||
[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,
|
||||
116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,
|
||||
43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,
|
||||
3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,
|
||||
55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,
|
||||
45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]];p.getRSBlocks=function(a,c){var d=p.getRsBlockTable(a,c);if(void 0==d)throw Error("bad rs block @ typeNumber:"+a+"/errorCorrectLevel:"+c);for(var b=d.length/3,e=[],f=0;f<b;f++)for(var h=d[3*f+0],g=d[3*f+1],j=d[3*f+2],l=0;l<h;l++)e.push(new p(g,j));return e};p.getRsBlockTable=function(a,c){switch(c){case 1:return p.RS_BLOCK_TABLE[4*(a-1)+0];case 0:return p.RS_BLOCK_TABLE[4*(a-1)+1];case 3:return p.RS_BLOCK_TABLE[4*
|
||||
(a-1)+2];case 2:return p.RS_BLOCK_TABLE[4*(a-1)+3]}};t.prototype={get:function(a){return 1==(this.buffer[Math.floor(a/8)]>>>7-a%8&1)},put:function(a,c){for(var d=0;d<c;d++)this.putBit(1==(a>>>c-d-1&1))},getLengthInBits:function(){return this.length},putBit:function(a){var c=Math.floor(this.length/8);this.buffer.length<=c&&this.buffer.push(0);a&&(this.buffer[c]|=128>>>this.length%8);this.length++}};"string"===typeof h&&(h={text:h});h=r.extend({},{render:"canvas",width:256,height:256,typeNumber:-1,
|
||||
correctLevel:2,background:"#ffffff",foreground:"#000000"},h);return this.each(function(){var a;if("canvas"==h.render){a=new o(h.typeNumber,h.correctLevel);a.addData(h.text);a.make();var c=document.createElement("canvas");c.width=h.width;c.height=h.height;for(var d=c.getContext("2d"),b=h.width/a.getModuleCount(),e=h.height/a.getModuleCount(),f=0;f<a.getModuleCount();f++)for(var i=0;i<a.getModuleCount();i++){d.fillStyle=a.isDark(f,i)?h.foreground:h.background;var g=Math.ceil((i+1)*b)-Math.floor(i*b),
|
||||
j=Math.ceil((f+1)*b)-Math.floor(f*b);d.fillRect(Math.round(i*b),Math.round(f*e),g,j)}}else{a=new o(h.typeNumber,h.correctLevel);a.addData(h.text);a.make();c=r("<table></table>").css("width",h.width+"px").css("height",h.height+"px").css("border","0px").css("border-collapse","collapse").css("background-color",h.background);d=h.width/a.getModuleCount();b=h.height/a.getModuleCount();for(e=0;e<a.getModuleCount();e++){f=r("<tr></tr>").css("height",b+"px").appendTo(c);for(i=0;i<a.getModuleCount();i++)r("<td></td>").css("width",
|
||||
d+"px").css("background-color",a.isDark(e,i)?h.foreground:h.background).appendTo(f)}}a=c;jQuery(a).appendTo(this)})}})(jQuery);
|
||||
|
|
@ -0,0 +1,596 @@
|
|||
/**
|
||||
* Name: 级联选择器控件
|
||||
* Version: 2020-06-16
|
||||
* Author: 王海峰 <wanghaifeng@iyiou.com>
|
||||
* Function List:
|
||||
* 1. 级联面板 - 支持多选 - 单选
|
||||
* 2. 支持回显已选中数据的完整路径 父级-父级-子级(可通过配置项 separator 自定义分隔符)
|
||||
* 3. 支持删除单个选中的数据项
|
||||
* 4. 支持一键删除所有选中数据项(可通过配置项 clearable 是否启用改功能)
|
||||
* 5. 接口: 一键获取所选中的所有文本数组
|
||||
* 6. 接口: 一键获取所选中的所有ID数组
|
||||
*/
|
||||
|
||||
(function() {
|
||||
/**
|
||||
* cascader_node 适配器模式
|
||||
* 将用户传入的数据通过该适配器进行处理
|
||||
* 数据驱动的思路,一个 CascaderNode 实例对应一个数据项(不管是子级还是父级)
|
||||
*/
|
||||
var cascader_node = function () {
|
||||
/**
|
||||
* @param {Object} data 数据
|
||||
* @param {Object} config 配置项
|
||||
* @param {Object} parentNode 父级 递归时传入
|
||||
*/
|
||||
function CascaderNode(data, config, parentNode) {
|
||||
this.data = data // 原始数据
|
||||
this.config = config // 配置项
|
||||
this.indeterminate = false // 该父级下的子级是否全选,用于控制父级显示状态(只有子级全选,父级才全选)
|
||||
this.parent = parentNode || null // 该项的父级
|
||||
this.level = !this.parent ? 1 : this.parent.level + 1 // 等级序列号
|
||||
this.uid = data[config.value] // 数据ID
|
||||
// 因是数据驱动的方式,一个数据项对应一个DOM,DOM选中与否
|
||||
this.checked = false // 该项数据是否选中
|
||||
this.initState()
|
||||
this.initChildren()
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
CascaderNode.prototype.initState = function initState() {
|
||||
var _config = this.config,
|
||||
valueKey = _config.value,
|
||||
labelKey = _config.label
|
||||
|
||||
this.value = this.data[valueKey]
|
||||
this.label = this.data[labelKey]
|
||||
this.pathNodes = this.calculatePathNodes()
|
||||
this.path = this.pathNodes.map(function (node) {
|
||||
return node.value
|
||||
})
|
||||
this.pathLabels = this.pathNodes.map(function (node) {
|
||||
return node.label
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化该数据下的子级
|
||||
* 内部通过递归生成 CascaderNode 实例,即子级
|
||||
*/
|
||||
CascaderNode.prototype.initChildren = function initChildren() {
|
||||
var _this = this
|
||||
var config = this.config
|
||||
var childrenKey = config.children
|
||||
var childrenData = this.data[childrenKey]
|
||||
this.hasChildren = Array.isArray(childrenData)
|
||||
this.children = (childrenData || []).map(function (child) {
|
||||
return new CascaderNode(child, config, _this)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算路径
|
||||
*/
|
||||
CascaderNode.prototype.calculatePathNodes = function calculatePathNodes() {
|
||||
var nodes = [this]
|
||||
var parent = this.parent
|
||||
|
||||
while (parent) {
|
||||
nodes.unshift(parent)
|
||||
parent = parent.parent
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取该项的路径(包含父级+)
|
||||
*/
|
||||
CascaderNode.prototype.getPath = function getPath() {
|
||||
return this.path
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取该项的路径(不包含父级)
|
||||
*/
|
||||
CascaderNode.prototype.getValue = function getPath() {
|
||||
return this.value
|
||||
}
|
||||
|
||||
/**
|
||||
* 多选 - 父级选中操作,让所有子级选中
|
||||
* @param {Boolean} checked
|
||||
*/
|
||||
CascaderNode.prototype.onParentCheck = function onParentCheck(checked) {
|
||||
var child = this.children.length ? this.children : this
|
||||
this.checked = checked
|
||||
this.indeterminate = false
|
||||
this.doAllCheck(child, checked)
|
||||
}
|
||||
|
||||
/**
|
||||
* 多选 - 父级选中时,子级全选
|
||||
* @param {Array} child
|
||||
* @param {Boolean} checked
|
||||
*/
|
||||
CascaderNode.prototype.doAllCheck = function doAllCheck(child, checked) {
|
||||
var _this = this
|
||||
if (Array.isArray(child) && child.length) {
|
||||
child.forEach(function (c) {
|
||||
c.checked = checked
|
||||
c.indeterminate = false
|
||||
_this.doAllCheck(c.children, checked)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 多选 - 子级选中,操作父级
|
||||
* @param {*} checked
|
||||
*/
|
||||
CascaderNode.prototype.onChildCheck = function onChildCheck(checked) {
|
||||
this.checked = checked
|
||||
var parent = this.parent
|
||||
var isChecked = parent.children.every(function (child) {
|
||||
return child.checked
|
||||
})
|
||||
this.setCheckState(this.parent, isChecked);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置父级相应的状态
|
||||
* 当该项有同级,且都没有选中,父级为 无选中 状态: 口
|
||||
* 当该项有同级,且同级的所有数据都为选中时,父级为 选中 状态:√
|
||||
* 当该项有同级,但同级中有且只有一项没有被选中,父级为 半选中 状态: -
|
||||
* @param {Object} parent
|
||||
* @param {Boolean} isChecked
|
||||
*/
|
||||
CascaderNode.prototype.setCheckState = function setCheckState(parent, isChecked) {
|
||||
parent.checked = isChecked
|
||||
var totalNum = parent.children.length;
|
||||
var checkedNum = parent.children.reduce(function (c, p) {
|
||||
var num = p.checked ? 1 : p.indeterminate ? 0.5 : 0;
|
||||
return c + num;
|
||||
}, 0);
|
||||
parent.indeterminate = checkedNum !== totalNum && checkedNum > 0;
|
||||
parent.parent && this.setCheckState(parent.parent, isChecked)
|
||||
}
|
||||
|
||||
return CascaderNode
|
||||
}()
|
||||
|
||||
/**
|
||||
* eo_cascader 生成级联选择器
|
||||
* 绑定相关事件、操作数据、渲染选择器、 回显选中列表
|
||||
*/
|
||||
var eo_cascader = function () {
|
||||
// 默认配置
|
||||
var defaultConfig = {
|
||||
disabled: 'disabled',
|
||||
emitPath: true,
|
||||
value: 'id',
|
||||
label: 'label',
|
||||
children: 'children'
|
||||
}
|
||||
/**
|
||||
* 级联选择器构造函数
|
||||
* @param {Array} data
|
||||
* @param {Object} config
|
||||
*/
|
||||
function EoCascader(data, config) {
|
||||
this.config = Object.assign(defaultConfig, config) || null
|
||||
this.multiple = config.multiple // 是否多选
|
||||
this.separator = config.separator // 自定义数据之间分隔符
|
||||
this.data = data // 原始数据
|
||||
this.clearable = config.clearable // 是否可一键清空
|
||||
this.panelShowState = false // 控制级联选择器显示
|
||||
this.storageChecked = {} // 存储已选中的数据项
|
||||
this.checkedText = [] // 选中的文本
|
||||
this.checkedID = [] // 选中的ID
|
||||
this.ele = document.getElementById(config.elementID) // DOM容器
|
||||
this.panelWrap = this.initPanel() // 级联选择器DOM容器
|
||||
this.checkedWrap = this.initCheckedWrap() // 回显选中列表DOM容器
|
||||
this.checkedCallback = config.checkedCallback || (() => {});
|
||||
this.initNodes(data)
|
||||
this.initEvents()
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件绑定
|
||||
*/
|
||||
EoCascader.prototype.initEvents = function initEvents(e) {
|
||||
this.ele.addEventListener('click', this.bindCascaderClick.bind(this))
|
||||
document.body.addEventListener('click', this.bindBodyClick.bind(this), true)
|
||||
if(this.clearable) {
|
||||
this.ele.addEventListener('mouseover', this.bindCascaderHover.bind(this))
|
||||
this.ele.addEventListener('mouseout', this.bindCascaderOut.bind(this))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* body点击隐藏级联面板
|
||||
*/
|
||||
EoCascader.prototype.bindBodyClick = function bindCascaderClick(e) {
|
||||
if(e.target.tagName !== 'BODY') return
|
||||
this.panelShowState = false
|
||||
this.ele.className = 'cascader-wrap'
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击容器控制切换级联面板显示
|
||||
*/
|
||||
EoCascader.prototype.bindCascaderClick = function bindCascaderClick(e) {
|
||||
e.stopPropagation();
|
||||
if(e.target.id !== this.ele.id ) return
|
||||
this.panelShowState = !this.panelShowState
|
||||
this.ele.className = this.panelShowState? 'cascader-wrap is-show': 'cascader-wrap'
|
||||
}
|
||||
|
||||
/**
|
||||
* 当且仅当 clearable 为 true 时绑定
|
||||
* 鼠标移入容器,显示一键清空按钮
|
||||
*/
|
||||
EoCascader.prototype.bindCascaderHover = function bindCascaderHover(e) {
|
||||
e.stopPropagation();
|
||||
if(e.target.id !== this.ele.id && e.target.className !== 'eo-clear-btn' ) return
|
||||
if(JSON.stringify(this.storageChecked) !== '{}') {
|
||||
this.ele.className = this.panelShowState? 'cascader-wrap is-show is-clear': 'cascader-wrap is-clear'
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 当且仅当 clearable 为 true 时绑定
|
||||
* 鼠标移出容器,隐藏一键清空按钮
|
||||
*/
|
||||
EoCascader.prototype.bindCascaderOut = function bindCascaderOut(e) {
|
||||
e.stopPropagation();
|
||||
if(e.target.id !== this.ele.id) return
|
||||
this.ele.className = this.panelShowState? 'cascader-wrap is-show': 'cascader-wrap'
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态生成级联面板DOM容器
|
||||
*/
|
||||
EoCascader.prototype.initPanel = function initPanel() {
|
||||
var panel = document.createElement('div')
|
||||
panel.className = 'eo-cascader-panel'
|
||||
return panel
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态生成回显选中列表DOM容器
|
||||
*/
|
||||
EoCascader.prototype.initCheckedWrap = function initCheckedWrap() {
|
||||
var checkedWrap = document.createElement('div')
|
||||
checkedWrap.className = 'eo-checked-wrap'
|
||||
return checkedWrap
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态生成一键清空按钮
|
||||
*/
|
||||
EoCascader.prototype.initClearDom = function initClearDom() {
|
||||
var clearBtn = document.createElement('i')
|
||||
clearBtn.className = 'eo-clear-btn'
|
||||
clearBtn.innerHTML = 'x'
|
||||
var _this = this
|
||||
// 绑定事件,初始化所有数据,重新渲染级联面板
|
||||
clearBtn.addEventListener('click', function(e) {
|
||||
e.stopPropagation();
|
||||
_this.storageChecked = {}
|
||||
_this.checkedCallback();
|
||||
_this.config.checkedValue = null
|
||||
_this.checkedText = []
|
||||
_this.checkedID = []
|
||||
_this.initNodes(_this.data)
|
||||
_this.initCheckedLi()
|
||||
_this.panelWrap.style.top = _this.ele.offsetHeight + 2 + 'px'
|
||||
})
|
||||
return clearBtn
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过 CascaderNode 适配器对原始数据进行改造,并赋值给当前构造函数的 nodes 对象
|
||||
* @param {Array} data 用户传入的原始数据
|
||||
*/
|
||||
EoCascader.prototype.initNodes = function initNodes(data) {
|
||||
var _this = this
|
||||
this.nodes = data.map(function (nodeData) {
|
||||
// 访问适配器
|
||||
return new cascader_node(nodeData, _this.config)
|
||||
})
|
||||
// 级联面板
|
||||
this.menus = [this.nodes]
|
||||
// 当为编辑页面时,往往需要回显上次提交的数据,即,
|
||||
// 如果存在 checkedValue
|
||||
// 那么调用 findChecked 方法,通过传入的已选 ID,渲染级联面板、回显列表
|
||||
// 反之,根据初始数据正常渲染即可
|
||||
this.config.checkedValue ? this.findChecked(this.config.checkedValue) : this.createNodes(this.menus)
|
||||
// 如果可一键清空,动态添加清空按钮
|
||||
this.clearable && this.ele.appendChild(this.initClearDom())
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} currentMenu 级联面板中,当前的点击项
|
||||
* 点击同级项时,通过操作 menus,使对应的子级进行渲染
|
||||
*/
|
||||
EoCascader.prototype.renderNodes = function (currentMenu) {
|
||||
// 操作 menus
|
||||
var menus = this.menus.slice(0, currentMenu.level)
|
||||
currentMenu.children.length && menus.push(currentMenu.children)
|
||||
this.menus = menus
|
||||
var wrap = this.panelWrap
|
||||
var wrapChild = wrap.children
|
||||
// 操作DOM
|
||||
for (let j = currentMenu.level; j < wrap.children.length; j++) {
|
||||
wrap.removeChild(wrapChild[j])
|
||||
j = j - 1
|
||||
}
|
||||
return menus
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据驱动的方式,通过 menus 渲染DOM
|
||||
* 每次操作 menus,增删都需要修改 menus,进而再次调用改方法进行渲染
|
||||
* @param {Array} menus 级联面板数据
|
||||
*/
|
||||
EoCascader.prototype.createNodes = function (menus) {
|
||||
var wrap = this.panelWrap
|
||||
wrap.innerHTML = ''
|
||||
var _this = this
|
||||
|
||||
for (let i = 0; i < menus.length; i++) {
|
||||
var menu = document.createElement('div')
|
||||
menu.className = 'eo-cascader-menu'
|
||||
var ul = document.createElement('ul')
|
||||
var menusList = menus[i];
|
||||
for (let k = 0; k < menusList.length; k++) {
|
||||
var li = document.createElement('li')
|
||||
if(menusList[k].children.length) li.className = 'has-child'
|
||||
// 当且仅当多选时 创建 label checkbox
|
||||
if(_this.multiple) {
|
||||
var label = document.createElement('label')
|
||||
var checkbox = document.createElement('input')
|
||||
checkbox.type = 'checkbox'
|
||||
checkbox.checked = menusList[k].checked
|
||||
checkbox.setAttribute('uid', menusList[k].uid)
|
||||
|
||||
checkbox.className = menusList[k].indeterminate ? 'is-indeterminate' : ''
|
||||
|
||||
|
||||
checkbox.addEventListener('click', _this.bindClickEvent.bind(checkbox,
|
||||
_this, _this.handleCheckCb)
|
||||
)
|
||||
|
||||
label.appendChild(checkbox)
|
||||
li.appendChild(label)
|
||||
}
|
||||
// 创建文本
|
||||
var span = document.createElement('span')
|
||||
span.innerHTML = menusList[k]['label']
|
||||
span.setAttribute('uid', menusList[k].uid)
|
||||
li.addEventListener('click', _this.bindClickEvent.bind(span, _this, _this.handleDanxuanCb))
|
||||
// 将 label 及 文本追加到 li
|
||||
li.appendChild(span)
|
||||
ul.appendChild(li)
|
||||
}
|
||||
menu.appendChild(ul)
|
||||
wrap.appendChild(menu)
|
||||
wrap.style.top = _this.ele.offsetHeight + 2 + 'px'
|
||||
}
|
||||
this.ele.appendChild(wrap)
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击 checkbox 和 文本回调函数
|
||||
* @param {this} _this 当前实例
|
||||
* @param {Function} cb 回调函数
|
||||
* 当且仅当点击 checkbox 时,传入 cb
|
||||
*/
|
||||
EoCascader.prototype.bindClickEvent = function bindClickEvent(_this, cb) {
|
||||
var uid = this.getAttribute('uid')
|
||||
var _thisMenu = _this.menus.flat(Infinity).filter(function (menu) {
|
||||
return menu.uid == uid
|
||||
})
|
||||
typeof cb === 'function' && cb.call(this, _thisMenu, _this, this.checked)
|
||||
_this.createNodes(_this.renderNodes(_thisMenu[0]))
|
||||
}
|
||||
|
||||
EoCascader.prototype.handleDanxuanCb = function handleDanxuanCb(currentMenu, _this) {
|
||||
if(_this.multiple) return
|
||||
var child = currentMenu[0].children
|
||||
if(!child.length) {
|
||||
_this.storageChecked = {};
|
||||
_this.storageChecked[currentMenu[0].uid] = {};
|
||||
_this.storageChecked[currentMenu[0].uid].pathLabels = currentMenu[0].pathLabels
|
||||
_this.storageChecked[currentMenu[0].uid].path = currentMenu[0].path
|
||||
_this.checkedWrap.innerHTML = ''
|
||||
// 渲染回显列表
|
||||
_this.initCheckedLi()
|
||||
_this.checkedCallback();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击 checkbox 触发回调
|
||||
* 内部对父级、子级选中状态进行修改
|
||||
* 同时对选中的数据进行存储,调用渲染回显列表函数
|
||||
* @param {Array} currentMenu 当前点击的面板项
|
||||
* @param {this} _this
|
||||
* @param {Boolean} isChecked
|
||||
*/
|
||||
EoCascader.prototype.handleCheckCb = function handleCheckCb(currentMenu, _this, isChecked) {
|
||||
// 如果当前点击项为第一级,那么让所有子级都选中
|
||||
// 如果当前项有父级,设置父级选中状态
|
||||
if (currentMenu[0].level !== 1) {
|
||||
currentMenu[0].onChildCheck(isChecked)
|
||||
}
|
||||
currentMenu[0].onParentCheck(isChecked)
|
||||
|
||||
// 存储当前选中状态
|
||||
currentMenu[0].children.length ?
|
||||
_this.showReviewCheckedOb(currentMenu[0]) :
|
||||
_this.handleReviewCheckedOb(currentMenu[0])
|
||||
|
||||
_this.checkedWrap.innerHTML = ''
|
||||
// 渲染回显列表
|
||||
_this.initCheckedLi()
|
||||
}
|
||||
|
||||
EoCascader.prototype.initCheckedLi = function () {
|
||||
var ul = document.createElement('ul')
|
||||
var _this = this
|
||||
if(JSON.stringify(this.storageChecked) === '{}') {
|
||||
return this.checkedWrap.innerHTML = ''
|
||||
}
|
||||
for (const key in this.storageChecked) {
|
||||
if (this.storageChecked.hasOwnProperty(key)) {
|
||||
var li = document.createElement('li')
|
||||
var p = document.createElement('p')
|
||||
var i = document.createElement('i')
|
||||
li.setAttribute('uid', key)
|
||||
p.innerHTML = this.storageChecked[key].pathLabels.join(_this.separator)
|
||||
i.innerHTML = 'x'
|
||||
|
||||
i.addEventListener('click', function () {
|
||||
var uidd = this.parentElement.getAttribute('uid')
|
||||
delete _this.storageChecked[uidd]
|
||||
var fn = function (parent) {
|
||||
for (let i = 0; i < parent.length; i++) {
|
||||
if (parent[i].children.length) {
|
||||
fn(parent[i].children)
|
||||
} else {
|
||||
if (parent[i].uid == uidd) {
|
||||
_this.handleCheckCb([parent[i]], _this, false)
|
||||
_this.createNodes(_this.menus)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fn(_this.nodes)
|
||||
})
|
||||
li.appendChild(p)
|
||||
li.appendChild(i)
|
||||
ul.appendChild(li)
|
||||
_this.checkedWrap.appendChild(ul)
|
||||
}
|
||||
}
|
||||
this.ele.appendChild(this.checkedWrap)
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据编辑页面传入的已选ID数组,修改面板数据 menus
|
||||
* @param {Array} uidArr
|
||||
*/
|
||||
EoCascader.prototype.findChecked = function (uidArr) {
|
||||
var _this = this
|
||||
// 获取上次已经提交过的三级标签
|
||||
var checkedNodesMatch = []
|
||||
var nodes = this.nodes
|
||||
var recursionFn = function (parent) {
|
||||
for (let i = 0; i < parent.length; i++) {
|
||||
if (parent[i].children.length) {
|
||||
recursionFn(parent[i].children)
|
||||
} else {
|
||||
if (uidArr.includes(parent[i].uid)) {
|
||||
parent[i].checked = true
|
||||
_this.handleCheckCb([parent[i]], _this, true)
|
||||
checkedNodesMatch.push(parent[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
recursionFn(nodes)
|
||||
|
||||
var menus = []
|
||||
var getMenusMatch = function (menu) {
|
||||
if (menu.parent) {
|
||||
menus.push(menu.parent.children)
|
||||
return getMenusMatch(menu.parent)
|
||||
}
|
||||
}
|
||||
|
||||
getMenusMatch(checkedNodesMatch[0])
|
||||
|
||||
menus.reverse().forEach(function (m) {
|
||||
_this.menus.push(m)
|
||||
})
|
||||
_this.createNodes(this.menus)
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归的找到当前 node 下最后一个子级,并将其存入 storageChecked 中
|
||||
* @param {Object} node
|
||||
*/
|
||||
EoCascader.prototype.showReviewCheckedOb = function (node) {
|
||||
if (!node.children.length) {
|
||||
this.handleReviewCheckedOb(node)
|
||||
} else {
|
||||
for (let k = 0; k < node.children.length; k++) {
|
||||
this.showReviewCheckedOb(node.children[k])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果当前 node 已选中,存入 storageChecked 中,反之删除 storageChecked 中的当前 node
|
||||
* @param {Object} node
|
||||
*/
|
||||
EoCascader.prototype.handleReviewCheckedOb = function (node) {
|
||||
if (node.checked) {
|
||||
this.storageChecked[node.uid] = {};
|
||||
this.storageChecked[node.uid].pathLabels = node.pathLabels;
|
||||
this.storageChecked[node.uid].path = node.path;
|
||||
} else {
|
||||
delete this.storageChecked[node.uid]
|
||||
}
|
||||
this.checkedCallback();
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口:获取所有选中的文本
|
||||
*/
|
||||
EoCascader.prototype.getCheckedByText = function () {
|
||||
this.checkedText = []
|
||||
for (const key in this.storageChecked) {
|
||||
if (this.storageChecked.hasOwnProperty(key)) {
|
||||
this.checkedText.push(this.storageChecked[key].pathLabels.join(this.separator))
|
||||
}
|
||||
}
|
||||
return this.checkedText
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口:获取所有选中的ID
|
||||
*/
|
||||
EoCascader.prototype.getCheckedByID = function () {
|
||||
this.checkedID = []
|
||||
for (const key in this.storageChecked) {
|
||||
if (this.storageChecked.hasOwnProperty(key)) {
|
||||
this.checkedID.push(key - 0)
|
||||
}
|
||||
}
|
||||
return this.checkedID
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口:获取所有层级id
|
||||
*/
|
||||
EoCascader.prototype.getCheckedPaths = function () {
|
||||
this.checkedPaths = []
|
||||
for (const key in this.storageChecked) {
|
||||
if (this.storageChecked.hasOwnProperty(key)) {
|
||||
this.checkedPaths.push(this.storageChecked[key].path)
|
||||
}
|
||||
}
|
||||
return this.checkedPaths
|
||||
}
|
||||
|
||||
return EoCascader
|
||||
}()
|
||||
|
||||
window.eo_cascader = eo_cascader
|
||||
|
||||
}(window))
|
||||
|
|
@ -391,7 +391,7 @@ var table = {
|
|||
importTemplate: function() {
|
||||
$.get(activeWindow().table.options.importTemplateUrl, function(result) {
|
||||
if (result.code == web_status.SUCCESS) {
|
||||
window.location.href = ctx + "common/download?fileName=" + encodeURI(result.msg) + "&delete=" + true;
|
||||
window.location.href = "http://gqz.opsoul.com/%E6%89%B9%E9%87%8F%E4%B8%8B%E5%8D%95%E5%AF%BC%E5%85%A5%E6%A8%A1%E6%9D%BF.xls";
|
||||
} else if (result.code == web_status.WARNING) {
|
||||
$.modal.alertWarning(result.msg)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,41 @@ $(function() {
|
|||
var url = ctx + "captcha/captchaImage?type=" + captchaType + "&s=" + Math.random();
|
||||
$(".imgcode").attr("src", url);
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
dataType:"json",
|
||||
url: ctx + "system/dept/list",
|
||||
data: { parentId: 100 },
|
||||
success: function (data) {
|
||||
$.each(data, function (index, value) {
|
||||
$('#deptId').append("<option value=" + value.deptId + ">" + value.deptName + "</option>");
|
||||
});
|
||||
}
|
||||
})
|
||||
// $('#deptId').select2({
|
||||
// placeholder: '请选择公司编码',
|
||||
// minimumResultsForSearch: -1,
|
||||
// ajax: {
|
||||
// type: "POST",
|
||||
// dataType:"json",
|
||||
// url: ctx + "system/dept/list",
|
||||
// data: { parentId: 100 },
|
||||
// processResults: function (data) {
|
||||
// var processedData = [];
|
||||
// $.each(data, function (index, value) {
|
||||
// processedData.push({
|
||||
// id: value.deptId,
|
||||
// text: value.deptName
|
||||
// })
|
||||
// });
|
||||
// return {
|
||||
// results: processedData
|
||||
// };
|
||||
// },
|
||||
// cache: true
|
||||
// }
|
||||
// });
|
||||
});
|
||||
|
||||
$.validator.setDefaults({
|
||||
|
|
@ -16,6 +51,8 @@ $.validator.setDefaults({
|
|||
function register() {
|
||||
$.modal.loading($("#btnSubmit").data("loading"));
|
||||
var username = $.common.trim($("input[name='username']").val());
|
||||
var phonenumber = $.common.trim($("input[name='phonenumber']").val());
|
||||
var deptId = $.common.trim($('#deptId').val());
|
||||
var password = $.common.trim($("input[name='password']").val());
|
||||
var validateCode = $("input[name='validateCode']").val();
|
||||
$.ajax({
|
||||
|
|
@ -23,6 +60,8 @@ function register() {
|
|||
url: ctx + "register",
|
||||
data: {
|
||||
"loginName": username,
|
||||
"phonenumber": phonenumber,
|
||||
"deptId": deptId,
|
||||
"password": password,
|
||||
"validateCode": validateCode
|
||||
},
|
||||
|
|
@ -49,15 +88,23 @@ function register() {
|
|||
|
||||
function validateRule() {
|
||||
var icon = "<i class='fa fa-times-circle'></i> ";
|
||||
$.validator.addMethod("checkPhone",function(value,element,params){
|
||||
var regex = /^1[345678]\d{9}$/;
|
||||
return regex.test(value);
|
||||
}, "请输入正确的手机号码");
|
||||
$("#registerForm").validate({
|
||||
rules: {
|
||||
username: {
|
||||
required: true,
|
||||
minlength: 2
|
||||
rangelength: [2,20]
|
||||
},
|
||||
phonenumber: {
|
||||
required: true,
|
||||
checkPhone: true
|
||||
},
|
||||
password: {
|
||||
required: true,
|
||||
minlength: 5
|
||||
rangelength: [5,20]
|
||||
},
|
||||
confirmPassword: {
|
||||
required: true,
|
||||
|
|
@ -66,15 +113,18 @@ function validateRule() {
|
|||
},
|
||||
messages: {
|
||||
username: {
|
||||
required: icon + "请输入您的用户名",
|
||||
minlength: icon + "用户名不能小于2个字符"
|
||||
required: icon + "请输入用户名",
|
||||
rangelength: icon + "账户长度必须在2到20个字符之间"
|
||||
},
|
||||
phonenumber: {
|
||||
required: icon + "请输入手机号码"
|
||||
},
|
||||
password: {
|
||||
required: icon + "请输入您的密码",
|
||||
minlength: icon + "密码不能小于5个字符",
|
||||
required: icon + "请输入密码",
|
||||
rangelength: icon + "密码长度必须在5到20个字符之间"
|
||||
},
|
||||
confirmPassword: {
|
||||
required: icon + "请再次输入您的密码",
|
||||
required: icon + "请再次输入密码",
|
||||
equalTo: icon + "两次密码输入不一致"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
|
||||
<head>
|
||||
<th:block th:include="include :: header('新增发单加价记录')" />
|
||||
</head>
|
||||
<body class="white-bg">
|
||||
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
|
||||
<form class="form-horizontal m" id="form-record-add">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label is-required">订单id:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="orderId" class="form-control" type="text" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label is-required">申请师傅:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="workerId" class="form-control" type="text" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label is-required">报价金额:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="addMoney" class="form-control" type="text" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">备注:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="remark" class="form-control" type="text">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<th:block th:include="include :: footer" />
|
||||
<script th:inline="javascript">
|
||||
var prefix = ctx + "worker/record"
|
||||
$("#form-record-add").validate({
|
||||
focusCleanup: true
|
||||
});
|
||||
|
||||
function submitHandler() {
|
||||
if ($.validate.form()) {
|
||||
$.operate.save(prefix + "/add", $('#form-record-add').serialize());
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
|
||||
<head>
|
||||
<th:block th:include="include :: header('修改发单加价记录')" />
|
||||
</head>
|
||||
<body class="white-bg">
|
||||
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
|
||||
<form class="form-horizontal m" id="form-record-edit" th:object="${orderAddRecord}">
|
||||
<input name="id" th:field="*{id}" type="hidden">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label is-required">订单id:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="orderId" th:field="*{orderId}" class="form-control" type="text" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label is-required">申请师傅:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="workerId" th:field="*{workerId}" class="form-control" type="text" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label is-required">报价金额:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="addMoney" th:field="*{addMoney}" class="form-control" type="text" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">备注:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="remark" th:field="*{remark}" class="form-control" type="text">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<th:block th:include="include :: footer" />
|
||||
<script th:inline="javascript">
|
||||
var prefix = ctx + "worker/record";
|
||||
$("#form-record-edit").validate({
|
||||
focusCleanup: true
|
||||
});
|
||||
|
||||
function submitHandler() {
|
||||
if ($.validate.form()) {
|
||||
$.operate.save(prefix + "/edit", $('#form-record-edit').serialize());
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
|
||||
<head>
|
||||
<th:block th:include="include :: header('发单加价记录列表')" />
|
||||
</head>
|
||||
<body class="gray-bg">
|
||||
<div class="container-div">
|
||||
<div class="row">
|
||||
<div class="col-sm-12 search-collapse">
|
||||
<form id="formId">
|
||||
<div class="select-list">
|
||||
<ul>
|
||||
<li>
|
||||
<label>订单id:</label>
|
||||
<input type="text" name="orderId"/>
|
||||
</li>
|
||||
<li>
|
||||
<label>申请师傅:</label>
|
||||
<input type="text" name="workerId"/>
|
||||
</li>
|
||||
<li>
|
||||
<label>报价金额:</label>
|
||||
<input type="text" name="addMoney"/>
|
||||
</li>
|
||||
<li>
|
||||
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i> 搜索</a>
|
||||
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i> 重置</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="btn-group-sm" id="toolbar" role="group">
|
||||
<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="worker:record:add">
|
||||
<i class="fa fa-plus"></i> 添加
|
||||
</a>
|
||||
<a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="worker:record:edit">
|
||||
<i class="fa fa-edit"></i> 修改
|
||||
</a>
|
||||
<a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="worker:record:remove">
|
||||
<i class="fa fa-remove"></i> 删除
|
||||
</a>
|
||||
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="worker:record:export">
|
||||
<i class="fa fa-download"></i> 导出
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-sm-12 select-table table-striped">
|
||||
<table id="bootstrap-table"></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<th:block th:include="include :: footer" />
|
||||
<script th:inline="javascript">
|
||||
var editFlag = [[${@permission.hasPermi('worker:record:edit')}]];
|
||||
var removeFlag = [[${@permission.hasPermi('worker:record:remove')}]];
|
||||
var prefix = ctx + "worker/record";
|
||||
|
||||
$(function() {
|
||||
var options = {
|
||||
url: prefix + "/list",
|
||||
createUrl: prefix + "/add",
|
||||
updateUrl: prefix + "/edit/{id}",
|
||||
removeUrl: prefix + "/remove",
|
||||
exportUrl: prefix + "/export",
|
||||
modalName: "发单加价记录",
|
||||
columns: [{
|
||||
checkbox: true
|
||||
},
|
||||
{
|
||||
field: 'id',
|
||||
title: '主键',
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
field: 'orderId',
|
||||
title: '订单id'
|
||||
},
|
||||
{
|
||||
field: 'workerId',
|
||||
title: '申请师傅'
|
||||
},
|
||||
{
|
||||
field: 'addMoney',
|
||||
title: '报价金额'
|
||||
},
|
||||
{
|
||||
field: 'status',
|
||||
title: '状态 01初始 02选中'
|
||||
},
|
||||
{
|
||||
field: 'remark',
|
||||
title: '备注'
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
align: 'center',
|
||||
formatter: function(value, row, index) {
|
||||
var actions = [];
|
||||
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.id + '\')"><i class="fa fa-edit"></i>编辑</a> ');
|
||||
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.id + '\')"><i class="fa fa-remove"></i>删除</a>');
|
||||
return actions.join('');
|
||||
}
|
||||
}]
|
||||
};
|
||||
$.table.init(options);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<th:block th:include="include :: header('')"/>
|
||||
<th:block th:include="include :: select2-css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div class="main-content">
|
||||
<form id="form-goods-add" class="form-horizontal">
|
||||
<h4 class="form-header h4">基本信息</h4>
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label is-required">主订单已发布更新提示音:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="orderMasterHaveReleasedUrl" id="orderMasterHaveReleasedUrl" placeholder="主订单已发布更新提示音" class="form-control" type="text"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label is-required">主订单新订单更新提示音:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="orderMasterNewOrderUrl" id="orderMasterNewOrderUrl" placeholder="主订单新订单更新提示音" class="form-control" type="text"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label is-required">子订单售后更新提示音:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="orderDetailsAfterUrl" id="orderDetailsAfterUrl" placeholder="子订单售后更新提示音" class="form-control" type="text"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label is-required">子订单售后纠纷更新提示音:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="orderDetailsAfterSalesDisputeUrl" id="orderDetailsAfterSalesDisputeUrl" placeholder="子订单售后纠纷更新提示音" class="form-control" type="text"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn btn-primary btn-rounded btn-sm" onclick="tijiao()">提交</a>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<th:block th:include="include :: footer"/>
|
||||
<th:block th:include="include :: select2-js"/>
|
||||
|
||||
<script>
|
||||
var prefix = ctx + "goods/goods";
|
||||
|
||||
var id = "";
|
||||
var name = "";
|
||||
var sort = "";
|
||||
var describe = "";
|
||||
var type = "";
|
||||
var dataType = "";
|
||||
var configUnit = "";
|
||||
|
||||
//请求接口加载页面输入框值
|
||||
function globalConfiginit(){
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
dataType:"json",
|
||||
url: "/config/globalConfig/search/type/1001",
|
||||
data: { },
|
||||
success: function (data) {
|
||||
id = data.data.id;
|
||||
name = data.data.name;
|
||||
sort = data.data.sort;
|
||||
describe = data.data.describe;
|
||||
type = data.data.type;
|
||||
dataType = data.data.dataType;
|
||||
configUnit = data.data.configUnit;
|
||||
//alert(data.data.content);
|
||||
var response = JSON.parse(data.data.content);
|
||||
$('#orderMasterHaveReleasedUrl').val(response.orderMasterHaveReleasedUrl);
|
||||
$('#orderMasterNewOrderUrl').val(response.orderMasterNewOrderUrl);
|
||||
$('#orderDetailsAfterUrl').val(response.orderDetailsAfterUrl);
|
||||
$('#orderDetailsAfterSalesDisputeUrl').val(response.orderDetailsAfterSalesDisputeUrl);
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//页面加载
|
||||
window.onload = function () {
|
||||
//请求接口加载页面输入框值
|
||||
globalConfiginit();
|
||||
}
|
||||
|
||||
//提交按钮
|
||||
function tijiao(){
|
||||
$.ajax({
|
||||
type: "PUT",
|
||||
dataType:"json",
|
||||
contentType: 'application/json',
|
||||
url: "/config/globalConfig/update",
|
||||
data: JSON.stringify({
|
||||
id: id,
|
||||
name: name,
|
||||
content: JSON.stringify({
|
||||
"orderMasterHaveReleasedUrl":$('#orderMasterHaveReleasedUrl').val(),
|
||||
"orderMasterNewOrderUrl":$('#orderMasterNewOrderUrl').val(),
|
||||
"orderDetailsAfterUrl":$('#orderDetailsAfterUrl').val(),
|
||||
"orderDetailsAfterSalesDisputeUrl":$('#orderDetailsAfterSalesDisputeUrl').val()
|
||||
}),
|
||||
sort: sort,
|
||||
describe: describe,
|
||||
type: type,
|
||||
dataType: dataType,
|
||||
unit: configUnit
|
||||
}),
|
||||
success: function (data) {
|
||||
if(data.code == 0){
|
||||
//请求接口加载页面输入框值
|
||||
globalConfiginit();
|
||||
alert("成功");
|
||||
}else {
|
||||
alert("失败");
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
|
||||
<head>
|
||||
<th:block th:include="include :: header('修改上级分销')" />
|
||||
</head>
|
||||
<body class="white-bg">
|
||||
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
|
||||
<form class="form-horizontal m" id="form-change-insurance">
|
||||
<input name="customerId" type="hidden" th:value="${customerId}" />
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">上级分销:</label>
|
||||
<div class="col-sm-8">
|
||||
<select id="customerPlace" name="customerPlace" class="form-control control-label" required>
|
||||
<option th:each="customerPlace:${customerPlaces}" th:value="${customerPlace.customerId}" th:text="${customerPlace.phone} + ${customerPlace.placeName}" ></option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<th:block th:include="include :: footer" />
|
||||
<script type="text/javascript">
|
||||
function submitHandler() {
|
||||
if ($.validate.form()) {
|
||||
$.operate.save(ctx + "customer/changePlace", $('#form-change-insurance').serialize());
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
@ -118,6 +118,22 @@
|
|||
field: 'phone',
|
||||
title: '手机号'
|
||||
},
|
||||
{
|
||||
field: 'customerPlaceName',
|
||||
title: '上级分销'
|
||||
},
|
||||
{
|
||||
field: 'customerPlacePhone',
|
||||
title: '上级手机号'
|
||||
},
|
||||
{
|
||||
field: 'parentCustomerPlaceName',
|
||||
title: '最上级分销'
|
||||
},
|
||||
{
|
||||
field: 'parentCustomerPlacePhone',
|
||||
title: '最上级手机号'
|
||||
},
|
||||
{
|
||||
field: 'openId',
|
||||
title: '微信唯一id',
|
||||
|
|
@ -130,7 +146,8 @@
|
|||
var actions = [];
|
||||
actions.push('<img class="img-circle" src="' + row.customerLogoUrl + '" alt="消费者头像" />');
|
||||
return actions.join('');
|
||||
}
|
||||
},
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
visible: editFlag == 'hidden' ? false : true,
|
||||
|
|
@ -151,6 +168,7 @@
|
|||
formatter: function(value, row, index) {
|
||||
if (row.customerId != 1) {
|
||||
var actions = [];
|
||||
actions.push('<a class="btn btn-success btn-xs " href="javascript:void(0)" onclick="changePlace(\'' + row.customerId + '\')"></i>修改上级分销</a> ');
|
||||
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.customerId + '\')"><i class="fa fa-remove"></i>删除</a> ');
|
||||
return actions.join('');
|
||||
} else {
|
||||
|
|
@ -162,6 +180,11 @@
|
|||
$.table.init(options);
|
||||
}
|
||||
|
||||
function changePlace(customerId) {
|
||||
var url = ctx + "customer/changePlace/" + customerId;
|
||||
$.modal.open("修改上级分销", url, '600', '300');
|
||||
}
|
||||
|
||||
|
||||
/* 用户管理-重置密码 */
|
||||
function resetPwd(customerId) {
|
||||
|
|
|
|||
|
|
@ -42,9 +42,9 @@
|
|||
<a class="btn btn-danger multiple disabled" onclick="auditStatus(1)" shiro:hasPermission="customer:place:remove">
|
||||
<i class="fa fa-remove"></i> 拒绝
|
||||
</a>
|
||||
<a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="customer:place:edit">
|
||||
<i class="fa fa-edit"></i> 修改
|
||||
</a>
|
||||
<!-- <a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="customer:place:edit">-->
|
||||
<!-- <i class="fa fa-edit"></i> 修改-->
|
||||
<!-- </a>-->
|
||||
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="customer:place:export">
|
||||
<i class="fa fa-download"></i> 导出
|
||||
</a>
|
||||
|
|
@ -79,17 +79,33 @@
|
|||
field: 'name',
|
||||
title: '名字'
|
||||
},
|
||||
{
|
||||
field: 'customerId',
|
||||
title: '关联消费者id'
|
||||
},
|
||||
// {
|
||||
// field: 'customerId',
|
||||
// title: '关联消费者id'
|
||||
// },
|
||||
{
|
||||
field: 'phone',
|
||||
title: '注册手机号'
|
||||
},
|
||||
{
|
||||
field: 'city',
|
||||
title: '城市id'
|
||||
field: 'customerPlaceName',
|
||||
title: '上级分销'
|
||||
},
|
||||
{
|
||||
field: 'customerPlacePhone',
|
||||
title: '上级手机号'
|
||||
},
|
||||
{
|
||||
field: 'parentCustomerPlaceName',
|
||||
title: '最上级分销'
|
||||
},
|
||||
{
|
||||
field: 'parentCustomerPlacePhone',
|
||||
title: '最上级手机号'
|
||||
},
|
||||
{
|
||||
field: 'cityName',
|
||||
title: '城市名'
|
||||
},
|
||||
{
|
||||
field: 'status',
|
||||
|
|
@ -107,7 +123,7 @@
|
|||
align: 'center',
|
||||
formatter: function(value, row, index) {
|
||||
var actions = [];
|
||||
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.id + '\')"><i class="fa fa-edit"></i>编辑</a> ');
|
||||
// actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.id + '\')"><i class="fa fa-edit"></i>编辑</a> ');
|
||||
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.id + '\')"><i class="fa fa-remove"></i>删除</a>');
|
||||
return actions.join('');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,18 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label class="col-xs-2 control-label">保险设定:</label>
|
||||
<div class="col-xs-10">
|
||||
<label th:each="insurance:${insurances}" class="check-box">
|
||||
<input name="insurance" type="checkbox" th:value="${insurance.id}" th:text="${insurance.companyName}">
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<th:block th:include="include :: footer" />
|
||||
|
|
@ -87,9 +99,38 @@
|
|||
|
||||
function submitHandler() {
|
||||
if ($.validate.form()) {
|
||||
$.operate.save(prefix + "/add", $('#form-dept-add').serialize());
|
||||
// 方法一:使用saveModal,新增成功后不刷新表格,只显示提示信息
|
||||
//$.operate.saveModal(prefix + "/add", $('#form-dept-add').serialize());
|
||||
|
||||
// 方法二:使用自定义Ajax保存(如果需要更多控制)
|
||||
customSave();
|
||||
}
|
||||
}
|
||||
|
||||
// 自定义保存方法(可选)
|
||||
function customSave() {
|
||||
$.ajax({
|
||||
url: prefix + "/add",
|
||||
type: "post",
|
||||
dataType: "json",
|
||||
data: $('#form-dept-add').serialize(),
|
||||
beforeSend: function () {
|
||||
$.modal.loading("正在处理中,请稍候...");
|
||||
},
|
||||
success: function(result) {
|
||||
$.modal.closeLoading();
|
||||
if (result.code == web_status.SUCCESS) {
|
||||
$.modal.alertSuccess(result.msg);
|
||||
// 如果需要关闭窗口,取消注释下面这行
|
||||
$.modal.close();
|
||||
} else if (result.code == web_status.WARNING) {
|
||||
$.modal.alertWarning(result.msg);
|
||||
} else {
|
||||
$.modal.alertError(result.msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*部门管理-新增-选择父部门树*/
|
||||
function selectDeptTree() {
|
||||
|
|
|
|||
|
|
@ -124,8 +124,29 @@
|
|||
|
||||
function remove(id) {
|
||||
$.modal.confirm("确认要删除吗", function () {
|
||||
$.operate.post(prefix + '/remove/' + id);
|
||||
})
|
||||
customRemove(id);
|
||||
});
|
||||
}
|
||||
|
||||
function customRemove(id) {
|
||||
$.ajax({
|
||||
url: prefix + '/remove/' + id,
|
||||
type: "post",
|
||||
dataType: "json",
|
||||
beforeSend: function () {
|
||||
$.modal.loading("正在处理中,请稍候...");
|
||||
},
|
||||
success: function(result) {
|
||||
$.modal.closeLoading();
|
||||
if (result.code == web_status.SUCCESS) {
|
||||
$.modal.alertSuccess(result.msg);
|
||||
} else if (result.code == web_status.WARNING) {
|
||||
$.modal.alertWarning(result.msg);
|
||||
} else {
|
||||
$.modal.alertError(result.msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -17,15 +17,15 @@
|
|||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label is-required">上级类目:</label>
|
||||
<div class="col-sm-8">
|
||||
<div class="input-group">
|
||||
<input class="form-control" type="text" onclick="selectDeptTree()" id="treeName" readonly="true" th:value="${goodsCategoryName}" required>
|
||||
<span class="input-group-addon"><i class="fa fa-search"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="form-group">-->
|
||||
<!-- <label class="col-sm-3 control-label is-required">上级类目:</label>-->
|
||||
<!-- <div class="col-sm-8">-->
|
||||
<!-- <div class="input-group">-->
|
||||
<!-- <input class="form-control" type="text" onclick="selectDeptTree()" id="treeName" readonly="true" th:value="${goodsCategoryName}" required>-->
|
||||
<!-- <span class="input-group-addon"><i class="fa fa-search"></i></span>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label is-required">类别名称:</label>
|
||||
<div class="col-sm-8">
|
||||
|
|
@ -48,7 +48,8 @@
|
|||
<label class="col-sm-3 control-label">类目类别:</label>
|
||||
<div class="col-sm-8">
|
||||
<div class="radio-box" th:each="dict : ${@dict.getType('goods_category_type')}">
|
||||
<input type="radio" th:id="${dict.dictCode}" name="type" th:value="${dict.dictValue}" th:checked="${dict.default}">
|
||||
<input type="radio" th:id="${dict.dictCode}" name="type" th:value="${dict.dictValue}"
|
||||
th:checked="${goodsCategory.type != null ? goodsCategory.type.toString() == dict.dictValue : dict.default}">
|
||||
<label th:for="${dict.dictCode}" th:text="${dict.dictLabel}"></label>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -62,6 +63,18 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label class="col-xs-2 control-label">保险设定:</label>
|
||||
<div class="col-xs-10">
|
||||
<label th:each="insurance:${insurances}" class="check-box">
|
||||
<input name="insurance" type="checkbox" th:value="${insurance.id}" th:text="${insurance.companyName}" th:checked="${insurance.flag}">
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<th:block th:include="include :: footer" />
|
||||
|
|
@ -103,10 +116,39 @@
|
|||
|
||||
function submitHandler() {
|
||||
if ($.validate.form()) {
|
||||
$.operate.save(prefix + "/edit", $('#form-dept-edit').serialize());
|
||||
var data = $("#form-dept-edit").serializeArray();
|
||||
var insuranceIds = $.form.selectCheckeds("insurance");
|
||||
data.push({"name": "insuranceIds", "value": insuranceIds});
|
||||
|
||||
// 自定义保存,不刷新表格
|
||||
customEditSave(data);
|
||||
}
|
||||
}
|
||||
|
||||
// 自定义编辑保存方法
|
||||
function customEditSave(data) {
|
||||
$.ajax({
|
||||
url: prefix + "/edit",
|
||||
type: "post",
|
||||
dataType: "json",
|
||||
data: data,
|
||||
beforeSend: function () {
|
||||
$.modal.loading("正在处理中,请稍候...");
|
||||
},
|
||||
success: function(result) {
|
||||
$.modal.closeLoading();
|
||||
if (result.code == web_status.SUCCESS) {
|
||||
$.modal.alertSuccess(result.msg);
|
||||
$.modal.close();
|
||||
} else if (result.code == web_status.WARNING) {
|
||||
$.modal.alertWarning(result.msg);
|
||||
} else {
|
||||
$.modal.alertError(result.msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*部门管理-修改-选择部门树*/
|
||||
function selectDeptTree() {
|
||||
var treeId = $("#treeId").val();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<th:block th:include="include :: header('选择服务类目')" />
|
||||
<th:block th:include="include :: ztree-css" />
|
||||
</head>
|
||||
<body class="white-bg">
|
||||
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
|
||||
<form class="form-horizontal m" id="form-tree">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">服务类目:</label>
|
||||
<div class="col-sm-8">
|
||||
<div class="input-group">
|
||||
<input class="form-control" type="text" id="treeName" readonly="true">
|
||||
<input type="hidden" id="treeId">
|
||||
<span class="input-group-addon"><i class="fa fa-search"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-8">
|
||||
<div id="tree" class="ztree"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="form-group">
|
||||
<div class="form-control-static col-sm-offset-9">
|
||||
<button type="button" class="btn btn-sm btn-primary" onclick="submitHandler()"><i class="fa fa-check"></i>保 存</button>
|
||||
<button type="button" class="btn btn-sm btn-danger" onclick="closeItem()"><i class="fa fa-reply-all"></i>关 闭</button>
|
||||
</div>
|
||||
</div> -->
|
||||
</form>
|
||||
</div>
|
||||
<th:block th:include="include :: footer" />
|
||||
<th:block th:include="include :: ztree-js" />
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
var url = ctx + "goods/category/serviceTreeData";
|
||||
var options = {
|
||||
url: url,
|
||||
expandLevel: 2,
|
||||
onClick : zOnClick
|
||||
};
|
||||
$.tree.init(options);
|
||||
});
|
||||
|
||||
function zOnClick(event, treeId, treeNode) {
|
||||
$("#treeId").val(treeNode.id);
|
||||
$("#treeName").val(treeNode.name);
|
||||
}
|
||||
|
||||
function submitHandler() {
|
||||
var treeId = $("#treeId").val();
|
||||
var treeName = $("#treeName").val();
|
||||
if (treeId == "" || treeName == "") {
|
||||
$.modal.alertWarning("请选择服务类目");
|
||||
return;
|
||||
}
|
||||
var index = parent.layer.getFrameIndex(window.name);
|
||||
parent.layer.close(index);
|
||||
}
|
||||
|
||||
function closeItem() {
|
||||
var index = parent.layer.getFrameIndex(window.name);
|
||||
parent.layer.close(index);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -145,9 +145,7 @@
|
|||
formatter: function (value, row, index) {
|
||||
if (row.parentId !== 0) {
|
||||
var actions = [];
|
||||
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.editTab(\'' + row.deptGoodsCategoryId + '\')"><i class="fa fa-edit"></i>编辑</a> ');
|
||||
// actions.push('<a class="btn btn-info btn-xs ' + addFlag + '" href="javascript:void(0)" onclick="$.operate.add(\'' + row.deptGoodsCategoryId + '\')"><i class="fa fa-plus"></i>新增</a> ');
|
||||
// actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="remove(\'' + row.deptGoodsCategoryId + '\')"><i class="fa fa-trash"></i>删除</a>');
|
||||
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.deptGoodsCategoryId + '\')"><i class="fa fa-edit"></i>编辑</a> ');
|
||||
return actions.join('');
|
||||
} else {
|
||||
return "";
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
<div class="main-content">
|
||||
<form class="form-horizontal" id="form-deptGoodsCategory-edit" th:object="${deptGoodsCategory}">
|
||||
<input id="deptGoodsCategoryId" name="deptGoodsCategoryId" type="hidden" th:field="*{deptGoodsCategoryId}"/>
|
||||
<input id="type" name="type" type="hidden" th:field="*{type}"/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
|
|
@ -23,6 +24,21 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6" th:if="*{type != 1}">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-6 control-label">服务类目:</label>
|
||||
<div class="col-sm-6">
|
||||
<div class="input-group">
|
||||
<input class="form-control" type="text" onclick="selectServiceCategoryTree()" id="treeName" readonly="true" th:value="*{serviceCategoryName}">
|
||||
<input type="hidden" id="treeId" name="serviceCategoryId" th:value="*{serviceCategoryId}">
|
||||
<input type="hidden" id="serviceCategoryName" name="serviceCategoryName" th:value="*{serviceCategoryName}">
|
||||
<span class="input-group-addon"><i class="fa fa-search"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-6 control-label is-required">一级分销扣点比例:</label>
|
||||
|
|
@ -33,6 +49,16 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-6 control-label is-required">PC一级分销扣点比例:</label>
|
||||
<div class="col-sm-6">
|
||||
<input name="pcOneRate" placeholder="请输入PC一级分销扣点比例" class="form-control" type="text" maxlength="12"
|
||||
th:field="*{pcOneRate}"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
|
@ -46,6 +72,18 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-6 control-label is-required">PC二级分销扣点比例:</label>
|
||||
<div class="col-sm-6">
|
||||
<input name="pcTwoRate" placeholder="请输入PC二级分销扣点比例" class="form-control" type="text"
|
||||
th:field="*{pcTwoRate}"
|
||||
maxlength="12" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-6 control-label is-required">三级分销扣点比例:</label>
|
||||
|
|
@ -56,6 +94,16 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-6 control-label is-required">PC三级分销扣点比例:</label>
|
||||
<div class="col-sm-6">
|
||||
<input name="pcThreeRate" placeholder="PC请输入三级分销扣点比例" class="form-control" type="text" maxlength="12"
|
||||
th:field="*{pcThreeRate}"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
|
@ -69,6 +117,19 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-6 control-label is-required">PC平台扣点比例:</label>
|
||||
<div class="col-sm-6">
|
||||
<input name="pcDeptRate" placeholder="请输入PC平台扣点比例" class="form-control" type="text"
|
||||
th:field="*{pcDeptRate}"
|
||||
maxlength="12" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-6 control-label is-required">平台固定扣金额:</label>
|
||||
|
|
@ -79,6 +140,16 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-6 control-label is-required">PC平台固定扣金额:</label>
|
||||
<div class="col-sm-6">
|
||||
<input name="pcDeptMoney" placeholder="请输入PC平台固定扣金额" class="form-control" type="text" maxlength="12"
|
||||
th:field="*{pcDeptMoney}"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
|
@ -92,6 +163,19 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-6 control-label is-required">PC截留扣点:</label>
|
||||
<div class="col-sm-6">
|
||||
<input name="pcRetainRate" placeholder="请输入PC截留扣点" class="form-control" type="text"
|
||||
th:field="*{pcRetainRate}"
|
||||
maxlength="12" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-6 control-label is-required">截留金额:</label>
|
||||
|
|
@ -102,6 +186,16 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-6 control-label is-required">PC截留金额:</label>
|
||||
<div class="col-sm-6">
|
||||
<input name="pcRetainMoney" placeholder="请输入PC截留金额" class="form-control" type="text" maxlength="12"
|
||||
th:field="*{pcRetainMoney}"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
|
@ -160,12 +254,38 @@
|
|||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-6 control-label">是否需要保险:</label>
|
||||
<label class="col-sm-6 control-label">倒计时小时数:</label>
|
||||
<div class="col-sm-6">
|
||||
<select name="isSure" class="form-control m-b" th:field="*{isSure}" th:with="type=${@dict.getType('sys_user_sex')}">
|
||||
<option th:text="否" th:value="0"/>
|
||||
<option th:text="是" th:value="1"/>
|
||||
</select>
|
||||
<input name="countdownHours" placeholder="请输入倒计时小时数" class="form-control" type="number" min="1" max="168"
|
||||
th:field="*{countdownHours}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label class="col-xs-3 control-label">PC保险设定:</label>
|
||||
<div class="col-xs-9">
|
||||
<label th:each="insurance:${pcInsurances}" class="check-box">
|
||||
<input name="pcInsurance" type="checkbox" th:value="${insurance.id}" th:text="${insurance.insuranceName}" th:checked="${insurance.flag}">
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label class="col-xs-3 control-label">商城保险设定:</label>
|
||||
<div class="col-xs-9">
|
||||
<label th:each="insurance:${shopInsurances}" class="check-box">
|
||||
<input name="shopInsurance" type="checkbox" th:value="${insurance.id}" th:text="${insurance.insuranceName}" th:checked="${insurance.flag}">
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -213,6 +333,10 @@
|
|||
function submitHandler() {
|
||||
if ($.validate.form()) {
|
||||
var data = $("#form-deptGoodsCategory-edit").serializeArray();
|
||||
var pcInsuranceIds = $.form.selectCheckeds("pcInsurance");
|
||||
var shopInsuranceIds = $.form.selectCheckeds("shopInsurance");
|
||||
data.push({"name": "pcInsuranceIds", "value": pcInsuranceIds});
|
||||
data.push({"name": "shopInsuranceIds", "value": shopInsuranceIds});
|
||||
$.operate.saveTab(prefix + "/edit", data);
|
||||
$.modal.close();
|
||||
}
|
||||
|
|
@ -274,6 +398,26 @@
|
|||
}
|
||||
});
|
||||
|
||||
/*选择服务类目树*/
|
||||
function selectServiceCategoryTree() {
|
||||
var treeId = $("#treeId").val();
|
||||
var options = {
|
||||
title: '服务类目选择',
|
||||
width: "380",
|
||||
url: ctx + "goods/category/selectServiceCategoryTree",
|
||||
callBack: doSubmit
|
||||
};
|
||||
$.modal.openOptions(options);
|
||||
}
|
||||
|
||||
function doSubmit(index, layero) {
|
||||
var body = $.modal.getChildFrame(index);
|
||||
$("#treeId").val(body.find('#treeId').val());
|
||||
$("#treeName").val(body.find('#treeName').val());
|
||||
$("#serviceCategoryName").val(body.find('#treeName').val());
|
||||
$.modal.close(index);
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
|
||||
<head>
|
||||
<th:block th:include="include :: header('新增保险管理')" />
|
||||
</head>
|
||||
<body class="white-bg">
|
||||
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
|
||||
<form class="form-horizontal m" id="form-manager-add">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">保险公司名称:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="companyName" class="form-control" type="text">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">保险项目名称:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="insuranceName" class="form-control" type="text">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label is-required">保险费用:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="insuranceAmount" class="form-control" type="text" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">保险条例url:</label>
|
||||
<div class="col-sm-8">
|
||||
<textarea name="insuranceUrl" class="form-control"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">备注:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="remark" class="form-control" type="text">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<th:block th:include="include :: footer" />
|
||||
<script th:inline="javascript">
|
||||
var prefix = ctx + "goods/manager"
|
||||
$("#form-manager-add").validate({
|
||||
focusCleanup: true
|
||||
});
|
||||
|
||||
function submitHandler() {
|
||||
if ($.validate.form()) {
|
||||
$.operate.save(prefix + "/add", $('#form-manager-add').serialize());
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
|
||||
<head>
|
||||
<th:block th:include="include :: header('修改保险管理')" />
|
||||
</head>
|
||||
<body class="white-bg">
|
||||
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
|
||||
<form class="form-horizontal m" id="form-manager-edit" th:object="${insuranceManager}">
|
||||
<input name="id" th:field="*{id}" type="hidden">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">保险公司名称:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="companyName" th:field="*{companyName}" class="form-control" type="text">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">保险项目名称:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="insuranceName" th:field="*{insuranceName}" class="form-control" type="text">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label is-required">保险费用:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="insuranceAmount" th:field="*{insuranceAmount}" class="form-control" type="text" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">保险条例url:</label>
|
||||
<div class="col-sm-8">
|
||||
<textarea name="insuranceUrl" class="form-control">[[*{insuranceUrl}]]</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">备注:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="remark" th:field="*{remark}" class="form-control" type="text">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<th:block th:include="include :: footer" />
|
||||
<script th:inline="javascript">
|
||||
var prefix = ctx + "goods/manager";
|
||||
$("#form-manager-edit").validate({
|
||||
focusCleanup: true
|
||||
});
|
||||
|
||||
function submitHandler() {
|
||||
if ($.validate.form()) {
|
||||
$.operate.save(prefix + "/edit", $('#form-manager-edit').serialize());
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
|
||||
<head>
|
||||
<th:block th:include="include :: header('保险管理列表')" />
|
||||
</head>
|
||||
<body class="gray-bg">
|
||||
<div class="container-div">
|
||||
<div class="row">
|
||||
<div class="col-sm-12 search-collapse">
|
||||
<form id="formId">
|
||||
<div class="select-list">
|
||||
<ul>
|
||||
<li>
|
||||
<label>保险公司名称:</label>
|
||||
<input type="text" name="companyName"/>
|
||||
</li>
|
||||
<li>
|
||||
<label>保险项目名称:</label>
|
||||
<input type="text" name="insuranceName"/>
|
||||
</li>
|
||||
<li>
|
||||
<label>保险费用:</label>
|
||||
<input type="text" name="insuranceAmount"/>
|
||||
</li>
|
||||
<li>
|
||||
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i> 搜索</a>
|
||||
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i> 重置</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="btn-group-sm" id="toolbar" role="group">
|
||||
<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="goods:manager:add">
|
||||
<i class="fa fa-plus"></i> 添加
|
||||
</a>
|
||||
<a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="goods:manager:edit">
|
||||
<i class="fa fa-edit"></i> 修改
|
||||
</a>
|
||||
<a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="goods:manager:remove">
|
||||
<i class="fa fa-remove"></i> 删除
|
||||
</a>
|
||||
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="goods:manager:export">
|
||||
<i class="fa fa-download"></i> 导出
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-sm-12 select-table table-striped">
|
||||
<table id="bootstrap-table"></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<th:block th:include="include :: footer" />
|
||||
<script th:inline="javascript">
|
||||
var editFlag = [[${@permission.hasPermi('goods:manager:edit')}]];
|
||||
var removeFlag = [[${@permission.hasPermi('goods:manager:remove')}]];
|
||||
var prefix = ctx + "goods/manager";
|
||||
|
||||
$(function() {
|
||||
var options = {
|
||||
url: prefix + "/list",
|
||||
createUrl: prefix + "/add",
|
||||
updateUrl: prefix + "/edit/{id}",
|
||||
removeUrl: prefix + "/remove",
|
||||
exportUrl: prefix + "/export",
|
||||
modalName: "保险管理",
|
||||
columns: [{
|
||||
checkbox: true
|
||||
},
|
||||
{
|
||||
field: 'id',
|
||||
title: '主键',
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
field: 'companyName',
|
||||
title: '保险公司名称'
|
||||
},
|
||||
{
|
||||
field: 'insuranceName',
|
||||
title: '保险项目名称'
|
||||
},
|
||||
{
|
||||
field: 'insuranceAmount',
|
||||
title: '保险费用'
|
||||
},
|
||||
{
|
||||
field: 'insuranceUrl',
|
||||
title: '保险条例url'
|
||||
},
|
||||
{
|
||||
field: 'remark',
|
||||
title: '备注'
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
align: 'center',
|
||||
formatter: function(value, row, index) {
|
||||
var actions = [];
|
||||
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.id + '\')"><i class="fa fa-edit"></i>编辑</a> ');
|
||||
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.id + '\')"><i class="fa fa-remove"></i>删除</a>');
|
||||
return actions.join('');
|
||||
}
|
||||
}]
|
||||
};
|
||||
$.table.init(options);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -2,8 +2,14 @@
|
|||
<html lang="en" xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<th:block th:include="include :: header('模板新增')"/>
|
||||
<th:block th:include="include :: layout-latest-css"/>
|
||||
<th:block th:include="include :: bootstrap-fileinput-css"/>
|
||||
|
||||
<style>
|
||||
body {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.pane1 {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
|
@ -14,6 +20,7 @@
|
|||
|
||||
.template-div {
|
||||
display: inline-block;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.template-body {
|
||||
|
|
@ -67,9 +74,44 @@
|
|||
color: red;
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
.multiply-symbol {
|
||||
font-size: large;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.goodsNumList {
|
||||
padding: 5px 8px 14px 5px;
|
||||
min-height: 40px;
|
||||
border: 1px solid #dcdfe6;
|
||||
box-sizing: border-box;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.oneGoodsNumList {
|
||||
padding: 5px 8px 5px 5px;
|
||||
min-height: 40px;
|
||||
border: 1px solid #dcdfe6;
|
||||
box-sizing: border-box;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.goodsNum {
|
||||
margin: 2px 0;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
#categoryCxSelect {
|
||||
z-index: 101
|
||||
}
|
||||
|
||||
#categoryCxSelect .eo-cascader-menu:nth-child(-n+3) .has-child label {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<th:block th:include="include :: datetimepicker-css" />
|
||||
<link rel="stylesheet" href="../../../static/css/cascader.css" th:href="@{/css/cascader.css}">
|
||||
</head>
|
||||
<body class="gray-bg">
|
||||
<form id="addTemplateForm">
|
||||
|
|
@ -89,22 +131,24 @@
|
|||
<div class="form-horizontal m">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label is-required">服务类目:</label>
|
||||
<div id="categoryCxSelect" class="col-sm-6 row">
|
||||
<div class="col-sm-3">
|
||||
<select class="category1 form-control m-b" name="category1" required></select>
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
<select class="category2 form-control m-b" name="category2" required></select>
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
<select class="category3 form-control m-b" name="category3" required></select>
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
<select class="category4 form-control m-b" name="category4" required></select>
|
||||
<div class="col-sm-6" style="padding-right: 0">
|
||||
<div id="categoryCxSelect" class="cascader-wrap">
|
||||
<!-- <div class="col-sm-3">-->
|
||||
<!-- <select class="category1 form-control m-b" name="category1" required></select>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="col-sm-3">-->
|
||||
<!-- <select class="category2 form-control m-b" name="category2" required></select>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="col-sm-3">-->
|
||||
<!-- <select class="category3 form-control m-b" name="category3" required></select>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="col-sm-3">-->
|
||||
<!-- <select class="category4 form-control m-b" name="category4" required></select>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-1">×</div>
|
||||
<div class="col-sm-1">
|
||||
<div class="col-sm-1 multiply-symbol">×</div>
|
||||
<div id="goodsNumList" class="col-sm-1 oneGoodsNumList">
|
||||
<input type="number" name="goodsNum" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -131,20 +175,17 @@
|
|||
<div class="col-sm-4">
|
||||
<div class="input-group date">
|
||||
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
|
||||
<input type="text" class="form-control" id="servDate" name="servDate" required>
|
||||
<input type="text" class="form-control" id="servDate" name="servDate" required readonly style="background: white;">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<select class="form-control" name="servTime" required>
|
||||
<option value="8:00-12:00">8:00-12:00</option>
|
||||
<option value="8:00-12:00">12:00-16:00</option>
|
||||
<option value="8:00-12:00">16:00-20:00</option>
|
||||
<option value="8:00-12:00">8:00-10:00</option>
|
||||
<option value="8:00-12:00">10:00-12:00</option>
|
||||
<option value="8:00-12:00">12:00-14:00</option>
|
||||
<option value="8:00-12:00">14:00-16:00</option>
|
||||
<option value="8:00-12:00">16:00-18:00</option>
|
||||
<option value="8:00-12:00">18:00-20:00</option>
|
||||
<option value="08:00-10:00">08:00-10:00</option>
|
||||
<option value="10:00-12:00">10:00-12:00</option>
|
||||
<option value="12:00-14:00">12:00-14:00</option>
|
||||
<option value="14:00-16:00">14:00-16:00</option>
|
||||
<option value="16:00-18:00">16:00-18:00</option>
|
||||
<option value="18:00-20:00">18:00-20:00</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -159,26 +200,27 @@
|
|||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label is-required">图片上传:</label>
|
||||
<div class="col-sm-8">
|
||||
<div class="file-loading">
|
||||
<input id="multipleFile" name="files" type="file" multiple>
|
||||
</div>
|
||||
<input type="text" name="imageUrl" value="" hidden>
|
||||
<input type="file" name="imageUrlStr" id="imageUrlStr" multiple class="file" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label is-required">服务地址:</label>
|
||||
<div id="areaCxSelect" class="col-sm-6 row">
|
||||
<div class="col-sm-3">
|
||||
<select class="province form-control m-b" name="province" id="province" required onchange="selectRegion('province', 'city')"></select>
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
<select class="city form-control m-b" name="city" id="city" required onchange="selectRegion('city', 'district')"></select>
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
<select class="district form-control m-b" name="district" id="district" required onchange="selectRegion('district', 'street')"></select>
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
<select class="street form-control m-b" name="streetId" id="streetId" required></select>
|
||||
<div class="col-sm-6">
|
||||
<div id="areaCxSelect" class="cascader-wrap">
|
||||
<!-- <div class="col-sm-3">-->
|
||||
<!-- <select class="province form-control m-b" name="province" id="province" required onchange="selectRegion('province', 'city')"></select>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="col-sm-3">-->
|
||||
<!-- <select class="city form-control m-b" name="city" id="city" required onchange="selectRegion('city', 'district')"></select>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="col-sm-3">-->
|
||||
<!-- <select class="district form-control m-b" name="district" id="district" required onchange="selectRegion('district', 'street')"></select>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="col-sm-3">-->
|
||||
<!-- <select class="street form-control m-b" name="streetId" id="streetId" required></select>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -201,15 +243,15 @@
|
|||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label is-required">下单模式:</label>
|
||||
<div class="col-sm-8 row">
|
||||
<div class="col-sm-8 row" id="orderModeRadioGroup">
|
||||
<div class="col-sm-2">
|
||||
<label><input type="radio" checked="" value="1" name="orderMode"> 带价发布</label>
|
||||
<label><input type="radio" value="02" name="orderMode" checked > 带价发布</label>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<label><input type="radio" value="2" name="orderMode"> 一票价发布</label>
|
||||
<label><input type="radio" value="01" name="orderMode"> 一票价发布</label>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<label><input type="radio" value="3" name="orderMode"> 回收模式</label>
|
||||
<label><input type="radio" value="03" name="orderMode"> 回收模式</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -230,7 +272,7 @@
|
|||
</div>
|
||||
<div class="col-sm-2">
|
||||
<div class="input-group">
|
||||
<input type="text" name="informationFee" class="form-control" required placeholder="信息费">
|
||||
<input type="text" name="informationFee" class="form-control" placeholder="信息费">
|
||||
<div class="input-group-btn">
|
||||
<button data-toggle="dropdown" class="btn btn-white dropdown-toggle dropdown-btn" type="button" id="informationFeeUnit">单位<span class="caret"></span></button>
|
||||
<ul class="dropdown-menu pull-right">
|
||||
|
|
@ -300,11 +342,15 @@
|
|||
<span class="yuan-symbol">¥</span>
|
||||
<span class="yuan-symbol" id="totalMoney">0</span>
|
||||
</div>
|
||||
<div class="oper-banner-end col-sm-5">
|
||||
<div class="oper-banner-end col-sm-5" >
|
||||
<div class="m-r">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" value="1" name="isPayOffline">线下到付</label>
|
||||
<a href="#" shiro:hasPermission="consult:order:add"><input id="consultOrder" type="checkbox" value="02" name="consultOrder" onclick="changeConsultOrder(this)" >合约订单</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-r">
|
||||
<div class="checkbox">
|
||||
<label><input id="payOnDoorMode" type="checkbox" value="02" name="payMode" onclick="changePayOnDoorMode(this)">上门到付/保外单</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-r">
|
||||
|
|
@ -320,10 +366,33 @@
|
|||
</form>
|
||||
|
||||
<th:block th:include="include :: footer"/>
|
||||
<th:block th:include="include :: layout-latest-js"/>
|
||||
<th:block th:include="include :: jquery-cxselect-js" />
|
||||
<th:block th:include="include :: datetimepicker-js" />
|
||||
|
||||
<th:block th:include="include :: bootstrap-fileinput-js"/>
|
||||
<script th:src="@{/js/plugins/miniCascader/cascader.js}"></script>
|
||||
<script th:src="@{/data/four-level-area.js}"></script>
|
||||
<script type="text/javascript">
|
||||
// 级联下拉
|
||||
let categoryCascader = new eo_cascader([], {
|
||||
elementID: 'categoryCxSelect',
|
||||
multiple: true, // 是否多选
|
||||
separator: '-', // 分割符 山西-太原-小店区 || 山西/太原/小店区
|
||||
clearable: true, // 是否可一键删除已选
|
||||
value: 'goodsCategoryId',
|
||||
label: 'goodsCategoryName',
|
||||
children: 'child',
|
||||
checkedCallback: checkedCategoryCallback
|
||||
});
|
||||
let areaCascader = new eo_cascader(fourLevelAreaList, {
|
||||
elementID: 'areaCxSelect',
|
||||
multiple: false, // 是否多选
|
||||
separator: '-', // 分割符 山西-太原-小店区 || 山西/太原/小店区
|
||||
clearable: false, // 是否可一键删除已选
|
||||
value: 'areaId',
|
||||
label: 'areaName',
|
||||
children: 'child'
|
||||
});
|
||||
$(function(){
|
||||
var icon = "<i class='fa fa-times-circle'></i> ";
|
||||
// $("#addTemplateForm").validate({
|
||||
|
|
@ -333,7 +402,6 @@
|
|||
// }
|
||||
// });
|
||||
|
||||
// 级联下拉
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
dataType:"json",
|
||||
|
|
@ -342,36 +410,47 @@
|
|||
contentType: 'application/json',
|
||||
success: function (result) {
|
||||
if (result.code == web_status.SUCCESS) {
|
||||
$('#categoryCxSelect').cxSelect({
|
||||
selects: ['category1', 'category2', 'category3', 'category4'],
|
||||
jsonValue: 'deptGoodsCategoryId',
|
||||
jsonName: 'goodsCategoryName',
|
||||
jsonSub: 'child',
|
||||
data: result.data
|
||||
});
|
||||
<!-- $('#categoryCxSelect').cxSelect({-->
|
||||
<!-- selects: ['category1', 'category2', 'category3', 'category4'],-->
|
||||
<!-- jsonValue: 'deptGoodsCategoryId',-->
|
||||
<!-- jsonName: 'goodsCategoryName',-->
|
||||
<!-- jsonSub: 'child',-->
|
||||
<!-- data: result.data-->
|
||||
<!-- });-->
|
||||
categoryCascader = new eo_cascader(result.data, {
|
||||
elementID: 'categoryCxSelect',
|
||||
multiple: true, // 是否多选
|
||||
checkedValue: null,
|
||||
separator: '-', // 分割符 山西-太原-小店区 || 山西/太原/小店区
|
||||
clearable: true, // 是否可一键删除已选
|
||||
value: 'deptGoodsCategoryId',
|
||||
label: 'goodsCategoryName',
|
||||
children: 'child',
|
||||
checkedCallback: checkedCategoryCallback
|
||||
})
|
||||
} else {
|
||||
$.modal.msgError("数据加载错误,请重试!")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
dataType:"json",
|
||||
url: ctx + "system/area/list",
|
||||
success: function (result) {
|
||||
if (result.code == web_status.SUCCESS) {
|
||||
$('#areaCxSelect').cxSelect({
|
||||
selects: ['province', 'city', 'district', 'street'],
|
||||
jsonValue: 'areaId',
|
||||
jsonName: 'areaName',
|
||||
data: result.data
|
||||
});
|
||||
} else {
|
||||
$.modal.msgError("数据加载错误,请重试!")
|
||||
}
|
||||
}
|
||||
})
|
||||
<!-- $.ajax({-->
|
||||
<!-- type: "POST",-->
|
||||
<!-- dataType:"json",-->
|
||||
<!-- url: ctx + "system/area/list",-->
|
||||
<!-- success: function (result) {-->
|
||||
<!-- if (result.code == web_status.SUCCESS) {-->
|
||||
<!-- $('#areaCxSelect').cxSelect({-->
|
||||
<!-- selects: ['province', 'city', 'district', 'street'],-->
|
||||
<!-- jsonValue: 'areaId',-->
|
||||
<!-- jsonName: 'areaName',-->
|
||||
<!-- data: result.data-->
|
||||
<!-- });-->
|
||||
<!-- } else {-->
|
||||
<!-- $.modal.msgError("数据加载错误,请重试!")-->
|
||||
<!-- }-->
|
||||
<!-- }-->
|
||||
<!-- })-->
|
||||
|
||||
$("#servDate").datetimepicker({
|
||||
format: "yyyy-mm-dd",
|
||||
|
|
@ -409,44 +488,156 @@
|
|||
// })
|
||||
});
|
||||
|
||||
function checkedCategoryCallback() {
|
||||
let checkedIdArr = categoryCascader.getCheckedByID();
|
||||
if (checkedIdArr && checkedIdArr.length > 0) {
|
||||
$('#goodsNumList').html(null);
|
||||
$('#goodsNumList').removeClass('oneGoodsNumList');
|
||||
$('#goodsNumList').addClass('goodsNumList');
|
||||
checkedIdArr.forEach(function(id, index) {
|
||||
$('#goodsNumList').append('<input type="number" name="goodsNum' + id + '" class="form-control goodsNum" required>');
|
||||
});
|
||||
} else {
|
||||
$('#goodsNumList').removeClass('goodsNumList');
|
||||
$('#goodsNumList').addClass('oneGoodsNumList');
|
||||
$('#goodsNumList').html('<input type="number" name="goodsNum" class="form-control" required>');
|
||||
}
|
||||
}
|
||||
|
||||
function changeInformationFeeUnit(unit) {
|
||||
this.$('#informationFeeUnit').html(unit + '<span class="caret"></span>');
|
||||
}
|
||||
|
||||
function selectRegion(regionLevelName, nextRegionLevelName) {
|
||||
var regionId = $("#" + regionLevelName).val();
|
||||
if ($.common.isEmpty(regionId)) {
|
||||
return;
|
||||
}
|
||||
<!-- function selectRegion(regionLevelName, nextRegionLevelName) {-->
|
||||
<!-- var regionId = $("#" + regionLevelName).val();-->
|
||||
<!-- if ($.common.isEmpty(regionId)) {-->
|
||||
<!-- return;-->
|
||||
<!-- }-->
|
||||
|
||||
//Ajax调用处理
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
dataType:"json",
|
||||
url: ctx + "system/area/list",
|
||||
data: {parentCode: regionId},
|
||||
success: function (result) {
|
||||
if (result.code == web_status.SUCCESS) {
|
||||
$('#areaCxSelect').cxSelect({
|
||||
selects: [nextRegionLevelName],
|
||||
jsonValue: 'areaId',
|
||||
jsonName: 'areaName',
|
||||
data: result.data
|
||||
});
|
||||
} else {
|
||||
$.modal.msgError("数据加载错误,请重试!")
|
||||
}
|
||||
}
|
||||
})
|
||||
<!-- //Ajax调用处理-->
|
||||
<!-- $.ajax({-->
|
||||
<!-- type: "POST",-->
|
||||
<!-- dataType:"json",-->
|
||||
<!-- url: ctx + "system/area/list",-->
|
||||
<!-- data: {parentCode: regionId},-->
|
||||
<!-- success: function (result) {-->
|
||||
<!-- if (result.code == web_status.SUCCESS) {-->
|
||||
<!-- $('#areaCxSelect').cxSelect({-->
|
||||
<!-- selects: [nextRegionLevelName],-->
|
||||
<!-- jsonValue: 'areaId',-->
|
||||
<!-- jsonName: 'areaName',-->
|
||||
<!-- data: result.data-->
|
||||
<!-- });-->
|
||||
<!-- } else {-->
|
||||
<!-- $.modal.msgError("数据加载错误,请重试!")-->
|
||||
<!-- }-->
|
||||
<!-- }-->
|
||||
<!-- })-->
|
||||
<!-- }-->
|
||||
|
||||
|
||||
function changeConsultOrder(e){
|
||||
if ($(e).is(':checked')) {
|
||||
$('#consultOrder').prop("value", '01');
|
||||
} else {
|
||||
$('#consultOrder').prop("value", '02');
|
||||
}
|
||||
}
|
||||
|
||||
function changePayOnDoorMode(e) {
|
||||
if ($(e).is(':checked')) {
|
||||
$('#payOnDoorMode').prop("value", '01');
|
||||
} else {
|
||||
$('#payOnDoorMode').prop("value", '02');
|
||||
}
|
||||
}
|
||||
|
||||
function validSpecialComponent() {
|
||||
// 类目
|
||||
let categoryIds = categoryCascader.getCheckedByID();
|
||||
if (!categoryIds || categoryIds.length === 0) {
|
||||
$.modal.msgError("服务类目不能为空")
|
||||
return false;
|
||||
}
|
||||
|
||||
// 图片是否上传
|
||||
if (!$('input[name=imageUrl]').val()) {
|
||||
$.modal.msgError("图片未上传")
|
||||
return false;
|
||||
}
|
||||
|
||||
// 地区
|
||||
let checkedAreaPathList = areaCascader.getCheckedPaths();
|
||||
if (!checkedAreaPathList || checkedAreaPathList.length === 0) {
|
||||
$.modal.msgError("服务地址不能为空")
|
||||
return false;
|
||||
}
|
||||
|
||||
// 下单模式
|
||||
if (!$('#orderModeRadioGroup input[name=orderMode]').is(':checked')) {
|
||||
$.modal.msgError("请录入完整必填信息")
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function translateForm(data) {
|
||||
var params = {};
|
||||
data.forEach(function (item){
|
||||
params[item.name] = item.value;
|
||||
});
|
||||
|
||||
let categoryIds = categoryCascader.getCheckedByID();
|
||||
let orderGoodsStandards = [];
|
||||
categoryIds.forEach(function (item){
|
||||
orderGoodsStandards.push({
|
||||
deptCategoryId: item,
|
||||
goodsStandardNum: $(".goodsNum[name=goodsNum" + item + "]").val()
|
||||
});
|
||||
});
|
||||
params.orderGoodsStandards = orderGoodsStandards;
|
||||
params.categoryId1 = categoryCascader.getCheckedPaths()[0][0];
|
||||
params.categoryId2 = categoryCascader.getCheckedPaths()[0][1];
|
||||
params.categoryId3 = categoryCascader.getCheckedPaths()[0][2];
|
||||
params.provinceId = areaCascader.getCheckedPaths()[0][0];
|
||||
params.cityId = areaCascader.getCheckedPaths()[0][1];
|
||||
params.districtId = areaCascader.getCheckedPaths()[0][2];
|
||||
params.streetId = areaCascader.getCheckedPaths()[0][3];
|
||||
params.payMode = $('#payOnDoorMode').val();
|
||||
params.consultMode = $('#consultOrder').val();
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
// 营业执照上传
|
||||
$('#imageUrlStr').fileinput({
|
||||
language: 'zh', //设置语言
|
||||
dropZoneEnabled: false, //是否显示拖拽区域
|
||||
showPreview: false,
|
||||
uploadExtraData: {
|
||||
"name": "imageUrlStr"
|
||||
},
|
||||
dropZoneTitle: "可以将图片拖放到这里", //拖拽区域显示文字
|
||||
uploadUrl: ctx + 'tool/qiniu/dept/upload', //上传路径
|
||||
allowedFileExtensions: ['jpg', 'png', 'gif', 'jpeg'], //指定上传文件类型
|
||||
maxFileSize: 0,
|
||||
maxFileSize: 2048, //上传文件最大值,单位kb
|
||||
uploadAsync: true, //异步上传
|
||||
maxFileCount: 2 //上传文件最大个数。
|
||||
}).on("fileuploaded", function(event,data) { //异步上传成功后回调
|
||||
if(data.response.code === 0){
|
||||
$("input[name='imageUrl']").val(data.response.url)
|
||||
}else {
|
||||
alert("上传失败!");
|
||||
}
|
||||
});
|
||||
|
||||
function submitOrder() {
|
||||
if (!validSpecialComponent()) return;
|
||||
if ($.validate.form()) {
|
||||
var data = $("#addTemplateForm").serializeArray();
|
||||
var params= {};
|
||||
data.forEach(function (item){
|
||||
params[item.name] = item.value;
|
||||
});
|
||||
var params= translateForm(data);
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
|
|
@ -456,22 +647,37 @@
|
|||
contentType: 'application/json',
|
||||
success: function (result) {
|
||||
if (result.code == web_status.SUCCESS) {
|
||||
$.modal.msgSuccess("提交成功")
|
||||
layer.open({
|
||||
type: 0,
|
||||
area: ['250px', '180px'],
|
||||
fix: false,
|
||||
//不固定
|
||||
maxmin: true,
|
||||
shade: 0.3,
|
||||
title: '系统通知',
|
||||
content: '发单成功,是否前往发单管理?',
|
||||
btn: ['确定','继续下单'],
|
||||
// 弹层外区域关闭
|
||||
shadeClose: true,
|
||||
yes: function(index) {
|
||||
$.modal.parentTab('发单管理', 'order/master/pc');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$.modal.msgError("请求失败")
|
||||
$.modal.msgError(result.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
$.modal.msgError("请录入完整必填信息")
|
||||
}
|
||||
}
|
||||
|
||||
function addTemplate() {
|
||||
if (!validSpecialComponent()) return;
|
||||
if ($.validate.form()) {
|
||||
var data = $("#addTemplateForm").serializeArray();
|
||||
var params= {};
|
||||
data.forEach(function (item){
|
||||
params[item.name] = item.value;
|
||||
});
|
||||
var params= translateForm(data);
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
|
|
@ -483,7 +689,7 @@
|
|||
if (result.code == web_status.SUCCESS) {
|
||||
$.modal.msgSuccess("提交成功")
|
||||
} else {
|
||||
$.modal.msgError("请求失败")
|
||||
$.modal.msgError(result.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
<script th:src="@{/ajax/libs/validate/jquery.validate.extend.js?v=1.19.3}"></script>
|
||||
<script th:src="@{/ajax/libs/validate/messages_zh.js?v=1.19.3}"></script>
|
||||
<!-- bootstrap-table 表格树插件 -->
|
||||
<script th:src="@{/ajax/libs/bootstrap-table/extensions/tree/bootstrap-table-tree.min.js?v=1.18.3}"></script>
|
||||
<script th:src="@{/ajax/libs/bootstrap-table/extensions/tree/bootstrap-table-tree.js?v=1.18.3}"></script>
|
||||
<!-- 遮罩层 -->
|
||||
<script th:src="@{/ajax/libs/blockUI/jquery.blockUI.js?v=2.70.0}"></script>
|
||||
<script th:src="@{/ajax/libs/iCheck/icheck.min.js?v=1.0.3}"></script>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="renderer" content="webkit">
|
||||
<title>工圈子管理系统</title>
|
||||
<title>管理系统</title>
|
||||
<!-- 避免IE使用兼容模式 -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<link th:href="@{favicon.ico}" rel="shortcut icon"/>
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
</div>
|
||||
<a th:href="@{/index}">
|
||||
<li class="logo hidden-xs">
|
||||
<span class="logo-lg">工圈子</span>
|
||||
<span class="logo-lg">后台系统</span>
|
||||
</li>
|
||||
</a>
|
||||
<div class="sidebar-collapse">
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
|
||||
<title>追风者</title>
|
||||
<meta name="description" content="叮咚工链后台管理框架">
|
||||
<title>叮咚工链</title>
|
||||
<meta name="description" content="后台管理框架">
|
||||
<link href="../static/css/bootstrap.min.css" th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
|
||||
<link href="../static/css/font-awesome.min.css" th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/>
|
||||
<link href="../static/css/style.min.css" th:href="@{/css/style.min.css}" rel="stylesheet"/>
|
||||
|
|
@ -26,14 +26,13 @@
|
|||
<div class="col-sm-7">
|
||||
<div class="signin-info">
|
||||
<div class="logopanel m-b">
|
||||
<h1>[ 叮咚工链 ]</h1>
|
||||
<h1>[ 后台管理系统 ]</h1>
|
||||
</div>
|
||||
<div class="m-b"></div>
|
||||
<h4>欢迎使用 <strong>叮咚工链 后台管理系统</strong></h4>
|
||||
<h4>欢迎使用 <strong>后台管理系统</strong></h4>
|
||||
<ul class="m-b">
|
||||
<li><i class="fa fa-arrow-circle-o-right m-r-xs"></i> 再多平方米</li>
|
||||
<li><i class="fa fa-arrow-circle-o-right m-r-xs"></i> 不如我懂你</li>
|
||||
<li><i class="fa fa-arrow-circle-o-right m-r-xs"></i> 叮咚工链</li>
|
||||
<li><i class="fa fa-arrow-circle-o-right m-r-xs"></i> 在你需要的时候</li>
|
||||
<li><i class="fa fa-arrow-circle-o-right m-r-xs"></i> 总在您身边</li>
|
||||
</ul>
|
||||
|
|
@ -65,8 +64,9 @@
|
|||
</div>
|
||||
<div class="signup-footer">
|
||||
<div class="pull-left">
|
||||
Copyright © 2018-2021 opsoul.com All Rights Reserved. <br>
|
||||
备案号 粤ICP备2021044349号-1
|
||||
Copyright © 2018-2021 gmjlb.com All Rights Reserved. <br>
|
||||
<a href="https://beian.miit.gov.cn/" target="_blank">备案号:</a>
|
||||
<a href="https://beian.miit.gov.cn/" target="_blank">桂ICP备2024024616号-3</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<!--360浏览器优先以webkit内核解析-->
|
||||
<title>工圈子介绍</title>
|
||||
<title>介绍</title>
|
||||
<link rel="shortcut icon" href="favicon.ico">
|
||||
<link href="../static/css/bootstrap.min.css" th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
|
||||
<link href="../static/css/font-awesome.min.css" th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/>
|
||||
|
|
@ -22,14 +22,11 @@
|
|||
<br>
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<h2>工圈子后台管理框架</h2>
|
||||
<p>一直想做一款后台管理系统,看了很多优秀的开源项目但是发现没有合适自己的。于是利用空闲休息时间开始自己写一套后台系统。如此有了工圈子管理系统。,她可以用于所有的Web应用程序,如<b>网站管理后台</b>,<b>网站会员中心</b>,<b>CMS</b>,<b>CRM</b>,<b>OA</b>等等,当然,您也可以对她进行深度定制,以做出更强系统。所有前端后台代码封装过后十分精简易上手,出错概率低。同时支持移动客户端访问。系统会陆续更新一些实用功能。</p>
|
||||
<h2>后台管理框架</h2>
|
||||
<p>一直想做一款后台管理系统,看了很多优秀的开源项目但是发现没有合适自己的。于是利用空闲休息时间开始自己写一套后台系统。如此有了本管理系统。,她可以用于所有的Web应用程序,如<b>网站管理后台</b>,<b>网站会员中心</b>,<b>CMS</b>,<b>CRM</b>,<b>OA</b>等等,当然,您也可以对她进行深度定制,以做出更强系统。所有前端后台代码封装过后十分精简易上手,出错概率低。同时支持移动客户端访问。系统会陆续更新一些实用功能。</p>
|
||||
<p>
|
||||
<b>当前版本:</b><span>v[[${version}]]</span>
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-warning">叮咚链家</span>
|
||||
</p>
|
||||
<br>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,289 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<head>
|
||||
<th:block th:include="include :: header('指派师傅')"/>
|
||||
<th:block th:include="include :: layout-latest-css"/>
|
||||
|
||||
<style>
|
||||
.custom-container {
|
||||
padding: 0 30px 20px 30px;
|
||||
}
|
||||
|
||||
.flex-board {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.flex-board-no-wrap {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.flex-board.select-content {
|
||||
flex-basis: 100%
|
||||
}
|
||||
|
||||
.flex-board.select-content .flex-board-no-wrap {
|
||||
flex-basis: 90%
|
||||
}
|
||||
|
||||
.flex-board.input-content {
|
||||
flex-basis: 50%;
|
||||
}
|
||||
|
||||
.flex-board.input-content input {
|
||||
flex-basis: 75%
|
||||
}
|
||||
|
||||
.specCanAssignNum {
|
||||
text-align: center;
|
||||
line-height: 31px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body class="gray-bg">
|
||||
<div class="animated fadeInRight row custom-container">
|
||||
<div class="col-sm-12 search-collapse">
|
||||
<form class="m" id="canAssignSpecForm">
|
||||
<div id="canAssignSpecList" class="m-b">
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-4">
|
||||
<span>派单金额:</span>
|
||||
<span id="moneyCanAssign"></span>
|
||||
<span>元</span>
|
||||
</div>
|
||||
<!-- <div class="col-sm-5">-->
|
||||
<!-- <div class="flex-board input-content">-->
|
||||
<!-- <label class="form-control-label">派出金额:</label>-->
|
||||
<!-- <input name="totalPay" type="number" class="form-control">-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 search-collapse">
|
||||
<form class="flex-board m" id="workerForm">
|
||||
<div class="flex-board select-content m-t">
|
||||
<label class="form-control-label">区域筛选:</label>
|
||||
<div id="areaCxSelect" class="flex-board-no-wrap">
|
||||
<select class="province form-control cx-select-input m-r" name="province" id="province" data-first-title="选择省" onchange="selectRegion('province', 'city')"></select>
|
||||
<select class="city form-control cx-select-input m-r" name="city" id="city" data-first-title="选择市" onchange="selectRegion('city', 'district')"></select>
|
||||
<select class="district form-control cx-select-input m-r" name="areaId" id="district" data-first-title="选择区" onchange="selectRegion('district', 'street')"></select>
|
||||
<select class="street form-control cx-select-input m-r" name="streetId" id="streetId" data-first-title="选择街道" ></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-board select-content m-t">
|
||||
<label class="form-control-label">类别筛选:</label>
|
||||
<div id="categoryCxSelect" class="flex-board-no-wrap">
|
||||
<select class="category1 form-control cx-select-input m-r" name="category1" id="category1" data-first-title="选择一类"></select>
|
||||
<select class="category2 form-control cx-select-input m-r" name="category2" id="category2" data-first-title="选择二类"></select>
|
||||
<select class="category3 form-control cx-select-input m-r" name="goodsCategoryId" id="category3" data-first-title="选择三类"></select>
|
||||
<select class="category4 form-control cx-select-input m-r" name="category4" id="category4" data-first-title="选择四类" ></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-board input-content m-t">
|
||||
<label class="form-control-label">名称/手机号:</label>
|
||||
<input name="keyWords" type="text" class="form-control normal-input m-r">
|
||||
</div>
|
||||
<div class="m-t">
|
||||
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search('workerForm')"><i
|
||||
class="fa fa-search"></i> 搜索</a>
|
||||
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset('workerForm')"><i
|
||||
class="fa fa-refresh"></i> 重置</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 select-table table-striped">
|
||||
<table id="bootstrap-table"></table>
|
||||
</div>
|
||||
</div>
|
||||
<th:block th:include="include :: footer"/>
|
||||
<th:block th:include="include :: jquery-cxselect-js" />
|
||||
<script type="text/javascript">
|
||||
var orderMasterId = '[[${orderId}]]';
|
||||
var prefix = ctx + "worker"
|
||||
|
||||
$(function () {
|
||||
loadCanAssignSpecInfo();
|
||||
initForm();
|
||||
initTable();
|
||||
});
|
||||
|
||||
function loadCanAssignSpecInfo() {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
dataType:"json",
|
||||
url: ctx + "order/can/assign",
|
||||
data: JSON.stringify({orderMasterId: orderMasterId}),
|
||||
contentType: 'application/json',
|
||||
success: function (result) {
|
||||
if (result.code == web_status.SUCCESS) {
|
||||
$('#canAssignSpecList').html('');
|
||||
$.each(result.data, function(index, spec) {
|
||||
$('#canAssignSpecList').append(
|
||||
'<div class="row m-b">' +
|
||||
' <div class="col-sm-6">' +
|
||||
' <input disabled class="form-control" value="' + spec.goodsName +'">' +
|
||||
' </div>' +
|
||||
' <div class="col-sm-2 specCanAssignNum">' +
|
||||
spec.goodsNum +
|
||||
' </div>' +
|
||||
'</div>'
|
||||
)
|
||||
});
|
||||
} else {
|
||||
$.modal.msgError("数据加载错误,请重试!")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
dataType:"json",
|
||||
url: ctx + "order/master/app/detail",
|
||||
data: JSON.stringify({id: orderMasterId}),
|
||||
contentType: 'application/json',
|
||||
success: function (result) {
|
||||
if (result.code == web_status.SUCCESS) {
|
||||
$('#moneyCanAssign').html(result.data.serverMoney);
|
||||
} else {
|
||||
$.modal.msgError("数据加载错误,请重试!")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function initForm() {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
dataType:"json",
|
||||
url: ctx + "system/area/list",
|
||||
success: function (result) {
|
||||
if (result.code == web_status.SUCCESS) {
|
||||
$('#areaCxSelect').cxSelect({
|
||||
selects: ['province', 'city', 'district', 'street'],
|
||||
jsonValue: 'areaId',
|
||||
jsonName: 'areaName',
|
||||
data: result.data
|
||||
});
|
||||
} else {
|
||||
$.modal.msgError("数据加载错误,请重试!")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
dataType:"json",
|
||||
url: ctx + "goods/deptcategory/app/list",
|
||||
data: JSON.stringify({deptId: 101, goodsCategoryId: 1}),
|
||||
contentType: 'application/json',
|
||||
success: function (result) {
|
||||
if (result.code == web_status.SUCCESS) {
|
||||
$('#categoryCxSelect').cxSelect({
|
||||
selects: ['category1', 'category2', 'category3', 'category4'],
|
||||
jsonValue: 'goodsCategoryId',
|
||||
jsonName: 'goodsCategoryName',
|
||||
jsonSub: 'child',
|
||||
data: result.data
|
||||
});
|
||||
} else {
|
||||
$.modal.msgError("数据加载错误,请重试!")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function initTable() {
|
||||
var options = {
|
||||
url: prefix + "/list",
|
||||
modalName: "师傅派单列表",
|
||||
firstLoad: false,
|
||||
columns: [
|
||||
{
|
||||
checkbox: true
|
||||
}, {
|
||||
field: 'name',
|
||||
title: '人员名称',
|
||||
align: "left"
|
||||
}, {
|
||||
field: 'phone',
|
||||
title: '手机号',
|
||||
align: "left"
|
||||
}, {
|
||||
title: '操作',
|
||||
align: 'left',
|
||||
formatter: function (value, row, index) {
|
||||
var actions = [];
|
||||
actions.push('<a class="btn btn-success btn-xs" href="javascript:void(0)" onclick="assign(' + row.workerId + ')">指派</a> ');
|
||||
return actions.join('');
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
$.table.init(options);
|
||||
$.table.search('workerForm');
|
||||
}
|
||||
|
||||
function selectRegion(regionLevelName, nextRegionLevelName) {
|
||||
var regionId = $("#" + regionLevelName).val();
|
||||
if ($.common.isEmpty(regionId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Ajax调用处理
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
dataType:"json",
|
||||
url: ctx + "system/area/list",
|
||||
data: {parentCode: regionId},
|
||||
success: function (result) {
|
||||
if (result.code == web_status.SUCCESS) {
|
||||
$('#areaCxSelect').cxSelect({
|
||||
selects: [nextRegionLevelName],
|
||||
jsonValue: 'areaId',
|
||||
jsonName: 'areaName',
|
||||
data: result.data
|
||||
});
|
||||
} else {
|
||||
$.modal.msgError("数据加载错误,请重试!")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function assign(workerId) {
|
||||
var params = {
|
||||
id: orderMasterId,
|
||||
workerId: workerId,
|
||||
orderStatus: 0
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
dataType:"json",
|
||||
url: ctx + "order/master/editOrderMaster",
|
||||
data: JSON.stringify(params),
|
||||
contentType: 'application/json',
|
||||
success: function (result) {
|
||||
if (result.code == web_status.SUCCESS) {
|
||||
$.modal.msgSuccess("指派成功")
|
||||
parent.layer.close(parent.layer.getFrameIndex(window.name));
|
||||
} else {
|
||||
$.modal.msgError("指派失败")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
|
||||
<head>
|
||||
<th:block th:include="include :: header('批量改价')" />
|
||||
</head>
|
||||
<body class="white-bg">
|
||||
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
|
||||
<form class="form-horizontal m" id="form-change-price">
|
||||
<input name="orderIds" type="hidden" th:value="${orderIds}" />
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">输入修改后价格:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="changePrice" id="changePrice">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<th:block th:include="include :: footer" />
|
||||
<script type="text/javascript">
|
||||
$("#changePrice").validate({
|
||||
rules:{
|
||||
changePrice:{
|
||||
required:true
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
function submitHandler() {
|
||||
if ($.validate.form()) {
|
||||
$.operate.save(ctx + "order/master/batchChangePrice", $('#form-change-price').serialize());
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
|
||||
<head>
|
||||
<th:block th:include="include :: header('选择保险')" />
|
||||
</head>
|
||||
<body class="white-bg">
|
||||
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
|
||||
<form class="form-horizontal m" id="form-change-insurance">
|
||||
<input name="orderMasterIds" type="hidden" th:value="${orderIds}" />
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">保险:</label>
|
||||
<div class="col-sm-8">
|
||||
<select id="insuranceId" name="insuranceId" class="form-control control-label" required>
|
||||
<option th:each="insurance:${insurances}" th:value="${insurance.id}" th:text="${insurance.insuranceName}" ></option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<th:block th:include="include :: footer" />
|
||||
<script type="text/javascript">
|
||||
function submitHandler() {
|
||||
if ($.validate.form()) {
|
||||
$.operate.save(ctx + "order/master/pcOrderWorker/batchChangeInsurance", $('#form-change-insurance').serialize());
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue