170 lines
4.4 KiB
TypeScript
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()
|
|
})
|