- big refactor.
This commit is contained in:
228
legacy/jd/controller/order.go
Normal file
228
legacy/jd/controller/order.go
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user