1. 排行榜悬浮窗关闭后小按钮消失问题 - 修复面板居中模式关闭时按钮位置错误 - 保存并恢复按钮的居中状态 2. 首页tag按钮按素材数量排序 - 添加按素材数量降序排序逻辑 3. 上传弹窗输入框浅色模式文字不可见 - 添加 text-slate-900 确保浅色模式下文字可见 - 添加 placeholder 样式确保占位符正确显示
183 lines
5.7 KiB
TypeScript
183 lines
5.7 KiB
TypeScript
/**
|
||
* 数据迁移脚本:迁移旧素材的templateId
|
||
*
|
||
* 功能:
|
||
* 1. 为没有templateId的素材分配默认模板
|
||
* 2. 验证所有模板的version字段
|
||
* 3. 验证数据完整性
|
||
*/
|
||
|
||
import { PrismaClient } from '@prisma/client'
|
||
|
||
const prisma = new PrismaClient()
|
||
|
||
// 内置模板映射
|
||
const BUILTIN_TEMPLATES: Record<string, string> = {
|
||
'3DMAX': 'builtin-3dmax-material',
|
||
'PSD': 'builtin-psd-material',
|
||
'音频': 'builtin-audio-material',
|
||
'视频': 'builtin-video-material',
|
||
'模型': 'builtin-model-material',
|
||
'其他': 'builtin-other-material',
|
||
}
|
||
|
||
async function migrateTemplateData() {
|
||
console.log('开始数据迁移...\n')
|
||
|
||
try {
|
||
// 1. 检查并更新模板version字段
|
||
console.log('步骤 1: 检查模板version字段...')
|
||
const templatesWithoutVersion = await prisma.uploadTemplate.findMany({
|
||
where: {
|
||
OR: [
|
||
{ version: { equals: 0 } },
|
||
{ version: { lt: 1 } }
|
||
]
|
||
},
|
||
select: { id: true }
|
||
})
|
||
|
||
if (templatesWithoutVersion.length > 0) {
|
||
console.log(`发现 ${templatesWithoutVersion.length} 个模板version字段异常,正在更新...`)
|
||
for (const template of templatesWithoutVersion) {
|
||
await prisma.uploadTemplate.update({
|
||
where: { id: template.id },
|
||
data: { version: 1 }
|
||
})
|
||
}
|
||
console.log('✓ 模板version字段更新完成\n')
|
||
} else {
|
||
console.log('✓ 所有模板都有version字段\n')
|
||
}
|
||
|
||
// 2. 迁移没有templateId的素材
|
||
console.log('步骤 2: 检查没有templateId的素材...')
|
||
const materialsWithoutTemplate = await prisma.material.findMany({
|
||
where: {
|
||
templateId: null,
|
||
deletedAt: null // 只处理未删除的素材
|
||
},
|
||
select: {
|
||
id: true,
|
||
materialType: true,
|
||
materialKind: true
|
||
}
|
||
})
|
||
|
||
if (materialsWithoutTemplate.length > 0) {
|
||
console.log(`发现 ${materialsWithoutTemplate.length} 个素材没有templateId,正在分配默认模板...`)
|
||
|
||
let successCount = 0
|
||
let errorCount = 0
|
||
|
||
for (const material of materialsWithoutTemplate) {
|
||
try {
|
||
// 根据materialType分配内置模板
|
||
const templateId = BUILTIN_TEMPLATES[material.materialType] || 'builtin-other-material'
|
||
|
||
await prisma.material.update({
|
||
where: { id: material.id },
|
||
data: { templateId }
|
||
})
|
||
|
||
successCount++
|
||
if (successCount % 100 === 0) {
|
||
console.log(` 已处理 ${successCount}/${materialsWithoutTemplate.length} 个素材...`)
|
||
}
|
||
} catch (error) {
|
||
console.error(` ✗ 处理素材失败: ${material.id}`, error)
|
||
errorCount++
|
||
}
|
||
}
|
||
|
||
console.log(`✓ 素材templateId迁移完成: 成功 ${successCount}, 失败 ${errorCount}\n`)
|
||
} else {
|
||
console.log('✓ 所有素材都有templateId\n')
|
||
}
|
||
|
||
// 3. 验证数据完整性
|
||
console.log('步骤 3: 验证数据完整性...')
|
||
|
||
// 3.1 检查模板
|
||
const totalTemplates = await prisma.uploadTemplate.count()
|
||
const templatesWithVersion = await prisma.uploadTemplate.count({
|
||
where: { version: { gte: 1 } }
|
||
})
|
||
console.log(` 模板总数: ${totalTemplates}`)
|
||
console.log(` 有version的模板: ${templatesWithVersion}`)
|
||
|
||
if (totalTemplates !== templatesWithVersion) {
|
||
console.warn(` ⚠ 警告: ${totalTemplates - templatesWithVersion} 个模板没有version字段`)
|
||
}
|
||
|
||
// 3.2 检查素材
|
||
const totalMaterials = await prisma.material.count({
|
||
where: { deletedAt: null }
|
||
})
|
||
const materialsWithTemplate = await prisma.material.count({
|
||
where: {
|
||
NOT: { templateId: null },
|
||
deletedAt: null
|
||
}
|
||
})
|
||
console.log(` 素材总数(未删除): ${totalMaterials}`)
|
||
console.log(` 有templateId的素材: ${materialsWithTemplate}`)
|
||
|
||
if (totalMaterials !== materialsWithTemplate) {
|
||
console.warn(` ⚠ 警告: ${totalMaterials - materialsWithTemplate} 个素材没有templateId`)
|
||
}
|
||
|
||
// 3.3 检查字段
|
||
const totalFields = await prisma.uploadField.count()
|
||
const fieldsWithTemplate = await prisma.uploadField.count({
|
||
where: { templateId: { not: '' } }
|
||
})
|
||
console.log(` 字段总数: ${totalFields}`)
|
||
console.log(` 有templateId的字段: ${fieldsWithTemplate}`)
|
||
|
||
// 3.4 检查字段池
|
||
const totalFieldDefs = await prisma.fieldDefinition.count()
|
||
console.log(` 字段池定义总数: ${totalFieldDefs}`)
|
||
|
||
console.log('\n✓ 数据完整性验证完成')
|
||
|
||
// 4. 生成迁移报告
|
||
console.log('\n' + '='.repeat(60))
|
||
console.log('迁移报告')
|
||
console.log('='.repeat(60))
|
||
console.log(`模板: ${templatesWithVersion}/${totalTemplates} 有version字段`)
|
||
console.log(`素材: ${materialsWithTemplate}/${totalMaterials} 有templateId`)
|
||
console.log(`字段: ${fieldsWithTemplate}/${totalFields} 有templateId`)
|
||
console.log(`字段池: ${totalFieldDefs} 个定义`)
|
||
console.log('='.repeat(60))
|
||
|
||
if (totalTemplates === templatesWithVersion && totalMaterials === materialsWithTemplate) {
|
||
console.log('\n✓ 数据迁移成功完成!')
|
||
return true
|
||
} else {
|
||
console.warn('\n⚠ 数据迁移完成,但存在警告,请检查上述信息')
|
||
return false
|
||
}
|
||
|
||
} catch (error) {
|
||
console.error('\n✗ 数据迁移失败:', error)
|
||
throw error
|
||
} finally {
|
||
await prisma.$disconnect()
|
||
}
|
||
}
|
||
|
||
// 执行迁移
|
||
if (require.main === module) {
|
||
migrateTemplateData()
|
||
.then((success) => {
|
||
process.exit(success ? 0 : 1)
|
||
})
|
||
.catch((error) => {
|
||
console.error('迁移脚本执行失败:', error)
|
||
process.exit(1)
|
||
})
|
||
}
|
||
|
||
export { migrateTemplateData }
|