添加拆单

master
kanade 3 years ago
parent 2b8d47cefa
commit 0442ce1f19

@ -11,6 +11,7 @@ import (
"recook/internal/v2/lib/common"
"recook/internal/v2/lib/jcook"
"recook/internal/v2/lib/shama"
"recook/internal/v2/lib/supply"
"recook/internal/v2/model/recook/after"
"recook/tools"
"time"
@ -62,7 +63,7 @@ func RefundOrder(c *gin.Context) {
return
}
if (orderTemp.Kind == 1 || orderTemp.Kind == 2 || orderTemp.Kind == 3) && orderTemp.JCookStatus == 0 {
if (orderTemp.Kind == 1 || orderTemp.Kind == 2 || orderTemp.Kind == 3 || orderTemp.Kind == 4) && orderTemp.JCookStatus == 0 {
var ogs []order.GoodsDetail
err = dbc.DB.Find(&ogs, "order_id = ?", orderTemp.ID).Error
if err != nil {
@ -281,6 +282,15 @@ func RefundOrder(c *gin.Context) {
}
}
if (orderInfo.Kind == 4) && orderInfo.ApplyStatus != 11 && orderInfo.ApplyStatus != 12 && orderInfo.JCookStatus == 0 {
_, err := supply.Api.Order.Cancel(orderInfo.ThirdPartyOrderSn)
if err != nil {
tx.Model(orderInfo).Update("apply_status", 12) // 取消申请失败
} else {
tx.Model(orderInfo).Update("apply_status", 11) // 取消申请成功
}
}
}
tx.Commit()
}

@ -46,6 +46,8 @@ func (s *supplyTask) run() {
go s.price()
// 商品信息更新任务
go s.data()
// 拆单
go s.orderSplit()
}
// @Title 价格更新通知
@ -93,3 +95,34 @@ func (s *supplyTask) data() {
log.Println(err)
}
}
// @Title 拆单通知
func (s *supplyTask) orderSplit() {
defer func() {
if recoverErr := recover(); recoverErr != nil {
log.Println("供应链拆单mq错误", recoverErr)
}
time.Sleep(time.Second * 3)
s.orderSplit()
}()
pool, _ := ants.NewPool(5)
rabbitmq.Rabbitmq.Consume(supply.Api.Mq.OrderSplit(), false, 5, func(delivery amqp.Delivery) {
pool.Submit(func() {
defer func() {
if recoverErr := recover(); recoverErr != nil {
log.Println("消息队列调用错误,err:", recoverErr)
}
}()
var orderSplit supply.OrderSplit
json.Unmarshal(delivery.Body, &orderSplit)
if err := third.SupplyLogic.OrderSplit(orderSplit); err != nil {
log.Println("拆单处理失败,skuId:", string(delivery.Body), ",err:", err)
delivery.Reject(true)
return
} else {
defer delivery.Ack(false)
}
})
})
}

@ -1,17 +1,26 @@
package supply
import "fmt"
import (
"fmt"
"github.com/shopspring/decimal"
)
const (
// QueueSkuPriceChange 商品价格变动
queueSkuPriceChange = "supplySkuPriceChange:%s"
// QueueSkuChange 商品信息变动
queueSkuChange = "supplySkuChange:%s"
// queueOrderSplit 订单拆单
queueOrderSplit = "supplyOrderSplit:%s"
)
type mq struct {
}
type skuMessage struct {
SkuId uint `json:"skuId"`
}
// SkuPriceChangeQueue @Title 商品价格变动
func (m *mq) SkuPriceChangeQueue() string {
return getQuesuName(queueSkuPriceChange)
@ -22,6 +31,24 @@ func (m *mq) SkuChangeQueue() string {
return getQuesuName(queueSkuChange)
}
type OrderSplit struct {
OrderSn uint64 `json:"orderSn"`
RootOrderSn uint64 `json:"rootOrderSn"`
ParentOrderSn uint64 `json:"parentOrderSn"`
FreightFee decimal.Decimal `json:"freightFee"`
OrderFee decimal.Decimal `json:"orderFee"`
Skus []OrderSplitSkuItem `json:"skus"`
}
type OrderSplitSkuItem struct {
SkuId uint `json:"skuId"`
Quantity uint `json:"quantity"`
}
// OrderSplit @Title 订单拆单
func (m *mq) OrderSplit() string {
return getQuesuName(queueOrderSplit)
}
// @Title 获取队列名称
func getQuesuName(queue string) string {
return fmt.Sprintf(queue, Api.Config.AppKey)

@ -7,6 +7,7 @@ const (
orderSubmit = "/order/submit" // 提交订单
orderLadingBill = "/order/lading_bill" // 提单
orderClose = "/order/close" // 关闭订单
orderCancel = "/order/cancel" // 取消订单
ReplyOrderFreightFeeErrCodeNone = 0 // 无错误
ReplyOrderFreightFeeErrCodeErr = 1 // 有错误
@ -82,3 +83,11 @@ func (o *order) Close(orderSn string) (result ReplyOrderSubmit, err error) {
}, &result)
return
}
// Cancel @Title 取消订单
func (o *order) Cancel(orderSubSn string) (result ReplyOrderSubmit, err error) {
err = exec(orderCancel, map[string]interface{}{
"orderSubSn": orderSubSn,
}, &result)
return
}

@ -7,10 +7,13 @@ import (
"github.com/golangkit/formatime"
"github.com/shopspring/decimal"
"gorm.io/gorm"
"log"
"path"
"recook/internal/libs/bean"
order4 "recook/internal/model/order"
"recook/internal/v2/lib/supply"
"recook/internal/v2/model/recook/goods"
manage2 "recook/internal/v2/model/recook/order"
manage "recook/internal/v2/model/third"
"recook/tools"
"sort"
@ -736,3 +739,163 @@ func (s *supplyLogic) SyncData(skuIds []uint) error {
}
return nil
}
// OrderSplit @Title 拆单
func (s *supplyLogic) OrderSplit(orderSplit supply.OrderSplit) error {
var orderInfo manage2.RecookOrderInfoModel
mysql.Db.Preload("OrderSku").First(&orderInfo, "third_party_order_sn = ?", orderSplit.OrderSn)
if orderInfo.Id > 0 {
log.Println("重复拆单请求")
return nil
}
var parentOrderInfo manage2.RecookOrderInfoModel
if err := mysql.Db.Preload("OrderSku").First(&parentOrderInfo, "third_party_order_sn = ?", orderSplit.ParentOrderSn).Error; err != nil {
return err
}
var rod manage2.RecookOrderInfoModel
if err := mysql.Db.Preload("OrderSku").First(&parentOrderInfo, "third_party_order_sn = ?", orderSplit.RootOrderSn).Error; err != nil {
return err
}
return mysql.Db.Transaction(func(tx *gorm.DB) error {
parentOrderInfo.IsSplit = true
parentOrderInfo.Status = 3
tx.Save(&parentOrderInfo)
if err := tx.Table((&order4.Profit{}).TableName()).Where("order_id = ?", rod.Id).Update("status", 1).Error; err != nil {
return err
}
if err := tx.Table((&order4.Profit{}).TableName()).Where("order_id = ?", parentOrderInfo.Id).Update("status", 1).Error; err != nil {
return err
}
var skuIds []uint
for _, sku := range orderSplit.Skus {
skuIds = append(skuIds, sku.SkuId)
}
var orderSku []manage2.RecookOrderGoodsDetailModel
var sku []goods.RecookGoodsSkuModel
sub := tx.Select("id").Find(&sku, "third_party_sku_id in (?)", skuIds)
if err := tx.Find(&orderSku, "sku_id in (?) AND order_id = ?", sub, rod.Id).Error; err != nil {
log.Println(err.Error())
return err
}
// 拆分拆单运费
unit := orderSplit.FreightFee.Div(decimal.NewFromInt(int64(len(orderSku)))).Round(2)
fee := orderSplit.FreightFee
unitMap := make(map[uint]decimal.Decimal)
var orderSkuNew []manage2.RecookOrderGoodsDetailModel
for i := 0; i < len(orderSku); i++ {
if i == len(orderSku)-1 {
unitMap[orderSku[i].SkuId] = fee
break
}
fee = fee.Sub(unit)
unitMap[orderSku[i].SkuId] = unit
}
coinTotal := decimal.Zero
goodsTotalAmount := decimal.Zero
goodsTotalCommission := decimal.Zero
actualAmount := decimal.Zero
for _, v := range orderSku {
actualAmount = actualAmount.Add(v.GoodsAmount).Add(unitMap[v.SkuId]).Sub(v.CoinAmount)
coinTotal = coinTotal.Add(v.CoinAmount)
goodsTotalAmount = goodsTotalAmount.Add(v.GoodsAmount)
}
orderNew := manage2.RecookOrderInfoModel{
AncestorId: rod.AncestorId,
ParentId: rod.ParentId,
SharerId: rod.SharerId,
LiveId: rod.LiveId,
UserId: rod.UserId,
UserRole: rod.UserRole,
Title: "",
CoinTotalAmount: coinTotal,
ExpressTotalFee: orderSplit.FreightFee,
GoodsTotalAmount: goodsTotalAmount,
GoodsTotalCommission: goodsTotalCommission,
ActualTotalAmount: actualAmount,
Channel: rod.Channel,
ShippingMethod: rod.ShippingMethod,
StoreId: rod.StoreId,
BuyerMessage: rod.BuyerMessage,
Status: 1,
ExpressStatus: rod.ExpressStatus,
InvoiceStatus: rod.InvoiceStatus,
CreatedAt: rod.CreatedAt,
ExpireTime: rod.ExpireTime,
PayIP: rod.PayIP,
TradeNo: rod.TradeNo,
PayTime: rod.PayTime,
PayMethod: rod.PayMethod,
RbacId: rod.RbacId,
IsFirst: rod.IsFirst,
VirtualID: rod.VirtualID,
PayType: rod.PayType,
Kind: rod.Kind,
ThirdPartyType: rod.ThirdPartyType,
ThirdPartyOrderSn: fmt.Sprintf("%d", orderSplit.OrderSn),
OrderType: rod.OrderType,
}
var orderAddr manage2.RecookOrderAddrModel
tx.First(&orderAddr, "order_id = ?", rod.Id)
if err := tx.Create(&orderNew).Error; err != nil {
log.Println(err.Error())
return err
}
orderAddr.Id = 0
orderAddr.OrderId = orderNew.Id
if err := tx.Create(&orderAddr).Error; err != nil {
log.Println(err.Error())
return err
}
cost := decimal.Zero
total := decimal.Zero
for _, v := range orderSku {
cost = cost.Add(v.PurchasePrice).Mul(decimal.NewFromInt(int64(v.Quantity)))
total = total.Add(v.GoodsAmount)
v.Id = 0
v.OrderId = orderNew.Id
v.ExpressFee = unitMap[v.SkuId]
//v.CoinAmount = decimal.Zero
v.ActualAmount = v.GoodsAmount.Add(v.ExpressFee).Sub(v.CoinAmount)
//coinTotal = decimal.Zero
orderSkuNew = append(orderSkuNew, v)
}
//orderNew.CoinTotalAmount = coinTotal
if err := tx.Save(orderNew).Error; err != nil {
log.Println(err.Error())
return err
}
if err := tx.Create(orderSkuNew).Error; err != nil {
log.Println(err.Error())
return err
}
var rp []order4.Profit
if err := tx.Table((&order4.Profit{}).TableName()).Find(&rp, "order_id = ?", rod.Id).Error; err != nil {
return err
}
profitNew := make([]*order4.Profit, 0)
b2 := decimal.Zero
for _, k := range orderSkuNew {
b2 = b2.Add(k.GetBase().Mul(decimal.NewFromInt(int64(k.Quantity))))
}
for _, v := range rp {
temp := order4.CreateProfit(v.UserID, v.Type, b2, orderNew.Id)
profitNew = append(profitNew, temp)
}
if len(profitNew) != 0 {
if err := tx.Create(profitNew).Error; err != nil {
log.Println(err.Error())
return err
}
}
return nil
})
}

@ -171,6 +171,8 @@ type RecookOrderInfoModel struct {
OrderSku []RecookOrderGoodsDetailModel `json:"-" gorm:"foreignKey:order_id"`
After []after.RecookAfterSalesGoodsModel `json:"-" gorm:"foreignKey:order_id"`
OrderType uint `json:"-"`
ThirdPartyType uint // 第三方类型
ThirdPartyOrderSn string // 第三方订单编号
User user.Information `json:"-" gorm:"foreignKey:user_id"`
}

Loading…
Cancel
Save