444 lines
16 KiB
Go
444 lines
16 KiB
Go
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"
|
|
)
|
|
|
|
// --- 控制器定义 ---
|
|
|
|
// PigFarmController 负责处理猪舍和猪栏相关的API请求
|
|
type PigFarmController struct {
|
|
logger *logs.Logger
|
|
service service.PigFarmService
|
|
}
|
|
|
|
// NewPigFarmController 创建一个新的 PigFarmController 实例
|
|
func NewPigFarmController(logger *logs.Logger, service service.PigFarmService) *PigFarmController {
|
|
return &PigFarmController{
|
|
logger: logger,
|
|
service: service,
|
|
}
|
|
}
|
|
|
|
// --- 猪舍 (PigHouse) API 实现 ---
|
|
|
|
// CreatePigHouse godoc
|
|
// @Summary 创建猪舍
|
|
// @Description 创建一个新的猪舍
|
|
// @Tags 猪场管理
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param body body dto.CreatePigHouseRequest true "猪舍信息"
|
|
// @Success 201 {object} controller.Response{data=dto.PigHouseResponse} "创建成功"
|
|
// @Router /api/v1/pig-houses [post]
|
|
func (c *PigFarmController) CreatePigHouse(ctx *gin.Context) {
|
|
const action = "创建猪舍"
|
|
var req dto.CreatePigHouseRequest
|
|
if err := ctx.ShouldBindJSON(&req); err != nil {
|
|
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体", action, "请求体绑定失败", req)
|
|
return
|
|
}
|
|
|
|
house, err := c.service.CreatePigHouse(req.Name, req.Description)
|
|
if err != nil {
|
|
c.logger.Errorf("%s: 业务逻辑失败: %v", action, err)
|
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "创建猪舍失败", action, "业务逻辑失败", req)
|
|
return
|
|
}
|
|
|
|
resp := dto.PigHouseResponse{
|
|
ID: house.ID,
|
|
Name: house.Name,
|
|
Description: house.Description,
|
|
}
|
|
controller.SendSuccessWithAudit(ctx, controller.CodeCreated, "创建成功", resp, action, "创建成功", resp)
|
|
}
|
|
|
|
// GetPigHouse godoc
|
|
// @Summary 获取单个猪舍
|
|
// @Description 根据ID获取单个猪舍信息
|
|
// @Tags 猪场管理
|
|
// @Produce json
|
|
// @Param id path int true "猪舍ID"
|
|
// @Success 200 {object} controller.Response{data=dto.PigHouseResponse} "获取成功"
|
|
// @Router /api/v1/pig-houses/{id} [get]
|
|
func (c *PigFarmController) GetPigHouse(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
|
|
}
|
|
|
|
house, err := c.service.GetPigHouseByID(uint(id))
|
|
if err != nil {
|
|
if errors.Is(err, service.ErrHouseNotFound) {
|
|
controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "猪舍不存在", action, "猪舍不存在", id)
|
|
return
|
|
}
|
|
c.logger.Errorf("%s: 业务逻辑失败: %v", action, err)
|
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取猪舍失败", action, "业务逻辑失败", id)
|
|
return
|
|
}
|
|
|
|
resp := dto.PigHouseResponse{
|
|
ID: house.ID,
|
|
Name: house.Name,
|
|
Description: house.Description,
|
|
}
|
|
controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取成功", resp, action, "获取成功", resp)
|
|
}
|
|
|
|
// ListPigHouses godoc
|
|
// @Summary 获取猪舍列表
|
|
// @Description 获取所有猪舍的列表
|
|
// @Tags 猪场管理
|
|
// @Produce json
|
|
// @Success 200 {object} controller.Response{data=[]dto.PigHouseResponse} "获取成功"
|
|
// @Router /api/v1/pig-houses [get]
|
|
func (c *PigFarmController) ListPigHouses(ctx *gin.Context) {
|
|
const action = "获取猪舍列表"
|
|
houses, err := c.service.ListPigHouses()
|
|
if err != nil {
|
|
c.logger.Errorf("%s: 业务逻辑失败: %v", action, err)
|
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取列表失败", action, "业务逻辑失败", nil)
|
|
return
|
|
}
|
|
|
|
var resp []dto.PigHouseResponse
|
|
for _, house := range houses {
|
|
resp = append(resp, dto.PigHouseResponse{
|
|
ID: house.ID,
|
|
Name: house.Name,
|
|
Description: house.Description,
|
|
})
|
|
}
|
|
|
|
controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取成功", resp, action, "获取成功", resp)
|
|
}
|
|
|
|
// UpdatePigHouse godoc
|
|
// @Summary 更新猪舍
|
|
// @Description 更新一个已存在的猪舍信息
|
|
// @Tags 猪场管理
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param id path int true "猪舍ID"
|
|
// @Param body body dto.UpdatePigHouseRequest true "猪舍信息"
|
|
// @Success 200 {object} controller.Response{data=dto.PigHouseResponse} "更新成功"
|
|
// @Router /api/v1/pig-houses/{id} [put]
|
|
func (c *PigFarmController) UpdatePigHouse(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.UpdatePigHouseRequest
|
|
if err := ctx.ShouldBindJSON(&req); err != nil {
|
|
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体", action, "请求体绑定失败", req)
|
|
return
|
|
}
|
|
|
|
house, err := c.service.UpdatePigHouse(uint(id), req.Name, req.Description)
|
|
if err != nil {
|
|
if errors.Is(err, service.ErrHouseNotFound) {
|
|
controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "猪舍不存在", action, "猪舍不存在", id)
|
|
return
|
|
}
|
|
c.logger.Errorf("%s: 业务逻辑失败: %v", action, err)
|
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "更新失败", action, "业务逻辑失败", req)
|
|
return
|
|
}
|
|
|
|
resp := dto.PigHouseResponse{
|
|
ID: house.ID,
|
|
Name: house.Name,
|
|
Description: house.Description,
|
|
}
|
|
controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "更新成功", resp, action, "更新成功", resp)
|
|
}
|
|
|
|
// DeletePigHouse godoc
|
|
// @Summary 删除猪舍
|
|
// @Description 根据ID删除一个猪舍
|
|
// @Tags 猪场管理
|
|
// @Produce json
|
|
// @Param id path int true "猪舍ID"
|
|
// @Success 200 {object} controller.Response "删除成功"
|
|
// @Router /api/v1/pig-houses/{id} [delete]
|
|
func (c *PigFarmController) DeletePigHouse(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.DeletePigHouse(uint(id)); err != nil {
|
|
if errors.Is(err, service.ErrHouseNotFound) {
|
|
controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "猪舍不存在", action, "猪舍不存在", id)
|
|
return
|
|
}
|
|
// 检查是否是业务逻辑错误
|
|
if errors.Is(err, service.ErrHouseContainsPens) {
|
|
controller.SendErrorWithAudit(ctx, controller.CodeConflict, err.Error(), action, err.Error(), 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)
|
|
}
|
|
|
|
// --- 猪栏 (Pen) API 实现 ---
|
|
|
|
// CreatePen godoc
|
|
// @Summary 创建猪栏
|
|
// @Description 创建一个新的猪栏
|
|
// @Tags 猪场管理
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param body body dto.CreatePenRequest true "猪栏信息"
|
|
// @Success 201 {object} controller.Response{data=dto.PenResponse} "创建成功"
|
|
// @Router /api/v1/pens [post]
|
|
func (c *PigFarmController) CreatePen(ctx *gin.Context) {
|
|
const action = "创建猪栏"
|
|
var req dto.CreatePenRequest
|
|
if err := ctx.ShouldBindJSON(&req); err != nil {
|
|
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体", action, "请求体绑定失败", req)
|
|
return
|
|
}
|
|
|
|
pen, err := c.service.CreatePen(req.PenNumber, req.HouseID, req.Capacity)
|
|
if err != nil {
|
|
// 检查是否是业务逻辑错误
|
|
if errors.Is(err, service.ErrHouseNotFound) {
|
|
controller.SendErrorWithAudit(ctx, controller.CodeNotFound, err.Error(), action, err.Error(), req)
|
|
return
|
|
}
|
|
c.logger.Errorf("%s: 业务逻辑失败: %v", action, err)
|
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "创建猪栏失败", action, "业务逻辑失败", req)
|
|
return
|
|
}
|
|
|
|
resp := dto.PenResponse{
|
|
ID: pen.ID,
|
|
PenNumber: pen.PenNumber,
|
|
HouseID: pen.HouseID,
|
|
Capacity: pen.Capacity,
|
|
Status: pen.Status,
|
|
PigBatchID: *pen.PigBatchID,
|
|
}
|
|
controller.SendSuccessWithAudit(ctx, controller.CodeCreated, "创建成功", resp, action, "创建成功", resp)
|
|
}
|
|
|
|
// GetPen godoc
|
|
// @Summary 获取单个猪栏
|
|
// @Description 根据ID获取单个猪栏信息
|
|
// @Tags 猪场管理
|
|
// @Produce json
|
|
// @Param id path int true "猪栏ID"
|
|
// @Success 200 {object} controller.Response{data=dto.PenResponse} "获取成功"
|
|
// @Router /api/v1/pens/{id} [get]
|
|
func (c *PigFarmController) GetPen(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
|
|
}
|
|
|
|
pen, err := c.service.GetPenByID(uint(id))
|
|
if err != nil {
|
|
if errors.Is(err, service.ErrPenNotFound) {
|
|
controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "猪栏不存在", action, "猪栏不存在", id)
|
|
return
|
|
}
|
|
c.logger.Errorf("%s: 业务逻辑失败: %v", action, err)
|
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取猪栏失败", action, "业务逻辑失败", id)
|
|
return
|
|
}
|
|
|
|
resp := dto.PenResponse{
|
|
ID: pen.ID,
|
|
PenNumber: pen.PenNumber,
|
|
HouseID: pen.HouseID,
|
|
Capacity: pen.Capacity,
|
|
Status: pen.Status,
|
|
PigBatchID: *pen.PigBatchID,
|
|
}
|
|
controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取成功", resp, action, "获取成功", resp)
|
|
}
|
|
|
|
// ListPens godoc
|
|
// @Summary 获取猪栏列表
|
|
// @Description 获取所有猪栏的列表
|
|
// @Tags 猪场管理
|
|
// @Produce json
|
|
// @Success 200 {object} controller.Response{data=[]dto.PenResponse} "获取成功"
|
|
// @Router /api/v1/pens [get]
|
|
func (c *PigFarmController) ListPens(ctx *gin.Context) {
|
|
const action = "获取猪栏列表"
|
|
pens, err := c.service.ListPens()
|
|
if err != nil {
|
|
c.logger.Errorf("%s: 业务逻辑失败: %v", action, err)
|
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取列表失败", action, "业务逻辑失败", nil)
|
|
return
|
|
}
|
|
|
|
var resp []dto.PenResponse
|
|
for _, pen := range pens {
|
|
resp = append(resp, dto.PenResponse{
|
|
ID: pen.ID,
|
|
PenNumber: pen.PenNumber,
|
|
HouseID: pen.HouseID,
|
|
Capacity: pen.Capacity,
|
|
Status: pen.Status,
|
|
PigBatchID: *pen.PigBatchID,
|
|
})
|
|
}
|
|
|
|
controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取成功", resp, action, "获取成功", resp)
|
|
}
|
|
|
|
// UpdatePen godoc
|
|
// @Summary 更新猪栏
|
|
// @Description 更新一个已存在的猪栏信息
|
|
// @Tags 猪场管理
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param id path int true "猪栏ID"
|
|
// @Param body body dto.UpdatePenRequest true "猪栏信息"
|
|
// @Success 200 {object} controller.Response{data=dto.PenResponse} "更新成功"
|
|
// @Router /api/v1/pens/{id} [put]
|
|
func (c *PigFarmController) UpdatePen(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.UpdatePenRequest
|
|
if err := ctx.ShouldBindJSON(&req); err != nil {
|
|
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体", action, "请求体绑定失败", req)
|
|
return
|
|
}
|
|
|
|
pen, err := c.service.UpdatePen(uint(id), req.PenNumber, req.HouseID, req.Capacity, req.Status)
|
|
if err != nil {
|
|
if errors.Is(err, service.ErrPenNotFound) {
|
|
controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "猪栏不存在", action, "猪栏不存在", id)
|
|
return
|
|
}
|
|
// 其他业务逻辑错误可以在这里添加处理
|
|
c.logger.Errorf("%s: 业务逻辑失败: %v", action, err)
|
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "更新失败", action, "业务逻辑失败", req)
|
|
return
|
|
}
|
|
|
|
resp := dto.PenResponse{
|
|
ID: pen.ID,
|
|
PenNumber: pen.PenNumber,
|
|
HouseID: pen.HouseID,
|
|
Capacity: pen.Capacity,
|
|
Status: pen.Status,
|
|
PigBatchID: *pen.PigBatchID,
|
|
}
|
|
controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "更新成功", resp, action, "更新成功", resp)
|
|
}
|
|
|
|
// DeletePen godoc
|
|
// @Summary 删除猪栏
|
|
// @Description 根据ID删除一个猪栏
|
|
// @Tags 猪场管理
|
|
// @Produce json
|
|
// @Param id path int true "猪栏ID"
|
|
// @Success 200 {object} controller.Response "删除成功"
|
|
// @Router /api/v1/pens/{id} [delete]
|
|
func (c *PigFarmController) DeletePen(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.DeletePen(uint(id)); err != nil {
|
|
if errors.Is(err, service.ErrPenNotFound) {
|
|
controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "猪栏不存在", action, "猪栏不存在", id)
|
|
return
|
|
}
|
|
// 检查是否是业务逻辑错误
|
|
if errors.Is(err, service.ErrPenInUse) {
|
|
controller.SendErrorWithAudit(ctx, controller.CodeConflict, err.Error(), action, err.Error(), 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)
|
|
}
|
|
|
|
// UpdatePenStatus godoc
|
|
// @Summary 更新猪栏状态
|
|
// @Description 更新指定猪栏的当前状态
|
|
// @Tags 猪场管理
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param id path int true "猪栏ID"
|
|
// @Param body body dto.UpdatePenStatusRequest true "新的猪栏状态"
|
|
// @Success 200 {object} controller.Response{data=dto.PenResponse} "更新成功"
|
|
// @Router /api/v1/pens/{id}/status [put]
|
|
func (c *PigFarmController) UpdatePenStatus(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.UpdatePenStatusRequest
|
|
if err := ctx.ShouldBindJSON(&req); err != nil {
|
|
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体", action, "请求体绑定失败", req)
|
|
return
|
|
}
|
|
|
|
pen, err := c.service.UpdatePenStatus(uint(id), req.Status)
|
|
if err != nil {
|
|
if errors.Is(err, service.ErrPenNotFound) {
|
|
controller.SendErrorWithAudit(ctx, controller.CodeNotFound, err.Error(), action, err.Error(), id)
|
|
return
|
|
} else if errors.Is(err, service.ErrPenStatusInvalidForOccupiedPen) || errors.Is(err, service.ErrPenStatusInvalidForUnoccupiedPen) {
|
|
controller.SendErrorWithAudit(ctx, controller.CodeConflict, err.Error(), action, err.Error(), id)
|
|
return
|
|
}
|
|
c.logger.Errorf("%s: 业务逻辑失败: %v", action, err)
|
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "更新猪栏状态失败", action, err.Error(), id)
|
|
return
|
|
}
|
|
|
|
resp := dto.PenResponse{
|
|
ID: pen.ID,
|
|
PenNumber: pen.PenNumber,
|
|
HouseID: pen.HouseID,
|
|
Capacity: pen.Capacity,
|
|
Status: pen.Status,
|
|
PigBatchID: *pen.PigBatchID,
|
|
}
|
|
controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "更新成功", resp, action, "更新成功", resp)
|
|
}
|