feat(assoc): v4.0.1 合伙人关联码、分佣账单与 H5 用户管理

订单佣金只认关联用户;合伙人备注写入独立表;H5 增加用户管理与首页统计。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-30 14:35:39 +08:00
parent 3b669f7e38
commit 9c8d5f2cad
125 changed files with 6355 additions and 1436 deletions
@@ -184,7 +184,7 @@ export class StoreService {
const stores = await this.prisma.store.findMany({
where: where as never,
include: {
category: true,
category: { include: { parent: true } },
coverResource: true,
},
orderBy: [{ sortOrder: 'asc' }, { createdAt: 'desc' }],
@@ -206,8 +206,21 @@ export class StoreService {
latitude?: unknown;
longitude?: unknown;
sortOrder?: number;
redeemCount: number;
};
const redeemGroups =
visible.length === 0
? []
: await this.prisma.redeemRecord.groupBy({
by: ['storeId'],
where: { storeId: { in: visible.map((s) => s.id) } },
_count: { _all: true },
});
const redeemCountByStore = new Map(
redeemGroups.map((g) => [g.storeId.toString(), g._count._all]),
);
const items: StoreListItem[] = [];
for (const store of visible) {
const coords = await this.ensureStoreCoordinates(store);
@@ -224,7 +237,11 @@ export class StoreService {
hasUser && coords
? Math.round(haversineMeters(userLat!, userLng!, coords.latitude, coords.longitude))
: null;
items.push({ ...mapped, distanceMeters });
items.push({
...mapped,
distanceMeters,
redeemCount: redeemCountByStore.get(store.id.toString()) ?? 0,
});
}
items.sort((a, b) => {
@@ -245,7 +262,7 @@ export class StoreService {
const store = await this.prisma.store.findFirst({
where: { id, status: 'OPEN' },
include: {
category: true,
category: { include: { parent: true } },
coverResource: true,
},
});
@@ -256,14 +273,17 @@ export class StoreService {
throw new NotFoundException('门店不存在');
}
const coords = await this.ensureStoreCoordinates(store);
const media = await this.prisma.commonResource.findMany({
where: { ownerType: 'STORE', ownerId: id, status: 'ACTIVE', bizType: 'ENV' },
orderBy: { sortOrder: 'asc' },
});
const packageRows = await this.prisma.storePackage.findMany({
where: { storeId: id },
orderBy: [{ sortOrder: 'asc' }, { id: 'asc' }],
});
const [media, packageRows, redeemCount] = await Promise.all([
this.prisma.commonResource.findMany({
where: { ownerType: 'STORE', ownerId: id, status: 'ACTIVE', bizType: 'ENV' },
orderBy: { sortOrder: 'asc' },
}),
this.prisma.storePackage.findMany({
where: { storeId: id },
orderBy: [{ sortOrder: 'asc' }, { id: 'asc' }],
}),
this.prisma.redeemRecord.count({ where: { storeId: id } }),
]);
const { visibilityWhitelistEnabled: _wl, ...rest } = store;
return serializeBigInt(
mapStoreCompat(
@@ -271,6 +291,7 @@ export class StoreService {
...rest,
latitude: coords?.latitude ?? store.latitude,
longitude: coords?.longitude ?? store.longitude,
redeemCount,
media,
packages: packageRows.map((p) => {
const imageUrls = normalizeStorePackageImageUrls({