实现ai
This commit is contained in:
@@ -261,6 +261,7 @@ func (a *API) setupRoutes() {
|
||||
feedGroup.GET("/recipes", a.recipeController.ListRecipes)
|
||||
feedGroup.POST("/recipes/generate-from-all-materials/:pig_type_id", a.recipeController.GenerateFromAllMaterials)
|
||||
feedGroup.POST("/recipes/generate-prioritized-stock/:pig_type_id", a.recipeController.GenerateRecipeWithPrioritizedStockRawMaterials)
|
||||
feedGroup.GET("/recipes/:id/ai-diagnose", a.recipeController.AIDiagnoseRecipe)
|
||||
}
|
||||
logger.Debug("饲料管理相关接口注册成功 (需要认证和审计)")
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package feed
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"git.huangwc.com/pig/pig-farm-controller/internal/app/controller"
|
||||
@@ -256,3 +257,48 @@ func (c *RecipeController) GenerateRecipeWithPrioritizedStockRawMaterials(ctx ec
|
||||
logger.Infof("%s: 配方生成成功, 新配方ID: %d", actionType, resp.ID)
|
||||
return controller.SendSuccessWithAudit(ctx, controller.CodeCreated, "配方生成成功", resp, actionType, "配方生成成功", resp)
|
||||
}
|
||||
|
||||
// AIDiagnoseRecipe godoc
|
||||
// @Summary AI点评配方
|
||||
// @Description 使用AI对指定配方进行点评,并针对目标猪类型给出建议。
|
||||
// @Tags 饲料管理-配方
|
||||
// @Security BearerAuth
|
||||
// @Produce json
|
||||
// @Param id path int true "配方ID"
|
||||
// @Param pig_type_id query int true "猪类型ID"
|
||||
// @Success 200 {object} controller.Response{data=dto.ReviewRecipeResponse} "业务码为200代表AI点评成功"
|
||||
// @Router /api/v1/feed/recipes/{id}/ai-diagnose [get]
|
||||
func (c *RecipeController) AIDiagnoseRecipe(ctx echo.Context) error {
|
||||
reqCtx, logger := logs.Trace(ctx.Request().Context(), c.ctx, "AIDiagnoseRecipe")
|
||||
const actionType = "AI点评配方"
|
||||
fmt.Println("xxx")
|
||||
// 从路径参数中获取配方ID
|
||||
recipeIDStr := ctx.Param("id")
|
||||
recipeID, err := strconv.ParseUint(recipeIDStr, 10, 32)
|
||||
if err != nil {
|
||||
logger.Errorf("%s: 配方ID格式错误: %v, ID: %s", actionType, err, recipeIDStr)
|
||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的配方ID格式", actionType, "配方ID格式错误", recipeIDStr)
|
||||
}
|
||||
|
||||
// 从查询参数中获取猪类型ID
|
||||
pigTypeIDStr := ctx.QueryParam("pig_type_id")
|
||||
pigTypeID, err := strconv.ParseUint(pigTypeIDStr, 10, 32)
|
||||
if err != nil {
|
||||
logger.Errorf("%s: 猪类型ID格式错误: %v, ID: %s", actionType, err, pigTypeIDStr)
|
||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的猪类型ID格式", actionType, "猪类型ID格式错误", pigTypeIDStr)
|
||||
}
|
||||
|
||||
// 调用应用服务进行AI点评
|
||||
reviewResponse, err := c.recipeService.AIDiagnoseRecipe(reqCtx, uint32(recipeID), uint32(pigTypeID))
|
||||
if err != nil {
|
||||
logger.Errorf("%s: 服务层AI点评失败: %v, RecipeID: %d, PigTypeID: %d", actionType, err, recipeID, pigTypeID)
|
||||
if errors.Is(err, service.ErrRecipeNotFound) {
|
||||
return controller.SendErrorWithAudit(ctx, controller.CodeNotFound, err.Error(), actionType, "配方或猪类型不存在", map[string]uint32{"recipe_id": uint32(recipeID), "pig_type_id": uint32(pigTypeID)})
|
||||
}
|
||||
// 对于其他错误,统一返回内部服务器错误
|
||||
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "AI点评失败: "+err.Error(), actionType, "服务层AI点评失败", map[string]uint32{"recipe_id": uint32(recipeID), "pig_type_id": uint32(pigTypeID)})
|
||||
}
|
||||
|
||||
logger.Infof("%s: AI点评成功, RecipeID: %d, PigTypeID: %d", actionType, recipeID, pigTypeID)
|
||||
return controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "AI点评成功", reviewResponse, actionType, "AI点评成功", reviewResponse)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package dto
|
||||
|
||||
import "git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
|
||||
|
||||
// =============================================================================================================
|
||||
// 营养种类 (Nutrient) 相关 DTO
|
||||
// =============================================================================================================
|
||||
@@ -335,3 +337,14 @@ type GenerateRecipeResponse struct {
|
||||
Name string `json:"name"` // 新生成的配方名称
|
||||
Description string `json:"description"` // 新生成的配方描述
|
||||
}
|
||||
|
||||
// ReviewRecipeRequest 定义了点评配方的请求体
|
||||
type ReviewRecipeRequest struct {
|
||||
PigTypeID uint32 `json:"pig_type_id" binding:"required"` // 猪类型ID
|
||||
}
|
||||
|
||||
// ReviewRecipeResponse 定义了点评配方的响应体
|
||||
type ReviewRecipeResponse struct {
|
||||
ReviewMessage string `json:"review_message"` // 点评内容
|
||||
AIModel models.AIModel `json:"ai_model"` // 使用的 AI 模型
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ type RecipeService interface {
|
||||
GenerateRecipeWithAllRawMaterials(ctx context.Context, pigTypeID uint32) (*models.Recipe, error)
|
||||
// GenerateRecipeWithPrioritizedStockRawMaterials 生成新配方,优先使用有库存的原料
|
||||
GenerateRecipeWithPrioritizedStockRawMaterials(ctx context.Context, pigTypeID uint32) (*models.Recipe, error)
|
||||
// AIDiagnoseRecipe 智能诊断配方, 返回智能诊断结果和使用的AI模型
|
||||
AIDiagnoseRecipe(ctx context.Context, recipeID uint32, pigTypeID uint32) (*dto.ReviewRecipeResponse, error)
|
||||
}
|
||||
|
||||
// recipeServiceImpl 是 RecipeService 接口的实现
|
||||
@@ -175,3 +177,18 @@ func (s *recipeServiceImpl) ListRecipes(ctx context.Context, req *dto.ListRecipe
|
||||
|
||||
return dto.ConvertRecipeListToDTO(recipes, total, req.Page, req.PageSize), nil
|
||||
}
|
||||
|
||||
// AIDiagnoseRecipe 实现智能诊断配方的方法
|
||||
func (s *recipeServiceImpl) AIDiagnoseRecipe(ctx context.Context, recipeID uint32, pigTypeID uint32) (*dto.ReviewRecipeResponse, error) {
|
||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "AIDiagnoseRecipe")
|
||||
|
||||
reviewMessage, aiModel, err := s.recipeSvc.AIDiagnoseRecipe(serviceCtx, recipeID, pigTypeID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("AI 诊断配方失败: %w", err)
|
||||
}
|
||||
|
||||
return &dto.ReviewRecipeResponse{
|
||||
ReviewMessage: reviewMessage,
|
||||
AIModel: aiModel,
|
||||
}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user