feat: 完善小组绩效与有效端统计并修复审查问题

This commit is contained in:
Yvan
2026-11-05 01:10:03 +08:00
parent ca9ce99b66
commit dc97690eb1
75 changed files with 5033 additions and 296 deletions
+61 -1
View File
@@ -1,15 +1,19 @@
package business
import (
"context"
"gorm.io/gorm"
databusiness "kra/internal/data/business"
datasystem "kra/internal/data/system"
datatask "kra/internal/data/task"
"kra/internal/modules/surface"
"kra/pkg/database/migration"
"kra/pkg/module"
"sort"
)
func Definition() module.Definition {
performanceMenu := module.Menu{Name: "sw_BusinessPerformance", Path: "BusinessPerformance", ParentName: "sw_DataAnalysis", Component: "view/sw/BusinessPerformance.vue", Title: "商务绩效统计", Icon: "DataLine", Sort: 7}
settingsMenu := module.Menu{Name: "sw_OtherSettings", Path: "OtherSettings", Component: "view/sw/OtherSettings.vue", Title: "其他设置", Icon: databusiness.MenuIcon("sw_OtherSettings"), Sort: 5}
migrations := append(databusiness.Migrations(), migration.Step{ID: "202611040016_business_other_settings_surface", Migrate: func(db *gorm.DB) error {
// First-install menus are created by the normal seed flow.
@@ -51,8 +55,59 @@ func Definition() module.Definition {
}, 888)
})
}})
return module.Definition{Name: "business", Migrations: migrations, Surface: module.Surface{
managementAPIs := []module.API{}
for _, api := range surface.APIsForPrefix("/sw/", 0) {
switch api.Path {
case "/sw/groups", "/sw/business/profile", "/sw/business/management", "/sw/performance", "/sw/performance/details", "/sw/performance/export", "/sw/goals", "/sw/goals/mine", "/sw/workbench/overview":
managementAPIs = append(managementAPIs, api)
}
}
tasks := []module.TimedTask{{Name: "ChannelEffectiveness", Description: "增量刷新渠道有效端", Spec: "*/1 * * * *", MethodName: "channelEffectivenessTask", Enabled: true}, {Name: "ChannelEffectivenessRecheck", Description: "每日核对有效端历史流水", Spec: "0 3 * * *", MethodName: "channelEffectivenessFullTask", Enabled: true}}
migrations = append(migrations, migration.Step{ID: "202611040019_business_performance_surface", Migrate: func(db *gorm.DB) error {
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
}
return db.Transaction(func(tx *gorm.DB) error {
if err := datasystem.EnsureAdminSurface(tx, module.Surface{Menus: []module.Menu{performanceMenu}, APIs: managementAPIs}, 888); err != nil {
return err
}
var roles []uint
if err := tx.Table("sys_authority_menus a").Joins("JOIN sys_base_menus m ON m.id=a.sys_base_menu_id").Where("m.name=? AND m.deleted_at IS NULL", "sw_BusinessList").Distinct().Pluck("a.sys_authority_authority_id", &roles).Error; err != nil {
return err
}
var menuIDs []uint
if err := tx.Table("sys_base_menus").Where("name IN ? AND deleted_at IS NULL", []string{"sw_DataAnalysis", performanceMenu.Name}).Pluck("id", &menuIDs).Error; err != nil {
return err
}
for _, role := range roles {
for _, id := range menuIDs {
var exists int64
if err := tx.Table("sys_authority_menus").Where("sys_authority_authority_id=? AND sys_base_menu_id=?", role, id).Count(&exists).Error; err != nil {
return err
}
if exists == 0 {
if err := tx.Table("sys_authority_menus").Create(map[string]any{"sys_authority_authority_id": role, "sys_base_menu_id": id}).Error; err != nil {
return err
}
}
}
}
if err := datasystem.GrantMenuAPIs(tx, "sw_BusinessList", managementAPIs); err != nil {
return err
}
return datatask.SeedDefaults(context.Background(), tx, tasks)
})
}})
definition := module.Definition{Name: "business", Migrations: migrations, TimedTasks: tasks, Surface: module.Surface{
Menus: []module.Menu{
performanceMenu,
settingsMenu,
{Name: "sw_RankingAnalysis", Path: "RankingAnalysis", ParentName: "sw_DataAnalysis", Component: "view/sw/RankingAnalysis.vue", Title: "排行榜", Icon: databusiness.MenuIcon("sw_RankingAnalysis"), Sort: 6},
{Name: "sw_ServerAnalysis", Path: "ServerAnalysis", ParentName: "sw_DataAnalysis", Component: "view/sw/ServerAnalysis.vue", Title: "区服分析", Icon: databusiness.MenuIcon("sw_ServerAnalysis"), Sort: 5},
@@ -71,4 +126,9 @@ func Definition() module.Definition {
},
APIs: surface.APIsForPrefix("/sw/", 0),
}}
// Parent menus must exist before their children in first-install seeding.
sort.SliceStable(definition.Surface.Menus, func(i, j int) bool {
return definition.Surface.Menus[i].ParentName == "" && definition.Surface.Menus[j].ParentName != ""
})
return definition
}
+2 -1
View File
@@ -7,6 +7,7 @@ import (
"github.com/glebarez/sqlite"
"gorm.io/gorm"
datasystem "kra/internal/data/system"
datatask "kra/internal/data/task"
)
func TestOtherSettingsUpgradeAddsStandaloneMenuForSuperAdmin(t *testing.T) {
@@ -16,7 +17,7 @@ func TestOtherSettingsUpgradeAddsStandaloneMenuForSuperAdmin(t *testing.T) {
}
pool, _ := db.DB()
t.Cleanup(func() { _ = pool.Close() })
for _, step := range datasystem.Migrations() {
for _, step := range append(datasystem.Migrations(), datatask.Migrations()...) {
if err := step.Migrate(db); err != nil {
t.Fatal(err)
}
+6 -6
View File
@@ -25,18 +25,18 @@ func TestCatalogContainsBuiltInModulesInDependencyOrder(t *testing.T) {
t.Fatalf("definition[%d] = %q, want %q", index, got, name)
}
}
if got := catalog.MigrationSteps(); len(got) != 30 {
t.Fatalf("module migrations = %d, want 30", len(got))
if got := catalog.MigrationSteps(); len(got) != 33 {
t.Fatalf("module migrations = %d, want 33", len(got))
}
var menus, apis int
for _, definition := range catalog.Definitions {
menus += len(definition.Surface.Menus)
apis += len(definition.Surface.APIs)
}
if menus != 19 || apis != 71 {
t.Fatalf("admin surface = %d menus/%d APIs, want 19/71", menus, apis)
if menus != 20 || apis != 82 {
t.Fatalf("admin surface = %d menus/%d APIs, want 20/82", menus, apis)
}
if got := catalog.DefaultTimedTasks(); len(got) != 2 {
t.Fatalf("default timed tasks = %d, want 2", len(got))
if got := catalog.DefaultTimedTasks(); len(got) != 4 {
t.Fatalf("default timed tasks = %d, want 4", len(got))
}
}