Files
baseapi/platformapi/fnpsapi/fnpsapi.go
邹宗楠 ab96fc6343 1
2026-01-21 14:14:26 +08:00

160 lines
4.6 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 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
}