1265 lines
41 KiB
Markdown
1265 lines
41 KiB
Markdown
我来分析文档,然后生成完整的 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
|
||
```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:"-"` // 采购单ID,Path参数
|
||
PurchaserId string `json:"PurchaserId"` // 采购方ID,Query参数
|
||
}
|
||
|
||
// 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:"-"` // 订单ID,Path参数
|
||
PurchaserId string `json:"PurchaserId"` // 采购方ID,Query参数
|
||
}
|
||
|
||
// 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:"-"` // 订单ID,Path参数
|
||
PurchaserId string `json:"PurchaserId"` // 采购方ID,Query参数
|
||
}
|
||
|
||
// 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:"-"` // 售后单ID,Path参数
|
||
PurchaserId string `json:"PurchaserId"` // 采购方ID,Query参数
|
||
}
|
||
|
||
// 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
|
||
```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
|
||
```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
|
||
```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
|
||
```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 |