- big refactor.

This commit is contained in:
gazebo
2018-07-05 12:21:25 +08:00
parent c43ec48837
commit bed727d3e5
21 changed files with 140 additions and 115 deletions

View File

@@ -0,0 +1,228 @@
package controller
import (
"encoding/json"
"git.rosy.net.cn/baseapi/platformapi/jdapi"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/jx-callback/globals/api"
"git.rosy.net.cn/jx-callback/legacy/controllers"
"git.rosy.net.cn/jx-callback/legacy/freshfood"
"git.rosy.net.cn/jx-callback/legacy/jd/models"
"github.com/astaxie/beego/orm"
)
const (
MsgNotHandledCode = "NH"
)
var (
orderMsgChan chan jdapi.CallbackOrderMsg
)
type OrderController struct {
}
func InitOrder() {
orderMsgChan = make(chan jdapi.CallbackOrderMsg, 128)
go orderMsgHandlerRoutine()
// todo 这样操作在有多个进程时,会有问题
// 另外当前这个模式可能会出现同一个定单的消息虽然远程推送过来顺序是对的但经过处理后推送到freshfood时乱序因为每个消息的处理时间是不确定的
handlePendingOrderMsg()
}
func handlePendingOrderMsg() {
var ordersInfo []models.Jdorder
db := orm.NewOrm()
_, err := db.Raw("SELECT * FROM jdorder WHERE orderstatustime >= DATE_ADD(NOW(), interval -2 day) AND 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.CallbackOrderMsg{
ID: jdOrderInfo.ID,
BillID: utils.Int64ToStr(jdOrderInfo.JdOrderID),
StatusID: utils.Int2Str(jdOrderInfo.OrderStatus),
Timestamp: jdOrderInfo.OrderStatusTime,
}
addOrderMsg(orderMsg)
}
}
}
func orderMsgHandlerRoutine() {
for {
msg := <-orderMsgChan
globals.SugarLogger.Debugf("orderMsgHandlerRoutine:%v", msg)
go handleOrderMsg(&msg)
}
}
func addOrderMsg(msg *jdapi.CallbackOrderMsg) {
globals.SugarLogger.Debugf("addOrderMsg:%v", msg)
orderMsgChan <- *msg
}
func handleOrderMsg(msg *jdapi.CallbackOrderMsg) {
globals.SugarLogger.Debugf("handleOrderMsg:%v", msg)
switch msg.StatusID {
case jdapi.OrderStatusNew:
newOrder(msg)
case jdapi.OrderStatusAdjust:
adjustOrder(msg)
default:
normalOrderStatus(msg)
}
}
// --------------
func (c *OrderController) OrderStatus(msg *jdapi.CallbackOrderMsg) *jdapi.CallbackResponse {
if msg.StatusID != jdapi.OrderStatusNew && msg.StatusID != jdapi.OrderStatusAdjust {
err := normalOrderStatus(msg)
if err != nil {
return jdapi.Err2CallbackResponse(err, "")
}
} else {
db := orm.NewOrm()
jdorderid := utils.Str2Int64(msg.BillID)
status := int(utils.Str2Int64(msg.StatusID))
rec := &models.Jdorder{
Code: MsgNotHandledCode,
JdOrderID: jdorderid,
OrderStatus: status,
OrderStatusTime: msg.Timestamp,
}
if created, _, err := db.ReadOrCreate(rec, "JdOrderID"); err == nil {
msg.ID = rec.ID
if created {
if msg.StatusID != jdapi.OrderStatusNew && msg.StatusID != jdapi.OrderStatusAdjust {
globals.SugarLogger.Warnf("order:%v get before create", msg)
oldStatusID := msg.StatusID
msg.StatusID = jdapi.OrderStatusNew
addOrderMsg(msg)
msg.StatusID = oldStatusID
}
addOrderMsg(msg)
} else {
if rec.OrderStatus != status {
if msg.StatusID == jdapi.OrderStatusNew {
globals.SugarLogger.Warnf("order:%v get after some other message:%d", msg, rec.OrderStatus)
} else {
rec.OrderStatus = status
rec.OrderStatusTime = msg.Timestamp
rec.Code = MsgNotHandledCode
utils.CallFuncLogError(func() error {
_, err := db.Update(rec, "OrderStatus", "OrderStatusTime", "Code")
return err
}, globals.ErrStrAccessDB)
addOrderMsg(msg)
}
} else {
globals.SugarLogger.Warnf("duplicated jd order msg:%v", msg)
}
}
} else {
globals.SugarLogger.Errorf("error when calling ReadOrCreate:%v", err)
return jdapi.Err2CallbackResponse(err, "")
}
}
return jdapi.SuccessResponse
}
func (c *OrderController) OrderDeliveryStatus(jdOrderDeliveryStatusMsg *jdapi.CallbackDeliveryStatusMsg) *jdapi.CallbackResponse {
if err := freshfood.FreshFoodAPI.JDOrderDeliveryStatus(jdOrderDeliveryStatusMsg); err != nil {
return jdapi.Err2CallbackResponse(err, "")
}
return jdapi.SuccessResponse
}
//-----------
func OnNewOrder(msg *jdapi.CallbackOrderMsg, userMobile string, db orm.Ormer) {
controllers.OnNewOrder(msg.BillID, controllers.JD_VENDERID, userMobile, 0, db, func(acceptIt bool) {
globals.SugarLogger.Infof("OrderAcceptOperate billid:%v, acceptIt:%v", msg.BillID, acceptIt)
api.Jdapi.OrderAcceptOperate(msg.BillID, acceptIt)
})
}
func newOrder(msg *jdapi.CallbackOrderMsg) error {
result, err := api.Jdapi.LegacyQuerySingleOrder(msg.BillID)
userMobile := ""
var db orm.Ormer
if err == nil {
rec := &models.Jdorder{
ID: msg.ID,
}
rec.Code, _ = result["code"].(string)
rec.Msg, _ = result["msg"].(string)
rec.Success, _ = result["success"].(bool)
// 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.JdOrderID = utils.Str2Int64(msg.BillID)
rec.OrderStatus = int(orderStatus)
rec.OrderStatusTime = resultList0["orderStatusTime"].(string)
resultByteArr := utils.MustMarshal(data)
rec.Data = string(resultByteArr)
rec.Data4Json = data
userMobile = resultList0["buyerMobile"].(string)
err = utils.CallFuncLogError(func() error {
db = orm.NewOrm()
_, err := db.Update(rec, "Data", "Code", "Msg", "Success", "CityName", "OrderStatus", "OrderStatusTime")
return err
}, globals.ErrStrAccessDB)
freshfood.FreshFoodAPI.NewJDOrder(rec, msg.StatusID == jdapi.OrderStatusNew)
} else {
globals.SugarLogger.Errorf("can not get jdorder info:%v", msg.BillID)
}
}
OnNewOrder(msg, userMobile, db)
return err
}
func adjustOrder(msg *jdapi.CallbackOrderMsg) error {
return newOrder(msg)
}
func normalOrderStatus(msg *jdapi.CallbackOrderMsg) (err error) {
if msg.StatusID == jdapi.OrderStatusAddComment || msg.StatusID == jdapi.OrderStatusModifyComment {
err = freshfood.FreshFoodAPI.JDOrderComment(msg)
} else {
db := orm.NewOrm()
rec := &models.Jdorder{
JdOrderID: utils.Str2Int64(msg.BillID),
}
err = db.Read(rec, "JdOrderId")
if err != nil {
globals.SugarLogger.Warnf("error when accessing db err:%v, rec:%v", err, rec)
} else {
if rec.OrderStatus == int(utils.Str2Int64(msg.StatusID)) {
globals.SugarLogger.Infof("Duplicate message msg:%v", msg)
} else {
if err = freshfood.FreshFoodAPI.JDOrderStatus(msg); err == nil {
rec.OrderStatus = int(utils.Str2Int64(msg.StatusID))
rec.OrderStatusTime = msg.Timestamp
rec.Code = "0"
err = utils.CallFuncLogError(func() error {
_, err := db.Update(rec, "OrderStatus", "OrderStatusTime", "Code")
return err
}, globals.ErrStrAccessDB)
}
}
}
}
return err
}