1801 lines
60 KiB
Markdown
1801 lines
60 KiB
Markdown
根据文档分析,该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 |