const PollsPage = { async render() { return '
'; }, async mount() { document.getElementById('page-title').textContent = '投票'; document.getElementById('page-actions').innerHTML = Auth.isOwner() ? '' : ''; await this.load(); }, async load() { const ct = document.getElementById('page-content'); try { const polls = await API.get('/polls/active'); ct.innerHTML = polls.length === 0 ? '

暂无进行中的投票

' : polls.map(p => this.renderPoll(p)).join(''); for (const p of polls) this.bindVote(p); } catch (e) { ct.innerHTML = `
${e.message}
`; } }, renderPoll(p) { const opts = p.options || []; const max = Math.max(1, ...Object.values(p.votes || {})); const showResult = Auth.isOwner() || !p.voted; return `
${U.esc(p.title)}${p.total||0} 票
${p.description?`

${U.esc(p.description)}

`:''} ${p.voted && !showResult ? `
已投票,结果仅在投票结束后向服主公开
` : ''}
${opts.map((o,i) => { const v = showResult ? (p.votes?.[i] || 0) : 0; const pct = showResult && p.total ? Math.round(v/p.total*100) : 0; const my = p.my_vote === i; return `
${showResult ? `
` : ''}
${my?' ':''}${U.esc(o)} ${showResult ? `${v}票 ${pct}%` : ''}
`; }).join('')}
`; }, bindVote(p) { if (p.voted) return; const card = document.getElementById('poll-'+p.id); if (!card) return; card.querySelectorAll('.poll-opt').forEach(el => { el.addEventListener('click', async () => { try { await API.post(`/polls/${p.id}/vote`, { option_index: parseInt(el.dataset.idx) }); this.load(); } catch (ex) { alert(ex.message); } }); }); }, showCreate() { U.modal('创建投票', `
`); document.getElementById('poll-form').onsubmit = async e => { e.preventDefault(); const opts = document.getElementById('pl-opts').value.split('\n').map(s=>s.trim()).filter(s=>s); if (opts.length < 2) return alert('至少需要2个选项'); try { await API.post('/polls', { title: document.getElementById('pl-title').value, description: document.getElementById('pl-desc').value, options: opts }); App.closeModal(); this.load(); } catch (ex) { alert(ex.message); } }; } };