From d108f3b51da5c3d340031ddc2eec42868a6b1186 Mon Sep 17 00:00:00 2001 From: yuyx <237899745@qq.com> Date: Wed, 31 Dec 2025 18:22:03 +0800 Subject: [PATCH] bust spa asset cache by build id --- routes/pages.py | 38 ++++++++++++++++++++++++++++++++++---- templates/admin.html | 9 ++++++++- templates/app.html | 8 ++++++++ 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/routes/pages.py b/routes/pages.py index b0656d8..54d6c3b 100644 --- a/routes/pages.py +++ b/routes/pages.py @@ -36,10 +36,18 @@ def render_app_spa_or_legacy( logger.warning(f"[app_spa] manifest缺少入口文件: {manifest_path}") return render_template(legacy_template_name, **legacy_context) + app_spa_js_file = f"app/{js_file}" + app_spa_css_files = [f"app/{p}" for p in css_files] + app_spa_build_id = _get_asset_build_id( + os.path.join(current_app.root_path, "static"), + [app_spa_js_file, *app_spa_css_files], + ) + return render_template( "app.html", - app_spa_js_file=f"app/{js_file}", - app_spa_css_files=[f"app/{p}" for p in css_files], + app_spa_js_file=app_spa_js_file, + app_spa_css_files=app_spa_css_files, + app_spa_build_id=app_spa_build_id, app_spa_initial_state=spa_initial_state, ) except FileNotFoundError: @@ -50,6 +58,20 @@ def render_app_spa_or_legacy( return render_template(legacy_template_name, **legacy_context) +def _get_asset_build_id(static_root: str, rel_paths: list[str]) -> Optional[str]: + mtimes = [] + for rel_path in rel_paths: + if not rel_path: + continue + try: + mtimes.append(os.path.getmtime(os.path.join(static_root, rel_path))) + except OSError: + continue + if not mtimes: + return None + return str(int(max(mtimes))) + + @pages_bp.route("/") def index(): """主页 - 重定向到登录或应用""" @@ -110,10 +132,18 @@ def admin_page(): logger.warning(f"[admin_spa] manifest缺少入口文件: {manifest_path}") return render_template("admin_legacy.html") + admin_spa_js_file = f"admin/{js_file}" + admin_spa_css_files = [f"admin/{p}" for p in css_files] + admin_spa_build_id = _get_asset_build_id( + os.path.join(current_app.root_path, "static"), + [admin_spa_js_file, *admin_spa_css_files], + ) + return render_template( "admin.html", - admin_spa_js_file=f"admin/{js_file}", - admin_spa_css_files=[f"admin/{p}" for p in css_files], + admin_spa_js_file=admin_spa_js_file, + admin_spa_css_files=admin_spa_css_files, + admin_spa_build_id=admin_spa_build_id, ) except FileNotFoundError: logger.warning(f"[admin_spa] 未找到manifest: {manifest_path},回退旧版后台模板") diff --git a/templates/admin.html b/templates/admin.html index e85f6ad..b9d01de 100644 --- a/templates/admin.html +++ b/templates/admin.html @@ -5,13 +5,20 @@ 后台管理 - 知识管理平台 {% for css_file in admin_spa_css_files %} + {% if admin_spa_build_id %} + + {% else %} + {% endif %} {% endfor %}
+ {% if admin_spa_build_id %} + + {% else %} + {% endif %} - diff --git a/templates/app.html b/templates/app.html index fcef7f5..646772b 100644 --- a/templates/app.html +++ b/templates/app.html @@ -5,7 +5,11 @@ 知识管理平台 {% for css_file in app_spa_css_files %} + {% if app_spa_build_id %} + + {% else %} + {% endif %} {% endfor %} @@ -16,6 +20,10 @@ window.__APP_INITIAL_STATE__ = {{ app_spa_initial_state | tojson }}; {% endif %} + {% if app_spa_build_id %} + + {% else %} + {% endif %}