- main.py admin_page 调用 _load_current_backend_menu_items 取当前用户权限菜单, 经 render_html 传入模板;Java 权限接口不可用时降级不渲染(避免展示越权菜单) - admin.html 删除写死的 16 个静态菜单按钮,改为 Jinja2 按权限渲染分组菜单, 渲染成功时 nav 带 data-server-rendered 标记,失败显示轻量占位 - admin.js loadAdminMenus 识别 data-server-rendered 后直接绑定事件并激活, 不再请求 /current-user/menus 重渲染(保留 API 兜底路径)
This commit is contained in:
@@ -268,8 +268,43 @@
|
||||
group.style.display = visible ? '' : 'none';
|
||||
});
|
||||
}
|
||||
function bindAdminMenuTabs(serverRendered) {
|
||||
adminMenuByRoute = {};
|
||||
var routes = [];
|
||||
adminMenuEl.querySelectorAll('#adminMenu .tab').forEach(function (tab) {
|
||||
var route = tab.dataset.tab;
|
||||
if (!route) return;
|
||||
routes.push(route);
|
||||
if (!adminMenuByRoute[route]) {
|
||||
adminMenuByRoute[route] = { route_path: route, name: tab.getAttribute('title') || route };
|
||||
}
|
||||
tab.onclick = function () {
|
||||
activateAdminTab(tab.dataset.tab);
|
||||
};
|
||||
});
|
||||
return routes;
|
||||
}
|
||||
function loadAdminMenus(preferredTab) {
|
||||
if (preferredTab) activeAdminTabName = preferredTab;
|
||||
// 服务端已按权限渲染菜单(data-server-rendered=true):直接绑定事件并激活,
|
||||
// 不再请求接口重渲染,避免"全量菜单→折叠"的闪烁。
|
||||
if (!adminMenuEl || adminMenuEl.getAttribute('data-server-rendered') !== 'true') {
|
||||
renderAdminTabsFromApi();
|
||||
return;
|
||||
}
|
||||
var serverRoutes = bindAdminMenuTabs(true);
|
||||
if (!serverRoutes.length) {
|
||||
activeAdminTabName = '';
|
||||
hideAllAdminPanels();
|
||||
return;
|
||||
}
|
||||
if (window.__initAdminMenuCollapse) window.__initAdminMenuCollapse();
|
||||
var fallbackTab = activeAdminTabName && serverRoutes.indexOf(activeAdminTabName) >= 0
|
||||
? activeAdminTabName
|
||||
: serverRoutes[0];
|
||||
activateAdminTab(fallbackTab);
|
||||
}
|
||||
function renderAdminTabsFromApi() {
|
||||
fetch('/api/admin/current-user/menus')
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (res) {
|
||||
|
||||
Reference in New Issue
Block a user