Compare commits
197 Commits
2aacbf1c3e
...
b9b7309edc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b9b7309edc | ||
|
|
d22be1d676 | ||
|
|
2d0b23e063 | ||
|
|
01b78a099a | ||
|
|
fcfea291e5 | ||
|
|
9c08acc97a | ||
|
|
1203c087d8 | ||
|
|
91c1c580f9 | ||
|
|
b571b1b31c | ||
|
|
62565fac4e | ||
|
|
54613f5be0 | ||
|
|
dd8b864a7f | ||
|
|
8d3fce919f | ||
|
|
c880cba0a3 | ||
|
|
194dc50eaa | ||
|
|
ee6e31473e | ||
|
|
0989faf35a | ||
|
|
93b0cadea9 | ||
|
|
f387e46977 | ||
|
|
c46d9d8fd9 | ||
|
|
ad01dbc0e5 | ||
|
|
26389bf4d6 | ||
|
|
15888a953b | ||
|
|
2c995e9512 | ||
|
|
44fd4f03e3 | ||
|
|
76f4a682ac | ||
|
|
9e6f919fa8 | ||
|
|
e2508cc347 | ||
|
|
d07350969f | ||
|
|
6e9f47ff85 | ||
|
|
42bd585fe9 | ||
|
|
f20b4fad3e | ||
|
|
871a7a278b | ||
|
|
83dc607ec4 | ||
|
|
fae365d59e | ||
|
|
821cbb8879 | ||
|
|
821e36281a | ||
|
|
ef522551e4 | ||
|
|
c7a2cf7d1c | ||
|
|
4dfeebeaed | ||
|
|
31debda97f | ||
|
|
a1d78b7a0c | ||
|
|
03cbe2894e | ||
|
|
82fc0f2b80 | ||
|
|
2747c9ddd9 | ||
|
|
d45a0eb680 | ||
|
|
4cd2e1ce65 | ||
|
|
00b3a974f9 | ||
|
|
f9595aad3f | ||
|
|
85cd2bff8d | ||
|
|
1e444ca616 | ||
|
|
1543e60301 | ||
|
|
600a6edd7b | ||
|
|
407ba29319 | ||
|
|
c42c37f65e | ||
|
|
cdeec5a4e1 | ||
|
|
94088b5aa4 | ||
|
|
e23ee6518d | ||
|
|
79120e1fd9 | ||
|
|
6a41be4f3a | ||
|
|
f7992279e2 | ||
|
|
01cc115a60 | ||
|
|
47a1ecfc79 | ||
|
|
55a4526536 | ||
|
|
7eab65be87 | ||
|
|
fc302ad1be | ||
|
|
87c2d7bf96 | ||
|
|
27f429cdec | ||
|
|
f615e4fe77 | ||
|
|
87ff25a2e6 | ||
|
|
a832a6fa81 | ||
|
|
0e282e741b | ||
|
|
d0323646c5 | ||
|
|
2331979b65 | ||
|
|
c12675698b | ||
|
|
abdf8a43e7 | ||
|
|
3bba720f67 | ||
|
|
46f3b2ff0e | ||
|
|
6c2fba2b3a | ||
|
|
916e050585 | ||
|
|
5b3e3f047e | ||
| b03e2d020f | |||
|
|
cb9b8ed6fd | ||
|
|
7490a3b324 | ||
|
|
3f4b341c33 | ||
|
|
cef9dfa34d | ||
|
|
95cbaea69a | ||
|
|
17b98f83ff | ||
|
|
4261a5a97d | ||
|
|
91acf4d2bc | ||
|
|
f713124154 | ||
|
|
4bbe9aaaa3 | ||
|
|
07185fdb46 | ||
|
|
178cda5402 | ||
|
|
3c094cf201 | ||
|
|
66084f9e96 | ||
|
|
c1203e8989 | ||
|
|
5be1edfa71 | ||
|
|
6005f20c5e | ||
|
|
8fe6e8be74 | ||
|
|
f2a0c7608e | ||
|
|
29c7dc54e3 | ||
|
|
d8d91e9270 | ||
|
|
02b3788dc9 | ||
|
|
a7f21da8da | ||
|
|
287ee4db37 | ||
|
|
0a4368ba7f | ||
|
|
656d5038fe | ||
|
|
c34811df83 | ||
|
|
98bc6294e6 | ||
|
|
2054b9ec97 | ||
|
|
b398da58e1 | ||
|
|
7e400ed761 | ||
|
|
bea1fd230a | ||
|
|
a2b7bfb253 | ||
|
|
646c04eba9 | ||
|
|
1bd2b83bca | ||
|
|
d6134a7407 | ||
|
|
c3011e87eb | ||
|
|
e811bf3e4a | ||
|
|
b3ed5703a8 | ||
|
|
f6e073bb41 | ||
|
|
b6651c4bdc | ||
|
|
bfea40c643 | ||
|
|
c8a52321a5 | ||
|
|
129583d19a | ||
|
|
c2bb174574 | ||
|
|
551f9083e9 | ||
|
|
c36c8ab6f9 | ||
|
|
6fd3bc8a3b | ||
|
|
4005af2040 | ||
|
|
20150a81b5 | ||
|
|
e4c165cd18 | ||
|
|
366a441cf2 | ||
|
|
ec4fe76856 | ||
|
|
173fa23e80 | ||
|
|
b6e994844e | ||
|
|
9a4899558e | ||
|
|
b1675ae0bf | ||
|
|
8b81308bd2 | ||
|
|
cc7d7361d4 | ||
|
|
730491ffed | ||
|
|
9753920595 | ||
|
|
2fc914214c | ||
|
|
ddb4ec944d | ||
|
|
c2723861fa | ||
|
|
c82ae399b7 | ||
|
|
c163cfe234 | ||
|
|
72e75e7858 | ||
|
|
c9af4fb420 | ||
|
|
27ae48991c | ||
|
|
65a7d530cc | ||
|
|
7866a5a369 | ||
|
|
0dcaf2ce09 | ||
|
|
dd6b80ee71 | ||
|
|
4c944c8c72 | ||
|
|
e29e8d8049 | ||
|
|
e1094b9be6 | ||
|
|
fc50bf587f | ||
|
|
11cee190b0 | ||
|
|
21c4907e44 | ||
|
|
951635e7f8 | ||
|
|
2a849dde38 | ||
|
|
caf2f753a5 | ||
|
|
2d224c0d67 | ||
|
|
e925d8c684 | ||
|
|
a6a40a2ad5 | ||
|
|
baa0cc1644 | ||
|
|
db7d53532a | ||
|
|
6985b76e49 | ||
|
|
745cea9617 | ||
|
|
d00089c625 | ||
|
|
0f7514b5bd | ||
|
|
95cd86d103 | ||
|
|
85b391a4d2 | ||
|
|
e2db17c326 | ||
|
|
741963275e | ||
|
|
541627183b | ||
|
|
cd6a919145 | ||
|
|
bb645ce6f6 | ||
|
|
1040f21ca6 | ||
|
|
fead7c6ae9 | ||
|
|
15f589c09d | ||
| c4b4b72947 | |||
| 99f785a7c3 | |||
| c280a661a1 | |||
| b37c2094ed | |||
| e6470719bb | |||
| 6260d29dc7 | |||
| 7aa4a57257 | |||
| 7324aabbd6 | |||
| 0b8f6e69cf | |||
| bd1b6ee23e | |||
| 58e2068170 | |||
| 45ef0b8bc9 | |||
| ff011f6452 | |||
| d3c96184b8 |
4
.gitignore
vendored
4
.gitignore
vendored
@ -44,4 +44,6 @@ shared-state
|
|||||||
|
|
||||||
*.zip
|
*.zip
|
||||||
|
|
||||||
vendor
|
vendor
|
||||||
|
|
||||||
|
grpc_server/gen
|
||||||
@ -3,7 +3,7 @@ package constants
|
|||||||
// 订单类型
|
// 订单类型
|
||||||
const (
|
const (
|
||||||
DELIVERYMETHODDIRECTMAIL int64 = 1
|
DELIVERYMETHODDIRECTMAIL int64 = 1
|
||||||
DELIVERYMETHODDSCLOUDSTORE int64 = 1
|
DELIVERYMETHODDSCLOUDSTORE int64 = 2
|
||||||
)
|
)
|
||||||
|
|
||||||
// 货币
|
// 货币
|
||||||
@ -23,8 +23,8 @@ type ExchangeRateUnit interface{}
|
|||||||
type PayMethods string
|
type PayMethods string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PAYMETHODCARD PayMethods = "CARD"
|
PAY_METHOD_CARD PayMethods = "CARD"
|
||||||
PayMethodVISA PayMethods = "VISA"
|
PayMethodVISA PayMethods = "VISA"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 支付状态
|
// 支付状态
|
||||||
@ -56,18 +56,21 @@ const (
|
|||||||
type OrderStatusCode int64
|
type OrderStatusCode int64
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ORDERSTATUSUNPAIDDEPOSIT OrderStatusCode = 0 // 0,未支付定金
|
ORDER_STATUS_UNPAIDDEPOSIT OrderStatusCode = 0 // 0,未支付定金
|
||||||
ORDERSTATUSDIRECTMAILORDERED OrderStatusCode = 10100 // 10100,直邮单--已下单
|
ORDER_STATUS_DIRECTMAIL_ORDERED OrderStatusCode = 10100 // 10100,直邮单--已下单
|
||||||
ORDERSTATUSDIRECTMAILCANCEL OrderStatusCode = 10101 // 10101,直邮单--已取消
|
ORDER_STATUS_DIRECTMAIL_ORDEREDMAINING OrderStatusCode = 10100001 // 10100001,直邮单--已下单--尾款
|
||||||
ORDERSTATUSDIRECTMAILSTARTPRODUCTION OrderStatusCode = 10200 // 10200,直邮单--开始生产
|
ORDER_STATUS_DIRECTMAIL_CANCEL OrderStatusCode = 10101 // 10101,直邮单--已取消
|
||||||
ORDERSTATUSDIRECTMAILCOMPLETEPRODUCTION OrderStatusCode = 10300 // 10300,直邮单--生产完成
|
ORDER_STATUS_DIRECTMAIL_STARTPRODUCTION OrderStatusCode = 10200 // 10200,直邮单--开始生产
|
||||||
ORDERSTATUSDIRECTMAILSHIPPED OrderStatusCode = 10400 // 10400,直邮单--已发货
|
ORDER_STATUS_DIRECTMAIL_COMPLETEPRODUCTION OrderStatusCode = 10300 // 10300,直邮单--生产完成
|
||||||
ORDERSTATUSDIRECTMAILARRIVED OrderStatusCode = 10500 // 10500,直邮单--已到达
|
ORDER_STATUS_DIRECTMAIL_SHIPPED OrderStatusCode = 10400 // 10400,直邮单--已发货
|
||||||
ORDERSTATUSCLOUDSTOREORDERED OrderStatusCode = 20100 // 20100,云仓单--已下单
|
ORDER_STATUS_DIRECTMAIL_ARRIVED OrderStatusCode = 10500 // 10500,直邮单--已到达
|
||||||
ORDERSTATUSCLOUDSTORECANCEL OrderStatusCode = 20101 // 20101,云仓单--已取消
|
ORDER_STATUS_CLOUDSTORE_ORDERED OrderStatusCode = 20100 // 20100,云仓单--已下单
|
||||||
ORDERSTATUSCLOUDSTORESTARTPRODUCTION OrderStatusCode = 20200 // 20200,云仓单--开始生产
|
ORDER_STATUS_CLOUDSTORE_ORDEREDMAINING OrderStatusCode = 20100001 // 20100001,云仓单--已下单-尾款
|
||||||
ORDERSTATUSCLOUDSTOREOMPLETEPRODUCTION OrderStatusCode = 20300 // 20300,云仓单--生产完成
|
ORDER_STATUS_CLOUDSTORE_CANCEL OrderStatusCode = 20101 // 20101,云仓单--已取消
|
||||||
ORDERSTATUSCLOUDSTOREARRIVEDWAREHOUSE OrderStatusCode = 20400 // 20400,云仓单--直达仓库
|
ORDER_STATUS_CLOUDSTORE_STARTPRODUCTION OrderStatusCode = 20200 // 20200,云仓单--开始生产
|
||||||
|
ORDER_STATUS_CLOUDSTORE_COMPLETEPRODUCTION OrderStatusCode = 20300 // 20300,云仓单--生产完成
|
||||||
|
ORDER_STATUS_CLOUDSTORE_ARRIVEDWAREHOUSE OrderStatusCode = 20400 // 20400,云仓单--直达仓库
|
||||||
|
ORDER_STATUS_COMPLETE OrderStatusCode = 30000 // 30000,订单完成
|
||||||
)
|
)
|
||||||
|
|
||||||
// 订单状态名称
|
// 订单状态名称
|
||||||
@ -85,33 +88,35 @@ var OrderStatusUserCLOUDSTORE []OrderStatusCode
|
|||||||
func init() {
|
func init() {
|
||||||
// 订单状态名称
|
// 订单状态名称
|
||||||
PayStatusMessage = make(map[PayStatusCode]string)
|
PayStatusMessage = make(map[PayStatusCode]string)
|
||||||
PayStatusMessage[PAYSTATUSUNPAID] = "Paid"
|
PayStatusMessage[PAYSTATUSUNPAID] = "Unpaid"
|
||||||
PayStatusMessage[PAYSTATUSPAID] = "Unpaid"
|
PayStatusMessage[PAYSTATUSPAID] = "Paid"
|
||||||
PayStatusMessage[PAYSTATUSREFUNDED] = "Refunded"
|
PayStatusMessage[PAYSTATUSREFUNDED] = "Refunded"
|
||||||
|
|
||||||
// 订单状态名称
|
// 订单状态名称
|
||||||
OrderStatusMessage = make(map[OrderStatusCode]string)
|
OrderStatusMessage = make(map[OrderStatusCode]string)
|
||||||
OrderStatusMessage[ORDERSTATUSUNPAIDDEPOSIT] = "未支付定金"
|
OrderStatusMessage[ORDER_STATUS_UNPAIDDEPOSIT] = "未支付定金"
|
||||||
|
|
||||||
OrderStatusMessage[ORDERSTATUSDIRECTMAILORDERED] = "直邮单--已下单"
|
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_ORDERED] = "直邮单--已下单"
|
||||||
OrderStatusMessage[ORDERSTATUSDIRECTMAILSTARTPRODUCTION] = "直邮单--开始生产"
|
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_STARTPRODUCTION] = "直邮单--开始生产"
|
||||||
OrderStatusMessage[ORDERSTATUSDIRECTMAILCOMPLETEPRODUCTION] = "直邮单--生产完成"
|
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_COMPLETEPRODUCTION] = "直邮单--生产完成"
|
||||||
OrderStatusMessage[ORDERSTATUSDIRECTMAILSHIPPED] = "直邮单--已发货"
|
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_SHIPPED] = "直邮单--已发货"
|
||||||
OrderStatusMessage[ORDERSTATUSDIRECTMAILARRIVED] = "直邮单--已到达"
|
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_ARRIVED] = "直邮单--已到达"
|
||||||
|
|
||||||
OrderStatusMessage[ORDERSTATUSCLOUDSTOREORDERED] = "云仓单--已下单"
|
OrderStatusMessage[ORDER_STATUS_CLOUDSTORE_ORDERED] = "云仓单--已下单"
|
||||||
OrderStatusMessage[ORDERSTATUSCLOUDSTORESTARTPRODUCTION] = "云仓单--开始生产"
|
OrderStatusMessage[ORDER_STATUS_CLOUDSTORE_STARTPRODUCTION] = "云仓单--开始生产"
|
||||||
OrderStatusMessage[ORDERSTATUSCLOUDSTOREOMPLETEPRODUCTION] = "云仓单--生产完成"
|
OrderStatusMessage[ORDER_STATUS_CLOUDSTORE_COMPLETEPRODUCTION] = "云仓单--生产完成"
|
||||||
OrderStatusMessage[ORDERSTATUSCLOUDSTOREARRIVEDWAREHOUSE] = "云仓单--直达仓库"
|
OrderStatusMessage[ORDER_STATUS_CLOUDSTORE_ARRIVEDWAREHOUSE] = "云仓单--直达仓库"
|
||||||
|
|
||||||
|
OrderStatusMessage[ORDER_STATUS_COMPLETE] = "订单完成"
|
||||||
|
|
||||||
// 订单状态--用户可见--直邮
|
// 订单状态--用户可见--直邮
|
||||||
OrderStatusUserDIRECTMAIL = []OrderStatusCode{
|
OrderStatusUserDIRECTMAIL = []OrderStatusCode{
|
||||||
ORDERSTATUSUNPAIDDEPOSIT,
|
ORDER_STATUS_UNPAIDDEPOSIT, ORDER_STATUS_COMPLETE,
|
||||||
ORDERSTATUSDIRECTMAILORDERED, ORDERSTATUSDIRECTMAILSTARTPRODUCTION, ORDERSTATUSDIRECTMAILCOMPLETEPRODUCTION, ORDERSTATUSDIRECTMAILSHIPPED, ORDERSTATUSDIRECTMAILARRIVED,
|
ORDER_STATUS_DIRECTMAIL_ORDERED, ORDER_STATUS_DIRECTMAIL_STARTPRODUCTION, ORDER_STATUS_DIRECTMAIL_COMPLETEPRODUCTION, ORDER_STATUS_DIRECTMAIL_SHIPPED, ORDER_STATUS_DIRECTMAIL_ARRIVED,
|
||||||
}
|
}
|
||||||
// 订单状态--用户可见--云仓
|
// 订单状态--用户可见--云仓
|
||||||
OrderStatusUserCLOUDSTORE = []OrderStatusCode{
|
OrderStatusUserCLOUDSTORE = []OrderStatusCode{
|
||||||
ORDERSTATUSUNPAIDDEPOSIT,
|
ORDER_STATUS_UNPAIDDEPOSIT, ORDER_STATUS_COMPLETE,
|
||||||
ORDERSTATUSCLOUDSTOREORDERED, ORDERSTATUSCLOUDSTORESTARTPRODUCTION, ORDERSTATUSCLOUDSTOREOMPLETEPRODUCTION, ORDERSTATUSCLOUDSTOREARRIVEDWAREHOUSE,
|
ORDER_STATUS_CLOUDSTORE_ORDERED, ORDER_STATUS_CLOUDSTORE_STARTPRODUCTION, ORDER_STATUS_CLOUDSTORE_COMPLETEPRODUCTION, ORDER_STATUS_CLOUDSTORE_ARRIVEDWAREHOUSE,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
8
env.yaml
8
env.yaml
@ -5,3 +5,11 @@ username: ...
|
|||||||
password: ...
|
password: ...
|
||||||
namespace: fs_server_api_dev
|
namespace: fs_server_api_dev
|
||||||
group: FS-SERVER-API
|
group: FS-SERVER-API
|
||||||
|
|
||||||
|
proxyserver:
|
||||||
|
key: /opt/server.dev.fusenpack.com.key
|
||||||
|
pem: /opt/server.dev.fusenpack.com.pem
|
||||||
|
|
||||||
|
serverbackend:
|
||||||
|
key: /opt/serverbackend.dev.fusenpack.com.key
|
||||||
|
pem: /opt/serverbackend.dev.fusenpack.com.pem
|
||||||
2
go.mod
2
go.mod
@ -18,7 +18,7 @@ require (
|
|||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||||
github.com/streadway/amqp v1.1.0
|
github.com/streadway/amqp v1.1.0
|
||||||
github.com/stripe/stripe-go/v74 v74.26.0
|
github.com/stripe/stripe-go/v75 v75.7.0
|
||||||
github.com/zeromicro/go-zero v1.5.4
|
github.com/zeromicro/go-zero v1.5.4
|
||||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8
|
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8
|
||||||
golang.org/x/oauth2 v0.10.0
|
golang.org/x/oauth2 v0.10.0
|
||||||
|
|||||||
4
go.sum
4
go.sum
@ -548,8 +548,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
|
|||||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
github.com/stripe/stripe-go/v74 v74.26.0 h1:enbhLtjKGWvJKcGM0f2CazqFSXzpHXcQ42nG2PNsWK0=
|
github.com/stripe/stripe-go/v75 v75.7.0 h1:Zk7trlj0kClZOwnpjGz7FgVQRBI0Koi28/eaNATgAs0=
|
||||||
github.com/stripe/stripe-go/v74 v74.26.0/go.mod h1:f9L6LvaXa35ja7eyvP6GQswoaIPaBRvGAimAO+udbBw=
|
github.com/stripe/stripe-go/v75 v75.7.0/go.mod h1:wT44gah+eCY8Z0aSpY/vQlYYbicU9uUAbAqdaUxxDqE=
|
||||||
github.com/tidwall/gjson v1.12.0 h1:61wEp/qfvFnqKH/WCI3M8HuRut+mHT6Mr82QrFmM2SY=
|
github.com/tidwall/gjson v1.12.0 h1:61wEp/qfvFnqKH/WCI3M8HuRut+mHT6Mr82QrFmM2SY=
|
||||||
github.com/tidwall/gjson v1.12.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
github.com/tidwall/gjson v1.12.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||||
|
|||||||
@ -2,24 +2,28 @@ package gmodel
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// fs_address 用户地址表
|
// fs_address 用户地址表
|
||||||
type FsAddress struct {
|
type FsAddress struct {
|
||||||
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"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:"index;default:0;" json:"user_id"` // 用户ID
|
||||||
Name *string `gorm:"default:'';" json:"name"` // 地址名称
|
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异常
|
||||||
IsDefault *int64 `gorm:"index;default:0;" json:"is_default"` // 1默认地址,0非默认地址
|
IsDefault *int64 `gorm:"index;default:0;" json:"is_default"` // 1默认地址,0非默认地址
|
||||||
|
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` // 创建时间
|
||||||
|
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
|
||||||
|
|||||||
@ -2,17 +2,19 @@ package gmodel
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (a *FsAddressModel) GetOne(ctx context.Context, id int64, userId int64) (resp *FsAddress, err error) {
|
func (a *FsAddressModel) GetOne(ctx context.Context, addressId int64, userId int64) (resp *FsAddress, err error) {
|
||||||
err = a.db.WithContext(ctx).Model(&FsAddress{}).Where("`id` = ? and `user_id` = ? and `status` = ? ", id, userId, 1).Take(&resp).Error
|
err = a.db.WithContext(ctx).Model(&FsAddress{}).Where("`address_id` = ? and `user_id` = ? and `status` = ? ", addressId, userId, 1).Take(&resp).Error
|
||||||
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 []FsAddress, err error) {
|
||||||
err = a.db.WithContext(ctx).Model(&FsAddress{}).Where("`user_id` = ? and `status` = ?", userId, 1).Order("`id` DESC").Find(&resp).Error
|
err = a.db.WithContext(ctx).Model(&FsAddress{}).Where("`user_id` = ? and `status` = ?", userId, 1).Order("`ltime` DESC").Find(&resp).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -21,25 +23,42 @@ func (a *FsAddressModel) GetUserAllAddress(ctx context.Context, userId int64) (r
|
|||||||
|
|
||||||
func (a *FsAddressModel) CreateOne(ctx context.Context, address *FsAddress) (result *FsAddress, err error) {
|
func (a *FsAddressModel) CreateOne(ctx context.Context, address *FsAddress) (result *FsAddress, err error) {
|
||||||
|
|
||||||
err = a.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
err = a.db.WithContext(ctx).Model(&FsAddress{}).Transaction(func(tx *gorm.DB) error {
|
||||||
// now := time.Now().UTC().Unix()
|
now := time.Now().UTC()
|
||||||
result = &FsAddress{
|
result = &FsAddress{
|
||||||
UserId: address.UserId,
|
UserId: address.UserId,
|
||||||
Name: address.Name,
|
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,
|
||||||
IsDefault: address.IsDefault,
|
IsDefault: address.IsDefault,
|
||||||
|
Ctime: &now,
|
||||||
|
Utime: &now,
|
||||||
|
Ltime: &now,
|
||||||
}
|
}
|
||||||
|
|
||||||
return tx.Create(result).Error
|
// lastOne := &FsAddress{}
|
||||||
|
// err = tx.Where("user_id = ?", lastOne.UserId).Order("ltime ASC").Take(&lastOne).Error
|
||||||
|
// if err == gorm.ErrRecordNotFound {
|
||||||
|
// result.Ltime = &now
|
||||||
|
// return tx.Model(&FsAddress{}).Create(result).Error
|
||||||
|
// }
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 根据lastOne处理时间
|
||||||
|
|
||||||
|
// ltime := (*lastOne.Ltime).Add(-time.Second)
|
||||||
|
// result.Ltime = <ime
|
||||||
|
return tx.Model(&FsAddress{}).Create(result).Error
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -49,15 +68,47 @@ func (a *FsAddressModel) CreateOne(ctx context.Context, address *FsAddress) (res
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *FsAddressModel) UpdateAddAddress(ctx context.Context, address *FsAddress) (err error) {
|
func (a *FsAddressModel) UpdateAddress(ctx context.Context, address *FsAddress) (err error) {
|
||||||
err = a.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
err = a.db.WithContext(ctx).Model(&FsAddress{}).Transaction(func(tx *gorm.DB) error {
|
||||||
if *address.IsDefault > 0 {
|
err = tx.
|
||||||
err = tx.Model(&FsAddress{}).Where("user_id = ? and is_default = 1 ", address.UserId).Update("is_default", 0).Error
|
Where("user_id = ? and address_id = ? and status = 1 ", address.UserId, address.AddressId).
|
||||||
if err != nil {
|
Updates(address).Error
|
||||||
return err
|
if err != nil {
|
||||||
}
|
return err
|
||||||
}
|
}
|
||||||
return tx.Model(&FsAddress{}).Where("id = ? and user_id = ?", address.Id, address.UserId).Omit("id", "user_id").Updates(address).Error
|
return err
|
||||||
})
|
})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *FsAddressModel) SettingUserDefaultAddress(ctx context.Context, userId int64, addressId int64) (err error) {
|
||||||
|
|
||||||
|
err = a.db.WithContext(ctx).Model(&FsAddress{}).Transaction(func(tx *gorm.DB) error {
|
||||||
|
|
||||||
|
now := time.Now().UTC()
|
||||||
|
|
||||||
|
err = tx.Model(&FsAddress{}).Where(" `user_id` = ? and `status` = ? and `address_id` = ? ", userId, 1, addressId).
|
||||||
|
UpdateColumn("ltime", now.AddDate(250, 0, 0)).
|
||||||
|
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)).
|
||||||
|
UpdateColumn("ltime", now).Error
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *FsAddressModel) DeleteOne(ctx context.Context, addressId int64, userId int64) (err error) {
|
||||||
|
err = a.db.WithContext(ctx).Model(&FsAddress{}).
|
||||||
|
Where("`address_id` = ? and `user_id` = ? and `status` = ? ", addressId, userId, 1).
|
||||||
|
UpdateColumn("status", 0).Error
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|||||||
@ -2,17 +2,18 @@ package gmodel
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// fs_change_code 忘记密码code表
|
// fs_change_code 忘记密码code表
|
||||||
type FsChangeCode struct {
|
type FsChangeCode 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
|
||||||
Email *string `gorm:"default:'';" json:"email"` //
|
Email *string `gorm:"default:'';" json:"email"` //
|
||||||
Code *string `gorm:"default:'';" json:"code"` //
|
Code *string `gorm:"default:'';" json:"code"` //
|
||||||
CreatedAt *int64 `gorm:"default:0;" json:"created_at"` // 创建时间
|
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` //
|
||||||
IsUse *int64 `gorm:"default:0;" json:"is_use"` // 是否使用 1已使用 0未使用
|
IsUse *int64 `gorm:"default:0;" json:"is_use"` // 是否使用 1已使用 0未使用
|
||||||
Metadata *[]byte `gorm:"default:'';" json:"metadata"` //
|
Metadata *[]byte `gorm:"default:'';" json:"metadata"` //
|
||||||
Module *string `gorm:"default:'logo';" json:"module"` //
|
Module *string `gorm:"default:'logo';" json:"module"` //
|
||||||
}
|
}
|
||||||
type FsChangeCodeModel struct {
|
type FsChangeCodeModel struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
|||||||
@ -2,20 +2,17 @@ package gmodel
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// fs_guest 游客表
|
// fs_guest 游客表
|
||||||
type FsGuest struct {
|
type FsGuest struct {
|
||||||
GuestId int64 `gorm:"primary_key;default:0;auto_increment;" json:"guest_id"` // ID
|
GuestId int64 `gorm:"primary_key;default:0;auto_increment;" json:"guest_id"` // ID
|
||||||
AuthKey *string `gorm:"default:'';" json:"auth_key"` // jwt token
|
AuthKey *string `gorm:"default:'';" json:"auth_key"` // jwt token
|
||||||
Status *int64 `gorm:"index;default:1;" json:"status"` // 1正常 0不正常
|
Status *int64 `gorm:"index;default:1;" json:"status"` // 1正常 0不正常
|
||||||
IsDel *int64 `gorm:"index;default:0;" json:"is_del"` // 是否删除 1删除
|
IsDel *int64 `gorm:"index;default:0;" json:"is_del"` // 是否删除 1删除
|
||||||
CreatedAt *int64 `gorm:"index;default:0;" json:"created_at"` // 添加时间
|
Ctime *time.Time `gorm:"index;default:'0000-00-00 00:00:00';" json:"ctime"` //
|
||||||
UpdatedAt *int64 `gorm:"default:0;" json:"updated_at"` // 更新时间
|
Utime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"utime"` //
|
||||||
IsOpenRender *int64 `gorm:"default:0;" json:"is_open_render"` // 是否打开个性化渲染(1:开启,0:关闭)
|
|
||||||
IsThousandFace *int64 `gorm:"default:0;" json:"is_thousand_face"` // 是否已经存在千人千面(1:存在,0:不存在)
|
|
||||||
IsLowRendering *int64 `gorm:"default:0;" json:"is_low_rendering"` // 是否开启低渲染模型渲染
|
|
||||||
IsRemoveBg *int64 `gorm:"default:1;" json:"is_remove_bg"` // 用户上传logo是否去除背景
|
|
||||||
}
|
}
|
||||||
type FsGuestModel struct {
|
type FsGuestModel struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
|||||||
@ -12,11 +12,11 @@ import (
|
|||||||
func (m *FsGuestModel) GenerateGuestID(ctx context.Context, AccessSecret uint64) (authKey string, err error) {
|
func (m *FsGuestModel) GenerateGuestID(ctx context.Context, AccessSecret uint64) (authKey string, err error) {
|
||||||
|
|
||||||
err = m.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
err = m.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||||
now := time.Now().UTC().Unix()
|
now := time.Now().UTC()
|
||||||
var record = &FsGuest{}
|
var record = &FsGuest{}
|
||||||
tx.Create(record)
|
tx.Create(record)
|
||||||
|
|
||||||
authKey, err = auth.GenerateJwtTokenUint64(AccessSecret, now, 31536000, 0, int64(record.GuestId))
|
authKey, err = auth.GenerateJwtTokenUint64(AccessSecret, now.Unix(), 31536000, 0, int64(record.GuestId))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
err = tx.Rollback().Error
|
err = tx.Rollback().Error
|
||||||
@ -26,7 +26,7 @@ func (m *FsGuestModel) GenerateGuestID(ctx context.Context, AccessSecret uint64)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
record.AuthKey = &authKey
|
record.AuthKey = &authKey
|
||||||
record.CreatedAt = &now
|
record.Ctime = &now
|
||||||
err = tx.Updates(record).Error
|
err = tx.Updates(record).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
|
|||||||
@ -40,7 +40,7 @@ type PayInfo struct {
|
|||||||
Metadata map[string]interface{} `json:"metadata"` // 额外参数
|
Metadata map[string]interface{} `json:"metadata"` // 额外参数
|
||||||
PayAmount AmountInfo `json:"pay_amount"` // 金额明细
|
PayAmount AmountInfo `json:"pay_amount"` // 金额明细
|
||||||
PayMethod string `json:"pay_method"` // 交易方式
|
PayMethod string `json:"pay_method"` // 交易方式
|
||||||
PayTime **time.Time `json:"pay_time"` // 支付时间
|
PayTime *time.Time `json:"pay_time"` // 支付时间
|
||||||
Status PayStatus `json:"status"` // 当前状态
|
Status PayStatus `json:"status"` // 当前状态
|
||||||
StatusLink []PayStatus `json:"status_link"` // 状态链路
|
StatusLink []PayStatus `json:"status_link"` // 状态链路
|
||||||
TradeNo string `json:"trade_no"` // 支付交易号
|
TradeNo string `json:"trade_no"` // 支付交易号
|
||||||
@ -95,23 +95,26 @@ type OrderStatus struct {
|
|||||||
|
|
||||||
// 订单商品
|
// 订单商品
|
||||||
type OrderProduct struct {
|
type OrderProduct struct {
|
||||||
TotalPrice AmountInfo `json:"amount"` // 商品总价
|
TotalPrice AmountInfo `json:"total_price"` // 商品总价
|
||||||
ExpectedDeliveryTime *time.Time `json:"expected_delivery_time"` // 预计到货时间
|
ExpectedDeliveryTime *time.Time `json:"expected_delivery_time"` // 预计到货时间
|
||||||
PurchaseQuantity int64 `json:"purchase_quantity"` // 购买数量
|
PurchaseQuantity PurchaseQuantity `json:"purchase_quantity"` // 购买数量
|
||||||
ProductID int64 `json:"product_id"` // 商品ID
|
ProductID int64 `json:"product_id"` // 商品ID
|
||||||
ProductName string `json:"product_name"` // 商品名称
|
ProductName string `json:"product_name"` // 商品名称
|
||||||
ItemPrice AmountInfo `json:"product_price"` // 商品单价
|
ItemPrice AmountInfo `json:"item_price"` // 商品单价
|
||||||
ProductSnapshot interface{} `json:"product_snapshot"` // 商品快照
|
ProductSnapshot interface{} `json:"product_snapshot"` // 商品快照
|
||||||
ShoppingCartSnapshot *FsShoppingCart `json:"shopping_cart_snapshot"` // 购物车快照
|
ShoppingCartSnapshot *FsShoppingCartData `json:"shopping_cart_snapshot"` // 购物车快照
|
||||||
ProductCover string `json:"product_cover"` // 商品封面
|
ProductCover string `json:"product_cover"` // 商品封面
|
||||||
ProductCoverMetadata map[string]interface{} `json:"product_cover_metadata"` // 商品封面
|
ProductCoverMetadata map[string]interface{} `json:"product_cover_metadata"` // 商品封面
|
||||||
ProductSn string `json:"product_sn"` // 商品编码
|
ProductSn string `json:"product_sn"` // 商品编码
|
||||||
DiyInformation *UserDiyInformation `json:"diy_information"`
|
DiyInformation *UserDiyInformation `json:"diy_information"`
|
||||||
SizeInfo *OrderProductSizeInfo `json:"size_info"`
|
SizeInfo *OrderProductSizeInfo `json:"size_info"`
|
||||||
FittingInfo *OrderProductFittingInfo `json:"fitting_info"`
|
FittingInfo *OrderProductFittingInfo `json:"fitting_info"`
|
||||||
StepNum []int `json:"step_num"` // 阶梯数量
|
|
||||||
IsHighlyCustomized int64 `json:"is_highly_customized"`
|
IsHighlyCustomized int64 `json:"is_highly_customized"`
|
||||||
}
|
}
|
||||||
|
type PurchaseQuantity struct {
|
||||||
|
Current interface{} `json:"current"`
|
||||||
|
Initiate interface{} `json:"initiate"`
|
||||||
|
}
|
||||||
|
|
||||||
type OrderProductSizeInfo struct {
|
type OrderProductSizeInfo struct {
|
||||||
SizeID int64 `json:"size_id"`
|
SizeID int64 `json:"size_id"`
|
||||||
|
|||||||
@ -36,6 +36,7 @@ type FsProduct struct {
|
|||||||
RecommendProductSort *string `gorm:"default:'';" json:"recommend_product_sort"` //
|
RecommendProductSort *string `gorm:"default:'';" json:"recommend_product_sort"` //
|
||||||
SceneIds *string `gorm:"default:'';" json:"scene_ids"` //
|
SceneIds *string `gorm:"default:'';" json:"scene_ids"` //
|
||||||
IsCustomization *int64 `gorm:"default:0;" json:"is_customization"` // 是否可定制
|
IsCustomization *int64 `gorm:"default:0;" json:"is_customization"` // 是否可定制
|
||||||
|
Unit *string `gorm:"default:'';" json:"unit"` //
|
||||||
}
|
}
|
||||||
type FsProductModel struct {
|
type FsProductModel struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
|||||||
@ -2,30 +2,34 @@ package gmodel
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// fs_product_model3d 产品模型表
|
// fs_product_model3d 产品模型表
|
||||||
type FsProductModel3d struct {
|
type FsProductModel3d struct {
|
||||||
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` //
|
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` //
|
||||||
ProductId *int64 `gorm:"index;default:0;" json:"product_id"` // 产品ID
|
ProductId *int64 `gorm:"index;default:0;" json:"product_id"` // 产品ID
|
||||||
Tag *int64 `gorm:"default:1;" json:"tag"` // 类别(1:模型,2:配件,3:场景)
|
Tag *int64 `gorm:"default:1;" json:"tag"` // 类别(1:模型,2:配件,3:场景)
|
||||||
Title *string `gorm:"default:'';" json:"title"` // 标题
|
Title *string `gorm:"default:'';" json:"title"` // 标题
|
||||||
Name *string `gorm:"default:'';" json:"name"` // 详情页展示名称
|
Name *string `gorm:"default:'';" json:"name"` // 详情页展示名称
|
||||||
ModelInfo *string `gorm:"default:'';" json:"model_info"` // 模型详情
|
ModelInfo *string `gorm:"default:'';" json:"model_info"` // 模型详情
|
||||||
MaterialId *int64 `gorm:"default:0;" json:"material_id"` // 材质ID
|
MaterialId *int64 `gorm:"default:0;" json:"material_id"` // 材质ID
|
||||||
SizeId *int64 `gorm:"default:0;" json:"size_id"` // 尺寸ID
|
SizeId *int64 `gorm:"default:0;" json:"size_id"` // 尺寸ID
|
||||||
Sort *int64 `gorm:"default:0;" json:"sort"` // 排序
|
Sort *int64 `gorm:"default:0;" json:"sort"` // 排序
|
||||||
Light *int64 `gorm:"default:0;" json:"light"` // 灯光组
|
Light *int64 `gorm:"default:0;" json:"light"` // 灯光组
|
||||||
LightList *string `gorm:"default:'';" json:"light_list"` // 灯光备选项
|
LightList *string `gorm:"default:'';" json:"light_list"` // 灯光备选项
|
||||||
PartId *int64 `gorm:"default:0;" json:"part_id"` // 配件选项id(配件就是模型的id)
|
PartId *int64 `gorm:"default:0;" json:"part_id"` // 配件选项id(配件就是模型的id)
|
||||||
PartList *string `gorm:"default:'';" json:"part_list"` //
|
PartList *string `gorm:"default:'';" json:"part_list"` //
|
||||||
Status *int64 `gorm:"default:0;" json:"status"` // 状态位 显示 删除
|
Status *int64 `gorm:"default:0;" json:"status"` // 状态位 显示 删除
|
||||||
Ctime *int64 `gorm:"default:0;" 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"` //
|
||||||
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"` // 是否设置为云渲染模型
|
||||||
|
Utime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"utime"` //
|
||||||
|
StepPrice *[]byte `gorm:"default:'';" json:"step_price"` //
|
||||||
|
PackedUnit *int64 `gorm:"default:0;" json:"packed_unit"` // 被打包的数量单位
|
||||||
}
|
}
|
||||||
type FsProductModel3dModel struct {
|
type FsProductModel3dModel struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
|||||||
@ -4,8 +4,19 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 阶梯价结构
|
||||||
|
type StepPriceJsonStruct struct {
|
||||||
|
PriceRange []struct {
|
||||||
|
Label string `json:"label"`
|
||||||
|
Price int64 `json:"price"`
|
||||||
|
EndQuantity int64 `json:"end_quantity"`
|
||||||
|
StartQuantity int64 `json:"start_quantity"`
|
||||||
|
} `json:"price_range"`
|
||||||
|
MinBuyUnitsNum int64 `json:"min_buy_units_num"`
|
||||||
|
}
|
||||||
|
|
||||||
func (d *FsProductModel3dModel) FindOne(ctx context.Context, id int64, fields ...string) (resp *FsProductModel3d, err error) {
|
func (d *FsProductModel3dModel) FindOne(ctx context.Context, id int64, fields ...string) (resp *FsProductModel3d, err error) {
|
||||||
db := d.db.WithContext(ctx).Model(&FsProductModel3d{}).Where("`id` = ? ", id)
|
db := d.db.WithContext(ctx).Model(&FsProductModel3d{}).Where("`id` = ? and `status` =? ", id, 1)
|
||||||
if len(fields) > 0 {
|
if len(fields) > 0 {
|
||||||
db = db.Select(fields[0])
|
db = db.Select(fields[0])
|
||||||
}
|
}
|
||||||
@ -30,7 +41,7 @@ func (d *FsProductModel3dModel) GetAllByIdsWithoutStatus(ctx context.Context, id
|
|||||||
if len(ids) == 0 {
|
if len(ids) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
db := d.db.WithContext(ctx).Model(&FsProductModel3d{}).Where("`id` in (?)", ids)
|
db := d.db.WithContext(ctx).Model(&FsProductModel3d{}).Where("`id` in (?) and `status` = ?", ids, 1)
|
||||||
if len(fields) > 0 {
|
if len(fields) > 0 {
|
||||||
db = db.Select(fields[0])
|
db = db.Select(fields[0])
|
||||||
}
|
}
|
||||||
@ -69,13 +80,13 @@ func (d *FsProductModel3dModel) Get3dModelsByParam(ctx context.Context, req Get3
|
|||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
func (d *FsProductModel3dModel) Update(ctx context.Context, id int64, data *FsProductModel3d) error {
|
func (d *FsProductModel3dModel) Update(ctx context.Context, id int64, data *FsProductModel3d) error {
|
||||||
return d.db.WithContext(ctx).Where("`id` = ? ", id).Updates(&data).Error
|
return d.db.WithContext(ctx).Where("`id` = ? and `status` =? ", id, 1).Updates(&data).Error
|
||||||
}
|
}
|
||||||
func (d *FsProductModel3dModel) GetAllBySizeIdsTag(ctx context.Context, sizeIds []int64, tag int64, fields ...string) (resp []FsProductModel3d, err error) {
|
func (d *FsProductModel3dModel) GetAllBySizeIdsTag(ctx context.Context, sizeIds []int64, tag int64, fields ...string) (resp []FsProductModel3d, err error) {
|
||||||
if len(sizeIds) == 0 {
|
if len(sizeIds) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
db := d.db.WithContext(ctx).Model(&FsProductModel3d{}).Where("`size_id` in (?) and `tag` = ?", sizeIds, tag)
|
db := d.db.WithContext(ctx).Model(&FsProductModel3d{}).Where("`size_id` in (?) and `tag` = ? and `status` = ?", sizeIds, tag, 1)
|
||||||
if len(fields) != 0 {
|
if len(fields) != 0 {
|
||||||
db = db.Select(fields[0])
|
db = db.Select(fields[0])
|
||||||
}
|
}
|
||||||
@ -83,7 +94,7 @@ func (d *FsProductModel3dModel) GetAllBySizeIdsTag(ctx context.Context, sizeIds
|
|||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
func (d *FsProductModel3dModel) GetAll(ctx context.Context) (resp []FsProductModel3d, err error) {
|
func (d *FsProductModel3dModel) GetAll(ctx context.Context) (resp []FsProductModel3d, err error) {
|
||||||
err = d.db.WithContext(ctx).Model(&FsProductModel3d{}).Find(&resp).Error
|
err = d.db.WithContext(ctx).Model(&FsProductModel3d{}).Where("`status` = ?", 1).Find(&resp).Error
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +107,7 @@ func (d *FsProductModel3dModel) GetGroupPartListByProductIds(ctx context.Context
|
|||||||
if len(productIds) == 0 {
|
if len(productIds) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = d.db.WithContext(ctx).Model(&FsProductModel3d{}).
|
err = d.db.WithContext(ctx).Model(&FsProductModel3d{}).Where("`product_id` in(?) and `status` =? ", productIds, 1).
|
||||||
Select("product_id,group_concat(part_list) as part_list").
|
Select("product_id,group_concat(part_list) as part_list").
|
||||||
Group("product_id").Find(&resp).Error
|
Group("product_id").Find(&resp).Error
|
||||||
return resp, err
|
return resp, err
|
||||||
@ -120,3 +131,24 @@ func (d *FsProductModel3dModel) GetOneBySizeIdTag(ctx context.Context, sizeId in
|
|||||||
err = db.Take(&resp).Error
|
err = db.Take(&resp).Error
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *FsProductModel3dModel) GetAllByProductIdTag(ctx context.Context, productId int64, tag int64, fields ...string) (resp []FsProductModel3d, err error) {
|
||||||
|
db := d.db.WithContext(ctx).Model(&FsProductModel3d{}).
|
||||||
|
Where("`product_id` = ? and `tag` = ? and `status` = ?", productId, tag, 1).
|
||||||
|
Order("sort DESC")
|
||||||
|
if len(fields) != 0 {
|
||||||
|
db = db.Select(fields[0])
|
||||||
|
}
|
||||||
|
err = db.Find(&resp).Error
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
func (d *FsProductModel3dModel) FindOneByProductIdSizeIdTag(ctx context.Context, productId, sizeId, tag int64, fields ...string) (resp *FsProductModel3d, err error) {
|
||||||
|
db := d.db.WithContext(ctx).Model(&FsProductModel3d{}).
|
||||||
|
Where("`product_id` = ? and `size_id` = ? and `tag` = ? and `status` = ?", productId, sizeId, tag, 1).
|
||||||
|
Order("sort DESC")
|
||||||
|
if len(fields) != 0 {
|
||||||
|
db = db.Select(fields[0])
|
||||||
|
}
|
||||||
|
err = db.Take(&resp).Error
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package gmodel
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m *FsShoppingCartModel) TableName() string {
|
func (m *FsShoppingCartModel) TableName() string {
|
||||||
@ -11,10 +12,26 @@ func (m *FsShoppingCartModel) TableName() string {
|
|||||||
// 关联查询
|
// 关联查询
|
||||||
type RelaFsShoppingCart struct {
|
type RelaFsShoppingCart struct {
|
||||||
FsShoppingCart
|
FsShoppingCart
|
||||||
ShoppingCartProduct *RelaFsProduct `json:"shopping_cart_product" gorm:"foreignkey:product_id;references:id"`
|
ShoppingCartProduct *RelaFsProduct `json:"shopping_cart_product" gorm:"foreignkey:product_id;references:id"`
|
||||||
ShoppingCartProductPriceList []*FsProductPrice `json:"shopping_cart_product_price_list" gorm:"foreignkey:product_id;references:product_id"`
|
ShoppingCartProductModel3d *FsProductModel3d `json:"shopping_cart_product_model3d_list" gorm:"foreignkey:model_id;references:id"`
|
||||||
ShoppingCartProductModel3dList []*FsProductModel3d `json:"shopping_cart_product_model3d_list" gorm:"foreignkey:product_id;references:product_id"`
|
ShoppingCartProductModel3dFitting *FsProductModel3d `json:"shopping_cart_product_model3d_list_fitting" gorm:"foreignkey:fitting_id;references:id"`
|
||||||
ShoppingCartProductModel3dFitting *FsProductModel3d `json:"shopping_cart_product_model3d_list_fitting" gorm:"foreignkey:fitting_id;references:id"`
|
}
|
||||||
|
type FsShoppingCartData struct {
|
||||||
|
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // id
|
||||||
|
UserId *int64 `gorm:"default:0;" json:"user_id"` // 用户id
|
||||||
|
ProductId *int64 `gorm:"default:0;" json:"product_id"` // 产品id
|
||||||
|
TemplateId *int64 `gorm:"default:0;" json:"template_id"` // 模板id
|
||||||
|
ModelId *int64 `gorm:"default:0;" json:"model_id"` // 模型id
|
||||||
|
SizeId *int64 `gorm:"default:0;" json:"size_id"` // 尺寸id
|
||||||
|
LightId *int64 `gorm:"default:0;" json:"light_id"` // 灯光id
|
||||||
|
FittingId *int64 `gorm:"default:0;" json:"fitting_id"` // 配件id
|
||||||
|
PurchaseQuantity *int64 `gorm:"default:0;" json:"purchase_quantity"` // 购买数量
|
||||||
|
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是
|
||||||
|
IsHighlyCustomized *int64 `gorm:"default:0;" json:"is_highly_customized"` // 是否高度定制 0非 1是(针对客人高度定制只能后台增加如购物车)
|
||||||
|
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"` //
|
||||||
}
|
}
|
||||||
|
|
||||||
// 快照json数据结构
|
// 快照json数据结构
|
||||||
|
|||||||
@ -2,35 +2,28 @@ package gmodel
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// fs_user 用户表
|
// fs_user 用户表
|
||||||
type FsUser struct {
|
type FsUser 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
|
||||||
FaceId *string `gorm:"default:'0';" json:"face_id"` // facebook的userid
|
FaceId *string `gorm:"default:'0';" json:"face_id"` // facebook的userid
|
||||||
GoogleId *string `gorm:"default:'0';" json:"google_id"` // google的sub
|
GoogleId *string `gorm:"default:'0';" json:"google_id"` // google的sub
|
||||||
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
|
||||||
Username *string `gorm:"index;default:'';" json:"username"` //
|
Username *string `gorm:"index;default:'';" json:"username"` //
|
||||||
Company *string `gorm:"default:'';" json:"company"` // 公司名称
|
Company *string `gorm:"default:'';" json:"company"` // 公司名称
|
||||||
Mobile *string `gorm:"default:'';" json:"mobile"` // 手机号码
|
Mobile *string `gorm:"default:'';" json:"mobile"` //
|
||||||
PasswordHash *string `gorm:"default:'';" json:"password_hash"` //
|
PasswordHash *string `gorm:"default:'';" json:"password_hash"` //
|
||||||
VerificationToken *string `gorm:"default:'';" json:"verification_token"` //
|
VerificationToken *string `gorm:"default:'';" json:"verification_token"` //
|
||||||
PasswordResetToken *string `gorm:"default:'';" json:"password_reset_token"` //
|
PasswordResetToken *string `gorm:"default:'';" json:"password_reset_token"` //
|
||||||
Email *string `gorm:"unique_key;default:'';" json:"email"` // 邮箱
|
Email *string `gorm:"unique_key;default:'';" json:"email"` // 邮箱
|
||||||
Type *int64 `gorm:"default:0;" json:"type"` // 1普通餐厅 2连锁餐厅
|
Type *int64 `gorm:"default:0;" json:"type"` // 1普通餐厅 2连锁餐厅
|
||||||
Status *int64 `gorm:"default:1;" json:"status"` // 1正常 0不正常
|
Status *int64 `gorm:"default:1;" json:"status"` // 1正常 0不正常
|
||||||
IsDel *int64 `gorm:"default:0;" json:"is_del"` // 是否删除 1删除
|
IsDel *int64 `gorm:"default:0;" json:"is_del"` // 是否删除 1删除
|
||||||
CreatedAt *int64 `gorm:"default:0;" json:"created_at"` // 添加时间
|
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` //
|
||||||
UpdatedAt *int64 `gorm:"default:0;" json:"updated_at"` // 更新时间
|
Utime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"utime"` //
|
||||||
IsOrderStatusEmail *int64 `gorm:"default:0;" json:"is_order_status_email"` // 订单状态改变时是否接收邮件
|
|
||||||
IsEmailAdvertisement *int64 `gorm:"default:0;" json:"is_email_advertisement"` // 是否接收邮件广告
|
|
||||||
IsOrderStatusPhone *int64 `gorm:"default:0;" json:"is_order_status_phone"` // 订单状态改变是是否接收电话
|
|
||||||
IsPhoneAdvertisement *int64 `gorm:"default:0;" json:"is_phone_advertisement"` // 是否接收短信广告
|
|
||||||
IsOpenRender *int64 `gorm:"default:0;" json:"is_open_render"` // 是否打开个性化渲染(1:开启,0:关闭)
|
|
||||||
IsThousandFace *int64 `gorm:"default:0;" json:"is_thousand_face"` // 是否已经存在千人千面(1:存在,0:不存在)
|
|
||||||
IsLowRendering *int64 `gorm:"default:0;" json:"is_low_rendering"` //
|
|
||||||
IsRemoveBg *int64 `gorm:"default:1;" json:"is_remove_bg"` // 用户上传logo是否去除背景
|
|
||||||
}
|
}
|
||||||
type FsUserModel struct {
|
type FsUserModel struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
|||||||
@ -4,6 +4,9 @@ package gmodel
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"fusenapi/utils/fssql"
|
||||||
"fusenapi/utils/handlers"
|
"fusenapi/utils/handlers"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@ -42,3 +45,39 @@ func (p *FsUserInfoModel) CreateOrUpdate(gormDB *gorm.DB, req *FsUserInfo) (resp
|
|||||||
}
|
}
|
||||||
return req, err
|
return req, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *FsUserInfoModel) MergeMetadata(userId int64, meta any) error {
|
||||||
|
return fssql.MetadataModulePATCH(m.db, "profile", FsUserInfo{}, map[string]any{
|
||||||
|
"base": meta,
|
||||||
|
}, "user_id = ?", userId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *FsUserInfoModel) GetProfile(ctx context.Context, pkey string, userId int64) (map[string]any, error) {
|
||||||
|
|
||||||
|
var baseinfo map[string]any
|
||||||
|
tname := fssql.GetGormTableName(m.db, FsUserInfo{})
|
||||||
|
|
||||||
|
if pkey == "." {
|
||||||
|
pkey = ""
|
||||||
|
} else {
|
||||||
|
pkey = "." + pkey
|
||||||
|
}
|
||||||
|
|
||||||
|
rawsql := fmt.Sprintf("select JSON_EXTRACT(metadata,'$%s') as query from %s where user_id = ? and module = 'profile' order by ctime DESC limit 1", pkey, tname)
|
||||||
|
err := m.db.Raw(rawsql, userId).Take(&baseinfo).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
v, ok := baseinfo["query"].(string)
|
||||||
|
if !ok {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var info map[string]any
|
||||||
|
err = json.Unmarshal([]byte(v), &info)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return info, nil
|
||||||
|
}
|
||||||
|
|||||||
@ -4,14 +4,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
|
|
||||||
"fusenapi/utils/auth"
|
"fusenapi/utils/auth"
|
||||||
"fusenapi/utils/fssql"
|
"fusenapi/utils/fssql"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -66,28 +63,26 @@ func InheritGuestIdResource(tx *gorm.DB, userId, guestId int64, afterDo func(txR
|
|||||||
if guestId != 0 {
|
if guestId != 0 {
|
||||||
// 继承guest_id的资源表
|
// 继承guest_id的资源表
|
||||||
err = txRes.
|
err = txRes.
|
||||||
Where("guest_id = ?", guestId).
|
Where("guest_id = ? and source != 'temp' and version != '0.0.0'", guestId).
|
||||||
UpdateColumn("user_id", userId).Error
|
UpdateColumn("user_id", userId).Error
|
||||||
|
|
||||||
if err != nil && err != gorm.ErrRecordNotFound {
|
if err != nil && err != gorm.ErrRecordNotFound {
|
||||||
logx.Info(err, "找到user_id1 afterDo")
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = txUserMaterial.
|
err = txUserMaterial.
|
||||||
Where("guest_id = ?", guestId).
|
Where("guest_id = ? and module != 'clear' and module != 'temp'", guestId).
|
||||||
UpdateColumn("user_id", userId).Error
|
UpdateColumn("user_id", userId).Error
|
||||||
|
|
||||||
if err != nil && err != gorm.ErrRecordNotFound {
|
if err != nil && err != gorm.ErrRecordNotFound {
|
||||||
logx.Info(err, "找到user_id1 afterDo")
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = txUserInfo.
|
err = txUserInfo.
|
||||||
Where("guest_id = ?", guestId).
|
Where("guest_id = ? and module != 'clear' and module != 'temp'", guestId).
|
||||||
UpdateColumn("user_id", userId).Error
|
UpdateColumn("user_id", userId).Error
|
||||||
|
|
||||||
if err != nil && err != gorm.ErrRecordNotFound {
|
if err != nil && err != gorm.ErrRecordNotFound {
|
||||||
logx.Info(err, "找到user_id1 afterDo")
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,9 +115,9 @@ func (u *FsUserModel) RegisterByGoogleOAuth(ctx context.Context, token *auth.Reg
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
// 没有找到在数据库就创建注册
|
// 没有找到在数据库就创建注册
|
||||||
if err == gorm.ErrRecordNotFound {
|
if err == gorm.ErrRecordNotFound {
|
||||||
createAt := time.Now().UTC().Unix()
|
createAt := time.Now().UTC()
|
||||||
user.Email = &token.Email
|
user.Email = &token.Email
|
||||||
user.CreatedAt = &createAt
|
user.Ctime = &createAt
|
||||||
user.GoogleId = &googleId
|
user.GoogleId = &googleId
|
||||||
user.PasswordHash = &token.Password
|
user.PasswordHash = &token.Password
|
||||||
user.FirstName = &firstName
|
user.FirstName = &firstName
|
||||||
@ -150,21 +145,6 @@ func (u *FsUserModel) RegisterByGoogleOAuth(ctx context.Context, token *auth.Reg
|
|||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubscriptionStatus 订阅状态
|
|
||||||
type SubscriptionStatus struct {
|
|
||||||
SubEmail bool `json:"all_emails"`
|
|
||||||
ItemMap *struct {
|
|
||||||
} `json:"item_map"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// UserProfile 个人信息
|
|
||||||
type UserProfile struct {
|
|
||||||
FirstName string `json:"first_name"`
|
|
||||||
LastName string `json:"last_name"`
|
|
||||||
Resetaurant string `json:"resetaurant"`
|
|
||||||
SubStatus SubscriptionStatus `json:"sub_status"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// 自平台的注册流程
|
// 自平台的注册流程
|
||||||
func (u *FsUserModel) RegisterByFusen(ctx context.Context, token *auth.RegisterToken) (user *FsUser, err error) {
|
func (u *FsUserModel) RegisterByFusen(ctx context.Context, token *auth.RegisterToken) (user *FsUser, err error) {
|
||||||
|
|
||||||
@ -174,44 +154,41 @@ func (u *FsUserModel) RegisterByFusen(ctx context.Context, token *auth.RegisterT
|
|||||||
var err error
|
var err error
|
||||||
|
|
||||||
err = tx.Model(&FsUser{}).Where("email = ?", token.Email).Take(user).Error
|
err = tx.Model(&FsUser{}).Where("email = ?", token.Email).Take(user).Error
|
||||||
log.Println("success", token.TraceId)
|
|
||||||
if err == gorm.ErrRecordNotFound {
|
if err == gorm.ErrRecordNotFound {
|
||||||
|
|
||||||
FirstName := token.Extend["first_name"].(string)
|
FirstName := token.Extend["first_name"].(string)
|
||||||
LastName := token.Extend["last_name"].(string)
|
LastName := token.Extend["last_name"].(string)
|
||||||
Resetaurant := token.Extend["resetaurant"].(string)
|
Resetaurant := token.Extend["resetaurant"].(string)
|
||||||
|
|
||||||
createAt := time.Now().UTC().Unix()
|
createAt := time.Now().UTC()
|
||||||
|
|
||||||
user.Email = &token.Email
|
user.Email = &token.Email
|
||||||
user.CreatedAt = &createAt
|
user.Ctime = &createAt
|
||||||
user.PasswordHash = &token.Password
|
user.PasswordHash = &token.Password
|
||||||
user.FirstName = &FirstName
|
user.FirstName = &FirstName
|
||||||
user.LastName = &LastName
|
user.LastName = &LastName
|
||||||
|
|
||||||
err = tx.Model(&FsUser{}).Create(user).Error
|
err = tx.Model(&FsUser{}).Create(user).Error
|
||||||
if err != nil && err != gorm.ErrRecordNotFound {
|
if err != nil && err != gorm.ErrRecordNotFound {
|
||||||
logx.Error(err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("success", token.TraceId)
|
|
||||||
|
|
||||||
// 继承guest_id的资源表
|
// 继承guest_id的资源表
|
||||||
err = InheritGuestIdResource(tx, user.Id, token.GuestId, func(txResouce, txUserMaterial, txUserInfo *gorm.DB) error {
|
err = InheritGuestIdResource(tx, user.Id, token.GuestId, func(txResouce, txUserMaterial, txUserInfo *gorm.DB) error {
|
||||||
log.Println("success", token.TraceId)
|
userProfileBase := UserProfileBase{
|
||||||
userProfile := &UserProfile{
|
|
||||||
FirstName: FirstName,
|
FirstName: FirstName,
|
||||||
LastName: LastName,
|
LastName: LastName,
|
||||||
Resetaurant: Resetaurant,
|
Resetaurant: Resetaurant,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
userProfile := &UserProfile{
|
||||||
|
ProfileBase: userProfileBase,
|
||||||
|
}
|
||||||
|
|
||||||
metadata, err := json.Marshal(userProfile)
|
metadata, err := json.Marshal(userProfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// txUserInfo.Where("user_id = ?", user.Id).Row().Err()
|
|
||||||
|
|
||||||
now := time.Now().UTC()
|
now := time.Now().UTC()
|
||||||
uinfo := &FsUserInfo{
|
uinfo := &FsUserInfo{
|
||||||
Module: FsString("profile"),
|
Module: FsString("profile"),
|
||||||
@ -222,18 +199,18 @@ func (u *FsUserModel) RegisterByFusen(ctx context.Context, token *auth.RegisterT
|
|||||||
Utime: &now,
|
Utime: &now,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = txUserInfo.Where("module = 'profile' and user_id = ?", uinfo.UserId).Take(nil).Error
|
// logx.Error(metadata)
|
||||||
// txUserInfo.Statement.Table
|
|
||||||
log.Println(err, "找到user_id1")
|
err = txUserInfo.Where("module = 'profile' and user_id = ?", *uinfo.UserId).Take(nil).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == gorm.ErrRecordNotFound {
|
if err == gorm.ErrRecordNotFound {
|
||||||
err = txUserInfo.Create(uinfo).Error
|
err = tx.Model(&FsUserInfo{}).Create(uinfo).Error
|
||||||
|
// logx.Info(err, "*uinfo.UserId:", *uinfo.UserId, " ", uinfo.Id)
|
||||||
if err == gorm.ErrRecordNotFound {
|
if err == gorm.ErrRecordNotFound {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Println("找到user_id2")
|
|
||||||
err = fssql.MetadataModulePATCH(txUserInfo, "profile", FsUserInfo{}, metadata, "user_id = ?", *uinfo.UserId)
|
err = fssql.MetadataModulePATCH(txUserInfo, "profile", FsUserInfo{}, metadata, "user_id = ?", *uinfo.UserId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@ -35,3 +35,25 @@ func FsFloat(v float64) *float64 {
|
|||||||
func FsBool(v bool) *bool {
|
func FsBool(v bool) *bool {
|
||||||
return &v
|
return &v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SubscriptionStatus 订阅状态
|
||||||
|
type SubscriptionStatus struct {
|
||||||
|
SubEmail bool `json:"all_emails"`
|
||||||
|
ItemMap *struct {
|
||||||
|
} `json:"item_map"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserProfile struct {
|
||||||
|
ProfileBase UserProfileBase `json:"base"`
|
||||||
|
SubStatus SubscriptionStatus `json:"sub_status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserProfileBase 个人信息
|
||||||
|
type UserProfileBase struct {
|
||||||
|
FirstName string `json:"first_name"` // 首名
|
||||||
|
LastName string `json:"last_name"` // 后名
|
||||||
|
UserName string `json:"user_name"` // 用户名
|
||||||
|
Mobile string `json:"mobile"` // 电话
|
||||||
|
Resetaurant string `json:"resetaurant"` // 不知道干什么
|
||||||
|
Company string `json:"company"` // 公司
|
||||||
|
}
|
||||||
|
|||||||
@ -18,7 +18,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
|
|
||||||
_ "fusenapi/utils/auth"
|
_ "fusenapi/utils/auth"
|
||||||
@ -97,14 +96,16 @@ func main() {
|
|||||||
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/") {
|
||||||
err := r.ParseMultipartForm(100 << 20)
|
|
||||||
if err != nil {
|
r.ParseMultipartForm(100 << 20)
|
||||||
logx.Error(err)
|
// 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 {
|
||||||
@ -208,22 +209,22 @@ func NewBackend(mux *http.ServeMux, httpAddress string, muxPaths ...string) *Bac
|
|||||||
target := url.URL{Scheme: "ws", Host: strings.Split(backend.HttpAddress, "//")[1], Path: r.URL.Path}
|
target := url.URL{Scheme: "ws", Host: strings.Split(backend.HttpAddress, "//")[1], Path: r.URL.Path}
|
||||||
|
|
||||||
var transfer = func(src, dest *websocket.Conn) {
|
var transfer = func(src, dest *websocket.Conn) {
|
||||||
|
defer src.Close()
|
||||||
|
defer dest.Close()
|
||||||
|
// TODO: 可以做错误处理
|
||||||
for {
|
for {
|
||||||
mType, msg, err := src.ReadMessage()
|
mType, msg, err := src.ReadMessage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
break
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = dest.WriteMessage(mType, msg)
|
err = dest.WriteMessage(mType, msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
break
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
src.Close()
|
|
||||||
dest.Close()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
header := r.Header.Clone()
|
header := r.Header.Clone()
|
||||||
@ -247,6 +248,7 @@ func NewBackend(mux *http.ServeMux, httpAddress string, muxPaths ...string) *Bac
|
|||||||
}
|
}
|
||||||
conn, err := upgrader.Upgrade(w, r, nil)
|
conn, err := upgrader.Upgrade(w, r, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// defer conn.Close()
|
// defer conn.Close()
|
||||||
@ -259,14 +261,14 @@ func NewBackend(mux *http.ServeMux, httpAddress string, muxPaths ...string) *Bac
|
|||||||
// 解析目标URL,包含了查询参数
|
// 解析目标URL,包含了查询参数
|
||||||
targetURL, err := url.Parse(httpAddress + r.URL.String())
|
targetURL, err := url.Parse(httpAddress + r.URL.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Error parsing target URL", http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建新的请求
|
// 创建新的请求
|
||||||
proxyReq, err := http.NewRequest(r.Method, targetURL.String(), r.Body)
|
proxyReq, err := http.NewRequest(r.Method, targetURL.String(), r.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Error creating proxy request", http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,7 +286,7 @@ func NewBackend(mux *http.ServeMux, httpAddress string, muxPaths ...string) *Bac
|
|||||||
// 发送请求
|
// 发送请求
|
||||||
resp, err := backend.Client.Do(proxyReq)
|
resp, err := backend.Client.Do(proxyReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Error sending proxy request", http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
@ -300,7 +302,7 @@ func NewBackend(mux *http.ServeMux, httpAddress string, muxPaths ...string) *Bac
|
|||||||
w.WriteHeader(resp.StatusCode)
|
w.WriteHeader(resp.StatusCode)
|
||||||
_, err = io.Copy(w, resp.Body)
|
_, err = io.Copy(w, resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Error copying proxy response", http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,64 +4,94 @@ single_server_name=$1
|
|||||||
|
|
||||||
go mod tidy
|
go mod tidy
|
||||||
go mod vendor
|
go mod vendor
|
||||||
|
find /tmp/go-build* -mmin +5 -exec rm -rf {} +
|
||||||
|
find /tmp/go-link* -mmin +5 -exec rm -rf {} +
|
||||||
|
|
||||||
|
run_proxyserver() {
|
||||||
|
# 定义目录和screen名称
|
||||||
|
dir_path="./proxyserver"
|
||||||
|
screen_name="proxyserver"
|
||||||
|
|
||||||
|
# 进入目录
|
||||||
|
cd $dir_path
|
||||||
|
# 检查是否存在screen session
|
||||||
|
if screen -list | grep -q "$screen_name"; then
|
||||||
|
# 结束存在的screen session
|
||||||
|
screen -S $screen_name -X quit
|
||||||
|
fi
|
||||||
|
go build
|
||||||
|
# 启动新的screen session并运行go程序
|
||||||
|
echo "run $screen_name"
|
||||||
|
screen -dmS $screen_name -L ./$screen_name
|
||||||
|
}
|
||||||
|
|
||||||
# 定义一个函数来在每个服务器目录下运行 go run <server_name>.go
|
# 定义一个函数来在每个服务器目录下运行 go run <server_name>.go
|
||||||
run_server() {
|
run_server() {
|
||||||
server_name=$1
|
server_name=$1
|
||||||
echo "Running $server_name"
|
|
||||||
|
# 导航到相应的目录
|
||||||
|
cd server/$server_name
|
||||||
|
echo "build $server_name"
|
||||||
|
go build
|
||||||
|
|
||||||
# 如果之前存在相同名字的 screen 会话,先将其终止
|
# 如果之前存在相同名字的 screen 会话,先将其终止
|
||||||
|
# 首先尝试关闭已存在的screen会话
|
||||||
existing_session=$(screen -ls | grep -w "$server_name")
|
existing_session=$(screen -ls | grep -w "$server_name")
|
||||||
if [ -n "$existing_session" ]; then
|
if [ -n "$existing_session" ]; then
|
||||||
echo "Terminating existing screen session for $server_name"
|
echo "Terminating existing screen session for $server_name"
|
||||||
screen -S "$server_name" -X quit
|
screen -S "$server_name" -X quit
|
||||||
|
while [[ $(screen -ls | grep "\.$server_name\s") ]]; do
|
||||||
|
sleep 0.1s # 等待0.1秒后再次检查
|
||||||
|
echo "wait for $server_name"
|
||||||
|
done
|
||||||
fi
|
fi
|
||||||
# 导航到相应的目录
|
|
||||||
cd server/$server_name
|
# 循环检查screen进程是否存在
|
||||||
go build
|
|
||||||
|
|
||||||
[ -f .gitignore ] || echo $server_name > .gitignore
|
[ -f .gitignore ] || echo $server_name > .gitignore
|
||||||
# 使用 screen 运行 go run <server_name>.go
|
# 使用 screen 运行 go run <server_name>.go
|
||||||
|
|
||||||
|
echo "Running $server_name"
|
||||||
screen -dmS $server_name -L ./$server_name
|
screen -dmS $server_name -L ./$server_name
|
||||||
|
|
||||||
# 返回到上一级目录
|
# 返回到上一级目录
|
||||||
cd - > /dev/null
|
cd - > /dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
find /tmp/go-build* -mmin +5 -exec rm -rf {} +
|
if [ "$single_server_name" = "proxyserver" ]; then
|
||||||
find /tmp/go-link* -mmin +5 -exec rm -rf {} +
|
# 重启proxyserver的逻辑
|
||||||
|
run_proxyserver
|
||||||
|
else
|
||||||
|
|
||||||
server_dirs=() # 初始化一个空数组
|
server_dirs=() # 初始化一个空数组
|
||||||
|
|
||||||
if [ -n "$single_server_name" ]; then
|
if [ -n "$single_server_name" ]; then
|
||||||
server_dirs=("$single_server_name")
|
server_dirs=("$single_server_name")
|
||||||
else
|
else
|
||||||
for dir in server/*/ ; do # 遍历 "server/" 下的所有子目录
|
for dir in server/*/ ; do # 遍历 "server/" 下的所有子目录
|
||||||
dir=${dir%*/} # 删除末尾的 "/"
|
dir=${dir%*/} # 删除末尾的 "/"
|
||||||
dir=${dir##*/} # 删除开头的 "server/"
|
dir=${dir##*/} # 删除开头的 "server/"
|
||||||
server_dirs+=("$dir") # 添加到数组
|
server_dirs+=("$dir") # 添加到数组
|
||||||
done
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 在每个服务器目录下运行相应的 go 程序
|
||||||
|
for server_dir in "${server_dirs[@]}"; do
|
||||||
|
run_server $server_dir
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -n "$single_server_name" ]; then
|
||||||
|
echo "no proxyserver restart"
|
||||||
|
else
|
||||||
|
run_proxyserver
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 在每个服务器目录下运行相应的 go 程序
|
|
||||||
for server_dir in "${server_dirs[@]}"; do
|
|
||||||
run_server $server_dir
|
|
||||||
done
|
|
||||||
|
|
||||||
|
|
||||||
# 定义目录和screen名称
|
|
||||||
dir_path="./proxyserver"
|
|
||||||
screen_name="proxyserver"
|
|
||||||
|
|
||||||
# 进入目录
|
|
||||||
cd $dir_path
|
|
||||||
# 检查是否存在screen session
|
|
||||||
if screen -list | grep -q "$screen_name"; then
|
|
||||||
# 结束存在的screen session
|
|
||||||
screen -S $screen_name -X quit
|
|
||||||
fi
|
|
||||||
go build
|
|
||||||
# 启动新的screen session并运行go程序
|
|
||||||
screen -dmS $screen_name -L ./$screen_name
|
|
||||||
|
|||||||
@ -97,7 +97,7 @@ func CommonNotify(WebsocketAddr, wid string, event *wevent.WebsocketEvent) error
|
|||||||
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
|
||||||
logx.Error("找到user_id1 UserEmailConfirmation")
|
|
||||||
switch auth.OperateType(req.OpType) {
|
switch auth.OperateType(req.OpType) {
|
||||||
case auth.OpTypeRegister:
|
case auth.OpTypeRegister:
|
||||||
|
|
||||||
|
|||||||
@ -49,50 +49,50 @@ func (l *UserAddAddressLogic) UserAddAddress(req *types.RequestAddAddress, useri
|
|||||||
isDefautl int64 = 1 // 默认地址为1
|
isDefautl int64 = 1 // 默认地址为1
|
||||||
)
|
)
|
||||||
createOne := &gmodel.FsAddress{ // 构建FsAddress结构体
|
createOne := &gmodel.FsAddress{ // 构建FsAddress结构体
|
||||||
Name: &req.Name,
|
AddressName: &req.Name,
|
||||||
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,
|
IsDefault: &isDefautl,
|
||||||
}
|
}
|
||||||
created, err := m.CreateOne(l.ctx, createOne) // 新增地址
|
created, 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) // 返回数据库创建错误
|
||||||
}
|
}
|
||||||
return resp.SetStatus(basic.CodeOK, map[string]int64{"id": created.Id}) // 返回成功并返回地址ID
|
return resp.SetStatus(basic.CodeOK, map[string]int64{"id": created.AddressId}) // 返回成功并返回地址ID
|
||||||
}
|
}
|
||||||
|
|
||||||
address := &gmodel.FsAddress{
|
address := &gmodel.FsAddress{
|
||||||
Id: req.Id,
|
AddressId: req.Id,
|
||||||
Name: &req.Name,
|
AddressName: &req.Name,
|
||||||
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,
|
||||||
Status: &status,
|
Status: &status,
|
||||||
UserId: &userinfo.UserId,
|
UserId: &userinfo.UserId,
|
||||||
ZipCode: &req.ZipCode,
|
ZipCode: &req.ZipCode,
|
||||||
IsDefault: &req.IsDefault,
|
IsDefault: &req.IsDefault,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 插入数据库 更新地址
|
// 插入数据库 更新地址
|
||||||
err := m.UpdateAddAddress(l.ctx, address)
|
err := m.UpdateAddress(l.ctx, address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
return resp.SetStatus(basic.CodeDbUpdateErr)
|
return resp.SetStatus(basic.CodeDbUpdateErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp.SetStatus(basic.CodeOK, map[string]int64{"id": address.Id})
|
return resp.SetStatus(basic.CodeOK, map[string]int64{"id": address.AddressId})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import (
|
|||||||
"fusenapi/server/home-user-auth/internal/types"
|
"fusenapi/server/home-user-auth/internal/types"
|
||||||
"fusenapi/utils/auth"
|
"fusenapi/utils/auth"
|
||||||
"fusenapi/utils/basic"
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
@ -45,13 +46,13 @@ func (l *UserBasicInfoLogic) UserBasicInfo(req *types.Request, userinfo *auth.Us
|
|||||||
}
|
}
|
||||||
|
|
||||||
return resp.SetStatus(basic.CodeOK, types.DataUserBasicInfo{
|
return resp.SetStatus(basic.CodeOK, types.DataUserBasicInfo{
|
||||||
Type: *user.Type,
|
Type: *user.Type,
|
||||||
IsOrderStatusEmail: *user.IsOrderStatusEmail,
|
// IsOrderStatusEmail: *user.IsOrderStatusEmail,
|
||||||
IsEmailAdvertisement: *user.IsEmailAdvertisement,
|
// IsEmailAdvertisement: *user.IsEmailAdvertisement,
|
||||||
IsOrderStatusPhone: *user.IsOrderStatusPhone,
|
// IsOrderStatusPhone: *user.IsOrderStatusPhone,
|
||||||
IsPhoneAdvertisement: *user.IsPhoneAdvertisement,
|
// IsPhoneAdvertisement: *user.IsPhoneAdvertisement,
|
||||||
IsOpenRender: *user.IsOpenRender,
|
// IsOpenRender: *user.IsOpenRender,
|
||||||
IsLowRendering: *user.IsLowRendering,
|
// IsLowRendering: *user.IsLowRendering,
|
||||||
IsRemoveBg: *user.IsRemoveBg,
|
// IsRemoveBg: *user.IsRemoveBg,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,8 +45,31 @@ func (l *UserLogoSetLogic) UserLogoSet(req *types.UserLogoSetReq, userinfo *auth
|
|||||||
// 如果是,返回未授权的错误码
|
// 如果是,返回未授权的错误码
|
||||||
return resp.SetStatus(basic.CodeUnAuth)
|
return resp.SetStatus(basic.CodeUnAuth)
|
||||||
}
|
}
|
||||||
|
var nowTime = time.Now().UTC()
|
||||||
if req.LogoSelectedId == 0 {
|
if req.LogoSelectedId == 0 {
|
||||||
return resp.SetStatus(basic.CodeLogoSetCategory, "logo logo_selected_id not null")
|
NewFsUserMaterialModel1 := gmodel.NewFsUserMaterialModel(l.svcCtx.MysqlConn)
|
||||||
|
NewFsUserMaterialModelRow1 := NewFsUserMaterialModel1.RowSelectBuilder(nil).Where("id = ?", 0)
|
||||||
|
|
||||||
|
defaultMaterialInfo, err := NewFsUserMaterialModel1.FindOne(l.ctx, NewFsUserMaterialModelRow1.Model(&gmodel.FsUserMaterial{}))
|
||||||
|
if err != nil {
|
||||||
|
logc.Errorf(l.ctx, "defaultMaterialInfo FindOne err:%+v", err)
|
||||||
|
return resp.SetStatus(basic.CodeLogoSetCategory, "logo not find")
|
||||||
|
}
|
||||||
|
var defaultMaterial = gmodel.FsUserMaterial{
|
||||||
|
Module: defaultMaterialInfo.Module,
|
||||||
|
UserId: &userinfo.UserId,
|
||||||
|
GuestId: &userinfo.GuestId,
|
||||||
|
ResourceId: defaultMaterialInfo.ResourceId,
|
||||||
|
ResourceUrl: defaultMaterialInfo.ResourceUrl,
|
||||||
|
Ctime: &nowTime,
|
||||||
|
}
|
||||||
|
MaterialCreateRes := l.svcCtx.MysqlConn.Create(&defaultMaterial)
|
||||||
|
err = MaterialCreateRes.Error
|
||||||
|
if err != nil {
|
||||||
|
logc.Errorf(l.ctx, "defaultMaterialInfo Create err:%+v", err)
|
||||||
|
return resp.SetStatus(basic.CodeLogoSetCategory, "logo not find")
|
||||||
|
}
|
||||||
|
req.LogoSelectedId = defaultMaterial.Id
|
||||||
}
|
}
|
||||||
if req.SetLogoCategory == 1 && req.CategoryId == 0 {
|
if req.SetLogoCategory == 1 && req.CategoryId == 0 {
|
||||||
return resp.SetStatus(basic.CodeLogoSetCategory, "logo category_id not null")
|
return resp.SetStatus(basic.CodeLogoSetCategory, "logo category_id not null")
|
||||||
@ -73,7 +96,6 @@ func (l *UserLogoSetLogic) UserLogoSet(req *types.UserLogoSetReq, userinfo *auth
|
|||||||
return resp.SetStatus(basic.CodeLogoSetCategory, "logo not find")
|
return resp.SetStatus(basic.CodeLogoSetCategory, "logo not find")
|
||||||
}
|
}
|
||||||
|
|
||||||
var nowTime = time.Now().UTC()
|
|
||||||
err = l.svcCtx.MysqlConn.WithContext(l.ctx).Transaction(func(tx *gorm.DB) error {
|
err = l.svcCtx.MysqlConn.WithContext(l.ctx).Transaction(func(tx *gorm.DB) error {
|
||||||
var metadataMapOldUserMaterial map[string]interface{}
|
var metadataMapOldUserMaterial map[string]interface{}
|
||||||
if userMaterialInfo.Metadata != nil {
|
if userMaterialInfo.Metadata != nil {
|
||||||
|
|||||||
@ -6,27 +6,27 @@ import (
|
|||||||
|
|
||||||
"fusenapi/utils/basic"
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
"fusenapi/server/pay/internal/logic"
|
"fusenapi/server/info/internal/logic"
|
||||||
"fusenapi/server/pay/internal/svc"
|
"fusenapi/server/info/internal/svc"
|
||||||
"fusenapi/server/pay/internal/types"
|
"fusenapi/server/info/internal/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func OrderPaymentIntentHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
func AddressAddHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
var req types.OrderPaymentIntentReq
|
var req types.AddressRequest
|
||||||
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.NewOrderPaymentIntentLogic(r.Context(), svcCtx)
|
l := logic.NewAddressAddLogic(r.Context(), svcCtx)
|
||||||
|
|
||||||
rl := reflect.ValueOf(l)
|
rl := reflect.ValueOf(l)
|
||||||
basic.BeforeLogic(w, r, rl)
|
basic.BeforeLogic(w, r, rl)
|
||||||
|
|
||||||
resp := l.OrderPaymentIntent(&req, userinfo)
|
resp := l.AddressAdd(&req, userinfo)
|
||||||
|
|
||||||
if !basic.AfterLogic(w, r, rl, resp) {
|
if !basic.AfterLogic(w, r, rl, resp) {
|
||||||
basic.NormalAfterLogic(w, r, resp)
|
basic.NormalAfterLogic(w, r, resp)
|
||||||
35
server/info/internal/handler/addressdefaulthandler.go
Normal file
35
server/info/internal/handler/addressdefaulthandler.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
|
"fusenapi/server/info/internal/logic"
|
||||||
|
"fusenapi/server/info/internal/svc"
|
||||||
|
"fusenapi/server/info/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AddressDefaultHandler(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.NewAddressDefaultLogic(r.Context(), svcCtx)
|
||||||
|
|
||||||
|
rl := reflect.ValueOf(l)
|
||||||
|
basic.BeforeLogic(w, r, rl)
|
||||||
|
|
||||||
|
resp := l.AddressDefault(&req, userinfo)
|
||||||
|
|
||||||
|
if !basic.AfterLogic(w, r, rl, resp) {
|
||||||
|
basic.NormalAfterLogic(w, r, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
35
server/info/internal/handler/addressdeletehandler.go
Normal file
35
server/info/internal/handler/addressdeletehandler.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
|
"fusenapi/server/info/internal/logic"
|
||||||
|
"fusenapi/server/info/internal/svc"
|
||||||
|
"fusenapi/server/info/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AddressDeleteHandler(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.NewAddressDeleteLogic(r.Context(), svcCtx)
|
||||||
|
|
||||||
|
rl := reflect.ValueOf(l)
|
||||||
|
basic.BeforeLogic(w, r, rl)
|
||||||
|
|
||||||
|
resp := l.AddressDelete(&req, userinfo)
|
||||||
|
|
||||||
|
if !basic.AfterLogic(w, r, rl, resp) {
|
||||||
|
basic.NormalAfterLogic(w, r, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
35
server/info/internal/handler/addresslisthandler.go
Normal file
35
server/info/internal/handler/addresslisthandler.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
|
"fusenapi/server/info/internal/logic"
|
||||||
|
"fusenapi/server/info/internal/svc"
|
||||||
|
"fusenapi/server/info/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AddressListHandler(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.NewAddressListLogic(r.Context(), svcCtx)
|
||||||
|
|
||||||
|
rl := reflect.ValueOf(l)
|
||||||
|
basic.BeforeLogic(w, r, rl)
|
||||||
|
|
||||||
|
resp := l.AddressList(&req, userinfo)
|
||||||
|
|
||||||
|
if !basic.AfterLogic(w, r, rl, resp) {
|
||||||
|
basic.NormalAfterLogic(w, r, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
35
server/info/internal/handler/addressupdatehandler.go
Normal file
35
server/info/internal/handler/addressupdatehandler.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
|
"fusenapi/server/info/internal/logic"
|
||||||
|
"fusenapi/server/info/internal/svc"
|
||||||
|
"fusenapi/server/info/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AddressUpdateHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
var req types.AddressRequest
|
||||||
|
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建一个业务逻辑层实例
|
||||||
|
l := logic.NewAddressUpdateLogic(r.Context(), svcCtx)
|
||||||
|
|
||||||
|
rl := reflect.ValueOf(l)
|
||||||
|
basic.BeforeLogic(w, r, rl)
|
||||||
|
|
||||||
|
resp := l.AddressUpdate(&req, userinfo)
|
||||||
|
|
||||||
|
if !basic.AfterLogic(w, r, rl, resp) {
|
||||||
|
basic.NormalAfterLogic(w, r, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -17,6 +17,41 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
Path: "/api/info/user",
|
Path: "/api/info/user",
|
||||||
Handler: InfoHandler(serverCtx),
|
Handler: InfoHandler(serverCtx),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/api/info/user/profile",
|
||||||
|
Handler: UserGetProfileHandler(serverCtx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/api/info/user/profile/base/update",
|
||||||
|
Handler: UpdateProfileBaseHandler(serverCtx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/api/info/address/default",
|
||||||
|
Handler: AddressDefaultHandler(serverCtx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/api/info/address/add",
|
||||||
|
Handler: AddressAddHandler(serverCtx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/api/info/address/update",
|
||||||
|
Handler: AddressUpdateHandler(serverCtx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/api/info/address/delete",
|
||||||
|
Handler: AddressDeleteHandler(serverCtx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: "/api/info/address/list",
|
||||||
|
Handler: AddressListHandler(serverCtx),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
35
server/info/internal/handler/updateprofilebasehandler.go
Normal file
35
server/info/internal/handler/updateprofilebasehandler.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
|
"fusenapi/server/info/internal/logic"
|
||||||
|
"fusenapi/server/info/internal/svc"
|
||||||
|
"fusenapi/server/info/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func UpdateProfileBaseHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
var req types.ProfileBaseRequest
|
||||||
|
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建一个业务逻辑层实例
|
||||||
|
l := logic.NewUpdateProfileBaseLogic(r.Context(), svcCtx)
|
||||||
|
|
||||||
|
rl := reflect.ValueOf(l)
|
||||||
|
basic.BeforeLogic(w, r, rl)
|
||||||
|
|
||||||
|
resp := l.UpdateProfileBase(&req, userinfo)
|
||||||
|
|
||||||
|
if !basic.AfterLogic(w, r, rl, resp) {
|
||||||
|
basic.NormalAfterLogic(w, r, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
35
server/info/internal/handler/usergetprofilehandler.go
Normal file
35
server/info/internal/handler/usergetprofilehandler.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
|
"fusenapi/server/info/internal/logic"
|
||||||
|
"fusenapi/server/info/internal/svc"
|
||||||
|
"fusenapi/server/info/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func UserGetProfileHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
var req types.QueryProfileRequest
|
||||||
|
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建一个业务逻辑层实例
|
||||||
|
l := logic.NewUserGetProfileLogic(r.Context(), svcCtx)
|
||||||
|
|
||||||
|
rl := reflect.ValueOf(l)
|
||||||
|
basic.BeforeLogic(w, r, rl)
|
||||||
|
|
||||||
|
resp := l.UserGetProfile(&req, userinfo)
|
||||||
|
|
||||||
|
if !basic.AfterLogic(w, r, rl, resp) {
|
||||||
|
basic.NormalAfterLogic(w, r, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
93
server/info/internal/logic/addressaddlogic.go
Normal file
93
server/info/internal/logic/addressaddlogic.go
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
package logic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fusenapi/model/gmodel"
|
||||||
|
"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 AddressAddLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAddressAddLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddressAddLogic {
|
||||||
|
return &AddressAddLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理进入前逻辑w,r
|
||||||
|
// func (l *AddressAddLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (l *AddressAddLogic) AddressAdd(req *types.AddressRequest, 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 // 创建地址模型
|
||||||
|
|
||||||
|
// 如果ID为0, 表示新增地址
|
||||||
|
|
||||||
|
var (
|
||||||
|
country string = "USA" // 国家默认为美国
|
||||||
|
isDefautl int64 = 1 // 默认地址为1
|
||||||
|
status int64 = 1 // 默认地址状态为1(正常)
|
||||||
|
)
|
||||||
|
|
||||||
|
createOne := &gmodel.FsAddress{ // 构建FsAddress结构体
|
||||||
|
AddressName: &req.AddressName,
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
_, err := m.CreateOne(l.ctx, createOne) // 新增地址
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err) // 日志记录错误
|
||||||
|
return resp.SetStatus(basic.CodeDbCreateErr) // 返回数据库创建错误
|
||||||
|
}
|
||||||
|
|
||||||
|
addresses, err := m.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_list": addresses,
|
||||||
|
}) // 返回成功并返回地址ID
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
// func (l *AddressAddLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||||
|
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
// }
|
||||||
52
server/info/internal/logic/addressdefaultlogic.go
Normal file
52
server/info/internal/logic/addressdefaultlogic.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
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 AddressDefaultLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAddressDefaultLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddressDefaultLogic {
|
||||||
|
return &AddressDefaultLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理进入前逻辑w,r
|
||||||
|
// func (l *AddressDefaultLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (l *AddressDefaultLogic) AddressDefault(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.SettingUserDefaultAddress(l.ctx, userinfo.UserId, req.AddressId)
|
||||||
|
if err != nil {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeApiErr, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.SetStatus(basic.CodeOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
// func (l *AddressDefaultLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||||
|
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
// }
|
||||||
52
server/info/internal/logic/addressdeletelogic.go
Normal file
52
server/info/internal/logic/addressdeletelogic.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
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 AddressDeleteLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAddressDeleteLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddressDeleteLogic {
|
||||||
|
return &AddressDeleteLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理进入前逻辑w,r
|
||||||
|
// func (l *AddressDeleteLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (l *AddressDeleteLogic) AddressDelete(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.DeleteOne(l.ctx, req.AddressId, userinfo.UserId)
|
||||||
|
if err != nil {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeApiErr, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.SetStatus(basic.CodeOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
// func (l *AddressDeleteLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||||
|
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
// }
|
||||||
56
server/info/internal/logic/addresslistlogic.go
Normal file
56
server/info/internal/logic/addresslistlogic.go
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
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 AddressListLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAddressListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddressListLogic {
|
||||||
|
return &AddressListLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理进入前逻辑w,r
|
||||||
|
// func (l *AddressListLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (l *AddressListLogic) AddressList(req *types.Request, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
|
// userinfo 传入值时, 一定不为null
|
||||||
|
|
||||||
|
if !userinfo.IsUser() {
|
||||||
|
return resp.SetStatus(basic.CodeUnAuth)
|
||||||
|
}
|
||||||
|
|
||||||
|
m := l.svcCtx.AllModels.FsAddress // 创建地址模型
|
||||||
|
result, err := m.GetUserAllAddress(l.ctx, userinfo.UserId)
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err) // 日志记录错误
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, err.Error()) // 返回数据库创建错误
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.SetStatus(basic.CodeOK, map[string]any{
|
||||||
|
"address_list": result,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
// func (l *AddressListLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||||
|
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
// }
|
||||||
76
server/info/internal/logic/addressupdatelogic.go
Normal file
76
server/info/internal/logic/addressupdatelogic.go
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
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 AddressUpdateLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAddressUpdateLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddressUpdateLogic {
|
||||||
|
return &AddressUpdateLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理进入前逻辑w,r
|
||||||
|
// func (l *AddressUpdateLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (l *AddressUpdateLogic) AddressUpdate(req *types.AddressRequest, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
|
// userinfo 传入值时, 一定不为null
|
||||||
|
|
||||||
|
if !userinfo.IsUser() {
|
||||||
|
return resp.SetStatus(basic.CodeUnAuth)
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now().UTC()
|
||||||
|
|
||||||
|
if req.AddressId == 0 {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeApiErr, "address_id must setting")
|
||||||
|
}
|
||||||
|
|
||||||
|
address := gmodel.FsAddress{
|
||||||
|
AddressId: req.AddressId,
|
||||||
|
UserId: &userinfo.UserId,
|
||||||
|
IsDefault: &req.IsDefault,
|
||||||
|
AddressName: &req.AddressName,
|
||||||
|
FirstName: &req.FirstName,
|
||||||
|
LastName: &req.LastName,
|
||||||
|
Mobile: &req.Mobile,
|
||||||
|
ZipCode: &req.ZipCode,
|
||||||
|
Street: &req.Street,
|
||||||
|
Suite: &req.Suite,
|
||||||
|
City: &req.City,
|
||||||
|
State: &req.State,
|
||||||
|
Utime: &now,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := l.svcCtx.AllModels.FsAddress.UpdateAddress(l.ctx, &address)
|
||||||
|
if err != nil {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeApiErr, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.SetStatus(basic.CodeOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
// func (l *AddressUpdateLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||||
|
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
// }
|
||||||
@ -39,6 +39,7 @@ func NewInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *InfoLogic {
|
|||||||
var ModuleTable map[string]string = map[string]string{
|
var ModuleTable map[string]string = map[string]string{
|
||||||
"userinfo": "fs_user_info",
|
"userinfo": "fs_user_info",
|
||||||
"material": "fs_user_material",
|
"material": "fs_user_material",
|
||||||
|
"address": "fs_address", // TODO: 地址列表
|
||||||
}
|
}
|
||||||
|
|
||||||
type ModuleQuery struct {
|
type ModuleQuery struct {
|
||||||
@ -82,6 +83,38 @@ func (mquery *ModuleQuery) EncodeEmpty() map[string]any {
|
|||||||
return qstr
|
return qstr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func QueryDefault(conn *gorm.DB, module string, moduleQuery string, tname string) map[string]any {
|
||||||
|
|
||||||
|
qname := strings.Split(moduleQuery, ".")
|
||||||
|
queryAsName := qname[len(qname)-1]
|
||||||
|
sqlstr := fmt.Sprintf(
|
||||||
|
"select JSON_EXTRACT(metadata,'$.%s') as %s from %s where module = '%s' and user_id = 0 and guest_id = 0 order by ctime DESC limit 1",
|
||||||
|
moduleQuery, // logo_selected
|
||||||
|
queryAsName, // logo_selected
|
||||||
|
tname, // fs_user_info
|
||||||
|
module, // profile
|
||||||
|
)
|
||||||
|
raw := conn.Raw(sqlstr)
|
||||||
|
var info map[string]any
|
||||||
|
err := raw.Scan(&info).Error
|
||||||
|
if err == gorm.ErrRecordNotFound {
|
||||||
|
logx.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, ok := info[queryAsName]; ok {
|
||||||
|
var qinfo map[string]any
|
||||||
|
err := json.Unmarshal([]byte(v.(string)), &qinfo)
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
} else {
|
||||||
|
info[queryAsName] = qinfo
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return info
|
||||||
|
}
|
||||||
|
|
||||||
func (l *InfoLogic) Info(req *types.UserInfoRequest, userinfo *auth.UserInfo) (resp *basic.Response) {
|
func (l *InfoLogic) Info(req *types.UserInfoRequest, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
// userinfo 传入值时, 一定不为null
|
// userinfo 传入值时, 一定不为null
|
||||||
@ -178,9 +211,70 @@ func (l *InfoLogic) Info(req *types.UserInfoRequest, userinfo *auth.UserInfo) (r
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 隐含白板用户逻辑
|
||||||
|
if v, ok := metadict["userinfo.profile"]; ok {
|
||||||
|
|
||||||
|
if v == nil {
|
||||||
|
|
||||||
|
info := QueryDefault(l.svcCtx.MysqlConn, "profile", "logo_selected", "fs_user_info")
|
||||||
|
metadict["userinfo.profile"] = info
|
||||||
|
} else {
|
||||||
|
profileDict := v.(map[string]any)
|
||||||
|
if _, ok := profileDict["logo_selected"]; !ok {
|
||||||
|
info := QueryDefault(l.svcCtx.MysqlConn, "profile", "logo_selected", "fs_user_info")
|
||||||
|
profileDict["logo_selected"] = info["logo_selected"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if v, ok := metadict["userinfo.profile.logo_selected"]; ok {
|
||||||
|
if v == nil {
|
||||||
|
info := QueryDefault(l.svcCtx.MysqlConn, "profile", "logo_selected", "fs_user_info")
|
||||||
|
metadict["userinfo.profile.logo_selected"] = info
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var info map[string]any
|
||||||
|
for k, v := range metadict {
|
||||||
|
if v == nil {
|
||||||
|
if strings.HasPrefix(k, "userinfo.profile.logo_selected") {
|
||||||
|
if info == nil {
|
||||||
|
info = QueryDefault(l.svcCtx.MysqlConn, "profile", "logo_selected", "fs_user_info")
|
||||||
|
}
|
||||||
|
|
||||||
|
curValue, err := GetMapValueByKey(info, strings.Split(k, ".")[2:])
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err, info)
|
||||||
|
continue
|
||||||
|
// return resp.SetStatus(basic.CodeOK, metadict)
|
||||||
|
}
|
||||||
|
metadict[k] = curValue
|
||||||
|
// curValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return resp.SetStatus(basic.CodeOK, metadict)
|
return resp.SetStatus(basic.CodeOK, metadict)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetMapValueByKey(info map[string]interface{}, keys []string) (interface{}, error) {
|
||||||
|
// keys := strings.Split(key, ".")[2:]
|
||||||
|
|
||||||
|
for _, k := range keys {
|
||||||
|
if cur, ok := info[k]; ok {
|
||||||
|
if curMap, ok := cur.(map[string]interface{}); ok {
|
||||||
|
info = curMap
|
||||||
|
} else {
|
||||||
|
// logx.Error(cur)
|
||||||
|
return cur, nil
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("info keys is not exists %#v", keys)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return info, nil
|
||||||
|
}
|
||||||
|
|
||||||
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
// func (l *InfoLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
// func (l *InfoLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||||
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import (
|
|||||||
"fusenapi/initalize"
|
"fusenapi/initalize"
|
||||||
"fusenapi/model/gmodel"
|
"fusenapi/model/gmodel"
|
||||||
"fusenapi/utils/check"
|
"fusenapi/utils/check"
|
||||||
|
"fusenapi/utils/fssql"
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
@ -117,57 +118,47 @@ func TestMain(t *testing.T) {
|
|||||||
if v == nil {
|
if v == nil {
|
||||||
|
|
||||||
info := QueryDefault(conn, "profile", "logo_selected", "fs_user_info")
|
info := QueryDefault(conn, "profile", "logo_selected", "fs_user_info")
|
||||||
log.Println(info)
|
|
||||||
metadict["userinfo.profile"] = info
|
metadict["userinfo.profile"] = info
|
||||||
// log.Println(metadict)
|
|
||||||
} else {
|
} else {
|
||||||
profileDict := v.(map[string]any)
|
profileDict := v.(map[string]any)
|
||||||
if _, ok := profileDict["logo_selected"]; !ok {
|
if _, ok := profileDict["logo_selected"]; !ok {
|
||||||
info := QueryDefault(conn, "profile", "logo_selected", "fs_user_info")
|
info := QueryDefault(conn, "profile", "logo_selected", "fs_user_info")
|
||||||
profileDict["logo_selected"] = info["logo_selected"]
|
profileDict["logo_selected"] = info["logo_selected"]
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if v, ok := metadict["userinfo.profile.logo_selected"]; ok {
|
} else if v, ok := metadict["userinfo.profile.logo_selected"]; ok {
|
||||||
if v == nil {
|
if v == nil {
|
||||||
|
info := QueryDefault(conn, "profile", "logo_selected", "fs_user_info")
|
||||||
|
metadict["userinfo.profile.logo_selected"] = info
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var info map[string]any
|
||||||
|
for k, v := range metadict {
|
||||||
|
if v == nil {
|
||||||
|
if strings.HasPrefix(k, "userinfo.profile.logo_selected") {
|
||||||
|
if info == nil {
|
||||||
|
info = QueryDefault(conn, "profile", "logo_selected", "fs_user_info")
|
||||||
|
}
|
||||||
|
|
||||||
|
curValue, err := GetMapValueByKey(info, strings.Split(k, ".")[2:])
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err, info)
|
||||||
|
continue
|
||||||
|
// return resp.SetStatus(basic.CodeOK, metadict)
|
||||||
|
}
|
||||||
|
metadict[k] = curValue
|
||||||
|
// curValue
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println(metadict)
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func QueryDefault(conn *gorm.DB, module string, moduleQuery string, tname string) map[string]any {
|
|
||||||
|
|
||||||
qname := strings.Split(moduleQuery, ".")
|
|
||||||
queryAsName := qname[len(qname)-1]
|
|
||||||
sqlstr := fmt.Sprintf(
|
|
||||||
"select JSON_EXTRACT(metadata,'$.%s') as %s from %s where module = '%s' and user_id = 0 and guest_id = 0 order by ctime DESC limit 1",
|
|
||||||
moduleQuery, // logo_selected
|
|
||||||
queryAsName, // logo_selected
|
|
||||||
tname, // fs_user_info
|
|
||||||
module, // profile
|
|
||||||
)
|
|
||||||
raw := conn.Raw(sqlstr)
|
|
||||||
var info map[string]any
|
|
||||||
err := raw.Scan(&info).Error
|
|
||||||
if err == gorm.ErrRecordNotFound {
|
|
||||||
logx.Error(err)
|
|
||||||
}
|
|
||||||
return info
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCaseJSON_EXTRACT(t *testing.T) {
|
func TestCaseJSON_EXTRACT(t *testing.T) {
|
||||||
|
|
||||||
userProfile := &gmodel.UserProfile{
|
userProfile := &gmodel.UserProfile{}
|
||||||
FirstName: "FirstName",
|
|
||||||
LastName: "LastName",
|
|
||||||
Resetaurant: "Resetaurant",
|
|
||||||
}
|
|
||||||
metadata, err := json.Marshal(userProfile)
|
metadata, err := json.Marshal(userProfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -185,6 +176,14 @@ func TestCaseJSON_EXTRACT(t *testing.T) {
|
|||||||
|
|
||||||
conn := initalize.InitMysql("fsreaderwriter:XErSYmLELKMnf3Dh@tcp(fusen.cdmigcvz3rle.us-east-2.rds.amazonaws.com:3306)/fusen")
|
conn := initalize.InitMysql("fsreaderwriter:XErSYmLELKMnf3Dh@tcp(fusen.cdmigcvz3rle.us-east-2.rds.amazonaws.com:3306)/fusen")
|
||||||
// err = conn.Exec(updatesql, 6).Error
|
// err = conn.Exec(updatesql, 6).Error
|
||||||
log.Println(conn.Model(&gmodel.FsChangeCode{}).Select("id").Where("id = 5").Take(nil).Error)
|
info := gmodel.UserProfileBase{}
|
||||||
|
|
||||||
|
var baseinfo map[string]any
|
||||||
|
tname := fssql.GetGormTableName(conn, gmodel.FsUserInfo{})
|
||||||
|
rawsql := fmt.Sprintf("select JSON_EXTRACT(metadata,'$.base') as base from %s where user_id = ? and module = ? order by ctime DESC limit 1", tname)
|
||||||
|
tx := conn.Raw(rawsql, 162, "profile").Take(&baseinfo)
|
||||||
|
log.Println(tx.Error)
|
||||||
|
json.Unmarshal([]byte(baseinfo["base"].(string)), &info)
|
||||||
|
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
|
|||||||
52
server/info/internal/logic/updateprofilebaselogic.go
Normal file
52
server/info/internal/logic/updateprofilebaselogic.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
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 UpdateProfileBaseLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUpdateProfileBaseLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateProfileBaseLogic {
|
||||||
|
return &UpdateProfileBaseLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理进入前逻辑w,r
|
||||||
|
// func (l *UpdateProfileBaseLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (l *UpdateProfileBaseLogic) UpdateProfileBase(req *types.ProfileBaseRequest, 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.FsUserInfo.MergeMetadata(userinfo.UserId, req)
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err) // 日志记录错误
|
||||||
|
return resp.SetStatus(basic.CodeDbSqlErr, err.Error()) // 返回数据库创建错误
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.SetStatus(basic.CodeOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
// func (l *UpdateProfileBaseLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||||
|
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
// }
|
||||||
52
server/info/internal/logic/usergetprofilelogic.go
Normal file
52
server/info/internal/logic/usergetprofilelogic.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
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 UserGetProfileLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUserGetProfileLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserGetProfileLogic {
|
||||||
|
return &UserGetProfileLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理进入前逻辑w,r
|
||||||
|
// func (l *UserGetProfileLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (l *UserGetProfileLogic) UserGetProfile(req *types.QueryProfileRequest, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
|
// userinfo 传入值时, 一定不为null
|
||||||
|
|
||||||
|
if !userinfo.IsUser() {
|
||||||
|
return resp.SetStatus(basic.CodeUnAuth)
|
||||||
|
}
|
||||||
|
|
||||||
|
profileBase, err := l.svcCtx.AllModels.FsUserInfo.GetProfile(l.ctx, req.TopKey, userinfo.UserId)
|
||||||
|
if err != nil {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeApiErr, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.SetStatus(basic.CodeOK, profileBase)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
// func (l *UserGetProfileLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||||
|
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
// }
|
||||||
@ -9,6 +9,46 @@ type UserInfoRequest struct {
|
|||||||
Module []string `json:"module"`
|
Module []string `json:"module"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AddressObjectRequest struct {
|
||||||
|
AddressId int64 `json:"address_id"` // 地址id
|
||||||
|
AddressName string `json:"address_name"` // 地址
|
||||||
|
}
|
||||||
|
|
||||||
|
type AddressIdRequest struct {
|
||||||
|
AddressId int64 `json:"address_id"` // 地址id
|
||||||
|
}
|
||||||
|
|
||||||
|
type AddressNameRequest struct {
|
||||||
|
AddressName string `json:"address_name"` // 地址
|
||||||
|
}
|
||||||
|
|
||||||
|
type AddressRequest struct {
|
||||||
|
AddressId int64 `json:"address_id,optional"`
|
||||||
|
IsDefault int64 `json:"is_default"` //是否默认
|
||||||
|
AddressName string `json:"address_name"` //收货人
|
||||||
|
FirstName string `json:"first_name"` //first_name
|
||||||
|
LastName string `json:"last_name"` //last_name
|
||||||
|
Mobile string `json:"mobile"` //手机
|
||||||
|
ZipCode string `json:"zip_code"` //邮编
|
||||||
|
Street string `json:"street"` //街道
|
||||||
|
Suite string `json:"suite"` //房号
|
||||||
|
City string `json:"city"` //城市
|
||||||
|
State string `json:"state"` //州
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProfileBaseRequest struct {
|
||||||
|
FirstName *string `json:"first_name,optional,omitempty"` // 首名
|
||||||
|
LastName *string `json:"last_name,optional,omitempty"` // 后名
|
||||||
|
UserName *string `json:"user_name,optional,omitempty"` // 用户名
|
||||||
|
Mobile *string `json:"mobile,optional,omitempty"` // 电话
|
||||||
|
Resetaurant *string `json:"resetaurant,optional,omitempty"` // 不知道干什么
|
||||||
|
Company *string `json:"company,optional,omitempty"` // 公司
|
||||||
|
}
|
||||||
|
|
||||||
|
type QueryProfileRequest struct {
|
||||||
|
TopKey string `json:"top_key"` // 首名
|
||||||
|
}
|
||||||
|
|
||||||
type Request struct {
|
type Request struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,10 +72,10 @@ type File struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Meta struct {
|
type Meta struct {
|
||||||
TotalCount int64 `json:"totalCount"`
|
TotalCount int64 `json:"total_count"`
|
||||||
PageCount int64 `json:"pageCount"`
|
PageCount int64 `json:"page_count"`
|
||||||
CurrentPage int `json:"currentPage"`
|
CurrentPage int `json:"current_page"`
|
||||||
PerPage int `json:"perPage"`
|
PerPage int `json:"per_page"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set 设置Response的Code和Message值
|
// Set 设置Response的Code和Message值
|
||||||
|
|||||||
@ -3,7 +3,7 @@ Host: 0.0.0.0
|
|||||||
Port: 9907
|
Port: 9907
|
||||||
Timeout: 15000 #服务超时时间(毫秒)
|
Timeout: 15000 #服务超时时间(毫秒)
|
||||||
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
|
||||||
SourceRabbitMq:
|
SourceRabbitMq: 213
|
||||||
Log:
|
Log:
|
||||||
Stat: false
|
Stat: false
|
||||||
Auth:
|
Auth:
|
||||||
|
|||||||
@ -47,7 +47,7 @@ func (l *CreateOrderLogic) CreateOrder(req *types.CreateOrderReq, userinfo *auth
|
|||||||
OriginalCurrency: string(constants.CURRENCYUSD),
|
OriginalCurrency: string(constants.CURRENCYUSD),
|
||||||
UserId: userinfo.UserId,
|
UserId: userinfo.UserId,
|
||||||
CartIds: req.CartIds,
|
CartIds: req.CartIds,
|
||||||
DeliveryMethod: req.DeliveryMethod,
|
DeliveryMethod: constants.DELIVERYMETHODDSCLOUDSTORE,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package logic
|
package logic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fusenapi/service/repositories"
|
||||||
"fusenapi/utils/auth"
|
"fusenapi/utils/auth"
|
||||||
"fusenapi/utils/basic"
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
@ -38,7 +39,22 @@ func (l *CreatePrePaymentByBalanceLogic) CreatePrePaymentByBalance(req *types.Cr
|
|||||||
return resp.SetStatus(basic.CodeUnAuth)
|
return resp.SetStatus(basic.CodeUnAuth)
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp.SetStatus(basic.CodeOK)
|
res, err := l.svcCtx.Repositories.NewOrder.CreatePrePaymentByBalance(l.ctx, &repositories.CreatePrePaymentByBalanceReq{
|
||||||
|
UserId: userinfo.UserId,
|
||||||
|
OrderSn: req.OrderSn,
|
||||||
|
Country: "US",
|
||||||
|
Currency: "usd",
|
||||||
|
StripeKey: l.svcCtx.Config.PayConfig.Stripe.Key,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return resp.SetStatus(&res.ErrorCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.SetStatus(basic.CodeOK, map[string]interface{}{
|
||||||
|
"order_detail": res.OrderDetail,
|
||||||
|
"order_pay": res.OrderPay,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
|||||||
@ -10,8 +10,7 @@ type OrderDetailReq struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type CreateOrderReq struct {
|
type CreateOrderReq struct {
|
||||||
CartIds []int64 `json:"cart_ids"`
|
CartIds []int64 `json:"cart_ids"`
|
||||||
DeliveryMethod int64 `json:"delivery_method,options=[1,2]"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreatePrePaymentByDepositReq struct {
|
type CreatePrePaymentByDepositReq struct {
|
||||||
|
|||||||
@ -12,11 +12,6 @@ import (
|
|||||||
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||||
server.AddRoutes(
|
server.AddRoutes(
|
||||||
[]rest.Route{
|
[]rest.Route{
|
||||||
{
|
|
||||||
Method: http.MethodPost,
|
|
||||||
Path: "/api/pay/payment-intent",
|
|
||||||
Handler: OrderPaymentIntentHandler(serverCtx),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
Method: http.MethodPost,
|
Method: http.MethodPost,
|
||||||
Path: "/api/pay/refund",
|
Path: "/api/pay/refund",
|
||||||
|
|||||||
@ -1,181 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fusenapi/utils/auth"
|
|
||||||
"fusenapi/utils/basic"
|
|
||||||
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"fusenapi/server/pay/internal/svc"
|
|
||||||
"fusenapi/server/pay/internal/types"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type OrderPaymentIntentLogic struct {
|
|
||||||
logx.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewOrderPaymentIntentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *OrderPaymentIntentLogic {
|
|
||||||
return &OrderPaymentIntentLogic{
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理进入前逻辑w,r
|
|
||||||
// func (l *OrderPaymentIntentLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
|
||||||
// func (l *OrderPaymentIntentLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
|
||||||
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
|
||||||
// }
|
|
||||||
|
|
||||||
func (l *OrderPaymentIntentLogic) OrderPaymentIntent(req *types.OrderPaymentIntentReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
|
||||||
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
|
||||||
// userinfo 传入值时, 一定不为null
|
|
||||||
|
|
||||||
// if userinfo == nil || userinfo.UserId == 0 {
|
|
||||||
// return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "order not found")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 查询订单数据
|
|
||||||
// orderModel := gmodel.NewFsOrderModel(l.svcCtx.MysqlConn)
|
|
||||||
// orderInfo, err := orderModel.FindOneBySn(l.ctx, userinfo.UserId, req.Sn)
|
|
||||||
|
|
||||||
// if err != nil {
|
|
||||||
// if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
// return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "order not found")
|
|
||||||
// }
|
|
||||||
// logx.Error(err)
|
|
||||||
// return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get order info")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 校验订单状态
|
|
||||||
// if *orderInfo.IsCancel == 1 {
|
|
||||||
// return resp.SetStatusWithMessage(basic.CodeServiceErr, "order cancelled")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 校验地址信息
|
|
||||||
// addressModel := gmodel.NewFsAddressModel(l.svcCtx.MysqlConn)
|
|
||||||
// _, err = addressModel.GetOne(l.ctx, req.AddressId, userinfo.UserId)
|
|
||||||
|
|
||||||
// if err != nil {
|
|
||||||
// if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
// return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "address not found")
|
|
||||||
// }
|
|
||||||
// logx.Error(err)
|
|
||||||
// return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get address info")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 校验订单支付信息
|
|
||||||
// if *orderInfo.IsPayCompleted == 1 {
|
|
||||||
// return resp.SetStatusWithMessage(basic.CodeServiceErr, "order is pay completed")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 判断订单状态以及该支付金额
|
|
||||||
// var nowAt int64 = time.Now().UTC().Unix()
|
|
||||||
// var payAmount int64
|
|
||||||
// if *orderInfo.Status == int64(constants.STATUS_NEW_NOT_PAY) {
|
|
||||||
// payAmount = *orderInfo.TotalAmount / 2
|
|
||||||
// *orderInfo.DeliveryMethod = req.DeliveryMethod
|
|
||||||
// *orderInfo.AddressId = req.AddressId
|
|
||||||
// *orderInfo.PayMethod = req.PayMethod
|
|
||||||
// } else {
|
|
||||||
// payAmount = *orderInfo.TotalAmount - *orderInfo.TotalAmount/2
|
|
||||||
// }
|
|
||||||
|
|
||||||
// payConfig := &pay.Config{}
|
|
||||||
// var generatePrepaymentReq = &pay.GeneratePrepaymentReq{
|
|
||||||
// OrderSn: req.Sn,
|
|
||||||
// ProductName: "支付标题",
|
|
||||||
// Amount: payAmount,
|
|
||||||
// Currency: "eur",
|
|
||||||
// Quantity: 1,
|
|
||||||
// ProductDescription: "支付描述",
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var resData types.OrderPaymentIntentRes
|
|
||||||
// // 事务处理
|
|
||||||
// ctx := l.ctx
|
|
||||||
// err = l.svcCtx.MysqlConn.Transaction(func(connGorm *gorm.DB) error {
|
|
||||||
// // 支付记录--处理 //支付记录改为一条订单多条,分首款尾款
|
|
||||||
// var payStatus int64 = 0
|
|
||||||
// var orderSource int64 = 1
|
|
||||||
// var payStage int64
|
|
||||||
// var fspay *gmodel.FsPay
|
|
||||||
// newFsPayModel := gmodel.NewFsPayModel(connGorm)
|
|
||||||
// if *orderInfo.Status == int64(constants.STATUS_NEW_NOT_PAY) {
|
|
||||||
// fspay, err = newFsPayModel.RBGetListByOrderNumberStage(ctx, *orderInfo.Sn, 1)
|
|
||||||
// if err != nil {
|
|
||||||
// if !errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// payStage = 1
|
|
||||||
// } else {
|
|
||||||
// fspay, err = newFsPayModel.RBGetListByOrderNumberStage(ctx, *orderInfo.Sn, 2)
|
|
||||||
// if err != nil {
|
|
||||||
// if !errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// payStage = 2
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 支付预付--生成
|
|
||||||
// if constants.PayMethod(req.PayMethod) == constants.PAYMETHOD_STRIPE {
|
|
||||||
// payConfig.Stripe.Key = l.svcCtx.Config.PayConfig.Stripe.Key
|
|
||||||
// generatePrepaymentReq.SuccessURL = l.svcCtx.Config.PayConfig.Stripe.SuccessURL
|
|
||||||
// generatePrepaymentReq.CancelURL = l.svcCtx.Config.PayConfig.Stripe.CancelURL
|
|
||||||
// }
|
|
||||||
// payDriver := pay.NewPayDriver(req.PayMethod, payConfig)
|
|
||||||
// prepaymentRes, err := payDriver.GeneratePrepayment(generatePrepaymentReq)
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 订单信息--修改
|
|
||||||
// err = gmodel.NewFsOrderModel(connGorm).RBUpdate(ctx, orderInfo)
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if fspay == nil {
|
|
||||||
// fspay = &gmodel.FsPay{
|
|
||||||
// UserId: orderInfo.UserId,
|
|
||||||
// OrderNumber: orderInfo.Sn,
|
|
||||||
// CreatedAt: &nowAt,
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// fspay.UpdatedAt = &nowAt
|
|
||||||
// }
|
|
||||||
// fspay.PayAmount = &payAmount
|
|
||||||
// fspay.PayStage = &payStage
|
|
||||||
// //fspay.TradeNo = &prepaymentRes.TradeNo
|
|
||||||
// fspay.PaymentMethod = &req.PayMethod
|
|
||||||
// fspay.OrderSource = &orderSource
|
|
||||||
// fspay.PayStatus = &payStatus
|
|
||||||
|
|
||||||
// _, err = newFsPayModel.RBCreateOrUpdate(ctx, fspay)
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// resData.RedirectUrl = prepaymentRes.URL
|
|
||||||
// resData.ClientSecret = prepaymentRes.ClientSecret
|
|
||||||
|
|
||||||
// return nil
|
|
||||||
// })
|
|
||||||
|
|
||||||
// if err != nil {
|
|
||||||
// logx.Error(err)
|
|
||||||
// return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to make payment")
|
|
||||||
// }
|
|
||||||
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeOK, "success")
|
|
||||||
}
|
|
||||||
@ -1,16 +1,24 @@
|
|||||||
package logic
|
package logic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"fusenapi/constants"
|
||||||
"fusenapi/model/gmodel"
|
"fusenapi/model/gmodel"
|
||||||
|
"fusenapi/service/repositories"
|
||||||
"fusenapi/utils/auth"
|
"fusenapi/utils/auth"
|
||||||
"fusenapi/utils/basic"
|
"fusenapi/utils/basic"
|
||||||
|
"time"
|
||||||
|
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"fusenapi/server/pay/internal/svc"
|
"fusenapi/server/pay/internal/svc"
|
||||||
"fusenapi/server/pay/internal/types"
|
"fusenapi/server/pay/internal/types"
|
||||||
|
|
||||||
"github.com/stripe/stripe-go/v74"
|
"github.com/stripe/stripe-go/v75"
|
||||||
|
"github.com/stripe/stripe-go/v75/webhook"
|
||||||
|
"github.com/zeromicro/go-zero/core/logc"
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -42,110 +50,116 @@ func (l *StripeWebhookLogic) StripeWebhook(req *types.StripeWebhookReq, userinfo
|
|||||||
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
// userinfo 传入值时, 一定不为null
|
// userinfo 传入值时, 一定不为null
|
||||||
|
|
||||||
// stripe.Key = l.svcCtx.Config.PayConfig.Stripe.Key
|
stripe.Key = l.svcCtx.Config.PayConfig.Stripe.Key
|
||||||
// event := stripe.Event{}
|
event := stripe.Event{}
|
||||||
|
|
||||||
// if err := json.Unmarshal(req.Payload, &event); err != nil {
|
if err := json.Unmarshal(req.Payload, &event); err != nil {
|
||||||
// logx.Error(err)
|
logc.Errorf(l.ctx, "StripeWebhookLogic StripeWebhook Unmarshal err:%v", err)
|
||||||
// return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail")
|
return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail")
|
||||||
// }
|
}
|
||||||
|
// fmt.Println(req)
|
||||||
|
// fmt.Println(event)
|
||||||
|
|
||||||
// endpointSecret := l.svcCtx.Config.PayConfig.Stripe.EndpointSecret
|
endpointSecret := l.svcCtx.Config.PayConfig.Stripe.EndpointSecret
|
||||||
// signatureHeader := req.StripeSignature
|
signatureHeader := req.StripeSignature
|
||||||
// event, err := webhook.ConstructEvent(req.Payload, signatureHeader, endpointSecret)
|
fmt.Println(endpointSecret)
|
||||||
// if err != nil {
|
event, err := webhook.ConstructEvent(req.Payload, signatureHeader, endpointSecret)
|
||||||
// logx.Error(err)
|
if err != nil {
|
||||||
// return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "Webhook signature verification failed")
|
logc.Errorf(l.ctx, "webhook.ConstructEvent err:%v", err)
|
||||||
// }
|
return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "Webhook signature verification failed")
|
||||||
|
}
|
||||||
|
|
||||||
// // 新增支付回调事件日志
|
// 支付回调事件日志
|
||||||
// var payMethod = int64(constants.PAYMETHOD_STRIPE)
|
var payMethod = int64(constants.PAYMETHOD_STRIPE)
|
||||||
// var nowTime = time.Now().UTC().Unix()
|
var nowTime = time.Now().UTC()
|
||||||
// var eventData = string(event.Data.Raw)
|
var eventData = []byte(event.Data.Raw)
|
||||||
// var fsPayEvent = &gmodel.FsPayEvent{
|
eventType := string(event.Type)
|
||||||
// PayMethod: &payMethod,
|
l.HandlePayEventCreate(&gmodel.FsOrderTradeEvent{
|
||||||
// EventId: &event.ID,
|
PayMethod: &payMethod,
|
||||||
// EventType: &event.Type,
|
EventId: &event.ID,
|
||||||
// EventData: &eventData,
|
EventType: &eventType,
|
||||||
// EventCreated: &event.Created,
|
EventData: &eventData,
|
||||||
// Ip: &req.RemoteAddr,
|
Ctime: &nowTime,
|
||||||
// CreatedAt: &nowTime,
|
})
|
||||||
// }
|
|
||||||
// l.HandlePayEventCreate(fsPayEvent)
|
|
||||||
|
|
||||||
// // Unmarshal the event data into an appropriate struct depending on its Type
|
// Unmarshal the event data into an appropriate struct depending on its Type
|
||||||
// switch event.Type {
|
fmt.Println("事件类型", event.Type)
|
||||||
// case "charge.succeeded":
|
switch event.Type {
|
||||||
// // var charge stripe.Charge
|
case "charge.succeeded":
|
||||||
// // err := json.Unmarshal(event.Data.Raw, &charge)
|
var charge stripe.Charge
|
||||||
// // if err != nil {
|
err := json.Unmarshal(event.Data.Raw, &charge)
|
||||||
// // logx.Error(err)
|
if err != nil {
|
||||||
// // return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type charge.succeeded")
|
logx.Errorf("err:%+v,desc:%s", err, "pay notify Unmarshal fail event.Type charge.succeeded")
|
||||||
// // }
|
return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type charge.succeeded")
|
||||||
|
}
|
||||||
|
err = l.HandleChargeSucceeded(&charge, event.ID)
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorf("err:%+v,desc:%s", err, "pay notify handle payment_intent.succeeded")
|
||||||
|
return resp.SetStatusWithMessage(basic.CodePaybackNotOk, "pay notify handle payment_intent.succeeded")
|
||||||
|
}
|
||||||
|
case "checkout.session.completed":
|
||||||
|
// checkout checkout.session.completed 处理逻辑
|
||||||
|
// var session stripe.CheckoutSession
|
||||||
|
// err := json.Unmarshal(event.Data.Raw, &session)
|
||||||
|
// if err != nil {
|
||||||
|
// logx.Error(err)
|
||||||
|
// return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type payment_intent.succeeded")
|
||||||
|
// }
|
||||||
|
// fmt.Println("checkout.session.completed")
|
||||||
|
// err = l.handlePaymentSessionCompleted(session.ID, session.PaymentIntent.ID)
|
||||||
|
// if err != nil {
|
||||||
|
// return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "checkout.session.completed fail")
|
||||||
|
// }
|
||||||
|
case "payment_intent.succeeded":
|
||||||
|
// var paymentIntent stripe.PaymentIntent
|
||||||
|
// err := json.Unmarshal(event.Data.Raw, &paymentIntent)
|
||||||
|
// if err != nil {
|
||||||
|
// logx.Errorf("err:%+v,desc:%s", err, "pay notify Unmarshal fail event.Type payment_intent.succeeded")
|
||||||
|
// return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type payment_intent.succeeded")
|
||||||
|
// }
|
||||||
|
// err = l.HandlePaymentIntentSucceeded(&paymentIntent, event.ID)
|
||||||
|
// if err != nil {
|
||||||
|
// logx.Errorf("err:%+v,desc:%s", err, "pay notify handle payment_intent.succeeded")
|
||||||
|
// return resp.SetStatusWithMessage(basic.CodePaybackNotOk, "pay notify handle payment_intent.succeeded")
|
||||||
|
// }
|
||||||
|
case "payment_method.attached":
|
||||||
|
// var paymentMethod stripe.PaymentMethod
|
||||||
|
// err := json.Unmarshal(event.Data.Raw, &paymentMethod)
|
||||||
|
// if err != nil {
|
||||||
|
// logx.Error(err)
|
||||||
|
// return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type payment_method.attached")
|
||||||
|
// }
|
||||||
|
case "charge.refunded":
|
||||||
|
var chargeRefunded stripe.Charge
|
||||||
|
err := json.Unmarshal(event.Data.Raw, &chargeRefunded)
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorf("err:%+v,desc:%s", err, "pay notify Unmarshal fail event.Type charge.refunded")
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type charge.refunded")
|
||||||
|
}
|
||||||
|
err = l.HandleChargeRefunded(&chargeRefunded)
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorf("err:%+v,desc:%s", err, "pay notify handle charge.refunded")
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify handle charge.refunded")
|
||||||
|
}
|
||||||
|
|
||||||
// case "checkout.session.completed":
|
// ... handle other event types
|
||||||
// // checkout checkout.session.completed 处理逻辑
|
default:
|
||||||
// // var session stripe.CheckoutSession
|
logx.Error("Unhandled event")
|
||||||
// // err := json.Unmarshal(event.Data.Raw, &session)
|
return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type Unhandled")
|
||||||
// // if err != nil {
|
}
|
||||||
// // logx.Error(err)
|
|
||||||
// // return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type payment_intent.succeeded")
|
|
||||||
// // }
|
|
||||||
// // fmt.Println("checkout.session.completed")
|
|
||||||
// // err = l.handlePaymentSessionCompleted(session.ID, session.PaymentIntent.ID)
|
|
||||||
// // if err != nil {
|
|
||||||
// // return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "checkout.session.completed fail")
|
|
||||||
// // }
|
|
||||||
// case "payment_intent.succeeded":
|
|
||||||
// var paymentIntent stripe.PaymentIntent
|
|
||||||
// err := json.Unmarshal(event.Data.Raw, &paymentIntent)
|
|
||||||
// if err != nil {
|
|
||||||
// logx.Errorf("err:%+v,desc:%s", err, "pay notify Unmarshal fail event.Type payment_intent.succeeded")
|
|
||||||
// return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type payment_intent.succeeded")
|
|
||||||
// }
|
|
||||||
// err = l.HandlePaymentIntentSucceeded(&paymentIntent)
|
|
||||||
// if err != nil {
|
|
||||||
// logx.Errorf("err:%+v,desc:%s", err, "pay notify handle payment_intent.succeeded")
|
|
||||||
// return resp.SetStatusWithMessage(basic.CodePaybackNotOk, "pay notify handle payment_intent.succeeded")
|
|
||||||
// }
|
|
||||||
// case "payment_method.attached":
|
|
||||||
// var paymentMethod stripe.PaymentMethod
|
|
||||||
// err := json.Unmarshal(event.Data.Raw, &paymentMethod)
|
|
||||||
// if err != nil {
|
|
||||||
// logx.Error(err)
|
|
||||||
// return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type payment_method.attached")
|
|
||||||
// }
|
|
||||||
// case "charge.refunded":
|
|
||||||
// var chargeRefunded stripe.Charge
|
|
||||||
// err := json.Unmarshal(event.Data.Raw, &chargeRefunded)
|
|
||||||
// if err != nil {
|
|
||||||
// logx.Errorf("err:%+v,desc:%s", err, "pay notify Unmarshal fail event.Type charge.refunded")
|
|
||||||
// return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type charge.refunded")
|
|
||||||
// }
|
|
||||||
// err = l.HandleChargeRefunded(&chargeRefunded)
|
|
||||||
// if err != nil {
|
|
||||||
// logx.Errorf("err:%+v,desc:%s", err, "pay notify handle charge.refunded")
|
|
||||||
// return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify handle charge.refunded")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // ... handle other event types
|
|
||||||
// default:
|
|
||||||
// logx.Error("Unhandled event")
|
|
||||||
// return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type Unhandled")
|
|
||||||
// }
|
|
||||||
|
|
||||||
return resp.SetStatus(basic.CodeOK)
|
return resp.SetStatus(basic.CodeOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 回调事件日志
|
// 回调事件日志
|
||||||
func (l *StripeWebhookLogic) HandlePayEventCreate(fsPayEvent *gmodel.FsPayEvent) error {
|
func (l *StripeWebhookLogic) HandlePayEventCreate(fsPayEvent *gmodel.FsOrderTradeEvent) error {
|
||||||
_, err := gmodel.NewFsPayEventModel(l.svcCtx.MysqlConn).CreateOrUpdate(l.ctx, fsPayEvent)
|
result := l.svcCtx.MysqlConn.Create(fsPayEvent)
|
||||||
return err
|
return result.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// 退款成功
|
// 退款成功
|
||||||
func (l *StripeWebhookLogic) HandleChargeRefunded(chargeRefunded *stripe.Charge) (err error) {
|
func (l *StripeWebhookLogic) HandleChargeRefunded(chargeRefunded *stripe.Charge) (err error) {
|
||||||
// // 退款成功
|
// 退款成功
|
||||||
// if chargeRefunded.Status == "succeeded" {
|
// if chargeRefunded.Status == "succeeded" {
|
||||||
// ctx := l.ctx
|
// ctx := l.ctx
|
||||||
// err = l.svcCtx.MysqlConn.Transaction(func(connGorm *gorm.DB) error {
|
// err = l.svcCtx.MysqlConn.Transaction(func(connGorm *gorm.DB) error {
|
||||||
@ -227,162 +241,27 @@ func (l *StripeWebhookLogic) HandleChargeRefunded(chargeRefunded *stripe.Charge)
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// 付款成功
|
// 付款成功
|
||||||
func (l *StripeWebhookLogic) HandlePaymentIntentSucceeded(paymentIntent *stripe.PaymentIntent) error {
|
func (l *StripeWebhookLogic) HandleChargeSucceeded(charge *stripe.Charge, eventId string) error {
|
||||||
// orderSn, ok := paymentIntent.Metadata["order_sn"]
|
// 支付成功
|
||||||
// if !ok || orderSn == "" {
|
if charge.Status == "succeeded" {
|
||||||
// return errors.New("order_sn not found")
|
model, ok := charge.Metadata["model"]
|
||||||
// }
|
if !ok {
|
||||||
|
err := errors.New("model is empty")
|
||||||
// // 查询支付记录
|
logc.Errorf(l.ctx, "PaymentSuccessful failed param, eventId:%s,err:%v", eventId, err)
|
||||||
// payModel := gmodel.NewFsPayModel(l.svcCtx.MysqlConn)
|
return err
|
||||||
// rsbPay := payModel.RowSelectBuilder(nil)
|
}
|
||||||
// rsbPay = rsbPay.Where("order_number = ?", orderSn).Where("pay_status = ?", constants.PAYSTATUS_UNSUCCESS)
|
switch model {
|
||||||
// payInfo, err := payModel.FindOneByQuery(l.ctx, rsbPay, nil)
|
case "product_order":
|
||||||
// if err != nil {
|
res, err := l.svcCtx.Repositories.NewOrder.PaymentSuccessful(l.ctx, &repositories.PaymentSuccessfulReq{
|
||||||
// return err
|
EventId: eventId,
|
||||||
// }
|
PaymentMethod: "stripe",
|
||||||
|
Charge: charge,
|
||||||
// //订单信息
|
})
|
||||||
// orderDetailTemplateModel := gmodel.NewFsOrderDetailTemplateModel(l.svcCtx.MysqlConn)
|
if err != nil {
|
||||||
// orderModel := gmodel.NewFsOrderModel(l.svcCtx.MysqlConn)
|
return err
|
||||||
// fsOrderDetailModel := gmodel.NewFsOrderDetailModel(l.svcCtx.MysqlConn)
|
}
|
||||||
// fsProductDesignModel := gmodel.NewFsProductDesignModel(l.svcCtx.MysqlConn)
|
fmt.Println(res)
|
||||||
|
}
|
||||||
// rsbOrder := orderModel.RowSelectBuilder(nil)
|
}
|
||||||
// rsbOrder = rsbOrder.Where("sn =?", orderSn).Preload("FsOrderDetails")
|
|
||||||
// rsbOrder = rsbOrder.Preload("FsOrderDetails", func(dbPreload *gorm.DB) *gorm.DB {
|
|
||||||
// return dbPreload.Table(fsOrderDetailModel.TableName()).Preload("FsOrderDetailTemplateInfo", func(dbPreload *gorm.DB) *gorm.DB {
|
|
||||||
// return dbPreload.Table(orderDetailTemplateModel.TableName()).Preload("FsProductDesignInfo", func(dbPreload *gorm.DB) *gorm.DB {
|
|
||||||
// return dbPreload.Table(fsProductDesignModel.TableName())
|
|
||||||
// })
|
|
||||||
// })
|
|
||||||
// })
|
|
||||||
// fsOrderRelInfo, err := orderModel.FindOneByQuery(l.ctx, rsbOrder, nil)
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var designIds []int64
|
|
||||||
// var cartIds []int64
|
|
||||||
// if len(fsOrderRelInfo.FsOrderDetails) > 0 {
|
|
||||||
// for _, fsOrderDetail := range fsOrderRelInfo.FsOrderDetails {
|
|
||||||
// if fsOrderDetail.FsOrderDetailTemplateInfo.FsProductDesignInfo.Id != 0 {
|
|
||||||
// designIds = append(designIds, fsOrderDetail.FsOrderDetailTemplateInfo.FsProductDesignInfo.Id)
|
|
||||||
// }
|
|
||||||
// cartIds = append(cartIds, *fsOrderDetail.CartId)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var nowTime int64 = time.Now().UTC().Unix()
|
|
||||||
|
|
||||||
// // 支付成功
|
|
||||||
// if paymentIntent.Status == "succeeded" {
|
|
||||||
// var card string
|
|
||||||
// var brand string
|
|
||||||
// if paymentIntent.LatestCharge.PaymentMethodDetails != nil {
|
|
||||||
// if paymentIntent.LatestCharge.PaymentMethodDetails.Card != nil {
|
|
||||||
// if paymentIntent.LatestCharge.PaymentMethodDetails.Card.Last4 != "" {
|
|
||||||
// card = paymentIntent.LatestCharge.PaymentMethodDetails.Card.Last4
|
|
||||||
// }
|
|
||||||
// if paymentIntent.LatestCharge.PaymentMethodDetails.Card.Brand != "" {
|
|
||||||
// brand = string(paymentIntent.LatestCharge.PaymentMethodDetails.Card.Brand)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// ctx := l.ctx
|
|
||||||
// err = l.svcCtx.MysqlConn.Transaction(func(connGorm *gorm.DB) error {
|
|
||||||
// // 更新支付信息
|
|
||||||
// payModelT := gmodel.NewFsPayModel(connGorm)
|
|
||||||
// *payInfo.PayStatus = 1
|
|
||||||
// *payInfo.PayTime = nowTime
|
|
||||||
// *payInfo.CardNo = card
|
|
||||||
// *payInfo.Brand = brand
|
|
||||||
// *payInfo.TradeNo = paymentIntent.ID
|
|
||||||
// _, err = payModelT.RBCreateOrUpdate(ctx, payInfo)
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 更新设计数据
|
|
||||||
// productDesignModelT := gmodel.NewFsProductDesignModel(connGorm)
|
|
||||||
// productDesignModelTRSB := productDesignModelT.BuilderTrans(ctx, nil)
|
|
||||||
// var isPay int64 = 1
|
|
||||||
// err = productDesignModelT.RBUpdateByIds(productDesignModelTRSB, designIds, &gmodel.FsProductDesign{IsPay: &isPay})
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var orderInfo = &gmodel.FsOrder{}
|
|
||||||
// var orderStatus int64
|
|
||||||
// var orderIsPartPay int64
|
|
||||||
// var orderPayedAmount int64
|
|
||||||
// var orderIsPayCompleted int64
|
|
||||||
// // 支付记录是首款
|
|
||||||
// if *payInfo.PayStage == int64(constants.PAYSTAGE_DEPOSIT) {
|
|
||||||
// orderStatus = int64(constants.STATUS_NEW_PART_PAY)
|
|
||||||
// orderIsPartPay = 1
|
|
||||||
// orderInfo.IsPartPay = &orderIsPartPay
|
|
||||||
// orderPayedAmount = paymentIntent.Amount
|
|
||||||
|
|
||||||
// // 删除购物车
|
|
||||||
// cartModelT := gmodel.NewFsCartModel(connGorm)
|
|
||||||
// cartModelTRSB := cartModelT.BuilderTrans(ctx, nil)
|
|
||||||
// err = cartModelT.RBDeleteCartsByIds(cartModelTRSB, cartIds)
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 支付记录是尾款
|
|
||||||
// if *payInfo.PayStage == int64(constants.PAYSTAGE_REMAINING) {
|
|
||||||
// if *fsOrderRelInfo.Status < int64(constants.STATUS_NEW_PAY_COMPLETED) {
|
|
||||||
// orderStatus = int64(constants.STATUS_NEW_PAY_COMPLETED)
|
|
||||||
// }
|
|
||||||
// orderIsPayCompleted = 1
|
|
||||||
// orderInfo.IsPayCompleted = &orderIsPayCompleted
|
|
||||||
// orderPayedAmount = *fsOrderRelInfo.PayedAmount + paymentIntent.Amount
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 更新订单信息
|
|
||||||
// orderInfo.Id = fsOrderRelInfo.Id
|
|
||||||
// orderInfo.Status = &orderStatus
|
|
||||||
// orderInfo.Ptime = &nowTime
|
|
||||||
// orderInfo.PayedAmount = &orderPayedAmount
|
|
||||||
// orderModelT := gmodel.NewFsOrderModel(connGorm)
|
|
||||||
// err = orderModelT.RBUpdate(ctx, orderInfo)
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// return err
|
|
||||||
// })
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //千人千面的处理
|
|
||||||
// // $renderServer = (new RenderService());
|
|
||||||
// // $renderServer->thousandsFacesV2($order->id);
|
|
||||||
// // //清除用户最新的设计
|
|
||||||
// // $cache = \Yii::$app->cache;
|
|
||||||
// // $cache->delete(CacheConfigHelper::LAST_DESIGN . $order->user_id);
|
|
||||||
// // //缓存最新订单编号
|
|
||||||
// // $cache->set(CacheConfigHelper::USER_ORDERNO . $order->user_id, $order->sn);
|
|
||||||
|
|
||||||
// // //查询用户邮箱信息
|
|
||||||
// // $user = \api\models\User::find()->where(['id' => $order->user_id])->one();
|
|
||||||
// // $redisData = [
|
|
||||||
// // 'key' => 'receipt_download',
|
|
||||||
// // 'param' => [
|
|
||||||
// // 'email' => $user->email,
|
|
||||||
// // 'order_id' => $order->id,
|
|
||||||
// // 'pay_id' => $pay->id,
|
|
||||||
// // 'type' => 1,//付款成功为1
|
|
||||||
// // ]
|
|
||||||
// // ];
|
|
||||||
// // Email::timely($redisData);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 订单记录
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,8 +18,9 @@ type ServiceContext struct {
|
|||||||
Config config.Config
|
Config config.Config
|
||||||
SharedState *shared.SharedState
|
SharedState *shared.SharedState
|
||||||
|
|
||||||
MysqlConn *gorm.DB
|
MysqlConn *gorm.DB
|
||||||
AllModels *gmodel.AllModelsGen
|
AllModels *gmodel.AllModelsGen
|
||||||
|
Repositories *initalize.Repositories
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
@ -31,6 +32,9 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
|||||||
MysqlConn: conn,
|
MysqlConn: conn,
|
||||||
SharedState: nil,
|
SharedState: nil,
|
||||||
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
||||||
|
Repositories: initalize.NewAllRepositories(&initalize.NewAllRepositorieData{
|
||||||
|
GormDB: conn,
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,18 +11,6 @@ type OrderRefundReq struct {
|
|||||||
type OrderRefundRes struct {
|
type OrderRefundRes struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type OrderPaymentIntentReq struct {
|
|
||||||
Sn string `form:"sn"` //订单编号
|
|
||||||
DeliveryMethod int64 `form:"delivery_method"` //发货方式
|
|
||||||
AddressId int64 `form:"address_id"` //地址id
|
|
||||||
PayMethod int64 `form:"pay_method"` //支付方式
|
|
||||||
}
|
|
||||||
|
|
||||||
type OrderPaymentIntentRes struct {
|
|
||||||
RedirectUrl string `json:"redirect_url"`
|
|
||||||
ClientSecret string `json:"clientSecret"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type StripeWebhookReq struct {
|
type StripeWebhookReq struct {
|
||||||
Payload []byte `json:"base_byte_slice,optional"`
|
Payload []byte `json:"base_byte_slice,optional"`
|
||||||
StripeSignature string `json:"Stripe-Signature"`
|
StripeSignature string `json:"Stripe-Signature"`
|
||||||
@ -52,10 +40,10 @@ type File struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Meta struct {
|
type Meta struct {
|
||||||
TotalCount int64 `json:"totalCount"`
|
TotalCount int64 `json:"total_count"`
|
||||||
PageCount int64 `json:"pageCount"`
|
PageCount int64 `json:"page_count"`
|
||||||
CurrentPage int `json:"currentPage"`
|
CurrentPage int `json:"current_page"`
|
||||||
PerPage int `json:"perPage"`
|
PerPage int `json:"per_page"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set 设置Response的Code和Message值
|
// Set 设置Response的Code和Message值
|
||||||
|
|||||||
@ -106,7 +106,7 @@ func (l *GetProductTemplateTagsLogic) GetProductTemplateTags(req *types.GetProdu
|
|||||||
for templateTag, _ := range mapMaterialTemplateTagColors {
|
for templateTag, _ := range mapMaterialTemplateTagColors {
|
||||||
templateTagNameList = append(templateTagNameList, templateTag)
|
templateTagNameList = append(templateTagNameList, templateTag)
|
||||||
}
|
}
|
||||||
productTemplateTags, err = l.svcCtx.AllModels.FsProductTemplateTags.GetListByTagNames(l.ctx, templateTagNameList, req.Limit, 1, "id DESC")
|
productTemplateTags, err = l.svcCtx.AllModels.FsProductTemplateTags.GetListByTagNames(l.ctx, templateTagNameList, len(templateTagNameList), 1, "id DESC")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get template tags")
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get template tags")
|
||||||
@ -135,6 +135,7 @@ func (l *GetProductTemplateTagsLogic) GetProductTemplateTags(req *types.GetProdu
|
|||||||
for k, v := range productTemplateTags {
|
for k, v := range productTemplateTags {
|
||||||
if templateTagStr == *v.TemplateTag {
|
if templateTagStr == *v.TemplateTag {
|
||||||
productTemplateTags[k], productTemplateTags[index] = productTemplateTags[index], productTemplateTags[k]
|
productTemplateTags[k], productTemplateTags[index] = productTemplateTags[index], productTemplateTags[k]
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,4 +11,22 @@ type Config struct {
|
|||||||
SourceMysql string
|
SourceMysql string
|
||||||
Auth types.Auth
|
Auth types.Auth
|
||||||
ReplicaId uint64
|
ReplicaId uint64
|
||||||
|
AWS struct {
|
||||||
|
S3 struct {
|
||||||
|
Credentials struct {
|
||||||
|
AccessKeyID string
|
||||||
|
Secret string
|
||||||
|
Token string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BLMService struct {
|
||||||
|
Url string
|
||||||
|
LogoCombine struct {
|
||||||
|
Url string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Unity struct {
|
||||||
|
Host string
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,35 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
|
"fusenapi/server/product/internal/logic"
|
||||||
|
"fusenapi/server/product/internal/svc"
|
||||||
|
"fusenapi/server/product/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CalculateProductPriceHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
var req types.CalculateProductPriceReq
|
||||||
|
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建一个业务逻辑层实例
|
||||||
|
l := logic.NewCalculateProductPriceLogic(r.Context(), svcCtx)
|
||||||
|
|
||||||
|
rl := reflect.ValueOf(l)
|
||||||
|
basic.BeforeLogic(w, r, rl)
|
||||||
|
|
||||||
|
resp := l.CalculateProductPrice(&req, userinfo)
|
||||||
|
|
||||||
|
if !basic.AfterLogic(w, r, rl, resp) {
|
||||||
|
basic.NormalAfterLogic(w, r, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
|
"fusenapi/server/product/internal/logic"
|
||||||
|
"fusenapi/server/product/internal/svc"
|
||||||
|
"fusenapi/server/product/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetProductStepPriceHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
var req types.GetProductStepPriceReq
|
||||||
|
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建一个业务逻辑层实例
|
||||||
|
l := logic.NewGetProductStepPriceLogic(r.Context(), svcCtx)
|
||||||
|
|
||||||
|
rl := reflect.ValueOf(l)
|
||||||
|
basic.BeforeLogic(w, r, rl)
|
||||||
|
|
||||||
|
resp := l.GetProductStepPrice(&req, userinfo)
|
||||||
|
|
||||||
|
if !basic.AfterLogic(w, r, rl, resp) {
|
||||||
|
basic.NormalAfterLogic(w, r, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -72,6 +72,16 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
Path: "/api/product/get_price_by_pid",
|
Path: "/api/product/get_price_by_pid",
|
||||||
Handler: GetPriceByPidHandler(serverCtx),
|
Handler: GetPriceByPidHandler(serverCtx),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: "/api/product/get_product_step_price",
|
||||||
|
Handler: GetProductStepPriceHandler(serverCtx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/api/product/calculate_product_price",
|
||||||
|
Handler: CalculateProductPriceHandler(serverCtx),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Method: http.MethodGet,
|
Method: http.MethodGet,
|
||||||
Path: "/api/product/get_size_by_pid",
|
Path: "/api/product/get_size_by_pid",
|
||||||
|
|||||||
101
server/product/internal/logic/calculateproductpricelogic.go
Normal file
101
server/product/internal/logic/calculateproductpricelogic.go
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
package logic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fusenapi/constants"
|
||||||
|
"fusenapi/model/gmodel"
|
||||||
|
"fusenapi/utils/auth"
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
"fusenapi/utils/format"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"fusenapi/server/product/internal/svc"
|
||||||
|
"fusenapi/server/product/internal/types"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CalculateProductPriceLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCalculateProductPriceLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CalculateProductPriceLogic {
|
||||||
|
return &CalculateProductPriceLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理进入前逻辑w,r
|
||||||
|
// func (l *CalculateProductPriceLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (l *CalculateProductPriceLogic) CalculateProductPrice(req *types.CalculateProductPriceReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
|
if req.ProductId <= 0 {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "err param:product id")
|
||||||
|
}
|
||||||
|
if req.SizeId <= 0 {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "err param:size id")
|
||||||
|
}
|
||||||
|
if req.PurchaseQuantity <= 0 {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "err param:purchase quantity")
|
||||||
|
}
|
||||||
|
//获取产品信息(只是获取id)
|
||||||
|
_, err := l.svcCtx.AllModels.FsProduct.FindOne(l.ctx, req.ProductId, "id")
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "the product is not exists")
|
||||||
|
}
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product info")
|
||||||
|
}
|
||||||
|
//根据产品跟尺寸获取模型价格信息
|
||||||
|
modelInfo, err := l.svcCtx.AllModels.FsProductModel3d.FindOneByProductIdSizeIdTag(l.ctx, req.ProductId, req.SizeId, constants.TAG_MODEL, "id,step_price")
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "model info is not exists")
|
||||||
|
}
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get model info")
|
||||||
|
}
|
||||||
|
var stepPrice gmodel.StepPriceJsonStruct
|
||||||
|
if modelInfo.StepPrice != nil && len(*modelInfo.StepPrice) != 0 {
|
||||||
|
if err = json.Unmarshal(*modelInfo.StepPrice, &stepPrice); err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeJsonErr, "failed to parse step price")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//配件
|
||||||
|
fittingPrice := int64(0)
|
||||||
|
if req.FittingId > 0 {
|
||||||
|
fittingInfo, err := l.svcCtx.AllModels.FsProductModel3d.FindOne(l.ctx, req.FittingId, "id,price")
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "fitting info is not exists")
|
||||||
|
}
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get fitting info")
|
||||||
|
}
|
||||||
|
fittingPrice = *fittingInfo.Price
|
||||||
|
}
|
||||||
|
totalPrice, itemPrice, err := l.svcCtx.Repositories.NewShoppingCart.CaculateStepPrice(req.PurchaseQuantity, stepPrice, fittingPrice)
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to calculate product price ")
|
||||||
|
}
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeOK, "success", types.CalculateProductPriceRsp{
|
||||||
|
ItemPrice: format.CentitoDollar(itemPrice, 3),
|
||||||
|
TotalPrice: format.CentitoDollarWithNoHalfAdjust(totalPrice, 2),
|
||||||
|
PurchaseQuantity: req.PurchaseQuantity,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
// func (l *CalculateProductPriceLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||||
|
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
// }
|
||||||
@ -2,12 +2,9 @@ package logic
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fusenapi/utils/auth"
|
"fusenapi/utils/auth"
|
||||||
"fusenapi/utils/basic"
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
|
||||||
|
|
||||||
"fusenapi/server/product/internal/svc"
|
"fusenapi/server/product/internal/svc"
|
||||||
"fusenapi/server/product/internal/types"
|
"fusenapi/server/product/internal/types"
|
||||||
|
|
||||||
@ -33,18 +30,18 @@ func (l *GetLastProductDesignLogic) GetLastProductDesign(req *types.Request, use
|
|||||||
return resp.SetStatusAddMessage(basic.CodeUnAuth, "please sign in")
|
return resp.SetStatusAddMessage(basic.CodeUnAuth, "please sign in")
|
||||||
}
|
}
|
||||||
//获取用户信息
|
//获取用户信息
|
||||||
user, err := l.svcCtx.AllModels.FsUser.FindUserById(l.ctx, userinfo.UserId)
|
// user, err := l.svcCtx.AllModels.FsUser.FindUserById(l.ctx, userinfo.UserId)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
// if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return resp.SetStatusWithMessage(basic.CodeUnAuth, "user not found")
|
// return resp.SetStatusWithMessage(basic.CodeUnAuth, "user not found")
|
||||||
}
|
// }
|
||||||
logx.Error(err)
|
// logx.Error(err)
|
||||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get user info")
|
// return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get user info")
|
||||||
}
|
// }
|
||||||
//若没打开了个性化渲染按钮
|
// //若没打开了个性化渲染按钮
|
||||||
if *user.IsOpenRender != 1 {
|
// if *user.IsOpenRender != 1 {
|
||||||
return resp.SetStatusWithMessage(basic.CodeOK, "success:IsOpenRender switch is closed")
|
// return resp.SetStatusWithMessage(basic.CodeOK, "success:IsOpenRender switch is closed")
|
||||||
}
|
// }
|
||||||
//查询用户最近下单成功的数据
|
//查询用户最近下单成功的数据
|
||||||
// orderInfo, err := l.svcCtx.AllModels.FsOrder.FindLastSuccessOneOrder(l.ctx, user.Id, int64(constants.STATUS_NEW_NOT_PAY))
|
// orderInfo, err := l.svcCtx.AllModels.FsOrder.FindLastSuccessOneOrder(l.ctx, user.Id, int64(constants.STATUS_NEW_NOT_PAY))
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
|
|||||||
@ -377,8 +377,8 @@ func (l *GetProductInfoLogic) GetProductInfo(req *types.GetProductInfoReq, useri
|
|||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get user info")
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get user info")
|
||||||
}
|
}
|
||||||
isLowRendering = *user.IsLowRendering > 0
|
isLowRendering = true
|
||||||
isRemoveBg = *user.IsRemoveBg > 0
|
isRemoveBg = true
|
||||||
lastDesign = l.getLastDesign(user)
|
lastDesign = l.getLastDesign(user)
|
||||||
}
|
}
|
||||||
var renderDesign interface{}
|
var renderDesign interface{}
|
||||||
|
|||||||
@ -12,12 +12,13 @@ import (
|
|||||||
"fusenapi/utils/basic"
|
"fusenapi/utils/basic"
|
||||||
"fusenapi/utils/format"
|
"fusenapi/utils/format"
|
||||||
"fusenapi/utils/image"
|
"fusenapi/utils/image"
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
"github.com/zeromicro/go-zero/core/stores/sqlc"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
"math"
|
"math"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlc"
|
||||||
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
type GetProductListLogic struct {
|
type GetProductListLogic struct {
|
||||||
@ -163,7 +164,7 @@ func (l *GetProductListLogic) GetProductList(req *types.GetProductListReq, useri
|
|||||||
UserId: user.Id,
|
UserId: user.Id,
|
||||||
}
|
}
|
||||||
if user.Id != 0 {
|
if user.Id != 0 {
|
||||||
r.IsThousandFace = int(*user.IsThousandFace)
|
r.IsThousandFace = 1
|
||||||
}
|
}
|
||||||
image.ThousandFaceImageFormat(&r)
|
image.ThousandFaceImageFormat(&r)
|
||||||
item.Cover = r.Cover
|
item.Cover = r.Cover
|
||||||
|
|||||||
137
server/product/internal/logic/getproductsteppricelogic.go
Normal file
137
server/product/internal/logic/getproductsteppricelogic.go
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
package logic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"fusenapi/constants"
|
||||||
|
"fusenapi/model/gmodel"
|
||||||
|
"fusenapi/utils/auth"
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
"fusenapi/utils/format"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
|
||||||
|
"fusenapi/server/product/internal/svc"
|
||||||
|
"fusenapi/server/product/internal/types"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetProductStepPriceLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGetProductStepPriceLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetProductStepPriceLogic {
|
||||||
|
return &GetProductStepPriceLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理进入前逻辑w,r
|
||||||
|
// func (l *GetProductStepPriceLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (l *GetProductStepPriceLogic) GetProductStepPrice(req *types.GetProductStepPriceReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
|
if req.ProductId <= 0 {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "err param:product id")
|
||||||
|
}
|
||||||
|
//获取产品信息(只是获取id)
|
||||||
|
_, err := l.svcCtx.AllModels.FsProduct.FindOne(l.ctx, req.ProductId, "id")
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "the product is not exists")
|
||||||
|
}
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product info")
|
||||||
|
}
|
||||||
|
//查询产品价格
|
||||||
|
modelPriceList, err := l.svcCtx.AllModels.FsProductModel3d.GetAllByProductIdTag(l.ctx, req.ProductId, constants.TAG_MODEL, "id,size_id,part_id,step_price,packed_unit")
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get model price list")
|
||||||
|
}
|
||||||
|
fittingIds := make([]int64, 0, len(modelPriceList))
|
||||||
|
for _, v := range modelPriceList {
|
||||||
|
if *v.PartId > 0 {
|
||||||
|
fittingIds = append(fittingIds, *v.PartId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//查询配件价格列表
|
||||||
|
fittingPriceList, err := l.svcCtx.AllModels.FsProductModel3d.GetAllByIdsTag(l.ctx, fittingIds, constants.TAG_PARTS, "id,price,packed_unit")
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get fitting price list")
|
||||||
|
}
|
||||||
|
mapFitting := make(map[int64]gmodel.FsProductModel3d)
|
||||||
|
for _, v := range fittingPriceList {
|
||||||
|
mapFitting[v.Id] = v
|
||||||
|
}
|
||||||
|
//遍历处理模型价格
|
||||||
|
mapRsp := make(map[string]interface{})
|
||||||
|
for _, modelPriceInfo := range modelPriceList {
|
||||||
|
var stepPrice gmodel.StepPriceJsonStruct
|
||||||
|
if err = json.Unmarshal(*modelPriceInfo.StepPrice, &stepPrice); err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeJsonErr, "failed to parse step price json")
|
||||||
|
}
|
||||||
|
rangeLen := len(stepPrice.PriceRange)
|
||||||
|
if rangeLen == 0 {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeServiceErr, fmt.Sprintf("step price is not set:%d", modelPriceInfo.Id))
|
||||||
|
}
|
||||||
|
//最小单价
|
||||||
|
minPrice := stepPrice.PriceRange[rangeLen-1].Price
|
||||||
|
//最大单价
|
||||||
|
maxPrice := stepPrice.PriceRange[0].Price
|
||||||
|
//购买数步进基数
|
||||||
|
stepPurchaseQuantity := *modelPriceInfo.PackedUnit
|
||||||
|
//购买数步进基数描述
|
||||||
|
stepPurchaseQuantityDescription := "主体装箱数为步进基数"
|
||||||
|
if *modelPriceInfo.PartId > 0 {
|
||||||
|
fittingPriceInfo, ok := mapFitting[*modelPriceInfo.PartId]
|
||||||
|
if !ok {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeServiceErr, fmt.Sprintf("fitting price is not exists:%d", *modelPriceInfo.PartId))
|
||||||
|
}
|
||||||
|
//最小价格要加配件
|
||||||
|
minPrice += *fittingPriceInfo.Price
|
||||||
|
//如果配件装箱基数比主体大,则基数以配件为主
|
||||||
|
if *fittingPriceInfo.PackedUnit > stepPurchaseQuantity {
|
||||||
|
stepPurchaseQuantity = *fittingPriceInfo.PackedUnit
|
||||||
|
stepPurchaseQuantityDescription = "配件装箱数为步进基数"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stepRange := make([]interface{}, 0, rangeLen)
|
||||||
|
for rIndex, rangeInfo := range stepPrice.PriceRange {
|
||||||
|
//最后一个
|
||||||
|
if rIndex+1 == rangeLen {
|
||||||
|
stepRange = append(stepRange, map[string]interface{}{
|
||||||
|
"range_description": fmt.Sprintf(">=%s Units", format.NumToStringWithThousandthPercentile(rangeInfo.StartQuantity)),
|
||||||
|
"item_price": format.CentitoDollar(rangeInfo.Price, 3),
|
||||||
|
})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
stepRange = append(stepRange, map[string]interface{}{
|
||||||
|
"range_description": fmt.Sprintf("%s-%s Units", format.NumToStringWithThousandthPercentile(rangeInfo.StartQuantity), format.NumToStringWithThousandthPercentile(rangeInfo.EndQuantity)),
|
||||||
|
"item_price": format.CentitoDollar(rangeInfo.Price, 3),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
mapRsp[fmt.Sprintf("_%d", *modelPriceInfo.SizeId)] = map[string]interface{}{
|
||||||
|
"step_purchase_quantity": stepPurchaseQuantity,
|
||||||
|
"step_purchase_quantity_description": stepPurchaseQuantityDescription,
|
||||||
|
"min_price": minPrice,
|
||||||
|
"max_price": maxPrice,
|
||||||
|
"step_range": stepRange,
|
||||||
|
"min_buy_units_quantity": stepPrice.MinBuyUnitsNum,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeOK, "success", mapRsp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
// func (l *GetProductStepPriceLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||||
|
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
// }
|
||||||
@ -77,8 +77,8 @@ func (l *GetRenderSettingByPidLogic) GetRenderSettingByPid(req *types.GetRenderS
|
|||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get user info")
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get user info")
|
||||||
}
|
}
|
||||||
isLowRendering = *user.IsLowRendering > 0
|
isLowRendering = true
|
||||||
isRemoveBg = *user.IsRemoveBg > 0
|
isRemoveBg = true
|
||||||
lastDesign, err = l.checkLastDesignExists(user.Id)
|
lastDesign, err = l.checkLastDesignExists(user.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
|
|||||||
@ -59,7 +59,10 @@ func (l *GetSizeByPidLogic) GetSizeByPid(req *types.GetSizeByPidReq, userinfo *a
|
|||||||
} else {
|
} else {
|
||||||
//根据模板找到模型sizeId
|
//根据模板找到模型sizeId
|
||||||
defaultModel3d, err := l.svcCtx.AllModels.FsProductModel3d.FindOne(l.ctx, *defaultTemplate.ModelId, "size_id")
|
defaultModel3d, err := l.svcCtx.AllModels.FsProductModel3d.FindOne(l.ctx, *defaultTemplate.ModelId, "size_id")
|
||||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
if err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "the template`s model is not exists ")
|
||||||
|
}
|
||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get default model ")
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get default model ")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,16 +1,10 @@
|
|||||||
package logic
|
package logic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"fusenapi/constants"
|
|
||||||
"fusenapi/model/gmodel"
|
|
||||||
"fusenapi/utils/auth"
|
"fusenapi/utils/auth"
|
||||||
"fusenapi/utils/basic"
|
"fusenapi/utils/basic"
|
||||||
"fusenapi/utils/format"
|
|
||||||
"fusenapi/utils/step_price"
|
"context"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"fusenapi/server/product/internal/svc"
|
"fusenapi/server/product/internal/svc"
|
||||||
"fusenapi/server/product/internal/types"
|
"fusenapi/server/product/internal/types"
|
||||||
@ -32,157 +26,18 @@ func NewGetSizeByProductLogic(ctx context.Context, svcCtx *svc.ServiceContext) *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取分类下的产品以及尺寸
|
// 处理进入前逻辑w,r
|
||||||
|
// func (l *GetSizeByProductLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// }
|
||||||
|
|
||||||
func (l *GetSizeByProductLogic) GetSizeByProduct(req *types.Request, userinfo *auth.UserInfo) (resp *basic.Response) {
|
func (l *GetSizeByProductLogic) GetSizeByProduct(req *types.Request, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
if userinfo.GetIdType() != auth.IDTYPE_User {
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
return resp.SetStatusWithMessage(basic.CodeUnAuth, "please sign in first")
|
// userinfo 传入值时, 一定不为null
|
||||||
}
|
|
||||||
//获取所有网站目录
|
return resp.SetStatus(basic.CodeOK)
|
||||||
tagsModel := gmodel.NewFsTagsModel(l.svcCtx.MysqlConn)
|
|
||||||
tagsList, err := tagsModel.GetAllByLevel(l.ctx, constants.TYPE_WEBSITE)
|
|
||||||
if err != nil {
|
|
||||||
logx.Error(err)
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get website tags")
|
|
||||||
}
|
|
||||||
if len(tagsList) == 0 {
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeOK, "tag list is null")
|
|
||||||
}
|
|
||||||
tagIds := make([]int64, 0, len(tagsList))
|
|
||||||
for _, v := range tagsList {
|
|
||||||
tagIds = append(tagIds, v.Id)
|
|
||||||
}
|
|
||||||
//获取这些类型的产品
|
|
||||||
productModel := gmodel.NewFsProductModel(l.svcCtx.MysqlConn)
|
|
||||||
productList, err := productModel.GetProductListByIds(l.ctx, tagIds, "sort-desc")
|
|
||||||
if err != nil {
|
|
||||||
logx.Error(err)
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get tag product list")
|
|
||||||
}
|
|
||||||
productIds := make([]int64, 0, len(productList))
|
|
||||||
for _, v := range productList {
|
|
||||||
productIds = append(productIds, v.Id)
|
|
||||||
}
|
|
||||||
productSizeModel := gmodel.NewFsProductSizeModel(l.svcCtx.MysqlConn)
|
|
||||||
productSizeList, err := productSizeModel.GetAllByProductIds(l.ctx, productIds, "sort DESC")
|
|
||||||
if err != nil {
|
|
||||||
logx.Error(err)
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product size list")
|
|
||||||
}
|
|
||||||
sizeIds := make([]int64, 0, len(productSizeList))
|
|
||||||
for _, v := range productSizeList {
|
|
||||||
sizeIds = append(sizeIds, v.Id)
|
|
||||||
}
|
|
||||||
//获取价格列表
|
|
||||||
productPriceModel := gmodel.NewFsProductPriceModel(l.svcCtx.MysqlConn)
|
|
||||||
productPriceList, err := productPriceModel.GetPriceListByProductIdsSizeIds(l.ctx, productIds, sizeIds)
|
|
||||||
if err != nil {
|
|
||||||
logx.Error(err)
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product proce list")
|
|
||||||
}
|
|
||||||
mapProductPrice := make(map[string]gmodel.FsProductPrice)
|
|
||||||
for _, v := range productPriceList {
|
|
||||||
mapProductPrice[fmt.Sprintf("%d_%d", *v.ProductId, *v.SizeId)] = v
|
|
||||||
}
|
|
||||||
//组装返回
|
|
||||||
list := make([]types.GetSizeByProductRsp, 0, len(tagsList))
|
|
||||||
for _, tag := range tagsList {
|
|
||||||
//获取第一层子类
|
|
||||||
firstChildrenList, err := l.GetFirstChildrenList(tag, productList, productSizeList, mapProductPrice)
|
|
||||||
if err != nil {
|
|
||||||
logx.Error(err)
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get first level children list")
|
|
||||||
}
|
|
||||||
data := types.GetSizeByProductRsp{
|
|
||||||
Id: tag.Id,
|
|
||||||
Name: *tag.Title,
|
|
||||||
Children: firstChildrenList,
|
|
||||||
}
|
|
||||||
list = append(list, data)
|
|
||||||
}
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeOK, "success", list)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 第一层子层
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
func (l *GetSizeByProductLogic) GetFirstChildrenList(tag gmodel.FsTags, productList []gmodel.FsProduct, productSizeList []gmodel.FsProductSize, mapProductPrice map[string]gmodel.FsProductPrice) (childrenList []types.Children, err error) {
|
// func (l *GetSizeByProductLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||||
childrenList = make([]types.Children, 0, len(productList))
|
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
for _, product := range productList {
|
// }
|
||||||
if *product.Type != tag.Id {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
childrenObjList, err := l.GetSecondChildrenList(product, productSizeList, mapProductPrice)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
//获取第二层子类
|
|
||||||
data := types.Children{
|
|
||||||
Id: product.Id,
|
|
||||||
Name: *product.Title,
|
|
||||||
Cycle: int(*product.DeliveryDays + *product.ProduceDays),
|
|
||||||
ChildrenList: childrenObjList,
|
|
||||||
}
|
|
||||||
childrenList = append(childrenList, data)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 第2层子层
|
|
||||||
func (l *GetSizeByProductLogic) GetSecondChildrenList(product gmodel.FsProduct, productSizeList []gmodel.FsProductSize, mapProductPrice map[string]gmodel.FsProductPrice) (childrenObjList []types.ChildrenObj, err error) {
|
|
||||||
childrenObjList = make([]types.ChildrenObj, 0, len(productSizeList))
|
|
||||||
for _, productSize := range productSizeList {
|
|
||||||
if product.Id != *productSize.ProductId {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
priceList := make([]types.PriceObj, 0, len(productSizeList))
|
|
||||||
price, ok := mapProductPrice[fmt.Sprintf("%d_%d", *productSize.ProductId, productSize.Id)]
|
|
||||||
//无对应尺寸价格
|
|
||||||
if !ok {
|
|
||||||
priceList = []types.PriceObj{
|
|
||||||
{Num: 1, Price: 0},
|
|
||||||
{Num: 1, Price: 0},
|
|
||||||
{Num: 1, Price: 0},
|
|
||||||
}
|
|
||||||
childrenObjList = append(childrenObjList, types.ChildrenObj{
|
|
||||||
Id: productSize.Id,
|
|
||||||
Name: *productSize.Capacity,
|
|
||||||
PriceList: priceList,
|
|
||||||
})
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if price.StepNum == nil || price.StepPrice == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
*price.StepNum = strings.Trim(*price.StepNum, " ")
|
|
||||||
*price.StepPrice = strings.Trim(*price.StepPrice, " ")
|
|
||||||
|
|
||||||
//阶梯数量切片
|
|
||||||
stepNum, err := format.StrSlicToIntSlice(strings.Split(*price.StepNum, ","))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
//阶梯价格切片
|
|
||||||
stepPrice, err := format.StrSlicToIntSlice(strings.Split(*price.StepPrice, ","))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(stepNum) == 0 || len(stepPrice) == 0 {
|
|
||||||
return nil, errors.New(fmt.Sprintf("stepNum count or stepPrice count is empty: product size id :%d ,product price id :%d", productSize.Id, price.Id))
|
|
||||||
}
|
|
||||||
index := 0
|
|
||||||
// 最小购买数量小于 最大阶梯数量+5
|
|
||||||
for int(*price.MinBuyNum) < (stepNum[len(stepNum)-1]+5) && index < 3 {
|
|
||||||
priceList = append(priceList, types.PriceObj{
|
|
||||||
Num: int(*price.MinBuyNum * *price.EachBoxNum),
|
|
||||||
Price: step_price.GetStepPrice(int(*price.MinBuyNum), stepNum, stepPrice),
|
|
||||||
})
|
|
||||||
*price.MinBuyNum++
|
|
||||||
index++
|
|
||||||
}
|
|
||||||
data := types.ChildrenObj{
|
|
||||||
Id: productSize.Id,
|
|
||||||
Name: *productSize.Capacity,
|
|
||||||
PriceList: priceList,
|
|
||||||
}
|
|
||||||
childrenObjList = append(childrenObjList, data)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import (
|
|||||||
"fusenapi/utils/auth"
|
"fusenapi/utils/auth"
|
||||||
"fusenapi/utils/basic"
|
"fusenapi/utils/basic"
|
||||||
"fusenapi/utils/image"
|
"fusenapi/utils/image"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
@ -75,7 +76,7 @@ func (l *GetSuccessRecommandLogic) GetSuccessRecommand(req *types.GetSuccessReco
|
|||||||
UserId: user.Id,
|
UserId: user.Id,
|
||||||
}
|
}
|
||||||
if user.Id > 0 {
|
if user.Id > 0 {
|
||||||
r.IsThousandFace = int(*user.IsThousandFace)
|
r.IsThousandFace = int(1)
|
||||||
}
|
}
|
||||||
image.ThousandFaceImageFormat(&r)
|
image.ThousandFaceImageFormat(&r)
|
||||||
data.Cover = r.Cover
|
data.Cover = r.Cover
|
||||||
|
|||||||
@ -8,9 +8,10 @@ import (
|
|||||||
"fusenapi/utils/basic"
|
"fusenapi/utils/basic"
|
||||||
"fusenapi/utils/format"
|
"fusenapi/utils/format"
|
||||||
"fusenapi/utils/image"
|
"fusenapi/utils/image"
|
||||||
"gorm.io/gorm"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
|
||||||
"fusenapi/server/product/internal/svc"
|
"fusenapi/server/product/internal/svc"
|
||||||
"fusenapi/server/product/internal/types"
|
"fusenapi/server/product/internal/types"
|
||||||
|
|
||||||
@ -83,7 +84,7 @@ func (l *OtherProductListLogic) OtherProductList(req *types.OtherProductListReq,
|
|||||||
UserId: user.Id,
|
UserId: user.Id,
|
||||||
}
|
}
|
||||||
if user.Id > 0 {
|
if user.Id > 0 {
|
||||||
r.IsThousandFace = int(*user.IsThousandFace)
|
r.IsThousandFace = 1
|
||||||
}
|
}
|
||||||
image.ThousandFaceImageFormat(r)
|
image.ThousandFaceImageFormat(r)
|
||||||
v.Cover = r.Cover
|
v.Cover = r.Cover
|
||||||
|
|||||||
@ -5,6 +5,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"fusenapi/server/product/internal/config"
|
"fusenapi/server/product/internal/config"
|
||||||
"fusenapi/shared"
|
"fusenapi/shared"
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"fusenapi/initalize"
|
"fusenapi/initalize"
|
||||||
@ -18,15 +21,28 @@ type ServiceContext struct {
|
|||||||
Config config.Config
|
Config config.Config
|
||||||
SharedState *shared.SharedState
|
SharedState *shared.SharedState
|
||||||
|
|
||||||
MysqlConn *gorm.DB
|
MysqlConn *gorm.DB
|
||||||
AllModels *gmodel.AllModelsGen
|
AllModels *gmodel.AllModelsGen
|
||||||
|
Repositories *initalize.Repositories
|
||||||
|
AwsSession *session.Session
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
|
conn := initalize.InitMysql(c.SourceMysql)
|
||||||
|
config := aws.Config{
|
||||||
|
Credentials: credentials.NewStaticCredentials(c.AWS.S3.Credentials.AccessKeyID, c.AWS.S3.Credentials.Secret, c.AWS.S3.Credentials.Token),
|
||||||
|
}
|
||||||
|
|
||||||
return &ServiceContext{
|
return &ServiceContext{
|
||||||
Config: c,
|
Config: c,
|
||||||
MysqlConn: initalize.InitMysql(c.SourceMysql),
|
MysqlConn: initalize.InitMysql(c.SourceMysql),
|
||||||
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
||||||
|
AwsSession: session.Must(session.NewSession(&config)),
|
||||||
|
Repositories: initalize.NewAllRepositories(&initalize.NewAllRepositorieData{
|
||||||
|
GormDB: conn,
|
||||||
|
BLMServiceUrl: &c.BLMService.Url,
|
||||||
|
AwsSession: session.Must(session.NewSession(&config)),
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -331,6 +331,23 @@ type PriceItem struct {
|
|||||||
Price int64 `json:"price"`
|
Price int64 `json:"price"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetProductStepPriceReq struct {
|
||||||
|
ProductId int64 `form:"product_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CalculateProductPriceReq struct {
|
||||||
|
ProductId int64 `json:"product_id"`
|
||||||
|
SizeId int64 `json:"size_id"`
|
||||||
|
FittingId int64 `json:"fitting_id,optional"`
|
||||||
|
PurchaseQuantity int64 `json:"purchase_quantity"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CalculateProductPriceRsp struct {
|
||||||
|
ItemPrice string `json:"item_price"`
|
||||||
|
TotalPrice string `json:"total_price"`
|
||||||
|
PurchaseQuantity int64 `json:"purchase_quantity"`
|
||||||
|
}
|
||||||
|
|
||||||
type GetSizeByPidReq struct {
|
type GetSizeByPidReq struct {
|
||||||
Pid string `form:"pid"`
|
Pid string `form:"pid"`
|
||||||
TemplateTag string `form:"template_tag"`
|
TemplateTag string `form:"template_tag"`
|
||||||
@ -440,10 +457,10 @@ type File struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Meta struct {
|
type Meta struct {
|
||||||
TotalCount int64 `json:"totalCount"`
|
TotalCount int64 `json:"total_count"`
|
||||||
PageCount int64 `json:"pageCount"`
|
PageCount int64 `json:"page_count"`
|
||||||
CurrentPage int `json:"currentPage"`
|
CurrentPage int `json:"current_page"`
|
||||||
PerPage int `json:"perPage"`
|
PerPage int `json:"per_page"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set 设置Response的Code和Message值
|
// Set 设置Response的Code和Message值
|
||||||
|
|||||||
@ -10,6 +10,8 @@ import (
|
|||||||
"fusenapi/server/shopping-cart/internal/types"
|
"fusenapi/server/shopping-cart/internal/types"
|
||||||
"fusenapi/utils/auth"
|
"fusenapi/utils/auth"
|
||||||
"fusenapi/utils/basic"
|
"fusenapi/utils/basic"
|
||||||
|
"fusenapi/utils/file"
|
||||||
|
"fusenapi/utils/hash"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -51,6 +53,31 @@ func (l *AddToCartLogic) AddToCart(req *types.AddToCartReq, userinfo *auth.UserI
|
|||||||
if cartCount >= 100 {
|
if cartCount >= 100 {
|
||||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "sorry,the count of your carts can`t greater than 100")
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "sorry,the count of your carts can`t greater than 100")
|
||||||
}
|
}
|
||||||
|
if req.RenderImage != "" {
|
||||||
|
//上传base64文件
|
||||||
|
// 上传文件
|
||||||
|
var upload = file.Upload{
|
||||||
|
Ctx: l.ctx,
|
||||||
|
MysqlConn: l.svcCtx.MysqlConn,
|
||||||
|
AwsSession: l.svcCtx.AwsSession,
|
||||||
|
}
|
||||||
|
uploadRes, err := upload.UploadFileByBase64(&file.UploadBaseReq{
|
||||||
|
Source: "webGl render image",
|
||||||
|
FileHash: hash.JsonHashKey(req.RenderImage),
|
||||||
|
FileData: req.RenderImage,
|
||||||
|
Metadata: "",
|
||||||
|
UploadBucket: 1,
|
||||||
|
ApiType: 2,
|
||||||
|
UserId: userinfo.UserId,
|
||||||
|
GuestId: userinfo.GuestId,
|
||||||
|
FileByte: nil,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeFileUploadErr, "failed to upload webGl render image")
|
||||||
|
}
|
||||||
|
req.RenderImage = uploadRes.ResourceUrl
|
||||||
|
}
|
||||||
//获取产品是否存在
|
//获取产品是否存在
|
||||||
productInfo, err := l.svcCtx.AllModels.FsProduct.FindOne(l.ctx, req.ProductId)
|
productInfo, err := l.svcCtx.AllModels.FsProduct.FindOne(l.ctx, req.ProductId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -2,9 +2,9 @@ package logic
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"fusenapi/constants"
|
|
||||||
"fusenapi/model/gmodel"
|
"fusenapi/model/gmodel"
|
||||||
"fusenapi/server/shopping-cart/internal/svc"
|
"fusenapi/server/shopping-cart/internal/svc"
|
||||||
"fusenapi/server/shopping-cart/internal/types"
|
"fusenapi/server/shopping-cart/internal/types"
|
||||||
@ -53,7 +53,7 @@ func (l *CalculateCartPriceLogic) CalculateCartPrice(req *types.CalculateCartPri
|
|||||||
//获取购物车列表
|
//获取购物车列表
|
||||||
carts, _, err := l.svcCtx.AllModels.FsShoppingCart.GetAllCartsByParam(l.ctx, gmodel.GetAllCartsByParamReq{
|
carts, _, err := l.svcCtx.AllModels.FsShoppingCart.GetAllCartsByParam(l.ctx, gmodel.GetAllCartsByParamReq{
|
||||||
Ids: cartIds,
|
Ids: cartIds,
|
||||||
Fields: "id,size_id,product_id,fitting_id",
|
Fields: "id,size_id,product_id,fitting_id,model_id",
|
||||||
UserId: userinfo.UserId,
|
UserId: userinfo.UserId,
|
||||||
Page: 1,
|
Page: 1,
|
||||||
Limit: len(cartIds),
|
Limit: len(cartIds),
|
||||||
@ -67,33 +67,24 @@ func (l *CalculateCartPriceLogic) CalculateCartPrice(req *types.CalculateCartPri
|
|||||||
}
|
}
|
||||||
sizeIds := make([]int64, 0, len(carts))
|
sizeIds := make([]int64, 0, len(carts))
|
||||||
productIds := make([]int64, 0, len(carts))
|
productIds := make([]int64, 0, len(carts))
|
||||||
fittingIds := make([]int64, 0, len(carts))
|
modelIds := make([]int64, 0, len(carts)) //模型+配件
|
||||||
for _, v := range carts {
|
for _, v := range carts {
|
||||||
sizeIds = append(sizeIds, *v.SizeId)
|
sizeIds = append(sizeIds, *v.SizeId)
|
||||||
productIds = append(productIds, *v.ProductId)
|
productIds = append(productIds, *v.ProductId)
|
||||||
|
modelIds = append(modelIds, *v.ModelId)
|
||||||
if *v.FittingId > 0 {
|
if *v.FittingId > 0 {
|
||||||
fittingIds = append(fittingIds, *v.FittingId)
|
modelIds = append(modelIds, *v.FittingId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//根据sizeid获取价格列表
|
|
||||||
priceList, err := l.svcCtx.AllModels.FsProductPrice.GetPriceListByProductIdsSizeIds(l.ctx, productIds, sizeIds)
|
|
||||||
if err != nil {
|
|
||||||
logx.Error(err)
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get price list")
|
|
||||||
}
|
|
||||||
mapPrice := make(map[string]gmodel.FsProductPrice)
|
|
||||||
for _, v := range priceList {
|
|
||||||
mapPrice[fmt.Sprintf("%d_%d", *v.ProductId, *v.SizeId)] = v
|
|
||||||
}
|
|
||||||
//获取配件列表(只有id跟价格)
|
//获取配件列表(只有id跟价格)
|
||||||
fittingList, err := l.svcCtx.AllModels.FsProductModel3d.GetAllByIdsTag(l.ctx, fittingIds, constants.TAG_PARTS, "id,price")
|
modelList, err := l.svcCtx.AllModels.FsProductModel3d.GetAllByIds(l.ctx, modelIds, "id,step_price,price")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get fitting list")
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get model list")
|
||||||
}
|
}
|
||||||
mapFitting := make(map[int64]int64)
|
mapModel := make(map[int64]gmodel.FsProductModel3d)
|
||||||
for _, v := range fittingList {
|
for _, v := range modelList {
|
||||||
mapFitting[v.Id] = *v.Price
|
mapModel[v.Id] = v
|
||||||
}
|
}
|
||||||
//开始计算价格
|
//开始计算价格
|
||||||
calculateResultList := make([]types.CalculateResultItem, 0, len(req.CalculateList))
|
calculateResultList := make([]types.CalculateResultItem, 0, len(req.CalculateList))
|
||||||
@ -102,9 +93,16 @@ func (l *CalculateCartPriceLogic) CalculateCartPrice(req *types.CalculateCartPri
|
|||||||
err = l.svcCtx.MysqlConn.Transaction(func(tx *gorm.DB) error {
|
err = l.svcCtx.MysqlConn.Transaction(func(tx *gorm.DB) error {
|
||||||
shoppingCartModel := gmodel.NewFsShoppingCartModel(tx)
|
shoppingCartModel := gmodel.NewFsShoppingCartModel(tx)
|
||||||
for _, cart := range carts {
|
for _, cart := range carts {
|
||||||
sizePrice, ok := mapPrice[fmt.Sprintf("%d_%d", *cart.ProductId, *cart.SizeId)]
|
modelInfo, ok := mapModel[*cart.ModelId]
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New(fmt.Sprintf("there carts contain some one which have no price info:%d_%d", *cart.ProductId, *cart.SizeId))
|
return err
|
||||||
|
}
|
||||||
|
var stepPrice gmodel.StepPriceJsonStruct
|
||||||
|
if modelInfo.StepPrice != nil && len(*modelInfo.StepPrice) != 0 {
|
||||||
|
if err = json.Unmarshal(*modelInfo.StepPrice, &stepPrice); err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//请求的数量
|
//请求的数量
|
||||||
reqPurchaseQuantity := mapCalculateQuantity[cart.Id].PurchaseQuantity
|
reqPurchaseQuantity := mapCalculateQuantity[cart.Id].PurchaseQuantity
|
||||||
@ -115,16 +113,15 @@ func (l *CalculateCartPriceLogic) CalculateCartPrice(req *types.CalculateCartPri
|
|||||||
//如果有配件,单价也要加入配件价格
|
//如果有配件,单价也要加入配件价格
|
||||||
fittingPrice := int64(0)
|
fittingPrice := int64(0)
|
||||||
if *cart.FittingId > 0 {
|
if *cart.FittingId > 0 {
|
||||||
if fPrice, ok := mapFitting[*cart.FittingId]; ok {
|
if fittingInfo, ok := mapModel[*cart.FittingId]; ok {
|
||||||
fittingPrice = fPrice
|
fittingPrice = *fittingInfo.Price
|
||||||
} else {
|
} else {
|
||||||
return errors.New(fmt.Sprintf("cart contain some one witch lose fitting:%d", *cart.FittingId))
|
return errors.New(fmt.Sprintf("cart contain some one witch lose fitting:%d", *cart.FittingId))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//计算价格
|
//计算价格
|
||||||
itemPrice, totalPrice, _, _, err := l.svcCtx.Repositories.NewShoppingCart.CaculateCartPrice(reqPurchaseQuantity, &sizePrice, fittingPrice)
|
totalPrice, itemPrice, err := l.svcCtx.Repositories.NewShoppingCart.CaculateStepPrice(reqPurchaseQuantity, stepPrice, fittingPrice)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
calculateResultList = append(calculateResultList, types.CalculateResultItem{
|
calculateResultList = append(calculateResultList, types.CalculateResultItem{
|
||||||
@ -149,6 +146,7 @@ func (l *CalculateCartPriceLogic) CalculateCartPrice(req *types.CalculateCartPri
|
|||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
logx.Error(err)
|
||||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, err.Error())
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, err.Error())
|
||||||
}
|
}
|
||||||
return resp.SetStatusWithMessage(basic.CodeOK, "success", types.CalculateCartPriceRsp{
|
return resp.SetStatusWithMessage(basic.CodeOK, "success", types.CalculateCartPriceRsp{
|
||||||
|
|||||||
@ -41,37 +41,28 @@ func (l *GetCartsLogic) GetCarts(req *types.GetCartsReq, userinfo *auth.UserInfo
|
|||||||
if !userinfo.IsUser() {
|
if !userinfo.IsUser() {
|
||||||
return resp.SetStatusWithMessage(basic.CodeUnAuth, "please sign in")
|
return resp.SetStatusWithMessage(basic.CodeUnAuth, "please sign in")
|
||||||
}
|
}
|
||||||
if req.CurrentPage <= 0 {
|
currentPage := constants.DEFAULT_PAGE
|
||||||
req.CurrentPage = constants.DEFAULT_PAGE
|
|
||||||
}
|
|
||||||
limit := 300
|
limit := 300
|
||||||
//获取用户购物车列表
|
//获取用户购物车列表
|
||||||
|
var cartIds []int64
|
||||||
|
if req.CartId > 0 {
|
||||||
|
cartIds = append(cartIds, req.CartId)
|
||||||
|
}
|
||||||
carts, total, err := l.svcCtx.AllModels.FsShoppingCart.GetAllCartsByParam(l.ctx, gmodel.GetAllCartsByParamReq{
|
carts, total, err := l.svcCtx.AllModels.FsShoppingCart.GetAllCartsByParam(l.ctx, gmodel.GetAllCartsByParamReq{
|
||||||
|
Ids: cartIds,
|
||||||
UserId: userinfo.UserId,
|
UserId: userinfo.UserId,
|
||||||
Sort: "id DESC",
|
Sort: "id DESC",
|
||||||
Page: req.CurrentPage,
|
Page: currentPage,
|
||||||
Limit: limit,
|
Limit: limit,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "system err:failed to get your shopping carts")
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "system err:failed to get your shopping carts")
|
||||||
}
|
}
|
||||||
if len(carts) == 0 {
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeOK, "success", types.GetCartsRsp{
|
|
||||||
Meta: types.Meta{
|
|
||||||
TotalCount: total,
|
|
||||||
PageCount: int64(math.Ceil(float64(total) / float64(limit))),
|
|
||||||
CurrentPage: req.CurrentPage,
|
|
||||||
PerPage: limit,
|
|
||||||
},
|
|
||||||
CartList: nil,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
var (
|
var (
|
||||||
mapSize = make(map[int64]gmodel.FsProductSize)
|
mapSize = make(map[int64]gmodel.FsProductSize)
|
||||||
mapModel = make(map[int64]gmodel.FsProductModel3d)
|
mapModel = make(map[int64]gmodel.FsProductModel3d)
|
||||||
mapTemplate = make(map[int64]gmodel.FsProductTemplateV2)
|
mapTemplate = make(map[int64]gmodel.FsProductTemplateV2)
|
||||||
mapSizePrice = make(map[string]gmodel.FsProductPrice)
|
|
||||||
mapProduct = make(map[int64]gmodel.FsProduct)
|
mapProduct = make(map[int64]gmodel.FsProduct)
|
||||||
mapResourceMetadata = make(map[string]interface{})
|
mapResourceMetadata = make(map[string]interface{})
|
||||||
)
|
)
|
||||||
@ -81,7 +72,6 @@ func (l *GetCartsLogic) GetCarts(req *types.GetCartsReq, userinfo *auth.UserInfo
|
|||||||
MapSize: mapSize,
|
MapSize: mapSize,
|
||||||
MapModel: mapModel,
|
MapModel: mapModel,
|
||||||
MapTemplate: mapTemplate,
|
MapTemplate: mapTemplate,
|
||||||
MapSizePrice: mapSizePrice,
|
|
||||||
MapProduct: mapProduct,
|
MapProduct: mapProduct,
|
||||||
MapResourceMetadata: mapResourceMetadata,
|
MapResourceMetadata: mapResourceMetadata,
|
||||||
})
|
})
|
||||||
@ -109,21 +99,34 @@ func (l *GetCartsLogic) GetCarts(req *types.GetCartsReq, userinfo *auth.UserInfo
|
|||||||
list := make([]types.CartItem, 0, len(carts))
|
list := make([]types.CartItem, 0, len(carts))
|
||||||
for _, cart := range carts {
|
for _, cart := range carts {
|
||||||
snapShot := mapSnapshot[cart.Id]
|
snapShot := mapSnapshot[cart.Id]
|
||||||
sizePrice, ok := mapSizePrice[fmt.Sprintf("%d_%d", *cart.ProductId, *cart.SizeId)]
|
modelInfo, ok := mapModel[*cart.ModelId]
|
||||||
if !ok {
|
if !ok {
|
||||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, fmt.Sprintf("the size`s price info is not exists:%d_%d", *cart.ProductId, *cart.SizeId))
|
return resp.SetStatusWithMessage(basic.CodeServiceErr, fmt.Sprintf("the size`s model info is not exists:%d_%d", *cart.ProductId, *cart.SizeId))
|
||||||
}
|
}
|
||||||
|
var stepPrice gmodel.StepPriceJsonStruct
|
||||||
|
if modelInfo.StepPrice != nil && len(*modelInfo.StepPrice) != 0 {
|
||||||
|
if err = json.Unmarshal(*modelInfo.StepPrice, &stepPrice); err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeJsonErr, fmt.Sprintf("failed to parse model step price:%d", *cart.ModelId))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//购买数量步进量
|
||||||
|
stepPurchaseQuantity := *modelInfo.PackedUnit
|
||||||
//如果有配件,单价也要加入配件价格
|
//如果有配件,单价也要加入配件价格
|
||||||
fittingPrice := int64(0)
|
fittingPrice := int64(0)
|
||||||
if *cart.FittingId > 0 {
|
if *cart.FittingId > 0 {
|
||||||
if curFittingInfo, ok := mapModel[*cart.FittingId]; ok {
|
curFittingInfo, ok := mapModel[*cart.FittingId]
|
||||||
fittingPrice = *curFittingInfo.Price
|
if !ok {
|
||||||
} else {
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, fmt.Sprintf("cart contain some one witch lose fitting:%d", *cart.FittingId))
|
return resp.SetStatusWithMessage(basic.CodeServiceErr, fmt.Sprintf("cart contain some one witch lose fitting:%d", *cart.FittingId))
|
||||||
}
|
}
|
||||||
|
fittingPrice = *curFittingInfo.Price
|
||||||
|
//取大的为步进量基数
|
||||||
|
if *curFittingInfo.PackedUnit > stepPurchaseQuantity {
|
||||||
|
stepPurchaseQuantity = *curFittingInfo.PackedUnit
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//计算价格
|
//计算阶梯价格
|
||||||
itemPrice, totalPrice, _, _, err := l.svcCtx.Repositories.NewShoppingCart.CaculateCartPrice(*cart.PurchaseQuantity, &sizePrice, fittingPrice)
|
totalPrice, itemPrice, err := l.svcCtx.Repositories.NewShoppingCart.CaculateStepPrice(*cart.PurchaseQuantity, stepPrice, fittingPrice)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, err.Error())
|
return resp.SetStatusWithMessage(basic.CodeServiceErr, err.Error())
|
||||||
@ -152,6 +155,10 @@ func (l *GetCartsLogic) GetCarts(req *types.GetCartsReq, userinfo *auth.UserInfo
|
|||||||
productCoverMetadata = metadata
|
productCoverMetadata = metadata
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
templateTag := ""
|
||||||
|
if templateInfo, ok := mapTemplate[*cart.TemplateId]; ok {
|
||||||
|
templateTag = *templateInfo.TemplateTag
|
||||||
|
}
|
||||||
item := types.CartItem{
|
item := types.CartItem{
|
||||||
CartId: cart.Id,
|
CartId: cart.Id,
|
||||||
ProductInfo: types.ProductInfo{
|
ProductInfo: types.ProductInfo{
|
||||||
@ -183,10 +190,12 @@ func (l *GetCartsLogic) GetCarts(req *types.GetCartsReq, userinfo *auth.UserInfo
|
|||||||
Slogan: snapShot.UserDiyInformation.Slogan,
|
Slogan: snapShot.UserDiyInformation.Slogan,
|
||||||
},
|
},
|
||||||
PurchaseQuantity: *cart.PurchaseQuantity,
|
PurchaseQuantity: *cart.PurchaseQuantity,
|
||||||
MinPurchaseQuantity: *sizePrice.EachBoxNum * (*sizePrice.MinBuyNum),
|
MinPurchaseQuantity: stepPrice.MinBuyUnitsNum,
|
||||||
StepPurchaseQuantity: *sizePrice.EachBoxNum,
|
StepPurchaseQuantity: stepPurchaseQuantity,
|
||||||
IsHighlyCustomized: *cart.IsHighlyCustomized > 0,
|
IsHighlyCustomized: *cart.IsHighlyCustomized > 0,
|
||||||
IsSelected: *cart.IsSelected > 0,
|
IsSelected: *cart.IsSelected > 0,
|
||||||
|
TemplateTag: templateTag,
|
||||||
|
Logo: snapShot.Logo,
|
||||||
}
|
}
|
||||||
//是否有失效的
|
//是否有失效的
|
||||||
if description, ok := mapCartChange[cart.Id]; ok {
|
if description, ok := mapCartChange[cart.Id]; ok {
|
||||||
@ -201,7 +210,7 @@ func (l *GetCartsLogic) GetCarts(req *types.GetCartsReq, userinfo *auth.UserInfo
|
|||||||
Meta: types.Meta{
|
Meta: types.Meta{
|
||||||
TotalCount: total,
|
TotalCount: total,
|
||||||
PageCount: int64(math.Ceil(float64(total) / float64(limit))),
|
PageCount: int64(math.Ceil(float64(total) / float64(limit))),
|
||||||
CurrentPage: req.CurrentPage,
|
CurrentPage: currentPage,
|
||||||
PerPage: limit,
|
PerPage: limit,
|
||||||
},
|
},
|
||||||
CartList: list,
|
CartList: list,
|
||||||
@ -214,7 +223,6 @@ type GetRelationInfoReq struct {
|
|||||||
MapSize map[int64]gmodel.FsProductSize
|
MapSize map[int64]gmodel.FsProductSize
|
||||||
MapModel map[int64]gmodel.FsProductModel3d
|
MapModel map[int64]gmodel.FsProductModel3d
|
||||||
MapTemplate map[int64]gmodel.FsProductTemplateV2
|
MapTemplate map[int64]gmodel.FsProductTemplateV2
|
||||||
MapSizePrice map[string]gmodel.FsProductPrice
|
|
||||||
MapProduct map[int64]gmodel.FsProduct
|
MapProduct map[int64]gmodel.FsProduct
|
||||||
MapResourceMetadata map[string]interface{}
|
MapResourceMetadata map[string]interface{}
|
||||||
}
|
}
|
||||||
@ -282,15 +290,6 @@ func (l *GetCartsLogic) GetRelationInfo(req GetRelationInfoReq) error {
|
|||||||
for _, v := range templateList {
|
for _, v := range templateList {
|
||||||
req.MapTemplate[v.Id] = v
|
req.MapTemplate[v.Id] = v
|
||||||
}
|
}
|
||||||
//根据sizeid获取价格列表
|
|
||||||
priceList, err := l.svcCtx.AllModels.FsProductPrice.GetPriceListByProductIdsSizeIds(l.ctx, productIds, sizeIds)
|
|
||||||
if err != nil {
|
|
||||||
logx.Error(err)
|
|
||||||
return errors.New("failed to get cart`s product price list")
|
|
||||||
}
|
|
||||||
for _, v := range priceList {
|
|
||||||
req.MapSizePrice[fmt.Sprintf("%d_%d", *v.ProductId, *v.SizeId)] = v
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,7 @@ type ServiceContext struct {
|
|||||||
AllModels *gmodel.AllModelsGen
|
AllModels *gmodel.AllModelsGen
|
||||||
RabbitMq *initalize.RabbitMqHandle
|
RabbitMq *initalize.RabbitMqHandle
|
||||||
Repositories *initalize.Repositories
|
Repositories *initalize.Repositories
|
||||||
|
AwsSession *session.Session
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
@ -24,10 +25,11 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
|||||||
Credentials: credentials.NewStaticCredentials(c.AWS.S3.Credentials.AccessKeyID, c.AWS.S3.Credentials.Secret, c.AWS.S3.Credentials.Token),
|
Credentials: credentials.NewStaticCredentials(c.AWS.S3.Credentials.AccessKeyID, c.AWS.S3.Credentials.Secret, c.AWS.S3.Credentials.Token),
|
||||||
}
|
}
|
||||||
return &ServiceContext{
|
return &ServiceContext{
|
||||||
Config: c,
|
Config: c,
|
||||||
MysqlConn: conn,
|
MysqlConn: conn,
|
||||||
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
||||||
RabbitMq: initalize.InitRabbitMq(c.SourceRabbitMq, nil),
|
RabbitMq: initalize.InitRabbitMq(c.SourceRabbitMq, nil),
|
||||||
|
AwsSession: session.Must(session.NewSession(&config)),
|
||||||
Repositories: initalize.NewAllRepositories(&initalize.NewAllRepositorieData{
|
Repositories: initalize.NewAllRepositories(&initalize.NewAllRepositorieData{
|
||||||
GormDB: conn,
|
GormDB: conn,
|
||||||
BLMServiceUrl: &c.BLMService.Url,
|
BLMServiceUrl: &c.BLMService.Url,
|
||||||
|
|||||||
@ -30,7 +30,7 @@ type DeleteCartReq struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type GetCartsReq struct {
|
type GetCartsReq struct {
|
||||||
CurrentPage int `form:"current_page"` //当前页
|
CartId int64 `form:"cart_id,optional"` //购物车ids可选
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetCartsRsp struct {
|
type GetCartsRsp struct {
|
||||||
@ -53,6 +53,8 @@ type CartItem struct {
|
|||||||
IsInvalid bool `json:"is_invalid"` //是否无效
|
IsInvalid bool `json:"is_invalid"` //是否无效
|
||||||
InvalidDescription string `json:"invalid_description"` //无效原因
|
InvalidDescription string `json:"invalid_description"` //无效原因
|
||||||
IsSelected bool `json:"is_selected"` //是否选中
|
IsSelected bool `json:"is_selected"` //是否选中
|
||||||
|
TemplateTag string `json:"template_tag"` //模板标签
|
||||||
|
Logo string `json:"logo"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProductInfo struct {
|
type ProductInfo struct {
|
||||||
|
|||||||
@ -67,9 +67,9 @@ var (
|
|||||||
//websocket连接存储
|
//websocket连接存储
|
||||||
mapConnPool = sync.Map{}
|
mapConnPool = sync.Map{}
|
||||||
//每个websocket连接入口缓冲队列长度默认值
|
//每个websocket连接入口缓冲队列长度默认值
|
||||||
websocketInChanLen = 500
|
websocketInChanLen = 2000
|
||||||
//每个websocket连接出口缓冲队列长度默认值
|
//每个websocket连接出口缓冲队列长度默认值
|
||||||
websocketOutChanLen = 500
|
websocketOutChanLen = 2000
|
||||||
//是否开启debug
|
//是否开启debug
|
||||||
openDebug = true
|
openDebug = true
|
||||||
//允许跨域的origin
|
//允许跨域的origin
|
||||||
@ -192,7 +192,7 @@ func (l *DataTransferLogic) setConnPool(conn *websocket.Conn, userInfo *auth.Use
|
|||||||
userId: userInfo.UserId,
|
userId: userInfo.UserId,
|
||||||
guestId: userInfo.GuestId,
|
guestId: userInfo.GuestId,
|
||||||
extendRenderProperty: extendRenderProperty{
|
extendRenderProperty: extendRenderProperty{
|
||||||
renderChan: make(chan []byte, renderChanLen),
|
renderChan: make(chan websocket_data.RenderImageReqMsg, renderChanLen),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
//保存连接
|
//保存连接
|
||||||
|
|||||||
@ -22,6 +22,8 @@ import (
|
|||||||
var (
|
var (
|
||||||
//每个websocket渲染任务缓冲队列长度默认值
|
//每个websocket渲染任务缓冲队列长度默认值
|
||||||
renderChanLen = 500
|
renderChanLen = 500
|
||||||
|
//每个websocket渲染并发数
|
||||||
|
renderChanConcurrency = 500
|
||||||
)
|
)
|
||||||
|
|
||||||
// 渲染处理器
|
// 渲染处理器
|
||||||
@ -30,16 +32,25 @@ type renderProcessor struct {
|
|||||||
|
|
||||||
// 云渲染属性
|
// 云渲染属性
|
||||||
type extendRenderProperty struct {
|
type extendRenderProperty struct {
|
||||||
renderChan chan []byte //渲染消息入口的缓冲队列
|
renderChan chan websocket_data.RenderImageReqMsg //渲染消息入口的缓冲队列
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理分发到这里的数据
|
// 处理分发到这里的数据
|
||||||
func (r *renderProcessor) allocationMessage(w *wsConnectItem, data []byte) {
|
func (r *renderProcessor) allocationMessage(w *wsConnectItem, data []byte) {
|
||||||
//logx.Info("开始处理渲染任务消息:", string(data))
|
logx.Info("收到渲染任务消息")
|
||||||
|
var renderImageData websocket_data.RenderImageReqMsg
|
||||||
|
if err := json.Unmarshal(data, &renderImageData); err != nil {
|
||||||
|
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "数据格式错误", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, 0, 0)
|
||||||
|
logx.Error("invalid format of websocket render image message", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
select {
|
select {
|
||||||
case <-w.closeChan: //已经关闭
|
case <-w.closeChan: //已经关闭
|
||||||
return
|
return
|
||||||
case w.extendRenderProperty.renderChan <- data: //发入到缓冲队列
|
case w.extendRenderProperty.renderChan <- renderImageData: //发入到缓冲队列
|
||||||
|
return
|
||||||
|
case <-time.After(time.Millisecond * 50): //超过50毫秒丢弃
|
||||||
|
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "渲染队列溢出,请稍后再发", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, 0, 0)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -48,29 +59,37 @@ func (r *renderProcessor) allocationMessage(w *wsConnectItem, data []byte) {
|
|||||||
func (w *wsConnectItem) consumeRenderImageData() {
|
func (w *wsConnectItem) consumeRenderImageData() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
logx.Error("func renderImage err:", err)
|
logx.Error("func consumeRenderImageData panic:", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
var data []byte
|
//限制并发
|
||||||
|
limitChan := make(chan struct{}, renderChanConcurrency)
|
||||||
|
defer close(limitChan)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-w.closeChan: //已关闭
|
case <-w.closeChan: //已关闭
|
||||||
return
|
return
|
||||||
case data = <-w.extendRenderProperty.renderChan: //消费数据
|
case data := <-w.extendRenderProperty.renderChan: //消费数据
|
||||||
w.renderImage(data)
|
logx.Info("准备执行任务。。。。。")
|
||||||
|
limitChan <- struct{}{}
|
||||||
|
logx.Info("执行任务中。。。。。")
|
||||||
|
go func(d websocket_data.RenderImageReqMsg) {
|
||||||
|
defer func() {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
logx.Error("func renderImage panic:", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
defer func() {
|
||||||
|
<-limitChan
|
||||||
|
}()
|
||||||
|
w.renderImage(d)
|
||||||
|
}(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 执行渲染任务
|
// 执行渲染任务
|
||||||
func (w *wsConnectItem) renderImage(data []byte) {
|
func (w *wsConnectItem) renderImage(renderImageData websocket_data.RenderImageReqMsg) {
|
||||||
//logx.Info("消费渲染数据:", string(data))
|
|
||||||
var renderImageData websocket_data.RenderImageReqMsg
|
|
||||||
if err := json.Unmarshal(data, &renderImageData); err != nil {
|
|
||||||
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "数据格式错误", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, 0, 0)
|
|
||||||
logx.Error("invalid format of websocket render image message", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if renderImageData.RenderData.Logo == "" {
|
if renderImageData.RenderData.Logo == "" {
|
||||||
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "请传入logo", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, 0, 0)
|
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "请传入logo", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, 0, 0)
|
||||||
return
|
return
|
||||||
@ -188,6 +207,7 @@ func (w *wsConnectItem) renderImage(data []byte) {
|
|||||||
logx.Error("failed to find render resource:", err)
|
logx.Error("failed to find render resource:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
logx.Info("无缓存的渲染图,需要unity")
|
||||||
} else {
|
} else {
|
||||||
//返回给客户端
|
//返回给客户端
|
||||||
w.sendRenderResultData(websocket_data.RenderImageRspMsg{
|
w.sendRenderResultData(websocket_data.RenderImageRspMsg{
|
||||||
|
|||||||
@ -12,10 +12,71 @@ import "basic.api"
|
|||||||
service info {
|
service info {
|
||||||
@handler InfoHandler
|
@handler InfoHandler
|
||||||
post /api/info/user(UserInfoRequest) returns (response);
|
post /api/info/user(UserInfoRequest) returns (response);
|
||||||
|
|
||||||
|
@handler UserGetProfileHandler
|
||||||
|
post /api/info/user/profile(QueryProfileRequest) returns (response);
|
||||||
|
|
||||||
|
@handler UpdateProfileBaseHandler
|
||||||
|
post /api/info/user/profile/base/update(ProfileBaseRequest) returns (response);
|
||||||
|
|
||||||
|
@handler AddressDefaultHandler
|
||||||
|
post /api/info/address/default(AddressIdRequest) returns (response);
|
||||||
|
|
||||||
|
@handler AddressAddHandler
|
||||||
|
post /api/info/address/add(AddressRequest) returns (response);
|
||||||
|
|
||||||
|
@handler AddressUpdateHandler
|
||||||
|
post /api/info/address/update(AddressRequest) returns (response);
|
||||||
|
|
||||||
|
@handler AddressDeleteHandler
|
||||||
|
post /api/info/address/delete(AddressIdRequest) returns (response);
|
||||||
|
|
||||||
|
@handler AddressListHandler
|
||||||
|
get /api/info/address/list(request) returns (response);
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
UserInfoRequest {
|
UserInfoRequest {
|
||||||
Module []string `json:"module"`
|
Module []string `json:"module"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AddressObjectRequest {
|
||||||
|
AddressId int64 `json:"address_id"` // 地址id
|
||||||
|
AddressName string `json:"address_name"` // 地址
|
||||||
|
}
|
||||||
|
|
||||||
|
AddressIdRequest {
|
||||||
|
AddressId int64 `json:"address_id"` // 地址id
|
||||||
|
}
|
||||||
|
|
||||||
|
AddressNameRequest {
|
||||||
|
AddressName string `json:"address_name"` // 地址
|
||||||
|
}
|
||||||
|
|
||||||
|
AddressRequest {
|
||||||
|
AddressId int64 `json:"address_id,optional"`
|
||||||
|
IsDefault int64 `json:"is_default"` //是否默认
|
||||||
|
AddressName string `json:"address_name"` //收货人
|
||||||
|
FirstName string `json:"first_name"` //first_name
|
||||||
|
LastName string `json:"last_name"` //last_name
|
||||||
|
Mobile string `json:"mobile"` //手机
|
||||||
|
ZipCode string `json:"zip_code"` //邮编
|
||||||
|
Street string `json:"street"` //街道
|
||||||
|
Suite string `json:"suite"` //房号
|
||||||
|
City string `json:"city"` //城市
|
||||||
|
State string `json:"state"` //州
|
||||||
|
}
|
||||||
|
|
||||||
|
ProfileBaseRequest {
|
||||||
|
FirstName *string `json:"first_name,optional,omitempty"` // 首名
|
||||||
|
LastName *string `json:"last_name,optional,omitempty"` // 后名
|
||||||
|
UserName *string `json:"user_name,optional,omitempty"` // 用户名
|
||||||
|
Mobile *string `json:"mobile,optional,omitempty"` // 电话
|
||||||
|
Resetaurant *string `json:"resetaurant,optional,omitempty"` // 不知道干什么
|
||||||
|
Company *string `json:"company,optional,omitempty"` // 公司
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryProfileRequest {
|
||||||
|
TopKey string `json:"top_key"` // 首名
|
||||||
|
}
|
||||||
)
|
)
|
||||||
@ -33,8 +33,8 @@ type OrderDetailReq {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type CreateOrderReq {
|
type CreateOrderReq {
|
||||||
CartIds []int64 `json:"cart_ids"`
|
CartIds []int64 `json:"cart_ids"`
|
||||||
DeliveryMethod int64 `json:"delivery_method,options=[1,2]"`
|
// DeliveryMethod int64 `json:"delivery_method,optional,options=[1,2],default=2"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreatePrePaymentByDepositReq {
|
type CreatePrePaymentByDepositReq {
|
||||||
|
|||||||
@ -11,9 +11,6 @@ import "basic.api"
|
|||||||
|
|
||||||
service pay {
|
service pay {
|
||||||
|
|
||||||
@handler OrderPaymentIntentHandler
|
|
||||||
post /api/pay/payment-intent(OrderPaymentIntentReq) returns (response);
|
|
||||||
|
|
||||||
@handler OrderRefundHandler
|
@handler OrderRefundHandler
|
||||||
post /api/pay/refund(OrderRefundReq) returns (response);
|
post /api/pay/refund(OrderRefundReq) returns (response);
|
||||||
|
|
||||||
@ -28,20 +25,6 @@ type (
|
|||||||
OrderRefundRes struct{}
|
OrderRefundRes struct{}
|
||||||
)
|
)
|
||||||
|
|
||||||
// 生成预付款
|
|
||||||
type (
|
|
||||||
OrderPaymentIntentReq {
|
|
||||||
Sn string `form:"sn"` //订单编号
|
|
||||||
DeliveryMethod int64 `form:"delivery_method"` //发货方式
|
|
||||||
AddressId int64 `form:"address_id"` //地址id
|
|
||||||
PayMethod int64 `form:"pay_method"` //支付方式
|
|
||||||
}
|
|
||||||
OrderPaymentIntentRes {
|
|
||||||
RedirectUrl string `json:"redirect_url"`
|
|
||||||
ClientSecret string `json:"clientSecret"`
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// StripeWebhook支付通知
|
// StripeWebhook支付通知
|
||||||
type (
|
type (
|
||||||
StripeWebhookReq {
|
StripeWebhookReq {
|
||||||
|
|||||||
@ -44,9 +44,15 @@ service product {
|
|||||||
//获取产品模型信息
|
//获取产品模型信息
|
||||||
@handler GetModelByPidHandler
|
@handler GetModelByPidHandler
|
||||||
get /api/product/get_model_by_pid(GetModelByPidReq) returns (response);
|
get /api/product/get_model_by_pid(GetModelByPidReq) returns (response);
|
||||||
//获取产品阶梯价格列表
|
//获取产品阶梯价格列表(即将废弃)
|
||||||
@handler GetPriceByPidHandler
|
@handler GetPriceByPidHandler
|
||||||
get /api/product/get_price_by_pid(GetPriceByPidReq) returns (response);
|
get /api/product/get_price_by_pid(GetPriceByPidReq) returns (response);
|
||||||
|
//获取产品阶梯价格信息
|
||||||
|
@handler GetProductStepPriceHandler
|
||||||
|
get /api/product/get_product_step_price(GetProductStepPriceReq) returns (response);
|
||||||
|
//根据产品+配件搭配计算价格
|
||||||
|
@handler CalculateProductPriceHandler
|
||||||
|
post /api/product/calculate_product_price(CalculateProductPriceReq) returns (response);
|
||||||
//获取产品尺寸列表
|
//获取产品尺寸列表
|
||||||
@handler GetSizeByPidHandler
|
@handler GetSizeByPidHandler
|
||||||
get /api/product/get_size_by_pid(GetSizeByPidReq) returns (response);
|
get /api/product/get_size_by_pid(GetSizeByPidReq) returns (response);
|
||||||
@ -376,6 +382,22 @@ type PriceItem {
|
|||||||
TotalNum int64 `json:"total_num"`
|
TotalNum int64 `json:"total_num"`
|
||||||
Price int64 `json:"price"`
|
Price int64 `json:"price"`
|
||||||
}
|
}
|
||||||
|
//获取产品阶梯价格信息
|
||||||
|
type GetProductStepPriceReq {
|
||||||
|
ProductId int64 `form:"product_id"`
|
||||||
|
}
|
||||||
|
//根据产品+配件搭配计算价格
|
||||||
|
type CalculateProductPriceReq {
|
||||||
|
ProductId int64 `json:"product_id"`
|
||||||
|
SizeId int64 `json:"size_id"`
|
||||||
|
FittingId int64 `json:"fitting_id,optional"`
|
||||||
|
PurchaseQuantity int64 `json:"purchase_quantity"`
|
||||||
|
}
|
||||||
|
type CalculateProductPriceRsp {
|
||||||
|
ItemPrice string `json:"item_price"`
|
||||||
|
TotalPrice string `json:"total_price"`
|
||||||
|
PurchaseQuantity int64 `json:"purchase_quantity"`
|
||||||
|
}
|
||||||
//获取产品尺寸列表
|
//获取产品尺寸列表
|
||||||
type GetSizeByPidReq {
|
type GetSizeByPidReq {
|
||||||
Pid string `form:"pid"`
|
Pid string `form:"pid"`
|
||||||
|
|||||||
@ -49,7 +49,7 @@ type DeleteCartReq {
|
|||||||
|
|
||||||
//获取购物车列表
|
//获取购物车列表
|
||||||
type GetCartsReq {
|
type GetCartsReq {
|
||||||
CurrentPage int `form:"current_page"` //当前页
|
CartId int64 `form:"cart_id,optional"` //购物车ids可选
|
||||||
}
|
}
|
||||||
type GetCartsRsp {
|
type GetCartsRsp {
|
||||||
Meta Meta `json:"meta"` //分页信息
|
Meta Meta `json:"meta"` //分页信息
|
||||||
@ -70,6 +70,8 @@ type CartItem {
|
|||||||
IsInvalid bool `json:"is_invalid"` //是否无效
|
IsInvalid bool `json:"is_invalid"` //是否无效
|
||||||
InvalidDescription string `json:"invalid_description"` //无效原因
|
InvalidDescription string `json:"invalid_description"` //无效原因
|
||||||
IsSelected bool `json:"is_selected"` //是否选中
|
IsSelected bool `json:"is_selected"` //是否选中
|
||||||
|
TemplateTag string `json:"template_tag"` //模板标签
|
||||||
|
Logo string `json:"logo"`
|
||||||
}
|
}
|
||||||
type ProductInfo {
|
type ProductInfo {
|
||||||
ProductId int64 `json:"product_id"` //产品id
|
ProductId int64 `json:"product_id"` //产品id
|
||||||
|
|||||||
@ -316,8 +316,9 @@ func (l *defaultImageHandle) LogoCombine(ctx context.Context, in *LogoCombineReq
|
|||||||
|
|
||||||
var resultBLM constants.BLMServiceUrlResult
|
var resultBLM constants.BLMServiceUrlResult
|
||||||
err = curl.NewClient(ctx, &curl.Config{
|
err = curl.NewClient(ctx, &curl.Config{
|
||||||
BaseUrl: *l.BLMServiceUrl,
|
BaseUrl: *l.BLMServiceUrl,
|
||||||
Url: constants.BLMServiceUrlLogoCombine,
|
Url: constants.BLMServiceUrlLogoCombine,
|
||||||
|
RequireTimeout: time.Second * 15,
|
||||||
}).PostJson(postMap, &resultBLM)
|
}).PostJson(postMap, &resultBLM)
|
||||||
|
|
||||||
logc.Infof(ctx, "合图--算法请求--合图--结束时间:%v", time.Now().UTC())
|
logc.Infof(ctx, "合图--算法请求--合图--结束时间:%v", time.Now().UTC())
|
||||||
|
|||||||
@ -15,6 +15,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/session"
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
|
"github.com/stripe/stripe-go/v75"
|
||||||
|
"github.com/zeromicro/go-zero/core/logc"
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
@ -34,10 +36,22 @@ type (
|
|||||||
Create(ctx context.Context, in *CreateReq) (res *CreateRes, err error)
|
Create(ctx context.Context, in *CreateReq) (res *CreateRes, err error)
|
||||||
// 预支付--定金
|
// 预支付--定金
|
||||||
CreatePrePaymentByDeposit(ctx context.Context, in *CreatePrePaymentByDepositReq) (res *CreatePrePaymentByDepositRes, err error)
|
CreatePrePaymentByDeposit(ctx context.Context, in *CreatePrePaymentByDepositReq) (res *CreatePrePaymentByDepositRes, err error)
|
||||||
|
// 预支付--定金
|
||||||
|
CreatePrePaymentByBalance(ctx context.Context, in *CreatePrePaymentByBalanceReq) (res *CreatePrePaymentByBalanceRes, err error)
|
||||||
// 列表
|
// 列表
|
||||||
List(ctx context.Context, in *ListReq) (res *ListRes, err error)
|
List(ctx context.Context, in *ListReq) (res *ListRes, err error)
|
||||||
// 详情
|
// 详情
|
||||||
Detail(ctx context.Context, in *DetailReq) (res *DetailRes, err error)
|
Detail(ctx context.Context, in *DetailReq) (res *DetailRes, err error)
|
||||||
|
// 支付成功
|
||||||
|
PaymentSuccessful(ctx context.Context, in *PaymentSuccessfulReq) (res *PaymentSuccessfulRes, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
PayInfo struct {
|
||||||
|
PayMethod string `json:"pay_method"` // 交易方式
|
||||||
|
PayTime time.Time `json:"pay_time"` // 支付时间
|
||||||
|
Status gmodel.PayStatus `json:"status"` // 当前状态
|
||||||
|
StatusLink []gmodel.PayStatus `json:"status_link"` // 状态链路
|
||||||
|
TradeNo string `json:"trade_no"` // 支付交易号
|
||||||
}
|
}
|
||||||
|
|
||||||
OrderAddress struct {
|
OrderAddress struct {
|
||||||
@ -61,6 +75,16 @@ type (
|
|||||||
Amount int64 `json:"amount"` // 金额
|
Amount int64 `json:"amount"` // 金额
|
||||||
Label string `json:"label"` // 标签
|
Label string `json:"label"` // 标签
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 支付成功 */
|
||||||
|
PaymentSuccessfulReq struct {
|
||||||
|
EventId string
|
||||||
|
PaymentMethod string
|
||||||
|
Charge *stripe.Charge
|
||||||
|
}
|
||||||
|
PaymentSuccessfulRes struct{}
|
||||||
|
/* 支付成功 */
|
||||||
|
|
||||||
/* 预支付--定金 */
|
/* 预支付--定金 */
|
||||||
CreatePrePaymentByDepositReq struct {
|
CreatePrePaymentByDepositReq struct {
|
||||||
StripeKey string `json:"stripe_key"`
|
StripeKey string `json:"stripe_key"`
|
||||||
@ -69,7 +93,7 @@ type (
|
|||||||
UserId int64 `json:"user_id"`
|
UserId int64 `json:"user_id"`
|
||||||
OrderSn string `json:"order_sn"`
|
OrderSn string `json:"order_sn"`
|
||||||
DeliveryMethod int64 `json:"delivery_method"`
|
DeliveryMethod int64 `json:"delivery_method"`
|
||||||
DeliveryAddress *OrderAddress `json:"delivery_address"` // 收货地址
|
DeliveryAddress *OrderAddress `json:"delivery_address"`
|
||||||
}
|
}
|
||||||
CreatePrePaymentByDepositRes struct {
|
CreatePrePaymentByDepositRes struct {
|
||||||
ErrorCode basic.StatusResponse
|
ErrorCode basic.StatusResponse
|
||||||
@ -78,6 +102,21 @@ type (
|
|||||||
}
|
}
|
||||||
/* 预支付--定金 */
|
/* 预支付--定金 */
|
||||||
|
|
||||||
|
/* 预支付--尾款 */
|
||||||
|
CreatePrePaymentByBalanceReq struct {
|
||||||
|
StripeKey string `json:"stripe_key"`
|
||||||
|
Currency string `json:"currency"`
|
||||||
|
Country string `json:"country"`
|
||||||
|
UserId int64 `json:"user_id"`
|
||||||
|
OrderSn string `json:"order_sn"`
|
||||||
|
}
|
||||||
|
CreatePrePaymentByBalanceRes struct {
|
||||||
|
ErrorCode basic.StatusResponse
|
||||||
|
OrderDetail gmodel.OrderDetail
|
||||||
|
OrderPay OrderPay
|
||||||
|
}
|
||||||
|
/* 预支付--尾款 */
|
||||||
|
|
||||||
/* 下单 */
|
/* 下单 */
|
||||||
CreateReq struct {
|
CreateReq struct {
|
||||||
ExpectedDeliveryTime time.Time `json:"expected_delivery_time"` // 预计到货时间
|
ExpectedDeliveryTime time.Time `json:"expected_delivery_time"` // 预计到货时间
|
||||||
@ -122,6 +161,312 @@ type (
|
|||||||
/* 列表 */
|
/* 列表 */
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 支付成功
|
||||||
|
func (d *defaultOrder) PaymentSuccessful(ctx context.Context, in *PaymentSuccessfulReq) (res *PaymentSuccessfulRes, err error) {
|
||||||
|
var orderSn string
|
||||||
|
var payStage string
|
||||||
|
var ok bool
|
||||||
|
var card string
|
||||||
|
var brand string
|
||||||
|
var country string
|
||||||
|
var currency string
|
||||||
|
var tradeSn string
|
||||||
|
var payAmount int64
|
||||||
|
var payTitle string
|
||||||
|
var payTime time.Time
|
||||||
|
|
||||||
|
var paymentMethod int64 = 1
|
||||||
|
if in.PaymentMethod == "stripe" {
|
||||||
|
paymentMethod = 1
|
||||||
|
}
|
||||||
|
if in.PaymentMethod == "paypal" {
|
||||||
|
paymentMethod = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
if in.Charge != nil {
|
||||||
|
charge := in.Charge
|
||||||
|
orderSn, ok = charge.Metadata["order_sn"]
|
||||||
|
if !ok || orderSn == "" {
|
||||||
|
err = errors.New("order_sn is empty")
|
||||||
|
logc.Errorf(ctx, "PaymentSuccessful failed param, eventId:%s,err:%v", in.EventId, err)
|
||||||
|
return &PaymentSuccessfulRes{}, err
|
||||||
|
}
|
||||||
|
payStage, ok = charge.Metadata["pay_stage"]
|
||||||
|
if !ok || payStage == "" {
|
||||||
|
err = errors.New("pay_stage is empty")
|
||||||
|
logc.Errorf(ctx, "PaymentSuccessful failed param, eventId:%s,err:%v", in.EventId, err)
|
||||||
|
return &PaymentSuccessfulRes{}, err
|
||||||
|
}
|
||||||
|
country, ok = charge.Metadata["country"]
|
||||||
|
if !ok || country == "" {
|
||||||
|
err = errors.New("country is empty")
|
||||||
|
logc.Errorf(ctx, "PaymentSuccessful failed param, eventId:%s,err:%v", in.EventId, err)
|
||||||
|
return &PaymentSuccessfulRes{}, err
|
||||||
|
}
|
||||||
|
if charge.PaymentMethodDetails != nil {
|
||||||
|
if charge.PaymentMethodDetails.Card != nil {
|
||||||
|
if charge.PaymentMethodDetails.Card.Last4 != "" {
|
||||||
|
card = charge.PaymentMethodDetails.Card.Last4
|
||||||
|
}
|
||||||
|
if charge.PaymentMethodDetails.Card.Brand != "" {
|
||||||
|
brand = string(charge.PaymentMethodDetails.Card.Brand)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if charge.Currency != "" {
|
||||||
|
currency = string(charge.Currency)
|
||||||
|
}
|
||||||
|
tradeSn = charge.ID
|
||||||
|
payAmount = charge.Amount
|
||||||
|
payTitle = charge.Description
|
||||||
|
payTime = time.Unix(charge.Created, 0).UTC()
|
||||||
|
}
|
||||||
|
err = d.MysqlConn.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||||
|
var orderInfo gmodel.FsOrder
|
||||||
|
result := tx.Where("is_del = ?", 0).Where("order_sn = ?", orderSn).Take(&orderInfo)
|
||||||
|
err = result.Error
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorf("PaymentSuccessful failed order Take, eventId:%s,err: %v", in.EventId, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ress, err := d.OrderDetailHandler(ctx, &orderInfo, 0)
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorf("PaymentSuccessful failed DetailOrderDetailHandler,eventId:%s, err: %v", in.EventId, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var ntime = time.Now().UTC()
|
||||||
|
if (payStage == "deposit" && *orderInfo.PayStatus == int64(constants.ORDERPAYSTATUSUNPAIDDEPOSIT)) || (payStage == "remaining_balance" && *orderInfo.PayStatus == int64(constants.ORDERPAYSTATUSPAIDDEPOSIT)) {
|
||||||
|
var payStatus = int64(constants.PAYSTATUSPAID)
|
||||||
|
var payStageInt int64
|
||||||
|
var orderPayStatusCode constants.OrderPayStatusCode
|
||||||
|
// 订单状态--当前
|
||||||
|
var status gmodel.OrderStatus
|
||||||
|
var statusLink []gmodel.OrderStatus
|
||||||
|
var uOrderDetail = make(map[string]interface{})
|
||||||
|
var payInfo PayInfo
|
||||||
|
payInfo.PayMethod = in.PaymentMethod
|
||||||
|
payInfo.PayTime = payTime
|
||||||
|
payInfo.TradeNo = tradeSn
|
||||||
|
// 当前状态
|
||||||
|
var statusCode constants.OrderStatusCode
|
||||||
|
var statusCodePre constants.OrderStatusCode
|
||||||
|
if payStage == "deposit" {
|
||||||
|
if *orderInfo.DeliveryMethod == constants.DELIVERYMETHODDIRECTMAIL {
|
||||||
|
// 直邮
|
||||||
|
statusCode = constants.ORDER_STATUS_DIRECTMAIL_ORDERED
|
||||||
|
}
|
||||||
|
if *orderInfo.DeliveryMethod == constants.DELIVERYMETHODDSCLOUDSTORE {
|
||||||
|
// 云仓
|
||||||
|
statusCode = constants.ORDER_STATUS_CLOUDSTORE_ORDERED
|
||||||
|
}
|
||||||
|
payStageInt = 1
|
||||||
|
orderPayStatusCode = constants.ORDERPAYSTATUSPAIDDEPOSIT
|
||||||
|
status = gmodel.OrderStatus{
|
||||||
|
Ctime: &ntime,
|
||||||
|
Utime: &ntime,
|
||||||
|
StatusCode: statusCode,
|
||||||
|
StatusTitle: constants.OrderStatusMessage[statusCode],
|
||||||
|
}
|
||||||
|
statusLink = order.UpdateOrderStatusLink(ress.OrderDetailOriginal.OrderInfo.StatusLink, gmodel.OrderStatus{
|
||||||
|
Ctime: &ntime,
|
||||||
|
Utime: &ntime,
|
||||||
|
StatusCode: statusCode,
|
||||||
|
StatusTitle: constants.OrderStatusMessage[statusCode],
|
||||||
|
})
|
||||||
|
payInfo.Status = gmodel.PayStatus{
|
||||||
|
StatusCode: int64(constants.PAYSTATUSPAID),
|
||||||
|
StatusTitle: constants.PayStatusMessage[constants.PAYSTATUSPAID],
|
||||||
|
}
|
||||||
|
payInfo.StatusLink = append(ress.OrderDetail.OrderAmount.Deposit.StatusLink, payInfo.Status)
|
||||||
|
uOrderDetail["order_amount"] = struct {
|
||||||
|
Deposit PayInfo `json:"deposit"`
|
||||||
|
}{
|
||||||
|
Deposit: payInfo,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if payStage == "remaining_balance" {
|
||||||
|
if *orderInfo.DeliveryMethod == constants.DELIVERYMETHODDIRECTMAIL {
|
||||||
|
// 直邮
|
||||||
|
statusCodePre = constants.ORDER_STATUS_DIRECTMAIL_ORDERED
|
||||||
|
statusCode = constants.ORDER_STATUS_DIRECTMAIL_ORDEREDMAINING
|
||||||
|
}
|
||||||
|
if *orderInfo.DeliveryMethod == constants.DELIVERYMETHODDSCLOUDSTORE {
|
||||||
|
// 云仓
|
||||||
|
statusCodePre = constants.ORDER_STATUS_CLOUDSTORE_ORDERED
|
||||||
|
statusCode = constants.ORDER_STATUS_CLOUDSTORE_ORDEREDMAINING
|
||||||
|
}
|
||||||
|
payStageInt = 2
|
||||||
|
orderPayStatusCode = constants.ORDERPAYSTATUSPAIDDREMAINING
|
||||||
|
|
||||||
|
var statusChildren []*gmodel.OrderStatus
|
||||||
|
// 更新订单状态链路--子状态
|
||||||
|
for oStatusLinkKey, oStatusLink := range ress.OrderDetail.OrderInfo.StatusLink {
|
||||||
|
if oStatusLink.StatusCode == statusCodePre {
|
||||||
|
statusChildren = append(oStatusLink.Children, &gmodel.OrderStatus{
|
||||||
|
Ctime: &ntime,
|
||||||
|
Utime: &ntime,
|
||||||
|
StatusCode: statusCode,
|
||||||
|
StatusTitle: constants.OrderStatusMessage[statusCode],
|
||||||
|
})
|
||||||
|
ress.OrderDetail.OrderInfo.StatusLink[oStatusLinkKey].Children = statusChildren
|
||||||
|
}
|
||||||
|
}
|
||||||
|
statusLink = ress.OrderDetail.OrderInfo.StatusLink
|
||||||
|
|
||||||
|
if ress.OrderDetail.OrderInfo.Status.StatusCode == constants.ORDER_STATUS_DIRECTMAIL_ORDERED || ress.OrderDetail.OrderInfo.Status.StatusCode == constants.ORDER_STATUS_CLOUDSTORE_ORDERED {
|
||||||
|
status = ress.OrderDetail.OrderInfo.Status
|
||||||
|
status.Children = statusChildren
|
||||||
|
}
|
||||||
|
payInfo.Status = gmodel.PayStatus{
|
||||||
|
StatusCode: int64(constants.PAYSTATUSPAID),
|
||||||
|
StatusTitle: constants.PayStatusMessage[constants.PAYSTATUSPAID],
|
||||||
|
}
|
||||||
|
|
||||||
|
payInfo.StatusLink = append(ress.OrderDetail.OrderAmount.RemainingBalance.StatusLink, payInfo.Status)
|
||||||
|
uOrderDetail["order_amount"] = struct {
|
||||||
|
RemainingBalance PayInfo `json:"remaining_balance"`
|
||||||
|
}{
|
||||||
|
RemainingBalance: payInfo,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增交易信息
|
||||||
|
tx.Create(&gmodel.FsOrderTrade{
|
||||||
|
UserId: orderInfo.UserId,
|
||||||
|
OrderSn: &orderSn,
|
||||||
|
OrderSource: orderInfo.OrderSource,
|
||||||
|
TradeSn: &tradeSn,
|
||||||
|
PayAmount: &payAmount,
|
||||||
|
PayStatus: &payStatus,
|
||||||
|
PaymentMethod: &paymentMethod,
|
||||||
|
PayStage: &payStageInt,
|
||||||
|
CardSn: &card,
|
||||||
|
CardBrand: &brand,
|
||||||
|
Country: &country,
|
||||||
|
Currency: ¤cy,
|
||||||
|
Ctime: &ntime,
|
||||||
|
Utime: &ntime,
|
||||||
|
PayTitle: &payTitle,
|
||||||
|
})
|
||||||
|
var sql string
|
||||||
|
if *orderInfo.Status == int64(constants.ORDER_STATUS_UNPAIDDEPOSIT) {
|
||||||
|
sql = fmt.Sprintf(", `utime` = '%s', `pay_status` = %d, `status` = %d ", ntime, orderPayStatusCode, statusCode)
|
||||||
|
} else {
|
||||||
|
sql = fmt.Sprintf(", `utime` = '%s', `pay_status` = %d", ntime, orderPayStatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新订单信息
|
||||||
|
uOrderDetail["pay_status"] = orderPayStatusCode
|
||||||
|
uOrderDetail["order_info"] = struct {
|
||||||
|
Utime *time.Time `json:"utime"`
|
||||||
|
Status gmodel.OrderStatus `json:"status"`
|
||||||
|
StatusLink []gmodel.OrderStatus `json:"status_link"`
|
||||||
|
}{
|
||||||
|
Utime: &ntime,
|
||||||
|
Status: status,
|
||||||
|
StatusLink: statusLink,
|
||||||
|
}
|
||||||
|
fmt.Printf("uOrderDetail :%+v", uOrderDetail)
|
||||||
|
if len(uOrderDetail) > 0 {
|
||||||
|
err = fssql.MetadataOrderPATCH(d.MysqlConn, sql, orderSn, gmodel.FsOrder{}, uOrderDetail, "id = ?", orderInfo.Id)
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorf("PaymentSuccessful failed MetadataOrderPATCH,eventId:%s, err: %v", in.EventId, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return &PaymentSuccessfulRes{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 预支付--尾款
|
||||||
|
func (d *defaultOrder) CreatePrePaymentByBalance(ctx context.Context, in *CreatePrePaymentByBalanceReq) (res *CreatePrePaymentByBalanceRes, err error) {
|
||||||
|
var errorCode basic.StatusResponse
|
||||||
|
var order gmodel.FsOrder
|
||||||
|
model := d.MysqlConn.Where("is_del = ?", 0)
|
||||||
|
if in.UserId != 0 {
|
||||||
|
model.Where("user_id = ?", in.UserId)
|
||||||
|
}
|
||||||
|
if in.OrderSn != "" {
|
||||||
|
model.Where("order_sn = ?", in.OrderSn)
|
||||||
|
}
|
||||||
|
result := model.Take(&order)
|
||||||
|
if result.Error != nil {
|
||||||
|
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
||||||
|
errorCode = *basic.CodeErrOrderCreatePrePaymentInfoNoFound
|
||||||
|
} else {
|
||||||
|
errorCode = *basic.CodeServiceErr
|
||||||
|
}
|
||||||
|
logx.Errorf("create prePayment balance failed, err: %v", err)
|
||||||
|
return &CreatePrePaymentByBalanceRes{
|
||||||
|
ErrorCode: errorCode,
|
||||||
|
}, result.Error
|
||||||
|
}
|
||||||
|
// 非未支付
|
||||||
|
if *order.PayStatus != int64(constants.ORDERPAYSTATUSPAIDDEPOSIT) {
|
||||||
|
errorCode = *basic.CodeErrOrderCreatePrePaymentNoUnPaid
|
||||||
|
err = errors.New("order balance pay status is not unPaid")
|
||||||
|
logx.Errorf("create prePayment balance failed, err: %v", err)
|
||||||
|
return &CreatePrePaymentByBalanceRes{
|
||||||
|
ErrorCode: errorCode,
|
||||||
|
}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ress, err := d.OrderDetailHandler(ctx, &order, 1)
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorf("create prePayment balance failed DetailOrderDetailHandler, err: %v", err)
|
||||||
|
errorCode = *basic.CodeServiceErr
|
||||||
|
return &CreatePrePaymentByBalanceRes{
|
||||||
|
ErrorCode: errorCode,
|
||||||
|
}, err
|
||||||
|
}
|
||||||
|
// 支付初始化
|
||||||
|
amount := int64(ress.OrderDetailOriginal.OrderAmount.RemainingBalance.PayAmount.Current.CurrentAmount.(float64) / float64(10))
|
||||||
|
payConfig := &pay.Config{}
|
||||||
|
payConfig.Stripe.PayType = "intent"
|
||||||
|
payConfig.Stripe.Key = in.StripeKey
|
||||||
|
var metadata = make(map[string]string, 2)
|
||||||
|
metadata["model"] = "product_order"
|
||||||
|
metadata["order_sn"] = in.OrderSn
|
||||||
|
metadata["pay_stage"] = "remaining_balance"
|
||||||
|
metadata["country"] = in.Country
|
||||||
|
var generatePrepaymentReq = &pay.GeneratePrepaymentReq{
|
||||||
|
Metadata: metadata,
|
||||||
|
ProductName: "支付尾款后期统一调整",
|
||||||
|
Amount: amount,
|
||||||
|
Currency: "usd",
|
||||||
|
Quantity: 1,
|
||||||
|
ProductDescription: "支付尾款后期统一调整",
|
||||||
|
}
|
||||||
|
payDriver := pay.NewPayDriver(1, payConfig)
|
||||||
|
|
||||||
|
prepaymentRes, err := payDriver.GeneratePrepayment(generatePrepaymentReq)
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorf("create prePayment balance failed GeneratePrepayment, err: %v", err)
|
||||||
|
errorCode = *basic.CodeServiceErr
|
||||||
|
return &CreatePrePaymentByBalanceRes{
|
||||||
|
ErrorCode: errorCode,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
return &CreatePrePaymentByBalanceRes{
|
||||||
|
OrderDetail: ress.OrderDetail,
|
||||||
|
OrderPay: OrderPay{
|
||||||
|
ClientSecret: prepaymentRes.ClientSecret,
|
||||||
|
Country: in.Country,
|
||||||
|
Currency: in.Currency,
|
||||||
|
Method: payConfig.Stripe.PayType,
|
||||||
|
OrderSn: in.OrderSn,
|
||||||
|
PayStage: 2,
|
||||||
|
Total: OrderPayTotal{
|
||||||
|
Amount: amount,
|
||||||
|
Label: "支付尾款后期统一调整",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// 预支付--定金
|
// 预支付--定金
|
||||||
func (d *defaultOrder) CreatePrePaymentByDeposit(ctx context.Context, in *CreatePrePaymentByDepositReq) (res *CreatePrePaymentByDepositRes, err error) {
|
func (d *defaultOrder) CreatePrePaymentByDeposit(ctx context.Context, in *CreatePrePaymentByDepositReq) (res *CreatePrePaymentByDepositRes, err error) {
|
||||||
var errorCode basic.StatusResponse
|
var errorCode basic.StatusResponse
|
||||||
@ -148,7 +493,7 @@ func (d *defaultOrder) CreatePrePaymentByDeposit(ctx context.Context, in *Create
|
|||||||
|
|
||||||
// 非未支付
|
// 非未支付
|
||||||
if *order.PayStatus != int64(constants.ORDERPAYSTATUSUNPAIDDEPOSIT) {
|
if *order.PayStatus != int64(constants.ORDERPAYSTATUSUNPAIDDEPOSIT) {
|
||||||
errorCode = *basic.CodeErrOrderCreatePrePaymentInfoNoFound
|
errorCode = *basic.CodeErrOrderCreatePrePaymentNoUnPaid
|
||||||
err = errors.New("order pay status is not unPaidDeposit")
|
err = errors.New("order pay status is not unPaidDeposit")
|
||||||
logx.Errorf("create prePayment deposit failed, err: %v", err)
|
logx.Errorf("create prePayment deposit failed, err: %v", err)
|
||||||
return &CreatePrePaymentByDepositRes{
|
return &CreatePrePaymentByDepositRes{
|
||||||
@ -161,6 +506,8 @@ func (d *defaultOrder) CreatePrePaymentByDeposit(ctx context.Context, in *Create
|
|||||||
ctime := *order.Ctime
|
ctime := *order.Ctime
|
||||||
ctimeTimeOut := ctime.Add(30 * time.Minute).UTC().Unix()
|
ctimeTimeOut := ctime.Add(30 * time.Minute).UTC().Unix()
|
||||||
ntimeTimeOut := ntime.Unix()
|
ntimeTimeOut := ntime.Unix()
|
||||||
|
|
||||||
|
// 测试超时支付不限制
|
||||||
if ctimeTimeOut == ntimeTimeOut {
|
if ctimeTimeOut == ntimeTimeOut {
|
||||||
errorCode = *basic.CodeErrOrderCreatePrePaymentTimeout
|
errorCode = *basic.CodeErrOrderCreatePrePaymentTimeout
|
||||||
err = errors.New("order pay timeout")
|
err = errors.New("order pay timeout")
|
||||||
@ -170,7 +517,7 @@ func (d *defaultOrder) CreatePrePaymentByDeposit(ctx context.Context, in *Create
|
|||||||
}, err
|
}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ress, err := d.OrderDetailHandler(ctx, &order)
|
ress, err := d.OrderDetailHandler(ctx, &order, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Errorf("create prePayment deposit failed DetailOrderDetailHandler, err: %v", err)
|
logx.Errorf("create prePayment deposit failed DetailOrderDetailHandler, err: %v", err)
|
||||||
errorCode = *basic.CodeServiceErr
|
errorCode = *basic.CodeServiceErr
|
||||||
@ -182,13 +529,11 @@ func (d *defaultOrder) CreatePrePaymentByDeposit(ctx context.Context, in *Create
|
|||||||
var uOrderDetail = make(map[string]interface{})
|
var uOrderDetail = make(map[string]interface{})
|
||||||
|
|
||||||
var orderAddress *gmodel.OrderAddress
|
var orderAddress *gmodel.OrderAddress
|
||||||
if in.DeliveryAddress != nil {
|
if in.DeliveryMethod == constants.DELIVERYMETHODDIRECTMAIL {
|
||||||
if in.DeliveryAddress.Name != ress.OrderDetailOriginal.DeliveryAddress.Name || in.DeliveryAddress.Address != ress.OrderDetail.DeliveryAddress.Address || in.DeliveryAddress.Mobile != ress.OrderDetail.DeliveryAddress.Mobile {
|
orderAddress = &gmodel.OrderAddress{
|
||||||
orderAddress = &gmodel.OrderAddress{
|
Name: in.DeliveryAddress.Name,
|
||||||
Name: in.DeliveryAddress.Name,
|
Mobile: in.DeliveryAddress.Mobile,
|
||||||
Mobile: in.DeliveryAddress.Mobile,
|
Address: in.DeliveryAddress.Address,
|
||||||
Address: in.DeliveryAddress.Address,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,31 +568,7 @@ func (d *defaultOrder) CreatePrePaymentByDeposit(ctx context.Context, in *Create
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 支付初始化
|
|
||||||
amount := int64(ress.OrderDetailOriginal.OrderAmount.Deposit.PayAmount.Current.CurrentAmount.(float64) / float64(10))
|
|
||||||
payConfig := &pay.Config{}
|
|
||||||
payConfig.Stripe.PayType = "intent"
|
|
||||||
payConfig.Stripe.Key = in.StripeKey
|
|
||||||
var generatePrepaymentReq = &pay.GeneratePrepaymentReq{
|
|
||||||
OrderSn: in.OrderSn,
|
|
||||||
ProductName: "支付标题",
|
|
||||||
Amount: amount,
|
|
||||||
Currency: "usd",
|
|
||||||
Quantity: 1,
|
|
||||||
ProductDescription: "支付描述",
|
|
||||||
}
|
|
||||||
payDriver := pay.NewPayDriver(1, payConfig)
|
|
||||||
|
|
||||||
prepaymentRes, err := payDriver.GeneratePrepayment(generatePrepaymentReq)
|
|
||||||
if err != nil {
|
|
||||||
logx.Errorf("create prePayment deposit failed GeneratePrepayment, err: %v", err)
|
|
||||||
errorCode = *basic.CodeServiceErr
|
|
||||||
return &CreatePrePaymentByDepositRes{
|
|
||||||
ErrorCode: errorCode,
|
|
||||||
}, nil
|
|
||||||
} else {
|
|
||||||
//uOrderDetail["order_amount"] = map[type]type
|
|
||||||
}
|
|
||||||
if len(uOrderDetail) > 0 {
|
if len(uOrderDetail) > 0 {
|
||||||
err = fssql.MetadataOrderPATCH(d.MysqlConn, sql, in.OrderSn, gmodel.FsOrder{}, uOrderDetail, "id = ?", order.Id)
|
err = fssql.MetadataOrderPATCH(d.MysqlConn, sql, in.OrderSn, gmodel.FsOrder{}, uOrderDetail, "id = ?", order.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -263,6 +584,34 @@ func (d *defaultOrder) CreatePrePaymentByDeposit(ctx context.Context, in *Create
|
|||||||
ress.OrderDetail.OrderInfo.DeliveryMethod = in.DeliveryMethod
|
ress.OrderDetail.OrderInfo.DeliveryMethod = in.DeliveryMethod
|
||||||
ress.OrderDetail.DeliveryAddress = orderAddress
|
ress.OrderDetail.DeliveryAddress = orderAddress
|
||||||
|
|
||||||
|
// 支付初始化
|
||||||
|
amount := int64(ress.OrderDetailOriginal.OrderAmount.Deposit.PayAmount.Current.CurrentAmount.(float64) / float64(10))
|
||||||
|
payConfig := &pay.Config{}
|
||||||
|
payConfig.Stripe.PayType = "intent"
|
||||||
|
payConfig.Stripe.Key = in.StripeKey
|
||||||
|
var metadata = make(map[string]string, 2)
|
||||||
|
metadata["model"] = "product_order"
|
||||||
|
metadata["order_sn"] = in.OrderSn
|
||||||
|
metadata["pay_stage"] = "deposit"
|
||||||
|
metadata["country"] = in.Country
|
||||||
|
var generatePrepaymentReq = &pay.GeneratePrepaymentReq{
|
||||||
|
Metadata: metadata,
|
||||||
|
ProductName: "支付首款",
|
||||||
|
Amount: amount,
|
||||||
|
Currency: "usd",
|
||||||
|
Quantity: 1,
|
||||||
|
ProductDescription: "支付首款",
|
||||||
|
}
|
||||||
|
payDriver := pay.NewPayDriver(1, payConfig)
|
||||||
|
|
||||||
|
prepaymentRes, err := payDriver.GeneratePrepayment(generatePrepaymentReq)
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorf("create prePayment deposit failed GeneratePrepayment, err: %v", err)
|
||||||
|
errorCode = *basic.CodeServiceErr
|
||||||
|
return &CreatePrePaymentByDepositRes{
|
||||||
|
ErrorCode: errorCode,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
return &CreatePrePaymentByDepositRes{
|
return &CreatePrePaymentByDepositRes{
|
||||||
OrderDetail: ress.OrderDetail,
|
OrderDetail: ress.OrderDetail,
|
||||||
OrderPay: OrderPay{
|
OrderPay: OrderPay{
|
||||||
@ -320,7 +669,7 @@ func (d *defaultOrder) List(ctx context.Context, in *ListReq) (res *ListRes, err
|
|||||||
return nil, result.Error
|
return nil, result.Error
|
||||||
}
|
}
|
||||||
for _, order := range orderList {
|
for _, order := range orderList {
|
||||||
ress, err := d.OrderDetailHandler(ctx, &order)
|
ress, err := d.OrderDetailHandler(ctx, &order, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -365,19 +714,21 @@ func (d *defaultOrder) Detail(ctx context.Context, in *DetailReq) (res *DetailRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 是否超时支付
|
// 是否超时支付
|
||||||
ctime := *order.Ctime
|
if *order.Status == int64(constants.ORDER_STATUS_UNPAIDDEPOSIT) {
|
||||||
ctimeTimeOut := ctime.Add(30 * time.Minute).UTC().Unix()
|
ctime := *order.Ctime
|
||||||
ntimeTimeOut := time.Now().UTC().Unix()
|
ctimeTimeOut := ctime.Add(30 * time.Minute).UTC().Unix()
|
||||||
if ctimeTimeOut < ntimeTimeOut {
|
ntimeTimeOut := time.Now().UTC().Unix()
|
||||||
errorCode = *basic.CodeErrOrderCreatePrePaymentTimeout
|
if ctimeTimeOut < ntimeTimeOut {
|
||||||
err = errors.New("order pay timeout")
|
errorCode = *basic.CodeErrOrderCreatePrePaymentTimeout
|
||||||
logx.Errorf("order detail failed, err: %v", err)
|
err = errors.New("order pay timeout")
|
||||||
return &DetailRes{
|
logx.Errorf("order detail failed, err: %v", err)
|
||||||
ErrorCode: errorCode,
|
return &DetailRes{
|
||||||
}, err
|
ErrorCode: errorCode,
|
||||||
|
}, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ress, err := d.OrderDetailHandler(ctx, &order)
|
ress, err := d.OrderDetailHandler(ctx, &order, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Errorf("order detail failed, err: %v", err)
|
logx.Errorf("order detail failed, err: %v", err)
|
||||||
errorCode = *basic.CodeServiceErr
|
errorCode = *basic.CodeServiceErr
|
||||||
@ -403,8 +754,8 @@ func (d *defaultOrder) Create(ctx context.Context, in *CreateReq) (res *CreateRe
|
|||||||
resShoppingCartFind := tx.Table(gmodel.NewFsShoppingCartModel(tx).TableName()).
|
resShoppingCartFind := tx.Table(gmodel.NewFsShoppingCartModel(tx).TableName()).
|
||||||
Preload("ShoppingCartProduct", func(dbPreload *gorm.DB) *gorm.DB {
|
Preload("ShoppingCartProduct", func(dbPreload *gorm.DB) *gorm.DB {
|
||||||
return dbPreload.Table(gmodel.NewFsProductModel(tx).TableName()).Preload("CoverResource")
|
return dbPreload.Table(gmodel.NewFsProductModel(tx).TableName()).Preload("CoverResource")
|
||||||
}).Preload("ShoppingCartProductPriceList").
|
}).
|
||||||
Preload("ShoppingCartProductModel3dList").
|
Preload("ShoppingCartProductModel3d").
|
||||||
Preload("ShoppingCartProductModel3dFitting").
|
Preload("ShoppingCartProductModel3dFitting").
|
||||||
Where("id IN ?", in.CartIds).
|
Where("id IN ?", in.CartIds).
|
||||||
Where("user_id = ?", in.UserId).
|
Where("user_id = ?", in.UserId).
|
||||||
@ -465,10 +816,6 @@ func (d *defaultOrder) Create(ctx context.Context, in *CreateReq) (res *CreateRe
|
|||||||
for _, shoppingCart := range shoppingCartList {
|
for _, shoppingCart := range shoppingCartList {
|
||||||
// 购物车快照
|
// 购物车快照
|
||||||
var shoppingCartSnapshot gmodel.CartSnapshot
|
var shoppingCartSnapshot gmodel.CartSnapshot
|
||||||
// 购物车商品价格
|
|
||||||
var shoppingCartProductPrice *gmodel.FsProductPrice
|
|
||||||
// 购物车商品模型
|
|
||||||
var shoppingCartProductModel3d *gmodel.FsProductModel3d
|
|
||||||
if shoppingCart.Snapshot != nil {
|
if shoppingCart.Snapshot != nil {
|
||||||
json.Unmarshal([]byte(*shoppingCart.Snapshot), &shoppingCartSnapshot)
|
json.Unmarshal([]byte(*shoppingCart.Snapshot), &shoppingCartSnapshot)
|
||||||
}
|
}
|
||||||
@ -478,69 +825,21 @@ func (d *defaultOrder) Create(ctx context.Context, in *CreateReq) (res *CreateRe
|
|||||||
errorCode.Message = "create order failed, product '" + shoppingCartSnapshot.ProductInfo.ProductName + "'is absent"
|
errorCode.Message = "create order failed, product '" + shoppingCartSnapshot.ProductInfo.ProductName + "'is absent"
|
||||||
return errors.New(errorCode.Message)
|
return errors.New(errorCode.Message)
|
||||||
}
|
}
|
||||||
// 商品价格异常
|
|
||||||
if len(shoppingCart.ShoppingCartProductPriceList) == 0 {
|
|
||||||
errorCode = *basic.CodeErrOrderCreatProductPriceAbsent
|
|
||||||
errorCode.Message = "create order failed, price of product '" + shoppingCartSnapshot.ProductInfo.ProductName + "'is absent"
|
|
||||||
return errors.New(errorCode.Message)
|
|
||||||
} else {
|
|
||||||
var isProductPrice bool
|
|
||||||
for _, shoppingCartProductPriceInfo := range shoppingCart.ShoppingCartProductPriceList {
|
|
||||||
if *shoppingCart.SizeId == *shoppingCartProductPriceInfo.SizeId {
|
|
||||||
shoppingCartProductPrice = shoppingCartProductPriceInfo
|
|
||||||
isProductPrice = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !isProductPrice {
|
|
||||||
errorCode = *basic.CodeErrOrderCreatProductPriceAbsent
|
|
||||||
errorCode.Message = "create order failed, price of product '" + shoppingCartSnapshot.ProductInfo.ProductName + "'is absent"
|
|
||||||
return errors.New(errorCode.Message)
|
|
||||||
}
|
|
||||||
shoppingCart.ShoppingCartProductPriceList = []*gmodel.FsProductPrice{shoppingCartProductPrice}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 商品模型异常
|
var stepPriceJson gmodel.StepPriceJsonStruct
|
||||||
if len(shoppingCart.ShoppingCartProductModel3dList) == 0 {
|
if shoppingCart.ShoppingCartProductModel3d.StepPrice != nil {
|
||||||
errorCode = *basic.CodeErrOrderCreatProductAccessoryAbsent
|
err = json.Unmarshal(*shoppingCart.ShoppingCartProductModel3d.StepPrice, &stepPriceJson)
|
||||||
errorCode.Message = "create order failed, accessoryof product '" + shoppingCartSnapshot.ProductInfo.ProductName + "'is absent"
|
if err != nil {
|
||||||
return errors.New(errorCode.Message)
|
return err
|
||||||
} else {
|
|
||||||
var isProductModel bool
|
|
||||||
for _, shoppingCartProductModel3dInfo := range shoppingCart.ShoppingCartProductModel3dList {
|
|
||||||
if *shoppingCart.SizeId == *shoppingCartProductModel3dInfo.SizeId {
|
|
||||||
shoppingCartProductModel3d = shoppingCartProductModel3dInfo
|
|
||||||
isProductModel = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if !isProductModel {
|
|
||||||
errorCode = *basic.CodeErrOrderCreatProductAccessoryAbsent
|
|
||||||
errorCode.Message = "create order failed, accessory of product '" + shoppingCartSnapshot.ProductInfo.ProductName + "'is absent"
|
|
||||||
return errors.New(errorCode.Message)
|
|
||||||
}
|
|
||||||
shoppingCart.ShoppingCartProductModel3dList = []*gmodel.FsProductModel3d{shoppingCartProductModel3d}
|
|
||||||
}
|
|
||||||
|
|
||||||
var stepNum []int
|
|
||||||
var stepPrice []int
|
|
||||||
if *shoppingCartProductPrice.StepNum == "" {
|
|
||||||
errorCode = *basic.CodeErrOrderCreatProductPriceAbsent
|
|
||||||
errorCode.Message = "create order failed, step num of product '" + shoppingCartSnapshot.ProductInfo.ProductName + "'is failed"
|
|
||||||
return errors.New(errorCode.Message)
|
|
||||||
} else {
|
} else {
|
||||||
json.Unmarshal([]byte(*shoppingCartProductPrice.StepNum), &stepNum)
|
|
||||||
}
|
|
||||||
if *shoppingCartProductPrice.StepPrice == "" {
|
|
||||||
errorCode = *basic.CodeErrOrderCreatProductPriceAbsent
|
errorCode = *basic.CodeErrOrderCreatProductPriceAbsent
|
||||||
errorCode.Message = "create order failed, step price of product '" + shoppingCartSnapshot.ProductInfo.ProductName + "'is failed"
|
errorCode.Message = "create order failed, step price of product '" + shoppingCartSnapshot.ProductInfo.ProductName + "'is failed"
|
||||||
return errors.New(errorCode.Message)
|
return errors.New("shoppingCartProductModel3d.StepPrice nil")
|
||||||
} else {
|
|
||||||
json.Unmarshal([]byte(*shoppingCartProductPrice.StepPrice), &stepPrice)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 计算价格 */
|
/* 计算价格 */
|
||||||
productPrice, productTotalPrice, stepNum, stepPrice, err := NewShoppingCart(tx, nil, nil).CaculateCartPrice(*shoppingCart.PurchaseQuantity, shoppingCartProductPrice, *shoppingCart.ShoppingCartProductModel3dFitting.Price)
|
productTotalPrice, productPrice, err := NewShoppingCart(tx, nil, nil).CaculateStepPrice(*shoppingCart.PurchaseQuantity, stepPriceJson, *shoppingCart.ShoppingCartProductModel3dFitting.Price)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorCode = *basic.CodeErrOrderCreatProductPriceAbsent
|
errorCode = *basic.CodeErrOrderCreatProductPriceAbsent
|
||||||
errorCode.Message = "create order failed, step price of product '" + shoppingCartSnapshot.ProductInfo.ProductName + "'is failed"
|
errorCode.Message = "create order failed, step price of product '" + shoppingCartSnapshot.ProductInfo.ProductName + "'is failed"
|
||||||
@ -556,7 +855,32 @@ func (d *defaultOrder) Create(ctx context.Context, in *CreateReq) (res *CreateRe
|
|||||||
if shoppingCart.ShoppingCartProduct.CoverResource != nil && shoppingCart.ShoppingCartProduct.CoverResource.Metadata != nil {
|
if shoppingCart.ShoppingCartProduct.CoverResource != nil && shoppingCart.ShoppingCartProduct.CoverResource.Metadata != nil {
|
||||||
json.Unmarshal(*shoppingCart.ShoppingCartProduct.CoverResource.Metadata, &productCoverMetadata)
|
json.Unmarshal(*shoppingCart.ShoppingCartProduct.CoverResource.Metadata, &productCoverMetadata)
|
||||||
}
|
}
|
||||||
orderProductList = append(orderProductList, gmodel.OrderProduct{
|
snapshot, err := d.OrderDetailSnapshotHandler(ctx, shoppingCart.FsShoppingCart.Snapshot)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var shoppingCartSnapshotInter = &gmodel.FsShoppingCartData{
|
||||||
|
Id: shoppingCart.FsShoppingCart.Id,
|
||||||
|
UserId: shoppingCart.FsShoppingCart.UserId,
|
||||||
|
ProductId: shoppingCart.FsShoppingCart.ProductId,
|
||||||
|
TemplateId: shoppingCart.FsShoppingCart.TemplateId,
|
||||||
|
ModelId: shoppingCart.FsShoppingCart.ModelId,
|
||||||
|
SizeId: shoppingCart.FsShoppingCart.SizeId,
|
||||||
|
LightId: shoppingCart.FsShoppingCart.LightId,
|
||||||
|
FittingId: shoppingCart.FsShoppingCart.FittingId,
|
||||||
|
PurchaseQuantity: shoppingCart.FsShoppingCart.PurchaseQuantity,
|
||||||
|
Snapshot: &snapshot,
|
||||||
|
SnapshotData: shoppingCart.FsShoppingCart.Snapshot,
|
||||||
|
IsSelected: shoppingCart.FsShoppingCart.IsSelected,
|
||||||
|
IsHighlyCustomized: shoppingCart.FsShoppingCart.IsHighlyCustomized,
|
||||||
|
Ctime: shoppingCart.FsShoppingCart.Ctime,
|
||||||
|
Utime: shoppingCart.FsShoppingCart.Utime,
|
||||||
|
}
|
||||||
|
var purchaseQuantityInter = gmodel.PurchaseQuantity{
|
||||||
|
Current: *shoppingCart.PurchaseQuantity,
|
||||||
|
Initiate: *shoppingCart.PurchaseQuantity,
|
||||||
|
}
|
||||||
|
productInter := gmodel.OrderProduct{
|
||||||
TotalPrice: order.GetAmountInfo(order.GetAmountInfoReq{
|
TotalPrice: order.GetAmountInfo(order.GetAmountInfoReq{
|
||||||
ExchangeRate: in.ExchangeRate,
|
ExchangeRate: in.ExchangeRate,
|
||||||
Initiate: productTotalPrice,
|
Initiate: productTotalPrice,
|
||||||
@ -565,7 +889,7 @@ func (d *defaultOrder) Create(ctx context.Context, in *CreateReq) (res *CreateRe
|
|||||||
OriginalCurrency: in.OriginalCurrency,
|
OriginalCurrency: in.OriginalCurrency,
|
||||||
}),
|
}),
|
||||||
ExpectedDeliveryTime: &in.ExpectedDeliveryTime,
|
ExpectedDeliveryTime: &in.ExpectedDeliveryTime,
|
||||||
PurchaseQuantity: *shoppingCart.PurchaseQuantity,
|
PurchaseQuantity: purchaseQuantityInter,
|
||||||
ProductID: *shoppingCart.ProductId,
|
ProductID: *shoppingCart.ProductId,
|
||||||
ProductCover: *shoppingCart.ShoppingCartProduct.Cover,
|
ProductCover: *shoppingCart.ShoppingCartProduct.Cover,
|
||||||
ProductCoverMetadata: productCoverMetadata,
|
ProductCoverMetadata: productCoverMetadata,
|
||||||
@ -578,7 +902,7 @@ func (d *defaultOrder) Create(ctx context.Context, in *CreateReq) (res *CreateRe
|
|||||||
OriginalCurrency: in.OriginalCurrency,
|
OriginalCurrency: in.OriginalCurrency,
|
||||||
}),
|
}),
|
||||||
ProductSnapshot: shoppingCart.ShoppingCartProduct,
|
ProductSnapshot: shoppingCart.ShoppingCartProduct,
|
||||||
ShoppingCartSnapshot: &shoppingCart.FsShoppingCart,
|
ShoppingCartSnapshot: shoppingCartSnapshotInter,
|
||||||
ProductSn: *shoppingCart.ShoppingCartProduct.Sn,
|
ProductSn: *shoppingCart.ShoppingCartProduct.Sn,
|
||||||
DiyInformation: &shoppingCartSnapshot.UserDiyInformation,
|
DiyInformation: &shoppingCartSnapshot.UserDiyInformation,
|
||||||
FittingInfo: &gmodel.OrderProductFittingInfo{
|
FittingInfo: &gmodel.OrderProductFittingInfo{
|
||||||
@ -593,9 +917,9 @@ func (d *defaultOrder) Create(ctx context.Context, in *CreateReq) (res *CreateRe
|
|||||||
Cm: shoppingCartSnapshot.SizeInfo.Cm,
|
Cm: shoppingCartSnapshot.SizeInfo.Cm,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
StepNum: stepNum,
|
|
||||||
IsHighlyCustomized: *shoppingCart.IsHighlyCustomized,
|
IsHighlyCustomized: *shoppingCart.IsHighlyCustomized,
|
||||||
})
|
}
|
||||||
|
orderProductList = append(orderProductList, productInter)
|
||||||
}
|
}
|
||||||
|
|
||||||
subtotal = order.GetAmountInfo(order.GetAmountInfoReq{
|
subtotal = order.GetAmountInfo(order.GetAmountInfoReq{
|
||||||
@ -621,6 +945,7 @@ func (d *defaultOrder) Create(ctx context.Context, in *CreateReq) (res *CreateRe
|
|||||||
StatusCode: int64(constants.PAYSTATUSUNPAID),
|
StatusCode: int64(constants.PAYSTATUSUNPAID),
|
||||||
StatusTitle: constants.PayStatusMessage[constants.PAYSTATUSUNPAID],
|
StatusTitle: constants.PayStatusMessage[constants.PAYSTATUSUNPAID],
|
||||||
},
|
},
|
||||||
|
StatusLink: make([]gmodel.PayStatus, 0),
|
||||||
PayAmount: order.GetAmountInfo(order.GetAmountInfoReq{
|
PayAmount: order.GetAmountInfo(order.GetAmountInfoReq{
|
||||||
ExchangeRate: in.ExchangeRate,
|
ExchangeRate: in.ExchangeRate,
|
||||||
Initiate: depositInt,
|
Initiate: depositInt,
|
||||||
@ -637,6 +962,7 @@ func (d *defaultOrder) Create(ctx context.Context, in *CreateReq) (res *CreateRe
|
|||||||
StatusCode: int64(constants.PAYSTATUSUNPAID),
|
StatusCode: int64(constants.PAYSTATUSUNPAID),
|
||||||
StatusTitle: constants.PayStatusMessage[constants.PAYSTATUSUNPAID],
|
StatusTitle: constants.PayStatusMessage[constants.PAYSTATUSUNPAID],
|
||||||
},
|
},
|
||||||
|
StatusLink: make([]gmodel.PayStatus, 0),
|
||||||
PayAmount: order.GetAmountInfo(order.GetAmountInfoReq{
|
PayAmount: order.GetAmountInfo(order.GetAmountInfoReq{
|
||||||
ExchangeRate: in.ExchangeRate,
|
ExchangeRate: in.ExchangeRate,
|
||||||
Initiate: remainingBalanceInt,
|
Initiate: remainingBalanceInt,
|
||||||
@ -659,8 +985,8 @@ func (d *defaultOrder) Create(ctx context.Context, in *CreateReq) (res *CreateRe
|
|||||||
var status = gmodel.OrderStatus{
|
var status = gmodel.OrderStatus{
|
||||||
Ctime: &nowTime,
|
Ctime: &nowTime,
|
||||||
Utime: &nowTime,
|
Utime: &nowTime,
|
||||||
StatusCode: constants.ORDERSTATUSUNPAIDDEPOSIT,
|
StatusCode: constants.ORDER_STATUS_UNPAIDDEPOSIT,
|
||||||
StatusTitle: constants.OrderStatusMessage[constants.ORDERSTATUSUNPAIDDEPOSIT],
|
StatusTitle: constants.OrderStatusMessage[constants.ORDER_STATUS_UNPAIDDEPOSIT],
|
||||||
}
|
}
|
||||||
// 订单状态--链路
|
// 订单状态--链路
|
||||||
var statusLink = order.GenerateOrderStatusLink(in.DeliveryMethod, nowTime, in.ExpectedDeliveryTime)
|
var statusLink = order.GenerateOrderStatusLink(in.DeliveryMethod, nowTime, in.ExpectedDeliveryTime)
|
||||||
@ -719,8 +1045,68 @@ func (d *defaultOrder) Create(ctx context.Context, in *CreateReq) (res *CreateRe
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理订单购物车快照
|
||||||
|
func (d *defaultOrder) OrderDetailSnapshotHandler(ctx context.Context, req *string) (res map[string]interface{}, err error) {
|
||||||
|
var snapshot map[string]interface{}
|
||||||
|
json.Unmarshal([]byte(*req), &snapshot)
|
||||||
|
snapshotFittingInfoData, snapshotFittingInfoEx := snapshot["fitting_info"]
|
||||||
|
var fittingInfoMap map[string]interface{}
|
||||||
|
if snapshotFittingInfoEx {
|
||||||
|
var snapshotFittingInfoJson map[string]interface{}
|
||||||
|
var fittingName string
|
||||||
|
snapshotFittingInfo := snapshotFittingInfoData.(map[string]interface{})
|
||||||
|
snapshotFittingInfoJsonData, snapshotFittingInfoJsonEx := snapshotFittingInfo["fitting_json"]
|
||||||
|
if snapshotFittingInfoJsonEx {
|
||||||
|
json.Unmarshal([]byte(snapshotFittingInfoJsonData.(string)), &snapshotFittingInfoJson)
|
||||||
|
}
|
||||||
|
fittingNameData, fittingNameEx := snapshotFittingInfo["fitting_name"]
|
||||||
|
if fittingNameEx {
|
||||||
|
fittingName = fittingNameData.(string)
|
||||||
|
}
|
||||||
|
fittingInfoMap = make(map[string]interface{}, 2)
|
||||||
|
fittingInfoMap["fitting_json"] = snapshotFittingInfoJson
|
||||||
|
fittingInfoMap["fitting_name"] = fittingName
|
||||||
|
}
|
||||||
|
snapshot["fitting_info"] = fittingInfoMap
|
||||||
|
|
||||||
|
snapshotModelInfoData, snapshotModelInfoEx := snapshot["model_info"]
|
||||||
|
var modelInfoMap map[string]interface{}
|
||||||
|
if snapshotModelInfoEx {
|
||||||
|
var snapshotModelInfoJson map[string]interface{}
|
||||||
|
snapshotModelInfo := snapshotModelInfoData.(map[string]interface{})
|
||||||
|
snapshotModelInfoJsonData, snapshotModelInfoJsonEx := snapshotModelInfo["model_json"]
|
||||||
|
if snapshotModelInfoJsonEx {
|
||||||
|
json.Unmarshal([]byte(snapshotModelInfoJsonData.(string)), &snapshotModelInfoJson)
|
||||||
|
}
|
||||||
|
modelInfoMap = make(map[string]interface{}, 1)
|
||||||
|
modelInfoMap["model_json"] = snapshotModelInfoJson
|
||||||
|
}
|
||||||
|
snapshot["model_info"] = modelInfoMap
|
||||||
|
|
||||||
|
snapshotTemplateInfoData, snapshotTemplateInfoEx := snapshot["template_info"]
|
||||||
|
var templateInfoMap map[string]interface{}
|
||||||
|
if snapshotTemplateInfoEx {
|
||||||
|
var snapshotTemplateInfoJson map[string]interface{}
|
||||||
|
var templateTag string
|
||||||
|
snapshotTemplateInfo := snapshotTemplateInfoData.(map[string]interface{})
|
||||||
|
snapshotTemplateInfoJsonData, snapshotTemplateInfoJsonEx := snapshotTemplateInfo["template_json"]
|
||||||
|
if snapshotTemplateInfoJsonEx {
|
||||||
|
json.Unmarshal([]byte(snapshotTemplateInfoJsonData.(string)), &snapshotTemplateInfoJson)
|
||||||
|
}
|
||||||
|
templateTagData, templateTagEx := snapshotTemplateInfo["template_tag"]
|
||||||
|
if templateTagEx {
|
||||||
|
templateTag = templateTagData.(string)
|
||||||
|
}
|
||||||
|
templateInfoMap = make(map[string]interface{}, 2)
|
||||||
|
templateInfoMap["template_json"] = snapshotTemplateInfoJson
|
||||||
|
templateInfoMap["template_tag"] = templateTag
|
||||||
|
}
|
||||||
|
snapshot["template_info"] = templateInfoMap
|
||||||
|
return snapshot, nil
|
||||||
|
}
|
||||||
|
|
||||||
// 详情处理
|
// 详情处理
|
||||||
func (d *defaultOrder) OrderDetailHandler(ctx context.Context, orderInfo *gmodel.FsOrder) (res *DetailRes, err error) {
|
func (d *defaultOrder) OrderDetailHandler(ctx context.Context, orderInfo *gmodel.FsOrder, original int64) (res *DetailRes, err error) {
|
||||||
var orderDetail gmodel.OrderDetail
|
var orderDetail gmodel.OrderDetail
|
||||||
|
|
||||||
err = json.Unmarshal(*orderInfo.Metadata, &orderDetail)
|
err = json.Unmarshal(*orderInfo.Metadata, &orderDetail)
|
||||||
@ -729,18 +1115,21 @@ func (d *defaultOrder) OrderDetailHandler(ctx context.Context, orderInfo *gmodel
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
orderDetailOriginal := orderDetail
|
orderDetailOriginal := orderDetail
|
||||||
for orderProductKey, orderProduct := range orderDetail.OrderProduct {
|
if original == 1 {
|
||||||
orderDetail.OrderProduct[orderProductKey].TotalPrice = order.GetAmountInfoFormat(&orderProduct.TotalPrice)
|
for orderProductKey, orderProduct := range orderDetail.OrderProduct {
|
||||||
orderDetail.OrderProduct[orderProductKey].ItemPrice = order.GetAmountInfoFormat(&orderProduct.ItemPrice)
|
orderDetail.OrderProduct[orderProductKey].TotalPrice = order.GetAmountInfoFormat(&orderProduct.TotalPrice)
|
||||||
orderDetail.OrderProduct[orderProductKey].ShoppingCartSnapshot = nil
|
orderDetail.OrderProduct[orderProductKey].TotalPrice = order.GetAmountInfoFormat(&orderProduct.TotalPrice)
|
||||||
orderDetail.OrderProduct[orderProductKey].ProductSnapshot = nil
|
orderDetail.OrderProduct[orderProductKey].PurchaseQuantity = order.GetPurchaseQuantity(&orderProduct.PurchaseQuantity)
|
||||||
|
orderDetail.OrderProduct[orderProductKey].ProductSnapshot = nil
|
||||||
|
orderDetail.OrderProduct[orderProductKey].ShoppingCartSnapshot.SnapshotData = nil
|
||||||
|
}
|
||||||
|
orderDetail.OrderInfo.StatusLink = order.GetOrderStatusLinkUser(orderDetail.OrderInfo.DeliveryMethod, orderDetail.OrderInfo.StatusLink)
|
||||||
|
orderDetail.OrderAmount.Deposit.PayAmount = order.GetAmountInfoFormat(&orderDetail.OrderAmount.Deposit.PayAmount)
|
||||||
|
orderDetail.OrderAmount.RemainingBalance.PayAmount = order.GetAmountInfoFormat(&orderDetail.OrderAmount.RemainingBalance.PayAmount)
|
||||||
|
orderDetail.OrderAmount.Subtotal = order.GetAmountInfoFormat(&orderDetail.OrderAmount.Subtotal)
|
||||||
|
orderDetail.OrderAmount.Total = order.GetAmountInfoFormat(&orderDetail.OrderAmount.Total)
|
||||||
|
orderDetail.PayTimeout = time.Duration(orderDetail.OrderInfo.Ctime.Add(orderDetail.PayTimeout).UTC().Unix() - time.Now().UTC().Unix())
|
||||||
}
|
}
|
||||||
orderDetail.OrderInfo.StatusLink = order.GetOrderStatusLinkUser(orderDetail.OrderInfo.DeliveryMethod, orderDetail.OrderInfo.StatusLink)
|
|
||||||
orderDetail.OrderAmount.Deposit.PayAmount = order.GetAmountInfoFormat(&orderDetail.OrderAmount.Deposit.PayAmount)
|
|
||||||
orderDetail.OrderAmount.RemainingBalance.PayAmount = order.GetAmountInfoFormat(&orderDetail.OrderAmount.RemainingBalance.PayAmount)
|
|
||||||
orderDetail.OrderAmount.Subtotal = order.GetAmountInfoFormat(&orderDetail.OrderAmount.Subtotal)
|
|
||||||
orderDetail.OrderAmount.Total = order.GetAmountInfoFormat(&orderDetail.OrderAmount.Total)
|
|
||||||
orderDetail.PayTimeout = time.Duration(orderDetail.OrderInfo.Ctime.Add(orderDetail.PayTimeout).UTC().Unix() - time.Now().UTC().Unix())
|
|
||||||
|
|
||||||
return &DetailRes{
|
return &DetailRes{
|
||||||
OrderDetail: orderDetail,
|
OrderDetail: orderDetail,
|
||||||
|
|||||||
@ -3,15 +3,10 @@ package repositories
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"fusenapi/model/gmodel"
|
"fusenapi/model/gmodel"
|
||||||
"fusenapi/utils/format"
|
|
||||||
"fusenapi/utils/hash"
|
"fusenapi/utils/hash"
|
||||||
"fusenapi/utils/step_price"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/session"
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"math"
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -33,7 +28,7 @@ type (
|
|||||||
// 校验订单
|
// 校验订单
|
||||||
VerifyShoppingCartSnapshotDataChange(req VerifyShoppingCartSnapshotDataChangeReq) error
|
VerifyShoppingCartSnapshotDataChange(req VerifyShoppingCartSnapshotDataChangeReq) error
|
||||||
//计算购物车价格
|
//计算购物车价格
|
||||||
CaculateCartPrice(purchaseQuantity int64, productPrice *gmodel.FsProductPrice, fittingPrice int64) (ItemPrice, totalPrice int64, stepNum, stepPrice []int, err error)
|
CaculateStepPrice(purchaseQuantity int64, stepPrice gmodel.StepPriceJsonStruct, fittingPrice int64) (totalPrice, itemPrice int64, err error)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -132,33 +127,23 @@ func (d *defaultShoppingCart) VerifyShoppingCartSnapshotDataChange(req VerifySho
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 计算价格
|
// 计算价格
|
||||||
func (d *defaultShoppingCart) CaculateCartPrice(purchaseQuantity int64, productPrice *gmodel.FsProductPrice, fittingPrice int64) (ItemPrice, totalPrice int64, stepNum, stepPrice []int, err error) {
|
func (d *defaultShoppingCart) CaculateStepPrice(purchaseQuantity int64, stepPrice gmodel.StepPriceJsonStruct, fittingPrice int64) (totalPrice, itemPrice int64, err error) {
|
||||||
//阶梯数量切片
|
l := len(stepPrice.PriceRange)
|
||||||
stepNum, err = format.StrSlicToIntSlice(strings.Split(*productPrice.StepNum, ","))
|
if l == 0 {
|
||||||
if err != nil {
|
return 0, 0, errors.New("price range is not set")
|
||||||
logx.Error(err)
|
|
||||||
return 0, 0, nil, nil, errors.New(fmt.Sprintf("failed to parse step number:%d_%d", *productPrice.ProductId, *productPrice.SizeId))
|
|
||||||
}
|
}
|
||||||
lenStepNum := len(stepNum)
|
//遍历查询合适的价格
|
||||||
//阶梯价格切片
|
for k, v := range stepPrice.PriceRange {
|
||||||
stepPrice, err = format.StrSlicToIntSlice(strings.Split(*productPrice.StepPrice, ","))
|
//购买数量>起点
|
||||||
if err != nil {
|
if purchaseQuantity > v.StartQuantity {
|
||||||
logx.Error(err)
|
//最后一个 || 小于等于终点
|
||||||
return 0, 0, nil, nil, errors.New(fmt.Sprintf("failed to parse step price:%d_%d", *productPrice.ProductId, *productPrice.SizeId))
|
if k == l-1 || purchaseQuantity <= v.EndQuantity {
|
||||||
|
itemPrice = v.Price + fittingPrice
|
||||||
|
return itemPrice * purchaseQuantity, itemPrice, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lenStepPrice := len(stepPrice)
|
//遍历里面没有则返回第一个
|
||||||
if lenStepPrice == 0 || lenStepNum == 0 {
|
itemPrice = stepPrice.PriceRange[0].Price + fittingPrice
|
||||||
return 0, 0, nil, nil, errors.New(fmt.Sprintf("step price or step number is not set:%d_%d", *productPrice.ProductId, *productPrice.SizeId))
|
return itemPrice * purchaseQuantity, itemPrice, nil
|
||||||
}
|
|
||||||
//请求的数量
|
|
||||||
reqPurchaseQuantity := purchaseQuantity
|
|
||||||
//购买箱数
|
|
||||||
boxQuantity := int(math.Ceil(float64(reqPurchaseQuantity) / float64(*productPrice.EachBoxNum)))
|
|
||||||
//根据数量获取阶梯价格中对应的价格
|
|
||||||
itemPrice := step_price.GetCentStepPrice(boxQuantity, stepNum, stepPrice)
|
|
||||||
//如果有配件,单价也要加入配件价格
|
|
||||||
itemPrice += fittingPrice
|
|
||||||
//单个购物车总价
|
|
||||||
totalPrice = itemPrice * reqPurchaseQuantity
|
|
||||||
return itemPrice, totalPrice, stepNum, stepPrice, nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -107,9 +107,10 @@ var (
|
|||||||
CodeErrOrderCreatProductPriceAbsent = &StatusResponse{5304, "create order failed, price of product is absent"} // 订单创建失败,商品价格不存在
|
CodeErrOrderCreatProductPriceAbsent = &StatusResponse{5304, "create order failed, price of product is absent"} // 订单创建失败,商品价格不存在
|
||||||
CodeErrOrderCreatProductAccessoryAbsent = &StatusResponse{5305, "create order failed, accessory of product is absent"} // 订单创建失败,商品配件不存在
|
CodeErrOrderCreatProductAccessoryAbsent = &StatusResponse{5305, "create order failed, accessory of product is absent"} // 订单创建失败,商品配件不存在
|
||||||
CodeErrOrderCreatePrePaymentParam = &StatusResponse{5306, "create payment failed, the shipping address is illegal"} // 订单创建失败,商品配件不存在
|
CodeErrOrderCreatePrePaymentParam = &StatusResponse{5306, "create payment failed, the shipping address is illegal"} // 订单创建失败,商品配件不存在
|
||||||
CodeErrOrderCreatePrePaymentInfoNoFound = &StatusResponse{5307, "create payment failed, order info not found"}
|
CodeErrOrderCreatePrePaymentInfoNoFound = &StatusResponse{5307, "order info not found"}
|
||||||
CodeErrOrderCreatePrePaymentPaidDeposit = &StatusResponse{5308, "create payment failed, order is paid"}
|
CodeErrOrderCreatePrePaymentNoUnPaid = &StatusResponse{5308, "create payment failed, order is not unpaid"}
|
||||||
CodeErrOrderCreatePrePaymentTimeout = &StatusResponse{5309, "create payment failed, timeout"}
|
CodeErrOrderCreatePrePaymentPaid = &StatusResponse{5309, "create payment failed, order is paid"}
|
||||||
|
CodeErrOrderCreatePrePaymentTimeout = &StatusResponse{5310, "create payment failed, timeout"}
|
||||||
)
|
)
|
||||||
|
|
||||||
type Response struct {
|
type Response struct {
|
||||||
|
|||||||
@ -20,8 +20,9 @@ func NewClient(ctx context.Context, c *Config) Client {
|
|||||||
client := resty.New().SetBaseURL(c.BaseUrl)
|
client := resty.New().SetBaseURL(c.BaseUrl)
|
||||||
|
|
||||||
// 设置超时时间为 5 分钟
|
// 设置超时时间为 5 分钟
|
||||||
client.SetTimeout(5 * time.Minute)
|
if c.RequireTimeout == 0 {
|
||||||
|
client.SetTimeout(5 * time.Minute)
|
||||||
|
}
|
||||||
/* 传输链路 */
|
/* 传输链路 */
|
||||||
tracer := otel.GetTracerProvider().Tracer(trace.TraceName)
|
tracer := otel.GetTracerProvider().Tracer(trace.TraceName)
|
||||||
spanCtx, span := tracer.Start(
|
spanCtx, span := tracer.Start(
|
||||||
@ -60,11 +61,12 @@ func NewClient(ctx context.Context, c *Config) Client {
|
|||||||
|
|
||||||
type (
|
type (
|
||||||
Config struct {
|
Config struct {
|
||||||
BaseUrl string `json:"base_url"`
|
BaseUrl string `json:"base_url"`
|
||||||
Url string `json:"url"`
|
Url string `json:"url"`
|
||||||
HeaderData map[string]string `json:"header_data"`
|
HeaderData map[string]string `json:"header_data"`
|
||||||
RetryCount int64 `json:"retry_count"`
|
RetryCount int64 `json:"retry_count"`
|
||||||
RetryWaitTime int64 `json:"retry_wait_time"`
|
RetryWaitTime int64 `json:"retry_wait_time"`
|
||||||
|
RequireTimeout time.Duration `json:"require_timeout"`
|
||||||
}
|
}
|
||||||
defaultClient struct {
|
defaultClient struct {
|
||||||
c *Config
|
c *Config
|
||||||
|
|||||||
25
utils/format/number.go
Normal file
25
utils/format/number.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package format
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 数字变成带千分位的字符串
|
||||||
|
func NumToStringWithThousandthPercentile(number int64) string {
|
||||||
|
s := fmt.Sprintf("%d", number)
|
||||||
|
l := len(s)
|
||||||
|
if l <= 3 {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
r := l % 3 //前面第几位开始加入千分位
|
||||||
|
b := strings.Builder{}
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
b.WriteString(string(s[i]))
|
||||||
|
if i+1 == r && i != l-1 {
|
||||||
|
b.WriteString(",")
|
||||||
|
r += 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b.String()
|
||||||
|
}
|
||||||
@ -59,7 +59,7 @@ func MetadataModulePATCH(tx *gorm.DB, module string, tableStructPointer any, upd
|
|||||||
WHEN metadata IS NULL THEN ?
|
WHEN metadata IS NULL THEN ?
|
||||||
ELSE JSON_MERGE_PATCH(metadata, ?)
|
ELSE JSON_MERGE_PATCH(metadata, ?)
|
||||||
END
|
END
|
||||||
WHERE order_sn = '%s' and %s;`
|
WHERE module = '%s' and %s;`
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
var metadata []byte
|
var metadata []byte
|
||||||
@ -191,3 +191,12 @@ func MetadataOrderPATCH(tx *gorm.DB, sql string, orderSn string, tableStructPoin
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetGormTableName(tx *gorm.DB, tableStructPointer any) string {
|
||||||
|
stype := reflect.TypeOf(tableStructPointer)
|
||||||
|
if stype.Kind() == reflect.Pointer {
|
||||||
|
stype = stype.Elem()
|
||||||
|
}
|
||||||
|
tname := tx.NamingStrategy.TableName(stype.Name())
|
||||||
|
return tname
|
||||||
|
}
|
||||||
|
|||||||
@ -8,10 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestCase1(t *testing.T) {
|
func TestCase1(t *testing.T) {
|
||||||
u := gmodel.UserProfile{
|
u := gmodel.UserProfile{}
|
||||||
FirstName: "h",
|
|
||||||
LastName: "sm",
|
|
||||||
}
|
|
||||||
|
|
||||||
conn := initalize.InitMysql("fsreaderwriter:XErSYmLELKMnf3Dh@tcp(fusen.cdmigcvz3rle.us-east-2.rds.amazonaws.com:3306)/fusen")
|
conn := initalize.InitMysql("fsreaderwriter:XErSYmLELKMnf3Dh@tcp(fusen.cdmigcvz3rle.us-east-2.rds.amazonaws.com:3306)/fusen")
|
||||||
err := fssql.MetadataModulePATCH(conn, "profile", gmodel.FsUserInfo{}, u, "id = ?", 90)
|
err := fssql.MetadataModulePATCH(conn, "profile", gmodel.FsUserInfo{}, u, "id = ?", 90)
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import (
|
|||||||
"fusenapi/constants"
|
"fusenapi/constants"
|
||||||
"fusenapi/model/gmodel"
|
"fusenapi/model/gmodel"
|
||||||
"fusenapi/utils/format"
|
"fusenapi/utils/format"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -112,6 +113,14 @@ func GetAmountInfoFormat(req *gmodel.AmountInfo) gmodel.AmountInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理商品数量
|
||||||
|
func GetPurchaseQuantity(req *gmodel.PurchaseQuantity) gmodel.PurchaseQuantity {
|
||||||
|
return gmodel.PurchaseQuantity{
|
||||||
|
Initiate: strconv.FormatInt(int64(req.Initiate.(float64)), 10),
|
||||||
|
Current: strconv.FormatInt(int64(req.Current.(float64)), 10),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 生成订单编号
|
// 生成订单编号
|
||||||
func GenerateOrderNumber() string {
|
func GenerateOrderNumber() string {
|
||||||
t := time.Now()
|
t := time.Now()
|
||||||
@ -120,7 +129,7 @@ func GenerateOrderNumber() string {
|
|||||||
return orderNumber
|
return orderNumber
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化订单状态
|
// 初始化订单状态--链路
|
||||||
func GenerateOrderStatusLink(deliveryMethod int64, noTime time.Time, expectedTime time.Time) []gmodel.OrderStatus {
|
func GenerateOrderStatusLink(deliveryMethod int64, noTime time.Time, expectedTime time.Time) []gmodel.OrderStatus {
|
||||||
var list []gmodel.OrderStatus
|
var list []gmodel.OrderStatus
|
||||||
|
|
||||||
@ -142,6 +151,42 @@ func GenerateOrderStatusLink(deliveryMethod int64, noTime time.Time, expectedTim
|
|||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 更新订单状态--链路
|
||||||
|
func UpdateOrderStatusLink(statusLink []gmodel.OrderStatus, status gmodel.OrderStatus) []gmodel.OrderStatus {
|
||||||
|
var list []gmodel.OrderStatus
|
||||||
|
for _, v := range statusLink {
|
||||||
|
if v.StatusCode == status.StatusCode {
|
||||||
|
item := v
|
||||||
|
if status.StatusTitle != "" {
|
||||||
|
item.StatusTitle = status.StatusTitle
|
||||||
|
}
|
||||||
|
if status.StatusCode != 0 {
|
||||||
|
item.StatusCode = status.StatusCode
|
||||||
|
}
|
||||||
|
if status.Utime != nil {
|
||||||
|
item.Utime = status.Utime
|
||||||
|
}
|
||||||
|
if status.Ctime != nil {
|
||||||
|
item.Ctime = status.Ctime
|
||||||
|
}
|
||||||
|
if status.Metadata != nil {
|
||||||
|
item.Metadata = status.Metadata
|
||||||
|
}
|
||||||
|
if status.ExpectedTime != nil {
|
||||||
|
item.ExpectedTime = status.ExpectedTime
|
||||||
|
}
|
||||||
|
if status.Children != nil || len(status.Children) > 0 {
|
||||||
|
item.Children = status.Children
|
||||||
|
}
|
||||||
|
|
||||||
|
list = append(list, item)
|
||||||
|
} else {
|
||||||
|
list = append(list, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
// 获取订单状态
|
// 获取订单状态
|
||||||
func GetOrderStatusLinkUser(deliveryMethod int64, statusLink []gmodel.OrderStatus) []gmodel.OrderStatus {
|
func GetOrderStatusLinkUser(deliveryMethod int64, statusLink []gmodel.OrderStatus) []gmodel.OrderStatus {
|
||||||
var list []gmodel.OrderStatus
|
var list []gmodel.OrderStatus
|
||||||
|
|||||||
@ -29,15 +29,15 @@ type Pay interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type GeneratePrepaymentReq struct {
|
type GeneratePrepaymentReq struct {
|
||||||
OrderSn string `json:"order_sn"` // 订单编号
|
Metadata map[string]string `json:"metadata"` // 元数据
|
||||||
Amount int64 `json:"amount"` // 支付金额
|
Amount int64 `json:"amount"` // 支付金额
|
||||||
Currency string `json:"currency"` // 支付货币
|
Currency string `json:"currency"` // 支付货币
|
||||||
ProductName string `json:"product_name"` // 商品名称
|
ProductName string `json:"product_name"` // 商品名称
|
||||||
ProductDescription string `json:"product_description"` // 商品描述
|
ProductDescription string `json:"product_description"` // 商品描述
|
||||||
ProductImages []*string `json:"product_imageso"` // 商品照片
|
ProductImages []*string `json:"product_imageso"` // 商品照片
|
||||||
Quantity int64 `json:"quantity"` //数量
|
Quantity int64 `json:"quantity"` //数量
|
||||||
SuccessURL string `json:"success_url"` // 支付成功回调
|
SuccessURL string `json:"success_url"` // 支付成功回调
|
||||||
CancelURL string `json:"cancel_url"` // 支付取消回调
|
CancelURL string `json:"cancel_url"` // 支付取消回调
|
||||||
}
|
}
|
||||||
|
|
||||||
type GeneratePrepaymentRes struct {
|
type GeneratePrepaymentRes struct {
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
package pay
|
package pay
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/stripe/stripe-go/v74"
|
"github.com/stripe/stripe-go/v75"
|
||||||
"github.com/stripe/stripe-go/v74/checkout/session"
|
"github.com/stripe/stripe-go/v75/checkout/session"
|
||||||
"github.com/stripe/stripe-go/v74/paymentintent"
|
"github.com/stripe/stripe-go/v75/paymentintent"
|
||||||
"github.com/stripe/stripe-go/v74/refund"
|
"github.com/stripe/stripe-go/v75/refund"
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ func (stripePay *Stripe) GeneratePrepayment(req *GeneratePrepaymentReq) (res *Ge
|
|||||||
case "session":
|
case "session":
|
||||||
// session 方式
|
// session 方式
|
||||||
params := &stripe.CheckoutSessionParams{
|
params := &stripe.CheckoutSessionParams{
|
||||||
PaymentIntentData: &stripe.CheckoutSessionPaymentIntentDataParams{Metadata: map[string]string{"order_sn": req.OrderSn}},
|
PaymentIntentData: &stripe.CheckoutSessionPaymentIntentDataParams{Metadata: req.Metadata},
|
||||||
// Params: stripe.Params{Metadata: map[string]string{"order_id": "1111111111111"}},
|
// Params: stripe.Params{Metadata: map[string]string{"order_id": "1111111111111"}},
|
||||||
PaymentMethodTypes: stripe.StringSlice([]string{
|
PaymentMethodTypes: stripe.StringSlice([]string{
|
||||||
"card",
|
"card",
|
||||||
@ -86,6 +86,9 @@ func (stripePay *Stripe) GeneratePrepayment(req *GeneratePrepaymentReq) (res *Ge
|
|||||||
// "ideal",
|
// "ideal",
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
for key, item := range req.Metadata {
|
||||||
|
params.AddMetadata(key, item)
|
||||||
|
}
|
||||||
resPaymentintent, err := paymentintent.New(params)
|
resPaymentintent, err := paymentintent.New(params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@ -1,22 +1,6 @@
|
|||||||
package step_price
|
package step_price
|
||||||
|
|
||||||
// 返回美元
|
// 旧的返回厘(即将废弃)
|
||||||
func GetStepPrice(minBuyNum int, stepNum []int, stepPrice []int) float64 {
|
|
||||||
if minBuyNum > stepNum[len(stepNum)-1] {
|
|
||||||
return float64(stepPrice[len(stepPrice)-1]) / float64(1000)
|
|
||||||
}
|
|
||||||
for k, v := range stepNum {
|
|
||||||
if minBuyNum <= v {
|
|
||||||
if k <= (len(stepPrice) - 1) {
|
|
||||||
return float64(stepPrice[k]) / float64(1000)
|
|
||||||
}
|
|
||||||
return float64(stepPrice[len(stepPrice)-1]) / float64(1000)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return float64(stepPrice[len(stepPrice)-1]) / float64(1000)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 返回厘
|
|
||||||
func GetCentStepPrice(minBuyNum int, stepNum []int, stepPrice []int) int64 {
|
func GetCentStepPrice(minBuyNum int, stepNum []int, stepPrice []int) int64 {
|
||||||
if minBuyNum > stepNum[len(stepNum)-1] {
|
if minBuyNum > stepNum[len(stepNum)-1] {
|
||||||
return int64(stepPrice[len(stepPrice)-1])
|
return int64(stepPrice[len(stepPrice)-1])
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user