497 lines
25 KiB
Go
497 lines
25 KiB
Go
package jdeclpapi
|
||
|
||
import (
|
||
"crypto/md5"
|
||
"fmt"
|
||
"net/http"
|
||
"sort"
|
||
"strings"
|
||
"time"
|
||
|
||
"git.rosy.net.cn/baseapi/platformapi"
|
||
"git.rosy.net.cn/baseapi/utils"
|
||
)
|
||
|
||
const (
|
||
prodURL = "https://api.jd.com/routerjson"
|
||
prodURL2 = "https://oauth.jd.com/oauth"
|
||
|
||
sigKey = "sign"
|
||
IsvSource = "ISV0020000000068"
|
||
DepartmentNo = "EBU4418046609452"
|
||
ShipperNo = "CYS4398046511104"
|
||
ShopNo = "ESP0020000066348"
|
||
WarehouseNo = "110014006"
|
||
CustomerCode = "028K595510"
|
||
OrderMark = "00000000000000000000000000000000000000000000000000"
|
||
|
||
// CustomerCode2 = "028K588716"
|
||
|
||
state = "1212"
|
||
orderType10 = "10" //订单号类型(10:代表ECLP订单号, 20:代表商家订单号)
|
||
orderType20 = "20"
|
||
SalePlatformSource = "6"
|
||
SalePlatSourceDelivery = "0030001"
|
||
|
||
SoStatusCode10010 = "10010" //订单初始化
|
||
SoStatusCode10022 = "10022" //暂停
|
||
SoStatusCode10014 = "10014" //已下发库房
|
||
SoStatusCode10015 = "10015" //任务已分配
|
||
SoStatusCode10016 = "10016" //拣货下架
|
||
SoStatusCode10019 = "10019" //交接发货
|
||
SoStatusCode10018 = "10018" //货品已打包
|
||
SoStatusCode10017 = "10017" //复核
|
||
SoStatusCode10054 = "10054" //分拣中心发货
|
||
SoStatusCode10033 = "10033" //站点验收
|
||
SoStatusCode10034 = "10034" //妥投
|
||
SoStatusCode10038 = "10038" //逆向完成
|
||
|
||
TraceInfoStateM625 = "-625" //揽收任务分配
|
||
TraceInfoStateM190 = "-190" //上门接货
|
||
TraceInfoStateM640 = "-640" //配送员完成揽收
|
||
TraceInfoStateM170 = "-170" //分拣中心收货
|
||
TraceInfoStateM790 = "-790" //下单取消
|
||
TraceInfoStateM650 = "-650" //终止揽收
|
||
|
||
TraceInfoState200 = "200" //站点装箱发货
|
||
TraceInfoState10 = "10" //分拣中心验货
|
||
TraceInfoState13 = "13" //分拣中心分拣
|
||
TraceInfoState16 = "16" //分拣中心发货
|
||
TraceInfoState60 = "60" //站点收货
|
||
TraceInfoState80 = "80" //站点验货
|
||
TraceInfoState110 = "110" //配送员收货
|
||
TraceInfoState150 = "150" //妥投
|
||
)
|
||
|
||
type API struct {
|
||
accessToken string
|
||
appKey string
|
||
appSecret string
|
||
client *http.Client
|
||
config *platformapi.APIConfig
|
||
}
|
||
|
||
type QuerySpSourceResult struct {
|
||
Website string `json:"website"` //销售平台网址
|
||
SpSourceName string `json:"spSourceName"` //销售平台名称
|
||
SpSourceNo string `json:"spSourceNo"` //销售平台编号(必填,长度:20)
|
||
Reserve5 string `json:"reserve5"`
|
||
Reserve4 string `json:"reserve4"`
|
||
Reserve3 string `json:"reserve3"`
|
||
Reserve2 string `json:"reserve2"`
|
||
Reserve1 string `json:"reserve1"` //预留字段1
|
||
}
|
||
|
||
type AddOrderParam struct {
|
||
IsvUUID string `json:"isvUUID"` //isv出库单号(商家出库单号),作为isv出库的唯一性校验码:长度不能超125
|
||
IsvSource string `json:"isvSource"` //ISV来源编号
|
||
ShopNo string `json:"shopNo"` //店铺编号(B2C订单必填,B2B(soType=2)订单非必填)
|
||
DepartmentNo string `json:"departmentNo"` //事业部编号,且与pin匹配
|
||
WarehouseNo string `json:"warehouseNo"` //库房编号,事业部开启寻源拆分服务可不填;否则必填;
|
||
ShipperNo string `json:"shipperNo"` //承运商编号
|
||
SalesPlatformOrderNo string `json:"salesPlatformOrderNo"` //销售平台订单号,如果销售平台来源为京东平台,则该字段不能为空,长度不超过200
|
||
SalePlatformSource string `json:"salePlatformSource"` //销售平台来源
|
||
ConsigneeName string `json:"consigneeName"` //收货人姓名,长度不能超20
|
||
ConsigneeMobile string `json:"consigneeMobile"` //收货人手机(收货人电话、手机至少有一个不为空),长度不能超30
|
||
ConsigneeAddress string `json:"consigneeAddress"` //收货人地址 ,长度不能超100
|
||
OrderMark string `json:"orderMark"` //订单标记位,首位为1代表货到付款
|
||
GoodsNo string `json:"goodsNo"` //ECLP商品编号,与商家商品编号二选一必填(两者都指定,以goodsNo为准)
|
||
Price string `json:"price"` //商品金额,会在订单面单上线上商品单价
|
||
Quantity string `json:"quantity"` //商品的出库数量,必须>0
|
||
// IsvGoodsNo string `json:"isvGoodsNo"` //商家商品编码
|
||
}
|
||
|
||
type AddOrderResult struct {
|
||
EclpSoNo string `json:"eclpSoNo"` //订单的出库单号
|
||
}
|
||
|
||
type CancelOrderResult struct {
|
||
Code string `json:"code"`
|
||
Msg string `json:"msg"`
|
||
}
|
||
|
||
type QueryOrderStatusResult struct {
|
||
OrderStatusList []struct {
|
||
SoStatusCode string `json:"soStatusCode"`
|
||
OperateTime string `json:"operateTime"`
|
||
SoStatusName string `json:"soStatusName"`
|
||
OperateUser string `json:"operateUser"`
|
||
} `json:"orderStatusList"`
|
||
IsvUUID string `json:"isvUUID"`
|
||
EclpSoNo string `json:"eclpSoNo"`
|
||
}
|
||
|
||
type GetTrackMessagePlusByOrderResult struct {
|
||
ResultData []struct {
|
||
OpeTitle string `json:"opeTitle"`
|
||
OpeTime string `json:"opeTime"`
|
||
OpeRemark string `json:"opeRemark"`
|
||
OpeName string `json:"opeName"`
|
||
WaybillCode string `json:"waybillCode"`
|
||
} `json:"resultData"`
|
||
ResultCode string `json:"resultCode"`
|
||
ResultMessage string `json:"resultMessage"`
|
||
}
|
||
|
||
type SearchShopStockParam struct {
|
||
RequestId string `json:"requestId"`
|
||
DeptNo string `json:"deptNo"`
|
||
ShopNo string `json:"shopNo"`
|
||
GoodsNo string `json:"goodsNo"`
|
||
PageSize int `json:"pageSize"`
|
||
PageNumber int `json:"pageNumber"`
|
||
}
|
||
|
||
type SearchShopStockResult struct {
|
||
PageCount string `json:"pageCount"`
|
||
ResponseCode string `json:"responseCode"`
|
||
RequestID string `json:"requestId"`
|
||
ErrMsg string `json:"errMsg"`
|
||
Data []struct {
|
||
DeptNo string `json:"deptNo"`
|
||
StockNum string `json:"stockNum"`
|
||
GoodsNo string `json:"goodsNo"`
|
||
WarehouseNo string `json:"warehouseNo"`
|
||
ShopNo string `json:"shopNo"`
|
||
} `json:"data"`
|
||
PageSize string `json:"pageSize"`
|
||
PageNumber string `json:"pageNumber"`
|
||
}
|
||
|
||
type QueryStockResult struct {
|
||
RecordCount int `json:"recordCount"`
|
||
IsvSku string `json:"isvSku"`
|
||
DeptName string `json:"deptName"`
|
||
SellerGoodsSign string `json:"sellerGoodsSign"`
|
||
GoodsNo string `json:"goodsNo"`
|
||
UsableNum int `json:"usableNum"`
|
||
DeptNo string `json:"deptNo"`
|
||
WarehouseName string `json:"warehouseName"`
|
||
TotalNum int `json:"totalNum"`
|
||
StockType string `json:"stockType"`
|
||
StockStatus string `json:"stockStatus"`
|
||
GoodsLevel string `json:"goodsLevel"`
|
||
WarehouseNo string `json:"warehouseNo"`
|
||
GoodsName string `json:"goodsName"`
|
||
}
|
||
|
||
type WaybillReceiveParam struct {
|
||
SalePlat string `json:"salePlat"` //是 无 销售平台
|
||
CustomerCode string `json:"customerCode"` //是 无 商家编码
|
||
OrderID string `json:"orderId"` //是 无 订单号
|
||
// ThrOrderID string `json:"thrOrderId"` //否 无 销售平台订单号(例如京东订单号或天猫订单号等等。总长度不要超过100。如果有多个单号,用英文,间隔。例如:7898675,7898676)
|
||
SenderName string `json:"senderName"` //是 无 寄件人姓名,说明:不能为生僻字
|
||
SenderAddress string `json:"senderAddress"` //是 无 寄件人地址,说明:不能为生僻字
|
||
SenderTel string `json:"senderTel"` //否 无 寄件人电话
|
||
// SenderMobile string `json:"senderMobile"` //否 无 寄件人手机(寄件人电话、手机至少有一个不为空)
|
||
// SenderPostcode string `json:"senderPostcode"` //否 100000 寄件人邮编,长度:6位
|
||
ReceiveName string `json:"receiveName"` //是 无 收件人名称,说明:不能为生僻字
|
||
ReceiveAddress string `json:"receiveAddress"` //是 无 收件人地址,说明:不能为生僻字
|
||
// Province string `json:"province"` //否 无 收件人省
|
||
// City string `json:"city"` //否 无 收件人市
|
||
// County string `json:"county"` //否 无 收件人县
|
||
// Town string `json:"town"` //否 无 收件人镇
|
||
// ProvinceID int `json:"provinceId"` //否 无 收件人省编码
|
||
// CityID int `json:"cityId"` //否 无 收件人市编码
|
||
// CountyID int `json:"countyId"` //否 无 收件人县编码
|
||
// TownID int `json:"townId"` //否 无 收件人镇编码
|
||
// SiteType int `json:"siteType"` //否 无 站点类型
|
||
// SiteID int `json:"siteId"` //否 无 站点编码
|
||
// SiteName string `json:"siteName"` //否 无 站点名称
|
||
ReceiveTel string `json:"receiveTel"` //否 无 收件人电话
|
||
// ReceiveMobile string `json:"receiveMobile"` //否 无 收件人手机号(收件人电话、手机至少有一个不为空)
|
||
// Postcode string `json:"postcode"` //否 100000 收件人邮编,长度:6
|
||
PackageCount int `json:"packageCount"` //是 无 包裹数(大于0,小于1000)
|
||
Weight float64 `json:"weight"` //是 2.5 重量(单位:kg,保留小数点后两位)
|
||
// VloumLong int `json:"vloumLong"` //否 无 包裹长(单位:cm,保留小数点后两位)
|
||
// VloumWidth int `json:"vloumWidth"` //否 无 包裹宽(单位:cm,保留小数点后两位)
|
||
// VloumHeight int `json:"vloumHeight"` //否 无 包裹高(单位:cm,保留小数点后两位)
|
||
Vloumn float64 `json:"vloumn"` //是 10000 体积(单位:cm3,保留小数点后两位)
|
||
Description string `json:"description,omitempty"` //否 无 商品描述
|
||
// CollectionValue int `json:"collectionValue"` //否 1 是否代收货款(是:1,否:0。不填或者超出范围,默认是0)
|
||
// CollectionMoney int `json:"collectionMoney"` //否 98.00 代收货款金额(保留小数点后两位)
|
||
// GuaranteeValue int `json:"guaranteeValue"` //否 1 是否保价(是:1,否:0。不填或者超出范围,默认是0)
|
||
// GuaranteeValueAmount int `json:"guaranteeValueAmount"` //否 100.00 保价金额(保留小数点后两位)
|
||
// SignReturn int `json:"signReturn"` //否 1 签单返还(签单返还类型:0 不返单,1 普通返单,2 校验身份返单,3 电子签返单,4 电子返单+普通返单)
|
||
Aging int `json:"aging"` //否 1 时效(普通:1,工作日:2,非工作日:3,晚间:4。O2O一小时达:5。O2O定时达:6。不填或者超出范围,默认是1)
|
||
// TransType int `json:"transType"` //否 1 运输类型(陆运:1,航空:2。不填或者超出范围,默认是1)
|
||
// Remark string `json:"remark"` //否 无 运单备注,长度:20,说明:打印面单时备注内容也会显示在快递面单上
|
||
// GoodsType int `json:"goodsType"` //否 无 配送业务类型( 1:普通,3:填仓,4:特配,6:控温,7:冷藏,8:冷冻,9:深冷)默认是1
|
||
// OrderType int `json:"orderType"` //否 无 运单类型。(普通外单:0,O2O外单:1)默认为0
|
||
// ShopCode string `json:"shopCode"` //否 无 门店编码(只O2O运单需要传,普通运单不需要传)
|
||
// OrderSendTime string `json:"orderSendTime"` //否 2014 09 18 08:30:00 预约配送时间(格式:yyyy MM dd HH:mm:ss)
|
||
// WarehouseCode string `json:"warehouseCode"` //否 无 发货仓编码
|
||
// AreaProvID int `json:"areaProvId"` //否 无 接货省ID
|
||
// AreaCityID int `json:"areaCityId"` //否 无 接货市ID
|
||
// ShipmentStartTime time.Time `json:"shipmentStartTime"` //否 1 配送起始时间
|
||
// ShipmentEndTime time.Time `json:"shipmentEndTime"` //否 1 配送结束时间
|
||
// Idint string `json:"idint"` //否 无 身份证号
|
||
// AddedService string `json:"addedService"` //否 无 扩展服务
|
||
// ExtendField1 string `json:"extendField1"` //否 无 扩展字段1
|
||
// ExtendField2 string `json:"extendField2"` //否 无 扩展字段2
|
||
// ExtendField3 string `json:"extendField3"` //否 无 扩展字段3
|
||
// ExtendField4 int `json:"extendField4"` //否 无 扩展字段4
|
||
// ExtendField5 int `json:"extendField5"` //否 无 扩展字段5
|
||
// SenderCompany string `json:"senderCompany"` //否 北京市大兴区亦庄经济开发区京东大厦 寄件人公司,长度:50,说明:不能为生僻字
|
||
// ReceiveCompany string `json:"receiveCompany"` //否 北京市大兴区亦庄经济开发区京东大厦 收件人公司,长度:50,说明:不能为生僻字
|
||
// Goods string `json:"goods"` //否 服装、3C等 托寄物名称,长度:200,说明:为避免托运物品在铁路、航空安检中被扣押,请务必下传商品类目或名称,例如:服装、3C等
|
||
// GoodsCount int `json:"goodsCount"` //否 无 寄托物数量
|
||
PromiseTimeType int `json:"promiseTimeType"` //否 无 产品类型(1:特惠送 2:特快送 4:城际闪送 5:同城当日达 6:次晨达 7:微小件 8: 生鲜专送 16:生鲜特快 17、生鲜特惠 21:特惠小包)
|
||
// Freight int `json:"freight"` //否 无 运费
|
||
PickUpStartTime time.Time `json:"pickUpStartTime,omitempty"` //否 1 预约取件开始时间
|
||
PickUpEndTime time.Time `json:"pickUpEndTime,omitempty"` //否 1 预约取件结束时间
|
||
// UnpackingInspection string `json:"unpackingInspection"` //否 无 开箱验货标识
|
||
// BoxCode []string `json:"boxCode"` //否 无 商家箱号,多个箱号请用逗号分隔,例如三个箱号为:a123,b456,c789
|
||
// FileURL string `json:"fileUrl"` //否 无 文件url
|
||
}
|
||
|
||
type CancelWayBillParam struct {
|
||
// UserPin string `json:"userPin"` //否 pin 用户唯一标识,与下单一致可不填写
|
||
WaybillCode string `json:"waybillCode"` //是 VA12345678 运单号
|
||
CustomerCode string `json:"customerCode"` //是 010K00000 商家编码
|
||
Source string `json:"source"` //是 JOS 来源
|
||
CancelReason string `json:"cancelReason"` //是 客户取消 取消原因
|
||
OperatorName string `json:"operatorName"` //是 张三 操作人
|
||
}
|
||
|
||
func New(accessToken, appKey, appSecret string, config ...*platformapi.APIConfig) *API {
|
||
curConfig := platformapi.DefAPIConfig
|
||
if len(config) > 0 {
|
||
curConfig = *config[0]
|
||
}
|
||
return &API{
|
||
accessToken: accessToken,
|
||
appKey: appKey,
|
||
appSecret: appSecret,
|
||
client: &http.Client{Timeout: curConfig.ClientTimeout},
|
||
config: &curConfig,
|
||
}
|
||
}
|
||
|
||
func (a *API) signParam(params map[string]interface{}) (sig string) {
|
||
var valueList []string
|
||
for k, v := range params {
|
||
if k != sigKey {
|
||
if str := fmt.Sprint(v); str != "" {
|
||
valueList = append(valueList, fmt.Sprintf("%s%s", k, str))
|
||
}
|
||
}
|
||
}
|
||
sort.Sort(sort.StringSlice(valueList))
|
||
valueList = append(valueList, fmt.Sprintf("%s", a.appSecret))
|
||
var valueList2 = make([]string, len(valueList)+1)
|
||
at := copy(valueList2, valueList[:0])
|
||
at += copy(valueList2[at:], []string{a.appSecret})
|
||
copy(valueList2[at:], valueList[0:])
|
||
sig = strings.Join(valueList2, "")
|
||
binSig := md5.Sum([]byte(sig))
|
||
sig = fmt.Sprintf("%X", binSig)
|
||
return sig
|
||
}
|
||
|
||
func (a *API) AccessAPI(action string, url string, bizParams map[string]interface{}) (retVal map[string]interface{}, err error) {
|
||
params := make(map[string]interface{})
|
||
var fullURL string
|
||
if url == prodURL2 {
|
||
params = utils.MergeMaps(params, bizParams)
|
||
fullURL = utils.GenerateGetURL(url, action, nil)
|
||
} else {
|
||
params["access_token"] = a.accessToken
|
||
params["app_key"] = a.appKey
|
||
params["timestamp"] = utils.Time2Str(time.Now())
|
||
params["method"] = action
|
||
params["v"] = "2.0"
|
||
params = utils.MergeMaps(params, bizParams)
|
||
signStr := a.signParam(params)
|
||
params["sign"] = signStr
|
||
fullURL = utils.GenerateGetURL(url, "", nil)
|
||
}
|
||
err = platformapi.AccessPlatformAPIWithRetry(a.client,
|
||
func() *http.Request {
|
||
request, _ := http.NewRequest(http.MethodPost, fullURL, strings.NewReader(utils.Map2URLValues(params).Encode()))
|
||
request.Header.Set("charset", "UTF-8")
|
||
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||
return request
|
||
},
|
||
a.config,
|
||
func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) {
|
||
if jsonResult1 == nil {
|
||
return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil")
|
||
}
|
||
if err == nil {
|
||
if jsonResult1["error_response"] != nil {
|
||
errLevel = platformapi.ErrLevelGeneralFail
|
||
err = utils.NewErrorCode(jsonResult1["error_response"].(map[string]interface{})["zh_desc"].(string), jsonResult1["error_response"].(map[string]interface{})["code"].(string))
|
||
}
|
||
retVal = jsonResult1
|
||
}
|
||
return errLevel, err
|
||
})
|
||
return retVal, err
|
||
}
|
||
|
||
//获取销售平台信息
|
||
//https://open.jd.com/home/home#/doc/api?apiCateId=138&apiId=947&apiName=jingdong.eclp.master.querySpSource
|
||
func (a *API) QuerySpSource() (querySpSourceResult []*QuerySpSourceResult, err error) {
|
||
result, err := a.AccessAPI("jingdong.eclp.master.querySpSource", prodURL, nil)
|
||
if err == nil {
|
||
utils.Map2StructByJson(result["jingdong_eclp_master_querySpSource_responce"].(map[string]interface{})["queryspsource_result"], &querySpSourceResult, false)
|
||
}
|
||
return querySpSourceResult, err
|
||
}
|
||
|
||
//销售出库单下发
|
||
//https://open.jd.com/home/home#/doc/api?apiCateId=138&apiId=928&apiName=jingdong.eclp.order.addOrder
|
||
func (a *API) AddOrder(addOrderParam *AddOrderParam) (eclpSoNo string, err error) {
|
||
result, err := a.AccessAPI("jingdong.eclp.order.addOrder", prodURL, utils.Struct2FlatMap(addOrderParam))
|
||
if err == nil {
|
||
return result["jingdong_eclp_order_addOrder_responce"].(map[string]interface{})["eclpSoNo"].(string), err
|
||
}
|
||
return "", err
|
||
}
|
||
|
||
//销售出库单取消
|
||
//https://open.jd.com/home/home#/doc/api?apiCateId=138&apiId=957&apiName=jingdong.eclp.order.cancelOrder
|
||
func (a *API) CancelOrder(eclpSoNo string) (cancelOrderResult *CancelOrderResult, err error) {
|
||
result, err := a.AccessAPI("jingdong.eclp.order.cancelOrder", prodURL, map[string]interface{}{
|
||
"eclpSoNo": eclpSoNo,
|
||
})
|
||
if err == nil {
|
||
utils.Map2StructByJson(result["jingdong_eclp_order_cancelOrder_responce"].(map[string]interface{})["cancelorder_result"], &cancelOrderResult, false)
|
||
}
|
||
return cancelOrderResult, err
|
||
}
|
||
|
||
//销售出库单状态查询
|
||
//https://jos.jd.com/api/detail.htm?apiName=jingdong.eclp.order.queryOrderStatus&id=929
|
||
func (a *API) QueryOrderStatus(eclpSoNo string) (queryOrderStatus *QueryOrderStatusResult, err error) {
|
||
result, err := a.AccessAPI("jingdong.eclp.order.queryOrderStatus", prodURL, map[string]interface{}{
|
||
"eclpSoNo": eclpSoNo,
|
||
})
|
||
if err == nil {
|
||
utils.Map2StructByJson(result["jingdong_eclp_order_queryOrderStatus_responce"].(map[string]interface{})["queryorderstatus_result"], &queryOrderStatus, false)
|
||
}
|
||
return queryOrderStatus, err
|
||
}
|
||
|
||
//查询物流跟踪消息
|
||
//https://open.jd.com/home/home#/doc/api?apiCateId=138&apiId=2378&apiName=jingdong.eclp.order.getTrackMessagePlusByOrder
|
||
func (a *API) GetTrackMessagePlusByOrder(bizCode string) (getTrackMessagePlusByOrderResult *GetTrackMessagePlusByOrderResult, err error) {
|
||
result, err := a.AccessAPI("jingdong.eclp.order.getTrackMessagePlusByOrder", prodURL, map[string]interface{}{
|
||
"bizCode": bizCode,
|
||
"customerCode": CustomerCode,
|
||
"type": orderType20,
|
||
})
|
||
if err == nil {
|
||
utils.Map2StructByJson(result["jingdong_eclp_order_getTrackMessagePlusByOrder_responce"].(map[string]interface{})["getTrackMessagePlusByOrder_result"], &getTrackMessagePlusByOrderResult, false)
|
||
}
|
||
return getTrackMessagePlusByOrderResult, err
|
||
}
|
||
|
||
//查询仓库商品库存
|
||
//https://open.jd.com/home/home#/doc/api?apiCateId=138&apiId=3396&apiName=jingdong.eclp.stock.searchShopStock
|
||
func (a *API) SearchShopStock(goodsNo string) (searchShopStockResult *SearchShopStockResult, err error) {
|
||
params := map[string]interface{}{
|
||
"requestId": utils.GetUUID(),
|
||
"deptNo": DepartmentNo,
|
||
"shopNo": ShopNo,
|
||
"pageSize": 100,
|
||
"pageNumber": 1,
|
||
}
|
||
if goodsNo != "" {
|
||
params["goodsNo"] = goodsNo
|
||
}
|
||
result, err := a.AccessAPI("jingdong.eclp.stock.searchShopStock", prodURL, params)
|
||
if err == nil {
|
||
utils.Map2StructByJson(result["jingdong_eclp_stock_searchShopStock_responce"].(map[string]interface{})["shopStockSearchResponse"], &searchShopStockResult, false)
|
||
}
|
||
return searchShopStockResult, err
|
||
}
|
||
|
||
//查询仓库商品库存
|
||
//https://open.jd.com/home/home#/doc/api?apiCateId=138&apiId=3396&apiName=jingdong.eclp.stock.searchShopStock
|
||
func (a *API) QueryStock(goodsNo string) (queryStockResult []*QueryStockResult, err error) {
|
||
params := map[string]interface{}{
|
||
"deptNo": DepartmentNo,
|
||
"warehouseNo": WarehouseNo,
|
||
"returnZeroStock": 2, //表示返回库存为0的数据
|
||
"stockType": 1,
|
||
"stockStatus": 1, //良品
|
||
}
|
||
if goodsNo != "" {
|
||
params["goodsNo"] = goodsNo
|
||
}
|
||
result, err := a.AccessAPI("jingdong.eclp.stock.queryStock", prodURL, params)
|
||
if err == nil {
|
||
utils.Map2StructByJson(result["jingdong_eclp_stock_queryStock_responce"].(map[string]interface{})["querystock_result"], &queryStockResult, false)
|
||
}
|
||
return queryStockResult, err
|
||
}
|
||
|
||
//京东物流接单接口
|
||
//https://open.jd.com/home/home#/doc/api?apiCateId=64&apiId=2122&apiName=jingdong.ldop.waybill.receive
|
||
func (a *API) WaybillReceive(waybillReceiveParam *WaybillReceiveParam) (deliveryId string, err error) {
|
||
result, err := a.AccessAPI("jingdong.ldop.waybill.receive", prodURL, utils.Struct2FlatMap(waybillReceiveParam))
|
||
if err == nil {
|
||
if utils.MustInterface2Int64(result["jingdong_ldop_waybill_receive_responce"].(map[string]interface{})["receiveorderinfo_result"].(map[string]interface{})["resultCode"]) != 100 {
|
||
return deliveryId, fmt.Errorf(result["jingdong_ldop_waybill_receive_responce"].(map[string]interface{})["receiveorderinfo_result"].(map[string]interface{})["resultMessage"].(string))
|
||
} else {
|
||
deliveryId = result["jingdong_ldop_waybill_receive_responce"].(map[string]interface{})["receiveorderinfo_result"].(map[string]interface{})["deliveryId"].(string)
|
||
}
|
||
}
|
||
return deliveryId, err
|
||
}
|
||
|
||
//京东物流取消接口
|
||
//https://open.jd.com/home/home#/doc/api?apiCateId=75&apiId=3482&apiName=jingdong.ldop.delivery.provider.cancelWayBill
|
||
func (a *API) CancelWayBill(cancelWayBillParam *CancelWayBillParam) (err error) {
|
||
_, err = a.AccessAPI("jingdong.ldop.delivery.provider.cancelWayBill", prodURL, utils.Struct2FlatMap(cancelWayBillParam))
|
||
return err
|
||
}
|
||
|
||
type QueryDynamicTraceInfoResult struct {
|
||
OpeTitle string `json:"opeTitle"`
|
||
OpeTime string `json:"opeTime"`
|
||
State string `json:"state"`
|
||
OpeRemark string `json:"opeRemark"`
|
||
OpeName string `json:"opeName"`
|
||
WaybillCode string `json:"waybillCode"`
|
||
}
|
||
|
||
//京东物流全程跟踪接口
|
||
//https://open.jd.com/home/home#/doc/api?apiCateId=64&apiId=4257&apiName=jingdong.trace.dynamicQueryService.queryDynamicTraceInfo
|
||
func (a *API) QueryDynamicTraceInfo(waybillCode string) (queryDynamicTraceInfo []*QueryDynamicTraceInfoResult, err error) {
|
||
result, err := a.AccessAPI("jingdong.trace.dynamicQueryService.queryDynamicTraceInfo", prodURL, map[string]interface{}{
|
||
"waybillCode": waybillCode,
|
||
"customerCode": CustomerCode,
|
||
})
|
||
if err == nil {
|
||
utils.Map2StructByJson(result["jingdong_trace_dynamicQueryService_queryDynamicTraceInfo_responce"].(map[string]interface{})["response"].(map[string]interface{})["data"], &queryDynamicTraceInfo, false)
|
||
}
|
||
return queryDynamicTraceInfo, err
|
||
}
|
||
|
||
type WaybillQueryResult struct {
|
||
Weight float64 `json:"weight"`
|
||
DeliveryID string `json:"deliveryId"`
|
||
GoodNumber int `json:"goodNumber"`
|
||
StatusCode int `json:"statusCode"`
|
||
StatusMessage string `json:"statusMessage"`
|
||
}
|
||
|
||
//京东物流运单查询
|
||
//https://open.jd.com/home/home#/doc/api?apiCateId=64&apiId=2189&apiName=jingdong.ldop.waybill.query
|
||
func (a *API) WaybillQuery(deliveryId string) (waybill *WaybillQueryResult, err error) {
|
||
result, err := a.AccessAPI("jingdong.ldop.waybill.query", prodURL, map[string]interface{}{
|
||
"deliveryId": deliveryId,
|
||
"customerCode": CustomerCode,
|
||
})
|
||
if err == nil {
|
||
utils.Map2StructByJson(result["jingdong_ldop_waybill_query_responce"].(map[string]interface{})["resultInfo"].(map[string]interface{})["data"], &waybill, false)
|
||
}
|
||
if waybill == nil {
|
||
utils.Map2StructByJson(result["jingdong_ldop_waybill_query_responce"].(map[string]interface{})["resultInfo"], &waybill, false)
|
||
}
|
||
return waybill, err
|
||
}
|