重构配方类服务层
This commit is contained in:
@@ -56,7 +56,6 @@ type API struct {
|
|||||||
monitorController *monitor.Controller // 数据监控控制器实例
|
monitorController *monitor.Controller // 数据监控控制器实例
|
||||||
healthController *health.Controller // 健康检查控制器实例
|
healthController *health.Controller // 健康检查控制器实例
|
||||||
alarmController *alarm.ThresholdAlarmController // 阈值告警控制器
|
alarmController *alarm.ThresholdAlarmController // 阈值告警控制器
|
||||||
feedController *feed.Controller // 饲料管理控制器实例
|
|
||||||
nutrientController *feed.NutrientController // 营养控制器实例
|
nutrientController *feed.NutrientController // 营养控制器实例
|
||||||
pigAgeStageController *feed.PigAgeStageController // 猪龄阶段控制器实例
|
pigAgeStageController *feed.PigAgeStageController // 猪龄阶段控制器实例
|
||||||
pigBreedController *feed.PigBreedController // 猪品种控制器实例
|
pigBreedController *feed.PigBreedController // 猪品种控制器实例
|
||||||
@@ -79,7 +78,11 @@ func NewAPI(cfg config.ServerConfig,
|
|||||||
userService service.UserService,
|
userService service.UserService,
|
||||||
auditService service.AuditService,
|
auditService service.AuditService,
|
||||||
alarmService service.ThresholdAlarmService,
|
alarmService service.ThresholdAlarmService,
|
||||||
feedManagementService service.FeedManagementService,
|
nutrientService service.NutrientService,
|
||||||
|
rawMaterialService service.RawMaterialService,
|
||||||
|
pigBreedService service.PigBreedService,
|
||||||
|
pigAgeStageService service.PigAgeStageService,
|
||||||
|
pigTypeService service.PigTypeService,
|
||||||
tokenGenerator token.Generator,
|
tokenGenerator token.Generator,
|
||||||
listenHandler webhook.ListenHandler,
|
listenHandler webhook.ListenHandler,
|
||||||
) *API {
|
) *API {
|
||||||
@@ -111,12 +114,11 @@ func NewAPI(cfg config.ServerConfig,
|
|||||||
monitorController: monitor.NewController(logs.AddCompName(baseCtx, "MonitorController"), monitorService),
|
monitorController: monitor.NewController(logs.AddCompName(baseCtx, "MonitorController"), monitorService),
|
||||||
healthController: health.NewController(logs.AddCompName(baseCtx, "HealthController")),
|
healthController: health.NewController(logs.AddCompName(baseCtx, "HealthController")),
|
||||||
alarmController: alarm.NewThresholdAlarmController(logs.AddCompName(baseCtx, "ThresholdAlarmController"), alarmService),
|
alarmController: alarm.NewThresholdAlarmController(logs.AddCompName(baseCtx, "ThresholdAlarmController"), alarmService),
|
||||||
feedController: feed.NewController(logs.AddCompName(baseCtx, "FeedController"), feedManagementService),
|
nutrientController: feed.NewNutrientController(logs.AddCompName(baseCtx, "NutrientController"), nutrientService),
|
||||||
nutrientController: feed.NewNutrientController(logs.AddCompName(baseCtx, "NutrientController"), feedManagementService),
|
pigAgeStageController: feed.NewPigAgeStageController(logs.AddCompName(baseCtx, "PigAgeStageController"), pigAgeStageService),
|
||||||
pigAgeStageController: feed.NewPigAgeStageController(logs.AddCompName(baseCtx, "PigAgeStageController"), feedManagementService),
|
pigBreedController: feed.NewPigBreedController(logs.AddCompName(baseCtx, "PigBreedController"), pigBreedService),
|
||||||
pigBreedController: feed.NewPigBreedController(logs.AddCompName(baseCtx, "PigBreedController"), feedManagementService),
|
pigTypeController: feed.NewPigTypeController(logs.AddCompName(baseCtx, "PigTypeController"), pigTypeService),
|
||||||
pigTypeController: feed.NewPigTypeController(logs.AddCompName(baseCtx, "PigTypeController"), feedManagementService),
|
rawMaterialController: feed.NewRawMaterialController(logs.AddCompName(baseCtx, "RawMaterialController"), rawMaterialService),
|
||||||
rawMaterialController: feed.NewRawMaterialController(logs.AddCompName(baseCtx, "RawMaterialController"), feedManagementService),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
api.setupRoutes() // 设置所有路由
|
api.setupRoutes() // 设置所有路由
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
package feed
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.huangwc.com/pig/pig-farm-controller/internal/app/service"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Controller 定义了饲料管理相关的控制器,作为各个子控制器的入口
|
|
||||||
type Controller struct {
|
|
||||||
ctx context.Context
|
|
||||||
feedManagementService service.FeedManagementService
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewController 创建一个新的 Controller 实例
|
|
||||||
func NewController(ctx context.Context, feedManagementService service.FeedManagementService) *Controller {
|
|
||||||
return &Controller{
|
|
||||||
ctx: ctx,
|
|
||||||
feedManagementService: feedManagementService,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -15,15 +15,15 @@ import (
|
|||||||
|
|
||||||
// NutrientController 定义了营养种类相关的控制器
|
// NutrientController 定义了营养种类相关的控制器
|
||||||
type NutrientController struct {
|
type NutrientController struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
feedManagementService service.FeedManagementService
|
nutrientService service.NutrientService
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNutrientController 创建一个新的 NutrientController 实例
|
// NewNutrientController 创建一个新的 NutrientController 实例
|
||||||
func NewNutrientController(ctx context.Context, feedManagementService service.FeedManagementService) *NutrientController {
|
func NewNutrientController(ctx context.Context, feedManagementService service.NutrientService) *NutrientController {
|
||||||
return &NutrientController{
|
return &NutrientController{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
feedManagementService: feedManagementService,
|
nutrientService: feedManagementService,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ func (c *NutrientController) CreateNutrient(ctx echo.Context) error {
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.feedManagementService.CreateNutrient(reqCtx, &req)
|
resp, err := c.nutrientService.CreateNutrient(reqCtx, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层创建营养种类失败: %v", actionType, err)
|
logger.Errorf("%s: 服务层创建营养种类失败: %v", actionType, err)
|
||||||
if errors.Is(err, service.ErrNutrientNameConflict) {
|
if errors.Is(err, service.ErrNutrientNameConflict) {
|
||||||
@@ -86,7 +86,7 @@ func (c *NutrientController) UpdateNutrient(ctx echo.Context) error {
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.feedManagementService.UpdateNutrient(reqCtx, uint32(id), &req)
|
resp, err := c.nutrientService.UpdateNutrient(reqCtx, uint32(id), &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层更新营养种类失败: %v, ID: %d", actionType, err, id)
|
logger.Errorf("%s: 服务层更新营养种类失败: %v, ID: %d", actionType, err, id)
|
||||||
if errors.Is(err, service.ErrNutrientNotFound) {
|
if errors.Is(err, service.ErrNutrientNotFound) {
|
||||||
@@ -121,7 +121,7 @@ func (c *NutrientController) DeleteNutrient(ctx echo.Context) error {
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的营养种类ID格式", actionType, "营养种类ID格式错误", idStr)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的营养种类ID格式", actionType, "营养种类ID格式错误", idStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.feedManagementService.DeleteNutrient(reqCtx, uint32(id))
|
err = c.nutrientService.DeleteNutrient(reqCtx, uint32(id))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层删除营养种类失败: %v, ID: %d", actionType, err, id)
|
logger.Errorf("%s: 服务层删除营养种类失败: %v, ID: %d", actionType, err, id)
|
||||||
if errors.Is(err, service.ErrNutrientNotFound) {
|
if errors.Is(err, service.ErrNutrientNotFound) {
|
||||||
@@ -153,7 +153,7 @@ func (c *NutrientController) GetNutrient(ctx echo.Context) error {
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的营养种类ID格式", actionType, "营养种类ID格式错误", idStr)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的营养种类ID格式", actionType, "营养种类ID格式错误", idStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.feedManagementService.GetNutrient(reqCtx, uint32(id))
|
resp, err := c.nutrientService.GetNutrient(reqCtx, uint32(id))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层获取营养种类详情失败: %v, ID: %d", actionType, err, id)
|
logger.Errorf("%s: 服务层获取营养种类详情失败: %v, ID: %d", actionType, err, id)
|
||||||
if errors.Is(err, service.ErrNutrientNotFound) {
|
if errors.Is(err, service.ErrNutrientNotFound) {
|
||||||
@@ -184,7 +184,7 @@ func (c *NutrientController) ListNutrients(ctx echo.Context) error {
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的查询参数: "+err.Error(), actionType, "查询参数绑定失败", req)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的查询参数: "+err.Error(), actionType, "查询参数绑定失败", req)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.feedManagementService.ListNutrients(reqCtx, &req)
|
resp, err := c.nutrientService.ListNutrients(reqCtx, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层获取营养种类列表失败: %v", actionType, err)
|
logger.Errorf("%s: 服务层获取营养种类列表失败: %v", actionType, err)
|
||||||
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取营养种类列表失败: "+err.Error(), actionType, "服务层获取营养种类列表失败", nil)
|
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取营养种类列表失败: "+err.Error(), actionType, "服务层获取营养种类列表失败", nil)
|
||||||
|
|||||||
@@ -15,15 +15,15 @@ import (
|
|||||||
|
|
||||||
// PigAgeStageController 定义了猪年龄阶段相关的控制器
|
// PigAgeStageController 定义了猪年龄阶段相关的控制器
|
||||||
type PigAgeStageController struct {
|
type PigAgeStageController struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
feedManagementService service.FeedManagementService
|
pigAgeStageService service.PigAgeStageService
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPigAgeStageController 创建一个新的 PigAgeStageController 实例
|
// NewPigAgeStageController 创建一个新的 PigAgeStageController 实例
|
||||||
func NewPigAgeStageController(ctx context.Context, feedManagementService service.FeedManagementService) *PigAgeStageController {
|
func NewPigAgeStageController(ctx context.Context, feedManagementService service.PigAgeStageService) *PigAgeStageController {
|
||||||
return &PigAgeStageController{
|
return &PigAgeStageController{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
feedManagementService: feedManagementService,
|
pigAgeStageService: feedManagementService,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ func (c *PigAgeStageController) CreatePigAgeStage(ctx echo.Context) error {
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.feedManagementService.CreatePigAgeStage(reqCtx, &req)
|
resp, err := c.pigAgeStageService.CreatePigAgeStage(reqCtx, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层创建猪年龄阶段失败: %v", actionType, err)
|
logger.Errorf("%s: 服务层创建猪年龄阶段失败: %v", actionType, err)
|
||||||
// 猪年龄阶段没有名称冲突的领域错误,这里直接返回内部错误
|
// 猪年龄阶段没有名称冲突的领域错误,这里直接返回内部错误
|
||||||
@@ -84,7 +84,7 @@ func (c *PigAgeStageController) UpdatePigAgeStage(ctx echo.Context) error {
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.feedManagementService.UpdatePigAgeStage(reqCtx, uint32(id), &req)
|
resp, err := c.pigAgeStageService.UpdatePigAgeStage(reqCtx, uint32(id), &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层更新猪年龄阶段失败: %v, ID: %d", actionType, err, id)
|
logger.Errorf("%s: 服务层更新猪年龄阶段失败: %v, ID: %d", actionType, err, id)
|
||||||
if errors.Is(err, service.ErrPigAgeStageNotFound) {
|
if errors.Is(err, service.ErrPigAgeStageNotFound) {
|
||||||
@@ -116,7 +116,7 @@ func (c *PigAgeStageController) DeletePigAgeStage(ctx echo.Context) error {
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的猪年龄阶段ID格式", actionType, "猪年龄阶段ID格式错误", idStr)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的猪年龄阶段ID格式", actionType, "猪年龄阶段ID格式错误", idStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.feedManagementService.DeletePigAgeStage(reqCtx, uint32(id))
|
err = c.pigAgeStageService.DeletePigAgeStage(reqCtx, uint32(id))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层删除猪年龄阶段失败: %v, ID: %d", actionType, err, id)
|
logger.Errorf("%s: 服务层删除猪年龄阶段失败: %v, ID: %d", actionType, err, id)
|
||||||
if errors.Is(err, service.ErrPigAgeStageNotFound) {
|
if errors.Is(err, service.ErrPigAgeStageNotFound) {
|
||||||
@@ -151,7 +151,7 @@ func (c *PigAgeStageController) GetPigAgeStage(ctx echo.Context) error {
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的猪年龄阶段ID格式", actionType, "猪年龄阶段ID格式错误", idStr)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的猪年龄阶段ID格式", actionType, "猪年龄阶段ID格式错误", idStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.feedManagementService.GetPigAgeStage(reqCtx, uint32(id))
|
resp, err := c.pigAgeStageService.GetPigAgeStage(reqCtx, uint32(id))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层获取猪年龄阶段详情失败: %v, ID: %d", actionType, err, id)
|
logger.Errorf("%s: 服务层获取猪年龄阶段详情失败: %v, ID: %d", actionType, err, id)
|
||||||
if errors.Is(err, service.ErrPigAgeStageNotFound) {
|
if errors.Is(err, service.ErrPigAgeStageNotFound) {
|
||||||
@@ -182,7 +182,7 @@ func (c *PigAgeStageController) ListPigAgeStages(ctx echo.Context) error {
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的查询参数: "+err.Error(), actionType, "查询参数绑定失败", req)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的查询参数: "+err.Error(), actionType, "查询参数绑定失败", req)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.feedManagementService.ListPigAgeStages(reqCtx, &req)
|
resp, err := c.pigAgeStageService.ListPigAgeStages(reqCtx, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层获取猪年龄阶段列表失败: %v", actionType, err)
|
logger.Errorf("%s: 服务层获取猪年龄阶段列表失败: %v", actionType, err)
|
||||||
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取猪年龄阶段列表失败: "+err.Error(), actionType, "服务层获取猪年龄阶段列表失败", nil)
|
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取猪年龄阶段列表失败: "+err.Error(), actionType, "服务层获取猪年龄阶段列表失败", nil)
|
||||||
|
|||||||
@@ -15,15 +15,15 @@ import (
|
|||||||
|
|
||||||
// PigBreedController 定义了猪品种相关的控制器
|
// PigBreedController 定义了猪品种相关的控制器
|
||||||
type PigBreedController struct {
|
type PigBreedController struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
feedManagementService service.FeedManagementService
|
pigBreedService service.PigBreedService
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPigBreedController 创建一个新的 PigBreedController 实例
|
// NewPigBreedController 创建一个新的 PigBreedController 实例
|
||||||
func NewPigBreedController(ctx context.Context, feedManagementService service.FeedManagementService) *PigBreedController {
|
func NewPigBreedController(ctx context.Context, feedManagementService service.PigBreedService) *PigBreedController {
|
||||||
return &PigBreedController{
|
return &PigBreedController{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
feedManagementService: feedManagementService,
|
pigBreedService: feedManagementService,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ func (c *PigBreedController) CreatePigBreed(ctx echo.Context) error {
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.feedManagementService.CreatePigBreed(reqCtx, &req)
|
resp, err := c.pigBreedService.CreatePigBreed(reqCtx, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层创建猪品种失败: %v", actionType, err)
|
logger.Errorf("%s: 服务层创建猪品种失败: %v", actionType, err)
|
||||||
// 猪品种没有名称冲突的领域错误,这里直接返回内部错误
|
// 猪品种没有名称冲突的领域错误,这里直接返回内部错误
|
||||||
@@ -84,7 +84,7 @@ func (c *PigBreedController) UpdatePigBreed(ctx echo.Context) error {
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.feedManagementService.UpdatePigBreed(reqCtx, uint32(id), &req)
|
resp, err := c.pigBreedService.UpdatePigBreed(reqCtx, uint32(id), &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层更新猪品种失败: %v, ID: %d", actionType, err, id)
|
logger.Errorf("%s: 服务层更新猪品种失败: %v, ID: %d", actionType, err, id)
|
||||||
if errors.Is(err, service.ErrPigBreedNotFound) {
|
if errors.Is(err, service.ErrPigBreedNotFound) {
|
||||||
@@ -116,7 +116,7 @@ func (c *PigBreedController) DeletePigBreed(ctx echo.Context) error {
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的猪品种ID格式", actionType, "猪品种ID格式错误", idStr)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的猪品种ID格式", actionType, "猪品种ID格式错误", idStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.feedManagementService.DeletePigBreed(reqCtx, uint32(id))
|
err = c.pigBreedService.DeletePigBreed(reqCtx, uint32(id))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层删除猪品种失败: %v, ID: %d", actionType, err, id)
|
logger.Errorf("%s: 服务层删除猪品种失败: %v, ID: %d", actionType, err, id)
|
||||||
if errors.Is(err, service.ErrPigBreedNotFound) {
|
if errors.Is(err, service.ErrPigBreedNotFound) {
|
||||||
@@ -151,7 +151,7 @@ func (c *PigBreedController) GetPigBreed(ctx echo.Context) error {
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的猪品种ID格式", actionType, "猪品种ID格式错误", idStr)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的猪品种ID格式", actionType, "猪品种ID格式错误", idStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.feedManagementService.GetPigBreed(reqCtx, uint32(id))
|
resp, err := c.pigBreedService.GetPigBreed(reqCtx, uint32(id))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层获取猪品种详情失败: %v, ID: %d", actionType, err, id)
|
logger.Errorf("%s: 服务层获取猪品种详情失败: %v, ID: %d", actionType, err, id)
|
||||||
if errors.Is(err, service.ErrPigBreedNotFound) {
|
if errors.Is(err, service.ErrPigBreedNotFound) {
|
||||||
@@ -182,7 +182,7 @@ func (c *PigBreedController) ListPigBreeds(ctx echo.Context) error {
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的查询参数: "+err.Error(), actionType, "查询参数绑定失败", req)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的查询参数: "+err.Error(), actionType, "查询参数绑定失败", req)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.feedManagementService.ListPigBreeds(reqCtx, &req)
|
resp, err := c.pigBreedService.ListPigBreeds(reqCtx, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层获取猪品种列表失败: %v", actionType, err)
|
logger.Errorf("%s: 服务层获取猪品种列表失败: %v", actionType, err)
|
||||||
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取猪品种列表失败: "+err.Error(), actionType, "服务层获取猪品种列表失败", nil)
|
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取猪品种列表失败: "+err.Error(), actionType, "服务层获取猪品种列表失败", nil)
|
||||||
|
|||||||
@@ -15,15 +15,15 @@ import (
|
|||||||
|
|
||||||
// PigTypeController 定义了猪类型相关的控制器
|
// PigTypeController 定义了猪类型相关的控制器
|
||||||
type PigTypeController struct {
|
type PigTypeController struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
feedManagementService service.FeedManagementService
|
typeService service.PigTypeService
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPigTypeController 创建一个新的 PigTypeController 实例
|
// NewPigTypeController 创建一个新的 PigTypeController 实例
|
||||||
func NewPigTypeController(ctx context.Context, feedManagementService service.FeedManagementService) *PigTypeController {
|
func NewPigTypeController(ctx context.Context, feedManagementService service.PigTypeService) *PigTypeController {
|
||||||
return &PigTypeController{
|
return &PigTypeController{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
feedManagementService: feedManagementService,
|
typeService: feedManagementService,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ func (c *PigTypeController) CreatePigType(ctx echo.Context) error {
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.feedManagementService.CreatePigType(reqCtx, &req)
|
resp, err := c.typeService.CreatePigType(reqCtx, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层创建猪类型失败: %v", actionType, err)
|
logger.Errorf("%s: 服务层创建猪类型失败: %v", actionType, err)
|
||||||
if errors.Is(err, service.ErrPigBreedNotFound) {
|
if errors.Is(err, service.ErrPigBreedNotFound) {
|
||||||
@@ -89,7 +89,7 @@ func (c *PigTypeController) UpdatePigType(ctx echo.Context) error {
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.feedManagementService.UpdatePigType(reqCtx, uint32(id), &req)
|
resp, err := c.typeService.UpdatePigType(reqCtx, uint32(id), &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层更新猪类型失败: %v, ID: %d", actionType, err, id)
|
logger.Errorf("%s: 服务层更新猪类型失败: %v, ID: %d", actionType, err, id)
|
||||||
if errors.Is(err, service.ErrPigTypeNotFound) {
|
if errors.Is(err, service.ErrPigTypeNotFound) {
|
||||||
@@ -127,7 +127,7 @@ func (c *PigTypeController) DeletePigType(ctx echo.Context) error {
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的猪类型ID格式", actionType, "猪类型ID格式错误", idStr)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的猪类型ID格式", actionType, "猪类型ID格式错误", idStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.feedManagementService.DeletePigType(reqCtx, uint32(id))
|
err = c.typeService.DeletePigType(reqCtx, uint32(id))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层删除猪类型失败: %v, ID: %d", actionType, err, id)
|
logger.Errorf("%s: 服务层删除猪类型失败: %v, ID: %d", actionType, err, id)
|
||||||
if errors.Is(err, service.ErrPigTypeNotFound) {
|
if errors.Is(err, service.ErrPigTypeNotFound) {
|
||||||
@@ -159,7 +159,7 @@ func (c *PigTypeController) GetPigType(ctx echo.Context) error {
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的猪类型ID格式", actionType, "猪类型ID格式错误", idStr)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的猪类型ID格式", actionType, "猪类型ID格式错误", idStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.feedManagementService.GetPigType(reqCtx, uint32(id))
|
resp, err := c.typeService.GetPigType(reqCtx, uint32(id))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层获取猪类型详情失败: %v, ID: %d", actionType, err, id)
|
logger.Errorf("%s: 服务层获取猪类型详情失败: %v, ID: %d", actionType, err, id)
|
||||||
if errors.Is(err, service.ErrPigTypeNotFound) {
|
if errors.Is(err, service.ErrPigTypeNotFound) {
|
||||||
@@ -190,7 +190,7 @@ func (c *PigTypeController) ListPigTypes(ctx echo.Context) error {
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的查询参数: "+err.Error(), actionType, "查询参数绑定失败", req)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的查询参数: "+err.Error(), actionType, "查询参数绑定失败", req)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.feedManagementService.ListPigTypes(reqCtx, &req)
|
resp, err := c.typeService.ListPigTypes(reqCtx, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层获取猪类型列表失败: %v", actionType, err)
|
logger.Errorf("%s: 服务层获取猪类型列表失败: %v", actionType, err)
|
||||||
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取猪类型列表失败: "+err.Error(), actionType, "服务层获取猪类型列表失败", nil)
|
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取猪类型列表失败: "+err.Error(), actionType, "服务层获取猪类型列表失败", nil)
|
||||||
@@ -228,7 +228,7 @@ func (c *PigTypeController) UpdatePigTypeNutrientRequirements(ctx echo.Context)
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.feedManagementService.UpdatePigTypeNutrientRequirements(reqCtx, uint32(id), &req)
|
resp, err := c.typeService.UpdatePigTypeNutrientRequirements(reqCtx, uint32(id), &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层更新猪类型营养需求失败: %v, ID: %d", actionType, err, id)
|
logger.Errorf("%s: 服务层更新猪类型营养需求失败: %v, ID: %d", actionType, err, id)
|
||||||
if errors.Is(err, service.ErrPigTypeNotFound) {
|
if errors.Is(err, service.ErrPigTypeNotFound) {
|
||||||
|
|||||||
@@ -15,15 +15,15 @@ import (
|
|||||||
|
|
||||||
// RawMaterialController 定义了原料相关的控制器
|
// RawMaterialController 定义了原料相关的控制器
|
||||||
type RawMaterialController struct {
|
type RawMaterialController struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
feedManagementService service.FeedManagementService
|
rawMaterialService service.RawMaterialService
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRawMaterialController 创建一个新的 RawMaterialController 实例
|
// NewRawMaterialController 创建一个新的 RawMaterialController 实例
|
||||||
func NewRawMaterialController(ctx context.Context, feedManagementService service.FeedManagementService) *RawMaterialController {
|
func NewRawMaterialController(ctx context.Context, feedManagementService service.RawMaterialService) *RawMaterialController {
|
||||||
return &RawMaterialController{
|
return &RawMaterialController{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
feedManagementService: feedManagementService,
|
rawMaterialService: feedManagementService,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ func (c *RawMaterialController) CreateRawMaterial(ctx echo.Context) error {
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.feedManagementService.CreateRawMaterial(reqCtx, &req)
|
resp, err := c.rawMaterialService.CreateRawMaterial(reqCtx, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层创建原料失败: %v", actionType, err)
|
logger.Errorf("%s: 服务层创建原料失败: %v", actionType, err)
|
||||||
if errors.Is(err, service.ErrRawMaterialNameConflict) {
|
if errors.Is(err, service.ErrRawMaterialNameConflict) {
|
||||||
@@ -86,7 +86,7 @@ func (c *RawMaterialController) UpdateRawMaterial(ctx echo.Context) error {
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.feedManagementService.UpdateRawMaterial(reqCtx, uint32(id), &req)
|
resp, err := c.rawMaterialService.UpdateRawMaterial(reqCtx, uint32(id), &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层更新原料失败: %v, ID: %d", actionType, err, id)
|
logger.Errorf("%s: 服务层更新原料失败: %v, ID: %d", actionType, err, id)
|
||||||
if errors.Is(err, service.ErrRawMaterialNotFound) {
|
if errors.Is(err, service.ErrRawMaterialNotFound) {
|
||||||
@@ -121,7 +121,7 @@ func (c *RawMaterialController) DeleteRawMaterial(ctx echo.Context) error {
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的原料ID格式", actionType, "原料ID格式错误", idStr)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的原料ID格式", actionType, "原料ID格式错误", idStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.feedManagementService.DeleteRawMaterial(reqCtx, uint32(id))
|
err = c.rawMaterialService.DeleteRawMaterial(reqCtx, uint32(id))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层删除原料失败: %v, ID: %d", actionType, err, id)
|
logger.Errorf("%s: 服务层删除原料失败: %v, ID: %d", actionType, err, id)
|
||||||
if errors.Is(err, service.ErrRawMaterialNotFound) {
|
if errors.Is(err, service.ErrRawMaterialNotFound) {
|
||||||
@@ -153,7 +153,7 @@ func (c *RawMaterialController) GetRawMaterial(ctx echo.Context) error {
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的原料ID格式", actionType, "原料ID格式错误", idStr)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的原料ID格式", actionType, "原料ID格式错误", idStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.feedManagementService.GetRawMaterial(reqCtx, uint32(id))
|
resp, err := c.rawMaterialService.GetRawMaterial(reqCtx, uint32(id))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层获取原料详情失败: %v, ID: %d", actionType, err, id)
|
logger.Errorf("%s: 服务层获取原料详情失败: %v, ID: %d", actionType, err, id)
|
||||||
if errors.Is(err, service.ErrRawMaterialNotFound) {
|
if errors.Is(err, service.ErrRawMaterialNotFound) {
|
||||||
@@ -184,7 +184,7 @@ func (c *RawMaterialController) ListRawMaterials(ctx echo.Context) error {
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的查询参数: "+err.Error(), actionType, "查询参数绑定失败", req)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的查询参数: "+err.Error(), actionType, "查询参数绑定失败", req)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.feedManagementService.ListRawMaterials(reqCtx, &req)
|
resp, err := c.rawMaterialService.ListRawMaterials(reqCtx, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层获取原料列表失败: %v", actionType, err)
|
logger.Errorf("%s: 服务层获取原料列表失败: %v", actionType, err)
|
||||||
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取原料列表失败: "+err.Error(), actionType, "服务层获取原料列表失败", nil)
|
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取原料列表失败: "+err.Error(), actionType, "服务层获取原料列表失败", nil)
|
||||||
@@ -222,7 +222,7 @@ func (c *RawMaterialController) UpdateRawMaterialNutrients(ctx echo.Context) err
|
|||||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.feedManagementService.UpdateRawMaterialNutrients(reqCtx, uint32(id), &req)
|
resp, err := c.rawMaterialService.UpdateRawMaterialNutrients(reqCtx, uint32(id), &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%s: 服务层更新原料营养成分失败: %v, ID: %d", actionType, err, id)
|
logger.Errorf("%s: 服务层更新原料营养成分失败: %v, ID: %d", actionType, err, id)
|
||||||
if errors.Is(err, service.ErrRawMaterialNotFound) {
|
if errors.Is(err, service.ErrRawMaterialNotFound) {
|
||||||
|
|||||||
@@ -1,618 +0,0 @@
|
|||||||
package service
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
|
|
||||||
"git.huangwc.com/pig/pig-farm-controller/internal/domain/recipe"
|
|
||||||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
|
|
||||||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
|
|
||||||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 定义服务层特定的错误
|
|
||||||
var (
|
|
||||||
ErrNutrientNameConflict = errors.New("营养种类名称已存在")
|
|
||||||
ErrNutrientNotFound = errors.New("营养种类不存在")
|
|
||||||
ErrRawMaterialNameConflict = errors.New("原料名称已存在")
|
|
||||||
ErrRawMaterialNotFound = errors.New("原料不存在")
|
|
||||||
ErrPigBreedInUse = errors.New("猪品种正在被猪类型使用,无法删除")
|
|
||||||
ErrPigBreedNotFound = errors.New("猪品种不存在")
|
|
||||||
ErrPigAgeStageInUse = errors.New("猪年龄阶段正在被猪类型使用,无法删除")
|
|
||||||
ErrPigAgeStageNotFound = errors.New("猪年龄阶段不存在")
|
|
||||||
ErrPigTypeNotFound = errors.New("猪类型不存在")
|
|
||||||
)
|
|
||||||
|
|
||||||
// FeedManagementService 定义了饲料管理的应用服务接口
|
|
||||||
type FeedManagementService interface {
|
|
||||||
// 营养种类相关
|
|
||||||
CreateNutrient(ctx context.Context, req *dto.CreateNutrientRequest) (*dto.NutrientResponse, error)
|
|
||||||
UpdateNutrient(ctx context.Context, id uint32, req *dto.UpdateNutrientRequest) (*dto.NutrientResponse, error)
|
|
||||||
DeleteNutrient(ctx context.Context, id uint32) error
|
|
||||||
GetNutrient(ctx context.Context, id uint32) (*dto.NutrientResponse, error)
|
|
||||||
ListNutrients(ctx context.Context, req *dto.ListNutrientRequest) (*dto.ListNutrientResponse, error)
|
|
||||||
|
|
||||||
// 原料相关
|
|
||||||
CreateRawMaterial(ctx context.Context, req *dto.CreateRawMaterialRequest) (*dto.RawMaterialResponse, error)
|
|
||||||
UpdateRawMaterial(ctx context.Context, id uint32, req *dto.UpdateRawMaterialRequest) (*dto.RawMaterialResponse, error)
|
|
||||||
DeleteRawMaterial(ctx context.Context, id uint32) error
|
|
||||||
GetRawMaterial(ctx context.Context, id uint32) (*dto.RawMaterialResponse, error)
|
|
||||||
ListRawMaterials(ctx context.Context, req *dto.ListRawMaterialRequest) (*dto.ListRawMaterialResponse, error)
|
|
||||||
UpdateRawMaterialNutrients(ctx context.Context, id uint32, req *dto.UpdateRawMaterialNutrientsRequest) (*dto.RawMaterialResponse, error) // 新增
|
|
||||||
|
|
||||||
// 猪品种相关
|
|
||||||
CreatePigBreed(ctx context.Context, req *dto.CreatePigBreedRequest) (*dto.PigBreedResponse, error)
|
|
||||||
UpdatePigBreed(ctx context.Context, id uint32, req *dto.UpdatePigBreedRequest) (*dto.PigBreedResponse, error)
|
|
||||||
DeletePigBreed(ctx context.Context, id uint32) error
|
|
||||||
GetPigBreed(ctx context.Context, id uint32) (*dto.PigBreedResponse, error)
|
|
||||||
ListPigBreeds(ctx context.Context, req *dto.ListPigBreedRequest) (*dto.ListPigBreedResponse, error)
|
|
||||||
|
|
||||||
// 猪年龄阶段相关
|
|
||||||
CreatePigAgeStage(ctx context.Context, req *dto.CreatePigAgeStageRequest) (*dto.PigAgeStageResponse, error)
|
|
||||||
UpdatePigAgeStage(ctx context.Context, id uint32, req *dto.UpdatePigAgeStageRequest) (*dto.PigAgeStageResponse, error)
|
|
||||||
DeletePigAgeStage(ctx context.Context, id uint32) error
|
|
||||||
GetPigAgeStage(ctx context.Context, id uint32) (*dto.PigAgeStageResponse, error)
|
|
||||||
ListPigAgeStages(ctx context.Context, req *dto.ListPigAgeStageRequest) (*dto.ListPigAgeStageResponse, error)
|
|
||||||
|
|
||||||
// 猪类型相关
|
|
||||||
CreatePigType(ctx context.Context, req *dto.CreatePigTypeRequest) (*dto.PigTypeResponse, error)
|
|
||||||
UpdatePigType(ctx context.Context, id uint32, req *dto.UpdatePigTypeRequest) (*dto.PigTypeResponse, error)
|
|
||||||
DeletePigType(ctx context.Context, id uint32) error
|
|
||||||
GetPigType(ctx context.Context, id uint32) (*dto.PigTypeResponse, error)
|
|
||||||
ListPigTypes(ctx context.Context, req *dto.ListPigTypeRequest) (*dto.ListPigTypeResponse, error)
|
|
||||||
UpdatePigTypeNutrientRequirements(ctx context.Context, id uint32, req *dto.UpdatePigTypeNutrientRequirementsRequest) (*dto.PigTypeResponse, error) // 新增
|
|
||||||
}
|
|
||||||
|
|
||||||
// feedManagementServiceImpl 是 FeedManagementService 接口的实现
|
|
||||||
type feedManagementServiceImpl struct {
|
|
||||||
ctx context.Context
|
|
||||||
recipeSvc recipe.Service
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFeedManagementService 创建一个新的 FeedManagementService 实例
|
|
||||||
func NewFeedManagementService(ctx context.Context, recipeSvc recipe.Service) FeedManagementService {
|
|
||||||
return &feedManagementServiceImpl{
|
|
||||||
ctx: ctx,
|
|
||||||
recipeSvc: recipeSvc,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =====================================================================================================================
|
|
||||||
// 营养种类 (Nutrient) 实现
|
|
||||||
// =====================================================================================================================
|
|
||||||
|
|
||||||
// CreateNutrient 创建营养种类
|
|
||||||
func (s *feedManagementServiceImpl) CreateNutrient(ctx context.Context, req *dto.CreateNutrientRequest) (*dto.NutrientResponse, error) {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "CreateNutrient")
|
|
||||||
|
|
||||||
nutrient, err := s.recipeSvc.CreateNutrient(serviceCtx, req.Name, req.Description)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, recipe.ErrNutrientNameConflict) {
|
|
||||||
return nil, ErrNutrientNameConflict
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("创建营养种类失败: %w", err)
|
|
||||||
}
|
|
||||||
return dto.ConvertNutrientToDTO(nutrient), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateNutrient 更新营养种类
|
|
||||||
func (s *feedManagementServiceImpl) UpdateNutrient(ctx context.Context, id uint32, req *dto.UpdateNutrientRequest) (*dto.NutrientResponse, error) {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdateNutrient")
|
|
||||||
|
|
||||||
nutrient, err := s.recipeSvc.UpdateNutrient(serviceCtx, id, req.Name, req.Description)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, recipe.ErrNutrientNotFound) {
|
|
||||||
return nil, ErrNutrientNotFound
|
|
||||||
}
|
|
||||||
if errors.Is(err, recipe.ErrNutrientNameConflict) {
|
|
||||||
return nil, ErrNutrientNameConflict
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("更新营养种类失败: %w", err)
|
|
||||||
}
|
|
||||||
return dto.ConvertNutrientToDTO(nutrient), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteNutrient 删除营养种类
|
|
||||||
func (s *feedManagementServiceImpl) DeleteNutrient(ctx context.Context, id uint32) error {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "DeleteNutrient")
|
|
||||||
err := s.recipeSvc.DeleteNutrient(serviceCtx, id)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, recipe.ErrNutrientNotFound) {
|
|
||||||
return ErrNutrientNotFound
|
|
||||||
}
|
|
||||||
return fmt.Errorf("删除营养种类失败: %w", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetNutrient 获取单个营养种类
|
|
||||||
func (s *feedManagementServiceImpl) GetNutrient(ctx context.Context, id uint32) (*dto.NutrientResponse, error) {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "GetNutrient")
|
|
||||||
|
|
||||||
nutrient, err := s.recipeSvc.GetNutrient(serviceCtx, id)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, recipe.ErrNutrientNotFound) {
|
|
||||||
return nil, ErrNutrientNotFound
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("获取营养种类失败: %w", err)
|
|
||||||
}
|
|
||||||
return dto.ConvertNutrientToDTO(nutrient), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListNutrients 列出营养种类
|
|
||||||
func (s *feedManagementServiceImpl) ListNutrients(ctx context.Context, req *dto.ListNutrientRequest) (*dto.ListNutrientResponse, error) {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListNutrients")
|
|
||||||
|
|
||||||
opts := repository.NutrientListOptions{
|
|
||||||
Name: req.Name,
|
|
||||||
RawMaterialName: req.RawMaterialName,
|
|
||||||
OrderBy: req.OrderBy,
|
|
||||||
}
|
|
||||||
nutrients, total, err := s.recipeSvc.ListNutrients(serviceCtx, opts, req.Page, req.PageSize)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("获取营养种类列表失败: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return dto.ConvertNutrientListToDTO(nutrients, total, req.Page, req.PageSize), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// =====================================================================================================================
|
|
||||||
// 原料 (RawMaterial) 实现
|
|
||||||
// =====================================================================================================================
|
|
||||||
|
|
||||||
// CreateRawMaterial 创建原料
|
|
||||||
func (s *feedManagementServiceImpl) CreateRawMaterial(ctx context.Context, req *dto.CreateRawMaterialRequest) (*dto.RawMaterialResponse, error) {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "CreateRawMaterial")
|
|
||||||
|
|
||||||
rawMaterial, err := s.recipeSvc.CreateRawMaterial(serviceCtx, req.Name, req.Description)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, recipe.ErrRawMaterialNameConflict) {
|
|
||||||
return nil, ErrRawMaterialNameConflict
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("创建原料失败: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return dto.ConvertRawMaterialToDTO(rawMaterial), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateRawMaterial 更新原料
|
|
||||||
func (s *feedManagementServiceImpl) UpdateRawMaterial(ctx context.Context, id uint32, req *dto.UpdateRawMaterialRequest) (*dto.RawMaterialResponse, error) {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdateRawMaterial")
|
|
||||||
|
|
||||||
rawMaterial, err := s.recipeSvc.UpdateRawMaterial(serviceCtx, id, req.Name, req.Description)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, recipe.ErrRawMaterialNotFound) {
|
|
||||||
return nil, ErrRawMaterialNotFound
|
|
||||||
}
|
|
||||||
if errors.Is(err, recipe.ErrRawMaterialNameConflict) {
|
|
||||||
return nil, ErrRawMaterialNameConflict
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("更新原料失败: %w", err)
|
|
||||||
}
|
|
||||||
return dto.ConvertRawMaterialToDTO(rawMaterial), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteRawMaterial 删除原料
|
|
||||||
func (s *feedManagementServiceImpl) DeleteRawMaterial(ctx context.Context, id uint32) error {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "DeleteRawMaterial")
|
|
||||||
err := s.recipeSvc.DeleteRawMaterial(serviceCtx, id)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, recipe.ErrRawMaterialNotFound) {
|
|
||||||
return ErrRawMaterialNotFound
|
|
||||||
}
|
|
||||||
return fmt.Errorf("删除原料失败: %w", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetRawMaterial 获取单个原料
|
|
||||||
func (s *feedManagementServiceImpl) GetRawMaterial(ctx context.Context, id uint32) (*dto.RawMaterialResponse, error) {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "GetRawMaterial")
|
|
||||||
|
|
||||||
rawMaterial, err := s.recipeSvc.GetRawMaterial(serviceCtx, id)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, recipe.ErrRawMaterialNotFound) {
|
|
||||||
return nil, ErrRawMaterialNotFound
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("获取原料失败: %w", err)
|
|
||||||
}
|
|
||||||
return dto.ConvertRawMaterialToDTO(rawMaterial), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListRawMaterials 列出原料
|
|
||||||
func (s *feedManagementServiceImpl) ListRawMaterials(ctx context.Context, req *dto.ListRawMaterialRequest) (*dto.ListRawMaterialResponse, error) {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListRawMaterials")
|
|
||||||
|
|
||||||
opts := repository.RawMaterialListOptions{
|
|
||||||
Name: req.Name,
|
|
||||||
NutrientName: req.NutrientName,
|
|
||||||
OrderBy: req.OrderBy,
|
|
||||||
}
|
|
||||||
rawMaterials, total, err := s.recipeSvc.ListRawMaterials(serviceCtx, opts, req.Page, req.PageSize)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("获取原料列表失败: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return dto.ConvertRawMaterialListToDTO(rawMaterials, total, req.Page, req.PageSize), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateRawMaterialNutrients 全量更新原料的营养成分
|
|
||||||
func (s *feedManagementServiceImpl) UpdateRawMaterialNutrients(ctx context.Context, id uint32, req *dto.UpdateRawMaterialNutrientsRequest) (*dto.RawMaterialResponse, error) {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdateRawMaterialNutrients")
|
|
||||||
|
|
||||||
// 1. 将 DTO 转换为领域模型
|
|
||||||
nutrients := make([]models.RawMaterialNutrient, len(req.Nutrients))
|
|
||||||
for i, item := range req.Nutrients {
|
|
||||||
nutrients[i] = models.RawMaterialNutrient{
|
|
||||||
RawMaterialID: id,
|
|
||||||
NutrientID: item.NutrientID,
|
|
||||||
Value: item.Value,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 调用领域服务执行更新命令
|
|
||||||
err := s.recipeSvc.UpdateRawMaterialNutrients(serviceCtx, id, nutrients)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, recipe.ErrRawMaterialNotFound) {
|
|
||||||
return nil, ErrRawMaterialNotFound
|
|
||||||
}
|
|
||||||
// 此处可以根据领域层可能返回的其他特定错误进行转换
|
|
||||||
return nil, fmt.Errorf("更新原料营养成分失败: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 更新成功后,调用查询服务获取最新的原料信息
|
|
||||||
updatedRawMaterial, err := s.recipeSvc.GetRawMaterial(serviceCtx, id)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, recipe.ErrRawMaterialNotFound) {
|
|
||||||
// 理论上不应该发生,因为刚更新成功
|
|
||||||
return nil, ErrRawMaterialNotFound
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("更新后获取原料信息失败: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. 将领域模型转换为 DTO 并返回
|
|
||||||
return dto.ConvertRawMaterialToDTO(updatedRawMaterial), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// =====================================================================================================================
|
|
||||||
// 猪品种 (PigBreed) 实现
|
|
||||||
// =====================================================================================================================
|
|
||||||
|
|
||||||
// CreatePigBreed 创建猪品种
|
|
||||||
func (s *feedManagementServiceImpl) CreatePigBreed(ctx context.Context, req *dto.CreatePigBreedRequest) (*dto.PigBreedResponse, error) {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "CreatePigBreed")
|
|
||||||
|
|
||||||
breed := &models.PigBreed{
|
|
||||||
Name: req.Name,
|
|
||||||
Description: req.Description,
|
|
||||||
ParentInfo: req.ParentInfo,
|
|
||||||
AppearanceFeatures: req.AppearanceFeatures,
|
|
||||||
BreedAdvantages: req.BreedAdvantages,
|
|
||||||
BreedDisadvantages: req.BreedDisadvantages,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := s.recipeSvc.CreatePigBreed(serviceCtx, breed); err != nil {
|
|
||||||
return nil, fmt.Errorf("创建猪品种失败: %w", err)
|
|
||||||
}
|
|
||||||
return dto.ConvertPigBreedToDTO(breed), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdatePigBreed 更新猪品种
|
|
||||||
func (s *feedManagementServiceImpl) UpdatePigBreed(ctx context.Context, id uint32, req *dto.UpdatePigBreedRequest) (*dto.PigBreedResponse, error) {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdatePigBreed")
|
|
||||||
|
|
||||||
breed := &models.PigBreed{
|
|
||||||
Model: models.Model{ID: id},
|
|
||||||
Name: req.Name,
|
|
||||||
Description: req.Description,
|
|
||||||
ParentInfo: req.ParentInfo,
|
|
||||||
AppearanceFeatures: req.AppearanceFeatures,
|
|
||||||
BreedAdvantages: req.BreedAdvantages,
|
|
||||||
BreedDisadvantages: req.BreedDisadvantages,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := s.recipeSvc.UpdatePigBreed(serviceCtx, breed); err != nil {
|
|
||||||
if errors.Is(err, recipe.ErrPigBreedNotFound) {
|
|
||||||
return nil, ErrPigBreedNotFound
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("更新猪品种失败: %w", err)
|
|
||||||
}
|
|
||||||
return dto.ConvertPigBreedToDTO(breed), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeletePigBreed 删除猪品种
|
|
||||||
func (s *feedManagementServiceImpl) DeletePigBreed(ctx context.Context, id uint32) error {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "DeletePigBreed")
|
|
||||||
err := s.recipeSvc.DeletePigBreed(serviceCtx, id)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, recipe.ErrPigBreedNotFound) {
|
|
||||||
return ErrPigBreedNotFound
|
|
||||||
}
|
|
||||||
if errors.Is(err, recipe.ErrPigBreedInUse) {
|
|
||||||
return ErrPigBreedInUse
|
|
||||||
}
|
|
||||||
return fmt.Errorf("删除猪品种失败: %w", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPigBreed 获取单个猪品种
|
|
||||||
func (s *feedManagementServiceImpl) GetPigBreed(ctx context.Context, id uint32) (*dto.PigBreedResponse, error) {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "GetPigBreed")
|
|
||||||
|
|
||||||
breed, err := s.recipeSvc.GetPigBreedByID(serviceCtx, id)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, recipe.ErrPigBreedNotFound) {
|
|
||||||
return nil, ErrPigBreedNotFound
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("获取猪品种失败: %w", err)
|
|
||||||
}
|
|
||||||
return dto.ConvertPigBreedToDTO(breed), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListPigBreeds 列出猪品种
|
|
||||||
func (s *feedManagementServiceImpl) ListPigBreeds(ctx context.Context, req *dto.ListPigBreedRequest) (*dto.ListPigBreedResponse, error) {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListPigBreeds")
|
|
||||||
|
|
||||||
opts := repository.PigBreedListOptions{
|
|
||||||
Name: req.Name,
|
|
||||||
OrderBy: req.OrderBy,
|
|
||||||
}
|
|
||||||
breeds, total, err := s.recipeSvc.ListPigBreeds(serviceCtx, opts, req.Page, req.PageSize)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("获取猪品种列表失败: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return dto.ConvertPigBreedListToDTO(breeds, total, req.Page, req.PageSize), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// =====================================================================================================================
|
|
||||||
// 猪年龄阶段 (PigAgeStage) 实现
|
|
||||||
// =====================================================================================================================
|
|
||||||
|
|
||||||
// CreatePigAgeStage 创建猪年龄阶段
|
|
||||||
func (s *feedManagementServiceImpl) CreatePigAgeStage(ctx context.Context, req *dto.CreatePigAgeStageRequest) (*dto.PigAgeStageResponse, error) {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "CreatePigAgeStage")
|
|
||||||
|
|
||||||
ageStage := &models.PigAgeStage{
|
|
||||||
Name: req.Name,
|
|
||||||
Description: req.Description,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := s.recipeSvc.CreatePigAgeStage(serviceCtx, ageStage); err != nil {
|
|
||||||
return nil, fmt.Errorf("创建猪年龄阶段失败: %w", err)
|
|
||||||
}
|
|
||||||
return dto.ConvertPigAgeStageToDTO(ageStage), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdatePigAgeStage 更新猪年龄阶段
|
|
||||||
func (s *feedManagementServiceImpl) UpdatePigAgeStage(ctx context.Context, id uint32, req *dto.UpdatePigAgeStageRequest) (*dto.PigAgeStageResponse, error) {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdatePigAgeStage")
|
|
||||||
|
|
||||||
ageStage := &models.PigAgeStage{
|
|
||||||
Model: models.Model{ID: id},
|
|
||||||
Name: req.Name,
|
|
||||||
Description: req.Description,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := s.recipeSvc.UpdatePigAgeStage(serviceCtx, ageStage); err != nil {
|
|
||||||
if errors.Is(err, recipe.ErrPigAgeStageNotFound) {
|
|
||||||
return nil, ErrPigAgeStageNotFound
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("更新猪年龄阶段失败: %w", err)
|
|
||||||
}
|
|
||||||
return dto.ConvertPigAgeStageToDTO(ageStage), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeletePigAgeStage 删除猪年龄阶段
|
|
||||||
func (s *feedManagementServiceImpl) DeletePigAgeStage(ctx context.Context, id uint32) error {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "DeletePigAgeStage")
|
|
||||||
err := s.recipeSvc.DeletePigAgeStage(serviceCtx, id)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, recipe.ErrPigAgeStageNotFound) {
|
|
||||||
return ErrPigAgeStageNotFound
|
|
||||||
}
|
|
||||||
if errors.Is(err, recipe.ErrPigAgeStageInUse) {
|
|
||||||
return ErrPigAgeStageInUse
|
|
||||||
}
|
|
||||||
return fmt.Errorf("删除猪年龄阶段失败: %w", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPigAgeStage 获取单个猪年龄阶段
|
|
||||||
func (s *feedManagementServiceImpl) GetPigAgeStage(ctx context.Context, id uint32) (*dto.PigAgeStageResponse, error) {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "GetPigAgeStage")
|
|
||||||
|
|
||||||
ageStage, err := s.recipeSvc.GetPigAgeStageByID(serviceCtx, id)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, recipe.ErrPigAgeStageNotFound) {
|
|
||||||
return nil, ErrPigAgeStageNotFound
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("获取猪年龄阶段失败: %w", err)
|
|
||||||
}
|
|
||||||
return dto.ConvertPigAgeStageToDTO(ageStage), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListPigAgeStages 列出猪年龄阶段
|
|
||||||
func (s *feedManagementServiceImpl) ListPigAgeStages(ctx context.Context, req *dto.ListPigAgeStageRequest) (*dto.ListPigAgeStageResponse, error) {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListPigAgeStages")
|
|
||||||
|
|
||||||
opts := repository.PigAgeStageListOptions{
|
|
||||||
Name: req.Name,
|
|
||||||
OrderBy: req.OrderBy,
|
|
||||||
}
|
|
||||||
ageStages, total, err := s.recipeSvc.ListPigAgeStages(serviceCtx, opts, req.Page, req.PageSize)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("获取猪年龄阶段列表失败: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return dto.ConvertPigAgeStageListToDTO(ageStages, total, req.Page, req.PageSize), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// =====================================================================================================================
|
|
||||||
// 猪类型 (PigType) 实现
|
|
||||||
// =====================================================================================================================
|
|
||||||
|
|
||||||
// CreatePigType 创建猪类型
|
|
||||||
func (s *feedManagementServiceImpl) CreatePigType(ctx context.Context, req *dto.CreatePigTypeRequest) (*dto.PigTypeResponse, error) {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "CreatePigType")
|
|
||||||
|
|
||||||
pigType := &models.PigType{
|
|
||||||
BreedID: req.BreedID,
|
|
||||||
AgeStageID: req.AgeStageID,
|
|
||||||
Description: req.Description,
|
|
||||||
DailyFeedIntake: req.DailyFeedIntake,
|
|
||||||
DailyGainWeight: req.DailyGainWeight,
|
|
||||||
MinDays: req.MinDays,
|
|
||||||
MaxDays: req.MaxDays,
|
|
||||||
MinWeight: req.MinWeight,
|
|
||||||
MaxWeight: req.MaxWeight,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := s.recipeSvc.CreatePigType(serviceCtx, pigType); err != nil {
|
|
||||||
if errors.Is(err, recipe.ErrPigBreedNotFound) {
|
|
||||||
return nil, ErrPigBreedNotFound
|
|
||||||
}
|
|
||||||
if errors.Is(err, recipe.ErrPigAgeStageNotFound) {
|
|
||||||
return nil, ErrPigAgeStageNotFound
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("创建猪类型失败: %w", err)
|
|
||||||
}
|
|
||||||
// 创建后需要重新获取,以包含关联数据
|
|
||||||
createdPigType, err := s.recipeSvc.GetPigTypeByID(serviceCtx, pigType.ID)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, recipe.ErrPigTypeNotFound) { // 理论上不应该发生,因为刚创建
|
|
||||||
return nil, ErrPigTypeNotFound
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("创建猪类型后获取详情失败: %w", err)
|
|
||||||
}
|
|
||||||
return dto.ConvertPigTypeToDTO(createdPigType), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdatePigType 更新猪类型
|
|
||||||
func (s *feedManagementServiceImpl) UpdatePigType(ctx context.Context, id uint32, req *dto.UpdatePigTypeRequest) (*dto.PigTypeResponse, error) {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdatePigType")
|
|
||||||
|
|
||||||
pigType := &models.PigType{
|
|
||||||
Model: models.Model{ID: id},
|
|
||||||
BreedID: req.BreedID,
|
|
||||||
AgeStageID: req.AgeStageID,
|
|
||||||
Description: req.Description,
|
|
||||||
DailyFeedIntake: req.DailyFeedIntake,
|
|
||||||
DailyGainWeight: req.DailyGainWeight,
|
|
||||||
MinDays: req.MinDays,
|
|
||||||
MaxDays: req.MaxDays,
|
|
||||||
MinWeight: req.MinWeight,
|
|
||||||
MaxWeight: req.MaxWeight,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := s.recipeSvc.UpdatePigType(serviceCtx, pigType); err != nil {
|
|
||||||
if errors.Is(err, recipe.ErrPigTypeNotFound) {
|
|
||||||
return nil, ErrPigTypeNotFound
|
|
||||||
}
|
|
||||||
if errors.Is(err, recipe.ErrPigBreedNotFound) {
|
|
||||||
return nil, ErrPigBreedNotFound
|
|
||||||
}
|
|
||||||
if errors.Is(err, recipe.ErrPigAgeStageNotFound) {
|
|
||||||
return nil, ErrPigAgeStageNotFound
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("更新猪类型失败: %w", err)
|
|
||||||
}
|
|
||||||
// 更新后需要重新获取,以包含关联数据
|
|
||||||
updatedPigType, err := s.recipeSvc.GetPigTypeByID(serviceCtx, id)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, recipe.ErrPigTypeNotFound) { // 理论上不应该发生,因为刚更新成功
|
|
||||||
return nil, ErrPigTypeNotFound
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("更新猪类型后获取详情失败: %w", err)
|
|
||||||
}
|
|
||||||
return dto.ConvertPigTypeToDTO(updatedPigType), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeletePigType 删除猪类型
|
|
||||||
func (s *feedManagementServiceImpl) DeletePigType(ctx context.Context, id uint32) error {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "DeletePigType")
|
|
||||||
err := s.recipeSvc.DeletePigType(serviceCtx, id)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, recipe.ErrPigTypeNotFound) {
|
|
||||||
return ErrPigTypeNotFound
|
|
||||||
}
|
|
||||||
return fmt.Errorf("删除猪类型失败: %w", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPigType 获取单个猪类型
|
|
||||||
func (s *feedManagementServiceImpl) GetPigType(ctx context.Context, id uint32) (*dto.PigTypeResponse, error) {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "GetPigType")
|
|
||||||
|
|
||||||
pigType, err := s.recipeSvc.GetPigTypeByID(serviceCtx, id)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, recipe.ErrPigTypeNotFound) {
|
|
||||||
return nil, ErrPigTypeNotFound
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("获取猪类型失败: %w", err)
|
|
||||||
}
|
|
||||||
return dto.ConvertPigTypeToDTO(pigType), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListPigTypes 列出猪类型
|
|
||||||
func (s *feedManagementServiceImpl) ListPigTypes(ctx context.Context, req *dto.ListPigTypeRequest) (*dto.ListPigTypeResponse, error) {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListPigTypes")
|
|
||||||
|
|
||||||
opts := repository.PigTypeListOptions{
|
|
||||||
BreedID: req.BreedID,
|
|
||||||
AgeStageID: req.AgeStageID,
|
|
||||||
BreedName: req.BreedName,
|
|
||||||
AgeStageName: req.AgeStageName,
|
|
||||||
OrderBy: req.OrderBy,
|
|
||||||
}
|
|
||||||
pigTypes, total, err := s.recipeSvc.ListPigTypes(serviceCtx, opts, req.Page, req.PageSize)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("获取猪类型列表失败: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return dto.ConvertPigTypeListToDTO(pigTypes, total, req.Page, req.PageSize), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdatePigTypeNutrientRequirements 全量更新猪类型的营养需求
|
|
||||||
func (s *feedManagementServiceImpl) UpdatePigTypeNutrientRequirements(ctx context.Context, id uint32, req *dto.UpdatePigTypeNutrientRequirementsRequest) (*dto.PigTypeResponse, error) {
|
|
||||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdatePigTypeNutrientRequirements")
|
|
||||||
|
|
||||||
// 1. 将 DTO 转换为领域模型
|
|
||||||
requirements := make([]models.PigNutrientRequirement, len(req.NutrientRequirements))
|
|
||||||
for i, item := range req.NutrientRequirements {
|
|
||||||
requirements[i] = models.PigNutrientRequirement{
|
|
||||||
PigTypeID: id, // 设置所属的 PigTypeID
|
|
||||||
NutrientID: item.NutrientID,
|
|
||||||
MinRequirement: item.MinRequirement,
|
|
||||||
MaxRequirement: item.MaxRequirement,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 调用领域服务执行更新命令
|
|
||||||
err := s.recipeSvc.UpdatePigTypeNutrientRequirements(serviceCtx, id, requirements)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, recipe.ErrPigTypeNotFound) {
|
|
||||||
return nil, ErrPigTypeNotFound
|
|
||||||
}
|
|
||||||
// 此处可以根据领域层可能返回的其他特定错误进行转换
|
|
||||||
return nil, fmt.Errorf("更新猪类型营养需求失败: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 更新成功后,调用查询服务获取最新的猪类型信息
|
|
||||||
updatedPigType, err := s.recipeSvc.GetPigTypeByID(serviceCtx, id)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, recipe.ErrPigTypeNotFound) {
|
|
||||||
// 理论上不应该发生,因为刚更新成功
|
|
||||||
return nil, ErrPigTypeNotFound
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("更新后获取猪类型信息失败: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. 将领域模型转换为 DTO 并返回
|
|
||||||
return dto.ConvertPigTypeToDTO(updatedPigType), nil
|
|
||||||
}
|
|
||||||
116
internal/app/service/nutrient_service.go
Normal file
116
internal/app/service/nutrient_service.go
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/domain/recipe"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 定义营养种类服务特定的错误
|
||||||
|
var (
|
||||||
|
ErrNutrientNameConflict = errors.New("营养种类名称已存在")
|
||||||
|
ErrNutrientNotFound = errors.New("营养种类不存在")
|
||||||
|
)
|
||||||
|
|
||||||
|
// NutrientService 定义了营养种类相关的应用服务接口
|
||||||
|
type NutrientService interface {
|
||||||
|
CreateNutrient(ctx context.Context, req *dto.CreateNutrientRequest) (*dto.NutrientResponse, error)
|
||||||
|
UpdateNutrient(ctx context.Context, id uint32, req *dto.UpdateNutrientRequest) (*dto.NutrientResponse, error)
|
||||||
|
DeleteNutrient(ctx context.Context, id uint32) error
|
||||||
|
GetNutrient(ctx context.Context, id uint32) (*dto.NutrientResponse, error)
|
||||||
|
ListNutrients(ctx context.Context, req *dto.ListNutrientRequest) (*dto.ListNutrientResponse, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// nutrientServiceImpl 是 NutrientService 接口的实现
|
||||||
|
type nutrientServiceImpl struct {
|
||||||
|
ctx context.Context
|
||||||
|
recipeSvc recipe.Service
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNutrientService 创建一个新的 NutrientService 实例
|
||||||
|
func NewNutrientService(ctx context.Context, recipeSvc recipe.Service) NutrientService {
|
||||||
|
return &nutrientServiceImpl{
|
||||||
|
ctx: ctx,
|
||||||
|
recipeSvc: recipeSvc,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateNutrient 创建营养种类
|
||||||
|
func (s *nutrientServiceImpl) CreateNutrient(ctx context.Context, req *dto.CreateNutrientRequest) (*dto.NutrientResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "CreateNutrient")
|
||||||
|
|
||||||
|
nutrient, err := s.recipeSvc.CreateNutrient(serviceCtx, req.Name, req.Description)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrNutrientNameConflict) {
|
||||||
|
return nil, ErrNutrientNameConflict
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("创建营养种类失败: %w", err)
|
||||||
|
}
|
||||||
|
return dto.ConvertNutrientToDTO(nutrient), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateNutrient 更新营养种类
|
||||||
|
func (s *nutrientServiceImpl) UpdateNutrient(ctx context.Context, id uint32, req *dto.UpdateNutrientRequest) (*dto.NutrientResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdateNutrient")
|
||||||
|
|
||||||
|
nutrient, err := s.recipeSvc.UpdateNutrient(serviceCtx, id, req.Name, req.Description)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrNutrientNotFound) {
|
||||||
|
return nil, ErrNutrientNotFound
|
||||||
|
}
|
||||||
|
if errors.Is(err, recipe.ErrNutrientNameConflict) {
|
||||||
|
return nil, ErrNutrientNameConflict
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("更新营养种类失败: %w", err)
|
||||||
|
}
|
||||||
|
return dto.ConvertNutrientToDTO(nutrient), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteNutrient 删除营养种类
|
||||||
|
func (s *nutrientServiceImpl) DeleteNutrient(ctx context.Context, id uint32) error {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "DeleteNutrient")
|
||||||
|
err := s.recipeSvc.DeleteNutrient(serviceCtx, id)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrNutrientNotFound) {
|
||||||
|
return ErrNutrientNotFound
|
||||||
|
}
|
||||||
|
return fmt.Errorf("删除营养种类失败: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetNutrient 获取单个营养种类
|
||||||
|
func (s *nutrientServiceImpl) GetNutrient(ctx context.Context, id uint32) (*dto.NutrientResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "GetNutrient")
|
||||||
|
|
||||||
|
nutrient, err := s.recipeSvc.GetNutrient(serviceCtx, id)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrNutrientNotFound) {
|
||||||
|
return nil, ErrNutrientNotFound
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("获取营养种类失败: %w", err)
|
||||||
|
}
|
||||||
|
return dto.ConvertNutrientToDTO(nutrient), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListNutrients 列出营养种类
|
||||||
|
func (s *nutrientServiceImpl) ListNutrients(ctx context.Context, req *dto.ListNutrientRequest) (*dto.ListNutrientResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListNutrients")
|
||||||
|
|
||||||
|
opts := repository.NutrientListOptions{
|
||||||
|
Name: req.Name,
|
||||||
|
RawMaterialName: req.RawMaterialName,
|
||||||
|
OrderBy: req.OrderBy,
|
||||||
|
}
|
||||||
|
nutrients, total, err := s.recipeSvc.ListNutrients(serviceCtx, opts, req.Page, req.PageSize)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("获取营养种类列表失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return dto.ConvertNutrientListToDTO(nutrients, total, req.Page, req.PageSize), nil
|
||||||
|
}
|
||||||
122
internal/app/service/pig_age_stage_service.go
Normal file
122
internal/app/service/pig_age_stage_service.go
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/domain/recipe"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 定义猪年龄阶段服务特定的错误
|
||||||
|
var (
|
||||||
|
ErrPigAgeStageInUse = errors.New("猪年龄阶段正在被猪类型使用,无法删除")
|
||||||
|
ErrPigAgeStageNotFound = errors.New("猪年龄阶段不存在")
|
||||||
|
)
|
||||||
|
|
||||||
|
// PigAgeStageService 定义了猪年龄阶段相关的应用服务接口
|
||||||
|
type PigAgeStageService interface {
|
||||||
|
CreatePigAgeStage(ctx context.Context, req *dto.CreatePigAgeStageRequest) (*dto.PigAgeStageResponse, error)
|
||||||
|
UpdatePigAgeStage(ctx context.Context, id uint32, req *dto.UpdatePigAgeStageRequest) (*dto.PigAgeStageResponse, error)
|
||||||
|
DeletePigAgeStage(ctx context.Context, id uint32) error
|
||||||
|
GetPigAgeStage(ctx context.Context, id uint32) (*dto.PigAgeStageResponse, error)
|
||||||
|
ListPigAgeStages(ctx context.Context, req *dto.ListPigAgeStageRequest) (*dto.ListPigAgeStageResponse, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// pigAgeStageServiceImpl 是 PigAgeStageService 接口的实现
|
||||||
|
type pigAgeStageServiceImpl struct {
|
||||||
|
ctx context.Context
|
||||||
|
recipeSvc recipe.Service
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPigAgeStageService 创建一个新的 PigAgeStageService 实例
|
||||||
|
func NewPigAgeStageService(ctx context.Context, recipeSvc recipe.Service) PigAgeStageService {
|
||||||
|
return &pigAgeStageServiceImpl{
|
||||||
|
ctx: ctx,
|
||||||
|
recipeSvc: recipeSvc,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatePigAgeStage 创建猪年龄阶段
|
||||||
|
func (s *pigAgeStageServiceImpl) CreatePigAgeStage(ctx context.Context, req *dto.CreatePigAgeStageRequest) (*dto.PigAgeStageResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "CreatePigAgeStage")
|
||||||
|
|
||||||
|
ageStage := &models.PigAgeStage{
|
||||||
|
Name: req.Name,
|
||||||
|
Description: req.Description,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.recipeSvc.CreatePigAgeStage(serviceCtx, ageStage); err != nil {
|
||||||
|
return nil, fmt.Errorf("创建猪年龄阶段失败: %w", err)
|
||||||
|
}
|
||||||
|
return dto.ConvertPigAgeStageToDTO(ageStage), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatePigAgeStage 更新猪年龄阶段
|
||||||
|
func (s *pigAgeStageServiceImpl) UpdatePigAgeStage(ctx context.Context, id uint32, req *dto.UpdatePigAgeStageRequest) (*dto.PigAgeStageResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdatePigAgeStage")
|
||||||
|
|
||||||
|
ageStage := &models.PigAgeStage{
|
||||||
|
Model: models.Model{ID: id},
|
||||||
|
Name: req.Name,
|
||||||
|
Description: req.Description,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.recipeSvc.UpdatePigAgeStage(serviceCtx, ageStage); err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrPigAgeStageNotFound) {
|
||||||
|
return nil, ErrPigAgeStageNotFound
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("更新猪年龄阶段失败: %w", err)
|
||||||
|
}
|
||||||
|
return dto.ConvertPigAgeStageToDTO(ageStage), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletePigAgeStage 删除猪年龄阶段
|
||||||
|
func (s *pigAgeStageServiceImpl) DeletePigAgeStage(ctx context.Context, id uint32) error {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "DeletePigAgeStage")
|
||||||
|
err := s.recipeSvc.DeletePigAgeStage(serviceCtx, id)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrPigAgeStageNotFound) {
|
||||||
|
return ErrPigAgeStageNotFound
|
||||||
|
}
|
||||||
|
if errors.Is(err, recipe.ErrPigAgeStageInUse) {
|
||||||
|
return ErrPigAgeStageInUse
|
||||||
|
}
|
||||||
|
return fmt.Errorf("删除猪年龄阶段失败: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPigAgeStage 获取单个猪年龄阶段
|
||||||
|
func (s *pigAgeStageServiceImpl) GetPigAgeStage(ctx context.Context, id uint32) (*dto.PigAgeStageResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "GetPigAgeStage")
|
||||||
|
|
||||||
|
ageStage, err := s.recipeSvc.GetPigAgeStageByID(serviceCtx, id)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrPigAgeStageNotFound) {
|
||||||
|
return nil, ErrPigAgeStageNotFound
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("获取猪年龄阶段失败: %w", err)
|
||||||
|
}
|
||||||
|
return dto.ConvertPigAgeStageToDTO(ageStage), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListPigAgeStages 列出猪年龄阶段
|
||||||
|
func (s *pigAgeStageServiceImpl) ListPigAgeStages(ctx context.Context, req *dto.ListPigAgeStageRequest) (*dto.ListPigAgeStageResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListPigAgeStages")
|
||||||
|
|
||||||
|
opts := repository.PigAgeStageListOptions{
|
||||||
|
Name: req.Name,
|
||||||
|
OrderBy: req.OrderBy,
|
||||||
|
}
|
||||||
|
ageStages, total, err := s.recipeSvc.ListPigAgeStages(serviceCtx, opts, req.Page, req.PageSize)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("获取猪年龄阶段列表失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return dto.ConvertPigAgeStageListToDTO(ageStages, total, req.Page, req.PageSize), nil
|
||||||
|
}
|
||||||
130
internal/app/service/pig_breed_service.go
Normal file
130
internal/app/service/pig_breed_service.go
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/domain/recipe"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 定义猪品种服务特定的错误
|
||||||
|
var (
|
||||||
|
ErrPigBreedInUse = errors.New("猪品种正在被猪类型使用,无法删除")
|
||||||
|
ErrPigBreedNotFound = errors.New("猪品种不存在")
|
||||||
|
)
|
||||||
|
|
||||||
|
// PigBreedService 定义了猪品种相关的应用服务接口
|
||||||
|
type PigBreedService interface {
|
||||||
|
CreatePigBreed(ctx context.Context, req *dto.CreatePigBreedRequest) (*dto.PigBreedResponse, error)
|
||||||
|
UpdatePigBreed(ctx context.Context, id uint32, req *dto.UpdatePigBreedRequest) (*dto.PigBreedResponse, error)
|
||||||
|
DeletePigBreed(ctx context.Context, id uint32) error
|
||||||
|
GetPigBreed(ctx context.Context, id uint32) (*dto.PigBreedResponse, error)
|
||||||
|
ListPigBreeds(ctx context.Context, req *dto.ListPigBreedRequest) (*dto.ListPigBreedResponse, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// pigBreedServiceImpl 是 PigBreedService 接口的实现
|
||||||
|
type pigBreedServiceImpl struct {
|
||||||
|
ctx context.Context
|
||||||
|
recipeSvc recipe.Service
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPigBreedService 创建一个新的 PigBreedService 实例
|
||||||
|
func NewPigBreedService(ctx context.Context, recipeSvc recipe.Service) PigBreedService {
|
||||||
|
return &pigBreedServiceImpl{
|
||||||
|
ctx: ctx,
|
||||||
|
recipeSvc: recipeSvc,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatePigBreed 创建猪品种
|
||||||
|
func (s *pigBreedServiceImpl) CreatePigBreed(ctx context.Context, req *dto.CreatePigBreedRequest) (*dto.PigBreedResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "CreatePigBreed")
|
||||||
|
|
||||||
|
breed := &models.PigBreed{
|
||||||
|
Name: req.Name,
|
||||||
|
Description: req.Description,
|
||||||
|
ParentInfo: req.ParentInfo,
|
||||||
|
AppearanceFeatures: req.AppearanceFeatures,
|
||||||
|
BreedAdvantages: req.BreedAdvantages,
|
||||||
|
BreedDisadvantages: req.BreedDisadvantages,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.recipeSvc.CreatePigBreed(serviceCtx, breed); err != nil {
|
||||||
|
return nil, fmt.Errorf("创建猪品种失败: %w", err)
|
||||||
|
}
|
||||||
|
return dto.ConvertPigBreedToDTO(breed), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatePigBreed 更新猪品种
|
||||||
|
func (s *pigBreedServiceImpl) UpdatePigBreed(ctx context.Context, id uint32, req *dto.UpdatePigBreedRequest) (*dto.PigBreedResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdatePigBreed")
|
||||||
|
|
||||||
|
breed := &models.PigBreed{
|
||||||
|
Model: models.Model{ID: id},
|
||||||
|
Name: req.Name,
|
||||||
|
Description: req.Description,
|
||||||
|
ParentInfo: req.ParentInfo,
|
||||||
|
AppearanceFeatures: req.AppearanceFeatures,
|
||||||
|
BreedAdvantages: req.BreedAdvantages,
|
||||||
|
BreedDisadvantages: req.BreedDisadvantages,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.recipeSvc.UpdatePigBreed(serviceCtx, breed); err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrPigBreedNotFound) {
|
||||||
|
return nil, ErrPigBreedNotFound
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("更新猪品种失败: %w", err)
|
||||||
|
}
|
||||||
|
return dto.ConvertPigBreedToDTO(breed), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletePigBreed 删除猪品种
|
||||||
|
func (s *pigBreedServiceImpl) DeletePigBreed(ctx context.Context, id uint32) error {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "DeletePigBreed")
|
||||||
|
err := s.recipeSvc.DeletePigBreed(serviceCtx, id)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrPigBreedNotFound) {
|
||||||
|
return ErrPigBreedNotFound
|
||||||
|
}
|
||||||
|
if errors.Is(err, recipe.ErrPigBreedInUse) {
|
||||||
|
return ErrPigBreedInUse
|
||||||
|
}
|
||||||
|
return fmt.Errorf("删除猪品种失败: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPigBreed 获取单个猪品种
|
||||||
|
func (s *pigBreedServiceImpl) GetPigBreed(ctx context.Context, id uint32) (*dto.PigBreedResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "GetPigBreed")
|
||||||
|
|
||||||
|
breed, err := s.recipeSvc.GetPigBreedByID(serviceCtx, id)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrPigBreedNotFound) {
|
||||||
|
return nil, ErrPigBreedNotFound
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("获取猪品种失败: %w", err)
|
||||||
|
}
|
||||||
|
return dto.ConvertPigBreedToDTO(breed), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListPigBreeds 列出猪品种
|
||||||
|
func (s *pigBreedServiceImpl) ListPigBreeds(ctx context.Context, req *dto.ListPigBreedRequest) (*dto.ListPigBreedResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListPigBreeds")
|
||||||
|
|
||||||
|
opts := repository.PigBreedListOptions{
|
||||||
|
Name: req.Name,
|
||||||
|
OrderBy: req.OrderBy,
|
||||||
|
}
|
||||||
|
breeds, total, err := s.recipeSvc.ListPigBreeds(serviceCtx, opts, req.Page, req.PageSize)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("获取猪品种列表失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return dto.ConvertPigBreedListToDTO(breeds, total, req.Page, req.PageSize), nil
|
||||||
|
}
|
||||||
203
internal/app/service/pig_type_service.go
Normal file
203
internal/app/service/pig_type_service.go
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/domain/recipe"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 定义猪类型服务特定的错误
|
||||||
|
var (
|
||||||
|
ErrPigTypeNotFound = errors.New("猪类型不存在")
|
||||||
|
)
|
||||||
|
|
||||||
|
// PigTypeService 定义了猪类型相关的应用服务接口
|
||||||
|
type PigTypeService interface {
|
||||||
|
CreatePigType(ctx context.Context, req *dto.CreatePigTypeRequest) (*dto.PigTypeResponse, error)
|
||||||
|
UpdatePigType(ctx context.Context, id uint32, req *dto.UpdatePigTypeRequest) (*dto.PigTypeResponse, error)
|
||||||
|
DeletePigType(ctx context.Context, id uint32) error
|
||||||
|
GetPigType(ctx context.Context, id uint32) (*dto.PigTypeResponse, error)
|
||||||
|
ListPigTypes(ctx context.Context, req *dto.ListPigTypeRequest) (*dto.ListPigTypeResponse, error)
|
||||||
|
UpdatePigTypeNutrientRequirements(ctx context.Context, id uint32, req *dto.UpdatePigTypeNutrientRequirementsRequest) (*dto.PigTypeResponse, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// pigTypeServiceImpl 是 PigTypeService 接口的实现
|
||||||
|
type pigTypeServiceImpl struct {
|
||||||
|
ctx context.Context
|
||||||
|
recipeSvc recipe.Service
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPigTypeService 创建一个新的 PigTypeService 实例
|
||||||
|
func NewPigTypeService(ctx context.Context, recipeSvc recipe.Service) PigTypeService {
|
||||||
|
return &pigTypeServiceImpl{
|
||||||
|
ctx: ctx,
|
||||||
|
recipeSvc: recipeSvc,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatePigType 创建猪类型
|
||||||
|
func (s *pigTypeServiceImpl) CreatePigType(ctx context.Context, req *dto.CreatePigTypeRequest) (*dto.PigTypeResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "CreatePigType")
|
||||||
|
|
||||||
|
pigType := &models.PigType{
|
||||||
|
BreedID: req.BreedID,
|
||||||
|
AgeStageID: req.AgeStageID,
|
||||||
|
Description: req.Description,
|
||||||
|
DailyFeedIntake: req.DailyFeedIntake,
|
||||||
|
DailyGainWeight: req.DailyGainWeight,
|
||||||
|
MinDays: req.MinDays,
|
||||||
|
MaxDays: req.MaxDays,
|
||||||
|
MinWeight: req.MinWeight,
|
||||||
|
MaxWeight: req.MaxWeight,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.recipeSvc.CreatePigType(serviceCtx, pigType); err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrPigBreedNotFound) {
|
||||||
|
return nil, ErrPigBreedNotFound
|
||||||
|
}
|
||||||
|
if errors.Is(err, recipe.ErrPigAgeStageNotFound) {
|
||||||
|
return nil, ErrPigAgeStageNotFound
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("创建猪类型失败: %w", err)
|
||||||
|
}
|
||||||
|
// 创建后需要重新获取,以包含关联数据
|
||||||
|
createdPigType, err := s.recipeSvc.GetPigTypeByID(serviceCtx, pigType.ID)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrPigTypeNotFound) { // 理论上不应该发生,因为刚创建
|
||||||
|
return nil, ErrPigTypeNotFound
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("创建猪类型后获取详情失败: %w", err)
|
||||||
|
}
|
||||||
|
return dto.ConvertPigTypeToDTO(createdPigType), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatePigType 更新猪类型
|
||||||
|
func (s *pigTypeServiceImpl) UpdatePigType(ctx context.Context, id uint32, req *dto.UpdatePigTypeRequest) (*dto.PigTypeResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdatePigType")
|
||||||
|
|
||||||
|
pigType := &models.PigType{
|
||||||
|
Model: models.Model{ID: id},
|
||||||
|
BreedID: req.BreedID,
|
||||||
|
AgeStageID: req.AgeStageID,
|
||||||
|
Description: req.Description,
|
||||||
|
DailyFeedIntake: req.DailyFeedIntake,
|
||||||
|
DailyGainWeight: req.DailyGainWeight,
|
||||||
|
MinDays: req.MinDays,
|
||||||
|
MaxDays: req.MaxDays,
|
||||||
|
MinWeight: req.MinWeight,
|
||||||
|
MaxWeight: req.MaxWeight,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.recipeSvc.UpdatePigType(serviceCtx, pigType); err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrPigTypeNotFound) {
|
||||||
|
return nil, ErrPigTypeNotFound
|
||||||
|
}
|
||||||
|
if errors.Is(err, recipe.ErrPigBreedNotFound) {
|
||||||
|
return nil, ErrPigBreedNotFound
|
||||||
|
}
|
||||||
|
if errors.Is(err, recipe.ErrPigAgeStageNotFound) {
|
||||||
|
return nil, ErrPigAgeStageNotFound
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("更新猪类型失败: %w", err)
|
||||||
|
}
|
||||||
|
// 更新后需要重新获取,以包含关联数据
|
||||||
|
updatedPigType, err := s.recipeSvc.GetPigTypeByID(serviceCtx, id)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrPigTypeNotFound) { // 理论上不应该发生,因为刚更新成功
|
||||||
|
return nil, ErrPigTypeNotFound
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("更新猪类型后获取详情失败: %w", err)
|
||||||
|
}
|
||||||
|
return dto.ConvertPigTypeToDTO(updatedPigType), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletePigType 删除猪类型
|
||||||
|
func (s *pigTypeServiceImpl) DeletePigType(ctx context.Context, id uint32) error {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "DeletePigType")
|
||||||
|
err := s.recipeSvc.DeletePigType(serviceCtx, id)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrPigTypeNotFound) {
|
||||||
|
return ErrPigTypeNotFound
|
||||||
|
}
|
||||||
|
return fmt.Errorf("删除猪类型失败: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPigType 获取单个猪类型
|
||||||
|
func (s *pigTypeServiceImpl) GetPigType(ctx context.Context, id uint32) (*dto.PigTypeResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "GetPigType")
|
||||||
|
|
||||||
|
pigType, err := s.recipeSvc.GetPigTypeByID(serviceCtx, id)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrPigTypeNotFound) {
|
||||||
|
return nil, ErrPigTypeNotFound
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("获取猪类型失败: %w", err)
|
||||||
|
}
|
||||||
|
return dto.ConvertPigTypeToDTO(pigType), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListPigTypes 列出猪类型
|
||||||
|
func (s *pigTypeServiceImpl) ListPigTypes(ctx context.Context, req *dto.ListPigTypeRequest) (*dto.ListPigTypeResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListPigTypes")
|
||||||
|
|
||||||
|
opts := repository.PigTypeListOptions{
|
||||||
|
BreedID: req.BreedID,
|
||||||
|
AgeStageID: req.AgeStageID,
|
||||||
|
BreedName: req.BreedName,
|
||||||
|
AgeStageName: req.AgeStageName,
|
||||||
|
OrderBy: req.OrderBy,
|
||||||
|
}
|
||||||
|
pigTypes, total, err := s.recipeSvc.ListPigTypes(serviceCtx, opts, req.Page, req.PageSize)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("获取猪类型列表失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return dto.ConvertPigTypeListToDTO(pigTypes, total, req.Page, req.PageSize), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatePigTypeNutrientRequirements 全量更新猪类型的营养需求
|
||||||
|
func (s *pigTypeServiceImpl) UpdatePigTypeNutrientRequirements(ctx context.Context, id uint32, req *dto.UpdatePigTypeNutrientRequirementsRequest) (*dto.PigTypeResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdatePigTypeNutrientRequirements")
|
||||||
|
|
||||||
|
// 1. 将 DTO 转换为领域模型
|
||||||
|
requirements := make([]models.PigNutrientRequirement, len(req.NutrientRequirements))
|
||||||
|
for i, item := range req.NutrientRequirements {
|
||||||
|
requirements[i] = models.PigNutrientRequirement{
|
||||||
|
PigTypeID: id, // 设置所属的 PigTypeID
|
||||||
|
NutrientID: item.NutrientID,
|
||||||
|
MinRequirement: item.MinRequirement,
|
||||||
|
MaxRequirement: item.MaxRequirement,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 调用领域服务执行更新命令
|
||||||
|
err := s.recipeSvc.UpdatePigTypeNutrientRequirements(serviceCtx, id, requirements)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrPigTypeNotFound) {
|
||||||
|
return nil, ErrPigTypeNotFound
|
||||||
|
}
|
||||||
|
// 此处可以根据领域层可能返回的其他特定错误进行转换
|
||||||
|
return nil, fmt.Errorf("更新猪类型营养需求失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 更新成功后,调用查询服务获取最新的猪类型信息
|
||||||
|
updatedPigType, err := s.recipeSvc.GetPigTypeByID(serviceCtx, id)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrPigTypeNotFound) {
|
||||||
|
// 理论上不应该发生,因为刚更新成功
|
||||||
|
return nil, ErrPigTypeNotFound
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("更新后获取猪类型信息失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 将领域模型转换为 DTO 并返回
|
||||||
|
return dto.ConvertPigTypeToDTO(updatedPigType), nil
|
||||||
|
}
|
||||||
157
internal/app/service/raw_material_service.go
Normal file
157
internal/app/service/raw_material_service.go
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/domain/recipe"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 定义原料服务特定的错误
|
||||||
|
var (
|
||||||
|
ErrRawMaterialNameConflict = errors.New("原料名称已存在")
|
||||||
|
ErrRawMaterialNotFound = errors.New("原料不存在")
|
||||||
|
)
|
||||||
|
|
||||||
|
// RawMaterialService 定义了原料相关的应用服务接口
|
||||||
|
type RawMaterialService interface {
|
||||||
|
CreateRawMaterial(ctx context.Context, req *dto.CreateRawMaterialRequest) (*dto.RawMaterialResponse, error)
|
||||||
|
UpdateRawMaterial(ctx context.Context, id uint32, req *dto.UpdateRawMaterialRequest) (*dto.RawMaterialResponse, error)
|
||||||
|
DeleteRawMaterial(ctx context.Context, id uint32) error
|
||||||
|
GetRawMaterial(ctx context.Context, id uint32) (*dto.RawMaterialResponse, error)
|
||||||
|
ListRawMaterials(ctx context.Context, req *dto.ListRawMaterialRequest) (*dto.ListRawMaterialResponse, error)
|
||||||
|
UpdateRawMaterialNutrients(ctx context.Context, id uint32, req *dto.UpdateRawMaterialNutrientsRequest) (*dto.RawMaterialResponse, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// rawMaterialServiceImpl 是 RawMaterialService 接口的实现
|
||||||
|
type rawMaterialServiceImpl struct {
|
||||||
|
ctx context.Context
|
||||||
|
recipeSvc recipe.Service
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRawMaterialService 创建一个新的 RawMaterialService 实例
|
||||||
|
func NewRawMaterialService(ctx context.Context, recipeSvc recipe.Service) RawMaterialService {
|
||||||
|
return &rawMaterialServiceImpl{
|
||||||
|
ctx: ctx,
|
||||||
|
recipeSvc: recipeSvc,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRawMaterial 创建原料
|
||||||
|
func (s *rawMaterialServiceImpl) CreateRawMaterial(ctx context.Context, req *dto.CreateRawMaterialRequest) (*dto.RawMaterialResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "CreateRawMaterial")
|
||||||
|
|
||||||
|
rawMaterial, err := s.recipeSvc.CreateRawMaterial(serviceCtx, req.Name, req.Description)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrRawMaterialNameConflict) {
|
||||||
|
return nil, ErrRawMaterialNameConflict
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("创建原料失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return dto.ConvertRawMaterialToDTO(rawMaterial), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateRawMaterial 更新原料
|
||||||
|
func (s *rawMaterialServiceImpl) UpdateRawMaterial(ctx context.Context, id uint32, req *dto.UpdateRawMaterialRequest) (*dto.RawMaterialResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdateRawMaterial")
|
||||||
|
|
||||||
|
rawMaterial, err := s.recipeSvc.UpdateRawMaterial(serviceCtx, id, req.Name, req.Description)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrRawMaterialNotFound) {
|
||||||
|
return nil, ErrRawMaterialNotFound
|
||||||
|
}
|
||||||
|
if errors.Is(err, recipe.ErrRawMaterialNameConflict) {
|
||||||
|
return nil, ErrRawMaterialNameConflict
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("更新原料失败: %w", err)
|
||||||
|
}
|
||||||
|
return dto.ConvertRawMaterialToDTO(rawMaterial), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRawMaterial 删除原料
|
||||||
|
func (s *rawMaterialServiceImpl) DeleteRawMaterial(ctx context.Context, id uint32) error {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "DeleteRawMaterial")
|
||||||
|
err := s.recipeSvc.DeleteRawMaterial(serviceCtx, id)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrRawMaterialNotFound) {
|
||||||
|
return ErrRawMaterialNotFound
|
||||||
|
}
|
||||||
|
return fmt.Errorf("删除原料失败: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRawMaterial 获取单个原料
|
||||||
|
func (s *rawMaterialServiceImpl) GetRawMaterial(ctx context.Context, id uint32) (*dto.RawMaterialResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "GetRawMaterial")
|
||||||
|
|
||||||
|
rawMaterial, err := s.recipeSvc.GetRawMaterial(serviceCtx, id)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrRawMaterialNotFound) {
|
||||||
|
return nil, ErrRawMaterialNotFound
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("获取原料失败: %w", err)
|
||||||
|
}
|
||||||
|
return dto.ConvertRawMaterialToDTO(rawMaterial), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRawMaterials 列出原料
|
||||||
|
func (s *rawMaterialServiceImpl) ListRawMaterials(ctx context.Context, req *dto.ListRawMaterialRequest) (*dto.ListRawMaterialResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListRawMaterials")
|
||||||
|
|
||||||
|
opts := repository.RawMaterialListOptions{
|
||||||
|
Name: req.Name,
|
||||||
|
NutrientName: req.NutrientName,
|
||||||
|
OrderBy: req.OrderBy,
|
||||||
|
}
|
||||||
|
rawMaterials, total, err := s.recipeSvc.ListRawMaterials(serviceCtx, opts, req.Page, req.PageSize)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("获取原料列表失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return dto.ConvertRawMaterialListToDTO(rawMaterials, total, req.Page, req.PageSize), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateRawMaterialNutrients 全量更新原料的营养成分
|
||||||
|
func (s *rawMaterialServiceImpl) UpdateRawMaterialNutrients(ctx context.Context, id uint32, req *dto.UpdateRawMaterialNutrientsRequest) (*dto.RawMaterialResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdateRawMaterialNutrients")
|
||||||
|
|
||||||
|
// 1. 将 DTO 转换为领域模型
|
||||||
|
nutrients := make([]models.RawMaterialNutrient, len(req.Nutrients))
|
||||||
|
for i, item := range req.Nutrients {
|
||||||
|
nutrients[i] = models.RawMaterialNutrient{
|
||||||
|
RawMaterialID: id,
|
||||||
|
NutrientID: item.NutrientID,
|
||||||
|
Value: item.Value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 调用领域服务执行更新命令
|
||||||
|
err := s.recipeSvc.UpdateRawMaterialNutrients(serviceCtx, id, nutrients)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrRawMaterialNotFound) {
|
||||||
|
return nil, ErrRawMaterialNotFound
|
||||||
|
}
|
||||||
|
// 此处可以根据领域层可能返回的其他特定错误进行转换
|
||||||
|
return nil, fmt.Errorf("更新原料营养成分失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 更新成功后,调用查询服务获取最新的原料信息
|
||||||
|
updatedRawMaterial, err := s.recipeSvc.GetRawMaterial(serviceCtx, id)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrRawMaterialNotFound) {
|
||||||
|
// 理论上不应该发生,因为刚更新成功
|
||||||
|
return nil, ErrRawMaterialNotFound
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("更新后获取原料信息失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 将领域模型转换为 DTO 并返回
|
||||||
|
return dto.ConvertRawMaterialToDTO(updatedRawMaterial), nil
|
||||||
|
}
|
||||||
@@ -63,7 +63,11 @@ func NewApplication(configPath string) (*Application, error) {
|
|||||||
appServices.userService,
|
appServices.userService,
|
||||||
appServices.auditService,
|
appServices.auditService,
|
||||||
appServices.thresholdAlarmService,
|
appServices.thresholdAlarmService,
|
||||||
appServices.feedManagementService,
|
appServices.nutrientService,
|
||||||
|
appServices.rawMaterialService,
|
||||||
|
appServices.pigBreedService,
|
||||||
|
appServices.pigAgeStageService,
|
||||||
|
appServices.pigTypeService,
|
||||||
infra.tokenGenerator,
|
infra.tokenGenerator,
|
||||||
infra.lora.listenHandler,
|
infra.lora.listenHandler,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -259,7 +259,11 @@ type AppServices struct {
|
|||||||
userService service.UserService
|
userService service.UserService
|
||||||
auditService service.AuditService
|
auditService service.AuditService
|
||||||
thresholdAlarmService service.ThresholdAlarmService
|
thresholdAlarmService service.ThresholdAlarmService
|
||||||
feedManagementService service.FeedManagementService
|
nutrientService service.NutrientService
|
||||||
|
pigAgeStageService service.PigAgeStageService
|
||||||
|
pigBreedService service.PigBreedService
|
||||||
|
pigTypeService service.PigTypeService
|
||||||
|
rawMaterialService service.RawMaterialService
|
||||||
}
|
}
|
||||||
|
|
||||||
// initAppServices 初始化所有的应用服务。
|
// initAppServices 初始化所有的应用服务。
|
||||||
@@ -307,7 +311,11 @@ func initAppServices(ctx context.Context, infra *Infrastructure, domainServices
|
|||||||
auditService := service.NewAuditService(logs.AddCompName(baseCtx, "AuditService"), infra.repos.userActionLogRepo)
|
auditService := service.NewAuditService(logs.AddCompName(baseCtx, "AuditService"), infra.repos.userActionLogRepo)
|
||||||
planService := service.NewPlanService(logs.AddCompName(baseCtx, "AppPlanService"), domainServices.planService)
|
planService := service.NewPlanService(logs.AddCompName(baseCtx, "AppPlanService"), domainServices.planService)
|
||||||
userService := service.NewUserService(logs.AddCompName(baseCtx, "UserService"), infra.repos.userRepo, infra.tokenGenerator, domainServices.notifyService)
|
userService := service.NewUserService(logs.AddCompName(baseCtx, "UserService"), infra.repos.userRepo, infra.tokenGenerator, domainServices.notifyService)
|
||||||
feedManagementService := service.NewFeedManagementService(logs.AddCompName(baseCtx, "FeedManagementService"), domainServices.recipeService)
|
nutrientService := service.NewNutrientService(logs.AddCompName(baseCtx, "NutrientService"), domainServices.recipeService)
|
||||||
|
pigAgeStageService := service.NewPigAgeStageService(logs.AddCompName(baseCtx, "PigAgeStageService"), domainServices.recipeService)
|
||||||
|
pigBreedService := service.NewPigBreedService(logs.AddCompName(baseCtx, "PigBreedService"), domainServices.recipeService)
|
||||||
|
pigTypeService := service.NewPigTypeService(logs.AddCompName(baseCtx, "PigTypeService"), domainServices.recipeService)
|
||||||
|
rawMaterialService := service.NewRawMaterialService(logs.AddCompName(baseCtx, "RawMaterialService"), domainServices.recipeService)
|
||||||
|
|
||||||
return &AppServices{
|
return &AppServices{
|
||||||
pigFarmService: pigFarmService,
|
pigFarmService: pigFarmService,
|
||||||
@@ -318,7 +326,11 @@ func initAppServices(ctx context.Context, infra *Infrastructure, domainServices
|
|||||||
planService: planService,
|
planService: planService,
|
||||||
userService: userService,
|
userService: userService,
|
||||||
thresholdAlarmService: thresholdAlarmService,
|
thresholdAlarmService: thresholdAlarmService,
|
||||||
feedManagementService: feedManagementService,
|
nutrientService: nutrientService,
|
||||||
|
pigAgeStageService: pigAgeStageService,
|
||||||
|
pigBreedService: pigBreedService,
|
||||||
|
pigTypeService: pigTypeService,
|
||||||
|
rawMaterialService: rawMaterialService,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ internal/app/api/router.go
|
|||||||
internal/app/controller/alarm/threshold_alarm_controller.go
|
internal/app/controller/alarm/threshold_alarm_controller.go
|
||||||
internal/app/controller/auth_utils.go
|
internal/app/controller/auth_utils.go
|
||||||
internal/app/controller/device/device_controller.go
|
internal/app/controller/device/device_controller.go
|
||||||
internal/app/controller/feed/feed_controller.go
|
|
||||||
internal/app/controller/feed/nutrient_controller.go
|
internal/app/controller/feed/nutrient_controller.go
|
||||||
internal/app/controller/feed/pig_age_stage_controller.go
|
internal/app/controller/feed/pig_age_stage_controller.go
|
||||||
internal/app/controller/feed/pig_breed_controller.go
|
internal/app/controller/feed/pig_breed_controller.go
|
||||||
@@ -85,12 +84,16 @@ internal/app/middleware/audit.go
|
|||||||
internal/app/middleware/auth.go
|
internal/app/middleware/auth.go
|
||||||
internal/app/service/audit_service.go
|
internal/app/service/audit_service.go
|
||||||
internal/app/service/device_service.go
|
internal/app/service/device_service.go
|
||||||
internal/app/service/feed_management_service.go
|
|
||||||
internal/app/service/monitor_service.go
|
internal/app/service/monitor_service.go
|
||||||
|
internal/app/service/nutrient_service.go
|
||||||
|
internal/app/service/pig_age_stage_service.go
|
||||||
internal/app/service/pig_batch_service.go
|
internal/app/service/pig_batch_service.go
|
||||||
|
internal/app/service/pig_breed_service.go
|
||||||
internal/app/service/pig_farm_service.go
|
internal/app/service/pig_farm_service.go
|
||||||
internal/app/service/pig_service.go
|
internal/app/service/pig_service.go
|
||||||
|
internal/app/service/pig_type_service.go
|
||||||
internal/app/service/plan_service.go
|
internal/app/service/plan_service.go
|
||||||
|
internal/app/service/raw_material_service.go
|
||||||
internal/app/service/threshold_alarm_service.go
|
internal/app/service/threshold_alarm_service.go
|
||||||
internal/app/service/user_service.go
|
internal/app/service/user_service.go
|
||||||
internal/app/webhook/chirp_stack.go
|
internal/app/webhook/chirp_stack.go
|
||||||
|
|||||||
Reference in New Issue
Block a user