package business import ( "context" "gorm.io/gorm" datasystem "kra/internal/data/system" datatask "kra/internal/data/task" "kra/internal/modules/surface" "kra/pkg/module" ) var alertExemptionMenu = module.Menu{Name: "sw_ExemptChannels", Path: "ExemptChannels", ParentName: "sw_AlertCenter", Component: "view/sw/ExemptChannels.vue", Title: "免预警渠道", Icon: "CircleCheck", Sort: 3} var alertDetectionTask = module.TimedTask{Name: "AlertTrigger", Description: "每日检测预警并清理流失渠道豁免", Spec: "CRON_TZ=Asia/Shanghai 0 0 * * *", MethodName: "alertTriggerTask", Enabled: true} func migrateAlertSurface(db *gorm.DB) error { if db.Migrator().HasTable("sys_timed_tasks") { var count int64 q := db.Table("sys_timed_tasks").Where("method_name=? AND deleted_at IS NULL", alertDetectionTask.MethodName) if err := q.Count(&count).Error; err != nil { return err } if count == 0 { if err := datatask.SeedDefaults(context.Background(), db, []module.TimedTask{alertDetectionTask}); err != nil { return err } } else { // 旧检测任务调整到上海零点;保留管理员主动停用的状态。 if err := db.Table("sys_timed_tasks").Where("method_name=? AND deleted_at IS NULL", alertDetectionTask.MethodName).Updates(map[string]any{"spec": alertDetectionTask.Spec, "with_seconds": false}).Error; err != nil { return err } } } if !db.Migrator().HasTable("sys_authorities") { return nil } var count int64 if err := db.Table("sys_authorities").Where("authority_id=888 AND deleted_at IS NULL").Count(&count).Error; err != nil { return err } if count == 0 { return nil } apis := []module.API{} for _, api := range surface.APIsForPrefix("/sw/", 0) { switch api.Path { case "/sw/alertRecord/platforms", "/sw/alertRecord/ignore", "/sw/alertRule/gap", "/sw/alertExemption/list", "/sw/alertExemption/candidates", "/sw/alertExemption/add", "/sw/alertExemption/remove/:id": apis = append(apis, api) } } return db.Transaction(func(tx *gorm.DB) error { if err := datasystem.EnsureAdminSurface(tx, module.Surface{Menus: []module.Menu{alertExemptionMenu}, APIs: apis}, 888); err != nil { return err } if err := datasystem.GrantMenuAPIs(tx, "sw_AlertList", apis); err != nil { return err } if err := datasystem.GrantMenuAPIs(tx, "sw_AlertRules", apis); err != nil { return err } var menuID uint if err := tx.Table("sys_base_menus").Select("id").Where("name=? AND deleted_at IS NULL", alertExemptionMenu.Name).Take(&menuID).Error; err != nil { return err } var roles []uint if err := tx.Table("sys_users").Where("level=1 AND deleted_at IS NULL").Distinct().Pluck("authority_id", &roles).Error; err != nil { return err } for _, role := range roles { if err := tx.Exec("INSERT INTO sys_authority_menus(sys_authority_authority_id,sys_base_menu_id) SELECT ?,? WHERE NOT EXISTS (SELECT 1 FROM sys_authority_menus WHERE sys_authority_authority_id=? AND sys_base_menu_id=?)", role, menuID, role, menuID).Error; err != nil { return err } } return datasystem.GrantMenuAPIs(tx, alertExemptionMenu.Name, apis) }) }