feat(settlement): 门店未出账手动提现与总部审核(OPT-010)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-03 15:32:01 +08:00
parent 666bcb8633
commit f3353bbce5
29 changed files with 1733 additions and 15 deletions
@@ -40,6 +40,21 @@ function num(v: Prisma.Decimal | number | string | null | undefined): number {
return typeof v === 'number' ? v : Number(v);
}
function isWithdrawOverdue(appliedAt: Date, now = new Date()): boolean {
const day = appliedAt.getDay();
if (day === 0 || day === 6) return false;
const deadline = new Date(
appliedAt.getFullYear(),
appliedAt.getMonth(),
appliedAt.getDate(),
18,
0,
0,
0,
);
return now.getTime() > deadline.getTime();
}
@Injectable()
export class AdminDashboardService {
constructor(private readonly prisma: PrismaService) {}
@@ -63,6 +78,7 @@ export class AdminDashboardService {
pendingBills,
pendingPartnerDraftBills,
openTickets,
pendingWithdrawRows,
] = await Promise.all([
this.prisma.user.count({ where: { status: 1, mergedIntoUserId: null } }),
this.prisma.user.count({
@@ -85,8 +101,18 @@ export class AdminDashboardService {
this.prisma.partnerBill.count({ where: { status: 'UNPAID' } }),
this.prisma.partnerBill.count({ where: { status: 'PENDING_REVIEW' } }),
this.prisma.commonTicket.count({ where: { status: { in: ['PENDING', 'OPEN'] } } }),
this.prisma.storeWithdrawRequest.findMany({
where: { status: 'PENDING_REVIEW' },
select: { appliedAt: true },
}),
]);
const now = new Date();
const pendingStoreWithdrawals = pendingWithdrawRows.length;
const overdueStoreWithdrawals = pendingWithdrawRows.filter((r) =>
isWithdrawOverdue(r.appliedAt, now),
).length;
return {
usersTotal,
guestUsers,
@@ -101,6 +127,8 @@ export class AdminDashboardService {
pendingBills,
pendingPartnerDraftBills,
openTickets,
pendingStoreWithdrawals,
overdueStoreWithdrawals,
ordersByStatus: ordersByStatus.map((row) => ({
status: row.status,
count: row._count.status,
@@ -357,6 +357,9 @@ export class AdminStoresService {
...(dto.visibilityWhitelistEnabled !== undefined
? { visibilityWhitelistEnabled: !!dto.visibilityWhitelistEnabled }
: {}),
...(dto.withdrawWhitelistEnabled !== undefined
? { withdrawWhitelistEnabled: !!dto.withdrawWhitelistEnabled }
: {}),
...(latitude != null && longitude != null ? { latitude, longitude } : {}),
},
});
@@ -516,6 +519,7 @@ export class AdminStoresService {
openTime2: openTime2 || null,
closeTime2: closeTime2 || null,
visibilityWhitelistEnabled: whitelistEnabled,
withdrawWhitelistEnabled: !!dto.withdrawWhitelistEnabled,
...(latitude != null && longitude != null ? { latitude, longitude } : {}),
status: 'OPEN',
auditStatus: 'APPROVED',
@@ -138,6 +138,11 @@ export class CreateStoreDto {
@IsArray()
@IsString({ each: true })
visibilityPhones?: string[];
/** FIN-001:允许未出账手动提现 */
@IsOptional()
@IsBoolean()
withdrawWhitelistEnabled?: boolean;
}
export class UpdateStoreDto {
@@ -237,6 +242,11 @@ export class UpdateStoreDto {
@IsArray()
@IsString({ each: true })
visibilityPhones?: string[];
/** FIN-001:允许未出账手动提现 */
@IsOptional()
@IsBoolean()
withdrawWhitelistEnabled?: boolean;
}
export class CreateStoreAccountDto {