From 77ab434d17b66d6ce7e00877b41562ccc068a2e8 Mon Sep 17 00:00:00 2001 From: huang <1724659546@qq.com> Date: Tue, 7 Oct 2025 00:18:17 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AE=80=E5=8C=96=E6=8E=A7=E5=88=B6=E5=99=A8?= =?UTF-8?q?=E5=B1=82=E9=87=8D=E5=A4=8D=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../management/controller_helpers.go | 184 ++++++------------ .../management/pig_batch_health_controller.go | 12 +- .../management/pig_batch_trade_controller.go | 4 +- .../pig_batch_transfer_controller.go | 4 +- 4 files changed, 74 insertions(+), 130 deletions(-) diff --git a/internal/app/controller/management/controller_helpers.go b/internal/app/controller/management/controller_helpers.go index ee43ed9..a37bd27 100644 --- a/internal/app/controller/management/controller_helpers.go +++ b/internal/app/controller/management/controller_helpers.go @@ -32,50 +32,40 @@ func mapAndSendError(c *PigBatchController, ctx *gin.Context, action string, err // idExtractorFunc 定义了一个函数类型,用于从gin.Context中提取主ID。 type idExtractorFunc func(ctx *gin.Context) (uint, error) -// handleAPIRequest 封装了控制器中处理带有请求体和路径参数的API请求的通用逻辑。 -// 它负责请求体绑定、操作员ID获取、服务层调用、错误映射和响应发送。 +// extractOperatorAndPrimaryID 封装了从gin.Context中提取操作员ID和主ID的通用逻辑。 +// 它负责处理ID提取过程中的错误,并发送相应的HTTP响应。 // // 参数: // -// c: *PigBatchController - 控制器实例,用于访问其服务和日志。 +// c: *PigBatchController - 控制器实例,用于访问其日志。 // ctx: *gin.Context - Gin上下文。 // action: string - 当前操作的描述,用于日志和审计。 -// reqDTO: Req - 请求数据传输对象。 -// serviceExecutor: func(ctx *gin.Context, operatorID uint, primaryID uint, req Req) error - 实际执行服务层逻辑的回调函数。 -// 这个回调函数负责从ctx中解析所有必要的路径参数(除了primaryID,如果idExtractorFunc提供了), -// 获取operatorID,并调用具体的服务方法。 -// successMsg: string - 操作成功时返回给客户端的消息。 // idExtractor: idExtractorFunc - 可选函数,用于从ctx中提取主ID。如果为nil,则尝试从":id"路径参数中提取。 -func handleAPIRequest[Req any]( // 使用泛型Req +// +// 返回值: +// +// operatorID: uint - 提取到的操作员ID。 +// primaryID: uint - 提取到的主ID。 +// ok: bool - 如果ID提取成功且没有发送错误响应,则为true。 +func extractOperatorAndPrimaryID( c *PigBatchController, ctx *gin.Context, action string, - reqDTO Req, - serviceExecutor func(ctx *gin.Context, operatorID uint, primaryID uint, req Req) error, - successMsg string, idExtractor idExtractorFunc, -) { - var primaryID uint // 用于审计和日志的主ID - - // 1. 绑定请求体 - if err := ctx.ShouldBindJSON(&reqDTO); err != nil { - controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体", action, "请求体绑定失败", reqDTO) - return - } - - // 2. 获取操作员ID +) (operatorID uint, primaryID uint, ok bool) { + // 1. 获取操作员ID operatorID, err := controller.GetOperatorIDFromContext(ctx) if err != nil { controller.SendErrorWithAudit(ctx, controller.CodeUnauthorized, "未授权", action, "无法获取操作员ID", nil) - return + return 0, 0, false } - // 3. 提取主ID + // 2. 提取主ID if idExtractor != nil { primaryID, err = idExtractor(ctx) if err != nil { controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的ID格式", action, "ID格式错误", err.Error()) - return + return 0, 0, false } } else { // 默认从 ":id" 路径参数提取 idParam := ctx.Param("id") @@ -85,20 +75,46 @@ func handleAPIRequest[Req any]( // 使用泛型Req parsedID, err := strconv.ParseUint(idParam, 10, 32) if err != nil { controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的ID格式", action, "ID格式错误", idParam) - return + return 0, 0, false } primaryID = uint(parsedID) } } - // 4. 执行服务层逻辑 - err = serviceExecutor(ctx, operatorID, primaryID, reqDTO) + return operatorID, primaryID, true +} + +// handleAPIRequest 封装了控制器中处理带有请求体和路径参数的API请求的通用逻辑。 +// 它负责请求体绑定、操作员ID获取、服务层调用、错误映射和响应发送。 +func handleAPIRequest[Req any]( + c *PigBatchController, + ctx *gin.Context, + action string, + reqDTO Req, + serviceExecutor func(ctx *gin.Context, operatorID uint, primaryID uint, req Req) error, + successMsg string, + idExtractor idExtractorFunc, +) { + // 1. 绑定请求体 + if err := ctx.ShouldBindJSON(&reqDTO); err != nil { + controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体", action, "请求体绑定失败", reqDTO) + return + } + + // 2. 提取操作员ID和主ID + operatorID, primaryID, ok := extractOperatorAndPrimaryID(c, ctx, action, idExtractor) + if !ok { + return // 错误已在 extractOperatorAndPrimaryID 中处理 + } + + // 3. 执行服务层逻辑 + err := serviceExecutor(ctx, operatorID, primaryID, reqDTO) if err != nil { mapAndSendError(c, ctx, action, err, primaryID) return } - // 5. 发送成功响应 + // 4. 发送成功响应 controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, successMsg, nil, action, successMsg, primaryID) } @@ -111,44 +127,20 @@ func handleNoBodyAPIRequest( successMsg string, idExtractor idExtractorFunc, ) { - var primaryID uint // 用于审计和日志的主ID - - // 1. 获取操作员ID - operatorID, err := controller.GetOperatorIDFromContext(ctx) - if err != nil { - controller.SendErrorWithAudit(ctx, controller.CodeUnauthorized, "未授权", action, "无法获取操作员ID", nil) - return + // 1. 提取操作员ID和主ID + operatorID, primaryID, ok := extractOperatorAndPrimaryID(c, ctx, action, idExtractor) + if !ok { + return // 错误已在 extractOperatorAndPrimaryID 中处理 } - // 2. 提取主ID - if idExtractor != nil { - primaryID, err = idExtractor(ctx) - if err != nil { - controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的ID格式", action, "ID格式错误", err.Error()) - return - } - } else { // 默认从 ":id" 路径参数提取 - idParam := ctx.Param("id") - if idParam == "" { - // 如果没有ID参数且没有自定义提取器,primaryID保持为0 - } else { - parsedID, err := strconv.ParseUint(idParam, 10, 32) - if err != nil { - controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的ID格式", action, "ID格式错误", idParam) - return - } - primaryID = uint(parsedID) - } - } - - // 3. 执行服务层逻辑 - err = serviceExecutor(ctx, operatorID, primaryID) + // 2. 执行服务层逻辑 + err := serviceExecutor(ctx, operatorID, primaryID) if err != nil { mapAndSendError(c, ctx, action, err, primaryID) return } - // 4. 发送成功响应 + // 3. 发送成功响应 controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, successMsg, nil, action, successMsg, primaryID) } @@ -162,50 +154,26 @@ func handleAPIRequestWithResponse[Req any, Resp any]( successMsg string, idExtractor idExtractorFunc, ) { - var primaryID uint // 用于审计和日志的主ID - // 1. 绑定请求体 if err := ctx.ShouldBindJSON(&reqDTO); err != nil { controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体", action, "请求体绑定失败", reqDTO) return } - // 2. 获取操作员ID - operatorID, err := controller.GetOperatorIDFromContext(ctx) - if err != nil { - controller.SendErrorWithAudit(ctx, controller.CodeUnauthorized, "未授权", action, "无法获取操作员ID", nil) - return + // 2. 提取操作员ID和主ID + operatorID, primaryID, ok := extractOperatorAndPrimaryID(c, ctx, action, idExtractor) + if !ok { + return // 错误已在 extractOperatorAndPrimaryID 中处理 } - // 3. 提取主ID - if idExtractor != nil { - primaryID, err = idExtractor(ctx) - if err != nil { - controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的ID格式", action, "ID格式错误", err.Error()) - return - } - } else { // 默认从 ":id" 路径参数提取 - idParam := ctx.Param("id") - if idParam == "" { // 有些端点可能没有 "id" 参数,例如列表或创建操作 - // 如果没有ID参数且没有自定义提取器,primaryID保持为0,这对于某些操作是可接受的 - } else { - parsedID, err := strconv.ParseUint(idParam, 10, 32) - if err != nil { - controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的ID格式", action, "ID格式错误", idParam) - return - } - primaryID = uint(parsedID) - } - } - - // 4. 执行服务层逻辑 + // 3. 执行服务层逻辑 respDTO, err := serviceExecutor(ctx, operatorID, primaryID, reqDTO) if err != nil { mapAndSendError(c, ctx, action, err, primaryID) return } - // 5. 发送成功响应 + // 4. 发送成功响应 controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, successMsg, respDTO, action, successMsg, primaryID) } @@ -218,44 +186,20 @@ func handleNoBodyAPIRequestWithResponse[Resp any]( successMsg string, idExtractor idExtractorFunc, ) { - var primaryID uint // 用于审计和日志的主ID - - // 1. 获取操作员ID - operatorID, err := controller.GetOperatorIDFromContext(ctx) - if err != nil { - controller.SendErrorWithAudit(ctx, controller.CodeUnauthorized, "未授权", action, "无法获取操作员ID", nil) - return + // 1. 提取操作员ID和主ID + operatorID, primaryID, ok := extractOperatorAndPrimaryID(c, ctx, action, idExtractor) + if !ok { + return // 错误已在 extractOperatorAndPrimaryID 中处理 } - // 2. 提取主ID - if idExtractor != nil { - primaryID, err = idExtractor(ctx) - if err != nil { - controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的ID格式", action, "ID格式错误", err.Error()) - return - } - } else { // 默认从 ":id" 路径参数提取 - idParam := ctx.Param("id") - if idParam == "" { - // 如果没有ID参数且没有自定义提取器,primaryID保持为0 - } else { - parsedID, err := strconv.ParseUint(idParam, 10, 32) - if err != nil { - controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的ID格式", action, "ID格式错误", idParam) - return - } - primaryID = uint(parsedID) - } - } - - // 3. 执行服务层逻辑 + // 2. 执行服务层逻辑 respDTO, err := serviceExecutor(ctx, operatorID, primaryID) if err != nil { mapAndSendError(c, ctx, action, err, primaryID) return } - // 4. 发送成功响应 + // 3. 发送成功响应 controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, successMsg, respDTO, action, successMsg, primaryID) } diff --git a/internal/app/controller/management/pig_batch_health_controller.go b/internal/app/controller/management/pig_batch_health_controller.go index 6afb94a..0bcff82 100644 --- a/internal/app/controller/management/pig_batch_health_controller.go +++ b/internal/app/controller/management/pig_batch_health_controller.go @@ -8,7 +8,7 @@ import ( // RecordSickPigs godoc // @Summary 记录新增病猪事件 // @Description 记录猪批次中新增病猪的数量、治疗地点和发生时间 -// @Tags 猪批次管理 +// @Tags 猪群管理 // @Accept json // @Produce json // @Param id path int true "猪批次ID" @@ -32,7 +32,7 @@ func (c *PigBatchController) RecordSickPigs(ctx *gin.Context) { // RecordSickPigRecovery godoc // @Summary 记录病猪康复事件 // @Description 记录猪批次中病猪康复的数量、治疗地点和发生时间 -// @Tags 猪批次管理 +// @Tags 猪群管理 // @Accept json // @Produce json // @Param id path int true "猪批次ID" @@ -56,7 +56,7 @@ func (c *PigBatchController) RecordSickPigRecovery(ctx *gin.Context) { // RecordSickPigDeath godoc // @Summary 记录病猪死亡事件 // @Description 记录猪批次中病猪死亡的数量、治疗地点和发生时间 -// @Tags 猪批次管理 +// @Tags 猪群管理 // @Accept json // @Produce json // @Param id path int true "猪批次ID" @@ -80,7 +80,7 @@ func (c *PigBatchController) RecordSickPigDeath(ctx *gin.Context) { // RecordSickPigCull godoc // @Summary 记录病猪淘汰事件 // @Description 记录猪批次中病猪淘汰的数量、治疗地点和发生时间 -// @Tags 猪批次管理 +// @Tags 猪群管理 // @Accept json // @Produce json // @Param id path int true "猪批次ID" @@ -104,7 +104,7 @@ func (c *PigBatchController) RecordSickPigCull(ctx *gin.Context) { // RecordDeath godoc // @Summary 记录正常猪只死亡事件 // @Description 记录猪批次中正常猪只死亡的数量和发生时间 -// @Tags 猪批次管理 +// @Tags 猪群管理 // @Accept json // @Produce json // @Param id path int true "猪批次ID" @@ -128,7 +128,7 @@ func (c *PigBatchController) RecordDeath(ctx *gin.Context) { // RecordCull godoc // @Summary 记录正常猪只淘汰事件 // @Description 记录猪批次中正常猪只淘汰的数量和发生时间 -// @Tags 猪批次管理 +// @Tags 猪群管理 // @Accept json // @Produce json // @Param id path int true "猪批次ID" diff --git a/internal/app/controller/management/pig_batch_trade_controller.go b/internal/app/controller/management/pig_batch_trade_controller.go index 08f2505..74e5bd8 100644 --- a/internal/app/controller/management/pig_batch_trade_controller.go +++ b/internal/app/controller/management/pig_batch_trade_controller.go @@ -8,7 +8,7 @@ import ( // SellPigs godoc // @Summary 处理卖猪的业务逻辑 // @Description 记录猪批次中的猪只出售事件 -// @Tags 猪批次管理 +// @Tags 猪群管理 // @Accept json // @Produce json // @Param id path int true "猪批次ID" @@ -32,7 +32,7 @@ func (c *PigBatchController) SellPigs(ctx *gin.Context) { // BuyPigs godoc // @Summary 处理买猪的业务逻辑 // @Description 记录猪批次中的猪只购买事件 -// @Tags 猪批次管理 +// @Tags 猪群管理 // @Accept json // @Produce json // @Param id path int true "猪批次ID" diff --git a/internal/app/controller/management/pig_batch_transfer_controller.go b/internal/app/controller/management/pig_batch_transfer_controller.go index 005a234..9089791 100644 --- a/internal/app/controller/management/pig_batch_transfer_controller.go +++ b/internal/app/controller/management/pig_batch_transfer_controller.go @@ -10,7 +10,7 @@ import ( // TransferPigsAcrossBatches godoc // @Summary 跨猪群调栏 // @Description 将指定数量的猪只从一个猪群的猪栏调动到另一个猪群的猪栏 -// @Tags 猪批次管理 +// @Tags 猪群管理 // @Accept json // @Produce json // @Param sourceBatchID path int true "源猪批次ID" @@ -42,7 +42,7 @@ func (c *PigBatchController) TransferPigsAcrossBatches(ctx *gin.Context) { // TransferPigsWithinBatch godoc // @Summary 群内调栏 // @Description 将指定数量的猪只在同一个猪群的不同猪栏间调动 -// @Tags 猪批次管理 +// @Tags 猪群管理 // @Accept json // @Produce json // @Param id path int true "猪批次ID"