fix(goauto): add the missing menu migration for SYB product filters #269
Registering a module in access.GoAutoModules() does not make its page reachable on an existing database. sys_menu rows are written by the versioned migration that first created them, and that version is already recorded in sys_migration everywhere — it never runs again. Startup only reconciles the casbin API matrix, not menus. So on a fresh database the page appeared and on every real one it did not: the table, the API and the route were all present with no way to navigate there. This adds a migration that upserts the entry under 采采管理 beside 「SYB 店铺」 and binds it to both 管理员 and 采购员. Verified by deleting the row from an already-migrated database and re-running migrate: 新执行 1 个,跳过 42 个, row restored with both roles. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NTDbDcwbDw1TSAcE6wfh2F
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
package version_local
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"go-admin/app/goauto/access"
|
||||
"go-admin/cmd/migrate/migration"
|
||||
migrationmodels "go-admin/cmd/migrate/migration/models"
|
||||
common "go-admin/common/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func init() {
|
||||
_, file, _, _ := runtime.Caller(0)
|
||||
migration.Migrate.SetVersion(migration.GetFilename(file), migrateSYBProductFilterMenu)
|
||||
}
|
||||
|
||||
// migrateSYBProductFilterMenu adds the 「SYB 商品过滤」 menu entry for #269.
|
||||
//
|
||||
// `[必须]` Adding a module to access.GoAutoModules() is not enough to make its
|
||||
// page reachable. Menus are written by the versioned migration that first
|
||||
// created them, and that version is already recorded in sys_migration on every
|
||||
// existing database — it never runs again. Startup only reconciles the casbin
|
||||
// API matrix (access.ReconcilePurchaserPermissions), not sys_menu. Without this
|
||||
// migration the page exists, the API answers and the route resolves, yet nobody
|
||||
// can navigate to it on an already-migrated database.
|
||||
func migrateSYBProductFilterMenu(db *gorm.DB, version string) error {
|
||||
return db.Transaction(func(tx *gorm.DB) error {
|
||||
module, ok := goAutoModuleByKey(access.ModuleSYBProductFilters)
|
||||
if !ok {
|
||||
return fmt.Errorf("module %q is not registered in access.GoAutoModules()", access.ModuleSYBProductFilters)
|
||||
}
|
||||
|
||||
// The page belongs beside 「SYB 店铺」 under 采采管理, which is where the
|
||||
// admin already manages which SYB data enters the system.
|
||||
var parent migrationmodels.SysMenu
|
||||
if err := tx.Where("menu_name = ?", "GoAutoCollectionManagement").First(&parent).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
child, _, err := upsertGoAutoMenu(tx, migrationmodels.SysMenu{
|
||||
MenuName: module.RouteName,
|
||||
Title: module.Title,
|
||||
Icon: module.Icon,
|
||||
Path: module.Path + "/index",
|
||||
MenuType: "C",
|
||||
Action: "无",
|
||||
ParentId: parent.MenuId,
|
||||
Component: module.Component,
|
||||
Sort: module.Sort,
|
||||
Visible: "0",
|
||||
IsFrame: "1",
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = tx.Model(&child).Update("paths", fmt.Sprintf("/0/%d/%d", parent.MenuId, child.MenuId)).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Bind to both roles the module declares. 采购员 needs it because the
|
||||
// module is PurchaserDefault; 管理员 needs it because only an admin may
|
||||
// change the rules (the write routes are RequireRoleKey("admin")).
|
||||
roleKeys := []string{"admin"}
|
||||
if module.PurchaserDefault {
|
||||
roleKeys = append(roleKeys, access.RolePurchaser)
|
||||
}
|
||||
for _, key := range roleKeys {
|
||||
var role migrationmodels.SysRole
|
||||
if err = tx.Where("role_key = ?", key).First(&role).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err = tx.Model(&role).Association("SysMenu").Append(&child); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return tx.Create(&common.Migration{Version: version}).Error
|
||||
})
|
||||
}
|
||||
|
||||
func goAutoModuleByKey(key string) (access.ModuleDefinition, bool) {
|
||||
for _, module := range access.GoAutoModules() {
|
||||
if module.Key == key {
|
||||
return module, true
|
||||
}
|
||||
}
|
||||
return access.ModuleDefinition{}, false
|
||||
}
|
||||
Reference in New Issue
Block a user