Compare commits
303 Commits
b9b7309edc
...
3d67fbbb62
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d67fbbb62 | ||
|
|
8af873ac42 | ||
|
|
7f88233f28 | ||
|
|
669be27e0a | ||
|
|
57f3270af2 | ||
|
|
b95c2f90d5 | ||
|
|
ce413c494c | ||
|
|
2e421a2968 | ||
|
|
4a620d46d5 | ||
|
|
23b2eded5a | ||
|
|
dbffda69fd | ||
|
|
7b3a16353c | ||
|
|
2c8b8b1aac | ||
|
|
2a1ceded61 | ||
|
|
d1313fca0c | ||
|
|
22ee293bfb | ||
|
|
e2b174a58f | ||
|
|
f5744c8d09 | ||
|
|
882be02d07 | ||
|
|
0b6428cf34 | ||
|
|
d0e0d17b5d | ||
|
|
1625975814 | ||
|
|
96c866f1d4 | ||
|
|
88ea78d67b | ||
|
|
8a349399e1 | ||
|
|
cefe601046 | ||
|
|
edc50a15ec | ||
|
|
f65ff33e19 | ||
|
|
9dad383b03 | ||
|
|
7cc1addfe4 | ||
|
|
d93b009816 | ||
|
|
2e4be2800f | ||
|
|
afe8b26eee | ||
|
|
394f0c6e46 | ||
|
|
91c984db43 | ||
|
|
3d000cdc14 | ||
|
|
e77638b0e1 | ||
|
|
90277394fa | ||
|
|
c24ddb4af2 | ||
|
|
a138cdbd01 | ||
|
|
df1b599e51 | ||
|
|
aa31451210 | ||
|
|
1b48a50da3 | ||
|
|
8e11157c92 | ||
|
|
9b09a33f47 | ||
|
|
3bb31daaa1 | ||
|
|
c67a7664ec | ||
|
|
9627cc12bf | ||
|
|
2b084bfdc9 | ||
|
|
68c332f20e | ||
|
|
2d897d26d0 | ||
|
|
9bb5f1b2dd | ||
|
|
a6f0d49c6e | ||
|
|
eb81faad39 | ||
|
|
2f45b83ba3 | ||
|
|
58d44a38a6 | ||
|
|
c04231d6d7 | ||
|
|
5584bfc4da | ||
|
|
b86d6748b4 | ||
|
|
fff760253a | ||
|
|
c6fa875148 | ||
|
|
543099c8d7 | ||
|
|
350f06116e | ||
|
|
77cb259124 | ||
|
|
5b483dadb5 | ||
|
|
5b0b45b141 | ||
|
|
8f8419b8c1 | ||
|
|
10e794110f | ||
|
|
501c4643f4 | ||
|
|
7883056ded | ||
|
|
c8e6467e9a | ||
|
|
3a9de995b2 | ||
|
|
a1bed56d19 | ||
|
|
a401d1e4c9 | ||
|
|
a8df57808f | ||
|
|
97ae9e4d8e | ||
|
|
8cf76c7051 | ||
|
|
a0106e30cc | ||
|
|
9e71d9a60f | ||
|
|
5e9c1df5da | ||
|
|
ba40f63b42 | ||
|
|
fec42ad634 | ||
|
|
21475d7d52 | ||
|
|
14e909a9a6 | ||
|
|
984690c47a | ||
|
|
ce31946e53 | ||
|
|
056fed40f1 | ||
|
|
8f92776103 | ||
|
|
2dc5a2435f | ||
|
|
8593eb2dd3 | ||
|
|
3105c29071 | ||
|
|
6e8d47ae91 | ||
|
|
2068825ae1 | ||
|
|
3f0d8d017e | ||
|
|
019a717706 | ||
|
|
11ef2223d3 | ||
|
|
ae27baa79b | ||
|
|
73caa3cedd | ||
|
|
1cfbbe7283 | ||
|
|
cbb57c8c34 | ||
|
|
83ef491069 | ||
|
|
0ce7cf8f17 | ||
|
|
32cda95788 | ||
|
|
83585d1c37 | ||
|
|
142bdbdcb9 | ||
|
|
d054d1a9ba | ||
|
|
b4e98d5238 | ||
|
|
ff0960e2bb | ||
|
|
bdb093e7da | ||
|
|
41949bef72 | ||
|
|
d73d748436 | ||
|
|
16acfb7320 | ||
|
|
9fdc5b4dbf | ||
|
|
f42c8bd18c | ||
|
|
ba3e7ce31b | ||
|
|
12a6e95a11 | ||
|
|
e91bc83912 | ||
|
|
49877b4ef7 | ||
|
|
23b8e3cf3c | ||
|
|
7c065901c4 | ||
|
|
17dc892c07 | ||
|
|
634f1b9584 | ||
|
|
9faae14892 | ||
|
|
6bd9a0ab05 | ||
|
|
8d4901cdcd | ||
|
|
af35164fb2 | ||
|
|
1a3fbfb175 | ||
|
|
939ee8e0fe | ||
|
|
f5de417b99 | ||
|
|
4dce0d7087 | ||
|
|
d2f24772ca | ||
|
|
d69870c882 | ||
|
|
96b69fc8b9 | ||
|
|
066c911439 | ||
|
|
885aa081c6 | ||
|
|
d191bb3ca4 | ||
|
|
fdcd485f9f | ||
|
|
88f407edb9 | ||
|
|
6dc591283e | ||
|
|
ddfe91a42e | ||
|
|
8c69e4d2d3 | ||
|
|
296194e730 | ||
|
|
a59273fe5b | ||
|
|
385540937e | ||
|
|
d146fbb631 | ||
|
|
bdf0dd7605 | ||
|
|
cfea0cb09b | ||
|
|
23094b2427 | ||
|
|
7a2820e496 | ||
|
|
0f7d35ea00 | ||
|
|
243fd29a60 | ||
|
|
98967990e7 | ||
|
|
8bc1607f00 | ||
|
|
b93691a0bf | ||
|
|
bfeacad5f0 | ||
|
|
f8c8c634cb | ||
|
|
24304b0c85 | ||
|
|
32b8ceeb96 | ||
|
|
fa011a1670 | ||
|
|
0410685138 | ||
|
|
0fde3c8d91 | ||
|
|
cb4e15e54b | ||
|
|
f933fcac69 | ||
|
|
e87ece4071 | ||
|
|
1480298bd7 | ||
|
|
414a3f8507 | ||
|
|
3f78cfd824 | ||
|
|
ae2c41364f | ||
|
|
0350315354 | ||
|
|
6aa842e328 | ||
|
|
ced3ce8657 | ||
|
|
d4867a7089 | ||
|
|
e031f804f3 | ||
|
|
73a67aa21a | ||
|
|
e46ac8ff63 | ||
|
|
734c4e9102 | ||
|
|
f2226ff0e4 | ||
|
|
e9f6b6cc68 | ||
|
|
da162f859e | ||
|
|
586e02c842 | ||
|
|
0b0e08c377 | ||
|
|
679a0c660f | ||
|
|
7b124d95c1 | ||
|
|
ff086a8fa4 | ||
|
|
560bc9a7d2 | ||
|
|
f5620e397e | ||
|
|
807f1aa70e | ||
|
|
c57f2acafd | ||
|
|
66acaa6095 | ||
|
|
e042cf209d | ||
|
|
9cfdfdbc77 | ||
|
|
0b8fc0915b | ||
|
|
342d1f99ec | ||
|
|
7301463857 | ||
|
|
7fa7b868ca | ||
|
|
67fe103ac1 | ||
|
|
34b2aef763 | ||
|
|
9858300984 | ||
|
|
6cdb8b6e6b | ||
|
|
a8a7132a66 | ||
|
|
1f46911f51 | ||
|
|
b0203593bb | ||
|
|
f980520ba7 | ||
|
|
550ca5b7b9 | ||
|
|
9dbcf33cb9 | ||
|
|
7d3f614356 | ||
|
|
6a35779bd5 | ||
|
|
a9bb36d394 | ||
|
|
87dd183279 | ||
|
|
6743f4dff1 | ||
|
|
e6d4e84fd4 | ||
|
|
eb4fd9cff9 | ||
|
|
ce35498c7e | ||
|
|
fcb3dd13c6 | ||
|
|
2261421ba5 | ||
|
|
fdd6ac9b44 | ||
|
|
a10d41405b | ||
|
|
8870b389be | ||
|
|
df5414fc1d | ||
|
|
8d987c4c54 | ||
|
|
c2f61fc61a | ||
|
|
122d558765 | ||
|
|
d113ef1c6e | ||
|
|
aafcbfcf50 | ||
|
|
cf83bd068b | ||
|
|
cc6da9a648 | ||
|
|
7c0b1107f8 | ||
|
|
d7894fd5c8 | ||
|
|
3a51a5f297 | ||
|
|
821c2063c9 | ||
|
|
e991ee3966 | ||
|
|
642ca772e8 | ||
|
|
de751d5d68 | ||
|
|
f7d0a6422e | ||
|
|
649e635d17 | ||
|
|
989b2daacc | ||
|
|
db0c8a2532 | ||
|
|
316ebd9fca | ||
|
|
6072341a2b | ||
|
|
1f9123c0f4 | ||
|
|
91bc3310a1 | ||
|
|
d92c77766c | ||
|
|
4032255694 | ||
|
|
b7a41d39e3 | ||
|
|
7573f9ccf6 | ||
|
|
5ecb8537c2 | ||
|
|
cb378afb1f | ||
|
|
06ab4a596f | ||
|
|
ccc5a2dabc | ||
|
|
4cb921853e | ||
|
|
4a55844d73 | ||
|
|
fbeebabf27 | ||
|
|
8d9ff4fe10 | ||
|
|
f68032c8ea | ||
|
|
39efb7eefb | ||
|
|
fef541dfe5 | ||
|
|
8bce140dd2 | ||
|
|
60749646e2 | ||
|
|
13420cd400 | ||
|
|
50c5e28381 | ||
|
|
b6d0ef1c7c | ||
|
|
1dfa390557 | ||
|
|
142ada5b07 | ||
|
|
e917792988 | ||
|
|
b6d4d06c25 | ||
|
|
31b712784f | ||
|
|
0a8f3cd5ba | ||
|
|
89e8b4cff9 | ||
|
|
2f4f59d6ab | ||
|
|
43752954ae | ||
|
|
9e2526405f | ||
|
|
2ac507ef34 | ||
|
|
59114aa94a | ||
|
|
d5e5f7e6e2 | ||
|
|
02f2e08329 | ||
|
|
3dc822fcde | ||
|
|
d61e939685 | ||
|
|
fe57705286 | ||
|
|
b4f201eb98 | ||
|
|
943eba6f1a | ||
|
|
8654ab3ecd | ||
|
|
82ce9a5114 | ||
|
|
465bc5e62d | ||
|
|
788dbd325e | ||
|
|
53446bb606 | ||
|
|
945a8ec83c | ||
|
|
5fcd76e32e | ||
|
|
840f7c8675 | ||
|
|
4ea3487043 | ||
|
|
887bc555fa | ||
|
|
4e45e1e393 | ||
|
|
884ce87972 | ||
|
|
9de1099b12 | ||
|
|
899db716f1 | ||
|
|
2eadff7876 | ||
|
|
0967df9113 | ||
|
|
36ae64f3e7 | ||
|
|
ab916ac13d | ||
|
|
6eccd11386 | ||
|
|
f876971e50 | ||
|
|
e6bd26a775 | ||
|
|
6c53238457 | ||
|
|
032d089359 |
@ -1,7 +0,0 @@
|
|||||||
package constants
|
|
||||||
|
|
||||||
// 千人千面windows访问图片的地址
|
|
||||||
const DOMAIN_RENDER_IMG_NAME = "https://fusenrenderimg.kayue.cn"
|
|
||||||
|
|
||||||
// 云渲染域名和访问地址
|
|
||||||
const DOMAIN_NAME = "https://fusenapi.kayue.cn:8010/"
|
|
||||||
@ -1,7 +1,8 @@
|
|||||||
package constants
|
package constants
|
||||||
|
|
||||||
// 主体页面
|
// 发票主体页面
|
||||||
const MAIN_INVOICE_HTML = `<!DOCTYPE html>
|
const MAIN_INVOICE_HTML = `
|
||||||
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
@ -9,230 +10,235 @@ const MAIN_INVOICE_HTML = `<!DOCTYPE html>
|
|||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Invoice</title>
|
<title>Invoice</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header_warp {
|
||||||
|
background-color: #F8F8FA;
|
||||||
|
padding: 20px 5% 20px 6%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header_td {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header_td.logo {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header_logo {
|
||||||
|
max-height: 15px;
|
||||||
|
max-width: 100%;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header_td.title {
|
||||||
|
color: #212121;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.information_warp {
|
||||||
|
padding: 30px 5% 30px 6%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.information_td {
|
||||||
|
width: 50%;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 20px;
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.information_td.bill {
|
||||||
|
color: #212121;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.information_td.right {
|
||||||
|
color: #212121;
|
||||||
|
}
|
||||||
|
|
||||||
|
.information_td.info {
|
||||||
|
color: #666666;
|
||||||
|
line-height: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bill_warp {
|
||||||
|
padding: 0 5% 0 6%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bill_td {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bill_td:first-child {
|
||||||
|
width: 47.59%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bill_td.title {
|
||||||
|
border-top: 2px solid #333;
|
||||||
|
padding: 13px 0 7px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #212121;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bill_td.info {
|
||||||
|
color: #666;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
padding: 8px 0;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bill_warp tr:last-child .bill_td.info {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.total_warp {
|
||||||
|
padding: 14px 5% 24px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.total_td {
|
||||||
|
color: #212121;
|
||||||
|
padding: 8px 0 7px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.total_td.info {
|
||||||
|
color: #666;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.total_td.border-dashed {
|
||||||
|
border-bottom: 1px dashed #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.total_td.border-solid {
|
||||||
|
border-bottom: 2px solid #333;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.total_td.total {
|
||||||
|
padding-top: 12px;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notes_warp {
|
||||||
|
padding: 0 5% 0 6%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notes_td {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #666;
|
||||||
|
font-weight: 300;
|
||||||
|
width: 50%;
|
||||||
|
line-height: 21px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notes_td.title {
|
||||||
|
color: #212121;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notes_td.notes {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body style="margin: 0;">
|
<body>
|
||||||
<!-- header -->
|
<!-- header -->
|
||||||
<table border="0" align="center" cellpadding="0" cellspacing="0" width="100%"
|
<table class="header_warp" border="0" align="center" cellpadding="0" cellspacing="0" width="100%">
|
||||||
style="background-color: #F8F8FA;padding: 0 5%;">
|
|
||||||
<tr height="30px"></tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td align="left" rowspan="9" style="vertical-align: top; width: 50%;">
|
<td class="header_td logo" align="left">
|
||||||
<img style="max-height: 40px;max-width: 100%;"
|
<img class="header_logo" src="https://fusenapi.kayue.cn:8010/storage/email/logo.png" alt="logo">
|
||||||
src="{{h5Url}}/storage/email/logo.png" alt="logo">
|
|
||||||
</td>
|
|
||||||
<td align="left" style="width: 50%;">
|
|
||||||
<span style="color: #212121;font-weight: bold;font-size: 42px; display: block;">Invoice</span>
|
|
||||||
</td>
|
</td>
|
||||||
|
<td class="header_td title" align="right">Invoice</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr height="30px"></tr>
|
</table>
|
||||||
|
<!-- information -->
|
||||||
|
<table class="information_warp" border="0" align="center" cellpadding="0" cellspacing="0" width="100%">
|
||||||
<tr>
|
<tr>
|
||||||
<td align="left" style="width: 50%;">
|
<td class="information_td bill" align="left">Bill To:</td>
|
||||||
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">Invoice Number:</span>
|
<td class="information_td right" align="right">Invoice No. {{invoice_number}}</td>
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr height="15px"></tr>
|
|
||||||
<tr>
|
|
||||||
<td align="left" style="width: 50%;">
|
|
||||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">{{order_sn}}</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr height="30px"></tr>
|
|
||||||
<tr>
|
|
||||||
<td align="left" style="width: 50%;">
|
|
||||||
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">Date:</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr height="15px"></tr>
|
|
||||||
<tr>
|
|
||||||
<td align="left" style="width: 50%;">
|
|
||||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">{{order_expire_time}}</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr height="30px"></tr>
|
|
||||||
</table>
|
|
||||||
<!-- information -->
|
|
||||||
<table border="0" align="center" cellpadding="0" cellspacing="0" width="100%"
|
|
||||||
style="background-color: #fff;padding: 0 5%;">
|
|
||||||
<tr height="30px"></tr>
|
|
||||||
<tr>
|
|
||||||
<td align="left" style="width: 50%;">
|
|
||||||
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">Bill To:</span>
|
|
||||||
</td>
|
|
||||||
<td align="left" style="width: 50%;">
|
|
||||||
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">Bill From:</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr height="15px"></tr>
|
|
||||||
<tr>
|
|
||||||
<td align="left" style="width: 50%;">
|
|
||||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">{{name}}</span>
|
|
||||||
</td>
|
|
||||||
<td align="left" style="width: 50%;">
|
|
||||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">Lemon
|
|
||||||
Squeezy LLC</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td align="left" style="width: 50%;">
|
<td class="information_td info" align="left">{{buyer_name}}</td>
|
||||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">{{street}} {{suite}}</span>
|
<td class="information_td right" align="right">Date: {{buy_date}}</td>
|
||||||
</td>
|
|
||||||
<td align="left" style="width: 50%;">
|
|
||||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">Lemon
|
|
||||||
Squeezy LLC</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td align="left" style="width: 50%;">
|
<td class="information_td info" align="left">{{street}}</td>
|
||||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">{{city}} {{state}} {{zip_code}}</span>
|
<td class="information_td" align="right"></td>
|
||||||
</td>
|
|
||||||
<td align="left" style="width: 50%;">
|
|
||||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">Lemon
|
|
||||||
Squeezy LLC</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td align="left" style="width: 50%;">
|
<td class="information_td info" align="left">{{city}}</td>
|
||||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;"> </span>
|
<td class="information_td" align="right"></td>
|
||||||
</td>
|
|
||||||
<td align="left" style="width: 50%;">
|
|
||||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">Lemon
|
|
||||||
Squeezy LLC</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr height="30px"></tr>
|
|
||||||
</table>
|
|
||||||
<!-- bill -->
|
|
||||||
<table border="0" align="center" cellpadding="0" cellspacing="0" width="100%"
|
|
||||||
style="background-color: #F8F8FA;padding: 0 5%;">
|
|
||||||
<tr>
|
<tr>
|
||||||
<td align="left" style="width: 50%;">
|
<td class="information_td info" align="left">{{country}}</td>
|
||||||
<span
|
<td class="information_td" align="right"></td>
|
||||||
style="color: #212121;font-weight: bold;font-size: 22px; display: block; line-height: 70px;">Product
|
|
||||||
Name</span>
|
|
||||||
</td>
|
|
||||||
<td align="left" style="width: 16.66%;">
|
|
||||||
<span style="color: #212121;font-weight: bold;font-size: 22px; display: block; line-height: 70px;">Unit
|
|
||||||
Price</span>
|
|
||||||
</td>
|
|
||||||
<td align="center" style="width: 16.66%;">
|
|
||||||
<span
|
|
||||||
style="color: #212121;font-weight: bold;font-size: 22px; display: block; line-height: 70px;">Quantity</span>
|
|
||||||
</td>
|
|
||||||
<td align="right" style="width: 16.66%;">
|
|
||||||
<span
|
|
||||||
style="color: #212121;font-weight: bold;font-size: 22px; display: block; line-height: 70px;">Total</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<table border="0" align="center" cellpadding="0" cellspacing="0" width="100%"
|
<!-- bill -->
|
||||||
style="background-color: #fff;padding: 0 5%;">
|
<table class="bill_warp" border="0" align="center" cellpadding="0" cellspacing="0" width="100%">
|
||||||
<tr height="30px"></tr>
|
<!--循环部分-->
|
||||||
{{orderHTML}}
|
{{product_loop_html}}
|
||||||
|
<!--循环部分-->
|
||||||
|
</table>
|
||||||
|
<!-- total -->
|
||||||
|
<table class="total_warp" border="0" align="right" cellpadding="0" cellspacing="0" width="50%">
|
||||||
<tr>
|
<tr>
|
||||||
<td align="left" colspan="2">
|
<td class="total_td" align="right">Subtotal</td>
|
||||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">Subtotal</span>
|
<td class="total_td info" align="right">${{subtotal_price}}</td>
|
||||||
</td>
|
|
||||||
<td align="right" style="width: 16.66%;">
|
|
||||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">${{total_amount}}</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr height="15px"></tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td align="left" colspan="2">
|
<td class="total_td" align="right">Shipping Fee</td>
|
||||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">Tax</span>
|
<td class="total_td info" align="right">Free</td>
|
||||||
</td>
|
|
||||||
<td align="right" style="width: 16.66%;">
|
|
||||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">$0.00</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr height="15px"></tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td align="left" colspan="2">
|
<td class="total_td border-dashed" align="right">Tax</td>
|
||||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">Invoice Total</span>
|
<td class="total_td info border-dashed" align="right">${{tax}}</td>
|
||||||
</td>
|
|
||||||
<td align="right" style="width: 16.66%;">
|
|
||||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">${{total_amount}}</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr height="15px"></tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td align="left" colspan="2" {{first_style1}}>
|
<td class="total_td" align="right">Total</td>
|
||||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">First Payment</span>
|
<td class="total_td info" align="right">${{total_price}}</td>
|
||||||
</td>
|
|
||||||
<td align="right" {{first_style2}}>
|
|
||||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">-${{first_payment}}</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr height="15px"></tr>
|
|
||||||
{{second_payment_html}}
|
|
||||||
<tr height="15px"></tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td align="left" colspan="2">
|
<td class="total_td border-solid" align="right">Deposit Requested</td>
|
||||||
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">Amount Due</span>
|
<td class="total_td info border-solid" align="right">${{deposit_price}}</td>
|
||||||
</td>
|
|
||||||
<td align="right" style="width: 16.66%;">
|
|
||||||
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">${{amount_due}}</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr height="88px"></tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td align="left" colspan="4">
|
<td class="total_td total" align="right">Deposit Due</td>
|
||||||
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">Payment Method:</span>
|
<td class="total_td total" align="right">${{deposit_price}}</td>
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
{{pay_html}}
|
</table>
|
||||||
<tr height="30px"></tr>
|
<!-- notes -->
|
||||||
|
<table class="notes_warp" border="0" align="center" cellpadding="0" cellspacing="0" width="100%">
|
||||||
<tr>
|
<tr>
|
||||||
<td align="left" colspan="4">
|
<td class="notes_td title" align="left">Payment Method:</td>
|
||||||
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">Notes:</span>
|
<td class="notes_td title" align="left">Notes:</td>
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr height="15px"></tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td align="left" colspan="4">
|
<td class="notes_td" align="left">{{payment_method}}</td>
|
||||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">Add a note...</span>
|
<td class="notes_td notes" align="left" rowspan="2">{{notes}}</td>
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<!-- <tr height="80px"></tr> -->
|
<tr>
|
||||||
</table>
|
<td class="notes_td" align="left">Account No. {{account_number}}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>`
|
</html>
|
||||||
|
|
||||||
// 发票支付html模板
|
`
|
||||||
const PAYMENT_HTML = `<tr height="15px"></tr>
|
|
||||||
<tr>
|
// 产品循环部分{{product_loop_html}}
|
||||||
<td align="left" colspan="4">
|
const PRODUCT_LOOP_HTML_CONTENT = ` <tr>
|
||||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">${{pay_amount}} payment from {{brand}}
|
<td class="bill_td title" align="left">{{product_name}}</td>
|
||||||
····{{card_no}}</span>
|
<td class="bill_td title" align="right">${{product_item_price}}</td>
|
||||||
</td>
|
<td class="bill_td title" align="right">{{purchase_quantity}}</td>
|
||||||
|
<td class="bill_td title" align="right">${{product_total_price}}</td>
|
||||||
</tr>`
|
</tr>`
|
||||||
|
|
||||||
// 二次支付html
|
|
||||||
const SECOND_PAYMENY_HTML = `<tr>
|
|
||||||
<td align="left" colspan="2" style="padding-bottom: 20px; border-bottom: 1px solid #212121;">
|
|
||||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">Second Payment</span>
|
|
||||||
</td>
|
|
||||||
<td align="right" style="width: 16.66%; padding-bottom: 20px; border-bottom: 1px solid #212121;">
|
|
||||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">-${{remain_amount}}</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr height="15px"></tr>`
|
|
||||||
|
|
||||||
// order html
|
|
||||||
const ORDER_HTML = `<tr>
|
|
||||||
<td align="left" style="width: 50%;{{style1}}" {{rowspan}}">
|
|
||||||
<span style="color: #212121;font-weight: bold;font-size: 22px; display: block;">{{product_title}}</span>
|
|
||||||
</td>
|
|
||||||
<td align="left" style="width: 16.66%;{{style2}}">
|
|
||||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">${{amount}}</span>
|
|
||||||
</td>
|
|
||||||
<td align="center" style="width: 16.66%;' . $style2 . '">
|
|
||||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">{{buy_num}}pcs</span>
|
|
||||||
</td>
|
|
||||||
<td align="right" style="width: 16.66%;' . $style2 . '">
|
|
||||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">${{sum_amount}}</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr height="15px"></tr>`
|
|
||||||
|
|||||||
@ -2,8 +2,8 @@ package constants
|
|||||||
|
|
||||||
// 订单类型
|
// 订单类型
|
||||||
const (
|
const (
|
||||||
DELIVERYMETHODDIRECTMAIL int64 = 1
|
DELIVERYMETHODDIRECTMAIL int64 = 1 // 直邮
|
||||||
DELIVERYMETHODDSCLOUDSTORE int64 = 2
|
DELIVERYMETHODDSCLOUDSTORE int64 = 2 // 云仓
|
||||||
)
|
)
|
||||||
|
|
||||||
// 货币
|
// 货币
|
||||||
@ -24,16 +24,16 @@ type PayMethods string
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
PAY_METHOD_CARD PayMethods = "CARD"
|
PAY_METHOD_CARD PayMethods = "CARD"
|
||||||
PayMethodVISA PayMethods = "VISA"
|
PAY_METHOD_VISA PayMethods = "VISA"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 支付状态
|
// 支付状态
|
||||||
type PayStatusCode int64
|
type PayStatusCode int64
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PAYSTATUSUNPAID PayStatusCode = 10 //10,未支付
|
PAY_STATUS_UNPAID PayStatusCode = 10 //10,未支付
|
||||||
PAYSTATUSPAID PayStatusCode = 20 //20,已支付
|
PAY_STATUS_PAID PayStatusCode = 20 //20,已支付
|
||||||
PAYSTATUSREFUNDED PayStatusCode = 30 //30,已退款
|
PAY_STATUS_REFUNDED PayStatusCode = 30 //30,已退款
|
||||||
)
|
)
|
||||||
|
|
||||||
// 订单支付状态
|
// 订单支付状态
|
||||||
@ -45,11 +45,11 @@ type OrderPayStatusCode int64
|
|||||||
// 30,已付尾款
|
// 30,已付尾款
|
||||||
// 40,已退尾款
|
// 40,已退尾款
|
||||||
const (
|
const (
|
||||||
ORDERPAYSTATUSUNPAIDDEPOSIT OrderPayStatusCode = 0
|
ORDER_PAY_STATUS_UNPAIDDEPOSIT OrderPayStatusCode = 0
|
||||||
ORDERPAYSTATUSPAIDDEPOSIT OrderPayStatusCode = 10
|
ORDER_PAY_STATUS_PAIDDEPOSIT OrderPayStatusCode = 10
|
||||||
ORDERPAYSTATUSREFUNDEDDEPOSIT OrderPayStatusCode = 20
|
ORDER_PAY_STATUS_REFUNDEDDEPOSIT OrderPayStatusCode = 20
|
||||||
ORDERPAYSTATUSPAIDDREMAINING OrderPayStatusCode = 30
|
ORDER_PAY_STATUS_PAIDDREMAINING OrderPayStatusCode = 30
|
||||||
ORDERPAYSTATUSREFUNDEDREMAINING OrderPayStatusCode = 40
|
ORDER_PAY_STATUS_REFUNDEDREMAINING OrderPayStatusCode = 40
|
||||||
)
|
)
|
||||||
|
|
||||||
// 订单状态
|
// 订单状态
|
||||||
@ -57,6 +57,10 @@ type OrderStatusCode int64
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
ORDER_STATUS_UNPAIDDEPOSIT OrderStatusCode = 0 // 0,未支付定金
|
ORDER_STATUS_UNPAIDDEPOSIT OrderStatusCode = 0 // 0,未支付定金
|
||||||
|
ORDER_STATUS_CLOSE OrderStatusCode = 10 // 10,订单已关闭
|
||||||
|
ORDER_STATUS_COMPLETE OrderStatusCode = 20 // 20,订单已完成
|
||||||
|
ORDER_STATUS_DELETE OrderStatusCode = 30 // 20,订单已删除
|
||||||
|
|
||||||
ORDER_STATUS_DIRECTMAIL_ORDERED OrderStatusCode = 10100 // 10100,直邮单--已下单
|
ORDER_STATUS_DIRECTMAIL_ORDERED OrderStatusCode = 10100 // 10100,直邮单--已下单
|
||||||
ORDER_STATUS_DIRECTMAIL_ORDEREDMAINING OrderStatusCode = 10100001 // 10100001,直邮单--已下单--尾款
|
ORDER_STATUS_DIRECTMAIL_ORDEREDMAINING OrderStatusCode = 10100001 // 10100001,直邮单--已下单--尾款
|
||||||
ORDER_STATUS_DIRECTMAIL_CANCEL OrderStatusCode = 10101 // 10101,直邮单--已取消
|
ORDER_STATUS_DIRECTMAIL_CANCEL OrderStatusCode = 10101 // 10101,直邮单--已取消
|
||||||
@ -64,13 +68,13 @@ const (
|
|||||||
ORDER_STATUS_DIRECTMAIL_COMPLETEPRODUCTION OrderStatusCode = 10300 // 10300,直邮单--生产完成
|
ORDER_STATUS_DIRECTMAIL_COMPLETEPRODUCTION OrderStatusCode = 10300 // 10300,直邮单--生产完成
|
||||||
ORDER_STATUS_DIRECTMAIL_SHIPPED OrderStatusCode = 10400 // 10400,直邮单--已发货
|
ORDER_STATUS_DIRECTMAIL_SHIPPED OrderStatusCode = 10400 // 10400,直邮单--已发货
|
||||||
ORDER_STATUS_DIRECTMAIL_ARRIVED OrderStatusCode = 10500 // 10500,直邮单--已到达
|
ORDER_STATUS_DIRECTMAIL_ARRIVED OrderStatusCode = 10500 // 10500,直邮单--已到达
|
||||||
|
|
||||||
ORDER_STATUS_CLOUDSTORE_ORDERED OrderStatusCode = 20100 // 20100,云仓单--已下单
|
ORDER_STATUS_CLOUDSTORE_ORDERED OrderStatusCode = 20100 // 20100,云仓单--已下单
|
||||||
ORDER_STATUS_CLOUDSTORE_ORDEREDMAINING OrderStatusCode = 20100001 // 20100001,云仓单--已下单-尾款
|
ORDER_STATUS_CLOUDSTORE_ORDEREDMAINING OrderStatusCode = 20100001 // 20100001,云仓单--已下单-尾款
|
||||||
ORDER_STATUS_CLOUDSTORE_CANCEL OrderStatusCode = 20101 // 20101,云仓单--已取消
|
ORDER_STATUS_CLOUDSTORE_CANCEL OrderStatusCode = 20101 // 20101,云仓单--已取消
|
||||||
ORDER_STATUS_CLOUDSTORE_STARTPRODUCTION OrderStatusCode = 20200 // 20200,云仓单--开始生产
|
ORDER_STATUS_CLOUDSTORE_STARTPRODUCTION OrderStatusCode = 20200 // 20200,云仓单--开始生产
|
||||||
ORDER_STATUS_CLOUDSTORE_COMPLETEPRODUCTION OrderStatusCode = 20300 // 20300,云仓单--生产完成
|
ORDER_STATUS_CLOUDSTORE_COMPLETEPRODUCTION OrderStatusCode = 20300 // 20300,云仓单--生产完成
|
||||||
ORDER_STATUS_CLOUDSTORE_ARRIVEDWAREHOUSE OrderStatusCode = 20400 // 20400,云仓单--直达仓库
|
ORDER_STATUS_CLOUDSTORE_ARRIVEDWAREHOUSE OrderStatusCode = 20400 // 20400,云仓单--直达仓库
|
||||||
ORDER_STATUS_COMPLETE OrderStatusCode = 30000 // 30000,订单完成
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// 订单状态名称
|
// 订单状态名称
|
||||||
@ -79,6 +83,9 @@ var OrderStatusMessage map[OrderStatusCode]string
|
|||||||
// 支付状态名称
|
// 支付状态名称
|
||||||
var PayStatusMessage map[PayStatusCode]string
|
var PayStatusMessage map[PayStatusCode]string
|
||||||
|
|
||||||
|
// 支付状态名称
|
||||||
|
var OrderPayStatusMessage map[OrderPayStatusCode]string
|
||||||
|
|
||||||
// 订单状态--用户可见--直邮
|
// 订单状态--用户可见--直邮
|
||||||
var OrderStatusUserDIRECTMAIL []OrderStatusCode
|
var OrderStatusUserDIRECTMAIL []OrderStatusCode
|
||||||
|
|
||||||
@ -86,37 +93,50 @@ var OrderStatusUserDIRECTMAIL []OrderStatusCode
|
|||||||
var OrderStatusUserCLOUDSTORE []OrderStatusCode
|
var OrderStatusUserCLOUDSTORE []OrderStatusCode
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
// 订单状态名称
|
||||||
|
OrderPayStatusMessage = make(map[OrderPayStatusCode]string)
|
||||||
|
OrderPayStatusMessage[ORDER_PAY_STATUS_UNPAIDDEPOSIT] = "Deposit Payment Unpaid"
|
||||||
|
OrderPayStatusMessage[ORDER_PAY_STATUS_PAIDDEPOSIT] = "Deposit Payment Paid"
|
||||||
|
OrderPayStatusMessage[ORDER_PAY_STATUS_REFUNDEDDEPOSIT] = "Deposit Payment Refunded"
|
||||||
|
OrderPayStatusMessage[ORDER_PAY_STATUS_PAIDDREMAINING] = "Final Payment Paid"
|
||||||
|
OrderPayStatusMessage[ORDER_PAY_STATUS_REFUNDEDREMAINING] = "Final Payment Refunded"
|
||||||
|
|
||||||
// 订单状态名称
|
// 订单状态名称
|
||||||
PayStatusMessage = make(map[PayStatusCode]string)
|
PayStatusMessage = make(map[PayStatusCode]string)
|
||||||
PayStatusMessage[PAYSTATUSUNPAID] = "Unpaid"
|
PayStatusMessage[PAY_STATUS_UNPAID] = "Unpaid"
|
||||||
PayStatusMessage[PAYSTATUSPAID] = "Paid"
|
PayStatusMessage[PAY_STATUS_PAID] = "Paid"
|
||||||
PayStatusMessage[PAYSTATUSREFUNDED] = "Refunded"
|
PayStatusMessage[PAY_STATUS_REFUNDED] = "Refunded"
|
||||||
|
|
||||||
// 订单状态名称
|
// 订单状态名称
|
||||||
OrderStatusMessage = make(map[OrderStatusCode]string)
|
OrderStatusMessage = make(map[OrderStatusCode]string)
|
||||||
OrderStatusMessage[ORDER_STATUS_UNPAIDDEPOSIT] = "未支付定金"
|
OrderStatusMessage[ORDER_STATUS_UNPAIDDEPOSIT] = "Deposit Payment Unpaid" // 首款未支付
|
||||||
|
OrderStatusMessage[ORDER_STATUS_CLOSE] = "Closed" // 已关闭
|
||||||
|
OrderStatusMessage[ORDER_STATUS_COMPLETE] = "Completed" // 已完成
|
||||||
|
OrderStatusMessage[ORDER_STATUS_DELETE] = "Deleted" // 已删除
|
||||||
|
|
||||||
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_ORDERED] = "直邮单--已下单"
|
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_ORDERED] = "Order" // 直邮单--已下单
|
||||||
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_STARTPRODUCTION] = "直邮单--开始生产"
|
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_ORDEREDMAINING] = "Final Payment Paid" // 直邮单--已下单--尾款
|
||||||
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_COMPLETEPRODUCTION] = "直邮单--生产完成"
|
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_STARTPRODUCTION] = "Start Production" // 直邮单--开始生产
|
||||||
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_SHIPPED] = "直邮单--已发货"
|
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_COMPLETEPRODUCTION] = "Production Complete" // 直邮单--生产完成
|
||||||
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_ARRIVED] = "直邮单--已到达"
|
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_SHIPPED] = "Shipped" // 直邮单--已发货
|
||||||
|
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_ARRIVED] = "Delivered" // 直邮单--已到达
|
||||||
|
|
||||||
OrderStatusMessage[ORDER_STATUS_CLOUDSTORE_ORDERED] = "云仓单--已下单"
|
OrderStatusMessage[ORDER_STATUS_CLOUDSTORE_ORDERED] = "Order" // 云仓单--已下单
|
||||||
OrderStatusMessage[ORDER_STATUS_CLOUDSTORE_STARTPRODUCTION] = "云仓单--开始生产"
|
OrderStatusMessage[ORDER_STATUS_CLOUDSTORE_ORDEREDMAINING] = "Final Payment Paid" // 云仓单--已下单-尾款
|
||||||
OrderStatusMessage[ORDER_STATUS_CLOUDSTORE_COMPLETEPRODUCTION] = "云仓单--生产完成"
|
OrderStatusMessage[ORDER_STATUS_CLOUDSTORE_STARTPRODUCTION] = "Start Production" // 云仓单--开始生产
|
||||||
OrderStatusMessage[ORDER_STATUS_CLOUDSTORE_ARRIVEDWAREHOUSE] = "云仓单--直达仓库"
|
OrderStatusMessage[ORDER_STATUS_CLOUDSTORE_COMPLETEPRODUCTION] = "Production Complete" // 云仓单--生产完成
|
||||||
|
OrderStatusMessage[ORDER_STATUS_CLOUDSTORE_ARRIVEDWAREHOUSE] = "Arrived Inventory" // 云仓单--直达仓库
|
||||||
OrderStatusMessage[ORDER_STATUS_COMPLETE] = "订单完成"
|
|
||||||
|
|
||||||
// 订单状态--用户可见--直邮
|
// 订单状态--用户可见--直邮
|
||||||
OrderStatusUserDIRECTMAIL = []OrderStatusCode{
|
OrderStatusUserDIRECTMAIL = []OrderStatusCode{
|
||||||
ORDER_STATUS_UNPAIDDEPOSIT, ORDER_STATUS_COMPLETE,
|
ORDER_STATUS_UNPAIDDEPOSIT,
|
||||||
ORDER_STATUS_DIRECTMAIL_ORDERED, ORDER_STATUS_DIRECTMAIL_STARTPRODUCTION, ORDER_STATUS_DIRECTMAIL_COMPLETEPRODUCTION, ORDER_STATUS_DIRECTMAIL_SHIPPED, ORDER_STATUS_DIRECTMAIL_ARRIVED,
|
ORDER_STATUS_DIRECTMAIL_ORDERED, ORDER_STATUS_DIRECTMAIL_STARTPRODUCTION, ORDER_STATUS_DIRECTMAIL_COMPLETEPRODUCTION, ORDER_STATUS_DIRECTMAIL_SHIPPED, ORDER_STATUS_DIRECTMAIL_ARRIVED,
|
||||||
|
ORDER_STATUS_COMPLETE, ORDER_STATUS_CLOSE,
|
||||||
}
|
}
|
||||||
// 订单状态--用户可见--云仓
|
// 订单状态--用户可见--云仓
|
||||||
OrderStatusUserCLOUDSTORE = []OrderStatusCode{
|
OrderStatusUserCLOUDSTORE = []OrderStatusCode{
|
||||||
ORDER_STATUS_UNPAIDDEPOSIT, ORDER_STATUS_COMPLETE,
|
ORDER_STATUS_UNPAIDDEPOSIT,
|
||||||
ORDER_STATUS_CLOUDSTORE_ORDERED, ORDER_STATUS_CLOUDSTORE_STARTPRODUCTION, ORDER_STATUS_CLOUDSTORE_COMPLETEPRODUCTION, ORDER_STATUS_CLOUDSTORE_ARRIVEDWAREHOUSE,
|
ORDER_STATUS_CLOUDSTORE_ORDERED, ORDER_STATUS_CLOUDSTORE_STARTPRODUCTION, ORDER_STATUS_CLOUDSTORE_COMPLETEPRODUCTION, ORDER_STATUS_CLOUDSTORE_ARRIVEDWAREHOUSE,
|
||||||
|
ORDER_STATUS_COMPLETE, ORDER_STATUS_CLOSE,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
5
constants/queue.go
Normal file
5
constants/queue.go
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package constants
|
||||||
|
|
||||||
|
const (
|
||||||
|
QUEUE_NAME_ORDER = "queue_order"
|
||||||
|
)
|
||||||
@ -7,9 +7,6 @@ const (
|
|||||||
WEBSOCKET_UNAUTH Websocket = "WEBSOCKET_UNAUTH" //鉴权失败 (1级消息,单向通信)
|
WEBSOCKET_UNAUTH Websocket = "WEBSOCKET_UNAUTH" //鉴权失败 (1级消息,单向通信)
|
||||||
WEBSOCKET_CONNECT_ERR Websocket = "WEBSOCKET_CONNECT_ERR" //ws连接错误 (1级消息,单向通信)
|
WEBSOCKET_CONNECT_ERR Websocket = "WEBSOCKET_CONNECT_ERR" //ws连接错误 (1级消息,单向通信)
|
||||||
WEBSOCKET_CONNECT_SUCCESS Websocket = "WEBSOCKET_CONNECT_SUCCESS" //ws连接成功 (1级消息,单向通信)
|
WEBSOCKET_CONNECT_SUCCESS Websocket = "WEBSOCKET_CONNECT_SUCCESS" //ws连接成功 (1级消息,单向通信)
|
||||||
WEBSOCKET_REQUEST_REUSE_LAST_CONNECT Websocket = "WEBSOCKET_REQUEST_REUSE_LAST_CONNECT" //请求恢复为上次连接的标识 (1级消息,单向通信)
|
|
||||||
WEBSOCKET_REQUEST_RESUME_LAST_CONNECT_ERR Websocket = "WEBSOCKET_REQUEST_RESUME_LAST_CONNECT_ERR" //请求恢复为上次连接的标识错误 (1级消息,单向通信)
|
|
||||||
WEBSOCKET_INCOME_CACHE_QUEUE_OVERFLOW = "WEBSOCKET_INCOME_CACHE_QUEUE_OVERFLOW" //数据接收速度超过数据消费速度(缓冲队列满了)(1级消息,单向通信)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// websocket消息类型(通用通知类别)
|
// websocket消息类型(通用通知类别)
|
||||||
|
|||||||
@ -2,14 +2,22 @@
|
|||||||
name=${1%%\\*}
|
name=${1%%\\*}
|
||||||
#进入对应服务目录
|
#进入对应服务目录
|
||||||
cd server/$name
|
cd server/$name
|
||||||
|
#把https加密密钥对复制进来
|
||||||
|
cp /opt/env.yaml ./
|
||||||
|
cp /opt/server.fusen.3718.cn.pem ./
|
||||||
|
cp /opt/server.fusen.3718.cn.key ./
|
||||||
#构建二进制文件
|
#构建二进制文件
|
||||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o ./bin/api-$name-srv ./$name.go
|
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o ./bin/api-$name-srv ./$name.go
|
||||||
#删除之前旧的镜像
|
|
||||||
docker rmi -f api-$name-srv:latest
|
|
||||||
docker rmi -f registry.cn-hangzhou.aliyuncs.com/fusen-test/fusen_docker_hub:latest
|
|
||||||
#打包docker镜像
|
#打包docker镜像
|
||||||
docker build -t api-$name-srv:latest .
|
docker build -t api-$name-srv:latest .
|
||||||
|
#删除临时复制进来的文件
|
||||||
|
rm ./env.yaml
|
||||||
|
rm ./server.fusen.3718.cn.pem
|
||||||
|
rm ./server.fusen.3718.cn.key
|
||||||
#打tag(测试环境,正式把命名空间fusentest改成fusen)
|
#打tag(测试环境,正式把命名空间fusentest改成fusen)
|
||||||
docker tag api-$name-srv:latest registry.cn-hangzhou.aliyuncs.com/fusen-test/$name:latest
|
docker tag api-$name-srv:latest registry.cn-hangzhou.aliyuncs.com/fusen-test/$name:latest
|
||||||
#推送到阿里云镜像库(测试环境,正式把命名空间fusentest改成fusen)
|
#推送到阿里云镜像库(测试环境,正式把命名空间fusentest改成fusen)
|
||||||
docker push registry.cn-hangzhou.aliyuncs.com/fusen-test/$name:latest
|
docker push registry.cn-hangzhou.aliyuncs.com/fusen-test/$name:latest
|
||||||
|
#上传了的镜像
|
||||||
|
docker rmi -f api-$name-srv:latest
|
||||||
|
docker rmi -f registry.cn-hangzhou.aliyuncs.com/fusen-test/$name:latest
|
||||||
|
|||||||
2
go.mod
2
go.mod
@ -98,11 +98,9 @@ require (
|
|||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/cenkalti/backoff/v4 v4.2.0 // indirect
|
github.com/cenkalti/backoff/v4 v4.2.0 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
|
||||||
github.com/fatih/color v1.15.0 // indirect
|
github.com/fatih/color v1.15.0 // indirect
|
||||||
github.com/go-logr/logr v1.2.3 // indirect
|
github.com/go-logr/logr v1.2.3 // indirect
|
||||||
github.com/go-logr/stdr v1.2.2 // indirect
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
github.com/go-redis/redis/v8 v8.11.5 // indirect
|
|
||||||
github.com/go-sql-driver/mysql v1.7.1
|
github.com/go-sql-driver/mysql v1.7.1
|
||||||
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
||||||
github.com/golang/protobuf v1.5.3 // indirect
|
github.com/golang/protobuf v1.5.3 // indirect
|
||||||
|
|||||||
13
go.sum
13
go.sum
@ -48,7 +48,6 @@ github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EF
|
|||||||
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno=
|
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno=
|
||||||
github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w=
|
github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w=
|
||||||
github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo=
|
github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo=
|
||||||
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
|
||||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||||
github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ=
|
github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ=
|
||||||
github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
||||||
@ -68,8 +67,6 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
|
|||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk=
|
|
||||||
github.com/alicebob/miniredis/v2 v2.30.4 h1:8S4/o1/KoUArAGbGwPxcwf0krlzceva2XVOSchFS7Eo=
|
|
||||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704 h1:PpfENOj/vPfhhy9N2OFRjpue0hjM5XqAp2thFmkXXIk=
|
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704 h1:PpfENOj/vPfhhy9N2OFRjpue0hjM5XqAp2thFmkXXIk=
|
||||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704/go.mod h1:RcDobYh8k5VP6TNybz9m++gL3ijVI5wueVr0EM10VsU=
|
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704/go.mod h1:RcDobYh8k5VP6TNybz9m++gL3ijVI5wueVr0EM10VsU=
|
||||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
||||||
@ -140,8 +137,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||||||
github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
|
github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
|
||||||
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
|
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
|
||||||
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
|
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
|
||||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
@ -164,7 +159,6 @@ github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga
|
|||||||
github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA=
|
github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA=
|
||||||
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
|
||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
|
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
|
||||||
github.com/getsentry/sentry-go v0.12.0 h1:era7g0re5iY13bHSdN/xMkyV+5zZppjRVQhZrXCaEIk=
|
github.com/getsentry/sentry-go v0.12.0 h1:era7g0re5iY13bHSdN/xMkyV+5zZppjRVQhZrXCaEIk=
|
||||||
@ -189,8 +183,6 @@ github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV
|
|||||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
|
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
|
||||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
|
||||||
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
|
||||||
github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
|
github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
|
||||||
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
|
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
|
||||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||||
@ -446,15 +438,12 @@ github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6
|
|||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||||
github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0=
|
github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0=
|
||||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
|
||||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||||
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
|
|
||||||
github.com/openzipkin/zipkin-go v0.4.1 h1:kNd/ST2yLLWhaWrkgchya40TJabe8Hioj9udfPcEO5A=
|
github.com/openzipkin/zipkin-go v0.4.1 h1:kNd/ST2yLLWhaWrkgchya40TJabe8Hioj9udfPcEO5A=
|
||||||
github.com/openzipkin/zipkin-go v0.4.1/go.mod h1:qY0VqDSN1pOBN94dBc6w2GJlWLiovAyg7Qt6/I9HecM=
|
github.com/openzipkin/zipkin-go v0.4.1/go.mod h1:qY0VqDSN1pOBN94dBc6w2GJlWLiovAyg7Qt6/I9HecM=
|
||||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
@ -585,7 +574,6 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
|||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
github.com/yuin/gopher-lua v1.1.0 h1:BojcDhfyDWgU2f2TOzYK/g5p2gxMrku8oupLDqlnSqE=
|
|
||||||
github.com/zeromicro/go-zero v1.5.4 h1:kRvcYuxcHOkUZvg7887KQl77Qv4klGL7MqGkTBgkpS8=
|
github.com/zeromicro/go-zero v1.5.4 h1:kRvcYuxcHOkUZvg7887KQl77Qv4klGL7MqGkTBgkpS8=
|
||||||
github.com/zeromicro/go-zero v1.5.4/go.mod h1:x/aUyLmSwRECvOyjOf+lhwThBOilJIY+s3slmPAeboA=
|
github.com/zeromicro/go-zero v1.5.4/go.mod h1:x/aUyLmSwRECvOyjOf+lhwThBOilJIY+s3slmPAeboA=
|
||||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||||
@ -1002,7 +990,6 @@ gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
|||||||
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
|||||||
14
initalize/delayMessage.go
Normal file
14
initalize/delayMessage.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package initalize
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fusenapi/utils/queue"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
func InitDelayMessage() *queue.DelayMessage {
|
||||||
|
//创建延迟消息
|
||||||
|
dm := queue.NewDelayMessage()
|
||||||
|
|
||||||
|
go dm.Start()
|
||||||
|
return dm
|
||||||
|
}
|
||||||
@ -2,6 +2,7 @@ package initalize
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fusenapi/service/repositories"
|
"fusenapi/service/repositories"
|
||||||
|
"fusenapi/utils/queue"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/session"
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@ -16,15 +17,16 @@ type Repositories struct {
|
|||||||
|
|
||||||
type NewAllRepositorieData struct {
|
type NewAllRepositorieData struct {
|
||||||
GormDB *gorm.DB
|
GormDB *gorm.DB
|
||||||
BLMServiceUrl *string
|
BLMServiceUrls []string
|
||||||
AwsSession *session.Session
|
AwsSession *session.Session
|
||||||
|
DelayQueue *queue.DelayMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAllRepositories(newData *NewAllRepositorieData) *Repositories {
|
func NewAllRepositories(newData *NewAllRepositorieData) *Repositories {
|
||||||
return &Repositories{
|
return &Repositories{
|
||||||
ImageHandle: repositories.NewImageHandle(newData.GormDB, newData.BLMServiceUrl, newData.AwsSession),
|
ImageHandle: repositories.NewImageHandle(newData.GormDB, newData.BLMServiceUrls, newData.AwsSession),
|
||||||
NewShoppingCart: repositories.NewShoppingCart(newData.GormDB, newData.BLMServiceUrl, newData.AwsSession),
|
NewShoppingCart: repositories.NewShoppingCart(newData.GormDB, newData.BLMServiceUrls, newData.AwsSession),
|
||||||
NewResource: repositories.NewResource(newData.GormDB, newData.BLMServiceUrl, newData.AwsSession),
|
NewResource: repositories.NewResource(newData.GormDB, newData.BLMServiceUrls, newData.AwsSession),
|
||||||
NewOrder: repositories.NewOrder(newData.GormDB, newData.BLMServiceUrl, newData.AwsSession),
|
NewOrder: repositories.NewOrder(newData.GormDB, newData.AwsSession, newData.DelayQueue),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,8 +4,9 @@ import (
|
|||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
// casbin_rule
|
// casbin_rule 后台--权限规则表
|
||||||
type CasbinRule struct {
|
type CasbinRule struct {
|
||||||
|
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // 序号
|
||||||
PType *string `gorm:"default:'';" json:"p_type"` //
|
PType *string `gorm:"default:'';" json:"p_type"` //
|
||||||
V0 *string `gorm:"default:'';" json:"v0"` //
|
V0 *string `gorm:"default:'';" json:"v0"` //
|
||||||
V1 *string `gorm:"default:'';" json:"v1"` //
|
V1 *string `gorm:"default:'';" json:"v1"` //
|
||||||
|
|||||||
@ -8,8 +8,7 @@ import (
|
|||||||
// fs_address 用户地址表
|
// fs_address 用户地址表
|
||||||
type FsAddress struct {
|
type FsAddress struct {
|
||||||
AddressId int64 `gorm:"primary_key;default:0;auto_increment;" json:"address_id"` //
|
AddressId int64 `gorm:"primary_key;default:0;auto_increment;" json:"address_id"` //
|
||||||
UserId *int64 `gorm:"index;default:0;" json:"user_id"` // 用户ID
|
UserId *int64 `gorm:"default:0;" json:"user_id"` // 用户ID
|
||||||
AddressName *string `gorm:"default:'';" json:"address_name"` //
|
|
||||||
FirstName *string `gorm:"default:'';" json:"first_name"` // FirstName
|
FirstName *string `gorm:"default:'';" json:"first_name"` // FirstName
|
||||||
LastName *string `gorm:"default:'';" json:"last_name"` // LastName
|
LastName *string `gorm:"default:'';" json:"last_name"` // LastName
|
||||||
Mobile *string `gorm:"default:'';" json:"mobile"` // 手机号码
|
Mobile *string `gorm:"default:'';" json:"mobile"` // 手机号码
|
||||||
@ -20,10 +19,9 @@ type FsAddress struct {
|
|||||||
Country *string `gorm:"default:'';" json:"country"` //
|
Country *string `gorm:"default:'';" json:"country"` //
|
||||||
ZipCode *string `gorm:"default:'';" json:"zip_code"` //
|
ZipCode *string `gorm:"default:'';" json:"zip_code"` //
|
||||||
Status *int64 `gorm:"default:0;" json:"status"` // 1正常 0异常
|
Status *int64 `gorm:"default:0;" json:"status"` // 1正常 0异常
|
||||||
IsDefault *int64 `gorm:"index;default:0;" json:"is_default"` // 1默认地址,0非默认地址
|
|
||||||
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` // 创建时间
|
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` // 创建时间
|
||||||
Utime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"utime"` // 更新时间
|
Utime *time.Time `gorm:"index;default:'0000-00-00 00:00:00';" json:"utime"` // 更新时间
|
||||||
Ltime *time.Time `gorm:"index;default:'0000-00-00 00:00:00';" json:"ltime"` // 上次被使用的时间
|
Ltime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ltime"` // 上次被使用的时间
|
||||||
}
|
}
|
||||||
type FsAddressModel struct {
|
type FsAddressModel struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
|||||||
@ -13,11 +13,30 @@ func (a *FsAddressModel) GetOne(ctx context.Context, addressId int64, userId int
|
|||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *FsAddressModel) GetUserAllAddress(ctx context.Context, userId int64) (resp []FsAddress, err error) {
|
func (a *FsAddressModel) GetUserAllAddress(ctx context.Context, userId int64) (resp []*FsAddressWithDefault, err error) {
|
||||||
err = a.db.WithContext(ctx).Model(&FsAddress{}).Where("`user_id` = ? and `status` = ?", userId, 1).Order("`ltime` DESC").Find(&resp).Error
|
resp = make([]*FsAddressWithDefault, 0)
|
||||||
|
|
||||||
|
var dbresp []*FsAddress
|
||||||
|
err = a.db.WithContext(ctx).Model(&FsAddress{}).Where("`user_id` = ? and `status` = 1", userId).Order("`ltime` DESC").Find(&dbresp).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
now := time.Now().UTC().AddDate(10, 0, 0).Unix()
|
||||||
|
for _, r := range dbresp {
|
||||||
|
rd := &FsAddressWithDefault{
|
||||||
|
FsAddress: r,
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.Ltime.UTC().Unix() > now {
|
||||||
|
rd.IsDefault = 1
|
||||||
|
} else {
|
||||||
|
rd.IsDefault = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
resp = append(resp, rd)
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,7 +46,6 @@ func (a *FsAddressModel) CreateOne(ctx context.Context, address *FsAddress) (res
|
|||||||
now := time.Now().UTC()
|
now := time.Now().UTC()
|
||||||
result = &FsAddress{
|
result = &FsAddress{
|
||||||
UserId: address.UserId,
|
UserId: address.UserId,
|
||||||
AddressName: address.AddressName,
|
|
||||||
FirstName: address.FirstName,
|
FirstName: address.FirstName,
|
||||||
LastName: address.LastName,
|
LastName: address.LastName,
|
||||||
Mobile: address.Mobile,
|
Mobile: address.Mobile,
|
||||||
@ -38,26 +56,10 @@ func (a *FsAddressModel) CreateOne(ctx context.Context, address *FsAddress) (res
|
|||||||
Country: address.Country,
|
Country: address.Country,
|
||||||
ZipCode: address.ZipCode,
|
ZipCode: address.ZipCode,
|
||||||
Status: address.Status,
|
Status: address.Status,
|
||||||
IsDefault: address.IsDefault,
|
|
||||||
Ctime: &now,
|
Ctime: &now,
|
||||||
Utime: &now,
|
Utime: &now,
|
||||||
Ltime: &now,
|
Ltime: &now,
|
||||||
}
|
}
|
||||||
|
|
||||||
// lastOne := &FsAddress{}
|
|
||||||
// err = tx.Where("user_id = ?", lastOne.UserId).Order("ltime ASC").Take(&lastOne).Error
|
|
||||||
// if err == gorm.ErrRecordNotFound {
|
|
||||||
// result.Ltime = &now
|
|
||||||
// return tx.Model(&FsAddress{}).Create(result).Error
|
|
||||||
// }
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 根据lastOne处理时间
|
|
||||||
|
|
||||||
// ltime := (*lastOne.Ltime).Add(-time.Second)
|
|
||||||
// result.Ltime = <ime
|
|
||||||
return tx.Model(&FsAddress{}).Create(result).Error
|
return tx.Model(&FsAddress{}).Create(result).Error
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -71,7 +73,7 @@ func (a *FsAddressModel) CreateOne(ctx context.Context, address *FsAddress) (res
|
|||||||
func (a *FsAddressModel) UpdateAddress(ctx context.Context, address *FsAddress) (err error) {
|
func (a *FsAddressModel) UpdateAddress(ctx context.Context, address *FsAddress) (err error) {
|
||||||
err = a.db.WithContext(ctx).Model(&FsAddress{}).Transaction(func(tx *gorm.DB) error {
|
err = a.db.WithContext(ctx).Model(&FsAddress{}).Transaction(func(tx *gorm.DB) error {
|
||||||
err = tx.
|
err = tx.
|
||||||
Where("user_id = ? and address_id = ? and status = 1 ", address.UserId, address.AddressId).
|
Where("address_id = ? and user_id = ? and status = 1 ", address.AddressId, address.UserId).
|
||||||
Updates(address).Error
|
Updates(address).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -81,34 +83,64 @@ func (a *FsAddressModel) UpdateAddress(ctx context.Context, address *FsAddress)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *FsAddressModel) SettingUserDefaultAddress(ctx context.Context, userId int64, addressId int64) (err error) {
|
func (a *FsAddressModel) SettingUserDefaultAddress(ctx context.Context, userId int64, addressId int64, isDefault int64) (err error) {
|
||||||
|
|
||||||
err = a.db.WithContext(ctx).Model(&FsAddress{}).Transaction(func(tx *gorm.DB) error {
|
err = a.db.WithContext(ctx).Model(&FsAddress{}).Transaction(func(tx *gorm.DB) error {
|
||||||
|
|
||||||
|
logx.Info("address_id:", addressId, " set default ", isDefault)
|
||||||
now := time.Now().UTC()
|
now := time.Now().UTC()
|
||||||
|
var updates = map[string]interface{}{
|
||||||
|
"ltime": now,
|
||||||
|
"utime": now,
|
||||||
|
}
|
||||||
|
|
||||||
err = tx.Model(&FsAddress{}).Where(" `user_id` = ? and `status` = ? and `address_id` = ? ", userId, 1, addressId).
|
if isDefault == 1 {
|
||||||
UpdateColumn("ltime", now.AddDate(250, 0, 0)).
|
err = tx.Where("`user_id` = ? and `status` = 1 and `ltime` > ? and `address_id` != ?", userId, now.AddDate(10, 0, 0), addressId).
|
||||||
UpdateColumn("utime", now).Error
|
UpdateColumns(updates).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
updates["ltime"] = now.AddDate(250, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
err = tx.Where(" `user_id` = ? and `status` = ? and `address_id` != ? and `ltime` > ? ", userId, 1, addressId, now.AddDate(10, 0, 0)).
|
tr := tx.Model(&FsAddress{}).Where("`address_id` = ? and `user_id` = ? and `status` = 1", addressId, userId).
|
||||||
UpdateColumn("ltime", now).Error
|
UpdateColumns(updates)
|
||||||
|
|
||||||
|
err = tr.Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *FsAddressModel) DeleteOne(ctx context.Context, addressId int64, userId int64) (err error) {
|
func (a *FsAddressModel) DeleteOne(ctx context.Context, addressId int64, userId int64) (err error) {
|
||||||
|
|
||||||
err = a.db.WithContext(ctx).Model(&FsAddress{}).
|
err = a.db.WithContext(ctx).Model(&FsAddress{}).
|
||||||
Where("`address_id` = ? and `user_id` = ? and `status` = ? ", addressId, userId, 1).
|
Where("`address_id` = ? and `user_id` = ? and `status` = 1 ", addressId, userId).
|
||||||
UpdateColumn("status", 0).Error
|
UpdateColumn("status", 0).Error
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateUsedAddress 当每次订单成功后, 更新一次地址使用时间
|
||||||
|
func (a *FsAddressModel) UpdateUsedAddress(ctx context.Context, addressId int64, userId int64) (err error) {
|
||||||
|
err = a.db.WithContext(ctx).Model(&FsAddress{}).Transaction(func(tx *gorm.DB) error {
|
||||||
|
logx.Info("address_id:", addressId, " update used")
|
||||||
|
now := time.Now().UTC()
|
||||||
|
var updates = map[string]interface{}{
|
||||||
|
"ltime": now,
|
||||||
|
"utime": now,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tx.Where("`address_id` = ? and `user_id` = ? and `status` = 1", addressId, userId).
|
||||||
|
UpdateColumns(updates).Error
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|||||||
@ -20,6 +20,7 @@ type FsAdminApi struct {
|
|||||||
UpdateUid *int64 `gorm:"default:0;" json:"update_uid"` // 更新人
|
UpdateUid *int64 `gorm:"default:0;" json:"update_uid"` // 更新人
|
||||||
DeleteUid *int64 `gorm:"default:0;" json:"delete_uid"` // 删除人
|
DeleteUid *int64 `gorm:"default:0;" json:"delete_uid"` // 删除人
|
||||||
IsDel *int64 `gorm:"default:0;" json:"is_del"` // 是否删除:1=是 0=否
|
IsDel *int64 `gorm:"default:0;" json:"is_del"` // 是否删除:1=是 0=否
|
||||||
|
Method *int64 `gorm:"default:0;" json:"method"` // 接口方法
|
||||||
}
|
}
|
||||||
type FsAdminApiModel struct {
|
type FsAdminApiModel struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
|||||||
@ -32,6 +32,7 @@ type FsAdminMenu struct {
|
|||||||
UpdateUid *int64 `gorm:"default:0;" json:"update_uid"` // 更新人
|
UpdateUid *int64 `gorm:"default:0;" json:"update_uid"` // 更新人
|
||||||
DeleteUid *int64 `gorm:"default:0;" json:"delete_uid"` // 删除人
|
DeleteUid *int64 `gorm:"default:0;" json:"delete_uid"` // 删除人
|
||||||
IsDel *int64 `gorm:"default:0;" json:"is_del"` // 是否删除:1=是 0=否
|
IsDel *int64 `gorm:"default:0;" json:"is_del"` // 是否删除:1=是 0=否
|
||||||
|
ApiAuth *[]byte `gorm:"default:'';" json:"api_auth"` //
|
||||||
}
|
}
|
||||||
type FsAdminMenuModel struct {
|
type FsAdminMenuModel struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
|||||||
23
model/gmodel/fs_admin_role_api_gen.go
Normal file
23
model/gmodel/fs_admin_role_api_gen.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package gmodel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// fs_admin_role_api 后台--角色接口表
|
||||||
|
type FsAdminRoleApi struct {
|
||||||
|
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // 序号
|
||||||
|
RoleId *int64 `gorm:"index;default:0;" json:"role_id"` // 角色ID
|
||||||
|
MenuId *int64 `gorm:"index;default:0;" json:"menu_id"` // 菜单ID
|
||||||
|
ApiId *int64 `gorm:"index;default:0;" json:"api_id"` // 接口ID
|
||||||
|
ApiPath *string `gorm:"default:'';" json:"api_path"` //
|
||||||
|
ApiMethod *int64 `gorm:"default:0;" json:"api_method"` // 接口方法
|
||||||
|
}
|
||||||
|
type FsAdminRoleApiModel struct {
|
||||||
|
db *gorm.DB
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFsAdminRoleApiModel(db *gorm.DB) *FsAdminRoleApiModel {
|
||||||
|
return &FsAdminRoleApiModel{db: db, name: "fs_admin_role_api"}
|
||||||
|
}
|
||||||
2
model/gmodel/fs_admin_role_api_logic.go
Normal file
2
model/gmodel/fs_admin_role_api_logic.go
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
package gmodel
|
||||||
|
// TODO: 使用model的属性做你想做的
|
||||||
@ -2,18 +2,20 @@ package gmodel
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// fs_contact 该表暂未使用
|
// fs_contact 该表暂未使用
|
||||||
type FsContact struct {
|
type FsContact struct {
|
||||||
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` //
|
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` //
|
||||||
Name *string `gorm:"default:'';" json:"name"` // 名字
|
Name *string `gorm:"default:'';" json:"name"` //
|
||||||
Email *string `gorm:"index;default:'';" json:"email"` // 邮箱
|
Email *string `gorm:"index;default:'';" json:"email"` // 邮箱
|
||||||
Subject *int64 `gorm:"default:0;" json:"subject"` // 主题
|
Subject *string `gorm:"default:'0';" json:"subject"` // 主题
|
||||||
Message *string `gorm:"default:'';" json:"message"` // 消息
|
Message *string `gorm:"default:'';" json:"message"` // 消息
|
||||||
Ctime *int64 `gorm:"default:0;" json:"ctime"` // 添加时间
|
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` //
|
||||||
Status *int64 `gorm:"default:0;" json:"status"` // 状态位 是否已处理
|
Status *int64 `gorm:"default:0;" json:"status"` // 状态位 是否已处理
|
||||||
Mark *string `gorm:"default:'';" json:"mark"` // 后台订单备注
|
Mark *string `gorm:"default:'';" json:"mark"` // 后台订单备注
|
||||||
|
Phone *string `gorm:"default:'';" json:"phone"` //
|
||||||
}
|
}
|
||||||
type FsContactModel struct {
|
type FsContactModel struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
|||||||
@ -1,3 +1,9 @@
|
|||||||
package gmodel
|
package gmodel
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
// TODO: 使用model的属性做你想做的
|
// TODO: 使用model的属性做你想做的
|
||||||
|
|
||||||
|
func (contact *FsContactModel) Save(ctx context.Context, obj *FsContact) (err error) {
|
||||||
|
return contact.db.WithContext(ctx).Model(&FsContact{}).Create(obj).Error
|
||||||
|
}
|
||||||
|
|||||||
@ -32,7 +32,16 @@ func (m *FsGuestModel) GenerateGuestID(ctx context.Context, AccessSecret uint64)
|
|||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
|
uinfo := &FsUserInfo{
|
||||||
|
Module: FsString("profile"),
|
||||||
|
UserId: FsInt64(0),
|
||||||
|
GuestId: &record.GuestId,
|
||||||
|
Metadata: FsBytes("{}"),
|
||||||
|
Ctime: &now,
|
||||||
|
Utime: &now,
|
||||||
|
}
|
||||||
|
return tx.Model(FsUserInfo{}).Create(uinfo).Error
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -18,6 +18,13 @@ type FsOrder struct {
|
|||||||
Utime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"utime"` //
|
Utime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"utime"` //
|
||||||
IsDel *int64 `gorm:"default:0;" json:"is_del"` // 是否删除:0=否,1=是
|
IsDel *int64 `gorm:"default:0;" json:"is_del"` // 是否删除:0=否,1=是
|
||||||
PayStatus *int64 `gorm:"default:0;" json:"pay_status"` // 支付状态
|
PayStatus *int64 `gorm:"default:0;" json:"pay_status"` // 支付状态
|
||||||
|
StatusLink *[]byte `gorm:"default:'';" json:"status_link"` //
|
||||||
|
OrderProduct *[]byte `gorm:"default:'';" json:"order_product"` //
|
||||||
|
OrderAddress *[]byte `gorm:"default:'';" json:"order_address"` //
|
||||||
|
OrderAmount *[]byte `gorm:"default:'';" json:"order_amount"` //
|
||||||
|
PayStatusLink *[]byte `gorm:"default:'';" json:"pay_status_link"` //
|
||||||
|
ShoppingCartSnapshot *[]byte `gorm:"default:'';" json:"shopping_cart_snapshot"` //
|
||||||
|
ShoppingProductSnapshot *[]byte `gorm:"default:'';" json:"shopping_product_snapshot"` //
|
||||||
}
|
}
|
||||||
type FsOrderModel struct {
|
type FsOrderModel struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
|||||||
@ -73,9 +73,10 @@ type PayStatus struct {
|
|||||||
|
|
||||||
// 订单信息
|
// 订单信息
|
||||||
type OrderInfo struct {
|
type OrderInfo struct {
|
||||||
|
UserId int64 `json:"user_id"` // 物流类型
|
||||||
Ctime *time.Time `json:"ctime"` // 创建日期
|
Ctime *time.Time `json:"ctime"` // 创建日期
|
||||||
DeliveryMethod int64 `json:"delivery_method"` // 物流类型
|
DeliveryMethod int64 `json:"delivery_method"` // 物流类型
|
||||||
Metadata map[string]interface{} `json:"metadata"` // 额外参数
|
Metadata OrderMetadata `json:"metadata"` // 额外参数
|
||||||
OrderSn string `json:"order_sn"` // 订单编号
|
OrderSn string `json:"order_sn"` // 订单编号
|
||||||
Status OrderStatus `json:"status"` // 当前状态
|
Status OrderStatus `json:"status"` // 当前状态
|
||||||
StatusLink []OrderStatus `json:"status_link"` // 状态链路
|
StatusLink []OrderStatus `json:"status_link"` // 状态链路
|
||||||
@ -96,20 +97,23 @@ type OrderStatus struct {
|
|||||||
// 订单商品
|
// 订单商品
|
||||||
type OrderProduct struct {
|
type OrderProduct struct {
|
||||||
TotalPrice AmountInfo `json:"total_price"` // 商品总价
|
TotalPrice AmountInfo `json:"total_price"` // 商品总价
|
||||||
|
ItemPrice AmountInfo `json:"item_price"` // 商品单价
|
||||||
ExpectedDeliveryTime *time.Time `json:"expected_delivery_time"` // 预计到货时间
|
ExpectedDeliveryTime *time.Time `json:"expected_delivery_time"` // 预计到货时间
|
||||||
PurchaseQuantity PurchaseQuantity `json:"purchase_quantity"` // 购买数量
|
PurchaseQuantity PurchaseQuantity `json:"purchase_quantity"` // 购买数量
|
||||||
ProductID int64 `json:"product_id"` // 商品ID
|
ProductId int64 `json:"product_id"` // 商品ID
|
||||||
|
ProductSn string `json:"product_sn"` // 商品编码
|
||||||
ProductName string `json:"product_name"` // 商品名称
|
ProductName string `json:"product_name"` // 商品名称
|
||||||
ItemPrice AmountInfo `json:"item_price"` // 商品单价
|
|
||||||
ProductSnapshot interface{} `json:"product_snapshot"` // 商品快照
|
|
||||||
ShoppingCartSnapshot *FsShoppingCartData `json:"shopping_cart_snapshot"` // 购物车快照
|
|
||||||
ProductCover string `json:"product_cover"` // 商品封面
|
ProductCover string `json:"product_cover"` // 商品封面
|
||||||
ProductCoverMetadata map[string]interface{} `json:"product_cover_metadata"` // 商品封面
|
ProductCoverMetadata map[string]interface{} `json:"product_cover_metadata"` // 商品封面
|
||||||
ProductSn string `json:"product_sn"` // 商品编码
|
ProductSnapshot interface{} `json:"product_snapshot"` // 商品快照
|
||||||
|
ShoppingCartSnapshot *FsShoppingCartData `json:"shopping_cart_snapshot"` // 购物车快照
|
||||||
|
|
||||||
DiyInformation *UserDiyInformation `json:"diy_information"`
|
DiyInformation *UserDiyInformation `json:"diy_information"`
|
||||||
SizeInfo *OrderProductSizeInfo `json:"size_info"`
|
SizeInfo *OrderProductSizeInfo `json:"size_info"`
|
||||||
FittingInfo *OrderProductFittingInfo `json:"fitting_info"`
|
FittingInfo *OrderProductFittingInfo `json:"fitting_info"`
|
||||||
IsHighlyCustomized int64 `json:"is_highly_customized"`
|
IsHighlyCustomized int64 `json:"is_highly_customized"`
|
||||||
|
RenderImage string `json:"render_image"`
|
||||||
|
SelectColorIndex int64 `json:"select_color_index"`
|
||||||
}
|
}
|
||||||
type PurchaseQuantity struct {
|
type PurchaseQuantity struct {
|
||||||
Current interface{} `json:"current"`
|
Current interface{} `json:"current"`
|
||||||
@ -131,3 +135,31 @@ type OrderProductFittingInfo struct {
|
|||||||
FittingID int64 `json:"fitting_id"` //配件ID
|
FittingID int64 `json:"fitting_id"` //配件ID
|
||||||
FittingName string `json:"fitting_name"` //配件名称
|
FittingName string `json:"fitting_name"` //配件名称
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ExpectedDelivery struct {
|
||||||
|
Current time.Time `json:"current"`
|
||||||
|
Initiate time.Time `json:"initiate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type OrderProductInter struct {
|
||||||
|
CartId int64 `json:"cart_id"` // 购物车ID
|
||||||
|
TotalPrice AmountInfo `json:"total_price"` // 商品总价
|
||||||
|
ItemPrice AmountInfo `json:"item_price"` // 商品单价
|
||||||
|
PurchaseQuantity *PurchaseQuantity `json:"purchase_quantity"` // 购买数量
|
||||||
|
ProductId int64 `json:"product_id"` // 商品ID
|
||||||
|
ProductName string `json:"product_name"` // 商品名称
|
||||||
|
ProductCover string `json:"product_cover"` // 商品封面
|
||||||
|
ProductCoverMetadata map[string]interface{} `json:"product_cover_metadata"` // 商品封面
|
||||||
|
ProductSn string `json:"product_sn"` // 商品编码
|
||||||
|
DiyInformation *UserDiyInformation `json:"diy_information"`
|
||||||
|
SizeInfo *OrderProductSizeInfo `json:"size_info"`
|
||||||
|
FittingInfo *OrderProductFittingInfo `json:"fitting_info"`
|
||||||
|
IsHighlyCustomized int64 `json:"is_highly_customized"`
|
||||||
|
RenderImage string `json:"render_image"`
|
||||||
|
ExpectedDeliveryTime *ExpectedDelivery `json:"expected_delivery_time"` // 预计到货时间
|
||||||
|
ActualDeliveryTime *ExpectedDelivery `json:"actual_delivery_time"` // 实际到货时间
|
||||||
|
}
|
||||||
|
type OrderMetadata struct {
|
||||||
|
ExpectedDeliveryTime *ExpectedDelivery `json:"expected_delivery_time"` // 预计到货时间
|
||||||
|
ActualDeliveryTime *ExpectedDelivery `json:"actual_delivery_time"` // 实际到货时间
|
||||||
|
}
|
||||||
|
|||||||
27
model/gmodel/fs_product_collection_gen.go
Normal file
27
model/gmodel/fs_product_collection_gen.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package gmodel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// fs_product_collection 产品收藏表
|
||||||
|
type FsProductCollection struct {
|
||||||
|
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // id
|
||||||
|
UserId *int64 `gorm:"default:0;" json:"user_id"` // 用户id
|
||||||
|
GuestId *int64 `gorm:"default:0;" json:"guest_id"` // 游客id
|
||||||
|
ProductId *int64 `gorm:"default:0;" json:"product_id"` // 产品id
|
||||||
|
TemplateTag *string `gorm:"default:'';" json:"template_tag"` //
|
||||||
|
SelectColorIndex *int64 `gorm:"default:0;" json:"select_color_index"` // 选择的颜色索引
|
||||||
|
Logo *string `gorm:"default:'';" json:"logo"` // logo地址
|
||||||
|
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` //
|
||||||
|
Utime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"utime"` //
|
||||||
|
}
|
||||||
|
type FsProductCollectionModel struct {
|
||||||
|
db *gorm.DB
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFsProductCollectionModel(db *gorm.DB) *FsProductCollectionModel {
|
||||||
|
return &FsProductCollectionModel{db: db, name: "fs_product_collection"}
|
||||||
|
}
|
||||||
52
model/gmodel/fs_product_collection_logic.go
Normal file
52
model/gmodel/fs_product_collection_logic.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package gmodel
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
// 查询
|
||||||
|
func (c *FsProductCollectionModel) FindOne(ctx context.Context, userId, guestId, productId int64) (resp *FsProductCollection, err error) {
|
||||||
|
err = c.db.WithContext(ctx).Model(&FsProductCollection{}).
|
||||||
|
Where("user_id = ? and guest_id = ? and product_id = ?", userId, guestId, productId).
|
||||||
|
Take(&resp).Error
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建
|
||||||
|
func (c *FsProductCollectionModel) Create(ctx context.Context, data *FsProductCollection) error {
|
||||||
|
return c.db.WithContext(ctx).Model(&FsProductCollection{}).Create(&data).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新
|
||||||
|
func (c *FsProductCollectionModel) Update(ctx context.Context, userId, guestId, productId int64, data *FsProductCollection) error {
|
||||||
|
return c.db.WithContext(ctx).Model(&FsProductCollection{}).
|
||||||
|
Where("user_id = ? and guest_id = ? and product_id = ?", userId, guestId, productId).
|
||||||
|
Updates(&data).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
func (c *FsProductCollectionModel) Delete(ctx context.Context, userId, guestId, productId int64) error {
|
||||||
|
return c.db.WithContext(ctx).Model(&FsProductCollection{}).
|
||||||
|
Where("user_id = ? and guest_id = ? and product_id = ?", userId, guestId, productId).
|
||||||
|
Delete(&FsProductCollection{}).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
func (c *FsProductCollectionModel) Delete2(ctx context.Context, userId, guestId, id int64) error {
|
||||||
|
return c.db.WithContext(ctx).Model(&FsProductCollection{}).
|
||||||
|
Where("user_id = ? and guest_id = ? and id = ?", userId, guestId, id).
|
||||||
|
Delete(&FsProductCollection{}).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取列表
|
||||||
|
func (c *FsProductCollectionModel) GetList(ctx context.Context, userId, guestId int64, page, limit int, sort string) (resp []FsProductCollection, total int64, err error) {
|
||||||
|
db := c.db.WithContext(ctx).Model(&FsProductCollection{}).
|
||||||
|
Where("user_id = ? and guest_id = ?", userId, guestId)
|
||||||
|
if sort != "" {
|
||||||
|
db = db.Order(sort)
|
||||||
|
}
|
||||||
|
if err = db.Count(&total).Error; err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
offset := (page - 1) * limit
|
||||||
|
err = db.Offset(offset).Limit(limit).Find(&resp).Error
|
||||||
|
return resp, total, err
|
||||||
|
}
|
||||||
@ -11,11 +11,11 @@ type FsProduct struct {
|
|||||||
Type *int64 `gorm:"default:0;" json:"type"` // 分类ID
|
Type *int64 `gorm:"default:0;" json:"type"` // 分类ID
|
||||||
Title *string `gorm:"default:'';" json:"title"` // 名称
|
Title *string `gorm:"default:'';" json:"title"` // 名称
|
||||||
TitleCn *string `gorm:"default:'';" json:"title_cn"` // 中文名称
|
TitleCn *string `gorm:"default:'';" json:"title_cn"` // 中文名称
|
||||||
|
Sort *int64 `gorm:"default:0;" json:"sort"` // 排序
|
||||||
Cover *string `gorm:"default:'';" json:"cover"` // 封面图
|
Cover *string `gorm:"default:'';" json:"cover"` // 封面图
|
||||||
Imgs *string `gorm:"default:'';" json:"imgs"` // 一个或多个介绍图或视频
|
Imgs *string `gorm:"default:'';" json:"imgs"` // 一个或多个介绍图或视频
|
||||||
Keywords *string `gorm:"default:'';" json:"keywords"` // 关键字
|
Keywords *string `gorm:"default:'';" json:"keywords"` // 关键字
|
||||||
Intro *string `gorm:"default:'';" json:"intro"` // 简要描述
|
Intro *string `gorm:"default:'';" json:"intro"` // 简要描述
|
||||||
Sort *int64 `gorm:"default:0;" json:"sort"` // 排序
|
|
||||||
SelledNum *int64 `gorm:"default:0;" json:"selled_num"` // 已卖数量
|
SelledNum *int64 `gorm:"default:0;" json:"selled_num"` // 已卖数量
|
||||||
Ctime *int64 `gorm:"default:0;" json:"ctime"` // 添加时间
|
Ctime *int64 `gorm:"default:0;" json:"ctime"` // 添加时间
|
||||||
View *int64 `gorm:"default:0;" json:"view"` // 浏览量
|
View *int64 `gorm:"default:0;" json:"view"` // 浏览量
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import "context"
|
|||||||
|
|
||||||
type RelaFsProduct struct {
|
type RelaFsProduct struct {
|
||||||
FsProduct
|
FsProduct
|
||||||
CoverResource *FsResource `json:"cover_resource" gorm:"foreignkey:cover;references:resource_id"`
|
CoverResource *FsResource `json:"cover_resource" gorm:"foreignkey:cover;references:resource_url"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *FsProductModel) TableName() string {
|
func (m *FsProductModel) TableName() string {
|
||||||
|
|||||||
@ -23,7 +23,7 @@ type FsProductModel3d struct {
|
|||||||
Status *int64 `gorm:"default:0;" json:"status"` // 状态位 显示 删除
|
Status *int64 `gorm:"default:0;" json:"status"` // 状态位 显示 删除
|
||||||
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` //
|
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` //
|
||||||
OptionTemplate *int64 `gorm:"default:0;" json:"option_template"` // 配件绑定的公共模板
|
OptionTemplate *int64 `gorm:"default:0;" json:"option_template"` // 配件绑定的公共模板
|
||||||
Price *int64 `gorm:"default:0;" json:"price"` //
|
Price *int64 `gorm:"default:0;" json:"price"` // 仅配件用,配件的价格, 单位:0.1美分
|
||||||
Sku *string `gorm:"default:'';" json:"sku"` // sku
|
Sku *string `gorm:"default:'';" json:"sku"` // sku
|
||||||
IsHot *int64 `gorm:"default:0;" json:"is_hot"` // 是否热门
|
IsHot *int64 `gorm:"default:0;" json:"is_hot"` // 是否热门
|
||||||
IsCloudRender *int64 `gorm:"default:0;" json:"is_cloud_render"` // 是否设置为云渲染模型
|
IsCloudRender *int64 `gorm:"default:0;" json:"is_cloud_render"` // 是否设置为云渲染模型
|
||||||
|
|||||||
@ -2,6 +2,11 @@ package gmodel
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"fusenapi/constants"
|
||||||
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 阶梯价结构
|
// 阶梯价结构
|
||||||
@ -152,3 +157,72 @@ func (d *FsProductModel3dModel) FindOneByProductIdSizeIdTag(ctx context.Context,
|
|||||||
err = db.Take(&resp).Error
|
err = db.Take(&resp).Error
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *FsProductModel3dModel) GetAllByProductIdsTags(ctx context.Context, productIds []int64, tags []int, fields ...string) (resp []FsProductModel3d, err error) {
|
||||||
|
if len(productIds) == 0 || len(tags) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
db := d.db.WithContext(ctx).Model(&FsProductModel3d{}).
|
||||||
|
Where("`product_id` in (?) and `tag` in (?) and `status` = ?", productIds, tags, 1).
|
||||||
|
Order("sort DESC")
|
||||||
|
if len(fields) != 0 {
|
||||||
|
db = db.Select(fields[0])
|
||||||
|
}
|
||||||
|
err = db.Find(&resp).Error
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取每个产品最低价格
|
||||||
|
func (d *FsProductModel3dModel) GetProductMinPrice(ctx context.Context, productIds []int64, mapProductMinPrice map[int64]int64) error {
|
||||||
|
//获取产品模型价格列表
|
||||||
|
modelList, err := d.GetAllByProductIdsTags(ctx, productIds, []int{constants.TAG_MODEL, constants.TAG_PARTS}, "id,product_id,price,tag,part_id,step_price")
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("failed to get model list")
|
||||||
|
}
|
||||||
|
mapModelMinPrice := make(map[int64]int64)
|
||||||
|
//每个模型/配件存储最小价格
|
||||||
|
for _, modelInfo := range modelList {
|
||||||
|
switch *modelInfo.Tag {
|
||||||
|
case constants.TAG_MODEL: //模型
|
||||||
|
if modelInfo.StepPrice == nil || len(*modelInfo.StepPrice) == 0 {
|
||||||
|
mapModelMinPrice[modelInfo.Id] = 0
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var stepPrice StepPriceJsonStruct
|
||||||
|
if err = json.Unmarshal(*modelInfo.StepPrice, &stepPrice); err != nil {
|
||||||
|
return errors.New(fmt.Sprintf("failed to parse model step price:%d", modelInfo.Id))
|
||||||
|
}
|
||||||
|
lenRange := len(stepPrice.PriceRange)
|
||||||
|
if lenRange == 0 {
|
||||||
|
mapModelMinPrice[modelInfo.Id] = 0
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
sort.SliceStable(stepPrice.PriceRange, func(i, j int) bool {
|
||||||
|
return stepPrice.PriceRange[i].Price > stepPrice.PriceRange[j].Price
|
||||||
|
})
|
||||||
|
mapModelMinPrice[modelInfo.Id] = stepPrice.PriceRange[lenRange-1].Price
|
||||||
|
case constants.TAG_PARTS: //配件
|
||||||
|
mapModelMinPrice[modelInfo.Id] = *modelInfo.Price
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//给产品存储最小价格
|
||||||
|
for _, v := range modelList {
|
||||||
|
if *v.Tag != constants.TAG_MODEL {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
itemPrice := mapModelMinPrice[v.Id]
|
||||||
|
if *v.PartId > 0 {
|
||||||
|
if fittingPrice, ok := mapModelMinPrice[*v.PartId]; ok {
|
||||||
|
itemPrice += fittingPrice
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if minPrice, ok := mapProductMinPrice[*v.ProductId]; ok {
|
||||||
|
if itemPrice < minPrice {
|
||||||
|
mapProductMinPrice[*v.ProductId] = itemPrice
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
mapProductMinPrice[*v.ProductId] = itemPrice
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@ -18,7 +18,7 @@ type FsShoppingCart struct {
|
|||||||
PurchaseQuantity *int64 `gorm:"default:0;" json:"purchase_quantity"` // 购买数量
|
PurchaseQuantity *int64 `gorm:"default:0;" json:"purchase_quantity"` // 购买数量
|
||||||
Snapshot *string `gorm:"default:'';" json:"snapshot"` //
|
Snapshot *string `gorm:"default:'';" json:"snapshot"` //
|
||||||
IsSelected *int64 `gorm:"default:0;" json:"is_selected"` // 是否被选中 0非 1是
|
IsSelected *int64 `gorm:"default:0;" json:"is_selected"` // 是否被选中 0非 1是
|
||||||
IsHighlyCustomized *int64 `gorm:"default:0;" json:"is_highly_customized"` // 是否高度定制 0非 1是(针对客人高度定制只能后台增加如购物车)
|
IsHighlyCustomized *int64 `gorm:"default:0;" json:"is_highly_customized"` // 是否高度定制 0非 1是(针对客人高度定制,该类行无法跳详情页)
|
||||||
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` //
|
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` //
|
||||||
Utime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"utime"` //
|
Utime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"utime"` //
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,14 +27,12 @@ type FsShoppingCartData struct {
|
|||||||
FittingId *int64 `gorm:"default:0;" json:"fitting_id"` // 配件id
|
FittingId *int64 `gorm:"default:0;" json:"fitting_id"` // 配件id
|
||||||
PurchaseQuantity *int64 `gorm:"default:0;" json:"purchase_quantity"` // 购买数量
|
PurchaseQuantity *int64 `gorm:"default:0;" json:"purchase_quantity"` // 购买数量
|
||||||
Snapshot *map[string]interface{} `gorm:"default:'';" json:"snapshot"` //
|
Snapshot *map[string]interface{} `gorm:"default:'';" json:"snapshot"` //
|
||||||
SnapshotData *string `gorm:"default:'';" json:"snapshot_data"` //
|
|
||||||
IsSelected *int64 `gorm:"default:0;" json:"is_selected"` // 是否被选中 0非 1是
|
IsSelected *int64 `gorm:"default:0;" json:"is_selected"` // 是否被选中 0非 1是
|
||||||
IsHighlyCustomized *int64 `gorm:"default:0;" json:"is_highly_customized"` // 是否高度定制 0非 1是(针对客人高度定制只能后台增加如购物车)
|
IsHighlyCustomized *int64 `gorm:"default:0;" json:"is_highly_customized"` // 是否高度定制 0非 1是(针对客人高度定制只能后台增加如购物车)
|
||||||
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` //
|
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` //
|
||||||
Utime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"utime"` //
|
Utime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"utime"` //
|
||||||
}
|
}
|
||||||
|
|
||||||
// 快照json数据结构
|
|
||||||
// 购物车快照数据结构
|
// 购物车快照数据结构
|
||||||
type CartSnapshot struct {
|
type CartSnapshot struct {
|
||||||
Logo string `json:"logo"` //logo地址
|
Logo string `json:"logo"` //logo地址
|
||||||
@ -53,16 +51,17 @@ type ProductInfo struct {
|
|||||||
ProductSn string `json:"product_sn"`
|
ProductSn string `json:"product_sn"`
|
||||||
}
|
}
|
||||||
type ModelInfo struct {
|
type ModelInfo struct {
|
||||||
ModelJson string `json:"model_json"` //模型设计json数据
|
ModelJson interface{} `json:"model_json"` //模型设计json数据
|
||||||
}
|
}
|
||||||
type FittingInfo struct {
|
type FittingInfo struct {
|
||||||
FittingJson string `json:"fitting_json"` //配件设计json数据
|
FittingJson interface{} `json:"fitting_json"` //配件设计json数据
|
||||||
FittingName string `json:"fitting_name"` //配件名称
|
FittingName string `json:"fitting_name"` //配件名称
|
||||||
|
|
||||||
}
|
}
|
||||||
type TemplateInfo struct {
|
type TemplateInfo struct {
|
||||||
TemplateJson string `json:"template_json"` //模板设计json数据
|
TemplateJson interface{} `json:"template_json"` //模板设计json数据
|
||||||
TemplateTag string `json:"template_tag"` //模板标签
|
TemplateTag string `json:"template_tag"` //模板标签
|
||||||
|
SelectColorIndex int64 `json:"select_color_index"` //颜色选择索引
|
||||||
}
|
}
|
||||||
type SizeInfo struct {
|
type SizeInfo struct {
|
||||||
Inch string `json:"inch"`
|
Inch string `json:"inch"`
|
||||||
@ -77,7 +76,7 @@ type UserDiyInformation struct {
|
|||||||
Slogan string `json:"slogan"` //slogan
|
Slogan string `json:"slogan"` //slogan
|
||||||
}
|
}
|
||||||
type LightInfo struct {
|
type LightInfo struct {
|
||||||
LightJson string `json:"light_json"` //灯光设计json数据
|
LightJson interface{} `json:"light_json"` //灯光设计json数据
|
||||||
LightName string `json:"light_name"` //名称
|
LightName string `json:"light_name"` //名称
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -47,9 +47,7 @@ func (p *FsUserInfoModel) CreateOrUpdate(gormDB *gorm.DB, req *FsUserInfo) (resp
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *FsUserInfoModel) MergeMetadata(userId int64, meta any) error {
|
func (m *FsUserInfoModel) MergeMetadata(userId int64, meta any) error {
|
||||||
return fssql.MetadataModulePATCH(m.db, "profile", FsUserInfo{}, map[string]any{
|
return fssql.MetadataModulePATCH(m.db, "profile", FsUserInfo{}, meta, "user_id = ?", userId)
|
||||||
"base": meta,
|
|
||||||
}, "user_id = ?", userId)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *FsUserInfoModel) GetProfile(ctx context.Context, pkey string, userId int64) (map[string]any, error) {
|
func (m *FsUserInfoModel) GetProfile(ctx context.Context, pkey string, userId int64) (map[string]any, error) {
|
||||||
@ -81,3 +79,11 @@ func (m *FsUserInfoModel) GetProfile(ctx context.Context, pkey string, userId in
|
|||||||
}
|
}
|
||||||
return info, nil
|
return info, nil
|
||||||
}
|
}
|
||||||
|
func (m *FsUserInfoModel) FindOneByUser(ctx context.Context, userId, guestId int64) (resp *FsUserInfo, err error) {
|
||||||
|
if userId > 0 {
|
||||||
|
err = m.db.WithContext(ctx).Model(&FsUserInfo{}).Where("user_id = ?", userId).Take(&resp).Error
|
||||||
|
} else {
|
||||||
|
err = m.db.WithContext(ctx).Model(&FsUserInfo{}).Where("user_id = ? and guest_id = ?", userId, guestId).Take(&resp).Error
|
||||||
|
}
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|||||||
@ -121,13 +121,58 @@ func (u *FsUserModel) RegisterByGoogleOAuth(ctx context.Context, token *auth.Reg
|
|||||||
user.GoogleId = &googleId
|
user.GoogleId = &googleId
|
||||||
user.PasswordHash = &token.Password
|
user.PasswordHash = &token.Password
|
||||||
user.FirstName = &firstName
|
user.FirstName = &firstName
|
||||||
user.FirstName = &lastName
|
user.LastName = &lastName
|
||||||
err = tx.Model(&FsUser{}).Create(user).Error
|
err = tx.Model(&FsUser{}).Create(user).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// 继承guest_id的资源表
|
// 继承guest_id的资源表
|
||||||
return InheritGuestIdResource(tx, user.Id, token.GuestId, nil)
|
return InheritGuestIdResource(tx, user.Id, token.GuestId, func(txResouce, txUserMaterial, txUserInfo *gorm.DB) error {
|
||||||
|
userProfileBase := UserProfileBase{
|
||||||
|
FirstName: *user.FirstName,
|
||||||
|
LastName: *user.LastName,
|
||||||
|
Email: *user.Email,
|
||||||
|
}
|
||||||
|
|
||||||
|
userProfile := &UserProfile{
|
||||||
|
ProfileBase: userProfileBase,
|
||||||
|
}
|
||||||
|
|
||||||
|
metadata, err := json.Marshal(userProfile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now().UTC()
|
||||||
|
uinfo := &FsUserInfo{
|
||||||
|
Module: FsString("profile"),
|
||||||
|
UserId: &user.Id,
|
||||||
|
GuestId: &token.GuestId,
|
||||||
|
Metadata: &metadata,
|
||||||
|
Ctime: &now,
|
||||||
|
Utime: &now,
|
||||||
|
}
|
||||||
|
|
||||||
|
// logx.Error(metadata)
|
||||||
|
|
||||||
|
err = txUserInfo.Where("module = 'profile' and user_id = ?", *uinfo.UserId).Take(nil).Error
|
||||||
|
if err != nil {
|
||||||
|
if err == gorm.ErrRecordNotFound {
|
||||||
|
err = tx.Model(&FsUserInfo{}).Create(uinfo).Error
|
||||||
|
// logx.Info(err, "*uinfo.UserId:", *uinfo.UserId, " ", uinfo.Id)
|
||||||
|
if err == gorm.ErrRecordNotFound {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = fssql.MetadataModulePATCH(txUserInfo, "profile", FsUserInfo{}, metadata, "user_id = ?", *uinfo.UserId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
@ -178,6 +223,7 @@ func (u *FsUserModel) RegisterByFusen(ctx context.Context, token *auth.RegisterT
|
|||||||
FirstName: FirstName,
|
FirstName: FirstName,
|
||||||
LastName: LastName,
|
LastName: LastName,
|
||||||
Resetaurant: Resetaurant,
|
Resetaurant: Resetaurant,
|
||||||
|
Email: *user.Email,
|
||||||
}
|
}
|
||||||
|
|
||||||
userProfile := &UserProfile{
|
userProfile := &UserProfile{
|
||||||
|
|||||||
@ -36,11 +36,22 @@ func FsBool(v bool) *bool {
|
|||||||
return &v
|
return &v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FsBytes(v string) *[]byte {
|
||||||
|
bs := []byte(v)
|
||||||
|
return &bs
|
||||||
|
}
|
||||||
|
|
||||||
// SubscriptionStatus 订阅状态
|
// SubscriptionStatus 订阅状态
|
||||||
type SubscriptionStatus struct {
|
type SubscriptionStatus struct {
|
||||||
SubEmail bool `json:"all_emails"`
|
NotificationEmail struct {
|
||||||
ItemMap *struct {
|
OrderUpdate bool `json:"order_update"`
|
||||||
} `json:"item_map"`
|
Newseleter bool `json:"newseleter"`
|
||||||
|
} `json:"notification_email"`
|
||||||
|
|
||||||
|
NotificationPhone struct {
|
||||||
|
OrderUpdate bool `json:"order_update"`
|
||||||
|
Newseleter bool `json:"newseleter"`
|
||||||
|
} `json:"notification_phone"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserProfile struct {
|
type UserProfile struct {
|
||||||
@ -52,8 +63,13 @@ type UserProfile struct {
|
|||||||
type UserProfileBase struct {
|
type UserProfileBase struct {
|
||||||
FirstName string `json:"first_name"` // 首名
|
FirstName string `json:"first_name"` // 首名
|
||||||
LastName string `json:"last_name"` // 后名
|
LastName string `json:"last_name"` // 后名
|
||||||
UserName string `json:"user_name"` // 用户名
|
Email string `json:"email"` // email
|
||||||
Mobile string `json:"mobile"` // 电话
|
Mobile string `json:"mobile"` // 电话
|
||||||
Resetaurant string `json:"resetaurant"` // 不知道干什么
|
Resetaurant string `json:"resetaurant"` // 不知道干什么
|
||||||
Company string `json:"company"` // 公司
|
Company string `json:"company"` // 公司
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FsAddressWithDefault struct {
|
||||||
|
*FsAddress
|
||||||
|
IsDefault int64 `json:"is_default"`
|
||||||
|
}
|
||||||
|
|||||||
@ -4,12 +4,13 @@ import "gorm.io/gorm"
|
|||||||
|
|
||||||
// AllModelsGen 所有Model集合,修改单行,只要不改字段名,不会根据新的内容修改,需要修改的话手动删除
|
// AllModelsGen 所有Model集合,修改单行,只要不改字段名,不会根据新的内容修改,需要修改的话手动删除
|
||||||
type AllModelsGen struct {
|
type AllModelsGen struct {
|
||||||
CasbinRule *CasbinRuleModel // casbin_rule
|
CasbinRule *CasbinRuleModel // casbin_rule 后台--权限规则表
|
||||||
FsAddress *FsAddressModel // fs_address 用户地址表
|
FsAddress *FsAddressModel // fs_address 用户地址表
|
||||||
FsAdminApi *FsAdminApiModel // fs_admin_api 后台--接口表
|
FsAdminApi *FsAdminApiModel // fs_admin_api 后台--接口表
|
||||||
FsAdminDepartment *FsAdminDepartmentModel // fs_admin_department 后台--部门表
|
FsAdminDepartment *FsAdminDepartmentModel // fs_admin_department 后台--部门表
|
||||||
FsAdminMenu *FsAdminMenuModel // fs_admin_menu 后台--菜单表
|
FsAdminMenu *FsAdminMenuModel // fs_admin_menu 后台--菜单表
|
||||||
FsAdminRole *FsAdminRoleModel // fs_admin_role 后台--角色表
|
FsAdminRole *FsAdminRoleModel // fs_admin_role 后台--角色表
|
||||||
|
FsAdminRoleApi *FsAdminRoleApiModel // fs_admin_role_api 后台--角色接口表
|
||||||
FsAdminUser *FsAdminUserModel // fs_admin_user 后台--管理员表
|
FsAdminUser *FsAdminUserModel // fs_admin_user 后台--管理员表
|
||||||
FsAuthAssignment *FsAuthAssignmentModel // fs_auth_assignment 用户角色和权限信息
|
FsAuthAssignment *FsAuthAssignmentModel // fs_auth_assignment 用户角色和权限信息
|
||||||
FsAuthItem *FsAuthItemModel // fs_auth_item 用户角色和权限信息
|
FsAuthItem *FsAuthItemModel // fs_auth_item 用户角色和权限信息
|
||||||
@ -67,6 +68,7 @@ type AllModelsGen struct {
|
|||||||
FsPay *FsPayModel // fs_pay 支付记录
|
FsPay *FsPayModel // fs_pay 支付记录
|
||||||
FsPayEvent *FsPayEventModel // fs_pay_event 支付回调事件日志
|
FsPayEvent *FsPayEventModel // fs_pay_event 支付回调事件日志
|
||||||
FsProduct *FsProductModel // fs_product 产品表
|
FsProduct *FsProductModel // fs_product 产品表
|
||||||
|
FsProductCollection *FsProductCollectionModel // fs_product_collection 产品收藏表
|
||||||
FsProductCopy1 *FsProductCopy1Model // fs_product_copy1 产品表
|
FsProductCopy1 *FsProductCopy1Model // fs_product_copy1 产品表
|
||||||
FsProductDesign *FsProductDesignModel // fs_product_design 产品设计表
|
FsProductDesign *FsProductDesignModel // fs_product_design 产品设计表
|
||||||
FsProductDesignGather *FsProductDesignGatherModel // fs_product_design_gather
|
FsProductDesignGather *FsProductDesignGatherModel // fs_product_design_gather
|
||||||
@ -121,6 +123,7 @@ func NewAllModels(gdb *gorm.DB) *AllModelsGen {
|
|||||||
FsAdminDepartment: NewFsAdminDepartmentModel(gdb),
|
FsAdminDepartment: NewFsAdminDepartmentModel(gdb),
|
||||||
FsAdminMenu: NewFsAdminMenuModel(gdb),
|
FsAdminMenu: NewFsAdminMenuModel(gdb),
|
||||||
FsAdminRole: NewFsAdminRoleModel(gdb),
|
FsAdminRole: NewFsAdminRoleModel(gdb),
|
||||||
|
FsAdminRoleApi: NewFsAdminRoleApiModel(gdb),
|
||||||
FsAdminUser: NewFsAdminUserModel(gdb),
|
FsAdminUser: NewFsAdminUserModel(gdb),
|
||||||
FsAuthAssignment: NewFsAuthAssignmentModel(gdb),
|
FsAuthAssignment: NewFsAuthAssignmentModel(gdb),
|
||||||
FsAuthItem: NewFsAuthItemModel(gdb),
|
FsAuthItem: NewFsAuthItemModel(gdb),
|
||||||
@ -178,6 +181,7 @@ func NewAllModels(gdb *gorm.DB) *AllModelsGen {
|
|||||||
FsPay: NewFsPayModel(gdb),
|
FsPay: NewFsPayModel(gdb),
|
||||||
FsPayEvent: NewFsPayEventModel(gdb),
|
FsPayEvent: NewFsPayEventModel(gdb),
|
||||||
FsProduct: NewFsProductModel(gdb),
|
FsProduct: NewFsProductModel(gdb),
|
||||||
|
FsProductCollection: NewFsProductCollectionModel(gdb),
|
||||||
FsProductCopy1: NewFsProductCopy1Model(gdb),
|
FsProductCopy1: NewFsProductCopy1Model(gdb),
|
||||||
FsProductDesign: NewFsProductDesignModel(gdb),
|
FsProductDesign: NewFsProductDesignModel(gdb),
|
||||||
FsProductDesignGather: NewFsProductDesignGatherModel(gdb),
|
FsProductDesignGather: NewFsProductDesignGatherModel(gdb),
|
||||||
|
|||||||
@ -91,23 +91,20 @@ func main() {
|
|||||||
routes...))
|
routes...))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Backends = append(Backends, NewBackend(mux,
|
||||||
|
fmt.Sprintf("http://%s:%d", "localhost", 9501),
|
||||||
|
"/api/v1/namespaces/kubernetes-dashboard"))
|
||||||
|
|
||||||
// 定义用于服务Vue dist文件夹的静态文件服务器
|
// 定义用于服务Vue dist文件夹的静态文件服务器
|
||||||
fs := http.FileServer(http.Dir(vueBuild))
|
fs := http.FileServer(http.Dir(vueBuild))
|
||||||
indexHtmlPath := vueBuild + "/index.html"
|
indexHtmlPath := vueBuild + "/index.html"
|
||||||
mux.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
mux.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
if strings.HasPrefix(r.URL.Path, "/api/") {
|
if strings.HasPrefix(r.URL.Path, "/api/") {
|
||||||
|
|
||||||
r.ParseMultipartForm(100 << 20)
|
r.ParseMultipartForm(100 << 20)
|
||||||
// if err != nil {
|
|
||||||
// logx.Error(err)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 对/api开头的请求进行反向代理
|
// 对/api开头的请求进行反向代理
|
||||||
proxy := httputil.NewSingleHostReverseProxy(apiURL)
|
proxy := httputil.NewSingleHostReverseProxy(apiURL)
|
||||||
proxy.ServeHTTP(w, r)
|
proxy.ServeHTTP(w, r)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// 根据请求路径判断是服务静态文件或者是返回index.html
|
// 根据请求路径判断是服务静态文件或者是返回index.html
|
||||||
idx := strings.Index(r.URL.Path[1:], "/")
|
idx := strings.Index(r.URL.Path[1:], "/")
|
||||||
|
|||||||
@ -48,7 +48,7 @@ run_server() {
|
|||||||
|
|
||||||
# 循环检查screen进程是否存在
|
# 循环检查screen进程是否存在
|
||||||
|
|
||||||
[ -f .gitignore ] || echo $server_name > .gitignore
|
[ -f .gitignore ] || (echo "$server_name" > .gitignore && echo "main" >> .gitignore)
|
||||||
# 使用 screen 运行 go run <server_name>.go
|
# 使用 screen 运行 go run <server_name>.go
|
||||||
|
|
||||||
echo "Running $server_name"
|
echo "Running $server_name"
|
||||||
|
|||||||
1
server/auth/.gitignore
vendored
1
server/auth/.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
auth
|
auth
|
||||||
|
main
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
FROM alpine
|
FROM alpine
|
||||||
|
|
||||||
WORKDIR /www/fusenapi/
|
WORKDIR /www/fusenapi/
|
||||||
COPY ./bin/api-assistant-srv /www/fusenapi/
|
COPY ./bin/api-auth-srv /www/fusenapi/
|
||||||
COPY ./etc /www/fusenapi/etc
|
COPY ./env.yaml /opt/
|
||||||
CMD ["/www/fusenapi/api-assistant-srv"]
|
COPY ./server.fusen.3718.cn.pem /opt/
|
||||||
|
COPY ./server.fusen.3718.cn.key /opt/
|
||||||
|
CMD ["/www/fusenapi/api-auth-srv"]
|
||||||
|
|||||||
@ -2,6 +2,7 @@ Name: auth
|
|||||||
Host: localhost
|
Host: localhost
|
||||||
Port: 9980
|
Port: 9980
|
||||||
ReplicaId: 10
|
ReplicaId: 10
|
||||||
|
HomePage: "http://www.fusen.3718.cn"
|
||||||
MainAddress: "https://server.fusen.3718.cn:9900"
|
MainAddress: "https://server.fusen.3718.cn:9900"
|
||||||
WebsocketAddr: "https://server.fusen.3718.cn:9914"
|
WebsocketAddr: "https://server.fusen.3718.cn:9914"
|
||||||
SourceMysql: "fsreaderwriter:XErSYmLELKMnf3Dh@tcp(fusen.cdmigcvz3rle.us-east-2.rds.amazonaws.com:3306)/fusen"
|
SourceMysql: "fsreaderwriter:XErSYmLELKMnf3Dh@tcp(fusen.cdmigcvz3rle.us-east-2.rds.amazonaws.com:3306)/fusen"
|
||||||
|
|||||||
@ -12,6 +12,7 @@ type Config struct {
|
|||||||
Auth types.Auth
|
Auth types.Auth
|
||||||
ReplicaId uint64
|
ReplicaId uint64
|
||||||
|
|
||||||
|
HomePage string
|
||||||
MainAddress string
|
MainAddress string
|
||||||
WebsocketAddr string
|
WebsocketAddr string
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@ func init() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeLimit = check.NewTimelimit[string](EmailTaskResendTime)
|
TimeLimit = check.NewTimeLimit[string](EmailTaskResendTime)
|
||||||
|
|
||||||
// Initialize the email manager
|
// Initialize the email manager
|
||||||
EmailManager = &EmailSender{
|
EmailManager = &EmailSender{
|
||||||
@ -60,9 +60,10 @@ type EmailFormat struct {
|
|||||||
ConfirmationLink string // fs确认连接
|
ConfirmationLink string // fs确认连接
|
||||||
SenderName string // 发送人
|
SenderName string // 发送人
|
||||||
SenderTitle string // 发送标题
|
SenderTitle string // 发送标题
|
||||||
Extend map[string]string
|
Extend map[string]string // 扩展参数
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 验证邮件格式是否符合要求
|
||||||
func (eformat *EmailFormat) Vaild() error {
|
func (eformat *EmailFormat) Vaild() error {
|
||||||
|
|
||||||
// 1. 检查模板名称
|
// 1. 检查模板名称
|
||||||
@ -123,39 +124,47 @@ type EmailTask struct {
|
|||||||
SendTime time.Time // 处理的任务时间
|
SendTime time.Time // 处理的任务时间
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProcessEmailTasks 是 EmailSender 结构体的方法,用于处理邮件任务。
|
||||||
func (m *EmailSender) ProcessEmailTasks() {
|
func (m *EmailSender) ProcessEmailTasks() {
|
||||||
for {
|
for {
|
||||||
|
// 从 EmailTasks 通道中接收邮件任务
|
||||||
emailformat, ok := <-m.EmailTasks
|
emailformat, ok := <-m.EmailTasks
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Println("Email task channel closed")
|
log.Println("Email task channel closed")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 验证邮件格式是否合法
|
||||||
err := emailformat.Vaild()
|
err := emailformat.Vaild()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 加锁,避免并发修改 emailSending 字典
|
||||||
m.lock.Lock()
|
m.lock.Lock()
|
||||||
|
|
||||||
|
// 检查 emailSending 字典中是否已存在相同的任务
|
||||||
_, isSending := m.emailSending[emailformat.UniqueKey]
|
_, isSending := m.emailSending[emailformat.UniqueKey]
|
||||||
if isSending {
|
if isSending {
|
||||||
m.lock.Unlock()
|
m.lock.Unlock()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 将邮件任务添加到 emailSending 字典中
|
||||||
m.emailSending[emailformat.UniqueKey] = &EmailTask{
|
m.emailSending[emailformat.UniqueKey] = &EmailTask{
|
||||||
Email: emailformat,
|
Email: emailformat,
|
||||||
SendTime: time.Now().UTC(),
|
SendTime: time.Now().UTC(),
|
||||||
}
|
}
|
||||||
m.lock.Unlock()
|
m.lock.Unlock()
|
||||||
|
|
||||||
// Acquire a token
|
// 获取一个信号量,限制同时发送的邮件任务数量
|
||||||
m.semaphore <- struct{}{}
|
m.semaphore <- struct{}{}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer func() { <-m.semaphore }() // Release a token
|
defer func() { <-m.semaphore }() // 释放一个信号量
|
||||||
|
|
||||||
|
// 渲染邮件模板内容
|
||||||
content := RenderEmailTemplate(
|
content := RenderEmailTemplate(
|
||||||
emailformat.TemplateName,
|
emailformat.TemplateName,
|
||||||
emailformat.CompanyName,
|
emailformat.CompanyName,
|
||||||
@ -164,34 +173,41 @@ func (m *EmailSender) ProcessEmailTasks() {
|
|||||||
emailformat.SenderTitle,
|
emailformat.SenderTitle,
|
||||||
emailformat.Extend,
|
emailformat.Extend,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 发送邮件
|
||||||
err := smtp.SendMail("smtp.gmail.com:587", m.Auth, m.FromEmail, []string{emailformat.TargetEmail}, content)
|
err := smtp.SendMail("smtp.gmail.com:587", m.Auth, m.FromEmail, []string{emailformat.TargetEmail}, content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to send email to %s: %v\n", emailformat, err)
|
log.Printf("Failed to send email to %s: %v\n", emailformat, err)
|
||||||
|
// 重新发送邮件
|
||||||
m.Resend(emailformat.UniqueKey, content)
|
m.Resend(emailformat.UniqueKey, content)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resend 重发邮件
|
// Resend 是 EmailSender 结构体的方法,用于重发邮件。
|
||||||
func (m *EmailSender) Resend(uniqueKey string, content []byte) {
|
func (m *EmailSender) Resend(uniqueKey string, content []byte) {
|
||||||
|
// 等待一段时间后重发邮件,避免频繁重发
|
||||||
time.Sleep(m.ResendTimeLimit)
|
time.Sleep(m.ResendTimeLimit)
|
||||||
|
|
||||||
m.lock.Lock()
|
m.lock.Lock()
|
||||||
defer m.lock.Unlock()
|
defer m.lock.Unlock()
|
||||||
// Check if the email task still exists and has not been sent successfully
|
|
||||||
|
// 检查邮件任务是否仍存在并且未成功发送
|
||||||
if task, ok := m.emailSending[uniqueKey]; ok && task.SendTime.Add(m.ResendTimeLimit).After(time.Now().UTC()) {
|
if task, ok := m.emailSending[uniqueKey]; ok && task.SendTime.Add(m.ResendTimeLimit).After(time.Now().UTC()) {
|
||||||
err := smtp.SendMail(task.Email.TargetEmail, m.Auth, m.FromEmail, []string{task.Email.TargetEmail}, content)
|
err := smtp.SendMail(task.Email.TargetEmail, m.Auth, m.FromEmail, []string{task.Email.TargetEmail}, content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to resend email to %s: %v\n", task.Email.TargetEmail, err)
|
log.Printf("Failed to resend email to %s: %v\n", task.Email.TargetEmail, err)
|
||||||
} else {
|
} else {
|
||||||
|
// 从 emailSending 字典中删除已成功发送的邮件任务
|
||||||
delete(m.emailSending, uniqueKey)
|
delete(m.emailSending, uniqueKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClearExpiredTasks 清除过期的邮件任务
|
// ClearExpiredTasks 是 EmailSender 结构体的方法,用于清除过期的邮件任务。
|
||||||
func (m *EmailSender) ClearExpiredTasks() {
|
func (m *EmailSender) ClearExpiredTasks() {
|
||||||
|
// 每分钟触发一次清除操作
|
||||||
ticker := time.NewTicker(time.Minute)
|
ticker := time.NewTicker(time.Minute)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
|
||||||
@ -199,6 +215,7 @@ func (m *EmailSender) ClearExpiredTasks() {
|
|||||||
<-ticker.C
|
<-ticker.C
|
||||||
|
|
||||||
m.lock.Lock()
|
m.lock.Lock()
|
||||||
|
// 遍历 emailSending 字典,删除发送时间超过一定限制的过期任务
|
||||||
for email, task := range m.emailSending {
|
for email, task := range m.emailSending {
|
||||||
if task.SendTime.Add(m.ResendTimeLimit).Before(time.Now().UTC()) {
|
if task.SendTime.Add(m.ResendTimeLimit).Before(time.Now().UTC()) {
|
||||||
delete(m.emailSending, email)
|
delete(m.emailSending, email)
|
||||||
@ -208,8 +225,19 @@ func (m *EmailSender) ClearExpiredTasks() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func RenderEmailTemplate(templateName, companyName, confirmationLink, senderName, senderTitle string, extend map[string]string) []byte {
|
// RenderEmailTemplate 是一个渲染邮件模板的函数,根据给定的参数生成邮件内容。
|
||||||
|
// 参数:
|
||||||
|
// - templateName: 邮件模板的名称
|
||||||
|
// - companyName: 公司名称
|
||||||
|
// - confirmationLink: 确认链接
|
||||||
|
// - senderName: 发件人姓名
|
||||||
|
// - senderTitle: 发件人职务
|
||||||
|
// - extend: 扩展字段,包含其他自定义键值对的映射
|
||||||
|
// 返回值:
|
||||||
|
// - []byte: 渲染后的邮件内容(以字节切片形式返回)
|
||||||
|
|
||||||
|
func RenderEmailTemplate(templateName, companyName, confirmationLink, senderName, senderTitle string, extend map[string]string) []byte {
|
||||||
|
// 创建一个包含邮件模板所需数据的映射
|
||||||
data := map[string]string{
|
data := map[string]string{
|
||||||
"CompanyName": companyName,
|
"CompanyName": companyName,
|
||||||
"ConfirmationLink": confirmationLink,
|
"ConfirmationLink": confirmationLink,
|
||||||
@ -217,16 +245,20 @@ func RenderEmailTemplate(templateName, companyName, confirmationLink, senderName
|
|||||||
"SenderTitle": senderTitle,
|
"SenderTitle": senderTitle,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 将扩展字段中的键值对添加到数据映射中
|
||||||
for k, v := range extend {
|
for k, v := range extend {
|
||||||
data[k] = v
|
data[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 创建一个字节缓冲区,用于存储渲染后的邮件内容
|
||||||
var result bytes.Buffer
|
var result bytes.Buffer
|
||||||
// result.Write([]byte("MIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\n\n"))
|
|
||||||
|
// 使用给定的数据映射执行邮件模板渲染
|
||||||
err := tpls.ExecuteTemplate(&result, templateName, data)
|
err := tpls.ExecuteTemplate(&result, templateName, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 将渲染后的邮件内容转换为字节切片并返回
|
||||||
return result.Bytes()
|
return result.Bytes()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,6 @@ import (
|
|||||||
"fusenapi/server/auth/internal/svc"
|
"fusenapi/server/auth/internal/svc"
|
||||||
"fusenapi/server/auth/internal/types"
|
"fusenapi/server/auth/internal/types"
|
||||||
|
|
||||||
"github.com/474420502/requests"
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
"github.com/zeromicro/go-zero/rest/httpx"
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@ -49,7 +48,6 @@ func FinishRegister(svcCtx *svc.ServiceContext, user *gmodel.FsUser, token *auth
|
|||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +55,7 @@ func FinishRegister(svcCtx *svc.ServiceContext, user *gmodel.FsUser, token *auth
|
|||||||
event.Data = wevent.DataEmailRegister{
|
event.Data = wevent.DataEmailRegister{
|
||||||
JwtToken: jwtToken,
|
JwtToken: jwtToken,
|
||||||
}
|
}
|
||||||
err = CommonNotify(svcCtx.Config.WebsocketAddr, token.Wid, event)
|
err = wevent.CommonNotify(svcCtx.Config.WebsocketAddr, token.Wid, event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// logx.Error(err, token.TraceId)
|
// logx.Error(err, token.TraceId)
|
||||||
return err
|
return err
|
||||||
@ -66,34 +64,6 @@ func FinishRegister(svcCtx *svc.ServiceContext, user *gmodel.FsUser, token *auth
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CommonNotify(WebsocketAddr, wid string, event *wevent.WebsocketEvent) error {
|
|
||||||
|
|
||||||
reqWebsocketAddr := fmt.Sprintf("%s/api/websocket/common_notify", WebsocketAddr)
|
|
||||||
tp := requests.Post(reqWebsocketAddr)
|
|
||||||
tp.SetBodyJson(requests.M{
|
|
||||||
"wid": wid,
|
|
||||||
"data": event,
|
|
||||||
})
|
|
||||||
|
|
||||||
wresp, err := tp.Execute()
|
|
||||||
if err != nil {
|
|
||||||
// logx.Error(err, token.TraceId)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
result := wresp.Json()
|
|
||||||
|
|
||||||
if !result.Get("code").Exists() {
|
|
||||||
return fmt.Errorf("send %s is error", reqWebsocketAddr)
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.Get("code").Int() != 200 {
|
|
||||||
return fmt.Errorf("%s", result.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *UserEmailConfirmationLogic) UserEmailConfirmation(req *types.RequestEmailConfirmation, userinfo *auth.UserInfo) (resp *basic.Response) {
|
func (l *UserEmailConfirmationLogic) UserEmailConfirmation(req *types.RequestEmailConfirmation, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
// userinfo 传入值时, 一定不为null
|
// userinfo 传入值时, 一定不为null
|
||||||
@ -176,7 +146,7 @@ func (l *UserEmailConfirmationLogic) UserEmailConfirmation(req *types.RequestEma
|
|||||||
}
|
}
|
||||||
|
|
||||||
event := wevent.NewWebsocketEventSuccess(wevent.UserResetToken, rt.TraceId)
|
event := wevent.NewWebsocketEventSuccess(wevent.UserResetToken, rt.TraceId)
|
||||||
err = CommonNotify(l.svcCtx.Config.MainAddress, rt.Wid, event)
|
err = wevent.CommonNotify(l.svcCtx.Config.MainAddress, rt.Wid, event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err, rt.TraceId)
|
logx.Error(err, rt.TraceId)
|
||||||
return resp.SetStatus(basic.CodeResetPasswordErr, err.Error())
|
return resp.SetStatus(basic.CodeResetPasswordErr, err.Error())
|
||||||
|
|||||||
@ -47,6 +47,10 @@ func (l *UserEmailRegisterLogic) UserEmailRegister(req *types.RequestEmailRegist
|
|||||||
return resp.SetStatus(basic.CodeOAuthEmailErr)
|
return resp.SetStatus(basic.CodeOAuthEmailErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(req.Email) > 50 {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeOAuthEmailErr, "email len must < 50")
|
||||||
|
}
|
||||||
|
|
||||||
if !TimeLimit.Is(req.Email) {
|
if !TimeLimit.Is(req.Email) {
|
||||||
return resp.SetStatus(basic.CodeEmailTimeShortErr)
|
return resp.SetStatus(basic.CodeEmailTimeShortErr)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,6 +41,10 @@ func (l *UserRegisterLogic) UserRegister(req *types.RequestUserRegister, userinf
|
|||||||
return resp.SetStatus(basic.CodeOAuthEmailErr)
|
return resp.SetStatus(basic.CodeOAuthEmailErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(req.Email) > 50 {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeOAuthEmailErr, "email len must < 50")
|
||||||
|
}
|
||||||
|
|
||||||
// _, err := l.svcCtx.AllModels.FsUser.FindUserByEmail(l.ctx, req.Email)
|
// _, err := l.svcCtx.AllModels.FsUser.FindUserByEmail(l.ctx, req.Email)
|
||||||
// if err == nil {
|
// if err == nil {
|
||||||
// return resp.SetStatus(basic.CodeEmailExistsErr)
|
// return resp.SetStatus(basic.CodeEmailExistsErr)
|
||||||
|
|||||||
@ -50,7 +50,7 @@ func (l *UserResetPasswordHtmlLogic) UserResetPasswordHtml(req *types.RequestUse
|
|||||||
func (l *UserResetPasswordHtmlLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
func (l *UserResetPasswordHtmlLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||||
|
|
||||||
err := tpls.ExecuteTemplate(w, "reset_confirm.tpl", map[string]string{
|
err := tpls.ExecuteTemplate(w, "reset_confirm.tpl", map[string]string{
|
||||||
"HomePage": "http://www.fusen.3718.cn",
|
"HomePage": l.svcCtx.Config.HomePage,
|
||||||
"ResetToken": l.ResetToken,
|
"ResetToken": l.ResetToken,
|
||||||
"ResetPasswordLink": l.svcCtx.Config.MainAddress + "/api/auth/reset/password",
|
"ResetPasswordLink": l.svcCtx.Config.MainAddress + "/api/auth/reset/password",
|
||||||
})
|
})
|
||||||
|
|||||||
@ -39,6 +39,10 @@ func (l *UserResetPasswordLogic) UserResetPassword(req *types.RequestUserResetPa
|
|||||||
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
// userinfo 传入值时, 一定不为null
|
// userinfo 传入值时, 一定不为null
|
||||||
|
|
||||||
|
if len(req.NewPassword) > 30 {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodePasswordErr, "password len must < 30")
|
||||||
|
}
|
||||||
|
|
||||||
rt, err := l.svcCtx.ResetTokenManger.Decrypt(req.ResetToken) // ResetToken
|
rt, err := l.svcCtx.ResetTokenManger.Decrypt(req.ResetToken) // ResetToken
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
@ -51,7 +55,7 @@ func (l *UserResetPasswordLogic) UserResetPassword(req *types.RequestUserResetPa
|
|||||||
}
|
}
|
||||||
|
|
||||||
if time.Since(rt.CreateAt) > 30*time.Minute {
|
if time.Since(rt.CreateAt) > 30*time.Minute {
|
||||||
return resp.SetStatusWithMessage(basic.CodeOAuthConfirmationTimeoutErr, "Verification links expire after 30 minute.")
|
return resp.SetStatusWithMessage(basic.CodeOAuthConfirmationTimeoutErr, "verification links expire after 30 minute.")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = l.svcCtx.AllModels.FsUser.Transaction(l.ctx, func(tx *gorm.DB) error {
|
err = l.svcCtx.AllModels.FsUser.Transaction(l.ctx, func(tx *gorm.DB) error {
|
||||||
@ -67,7 +71,7 @@ func (l *UserResetPasswordLogic) UserResetPassword(req *types.RequestUserResetPa
|
|||||||
}
|
}
|
||||||
|
|
||||||
if *user.PasswordHash == req.NewPassword {
|
if *user.PasswordHash == req.NewPassword {
|
||||||
return fmt.Errorf("the password is the same as the old one. It needs to be changed")
|
return fmt.Errorf("the password is the same as the old one. it needs to be changed")
|
||||||
}
|
}
|
||||||
|
|
||||||
return tx.Where("id = ?", rt.UserId).Update("PasswordHash", req.NewPassword).Error
|
return tx.Where("id = ?", rt.UserId).Update("PasswordHash", req.NewPassword).Error
|
||||||
@ -79,7 +83,7 @@ func (l *UserResetPasswordLogic) UserResetPassword(req *types.RequestUserResetPa
|
|||||||
}
|
}
|
||||||
|
|
||||||
event := wevent.NewWebsocketEventSuccess(wevent.UserResetToken, rt.TraceId)
|
event := wevent.NewWebsocketEventSuccess(wevent.UserResetToken, rt.TraceId)
|
||||||
err = CommonNotify(l.svcCtx.Config.WebsocketAddr, rt.Wid, event)
|
err = wevent.CommonNotify(l.svcCtx.Config.WebsocketAddr, rt.Wid, event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err, rt.TraceId)
|
logx.Error(err, rt.TraceId)
|
||||||
return resp.SetStatusWithMessage(basic.CodeResetPasswordErr, err.Error())
|
return resp.SetStatusWithMessage(basic.CodeResetPasswordErr, err.Error())
|
||||||
|
|||||||
@ -39,7 +39,7 @@ func (l *UserResetTokenLogic) UserResetToken(req *types.RequestUserResetToken, u
|
|||||||
user, err := l.svcCtx.AllModels.FsUser.FindUserByEmail(context.TODO(), req.Email)
|
user, err := l.svcCtx.AllModels.FsUser.FindUserByEmail(context.TODO(), req.Email)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
return resp.SetStatus(basic.CodeRequestParamsErr, err.Error())
|
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
token := &auth.ResetToken{
|
token := &auth.ResetToken{
|
||||||
|
|||||||
1
server/base/.gitignore
vendored
1
server/base/.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
base
|
base
|
||||||
|
main
|
||||||
|
|||||||
8
server/base/Dockerfile
Executable file
8
server/base/Dockerfile
Executable file
@ -0,0 +1,8 @@
|
|||||||
|
FROM alpine
|
||||||
|
|
||||||
|
WORKDIR /www/fusenapi/
|
||||||
|
COPY ./bin/api-base-srv /www/fusenapi/
|
||||||
|
COPY ./env.yaml /opt/
|
||||||
|
COPY ./server.fusen.3718.cn.pem /opt/
|
||||||
|
COPY ./server.fusen.3718.cn.key /opt/
|
||||||
|
CMD ["/www/fusenapi/api-base-srv"]
|
||||||
1
server/canteen/.gitignore
vendored
1
server/canteen/.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
canteen
|
canteen
|
||||||
|
main
|
||||||
|
|||||||
@ -2,5 +2,7 @@ FROM alpine
|
|||||||
|
|
||||||
WORKDIR /www/fusenapi/
|
WORKDIR /www/fusenapi/
|
||||||
COPY ./bin/api-canteen-srv /www/fusenapi/
|
COPY ./bin/api-canteen-srv /www/fusenapi/
|
||||||
COPY ./etc /www/fusenapi/etc
|
COPY ./env.yaml /opt/
|
||||||
|
COPY ./server.fusen.3718.cn.pem /opt/
|
||||||
|
COPY ./server.fusen.3718.cn.key /opt/
|
||||||
CMD ["/www/fusenapi/api-canteen-srv"]
|
CMD ["/www/fusenapi/api-canteen-srv"]
|
||||||
|
|||||||
2
server/collection/.gitignore
vendored
Normal file
2
server/collection/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
collection
|
||||||
|
main
|
||||||
8
server/collection/Dockerfile
Executable file
8
server/collection/Dockerfile
Executable file
@ -0,0 +1,8 @@
|
|||||||
|
FROM alpine
|
||||||
|
|
||||||
|
WORKDIR /www/fusenapi/
|
||||||
|
COPY ./bin/api-collection-srv /www/fusenapi/
|
||||||
|
COPY ./env.yaml /opt/
|
||||||
|
COPY ./server.fusen.3718.cn.pem /opt/
|
||||||
|
COPY ./server.fusen.3718.cn.key /opt/
|
||||||
|
CMD ["/www/fusenapi/api-collection-srv"]
|
||||||
36
server/collection/collection.go
Normal file
36
server/collection/collection.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"fusenapi/utils/auth"
|
||||||
|
"fusenapi/utils/fsconfig"
|
||||||
|
|
||||||
|
"fusenapi/server/collection/internal/config"
|
||||||
|
"fusenapi/server/collection/internal/handler"
|
||||||
|
"fusenapi/server/collection/internal/svc"
|
||||||
|
"github.com/zeromicro/go-zero/rest"
|
||||||
|
)
|
||||||
|
|
||||||
|
var configFile = flag.String("f", "etc/collection.yaml", "the config file")
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
var c config.Config
|
||||||
|
fsconfig.StartNacosConfig(*configFile, &c, nil)
|
||||||
|
|
||||||
|
c.Timeout = int64(time.Second * 15)
|
||||||
|
server := rest.MustNewServer(c.RestConf, rest.WithCustomCors(auth.FsCors, func(w http.ResponseWriter) {
|
||||||
|
}))
|
||||||
|
defer server.Stop()
|
||||||
|
|
||||||
|
ctx := svc.NewServiceContext(c)
|
||||||
|
handler.RegisterHandlers(server, ctx)
|
||||||
|
|
||||||
|
fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
|
||||||
|
server.Start()
|
||||||
|
}
|
||||||
10
server/collection/etc/collection.yaml
Normal file
10
server/collection/etc/collection.yaml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Name: collection
|
||||||
|
Host: 0.0.0.0
|
||||||
|
Port: 9922
|
||||||
|
Timeout: 15000 #服务超时时间(毫秒)
|
||||||
|
SourceMysql: fsreaderwriter:XErSYmLELKMnf3Dh@tcp(fusen.cdmigcvz3rle.us-east-2.rds.amazonaws.com:3306)/fusen
|
||||||
|
SourceRabbitMq: ""
|
||||||
|
Auth:
|
||||||
|
AccessSecret: fusen2023
|
||||||
|
AccessExpire: 2592000
|
||||||
|
RefreshAfter: 1592000
|
||||||
17
server/collection/internal/config/config.go
Normal file
17
server/collection/internal/config/config.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fusenapi/server/collection/internal/types"
|
||||||
|
"github.com/zeromicro/go-zero/rest"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
rest.RestConf
|
||||||
|
SourceMysql string
|
||||||
|
Auth types.Auth
|
||||||
|
SourceRabbitMq string
|
||||||
|
BLMService struct {
|
||||||
|
Version string
|
||||||
|
Urls []string
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,27 +6,27 @@ import (
|
|||||||
|
|
||||||
"fusenapi/utils/basic"
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
"fusenapi/server/product/internal/logic"
|
"fusenapi/server/collection/internal/logic"
|
||||||
"fusenapi/server/product/internal/svc"
|
"fusenapi/server/collection/internal/svc"
|
||||||
"fusenapi/server/product/internal/types"
|
"fusenapi/server/collection/internal/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetProductListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
func CollectProductHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
var req types.GetProductListReq
|
var req types.CollectProductReq
|
||||||
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建一个业务逻辑层实例
|
// 创建一个业务逻辑层实例
|
||||||
l := logic.NewGetProductListLogic(r.Context(), svcCtx)
|
l := logic.NewCollectProductLogic(r.Context(), svcCtx)
|
||||||
|
|
||||||
rl := reflect.ValueOf(l)
|
rl := reflect.ValueOf(l)
|
||||||
basic.BeforeLogic(w, r, rl)
|
basic.BeforeLogic(w, r, rl)
|
||||||
|
|
||||||
resp := l.GetProductList(&req, userinfo)
|
resp := l.CollectProduct(&req, userinfo)
|
||||||
|
|
||||||
if !basic.AfterLogic(w, r, rl, resp) {
|
if !basic.AfterLogic(w, r, rl, resp) {
|
||||||
basic.NormalAfterLogic(w, r, resp)
|
basic.NormalAfterLogic(w, r, resp)
|
||||||
@ -6,27 +6,27 @@ import (
|
|||||||
|
|
||||||
"fusenapi/utils/basic"
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
"fusenapi/server/product/internal/logic"
|
"fusenapi/server/collection/internal/logic"
|
||||||
"fusenapi/server/product/internal/svc"
|
"fusenapi/server/collection/internal/svc"
|
||||||
"fusenapi/server/product/internal/types"
|
"fusenapi/server/collection/internal/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetLastProductDesignHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
func DeleteCollectProductHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
var req types.Request
|
var req types.DeleteCollectProductReq
|
||||||
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建一个业务逻辑层实例
|
// 创建一个业务逻辑层实例
|
||||||
l := logic.NewGetLastProductDesignLogic(r.Context(), svcCtx)
|
l := logic.NewDeleteCollectProductLogic(r.Context(), svcCtx)
|
||||||
|
|
||||||
rl := reflect.ValueOf(l)
|
rl := reflect.ValueOf(l)
|
||||||
basic.BeforeLogic(w, r, rl)
|
basic.BeforeLogic(w, r, rl)
|
||||||
|
|
||||||
resp := l.GetLastProductDesign(&req, userinfo)
|
resp := l.DeleteCollectProduct(&req, userinfo)
|
||||||
|
|
||||||
if !basic.AfterLogic(w, r, rl, resp) {
|
if !basic.AfterLogic(w, r, rl, resp) {
|
||||||
basic.NormalAfterLogic(w, r, resp)
|
basic.NormalAfterLogic(w, r, resp)
|
||||||
@ -6,27 +6,27 @@ import (
|
|||||||
|
|
||||||
"fusenapi/utils/basic"
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
"fusenapi/server/home-user-auth/internal/logic"
|
"fusenapi/server/collection/internal/logic"
|
||||||
"fusenapi/server/home-user-auth/internal/svc"
|
"fusenapi/server/collection/internal/svc"
|
||||||
"fusenapi/server/home-user-auth/internal/types"
|
"fusenapi/server/collection/internal/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func UserAddAddressHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
func GetCollectProductListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
var req types.RequestAddAddress
|
var req types.GetCollectProductListReq
|
||||||
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建一个业务逻辑层实例
|
// 创建一个业务逻辑层实例
|
||||||
l := logic.NewUserAddAddressLogic(r.Context(), svcCtx)
|
l := logic.NewGetCollectProductListLogic(r.Context(), svcCtx)
|
||||||
|
|
||||||
rl := reflect.ValueOf(l)
|
rl := reflect.ValueOf(l)
|
||||||
basic.BeforeLogic(w, r, rl)
|
basic.BeforeLogic(w, r, rl)
|
||||||
|
|
||||||
resp := l.UserAddAddress(&req, userinfo)
|
resp := l.GetCollectProductList(&req, userinfo)
|
||||||
|
|
||||||
if !basic.AfterLogic(w, r, rl, resp) {
|
if !basic.AfterLogic(w, r, rl, resp) {
|
||||||
basic.NormalAfterLogic(w, r, resp)
|
basic.NormalAfterLogic(w, r, resp)
|
||||||
42
server/collection/internal/handler/routes.go
Normal file
42
server/collection/internal/handler/routes.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"fusenapi/server/collection/internal/svc"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/rest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||||
|
server.AddRoutes(
|
||||||
|
[]rest.Route{
|
||||||
|
{
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/api/collection/collect_product",
|
||||||
|
Handler: CollectProductHandler(serverCtx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/api/collection/delete_collect_product",
|
||||||
|
Handler: DeleteCollectProductHandler(serverCtx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: "/api/collection/get_collect_product_list",
|
||||||
|
Handler: GetCollectProductListHandler(serverCtx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: "/api/collection/test_ai",
|
||||||
|
Handler: TestAiHandler(serverCtx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/api/collection/test_pdf",
|
||||||
|
Handler: TestPdfHandler(serverCtx),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -6,27 +6,27 @@ import (
|
|||||||
|
|
||||||
"fusenapi/utils/basic"
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
"fusenapi/server/product/internal/logic"
|
"fusenapi/server/collection/internal/logic"
|
||||||
"fusenapi/server/product/internal/svc"
|
"fusenapi/server/collection/internal/svc"
|
||||||
"fusenapi/server/product/internal/types"
|
"fusenapi/server/collection/internal/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func DesignGatherHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
func TestAiHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
var req types.DesignGatherReq
|
var req types.TestAiReq
|
||||||
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建一个业务逻辑层实例
|
// 创建一个业务逻辑层实例
|
||||||
l := logic.NewDesignGatherLogic(r.Context(), svcCtx)
|
l := logic.NewTestAiLogic(r.Context(), svcCtx)
|
||||||
|
|
||||||
rl := reflect.ValueOf(l)
|
rl := reflect.ValueOf(l)
|
||||||
basic.BeforeLogic(w, r, rl)
|
basic.BeforeLogic(w, r, rl)
|
||||||
|
|
||||||
resp := l.DesignGather(&req, userinfo)
|
resp := l.TestAi(&req, userinfo)
|
||||||
|
|
||||||
if !basic.AfterLogic(w, r, rl, resp) {
|
if !basic.AfterLogic(w, r, rl, resp) {
|
||||||
basic.NormalAfterLogic(w, r, resp)
|
basic.NormalAfterLogic(w, r, resp)
|
||||||
35
server/collection/internal/handler/testpdfhandler.go
Normal file
35
server/collection/internal/handler/testpdfhandler.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
|
"fusenapi/server/collection/internal/logic"
|
||||||
|
"fusenapi/server/collection/internal/svc"
|
||||||
|
"fusenapi/server/collection/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPdfHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
var req types.TestPdfReq
|
||||||
|
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建一个业务逻辑层实例
|
||||||
|
l := logic.NewTestPdfLogic(r.Context(), svcCtx)
|
||||||
|
|
||||||
|
rl := reflect.ValueOf(l)
|
||||||
|
basic.BeforeLogic(w, r, rl)
|
||||||
|
|
||||||
|
resp := l.TestPdf(&req, userinfo)
|
||||||
|
|
||||||
|
if !basic.AfterLogic(w, r, rl, resp) {
|
||||||
|
basic.NormalAfterLogic(w, r, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
92
server/collection/internal/logic/collectproductlogic.go
Normal file
92
server/collection/internal/logic/collectproductlogic.go
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
package logic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fusenapi/model/gmodel"
|
||||||
|
"fusenapi/utils/auth"
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"fusenapi/server/collection/internal/svc"
|
||||||
|
"fusenapi/server/collection/internal/types"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CollectProductLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCollectProductLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CollectProductLogic {
|
||||||
|
return &CollectProductLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理进入前逻辑w,r
|
||||||
|
// func (l *CollectProductLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (l *CollectProductLogic) CollectProduct(req *types.CollectProductReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
|
if !userinfo.IsUser() && !userinfo.IsGuest() {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeUnAuth, "please sign in before collect product")
|
||||||
|
}
|
||||||
|
//查询产品
|
||||||
|
productInfo, err := l.svcCtx.AllModels.FsProduct.FindOne(l.ctx, req.ProductId)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "the product is not found")
|
||||||
|
}
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "faile to get product info")
|
||||||
|
}
|
||||||
|
//校验下状态
|
||||||
|
/*if *productInfo.Status != 1 {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "the product status is unNormal")
|
||||||
|
}*/
|
||||||
|
//下架了
|
||||||
|
if *productInfo.IsShelf == 0 {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "the product is off shelf")
|
||||||
|
}
|
||||||
|
if *productInfo.IsDel == 1 {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "the product is deleted")
|
||||||
|
}
|
||||||
|
//查询收藏
|
||||||
|
_, err = l.svcCtx.AllModels.FsProductCollection.FindOne(l.ctx, userinfo.UserId, userinfo.GuestId, req.ProductId)
|
||||||
|
if err != nil {
|
||||||
|
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to check repeat of collection")
|
||||||
|
}
|
||||||
|
//创建
|
||||||
|
now := time.Now().UTC()
|
||||||
|
err = l.svcCtx.AllModels.FsProductCollection.Create(l.ctx, &gmodel.FsProductCollection{
|
||||||
|
UserId: &userinfo.UserId,
|
||||||
|
GuestId: &userinfo.GuestId,
|
||||||
|
ProductId: &req.ProductId,
|
||||||
|
TemplateTag: &req.TemplateTag,
|
||||||
|
SelectColorIndex: &req.SelectColorIndex,
|
||||||
|
Logo: &req.Logo,
|
||||||
|
Ctime: &now,
|
||||||
|
Utime: &now,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to collect product")
|
||||||
|
}
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeOK, "The product has been collected successfully")
|
||||||
|
}
|
||||||
|
return resp.SetStatusAddMessage(basic.CodeOK, "You have collect this product and don`t need to repeat again")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
// func (l *CollectProductLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||||
|
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
// }
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
package logic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fusenapi/utils/auth"
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"fusenapi/server/collection/internal/svc"
|
||||||
|
"fusenapi/server/collection/internal/types"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DeleteCollectProductLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDeleteCollectProductLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteCollectProductLogic {
|
||||||
|
return &DeleteCollectProductLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理进入前逻辑w,r
|
||||||
|
// func (l *DeleteCollectProductLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (l *DeleteCollectProductLogic) DeleteCollectProduct(req *types.DeleteCollectProductReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
|
if !userinfo.IsUser() && !userinfo.IsGuest() {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeUnAuth, "please sign in before to collect product")
|
||||||
|
}
|
||||||
|
for _, id := range req.Ids {
|
||||||
|
err := l.svcCtx.AllModels.FsProductCollection.Delete2(l.ctx, userinfo.UserId, userinfo.GuestId, id)
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to remove product collection")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp.SetStatus(basic.CodeOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
// func (l *DeleteCollectProductLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||||
|
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
// }
|
||||||
190
server/collection/internal/logic/getcollectproductlistlogic.go
Normal file
190
server/collection/internal/logic/getcollectproductlistlogic.go
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
package logic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"fusenapi/constants"
|
||||||
|
"fusenapi/model/gmodel"
|
||||||
|
"fusenapi/utils/auth"
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
"fusenapi/utils/format"
|
||||||
|
"fusenapi/utils/s3url_to_s3id"
|
||||||
|
"math"
|
||||||
|
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"fusenapi/server/collection/internal/svc"
|
||||||
|
"fusenapi/server/collection/internal/types"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetCollectProductListLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGetCollectProductListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetCollectProductListLogic {
|
||||||
|
return &GetCollectProductListLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理进入前逻辑w,r
|
||||||
|
// func (l *GetCollectProductListLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (l *GetCollectProductListLogic) GetCollectProductList(req *types.GetCollectProductListReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
|
if req.CurrentPage <= 0 {
|
||||||
|
req.CurrentPage = constants.DEFAULT_PAGE
|
||||||
|
}
|
||||||
|
limit := 10
|
||||||
|
//查询列表
|
||||||
|
collectionList, total, err := l.svcCtx.AllModels.FsProductCollection.GetList(l.ctx, userinfo.UserId, userinfo.GuestId, req.CurrentPage, limit, "id DESC")
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get collection list")
|
||||||
|
}
|
||||||
|
//没有数据
|
||||||
|
if len(collectionList) == 0 {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeOK, "success", types.GetCollectProductListRsp{
|
||||||
|
Meta: types.Meta{
|
||||||
|
TotalCount: total,
|
||||||
|
PageCount: int64(math.Ceil(float64(total) / float64(limit))),
|
||||||
|
CurrentPage: req.CurrentPage,
|
||||||
|
PerPage: limit,
|
||||||
|
},
|
||||||
|
List: []types.GetCollectProductListRspItem{},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
productIds := make([]int64, 0, len(collectionList))
|
||||||
|
for _, v := range collectionList {
|
||||||
|
productIds = append(productIds, *v.ProductId)
|
||||||
|
}
|
||||||
|
//获取产品所有模型+配件来计算最低价
|
||||||
|
modelList, err := l.svcCtx.AllModels.FsProductModel3d.GetAllByProductIdsTags(l.ctx, productIds, []int{constants.TAG_MODEL, constants.TAG_PARTS}, "id,tag,product_id,part_id,price,step_price")
|
||||||
|
mapModel := make(map[int64]int)
|
||||||
|
for k, v := range modelList {
|
||||||
|
mapModel[v.Id] = k
|
||||||
|
}
|
||||||
|
//计算最低价
|
||||||
|
mapProductMinPrice := make(map[int64]int64)
|
||||||
|
for _, v := range modelList {
|
||||||
|
if *v.Tag != constants.TAG_MODEL {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var stepPrice gmodel.StepPriceJsonStruct
|
||||||
|
if err = json.Unmarshal(*v.StepPrice, &stepPrice); err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeJsonErr, fmt.Sprintf("failed to parse step price:%d", v.Id))
|
||||||
|
}
|
||||||
|
//阶梯最低单价
|
||||||
|
itemPrice := int64(0)
|
||||||
|
if len(stepPrice.PriceRange) > 0 {
|
||||||
|
itemPrice = stepPrice.PriceRange[0].Price
|
||||||
|
}
|
||||||
|
//配件价格
|
||||||
|
if fittingIndex, ok := mapModel[*v.PartId]; ok {
|
||||||
|
itemPrice += *modelList[fittingIndex].Price
|
||||||
|
}
|
||||||
|
//查询比较最低价
|
||||||
|
if minPrice, ok := mapProductMinPrice[*v.ProductId]; ok {
|
||||||
|
if minPrice < itemPrice {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mapProductMinPrice[*v.ProductId] = itemPrice
|
||||||
|
}
|
||||||
|
//获取产品列表
|
||||||
|
productList, err := l.svcCtx.AllModels.FsProduct.GetProductListByIdsWithoutStatus(l.ctx, productIds, "")
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product list")
|
||||||
|
}
|
||||||
|
mapProduct := make(map[int64]int)
|
||||||
|
resourceIds := make([]string, 0, len(productList))
|
||||||
|
for k, v := range productList {
|
||||||
|
mapProduct[v.Id] = k
|
||||||
|
resourceIds = append(resourceIds, s3url_to_s3id.GetS3ResourceIdFormUrl(*v.Cover))
|
||||||
|
}
|
||||||
|
sizeCounts, err := l.svcCtx.AllModels.FsProductSize.GetGroupProductSizeByStatus(l.ctx, productIds, 1)
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product size count")
|
||||||
|
}
|
||||||
|
mapProductSizeCount := make(map[int64]int64)
|
||||||
|
for _, v := range sizeCounts {
|
||||||
|
mapProductSizeCount[v.ProductId] = v.Num
|
||||||
|
}
|
||||||
|
//获取资源列表
|
||||||
|
resourceList, err := l.svcCtx.AllModels.FsResource.FindAllByResourceIds(l.ctx, resourceIds)
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get resource list")
|
||||||
|
}
|
||||||
|
mapResourceMetadata := make(map[string]interface{})
|
||||||
|
for _, v := range resourceList {
|
||||||
|
var metadata interface{}
|
||||||
|
if err = json.Unmarshal(*v.Metadata, &metadata); err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusAddMessage(basic.CodeJsonErr, fmt.Sprintf("failed to parse resource metadata:%s", v.ResourceId))
|
||||||
|
}
|
||||||
|
mapResourceMetadata[*v.ResourceUrl] = metadata
|
||||||
|
}
|
||||||
|
listRsp := make([]types.GetCollectProductListRspItem, 0, len(collectionList))
|
||||||
|
for _, collection := range collectionList {
|
||||||
|
productName := ""
|
||||||
|
cover := ""
|
||||||
|
isShelf := int64(0)
|
||||||
|
isDeleted := int64(0)
|
||||||
|
var coverMetadata interface{}
|
||||||
|
if productIndex, ok := mapProduct[*collection.ProductId]; ok {
|
||||||
|
productName = *productList[productIndex].Title
|
||||||
|
cover = *productList[productIndex].Cover
|
||||||
|
isShelf = *productList[productIndex].IsShelf
|
||||||
|
isDeleted = *productList[productIndex].IsDel
|
||||||
|
if metadata, ok := mapResourceMetadata[cover]; ok {
|
||||||
|
coverMetadata = metadata
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sizeCount := int64(0)
|
||||||
|
if count, ok := mapProductSizeCount[*collection.ProductId]; ok {
|
||||||
|
sizeCount = count
|
||||||
|
}
|
||||||
|
minPrice := ""
|
||||||
|
if price, ok := mapProductMinPrice[*collection.ProductId]; ok {
|
||||||
|
minPrice = format.CentitoDollar(price, 3)
|
||||||
|
}
|
||||||
|
listRsp = append(listRsp, types.GetCollectProductListRspItem{
|
||||||
|
Id: collection.Id,
|
||||||
|
ProductId: *collection.ProductId,
|
||||||
|
ProductName: productName,
|
||||||
|
Logo: *collection.Logo,
|
||||||
|
Cover: cover,
|
||||||
|
CoverMetadata: coverMetadata,
|
||||||
|
SelectColorIndex: *collection.SelectColorIndex,
|
||||||
|
TemplateTag: *collection.TemplateTag,
|
||||||
|
SizeCount: sizeCount,
|
||||||
|
MinPrice: minPrice,
|
||||||
|
IsShelf: isShelf,
|
||||||
|
IsDeleted: isDeleted,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeOK, "success", types.GetCollectProductListRsp{
|
||||||
|
Meta: types.Meta{
|
||||||
|
TotalCount: total,
|
||||||
|
PageCount: int64(math.Ceil(float64(total) / float64(limit))),
|
||||||
|
CurrentPage: req.CurrentPage,
|
||||||
|
PerPage: limit,
|
||||||
|
},
|
||||||
|
List: listRsp,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
// func (l *GetCollectProductListLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||||
|
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
// }
|
||||||
107
server/collection/internal/logic/testailogic.go
Normal file
107
server/collection/internal/logic/testailogic.go
Normal file
File diff suppressed because one or more lines are too long
50
server/collection/internal/logic/testpdflogic.go
Normal file
50
server/collection/internal/logic/testpdflogic.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package logic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fusenapi/server/collection/internal/svc"
|
||||||
|
"fusenapi/server/collection/internal/types"
|
||||||
|
"fusenapi/utils/auth"
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
"fusenapi/utils/pdf"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TestPdfLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTestPdfLogic(ctx context.Context, svcCtx *svc.ServiceContext) *TestPdfLogic {
|
||||||
|
return &TestPdfLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理进入前逻辑w,r
|
||||||
|
// func (l *TestPdfLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (l *TestPdfLogic) TestPdf(req *types.TestPdfReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeOK, "你干嘛,哎哟")
|
||||||
|
switch req.Type {
|
||||||
|
case "url":
|
||||||
|
case "html":
|
||||||
|
default:
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "invalid type")
|
||||||
|
}
|
||||||
|
res, err := pdf.HtmlToPdfBase64(req.Content, req.Type)
|
||||||
|
if err != nil {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeServiceErr, err.Error())
|
||||||
|
}
|
||||||
|
return resp.SetStatus(basic.CodeOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
// func (l *TestPdfLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||||
|
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
// }
|
||||||
26
server/collection/internal/svc/servicecontext.go
Normal file
26
server/collection/internal/svc/servicecontext.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package svc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fusenapi/initalize"
|
||||||
|
"fusenapi/model/gmodel"
|
||||||
|
"fusenapi/server/collection/internal/config"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ServiceContext struct {
|
||||||
|
Config config.Config
|
||||||
|
MysqlConn *gorm.DB
|
||||||
|
AllModels *gmodel.AllModelsGen
|
||||||
|
RabbitMq *initalize.RabbitMqHandle
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
|
conn := initalize.InitMysql(c.SourceMysql)
|
||||||
|
|
||||||
|
return &ServiceContext{
|
||||||
|
Config: c,
|
||||||
|
MysqlConn: conn,
|
||||||
|
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
||||||
|
RabbitMq: initalize.InitRabbitMq(c.SourceRabbitMq, nil),
|
||||||
|
}
|
||||||
|
}
|
||||||
119
server/collection/internal/types/types.go
Normal file
119
server/collection/internal/types/types.go
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CollectProductReq struct {
|
||||||
|
ProductId int64 `json:"product_id"`
|
||||||
|
Logo string `json:"logo"`
|
||||||
|
SelectColorIndex int64 `json:"select_color_index"`
|
||||||
|
TemplateTag string `json:"template_tag"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteCollectProductReq struct {
|
||||||
|
Ids []int64 `json:"ids"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetCollectProductListReq struct {
|
||||||
|
CurrentPage int `form:"current_page"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetCollectProductListRsp struct {
|
||||||
|
Meta Meta `json:"meta"` //分页信息
|
||||||
|
List []GetCollectProductListRspItem `json:"list"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetCollectProductListRspItem struct {
|
||||||
|
Id int64 `json:"id"`
|
||||||
|
ProductId int64 `json:"product_id"`
|
||||||
|
ProductName string `json:"product_name"`
|
||||||
|
Logo string `json:"logo"`
|
||||||
|
Cover string `json:"cover"`
|
||||||
|
CoverMetadata interface{} `json:"coverMetadata"`
|
||||||
|
SelectColorIndex int64 `json:"select_color_index"`
|
||||||
|
TemplateTag string `json:"template_tag"`
|
||||||
|
SizeCount int64 `json:"size_count"`
|
||||||
|
MinPrice string `json:"min_price"`
|
||||||
|
IsShelf int64 `json:"is_shelf"`
|
||||||
|
IsDeleted int64 `json:"is_deleted"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TestAiReq struct {
|
||||||
|
Num int `form:"num"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TestPdfReq struct {
|
||||||
|
Content string `json:"content"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Request struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type Response struct {
|
||||||
|
Code int `json:"code"`
|
||||||
|
Message string `json:"msg"`
|
||||||
|
Data interface{} `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Auth struct {
|
||||||
|
AccessSecret string `json:"accessSecret"`
|
||||||
|
AccessExpire int64 `json:"accessExpire"`
|
||||||
|
RefreshAfter int64 `json:"refreshAfter"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type File struct {
|
||||||
|
Filename string `fsfile:"filename"`
|
||||||
|
Header map[string][]string `fsfile:"header"`
|
||||||
|
Size int64 `fsfile:"size"`
|
||||||
|
Data []byte `fsfile:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Meta struct {
|
||||||
|
TotalCount int64 `json:"total_count"`
|
||||||
|
PageCount int64 `json:"page_count"`
|
||||||
|
CurrentPage int `json:"current_page"`
|
||||||
|
PerPage int `json:"per_page"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set 设置Response的Code和Message值
|
||||||
|
func (resp *Response) Set(Code int, Message string) *Response {
|
||||||
|
return &Response{
|
||||||
|
Code: Code,
|
||||||
|
Message: Message,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set 设置整个Response
|
||||||
|
func (resp *Response) SetWithData(Code int, Message string, Data interface{}) *Response {
|
||||||
|
return &Response{
|
||||||
|
Code: Code,
|
||||||
|
Message: Message,
|
||||||
|
Data: Data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetStatus 设置默认StatusResponse(内部自定义) 默认msg, 可以带data, data只使用一个参数
|
||||||
|
func (resp *Response) SetStatus(sr *basic.StatusResponse, data ...interface{}) *Response {
|
||||||
|
newResp := &Response{
|
||||||
|
Code: sr.Code,
|
||||||
|
}
|
||||||
|
if len(data) == 1 {
|
||||||
|
newResp.Data = data[0]
|
||||||
|
}
|
||||||
|
return newResp
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetStatusWithMessage 设置默认StatusResponse(内部自定义) 非默认msg, 可以带data, data只使用一个参数
|
||||||
|
func (resp *Response) SetStatusWithMessage(sr *basic.StatusResponse, msg string, data ...interface{}) *Response {
|
||||||
|
newResp := &Response{
|
||||||
|
Code: sr.Code,
|
||||||
|
Message: msg,
|
||||||
|
}
|
||||||
|
if len(data) == 1 {
|
||||||
|
newResp.Data = data[0]
|
||||||
|
}
|
||||||
|
return newResp
|
||||||
|
}
|
||||||
1
server/data-transfer/.gitignore
vendored
1
server/data-transfer/.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
data-transfer
|
data-transfer
|
||||||
|
main
|
||||||
|
|||||||
@ -2,5 +2,7 @@ FROM alpine
|
|||||||
|
|
||||||
WORKDIR /www/fusenapi/
|
WORKDIR /www/fusenapi/
|
||||||
COPY ./bin/api-data-transfer-srv /www/fusenapi/
|
COPY ./bin/api-data-transfer-srv /www/fusenapi/
|
||||||
COPY ./etc /www/fusenapi/etc
|
COPY ./env.yaml /opt/
|
||||||
|
COPY ./server.fusen.3718.cn.pem /opt/
|
||||||
|
COPY ./server.fusen.3718.cn.key /opt/
|
||||||
CMD ["/www/fusenapi/api-data-transfer-srv"]
|
CMD ["/www/fusenapi/api-data-transfer-srv"]
|
||||||
|
|||||||
1
server/home-user-auth/.gitignore
vendored
1
server/home-user-auth/.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
home-user-auth
|
home-user-auth
|
||||||
|
main
|
||||||
|
|||||||
@ -2,5 +2,7 @@ FROM alpine
|
|||||||
|
|
||||||
WORKDIR /www/fusenapi/
|
WORKDIR /www/fusenapi/
|
||||||
COPY ./bin/api-home-user-auth-srv /www/fusenapi/
|
COPY ./bin/api-home-user-auth-srv /www/fusenapi/
|
||||||
COPY ./etc /www/fusenapi/etc
|
COPY ./env.yaml /opt/
|
||||||
|
COPY ./server.fusen.3718.cn.pem /opt/
|
||||||
|
COPY ./server.fusen.3718.cn.key /opt/
|
||||||
CMD ["/www/fusenapi/api-home-user-auth-srv"]
|
CMD ["/www/fusenapi/api-home-user-auth-srv"]
|
||||||
|
|||||||
@ -36,9 +36,7 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
BLMService struct {
|
BLMService struct {
|
||||||
Url string
|
Version string
|
||||||
LogoCombine struct {
|
Urls []string
|
||||||
Url string
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,36 +17,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
Path: "/api/user/fonts",
|
Path: "/api/user/fonts",
|
||||||
Handler: UserFontsHandler(serverCtx),
|
Handler: UserFontsHandler(serverCtx),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Method: http.MethodGet,
|
|
||||||
Path: "/api/user/get-type",
|
|
||||||
Handler: UserGetTypeHandler(serverCtx),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Method: http.MethodPost,
|
|
||||||
Path: "/api/user/basic-info",
|
|
||||||
Handler: UserSaveBasicInfoHandler(serverCtx),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
Method: http.MethodGet,
|
Method: http.MethodGet,
|
||||||
Path: "/api/user/status-config",
|
Path: "/api/user/status-config",
|
||||||
Handler: UserStatusConfigHandler(serverCtx),
|
Handler: UserStatusConfigHandler(serverCtx),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Method: http.MethodGet,
|
|
||||||
Path: "/api/user/basic-info",
|
|
||||||
Handler: UserBasicInfoHandler(serverCtx),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Method: http.MethodGet,
|
|
||||||
Path: "/api/user/address-list",
|
|
||||||
Handler: UserAddressListHandler(serverCtx),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Method: http.MethodPost,
|
|
||||||
Path: "/api/user/add-address",
|
|
||||||
Handler: UserAddAddressHandler(serverCtx),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
Method: http.MethodPost,
|
Method: http.MethodPost,
|
||||||
Path: "/api/user/contact-service",
|
Path: "/api/user/contact-service",
|
||||||
|
|||||||
@ -1,35 +0,0 @@
|
|||||||
package handler
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"reflect"
|
|
||||||
|
|
||||||
"fusenapi/utils/basic"
|
|
||||||
|
|
||||||
"fusenapi/server/home-user-auth/internal/logic"
|
|
||||||
"fusenapi/server/home-user-auth/internal/svc"
|
|
||||||
"fusenapi/server/home-user-auth/internal/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
func UserAddressListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
|
|
||||||
var req types.Request
|
|
||||||
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建一个业务逻辑层实例
|
|
||||||
l := logic.NewUserAddressListLogic(r.Context(), svcCtx)
|
|
||||||
|
|
||||||
rl := reflect.ValueOf(l)
|
|
||||||
basic.BeforeLogic(w, r, rl)
|
|
||||||
|
|
||||||
resp := l.UserAddressList(&req, userinfo)
|
|
||||||
|
|
||||||
if !basic.AfterLogic(w, r, rl, resp) {
|
|
||||||
basic.NormalAfterLogic(w, r, resp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,98 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fusenapi/model/gmodel"
|
|
||||||
"fusenapi/utils/auth"
|
|
||||||
"fusenapi/utils/basic"
|
|
||||||
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"fusenapi/server/home-user-auth/internal/svc"
|
|
||||||
"fusenapi/server/home-user-auth/internal/types"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UserAddAddressLogic struct {
|
|
||||||
logx.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewUserAddAddressLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserAddAddressLogic {
|
|
||||||
return &UserAddAddressLogic{
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *UserAddAddressLogic) UserAddAddress(req *types.RequestAddAddress, userinfo *auth.UserInfo) (resp *basic.Response) {
|
|
||||||
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
|
||||||
// userinfo 传入值时, 一定不为null
|
|
||||||
if !userinfo.IsUser() {
|
|
||||||
return resp.SetStatus(basic.CodeUnAuth) // 如果不是用户信息, 返回未授权错误
|
|
||||||
}
|
|
||||||
|
|
||||||
// 确认这个IsDefault的值范围
|
|
||||||
if !auth.CheckValueRange(req.IsDefault, 0, 1) {
|
|
||||||
return resp.SetStatus(basic.CodeSafeValueRangeErr) // IsDefault值超出范围, 返回安全值范围错误
|
|
||||||
}
|
|
||||||
|
|
||||||
m := l.svcCtx.AllModels.FsAddress // 创建地址模型
|
|
||||||
var status int64 = 1 // 默认地址状态为1(正常)
|
|
||||||
|
|
||||||
// 如果ID为0, 表示新增地址
|
|
||||||
if req.Id == 0 {
|
|
||||||
var (
|
|
||||||
country string = "USA" // 国家默认为美国
|
|
||||||
isDefautl int64 = 1 // 默认地址为1
|
|
||||||
)
|
|
||||||
createOne := &gmodel.FsAddress{ // 构建FsAddress结构体
|
|
||||||
AddressName: &req.Name,
|
|
||||||
FirstName: &req.FirstName,
|
|
||||||
LastName: &req.LastName,
|
|
||||||
Mobile: &req.Mobile,
|
|
||||||
Street: &req.Street,
|
|
||||||
Suite: &req.Suite,
|
|
||||||
City: &req.City,
|
|
||||||
State: &req.State,
|
|
||||||
Country: &country,
|
|
||||||
Status: &status,
|
|
||||||
UserId: &userinfo.UserId,
|
|
||||||
ZipCode: &req.ZipCode,
|
|
||||||
IsDefault: &isDefautl,
|
|
||||||
}
|
|
||||||
created, err := m.CreateOne(l.ctx, createOne) // 新增地址
|
|
||||||
if err != nil {
|
|
||||||
logx.Error(err) // 日志记录错误
|
|
||||||
return resp.SetStatus(basic.CodeDbCreateErr) // 返回数据库创建错误
|
|
||||||
}
|
|
||||||
return resp.SetStatus(basic.CodeOK, map[string]int64{"id": created.AddressId}) // 返回成功并返回地址ID
|
|
||||||
}
|
|
||||||
|
|
||||||
address := &gmodel.FsAddress{
|
|
||||||
AddressId: req.Id,
|
|
||||||
AddressName: &req.Name,
|
|
||||||
FirstName: &req.FirstName,
|
|
||||||
LastName: &req.LastName,
|
|
||||||
Mobile: &req.Mobile,
|
|
||||||
Street: &req.Street,
|
|
||||||
Suite: &req.Suite,
|
|
||||||
City: &req.City,
|
|
||||||
State: &req.State,
|
|
||||||
Status: &status,
|
|
||||||
UserId: &userinfo.UserId,
|
|
||||||
ZipCode: &req.ZipCode,
|
|
||||||
IsDefault: &req.IsDefault,
|
|
||||||
}
|
|
||||||
|
|
||||||
// 插入数据库 更新地址
|
|
||||||
err := m.UpdateAddress(l.ctx, address)
|
|
||||||
if err != nil {
|
|
||||||
logx.Error(err)
|
|
||||||
return resp.SetStatus(basic.CodeDbUpdateErr)
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp.SetStatus(basic.CodeOK, map[string]int64{"id": address.AddressId})
|
|
||||||
}
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"fusenapi/server/home-user-auth/internal/svc"
|
|
||||||
"fusenapi/server/home-user-auth/internal/types"
|
|
||||||
"fusenapi/utils/auth"
|
|
||||||
"fusenapi/utils/basic"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UserAddressListLogic struct {
|
|
||||||
logx.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewUserAddressListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserAddressListLogic {
|
|
||||||
return &UserAddressListLogic{
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *UserAddressListLogic) UserAddressList(req *types.Request, userinfo *auth.UserInfo) (resp *basic.Response) {
|
|
||||||
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
|
||||||
if !userinfo.IsUser() {
|
|
||||||
return resp.SetStatus(basic.CodeUnAuth)
|
|
||||||
}
|
|
||||||
|
|
||||||
m := l.svcCtx.AllModels.FsAddress
|
|
||||||
|
|
||||||
data, err := m.GetUserAllAddress(l.ctx, userinfo.UserId)
|
|
||||||
if err != nil {
|
|
||||||
logx.Error(err)
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, err.Error())
|
|
||||||
}
|
|
||||||
return resp.SetStatus(basic.CodeOK, data)
|
|
||||||
}
|
|
||||||
@ -62,6 +62,7 @@ func (l *UserLogoSetLogic) UserLogoSet(req *types.UserLogoSetReq, userinfo *auth
|
|||||||
ResourceId: defaultMaterialInfo.ResourceId,
|
ResourceId: defaultMaterialInfo.ResourceId,
|
||||||
ResourceUrl: defaultMaterialInfo.ResourceUrl,
|
ResourceUrl: defaultMaterialInfo.ResourceUrl,
|
||||||
Ctime: &nowTime,
|
Ctime: &nowTime,
|
||||||
|
Metadata: defaultMaterialInfo.Metadata,
|
||||||
}
|
}
|
||||||
MaterialCreateRes := l.svcCtx.MysqlConn.Create(&defaultMaterial)
|
MaterialCreateRes := l.svcCtx.MysqlConn.Create(&defaultMaterial)
|
||||||
err = MaterialCreateRes.Error
|
err = MaterialCreateRes.Error
|
||||||
|
|||||||
@ -39,7 +39,7 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
|||||||
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
||||||
Repositories: initalize.NewAllRepositories(&initalize.NewAllRepositorieData{
|
Repositories: initalize.NewAllRepositories(&initalize.NewAllRepositorieData{
|
||||||
GormDB: initalize.InitMysql(c.SourceMysql),
|
GormDB: initalize.InitMysql(c.SourceMysql),
|
||||||
BLMServiceUrl: &c.BLMService.Url,
|
BLMServiceUrls: c.BLMService.Urls,
|
||||||
AwsSession: session.Must(session.NewSession(&config)),
|
AwsSession: session.Must(session.NewSession(&config)),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
|||||||
1
server/info/.gitignore
vendored
1
server/info/.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
info
|
info
|
||||||
|
main
|
||||||
|
|||||||
8
server/info/Dockerfile
Executable file
8
server/info/Dockerfile
Executable file
@ -0,0 +1,8 @@
|
|||||||
|
FROM alpine
|
||||||
|
|
||||||
|
WORKDIR /www/fusenapi/
|
||||||
|
COPY ./bin/api-info-srv /www/fusenapi/
|
||||||
|
COPY ./env.yaml /opt/
|
||||||
|
COPY ./server.fusen.3718.cn.pem /opt/
|
||||||
|
COPY ./server.fusen.3718.cn.key /opt/
|
||||||
|
CMD ["/www/fusenapi/api-info-srv"]
|
||||||
@ -14,7 +14,7 @@ import (
|
|||||||
func AddressDefaultHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
func AddressDefaultHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
var req types.AddressIdRequest
|
var req types.AddressDefaultRequest
|
||||||
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
|||||||
35
server/info/internal/handler/addressusedupdatehandler.go
Normal file
35
server/info/internal/handler/addressusedupdatehandler.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
|
"fusenapi/server/info/internal/logic"
|
||||||
|
"fusenapi/server/info/internal/svc"
|
||||||
|
"fusenapi/server/info/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AddressUsedUpdateHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
var req types.AddressIdRequest
|
||||||
|
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建一个业务逻辑层实例
|
||||||
|
l := logic.NewAddressUsedUpdateLogic(r.Context(), svcCtx)
|
||||||
|
|
||||||
|
rl := reflect.ValueOf(l)
|
||||||
|
basic.BeforeLogic(w, r, rl)
|
||||||
|
|
||||||
|
resp := l.AddressUsedUpdate(&req, userinfo)
|
||||||
|
|
||||||
|
if !basic.AfterLogic(w, r, rl, resp) {
|
||||||
|
basic.NormalAfterLogic(w, r, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
35
server/info/internal/handler/contactushandler.go
Normal file
35
server/info/internal/handler/contactushandler.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
|
"fusenapi/server/info/internal/logic"
|
||||||
|
"fusenapi/server/info/internal/svc"
|
||||||
|
"fusenapi/server/info/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ContactUsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
var req types.ContactUsRequest
|
||||||
|
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建一个业务逻辑层实例
|
||||||
|
l := logic.NewContactUsLogic(r.Context(), svcCtx)
|
||||||
|
|
||||||
|
rl := reflect.ValueOf(l)
|
||||||
|
basic.BeforeLogic(w, r, rl)
|
||||||
|
|
||||||
|
resp := l.ContactUs(&req, userinfo)
|
||||||
|
|
||||||
|
if !basic.AfterLogic(w, r, rl, resp) {
|
||||||
|
basic.NormalAfterLogic(w, r, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,12 +6,12 @@ import (
|
|||||||
|
|
||||||
"fusenapi/utils/basic"
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
"fusenapi/server/product/internal/logic"
|
"fusenapi/server/info/internal/logic"
|
||||||
"fusenapi/server/product/internal/svc"
|
"fusenapi/server/info/internal/svc"
|
||||||
"fusenapi/server/product/internal/types"
|
"fusenapi/server/info/internal/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetSizeByProductHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
func RestaurantListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
var req types.Request
|
var req types.Request
|
||||||
@ -21,12 +21,12 @@ func GetSizeByProductHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 创建一个业务逻辑层实例
|
// 创建一个业务逻辑层实例
|
||||||
l := logic.NewGetSizeByProductLogic(r.Context(), svcCtx)
|
l := logic.NewRestaurantListLogic(r.Context(), svcCtx)
|
||||||
|
|
||||||
rl := reflect.ValueOf(l)
|
rl := reflect.ValueOf(l)
|
||||||
basic.BeforeLogic(w, r, rl)
|
basic.BeforeLogic(w, r, rl)
|
||||||
|
|
||||||
resp := l.GetSizeByProduct(&req, userinfo)
|
resp := l.RestaurantList(&req, userinfo)
|
||||||
|
|
||||||
if !basic.AfterLogic(w, r, rl, resp) {
|
if !basic.AfterLogic(w, r, rl, resp) {
|
||||||
basic.NormalAfterLogic(w, r, resp)
|
basic.NormalAfterLogic(w, r, resp)
|
||||||
@ -42,6 +42,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
Path: "/api/info/address/update",
|
Path: "/api/info/address/update",
|
||||||
Handler: AddressUpdateHandler(serverCtx),
|
Handler: AddressUpdateHandler(serverCtx),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/api/info/address/update/used",
|
||||||
|
Handler: AddressUsedUpdateHandler(serverCtx),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Method: http.MethodPost,
|
Method: http.MethodPost,
|
||||||
Path: "/api/info/address/delete",
|
Path: "/api/info/address/delete",
|
||||||
@ -52,6 +57,16 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
Path: "/api/info/address/list",
|
Path: "/api/info/address/list",
|
||||||
Handler: AddressListHandler(serverCtx),
|
Handler: AddressListHandler(serverCtx),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: "/api/info/restaurant/list",
|
||||||
|
Handler: RestaurantListHandler(serverCtx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/api/info/contact/us",
|
||||||
|
Handler: ContactUsHandler(serverCtx),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import (
|
|||||||
func UpdateProfileBaseHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
func UpdateProfileBaseHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
var req types.ProfileBaseRequest
|
var req types.ProfileRequest
|
||||||
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
|||||||
@ -50,12 +50,10 @@ func (l *AddressAddLogic) AddressAdd(req *types.AddressRequest, userinfo *auth.U
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
country string = "USA" // 国家默认为美国
|
country string = "USA" // 国家默认为美国
|
||||||
isDefautl int64 = 1 // 默认地址为1
|
|
||||||
status int64 = 1 // 默认地址状态为1(正常)
|
status int64 = 1 // 默认地址状态为1(正常)
|
||||||
)
|
)
|
||||||
|
|
||||||
createOne := &gmodel.FsAddress{ // 构建FsAddress结构体
|
createOne := &gmodel.FsAddress{ // 构建FsAddress结构体
|
||||||
AddressName: &req.AddressName,
|
|
||||||
FirstName: &req.FirstName,
|
FirstName: &req.FirstName,
|
||||||
LastName: &req.LastName,
|
LastName: &req.LastName,
|
||||||
Mobile: &req.Mobile,
|
Mobile: &req.Mobile,
|
||||||
@ -67,14 +65,17 @@ func (l *AddressAddLogic) AddressAdd(req *types.AddressRequest, userinfo *auth.U
|
|||||||
Status: &status,
|
Status: &status,
|
||||||
UserId: &userinfo.UserId,
|
UserId: &userinfo.UserId,
|
||||||
ZipCode: &req.ZipCode,
|
ZipCode: &req.ZipCode,
|
||||||
IsDefault: &isDefautl,
|
|
||||||
}
|
}
|
||||||
_, err := m.CreateOne(l.ctx, createOne) // 新增地址
|
address, err := m.CreateOne(l.ctx, createOne) // 新增地址
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err) // 日志记录错误
|
logx.Error(err) // 日志记录错误
|
||||||
return resp.SetStatus(basic.CodeDbCreateErr) // 返回数据库创建错误
|
return resp.SetStatus(basic.CodeDbCreateErr) // 返回数据库创建错误
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if req.IsDefault > 0 {
|
||||||
|
m.SettingUserDefaultAddress(l.ctx, userinfo.UserId, address.AddressId, req.IsDefault)
|
||||||
|
}
|
||||||
|
|
||||||
addresses, err := m.GetUserAllAddress(l.ctx, userinfo.UserId)
|
addresses, err := m.GetUserAllAddress(l.ctx, userinfo.UserId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
@ -82,6 +83,7 @@ func (l *AddressAddLogic) AddressAdd(req *types.AddressRequest, userinfo *auth.U
|
|||||||
}
|
}
|
||||||
|
|
||||||
return resp.SetStatus(basic.CodeOK, map[string]any{
|
return resp.SetStatus(basic.CodeOK, map[string]any{
|
||||||
|
"address_id": address.AddressId,
|
||||||
"address_list": addresses,
|
"address_list": addresses,
|
||||||
}) // 返回成功并返回地址ID
|
}) // 返回成功并返回地址ID
|
||||||
|
|
||||||
|
|||||||
@ -30,7 +30,7 @@ func NewAddressDefaultLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Ad
|
|||||||
// func (l *AddressDefaultLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
// func (l *AddressDefaultLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
func (l *AddressDefaultLogic) AddressDefault(req *types.AddressIdRequest, userinfo *auth.UserInfo) (resp *basic.Response) {
|
func (l *AddressDefaultLogic) AddressDefault(req *types.AddressDefaultRequest, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
// userinfo 传入值时, 一定不为null
|
// userinfo 传入值时, 一定不为null
|
||||||
|
|
||||||
@ -38,12 +38,26 @@ func (l *AddressDefaultLogic) AddressDefault(req *types.AddressIdRequest, userin
|
|||||||
return resp.SetStatus(basic.CodeUnAuth)
|
return resp.SetStatus(basic.CodeUnAuth)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := l.svcCtx.AllModels.FsAddress.SettingUserDefaultAddress(l.ctx, userinfo.UserId, req.AddressId)
|
// 确认这个IsDefault的值范围
|
||||||
|
if !auth.CheckValueRange(req.IsDefault, 0, 1) {
|
||||||
|
return resp.SetStatus(basic.CodeSafeValueRangeErr) // IsDefault值超出范围, 返回安全值范围错误
|
||||||
|
}
|
||||||
|
|
||||||
|
err := l.svcCtx.AllModels.FsAddress.SettingUserDefaultAddress(l.ctx, userinfo.UserId, req.AddressId, req.IsDefault)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return resp.SetStatusWithMessage(basic.CodeApiErr, err.Error())
|
return resp.SetStatusWithMessage(basic.CodeApiErr, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp.SetStatus(basic.CodeOK)
|
addresses, err := l.svcCtx.AllModels.FsAddress.GetUserAllAddress(l.ctx, userinfo.UserId)
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatus(basic.CodeDbSqlErr) // 返回数据库创建错误
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.SetStatus(basic.CodeOK, map[string]any{
|
||||||
|
"address_id": req.AddressId,
|
||||||
|
"address_list": addresses,
|
||||||
|
}) // 返回成功并返回地址ID
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
|||||||
@ -43,7 +43,9 @@ func (l *AddressDeleteLogic) AddressDelete(req *types.AddressIdRequest, userinfo
|
|||||||
return resp.SetStatusWithMessage(basic.CodeApiErr, err.Error())
|
return resp.SetStatusWithMessage(basic.CodeApiErr, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp.SetStatus(basic.CodeOK)
|
return resp.SetStatus(basic.CodeOK, map[string]any{
|
||||||
|
"address_id": req.AddressId,
|
||||||
|
}) // 返回成功并返回地址ID
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
|||||||
@ -40,6 +40,11 @@ func (l *AddressUpdateLogic) AddressUpdate(req *types.AddressRequest, userinfo *
|
|||||||
return resp.SetStatus(basic.CodeUnAuth)
|
return resp.SetStatus(basic.CodeUnAuth)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 确认这个IsDefault的值范围
|
||||||
|
if !auth.CheckValueRange(req.IsDefault, 0, 1) {
|
||||||
|
return resp.SetStatus(basic.CodeSafeValueRangeErr) // IsDefault值超出范围, 返回安全值范围错误
|
||||||
|
}
|
||||||
|
|
||||||
now := time.Now().UTC()
|
now := time.Now().UTC()
|
||||||
|
|
||||||
if req.AddressId == 0 {
|
if req.AddressId == 0 {
|
||||||
@ -49,8 +54,6 @@ func (l *AddressUpdateLogic) AddressUpdate(req *types.AddressRequest, userinfo *
|
|||||||
address := gmodel.FsAddress{
|
address := gmodel.FsAddress{
|
||||||
AddressId: req.AddressId,
|
AddressId: req.AddressId,
|
||||||
UserId: &userinfo.UserId,
|
UserId: &userinfo.UserId,
|
||||||
IsDefault: &req.IsDefault,
|
|
||||||
AddressName: &req.AddressName,
|
|
||||||
FirstName: &req.FirstName,
|
FirstName: &req.FirstName,
|
||||||
LastName: &req.LastName,
|
LastName: &req.LastName,
|
||||||
Mobile: &req.Mobile,
|
Mobile: &req.Mobile,
|
||||||
@ -67,7 +70,19 @@ func (l *AddressUpdateLogic) AddressUpdate(req *types.AddressRequest, userinfo *
|
|||||||
return resp.SetStatusWithMessage(basic.CodeApiErr, err.Error())
|
return resp.SetStatusWithMessage(basic.CodeApiErr, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp.SetStatus(basic.CodeOK)
|
l.svcCtx.AllModels.FsAddress.SettingUserDefaultAddress(l.ctx, userinfo.UserId, address.AddressId, req.IsDefault)
|
||||||
|
|
||||||
|
addresses, err := l.svcCtx.AllModels.FsAddress.GetUserAllAddress(l.ctx, userinfo.UserId)
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatus(basic.CodeDbSqlErr) // 返回数据库创建错误
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.SetStatus(basic.CodeOK, map[string]any{
|
||||||
|
"address_id": req.AddressId,
|
||||||
|
"address_list": addresses,
|
||||||
|
}) // 返回成功并返回地址ID
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
|||||||
54
server/info/internal/logic/addressusedupdatelogic.go
Normal file
54
server/info/internal/logic/addressusedupdatelogic.go
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package logic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fusenapi/utils/auth"
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"fusenapi/server/info/internal/svc"
|
||||||
|
"fusenapi/server/info/internal/types"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AddressUsedUpdateLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAddressUsedUpdateLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddressUsedUpdateLogic {
|
||||||
|
return &AddressUsedUpdateLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理进入前逻辑w,r
|
||||||
|
// func (l *AddressUsedUpdateLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (l *AddressUsedUpdateLogic) AddressUsedUpdate(req *types.AddressIdRequest, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
|
// userinfo 传入值时, 一定不为null
|
||||||
|
if !userinfo.IsUser() {
|
||||||
|
return resp.SetStatus(basic.CodeUnAuth)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := l.svcCtx.AllModels.FsAddress.UpdateUsedAddress(l.ctx, req.AddressId, userinfo.UserId)
|
||||||
|
if err != nil {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeApiErr, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.SetStatus(basic.CodeOK, map[string]any{
|
||||||
|
"address_id": req.AddressId,
|
||||||
|
}) // 返回成功并返回地址ID
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
// func (l *AddressUsedUpdateLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||||
|
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
// }
|
||||||
66
server/info/internal/logic/contactuslogic.go
Normal file
66
server/info/internal/logic/contactuslogic.go
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
package logic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fusenapi/model/gmodel"
|
||||||
|
"fusenapi/utils/auth"
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"fusenapi/server/info/internal/svc"
|
||||||
|
"fusenapi/server/info/internal/types"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ContactUsLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewContactUsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ContactUsLogic {
|
||||||
|
return &ContactUsLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理进入前逻辑w,r
|
||||||
|
// func (l *ContactUsLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (l *ContactUsLogic) ContactUs(req *types.ContactUsRequest, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
|
// userinfo 传入值时, 一定不为null
|
||||||
|
|
||||||
|
if !auth.ValidateEmail(req.Email) {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "email format error")
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.Message == "" {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "remarks must exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now().UTC()
|
||||||
|
err := l.svcCtx.AllModels.FsContact.Save(l.ctx, &gmodel.FsContact{
|
||||||
|
Name: &req.Name,
|
||||||
|
Email: &req.Email,
|
||||||
|
Phone: &req.Phone,
|
||||||
|
Message: &req.Message,
|
||||||
|
Status: gmodel.FsInt64(0),
|
||||||
|
Ctime: &now,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.SetStatus(basic.CodeOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
// func (l *ContactUsLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||||
|
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
// }
|
||||||
71
server/info/internal/logic/restaurantlistlogic.go
Normal file
71
server/info/internal/logic/restaurantlistlogic.go
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package logic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fusenapi/utils/auth"
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"fusenapi/server/info/internal/svc"
|
||||||
|
"fusenapi/server/info/internal/types"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RestaurantListLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRestaurantListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RestaurantListLogic {
|
||||||
|
return &RestaurantListLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理进入前逻辑w,r
|
||||||
|
// func (l *RestaurantListLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (l *RestaurantListLogic) RestaurantList(req *types.Request, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
|
// userinfo 传入值时, 一定不为null
|
||||||
|
|
||||||
|
values := []string{
|
||||||
|
"Pizza Shop",
|
||||||
|
"Coffee Shop",
|
||||||
|
"Salad Shop",
|
||||||
|
"Other Non-Asian Restaurants",
|
||||||
|
"Fried Chicken / Burger / Sandwich Restaurant",
|
||||||
|
"Other Restaurants",
|
||||||
|
"Bakery / Dessert Shop",
|
||||||
|
"Ramen /Vietnamese / Thai / Korean / Chinese",
|
||||||
|
"Breakfast & Brunch",
|
||||||
|
"Moxican",
|
||||||
|
"Pho",
|
||||||
|
"Ramen",
|
||||||
|
"Chinese",
|
||||||
|
"Burgers",
|
||||||
|
"Sushi Restaurant",
|
||||||
|
"Indian",
|
||||||
|
"Vegan",
|
||||||
|
"Smoothie",
|
||||||
|
"Healthy",
|
||||||
|
"Soup",
|
||||||
|
"Italian",
|
||||||
|
"Boba Tea Shop",
|
||||||
|
"Other",
|
||||||
|
"Korean / Thai",
|
||||||
|
"Bar",
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.SetStatus(basic.CodeOK, values)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
// func (l *RestaurantListLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||||
|
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
// }
|
||||||
@ -30,13 +30,15 @@ func NewUpdateProfileBaseLogic(ctx context.Context, svcCtx *svc.ServiceContext)
|
|||||||
// func (l *UpdateProfileBaseLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
// func (l *UpdateProfileBaseLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
func (l *UpdateProfileBaseLogic) UpdateProfileBase(req *types.ProfileBaseRequest, userinfo *auth.UserInfo) (resp *basic.Response) {
|
func (l *UpdateProfileBaseLogic) UpdateProfileBase(req *types.ProfileRequest, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
// userinfo 传入值时, 一定不为null
|
// userinfo 传入值时, 一定不为null
|
||||||
if !userinfo.IsUser() {
|
if !userinfo.IsUser() {
|
||||||
return resp.SetStatus(basic.CodeUnAuth)
|
return resp.SetStatus(basic.CodeUnAuth)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
req.ProfileBase.Email = nil
|
||||||
|
|
||||||
err := l.svcCtx.AllModels.FsUserInfo.MergeMetadata(userinfo.UserId, req)
|
err := l.svcCtx.AllModels.FsUserInfo.MergeMetadata(userinfo.UserId, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err) // 日志记录错误
|
logx.Error(err) // 日志记录错误
|
||||||
|
|||||||
@ -5,6 +5,13 @@ import (
|
|||||||
"fusenapi/utils/basic"
|
"fusenapi/utils/basic"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ContactUsRequest struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
Phone string `json:"phone"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
type UserInfoRequest struct {
|
type UserInfoRequest struct {
|
||||||
Module []string `json:"module"`
|
Module []string `json:"module"`
|
||||||
}
|
}
|
||||||
@ -18,14 +25,14 @@ type AddressIdRequest struct {
|
|||||||
AddressId int64 `json:"address_id"` // 地址id
|
AddressId int64 `json:"address_id"` // 地址id
|
||||||
}
|
}
|
||||||
|
|
||||||
type AddressNameRequest struct {
|
type AddressDefaultRequest struct {
|
||||||
AddressName string `json:"address_name"` // 地址
|
AddressId int64 `json:"address_id"` // 地址id
|
||||||
|
IsDefault int64 `json:"is_default"` // 是否默认
|
||||||
}
|
}
|
||||||
|
|
||||||
type AddressRequest struct {
|
type AddressRequest struct {
|
||||||
AddressId int64 `json:"address_id,optional"`
|
AddressId int64 `json:"address_id,optional"`
|
||||||
IsDefault int64 `json:"is_default"` //是否默认
|
IsDefault int64 `json:"is_default"` //是否默认
|
||||||
AddressName string `json:"address_name"` //收货人
|
|
||||||
FirstName string `json:"first_name"` //first_name
|
FirstName string `json:"first_name"` //first_name
|
||||||
LastName string `json:"last_name"` //last_name
|
LastName string `json:"last_name"` //last_name
|
||||||
Mobile string `json:"mobile"` //手机
|
Mobile string `json:"mobile"` //手机
|
||||||
@ -36,15 +43,35 @@ type AddressRequest struct {
|
|||||||
State string `json:"state"` //州
|
State string `json:"state"` //州
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProfileBaseRequest struct {
|
type ProfileRequest struct {
|
||||||
|
ProfileBase *ProfileBase `json:"base,optional,omitempty"` // 基础的个人消息, 姓名 公司等
|
||||||
|
SubscriptionStatus *SubscriptionStatus `json:"sub_status,optional,omitempty"` // 订阅的通知状态
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProfileBase struct {
|
||||||
FirstName *string `json:"first_name,optional,omitempty"` // 首名
|
FirstName *string `json:"first_name,optional,omitempty"` // 首名
|
||||||
LastName *string `json:"last_name,optional,omitempty"` // 后名
|
LastName *string `json:"last_name,optional,omitempty"` // 后名
|
||||||
UserName *string `json:"user_name,optional,omitempty"` // 用户名
|
Email *string `json:"email,optional,omitempty"` // email
|
||||||
Mobile *string `json:"mobile,optional,omitempty"` // 电话
|
Mobile *string `json:"mobile,optional,omitempty"` // 电话
|
||||||
Resetaurant *string `json:"resetaurant,optional,omitempty"` // 不知道干什么
|
Resetaurant *string `json:"resetaurant,optional,omitempty"` // 不知道干什么
|
||||||
Company *string `json:"company,optional,omitempty"` // 公司
|
Company *string `json:"company,optional,omitempty"` // 公司
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SubscriptionStatus struct {
|
||||||
|
NotificationEmail NotificationEmail `json:"notification_email,optional,omitempty"`
|
||||||
|
NotificationPhone NotificationPhone `json:"notification_phone,optional,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type NotificationEmail struct {
|
||||||
|
OrderUpdate bool `json:"order_update,optional,omitempty"`
|
||||||
|
Newseleter bool `json:"newseleter,optional,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type NotificationPhone struct {
|
||||||
|
OrderUpdate bool `json:"order_update,optional,omitempty"`
|
||||||
|
Newseleter bool `json:"newseleter,optional,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
type QueryProfileRequest struct {
|
type QueryProfileRequest struct {
|
||||||
TopKey string `json:"top_key"` // 首名
|
TopKey string `json:"top_key"` // 首名
|
||||||
}
|
}
|
||||||
|
|||||||
1
server/map-library/.gitignore
vendored
1
server/map-library/.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
map-library
|
map-library
|
||||||
|
main
|
||||||
|
|||||||
@ -2,5 +2,7 @@ FROM alpine
|
|||||||
|
|
||||||
WORKDIR /www/fusenapi/
|
WORKDIR /www/fusenapi/
|
||||||
COPY ./bin/api-map-library-srv /www/fusenapi/
|
COPY ./bin/api-map-library-srv /www/fusenapi/
|
||||||
COPY ./etc /www/fusenapi/etc
|
COPY ./env.yaml /opt/
|
||||||
|
COPY ./server.fusen.3718.cn.pem /opt/
|
||||||
|
COPY ./server.fusen.3718.cn.key /opt/
|
||||||
CMD ["/www/fusenapi/api-map-library-srv"]
|
CMD ["/www/fusenapi/api-map-library-srv"]
|
||||||
|
|||||||
1
server/order/.gitignore
vendored
1
server/order/.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
order
|
order
|
||||||
|
main
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user