Files
jx-callback/business/controller/elm/order.go

243 lines
9.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package elm
import (
"fmt"
"math"
"strings"
"git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/jx-callback/globals/api"
"git.rosy.net.cn/baseapi/platformapi/elmapi"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/controller"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/scheduler"
)
type OrderController struct {
}
func init() {
scheduler.CurrentScheduler.RegisterPurchasePlatform(model.VendorIDJD, new(OrderController))
}
func (c *OrderController) OnOrderStatusMsg(msg *elmapi.CallbackOrderStatusMsg) (retVal *elmapi.CallbackResponse) {
controller.CallMsgHandler(func() {
retVal = c.onOrderStatusMsg(msg)
}, controller.ComposeUniversalOrderID(msg.OrderID, model.VendorIDELM))
return retVal
}
func (c *OrderController) OnOrderNewMsg(msg map[string]interface{}) (retVal *elmapi.CallbackResponse) {
controller.CallMsgHandler(func() {
retVal = c.onOrderNew(msg)
}, controller.ComposeUniversalOrderID(msg["orderId"].(string), model.VendorIDELM))
return retVal
}
func (c *OrderController) OnOrderCancelRefundMsg(msg *elmapi.CallbackOrderCancelRefundMsg) (retVal *elmapi.CallbackResponse) {
controller.CallMsgHandler(func() {
retVal = c.onOrderCancelRefundMsg(msg)
}, controller.ComposeUniversalOrderID(msg.OrderID, model.VendorIDELM))
return retVal
}
func (c *OrderController) orderStatusMsg2Status(msg *elmapi.CallbackOrderStatusMsg) *model.OrderStatus {
orderStatus := &model.OrderStatus{
VendorOrderID: msg.OrderID,
VendorID: model.VendorIDELM,
OrderType: model.OrderTypeOrder,
RefVendorOrderID: msg.OrderID,
RefVendorID: model.VendorIDELM,
VendorStatus: c.stateAndType2Str(msg.State, msg.MsgType),
StatusTime: utils.Timestamp2Time(msg.UpdateTime),
}
return orderStatus
}
func (c *OrderController) cancelRefundMsg2Status(msg *elmapi.CallbackOrderCancelRefundMsg) *model.OrderStatus {
orderStatus := &model.OrderStatus{
VendorOrderID: msg.OrderID,
VendorID: model.VendorIDELM,
OrderType: model.OrderTypeOrder,
RefVendorOrderID: msg.OrderID,
RefVendorID: model.VendorIDELM,
VendorStatus: c.stateAndType2Str(msg.RefundStatus, msg.MsgType),
StatusTime: utils.Timestamp2Time(msg.UpdateTime),
}
return orderStatus
}
func (c *OrderController) onOrderStatusMsg(msg *elmapi.CallbackOrderStatusMsg) (retVal *elmapi.CallbackResponse) {
status := c.orderStatusMsg2Status(msg)
switch msg.MsgType {
case elmapi.MsgTypeOrderAccepted:
status.Status = model.OrderStatusAccepted
case elmapi.MsgTypeOrderCanceled, elmapi.MsgTypeOrderInvalid, elmapi.MsgTypeOrderForceInvalid:
status.Status = model.OrderStatusCanceled
case elmapi.MsgTypeOrderFinished:
status.Status = model.OrderStatusFinished
default:
globals.SugarLogger.Warnf("elm msg:%d not handled", msg.MsgType)
return elmapi.SuccessResponse
}
err := controller.OrderManager.OnOrderStatusChanged(status)
// if globals.HandleLegacyJxOrder && err == nil {
// c.legacyElmOrderStatusChanged(status)
// }
return elmapi.Err2CallbackResponse(err, status.VendorStatus)
}
func (c *OrderController) onOrderCancelRefundMsg(msg *elmapi.CallbackOrderCancelRefundMsg) (retVal *elmapi.CallbackResponse) {
status := c.cancelRefundMsg2Status(msg)
switch msg.MsgType {
case elmapi.MsgTypeUserApplyCancel:
status.Status = model.OrderStatusApplyCancel
case elmapi.MsgTypeUserApplyRefund:
status.Status = model.OrderStatusApplyRefund
default:
status.Status = model.OrderStatusUnknown
}
return elmapi.Err2CallbackResponse(controller.OrderManager.OnOrderStatusChanged(status), status.VendorStatus)
}
func (c *OrderController) getOrderInfo(orderID string) (order *model.GoodsOrder, err error) {
result, err := api.ElmAPI.GetOrder(orderID)
if err == nil {
phoneList := result["phoneList"].([]interface{})
consigneeMobile := ""
if len(phoneList) > 0 {
consigneeMobile = utils.Interface2String(phoneList[0])
}
// globals.SugarLogger.Debug(result)
order = &model.GoodsOrder{
VendorOrderID: orderID,
VendorID: model.VendorIDELM,
WaybillVendorID: model.VendorIDELM,
VendorStoreID: utils.Int64ToStr(utils.MustInterface2Int64(result["shopId"])),
StoreID: int(utils.Str2Int64WithDefault(utils.Interface2String(result["openId"]), 0)),
StoreName: result["shopName"].(string),
ConsigneeName: utils.FilterMb4(result["consignee"].(string)),
ConsigneeMobile: consigneeMobile,
ConsigneeAddress: utils.FilterMb4(result["address"].(string)),
BuyerComment: utils.FilterMb4(strings.Trim(utils.Interface2String(result["description"]), "\n\r\t ")),
ExpectedDeliveredTime: utils.Str2TimeWithDefault(utils.Interface2String(result["deliverTime"]), utils.DefaultTimeValue),
VendorStatus: utils.Interface2String(result["status"]), // 取订单的原始status不合并消息类型因为当前消息类型没有意义
OrderSeq: int(utils.MustInterface2Int64(result["daySn"])),
OrderCreatedAt: utils.Str2Time(result["createdAt"].(string)),
OriginalData: utils.FilterMb4(string(utils.MustMarshal(result))),
Skus: []*model.OrderSku{},
}
deliveryGeo := strings.Split(utils.Interface2String(result["deliveryGeo"]), ",")
if len(deliveryGeo) == 2 {
order.CoordinateType = model.CoordinateTypeMars
order.ConsigneeLng = controller.StandardCoordinate2Int(utils.Str2Float64(deliveryGeo[0]))
order.ConsigneeLat = controller.StandardCoordinate2Int(utils.Str2Float64(deliveryGeo[1]))
}
for _, group2 := range result["groups"].([]interface{}) {
group := group2.(map[string]interface{})
for _, product2 := range group["items"].([]interface{}) {
product := product2.(map[string]interface{})
sku := &model.OrderSku{
VendorOrderID: orderID,
VendorID: model.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: controller.StandardPrice2Int(utils.MustInterface2Float64(product["userPrice"])),
Weight: int(math.Round(utils.Interface2FloatWithDefault(product["weight"], 0.0))),
OrderCreatedAt: order.OrderCreatedAt,
}
order.Skus = append(order.Skus, sku)
order.SkuCount++
order.GoodsCount += sku.Count
order.SalePrice += sku.SalePrice * int64(sku.Count)
order.Weight += sku.Weight * sku.Count
}
}
}
return order, err
}
//
func (c *OrderController) onOrderNew(msg map[string]interface{}) (response *elmapi.CallbackResponse) {
// todo 这里应该可以直接用msg里的内容而不用再次去查
order, err := c.getOrderInfo(msg["orderId"].(string))
if err == nil {
order.VendorStatus = c.stateAndType2Str(msg["status"].(string), elmapi.MsgTypeOrderValid)
order.Status = model.OrderStatusNew
err = controller.OrderManager.OnOrderNew(order)
// if globals.HandleLegacyJxOrder && err == nil {
// c.legacyWriteElmOrder(order)
// }
}
return elmapi.Err2CallbackResponse(err, "elm onOrderNew")
}
func (c *OrderController) onOrderUserUrgeOrder(msg *elmapi.CallbackOrderUrgeMsg) *elmapi.CallbackResponse {
status := &model.OrderStatus{
VendorOrderID: msg.OrderID,
VendorID: model.VendorIDELM,
OrderType: model.OrderTypeOrder,
RefVendorOrderID: msg.OrderID,
RefVendorID: model.VendorIDELM,
Status: model.OrderStatusApplyUrgeOrder,
VendorStatus: utils.Int2Str(msg.MsgType),
StatusTime: utils.Timestamp2Time(msg.UpdateTime),
}
return elmapi.Err2CallbackResponse(controller.OrderManager.OnOrderStatusChanged(status), status.VendorStatus)
}
func (c *OrderController) stateAndType2Str(state string, msgType int) string {
return fmt.Sprintf("%s-%d", state, msgType)
}
func (c *OrderController) spliltCompositeState(compositeState string) (state string, msgType int) {
index := strings.Index(compositeState, "-")
if index >= 0 {
msgType = int(utils.Str2Int64(compositeState[index+1:]))
if msgType == 0 {
globals.SugarLogger.Debug(compositeState)
}
return compositeState[:index], msgType
}
return compositeState, 0
}
// PurchasePlatformHandler
func (c *OrderController) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool) (err error) {
if isAcceptIt {
err = api.ElmAPI.ConfirmOrder(order.VendorOrderID)
} else {
err = api.ElmAPI.CancelOrder(order.VendorOrderID, elmapi.CancelOrderTypeOthers, "")
}
return err
}
// 饿了么没有拣货这个状态,直接返回成功
// 真实流程中也不会调用这个方法,因为接收订单后状态会直接转移到已拣货
func (c *OrderController) PickedUpGoods(order *model.GoodsOrder) (err error) {
return nil
}
func (c *OrderController) Swtich2SelfDeliver(order *model.GoodsOrder) (err error) {
return api.ElmAPI.DeliveryBySelfLite(order.VendorOrderID)
}
// 饿了么没有这个操作,直接返回成功
func (c *OrderController) SelfDeliverPickedUpGoods(order *model.GoodsOrder) (err error) {
return nil
}
func (c *OrderController) SelfDeliverDelievering(order *model.GoodsOrder) (err error) {
return api.ElmAPI.StartDeliveryBySelf(order.VendorOrderID, order.ConsigneeMobile)
}
func (c *OrderController) SelfDeliverDelievered(order *model.GoodsOrder) (err error) {
return api.ElmAPI.CompleteDeliveryBySelf(order.VendorOrderID, order.ConsigneeMobile)
}