diff --git a/platformapi/jdeclpapi/jdeclpapi.go b/platformapi/jdeclpapi/jdeclpapi.go index 3982d9ae..5b7e302a 100644 --- a/platformapi/jdeclpapi/jdeclpapi.go +++ b/platformapi/jdeclpapi/jdeclpapi.go @@ -281,7 +281,7 @@ func (a *API) SearchShopStock(goodsNo string) (searchShopStockResult *SearchShop "requestId": utils.GetUUID(), "deptNo": DepartmentNo, "shopNo": ShopNo, - "pageSize": 1000, + "pageSize": 100, "pageNumber": 1, } if goodsNo != "" { @@ -294,35 +294,20 @@ func (a *API) SearchShopStock(goodsNo string) (searchShopStockResult *SearchShop return searchShopStockResult, err } -//获取tokenCode -//https://oauth.jd.com/oauth/authorize?response_type=code&client_id=YOUR_APP_KEY&redirect_uri=YOUR_REGISTERED_REDIRECT_URI&state=YOUR_CUSTOM_CODE -//https://oauth.jd.com/oauth/authorize?response_type=code&client_id=YOUR_APP_KEY&redirect_uri=urn:ietf:wg:oauth:2.0:oob&state=1212 -// func (a *API) GetTokenInfo() (code string, err error) { -// result, err := a.AccessAPI("authorize", prodURL2, map[string]interface{}{ -// "response_type": "code", -// "client_id": a.appKey, -// "redirect_uri": a.redirectUri, -// "state": state, -// }) -// if err == nil { -// code = result["code"].(string) -// } -// return code, err -// } - -//获取token -//https://oauth.jd.com/oauth/token?grant_type=authorization_code&client_id=YOUR_APP_KEY&redirect_uri=YOUR_REGISTERED_REDIRECT_URI&code=GET_CODE&state=YOUR_CUSTOM_CODE&client_secret= YOUR_APP_SECRET -// func (a *API) GetToken() (token string, err error) { -// code, err := a.GetTokenInfo() -// result, err := a.AccessAPI("token", prodURL2, map[string]interface{}{ -// "grant_type": "authorization_code", -// "client_id": a.appKey, -// "redirect_uri": a.redirectUri, -// "code": code, -// "state": state, -// }) -// if err == nil { -// token = result["token"].(string) -// } -// return token, err -// } +//查询仓库商品库存 +//https://open.jd.com/home/home#/doc/api?apiCateId=138&apiId=3396&apiName=jingdong.eclp.stock.searchShopStock +func (a *API) QueryStock(goodsNo string) (searchShopStockResult *SearchShopStockResult, err error) { + params := map[string]interface{}{ + "deptNo": DepartmentNo, + "warehouseNo": WarehouseNo, + "returnZeroStock": 2, //表示返回库存为0的数据 + } + 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"], &searchShopStockResult, false) + } + return searchShopStockResult, err +} diff --git a/platformapi/jdeclpapi/jdeclpapi_test.go b/platformapi/jdeclpapi/jdeclpapi_test.go index 3bfdd0d6..fc8ea4a5 100644 --- a/platformapi/jdeclpapi/jdeclpapi_test.go +++ b/platformapi/jdeclpapi/jdeclpapi_test.go @@ -1,6 +1,8 @@ package jdeclpapi import ( + "fmt" + "regexp" "testing" "git.rosy.net.cn/baseapi/utils" @@ -80,3 +82,262 @@ func TestSearchShopStock(t *testing.T) { } t.Log(utils.Format4Output(result, false)) } + +func TestQueryStock(t *testing.T) { + result, err := api.QueryStock("JX10001") + if err != nil { + t.Fatal(err) + } + t.Log(utils.Format4Output(result, false)) +} + +type JxOrderInfo struct { + BuyerComment string `json:"buyerComment"` + StoreID int `json:"storeID"` + Skus []*JxSkuInfo `json:"skus"` + + ExpectedDeliveredTimestamp int64 `json:"expectedDeliveredTimestamp"` // 预期送达时间 + + TotalPrice int64 `json:"totalPrice"` // 单位为分 订单总价 + FreightPrice int64 `json:"freightPrice"` // 单位为分 订单配送费 + OrderPrice int64 `json:"orderPrice"` // 单位为分 订单商品价格 + ActualPayPrice int64 `json:"actualPayPrice"` // 单位为分 顾客实际支付 + + OrderID int64 `json:"orderID"` + StoreName string `json:"storeName"` + Weight int `json:"weight"` + FromStoreID int `json:"fromStoreID"` +} + +type JxSkuInfo struct { + SkuID int `json:"skuID"` + Count int `json:"count"` + + Price int64 `json:"price,omitempty"` // 原价 + SalePrice int64 `json:"salePrice,omitempty"` // 售卖价 + + Name string `json:"name"` + Weight int `json:"weight"` + GroupSign bool `json:"groupSign"` +} + +type JxSkuInfo2 struct { + SkuID int `json:"skuID"` + Count int `json:"count"` + + Price int64 `json:"price,omitempty"` // 原价 + SalePrice int64 `json:"salePrice,omitempty"` // 售卖价 + + Name string `json:"name"` + Weight int `json:"weight"` + GroupSign bool `json:"groupSign"` +} + +func TestAA(t *testing.T) { + var skus []*JxSkuInfo + weight := 0 + sku1 := &JxSkuInfo{ + SkuID: 6039387, + Weight: 1400, + Count: 2, + } + skus = append(skus, sku1) + weight += sku1.Count * sku1.Weight + sku2 := &JxSkuInfo{ + SkuID: 6039382, + Weight: 1460, + Count: 1, + } + skus = append(skus, sku2) + weight += sku2.Count * sku2.Weight + sku3 := &JxSkuInfo{ + SkuID: 6039381, + Weight: 280, + Count: 4, + } + skus = append(skus, sku3) + weight += sku3.Count * sku3.Weight + jxOrderInfo := &JxOrderInfo{ + StoreID: 666666, + Skus: skus, + FromStoreID: 100118, + Weight: weight, + } + _, _, _ = tryToSplitMatterOrder(jxOrderInfo) + // t.Log(utils.Format4Output(result1, false)) +} + +func tryToSplitMatterOrder(jxOrder *JxOrderInfo) (outOrders []*JxOrderInfo, freightPrice int, err error) { + var ( + skus = jxOrder.Skus + weightList []*JxSkuInfo2 + // flag = true + ) + for _, v := range skus { + for i := 0; i < v.Count; i++ { + var sku2 = &JxSkuInfo2{} + sku2.Count = v.Count + sku2.Name = v.Name + sku2.Price = v.Price + sku2.SalePrice = v.SalePrice + sku2.Weight = v.Weight + sku2.SkuID = v.SkuID + weightList = append(weightList, sku2) + } + } + for i := 0; i < len(weightList)-1; i++ { + for j := 0; j < len(weightList)-i-1; j++ { + if weightList[j].Weight < weightList[j+1].Weight { + tmp := weightList[j] + weightList[j] = weightList[j+1] + weightList[j+1] = tmp + } + } + } + weight := jxOrder.Weight + for { + outOrders = append(outOrders, loop2(weightList, jxOrder.StoreID, &weight)) + for i := 0; i < len(weightList); { + if weightList[i].GroupSign { + var weightList3 []*JxSkuInfo2 + weightList3 = append(weightList[:i], weightList[i+1:]...) + weightList = weightList3 + } else { + i++ + } + } + if len(weightList) == 0 { + break + } + } + fmt.Println(utils.Format4Output(outOrders, false)) + return outOrders, freightPrice, err +} + +func loop(weightList []*JxSkuInfo2, jxOrder *JxOrderInfo, flag bool) (outOrder *JxOrderInfo) { + outOrder = &JxOrderInfo{} + outOrder.StoreID = jxOrder.StoreID + sum5 := 0 + sum3 := 0 + for i := 0; i < len(weightList); i++ { + if flag { + if weightList[i].Weight+sum5 <= 5000 { + sum5 += weightList[i].Weight + weightList[i].GroupSign = true + if len(outOrder.Skus) > 0 { + for _, v := range outOrder.Skus { + if v.SkuID == weightList[i].SkuID { + v.Count++ + } else { + outOrder.Skus = append(outOrder.Skus, jxOrderChange(weightList[i])) + } + } + } else { + outOrder.Skus = append(outOrder.Skus, jxOrderChange(weightList[i])) + } + } else { + if sum5 >= 5000 { + break + } + continue + } + } else { + if weightList[i].Weight+sum3 <= 3000 { + sum3 += weightList[i].Weight + weightList[i].GroupSign = true + if len(outOrder.Skus) > 0 { + for _, v := range outOrder.Skus { + if v.SkuID == weightList[i].SkuID { + v.Count++ + } else { + outOrder.Skus = append(outOrder.Skus, jxOrderChange(weightList[i])) + } + } + } else { + outOrder.Skus = append(outOrder.Skus, jxOrderChange(weightList[i])) + } + } else { + if sum3 >= 3000 { + break + } + continue + } + } + } + return outOrder +} + +func jxOrderChange(sku2 *JxSkuInfo2) *JxSkuInfo { + sku := &JxSkuInfo{} + sku.Count = 1 + sku.Name = sku2.Name + sku.Price = sku2.Price + sku.SalePrice = sku2.SalePrice + sku.SkuID = sku2.SkuID + sku.Weight = sku2.Weight + return sku +} + +func TestBB(t *testing.T) { + regexpCnameAndCmobile := regexp.MustCompile(`配送员,(.*),手机号,(.*)`) + s := "配送员开始配送,请您准备收货,配送员,彭林,手机号,18008096393" + result := regexpCnameAndCmobile.FindAllStringSubmatch(s, -1) + cName := result[0][1] + cMobile := result[0][2] + fmt.Println(cName, cMobile) +} + +func loop2(weightList []*JxSkuInfo2, storeID int, weight *int) (outOrder *JxOrderInfo) { + outOrder = &JxOrderInfo{} + outOrder.StoreID = storeID + sum3 := 0 + if *weight <= 5000 { + for i := 0; i < len(weightList); i++ { + weightList[i].GroupSign = true + outOrder.Weight += weightList[i].Weight + if len(outOrder.Skus) > 0 { + var flag = false + for _, v := range outOrder.Skus { + if v.SkuID == weightList[i].SkuID { + v.Count++ + flag = true + } + } + if !flag { + outOrder.Skus = append(outOrder.Skus, jxOrderChange(weightList[i])) + } + } else { + outOrder.Skus = append(outOrder.Skus, jxOrderChange(weightList[i])) + } + } + } else { + for i := 0; i < len(weightList); i++ { + if weightList[i].Weight+sum3 <= 3000 { + sum3 += weightList[i].Weight + weightList[i].GroupSign = true + outOrder.Weight += weightList[i].Weight + *weight -= weightList[i].Weight + if len(outOrder.Skus) > 0 { + var flag = false + for _, v := range outOrder.Skus { + if v.SkuID == weightList[i].SkuID { + v.Count++ + flag = true + } + } + if !flag { + outOrder.Skus = append(outOrder.Skus, jxOrderChange(weightList[i])) + } + } else { + outOrder.Skus = append(outOrder.Skus, jxOrderChange(weightList[i])) + } + } else { + if sum3 >= 3000 { + break + } + continue + } + } + } + return outOrder +} diff --git a/platformapi/yinbaoapi/yinbaoapi.go b/platformapi/yinbaoapi/yinbaoapi.go new file mode 100644 index 00000000..370a4446 --- /dev/null +++ b/platformapi/yinbaoapi/yinbaoapi.go @@ -0,0 +1,114 @@ +package yinbaoapi + +import ( + "crypto/md5" + "fmt" + "net/http" + "sort" + "strings" + "time" + + "git.rosy.net.cn/baseapi" + "git.rosy.net.cn/baseapi/platformapi" + "git.rosy.net.cn/baseapi/utils" +) + +const ( + sigKey = "sign" + url = "https://area27-win.pospal.cn:443/pospal-api2/openapi/v1" +) + +type API struct { + appKey string + appID string + client *http.Client + config *platformapi.APIConfig +} + +func New(appKey, appID string, config ...*platformapi.APIConfig) *API { + curConfig := platformapi.DefAPIConfig + if len(config) > 0 { + curConfig = *config[0] + } + return &API{ + appKey: appKey, + appID: appID, + 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("key=%s", a.appKey)) + sig = strings.Join(valueList, "&") + binSig := md5.Sum([]byte(sig)) + sig = fmt.Sprintf("%X", binSig) + return sig +} + +func (a *API) AccessAPI(action string, bizParams map[string]interface{}) (retVal map[string]interface{}, err error) { + params := make(map[string]interface{}) + params["appId"] = a.appID + fullURL := utils.GenerateGetURL(url, action, nil) + err = platformapi.AccessPlatformAPIWithRetry(a.client, + func() *http.Request { + request, _ := http.NewRequest(http.MethodPost, fullURL, strings.NewReader(utils.Map2URLValues(params).Encode())) + signStr := a.signParam(params) + request.Header.Set("User-Agent", "openApi") + request.Header.Set("accept-encoding", "gzip,deflate") + request.Header.Set("data-signature", signStr) + request.Header.Set("time-stamp", utils.Int64ToStr(time.Now().Unix())) + request.Header.Set("Content-Type", "application/json; charset=utf-8") + 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)) + baseapi.SugarLogger.Debugf("jdeclp AccessAPI failed, jsonResult1:%s", utils.Format4Output(jsonResult1, true)) + } + retVal = jsonResult1 + } + return errLevel, err + }) + return retVal, err +} + +type AddProductInfoParam struct{ + ProductInfo struct { + CategoryUID int `json:"categoryUid"` + Name string `json:"name"` + Barcode string `json:"barcode"` + BuyPrice int `json:"buyPrice"` + SellPrice int `json:"sellPrice"` + Stock int `json:"stock"` + Pinyin string `json:"pinyin"` + Description string `json:"description"` + IsCustomerDiscount int `json:"isCustomerDiscount"` + SupplierUID int `json:"supplierUid"` + Enable int `json:"enable"` + } `json:"productInfo"` + AppID string `json:"appId"` +} + +//新增商品 +//http://pospal.cn/openplatform/productapi.html#addProductInfo +func (a *API) AddProductInfo(addProductInfoParam *AddProductInfoParam) (err error) { + result, err := a.AccessAPI("productOpenApi/addProductInfo", utils.Struct2FlatMap(addProductInfoParam)) + + return err +} diff --git a/platformapi/yinbaoapi/yinbaoapi_test.go b/platformapi/yinbaoapi/yinbaoapi_test.go new file mode 100644 index 00000000..3e40e712 --- /dev/null +++ b/platformapi/yinbaoapi/yinbaoapi_test.go @@ -0,0 +1 @@ +package yinbaoapi