244 lines
9.1 KiB
JavaScript
244 lines
9.1 KiB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
};
|
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
};
|
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
};
|
|
import { Controller, Get, Injectable, Module, NotFoundException, Param } from "@nestjs/common";
|
|
import { MediaModule } from "../media/media.controller.js";
|
|
import { MediaService } from "../media/media.service.js";
|
|
import { PrismaService } from "../prisma/prisma.service.js";
|
|
import { SectionsModule, SectionsService } from "../sections/sections.module.js";
|
|
const visible = { isPublished: true, category: { isPublished: true } };
|
|
const RELATED_LIMIT = 4;
|
|
const isAttribute = (a) => !!a && typeof a === "object" && typeof a.name === "string" && typeof a.value === "string";
|
|
let PublicService = class PublicService {
|
|
prisma;
|
|
media;
|
|
sections;
|
|
constructor(prisma, media, sections) {
|
|
this.prisma = prisma;
|
|
this.media = media;
|
|
this.sections = sections;
|
|
}
|
|
async site() {
|
|
const [sections, categories] = await Promise.all([this.sections.getAll(), this.categories()]);
|
|
return { sections, categories };
|
|
}
|
|
async categories() {
|
|
const rows = await this.prisma.category.findMany({
|
|
where: { isPublished: true },
|
|
orderBy: [{ sortOrder: "asc" }, { id: "asc" }],
|
|
include: {
|
|
coverImage: true,
|
|
_count: { select: { products: { where: { isPublished: true } } } },
|
|
},
|
|
});
|
|
return rows.map((c) => ({
|
|
slug: c.slug,
|
|
code: c.code,
|
|
name: c.name,
|
|
nameEn: c.nameEn,
|
|
shortDesc: c.shortDesc,
|
|
icon: c.icon,
|
|
coverImage: c.coverImage && this.media.url(c.coverImage.key),
|
|
productCount: c._count.products,
|
|
}));
|
|
}
|
|
async category(slug) {
|
|
const c = await this.prisma.category.findFirst({
|
|
where: { slug, isPublished: true },
|
|
include: {
|
|
coverImage: true,
|
|
groups: { orderBy: { sortOrder: "asc" } },
|
|
products: {
|
|
where: { isPublished: true },
|
|
orderBy: [{ sortOrder: "asc" }, { id: "asc" }],
|
|
include: { image: true, group: { select: { slug: true } } },
|
|
},
|
|
},
|
|
});
|
|
if (!c)
|
|
throw new NotFoundException("دستهبندی یافت نشد");
|
|
const products = c.products.map((p) => this.toPublicProduct(p));
|
|
const usedGroups = new Set(products.map((p) => p.group));
|
|
return {
|
|
slug: c.slug,
|
|
code: c.code,
|
|
name: c.name,
|
|
nameEn: c.nameEn,
|
|
shortDesc: c.shortDesc,
|
|
fullDesc: c.fullDesc,
|
|
icon: c.icon,
|
|
seoTitle: c.seoTitle,
|
|
seoDescription: c.seoDescription,
|
|
coverImage: c.coverImage && this.media.url(c.coverImage.key),
|
|
productCount: products.length,
|
|
groups: c.groups
|
|
.filter((g) => usedGroups.has(g.slug))
|
|
.map((g) => ({ slug: g.slug, name: g.name, desc: g.desc })),
|
|
products,
|
|
};
|
|
}
|
|
async product(slug) {
|
|
const p = await this.prisma.product.findFirst({
|
|
where: { slug, ...visible },
|
|
include: {
|
|
image: true,
|
|
gallery: { orderBy: { sortOrder: "asc" }, include: { media: true } },
|
|
group: true,
|
|
category: { include: { coverImage: true } },
|
|
},
|
|
});
|
|
if (!p)
|
|
throw new NotFoundException("محصول یافت نشد");
|
|
const media = new Map();
|
|
for (const m of [p.image, ...p.gallery.map((g) => g.media)])
|
|
if (m)
|
|
media.set(m.id, m);
|
|
const siblings = await this.prisma.product.findMany({
|
|
where: { categoryId: p.categoryId, isPublished: true, id: { not: p.id } },
|
|
orderBy: [{ sortOrder: "asc" }, { id: "asc" }],
|
|
include: { image: true, group: { select: { slug: true } } },
|
|
});
|
|
const sameGroup = (s) => p.groupId !== null && s.groupId === p.groupId;
|
|
const related = [...siblings.filter(sameGroup), ...siblings.filter((s) => !sameGroup(s))]
|
|
.slice(0, RELATED_LIMIT)
|
|
.map((s) => this.toPublicProduct(s));
|
|
return {
|
|
...this.toPublicProduct(p),
|
|
details: p.details,
|
|
brand: p.brand,
|
|
origin: p.origin,
|
|
sizes: p.sizes,
|
|
standards: p.standards,
|
|
features: p.features,
|
|
applications: p.applications,
|
|
attributes: Array.isArray(p.attributes) ? p.attributes.filter(isAttribute) : [],
|
|
packaging: p.packaging,
|
|
minOrder: p.minOrder,
|
|
seoTitle: p.seoTitle,
|
|
seoDescription: p.seoDescription,
|
|
images: [...media.values()].map((m) => ({
|
|
url: this.media.url(m.key),
|
|
alt: m.alt || p.name,
|
|
width: m.width,
|
|
height: m.height,
|
|
})),
|
|
groupName: p.group?.name ?? null,
|
|
category: {
|
|
slug: p.category.slug,
|
|
code: p.category.code,
|
|
name: p.category.name,
|
|
nameEn: p.category.nameEn,
|
|
fullDesc: p.category.fullDesc,
|
|
coverImage: p.category.coverImage && this.media.url(p.category.coverImage.key),
|
|
},
|
|
related,
|
|
updatedAt: p.updatedAt.toISOString(),
|
|
};
|
|
}
|
|
async productRefs() {
|
|
const rows = await this.prisma.product.findMany({
|
|
where: visible,
|
|
orderBy: [{ category: { sortOrder: "asc" } }, { sortOrder: "asc" }],
|
|
select: { slug: true, updatedAt: true },
|
|
});
|
|
return rows.map((r) => ({ slug: r.slug, updatedAt: r.updatedAt.toISOString() }));
|
|
}
|
|
toPublicProduct(p) {
|
|
return {
|
|
code: p.code,
|
|
slug: p.slug,
|
|
name: p.name,
|
|
nameEn: p.nameEn,
|
|
desc: p.desc,
|
|
specs: p.specs,
|
|
variants: p.variants,
|
|
image: p.image && this.media.url(p.image.key),
|
|
group: p.group?.slug ?? null,
|
|
};
|
|
}
|
|
};
|
|
PublicService = __decorate([
|
|
Injectable(),
|
|
__metadata("design:paramtypes", [PrismaService,
|
|
MediaService,
|
|
SectionsService])
|
|
], PublicService);
|
|
export { PublicService };
|
|
let PublicController = class PublicController {
|
|
publicData;
|
|
constructor(publicData) {
|
|
this.publicData = publicData;
|
|
}
|
|
site() {
|
|
return this.publicData.site();
|
|
}
|
|
categories() {
|
|
return this.publicData.categories();
|
|
}
|
|
category(slug) {
|
|
return this.publicData.category(slug);
|
|
}
|
|
products() {
|
|
return this.publicData.productRefs();
|
|
}
|
|
product(slug) {
|
|
return this.publicData.product(slug);
|
|
}
|
|
};
|
|
__decorate([
|
|
Get("site"),
|
|
__metadata("design:type", Function),
|
|
__metadata("design:paramtypes", []),
|
|
__metadata("design:returntype", void 0)
|
|
], PublicController.prototype, "site", null);
|
|
__decorate([
|
|
Get("categories"),
|
|
__metadata("design:type", Function),
|
|
__metadata("design:paramtypes", []),
|
|
__metadata("design:returntype", void 0)
|
|
], PublicController.prototype, "categories", null);
|
|
__decorate([
|
|
Get("categories/:slug"),
|
|
__param(0, Param("slug")),
|
|
__metadata("design:type", Function),
|
|
__metadata("design:paramtypes", [String]),
|
|
__metadata("design:returntype", void 0)
|
|
], PublicController.prototype, "category", null);
|
|
__decorate([
|
|
Get("products"),
|
|
__metadata("design:type", Function),
|
|
__metadata("design:paramtypes", []),
|
|
__metadata("design:returntype", void 0)
|
|
], PublicController.prototype, "products", null);
|
|
__decorate([
|
|
Get("products/:slug"),
|
|
__param(0, Param("slug")),
|
|
__metadata("design:type", Function),
|
|
__metadata("design:paramtypes", [String]),
|
|
__metadata("design:returntype", void 0)
|
|
], PublicController.prototype, "product", null);
|
|
PublicController = __decorate([
|
|
Controller("public"),
|
|
__metadata("design:paramtypes", [PublicService])
|
|
], PublicController);
|
|
export { PublicController };
|
|
let PublicModule = class PublicModule {
|
|
};
|
|
PublicModule = __decorate([
|
|
Module({
|
|
imports: [MediaModule, SectionsModule],
|
|
controllers: [PublicController],
|
|
providers: [PublicService],
|
|
})
|
|
], PublicModule);
|
|
export { PublicModule };
|
|
//# sourceMappingURL=public.module.js.map
|