This commit is contained in:
2026-07-01 08:27:26 +08:00
parent 9f4577d3d8
commit 25f0d8e97b
56 changed files with 5298 additions and 2 deletions
@@ -0,0 +1,153 @@
import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common';
import { Prisma } from '@prisma/client';
import { PrismaService } from '../../common/prisma/prisma.module';
import { serializeBigInt } from '../../common/decorators/current-user.decorator';
import type { AdminPartnerAccountsQueryDto, AdminPartnersQueryDto } from './dto/admin-query.dto';
import type {
CreatePartnerAccountDto,
CreatePartnerDto,
UpdatePartnerAccountDto,
UpdatePartnerDto,
} from './dto/admin-mutate.dto';
@Injectable()
export class AdminPartnersService {
constructor(private readonly prisma: PrismaService) {}
async listPartners(query: AdminPartnersQueryDto) {
const page = query.page ?? 1;
const pageSize = query.pageSize ?? 20;
const where: Prisma.PartnerWhereInput = {};
if (query.companyName) where.companyName = { contains: query.companyName };
if (query.contactPhone) where.contactPhone = { contains: query.contactPhone };
const [items, total] = await Promise.all([
this.prisma.partner.findMany({
where,
orderBy: { createdAt: 'desc' },
skip: (page - 1) * pageSize,
take: pageSize,
include: {
_count: { select: { stores: true, accounts: true, cities: true } },
},
}),
this.prisma.partner.count({ where }),
]);
return serializeBigInt({
items: items.map((p) => ({
...p,
storeCount: p._count.stores,
accountCount: p._count.accounts,
cityCount: p._count.cities,
_count: undefined,
})),
total,
page,
pageSize,
});
}
async detailPartner(id: bigint) {
const partner = await this.prisma.partner.findUnique({
where: { id },
include: {
cities: { select: { id: true, code: true, name: true, status: true } },
accounts: { select: { id: true, phone: true, name: true, isPrimary: true, status: true } },
stores: { select: { id: true, name: true, status: true }, take: 10, orderBy: { createdAt: 'desc' } },
_count: { select: { stores: true, accounts: true } },
},
});
if (!partner) throw new NotFoundException('开城合伙人不存在');
return serializeBigInt(partner);
}
async createPartner(dto: CreatePartnerDto) {
const partner = await this.prisma.partner.create({ data: dto });
return serializeBigInt(partner);
}
async updatePartner(id: bigint, dto: UpdatePartnerDto) {
const partner = await this.prisma.partner.update({ where: { id }, data: dto });
return serializeBigInt(partner);
}
async listPartnerAccounts(query: AdminPartnerAccountsQueryDto) {
const page = query.page ?? 1;
const pageSize = query.pageSize ?? 20;
const where: Prisma.PartnerAccountWhereInput = {};
if (query.phone) where.phone = { contains: query.phone };
if (query.partnerId) where.partnerId = BigInt(query.partnerId);
if (query.status) where.status = query.status as Prisma.EnumAccountStatusFilter['equals'];
const [items, total] = await Promise.all([
this.prisma.partnerAccount.findMany({
where,
orderBy: { createdAt: 'desc' },
skip: (page - 1) * pageSize,
take: pageSize,
include: {
partner: { select: { id: true, companyName: true } },
},
}),
this.prisma.partnerAccount.count({ where }),
]);
return serializeBigInt({ items, total, page, pageSize });
}
async detailPartnerAccount(id: bigint) {
const account = await this.prisma.partnerAccount.findUnique({
where: { id },
include: { partner: true },
});
if (!account) throw new NotFoundException('开城合伙人账号不存在');
const [bills, orders] = await Promise.all([
this.prisma.partnerBill.findMany({
where: { partnerId: account.partnerId },
orderBy: { createdAt: 'desc' },
take: 50,
}),
this.prisma.order.findMany({
where: { city: { partnerId: account.partnerId } },
orderBy: { createdAt: 'desc' },
take: 50,
select: {
id: true,
orderNo: true,
status: true,
payAmount: true,
createdAt: true,
user: { select: { userNo: true, phone: true } },
},
}),
]);
return serializeBigInt({ ...account, bills, orders });
}
async createPartnerAccount(dto: CreatePartnerAccountDto) {
const partner = await this.prisma.partner.findUnique({ where: { id: BigInt(dto.partnerId) } });
if (!partner) throw new BadRequestException('开城合伙人不存在');
const account = await this.prisma.partnerAccount.create({
data: {
partnerId: partner.id,
phone: dto.phone,
name: dto.name,
staffRole: dto.staffRole ? (dto.staffRole as 'PARTNER' | 'INTERNAL' | 'PROMOTER') : undefined,
isPrimary: 0,
},
});
return serializeBigInt(account);
}
async updatePartnerAccount(id: bigint, dto: UpdatePartnerAccountDto) {
const account = await this.prisma.partnerAccount.update({
where: { id },
data: {
...(dto.name !== undefined ? { name: dto.name } : {}),
...(dto.status !== undefined ? { status: dto.status as 'ACTIVE' | 'DISABLED' } : {}),
},
});
return serializeBigInt(account);
}
}