初始化:职引项目 v1.0
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
import { Controller, Get, Post, Body, Query, HttpException, HttpStatus, UseGuards } from '@nestjs/common'
|
||||
import { InjectModel } from '@nestjs/mongoose'
|
||||
import { Model } from 'mongoose'
|
||||
import { Public } from '../../common/decorators/public.decorator'
|
||||
import { JwtAuthGuard } from '../../common/guards/jwt-auth.guard'
|
||||
import { CurrentUser } from '../../common/decorators/current-user.decorator'
|
||||
import { User, UserDocument } from '../user/user.schema'
|
||||
import { Interview, InterviewDocument } from '../interview/interview.schema'
|
||||
|
||||
@Controller('admin')
|
||||
export class AdminController {
|
||||
constructor(
|
||||
@InjectModel(User.name) private userModel: Model<UserDocument>,
|
||||
@InjectModel(Interview.name) private interviewModel: Model<InterviewDocument>,
|
||||
) {}
|
||||
|
||||
@Get('check')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
async checkAdmin(@CurrentUser('userId') userId: string) {
|
||||
const user = await this.userModel.findById(userId).select('role').exec()
|
||||
return { isAdmin: user?.role === 'admin' }
|
||||
}
|
||||
|
||||
@Public()
|
||||
@Post('verify')
|
||||
async verify(@Body('adminId') adminId: string) {
|
||||
const user = await this.userModel.findById(adminId).exec()
|
||||
if (!user || user.role !== 'admin') {
|
||||
throw new HttpException('无权限访问', HttpStatus.FORBIDDEN)
|
||||
}
|
||||
return { ok: true, nickname: user.nickname || '管理员' }
|
||||
}
|
||||
|
||||
@Public()
|
||||
@Get('overview')
|
||||
async overview() {
|
||||
const [userCount, interviewCount, todayUsers, todayInterviews] = await Promise.all([
|
||||
this.userModel.countDocuments().exec(),
|
||||
this.interviewModel.countDocuments().exec(),
|
||||
this.userModel.countDocuments({ createdAt: { $gte: new Date(Date.now() - 24 * 60 * 60 * 1000) } }).exec(),
|
||||
this.interviewModel.countDocuments({ createdAt: { $gte: new Date(Date.now() - 24 * 60 * 60 * 1000) } }).exec(),
|
||||
])
|
||||
return { userCount, interviewCount, todayUsers, todayInterviews }
|
||||
}
|
||||
|
||||
@Public()
|
||||
@Get('users')
|
||||
async getUsers(@Query('keyword') keyword: string, @Query('page') page = '1', @Query('limit') limit = '20') {
|
||||
const filter: any = {}
|
||||
if (keyword) filter.$or = [
|
||||
{ phone: { $regex: keyword, $options: 'i' } },
|
||||
{ nickname: { $regex: keyword, $options: 'i' } },
|
||||
]
|
||||
const skip = (Math.max(1, +page) - 1) * +limit
|
||||
const [users, total] = await Promise.all([
|
||||
this.userModel.find(filter).sort({ createdAt: -1 }).skip(skip).limit(+limit).select('-password').lean().exec(),
|
||||
this.userModel.countDocuments(filter).exec(),
|
||||
])
|
||||
return { users, total, page: +page }
|
||||
}
|
||||
|
||||
@Public()
|
||||
@Get('interviews')
|
||||
async getInterviews(@Query('page') page = '1', @Query('limit') limit = '20') {
|
||||
const skip = (Math.max(1, +page) - 1) * +limit
|
||||
const [interviews, total] = await Promise.all([
|
||||
this.interviewModel.find().sort({ createdAt: -1 }).skip(skip).limit(+limit).populate('userId', 'phone nickname').lean().exec(),
|
||||
this.interviewModel.countDocuments().exec(),
|
||||
])
|
||||
return { interviews, total, page: +page }
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Post('set-vip')
|
||||
async setVip(@Body('userId') targetUserId: string, @CurrentUser('userId') adminUserId: string) {
|
||||
const admin = await this.userModel.findById(adminUserId).exec()
|
||||
if (admin?.role !== 'admin') throw new HttpException('无权限', HttpStatus.FORBIDDEN)
|
||||
const user = await this.userModel.findById(targetUserId).exec()
|
||||
if (!user) throw new HttpException('用户不存在', HttpStatus.NOT_FOUND)
|
||||
const expireAt = new Date()
|
||||
expireAt.setDate(expireAt.getDate() + 30)
|
||||
user.plan = 'vip'
|
||||
user.vipExpireAt = expireAt
|
||||
user.remaining = 999
|
||||
await user.save()
|
||||
return { success: true, plan: 'vip', expireAt }
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Get('admins')
|
||||
async getAdmins(@CurrentUser('userId') adminUserId: string) {
|
||||
const admin = await this.userModel.findById(adminUserId).exec()
|
||||
if (admin?.role !== 'admin') throw new HttpException('无权限', HttpStatus.FORBIDDEN)
|
||||
const admins = await this.userModel.find({ role: 'admin' }).select('phone nickname email createdAt isSystemAdmin').lean().exec()
|
||||
return { admins }
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Post('set-admin')
|
||||
async setAdmin(@Body('userId') targetUserId: string, @CurrentUser('userId') adminUserId: string) {
|
||||
const admin = await this.userModel.findById(adminUserId).exec()
|
||||
if (admin?.role !== 'admin') throw new HttpException('无权限', HttpStatus.FORBIDDEN)
|
||||
const user = await this.userModel.findById(targetUserId).exec()
|
||||
if (!user) throw new HttpException('用户不存在', HttpStatus.NOT_FOUND)
|
||||
if (user.role === 'admin') throw new HttpException('该用户已是管理员', HttpStatus.BAD_REQUEST)
|
||||
user.role = 'admin'
|
||||
await user.save()
|
||||
return { success: true, message: '已设为管理员' }
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Get('config')
|
||||
async getConfig(@CurrentUser('userId') adminUserId: string) {
|
||||
const admin = await this.userModel.findById(adminUserId).exec()
|
||||
if (admin?.role !== 'admin') throw new HttpException('无权限', HttpStatus.FORBIDDEN)
|
||||
return {
|
||||
interview: {
|
||||
maxRoundsFree: 5,
|
||||
maxRoundsVip: 10,
|
||||
dailyFreeLimit: 3,
|
||||
},
|
||||
diagnosis: {
|
||||
dailyFreeLimit: 2,
|
||||
},
|
||||
optimize: {
|
||||
dailyFreeLimit: 2,
|
||||
},
|
||||
price: {
|
||||
monthly: 2900, // 分
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { Module } from '@nestjs/common'
|
||||
import { MongooseModule } from '@nestjs/mongoose'
|
||||
import { AdminController } from './admin.controller'
|
||||
import { User, UserSchema } from '../user/user.schema'
|
||||
import { Interview, InterviewSchema } from '../interview/interview.schema'
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
|
||||
MongooseModule.forFeature([{ name: Interview.name, schema: InterviewSchema }]),
|
||||
],
|
||||
controllers: [AdminController],
|
||||
})
|
||||
export class AdminModule {}
|
||||
Reference in New Issue
Block a user