const TicketsPage = { tab: 'all', filters: {}, async render() { return '
'; }, async mount() { document.getElementById('page-title').textContent = '工单列表'; document.getElementById('page-actions').innerHTML = ` `; this.renderLayout(); await this.loadTab(this.tab); }, renderLayout() { const ct = document.getElementById('page-content'); const isStaff = Auth.isAdmin(); ct.innerHTML = ` ${isStaff ? `
` : ''}
${isStaff ? `` : ''}
`; if (document.getElementById('ticket-tabs')) { document.querySelectorAll('#ticket-tabs button').forEach(btn => { btn.onclick = () => { document.querySelectorAll('#ticket-tabs button').forEach(b => b.classList.remove('active')); btn.classList.add('active'); this.tab = btn.dataset.tab; this.loadTab(this.tab); }; }); } }, async loadTab(tab) { const list = document.getElementById('ticket-list'); U.loading(list); try { const params = new URLSearchParams(); if (this.filters.type) params.set('type', this.filters.type); if (this.filters.status) params.set('status', this.filters.status); if (tab === 'pending') params.set('claimed', '0'); else if (tab === 'claimed') params.set('claimed', '1'); if (this.filters.search) params.set('search', this.filters.search); const qs = params.toString(); const tickets = await API.get('/tickets' + (qs ? '?' + qs : '')); this.renderList(list, tickets); } catch (e) { list.innerHTML = `
${e.message}
`; } }, renderList(ct, tickets) { ct.innerHTML = tickets.length === 0 ? `

暂无工单

` : `
${tickets.map(t => ` `).join('')}
#类型标题提交者对象状态优先级负责人时间操作
${t.id} ${U.badge(t.type,'type')} ${U.esc(t.title)} ${U.esc(t.reporter_game_name)}
UID:${U.esc(t.reporter_game_uid)}
${t.target_game_name||t.target_game_uid?`${U.esc(t.target_game_name||'?')}${t.target_game_uid?`
UID:${U.esc(t.target_game_uid)}`:''}`:'-'}
${U.badge(t.status,'status')} ${U.badge(t.priority,'priority')} ${t.assignee_name?`${U.esc(t.assignee_name)}`:`待认领`} ${U.date(t.updated_at)}
`; }, applyFilters() { this.filters = { type: document.getElementById('ft-type')?.value, status: document.getElementById('ft-status').value, search: document.getElementById('ft-search').value, }; this.loadTab(this.tab); }, resetFilters() { this.filters = {}; document.querySelectorAll('.filter-bar select, .filter-bar input').forEach(el => { if (el.tagName === 'SELECT' || el.tagName === 'INPUT') el.value = ''; }); this.loadTab(this.tab); } };