This commit is contained in:
邹宗楠
2022-10-14 09:00:50 +08:00
parent c9da2889c3
commit dc9941c99c
12 changed files with 382 additions and 6 deletions

View File

@@ -9,11 +9,12 @@ const (
type RiderInfo struct {
OrderId string `json:"order_id"` // 发单平台订单id(美团,京西,京,京东)
ThirdCarrierOrderId string `json:"third_carrier_order_id"` // 京西平台id
ThirdCarrierOrderId string `json:"third_carrier_order_id"` // 京西平台id(运单id)
CourierName string `json:"courier_name"` // 骑手名称
CourierPhone string `json:"courier_phone"` // 骑手电话
LogisticsProviderCode string `json:"logistics_provider_code"` // 配送平台code 10001-顺丰, 10002-达达, 10003-闪送, 10004-蜂鸟, 10005 UU跑腿,10006 快跑者, 10007 极客快送,10008-点我达,10009 同达, 10010-生活半径,10011 邻趣,10012 趣送, 10013 快服务 10014 菜鸟新配盟 10015 商家自建配送 10016 风先生,10017-其他,10032-美团跑腿
LogisticsStatus int `json:"logistics_status"` // 配送状态
LogisticsContext string `json:"logistics_context"` // 配送状态描述
Latitude string `json:"latitude"` // 骑手当前的纬度,美团使用的是高德坐标系。
Longitude string `json:"longitude"` // 骑手当前的经度,美团使用的是高德坐标系。
}

View File

@@ -0,0 +1,90 @@
package logistics_indTrackPush_reqeust
import (
"encoding/json"
logistics_indTrackPush_response "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/logistics_indTrackPush/response"
doudian_sdk "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/core"
)
type LogisticsIndTrackPushRequest struct {
doudian_sdk.BaseDoudianOpApiRequest
Param *LogisticsIndTrackPushParam
}
// GetUrlPath 同步配送坐标,配送轨迹推送
func (c *LogisticsIndTrackPushRequest) GetUrlPath() string {
return "/logistics/indTrackPush"
}
func New() *LogisticsIndTrackPushRequest {
request := &LogisticsIndTrackPushRequest{
Param: &LogisticsIndTrackPushParam{},
}
request.SetConfig(doudian_sdk.GlobalConfig)
request.SetClient(doudian_sdk.DefaultDoudianOpApiClient)
return request
}
func (c *LogisticsIndTrackPushRequest) Execute(accessToken *doudian_sdk.AccessToken) (*logistics_indTrackPush_response.LogisticsIndTrackPushResponse, error) {
responseJson, err := c.GetClient().Request(c, accessToken)
if err != nil {
return nil, err
}
response := &logistics_indTrackPush_response.LogisticsIndTrackPushResponse{}
_ = json.Unmarshal([]byte(responseJson), response)
return response, nil
}
func (c *LogisticsIndTrackPushRequest) GetParamObject() interface{} {
return c.Param
}
func (c *LogisticsIndTrackPushRequest) GetParams() *LogisticsIndTrackPushParam {
return c.Param
}
type LogisticsIndTrackPushParam struct {
// 请求时间
CurTime string `json:"cur_time"`
// 公司编码
Company string `json:"company"`
// 轨迹信息
TraceMsgs []TraceMsgList `json:"trace_msgs"`
// 未知
AuthorityId string `json:"authority_id"`
}
type TraceMsgList struct {
// 运单号
TrackNo string `json:"track_no"`
// 轨迹列表
Traces []TracesList `json:"traces"`
}
type TracesList struct {
// 事件编码
Opcode string `json:"opcode"`
// 时间操作时间
OpTime string `json:"op_time"`
// 文案
Content string `json:"content"`
// 骑手信息
Rider ReiderInfo `json:"rider"`
// 三方运力公司,顺丰同城 sftc 闪送 shansong 达达 dada UU uupt 美团 meituan 蜂鸟 fengniao
ThirdPartyCompany string `json:"third_party_company"`
// 异常编码
ExceptionCode string `json:"exception_code"`
// 异常原因
ExceptionDesc string `json:"exception_desc"`
// 取消编码
CancelCode string `json:"cancel_code"`
// 取消原因
CancelDesc string `json:"cancel_desc"`
}
type ReiderInfo struct {
Name string `json:"name"` // 骑手姓名
Mobile string `json:"mobile"` // 骑手电话号码
}

View File

@@ -0,0 +1,12 @@
package logistics_indTrackPush_response
import (
doudian_sdk "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/core"
)
type LogisticsIndTrackPushResponse struct {
doudian_sdk.BaseDoudianOpApiResponse
Data *LogisticsIndTrackPushData `json:"data"`
}
type LogisticsIndTrackPushData struct {
}

View File

@@ -0,0 +1,55 @@
package logistics_indTrackRegister_reqeust
import (
"encoding/json"
logistics_indTrackRegister_response "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/logistics_indTrackRegister/response"
doudian_sdk "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/core"
)
type LogisticsIndTrackRegisterRequest struct {
doudian_sdk.BaseDoudianOpApiRequest
Param *LogisticsIndTrackRegisterRequestParam
}
// GetUrlPath 根据即时配单号和公司编码订阅轨迹,用于即时配服务商推送轨迹
func (c *LogisticsIndTrackRegisterRequest) GetUrlPath() string {
return "/logistics/ind/track/register"
}
func New() *LogisticsIndTrackRegisterRequest {
request := &LogisticsIndTrackRegisterRequest{
Param: &LogisticsIndTrackRegisterRequestParam{},
}
request.SetConfig(doudian_sdk.GlobalConfig)
request.SetClient(doudian_sdk.DefaultDoudianOpApiClient)
return request
}
func (c *LogisticsIndTrackRegisterRequest) Execute(accessToken *doudian_sdk.AccessToken) (*logistics_indTrackRegister_response.LogisticsIndTrackRegisterRequestResponse, error) {
responseJson, err := c.GetClient().Request(c, accessToken)
if err != nil {
return nil, err
}
response := &logistics_indTrackRegister_response.LogisticsIndTrackRegisterRequestResponse{}
_ = json.Unmarshal([]byte(responseJson), response)
return response, nil
}
func (c *LogisticsIndTrackRegisterRequest) GetParamObject() interface{} {
return c.Param
}
func (c *LogisticsIndTrackRegisterRequest) GetParams() *LogisticsIndTrackRegisterRequestParam {
return c.Param
}
type LogisticsIndTrackRegisterRequestParam struct {
// 运单号
TrackNo string `json:"track_no"`
// 回调地址
CallbackUrl string `json:"callback_url"`
// 物流商编码
Company string `json:"company"`
}

View File

@@ -0,0 +1,16 @@
package logistics_indTrackRegister_response
import (
doudian_sdk "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/core"
)
type LogisticsIndTrackRegisterRequestResponse struct {
doudian_sdk.BaseDoudianOpApiResponse
Data *LogisticsIndTrackRegisterRequestData `json:"data"`
}
type LogisticsIndTrackRegisterRequestData struct {
Result bool `json:"result"` // 请求结果
ReturnCode string `json:"return_code"` // 响应码
Message string `json:"message"` // 错误消息
}

View File

@@ -2,6 +2,8 @@ package token_create_request
import (
"encoding/json"
token_create_response "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/token_create/response"
doudian_sdk "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/core"
)
type TokenCreateRequest struct {

View File

@@ -1,5 +1,7 @@
package token_create_response
import doudian_sdk "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/core"
type TokenCreateResponse struct {
doudian_sdk.BaseDoudianOpApiResponse
Data *TokenCreateData `json:"data"`

View File

@@ -15,9 +15,12 @@ func (at *AccessToken) IsSuccess() bool {
}
type BuildAccessTokenParam struct {
Code string
ShopId int64
Config *DoudianOpConfig
Code string
ShopId int64
TestShop string `json:"test_shop"`
AuthId string `json:"auth_id"`
AuthSubjectType string `json:"auth_subject_type"`
Config *DoudianOpConfig
}
type RefreshAccessTokenParam struct {

View File

@@ -2,6 +2,7 @@ package tiktok_api
import (
"fmt"
order_logisticsAdd_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/order_logisticsAdd/request"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/globals"
"testing"
@@ -37,3 +38,26 @@ func TestTimeNow(t *testing.T) {
h, m, s := time.Now().Clock()
fmt.Println(h, m, s)
}
func TestSendGoods(t *testing.T) {
token := `{"access_token":"a1746210-a8a3-4497-a87b-09d1f10dbb95","expires_in":1665652230,"scope":"SCOPE","shop_id":"","shop_name":"小时达开放平台对接专用店","refresh_token":"c1cf8d88-0983-4f2a-b969-3746fae6b0cd","authority_id":""}`
a := New("7136048270014416392", "c397aa9f-3927-47c4-8cfe-4d84e02602e0", token)
param := &order_logisticsAdd_request.OrderLogisticsAddParam{
OrderId: "7136048270014416392",
Company: "",
CompanyCode: "chengdouruoxi",
LogisticsCode: "7136048270014416392111",
IsRefundReject: false,
IsRejectRefund: false,
SerialNumberList: nil,
AddressId: 0,
StoreId: 63114504,
}
a.OrderDelivering(param)
}
// 创建物流token
func TestCreateExpss(t *testing.T) {
a := NewExpress("7152420904331429407", "cc7ba367-2394-4cbb-81c6-26f0e929d1c6", "")
a.CreateToken()
}

View File

@@ -0,0 +1,160 @@
package tiktok_api
import (
"encoding/json"
"errors"
logistics_indTrackPush_reqeust "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/logistics_indTrackPush/request"
token_create_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/token_create/request"
token_create_response "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/token_create/response"
doudian_sdk "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/core"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/globals"
"sync"
"time"
)
type APIExpress struct {
appKey string
appSecret string
accessToken string
refreshToken string
expiresIn int64 // 当前时间的七天内为有效期
locker sync.RWMutex
accessTokenObj *doudian_sdk.AccessToken // 存储数据库
}
func NewExpress(appKey, appSecret, accessToken string) *APIExpress {
var access *doudian_sdk.AccessToken
doudian_sdk.GlobalConfig.AppKey = appKey
doudian_sdk.GlobalConfig.AppSecret = appSecret
if accessToken != "" {
if err := json.Unmarshal([]byte(accessToken), &access); err != nil {
globals.SugarLogger.Debug("accessToken init err :", err)
return nil
}
api := &APIExpress{
appKey: appKey,
appSecret: appSecret,
accessToken: access.AccessToken,
refreshToken: access.RefreshToken,
expiresIn: access.ExpiresIn,
accessTokenObj: access,
}
if access.ExpiresIn < time.Now().Unix() {
api.RefreshToken()
}
return api
}
return &APIExpress{
appKey: appKey,
appSecret: appSecret,
}
}
// CreateToken 创建token只有第一次授权或者更新授权才需要,其他时候直接刷新就可以啦
func (a *APIExpress) CreateToken() (*token_create_response.TokenCreateData, error) {
request := token_create_request.New()
param := request.GetParams()
param.Code = ""
param.GrantType = "authorization_self"
param.AuthId = "powertestexpress"
param.AuthSubjectType = "WuLiuShang"
response, err := request.Execute(nil)
if err != nil {
return nil, err
}
if response.Code != RequestSuccessCode {
return nil, errors.New(response.SubMsg)
}
a.accessTokenObj.CreateTokenData = doudian_sdk.CreateTokenData{
AccessToken: response.Data.AccessToken,
ExpiresIn: time.Now().Unix() + response.Data.ExpiresIn,
Scope: response.Data.Scope,
ShopId: utils.Int64ToStr(response.Data.ShopId),
ShopName: response.Data.ShopName,
RefreshToken: response.Data.RefreshToken,
AuthorityId: response.Data.AuthorityId,
}
return response.Data, nil
}
// RefreshToken 刷新token
func (a *APIExpress) RefreshToken() (*doudian_sdk.CreateTokenData, error) {
doudian_sdk.GlobalConfig.AppKey = a.appKey
doudian_sdk.GlobalConfig.AppSecret = a.appSecret
refresh := doudian_sdk.NewRefreshTokenRequest()
refresh.GetParam().RefreshToken = a.refreshToken
refresh.GetParam().GrantType = "refresh_token"
createToken, err := refresh.Execute(a.accessTokenObj)
if err != nil {
return nil, err
}
if createToken.Code != RequestSuccessCode {
return nil, errors.New(createToken.SubMsg)
}
a.accessToken = createToken.Data.AccessToken
a.refreshToken = createToken.Data.RefreshToken
a.expiresIn = time.Now().Unix() + createToken.Data.ExpiresIn
globals.SugarLogger.Debug("===============data", createToken.Data)
// 不要
createToken.Data.ExpiresIn = a.expiresIn
strData, _ := json.Marshal(createToken.Data)
a.accessTokenObj.CreateTokenData = createToken.Data
globals.SugarLogger.Debug("=========", string(strData))
return &createToken.Data, nil
}
// OrderStatusAndPsInfo 三方配送同步骑手位置信息
// 抖音物流信息和抖音小时达完全区分开(这边的appKey和APPSecret完全不同于小时达)
func (a *APIExpress) OrderStatusAndPsInfo(param map[string]interface{}) error {
// 组合参数
request := logistics_indTrackPush_reqeust.New()
psInfo := &logistics_indTrackPush_reqeust.LogisticsIndTrackPushParam{
CurTime: utils.Time2Str(time.Now()),
Company: TiktokExpressCode,
TraceMsgs: nil,
AuthorityId: "",
}
traceMsgs := make([]logistics_indTrackPush_reqeust.TraceMsgList, 0, 1)
traceMsg := logistics_indTrackPush_reqeust.TraceMsgList{
TrackNo: param["third_carrier_order_id"].(string),
Traces: []logistics_indTrackPush_reqeust.TracesList{
{
Opcode: "ORDER_RECEIVED",
OpTime: utils.Time2TimeStr(time.Now()),
Content: param["logistics_context"].(string),
Rider: logistics_indTrackPush_reqeust.ReiderInfo{
Name: param["courier_name"].(string),
Mobile: param["courier_phone"].(string),
},
ThirdPartyCompany: TiktokExpressCode,
ExceptionCode: "",
ExceptionDesc: "",
CancelCode: "",
CancelDesc: "",
},
},
}
traceMsgs = append(traceMsgs, traceMsg)
psInfo.TraceMsgs = traceMsgs
request.Param = psInfo
if a.accessTokenObj == nil || a.accessTokenObj.CreateTokenData.AccessToken == "" {
a.CreateToken()
} else if a.accessTokenObj.CreateTokenData.ExpiresIn < time.Now().Unix() {
a.RefreshToken()
}
result, err := request.Execute(a.accessTokenObj)
if err != nil {
return err
}
if result.Code != RequestSuccessCode {
return errors.New(result.SubMsg)
}
return nil
}

View File

@@ -595,7 +595,17 @@ func (a *API) GetCallbackOrderId(msgId string, data interface{}) (string, *Callb
return "", &CallbackResponse{Code: CallbackSuccessCode, Msg: CallbackSuccess}
}
// OrderStatusAndPsInfo 三方配送同步骑手位置信息
func (a *API) OrderStatusAndPsInfo(param map[string]interface{}) error {
// OrderDelivering 订单发货
func (a *API) OrderDelivering(param *order_logisticsAdd_request.OrderLogisticsAddParam) error {
request := order_logisticsAdd_request.New()
request.Param = param
result, err := request.Execute(a.accessTokenObj)
if err != nil {
return err
}
if result.Code != RequestSuccessCode {
return errors.New(result.SubMsg)
}
return nil
}

View File

@@ -1,6 +1,7 @@
package tiktok_api
const RequestSuccessCode = 10000
const TiktokExpressCode = "chengduruoxi"
// 订单消息回调类型(正向订单)
const (