diff --git a/business/controller/controller.go b/business/controller/controller.go index 1d26c2127..fcf3f6c9d 100644 --- a/business/controller/controller.go +++ b/business/controller/controller.go @@ -6,19 +6,27 @@ import ( "sync" "time" + "github.com/astaxie/beego/orm" + + "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/baseapi/utils/routinepool" "git.rosy.net.cn/jx-callback/globals" ) const ( - VenderIDUnknown = -1 - VendorIDJD = 0 - VendorIDMTWM = 1 - VendorIDELM = 2 + VenderIDUnknown = -1 + VendorIDPurchaseBegin = 0 + VendorIDJD = 0 + VendorIDMTWM = 1 + VendorIDELM = 2 + VendorIDPurchaseEnd = 2 - VendorIDDada = 101 - VendorIDMTPS = 102 + VendorIDDeliveryBegin = 101 + VendorIDDada = 101 + VendorIDMTPS = 102 + VendorIDDeliveryEnd = 102 ) const ( @@ -26,18 +34,33 @@ const ( OrderTypeWaybill = 2 ) +const ( + CoordinateTypeMars = 0 // 火星坐标 + CoordinateTypeReal = 1 // 真实坐标 +) + const ( DefaultOrderCacheTimeout = 24 * time.Hour ) var ( - RoutinePool *routinepool.Pool + DefaultTimeValue = utils.Str2Time("1970-01-01 00:00:00") + OrderManager *OrderController + WaybillManager *WaybillController + + routinePool *routinepool.Pool ) type SyncMapWithTimeout struct { sync.Map } +func init() { + routinePool = routinepool.New(1000, 1000) + OrderManager = NewOrderManager() + WaybillManager = NewWaybillManager() +} + func (m *SyncMapWithTimeout) StoreWithTimeout(key, value interface{}, timeout time.Duration) { m.Map.Store(key, value) time.AfterFunc(timeout, func() { @@ -49,26 +72,61 @@ func (m *SyncMapWithTimeout) Store(key, value interface{}) { m.StoreWithTimeout(key, value, DefaultOrderCacheTimeout) } -func GetVendorIDFromUniversalOrderID(orderID string) (vendorID int) { - index := strings.Index(orderID, "|") +func SplitUniversalOrderID(universalOrderID string) (orderID string, vendorID int) { + index := strings.Index(universalOrderID, "|") if index != -1 { - vendorID = int(utils.Str2Int64(orderID[index:])) + orderID = universalOrderID[:index] + vendorID = int(utils.Str2Int64(universalOrderID[index:])) } else { // 800402581000221 jd order // 3022716176275221584 elm order - orderIDLen := len(orderID) + orderIDLen := len(universalOrderID) if orderIDLen == len("800402581000221") { vendorID = VendorIDJD } else if orderIDLen == len("3022716176275221584") { vendorID = VendorIDELM } else { - globals.SugarLogger.Errorf("unkown order type:%v", orderID) + globals.SugarLogger.Errorf("unkown order type:%v", universalOrderID) vendorID = VenderIDUnknown } + orderID = universalOrderID } - return vendorID + return orderID, vendorID } func ComposeUniversalOrderID(orderID string, vendorID int) string { return fmt.Sprintf("%s|%d", orderID, vendorID) } + +func StandardCoordinate2Int(value float64) int { + return int(value * 1000000) +} + +func IntCoordinate2Standard(value int) float64 { + return float64(value / 1000000) +} + +func addOrderOrWaybillStatus(status *model.OrderStatus, db orm.Ormer) (isDuplicated bool, err error) { + status.ID = 0 + created, _, err := db.ReadOrCreate(status, "VendorOrderID", "VendorID", "OrderType", "VendorStatus", "StatusTime") + if err == nil { + if !created { + isDuplicated = true + status.DuplicatedCount++ + _, err = db.Update(status, "DuplicatedCount") + globals.SugarLogger.Infof("duplicated event:%v", status) + } + } + if err != nil { + // todo 这里居然会有主键重复错误,逻辑上是不应该的 + globals.SugarLogger.Warnf("access db error:%v", err) + } + return isDuplicated, err +} + +func CallMsgHandler(handler func(), primaryID string) { + handler() + // controller.routinePool.CallFun(func() { + // handler() + // }, primaryID) +} diff --git a/business/controller/dada/waybill.go b/business/controller/dada/waybill.go index e3b110c70..310d586fa 100644 --- a/business/controller/dada/waybill.go +++ b/business/controller/dada/waybill.go @@ -8,80 +8,49 @@ import ( ) type WaybillController struct { - controller.WaybillController +} + +func init() { + controller.OrderManager.RegisterDeliveryPlatform(controller.VendorIDDada, new(WaybillController)) } func (c *WaybillController) OnWaybillMsg(msg *dadaapi.CallbackMsg) (retVal *dadaapi.CallbackResponse) { - controller.RoutinePool.CallFun(func() { + controller.CallMsgHandler(func() { retVal = c.onWaybillMsg(msg) }, msg.OrderID) return retVal } -func (c *WaybillController) callbackMsg2Status(msg *dadaapi.CallbackMsg) *model.OrderStatus { - orderStatus := &model.OrderStatus{ - VendorOrderID: msg.ClientID, - VendorID: controller.VendorIDDada, - OrderType: controller.OrderTypeWaybill, - VendorStatus: utils.Int2Str(msg.OrderStatus), - StatusTime: utils.Timestamp2Time(int64(msg.UpdateTime)), - } - return orderStatus -} - func (c *WaybillController) onWaybillMsg(msg *dadaapi.CallbackMsg) (retVal *dadaapi.CallbackResponse) { + order := c.callbackMsg2Waybill(msg) switch msg.OrderStatus { case dadaapi.OrderStatusWaitingForAccept: - retVal = c.onWaybillNew(msg) + order.Status = controller.WaybillStatusNew case dadaapi.OrderStatusAccepted: - retVal = c.onWaybillAccepted(msg) + order.Status = controller.WaybillStatusAccepted case dadaapi.OrderStatusDeliverying: - retVal = c.onWaybillDelivering(msg) + order.Status = controller.WaybillStatusDelivering case dadaapi.OrderStatusFinished: - retVal = c.onWaybillDelivered(msg) + order.Status = controller.WaybillStatusDelivered case dadaapi.OrderStatusCanceled: - retVal = c.onWaybillCanceled(msg) + order.Status = controller.WaybillStatusCanceled case dadaapi.OrderStatusExpired, dadaapi.OrderStatusAddOrderFailed: - retVal = c.onWaybillFailed(msg) + order.Status = controller.WaybillStatusFailed default: - retVal = c.onWaybillOtherStatus(msg) + order.Status = controller.WaybillStatusUnknown } - return retVal + return dadaapi.Err2CallbackResponse(controller.WaybillManager.OnWaybillStatusChanged(order), utils.Int2Str(order.Status)) } -func (c *WaybillController) onWaybillNew(msg *dadaapi.CallbackMsg) (retVal *dadaapi.CallbackResponse) { - order := &model.Waybill{ - VendorOrderID: msg.OrderID, - VendorID: controller.GetVendorIDFromUniversalOrderID(msg.OrderID), +func (c *WaybillController) callbackMsg2Waybill(msg *dadaapi.CallbackMsg) (retVal *model.Waybill) { + retVal = &model.Waybill{ VendorWaybillID: msg.ClientID, WaybillVendorID: controller.VendorIDDada, CourierName: msg.DmName, CourierMobile: msg.DmMobile, + VendorStatus: utils.Int2Str(msg.OrderStatus), WaybillCreatedAt: utils.Timestamp2Time(int64(msg.UpdateTime)), } - return dadaapi.Err2CallbackResponse(c.OnWaybillNew(order), "dada onWaybillNew") -} - -func (c *WaybillController) onWaybillAccepted(msg *dadaapi.CallbackMsg) (retVal *dadaapi.CallbackResponse) { - return dadaapi.Err2CallbackResponse(c.OnWaybillAccepted(c.callbackMsg2Status(msg)), "dada onWaybillAccepted") -} - -func (c *WaybillController) onWaybillDelivering(msg *dadaapi.CallbackMsg) (retVal *dadaapi.CallbackResponse) { - return dadaapi.Err2CallbackResponse(c.OnWaybillDelivering(c.callbackMsg2Status(msg)), "dada onWaybillDelivering") -} - -func (c *WaybillController) onWaybillDelivered(msg *dadaapi.CallbackMsg) (retVal *dadaapi.CallbackResponse) { - return dadaapi.Err2CallbackResponse(c.OnWaybillDelivered(c.callbackMsg2Status(msg)), "dada onWaybillDelivered") -} - -func (c *WaybillController) onWaybillCanceled(msg *dadaapi.CallbackMsg) (retVal *dadaapi.CallbackResponse) { - return dadaapi.Err2CallbackResponse(c.OnWaybillCanceled(c.callbackMsg2Status(msg)), "dada onWaybillCanceled") -} - -func (c *WaybillController) onWaybillFailed(msg *dadaapi.CallbackMsg) (retVal *dadaapi.CallbackResponse) { - return dadaapi.Err2CallbackResponse(c.OnWaybillFailed(c.callbackMsg2Status(msg)), "dada onWaybillFailed") -} - -func (c *WaybillController) onWaybillOtherStatus(msg *dadaapi.CallbackMsg) (retVal *dadaapi.CallbackResponse) { - return dadaapi.Err2CallbackResponse(c.OnWaybillOtherStatus(c.callbackMsg2Status(msg)), "dada onWaybillOtherStatus") + retVal.VendorOrderID, retVal.OrderVendorID = controller.SplitUniversalOrderID(msg.OrderID) + return retVal } diff --git a/business/controller/elm/elm.go b/business/controller/elm/elm.go index 9ef840e40..62d30f4a0 100644 --- a/business/controller/elm/elm.go +++ b/business/controller/elm/elm.go @@ -44,7 +44,7 @@ func (c *Controller) OnCallbackMsg(msg *elmapi.CallbackMsg) (retVal *elmapi.Call retVal = elmapi.Err2CallbackResponse(err, "") } else { innerMsg.MsgType = msg.Type - controller.RoutinePool.CallFun(func() { + controller.CallMsgHandler(func() { retVal = new(OrderController).onOrderUserUrgeOrder(&innerMsg) }, innerMsg.OrderID) } diff --git a/business/controller/elm/order.go b/business/controller/elm/order.go index 8b1092e42..d14679c86 100644 --- a/business/controller/elm/order.go +++ b/business/controller/elm/order.go @@ -3,6 +3,7 @@ package elm import ( "fmt" "math" + "strings" "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/globals/api" @@ -14,25 +15,28 @@ import ( ) type OrderController struct { - controller.OrderController +} + +func init() { + controller.OrderManager.RegisterPurchasePlatform(controller.VendorIDJD, new(OrderController)) } func (c *OrderController) OnOrderStatusMsg(msg *elmapi.CallbackOrderStatusMsg) (retVal *elmapi.CallbackResponse) { - controller.RoutinePool.CallFun(func() { + controller.CallMsgHandler(func() { retVal = c.onOrderStatusMsg(msg) }, msg.OrderID) return retVal } func (c *OrderController) OnOrderNewMsg(msg map[string]interface{}) (retVal *elmapi.CallbackResponse) { - controller.RoutinePool.CallFun(func() { + controller.CallMsgHandler(func() { retVal = c.onOrderNew(msg) }, msg["orderId"].(string)) return retVal } func (c *OrderController) OnOrderCancelRefundMsg(msg *elmapi.CallbackOrderCancelRefundMsg) (retVal *elmapi.CallbackResponse) { - controller.RoutinePool.CallFun(func() { + controller.CallMsgHandler(func() { retVal = c.onOrderCancelRefundMsg(msg) }, msg.OrderID) return retVal @@ -43,7 +47,7 @@ func (c *OrderController) orderStatusMsg2Status(msg *elmapi.CallbackOrderStatusM VendorOrderID: msg.OrderID, VendorID: controller.VendorIDELM, OrderType: controller.OrderTypeOrder, - VendorStatus: fmt.Sprintf("%s-%d", msg.State, msg.MsgType), + VendorStatus: c.stateAndType2Str(msg.State, msg.MsgType), StatusTime: utils.Timestamp2Time(msg.UpdateTime), } return orderStatus @@ -54,7 +58,6 @@ func (c *OrderController) cancelRefundMsg2Status(msg *elmapi.CallbackOrderCancel VendorOrderID: msg.OrderID, VendorID: controller.VendorIDELM, OrderType: controller.OrderTypeOrder, - Status: controller.OrderStatusEvent, VendorStatus: utils.Int2Str(msg.MsgType), StatusTime: utils.Timestamp2Time(msg.UpdateTime), } @@ -62,34 +65,32 @@ func (c *OrderController) cancelRefundMsg2Status(msg *elmapi.CallbackOrderCancel } func (c *OrderController) onOrderStatusMsg(msg *elmapi.CallbackOrderStatusMsg) (retVal *elmapi.CallbackResponse) { + status := c.orderStatusMsg2Status(msg) switch msg.MsgType { case elmapi.MsgTypeOrderAccepted: - retVal = c.onOrderAccepted(msg) - case elmapi.MsgTypeOrderCanceled: - retVal = c.onOrderCanceled(msg) - case elmapi.MsgTypeOrderInvalid: - retVal = c.onOrderInvalid(msg) - case elmapi.MsgTypeOrderForceInvalid: - retVal = c.onOrderForceInvalid(msg) + status.Status = controller.OrderStatusAccepted + case elmapi.MsgTypeOrderCanceled, elmapi.MsgTypeOrderInvalid, elmapi.MsgTypeOrderForceInvalid: + status.Status = controller.OrderStatusCanceled case elmapi.MsgTypeOrderFinished: - retVal = c.onOrderFinished(msg) + status.Status = controller.OrderStatusFinished default: globals.SugarLogger.Warnf("elm msg:%d not handled", msg.MsgType) - retVal = elmapi.SuccessResponse + return elmapi.SuccessResponse } - return retVal + return elmapi.Err2CallbackResponse(controller.OrderManager.OnOrderStatusChanged(status), status.VendorStatus) } func (c *OrderController) onOrderCancelRefundMsg(msg *elmapi.CallbackOrderCancelRefundMsg) (retVal *elmapi.CallbackResponse) { + status := c.cancelRefundMsg2Status(msg) switch msg.MsgType { case elmapi.MsgTypeUserApplyCancel: - retVal = c.onOrderUserApplyCancel(msg) + status.Status = controller.OrderStatusApplyCancel case elmapi.MsgTypeUserApplyRefund: - retVal = c.onOrderUserApplyRefund(msg) + status.Status = controller.OrderStatusApplyRefund default: - retVal = c.onOrderOtherCancelRefundStatus(msg) + status.Status = controller.OrderStatusUnknown } - return retVal + return elmapi.Err2CallbackResponse(controller.OrderManager.OnOrderStatusChanged(status), status.VendorStatus) } func (c *OrderController) getOrderInfo(msg *elmapi.CallbackOrderStatusMsg) (order *model.GoodsOrder, orderSkus []*model.OrderSku, err error) { @@ -100,18 +101,26 @@ func (c *OrderController) getOrderInfo(msg *elmapi.CallbackOrderStatusMsg) (orde if len(phoneList) > 0 { consigneeMobile = phoneList[0].(string) } + // globals.SugarLogger.Debug(result) order = &model.GoodsOrder{ - VendorOrderID: msg.OrderID, - VendorID: controller.VendorIDELM, - VendorStoreID: utils.Int64ToStr(utils.MustInterface2Int64(result["shopId"])), - StoreID: int(utils.Str2Int64WithDefault(utils.Interface2String(result["openId"]), 0)), - StoreName: result["shopName"].(string), - ConsigneeName: result["consignee"].(string), - ConsigneeMobile: consigneeMobile, - VendorStatus: msg.State, - OrderCreatedAt: utils.Str2Time(result["createdAt"].(string)), - OriginalData: string(utils.MustMarshal(result)), + VendorOrderID: msg.OrderID, + VendorID: controller.VendorIDELM, + VendorStoreID: utils.Int64ToStr(utils.MustInterface2Int64(result["shopId"])), + StoreID: int(utils.Str2Int64WithDefault(utils.Interface2String(result["openId"]), 0)), + StoreName: result["shopName"].(string), + ConsigneeName: result["consignee"].(string), + ConsigneeMobile: consigneeMobile, + ConsigneeAddress: result["address"].(string), + VendorStatus: msg.State, + OrderCreatedAt: utils.Str2Time(result["createdAt"].(string)), + OriginalData: string(utils.MustMarshal(result)), + } + deliveryGeo := strings.Split(utils.Interface2String(result["deliveryGeo"]), ",") + if len(deliveryGeo) == 2 { + order.CoordinateType = controller.CoordinateTypeMars + order.ConsigneeLng = controller.StandardCoordinate2Int(utils.Str2Float64(deliveryGeo[0])) + order.ConsigneeLat = controller.StandardCoordinate2Int(utils.Str2Float64(deliveryGeo[1])) } orderSkus = []*model.OrderSku{} @@ -121,21 +130,23 @@ func (c *OrderController) getOrderInfo(msg *elmapi.CallbackOrderStatusMsg) (orde product := product2.(map[string]interface{}) sku := &model.OrderSku{ VendorOrderID: msg.OrderID, - VendorID: controller.VendorIDJD, + VendorID: controller.VendorIDELM, Count: int(utils.MustInterface2Int64(product["quantity"])), SkuID: int(utils.Str2Int64WithDefault(utils.Interface2String(product["extendCode"]), 0)), VendorSkuID: utils.Int64ToStr(utils.MustInterface2Int64(product["skuId"])), SkuName: product["name"].(string), SalePrice: int64(math.Round(utils.MustInterface2Float64(product["userPrice"]) * 100)), + Weight: int(math.Round(utils.Interface2Float64(product["weight"]))), OrderCreatedAt: order.OrderCreatedAt, } orderSkus = append(orderSkus, sku) order.SkuCount++ + order.GoodsCount += sku.Count order.SalePrice += sku.SalePrice + order.Weight += sku.Weight } } } - return order, orderSkus, err } @@ -144,63 +155,25 @@ func (c *OrderController) onOrderNew(msg map[string]interface{}) (response *elma // todo 这里应该可以直接用msg里的内容,而不用再次去查 fakeOrderMsg := &elmapi.CallbackOrderStatusMsg{ OrderID: msg["orderId"].(string), - State: elmapi.OrderStatusFake, + State: c.stateAndType2Str(msg["status"].(string), elmapi.MsgTypeOrderValid), } order, orderSkus, err := c.getOrderInfo(fakeOrderMsg) if err == nil { - err = c.OnOrderNew(c, order, orderSkus) + err = controller.OrderManager.OnOrderNew(order, orderSkus) } return elmapi.Err2CallbackResponse(err, "elm onOrderNew") } -func (c *OrderController) onOrderAccepted(msg *elmapi.CallbackOrderStatusMsg) *elmapi.CallbackResponse { - status := c.orderStatusMsg2Status(msg) - err := c.OnOrderAccepted(c, status) - if err == nil { - status.VendorStatus = "fakeautopickup" - err = c.OnOrderFinishedPickup(c, c.orderStatusMsg2Status(msg)) - } - return elmapi.Err2CallbackResponse(err, "elm onOrderAccepted") -} - -func (c *OrderController) onOrderCanceled(msg *elmapi.CallbackOrderStatusMsg) *elmapi.CallbackResponse { - return elmapi.Err2CallbackResponse(c.OnOrderCanceled(c, c.orderStatusMsg2Status(msg)), "elm onOrderCanceled") -} - -func (c *OrderController) onOrderInvalid(msg *elmapi.CallbackOrderStatusMsg) *elmapi.CallbackResponse { - return c.onOrderCanceled(msg) -} - -func (c *OrderController) onOrderForceInvalid(msg *elmapi.CallbackOrderStatusMsg) *elmapi.CallbackResponse { - return c.onOrderCanceled(msg) -} - -func (c *OrderController) onOrderFinished(msg *elmapi.CallbackOrderStatusMsg) *elmapi.CallbackResponse { - return elmapi.Err2CallbackResponse(c.OnOrderDelivered(c, c.orderStatusMsg2Status(msg)), "elm onOrderFinished") -} - func (c *OrderController) onOrderUserUrgeOrder(msg *elmapi.CallbackOrderUrgeMsg) *elmapi.CallbackResponse { - orderStatus := &model.OrderStatus{ + status := &model.OrderStatus{ VendorOrderID: msg.OrderID, VendorID: controller.VendorIDELM, OrderType: controller.OrderTypeOrder, - Status: controller.OrderStatusEvent, + Status: controller.OrderStatusApplyUrgeOrder, VendorStatus: utils.Int2Str(msg.MsgType), StatusTime: utils.Timestamp2Time(msg.UpdateTime), } - return elmapi.Err2CallbackResponse(c.OnOrderUserUrgeOrder(c, orderStatus), "elm onOrderUserUrgeOrder") -} - -func (c *OrderController) onOrderUserApplyCancel(msg *elmapi.CallbackOrderCancelRefundMsg) *elmapi.CallbackResponse { - return elmapi.Err2CallbackResponse(c.OnOrderUserApplyCancel(c, c.cancelRefundMsg2Status(msg)), "elm onOrderUserApplyCancel") -} - -func (c *OrderController) onOrderUserApplyRefund(msg *elmapi.CallbackOrderCancelRefundMsg) *elmapi.CallbackResponse { - return elmapi.Err2CallbackResponse(c.OnOrderUserApplyRefund(c, c.cancelRefundMsg2Status(msg)), "elm onOrderUserApplyRefund") -} - -func (c *OrderController) onOrderOtherCancelRefundStatus(msg *elmapi.CallbackOrderCancelRefundMsg) *elmapi.CallbackResponse { - return elmapi.Err2CallbackResponse(c.OnOrderOtherStatus(c, c.cancelRefundMsg2Status(msg)), "elm onOrderOtherCancelRefundStatus") + return elmapi.Err2CallbackResponse(controller.OrderManager.OnOrderStatusChanged(status), status.VendorStatus) } // PurchasePlatformHandler @@ -211,3 +184,7 @@ func (c *OrderController) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptI api.ElmAPI.CancelOrder(order.VendorOrderID, elmapi.CancelOrderTypeOthers, "") } } + +func (c *OrderController) stateAndType2Str(state string, msgType int) string { + return fmt.Sprintf("%s-%d", state, msgType) +} diff --git a/business/controller/elm/waybill.go b/business/controller/elm/waybill.go index b1e8e3d7a..f8af05bf1 100644 --- a/business/controller/elm/waybill.go +++ b/business/controller/elm/waybill.go @@ -10,83 +10,59 @@ import ( ) type WaybillController struct { - controller.WaybillController +} + +func init() { + controller.WaybillManager.RegisterDeliveryProvider(controller.VendorIDELM, new(WaybillController)) } func (c *WaybillController) OnWaybillStatusMsg(msg *elmapi.CallbackWaybillStatusMsg) (retVal *elmapi.CallbackResponse) { - controller.RoutinePool.CallFun(func() { + controller.CallMsgHandler(func() { retVal = c.onWaybillStatusMsg(msg) }, msg.OrderID) return retVal } func (c *WaybillController) onWaybillStatusMsg(msg *elmapi.CallbackWaybillStatusMsg) (retVal *elmapi.CallbackResponse) { + order := c.callbackMsg2Waybill(msg) if msg.MsgType == elmapi.MsgTypeWaybillWait4DeliveryVendor { - retVal = c.onWaybillWait4DeliveryVendor(msg) + order.Status = controller.WaybillStatusNew } else if msg.MsgType == elmapi.MsgTypeWaybillPickingUp { - retVal = c.onWaybillPickingUp(msg) + order.Status = controller.WaybillStatusAccepted + } else if msg.MsgType == elmapi.MsgTypeWaybillCourierArrived { + order.Status = controller.WaybillStatusCourierArrived } else if msg.MsgType == elmapi.MsgTypeWaybillDelivering { - retVal = c.onWaybillDelivering(msg) + order.Status = controller.WaybillStatusDelivering } else if msg.MsgType == elmapi.MsgTypeWaybillDelivered { - retVal = c.onWaybillDelivered(msg) + order.Status = controller.WaybillStatusDelivered } else if msg.MsgType >= elmapi.MsgTypeWaybillCanceledByMerchant && msg.MsgType <= elmapi.MsgTypeWaybillCanceledBySystem { - retVal = c.onWaybillCanceled(msg) + order.Status = controller.WaybillStatusCanceled } else if msg.MsgType >= elmapi.MsgTypeWaybillFailedCallLate && msg.MsgType <= elmapi.MsgTypeRejectedSystemError && msg.MsgType != elmapi.MsgTypeDeiverBySelf { - retVal = c.onWaybillFailed(msg) + order.Status = controller.WaybillStatusFailed } else { // MsgTypeWait4Courier // MsgTypeDeiverBySelf - retVal = c.onWaybillOtherStatus(msg) + order.Status = controller.WaybillStatusUnknown } - return retVal + return elmapi.Err2CallbackResponse(controller.WaybillManager.OnWaybillStatusChanged(order), order.VendorStatus) } -func (c *WaybillController) onWaybillWait4DeliveryVendor(msg *elmapi.CallbackWaybillStatusMsg) (retVal *elmapi.CallbackResponse) { - order := &model.Waybill{ +func (c *WaybillController) callbackMsg2Waybill(msg *elmapi.CallbackWaybillStatusMsg) (retVal *model.Waybill) { + retVal = &model.Waybill{ VendorOrderID: msg.OrderID, - VendorID: controller.VendorIDELM, + OrderVendorID: controller.VendorIDELM, VendorWaybillID: msg.OrderID, WaybillVendorID: controller.VendorIDELM, CourierName: msg.Name, CourierMobile: msg.Phone, + VendorStatus: c.composeState(msg.State, msg.SubState, elmapi.MsgTypeWaybillWait4DeliveryVendor), WaybillCreatedAt: utils.Timestamp2Time(msg.UpdateAt / 1000), } - return elmapi.Err2CallbackResponse(c.OnWaybillNew(order), "elm onWaybillWait4DeliveryVendor") + return retVal } -func (c *WaybillController) onWaybillPickingUp(msg *elmapi.CallbackWaybillStatusMsg) (retVal *elmapi.CallbackResponse) { - return elmapi.Err2CallbackResponse(c.OnWaybillAccepted(c.callbackMsg2Status(msg)), "elm onWaybillPickingUp") -} - -func (c *WaybillController) onWaybillDelivering(msg *elmapi.CallbackWaybillStatusMsg) (retVal *elmapi.CallbackResponse) { - return elmapi.Err2CallbackResponse(c.OnWaybillDelivering(c.callbackMsg2Status(msg)), "elm onWaybillDelivering") -} - -func (c *WaybillController) onWaybillDelivered(msg *elmapi.CallbackWaybillStatusMsg) (retVal *elmapi.CallbackResponse) { - return elmapi.Err2CallbackResponse(c.OnWaybillDelivered(c.callbackMsg2Status(msg)), "elm onWaybillDelivered") -} - -func (c *WaybillController) onWaybillCanceled(msg *elmapi.CallbackWaybillStatusMsg) (retVal *elmapi.CallbackResponse) { - return elmapi.Err2CallbackResponse(c.OnWaybillCanceled(c.callbackMsg2Status(msg)), "elm onWaybillCanceled") -} - -func (c *WaybillController) onWaybillFailed(msg *elmapi.CallbackWaybillStatusMsg) (retVal *elmapi.CallbackResponse) { - return elmapi.Err2CallbackResponse(c.OnWaybillFailed(c.callbackMsg2Status(msg)), "elm onWaybillFailed") -} - -func (c *WaybillController) onWaybillOtherStatus(msg *elmapi.CallbackWaybillStatusMsg) (retVal *elmapi.CallbackResponse) { - return elmapi.Err2CallbackResponse(c.OnWaybillOtherStatus(c.callbackMsg2Status(msg)), "elm onWaybillOtherStatus") -} - -func (c *WaybillController) callbackMsg2Status(msg *elmapi.CallbackWaybillStatusMsg) (retVal *model.OrderStatus) { - status := &model.OrderStatus{ - VendorOrderID: msg.OrderID, - VendorID: controller.VendorIDELM, - OrderType: controller.OrderTypeWaybill, - VendorStatus: fmt.Sprintf("%s-%s-%d", msg.State, msg.SubState, msg.MsgType), - StatusTime: utils.Timestamp2Time(msg.UpdateAt / 1000), - } - return status +func (c *WaybillController) composeState(state, subState string, msgType int) string { + return fmt.Sprintf("%s-%s-%d", state, subState, msgType) } diff --git a/business/controller/jd/order.go b/business/controller/jd/order.go index 685a4635d..7042a1399 100644 --- a/business/controller/jd/order.go +++ b/business/controller/jd/order.go @@ -10,47 +10,41 @@ import ( ) type OrderController struct { - controller.OrderController +} + +func init() { + controller.OrderManager.RegisterPurchasePlatform(controller.VendorIDELM, new(OrderController)) } func (c *OrderController) OnOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { - controller.RoutinePool.CallFun(func() { + controller.CallMsgHandler(func() { retVal = c.onOrderMsg(msg) }, msg.BillID) return retVal } -func (c *OrderController) callbackMsg2Status(msg *jdapi.CallbackOrderMsg) *model.OrderStatus { - orderStatus := &model.OrderStatus{ - VendorOrderID: msg.BillID, - VendorID: controller.VendorIDJD, - OrderType: controller.OrderTypeOrder, - VendorStatus: msg.StatusID, - StatusTime: utils.Str2Time(msg.Timestamp), - } - return orderStatus -} - func (c *OrderController) onOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { - switch msg.StatusID { - case jdapi.OrderStatusNew: + if jdapi.OrderStatusNew == msg.StatusID || jdapi.OrderStatusAdjust == msg.StatusID { retVal = c.onOrderNew(msg) - case jdapi.OrderStatusAdjust: - retVal = c.onOrderAdjust(msg) - case jdapi.OrderStatusWaitOutStore: - retVal = c.onOrderWaitOutStore(msg) - case jdapi.OrderStatusFinishedPickup: - retVal = c.onOrderFinishedPickup(msg) - case jdapi.OrderStatusDelivering: - retVal = c.onOrderDelivering(msg) - case jdapi.OrderStatusDelivered: - retVal = c.onOrderDelivered(msg) - case jdapi.OrderStatusCanceled: - retVal = c.onOrderCanceled(msg) - case jdapi.OrderStatusUserApplyCancel: - retVal = c.onOrderUserApplyCancel(msg) - default: - retVal = c.onOrderOtherStatus(msg) + } else { + status := c.callbackMsg2Status(msg) + switch msg.StatusID { + case jdapi.OrderStatusWaitOutStore: + status.Status = controller.OrderStatusAccepted + case jdapi.OrderStatusFinishedPickup: + status.Status = controller.OrderStatusFinishedPickup + case jdapi.OrderStatusDelivering: + status.Status = controller.OrderStatusDelivering + case jdapi.OrderStatusDelivered: + status.Status = controller.OrderStatusDelivered + case jdapi.OrderStatusCanceled: + status.Status = controller.OrderStatusCanceled + case jdapi.OrderStatusUserApplyCancel: + status.Status = controller.OrderStatusApplyCancel + default: + status.Status = controller.OrderStatusUnknown + } + retVal = jdapi.Err2CallbackResponse(controller.OrderManager.OnOrderStatusChanged(status), status.VendorStatus) } return retVal } @@ -60,16 +54,20 @@ func (c *OrderController) getOrderInfo(msg *jdapi.CallbackOrderMsg) (order *mode // globals.SugarLogger.Info(result) if err == nil { order = &model.GoodsOrder{ - VendorOrderID: msg.BillID, - VendorID: controller.VendorIDJD, - VendorStoreID: result["produceStationNo"].(string), - StoreID: int(utils.Str2Int64WithDefault(utils.Interface2String(result["produceStationNoIsv"]), 0)), - StoreName: result["produceStationName"].(string), - ConsigneeName: result["buyerFullName"].(string), - ConsigneeMobile: result["buyerMobile"].(string), - VendorStatus: msg.StatusID, - OrderCreatedAt: utils.Str2Time(result["orderPurchaseTime"].(string)), - OriginalData: string(utils.MustMarshal(result)), + VendorOrderID: msg.BillID, + VendorID: controller.VendorIDJD, + VendorStoreID: result["produceStationNo"].(string), + StoreID: int(utils.Str2Int64WithDefault(utils.Interface2String(result["produceStationNoIsv"]), 0)), + StoreName: result["produceStationName"].(string), + ConsigneeName: result["buyerFullName"].(string), + ConsigneeMobile: result["buyerMobile"].(string), + ConsigneeAddress: result["buyerFullAddress"].(string), + ConsigneeLat: controller.StandardCoordinate2Int(utils.MustInterface2Float64(result["buyerLat"])), + ConsigneeLng: controller.StandardCoordinate2Int(utils.MustInterface2Float64(result["buyerLng"])), + CoordinateType: controller.CoordinateTypeMars, + VendorStatus: msg.StatusID, + OrderCreatedAt: utils.Str2Time(result["orderPurchaseTime"].(string)), + OriginalData: string(utils.MustMarshal(result)), } // discounts := result["discount"].(map[string]interface{}) orderSkus = []*model.OrderSku{} @@ -82,15 +80,17 @@ func (c *OrderController) getOrderInfo(msg *jdapi.CallbackOrderMsg) (order *mode SkuID: int(utils.Str2Int64WithDefault(utils.Interface2String(product["skuIdIsv"]), 0)), VendorSkuID: utils.Int64ToStr(utils.MustInterface2Int64(product["skuId"])), SkuName: product["skuName"].(string), + Weight: int(utils.MustInterface2Float64(product["skuWeight"]) * 1000), SalePrice: utils.MustInterface2Int64(product["skuJdPrice"]), OrderCreatedAt: order.OrderCreatedAt, } orderSkus = append(orderSkus, sku) order.SkuCount++ + order.GoodsCount += sku.Count order.SalePrice += sku.SalePrice + order.Weight += sku.Weight } } - return order, orderSkus, err } @@ -98,7 +98,7 @@ func (c *OrderController) getOrderInfo(msg *jdapi.CallbackOrderMsg) (order *mode func (c *OrderController) onOrderNew(msg *jdapi.CallbackOrderMsg) (response *jdapi.CallbackResponse) { order, orderSkus, err := c.getOrderInfo(msg) if err == nil { - err = c.OnOrderNew(c, order, orderSkus) + err = controller.OrderManager.OnOrderNew(order, orderSkus) } else { globals.SugarLogger.Debugf("get order error:%v", err) } @@ -108,40 +108,23 @@ func (c *OrderController) onOrderNew(msg *jdapi.CallbackOrderMsg) (response *jda func (c *OrderController) onOrderAdjust(msg *jdapi.CallbackOrderMsg) *jdapi.CallbackResponse { order, orderSkus, err := c.getOrderInfo(msg) if err == nil { - err = c.OnOrderAdjust(c, order, orderSkus) + err = controller.OrderManager.OnOrderAdjust(order, orderSkus) } return jdapi.Err2CallbackResponse(err, "jd onOrderAdjust") } -func (c *OrderController) onOrderWaitOutStore(msg *jdapi.CallbackOrderMsg) *jdapi.CallbackResponse { - return jdapi.Err2CallbackResponse(c.OnOrderAccepted(c, c.callbackMsg2Status(msg)), "jd onOrderWaitOutStore") -} - -func (c *OrderController) onOrderFinishedPickup(msg *jdapi.CallbackOrderMsg) *jdapi.CallbackResponse { - return jdapi.Err2CallbackResponse(c.OnOrderFinishedPickup(c, c.callbackMsg2Status(msg)), "jd onOrderFinishedPickup") -} - -func (c *OrderController) onOrderDelivering(msg *jdapi.CallbackOrderMsg) *jdapi.CallbackResponse { - return jdapi.Err2CallbackResponse(c.OnOrderDelivering(c, c.callbackMsg2Status(msg)), "jd onOrderDelivering") -} - -func (c *OrderController) onOrderDelivered(msg *jdapi.CallbackOrderMsg) *jdapi.CallbackResponse { - return jdapi.Err2CallbackResponse(c.OnOrderDelivered(c, c.callbackMsg2Status(msg)), "jd onOrderDelivered") -} - -func (c *OrderController) onOrderCanceled(msg *jdapi.CallbackOrderMsg) *jdapi.CallbackResponse { - return jdapi.Err2CallbackResponse(c.OnOrderCanceled(c, c.callbackMsg2Status(msg)), "jd onOrderCanceled") -} - -func (c *OrderController) onOrderUserApplyCancel(msg *jdapi.CallbackOrderMsg) *jdapi.CallbackResponse { - return jdapi.Err2CallbackResponse(c.OnOrderUserApplyCancel(c, c.callbackMsg2Status(msg)), "jd onOrderUserApplyCancel") -} - -func (c *OrderController) onOrderOtherStatus(msg *jdapi.CallbackOrderMsg) *jdapi.CallbackResponse { - return jdapi.Err2CallbackResponse(c.OnOrderOtherStatus(c, c.callbackMsg2Status(msg)), "jd onOrderOtherStatus") -} - // PurchasePlatformHandler func (c *OrderController) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool) { api.JdAPI.OrderAcceptOperate(order.VendorOrderID, isAcceptIt) } + +func (c *OrderController) callbackMsg2Status(msg *jdapi.CallbackOrderMsg) *model.OrderStatus { + orderStatus := &model.OrderStatus{ + VendorOrderID: msg.BillID, + VendorID: controller.VendorIDJD, + OrderType: controller.OrderTypeOrder, + VendorStatus: msg.StatusID, + StatusTime: utils.Str2Time(msg.Timestamp), + } + return orderStatus +} diff --git a/business/controller/jd/waybill.go b/business/controller/jd/waybill.go index dc780cd99..3dd31a709 100644 --- a/business/controller/jd/waybill.go +++ b/business/controller/jd/waybill.go @@ -8,80 +8,52 @@ import ( ) type WaybillController struct { - controller.WaybillController +} + +func init() { + controller.WaybillManager.RegisterDeliveryProvider(controller.VendorIDJD, new(WaybillController)) } func (c *WaybillController) OnWaybillMsg(msg *jdapi.CallbackDeliveryStatusMsg) (retVal *jdapi.CallbackResponse) { - controller.RoutinePool.CallFun(func() { + controller.CallMsgHandler(func() { retVal = c.onWaybillMsg(msg) }, msg.OrderID) return retVal } -func (c *WaybillController) callbackMsg2Status(msg *jdapi.CallbackDeliveryStatusMsg) *model.OrderStatus { - status := &model.OrderStatus{ - VendorOrderID: msg.OrderID, - VendorID: controller.VendorIDJD, - OrderType: controller.OrderTypeWaybill, - VendorStatus: msg.DeliveryStatus, - StatusTime: utils.Str2Time(msg.DeliveryStatusTime), - } - return status -} - func (c *WaybillController) onWaybillMsg(msg *jdapi.CallbackDeliveryStatusMsg) (retVal *jdapi.CallbackResponse) { + order := c.callbackMsg2Waybill(msg) switch msg.DeliveryStatus { case jdapi.DeliveryStatusWait4Grap: - retVal = c.onWaybillNew(msg) + order.Status = controller.WaybillStatusNew case jdapi.DeliveryStatusAccepted: - retVal = c.onWaybillAccepted(msg) + order.Status = controller.WaybillStatusAccepted case jdapi.DeliveryStatusCourierCanceled: - retVal = c.onWaybillAcceptCanceled(msg) + order.Status = controller.WaybillStatusCanceled + case jdapi.DeliveryStatusCourierArrived: + order.Status = controller.WaybillStatusCourierArrived case jdapi.DeliveryStatusGotGoods: - retVal = c.onWaybillGotGoods(msg) + order.Status = controller.WaybillStatusDelivering case jdapi.DeliveryStatusFinished: - retVal = c.onWaybillFinished(msg) + order.Status = controller.WaybillStatusDelivered case jdapi.DeliveryStatusFailedDelivery: - retVal = c.onWaybillFailed(msg) + order.Status = controller.WaybillStatusFailed default: - retVal = c.onWaybillOtherStatus(msg) + order.Status = controller.WaybillStatusUnknown } - return retVal + return jdapi.Err2CallbackResponse(controller.WaybillManager.OnWaybillStatusChanged(order), order.VendorStatus) } -func (c *WaybillController) onWaybillNew(msg *jdapi.CallbackDeliveryStatusMsg) (retVal *jdapi.CallbackResponse) { - order := &model.Waybill{ +func (c *WaybillController) callbackMsg2Waybill(msg *jdapi.CallbackDeliveryStatusMsg) (retVal *model.Waybill) { + retVal = &model.Waybill{ VendorOrderID: msg.OrderID, - VendorID: controller.VendorIDJD, + OrderVendorID: controller.VendorIDJD, VendorWaybillID: msg.OrderID, WaybillVendorID: controller.VendorIDJD, CourierName: msg.DeliveryManName, CourierMobile: msg.DeliveryManPhone, + VendorStatus: msg.DeliveryStatus, WaybillCreatedAt: utils.Str2Time(msg.DeliveryStatusTime), } - return jdapi.Err2CallbackResponse(c.OnWaybillNew(order), "jd onWaybillNew") -} - -func (c *WaybillController) onWaybillAccepted(msg *jdapi.CallbackDeliveryStatusMsg) (retVal *jdapi.CallbackResponse) { - return jdapi.Err2CallbackResponse(c.OnWaybillAccepted(c.callbackMsg2Status(msg)), "jd onWaybillAccepted") -} - -func (c *WaybillController) onWaybillAcceptCanceled(msg *jdapi.CallbackDeliveryStatusMsg) (retVal *jdapi.CallbackResponse) { - return jdapi.Err2CallbackResponse(c.OnWaybillAcceptCanceled(c.callbackMsg2Status(msg)), "jd onWaybillAcceptCanceled") -} - -func (c *WaybillController) onWaybillGotGoods(msg *jdapi.CallbackDeliveryStatusMsg) (retVal *jdapi.CallbackResponse) { - return jdapi.Err2CallbackResponse(c.OnWaybillDelivering(c.callbackMsg2Status(msg)), "jd onWaybillGotGoods") -} - -func (c *WaybillController) onWaybillFinished(msg *jdapi.CallbackDeliveryStatusMsg) (retVal *jdapi.CallbackResponse) { - return jdapi.Err2CallbackResponse(c.OnWaybillDelivered(c.callbackMsg2Status(msg)), "jd onWaybillFinished") -} - -func (c *WaybillController) onWaybillFailed(msg *jdapi.CallbackDeliveryStatusMsg) (retVal *jdapi.CallbackResponse) { - return jdapi.Err2CallbackResponse(c.OnWaybillFailed(c.callbackMsg2Status(msg)), "jd onWaybillFailed") -} - -func (c *WaybillController) onWaybillOtherStatus(msg *jdapi.CallbackDeliveryStatusMsg) (retVal *jdapi.CallbackResponse) { - return jdapi.Err2CallbackResponse(c.OnWaybillOtherStatus(c.callbackMsg2Status(msg)), "jd onWaybillOtherStatus") + return retVal } diff --git a/business/controller/mtps/waybill.go b/business/controller/mtps/waybill.go index d3e381038..523293293 100644 --- a/business/controller/mtps/waybill.go +++ b/business/controller/mtps/waybill.go @@ -9,86 +9,67 @@ import ( ) type WaybillController struct { - controller.WaybillController +} + +func init() { + controller.OrderManager.RegisterDeliveryPlatform(controller.VendorIDMTPS, new(WaybillController)) } func (c *WaybillController) OnWaybillMsg(msg *mtpsapi.CallbackOrderMsg) (retVal *mtpsapi.CallbackResponse) { - controller.RoutinePool.CallFun(func() { + controller.CallMsgHandler(func() { retVal = c.onWaybillMsg(msg) }, msg.MtPeisongID) return retVal } func (c *WaybillController) OnWaybillExcept(msg *mtpsapi.CallbackOrderExceptionMsg) (retVal *mtpsapi.CallbackResponse) { - controller.RoutinePool.CallFun(func() { - status := &model.OrderStatus{ - VendorOrderID: msg.MtPeisongID, - VendorID: controller.VendorIDMTPS, - OrderType: controller.OrderTypeWaybill, - VendorStatus: utils.Int2Str(msg.ExceptionCode), - StatusTime: utils.Timestamp2Time(int64(msg.Timestamp)), + controller.CallMsgHandler(func() { + order := &model.Waybill{ + VendorWaybillID: msg.MtPeisongID, + VendorWaybillID2: utils.Int64ToStr(msg.DeliveryID), + WaybillVendorID: controller.VendorIDMTPS, + CourierName: msg.CourierName, + CourierMobile: msg.CourierPhone, + Status: controller.WaybillStatusFailed, + VendorStatus: utils.Int2Str(msg.ExceptionCode), + WaybillCreatedAt: utils.Timestamp2Time(msg.Timestamp), } - retVal = mtpsapi.Err2CallbackResponse(c.OnWaybillFailed(status), "mtps OnWaybillExcept") + order.VendorOrderID, order.OrderVendorID = controller.SplitUniversalOrderID(msg.OrderID) + retVal = mtpsapi.Err2CallbackResponse(controller.WaybillManager.OnWaybillStatusChanged(order), "mtps OnWaybillExcept") }, msg.MtPeisongID) return retVal } -func (c *WaybillController) callbackMsg2Status(msg *mtpsapi.CallbackOrderMsg) *model.OrderStatus { - status := &model.OrderStatus{ - VendorOrderID: msg.MtPeisongID, - VendorID: controller.VendorIDMTPS, - OrderType: controller.OrderTypeWaybill, - VendorStatus: utils.Int2Str(msg.Status), - StatusTime: utils.Timestamp2Time(int64(msg.Timestamp)), - } - return status -} - func (c *WaybillController) onWaybillMsg(msg *mtpsapi.CallbackOrderMsg) (retVal *mtpsapi.CallbackResponse) { + order := c.callbackMsg2Waybill(msg) switch msg.Status { case mtpsapi.OrderStatusWaitingForSchedule: - retVal = c.onWaybillNew(msg) + order.Status = controller.WaybillStatusNew case mtpsapi.OrderStatusAccepted: - retVal = c.onWaybillAccepted(msg) + order.Status = controller.WaybillStatusAccepted case mtpsapi.OrderStatusPickedUp: - retVal = c.onWaybillPickedUp(msg) + order.Status = controller.WaybillStatusDelivering case mtpsapi.OrderStatusDeliverred: - retVal = c.onWaybillDelivered(msg) + order.Status = controller.WaybillStatusDelivered case mtpsapi.OrderStatusCanceled: - retVal = c.onWaybillCanceled(msg) + order.Status = controller.WaybillStatusCanceled default: globals.SugarLogger.Warnf("unknown msg:%v", msg) - retVal = mtpsapi.SuccessResponse + return mtpsapi.SuccessResponse } - return retVal + return mtpsapi.Err2CallbackResponse(controller.WaybillManager.OnWaybillStatusChanged(order), order.VendorStatus) } -func (c *WaybillController) onWaybillNew(msg *mtpsapi.CallbackOrderMsg) (retVal *mtpsapi.CallbackResponse) { - order := &model.Waybill{ - VendorOrderID: msg.OrderID, - VendorID: controller.GetVendorIDFromUniversalOrderID(msg.OrderID), +func (c *WaybillController) callbackMsg2Waybill(msg *mtpsapi.CallbackOrderMsg) (retVal *model.Waybill) { + retVal = &model.Waybill{ VendorWaybillID: msg.MtPeisongID, VendorWaybillID2: utils.Int64ToStr(msg.DeliveryID), WaybillVendorID: controller.VendorIDMTPS, CourierName: msg.CourierName, CourierMobile: msg.CourierPhone, + VendorStatus: utils.Int2Str(msg.Status), WaybillCreatedAt: utils.Timestamp2Time(msg.Timestamp), } - return mtpsapi.Err2CallbackResponse(c.OnWaybillNew(order), "mtps onWaybillNew") -} - -func (c *WaybillController) onWaybillAccepted(msg *mtpsapi.CallbackOrderMsg) (retVal *mtpsapi.CallbackResponse) { - return mtpsapi.Err2CallbackResponse(c.OnWaybillAccepted(c.callbackMsg2Status(msg)), "mtps onWaybillAccepted") -} - -func (c *WaybillController) onWaybillPickedUp(msg *mtpsapi.CallbackOrderMsg) (retVal *mtpsapi.CallbackResponse) { - return mtpsapi.Err2CallbackResponse(c.OnWaybillDelivering(c.callbackMsg2Status(msg)), "mtps onWaybillPickedUp") -} - -func (c *WaybillController) onWaybillDelivered(msg *mtpsapi.CallbackOrderMsg) (retVal *mtpsapi.CallbackResponse) { - return mtpsapi.Err2CallbackResponse(c.OnWaybillDelivered(c.callbackMsg2Status(msg)), "mtps onWaybillDelivered") -} - -func (c *WaybillController) onWaybillCanceled(msg *mtpsapi.CallbackOrderMsg) (retVal *mtpsapi.CallbackResponse) { - return mtpsapi.Err2CallbackResponse(c.OnWaybillCanceled(c.callbackMsg2Status(msg)), "mtps onWaybillCanceled") + retVal.VendorOrderID, retVal.OrderVendorID = controller.SplitUniversalOrderID(msg.OrderID) + return retVal } diff --git a/business/controller/order.go b/business/controller/order.go index cd31f599a..ab92e41b8 100644 --- a/business/controller/order.go +++ b/business/controller/order.go @@ -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 } diff --git a/business/controller/waybill.go b/business/controller/waybill.go index c5b07a443..ab076153e 100644 --- a/business/controller/waybill.go +++ b/business/controller/waybill.go @@ -1,7 +1,8 @@ package controller import ( - "git.rosy.net.cn/baseapi" + "fmt" + "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/globals" @@ -11,104 +12,148 @@ import ( const ( WaybillStatusUnknown = 0 - WaybillStatusNew = 5 - WaybillStatusAccepted = 10 - WaybillStatusDelivering = 20 + WaybillStatusNew = 5 + WaybillStatusAcceptCanceled = 8 + WaybillStatusAccepted = 10 + WaybillStatusCourierArrived = 15 // 此状态是可选的,明确写出来是因为还是较重要的状态,但业务逻辑不应依赖此状态 + WaybillStatusDelivering = 20 WaybillStatusDelivered = 105 WaybillStatusCanceled = 115 WaybillStatusFailed = 120 ) -type WaybillController struct { - OrderController +type DeliveryProvider interface { } -var ( - WaybillMap SyncMapWithTimeout -) +type WaybillController struct { + WaybillMap SyncMapWithTimeout + deliveryProviders map[int]DeliveryProvider +} -func (w *WaybillController) OnWaybillNew(bill *model.Waybill) (err error) { +func NewWaybillManager() *WaybillController { + return &WaybillController{ + deliveryProviders: make(map[int]DeliveryProvider), + } +} + +func (w *WaybillController) RegisterDeliveryProvider(vendorID int, handler DeliveryProvider) { + if !(vendorID >= VendorIDDeliveryBegin && vendorID <= VendorIDDeliveryEnd || + vendorID >= VendorIDPurchaseBegin && vendorID <= VendorIDPurchaseEnd) { + panic(fmt.Sprintf("delivery provider vendor:%d is illegal", vendorID)) + } + if _, ok := w.deliveryProviders[vendorID]; ok { + panic(fmt.Sprintf("delivery provider vendor:%d, already exists", vendorID)) + } + w.deliveryProviders[vendorID] = handler +} + +func (w *WaybillController) onWaybillNew(bill *model.Waybill) (err error) { db := orm.NewOrm() bill.Status = WaybillStatusNew - created, _, err := db.ReadOrCreate(bill, "VendorWaybillID", "WaybillVendorID") - if err == nil { - WaybillMap.Store(ComposeUniversalOrderID(bill.VendorWaybillID, bill.WaybillVendorID), bill.ID) - if !created { - baseapi.SugarLogger.Warnf("duplicated waybill:%v msg received", bill) + isDuplicated, err := addOrderOrWaybillStatus(w.waybill2Status(bill), db) + if !isDuplicated { + bill.Status = WaybillStatusNew + bill.WaybillFinishedAt = DefaultTimeValue + bill.ID = 0 + created, _, err := db.ReadOrCreate(bill, "VendorWaybillID", "WaybillVendorID") + if err == nil { + w.WaybillMap.Store(ComposeUniversalOrderID(bill.VendorWaybillID, bill.WaybillVendorID), bill.ID) + if !created { + bill.DuplicatedCount++ + db.Update(bill, "DuplicatedCount") + globals.SugarLogger.Infof("duplicated bill:%v vendorID:%d, msg received", bill.VendorWaybillID, bill.WaybillVendorID) + } + err = OrderManager.OnWaybillStatusChanged(bill, db) + } else { + globals.SugarLogger.Warnf("create bill:%v, error:%v", bill, err) } - } else { - globals.SugarLogger.Warnf("create bill:%v, error:%v", bill, err) } return err } -func (w *WaybillController) OnWaybillAccepted(msg *model.OrderStatus) (err error) { - msg.Status = WaybillStatusAccepted - return w.addWaybillStatus(msg) -} - -func (w *WaybillController) OnWaybillAcceptCanceled(msg *model.OrderStatus) (err error) { - msg.Status = WaybillStatusNew - return w.addWaybillStatus(msg) -} - -func (w *WaybillController) OnWaybillDelivering(msg *model.OrderStatus) (err error) { - msg.Status = WaybillStatusDelivering - return w.addWaybillStatus(msg) -} - -func (w *WaybillController) OnWaybillDelivered(msg *model.OrderStatus) (err error) { - msg.Status = WaybillStatusDelivered - return w.addWaybillStatus(msg) -} - -func (w *WaybillController) OnWaybillCanceled(msg *model.OrderStatus) (err error) { - msg.Status = WaybillStatusCanceled - return w.addWaybillStatus(msg) -} - -func (w *WaybillController) OnWaybillFailed(msg *model.OrderStatus) (err error) { - msg.Status = WaybillStatusFailed - return w.addWaybillStatus(msg) -} - -func (w *WaybillController) OnWaybillOtherStatus(msg *model.OrderStatus) (err error) { - msg.Status = OrderStatusEvent - return w.addWaybillStatus(msg) -} - -func (w *WaybillController) addWaybillStatus(msg *model.OrderStatus) (err error) { - order := &model.Waybill{ - VendorWaybillID: msg.VendorOrderID, - WaybillVendorID: 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, "VendorWaybillID", "WaybillVendorID") +func (w *WaybillController) OnWaybillStatusChanged(bill *model.Waybill) (err error) { + if bill.Status == WaybillStatusNew { + err = w.onWaybillNew(bill) + } else if bill.Status == WaybillStatusAccepted { + err = w.onWaybillAccepted(bill) } else { - order.ID = value.(int64) + db := orm.NewOrm() + isDuplicated, err2 := w.addWaybillStatus(bill, db) + if err2 == nil && !isDuplicated { + err2 = OrderManager.OnWaybillStatusChanged(bill, db) + } + err = err2 } + return err +} - if err == nil { - if msg.Status != OrderStatusEvent { - order.Status = msg.Status +func (w *WaybillController) onWaybillAccepted(bill *model.Waybill) (err error) { + db := orm.NewOrm() + bill.Status = WaybillStatusAccepted + isDuplicated, err := w.addWaybillStatus(bill, db) + if !isDuplicated { + err = w.updateWaybillPKID(bill, db) + if err == nil { utils.CallFuncLogError(func() error { - columns := []string{"Status"} - if msg.Status >= OrderStatusDelivered { - order.WaybillFinishedAt = msg.StatusTime + _, err = db.Update(bill, "CourierName", "CourierMobile") + return err + }, "update waybill info") + if err == nil { + err = OrderManager.OnWaybillStatusChanged(bill, db) + } + } + } + return err +} + +func (w *WaybillController) addWaybillStatus(bill *model.Waybill, db orm.Ormer) (isDuplicated bool, err error) { + if db == nil { + db = orm.NewOrm() + } + waybillStatus := w.waybill2Status(bill) + isDuplicated, err = addOrderOrWaybillStatus(waybillStatus, db) + if !isDuplicated && waybillStatus.Status > WaybillStatusUnknown { + if err = w.updateWaybillPKID(bill, db); err == nil { + bill.Status = waybillStatus.Status + bill.VendorStatus = waybillStatus.VendorStatus + utils.CallFuncLogError(func() error { + columns := []string{"Status", "VendorStatus"} + if waybillStatus.Status >= OrderStatusDelivered { + bill.WaybillFinishedAt = waybillStatus.StatusTime columns = append(columns, "WaybillFinishedAt") } - _, err := db.Update(order, columns...) + _, err := db.Update(bill, columns...) return err - }, "update order") + }, "update waybill") } - utils.CallFuncLogError(func() error { - _, err := db.Insert(msg) - return err - }, "insert status") + } + return isDuplicated, err +} + +func (w *WaybillController) waybill2Status(bill *model.Waybill) (retVal *model.OrderStatus) { + retVal = &model.OrderStatus{ + VendorOrderID: bill.VendorWaybillID, + VendorID: bill.WaybillVendorID, + OrderType: OrderTypeWaybill, + Status: bill.Status, + VendorStatus: bill.VendorStatus, + StatusTime: bill.WaybillCreatedAt, + } + return retVal +} + +func (w *WaybillController) updateWaybillPKID(bill *model.Waybill, db orm.Ormer) (err error) { + value, ok := w.WaybillMap.Load(ComposeUniversalOrderID(bill.VendorWaybillID, bill.WaybillVendorID)) + if !ok { + err = db.Read(bill, "VendorWaybillID", "WaybillVendorID") + // todo 这里应该要报警,但测试阶段先去掉 + // utils.CallFuncLogError(func() error { + // err = db.Read(bill, "VendorWaybillID", "WaybillVendorID") + // return err + // }, "can not get waybill info from db") + } else { + bill.ID = value.(int64) } return err } diff --git a/business/model/order.go b/business/model/order.go index a80094589..341eea865 100644 --- a/business/model/order.go +++ b/business/model/order.go @@ -8,28 +8,37 @@ type ModelTimeInfo struct { } type GoodsOrder struct { - ID int64 `orm:"column(id)"` - VendorOrderID string `orm:"column(vendor_order_id);size(48)"` - VendorID int `orm:"column(vendor_id)"` - VendorStoreID string `orm:"column(vendor_store_id);size(48)"` - StoreID int `orm:"column(store_id)"` // 外部系统里记录的 jxstoreid - JxStoreID int `orm:"column(jx_store_id)"` // 根据VendorStoreID在本地系统里查询出来的 jxstoreid - StoreName string `orm:"size(64)"` - SubStoreID int `orm:"column(sub_store_id)"` - SubStoreName string `orm:"size(64)"` - ShopPrice int64 - SalePrice int64 - ConsigneeName string `orm:"size(32)"` - ConsigneeMobile string `orm:"size(32)"` - SkuCount int - Status int - VendorStatus string `orm:"size(16)"` - LockStatus int - CancelApplyReason string `orm:"size(255);null;default(null)"` // null表示没有申请,不为null表示用户正在取消申请 - WaybillVendorID int `orm:"column(waybill_vendor_id);default(-1)"` - OriginalData string `orm:"type(text)"` - OrderCreatedAt time.Time `orm:"type(datetime);index"` - OrderFinishedAt time.Time `orm:"type(datetime);null;default(null)"` + ID int64 `orm:"column(id)"` + VendorOrderID string `orm:"column(vendor_order_id);size(48)"` + VendorID int `orm:"column(vendor_id)"` + VendorStoreID string `orm:"column(vendor_store_id);size(48)"` + StoreID int `orm:"column(store_id)"` // 外部系统里记录的 jxstoreid + JxStoreID int `orm:"column(jx_store_id)"` // 根据VendorStoreID在本地系统里查询出来的 jxstoreid + StoreName string `orm:"size(64)"` + SubStoreID int `orm:"column(sub_store_id)"` + SubStoreName string `orm:"size(64)"` + ShopPrice int64 // 单位为分 + SalePrice int64 // 单位为分 + Weight int // 单位为克 + ConsigneeName string `orm:"size(32)"` + ConsigneeMobile string `orm:"size(32)"` + ConsigneeAddress string `orm:"size(255)"` + ConsigneeLng int // 坐标 * (10的六次方) + ConsigneeLat int // 坐标 * (10的六次方) + CoordinateType int + SkuCount int // 商品类别数量,即有多少种商品(注意在某些情况下,相同SKU的商品由于售价不同,也会当成不同商品在这个值里) + GoodsCount int // 商品个数 + Status int // 参见相关常量定义 + VendorStatus string `orm:"size(16)"` + LockStatus int + CancelApplyReason string `orm:"size(255)"` // ""表示没有申请,不为null表示用户正在取消申请 + WaybillVendorID int `orm:"column(waybill_vendor_id)"` + WaybillStatus int + WaybillVendorStatus string `orm:"size(16)"` + DuplicatedCount int // 重复新定单消息数,这个一般不是由于消息重发赞成的(消息重发由OrderStatus过滤),一般是业务逻辑赞成的 + OriginalData string `orm:"type(text)"` + OrderCreatedAt time.Time `orm:"type(datetime);index"` + OrderFinishedAt time.Time `orm:"type(datetime)"` ModelTimeInfo } @@ -50,6 +59,7 @@ type OrderSku struct { SkuName string `orm:"size(255)"` ShopPrice int64 SalePrice int64 + Weight int // 单位为克 OrderCreatedAt time.Time `orm:"type(datetime);index"` } @@ -64,7 +74,7 @@ func (o *OrderSku) TableIndex() [][]string { type Waybill struct { ID int64 `orm:"column(id)"` VendorOrderID string `orm:"column(vendor_order_id);size(48)"` - VendorID int `orm:"column(vendor_id)"` + OrderVendorID int `orm:"column(order_vendor_id)"` VendorWaybillID string `orm:"column(vendor_waybill_id);size(48)"` VendorWaybillID2 string `orm:"column(vendor_waybill_id2);size(48)"` WaybillVendorID int `orm:"column(waybill_vendor_id)"` @@ -73,8 +83,9 @@ type Waybill struct { Status int VendorStatus string `orm:"size(16)"` ActualFee int64 + DuplicatedCount int // 重复新定单消息数,这个一般不是由于消息重发赞成的(消息重发由OrderStatus过滤),一般是业务逻辑赞成的 WaybillCreatedAt time.Time `orm:"type(datetime);index"` - WaybillFinishedAt time.Time `orm:"type(datetime);null;default(null)"` + WaybillFinishedAt time.Time `orm:"type(datetime)"` ModelTimeInfo } @@ -92,19 +103,19 @@ func (w *Waybill) TableIndex() [][]string { // 包含定单与运单的状态及事件vendor status type OrderStatus struct { - ID int64 `orm:"column(id)"` - VendorOrderID string `orm:"column(vendor_order_id);size(48)"` - VendorID int `orm:"column(vendor_id)"` - OrderType int // 0:定单,1:运单 - Status int // 如果Status为OrderStatusEvent,表示VendorStatus只是一个事件,不是状态 - VendorStatus string `orm:"size(16)"` - StatusTime time.Time `orm:"type(datetime);index"` - Count int `orm:"default(1)"` + ID int64 `orm:"column(id)"` + VendorOrderID string `orm:"column(vendor_order_id);size(48)"` + VendorID int `orm:"column(vendor_id)"` + OrderType int // 0:定单,1:运单 + Status int // 如果Status为OrderStatusEvent,表示VendorStatus只是一个通知事件,不是状态变化 + VendorStatus string `orm:"size(16)"` + StatusTime time.Time `orm:"type(datetime);index"` + DuplicatedCount int // 收到的重复状态转换(或消息)数,一般是由于重发赞成的 ModelTimeInfo } func (v *OrderStatus) TableIndex() [][]string { return [][]string{ - []string{"VendorOrderID", "Status"}, + []string{"VendorOrderID", "VendorStatus", "Status"}, } } diff --git a/conf/app.conf b/conf/app.conf index 3d53f2f44..cf62a1a0d 100644 --- a/conf/app.conf +++ b/conf/app.conf @@ -12,6 +12,9 @@ routinePoolSize = 1000 dadaAppKey = "dada9623324449cd250" dadaAppSecret = "30c2abbfe8a8780ad5aace46300c64b9" +callLegacy = true +callNew = false + [dev] freshFoodServerURL = "http://portal.beta.jxc4.com" @@ -84,3 +87,5 @@ weixinSecret = "6bbbed1443cc062c20a015a64c07a531" dbConnectStr = "root:WebServer@1@tcp(127.0.0.1:3306)/jxd_dev_0?charset=utf8&loc=Local" +callLegacy = false +callNew = true diff --git a/controllers/dada_order.go b/controllers/dada_order.go index 668e816bd..47560f56b 100644 --- a/controllers/dada_order.go +++ b/controllers/dada_order.go @@ -2,6 +2,8 @@ package controllers import ( "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/controller/dada" + "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/globals/api" "git.rosy.net.cn/jx-callback/legacy/dada/controller" "github.com/astaxie/beego" @@ -24,15 +26,18 @@ func (c *DadaOrderController) URLMapping() { func (c *DadaOrderController) OrderStatusChanged() { obj, callbackResponse := api.DadaAPI.GetOrderCallbackMsg(c.Ctx.Input.RequestBody) if callbackResponse == nil { - cc := &controller.OrderController{} - callbackResponse = cc.OrderStatusChanged(obj) - - // utils.CallFuncAsync(func() { - // cc2 := &dada.WaybillController{} - // cc2.OnWaybillMsg(obj) - // }) + if globals.CallLegacy { + cc := &controller.OrderController{} + callbackResponse = cc.OrderStatusChanged(obj) + } + if globals.CallNew { + utils.CallFuncAsync(func() { + cc2 := &dada.WaybillController{} + cc2.OnWaybillMsg(obj) + }) + } } - if callbackResponse.Code != 200 { + if callbackResponse != nil && callbackResponse.Code != 200 { c.CustomAbort(callbackResponse.Code, string(utils.MustMarshal(callbackResponse))) } else { c.Data["json"] = callbackResponse diff --git a/controllers/elm_order.go b/controllers/elm_order.go index 91ee2802f..7ac416331 100644 --- a/controllers/elm_order.go +++ b/controllers/elm_order.go @@ -2,6 +2,9 @@ package controllers import ( "git.rosy.net.cn/baseapi/platformapi/elmapi" + "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/controller/elm" + "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/globals/api" "git.rosy.net.cn/jx-callback/legacy/elm/controller" "github.com/astaxie/beego" @@ -25,13 +28,16 @@ func (c *ELMOrderController) URLMapping() { func (c *ELMOrderController) MsgPost() { obj, callbackResponse := api.ElmAPI.GetCallbackMsg(c.Ctx.Input.RequestBody) if callbackResponse == nil { - cc := &controller.OrderController{} - callbackResponse = cc.OrderMessage(obj) - - // utils.CallFuncAsync(func() { - // cc2 := &elm.Controller{} - // cc2.OnCallbackMsg(obj) - // }) + if globals.CallLegacy { + cc := &controller.OrderController{} + callbackResponse = cc.OrderMessage(obj) + } + if globals.CallNew { + utils.CallFuncAsync(func() { + cc2 := &elm.Controller{} + cc2.OnCallbackMsg(obj) + }) + } } c.Data["json"] = callbackResponse c.ServeJSON() diff --git a/controllers/jd_order.go b/controllers/jd_order.go index ce86be4d4..159b85f6a 100644 --- a/controllers/jd_order.go +++ b/controllers/jd_order.go @@ -2,6 +2,9 @@ package controllers import ( "git.rosy.net.cn/baseapi/platformapi/jdapi" + "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/controller/jd" + "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/globals/api" "git.rosy.net.cn/jx-callback/legacy/jd/controller" "github.com/astaxie/beego" @@ -34,13 +37,16 @@ func (c *JDOrderController) orderStatus(isCancelOrder bool) { obj, callbackResponse = api.JdAPI.GetOrderCallbackMsg(c.Ctx.Input.RequestBody) } if callbackResponse == nil { - cc := controller.OrderController{} - callbackResponse = cc.OrderStatus(obj) - - // utils.CallFuncAsync(func() { - // cc2 := &jd.OrderController{} - // cc2.OnOrderMsg(obj) - // }) + if globals.CallLegacy { + cc := controller.OrderController{} + callbackResponse = cc.OrderStatus(obj) + } + if globals.CallNew { + utils.CallFuncAsync(func() { + cc2 := &jd.OrderController{} + cc2.OnOrderMsg(obj) + }) + } } c.Data["json"] = callbackResponse c.ServeJSON() @@ -145,13 +151,16 @@ func (c *JDOrderController) ApplyCancelOrder() { func (c *JDOrderController) PushDeliveryStatus() { obj, callbackResponse := api.JdAPI.GetOrderDeliveryCallbackMsg(c.Ctx.Input.RequestBody) if callbackResponse == nil { - cc := controller.OrderController{} - callbackResponse = cc.OrderDeliveryStatus(obj) - - // utils.CallFuncAsync(func() { - // cc2 := &jd.WaybillController{} - // cc2.OnWaybillMsg(obj) - // }) + if globals.CallLegacy { + cc := controller.OrderController{} + callbackResponse = cc.OrderDeliveryStatus(obj) + } + if globals.CallNew { + utils.CallFuncAsync(func() { + cc2 := &jd.WaybillController{} + cc2.OnWaybillMsg(obj) + }) + } } c.Data["json"] = callbackResponse c.ServeJSON() diff --git a/controllers/mtps_order.go b/controllers/mtps_order.go index 7555ea165..a5929264a 100644 --- a/controllers/mtps_order.go +++ b/controllers/mtps_order.go @@ -1,6 +1,9 @@ package controllers import ( + "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/controller/mtps" + "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/globals/api" "git.rosy.net.cn/jx-callback/legacy/mtps/controller" "github.com/astaxie/beego" @@ -24,13 +27,16 @@ func (c *MTPSOrderController) URLMapping() { func (c *MTPSOrderController) Status() { obj, callbackResponse := api.MtpsAPI.GetOrderCallbackMsg(c.Ctx.Request) if callbackResponse == nil { - cc := &controller.OrderController{} - callbackResponse = cc.OrderStatusChanged(obj) - - // utils.CallFuncAsync(func() { - // cc2 := &mtps.WaybillController{} - // cc2.OnWaybillMsg(obj) - // }) + if globals.CallLegacy { + cc := &controller.OrderController{} + callbackResponse = cc.OrderStatusChanged(obj) + } + if globals.CallNew { + utils.CallFuncAsync(func() { + cc2 := &mtps.WaybillController{} + cc2.OnWaybillMsg(obj) + }) + } } c.Data["json"] = callbackResponse c.ServeJSON() @@ -44,13 +50,16 @@ func (c *MTPSOrderController) Status() { func (c *MTPSOrderController) Except() { obj, callbackResponse := api.MtpsAPI.GetOrderExceptionCallbackMsg(c.Ctx.Request) if callbackResponse == nil { - cc := &controller.OrderController{} - callbackResponse = cc.OrderException(obj) - - // utils.CallFuncAsync(func() { - // cc2 := &mtps.WaybillController{} - // cc2.OnWaybillExcept(obj) - // }) + if globals.CallLegacy { + cc := &controller.OrderController{} + callbackResponse = cc.OrderException(obj) + } + if globals.CallNew { + utils.CallFuncAsync(func() { + cc2 := &mtps.WaybillController{} + cc2.OnWaybillExcept(obj) + }) + } } c.Data["json"] = callbackResponse c.ServeJSON() diff --git a/globals/globals.go b/globals/globals.go index 647e05777..7e59aa324 100644 --- a/globals/globals.go +++ b/globals/globals.go @@ -16,10 +16,16 @@ const ( ) var ( + CallLegacy bool + CallNew bool + SugarLogger *zap.SugaredLogger ) func init() { + CallLegacy = beego.AppConfig.DefaultBool("callLegacy", true) + CallNew = beego.AppConfig.DefaultBool("callNew", false) + logs.SetLogFuncCallDepth(3) beego.BConfig.Log.AccessLogs = true diff --git a/legacy/freshfood/freshfood.go b/legacy/freshfood/freshfood.go index 05e880a70..aee111661 100644 --- a/legacy/freshfood/freshfood.go +++ b/legacy/freshfood/freshfood.go @@ -27,7 +27,7 @@ const ( URL_FRESHFOOD_ELEME_TOKENUPDATE = "eleme/token/update" URL_FRESHFOOD_ORDER_CREATE_ELEME = "order/eleme" - URL_FRESHFOOD_ELEME_USER_URGE_ORDER = "reminders/pushElmSmsReminders " + URL_FRESHFOOD_ELEME_USER_URGE_ORDER = "reminders/pushElmSmsReminders" URL_FRESHFOOD_MTPS_DELIVERYSTATUS = "mtps/status" URL_FRESHFOOD_MTPS_EXCEPTION = "mtps/except"