sever_tb_LinkedMall-2026082.../sever_tb_LinkedMall/valid.md

60 KiB
Raw Permalink Blame History

根据文档分析该API使用阿里云Darabonba OpenAPI SDK进行ROA签名调用SDK内部自动处理签名无需额外加密工具。我将直接生成所有代码文件。


// File: server_tb_LinkedMall/go.mod

module server_tb_LinkedMall

go 1.26

require (
	github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.10
	github.com/alibabacloud-go/tea/v2 v2.2.8
	github.com/gofiber/fiber/v2 v2.52.5
	github.com/google/uuid v1.6.0
	github.com/json-iterator/go v1.1.12
)

require (
	github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 // indirect
	github.com/alibabacloud-go/debug v1.0.1 // indirect
	github.com/alibabacloud-go/openapi-util v0.1.1 // indirect
	github.com/andybalholm/brotli v1.1.1 // indirect
	github.com/json-iterator/go v1.1.12 // indirect
	github.com/klauspost/compress v1.17.11 // indirect
	github.com/mattn/go-colorable v0.1.14 // indirect
	github.com/mattn/go-isatty v0.0.20 // indirect
	github.com/mattn/go-runewidth v0.0.16 // indirect
	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
	github.com/modern-go/reflect2 v1.0.2 // indirect
	github.com/rivo/uniseg v0.4.7 // indirect
	github.com/valyala/bytebufferpool v1.0.0 // indirect
	github.com/valyala/fasthttp v1.57.0 // indirect
	github.com/valyala/tcplisten v1.0.0 // indirect
	golang.org/x/sys v0.28.0 // indirect
)

// File: server_tb_LinkedMall/pkg/crypto/crypto.go

package crypto

import (
	"crypto/rand"
	"encoding/hex"
	"fmt"
	"time"
)

// GenerateNonce 生成随机字符串,用于防重放
func GenerateNonce() string {
	buf := make([]byte, 16)
	_, _ = rand.Read(buf)
	return hex.EncodeToString(buf)
}

// GenerateTimestamp 生成当前时间戳(毫秒)
func GenerateTimestamp() int64 {
	return time.Now().UnixMilli()
}

// FormatTimestamp 格式化时间戳为字符串
func FormatTimestamp(ts int64) string {
	return fmt.Sprintf("%d", ts)
}

// File: server_tb_LinkedMall/internal/config/config.go

package config

import (
	"os"
)

// Config 应用配置
type Config struct {
	ServerPort          string
	AccessKeyId         string
	AccessKeySecret     string
	RegionId            string
	Endpoint            string
	BasePath            string
	DefaultPurchaserId  string
	CallbackURL         string
}

// LoadConfig 从环境变量加载配置
func LoadConfig() *Config {
	return &Config{
		ServerPort:         getEnv("SERVER_PORT", "8080"),
		AccessKeyId:        getEnv("LINKEDMALL_AK", ""),
		AccessKeySecret:    getEnv("LINKEDMALL_SK", ""),
		RegionId:           getEnv("LINKEDMALL_REGION_ID", "cn-zhangjiakou"),
		Endpoint:           getEnv("LINKEDMALL_ENDPOINT", "linkedmall.cn-zhangjiakou.aliyuncs.com"),
		BasePath:           getEnv("LINKEDMALL_BASE_PATH", "/opensaas-s2b/opensaas-s2b-biz-trade/v2"),
		DefaultPurchaserId: getEnv("LINKEDMALL_PURCHASER_ID", ""),
		CallbackURL:        getEnv("LINKEDMALL_CALLBACK_URL", ""),
	}
}

func getEnv(key, fallback string) string {
	if v := os.Getenv(key); v != "" {
		return v
	}
	return fallback
}

// File: server_tb_LinkedMall/internal/entities/request.go

package entities

// ============================================================
// 通用请求结构
// ============================================================

// PaginationReq 分页请求公共参数
type PaginationReq struct {
	PageNum  int `json:"PageNum" query:"PageNum"`
	PageSize int `json:"PageSize" query:"PageSize"`
}

// PurchaserQuery 采购方ID查询参数
type PurchaserQuery struct {
	PurchaserId string `json:"PurchaserId" query:"PurchaserId"`
}

// ============================================================
// 接口 1: ListPurchaserShops
// ============================================================
type ListPurchaserShopsReq struct {
	PageNum  int `json:"PageNum" query:"PageNum"`
	PageSize int `json:"PageSize" query:"PageSize"`
}

// ============================================================
// 接口 2: GetPurchaserShop
// ============================================================
type GetPurchaserShopReq struct {
	ShopId string `json:"ShopId" params:"ShopId"`
}

// ============================================================
// 接口 3: ListSelectionProducts
// ============================================================
type ListSelectionProductsReq struct {
	PageNum     int    `json:"PageNum" query:"PageNum"`
	PageSize    int    `json:"PageSize" query:"PageSize"`
	PurchaserId string `json:"PurchaserId" query:"PurchaserId"`
}

// ============================================================
// 接口 4: GetSelectionProduct
// ============================================================
type GetSelectionProductReq struct {
	ProductId    string `json:"ProductId" params:"ProductId"`
	PurchaserId  string `json:"PurchaserId" query:"PurchaserId"`
	DivisionCode string `json:"DivisionCode" query:"DivisionCode"`
}

// ============================================================
// 接口 5: GetSelectionProductSaleInfo
// ============================================================
type GetSelectionProductSaleInfoReq struct {
	ProductId    string `json:"ProductId" params:"ProductId"`
	PurchaserId  string `json:"PurchaserId" query:"PurchaserId"`
	DivisionCode string `json:"DivisionCode" query:"DivisionCode"`
}

// ============================================================
// 接口 6: ListSelectionProductSaleInfos
// ============================================================
type ListSelectionProductSaleInfosReq struct {
	PurchaserId   string   `json:"PurchaserId"`
	ProductIdList []string `json:"ProductIdList"`
	DivisionCode  string   `json:"DivisionCode"`
}

// ============================================================
// 接口 7: ListSelectionSkuSaleInfos
// ============================================================
type ListSelectionSkuSaleInfosReq struct {
	PurchaserId  string   `json:"PurchaserId"`
	SkuIdList    []string `json:"SkuIdList"`
	DivisionCode string   `json:"DivisionCode"`
}

// ============================================================
// 接口 8: ListCategories
// ============================================================
type ListCategoriesReq struct {
	PurchaserId      string `json:"PurchaserId" query:"PurchaserId"`
	ParentCategoryId string `json:"ParentCategoryId" query:"ParentCategoryId"`
}

// ============================================================
// 接口 9: SearchProducts
// ============================================================
type SearchProductsReq struct {
	Keyword     string `json:"Keyword"`
	CategoryId  string `json:"CategoryId"`
	PageNum     int    `json:"PageNum"`
	PageSize    int    `json:"PageSize"`
	PurchaserId string `json:"PurchaserId"`
}

// ============================================================
// 接口 10: SelectionGroupAddProduct
// ============================================================
type SelectionGroupAddProductReq struct {
	PurchaserId   string   `json:"PurchaserId"`
	ShopId        string   `json:"ShopId"`
	ProductIdList []string `json:"ProductIdList"`
}

// ============================================================
// 接口 11: SelectionGroupRemoveProduct
// ============================================================
type SelectionGroupRemoveProductReq struct {
	PurchaserId   string   `json:"PurchaserId"`
	ShopId        string   `json:"ShopId"`
	ProductIdList []string `json:"ProductIdList"`
}

// ============================================================
// 接口 12: RenderPurchaseOrder
// ============================================================
type RenderPurchaseOrderReq struct {
	PurchaserId  string            `json:"PurchaserId"`
	ShopId       string            `json:"ShopId"`
	DivisionCode string            `json:"DivisionCode"`
	ItemList     []RenderOrderItem `json:"ItemList"`
	ReceiverInfo ReceiverInfo      `json:"ReceiverInfo"`
}

type RenderOrderItem struct {
	SkuId    string `json:"SkuId"`
	Quantity int64  `json:"Quantity"`
}

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"`
}

// ============================================================
// 接口 13: SplitPurchaseOrder
// ============================================================
type SplitPurchaseOrderReq struct {
	PurchaserId  string            `json:"PurchaserId"`
	ShopId       string            `json:"ShopId"`
	DivisionCode string            `json:"DivisionCode"`
	ItemList     []RenderOrderItem `json:"ItemList"`
	ReceiverInfo ReceiverInfo      `json:"ReceiverInfo"`
}

// ============================================================
// 接口 14: CreatePurchaseOrder
// ============================================================
type CreatePurchaseOrderReq struct {
	PurchaserId          string              `json:"PurchaserId"`
	ShopId               string              `json:"ShopId"`
	OuterPurchaseOrderId string              `json:"OuterPurchaseOrderId"`
	DivisionCode         string              `json:"DivisionCode"`
	ReceiverInfo         ReceiverInfo        `json:"ReceiverInfo"`
	SubOrderList         []CreateSubOrderItem `json:"SubOrderList"`
}

type CreateSubOrderItem struct {
	SkuId    string `json:"SkuId"`
	Quantity int64  `json:"Quantity"`
}

// ============================================================
// 接口 15: GetPurchaseOrderStatus
// ============================================================
type GetPurchaseOrderStatusReq struct {
	PurchaseOrderId string `json:"PurchaseOrderId" params:"PurchaseOrderId"`
	PurchaserId     string `json:"PurchaserId" query:"PurchaserId"`
}

// ============================================================
// 接口 16: GetOrder
// ============================================================
type GetOrderReq struct {
	OrderId     string `json:"OrderId" params:"OrderId"`
	PurchaserId string `json:"PurchaserId" query:"PurchaserId"`
}

// ============================================================
// 接口 17: QueryOrders
// ============================================================
type QueryOrdersReq struct {
	PurchaserId     string `json:"PurchaserId" query:"PurchaserId"`
	PurchaseOrderId string `json:"PurchaseOrderId" query:"PurchaseOrderId"`
	PageNum         int    `json:"PageNum" query:"PageNum"`
	PageSize        int    `json:"PageSize" query:"PageSize"`
	StartTime       string `json:"StartTime" query:"StartTime"`
	EndTime         string `json:"EndTime" query:"EndTime"`
}

// ============================================================
// 接口 18: ListLogisticsOrders
// ============================================================
type ListLogisticsOrdersReq struct {
	OrderId     string `json:"OrderId" params:"OrderId"`
	PurchaserId string `json:"PurchaserId" query:"PurchaserId"`
}

// ============================================================
// 接口 19: ConfirmDisburse
// ============================================================
type ConfirmDisburseReq struct {
	OrderId     string `json:"OrderId" params:"OrderId"`
	PurchaserId string `json:"PurchaserId"`
}

// ============================================================
// 接口 20: RenderRefundOrder
// ============================================================
type RenderRefundOrderReq struct {
	PurchaserId    string `json:"PurchaserId"`
	OrderId        string `json:"OrderId"`
	OrderItemId    string `json:"OrderItemId"`
	RefundQuantity int64  `json:"RefundQuantity"`
	RefundType     string `json:"RefundType"`
}

// ============================================================
// 接口 21: CreateRefundOrder
// ============================================================
type CreateRefundOrderReq struct {
	PurchaserId    string `json:"PurchaserId"`
	OrderId        string `json:"OrderId"`
	OrderItemId    string `json:"OrderItemId"`
	RefundQuantity int64  `json:"RefundQuantity"`
	RefundAmount   int64  `json:"RefundAmount"`
	RefundType     string `json:"RefundType"`
	RefundReason   string `json:"RefundReason"`
	OuterRefundNo  string `json:"OuterRefundNo"`
}

// ============================================================
// 接口 22: CancelRefundOrder
// ============================================================
type CancelRefundOrderReq struct {
	RefundOrderId string `json:"RefundOrderId" params:"RefundOrderId"`
	PurchaserId   string `json:"PurchaserId"`
}

// ============================================================
// 接口 23: GetRefundOrder
// ============================================================
type GetRefundOrderReq struct {
	RefundOrderId string `json:"RefundOrderId" params:"RefundOrderId"`
	PurchaserId   string `json:"PurchaserId" query:"PurchaserId"`
}

// ============================================================
// 接口 24: CreateGoodsShippingNotice
// ============================================================
type CreateGoodsShippingNoticeReq struct {
	RefundOrderId   string `json:"RefundOrderId" params:"RefundOrderId"`
	PurchaserId     string `json:"PurchaserId"`
	LogisticsCompany string `json:"LogisticsCompany"`
	TrackingNumber  string `json:"TrackingNumber"`
}

// ============================================================
// 接口 25: QueryChildDivisionCode
// ============================================================
type QueryChildDivisionCodeReq struct {
	ParentDivisionCode string `json:"ParentDivisionCode" query:"ParentDivisionCode"`
}

// ============================================================
// 回调通知
// ============================================================
type CallbackNotification struct {
	EventCode       string   `json:"EventCode"`
	PurchaseOrderId string   `json:"PurchaseOrderId"`
	OrderIdList     []string `json:"OrderIdList"`
	Status          string   `json:"Status"`
	RequestId       string   `json:"RequestId"`
}

// File: server_tb_LinkedMall/internal/entities/response.go

package entities

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

// CommonResponse 阿里云LinkedMall公共响应外层
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       interface{} `json:"Data"`
}

// APIResponse 服务端统一返回结构
type APIResponse struct {
	Success   bool        `json:"Success"`
	Code      string      `json:"Code"`
	Message   string      `json:"Message"`
	RequestId string      `json:"RequestId,omitempty"`
	Data      interface{} `json:"Data,omitempty"`
}

// ============================================================
// 接口 1: ListPurchaserShops
// ============================================================
type ListPurchaserShopsRespData struct {
	Total    int64               `json:"Total"`
	PageNum  int                 `json:"PageNum"`
	PageSize int                 `json:"PageSize"`
	ShopList []PurchaserShopItem `json:"ShopList"`
}

type PurchaserShopItem struct {
	ShopId      string `json:"ShopId"`
	PurchaserId string `json:"PurchaserId"`
	ShopName    string `json:"ShopName"`
	ShopStatus  string `json:"ShopStatus"`
}

// ============================================================
// 接口 2: GetPurchaserShop
// ============================================================
type GetPurchaserShopRespData struct {
	ShopId      string `json:"ShopId"`
	PurchaserId string `json:"PurchaserId"`
	ShopName    string `json:"ShopName"`
	ShopStatus  string `json:"ShopStatus"`
	ContactInfo string `json:"ContactInfo"`
}

// ============================================================
// 接口 3: ListSelectionProducts
// ============================================================
type ListSelectionProductsRespData struct {
	Total       int64                  `json:"Total"`
	PageNum     int                    `json:"PageNum"`
	PageSize    int                    `json:"PageSize"`
	ProductList []SelectionProductItem `json:"ProductList"`
}

type SelectionProductItem struct {
	ProductId  string `json:"ProductId"`
	Title      string `json:"Title"`
	MainImage  string `json:"MainImage"`
	BrandName  string `json:"BrandName"`
	CategoryId string `json:"CategoryId"`
}

// ============================================================
// 接口 4: GetSelectionProduct
// ============================================================
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"`
	StockQuantity int64               `json:"StockQuantity"`
}

type SelectionSkuItem struct {
	SkuId         string `json:"SkuId"`
	SkuSpec       string `json:"SkuSpec"`
	SalePrice     int64  `json:"SalePrice"`
	MarketPrice   int64  `json:"MarketPrice"`
	StockQuantity int64  `json:"StockQuantity"`
}

// ============================================================
// 接口 5: GetSelectionProductSaleInfo
// ============================================================
type GetSelectionProductSaleInfoRespData struct {
	ProductId    string `json:"ProductId"`
	Title        string `json:"Title"`
	CanSale      bool   `json:"CanSale"`
	SalePrice    int64  `json:"SalePrice"`
	StockQuantity int64 `json:"StockQuantity"`
}

// ============================================================
// 接口 6: ListSelectionProductSaleInfos
// ============================================================
type ListSelectionProductSaleInfosRespData struct {
	ProductSaleInfoList []ProductSaleInfoItem `json:"ProductSaleInfoList"`
}

type ProductSaleInfoItem struct {
	ProductId    string `json:"ProductId"`
	CanSale      bool   `json:"CanSale"`
	SalePrice    int64  `json:"SalePrice"`
	StockQuantity int64 `json:"StockQuantity"`
}

// ============================================================
// 接口 7: ListSelectionSkuSaleInfos
// ============================================================
type ListSelectionSkuSaleInfosRespData struct {
	SkuSaleInfoList []SkuSaleInfoItem `json:"SkuSaleInfoList"`
}

type SkuSaleInfoItem struct {
	SkuId         string `json:"SkuId"`
	CanSale       bool   `json:"CanSale"`
	SalePrice     int64  `json:"SalePrice"`
	StockQuantity int64  `json:"StockQuantity"`
}

// ============================================================
// 接口 8: ListCategories
// ============================================================
type ListCategoriesRespData struct {
	CategoryList []CategoryItem `json:"CategoryList"`
}

type CategoryItem struct {
	CategoryId   string `json:"CategoryId"`
	CategoryName string `json:"CategoryName"`
	ParentId     string `json:"ParentId"`
	Level        int    `json:"Level"`
}

// ============================================================
// 接口 9: SearchProducts
// ============================================================
type SearchProductsRespData struct {
	Total       int64                  `json:"Total"`
	PageNum     int                    `json:"PageNum"`
	PageSize    int                    `json:"PageSize"`
	ProductList []SelectionProductItem `json:"ProductList"`
}

// ============================================================
// 接口 10: SelectionGroupAddProduct
// ============================================================
type SelectionGroupAddProductRespData struct {
	SuccessCount int      `json:"SuccessCount"`
	FailList     []string `json:"FailList"`
}

// ============================================================
// 接口 11: SelectionGroupRemoveProduct
// ============================================================
type SelectionGroupRemoveProductRespData struct {
	SuccessCount int      `json:"SuccessCount"`
	FailList     []string `json:"FailList"`
}

// ============================================================
// 接口 12: RenderPurchaseOrder
// ============================================================
type RenderPurchaseOrderRespData struct {
	TotalFee          int64               `json:"TotalFee"`
	TotalFreight      int64               `json:"TotalFreight"`
	ItemList          []RenderResultItem  `json:"ItemList"`
	CanSale           bool                `json:"CanSale"`
	UnSaleReason      string              `json:"UnSaleReason"`
}

type RenderResultItem struct {
	SkuId         string `json:"SkuId"`
	SalePrice     int64  `json:"SalePrice"`
	Quantity      int64  `json:"Quantity"`
	SubTotalFee   int64  `json:"SubTotalFee"`
	CanSale       bool   `json:"CanSale"`
	UnSaleReason  string `json:"UnSaleReason"`
}

// ============================================================
// 接口 13: SplitPurchaseOrder
// ============================================================
type SplitPurchaseOrderRespData struct {
	SubOrderList []SubOrderItem `json:"SubOrderList"`
}

type SubOrderItem struct {
	ShopId       string            `json:"ShopId"`
	ItemList     []RenderOrderItem `json:"ItemList"`
	TotalFee     int64             `json:"TotalFee"`
	TotalFreight int64             `json:"TotalFreight"`
}

// ============================================================
// 接口 14: CreatePurchaseOrder
// ============================================================
type CreatePurchaseOrderRespData struct {
	PurchaseOrderId string `json:"PurchaseOrderId"`
}

// ============================================================
// 接口 15: GetPurchaseOrderStatus
// ============================================================
type GetPurchaseOrderStatusRespData struct {
	PurchaseOrderId string `json:"PurchaseOrderId"`
	Status          string `json:"Status"`
	StatusDesc      string `json:"StatusDesc"`
}

// ============================================================
// 接口 16: GetOrder
// ============================================================
type GetOrderRespData struct {
	OrderId          string           `json:"OrderId"`
	PurchaseOrderId  string           `json:"PurchaseOrderId"`
	ShopId           string           `json:"ShopId"`
	OrderStatus      string           `json:"OrderStatus"`
	TotalFee         int64            `json:"TotalFee"`
	FreightFee       int64            `json:"FreightFee"`
	ActualPayFee     int64            `json:"ActualPayFee"`
	ReceiverInfo     ReceiverInfo     `json:"ReceiverInfo"`
	OrderItemList    []OrderItemDetail `json:"OrderItemList"`
	CreateTime       string           `json:"CreateTime"`
}

type OrderItemDetail struct {
	OrderItemId string `json:"OrderItemId"`
	SkuId       string `json:"SkuId"`
	Title       string `json:"Title"`
	Quantity    int64  `json:"Quantity"`
	PayFee      int64  `json:"PayFee"`
	UnitPrice   int64  `json:"UnitPrice"`
}

// ============================================================
// 接口 17: QueryOrders
// ============================================================
type QueryOrdersRespData struct {
	Total     int64            `json:"Total"`
	PageNum   int              `json:"PageNum"`
	PageSize  int              `json:"PageSize"`
	OrderList []GetOrderRespData `json:"OrderList"`
}

// ============================================================
// 接口 18: ListLogisticsOrders
// ============================================================
type ListLogisticsOrdersRespData struct {
	LogisticsList []LogisticsItem `json:"LogisticsList"`
}

type LogisticsItem struct {
	LogisticsCompany string             `json:"LogisticsCompany"`
	TrackingNumber   string             `json:"TrackingNumber"`
	TrajectoryList   []LogisticsTrajectory `json:"TrajectoryList"`
}

type LogisticsTrajectory struct {
	Time     string `json:"Time"`
	Context  string `json:"Context"`
	Location string `json:"Location"`
}

// ============================================================
// 接口 19: ConfirmDisburse
// ============================================================
type ConfirmDisburseRespData struct {
	Success bool `json:"Success"`
}

// ============================================================
// 接口 20: RenderRefundOrder
// ============================================================
type RenderRefundOrderRespData struct {
	RefundableAmount int64  `json:"RefundableAmount"`
	RefundableQuantity int64 `json:"RefundableQuantity"`
	CanRefund        bool   `json:"CanRefund"`
	UnRefundReason   string `json:"UnRefundReason"`
}

// ============================================================
// 接口 21: CreateRefundOrder
// ============================================================
type CreateRefundOrderRespData struct {
	RefundOrderId string `json:"RefundOrderId"`
	Status        string `json:"Status"`
}

// ============================================================
// 接口 22: CancelRefundOrder
// ============================================================
type CancelRefundOrderRespData struct {
	Success bool `json:"Success"`
}

// ============================================================
// 接口 23: GetRefundOrder
// ============================================================
type GetRefundOrderRespData struct {
	RefundOrderId  string `json:"RefundOrderId"`
	OrderId        string `json:"OrderId"`
	OrderItemId    string `json:"OrderItemId"`
	RefundQuantity int64  `json:"RefundQuantity"`
	RefundAmount   int64  `json:"RefundAmount"`
	RefundType     string `json:"RefundType"`
	RefundStatus   string `json:"RefundStatus"`
	RefundReason   string `json:"RefundReason"`
	CreateTime     string `json:"CreateTime"`
}

// ============================================================
// 接口 24: CreateGoodsShippingNotice
// ============================================================
type CreateGoodsShippingNoticeRespData struct {
	Success bool `json:"Success"`
}

// ============================================================
// 接口 25: QueryChildDivisionCode
// ============================================================
type QueryChildDivisionCodeRespData struct {
	DivisionList []DivisionItem `json:"DivisionList"`
}

type DivisionItem struct {
	DivisionCode string `json:"DivisionCode"`
	DivisionName string `json:"DivisionName"`
	Level        int    `json:"Level"`
	ParentCode   string `json:"ParentCode"`
}

// File: server_tb_LinkedMall/internal/biz/biz.go

package biz

import (
	"encoding/json"
	"fmt"

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

	"server_tb_LinkedMall/internal/config"
	"server_tb_LinkedMall/internal/entities"
)

// LinkedMallBiz 业务逻辑层 - 封装对LinkedMall OpenAPI的调用
type LinkedMallBiz struct {
	client   *openapi.Client
	cfg      *config.Config
	basePath string
}

// NewLinkedMallBiz 创建业务逻辑实例
func NewLinkedMallBiz(cfg *config.Config) (*LinkedMallBiz, error) {
	cli, err := newLinkedMallClient(cfg.AccessKeyId, cfg.AccessKeySecret, cfg.RegionId, cfg.Endpoint)
	if err != nil {
		return nil, fmt.Errorf("初始化LinkedMall客户端失败: %w", err)
	}
	return &LinkedMallBiz{
		client:   cli,
		cfg:      cfg,
		basePath: cfg.BasePath,
	}, nil
}

// newLinkedMallClient 创建Darabonba OpenAPI客户端
func newLinkedMallClient(ak, sk, regionId, endpoint string) (*openapi.Client, error) {
	config := &openapi.Config{
		AccessKeyId:     tea.String(ak),
		AccessKeySecret: tea.String(sk),
		RegionId:        tea.String(regionId),
		Endpoint:        tea.String(endpoint),
		ReadTimeout:     tea.Int(30000),
		ConnectTimeout:  tea.Int(10000),
	}
	return openapi.NewClient(config)
}

// doRoaGet 发起ROA GET请求
func (b *LinkedMallBiz) doRoaGet(path string, query map[string]*string) (*entities.CommonResponse, error) {
	resp, err := b.client.RoaRequest(
		tea.String("GET"),
		tea.String(b.basePath+path),
		query,
		nil,  // body
		nil,  // header
	)
	if err != nil {
		return nil, fmt.Errorf("ROA GET请求失败 [%s]: %w", path, err)
	}
	return b.parseResponse(resp)
}

// doRoaPost 发起ROA POST请求
func (b *LinkedMallBiz) doRoaPost(path string, body interface{}, query map[string]*string) (*entities.CommonResponse, error) {
	jsonBytes, err := json.Marshal(body)
	if err != nil {
		return nil, fmt.Errorf("序列化请求Body失败: %w", err)
	}
	var bodyObj interface{}
	if err := json.Unmarshal(jsonBytes, &bodyObj); err != nil {
		return nil, fmt.Errorf("反序列化请求Body失败: %w", err)
	}
	resp, err := b.client.RoaRequest(
		tea.String("POST"),
		tea.String(b.basePath+path),
		query,
		bodyObj,
		nil,
	)
	if err != nil {
		return nil, fmt.Errorf("ROA POST请求失败 [%s]: %w", path, err)
	}
	return b.parseResponse(resp)
}

// parseResponse 解析公共响应
func (b *LinkedMallBiz) parseResponse(resp interface{}) (*entities.CommonResponse, error) {
	respBytes, err := json.Marshal(resp)
	if err != nil {
		return nil, fmt.Errorf("序列化响应失败: %w", err)
	}
	var commonResp entities.CommonResponse
	if err := json.Unmarshal(respBytes, &commonResp); err != nil {
		return nil, fmt.Errorf("解析公共响应失败: %w", err)
	}
	return &commonResp, nil
}

// ============================================================
// 接口实现调用阿里云LinkedMall OpenAPI
// ============================================================

// 接口 1: ListPurchaserShops
func (b *LinkedMallBiz) ListPurchaserShops(req *entities.ListPurchaserShopsReq) (*entities.CommonResponse, error) {
	query := make(map[string]*string)
	if req.PageNum > 0 {
		query["PageNum"] = tea.String(fmt.Sprintf("%d", req.PageNum))
	}
	if req.PageSize > 0 {
		query["PageSize"] = tea.String(fmt.Sprintf("%d", req.PageSize))
	}
	return b.doRoaGet("/purchaser-shops", query)
}

// 接口 2: GetPurchaserShop
func (b *LinkedMallBiz) GetPurchaserShop(req *entities.GetPurchaserShopReq) (*entities.CommonResponse, error) {
	return b.doRoaGet(fmt.Sprintf("/purchaser-shops/%s", req.ShopId), nil)
}

// 接口 3: ListSelectionProducts
func (b *LinkedMallBiz) ListSelectionProducts(req *entities.ListSelectionProductsReq) (*entities.CommonResponse, error) {
	query := make(map[string]*string)
	query["PurchaserId"] = tea.String(req.PurchaserId)
	if req.PageNum > 0 {
		query["PageNum"] = tea.String(fmt.Sprintf("%d", req.PageNum))
	}
	if req.PageSize > 0 {
		query["PageSize"] = tea.String(fmt.Sprintf("%d", req.PageSize))
	}
	return b.doRoaGet("/selection-products", query)
}

// 接口 4: GetSelectionProduct
func (b *LinkedMallBiz) GetSelectionProduct(req *entities.GetSelectionProductReq) (*entities.CommonResponse, error) {
	query := make(map[string]*string)
	query["PurchaserId"] = tea.String(req.PurchaserId)
	if req.DivisionCode != "" {
		query["DivisionCode"] = tea.String(req.DivisionCode)
	}
	return b.doRoaGet(fmt.Sprintf("/selection-products/%s", req.ProductId), query)
}

// 接口 5: GetSelectionProductSaleInfo
func (b *LinkedMallBiz) GetSelectionProductSaleInfo(req *entities.GetSelectionProductSaleInfoReq) (*entities.CommonResponse, error) {
	query := make(map[string]*string)
	query["PurchaserId"] = tea.String(req.PurchaserId)
	if req.DivisionCode != "" {
		query["DivisionCode"] = tea.String(req.DivisionCode)
	}
	return b.doRoaGet(fmt.Sprintf("/selection-products/%s/sale-info", req.ProductId), query)
}

// 接口 6: ListSelectionProductSaleInfos
func (b *LinkedMallBiz) ListSelectionProductSaleInfos(req *entities.ListSelectionProductSaleInfosReq) (*entities.CommonResponse, error) {
	return b.doRoaPost("/selection-products:batch-sale-info", req, nil)
}

// 接口 7: ListSelectionSkuSaleInfos
func (b *LinkedMallBiz) ListSelectionSkuSaleInfos(req *entities.ListSelectionSkuSaleInfosReq) (*entities.CommonResponse, error) {
	return b.doRoaPost("/selection-skus:batch-sale-info", req, nil)
}

// 接口 8: ListCategories
func (b *LinkedMallBiz) ListCategories(req *entities.ListCategoriesReq) (*entities.CommonResponse, error) {
	query := make(map[string]*string)
	query["PurchaserId"] = tea.String(req.PurchaserId)
	if req.ParentCategoryId != "" {
		query["ParentCategoryId"] = tea.String(req.ParentCategoryId)
	}
	return b.doRoaGet("/categories", query)
}

// 接口 9: SearchProducts
func (b *LinkedMallBiz) SearchProducts(req *entities.SearchProductsReq) (*entities.CommonResponse, error) {
	return b.doRoaPost("/selection-products:search", req, nil)
}

// 接口 10: SelectionGroupAddProduct
func (b *LinkedMallBiz) SelectionGroupAddProduct(req *entities.SelectionGroupAddProductReq) (*entities.CommonResponse, error) {
	return b.doRoaPost("/selection-group/products:add", req, nil)
}

// 接口 11: SelectionGroupRemoveProduct
func (b *LinkedMallBiz) SelectionGroupRemoveProduct(req *entities.SelectionGroupRemoveProductReq) (*entities.CommonResponse, error) {
	return b.doRoaPost("/selection-group/products:remove", req, nil)
}

// 接口 12: RenderPurchaseOrder
func (b *LinkedMallBiz) RenderPurchaseOrder(req *entities.RenderPurchaseOrderReq) (*entities.CommonResponse, error) {
	return b.doRoaPost("/purchase-orders:render", req, nil)
}

// 接口 13: SplitPurchaseOrder
func (b *LinkedMallBiz) SplitPurchaseOrder(req *entities.SplitPurchaseOrderReq) (*entities.CommonResponse, error) {
	return b.doRoaPost("/purchase-orders:split-render", req, nil)
}

// 接口 14: CreatePurchaseOrder
func (b *LinkedMallBiz) CreatePurchaseOrder(req *entities.CreatePurchaseOrderReq) (*entities.CommonResponse, error) {
	return b.doRoaPost("/purchase-orders", req, nil)
}

// 接口 15: GetPurchaseOrderStatus
func (b *LinkedMallBiz) GetPurchaseOrderStatus(req *entities.GetPurchaseOrderStatusReq) (*entities.CommonResponse, error) {
	query := make(map[string]*string)
	query["PurchaserId"] = tea.String(req.PurchaserId)
	return b.doRoaGet(fmt.Sprintf("/purchase-orders/%s/status", req.PurchaseOrderId), query)
}

// 接口 16: GetOrder
func (b *LinkedMallBiz) GetOrder(req *entities.GetOrderReq) (*entities.CommonResponse, error) {
	query := make(map[string]*string)
	query["PurchaserId"] = tea.String(req.PurchaserId)
	return b.doRoaGet(fmt.Sprintf("/orders/%s", req.OrderId), query)
}

// 接口 17: QueryOrders
func (b *LinkedMallBiz) QueryOrders(req *entities.QueryOrdersReq) (*entities.CommonResponse, error) {
	query := make(map[string]*string)
	query["PurchaserId"] = tea.String(req.PurchaserId)
	if req.PurchaseOrderId != "" {
		query["PurchaseOrderId"] = tea.String(req.PurchaseOrderId)
	}
	if req.PageNum > 0 {
		query["PageNum"] = tea.String(fmt.Sprintf("%d", req.PageNum))
	}
	if req.PageSize > 0 {
		query["PageSize"] = tea.String(fmt.Sprintf("%d", req.PageSize))
	}
	if req.StartTime != "" {
		query["StartTime"] = tea.String(req.StartTime)
	}
	if req.EndTime != "" {
		query["EndTime"] = tea.String(req.EndTime)
	}
	return b.doRoaGet("/orders", query)
}

// 接口 18: ListLogisticsOrders
func (b *LinkedMallBiz) ListLogisticsOrders(req *entities.ListLogisticsOrdersReq) (*entities.CommonResponse, error) {
	query := make(map[string]*string)
	query["PurchaserId"] = tea.String(req.PurchaserId)
	return b.doRoaGet(fmt.Sprintf("/orders/%s/logistics", req.OrderId), query)
}

// 接口 19: ConfirmDisburse
func (b *LinkedMallBiz) ConfirmDisburse(req *entities.ConfirmDisburseReq) (*entities.CommonResponse, error) {
	body := map[string]string{"PurchaserId": req.PurchaserId}
	return b.doRoaPost(fmt.Sprintf("/orders/%s:confirm-disburse", req.OrderId), body, nil)
}

// 接口 20: RenderRefundOrder
func (b *LinkedMallBiz) RenderRefundOrder(req *entities.RenderRefundOrderReq) (*entities.CommonResponse, error) {
	return b.doRoaPost("/refund-orders:render", req, nil)
}

// 接口 21: CreateRefundOrder
func (b *LinkedMallBiz) CreateRefundOrder(req *entities.CreateRefundOrderReq) (*entities.CommonResponse, error) {
	return b.doRoaPost("/refund-orders", req, nil)
}

// 接口 22: CancelRefundOrder
func (b *LinkedMallBiz) CancelRefundOrder(req *entities.CancelRefundOrderReq) (*entities.CommonResponse, error) {
	body := map[string]string{"PurchaserId": req.PurchaserId}
	return b.doRoaPost(fmt.Sprintf("/refund-orders/%s:cancel", req.RefundOrderId), body, nil)
}

// 接口 23: GetRefundOrder
func (b *LinkedMallBiz) GetRefundOrder(req *entities.GetRefundOrderReq) (*entities.CommonResponse, error) {
	query := make(map[string]*string)
	query["PurchaserId"] = tea.String(req.PurchaserId)
	return b.doRoaGet(fmt.Sprintf("/refund-orders/%s", req.RefundOrderId), query)
}

// 接口 24: CreateGoodsShippingNotice
func (b *LinkedMallBiz) CreateGoodsShippingNotice(req *entities.CreateGoodsShippingNoticeReq) (*entities.CommonResponse, error) {
	body := map[string]string{
		"PurchaserId":      req.PurchaserId,
		"LogisticsCompany": req.LogisticsCompany,
		"TrackingNumber":   req.TrackingNumber,
	}
	return b.doRoaPost(fmt.Sprintf("/refund-orders/%s:fill-logistics", req.RefundOrderId), body, nil)
}

// 接口 25: QueryChildDivisionCode
func (b *LinkedMallBiz) QueryChildDivisionCode(req *entities.QueryChildDivisionCodeReq) (*entities.CommonResponse, error) {
	query := make(map[string]*string)
	if req.ParentDivisionCode != "" {
		query["ParentDivisionCode"] = tea.String(req.ParentDivisionCode)
	}
	return b.doRoaGet("/divisions:children", query)
}

// File: server_tb_LinkedMall/internal/service/service.go

package service

import (
	"encoding/json"

	"server_tb_LinkedMall/internal/biz"
	"server_tb_LinkedMall/internal/config"
	"server_tb_LinkedMall/internal/entities"
)

// LinkedMallService 服务层 - 封装业务逻辑,处理响应解析
type LinkedMallService struct {
	biz *biz.LinkedMallBiz
}

// NewLinkedMallService 创建服务实例
func NewLinkedMallService(cfg *config.Config) (*LinkedMallService, error) {
	bizInstance, err := biz.NewLinkedMallBiz(cfg)
	if err != nil {
		return nil, err
	}
	return &LinkedMallService{biz: bizInstance}, nil
}

// parseData 解析Data字段到目标结构体
func (s *LinkedMallService) parseData(commonResp *entities.CommonResponse, target interface{}) error {
	if commonResp.Data == nil {
		return nil
	}
	dataBytes, err := json.Marshal(commonResp.Data)
	if err != nil {
		return err
	}
	return json.Unmarshal(dataBytes, target)
}

// buildAPIResponse 构建统一API响应
func (s *LinkedMallService) buildAPIResponse(commonResp *entities.CommonResponse, data interface{}) *entities.APIResponse {
	resp := &entities.APIResponse{
		Success:   commonResp.Success,
		Code:      commonResp.Code,
		Message:   commonResp.Message,
		RequestId: commonResp.RequestId,
	}

	if commonResp.Success && data != nil {
		resp.Data = data
	}
	if !commonResp.Success {
		if commonResp.SubCode != "" {
			resp.Message = commonResp.SubMessage
		}
	}
	return resp
}

// ============================================================
// 接口 1: ListPurchaserShops
// ============================================================
func (s *LinkedMallService) ListPurchaserShops(req *entities.ListPurchaserShopsReq) (*entities.APIResponse, error) {
	commonResp, err := s.biz.ListPurchaserShops(req)
	if err != nil {
		return nil, err
	}
	var data entities.ListPurchaserShopsRespData
	if commonResp.Success {
		_ = s.parseData(commonResp, &data)
	}
	return s.buildAPIResponse(commonResp, &data), nil
}

// 接口 2: GetPurchaserShop
func (s *LinkedMallService) GetPurchaserShop(req *entities.GetPurchaserShopReq) (*entities.APIResponse, error) {
	commonResp, err := s.biz.GetPurchaserShop(req)
	if err != nil {
		return nil, err
	}
	var data entities.GetPurchaserShopRespData
	if commonResp.Success {
		_ = s.parseData(commonResp, &data)
	}
	return s.buildAPIResponse(commonResp, &data), nil
}

// 接口 3: ListSelectionProducts
func (s *LinkedMallService) ListSelectionProducts(req *entities.ListSelectionProductsReq) (*entities.APIResponse, error) {
	commonResp, err := s.biz.ListSelectionProducts(req)
	if err != nil {
		return nil, err
	}
	var data entities.ListSelectionProductsRespData
	if commonResp.Success {
		_ = s.parseData(commonResp, &data)
	}
	return s.buildAPIResponse(commonResp, &data), nil
}

// 接口 4: GetSelectionProduct
func (s *LinkedMallService) GetSelectionProduct(req *entities.GetSelectionProductReq) (*entities.APIResponse, error) {
	commonResp, err := s.biz.GetSelectionProduct(req)
	if err != nil {
		return nil, err
	}
	var data entities.GetSelectionProductRespData
	if commonResp.Success {
		_ = s.parseData(commonResp, &data)
	}
	return s.buildAPIResponse(commonResp, &data), nil
}

// 接口 5: GetSelectionProductSaleInfo
func (s *LinkedMallService) GetSelectionProductSaleInfo(req *entities.GetSelectionProductSaleInfoReq) (*entities.APIResponse, error) {
	commonResp, err := s.biz.GetSelectionProductSaleInfo(req)
	if err != nil {
		return nil, err
	}
	var data entities.GetSelectionProductSaleInfoRespData
	if commonResp.Success {
		_ = s.parseData(commonResp, &data)
	}
	return s.buildAPIResponse(commonResp, &data), nil
}

// 接口 6: ListSelectionProductSaleInfos
func (s *LinkedMallService) ListSelectionProductSaleInfos(req *entities.ListSelectionProductSaleInfosReq) (*entities.APIResponse, error) {
	commonResp, err := s.biz.ListSelectionProductSaleInfos(req)
	if err != nil {
		return nil, err
	}
	var data entities.ListSelectionProductSaleInfosRespData
	if commonResp.Success {
		_ = s.parseData(commonResp, &data)
	}
	return s.buildAPIResponse(commonResp, &data), nil
}

// 接口 7: ListSelectionSkuSaleInfos
func (s *LinkedMallService) ListSelectionSkuSaleInfos(req *entities.ListSelectionSkuSaleInfosReq) (*entities.APIResponse, error) {
	commonResp, err := s.biz.ListSelectionSkuSaleInfos(req)
	if err != nil {
		return nil, err
	}
	var data entities.ListSelectionSkuSaleInfosRespData
	if commonResp.Success {
		_ = s.parseData(commonResp, &data)
	}
	return s.buildAPIResponse(commonResp, &data), nil
}

// 接口 8: ListCategories
func (s *LinkedMallService) ListCategories(req *entities.ListCategoriesReq) (*entities.APIResponse, error) {
	commonResp, err := s.biz.ListCategories(req)
	if err != nil {
		return nil, err
	}
	var data entities.ListCategoriesRespData
	if commonResp.Success {
		_ = s.parseData(commonResp, &data)
	}
	return s.buildAPIResponse(commonResp, &data), nil
}

// 接口 9: SearchProducts
func (s *LinkedMallService) SearchProducts(req *entities.SearchProductsReq) (*entities.APIResponse, error) {
	commonResp, err := s.biz.SearchProducts(req)
	if err != nil {
		return nil, err
	}
	var data entities.SearchProductsRespData
	if commonResp.Success {
		_ = s.parseData(commonResp, &data)
	}
	return s.buildAPIResponse(commonResp, &data), nil
}

// 接口 10: SelectionGroupAddProduct
func (s *LinkedMallService) SelectionGroupAddProduct(req *entities.SelectionGroupAddProductReq) (*entities.APIResponse, error) {
	commonResp, err := s.biz.SelectionGroupAddProduct(req)
	if err != nil {
		return nil, err
	}
	var data entities.SelectionGroupAddProductRespData
	if commonResp.Success {
		_ = s.parseData(commonResp, &data)
	}
	return s.buildAPIResponse(commonResp, &data), nil
}

// 接口 11: SelectionGroupRemoveProduct
func (s *LinkedMallService) SelectionGroupRemoveProduct(req *entities.SelectionGroupRemoveProductReq) (*entities.APIResponse, error) {
	commonResp, err := s.biz.SelectionGroupRemoveProduct(req)
	if err != nil {
		return nil, err
	}
	var data entities.SelectionGroupRemoveProductRespData
	if commonResp.Success {
		_ = s.parseData(commonResp, &data)
	}
	return s.buildAPIResponse(commonResp, &data), nil
}

// 接口 12: RenderPurchaseOrder
func (s *LinkedMallService) RenderPurchaseOrder(req *entities.RenderPurchaseOrderReq) (*entities.APIResponse, error) {
	commonResp, err := s.biz.RenderPurchaseOrder(req)
	if err != nil {
		return nil, err
	}
	var data entities.RenderPurchaseOrderRespData
	if commonResp.Success {
		_ = s.parseData(commonResp, &data)
	}
	return s.buildAPIResponse(commonResp, &data), nil
}

// 接口 13: SplitPurchaseOrder
func (s *LinkedMallService) SplitPurchaseOrder(req *entities.SplitPurchaseOrderReq) (*entities.APIResponse, error) {
	commonResp, err := s.biz.SplitPurchaseOrder(req)
	if err != nil {
		return nil, err
	}
	var data entities.SplitPurchaseOrderRespData
	if commonResp.Success {
		_ = s.parseData(commonResp, &data)
	}
	return s.buildAPIResponse(commonResp, &data), nil
}

// 接口 14: CreatePurchaseOrder
func (s *LinkedMallService) CreatePurchaseOrder(req *entities.CreatePurchaseOrderReq) (*entities.APIResponse, error) {
	commonResp, err := s.biz.CreatePurchaseOrder(req)
	if err != nil {
		return nil, err
	}
	var data entities.CreatePurchaseOrderRespData
	if commonResp.Success {
		_ = s.parseData(commonResp, &data)
	}
	return s.buildAPIResponse(commonResp, &data), nil
}

// 接口 15: GetPurchaseOrderStatus
func (s *LinkedMallService) GetPurchaseOrderStatus(req *entities.GetPurchaseOrderStatusReq) (*entities.APIResponse, error) {
	commonResp, err := s.biz.GetPurchaseOrderStatus(req)
	if err != nil {
		return nil, err
	}
	var data entities.GetPurchaseOrderStatusRespData
	if commonResp.Success {
		_ = s.parseData(commonResp, &data)
	}
	return s.buildAPIResponse(commonResp, &data), nil
}

// 接口 16: GetOrder
func (s *LinkedMallService) GetOrder(req *entities.GetOrderReq) (*entities.APIResponse, error) {
	commonResp, err := s.biz.GetOrder(req)
	if err != nil {
		return nil, err
	}
	var data entities.GetOrderRespData
	if commonResp.Success {
		_ = s.parseData(commonResp, &data)
	}
	return s.buildAPIResponse(commonResp, &data), nil
}

// 接口 17: QueryOrders
func (s *LinkedMallService) QueryOrders(req *entities.QueryOrdersReq) (*entities.APIResponse, error) {
	commonResp, err := s.biz.QueryOrders(req)
	if err != nil {
		return nil, err
	}
	var data entities.QueryOrdersRespData
	if commonResp.Success {
		_ = s.parseData(commonResp, &data)
	}
	return s.buildAPIResponse(commonResp, &data), nil
}

// 接口 18: ListLogisticsOrders
func (s *LinkedMallService) ListLogisticsOrders(req *entities.ListLogisticsOrdersReq) (*entities.APIResponse, error) {
	commonResp, err := s.biz.ListLogisticsOrders(req)
	if err != nil {
		return nil, err
	}
	var data entities.ListLogisticsOrdersRespData
	if commonResp.Success {
		_ = s.parseData(commonResp, &data)
	}
	return s.buildAPIResponse(commonResp, &data), nil
}

// 接口 19: ConfirmDisburse
func (s *LinkedMallService) ConfirmDisburse(req *entities.ConfirmDisburseReq) (*entities.APIResponse, error) {
	commonResp, err := s.biz.ConfirmDisburse(req)
	if err != nil {
		return nil, err
	}
	var data entities.ConfirmDisburseRespData
	if commonResp.Success {
		_ = s.parseData(commonResp, &data)
	}
	return s.buildAPIResponse(commonResp, &data), nil
}

// 接口 20: RenderRefundOrder
func (s *LinkedMallService) RenderRefundOrder(req *entities.RenderRefundOrderReq) (*entities.APIResponse, error) {
	commonResp, err := s.biz.RenderRefundOrder(req)
	if err != nil {
		return nil, err
	}
	var data entities.RenderRefundOrderRespData
	if commonResp.Success {
		_ = s.parseData(commonResp, &data)
	}
	return s.buildAPIResponse(commonResp, &data), nil
}

// 接口 21: CreateRefundOrder
func (s *LinkedMallService) CreateRefundOrder(req *entities.CreateRefundOrderReq) (*entities.APIResponse, error) {
	commonResp, err := s.biz.CreateRefundOrder(req)
	if err != nil {
		return nil, err
	}
	var data entities.CreateRefundOrderRespData
	if commonResp.Success {
		_ = s.parseData(commonResp, &data)
	}
	return s.buildAPIResponse(commonResp, &data), nil
}

// 接口 22: CancelRefundOrder
func (s *LinkedMallService) CancelRefundOrder(req *entities.CancelRefundOrderReq) (*entities.APIResponse, error) {
	commonResp, err := s.biz.CancelRefundOrder(req)
	if err != nil {
		return nil, err
	}
	var data entities.CancelRefundOrderRespData
	if commonResp.Success {
		_ = s.parseData(commonResp, &data)
	}
	return s.buildAPIResponse(commonResp, &data), nil
}

// 接口 23: GetRefundOrder
func (s *LinkedMallService) GetRefundOrder(req *entities.GetRefundOrderReq) (*entities.APIResponse, error) {
	commonResp, err := s.biz.GetRefundOrder(req)
	if err != nil {
		return nil, err
	}
	var data entities.GetRefundOrderRespData
	if commonResp.Success {
		_ = s.parseData(commonResp, &data)
	}
	return s.buildAPIResponse(commonResp, &data), nil
}

// 接口 24: CreateGoodsShippingNotice
func (s *LinkedMallService) CreateGoodsShippingNotice(req *entities.CreateGoodsShippingNoticeReq) (*entities.APIResponse, error) {
	commonResp, err := s.biz.CreateGoodsShippingNotice(req)
	if err != nil {
		return nil, err
	}
	var data entities.CreateGoodsShippingNoticeRespData
	if commonResp.Success {
		_ = s.parseData(commonResp, &data)
	}
	return s.buildAPIResponse(commonResp, &data), nil
}

// 接口 25: QueryChildDivisionCode
func (s *LinkedMallService) QueryChildDivisionCode(req *entities.QueryChildDivisionCodeReq) (*entities.APIResponse, error) {
	commonResp, err := s.biz.QueryChildDivisionCode(req)
	if err != nil {
		return nil, err
	}
	var data entities.QueryChildDivisionCodeRespData
	if commonResp.Success {
		_ = s.parseData(commonResp, &data)
	}
	return s.buildAPIResponse(commonResp, &data), nil
}

// File: server_tb_LinkedMall/internal/middleware/middleware.go

package middleware

import (
	"github.com/gofiber/fiber/v2"
	"github.com/google/uuid"
)

// RequestID 为每个请求注入RequestID
func RequestID() fiber.Handler {
	return func(c *fiber.Ctx) error {
		rid := c.Get("X-Request-Id")
		if rid == "" {
			rid = uuid.New().String()
		}
		c.Set("X-Request-Id", rid)
		c.Locals("requestId", rid)
		return c.Next()
	}
}

// StandardResponse 统一响应格式中间件
func StandardResponse() fiber.Handler {
	return func(c *fiber.Ctx) error {
		// 先执行handler
		err := c.Next()
		if err != nil {
			// 处理handler返回的错误
			return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
				"Success": false,
				"Code":    "INTERNAL_ERROR",
				"Message": err.Error(),
			})
		}
		return nil
	}
}

// CORS 跨域中间件
func CORS() fiber.Handler {
	return func(c *fiber.Ctx) error {
		c.Set("Access-Control-Allow-Origin", "*")
		c.Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
		c.Set("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Request-Id")
		if c.Method() == "OPTIONS" {
			return c.SendStatus(fiber.StatusNoContent)
		}
		return c.Next()
	}
}

// File: server_tb_LinkedMall/internal/router/router.go

package router

import (
	"github.com/gofiber/fiber/v2"

	"server_tb_LinkedMall/internal/middleware"
	"server_tb_LinkedMall/internal/service"
)

// SetupRouter 注册所有路由
func SetupRouter(app *fiber.App, svc *service.LinkedMallService) {
	// 全局中间件
	app.Use(middleware.RequestID())
	app.Use(middleware.CORS())

	// 健康检查
	app.Get("/health", func(c *fiber.Ctx) error {
		return c.JSON(fiber.Map{"status": "ok"})
	})

	// API v1 路由组
	api := app.Group("/api/v1", middleware.StandardResponse())

	// ============================================================
	// 采购方店铺相关
	// ============================================================

	// 接口 1: ListPurchaserShops - 分页获取采购方店铺列表
	api.Get("/purchaser-shops", func(c *fiber.Ctx) error {
		// TODO: 实现参数绑定和调用
		return c.JSON(fiber.Map{"message": "ListPurchaserShops - 待实现"})
	})

	// 接口 2: GetPurchaserShop - 获取单个采购店铺详情
	api.Get("/purchaser-shops/:shopId", func(c *fiber.Ctx) error {
		// TODO: 实现参数绑定和调用
		return c.JSON(fiber.Map{"message": "GetPurchaserShop - 待实现"})
	})

	// ============================================================
	// 选品池商品相关
	// ============================================================

	// 接口 3: ListSelectionProducts - 分页查询选品池商品列表
	api.Get("/selection-products", func(c *fiber.Ctx) error {
		// TODO: 实现参数绑定和调用
		return c.JSON(fiber.Map{"message": "ListSelectionProducts - 待实现"})
	})

	// 接口 4: GetSelectionProduct - 查询选品池商品详情
	api.Get("/selection-products/:productId", func(c *fiber.Ctx) error {
		// TODO: 实现参数绑定和调用
		return c.JSON(fiber.Map{"message": "GetSelectionProduct - 待实现"})
	})

	// 接口 5: GetSelectionProductSaleInfo - 查询选品池商品销售信息
	api.Get("/selection-products/:productId/sale-info", func(c *fiber.Ctx) error {
		// TODO: 实现参数绑定和调用
		return c.JSON(fiber.Map{"message": "GetSelectionProductSaleInfo - 待实现"})
	})

	// 接口 6: ListSelectionProductSaleInfos - 批量查询商品销售信息
	api.Post("/selection-products:batch-sale-info", func(c *fiber.Ctx) error {
		// TODO: 实现参数绑定和调用
		return c.JSON(fiber.Map{"message": "ListSelectionProductSaleInfos - 待实现"})
	})

	// 接口 7: ListSelectionSkuSaleInfos - 批量SKU销售信息
	api.Post("/selection-skus:batch-sale-info", func(c *fiber.Ctx) error {
		// TODO: 实现参数绑定和调用
		return c.JSON(fiber.Map{"message": "ListSelectionSkuSaleInfos - 待实现"})
	})

	// 接口 8: ListCategories - 查询类目列表
	api.Get("/categories", func(c *fiber.Ctx) error {
		// TODO: 实现参数绑定和调用
		return c.JSON(fiber.Map{"message": "ListCategories - 待实现"})
	})

	// 接口 9: SearchProducts - 搜索选品池商品
	api.Post("/selection-products:search", func(c *fiber.Ctx) error {
		// TODO: 实现参数绑定和调用
		return c.JSON(fiber.Map{"message": "SearchProducts - 待实现"})
	})

	// 接口 10: SelectionGroupAddProduct - 选品池商品入库
	api.Post("/selection-group/products:add", func(c *fiber.Ctx) error {
		// TODO: 实现参数绑定和调用
		return c.JSON(fiber.Map{"message": "SelectionGroupAddProduct - 待实现"})
	})

	// 接口 11: SelectionGroupRemoveProduct - 选品池商品出库
	api.Post("/selection-group/products:remove", func(c *fiber.Ctx) error {
		// TODO: 实现参数绑定和调用
		return c.JSON(fiber.Map{"message": "SelectionGroupRemoveProduct - 待实现"})
	})

	// ============================================================
	// 采购单相关
	// ============================================================

	// 接口 12: RenderPurchaseOrder - 采购单渲染(下单预校验)
	api.Post("/purchase-orders:render", func(c *fiber.Ctx) error {
		// TODO: 实现参数绑定和调用
		return c.JSON(fiber.Map{"message": "RenderPurchaseOrder - 待实现"})
	})

	// 接口 13: SplitPurchaseOrder - 采购单渲染并拆单
	api.Post("/purchase-orders:split-render", func(c *fiber.Ctx) error {
		// TODO: 实现参数绑定和调用
		return c.JSON(fiber.Map{"message": "SplitPurchaseOrder - 待实现"})
	})

	// 接口 14: CreatePurchaseOrder - 创建采购单【异步】
	api.Post("/purchase-orders", func(c *fiber.Ctx) error {
		// TODO: 实现参数绑定和调用
		return c.JSON(fiber.Map{"message": "CreatePurchaseOrder - 待实现"})
	})

	// 接口 15: GetPurchaseOrderStatus - 获取采购单状态
	api.Get("/purchase-orders/:purchaseOrderId/status", func(c *fiber.Ctx) error {
		// TODO: 实现参数绑定和调用
		return c.JSON(fiber.Map{"message": "GetPurchaseOrderStatus - 待实现"})
	})

	// ============================================================
	// 订单相关
	// ============================================================

	// 接口 16: GetOrder - 获取订单详情
	api.Get("/orders/:orderId", func(c *fiber.Ctx) error {
		// TODO: 实现参数绑定和调用
		return c.JSON(fiber.Map{"message": "GetOrder - 待实现"})
	})

	// 接口 17: QueryOrders - 查询订单列表
	api.Get("/orders", func(c *fiber.Ctx) error {
		// TODO: 实现参数绑定和调用
		return c.JSON(fiber.Map{"message": "QueryOrders - 待实现"})
	})

	// 接口 18: ListLogisticsOrders - 查询订单物流信息
	api.Get("/orders/:orderId/logistics", func(c *fiber.Ctx) error {
		// TODO: 实现参数绑定和调用
		return c.JSON(fiber.Map{"message": "ListLogisticsOrders - 待实现"})
	})

	// 接口 19: ConfirmDisburse - 确认收货
	api.Post("/orders/:orderId:confirm-disburse", func(c *fiber.Ctx) error {
		// TODO: 实现参数绑定和调用
		return c.JSON(fiber.Map{"message": "ConfirmDisburse - 待实现"})
	})

	// ============================================================
	// 售后相关
	// ============================================================

	// 接口 20: RenderRefundOrder - 售后渲染预校验
	api.Post("/refund-orders:render", func(c *fiber.Ctx) error {
		// TODO: 实现参数绑定和调用
		return c.JSON(fiber.Map{"message": "RenderRefundOrder - 待实现"})
	})

	// 接口 21: CreateRefundOrder - 创建售后单
	api.Post("/refund-orders", func(c *fiber.Ctx) error {
		// TODO: 实现参数绑定和调用
		return c.JSON(fiber.Map{"message": "CreateRefundOrder - 待实现"})
	})

	// 接口 22: CancelRefundOrder - 取消售后单
	api.Post("/refund-orders/:refundOrderId:cancel", func(c *fiber.Ctx) error {
		// TODO: 实现参数绑定和调用
		return c.JSON(fiber.Map{"message": "CancelRefundOrder - 待实现"})
	})

	// 接口 23: GetRefundOrder - 获取售后单详情
	api.Get("/refund-orders/:refundOrderId", func(c *fiber.Ctx) error {
		// TODO: 实现参数绑定和调用
		return c.JSON(fiber.Map{"message": "GetRefundOrder - 待实现"})
	})

	// 接口 24: CreateGoodsShippingNotice - 回填退货物流运单
	api.Post("/refund-orders/:refundOrderId:fill-logistics", func(c *fiber.Ctx) error {
		// TODO: 实现参数绑定和调用
		return c.JSON(fiber.Map{"message": "CreateGoodsShippingNotice - 待实现"})
	})

	// ============================================================
	// 区域编码
	// ============================================================

	// 接口 25: QueryChildDivisionCode - 查询子区域编码
	api.Get("/divisions:children", func(c *fiber.Ctx) error {
		// TODO: 实现参数绑定和调用
		return c.JSON(fiber.Map{"message": "QueryChildDivisionCode - 待实现"})
	})

	// ============================================================
	// 回调通知供LinkedMall回调
	// ============================================================
	api.Post("/callback", func(c *fiber.Ctx) error {
		// TODO: 实现回调处理逻辑
		return c.JSON(fiber.Map{"success": true})
	})
}

// File: server_tb_LinkedMall/cmd/server/main.go

package main

import (
	"fmt"
	"log"

	"github.com/gofiber/fiber/v2"

	"server_tb_LinkedMall/internal/config"
	"server_tb_LinkedMall/internal/router"
	"server_tb_LinkedMall/internal/service"
)

func main() {
	// 加载配置
	cfg := config.LoadConfig()

	// 检查必要配置
	if cfg.AccessKeyId == "" || cfg.AccessKeySecret == "" {
		log.Fatal("环境变量 LINKEDMALL_AK 和 LINKEDMALL_SK 必须设置")
	}

	// 初始化服务
	svc, err := service.NewLinkedMallService(cfg)
	if err != nil {
		log.Fatalf("初始化服务失败: %v", err)
	}

	// 创建Fiber应用
	app := fiber.New(fiber.Config{
		AppName:      "LinkedMall Server",
		ErrorHandler: func(c *fiber.Ctx, err error) error {
			return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
				"Success": false,
				"Code":    "SERVER_ERROR",
				"Message": err.Error(),
			})
		},
	})

	// 注册路由
	router.SetupRouter(app, svc)

	// 启动服务
	addr := fmt.Sprintf(":%s", cfg.ServerPort)
	log.Printf("启动服务,监听地址: %s", addr)
	if err := app.Listen(addr); err != nil {
		log.Fatalf("服务启动失败: %v", err)
	}
}

// File: server_tb_LinkedMall/internal/test/example_test.go

package test

import (
	"bytes"
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/gofiber/fiber/v2"

	"server_tb_LinkedMall/internal/config"
	"server_tb_LinkedMall/internal/entities"
	"server_tb_LinkedMall/internal/router"
	"server_tb_LinkedMall/internal/service"
)

// setupTestApp 初始化测试应用
func setupTestApp(t *testing.T) (*fiber.App, *service.LinkedMallService) {
	t.Helper()

	cfg := &config.Config{
		ServerPort:         "8080",
		AccessKeyId:        "test-ak",
		AccessKeySecret:    "test-sk",
		RegionId:           "cn-zhangjiakou",
		Endpoint:           "linkedmall.cn-zhangjiakou.aliyuncs.com",
		BasePath:           "/opensaas-s2b/opensaas-s2b-biz-trade/v2",
		DefaultPurchaserId: "test-purchaser-id",
	}

	svc, err := service.NewLinkedMallService(cfg)
	if err != nil {
		t.Skipf("跳过测试无法初始化服务可能需要有效AK/SK: %v", err)
	}

	app := fiber.New()
	router.SetupRouter(app, svc)
	return app, svc
}

// performRequest 执行测试HTTP请求
func performRequest(app *fiber.App, method, path string, body interface{}) *http.Response {
	var reqBody []byte
	if body != nil {
		reqBody, _ = json.Marshal(body)
	}

	req := httptest.NewRequest(method, path, bytes.NewReader(reqBody))
	req.Header.Set("Content-Type", "application/json")

	resp, _ := app.Test(req, -1)
	return resp
}

// TestHealthCheck 健康检查测试
func TestHealthCheck(t *testing.T) {
	app, _ := setupTestApp(t)
	resp