package order_preview import ( "recook/internal/back" "recook/internal/dbc" "recook/internal/model/order_preview" "recook/internal/model/user" goods3 "recook/internal/v2/model/recook/goods" "recook/tools" "github.com/astaxie/beego" "github.com/gin-gonic/gin" "github.com/shopspring/decimal" ) func OrderCoinOnOff(c *gin.Context) { type coinOnOff struct { UserID uint `json:"userId" validate:"required"` PreviewOrderID uint `json:"previewOrderId" validate:"numeric"` } var p coinOnOff err := tools.ParseParams(&p, c) if err != nil { back.Fail(c, err.Error()) return } if p.UserID <= 0 { back.Fail(c, "游客无法使用该功能,请先登录") return } // 获取preview 数据 var previewOrderInfo order_preview.Information if err = dbc.DB.First(&previewOrderInfo, "id = ?", p.PreviewOrderID).Error; err != nil { back.Err(c, err.Error()) return } // 获取对应商品数据 var preOrderGoodsList []order_preview.GoodsDetail if err = dbc.DB.Find(&preOrderGoodsList, "order_id = ?", p.PreviewOrderID).Error; err != nil { back.Err(c, err.Error()) return } // 获取用户钱包数据 var wallet user.Wallet if err = dbc.DB.First(&wallet, "user_id = ?", p.UserID).Error; err != nil { back.Err(c, err.Error()) return } // 判断开关 is_on := true if previewOrderInfo.CoinTotalAmount.Equal(decimal.NewFromInt(0)) && wallet.Coin.GreaterThan(decimal.NewFromInt(0)) { is_on = false } beego.Info(is_on) // 如果是打开的状态 去关闭 if is_on { tx := dbc.DB.Begin() { // previewOrder 去掉瑞比支付 if err = tx.Model(&previewOrderInfo).Updates(map[string]interface{}{ "actual_total_amount": previewOrderInfo.ActualTotalAmount.Add(previewOrderInfo.CoinTotalAmount), "coin_total_amount": decimal.NewFromInt(0), }).Error; err != nil { back.Err(c, err.Error()) tx.Rollback() return } // 商品去掉瑞比支付 for i, _ := range preOrderGoodsList { if err = tx.Model(&preOrderGoodsList[i]).Updates(map[string]interface{}{ "actual_amount": preOrderGoodsList[i].ActualAmount.Add(preOrderGoodsList[i].CoinAmount), "coin_amount": decimal.NewFromInt(0), }).Error; err != nil { back.Err(c, err.Error()) tx.Rollback() return } } } tx.Commit() } else { // 如果是关闭的状态 去打开 // 判断是否包含不支持瑞币的商品 recookGoodsInfoModel := &goods3.RecookGoodsInfoModel{} for _, v := range preOrderGoodsList { if !recookGoodsInfoModel.HasCoin(v.Storehouse) { back.Err(c, "订单含保税仓或海外仓商品,无法使用瑞币抵扣") return } } goodsTotalAmount := previewOrderInfo.GoodsTotalAmount expressTotalFee := previewOrderInfo.ExpressTotalFee universeCouponTotalAmount := previewOrderInfo.UniverseCouponTotalAmount brandCouponTotalAmount := previewOrderInfo.BrandCouponTotalAmount coinTotalAmount := decimal.NewFromFloat(0.0) actualTotalAmount := goodsTotalAmount.Add(expressTotalFee).Sub(universeCouponTotalAmount).Sub(brandCouponTotalAmount) if wallet.Coin.GreaterThanOrEqual(decimal.NewFromInt(0)) { // 瑞币金额不小于1块钱时可以抵扣 walletCoinAmount := wallet.Coin if actualTotalAmount.GreaterThanOrEqual(walletCoinAmount) { // 只能抵扣部分价格, 全部花光瑞比 coinTotalAmount = walletCoinAmount actualTotalAmount = actualTotalAmount.Sub(coinTotalAmount) } else { // 不能全部花光瑞比,瑞比足够支付时 将瑞币直接使用掉 订单金额为0 coinTotalAmount = actualTotalAmount actualTotalAmount = decimal.NewFromFloat(0.0) // 如果可以全部抵扣 for _, v := range preOrderGoodsList { v.CoinAmount = v.GoodsAmount.Sub(v.BrandCouponAmount).Sub(v.UniverseCouponAmount) } } // 折算到每件商品上的抵扣 length := len(preOrderGoodsList) previousTotalAmount := decimal.NewFromFloat(0.0) for i, v := range preOrderGoodsList { if i == length-1 { // 保证没有循环小数 preOrderGoodsList[i].CoinAmount = coinTotalAmount.Sub(previousTotalAmount) } else { rate := (v.GoodsAmount.Add(v.ExpressFee)).Div(goodsTotalAmount.Add(expressTotalFee)) preOrderGoodsList[i].CoinAmount = coinTotalAmount.Mul(rate).Round(2) previousTotalAmount = previousTotalAmount.Add(preOrderGoodsList[i].CoinAmount) } } } tx := dbc.DB.Begin() { // previewOrder 进行瑞比支付 if err = tx.Model(&previewOrderInfo).Updates(map[string]interface{}{ "actual_total_amount": previewOrderInfo.ActualTotalAmount.Sub(coinTotalAmount), "coin_total_amount": coinTotalAmount, }).Error; err != nil { back.Err(c, err.Error()) tx.Rollback() return } // 商品进行瑞比支付 for i, _ := range preOrderGoodsList { if err = tx.Model(&preOrderGoodsList[i]).Updates(map[string]interface{}{ "actual_amount": preOrderGoodsList[i].ActualAmount.Sub(preOrderGoodsList[i].CoinAmount), "coin_amount": preOrderGoodsList[i].CoinAmount, }).Error; err != nil { back.Err(c, err.Error()) tx.Rollback() return } } } tx.Commit() } back.Suc(c, "", queryPreviewOrderGroup(previewOrderInfo.ID)) }