160 lines
3.4 KiB
TypeScript
160 lines
3.4 KiB
TypeScript
import { prisma } from '@/lib/prisma'
|
||
|
||
export interface ComponentQueryParams {
|
||
type?: string
|
||
typeId?: string // 直接使用typeId
|
||
brand?: string
|
||
minPrice?: number
|
||
maxPrice?: number
|
||
search?: string
|
||
page?: number
|
||
limit?: number
|
||
}
|
||
|
||
export interface ComponentQueryResult {
|
||
components: Array<{
|
||
id: string
|
||
name: string
|
||
brand: string
|
||
model: string
|
||
price: number
|
||
description: string | null
|
||
stock: number
|
||
type: string
|
||
specifications: string | null
|
||
imageUrl: string | null
|
||
}>
|
||
pagination: {
|
||
page: number
|
||
limit: number
|
||
total: number
|
||
totalPages: number
|
||
hasNext: boolean
|
||
hasPrev: boolean
|
||
}
|
||
}
|
||
|
||
export class ComponentService {
|
||
/**
|
||
* 查询组件列表
|
||
*/
|
||
static async queryComponents(params: ComponentQueryParams): Promise<ComponentQueryResult> {
|
||
const {
|
||
type,
|
||
typeId,
|
||
brand,
|
||
minPrice,
|
||
maxPrice,
|
||
search,
|
||
page = 1,
|
||
limit = 12
|
||
} = params
|
||
|
||
const where: any = {}
|
||
|
||
// 优先使用typeId,如果没有但有type,则查找typeId
|
||
if (typeId) {
|
||
where.componentTypeId = typeId
|
||
} else if (type) {
|
||
const componentType = await prisma.componentType.findFirst({
|
||
where: {
|
||
name: {
|
||
contains: type,
|
||
mode: 'insensitive'
|
||
}
|
||
}
|
||
})
|
||
if (componentType) {
|
||
where.componentTypeId = componentType.id
|
||
}
|
||
}
|
||
|
||
if (brand) {
|
||
where.brand = {
|
||
contains: brand,
|
||
mode: 'insensitive'
|
||
}
|
||
}
|
||
|
||
if (minPrice || maxPrice) {
|
||
where.price = {}
|
||
if (minPrice) where.price.gte = minPrice
|
||
if (maxPrice) where.price.lte = 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 {
|
||
components: components.map(comp => ({
|
||
id: comp.id,
|
||
name: comp.name,
|
||
brand: comp.brand,
|
||
model: comp.model,
|
||
price: comp.price,
|
||
description: comp.description,
|
||
stock: comp.stock,
|
||
type: comp.componentType.name,
|
||
specifications: comp.specifications,
|
||
imageUrl: comp.imageUrl
|
||
})),
|
||
pagination: {
|
||
page,
|
||
limit,
|
||
total,
|
||
totalPages,
|
||
hasNext: page < totalPages,
|
||
hasPrev: page > 1
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 根据ID获取单个组件
|
||
*/
|
||
static async getComponentById(id: string) {
|
||
return await prisma.component.findUnique({
|
||
where: { id },
|
||
include: {
|
||
componentType: true
|
||
}
|
||
})
|
||
}
|
||
static async getComponentsByIds(componentIds: string[]) {
|
||
return await Promise.all(componentIds.map(id => ComponentService.getComponentById(id)))
|
||
}
|
||
/**
|
||
* 获取所有组件类型
|
||
*/
|
||
static async getComponentTypes() {
|
||
return await prisma.componentType.findMany({
|
||
orderBy: {
|
||
name: 'asc'
|
||
}
|
||
})
|
||
}
|
||
}
|