220 lines
7.1 KiB
Go
220 lines
7.1 KiB
Go
package controller
|
||
|
||
import (
|
||
"git.rosy.net.cn/baseapi"
|
||
"git.rosy.net.cn/baseapi/utils"
|
||
"git.rosy.net.cn/jx-callback/business/model"
|
||
"git.rosy.net.cn/jx-callback/globals"
|
||
"git.rosy.net.cn/jx-callback/legacy/models"
|
||
"github.com/astaxie/beego/orm"
|
||
)
|
||
|
||
// 所有公共接口调用前,要求在order里或status中设置合适的Status
|
||
type OrderController struct {
|
||
orderMap SyncMapWithTimeout
|
||
}
|
||
|
||
func NewOrderManager() *OrderController {
|
||
return &OrderController{}
|
||
}
|
||
|
||
func (c *OrderController) OnOrderNew(order *model.GoodsOrder, orderSkus []*model.OrderSku) (err error) {
|
||
db := orm.NewOrm()
|
||
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 = model.OrderStatusAccepted
|
||
} else {
|
||
order.Status = model.OrderStatusFailed
|
||
}
|
||
})
|
||
if err = c.updateOrderOtherInfo(order, db); err == nil {
|
||
if err = c.updateOrderSkuOtherInfo(orderSkus, db); err == nil {
|
||
db.Begin()
|
||
// globals.SugarLogger.Debugf("new order:%v", order)
|
||
order.OrderFinishedAt = DefaultTimeValue
|
||
order.ID = 0
|
||
created, _, err2 := db.ReadOrCreate(order, "VendorOrderID", "VendorID")
|
||
if err = err2; 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] + ";"
|
||
if _, err = db.Raw(sql, params...).Exec(); err != nil {
|
||
db.Rollback()
|
||
baseapi.SugarLogger.Infof("insert order_sku error:%v", err)
|
||
} else {
|
||
db.Commit()
|
||
}
|
||
} 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()
|
||
globals.SugarLogger.Warnf("create order:%v, error:%v", order, err)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return err
|
||
}
|
||
|
||
func (c *OrderController) OnOrderAdjust(order *model.GoodsOrder, orderSkus []*model.OrderSku) (err error) {
|
||
db := orm.NewOrm()
|
||
isDuplicated, err := addOrderOrWaybillStatus(c.order2Status(order), db)
|
||
if 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 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)
|
||
}
|
||
|
||
func (c *OrderController) OnOrderStatusChanged(orderStatus *model.OrderStatus) (err error) {
|
||
isDuplicated, err := c.addOrderStatus(orderStatus, nil)
|
||
if err == nil && !isDuplicated {
|
||
}
|
||
return err
|
||
}
|
||
|
||
// private
|
||
func (c *OrderController) updateOrderSkuOtherInfo(orderSkus []*model.OrderSku, db orm.Ormer) (err error) {
|
||
return nil
|
||
}
|
||
|
||
func (c *OrderController) updateOrderOtherInfo(order *model.GoodsOrder, db orm.Ormer) (err error) {
|
||
return nil
|
||
}
|
||
|
||
func (c *OrderController) handleAutoAcceptOrder(orderID string, vendorID int, userMobile string, jxStoreID int, db orm.Ormer, handler func(accepted bool)) int {
|
||
handleType := 0
|
||
if userMobile != "" {
|
||
if db == nil {
|
||
db = orm.NewOrm()
|
||
}
|
||
user := &models.BlackClient{
|
||
Mobile: userMobile,
|
||
}
|
||
if err := db.Read(user, "Mobile"); err != nil {
|
||
if err != orm.ErrNoRows {
|
||
globals.SugarLogger.Errorf("read data error:%v, data:%v, vendorID:%d", err, user, vendorID)
|
||
}
|
||
// 在访问数据库出错的情况下,也需要自动接单
|
||
handleType = 1
|
||
} else {
|
||
// 强制拒单
|
||
globals.SugarLogger.Infof("force reject order:%s, vendorID:%d", orderID, vendorID)
|
||
handleType = -1
|
||
}
|
||
} else {
|
||
globals.SugarLogger.Infof("order:%s, vendorID:%d, mobile is empty, should accept it", orderID, vendorID)
|
||
handleType = 1
|
||
}
|
||
|
||
if handleType == 1 {
|
||
handler(true)
|
||
} else if handleType == -1 {
|
||
handler(false)
|
||
}
|
||
return handleType
|
||
}
|
||
|
||
func (c *OrderController) addOrderStatus(orderStatus *model.OrderStatus, db orm.Ormer) (isDuplicated bool, err error) {
|
||
if db == nil {
|
||
db = orm.NewOrm()
|
||
}
|
||
isDuplicated, err = addOrderOrWaybillStatus(orderStatus, db)
|
||
if !isDuplicated && orderStatus.Status > model.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", "VendorStatus"}
|
||
if orderStatus.Status >= model.OrderStatusEndBegin {
|
||
order.OrderFinishedAt = orderStatus.StatusTime
|
||
columns = append(columns, "OrderFinishedAt")
|
||
}
|
||
_, err := db.Update(order, columns...)
|
||
return err
|
||
}, "update order")
|
||
}
|
||
}
|
||
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: model.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 < model.OrderStatusEndBegin {
|
||
order.WaybillStatus = bill.Status
|
||
order.WaybillVendorStatus = bill.VendorStatus
|
||
db.Update(order, "WaybillStatus", "WaybillVendorStatus")
|
||
}
|
||
}
|
||
return err
|
||
}
|