实现猪批次增删改查
This commit is contained in:
@@ -48,6 +48,7 @@ type API struct {
|
|||||||
deviceController *device.Controller // 设备控制器实例
|
deviceController *device.Controller // 设备控制器实例
|
||||||
planController *plan.Controller // 计划控制器实例
|
planController *plan.Controller // 计划控制器实例
|
||||||
pigFarmController *management.PigFarmController // 猪场管理控制器实例
|
pigFarmController *management.PigFarmController // 猪场管理控制器实例
|
||||||
|
pigBatchController *management.PigBatchController // 猪批次控制器实例
|
||||||
listenHandler webhook.ListenHandler // 设备上行事件监听器
|
listenHandler webhook.ListenHandler // 设备上行事件监听器
|
||||||
analysisTaskManager *task.AnalysisPlanTaskManager // 计划触发器管理器实例
|
analysisTaskManager *task.AnalysisPlanTaskManager // 计划触发器管理器实例
|
||||||
}
|
}
|
||||||
@@ -62,6 +63,7 @@ func NewAPI(cfg config.ServerConfig,
|
|||||||
deviceTemplateRepository repository.DeviceTemplateRepository, // 添加设备模板仓库
|
deviceTemplateRepository repository.DeviceTemplateRepository, // 添加设备模板仓库
|
||||||
planRepository repository.PlanRepository,
|
planRepository repository.PlanRepository,
|
||||||
pigFarmService service.PigFarmService,
|
pigFarmService service.PigFarmService,
|
||||||
|
pigBatchService service.PigBatchService, // 添加猪批次服务
|
||||||
userActionLogRepository repository.UserActionLogRepository,
|
userActionLogRepository repository.UserActionLogRepository,
|
||||||
tokenService token.TokenService,
|
tokenService token.TokenService,
|
||||||
auditService audit.Service, // 注入审计服务
|
auditService audit.Service, // 注入审计服务
|
||||||
@@ -96,6 +98,8 @@ func NewAPI(cfg config.ServerConfig,
|
|||||||
planController: plan.NewController(logger, planRepository, analysisTaskManager),
|
planController: plan.NewController(logger, planRepository, analysisTaskManager),
|
||||||
// 在 NewAPI 中初始化猪场管理控制器
|
// 在 NewAPI 中初始化猪场管理控制器
|
||||||
pigFarmController: management.NewPigFarmController(logger, pigFarmService),
|
pigFarmController: management.NewPigFarmController(logger, pigFarmService),
|
||||||
|
// 在 NewAPI 中初始化猪批次控制器
|
||||||
|
pigBatchController: management.NewPigBatchController(logger, pigBatchService),
|
||||||
}
|
}
|
||||||
|
|
||||||
api.setupRoutes() // 设置所有路由
|
api.setupRoutes() // 设置所有路由
|
||||||
@@ -221,6 +225,17 @@ func (a *API) setupRoutes() {
|
|||||||
}
|
}
|
||||||
a.logger.Info("猪圈相关接口注册成功 (需要认证和审计)")
|
a.logger.Info("猪圈相关接口注册成功 (需要认证和审计)")
|
||||||
|
|
||||||
|
// 猪批次相关路由组
|
||||||
|
pigBatchGroup := authGroup.Group("/pig-batches")
|
||||||
|
{
|
||||||
|
pigBatchGroup.POST("", a.pigBatchController.CreatePigBatch)
|
||||||
|
pigBatchGroup.GET("", a.pigBatchController.ListPigBatches)
|
||||||
|
pigBatchGroup.GET("/:id", a.pigBatchController.GetPigBatch)
|
||||||
|
pigBatchGroup.PUT("/:id", a.pigBatchController.UpdatePigBatch)
|
||||||
|
pigBatchGroup.DELETE("/:id", a.pigBatchController.DeletePigBatch)
|
||||||
|
}
|
||||||
|
a.logger.Info("猪批次相关接口注册成功 (需要认证和审计)")
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
190
internal/app/controller/management/pig_batch_controller.go
Normal file
190
internal/app/controller/management/pig_batch_controller.go
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
package management
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/app/controller"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/app/service"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PigBatchController 负责处理猪批次相关的API请求
|
||||||
|
type PigBatchController struct {
|
||||||
|
logger *logs.Logger
|
||||||
|
service service.PigBatchService
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPigBatchController 创建一个新的 PigBatchController 实例
|
||||||
|
func NewPigBatchController(logger *logs.Logger, service service.PigBatchService) *PigBatchController {
|
||||||
|
return &PigBatchController{
|
||||||
|
logger: logger,
|
||||||
|
service: service,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatePigBatch godoc
|
||||||
|
// @Summary 创建猪批次
|
||||||
|
// @Description 创建一个新的猪批次
|
||||||
|
// @Tags 猪批次管理
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param body body dto.PigBatchCreateDTO true "猪批次信息"
|
||||||
|
// @Success 201 {object} controller.Response{data=dto.PigBatchResponseDTO} "创建成功"
|
||||||
|
// @Failure 400 {object} controller.Response "请求参数错误"
|
||||||
|
// @Failure 500 {object} controller.Response "内部服务器错误"
|
||||||
|
// @Router /api/v1/pig-batches [post]
|
||||||
|
func (c *PigBatchController) CreatePigBatch(ctx *gin.Context) {
|
||||||
|
const action = "创建猪批次"
|
||||||
|
var req dto.PigBatchCreateDTO
|
||||||
|
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体", action, "请求体绑定失败", req)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
respDTO, err := c.service.CreatePigBatch(&req)
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Errorf("%s: 业务逻辑失败: %v", action, err)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "创建猪批次失败", action, "业务逻辑失败", req)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
controller.SendSuccessWithAudit(ctx, controller.CodeCreated, "创建成功", respDTO, action, "创建成功", respDTO)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPigBatch godoc
|
||||||
|
// @Summary 获取单个猪批次
|
||||||
|
// @Description 根据ID获取单个猪批次信息
|
||||||
|
// @Tags 猪批次管理
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path int true "猪批次ID"
|
||||||
|
// @Success 200 {object} controller.Response{data=dto.PigBatchResponseDTO} "获取成功"
|
||||||
|
// @Failure 400 {object} controller.Response "无效的ID格式"
|
||||||
|
// @Failure 404 {object} controller.Response "猪批次不存在"
|
||||||
|
// @Failure 500 {object} controller.Response "内部服务器错误"
|
||||||
|
// @Router /api/v1/pig-batches/{id} [get]
|
||||||
|
func (c *PigBatchController) GetPigBatch(ctx *gin.Context) {
|
||||||
|
const action = "获取猪批次"
|
||||||
|
id, err := strconv.ParseUint(ctx.Param("id"), 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的ID格式", action, "ID格式错误", ctx.Param("id"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
respDTO, err := c.service.GetPigBatch(uint(id))
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, service.ErrPigBatchNotFound) {
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "猪批次不存在", action, "猪批次不存在", id)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.logger.Errorf("%s: 业务逻辑失败: %v", action, err)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取猪批次失败", action, "业务逻辑失败", id)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取成功", respDTO, action, "获取成功", respDTO)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatePigBatch godoc
|
||||||
|
// @Summary 更新猪批次
|
||||||
|
// @Description 更新一个已存在的猪批次信息
|
||||||
|
// @Tags 猪批次管理
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path int true "猪批次ID"
|
||||||
|
// @Param body body dto.PigBatchUpdateDTO true "猪批次信息"
|
||||||
|
// @Success 200 {object} controller.Response{data=dto.PigBatchResponseDTO} "更新成功"
|
||||||
|
// @Failure 400 {object} controller.Response "请求参数错误或无效的ID格式"
|
||||||
|
// @Failure 404 {object} controller.Response "猪批次不存在"
|
||||||
|
// @Failure 500 {object} controller.Response "内部服务器错误"
|
||||||
|
// @Router /api/v1/pig-batches/{id} [put]
|
||||||
|
func (c *PigBatchController) UpdatePigBatch(ctx *gin.Context) {
|
||||||
|
const action = "更新猪批次"
|
||||||
|
id, err := strconv.ParseUint(ctx.Param("id"), 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的ID格式", action, "ID格式错误", ctx.Param("id"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var req dto.PigBatchUpdateDTO
|
||||||
|
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体", action, "请求体绑定失败", req)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
respDTO, err := c.service.UpdatePigBatch(uint(id), &req)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, service.ErrPigBatchNotFound) {
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "猪批次不存在", action, "猪批次不存在", id)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.logger.Errorf("%s: 业务逻辑失败: %v", action, err)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "更新猪批次失败", action, "业务逻辑失败", req)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "更新成功", respDTO, action, "更新成功", respDTO)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletePigBatch godoc
|
||||||
|
// @Summary 删除猪批次
|
||||||
|
// @Description 根据ID删除一个猪批次
|
||||||
|
// @Tags 猪批次管理
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path int true "猪批次ID"
|
||||||
|
// @Success 200 {object} controller.Response "删除成功"
|
||||||
|
// @Failure 400 {object} controller.Response "无效的ID格式"
|
||||||
|
// @Failure 404 {object} controller.Response "猪批次不存在"
|
||||||
|
// @Failure 500 {object} controller.Response "内部服务器错误"
|
||||||
|
// @Router /api/v1/pig-batches/{id} [delete]
|
||||||
|
func (c *PigBatchController) DeletePigBatch(ctx *gin.Context) {
|
||||||
|
const action = "删除猪批次"
|
||||||
|
id, err := strconv.ParseUint(ctx.Param("id"), 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的ID格式", action, "ID格式错误", ctx.Param("id"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.service.DeletePigBatch(uint(id)); err != nil {
|
||||||
|
if errors.Is(err, service.ErrPigBatchNotFound) {
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "猪批次不存在", action, "猪批次不存在", id)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.logger.Errorf("%s: 业务逻辑失败: %v", action, err)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "删除猪批次失败", action, "业务逻辑失败", id)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "删除成功", nil, action, "删除成功", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListPigBatches godoc
|
||||||
|
// @Summary 获取猪批次列表
|
||||||
|
// @Description 获取所有猪批次的列表,支持按活跃状态筛选
|
||||||
|
// @Tags 猪批次管理
|
||||||
|
// @Produce json
|
||||||
|
// @Param is_active query bool false "是否活跃 (true/false)"
|
||||||
|
// @Success 200 {object} controller.Response{data=[]dto.PigBatchResponseDTO} "获取成功"
|
||||||
|
// @Failure 500 {object} controller.Response "内部服务器错误"
|
||||||
|
// @Router /api/v1/pig-batches [get]
|
||||||
|
func (c *PigBatchController) ListPigBatches(ctx *gin.Context) {
|
||||||
|
const action = "获取猪批次列表"
|
||||||
|
var query dto.PigBatchQueryDTO
|
||||||
|
// ShouldBindQuery 会自动处理 URL 查询参数,例如 ?is_active=true
|
||||||
|
if err := ctx.ShouldBindQuery(&query); err != nil {
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的查询参数", action, "查询参数绑定失败", nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
respDTOs, err := c.service.ListPigBatches(query.IsActive)
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Errorf("%s: 业务逻辑失败: %v", action, err)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取猪批次列表失败", action, "业务逻辑失败", nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取成功", respDTOs, action, "获取成功", respDTOs)
|
||||||
|
}
|
||||||
45
internal/app/dto/pig_batch_dto.go
Normal file
45
internal/app/dto/pig_batch_dto.go
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package dto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models" // 导入 models 包以使用 PigBatchOriginType 和 PigBatchStatus
|
||||||
|
)
|
||||||
|
|
||||||
|
// PigBatchCreateDTO 定义了创建猪批次的请求结构
|
||||||
|
type PigBatchCreateDTO struct {
|
||||||
|
BatchNumber string `json:"batch_number" binding:"required"` // 批次编号,必填
|
||||||
|
OriginType models.PigBatchOriginType `json:"origin_type" binding:"required"` // 批次来源,必填
|
||||||
|
StartDate time.Time `json:"start_date" binding:"required"` // 批次开始日期,必填
|
||||||
|
InitialCount int `json:"initial_count" binding:"required,min=1"` // 初始数量,必填,最小为1
|
||||||
|
Status models.PigBatchStatus `json:"status" binding:"required"` // 批次状态,必填
|
||||||
|
}
|
||||||
|
|
||||||
|
// PigBatchUpdateDTO 定义了更新猪批次的请求结构
|
||||||
|
type PigBatchUpdateDTO struct {
|
||||||
|
BatchNumber *string `json:"batch_number"` // 批次编号,可选
|
||||||
|
OriginType *models.PigBatchOriginType `json:"origin_type"` // 批次来源,可选
|
||||||
|
StartDate *time.Time `json:"start_date"` // 批次开始日期,可选
|
||||||
|
EndDate *time.Time `json:"end_date"` // 批次结束日期,可选
|
||||||
|
InitialCount *int `json:"initial_count"` // 初始数量,可选
|
||||||
|
Status *models.PigBatchStatus `json:"status"` // 批次状态,可选
|
||||||
|
}
|
||||||
|
|
||||||
|
// PigBatchQueryDTO 定义了查询猪批次的请求结构
|
||||||
|
type PigBatchQueryDTO struct {
|
||||||
|
IsActive *bool `json:"is_active" form:"is_active"` // 是否活跃,可选,用于URL查询参数
|
||||||
|
}
|
||||||
|
|
||||||
|
// PigBatchResponseDTO 定义了猪批次信息的响应结构
|
||||||
|
type PigBatchResponseDTO struct {
|
||||||
|
ID uint `json:"id"` // 批次ID
|
||||||
|
BatchNumber string `json:"batch_number"` // 批次编号
|
||||||
|
OriginType models.PigBatchOriginType `json:"origin_type"` // 批次来源
|
||||||
|
StartDate time.Time `json:"start_date"` // 批次开始日期
|
||||||
|
EndDate time.Time `json:"end_date"` // 批次结束日期
|
||||||
|
InitialCount int `json:"initial_count"` // 初始数量
|
||||||
|
Status models.PigBatchStatus `json:"status"` // 批次状态
|
||||||
|
IsActive bool `json:"is_active"` // 是否活跃
|
||||||
|
CreateTime time.Time `json:"create_time"` // 创建时间
|
||||||
|
UpdateTime time.Time `json:"update_time"` // 更新时间
|
||||||
|
}
|
||||||
176
internal/app/service/pig_batch_service.go
Normal file
176
internal/app/service/pig_batch_service.go
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
|
||||||
|
"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"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrPigBatchNotFound = errors.New("指定的猪批次不存在")
|
||||||
|
ErrPigBatchActive = errors.New("活跃的猪批次不能被删除") // 新增错误:活跃的猪批次不能被删除
|
||||||
|
)
|
||||||
|
|
||||||
|
// PigBatchService 提供了猪批次管理的业务逻辑
|
||||||
|
type PigBatchService interface {
|
||||||
|
CreatePigBatch(dto *dto.PigBatchCreateDTO) (*dto.PigBatchResponseDTO, error)
|
||||||
|
GetPigBatch(id uint) (*dto.PigBatchResponseDTO, error)
|
||||||
|
UpdatePigBatch(id uint, dto *dto.PigBatchUpdateDTO) (*dto.PigBatchResponseDTO, error)
|
||||||
|
DeletePigBatch(id uint) error
|
||||||
|
ListPigBatches(isActive *bool) ([]*dto.PigBatchResponseDTO, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type pigBatchService struct {
|
||||||
|
logger *logs.Logger
|
||||||
|
repo repository.PigBatchRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPigBatchService 创建一个新的 PigBatchService 实例
|
||||||
|
func NewPigBatchService(repo repository.PigBatchRepository, logger *logs.Logger) PigBatchService {
|
||||||
|
return &pigBatchService{
|
||||||
|
logger: logger,
|
||||||
|
repo: repo,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// toPigBatchResponseDTO 将 models.PigBatch 转换为 dto.PigBatchResponseDTO
|
||||||
|
func (s *pigBatchService) toPigBatchResponseDTO(batch *models.PigBatch) *dto.PigBatchResponseDTO {
|
||||||
|
if batch == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &dto.PigBatchResponseDTO{
|
||||||
|
ID: batch.ID,
|
||||||
|
BatchNumber: batch.BatchNumber,
|
||||||
|
OriginType: batch.OriginType,
|
||||||
|
StartDate: batch.StartDate,
|
||||||
|
EndDate: batch.EndDate,
|
||||||
|
InitialCount: batch.InitialCount,
|
||||||
|
Status: batch.Status,
|
||||||
|
IsActive: batch.IsActive(), // 使用模型自带的 IsActive 方法
|
||||||
|
CreateTime: batch.CreatedAt,
|
||||||
|
UpdateTime: batch.UpdatedAt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatePigBatch 处理创建猪批次的业务逻辑
|
||||||
|
func (s *pigBatchService) CreatePigBatch(dto *dto.PigBatchCreateDTO) (*dto.PigBatchResponseDTO, error) {
|
||||||
|
batch := &models.PigBatch{
|
||||||
|
BatchNumber: dto.BatchNumber,
|
||||||
|
OriginType: dto.OriginType,
|
||||||
|
StartDate: dto.StartDate,
|
||||||
|
InitialCount: dto.InitialCount,
|
||||||
|
Status: dto.Status,
|
||||||
|
}
|
||||||
|
|
||||||
|
createdBatch, err := s.repo.CreatePigBatch(batch)
|
||||||
|
if err != nil {
|
||||||
|
s.logger.Errorf("创建猪批次失败: %v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.toPigBatchResponseDTO(createdBatch), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPigBatch 处理获取单个猪批次的业务逻辑
|
||||||
|
func (s *pigBatchService) GetPigBatch(id uint) (*dto.PigBatchResponseDTO, error) {
|
||||||
|
batch, err := s.repo.GetPigBatchByID(id)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return nil, ErrPigBatchNotFound
|
||||||
|
}
|
||||||
|
s.logger.Errorf("获取猪批次失败,ID: %d, 错误: %v", id, err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.toPigBatchResponseDTO(batch), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatePigBatch 处理更新猪批次的业务逻辑
|
||||||
|
func (s *pigBatchService) UpdatePigBatch(id uint, dto *dto.PigBatchUpdateDTO) (*dto.PigBatchResponseDTO, error) {
|
||||||
|
existingBatch, err := s.repo.GetPigBatchByID(id)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return nil, ErrPigBatchNotFound
|
||||||
|
}
|
||||||
|
s.logger.Errorf("更新猪批次失败,获取原批次信息错误,ID: %d, 错误: %v", id, err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据 DTO 中的非空字段更新模型
|
||||||
|
if dto.BatchNumber != nil {
|
||||||
|
existingBatch.BatchNumber = *dto.BatchNumber
|
||||||
|
}
|
||||||
|
if dto.OriginType != nil {
|
||||||
|
existingBatch.OriginType = *dto.OriginType
|
||||||
|
}
|
||||||
|
if dto.StartDate != nil {
|
||||||
|
existingBatch.StartDate = *dto.StartDate
|
||||||
|
}
|
||||||
|
if dto.EndDate != nil {
|
||||||
|
existingBatch.EndDate = *dto.EndDate
|
||||||
|
}
|
||||||
|
if dto.InitialCount != nil {
|
||||||
|
existingBatch.InitialCount = *dto.InitialCount
|
||||||
|
}
|
||||||
|
if dto.Status != nil {
|
||||||
|
existingBatch.Status = *dto.Status
|
||||||
|
}
|
||||||
|
|
||||||
|
updatedBatch, err := s.repo.UpdatePigBatch(existingBatch)
|
||||||
|
if err != nil {
|
||||||
|
s.logger.Errorf("更新猪批次失败,ID: %d, 错误: %v", id, err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.toPigBatchResponseDTO(updatedBatch), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletePigBatch 处理删除猪批次的业务逻辑
|
||||||
|
func (s *pigBatchService) DeletePigBatch(id uint) error {
|
||||||
|
// 1. 获取猪批次信息
|
||||||
|
batch, err := s.repo.GetPigBatchByID(id)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return ErrPigBatchNotFound
|
||||||
|
}
|
||||||
|
s.logger.Errorf("删除猪批次失败,获取批次信息错误,ID: %d, 错误: %v", id, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 检查猪批次是否活跃
|
||||||
|
if batch.IsActive() {
|
||||||
|
return ErrPigBatchActive // 如果活跃,则不允许删除
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 执行删除操作
|
||||||
|
err = s.repo.DeletePigBatch(id)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) || errors.New("未找到要删除的猪批次").Error() == err.Error() {
|
||||||
|
return ErrPigBatchNotFound
|
||||||
|
}
|
||||||
|
s.logger.Errorf("删除猪批次失败,ID: %d, 错误: %v", id, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListPigBatches 处理批量查询猪批次的业务逻辑
|
||||||
|
func (s *pigBatchService) ListPigBatches(isActive *bool) ([]*dto.PigBatchResponseDTO, error) {
|
||||||
|
batches, err := s.repo.ListPigBatches(isActive)
|
||||||
|
if err != nil {
|
||||||
|
s.logger.Errorf("批量查询猪批次失败,错误: %v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var responseDTOs []*dto.PigBatchResponseDTO
|
||||||
|
for _, batch := range batches {
|
||||||
|
responseDTOs = append(responseDTOs, s.toPigBatchResponseDTO(batch))
|
||||||
|
}
|
||||||
|
|
||||||
|
return responseDTOs, nil
|
||||||
|
}
|
||||||
@@ -72,9 +72,11 @@ func NewApplication(configPath string) (*Application, error) {
|
|||||||
deviceCommandLogRepo := repository.NewGormDeviceCommandLogRepository(storage.GetDB())
|
deviceCommandLogRepo := repository.NewGormDeviceCommandLogRepository(storage.GetDB())
|
||||||
pendingCollectionRepo := repository.NewGormPendingCollectionRepository(storage.GetDB())
|
pendingCollectionRepo := repository.NewGormPendingCollectionRepository(storage.GetDB())
|
||||||
userActionLogRepo := repository.NewGormUserActionLogRepository(storage.GetDB())
|
userActionLogRepo := repository.NewGormUserActionLogRepository(storage.GetDB())
|
||||||
|
pigBatchRepo := repository.NewGormPigBatchRepository(storage.GetDB())
|
||||||
|
|
||||||
// --- 业务逻辑处理器初始化 ---
|
// --- 业务逻辑处理器初始化 ---
|
||||||
pigFarmService := service.NewPigFarmService(pigFarmRepo, logger)
|
pigFarmService := service.NewPigFarmService(pigFarmRepo, logger)
|
||||||
|
pigBatchService := service.NewPigBatchService(pigBatchRepo, logger)
|
||||||
|
|
||||||
// 初始化审计服务
|
// 初始化审计服务
|
||||||
auditService := audit.NewService(userActionLogRepo, logger)
|
auditService := audit.NewService(userActionLogRepo, logger)
|
||||||
@@ -121,6 +123,7 @@ func NewApplication(configPath string) (*Application, error) {
|
|||||||
deviceTemplateRepo,
|
deviceTemplateRepo,
|
||||||
planRepo,
|
planRepo,
|
||||||
pigFarmService,
|
pigFarmService,
|
||||||
|
pigBatchService,
|
||||||
userActionLogRepo,
|
userActionLogRepo,
|
||||||
tokenService,
|
tokenService,
|
||||||
auditService,
|
auditService,
|
||||||
|
|||||||
89
internal/infra/repository/pig_batch_repository.go
Normal file
89
internal/infra/repository/pig_batch_repository.go
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PigBatchRepository 定义了与猪批次相关的数据库操作接口
|
||||||
|
type PigBatchRepository interface {
|
||||||
|
CreatePigBatch(batch *models.PigBatch) (*models.PigBatch, error)
|
||||||
|
GetPigBatchByID(id uint) (*models.PigBatch, error)
|
||||||
|
UpdatePigBatch(batch *models.PigBatch) (*models.PigBatch, error)
|
||||||
|
DeletePigBatch(id uint) error
|
||||||
|
ListPigBatches(isActive *bool) ([]*models.PigBatch, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// gormPigBatchRepository 是 PigBatchRepository 的 GORM 实现
|
||||||
|
type gormPigBatchRepository struct {
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGormPigBatchRepository 创建一个新的 PigBatchRepository GORM 实现实例
|
||||||
|
func NewGormPigBatchRepository(db *gorm.DB) PigBatchRepository {
|
||||||
|
return &gormPigBatchRepository{db: db}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatePigBatch 创建一个新的猪批次
|
||||||
|
func (r *gormPigBatchRepository) CreatePigBatch(batch *models.PigBatch) (*models.PigBatch, error) {
|
||||||
|
if err := r.db.Create(batch).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return batch, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPigBatchByID 根据ID获取单个猪批次
|
||||||
|
func (r *gormPigBatchRepository) GetPigBatchByID(id uint) (*models.PigBatch, error) {
|
||||||
|
var batch models.PigBatch
|
||||||
|
if err := r.db.First(&batch, id).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &batch, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatePigBatch 更新一个猪批次
|
||||||
|
func (r *gormPigBatchRepository) UpdatePigBatch(batch *models.PigBatch) (*models.PigBatch, error) {
|
||||||
|
result := r.db.Model(&models.PigBatch{}).Where("id = ?", batch.ID).Updates(batch)
|
||||||
|
if result.Error != nil {
|
||||||
|
return nil, result.Error
|
||||||
|
}
|
||||||
|
if result.RowsAffected == 0 {
|
||||||
|
return nil, errors.New("未找到要更新的猪批次或数据未改变") // 明确返回错误,而不是 gorm.ErrRecordNotFound
|
||||||
|
}
|
||||||
|
return batch, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletePigBatch 根据ID删除一个猪批次 (GORM 会执行软删除)
|
||||||
|
func (r *gormPigBatchRepository) DeletePigBatch(id uint) error {
|
||||||
|
result := r.db.Delete(&models.PigBatch{}, id)
|
||||||
|
if result.Error != nil {
|
||||||
|
return result.Error
|
||||||
|
}
|
||||||
|
if result.RowsAffected == 0 {
|
||||||
|
return errors.New("未找到要删除的猪批次") // 明确返回错误
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListPigBatches 批量查询猪批次,支持根据 IsActive 筛选
|
||||||
|
func (r *gormPigBatchRepository) ListPigBatches(isActive *bool) ([]*models.PigBatch, error) {
|
||||||
|
var batches []*models.PigBatch
|
||||||
|
query := r.db.Model(&models.PigBatch{})
|
||||||
|
|
||||||
|
if isActive != nil {
|
||||||
|
if *isActive {
|
||||||
|
// 查询活跃的批次:状态不是已出售或已归档
|
||||||
|
query = query.Where("status NOT IN (?) ", []models.PigBatchStatus{models.BatchStatusSold, models.BatchStatusArchived})
|
||||||
|
} else {
|
||||||
|
// 查询非活跃的批次:状态是已出售或已归档
|
||||||
|
query = query.Where("status IN (?) ", []models.PigBatchStatus{models.BatchStatusSold, models.BatchStatusArchived})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := query.Find(&batches).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return batches, nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user