同程api对接
This commit is contained in:
parent
cdb09a992f
commit
08359eefcc
3
go.mod
3
go.mod
@ -12,6 +12,8 @@ require (
|
|||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
require google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/fatih/color v1.15.0 // indirect
|
github.com/fatih/color v1.15.0 // indirect
|
||||||
@ -26,5 +28,6 @@ require (
|
|||||||
go.uber.org/automaxprocs v1.5.3 // indirect
|
go.uber.org/automaxprocs v1.5.3 // indirect
|
||||||
go.uber.org/multierr v1.9.0 // indirect
|
go.uber.org/multierr v1.9.0 // indirect
|
||||||
golang.org/x/sys v0.11.0 // indirect
|
golang.org/x/sys v0.11.0 // indirect
|
||||||
|
google.golang.org/protobuf v1.31.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
9
index.go
9
index.go
@ -10,6 +10,7 @@ import (
|
|||||||
"gitee.com/chengdu-lenntc/third-platform-sdk/platform/meituan-media"
|
"gitee.com/chengdu-lenntc/third-platform-sdk/platform/meituan-media"
|
||||||
meituanunion "gitee.com/chengdu-lenntc/third-platform-sdk/platform/meituan-union"
|
meituanunion "gitee.com/chengdu-lenntc/third-platform-sdk/platform/meituan-union"
|
||||||
t3_union "gitee.com/chengdu-lenntc/third-platform-sdk/platform/t3-union"
|
t3_union "gitee.com/chengdu-lenntc/third-platform-sdk/platform/t3-union"
|
||||||
|
tong_cheng "gitee.com/chengdu-lenntc/third-platform-sdk/platform/tong-cheng"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Platform 第三方平台
|
// Platform 第三方平台
|
||||||
@ -28,6 +29,8 @@ const (
|
|||||||
PlatformMeituanMedia = "meituan_media"
|
PlatformMeituanMedia = "meituan_media"
|
||||||
// PlatformJutuike 聚推客
|
// PlatformJutuike 聚推客
|
||||||
PlatformJutuike = "jutuike"
|
PlatformJutuike = "jutuike"
|
||||||
|
// PlatformTongCheng 同程酒店
|
||||||
|
PlatformTongCheng = "tong_cheng"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PlatformNameMap 平台名称
|
// PlatformNameMap 平台名称
|
||||||
@ -39,6 +42,7 @@ var PlatformNameMap = map[string]string{
|
|||||||
PlatformT3Union: "t3联盟",
|
PlatformT3Union: "t3联盟",
|
||||||
PlatformMeituanMedia: "美团-美天赚",
|
PlatformMeituanMedia: "美团-美天赚",
|
||||||
PlatformJutuike: "聚推客",
|
PlatformJutuike: "聚推客",
|
||||||
|
PlatformTongCheng: "同程酒店",
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPlatformName 获取平台名称
|
// GetPlatformName 获取平台名称
|
||||||
@ -80,3 +84,8 @@ func NewMeituanMediaApi(log logx.Logger, conf meituan_media.AuthConfig) meituan_
|
|||||||
func NewJutuikeApi(log logx.Logger, conf jutuike.AuthConfig) jutuike.JutuikeApi {
|
func NewJutuikeApi(log logx.Logger, conf jutuike.AuthConfig) jutuike.JutuikeApi {
|
||||||
return jutuike.NewApiClient(log, conf)
|
return jutuike.NewApiClient(log, conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewTongChengApi 同程酒店
|
||||||
|
func NewTongChengApi(log logx.Logger, conf tong_cheng.AuthConfig) tong_cheng.TongChengApi {
|
||||||
|
return tong_cheng.NewApiClient(log, conf)
|
||||||
|
}
|
||||||
|
|||||||
90
platform/tong-cheng/api.go
Normal file
90
platform/tong-cheng/api.go
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
package tong_cheng
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/md5"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
|
||||||
|
"gitee.com/chengdu-lenntc/third-platform-sdk/client"
|
||||||
|
"gitee.com/chengdu-lenntc/third-platform-sdk/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TongChengApi 同程酒店的api
|
||||||
|
// Api defines the interface of tong-cheng api
|
||||||
|
type TongChengApi interface {
|
||||||
|
// GenerateLink 生成链接
|
||||||
|
GenerateLink(ctx context.Context, req GenerateLinkRequest, env string) (*ExternalChannelConfigResponse, error)
|
||||||
|
// QueryOrderList 查询订单列表
|
||||||
|
QueryOrderList(ctx context.Context, req QueryOrderListRequest, env string) (*ExternalOrderData, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type tongChengApiImpl struct {
|
||||||
|
log logx.Logger
|
||||||
|
client *Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func newTongChengApiImpl(log logx.Logger, client *Client) TongChengApi {
|
||||||
|
return &tongChengApiImpl{
|
||||||
|
log: log,
|
||||||
|
client: client,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateLink 生成短链
|
||||||
|
func (t *tongChengApiImpl) GenerateLink(ctx context.Context, req GenerateLinkRequest, env string) (*ExternalChannelConfigResponse, error) {
|
||||||
|
var url string
|
||||||
|
token := t.client.authConfig.Token
|
||||||
|
tn := time.Now()
|
||||||
|
actionTime := tn.Unix()
|
||||||
|
h := md5.New()
|
||||||
|
h.Write([]byte(fmt.Sprintf("%s%d", token, actionTime)))
|
||||||
|
queryArgs := &GetExternalChannelConfigReq{
|
||||||
|
ActionTime: tn.Unix(),
|
||||||
|
Token: token,
|
||||||
|
Code: string(h.Sum(nil)),
|
||||||
|
Trackid: req.Trackid,
|
||||||
|
}
|
||||||
|
args := util.StructToMap(queryArgs)
|
||||||
|
request := &client.HttpRequest{Headers: t.client.headers, QueryArgs: args}
|
||||||
|
response := new(GetExternalChannelConfigResp)
|
||||||
|
if env == EnvHuidu {
|
||||||
|
url = HDApiDomain + GetLinkUri
|
||||||
|
} else {
|
||||||
|
url = ApiDomain + GetLinkUri
|
||||||
|
}
|
||||||
|
if err := t.client.HttpGet(url, request, &client.HttpResponse{Result: response}); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if response.Code != 200 {
|
||||||
|
t.log.WithFields(logx.LogField{Key: "data", Value: map[string]any{"req": req, "resp": response}}).
|
||||||
|
Errorf("[tongChengApiImpl][GenerateLink] response result error: %s", response.Msg)
|
||||||
|
return nil, errors.New(response.Msg)
|
||||||
|
}
|
||||||
|
return response.Data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryOrderList 查询订单列表
|
||||||
|
func (t *tongChengApiImpl) QueryOrderList(ctx context.Context, req QueryOrderListRequest, env string) (*ExternalOrderData, error) {
|
||||||
|
var url string
|
||||||
|
args := util.StructToMap(req)
|
||||||
|
request := &client.HttpRequest{Headers: t.client.headers, QueryArgs: args}
|
||||||
|
response := new(GetExternalOrderResp)
|
||||||
|
if env == EnvHuidu {
|
||||||
|
url = HDApiDomain + GetOrderListUri
|
||||||
|
} else {
|
||||||
|
url = ApiDomain + GetOrderListUri
|
||||||
|
}
|
||||||
|
if err := t.client.HttpGet(url, request, &client.HttpResponse{Result: response}); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if response.Code != 200 {
|
||||||
|
t.log.WithFields(logx.LogField{Key: "data", Value: map[string]any{"req": req, "resp": response}}).
|
||||||
|
Errorf("[tongChengApiImpl][QueryOrderList] response result error: %s", response.Msg)
|
||||||
|
return nil, errors.New(response.Msg)
|
||||||
|
}
|
||||||
|
return response.Data, nil
|
||||||
|
}
|
||||||
68
platform/tong-cheng/api_test.go
Normal file
68
platform/tong-cheng/api_test.go
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
package tong_cheng
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
// api-单元测试
|
||||||
|
type apiClientSuite struct {
|
||||||
|
suite.Suite
|
||||||
|
api TongChengApi
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestApiClient(t *testing.T) {
|
||||||
|
suite.Run(t, new(apiClientSuite))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *apiClientSuite) SetupSuite() {
|
||||||
|
log := logx.WithContext(context.Background())
|
||||||
|
apiClient := NewApiClient(log, AuthConfig{
|
||||||
|
Token: "dfae91a85341865b",
|
||||||
|
})
|
||||||
|
a.api = apiClient
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *apiClientSuite) Test_GenerateLink() {
|
||||||
|
req := GenerateLinkRequest{
|
||||||
|
Trackid: "elong_hotel",
|
||||||
|
}
|
||||||
|
result, err := a.api.GenerateLink(context.Background(), req, "huidu")
|
||||||
|
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{
|
||||||
|
AppId: "",
|
||||||
|
Trackid: "",
|
||||||
|
BeginDate: "2024-07-01 00:00:00",
|
||||||
|
EndDate: "2024-07-01 23:59:59",
|
||||||
|
Update: 1,
|
||||||
|
PageIndex: 0,
|
||||||
|
PageSize: 1,
|
||||||
|
}
|
||||||
|
result, err := a.api.QueryOrderList(context.Background(), req, "huidu")
|
||||||
|
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))
|
||||||
|
}
|
||||||
36
platform/tong-cheng/client.go
Normal file
36
platform/tong-cheng/client.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package tong_cheng
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
|
||||||
|
"gitee.com/chengdu-lenntc/third-platform-sdk/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AuthConfig api鉴权参数
|
||||||
|
type AuthConfig struct {
|
||||||
|
Token string // 分配的token
|
||||||
|
}
|
||||||
|
|
||||||
|
// 连接第三方平台的client
|
||||||
|
type Client struct {
|
||||||
|
log logx.Logger
|
||||||
|
authConfig AuthConfig
|
||||||
|
client.HttpClient
|
||||||
|
headers map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewApiClient(log logx.Logger, conf AuthConfig) TongChengApi {
|
||||||
|
clt := newClient(log, conf)
|
||||||
|
return newTongChengApiImpl(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",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
26
platform/tong-cheng/consts.go
Normal file
26
platform/tong-cheng/consts.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package tong_cheng
|
||||||
|
|
||||||
|
// 相关地址
|
||||||
|
const (
|
||||||
|
SiteDomain = "" // Domain 后台域名
|
||||||
|
SiteUrl = "" // SiteUrl 后台地址
|
||||||
|
DocUrl = "" // DocUrl 文档地址
|
||||||
|
ApiDocUrl = "" // ApiDocUrl api文档地址
|
||||||
|
)
|
||||||
|
|
||||||
|
// header头信息
|
||||||
|
const ()
|
||||||
|
|
||||||
|
// 环境
|
||||||
|
const (
|
||||||
|
EnvProd = "prod" // 正式环境
|
||||||
|
EnvHuidu = "huidu" // 灰度
|
||||||
|
)
|
||||||
|
|
||||||
|
// 接口地址
|
||||||
|
const (
|
||||||
|
HDApiDomain = "https://mp-blindbox-hd.elong.com" // Domain api域名 (灰度环境)
|
||||||
|
ApiDomain = "https://mp-blindbox.elong.com" // api域名(正式环境)
|
||||||
|
GetLinkUri = "/nopaymentorder/externalorder/getExternalChannelConfig" // 生成跳转链接uri
|
||||||
|
GetOrderListUri = "/nopaymentorder/externalorder/getExternalOrder" // 获取订单uri
|
||||||
|
)
|
||||||
1
platform/tong-cheng/sign.go
Normal file
1
platform/tong-cheng/sign.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package tong_cheng
|
||||||
90
platform/tong-cheng/types.go
Normal file
90
platform/tong-cheng/types.go
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
package tong_cheng
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"google.golang.org/genproto/googleapis/type/decimal"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CommonResponse struct {
|
||||||
|
Code int32 `json:"code"` // 状态码,200为正常
|
||||||
|
Msg string `json:"msg"` // 返回信息
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成链接请求
|
||||||
|
type GenerateLinkRequest struct {
|
||||||
|
Trackid string `json:"trackid"` // 跟踪id,排查问题使用,guid即可
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取外部渠道配置请求
|
||||||
|
type GetExternalChannelConfigReq struct {
|
||||||
|
ActionTime int64 `json:"action_time"` // 必传,请求时间戳
|
||||||
|
Token string `json:"token"` // 必传,token
|
||||||
|
Code string `json:"code"` // 必传,校验参数
|
||||||
|
Trackid string `json:"trackid"` // 必传,跟踪id,排查问题使用,guid即可
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取外部渠道配置响应
|
||||||
|
type GetExternalChannelConfigResp struct {
|
||||||
|
CommonResponse
|
||||||
|
Data *ExternalChannelConfigResponse `json:"data"` // 数据
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取外部渠道配置数据
|
||||||
|
type ExternalChannelConfigResponse struct {
|
||||||
|
ActivityUrl string `json:"activityUrl"` // 渠道方合作页地址
|
||||||
|
AppId string `json:"appId"` // appId,接口查询验证使用
|
||||||
|
AppSecret string `json:"appSecret"` // appSecret,密钥验证使用
|
||||||
|
GetOrderServiceUrl string `json:"getOrderServiceUrl"` // 渠道方主动查询地址
|
||||||
|
PushOrderServiceUrl string `json:"pushOrderServiceUrl"` // 渠道方推送地址
|
||||||
|
OtherActivityUrls []*OtherActivityUrl `json:"otherActivityUrls"` // 其他的渠道方合作页地址
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其他的渠道方合作页地址
|
||||||
|
type OtherActivityUrl struct {
|
||||||
|
Name string `json:"name"` // 合作页地址名称
|
||||||
|
ActivityUrl string `json:"activityUrl"` // 渠道方合作页地址
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取外部订单请求
|
||||||
|
type QueryOrderListRequest struct {
|
||||||
|
AppId string `json:"appId"` // 必传,分配token查询接口提供的appId(getExternalChannelConfig接口返回的appId)
|
||||||
|
Trackid string `json:"trackid"` // 必传,跟踪id,排查问题使用,guid即可
|
||||||
|
BeginDate string `json:"begin_date"` // 订单更新时间查询起始,精确到秒, yyyy-MM-dd HH:mm:ss(除了传订单号外,其他查询必传)
|
||||||
|
EndDate string `json:"end_date"` // 订单更新时间查询结束,精确到秒, yyyy-MM-dd HH:mm:ss(除了传订单号外,其他查询必传)
|
||||||
|
OrderId string `json:"order_id"` // 指定订单号查询,返回该订单的最新详情
|
||||||
|
Update int32 `json:"update"` // 0:仅已支付的订单, 1:所有状态订单, 默认查所有传1
|
||||||
|
PageIndex int32 `json:"page_index"` // 分页index,从0开始(除了传订单号外,其他查询必传)
|
||||||
|
PageSize int32 `json:"page_size"` // 分页条数(除了传订单号外,其他查询必传)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取外部订单响应
|
||||||
|
type GetExternalOrderResp struct {
|
||||||
|
CommonResponse
|
||||||
|
Data *ExternalOrderData `json:"data"` // 数据
|
||||||
|
}
|
||||||
|
|
||||||
|
type ExternalOrderData struct {
|
||||||
|
ExternalOrderDataList []*ExternalOrder `json:"externalOrderDataList"` // 订单数据
|
||||||
|
}
|
||||||
|
|
||||||
|
// 订单详情
|
||||||
|
type ExternalOrder struct {
|
||||||
|
ExtendInfo string `json:"extendInfo"` // 订单附加信息json格式
|
||||||
|
HotelCityName string `json:"hotelCityName"` // 酒店所在城市名称
|
||||||
|
HotelName string `json:"hotelName"` // 酒店名称
|
||||||
|
OrderCheckIn string `json:"orderCheckIn"` // 入住日期
|
||||||
|
OrderCheckOut string `json:"orderCheckOut"` // 离店时间
|
||||||
|
OrderCreateTime string `json:"orderCreateTime"` // 订单创建时间date-time
|
||||||
|
OrderModifyTime string `json:"orderModifyTime"` // 订单更新时间date-time
|
||||||
|
OrderNo string `json:"orderNo"` // 订单号
|
||||||
|
OrderPayAmount decimal.Decimal `json:"orderPayAmount"` // 订单实付金额
|
||||||
|
OrderPayTime time.Time `json:"orderPayTime"` // 订单支付时间 date-time
|
||||||
|
OrderStatus int32 `json:"orderStatus"` // 订单组推送的订单状态(1: 已支付 2:已离店 3:已取消)
|
||||||
|
OrderCommission decimal.Decimal `json:"orderCommission"` // 订单佣金
|
||||||
|
Uid string `json:"uid"` // 第三方用户id
|
||||||
|
HotelProvinceName string `json:"hotelProvinceName"` // 酒店所在省份
|
||||||
|
RoomNights int32 `json:"roomNights"` // 入住间夜
|
||||||
|
RoomCount int32 `json:"roomCount"` // 入住房间数量
|
||||||
|
HourRoom int32 `json:"hourRoom"` // 是否钟点房1:是 0:不是 -1:旧数据
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user