package jdapi // todo 没有删除门店的方法? import ( "encoding/json" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/globals" ) const ( KeyStationName = "stationName" KeyOutSystemId = "outSystemId" KeyPhone = "phone" KeyMobile = "mobile" KeyCity = "city" KeyCounty = "county" KeyStationAddress = "stationAddress" KeyOperator = "operator" KeyServiceTimeStart1 = "serviceTimeStart1" KeyServiceTimeEnd1 = "serviceTimeEnd1" KeyServiceTimeStart2 = "serviceTimeStart2" KeyServiceTimeEnd2 = "serviceTimeEnd2" KeyLng = "lng" KeyLat = "lat" KeyDeliveryRangeType = "deliveryRangeType" KeyCoordinateType = "coordinateType" KeyDeliveryRangeRadius = "deliveryRangeRadius" KeyCoordinatePoints = "coordinatePoints" KeyCloseStatus = "closeStatus" KeyStoreNotice = "storeNotice" KeyStandByPhone = "standByPhone" ) const ( CarrierNoCrowdSourcing = 9966 // 众包 CarrierNoSelfDelivery = 2938 // 自送 CarrierNoSelfTake = 9999 // 到店自提 ) const ( CoordinateTypeGoogle = 1 // 谷歌 CoordinateTypeBaidu = 2 // 百度 CoordinateTypeAutonavi = 3 // 高德 CoordinateTypeTencent = 4 // 腾讯 ) const ( FreightFreeTypeAll = 0 // 全免 FreightFreeTypeBase = 1 // 免基础运费 FreightFreeTypePartBase = 2 // 免部分基础运费 ) const ( MaxStoreNameLen = 100 // 门店名称最大长度(2个英文或数字算一位) ) type CreateShopResult struct { DeliveryRangeType int `json:"deliveryRangeType"` CoordinatePoints string `json:"coordinatePoints"` StationNo string `json:"stationNo"` } type CityInfo struct { AreaCode int `json:"areaCode"` AreaLevel int `json:"areaLevel"` AreaName string `json:"areaName"` ParentAreaID int `json:"parentAreaId"` TencentAddressCode int `json:"tencentAddressCode"` Yn int `json:"yn"` } type OpStoreParams struct { // 以下可用于修改(及查询) StationNo string `json:"stationNo"` // 强制参数,主键 StationName string `json:"stationName,omitempty"` OutSystemID string `json:"outSystemId,omitempty"` Mobile string `json:"mobile,omitempty"` Phone string `json:"phone,omitempty"` Lat float64 `json:"lat,omitempty"` Lng float64 `json:"lng,omitempty"` City int `json:"city,omitempty"` County int `json:"county,omitempty"` StationAddress string `json:"stationAddress,omitempty"` Operator string `json:"operator"` // 返回值无 ServiceTimeEnd1 int `json:"serviceTimeEnd1"` ServiceTimeStart1 int `json:"serviceTimeStart1"` ServiceTimeEnd2 int `json:"serviceTimeEnd2,omitempty"` ServiceTimeStart2 int `json:"serviceTimeStart2,omitempty"` DeliveryRangeType int8 `json:"deliveryRangeType,omitempty"` // 返回值无,划分配送服务范围的类型(3、圆心半径、2、不规则多边形(手动画范围))。若更新此字段需传完整值。 CoordinateType int `json:"coordinateType,omitempty"` // 返回值无,使用的地图类型(1,谷歌), (2,百度), (3,高德), (4,腾讯) DeliveryRangeRadius int `json:"deliveryRangeRadius,omitempty"` // 返回值无,时效服务范围半径(单位:米)(如果服务范围为类型3的话,该字段有值) CoordinatePoints string `json:"coordinatePoints,omitempty"` // 返回值无,坐标点集合(如果服务范围为类型2的话,该字段有值),每个点以:经度,纬度 的格式表示,用“;”隔开多个点;对于腾讯地图、谷歌地图和高德地图,整个coordinatePoints的长度必须小于2k;对于百度地图,整个coordinatePoints的长度必须小于1k CloseStatus int `json:"closeStatus"` // 0是有意义的值,所以不能是omitempty StoreNotice string `json:"storeNotice,omitempty"` StandByPhone string `json:"standByPhone,omitempty"` } type StoreDetail struct { // 以下可用于修改(及查询) StationNo string `json:"stationNo"` // 强制参数,主键 StationName string `json:"stationName,omitempty"` OutSystemID string `json:"outSystemId,omitempty"` Mobile string `json:"mobile,omitempty"` Phone string `json:"phone,omitempty"` Lat float64 `json:"lat,omitempty"` Lng float64 `json:"lng,omitempty"` City int `json:"city,omitempty"` County int `json:"county,omitempty"` StationAddress string `json:"stationAddress,omitempty"` // Operator string `json:"operator"` // 返回值无 ServiceTimeEnd1 int `json:"serviceTimeEnd1,omitempty"` ServiceTimeStart1 int `json:"serviceTimeStart1,omitempty"` ServiceTimeEnd2 int `json:"serviceTimeEnd2,omitempty"` ServiceTimeStart2 int `json:"serviceTimeStart2,omitempty"` // DeliveryRangeType int8 `json:"deliveryRangeType,omitempty"` // 返回值无,划分配送服务范围的类型(3、圆心半径、2、不规则多边形(手动画范围))。若更新此字段需传完整值。 // CoordinateType int `json:"coordinateType,omitempty"` // 返回值无,使用的地图类型(1,谷歌), (2,百度), (3,高德), (4,腾讯) // DeliveryRangeRadius int `json:"deliveryRangeRadius,omitempty"` // 返回值无,时效服务范围半径(单位:米)(如果服务范围为类型3的话,该字段有值) // CoordinatePoints string `json:"coordinatePoints,omitempty"` // 返回值无,坐标点集合(如果服务范围为类型2的话,该字段有值),每个点以:经度,纬度 的格式表示,用“;”隔开多个点;对于腾讯地图、谷歌地图和高德地图,整个coordinatePoints的长度必须小于2k;对于百度地图,整个coordinatePoints的长度必须小于1k CloseStatus int `json:"closeStatus"` // 0是有意义的值,所以不能是omitempty StoreNotice string `json:"storeNotice,omitempty"` StandByPhone string `json:"standByPhone,omitempty"` // 以下仅用于查询 AllowRangeOptimized int `json:"allowRangeOptimized"` CacheKey4StoreList string `json:"cacheKey4StoreList"` CarrierNo int `json:"carrierNo"` CityName string `json:"cityName"` Coordinate string `json:"coordinate"` CoordinateAddress string `json:"coordinateAddress"` CountyName string `json:"countyName"` CreatePin string `json:"createPin"` CreateTime *utils.JavaDate `json:"createTime"` ID int64 `json:"id"` IndustryTag int `json:"industryTag"` InnerNoStatus int `json:"innerNoStatus"` IsAutoOrder int `json:"isAutoOrder"` // 是否自动接单,0:是1:否 IsMembership int `json:"isMembership"` IsNoPaper int `json:"isNoPaper"` OnlineTime *utils.JavaDate `json:"onlineTime"` OrderAging int `json:"orderAging"` OrderNoticeType int `json:"orderNoticeType"` PreWarehouse int `json:"preWarehouse"` Province int `json:"province"` ProvinceName string `json:"provinceName"` QualifyStatus int `json:"qualifyStatus"` RegularFlag int `json:"regularFlag"` StationDeliveryStatus int `json:"stationDeliveryStatus"` SupportInvoice int `json:"supportInvoice"` SupportOfflinePurchase int `json:"supportOfflinePurchase"` TestMark int `json:"testMark"` TimeAmType int `json:"timeAmType"` TimePmType int `json:"timePmType"` Ts *utils.JavaDate `json:"ts"` UpdatePin string `json:"updatePin"` UpdateTime *utils.JavaDate `json:"updateTime"` VenderID string `json:"venderId"` VenderName string `json:"venderName"` WareType int `json:"wareType"` WhiteDelivery bool `json:"whiteDelivery"` Yn int8 `json:"yn"` // 门店状态,0启用,1禁用 } type OrderProdCommentVo struct { CreatePin string `json:"createPin"` CreateTime *utils.JavaDate `json:"createTime"` ID int64 `json:"id"` IsPraise int `json:"isPraise"` Score int `json:"score"` ScoreLevel int `json:"scoreLevel"` SkuID int64 `json:"skuId"` SkuName string `json:"skuName"` UpdatePin string `json:"updatePin"` UpdateTime *utils.JavaDate `json:"updateTime"` Yn int8 `json:"yn"` } type OrderCommentInfo struct { AppVersion string `json:"appVersion"` CreatePin string `json:"createPin"` CreateTime *utils.JavaDate `json:"createTime"` DeliveryCarrierNo string `json:"deliveryCarrierNo"` DeliveryConfirmTime *utils.JavaDate `json:"deliveryConfirmTime"` DeliveryConfirmTime2 *utils.JavaDate `json:"deliveryConfirmTime2"` DeliveryDifTime int `json:"deliveryDifTime"` DeliveryDifTime2 int `json:"deliveryDifTime2"` DeliveryManNo string `json:"deliveryManNo"` DocID interface{} `json:"docId"` ID int64 `json:"id"` IsUpdate int `json:"isUpdate"` OrderID int64 `json:"orderId"` OrderProdCommentVoList []*OrderProdCommentVo `json:"orderProdCommentVoList"` OrderType int `json:"orderType"` OrgCode int `json:"orgCode"` OrgCommentContent string `json:"orgCommentContent"` OrgCommentStatus int `json:"orgCommentStatus"` OrgCommentTime *utils.JavaDate `json:"orgCommentTime"` OrgName string `json:"orgName"` Score3 int `json:"score3"` Score3Content string `json:"score3Content"` Score4 int `json:"score4"` Score4Content string `json:"score4Content"` ScoreLevel int `json:"scoreLevel"` StoreID int64 `json:"storeId"` StoreName string `json:"storeName"` Tags []string `json:"tags"` TagsKey []string `json:"tagsKey"` UpdatePin string `json:"updatePin"` UpdateTime *utils.JavaDate `json:"updateTime"` VenderTageKey []string `json:"venderTageKey"` VenderTags []string `json:"venderTags"` Yn int8 `json:"yn"` } type StoreDeliveryRange struct { Adresses string `json:"adresses"` CreatePin string `json:"createPin"` CreateTime *utils.JavaDate `json:"createTime"` DeliveryRange string `json:"deliveryRange"` DeliveryRangeRadius int `json:"deliveryRangeRadius"` DeliveryRangeType int `json:"deliveryRangeType"` DeliveryServiceType int `json:"deliveryServiceType"` ID int `json:"id"` StationNo string `json:"stationNo"` Ts *utils.JavaDate `json:"ts"` UpdatePin string `json:"updatePin"` UpdateTime *utils.JavaDate `json:"updateTime"` VenderID string `json:"venderId"` Yn int8 `json:"yn"` } type FreeFreightTime struct { FreeBeginTime string `json:"freeBeginTime,omitempty"` FreeEndTime string `json:"freeEndTime,omitempty"` } type FreeFreightInfo struct { FullFreeMoney int64 `json:"fullFreeMoney"` FreeType int `json:"freeType"` FreeMoney int64 `json:"freeMoney,omitempty"` OutActivityID string `json:"outActivityId,omitempty"` FreeFreightTimes []*FreeFreightTime `json:"freeFreightTimes,omitempty"` } type UpdateStoreFreightParam struct { UserPin string `json:"userPin"` OpenDistanceFreight bool `json:"openDistanceFreight"` IsFullFree bool `json:"isFullFree"` StationNo string `json:"stationNo,omitempty"` MerchantStationNo string `json:"merchantStationNo,omitempty"` StartCharge int64 `json:"startCharge,omitempty"` SelfDeliveryFreightMoney int64 `json:"selfDeliveryFreightMoney,omitempty"` StartBeginTime string `json:"startBeginTime,omitempty"` StartEndTime string `json:"startEndTime,omitempty"` DistanceFreightThreshold int `json:"distanceFreightThreshold,omitempty"` DistanceUnit int `json:"distanceUnit,omitempty"` DistanceFreight int64 `json:"distanceFreight,omitempty"` FreeFreightInfoList []*FreeFreightInfo `json:"freeFreightInfoList,omitempty"` } func (a *API) GetAllCities() (cities []*CityInfo, err error) { result, err := a.AccessAPINoPage("address/allcities", nil, nil, nil, genNoPageResultParser("code", "msg", "result", "0")) if err == nil { err = JdMap2StructByJson(result, &cities, false) } return cities, err } // 获取门店编码列表接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=194&apiid=138426aa19b54c48ae8464af1ca3b681 func (a *API) GetStationsByVenderId() ([]string, error) { result, err := a.AccessAPINoPage("store/getStationsByVenderId", nil, nil, nil, genNoPageResultParser("code", "msg", "result", "0")) if err == nil { result2 := result.([]interface{}) retVal := make([]string, len(result2)) for k, v := range result2 { retVal[k] = v.(string) } return retVal, nil } return nil, err } // 新增不带资质的门店信息接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=194&apiid=93acef27c3aa4d8286d5c8c26b493629 func (a *API) CreateStore(createParams *OpStoreParams) (*CreateShopResult, error) { createParams.Operator = utils.GetAPIOperator(createParams.Operator) mapData := utils.Struct2MapByJson(createParams) if createParams.ServiceTimeStart1 == 0 && createParams.ServiceTimeEnd1 == 0 { delete(mapData, "serviceTimeStart1") delete(mapData, "serviceTimeEnd1") } result, err := a.AccessAPINoPage("store/createStore", mapData, nil, nil, func(data map[string]interface{}) (interface{}, error) { innerCode := data["code"].(string) if data["code"] == "0" { mapData := data mapData["result"] = data["result"].(string) return mapData, nil } return nil, utils.NewErrorCode(data["msg"].(string), innerCode, 1) }) if err == nil { return &CreateShopResult{ StationNo: result.(map[string]interface{})["result"].(string), }, nil } return nil, err } // 根据到家门店编码查询门店基本信息接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=194&apiid=4c48e347027146d5a103e851055cb1a7 // func (a *API) GetStoreInfoByStationNo(storeNo string) (map[string]interface{}, error) { // result, err := a.AccessAPINoPage("storeapi/getStoreInfoByStationNo", utils.Params2Map("StoreNo", storeNo), nil, nil, nil) // if err == nil { // return result.(map[string]interface{}), nil // } // return nil, err // } func (a *API) GetStoreInfoByStationNo2(storeNo string) (storeDetail *StoreDetail, err error) { result, err := a.AccessAPINoPage("storeapi/getStoreInfoByStationNo", utils.Params2Map("StoreNo", storeNo), nil, nil, nil) if err == nil { err = JdMap2StructByJson(result, &storeDetail, false) } return storeDetail, err } // 修改门店基础信息接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=194&apiid=2600369a456446f0921e918f3d15e96a // func (a *API) UpdateStoreInfo4Open(storeNo, userName string, addParams map[string]interface{}) error { // jdParams := map[string]interface{}{ // "stationNo": storeNo, // "operator": utils.GetAPIOperator(userName), // } // jdParams = utils.MergeMaps(jdParams, addParams) // _, err := a.AccessAPINoPage("store/updateStoreInfo4Open", jdParams, nil, nil, nullResultParser) // return err // } func (a *API) UpdateStoreInfo4Open2(updateParams *OpStoreParams, modifyCloseStatus bool) (err error) { updateParams.Operator = utils.GetAPIOperator(updateParams.Operator) mapData := utils.Struct2MapByJson(updateParams) if !modifyCloseStatus { delete(mapData, "closeStatus") } delete(mapData, "storeNotice") // 这个限制长度100个汉字老是超长!直接不修改了! // else { // jdStoreID, err := a.GetJdStoreID(int(utils.Str2Int64(updateParams.OutSystemID))) // if err != nil { // return err // } // err = a.UpdateClosetStatus(jdStoreID, updateParams.CloseStatus) // if err != nil { // return err // } // } if updateParams.ServiceTimeStart1 == 0 && updateParams.ServiceTimeEnd1 == 0 { delete(mapData, "serviceTimeStart1") delete(mapData, "serviceTimeEnd1") } _, err = a.AccessAPINoPage("store/updateStoreInfo4Open", mapData, nil, nil, nullResultParser) if err != nil { globals.SugarLogger.Debugf("九点半定时任务,更新门店错误: %v", err) globals.SugarLogger.Debugf("九点半定时任务,更新门店参数: %s", utils.Format4Output(updateParams, false)) } return err } // 根据订单号查询商家门店评价信息接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=194&apiid=bd23397725bb4e74b69e2f2fa1c88d43 // func (a *API) GetCommentByOrderId(orderId int64) (map[string]interface{}, error) { // jdParams := map[string]interface{}{ // "orderId": orderId, // } // result, err := a.AccessAPINoPage("commentOutApi/getCommentByOrderId", jdParams, nil, nil, genNoPageResultParser("code", "msg", "result", "200")) // if err == nil { // return result.(map[string]interface{}), nil // } // return nil, err // } func (a *API) GetCommentByOrderId2(orderId int64) (orderComment *OrderCommentInfo, err error) { jdParams := map[string]interface{}{ "orderId": orderId, } result, err := a.AccessAPINoPage("commentOutApi/getCommentByOrderId", jdParams, nil, nil, genNoPageResultParser("code", "msg", "result", "200")) if err == nil { err = JdMap2StructByJson(result, &orderComment, false) } return orderComment, err } // 商家门店评价信息回复接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=194&apiid=ea0b466a7fa8489b813e8b197efca2d4 func (a *API) OrgReplyComment(orderID int64, storeID, content, replayPin string) error { jdParams := map[string]interface{}{ "orderId": orderID, "storeId": storeID, "content": content, "replyPin": utils.GetAPIOperator(replayPin), } _, err := a.AccessAPINoPage("commentOutApi/orgReplyComment", jdParams, nil, nil, genNoPageResultParser("code", "msg", "result", "200")) return err } // 根据城市编码查询区域信息列表接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=194&apiid=cc2a3b5d49e84f3eb41ee39a0afe33c3 func (a *API) GetNextLevelByType(areaCode int64, pin string) (interface{}, error) { jdParams := map[string]interface{}{ "areaCode": areaCode, "pin": pin, } result, err := a.AccessAPI("address/getNextLevelByType", jdParams) return result, err } // 根据到家门店编码修改商家自动接单接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=194&apiid=5df446bb5ff14413965b8d702718dc48 func (a *API) UpdateStoreConfig4Open(stationNo string, isAutoOrder bool) (bool, error) { jdParams := map[string]interface{}{ "stationNo": stationNo, } // 0,1是反的 if isAutoOrder { jdParams["isAutoOrder"] = 0 } else { jdParams["isAutoOrder"] = 1 } result, err := a.AccessAPINoPage("store/updateStoreConfig4Open", jdParams, nil, nil, nil) if err != nil { return false, err } return result.(bool), nil } // 获取门店配送范围接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=194&apiid=8f6d0ac75d734c68bf5bd2a09f376a78 // func (a *API) GetDeliveryRangeByStationNo(stationNo string) (map[string]interface{}, error) { // jdParams := map[string]interface{}{ // "stationNo": stationNo, // } // result, err := a.AccessAPINoPage("store/getDeliveryRangeByStationNo", jdParams, nil, nil, nil) // if err == nil { // return result.(map[string]interface{}), nil // } // return nil, err // } func (a *API) GetDeliveryRangeByStationNo2(stationNo string) (deliveryRange *StoreDeliveryRange, err error) { jdParams := map[string]interface{}{ "stationNo": stationNo, } result, err := a.AccessAPINoPage("store/getDeliveryRangeByStationNo", jdParams, nil, nil, nil) if err == nil { err = JdMap2StructByJson(result, &deliveryRange, false) } return deliveryRange, err } // 私有函数 func interface2CreateShopResult(data interface{}) (retVal *CreateShopResult) { if result, ok := data.(map[string]interface{}); ok { retVal = &CreateShopResult{ DeliveryRangeType: int(utils.MustInterface2Int64(result["deliveryRangeType"])), CoordinatePoints: utils.Interface2String(result["coordinatePoints"]), StationNo: utils.Interface2String(result["result"]), } } return retVal } // 根据门店编码修改运费起送价、满免以及商家自送运费接口 // https://openo2o.jddj.com/staticnew/widgets/resources.html?groupid=194&apiid=997977a13c62449ba15f3db3b4aec932 func (a *API) UpdateStoreFreightConfigNew(upateParam *UpdateStoreFreightParam) (err error) { if upateParam.UserPin != "" { upateParam.UserPin = utils.GetAPIOperator(upateParam.UserPin) } jdParams := utils.Struct2MapByJson(upateParam) _, err = a.AccessAPINoPage("freight/updateStoreFreightConfigNew", jdParams, nil, nil, genNoPageResultParser("code", "detail", "", "0")) return err } func parsePrivilegeSearchUser(data map[string]interface{}) (innerData interface{}, err error) { status, ok := data["status"] if !ok { panic("parsePrivilegeSearchUser") } statusMap := status.(map[string]interface{}) innerCode := utils.Interface2String(statusMap["result"]) innerData, _ = data["result"] if innerCode != "success" { errMsg := formatErrorMsg(statusMap["message"]) err = utils.NewErrorCode(errMsg, innerCode, 1) } return innerData, err } type GetCommonMemberRegisteredInfoResult struct { Result struct { Birthday interface{} `json:"birthday"` Usersex interface{} `json:"userSex"` Address interface{} `json:"address"` Orderid string `json:"orderId"` Userfullname interface{} `json:"userFullName"` Username interface{} `json:"userName"` Storeid int `json:"storeId"` Userage interface{} `json:"userAge"` Timestamp string `json:"timeStamp"` Phonenumber string `json:"phoneNumber"` Identitytype interface{} `json:"identityType"` Identitynumber interface{} `json:"identityNumber"` Orgcode string `json:"orgCode"` Userfamilyname interface{} `json:"userFamilyname"` } `json:"result"` Msg string `json:"msg"` Code string `json:"code"` Success bool `json:"success"` Detail interface{} `json:"detail"` } func (a *API) GetCommonMemberRegisteredInfo(orderId string) (getCommonMemberRegisteredInfoResult *GetCommonMemberRegisteredInfoResult, err error) { jdParams := map[string]interface{}{ "orderId": orderId, } result, err := a.AccessAPI2("member/getCommonMemberRegisteredInfo", jdParams, "") if err == nil { json.Unmarshal([]byte(result["data"].(string)), &getCommonMemberRegisteredInfoResult) } return getCommonMemberRegisteredInfoResult, err }