feat: add mark-staff/mark-student endpoints with studentStatus in user list
This commit is contained in:
@@ -127,8 +127,9 @@ export class RbacController {
|
|||||||
|
|
||||||
@Get('users')
|
@Get('users')
|
||||||
@RequirePermission('user:view')
|
@RequirePermission('user:view')
|
||||||
getUsers() {
|
getUsers(@Query('isArchived') isArchived?: string) {
|
||||||
return this.rbacService.findAllUsers();
|
const archived = isArchived === 'true';
|
||||||
|
return this.rbacService.findAllUsers(archived);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('users')
|
@Post('users')
|
||||||
@@ -219,6 +220,50 @@ export class RbacController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Put('users/:id/archive')
|
||||||
|
@RequirePermission('user:edit')
|
||||||
|
async archiveUser(@Param('id') id: string) {
|
||||||
|
try {
|
||||||
|
return await this.rbacService.archiveUser(+id);
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const err = e as { message?: string };
|
||||||
|
throw new BadRequestException(err?.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put('users/:id/restore')
|
||||||
|
@RequirePermission('user:edit')
|
||||||
|
async restoreUser(@Param('id') id: string) {
|
||||||
|
try {
|
||||||
|
return await this.rbacService.restoreUser(+id);
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const err = e as { message?: string };
|
||||||
|
throw new BadRequestException(err?.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put('users/:id/mark-staff')
|
||||||
|
@RequirePermission('user:edit')
|
||||||
|
async markAsStaff(@Param('id') id: string) {
|
||||||
|
try {
|
||||||
|
return await this.rbacService.markAsStaff(+id);
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const err = e as { message?: string };
|
||||||
|
throw new BadRequestException(err?.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put('users/:id/mark-student')
|
||||||
|
@RequirePermission('user:edit')
|
||||||
|
async markAsStudent(@Param('id') id: string) {
|
||||||
|
try {
|
||||||
|
return await this.rbacService.markAsStudent(+id);
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const err = e as { message?: string };
|
||||||
|
throw new BadRequestException(err?.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ---- 用户资料 ----
|
// ---- 用户资料 ----
|
||||||
|
|
||||||
@Get('users/:id/profile')
|
@Get('users/:id/profile')
|
||||||
|
|||||||
@@ -325,16 +325,25 @@ export class RbacService {
|
|||||||
|
|
||||||
// ---- 用户管理 ----
|
// ---- 用户管理 ----
|
||||||
|
|
||||||
async findAllUsers() {
|
async findAllUsers(isArchived = false) {
|
||||||
const users = await this.userRepo.find({
|
const users = await this.userRepo.find({
|
||||||
|
where: { isArchived },
|
||||||
relations: ['roles'],
|
relations: ['roles'],
|
||||||
order: { createdAt: 'DESC' },
|
order: { createdAt: 'DESC' },
|
||||||
});
|
});
|
||||||
|
const userIds = users.map((u) => u.id);
|
||||||
|
const students = await this.studentRepo.find({
|
||||||
|
where: { userId: In(userIds) },
|
||||||
|
select: ['userId', 'status'],
|
||||||
|
});
|
||||||
|
const statusMap = new Map(students.map((s) => [s.userId, s.status]));
|
||||||
return users.map((u) => ({
|
return users.map((u) => ({
|
||||||
id: u.id,
|
id: u.id,
|
||||||
username: u.username,
|
username: u.username,
|
||||||
name: u.name,
|
name: u.name,
|
||||||
isActive: u.isActive,
|
isActive: u.isActive,
|
||||||
|
isArchived: u.isArchived,
|
||||||
|
studentStatus: statusMap.get(u.id) || null,
|
||||||
lastLoginAt: u.lastLoginAt,
|
lastLoginAt: u.lastLoginAt,
|
||||||
createdAt: u.createdAt,
|
createdAt: u.createdAt,
|
||||||
updatedAt: u.updatedAt,
|
updatedAt: u.updatedAt,
|
||||||
@@ -386,10 +395,42 @@ export class RbacService {
|
|||||||
return { message: '密码已重置' };
|
return { message: '密码已重置' };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async archiveUser(id: number) {
|
||||||
|
const user = await this.userRepo.findOne({ where: { id } });
|
||||||
|
if (!user) throw new Error('用户不存在');
|
||||||
|
if (user.username === 'admin') throw new Error('不能归档默认管理员');
|
||||||
|
await this.userRepo.update(id, { isArchived: true });
|
||||||
|
return { message: '用户已归档' };
|
||||||
|
}
|
||||||
|
|
||||||
|
async restoreUser(id: number) {
|
||||||
|
const user = await this.userRepo.findOne({ where: { id } });
|
||||||
|
if (!user) throw new Error('用户不存在');
|
||||||
|
await this.userRepo.update(id, { isArchived: false });
|
||||||
|
return { message: '用户已恢复' };
|
||||||
|
}
|
||||||
|
|
||||||
|
async markAsStaff(userId: number) {
|
||||||
|
const student = await this.studentRepo.findOne({ where: { userId } });
|
||||||
|
if (!student) throw new Error('该用户没有学员记录');
|
||||||
|
await this.studentRepo.update(student.id, { status: 'staff' });
|
||||||
|
this.logger.log(`User ${userId} Student ${student.id} marked as staff`);
|
||||||
|
return { message: '已标记为教职工' };
|
||||||
|
}
|
||||||
|
|
||||||
|
async markAsStudent(userId: number) {
|
||||||
|
const student = await this.studentRepo.findOne({ where: { userId } });
|
||||||
|
if (!student) throw new Error('该用户没有学员记录');
|
||||||
|
await this.studentRepo.update(student.id, { status: 'active' });
|
||||||
|
this.logger.log(`User ${userId} Student ${student.id} restored to student`);
|
||||||
|
return { message: '已恢复为学员' };
|
||||||
|
}
|
||||||
|
|
||||||
async deleteUser(id: number) {
|
async deleteUser(id: number) {
|
||||||
const user = await this.userRepo.findOne({ where: { id } });
|
const user = await this.userRepo.findOne({ where: { id } });
|
||||||
if (!user) throw new Error('用户不存在');
|
if (!user) throw new Error('用户不存在');
|
||||||
if (user.username === 'admin') throw new Error('不能删除默认管理员');
|
if (user.username === 'admin') throw new Error('不能删除默认管理员');
|
||||||
|
if (!user.isArchived) throw new Error('请先归档再删除');
|
||||||
await this.userRepo.remove(user);
|
await this.userRepo.remove(user);
|
||||||
return { message: '用户已删除' };
|
return { message: '用户已删除' };
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user