141 lines
4.4 KiB
Go
141 lines
4.4 KiB
Go
package models
|
||
|
||
import (
|
||
"encoding/json"
|
||
"errors"
|
||
"log"
|
||
"os"
|
||
"strings"
|
||
|
||
"git.apinb.com/bsm-sdk/core/types"
|
||
"git.apinb.com/bsm-sdk/core/utils"
|
||
"gorm.io/gorm"
|
||
)
|
||
|
||
// DefaultFilePath 相对进程工作目录,与服务启动时读取配置方式一致
|
||
const DefaultFilePath = "etc/menu.json"
|
||
|
||
// File 与 etc/menu_structure.json 根结构一致
|
||
type File struct {
|
||
Menus []Node `json:"menus"`
|
||
TotalLevel1 int `json:"total_level1"`
|
||
TotalLevel2 int `json:"total_level2"`
|
||
}
|
||
|
||
// Node 菜单节点(可嵌套 children)
|
||
type Node struct {
|
||
Title string `json:"title"`
|
||
TitleEn string `json:"title_en"`
|
||
Code string `json:"code"`
|
||
Description string `json:"description"`
|
||
MenuPath string `json:"menu_path"`
|
||
Type int8 `json:"type"`
|
||
SortKey int8 `json:"sort_key"`
|
||
IsWebPage bool `json:"is_web_page"`
|
||
IsNewTab bool `json:"is_new_tab"`
|
||
IsFull bool `json:"is_full"`
|
||
HideMenu bool `json:"hide_menu"`
|
||
WebURL string `json:"web_url"`
|
||
Component string `json:"component"`
|
||
Children []Node `json:"children"`
|
||
}
|
||
|
||
// Load 读取并解析 path
|
||
func Load(path string) (*File, error) {
|
||
raw, err := os.ReadFile(path)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
var f File
|
||
if err := json.Unmarshal(raw, &f); err != nil {
|
||
return nil, err
|
||
}
|
||
return &f, nil
|
||
}
|
||
|
||
func buildPermissions(tx *gorm.DB, appID uint) ([]MgtPermission, error) {
|
||
mf, err := Load(DefaultFilePath)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
if len(mf.Menus) == 0 {
|
||
return nil, errors.New("menu is empty")
|
||
}
|
||
var out []MgtPermission
|
||
if err := walkMenuTree(tx, appID, 0, mf.Menus, &out); err != nil {
|
||
return nil, err
|
||
}
|
||
log.Printf("已从 %s 载入 %d 条权限(含子级)", DefaultFilePath, len(out))
|
||
return out, nil
|
||
}
|
||
|
||
func walkMenuTree(tx *gorm.DB, appID uint, parentID uint, nodes []Node, out *[]MgtPermission) error {
|
||
for i := range nodes {
|
||
p, err := upsertMenuPermissionFromJSON(tx, appID, parentID, nodes[i])
|
||
if err != nil {
|
||
return err
|
||
}
|
||
*out = append(*out, p)
|
||
if len(nodes[i].Children) > 0 {
|
||
if err := walkMenuTree(tx, appID, p.ID, nodes[i].Children, out); err != nil {
|
||
return err
|
||
}
|
||
}
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func upsertMenuPermissionFromJSON(tx *gorm.DB, appID, parentID uint, n Node) (MgtPermission, error) {
|
||
code := strings.TrimSpace(n.Code)
|
||
if code == "" {
|
||
code = "menu_" + strings.ReplaceAll(utils.UUID(), "-", "")
|
||
}
|
||
typ := n.Type
|
||
if typ == 0 {
|
||
typ = 1
|
||
}
|
||
p := MgtPermission{
|
||
Std_IICUDS: types.Std_IICUDS{Identity: utils.UUID(), Status: 1},
|
||
Title: n.Title,
|
||
TitleEn: n.TitleEn,
|
||
Code: code,
|
||
Description: n.Description,
|
||
Appid: appID,
|
||
ParentID: parentID,
|
||
MenuPath: n.MenuPath,
|
||
MenuIcon: "",
|
||
SortKey: n.SortKey,
|
||
Type: typ,
|
||
Component: n.Component,
|
||
IsWebPage: n.IsWebPage,
|
||
IsNewTab: n.IsNewTab,
|
||
IsFull: n.IsFull,
|
||
HideMenu: n.HideMenu,
|
||
WebUrl: n.WebURL,
|
||
}
|
||
var existingPmn MgtPermission
|
||
err := tx.Model(&MgtPermission{}).Where("code = ? AND app_id = ?", p.Code, appID).First(&existingPmn).Error
|
||
if err == gorm.ErrRecordNotFound {
|
||
if err := tx.Create(&p).Error; err != nil {
|
||
return p, err
|
||
}
|
||
return p, nil
|
||
}
|
||
if err != nil {
|
||
return p, err
|
||
}
|
||
p.ID = existingPmn.ID
|
||
return p, nil
|
||
}
|
||
|
||
func builtinManagementMenuTemplates() []MgtPermission {
|
||
return []MgtPermission{
|
||
{Title: "系统管理", TitleEn: "System Management", Code: "system:management", Description: "系统管理菜单", MenuPath: "/system", MenuIcon: "setting", SortKey: 1, Type: 1},
|
||
{Title: "用户管理", TitleEn: "User Management", Code: "user:management", Description: "用户管理菜单", MenuPath: "/system/user", MenuIcon: "user", SortKey: 2, Type: 1},
|
||
{Title: "角色管理", TitleEn: "Role Management", Code: "role:management", Description: "角色管理菜单", MenuPath: "/system/role", MenuIcon: "team", SortKey: 3, Type: 1},
|
||
{Title: "权限管理", TitleEn: "Permission Management", Code: "permission:management", Description: "权限管理菜单", MenuPath: "/system/permission", MenuIcon: "safety", SortKey: 4, Type: 1},
|
||
{Title: "应用管理", TitleEn: "Application Management", Code: "application:management", Description: "应用管理菜单", MenuPath: "/system/application", MenuIcon: "appstore", SortKey: 5, Type: 1},
|
||
{Title: "部门管理", TitleEn: "Department Management", Code: "department:management", Description: "部门管理菜单", MenuPath: "/system/department", MenuIcon: "apartment", SortKey: 6, Type: 1},
|
||
}
|
||
}
|