package fnpsapi import ( "crypto/sha256" "encoding/hex" "encoding/json" "errors" "fmt" "net/http" "sort" "strings" "sync" "time" "git.rosy.net.cn/baseapi/platformapi" "git.rosy.net.cn/baseapi/utils" ) func (a *API) SetToken(token string) { a.locker.Lock() defer a.locker.Unlock() a.accessToken = token } func (a *API) SetRefreshToken(token string) { a.locker.Lock() defer a.locker.Unlock() a.refreshToken = token } func (a *API) MakeFnRequestHead() map[string]interface{} { requestParam := make(map[string]interface{}, 6) requestParam["access_token"] = a.accessToken requestParam["signature"] = a.signature requestParam["merchant_id"] = a.merchantId requestParam["version"] = a.version requestParam["app_id"] = a.appID requestParam["timestamp"] = a.timestamp return requestParam } func New(appID, appSecret, merchantId, code string, config ...*platformapi.APIConfig) *API { curConfig := platformapi.DefAPIConfig if len(config) > 0 { curConfig = *config[0] } if appID == "" { return nil } // 查询蜂鸟refeshToken return &API{ grantType: "authorization_code", // 授权模式,填固定值authorization_code code: code, appID: appID, merchantId: merchantId, signature: "", accessToken: "", refreshToken: "", version: "1.0", appSecret: appSecret, locker: sync.RWMutex{}, 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 != "signature" { if str := fmt.Sprint(v); str != "" { valueList = append(valueList, fmt.Sprintf("%s=%s", k, str)) } } } sort.Sort(sort.StringSlice(valueList)) sig = strings.Join(valueList, "&") sig = a.appSecret + sig signature := sha256.Sum256([]byte(sig)) return hex.EncodeToString(signature[:]) } func (a *API) AccessAPI(baseUrl, actionApi, method string, bizParams map[string]interface{}) (retVal map[string]interface{}, err error) { bizParams["timestamp"] = utils.Int64ToStr(time.Now().Unix() * 1000) bizParams["signature"] = a.signParam(bizParams) // 序列化 data, err := json.Marshal(bizParams) if err != nil { return nil, err } // 全路径请求参数 fullURL := utils.GenerateGetURL(baseUrl, actionApi, nil) // 发送请求 sendUrl := func() *http.Request { var request *http.Request if http.MethodPost == method { request, _ = http.NewRequest(http.MethodPost, fullURL, strings.NewReader(string(data))) } else { request, _ = http.NewRequest(http.MethodGet, utils.GenerateGetURL(baseUrl, actionApi, bizParams), nil) } request.Header.Set("Content-Type", "application/json") return request } // 数据解析 dataMarshal := 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 { return "", err } if utils.MustInterface2Int64(jsonResult1["code"]) != 200 { errLevel = platformapi.ErrLevelGeneralFail err = utils.NewErrorCode(jsonResult1["msg"].(string), utils.Int64ToStr(utils.MustInterface2Int64(jsonResult1["code"]))) } retVal = jsonResult1 return errLevel, err } err = platformapi.AccessPlatformAPIWithRetry(a.client, sendUrl, a.config, dataMarshal) return retVal, err } // 获取access_token func (a *API) GetAccessToken() (tokenInfo *TokenInfo, err error) { parameter := make(map[string]interface{}, 6) parameter["grant_type"] = "refresh_token" parameter["app_id"] = a.appID parameter["merchant_id"] = a.merchantId // 先去刷新token,没有的话再去获取token(code只能使用一次,生成的token管一年) var result map[string]interface{} switch { case a.accessToken != "" && a.refreshToken != "": parameter["refresh_token"] = a.refreshToken result, err = a.AccessAPI(RefreshTokenUrl, "", http.MethodPost, parameter) case a.accessToken == "" && a.refreshToken == "": parameter["grant_type"] = "authorization_code" parameter["code"] = a.code result, err = a.AccessAPI(TokenURL, "", http.MethodPost, parameter) default: return nil, errors.New("更换code,请在配置表中删除原蜂鸟token") } if err != nil { return nil, err } if err := utils.Map2StructByJson(result, &tokenInfo, false); err != nil { return nil, err } businessData := &BusinessData{} if err := json.Unmarshal([]byte(utils.Interface2String(result["business_data"])), businessData); err != nil { return nil, err } tokenInfo.BusinessDataObj = businessData return tokenInfo, err }