修复报错

This commit is contained in:
2025-11-05 23:10:51 +08:00
parent 10b123ab93
commit a1f7c09b2a
12 changed files with 51 additions and 44 deletions

View File

@@ -1,19 +1,21 @@
package management
import (
"context"
"errors"
"fmt"
"strconv"
"git.huangwc.com/pig/pig-farm-controller/internal/app/controller"
"git.huangwc.com/pig/pig-farm-controller/internal/app/service"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
"github.com/labstack/echo/v4"
)
// mapAndSendError 统一映射服务层错误并发送响应。
// 这个函数将服务层返回的错误转换为控制器层应返回的HTTP状态码和审计信息。
func mapAndSendError(c *PigBatchController, ctx echo.Context, action string, err error, id uint) error {
func mapAndSendError(reqContext context.Context, c *PigBatchController, ctx echo.Context, action string, err error, id uint) error {
if errors.Is(err, service.ErrPigBatchNotFound) ||
errors.Is(err, service.ErrPenNotFound) ||
errors.Is(err, service.ErrPenNotAssociatedWithBatch) {
@@ -26,7 +28,7 @@ func mapAndSendError(c *PigBatchController, ctx echo.Context, action string, err
errors.Is(err, service.ErrPenNotEmpty) {
return controller.SendErrorWithAudit(ctx, controller.CodeConflict, err.Error(), action, err.Error(), id)
} else {
c.logger.Errorf("操作[%s]业务逻辑失败: %v", action, err)
logs.GetLogger(reqContext).Errorf("操作[%s]业务逻辑失败: %v", action, err)
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, fmt.Sprintf("操作失败: %v", err), action, err.Error(), id)
}
}
@@ -86,6 +88,7 @@ func extractOperatorAndPrimaryID(
// handleAPIRequest 封装了控制器中处理带有请求体和路径参数的API请求的通用逻辑。
// 它负责请求体绑定、操作员ID获取、服务层调用、错误映射和响应发送。
func handleAPIRequest[Req any](
reqContext context.Context,
c *PigBatchController,
ctx echo.Context,
action string,
@@ -108,7 +111,7 @@ func handleAPIRequest[Req any](
// 3. 执行服务层逻辑
err = serviceExecutor(ctx, operatorID, primaryID, reqDTO)
if err != nil {
return mapAndSendError(c, ctx, action, err, primaryID)
return mapAndSendError(reqContext, c, ctx, action, err, primaryID)
}
// 4. 发送成功响应
@@ -117,6 +120,7 @@ func handleAPIRequest[Req any](
// handleNoBodyAPIRequest 封装了处理不带请求体但有路径参数和操作员ID的API请求的通用逻辑。
func handleNoBodyAPIRequest(
reqContext context.Context,
c *PigBatchController,
ctx echo.Context,
action string,
@@ -133,7 +137,7 @@ func handleNoBodyAPIRequest(
// 2. 执行服务层逻辑
err = serviceExecutor(ctx, operatorID, primaryID)
if err != nil {
return mapAndSendError(c, ctx, action, err, primaryID)
return mapAndSendError(reqContext, c, ctx, action, err, primaryID)
}
// 3. 发送成功响应
@@ -142,6 +146,7 @@ func handleNoBodyAPIRequest(
// handleAPIRequestWithResponse 封装了控制器中处理带有请求体、路径参数并返回响应DTO的API请求的通用逻辑。
func handleAPIRequestWithResponse[Req any, Resp any](
reqContext context.Context,
c *PigBatchController,
ctx echo.Context,
action string,
@@ -164,7 +169,7 @@ func handleAPIRequestWithResponse[Req any, Resp any](
// 3. 执行服务层逻辑
respDTO, err := serviceExecutor(ctx, operatorID, primaryID, reqDTO)
if err != nil {
return mapAndSendError(c, ctx, action, err, primaryID)
return mapAndSendError(reqContext, c, ctx, action, err, primaryID)
}
// 4. 发送成功响应
@@ -173,6 +178,7 @@ func handleAPIRequestWithResponse[Req any, Resp any](
// handleNoBodyAPIRequestWithResponse 封装了处理不带请求体但有路径参数和操作员ID并返回响应DTO的API请求的通用逻辑。
func handleNoBodyAPIRequestWithResponse[Resp any](
reqContext context.Context,
c *PigBatchController,
ctx echo.Context,
action string,
@@ -189,7 +195,7 @@ func handleNoBodyAPIRequestWithResponse[Resp any](
// 2. 执行服务层逻辑
respDTO, err := serviceExecutor(ctx, operatorID, primaryID)
if err != nil {
return mapAndSendError(c, ctx, action, err, primaryID)
return mapAndSendError(reqContext, c, ctx, action, err, primaryID)
}
// 3. 发送成功响应
@@ -198,6 +204,7 @@ func handleNoBodyAPIRequestWithResponse[Resp any](
// handleQueryAPIRequestWithResponse 封装了处理带有查询参数并返回响应DTO的API请求的通用逻辑。
func handleQueryAPIRequestWithResponse[Query any, Resp any](
reqContext context.Context,
c *PigBatchController,
ctx echo.Context,
action string,
@@ -220,7 +227,7 @@ func handleQueryAPIRequestWithResponse[Query any, Resp any](
respDTO, err := serviceExecutor(ctx, operatorID, queryDTO)
if err != nil {
// 对于列表查询通常没有primaryID所以传递0
return mapAndSendError(c, ctx, action, err, 0)
return mapAndSendError(reqContext, c, ctx, action, err, 0)
}
// 4. 发送成功响应

View File

@@ -42,7 +42,7 @@ func (c *PigBatchController) CreatePigBatch(ctx echo.Context) error {
var req dto.PigBatchCreateDTO
return handleAPIRequestWithResponse(
c, ctx, action, &req,
reqCtx, c, ctx, action, &req,
func(ctx echo.Context, operatorID uint, primaryID uint, req *dto.PigBatchCreateDTO) (*dto.PigBatchResponseDTO, error) {
// 对于创建操作primaryID通常不从路径中获取而是由服务层生成
return c.service.CreatePigBatch(reqCtx, operatorID, req)
@@ -67,7 +67,7 @@ func (c *PigBatchController) GetPigBatch(ctx echo.Context) error {
const action = "获取猪批次"
return handleNoBodyAPIRequestWithResponse(
c, ctx, action,
reqCtx, c, ctx, action,
func(ctx echo.Context, operatorID uint, primaryID uint) (*dto.PigBatchResponseDTO, error) {
return c.service.GetPigBatch(reqCtx, primaryID)
},
@@ -94,7 +94,7 @@ func (c *PigBatchController) UpdatePigBatch(ctx echo.Context) error {
var req dto.PigBatchUpdateDTO
return handleAPIRequestWithResponse(
c, ctx, action, &req,
reqCtx, c, ctx, action, &req,
func(ctx echo.Context, operatorID uint, primaryID uint, req *dto.PigBatchUpdateDTO) (*dto.PigBatchResponseDTO, error) {
return c.service.UpdatePigBatch(reqCtx, primaryID, req)
},
@@ -118,7 +118,7 @@ func (c *PigBatchController) DeletePigBatch(ctx echo.Context) error {
const action = "删除猪批次"
return handleNoBodyAPIRequest(
c, ctx, action,
reqCtx, c, ctx, action,
func(ctx echo.Context, operatorID uint, primaryID uint) error {
return c.service.DeletePigBatch(reqCtx, primaryID)
},
@@ -143,7 +143,7 @@ func (c *PigBatchController) ListPigBatches(ctx echo.Context) error {
var query dto.PigBatchQueryDTO
return handleQueryAPIRequestWithResponse(
c, ctx, action, &query,
reqCtx, c, ctx, action, &query,
func(ctx echo.Context, operatorID uint, query *dto.PigBatchQueryDTO) ([]*dto.PigBatchResponseDTO, error) {
return c.service.ListPigBatches(reqCtx, query.IsActive)
},
@@ -169,7 +169,7 @@ func (c *PigBatchController) AssignEmptyPensToBatch(ctx echo.Context) error {
var req dto.AssignEmptyPensToBatchRequest
return handleAPIRequest(
c, ctx, action, &req,
reqCtx, c, ctx, action, &req,
func(ctx echo.Context, operatorID uint, primaryID uint, req *dto.AssignEmptyPensToBatchRequest) error {
return c.service.AssignEmptyPensToBatch(reqCtx, primaryID, req.PenIDs, operatorID)
},
@@ -196,7 +196,7 @@ func (c *PigBatchController) ReclassifyPenToNewBatch(ctx echo.Context) error {
var req dto.ReclassifyPenToNewBatchRequest
return handleAPIRequest(
c, ctx, action, &req,
reqCtx, c, ctx, action, &req,
func(ctx echo.Context, operatorID uint, primaryID uint, req *dto.ReclassifyPenToNewBatchRequest) error {
// primaryID 在这里是 fromBatchID
return c.service.ReclassifyPenToNewBatch(reqCtx, primaryID, req.ToBatchID, req.PenID, operatorID, req.Remarks)
@@ -229,7 +229,7 @@ func (c *PigBatchController) RemoveEmptyPenFromBatch(ctx echo.Context) error {
const action = "从猪批次移除空栏"
return handleNoBodyAPIRequest(
c, ctx, action,
reqCtx, c, ctx, action,
func(ctx echo.Context, operatorID uint, primaryID uint) error {
// primaryID 在这里是 batchID
penIDParam := ctx.Param("penID")
@@ -269,7 +269,7 @@ func (c *PigBatchController) MovePigsIntoPen(ctx echo.Context) error {
var req dto.MovePigsIntoPenRequest
return handleAPIRequest(
c, ctx, action, &req,
reqCtx, c, ctx, action, &req,
func(ctx echo.Context, operatorID uint, primaryID uint, req *dto.MovePigsIntoPenRequest) error {
return c.service.MovePigsIntoPen(reqCtx, primaryID, req.ToPenID, req.Quantity, operatorID, req.Remarks)
},

View File

@@ -25,9 +25,9 @@ func (c *PigBatchController) RecordSickPigs(ctx echo.Context) error {
var req dto.RecordSickPigsRequest
return handleAPIRequest(
c, ctx, action, &req,
reqCtx, c, ctx, action, &req,
func(ctx echo.Context, operatorID uint, primaryID uint, req *dto.RecordSickPigsRequest) error {
return c.service.RecordSickPigs(reqCtx, primaryID, req.PenID, req.Quantity, req.TreatmentLocation, req.HappenedAt, req.Remarks)
return c.service.RecordSickPigs(reqCtx, operatorID, primaryID, req.PenID, req.Quantity, req.TreatmentLocation, req.HappenedAt, req.Remarks)
},
"记录成功",
nil, // 默认从 ":id" 路径参数提取ID
@@ -52,7 +52,7 @@ func (c *PigBatchController) RecordSickPigRecovery(ctx echo.Context) error {
var req dto.RecordSickPigRecoveryRequest
return handleAPIRequest(
c, ctx, action, &req,
reqCtx, c, ctx, action, &req,
func(ctx echo.Context, operatorID uint, primaryID uint, req *dto.RecordSickPigRecoveryRequest) error {
return c.service.RecordSickPigRecovery(reqCtx, operatorID, primaryID, req.PenID, req.Quantity, req.TreatmentLocation, req.HappenedAt, req.Remarks)
},
@@ -79,7 +79,7 @@ func (c *PigBatchController) RecordSickPigDeath(ctx echo.Context) error {
var req dto.RecordSickPigDeathRequest
return handleAPIRequest(
c, ctx, action, &req,
reqCtx, c, ctx, action, &req,
func(ctx echo.Context, operatorID uint, primaryID uint, req *dto.RecordSickPigDeathRequest) error {
return c.service.RecordSickPigDeath(reqCtx, operatorID, primaryID, req.PenID, req.Quantity, req.TreatmentLocation, req.HappenedAt, req.Remarks)
},
@@ -106,7 +106,7 @@ func (c *PigBatchController) RecordSickPigCull(ctx echo.Context) error {
var req dto.RecordSickPigCullRequest
return handleAPIRequest(
c, ctx, action, &req,
reqCtx, c, ctx, action, &req,
func(ctx echo.Context, operatorID uint, primaryID uint, req *dto.RecordSickPigCullRequest) error {
return c.service.RecordSickPigCull(reqCtx, operatorID, primaryID, req.PenID, req.Quantity, req.TreatmentLocation, req.HappenedAt, req.Remarks)
},
@@ -133,7 +133,7 @@ func (c *PigBatchController) RecordDeath(ctx echo.Context) error {
var req dto.RecordDeathRequest
return handleAPIRequest(
c, ctx, action, &req,
reqCtx, c, ctx, action, &req,
func(ctx echo.Context, operatorID uint, primaryID uint, req *dto.RecordDeathRequest) error {
return c.service.RecordDeath(reqCtx, operatorID, primaryID, req.PenID, req.Quantity, req.HappenedAt, req.Remarks)
},
@@ -160,7 +160,7 @@ func (c *PigBatchController) RecordCull(ctx echo.Context) error {
var req dto.RecordCullRequest
return handleAPIRequest(
c, ctx, action, &req,
reqCtx, c, ctx, action, &req,
func(ctx echo.Context, operatorID uint, primaryID uint, req *dto.RecordCullRequest) error {
return c.service.RecordCull(reqCtx, operatorID, primaryID, req.PenID, req.Quantity, req.HappenedAt, req.Remarks)
},

View File

@@ -24,7 +24,7 @@ func (c *PigBatchController) SellPigs(ctx echo.Context) error {
var req dto.SellPigsRequest
return handleAPIRequest(
c, ctx, action, &req,
reqCtx, c, ctx, action, &req,
func(ctx echo.Context, operatorID uint, primaryID uint, req *dto.SellPigsRequest) error {
return c.service.SellPigs(reqCtx, primaryID, req.PenID, req.Quantity, req.UnitPrice, req.TotalPrice, req.TraderName, req.TradeDate, req.Remarks, operatorID)
},
@@ -50,7 +50,7 @@ func (c *PigBatchController) BuyPigs(ctx echo.Context) error {
var req dto.BuyPigsRequest
return handleAPIRequest(
c, ctx, action, &req,
reqCtx, c, ctx, action, &req,
func(ctx echo.Context, operatorID uint, primaryID uint, req *dto.BuyPigsRequest) error {
return c.service.BuyPigs(reqCtx, primaryID, req.PenID, req.Quantity, req.UnitPrice, req.TotalPrice, req.TraderName, req.TradeDate, req.Remarks, operatorID)
},

View File

@@ -27,7 +27,7 @@ func (c *PigBatchController) TransferPigsAcrossBatches(ctx echo.Context) error {
var req dto.TransferPigsAcrossBatchesRequest
return handleAPIRequest(
c, ctx, action, &req,
reqCtx, c, ctx, action, &req,
func(ctx echo.Context, operatorID uint, primaryID uint, req *dto.TransferPigsAcrossBatchesRequest) error {
// primaryID 在这里是 sourceBatchID
return c.service.TransferPigsAcrossBatches(reqCtx, primaryID, req.DestBatchID, req.FromPenID, req.ToPenID, req.Quantity, operatorID, req.Remarks)
@@ -62,7 +62,7 @@ func (c *PigBatchController) TransferPigsWithinBatch(ctx echo.Context) error {
var req dto.TransferPigsWithinBatchRequest
return handleAPIRequest(
c, ctx, action, &req,
reqCtx, c, ctx, action, &req,
func(ctx echo.Context, operatorID uint, primaryID uint, req *dto.TransferPigsWithinBatchRequest) error {
// primaryID 在这里是 batchID
return c.service.TransferPigsWithinBatch(reqCtx, primaryID, req.FromPenID, req.ToPenID, req.Quantity, operatorID, req.Remarks)