b392c28787
CI / verify (pull_request) Has been cancelled
Add WineryBill/StoreBill tables, partner review-send-confirm flow, daily/monthly cron, and admin multi-select confirm with status filters. Co-authored-by: Cursor <cursoragent@cursor.com>
89 lines
2.6 KiB
TypeScript
89 lines
2.6 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { PrismaService } from '../../common/prisma/prisma.module';
|
|
|
|
@Injectable()
|
|
export class AdminDashboardService {
|
|
constructor(private readonly prisma: PrismaService) {}
|
|
|
|
async getStats() {
|
|
const todayStart = new Date();
|
|
todayStart.setHours(0, 0, 0, 0);
|
|
|
|
const [
|
|
usersTotal,
|
|
guestUsers,
|
|
verifiedUsers,
|
|
mergedUsers,
|
|
ordersToday,
|
|
ordersByStatus,
|
|
storesTotal,
|
|
partnersTotal,
|
|
redeemToday,
|
|
deliveriesTotal,
|
|
pendingPayouts,
|
|
pendingBills,
|
|
pendingPartnerDraftBills,
|
|
openTickets,
|
|
] = await Promise.all([
|
|
this.prisma.user.count({ where: { status: 1, mergedIntoUserId: null } }),
|
|
this.prisma.user.count({
|
|
where: { status: 1, mergedIntoUserId: null, phoneVerifiedAt: null },
|
|
}),
|
|
this.prisma.user.count({
|
|
where: { status: 1, mergedIntoUserId: null, phoneVerifiedAt: { not: null } },
|
|
}),
|
|
this.prisma.user.count({ where: { mergedIntoUserId: { not: null } } }),
|
|
this.prisma.order.count({ where: { createdAt: { gte: todayStart } } }),
|
|
this.prisma.order.groupBy({
|
|
by: ['status'],
|
|
_count: { status: true },
|
|
}),
|
|
this.prisma.store.count(),
|
|
this.prisma.partnerAccount.count({ where: { isPrimary: 1 } }),
|
|
this.prisma.redeemRecord.count({ where: { createdAt: { gte: todayStart } } }),
|
|
this.prisma.orderDelivery.count(),
|
|
this.prisma.storePayout.count({ where: { status: 'PENDING' } }),
|
|
this.prisma.partnerBill.count({ where: { status: 'UNPAID' } }),
|
|
this.prisma.partnerBill.count({ where: { status: 'PENDING_REVIEW' } }),
|
|
this.prisma.commonTicket.count({ where: { status: { in: ['PENDING', 'OPEN'] } } }),
|
|
]);
|
|
|
|
return {
|
|
usersTotal,
|
|
guestUsers,
|
|
verifiedUsers,
|
|
mergedUsers,
|
|
ordersToday,
|
|
storesTotal,
|
|
partnersTotal,
|
|
redeemToday,
|
|
deliveriesTotal,
|
|
pendingPayouts,
|
|
/** 合伙人已确认、待总部审核打款 */
|
|
pendingBills,
|
|
pendingPartnerDraftBills,
|
|
openTickets,
|
|
ordersByStatus: ordersByStatus.map((row) => ({
|
|
status: row.status,
|
|
count: row._count.status,
|
|
})),
|
|
};
|
|
}
|
|
|
|
async getLatestVersion() {
|
|
const row = await this.prisma.systemVersion.findFirst({
|
|
orderBy: { deployedAt: 'desc' },
|
|
});
|
|
if (!row) return null;
|
|
return {
|
|
id: row.id.toString(),
|
|
gitTag: row.gitTag,
|
|
commitId: row.commitId,
|
|
commitMessage: row.commitMessage,
|
|
branch: row.branch,
|
|
deployedBy: row.deployedBy,
|
|
deployedAt: row.deployedAt.toISOString(),
|
|
};
|
|
}
|
|
}
|