2024-06-14 15:26:27 +08:00
|
|
|
package coach_client
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2024-06-14 17:42:07 +08:00
|
|
|
"crypto/tls"
|
2024-06-14 15:26:27 +08:00
|
|
|
"fmt"
|
2024-12-06 17:07:14 +08:00
|
|
|
"time"
|
|
|
|
|
2024-06-14 15:26:27 +08:00
|
|
|
"github.com/bytedance/sonic"
|
|
|
|
"github.com/cloudwego/hertz/pkg/app/client"
|
2024-06-14 17:42:07 +08:00
|
|
|
"github.com/cloudwego/hertz/pkg/network/standard"
|
2024-06-14 15:26:27 +08:00
|
|
|
"github.com/cloudwego/hertz/pkg/protocol"
|
|
|
|
"github.com/corpix/uarand"
|
|
|
|
)
|
|
|
|
|
2024-06-16 10:02:31 +08:00
|
|
|
type XMacHeader string
|
|
|
|
|
|
|
|
const (
|
|
|
|
XMac_Coach XMacHeader = "e6d4b3d780db4251bc4b6b54f41ee7b0"
|
|
|
|
XMac_Outlet XMacHeader = "b55d4769f3e768630046291ee2ee26f0"
|
|
|
|
)
|
|
|
|
|
2024-06-14 15:26:27 +08:00
|
|
|
type CN struct {
|
2024-06-16 10:02:31 +08:00
|
|
|
c *client.Client
|
|
|
|
xmac XMacHeader
|
2024-06-14 15:26:27 +08:00
|
|
|
}
|
|
|
|
|
2024-06-16 10:02:31 +08:00
|
|
|
func CNClient(xmac XMacHeader) (cli *CN, err error) {
|
2024-06-14 15:26:27 +08:00
|
|
|
cli = new(CN)
|
2024-06-14 17:42:07 +08:00
|
|
|
clientCfg := &tls.Config{
|
|
|
|
InsecureSkipVerify: true,
|
|
|
|
}
|
|
|
|
cli.c, err = client.NewClient(
|
|
|
|
client.WithTLSConfig(clientCfg),
|
|
|
|
client.WithDialer(standard.NewDialer()),
|
|
|
|
)
|
2024-06-16 10:02:31 +08:00
|
|
|
cli.xmac = xmac
|
2024-06-14 15:26:27 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
type CNData interface {
|
|
|
|
ItemListData
|
|
|
|
}
|
|
|
|
|
|
|
|
type CNResponse[data CNData] struct {
|
|
|
|
Data data `json:"data"`
|
|
|
|
Msg string `json:"msg"`
|
|
|
|
Rid string `json:"rid"`
|
|
|
|
StatusCode string `json:"statusCode"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type ItemListData struct {
|
|
|
|
Count int `json:"count"`
|
|
|
|
CurrentPage int `json:"currentPage"`
|
|
|
|
Items []CNItem `json:"items"`
|
|
|
|
Size int `json:"size"`
|
|
|
|
TotalPages int `json:"totalPages"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type CNItem struct {
|
|
|
|
Code string `json:"code"`
|
|
|
|
DiscountRateMin float64 `json:"discountRateMin"`
|
|
|
|
Id int `json:"id"`
|
|
|
|
Images []struct {
|
|
|
|
Imgs []struct {
|
|
|
|
Config string `json:"config"`
|
|
|
|
Img string `json:"img"`
|
|
|
|
Position int `json:"position"`
|
|
|
|
Resource string `json:"resource"`
|
|
|
|
Type int `json:"type"`
|
|
|
|
} `json:"imgs"`
|
|
|
|
ItemPropId int `json:"itemPropId"`
|
|
|
|
} `json:"images"`
|
|
|
|
ListPrice float64 `json:"listPrice"`
|
|
|
|
SalePrice float64 `json:"salePrice"`
|
|
|
|
SkuMaxPrice float64 `json:"skuMaxPrice"`
|
|
|
|
Stock int `json:"stock"`
|
|
|
|
Style string `json:"style"`
|
|
|
|
Title string `json:"title"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *CN) ListItems(_ctx context.Context, page, size int) (ItemListData, error) {
|
|
|
|
req, resp := protocol.AcquireRequest(), protocol.AcquireResponse()
|
|
|
|
defer func() {
|
|
|
|
protocol.ReleaseRequest(req)
|
|
|
|
protocol.ReleaseResponse(resp)
|
|
|
|
}()
|
|
|
|
page = max(page, 1)
|
|
|
|
size = max(size, 50)
|
|
|
|
req.SetRequestURI("https://ec-api.coach.com.cn/api/v2/item/search")
|
|
|
|
req.SetMethod("GET")
|
2024-06-16 10:02:31 +08:00
|
|
|
req.SetHeader("X-Ma-C", string(c.xmac))
|
2024-06-14 15:26:27 +08:00
|
|
|
req.SetHeader("User-Agent", uarand.GetRandom())
|
|
|
|
req.SetQueryString(fmt.Sprintf("scope=shop&pageNo=%d&pageSize=%d", page, size))
|
|
|
|
|
|
|
|
ctx, cancel := context.WithTimeout(_ctx, time.Second*30)
|
|
|
|
defer cancel()
|
|
|
|
err := c.c.Do(ctx, req, resp)
|
|
|
|
if err != nil {
|
|
|
|
return ItemListData{}, err
|
|
|
|
}
|
|
|
|
var respData CNResponse[ItemListData]
|
|
|
|
if err = sonic.Unmarshal(resp.Body(), &respData); err != nil {
|
|
|
|
return ItemListData{}, err
|
|
|
|
}
|
|
|
|
if respData.StatusCode != "100010" {
|
|
|
|
return ItemListData{}, fmt.Errorf("status code: %s, msg: %s", respData.StatusCode, respData.Msg)
|
|
|
|
}
|
|
|
|
return respData.Data, nil
|
|
|
|
}
|