diff --git a/sdk_tb_linkedmall/client.go b/sdk_tb_linkedmall/client.go new file mode 100644 index 0000000..b5b3d7a --- /dev/null +++ b/sdk_tb_linkedmall/client.go @@ -0,0 +1,674 @@ +package sdk_tb_linkedmall + +import ( + "encoding/json" + "fmt" + "strconv" + + openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client" + "github.com/alibabacloud-go/tea" +) + +// Client 是LinkedMall SDK客户端,封装了所有API方法 +type Client struct { + openapiClient *openapi.Client + basePath string +} + +// NewClient 创建LinkedMall SDK客户端 +// - accessKeyId: RAM子账号的AccessKeyId +// - accessKeySecret: RAM子账号的AccessKeySecret +func NewClient(accessKeyId, accessKeySecret string) (*Client, error) { + config := &openapi.Config{ + AccessKeyId: tea.String(accessKeyId), + AccessKeySecret: tea.String(accessKeySecret), + RegionId: tea.String("cn-zhangjiakou"), + Endpoint: tea.String("linkedmall.cn-zhangjiakou.aliyuncs.com"), + ReadTimeout: tea.Int(30000), + ConnectTimeout: tea.Int(10000), + } + apiClient, err := openapi.NewClient(config) + if err != nil { + return nil, fmt.Errorf("failed to create openapi client: %w", err) + } + return &Client{ + openapiClient: apiClient, + basePath: "/opensaas-s2b/opensaas-s2b-biz-trade/v2", + }, nil +} + +// doRequest 执行ROA请求,并解析公共响应体 +func (c *Client) doRequest(method, path string, query map[string]string, body interface{}) (*CommonResponse, error) { + // 转换query为map[string]*string + teaQuery := make(map[string]*string, len(query)) + for k, v := range query { + if v != "" { + teaQuery[k] = tea.String(v) + } + } + + fullPath := c.basePath + path + + respBytes, err := c.openapiClient.RoaRequest( + tea.String(method), + tea.String(fullPath), + teaQuery, + body, + nil, + ) + if err != nil { + return nil, fmt.Errorf("roa request failed: %w", err) + } + + var commonResp CommonResponse + if err := json.Unmarshal(respBytes, &commonResp); err != nil { + return nil, fmt.Errorf("failed to parse response: %w", err) + } + + return &commonResp, nil +} + +// parseData 将CommonResponse的Data字段解析到目标结构体 +func parseData(commonResp *CommonResponse, target interface{}) error { + dataBytes, err := json.Marshal(commonResp.Data) + if err != nil { + return fmt.Errorf("failed to marshal data: %w", err) + } + if err := json.Unmarshal(dataBytes, target); err != nil { + return fmt.Errorf("failed to unmarshal data: %w", err) + } + return nil +} + +// ============================================================ +// 接口1:ListPurchaserShops - 分页获取采购方店铺列表 +// ============================================================ + +// ListPurchaserShops 分页获取采购方店铺列表 +func (c *Client) ListPurchaserShops(req *ListPurchaserShopsReq) (*CommonResponse, *ListPurchaserShopsRespData, error) { + query := make(map[string]string) + if req.PageNum > 0 { + query["PageNum"] = strconv.Itoa(req.PageNum) + } + if req.PageSize > 0 { + query["PageSize"] = strconv.Itoa(req.PageSize) + } + + commonResp, err := c.doRequest("GET", "/purchaser-shops", query, nil) + if err != nil { + return nil, nil, err + } + if err := CheckResponse(commonResp); err != nil { + return commonResp, nil, err + } + + var data ListPurchaserShopsRespData + if err := parseData(commonResp, &data); err != nil { + return commonResp, nil, err + } + return commonResp, &data, nil +} + +// ============================================================ +// 接口2:GetPurchaserShop - 获取单个采购店铺详情 +// ============================================================ + +// GetPurchaserShop 获取单个采购店铺详情 +func (c *Client) GetPurchaserShop(shopId string) (*CommonResponse, *GetPurchaserShopRespData, error) { + query := make(map[string]string) + + commonResp, err := c.doRequest("GET", "/purchaser-shops/"+shopId, query, nil) + if err != nil { + return nil, nil, err + } + if err := CheckResponse(commonResp); err != nil { + return commonResp, nil, err + } + + var data GetPurchaserShopRespData + if err := parseData(commonResp, &data); err != nil { + return commonResp, nil, err + } + return commonResp, &data, nil +} + +// ============================================================ +// 接口3:ListSelectionProducts - 分页查询选品池商品列表 +// ============================================================ + +// ListSelectionProducts 分页查询选品池商品列表 +func (c *Client) ListSelectionProducts(req *ListSelectionProductsReq) (*CommonResponse, *ListSelectionProductsRespData, error) { + query := make(map[string]string) + query["PurchaserId"] = req.PurchaserId + if req.PageNum > 0 { + query["PageNum"] = strconv.Itoa(req.PageNum) + } + if req.PageSize > 0 { + query["PageSize"] = strconv.Itoa(req.PageSize) + } + + commonResp, err := c.doRequest("GET", "/selection-products", query, nil) + if err != nil { + return nil, nil, err + } + if err := CheckResponse(commonResp); err != nil { + return commonResp, nil, err + } + + var data ListSelectionProductsRespData + if err := parseData(commonResp, &data); err != nil { + return commonResp, nil, err + } + return commonResp, &data, nil +} + +// ============================================================ +// 接口4:GetSelectionProduct - 查询选品池商品详情 +// ============================================================ + +// GetSelectionProduct 查询选品池商品详情 +// - divisionCode: 可选,五级乡镇区域编码,传入后返回该区域可售状态 +func (c *Client) GetSelectionProduct(req *GetSelectionProductReq) (*CommonResponse, *GetSelectionProductRespData, error) { + query := make(map[string]string) + query["PurchaserId"] = req.PurchaserId + if req.DivisionCode != "" { + query["DivisionCode"] = req.DivisionCode + } + + commonResp, err := c.doRequest("GET", "/selection-products/"+req.ProductId, query, nil) + if err != nil { + return nil, nil, err + } + if err := CheckResponse(commonResp); err != nil { + return commonResp, nil, err + } + + var data GetSelectionProductRespData + if err := parseData(commonResp, &data); err != nil { + return commonResp, nil, err + } + return commonResp, &data, nil +} + +// ============================================================ +// 接口5:GetSelectionProductSaleInfo - 查询选品池商品销售信息 +// ============================================================ + +// GetSelectionProductSaleInfo 查询选品池商品销售信息 +func (c *Client) GetSelectionProductSaleInfo(req *GetSelectionProductSaleInfoReq) (*CommonResponse, *GetSelectionProductSaleInfoRespData, error) { + query := make(map[string]string) + query["PurchaserId"] = req.PurchaserId + if req.DivisionCode != "" { + query["DivisionCode"] = req.DivisionCode + } + + commonResp, err := c.doRequest("GET", "/selection-products/"+req.ProductId+"/sale-info", query, nil) + if err != nil { + return nil, nil, err + } + if err := CheckResponse(commonResp); err != nil { + return commonResp, nil, err + } + + var data GetSelectionProductSaleInfoRespData + if err := parseData(commonResp, &data); err != nil { + return commonResp, nil, err + } + return commonResp, &data, nil +} + +// ============================================================ +// 接口6:ListSelectionProductSaleInfos - 批量查询商品销售信息 +// ============================================================ + +// ListSelectionProductSaleInfos 批量查询商品销售信息 +func (c *Client) ListSelectionProductSaleInfos(req *ListSelectionProductSaleInfosReq) (*CommonResponse, *ListSelectionProductSaleInfosRespData, error) { + commonResp, err := c.doRequest("POST", "/selection-products:batch-sale-info", nil, req) + if err != nil { + return nil, nil, err + } + if err := CheckResponse(commonResp); err != nil { + return commonResp, nil, err + } + + var data ListSelectionProductSaleInfosRespData + if err := parseData(commonResp, &data); err != nil { + return commonResp, nil, err + } + return commonResp, &data, nil +} + +// ============================================================ +// 接口7:ListSelectionSkuSaleInfos - 批量SKU销售信息 +// ============================================================ + +// ListSelectionSkuSaleInfos 批量查询SKU销售信息 +func (c *Client) ListSelectionSkuSaleInfos(req *ListSelectionSkuSaleInfosReq) (*CommonResponse, *ListSelectionSkuSaleInfosRespData, error) { + commonResp, err := c.doRequest("POST", "/selection-skus:batch-sale-info", nil, req) + if err != nil { + return nil, nil, err + } + if err := CheckResponse(commonResp); err != nil { + return commonResp, nil, err + } + + var data ListSelectionSkuSaleInfosRespData + if err := parseData(commonResp, &data); err != nil { + return commonResp, nil, err + } + return commonResp, &data, nil +} + +// ============================================================ +// 接口8:ListCategories - 查询类目列表 +// ============================================================ + +// ListCategories 查询类目列表 +// - parentCategoryId: 父类目ID,不传时查询一级类目 +func (c *Client) ListCategories(req *ListCategoriesReq) (*CommonResponse, *ListCategoriesRespData, error) { + query := make(map[string]string) + query["PurchaserId"] = req.PurchaserId + if req.ParentCategoryId != "" { + query["ParentCategoryId"] = req.ParentCategoryId + } + + commonResp, err := c.doRequest("GET", "/categories", query, nil) + if err != nil { + return nil, nil, err + } + if err := CheckResponse(commonResp); err != nil { + return commonResp, nil, err + } + + var data ListCategoriesRespData + if err := parseData(commonResp, &data); err != nil { + return commonResp, nil, err + } + return commonResp, &data, nil +} + +// ============================================================ +// 接口9:SearchProducts - 搜索选品池商品 +// ============================================================ + +// SearchProducts 搜索选品池商品 +func (c *Client) SearchProducts(req *SearchProductsReq) (*CommonResponse, *SearchProductsRespData, error) { + commonResp, err := c.doRequest("POST", "/selection-products:search", nil, req) + if err != nil { + return nil, nil, err + } + if err := CheckResponse(commonResp); err != nil { + return commonResp, nil, err + } + + var data SearchProductsRespData + if err := parseData(commonResp, &data); err != nil { + return commonResp, nil, err + } + return commonResp, &data, nil +} + +// ============================================================ +// 接口10:SelectionGroupAddProduct - 选品池商品入库 +// ============================================================ + +// SelectionGroupAddProduct 选品池商品入库 +func (c *Client) SelectionGroupAddProduct(req *SelectionGroupAddProductReq) (*CommonResponse, error) { + commonResp, err := c.doRequest("POST", "/selection-group/products:add", nil, req) + if err != nil { + return nil, err + } + if err := CheckResponse(commonResp); err != nil { + return commonResp, err + } + return commonResp, nil +} + +// ============================================================ +// 接口11:SelectionGroupRemoveProduct - 选品池商品出库 +// ============================================================ + +// SelectionGroupRemoveProduct 选品池商品出库 +func (c *Client) SelectionGroupRemoveProduct(req *SelectionGroupRemoveProductReq) (*CommonResponse, error) { + commonResp, err := c.doRequest("POST", "/selection-group/products:remove", nil, req) + if err != nil { + return nil, err + } + if err := CheckResponse(commonResp); err != nil { + return commonResp, err + } + return commonResp, nil +} + +// ============================================================ +// 接口12:RenderPurchaseOrder - 采购单渲染(下单预校验) +// ============================================================ + +// RenderPurchaseOrder 采购单渲染(下单预校验) +// 下单前必须调用,获取实时价格、校验商品是否可售 +func (c *Client) RenderPurchaseOrder(req *RenderPurchaseOrderReq) (*CommonResponse, *RenderPurchaseOrderRespData, error) { + commonResp, err := c.doRequest("POST", "/purchase-orders:render", nil, req) + if err != nil { + return nil, nil, err + } + if err := CheckResponse(commonResp); err != nil { + return commonResp, nil, err + } + + var data RenderPurchaseOrderRespData + if err := parseData(commonResp, &data); err != nil { + return commonResp, nil, err + } + return commonResp, &data, nil +} + +// ============================================================ +// 接口13:SplitPurchaseOrder - 采购单渲染并拆单 +// ============================================================ + +// SplitPurchaseOrder 采购单渲染并拆单 +// 返回拆成多份子单结构,用于前端展示,拆单结果用于创建采购单入参 +func (c *Client) SplitPurchaseOrder(req *SplitPurchaseOrderReq) (*CommonResponse, *SplitPurchaseOrderRespData, error) { + commonResp, err := c.doRequest("POST", "/purchase-orders:split-render", nil, req) + if err != nil { + return nil, nil, err + } + if err := CheckResponse(commonResp); err != nil { + return commonResp, nil, err + } + + var data SplitPurchaseOrderRespData + if err := parseData(commonResp, &data); err != nil { + return commonResp, nil, err + } + return commonResp, &data, nil +} + +// ============================================================ +// 接口14:CreatePurchaseOrder - 创建采购单【异步】 +// ============================================================ + +// CreatePurchaseOrder 创建采购单【异步】 +// 重要:接口只返回采购单号,不代表下单成功,必须等待回调通知,再查询订单接口 +func (c *Client) CreatePurchaseOrder(req *CreatePurchaseOrderReq) (*CommonResponse, *CreatePurchaseOrderRespData, error) { + commonResp, err := c.doRequest("POST", "/purchase-orders", nil, req) + if err != nil { + return nil, nil, err + } + if err := CheckResponse(commonResp); err != nil { + return commonResp, nil, err + } + + var data CreatePurchaseOrderRespData + if err := parseData(commonResp, &data); err != nil { + return commonResp, nil, err + } + return commonResp, &data, nil +} + +// ============================================================ +// 接口15:GetPurchaseOrderStatus - 获取采购单状态 +// ============================================================ + +// GetPurchaseOrderStatus 获取采购单状态 +// 状态枚举:INIT、PROCESS、SUCCESS、FAIL、CLOSED +func (c *Client) GetPurchaseOrderStatus(purchaseOrderId, purchaserId string) (*CommonResponse, *GetPurchaseOrderStatusRespData, error) { + query := make(map[string]string) + query["PurchaserId"] = purchaserId + + commonResp, err := c.doRequest("GET", "/purchase-orders/"+purchaseOrderId+"/status", query, nil) + if err != nil { + return nil, nil, err + } + if err := CheckResponse(commonResp); err != nil { + return commonResp, nil, err + } + + var data GetPurchaseOrderStatusRespData + if err := parseData(commonResp, &data); err != nil { + return commonResp, nil, err + } + return commonResp, &data, nil +} + +// ============================================================ +// 接口16:GetOrder - 获取订单详情 +// ============================================================ + +// GetOrder 获取订单详情 +func (c *Client) GetOrder(orderId, purchaserId string) (*CommonResponse, *GetOrderRespData, error) { + query := make(map[string]string) + query["PurchaserId"] = purchaserId + + commonResp, err := c.doRequest("GET", "/orders/"+orderId, query, nil) + if err != nil { + return nil, nil, err + } + if err := CheckResponse(commonResp); err != nil { + return commonResp, nil, err + } + + var data GetOrderRespData + if err := parseData(commonResp, &data); err != nil { + return commonResp, nil, err + } + return commonResp, &data, nil +} + +// ============================================================ +// 接口17:QueryOrders - 查询订单列表 +// ============================================================ + +// QueryOrders 查询订单列表 +func (c *Client) QueryOrders(req *QueryOrdersReq) (*CommonResponse, *QueryOrdersRespData, error) { + query := make(map[string]string) + query["PurchaserId"] = req.PurchaserId + if req.PurchaseOrderId != "" { + query["PurchaseOrderId"] = req.PurchaseOrderId + } + if req.PageNum > 0 { + query["PageNum"] = strconv.Itoa(req.PageNum) + } + if req.PageSize > 0 { + query["PageSize"] = strconv.Itoa(req.PageSize) + } + if req.StartTime != "" { + query["StartTime"] = req.StartTime + } + if req.EndTime != "" { + query["EndTime"] = req.EndTime + } + + commonResp, err := c.doRequest("GET", "/orders", query, nil) + if err != nil { + return nil, nil, err + } + if err := CheckResponse(commonResp); err != nil { + return commonResp, nil, err + } + + var data QueryOrdersRespData + if err := parseData(commonResp, &data); err != nil { + return commonResp, nil, err + } + return commonResp, &data, nil +} + +// ============================================================ +// 接口18:ListLogisticsOrders - 查询订单物流信息 +// ============================================================ + +// ListLogisticsOrders 查询订单物流信息 +func (c *Client) ListLogisticsOrders(orderId, purchaserId string) (*CommonResponse, *ListLogisticsOrdersRespData, error) { + query := make(map[string]string) + query["PurchaserId"] = purchaserId + + commonResp, err := c.doRequest("GET", "/orders/"+orderId+"/logistics", query, nil) + if err != nil { + return nil, nil, err + } + if err := CheckResponse(commonResp); err != nil { + return commonResp, nil, err + } + + var data ListLogisticsOrdersRespData + if err := parseData(commonResp, &data); err != nil { + return commonResp, nil, err + } + return commonResp, &data, nil +} + +// ============================================================ +// 接口19:ConfirmDisburse - 确认收货 +// ============================================================ + +// ConfirmDisburse 确认收货 +func (c *Client) ConfirmDisburse(orderId, purchaserId string) (*CommonResponse, error) { + body := map[string]string{ + "PurchaserId": purchaserId, + } + + commonResp, err := c.doRequest("POST", "/orders/"+orderId+":confirm-disburse", nil, body) + if err != nil { + return nil, err + } + if err := CheckResponse(commonResp); err != nil { + return commonResp, err + } + return commonResp, nil +} + +// ============================================================ +// 接口20:RenderRefundOrder - 售后渲染预校验 +// ============================================================ + +// RenderRefundOrder 售后渲染预校验 +func (c *Client) RenderRefundOrder(req *RenderRefundOrderReq) (*CommonResponse, *RenderRefundOrderRespData, error) { + commonResp, err := c.doRequest("POST", "/refund-orders:render", nil, req) + if err != nil { + return nil, nil, err + } + if err := CheckResponse(commonResp); err != nil { + return commonResp, nil, err + } + + var data RenderRefundOrderRespData + if err := parseData(commonResp, &data); err != nil { + return commonResp, nil, err + } + return commonResp, &data, nil +} + +// ============================================================ +// 接口21:CreateRefundOrder - 创建售后单 +// ============================================================ + +// CreateRefundOrder 创建售后单 +func (c *Client) CreateRefundOrder(req *CreateRefundOrderReq) (*CommonResponse, *CreateRefundOrderRespData, error) { + commonResp, err := c.doRequest("POST", "/refund-orders", nil, req) + if err != nil { + return nil, nil, err + } + if err := CheckResponse(commonResp); err != nil { + return commonResp, nil, err + } + + var data CreateRefundOrderRespData + if err := parseData(commonResp, &data); err != nil { + return commonResp, nil, err + } + return commonResp, &data, nil +} + +// ============================================================ +// 接口22:CancelRefundOrder - 取消售后单 +// ============================================================ + +// CancelRefundOrder 取消售后单 +func (c *Client) CancelRefundOrder(refundOrderId, purchaserId string) (*CommonResponse, error) { + body := map[string]string{ + "PurchaserId": purchaserId, + } + + commonResp, err := c.doRequest("POST", "/refund-orders/"+refundOrderId+":cancel", nil, body) + if err != nil { + return nil, err + } + if err := CheckResponse(commonResp); err != nil { + return commonResp, err + } + return commonResp, nil +} + +// ============================================================ +// 接口23:GetRefundOrder - 获取售后单详情 +// ============================================================ + +// GetRefundOrder 获取售后单详情 +func (c *Client) GetRefundOrder(refundOrderId, purchaserId string) (*CommonResponse, *GetRefundOrderRespData, error) { + query := make(map[string]string) + query["PurchaserId"] = purchaserId + + commonResp, err := c.doRequest("GET", "/refund-orders/"+refundOrderId, query, nil) + if err != nil { + return nil, nil, err + } + if err := CheckResponse(commonResp); err != nil { + return commonResp, nil, err + } + + var data GetRefundOrderRespData + if err := parseData(commonResp, &data); err != nil { + return commonResp, nil, err + } + return commonResp, &data, nil +} + +// ============================================================ +// 接口24:CreateGoodsShippingNotice - 回填退货物流运单 +// ============================================================ + +// CreateGoodsShippingNotice 回填退货物流运单 +func (c *Client) CreateGoodsShippingNotice(refundOrderId, purchaserId, logisticsCompany, trackingNumber string) (*CommonResponse, error) { + body := map[string]string{ + "PurchaserId": purchaserId, + "LogisticsCompany": logisticsCompany, + "TrackingNumber": trackingNumber, + } + + commonResp, err := c.doRequest("POST", "/refund-orders/"+refundOrderId+":fill-logistics", nil, body) + if err != nil { + return nil, err + } + if err := CheckResponse(commonResp); err != nil { + return commonResp, err + } + return commonResp, nil +} + +// ============================================================ +// 接口25:QueryChildDivisionCode - 查询子区域编码 +// ============================================================ + +// QueryChildDivisionCode 查询子区域编码 +// 不传返回省级;传入省返回市,传入市返回区,传入区返回乡镇(五级) +func (c *Client) QueryChildDivisionCode(parentDivisionCode string) (*CommonResponse, *QueryChildDivisionCodeRespData, error) { + query := make(map[string]string) + if parentDivisionCode != "" { + query["ParentDivisionCode"] = parentDivisionCode + } + + commonResp, err := c.doRequest("GET", "/divisions:children", query, nil) + if err != nil { + return nil, nil, err + } + if err := CheckResponse(commonResp); err != nil { + return commonResp, nil, err + } + + var data QueryChildDivisionCodeRespData + if err := parseData(commonResp, &data); err != nil { + return commonResp, nil, err + } + return commonResp, &data, nil +} \ No newline at end of file