- big big refactor.
This commit is contained in:
109
platformapi/mtpsapi/callback.go
Normal file
109
platformapi/mtpsapi/callback.go
Normal file
@@ -0,0 +1,109 @@
|
||||
package mtpsapi
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"git.rosy.net.cn/baseapi"
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
)
|
||||
|
||||
type CallbackResponse struct {
|
||||
Code int `json:"code"`
|
||||
}
|
||||
|
||||
type CallbackCommonMsg struct {
|
||||
AppKey string
|
||||
Timestamp int64
|
||||
Sign string
|
||||
}
|
||||
|
||||
type CallbackOrderMsg struct {
|
||||
OrderInfoCommon
|
||||
CallbackCommonMsg
|
||||
Status int
|
||||
CancelReasonId int
|
||||
CancelReason string
|
||||
}
|
||||
|
||||
type CallbackOrderExceptionMsg struct {
|
||||
OrderInfoCommon
|
||||
CallbackCommonMsg
|
||||
ExceptionID int64
|
||||
ExceptionCode int
|
||||
ExceptionDescr string
|
||||
ExceptionTime int64
|
||||
}
|
||||
|
||||
var (
|
||||
SuccessResponse = &CallbackResponse{Code: 0}
|
||||
SignatureIsNotOk = &CallbackResponse{Code: -1}
|
||||
)
|
||||
|
||||
func (a *API) CheckCallbackValidation(request *http.Request) (callbackResponse *CallbackResponse) {
|
||||
request.ParseForm()
|
||||
sign := a.signParams(request.PostForm)
|
||||
if sign != request.FormValue(signKey) {
|
||||
baseapi.SugarLogger.Infof("Signature is not ok, mine:%v, get:%v", sign, request.FormValue(signKey))
|
||||
return SignatureIsNotOk
|
||||
}
|
||||
|
||||
for _, valueKey := range []string{"delivery_id", "mt_peisong_id", "order_id"} {
|
||||
baseapi.SugarLogger.Errorf("Missing mandatory param:%v", valueKey)
|
||||
if request.FormValue(valueKey) == "" {
|
||||
return &CallbackResponse{
|
||||
Code: -1,
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *API) GetOrderCallbackMsg(request *http.Request) (orderMsg *CallbackOrderMsg, callbackResponse *CallbackResponse) {
|
||||
if callbackResponse = a.CheckCallbackValidation(request); callbackResponse != nil {
|
||||
return nil, callbackResponse
|
||||
}
|
||||
orderMsg = &CallbackOrderMsg{
|
||||
OrderInfoCommon: OrderInfoCommon{
|
||||
DeliveryId: utils.Str2Int64(request.FormValue("delivery_id")),
|
||||
MtPeisongId: request.FormValue("mt_peisong_id"),
|
||||
OrderId: request.FormValue("order_id"),
|
||||
CourierName: request.FormValue("courier_name"),
|
||||
CourierPhone: request.FormValue("courier_phone"),
|
||||
},
|
||||
CallbackCommonMsg: CallbackCommonMsg{
|
||||
AppKey: request.FormValue("appkey"),
|
||||
Timestamp: utils.Str2Int64(request.FormValue("timestamp")),
|
||||
Sign: request.FormValue("sign"),
|
||||
},
|
||||
Status: int(utils.Str2Int64(request.FormValue("status"))),
|
||||
CancelReasonId: int(utils.Str2Int64(request.FormValue("cancel_reason_id"))),
|
||||
CancelReason: request.FormValue("cancel_reason"),
|
||||
}
|
||||
return orderMsg, nil
|
||||
}
|
||||
|
||||
func (a *API) GetOrderExceptionCallbackMsg(request *http.Request) (orderMsg *CallbackOrderExceptionMsg, callbackResponse *CallbackResponse) {
|
||||
if callbackResponse = a.CheckCallbackValidation(request); callbackResponse != nil {
|
||||
return nil, callbackResponse
|
||||
}
|
||||
orderMsg = &CallbackOrderExceptionMsg{
|
||||
OrderInfoCommon: OrderInfoCommon{
|
||||
DeliveryId: utils.Str2Int64(request.FormValue("delivery_id")),
|
||||
MtPeisongId: request.FormValue("mt_peisong_id"),
|
||||
OrderId: request.FormValue("order_id"),
|
||||
CourierName: request.FormValue("courier_name"),
|
||||
CourierPhone: request.FormValue("courier_phone"),
|
||||
},
|
||||
CallbackCommonMsg: CallbackCommonMsg{
|
||||
AppKey: request.FormValue("appkey"),
|
||||
Timestamp: utils.Str2Int64(request.FormValue("timestamp")),
|
||||
Sign: request.FormValue("sign"),
|
||||
},
|
||||
ExceptionID: utils.Str2Int64(request.FormValue("exception_id")),
|
||||
ExceptionCode: int(utils.Str2Int64(request.FormValue("exception_code"))),
|
||||
ExceptionDescr: request.FormValue("exception_descr"),
|
||||
ExceptionTime: utils.Str2Int64(request.FormValue("exception_time")),
|
||||
}
|
||||
|
||||
return orderMsg, nil
|
||||
}
|
||||
279
platformapi/mtpsapi/mtpsapi.go
Normal file
279
platformapi/mtpsapi/mtpsapi.go
Normal file
@@ -0,0 +1,279 @@
|
||||
package mtpsapi
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
|
||||
"git.rosy.net.cn/baseapi"
|
||||
"git.rosy.net.cn/baseapi/platformapi"
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
mtpsAPIURL = "https://peisongopen.meituan.com/api"
|
||||
signKey = "sign"
|
||||
)
|
||||
|
||||
const (
|
||||
OrderStatusWaitingForSchedule = 0
|
||||
OrderStatusAccepted = 20
|
||||
OrderStatusPickedUp = 30
|
||||
OrderStatusDeliverred = 50
|
||||
OrderStatusCanceled = 99
|
||||
)
|
||||
|
||||
const (
|
||||
DeliveryServiceCodeRapid = 4011
|
||||
DeliveryServiceCodeIntime = 4012
|
||||
DeliveryServiceCodeTogether = 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 OrderInfoCommon struct {
|
||||
DeliveryId int64
|
||||
MtPeisongId string
|
||||
OrderId string
|
||||
CourierName string
|
||||
CourierPhone string
|
||||
}
|
||||
|
||||
type OrderInfo struct {
|
||||
OrderInfoCommon
|
||||
Status int
|
||||
OperateTime int
|
||||
CancelReasonID int
|
||||
CancelReason string
|
||||
}
|
||||
|
||||
type OrderResponse struct {
|
||||
MtPeisongID string `json:"mt_peisong_id"`
|
||||
DeliveryID int64 `json:"delivery_id"`
|
||||
OrderID string `json:"order_id"`
|
||||
}
|
||||
|
||||
type ResponseResult struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data map[string]interface{} `json:"data"`
|
||||
}
|
||||
|
||||
type CreateOrderByShopParam struct {
|
||||
DeliveryID int64 `json:"delivery_id"`
|
||||
OrderID string `json:"order_id"`
|
||||
ShopID string `json:"shop_id"`
|
||||
DeliveryServiceCode int `json:"delivery_service_code"`
|
||||
ReceiverName string `json:"receiver_name"`
|
||||
ReceiverAddress string `json:"receiver_address"`
|
||||
ReceiverPhone string `json:"receiver_phone"`
|
||||
ReceiverLng int `json:"receiver_lng"`
|
||||
ReceiverLat int `json:"receiver_lat"`
|
||||
CoordinateType int `json:"coordinate_type"`
|
||||
GoodsValue float64 `json:"goods_value"`
|
||||
GoodsWeight float64 `json:"goods_weight"`
|
||||
ExpectedDeliveryTime int64 `json:"expected_delivery_time"`
|
||||
OrderType int `json:"order_type"`
|
||||
}
|
||||
|
||||
type API struct {
|
||||
appKey string
|
||||
secret string
|
||||
client *http.Client
|
||||
config *platformapi.APIConfig
|
||||
}
|
||||
|
||||
func New(appKey, secret string, config ...*platformapi.APIConfig) *API {
|
||||
curConfig := platformapi.DefAPIConfig
|
||||
if len(config) > 0 {
|
||||
curConfig = *config[0]
|
||||
}
|
||||
return &API{
|
||||
appKey: appKey,
|
||||
secret: secret,
|
||||
client: &http.Client{Timeout: curConfig.ClientTimeout},
|
||||
config: &curConfig,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *API) signParams(params url.Values) string {
|
||||
keys := make([]string, 0)
|
||||
for k := range params {
|
||||
if k != signKey {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
finalStr := a.secret
|
||||
for _, key := range keys {
|
||||
valStr := strings.Join(params[key], "")
|
||||
if valStr != "" {
|
||||
finalStr += key + valStr
|
||||
}
|
||||
}
|
||||
|
||||
// baseapi.SugarLogger.Debug(finalStr)
|
||||
return fmt.Sprintf("%x", sha1.Sum([]byte(finalStr)))
|
||||
}
|
||||
|
||||
func (a *API) AccessAPI(action string, params map[string]interface{}) (retVal *ResponseResult, 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{a.appKey}
|
||||
params2["timestamp"] = []string{utils.Int64ToStr(utils.GetCurTimestamp())}
|
||||
params2["version"] = []string{"1.0"}
|
||||
params2[signKey] = []string{a.signParams(params2)}
|
||||
// baseapi.SugarLogger.Debug(params2.Encode())
|
||||
request, _ := http.NewRequest("POST", mtpsAPIURL+"/"+action, strings.NewReader(params2.Encode()))
|
||||
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
|
||||
err = platformapi.AccessPlatformAPIWithRetry(a.client, request, a.config, func(response *http.Response) (result string, err error) {
|
||||
jsonResult1, err := utils.HTTPResponse2Json(response)
|
||||
if err != nil {
|
||||
return platformapi.ErrLevelGeneralFail, platformapi.ErrResponseDataFormatWrong
|
||||
}
|
||||
code := int(utils.MustInterface2Int64(jsonResult1["code"]))
|
||||
retVal = &ResponseResult{
|
||||
Code: code,
|
||||
}
|
||||
if code == ResponseCodeSuccess {
|
||||
if innerData, ok := jsonResult1["data"]; ok {
|
||||
retVal.Data, _ = innerData.(map[string]interface{})
|
||||
}
|
||||
return platformapi.ErrLevelSuccess, nil
|
||||
}
|
||||
baseapi.SugarLogger.Warnf("response business code is not ok, data:%v, code:%v", jsonResult1, code)
|
||||
retVal.Message = jsonResult1["message"].(string)
|
||||
newErr := utils.NewErrorIntCode(retVal.Message, code)
|
||||
return platformapi.ErrLevelCodeIsNotOK, newErr
|
||||
})
|
||||
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
func (a *API) result2OrderResponse(result *ResponseResult) (order *OrderResponse) {
|
||||
order = new(OrderResponse)
|
||||
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 (a *API) CreateOrderByShop(basicParams *CreateOrderByShopParam, addParams map[string]interface{}) (order *OrderResponse, err error) {
|
||||
params := structs.Map(basicParams)
|
||||
params["goods_value"] = strconv.FormatFloat(basicParams.GoodsValue, 'f', 2, 64)
|
||||
params["goods_weight"] = strconv.FormatFloat(basicParams.GoodsWeight, 'f', 2, 64)
|
||||
allParams := utils.MergeMaps(params, addParams)
|
||||
|
||||
if params["order_type"] != utils.Int2Str(OrderTypeBook) {
|
||||
delete(params, "expected_delivery_time")
|
||||
}
|
||||
if result, err := a.AccessAPI("order/createByShop", allParams); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return a.result2OrderResponse(result), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a *API) 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 := a.AccessAPI("order/status/query", params); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.Data, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a *API) CancelOrder(deliveryId int64, mtPeiSongId string, cancelReasonId int, cancelReason string) (result *OrderResponse, err error) {
|
||||
params := map[string]interface{}{
|
||||
"delivery_id": deliveryId,
|
||||
"mt_peisong_id": mtPeiSongId,
|
||||
"cancel_reason_id": cancelReasonId,
|
||||
"cancel_reason": cancelReason,
|
||||
}
|
||||
if result, err := a.AccessAPI("order/delete", params); err != nil {
|
||||
baseapi.SugarLogger.Debugf("result:%v", result)
|
||||
return nil, err
|
||||
} else {
|
||||
return a.result2OrderResponse(result), nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (a *API) simulateOrderBehavior(action string, deliveryId int64, mtPeiSongId string) (err error) {
|
||||
params := map[string]interface{}{
|
||||
"delivery_id": deliveryId,
|
||||
"mt_peisong_id": mtPeiSongId,
|
||||
}
|
||||
_, err = a.AccessAPI("test/order/"+action, params)
|
||||
return err
|
||||
}
|
||||
|
||||
func (a *API) SimulateArrange(deliveryId int64, mtPeiSongId string) (err error) {
|
||||
return a.simulateOrderBehavior("arrange", deliveryId, mtPeiSongId)
|
||||
}
|
||||
|
||||
func (a *API) SimulatePickup(deliveryId int64, mtPeiSongId string) (err error) {
|
||||
return a.simulateOrderBehavior("pickup", deliveryId, mtPeiSongId)
|
||||
}
|
||||
|
||||
func (a *API) SimulateDeliver(deliveryId int64, mtPeiSongId string) (err error) {
|
||||
return a.simulateOrderBehavior("deliver", deliveryId, mtPeiSongId)
|
||||
}
|
||||
|
||||
func (a *API) SimulateRearrange(deliveryId int64, mtPeiSongId string) (err error) {
|
||||
return a.simulateOrderBehavior("rearrange", deliveryId, mtPeiSongId)
|
||||
}
|
||||
|
||||
func (a *API) SimulateReportException(deliveryId int64, mtPeiSongId string) (err error) {
|
||||
return a.simulateOrderBehavior("reportException", deliveryId, mtPeiSongId)
|
||||
}
|
||||
106
platformapi/mtpsapi/mtpsapi_test.go
Normal file
106
platformapi/mtpsapi/mtpsapi_test.go
Normal file
@@ -0,0 +1,106 @@
|
||||
package mtpsapi
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.rosy.net.cn/baseapi"
|
||||
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var (
|
||||
mtpsapi *API
|
||||
sugarLogger *zap.SugaredLogger
|
||||
)
|
||||
|
||||
func init() {
|
||||
logger, _ := zap.NewDevelopment()
|
||||
sugarLogger = logger.Sugar()
|
||||
baseapi.Init(sugarLogger)
|
||||
mtpsapi = New("25e816550bc9484480642f19a95f13fd", "r4$HqrKx9~=7?2Jfo,$Z~a7%~k!Au&pEdI2)oPJvSbH2ao@2N0[8wSIvtuumh_J^")
|
||||
// mtpsapi = New("3c0a05d464c247c19d7ec13accc78605", "b1M}9?:sTbsB[OF2gNORnN(|(iy9rB8(`7]|[wGLnbmt`evfM>E:A90DjHAW:UPE")
|
||||
}
|
||||
|
||||
func handleError(t *testing.T, err error) {
|
||||
if err != nil {
|
||||
sugarLogger.Debug(err)
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
func TestTest(t *testing.T) {
|
||||
sugarLogger.Debug(utils.GetCurTimeStr())
|
||||
}
|
||||
|
||||
func TestAccessAPI(t *testing.T) {
|
||||
mtPeiSongId := "1529387562097059"
|
||||
params := map[string]interface{}{
|
||||
"delivery_id": 123456789,
|
||||
"mt_peisong_id": mtPeiSongId,
|
||||
}
|
||||
result, err := mtpsapi.AccessAPI("order/status/query", params)
|
||||
if err != nil {
|
||||
t.Fatalf("Error when accessing AccessAPI result:%v, error:%v", result, err)
|
||||
} else {
|
||||
getMtPsId := result.Data["mt_peisong_id"].(string)
|
||||
if getMtPsId != mtPeiSongId {
|
||||
t.Fatalf("mt_peisong_id is not same, %v vs %v", mtPeiSongId, getMtPsId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateOrderByShop(t *testing.T) {
|
||||
basicParams := &CreateOrderByShopParam{
|
||||
DeliveryID: 123456789,
|
||||
OrderID: "order_123456789",
|
||||
// 设置测试门店 id,测试门店的坐标地址为 97235456,31065079(高德坐标),配送范围3km
|
||||
ShopID: "test_0001",
|
||||
DeliveryServiceCode: DeliveryServiceCodeIntime,
|
||||
ReceiverName: "xjh",
|
||||
ReceiverAddress: "九里堤",
|
||||
ReceiverPhone: "18112345678",
|
||||
ReceiverLng: 97235456,
|
||||
ReceiverLat: 31065079,
|
||||
CoordinateType: CoordinateTypeMars,
|
||||
GoodsValue: 12.34,
|
||||
GoodsWeight: 3.4,
|
||||
OrderType: OrderTypeASAP,
|
||||
}
|
||||
|
||||
order, err := mtpsapi.CreateOrderByShop(basicParams, nil)
|
||||
handleError(t, err)
|
||||
if order != nil {
|
||||
sugarLogger.Debugf("order:%v", order)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSimulateArrange(t *testing.T) {
|
||||
err := mtpsapi.SimulateArrange(123456789, "1529387562097059")
|
||||
handleError(t, err)
|
||||
}
|
||||
|
||||
func TestSimulatePickup(t *testing.T) {
|
||||
err := mtpsapi.SimulatePickup(123456789, "1529387562097059")
|
||||
handleError(t, err)
|
||||
}
|
||||
|
||||
func TestSimulateRearrange(t *testing.T) {
|
||||
err := mtpsapi.SimulateRearrange(123456789, "1529387562097059")
|
||||
handleError(t, err)
|
||||
}
|
||||
|
||||
func TestSimulateDeliver(t *testing.T) {
|
||||
err := mtpsapi.SimulateDeliver(123456789, "1529387562097059")
|
||||
handleError(t, err)
|
||||
}
|
||||
|
||||
func TestSimulateReportException(t *testing.T) {
|
||||
err := mtpsapi.SimulateReportException(123456789, "1529387562097059")
|
||||
handleError(t, err)
|
||||
}
|
||||
|
||||
func TestCancelOrder(t *testing.T) {
|
||||
result, err := mtpsapi.CancelOrder(123456789, "1529387562097059", CancelReasonMerchantOther, "just a test")
|
||||
handleError(t, err)
|
||||
sugarLogger.Debug(result)
|
||||
}
|
||||
Reference in New Issue
Block a user