feat: admin complaint (owner only) + result appeal (one per ticket, owner only)
This commit is contained in:
@@ -46,6 +46,10 @@ const TicketCreate = {
|
||||
</datalist>
|
||||
</div>
|
||||
<div class="form-group"><label>详细描述</label><textarea name="description" rows="4" placeholder="请详细描述事件经过..."></textarea></div>
|
||||
<div class="form-group" style="display:flex;align-items:center;gap:8px;margin-top:12px">
|
||||
<input type="checkbox" name="is_admin_complaint" value="1" id="cb-admin" style="width:auto">
|
||||
<label for="cb-admin" style="margin:0;font-weight:500;text-transform:none;letter-spacing:0;color:var(--d)"><i class="fas fa-exclamation-triangle"></i> 投诉管理员(仅服主可见)</label>
|
||||
</div>
|
||||
` : isAppeal ? `
|
||||
<div class="form-group"><label>申诉理由 *</label><input name="reason" required placeholder="如:误封、证据不足被封、违规行为已纠正等"></div>
|
||||
<div class="form-group"><label>详细说明 *</label><textarea name="description" rows="5" placeholder="请详细说明情况,包括被封时间、可能原因、为什么应解封等..." required></textarea></div>
|
||||
|
||||
@@ -34,6 +34,10 @@ const TicketDetail = {
|
||||
|
||||
${t.claim_note?`<div class="card"><div class="card-h">处理备注</div><div class="card-b" style="white-space:pre-wrap">${U.esc(t.claim_note)}</div></div>`:''}
|
||||
|
||||
${t.parent_ticket?`<div class="card"><div class="card-h">关联工单</div><div class="card-b">
|
||||
<div class="detail-row"><span class="lbl">原工单</span><span class="val"><a href="#" onclick="App.navigate('ticket',${t.parent_ticket.id});return false" style="color:var(--p)">#${t.parent_ticket.id} ${U.esc(t.parent_ticket.title)}</a> — ${U.badge(t.parent_ticket.status,'status')}</span></div>
|
||||
</div></div>`:''}
|
||||
|
||||
${t.attachments?.length?`<div class="card"><div class="card-h">附件 (${t.attachments.length})</div><div class="card-b" style="display:flex;flex-wrap:wrap;gap:10px">
|
||||
${t.attachments.map(a=>a.mime_type.startsWith('image')?`<a href="/api/uploads/${a.stored_name}" target="_blank"><img src="/api/uploads/${a.stored_name}" style="max-width:150px;max-height:120px;border-radius:6px;border:1px solid var(--g200)" title="${U.esc(a.original_name)}"></a>`:`<a href="/api/uploads/${a.stored_name}" target="_blank" class="btn btn-o btn-sm"><i class="fas fa-video"></i> ${U.esc(a.original_name)}</a>`).join('')}
|
||||
</div></div>`:''}
|
||||
@@ -63,6 +67,12 @@ const TicketDetail = {
|
||||
</div></div>
|
||||
`:''}
|
||||
|
||||
${!isStaff && t.user_id === Auth.user().id && ['resolved','rejected','closed'].includes(t.status) && t.type !== 'result_appeal' ? `
|
||||
<div class="card"><div class="card-h">结果申诉</div><div class="card-b">
|
||||
<p class="tm mb-4">对处理结果有异议?可以提交一次申诉,由服主复核。</p>
|
||||
<button class="btn btn-w btn-sm w-full" onclick="TicketDetail.appealResult(${t.id})"><i class="fas fa-gavel"></i> 对结果提出申诉</button>
|
||||
</div></div>`:''}
|
||||
|
||||
${t.transfers?.length?`
|
||||
<div class="card"><div class="card-h">转交历史</div><div class="card-b">
|
||||
<div class="timeline">${t.transfers.map(tf=>`<div class="timeline-item"><div class="th"><span class="tn">${U.esc(tf.from_game_name||tf.from_username)}</span><i class="fas fa-arrow-right ts tm"></i><span class="tn">${U.esc(tf.to_game_name||tf.to_username)}</span><span>${U.date(tf.created_at)}</span></div>${tf.reason?`<div class="tc">${U.esc(tf.reason)}</div>`:''}</div>`).join('')}</div>
|
||||
@@ -104,5 +114,28 @@ const TicketDetail = {
|
||||
document.getElementById('cs-form').onsubmit = async e => { e.preventDefault();
|
||||
try { await API.put(`/tickets/${id}`, {status:document.getElementById('cs-status').value}); App.closeModal(); this.mount(); } catch(ex){alert(ex.message);}
|
||||
};
|
||||
},
|
||||
|
||||
appealResult(parentId) {
|
||||
U.modal('结果申诉', `<form id="ar-form">
|
||||
<div class="form-group"><label>申诉理由 *</label><input id="ar-reason" required placeholder="为什么对该处理结果有异议?"></div>
|
||||
<div class="form-group"><label>详细说明 *</label><textarea id="ar-desc" rows="4" required placeholder="请详细说明情况..."></textarea></div>
|
||||
<div class="alert alert-i ts">申诉后将生成新工单,仅服主可见及处理</div>
|
||||
<div class="modal-f"><button type="button" class="btn btn-o" onclick="App.closeModal()">取消</button><button type="submit" class="btn btn-w"><i class="fas fa-gavel"></i> 提交申诉</button></div>
|
||||
</form>`);
|
||||
document.getElementById('ar-form').onsubmit = async e => { e.preventDefault();
|
||||
try {
|
||||
await API.post('/tickets', {
|
||||
type: 'result_appeal',
|
||||
title: `结果申诉: #${parentId}`,
|
||||
reason: document.getElementById('ar-reason').value,
|
||||
description: document.getElementById('ar-desc').value,
|
||||
parent_ticket_id: parentId,
|
||||
});
|
||||
App.closeModal();
|
||||
alert('申诉已提交,请等待服主处理');
|
||||
this.mount();
|
||||
} catch(ex) { alert(ex.message); }
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user