feat: automate business upgrades and sync reviewed frontend
This commit is contained in:
@@ -204,26 +204,11 @@ func (r *accountRepo) Update(ctx context.Context, a *business.Account) error {
|
||||
}
|
||||
|
||||
func (r *accountRepo) AuthorityForLevel(ctx context.Context, level int) (uint, error) {
|
||||
// 原角色 ID 仅用于查迁移映射,不作为 Kra 角色 ID 使用。
|
||||
legacy := map[int]string{1: "2083497078545207297", 2: "2087435436573081601", 3: "2087361690139152385"}
|
||||
oldID, ok := legacy[level]
|
||||
if !ok {
|
||||
if level < 1 || level > 3 {
|
||||
return 0, business.ErrBusinessRole
|
||||
}
|
||||
db := r.data.DB().WithContext(ctx)
|
||||
var id uint
|
||||
if db.Migrator().HasTable("sw_kra_id_map") {
|
||||
if err := db.Table("sw_kra_id_map m").Select("m.new_id").Joins("JOIN sys_authorities a ON a.authority_id=m.new_id AND a.deleted_at IS NULL").Where("m.entity = ? AND m.old_id = ?", "role", oldID).Scan(&id).Error; err != nil {
|
||||
return 0, business.ErrStorage
|
||||
}
|
||||
if id != 0 && id != 888 {
|
||||
return id, nil
|
||||
}
|
||||
}
|
||||
// 新安装可使用对应中文角色;匹配不唯一时停止创建,避免错授权限。
|
||||
names := map[int]string{1: "一级商务", 2: "二级商务", 3: "三级商务"}
|
||||
var ids []uint
|
||||
if err := db.Table("sys_authorities").Where("authority_name = ? AND deleted_at IS NULL AND authority_id <> ?", names[level], 888).Pluck("authority_id", &ids).Error; err != nil {
|
||||
if err := r.data.DB().WithContext(ctx).Table("sys_authorities").Where("business_level=? AND deleted_at IS NULL AND authority_id<>888", level).Pluck("authority_id", &ids).Error; err != nil {
|
||||
return 0, business.ErrStorage
|
||||
}
|
||||
if len(ids) != 1 {
|
||||
|
||||
@@ -15,10 +15,10 @@ func prepareAccounts(t *testing.T) *gorm.DB {
|
||||
}
|
||||
for _, sql := range []string{
|
||||
"CREATE TABLE sys_user_authority (sys_user_id INTEGER,sys_authority_authority_id INTEGER)",
|
||||
"CREATE TABLE sys_authorities (authority_id INTEGER,authority_name TEXT,deleted_at DATETIME)",
|
||||
"CREATE TABLE sys_authorities (authority_id INTEGER,authority_name TEXT,deleted_at DATETIME,business_level INTEGER UNIQUE)",
|
||||
"CREATE TABLE sw_kra_id_map (entity TEXT,old_id TEXT,new_id INTEGER)",
|
||||
"CREATE TABLE tab_promote (id INTEGER,source_db TEXT,busier_id INTEGER,promote_level INTEGER,status INTEGER)",
|
||||
"INSERT INTO sys_authorities VALUES (901,'一级商务',NULL),(902,'已改名二级角色',NULL),(903,'三级商务',NULL)",
|
||||
"INSERT INTO sys_authorities VALUES (901,'一级商务',NULL,1),(902,'已改名二级角色',NULL,2),(903,'三级商务',NULL,3)",
|
||||
"INSERT INTO sw_kra_id_map VALUES ('role','2087435436573081601',902)",
|
||||
} {
|
||||
if err := db.Exec(sql).Error; err != nil {
|
||||
@@ -32,6 +32,9 @@ func TestAccountCreateIsAtomicAndPreferencesDefaultOn(t *testing.T) {
|
||||
db := prepareAccounts(t)
|
||||
r := NewAccountRepo(testData{db})
|
||||
ctx := context.Background()
|
||||
if err := db.Exec("DROP TABLE sw_kra_id_map").Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
role, err := r.AuthorityForLevel(ctx, 2)
|
||||
if err != nil || role != 902 {
|
||||
t.Fatalf("角色映射不正确: %d %v", role, err)
|
||||
|
||||
@@ -394,13 +394,11 @@ func fillLedgerNames(db *gorm.DB, scope business.LedgerScope, filter business.Le
|
||||
SourceDB string `gorm:"column:source_db"`
|
||||
PlatformBusierID uint64
|
||||
PlatformBusierAccount, Username string
|
||||
UserID uint
|
||||
IDPath string `gorm:"column:id_path"`
|
||||
}
|
||||
names := map[business.PlatformKey]bindName{}
|
||||
for start := 0; start < len(pairs); start += 300 {
|
||||
var rows []bindName
|
||||
q := channelBindingQuery(db, scope.Viewer, business.ChannelFilter{}).Select("b.source_db,b.platform_busier_id,b.platform_busier_account,b.user_id,COALESCE(NULLIF(u.nick_name,''),u.username) AS username,u.id_path").Where("(b.source_db,b.platform_busier_id) IN ?", portraitBindingPairs(pairs[start:min(start+300, len(pairs))])).Order("b.user_id")
|
||||
q := channelBindingQuery(db, scope.Viewer, business.ChannelFilter{}).Select("b.source_db,b.platform_busier_id,b.platform_busier_account,u.username").Where("(b.source_db,b.platform_busier_id) IN ?", portraitBindingPairs(pairs[start:min(start+300, len(pairs))])).Order("b.user_id")
|
||||
if err := q.Scan(&rows).Error; err != nil {
|
||||
return business.ErrStorage
|
||||
}
|
||||
@@ -411,31 +409,6 @@ func fillLedgerNames(db *gorm.DB, scope business.LedgerScope, filter business.Le
|
||||
}
|
||||
}
|
||||
}
|
||||
ancestorIDs := map[uint]bool{}
|
||||
paths := map[business.PlatformKey][]uint{}
|
||||
for key, binding := range names {
|
||||
for _, part := range strings.Split(binding.IDPath, ",") {
|
||||
id, err := strconv.ParseUint(strings.TrimSpace(part), 10, strconv.IntSize)
|
||||
if err == nil && id > 0 && uint(id) != binding.UserID {
|
||||
paths[key] = append(paths[key], uint(id))
|
||||
ancestorIDs[uint(id)] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
ids := make([]uint, 0, len(ancestorIDs))
|
||||
for id := range ancestorIDs {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
ancestors := map[uint]string{}
|
||||
for start := 0; start < len(ids); start += 300 {
|
||||
var rows []accountPO
|
||||
if err := db.Select("id,COALESCE(NULLIF(nick_name,''),username) AS username").Where("id IN ? AND level > 0", ids[start:min(start+300, len(ids))]).Find(&rows).Error; err != nil {
|
||||
return business.ErrStorage
|
||||
}
|
||||
for _, row := range rows {
|
||||
ancestors[row.ID] = row.Username
|
||||
}
|
||||
}
|
||||
for _, target := range targets {
|
||||
n := target.Names
|
||||
if n.PromoteID == nil || *n.PromoteID < 0 {
|
||||
@@ -448,14 +421,6 @@ func fillLedgerNames(db *gorm.DB, scope business.LedgerScope, filter business.Le
|
||||
if binding, ok := names[business.PlatformKey{SourceDB: c.SourceDB, BusierID: c.BusierID}]; ok {
|
||||
n.BindingAccount = binding.PlatformBusierAccount
|
||||
n.BindingUserName = binding.Username
|
||||
for _, id := range paths[business.PlatformKey{SourceDB: c.SourceDB, BusierID: c.BusierID}] {
|
||||
if name := strings.TrimSpace(ancestors[id]); name != "" {
|
||||
n.BusinessPath = append(n.BusinessPath, name)
|
||||
}
|
||||
}
|
||||
if name := strings.TrimSpace(binding.Username); name != "" {
|
||||
n.BusinessPath = append(n.BusinessPath, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ func TestRegistrationScopePuidAndUnboundedPlayerPay(t *testing.T) {
|
||||
first = row
|
||||
}
|
||||
}
|
||||
if first == nil || first.TotalPayAmount == nil || portraitTestMoney(*first.TotalPayAmount) != "710.10" || first.FirstGameName != "历史游戏名" || first.DisplayBusiness() != "parent→branch→leaf" {
|
||||
if first == nil || first.TotalPayAmount == nil || portraitTestMoney(*first.TotalPayAmount) != "710.10" || first.FirstGameName != "历史游戏名" || first.DisplayBusiness() != "lx-business(leaf)" {
|
||||
t.Fatalf("累计充值不能受本次时间/渠道限制,且需保留游戏快照: %+v", first)
|
||||
}
|
||||
filter.SortField = "totalPayAmount"
|
||||
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"strings"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"kra/internal/data/swmigration"
|
||||
datasystem "kra/internal/data/system"
|
||||
"kra/pkg/database/migration"
|
||||
)
|
||||
|
||||
@@ -36,6 +38,9 @@ func CheckPrerequisites(db *gorm.DB) error {
|
||||
}
|
||||
|
||||
func CheckSchema(db *gorm.DB) error {
|
||||
if err := swmigration.CheckSchema(db); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := CheckPrerequisites(db); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -50,6 +55,9 @@ func CheckSchema(db *gorm.DB) error {
|
||||
if db.Dialector.Name() != "mysql" {
|
||||
return nil
|
||||
}
|
||||
if err := datasystem.CheckBusinessRoles(db); err != nil {
|
||||
return err
|
||||
}
|
||||
indexes := append([]businessQueryIndex{}, businessQueryIndexes...)
|
||||
var idType string
|
||||
if err := db.Raw("SELECT data_type FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='tab_promote' AND column_name='id'").Scan(&idType).Error; err != nil {
|
||||
|
||||
@@ -2,11 +2,12 @@ package business
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
"kra/internal/data/swmigration"
|
||||
"kra/pkg/database/migration"
|
||||
)
|
||||
|
||||
func Migrations() []migration.Step {
|
||||
return []migration.Step{{ID: "202611060023_business_binding_status_index", Migrate: migrateBindingStatusIndex}, {ID: "202611060022_business_promote_id_capacity", Migrate: migratePromoteIDCapacity}, {ID: "202611050020_business_alert_v2", Migrate: migrateAlertV2}, {ID: "202611040017_business_groups_goals_effectiveness", Migrate: migrateBusinessManagement}, {ID: "202611040018_business_effectiveness_query_index", Migrate: migrateEffectivenessQueryIndex}, {ID: "202611040015_business_approved_game_index", Migrate: migrateApprovedGameIndexes}, {ID: "202611040014_business_report_build_indexes", Migrate: migrateReportBuildQueryIndexes}, {ID: "202611040013_business_query_indexes", Migrate: migrateBusinessQueryIndexes}, {ID: "202611040012_business_server_report_index", Migrate: migrateServerReportIndex}, {ID: "202611040011_business_registration_index", Migrate: migrateRegistrationIndex}, {ID: "202611040010_business_alert_trigger_locks", Migrate: func(db *gorm.DB) error { return migration.CreateMissingTables(db, &alertTriggerLockPO{}) }}, {ID: "202611040009_business_menu_icons", Migrate: migrateBusinessMenuIcons}, {ID: "202611040008_business_report_build_locks", Migrate: func(db *gorm.DB) error { return migration.CreateMissingTables(db, &reportBuildLockPO{}) }}, {ID: "202611030007_business_alert_attachments", Migrate: migrateAlertAttachments}, {ID: "202611030006_business_alert_schema", Migrate: migrateAlertSchema}, {ID: "202611030005_business_password_reset", Migrate: func(db *gorm.DB) error {
|
||||
return []migration.Step{swmigration.StateMigration(), {ID: "202611060023_business_binding_status_index", Migrate: migrateBindingStatusIndex}, {ID: "202611060022_business_promote_id_capacity", Migrate: migratePromoteIDCapacity}, {ID: "202611050020_business_alert_v2", Migrate: migrateAlertV2}, {ID: "202611040017_business_groups_goals_effectiveness", Migrate: migrateBusinessManagement}, {ID: "202611040018_business_effectiveness_query_index", Migrate: migrateEffectivenessQueryIndex}, {ID: "202611040015_business_approved_game_index", Migrate: migrateApprovedGameIndexes}, {ID: "202611040014_business_report_build_indexes", Migrate: migrateReportBuildQueryIndexes}, {ID: "202611040013_business_query_indexes", Migrate: migrateBusinessQueryIndexes}, {ID: "202611040012_business_server_report_index", Migrate: migrateServerReportIndex}, {ID: "202611040011_business_registration_index", Migrate: migrateRegistrationIndex}, {ID: "202611040010_business_alert_trigger_locks", Migrate: func(db *gorm.DB) error { return migration.CreateMissingTables(db, &alertTriggerLockPO{}) }}, {ID: "202611040009_business_menu_icons", Migrate: migrateBusinessMenuIcons}, {ID: "202611040008_business_report_build_locks", Migrate: func(db *gorm.DB) error { return migration.CreateMissingTables(db, &reportBuildLockPO{}) }}, {ID: "202611030007_business_alert_attachments", Migrate: migrateAlertAttachments}, {ID: "202611030006_business_alert_schema", Migrate: migrateAlertSchema}, {ID: "202611030005_business_password_reset", Migrate: func(db *gorm.DB) error {
|
||||
return migration.CreateMissingTables(db, &resetCodePO{}, &resetTokenPO{})
|
||||
}}, {ID: "202611030004_business_binding_locks", Migrate: func(db *gorm.DB) error {
|
||||
return migration.CreateMissingTables(db, &bindingLockPO{})
|
||||
|
||||
Reference in New Issue
Block a user