From a90941b26e82cb4ac25946e2637db9e12e8a65ff Mon Sep 17 00:00:00 2001 From: gazebo Date: Tue, 10 Sep 2019 17:21:44 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E4=BA=AC=E8=A5=BF=E8=87=AA=E8=90=A5?= =?UTF-8?q?=E5=95=86=E5=9F=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxutils/jxutils.go | 2 + business/model/const.go | 4 + business/model/dao/store.go | 9 +- business/partner/purchase/jx/callback.go | 28 ++++-- business/partner/purchase/jx/jxapi.go | 99 +++++++++++++++++++ business/partner/purchase/jx/jxapi_order.go | 31 ++++++ .../partner/purchase/jx/jxapi_order_test.go | 21 ++++ business/partner/purchase/jx/order.go | 35 ++++++- 8 files changed, 219 insertions(+), 10 deletions(-) create mode 100644 business/partner/purchase/jx/jxapi.go create mode 100644 business/partner/purchase/jx/jxapi_order.go create mode 100644 business/partner/purchase/jx/jxapi_order_test.go diff --git a/business/jxutils/jxutils.go b/business/jxutils/jxutils.go index ef91ef5ef..21b2078fe 100644 --- a/business/jxutils/jxutils.go +++ b/business/jxutils/jxutils.go @@ -136,6 +136,8 @@ func GetPossibleVendorIDFromVendorOrderID(vendorOrderID string) (vendorID int) { vendorID = model.VendorIDMTWM } else if orderIDLen == len("5287873015048") { vendorID = model.VendorIDWSC + } else if orderIDLen == len("1000004390") { + vendorID = model.VendorIDJX } } return vendorID diff --git a/business/model/const.go b/business/model/const.go index 155dbb4fc..28af4dc65 100644 --- a/business/model/const.go +++ b/business/model/const.go @@ -338,6 +338,10 @@ func IsOrderImportantStatus(status int) bool { return IsOrderMainStatus(status) || IsOrderLockStatus(status) || IsOrderUnlockStatus(status) } +func IsSpecialVendorID(vendorID int) bool { + return vendorID == VendorIDWSC || vendorID == VendorIDJX +} + func WaybillVendorID2Mask(vendorID int) (mask int8) { if vendorID == VendorIDDada { mask = OrderDeliveryFlagMaskDada diff --git a/business/model/dao/store.go b/business/model/dao/store.go index d67c32274..3f6d92bd6 100644 --- a/business/model/dao/store.go +++ b/business/model/dao/store.go @@ -399,10 +399,10 @@ func GetStoreMapByStoreID(db *DaoDB, storeID, vendorID int) (storeMap *model.Sto func FakeGetStoreMapByStoreID(db *DaoDB, storeID, vendorID int) (storeMap *model.StoreMap, err error) { vendorID2 := vendorID - if vendorID == model.VendorIDWSC { - vendorID2 = model.VendorIDJD // 微商城的属性以京东属性为准(以免再绑定) + if model.IsSpecialVendorID(vendorID) { + vendorID2 = model.VendorIDJD // 微商城与京西的属性以京东属性为准(以免再绑定) } - if storeMap, err = GetStoreMapByStoreID(db, storeID, vendorID2); vendorID == model.VendorIDWSC && IsNoRowsError(err) { + if storeMap, err = GetStoreMapByStoreID(db, storeID, vendorID2); model.IsSpecialVendorID(vendorID) && IsNoRowsError(err) { err = nil storeMap = &model.StoreMap{ StoreID: storeID, @@ -416,6 +416,9 @@ func FakeGetStoreMapByStoreID(db *DaoDB, storeID, vendorID int) (storeMap *model IsSync: 1, } } + if storeMap != nil && vendorID == model.VendorIDJX { + storeMap.DeliveryType = model.StoreDeliveryTypeByStore + } return storeMap, err } diff --git a/business/partner/purchase/jx/callback.go b/business/partner/purchase/jx/callback.go index 20e00d4ce..243440b46 100644 --- a/business/partner/purchase/jx/callback.go +++ b/business/partner/purchase/jx/callback.go @@ -1,15 +1,17 @@ package jx -import "fmt" +import ( + "fmt" + "time" + + "git.rosy.net.cn/baseapi/utils" +) const ( appKey = "4A86853D-E4B6-454E-940A-B68ECDA2B73E" - MsgTypeOrder = "order" - SubMsgTypeOrderNew = "newOrder" - SubMsgTypeOrderAdjust = "adjustOrder" - SubMsgTypeOrderApplyCancel = "applyCancel" - // SubMsgTypeOrderApplayRefund = "applyRefund" + MsgTypeOrder = "order" + SubMsgTypeOrderNew = "newOrder" ) type CallbackResponse struct { @@ -23,6 +25,7 @@ type CallbackMsg struct { SubMsgType string `json:"subMsgType"` ThingID string `json:"thingID"` Data string `json:"data"` + Timestamp int64 `json:"timestamp"` } func OnCallbackMsg(msg *CallbackMsg) (retVal, errCode string, err error) { @@ -34,3 +37,16 @@ func OnCallbackMsg(msg *CallbackMsg) (retVal, errCode string, err error) { } return retVal, errCode, err } + +func (p *PurchaseHandler) postFakeMsg(orderNo string, status int) { + msg := &CallbackMsg{ + AppKey: appKey, + MsgType: MsgTypeOrder, + SubMsgType: utils.Int2Str(status), + ThingID: orderNo, + Timestamp: time.Now().Unix(), + } + utils.CallFuncAsync(func() { + OnCallbackMsg(msg) + }) +} diff --git a/business/partner/purchase/jx/jxapi.go b/business/partner/purchase/jx/jxapi.go new file mode 100644 index 000000000..89f30856f --- /dev/null +++ b/business/partner/purchase/jx/jxapi.go @@ -0,0 +1,99 @@ +package jx + +import ( + "fmt" + "net/http" + "strings" + + "git.rosy.net.cn/baseapi" + "git.rosy.net.cn/baseapi/platformapi" + "git.rosy.net.cn/baseapi/utils" +) + +type API struct { + token string + appKey string + appSecret string + client *http.Client + config *platformapi.APIConfig +} + +const ( + ResponseCodeSuccess = 200 +) + +const ( + prodURL = "https://www.jingxicaishi.com/index.php/Weimendian/index" +) + +var ( + exceedLimitCodes = map[int]int{} + canRetryCodes = map[int]int{} +) + +var ( + jxAPI *API +) + +func NewAPI(token, appKey, appSecret string, config ...*platformapi.APIConfig) *API { + curConfig := platformapi.DefAPIConfig + if len(config) > 0 { + curConfig = *config[0] + } + return &API{ + token: token, + appKey: appKey, + appSecret: appSecret, + client: &http.Client{Timeout: curConfig.ClientTimeout}, + config: &curConfig, + } +} + +func init() { + jxAPI = NewAPI("", "", "") +} + +func (a *API) AccessAPI(apiStr string, jxParams map[string]interface{}, traceInfo string) (retVal map[string]interface{}, err error) { + err = platformapi.AccessPlatformAPIWithRetry(a.client, + func() *http.Request { + params := utils.MergeMaps(jxParams, map[string]interface{}{ + "timestamp": utils.GetCurTimeStr(), + }) + var request *http.Request + if false { + + } else { + fullURL := prodURL + "/" + apiStr + // baseapi.SugarLogger.Debug(utils.Map2URLValues(params).Encode()) + request, _ = http.NewRequest(http.MethodPost, fullURL, strings.NewReader(utils.Map2URLValues(params).Encode())) + request.Header.Set("charset", "UTF-8") + request.Header.Set("Content-Type", "application/x-www-form-urlencoded") + } + if traceInfo != "" { + request.Header.Set(platformapi.KeyTrackInfo, traceInfo) + } + // request.Close = true //todo 为了性能考虑还是不要关闭 + return request + }, + a.config, + func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) { + if jsonResult1 == nil { + return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil") + } + code := int(utils.Interface2Int64WithDefault(jsonResult1["code"], 0)) + if code == ResponseCodeSuccess { + retVal = jsonResult1 + return platformapi.ErrLevelSuccess, nil + } + newErr := utils.NewErrorIntCode(jsonResult1["msg"].(string), code) + if _, ok := exceedLimitCodes[code]; ok { + return platformapi.ErrLevelExceedLimit, newErr + } else if _, ok := canRetryCodes[code]; ok { + return platformapi.ErrLevelRecoverableErr, newErr + } else { + baseapi.SugarLogger.Debugf("jx AccessAPI failed, jsonResult1:%s", utils.Format4Output(jsonResult1, true)) + return platformapi.ErrLevelCodeIsNotOK, newErr + } + }) + return retVal, err +} diff --git a/business/partner/purchase/jx/jxapi_order.go b/business/partner/purchase/jx/jxapi_order.go new file mode 100644 index 000000000..7fac07be5 --- /dev/null +++ b/business/partner/purchase/jx/jxapi_order.go @@ -0,0 +1,31 @@ +package jx + +import ( + "git.rosy.net.cn/jx-callback/business/model" +) + +var ( + orderStatusMap = map[int]int{ + model.OrderStatusFinishedPickup: 7, + model.OrderStatusDelivering: 8, + // 4, + model.OrderStatusFinished: 3, + model.OrderStatusCanceled: 3, + } +) + +func translateOrderStatus(status int) (outStatus int) { + return orderStatusMap[status] +} + +func (a *API) NotifyOrderStatusChanged(order *model.GoodsOrder) (err error) { + status := translateOrderStatus(order.Status) + if status > 0 { + _, err = a.AccessAPI("orderChangeStatus", map[string]interface{}{ + "orderid": order.VendorOrderID, + "status": status, + "data": "", //string(utils.MustMarshal(order)), + }, "") + } + return err +} diff --git a/business/partner/purchase/jx/jxapi_order_test.go b/business/partner/purchase/jx/jxapi_order_test.go new file mode 100644 index 000000000..be0939963 --- /dev/null +++ b/business/partner/purchase/jx/jxapi_order_test.go @@ -0,0 +1,21 @@ +package jx + +import ( + "testing" + + _ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" + + "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/jx-callback/business/partner" +) + +func TestNotifyOrderStatusChanged(t *testing.T) { + order, err := partner.CurOrderManager.LoadOrder("920931913000041", model.VendorIDJX) + if err != nil { + t.Fatal(err) + } + err = jxAPI.NotifyOrderStatusChanged(order) + if err != nil { + t.Fatal(err) + } +} diff --git a/business/partner/purchase/jx/order.go b/business/partner/purchase/jx/order.go index daadb0e1f..da762c386 100644 --- a/business/partner/purchase/jx/order.go +++ b/business/partner/purchase/jx/order.go @@ -25,15 +25,34 @@ func (c *PurchaseHandler) OnOrderMsg(msg *CallbackMsg) (retVal, errCode string, } func (c *PurchaseHandler) onOrderMsg(msg *CallbackMsg) (retVal, errCode string, err error) { - if msg.SubMsgType == SubMsgTypeOrderNew || msg.SubMsgType == SubMsgTypeOrderAdjust { + subMsgType := int(utils.Str2Int64WithDefault(msg.SubMsgType, 0)) + if subMsgType == model.OrderStatusNew || subMsgType == model.OrderStatusAdjust { var order *Data4Neworder if err = utils.UnmarshalUseNumber([]byte(msg.Data), &order); err == nil { retVal, errCode, err = c.onOrderNew(msg, order) } + } else { + status := c.callbackMsg2Status(msg) + err = partner.CurOrderManager.OnOrderStatusChanged(status) } return retVal, errCode, err } +func (c *PurchaseHandler) callbackMsg2Status(msg *CallbackMsg) *model.OrderStatus { + orderStatus := &model.OrderStatus{ + VendorOrderID: msg.ThingID, + VendorID: model.VendorIDJX, + OrderType: model.OrderTypeOrder, + RefVendorOrderID: msg.ThingID, + RefVendorID: model.VendorIDJX, + VendorStatus: msg.SubMsgType, + Status: int(utils.Str2Int64WithDefault(msg.SubMsgType, 0)), + StatusTime: utils.Timestamp2Time(msg.Timestamp), + Remark: "", + } + return orderStatus +} + func (c *PurchaseHandler) onOrderNew(msg *CallbackMsg, order *Data4Neworder) (retVal, errCode string, err error) { globals.SugarLogger.Debugf("onOrderNew orderID:%s", msg.ThingID) order.GoodsOrder.Skus = order.Skus @@ -55,10 +74,18 @@ func (c *PurchaseHandler) GetOrder(orderID string) (order *model.GoodsOrder, err } func (c *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) { + if isAcceptIt { + order.Status = model.OrderStatusAccepted + } else { + order.Status = model.OrderStatusCanceled + } + c.postFakeMsg(order.VendorOrderID, order.Status) return err } func (c *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) { + order.Status = model.OrderStatusFinishedPickup + c.postFakeMsg(order.VendorOrderID, order.Status) return err } @@ -83,11 +110,17 @@ func (c *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName } func (c *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) { + order.Status = model.OrderStatusDelivering + c.postFakeMsg(order.VendorOrderID, order.Status) + jxAPI.NotifyOrderStatusChanged(order) return err } // 京东送达接口都是一样的 func (c *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) { + order.Status = model.OrderStatusFinished + c.postFakeMsg(order.VendorOrderID, order.Status) + jxAPI.NotifyOrderStatusChanged(order) return err }