Files
chinese-family-tree-2/app/api/upload/route.ts
T
freedakgmail 3d075c6076 0.0.8.5
2025-11-24 14:02:34 +08:00

71 lines
2.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { NextRequest, NextResponse } from 'next/server'
import { writeFile, mkdir } from 'fs/promises'
import { join } from 'path'
import { existsSync } from 'fs'
import { getServerSession } from 'next-auth'
import { authOptions } from '@/lib/auth'
export async function POST(req: NextRequest) {
try {
// 验证用户登录
const session = await getServerSession(authOptions)
if (!session?.user?.id) {
return NextResponse.json({ error: '未授权' }, { status: 401 })
}
const formData = await req.formData()
const file = formData.get('file') as File
if (!file) {
return NextResponse.json({ error: '没有文件' }, { status: 400 })
}
// 验证文件类型
if (!file.type.startsWith('image/')) {
return NextResponse.json({ error: '只能上传图片文件' }, { status: 400 })
}
// 验证文件大小(限制为 5MB
const maxSize = 5 * 1024 * 1024 // 5MB
if (file.size > maxSize) {
return NextResponse.json({ error: '文件大小不能超过 5MB' }, { status: 400 })
}
// 读取文件内容
const bytes = await file.arrayBuffer()
const buffer = Buffer.from(bytes)
// 确保上传目录存在
const uploadDir = join(process.cwd(), 'public', 'uploads')
if (!existsSync(uploadDir)) {
await mkdir(uploadDir, { recursive: true })
}
// 生成唯一文件名
const timestamp = Date.now()
const randomStr = Math.random().toString(36).substring(2, 8)
const ext = file.name.split('.').pop()
const fileName = `${timestamp}-${randomStr}.${ext}`
// 保存文件
const filePath = join(uploadDir, fileName)
await writeFile(filePath, buffer)
// 返回可访问的 URL
const url = `/uploads/${fileName}`
return NextResponse.json({
url,
fileName,
size: file.size,
type: file.type,
})
} catch (error) {
console.error('上传文件失败:', error)
return NextResponse.json(
{ error: '上传文件失败' },
{ status: 500 }
)
}
}