308 lines
8.6 KiB
Go
308 lines
8.6 KiB
Go
package mtpsapi
|
|
|
|
import (
|
|
"crypto/sha1"
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
"sort"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.rosy.net.cn/baseapi/platform/common"
|
|
"git.rosy.net.cn/baseapi/utils"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
const (
|
|
clientTimeout = time.Second * 10
|
|
sleepSecondWhenLimited = 6 * time.Second
|
|
maxRetryCountWhenNetworkException = 3
|
|
maxRetryCountWhenReachLimited = 10
|
|
)
|
|
|
|
const (
|
|
mtpsAPIURL = "https://peisongopen.meituan.com/api"
|
|
signKey = "sign"
|
|
)
|
|
|
|
const (
|
|
OrderStatusWaitingForSchedule = 0
|
|
OrderStatusAccepted = 20
|
|
OrderStatusPickedUp = 30
|
|
OrderStatusDeliverred = 50
|
|
OrderStatusCanceled = 99
|
|
)
|
|
|
|
const (
|
|
DSCRapid = 4011
|
|
DSCIntime = 4012
|
|
DSCTogether = 4013
|
|
)
|
|
|
|
const (
|
|
PickupTypeClientSendToStation = 1
|
|
PickupTypeMtPick = 2
|
|
)
|
|
|
|
const (
|
|
OrderTypeASAP = 0
|
|
OrderTypeBook = 1
|
|
)
|
|
|
|
const (
|
|
CoordinateTypeMars = 0
|
|
CoordinateTypeBaidu = 1
|
|
)
|
|
|
|
// 错误码
|
|
const (
|
|
ResponseCodeSuccess = 0
|
|
)
|
|
|
|
// 取消原因
|
|
const (
|
|
CancelReasonClientActive = 101
|
|
CancelReasonClientChangeTimeOrAddress = 102
|
|
CancelReasonGoodRelated = 103
|
|
CancelReasonMerchantOther = 199
|
|
|
|
CancelReasonMtpsAttitude = 201
|
|
CancelReasonRidderSendNotIntime = 202
|
|
CancelReasonRideerGetGoodNotIntime = 203
|
|
CancelReasonRideerMtpsOther = 299
|
|
|
|
CancelReasonRideerOther = 399
|
|
)
|
|
|
|
type MtpsOrderInfoCommon struct {
|
|
DeliveryId int64
|
|
MtPeisongId string
|
|
OrderId string
|
|
CourierName string
|
|
CourierPhone string
|
|
}
|
|
|
|
type MtpsOrderInfo struct {
|
|
MtpsOrderInfoCommon
|
|
Status int
|
|
OperateTime int
|
|
CancelReasonId int
|
|
CancelReason string
|
|
}
|
|
|
|
type MtpsOrderResponse struct {
|
|
MtPeisongId string `json:"mt_peisong_id`
|
|
DeliveryId int64 `json:"delivery_id`
|
|
OrderId string `json:"order_id`
|
|
}
|
|
|
|
type MTPSResult struct {
|
|
Code int `json:"code"`
|
|
Message string `json:"message"`
|
|
Data map[string]interface{} `json:"data"`
|
|
}
|
|
|
|
type MtpsCreateOrderByShopInfo struct {
|
|
DeliveryId int64
|
|
OrderId string
|
|
ShopId string
|
|
DeliveryServiceCode int
|
|
ReceiverName string
|
|
ReceiverAddress string
|
|
ReceiverPhone string
|
|
ReceiverLng int
|
|
ReceiverLat int
|
|
CoordinateType int
|
|
GoodsValue float64
|
|
GoodsWeight float64
|
|
ExpectedDeliveryTime int64
|
|
OrderType int
|
|
}
|
|
|
|
type MTPSAPI struct {
|
|
appKey string
|
|
secret string
|
|
sugarLogger *zap.SugaredLogger
|
|
client *http.Client
|
|
}
|
|
|
|
func NewMTPSAPI(appKey, secret string, sugarLogger *zap.SugaredLogger) *MTPSAPI {
|
|
api := &MTPSAPI{
|
|
appKey: appKey,
|
|
secret: secret,
|
|
sugarLogger: sugarLogger,
|
|
client: &http.Client{Timeout: clientTimeout},
|
|
}
|
|
|
|
return api
|
|
}
|
|
|
|
func (m *MTPSAPI) signParams(params url.Values) string {
|
|
keys := make([]string, 0)
|
|
for k := range params {
|
|
if k != signKey {
|
|
keys = append(keys, k)
|
|
}
|
|
}
|
|
|
|
sort.Strings(keys)
|
|
finalStr := m.secret
|
|
for _, key := range keys {
|
|
valStr := strings.Join(params[key], "")
|
|
if valStr != "" {
|
|
finalStr += key + valStr
|
|
}
|
|
}
|
|
|
|
// m.sugarLogger.Debug(finalStr)
|
|
return fmt.Sprintf("%x", sha1.Sum([]byte(finalStr)))
|
|
}
|
|
|
|
func (m *MTPSAPI) AccessMTPS(action string, params map[string]interface{}) (retVal *MTPSResult, err error) {
|
|
if params == nil {
|
|
panic("params is nil!")
|
|
}
|
|
|
|
params2 := make(url.Values)
|
|
for k, v := range params {
|
|
params2[k] = []string{fmt.Sprint(v)}
|
|
}
|
|
params2["appkey"] = []string{m.appKey}
|
|
params2["timestamp"] = []string{utils.Int64ToStr(utils.GetCurTimestamp())}
|
|
params2["version"] = []string{"1.0"}
|
|
params2[signKey] = []string{m.signParams(params2)}
|
|
// m.sugarLogger.Debug(params2.Encode())
|
|
request, _ := http.NewRequest("POST", mtpsAPIURL+"/"+action, strings.NewReader(params2.Encode()))
|
|
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
apiAccess := &common.AccessPlatformAPIWithRetryParams{
|
|
MaxExceedLimitRetryCount: maxRetryCountWhenReachLimited,
|
|
MaxRecoverableRetryCount: maxRetryCountWhenNetworkException,
|
|
SleepSecondWhenExceedLimit: sleepSecondWhenLimited,
|
|
Client: m.client,
|
|
Request: request,
|
|
SugarLogger: m.sugarLogger,
|
|
}
|
|
|
|
err = common.AccessPlatformAPIWithRetry(apiAccess, func(response *http.Response) (result string, err error) {
|
|
jsonResult1, err := utils.HttpResponse2Json(response)
|
|
if err != nil {
|
|
m.sugarLogger.Warnf("HttpResponse2Json return:%v", err)
|
|
return common.PAErrorLevelGeneralFail, err
|
|
}
|
|
code := int(utils.MustInterface2Int64(jsonResult1["code"]))
|
|
retVal = &MTPSResult{
|
|
Code: code,
|
|
}
|
|
m.sugarLogger.Debug(jsonResult1)
|
|
if code == ResponseCodeSuccess {
|
|
if innerData, ok := jsonResult1["data"]; ok {
|
|
retVal.Data, _ = innerData.(map[string]interface{})
|
|
}
|
|
return common.PAErrorLevelSuccess, nil
|
|
}
|
|
retVal.Message = jsonResult1["message"].(string)
|
|
return common.PAErrorLevelGeneralFail, utils.NewErrorIntCode(retVal.Message, code)
|
|
})
|
|
|
|
return retVal, err
|
|
}
|
|
|
|
func (m *MTPSAPI) result2OrderResponse(result *MTPSResult) (order *MtpsOrderResponse) {
|
|
order = new(MtpsOrderResponse)
|
|
order.MtPeisongId = result.Data["mt_peisong_id"].(string)
|
|
order.DeliveryId = utils.MustInterface2Int64(result.Data["delivery_id"])
|
|
order.OrderId = result.Data["order_id"].(string)
|
|
return order
|
|
}
|
|
|
|
func (m *MTPSAPI) CreateOrderByShop(basicParams *MtpsCreateOrderByShopInfo, addParams map[string]interface{}) (order *MtpsOrderResponse, err error) {
|
|
params := make(map[string]interface{})
|
|
params["delivery_id"] = utils.Int64ToStr(basicParams.DeliveryId)
|
|
params["order_id"] = basicParams.OrderId
|
|
params["shop_id"] = basicParams.ShopId
|
|
params["delivery_service_code"] = utils.Int2Str(basicParams.DeliveryServiceCode)
|
|
params["receiver_name"] = basicParams.ReceiverName
|
|
params["receiver_address"] = basicParams.ReceiverAddress
|
|
params["receiver_phone"] = basicParams.ReceiverPhone
|
|
params["receiver_lng"] = utils.Int2Str(basicParams.ReceiverLng)
|
|
params["receiver_lat"] = utils.Int2Str(basicParams.ReceiverLat)
|
|
params["coordinate_type"] = utils.Int2Str(basicParams.CoordinateType)
|
|
params["goods_value"] = strconv.FormatFloat(basicParams.GoodsValue, 'f', 2, 64)
|
|
params["goods_weight"] = strconv.FormatFloat(basicParams.GoodsWeight, 'f', 2, 64)
|
|
params["expected_delivery_time"] = utils.Int64ToStr(basicParams.ExpectedDeliveryTime)
|
|
params["order_type"] = utils.Int2Str(basicParams.OrderType)
|
|
if addParams != nil {
|
|
for k, v := range addParams {
|
|
params[k] = v
|
|
}
|
|
}
|
|
if params["order_type"] != utils.Int2Str(OrderTypeBook) {
|
|
delete(params, "expected_delivery_time")
|
|
}
|
|
if result, err := m.AccessMTPS("order/createByShop", params); err != nil {
|
|
m.sugarLogger.Debugf("result:%v", result)
|
|
return nil, utils.NewErrorIntCode(err.Error(), result.Code)
|
|
} else {
|
|
return m.result2OrderResponse(result), nil
|
|
}
|
|
}
|
|
|
|
func (m *MTPSAPI) QueryOrderStatus(deliveryId int64, mtPeiSongId string) (retVal map[string]interface{}, err error) {
|
|
params := map[string]interface{}{
|
|
"delivery_id": deliveryId,
|
|
"mt_peisong_id": mtPeiSongId,
|
|
}
|
|
if result, err := m.AccessMTPS("order/status/query", params); err != nil {
|
|
return nil, err
|
|
} else {
|
|
return result.Data, nil
|
|
}
|
|
}
|
|
|
|
func (m *MTPSAPI) CancelOrder(deliveryId int64, mtPeiSongId string, cancelReasonId int, cancelReason string) (result *MtpsOrderResponse, err error) {
|
|
params := map[string]interface{}{
|
|
"delivery_id": deliveryId,
|
|
"mt_peisong_id": mtPeiSongId,
|
|
"cancel_reason_id": cancelReasonId,
|
|
"cancel_reason": cancelReason,
|
|
}
|
|
if result, err := m.AccessMTPS("order/delete", params); err != nil {
|
|
m.sugarLogger.Debugf("result:%v", result)
|
|
return nil, err
|
|
} else {
|
|
return m.result2OrderResponse(result), nil
|
|
}
|
|
|
|
}
|
|
|
|
func (m *MTPSAPI) simulateOrderBehavior(action string, deliveryId int64, mtPeiSongId string) (err error) {
|
|
params := map[string]interface{}{
|
|
"delivery_id": deliveryId,
|
|
"mt_peisong_id": mtPeiSongId,
|
|
}
|
|
_, err = m.AccessMTPS("test/order/"+action, params)
|
|
return err
|
|
}
|
|
|
|
func (m *MTPSAPI) SimulateArrange(deliveryId int64, mtPeiSongId string) (err error) {
|
|
return m.simulateOrderBehavior("arrange", deliveryId, mtPeiSongId)
|
|
}
|
|
|
|
func (m *MTPSAPI) SimulatePickup(deliveryId int64, mtPeiSongId string) (err error) {
|
|
return m.simulateOrderBehavior("pickup", deliveryId, mtPeiSongId)
|
|
}
|
|
|
|
func (m *MTPSAPI) SimulateDeliver(deliveryId int64, mtPeiSongId string) (err error) {
|
|
return m.simulateOrderBehavior("deliver", deliveryId, mtPeiSongId)
|
|
}
|
|
|
|
func (m *MTPSAPI) SimulateRearrange(deliveryId int64, mtPeiSongId string) (err error) {
|
|
return m.simulateOrderBehavior("rearrange", deliveryId, mtPeiSongId)
|
|
}
|
|
|
|
func (m *MTPSAPI) SimulateReportException(deliveryId int64, mtPeiSongId string) (err error) {
|
|
return m.simulateOrderBehavior("reportException", deliveryId, mtPeiSongId)
|
|
}
|