fusenapi/service/repositories/order.go

1177 lines
40 KiB
Go
Raw Normal View History

2023-09-15 09:58:45 +00:00
package repositories
import (
"context"
"encoding/json"
"errors"
2023-09-21 11:01:48 +00:00
"fmt"
2023-09-19 11:17:04 +00:00
"fusenapi/constants"
2023-09-15 09:58:45 +00:00
"fusenapi/model/gmodel"
"fusenapi/utils/basic"
2023-09-21 11:01:48 +00:00
"fusenapi/utils/fssql"
"fusenapi/utils/handlers"
2023-09-18 07:39:12 +00:00
"fusenapi/utils/order"
2023-09-21 11:01:48 +00:00
"fusenapi/utils/pay"
2023-09-19 11:17:04 +00:00
"time"
2023-09-15 09:58:45 +00:00
"github.com/aws/aws-sdk-go/aws/session"
2023-09-25 09:31:42 +00:00
"github.com/stripe/stripe-go/v75"
2023-09-22 08:27:17 +00:00
"github.com/zeromicro/go-zero/core/logc"
2023-09-20 10:04:33 +00:00
"github.com/zeromicro/go-zero/core/logx"
2023-09-15 09:58:45 +00:00
"gorm.io/gorm"
)
func NewOrder(gormDB *gorm.DB, bLMServiceUrl *string, awsSession *session.Session) Order {
return &defaultOrder{
MysqlConn: gormDB,
}
}
type (
defaultOrder struct {
MysqlConn *gorm.DB
}
Order interface {
// 下单
2023-09-20 07:07:12 +00:00
Create(ctx context.Context, in *CreateReq) (res *CreateRes, err error)
2023-09-21 11:01:48 +00:00
// 预支付--定金
CreatePrePaymentByDeposit(ctx context.Context, in *CreatePrePaymentByDepositReq) (res *CreatePrePaymentByDepositRes, err error)
2023-09-22 02:39:02 +00:00
// 预支付--定金
CreatePrePaymentByBalance(ctx context.Context, in *CreatePrePaymentByBalanceReq) (res *CreatePrePaymentByBalanceRes, err error)
2023-09-15 09:58:45 +00:00
// 列表
2023-09-21 11:01:48 +00:00
List(ctx context.Context, in *ListReq) (res *ListRes, err error)
2023-09-15 09:58:45 +00:00
// 详情
2023-09-21 02:30:36 +00:00
Detail(ctx context.Context, in *DetailReq) (res *DetailRes, err error)
2023-09-22 08:27:17 +00:00
// 支付成功
PaymentSuccessful(ctx context.Context, in *PaymentSuccessfulReq) (res *PaymentSuccessfulRes, err error)
}
PayInfo struct {
2023-09-26 02:56:57 +00:00
PayMethod string `json:"pay_method"` // 交易方式
2023-09-22 08:27:17 +00:00
PayTime time.Time `json:"pay_time"` // 支付时间
Status gmodel.PayStatus `json:"status"` // 当前状态
StatusLink []gmodel.PayStatus `json:"status_link"` // 状态链路
TradeNo string `json:"trade_no"` // 支付交易号
2023-09-15 09:58:45 +00:00
}
2023-09-19 11:17:04 +00:00
OrderAddress struct {
Address string `json:"address"` // 详细地址
Mobile string `json:"mobile"` // 手机
Name string `json:"name"` // 姓名
}
2023-09-21 11:01:48 +00:00
OrderPay struct {
ClientSecret string `json:"client_secret"` // 支付方--秘钥
Country string `json:"country"` // 国家
Currency string `json:"currency"` // 货币
Metadata map[string]interface{} `json:"metadata"` // 额外参数
Method string `json:"method"` // 支付方--途径
OrderSn string `json:"order_sn"` // 订单编码
PayStage int64 `json:"pay_stage"` // 支付阶段
RedirectURL *string `json:"redirect_url"` // 支付方--重定向地址
Total OrderPayTotal `json:"total"` // 支付参数
}
// 支付参数
OrderPayTotal struct {
Amount int64 `json:"amount"` // 金额
Label string `json:"label"` // 标签
}
2023-09-22 08:27:17 +00:00
/* 支付成功 */
PaymentSuccessfulReq struct {
EventId string
2023-09-26 02:56:57 +00:00
PaymentMethod string
2023-09-25 10:28:53 +00:00
Charge *stripe.Charge
2023-09-22 08:27:17 +00:00
}
PaymentSuccessfulRes struct{}
/* 支付成功 */
2023-09-21 11:01:48 +00:00
/* 预支付--定金 */
CreatePrePaymentByDepositReq struct {
StripeKey string `json:"stripe_key"`
Currency string `json:"currency"`
Country string `json:"country"`
UserId int64 `json:"user_id"`
OrderSn string `json:"order_sn"`
DeliveryMethod int64 `json:"delivery_method"`
2023-09-22 02:39:02 +00:00
DeliveryAddress *OrderAddress `json:"delivery_address"`
2023-09-21 11:01:48 +00:00
}
CreatePrePaymentByDepositRes struct {
ErrorCode basic.StatusResponse
OrderDetail gmodel.OrderDetail
OrderPay OrderPay
}
/* 预支付--定金 */
2023-09-19 11:17:04 +00:00
2023-09-22 02:39:02 +00:00
/* 预支付--尾款 */
CreatePrePaymentByBalanceReq struct {
2023-09-22 03:00:54 +00:00
StripeKey string `json:"stripe_key"`
Currency string `json:"currency"`
Country string `json:"country"`
UserId int64 `json:"user_id"`
OrderSn string `json:"order_sn"`
2023-09-22 02:39:02 +00:00
}
CreatePrePaymentByBalanceRes struct {
ErrorCode basic.StatusResponse
OrderDetail gmodel.OrderDetail
OrderPay OrderPay
}
/* 预支付--尾款 */
2023-09-15 09:58:45 +00:00
/* 下单 */
CreateReq struct {
2023-09-20 07:07:12 +00:00
ExpectedDeliveryTime time.Time `json:"expected_delivery_time"` // 预计到货时间
2023-09-19 11:17:04 +00:00
ExchangeRate int64 `json:"exchange_rate"` // 换算汇率(厘)
CurrentCurrency string `json:"current_currency"` // 当前货币
OriginalCurrency string `json:"original_currency"` // 原始货币
UserId int64 `json:"user_id"`
CartIds []int64 `json:"cart_ids"`
DeliveryMethod int64 `json:"delivery_method"`
DeliveryAddress *OrderAddress `json:"delivery_address"` // 收货地址
2023-09-15 09:58:45 +00:00
}
CreateRes struct {
ErrorCode basic.StatusResponse
OrderSn string
}
/* 下单 */
2023-09-21 02:30:36 +00:00
/* 详情 */
DetailReq struct {
UserId int64 `json:"user_id"`
OrderSn string `json:"order_sn"`
}
DetailRes struct {
2023-09-21 11:01:48 +00:00
ErrorCode basic.StatusResponse
OrderDetail gmodel.OrderDetail
OrderDetailOriginal gmodel.OrderDetail
2023-09-21 02:30:36 +00:00
}
/* 详情 */
2023-09-21 11:01:48 +00:00
/* 列表 */
ListReq struct {
UserId int64 `json:"user_id"`
DeliveryMethod int64 `json:"delivery_method"`
OrderCycle string `json:"order_cycle"`
CurrentPage int64 `json:"current_page"`
PerPage int64 `json:"per_page"`
}
ListRes struct {
OrderDetailList []gmodel.OrderDetail
Meta interface{}
}
/* 列表 */
2023-09-15 09:58:45 +00:00
)
2023-09-22 08:27:17 +00:00
// 支付成功
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
2023-09-26 02:56:57 +00:00
var paymentMethod int64 = 1
if in.PaymentMethod == "stripe" {
paymentMethod = 1
}
if in.PaymentMethod == "paypal" {
paymentMethod = 2
}
2023-09-25 10:28:53 +00:00
if in.Charge != nil {
charge := in.Charge
orderSn, ok = charge.Metadata["order_sn"]
2023-09-22 08:27:17 +00:00
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
}
2023-09-25 10:28:53 +00:00
payStage, ok = charge.Metadata["pay_stage"]
2023-09-22 08:27:17 +00:00
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
}
2023-09-25 10:28:53 +00:00
country, ok = charge.Metadata["country"]
2023-09-22 08:27:17 +00:00
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
}
2023-09-25 10:28:53 +00:00
if charge.PaymentMethodDetails != nil {
if charge.PaymentMethodDetails.Card != nil {
if charge.PaymentMethodDetails.Card.Last4 != "" {
card = charge.PaymentMethodDetails.Card.Last4
2023-09-22 08:27:17 +00:00
}
2023-09-25 10:28:53 +00:00
if charge.PaymentMethodDetails.Card.Brand != "" {
brand = string(charge.PaymentMethodDetails.Card.Brand)
2023-09-22 08:27:17 +00:00
}
}
}
2023-09-25 10:28:53 +00:00
if charge.Currency != "" {
currency = string(charge.Currency)
2023-09-22 08:27:17 +00:00
}
2023-09-25 10:28:53 +00:00
tradeSn = charge.ID
payAmount = charge.Amount
payTitle = charge.Description
payTime = time.Unix(charge.Created, 0)
2023-09-22 08:27:17 +00:00
}
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
2023-09-26 02:56:57 +00:00
// 当前状态
var statusCode constants.OrderStatusCode
var statusCodePre constants.OrderStatusCode
2023-09-22 08:27:17 +00:00
if payStage == "deposit" {
2023-09-26 02:56:57 +00:00
if *orderInfo.DeliveryMethod == constants.DELIVERYMETHODDIRECTMAIL {
// 直邮
statusCode = constants.ORDERSTATUSDIRECTMAILORDERED
}
if *orderInfo.DeliveryMethod == constants.DELIVERYMETHODDSCLOUDSTORE {
// 云仓
statusCode = constants.ORDERSTATUSCLOUDSTOREORDERED
}
2023-09-22 08:27:17 +00:00
payStageInt = 1
orderPayStatusCode = constants.ORDERPAYSTATUSPAIDDEPOSIT
status = gmodel.OrderStatus{
Ctime: &ntime,
Utime: &ntime,
2023-09-26 02:56:57 +00:00
StatusCode: statusCode,
StatusTitle: constants.OrderStatusMessage[statusCode],
2023-09-22 08:27:17 +00:00
}
statusLink = order.UpdateOrderStatusLink(ress.OrderDetailOriginal.OrderInfo.StatusLink, gmodel.OrderStatus{
2023-09-26 07:25:05 +00:00
Ctime: &ntime,
2023-09-22 08:27:17 +00:00
Utime: &ntime,
2023-09-26 02:56:57 +00:00
StatusCode: statusCode,
StatusTitle: constants.OrderStatusMessage[statusCode],
2023-09-22 08:27:17 +00:00
})
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" {
2023-09-26 02:56:57 +00:00
if *orderInfo.DeliveryMethod == constants.DELIVERYMETHODDIRECTMAIL {
// 直邮
statusCodePre = constants.ORDERSTATUSDIRECTMAILORDERED
statusCode = constants.ORDERSTATUSDIRECTMAILORDEREDMAINING
}
if *orderInfo.DeliveryMethod == constants.DELIVERYMETHODDSCLOUDSTORE {
// 云仓
statusCodePre = constants.ORDERSTATUSCLOUDSTOREORDERED
statusCode = constants.ORDERSTATUSCLOUDSTOREORDEREDMAINING
}
2023-09-22 08:27:17 +00:00
payStageInt = 2
orderPayStatusCode = constants.ORDERPAYSTATUSPAIDDREMAINING
2023-09-26 02:56:57 +00:00
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
}
2023-09-22 08:27:17 +00:00
}
2023-09-26 02:56:57 +00:00
if ress.OrderDetail.OrderInfo.Status.StatusCode == constants.ORDERSTATUSDIRECTMAILORDERED || ress.OrderDetail.OrderInfo.Status.StatusCode == constants.ORDERSTATUSCLOUDSTOREORDERED {
status = ress.OrderDetail.OrderInfo.Status
status.Children = statusChildren
}
2023-09-22 08:27:17 +00:00
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,
2023-09-26 02:56:57 +00:00
PaymentMethod: &paymentMethod,
2023-09-22 08:27:17 +00:00
PayStage: &payStageInt,
CardSn: &card,
CardBrand: &brand,
Country: &country,
Currency: &currency,
Ctime: &ntime,
Utime: &ntime,
PayTitle: &payTitle,
})
// 更新订单信息
2023-09-26 07:25:05 +00:00
var sql string = fmt.Sprintf(", `utime` = '%s', `pay_status` = %d", ntime, orderPayStatusCode)
2023-09-22 08:27:17 +00:00
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,
}
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
}
2023-09-22 02:39:02 +00:00
// 预支付--尾款
func (d *defaultOrder) CreatePrePaymentByBalance(ctx context.Context, in *CreatePrePaymentByBalanceReq) (res *CreatePrePaymentByBalanceRes, err error) {
2023-09-22 03:00:54 +00:00
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
}
2023-09-22 08:27:17 +00:00
ress, err := d.OrderDetailHandler(ctx, &order, 1)
2023-09-22 03:00:54 +00:00
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
2023-09-22 08:27:17 +00:00
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
2023-09-22 03:00:54 +00:00
var generatePrepaymentReq = &pay.GeneratePrepaymentReq{
2023-09-22 08:27:17 +00:00
Metadata: metadata,
2023-09-22 03:00:54 +00:00
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: 1,
Total: OrderPayTotal{
Amount: amount,
Label: "支付尾款后期统一调整",
},
},
}, nil
2023-09-22 02:39:02 +00:00
}
2023-09-21 11:01:48 +00:00
// 预支付--定金
func (d *defaultOrder) CreatePrePaymentByDeposit(ctx context.Context, in *CreatePrePaymentByDepositReq) (res *CreatePrePaymentByDepositRes, err error) {
var errorCode basic.StatusResponse
2023-09-21 02:30:36 +00:00
var order gmodel.FsOrder
2023-09-21 11:01:48 +00:00
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)
2023-09-21 02:30:36 +00:00
if result.Error != nil {
2023-09-21 11:01:48 +00:00
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
errorCode = *basic.CodeErrOrderCreatePrePaymentInfoNoFound
} else {
errorCode = *basic.CodeServiceErr
}
logx.Errorf("create prePayment deposit failed, err: %v", err)
return &CreatePrePaymentByDepositRes{
ErrorCode: errorCode,
}, result.Error
2023-09-21 02:30:36 +00:00
}
2023-09-21 11:01:48 +00:00
// 非未支付
if *order.PayStatus != int64(constants.ORDERPAYSTATUSUNPAIDDEPOSIT) {
2023-09-22 03:00:54 +00:00
errorCode = *basic.CodeErrOrderCreatePrePaymentNoUnPaid
2023-09-21 11:01:48 +00:00
err = errors.New("order pay status is not unPaidDeposit")
logx.Errorf("create prePayment deposit failed, err: %v", err)
return &CreatePrePaymentByDepositRes{
ErrorCode: errorCode,
}, err
}
// 是否超时支付
ntime := time.Now().UTC()
ctime := *order.Ctime
ctimeTimeOut := ctime.Add(30 * time.Minute).UTC().Unix()
ntimeTimeOut := ntime.Unix()
2023-09-22 03:00:54 +00:00
// 测试超时支付不限制
2023-09-21 11:01:48 +00:00
if ctimeTimeOut == ntimeTimeOut {
errorCode = *basic.CodeErrOrderCreatePrePaymentTimeout
err = errors.New("order pay timeout")
logx.Errorf("create prePayment deposit failed, err: %v", err)
return &CreatePrePaymentByDepositRes{
ErrorCode: errorCode,
}, err
}
2023-09-22 08:27:17 +00:00
ress, err := d.OrderDetailHandler(ctx, &order, 0)
2023-09-21 06:26:14 +00:00
if err != nil {
2023-09-21 11:01:48 +00:00
logx.Errorf("create prePayment deposit failed DetailOrderDetailHandler, err: %v", err)
errorCode = *basic.CodeServiceErr
return &CreatePrePaymentByDepositRes{
ErrorCode: errorCode,
}, err
2023-09-21 06:26:14 +00:00
}
2023-09-21 11:01:48 +00:00
var uOrderDetail = make(map[string]interface{})
var orderAddress *gmodel.OrderAddress
2023-09-22 04:12:33 +00:00
if in.DeliveryMethod == constants.DELIVERYMETHODDIRECTMAIL {
orderAddress = &gmodel.OrderAddress{
Name: in.DeliveryAddress.Name,
Mobile: in.DeliveryAddress.Mobile,
Address: in.DeliveryAddress.Address,
2023-09-21 11:01:48 +00:00
}
}
var sql string = fmt.Sprintf(", `utime` = '%s'", ntime)
// 是否更新
if in.DeliveryMethod != *order.DeliveryMethod {
sql = sql + fmt.Sprintf(",`delivery_method` = %d", in.DeliveryMethod)
if in.DeliveryMethod == constants.DELIVERYMETHODDIRECTMAIL {
uOrderDetail["delivery_address"] = orderAddress
} else {
uOrderDetail["delivery_address"] = nil
}
uOrderDetail["order_info"] = struct {
DeliveryMethod int64 `json:"delivery_method"`
Utime *time.Time `json:"utime"`
}{
DeliveryMethod: in.DeliveryMethod,
Utime: &ntime,
}
} else {
if in.DeliveryMethod == constants.DELIVERYMETHODDIRECTMAIL {
// 更新收货地址
if orderAddress != nil {
uOrderDetail["delivery_address"] = orderAddress
uOrderDetail["order_info"] = struct {
DeliveryMethod int64 `json:"delivery_method"`
Utime *time.Time `json:"utime"`
}{
DeliveryMethod: in.DeliveryMethod,
Utime: &ntime,
}
}
}
}
2023-09-22 02:39:02 +00:00
if len(uOrderDetail) > 0 {
err = fssql.MetadataOrderPATCH(d.MysqlConn, sql, in.OrderSn, gmodel.FsOrder{}, uOrderDetail, "id = ?", order.Id)
if err != nil {
errorCode = *basic.CodeServiceErr
logx.Errorf("create prePayment deposit failed MetadataOrderPATCH, err: %v", err)
return &CreatePrePaymentByDepositRes{
ErrorCode: errorCode,
}, result.Error
}
}
ress.OrderDetail.OrderInfo.Utime = &ntime
ress.OrderDetail.OrderInfo.DeliveryMethod = in.DeliveryMethod
ress.OrderDetail.DeliveryAddress = orderAddress
2023-09-21 11:01:48 +00:00
// 支付初始化
amount := int64(ress.OrderDetailOriginal.OrderAmount.Deposit.PayAmount.Current.CurrentAmount.(float64) / float64(10))
payConfig := &pay.Config{}
payConfig.Stripe.PayType = "intent"
payConfig.Stripe.Key = in.StripeKey
2023-09-22 08:27:17 +00:00
var metadata = make(map[string]string, 2)
metadata["model"] = "product_order"
metadata["order_sn"] = in.OrderSn
metadata["pay_stage"] = "deposit"
metadata["country"] = in.Country
2023-09-21 11:01:48 +00:00
var generatePrepaymentReq = &pay.GeneratePrepaymentReq{
2023-09-22 08:27:17 +00:00
Metadata: metadata,
2023-09-22 03:00:54 +00:00
ProductName: "支付首款",
2023-09-21 11:01:48 +00:00
Amount: amount,
Currency: "usd",
Quantity: 1,
2023-09-22 03:00:54 +00:00
ProductDescription: "支付首款",
2023-09-21 11:01:48 +00:00
}
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{
OrderDetail: ress.OrderDetail,
OrderPay: OrderPay{
ClientSecret: prepaymentRes.ClientSecret,
Country: in.Country,
Currency: in.Currency,
Method: payConfig.Stripe.PayType,
OrderSn: in.OrderSn,
PayStage: 1,
Total: OrderPayTotal{
Amount: amount,
Label: "",
},
},
2023-09-21 06:26:14 +00:00
}, nil
2023-09-21 02:30:36 +00:00
}
2023-09-21 11:01:48 +00:00
// 列表
func (d *defaultOrder) List(ctx context.Context, in *ListReq) (res *ListRes, err error) {
var orderList []gmodel.FsOrder
model := d.MysqlConn.Model(&gmodel.FsOrder{}).Where("is_del = ?", 0)
if in.UserId != 0 {
model.Where("user_id = ?", in.UserId)
}
2023-09-21 02:30:36 +00:00
2023-09-21 11:01:48 +00:00
// Where("pay_status > ?", 0)
if in.DeliveryMethod != 0 {
model.Where("delivery_method = ?", in.DeliveryMethod)
2023-09-21 02:30:36 +00:00
}
2023-09-21 11:01:48 +00:00
if in.OrderCycle != "" {
// 下单时间
switch in.OrderCycle {
case "within_one_month":
model.Where("ctime >?", time.Now().UTC().AddDate(0, -1, 0).Unix())
case "within_three_month":
model.Where("ctime >?", time.Now().UTC().AddDate(0, -3, 0).Unix())
case "within_six_month":
model.Where("ctime >?", time.Now().UTC().AddDate(0, -6, 0).Unix())
case "within_one_year":
model.Where("ctime >?", time.Now().UTC().AddDate(-1, 0, 0).Unix())
}
}
var count int64
resultCount := model.Count(&count)
if resultCount.Error != nil {
logx.Errorf("order count failed, err: %v", err)
return nil, resultCount.Error
}
var orderDetailList []gmodel.OrderDetail
if count > 0 {
m := model.Scopes(handlers.Paginate(&in.CurrentPage, &in.PerPage))
result := m.Find(&orderList)
if result.Error != nil {
logx.Errorf("order list failed, err: %v", err)
return nil, result.Error
}
for _, order := range orderList {
2023-09-22 08:27:17 +00:00
ress, err := d.OrderDetailHandler(ctx, &order, 1)
2023-09-21 11:01:48 +00:00
if err != nil {
return nil, err
}
orderDetailList = append(orderDetailList, ress.OrderDetail)
}
} else {
orderDetailList = make([]gmodel.OrderDetail, 0)
}
return &ListRes{
OrderDetailList: orderDetailList,
Meta: map[string]int64{
"total_count": count,
"page_count": count / in.PerPage,
"current_page": in.CurrentPage,
"per_page": in.PerPage,
},
}, nil
}
// 详情
func (d *defaultOrder) Detail(ctx context.Context, in *DetailReq) (res *DetailRes, 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("order detail failed, err: %v", err)
return &DetailRes{
ErrorCode: errorCode,
}, result.Error
}
// 是否超时支付
ctime := *order.Ctime
ctimeTimeOut := ctime.Add(30 * time.Minute).UTC().Unix()
ntimeTimeOut := time.Now().UTC().Unix()
if ctimeTimeOut < ntimeTimeOut {
errorCode = *basic.CodeErrOrderCreatePrePaymentTimeout
err = errors.New("order pay timeout")
logx.Errorf("order detail failed, err: %v", err)
return &DetailRes{
ErrorCode: errorCode,
}, err
}
2023-09-22 08:27:17 +00:00
ress, err := d.OrderDetailHandler(ctx, &order, 1)
2023-09-21 11:01:48 +00:00
if err != nil {
logx.Errorf("order detail failed, err: %v", err)
errorCode = *basic.CodeServiceErr
return &DetailRes{
ErrorCode: errorCode,
}, err
2023-09-21 04:11:15 +00:00
}
2023-09-21 06:26:14 +00:00
return &DetailRes{
2023-09-21 11:01:48 +00:00
ErrorCode: errorCode,
OrderDetail: ress.OrderDetail,
2023-09-21 06:26:14 +00:00
}, nil
2023-09-21 02:30:36 +00:00
}
2023-09-15 09:58:45 +00:00
// 下单
func (d *defaultOrder) Create(ctx context.Context, in *CreateReq) (res *CreateRes, err error) {
var errorCode basic.StatusResponse
2023-09-20 03:39:56 +00:00
// 订单编号
2023-09-21 02:30:36 +00:00
var orderSn string = order.GenerateOrderNumber()
2023-09-20 03:39:56 +00:00
2023-09-15 09:58:45 +00:00
err = d.MysqlConn.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
// 查询购物车
var shoppingCartList []*gmodel.RelaFsShoppingCart
2023-09-20 10:04:33 +00:00
resShoppingCartFind := tx.Table(gmodel.NewFsShoppingCartModel(tx).TableName()).
Preload("ShoppingCartProduct", func(dbPreload *gorm.DB) *gorm.DB {
return dbPreload.Table(gmodel.NewFsProductModel(tx).TableName()).Preload("CoverResource")
}).Preload("ShoppingCartProductPriceList").
2023-09-20 07:10:18 +00:00
Preload("ShoppingCartProductModel3dList").
Preload("ShoppingCartProductModel3dFitting").
2023-09-15 09:58:45 +00:00
Where("id IN ?", in.CartIds).
Where("user_id = ?", in.UserId).
Find(&shoppingCartList)
err = resShoppingCartFind.Error
if err != nil {
return err
}
shoppingCartListLen := len(shoppingCartList)
if shoppingCartListLen == 0 {
errorCode = *basic.CodeErrOrderCreatShoppingCartEmpty
return errors.New(errorCode.Message)
}
if shoppingCartListLen != len(in.CartIds) {
errorCode = *basic.CodeErrOrderCreatShoppingCartNotMatched
return errors.New(errorCode.Message)
}
2023-09-18 07:39:12 +00:00
// 订单商品列表
2023-09-20 03:39:56 +00:00
var orderProductList []gmodel.OrderProduct
2023-09-15 09:58:45 +00:00
2023-09-18 07:39:12 +00:00
var shippingFee gmodel.AmountInfo
// 订单税费总价(厘)
var shippingFeeTotal int64
var tax = gmodel.AmountInfo{}
// 订单邮费总价(厘)
var taxTotal int64
var discount gmodel.AmountInfo
// 订单折扣总价(厘)
var discountTotal int64
var subtotal gmodel.AmountInfo
// 订单商品总价(厘)
var orderProductTotal int64
var total gmodel.AmountInfo
// 订单总价(厘)
var orderTotal int64
2023-09-19 11:17:04 +00:00
var nowTime = time.Now().UTC()
// 收货地址
var orderAddress *gmodel.OrderAddress
// 支付状态
var payStatus = constants.ORDERPAYSTATUSUNPAIDDEPOSIT
// 直邮
if in.DeliveryMethod == constants.DELIVERYMETHODDIRECTMAIL {
orderAddress = &gmodel.OrderAddress{
Mobile: in.DeliveryAddress.Mobile,
Name: in.DeliveryAddress.Name,
}
}
2023-09-19 05:56:59 +00:00
2023-09-15 09:58:45 +00:00
for _, shoppingCart := range shoppingCartList {
// 购物车快照
2023-09-20 07:28:57 +00:00
var shoppingCartSnapshot gmodel.CartSnapshot
2023-09-15 09:58:45 +00:00
// 购物车商品价格
var shoppingCartProductPrice *gmodel.FsProductPrice
// 购物车商品模型
var shoppingCartProductModel3d *gmodel.FsProductModel3d
if shoppingCart.Snapshot != nil {
json.Unmarshal([]byte(*shoppingCart.Snapshot), &shoppingCartSnapshot)
}
// 商品异常
if shoppingCart.ShoppingCartProduct == nil || (shoppingCart.ShoppingCartProduct != nil && *shoppingCart.ShoppingCartProduct.IsShelf == 0) {
errorCode = *basic.CodeErrOrderCreatProductAbsent
2023-09-15 10:30:45 +00:00
errorCode.Message = "create order failed, product '" + shoppingCartSnapshot.ProductInfo.ProductName + "'is absent"
2023-09-15 09:58:45 +00:00
return errors.New(errorCode.Message)
}
// 商品价格异常
if len(shoppingCart.ShoppingCartProductPriceList) == 0 {
errorCode = *basic.CodeErrOrderCreatProductPriceAbsent
2023-09-15 10:30:45 +00:00
errorCode.Message = "create order failed, price of product '" + shoppingCartSnapshot.ProductInfo.ProductName + "'is absent"
2023-09-15 09:58:45 +00:00
return errors.New(errorCode.Message)
} else {
var isProductPrice bool
for _, shoppingCartProductPriceInfo := range shoppingCart.ShoppingCartProductPriceList {
2023-09-20 10:04:33 +00:00
if *shoppingCart.SizeId == *shoppingCartProductPriceInfo.SizeId {
2023-09-15 09:58:45 +00:00
shoppingCartProductPrice = shoppingCartProductPriceInfo
isProductPrice = true
break
}
}
if !isProductPrice {
errorCode = *basic.CodeErrOrderCreatProductPriceAbsent
2023-09-15 10:30:45 +00:00
errorCode.Message = "create order failed, price of product '" + shoppingCartSnapshot.ProductInfo.ProductName + "'is absent"
2023-09-15 09:58:45 +00:00
return errors.New(errorCode.Message)
}
shoppingCart.ShoppingCartProductPriceList = []*gmodel.FsProductPrice{shoppingCartProductPrice}
}
// 商品模型异常
if len(shoppingCart.ShoppingCartProductModel3dList) == 0 {
errorCode = *basic.CodeErrOrderCreatProductAccessoryAbsent
2023-09-15 10:30:45 +00:00
errorCode.Message = "create order failed, accessoryof product '" + shoppingCartSnapshot.ProductInfo.ProductName + "'is absent"
2023-09-15 09:58:45 +00:00
return errors.New(errorCode.Message)
} else {
var isProductModel bool
for _, shoppingCartProductModel3dInfo := range shoppingCart.ShoppingCartProductModel3dList {
2023-09-20 10:04:33 +00:00
if *shoppingCart.SizeId == *shoppingCartProductModel3dInfo.SizeId {
2023-09-15 09:58:45 +00:00
shoppingCartProductModel3d = shoppingCartProductModel3dInfo
isProductModel = true
break
}
}
if !isProductModel {
errorCode = *basic.CodeErrOrderCreatProductAccessoryAbsent
2023-09-15 10:30:45 +00:00
errorCode.Message = "create order failed, accessory of product '" + shoppingCartSnapshot.ProductInfo.ProductName + "'is absent"
2023-09-15 09:58:45 +00:00
return errors.New(errorCode.Message)
}
shoppingCart.ShoppingCartProductModel3dList = []*gmodel.FsProductModel3d{shoppingCartProductModel3d}
}
2023-09-15 10:30:45 +00:00
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 {
json.Unmarshal([]byte(*shoppingCartProductPrice.StepNum), &stepNum)
}
if *shoppingCartProductPrice.StepPrice == "" {
errorCode = *basic.CodeErrOrderCreatProductPriceAbsent
errorCode.Message = "create order failed, step price of product '" + shoppingCartSnapshot.ProductInfo.ProductName + "'is failed"
return errors.New(errorCode.Message)
} else {
json.Unmarshal([]byte(*shoppingCartProductPrice.StepPrice), &stepPrice)
}
2023-09-20 03:57:08 +00:00
/* 计算价格 */
2023-09-25 07:49:59 +00:00
productPrice, productTotalPrice, stepNum, stepPrice, err := NewShoppingCart(tx, nil, nil).CaculateCartPrice(*shoppingCart.PurchaseQuantity, shoppingCartProductPrice, *shoppingCart.ShoppingCartProductModel3dFitting.Price)
2023-09-20 03:55:51 +00:00
if err != nil {
errorCode = *basic.CodeErrOrderCreatProductPriceAbsent
2023-09-20 08:21:06 +00:00
errorCode.Message = "create order failed, step price of product '" + shoppingCartSnapshot.ProductInfo.ProductName + "'is failed"
return err
2023-09-20 03:55:51 +00:00
}
2023-09-20 03:57:08 +00:00
/* 计算价格 */
2023-09-18 07:39:12 +00:00
// 订单商品总价(厘)
orderProductTotal = orderProductTotal + productTotalPrice
// 订单商品
2023-09-20 07:07:12 +00:00
var productCoverMetadata map[string]interface{}
if shoppingCart.ShoppingCartProduct.CoverResource != nil && shoppingCart.ShoppingCartProduct.CoverResource.Metadata != nil {
json.Unmarshal(*shoppingCart.ShoppingCartProduct.CoverResource.Metadata, &productCoverMetadata)
}
2023-09-26 07:14:08 +00:00
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{
2023-09-20 07:07:12 +00:00
TotalPrice: order.GetAmountInfo(order.GetAmountInfoReq{
2023-09-18 07:39:12 +00:00
ExchangeRate: in.ExchangeRate,
Initiate: productTotalPrice,
Current: productTotalPrice,
CurrentCurrency: in.CurrentCurrency,
OriginalCurrency: in.OriginalCurrency,
}),
2023-09-20 10:04:33 +00:00
ExpectedDeliveryTime: &in.ExpectedDeliveryTime,
2023-09-26 07:14:08 +00:00
PurchaseQuantity: purchaseQuantityInter,
2023-09-18 07:39:12 +00:00
ProductID: *shoppingCart.ProductId,
2023-09-20 07:07:12 +00:00
ProductCover: *shoppingCart.ShoppingCartProduct.Cover,
ProductCoverMetadata: productCoverMetadata,
2023-09-18 07:39:12 +00:00
ProductName: *shoppingCart.ShoppingCartProduct.Title,
2023-09-20 07:07:12 +00:00
ItemPrice: order.GetAmountInfo(order.GetAmountInfoReq{
2023-09-18 07:39:12 +00:00
ExchangeRate: in.ExchangeRate,
Initiate: productPrice,
Current: productPrice,
CurrentCurrency: in.CurrentCurrency,
OriginalCurrency: in.OriginalCurrency,
}),
2023-09-20 10:04:33 +00:00
ProductSnapshot: shoppingCart.ShoppingCartProduct,
2023-09-26 07:14:08 +00:00
ShoppingCartSnapshot: shoppingCartSnapshotInter,
2023-09-20 07:07:12 +00:00
ProductSn: *shoppingCart.ShoppingCartProduct.Sn,
2023-09-20 07:39:23 +00:00
DiyInformation: &shoppingCartSnapshot.UserDiyInformation,
2023-09-20 08:37:37 +00:00
FittingInfo: &gmodel.OrderProductFittingInfo{
FittingID: *shoppingCart.FittingId,
FittingName: shoppingCartSnapshot.FittingInfo.FittingName,
},
SizeInfo: &gmodel.OrderProductSizeInfo{
SizeID: *shoppingCart.SizeId,
Capacity: shoppingCartSnapshot.SizeInfo.Capacity,
Title: gmodel.OrderProductSizeInfoTitle{
Inch: shoppingCartSnapshot.SizeInfo.Inch,
Cm: shoppingCartSnapshot.SizeInfo.Cm,
},
},
2023-09-21 04:11:15 +00:00
StepNum: stepNum,
IsHighlyCustomized: *shoppingCart.IsHighlyCustomized,
2023-09-26 07:14:08 +00:00
}
orderProductList = append(orderProductList, productInter)
2023-09-15 09:58:45 +00:00
}
2023-09-18 07:39:12 +00:00
subtotal = order.GetAmountInfo(order.GetAmountInfoReq{
ExchangeRate: in.ExchangeRate,
Initiate: orderProductTotal,
Current: orderProductTotal,
CurrentCurrency: in.CurrentCurrency,
OriginalCurrency: in.OriginalCurrency,
})
orderTotal = orderProductTotal + shippingFeeTotal + taxTotal - discountTotal
total = order.GetAmountInfo(order.GetAmountInfoReq{
ExchangeRate: in.ExchangeRate,
Initiate: orderTotal,
Current: orderTotal,
CurrentCurrency: in.CurrentCurrency,
OriginalCurrency: in.OriginalCurrency,
})
2023-09-19 11:17:04 +00:00
// 定金
2023-09-20 03:39:56 +00:00
var depositInt int64 = orderTotal / 2
2023-09-19 11:17:04 +00:00
var deposit = gmodel.PayInfo{
Status: gmodel.PayStatus{
StatusCode: int64(constants.PAYSTATUSUNPAID),
StatusTitle: constants.PayStatusMessage[constants.PAYSTATUSUNPAID],
},
2023-09-22 08:27:17 +00:00
StatusLink: make([]gmodel.PayStatus, 0),
2023-09-20 03:39:56 +00:00
PayAmount: order.GetAmountInfo(order.GetAmountInfoReq{
ExchangeRate: in.ExchangeRate,
Initiate: depositInt,
Current: depositInt,
CurrentCurrency: in.CurrentCurrency,
OriginalCurrency: in.OriginalCurrency,
}),
2023-09-19 11:17:04 +00:00
}
2023-09-18 07:39:12 +00:00
2023-09-19 11:17:04 +00:00
// 尾款
2023-09-20 03:39:56 +00:00
var remainingBalanceInt int64 = orderTotal - depositInt
var remainingBalance = gmodel.PayInfo{
Status: gmodel.PayStatus{
StatusCode: int64(constants.PAYSTATUSUNPAID),
StatusTitle: constants.PayStatusMessage[constants.PAYSTATUSUNPAID],
},
2023-09-22 08:27:17 +00:00
StatusLink: make([]gmodel.PayStatus, 0),
2023-09-20 03:39:56 +00:00
PayAmount: order.GetAmountInfo(order.GetAmountInfoReq{
ExchangeRate: in.ExchangeRate,
Initiate: remainingBalanceInt,
Current: remainingBalanceInt,
CurrentCurrency: in.CurrentCurrency,
OriginalCurrency: in.OriginalCurrency,
}),
}
2023-09-19 11:17:04 +00:00
var orderAmount = gmodel.OrderAmount{
Deposit: deposit,
RemainingBalance: remainingBalance,
2023-09-20 03:39:56 +00:00
Discount: discount,
ShippingFee: shippingFee,
Tax: tax,
Subtotal: subtotal,
Total: total,
}
// 订单状态--当前
var status = gmodel.OrderStatus{
2023-09-20 10:04:33 +00:00
Ctime: &nowTime,
Utime: &nowTime,
2023-09-20 03:39:56 +00:00
StatusCode: constants.ORDERSTATUSUNPAIDDEPOSIT,
StatusTitle: constants.OrderStatusMessage[constants.ORDERSTATUSUNPAIDDEPOSIT],
}
// 订单状态--链路
2023-09-20 07:07:12 +00:00
var statusLink = order.GenerateOrderStatusLink(in.DeliveryMethod, nowTime, in.ExpectedDeliveryTime)
2023-09-20 03:39:56 +00:00
var orderInfo = gmodel.OrderInfo{
2023-09-20 10:04:33 +00:00
Ctime: &nowTime,
2023-09-20 03:39:56 +00:00
DeliveryMethod: in.DeliveryMethod,
OrderSn: orderSn,
Status: status,
StatusLink: statusLink,
}
var orderDetail = gmodel.OrderDetail{
DeliveryAddress: orderAddress,
OrderAmount: orderAmount,
OrderInfo: orderInfo,
OrderProduct: orderProductList,
PayStatus: payStatus,
2023-09-21 11:01:48 +00:00
PayTimeout: 30 * time.Minute,
2023-09-20 03:39:56 +00:00
}
// 数据库操作
2023-09-20 10:04:33 +00:00
orderDetailByte, err := json.Marshal(orderDetail)
if err != nil {
return err
}
var order = gmodel.FsOrder{
2023-09-20 03:39:56 +00:00
UserId: &in.UserId,
DeliveryMethod: &in.DeliveryMethod,
OrderSn: &orderSn,
Status: (*int64)(&status.StatusCode),
PayStatus: (*int64)(&payStatus),
Ctime: &nowTime,
2023-09-20 10:04:33 +00:00
Metadata: &orderDetailByte,
2023-09-20 03:39:56 +00:00
}
result := tx.Create(&order)
if result.Error != nil {
return result.Error
2023-09-19 11:17:04 +00:00
}
2023-09-15 09:58:45 +00:00
return nil
})
if err != nil {
2023-09-21 11:01:48 +00:00
logx.Errorf("order create order failed, err: %v", err)
2023-09-20 10:04:33 +00:00
if errorCode.Code == 0 {
errorCode.Code = basic.CodeApiErr.Code
errorCode.Message = basic.CodeApiErr.Message
}
2023-09-20 03:39:56 +00:00
return &CreateRes{
OrderSn: orderSn,
ErrorCode: errorCode,
}, err
2023-09-15 09:58:45 +00:00
}
return &CreateRes{
2023-09-20 03:39:56 +00:00
OrderSn: orderSn,
2023-09-15 09:58:45 +00:00
ErrorCode: errorCode,
}, nil
}
2023-09-21 11:01:48 +00:00
2023-09-26 07:14:08 +00:00
// 处理订单购物车快照
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
}
2023-09-21 11:01:48 +00:00
// 详情处理
2023-09-22 08:27:17 +00:00
func (d *defaultOrder) OrderDetailHandler(ctx context.Context, orderInfo *gmodel.FsOrder, original int64) (res *DetailRes, err error) {
2023-09-21 11:01:48 +00:00
var orderDetail gmodel.OrderDetail
err = json.Unmarshal(*orderInfo.Metadata, &orderDetail)
if err != nil {
logx.Errorf("order detail handler unmarshal metadata failed, err: %v", err)
return nil, err
}
orderDetailOriginal := orderDetail
2023-09-22 08:27:17 +00:00
if original == 1 {
for orderProductKey, orderProduct := range orderDetail.OrderProduct {
orderDetail.OrderProduct[orderProductKey].TotalPrice = order.GetAmountInfoFormat(&orderProduct.TotalPrice)
2023-09-22 09:32:23 +00:00
orderDetail.OrderProduct[orderProductKey].TotalPrice = order.GetAmountInfoFormat(&orderProduct.TotalPrice)
orderDetail.OrderProduct[orderProductKey].PurchaseQuantity = order.GetPurchaseQuantity(&orderProduct.PurchaseQuantity)
2023-09-22 08:27:17 +00:00
orderDetail.OrderProduct[orderProductKey].ProductSnapshot = nil
2023-09-26 07:14:08 +00:00
orderDetail.OrderProduct[orderProductKey].ShoppingCartSnapshot.SnapshotData = nil
2023-09-22 08:27:17 +00:00
}
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())
}
2023-09-21 11:01:48 +00:00
return &DetailRes{
OrderDetail: orderDetail,
OrderDetailOriginal: orderDetailOriginal,
}, nil
}