WuYongJie 63ec6b7dfb fix: 修复排行榜按钮消失、tag排序和输入框浅色模式问题
1. 排行榜悬浮窗关闭后小按钮消失问题
   - 修复面板居中模式关闭时按钮位置错误
   - 保存并恢复按钮的居中状态

2. 首页tag按钮按素材数量排序
   - 添加按素材数量降序排序逻辑

3. 上传弹窗输入框浅色模式文字不可见
   - 添加 text-slate-900 确保浅色模式下文字可见
   - 添加 placeholder 样式确保占位符正确显示
2025-12-14 21:41:29 +08:00

159 lines
4.1 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.

/**
* 模板素材迁移 API
*
* POST: 将使用指定模板的素材迁移到另一个模板
*/
import { NextRequest, NextResponse } from 'next/server'
import { getServerSession } from 'next-auth'
import { authOptions } from '@/lib/auth'
import { prisma } from '@/lib/prisma'
async function ensureAdmin() {
const session = await getServerSession(authOptions)
if (!session || (session.user as any)?.role !== 'ADMIN') {
return null
}
return session
}
/**
* POST /api/admin/upload-templates/[id]/migrate
*
* 将使用源模板的素材迁移到目标模板
*
* Body:
* - targetTemplateId: 目标模板ID
* - updateMaterialType: 是否同时更新素材的 materialType 字段(可选,默认 true)
*/
export async function POST(
req: NextRequest,
{ params }: { params: { id: string } }
) {
try {
const session = await ensureAdmin()
if (!session) {
return NextResponse.json({ error: '无权限' }, { status: 403 })
}
const sourceTemplateId = params.id
const body = await req.json()
const { targetTemplateId, updateMaterialType = true } = body
if (!targetTemplateId) {
return NextResponse.json({
error: '请选择目标模板',
errorCode: 'MISSING_TARGET',
}, { status: 400 })
}
if (sourceTemplateId === targetTemplateId) {
return NextResponse.json({
error: '源模板和目标模板不能相同',
errorCode: 'SAME_TEMPLATE',
}, { status: 400 })
}
// 检查源模板是否存在
const sourceTemplate = await prisma.uploadTemplate.findUnique({
where: { id: sourceTemplateId },
select: {
id: true,
name: true,
materialType: true,
_count: { select: { materials: true } }
},
})
if (!sourceTemplate) {
return NextResponse.json({
error: '源模板不存在',
errorCode: 'SOURCE_NOT_FOUND',
}, { status: 404 })
}
// 检查目标模板是否存在
const targetTemplate = await prisma.uploadTemplate.findUnique({
where: { id: targetTemplateId },
select: {
id: true,
name: true,
materialType: true,
},
})
if (!targetTemplate) {
return NextResponse.json({
error: '目标模板不存在',
errorCode: 'TARGET_NOT_FOUND',
}, { status: 404 })
}
const materialCount = sourceTemplate._count.materials
if (materialCount === 0) {
return NextResponse.json({
success: true,
migratedCount: 0,
message: '没有需要迁移的素材',
})
}
console.log('[TemplateMigrate] Starting migration:', {
sourceTemplateId,
sourceTemplateName: sourceTemplate.name,
targetTemplateId,
targetTemplateName: targetTemplate.name,
materialCount,
updateMaterialType,
})
// 构建更新数据
const updateData: any = {
templateId: targetTemplateId,
}
// 如果需要更新 materialType
if (updateMaterialType && targetTemplate.materialType) {
updateData.materialType = targetTemplate.materialType
}
// 批量更新素材
const result = await prisma.material.updateMany({
where: { templateId: sourceTemplateId },
data: updateData,
})
console.log('[TemplateMigrate] Migration completed:', {
sourceTemplateId,
targetTemplateId,
migratedCount: result.count,
})
return NextResponse.json({
success: true,
migratedCount: result.count,
message: `成功将 ${result.count} 个素材从"${sourceTemplate.name}"迁移到"${targetTemplate.name}"`,
sourceTemplate: {
id: sourceTemplate.id,
name: sourceTemplate.name,
},
targetTemplate: {
id: targetTemplate.id,
name: targetTemplate.name,
},
})
} catch (error: any) {
console.error('[TemplateMigrate] Migration error:', {
sourceTemplateId: params.id,
error: error?.message,
stack: error?.stack,
})
return NextResponse.json({
error: error?.message || '迁移失败',
errorCode: 'MIGRATION_FAILED',
}, { status: 500 })
}
}