添加蜂鸟配送

This commit is contained in:
邹宗楠
2022-03-25 09:33:46 +08:00
parent c71429a3fd
commit c112e5e282
21 changed files with 2117 additions and 500 deletions

View File

@@ -1,102 +1,299 @@
package fnpsapi
import (
"encoding/json"
"errors"
"time"
"git.rosy.net.cn/baseapi/utils"
)
const (
OrderCancelReson1 = 1 // 1:物流原因:订单长时间未分配骑手,
OrderCancelReson2 = 2 // 2:物流原因:分配骑手后,骑手长时间未取件 ,
OrderCancelReson3 = 3 // 3:物流原因:骑手告知不配送,让取消订单,
OrderCancelReson0 = 0 // 0:其它(必填原因)必须填写原因
OrderCancelReson1 = 1 // 1:物流原因:订单长时间未分配骑手
OrderCancelReson4 = 4 // 4:商品缺货/无法出货/已售完,
OrderCancelReson5 = 5 // 5:商户联系不上门店/门店关门了,
OrderCancelReson6 = 6 // 6:商户发错单,
OrderCancelReson7 = 7 // 7:商户/顾客自身定位错误,
OrderCancelReson8 = 8 // 8:商户改其他第三方配送,
OrderCancelReson9 = 9 // 9:顾客下错单/临时不想要了,
OrderCancelReson10 = 10 // 10:顾客自取/不在家/要求另改时间配送0类型已下线
OrderCancelReson32 = 32 // 32:订单信息填写错误
OrderCancelReson36 = 36 // 36:重复下单了
OrderCancelReson2 = 2 // 2:物流原因:分配骑手后,骑手长时间未取件(类型已下线)
OrderCancelReson3 = 3 // 3:物流原因:骑手告知不配送,让取消订单(类型已下线)
OrderCancelReson5 = 5 // 5:商户联系不上门店/门店关门了(类型已下线)
OrderStatusAccept = 1 //系统已接单
OrderStatusAssigned = 20 //已分配骑手
OrderStatusArrived = 80 //已到店
OrderStatusDelivering = 2 //配送中
OrderStatusDelivered = 3 //已送达
OrderStatusException = 5 //异常
OrderStatusAcceptCreate = 0 //订单生成
OrderStatusAcceptCacle = 4 //订单取消
OrderStatusAccept = 1 //系统已接单
OrderStatusAssigned = 20 //已分配骑手
OrderStatusArrived = 80 //已到店
OrderStatusDelivering = 2 //配送中
OrderStatusDelivered = 3 //已送达
OrderStatusException = 5 //异常
)
type CreateOrderParam struct {
PartnerRemark string `json:"partner_remark,omitempty"`
PartnerOrderCode string `json:"partner_order_code,omitempty"`
NotifyURL string `json:"notify_url,omitempty"`
OrderType int `json:"order_type,omitempty"`
ChainStoreCode string `json:"chain_store_code,omitempty"`
TransportInfo *TransportInfo `json:"transport_info,omitempty"`
OrderAddTime int64 `json:"order_add_time,omitempty"`
OrderTotalAmount float64 `json:"order_total_amount,omitempty"`
OrderActualAmount float64 `json:"order_actual_amount,omitempty"`
OrderWeight float64 `json:"order_weight,omitempty"`
OrderRemark string `json:"order_remark,omitempty"`
IsInvoiced int `json:"is_invoiced"`
Invoice string `json:"invoice,omitempty"`
OrderPaymentStatus int `json:"order_payment_status,omitempty"`
OrderPaymentMethod int `json:"order_payment_method,omitempty"`
IsAgentPayment int `json:"is_agent_payment"`
RequirePaymentPay float64 `json:"require_payment_pay,omitempty"`
GoodsCount int `json:"goods_count,omitempty"`
RequireReceiveTime int64 `json:"require_receive_time,omitempty"`
SerialNumber string `json:"serial_number,omitempty"`
ReceiverInfo *ReceiverInfo `json:"receiver_info,omitempty"`
ItemsJSON []*ItemsJSON `json:"items_json,omitempty"`
OrderSource string `json:"order_source,omitempty"` //饿百订单传109
ChannelOrderCode string `json:"channel_order_code,omitempty"`
CookingTime int64 `json:"cooking_time,omitempty"`
PlatformPaidTime int64 `json:"platform_paid_time,omitempty"`
PlatformCreatedTime int64 `json:"platform_created_time,omitempty"`
MerchantCode string `json:"merchant_code,omitempty"`
//
//type CreateOrderParam struct {
// PartnerRemark string `json:"partner_remark,omitempty"`
// PartnerOrderCode string `json:"partner_order_code,omitempty"`
// NotifyURL string `json:"notify_url,omitempty"`
// OrderType int `json:"order_type,omitempty"`
// ChainStoreCode string `json:"chain_store_code,omitempty"`
// TransportInfo *TransportInfo `json:"transport_info,omitempty"`
// OrderAddTime int64 `json:"order_add_time,omitempty"`
// OrderTotalAmount float64 `json:"order_total_amount,omitempty"`
// OrderActualAmount float64 `json:"order_actual_amount,omitempty"`
// OrderWeight float64 `json:"order_weight,omitempty"`
// OrderRemark string `json:"order_remark,omitempty"`
// IsInvoiced int `json:"is_invoiced"`
// Invoice string `json:"invoice,omitempty"`
// OrderPaymentStatus int `json:"order_payment_status,omitempty"`
// OrderPaymentMethod int `json:"order_payment_method,omitempty"`
// IsAgentPayment int `json:"is_agent_payment"`
// RequirePaymentPay float64 `json:"require_payment_pay,omitempty"`
// GoodsCount int `json:"goods_count,omitempty"`
// RequireReceiveTime int64 `json:"require_receive_time,omitempty"`
// SerialNumber string `json:"serial_number,omitempty"`
// ReceiverInfo *ReceiverInfo `json:"receiver_info,omitempty"`
// ItemsJSON []*ItemsJSON `json:"items_json,omitempty"`
// OrderSource string `json:"order_source,omitempty"` //饿百订单传109
// ChannelOrderCode string `json:"channel_order_code,omitempty"`
// CookingTime int64 `json:"cooking_time,omitempty"`
// PlatformPaidTime int64 `json:"platform_paid_time,omitempty"`
// PlatformCreatedTime int64 `json:"platform_created_time,omitempty"`
// MerchantCode string `json:"merchant_code,omitempty"`
//}
//
//type ReceiverInfo struct {
// ReceiverName string `json:"receiver_name,omitempty"`
// ReceiverPrimaryPhone string `json:"receiver_primary_phone,omitempty"`
// ReceiverSecondPhone string `json:"receiver_second_phone,omitempty"`
// ReceiverAddress string `json:"receiver_address,omitempty"`
// ReceiverLongitude float64 `json:"receiver_longitude,omitempty"`
// ReceiverLatitude float64 `json:"receiver_latitude,omitempty"`
// PositionSource int `json:"position_source,omitempty"`
//}
//
//type TransportInfo struct {
// TransportName string `json:"transport_name,omitempty"`
// TransportAddress string `json:"transport_address,omitempty"`
// TransportLongitude float64 `json:"transport_longitude,omitempty"`
// TransportLatitude float64 `json:"transport_latitude,omitempty"`
// PositionSource int `json:"position_source,omitempty"`
// TransportTel string `json:"transport_tel,omitempty"`
// TransportRemark string `json:"transport_remark,omitempty"`
//}
//
//type ItemsJSON struct {
// ItemID string `json:"item_id,omitempty"`
// ItemName string `json:"item_name,omitempty"`
// ItemQuantity int `json:"item_quantity,omitempty"`
// ItemPrice float64 `json:"item_price"`
// ItemActualPrice float64 `json:"item_actual_price"`
// ItemSize int `json:"item_size,omitempty"`
// ItemRemark string `json:"item_remark,omitempty"`
// IsNeedPackage int `json:"is_need_package"`
// IsAgentPurchase int `json:"is_agent_purchase"`
// AgentPurchasePrice float64 `json:"agent_purchase_price,omitempty"`
//}
// 蜂鸟预下单
func (a *API) PreCreateByShopFn(basicParams *PreCreateOrder) (deliveryFee, baseDeliveryFee int64, err error) {
preOrder := a.MakeFnRequestHead()
bytes, err := json.Marshal(basicParams)
if err != nil {
return 0, 0, err
}
preOrder["business_data"] = string(bytes)
result, err := a.AccessAPI(ApiURL, "preCreateOrder", RequestPost, preOrder)
if err != nil {
return 0, 0, err
}
preOrderResult := PreCreateOrderResp{}
if err := json.Unmarshal([]byte(result["business_data"].(string)), &preOrderResult); err != nil {
return 0, 0, err
}
// 返回所有可选的商品列表,每项包含当前使用该商品下单时对应的价格等信息,(其中不可用的商品会返回不可用原因) 可挑选其中一个可用的商品进行正式下单。
for _, v := range preOrderResult.GoodsInfos {
if v.IsValid != 1 {
continue
}
deliveryFee = v.ActualDeliveryAmountCent
baseDeliveryFee = v.TotalDeliveryAmountCent
}
// 异常检测
if deliveryFee == 0 && baseDeliveryFee == 0 {
err = errors.New("门店数据异常")
}
return deliveryFee, baseDeliveryFee, nil
}
type ReceiverInfo struct {
ReceiverName string `json:"receiver_name,omitempty"`
ReceiverPrimaryPhone string `json:"receiver_primary_phone,omitempty"`
ReceiverSecondPhone string `json:"receiver_second_phone,omitempty"`
ReceiverAddress string `json:"receiver_address,omitempty"`
ReceiverLongitude float64 `json:"receiver_longitude,omitempty"`
ReceiverLatitude float64 `json:"receiver_latitude,omitempty"`
PositionSource int `json:"position_source,omitempty"`
}
type TransportInfo struct {
TransportName string `json:"transport_name,omitempty"`
TransportAddress string `json:"transport_address,omitempty"`
TransportLongitude float64 `json:"transport_longitude,omitempty"`
TransportLatitude float64 `json:"transport_latitude,omitempty"`
PositionSource int `json:"position_source,omitempty"`
TransportTel string `json:"transport_tel,omitempty"`
TransportRemark string `json:"transport_remark,omitempty"`
}
type ItemsJSON struct {
ItemID string `json:"item_id,omitempty"`
ItemName string `json:"item_name,omitempty"`
ItemQuantity int `json:"item_quantity,omitempty"`
ItemPrice float64 `json:"item_price"`
ItemActualPrice float64 `json:"item_actual_price"`
ItemSize int `json:"item_size,omitempty"`
ItemRemark string `json:"item_remark,omitempty"`
IsNeedPackage int `json:"is_need_package"`
IsAgentPurchase int `json:"is_agent_purchase"`
AgentPurchasePrice float64 `json:"agent_purchase_price,omitempty"`
}
//https://open.ele.me/documents/%E5%88%9B%E5%BB%BA%E8%9C%82%E9%B8%9F%E8%AE%A2%E5%8D%95
func (a *API) CreateOrder(createOrderParam *CreateOrderParam) (err error) {
params := utils.Struct2FlatMap(createOrderParam)
_, err = a.AccessAPI("v2/order", URL, params, true)
// 蜂鸟正式下单
func (a *API) CreateOrder(createOrderParam *CreateOrderReqParam) (err error) {
orderHead := a.MakeFnRequestHead()
bytes, err := json.Marshal(createOrderParam)
if err != nil {
return err
}
orderHead["business_data"] = string(bytes)
_, err = a.AccessAPI(ApiURL, "createOrder", RequestPost, orderHead)
return err
}
// addTip 加小费接口
func (a *API) AddTip(req *AddTipRes) (err error) {
if req.PartnerOrderCode == "" && req.OrderId == "" {
return errors.New("内部订单号或者外部订单号比填写一个")
}
orderHead := a.MakeFnRequestHead()
addTipString, err := json.Marshal(req)
if err != nil {
return err
}
orderHead["businessData"] = string(addTipString)
if _, err = a.AccessAPI(ApiURL, "addTip", RequestPost, orderHead); err != nil {
return err
}
return nil
}
// getCancelReasonList 获取可用取消原因列表(暂油前端写死)
func (a *API) GetCancelReasonList(req *GetOrderDetailReq) (result *GetCancelReasonListRes, err error) {
if req.PartnerOrderCode == "" && req.OrderId == "" {
return nil, errors.New("内部订单号或者外部订单号比填写一个")
}
a.timestamp = time.Now().Unix() * 1000
orderHead := a.MakeFnRequestHead()
business, err := json.Marshal(req)
if err != nil {
return nil, err
}
orderHead["businessData"] = string(business)
data, err := a.AccessAPI(ApiURL, "getCancelReasonList", RequestPost, orderHead)
if err != nil {
return nil, err
}
cancel := make(map[string]*GetCancelReasonListRes, 0)
if k, ok := data["business_data"]; ok {
if err := json.Unmarshal([]byte(utils.Interface2String(k)), cancel); err != nil {
return nil, err
}
}
return cancel["cancel_reason_list"], nil
}
// preCancelOrder 预取消订单接口,获取取消订单需要扣除的金额
func (a *API) PreCancelOrder(req *PreCancelOrderReq) (actualCancelCostCent int64, err error) {
if req.PartnerOrderCode == "" && req.OrderId == "" {
return 0, errors.New("内部订单号或者外部订单号比填写一个")
}
orderHead := a.MakeFnRequestHead()
business, err := json.Marshal(req)
if err != nil {
return 0, err
}
orderHead["businessData"] = string(business)
data, err := a.AccessAPI(ApiURL, "preCancelOrder", RequestPost, orderHead)
if err != nil {
return 0, err
}
if k, ok := data["businessData"]; ok {
respParam := struct {
ActualCancelCostCent int64 `json:"actual_cancel_cost_cent"`
}{}
if err := json.Unmarshal([]byte(utils.Interface2String(k)), respParam); err != nil {
return 0, err
}
return respParam.ActualCancelCostCent, nil
}
return
}
// cancelOrder 取消订单
func (a *API) CancelOrder(req *CancelOrderReq) (err error) {
if req.PartnerOrderCode == "" && req.OrderId == "" {
return errors.New("内部订单号或者外部订单号比填写一个")
}
if req.OrderCancelCode == 0 && req.OrderCancelOtherReason == "" {
return errors.New("请补充退单原因")
}
orderHead := a.MakeFnRequestHead()
business, err := json.Marshal(req)
if err != nil {
return err
}
orderHead["business_data"] = string(business)
if _, err := a.AccessAPI(ApiURL, "cancelOrder", RequestPost, orderHead); err != nil {
return err
}
return
}
// 查询订单详情接口 todo
func (a *API) QueryOrder(partnerOrderCode string) (result *GetOrderDetailRes, err error) {
orderHead := a.MakeFnRequestHead()
orderHead["business_data"] = partnerOrderCode
data, err := a.AccessAPI(ApiURL, "getOrderDetail", RequestPost, orderHead)
if err != nil {
return nil, err
}
if err := json.Unmarshal([]byte(data["business_data"].(string)), &result); err != nil {
return nil, err
}
return
}
// 查询骑手信息
func (a *API) GetKnightInfo(req *GetOrderDetailReq) (result *GetKnightInfoRes, err error) {
if req.PartnerOrderCode == "" && req.OrderId == "" {
return nil, errors.New("内部订单号或者外部订单号比填写一个")
}
orderHead := a.MakeFnRequestHead()
bytes, err := json.Marshal(req)
if err != nil {
return nil, err
}
orderHead["business_data"] = string(bytes)
data, err := a.AccessAPI(ApiURL, "getKnightInfo", RequestPost, orderHead)
if err != nil {
return nil, err
}
if err := json.Unmarshal([]byte(utils.Interface2String(data["business_data"])), &result); err != nil {
return nil, err
}
return
}
// 余额查询
func (a *API) GetAmount() (outAmount map[string]interface{}, err error) {
orderHead := a.MakeFnRequestHead()
result, err := a.AccessAPI(ApiURL, "getAmount", RequestPost, orderHead)
if err != nil {
return nil, err
}
return result, err
}
//order_cancel_reason_code 订单取消原因代码(1:用户取消,2:商家取消)
// order_cancel_code 订单取消编码(
// 1:物流原因:订单长时间未分配骑手,
@@ -106,70 +303,69 @@ func (a *API) CreateOrder(createOrderParam *CreateOrderParam) (err error) {
// 7:商户/顾客自身定位错误, 8:商户改其他第三方配送, 9:顾客下错单/临时不想要了,
// 10:顾客自取/不在家/要求另改时间配送0类型已下线
type CancelOrderParam struct {
PartnerOrderCode string `json:"partner_order_code,omitempty"`
OrderCancelReasonCode int `json:"order_cancel_reason_code,omitempty"`
OrderCancelCode int `json:"order_cancel_code,omitempty"`
OrderCancelDescription string `json:"order_cancel_description,omitempty"`
OrderCancelTime int64 `json:"order_cancel_time,omitempty"`
}
//type CancelOrderParam struct {
// PartnerOrderCode string `json:"partner_order_code,omitempty"`
// OrderCancelReasonCode int `json:"order_cancel_reason_code,omitempty"`
// OrderCancelCode int `json:"order_cancel_code,omitempty"`
// OrderCancelDescription string `json:"order_cancel_description,omitempty"`
// OrderCancelTime int64 `json:"order_cancel_time,omitempty"`
//}
func (a *API) CancelOrder(cancelOrderParam *CancelOrderParam) (err error) {
params := utils.Struct2FlatMap(cancelOrderParam)
_, err = a.AccessAPI("v2/order/cancel", URL, params, true)
return err
}
func (a *API) ComplaintOrder(cancelOrderParam *CancelOrderParam) (err error) {
params := utils.Struct2FlatMap(cancelOrderParam)
_, err = a.AccessAPI("v2/order/complaint", URL, params, true)
return err
}
type QueryOrderResult struct {
AbnormalCode string `json:"abnormal_code"`
AbnormalDesc string `json:"abnormal_desc"`
CarrierDriverID int `json:"carrier_driver_id"`
CarrierDriverName string `json:"carrier_driver_name"`
CarrierDriverPhone string `json:"carrier_driver_phone"`
ComplaintDescription interface{} `json:"complaintDescription"`
ComplaintStatus interface{} `json:"complaintStatus"`
EstimateArriveTime int64 `json:"estimate_arrive_time"`
EventLogDetails []struct {
CarrierDriverName string `json:"carrier_driver_name"`
CarrierDriverPhone string `json:"carrier_driver_phone"`
OccurTime int64 `json:"occur_time"`
OrderStatus int `json:"order_status"`
} `json:"event_log_details"`
HandleID interface{} `json:"handleId"`
OrderID interface{} `json:"orderId"`
OrderStatus int `json:"order_status"`
OrderTotalDeliveryCost float64 `json:"order_total_delivery_cost"`
OrderTotalDeliveryDiscount interface{} `json:"order_total_delivery_discount"`
OvertimeCompensationCost float64 `json:"overtime_compensation_cost"`
Reason string `json:"reason"`
SupportClaims bool `json:"support_claims"`
TrackingID int64 `json:"trackingId"`
TrackingID2 int64 `json:"tracking_id"`
TransportStationID string `json:"transport_station_id"`
TransportStationTel string `json:"transport_station_tel"`
}
func (a *API) QueryOrder(partnerOrderCode string) (queryOrderResult *QueryOrderResult, err error) {
result, err := a.AccessAPI("v2/order/query", URL, map[string]interface{}{
"partner_order_code": partnerOrderCode,
}, true)
if err == nil {
utils.Map2StructByJson(result["data"], &queryOrderResult, false)
func (a *API) ComplaintOrder(req *ComplaintOrderReq) (err error) {
if req.PartnerOrderCode == "" && req.OrderId == "" {
return errors.New("内部订单号或者外部订单号比填写一个")
}
return queryOrderResult, err
orderHead := a.MakeFnRequestHead()
bytes, err := json.Marshal(req)
if err != nil {
return err
}
orderHead["businessData"] = string(bytes)
_, err = a.AccessAPI(ApiURL, "cancelOrder", RequestPost, orderHead)
return err
}
//
//type QueryOrderResult struct {
// AbnormalCode string `json:"abnormal_code"`
// AbnormalDesc string `json:"abnormal_desc"`
// CarrierDriverID int `json:"carrier_driver_id"`
// CarrierDriverName string `json:"carrier_driver_name"`
// CarrierDriverPhone string `json:"carrier_driver_phone"`
// ComplaintDescription interface{} `json:"complaintDescription"`
// ComplaintStatus interface{} `json:"complaintStatus"`
// EstimateArriveTime int64 `json:"estimate_arrive_time"`
// EventLogDetails []struct {
// CarrierDriverName string `json:"carrier_driver_name"`
// CarrierDriverPhone string `json:"carrier_driver_phone"`
// OccurTime int64 `json:"occur_time"`
// OrderStatus int `json:"order_status"`
// } `json:"event_log_details"`
// HandleID interface{} `json:"handleId"`
// OrderID interface{} `json:"orderId"`
// OrderStatus int `json:"order_status"`
// OrderTotalDeliveryCost float64 `json:"order_total_delivery_cost"`
// OrderTotalDeliveryDiscount interface{} `json:"order_total_delivery_discount"`
// OvertimeCompensationCost float64 `json:"overtime_compensation_cost"`
// Reason string `json:"reason"`
// SupportClaims bool `json:"support_claims"`
// TrackingID int64 `json:"trackingId"`
// TrackingID2 int64 `json:"tracking_id"`
// TransportStationID string `json:"transport_station_id"`
// TransportStationTel string `json:"transport_station_tel"`
//}
func (a *API) ComplaintRider(partnerOrderCode string, orderComplaintCode int) (err error) {
_, err = a.AccessAPI("v2/order/complaint", URL, map[string]interface{}{
orderHead := a.MakeFnRequestHead()
bytes, err := json.Marshal(map[string]interface{}{
"partner_order_code": partnerOrderCode,
"order_complaint_code": orderComplaintCode,
"order_complaint_time": time.Now().UnixNano() / 1e6,
}, true)
})
if err != nil {
return err
}
orderHead["businessData"] = string(bytes)
_, err = a.AccessAPI(ApiURL, "cancelOrder", RequestPost, orderHead)
return err
}