Compare commits

...

303 Commits

Author SHA1 Message Date
eson
3d67fbbb62 fix 2023-10-16 15:42:19 +08:00
eson
8af873ac42 fix 2023-10-16 15:19:25 +08:00
laodaming
7f88233f28 fix 2023-10-16 15:18:43 +08:00
laodaming
669be27e0a fix 2023-10-16 15:05:03 +08:00
laodaming
57f3270af2 fix 2023-10-16 12:27:39 +08:00
laodaming
b95c2f90d5 fix 2023-10-16 12:04:27 +08:00
laodaming
ce413c494c fix 2023-10-16 11:16:39 +08:00
laodaming
2e421a2968 fix 2023-10-16 10:57:33 +08:00
laodaming
4a620d46d5 fix 2023-10-16 10:04:30 +08:00
laodaming
23b2eded5a fix 2023-10-13 18:17:31 +08:00
laodaming
dbffda69fd fix 2023-10-13 17:44:02 +08:00
laodaming
7b3a16353c fix 2023-10-12 18:33:29 +08:00
laodaming
2c8b8b1aac fix 2023-10-12 18:29:47 +08:00
laodaming
2a1ceded61 fix 2023-10-12 17:02:16 +08:00
laodaming
d1313fca0c fix 2023-10-12 16:01:38 +08:00
laodaming
22ee293bfb fix 2023-10-12 14:44:09 +08:00
laodaming
e2b174a58f Merge branch 'develop' into feature/websocket 2023-10-12 14:31:04 +08:00
laodaming
f5744c8d09 fix 2023-10-12 14:30:06 +08:00
laodaming
882be02d07 fix 2023-10-12 14:02:55 +08:00
laodaming
0b6428cf34 fix 2023-10-12 14:01:23 +08:00
laodaming
d0e0d17b5d fix 2023-10-12 12:30:33 +08:00
laodaming
1625975814 fix 2023-10-12 11:49:52 +08:00
laodaming
96c866f1d4 fix 2023-10-12 11:27:16 +08:00
laodaming
88ea78d67b fix 2023-10-12 11:25:26 +08:00
laodaming
8a349399e1 fix 2023-10-12 11:19:01 +08:00
laodaming
cefe601046 fix 2023-10-12 11:05:05 +08:00
laodaming
edc50a15ec fix 2023-10-11 19:13:54 +08:00
laodaming
f65ff33e19 fix 2023-10-11 19:12:45 +08:00
laodaming
9dad383b03 fix 2023-10-11 19:10:03 +08:00
laodaming
7cc1addfe4 fix 2023-10-11 19:01:48 +08:00
laodaming
d93b009816 fix 2023-10-11 18:54:54 +08:00
laodaming
2e4be2800f fix 2023-10-11 18:54:14 +08:00
laodaming
afe8b26eee fix 2023-10-11 18:37:47 +08:00
laodaming
394f0c6e46 fix 2023-10-11 18:32:35 +08:00
laodaming
91c984db43 fix 2023-10-11 18:29:58 +08:00
laodaming
3d000cdc14 fix 2023-10-11 18:10:24 +08:00
laodaming
e77638b0e1 fix 2023-10-11 18:06:40 +08:00
laodaming
90277394fa fix 2023-10-11 17:58:38 +08:00
laodaming
c24ddb4af2 fix 2023-10-11 17:54:46 +08:00
laodaming
a138cdbd01 fix 2023-10-11 17:50:08 +08:00
laodaming
df1b599e51 fix 2023-10-11 16:28:39 +08:00
laodaming
aa31451210 fix 2023-10-11 16:21:20 +08:00
laodaming
1b48a50da3 fix 2023-10-11 15:50:43 +08:00
laodaming
8e11157c92 Merge branch 'develop' into feature/websocket 2023-10-11 15:22:48 +08:00
momo
9b09a33f47 fix:算法请求调整 2023-10-11 15:13:13 +08:00
momo
3bb31daaa1 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-11 15:10:42 +08:00
momo
c67a7664ec fix:算法请求调整 2023-10-11 15:10:38 +08:00
laodaming
9627cc12bf fix 2023-10-11 14:42:49 +08:00
laodaming
2b084bfdc9 fix 2023-10-11 14:19:22 +08:00
eson
68c332f20e contact us 2023-10-11 14:10:44 +08:00
eson
2d897d26d0 Merge branch 'develop' of https://gitee.com/fusenpack/fusenapi into develop 2023-10-11 12:23:46 +08:00
eson
9bb5f1b2dd contact us 2023-10-11 12:23:41 +08:00
laodaming
a6f0d49c6e fix 2023-10-11 12:20:38 +08:00
laodaming
eb81faad39 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-11 12:17:02 +08:00
laodaming
2f45b83ba3 fix 2023-10-11 12:16:54 +08:00
momo
58d44a38a6 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-11 12:11:24 +08:00
momo
c04231d6d7 fix:算法请求调整 2023-10-11 12:11:21 +08:00
laodaming
5584bfc4da Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-11 12:10:14 +08:00
laodaming
b86d6748b4 fix 2023-10-11 12:10:08 +08:00
eson
fff760253a Merge branch 'develop' of https://gitee.com/fusenpack/fusenapi into develop 2023-10-11 11:55:49 +08:00
eson
c6fa875148 email limit & password limit 2023-10-11 11:55:44 +08:00
laodaming
543099c8d7 fix 2023-10-11 11:52:54 +08:00
laodaming
350f06116e Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-11 11:49:11 +08:00
laodaming
77cb259124 fix 2023-10-11 11:49:04 +08:00
eson
5b483dadb5 info nofitycation 2023-10-11 11:36:09 +08:00
eson
5b0b45b141 Merge branch 'develop' of https://gitee.com/fusenpack/fusenapi into develop 2023-10-11 11:26:22 +08:00
laodaming
8f8419b8c1 fix 2023-10-11 11:26:11 +08:00
eson
10e794110f info address list 2023-10-11 11:25:38 +08:00
laodaming
501c4643f4 fix 2023-10-11 11:22:34 +08:00
laodaming
7883056ded fix 2023-10-11 11:22:11 +08:00
laodaming
c8e6467e9a fix 2023-10-11 11:18:50 +08:00
laodaming
3a9de995b2 fix 2023-10-11 10:49:00 +08:00
momo
a1bed56d19 fix:算法请求调整 2023-10-11 10:16:45 +08:00
momo
a401d1e4c9 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-11 10:14:54 +08:00
momo
a8df57808f fix:算法请求调整 2023-10-11 10:14:31 +08:00
laodaming
97ae9e4d8e fix 2023-10-10 18:11:47 +08:00
laodaming
8cf76c7051 fix 2023-10-10 18:08:58 +08:00
laodaming
a0106e30cc fix 2023-10-10 17:50:56 +08:00
laodaming
9e71d9a60f fix 2023-10-10 17:49:47 +08:00
momo
5e9c1df5da fix:算法请求调整 2023-10-10 17:30:31 +08:00
momo
ba40f63b42 fix:算法请求调整 2023-10-10 17:25:51 +08:00
momo
fec42ad634 fix:算法请求调整 2023-10-10 17:17:28 +08:00
momo
21475d7d52 fix:算法请求调整 2023-10-10 15:58:37 +08:00
momo
14e909a9a6 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-10 15:10:42 +08:00
momo
984690c47a fix:算法请求调整 2023-10-10 15:10:15 +08:00
laodaming
ce31946e53 fix 2023-10-10 15:09:20 +08:00
laodaming
056fed40f1 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-10 15:08:48 +08:00
laodaming
8f92776103 fix 2023-10-10 15:08:41 +08:00
momo
2dc5a2435f fix:算法请求调整 2023-10-10 15:03:12 +08:00
laodaming
8593eb2dd3 fix 2023-10-10 14:59:00 +08:00
momo
3105c29071 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-10 14:58:55 +08:00
momo
6e8d47ae91 fix:算法请求调整 2023-10-10 14:58:36 +08:00
laodaming
2068825ae1 fix 2023-10-10 14:19:11 +08:00
laodaming
3f0d8d017e fix 2023-10-10 14:15:43 +08:00
momo
019a717706 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-10 11:29:43 +08:00
momo
11ef2223d3 fix:订单列表 2023-10-10 11:29:28 +08:00
eson
ae27baa79b Merge branch 'develop' of https://gitee.com/fusenpack/fusenapi into develop 2023-10-10 11:21:50 +08:00
eson
73caa3cedd info address list 2023-10-10 11:21:43 +08:00
laodaming
1cfbbe7283 fix 2023-10-09 18:28:43 +08:00
laodaming
cbb57c8c34 fix 2023-10-09 18:21:45 +08:00
laodaming
83ef491069 fix 2023-10-09 17:57:54 +08:00
laodaming
0ce7cf8f17 fix 2023-10-09 17:56:28 +08:00
laodaming
32cda95788 fix 2023-10-09 17:30:29 +08:00
laodaming
83585d1c37 fix 2023-10-09 17:27:47 +08:00
laodaming
142bdbdcb9 fix 2023-10-09 17:02:30 +08:00
laodaming
d054d1a9ba fix 2023-10-09 17:01:44 +08:00
laodaming
b4e98d5238 fix 2023-10-09 16:14:03 +08:00
eson
ff0960e2bb Merge branch 'develop' of https://gitee.com/fusenpack/fusenapi into develop 2023-10-09 16:03:18 +08:00
eson
bdb093e7da 添加 .gitignore 忽略二进制执行文件 2023-10-09 16:02:46 +08:00
laodaming
41949bef72 fix 2023-10-09 15:15:44 +08:00
laodaming
d73d748436 fix 2023-10-09 15:05:50 +08:00
eson
16acfb7320 Merge branch 'develop' of https://gitee.com/fusenpack/fusenapi into develop 2023-10-09 14:42:01 +08:00
eson
9fdc5b4dbf proxyserver 2023-10-09 14:41:57 +08:00
laodaming
f42c8bd18c fix 2023-10-09 14:08:43 +08:00
laodaming
ba3e7ce31b fix 2023-10-09 12:28:08 +08:00
laodaming
12a6e95a11 fix 2023-10-09 11:20:38 +08:00
laodaming
e91bc83912 fix 2023-10-09 10:08:05 +08:00
laodaming
49877b4ef7 fix 2023-10-09 10:04:41 +08:00
laodaming
23b8e3cf3c fix 2023-10-09 10:03:15 +08:00
laodaming
7c065901c4 fix 2023-10-09 10:01:44 +08:00
momo
17dc892c07 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-08 18:38:45 +08:00
momo
634f1b9584 fix:新增订单关闭 2023-10-08 18:38:39 +08:00
laodaming
9faae14892 fix 2023-10-08 18:11:11 +08:00
laodaming
6bd9a0ab05 fix 2023-10-08 18:07:34 +08:00
laodaming
8d4901cdcd fix 2023-10-08 18:00:21 +08:00
laodaming
af35164fb2 fix 2023-10-08 17:15:27 +08:00
laodaming
1a3fbfb175 fix 2023-10-08 17:13:28 +08:00
laodaming
939ee8e0fe fix 2023-10-08 17:07:59 +08:00
laodaming
f5de417b99 fix 2023-10-08 17:06:10 +08:00
laodaming
4dce0d7087 fix 2023-10-08 17:04:37 +08:00
momo
d2f24772ca Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-08 16:54:51 +08:00
momo
d69870c882 fix:订单列表 2023-10-08 16:54:48 +08:00
laodaming
96b69fc8b9 fix 2023-10-08 16:27:25 +08:00
laodaming
066c911439 fix 2023-10-08 16:08:47 +08:00
laodaming
885aa081c6 fix 2023-10-08 16:07:55 +08:00
laodaming
d191bb3ca4 fix 2023-10-08 16:00:45 +08:00
laodaming
fdcd485f9f fix 2023-10-08 15:53:53 +08:00
momo
88f407edb9 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-08 15:48:34 +08:00
momo
6dc591283e fix:合图调整 2023-10-08 15:48:22 +08:00
laodaming
ddfe91a42e 新增获取收藏列表接口 2023-10-08 15:29:03 +08:00
momo
8c69e4d2d3 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-08 14:32:36 +08:00
momo
296194e730 fix:上传logo,报错信息反馈给前端 2023-10-08 14:32:31 +08:00
laodaming
a59273fe5b Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-08 12:31:12 +08:00
laodaming
385540937e 11 2023-10-08 12:31:06 +08:00
eson
d146fbb631 Merge branch 'develop' of https://gitee.com/fusenpack/fusenapi into develop 2023-10-08 12:19:03 +08:00
eson
bdf0dd7605 info address default 2023-10-08 12:18:58 +08:00
laodaming
cfea0cb09b Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-08 12:11:28 +08:00
laodaming
23094b2427 11 2023-10-08 12:11:19 +08:00
eson
7a2820e496 Merge branch 'develop' of https://gitee.com/fusenpack/fusenapi into develop 2023-10-08 12:09:51 +08:00
eson
0f7d35ea00 info address default 2023-10-08 12:09:46 +08:00
laodaming
243fd29a60 增加收藏页的添加和删除接口 2023-10-08 12:06:48 +08:00
laodaming
98967990e7 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-08 12:04:08 +08:00
eson
8bc1607f00 info address default 2023-10-08 12:04:02 +08:00
laodaming
b93691a0bf 增加收藏页的添加和删除接口 2023-10-08 12:04:00 +08:00
eson
bfeacad5f0 info address default 2023-10-08 11:55:06 +08:00
eson
f8c8c634cb info address default 2023-10-08 11:46:51 +08:00
eson
24304b0c85 info address default 2023-10-08 11:38:10 +08:00
eson
32b8ceeb96 info address default 2023-10-08 11:29:04 +08:00
eson
fa011a1670 Merge branch 'develop' of https://gitee.com/fusenpack/fusenapi into develop 2023-10-08 11:23:28 +08:00
eson
0410685138 info address default 2023-10-08 11:23:22 +08:00
laodaming
0fde3c8d91 fix 2023-10-08 10:33:25 +08:00
laodaming
cb4e15e54b Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-08 10:31:49 +08:00
laodaming
f933fcac69 fix 2023-10-08 10:31:42 +08:00
momo
e87ece4071 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-08 10:23:44 +08:00
momo
1480298bd7 fix:订单逻辑 2023-10-08 10:23:39 +08:00
laodaming
414a3f8507 fix 2023-10-08 10:22:00 +08:00
momo
3f78cfd824 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-07 18:37:04 +08:00
momo
ae2c41364f fix:删除订单 2023-10-07 18:36:59 +08:00
laodaming
0350315354 fix 2023-10-07 18:09:17 +08:00
eson
6aa842e328 Merge branch 'develop' of https://gitee.com/fusenpack/fusenapi into develop 2023-10-07 17:58:29 +08:00
eson
ced3ce8657 info address default 2023-10-07 17:58:24 +08:00
laodaming
d4867a7089 删除产品服务不用的接口 2023-10-07 17:42:34 +08:00
momo
e031f804f3 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-07 17:31:29 +08:00
momo
73a67aa21a fix 2023-10-07 17:31:24 +08:00
laodaming
e46ac8ff63 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-07 17:08:01 +08:00
laodaming
734c4e9102 fix 2023-10-07 17:07:53 +08:00
momo
f2226ff0e4 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-07 17:03:45 +08:00
momo
e9f6b6cc68 fix 2023-10-07 17:03:28 +08:00
eson
da162f859e Merge branch 'develop' of https://gitee.com/fusenpack/fusenapi into develop 2023-10-07 16:59:56 +08:00
eson
586e02c842 info address used 2023-10-07 16:59:52 +08:00
momo
0b0e08c377 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-07 16:59:26 +08:00
momo
679a0c660f fix 2023-10-07 16:59:19 +08:00
momo
7b124d95c1 fix 2023-10-07 16:58:51 +08:00
laodaming
ff086a8fa4 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-07 16:58:30 +08:00
laodaming
560bc9a7d2 fix 2023-10-07 16:58:22 +08:00
momo
f5620e397e fix 2023-10-07 16:58:00 +08:00
momo
807f1aa70e Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-07 16:42:53 +08:00
momo
c57f2acafd fix 2023-10-07 16:42:40 +08:00
laodaming
66acaa6095 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-07 16:25:45 +08:00
laodaming
e042cf209d 11 2023-10-07 16:25:39 +08:00
momo
9cfdfdbc77 fix 2023-10-07 16:14:46 +08:00
momo
0b8fc0915b fix 2023-10-07 16:13:08 +08:00
momo
342d1f99ec Merge branches 'develop' and 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-07 16:12:35 +08:00
momo
7301463857 fix:优化订单自动取消 2023-10-07 16:12:29 +08:00
laodaming
7fa7b868ca 11 2023-10-07 16:10:51 +08:00
laodaming
67fe103ac1 11 2023-10-07 16:03:54 +08:00
laodaming
34b2aef763 11 2023-10-07 15:55:12 +08:00
laodaming
9858300984 11 2023-10-07 15:44:44 +08:00
momo
6cdb8b6e6b fix 2023-10-07 15:42:25 +08:00
momo
a8a7132a66 Merge branches 'develop' and 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-07 15:39:19 +08:00
momo
1f46911f51 fix 2023-10-07 15:38:59 +08:00
laodaming
b0203593bb 11 2023-10-07 15:36:57 +08:00
laodaming
f980520ba7 11 2023-10-07 15:16:49 +08:00
laodaming
550ca5b7b9 11 2023-10-07 15:16:26 +08:00
laodaming
9dbcf33cb9 11 2023-10-07 15:15:16 +08:00
laodaming
7d3f614356 11 2023-10-07 15:09:49 +08:00
laodaming
6a35779bd5 11 2023-10-07 15:00:41 +08:00
laodaming
a9bb36d394 fix 2023-10-07 14:30:44 +08:00
laodaming
87dd183279 fix 2023-10-07 14:24:57 +08:00
momo
6743f4dff1 fix调整 2023-10-07 14:11:11 +08:00
momo
e6d4e84fd4 fix调整 2023-10-07 14:10:06 +08:00
momo
eb4fd9cff9 fix调整 2023-10-07 14:06:00 +08:00
momo
ce35498c7e fix调整 2023-10-07 13:41:06 +08:00
momo
fcb3dd13c6 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-07 13:33:51 +08:00
momo
2261421ba5 fix调整 2023-10-07 13:33:40 +08:00
laodaming
fdd6ac9b44 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-07 12:06:27 +08:00
laodaming
a10d41405b fix 2023-10-07 12:06:21 +08:00
momo
8870b389be fix列表调整 2023-10-07 11:54:38 +08:00
momo
df5414fc1d fix列表调整 2023-10-07 11:53:12 +08:00
momo
8d987c4c54 fix:合图调整 2023-10-07 11:48:53 +08:00
momo
c2f61fc61a Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-10-07 11:32:16 +08:00
momo
122d558765 fix:合图调整 2023-10-07 11:32:11 +08:00
laodaming
d113ef1c6e fix 2023-10-07 11:24:18 +08:00
laodaming
aafcbfcf50 fix 2023-10-07 10:43:33 +08:00
momo
cf83bd068b fix:订单模块 2023-10-07 10:40:44 +08:00
laodaming
cc6da9a648 fix 2023-10-07 10:13:15 +08:00
momo
7c0b1107f8 fix:支付 2023-09-28 18:27:43 +08:00
momo
d7894fd5c8 fix:支付 2023-09-28 18:27:15 +08:00
momo
3a51a5f297 fix:支付 2023-09-28 18:17:43 +08:00
momo
821c2063c9 fix:支付 2023-09-28 18:04:35 +08:00
momo
e991ee3966 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-09-28 17:53:46 +08:00
momo
642ca772e8 fix:支付 2023-09-28 17:53:41 +08:00
eson
de751d5d68 info address used 2023-09-28 17:27:52 +08:00
eson
f7d0a6422e info address used 2023-09-28 17:06:38 +08:00
eson
649e635d17 info get profile 2023-09-28 16:54:10 +08:00
eson
989b2daacc info get profile 2023-09-28 16:47:02 +08:00
eson
db0c8a2532 info get profile 2023-09-28 15:26:02 +08:00
eson
316ebd9fca info get profile 2023-09-28 15:19:45 +08:00
eson
6072341a2b info get profile 2023-09-28 14:42:26 +08:00
eson
1f9123c0f4 info get profile 2023-09-28 13:32:37 +08:00
eson
91bc3310a1 Merge branch 'develop' of https://gitee.com/fusenpack/fusenapi into develop 2023-09-28 13:25:12 +08:00
eson
d92c77766c info get profile 2023-09-28 13:25:06 +08:00
momo
4032255694 fix:支付 2023-09-28 10:51:53 +08:00
momo
b7a41d39e3 fix:支付 2023-09-28 10:05:55 +08:00
momo
7573f9ccf6 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-09-28 10:00:08 +08:00
momo
5ecb8537c2 fix:支付 2023-09-28 09:59:53 +08:00
laodaming
cb378afb1f Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-09-27 18:35:29 +08:00
laodaming
06ab4a596f fix 2023-09-27 18:35:20 +08:00
momo
ccc5a2dabc fix:支付 2023-09-27 18:22:30 +08:00
momo
4cb921853e Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-09-27 18:01:21 +08:00
momo
4a55844d73 fix:支付 2023-09-27 18:00:35 +08:00
laodaming
fbeebabf27 fix 2023-09-27 17:52:03 +08:00
momo
8d9ff4fe10 fix:支付 2023-09-27 17:51:25 +08:00
momo
f68032c8ea fix:支付 2023-09-27 17:40:44 +08:00
momo
39efb7eefb Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-09-27 17:24:05 +08:00
momo
fef541dfe5 fix:支付 2023-09-27 17:23:58 +08:00
laodaming
8bce140dd2 fix 2023-09-27 17:10:17 +08:00
laodaming
60749646e2 fix 2023-09-27 17:03:15 +08:00
laodaming
13420cd400 fix 2023-09-27 17:01:30 +08:00
laodaming
50c5e28381 fix 2023-09-27 16:51:29 +08:00
laodaming
b6d0ef1c7c fix 2023-09-27 16:36:38 +08:00
laodaming
1dfa390557 fix 2023-09-27 16:16:33 +08:00
laodaming
142ada5b07 fix 2023-09-27 16:09:28 +08:00
laodaming
e917792988 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-09-27 16:01:33 +08:00
laodaming
b6d4d06c25 fix 2023-09-27 16:01:22 +08:00
eson
31b712784f info get profile 2023-09-27 15:48:13 +08:00
eson
0a8f3cd5ba info get profile 2023-09-27 15:47:40 +08:00
eson
89e8b4cff9 info get profile 2023-09-27 15:46:35 +08:00
eson
2f4f59d6ab Merge branch 'develop' of https://gitee.com/fusenpack/fusenapi into develop 2023-09-27 15:37:06 +08:00
eson
43752954ae info get profile 2023-09-27 15:37:02 +08:00
laodaming
9e2526405f fix 2023-09-27 15:12:18 +08:00
laodaming
2ac507ef34 fix 2023-09-27 14:14:16 +08:00
laodaming
59114aa94a fix 2023-09-27 14:13:34 +08:00
laodaming
d5e5f7e6e2 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-09-27 14:05:34 +08:00
laodaming
02f2e08329 fix 2023-09-27 14:05:26 +08:00
eson
3dc822fcde info get profile 2023-09-27 12:28:53 +08:00
eson
d61e939685 info get profile 2023-09-27 12:24:47 +08:00
eson
fe57705286 info get profile 2023-09-27 12:23:02 +08:00
eson
b4f201eb98 info get profile 2023-09-27 12:18:16 +08:00
eson
943eba6f1a info get profile 2023-09-27 12:12:28 +08:00
eson
8654ab3ecd Merge branch 'develop' of https://gitee.com/fusenpack/fusenapi into develop 2023-09-27 12:04:57 +08:00
eson
82ce9a5114 info get profile 2023-09-27 12:04:53 +08:00
laodaming
465bc5e62d Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-09-27 11:57:16 +08:00
laodaming
788dbd325e fix 2023-09-27 11:57:10 +08:00
eson
53446bb606 info get profile 2023-09-27 11:55:21 +08:00
eson
945a8ec83c Merge branch 'develop' of https://gitee.com/fusenpack/fusenapi into develop 2023-09-27 11:51:28 +08:00
eson
5fcd76e32e info get profile 2023-09-27 11:51:24 +08:00
laodaming
840f7c8675 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-09-27 11:48:22 +08:00
laodaming
4ea3487043 fix 2023-09-27 11:48:15 +08:00
eson
887bc555fa Merge branch 'develop' of https://gitee.com/fusenpack/fusenapi into develop 2023-09-27 11:47:43 +08:00
eson
4e45e1e393 info get profile 2023-09-27 11:47:38 +08:00
laodaming
884ce87972 fix 2023-09-27 11:36:09 +08:00
eson
9de1099b12 info get profile 2023-09-27 11:35:34 +08:00
eson
899db716f1 Merge branch 'develop' of https://gitee.com/fusenpack/fusenapi into develop 2023-09-27 11:30:22 +08:00
eson
2eadff7876 info get profile 2023-09-27 11:30:17 +08:00
laodaming
0967df9113 fix 2023-09-27 11:23:22 +08:00
laodaming
36ae64f3e7 fix 2023-09-27 11:21:16 +08:00
laodaming
ab916ac13d fix 2023-09-27 11:13:37 +08:00
momo
6eccd11386 Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop 2023-09-27 11:11:52 +08:00
momo
f876971e50 fix:支付 2023-09-27 11:10:31 +08:00
laodaming
e6bd26a775 fix 2023-09-27 10:16:40 +08:00
momo
6c53238457 fix:支付 2023-09-27 10:12:52 +08:00
momo
032d089359 fix:支付 2023-09-27 10:09:26 +08:00
220 changed files with 5007 additions and 4346 deletions

View File

@ -1,7 +0,0 @@
package constants
// 千人千面windows访问图片的地址
const DOMAIN_RENDER_IMG_NAME = "https://fusenrenderimg.kayue.cn"
// 云渲染域名和访问地址
const DOMAIN_NAME = "https://fusenapi.kayue.cn:8010/"

View File

@ -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>
<tr height="30px"></tr> <td class="header_td logo" align="left">
<tr> <img class="header_logo" src="https://fusenapi.kayue.cn:8010/storage/email/logo.png" alt="logo">
<td align="left" rowspan="9" style="vertical-align: top; width: 50%;"> </td>
<img style="max-height: 40px;max-width: 100%;" <td class="header_td title" align="right">Invoice</td>
src="{{h5Url}}/storage/email/logo.png" alt="logo"> </tr>
</td> </table>
<td align="left" style="width: 50%;"> <!-- information -->
<span style="color: #212121;font-weight: bold;font-size: 42px; display: block;">Invoice</span> <table class="information_warp" border="0" align="center" cellpadding="0" cellspacing="0" width="100%">
</td> <tr>
</tr> <td class="information_td bill" align="left">Bill To:</td>
<tr height="30px"></tr> <td class="information_td right" align="right">Invoice No. {{invoice_number}}</td>
<tr> </tr>
<td align="left" style="width: 50%;"> <tr>
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">Invoice Number:</span> <td class="information_td info" align="left">{{buyer_name}}</td>
</td> <td class="information_td right" align="right">Date: {{buy_date}}</td>
</tr> </tr>
<tr height="15px"></tr> <tr>
<tr> <td class="information_td info" align="left">{{street}}</td>
<td align="left" style="width: 50%;"> <td class="information_td" align="right"></td>
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">{{order_sn}}</span> </tr>
</td> <tr>
</tr> <td class="information_td info" align="left">{{city}}</td>
<tr height="30px"></tr> <td class="information_td" align="right"></td>
<tr> </tr>
<td align="left" style="width: 50%;"> <tr>
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">Date:</span> <td class="information_td info" align="left">{{country}}</td>
</td> <td class="information_td" align="right"></td>
</tr> </tr>
<tr height="15px"></tr> </table>
<tr> <!-- bill -->
<td align="left" style="width: 50%;"> <table class="bill_warp" border="0" align="center" cellpadding="0" cellspacing="0" width="100%">
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">{{order_expire_time}}</span> <!--循环部分-->
</td> {{product_loop_html}}
</tr> <!--循环部分-->
<tr height="30px"></tr> </table>
</table> <!-- total -->
<!-- information --> <table class="total_warp" border="0" align="right" cellpadding="0" cellspacing="0" width="50%">
<table border="0" align="center" cellpadding="0" cellspacing="0" width="100%" <tr>
style="background-color: #fff;padding: 0 5%;"> <td class="total_td" align="right">Subtotal</td>
<tr height="30px"></tr> <td class="total_td info" align="right">${{subtotal_price}}</td>
<tr> </tr>
<td align="left" style="width: 50%;"> <tr>
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">Bill To:</span> <td class="total_td" align="right">Shipping Fee</td>
</td> <td class="total_td info" align="right">Free</td>
<td align="left" style="width: 50%;"> </tr>
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">Bill From:</span> <tr>
</td> <td class="total_td border-dashed" align="right">Tax</td>
</tr> <td class="total_td info border-dashed" align="right">${{tax}}</td>
<tr height="15px"></tr> </tr>
<tr> <tr>
<td align="left" style="width: 50%;"> <td class="total_td" align="right">Total</td>
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">{{name}}</span> <td class="total_td info" align="right">${{total_price}}</td>
</td> </tr>
<td align="left" style="width: 50%;"> <tr>
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">Lemon <td class="total_td border-solid" align="right">Deposit Requested</td>
Squeezy LLC</span> <td class="total_td info border-solid" align="right">${{deposit_price}}</td>
</td> </tr>
</tr> <tr>
<tr> <td class="total_td total" align="right">Deposit Due</td>
<td align="left" style="width: 50%;"> <td class="total_td total" align="right">${{deposit_price}}</td>
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">{{street}} {{suite}}</span> </tr>
</td> </table>
<td align="left" style="width: 50%;"> <!-- notes -->
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">Lemon <table class="notes_warp" border="0" align="center" cellpadding="0" cellspacing="0" width="100%">
Squeezy LLC</span> <tr>
</td> <td class="notes_td title" align="left">Payment Method:</td>
</tr> <td class="notes_td title" align="left">Notes:</td>
<tr> </tr>
<td align="left" style="width: 50%;"> <tr>
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">{{city}} {{state}} {{zip_code}}</span> <td class="notes_td" align="left">{{payment_method}}</td>
</td> <td class="notes_td notes" align="left" rowspan="2">{{notes}}</td>
<td align="left" style="width: 50%;"> </tr>
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">Lemon <tr>
Squeezy LLC</span> <td class="notes_td" align="left">Account No. {{account_number}}</td>
</td> </tr>
</tr> </table>
<tr>
<td align="left" style="width: 50%;">
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;"> </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 height="30px"></tr>
</table>
<!-- bill -->
<table border="0" align="center" cellpadding="0" cellspacing="0" width="100%"
style="background-color: #F8F8FA;padding: 0 5%;">
<tr>
<td align="left" style="width: 50%;">
<span
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>
</table>
<table border="0" align="center" cellpadding="0" cellspacing="0" width="100%"
style="background-color: #fff;padding: 0 5%;">
<tr height="30px"></tr>
{{orderHTML}}
<tr>
<td align="left" colspan="2">
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">Subtotal</span>
</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 height="15px"></tr>
<tr>
<td align="left" colspan="2">
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">Tax</span>
</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 height="15px"></tr>
<tr>
<td align="left" colspan="2">
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">Invoice Total</span>
</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 height="15px"></tr>
<tr>
<td align="left" colspan="2" {{first_style1}}>
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">First Payment</span>
</td>
<td align="right" {{first_style2}}>
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">-${{first_payment}}</span>
</td>
</tr>
<tr height="15px"></tr>
{{second_payment_html}}
<tr height="15px"></tr>
<tr>
<td align="left" colspan="2">
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">Amount Due</span>
</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 height="88px"></tr>
<tr>
<td align="left" colspan="4">
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">Payment Method:</span>
</td>
</tr>
{{pay_html}}
<tr height="30px"></tr>
<tr>
<td align="left" colspan="4">
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">Notes:</span>
</td>
</tr>
<tr height="15px"></tr>
<tr>
<td align="left" colspan="4">
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">Add a note...</span>
</td>
</tr>
<!-- <tr height="80px"></tr> -->
</table>
</body> </body>
</html>` </html>
// 发票支付html模板 `
const PAYMENT_HTML = `<tr height="15px"></tr>
<tr>
<td align="left" colspan="4">
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">${{pay_amount}} payment from {{brand}}
····{{card_no}}</span>
</td>
</tr>`
// 二次支付html // 产品循环部分{{product_loop_html}}
const SECOND_PAYMENY_HTML = `<tr> const PRODUCT_LOOP_HTML_CONTENT = ` <tr>
<td align="left" colspan="2" style="padding-bottom: 20px; border-bottom: 1px solid #212121;"> <td class="bill_td title" align="left">{{product_name}}</td>
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">Second Payment</span> <td class="bill_td title" align="right">${{product_item_price}}</td>
</td> <td class="bill_td title" align="right">{{purchase_quantity}}</td>
<td align="right" style="width: 16.66%; padding-bottom: 20px; border-bottom: 1px solid #212121;"> <td class="bill_td title" align="right">${{product_total_price}}</td>
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">-${{remain_amount}}</span> </tr>`
</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>`

View File

@ -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,18 +45,22 @@ 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
) )
// 订单状态 // 订单状态
type OrderStatusCode int64 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
View File

@ -0,0 +1,5 @@
package constants
const (
QUEUE_NAME_ORDER = "queue_order"
)

View File

@ -4,12 +4,9 @@ type Websocket string
// websocket消息类型(主类别) // websocket消息类型(主类别)
const ( 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消息类型(通用通知类别)

View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -0,0 +1,14 @@
package initalize
import (
"fusenapi/utils/queue"
)
// 初始化
func InitDelayMessage() *queue.DelayMessage {
//创建延迟消息
dm := queue.NewDelayMessage()
go dm.Start()
return dm
}

View File

@ -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"
@ -15,16 +16,17 @@ 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),
} }
} }

View File

@ -4,15 +4,16 @@ import (
"gorm.io/gorm" "gorm.io/gorm"
) )
// casbin_rule // casbin_rule 后台--权限规则表
type CasbinRule struct { type CasbinRule struct {
PType *string `gorm:"default:'';" json:"p_type"` // Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // 序号
V0 *string `gorm:"default:'';" json:"v0"` // PType *string `gorm:"default:'';" json:"p_type"` //
V1 *string `gorm:"default:'';" json:"v1"` // V0 *string `gorm:"default:'';" json:"v0"` //
V2 *string `gorm:"default:'';" json:"v2"` // V1 *string `gorm:"default:'';" json:"v1"` //
V3 *string `gorm:"default:'';" json:"v3"` // V2 *string `gorm:"default:'';" json:"v2"` //
V4 *string `gorm:"default:'';" json:"v4"` // V3 *string `gorm:"default:'';" json:"v3"` //
V5 *string `gorm:"default:'';" json:"v5"` // V4 *string `gorm:"default:'';" json:"v4"` //
V5 *string `gorm:"default:'';" json:"v5"` //
} }
type CasbinRuleModel struct { type CasbinRuleModel struct {
db *gorm.DB db *gorm.DB

View File

@ -7,23 +7,21 @@ 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"` // 手机号码 Street *string `gorm:"default:'';" json:"street"` // 街道
Street *string `gorm:"default:'';" json:"street"` // 街道 Suite *string `gorm:"default:'';" json:"suite"` // 房号
Suite *string `gorm:"default:'';" json:"suite"` // 房号 City *string `gorm:"default:'';" json:"city"` // 城市
City *string `gorm:"default:'';" json:"city"` // 城市 State *string `gorm:"default:'';" json:"state"` //
State *string `gorm:"default:'';" json:"state"` // 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异常 Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` // 创建时间
IsDefault *int64 `gorm:"index;default:0;" json:"is_default"` // 1默认地址0非默认地址 Utime *time.Time `gorm:"index;default:'0000-00-00 00:00:00';" json:"utime"` // 更新时间
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` // 创建时间 Ltime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ltime"` // 上次被使用的时间
Utime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"utime"` // 更新时间
Ltime *time.Time `gorm:"index;default:'0000-00-00 00:00:00';" json:"ltime"` // 上次被使用的时间
} }
type FsAddressModel struct { type FsAddressModel struct {
db *gorm.DB db *gorm.DB

View File

@ -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
} }
@ -26,38 +45,21 @@ func (a *FsAddressModel) CreateOne(ctx context.Context, address *FsAddress) (res
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 {
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, Street: address.Street,
Street: address.Street, Suite: address.Suite,
Suite: address.Suite, City: address.City,
City: address.City, State: address.State,
State: address.State, Country: address.Country,
Country: address.Country, ZipCode: address.ZipCode,
ZipCode: address.ZipCode, Status: address.Status,
Status: address.Status, Ctime: &now,
IsDefault: address.IsDefault, Utime: &now,
Ctime: &now, Ltime: &now,
Utime: &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 = &ltime
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{}{
err = tx.Model(&FsAddress{}).Where(" `user_id` = ? and `status` = ? and `address_id` = ? ", userId, 1, addressId). "ltime": now,
UpdateColumn("ltime", now.AddDate(250, 0, 0)). "utime": now,
UpdateColumn("utime", now).Error
if err != nil {
return err
} }
err = tx.Where(" `user_id` = ? and `status` = ? and `address_id` != ? and `ltime` > ? ", userId, 1, addressId, now.AddDate(10, 0, 0)). if isDefault == 1 {
UpdateColumn("ltime", now).Error err = tx.Where("`user_id` = ? and `status` = 1 and `ltime` > ? and `address_id` != ?", userId, now.AddDate(10, 0, 0), addressId).
UpdateColumns(updates).Error
if err != nil {
return err
}
updates["ltime"] = now.AddDate(250, 0, 0)
}
tr := tx.Model(&FsAddress{}).Where("`address_id` = ? and `user_id` = ? and `status` = 1", addressId, userId).
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
}

View File

@ -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

View File

@ -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

View 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"}
}

View File

@ -0,0 +1,2 @@
package gmodel
// TODO: 使用model的属性做你想做的

View File

@ -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

View File

@ -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
}

View File

@ -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 {

View File

@ -7,17 +7,24 @@ import (
// fs_order 订单表 // fs_order 订单表
type FsOrder struct { type FsOrder struct {
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // 订单ID Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // 订单ID
UserId *int64 `gorm:"index;default:0;" json:"user_id"` // 用户ID UserId *int64 `gorm:"index;default:0;" json:"user_id"` // 用户ID
DeliveryMethod *int64 `gorm:"index;default:0;" json:"delivery_method"` // 物流类型 DeliveryMethod *int64 `gorm:"index;default:0;" json:"delivery_method"` // 物流类型
OrderSn *string `gorm:"unique_key;default:'';" json:"order_sn"` // OrderSn *string `gorm:"unique_key;default:'';" json:"order_sn"` //
OrderSource *string `gorm:"default:'';" json:"order_source"` // OrderSource *string `gorm:"default:'';" json:"order_source"` //
Status *int64 `gorm:"index;default:0;" json:"status"` // 订单状态 Status *int64 `gorm:"index;default:0;" json:"status"` // 订单状态
Metadata *[]byte `gorm:"default:'';" json:"metadata"` // Metadata *[]byte `gorm:"default:'';" json:"metadata"` //
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"` //
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

View File

@ -73,13 +73,14 @@ type PayStatus struct {
// 订单信息 // 订单信息
type OrderInfo struct { type OrderInfo struct {
Ctime *time.Time `json:"ctime"` // 创建日期 UserId int64 `json:"user_id"` // 物流类型
DeliveryMethod int64 `json:"delivery_method"` // 物流类型 Ctime *time.Time `json:"ctime"` // 创建日期
Metadata map[string]interface{} `json:"metadata"` // 额外参数 DeliveryMethod int64 `json:"delivery_method"` // 物流类型
OrderSn string `json:"order_sn"` // 订单编号 Metadata OrderMetadata `json:"metadata"` // 额外参数
Status OrderStatus `json:"status"` // 当前状态 OrderSn string `json:"order_sn"` // 订单编号
StatusLink []OrderStatus `json:"status_link"` // 状态链路 Status OrderStatus `json:"status"` // 当前状态
Utime *time.Time `json:"utime"` // 更新时间 StatusLink []OrderStatus `json:"status_link"` // 状态链路
Utime *time.Time `json:"utime"` // 更新时间
} }
// 订单状态--用户 // 订单状态--用户
@ -95,21 +96,24 @@ type OrderStatus struct {
// 订单商品 // 订单商品
type OrderProduct struct { type OrderProduct struct {
TotalPrice AmountInfo `json:"total_price"` // 商品总价 TotalPrice AmountInfo `json:"total_price"` // 商品总价
ExpectedDeliveryTime *time.Time `json:"expected_delivery_time"` // 预计到货时间 ItemPrice AmountInfo `json:"item_price"` // 商品单价
PurchaseQuantity PurchaseQuantity `json:"purchase_quantity"` // 购买数量 ExpectedDeliveryTime *time.Time `json:"expected_delivery_time"` // 预计到货时间
ProductID int64 `json:"product_id"` // 商品ID PurchaseQuantity PurchaseQuantity `json:"purchase_quantity"` // 购买数量
ProductName string `json:"product_name"` // 商品名称 ProductId int64 `json:"product_id"` // 商品ID
ItemPrice AmountInfo `json:"item_price"` // 商品单价 ProductSn string `json:"product_sn"` // 商品编码
ProductSnapshot interface{} `json:"product_snapshot"` // 商品快照 ProductName string `json:"product_name"` // 商品名称
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"` // 商品封面 ProductSnapshot interface{} `json:"product_snapshot"` // 商品快照
ProductSn string `json:"product_sn"` // 商品编码 ShoppingCartSnapshot *FsShoppingCartData `json:"shopping_cart_snapshot"` // 购物车快照
DiyInformation *UserDiyInformation `json:"diy_information"`
SizeInfo *OrderProductSizeInfo `json:"size_info"` DiyInformation *UserDiyInformation `json:"diy_information"`
FittingInfo *OrderProductFittingInfo `json:"fitting_info"` SizeInfo *OrderProductSizeInfo `json:"size_info"`
IsHighlyCustomized int64 `json:"is_highly_customized"` FittingInfo *OrderProductFittingInfo `json:"fitting_info"`
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"` // 实际到货时间
}

View 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"}
}

View 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
}

View File

@ -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"` // 浏览量

View File

@ -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 {

View File

@ -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"` // 是否设置为云渲染模型

View File

@ -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
}

View File

@ -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"` //
} }

View File

@ -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,8 +76,8 @@ 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"` //名称
} }
// 获取单个 // 获取单个

View File

@ -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
}

View File

@ -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{

View File

@ -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"`
}

View File

@ -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),

View File

@ -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:], "/")

View File

@ -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"

View File

@ -1 +1,2 @@
auth auth
main

View File

@ -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"]

View File

@ -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"

View File

@ -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

View File

@ -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{
@ -53,16 +53,17 @@ func init() {
} }
type EmailFormat struct { type EmailFormat struct {
TemplateName string // 模板名字 TemplateName string // 模板名字
UniqueKey string // 用于处理唯一的任务,重发都会被利用到 UniqueKey string // 用于处理唯一的任务,重发都会被利用到
TargetEmail string // 发送的目标email TargetEmail string // 发送的目标email
CompanyName string // fs公司名 CompanyName string // fs公司名
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()
} }

View File

@ -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())

View File

@ -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)
} }

View File

@ -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)

View File

@ -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",
}) })

View File

@ -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())

View File

@ -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{

View File

@ -1 +1,2 @@
base base
main

8
server/base/Dockerfile Executable file
View 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"]

View File

@ -1 +1,2 @@
canteen canteen
main

View File

@ -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
View File

@ -0,0 +1,2 @@
collection
main

8
server/collection/Dockerfile Executable file
View 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"]

View 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()
}

View 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

View 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
}
}

View File

@ -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)

View File

@ -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)

View File

@ -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)

View 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),
},
},
)
}

View File

@ -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)

View 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)
}
}
}

View 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)
// }

View File

@ -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)
// }

View 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)
// }

File diff suppressed because one or more lines are too long

View 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)
// }

View 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),
}
}

View 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
}

View File

@ -1 +1,2 @@
data-transfer data-transfer
main

View File

@ -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"]

View File

@ -1 +1,2 @@
home-user-auth home-user-auth
main

View File

@ -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"]

View File

@ -36,9 +36,7 @@ type Config struct {
} }
} }
BLMService struct { BLMService struct {
Url string Version string
LogoCombine struct { Urls []string
Url string
}
} }
} }

View File

@ -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",

View File

@ -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)
}
}
}

View File

@ -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})
}

View File

@ -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)
}

View File

@ -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

View File

@ -38,9 +38,9 @@ func NewServiceContext(c config.Config) *ServiceContext {
SharedState: nil, SharedState: nil,
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)),
}), }),
} }
} }

View File

@ -1 +1,2 @@
info info
main

8
server/info/Dockerfile Executable file
View 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"]

View File

@ -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

View 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)
}
}
}

View 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)
}
}
}

View File

@ -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)

View File

@ -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),
},
}, },
) )
} }

View File

@ -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

View File

@ -49,32 +49,33 @@ func (l *AddressAddLogic) AddressAdd(req *types.AddressRequest, userinfo *auth.U
// 如果ID为0, 表示新增地址 // 如果ID为0, 表示新增地址
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, Street: &req.Street,
Street: &req.Street, Suite: &req.Suite,
Suite: &req.Suite, City: &req.City,
City: &req.City, State: &req.State,
State: &req.State, Country: &country,
Country: &country, 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

View File

@ -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 必须重新处理

View File

@ -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 必须重新处理

View File

@ -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 {
@ -47,19 +52,17 @@ 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, FirstName: &req.FirstName,
AddressName: &req.AddressName, LastName: &req.LastName,
FirstName: &req.FirstName, Mobile: &req.Mobile,
LastName: &req.LastName, ZipCode: &req.ZipCode,
Mobile: &req.Mobile, Street: &req.Street,
ZipCode: &req.ZipCode, Suite: &req.Suite,
Street: &req.Street, City: &req.City,
Suite: &req.Suite, State: &req.State,
City: &req.City, Utime: &now,
State: &req.State,
Utime: &now,
} }
err := l.svcCtx.AllModels.FsAddress.UpdateAddress(l.ctx, &address) err := l.svcCtx.AllModels.FsAddress.UpdateAddress(l.ctx, &address)
@ -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 必须重新处理

View 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)
// }

View 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)
// }

View 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)
// }

View File

@ -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) // 日志记录错误

View File

@ -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,33 +25,53 @@ 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"` //手机 ZipCode string `json:"zip_code"` //邮编
ZipCode string `json:"zip_code"` //邮编 Street string `json:"street"` //街道
Street string `json:"street"` //街道 Suite string `json:"suite"` //房号
Suite string `json:"suite"` //房号 City string `json:"city"` //城市
City string `json:"city"` //城市 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"` // 首名
} }

View File

@ -1 +1,2 @@
map-library map-library
main

View File

@ -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"]

View File

@ -1 +1,2 @@
order order
main

Some files were not shown because too many files have changed in this diff Show More