meituan-union平台api对接完成
This commit is contained in:
parent
15bcb2ed31
commit
d31b52d38a
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
.idea/
|
||||
vendor
|
||||
.vscode
|
||||
go.sum
|
||||
20
api/api.go
Normal file
20
api/api.go
Normal file
@ -0,0 +1,20 @@
|
||||
package api
|
||||
|
||||
type PromotionSdk interface {
|
||||
Sign(data map[string]interface{}) string //签名
|
||||
GetLink(r *GetLinkRequest) (*GetLinkResponse, error) //推广取链
|
||||
GetOrder(r *GetOrderRequest) (*GetOrderResponse, error) //拉取订单信息
|
||||
}
|
||||
|
||||
type PromotionConf struct {
|
||||
AppKey string
|
||||
AppSecret string
|
||||
Ext1 string
|
||||
Ext2 string
|
||||
Ext3 string
|
||||
Ext4 string
|
||||
}
|
||||
|
||||
func NewPromotionSdk(sdk PromotionSdk) PromotionSdk {
|
||||
return sdk
|
||||
}
|
||||
51
api/entity.go
Normal file
51
api/entity.go
Normal file
@ -0,0 +1,51 @@
|
||||
package api
|
||||
|
||||
type GetLinkRequest struct {
|
||||
ActivityId string `json:"activity_id"` //活动ID
|
||||
Position string `json:"position"` //推广位ID
|
||||
}
|
||||
|
||||
type GetLinkResponse struct {
|
||||
H5 string `json:"h5"`
|
||||
ShortLink string `json:"shortLink"`
|
||||
DeepLink string `json:"deepLink"`
|
||||
EvokeLink string `json:"evokeLink"`
|
||||
WechatApplet string `json:"wechatApplet"`
|
||||
WechatAppletQrcode string `json:"wechatAppletQrcode"`
|
||||
AlipayApplet string `json:"alipayApplet"`
|
||||
Tkl string `json:"tkl"`
|
||||
Poster string `json:"poster"`
|
||||
}
|
||||
|
||||
type GetOrderRequest struct {
|
||||
OrderNo string `json:"orderNo"`
|
||||
ActId string `json:"actId"`
|
||||
StartTime int64 `json:"startTime"`
|
||||
EndTime int64 `json:"endTime"`
|
||||
Page int64 `json:"page"`
|
||||
PageSize int64 `json:"pageSize"`
|
||||
}
|
||||
type OrderItem struct {
|
||||
OrderNo string `json:"orderNo"` //订单号
|
||||
ActId string `json:"actId"` //活动ID
|
||||
ActName string `json:"actName"` //活动名称
|
||||
Sid string `json:"sid"` //Sid
|
||||
OrderTitle string `json:"orderTitle"` //订标题
|
||||
Commission string `json:"commission"` //佣金
|
||||
CommissionRate string `json:"commissionRate"` //佣金比率
|
||||
OrderTime int64 `json:"orderTime"` //订单时间
|
||||
PayTime int64 `json:"payTime"` //支付时间
|
||||
ModifiedTime int64 `json:"modifiedTime"` //最后一次更新时间
|
||||
OrderPrice string `json:"orderPrice"` //订单金额
|
||||
PayPrice string `json:"payPrice"` //支付金额
|
||||
RefundPrice string `json:"refundPrice"` //退款金额
|
||||
RefundReason string `json:"refundReason"` //退款原因
|
||||
Status string `json:"status"` //状态
|
||||
Quantity int64 `json:"quantity"` //商品数量
|
||||
AppKey string `json:"appKey"`
|
||||
Ext string `json:"ext"` //拓展参数
|
||||
}
|
||||
type GetOrderResponse struct {
|
||||
Total int64 `json:"total"`
|
||||
List []*OrderItem `json:"list"`
|
||||
}
|
||||
106
client/client.go
Normal file
106
client/client.go
Normal file
@ -0,0 +1,106 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
|
||||
"chengdu-lenntc/third-platform-sdk/util"
|
||||
)
|
||||
|
||||
// HttpRequest http请求参数
|
||||
type HttpRequest struct {
|
||||
Headers map[string]string // 请求header参数
|
||||
QueryArgs map[string]any // 请求query参数
|
||||
BodyArgs map[string]any // 请求body参数
|
||||
}
|
||||
|
||||
// HttpResponse http响应结果
|
||||
type HttpResponse struct {
|
||||
Result any // 响应的body数据结构, 必须为指针类型
|
||||
RespHeader *http.Header // 响应header
|
||||
}
|
||||
|
||||
// ThirdClient 第三方平台的client
|
||||
type ThirdClient interface {
|
||||
// HttpGet GET请求
|
||||
HttpGet(url string, req *HttpRequest, resp *HttpResponse) error
|
||||
// HttpPost POST请求
|
||||
HttpPost(url string, req *HttpRequest, resp *HttpResponse) error
|
||||
// HttpPut PUT请求
|
||||
HttpPut(url string, req *HttpRequest, resp *HttpResponse) error
|
||||
// HttpDelete DELETE请求
|
||||
HttpDelete(url string, req *HttpRequest, resp *HttpResponse) error
|
||||
// DoHttp 发起http请求
|
||||
DoHttp(method string, url string, req *HttpRequest, resp *HttpResponse) error
|
||||
}
|
||||
|
||||
type ThirdClientImpl struct {
|
||||
log logx.Logger
|
||||
}
|
||||
|
||||
func NewThirdClient(log logx.Logger) *ThirdClientImpl {
|
||||
return &ThirdClientImpl{
|
||||
log: log,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ThirdClientImpl) HttpGet(url string, req *HttpRequest, resp *HttpResponse) error {
|
||||
return c.DoHttp(http.MethodGet, url, req, resp)
|
||||
}
|
||||
|
||||
func (c *ThirdClientImpl) HttpPost(url string, req *HttpRequest, resp *HttpResponse) error {
|
||||
return c.DoHttp(http.MethodPost, url, req, resp)
|
||||
}
|
||||
|
||||
func (c *ThirdClientImpl) HttpPut(url string, req *HttpRequest, resp *HttpResponse) error {
|
||||
return c.DoHttp(http.MethodPut, url, req, resp)
|
||||
}
|
||||
|
||||
func (c *ThirdClientImpl) HttpDelete(url string, req *HttpRequest, resp *HttpResponse) error {
|
||||
return c.DoHttp(http.MethodDelete, url, req, resp)
|
||||
}
|
||||
|
||||
func (c *ThirdClientImpl) DoHttp(method string, url string, req *HttpRequest, resp *HttpResponse) error {
|
||||
// 发起请求
|
||||
reqConfig := &util.ReqConfig{
|
||||
Headers: req.Headers,
|
||||
QueryArgs: req.QueryArgs,
|
||||
BodyArgs: req.BodyArgs,
|
||||
}
|
||||
hc := util.NewHttpClient(c.log).NewRequest(method, url, reqConfig).Do()
|
||||
if hc.Error != nil {
|
||||
return hc.Error
|
||||
}
|
||||
var responseHeader *http.Header
|
||||
if hc.Response != nil {
|
||||
responseHeader = &hc.Response.Header
|
||||
}
|
||||
// 检查http响应错误
|
||||
if err := c.checkResponseError(hc.Response); err != nil {
|
||||
c.log.WithFields([]logx.LogField{{Key: "method", Value: method}, {Key: "url", Value: url}, {Key: "reqConfig", Value: reqConfig}}...).
|
||||
Errorf("[ThirdClientImpl][DoHttp] checkResponseError err:%s", err)
|
||||
return err
|
||||
}
|
||||
// 获取响应结果
|
||||
if resp == nil {
|
||||
return nil
|
||||
}
|
||||
result := resp.Result
|
||||
if err := hc.Result(result).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
resp.Result = result
|
||||
resp.RespHeader = responseHeader
|
||||
return nil
|
||||
}
|
||||
|
||||
// 检查http响应错误
|
||||
func (c *ThirdClientImpl) checkResponseError(r *util.Response) error {
|
||||
if r.StatusCode >= 200 && r.StatusCode < 300 {
|
||||
return nil
|
||||
}
|
||||
return errors.New(fmt.Sprintf("http response error, status code: %d, status: %s", r.StatusCode, r.Status))
|
||||
}
|
||||
7
go.mod
Normal file
7
go.mod
Normal file
@ -0,0 +1,7 @@
|
||||
module chengdu-lenntc/third-platform-sdk
|
||||
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/zeromicro/go-zero v1.5.5
|
||||
)
|
||||
41
platform/eleme-union/api.go
Normal file
41
platform/eleme-union/api.go
Normal file
@ -0,0 +1,41 @@
|
||||
package eleme_union
|
||||
|
||||
import (
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
// todo:: 调用第三方平台的api
|
||||
// Api defines the interface of eleme_union api
|
||||
type Api interface {
|
||||
Sign(data map[string]interface{}) string
|
||||
GetLink() error
|
||||
GetOrder() error
|
||||
}
|
||||
|
||||
type ApiImpl struct {
|
||||
log logx.Logger
|
||||
client *Client
|
||||
}
|
||||
|
||||
func NewApiImpl(log logx.Logger, client *Client) Api {
|
||||
return &ApiImpl{
|
||||
log: log,
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
||||
// todo::
|
||||
func (a *ApiImpl) Sign(data map[string]interface{}) string {
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// todo::
|
||||
func (a *ApiImpl) GetLink() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// todo::
|
||||
func (a *ApiImpl) GetOrder() error {
|
||||
return nil
|
||||
}
|
||||
54
platform/eleme-union/client.go
Normal file
54
platform/eleme-union/client.go
Normal file
@ -0,0 +1,54 @@
|
||||
package eleme_union
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
|
||||
"chengdu-lenntc/third-platform-sdk/client"
|
||||
"chengdu-lenntc/third-platform-sdk/util"
|
||||
)
|
||||
|
||||
// AuthConfig api鉴权参数
|
||||
type AuthConfig struct {
|
||||
}
|
||||
|
||||
// todo:: 连接第三方平台的client
|
||||
type Client struct {
|
||||
client.ThirdClient
|
||||
log logx.Logger
|
||||
authConfig AuthConfig
|
||||
}
|
||||
|
||||
func NewClient(log logx.Logger, conf AuthConfig) *Client {
|
||||
// todo:: 请求第三方平台的配置参数
|
||||
return &Client{
|
||||
ThirdClient: client.NewThirdClient(log),
|
||||
log: log,
|
||||
authConfig: conf,
|
||||
}
|
||||
}
|
||||
|
||||
// todo:: DoHttp 发起http请求
|
||||
func (c *Client) DoHttp(method string, url string, req *client.HttpRequest, resp *client.HttpResponse) error {
|
||||
// todo:: api请求频率限制?
|
||||
c.apiRateLimit()
|
||||
// 发起请求
|
||||
err := c.ThirdClient.DoHttp(method, url, req, resp)
|
||||
return err
|
||||
}
|
||||
|
||||
// todo:: 请求api的频率限制
|
||||
func (c *Client) apiRateLimit() {
|
||||
|
||||
}
|
||||
|
||||
// todo:: 检查api请求频率限制
|
||||
func (c *Client) checkRateLimit(header *http.Header) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// todo:: 检查http响应错误
|
||||
func (c *Client) checkResponseError(r *util.Response) error {
|
||||
return nil
|
||||
}
|
||||
1
platform/eleme-union/consts.go
Normal file
1
platform/eleme-union/consts.go
Normal file
@ -0,0 +1 @@
|
||||
package eleme_union
|
||||
1
platform/eleme-union/index.go
Normal file
1
platform/eleme-union/index.go
Normal file
@ -0,0 +1 @@
|
||||
package eleme_union
|
||||
3
platform/eleme-union/types.go
Normal file
3
platform/eleme-union/types.go
Normal file
@ -0,0 +1,3 @@
|
||||
package eleme_union
|
||||
|
||||
// todo:: 定义第三方平台api接口的结构体
|
||||
28
platform/meituan-csr/api.go
Normal file
28
platform/meituan-csr/api.go
Normal file
@ -0,0 +1,28 @@
|
||||
package meituan_csr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
|
||||
"chengdu-lenntc/third-platform-sdk/client"
|
||||
"chengdu-lenntc/third-platform-sdk/util"
|
||||
)
|
||||
|
||||
// Api 调用第三方平台的api
|
||||
type MeituanCsrApi interface {
|
||||
}
|
||||
|
||||
type meituanApiImpl struct {
|
||||
log logx.Logger
|
||||
client *Client
|
||||
}
|
||||
|
||||
func newMeituanApiImpl(log logx.Logger, client *Client) MeituanCsrApi {
|
||||
return &meituanApiImpl{
|
||||
log: log,
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
1
platform/meituan-csr/client.go
Normal file
1
platform/meituan-csr/client.go
Normal file
@ -0,0 +1 @@
|
||||
package meituan_csr
|
||||
1
platform/meituan-csr/consts.go
Normal file
1
platform/meituan-csr/consts.go
Normal file
@ -0,0 +1 @@
|
||||
package meituan_csr
|
||||
1
platform/meituan-csr/types.go
Normal file
1
platform/meituan-csr/types.go
Normal file
@ -0,0 +1 @@
|
||||
package meituan_csr
|
||||
107
platform/meituan-union/api.go
Normal file
107
platform/meituan-union/api.go
Normal file
@ -0,0 +1,107 @@
|
||||
package meituan_union
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
|
||||
"chengdu-lenntc/third-platform-sdk/client"
|
||||
"chengdu-lenntc/third-platform-sdk/util"
|
||||
)
|
||||
|
||||
// Api 调用第三方平台的api
|
||||
type MeituanUnionApi interface {
|
||||
GetLink(params GenerateLinkRequest) (*GenerateLinkResponse, error)
|
||||
MiniCode(params MiniCodeRequest) (*MimiCodeResponse, error)
|
||||
GetOrderBySinge(params GetOrderBySingeRequest) (*GetOrderBySingeResponse, error)
|
||||
GetOrderByBatch(params GetOrderByBatchRequest) (*GetOrderByBatchResponse, error)
|
||||
}
|
||||
|
||||
type meituanApiImpl struct {
|
||||
log logx.Logger
|
||||
client *Client
|
||||
}
|
||||
|
||||
func newMeituanApiImpl(log logx.Logger, client *Client) MeituanUnionApi {
|
||||
return &meituanApiImpl{
|
||||
log: log,
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *meituanApiImpl) GetLink(params GenerateLinkRequest) (*GenerateLinkResponse, error) {
|
||||
params.Sign = a.sign(util.StructToMap(params))
|
||||
queryArgs := util.StructToMap(params)
|
||||
req := &client.HttpRequest{Headers: a.client.Headers, QueryArgs: queryArgs}
|
||||
response := new(GenerateLinkResponse)
|
||||
if err := a.client.HttpGet(GetLinkUrl, req, &client.HttpResponse{Result: response}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (a *meituanApiImpl) MiniCode(params MiniCodeRequest) (*MimiCodeResponse, error) {
|
||||
params.Sign = a.sign(util.StructToMap(params))
|
||||
queryArgs := util.StructToMap(params)
|
||||
req := &client.HttpRequest{Headers: a.client.Headers, QueryArgs: queryArgs}
|
||||
response := new(MimiCodeResponse)
|
||||
if err := a.client.HttpGet(GetMiniCode, req, &client.HttpResponse{Result: response}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
func (a *meituanApiImpl) GetOrderBySinge(params GetOrderBySingeRequest) (*GetOrderBySingeResponse, error) {
|
||||
params.Sign = a.sign(util.StructToMap(params))
|
||||
queryArgs := util.StructToMap(params)
|
||||
req := &client.HttpRequest{Headers: a.client.Headers, QueryArgs: queryArgs}
|
||||
response := new(GetOrderBySingeResponse)
|
||||
if err := a.client.HttpGet(GetOrderSinge, req, &client.HttpResponse{Result: response}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
func (a *meituanApiImpl) GetOrderByBatch(params GetOrderByBatchRequest) (*GetOrderByBatchResponse, error) {
|
||||
params.Sign = a.sign(util.StructToMap(params))
|
||||
queryArgs := util.StructToMap(params)
|
||||
req := &client.HttpRequest{Headers: a.client.Headers, QueryArgs: queryArgs}
|
||||
response := new(GetOrderByBatchResponse)
|
||||
if err := a.client.HttpGet(GetOrderBatch, req, &client.HttpResponse{Result: response}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (a *meituanApiImpl) sign(params map[string]interface{}) string {
|
||||
kvPairs := a.getSignStr(params)
|
||||
sort.Strings(kvPairs)
|
||||
paramStr := strings.Join(kvPairs, "")
|
||||
return util.Md5String(a.client.authConfig.SignKey + paramStr + a.client.authConfig.SignKey)
|
||||
}
|
||||
|
||||
func (a *meituanApiImpl) notifySign(params map[string]interface{}) string {
|
||||
kvPairs := a.getSignStr(params)
|
||||
sort.Strings(kvPairs)
|
||||
paramStr := strings.Join(kvPairs, "")
|
||||
return util.Md5String(a.client.authConfig.NotifyKey + paramStr + a.client.authConfig.NotifyKey)
|
||||
}
|
||||
|
||||
func (a *meituanApiImpl) getSignStr(dataMap map[string]any) []string {
|
||||
var kvPairs []string
|
||||
for k, v := range dataMap {
|
||||
key := a.lowerFirstLetter(k)
|
||||
if key == "sign" || key == "Sign" {
|
||||
continue
|
||||
}
|
||||
kvPairs = append(kvPairs, fmt.Sprintf("%s%v", key, v))
|
||||
}
|
||||
return kvPairs
|
||||
}
|
||||
|
||||
func (a *meituanApiImpl) lowerFirstLetter(s string) string {
|
||||
if len(s) == 0 {
|
||||
return s
|
||||
}
|
||||
return strings.ToLower(string(s[0])) + s[1:]
|
||||
}
|
||||
35
platform/meituan-union/client.go
Normal file
35
platform/meituan-union/client.go
Normal file
@ -0,0 +1,35 @@
|
||||
package meituan_union
|
||||
|
||||
import (
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
|
||||
"chengdu-lenntc/third-platform-sdk/client"
|
||||
)
|
||||
|
||||
// AuthConfig api鉴权参数
|
||||
type AuthConfig struct {
|
||||
SignKey string //签名秘钥
|
||||
NotifyKey string //回调秘钥
|
||||
}
|
||||
|
||||
// 连接第三方平台的client
|
||||
type Client struct {
|
||||
client.ThirdClient
|
||||
log logx.Logger
|
||||
authConfig AuthConfig
|
||||
Headers map[string]string
|
||||
}
|
||||
|
||||
func newClient(log logx.Logger, conf AuthConfig) *Client {
|
||||
// todo:: 请求第三方平台的配置参数
|
||||
return &Client{
|
||||
ThirdClient: client.NewThirdClient(log),
|
||||
log: log,
|
||||
authConfig: conf,
|
||||
}
|
||||
}
|
||||
|
||||
func NewApiClient(log logx.Logger, conf AuthConfig) MeituanUnionApi {
|
||||
clt := newClient(log, conf)
|
||||
return newMeituanApiImpl(log, clt)
|
||||
}
|
||||
9
platform/meituan-union/consts.go
Normal file
9
platform/meituan-union/consts.go
Normal file
@ -0,0 +1,9 @@
|
||||
package meituan_union
|
||||
|
||||
const (
|
||||
Domain = "https://openapi.meituan.com"
|
||||
GetLinkUrl = Domain + "/api/generateLink"
|
||||
GetMiniCode = Domain + "/api/miniCode"
|
||||
GetOrderSinge = Domain + "/api/order"
|
||||
GetOrderBatch = Domain + "/api/orderList"
|
||||
)
|
||||
1
platform/meituan-union/index.go
Normal file
1
platform/meituan-union/index.go
Normal file
@ -0,0 +1 @@
|
||||
package meituan_union
|
||||
87
platform/meituan-union/types.go
Normal file
87
platform/meituan-union/types.go
Normal file
@ -0,0 +1,87 @@
|
||||
package meituan_union
|
||||
|
||||
type GenerateLinkRequest struct {
|
||||
ActId int64 `form:"actId"`
|
||||
Appkey string `form:"appkey"`
|
||||
LinkType int64 `form:"linkType"`
|
||||
ShortLink int64 `form:"shortLink"`
|
||||
Sid string `form:"sid"`
|
||||
Sign string `form:"sign"`
|
||||
}
|
||||
|
||||
type MiniCodeRequest struct {
|
||||
ActId int64 `form:"actId"`
|
||||
Appkey string `form:"appkey"`
|
||||
Sid string `form:"sid"`
|
||||
Sign string `form:"sign"`
|
||||
LinkType int64 `form:"linkType"`
|
||||
}
|
||||
|
||||
type MimiCodeResponse struct {
|
||||
}
|
||||
|
||||
type GenerateLinkResponse struct {
|
||||
Status int64 `json:"status"`
|
||||
Des string `json:"des"`
|
||||
Data string `json:"data"`
|
||||
}
|
||||
type GetOrderBySingeRequest struct {
|
||||
Appkey string `form:"appkey"`
|
||||
ActId int64 `form:"actId"`
|
||||
Full int64 `form:"full"`
|
||||
Sign string `form:"sign"`
|
||||
OrderId string `form:"orderId"`
|
||||
}
|
||||
type GetOrderBySingeResponse struct {
|
||||
Status int64 `json:"status"`
|
||||
Des string `json:"des"`
|
||||
Data OrderSinge `json:"data"`
|
||||
}
|
||||
type OrderSinge struct {
|
||||
ActId int64 `json:"actId"`
|
||||
Quantity int64 `json:"quantity"`
|
||||
OrderId string `json:"orderId"`
|
||||
PayTime string `json:"paytime"`
|
||||
ModTime string `json:"modTime"`
|
||||
PayPrice string `json:"payprice"`
|
||||
Profit string `json:"profit"`
|
||||
CpaProfit string `json:"cpaProfit"`
|
||||
Sid string `json:"sid"`
|
||||
AppKey string `json:"appkey"`
|
||||
SmsTitle string `json:"smstitle"`
|
||||
Status int64 `json:"status"`
|
||||
RiskOrder int64 `json:"riskOrder"`
|
||||
RefundProfit string `json:"refundProfit"`
|
||||
CpaRefundProfit string `json:"cpaRefundProfit"`
|
||||
}
|
||||
|
||||
type GetOrderByBatchRequest struct {
|
||||
Appkey string `form:"appkey"`
|
||||
Ts string `form:"ts"`
|
||||
ActId string `form:"actId"`
|
||||
StartTime string `form:"startTime"`
|
||||
EndTime string `form:"endTime"`
|
||||
Sign string `form:"sign"`
|
||||
Page string `form:"page"`
|
||||
Limit string `form:"limit"`
|
||||
}
|
||||
type GetOrderByBatchResponse struct {
|
||||
Total int64 `json:"total"`
|
||||
DataList []OrderBatch `json:"dataList"`
|
||||
}
|
||||
type OrderBatch struct {
|
||||
ActId int64 `json:"actId"`
|
||||
OrderId string `json:"orderId"`
|
||||
PayTime string `json:"paytime"`
|
||||
ModTime string `json:"modTime"`
|
||||
PayPrice string `json:"payprice"`
|
||||
Profit string `json:"profit"`
|
||||
CpaProfit string `json:"cpaProfit"`
|
||||
Sid string `json:"sid"`
|
||||
AppKey string `json:"appkey"`
|
||||
SmsTitle string `json:"smstitle"`
|
||||
Status int64 `json:"status"`
|
||||
RiskOrder int64 `json:"riskOrder"`
|
||||
RefundProfit string `json:"refundProfit"`
|
||||
CpaRefundProfit string `json:"cpaRefundProfit"`
|
||||
}
|
||||
202
util/http.go
Normal file
202
util/http.go
Normal file
@ -0,0 +1,202 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
netUrl "net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
const (
|
||||
TimeOut = time.Duration(30) * time.Second // http请求超时时间, 默认30s
|
||||
)
|
||||
|
||||
type HttpClient struct {
|
||||
log logx.Logger
|
||||
ReqConfig *ReqConfig // 请求参数
|
||||
TimeOut time.Duration // 超时时间
|
||||
Request *http.Request // 请求request
|
||||
Response *Response // 响应结果
|
||||
Error error
|
||||
}
|
||||
|
||||
// ReqConfig 请求参数
|
||||
type ReqConfig struct {
|
||||
Headers map[string]string
|
||||
QueryArgs map[string]any
|
||||
BodyArgs map[string]any
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
Status string // e.g. "200 OK"
|
||||
StatusCode int // e.g. 200
|
||||
Header http.Header
|
||||
Body []byte // body实体,即io.ReadAll(resp.body)后的结果
|
||||
}
|
||||
|
||||
func NewHttpClient(log logx.Logger) *HttpClient {
|
||||
return &HttpClient{
|
||||
log: log,
|
||||
}
|
||||
}
|
||||
|
||||
// Get GET请求
|
||||
// @param url 请求的http地址
|
||||
// @param reqConfig 中header、query、body等参数
|
||||
func (h *HttpClient) Get(url string, reqConfig *ReqConfig) *HttpClient {
|
||||
return h.NewRequest(http.MethodGet, url, reqConfig)
|
||||
}
|
||||
|
||||
// Post POST请求
|
||||
func (h *HttpClient) Post(url string, reqConfig *ReqConfig) *HttpClient {
|
||||
return h.NewRequest(http.MethodPost, url, reqConfig)
|
||||
}
|
||||
|
||||
// Put PUT请求
|
||||
func (h *HttpClient) Put(url string, reqConfig *ReqConfig) *HttpClient {
|
||||
return h.NewRequest(http.MethodPut, url, reqConfig)
|
||||
}
|
||||
|
||||
// Delete DELETE请求
|
||||
func (h *HttpClient) Delete(url string, reqConfig *ReqConfig) *HttpClient {
|
||||
return h.NewRequest(http.MethodDelete, url, reqConfig)
|
||||
}
|
||||
|
||||
// NewRequest 组装请求参数
|
||||
func (h *HttpClient) NewRequest(method, url string, reqConfig *ReqConfig) (hc *HttpClient) {
|
||||
if h.Error != nil {
|
||||
return h
|
||||
}
|
||||
h.ReqConfig = reqConfig
|
||||
hc = h
|
||||
// 请求
|
||||
req, err := http.NewRequest(method, url, nil)
|
||||
if err != nil {
|
||||
h.log.WithFields([]logx.LogField{{Key: "method", Value: method}, {Key: "url", Value: url}, {Key: "reqConfig", Value: reqConfig}}...).
|
||||
Errorf("[HttpClient][NewRequest] http new request error", err)
|
||||
hc.Error = err
|
||||
return
|
||||
}
|
||||
hc.Request = req
|
||||
// 请求参数
|
||||
err = hc.requestConfig()
|
||||
if err != nil {
|
||||
hc.Error = err
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Do http请求及响应处理
|
||||
func (h *HttpClient) Do() (hc *HttpClient) {
|
||||
if h.Error != nil {
|
||||
return h
|
||||
}
|
||||
hc = h
|
||||
// http请求
|
||||
timeOut := hc.TimeOut
|
||||
if hc.TimeOut == 0 {
|
||||
timeOut = TimeOut
|
||||
}
|
||||
client := &http.Client{}
|
||||
client.Timeout = timeOut
|
||||
// 开始请求
|
||||
resp, err := client.Do(hc.Request)
|
||||
if err != nil {
|
||||
h.log.WithFields(logx.LogField{Key: "req", Value: hc.Request}).
|
||||
Errorf("[HttpClient][Do] http client do error", err)
|
||||
hc.Error = err
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
content, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
h.log.WithFields(logx.LogField{Key: "req", Value: hc.Request}).
|
||||
Errorf("[HttpClient][Do] http response ReadAll error", err)
|
||||
hc.Error = err
|
||||
return
|
||||
}
|
||||
hc.Response = &Response{
|
||||
Status: resp.Status,
|
||||
StatusCode: resp.StatusCode,
|
||||
Header: resp.Header,
|
||||
Body: content,
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Result 获取http的响应结果
|
||||
// @param result 为结构体(指针类型),解析http请求返回数据json.Unmarshal后的结构
|
||||
func (h *HttpClient) Result(result any) (hc *HttpClient) {
|
||||
if h.Error != nil {
|
||||
return h
|
||||
}
|
||||
hc = h
|
||||
if result == nil {
|
||||
return
|
||||
}
|
||||
if hc.Response == nil || len(hc.Response.Body) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
err := json.Unmarshal(hc.Response.Body, &result)
|
||||
if err != nil {
|
||||
h.log.WithFields(logx.LogField{Key: "HttpClient", Value: hc}, logx.LogField{Key: "result", Value: result}).
|
||||
Errorf("[HttpClient][Result] http response body json unmarshal error", err)
|
||||
hc.Error = err
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 请求参数
|
||||
func (h *HttpClient) requestConfig() error {
|
||||
if h.Request == nil {
|
||||
return errors.New("http request is nil")
|
||||
}
|
||||
if h.ReqConfig == nil {
|
||||
return nil
|
||||
}
|
||||
// header参数
|
||||
if h.ReqConfig.Headers != nil {
|
||||
for key, value := range h.ReqConfig.Headers {
|
||||
h.Request.Header.Set(key, value)
|
||||
}
|
||||
}
|
||||
|
||||
// 请求query参数
|
||||
queryParams := h.Request.URL.Query()
|
||||
if h.ReqConfig.QueryArgs != nil {
|
||||
for key, value := range h.ReqConfig.QueryArgs {
|
||||
queryParams.Add(key, fmt.Sprint(value))
|
||||
}
|
||||
}
|
||||
h.Request.URL.RawQuery = queryParams.Encode()
|
||||
// 请求body参数
|
||||
if h.ReqConfig.BodyArgs != nil {
|
||||
switch h.Request.Header.Get("Content-Type") {
|
||||
case "application/x-www-form-urlencoded":
|
||||
form := make(netUrl.Values)
|
||||
for k, v := range h.ReqConfig.BodyArgs {
|
||||
form.Add(k, fmt.Sprint(v))
|
||||
}
|
||||
h.Request.Body = io.NopCloser(strings.NewReader(form.Encode()))
|
||||
case "application/json":
|
||||
data, err := json.Marshal(h.ReqConfig.BodyArgs)
|
||||
if err != nil {
|
||||
h.Error = err
|
||||
return err
|
||||
}
|
||||
h.Request.Body = io.NopCloser(strings.NewReader(string(data)))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
19
util/json.go
Normal file
19
util/json.go
Normal file
@ -0,0 +1,19 @@
|
||||
package util
|
||||
|
||||
//// StructToMap 将struct转为map
|
||||
//func StructToMap(info any) (map[string]any, error) {
|
||||
// result := make(map[string]any)
|
||||
// data, err := json.Marshal(info)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
//
|
||||
// d := json.NewDecoder(bytes.NewReader(data))
|
||||
// d.UseNumber()
|
||||
// err = d.Decode(&result)
|
||||
// //err = json.Unmarshal(data, &result)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// return result, nil
|
||||
//}
|
||||
13
util/md5.go
Normal file
13
util/md5.go
Normal file
@ -0,0 +1,13 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
)
|
||||
|
||||
// Md5String 字符串计算md5
|
||||
func Md5String(v string) string {
|
||||
h := md5.New()
|
||||
h.Write([]byte(v))
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
17
util/util.go
Normal file
17
util/util.go
Normal file
@ -0,0 +1,17 @@
|
||||
package util
|
||||
|
||||
import "reflect"
|
||||
|
||||
func StructToMap(obj interface{}) map[string]any {
|
||||
objValue := reflect.ValueOf(obj)
|
||||
objType := objValue.Type()
|
||||
|
||||
data := make(map[string]any)
|
||||
for i := 0; i < objValue.NumField(); i++ {
|
||||
field := objValue.Field(i)
|
||||
key := objType.Field(i).Name
|
||||
value := field.Interface()
|
||||
data[key] = value
|
||||
}
|
||||
return data
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user