Compare commits
No commits in common. "98580f4b7bea88a743761de0bca7f51e8994fec8" and "bfd212cbb3e23a7115ac4e0ada67f53f5f4fd12f" have entirely different histories.
98580f4b7b
...
bfd212cbb3
1
go.mod
1
go.mod
@ -28,7 +28,6 @@ require (
|
|||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||||
github.com/spf13/cast v1.7.0 // indirect
|
|
||||||
go.opentelemetry.io/otel v1.14.0 // indirect
|
go.opentelemetry.io/otel v1.14.0 // indirect
|
||||||
go.opentelemetry.io/otel/exporters/jaeger v1.14.0 // indirect
|
go.opentelemetry.io/otel/exporters/jaeger v1.14.0 // indirect
|
||||||
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 // indirect
|
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 // indirect
|
||||||
|
|||||||
35
index.go
35
index.go
@ -2,11 +2,7 @@ package third_platform_sdk
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
|
||||||
"repository.lenntc.com/lenntc/third-platform-sdk/platform/fliggy"
|
"repository.lenntc.com/lenntc/third-platform-sdk/platform/fliggy"
|
||||||
"repository.lenntc.com/lenntc/third-platform-sdk/platform/meituan"
|
|
||||||
shoutu_show "repository.lenntc.com/lenntc/third-platform-sdk/platform/shoutu-show"
|
|
||||||
"repository.lenntc.com/lenntc/third-platform-sdk/platform/youpiaopiao"
|
|
||||||
|
|
||||||
didiunion "repository.lenntc.com/lenntc/third-platform-sdk/platform/didi-union"
|
didiunion "repository.lenntc.com/lenntc/third-platform-sdk/platform/didi-union"
|
||||||
elemeunion "repository.lenntc.com/lenntc/third-platform-sdk/platform/eleme-union"
|
elemeunion "repository.lenntc.com/lenntc/third-platform-sdk/platform/eleme-union"
|
||||||
@ -24,7 +20,7 @@ const (
|
|||||||
PlatformElemeUnion = "ele"
|
PlatformElemeUnion = "ele"
|
||||||
// PlatformMeituanCsr 美团分销联盟
|
// PlatformMeituanCsr 美团分销联盟
|
||||||
PlatformMeituanCsr = "meituan_csr"
|
PlatformMeituanCsr = "meituan_csr"
|
||||||
// PlatformMeituanUnion 美团千载
|
// PlatformMeituanUnion 美团联盟
|
||||||
PlatformMeituanUnion = "meituan_union"
|
PlatformMeituanUnion = "meituan_union"
|
||||||
// PlatformDidiUnion 滴滴联盟
|
// PlatformDidiUnion 滴滴联盟
|
||||||
PlatformDidiUnion = "didi_union"
|
PlatformDidiUnion = "didi_union"
|
||||||
@ -38,28 +34,19 @@ const (
|
|||||||
PlatformElongHotel = "elong_hotel"
|
PlatformElongHotel = "elong_hotel"
|
||||||
// PlatformFliggy 飞猪
|
// PlatformFliggy 飞猪
|
||||||
PlatformFliggy = "fliggy"
|
PlatformFliggy = "fliggy"
|
||||||
// PlatformShoutuShow 守兔演出
|
|
||||||
PlatformShoutuShow = "shoutu_show"
|
|
||||||
// PlatformYouPiaoPiao 有票票
|
|
||||||
PlatformYouPiaoPiao = "youpiaopiao"
|
|
||||||
// PlatformMeituan 美团联盟
|
|
||||||
PlatformMeituan = "meituan"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// PlatformNameMap 平台名称
|
// PlatformNameMap 平台名称
|
||||||
var PlatformNameMap = map[string]string{
|
var PlatformNameMap = map[string]string{
|
||||||
PlatformElemeUnion: "饿了么联盟",
|
PlatformElemeUnion: "饿了么联盟",
|
||||||
PlatformMeituanCsr: "美团分销联盟",
|
PlatformMeituanCsr: "美团分销联盟",
|
||||||
PlatformMeituanUnion: "美团千载",
|
PlatformMeituanUnion: "美团联盟",
|
||||||
PlatformDidiUnion: "滴滴联盟",
|
PlatformDidiUnion: "滴滴联盟",
|
||||||
PlatformT3Union: "t3联盟",
|
PlatformT3Union: "t3联盟",
|
||||||
PlatformMeituanMedia: "美团-美天赚",
|
PlatformMeituanMedia: "美团-美天赚",
|
||||||
PlatformJutuike: "聚推客",
|
PlatformJutuike: "聚推客",
|
||||||
PlatformElongHotel: "同程酒店",
|
PlatformElongHotel: "同程酒店",
|
||||||
PlatformFliggy: "飞猪",
|
PlatformFliggy: "飞猪",
|
||||||
PlatformShoutuShow: "守兔演出",
|
|
||||||
PlatformYouPiaoPiao: "有票票",
|
|
||||||
PlatformMeituan: "美团联盟",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPlatformName 获取平台名称
|
// GetPlatformName 获取平台名称
|
||||||
@ -77,7 +64,7 @@ func NewMeituanCsrApi(log logx.Logger, conf meituancsr.AuthConfig) meituancsr.Me
|
|||||||
return meituancsr.NewApiClient(log, conf)
|
return meituancsr.NewApiClient(log, conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewMeituanUnionApi 美团千载
|
// NewMeituanUnionApi 美团联盟
|
||||||
func NewMeituanUnionApi(log logx.Logger, conf meituanunion.AuthConfig) meituanunion.MeituanUnionApi {
|
func NewMeituanUnionApi(log logx.Logger, conf meituanunion.AuthConfig) meituanunion.MeituanUnionApi {
|
||||||
return meituanunion.NewApiClient(log, conf)
|
return meituanunion.NewApiClient(log, conf)
|
||||||
}
|
}
|
||||||
@ -107,22 +94,6 @@ func NewElongHotelApi(log logx.Logger, conf elonghotel.AuthConfig) elonghotel.El
|
|||||||
return elonghotel.NewApiClient(log, conf)
|
return elonghotel.NewApiClient(log, conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFliggyApi 飞猪
|
|
||||||
func NewFliggyApi(log logx.Logger, conf fliggy.AuthConfig) fliggy.FliggyApi {
|
func NewFliggyApi(log logx.Logger, conf fliggy.AuthConfig) fliggy.FliggyApi {
|
||||||
return fliggy.NewApiClient(log, conf)
|
return fliggy.NewApiClient(log, conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewShoutuShow 守兔
|
|
||||||
func NewShoutuShow(log logx.Logger, conf shoutu_show.AuthConfig) shoutu_show.ShouTuShowApi {
|
|
||||||
return shoutu_show.NewApiClient(log, conf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewYouPiaoPiao 有票票
|
|
||||||
func NewYouPiaoPiao(log logx.Logger, conf youpiaopiao.AuthConfig) youpiaopiao.YouPiaoPiaoApi {
|
|
||||||
return youpiaopiao.NewApiClient(log, conf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewMeituanApi 美团联盟
|
|
||||||
func NewMeituanApi(log logx.Logger, conf meituan.AuthConfig) meituan.MeituanApi {
|
|
||||||
return meituan.NewApiClient(log, conf)
|
|
||||||
}
|
|
||||||
|
|||||||
@ -24,8 +24,8 @@ func TestApiClient(t *testing.T) {
|
|||||||
func (a *apiClientSuite) SetupSuite() {
|
func (a *apiClientSuite) SetupSuite() {
|
||||||
log := logx.WithContext(context.Background())
|
log := logx.WithContext(context.Background())
|
||||||
apiClient := NewApiClient(log, AuthConfig{
|
apiClient := NewApiClient(log, AuthConfig{
|
||||||
AppKey: "",
|
AppKey: "2M0QUa0o6ER8nuX1",
|
||||||
AppSecret: "",
|
AppSecret: "obvJ5mmV45ZWA3YpO95njR1xH62JT50h",
|
||||||
})
|
})
|
||||||
a.api = apiClient
|
a.api = apiClient
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,8 +27,8 @@ func TestApiClient(t *testing.T) {
|
|||||||
func (a *apiClientSuite) SetupSuite() {
|
func (a *apiClientSuite) SetupSuite() {
|
||||||
log := logx.WithContext(context.Background())
|
log := logx.WithContext(context.Background())
|
||||||
apiClient := NewApiClient(log, AuthConfig{
|
apiClient := NewApiClient(log, AuthConfig{
|
||||||
AppKey: "",
|
AppKey: "34632005",
|
||||||
AppSecret: "",
|
AppSecret: "b0e6b6654825e6124f743b2528be95d7",
|
||||||
})
|
})
|
||||||
a.api = apiClient
|
a.api = apiClient
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,7 +22,7 @@ func TestApiClient(t *testing.T) {
|
|||||||
func (a *apiClientSuite) SetupSuite() {
|
func (a *apiClientSuite) SetupSuite() {
|
||||||
log := logx.WithContext(context.Background())
|
log := logx.WithContext(context.Background())
|
||||||
apiClient := NewApiClient(log, AuthConfig{
|
apiClient := NewApiClient(log, AuthConfig{
|
||||||
Token: "",
|
Token: "dfae91a85341865b",
|
||||||
})
|
})
|
||||||
a.api = apiClient
|
a.api = apiClient
|
||||||
}
|
}
|
||||||
|
|||||||
@ -59,7 +59,7 @@ func (a *fliggyApiImpl) GenerateWechatUrl(ctx context.Context, req GenerateWecha
|
|||||||
// 分两种类型的URL
|
// 分两种类型的URL
|
||||||
// 1. 小程序路径为 pages/home/index 只处理fpsid的值即可
|
// 1. 小程序路径为 pages/home/index 只处理fpsid的值即可
|
||||||
// 2. 小程序路径为 pages/main/webview 需要将小程序后面的参数url urldecode后 将fpsid填充 再次urlencode后拼接回 小程序路径后面?url=
|
// 2. 小程序路径为 pages/main/webview 需要将小程序后面的参数url urldecode后 将fpsid填充 再次urlencode后拼接回 小程序路径后面?url=
|
||||||
urls := strings.Split(req.ActivityUrl, "?")
|
urls := strings.Split("?", req.ActivityUrl)
|
||||||
if len(urls) < 2 {
|
if len(urls) < 2 {
|
||||||
return "", errors.New("活动链接错误")
|
return "", errors.New("活动链接错误")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,6 @@ package fliggy
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
"repository.lenntc.com/lenntc/third-platform-sdk/sdk/fliggysdk/util"
|
"repository.lenntc.com/lenntc/third-platform-sdk/sdk/fliggysdk/util"
|
||||||
@ -26,28 +25,27 @@ func (a *apiClientSuite) SetupSuite() {
|
|||||||
log := logx.WithContext(context.Background())
|
log := logx.WithContext(context.Background())
|
||||||
apiClient := NewApiClient(log, AuthConfig{
|
apiClient := NewApiClient(log, AuthConfig{
|
||||||
AppKey: "34755002",
|
AppKey: "34755002",
|
||||||
AppSecret: "",
|
AppSecret: "0d4da23206d78ec991c3a96e789dec40",
|
||||||
})
|
})
|
||||||
a.api = apiClient
|
a.api = apiClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *apiClientSuite) Test_FliggyPromoteOrdersList() {
|
func (a *apiClientSuite) Test_FliggyPromoteOrdersList() {
|
||||||
page := int64(0)
|
page := int64(1)
|
||||||
start, _ := time.ParseInLocation(time.DateTime, "2024-11-05 16:10:00", time.Local)
|
start, _ := time.ParseInLocation(time.DateTime, "2024-08-04 00:00:00", time.Local)
|
||||||
end, _ := time.ParseInLocation(time.DateTime, "2024-11-05 16:20:00", time.Local)
|
end, _ := time.ParseInLocation(time.DateTime, "2024-08-04 23:59:59", time.Local)
|
||||||
sTime := util.LocalTime(start)
|
sTime := util.LocalTime(start)
|
||||||
eTime := util.LocalTime(end)
|
eTime := util.LocalTime(end)
|
||||||
|
|
||||||
req := &request.AlibabaFliggyPromoteOrdersListRequest{
|
req := &request.AlibabaFliggyPromoteOrdersListRequest{
|
||||||
PageNo: &page,
|
PageNo: &page,
|
||||||
BeforeModifyTime: &eTime,
|
BeforeModifyTime: &sTime,
|
||||||
AfterModifyTime: &sTime,
|
AfterModifyTime: &eTime,
|
||||||
}
|
}
|
||||||
resp, err := a.api.FliggyPromoteOrdersList(req)
|
resp, err := a.api.FliggyPromoteOrdersList(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.T().Errorf("=====[Test_FliggyPromoteOrdersList] err: %v", err)
|
a.T().Errorf("=====[Test_FliggyPromoteOrdersList] err: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ret, _ := json.Marshal(resp)
|
a.T().Logf("=====[Test_FliggyPromoteOrdersList] resp: %+v", resp)
|
||||||
a.T().Logf("=====[Test_FliggyPromoteOrdersList] resp: %+v", string(ret))
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,8 +3,6 @@ package jutuike
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/spf13/cast"
|
|
||||||
"reflect"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
@ -50,55 +48,12 @@ func (a *jutuikeApiImpl) GenerateLink(ctx context.Context, req GenerateLinkReque
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if response.Code != 1 {
|
if response.Code != 1 {
|
||||||
a.log.WithFields(logx.LogField{Key: "data", Value: map[string]any{"req": req, "resp": response}}).Errorf("[jutuikeApiImpl][GenerateLink] response result error: %s", response.Msg)
|
a.log.WithFields(logx.LogField{Key: "data", Value: map[string]any{"req": req, "resp": response}}).
|
||||||
|
Errorf("[jutuikeApiImpl][GenerateLink] response result error: %s", response.Msg)
|
||||||
return nil, errors.New(response.Msg)
|
return nil, errors.New(response.Msg)
|
||||||
}
|
}
|
||||||
result := new(GenerateLinkData)
|
result := response.Data.(GenerateLinkData)
|
||||||
data := cast.ToStringMap(response.Data)
|
return &result, nil
|
||||||
if _, ok := data["act_name"]; ok {
|
|
||||||
result.ActName = data["act_name"].(string)
|
|
||||||
}
|
|
||||||
if _, ok := data["poster_qrcode_url"]; ok {
|
|
||||||
result.PosterQrcodeUrl = data["poster_qrcode_url"].(string)
|
|
||||||
}
|
|
||||||
if _, ok := data["h5"]; ok {
|
|
||||||
result.H5 = data["h5"].(string)
|
|
||||||
}
|
|
||||||
if _, ok := data["long_h5"]; ok {
|
|
||||||
result.LongH5 = data["long_h5"].(string)
|
|
||||||
}
|
|
||||||
if _, ok := data["h5_evoke"]; ok {
|
|
||||||
result.H5Evoke = data["h5_evoke"].(string)
|
|
||||||
}
|
|
||||||
if _, ok := data["deeplink"]; ok {
|
|
||||||
result.DeepLink = data["deeplink"].(string)
|
|
||||||
}
|
|
||||||
if _, ok := data["we_app_info"]; ok {
|
|
||||||
weApp := cast.ToStringMap(data["we_app_info"])
|
|
||||||
weAppInfoTemp := new(WeAppInfo)
|
|
||||||
if _, tok := weApp["app_id"]; tok {
|
|
||||||
weAppInfoTemp.AppId = weApp["app_id"].(string)
|
|
||||||
}
|
|
||||||
if _, tok := weApp["page_path"]; tok {
|
|
||||||
weAppInfoTemp.PagePath = weApp["page_path"].(string)
|
|
||||||
}
|
|
||||||
if _, tok := weApp["miniCode"]; tok {
|
|
||||||
weAppInfoTemp.MiniCode = weApp["miniCode"].(string)
|
|
||||||
}
|
|
||||||
result.WeAppInfo = weAppInfoTemp
|
|
||||||
}
|
|
||||||
if _, ok := data["alipay_app_info"]; ok {
|
|
||||||
alipayApp := cast.ToStringMap(data["alipay_app_info"])
|
|
||||||
alipayAppInfoTemp := new(AlipayAppInfo)
|
|
||||||
if _, tok := alipayApp["app_id"]; tok {
|
|
||||||
alipayAppInfoTemp.AppId = alipayApp["app_id"].(string)
|
|
||||||
}
|
|
||||||
if _, tok := alipayApp["page_path"]; tok {
|
|
||||||
alipayAppInfoTemp.PagePath = alipayApp["page_path"].(string)
|
|
||||||
}
|
|
||||||
result.AlipayAppInfo = alipayAppInfoTemp
|
|
||||||
}
|
|
||||||
return result, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryOrderList 查询订单列表
|
// QueryOrderList 查询订单列表
|
||||||
@ -121,20 +76,12 @@ func (a *jutuikeApiImpl) QueryOrderList(ctx context.Context, req QueryOrderListR
|
|||||||
if err := a.client.HttpPost(GetOrderListUrl, request, &client.HttpResponse{Result: response}); err != nil {
|
if err := a.client.HttpPost(GetOrderListUrl, request, &client.HttpResponse{Result: response}); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
responseData := new(QueryOrderListData)
|
|
||||||
if response.Code != 1 {
|
if response.Code != 1 {
|
||||||
dataType := reflect.TypeOf(response.Data).String()
|
a.log.WithFields(logx.LogField{Key: "data", Value: map[string]any{"req": req, "resp": response}}).
|
||||||
if dataType == "string" {
|
Errorf("[jutuikeApiImpl][QueryOrderList] response result error: %s", response.Msg)
|
||||||
a.log.WithFields(logx.LogField{Key: "data", Value: map[string]any{"req": req, "resp": response}}).Errorf("[jutuikeApiImpl][QueryOrderList] response result error: %s", response.Msg)
|
|
||||||
return nil, errors.New(response.Msg)
|
return nil, errors.New(response.Msg)
|
||||||
} else {
|
|
||||||
responseData.PerPage = req.Page
|
|
||||||
responseData.CurrentPage = req.Page
|
|
||||||
responseData.LastPage = req.Page
|
|
||||||
responseData.Data = make([]*OrderItem, 0)
|
|
||||||
return responseData, nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
var responseData *QueryOrderListData
|
||||||
if err := xcopy.Copy(&responseData, response.Data); err != nil {
|
if err := xcopy.Copy(&responseData, response.Data); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,9 +3,11 @@ package jutuike
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// api-单元测试
|
// api-单元测试
|
||||||
@ -21,14 +23,14 @@ func TestApiClient(t *testing.T) {
|
|||||||
func (a *apiClientSuite) SetupSuite() {
|
func (a *apiClientSuite) SetupSuite() {
|
||||||
log := logx.WithContext(context.Background())
|
log := logx.WithContext(context.Background())
|
||||||
apiClient := NewApiClient(log, AuthConfig{
|
apiClient := NewApiClient(log, AuthConfig{
|
||||||
ApiKey: "", //
|
ApiKey: "IyftVpzDVqDIRDqPZByW5xVpj9MgZSB7",
|
||||||
})
|
})
|
||||||
a.api = apiClient
|
a.api = apiClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *apiClientSuite) Test_GenerateLink() {
|
func (a *apiClientSuite) Test_GenerateLink() {
|
||||||
req := GenerateLinkRequest{
|
req := GenerateLinkRequest{
|
||||||
ActId: 65,
|
ActId: 3,
|
||||||
Sid: "f3a8c1",
|
Sid: "f3a8c1",
|
||||||
}
|
}
|
||||||
result, err := a.api.GenerateLink(context.Background(), req)
|
result, err := a.api.GenerateLink(context.Background(), req)
|
||||||
@ -46,8 +48,8 @@ func (a *apiClientSuite) Test_GenerateLink() {
|
|||||||
|
|
||||||
func (a *apiClientSuite) Test_QueryOrderList() {
|
func (a *apiClientSuite) Test_QueryOrderList() {
|
||||||
req := QueryOrderListRequest{
|
req := QueryOrderListRequest{
|
||||||
StartTime: "2024-11-05 14:16:07",
|
StartTime: time.Unix(1718726400, 0).Format(time.DateTime),
|
||||||
EndTime: "2024-11-05 14:26:07",
|
EndTime: time.Unix(1718812799, 0).Format(time.DateTime),
|
||||||
PageSize: 1,
|
PageSize: 1,
|
||||||
}
|
}
|
||||||
result, err := a.api.QueryOrderList(context.Background(), req)
|
result, err := a.api.QueryOrderList(context.Background(), req)
|
||||||
|
|||||||
@ -14,19 +14,10 @@ type GenerateLinkResponse struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type GenerateLinkData struct {
|
type GenerateLinkData struct {
|
||||||
ActName string `json:"act_name"` // 活动名称
|
|
||||||
PosterQrcodeUrl string `json:"poster_qrcode_url"` //活动海报
|
|
||||||
H5 string `json:"h5"` // 推广短链接(部分活动没有,请注意判断)
|
H5 string `json:"h5"` // 推广短链接(部分活动没有,请注意判断)
|
||||||
|
WeAppInfo WeAppInfo `json:"we_app_info"` // 小程序信息(部分活动没有,请注意判断)
|
||||||
|
ActName string `json:"act_name"` // 活动名称
|
||||||
LongH5 string `json:"long_h5"` // 推广长链接(部分活动没有,请注意判断)
|
LongH5 string `json:"long_h5"` // 推广长链接(部分活动没有,请注意判断)
|
||||||
H5Evoke string `json:"h5_evoke"`
|
|
||||||
DeepLink string `json:"deeplink"`
|
|
||||||
WeAppInfo *WeAppInfo `json:"we_app_info"` // 微信小程序信息(部分活动没有,请注意判断)
|
|
||||||
AlipayAppInfo *AlipayAppInfo `json:"alipay_app_info"` //支付宝小程序信息(部分活动没有,请注意判断)
|
|
||||||
}
|
|
||||||
|
|
||||||
type AlipayAppInfo struct {
|
|
||||||
AppId string `json:"app_id"` // 小程序ID
|
|
||||||
PagePath string `json:"page_path"` // 小程序路径
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type WeAppInfo struct {
|
type WeAppInfo struct {
|
||||||
|
|||||||
@ -36,7 +36,7 @@ func newMeituanMediaApiImpl(log logx.Logger, client *Client, sign *Sign) Meituan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sign 签名
|
// Sign todo:: 签名
|
||||||
func (a *meituanMediaApiImpl) Sign(methodType string, uri string, data map[string]interface{}) string {
|
func (a *meituanMediaApiImpl) Sign(methodType string, uri string, data map[string]interface{}) string {
|
||||||
headers := a.sign.BuildHeader(methodType, uri, data)
|
headers := a.sign.BuildHeader(methodType, uri, data)
|
||||||
if sign, ok := headers[SCaSignature]; ok {
|
if sign, ok := headers[SCaSignature]; ok {
|
||||||
|
|||||||
@ -22,8 +22,8 @@ func TestApiClient(t *testing.T) {
|
|||||||
func (a *apiClientSuite) SetupSuite() {
|
func (a *apiClientSuite) SetupSuite() {
|
||||||
log := logx.WithContext(context.Background())
|
log := logx.WithContext(context.Background())
|
||||||
apiClient := NewApiClient(log, AuthConfig{
|
apiClient := NewApiClient(log, AuthConfig{
|
||||||
AppKey: "",
|
AppKey: "edf37a6019e045aeaec646220e4bd369",
|
||||||
AppSecret: "",
|
AppSecret: "975a5782165041be891c098cd3afe4ce",
|
||||||
})
|
})
|
||||||
a.api = apiClient
|
a.api = apiClient
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import (
|
|||||||
"repository.lenntc.com/lenntc/third-platform-sdk/util"
|
"repository.lenntc.com/lenntc/third-platform-sdk/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MeituanUnionApi 美团千载 平台的api
|
// MeituanUnionApi 美团联盟平台的api
|
||||||
type MeituanUnionApi interface {
|
type MeituanUnionApi interface {
|
||||||
// Sign 签名
|
// Sign 签名
|
||||||
Sign(params map[string]interface{}) string
|
Sign(params map[string]interface{}) string
|
||||||
|
|||||||
@ -21,8 +21,9 @@ func TestApiClient(t *testing.T) {
|
|||||||
func (a *apiClientSuite) SetupSuite() {
|
func (a *apiClientSuite) SetupSuite() {
|
||||||
log := logx.WithContext(context.Background())
|
log := logx.WithContext(context.Background())
|
||||||
apiClient := NewApiClient(log, AuthConfig{
|
apiClient := NewApiClient(log, AuthConfig{
|
||||||
SignKey: "",
|
//AppKey: "8b0a6d711cd573b5b048c90820dbb3fe756",
|
||||||
NotifyKey: "",
|
SignKey: "3e4a697ecd9eafa27c2f3f4ccf22072d",
|
||||||
|
NotifyKey: "gb8cwkj53x",
|
||||||
})
|
})
|
||||||
a.api = apiClient
|
a.api = apiClient
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,107 +0,0 @@
|
|||||||
package meituan
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
|
|
||||||
"repository.lenntc.com/lenntc/third-platform-sdk/client"
|
|
||||||
"repository.lenntc.com/lenntc/third-platform-sdk/util"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MeituanApi 美团联盟 平台的api
|
|
||||||
type MeituanApi interface {
|
|
||||||
// Sign 签名
|
|
||||||
Sign(methodType string, url string, data map[string]interface{}) string
|
|
||||||
// GenerateLink 获取推广链接
|
|
||||||
GenerateLink(ctx context.Context, req GenerateLinkRequest) (*GenerateLinkResponse, error)
|
|
||||||
// QueryOrderList 查询订单
|
|
||||||
QueryOrderList(ctx context.Context, req QueryOrderListRequest) (*QueryOrderData, error)
|
|
||||||
// QueryCouponList 查询商品
|
|
||||||
QueryCouponList(ctx context.Context, req QueryCouponListRequest) (*QueryCouponListResponse, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type meituanApiImpl struct {
|
|
||||||
log logx.Logger
|
|
||||||
client *Client
|
|
||||||
sign *Sign
|
|
||||||
}
|
|
||||||
|
|
||||||
func newMeituanApiImpl(log logx.Logger, client *Client, sign *Sign) MeituanApi {
|
|
||||||
return &meituanApiImpl{
|
|
||||||
log: log,
|
|
||||||
client: client,
|
|
||||||
sign: sign,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sign 签名
|
|
||||||
func (a *meituanApiImpl) Sign(methodType string, uri string, data map[string]interface{}) string {
|
|
||||||
headers := a.sign.BuildHeader(methodType, uri, data)
|
|
||||||
if sign, ok := headers[SCaSignature]; ok {
|
|
||||||
return sign
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetLink 获取推广链接
|
|
||||||
func (a *meituanApiImpl) GenerateLink(ctx context.Context, req GenerateLinkRequest) (*GenerateLinkResponse, error) {
|
|
||||||
args := util.StructToMap(req)
|
|
||||||
headers := a.sign.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.Code != 0 {
|
|
||||||
a.log.WithFields(logx.LogField{Key: "data", Value: map[string]any{"req": req, "args": args, "resp": response}}).
|
|
||||||
Errorf("[meituanApiImpl][GenerateLink] response result error: %s", response.Message)
|
|
||||||
return nil, errors.New(response.Message)
|
|
||||||
}
|
|
||||||
return response, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// QueryOrderList 查询订单
|
|
||||||
func (a *meituanApiImpl) QueryOrderList(ctx context.Context, req QueryOrderListRequest) (*QueryOrderData, error) {
|
|
||||||
args := util.StructToMap(req)
|
|
||||||
headers := a.sign.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.Code != 0 {
|
|
||||||
a.log.WithFields(logx.LogField{Key: "data", Value: map[string]any{"req": req, "resp": response}}).
|
|
||||||
Errorf("[meituanApiImpl][QueryOrderList] response result error: %s", response.Message)
|
|
||||||
return nil, errors.New(response.Message)
|
|
||||||
}
|
|
||||||
return response.Data, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// QueryCouponList 查询商品
|
|
||||||
func (a *meituanApiImpl) QueryCouponList(ctx context.Context, req QueryCouponListRequest) (*QueryCouponListResponse, error) {
|
|
||||||
args := util.StructToMap(req)
|
|
||||||
headers := a.sign.BuildHeader(http.MethodPost, GetProductListUri, args)
|
|
||||||
for k, v := range a.client.headers {
|
|
||||||
headers[k] = v
|
|
||||||
}
|
|
||||||
request := &client.HttpRequest{Headers: headers, BodyArgs: args}
|
|
||||||
response := new(QueryCouponListResponse)
|
|
||||||
if err := a.client.HttpPost(GetProductListUrl, request, &client.HttpResponse{Result: response}); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if response.Code != 0 {
|
|
||||||
a.log.WithFields(logx.LogField{Key: "data", Value: map[string]any{"req": req, "resp": response}}).
|
|
||||||
Errorf("[meituanApiImpl][QueryCouponList] response result error: %s", response.Message)
|
|
||||||
return nil, errors.New(response.Message)
|
|
||||||
}
|
|
||||||
return response, nil
|
|
||||||
}
|
|
||||||
@ -1,95 +0,0 @@
|
|||||||
package meituan
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/suite"
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
// api-单元测试
|
|
||||||
type apiClientSuite struct {
|
|
||||||
suite.Suite
|
|
||||||
api MeituanApi
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestApiClient(t *testing.T) {
|
|
||||||
suite.Run(t, new(apiClientSuite))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *apiClientSuite) SetupSuite() {
|
|
||||||
log := logx.WithContext(context.Background())
|
|
||||||
apiClient := NewApiClient(log, AuthConfig{
|
|
||||||
AppKey: "",
|
|
||||||
AppSecret: "",
|
|
||||||
})
|
|
||||||
a.api = apiClient
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *apiClientSuite) Test_Sign() {
|
|
||||||
data := map[string]interface{}{
|
|
||||||
"name": "zhangsan",
|
|
||||||
"phone": "13800000001",
|
|
||||||
}
|
|
||||||
sign := a.api.Sign("POST", "/t3/union/test", data)
|
|
||||||
a.T().Logf("=====[TestSign] sign: %s", sign)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *apiClientSuite) Test_GenerateLink() {
|
|
||||||
req := GenerateLinkRequest{
|
|
||||||
LinkType: 1,
|
|
||||||
ActId: "7",
|
|
||||||
Sid: "f3a8c1",
|
|
||||||
}
|
|
||||||
result, err := a.api.GenerateLink(context.Background(), req)
|
|
||||||
if !a.NoError(err) {
|
|
||||||
a.T().Errorf("========[Test_GenerateLink] response error:%s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resultByte, err := json.Marshal(result)
|
|
||||||
if err != nil {
|
|
||||||
a.T().Errorf("========[Test_GenerateLink] json_marshal error:%s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
a.T().Logf("=====[Test_GenerateLink] result: %s", string(resultByte))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *apiClientSuite) Test_QueryOrderList() {
|
|
||||||
req := QueryOrderListRequest{
|
|
||||||
Page: 1,
|
|
||||||
Limit: 2,
|
|
||||||
}
|
|
||||||
result, err := a.api.QueryOrderList(context.Background(), req)
|
|
||||||
if !a.NoError(err) {
|
|
||||||
a.T().Errorf("========[Test_QueryOrderList] response error:%s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resultByte, err := json.Marshal(result)
|
|
||||||
if err != nil {
|
|
||||||
a.T().Errorf("========[Test_QueryOrderList] json_marshal error:%s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
a.T().Logf("=====[Test_QueryOrderList] result: %s", string(resultByte))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *apiClientSuite) Test_QueryCouponList() {
|
|
||||||
req := QueryCouponListRequest{
|
|
||||||
PageNo: 1,
|
|
||||||
PageSize: 2,
|
|
||||||
Platform: 1,
|
|
||||||
SearchText: "券",
|
|
||||||
}
|
|
||||||
result, err := a.api.QueryCouponList(context.Background(), req)
|
|
||||||
if !a.NoError(err) {
|
|
||||||
a.T().Errorf("========[Test_QueryCouponList] response error:%s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resultByte, err := json.Marshal(result)
|
|
||||||
if err != nil {
|
|
||||||
a.T().Errorf("========[Test_QueryCouponList] json_marshal error:%s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
a.T().Logf("=====[Test_QueryCouponList] result: %s", string(resultByte))
|
|
||||||
}
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
package meituan
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
|
|
||||||
"repository.lenntc.com/lenntc/third-platform-sdk/client"
|
|
||||||
)
|
|
||||||
|
|
||||||
// AuthConfig api鉴权参数
|
|
||||||
type AuthConfig struct {
|
|
||||||
AppKey string // 应用key
|
|
||||||
AppSecret string // 应用秘钥
|
|
||||||
}
|
|
||||||
|
|
||||||
// 连接第三方平台的client
|
|
||||||
type Client struct {
|
|
||||||
log logx.Logger
|
|
||||||
authConfig AuthConfig
|
|
||||||
client.HttpClient
|
|
||||||
headers map[string]string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewApiClient(log logx.Logger, conf AuthConfig) MeituanApi {
|
|
||||||
clt := newClient(log, conf)
|
|
||||||
sign := newSign(conf.AppKey, conf.AppSecret)
|
|
||||||
return newMeituanApiImpl(log, clt, sign)
|
|
||||||
}
|
|
||||||
|
|
||||||
func newClient(log logx.Logger, conf AuthConfig) *Client {
|
|
||||||
return &Client{
|
|
||||||
log: log,
|
|
||||||
authConfig: conf,
|
|
||||||
HttpClient: client.NewHttpClient(log),
|
|
||||||
headers: map[string]string{
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
package meituan
|
|
||||||
|
|
||||||
// 相关地址
|
|
||||||
const (
|
|
||||||
SiteDomain = "https://media.meituan.com" // Domain 后台域名
|
|
||||||
SiteUrl = "https://media.meituan.com/pc/index.html#/account/qualification/view" // SiteUrl 后台地址
|
|
||||||
DocUrl = "https://media.meituan.com/pc/index.html#/help" // DocUrl 文档地址
|
|
||||||
ApiDocUrl = "https://media.meituan.com/pc/index.html#/materials/api" // ApiDocUrl api文档地址
|
|
||||||
)
|
|
||||||
|
|
||||||
// 接口地址
|
|
||||||
const (
|
|
||||||
ApiDomain = "https://media.meituan.com" //
|
|
||||||
GetLinkUri = "/cps_open/common/api/v1/get_referral_link"
|
|
||||||
GetOrderListUri = "/cps_open/common/api/v1/query_order"
|
|
||||||
GetProductListUri = "/cps_open/common/api/v1/query_coupon"
|
|
||||||
GetLinkUrl = ApiDomain + GetLinkUri
|
|
||||||
GetOrderListUrl = ApiDomain + GetOrderListUri
|
|
||||||
GetProductListUrl = ApiDomain + GetProductListUri
|
|
||||||
)
|
|
||||||
|
|
||||||
// header头信息
|
|
||||||
const (
|
|
||||||
SCaApp = "S-Ca-App"
|
|
||||||
SCaTimestamp = "S-Ca-Timestamp"
|
|
||||||
ContentMd5 = "Content-MD5"
|
|
||||||
SCaSignature = "S-Ca-Signature"
|
|
||||||
SCaSignatureHeaders = "S-Ca-Signature-Headers"
|
|
||||||
)
|
|
||||||
@ -1,120 +0,0 @@
|
|||||||
package meituan
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/hmac"
|
|
||||||
"crypto/md5"
|
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/base64"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"repository.lenntc.com/lenntc/third-platform-sdk/util"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Sign struct {
|
|
||||||
AppKey string // 应用key
|
|
||||||
AppSecret string // 应用秘钥
|
|
||||||
}
|
|
||||||
|
|
||||||
func newSign(appKey, appSecret string) *Sign {
|
|
||||||
return &Sign{
|
|
||||||
AppKey: appKey,
|
|
||||||
AppSecret: appSecret,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Sign) BuildHeader(methodType string, uri string, data map[string]any) map[string]string {
|
|
||||||
headers := map[string]string{
|
|
||||||
SCaApp: s.AppKey, // 应用app_key
|
|
||||||
SCaTimestamp: fmt.Sprintf("%d", time.Now().UnixMilli()), // 请求发起时间戳(毫秒),有效时1分钟
|
|
||||||
SCaSignatureHeaders: "S-Ca-Timestamp,S-Ca-App", // 将需要签名的header
|
|
||||||
ContentMd5: s.contentMD5(methodType, data), // body数据Md5加密
|
|
||||||
//"Content-Type": "application/json",
|
|
||||||
}
|
|
||||||
headers[SCaSignature] = s.GetSign(methodType, uri, data, headers)
|
|
||||||
return headers
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Sign) GetSign(methodType string, uri string, data map[string]any, signHeaders map[string]string) string {
|
|
||||||
httpMethod := s.httpMethod(methodType)
|
|
||||||
contentMD5 := s.contentMD5(methodType, data)
|
|
||||||
headers := s.headers(signHeaders)
|
|
||||||
url := s.url(methodType, uri, data)
|
|
||||||
strSign := httpMethod + "\n" + contentMD5 + "\n" + headers + url
|
|
||||||
hm := hmac.New(sha256.New, []byte(s.AppSecret))
|
|
||||||
hm.Write([]byte(strSign))
|
|
||||||
signStr := base64.StdEncoding.EncodeToString(hm.Sum(nil))
|
|
||||||
return signStr
|
|
||||||
}
|
|
||||||
|
|
||||||
// 请求方式大写
|
|
||||||
func (s *Sign) httpMethod(methodType string) string {
|
|
||||||
return strings.ToUpper(methodType)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 请求参数执行base64+md5的值
|
|
||||||
func (s *Sign) contentMD5(methodType string, data map[string]any) string {
|
|
||||||
methodType = s.httpMethod(methodType)
|
|
||||||
if (methodType == http.MethodPost || methodType == http.MethodPut) && data != nil {
|
|
||||||
dataByte, _ := json.Marshal(data)
|
|
||||||
h := md5.New()
|
|
||||||
h.Write(dataByte)
|
|
||||||
return base64.StdEncoding.EncodeToString(h.Sum(nil))
|
|
||||||
} else {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 签名计算Header的Key拼接
|
|
||||||
func (s *Sign) headers(signHeaders map[string]string) string {
|
|
||||||
var str = ""
|
|
||||||
// key排序
|
|
||||||
sortData := sort.StringSlice{}
|
|
||||||
for k := range signHeaders {
|
|
||||||
if k != SCaSignature && k != SCaSignatureHeaders && k != ContentMd5 {
|
|
||||||
sortData = append(sortData, k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sortData.Sort()
|
|
||||||
|
|
||||||
for _, k := range sortData {
|
|
||||||
str += k + ":" + signHeaders[k] + "\n"
|
|
||||||
}
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
// url拼接
|
|
||||||
// post直接返回path,get有参数的情况下拼接url
|
|
||||||
func (s *Sign) url(methodType, uri string, data map[string]any) string {
|
|
||||||
var query = ""
|
|
||||||
methodType = s.httpMethod(methodType)
|
|
||||||
// key排序
|
|
||||||
sortData := sort.StringSlice{}
|
|
||||||
for k := range data {
|
|
||||||
sortData = append(sortData, k)
|
|
||||||
}
|
|
||||||
sortData.Sort()
|
|
||||||
if len(sortData) > 0 && methodType == http.MethodGet {
|
|
||||||
for num, key := range sortData {
|
|
||||||
value, err := util.ToString(data[key])
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
str1 := ""
|
|
||||||
if len(sortData)-1 != num {
|
|
||||||
str1 = "&"
|
|
||||||
}
|
|
||||||
if len(value) > 0 {
|
|
||||||
query += fmt.Sprintf("%s=%s", key, value)
|
|
||||||
} else {
|
|
||||||
query += key
|
|
||||||
}
|
|
||||||
query += str1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%s%s", uri, query)
|
|
||||||
}
|
|
||||||
@ -1,188 +0,0 @@
|
|||||||
package meituan
|
|
||||||
|
|
||||||
// GenerateLinkRequest 生成推广链接请求
|
|
||||||
type GenerateLinkRequest struct {
|
|
||||||
LinkType int32 `json:"linkType"` // 必填 链接类型,枚举值:1 H5长链接;2 H5短链接;3 deeplink(唤起)链接;4 微信小程序唤起路径;5 团口令
|
|
||||||
Platform int32 `json:"platform,omitempty"` // 非必填 商品所属业务一级分类类型;请求的商品推广链接所属的业务类型信息,即只有输入skuViewId时才需要传本字段:1 到家及其他业务类型,2 到店业务类型;不填则默认1
|
|
||||||
BizLine int32 `json:"bizLine,omitempty"` // 非必填 商品所属业务二级分类类型;请求的商品推广链接所属的业务类型信息,即只有输入skuViewId时才需要传本字段;当字段platform为1,选择到家及其他业务类型时:5 医药,不填则默认null,表示外卖商品券;当字段platform为2,选择到店业务类型时:1 到餐,2 到综 3:酒店 4:门票 不填则默认1
|
|
||||||
ActId string `json:"actId,omitempty"` // 非必填 活动物料ID,我要推广-活动推广中第一列的id信息(和商品id、活动链接三选一填写,不能全填)
|
|
||||||
SkuViewId string `json:"skuViewId,omitempty"` // 非必填 商品id,对商品查询接口返回的skuViewid(和活动物料ID、活动链接三选一,不能全填)
|
|
||||||
Sid string `json:"sid,omitempty"` // 非必填 二级媒体身份标识,用于渠道效果追踪,限制64个字符,仅支持英文、数字和下划线
|
|
||||||
Text string `json:"text,omitempty"` // 非必填 只支持到家外卖商品券、买菜业务类型链接和活动物料链接。活动链接,即想要推广的目标链接,出参会返回成自己可推的链接,限定为当前可推广的活动链接或者商品券链接,请求内容尽量保持在200字以内,文本中仅存在一个http协议头的链接
|
|
||||||
}
|
|
||||||
|
|
||||||
// GenerateLinkResponse 生成推广链接响应
|
|
||||||
type GenerateLinkResponse struct {
|
|
||||||
Code int32 `json:"code"` // 响应码,0成功,其他失败
|
|
||||||
Message string `json:"message"` // 响应文案
|
|
||||||
Data string `json:"data"` // 返回对应的推广链接,这里的链接才能实现跟单计佣
|
|
||||||
SkuViewId string `json:"skuViewId"` // 若用text进行入参取链,且返回的推广链接为商品券链接,则返回对应商品的展示ID,可以根据该ID查商品券接口获取对应的展示信息和佣金信息
|
|
||||||
}
|
|
||||||
|
|
||||||
// QueryOrderListRequest 查询订单请求
|
|
||||||
type QueryOrderListRequest struct {
|
|
||||||
Platform int32 `json:"platform,omitempty"` // 非必填 商品所属业务一级分类类型:1 到家及其他业务类型,2 到店业务类型(包含到店美食、休闲生活、酒店、门票);不填则默认1
|
|
||||||
BusinessLine []int32 `json:"businessLine,omitempty"` // 非必填 业务线标识;1)当platform为1,选择到家及其他业务类型时,业务线枚举为1:外卖订单 WAIMAI 2:闪购红包 3:酒旅 4:美团电商订单(团好货) 5:医药 6:拼好饭 7:商品超值券包 COUPON 8:买菜 MAICAI 11:闪购商品;不传则默认传空表示非售卖券包订单类型的全部查询。若输入参数含7 商品超值券包,则只返回商品超值券包订单;2)当platform为2,选择到店业务类型 时,业务线枚举1:到餐 2:到综 3:酒店 4:门票,不填则默认传1
|
|
||||||
CategoryIds []int64 `json:"categoryIds,omitempty"` // 订单品类;1)当platform为1,当businessLine为11时,枚举值支持:大型连锁商超便利店(12),小型商超便利店(14),线上便利店(21),日百服饰(128),数码家电(106),美妆日化(107),母婴玩具(108),宠物(110),生鲜食材(24),鲜花(16),水果(15),酒饮(26),休闲食品(25),旗舰店(137),其他(-2);
|
|
||||||
// 2)当platform为1,当businessLine为9时,枚举值支持:进群(1),下单(2),首关注(3);
|
|
||||||
// 3)当platform为2,当businessLine为3时,枚举值支持:酒店(209),非标住宿(2327);
|
|
||||||
// 4)当platform为2,当businessLine为2时,枚举值支持:休闲娱乐(3),结婚(338),教育培训(289),养车/用车(390),运动健身(206),家居(600),购物(379),亲子(389),医疗健康(450),生活服务(4),K歌(1853),宠物(1861),其他(-1)
|
|
||||||
ActId int64 `json:"actId,omitempty"` // 非必填 活动物料id,我要推广-活动推广中第一列的id信息,不传则返回所有actId的数据,建议查询订单时传入actId
|
|
||||||
Sid string `json:"sid,omitempty"` // 非必填 二级推广位id,最长64位,不传则返回所有sid的数据
|
|
||||||
OrderId string `json:"orderId,omitempty"` // 非必填 订单id,入参后可与业务线标识businessLine配合使用,输入的orderId需要与businessLine能对应上。举例:如查询商品超值券包订单时orderId传券包订单号,businessLine传7;除此以外其他查询筛选条件不生效,不传业务线标识businessLine则默认仅查非券包订单
|
|
||||||
StartTime int32 `json:"startTime,omitempty"` // 非必填 查询时间类型对应的查询开始时间,10位时间戳表示,单位秒
|
|
||||||
EndTime int32 `json:"endTime,omitempty"` // 非必填 查询时间类型对应的查询结束时间,10位时间戳表示,单位秒
|
|
||||||
Page int32 `json:"page,omitempty"` // 非必填 页码,默认1,从1开始,若searchType选择2,本字段必须传1,若不传参数默认1
|
|
||||||
Limit int32 `json:"limit,omitempty"` // 非必填 每页限制条数,默认100,最大支持100
|
|
||||||
QueryTimeType int32 `json:"queryTimeType,omitempty"` // 非必填 查询时间类型,枚举值, 1 按订单支付时间查询, 2 按照更新时间查询, 默认为1
|
|
||||||
TradeType int32 `json:"tradeType,omitempty"` // 非必填 交易类型,1表示CPS,2表示CPA
|
|
||||||
ScrollId string `json:"scrollId,omitempty"` // 非必填 分页id,当searchType选择2逐页查询时,本字段为必填。若不填写,默认查询首页。取值为上一页查询时出参的scrollId字段
|
|
||||||
SearchType int32 `json:"searchType,omitempty"` // 非必填 订单分页查询方案选择,不填则默认为1。1 分页查询(最多能查询到1万条订单),当选择本查询方案,page参数不能为空。此查询方式后续不再维护,建议使用2逐页查询。2 逐页查询(不限制查询订单数,只能逐页查询,不能指定页数),当选择本查询方案,需配合scrollId参数使用
|
|
||||||
CityNames []string `json:"cityNames,omitempty"` // 非必填 可输入城市名称圈定特定城市的订单,单次最多查询10个城市(英文逗号分隔)。不传则默认全部城市订单。 注:如需确认城市具体名称,可参考后台订单明细页的城市筛选项,或参考具体活动的城市命名。目前只支持到家业务类型-商品超值券包业务线。
|
|
||||||
}
|
|
||||||
|
|
||||||
// QueryOrderListResponse 查询订单响应
|
|
||||||
type QueryOrderListResponse struct {
|
|
||||||
Code int `json:"code"` // 响应码,0成功,其他值为失败
|
|
||||||
Message string `json:"message"` // 响应文案
|
|
||||||
Data *QueryOrderData `json:"data"` // 响应结果信息
|
|
||||||
}
|
|
||||||
|
|
||||||
type QueryOrderData struct {
|
|
||||||
ActId int64 `json:"actId"` // 活动物料id,我要推广-活动推广中第一列的id信息
|
|
||||||
SkuCount int32 `json:"skuCount"` // 查询返回本页的数量合计(无实际使用场景,若查询订单购买商品数可以看返回的dataList中skuCount)
|
|
||||||
ScrollId string `json:"scrollId"` // 分页id,当searchType选择2逐页查询时,出参会返回本字段。用于下一页查询的scrollId字段入参使用
|
|
||||||
DataList []*OrderItem `json:"dataList"` // 数据列表
|
|
||||||
}
|
|
||||||
|
|
||||||
type OrderItem struct {
|
|
||||||
BusinessLine int32 `json:"businessLine"` // 业务线,同入参枚举说明
|
|
||||||
OrderId string `json:"orderId"` // 订单ID
|
|
||||||
PayTime int64 `json:"payTime"` // 订单支付时间
|
|
||||||
PayPrice string `json:"payPrice"` // 订单支付价格。针对到餐、到综、酒店、闪购、医药业务类型,为父订单的支付价格,单位元
|
|
||||||
UpdateTime int64 `json:"updateTime"` // 订单最近一次的更新时间。到家外卖商品券、到家医药、到家闪购商品业务、到店到餐、到综、酒店类型,订单时间为用户买券包的更新时间,非每张券的更新时间。针对以上业务类型,建议查询单张券的更新时间
|
|
||||||
CommissionRate string `json:"commissionRate"` // 订单预估佣金比例,300表示3%
|
|
||||||
Profit string `json:"profit"` // 订单整体的预估佣金收入,单位元,1.60表示1.6元
|
|
||||||
CpaProfit string `json:"cpaProfit"` // cpa类型的预估佣金收入,单位元,6.50表示6.5元
|
|
||||||
Sid string `json:"sid"` // 二级媒体身份标识,用于渠道效果追踪
|
|
||||||
ProductId string `json:"productId"` // 产品ID,对应商品查询接口的skuViewId,目前只支持到家外卖商品券、到家医药、到家闪购商品业务、到店业务类型
|
|
||||||
ProductName string `json:"productName"` // 产品名称,外卖订单展示店铺名称,到店取单个商品券的名称、其他展示全部商品名称
|
|
||||||
OrderDetail []*OrderDetail `json:"orderDetail"` // 订单详情,只支持到家外卖商品券、到家医药、到家闪购商品业务、到店到餐、到综、酒店类型返回数据
|
|
||||||
RefundPrice string `json:"refundPrice"` // 只对非到店到餐、非到综、非酒店业务类型有效。订单维度退款价格,该笔订单用户发生退款行为时的退款计佣金额之和,超值券包订单本期不返回退款数据,单位元
|
|
||||||
RefundTime string `json:"refundTime"` // 只对非到店到餐、非到综、非酒店业务类型有效。订单维度最新一次发生退款的时间;超值券包订单本期不返回退款数据,单位元
|
|
||||||
RefundProfit string `json:"refundProfit"` // 只对非到店到餐、非到综、非酒店业务类型有效。订单维度退款预估佣金,该笔订单用户发生退款行为时的退款预估佣金金额之和;超值券包订单本期不返回退款数据,单位元
|
|
||||||
CpaRefundProfit string `json:"cpaRefundProfit"` // cpa退款预估佣金,单位元
|
|
||||||
Status string `json:"status"` // 表示订单维度状态,枚举有 2:付款(如果是CPA订单则表示奖励已创建) 3:完成 4:取消 5:风控 6:结算
|
|
||||||
TradeType int32 `json:"tradeType"` // 交易类型,1:cps,2:cpa
|
|
||||||
ActId int64 `json:"actId"` // 活动物料id,我要推广-活动推广中第一列的id信息
|
|
||||||
Appkey string `json:"appkey"` // 归因到的appKey,对应取链时入参的appkey
|
|
||||||
SkuCount int32 `json:"skuCount"` // 表示sku数量,团好货和券包类型的CPS订单返回有值,其余类型订单不返回该值
|
|
||||||
CityName string `json:"cityName"` // 订单所属的城市,目前支持二级城市粒度。目前只支持到家业务类型-商品超值券包业务线。
|
|
||||||
CategoryId int64 `json:"categoryId"` // 订单品类id。
|
|
||||||
CategoryName string `json:"categoryName"` // 订单品类名称。
|
|
||||||
}
|
|
||||||
|
|
||||||
// 订单详情
|
|
||||||
type OrderDetail struct {
|
|
||||||
CouponStatus string `json:"couponStatus"` // 本期只有到到家外卖商品券、到家医药、到家闪购商品业务、到店到餐、到综、酒店业务类型展示订单明细,表示商品券/子订单推广计佣状态,1、付款,2、完成(或券已核销),3、结算,4、失效(含取消或风控的情况)
|
|
||||||
ItemOrderId string `json:"itemOrderId"` // 针对到店到餐、到综、酒店商品券,返回商品券的子订单号。其他业务类型不返回
|
|
||||||
FinishTime string `json:"finishTime"` // 1、针对到家外卖商品券,返回商品券核销完成履约的实物菜品订单号对应的完成时间;2、针对到家医药&闪购商品,返回商品订单完成时间;3、针对到店到餐、到综、酒店子订单,返回子订单对应的券核销时间
|
|
||||||
BasicAmount string `json:"basicAmount"` // 商品的计佣金额,每个商品对应的支付分摊金额,单位元
|
|
||||||
CouponFee string `json:"couponFee"` // 商品的佣金,当推广状态为失效、取消、风控时,佣金值为0,单位元
|
|
||||||
OrderViewId string `json:"orderViewId"` // 只对到家外卖商品券有效。商品券的核销完成履约的实物菜品订单号
|
|
||||||
RefundAmount string `json:"refundAmount"` // 到店到餐、到综、酒店子订单、到家闪购商品、到家医药业务类型的退款金额,到家其他业务类型不返回数据,单位元
|
|
||||||
RefundFee string `json:"refundFee"` // 到店到餐、到综、酒店子订单、到家闪购商品、到家医药业务类型的退款佣金,到家其他业务类型不返回数据,单位元
|
|
||||||
RefundTime string `json:"refundTime"` // 到店到餐、到综、酒店子订单、到家闪购商品、到家医药业务类型的退款时间,到家其他业务类型不返回数据
|
|
||||||
SettleTime string `json:"settleTime"` // 到家商品券/到家闪购商品/到店到餐/到综/酒店子订单的结算时间,完成并且进入结算账期时则变为结算状态。若存在多次结算记录则取最新结算时间
|
|
||||||
UpdateTime string `json:"updateTime"` // 到家商品券/到家闪购商品/到家医药/到店到餐、到综、酒店子订单的更新时间
|
|
||||||
}
|
|
||||||
|
|
||||||
// QueryCouponListRequest 查询商品请求
|
|
||||||
type QueryCouponListRequest struct {
|
|
||||||
Platform int32 `json:"platform,omitempty"` // 非必填 商品所属业务一级分类类型:1 到家及其他业务类型,2 到店业务类型(包含到店美食、休闲生活、酒店、门票);不填则默认1
|
|
||||||
BizLine int32 `json:"bizLine,omitempty"` // 非必填 商品所属业务二级分类类型;当字段platform为1,选择到家及其他业务类型时:5 医药 ,不填则默认为null,返回外卖商品券;当字段platform为2,选择到店业务类型时:1 到餐,2 到综 3:酒店 4:门票度假 不填则默认1
|
|
||||||
Longitude int64 `json:"longitude,omitempty"` // 非必填 定位经纬度的经度,请传递经度*100万倍的整形数字,如经度116.404*100万倍为116404000; 针对到店、到家医药商品业务类型,若未输入经纬度,则默认北京;针对到家外卖商品券业务类型,若未输入经纬度,则默认全国
|
|
||||||
Latitude int64 `json:"latitude,omitempty"` // 非必填 定位经纬度的纬度,请传递纬度*100万倍的整形数字,如纬度39.928*100万倍为39928000; 针对到店、到家医药商品业务类型,若未输入经纬度,则默认北京;针对到家外卖商品券业务类型,若未输入经纬度,则默认全国
|
|
||||||
PriceCap int32 `json:"priceCap,omitempty"` // 非必填 筛选商品售卖价格上限【单位元】
|
|
||||||
PriceFloor int32 `json:"priceFloor,omitempty"` // 非必填 筛选商品价格下限【单位元】
|
|
||||||
CommissionCap int32 `json:"commissionCap,omitempty"` // 非必填 筛选商品佣金值上限【单位元】,若商品按照佣金值进行范围筛选,则排序只能按照佣金降序,本字段只支持到店业务类型、到家医药业务类型
|
|
||||||
CommissionFloor int32 `json:"commissionFloor,omitempty"` // 非必填 筛选商品佣金值下限【单位元】,若商品按照佣金值进行范围筛选,则排序只能按照佣金降序,本字段只支持到店业务类型、到家医药业务类型
|
|
||||||
VpSkuViewIds []string `json:"vpSkuViewIds,omitempty"` // 非必填 商品ID集合,非必填,若填写该字段则不支持其他筛选条件,集合里ID用英文“,”隔开。一次最多支持查询20个售卖券ID
|
|
||||||
ListTopiId int32 `json:"listTopiId,omitempty"` // 非必填 选品池榜单主题ID,到家及其他业务类型支持查询:1 精选,2 今日必推,3 同城热销,4 跟推爆款的商品售卖券(其中到家医药业务类型,本项为必填,且只支持传枚举3);到店业务类型支持查询:2 今日必推,3 同城热销(全部商品)5 实时热销(其中到店酒店、门票业务类型,本项为必填,且只支持传枚举3)
|
|
||||||
SearchText string `json:"searchText,omitempty"` // 非必填 搜索关键字,限制1-100个字符,不支持入参指定Platform、bizLine搜索,搜索范围为全品类。如需使用该字段查询商品信息,则vpSkuViewIds、listTopiId字段必须为空!!!如不为空,则按下述字段优先级执行查询:vpSkuViewIds>listTopiId>searchText。
|
|
||||||
SearchId string `json:"searchId,omitempty"` // 非必填 仅搜索场景分页使用,首次调用不用填。查询相同搜索关键词、相同排序规则的下一页数据,需携带填写上次查询时出参中的'searchId'。如变更搜索关键字或排序规则,则也无需填写。
|
|
||||||
PageSize int32 `json:"pageSize,omitempty"` // 非必填 分页大小,不填返回默认分页20
|
|
||||||
PageNo int32 `json:"pageNo,omitempty"` // 非必填 页数,不填返回默认页数1
|
|
||||||
SortField int32 `json:"sortField,omitempty"` // 非必填 1)未入参榜单listTopiId时:支持1 售价排序、2 销量排序;2)入参榜单listTopiId时:当platform为1,选择到家业务类型:外卖商品券类型,支持1 售价排序、 2 销量降序、 3佣金降序,不填则默认为1;到家医药类型,支持2 销量降序、 3 佣金降序,不填则默认为2; 当platform为2,选择到店业务类型:支持2 销量降序、 3佣金降序,不填则默认为2。其中listTopiId为5时,仅支持默认排序,sortField不生效;3)通过搜索searchText召回时:支持1综合排序、2价格升序,不填默认为1
|
|
||||||
AscDescOrder int32 `json:"ascDescOrder,omitempty"` // 非必填 仅对到家业务类型生效,未入参榜单listTopiId时:1 升序,2 降序; 入参榜单listTopiId时:1 升序,2 降序,并且仅对sortField为1售价排序的时候生效,其他筛选值不生效; 其他说明:不填则默认为1升序
|
|
||||||
}
|
|
||||||
|
|
||||||
// QueryCouponListResponse 查询商品响应
|
|
||||||
type QueryCouponListResponse struct {
|
|
||||||
Code int `json:"code"` // 响应码,0成功,其他值为失败
|
|
||||||
Message string `json:"message"` // 响应文案
|
|
||||||
HasNext bool `json:"hasNext"` // 分页使用,看是否有下一页
|
|
||||||
SearchId string `json:"searchId"` // 搜索场景出参,用于相同条件下一页请求入参
|
|
||||||
Data []*QueryCouponData `json:"data"` // 响应结果信息
|
|
||||||
}
|
|
||||||
|
|
||||||
type QueryCouponData struct {
|
|
||||||
AvailablePoiInfo *AvailablePoiInfo `json:"availablePoiInfo"` // 可用门店信息
|
|
||||||
BrandInfo *BrandInfo `json:"brandInfo"` // 品牌信息
|
|
||||||
CommissionInfo *CommissionInfo `json:"commissionInfo"` // 佣金信息
|
|
||||||
CouponPackDetail *CouponPackDetail `json:"couponPackDetail"` // 商品详情
|
|
||||||
DeliverablePoiInfo *DeliverablePoiInfo `json:"deliverablePoiInfo"` // 只支持到家外卖商品券业务类型,可配送门店信息
|
|
||||||
PurchaseLimitInfo *PurchaseLimitInfo `json:"purchaseLimitInfo"` // 购买限制信息
|
|
||||||
CouponValidTimeInfo *CouponValidTimeInfo `json:"couponValidTimeInfo"` // 只支持到家外卖商品券业务类型,券包活动有效时间信息
|
|
||||||
}
|
|
||||||
|
|
||||||
type AvailablePoiInfo struct {
|
|
||||||
AvailablePoiNum int64 `json:"availablePoiNum"` // 可用门店数量。针对到店、到家医药业务类型商品,若传入经纬度信息,则为经纬度所在城市可用的门店数。若不传入经纬度信息,则输出北京可用的门店数
|
|
||||||
}
|
|
||||||
|
|
||||||
type BrandInfo struct {
|
|
||||||
BrandName string `json:"brandName"` // 品牌名称
|
|
||||||
BrandLogoUrl string `json:"brandLogoUrl"` // 品牌Logo的url
|
|
||||||
}
|
|
||||||
|
|
||||||
type CommissionInfo struct {
|
|
||||||
CommissionPercent string `json:"commissionPercent"` // 查询当时生效的佣金比例, 商品券拉取、通过商品券ID查询、通过榜单listTopiId查询,返回的数据需要除以100表示对应的佣金比例,如返回400表示佣金比例为4%
|
|
||||||
Commission string `json:"commission"` // 只支持到店、到家医药业务类型。查询当时生效的佣金值。单位元,保留小数点后两位
|
|
||||||
}
|
|
||||||
|
|
||||||
type CouponPackDetail struct {
|
|
||||||
Name string `json:"name"` // 商品名称
|
|
||||||
SkuViewId string `json:"skuViewId"` // 商品skuViewId,传入开放平台取链接口的skuViewId,取得对应推广链接才能正常归因订单
|
|
||||||
Specification string `json:"specification"` // 规格信息,只支持到家医药商品业务类型
|
|
||||||
CouponNum int32 `json:"couponNum"` // 只支持到家外卖商品券业务类型,券包中券的数量
|
|
||||||
ValidTime int32 `json:"validTime"` // 只支持到家外卖商品券业务类型,活动截止有效日期,仅作参考,具体结束时间详见couponValidTimeInfo中的信息
|
|
||||||
HeadUrl string `json:"headUrl"` // 商品头图的url
|
|
||||||
SaleVolume string `json:"saleVolume"` // 美团累计销量,例:100+,1000+,10000+
|
|
||||||
StartTime int64 `json:"startTime"` // 只支持到家外卖商品券业务类型,活动有效期开始时间
|
|
||||||
EndTime int64 `json:"endTime"` // 只支持到家外卖商品券业务类型,活动有效期结束时间
|
|
||||||
SaleStatus bool `json:"saleStatus"` // 售卖状态,可售为是,不可售为否。不可售商品不返回商品数据
|
|
||||||
OriginalPrice string `json:"originalPrice"` // 原始价格,如划线价(元)
|
|
||||||
SellPrice string `json:"sellPrice"` // 售卖价格(元)
|
|
||||||
Platform int32 `json:"platform"` // 平台,1-到家、2-到店
|
|
||||||
BizLine int32 `json:"bizLine"` // 二级分类,当platform为1时null代表外卖,当platform为2时1代表餐
|
|
||||||
}
|
|
||||||
|
|
||||||
type DeliverablePoiInfo struct {
|
|
||||||
PoiName string `json:"poiName"` // 门店名称,商品券可配送门店信息,无则不返回 注:入参经纬度可展示附近配送门店名称。按主题榜单查询时不展示该字段
|
|
||||||
PoiLogoUrl string `json:"poiLogoUrl"` // 门店Logo的url 注:入参经纬度可展示附近配送门店logo。按主题榜单查询时不展示该字段。
|
|
||||||
DeliveryDistance string `json:"deliveryDistance"` // 配送距离 注:入参经纬度可展示附近配送门店的配送距离。按主题榜单查询时不展示该字段。
|
|
||||||
DistributionCost string `json:"distributionCost"` // 配送费 注:入参经纬度可展示附近配送门店的配送费。按主题榜单查询时不展示该字段。
|
|
||||||
DeliveryDuration string `json:"deliveryDuration"` // 配送时长 注:入参经纬度可展示附近配送门店的配送时长。按主题榜单查询时不展示该字段。
|
|
||||||
LastDeliveryFee string `json:"lastDeliveryFee"` // 起送额 注:入参经纬度可展示附近配送门店的起送金额。按主题榜单查询时不展示该字段。
|
|
||||||
}
|
|
||||||
|
|
||||||
type PurchaseLimitInfo struct {
|
|
||||||
SingleDayPurchaseLimit int32 `json:"singleDayPurchaseLimit"` // 单日售卖上限
|
|
||||||
}
|
|
||||||
|
|
||||||
type CouponValidTimeInfo struct {
|
|
||||||
CouponValidTimeType int32 `json:"couponValidTimeType"` // 券包活动生效时间类型,1:按生效天数,2:按时间段
|
|
||||||
CouponValidDay int32 `json:"couponValidDay"` // 券生效天数;couponValidTimeType为1有效
|
|
||||||
CouponValidSTime int64 `json:"couponValidSTime"` // 券开始时间戳,单位秒;couponValidTimeType为2有效
|
|
||||||
CouponValidETime int64 `json:"couponValidETime"` // 券结束时间戳,单位秒;couponValidTimeType为2有效
|
|
||||||
}
|
|
||||||
@ -15,8 +15,6 @@ import (
|
|||||||
type ShouTuShowApi interface {
|
type ShouTuShowApi interface {
|
||||||
// GenerateLink 生成推广链接
|
// GenerateLink 生成推广链接
|
||||||
GenerateLink(ctx context.Context, req GenerateLinkRequest) (*GenerateLinkResponse, error)
|
GenerateLink(ctx context.Context, req GenerateLinkRequest) (*GenerateLinkResponse, error)
|
||||||
// GenerateWechatUrl 生成微信小程序链接
|
|
||||||
GenerateWechatUrl(ctx context.Context, req GenerateLinkRequest) (*GenerateLinkResponse, error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ShouTuShowApiImpl struct {
|
type ShouTuShowApiImpl struct {
|
||||||
@ -31,26 +29,15 @@ func newShouTuShowApiImpl(log logx.Logger, client *Client) ShouTuShowApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 守兔演出不支持H5取链,生成的H5url为小程序中间页URL
|
|
||||||
func (a *ShouTuShowApiImpl) GenerateLink(ctx context.Context, req GenerateLinkRequest) (*GenerateLinkResponse, error) {
|
func (a *ShouTuShowApiImpl) GenerateLink(ctx context.Context, req GenerateLinkRequest) (*GenerateLinkResponse, error) {
|
||||||
if req.ActivityUrl == "" || req.LinkCode == "" || req.ActId == "" {
|
|
||||||
return nil, errors.New("请求参数activityUrl或linkCode或actId不能为空")
|
|
||||||
}
|
|
||||||
activityUrl := fmt.Sprintf("%s?linkCode=%s&actId=%s", req.ActivityUrl, req.LinkCode, req.ActId)
|
|
||||||
return &GenerateLinkResponse{
|
|
||||||
H5: activityUrl,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 小程序链接
|
|
||||||
func (a *ShouTuShowApiImpl) GenerateWechatUrl(ctx context.Context, req GenerateLinkRequest) (*GenerateLinkResponse, error) {
|
|
||||||
if req.ActivityUrl == "" || req.Sid == "" {
|
if req.ActivityUrl == "" || req.Sid == "" {
|
||||||
return nil, errors.New("请求参数activityUrl或sid不能为空")
|
return nil, errors.New("请求参数activityUrl或sid不能为空")
|
||||||
}
|
}
|
||||||
|
//测试联调地址 https://pre-show.shouto.cn/?distributorId=8&subChannelId=
|
||||||
//直接替换
|
//直接替换
|
||||||
newUrl := strings.ReplaceAll(req.ActivityUrl, "subChannelId=", fmt.Sprintf("subChannelId=%s", req.Sid))
|
newUrl := strings.ReplaceAll(req.ActivityUrl, "subChannelId=", fmt.Sprintf("subChannelId=%s", req.Sid))
|
||||||
return &GenerateLinkResponse{
|
return &GenerateLinkResponse{
|
||||||
MiniProgramUrl: newUrl,
|
H5: newUrl,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,66 +0,0 @@
|
|||||||
package shoutu_show
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"github.com/stretchr/testify/suite"
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
// api-单元测试
|
|
||||||
type apiClientSuite struct {
|
|
||||||
suite.Suite
|
|
||||||
api ShouTuShowApi
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestApiClient(t *testing.T) {
|
|
||||||
suite.Run(t, new(apiClientSuite))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *apiClientSuite) SetupSuite() {
|
|
||||||
log := logx.WithContext(context.Background())
|
|
||||||
apiClient := NewApiClient(log, AuthConfig{
|
|
||||||
AppKey: "", //
|
|
||||||
AppSecret: "",
|
|
||||||
})
|
|
||||||
a.api = apiClient
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *apiClientSuite) Test_GenerateLink() {
|
|
||||||
req := GenerateLinkRequest{
|
|
||||||
ActivityUrl: "https://cms.zhongdiantui.com/#/pages/toMiniProgram/toMiniProgram",
|
|
||||||
Sid: "f3a8c1",
|
|
||||||
LinkCode: "aaakfhkahfkadk",
|
|
||||||
ActId: "1111",
|
|
||||||
}
|
|
||||||
result, err := a.api.GenerateLink(context.Background(), req)
|
|
||||||
if !a.NoError(err) {
|
|
||||||
a.T().Errorf("========[Test_GenerateLink] response error:%s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resultByte, err := json.Marshal(result)
|
|
||||||
if err != nil {
|
|
||||||
a.T().Errorf("========[Test_GenerateLink] json_marshal error:%s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
a.T().Logf("=====[Test_GenerateLink] result: %s", string(resultByte))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *apiClientSuite) Test_GenerateWechatUrl() {
|
|
||||||
req := GenerateLinkRequest{
|
|
||||||
ActivityUrl: "pages/index/index?distributorId=VCiCWwU2&subChannelId=",
|
|
||||||
Sid: "f3a8c1",
|
|
||||||
}
|
|
||||||
result, err := a.api.GenerateWechatUrl(context.Background(), req)
|
|
||||||
if !a.NoError(err) {
|
|
||||||
a.T().Errorf("========[Test_GenerateLink] response error:%s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resultByte, err := json.Marshal(result)
|
|
||||||
if err != nil {
|
|
||||||
a.T().Errorf("========[Test_GenerateLink] json_marshal error:%s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
a.T().Logf("=====[Test_GenerateLink] result: %s", string(resultByte))
|
|
||||||
}
|
|
||||||
@ -3,14 +3,11 @@ package shoutu_show
|
|||||||
type GenerateLinkRequest struct {
|
type GenerateLinkRequest struct {
|
||||||
ActivityUrl string `json:"activityUrl"` // 渠道方合作页地址
|
ActivityUrl string `json:"activityUrl"` // 渠道方合作页地址
|
||||||
Sid string `json:"sid"` // 必传 自定义参数
|
Sid string `json:"sid"` // 必传 自定义参数
|
||||||
LinkCode string `json:"linkCode"` // 链接code
|
|
||||||
ActId string `json:"actId"` // 活动id
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateLinkResponse 生成推广链接响应
|
// GenerateLinkResponse 生成推广链接响应
|
||||||
type GenerateLinkResponse struct {
|
type GenerateLinkResponse struct {
|
||||||
H5 string `json:"h5"` // H5链接
|
H5 string `json:"h5"` // H5链接
|
||||||
MiniProgramUrl string `json:"MiniProgramUrl"` //小程序链接
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type QueryOrderListRequest struct {
|
type QueryOrderListRequest struct {
|
||||||
|
|||||||
@ -22,8 +22,8 @@ func TestApiClient(t *testing.T) {
|
|||||||
func (a *apiClientSuite) SetupSuite() {
|
func (a *apiClientSuite) SetupSuite() {
|
||||||
log := logx.WithContext(context.Background())
|
log := logx.WithContext(context.Background())
|
||||||
apiClient := NewApiClient(log, AuthConfig{
|
apiClient := NewApiClient(log, AuthConfig{
|
||||||
AppKey: "",
|
AppKey: "QOHEgCUTeK",
|
||||||
AppSecret: "",
|
AppSecret: "tsTSxrCgibcFbxGOxRDEBGQUhRVJLsFs",
|
||||||
})
|
})
|
||||||
a.api = apiClient
|
a.api = apiClient
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,33 +0,0 @@
|
|||||||
package youpiaopiao
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
// YouPiaoPiaoApi 有票票
|
|
||||||
type YouPiaoPiaoApi interface {
|
|
||||||
// GenerateH5Url 生成H5链接
|
|
||||||
GenerateH5Url(ctx context.Context, req GenerateH5UrlRequest) (string, error)
|
|
||||||
}
|
|
||||||
type youpiaopiaoApiImpl struct {
|
|
||||||
log logx.Logger
|
|
||||||
client *Client
|
|
||||||
}
|
|
||||||
|
|
||||||
func newYoupiaopiaoApiImpl(log logx.Logger, client *Client) YouPiaoPiaoApi {
|
|
||||||
return &youpiaopiaoApiImpl{
|
|
||||||
log: log,
|
|
||||||
client: client,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GenerateH5Url 生成H5推广链接
|
|
||||||
func (a *youpiaopiaoApiImpl) GenerateH5Url(ctx context.Context, req GenerateH5UrlRequest) (string, error) {
|
|
||||||
if len(req.ActivityUrl) == 0 {
|
|
||||||
return "", errors.New("url参数不能为空")
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%s&entpara=%s", req.ActivityUrl, req.Sid), nil
|
|
||||||
}
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
package youpiaopiao
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"github.com/stretchr/testify/suite"
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
// api-单元测试
|
|
||||||
type apiClientSuite struct {
|
|
||||||
suite.Suite
|
|
||||||
api YouPiaoPiaoApi
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestApiClient(t *testing.T) {
|
|
||||||
suite.Run(t, new(apiClientSuite))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *apiClientSuite) SetupSuite() {
|
|
||||||
log := logx.WithContext(context.Background())
|
|
||||||
apiClient := NewApiClient(log, AuthConfig{
|
|
||||||
ApiKey: "", //
|
|
||||||
})
|
|
||||||
a.api = apiClient
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *apiClientSuite) Test_GenerateLink() {
|
|
||||||
req := GenerateH5UrlRequest{
|
|
||||||
ActivityUrl: "",
|
|
||||||
Sid: "f3a8c1",
|
|
||||||
}
|
|
||||||
result, err := a.api.GenerateH5Url(context.Background(), req)
|
|
||||||
if !a.NoError(err) {
|
|
||||||
a.T().Errorf("========[Test_GenerateLink] response error:%s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resultByte, err := json.Marshal(result)
|
|
||||||
if err != nil {
|
|
||||||
a.T().Errorf("========[Test_GenerateLink] json_marshal error:%s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
a.T().Logf("=====[Test_GenerateLink] result: %s", string(resultByte))
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
package youpiaopiao
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
"repository.lenntc.com/lenntc/third-platform-sdk/client"
|
|
||||||
)
|
|
||||||
|
|
||||||
// AuthConfig api鉴权参数
|
|
||||||
type AuthConfig struct {
|
|
||||||
ApiKey string // api key
|
|
||||||
AppSecret string // api secret
|
|
||||||
}
|
|
||||||
|
|
||||||
// 连接第三方平台的client
|
|
||||||
type Client struct {
|
|
||||||
log logx.Logger
|
|
||||||
authConfig AuthConfig
|
|
||||||
client.HttpClient
|
|
||||||
headers map[string]string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewApiClient(log logx.Logger, conf AuthConfig) YouPiaoPiaoApi {
|
|
||||||
clt := newClient(log, conf)
|
|
||||||
return newYoupiaopiaoApiImpl(log, clt)
|
|
||||||
}
|
|
||||||
|
|
||||||
func newClient(log logx.Logger, conf AuthConfig) *Client {
|
|
||||||
return &Client{
|
|
||||||
log: log,
|
|
||||||
authConfig: conf,
|
|
||||||
HttpClient: client.NewHttpClient(log),
|
|
||||||
headers: map[string]string{
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
package youpiaopiao
|
|
||||||
|
|
||||||
// 相关地址
|
|
||||||
const (
|
|
||||||
SiteDomain = "https://www.youpiaopiao.cn" // Domain 后台域名
|
|
||||||
SiteUrl = "https://www.youpiaopiao.cn" // SiteUrl 后台地址
|
|
||||||
DocUrl = "https://www.youpiaopiao.cn" // DocUrl 文档地址
|
|
||||||
ApiDocUrl = "https://www.youpiaopiao.cn" // ApiDocUrl api文档地址
|
|
||||||
)
|
|
||||||
|
|
||||||
// 接口地址
|
|
||||||
const (
|
|
||||||
ApiDomain = "https://www.youpiaopiao.cn" // Domain api域名
|
|
||||||
)
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
package youpiaopiao
|
|
||||||
|
|
||||||
// GenerateH5UrlRequest 生成H5链接请求
|
|
||||||
type GenerateH5UrlRequest struct {
|
|
||||||
ActivityUrl string `json:"activityUrl"` // 活动url
|
|
||||||
Sid string `json:"sid"` // 二级分销ID
|
|
||||||
}
|
|
||||||
@ -30,7 +30,7 @@ type ResponseOrderItem struct {
|
|||||||
// 推送状态: 1.已预估归因 2.预估订单已推送 3.预估订单推送失败 4.结算已提交 5.结算提交中 6.结算取消 7.结算成功 8.结算失败
|
// 推送状态: 1.已预估归因 2.预估订单已推送 3.预估订单推送失败 4.结算已提交 5.结算提交中 6.结算取消 7.结算成功 8.结算失败
|
||||||
Status int `json:"status"`
|
Status int `json:"status"`
|
||||||
// 推广位ID
|
// 推广位ID
|
||||||
PromotionId string `json:"promotion_id"`
|
PromotionId int `json:"promotion_id"`
|
||||||
// 来源ID
|
// 来源ID
|
||||||
SourceId string `json:"source_id"`
|
SourceId string `json:"source_id"`
|
||||||
// 是否被风控
|
// 是否被风控
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user