72 lines
2.9 KiB
TypeScript
72 lines
2.9 KiB
TypeScript
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 { exportTicketsToExcel } from '@/lib/excel'
|
|
import { writeAuditLog, getClientIP } from '@/lib/audit'
|
|
|
|
export async function GET(request: NextRequest) {
|
|
try {
|
|
initDatabase()
|
|
const user = await getCurrentUser()
|
|
if (!user) return NextResponse.json({ error: '未登录' }, { status: 401 })
|
|
if (!hasPermission(user, 'tickets:export')) return NextResponse.json({ error: '权限不足' }, { status: 403 })
|
|
|
|
const { searchParams } = request.nextUrl
|
|
const idsParam = searchParams.get('ids')
|
|
|
|
const db = getDb()
|
|
let tickets: Array<Record<string, unknown>>
|
|
|
|
if (idsParam) {
|
|
// 导出选中的工单
|
|
const ids = idsParam.split(',').map(Number).filter(n => !isNaN(n))
|
|
if (ids.length === 0) {
|
|
return NextResponse.json({ error: '无效的工单 ID' }, { status: 400 })
|
|
}
|
|
const placeholders = ids.map(() => '?').join(',')
|
|
tickets = db.prepare(`SELECT * FROM tickets WHERE id IN (${placeholders}) ORDER BY created_at DESC`).all(...ids) as Array<Record<string, unknown>>
|
|
} else {
|
|
// 导出筛选后的工单(保持原有逻辑)
|
|
const status = searchParams.get('status') || ''
|
|
const category = searchParams.get('category') || ''
|
|
const startDate = searchParams.get('startDate') || ''
|
|
const endDate = searchParams.get('endDate') || ''
|
|
|
|
const conditions: string[] = []
|
|
const params: unknown[] = []
|
|
|
|
if (status) { conditions.push('current_status = ?'); params.push(status) }
|
|
if (category) { conditions.push('fault_category = ?'); params.push(category) }
|
|
if (startDate) { conditions.push('assign_time >= ?'); params.push(startDate) }
|
|
if (endDate) { conditions.push('assign_time <= ?'); params.push(endDate) }
|
|
|
|
const where = conditions.length ? `WHERE ${conditions.join(' AND ')}` : ''
|
|
tickets = db.prepare(`SELECT * FROM tickets ${where} ORDER BY created_at DESC`).all(...params) as Array<Record<string, unknown>>
|
|
}
|
|
|
|
const buffer = exportTicketsToExcel(tickets)
|
|
|
|
writeAuditLog({
|
|
userId: user.id,
|
|
apiKeyId: null,
|
|
action: 'export',
|
|
entityType: 'ticket',
|
|
entityId: null,
|
|
details: { count: tickets.length },
|
|
ipAddress: getClientIP(request),
|
|
})
|
|
|
|
return new NextResponse(new Uint8Array(buffer), {
|
|
headers: {
|
|
'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
'Content-Disposition': `attachment; filename="tickets_${new Date().toISOString().slice(0, 10)}.xlsx"`,
|
|
},
|
|
})
|
|
} catch (e) {
|
|
const msg = e instanceof Error ? e.message : '导出失败'
|
|
return NextResponse.json({ error: msg }, { status: 500 })
|
|
}
|
|
}
|