Files

141 lines
4.4 KiB
Go
Raw Permalink Normal View History

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},
}
}