/** * 分类字段配置 API * * 支持查询「哪些字段可用于分类管理」以及启用/停用指定字段 * 这样管理字段无需回到模板编辑器逐一勾选。 */ import { NextRequest, NextResponse } from 'next/server' import { getServerSession } from 'next-auth' import { authOptions } from '@/lib/auth' import { isCurrentSuperAdmin } from '@/lib/admin-permissions' import { getFieldPoolRecords, syncFieldPoolFromTemplates } from '@/lib/field-pool' import { prisma } from '@/lib/prisma' type FieldPoolRecord = { key: string label: string filterDisplayName?: string | null source: string type: string isFilterEnabled: boolean filterOrder?: number | null } export async function GET() { const session = await getServerSession(authOptions) if (!session || (session.user as any)?.role !== 'ADMIN') { return NextResponse.json({ error: '权限不足' }, { status: 403 }) } const fields = (await getFieldPoolRecords()) as FieldPoolRecord[] const managedFields = fields .filter((field: FieldPoolRecord) => field.isFilterEnabled) .map((field: FieldPoolRecord) => field.key) const availableFields = fields.map((field: FieldPoolRecord) => ({ key: field.key, label: field.filterDisplayName || field.label, source: field.source === 'standard' ? 'standard' : 'custom', type: field.type, filterDisplayName: field.filterDisplayName, filterOrder: field.filterOrder ?? 0, })) return NextResponse.json({ managedFields, availableFields, }) } export async function POST() { try { const session = await getServerSession(authOptions) if (!session || !(await isCurrentSuperAdmin(session))) { return NextResponse.json({ error: '仅最高权限账号可同步分类字段' }, { status: 403 }) } await syncFieldPoolFromTemplates() const fields = (await getFieldPoolRecords()) as FieldPoolRecord[] return NextResponse.json({ success: true, managedFields: fields.filter((field) => field.isFilterEnabled).map((field) => field.key), availableFields: fields.map((field) => ({ key: field.key, label: field.filterDisplayName || field.label, source: field.source === 'standard' ? 'standard' : 'custom', type: field.type, filterDisplayName: field.filterDisplayName, filterOrder: field.filterOrder ?? 0, })), }) } catch (error) { console.error('Sync category fields failed:', error) return NextResponse.json({ error: '同步失败' }, { status: 500 }) } } export async function PATCH(req: NextRequest) { try { const session = await getServerSession(authOptions) if (!session || !(await isCurrentSuperAdmin(session))) { return NextResponse.json({ error: '仅最高权限账号可修改分类字段配置' }, { status: 403 }) } const { fieldKey, enabled } = await req.json() if (typeof fieldKey !== 'string' || typeof enabled !== 'boolean') { return NextResponse.json({ error: '参数错误' }, { status: 400 }) } const field = await prisma.fieldDefinition.findUnique({ where: { key: fieldKey }, }) if (!field) { return NextResponse.json({ error: '未找到该字段' }, { status: 404 }) } await prisma.fieldDefinition.update({ where: { id: field.id }, data: { isFilterEnabled: enabled, }, }) return NextResponse.json({ success: true }) } catch (error) { console.error('Update category fields failed:', error) return NextResponse.json({ error: '更新失败' }, { status: 500 }) } } export async function PUT(req: NextRequest) { const session = await getServerSession(authOptions) if (!session || !(await isCurrentSuperAdmin(session))) { return NextResponse.json({ error: '仅最高权限账号可修改分类字段配置' }, { status: 403 }) } try { const { updates } = await req.json() if (!Array.isArray(updates)) { return NextResponse.json({ error: '参数错误' }, { status: 400 }) } const normalizedUpdates = updates .map((item: any, index: number) => { if (!item || typeof item.fieldKey !== 'string') { return null } const payload: { fieldKey: string; filterDisplayName?: string | null; filterOrder?: number } = { fieldKey: item.fieldKey, } if (typeof item.filterDisplayName === 'string') { payload.filterDisplayName = item.filterDisplayName.trim() || null } else if (item.filterDisplayName === null) { payload.filterDisplayName = null } if (typeof item.filterOrder === 'number' && Number.isFinite(item.filterOrder)) { payload.filterOrder = item.filterOrder } else { payload.filterOrder = index } return payload }) .filter((item): item is { fieldKey: string; filterDisplayName?: string | null; filterOrder?: number } => !!item) if (!normalizedUpdates.length) { return NextResponse.json({ error: '缺少有效的字段更新' }, { status: 400 }) } await prisma.$transaction(async (tx) => { for (const update of normalizedUpdates) { await tx.fieldDefinition.update({ where: { key: update.fieldKey }, data: { filterDisplayName: update.filterDisplayName ?? null, filterOrder: update.filterOrder ?? 0, }, }) } }) return NextResponse.json({ success: true }) } catch (error) { console.error('Reorder/rename category fields failed:', error) return NextResponse.json({ error: '保存失败' }, { status: 500 }) } }