v4.0.9版本更新-门店分类支持多选
CI / verify (pull_request) Has been cancelled

This commit is contained in:
2026-09-02 11:12:51 +08:00
parent 77e9917a18
commit fe557c912d
18 changed files with 742 additions and 239 deletions
@@ -14,6 +14,12 @@ import { contractMediaType, normalizeContractUrls } from '../../common/store-med
import type { AdminStoreAccountsQueryDto, AdminStoreMediaQueryDto, AdminStoresQueryDto } from './dto/admin-query.dto';
import { PartnerCityService } from '../city-scope/partner-city.service';
import { StoreCategoryService } from '../store/store-category.service';
import {
attachStoreCategories,
parseUniqueCategoryIds,
storeCategoryLinkInclude,
syncStoreCategoryLinks,
} from '../store/store-category-link.util';
import { AnalyticsService } from '../analytics/analytics.service';
import type {
CreateStoreAccountDto,
@@ -123,6 +129,7 @@ export class AdminStoresService {
cityRef: { select: { id: true, name: true, code: true } },
partnerAccount: { select: { id: true, companyName: true, name: true, phone: true } },
category: { select: { id: true, name: true, parentId: true } },
...storeCategoryLinkInclude,
bindings: {
where: { storeAccount: { isPrimary: 1 } },
take: 1,
@@ -169,7 +176,7 @@ export class AdminStoresService {
return serializeBigInt({
items: items.map((s) => {
const { visibilityPhones, ...rest } = s;
return mapStoreCompat({
return mapStoreCompat(attachStoreCategories({
...rest,
visibilityWhitelistEnabled: s.visibilityWhitelistEnabled,
visibilityPhones: visibilityPhones.map((p) => p.phone),
@@ -180,7 +187,7 @@ export class AdminStoresService {
partner: s.partnerAccount,
account: s.bindings[0]?.storeAccount ?? null,
bindings: undefined,
});
}));
}),
total,
page,
@@ -196,6 +203,7 @@ export class AdminStoresService {
cityRef: true,
partnerAccount: true,
category: true,
...storeCategoryLinkInclude,
bindings: {
where: { storeAccount: { isPrimary: 1 } },
take: 1,
@@ -219,7 +227,7 @@ export class AdminStoresService {
}),
]);
const { visibilityPhones, ...rest } = store;
return serializeBigInt(mapStoreCompat({
return serializeBigInt(mapStoreCompat(attachStoreCategories({
...rest,
visibilityWhitelistEnabled: store.visibilityWhitelistEnabled,
visibilityPhones: visibilityPhones.map((p) => p.phone),
@@ -235,7 +243,7 @@ export class AdminStoresService {
redeemCount: store._count.redeemRecords,
ratingCount: store._count.ratings,
_count: undefined,
}));
})));
}
async updateStoreStatus(id: bigint, dto: UpdateStoreStatusDto, actorId: bigint) {
@@ -430,11 +438,22 @@ export class AdminStoresService {
}
let categoryId: bigint | undefined;
if (dto.categoryId !== undefined) {
let categoryIds: bigint[] | undefined;
if (dto.categoryIds !== undefined) {
categoryIds = parseUniqueCategoryIds(dto.categoryIds);
if (!categoryIds.length) {
throw new BadRequestException('请选择门店分类');
}
for (const id of categoryIds) {
await this.storeCategoryService.assertLeafCategoryId(id);
}
categoryId = categoryIds[0];
} else if (dto.categoryId !== undefined) {
if (!dto.categoryId?.trim()) {
throw new BadRequestException('请选择门店分类');
}
categoryId = BigInt(dto.categoryId);
categoryIds = [categoryId];
await this.storeCategoryService.assertLeafCategoryId(categoryId);
}
@@ -661,6 +680,10 @@ export class AdminStoresService {
});
}
}
if (categoryIds !== undefined) {
await syncStoreCategoryLinks(tx, id, categoryIds);
}
});
return this.detailStore(id, actorId);
@@ -693,11 +716,20 @@ export class AdminStoresService {
if (!city) throw new BadRequestException('开城城市不存在');
await this.partnerCityService.assertPartnerAccountBoundToCity(partnerAccountId, city.id);
if (!dto.categoryId?.trim()) {
if (!dto.categoryId?.trim() && (!dto.categoryIds || !dto.categoryIds.length)) {
throw new BadRequestException('请选择门店分类');
}
const categoryId = BigInt(dto.categoryId);
await this.storeCategoryService.assertLeafCategoryId(categoryId);
const categoryIds = parseUniqueCategoryIds(dto.categoryIds);
if (!categoryIds.length && dto.categoryId?.trim()) {
categoryIds.push(BigInt(dto.categoryId));
}
if (!categoryIds.length) {
throw new BadRequestException('请选择门店分类');
}
for (const id of categoryIds) {
await this.storeCategoryService.assertLeafCategoryId(id);
}
const categoryId = categoryIds[0];
const latitude = dto.latitude != null ? Number(dto.latitude) : null;
const longitude = dto.longitude != null ? Number(dto.longitude) : null;
@@ -775,6 +807,8 @@ export class AdminStoresService {
},
});
await syncStoreCategoryLinks(this.prisma, store.id, categoryIds);
if (dto.coverUrl) {
const cover = await this.prisma.commonResource.create({
data: {