170 lines
4.4 KiB
TypeScript

import 'dotenv/config'
import { prisma } from '../src/lib/prisma'
import { STANDARD_FINISH_CATALOG } from '../src/lib/standard-finish-catalog'
import { buildStandardFinishMaterialData } from '../src/lib/standard-finish-sync'
interface SyncSummary {
categoriesCreated: number
categoriesUpdated: number
categoriesDeactivated: number
materialsCreated: number
materialsUpdated: number
materialsDeactivated: number
}
async function main() {
const summary: SyncSummary = {
categoriesCreated: 0,
categoriesUpdated: 0,
categoriesDeactivated: 0,
materialsCreated: 0,
materialsUpdated: 0,
materialsDeactivated: 0,
}
const standardCategoryNames = new Set(STANDARD_FINISH_CATALOG.map((category) => category.name))
const standardMaterialKeys = new Set(
STANDARD_FINISH_CATALOG.flatMap((category) =>
category.materials.map((material) => `${category.name}::${material.name}`),
),
)
for (const categoryDefinition of STANDARD_FINISH_CATALOG) {
const category = await prisma.materialCategory.upsert({
where: { name: categoryDefinition.name },
update: {
icon: categoryDefinition.icon,
sortOrder: categoryDefinition.sortOrder,
isActive: true,
},
create: {
name: categoryDefinition.name,
icon: categoryDefinition.icon,
sortOrder: categoryDefinition.sortOrder,
isActive: true,
},
})
const existingCategory = await prisma.materialCategory.findUnique({
where: { id: category.id },
select: { createdAt: true, updatedAt: true },
})
if (existingCategory && existingCategory.createdAt.getTime() === existingCategory.updatedAt.getTime()) {
summary.categoriesCreated += 1
} else {
summary.categoriesUpdated += 1
}
for (const materialDefinition of categoryDefinition.materials) {
const data = buildStandardFinishMaterialData({
material: materialDefinition,
category: categoryDefinition,
categoryId: category.id,
})
const existingMaterial = await prisma.material.findFirst({
where: {
categoryId: category.id,
name: materialDefinition.name,
},
select: {
id: true,
},
})
if (existingMaterial) {
await prisma.material.update({
where: { id: existingMaterial.id },
data: {
thumbnailUrl: data.thumbnailUrl,
color: data.color,
metalness: data.metalness,
roughness: data.roughness,
opacity: data.opacity,
textureUrl: data.textureUrl,
normalMapUrl: data.normalMapUrl,
textureRepeat: data.textureRepeat,
textureRotation: data.textureRotation,
textureSizeMm: data.textureSizeMm,
isPreset: true,
isActive: true,
},
})
summary.materialsUpdated += 1
} else {
await prisma.material.create({ data })
summary.materialsCreated += 1
}
}
}
const presetCategoriesToDeactivate = await prisma.materialCategory.findMany({
where: {
isActive: true,
materials: {
some: {
isPreset: true,
},
},
name: {
notIn: Array.from(standardCategoryNames),
},
},
select: { id: true },
})
for (const category of presetCategoriesToDeactivate) {
await prisma.materialCategory.update({
where: { id: category.id },
data: { isActive: false },
})
summary.categoriesDeactivated += 1
}
const presetMaterials = await prisma.material.findMany({
where: {
isPreset: true,
category: {
isActive: true,
},
},
select: {
id: true,
name: true,
category: {
select: {
name: true,
},
},
},
})
for (const material of presetMaterials) {
const materialKey = `${material.category.name}::${material.name}`
if (standardMaterialKeys.has(materialKey)) {
continue
}
await prisma.material.update({
where: { id: material.id },
data: { isActive: false },
})
summary.materialsDeactivated += 1
}
console.log('标准饰面同步完成。')
console.log(JSON.stringify(summary, null, 2))
}
main()
.catch((error) => {
console.error('标准饰面同步失败:')
console.error(error)
process.exitCode = 1
})
.finally(async () => {
await prisma.$disconnect()
})