feat: 完成 Passkey 能力与前后台加载优化
更新说明:\n1. 新增用户端与管理员端 Passkey 登录/注册/设备管理(最多3台,支持设备备注、删除设备)。\n2. 修复 Passkey 注册与登录流程中的浏览器/证书/CSRF相关问题,增强错误提示。\n3. 前台登录页改为独立入口,首屏仅加载必要资源,其他页面按需加载。\n4. 系统配置页改为静默获取金山文档状态,避免首屏阻塞,并优化状态展示为“检测中/已登录/未登录/异常”。\n5. 补充后端接口与页面渲染适配,修复多入口下样式依赖注入问题。\n6. 同步更新前后台构建产物与相关静态资源。
This commit is contained in:
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user