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