- ready to test jd callback.
This commit is contained in:
@@ -2,70 +2,243 @@ package controller
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
|
||||
"git.rosy.net.cn/baseapi/platform/jdapi"
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-callback/business/freshfood"
|
||||
"git.rosy.net.cn/jx-callback/business/jd/models"
|
||||
"git.rosy.net.cn/jx-callback/compat/corm"
|
||||
"github.com/astaxie/beego/orm"
|
||||
_ "github.com/go-sql-driver/mysql" // import your used driver
|
||||
)
|
||||
|
||||
var errChecker corm.DBErrorChecker
|
||||
const (
|
||||
MsgNotHandledCode = "9527"
|
||||
)
|
||||
|
||||
func init() {
|
||||
errChecker = new(corm.MysqlErrorChecker)
|
||||
var (
|
||||
errChecker corm.DBErrorChecker
|
||||
orderMsgChan chan *jdapi.JDOrderMsg
|
||||
|
||||
// set default database
|
||||
orm.RegisterDataBase("default", "mysql", "root:WebServer@1@tcp(127.0.0.1:3306)/jx-callback?charset=utf8&loc=Local", 30)
|
||||
|
||||
// register model
|
||||
orm.RegisterModel(new(models.Jdorder))
|
||||
|
||||
// create table
|
||||
orm.RunSyncdb("default", false, true)
|
||||
}
|
||||
// freshFoodServerURL = "http://portal.jingxicaishi.com"
|
||||
freshFoodServerURL = "http://test.jxc4.com"
|
||||
freshFoodAPI *freshfood.FreshFoodAPI
|
||||
)
|
||||
|
||||
type OrderControler struct {
|
||||
}
|
||||
|
||||
func (c *OrderControler) NewOrder(order *models.NewOrderMsg) *models.OrderMsgResponse {
|
||||
db := orm.NewOrm()
|
||||
jdorderid, _ := strconv.ParseInt(order.BillId, 10, 64)
|
||||
status, _ := strconv.Atoi(order.StatusId)
|
||||
rec := &models.Jdorder{
|
||||
JdOrderId: jdorderid,
|
||||
OrderStatus: status,
|
||||
}
|
||||
func initOrder() {
|
||||
errChecker = new(corm.MysqlErrorChecker)
|
||||
freshFoodAPI = freshfood.NewFreshFoodAPI(freshFoodServerURL, sugarLogger.Desugar())
|
||||
|
||||
if created, _, err := db.ReadOrCreate(rec, "Jdorderid"); err == nil {
|
||||
if created {
|
||||
c.AcceptOrder(order)
|
||||
result, err := gJdapi.LegacyQuerySingleOrder(order.BillId)
|
||||
if err != nil {
|
||||
sugarLogger.Warnf("error when query jd order:%s, error:%v", order.BillId, err)
|
||||
} else {
|
||||
rec.Code = result.Code
|
||||
rec.Msg = result.Msg
|
||||
rec.Success = 1
|
||||
rec.CityName = "all"
|
||||
rec.OrderStatus = result.OrderStatus
|
||||
rec.OrderStatusTime = result.OrderStatusTime
|
||||
result.Msg = "成功"
|
||||
resultByteArr, _ := json.Marshal(result)
|
||||
rec.Data = string(resultByteArr)
|
||||
db.Update(rec, "Data", "Code", "Msg", "Success", "CityName", "OrderStatus", "OrderStatusTime")
|
||||
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 {
|
||||
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,
|
||||
}
|
||||
|
||||
} else {
|
||||
sugarLogger.Warnf("duplicated jd orderid:%s", order.BillId)
|
||||
sugarLogger.Debug(rec)
|
||||
addOrderMsg(orderMsg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func orderMsgHandlerRoutinue() {
|
||||
for {
|
||||
msg := <-orderMsgChan
|
||||
sugarLogger.Debugf("OrderMsgHandlerRoutinue:%v", msg)
|
||||
go handleOrderMsg(msg)
|
||||
}
|
||||
}
|
||||
|
||||
func addOrderMsg(orderMsg *jdapi.JDOrderMsg) {
|
||||
sugarLogger.Debugf("addOrderMsg:%v", orderMsg)
|
||||
orderMsgChan <- orderMsg
|
||||
}
|
||||
|
||||
func handleOrderMsg(orderMsg *jdapi.JDOrderMsg) {
|
||||
sugarLogger.Debugf("handleOrderMsg:%v", orderMsg)
|
||||
switch orderMsg.StatusId {
|
||||
case jdapi.JdOrderStatusNew:
|
||||
newOrder(orderMsg)
|
||||
case jdapi.JdOrderStatusAdjust:
|
||||
adjustOrder(orderMsg)
|
||||
default:
|
||||
normalOrderStatus(orderMsg)
|
||||
}
|
||||
}
|
||||
|
||||
// --------------
|
||||
func (c *OrderControler) OrderStatus(order *jdapi.JDOrderMsg) *jdapi.JDOrderMsgResponse {
|
||||
if order.StatusId != jdapi.JdOrderStatusNew && order.StatusId != jdapi.JdOrderStatusAdjust {
|
||||
err := normalOrderStatus(order)
|
||||
if err != nil {
|
||||
sugarLogger.Warnf("error in OrderStatus, error:%v", err)
|
||||
return &jdapi.JDOrderMsgResponse{jdapi.JDerrorCodeAccessFailed, err.Error(), ""}
|
||||
}
|
||||
} else {
|
||||
sugarLogger.Errorf("error when calling ReadOrCreate:%v", err)
|
||||
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
|
||||
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 {
|
||||
sugarLogger.Warnf("duplicated jd orderid:%s", order.BillId)
|
||||
sugarLogger.Debug(rec)
|
||||
}
|
||||
} else {
|
||||
sugarLogger.Errorf("error when calling ReadOrCreate:%v", err)
|
||||
return &jdapi.JDOrderMsgResponse{jdapi.JDerrorCodeAccessFailed, err.Error(), ""}
|
||||
}
|
||||
}
|
||||
return jdSuccessResponse
|
||||
}
|
||||
|
||||
func (c *OrderControler) OrderDeliveryStatus(jdOrderDeliveryStatusMsg *jdapi.JDDeliveryStatusMsg) *jdapi.JDOrderMsgResponse {
|
||||
err := freshFoodAPI.JDOrderDeliveryStatus(jdOrderDeliveryStatusMsg, "0")
|
||||
|
||||
if err != nil {
|
||||
sugarLogger.Errorf("Error when calling JDOrderDeliveryStatus, error:%v", err)
|
||||
return &jdapi.JDOrderMsgResponse{jdapi.JDerrorCodeAccessFailed, err.Error(), ""}
|
||||
}
|
||||
|
||||
return &models.OrderMsgResponse{"0", "success", ""}
|
||||
return jdSuccessResponse
|
||||
}
|
||||
|
||||
func (c *OrderControler) AcceptOrder(order *models.NewOrderMsg) {
|
||||
//-----------
|
||||
func acceptOrder(order *jdapi.JDOrderMsg) {
|
||||
gJdapi.OrderAcceptOperate(order.BillId, true)
|
||||
}
|
||||
|
||||
func newOrder(order *jdapi.JDOrderMsg) error {
|
||||
sugarLogger.Debug("NewOrder2")
|
||||
|
||||
result, err := gJdapi.LegacyQuerySingleOrder(order.BillId)
|
||||
acceptOrder(order)
|
||||
if err != nil {
|
||||
sugarLogger.Warnf("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 := dataResult["resultList"].([]interface{})
|
||||
if 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, _ := json.Marshal(data)
|
||||
rec.Data = string(resultByteArr)
|
||||
err = freshFoodAPI.NewJDOrder(rec)
|
||||
if err == nil {
|
||||
db := orm.NewOrm()
|
||||
_, err = db.Update(rec, "Data", "Code", "Msg", "Success", "CityName", "OrderStatus", "OrderStatusTime")
|
||||
if err != nil {
|
||||
sugarLogger.Errorf("update order error:%v", err)
|
||||
}
|
||||
} else {
|
||||
sugarLogger.Errorf("Error when calling NewJDOrder error:%v", err)
|
||||
}
|
||||
} else {
|
||||
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 {
|
||||
sugarLogger.Warnf("error when accessing db:%v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if rec.OrderStatus == utils.Str2Int(order.StatusId) {
|
||||
sugarLogger.Infof("Duplicate message order:%v", order)
|
||||
return nil
|
||||
}
|
||||
|
||||
rec.OrderStatus = utils.Str2Int(order.StatusId)
|
||||
rec.OrderStatusTime = order.Timestamp
|
||||
err = freshFoodAPI.JDOrderStatus(rec, "0")
|
||||
if err != nil {
|
||||
sugarLogger.Warnf("access freshfood failed, error:%v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
rec.Code = "0"
|
||||
_, err = db.Update(rec, "OrderStatus", "OrderStatusTime", "Code")
|
||||
if err != nil {
|
||||
sugarLogger.Warnf("error when accessing db:%v", err)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user