Files
jx-callback/business/jd/controller/order.go
gazebo 03c7efbe1e - mtps added.
- refactor.
2018-06-18 12:03:53 +08:00

239 lines
6.6 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 controller
import (
"encoding/json"
"git.rosy.net.cn/baseapi/platform/jdapi"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/jd/models"
"git.rosy.net.cn/jx-callback/compat/corm"
"git.rosy.net.cn/jx-callback/globals"
"github.com/astaxie/beego/orm"
)
const (
MsgNotHandledCode = "9527"
)
var (
errChecker corm.DBErrorChecker
orderMsgChan chan *jdapi.JDOrderMsg
)
type OrderController struct {
}
func InitOrder() {
errChecker = new(corm.MysqlErrorChecker)
orderMsgChan = make(chan *jdapi.JDOrderMsg, 128)
go orderMsgHandlerRoutinue()
// todo 这样操作在有多个进程时,会有问题
// 另外当前这个模式可能会出现同一个定单的消息虽然远程推送过来顺序是对的但经过处理后推送到freshfood时乱序因为每个消息的处理时间是不确定的
handlePendingOrderMsg()
}
func handlePendingOrderMsg() {
var ordersInfo []models.Jdorder
db := orm.NewOrm()
_, err := db.Raw("SELECT * FROM jdorder WHERE code = ?", MsgNotHandledCode).QueryRows(&ordersInfo)
if err != nil {
globals.SugarLogger.Errorf("can not get jdorder from db, error:%v", err)
} else {
for _, jdOrderInfo := range ordersInfo {
orderMsg := &jdapi.JDOrderMsg{
Id: jdOrderInfo.Id,
BillId: utils.Int64ToStr(jdOrderInfo.JdOrderId),
StatusId: utils.Int2Str(jdOrderInfo.OrderStatus),
Timestamp: jdOrderInfo.OrderStatusTime,
}
addOrderMsg(orderMsg)
}
}
}
func orderMsgHandlerRoutinue() {
for {
msg := <-orderMsgChan
globals.SugarLogger.Debugf("OrderMsgHandlerRoutinue:%v", msg)
go handleOrderMsg(msg)
}
}
func addOrderMsg(orderMsg *jdapi.JDOrderMsg) {
globals.SugarLogger.Debugf("addOrderMsg:%v", orderMsg)
orderMsgChan <- orderMsg
}
func handleOrderMsg(orderMsg *jdapi.JDOrderMsg) {
globals.SugarLogger.Debugf("handleOrderMsg:%v", orderMsg)
switch orderMsg.StatusId {
case jdapi.JdOrderStatusNew:
newOrder(orderMsg)
case jdapi.JdOrderStatusAdjust:
adjustOrder(orderMsg)
default:
normalOrderStatus(orderMsg)
}
}
// --------------
func (c *OrderController) OrderStatus(order *jdapi.JDOrderMsg) *jdapi.JDCallbackResponse {
if order.StatusId != jdapi.JdOrderStatusNew && order.StatusId != jdapi.JdOrderStatusAdjust {
err := normalOrderStatus(order)
if err != nil {
globals.SugarLogger.Warnf("error in OrderStatus, error:%v", err)
return &jdapi.JDCallbackResponse{jdapi.JDerrorCodeAccessFailed, err.Error(), ""}
}
} else {
db := orm.NewOrm()
jdorderid := utils.Str2Int64(order.BillId)
status := utils.Str2Int(order.StatusId)
rec := &models.Jdorder{
Code: MsgNotHandledCode,
JdOrderId: jdorderid,
OrderStatus: status,
OrderStatusTime: order.Timestamp,
}
if created, _, err := db.ReadOrCreate(rec, "Jdorderid"); err == nil {
order.Id = rec.Id
if created {
isStatusSame := order.StatusId == jdapi.JdOrderStatusNew
if !isStatusSame {
order.StatusId = jdapi.JdOrderStatusNew
globals.SugarLogger.Warnf("order:%s get %s before create", order.BillId, order.StatusId)
}
addOrderMsg(order)
if !isStatusSame {
order.StatusId = utils.Int2Str(status)
}
}
if rec.OrderStatus != status {
rec.OrderStatus = status
rec.OrderStatusTime = order.Timestamp
rec.Code = MsgNotHandledCode
db.Update(rec, "OrderStatus", "OrderStatusTime", "Code")
addOrderMsg(order)
} else {
globals.SugarLogger.Warnf("duplicated jd orderid:%s", order.BillId)
globals.SugarLogger.Debug(rec)
}
} else {
globals.SugarLogger.Errorf("error when calling ReadOrCreate:%v", err)
return &jdapi.JDCallbackResponse{jdapi.JDerrorCodeAccessFailed, err.Error(), ""}
}
}
return jdapi.SuccessResponse
}
func (c *OrderController) OrderDeliveryStatus(jdOrderDeliveryStatusMsg *jdapi.JDDeliveryStatusMsg) *jdapi.JDCallbackResponse {
err := globals.FreshFoodAPI.JDOrderDeliveryStatus(jdOrderDeliveryStatusMsg)
if err != nil {
globals.SugarLogger.Errorf("Error when calling JDOrderDeliveryStatus, error:%v", err)
return &jdapi.JDCallbackResponse{jdapi.JDerrorCodeAccessFailed, err.Error(), ""}
}
return jdapi.SuccessResponse
}
//-----------
func acceptOrder(order *jdapi.JDOrderMsg) {
globals.Jdapi.OrderAcceptOperate(order.BillId, true)
}
func newOrder(order *jdapi.JDOrderMsg) error {
globals.SugarLogger.Debug("NewOrder2")
result, err := globals.Jdapi.LegacyQuerySingleOrder(order.BillId)
acceptOrder(order)
if err != nil {
globals.SugarLogger.Errorf("error when query jd order:%s, error:%v", order.BillId, err)
} else {
rec := &models.Jdorder{
Id: order.Id,
}
rec.Code, _ = result["code"].(string)
rec.Msg, _ = result["msg"].(string)
success, _ := result["success"].(bool)
if success {
rec.Success = 1
} else {
rec.Success = 0
}
// todo
rec.CityName = "all"
data := result["data"].(map[string]interface{})
dataResult := data["result"].(map[string]interface{})
resultList, ok := dataResult["resultList"].([]interface{})
if ok && len(resultList) == 1 {
resultList0 := resultList[0].(map[string]interface{})
orderStatus, _ := resultList0["orderStatus"].(json.Number).Int64()
rec.OrderStatus = int(orderStatus)
rec.OrderStatusTime = resultList0["orderStatusTime"].(string)
resultByteArr := utils.MustMarshal(data)
rec.Data = string(resultByteArr)
err = globals.FreshFoodAPI.NewJDOrder(rec)
if err == nil {
db := orm.NewOrm()
_, err = db.Update(rec, "Data", "Code", "Msg", "Success", "CityName", "OrderStatus", "OrderStatusTime")
if err != nil {
globals.SugarLogger.Errorf("update order error:%v", err)
}
} else {
globals.SugarLogger.Errorf("Error when calling NewJDOrder error:%v", err)
}
} else {
globals.SugarLogger.Warnf("can not get jdorder info:%v", order.BillId)
}
}
return err
}
func adjustOrder(order *jdapi.JDOrderMsg) error {
return newOrder(order)
}
func normalOrderStatus(order *jdapi.JDOrderMsg) error {
db := orm.NewOrm()
rec := &models.Jdorder{
JdOrderId: utils.Str2Int64(order.BillId),
}
err := db.Read(rec, "JdOrderId")
if err != nil {
globals.SugarLogger.Warnf("error when accessing db:%v", err)
return err
}
if rec.OrderStatus == utils.Str2Int(order.StatusId) {
globals.SugarLogger.Infof("Duplicate message order:%v", order)
return nil
}
rec.OrderStatus = utils.Str2Int(order.StatusId)
rec.OrderStatusTime = order.Timestamp
err = globals.FreshFoodAPI.JDOrderStatus(rec)
if err != nil {
globals.SugarLogger.Warnf("access freshfood failed, error:%v", err)
return err
}
rec.Code = "0"
_, err = db.Update(rec, "OrderStatus", "OrderStatusTime", "Code")
if err != nil {
globals.SugarLogger.Warnf("error when accessing db:%v", err)
}
return err
}