feat: batch ticket operations (close/delete/change status)

This commit is contained in:
2026-07-17 21:55:15 +08:00
parent ed6fe9dcf1
commit 5497de9aac
2 changed files with 61 additions and 1 deletions

View File

@@ -259,6 +259,32 @@ router.post('/:id/transfer', authenticate, requireRole('owner','admin'), async (
res.json({ message: '转交成功' });
});
router.post('/batch', authenticate, requireRole('owner','admin'), async (req, res) => {
const { ids, action, status } = req.body;
if (!ids || !Array.isArray(ids) || ids.length === 0) return res.status(400).json({ error: '请选择工单' });
if (!['delete','status','close'].includes(action)) return res.status(400).json({ error: '无效操作' });
const pool = await getPool();
const conn = await pool.getConnection();
try {
await conn.beginTransaction();
for (const id of ids) {
if (action === 'delete') {
await conn.execute('DELETE FROM responses WHERE ticket_id = ?', [id]);
await conn.execute('DELETE FROM attachments WHERE ticket_id = ?', [id]);
await conn.execute('DELETE FROM ticket_transfers WHERE ticket_id = ?', [id]);
await conn.execute('DELETE FROM tickets WHERE id = ?', [id]);
} else {
const s = action === 'close' ? 'closed' : (status || 'closed');
await conn.execute('UPDATE tickets SET status = ? WHERE id = ?', [s, id]);
await conn.execute("INSERT INTO responses(ticket_id, user_id, content, is_staff) VALUES (?,?,?,1)", [id, req.user.id, `【批量】状态变更为: ${SL[s]||s}`]);
}
}
await conn.commit();
res.json({ message: `已处理 ${ids.length} 个工单` });
} catch(e) { await conn.rollback(); conn.release(); return res.status(500).json({ error: e.message }); }
conn.release();
});
router.post('/:id/response', authenticate, async (req, res) => {
const { content } = req.body;
if (!content) return res.status(400).json({ error: '内容不能为空' });