package services import ( "ai_scheduler/internal/config" "ai_scheduler/internal/data/constants" errorcode "ai_scheduler/internal/data/error" "ai_scheduler/internal/domain/workflow/runtime" "ai_scheduler/internal/entitys" "ai_scheduler/internal/pkg/util" "ai_scheduler/internal/pkg/utils_ollama" "context" "fmt" "strings" "time" "github.com/gofiber/fiber/v2" "github.com/ollama/ollama/api" ) // CapabilityService 统一回调入口 type CapabilityService struct { cfg *config.Config workflowManager *runtime.Registry } func NewCapabilityService(cfg *config.Config, workflowManager *runtime.Registry) *CapabilityService { return &CapabilityService{ cfg: cfg, workflowManager: workflowManager, } } // 产品数据提取入参 type ProductIngestReq struct { Url string `json:"url"` // 商品详情页URL Title string `json:"title"` // 商品标题 Text string `json:"text"` // 商品描述 Images []string `json:"images"` // 商品图片URL列表 Timestamp int64 `json:"timestamp"` // 商品发布时间戳 } // ProductIngest 产品数据提取 func (s *CapabilityService) ProductIngest(c *fiber.Ctx) error { // 请求头校验 if err := s.checkRequestHeader(c); err != nil { return err } // 解析请求参数 req := ProductIngestReq{} if err := c.BodyParser(&req); err != nil { return errorcode.ParamErr("invalid request body: %v", err) } // 必要参数校验 if req.Text == "" { return errorcode.ParamErr("missing required fields") } // 模型调用 client, cleanup, err := utils_ollama.NewClient(s.cfg) if err != nil { return err } defer cleanup() res, err := client.Chat(context.Background(), []api.Message{ { Role: "system", Content: fmt.Sprintf(constants.SystemPrompt, constants.HYTProductPropertyTemplateZH), }, { Role: "user", Content: req.Text, }, { Role: "user", Content: "商品图片URL列表:" + strings.Join(req.Images, ","), }, }) if err != nil { return err } // res.Message.Content Go中map会无序,交给前端解析 // 解析模型输出 c.JSON(res.Message.Content) return nil } // checkRequestHeader 校验请求头 func (s *CapabilityService) checkRequestHeader(c *fiber.Ctx) error { // 读取头 token := strings.TrimSpace(c.Get("X-Source-Key")) ts := strings.TrimSpace(c.Get("X-Timestamp")) // 时间窗口校验 if ts != "" && !util.IsInTimeWindow(ts, 5*time.Minute) { return errorcode.AuthNotFound } // token校验 if token == "" || token != "A7f9KQ3mP2X8LZC4R5e" { return errorcode.KeyErr() } return nil } // ProductUploadHyt 商品上传至货易通 func (s *CapabilityService) ProductUploadHyt(c *fiber.Ctx) error { // 请求头校验 if err := s.checkRequestHeader(c); err != nil { return err } // 获取 body json 串 raw := append([]byte(nil), c.BodyRaw()...) bodyStr := string(raw) // 调用eino工作流,实现商品上传到货易通 workflowId := "hyt.productUpload" rec := &entitys.Recognize{UserContent: &entitys.RecognizeUserContent{Text: bodyStr}} res, err := s.workflowManager.Invoke(context.Background(), workflowId, rec) if err != nil { return err } return c.JSON(res) }