issue_20 #24
| @@ -120,17 +120,18 @@ func newListDeviceResponse(devices []*models.Device) ([]*DeviceResponse, error) | |||||||
| // @Success      200 {object} controller.Response{data=DeviceResponse} | // @Success      200 {object} controller.Response{data=DeviceResponse} | ||||||
| // @Router       /api/v1/devices [post] | // @Router       /api/v1/devices [post] | ||||||
| func (c *Controller) CreateDevice(ctx *gin.Context) { | func (c *Controller) CreateDevice(ctx *gin.Context) { | ||||||
|  | 	const actionType = "创建设备" | ||||||
| 	var req CreateDeviceRequest | 	var req CreateDeviceRequest | ||||||
| 	if err := ctx.ShouldBindJSON(&req); err != nil { | 	if err := ctx.ShouldBindJSON(&req); err != nil { | ||||||
| 		c.logger.Errorf("创建设备: 参数绑定失败: %v", err) | 		c.logger.Errorf("创建设备: 参数绑定失败: %v", err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, err.Error(), "创建设备", "请求体绑定失败", req) | 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	propertiesJSON, err := json.Marshal(req.Properties) | 	propertiesJSON, err := json.Marshal(req.Properties) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		c.logger.Errorf("创建设备: 序列化属性失败: %v", err) | 		c.logger.Errorf("创建设备: 序列化属性失败: %v", err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "属性字段格式错误", "创建设备", "属性序列化失败", req.Properties) | 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "属性字段格式错误", actionType, "属性序列化失败", req.Properties) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -146,24 +147,24 @@ func (c *Controller) CreateDevice(ctx *gin.Context) { | |||||||
| 	// 在创建设备前进行自检 | 	// 在创建设备前进行自检 | ||||||
| 	if !device.SelfCheck() { | 	if !device.SelfCheck() { | ||||||
| 		c.logger.Errorf("创建设备: 设备属性自检失败: %v", device) | 		c.logger.Errorf("创建设备: 设备属性自检失败: %v", device) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "设备属性不符合要求", "创建设备", "设备属性自检失败", device) | 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "设备属性不符合要求", actionType, "设备属性自检失败", device) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := c.repo.Create(device); err != nil { | 	if err := c.repo.Create(device); err != nil { | ||||||
| 		c.logger.Errorf("创建设备: 数据库操作失败: %v", err) | 		c.logger.Errorf("创建设备: 数据库操作失败: %v", err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "创建设备失败", "创建设备", "数据库创建失败", device) | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "创建设备失败: "+err.Error(), actionType, "数据库创建失败", device) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	resp, err := newDeviceResponse(device) | 	resp, err := newDeviceResponse(device) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		c.logger.Errorf("创建设备: 序列化响应失败: %v", err) | 		c.logger.Errorf("创建设备: 序列化响应失败: %v", err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "设备创建成功,但响应生成失败", "创建设备", "响应序列化失败", device) | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "设备创建成功,但响应生成失败", actionType, "响应序列化失败", device) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	controller.SendSuccessWithAudit(ctx, controller.CodeCreated, "设备创建成功", resp, "创建设备", "设备创建成功", resp) | 	controller.SendSuccessWithAudit(ctx, controller.CodeCreated, "设备创建成功", resp, actionType, "设备创建成功", resp) | ||||||
| } | } | ||||||
|  |  | ||||||
| // GetDevice godoc | // GetDevice godoc | ||||||
| @@ -175,31 +176,32 @@ func (c *Controller) CreateDevice(ctx *gin.Context) { | |||||||
| // @Success      200 {object} controller.Response{data=DeviceResponse} | // @Success      200 {object} controller.Response{data=DeviceResponse} | ||||||
| // @Router       /api/v1/devices/{id} [get] | // @Router       /api/v1/devices/{id} [get] | ||||||
| func (c *Controller) GetDevice(ctx *gin.Context) { | func (c *Controller) GetDevice(ctx *gin.Context) { | ||||||
|  | 	const actionType = "获取设备" | ||||||
| 	deviceID := ctx.Param("id") | 	deviceID := ctx.Param("id") | ||||||
|  |  | ||||||
| 	device, err := c.repo.FindByIDString(deviceID) | 	device, err := c.repo.FindByIDString(deviceID) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if errors.Is(err, gorm.ErrRecordNotFound) { | 		if errors.Is(err, gorm.ErrRecordNotFound) { | ||||||
| 			controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "设备未找到", "获取设备", "设备不存在", deviceID) | 			controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "设备未找到", actionType, "设备不存在", deviceID) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		if strings.Contains(err.Error(), "无效的设备ID格式") { | 		if strings.Contains(err.Error(), "无效的设备ID格式") { | ||||||
| 			controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, err.Error(), "获取设备", "设备ID格式错误", deviceID) | 			controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, err.Error(), actionType, "设备ID格式错误", deviceID) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		c.logger.Errorf("获取设备: 数据库操作失败: %v", err) | 		c.logger.Errorf("获取设备: 数据库操作失败: %v", err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取设备信息失败", "获取设备", "数据库查询失败", deviceID) | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取设备信息失败: "+err.Error(), actionType, "数据库查询失败", deviceID) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	resp, err := newDeviceResponse(device) | 	resp, err := newDeviceResponse(device) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		c.logger.Errorf("获取设备: 序列化响应失败: %v", err) | 		c.logger.Errorf("获取设备: 序列化响应失败: %v", err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取设备信息失败: 内部数据格式错误", "获取设备", "响应序列化失败", device) | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取设备信息失败: 内部数据格式错误", actionType, "响应序列化失败", device) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取设备信息成功", resp, "获取设备", "获取设备信息成功", resp) | 	controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取设备信息成功", resp, actionType, "获取设备信息成功", resp) | ||||||
| } | } | ||||||
|  |  | ||||||
| // ListDevices godoc | // ListDevices godoc | ||||||
| @@ -210,21 +212,22 @@ func (c *Controller) GetDevice(ctx *gin.Context) { | |||||||
| // @Success      200 {object} controller.Response{data=[]DeviceResponse} | // @Success      200 {object} controller.Response{data=[]DeviceResponse} | ||||||
| // @Router       /api/v1/devices [get] | // @Router       /api/v1/devices [get] | ||||||
| func (c *Controller) ListDevices(ctx *gin.Context) { | func (c *Controller) ListDevices(ctx *gin.Context) { | ||||||
|  | 	const actionType = "获取设备列表" | ||||||
| 	devices, err := c.repo.ListAll() | 	devices, err := c.repo.ListAll() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		c.logger.Errorf("获取设备列表: 数据库操作失败: %v", err) | 		c.logger.Errorf("获取设备列表: 数据库操作失败: %v", err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取设备列表失败", "获取设备列表", "数据库查询失败", nil) | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取设备列表失败: "+err.Error(), actionType, "数据库查询失败", nil) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	resp, err := newListDeviceResponse(devices) | 	resp, err := newListDeviceResponse(devices) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		c.logger.Errorf("获取设备列表: 序列化响应失败: %v", err) | 		c.logger.Errorf("获取设备列表: 序列化响应失败: %v", err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取设备列表失败: 内部数据格式错误", "获取设备列表", "响应序列化失败", devices) | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取设备列表失败: 内部数据格式错误", actionType, "响应序列化失败", devices) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取设备列表成功", resp, "获取设备列表", "获取设备列表成功", resp) | 	controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取设备列表成功", resp, actionType, "获取设备列表成功", resp) | ||||||
| } | } | ||||||
|  |  | ||||||
| // UpdateDevice godoc | // UpdateDevice godoc | ||||||
| @@ -238,21 +241,22 @@ func (c *Controller) ListDevices(ctx *gin.Context) { | |||||||
| // @Success      200 {object} controller.Response{data=DeviceResponse} | // @Success      200 {object} controller.Response{data=DeviceResponse} | ||||||
| // @Router       /api/v1/devices/{id} [put] | // @Router       /api/v1/devices/{id} [put] | ||||||
| func (c *Controller) UpdateDevice(ctx *gin.Context) { | func (c *Controller) UpdateDevice(ctx *gin.Context) { | ||||||
|  | 	const actionType = "更新设备" | ||||||
| 	deviceID := ctx.Param("id") | 	deviceID := ctx.Param("id") | ||||||
|  |  | ||||||
| 	// 1. 检查设备是否存在 | 	// 1. 检查设备是否存在 | ||||||
| 	existingDevice, err := c.repo.FindByIDString(deviceID) | 	existingDevice, err := c.repo.FindByIDString(deviceID) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if errors.Is(err, gorm.ErrRecordNotFound) { | 		if errors.Is(err, gorm.ErrRecordNotFound) { | ||||||
| 			controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "设备未找到", "更新设备", "设备不存在", deviceID) | 			controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "设备未找到", actionType, "设备不存在", deviceID) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		if strings.Contains(err.Error(), "无效的设备ID格式") { | 		if strings.Contains(err.Error(), "无效的设备ID格式") { | ||||||
| 			controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, err.Error(), "更新设备", "设备ID格式错误", deviceID) | 			controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, err.Error(), actionType, "设备ID格式错误", deviceID) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		c.logger.Errorf("更新设备: 查找设备失败: %v", err) | 		c.logger.Errorf("更新设备: 查找设备失败: %v", err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "更新设备失败", "更新设备", "数据库查询失败", deviceID) | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "更新设备失败: "+err.Error(), actionType, "数据库查询失败", deviceID) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -260,14 +264,14 @@ func (c *Controller) UpdateDevice(ctx *gin.Context) { | |||||||
| 	var req UpdateDeviceRequest | 	var req UpdateDeviceRequest | ||||||
| 	if err := ctx.ShouldBindJSON(&req); err != nil { | 	if err := ctx.ShouldBindJSON(&req); err != nil { | ||||||
| 		c.logger.Errorf("更新设备: 参数绑定失败: %v", err) | 		c.logger.Errorf("更新设备: 参数绑定失败: %v", err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, err.Error(), "更新设备", "请求体绑定失败", req) | 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	propertiesJSON, err := json.Marshal(req.Properties) | 	propertiesJSON, err := json.Marshal(req.Properties) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		c.logger.Errorf("更新设备: 序列化属性失败: %v", err) | 		c.logger.Errorf("更新设备: 序列化属性失败: %v", err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "属性字段格式错误", "更新设备", "属性序列化失败", req.Properties) | 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "属性字段格式错误", actionType, "属性序列化失败", req.Properties) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -282,25 +286,25 @@ func (c *Controller) UpdateDevice(ctx *gin.Context) { | |||||||
| 	// 在更新设备前进行自检 | 	// 在更新设备前进行自检 | ||||||
| 	if !existingDevice.SelfCheck() { | 	if !existingDevice.SelfCheck() { | ||||||
| 		c.logger.Errorf("更新设备: 设备属性自检失败: %v", existingDevice) | 		c.logger.Errorf("更新设备: 设备属性自检失败: %v", existingDevice) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "设备属性不符合要求", "更新设备", "设备属性自检失败", existingDevice) | 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "设备属性不符合要求", actionType, "设备属性自检失败", existingDevice) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// 4. 将修改后的 existingDevice 对象保存回数据库 | 	// 4. 将修改后的 existingDevice 对象保存回数据库 | ||||||
| 	if err := c.repo.Update(existingDevice); err != nil { | 	if err := c.repo.Update(existingDevice); err != nil { | ||||||
| 		c.logger.Errorf("更新设备: 数据库操作失败: %v", err) | 		c.logger.Errorf("更新设备: 数据库操作失败: %v", err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "更新设备失败", "更新设备", "数据库更新失败", existingDevice) | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "更新设备失败: "+err.Error(), actionType, "数据库更新失败", existingDevice) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	resp, err := newDeviceResponse(existingDevice) | 	resp, err := newDeviceResponse(existingDevice) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		c.logger.Errorf("更新设备: 序列化响应失败: %v", err) | 		c.logger.Errorf("更新设备: 序列化响应失败: %v", err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "设备更新成功,但响应生成失败", "更新设备", "响应序列化失败", existingDevice) | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "设备更新成功,但响应生成失败", actionType, "响应序列化失败", existingDevice) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "设备更新成功", resp, "更新设备", "设备更新成功", resp) | 	controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "设备更新成功", resp, actionType, "设备更新成功", resp) | ||||||
| } | } | ||||||
|  |  | ||||||
| // DeleteDevice godoc | // DeleteDevice godoc | ||||||
| @@ -312,20 +316,21 @@ func (c *Controller) UpdateDevice(ctx *gin.Context) { | |||||||
| // @Success      200 {object} controller.Response | // @Success      200 {object} controller.Response | ||||||
| // @Router       /api/v1/devices/{id} [delete] | // @Router       /api/v1/devices/{id} [delete] | ||||||
| func (c *Controller) DeleteDevice(ctx *gin.Context) { | func (c *Controller) DeleteDevice(ctx *gin.Context) { | ||||||
|  | 	const actionType = "删除设备" | ||||||
| 	deviceID := ctx.Param("id") | 	deviceID := ctx.Param("id") | ||||||
|  |  | ||||||
| 	// 我们需要先将字符串ID转换为uint,因为Delete方法需要uint类型 | 	// 我们需要先将字符串ID转换为uint,因为Delete方法需要uint类型 | ||||||
| 	idUint, err := strconv.ParseUint(deviceID, 10, 64) | 	idUint, err := strconv.ParseUint(deviceID, 10, 64) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的设备ID格式", "删除设备", "设备ID格式错误", deviceID) | 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的设备ID格式", actionType, "设备ID格式错误", deviceID) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := c.repo.Delete(uint(idUint)); err != nil { | 	if err := c.repo.Delete(uint(idUint)); err != nil { | ||||||
| 		c.logger.Errorf("删除设备: 数据库操作失败: %v", err) | 		c.logger.Errorf("删除设备: 数据库操作失败: %v", err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "删除设备失败", "删除设备", "数据库删除失败", deviceID) | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "删除设备失败: "+err.Error(), actionType, "数据库删除失败", deviceID) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "设备删除成功", nil, "删除设备", "设备删除成功", deviceID) | 	controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "设备删除成功", nil, actionType, "设备删除成功", deviceID) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -118,15 +118,16 @@ func NewController(logger *logs.Logger, planRepo repository.PlanRepository, anal | |||||||
| // @Router       /api/v1/plans [post] | // @Router       /api/v1/plans [post] | ||||||
| func (c *Controller) CreatePlan(ctx *gin.Context) { | func (c *Controller) CreatePlan(ctx *gin.Context) { | ||||||
| 	var req CreatePlanRequest | 	var req CreatePlanRequest | ||||||
|  | 	const actionType = "创建计划" | ||||||
| 	if err := ctx.ShouldBindJSON(&req); err != nil { | 	if err := ctx.ShouldBindJSON(&req); err != nil { | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), "创建计划", "请求体绑定失败", req) | 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// 使用已有的转换函数,它已经包含了验证和重排逻辑 | 	// 使用已有的转换函数,它已经包含了验证和重排逻辑 | ||||||
| 	planToCreate, err := PlanFromCreateRequest(&req) | 	planToCreate, err := PlanFromCreateRequest(&req) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "计划数据校验失败: "+err.Error(), "创建计划", "计划数据校验失败", req) | 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "计划数据校验失败: "+err.Error(), actionType, "计划数据校验失败", req) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -140,7 +141,7 @@ func (c *Controller) CreatePlan(ctx *gin.Context) { | |||||||
|  |  | ||||||
| 	// 调用仓库方法创建计划 | 	// 调用仓库方法创建计划 | ||||||
| 	if err := c.planRepo.CreatePlan(planToCreate); err != nil { | 	if err := c.planRepo.CreatePlan(planToCreate); err != nil { | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "创建计划失败: "+err.Error(), "创建计划", "数据库创建计划失败", planToCreate) | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "创建计划失败: "+err.Error(), actionType, "数据库创建计划失败", planToCreate) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -154,12 +155,12 @@ func (c *Controller) CreatePlan(ctx *gin.Context) { | |||||||
| 	resp, err := PlanToResponse(planToCreate) | 	resp, err := PlanToResponse(planToCreate) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		c.logger.Errorf("创建计划: 序列化响应失败: %v", err) | 		c.logger.Errorf("创建计划: 序列化响应失败: %v", err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "计划创建成功,但响应生成失败", "创建计划", "响应序列化失败", planToCreate) | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "计划创建成功,但响应生成失败", actionType, "响应序列化失败", planToCreate) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// 使用统一的成功响应函数 | 	// 使用统一的成功响应函数 | ||||||
| 	controller.SendSuccessWithAudit(ctx, controller.CodeCreated, "计划创建成功", resp, "创建计划", "计划创建成功", resp) | 	controller.SendSuccessWithAudit(ctx, controller.CodeCreated, "计划创建成功", resp, actionType, "计划创建成功", resp) | ||||||
| } | } | ||||||
|  |  | ||||||
| // GetPlan godoc | // GetPlan godoc | ||||||
| @@ -171,11 +172,12 @@ func (c *Controller) CreatePlan(ctx *gin.Context) { | |||||||
| // @Success      200 {object} controller.Response{data=plan.PlanResponse} "业务码为200代表成功获取" | // @Success      200 {object} controller.Response{data=plan.PlanResponse} "业务码为200代表成功获取" | ||||||
| // @Router       /api/v1/plans/{id} [get] | // @Router       /api/v1/plans/{id} [get] | ||||||
| func (c *Controller) GetPlan(ctx *gin.Context) { | func (c *Controller) GetPlan(ctx *gin.Context) { | ||||||
|  | 	const actionType = "获取计划详情" | ||||||
| 	// 1. 从 URL 路径中获取 ID | 	// 1. 从 URL 路径中获取 ID | ||||||
| 	idStr := ctx.Param("id") | 	idStr := ctx.Param("id") | ||||||
| 	id, err := strconv.ParseUint(idStr, 10, 32) | 	id, err := strconv.ParseUint(idStr, 10, 32) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的计划ID格式", "获取计划详情", "计划ID格式错误", idStr) | 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的计划ID格式", actionType, "计划ID格式错误", idStr) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -184,12 +186,12 @@ func (c *Controller) GetPlan(ctx *gin.Context) { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		// 判断是否为“未找到”错误 | 		// 判断是否为“未找到”错误 | ||||||
| 		if errors.Is(err, gorm.ErrRecordNotFound) { | 		if errors.Is(err, gorm.ErrRecordNotFound) { | ||||||
| 			controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "计划不存在", "获取计划详情", "计划不存在", id) | 			controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "计划不存在", actionType, "计划不存在", id) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		// 其他数据库错误视为内部错误 | 		// 其他数据库错误视为内部错误 | ||||||
| 		c.logger.Errorf("获取计划详情失败: %v", err) | 		c.logger.Errorf("获取计划详情失败: %v", err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取计划详情时发生内部错误", "获取计划详情", "数据库查询失败", id) | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取计划详情时发生内部错误", actionType, "数据库查询失败", id) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -197,12 +199,12 @@ func (c *Controller) GetPlan(ctx *gin.Context) { | |||||||
| 	resp, err := PlanToResponse(plan) | 	resp, err := PlanToResponse(plan) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		c.logger.Errorf("获取计划详情: 序列化响应失败: %v", err) | 		c.logger.Errorf("获取计划详情: 序列化响应失败: %v", err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取计划详情失败: 内部数据格式错误", "获取计划详情", "响应序列化失败", plan) | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取计划详情失败: 内部数据格式错误", actionType, "响应序列化失败", plan) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// 4. 发送成功响应 | 	// 4. 发送成功响应 | ||||||
| 	controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取计划详情成功", resp, "获取计划详情", "获取计划详情成功", resp) | 	controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取计划详情成功", resp, actionType, "获取计划详情成功", resp) | ||||||
| } | } | ||||||
|  |  | ||||||
| // ListPlans godoc | // ListPlans godoc | ||||||
| @@ -213,11 +215,12 @@ func (c *Controller) GetPlan(ctx *gin.Context) { | |||||||
| // @Success      200 {object} controller.Response{data=plan.ListPlansResponse} "业务码为200代表成功获取列表" | // @Success      200 {object} controller.Response{data=plan.ListPlansResponse} "业务码为200代表成功获取列表" | ||||||
| // @Router       /api/v1/plans [get] | // @Router       /api/v1/plans [get] | ||||||
| func (c *Controller) ListPlans(ctx *gin.Context) { | func (c *Controller) ListPlans(ctx *gin.Context) { | ||||||
|  | 	const actionType = "获取计划列表" | ||||||
| 	// 1. 调用仓库层获取所有计划 | 	// 1. 调用仓库层获取所有计划 | ||||||
| 	plans, err := c.planRepo.ListBasicPlans() | 	plans, err := c.planRepo.ListBasicPlans() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		c.logger.Errorf("获取计划列表失败: %v", err) | 		c.logger.Errorf("获取计划列表失败: %v", err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取计划列表时发生内部错误", "获取计划列表", "数据库查询失败", nil) | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取计划列表时发生内部错误", actionType, "数据库查询失败", nil) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -227,7 +230,7 @@ func (c *Controller) ListPlans(ctx *gin.Context) { | |||||||
| 		resp, err := PlanToResponse(&p) | 		resp, err := PlanToResponse(&p) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			c.logger.Errorf("获取计划列表: 序列化响应失败: %v", err) | 			c.logger.Errorf("获取计划列表: 序列化响应失败: %v", err) | ||||||
| 			controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取计划列表失败: 内部数据格式错误", "获取计划列表", "响应序列化失败", p) | 			controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取计划列表失败: 内部数据格式错误", actionType, "响应序列化失败", p) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		planResponses = append(planResponses, *resp) | 		planResponses = append(planResponses, *resp) | ||||||
| @@ -238,7 +241,7 @@ func (c *Controller) ListPlans(ctx *gin.Context) { | |||||||
| 		Plans: planResponses, | 		Plans: planResponses, | ||||||
| 		Total: len(planResponses), | 		Total: len(planResponses), | ||||||
| 	} | 	} | ||||||
| 	controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取计划列表成功", resp, "获取计划列表", "获取计划列表成功", resp) | 	controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取计划列表成功", resp, actionType, "获取计划列表成功", resp) | ||||||
| } | } | ||||||
|  |  | ||||||
| // UpdatePlan godoc | // UpdatePlan godoc | ||||||
| @@ -252,25 +255,26 @@ func (c *Controller) ListPlans(ctx *gin.Context) { | |||||||
| // @Success      200 {object} controller.Response{data=plan.PlanResponse} "业务码为200代表更新成功" | // @Success      200 {object} controller.Response{data=plan.PlanResponse} "业务码为200代表更新成功" | ||||||
| // @Router       /api/v1/plans/{id} [put] | // @Router       /api/v1/plans/{id} [put] | ||||||
| func (c *Controller) UpdatePlan(ctx *gin.Context) { | func (c *Controller) UpdatePlan(ctx *gin.Context) { | ||||||
|  | 	const actionType = "更新计划" | ||||||
| 	// 1. 从 URL 路径中获取 ID | 	// 1. 从 URL 路径中获取 ID | ||||||
| 	idStr := ctx.Param("id") | 	idStr := ctx.Param("id") | ||||||
| 	id, err := strconv.ParseUint(idStr, 10, 32) | 	id, err := strconv.ParseUint(idStr, 10, 32) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的计划ID格式", "更新计划", "计划ID格式错误", idStr) | 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的计划ID格式", actionType, "计划ID格式错误", idStr) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// 2. 绑定请求体 | 	// 2. 绑定请求体 | ||||||
| 	var req UpdatePlanRequest | 	var req UpdatePlanRequest | ||||||
| 	if err := ctx.ShouldBindJSON(&req); err != nil { | 	if err := ctx.ShouldBindJSON(&req); err != nil { | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), "更新计划", "请求体绑定失败", req) | 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// 3. 将请求转换为模型(转换函数带校验) | 	// 3. 将请求转换为模型(转换函数带校验) | ||||||
| 	planToUpdate, err := PlanFromUpdateRequest(&req) | 	planToUpdate, err := PlanFromUpdateRequest(&req) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "计划数据校验失败: "+err.Error(), "更新计划", "计划数据校验失败", req) | 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "计划数据校验失败: "+err.Error(), actionType, "计划数据校验失败", req) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	planToUpdate.ID = uint(id) // 确保ID被设置 | 	planToUpdate.ID = uint(id) // 确保ID被设置 | ||||||
| @@ -287,11 +291,11 @@ func (c *Controller) UpdatePlan(ctx *gin.Context) { | |||||||
| 	_, err = c.planRepo.GetBasicPlanByID(uint(id)) | 	_, err = c.planRepo.GetBasicPlanByID(uint(id)) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if errors.Is(err, gorm.ErrRecordNotFound) { | 		if errors.Is(err, gorm.ErrRecordNotFound) { | ||||||
| 			controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "计划不存在", "更新计划", "计划不存在", id) | 			controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "计划不存在", actionType, "计划不存在", id) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		c.logger.Errorf("获取计划详情失败: %v", err) | 		c.logger.Errorf("获取计划详情失败: %v", err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取计划详情时发生内部错误", "更新计划", "数据库查询失败", id) | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取计划详情时发生内部错误", actionType, "数据库查询失败", id) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -301,7 +305,7 @@ func (c *Controller) UpdatePlan(ctx *gin.Context) { | |||||||
| 	c.logger.Infof("计划 #%d 被更新,执行计数器已重置为 0。", planToUpdate.ID) | 	c.logger.Infof("计划 #%d 被更新,执行计数器已重置为 0。", planToUpdate.ID) | ||||||
|  |  | ||||||
| 	if err := c.planRepo.UpdatePlan(planToUpdate); err != nil { | 	if err := c.planRepo.UpdatePlan(planToUpdate); err != nil { | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "更新计划失败: "+err.Error(), "更新计划", "数据库更新计划失败", planToUpdate) | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "更新计划失败: "+err.Error(), actionType, "数据库更新计划失败", planToUpdate) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -315,7 +319,7 @@ func (c *Controller) UpdatePlan(ctx *gin.Context) { | |||||||
| 	updatedPlan, err := c.planRepo.GetPlanByID(uint(id)) | 	updatedPlan, err := c.planRepo.GetPlanByID(uint(id)) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		c.logger.Errorf("获取更新后的计划详情失败: %v", err) | 		c.logger.Errorf("获取更新后的计划详情失败: %v", err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取更新后计划详情时发生内部错误", "更新计划", "获取更新后计划详情失败", id) | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取更新后计划详情时发生内部错误", actionType, "获取更新后计划详情失败", id) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -323,12 +327,12 @@ func (c *Controller) UpdatePlan(ctx *gin.Context) { | |||||||
| 	resp, err := PlanToResponse(updatedPlan) | 	resp, err := PlanToResponse(updatedPlan) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		c.logger.Errorf("更新计划: 序列化响应失败: %v", err) | 		c.logger.Errorf("更新计划: 序列化响应失败: %v", err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "计划更新成功,但响应生成失败", "更新计划", "响应序列化失败", updatedPlan) | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "计划更新成功,但响应生成失败", actionType, "响应序列化失败", updatedPlan) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// 8. 发送成功响应 | 	// 8. 发送成功响应 | ||||||
| 	controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "计划更新成功", resp, "更新计划", "计划更新成功", resp) | 	controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "计划更新成功", resp, actionType, "计划更新成功", resp) | ||||||
| } | } | ||||||
|  |  | ||||||
| // DeletePlan godoc | // DeletePlan godoc | ||||||
| @@ -340,11 +344,12 @@ func (c *Controller) UpdatePlan(ctx *gin.Context) { | |||||||
| // @Success      200 {object} controller.Response "业务码为200代表删除成功" | // @Success      200 {object} controller.Response "业务码为200代表删除成功" | ||||||
| // @Router       /api/v1/plans/{id} [delete] | // @Router       /api/v1/plans/{id} [delete] | ||||||
| func (c *Controller) DeletePlan(ctx *gin.Context) { | func (c *Controller) DeletePlan(ctx *gin.Context) { | ||||||
|  | 	const actionType = "删除计划" | ||||||
| 	// 1. 从 URL 路径中获取 ID | 	// 1. 从 URL 路径中获取 ID | ||||||
| 	idStr := ctx.Param("id") | 	idStr := ctx.Param("id") | ||||||
| 	id, err := strconv.ParseUint(idStr, 10, 32) | 	id, err := strconv.ParseUint(idStr, 10, 32) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的计划ID格式", "删除计划", "计划ID格式错误", idStr) | 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的计划ID格式", actionType, "计划ID格式错误", idStr) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -352,11 +357,11 @@ func (c *Controller) DeletePlan(ctx *gin.Context) { | |||||||
| 	plan, err := c.planRepo.GetBasicPlanByID(uint(id)) | 	plan, err := c.planRepo.GetBasicPlanByID(uint(id)) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if errors.Is(err, gorm.ErrRecordNotFound) { | 		if errors.Is(err, gorm.ErrRecordNotFound) { | ||||||
| 			controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "计划不存在", "删除计划", "计划不存在", id) | 			controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "计划不存在", actionType, "计划不存在", id) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		c.logger.Errorf("启动计划时获取计划信息失败: %v", err) | 		c.logger.Errorf("启动计划时获取计划信息失败: %v", err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取计划信息时发生内部错误", "删除计划", "数据库查询失败", id) | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取计划信息时发生内部错误", actionType, "数据库查询失败", id) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -364,7 +369,7 @@ func (c *Controller) DeletePlan(ctx *gin.Context) { | |||||||
| 	if plan.Status == models.PlanStatusEnabled { | 	if plan.Status == models.PlanStatusEnabled { | ||||||
| 		if err := c.planRepo.StopPlanTransactionally(uint(id)); err != nil { | 		if err := c.planRepo.StopPlanTransactionally(uint(id)); err != nil { | ||||||
| 			c.logger.Errorf("停止计划 #%d 失败: %v", id, err) | 			c.logger.Errorf("停止计划 #%d 失败: %v", id, err) | ||||||
| 			controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "停止计划时发生内部错误: "+err.Error(), "删除计划", "停止计划失败", id) | 			controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "停止计划时发生内部错误: "+err.Error(), actionType, "停止计划失败", id) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -372,12 +377,12 @@ func (c *Controller) DeletePlan(ctx *gin.Context) { | |||||||
| 	// 4. 调用仓库层删除计划 | 	// 4. 调用仓库层删除计划 | ||||||
| 	if err := c.planRepo.DeletePlan(uint(id)); err != nil { | 	if err := c.planRepo.DeletePlan(uint(id)); err != nil { | ||||||
| 		c.logger.Errorf("删除计划: 数据库操作失败: %v", err) | 		c.logger.Errorf("删除计划: 数据库操作失败: %v", err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "删除计划时发生内部错误", "删除计划", "数据库删除失败", id) | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "删除计划时发生内部错误", actionType, "数据库删除失败", id) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// 5. 发送成功响应 | 	// 5. 发送成功响应 | ||||||
| 	controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "计划删除成功", nil, "删除计划", "计划删除成功", id) | 	controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "计划删除成功", nil, actionType, "计划删除成功", id) | ||||||
| } | } | ||||||
|  |  | ||||||
| // StartPlan godoc | // StartPlan godoc | ||||||
| @@ -389,11 +394,12 @@ func (c *Controller) DeletePlan(ctx *gin.Context) { | |||||||
| // @Success      200 {object} controller.Response "业务码为200代表成功启动计划" | // @Success      200 {object} controller.Response "业务码为200代表成功启动计划" | ||||||
| // @Router       /api/v1/plans/{id}/start [post] | // @Router       /api/v1/plans/{id}/start [post] | ||||||
| func (c *Controller) StartPlan(ctx *gin.Context) { | func (c *Controller) StartPlan(ctx *gin.Context) { | ||||||
|  | 	const actionType = "启动计划" | ||||||
| 	// 1. 从 URL 路径中获取 ID | 	// 1. 从 URL 路径中获取 ID | ||||||
| 	idStr := ctx.Param("id") | 	idStr := ctx.Param("id") | ||||||
| 	id, err := strconv.ParseUint(idStr, 10, 32) | 	id, err := strconv.ParseUint(idStr, 10, 32) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的计划ID格式", "启动计划", "计划ID格式错误", idStr) | 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的计划ID格式", actionType, "计划ID格式错误", idStr) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -401,17 +407,17 @@ func (c *Controller) StartPlan(ctx *gin.Context) { | |||||||
| 	plan, err := c.planRepo.GetBasicPlanByID(uint(id)) | 	plan, err := c.planRepo.GetBasicPlanByID(uint(id)) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if errors.Is(err, gorm.ErrRecordNotFound) { | 		if errors.Is(err, gorm.ErrRecordNotFound) { | ||||||
| 			controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "计划不存在", "启动计划", "计划不存在", id) | 			controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "计划不存在", actionType, "计划不存在", id) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		c.logger.Errorf("启动计划时获取计划信息失败: %v", err) | 		c.logger.Errorf("启动计划时获取计划信息失败: %v", err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取计划信息时发生内部错误", "启动计划", "数据库查询失败", id) | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取计划信息时发生内部错误", actionType, "数据库查询失败", id) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// 3. 检查计划当前状态 | 	// 3. 检查计划当前状态 | ||||||
| 	if plan.Status == models.PlanStatusEnabled { | 	if plan.Status == models.PlanStatusEnabled { | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "计划已处于启动状态,无需重复操作", "启动计划", "计划已启动", id) | 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "计划已处于启动状态,无需重复操作", actionType, "计划已处于启动状态", id) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -422,7 +428,7 @@ func (c *Controller) StartPlan(ctx *gin.Context) { | |||||||
| 		if plan.ExecuteCount > 0 { | 		if plan.ExecuteCount > 0 { | ||||||
| 			if err := c.planRepo.UpdateExecuteCount(plan.ID, 0); err != nil { | 			if err := c.planRepo.UpdateExecuteCount(plan.ID, 0); err != nil { | ||||||
| 				c.logger.Errorf("重置计划 #%d 执行计数失败: %v", plan.ID, err) | 				c.logger.Errorf("重置计划 #%d 执行计数失败: %v", plan.ID, err) | ||||||
| 				controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "重置计划执行计数失败", "启动计划", "重置执行计数失败", plan.ID) | 				controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "重置计划执行计数失败", actionType, "重置执行计数失败", plan.ID) | ||||||
| 				return | 				return | ||||||
| 			} | 			} | ||||||
| 			c.logger.Infof("计划 #%d 的执行计数器已重置为 0。", plan.ID) | 			c.logger.Infof("计划 #%d 的执行计数器已重置为 0。", plan.ID) | ||||||
| @@ -431,14 +437,14 @@ func (c *Controller) StartPlan(ctx *gin.Context) { | |||||||
| 		// 更新计划状态为“已启动” | 		// 更新计划状态为“已启动” | ||||||
| 		if err := c.planRepo.UpdatePlanStatus(plan.ID, models.PlanStatusEnabled); err != nil { | 		if err := c.planRepo.UpdatePlanStatus(plan.ID, models.PlanStatusEnabled); err != nil { | ||||||
| 			c.logger.Errorf("更新计划 #%d 状态失败: %v", plan.ID, err) | 			c.logger.Errorf("更新计划 #%d 状态失败: %v", plan.ID, err) | ||||||
| 			controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "更新计划状态失败", "启动计划", "更新计划状态失败", plan.ID) | 			controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "更新计划状态失败", actionType, "更新计划状态失败", plan.ID) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		c.logger.Infof("已成功更新计划 #%d 的状态为 '已启动'。", plan.ID) | 		c.logger.Infof("已成功更新计划 #%d 的状态为 '已启动'。", plan.ID) | ||||||
| 	} else { | 	} else { | ||||||
| 		// 如果计划已经处于 Enabled 状态,则无需更新 | 		// 如果计划已经处于 Enabled 状态,则无需更新 | ||||||
| 		c.logger.Infof("计划 #%d 已处于启动状态,无需重复操作。", plan.ID) | 		c.logger.Infof("计划 #%d 已处于启动状态,无需重复操作。", plan.ID) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "计划已处于启动状态,无需重复操作", "启动计划", "计划已处于启动状态", plan.ID) | 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "计划已处于启动状态,无需重复操作", actionType, "计划已处于启动状态", plan.ID) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -446,12 +452,12 @@ func (c *Controller) StartPlan(ctx *gin.Context) { | |||||||
| 	if err := c.analysisPlanTaskManager.CreateOrUpdateTrigger(plan.ID); err != nil { | 	if err := c.analysisPlanTaskManager.CreateOrUpdateTrigger(plan.ID); err != nil { | ||||||
| 		// 此处错误不回滚状态,因为状态更新已成功,但需要明确告知用户触发器创建失败 | 		// 此处错误不回滚状态,因为状态更新已成功,但需要明确告知用户触发器创建失败 | ||||||
| 		c.logger.Errorf("为计划 #%d 创建或更新触发器失败: %v", plan.ID, err) | 		c.logger.Errorf("为计划 #%d 创建或更新触发器失败: %v", plan.ID, err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "计划状态已更新,但创建执行触发器失败,请检查计划配置或稍后重试", "启动计划", "创建执行触发器失败", plan.ID) | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "计划状态已更新,但创建执行触发器失败,请检查计划配置或稍后重试", actionType, "创建执行触发器失败", plan.ID) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// 6. 发送成功响应 | 	// 6. 发送成功响应 | ||||||
| 	controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "计划已成功启动", nil, "启动计划", "计划已成功启动", id) | 	controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "计划已成功启动", nil, actionType, "计划已成功启动", id) | ||||||
| } | } | ||||||
|  |  | ||||||
| // StopPlan godoc | // StopPlan godoc | ||||||
| @@ -463,11 +469,12 @@ func (c *Controller) StartPlan(ctx *gin.Context) { | |||||||
| // @Success      200 {object} controller.Response "业务码为200代表成功停止计划" | // @Success      200 {object} controller.Response "业务码为200代表成功停止计划" | ||||||
| // @Router       /api/v1/plans/{id}/stop [post] | // @Router       /api/v1/plans/{id}/stop [post] | ||||||
| func (c *Controller) StopPlan(ctx *gin.Context) { | func (c *Controller) StopPlan(ctx *gin.Context) { | ||||||
|  | 	const actionType = "停止计划" | ||||||
| 	// 1. 从 URL 路径中获取 ID | 	// 1. 从 URL 路径中获取 ID | ||||||
| 	idStr := ctx.Param("id") | 	idStr := ctx.Param("id") | ||||||
| 	id, err := strconv.ParseUint(idStr, 10, 32) | 	id, err := strconv.ParseUint(idStr, 10, 32) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的计划ID格式", "停止计划", "计划ID格式错误", idStr) | 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的计划ID格式", actionType, "计划ID格式错误", idStr) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -475,27 +482,27 @@ func (c *Controller) StopPlan(ctx *gin.Context) { | |||||||
| 	plan, err := c.planRepo.GetBasicPlanByID(uint(id)) | 	plan, err := c.planRepo.GetBasicPlanByID(uint(id)) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if errors.Is(err, gorm.ErrRecordNotFound) { | 		if errors.Is(err, gorm.ErrRecordNotFound) { | ||||||
| 			controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "计划不存在", "停止计划", "计划不存在", id) | 			controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "计划不存在", actionType, "计划不存在", id) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		c.logger.Errorf("启动计划时获取计划信息失败: %v", err) | 		c.logger.Errorf("启动计划时获取计划信息失败: %v", err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取计划信息时发生内部错误", "停止计划", "数据库查询失败", id) | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取计划信息时发生内部错误", actionType, "数据库查询失败", id) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// 3. 检查计划当前状态 | 	// 3. 检查计划当前状态 | ||||||
| 	if plan.Status != models.PlanStatusEnabled { | 	if plan.Status != models.PlanStatusEnabled { | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "计划当前不是启用状态", "停止计划", "计划未启用", id) | 		controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "计划当前不是启用状态", actionType, "计划未启用", id) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// 4. 调用仓库层方法,该方法内部处理事务 | 	// 4. 调用仓库层方法,该方法内部处理事务 | ||||||
| 	if err := c.planRepo.StopPlanTransactionally(uint(id)); err != nil { | 	if err := c.planRepo.StopPlanTransactionally(uint(id)); err != nil { | ||||||
| 		c.logger.Errorf("停止计划 #%d 失败: %v", id, err) | 		c.logger.Errorf("停止计划 #%d 失败: %v", id, err) | ||||||
| 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "停止计划时发生内部错误: "+err.Error(), "停止计划", "停止计划失败", id) | 		controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "停止计划时发生内部错误: "+err.Error(), actionType, "停止计划失败", id) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// 5. 发送成功响应 | 	// 5. 发送成功响应 | ||||||
| 	controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "计划已成功停止", nil, "停止计划", "计划已成功停止", id) | 	controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "计划已成功停止", nil, actionType, "计划已成功停止", id) | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user