feat(public): merge secondary media gallery images with URL dedup

This commit is contained in:
yeuimu
2026-08-28 11:19:27 +08:00
parent 457792b729
commit d826c5bdd4
2 changed files with 37 additions and 1 deletions
+30 -1
View File
@@ -385,7 +385,7 @@ export class PublicService {
designArea: detail?.designArea ?? null,
pictureRequest: detail?.pictureRequest ?? null,
},
media: (detail?.media as Record<string, unknown> | null) ?? null,
media: this.mergeMedia(detail, secondaryDetails),
mediaByColor: this.groupImagesByColor(allVariants),
options: this.mergeOptions(detail, secondaryDetails),
sizeChart: this.mergeRowsByKey(detail, secondaryDetails, 'sizeChart'),
@@ -496,6 +496,35 @@ export class PublicService {
return merged;
}
/**
* Merge the gallery `media` across details: primary images first,
* secondary-only image URLs appended (URL-deduped). `primaryImageUrl`
* stays the primary's.
*/
private mergeMedia(
primary: PublicGoodRow['originGood']['detail'],
secondaries: NonNullable<PublicGoodRow['originGood']['detail']>[],
): Record<string, unknown> | null {
const toImages = (media: unknown): string[] => {
const images = (media as { images?: unknown } | null)?.images;
return Array.isArray(images) ? images.filter((u): u is string => typeof u === 'string') : [];
};
const primaryMedia = (primary?.media as Record<string, unknown> | null) ?? null;
if (!primaryMedia && secondaries.length === 0) return null;
const images = toImages(primaryMedia);
const seen = new Set(images);
for (const sec of secondaries) {
for (const url of toImages(sec.media)) {
if (!seen.has(url)) {
seen.add(url);
images.push(url);
}
}
}
if (images.length === 0) return null;
return { ...(primaryMedia ?? {}), images };
}
private async buildTagGroupFilters(
selectedGroups: PublicTagFilterDto[],
): Promise<Prisma.GoodWhereInput[]> {