package service import ( "bytes" "context" "encoding/json" "fmt" "io" "net/http" "time" "go.uber.org/zap" "github.com/topfans/backend/pkg/logger" ) // CompositorClient laser-compositor 合成服务 HTTP 客户端 type CompositorClient struct { BaseURL string HTTPClient *http.Client } // NewCompositorClient 创建 compositor 客户端 func NewCompositorClient(baseURL string) *CompositorClient { return &CompositorClient{ BaseURL: baseURL, HTTPClient: &http.Client{ Timeout: 60 * time.Second, }, } } // ComposeRequest 合成请求(与 compositor 接口对齐) type ComposeRequest struct { BackgroundURL string `json:"background_url"` CutoutURL string `json:"cutout_url"` OverlayURL string `json:"overlay_url"` GratingConfig map[string]interface{} `json:"grating_config"` ExportWidth int `json:"export_width"` ExportHeight int `json:"export_height"` VariantIndex int `json:"variant_index"` OutputOSSKey string `json:"output_oss_key"` } // ComposeResponse 合成响应 type ComposeResponse struct { Status string `json:"status"` VariantIndex int `json:"variant_index"` Width int `json:"width"` Height int `json:"height"` OSSKey string `json:"oss_key"` SignedURL string `json:"signed_url"` Base64 string `json:"base64"` Warning string `json:"warning"` } // Compose 调用 laser-compositor 服务合成单张镭射卡 func (c *CompositorClient) Compose(ctx context.Context, req ComposeRequest) (*ComposeResponse, error) { body, err := json.Marshal(req) if err != nil { return nil, fmt.Errorf("marshal compose request: %w", err) } url := fmt.Sprintf("%s/compose", c.BaseURL) httpReq, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewReader(body)) if err != nil { return nil, fmt.Errorf("create compose request: %w", err) } httpReq.Header.Set("Content-Type", "application/json") resp, err := c.HTTPClient.Do(httpReq) if err != nil { return nil, fmt.Errorf("compositor http: %w", err) } defer resp.Body.Close() respBody, _ := io.ReadAll(resp.Body) var compResp ComposeResponse if err := json.Unmarshal(respBody, &compResp); err != nil { return nil, fmt.Errorf("parse compositor response: %w, body=%s", err, string(respBody)) } logger.Logger.Info("Compositor result", zap.Int("variant_index", compResp.VariantIndex), zap.String("status", compResp.Status), zap.String("oss_key", compResp.OSSKey), ) return &compResp, nil }