feat: anonymous ticket tracking as standalone public page

- tracking: promoted to public route (before auth gate) with full single-ticket view
- backend: GET /tickets/tracking/:id validates cookie tracking_token, returns responses/attachments/transfers
- tracking.js: rewrite - token list + chat-flow detail (player/staff bubbles) + processing log + anon reply
- ticket-create: anon submit now lands on #/tracking instead of home
- home: tracking tab navigates to standalone page
This commit is contained in:
2026-08-23 17:50:42 +08:00
parent 09e33128a8
commit 1979cab5ec
5 changed files with 125 additions and 24 deletions

View File

@@ -206,6 +206,7 @@ const App = {
if (page === 'install') { this.showPublic('install'); return; }
if (page === 'home') { this.showPublic('home', param); return; }
if (page === 'tracking') { this.showPublic('tracking', param); return; }
if (page === 'login' || page === 'register' || page === 'forgot' || page === 'reset') { this.showPublic(page); return; }
// 受保护页面: Auth.logged() 内部解码 JWT exp,过期自动清除登录态(同步,无异步循环)
@@ -258,7 +259,7 @@ const App = {
document.getElementById('top-bar').classList.remove('hidden');
this.updateTopAuth();
this.loadFooter();
const comp = page === 'login' ? LoginPage : page === 'register' ? RegisterPage : page === 'install' ? InstallPage : page === 'forgot' ? ForgotPage : page === 'reset' ? ResetPage : page === 'verify' ? VerifyPage : HomePage;
const comp = page === 'login' ? LoginPage : page === 'register' ? RegisterPage : page === 'install' ? InstallPage : page === 'forgot' ? ForgotPage : page === 'reset' ? ResetPage : page === 'verify' ? VerifyPage : page === 'tracking' ? TrackingPage : HomePage;
comp.render(param).then(html => { pub.innerHTML = html; if (comp.mount) comp.mount(param); }).catch(() => {
pub.innerHTML = '<div class="pub-card"><div class="logo"><i class="fas fa-exclamation-triangle" style="color:var(--d)"></i><h2>加载失败</h2><p>请刷新页面重试</p></div></div>';
});