Files
rmser/internal/transport/http/handlers/ocr.go
SERTY c8aab42e8e Полноценно редактируются черновики
Добавляются фасовки как в черновике, так и в обучении
Исправил внешний вид
2025-12-17 22:00:21 +03:00

137 lines
4.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package handlers
import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"github.com/shopspring/decimal"
"go.uber.org/zap"
ocrService "rmser/internal/services/ocr"
"rmser/pkg/logger"
)
type OCRHandler struct {
service *ocrService.Service
}
func NewOCRHandler(service *ocrService.Service) *OCRHandler {
return &OCRHandler{service: service}
}
// GetCatalog возвращает список товаров для OCR сервиса
func (h *OCRHandler) GetCatalog(c *gin.Context) {
items, err := h.service.GetCatalogForIndexing()
if err != nil {
logger.Log.Error("Ошибка получения каталога для OCR", zap.Error(err))
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, items)
}
type MatchRequest struct {
RawName string `json:"raw_name" binding:"required"`
ProductID string `json:"product_id" binding:"required"`
Quantity float64 `json:"quantity"`
ContainerID *string `json:"container_id"`
}
// SaveMatch сохраняет привязку (обучение)
func (h *OCRHandler) SaveMatch(c *gin.Context) {
var req MatchRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
pID, err := uuid.Parse(req.ProductID)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid product_id format"})
return
}
qty := decimal.NewFromFloat(1.0)
if req.Quantity > 0 {
qty = decimal.NewFromFloat(req.Quantity)
}
var contID *uuid.UUID
if req.ContainerID != nil && *req.ContainerID != "" {
if uid, err := uuid.Parse(*req.ContainerID); err == nil {
contID = &uid
}
}
if err := h.service.SaveMapping(req.RawName, pID, qty, contID); err != nil {
logger.Log.Error("Ошибка сохранения матчинга", zap.Error(err))
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"status": "saved"})
}
// DeleteMatch удаляет связь
func (h *OCRHandler) DeleteMatch(c *gin.Context) {
// Получаем raw_name из query параметров, так как в URL path могут быть спецсимволы
// Пример: DELETE /api/ocr/match?raw_name=Хлеб%20Бородинский
rawName := c.Query("raw_name")
if rawName == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "raw_name is required"})
return
}
if err := h.service.DeleteMatch(rawName); err != nil {
logger.Log.Error("Ошибка удаления матча", zap.Error(err))
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"status": "deleted"})
}
// SearchProducts ищет товары (для автокомплита)
func (h *OCRHandler) SearchProducts(c *gin.Context) {
query := c.Query("q") // ?q=молоко
if query == "" {
c.JSON(http.StatusOK, []interface{}{})
return
}
products, err := h.service.SearchProducts(query)
if err != nil {
logger.Log.Error("Search error", zap.Error(err))
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// Отдаем на фронт упрощенную структуру или полную, в зависимости от нужд.
// Product entity уже содержит JSON теги, так что можно отдать напрямую.
c.JSON(http.StatusOK, products)
}
// GetMatches возвращает список всех обученных связей
func (h *OCRHandler) GetMatches(c *gin.Context) {
matches, err := h.service.GetKnownMatches()
if err != nil {
logger.Log.Error("Ошибка получения списка матчей", zap.Error(err))
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, matches)
}
// GetUnmatched возвращает список нераспознанных позиций для подсказок
func (h *OCRHandler) GetUnmatched(c *gin.Context) {
items, err := h.service.GetUnmatchedItems()
if err != nil {
logger.Log.Error("Ошибка получения списка unmatched", zap.Error(err))
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, items)
}