/** * 视频转码统计 API(管理员) * * 提供转码任务的统计信息 */ import { NextRequest, NextResponse } from 'next/server' import { getServerSession } from 'next-auth' import { authOptions } from '@/lib/auth' import { prisma } from '@/lib/prisma' import { transcodeQueue } from '@/lib/video-transcode-queue' import { isCurrentAdmin } from '@/lib/admin-permissions' export const dynamic = 'force-dynamic' /** * GET /api/admin/video-transcode-stats * 获取转码统计信息 */ export async function GET(req: NextRequest) { try { const session = await getServerSession(authOptions) if (!session) { return NextResponse.json( { error: '未登录' }, { status: 401 } ) } if (!(await isCurrentAdmin(session))) { return NextResponse.json( { error: '需要管理员权限' }, { status: 403 } ) } // 获取转码队列状态 const queueStatus = transcodeQueue.getStatus() // 统计数据库中的转码状态 const [pendingCount, processingCount, doneCount, failedCount] = await Promise.all([ prisma.material.count({ where: { materialKind: 'VIDEO', videoProcessingStatus: 'pending', }, }), prisma.material.count({ where: { materialKind: 'VIDEO', videoProcessingStatus: 'processing', }, }), prisma.material.count({ where: { materialKind: 'VIDEO', videoProcessingStatus: 'done', }, }), prisma.material.count({ where: { materialKind: 'VIDEO', videoProcessingStatus: 'failed', }, }), ]) const [queuedJobCount, processingJobCount, failedJobCount] = await Promise.all([ (prisma as any).videoTranscodeJob.count({ where: { status: 'queued' }, }), (prisma as any).videoTranscodeJob.count({ where: { status: 'processing' }, }), (prisma as any).videoTranscodeJob.count({ where: { status: 'failed' }, }), ]) // 获取最近失败的转码任务(最多10个) const recentFailed = await prisma.material.findMany({ where: { materialKind: 'VIDEO', videoProcessingStatus: 'failed', }, select: { id: true, productModel: true, categoryName: true, sceneName: true, createdAt: true, updatedAt: true, }, orderBy: { updatedAt: 'desc', }, take: 10, }) return NextResponse.json({ queue: { queueLength: queueStatus.queueLength, processingCount: queueStatus.processingCount, maxConcurrent: queueStatus.maxConcurrent, processingIds: queueStatus.processingIds, queuedIds: queueStatus.queuedIds, }, statistics: { pending: pendingCount, processing: processingCount, done: doneCount, failed: failedCount, total: pendingCount + processingCount + doneCount + failedCount, }, jobs: { queued: queuedJobCount, processing: processingJobCount, failed: failedJobCount, }, recentFailed: recentFailed.map((m) => ({ id: m.id, name: `${m.productModel}_${m.categoryName}_${m.sceneName}`, createdAt: m.createdAt, failedAt: m.updatedAt, })), }) } catch (error) { console.error('[TranscodeStats] Error:', error) return NextResponse.json( { error: '获取统计信息失败' }, { status: 500 } ) } }