Files
pig-farm-controller/internal/app/controller/device/area_controller_controller.go

311 lines
15 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"
)
// AreaControllerController 区域主控控制器
type AreaControllerController struct {
ctx context.Context
areaControllerService service.AreaControllerService
}
// NewAreaControllerController 创建一个新的区域主控控制器实例
func NewAreaControllerController(
ctx context.Context,
areaControllerService service.AreaControllerService,
) *AreaControllerController {
return &AreaControllerController{
ctx: ctx,
areaControllerService: areaControllerService,
}
}
// CreateAreaController godoc
// @Summary 创建新区域主控
// @Description 根据提供的信息创建一个新区域主控
// @Tags 区域主控管理
// @Security BearerAuth
// @Accept json
// @Produce json
// @Param areaController body dto.CreateAreaControllerRequest true "区域主控信息"
// @Success 200 {object} controller.Response{data=dto.AreaControllerResponse}
// @Router /api/v1/area-controllers [post]
func (c *AreaControllerController) CreateAreaController(ctx echo.Context) error {
reqCtx, logger := logs.Trace(ctx.Request().Context(), c.ctx, "CreateAreaController")
const actionType = "创建区域主控"
var req dto.CreateAreaControllerRequest
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.areaControllerService.CreateAreaController(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)
}
// GetAreaController godoc
// @Summary 获取区域主控信息
// @Description 根据ID获取单个区域主控的详细信息
// @Tags 区域主控管理
// @Security BearerAuth
// @Produce json
// @Param id path string true "区域主控ID"
// @Success 200 {object} controller.Response{data=dto.AreaControllerResponse}
// @Router /api/v1/area-controllers/{id} [get]
func (c *AreaControllerController) GetAreaController(ctx echo.Context) error {
reqCtx, logger := logs.Trace(ctx.Request().Context(), c.ctx, "GetAreaController")
const actionType = "获取区域主控"
acID := ctx.Param("id")
id, err := strconv.ParseUint(acID, 10, 64)
if err != nil {
logger.Errorf("%s: 无效的ID: %s", actionType, acID)
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的ID: "+acID, actionType, "无效的ID", acID)
}
resp, err := c.areaControllerService.GetAreaController(reqCtx, uint32(id))
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
logger.Warnf("%s: 区域主控不存在, ID: %s", actionType, acID)
return controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "区域主控未找到", actionType, "区域主控不存在", acID)
}
logger.Errorf("%s: 服务层获取失败: %v, ID: %s", actionType, err, acID)
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取区域主控信息失败: "+err.Error(), actionType, "服务层获取失败", acID)
}
logger.Infof("%s: 获取区域主控信息成功, ID: %d", actionType, resp.ID)
return controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取区域主控信息成功", resp, actionType, "获取区域主控信息成功", resp)
}
// ListAreaControllers godoc
// @Summary 获取所有区域主控列表
// @Description 获取系统中所有区域主控的列表
// @Tags 区域主控管理
// @Security BearerAuth
// @Produce json
// @Success 200 {object} controller.Response{data=[]dto.AreaControllerResponse}
// @Router /api/v1/area-controllers [get]
func (c *AreaControllerController) ListAreaControllers(ctx echo.Context) error {
reqCtx, logger := logs.Trace(ctx.Request().Context(), c.ctx, "ListAreaControllers")
const actionType = "获取区域主控列表"
resp, err := c.areaControllerService.ListAreaControllers(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)
}
// UpdateAreaController godoc
// @Summary 更新区域主控信息
// @Description 根据ID更新一个已存在的区域主控信息
// @Tags 区域主控管理
// @Security BearerAuth
// @Accept json
// @Produce json
// @Param id path string true "区域主控ID"
// @Param areaController body dto.UpdateAreaControllerRequest true "要更新的区域主控信息"
// @Success 200 {object} controller.Response{data=dto.AreaControllerResponse}
// @Router /api/v1/area-controllers/{id} [put]
func (c *AreaControllerController) UpdateAreaController(ctx echo.Context) error {
reqCtx, logger := logs.Trace(ctx.Request().Context(), c.ctx, "UpdateAreaController")
const actionType = "更新区域主控"
acID := ctx.Param("id")
var req dto.UpdateAreaControllerRequest
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(acID, 10, 64)
if err != nil {
logger.Errorf("%s: 无效的ID: %s", actionType, acID)
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的ID: "+acID, actionType, "无效的ID", acID)
}
resp, err := c.areaControllerService.UpdateAreaController(reqCtx, uint32(id), &req)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
logger.Warnf("%s: 区域主控不存在, ID: %s", actionType, acID)
return controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "区域主控未找到", actionType, "区域主控不存在", acID)
}
logger.Errorf("%s: 服务层更新失败: %v, ID: %s", actionType, err, acID)
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "更新区域主控失败: "+err.Error(), actionType, "服务层更新失败", acID)
}
logger.Infof("%s: 区域主控更新成功, ID: %d", actionType, resp.ID)
return controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "区域主控更新成功", resp, actionType, "区域主控更新成功", resp)
}
// DeleteAreaController godoc
// @Summary 删除区域主控
// @Description 根据ID删除一个区域主控软删除
// @Tags 区域主控管理
// @Security BearerAuth
// @Produce json
// @Param id path string true "区域主控ID"
// @Success 200 {object} controller.Response
// @Router /api/v1/area-controllers/{id} [delete]
func (c *AreaControllerController) DeleteAreaController(ctx echo.Context) error {
reqCtx, logger := logs.Trace(ctx.Request().Context(), c.ctx, "DeleteAreaController")
const actionType = "删除区域主控"
acID := ctx.Param("id")
id, err := strconv.ParseUint(acID, 10, 64)
if err != nil {
logger.Errorf("%s: 无效的ID: %s", actionType, acID)
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的ID: "+acID, actionType, "无效的ID", acID)
}
if err := c.areaControllerService.DeleteAreaController(reqCtx, uint32(id)); err != nil {
switch {
case errors.Is(err, gorm.ErrRecordNotFound):
logger.Warnf("%s: 区域主控不存在, ID: %s", actionType, acID)
return controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "区域主控未找到", actionType, "区域主控不存在", acID)
case errors.Is(err, service.ErrAreaControllerInUse):
logger.Warnf("%s: 尝试删除正在被使用的主控, ID: %s", actionType, acID)
return controller.SendErrorWithAudit(ctx, controller.CodeConflict, err.Error(), actionType, "主控正在被使用", acID)
default:
logger.Errorf("%s: 服务层删除失败: %v, ID: %s", actionType, err, acID)
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "删除区域主控失败: "+err.Error(), actionType, "服务层删除失败", acID)
}
}
logger.Infof("%s: 区域主控删除成功, ID: %s", actionType, acID)
return controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "区域主控删除成功", nil, actionType, "区域主控删除成功", acID)
}
// StartUpgrade godoc
// @Summary 启动区域主控OTA升级
// @Description 为指定的区域主控上传固件并启动一个OTA升级任务
// @Tags 区域主控管理
// @Security BearerAuth
// @Accept mpfd
// @Produce json
// @Param id path string true "区域主控ID"
// @Param firmware_file formData file true "固件压缩包文件"
// @Success 200 {object} controller.Response{data=dto.OtaUpgradeResponse}
// @Router /api/v1/area-controllers/{id}/ota/start [post]
func (c *AreaControllerController) StartUpgrade(ctx echo.Context) error {
reqCtx, logger := logs.Trace(ctx.Request().Context(), c.ctx, "StartUpgrade")
const actionType = "启动区域主控OTA升级"
acID := ctx.Param("id")
id, err := strconv.ParseUint(acID, 10, 64)
if err != nil {
logger.Errorf("%s: 无效的区域主控ID: %s", actionType, acID)
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的区域主控ID: "+acID, actionType, "无效的ID", acID)
}
var req dto.OtaUpgradeRequest
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.areaControllerService.StartUpgrade(reqCtx, uint32(id), &req)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
logger.Warnf("%s: 区域主控不存在, ID: %s", actionType, acID)
return controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "区域主控未找到", actionType, "区域主控不存在", acID)
}
logger.Errorf("%s: 服务层启动升级失败: %v, ID: %s", actionType, err, acID)
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "启动升级失败: "+err.Error(), actionType, "服务层启动升级失败", acID)
}
logger.Infof("%s: 升级任务启动成功, 任务ID: %d", actionType, resp.TaskID)
return controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "升级任务启动成功", resp, actionType, "升级任务启动成功", resp)
}
// GetUpgradeProgress godoc
// @Summary 查询OTA升级进度
// @Description 根据任务ID查询指定OTA升级任务的当前进度
// @Tags 区域主控管理
// @Security BearerAuth
// @Produce json
// @Param taskId path string true "OTA任务ID"
// @Success 200 {object} controller.Response{data=dto.OtaUpgradeProgressResponse}
// @Router /api/v1/area-controllers/ota/progress/{taskId} [get]
func (c *AreaControllerController) GetUpgradeProgress(ctx echo.Context) error {
reqCtx, logger := logs.Trace(ctx.Request().Context(), c.ctx, "GetUpgradeProgress")
const actionType = "查询OTA升级进度"
taskIDStr := ctx.Param("taskId")
taskID, err := strconv.ParseUint(taskIDStr, 10, 64)
if err != nil {
logger.Errorf("%s: 无效的任务ID: %s", actionType, taskIDStr)
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的任务ID: "+taskIDStr, actionType, "无效的ID", taskIDStr)
}
resp, err := c.areaControllerService.GetUpgradeProgress(reqCtx, uint32(taskID))
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
logger.Warnf("%s: 升级任务不存在, ID: %s", actionType, taskIDStr)
return controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "升级任务未找到", actionType, "升级任务不存在", taskIDStr)
}
logger.Errorf("%s: 服务层查询进度失败: %v, ID: %s", actionType, err, taskIDStr)
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "查询进度失败: "+err.Error(), actionType, "服务层查询进度失败", taskIDStr)
}
logger.Infof("%s: 查询进度成功, 任务ID: %d", actionType, resp.TaskID)
return controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "查询进度成功", resp, actionType, "查询进度成功", resp)
}
// StopUpgrade godoc
// @Summary 停止OTA升级任务
// @Description 根据任务ID请求停止一个正在进行的OTA升级任务
// @Tags 区域主控管理
// @Security BearerAuth
// @Produce json
// @Param taskId path string true "OTA任务ID"
// @Success 200 {object} controller.Response
// @Router /api/v1/area-controllers/ota/tasks/{taskId}/stop [post]
func (c *AreaControllerController) StopUpgrade(ctx echo.Context) error {
reqCtx, logger := logs.Trace(ctx.Request().Context(), c.ctx, "StopUpgrade")
const actionType = "停止OTA升级任务"
taskIDStr := ctx.Param("taskId")
taskID, err := strconv.ParseUint(taskIDStr, 10, 64)
if err != nil {
logger.Errorf("%s: 无效的任务ID: %s", actionType, taskIDStr)
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的任务ID: "+taskIDStr, actionType, "无效的ID", taskIDStr)
}
err = c.areaControllerService.StopUpgrade(reqCtx, uint32(taskID))
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
logger.Warnf("%s: 升级任务不存在, ID: %s", actionType, taskIDStr)
return controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "升级任务未找到", actionType, "升级任务不存在", taskIDStr)
}
logger.Errorf("%s: 服务层停止任务失败: %v, ID: %s", actionType, err, taskIDStr)
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "停止任务失败: "+err.Error(), actionType, "服务层停止任务失败", taskIDStr)
}
logger.Infof("%s: 停止任务请求成功, 任务ID: %s", actionType, taskIDStr)
return controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "停止任务请求成功", nil, actionType, "停止任务请求成功", taskIDStr)
}