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) }