添加复合案例服务日志记录,改进事务处理和错误捕获逻辑,完善处理器与服务初始化

This commit is contained in:
longpeng 2025-06-24 12:14:06 +08:00
parent e246f2fc06
commit 8f073eb9d1
3 changed files with 115 additions and 5 deletions

View File

@ -13,9 +13,15 @@ type CompositeCaseHandler struct {
service *services.CompositeCaseService service *services.CompositeCaseService
} }
// NewCompositeCaseHandler 创建 CompositeCaseHandler 实例
func NewCompositeCaseHandler() *CompositeCaseHandler {
return &CompositeCaseHandler{
service: &services.CompositeCaseService{},
}
}
// CreateCompositeCase POST /api/composite-cases // CreateCompositeCase POST /api/composite-cases
func (h *CompositeCaseHandler) CreateCompositeCase(c *gin.Context) { func (h *CompositeCaseHandler) CreateCompositeCase(c *gin.Context) {
zap.L().Info("CreateCompositeCase")
var req models.CreateCompositeCaseRequest var req models.CreateCompositeCaseRequest
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{ c.JSON(http.StatusBadRequest, gin.H{
@ -27,6 +33,7 @@ func (h *CompositeCaseHandler) CreateCompositeCase(c *gin.Context) {
zap.L().Info("req", zap.Any("req", req)) zap.L().Info("req", zap.Any("req", req))
compositeCase, err := h.service.CreateCompositeCase(&req) compositeCase, err := h.service.CreateCompositeCase(&req)
zap.L().Info("compositeCase", zap.Any("compositeCase", compositeCase))
if err != nil { if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{ c.JSON(http.StatusInternalServerError, gin.H{
"error": "创建复合案例失败", "error": "创建复合案例失败",
@ -35,10 +42,9 @@ func (h *CompositeCaseHandler) CreateCompositeCase(c *gin.Context) {
return return
} }
zap.L().Info("compositeCase", zap.Any("compositeCase", compositeCase))
c.JSON(http.StatusCreated, gin.H{ c.JSON(http.StatusCreated, gin.H{
"message": "创建复合案例成功", "message": "创建复合案例成功",
"data": compositeCase, "data": "compositeCase",
}) })
} }

View File

@ -91,7 +91,8 @@ func Init() *gin.Engine {
func SetupCompositeCaseRoutes(group *gin.RouterGroup) { func SetupCompositeCaseRoutes(group *gin.RouterGroup) {
// 初始化服务和处理器 // 初始化服务和处理器
var handler *handlers.CompositeCaseHandler //var handler *handlers.CompositeCaseHandler
handler := *handlers.NewCompositeCaseHandler()
api := group.Group("/api") api := group.Group("/api")
{ {

View File

@ -14,14 +14,21 @@ type CompositeCaseService struct {
// CreateCompositeCase 创建复合案例 // CreateCompositeCase 创建复合案例
func (s *CompositeCaseService) CreateCompositeCase(req *models.CreateCompositeCaseRequest) (*models.CompositeCase, error) { func (s *CompositeCaseService) CreateCompositeCase(req *models.CreateCompositeCaseRequest) (*models.CompositeCase, error) {
zap.L().Info("CreateCompositeCase") zap.L().Info("开始创建复合案例",
zap.String("name", req.Name),
zap.String("description", req.Description),
zap.String("status", req.Status),
zap.Int("steps_count", len(req.Steps)))
// 开启事务 // 开启事务
tx := dao.DB.Begin() tx := dao.DB.Begin()
if tx.Error != nil { if tx.Error != nil {
zap.L().Error("创建复合案例失败 - 事务开启失败", zap.Error(tx.Error))
return nil, tx.Error return nil, tx.Error
} }
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
zap.L().Error("创建复合案例失败 - 发生panic", zap.Any("panic", r))
tx.Rollback() tx.Rollback()
} }
}() }()
@ -35,15 +42,22 @@ func (s *CompositeCaseService) CreateCompositeCase(req *models.CreateCompositeCa
if compositeCase.Status == "" { if compositeCase.Status == "" {
compositeCase.Status = "active" compositeCase.Status = "active"
zap.L().Debug("设置默认状态", zap.String("status", "active"))
} }
if err := tx.Create(compositeCase).Error; err != nil { if err := tx.Create(compositeCase).Error; err != nil {
zap.L().Error("创建复合案例失败 - 数据库创建失败", zap.Error(err))
tx.Rollback() tx.Rollback()
return nil, fmt.Errorf("创建复合案例失败: %w", err) return nil, fmt.Errorf("创建复合案例失败: %w", err)
} }
zap.L().Info("复合案例创建成功",
zap.Uint("id", compositeCase.ID),
zap.String("name", compositeCase.Name))
// 创建步骤 // 创建步骤
if len(req.Steps) > 0 { if len(req.Steps) > 0 {
zap.L().Info("开始创建步骤", zap.Int("steps_count", len(req.Steps)))
var steps []models.CompositeCaseStep var steps []models.CompositeCaseStep
for _, stepReq := range req.Steps { for _, stepReq := range req.Steps {
step := models.CompositeCaseStep{ step := models.CompositeCaseStep{
@ -59,19 +73,30 @@ func (s *CompositeCaseService) CreateCompositeCase(req *models.CreateCompositeCa
} }
if err := tx.Create(&steps).Error; err != nil { if err := tx.Create(&steps).Error; err != nil {
zap.L().Error("创建复合案例步骤失败",
zap.Uint("composite_case_id", compositeCase.ID),
zap.Error(err))
tx.Rollback() tx.Rollback()
return nil, fmt.Errorf("创建复合案例步骤失败: %w", err) return nil, fmt.Errorf("创建复合案例步骤失败: %w", err)
} }
zap.L().Info("复合案例步骤创建成功",
zap.Uint("composite_case_id", compositeCase.ID),
zap.Int("created_steps_count", len(steps)))
compositeCase.Steps = steps compositeCase.Steps = steps
} }
tx.Commit() tx.Commit()
zap.L().Info("复合案例创建完成",
zap.Uint("id", compositeCase.ID),
zap.String("name", compositeCase.Name))
return compositeCase, nil return compositeCase, nil
} }
// GetCompositeCaseByID 根据ID获取复合案例 // GetCompositeCaseByID 根据ID获取复合案例
func (s *CompositeCaseService) GetCompositeCaseByID(id uint) (*models.CompositeCase, error) { func (s *CompositeCaseService) GetCompositeCaseByID(id uint) (*models.CompositeCase, error) {
zap.L().Debug("开始查询复合案例", zap.Uint("id", id))
var compositeCase models.CompositeCase var compositeCase models.CompositeCase
err := dao.DB.Preload("Steps", func(db *gorm.DB) *gorm.DB { err := dao.DB.Preload("Steps", func(db *gorm.DB) *gorm.DB {
@ -80,23 +105,37 @@ func (s *CompositeCaseService) GetCompositeCaseByID(id uint) (*models.CompositeC
if err != nil { if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
zap.L().Warn("复合案例不存在", zap.Uint("id", id))
return nil, fmt.Errorf("复合案例不存在") return nil, fmt.Errorf("复合案例不存在")
} }
zap.L().Error("获取复合案例失败", zap.Uint("id", id), zap.Error(err))
return nil, fmt.Errorf("获取复合案例失败: %w", err) return nil, fmt.Errorf("获取复合案例失败: %w", err)
} }
zap.L().Debug("复合案例查询成功",
zap.Uint("id", compositeCase.ID),
zap.String("name", compositeCase.Name),
zap.Int("steps_count", len(compositeCase.Steps)))
return &compositeCase, nil return &compositeCase, nil
} }
// UpdateCompositeCase 更新复合案例 // UpdateCompositeCase 更新复合案例
func (s *CompositeCaseService) UpdateCompositeCase(id uint, req *models.UpdateCompositeCaseRequest) (*models.CompositeCase, error) { func (s *CompositeCaseService) UpdateCompositeCase(id uint, req *models.UpdateCompositeCaseRequest) (*models.CompositeCase, error) {
zap.L().Info("开始更新复合案例", zap.Uint("id", id))
// 开启事务 // 开启事务
tx := dao.DB.Begin() tx := dao.DB.Begin()
if tx.Error != nil { if tx.Error != nil {
zap.L().Error("更新复合案例失败 - 事务开启失败",
zap.Uint("id", id),
zap.Error(tx.Error))
return nil, tx.Error return nil, tx.Error
} }
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
zap.L().Error("更新复合案例失败 - 发生panic",
zap.Uint("id", id),
zap.Any("panic", r))
tx.Rollback() tx.Rollback()
} }
}() }()
@ -106,8 +145,12 @@ func (s *CompositeCaseService) UpdateCompositeCase(id uint, req *models.UpdateCo
if err := tx.First(&compositeCase, id).Error; err != nil { if err := tx.First(&compositeCase, id).Error; err != nil {
tx.Rollback() tx.Rollback()
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
zap.L().Warn("更新复合案例失败 - 复合案例不存在", zap.Uint("id", id))
return nil, fmt.Errorf("复合案例不存在") return nil, fmt.Errorf("复合案例不存在")
} }
zap.L().Error("更新复合案例失败 - 查询失败",
zap.Uint("id", id),
zap.Error(err))
return nil, fmt.Errorf("查询复合案例失败: %w", err) return nil, fmt.Errorf("查询复合案例失败: %w", err)
} }
@ -124,7 +167,13 @@ func (s *CompositeCaseService) UpdateCompositeCase(id uint, req *models.UpdateCo
} }
if len(updates) > 0 { if len(updates) > 0 {
zap.L().Info("更新复合案例基本信息",
zap.Uint("id", id),
zap.Any("updates", updates))
if err := tx.Model(&compositeCase).Updates(updates).Error; err != nil { if err := tx.Model(&compositeCase).Updates(updates).Error; err != nil {
zap.L().Error("更新复合案例基本信息失败",
zap.Uint("id", id),
zap.Error(err))
tx.Rollback() tx.Rollback()
return nil, fmt.Errorf("更新复合案例失败: %w", err) return nil, fmt.Errorf("更新复合案例失败: %w", err)
} }
@ -132,8 +181,15 @@ func (s *CompositeCaseService) UpdateCompositeCase(id uint, req *models.UpdateCo
// 更新步骤 // 更新步骤
if req.Steps != nil { if req.Steps != nil {
zap.L().Info("开始更新复合案例步骤",
zap.Uint("id", id),
zap.Int("new_steps_count", len(req.Steps)))
// 删除现有步骤 // 删除现有步骤
if err := tx.Where("composite_case_id = ?", id).Delete(&models.CompositeCaseStep{}).Error; err != nil { if err := tx.Where("composite_case_id = ?", id).Delete(&models.CompositeCaseStep{}).Error; err != nil {
zap.L().Error("删除现有步骤失败",
zap.Uint("id", id),
zap.Error(err))
tx.Rollback() tx.Rollback()
return nil, fmt.Errorf("删除现有步骤失败: %w", err) return nil, fmt.Errorf("删除现有步骤失败: %w", err)
} }
@ -155,13 +211,20 @@ func (s *CompositeCaseService) UpdateCompositeCase(id uint, req *models.UpdateCo
} }
if err := tx.Create(&steps).Error; err != nil { if err := tx.Create(&steps).Error; err != nil {
zap.L().Error("创建新步骤失败",
zap.Uint("id", id),
zap.Error(err))
tx.Rollback() tx.Rollback()
return nil, fmt.Errorf("创建新步骤失败: %w", err) return nil, fmt.Errorf("创建新步骤失败: %w", err)
} }
zap.L().Info("新步骤创建成功",
zap.Uint("id", id),
zap.Int("created_steps_count", len(steps)))
} }
} }
tx.Commit() tx.Commit()
zap.L().Info("复合案例更新完成", zap.Uint("id", id))
// 重新查询并返回更新后的数据 // 重新查询并返回更新后的数据
return s.GetCompositeCaseByID(id) return s.GetCompositeCaseByID(id)
@ -169,13 +232,21 @@ func (s *CompositeCaseService) UpdateCompositeCase(id uint, req *models.UpdateCo
// DeleteCompositeCase 删除复合案例 // DeleteCompositeCase 删除复合案例
func (s *CompositeCaseService) DeleteCompositeCase(id uint) error { func (s *CompositeCaseService) DeleteCompositeCase(id uint) error {
zap.L().Info("开始删除复合案例", zap.Uint("id", id))
// 开启事务 // 开启事务
tx := dao.DB.Begin() tx := dao.DB.Begin()
if tx.Error != nil { if tx.Error != nil {
zap.L().Error("删除复合案例失败 - 事务开启失败",
zap.Uint("id", id),
zap.Error(tx.Error))
return tx.Error return tx.Error
} }
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
zap.L().Error("删除复合案例失败 - 发生panic",
zap.Uint("id", id),
zap.Any("panic", r))
tx.Rollback() tx.Rollback()
} }
}() }()
@ -185,29 +256,53 @@ func (s *CompositeCaseService) DeleteCompositeCase(id uint) error {
if err := tx.First(&compositeCase, id).Error; err != nil { if err := tx.First(&compositeCase, id).Error; err != nil {
tx.Rollback() tx.Rollback()
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
zap.L().Warn("删除复合案例失败 - 复合案例不存在", zap.Uint("id", id))
return fmt.Errorf("复合案例不存在") return fmt.Errorf("复合案例不存在")
} }
zap.L().Error("删除复合案例失败 - 查询失败",
zap.Uint("id", id),
zap.Error(err))
return fmt.Errorf("查询复合案例失败: %w", err) return fmt.Errorf("查询复合案例失败: %w", err)
} }
zap.L().Info("找到复合案例,开始删除",
zap.Uint("id", id),
zap.String("name", compositeCase.Name))
// 删除关联的步骤 // 删除关联的步骤
if err := tx.Where("composite_case_id = ?", id).Delete(&models.CompositeCaseStep{}).Error; err != nil { if err := tx.Where("composite_case_id = ?", id).Delete(&models.CompositeCaseStep{}).Error; err != nil {
zap.L().Error("删除复合案例步骤失败",
zap.Uint("id", id),
zap.Error(err))
tx.Rollback() tx.Rollback()
return fmt.Errorf("删除复合案例步骤失败: %w", err) return fmt.Errorf("删除复合案例步骤失败: %w", err)
} }
zap.L().Debug("复合案例步骤删除成功", zap.Uint("id", id))
// 删除复合案例 // 删除复合案例
if err := tx.Delete(&compositeCase).Error; err != nil { if err := tx.Delete(&compositeCase).Error; err != nil {
zap.L().Error("删除复合案例失败",
zap.Uint("id", id),
zap.Error(err))
tx.Rollback() tx.Rollback()
return fmt.Errorf("删除复合案例失败: %w", err) return fmt.Errorf("删除复合案例失败: %w", err)
} }
tx.Commit() tx.Commit()
zap.L().Info("复合案例删除完成",
zap.Uint("id", id),
zap.String("name", compositeCase.Name))
return nil return nil
} }
// ListCompositeCases 获取复合案例列表 // ListCompositeCases 获取复合案例列表
func (s *CompositeCaseService) ListCompositeCases(page, pageSize int, status string) ([]models.CompositeCase, int64, error) { func (s *CompositeCaseService) ListCompositeCases(page, pageSize int, status string) ([]models.CompositeCase, int64, error) {
zap.L().Info("开始查询复合案例列表",
zap.Int("page", page),
zap.Int("page_size", pageSize),
zap.String("status", status))
var compositeCases []models.CompositeCase var compositeCases []models.CompositeCase
var total int64 var total int64
@ -215,13 +310,17 @@ func (s *CompositeCaseService) ListCompositeCases(page, pageSize int, status str
if status != "" { if status != "" {
query = query.Where("status = ?", status) query = query.Where("status = ?", status)
zap.L().Debug("添加状态过滤条件", zap.String("status", status))
} }
// 获取总数 // 获取总数
if err := query.Count(&total).Error; err != nil { if err := query.Count(&total).Error; err != nil {
zap.L().Error("获取复合案例总数失败", zap.Error(err))
return nil, 0, fmt.Errorf("获取复合案例总数失败: %w", err) return nil, 0, fmt.Errorf("获取复合案例总数失败: %w", err)
} }
zap.L().Debug("查询到复合案例总数", zap.Int64("total", total))
// 分页查询 // 分页查询
offset := (page - 1) * pageSize offset := (page - 1) * pageSize
err := query.Preload("Steps", func(db *gorm.DB) *gorm.DB { err := query.Preload("Steps", func(db *gorm.DB) *gorm.DB {
@ -229,8 +328,12 @@ func (s *CompositeCaseService) ListCompositeCases(page, pageSize int, status str
}).Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&compositeCases).Error }).Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&compositeCases).Error
if err != nil { if err != nil {
zap.L().Error("获取复合案例列表失败", zap.Error(err))
return nil, 0, fmt.Errorf("获取复合案例列表失败: %w", err) return nil, 0, fmt.Errorf("获取复合案例列表失败: %w", err)
} }
zap.L().Info("复合案例列表查询成功",
zap.Int("returned_count", len(compositeCases)),
zap.Int64("total_count", total))
return compositeCases, total, nil return compositeCases, total, nil
} }