fix(admin): 发版 chunk 自动刷新、nginx 缓存策略与审计页 i18n

lazy route 加载失败时刷新入口;index.html 不缓存;补全 audit.col.operator/ip 等拆包遗漏 key。
This commit is contained in:
2026-06-18 16:59:39 +08:00
parent e39798ae0a
commit c40ebb56ca
5 changed files with 55 additions and 2 deletions

View File

@@ -357,10 +357,14 @@ const adminPages: Record<string, string> = {
'bet.col.result': 'Result', 'bet.col.result': 'Result',
'audit.module_ph': 'e.g. USERS, AGENTS', 'audit.module_ph': 'e.g. USERS, AGENTS',
'audit.col.time': 'Time',
'audit.col.operator': 'Operator',
'audit.col.action': 'Action', 'audit.col.action': 'Action',
'audit.col.module': 'Module', 'audit.col.module': 'Module',
'audit.col.target_id': 'Target ID', 'audit.col.target_id': 'Target ID',
'audit.col.time': 'Time', 'audit.col.ip': 'IP',
'audit.operator_system': 'System',
'audit.operator_player': 'Player',
'audit.action.CREATE_PLAYER': 'Create player', 'audit.action.CREATE_PLAYER': 'Create player',
'audit.action.UPDATE_PLAYER': 'Update player', 'audit.action.UPDATE_PLAYER': 'Update player',
'audit.action.RESET_DATABASE': 'Reset database', 'audit.action.RESET_DATABASE': 'Reset database',

View File

@@ -358,10 +358,14 @@ const adminPages: Record<string, string> = {
'bet.col.result': '赛果', 'bet.col.result': '赛果',
'audit.module_ph': '如 USERS、AGENTS', 'audit.module_ph': '如 USERS、AGENTS',
'audit.col.time': '时间',
'audit.col.operator': '操作人',
'audit.col.action': '操作', 'audit.col.action': '操作',
'audit.col.module': '模块', 'audit.col.module': '模块',
'audit.col.target_id': '目标 ID', 'audit.col.target_id': '目标 ID',
'audit.col.time': '时间', 'audit.col.ip': 'IP',
'audit.operator_system': '系统',
'audit.operator_player': '玩家',
'audit.action.CREATE_PLAYER': '新建玩家', 'audit.action.CREATE_PLAYER': '新建玩家',
'audit.action.UPDATE_PLAYER': '更新玩家', 'audit.action.UPDATE_PLAYER': '更新玩家',
'audit.action.RESET_DATABASE': '重置数据库', 'audit.action.RESET_DATABASE': '重置数据库',

View File

@@ -250,4 +250,28 @@ router.beforeEach(async (to) => {
return true; return true;
}); });
/** 发版后旧 index.html 可能引用已不存在的 hash chunk自动刷新一次拉最新入口。 */
function isLazyChunkLoadError(err: unknown): boolean {
const msg = err instanceof Error ? err.message : String(err ?? '');
return (
msg.includes('Failed to fetch dynamically imported module') ||
msg.includes('Importing a module script failed') ||
msg.includes('error loading dynamically imported module')
);
}
const CHUNK_RELOAD_FLAG = 'admin:chunk-reload';
router.onError((error, to) => {
if (!isLazyChunkLoadError(error)) throw error;
const target = to.fullPath || '/';
if (!sessionStorage.getItem(CHUNK_RELOAD_FLAG)) {
sessionStorage.setItem(CHUNK_RELOAD_FLAG, target);
window.location.assign(target);
return;
}
sessionStorage.removeItem(CHUNK_RELOAD_FLAG);
throw error;
});
export default router; export default router;

View File

@@ -9,6 +9,17 @@ server {
gzip on; gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml; gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
# 带 hash 的静态资源可长期缓存index.html 禁止缓存,避免发版后引用旧 chunk
location /assets/ {
add_header Cache-Control "public, max-age=31536000, immutable";
try_files $uri =404;
}
location = /index.html {
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
}
location /api/ { location /api/ {
proxy_pass http://api:3000; proxy_pass http://api:3000;
proxy_http_version 1.1; proxy_http_version 1.1;

View File

@@ -10,6 +10,16 @@ server {
gzip on; gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml; gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
location /assets/ {
add_header Cache-Control "public, max-age=31536000, immutable";
try_files $uri =404;
}
location = /index.html {
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
}
location /api/ { location /api/ {
set $api_upstream api:3000; set $api_upstream api:3000;
proxy_pass http://$api_upstream; proxy_pass http://$api_upstream;