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(), }; } }