import { NextRequest, NextResponse } from 'next/server' import { getDb } from '@/lib/db' import { initDatabase } from '@/lib/db-schema' import { getCurrentUser } from '@/lib/auth' import { hasPermission } from '@/lib/permissions' import { getAssetByIp } from '@/lib/assets-client' export async function GET(_request: NextRequest, { params }: { params: Promise<{ id: string }> }) { try { initDatabase() const user = await getCurrentUser() if (!user) return NextResponse.json({ error: '未登录' }, { status: 401 }) const { id } = await params const db = getDb() const ticket = db.prepare('SELECT * FROM tickets WHERE id = ?').get(id) if (!ticket) return NextResponse.json({ error: '工单不存在' }, { status: 404 }) const steps = db.prepare('SELECT * FROM ticket_steps WHERE ticket_id = ? ORDER BY step_order').all((ticket as any).id) // Try to get device info from assets API let assetInfo = null const t = ticket as any if (t.device_ip) { try { assetInfo = await getAssetByIp(t.device_ip) } catch { // Assets API may not be available } } return NextResponse.json({ ticket, steps, assetInfo }) } catch (e) { const msg = e instanceof Error ? e.message : '查询失败' return NextResponse.json({ error: msg }, { status: 500 }) } } export async function PUT(request: NextRequest, { params }: { params: Promise<{ id: string }> }) { try { initDatabase() const user = await getCurrentUser() if (!user) return NextResponse.json({ error: '未登录' }, { status: 401 }) if (!hasPermission(user, 'tickets:write')) return NextResponse.json({ error: '权限不足' }, { status: 403 }) const { id } = await params const body = await request.json() const db = getDb() const existing = db.prepare('SELECT * FROM tickets WHERE id = ?').get(id) as Record if (!existing) return NextResponse.json({ error: '工单不存在' }, { status: 404 }) // 非管理员不可编辑已办工单 const completedStatuses = ['resolved', 'closed'] if (user.role !== 'admin' && completedStatuses.includes(existing.current_status as string)) { return NextResponse.json({ error: '已办工单仅管理员可修改' }, { status: 403 }) } // 自动计算处理时长 if (body.close_time && existing.assign_time) { const assignMs = new Date(existing.assign_time as string).getTime() const closeMs = new Date(body.close_time).getTime() if (!isNaN(assignMs) && !isNaN(closeMs)) { body.duration_minutes = Math.round((closeMs - assignMs) / 60000) } } // resolved 但未传 close_time 时自动设置为北京时间 if (body.current_status === 'resolved' && !body.close_time && !existing.close_time) { const d = new Date(Date.now() + 8 * 60 * 60 * 1000) body.close_time = d.toISOString().slice(0, 19) } const fields: string[] = [] const values: unknown[] = [] const updatable = [ 'device_ip', 'device_sn', 'device_name', 'content', 'assign_time', 'close_time', 'duration_minutes', 'availability', 'process_summary', 'conclusion', 'ticket_type', 'fault_category', 'fault_subcategory', 'parts_replaced', 'parts_name', 'current_status', 'counted_in_sla', 'responsibility', ] for (const key of updatable) { if (key in body) { fields.push(`${key} = ?`) values.push(body[key]) } } if (fields.length > 0) { fields.push('updated_by = ?') values.push(user.id) fields.push("updated_at = datetime('now')") values.push(id) db.prepare(`UPDATE tickets SET ${fields.join(', ')} WHERE id = ?`).run(...values) } // Update steps if provided if (body.steps && Array.isArray(body.steps)) { db.prepare('DELETE FROM ticket_steps WHERE ticket_id = ?').run(id) const stmt = db.prepare('INSERT INTO ticket_steps (ticket_id, step_order, time_node, handler, description) VALUES (?, ?, ?, ?, ?)') for (let i = 0; i < body.steps.length; i++) { const step = body.steps[i] stmt.run(id, i + 1, step.time_node || null, step.handler || null, step.description || null) } } const ticket = db.prepare('SELECT * FROM tickets WHERE id = ?').get(id) return NextResponse.json({ ticket }) } catch (e) { const msg = e instanceof Error ? e.message : '更新失败' return NextResponse.json({ error: msg }, { status: 500 }) } } export async function DELETE(_request: NextRequest, { params }: { params: Promise<{ id: string }> }) { try { initDatabase() const user = await getCurrentUser() if (!user) return NextResponse.json({ error: '未登录' }, { status: 401 }) if (!hasPermission(user, 'tickets:write')) return NextResponse.json({ error: '权限不足' }, { status: 403 }) const { id } = await params const db = getDb() const existing = db.prepare('SELECT current_status, created_by FROM tickets WHERE id = ?').get(id) as { current_status: string; created_by: number | null } | undefined if (!existing) return NextResponse.json({ error: '工单不存在' }, { status: 404 }) // 非管理员不可删除已办工单,非创建人不可删除待办工单 const completedStatuses = ['resolved', 'closed'] if (user.role !== 'admin') { if (completedStatuses.includes(existing.current_status)) { return NextResponse.json({ error: '已办工单仅管理员可删除' }, { status: 403 }) } if (existing.created_by !== user.id) { return NextResponse.json({ error: '仅创建人和管理员可删除此工单' }, { status: 403 }) } } db.prepare('DELETE FROM tickets WHERE id = ?').run(id) return NextResponse.json({ success: true }) } catch (e) { const msg = e instanceof Error ? e.message : '删除失败' return NextResponse.json({ error: msg }, { status: 500 }) } }