diff --git a/go.mod b/go.mod index 226c774..5a861eb 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.19 require ( github.com/stretchr/testify v1.8.4 github.com/zeromicro/go-zero v1.5.5 + github.com/zywaited/xcopy v1.1.0 ) require ( @@ -12,6 +13,7 @@ require ( github.com/fatih/color v1.15.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.17 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect go.opentelemetry.io/otel v1.14.0 // indirect diff --git a/platform/meituan-union/api.go b/platform/meituan-union/api.go index 0ccf2f6..618077e 100644 --- a/platform/meituan-union/api.go +++ b/platform/meituan-union/api.go @@ -4,8 +4,10 @@ import ( "fmt" "sort" "strings" + "time" "github.com/zeromicro/go-zero/core/logx" + "github.com/zywaited/xcopy" "gitee.com/chengdu-lenntc/third-platform-sdk/client" "gitee.com/chengdu-lenntc/third-platform-sdk/util" @@ -57,8 +59,14 @@ func (a *meituanUnionApiImpl) NotifySign(params map[string]interface{}) string { // GetLink 获取推广链接 func (a *meituanUnionApiImpl) GetLink(params GenerateLinkRequest) (*GenerateLinkResponse, error) { - params.Sign = a.Sign(util.StructToMap(params)) - queryArgs := util.StructToMap(params) + request := new(ThirdGenerateLinkRequest) + if err := xcopy.Copy(&request, params); err != nil { + a.log.WithFields().Errorf("[meituanUnionApiImpl][GetLink] copy request error: %v", err) + return nil, err + } + request.Appkey = a.client.authConfig.AppKey + request.Sign = a.Sign(util.StructToMap(request)) + queryArgs := util.StructToMap(request) 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 { @@ -69,8 +77,14 @@ func (a *meituanUnionApiImpl) GetLink(params GenerateLinkRequest) (*GenerateLink // MiniCode 获取小程序码 func (a *meituanUnionApiImpl) MiniCode(params MiniCodeRequest) (*MimiCodeResponse, error) { - params.Sign = a.Sign(util.StructToMap(params)) - queryArgs := util.StructToMap(params) + request := new(ThirdMiniCodeRequest) + if err := xcopy.Copy(&request, params); err != nil { + a.log.WithFields().Errorf("[meituanUnionApiImpl][GetLink] copy request error: %v", err) + return nil, err + } + request.Appkey = a.client.authConfig.AppKey + request.Sign = a.Sign(util.StructToMap(request)) + queryArgs := util.StructToMap(request) 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 { @@ -81,8 +95,14 @@ func (a *meituanUnionApiImpl) MiniCode(params MiniCodeRequest) (*MimiCodeRespons // GetOrderBySinge 获取单个订单 func (a *meituanUnionApiImpl) GetOrderBySinge(params GetOrderBySingeRequest) (*GetOrderBySingeResponse, error) { - params.Sign = a.Sign(util.StructToMap(params)) - queryArgs := util.StructToMap(params) + request := new(ThirdGetOrderBySingeRequest) + if err := xcopy.Copy(&request, params); err != nil { + a.log.WithFields().Errorf("[meituanUnionApiImpl][GetLink] copy request error: %v", err) + return nil, err + } + request.Appkey = a.client.authConfig.AppKey + request.Sign = a.Sign(util.StructToMap(request)) + queryArgs := util.StructToMap(request) 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 { @@ -93,11 +113,21 @@ func (a *meituanUnionApiImpl) GetOrderBySinge(params GetOrderBySingeRequest) (*G // GetOrderByBatch 批量获取订单 func (a *meituanUnionApiImpl) GetOrderByBatch(params GetOrderByBatchRequest) (*GetOrderByBatchResponse, error) { - params.Sign = a.Sign(util.StructToMap(params)) - queryArgs := util.StructToMap(params) + fmt.Printf("params: %+v\n", util.StructToMap(params)) + request := new(ThirdGetOrderByBatchRequest) + if err := xcopy.Copy(&request, params); err != nil { + a.log.WithFields().Errorf("[meituanUnionApiImpl][GetLink] copy request error: %v", err) + return nil, err + } + request.Appkey = a.client.authConfig.AppKey + request.Ts = int32(time.Now().Unix()) + request.Sign = a.Sign(util.StructToMap(request)) + queryArgs := util.StructToMap(request) + fmt.Printf("queryArgs: %+v\n", queryArgs) 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 { + a.log.Errorf("GetOrderByBatch error: %v", err) return nil, err } return response, nil diff --git a/platform/meituan-union/api_test.go b/platform/meituan-union/api_test.go new file mode 100644 index 0000000..903aebe --- /dev/null +++ b/platform/meituan-union/api_test.go @@ -0,0 +1,65 @@ +package meituan_union + +import ( + "context" + "testing" + + "github.com/stretchr/testify/suite" + "github.com/zeromicro/go-zero/core/logx" +) + +// api-单元测试 +type apiClientSuite struct { + suite.Suite + api MeituanUnionApi +} + +func TestApiClient(t *testing.T) { + suite.Run(t, new(apiClientSuite)) +} + +func (a *apiClientSuite) SetupSuite() { + log := logx.WithContext(context.Background()) + apiClient := NewApiClient(log, AuthConfig{ + AppKey: "8b0a6d711cd573b5b048c90820dbb3fe756", + SignKey: "3e4a697ecd9eafa27c2f3f4ccf22072d", + NotifyKey: "gb8cwkj53x", + }) + a.api = apiClient +} + +func (a *apiClientSuite) Test_Sign() { + data := map[string]interface{}{ + "method": "test", + } + sign := a.api.Sign(data) + a.T().Logf("=====[TestSign] sign: %s", sign) +} + +func (a *apiClientSuite) Test_GetOrderBySinge() { + req := GetOrderBySingeRequest{ + ActId: 33, + } + resp, err := a.api.GetOrderBySinge(req) + if !a.NoError(err) { + a.T().Error(err) + return + } + a.T().Logf("=====[Test_GetOrderBySinge] resp: %+v", resp) +} + +func (a *apiClientSuite) Test_GetOrderByBatch() { + req := GetOrderByBatchRequest{ + ActId: 33, + Page: 1, + Limit: 10, + StartTime: 1714147200, + //EndTime: 1714233600, + } + list, err := a.api.GetOrderByBatch(req) + if !a.NoError(err) { + a.T().Errorf("========[Test_GetOrderByBatch] error:%s", err) + return + } + a.T().Logf("=====[Test_GetOrderByBatch] list: %+v", list) +} diff --git a/platform/meituan-union/client.go b/platform/meituan-union/client.go index 6626230..f47c1e5 100644 --- a/platform/meituan-union/client.go +++ b/platform/meituan-union/client.go @@ -8,6 +8,7 @@ import ( // AuthConfig api鉴权参数 type AuthConfig struct { + AppKey string // 应用key SignKey string // 签名秘钥 NotifyKey string // 回调秘钥 } diff --git a/platform/meituan-union/third_types.go b/platform/meituan-union/third_types.go new file mode 100644 index 0000000..2fd40fa --- /dev/null +++ b/platform/meituan-union/third_types.go @@ -0,0 +1,105 @@ +package meituan_union + +// ThirdGenerateLinkRequest 生成推广链接请求 (第三方) +type ThirdGenerateLinkRequest struct { + ActId int64 `json:"actId"` // 活动id + Appkey string `json:"appkey"` // 应用appKey + LinkType int64 `json:"linkType"` // 链接类型 + ShortLink int64 `json:"shortLink"` // 是否生成短链接 + Sid string `json:"sid"` // 推广位id + Sign string `json:"sign,omitempty"` // 签名 +} + +// GenerateLinkResponse 生成推广链接响应 +type GenerateLinkResponse struct { + Status int64 `json:"status"` + Des string `json:"des"` + Data string `json:"data"` +} + +// ThirdMiniCodeRequest 获取小程序码请求(第三方) +type ThirdMiniCodeRequest struct { + ActId int64 `json:"actId"` + Appkey string `json:"appkey"` + Sid string `json:"sid"` + Sign string `json:"sign,omitempty"` + LinkType int64 `json:"linkType"` +} + +// MimiCodeResponse 获取小程序码响应 +type MimiCodeResponse struct { + Status int64 `json:"status"` + Des string `json:"des"` + Data string `json:"data"` +} + +// ThirdGetOrderBySingeRequest 获取单个订单请求 (第三方) +type ThirdGetOrderBySingeRequest struct { + Appkey string `json:"appkey"` + ActId int64 `json:"actId"` + Full int64 `json:"full"` + Sign string `json:"sign,omitempty"` + OrderId string `json:"orderId"` +} + +// GetOrderBySingeResponse 获取单个订单响应 +type GetOrderBySingeResponse struct { + Status int64 `json:"status"` + Des string `json:"des"` + Data OrderSinge `json:"data"` +} + +// OrderSinge 订单详情 +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"` +} + +// ThirdGetOrderByBatchRequest 批量获取订单请求 (第三方) +type ThirdGetOrderByBatchRequest struct { + Appkey string `json:"appkey"` // 应用appKey + Ts int32 `json:"ts"` // 请求时间戳 + ActId int32 `json:"actId"` // 活动id + StartTime int32 `json:"startTime"` // 开始时间戳 + EndTime int32 `json:"endTime"` // 结束时间戳 + Sign string `json:"sign,omitempty"` // 签名 + Page int32 `json:"page"` // 页码 + Limit int32 `json:"limit"` // 每页数量 +} + +// GetOrderByBatchResponse 批量获取订单响应 +type GetOrderByBatchResponse struct { + Total int64 `json:"total"` + DataList []OrderBatch `json:"dataList"` +} + +// OrderBatch 订单详情 +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"` +} diff --git a/platform/meituan-union/types.go b/platform/meituan-union/types.go index e3eb551..a44df80 100644 --- a/platform/meituan-union/types.go +++ b/platform/meituan-union/types.go @@ -1,105 +1,32 @@ package meituan_union -// GenerateLinkRequest 生成推广链接请求 +// GenerateLinkRequest 生成推广链接请求 (内部) 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"` -} - -// GenerateLinkResponse 生成推广链接响应 -type GenerateLinkResponse struct { - Status int64 `json:"status"` - Des string `json:"des"` - Data string `json:"data"` + ActId int64 `json:"actId"` // 活动id + LinkType int64 `json:"linkType"` // 链接类型 + ShortLink int64 `json:"shortLink"` // 是否生成短链接 + Sid string `json:"sid"` // 推广位id } // MiniCodeRequest 获取小程序码请求 type MiniCodeRequest struct { - ActId int64 `form:"actId"` - Appkey string `form:"appkey"` - Sid string `form:"sid"` - Sign string `form:"sign"` - LinkType int64 `form:"linkType"` -} - -// MimiCodeResponse 获取小程序码响应 -type MimiCodeResponse struct { - Status int64 `json:"status"` - Des string `json:"des"` - Data string `json:"data"` + ActId int64 `json:"actId"` + Sid string `json:"sid"` + LinkType int64 `json:"linkType"` } // GetOrderBySingeRequest 获取单个订单请求 type GetOrderBySingeRequest struct { - Appkey string `form:"appkey"` - ActId int64 `form:"actId"` - Full int64 `form:"full"` - Sign string `form:"sign"` - OrderId string `form:"orderId"` -} - -// GetOrderBySingeResponse 获取单个订单响应 -type GetOrderBySingeResponse struct { - Status int64 `json:"status"` - Des string `json:"des"` - Data OrderSinge `json:"data"` -} - -// OrderSinge 订单详情 -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"` + ActId int64 `json:"actId"` + Full int64 `json:"full"` + OrderId string `json:"orderId"` } // GetOrderByBatchRequest 批量获取订单请求 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"` -} - -// GetOrderByBatchResponse 批量获取订单响应 -type GetOrderByBatchResponse struct { - Total int64 `json:"total"` - DataList []OrderBatch `json:"dataList"` -} - -// OrderBatch 订单详情 -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"` + ActId int32 `json:"actId"` // 活动id + StartTime int32 `json:"startTime"` // 开始时间戳 + EndTime int32 `json:"endTime"` // 结束时间戳 + Page int32 `json:"page"` // 页码 + Limit int32 `json:"limit"` // 每页数量 } diff --git a/util/http.go b/util/http.go index 6b8d3ff..569f6b2 100644 --- a/util/http.go +++ b/util/http.go @@ -123,6 +123,7 @@ func (h *HttpUtil) Do() (hc *HttpUtil) { hc.Error = err return } + fmt.Printf("===== http response content: %s\n", content) hc.Response = &Response{ Status: resp.Status, StatusCode: resp.StatusCode, diff --git a/util/json.go b/util/json.go index f07e661..b590455 100644 --- a/util/json.go +++ b/util/json.go @@ -1,19 +1,24 @@ 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 -//} +import ( + "bytes" + "encoding/json" +) + +// StructToMap 将struct转为map +func StructToMap(info any) map[string]any { + result := make(map[string]any) + data, err := json.Marshal(info) + if err != nil { + return nil + } + + d := json.NewDecoder(bytes.NewReader(data)) + d.UseNumber() + err = d.Decode(&result) + //err = json.Unmarshal(data, &result) + if err != nil { + return nil + } + return result +} diff --git a/util/util.go b/util/util.go index 5ab0699..bd17954 100644 --- a/util/util.go +++ b/util/util.go @@ -1,17 +1,15 @@ 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 -} +//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 +//}