feat: 完成 Passkey 能力与前后台加载优化

更新说明:\n1. 新增用户端与管理员端 Passkey 登录/注册/设备管理(最多3台,支持设备备注、删除设备)。\n2. 修复 Passkey 注册与登录流程中的浏览器/证书/CSRF相关问题,增强错误提示。\n3. 前台登录页改为独立入口,首屏仅加载必要资源,其他页面按需加载。\n4. 系统配置页改为静默获取金山文档状态,避免首屏阻塞,并优化状态展示为“检测中/已登录/未登录/异常”。\n5. 补充后端接口与页面渲染适配,修复多入口下样式依赖注入问题。\n6. 同步更新前后台构建产物与相关静态资源。
This commit is contained in:
2026-02-15 23:51:12 +08:00
parent ebfac7266b
commit 7007f5f6f5
129 changed files with 3747 additions and 432 deletions

View File

@@ -15,10 +15,45 @@ from services.runtime import get_logger
pages_bp = Blueprint("pages", __name__)
def _collect_entry_css_files(manifest: dict, entry_name: str) -> list[str]:
css_files: list[str] = []
seen_css: set[str] = set()
visited: set[str] = set()
def _append_css(entry_obj: dict) -> None:
for css_file in entry_obj.get("css") or []:
css_path = str(css_file or "").strip()
if not css_path or css_path in seen_css:
continue
seen_css.add(css_path)
css_files.append(css_path)
def _walk_manifest_key(manifest_key: str) -> None:
key = str(manifest_key or "").strip()
if not key or key in visited:
return
visited.add(key)
entry_obj = manifest.get(key)
if not isinstance(entry_obj, dict):
return
_append_css(entry_obj)
for imported_key in entry_obj.get("imports") or []:
_walk_manifest_key(imported_key)
entry = manifest.get(entry_name) or {}
if isinstance(entry, dict):
_append_css(entry)
for imported_key in entry.get("imports") or []:
_walk_manifest_key(imported_key)
return css_files
def render_app_spa_or_legacy(
legacy_template_name: str,
legacy_context: Optional[dict] = None,
spa_initial_state: Optional[dict] = None,
spa_entry_name: str = "index.html",
):
"""渲染前台 Vue SPA构建产物位于 static/app失败则回退旧模板。"""
logger = get_logger()
@@ -28,9 +63,9 @@ def render_app_spa_or_legacy(
with open(manifest_path, "r", encoding="utf-8") as f:
manifest = json.load(f)
entry = manifest.get("index.html") or {}
entry = manifest.get(spa_entry_name) or {}
js_file = entry.get("file")
css_files = entry.get("css") or []
css_files = _collect_entry_css_files(manifest, spa_entry_name)
if not js_file:
logger.warning(f"[app_spa] manifest缺少入口文件: {manifest_path}")
@@ -83,7 +118,7 @@ def index():
@pages_bp.route("/login")
def login_page():
"""登录页面"""
return render_app_spa_or_legacy("login.html")
return render_app_spa_or_legacy("login.html", spa_entry_name="login.html")
@pages_bp.route("/register")