diff --git a/index.go b/index.go new file mode 100644 index 0000000..117804e --- /dev/null +++ b/index.go @@ -0,0 +1 @@ +package third_platform_sdk diff --git a/platform/meituan-csr/aes.go b/platform/meituan-csr/aes.go new file mode 100644 index 0000000..d0fe53d --- /dev/null +++ b/platform/meituan-csr/aes.go @@ -0,0 +1,61 @@ +package meituan_csr + +import ( + "bytes" + "crypto/aes" + "encoding/base64" +) + +type AES struct { + AesKey string +} + +func NewAes(aesKey string) *AES { + return &AES{ + AesKey: aesKey, + } +} + +func (c *AES) Encode(data string) (string, error) { + _key := []byte(c.AesKey) + + block, err := aes.NewCipher(_key) + if err != nil { + return "", err + } + // 计算需要补齐的字节数 + paddingSize := block.BlockSize() - len([]byte(data))%block.BlockSize() + paddedText := append([]byte(data), bytes.Repeat([]byte{byte(paddingSize)}, paddingSize)...) + + encryptedData := make([]byte, len(paddedText)) + for i := 0; i < len(paddedText); i += block.BlockSize() { + block.Encrypt(encryptedData[i:], paddedText[i:]) // 分组加密 + } + + encodedString := base64.StdEncoding.EncodeToString(encryptedData) // Base64编码 + return encodedString, nil +} +func (c *AES) Decode(data string) (str string, err error) { + _key := []byte(c.AesKey) + + decodedBytes, err := base64.StdEncoding.DecodeString(data) // Base64解码 + if err != nil { + return "", err + } + block, err := aes.NewCipher(_key) // 创建AES对象 + if err != nil { + return "", err + } + decryptedData := make([]byte, len(decodedBytes)) + for i := 0; i < len(decodedBytes); i += block.BlockSize() { + block.Decrypt(decryptedData[i:], decodedBytes[i:]) // 分组解密 + } + unpadedText := c._PKCS5UnPadding(decryptedData) // 去除填充 + return string(unpadedText), nil +} + +func (c *AES) _PKCS5UnPadding(data []byte) []byte { + length := len(data) + unpadding := int(data[length-1]) + return data[:(length - unpadding)] +} diff --git a/platform/meituan-csr/api.go b/platform/meituan-csr/api.go index 8b9ceb1..48739e7 100644 --- a/platform/meituan-csr/api.go +++ b/platform/meituan-csr/api.go @@ -1,11 +1,12 @@ package meituan_csr import ( + "context" "fmt" - "sort" - "strings" + "time" "github.com/zeromicro/go-zero/core/logx" + "github.com/zeromicro/go-zero/core/trace" "chengdu-lenntc/third-platform-sdk/client" "chengdu-lenntc/third-platform-sdk/util" @@ -13,16 +14,50 @@ import ( // Api 调用第三方平台的api type MeituanCsrApi interface { + GetLink(params PromotionLinkRequest) (*PromotionLinkResponse, error) + Url(ctx context.Context, url string) string } -type meituanApiImpl struct { +type meituanCsrApiImpl struct { log logx.Logger client *Client } -func newMeituanApiImpl(log logx.Logger, client *Client) MeituanCsrApi { - return &meituanApiImpl{ +func newMeituanCsrApiImpl(log logx.Logger, client *Client) MeituanCsrApi { + return &meituanCsrApiImpl{ log: log, client: client, } -} \ No newline at end of file +} + +func (a *meituanCsrApiImpl) GetLink(params PromotionLinkRequest) (*PromotionLinkResponse, error) { + queryArgs := util.StructToMap(params) + req := &client.HttpRequest{Headers: a.client.Headers, QueryArgs: queryArgs} + response := new(PromotionLinkResponse) + if err := a.client.HttpGet(GetLinkUrl, req, &client.HttpResponse{Result: response}); err != nil { + return nil, err + } + return response, nil +} + +func (a *meituanCsrApiImpl) Url(ctx context.Context, url string) string { + requestId := trace.TraceIDFromContext(ctx) + timestamp := time.Now().Unix() + accessToken := a.generateAccessToken(timestamp) + return fmt.Sprintf("%s?requestId=%s&version=%s&accessToken=%s&utmSource=%s×tamp=%d", url, requestId, "2.0", accessToken, a.client.authConfig.UtmSource, timestamp) +} + +func (a *meituanCsrApiImpl) sign(params map[string]any) string { + //kvPairs := util.MapToSliceByKeyValue(params) + //sort.Strings(kvPairs) + //paramStr := strings.Join(kvPairs, "") + //return util.Md5String(a.SignKey + paramStr + a.SignKey) + return "" +} + +func (a *meituanCsrApiImpl) generateAccessToken(ts int64) string { + //Access_token生成规则 + //将媒体utmSource与时间戳(秒)拼接起来,然后使用AES加密生成。例如:utmSource为1000,时间戳1555510603,则access_token为AesEncode(10001555510603),每个token有效期为1小时 + encodeStr, _ := a.client.authConfig.aes.Encode(fmt.Sprintf("%s%d", a.client.authConfig.UtmSource, ts)) + return encodeStr +} diff --git a/platform/meituan-csr/client.go b/platform/meituan-csr/client.go index 566b7d1..3ee392e 100644 --- a/platform/meituan-csr/client.go +++ b/platform/meituan-csr/client.go @@ -1 +1,35 @@ package meituan_csr + +import ( + "github.com/zeromicro/go-zero/core/logx" + + "chengdu-lenntc/third-platform-sdk/client" +) + +// AuthConfig api鉴权参数 +type AuthConfig struct { + AppKey string + UtmSource string + aes *AES +} + +// 连接第三方平台的client +type Client struct { + client.ThirdClient + log logx.Logger + authConfig AuthConfig + Headers map[string]string +} + +func newClient(log logx.Logger, conf AuthConfig) *Client { + return &Client{ + ThirdClient: client.NewThirdClient(log), + log: log, + authConfig: conf, + } +} + +func NewApiClient(log logx.Logger, conf AuthConfig) MeituanCsrApi { + clt := newClient(log, conf) + return newMeituanCsrApiImpl(log, clt) +} diff --git a/platform/meituan-csr/consts.go b/platform/meituan-csr/consts.go index 566b7d1..8f83bf5 100644 --- a/platform/meituan-csr/consts.go +++ b/platform/meituan-csr/consts.go @@ -1 +1,6 @@ package meituan_csr + +const ( + Domain = "https://union.dianping.com" + GetLinkUrl = Domain + "/api/promotion/link" +) diff --git a/platform/meituan-csr/types.go b/platform/meituan-csr/types.go index 566b7d1..58c8ba2 100644 --- a/platform/meituan-csr/types.go +++ b/platform/meituan-csr/types.go @@ -1 +1,29 @@ package meituan_csr + +type PromotionLinkRequest struct { + UtmSource string `json:"utmSource"` + UtmMedium string `json:"utmMedium"` + Activity string `json:"activity"` + PromotionId string `json:"promotionId"` + PageLevel int64 `json:"pageLevel"` + UserLevel float64 `json:"userLevel"` + DemandQrInfo bool `json:"demandQrInfo"` +} + +type LinkVO struct { + Activity string `json:"activity"` + CommonLink string `json:"commonLink"` + ShortLink string `json:"shortLink"` + CommonQrCode string `json:"commonQrCode"` + MiniProgramPath string `json:"miniProgramPath"` + MiniProgramQrCode string `json:"miniProgramQrCode"` + MaterialDownloadLink string `json:"materialDownloadLink"` + BeginTime int64 `json:"beginTime"` + EndTime int64 `json:"endTime"` +} + +type PromotionLinkResponse struct { + Code int64 `json:"code"` + Msg string `json:"msg"` + Data LinkVO `json:"data"` +} diff --git a/platform/meituan-union/api.go b/platform/meituan-union/api.go index b1f6e33..b8699e6 100644 --- a/platform/meituan-union/api.go +++ b/platform/meituan-union/api.go @@ -19,19 +19,19 @@ type MeituanUnionApi interface { GetOrderByBatch(params GetOrderByBatchRequest) (*GetOrderByBatchResponse, error) } -type meituanApiImpl struct { +type meituanUnionApiImpl struct { log logx.Logger client *Client } -func newMeituanApiImpl(log logx.Logger, client *Client) MeituanUnionApi { - return &meituanApiImpl{ +func newMeituanUnionApiImpl(log logx.Logger, client *Client) MeituanUnionApi { + return &meituanUnionApiImpl{ log: log, client: client, } } -func (a *meituanApiImpl) GetLink(params GenerateLinkRequest) (*GenerateLinkResponse, error) { +func (a *meituanUnionApiImpl) GetLink(params GenerateLinkRequest) (*GenerateLinkResponse, error) { params.Sign = a.sign(util.StructToMap(params)) queryArgs := util.StructToMap(params) req := &client.HttpRequest{Headers: a.client.Headers, QueryArgs: queryArgs} @@ -42,7 +42,7 @@ func (a *meituanApiImpl) GetLink(params GenerateLinkRequest) (*GenerateLinkRespo return response, nil } -func (a *meituanApiImpl) MiniCode(params MiniCodeRequest) (*MimiCodeResponse, error) { +func (a *meituanUnionApiImpl) MiniCode(params MiniCodeRequest) (*MimiCodeResponse, error) { params.Sign = a.sign(util.StructToMap(params)) queryArgs := util.StructToMap(params) req := &client.HttpRequest{Headers: a.client.Headers, QueryArgs: queryArgs} @@ -52,7 +52,7 @@ func (a *meituanApiImpl) MiniCode(params MiniCodeRequest) (*MimiCodeResponse, er } return response, nil } -func (a *meituanApiImpl) GetOrderBySinge(params GetOrderBySingeRequest) (*GetOrderBySingeResponse, error) { +func (a *meituanUnionApiImpl) GetOrderBySinge(params GetOrderBySingeRequest) (*GetOrderBySingeResponse, error) { params.Sign = a.sign(util.StructToMap(params)) queryArgs := util.StructToMap(params) req := &client.HttpRequest{Headers: a.client.Headers, QueryArgs: queryArgs} @@ -62,7 +62,7 @@ func (a *meituanApiImpl) GetOrderBySinge(params GetOrderBySingeRequest) (*GetOrd } return response, nil } -func (a *meituanApiImpl) GetOrderByBatch(params GetOrderByBatchRequest) (*GetOrderByBatchResponse, error) { +func (a *meituanUnionApiImpl) GetOrderByBatch(params GetOrderByBatchRequest) (*GetOrderByBatchResponse, error) { params.Sign = a.sign(util.StructToMap(params)) queryArgs := util.StructToMap(params) req := &client.HttpRequest{Headers: a.client.Headers, QueryArgs: queryArgs} @@ -73,21 +73,21 @@ func (a *meituanApiImpl) GetOrderByBatch(params GetOrderByBatchRequest) (*GetOrd return response, nil } -func (a *meituanApiImpl) sign(params map[string]interface{}) string { +func (a *meituanUnionApiImpl) sign(params map[string]interface{}) string { kvPairs := a.getSignStr(params) sort.Strings(kvPairs) paramStr := strings.Join(kvPairs, "") return util.Md5String(a.client.authConfig.SignKey + paramStr + a.client.authConfig.SignKey) } -func (a *meituanApiImpl) notifySign(params map[string]interface{}) string { +func (a *meituanUnionApiImpl) notifySign(params map[string]interface{}) string { kvPairs := a.getSignStr(params) sort.Strings(kvPairs) paramStr := strings.Join(kvPairs, "") return util.Md5String(a.client.authConfig.NotifyKey + paramStr + a.client.authConfig.NotifyKey) } -func (a *meituanApiImpl) getSignStr(dataMap map[string]any) []string { +func (a *meituanUnionApiImpl) getSignStr(dataMap map[string]any) []string { var kvPairs []string for k, v := range dataMap { key := a.lowerFirstLetter(k) @@ -99,7 +99,7 @@ func (a *meituanApiImpl) getSignStr(dataMap map[string]any) []string { return kvPairs } -func (a *meituanApiImpl) lowerFirstLetter(s string) string { +func (a *meituanUnionApiImpl) lowerFirstLetter(s string) string { if len(s) == 0 { return s } diff --git a/platform/meituan-union/client.go b/platform/meituan-union/client.go index 2982e5c..fd5bc0d 100644 --- a/platform/meituan-union/client.go +++ b/platform/meituan-union/client.go @@ -31,5 +31,5 @@ func newClient(log logx.Logger, conf AuthConfig) *Client { func NewApiClient(log logx.Logger, conf AuthConfig) MeituanUnionApi { clt := newClient(log, conf) - return newMeituanApiImpl(log, clt) + return newMeituanUnionApiImpl(log, clt) }