package repositories import ( "context" "encoding/json" "errors" "fmt" "fusenapi/model/gmodel" "fusenapi/utils/basic" "fusenapi/utils/order" "fusenapi/utils/shopping_cart" "fusenapi/utils/step_price" "math" "github.com/aws/aws-sdk-go/aws/session" "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 { // 下单 // 预支付 // 列表 // 详情 } /* 下单 */ CreateReq struct { ExpectedDeliveryTime string `json:"expected_delivery_time"` // 预计到货时间 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 string `json:"delivery_method"` } CreateRes struct { ErrorCode basic.StatusResponse OrderSn string } /* 下单 */ ) // 下单 func (d *defaultOrder) Create(ctx context.Context, in *CreateReq) (res *CreateRes, err error) { var errorCode basic.StatusResponse err = d.MysqlConn.WithContext(ctx).Transaction(func(tx *gorm.DB) error { // 查询购物车 var shoppingCartList []*gmodel.RelaFsShoppingCart resShoppingCartFind := tx.Preload("ShoppingCartProduct", func(dbPreload *gorm.DB) *gorm.DB { return dbPreload.Table(gmodel.NewFsProductModel(tx).TableName()).Preload("CoverResource") }).Preload("ShoppingCartProductPriceList").Preload("ShoppingCartProductModel3dList"). 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) } // 订单商品列表 var orderProductList []*gmodel.OrderProduct 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 for _, shoppingCart := range shoppingCartList { // 购物车快照 var shoppingCartSnapshot shopping_cart.CartSnapshot // 购物车商品价格 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 errorCode.Message = "create order failed, product '" + shoppingCartSnapshot.ProductInfo.ProductName + "'is absent" 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} } // 商品模型异常 if len(shoppingCart.ShoppingCartProductModel3dList) == 0 { errorCode = *basic.CodeErrOrderCreatProductAccessoryAbsent errorCode.Message = "create order failed, accessoryof product '" + shoppingCartSnapshot.ProductInfo.ProductName + "'is absent" return errors.New(errorCode.Message) } 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 purchaseQuantity float64 = float64(*shoppingCart.PurchaseQuantity) var eachBoxNum float64 = float64(*shoppingCartProductPrice.EachBoxNum) var boxNum float64 = math.Ceil(purchaseQuantity / eachBoxNum) 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) } // 商品单价(厘) productPrice := step_price.GetCentStepPrice(int(boxNum), stepNum, stepPrice) // 商品总价(厘) productTotalPrice := productPrice * *shoppingCart.PurchaseQuantity // 订单商品总价(厘) orderProductTotal = orderProductTotal + productTotalPrice // 订单商品 var productLogoResource *gmodel.Resource if shoppingCart.ShoppingCartProduct.CoverResource != nil { var coverResourceMetadata map[string]interface{} if shoppingCart.ShoppingCartProduct.CoverResource.Metadata != nil { json.Unmarshal(*shoppingCart.ShoppingCartProduct.CoverResource.Metadata, &coverResourceMetadata) } productLogoResource = &gmodel.Resource{ Metadata: coverResourceMetadata, ResourceID: shoppingCart.ShoppingCartProduct.CoverResource.ResourceId, ResourceType: *shoppingCart.ShoppingCartProduct.CoverResource.ResourceType, ResourceURL: *shoppingCart.ShoppingCartProduct.CoverResource.ResourceUrl, } } var productSnapshot = make(map[string]interface{}, 1) productSnapshot["product_snapshot"] = shoppingCart.ShoppingCartProduct orderProductList = append(orderProductList, &gmodel.OrderProduct{ Amount: order.GetAmountInfo(order.GetAmountInfoReq{ ExchangeRate: in.ExchangeRate, Initiate: productTotalPrice, Current: productTotalPrice, CurrentCurrency: in.CurrentCurrency, OriginalCurrency: in.OriginalCurrency, }), ExpectedDeliveryTime: in.ExpectedDeliveryTime, Number: *shoppingCart.PurchaseQuantity, ProductID: *shoppingCart.ProductId, ProductLogo: *shoppingCart.ShoppingCartProduct.Cover, ProductLogoResource: productLogoResource, ProductName: *shoppingCart.ShoppingCartProduct.Title, ProductPrice: order.GetAmountInfo(order.GetAmountInfoReq{ ExchangeRate: in.ExchangeRate, Initiate: productPrice, Current: productPrice, CurrentCurrency: in.CurrentCurrency, OriginalCurrency: in.OriginalCurrency, }), ProductSnapshot: productSnapshot, ShoppingCartSnapshot: &shoppingCart.FsShoppingCart, }) } 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, }) fmt.Println(orderProductList, shippingFee, shippingFeeTotal, tax, taxTotal, discount, discountTotal, subtotal, orderProductTotal, total) return nil }) if err != nil { fmt.Println(err) } return &CreateRes{ ErrorCode: errorCode, }, nil }