- big big refactor.

This commit is contained in:
gazebo
2018-07-12 14:41:40 +08:00
parent ac2d4214e5
commit 6386f1b6f5
18 changed files with 687 additions and 644 deletions

View File

@@ -1,9 +1,10 @@
package controller
import (
"fmt"
"git.rosy.net.cn/baseapi"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/baseapi/utils/routinepool"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/jx-callback/legacy/models"
@@ -11,15 +12,19 @@ import (
)
const (
OrderStatusEvent = -1
OrderStatusApplyUrgeOrder = -15
OrderStatusApplyRefund = -10
OrderStatusApplyCancel = -5
OrderStatusUnknown = 0
OrderStatusNew = 5 // 新定单
OrderStatusAdjust = 8 // 定单调整
OrderStatusAccepted = 10 // 已经接单,也即待出库,待拣货
OrderStatusFinishedPickup = 15 // 拣货完成
OrderStatusDelivering = 20 // 开始配送,配送员已取货,从这里开始就是运单消息了
OrderStatusEndBegin = 100 // 以上的状态就是结束状态
OrderStatusDelivered = 105 // 妥投
OrderStatusFinished = 110 // 定单已完成
OrderStatusCanceled = 115 // 定单已取消
@@ -35,143 +40,127 @@ type PurchasePlatformHandler interface {
AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool)
}
var (
OrderMap SyncMapWithTimeout
)
func init() {
RoutinePool = routinepool.New(1000, 1000)
type DeliveryPlatformHandler interface {
DeliveryProvider
}
type OrderController struct {
orderMap SyncMapWithTimeout
purchasePlatformHandlers map[int]PurchasePlatformHandler
deliveryPlatformHandlers map[int]DeliveryPlatformHandler
}
func (c *OrderController) OnOrderNew(purchasePlatform PurchasePlatformHandler, order *model.GoodsOrder, orderSkus []*model.OrderSku) (err error) {
func NewOrderManager() *OrderController {
return &OrderController{
purchasePlatformHandlers: make(map[int]PurchasePlatformHandler),
deliveryPlatformHandlers: make(map[int]DeliveryPlatformHandler),
}
}
func (c *OrderController) RegisterPurchasePlatform(vendorID int, handler PurchasePlatformHandler) {
if !(vendorID >= VendorIDPurchaseBegin && vendorID <= VendorIDPurchaseEnd) {
panic(fmt.Sprintf("purchase vendor:%d is illegal", vendorID))
}
if _, ok := c.purchasePlatformHandlers[vendorID]; ok {
panic(fmt.Sprintf("purchase vendor:%d, already exists", vendorID))
}
c.purchasePlatformHandlers[vendorID] = handler
}
func (c *OrderController) RegisterDeliveryPlatform(vendorID int, handler DeliveryPlatformHandler) {
if !(vendorID >= VendorIDDeliveryBegin && vendorID <= VendorIDDeliveryEnd) {
panic(fmt.Sprintf("delivery vendor:%d is illegal", vendorID))
}
if _, ok := c.deliveryPlatformHandlers[vendorID]; ok {
panic(fmt.Sprintf("delivery vendor:%d, already exists", vendorID))
}
c.deliveryPlatformHandlers[vendorID] = handler
}
func (c *OrderController) OnOrderNew(order *model.GoodsOrder, orderSkus []*model.OrderSku) (err error) {
db := orm.NewOrm()
c.handleAutoAcceptOrder(order.VendorOrderID, order.VendorID, order.ConsigneeMobile, order.StoreID, db, func(isAccept bool) {
// purchasePlatform.AcceptOrRefuseOrder(order, isAccept)
if isAccept {
order.Status = OrderStatusAccepted
} else {
order.Status = OrderStatusFailed
}
})
order.Status = OrderStatusNew
isDuplicated, err := addOrderOrWaybillStatus(c.order2Status(order), db)
if !isDuplicated {
c.handleAutoAcceptOrder(order.VendorOrderID, order.VendorID, order.ConsigneeMobile, order.StoreID, db, func(isAccept bool) {
// c.purchasePlatformHandlers[order.VendorID].AcceptOrRefuseOrder(order, isAccept)
if isAccept {
order.Status = OrderStatusAccepted
} else {
order.Status = OrderStatusFailed
}
})
err = c.updateOrderOtherInfo(order, db)
if err == nil {
err = c.updateOrderSkuOtherInfo(orderSkus, db)
err = c.updateOrderOtherInfo(order, db)
if err == nil {
db.Begin()
// globals.SugarLogger.Debugf("new order:%v", order)
created, _, err2 := db.ReadOrCreate(order, "VendorOrderID", "VendorID")
err = err2
err = c.updateOrderSkuOtherInfo(orderSkus, db)
if err == nil {
OrderMap.Store(ComposeUniversalOrderID(order.VendorOrderID, order.VendorID), order.ID)
if created {
sql := ""
params := []interface{}{}
for _, sku := range orderSkus {
if sql == "" {
sql = "INSERT INTO order_sku(vendor_order_id, vendor_id, count, sku_id, vendor_sku_id, sku_name, shop_price, sale_price, order_created_at) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)"
} else {
sql += ",(?, ?, ?, ?, ?, ?, ?, ?, ?)"
db.Begin()
// globals.SugarLogger.Debugf("new order:%v", order)
order.OrderFinishedAt = DefaultTimeValue
order.ID = 0
created, _, err2 := db.ReadOrCreate(order, "VendorOrderID", "VendorID")
err = err2
if err == nil {
c.orderMap.Store(ComposeUniversalOrderID(order.VendorOrderID, order.VendorID), order.ID)
if created {
sql := "INSERT INTO order_sku(vendor_order_id, vendor_id, count, sku_id, vendor_sku_id, sku_name, shop_price, sale_price, weight, order_created_at) VALUES"
params := []interface{}{}
for _, sku := range orderSkus {
sql += "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?),"
params = append(params, sku.VendorOrderID, sku.VendorID, sku.Count, sku.SkuID, sku.VendorSkuID, sku.SkuName, sku.ShopPrice, sku.SalePrice, order.Weight, order.OrderCreatedAt)
}
sql = sql[:len(sql)-1] + ";"
_, err = db.Raw(sql, params...).Exec()
if err != nil {
db.Rollback()
baseapi.SugarLogger.Infof("insert order_sku error:%v", err)
} else {
db.Commit()
}
params = append(params, sku.VendorOrderID, sku.VendorID, sku.Count, sku.SkuID, sku.VendorSkuID, sku.SkuName, sku.ShopPrice, sku.SalePrice, order.OrderCreatedAt)
}
sql += ";"
_, err = db.Raw(sql, params...).Exec()
if err != nil {
db.Rollback()
baseapi.SugarLogger.Infof("insert order_sku error:%v", err)
} else {
order.DuplicatedCount++
db.Update(order, "DuplicatedCount")
db.Commit()
baseapi.SugarLogger.Infof("duplicated order:%s vendorID:%d, msg received", order.VendorOrderID, order.VendorID)
}
} else {
db.Rollback()
baseapi.SugarLogger.Warnf("duplicated order:%v msg received", order)
globals.SugarLogger.Warnf("create order:%v, error:%v", order, err)
}
} else {
db.Rollback()
globals.SugarLogger.Warnf("create order:%v, error:%v", order, err)
}
}
}
return err
}
func (c *OrderController) OnOrderAdjust(purchasePlatform PurchasePlatformHandler, order *model.GoodsOrder, orderSkus []*model.OrderSku) (err error) {
func (c *OrderController) OnOrderAdjust(order *model.GoodsOrder, orderSkus []*model.OrderSku) (err error) {
db := orm.NewOrm()
order.Status = OrderStatusAdjust
if isDuplicated, err := addOrderOrWaybillStatus(c.order2Status(order), db); err == nil && !isDuplicated {
err = utils.CallFuncLogError(func() error {
_, err := db.Raw("DELETE FROM order_sku WHERE vendor_order_id = ? AND vendor_id = ?", order.VendorOrderID, order.VendorID).Exec()
return err
}, "OnAdjustOrder delete order")
if err != nil {
return err
}
err = utils.CallFuncLogError(func() error {
_, err := db.Raw("DELETE FROM order_sku WHERE vendor_order_id = ? AND vendor_id = ?", order.VendorOrderID, order.VendorID).Exec()
return err
}, "OnAdjustOrder delete order")
if err != nil {
return err
err = utils.CallFuncLogError(func() error {
_, err := db.Raw("DELETE FROM goods_order WHERE vendor_order_id = ? AND vendor_id = ?", order.VendorOrderID, order.VendorID).Exec()
return err
}, "OnAdjustOrder delete order_sku")
if err != nil {
return err
}
}
return c.OnOrderNew(order, orderSkus)
}
err = utils.CallFuncLogError(func() error {
_, err := db.Raw("DELETE FROM goods_order WHERE vendor_order_id = ? AND vendor_id = ?", order.VendorOrderID, order.VendorID).Exec()
return err
}, "OnAdjustOrder delete order_sku")
if err != nil {
return err
func (c *OrderController) OnOrderStatusChanged(orderStatus *model.OrderStatus) (err error) {
if isDuplicated, err := c.addOrderStatus(orderStatus, nil); err == nil && !isDuplicated {
}
return c.OnOrderNew(purchasePlatform, order, orderSkus)
}
func (c *OrderController) OnOrderAccepted(purchasePlatform PurchasePlatformHandler, msg *model.OrderStatus) (err error) {
msg.Status = OrderStatusAccepted
return c.addOrderStatus(msg)
}
func (c *OrderController) OnOrderFinishedPickup(purchasePlatform PurchasePlatformHandler, msg *model.OrderStatus) (err error) {
msg.Status = OrderStatusFinishedPickup
return c.addOrderStatus(msg)
}
func (c *OrderController) OnOrderDelivering(purchasePlatform PurchasePlatformHandler, msg *model.OrderStatus) (err error) {
msg.Status = OrderStatusDelivering
return c.addOrderStatus(msg)
}
func (c *OrderController) OnOrderDelivered(purchasePlatform PurchasePlatformHandler, msg *model.OrderStatus) (err error) {
msg.Status = OrderStatusDelivered
return c.addOrderStatus(msg)
}
func (c *OrderController) OnOrderCanceled(purchasePlatform PurchasePlatformHandler, msg *model.OrderStatus) (err error) {
msg.Status = OrderStatusFailed
return c.addOrderStatus(msg)
}
func (c *OrderController) OnOrderFailed(purchasePlatform PurchasePlatformHandler, msg *model.OrderStatus) (err error) {
msg.Status = OrderStatusFailed
return c.addOrderStatus(msg)
}
//
func (c *OrderController) OnOrderUserApplyCancel(purchasePlatform PurchasePlatformHandler, msg *model.OrderStatus) (err error) {
msg.Status = OrderStatusEvent
return c.addOrderStatus(msg)
}
func (c *OrderController) OnOrderUserApplyRefund(purchasePlatform PurchasePlatformHandler, msg *model.OrderStatus) (err error) {
msg.Status = OrderStatusEvent
return c.addOrderStatus(msg)
}
func (c *OrderController) OnOrderUserUrgeOrder(purchasePlatform PurchasePlatformHandler, msg *model.OrderStatus) (err error) {
msg.Status = OrderStatusEvent
return c.addOrderStatus(msg)
}
//
func (c *OrderController) OnOrderOtherStatus(purchasePlatform PurchasePlatformHandler, msg *model.OrderStatus) (err error) {
msg.Status = OrderStatusEvent
return c.addOrderStatus(msg)
return err
}
// private
@@ -213,41 +202,83 @@ func (c *OrderController) handleAutoAcceptOrder(orderID string, vendorID int, us
} else if handleType == -1 {
handler(false)
}
return handleType
}
func (c *OrderController) addOrderStatus(msg *model.OrderStatus) (err error) {
order := &model.GoodsOrder{
VendorOrderID: msg.VendorOrderID,
VendorID: msg.VendorID,
func (c *OrderController) addOrderStatus(orderStatus *model.OrderStatus, db orm.Ormer) (isDuplicated bool, err error) {
if db == nil {
db = orm.NewOrm()
}
db := orm.NewOrm()
value, ok := OrderMap.Load(ComposeUniversalOrderID(msg.VendorOrderID, msg.VendorID))
if !ok {
// globals.SugarLogger.Infof("can not get order:%v, from cache", order)
err = db.Read(order, "VendorOrderID", "VendorID")
} else {
order.ID = value.(int64)
}
if err == nil {
if msg.Status != OrderStatusEvent {
order.Status = msg.Status
isDuplicated, err = addOrderOrWaybillStatus(orderStatus, db)
if !isDuplicated && orderStatus.Status > OrderStatusUnknown {
order := &model.GoodsOrder{
VendorOrderID: orderStatus.VendorOrderID,
VendorID: orderStatus.VendorID,
}
if err = c.updateOrderPKID(order, db); err == nil {
order.Status = orderStatus.Status
order.VendorStatus = orderStatus.VendorStatus
utils.CallFuncLogError(func() error {
columns := []string{"Status"}
if msg.Status >= OrderStatusDelivered {
order.OrderFinishedAt = msg.StatusTime
columns := []string{"Status", "VendorStatus"}
if orderStatus.Status >= OrderStatusDelivered {
order.OrderFinishedAt = orderStatus.StatusTime
columns = append(columns, "OrderFinishedAt")
}
_, err := db.Update(order, columns...)
return err
}, "update order")
}
utils.CallFuncLogError(func() error {
_, err := db.Insert(msg)
return err
}, "insert status")
}
return isDuplicated, err
}
func (c *OrderController) updateOrderPKID(order *model.GoodsOrder, db orm.Ormer) (err error) {
value, ok := c.orderMap.Load(ComposeUniversalOrderID(order.VendorOrderID, order.VendorID))
if !ok {
err = db.Read(order, "VendorOrderID", "VendorID")
// todo 这里应该要报警,但测试阶段先去掉
// utils.CallFuncLogError(func() error {
// err = db.Read(order, "VendorOrderID", "VendorID")
// return err
// }, "can not get order info from db")
} else {
order.ID = value.(int64)
}
return err
}
func (c *OrderController) order2Status(order *model.GoodsOrder) (retVal *model.OrderStatus) {
retVal = &model.OrderStatus{
VendorOrderID: order.VendorOrderID,
VendorID: order.VendorID,
OrderType: OrderTypeOrder,
Status: order.Status,
VendorStatus: order.VendorStatus,
StatusTime: order.OrderCreatedAt,
}
return retVal
}
//Waybill
func (c *OrderController) OnWaybillStatusChanged(bill *model.Waybill, db orm.Ormer) (err error) {
return c.updateOrderByWaybill(bill, db)
}
func (c *OrderController) updateOrderByWaybill(bill *model.Waybill, db orm.Ormer) (err error) {
if db == nil {
db = orm.NewOrm()
}
order := &model.GoodsOrder{
VendorOrderID: bill.VendorOrderID,
VendorID: bill.OrderVendorID,
}
if err = db.Read(order, "VendorOrderID", "VendorID"); err == nil {
if order.Status < OrderStatusEndBegin {
order.WaybillStatus = bill.Status
order.WaybillVendorStatus = bill.VendorStatus
db.Update(order, "WaybillStatus", "WaybillVendorStatus")
}
}
return err
}