feat(v3.4.15): HQ store media edit and package images up to 20

Allow HQ to replace/delete store photos; support multi-image packages with a 20-image cap.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-07 19:24:07 +08:00
parent 0692bebf07
commit 76375eff83
19 changed files with 657 additions and 302 deletions
@@ -4,7 +4,12 @@ import {
NotFoundException,
} from '@nestjs/common';
import { Prisma } from '@prisma/client';
import { STORE_PACKAGE_MAX_COUNT, type StorePackageItemDto } from '@dukang/shared-types';
import {
STORE_PACKAGE_IMAGE_MAX_COUNT,
STORE_PACKAGE_MAX_COUNT,
normalizeStorePackageImageUrls,
type StorePackageItemDto,
} from '@dukang/shared-types';
import { PrismaService } from '../../common/prisma/prisma.module';
import { serializeBigInt } from '../../common/decorators/current-user.decorator';
import { StoreService } from './store.service';
@@ -44,9 +49,18 @@ export class StorePackageService {
const otherNotes = item.otherNotes != null && String(item.otherNotes).trim()
? String(item.otherNotes).trim()
: null;
const imageUrl = item.imageUrl != null && String(item.imageUrl).trim()
? String(item.imageUrl).trim()
: null;
const imageUrls = normalizeStorePackageImageUrls({
imageUrl: item.imageUrl as string | null | undefined,
imageUrls: item.imageUrls,
});
if (
Array.isArray(item.imageUrls) &&
item.imageUrls.filter((u) => String(u ?? '').trim()).length > STORE_PACKAGE_IMAGE_MAX_COUNT
) {
throw new BadRequestException(
`${index + 1} 条套餐图片最多 ${STORE_PACKAGE_IMAGE_MAX_COUNT}`,
);
}
const sortOrder = item.sortOrder != null ? Number(item.sortOrder) : index;
return {
name,
@@ -54,7 +68,8 @@ export class StorePackageService {
dishes,
usableTime,
otherNotes,
imageUrl,
imageUrl: imageUrls[0] ?? null,
imageUrls: imageUrls.length ? imageUrls : null,
sortOrder: Number.isFinite(sortOrder) ? sortOrder : index,
};
}
@@ -67,8 +82,13 @@ export class StorePackageService {
usableTime: string | null;
otherNotes: string | null;
imageUrl: string | null;
imageUrls: Prisma.JsonValue | null;
sortOrder: number;
}) {
const imageUrls = normalizeStorePackageImageUrls({
imageUrl: row.imageUrl,
imageUrls: row.imageUrls,
});
return {
id: row.id.toString(),
name: row.name,
@@ -76,7 +96,8 @@ export class StorePackageService {
dishes: row.dishes,
usableTime: row.usableTime,
otherNotes: row.otherNotes,
imageUrl: row.imageUrl,
imageUrl: imageUrls[0] ?? null,
imageUrls: imageUrls.length ? imageUrls : null,
sortOrder: row.sortOrder,
};
}
@@ -221,6 +242,9 @@ export class StorePackageService {
usableTime: pkg.usableTime ?? null,
otherNotes: pkg.otherNotes ?? null,
imageUrl: pkg.imageUrl ?? null,
imageUrls: pkg.imageUrls?.length
? (pkg.imageUrls as Prisma.InputJsonValue)
: Prisma.JsonNull,
sortOrder: pkg.sortOrder ?? index,
},
}),