import { NextRequest, NextResponse } from "next/server"; import { db } from "@/lib/db"; import { generatedImage, user } from "@/lib/db/schema"; import { eq, desc, sql, and, gte, lte, like, or } from "drizzle-orm"; import { auth } from "@/app/(auth)/auth"; export async function GET(request: NextRequest) { try { const session = await auth(); if (!session?.user?.id) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } // 检查是否为管理员 const currentUser = await db.query.user.findFirst({ where: eq(user.id, session.user.id), }); if (currentUser?.role !== "admin") { return NextResponse.json({ error: "Forbidden" }, { status: 403 }); } // 获取查询参数 const searchParams = request.nextUrl.searchParams; const page = Number.parseInt(searchParams.get("page") || "1"); const pageSize = Number.parseInt(searchParams.get("pageSize") || "200"); const offset = (page - 1) * pageSize; const search = searchParams.get("search") || ""; const startDate = searchParams.get("startDate"); const endDate = searchParams.get("endDate"); // 构建查询条件 const conditions = []; if (search) { // 搜索用户名或邮箱 const matchingUsers = await db .select({ id: user.id }) .from(user) .where(or( like(user.name, `%${search}%`), like(user.email, `%${search}%`) )); if (matchingUsers.length > 0) { const userIds = matchingUsers.map(u => u.id); conditions.push(sql`${generatedImage.userId} IN (${sql.join(userIds.map(id => sql`${id}`), sql`, `)})`); } else { // 没有匹配的用户,返回空结果 return NextResponse.json({ images: [], pagination: { page, pageSize, total: 0, totalPages: 0 } }); } } if (startDate) { conditions.push(gte(generatedImage.createdAt, new Date(startDate))); } if (endDate) { const end = new Date(endDate); end.setHours(23, 59, 59, 999); conditions.push(lte(generatedImage.createdAt, end)); } const whereClause = conditions.length > 0 ? and(...conditions) : undefined; // 查询总数 const countResult = await db .select({ count: sql`count(*)::int` }) .from(generatedImage) .where(whereClause); const total = countResult[0]?.count || 0; // 查询图片列表(包含用户信息) const images = await db .select({ id: generatedImage.id, userId: generatedImage.userId, userName: user.name, userEmail: user.email, userDepartment: user.department, thumbnailUrl: generatedImage.thumbnailUrl, originalUrl: generatedImage.originalUrl, imageSize: generatedImage.imageSize, prompt: generatedImage.prompt, modelId: generatedImage.modelId, isFeatured: generatedImage.isFeatured, featuredAt: generatedImage.featuredAt, createdAt: generatedImage.createdAt, chatId: generatedImage.chatId, }) .from(generatedImage) .leftJoin(user, eq(generatedImage.userId, user.id)) .where(whereClause) .orderBy(desc(generatedImage.createdAt)) .limit(pageSize) .offset(offset); const totalPages = Math.ceil(total / pageSize); return NextResponse.json({ images, pagination: { page, pageSize, total, totalPages } }); } catch (error) { console.error("[Admin Images API] Error:", error); return NextResponse.json({ error: "Failed to fetch images" }, { status: 500 }); } } // PATCH: 设置/取消图片精选 export async function PATCH(request: NextRequest) { try { const session = await auth(); if (!session?.user?.id) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } // 检查是否为管理员 const currentUser = await db.query.user.findFirst({ where: eq(user.id, session.user.id), }); if (currentUser?.role !== "admin") { return NextResponse.json({ error: "Forbidden" }, { status: 403 }); } const body = await request.json(); const { imageId, isFeatured } = body; if (!imageId) { return NextResponse.json({ error: "Image ID is required" }, { status: 400 }); } // 更新精选状态 const updateData: Record = { isFeatured: Boolean(isFeatured), }; if (isFeatured) { updateData.featuredAt = new Date(); updateData.featuredBy = session.user.id; } else { updateData.featuredAt = null; updateData.featuredBy = null; } await db .update(generatedImage) .set(updateData) .where(eq(generatedImage.id, imageId)); console.log(`[Admin Images API] Image ${imageId} featured status set to ${isFeatured} by ${session.user.id}`); return NextResponse.json({ success: true, message: isFeatured ? "已添加到精选" : "已取消精选" }); } catch (error) { console.error("[Admin Images API] PATCH Error:", error); return NextResponse.json({ error: "Failed to update featured status" }, { status: 500 }); } }