import { Injectable, UnauthorizedException } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; import * as bcrypt from 'bcryptjs'; import { PrismaService } from '../../prisma/prisma.service'; @Injectable() export class AdminService { constructor( private prisma: PrismaService, private jwtService: JwtService, ) {} async login(username: string, password: string) { const admin = await this.prisma.adminUser.findUnique({ where: { username }, include: { role: true }, }); if (!admin || admin.status !== 'ACTIVE') { throw new UnauthorizedException('管理员账号不可用'); } const isValid = await bcrypt.compare(password, admin.passwordHash); if (!isValid) { throw new UnauthorizedException('密码错误'); } await this.prisma.adminUser.update({ where: { id: admin.id }, data: { lastLoginAt: new Date() }, }); const token = this.jwtService.sign( { sub: admin.id, type: 'admin' }, { expiresIn: '7d' }, ); return { token, id: admin.id, username: admin.username, role: admin.role?.name }; } async getDashboard() { const [userCount, courseCount, contentCount, promptCount, orderCount] = await Promise.all([ this.prisma.user.count({ where: { deletedAt: null } }), this.prisma.course.count({ where: { deletedAt: null } }), this.prisma.content.count({ where: { deletedAt: null, status: 'PUBLISHED' } }), this.prisma.prompt.count({ where: { deletedAt: null, status: 'PUBLISHED' } }), this.prisma.order.count(), ]); return { stats: { userCount, courseCount, contentCount, promptCount, orderCount }, }; } async logAction(adminId: number, action: string, target?: string, detail?: string, ip?: string) { return this.prisma.adminLog.create({ data: { adminId, action, target, detail, ip }, }); } }