根据文档分析,该API使用阿里云Darabonba OpenAPI SDK进行ROA签名调用(SDK内部自动处理签名),无需额外加密工具。我将直接生成所有代码文件。 --- // File: server_tb_LinkedMall/go.mod ```go 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 ```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 ```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 ```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 ```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 ```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 ```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 ```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 ```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 ```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 ```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