This commit is contained in:
2025-06-22 11:34:32 +08:00
parent 142992a6c9
commit 7d139b22db
55 changed files with 11035 additions and 105 deletions
+90
View File
@@ -0,0 +1,90 @@
import { NextRequest, NextResponse } from 'next/server'
import { prisma } from '@/lib/prisma'
export async function GET(
request: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
try {
const { id } = await params
const component = await prisma.component.findUnique({
where: { id: id },
include: {
componentType: true
}
})
if (!component) {
return NextResponse.json(
{ message: '配件不存在' },
{ status: 404 }
)
}
return NextResponse.json(component)
} catch (error) {
console.error('Component fetch error:', error)
return NextResponse.json(
{ message: '获取配件详情失败' },
{ status: 500 }
)
}
}
export async function PUT(
request: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
try {
const { id } = await params
const data = await request.json()
const component = await prisma.component.update({
where: { id: id },
data: {
name: data.name,
brand: data.brand,
model: data.model,
price: parseFloat(data.price),
description: data.description,
imageUrl: data.imageUrl,
stock: parseInt(data.stock),
specifications: data.specifications,
componentTypeId: data.componentTypeId
},
include: {
componentType: true
}
})
return NextResponse.json(component)
} catch (error) {
console.error('Component update error:', error)
return NextResponse.json(
{ message: '更新配件失败' },
{ status: 500 }
)
}
}
export async function DELETE(
request: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
try {
const { id } = await params
await prisma.component.delete({
where: { id: id }
})
return NextResponse.json({ message: '删除成功' })
} catch (error) {
console.error('Component delete error:', error)
return NextResponse.json(
{ message: '删除配件失败' },
{ status: 500 }
)
}
}
+215
View File
@@ -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 }
)
}
}
+110
View File
@@ -0,0 +1,110 @@
import { NextRequest, NextResponse } from 'next/server'
import { prisma } from '@/lib/prisma'
export async function GET(request: NextRequest) {
try {
const { searchParams } = new URL(request.url)
const typeId = searchParams.get('type')
const brand = searchParams.get('brand')
const minPrice = searchParams.get('minPrice')
const maxPrice = searchParams.get('maxPrice')
const search = searchParams.get('search')
const page = parseInt(searchParams.get('page') || '1')
const limit = parseInt(searchParams.get('limit') || '12')
const where: any = {}
if (typeId) {
where.componentTypeId = typeId
}
if (brand) {
where.brand = {
contains: brand,
mode: 'insensitive'
}
}
if (minPrice || maxPrice) {
where.price = {}
if (minPrice) where.price.gte = parseFloat(minPrice)
if (maxPrice) where.price.lte = parseFloat(maxPrice)
}
if (search) {
where.OR = [
{ name: { contains: search, mode: 'insensitive' } },
{ brand: { contains: search, mode: 'insensitive' } },
{ model: { contains: search, mode: 'insensitive' } },
{ description: { contains: search, mode: 'insensitive' } }
]
}
const [components, total] = await Promise.all([
prisma.component.findMany({
where,
include: {
componentType: true
},
orderBy: {
createdAt: 'desc'
},
skip: (page - 1) * limit,
take: limit
}),
prisma.component.count({ where })
])
const totalPages = Math.ceil(total / limit)
return NextResponse.json({
components,
pagination: {
page,
limit,
total,
totalPages,
hasNext: page < totalPages,
hasPrev: page > 1
}
})
} catch (error) {
console.error('Components fetch error:', error)
return NextResponse.json(
{ message: '获取配件列表失败' },
{ status: 500 }
)
}
}
export async function POST(request: NextRequest) {
try {
// 这个API需要管理员权限,暂时简化处理
const data = await request.json()
const component = await prisma.component.create({
data: {
name: data.name,
brand: data.brand,
model: data.model,
price: parseFloat(data.price),
description: data.description,
imageUrl: data.imageUrl,
stock: parseInt(data.stock),
specifications: data.specifications,
componentTypeId: data.componentTypeId
},
include: {
componentType: true
}
})
return NextResponse.json(component, { status: 201 })
} catch (error) {
console.error('Component create error:', error)
return NextResponse.json(
{ message: '创建配件失败' },
{ status: 500 }
)
}
}