Files
baseapi/platformapi/jdapi/store_sku.go
苏尹岚 f258539de6 aa
2021-02-08 14:40:47 +08:00

335 lines
13 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package jdapi
import (
"errors"
"fmt"
"git.rosy.net.cn/baseapi/utils"
)
const (
MaxStoreSkuBatchSize = 50
MaxStockQty = 100000000
MaxAddByStoreAndSkusCount = 30 // 批量置顶商品排序接口的最大个数
)
type SkuPriceInfo struct {
OutSkuId string `json:"outSkuId"`
Price int `json:"price"`
}
type SkuStock struct {
OutSkuId string `json:"outSkuId"`
StockQty int `json:"stockQty"`
}
type QueryStockRequest struct {
StationNo string `json:"stationNo"`
SkuId int64 `json:"skuId"`
DoSale int `json:"doSale"` //可售状态0:可售1:不可售)
}
type StockVendibility struct {
OutSkuId string `json:"outSkuId"`
DoSale bool `json:"doSale"` // 可售状态true:可售false:不可售)
}
type BaseStockCenterRequest struct {
StationNo string `json:"stationNo"`
SkuId int64 `json:"skuId"`
}
type SkuIdEntity struct {
OutSkuId string `json:"outSkuId"`
}
type StorePriceInfo struct {
MarketPrice int64 `json:"marketPrice"`
Pin string `json:"pin"`
Price int64 `json:"price"`
PromoteVipPrice int64 `json:"promoteVipPrice"`
SkuID int64 `json:"skuId"`
StationNo string `json:"stationNo"`
VenderID string `json:"venderId"`
VipPrice int64 `json:"vipPrice"`
}
type QueryStockResponse struct {
SkuID int64 `json:"skuId"`
StationNo string `json:"stationNo"`
UsableQty int `json:"usableQty"`
LockQty int `json:"lockQty"`
OrderQty int `json:"orderQty"`
Vendibility int `json:"vendibility"`
}
type UpdateVendibilityResponse struct {
OutSkuID string `json:"outSkuId"`
Code int `json:"code"`
Msg string `json:"msg"`
SkuID int64 `json:"skuId"`
CurrentQty int `json:"currentQty"`
LockQty int `json:"lockQty"`
OrderQty int `json:"orderQty"`
UsableQty int `json:"usableQty"`
Vendibility int `json:"vendibility"`
}
type StoreSkuBatchUpdateResponse struct {
OutSkuID string `json:"outSkuId" json2:"outSkuId"`
Code string `json:"code" json2:"errorCode"` // 这个Code有可能返回19000B这种形式只能当成字符串处理
Msg string `json:"msg" json2:"errorMessage"`
// UpdateVendibility会返回以下字段
SkuID int64 `json:"skuId"`
StationNo string `json:"stationNo"`
BusinessNo int `json:"businessNo"`
CreatePin string `json:"createPin"`
StockQty int `json:"stockQty"`
StockSource int `json:"stockSource"`
UpdatePin string `json:"updatePin"`
Vendibility int `json:"vendibility"`
}
func IsCodeSuccess(code string) bool {
return code == "" || code == "0"
}
// 传入为数组的最多一次为50个
// 有好些功能有两个类似的函数一个为到家ID一个为商家ID建议都只用商家ID的那个因为
// 1这类函数一般可以批量操作
// 2这类函数一般可以记录操作人员
// 根据商家商品编码和商家门店编码批量修改门店价格接口
// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=205&apiid=fcbf346648a54d03b92dec8fa62ea643
func (a *API) UpdateVendorStationPrice(trackInfo string, outStationNo, stationNo string, skuPriceInfoList []*SkuPriceInfo) (responseList []*StoreSkuBatchUpdateResponse, err error) {
jdParams := map[string]interface{}{
"skuPriceInfoList": skuPriceInfoList,
}
if outStationNo != "" {
jdParams["outStationNo"] = outStationNo
} else {
jdParams["stationNo"] = stationNo
}
result, err := a.AccessAPINoPage2("venderprice/updateStationPrice", jdParams, nil, nil, genNoPageResultParser("code", "msg", "result", "0"), trackInfo)
if result != nil {
var err2 error
if responseList, err2 = a.handleBatchOpResult(outStationNo, stationNo, len(skuPriceInfoList), err, result, "json2"); err2 != nil && err == nil {
err = err2
}
}
return responseList, err
}
// 根据到家商品编码和到家门店编码修改门店价格接口
// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=205&apiid=45f83ef7c6e74dad94b6b68d3c50b673
// 单商品用此接口
func (a *API) UpdateStationPrice(trackInfo string, skuId int64, stationNo string, price int) (string, error) {
jdParams := map[string]interface{}{
"skuId": skuId,
"stationNo": stationNo,
"price": price,
}
result, err := a.AccessAPINoPage2("price/updateStationPrice", jdParams, nil, nil, nil, trackInfo)
if err == nil && result != nil {
return utils.Interface2String(result), nil
}
return "", err
}
// 根据到家商品编码和到家门店编码批量查询商品门店价格信息接口
// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=205&apiid=21ccd5a00d3a4582b4c9a8ef0ae238fc
func (a *API) GetStationInfoList(stationNo string, skuIds []int64) (priceInfo []*StorePriceInfo, err error) {
jdParams := map[string]interface{}{
"skuIds": skuIds,
"stationNo": stationNo,
}
result, err := a.AccessAPINoPage("price/getStationInfoList", jdParams, nil, nil, genNoPageResultParser("code", "detail", "result", "0"))
if err == nil && result != nil {
err = JdMap2StructByJson(result, &priceInfo, false)
}
return priceInfo, err
}
func (a *API) handleBatchOpResult(outStationNo, stationNo string, batchCount int, inErr error, result interface{}, tagName string) (responseList []*StoreSkuBatchUpdateResponse, err error) {
if result != nil {
if err = utils.Map2Struct(result, &responseList, true, tagName, JavaDateHook); err == nil {
var failedList []*StoreSkuBatchUpdateResponse
for _, v := range responseList {
if !IsCodeSuccess(v.Code) {
failedList = append(failedList, v)
}
}
var err2 *utils.ErrorWithCode
if len(failedList) >= batchCount {
err2 = utils.NewErrorCode(string(utils.MustMarshal(failedList)), ResponseCodeAccessFailed, 1) // 此错误基本用不到
} else if len(failedList) > 0 { // 部分失败
err2 = utils.NewErrorCode(string(utils.MustMarshal(failedList)), ResponseInnerCodePartialFailed, 1)
}
if err2 != nil {
if stationNo != "" {
err2.AddPrefixMsg(fmt.Sprintf("stationNo:%s", stationNo))
} else if outStationNo != "" {
err2.AddPrefixMsg(fmt.Sprintf("outStationNo:%s", outStationNo))
}
err = err2
}
}
}
return responseList, err
}
// 根据商家商品编码和商家门店编码批量修改现货库存接口
// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=200&apiid=10812f9fc7ee4564b552f19270a7e92e
func (a *API) BatchUpdateCurrentQtys(trackInfo, outStationNo, stationNo string, skuStockList []*SkuStock, userPin string) (responseList []*StoreSkuBatchUpdateResponse, err error) {
if (outStationNo == "" && stationNo == "") || (outStationNo != "" && stationNo != "") {
return nil, errors.New("outStationNo and stationNo can not all be empty or have value")
}
jdParams := map[string]interface{}{
"skuStockList": skuStockList,
"userPin": utils.GetAPIOperator(userPin),
}
if outStationNo != "" {
jdParams["outStationNo"] = outStationNo
} else {
jdParams["stationNo"] = stationNo
}
result, err := a.AccessAPINoPage2("stock/batchUpdateCurrentQtys", jdParams, nil, nil, genNoPageResultParser("retCode", "retMsg", "data", "0"), trackInfo)
if result != nil {
var err2 error
if responseList, err2 = a.handleBatchOpResult(outStationNo, stationNo, len(skuStockList), err, result, ""); err2 != nil && err == nil {
err = err2
}
}
return responseList, err
}
// 根据商家商品编码和商家门店编码更新门店现货库存接口
// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=200&apiid=a78664d4ead349da95d2f4576ed18d7f
// 此接口基本可以不用
func (a *API) StockUpdate(trackInfo string, outStationNo string, outSkuID string, currentQty int) error {
// !这个接口的stationNo与skuId好像本身就写错了的
jdParams := map[string]interface{}{
"stationNo": outStationNo,
"skuId": outSkuID,
"currentQty": currentQty,
}
_, err := a.AccessAPINoPage2("stock/update", jdParams, nil, nil, genNoPageResultParser("retCode", "retMsg", "", "0"), trackInfo)
if err == nil {
return nil
}
return err
}
// 根据到家商品编码和到家门店编码更新门店现货库存
// https://openo2o.jddj.com/staticnew/widgets/resources.html?groupid=200&apiid=af70e699d4974e1683128742018f6381
// 单商品用此接口
func (a *API) UpdateCurrentQty(trackInfo string, stationNo string, skuID int64, currentQty int) error {
jdParams := map[string]interface{}{
"stationNo": stationNo,
"skuId": skuID,
"currentQty": currentQty,
}
_, err := a.AccessAPINoPage2("update/currentQty", jdParams, nil, nil, genNoPageResultParser("retCode", "retMsg", "", "0"), trackInfo)
if err == nil {
return nil
}
return err
}
// 根据到家商品编码和到家门店编码批量修改门店商品可售状态接口
// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=200&apiid=b783a508e2cf4aca94681e4eed9af5bc
// 尽量不用这个接口用下面那个原因是这个不支持设置操作人BatchUpdateVendibility可以
func (a *API) UpdateVendibility(trackInfo string, listBaseStockCenterRequest []*QueryStockRequest) (responseList []*StoreSkuBatchUpdateResponse, err error) {
jdParams := map[string]interface{}{
"listBaseStockCenterRequest": listBaseStockCenterRequest,
}
result, err := a.AccessAPINoPage2("stock/updateVendibility", jdParams, nil, nil, genNoPageResultParser("retCode", "retMsg", "data", "0"), trackInfo)
if result != nil {
var err2 error
if responseList, err2 = a.handleBatchOpResult("", listBaseStockCenterRequest[0].StationNo, len(listBaseStockCenterRequest), err, result, ""); err2 != nil && err == nil {
err = err2
}
}
return responseList, err
}
// 根据商家商品编码和门店编码批量修改门店商品可售状态接口
// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=200&apiid=ac6f559ebabf4b70bc423687638e07c1
func (a *API) BatchUpdateVendibility(trackInfo, outStationNo, stationNo string, stockVendibilityList []*StockVendibility, userPin string) (responseList []*StoreSkuBatchUpdateResponse, err error) {
if (outStationNo == "" && stationNo == "") || (outStationNo != "" && stationNo != "") {
return nil, errors.New("outStationNo and stationNo can not all be empty or have value")
}
jdParams := map[string]interface{}{
"stockVendibilityList": stockVendibilityList,
"userPin": utils.GetAPIOperator(userPin),
}
if outStationNo != "" {
jdParams["outStationNo"] = outStationNo
} else {
jdParams["stationNo"] = stationNo
}
// 此函数在全部失败时err仍然返回成功
result, err := a.AccessAPINoPage2("stock/batchUpdateVendibility", jdParams, nil, nil, genNoPageResultParser("retCode", "retMsg", "data", "0"), trackInfo)
if result != nil {
var err2 error
if responseList, err2 = a.handleBatchOpResult(outStationNo, stationNo, len(stockVendibilityList), err, result, ""); err2 != nil && err == nil {
err = err2
}
}
return responseList, err
}
// 根据到家商品编码和门店编码批量查询商品库存及可售状态信息接口
// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=200&apiid=bc6ad75e8fd34580856e06b5eb149aad
// 尽量不用这个接口,用下面那个
func (a *API) QueryOpenUseable(listBaseStockCenterRequest []*BaseStockCenterRequest) (stockResponse []*QueryStockResponse, err error) {
jdParams := map[string]interface{}{
"listBaseStockCenterRequest": listBaseStockCenterRequest,
}
result, err := a.AccessAPINoPage("stock/queryOpenUseable", jdParams, nil, nil, genNoPageResultParser("retCode", "retMsg", "data", "0"))
if err == nil && result != nil {
err = JdMap2StructByJson(result, &stockResponse, false)
}
return stockResponse, err
}
// 根据商家商品编码和门店编码批量查询商品库存及可售状态信息接口
// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=200&apiid=ba70316bb84f425f8c088d3c19b2570d
func (a *API) QueryStockCenter(outStationNo string, skuIds []*SkuIdEntity, userPin string) (vendibilityResponse []*UpdateVendibilityResponse, err error) {
jdParams := map[string]interface{}{
"outStationNo": outStationNo,
"skuIds": skuIds,
"userPin": utils.GetAPIOperator(userPin),
}
result, err := a.AccessAPINoPage("stock/queryStockCenter", jdParams, nil, nil, genNoPageResultParser("retCode", "retMsg", "data", "0"))
if err == nil && result != nil {
err = JdMap2StructByJson(result, &vendibilityResponse, false)
}
return vendibilityResponse, err
}
// 批量置顶商品排序接口
// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=a7677f1a75984ed3a6ea3d4827f5a6b4
func (a *API) AddByStoreAndSkus(stationNo int64, skuIDs []int64) (err error) {
jdParams := map[string]interface{}{
"storeId": stationNo,
"skuIds": skuIDs,
}
_, err = a.AccessAPINoPage("OrgSortService/addByStoreAndSkus", jdParams, nil, nil, genNoPageResultParser("status", "message", "", "200"))
return err
}
// 删除门店商品会员价接口
// https://openo2o.jddj.com/staticnew/widgets/resources.html?groupid=205&apiid=73116e2b9f374814880f1272ba301fdf
func (a *API) DelVipPrice(outStationNo string, skuIds []*SkuIdEntity) (err error) {
jdParams := map[string]interface{}{
"outStationNo": outStationNo,
"skuPriceInfoList": skuIds,
}
_, err = a.AccessAPINoPage("vender/delVipPrice", jdParams, nil, nil, genNoPageResultParser("code", "msg", "", "0"))
return err
}