diff --git a/platformapi/dadaapi/dadaapi_test.go b/platformapi/dadaapi/dadaapi_test.go index 979f7eb6..87c6b965 100644 --- a/platformapi/dadaapi/dadaapi_test.go +++ b/platformapi/dadaapi/dadaapi_test.go @@ -26,10 +26,10 @@ func init() { baseapi.Init(sugarLogger) // sandbox - // dadaapi = New("dada9623324449cd250", "30c2abbfe8a8780ad5aace46300c64b9", "73753", "http://callback.jxc4.com/dada/order", false) + dadaapi = New("dada9623324449cd250", "30c2abbfe8a8780ad5aace46300c64b9", "73753", "http://callback.jxc4.com/dada/order", false) // prod - dadaapi = New("dada147f7a190ce7b3c", "2c717ad914767d6e2beb3f743db9e477", "6660", "http://callback.jxc4.com/dada/order", true) + // dadaapi = New("dada147f7a190ce7b3c", "2c717ad914767d6e2beb3f743db9e477", "6660", "http://callback.jxc4.com/dada/order", true) // prod testOrder = &OperateOrderRequiredParams{ diff --git a/platformapi/dadaapi/order.go b/platformapi/dadaapi/order.go index ca0badc9..2e5857d7 100644 --- a/platformapi/dadaapi/order.go +++ b/platformapi/dadaapi/order.go @@ -30,6 +30,25 @@ const ( OrderStatusAddOrderFailed = 1000 ) +const ( + CargoTypeSnak = 1 // 食品小吃 + CargoTypeDrink = 2 // 饮料 + CargoTypeFlower = 3 // 鲜花 + CargoTypePrint = 8 // 文印票务 + CargoTypeCVS = 9 // 便利店 + CargoTypeFresh = 13 // 水果生鲜 + CargoTypeCityEC = 19 // 同城电商 + CargoTypeMedicine = 20 // 医药 + CargoTypeCake = 21 // 蛋糕 + CargoTypeSwine = 24 // 酒品 + CargoTypeSmallMarket = 25 // 小商品市场 + CargoTypeClothing = 26 // 服装 + CargoTypeCarPart = 27 // 汽修零配 + CargoTypeDigital = 28 // 数码 + CargoTypeLobster = 29 // 小龙虾 + CargoTypeOther = 5 // 其他 +) + type OperateOrderRequiredParams struct { ShopNo string `json:"shop_no"` OriginID string `json:"origin_id"` @@ -44,14 +63,45 @@ type OperateOrderRequiredParams struct { ReceiverTel string `json:"receiver_tel"` } +type OperateOrderParams struct { + // 以下为必要参数 + + ShopNo string `json:"shop_no"` + OriginID string `json:"origin_id"` + CityCode string `json:"city_code"` + CargoPrice float64 `json:"cargo_price"` + IsPrepay int `json:"is_prepay"` + ReceiverName string `json:"receiver_name"` + ReceiverAddress string `json:"receiver_address"` + ReceiverLat float64 `json:"receiver_lat"` + ReceiverLng float64 `json:"receiver_lng"` + ReceiverPhone string `json:"receiver_phone"` + ReceiverTel string `json:"receiver_tel"` + + // 以下为可选参数 + + Tips float64 `json:"tips,omitempty"` + Info string `json:"info,omitempty"` + CargoType int `json:"cargo_type,omitempty"` + CargoWeight float64 `json:"cargo_weight,omitempty"` + CargoNum int `json:"cargo_num,omitempty"` + InvoiceTitle string `json:"invoice_title,omitempty"` + OriginMark string `json:"origin_mark,omitempty"` + OriginMarkNo string `json:"origin_mark_no,omitempty"` + IsUseInsurance int `json:"is_use_insurance"` + IsFinishCodeNeeded int `json:"is_finish_code_needed,omitempty"` + DelayPublishTime int `json:"delay_publish_time,omitempty"` + IsDirectDelivery int `json:"is_direct_delivery,omitempty"` +} + type CreateOrderResponse struct { - DeliveryNo string - Distance float64 - Fee float64 - DeliverFee float64 - CouponFee float64 - Tips float64 - InsuranceFee float64 + DeliveryNo string `json:"deliveryNo"` + Distance float64 `json:"distance"` + Fee float64 `json:"fee"` + DeliverFee float64 `json:"deliverFee"` + CouponFee float64 `json:"couponFee"` + Tips float64 `json:"tips"` + InsuranceFee float64 `json:"insuranceFee"` } type CancelOrderResponse struct { @@ -63,6 +113,34 @@ type ComplaintReason struct { Reason string `json:"reason"` } +type OrderInfo struct { + AcceptTime string `json:"acceptTime"` + ActualFee float64 `json:"actualFee"` + CancelTime string `json:"cancelTime"` + CreateTime string `json:"createTime"` + DeductFee float64 `json:"deductFee"` + DeliveryFee float64 `json:"deliveryFee"` + Distance float64 `json:"distance"` + FetchTime string `json:"fetchTime"` + FinishTime string `json:"finishTime"` + InsuranceFee float64 `json:"insuranceFee"` + OrderFinishCode string `json:"orderFinishCode"` + OrderID string `json:"orderId"` + ReceiptURL string `json:"receiptUrl"` + StatusCode int `json:"statusCode"` + StatusMsg string `json:"statusMsg"` + SupplierAddress string `json:"supplierAddress"` + SupplierLat string `json:"supplierLat"` + SupplierLng string `json:"supplierLng"` + SupplierName string `json:"supplierName"` + SupplierPhone string `json:"supplierPhone"` + Tips float64 `json:"tips"` + TransporterLat string `json:"transporterLat"` + TransporterLng string `json:"transporterLng"` + TransporterName string `json:"transporterName"` + TransporterPhone string `json:"transporterPhone"` +} + func (a *API) QueryOrderInfo(orderID string) (retVal map[string]interface{}, err error) { params := make(map[string]interface{}) params["order_id"] = orderID @@ -73,48 +151,82 @@ func (a *API) QueryOrderInfo(orderID string) (retVal map[string]interface{}, err return result.Result.(map[string]interface{}), nil } -func map2CreateOrderResponse(mapData map[string]interface{}) *CreateOrderResponse { - retVal := new(CreateOrderResponse) - retVal.Distance = utils.MustInterface2Float64(mapData["distance"]) - retVal.Fee = utils.MustInterface2Float64(mapData["fee"]) - retVal.DeliverFee = utils.MustInterface2Float64(mapData["deliverFee"]) - retVal.DeliveryNo = utils.Interface2String(mapData["deliveryNo"]) - - if value, ok := mapData["couponFee"]; ok { - retVal.CouponFee = utils.MustInterface2Float64(value) +// 订单详情查询 +// http://newopen.imdada.cn/#/development/file/statusQuery?_k=7ou2o1 +func (a *API) QueryOrderInfo2(orderID string) (order *OrderInfo, err error) { + params := make(map[string]interface{}) + params["order_id"] = orderID + result, err := a.AccessAPI("api/order/status/query", params) + if err == nil { + err = utils.Map2StructByJson(result.Result, &order, false) } - if value, ok := mapData["tips"]; ok { - retVal.CouponFee = utils.MustInterface2Float64(value) - } - if value, ok := mapData["insuranceFee"]; ok { - retVal.CouponFee = utils.MustInterface2Float64(value) - } - return retVal + return order, err } +// func map2CreateOrderResponse(mapData map[string]interface{}) *CreateOrderResponse { +// retVal := new(CreateOrderResponse) +// retVal.Distance = utils.MustInterface2Float64(mapData["distance"]) +// retVal.Fee = utils.MustInterface2Float64(mapData["fee"]) +// retVal.DeliverFee = utils.MustInterface2Float64(mapData["deliverFee"]) +// retVal.DeliveryNo = utils.Interface2String(mapData["deliveryNo"]) + +// if value, ok := mapData["couponFee"]; ok { +// retVal.CouponFee = utils.MustInterface2Float64(value) +// } +// if value, ok := mapData["tips"]; ok { +// retVal.CouponFee = utils.MustInterface2Float64(value) +// } +// if value, ok := mapData["insuranceFee"]; ok { +// retVal.CouponFee = utils.MustInterface2Float64(value) +// } +// return retVal +// } + func (a *API) operateOrder(action string, orderInfo *OperateOrderRequiredParams, addParams map[string]interface{}) (retVal *CreateOrderResponse, err error) { params := utils.Struct2MapByJson(orderInfo) params["callback"] = a.callbackURL allParams := utils.MergeMaps(params, addParams) result, err := a.AccessAPI(action, allParams) - if err != nil { - return nil, err + if err == nil { + err = utils.Map2StructByJson(result.Result, &retVal, false) } - return map2CreateOrderResponse(result.Result.(map[string]interface{})), nil + return retVal, err +} + +func (a *API) operateOrder2(action string, orderInfo *OperateOrderParams) (retVal *CreateOrderResponse, err error) { + params := utils.Struct2MapByJson(orderInfo) + params["callback"] = a.callbackURL + result, err := a.AccessAPI(action, params) + if err == nil { + err = utils.Map2StructByJson(result.Result, &retVal, false) + } + return retVal, err } func (a *API) AddOrder(orderInfo *OperateOrderRequiredParams, addParams map[string]interface{}) (retVal *CreateOrderResponse, err error) { return a.operateOrder("api/order/addOrder", orderInfo, addParams) } +func (a *API) AddOrder2(orderInfo *OperateOrderParams) (retVal *CreateOrderResponse, err error) { + return a.operateOrder2("api/order/addOrder", orderInfo) +} + func (a *API) ReaddOrder(orderInfo *OperateOrderRequiredParams, addParams map[string]interface{}) (retVal *CreateOrderResponse, err error) { return a.operateOrder("api/order/reAddOrder", orderInfo, addParams) } +func (a *API) ReaddOrder2(orderInfo *OperateOrderParams) (retVal *CreateOrderResponse, err error) { + return a.operateOrder2("api/order/reAddOrder", orderInfo) +} + func (a *API) QueryDeliverFee(orderInfo *OperateOrderRequiredParams, addParams map[string]interface{}) (retVal *CreateOrderResponse, err error) { return a.operateOrder("api/order/queryDeliverFee", orderInfo, addParams) } +func (a *API) QueryDeliverFee2(orderInfo *OperateOrderParams) (retVal *CreateOrderResponse, err error) { + return a.operateOrder2("api/order/queryDeliverFee", orderInfo) +} + func (a *API) AddOrderAfterQuery(deliveryNo string) (err error) { _, err = a.AccessAPI("api/order/addAfterQuery", map[string]interface{}{ "deliveryNo": deliveryNo, @@ -155,3 +267,18 @@ func (a *API) ComplaintRider(orderID string, resonID int) (err error) { _, err = a.AccessAPI("api/complaint/dada", mapData) return err } + +// 增加小费 +// http://newopen.imdada.cn/#/development/file/addTip?_k=5yerib +func (a *API) AddTip(orderID string, tips float64, cityCode, info string) (err error) { + mapData := map[string]interface{}{ + "order_id": orderID, + "tips": tips, + "city_code": cityCode, + } + if info != "" { + mapData["info"] = info + } + _, err = a.AccessAPI("api/order/addTip", mapData) + return err +} diff --git a/platformapi/dadaapi/order_test.go b/platformapi/dadaapi/order_test.go index f30280f6..5dd04012 100644 --- a/platformapi/dadaapi/order_test.go +++ b/platformapi/dadaapi/order_test.go @@ -11,7 +11,7 @@ import ( func TestAddOrderAfterQuery(t *testing.T) { orderID := utils.GetUUID() result, err := dadaapi.QueryDeliverFee(&OperateOrderRequiredParams{ - ShopNo: "18180948107", + ShopNo: testShopNo, OriginID: orderID, CityCode: "028", CargoPrice: 0.01, @@ -39,8 +39,34 @@ func TestAddOrderAfterQuery(t *testing.T) { baseapi.SugarLogger.Debug(utils.Format4Output(cancelResponse, false)) } +func TestAddOrderAfterQuery2(t *testing.T) { + orderID := utils.GetUUID() + result, err := dadaapi.QueryDeliverFee2(&OperateOrderParams{ + ShopNo: testShopNo, + OriginID: orderID, + CityCode: "028", + CargoPrice: 0.01, + IsPrepay: 0, + ReceiverName: "徐建华", + ReceiverAddress: "西南交通大学科技大厦", + ReceiverLng: 104.056822, + ReceiverLat: 30.696041, + ReceiverPhone: "18180948107", + }) + if err != nil { + t.Fatal(err) + } + baseapi.SugarLogger.Debug(orderID) + baseapi.SugarLogger.Debug(utils.Format4Output(result, false)) + + err = dadaapi.AddOrderAfterQuery(result.DeliveryNo) + if err != nil { + t.Fatal(err) + } +} + func TestCancel(t *testing.T) { - cancelResponse, err := dadaapi.CancelOrder("94065C161F8E11E9AAC8186590E02977", ReasonIDOther, "test") + cancelResponse, err := dadaapi.CancelOrder("91BBFE1626E011EAA059186590E02977", ReasonIDOther, "test") if err != nil { t.Fatal(err) } @@ -61,3 +87,18 @@ func TestComplaintRider(t *testing.T) { t.Fatal(err) } } + +func TestQueryOrderInfo2(t *testing.T) { + result, err := dadaapi.QueryOrderInfo2("80704840263399812") + if err != nil { + t.Fatal(err) + } + t.Log(utils.Format4Output(result, false)) +} + +func TestAddTip(t *testing.T) { + err := dadaapi.AddTip("80704840263399812", 1.0, "530100", "") + if err != nil { + t.Fatal(err) + } +} diff --git a/platformapi/mtpsapi/mtpsapi.go b/platformapi/mtpsapi/mtpsapi.go index 592332bd..7fb510ff 100644 --- a/platformapi/mtpsapi/mtpsapi.go +++ b/platformapi/mtpsapi/mtpsapi.go @@ -130,6 +130,8 @@ type ResponseResult struct { } type CreateOrderByShopParam struct { + // 以下为必要参数 + DeliveryID int64 `json:"delivery_id"` OrderID string `json:"order_id"` ShopID string `json:"shop_id"` @@ -139,11 +141,29 @@ type CreateOrderByShopParam struct { 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"` + + // 以下为可选参数 + + CoordinateType int `json:"coordinate_type"` + GoodsHeight float64 `json:"goods_height,omitempty"` + GoodsWidth float64 `json:"goods_width,omitempty"` + GoodsLength float64 `json:"goods_length,omitempty"` + GoodsDetail string `json:"goods_detail,omitempty"` + GoodsPickupInfo string `json:"goods_pickup_info,omitempty"` + GoodsDeliveryInfo string `json:"goods_delivery_info,omitempty"` + ExpectedPickupTime int64 `json:"expected_pickup_time,omitempty"` // 期望取货时间,时区为GMT+8,当前距离Epoch(1970年1月1日) 以秒计算的时间,即unix-timestamp。 + // 期望送达时间,时区为GMT+8,当前距离Epoch(1970年1月1日) 以秒计算的时间,即unix-timestamp + // 即时单:以发单时间 + 服务包时效作为期望送达时间(当天送服务包需客户指定期望送达时间) + // 预约单:以客户传参数据为准(预约时间必须大于当前下单时间+服务包时效+3分钟) + ExpectedDeliveryTime int64 `json:"expected_delivery_time,omitempty"` + OrderType int `json:"order_type,omitempty"` + PoiSeq string `json:"poi_seq,omitempty"` + Note string `json:"note,omitempty"` + CashOnDelivery float64 `json:"cash_on_delivery,omitempty"` + CashOnPickup float64 `json:"cash_on_pickup,omitempty"` + InvoiceTitle string `json:"invoice_title,omitempty"` } type GoodsItem struct { @@ -280,7 +300,7 @@ func (a *API) CreateOrderByShop(basicParams *CreateOrderByShopParam, addParams m allParams := utils.MergeMaps(params, addParams) if params["order_type"] != utils.Int2Str(OrderTypeBook) { - delete(params, "expected_delivery_time") + delete(allParams, "expected_delivery_time") } if result, err := a.AccessAPI("order/createByShop", allParams); err != nil { return nil, err @@ -289,6 +309,18 @@ func (a *API) CreateOrderByShop(basicParams *CreateOrderByShopParam, addParams m } } +func (a *API) CreateOrderByShop2(basicParams *CreateOrderByShopParam) (order *OrderResponse, err error) { + params := utils.Struct2MapByJson(basicParams) + if basicParams.OrderType != OrderTypeBook { + delete(params, "expected_delivery_time") + } + if result, err := a.AccessAPI("order/createByShop", params); 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, @@ -355,3 +387,18 @@ func (a *API) EvaluateRider(deliveryId int64, mtPeiSongId string, score int, com _, err = a.AccessAPI("order/evaluate", params) return err } + +// 获取骑手当前位置 +// https://peisong.meituan.com/open/doc#section2-9 +func (a *API) RiderLocation(deliveryId int64, mtPeiSongId string) (lng, lat int, err error) { + params := map[string]interface{}{ + "delivery_id": deliveryId, + "mt_peisong_id": mtPeiSongId, + } + result, err := a.AccessAPI("order/rider/location", params) + if err == nil { + lng = int(utils.ForceInterface2Int64(result.Data["lng"])) + lat = int(utils.ForceInterface2Int64(result.Data["lat"])) + } + return lng, lat, err +} diff --git a/platformapi/mtpsapi/mtpsapi_test.go b/platformapi/mtpsapi/mtpsapi_test.go index 02e17ebc..d06e2755 100644 --- a/platformapi/mtpsapi/mtpsapi_test.go +++ b/platformapi/mtpsapi/mtpsapi_test.go @@ -57,8 +57,33 @@ func TestAccessAPI(t *testing.T) { } } +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 := api.CreateOrderByShop2(basicParams) + handleError(t, err) + if order != nil { + sugarLogger.Debugf("order:%v", order) + } +} + func TestCancelOrder(t *testing.T) { - result, err := api.CancelOrder(123456789, "1529387562097059", CancelReasonMerchantOther, "just a test") + result, err := api.CancelOrder(123456789, "1577258173664001659", CancelReasonMerchantOther, "just a test") handleError(t, err) sugarLogger.Debug(result) } @@ -69,3 +94,11 @@ func TestEvaluateRider(t *testing.T) { t.Fatal(err) } } + +func TestRiderLocation(t *testing.T) { + lng, lat, err := api.RiderLocation(2997655, "1577100357518191619") + if err != nil { + t.Fatal(err) + } + t.Logf("lng:%d,lat:%d", lng, lat) +} diff --git a/platformapi/mtpsapi/shop_test.go b/platformapi/mtpsapi/shop_test.go index 5638cdc1..2074d170 100644 --- a/platformapi/mtpsapi/shop_test.go +++ b/platformapi/mtpsapi/shop_test.go @@ -13,31 +13,6 @@ func TestSimulateShopStatus(t *testing.T) { } } -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 := api.CreateOrderByShop(basicParams, nil) - handleError(t, err) - if order != nil { - sugarLogger.Debugf("order:%v", order) - } -} - func TestShopQuery(t *testing.T) { shopInfo, err := api.ShopQuery("not exist") if err == nil {