fix: remove Google Fonts dependency + lazy-load page scripts

- CSS: drop @import fonts.googleapis (blocked by CSP style-src,
  unreachable in CN) - use system font stack with YaHei fallback
- index.html: remove all 26 js/pages/*.js tags - core 4 scripts only
- app.js: route-based lazy loading - PAGE_SCRIPTS map, loadScript
  with cache, async route() loads page scripts before render
- cross-deps: home->ticket-create, reset defined in forgot.js
This commit is contained in:
2026-08-22 12:26:15 +08:00
parent da26dd5f69
commit 4ebabfc703
3 changed files with 60 additions and 29 deletions

View File

@@ -1,5 +1,5 @@
/* ===== Modern MC Report System ===== */ /* ===== Modern MC Report System ===== */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap'); /* 字体使用系统栈, 不依赖 Google Fonts(国内不可达且受 CSP 限制) */
:root { :root {
--p: #6366f1; --pd: #4f46e5; --pl: #eef2ff; --pg: linear-gradient(135deg,#6366f1,#8b5cf6); --p: #6366f1; --pd: #4f46e5; --pl: #eef2ff; --pg: linear-gradient(135deg,#6366f1,#8b5cf6);
@@ -19,7 +19,7 @@
*{margin:0;padding:0;box-sizing:border-box} *{margin:0;padding:0;box-sizing:border-box}
body{ body{
font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI','Noto Sans SC',sans-serif; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI','Noto Sans SC','Microsoft YaHei',sans-serif;
background:var(--g1);color:var(--g8);line-height:1.6; background:var(--g1);color:var(--g8);line-height:1.6;
-webkit-font-smoothing:antialiased;display:flex;flex-direction:column;min-height:100vh; -webkit-font-smoothing:antialiased;display:flex;flex-direction:column;min-height:100vh;
} }

View File

@@ -54,32 +54,7 @@
<script src="js/utils.js"></script> <script src="js/utils.js"></script>
<script src="js/api.js"></script> <script src="js/api.js"></script>
<script src="js/auth.js"></script> <script src="js/auth.js"></script>
<script src="js/pages/install.js"></script> <!-- 页面脚本按路由懒加载(app.js 动态注入), 不再全量下发 -->
<script src="js/pages/login.js"></script>
<script src="js/pages/register.js"></script>
<script src="js/pages/forgot.js"></script>
<script src="js/pages/verify.js"></script>
<script src="js/pages/home.js"></script>
<script src="js/pages/dashboard.js"></script>
<script src="js/pages/tickets.js"></script>
<script src="js/pages/ticket-create.js"></script>
<script src="js/pages/ticket-detail.js"></script>
<script src="js/pages/tracking.js"></script>
<script src="js/pages/unclaimed.js"></script>
<script src="js/pages/users.js"></script>
<script src="js/pages/templates.js"></script>
<script src="js/pages/notifications.js"></script>
<script src="js/pages/external-api.js"></script>
<script src="js/pages/external-api-docs.js"></script>
<script src="js/pages/settings-page.js"></script>
<script src="js/pages/export-page.js"></script>
<script src="js/pages/polls.js"></script>
<script src="js/pages/servers.js"></script>
<script src="js/pages/bans.js"></script>
<script src="js/pages/logs.js"></script>
<script src="js/pages/sources.js"></script>
<script src="js/pages/features.js"></script>
<script src="js/pages/feature-detail.js"></script>
<script src="js/app.js"></script> <script src="js/app.js"></script>
</body> </body>
</html> </html>

View File

@@ -97,12 +97,68 @@ const App = {
closeModal() { document.getElementById('modal-overlay').classList.add('hidden'); }, closeModal() { document.getElementById('modal-overlay').classList.add('hidden'); },
navigate(page, param) { location.hash = `#/${page}` + (param ? `/${param}` : ''); }, navigate(page, param) { location.hash = `#/${page}` + (param ? `/${param}` : ''); },
route() { // ===== 页面脚本懒加载: 按路由动态注入, 避免全量下发 =====
_scriptCache: {},
// 路由 → 依赖脚本(不带 .js 后缀); home 依赖 ticket-create(首页内嵌提交表单), reset 定义于 forgot.js
PAGE_SCRIPTS: {
home: ['home', 'ticket-create'],
install: ['install'],
login: ['login'],
register: ['register'],
forgot: ['forgot'],
reset: ['forgot'],
verify: ['verify'],
dashboard: ['dashboard'],
unclaimed: ['unclaimed'],
tickets: ['tickets', 'ticket-create'],
ticket: ['ticket-detail'],
tracking: ['tracking'],
users: ['users'],
notifications: ['notifications'],
'external-api': ['external-api'],
'external-api-docs': ['external-api-docs'],
sources: ['sources'],
templates: ['templates'],
settings: ['settings-page'],
export: ['export-page'],
polls: ['polls'],
features: ['features'],
feature: ['feature-detail'],
servers: ['servers'],
bans: ['bans'],
logs: ['logs'],
},
loadScript(src) {
if (this._scriptCache[src]) return this._scriptCache[src];
const p = new Promise((resolve, reject) => {
const s = document.createElement('script');
s.src = src;
s.onload = () => resolve();
s.onerror = () => { delete this._scriptCache[src]; reject(new Error('脚本加载失败: ' + src)); };
document.head.appendChild(s);
});
this._scriptCache[src] = p;
return p;
},
async loadPageScripts(page) {
const files = this.PAGE_SCRIPTS[page] || [page];
for (const f of files) await this.loadScript(`js/pages/${f}.js`);
},
async route() {
const hash = location.hash || '#/home'; const hash = location.hash || '#/home';
const parts = hash.replace('#/', '').split('/'); const parts = hash.replace('#/', '').split('/');
const page = parts[0]; const page = parts[0];
const param = parts.slice(1).join('/'); const param = parts.slice(1).join('/');
// 先加载当前路由所需页面脚本, 再渲染
try { await this.loadPageScripts(page); }
catch (e) {
console.error('页面脚本加载失败:', e.message);
document.getElementById('page-content').innerHTML = `<div class="card"><div class="card-b" style="text-align:center;color:var(--d)">页面资源加载失败, 请刷新重试</div></div>`;
return;
}
if (page === 'verify') { if (page === 'verify') {
this.showPublic('verify'); this.showPublic('verify');
return; return;