feat: auto-close resolved/rejected after 7 days, closed only owner can modify
This commit is contained in:
@@ -16,7 +16,14 @@ const SO = { processing:1, awaiting_info:2, appealing:3, pending:4, resolved:5,
|
|||||||
|
|
||||||
async function siteUrl() { const r = await getRow("SELECT v FROM settings WHERE k='site_url'"); return r?.v || 'http://localhost:3100'; }
|
async function siteUrl() { const r = await getRow("SELECT v FROM settings WHERE k='site_url'"); return r?.v || 'http://localhost:3100'; }
|
||||||
|
|
||||||
|
async function autoCloseExpired() {
|
||||||
|
try {
|
||||||
|
await query(`UPDATE tickets SET status = 'closed' WHERE status IN ('resolved','rejected') AND updated_at < NOW() - INTERVAL 7 DAY`);
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
router.get('/', authenticate, async (req, res) => {
|
router.get('/', authenticate, async (req, res) => {
|
||||||
|
await autoCloseExpired();
|
||||||
let q = `SELECT t.*, u.game_name as user_game_name, u.username as submitter, a.game_name as assignee_name
|
let q = `SELECT t.*, u.game_name as user_game_name, u.username as submitter, a.game_name as assignee_name
|
||||||
FROM tickets t LEFT JOIN users u ON t.user_id = u.id LEFT JOIN users a ON t.assigned_to = a.id`;
|
FROM tickets t LEFT JOIN users u ON t.user_id = u.id LEFT JOIN users a ON t.assigned_to = a.id`;
|
||||||
const conds = [], params = [];
|
const conds = [], params = [];
|
||||||
@@ -78,6 +85,7 @@ router.get('/tracking', async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
router.get('/:id', authenticate, async (req, res) => {
|
router.get('/:id', authenticate, async (req, res) => {
|
||||||
|
await autoCloseExpired();
|
||||||
const t = await getRow(`SELECT t.*, u.game_name as user_game_name, u.username as submitter, a.game_name as assignee_name, a.username as assignee_username
|
const t = await getRow(`SELECT t.*, u.game_name as user_game_name, u.username as submitter, a.game_name as assignee_name, a.username as assignee_username
|
||||||
FROM tickets t LEFT JOIN users u ON t.user_id = u.id LEFT JOIN users a ON t.assigned_to = a.id WHERE t.id = ?`, [req.params.id]);
|
FROM tickets t LEFT JOIN users u ON t.user_id = u.id LEFT JOIN users a ON t.assigned_to = a.id WHERE t.id = ?`, [req.params.id]);
|
||||||
if (!t) return res.status(404).json({ error: '工单不存在' });
|
if (!t) return res.status(404).json({ error: '工单不存在' });
|
||||||
@@ -172,7 +180,7 @@ router.post('/', optionalAuth, upload.array('files', 5), finalizeUpload, validat
|
|||||||
router.put('/:id', authenticate, requireRole('owner','admin'), async (req, res) => {
|
router.put('/:id', authenticate, requireRole('owner','admin'), async (req, res) => {
|
||||||
const t = await getRow('SELECT * FROM tickets WHERE id = ?', [req.params.id]);
|
const t = await getRow('SELECT * FROM tickets WHERE id = ?', [req.params.id]);
|
||||||
if (!t) return res.status(404).json({ error: '工单不存在' });
|
if (!t) return res.status(404).json({ error: '工单不存在' });
|
||||||
if (t.status === 'closed') return res.status(400).json({ error: '已关闭的工单不可再修改' });
|
if (t.status === 'closed' && req.user.role !== 'owner') return res.status(400).json({ error: '已关闭的工单仅服主可操作' });
|
||||||
const fields = {};
|
const fields = {};
|
||||||
if (req.body.status) fields.status = req.body.status;
|
if (req.body.status) fields.status = req.body.status;
|
||||||
if (req.body.priority) fields.priority = req.body.priority;
|
if (req.body.priority) fields.priority = req.body.priority;
|
||||||
@@ -199,7 +207,7 @@ router.post('/:id/claim', authenticate, requireRole('owner','admin'), async (req
|
|||||||
const t = await getRow('SELECT * FROM tickets WHERE id = ?', [req.params.id]);
|
const t = await getRow('SELECT * FROM tickets WHERE id = ?', [req.params.id]);
|
||||||
if (!t) return res.status(404).json({ error: '工单不存在' });
|
if (!t) return res.status(404).json({ error: '工单不存在' });
|
||||||
if (t.assigned_to && t.assigned_to !== req.user.id && t.status !== 'pending') return res.status(400).json({ error: '该工单已被他人认领' });
|
if (t.assigned_to && t.assigned_to !== req.user.id && t.status !== 'pending') return res.status(400).json({ error: '该工单已被他人认领' });
|
||||||
if (t.status === 'closed') return res.status(400).json({ error: '已关闭的工单不可认领' });
|
if (t.status === 'closed' && req.user.role !== 'owner') return res.status(400).json({ error: '已关闭的工单仅服主可操作' });
|
||||||
if (t.type === 'suggestion' && req.user.role !== 'owner') return res.status(403).json({ error: '建议工单仅服主可处理' });
|
if (t.type === 'suggestion' && req.user.role !== 'owner') return res.status(403).json({ error: '建议工单仅服主可处理' });
|
||||||
if ((t.type === 'result_appeal' || t.is_admin_complaint) && req.user.role !== 'owner') return res.status(403).json({ error: '该工单仅服主可处理' });
|
if ((t.type === 'result_appeal' || t.is_admin_complaint) && req.user.role !== 'owner') return res.status(403).json({ error: '该工单仅服主可处理' });
|
||||||
|
|
||||||
@@ -220,7 +228,7 @@ router.post('/:id/claim', authenticate, requireRole('owner','admin'), async (req
|
|||||||
router.post('/:id/transfer', authenticate, requireRole('owner','admin'), async (req, res) => {
|
router.post('/:id/transfer', authenticate, requireRole('owner','admin'), async (req, res) => {
|
||||||
const t = await getRow('SELECT * FROM tickets WHERE id = ?', [req.params.id]);
|
const t = await getRow('SELECT * FROM tickets WHERE id = ?', [req.params.id]);
|
||||||
if (!t) return res.status(404).json({ error: '工单不存在' });
|
if (!t) return res.status(404).json({ error: '工单不存在' });
|
||||||
if (t.status === 'closed') return res.status(400).json({ error: '已关闭的工单不可转交' });
|
if (t.status === 'closed' && req.user.role !== 'owner') return res.status(400).json({ error: '已关闭的工单仅服主可操作' });
|
||||||
if (t.assigned_to !== req.user.id && req.user.role !== 'owner') return res.status(403).json({ error: '只能转交自己负责的工单' });
|
if (t.assigned_to !== req.user.id && req.user.role !== 'owner') return res.status(403).json({ error: '只能转交自己负责的工单' });
|
||||||
const { to_user_id, reason } = req.body;
|
const { to_user_id, reason } = req.body;
|
||||||
if (!to_user_id) return res.status(400).json({ error: '请选择转交目标' });
|
if (!to_user_id) return res.status(400).json({ error: '请选择转交目标' });
|
||||||
|
|||||||
Reference in New Issue
Block a user