import { BadRequestException, Injectable } from '@nestjs/common'; import { PrismaService } from '../../common/prisma/prisma.module'; import { serializeBigInt } from '../../common/decorators/current-user.decorator'; import { groupResourcesByProductId, mapProductMedia } from './catalog.mapper'; @Injectable() export class CatalogService { constructor(private readonly prisma: PrismaService) {} async listCities() { const cities = await this.prisma.commonCity.findMany({ where: { status: 'ACTIVE' }, include: { partner: { select: { companyName: true } } }, orderBy: { name: 'asc' }, }); return serializeBigInt(cities); } async listProducts(aromaType?: string, cityCode?: string) { if (cityCode) { const city = await this.prisma.commonCity.findFirst({ where: { code: cityCode, status: 'ACTIVE' }, }); if (!city) throw new BadRequestException('该城市暂未开城'); } const products = await this.prisma.commonProductItem.findMany({ where: { status: 'ON_SALE', ...(aromaType ? { aromaType: aromaType as never } : {}) }, orderBy: { sortOrder: 'asc' }, include: { coverResource: true }, }); const productIds = products.map((p) => p.id); const resources = productIds.length ? await this.prisma.commonResource.findMany({ where: { ownerType: 'PRODUCT', ownerId: { in: productIds }, status: 'ACTIVE', bizType: { in: ['CAROUSEL', 'DETAIL'] }, }, orderBy: { sortOrder: 'asc' }, }) : []; const resourceMap = groupResourcesByProductId(resources); return serializeBigInt( products.map((p) => { const media = mapProductMedia(p, resourceMap.get(p.id.toString()) ?? []); return { ...p, benefitAmount: p.benefitAmount ?? p.price, price: Number(p.price), benefitDisplay: Number(p.benefitAmount ?? p.price), ...media, }; }), ); } async getProduct(id: bigint) { const product = await this.prisma.commonProductItem.findUnique({ where: { id }, include: { coverResource: true }, }); if (!product) return null; const resources = await this.prisma.commonResource.findMany({ where: { ownerType: 'PRODUCT', ownerId: id, status: 'ACTIVE', bizType: { in: ['CAROUSEL', 'DETAIL'] }, }, orderBy: { sortOrder: 'asc' }, }); const media = mapProductMedia(product, resources); return serializeBigInt({ ...product, benefitAmount: product.benefitAmount ?? product.price, price: Number(product.price), ...media, }); } }