v1
This commit is contained in:
@@ -0,0 +1,215 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { prisma } from '@/lib/prisma'
|
||||
|
||||
interface BatchComponentData {
|
||||
name: string
|
||||
brand: string
|
||||
model: string
|
||||
price: number
|
||||
description?: string
|
||||
imageUrl?: string
|
||||
stock: number
|
||||
specifications?: string
|
||||
componentTypeId?: string
|
||||
typeName?: string
|
||||
type?: string
|
||||
}
|
||||
|
||||
interface BatchResult {
|
||||
success: boolean
|
||||
item: BatchComponentData
|
||||
error?: string
|
||||
componentId?: string
|
||||
}
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
// 这个API需要管理员权限,实际应用中需要验证
|
||||
const { components } = await request.json()
|
||||
|
||||
if (!Array.isArray(components) || components.length === 0) {
|
||||
return NextResponse.json(
|
||||
{ message: '请提供有效的配件数据数组' },
|
||||
{ status: 400 }
|
||||
)
|
||||
}
|
||||
|
||||
const results: BatchResult[] = []
|
||||
const createdTypes: { [key: string]: string } = {} // 缓存新创建的类型
|
||||
|
||||
// 获取现有的配件类型,用于匹配
|
||||
const existingTypes = await prisma.componentType.findMany()
|
||||
const typeMap = new Map(existingTypes.map(type => [type.name.toLowerCase(), type.id]))
|
||||
|
||||
for (const componentData of components) {
|
||||
try {
|
||||
// 验证必需字段
|
||||
if (!componentData.name || !componentData.brand || !componentData.model) {
|
||||
results.push({
|
||||
success: false,
|
||||
item: componentData,
|
||||
error: '缺少必需字段: name, brand, model'
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
// 处理价格和库存
|
||||
const price = typeof componentData.price === 'string'
|
||||
? parseFloat(componentData.price)
|
||||
: componentData.price
|
||||
const stock = typeof componentData.stock === 'string'
|
||||
? parseInt(componentData.stock)
|
||||
: componentData.stock
|
||||
|
||||
if (isNaN(price) || price < 0) {
|
||||
results.push({
|
||||
success: false,
|
||||
item: componentData,
|
||||
error: '价格必须是有效的正数'
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
if (isNaN(stock) || stock < 0) {
|
||||
results.push({
|
||||
success: false,
|
||||
item: componentData,
|
||||
error: '库存必须是有效的非负整数'
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
// 处理配件类型
|
||||
let componentTypeId = componentData.componentTypeId
|
||||
|
||||
if (!componentTypeId) {
|
||||
const typeName = componentData.typeName || componentData.type
|
||||
if (!typeName) {
|
||||
results.push({
|
||||
success: false,
|
||||
item: componentData,
|
||||
error: '缺少配件类型信息 (componentTypeId, typeName 或 type)'
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
const lowerTypeName = typeName.toLowerCase()
|
||||
|
||||
// 检查是否已存在
|
||||
if (typeMap.has(lowerTypeName)) {
|
||||
componentTypeId = typeMap.get(lowerTypeName)
|
||||
} else if (createdTypes[lowerTypeName]) {
|
||||
// 检查本次批量导入中是否已创建
|
||||
componentTypeId = createdTypes[lowerTypeName]
|
||||
} else {
|
||||
// 创建新的配件类型
|
||||
try {
|
||||
const newType = await prisma.componentType.create({
|
||||
data: {
|
||||
name: typeName,
|
||||
description: `自动创建的${typeName}类型`
|
||||
}
|
||||
})
|
||||
componentTypeId = newType.id
|
||||
createdTypes[lowerTypeName] = newType.id
|
||||
typeMap.set(lowerTypeName, newType.id)
|
||||
} catch (typeError) {
|
||||
results.push({
|
||||
success: false,
|
||||
item: componentData,
|
||||
error: `创建配件类型失败: ${typeError instanceof Error ? typeError.message : '未知错误'}`
|
||||
})
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 验证配件类型ID
|
||||
if (!componentTypeId) {
|
||||
results.push({
|
||||
success: false,
|
||||
item: componentData,
|
||||
error: '无法确定配件类型'
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
// 检查是否已存在相同的配件
|
||||
const existingComponent = await prisma.component.findFirst({
|
||||
where: {
|
||||
name: componentData.name,
|
||||
brand: componentData.brand,
|
||||
model: componentData.model
|
||||
}
|
||||
})
|
||||
|
||||
if (existingComponent) {
|
||||
results.push({
|
||||
success: false,
|
||||
item: componentData,
|
||||
error: `配件已存在: ${componentData.name} - ${componentData.brand} ${componentData.model}`
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
// 创建配件
|
||||
const newComponent = await prisma.component.create({
|
||||
data: {
|
||||
name: componentData.name.trim(),
|
||||
brand: componentData.brand.trim(),
|
||||
model: componentData.model.trim(),
|
||||
price,
|
||||
description: componentData.description?.trim() || '',
|
||||
imageUrl: componentData.imageUrl?.trim() || '',
|
||||
stock,
|
||||
specifications: componentData.specifications?.trim() || '',
|
||||
componentTypeId
|
||||
},
|
||||
include: {
|
||||
componentType: true
|
||||
}
|
||||
})
|
||||
|
||||
results.push({
|
||||
success: true,
|
||||
item: componentData,
|
||||
componentId: newComponent.id
|
||||
})
|
||||
|
||||
} catch (error) {
|
||||
console.error('处理单个配件时出错:', error)
|
||||
results.push({
|
||||
success: false,
|
||||
item: componentData,
|
||||
error: error instanceof Error ? error.message : '创建配件失败'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 统计结果
|
||||
const successCount = results.filter(r => r.success).length
|
||||
const failCount = results.filter(r => !r.success).length
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
results,
|
||||
summary: {
|
||||
total: components.length,
|
||||
successful: successCount,
|
||||
failed: failCount,
|
||||
newTypesCreated: Object.keys(createdTypes).length
|
||||
}
|
||||
})
|
||||
|
||||
} catch (error) {
|
||||
console.error('批量导入配件失败:', error)
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
message: '批量导入失败',
|
||||
error: error instanceof Error ? error.message : '未知错误'
|
||||
},
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user