third-platform-sdk/platform/t3-union/api.go
2024-06-15 21:01:51 +08:00

180 lines
6.5 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 t3_union
import (
"context"
"encoding/json"
"errors"
"fmt"
"math/rand"
"net/http"
"sort"
"strings"
"time"
"github.com/zeromicro/go-zero/core/logx"
"gitee.com/chengdu-lenntc/third-platform-sdk/client"
"gitee.com/chengdu-lenntc/third-platform-sdk/util"
)
// T3UnionApi 调用第三方平台的api
// Api defines the interface of t3_union api
type T3UnionApi interface {
// Sign 签名
Sign(methodType string, url string, data map[string]interface{}) string
// GenerateLink 生成短链
GenerateLink(ctx context.Context, req GenerateLinkRequest) (*GenerateLinkData, error)
// GenerateCode 生成二维码
GenerateCode(ctx context.Context, req GenerateCodeRequest) (*GenerateCodeData, error)
// GeneratePoster 生成推广海报
GeneratePoster(ctx context.Context, req GeneratePosterRequest) (*GeneratePosterData, error)
// QueryOrderList 查询订单列表
QueryOrderList(ctx context.Context, req QueryOrderListRequest) (*QueryOrderData, error)
}
type t3UnionApiImpl struct {
log logx.Logger
client *Client
}
func newT3UnionApiImpl(log logx.Logger, client *Client) T3UnionApi {
return &t3UnionApiImpl{
log: log,
client: client,
}
}
func (a *t3UnionApiImpl) buildHeader(methodType string, uri string, data map[string]any) map[string]string {
// 随机数
tn := time.Now()
src := rand.NewSource(tn.Unix())
randNum := rand.New(src).Int31n(10000)
nonce := util.Md5String(fmt.Sprintf("%d_nonce_%d", tn.UnixMicro(), randNum))
headers := map[string]string{
XT3Nonce: nonce, // 请求标识10分钟内保证唯一性
XT3Timestamp: fmt.Sprintf("%d", time.Now().UnixMilli()), // 请求发起时间戳(毫秒)有效时1分钟
XT3Version: "V1", // 版本(固定值传"V1"
XT3Key: a.client.authConfig.AppKey, // 使用前联系分配账号APP Key
XT3SignatureMethod: "MD5", // 固定值传 "MD5"
}
headers[XT3Signature] = a.getSign(methodType, uri, headers, data) // 在获得签名后赋值
headers[XT3SignatureHeaders] = "x-t3-nonce,x-t3-timestamp,x-t3-version,x-t3-key,x-t3-signature-method" // 固定传值
return headers
}
func (a *t3UnionApiImpl) getSign(methodType string, uri string, headers map[string]string, data map[string]any) string {
// key排序
arr := sort.StringSlice{}
for k := range headers {
if k != XT3Signature && k != XT3SignatureHeaders {
arr = append(arr, k)
}
}
arr.Sort()
// 参数拼接
var build strings.Builder
build.WriteString(fmt.Sprintf("%s%s", methodType, uri))
for _, k := range arr {
build.WriteString(fmt.Sprintf("%s:%v", k, headers[k]))
}
// 请求参数body转json string后用MD5进行加密
dataByte, _ := json.Marshal(data)
build.WriteString(util.Md5String(string(dataByte)))
build.WriteString(a.client.authConfig.AppSecret)
return util.Md5String(build.String())
}
// Sign 签名
func (a *t3UnionApiImpl) Sign(methodType string, uri string, dataMap map[string]any) string {
headers := a.buildHeader(methodType, uri, dataMap)
if sign, ok := headers[XT3Signature]; ok {
return sign
}
return ""
}
// GenerateLink 生成短链
func (a *t3UnionApiImpl) GenerateLink(ctx context.Context, req GenerateLinkRequest) (*GenerateLinkData, error) {
args := util.StructToMap(req)
headers := a.buildHeader(http.MethodPost, GetLinkUri, args)
for k, v := range a.client.headers {
headers[k] = v
}
request := &client.HttpRequest{Headers: headers, BodyArgs: args}
response := new(GenerateLinkResponse)
if err := a.client.HttpPost(GetLinkUrl, request, &client.HttpResponse{Result: response}); err != nil {
return nil, err
}
if !response.Success || response.ErrCode != 0 {
a.log.WithFields(logx.LogField{Key: "data", Value: map[string]any{"req": req, "resp": response}}).
Errorf("[t3UnionApiImpl][GenerateLink] response result error: %s", response.Msg)
return nil, errors.New(response.Msg)
}
return response.Data, nil
}
// GenerateCode 生成二维码
func (a *t3UnionApiImpl) GenerateCode(ctx context.Context, req GenerateCodeRequest) (*GenerateCodeData, error) {
args := util.StructToMap(req)
headers := a.buildHeader(http.MethodPost, GetMiniCodeUri, args)
for k, v := range a.client.headers {
headers[k] = v
}
request := &client.HttpRequest{Headers: headers, BodyArgs: args}
response := new(GenerateCodeResponse)
if err := a.client.HttpPost(GetMiniCodeUrl, request, &client.HttpResponse{Result: response}); err != nil {
return nil, err
}
if !response.Success || response.ErrCode != 0 {
a.log.WithFields(logx.LogField{Key: "data", Value: map[string]any{"req": req, "resp": response}}).
Errorf("[t3UnionApiImpl][GenerateCode] response result error: %s", response.Msg)
return nil, errors.New(response.Msg)
}
return response.Data, nil
}
// GeneratePoster 生成推广海报
func (a *t3UnionApiImpl) GeneratePoster(ctx context.Context, req GeneratePosterRequest) (*GeneratePosterData, error) {
args := util.StructToMap(req)
headers := a.buildHeader(http.MethodPost, GetPosterUri, args)
for k, v := range a.client.headers {
headers[k] = v
}
request := &client.HttpRequest{Headers: headers, BodyArgs: args}
response := new(GeneratePosterResponse)
if err := a.client.HttpPost(GetPosterUrl, request, &client.HttpResponse{Result: response}); err != nil {
return nil, err
}
if !response.Success || response.ErrCode != 0 {
a.log.WithFields(logx.LogField{Key: "data", Value: map[string]any{"req": req, "resp": response}}).
Errorf("[t3UnionApiImpl][GeneratePoster] response result error: %s", response.Msg)
return nil, errors.New(response.Msg)
}
return response.Data, nil
}
// QueryOrderList 查询订单列表
func (a *t3UnionApiImpl) QueryOrderList(ctx context.Context, req QueryOrderListRequest) (*QueryOrderData, error) {
if len(req.SupplierUuid) == 0 {
req.SupplierUuid = a.client.authConfig.SupplierID
}
args := util.StructToMap(req)
headers := a.buildHeader(http.MethodPost, GetOrderListUri, args)
for k, v := range a.client.headers {
headers[k] = v
}
request := &client.HttpRequest{Headers: headers, BodyArgs: args}
response := new(QueryOrderListResponse)
if err := a.client.HttpPost(GetOrderListUrl, request, &client.HttpResponse{Result: response}); err != nil {
return nil, err
}
if !response.Success || response.ErrCode != 0 {
a.log.WithFields(logx.LogField{Key: "data", Value: map[string]any{"req": req, "resp": response}}).
Errorf("[t3UnionApiImpl][QueryOrderList] response result error: %s", response.Msg)
return nil, errors.New(response.Msg)
}
return response.Data, nil
}