package ebaiapi import ( "crypto/md5" "fmt" "net/http" "net/url" "sort" "strings" "gitrosy.jxc4.com/baseapi/platformapi" "gitrosy.jxc4.com/baseapi/utils" ) const ( prodURL = "https://api-be.ele.me/" signKey = "sign" secretKey = "secret" ) const ( ResponseCodeSuccess = 0 ResponseCodeSuccess2 = 200 GetStoreSuccessButUnderfind = 4001 // 拉取网页饿百门店信息,但是显示门店不存在 ResponseCodeCallElmFailed = 2101 // 这个可以尝试重试 ) type ResponseResult struct { ErrNo int `json:"errno"` Error string `json:"error"` Data interface{} `json:"data"` } type API struct { platformapi.APICookie source string secret string encrypt string client *http.Client config *platformapi.APIConfig speedLimiter *platformapi.Limiter supplierID int64 } func New(source, secret string, config ...*platformapi.APIConfig) *API { // baseapi.SugarLogger.Debugf("token=%v, pay=%v, secret=%v", token, appKey, secret) curConfig := platformapi.DefAPIConfig if len(config) > 0 { curConfig = *config[0] } api := &API{ source: source, secret: secret, client: &http.Client{Timeout: curConfig.ClientTimeout}, config: &curConfig, speedLimiter: platformapi.New(apiLimitConfigs, nil), //defaultAPILimitConfig), supplierID: -1, } return api } func (a *API) signParams(params url.Values) string { keyValues := make([]string, 0) for k, v := range params { if k != signKey { keyValues = append(keyValues, k+"="+v[0]) } } keyValues = append(keyValues, secretKey+"="+a.secret) sort.Strings(keyValues) finalStr := strings.Join(keyValues, "&") // baseapi.SugarLogger.Debugf("sign str:%v", finalStr) return fmt.Sprintf("%X", md5.Sum([]byte(finalStr))) } func (a *API) getShopID(body map[string]interface{}) (shopID string) { if body[KeyShopID] != nil { return body[KeyShopID].(string) } else if body[KeyBaiduShopID] != nil { return fmt.Sprint(body[KeyBaiduShopID]) } return "" } func (a *API) GetSource() string { return a.source } func (a *API) AccessAPI2(cmd string, body map[string]interface{}, trackInfo string) (retVal *ResponseResult, err error) { a.speedLimiter.AccessAPI(cmd, a.getShopID(body)) if body == nil { body = make(map[string]interface{}, 0) } params := url.Values{ "cmd": []string{cmd}, "version": []string{"3"}, "timestamp": []string{utils.Int64ToStr(utils.GetCurTimestamp())}, "ticket": []string{utils.GetUpperUUID()}, "source": []string{a.source}, "body": []string{string(utils.MustMarshal(body))}, "encrypt": []string{a.encrypt}, } params[signKey] = []string{a.signParams(params)} encodedParams := params.Encode() err = platformapi.AccessPlatformAPIWithRetry(a.client, func() *http.Request { request, _ := http.NewRequest(http.MethodPost, prodURL, strings.NewReader(encodedParams)) request.Header.Set("Content-Type", "application/x-www-form-urlencoded") request.Header.Set("User-Agent", "ebai-golang-api") if trackInfo != "" { request.Header.Set(platformapi.KeyTrackInfo, trackInfo) } 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") } Body := jsonResult1["body"].(map[string]interface{}) retVal = &ResponseResult{ ErrNo: int(utils.MustInterface2Int64(Body["errno"])), Error: utils.Interface2String(Body["error"]), Data: Body["data"], } if retVal.ErrNo == ResponseCodeSuccess { return platformapi.ErrLevelSuccess, nil } newErr := utils.NewErrorIntCode(retVal.Error, retVal.ErrNo) // todo 临时处理超过阈值错... if (newErr.IntCode() == 20501 && strings.Index(retVal.Error, "阈值") >= 0) || (newErr.IntCode() == 20502 && strings.Index(retVal.Error, "系统繁忙") >= 0) { return platformapi.ErrLevelExceedLimit, newErr } return platformapi.ErrLevelCodeIsNotOK, newErr }) err = platformapi.RebuildError(err, body, []string{ KeyBaiduShopID, KeyShopID, KeySkuID, KeyCustomSkuID, }) return retVal, err } func (a *API) AccessAPI(cmd string, body map[string]interface{}) (retVal *ResponseResult, err error) { return a.AccessAPI2(cmd, body, "") } func (a *API) GetSupplierID() (supplierID int64) { a.RLock() supplierID = a.supplierID a.RUnlock() if supplierID < 0 { a.Lock() defer a.Unlock() a.supplierID = 0 if shopList, err := a.ShopList(SysStatusAll); err == nil { for _, shop := range shopList { if shopDetail, err := a.ShopGet2("", shop.BaiduShopID); err != nil { break } else if shopDetail.SupplierID > 0 { a.supplierID = shopDetail.SupplierID break } } } } return a.supplierID }