package controller import ( "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" "github.com/astaxie/beego/orm" ) const ( OrderStatusEvent = -1 OrderStatusUnknown = 0 OrderStatusNew = 5 // 新定单 OrderStatusAccepted = 10 // 已经接单,也即待出库,待拣货 OrderStatusFinishedPickup = 15 // 拣货完成 OrderStatusDelivering = 20 // 开始配送,配送员已取货,从这里开始就是运单消息了 OrderStatusDelivered = 105 // 妥投 OrderStatusFinished = 110 // 定单已完成 OrderStatusCanceled = 115 // 定单已取消 OrderStatusFailed = 120 // 定单已失败 ) const ( LockStatusUnlocked = 0 LockStatusLocked = 1 ) type PurchasePlatformHandler interface { AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool) } var ( OrderMap SyncMapWithTimeout ) func init() { RoutinePool = routinepool.New(1000, 1000) } type OrderController struct { } func (c *OrderController) OnOrderNew(purchasePlatform PurchasePlatformHandler, 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 } }) err = c.updateOrderOtherInfo(order, db) if err == nil { err = c.updateOrderSkuOtherInfo(orderSkus, db) if err == nil { db.Begin() // globals.SugarLogger.Debugf("new order:%v", order) created, _, err2 := db.ReadOrCreate(order, "VendorOrderID", "VendorID") err = err2 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 += ",(?, ?, ?, ?, ?, ?, ?, ?, ?)" } 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 { db.Commit() } } else { db.Rollback() baseapi.SugarLogger.Warnf("duplicated order:%v msg received", order) } } 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) { db := orm.NewOrm() 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(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) } // 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(msg *model.OrderStatus) (err error) { order := &model.GoodsOrder{ VendorOrderID: msg.VendorOrderID, VendorID: msg.VendorID, } 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 utils.CallFuncLogError(func() error { columns := []string{"Status"} if msg.Status >= OrderStatusDelivered { order.OrderFinishedAt = msg.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 err }