feat(store): add two-level store categories for admin and partner open-store
CI / verify (pull_request) Has been cancelled

Admin CRUD under stores menu; partner picks leaf category on create.
Default sync only inserts missing rows and never updates existing ones.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-22 12:10:02 +08:00
parent 823e439101
commit 9a550cbaaf
18 changed files with 848 additions and 26 deletions
@@ -13,6 +13,7 @@ import { parseBigIntParam } from '../../common/parse-bigint';
import { AnalyticsService } from '../analytics/analytics.service';
import { PartnerCityService } from '../city-scope/partner-city.service';
import { AuthService } from '../iam/auth.service';
import { StoreCategoryService } from './store-category.service';
@Injectable()
export class StoreService {
@@ -23,6 +24,7 @@ export class StoreService {
private readonly analyticsService: AnalyticsService,
private readonly partnerCityService: PartnerCityService,
private readonly authService: AuthService,
private readonly storeCategoryService: StoreCategoryService,
) {}
async listOpenStores(cityCode?: string) {
@@ -172,11 +174,17 @@ export class StoreService {
const bankAccountNo = body.bankAccountNo ? String(body.bankAccountNo) : null;
const bankBranch = body.bankBranch ? String(body.bankBranch) : null;
if (!body.categoryId) {
throw new BadRequestException('请选择店铺类型');
}
const categoryId = parseBigIntParam(body.categoryId, '分类ID');
await this.storeCategoryService.assertLeafCategoryId(categoryId);
const store = await this.prisma.store.create({
data: {
cityId: city.id,
partnerAccountId: primaryId,
categoryId: body.categoryId ? parseBigIntParam(body.categoryId, '分类ID') : null,
categoryId,
name: String(body.name),
phone: normalizedPhone,
province: String(body.province ?? city.province ?? '河南省'),