feat: 移除门户页,登录后默认直达驾驶舱(issue #131)
- web/index.html 改为纯重定向页(/ → cockpit/,驾驶舱自带登录守卫) - 登录页默认 next 改为 ../cockpit/,页脚入口链接同步调整 - Sider 菜单移除「门户」项,logo/默认首页指向驾驶舱
This commit is contained in:
+3
-2
@@ -269,9 +269,9 @@
|
|||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<div class="links">
|
<div class="links">
|
||||||
<a href="../index.html">平台门户</a>
|
|
||||||
<a href="../cockpit/">驾驶舱</a>
|
<a href="../cockpit/">驾驶舱</a>
|
||||||
<a href="../chat/assistant.html">对话助手</a>
|
<a href="../chat/assistant.html">对话助手</a>
|
||||||
|
<a href="../mobile/">移动端</a>
|
||||||
</div>
|
</div>
|
||||||
iAOP-Core v1.0 · 认证后端 core/auth(PBKDF2-HMAC-SHA256)· 部署底座 K8s/Helm
|
iAOP-Core v1.0 · 认证后端 core/auth(PBKDF2-HMAC-SHA256)· 部署底座 K8s/Helm
|
||||||
</footer>
|
</footer>
|
||||||
@@ -291,7 +291,8 @@
|
|||||||
function clearAlert() { $("alert").className = "alert"; }
|
function clearAlert() { $("alert").className = "alert"; }
|
||||||
|
|
||||||
function nextUrl() {
|
function nextUrl() {
|
||||||
return new URLSearchParams(location.search).get("next") || "../index.html";
|
// 无门户页(2026-08):登录后默认直达驾驶舱
|
||||||
|
return new URLSearchParams(location.search).get("next") || "../cockpit/";
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", function () {
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
|||||||
+1
-1
@@ -39,7 +39,7 @@
|
|||||||
</style>
|
</style>
|
||||||
<link rel="stylesheet" href="../shared/pro.css">
|
<link rel="stylesheet" href="../shared/pro.css">
|
||||||
</head>
|
</head>
|
||||||
<body data-pro-title="用户与角色管理" data-pro-home="../index.html" data-pro-login="login.html">
|
<body data-pro-title="用户与角色管理" data-pro-home="../cockpit/" data-pro-login="login.html">
|
||||||
<header id="topbar">
|
<header id="topbar">
|
||||||
<h1>用户/角色管理 <span class="sub">RBAC 三级:readonly / engineer / admin · PRD 8.2</span></h1>
|
<h1>用户/角色管理 <span class="sub">RBAC 三级:readonly / engineer / admin · PRD 8.2</span></h1>
|
||||||
<div id="topbar-right">
|
<div id="topbar-right">
|
||||||
|
|||||||
+13
-175
@@ -3,183 +3,21 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title>iAOP 云美工业AI优化平台 · 门户</title>
|
<title>iAOP 云美工业AI优化平台</title>
|
||||||
<link rel="stylesheet" href="shared/pro.css">
|
<meta http-equiv="refresh" content="0; url=cockpit/">
|
||||||
<style>
|
<style>
|
||||||
/* iAOP 平台门户(Ant Design Pro 风格重构,2026-08)。
|
/* 根路径仅做跳转(2026-08 起门户页移除,登录后默认进驾驶舱):
|
||||||
* 未登录跳登录页(?next 回跳);登录后按角色过滤可见模块:
|
* / → cockpit/(驾驶舱自带登录守卫,未登录会再跳登录页并回跳)。 */
|
||||||
* readonly → 驾驶舱/对话助手/移动端
|
body { margin: 0; min-height: 100vh; display: flex; align-items: center;
|
||||||
* engineer → + 模板配置台
|
justify-content: center; background: #f0f2f5;
|
||||||
* admin → + 管理控制台/用户与角色(全部 6 模块) */
|
font-family: -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||||
body { background: var(--ant-bg-layout); min-height: 100vh;
|
color: rgba(0,0,0,.45); font-size: 14px; }
|
||||||
display: flex; flex-direction: column; margin: 0; }
|
a { color: #1677ff; text-decoration: none; }
|
||||||
|
|
||||||
.page-container { flex: 1; max-width: 1200px; width: 100%;
|
|
||||||
margin: 0 auto; padding: 24px; }
|
|
||||||
|
|
||||||
/* ---- PageHeader(AntD Pro 页头:标题 + 描述 + 右侧状态) --------------- */
|
|
||||||
.page-header {
|
|
||||||
background: var(--ant-bg-container);
|
|
||||||
border-radius: var(--ant-radius-lg);
|
|
||||||
box-shadow: var(--ant-shadow-card);
|
|
||||||
padding: 20px 24px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: 16px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
.page-header .ph-title { font-size: 20px; font-weight: 600; }
|
|
||||||
.page-header .ph-desc { margin-top: 4px; font-size: 13px;
|
|
||||||
color: var(--ant-text-tertiary); }
|
|
||||||
.page-header .ph-extra { display: flex; align-items: center; gap: 8px;
|
|
||||||
font-size: 13px; color: var(--ant-text-secondary); }
|
|
||||||
|
|
||||||
/* ---- 模块卡片网格 ------------------------------------------------------ */
|
|
||||||
.module-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
|
|
||||||
gap: 16px;
|
|
||||||
}
|
|
||||||
a.module-card {
|
|
||||||
display: block;
|
|
||||||
text-decoration: none;
|
|
||||||
background: var(--ant-bg-container);
|
|
||||||
border: 1px solid var(--ant-split);
|
|
||||||
border-radius: var(--ant-radius-lg);
|
|
||||||
box-shadow: var(--ant-shadow-card);
|
|
||||||
padding: 20px 24px;
|
|
||||||
transition: box-shadow .2s, transform .2s;
|
|
||||||
color: var(--ant-text);
|
|
||||||
}
|
|
||||||
a.module-card:hover {
|
|
||||||
box-shadow: 0 3px 6px -4px rgba(0,0,0,.12), 0 6px 16px 0 rgba(0,0,0,.08),
|
|
||||||
0 9px 28px 8px rgba(0,0,0,.05);
|
|
||||||
transform: translateY(-2px);
|
|
||||||
}
|
|
||||||
.module-card .mc-head { display: flex; align-items: center; gap: 10px; }
|
|
||||||
.module-card .mc-icon {
|
|
||||||
width: 40px; height: 40px;
|
|
||||||
border-radius: var(--ant-radius-lg);
|
|
||||||
background: #e6f4ff;
|
|
||||||
display: flex; align-items: center; justify-content: center;
|
|
||||||
font-size: 20px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
.module-card h2 { font-size: 16px; font-weight: 600; margin: 0; }
|
|
||||||
.module-card .mc-desc { margin-top: 12px; font-size: 13px;
|
|
||||||
color: var(--ant-text-tertiary); line-height: 1.7;
|
|
||||||
min-height: 44px; }
|
|
||||||
.module-card .mc-foot { margin-top: 12px; display: flex;
|
|
||||||
justify-content: space-between; align-items: center; }
|
|
||||||
.module-card .mc-enter { font-size: 13px; color: var(--ant-primary); }
|
|
||||||
a.module-card:hover .mc-enter { text-decoration: underline; }
|
|
||||||
|
|
||||||
.portal-footer { text-align: center; padding: 24px; font-size: 12px;
|
|
||||||
color: var(--ant-text-tertiary); }
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body data-pro-title="平台门户" data-pro-home="index.html" data-pro-login="auth/login.html">
|
<body>
|
||||||
<!--
|
<!-- iAOP 平台入口(无门户页):直接重定向到配置化驾驶舱。 -->
|
||||||
iAOP 平台门户(2026-08 Ant Design Pro 风格重构)。
|
<p>正在进入驾驶舱… <a href="cockpit/">立即进入</a></p>
|
||||||
守卫:IAOP_SESSION.requireLoginElseRedirect —— 未登录跳 auth/login.html。
|
<script>location.replace("cockpit/");</script>
|
||||||
模块可见性:IAOP_SESSION.modulesFor(role)(PRD 8.2 三级 RBAC)。
|
|
||||||
-->
|
|
||||||
<div class="page-container">
|
|
||||||
<div class="page-header">
|
|
||||||
<div>
|
|
||||||
<div class="ph-title" id="welcome">平台门户</div>
|
|
||||||
<div class="ph-desc">iAOP-Core 通用内核 · Template-Ti(海绵钛)一期 · 配置化驾驶舱 / 模板配置台 / LLM 助手</div>
|
|
||||||
</div>
|
|
||||||
<div class="ph-extra">
|
|
||||||
推理服务
|
|
||||||
<span id="health" class="pro-tag pro-tag-default">检测中…</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="module-grid" id="moduleGrid" aria-busy="true"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="portal-footer">iAOP-Core v1.0 · 部署底座 K8s/Helm · 推理服务 :30800 · 前端 :8090</div>
|
|
||||||
|
|
||||||
<script src="auth/user_store.js"></script>
|
|
||||||
<script src="shared/session.js"></script>
|
|
||||||
<script src="shared/pro-header.js"></script>
|
|
||||||
<script>
|
|
||||||
(function () {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
function renderModules(user) {
|
|
||||||
var grid = document.getElementById("moduleGrid");
|
|
||||||
grid.innerHTML = "";
|
|
||||||
grid.removeAttribute("aria-busy");
|
|
||||||
document.getElementById("welcome").textContent =
|
|
||||||
"你好," + user.username + ",欢迎使用 iAOP 平台";
|
|
||||||
|
|
||||||
var modules = IAOP_SESSION.modulesFor(user.role);
|
|
||||||
modules.forEach(function (m) {
|
|
||||||
var a = document.createElement("a");
|
|
||||||
a.className = "module-card";
|
|
||||||
a.href = m.url;
|
|
||||||
|
|
||||||
var head = document.createElement("div");
|
|
||||||
head.className = "mc-head";
|
|
||||||
var icon = document.createElement("div");
|
|
||||||
icon.className = "mc-icon";
|
|
||||||
icon.textContent = m.icon;
|
|
||||||
var h2 = document.createElement("h2");
|
|
||||||
h2.textContent = m.title;
|
|
||||||
head.appendChild(icon);
|
|
||||||
head.appendChild(h2);
|
|
||||||
|
|
||||||
var desc = document.createElement("div");
|
|
||||||
desc.className = "mc-desc";
|
|
||||||
desc.textContent = m.desc;
|
|
||||||
|
|
||||||
var foot = document.createElement("div");
|
|
||||||
foot.className = "mc-foot";
|
|
||||||
var tag = document.createElement("span");
|
|
||||||
tag.className = "pro-tag pro-tag-" + (m.tagColor || "default");
|
|
||||||
tag.textContent = m.tag;
|
|
||||||
var enter = document.createElement("span");
|
|
||||||
enter.className = "mc-enter";
|
|
||||||
enter.textContent = "进入 →";
|
|
||||||
foot.appendChild(tag);
|
|
||||||
foot.appendChild(enter);
|
|
||||||
|
|
||||||
a.appendChild(head);
|
|
||||||
a.appendChild(desc);
|
|
||||||
a.appendChild(foot);
|
|
||||||
grid.appendChild(a);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 登录守卫:未登录 → auth/login.html?next=<回跳地址>
|
|
||||||
IAOP_SESSION.requireLoginElseRedirect("auth/login.html").then(function (user) {
|
|
||||||
if (!user) return; // 正在跳转登录页
|
|
||||||
renderModules(user);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 推理服务健康检测(直连 NodePort,CORS 已放行)
|
|
||||||
fetch("http://39.101.182.167:30800/health", { method: "GET" })
|
|
||||||
.then(function (r) { return r.json(); })
|
|
||||||
.then(function (d) {
|
|
||||||
var el = document.getElementById("health");
|
|
||||||
if (d.status === "ok" || d.status === "dry-run") {
|
|
||||||
el.textContent = "在线 · " + d.backend;
|
|
||||||
el.className = "pro-tag pro-tag-green";
|
|
||||||
} else {
|
|
||||||
el.textContent = "异常";
|
|
||||||
el.className = "pro-tag pro-tag-red";
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function () {
|
|
||||||
var el = document.getElementById("health");
|
|
||||||
el.textContent = "不可达";
|
|
||||||
el.className = "pro-tag pro-tag-red";
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
return mods[i].key;
|
return mods[i].key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return path === "/" || /\/index\.html$/.test(path) ? "portal" : "";
|
return ""; // 根路径已重定向驾驶舱,无独立「门户」页
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 当前 hash 命中的子菜单 key(# 前缀归一化) */
|
/* 当前 hash 命中的子菜单 key(# 前缀归一化) */
|
||||||
@@ -96,7 +96,8 @@
|
|||||||
if (!body || document.querySelector(".pro-sider")) return;
|
if (!body || document.querySelector(".pro-sider")) return;
|
||||||
|
|
||||||
var title = body.getAttribute("data-pro-title") || document.title || "";
|
var title = body.getAttribute("data-pro-title") || document.title || "";
|
||||||
var home = body.getAttribute("data-pro-home") || "../index.html";
|
// 无门户页(2026-08):logo 与默认首页均指向驾驶舱
|
||||||
|
var home = body.getAttribute("data-pro-home") || "../cockpit/";
|
||||||
var loginUrl = body.getAttribute("data-pro-login") || "../auth/login.html";
|
var loginUrl = body.getAttribute("data-pro-login") || "../auth/login.html";
|
||||||
var prefix = rootPrefix();
|
var prefix = rootPrefix();
|
||||||
var active = activeModuleKey();
|
var active = activeModuleKey();
|
||||||
@@ -202,7 +203,7 @@
|
|||||||
|
|
||||||
function renderMenu(user) {
|
function renderMenu(user) {
|
||||||
menu.innerHTML = "";
|
menu.innerHTML = "";
|
||||||
addLeafItem("portal", "🏠", "门户", prefix + "index.html");
|
// 无门户页(2026-08):菜单即模块清单,按角色过滤
|
||||||
var mods = user ? IAOP_SESSION.modulesFor(user.role) : [];
|
var mods = user ? IAOP_SESSION.modulesFor(user.role) : [];
|
||||||
mods.forEach(function (m) {
|
mods.forEach(function (m) {
|
||||||
if (m.children && m.children.length) addSubMenu(m);
|
if (m.children && m.children.length) addSubMenu(m);
|
||||||
|
|||||||
Reference in New Issue
Block a user