sdk_LinkedMall-20260828093422/sdk_LinkedMall/generate.md

41 KiB
Raw Blame History

我来分析文档,然后生成完整的 SDK 代码。首先,文档提到 ROA 签名由 darabonba-openapi 客户端内部处理,因此不需要调用加密工具。让我直接生成所有文件。

// File: sdk_LinkedMall/go.mod

module sdk_LinkedMall

go 1.21

require (
	github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.10
	github.com/alibabacloud-go/tea/v2 v2.2.0
)

// File: sdk_LinkedMall/types.go

package sdk_LinkedMall

import "encoding/json"

// ============================================================
// 公共响应结构体
// ============================================================

// CommonResponse 是所有接口返回的统一外层包装
type CommonResponse struct {
	RequestId  string          `json:"RequestId"`
	Success    bool            `json:"Success"`
	Code       string          `json:"Code"`
	Message    string          `json:"Message"`
	SubCode    string          `json:"SubCode"`
	SubMessage string          `json:"SubMessage"`
	Data       json.RawMessage `json:"Data"`
}

// ============================================================
// 采购方店铺 (Purchaser Shop)
// ============================================================

// ListPurchaserShopsReq 分页获取采购方店铺列表的请求参数Query
type ListPurchaserShopsReq struct {
	PageNum  int `json:"PageNum,omitempty"`  // 页码默认1
	PageSize int `json:"PageSize,omitempty"` // 每页条数最大100
}

// ListPurchaserShopsRespData 分页获取采购方店铺列表的响应Data
type ListPurchaserShopsRespData struct {
	Total    int64               `json:"Total"`
	PageNum  int                 `json:"PageNum"`
	PageSize int                 `json:"PageSize"`
	ShopList []PurchaserShopItem `json:"ShopList"`
}

// PurchaserShopItem 采购方店铺信息
type PurchaserShopItem struct {
	ShopId      string `json:"ShopId"`
	PurchaserId string `json:"PurchaserId"`
	ShopName    string `json:"ShopName"`
	ShopStatus  string `json:"ShopStatus"`
}

// GetPurchaserShopRespData 获取单个采购店铺详情的响应Data
type GetPurchaserShopRespData struct {
	ShopId      string `json:"ShopId"`
	PurchaserId string `json:"PurchaserId"`
	ShopName    string `json:"ShopName"`
	ShopStatus  string `json:"ShopStatus"`
	ContactInfo string `json:"ContactInfo"`
}

// ============================================================
// 选品池商品 (Selection Product)
// ============================================================

// ListSelectionProductsReq 分页查询选品池商品列表的请求参数Query
type ListSelectionProductsReq struct {
	PurchaserId string `json:"PurchaserId"`           // 采购方ID必填
	PageNum     int    `json:"PageNum,omitempty"`     // 页码
	PageSize    int    `json:"PageSize,omitempty"`    // 每页条数最大100
}

// ListSelectionProductsRespData 分页查询选品池商品列表的响应Data
type ListSelectionProductsRespData struct {
	Total       int64                  `json:"Total"`
	PageNum     int                    `json:"PageNum"`
	PageSize    int                    `json:"PageSize"`
	ProductList []SelectionProductItem `json:"ProductList"`
}

// SelectionProductItem 选品池商品摘要信息
type SelectionProductItem struct {
	ProductId  string `json:"ProductId"`
	Title      string `json:"Title"`
	MainImage  string `json:"MainImage"`
	BrandName  string `json:"BrandName"`
	CategoryId string `json:"CategoryId"`
}

// GetSelectionProductRespData 查询选品池商品详情的响应Data
type GetSelectionProductRespData struct {
	ProductId     string             `json:"ProductId"`
	Title         string             `json:"Title"`
	MainImage     string             `json:"MainImage"`
	Images        []string           `json:"Images"`
	BrandName     string             `json:"BrandName"`
	CategoryId    string             `json:"CategoryId"`
	Desc          string             `json:"Desc"`
	SkuList       []SelectionSkuItem `json:"SkuList"`
	CanSale       bool               `json:"CanSale"`       // 传入divisionCode才有效该区域是否可售
	StockQuantity int64              `json:"StockQuantity"` // 总库存数量
}

// SelectionSkuItem SKU信息
type SelectionSkuItem struct {
	SkuId         string `json:"SkuId"`
	SkuSpec       string `json:"SkuSpec"`
	SalePrice     int64  `json:"SalePrice"`     // 单位分
	MarketPrice   int64  `json:"MarketPrice"`   // 单位分
	StockQuantity int64  `json:"StockQuantity"` // 库存数量
}

// SearchProductsReq 搜索选品池商品的请求Body
type SearchProductsReq struct {
	Keyword     string `json:"Keyword,omitempty"`     // 关键词
	CategoryId  string `json:"CategoryId,omitempty"`  // 类目ID
	PageNum     int    `json:"PageNum,omitempty"`     // 页码
	PageSize    int    `json:"PageSize,omitempty"`    // 每页条数
	PurchaserId string `json:"PurchaserId"`           // 采购方ID必填
}

// SearchProductsRespData 搜索选品池商品的响应Data
type SearchProductsRespData struct {
	Total       int64                  `json:"Total"`
	PageNum     int                    `json:"PageNum"`
	PageSize    int                    `json:"PageSize"`
	ProductList []SelectionProductItem `json:"ProductList"`
}

// ============================================================
// 类目 (Category)
// ============================================================

// ListCategoriesReq 查询类目列表的请求参数Query
type ListCategoriesReq struct {
	PurchaserId      string `json:"PurchaserId"`                // 采购方ID必填
	ParentCategoryId string `json:"ParentCategoryId,omitempty"` // 父类目ID不传查一级类目
}

// CategoryItem 类目信息
type CategoryItem struct {
	CategoryId   string `json:"CategoryId"`
	CategoryName string `json:"CategoryName"`
	ParentId     string `json:"ParentId"`
	Level        int    `json:"Level"`
}

// ListCategoriesRespData 查询类目列表的响应Data
type ListCategoriesRespData struct {
	CategoryList []CategoryItem `json:"CategoryList"`
}

// ============================================================
// 选品池入库/出库 (Selection Group)
// ============================================================

// SelectionGroupAddProductReq 选品池商品入库请求Body
type SelectionGroupAddProductReq struct {
	PurchaserId   string   `json:"PurchaserId"`   // 采购方ID必填
	ShopId        string   `json:"ShopId"`         // 店铺ID必填
	ProductIdList []string `json:"ProductIdList"`  // 商品ID列表必填
}

// SelectionGroupRemoveProductReq 选品池商品出库请求Body
type SelectionGroupRemoveProductReq struct {
	PurchaserId   string   `json:"PurchaserId"`   // 采购方ID必填
	ShopId        string   `json:"ShopId"`         // 店铺ID必填
	ProductIdList []string `json:"ProductIdList"`  // 商品ID列表必填
}

// ============================================================
// 采购单 (Purchase Order)
// ============================================================

// RenderPurchaseOrderReq 采购单渲染请求Body
type RenderPurchaseOrderReq struct {
	PurchaserId  string           `json:"PurchaserId"`  // 采购方ID
	ShopId       string           `json:"ShopId"`       // 店铺ID
	DivisionCode string           `json:"DivisionCode"` // 五级乡镇编码
	ItemList     []RenderOrderItem `json:"ItemList"`    // 商品列表
	ReceiverInfo ReceiverInfo     `json:"ReceiverInfo"` // 收货人信息
}

// RenderOrderItem 渲染采购单的商品条目
type RenderOrderItem struct {
	SkuId    string `json:"SkuId"`    // SKU ID
	Quantity int64  `json:"Quantity"` // 数量
}

// ReceiverInfo 收货人信息
type ReceiverInfo struct {
	ReceiverName  string `json:"ReceiverName"`  // 收货人姓名
	ReceiverPhone string `json:"ReceiverPhone"` // 收货人电话
	ProvinceCode  string `json:"ProvinceCode"`  // 省份编码
	CityCode      string `json:"CityCode"`      // 城市编码
	DistrictCode  string `json:"DistrictCode"`  // 区县编码
	TownCode      string `json:"TownCode"`      // 乡镇编码
	DetailAddress string `json:"DetailAddress"` // 详细地址
}

// RenderPurchaseOrderRespData 采购单渲染的响应Data
type RenderPurchaseOrderRespData struct {
	TotalAmount     int64                  `json:"TotalAmount"`     // 总金额,单位分
	TotalFreight    int64                  `json:"TotalFreight"`    // 总运费,单位分
	ItemValidResult []ItemValidResultItem  `json:"ItemValidResult"` // 商品校验结果
	RenderItemList  []RenderOrderItemResult `json:"RenderItemList"` // 渲染后的商品列表
}

// ItemValidResultItem 商品校验结果
type ItemValidResultItem struct {
	SkuId     string `json:"SkuId"`
	Valid     bool   `json:"Valid"`     // 是否有效
	Reason    string `json:"Reason"`    // 不可售原因
}

// RenderOrderItemResult 渲染后的商品条目
type RenderOrderItemResult struct {
	SkuId     string `json:"SkuId"`
	SalePrice int64  `json:"SalePrice"` // 实时售价,单位分
	Quantity  int64  `json:"Quantity"`
	SubTotal  int64  `json:"SubTotal"` // 小计,单位分
}

// SplitPurchaseOrderReq 采购单渲染并拆单的请求Body与RenderPurchaseOrderReq结构一致
type SplitPurchaseOrderReq = RenderPurchaseOrderReq

// SplitOrderItem 拆单后的子单
type SplitOrderItem struct {
	SubOrderId   string           `json:"SubOrderId"`   // 子单ID
	SkuId        string           `json:"SkuId"`
	Quantity     int64            `json:"Quantity"`
	SalePrice    int64            `json:"SalePrice"`    // 单位分
	SubTotal     int64            `json:"SubTotal"`     // 单位分
	Freight      int64            `json:"Freight"`      // 运费,单位分
}

// SplitPurchaseOrderRespData 采购单渲染并拆单的响应Data
type SplitPurchaseOrderRespData struct {
	TotalAmount    int64             `json:"TotalAmount"`    // 总金额,单位分
	TotalFreight   int64             `json:"TotalFreight"`   // 总运费,单位分
	SubOrderList   []SplitOrderItem  `json:"SubOrderList"`   // 子单列表
}

// CreatePurchaseOrderReq 创建采购单请求Body
type CreatePurchaseOrderReq struct {
	PurchaserId          string               `json:"PurchaserId"`          // 采购方ID
	ShopId               string               `json:"ShopId"`               // 店铺ID
	OuterPurchaseOrderId string               `json:"OuterPurchaseOrderId"` // 外部业务唯一单号,幂等
	DivisionCode         string               `json:"DivisionCode"`         // 五级乡镇编码
	ReceiverInfo         ReceiverInfo         `json:"ReceiverInfo"`         // 收货人信息
	SubOrderList         []CreateSubOrderItem `json:"SubOrderList"`         // 子单列表
}

// CreateSubOrderItem 创建采购单的子单条目
type CreateSubOrderItem struct {
	SkuId    string `json:"SkuId"`
	Quantity int64  `json:"Quantity"`
}

// CreatePurchaseOrderRespData 创建采购单的响应Data
type CreatePurchaseOrderRespData struct {
	PurchaseOrderId string `json:"PurchaseOrderId"` // 阿里云采购单号
}

// GetPurchaseOrderStatusReq 获取采购单状态的请求参数Query + Path
type GetPurchaseOrderStatusReq struct {
	PurchaseOrderId string `json:"-"`               // 采购单IDPath参数
	PurchaserId     string `json:"PurchaserId"`     // 采购方IDQuery参数
}

// GetPurchaseOrderStatusRespData 获取采购单状态的响应Data
type GetPurchaseOrderStatusRespData struct {
	PurchaseOrderId string `json:"PurchaseOrderId"`
	Status          string `json:"Status"` // INIT / PROCESS / SUCCESS / FAIL / CLOSED
}

// ============================================================
// 订单 (Order)
// ============================================================

// GetOrderReq 获取订单详情的请求参数
type GetOrderReq struct {
	OrderId     string `json:"-"`           // 订单IDPath参数
	PurchaserId string `json:"PurchaserId"` // 采购方IDQuery参数
}

// GetOrderRespData 获取订单详情的响应Data
type GetOrderRespData struct {
	OrderId         string            `json:"OrderId"`
	PurchaseOrderId string            `json:"PurchaseOrderId"`
	PurchaserId     string            `json:"PurchaserId"`
	ShopId          string            `json:"ShopId"`
	OrderStatus     string            `json:"OrderStatus"`
	TotalAmount     int64             `json:"TotalAmount"`     // 实付金额,单位分
	TotalFreight    int64             `json:"TotalFreight"`    // 运费,单位分
	ReceiverInfo    ReceiverInfo      `json:"ReceiverInfo"`
	OrderItemList   []OrderItemDetail `json:"OrderItemList"`
	CreateTime      string            `json:"CreateTime"`
	PayTime         string            `json:"PayTime"`
}

// OrderItemDetail 订单商品明细
type OrderItemDetail struct {
	OrderItemId    string `json:"OrderItemId"`
	SkuId          string `json:"SkuId"`
	ProductId      string `json:"ProductId"`
	ProductName    string `json:"ProductName"`
	Quantity       int64  `json:"Quantity"`
	SalePrice      int64  `json:"SalePrice"`      // 单位分
	SubTotal       int64  `json:"SubTotal"`       // 单位分
	ItemStatus     string `json:"ItemStatus"`
	RefundQuantity int64  `json:"RefundQuantity"`
}

// QueryOrdersReq 查询订单列表的请求参数Query
type QueryOrdersReq struct {
	PurchaserId      string `json:"PurchaserId"`                // 采购方ID必填
	PurchaseOrderId  string `json:"PurchaseOrderId,omitempty"`  // 采购单ID
	PageNum          int    `json:"PageNum,omitempty"`          // 页码
	PageSize         int    `json:"PageSize,omitempty"`         // 每页条数
	StartTime        string `json:"StartTime,omitempty"`        // 开始时间
	EndTime          string `json:"EndTime,omitempty"`          // 结束时间
}

// QueryOrdersRespData 查询订单列表的响应Data
type QueryOrdersRespData struct {
	Total     int64              `json:"Total"`
	PageNum   int                `json:"PageNum"`
	PageSize  int                `json:"PageSize"`
	OrderList []OrderSummaryItem `json:"OrderList"`
}

// OrderSummaryItem 订单摘要信息
type OrderSummaryItem struct {
	OrderId         string `json:"OrderId"`
	PurchaseOrderId string `json:"PurchaseOrderId"`
	OrderStatus     string `json:"OrderStatus"`
	TotalAmount     int64  `json:"TotalAmount"` // 单位分
	CreateTime      string `json:"CreateTime"`
	PayTime         string `json:"PayTime"`
}

// ============================================================
// 物流 (Logistics)
// ============================================================

// ListLogisticsOrdersReq 查询订单物流信息的请求参数
type ListLogisticsOrdersReq struct {
	OrderId     string `json:"-"`           // 订单IDPath参数
	PurchaserId string `json:"PurchaserId"` // 采购方IDQuery参数
}

// ListLogisticsOrdersRespData 查询订单物流信息的响应Data
type ListLogisticsOrdersRespData struct {
	LogisticsList []LogisticsInfo `json:"LogisticsList"`
}

// LogisticsInfo 物流信息
type LogisticsInfo struct {
	LogisticsCompany string         `json:"LogisticsCompany"` // 物流公司
	TrackingNumber   string         `json:"TrackingNumber"`   // 运单号
	Traces           []LogisticsTrace `json:"Traces"`         // 物流轨迹
}

// LogisticsTrace 物流轨迹
type LogisticsTrace struct {
	Time     string `json:"Time"`     // 轨迹时间
	Location string `json:"Location"` // 轨迹地点
	Action   string `json:"Action"`   // 轨迹描述
}

// ============================================================
// 确认收货 (Confirm Disburse)
// ============================================================

// ConfirmDisburseReq 确认收货的请求Body
type ConfirmDisburseReq struct {
	PurchaserId string `json:"PurchaserId"` // 采购方ID
}

// ============================================================
// 售后单 (Refund Order)
// ============================================================

// RenderRefundOrderReq 售后渲染预校验的请求Body
type RenderRefundOrderReq struct {
	PurchaserId   string `json:"PurchaserId"`   // 采购方ID
	OrderId       string `json:"OrderId"`       // 订单ID
	OrderItemId   string `json:"OrderItemId"`   // 订单商品明细ID
	RefundQuantity int64  `json:"RefundQuantity"` // 退款数量
	RefundType    string `json:"RefundType"`    // 退款类型(仅退款/退货退款)
}

// RenderRefundOrderRespData 售后渲染预校验的响应Data
type RenderRefundOrderRespData struct {
	Valid                 bool   `json:"Valid"`                 // 是否可售后
	MaxRefundQuantity     int64  `json:"MaxRefundQuantity"`     // 最大可退数量
	MaxRefundAmount       int64  `json:"MaxRefundAmount"`       // 最大可退金额,单位分
	RefundReason          string `json:"RefundReason"`          // 不可售原因
}

// CreateRefundOrderReq 创建售后单的请求Body
type CreateRefundOrderReq struct {
	PurchaserId   string `json:"PurchaserId"`   // 采购方ID
	OrderId       string `json:"OrderId"`       // 订单ID
	OrderItemId   string `json:"OrderItemId"`   // 订单商品明细ID
	RefundQuantity int64  `json:"RefundQuantity"` // 退款数量
	RefundAmount  int64  `json:"RefundAmount"`   // 退款金额,单位分
	RefundType    string `json:"RefundType"`     // 退款类型
	RefundReason  string `json:"RefundReason"`   // 退款原因
	OuterRefundNo string `json:"OuterRefundNo"`  // 外部售后单号
}

// CreateRefundOrderRespData 创建售后单的响应Data
type CreateRefundOrderRespData struct {
	RefundOrderId string `json:"RefundOrderId"` // 售后单ID
}

// CancelRefundOrderReq 取消售后单的请求Body
type CancelRefundOrderReq struct {
	PurchaserId string `json:"PurchaserId"` // 采购方ID
}

// CancelRefundOrderRespData 取消售后单的响应Data
type CancelRefundOrderRespData struct {
	RefundOrderId string `json:"RefundOrderId"`
	Status        string `json:"Status"`
}

// GetRefundOrderReq 获取售后单详情的请求参数
type GetRefundOrderReq struct {
	RefundOrderId string `json:"-"`           // 售后单IDPath参数
	PurchaserId   string `json:"PurchaserId"` // 采购方IDQuery参数
}

// GetRefundOrderRespData 获取售后单详情的响应Data
type GetRefundOrderRespData struct {
	RefundOrderId  string `json:"RefundOrderId"`
	OrderId        string `json:"OrderId"`
	OrderItemId    string `json:"OrderItemId"`
	PurchaserId    string `json:"PurchaserId"`
	RefundType     string `json:"RefundType"`
	RefundStatus   string `json:"RefundStatus"`
	RefundQuantity int64  `json:"RefundQuantity"`
	RefundAmount   int64  `json:"RefundAmount"`   // 单位分
	RefundReason   string `json:"RefundReason"`
	OuterRefundNo  string `json:"OuterRefundNo"`
	CreateTime     string `json:"CreateTime"`
}

// CreateGoodsShippingNoticeReq 回填退货物流运单的请求Body
type CreateGoodsShippingNoticeReq struct {
	PurchaserId     string `json:"PurchaserId"`     // 采购方ID
	LogisticsCompany string `json:"LogisticsCompany"` // 物流公司
	TrackingNumber  string `json:"TrackingNumber"`   // 运单号
}

// CreateGoodsShippingNoticeRespData 回填退货物流运单的响应Data
type CreateGoodsShippingNoticeRespData struct {
	Result bool `json:"Result"`
}

// ============================================================
// 区域编码 (Division Code)
// ============================================================

// QueryChildDivisionCodeReq 查询子区域编码的请求参数Query
type QueryChildDivisionCodeReq struct {
	ParentDivisionCode string `json:"ParentDivisionCode,omitempty"` // 父区域编码,不传返回省级
}

// DivisionInfo 区域编码信息
type DivisionInfo struct {
	DivisionCode string `json:"DivisionCode"` // 区域编码
	DivisionName string `json:"DivisionName"` // 区域名称
	Level        int    `json:"Level"`        // 层级1-省2-市3-区4-乡镇
	ParentCode   string `json:"ParentCode"`   // 父区域编码
}

// QueryChildDivisionCodeRespData 查询子区域编码的响应Data
type QueryChildDivisionCodeRespData struct {
	DivisionList []DivisionInfo `json:"DivisionList"`
}

// ============================================================
// 通用操作响应
// ============================================================

// OperationRespData 通用操作响应Data入库/出库/确认收货等)
type OperationRespData struct {
	Result bool `json:"Result"`
}

// File: sdk_LinkedMall/errors.go

package sdk_LinkedMall

import "fmt"

// APIError 表示API返回的业务错误
type APIError struct {
	Code       string `json:"Code"`       // 错误码
	Message    string `json:"Message"`    // 错误信息
	SubCode    string `json:"SubCode"`    // 子错误码
	SubMessage string `json:"SubMessage"` // 子错误信息
	RequestId  string `json:"RequestId"`  // 请求ID
}

func (e *APIError) Error() string {
	return fmt.Sprintf("linkedmall API error: code=%s, message=%s, subCode=%s, subMessage=%s, requestId=%s",
		e.Code, e.Message, e.SubCode, e.SubMessage, e.RequestId)
}

// IsSuccess 判断是否业务成功
func (e *APIError) IsSuccess() bool {
	return e.Code == "SUCCESS"
}

// 预定义错误码常量
const (
	ErrCodeShopTypeInvalid              = "ShopTypeInvalid"
	ErrCodeSkuPriceNotLatest            = "SkuPriceUnique"
	ErrCodePurchaseOrderNotFound        = "PurchaseOrderNotFound"
	ErrCodeRefundNumberExceed           = "RefundNumberMustLessThanOrder"
	ErrCodeRefundAmountExceed           = "RefundAmountMustLessThanOrder"
	ErrCodeNoPrivilege                  = "HasNoPrivilege"
	ErrCodeOrderNotFound                = "OrderNotFound"
	ErrCodeShopNotFound                 = "ShopNotFind"
	ErrCodeSavePurchaseOrderError       = "SavePurchaseOrderError"
	ErrCodeOuterPurchaseOrderIdExist    = "OuterPurchaseOrderIdExist"
)

// ErrResp 用于解析错误响应
type ErrResp struct {
	Code       string `json:"Code"`
	Message    string `json:"Message"`
	SubCode    string `json:"SubCode"`
	SubMessage string `json:"SubMessage"`
	RequestId  string `json:"RequestId"`
}

// File: sdk_LinkedMall/crypto.go

package sdk_LinkedMall

// 本文件预留用于加密相关功能。
//
// 当前SDK使用阿里云 darabonba-openapi 客户端发起ROA签名调用
// 签名过程由底层客户端自动处理,业务层无需实现签名算法。
//
// 如需使用国密SM2/SM3/SM4或其他加密算法可在此文件中添加实现。
// 建议使用 github.com/tjfoc/gmsm 库进行国密算法实现。
//
// 示例:
//   import "github.com/tjfoc/gmsm/sm3"
//   func SM3Hash(data []byte) []byte {
//       h := sm3.New()
//       h.Write(data)
//       return h.Sum(nil)
//   }

// File: sdk_LinkedMall/client.go

package sdk_LinkedMall

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"strconv"
	"strings"

	openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
	"github.com/alibabacloud-go/tea/v2"
)

const (
	defaultRegionId = "cn-zhangjiakou"
	defaultEndpoint = "linkedmall.cn-zhangjiakou.aliyuncs.com"
	basePath        = "/opensaas-s2b/opensaas-s2b-biz-trade/v2"
	readTimeout     = 30000
	connectTimeout  = 10000
)

// Client LinkedMall SDK 客户端
type Client struct {
	inner *openapi.Client
}

// NewClient 创建一个新的LinkedMall SDK客户端
//
// 使用RAM子账号的AccessKey初始化禁止使用主账号AK。
// 示例:
//
//	cli, err := NewClient("your-access-key-id", "your-access-key-secret")
//	if err != nil {
//	    panic(err)
//	}
func NewClient(accessKeyId, accessKeySecret string) (*Client, error) {
	config := &openapi.Config{
		AccessKeyId:     tea.String(accessKeyId),
		AccessKeySecret: tea.String(accessKeySecret),
		RegionId:        tea.String(defaultRegionId),
		Endpoint:        tea.String(defaultEndpoint),
		ReadTimeout:     tea.Int(readTimeout),
		ConnectTimeout:  tea.Int(connectTimeout),
	}
	c, err := openapi.NewClient(config)
	if err != nil {
		return nil, fmt.Errorf("failed to create openapi client: %w", err)
	}
	return &Client{inner: c}, nil
}

// buildPath 构建完整的请求路径
func buildPath(suffix string) string {
	return basePath + suffix
}

// toQueryMap 将结构体转为查询参数map
func toQueryMap(params interface{}) map[string]*string {
	result := make(map[string]*string)
	if params == nil {
		return result
	}

	// 使用json标签序列化后转为map
	data, _ := json.Marshal(params)
	var rawMap map[string]interface{}
	if err := json.Unmarshal(data, &rawMap); err != nil {
		return result
	}

	for k, v := range rawMap {
		switch val := v.(type) {
		case string:
			if val != "" {
				result[k] = tea.String(val)
			}
		case float64:
			if val != 0 {
				result[k] = tea.String(strconv.FormatInt(int64(val), 10))
			}
		case bool:
			result[k] = tea.String(strconv.FormatBool(val))
		default:
			// 忽略复杂类型
		}
	}
	return result
}

// doRequest 执行HTTP请求并返回响应体字节
func (c *Client) doRequest(method, path string, query map[string]*string, body interface{}) ([]byte, error) {
	resp, err := c.inner.RoaRequest(
		tea.String(method),
		tea.String(path),
		query,
		body,
		nil,
	)
	if err != nil {
		return nil, fmt.Errorf("roa request failed: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		bodyBytes, _ := io.ReadAll(resp.Body)
		return nil, fmt.Errorf("unexpected http status %d, body: %s", resp.StatusCode, string(bodyBytes))
	}

	return io.ReadAll(resp.Body)
}

// parseResponse 解析通用响应,如果业务失败返回 *APIError
func (c *Client) parseResponse(data []byte, target interface{}) error {
	var commonResp CommonResponse
	if err := json.Unmarshal(data, &commonResp); err != nil {
		return fmt.Errorf("failed to parse common response: %w, body: %s", err, string(data))
	}

	if !commonResp.Success {
		return &APIError{
			Code:       commonResp.Code,
			Message:    commonResp.Message,
			SubCode:    commonResp.SubCode,
			SubMessage: commonResp.SubMessage,
			RequestId:  commonResp.RequestId,
		}
	}

	if target != nil && len(commonResp.Data) > 0 {
		if err := json.Unmarshal(commonResp.Data, target); err != nil {
			return fmt.Errorf("failed to parse data field: %w, data: %s", err, string(commonResp.Data))
		}
	}
	return nil
}

// ============================================================
// 采购方店铺 (Purchaser Shop)
// ============================================================

// ListPurchaserShops 分页获取采购方店铺列表
func (c *Client) ListPurchaserShops(req *ListPurchaserShopsReq) (*ListPurchaserShopsRespData, error) {
	path := buildPath("/purchaser-shops")
	query := toQueryMap(req)

	data, err := c.doRequest("GET", path, query, nil)
	if err != nil {
		return nil, err
	}

	var result ListPurchaserShopsRespData
	if err := c.parseResponse(data, &result); err != nil {
		return nil, err
	}
	return &result, nil
}

// GetPurchaserShop 获取单个采购店铺详情
func (c *Client) GetPurchaserShop(shopId string) (*GetPurchaserShopRespData, error) {
	path := buildPath("/purchaser-shops/" + shopId)

	data, err := c.doRequest("GET", path, nil, nil)
	if err != nil {
		return nil, err
	}

	var result GetPurchaserShopRespData
	if err := c.parseResponse(data, &result); err != nil {
		return nil, err
	}
	return &result, nil
}

// ============================================================
// 选品池商品 (Selection Product)
// ============================================================

// ListSelectionProducts 分页查询选品池商品列表
func (c *Client) ListSelectionProducts(req *ListSelectionProductsReq) (*ListSelectionProductsRespData, error) {
	path := buildPath("/selection-products")
	query := toQueryMap(req)

	data, err := c.doRequest("GET", path, query, nil)
	if err != nil {
		return nil, err
	}

	var result ListSelectionProductsRespData
	if err := c.parseResponse(data, &result); err != nil {
		return nil, err
	}
	return &result, nil
}

// GetSelectionProduct 查询选品池商品详情
//
// divisionCode 为可选参数,传入五级乡镇区域编码后可返回该区域可售状态和库存。
func (c *Client) GetSelectionProduct(productId, purchaserId, divisionCode string) (*GetSelectionProductRespData, error) {
	path := buildPath("/selection-products/" + productId)
	query := map[string]*string{
		"PurchaserId": tea.String(purchaserId),
	}
	if divisionCode != "" {
		query["DivisionCode"] = tea.String(divisionCode)
	}

	data, err := c.doRequest("GET", path, query, nil)
	if err != nil {
		return nil, err
	}

	var result GetSelectionProductRespData
	if err := c.parseResponse(data, &result); err != nil {
		return nil, err
	}
	return &result, nil
}

// ListCategories 查询类目列表
func (c *Client) ListCategories(req *ListCategoriesReq) (*ListCategoriesRespData, error) {
	path := buildPath("/categories")
	query := toQueryMap(req)

	data, err := c.doRequest("GET", path, query, nil)
	if err != nil {
		return nil, err
	}

	var result ListCategoriesRespData
	if err := c.parseResponse(data, &result); err != nil {
		return nil, err
	}
	return &result, nil
}

// SearchProducts 搜索选品池商品
func (c *Client) SearchProducts(req *SearchProductsReq) (*SearchProductsRespData, error) {
	path := buildPath("/selection-products:search")

	data, err := c.doRequest("POST", path, nil, req)
	if err != nil {
		return nil, err
	}

	var result SearchProductsRespData
	if err := c.parseResponse(data, &result); err != nil {
		return nil, err
	}
	return &result, nil
}

// ============================================================
// 选品池入库/出库
// ============================================================

// SelectionGroupAddProduct 选品池商品入库
func (c *Client) SelectionGroupAddProduct(req *SelectionGroupAddProductReq) (*OperationRespData, error) {
	path := buildPath("/selection-group/products:add")

	data, err := c.doRequest("POST", path, nil, req)
	if err != nil {
		return nil, err
	}

	var result OperationRespData
	if err := c.parseResponse(data, &result); err != nil {
		return nil, err
	}
	return &result, nil
}

// SelectionGroupRemoveProduct 选品池商品出库
func (c *Client) SelectionGroupRemoveProduct(req *SelectionGroupRemoveProductReq) (*OperationRespData, error) {
	path := buildPath("/selection-group/products:remove")

	data, err := c.doRequest("POST", path, nil, req)
	if err != nil {
		return nil, err
	}

	var result OperationRespData
	if err := c.parseResponse(data, &result); err != nil {
		return nil, err
	}
	return &result, nil
}

// ============================================================
// 采购单 (Purchase Order)
// ============================================================

// RenderPurchaseOrder 采购单渲染(下单预校验)
//
// 下单前必须调用,获取实时价格、校验商品是否可售。
func (c *Client) RenderPurchaseOrder(req *RenderPurchaseOrderReq) (*RenderPurchaseOrderRespData, error) {
	path := buildPath("/purchase-orders:render")

	data, err := c.doRequest("POST", path, nil, req)
	if err != nil {
		return nil, err
	}

	var result RenderPurchaseOrderRespData
	if err := c.parseResponse(data, &result); err != nil {
		return nil, err
	}
	return &result, nil
}

// SplitPurchaseOrder 采购单渲染并拆单
//
// 返回拆成多份子单结构,用于前端展示,拆单结果用于创建采购单入参。
func (c *Client) SplitPurchaseOrder(req *SplitPurchaseOrderReq) (*SplitPurchaseOrderRespData, error) {
	path := buildPath("/purchase-orders:split-render")

	data, err := c.doRequest("POST", path, nil, req)
	if err != nil {
		return nil, err
	}

	var result SplitPurchaseOrderRespData
	if err := c.parseResponse(data, &result); err != nil {
		return nil, err
	}
	return &result, nil
}

// CreatePurchaseOrder 创建采购单【异步】
//
// 重要:接口只返回采购单号,不代表下单成功,必须等待回调通知,再查询订单接口。
// 禁止在同步返回后直接标记本地订单成功。
func (c *Client) CreatePurchaseOrder(req *CreatePurchaseOrderReq) (*CreatePurchaseOrderRespData, error) {
	path := buildPath("/purchase-orders")

	data, err := c.doRequest("POST", path, nil, req)
	if err != nil {
		return nil, err
	}

	var result CreatePurchaseOrderRespData
	if err := c.parseResponse(data, &result); err != nil {
		return nil, err
	}
	return &result, nil
}

// GetPurchaseOrderStatus 获取采购单状态
//
// 状态枚举INIT初始化、PROCESS处理中、SUCCESS成功、FAIL失败、CLOSED已关闭
func (c *Client) GetPurchaseOrderStatus(purchaseOrderId, purchaserId string) (*GetPurchaseOrderStatusRespData, error) {
	path := buildPath("/purchase-orders/" + purchaseOrderId + "/status")
	query := map[string]*string{
		"PurchaserId": tea.String(purchaserId),
	}

	data, err := c.doRequest("GET", path, query, nil)
	if err != nil {
		return nil, err
	}

	var result GetPurchaseOrderStatusRespData
	if err := c.parseResponse(data, &result); err != nil {
		return nil, err
	}
	return &result, nil
}

// ============================================================
// 订单 (Order)
// ============================================================

// GetOrder 获取订单详情
func (c *Client) GetOrder(orderId, purchaserId string) (*GetOrderRespData, error) {
	path := buildPath("/orders/" + orderId)
	query := map[string]*string{
		"PurchaserId": tea.String(purchaserId),
	}

	data, err := c.doRequest("GET", path, query, nil)
	if err != nil {
		return nil, err
	}

	var result GetOrderRespData
	if err := c.parseResponse(data, &result); err != nil {
		return nil, err
	}
	return &result, nil
}

// QueryOrders 查询订单列表
func (c *Client) QueryOrders(req *QueryOrdersReq) (*QueryOrdersRespData, error) {
	path := buildPath("/orders")
	query := toQueryMap(req)

	data, err := c.doRequest("GET", path, query, nil)
	if err != nil {
		return nil, err
	}

	var result QueryOrdersRespData
	if err := c.parseResponse(data, &result); err != nil {
		return nil, err
	}
	return &result, nil
}

// ListLogisticsOrders 查询订单物流信息
func (c *Client) ListLogisticsOrders(orderId, purchaserId string) (*ListLogisticsOrdersRespData, error) {
	path := buildPath("/orders/" + orderId + "/logistics")
	query := map[string]*string{
		"PurchaserId": tea.String(purchaserId),
	}

	data, err := c.doRequest("GET", path, query, nil)
	if err != nil {
		return nil, err
	}

	var result ListLogisticsOrdersRespData
	if err := c.parseResponse(data, &result); err != nil {
		return nil, err
	}
	return &result, nil
}

// ConfirmDisburse 确认收货
func (c *Client) ConfirmDisburse(orderId, purchaserId string) (*OperationRespData, error) {
	path := buildPath("/orders/" + orderId + ":confirm-disburse")
	body := map[string]*string{
		"PurchaserId": tea.String(purchaserId),
	}

	data, err := c.doRequest("POST", path, nil, body)
	if err != nil {
		return nil, err
	}

	var result OperationRespData
	if err := c.parseResponse(data, &result); err != nil {
		return nil, err
	}
	return &result, nil
}

// ============================================================
// 售后单 (Refund Order)
// ============================================================

// RenderRefundOrder 售后渲染预校验
func (c *Client) RenderRefundOrder(req *RenderRefundOrderReq) (*RenderRefundOrderRespData, error) {
	path := buildPath("/refund-orders:render")

	data, err := c.doRequest("POST", path, nil, req)
	if err != nil {
		return nil, err
	}

	var result RenderRefundOrderRespData
	if err := c.parseResponse(data, &result); err != nil {
		return nil, err
	}
	return &result, nil
}

// CreateRefundOrder 创建售后单
func (c *Client) CreateRefundOrder(req *CreateRefundOrderReq) (*CreateRefundOrderRespData, error) {
	path := buildPath("/refund-orders")

	data, err := c.doRequest("POST", path, nil, req)
	if err != nil {
		return nil, err
	}

	var result CreateRefundOrderRespData
	if err := c.parseResponse(data, &result); err != nil {
		return nil, err
	}
	return &result, nil
}

// CancelRefundOrder 取消售后单
func (c *Client) CancelRefundOrder(refundOrderId, purchaserId string) (*CancelRefundOrderRespData, error) {
	path := buildPath("/refund-orders/" + refundOrderId + ":cancel")
	body := map[string]*string{
		"PurchaserId": tea.String(purchaserId),
	}

	data, err := c.doRequest("POST", path, nil, body)
	if err != nil {
		return nil, err
	}

	var result CancelRefundOrderRespData
	if err := c.parseResponse(data, &result); err != nil {
		return nil, err
	}
	return &result, nil
}

// GetRefundOrder 获取售后单详情
func (c *Client) GetRefundOrder(refundOrderId, purchaserId string) (*GetRefundOrderRespData, error) {
	path := buildPath("/refund-orders/" + refundOrderId)
	query := map[string]*string{
		"PurchaserId": tea.String(purchaserId),
	}

	data, err := c.doRequest("GET", path, query, nil)
	if err != nil {
		return nil, err
	}

	var result GetRefundOrderRespData
	if err := c.parseResponse(data, &result); err != nil {
		return nil, err
	}
	return &result, nil
}

// CreateGoodsShippingNotice 回填退货物流运单
func (c *Client) CreateGoodsShippingNotice(refundOrderId string, req *CreateGoodsShippingNoticeReq) (*CreateGoodsShippingNoticeRespData, error) {
	path := buildPath("/refund-orders/" + refundOrderId + ":fill-logistics")

	data, err := c.doRequest("POST", path, nil, req)
	if err != nil {
		return nil, err
	}

	var result CreateGoodsShippingNoticeRespData
	if err := c.parseResponse(data, &result); err != nil {
		return nil, err
	}
	return &result, nil
}

// ============================================================
// 区域编码 (Division Code)
// ============================================================

// QueryChildDivisionCode 查询子区域编码
//
// 不传ParentDivisionCode返回省级编码
// 传入省返回市,传入市返回区,传入区返回乡镇(五级)。
// 下单、商品可售校验必须拿到乡镇级DivisionCode。
func (c *Client) QueryChildDivisionCode(parentDivisionCode string) (*QueryChildDivisionCodeRespData, error) {
	path := buildPath("/divisions:children")
	var query map[string]*string
	if parentDivisionCode != "" {
		query = map[string]*string{
			"ParentDivisionCode": tea.String(parentDivisionCode),
		}
	}

	data, err := c.doRequest("GET", path, query, nil)
	if err != nil {
		return nil, err
	}

	var result QueryChildDivisionCodeRespData
	if err := c.parseResponse(data, &result); err != nil {
		return nil, err
	}
	return &result, nil
}

// ============================================================
// 回调解析工具
// ============================================================

// CallbackEvent 回调通知事件结构体
type CallbackEvent struct {
	EventCode       string   `json:"EventCode"`       // 事件类型
	PurchaseOrderId string   `json:"PurchaseOrderId"` // 采购单ID
	OrderIdList     []string `json:"OrderIdList"`     // 附属真实订单ID数组
	Status          string   `json:"Status"`          // 状态
	RequestId       string   `json:"RequestId"`       // 请求ID
}

// ParseCallbackEvent 解析回调通知的JSON Body
//
// 业务侧在回调接口中接收阿里云POST请求解析事件后做本地状态同步。
// 处理完成后需返回 {"success":true} 告知阿里云消费成功。
func ParseCallbackEvent(body []byte) (*CallbackEvent, error) {
	var event CallbackEvent
	if err := json.Unmarshal(body, &event); err != nil {
		return nil, fmt.Errorf("failed to parse callback event: %w", err)
	}
	return &event, nil
}

// CallbackSuccessResponse 回调成功响应
//
// 业务处理完回调事件后,返回此结构告知阿里云消费成功。
func CallbackSuccessResponse() string {
	return `{"success":true}`
}

// IsAPIError 判断错误是否为指定错误码
func IsAPIError(err error, code string) bool {
	if apiErr, ok := err.(*APIError); ok {
		return apiErr.Code == code
	}
	return false
}

// ============================================================
// 辅助函数
// ============================================================

// ToQueryString 将结构体转为URL查询字符串仅用于调试
func ToQueryString(params interface{}) string {
	query := toQueryMap(params)
	if len(query) == 0 {
		return ""
	}
	var parts []string
	for k, v := range query {
		if v != nil {
			parts = append(parts, k+"="+*v)
		}
	}
	return strings.Join(parts, "&")
}

// File: sdk_LinkedMall/example_test.go

package sdk_LinkedMall

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"
)

// 本文件包含SDK使用示例
// 运行方式: go test -v -run Example

// ExampleNewClient 演示如何创建客户端
func ExampleNewClient() {
	// 从环境变量获取AK禁止硬编码
	accessKeyId := os.Getenv("LINKEDMALL_AK_ID")
	accessKeySecret := os.Getenv("LINKEDMALL_AK_SECRET")

	cli, err := NewClient(accessKeyId, accessKeySecret)
	if err != nil {
		log.Fatalf("failed to create client: %v", err)
	}
	_ = cli
	fmt.Println("client created successfully")
	// Output: client created successfully
}

// ExampleClient_ListPurchaserShops 演示分页获取采购方店铺列表
func ExampleClient_ListPurchaserShops() {
	cli := createTestClient()

	req := &ListPurchaserShopsReq{
		PageNum:  1,
		PageSize: 20,
	}
	resp, err := cli.ListPurchaserShops(req)
	if err != nil {
		if apiErr, ok := err.(*APIError); ok {
			log.Printf("API error: code=%s, message=%s", apiErr.Code, apiErr.Message)
		}
		log.Fatalf("failed to list purchaser shops: %v", err)
	}
	fmt.Printf("total shops: %d, page: %d/%d\n", resp.Total, resp.PageNum, resp.PageSize)
	for _, shop := range resp.ShopList {
		fmt.Printf("  shopId=%s, shopName=%s, status=%s\n", shop.ShopId, shop.ShopName, shop.ShopStatus)
	}
}

// ExampleClient_GetPurchaserShop 演示获取单个采购店铺详情
func ExampleClient_GetPurchaserShop() {
	cli := createTestClient()

	resp, err := cli.GetPurchaserShop("shopId123")
	if err != nil {
		log.Fatalf("failed to get purchaser shop: %v", err)
	}
	fmt.Printf("shop: %s (%s), contact: %s\n", resp.ShopName, resp.ShopId, resp.ContactInfo)
}

// ExampleClient_ListSelectionProducts 演示分页查询选品池商品列表
func ExampleClient