Files
pig-farm-controller/internal/app/controller/device/device_controller.go
2025-12-05 14:44:36 +08:00

244 lines
11 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package device
import (
"context"
"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/labstack/echo/v4"
"gorm.io/gorm"
)
// DeviceController 设备控制器
type DeviceController struct {
ctx context.Context
deviceService service.DeviceService
}
// NewDeviceController 创建一个新的设备控制器实例
func NewDeviceController(
ctx context.Context,
deviceService service.DeviceService,
) *DeviceController {
return &DeviceController{
ctx: ctx,
deviceService: deviceService,
}
}
// CreateDevice godoc
// @Summary 创建新设备
// @Description 根据提供的信息创建一个新设备
// @Tags 设备管理
// @Security BearerAuth
// @Accept json
// @Produce json
// @Param device body dto.CreateDeviceRequest true "设备信息"
// @Success 200 {object} controller.Response{data=dto.DeviceResponse}
// @Router /api/v1/devices [post]
func (c *DeviceController) CreateDevice(ctx echo.Context) error {
reqCtx, logger := logs.Trace(ctx.Request().Context(), c.ctx, "CreateDevice")
const actionType = "创建设备"
var req dto.CreateDeviceRequest
if err := ctx.Bind(&req); err != nil {
logger.Errorf("%s: 参数绑定失败: %v", actionType, err)
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
}
resp, err := c.deviceService.CreateDevice(reqCtx, &req)
if err != nil {
logger.Errorf("%s: 服务层创建失败: %v", actionType, err)
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "创建设备失败: "+err.Error(), actionType, "服务层创建失败", req)
}
logger.Infof("%s: 设备创建成功, ID: %d", actionType, resp.ID)
return controller.SendSuccessWithAudit(ctx, controller.CodeCreated, "设备创建成功", resp, actionType, "设备创建成功", resp)
}
// GetDevice godoc
// @Summary 获取设备信息
// @Description 根据设备ID获取单个设备的详细信息
// @Tags 设备管理
// @Security BearerAuth
// @Produce json
// @Param id path string true "设备ID"
// @Success 200 {object} controller.Response{data=dto.DeviceResponse}
// @Router /api/v1/devices/{id} [get]
func (c *DeviceController) GetDevice(ctx echo.Context) error {
reqCtx, logger := logs.Trace(ctx.Request().Context(), c.ctx, "GetDevice")
const actionType = "获取设备"
deviceID := ctx.Param("id")
id, err := strconv.ParseUint(deviceID, 10, 64)
if err != nil {
logger.Errorf("%s: 无效的ID: %s", actionType, deviceID)
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的ID: "+deviceID, actionType, "无效的ID", deviceID)
}
resp, err := c.deviceService.GetDevice(reqCtx, uint32(id))
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
logger.Warnf("%s: 设备不存在, ID: %s", actionType, deviceID)
return controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "设备未找到", actionType, "设备不存在", deviceID)
}
logger.Errorf("%s: 服务层获取失败: %v, ID: %s", actionType, err, deviceID)
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取设备信息失败: "+err.Error(), actionType, "服务层获取失败", deviceID)
}
logger.Infof("%s: 获取设备信息成功, ID: %d", actionType, resp.ID)
return controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取设备信息成功", resp, actionType, "获取设备信息成功", resp)
}
// ListDevices godoc
// @Summary 获取设备列表
// @Description 获取系统中所有设备的列表
// @Tags 设备管理
// @Security BearerAuth
// @Produce json
// @Success 200 {object} controller.Response{data=[]dto.DeviceResponse}
// @Router /api/v1/devices [get]
func (c *DeviceController) ListDevices(ctx echo.Context) error {
reqCtx, logger := logs.Trace(ctx.Request().Context(), c.ctx, "ListDevices")
const actionType = "获取设备列表"
resp, err := c.deviceService.ListDevices(reqCtx)
if err != nil {
logger.Errorf("%s: 服务层获取列表失败: %v", actionType, err)
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取设备列表失败: "+err.Error(), actionType, "服务层获取列表失败", nil)
}
logger.Infof("%s: 获取设备列表成功, 数量: %d", actionType, len(resp))
return controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取设备列表成功", resp, actionType, "获取设备列表成功", resp)
}
// UpdateDevice godoc
// @Summary 更新设备信息
// @Description 根据设备ID更新一个已存在的设备信息
// @Tags 设备管理
// @Security BearerAuth
// @Accept json
// @Produce json
// @Param id path string true "设备ID"
// @Param device body dto.UpdateDeviceRequest true "要更新的设备信息"
// @Success 200 {object} controller.Response{data=dto.DeviceResponse}
// @Router /api/v1/devices/{id} [put]
func (c *DeviceController) UpdateDevice(ctx echo.Context) error {
reqCtx, logger := logs.Trace(ctx.Request().Context(), c.ctx, "UpdateDevice")
const actionType = "更新设备"
deviceID := ctx.Param("id")
var req dto.UpdateDeviceRequest
if err := ctx.Bind(&req); err != nil {
logger.Errorf("%s: 参数绑定失败: %v", actionType, err)
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
}
id, err := strconv.ParseUint(deviceID, 10, 64)
if err != nil {
logger.Errorf("%s: 无效的ID: %s", actionType, deviceID)
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的ID: "+deviceID, actionType, "无效的ID", deviceID)
}
resp, err := c.deviceService.UpdateDevice(reqCtx, uint32(id), &req)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
logger.Warnf("%s: 设备不存在, ID: %s", actionType, deviceID)
return controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "设备未找到", actionType, "设备不存在", deviceID)
}
logger.Errorf("%s: 服务层更新失败: %v, ID: %s", actionType, err, deviceID)
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "更新设备失败: "+err.Error(), actionType, "服务层更新失败", deviceID)
}
logger.Infof("%s: 设备更新成功, ID: %d", actionType, resp.ID)
return controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "设备更新成功", resp, actionType, "设备更新成功", resp)
}
// DeleteDevice godoc
// @Summary 删除设备
// @Description 根据设备ID删除一个设备软删除
// @Tags 设备管理
// @Security BearerAuth
// @Produce json
// @Param id path string true "设备ID"
// @Success 200 {object} controller.Response
// @Router /api/v1/devices/{id} [delete]
func (c *DeviceController) DeleteDevice(ctx echo.Context) error {
reqCtx, logger := logs.Trace(ctx.Request().Context(), c.ctx, "DeleteDevice")
const actionType = "删除设备"
deviceID := ctx.Param("id")
id, err := strconv.ParseUint(deviceID, 10, 64)
if err != nil {
logger.Errorf("%s: 无效的ID: %s", actionType, deviceID)
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的ID: "+deviceID, actionType, "无效的ID", deviceID)
}
if err := c.deviceService.DeleteDevice(reqCtx, uint32(id)); err != nil {
switch {
case errors.Is(err, gorm.ErrRecordNotFound):
logger.Warnf("%s: 设备不存在, ID: %s", actionType, deviceID)
return controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "设备未找到", actionType, "设备不存在", deviceID)
case errors.Is(err, service.ErrDeviceInUse):
logger.Warnf("%s: 尝试删除正在被使用的设备, ID: %s", actionType, deviceID)
// 返回 409 Conflict 状态码,表示请求与服务器当前状态冲突
return controller.SendErrorWithAudit(ctx, controller.CodeConflict, err.Error(), actionType, "设备正在被使用", deviceID)
default:
logger.Errorf("%s: 服务层删除失败: %v, ID: %s", actionType, err, deviceID)
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "删除设备失败: "+err.Error(), actionType, "服务层删除失败", deviceID)
}
}
logger.Infof("%s: 设备删除成功, ID: %s", actionType, deviceID)
return controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "设备删除成功", nil, actionType, "设备删除成功", deviceID)
}
// ManualControl godoc
// @Summary 手动控制设备
// @Description 根据设备ID和指定的动作开启或关闭来手动控制设备
// @Tags 设备管理
// @Security BearerAuth
// @Accept json
// @Produce json
// @Param id path string true "设备ID"
// @Param manualControl body dto.ManualControlDeviceRequest true "手动控制指令"
// @Success 200 {object} controller.Response
// @Router /api/v1/devices/manual-control/{id} [post]
func (c *DeviceController) ManualControl(ctx echo.Context) error {
reqCtx, logger := logs.Trace(ctx.Request().Context(), c.ctx, "ManualControlDevice")
const actionType = "手动控制设备"
deviceID := ctx.Param("id")
var req dto.ManualControlDeviceRequest
if err := ctx.Bind(&req); err != nil {
logger.Errorf("%s: 参数绑定失败: %v", actionType, err)
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
}
id, err := strconv.ParseUint(deviceID, 10, 64)
if err != nil {
logger.Errorf("%s: 无效的ID: %s", actionType, deviceID)
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的ID: "+deviceID, actionType, "无效的ID", deviceID)
}
if err := c.deviceService.ManualControl(reqCtx, uint32(id), &req); err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
logger.Warnf("%s: 设备不存在, ID: %s", actionType, deviceID)
return controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "设备未找到", actionType, "设备不存在", deviceID)
}
logger.Errorf("%s: 服务层手动控制失败: %v, ID: %s", actionType, err, deviceID)
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "手动控制失败: "+err.Error(), actionType, "服务层手动控制失败", deviceID)
}
return controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "指令已发送", nil, actionType, "指令发送成功", nil)
}