csdesign-pc-diy-store/lib/services/component-service.ts
2025-06-24 14:09:12 +08:00

160 lines
3.4 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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'
}
})
}
}