Files
ai-learning-platform/backend/src/modules/admin/users.controller.ts
T
yuzhiran-dev 728edc59ef feat: admin back-office system + AI assistant with action commands
- Admin analytics (recharts charts, overview stats, trend analysis, time range selector)
- Admin permissions (AdminRole/AdminUser models, role CRUD, permission catalog)
- Admin system config (site/AI/member category tabs, per-key save)
- Admin operations (Banner CRUD, push notification send/delete)
- Admin user management (table, search, create/edit, ban/delete)
- Admin layout (custom top bar with branding + sidebar, admin AI assistant)
- Admin login (adminToken localStorage, adminInfo display)
- Admin AI assistant (purple '运营助手', context-aware prompts, action commands)
- Public AI assistant Phase B (action commands: navigate, setModel, startChat, openSkill, setParameter)
- Assistant context mapping + action executor
- Skills API fix: tags parsing fallback (JSON.parse → split)
- Sandbox crash fix: curScene fallback system prompt
- JWT token expiration: access 2h→7d, refresh 7d→30d, admin 8h→7d
- i18n: assistant-related translations (zh/en)
- PM2 ecosystem config for process management
- AI assistant login prompt fix: admin uses getAdminToken(), public uses apiFetch with token refresh
2026-05-20 10:38:58 +08:00

68 lines
2.1 KiB
TypeScript

import { Controller, Get, Post, Put, Delete, Body, Param, Query, UseGuards } from '@nestjs/common';
import { ApiTags, ApiBearerAuth } from '@nestjs/swagger';
import { AuthGuard } from '@nestjs/passport';
import { AdminGuard } from './admin.guard';
import { PrismaService } from '../../prisma/prisma.service';
@ApiTags('管理后台 - 用户管理')
@Controller('admin/users')
@UseGuards(AuthGuard('jwt'), AdminGuard)
@ApiBearerAuth()
export class UsersController {
constructor(private prisma: PrismaService) {}
@Get()
async list(@Query('search') search?: string) {
const where: any = {};
if (search) {
where.OR = [
{ nickname: { contains: search } },
{ phone: { contains: search } },
{ email: { contains: search } },
];
}
return {
items: await this.prisma.user.findMany({
where,
select: {
id: true, phone: true, nickname: true, email: true,
status: true, memberPlan: true, createdAt: true,
},
orderBy: { id: 'desc' },
take: 100,
}),
};
}
@Post()
async create(@Body() body: { phone: string; nickname?: string; email?: string; password: string }) {
const bcrypt = require('bcryptjs');
const passwordHash = await bcrypt.hash(body.password, 10);
return this.prisma.user.create({
data: {
phone: body.phone,
nickname: body.nickname || '',
email: body.email || '',
passwordHash,
status: 'ACTIVE',
},
});
}
@Put(':id')
async update(@Param('id') id: string, @Body() body: { nickname?: string; email?: string; status?: string }) {
const data: any = {};
if (body.nickname !== undefined) data.nickname = body.nickname;
if (body.email !== undefined) data.email = body.email;
if (body.status) data.status = body.status;
return this.prisma.user.update({ where: { id: parseInt(id) }, data });
}
@Delete(':id')
async delete(@Param('id') id: string) {
return this.prisma.user.update({
where: { id: parseInt(id) },
data: { deletedAt: new Date() },
});
}
}