import { NextRequest, NextResponse } from 'next/server' import { getServerSession } from 'next-auth' import { authOptions } from '@/lib/auth' import { prisma } from '@/lib/prisma' import { isCurrentSuperAdmin } from '@/lib/admin-permissions' import { canUseSystemSettings } from '@/lib/license' export const dynamic = 'force-dynamic' const REQUIRED_CONFIRM_PHRASE = '执行字段迁移' export async function POST(req: NextRequest) { try { const session = await getServerSession(authOptions) if (!session || !(await isCurrentSuperAdmin(session))) { return NextResponse.json( { error: '仅最高权限账号可执行素材字段迁移' }, { status: 403 } ) } if (!(await canUseSystemSettings())) { return NextResponse.json( { error: '当前许可证未包含系统设置功能,请联系管理员处理授权' }, { status: 403 } ) } const body = await req.json().catch(() => ({})) if (body?.confirmPhrase !== REQUIRED_CONFIRM_PHRASE) { return NextResponse.json( { error: '素材字段迁移是高风险操作,请输入确认短语后再执行', requiredConfirmPhrase: REQUIRED_CONFIRM_PHRASE, }, { status: 400 } ) } // 执行 SQL 迁移 - 需要分开执行每个命令 const commands = [ `ALTER TABLE "materials" ADD COLUMN IF NOT EXISTS "brandName" TEXT`, `ALTER TABLE "materials" ADD COLUMN IF NOT EXISTS "seriesName" TEXT`, `ALTER TABLE "materials" ADD COLUMN IF NOT EXISTS "skuCode" TEXT`, `ALTER TABLE "materials" ADD COLUMN IF NOT EXISTS "materialTexture" TEXT`, `ALTER TABLE "materials" ADD COLUMN IF NOT EXISTS "renderTime" TEXT`, `ALTER TABLE "materials" ADD COLUMN IF NOT EXISTS "imageResolution" TEXT`, `ALTER TABLE "materials" ADD COLUMN IF NOT EXISTS "colorMode" TEXT`, `ALTER TABLE "materials" ADD COLUMN IF NOT EXISTS "displayImages" TEXT NOT NULL DEFAULT ''`, `ALTER TABLE "materials" ADD COLUMN IF NOT EXISTS "platformName" TEXT NOT NULL DEFAULT ''`, `ALTER TABLE "materials" ADD COLUMN IF NOT EXISTS "previewUrls" TEXT`, `ALTER TABLE "materials" ADD COLUMN IF NOT EXISTS "metadata" TEXT`, `ALTER TABLE "materials" ADD COLUMN IF NOT EXISTS "templateId" TEXT`, `CREATE INDEX IF NOT EXISTS "materials_platformName_idx" ON "materials"("platformName")`, ] // 执行每个 ALTER TABLE 和 CREATE INDEX 命令 for (const cmd of commands) { try { await prisma.$executeRawUnsafe(cmd) } catch (error: any) { // 如果列已存在,忽略错误 if (error?.message?.includes('already exists')) { // 忽略 } else { throw error } } } // 执行外键约束(使用 $queryRawUnsafe 因为包含 DO 块) const fkCommand = ` DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM pg_constraint WHERE conname = 'materials_templateId_fkey' ) THEN ALTER TABLE "materials" ADD CONSTRAINT "materials_templateId_fkey" FOREIGN KEY ("templateId") REFERENCES "UploadTemplate"("id") ON DELETE SET NULL ON UPDATE CASCADE; END IF; END $$; ` try { await prisma.$queryRawUnsafe(fkCommand) } catch (error: any) { // 忽略外键已存在的错误 if (!error?.message?.includes('already exists')) { throw error } } return NextResponse.json({ message: '迁移成功', success: true }) } catch (error) { console.error('[Migrate] Error:', error) return NextResponse.json( { error: '迁移失败', details: error instanceof Error ? error.message : '未知错误' }, { status: 500 } ) } }