增加功能报价
This commit is contained in:
@@ -113,10 +113,12 @@ func (c *BackendMenuController) GetBackendMenu() {
|
||||
}
|
||||
}
|
||||
|
||||
// 套餐功能开通过滤:仅展示租户套餐已包含的功能模块对应的菜单(未包含的整块菜单不展示)
|
||||
backendMenus = filterMenusByTenantPackage(c.Ctx.Request.Header.Get("Authorization"), backendMenus, tid)
|
||||
// 套餐功能开通标记:未开通模块的菜单保留但标记 locked(前端展示锁定态与升级提示,不再 404)
|
||||
backendMenus, lockedMenuIDs := filterMenusByTenantPackageLocked(c.Ctx.Request.Header.Get("Authorization"), backendMenus, tid, true)
|
||||
menuTree := buildMenuTree(backendMenus, 0)
|
||||
markTreeLocked(menuTree, lockedMenuIDs)
|
||||
|
||||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": buildMenuTree(backendMenus, 0)}
|
||||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": menuTree}
|
||||
_ = c.ServeJSON()
|
||||
}
|
||||
|
||||
@@ -139,26 +141,51 @@ func backendJWTTenantID(auth string) uint64 {
|
||||
return uint64(claims.TenantId)
|
||||
}
|
||||
|
||||
// filterMenusByTenantPackage 按租户套餐包含的功能模块过滤菜单。
|
||||
// filterMenusByTenantPackage 按租户套餐包含的功能模块过滤菜单(剔除未开通模块,用于角色菜单分配等场景)。
|
||||
// tid 优先取 token 中的租户ID,其次用调用方传入的兜底值;两者都取不到时不处理(保持原行为)。
|
||||
func filterMenusByTenantPackage(authHeader string, menus []models.SystemMenu, tid uint64) []models.SystemMenu {
|
||||
filtered, _ := filterMenusByTenantPackageLocked(authHeader, menus, tid, false)
|
||||
return filtered
|
||||
}
|
||||
|
||||
// filterMenusByTenantPackageLocked 按租户套餐处理菜单。
|
||||
// markLocked=false:剔除未开通模块的菜单(原行为);markLocked=true:保留菜单并返回锁定菜单ID集合(含后代)。
|
||||
func filterMenusByTenantPackageLocked(authHeader string, menus []models.SystemMenu, tid uint64, markLocked bool) ([]models.SystemMenu, map[uint64]bool) {
|
||||
if jwtTid := backendJWTTenantID(authHeader); jwtTid > 0 {
|
||||
tid = jwtTid
|
||||
}
|
||||
if tid == 0 {
|
||||
return menus
|
||||
return menus, nil
|
||||
}
|
||||
allModules, err := services.ListEnabledModules()
|
||||
if err != nil || len(allModules) == 0 {
|
||||
return menus
|
||||
return menus, nil
|
||||
}
|
||||
allowed := services.GetTenantModuleCodes(tid)
|
||||
// 安全兜底:租户没有绑定套餐或套餐未配置任何功能模块时不做过滤,
|
||||
// 避免因套餐数据缺失导致租户端菜单整体消失。
|
||||
if len(allowed) == 0 {
|
||||
return menus
|
||||
return menus, nil
|
||||
}
|
||||
if markLocked {
|
||||
return services.MarkMenusLockedByTenantModules(menus, allModules, allowed)
|
||||
}
|
||||
return services.FilterMenusByTenantModules(menus, allModules, allowed), nil
|
||||
}
|
||||
|
||||
// markTreeLocked 将菜单树中位于锁定集合的节点标记为 locked
|
||||
func markTreeLocked(nodes []*menuNode, locked map[uint64]bool) {
|
||||
if len(nodes) == 0 || len(locked) == 0 {
|
||||
return
|
||||
}
|
||||
for _, n := range nodes {
|
||||
if locked[n.ID] {
|
||||
n.Locked = true
|
||||
}
|
||||
if len(n.Children) > 0 {
|
||||
markTreeLocked(n.Children, locked)
|
||||
}
|
||||
}
|
||||
return services.FilterMenusByTenantModules(menus, allModules, allowed)
|
||||
}
|
||||
|
||||
// parseRightsToSet 将角色 rights 解析为菜单 ID 集合(兼容 JSON 数组 / 逗号分隔)
|
||||
@@ -350,6 +377,7 @@ type menuNode struct {
|
||||
Views []int `json:"views,omitempty"`
|
||||
Type int8 `json:"type"`
|
||||
Permission string `json:"permission,omitempty"`
|
||||
Locked bool `json:"locked,omitempty"`
|
||||
Children []*menuNode `json:"children,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user