270 lines
9.7 KiB
Go
270 lines
9.7 KiB
Go
package jdapi
|
||
|
||
import (
|
||
"fmt"
|
||
"io/ioutil"
|
||
"net/http"
|
||
"net/url"
|
||
"strings"
|
||
|
||
"git.rosy.net.cn/baseapi"
|
||
"git.rosy.net.cn/baseapi/platformapi"
|
||
"git.rosy.net.cn/baseapi/utils"
|
||
)
|
||
|
||
const (
|
||
CallbackPrefix = "/djsw/"
|
||
)
|
||
|
||
// 如下的常量其实都是京东回调消息的
|
||
const (
|
||
OrderStatusAddComment = "12001"
|
||
OrderStatusModifyComment = "12006"
|
||
OrderStatusTipChanged = "12008"
|
||
|
||
OrderStatusPurchased = "41000" // 也即待处理,JD的消息很怪,新订单消息发过来是32000,但如果不是自动接单的,去查却是41000?,接单后才变为32000
|
||
|
||
OrderStatusPayed = "31020" // 已付款
|
||
|
||
StatusIDNewOrder = "32000"
|
||
OrderStatusWaitOutStore = "32000"
|
||
OrderStatusAdjust = "33080"
|
||
StatusIDWaitOutStore = "32001"
|
||
OrderStatusFinishedPickup = "2"
|
||
OrderStatusDelivering = "33040"
|
||
|
||
OrderStatusDelivered = "33060"
|
||
OrderStatusFinished = "90000"
|
||
OrderStatusCanceled = "20020"
|
||
|
||
OrderStatusUserApplyCancel = "20030" // 这个其实不是一个状态,是一个动作
|
||
OrderStatusLocked = "20010"
|
||
OrderStatusUnlocked = "20050"
|
||
OrderStatusInfoChanged = "1" // 订单信息变更消息
|
||
|
||
OrderStatusPayFinishedSettle = "330901" // 订单支付完成应结
|
||
OrderStatusAdjustSettle = "330902" // 订单调整后应结
|
||
OrderStatusSwitch2SelfSettle = "330903" // 订单众包配送转自送后应结
|
||
|
||
PromotionStatusSingleOK = "35" // 单品直降活动已生效
|
||
PromotionStatusLimitTimeOK = "45" // 限时抢活动已生效
|
||
)
|
||
|
||
const (
|
||
StatusIDAddStore = "12003" // 新增门店消息
|
||
StatusIDDelStore = "12004" // 删除门店消息
|
||
StatusIDUpdateStore = "12009" // 修改门店消息
|
||
)
|
||
|
||
const (
|
||
AfsServiceStateWaiting4Audit = "10" // 待审核
|
||
AfsServiceStateWaiting4UserFeedback = "11" // 待用户反馈
|
||
AfsServiceStateWaiting4CSFeedback = "12" // 待客服反馈
|
||
AfsServiceStateWaiting4GetGoods = "20" // 待取件
|
||
AfsServiceStateRefundProcessing = "30" // 退款处理中
|
||
AfsServiceStateWaiting4MerchantReceiveGoods = "31" // 待商家收货审核
|
||
AfsServiceStateRefundSuccess = "32" // 退款成功
|
||
AfsServiceStateRefundFailed = "33" // 退款失败
|
||
AfsServiceStateAuditRefused = "40" // 审核不通过-驳回
|
||
AfsServiceStateUserCanceled = "50" // 客户取消
|
||
AfsServiceStateMerchantFailedReceiveGoods = "60" // 商家收货审核不通过
|
||
AfsServiceStateSolved = "70" // 已解决
|
||
AfsServiceStateWaiting4DirectCompensate = "90" // 待直陪
|
||
AfsServiceStateDirectCompensate = "91" // 直赔
|
||
AfsServiceStateDirectCompensateSuccess = "92" // 直赔成功
|
||
AfsServiceStateDirectCompensateFailed = "93" // 直赔失败
|
||
|
||
AfsServiceStateWaiting4ReturnGoods = "110" // 待退货
|
||
AfsServiceStateGetGoodsSuccess = "111" // 取货成功
|
||
AfsServiceStateGettingGoods = "1101" // 取货中
|
||
AfsServiceStateGetGoods2Shop = "1111" // 退货成功-商品已送至门店
|
||
AfsServiceStateGetGoodsConfirmed = "1112" // 退货成功-商家已确认收货
|
||
|
||
AfsServiceStateGetGoodsWaiting4Refund = "112" // 退货成功-待退款
|
||
AfsServiceStateReturnGoodsFailed = "113" // 退货失败
|
||
AfsServiceStateReturnGoodsSuccess = "114" // 退货成功
|
||
)
|
||
|
||
const (
|
||
// 订单
|
||
CallbackMsgDeliveryCarrierModify = "deliveryCarrierModify" // 订单转自送消息(是指转自送成功后,用处不大)
|
||
CallbackMsgOrderAccounting = "orderAccounting" // 订单应结消息
|
||
|
||
// 账务
|
||
CallbackMsgEndOrderFinance = "endOrderFinance" // 订单金额拆分完成消息
|
||
CallbackMsgFinanceAdjustment = "financeAdjustment" // 财务调整单消息
|
||
|
||
// 售后
|
||
CallbackMsgNewApplyAfterSaleBill = "newApplyAfterSaleBill" // 新建售后单申请消息
|
||
CallbackMsgUpdateApplyAfterSaleBill = "updateApplyAfterSaleBill" // 修改售后单申请消息
|
||
CallbackMsgNewAfterSaleBill = "newAfterSaleBill" // 新建售后单消息
|
||
CallbackMsgAfterSaleBillStatus = "afterSaleBillStatus" // 售后单状态消息
|
||
)
|
||
|
||
type CallbackResponse struct {
|
||
Code string `json:"code"`
|
||
Msg string `json:"msg"`
|
||
Data string `json:"data"`
|
||
}
|
||
|
||
type CallbackOrderMsg struct {
|
||
MsgURL string `json:"msgURL"`
|
||
BillID string `json:"billId"`
|
||
OutBillID string `json:"outBillId"`
|
||
StatusID string `json:"statusId"`
|
||
Timestamp string `json:"timestamp"`
|
||
Remark string `json:"remark"`
|
||
}
|
||
|
||
type CallbackDeliveryStatusMsg struct {
|
||
MsgURL string `json:"msgURL"`
|
||
OrderID string `json:"orderId"`
|
||
DeliveryStatusTime string `json:"deliveryStatusTime"`
|
||
DeliveryManNo string `json:"deliveryManNo"`
|
||
DeliveryManName string `json:"deliveryManName"`
|
||
DeliveryManPhone string `json:"deliveryManPhone"`
|
||
DeliveryCarrierNo string `json:"deliveryCarrierNo"`
|
||
DeliveryCarrierName string `json:"deliveryCarrierName"`
|
||
DeliveryStatus string `json:"deliveryStatus"`
|
||
Remark string `json:"remark"`
|
||
FailType string `json:"failType"`
|
||
CreatePin string `json:"createPin"`
|
||
OpTime string `json:"opTime"`
|
||
InputTime string `json:"inputTime"`
|
||
}
|
||
|
||
const (
|
||
OpenSourceJDLSP = 1
|
||
OpenSourceJDMedicineCity = 2
|
||
OpenSourceJDMerchantDirect = 3
|
||
OpenSourceJDOne = 4
|
||
OpenSourceStockCenter = 5
|
||
OpenSourceOrderCenter = 6
|
||
OpenSourceGoodsSystem = 7
|
||
OpenSourcePrepositionWH = 8
|
||
OpenSourceStoreSystem = 9
|
||
OpenSourceMerchantCenter = 10
|
||
OpenSourceOpenPlatform = 11
|
||
OpenSourcePickupSystem = 13
|
||
OpenSourceBatchTask = 14
|
||
)
|
||
|
||
type CallbackStoreStockMsg struct {
|
||
MsgURL string `json:"msgURL"`
|
||
StationNo string `json:"stationNo"`
|
||
SkuId int64 `json:"skuId"`
|
||
Have bool `json:"have"`
|
||
Vendibility int `json:"vendibility"`
|
||
OperPin string `json:"operPin"`
|
||
OperTime int64 `json:"operTime"`
|
||
OperSource int `json:"operSource"`
|
||
}
|
||
|
||
var (
|
||
SuccessResponse = &CallbackResponse{Code: "0", Msg: "success", Data: ""}
|
||
FormatErrorResponse = &CallbackResponse{Code: "-1", Msg: "failed", Data: ""}
|
||
)
|
||
|
||
func Err2CallbackResponse(err error, data string) *CallbackResponse {
|
||
if err == nil {
|
||
return SuccessResponse
|
||
}
|
||
return &CallbackResponse{
|
||
Code: ResponseCodeFailedCanAutoRetry,
|
||
Msg: err.Error(),
|
||
Data: data,
|
||
}
|
||
}
|
||
|
||
func (a *API) unmarshalData(strData string, msg interface{}) (callbackResponse *CallbackResponse) {
|
||
err := utils.UnmarshalUseNumber([]byte(strData), msg)
|
||
if err != nil {
|
||
return &CallbackResponse{
|
||
Code: ResponseCodeAbnormalParam,
|
||
Msg: fmt.Sprintf(platformapi.ErrStrUnmarshalError, strData, err),
|
||
Data: strData,
|
||
}
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func (a *API) CheckCallbackValidation(values url.Values) (callbackResponse *CallbackResponse) {
|
||
mapData := utils.URLValues2Map(values)
|
||
sign := a.signParams(mapData)
|
||
if sign != values.Get(signKey) {
|
||
baseapi.SugarLogger.Infof("Signature is not ok, mine:%v, get:%v", sign, values.Get(signKey))
|
||
return FormatErrorResponse
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func (a *API) getCommonOrderCallbackMsg(request *http.Request, msg interface{}, needDecode bool) (callbackResponse *CallbackResponse) {
|
||
data, err := ioutil.ReadAll(request.Body)
|
||
if err != nil {
|
||
return Err2CallbackResponse(err, "")
|
||
}
|
||
// baseapi.SugarLogger.Debug(string(data))
|
||
result, err := utils.HTTPBody2Values(data, needDecode)
|
||
if err != nil {
|
||
return FormatErrorResponse
|
||
}
|
||
if callbackResponse = a.CheckCallbackValidation(result); callbackResponse != nil {
|
||
return callbackResponse
|
||
}
|
||
|
||
jdParamJSON := result.Get(paramJson)
|
||
// baseapi.SugarLogger.Debug(jdParamJSON)
|
||
if callbackResponse = a.unmarshalData(jdParamJSON, msg); callbackResponse != nil {
|
||
return callbackResponse
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func (a *API) GetOrderCallbackMsg(request *http.Request) (msg *CallbackOrderMsg, callbackResponse *CallbackResponse) {
|
||
msg = new(CallbackOrderMsg)
|
||
if callbackResponse = a.getCommonOrderCallbackMsg(request, msg, false); callbackResponse == nil {
|
||
msg.MsgURL = getMsgURLFromRequest(request)
|
||
}
|
||
return msg, callbackResponse
|
||
}
|
||
|
||
func (a *API) GetOrderApplyCancelCallbackMsg(request *http.Request) (msg *CallbackOrderMsg, callbackResponse *CallbackResponse) {
|
||
msg = new(CallbackOrderMsg)
|
||
if callbackResponse = a.getCommonOrderCallbackMsg(request, msg, true); callbackResponse == nil {
|
||
msg.MsgURL = getMsgURLFromRequest(request)
|
||
}
|
||
return msg, callbackResponse
|
||
}
|
||
|
||
func (a *API) GetOrderDeliveryCallbackMsg(request *http.Request) (msg *CallbackDeliveryStatusMsg, callbackResponse *CallbackResponse) {
|
||
if callbackResponse = a.getCommonOrderCallbackMsg(request, &msg, true); callbackResponse == nil {
|
||
msg.MsgURL = getMsgURLFromRequest(request)
|
||
}
|
||
return msg, callbackResponse
|
||
}
|
||
|
||
func (a *API) GetStoreStockCallbackMsg(request *http.Request) (msg *CallbackStoreStockMsg, callbackResponse *CallbackResponse) {
|
||
msg = new(CallbackStoreStockMsg)
|
||
msg.MsgURL = getMsgURLFromRequest(request)
|
||
var tmpMsg map[string]interface{}
|
||
callbackResponse = a.getCommonOrderCallbackMsg(request, &tmpMsg, true)
|
||
if callbackResponse == nil {
|
||
msg.StationNo = utils.Interface2String(tmpMsg["stationNo"])
|
||
msg.SkuId = utils.Str2Int64(utils.Interface2String(tmpMsg["skuId"]))
|
||
msg.Vendibility = int(utils.Str2Int64(utils.Interface2String(tmpMsg["vendibility"])))
|
||
msg.OperPin = utils.Interface2String(tmpMsg["operPin"])
|
||
msg.OperTime = utils.Str2Int64(utils.Interface2String(tmpMsg["operTime"]))
|
||
msg.OperSource = int(utils.Str2Int64((utils.Interface2String(tmpMsg["operSource"]))))
|
||
msg.Have = utils.Interface2String(tmpMsg["have"]) == "true"
|
||
}
|
||
return msg, callbackResponse
|
||
}
|
||
|
||
func getMsgURLFromRequest(request *http.Request) (msgURL string) {
|
||
index := strings.Index(request.URL.Path, CallbackPrefix)
|
||
if index >= 0 {
|
||
msgURL = request.URL.Path[index+len(CallbackPrefix):]
|
||
}
|
||
return msgURL
|
||
}
|