ListPigBatchLogs
This commit is contained in:
		| @@ -503,3 +503,52 @@ func (c *Controller) ListMedicationLogs(ctx *gin.Context) { | |||||||
| 	c.logger.Infof("%s: 成功, 获取到 %d 条记录, 总计 %d 条", actionType, len(data), total) | 	c.logger.Infof("%s: 成功, 获取到 %d 条记录, 总计 %d 条", actionType, len(data), total) | ||||||
| 	controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取用药记录成功", resp, actionType, "获取用药记录成功", req) | 	controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取用药记录成功", resp, actionType, "获取用药记录成功", req) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // ListPigBatchLogs godoc | ||||||
|  | // @Summary      获取猪批次日志列表 | ||||||
|  | // @Description  根据提供的过滤条件,分页获取猪批次日志 | ||||||
|  | // @Tags         数据监控 | ||||||
|  | // @Security     BearerAuth | ||||||
|  | // @Produce      json | ||||||
|  | // @Param        query query dto.ListPigBatchLogRequest true "查询参数" | ||||||
|  | // @Success      200 {object} controller.Response{data=dto.ListPigBatchLogResponse} | ||||||
|  | // @Router       /api/v1/monitor/pig-batch-logs [get] | ||||||
|  | func (c *Controller) ListPigBatchLogs(ctx *gin.Context) { | ||||||
|  | 	const actionType = "获取猪批次日志列表" | ||||||
|  |  | ||||||
|  | 	var req dto.ListPigBatchLogRequest | ||||||
|  | 	if err := ctx.ShouldBindQuery(&req); err != nil { | ||||||
|  | 		c.logger.Errorf("%s: 参数绑定失败: %v", actionType, err) | ||||||
|  | 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的查询参数: "+err.Error(), actionType, "参数绑定失败", req) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	opts := repository.PigBatchLogListOptions{ | ||||||
|  | 		PigBatchID: req.PigBatchID, | ||||||
|  | 		OperatorID: req.OperatorID, | ||||||
|  | 		OrderBy:    req.OrderBy, | ||||||
|  | 		StartTime:  req.StartTime, | ||||||
|  | 		EndTime:    req.EndTime, | ||||||
|  | 	} | ||||||
|  | 	if req.ChangeType != nil { | ||||||
|  | 		changeType := models.LogChangeType(*req.ChangeType) | ||||||
|  | 		opts.ChangeType = &changeType | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	data, total, err := c.monitorService.ListPigBatchLogs(opts, req.Page, req.PageSize) | ||||||
|  | 	if err != nil { | ||||||
|  | 		if errors.Is(err, repository.ErrInvalidPagination) { | ||||||
|  | 			c.logger.Warnf("%s: 无效的分页参数: %v", actionType, err) | ||||||
|  | 			controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的分页参数: "+err.Error(), actionType, "无效分页参数", req) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		c.logger.Errorf("%s: 服务层查询失败: %v", actionType, err) | ||||||
|  | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取猪批次日志失败: "+err.Error(), actionType, "服务层查询失败", req) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	resp := dto.NewListPigBatchLogResponse(data, total, req.Page, req.PageSize) | ||||||
|  | 	c.logger.Infof("%s: 成功, 获取到 %d 条记录, 总计 %d 条", actionType, len(data), total) | ||||||
|  | 	controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取猪批次日志成功", resp, actionType, "获取猪批次日志成功", req) | ||||||
|  | } | ||||||
|   | |||||||
| @@ -191,7 +191,7 @@ type ListTaskExecutionLogRequest struct { | |||||||
|  |  | ||||||
| // TaskDTO 是用于API响应的简化版任务结构 | // TaskDTO 是用于API响应的简化版任务结构 | ||||||
| type TaskDTO struct { | type TaskDTO struct { | ||||||
| 	ID          int    `json:"id"` | 	ID          uint   `json:"id"` | ||||||
| 	Name        string `json:"name"` | 	Name        string `json:"name"` | ||||||
| 	Description string `json:"description"` | 	Description string `json:"description"` | ||||||
| } | } | ||||||
| @@ -227,7 +227,7 @@ func NewListTaskExecutionLogResponse(data []models.TaskExecutionLog, total int64 | |||||||
| 			PlanExecutionLogID: item.PlanExecutionLogID, | 			PlanExecutionLogID: item.PlanExecutionLogID, | ||||||
| 			TaskID:             item.TaskID, | 			TaskID:             item.TaskID, | ||||||
| 			Task: TaskDTO{ | 			Task: TaskDTO{ | ||||||
| 				ID:          item.Task.ID, | 				ID:          uint(item.Task.ID), | ||||||
| 				Name:        item.Task.Name, | 				Name:        item.Task.Name, | ||||||
| 				Description: item.Task.Description, | 				Description: item.Task.Description, | ||||||
| 			}, | 			}, | ||||||
| @@ -641,3 +641,67 @@ func NewListMedicationLogResponse(data []models.MedicationLog, total int64, page | |||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // --- PigBatchLog --- | ||||||
|  |  | ||||||
|  | // ListPigBatchLogRequest 定义了获取猪批次日志列表的请求参数 | ||||||
|  | type ListPigBatchLogRequest struct { | ||||||
|  | 	Page       int        `form:"page,default=1"` | ||||||
|  | 	PageSize   int        `form:"pageSize,default=10"` | ||||||
|  | 	PigBatchID *uint      `form:"pig_batch_id"` | ||||||
|  | 	ChangeType *string    `form:"change_type"` | ||||||
|  | 	OperatorID *uint      `form:"operator_id"` | ||||||
|  | 	StartTime  *time.Time `form:"start_time" time_format:"rfc3339"` | ||||||
|  | 	EndTime    *time.Time `form:"end_time" time_format:"rfc3339"` | ||||||
|  | 	OrderBy    string     `form:"order_by"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // PigBatchLogDTO 是用于API响应的猪批次日志结构 | ||||||
|  | type PigBatchLogDTO struct { | ||||||
|  | 	ID          uint                 `json:"id"` | ||||||
|  | 	CreatedAt   time.Time            `json:"created_at"` | ||||||
|  | 	UpdatedAt   time.Time            `json:"updated_at"` | ||||||
|  | 	PigBatchID  uint                 `json:"pig_batch_id"` | ||||||
|  | 	ChangeType  models.LogChangeType `json:"change_type"` | ||||||
|  | 	ChangeCount int                  `json:"change_count"` | ||||||
|  | 	Reason      string               `json:"reason"` | ||||||
|  | 	BeforeCount int                  `json:"before_count"` | ||||||
|  | 	AfterCount  int                  `json:"after_count"` | ||||||
|  | 	OperatorID  uint                 `json:"operator_id"` | ||||||
|  | 	HappenedAt  time.Time            `json:"happened_at"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ListPigBatchLogResponse 是获取猪批次日志列表的响应结构 | ||||||
|  | type ListPigBatchLogResponse struct { | ||||||
|  | 	List       []PigBatchLogDTO `json:"list"` | ||||||
|  | 	Pagination PaginationDTO    `json:"pagination"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewListPigBatchLogResponse 从模型数据创建列表响应 DTO | ||||||
|  | func NewListPigBatchLogResponse(data []models.PigBatchLog, total int64, page, pageSize int) *ListPigBatchLogResponse { | ||||||
|  | 	dtos := make([]PigBatchLogDTO, len(data)) | ||||||
|  | 	for i, item := range data { | ||||||
|  | 		dtos[i] = PigBatchLogDTO{ | ||||||
|  | 			ID:          item.ID, | ||||||
|  | 			CreatedAt:   item.CreatedAt, | ||||||
|  | 			UpdatedAt:   item.UpdatedAt, | ||||||
|  | 			PigBatchID:  item.PigBatchID, | ||||||
|  | 			ChangeType:  item.ChangeType, | ||||||
|  | 			ChangeCount: item.ChangeCount, | ||||||
|  | 			Reason:      item.Reason, | ||||||
|  | 			BeforeCount: item.BeforeCount, | ||||||
|  | 			AfterCount:  item.AfterCount, | ||||||
|  | 			OperatorID:  item.OperatorID, | ||||||
|  | 			HappenedAt:  item.HappenedAt, | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return &ListPigBatchLogResponse{ | ||||||
|  | 		List: dtos, | ||||||
|  | 		Pagination: PaginationDTO{ | ||||||
|  | 			Total:    total, | ||||||
|  | 			Page:     page, | ||||||
|  | 			PageSize: pageSize, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|   | |||||||
| @@ -14,6 +14,7 @@ type MonitorService struct { | |||||||
| 	userActionLogRepo     repository.UserActionLogRepository | 	userActionLogRepo     repository.UserActionLogRepository | ||||||
| 	rawMaterialRepo       repository.RawMaterialRepository | 	rawMaterialRepo       repository.RawMaterialRepository | ||||||
| 	medicationRepo        repository.MedicationRepository | 	medicationRepo        repository.MedicationRepository | ||||||
|  | 	pigBatchLogRepo       repository.PigBatchLogRepository | ||||||
| 	// 在这里可以添加其他超表模型的仓库依赖 | 	// 在这里可以添加其他超表模型的仓库依赖 | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -26,6 +27,7 @@ func NewMonitorService( | |||||||
| 	userActionLogRepo repository.UserActionLogRepository, | 	userActionLogRepo repository.UserActionLogRepository, | ||||||
| 	rawMaterialRepo repository.RawMaterialRepository, | 	rawMaterialRepo repository.RawMaterialRepository, | ||||||
| 	medicationRepo repository.MedicationRepository, | 	medicationRepo repository.MedicationRepository, | ||||||
|  | 	pigBatchLogRepo repository.PigBatchLogRepository, | ||||||
| ) *MonitorService { | ) *MonitorService { | ||||||
| 	return &MonitorService{ | 	return &MonitorService{ | ||||||
| 		sensorDataRepo:        sensorDataRepo, | 		sensorDataRepo:        sensorDataRepo, | ||||||
| @@ -35,6 +37,7 @@ func NewMonitorService( | |||||||
| 		userActionLogRepo:     userActionLogRepo, | 		userActionLogRepo:     userActionLogRepo, | ||||||
| 		rawMaterialRepo:       rawMaterialRepo, | 		rawMaterialRepo:       rawMaterialRepo, | ||||||
| 		medicationRepo:        medicationRepo, | 		medicationRepo:        medicationRepo, | ||||||
|  | 		pigBatchLogRepo:       pigBatchLogRepo, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -87,3 +90,8 @@ func (s *MonitorService) ListFeedUsageRecords(opts repository.FeedUsageRecordLis | |||||||
| func (s *MonitorService) ListMedicationLogs(opts repository.MedicationLogListOptions, page, pageSize int) ([]models.MedicationLog, int64, error) { | func (s *MonitorService) ListMedicationLogs(opts repository.MedicationLogListOptions, page, pageSize int) ([]models.MedicationLog, int64, error) { | ||||||
| 	return s.medicationRepo.ListMedicationLogs(opts, page, pageSize) | 	return s.medicationRepo.ListMedicationLogs(opts, page, pageSize) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // ListPigBatchLogs 负责处理查询猪批次日志列表的业务逻辑 | ||||||
|  | func (s *MonitorService) ListPigBatchLogs(opts repository.PigBatchLogListOptions, page, pageSize int) ([]models.PigBatchLog, int64, error) { | ||||||
|  | 	return s.pigBatchLogRepo.List(opts, page, pageSize) | ||||||
|  | } | ||||||
|   | |||||||
| @@ -1,12 +1,22 @@ | |||||||
| package repository | package repository | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"time" // 引入 time 包 | 	"time" | ||||||
|  |  | ||||||
| 	"git.huangwc.com/pig/pig-farm-controller/internal/infra/models" | 	"git.huangwc.com/pig/pig-farm-controller/internal/infra/models" | ||||||
| 	"gorm.io/gorm" | 	"gorm.io/gorm" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | // PigBatchLogListOptions 定义了查询猪批次日志时的可选参数 | ||||||
|  | type PigBatchLogListOptions struct { | ||||||
|  | 	PigBatchID *uint | ||||||
|  | 	ChangeType *models.LogChangeType | ||||||
|  | 	OperatorID *uint | ||||||
|  | 	StartTime  *time.Time // 基于 happened_at 字段 | ||||||
|  | 	EndTime    *time.Time // 基于 happened_at 字段 | ||||||
|  | 	OrderBy    string     // 例如 "happened_at asc" | ||||||
|  | } | ||||||
|  |  | ||||||
| // PigBatchLogRepository 定义了与猪批次日志相关的数据库操作接口。 | // PigBatchLogRepository 定义了与猪批次日志相关的数据库操作接口。 | ||||||
| type PigBatchLogRepository interface { | type PigBatchLogRepository interface { | ||||||
| 	// CreateTx 在指定的事务中创建一条新的猪批次日志。 | 	// CreateTx 在指定的事务中创建一条新的猪批次日志。 | ||||||
| @@ -17,6 +27,9 @@ type PigBatchLogRepository interface { | |||||||
|  |  | ||||||
| 	// GetLastLogByBatchIDTx 在指定的事务中,获取某批次的最后一条日志记录。 | 	// GetLastLogByBatchIDTx 在指定的事务中,获取某批次的最后一条日志记录。 | ||||||
| 	GetLastLogByBatchIDTx(tx *gorm.DB, batchID uint) (*models.PigBatchLog, error) | 	GetLastLogByBatchIDTx(tx *gorm.DB, batchID uint) (*models.PigBatchLog, error) | ||||||
|  |  | ||||||
|  | 	// List 支持分页和过滤的列表查询 | ||||||
|  | 	List(opts PigBatchLogListOptions, page, pageSize int) ([]models.PigBatchLog, int64, error) | ||||||
| } | } | ||||||
|  |  | ||||||
| // gormPigBatchLogRepository 是 PigBatchLogRepository 的 GORM 实现。 | // gormPigBatchLogRepository 是 PigBatchLogRepository 的 GORM 实现。 | ||||||
| @@ -29,7 +42,7 @@ func NewGormPigBatchLogRepository(db *gorm.DB) PigBatchLogRepository { | |||||||
| 	return &gormPigBatchLogRepository{db: db} | 	return &gormPigBatchLogRepository{db: db} | ||||||
| } | } | ||||||
|  |  | ||||||
| // Create 实现了创建猪批次日志的逻辑。 | // CreateTx 实现了在事务中创建猪批次日志的逻辑。 | ||||||
| func (r *gormPigBatchLogRepository) CreateTx(tx *gorm.DB, log *models.PigBatchLog) error { | func (r *gormPigBatchLogRepository) CreateTx(tx *gorm.DB, log *models.PigBatchLog) error { | ||||||
| 	return tx.Create(log).Error | 	return tx.Create(log).Error | ||||||
| } | } | ||||||
| @@ -53,3 +66,46 @@ func (r *gormPigBatchLogRepository) GetLastLogByBatchIDTx(tx *gorm.DB, batchID u | |||||||
| 	} | 	} | ||||||
| 	return &log, nil | 	return &log, nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // List 实现了分页和过滤查询猪批次日志的功能 | ||||||
|  | func (r *gormPigBatchLogRepository) List(opts PigBatchLogListOptions, page, pageSize int) ([]models.PigBatchLog, int64, error) { | ||||||
|  | 	if page <= 0 || pageSize <= 0 { | ||||||
|  | 		return nil, 0, ErrInvalidPagination | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var results []models.PigBatchLog | ||||||
|  | 	var total int64 | ||||||
|  |  | ||||||
|  | 	query := r.db.Model(&models.PigBatchLog{}) | ||||||
|  |  | ||||||
|  | 	if opts.PigBatchID != nil { | ||||||
|  | 		query = query.Where("pig_batch_id = ?", *opts.PigBatchID) | ||||||
|  | 	} | ||||||
|  | 	if opts.ChangeType != nil { | ||||||
|  | 		query = query.Where("change_type = ?", *opts.ChangeType) | ||||||
|  | 	} | ||||||
|  | 	if opts.OperatorID != nil { | ||||||
|  | 		query = query.Where("operator_id = ?", *opts.OperatorID) | ||||||
|  | 	} | ||||||
|  | 	if opts.StartTime != nil { | ||||||
|  | 		query = query.Where("happened_at >= ?", *opts.StartTime) | ||||||
|  | 	} | ||||||
|  | 	if opts.EndTime != nil { | ||||||
|  | 		query = query.Where("happened_at <= ?", *opts.EndTime) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if err := query.Count(&total).Error; err != nil { | ||||||
|  | 		return nil, 0, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	orderBy := "happened_at DESC" | ||||||
|  | 	if opts.OrderBy != "" { | ||||||
|  | 		orderBy = opts.OrderBy | ||||||
|  | 	} | ||||||
|  | 	query = query.Order(orderBy) | ||||||
|  |  | ||||||
|  | 	offset := (page - 1) * pageSize | ||||||
|  | 	err := query.Limit(pageSize).Offset(offset).Find(&results).Error | ||||||
|  |  | ||||||
|  | 	return results, total, err | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user