forked from wangziqi/gongxue-base
fix permissions and teacher attendance workflows
This commit is contained in:
@@ -31,6 +31,16 @@ import { NotificationsService } from '../notifications/notifications.service';
|
||||
import { NotificationType } from '../entities/notification.entity';
|
||||
import * as ExcelJS from 'exceljs';
|
||||
|
||||
interface RequestUser {
|
||||
id: number;
|
||||
permissions?: string[];
|
||||
isSuperAdmin?: boolean;
|
||||
}
|
||||
|
||||
interface AuthenticatedRequest {
|
||||
user: RequestUser;
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Controller('classes')
|
||||
export class ClassesController {
|
||||
@@ -40,30 +50,48 @@ export class ClassesController {
|
||||
private readonly notificationsService: NotificationsService,
|
||||
) {}
|
||||
|
||||
private assertReadAccess(req: AuthenticatedRequest, classId: number) {
|
||||
const canManageAll =
|
||||
req.user.isSuperAdmin === true || req.user.permissions?.includes('class:edit') === true;
|
||||
return this.service.assertClassAccess(req.user.id, classId, canManageAll);
|
||||
}
|
||||
|
||||
@Get()
|
||||
@RequirePermission('class:view')
|
||||
findAll(@Query() query: QueryClassDto) {
|
||||
return this.service.findAll(query);
|
||||
async findAll(@Query() query: QueryClassDto, @Request() req: AuthenticatedRequest) {
|
||||
const classIds = await this.service.getAccessibleClassIds(
|
||||
req.user.id,
|
||||
req.user.isSuperAdmin === true || req.user.permissions?.includes('class:edit') === true,
|
||||
);
|
||||
return this.service.findAll(query, classIds);
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@RequirePermission('class:view')
|
||||
findOne(@Param('id') id: string) {
|
||||
async findOne(@Param('id') id: string, @Request() req: AuthenticatedRequest) {
|
||||
await this.assertReadAccess(req, +id);
|
||||
return this.service.findOne(+id);
|
||||
}
|
||||
|
||||
@Get(':id/schedule')
|
||||
@RequirePermission('class:view')
|
||||
getSchedule(@Param('id') id: string, @Query() query: QueryClassScheduleDto) {
|
||||
async getSchedule(
|
||||
@Param('id') id: string,
|
||||
@Query() query: QueryClassScheduleDto,
|
||||
@Request() req: AuthenticatedRequest,
|
||||
) {
|
||||
await this.assertReadAccess(req, +id);
|
||||
return this.service.getSchedule(+id, query);
|
||||
}
|
||||
|
||||
@Get(':id/attendance-summary')
|
||||
@RequirePermission('class:view')
|
||||
getAttendanceSummary(
|
||||
async getAttendanceSummary(
|
||||
@Param('id') id: string,
|
||||
@Query() query: QueryClassAttendanceSummaryDto,
|
||||
@Request() req: AuthenticatedRequest,
|
||||
) {
|
||||
await this.assertReadAccess(req, +id);
|
||||
return this.service.getAttendanceSummary(+id, query);
|
||||
}
|
||||
|
||||
@@ -86,14 +114,10 @@ export class ClassesController {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/** 批量导入学生到班级(通过钉钉用户ID) */
|
||||
@Post(':id/students/import')
|
||||
@RequirePermission('class:edit')
|
||||
async batchImportStudents(
|
||||
@Param('id') id: string,
|
||||
@Body() dto: BatchImportStudentsDto,
|
||||
) {
|
||||
async batchImportStudents(@Param('id') id: string, @Body() dto: BatchImportStudentsDto) {
|
||||
return this.service.batchImportStudents(+id, dto.users);
|
||||
}
|
||||
|
||||
@@ -113,11 +137,7 @@ export class ClassesController {
|
||||
|
||||
@Put(':id')
|
||||
@RequirePermission('class:edit')
|
||||
async update(
|
||||
@Param('id') id: string,
|
||||
@Body() dto: UpdateClassDto,
|
||||
@Request() req: any,
|
||||
) {
|
||||
async update(@Param('id') id: string, @Body() dto: UpdateClassDto, @Request() req: any) {
|
||||
const { ipAddress, userAgent } = extractRequestInfo(req);
|
||||
const result = await this.service.update(+id, dto);
|
||||
await this.logService.log({
|
||||
@@ -154,7 +174,12 @@ export class ClassesController {
|
||||
|
||||
@Get(':id/roster/export')
|
||||
@RequirePermission('class:view')
|
||||
async exportRoster(@Param('id') id: string, @Res() res: Response) {
|
||||
async exportRoster(
|
||||
@Param('id') id: string,
|
||||
@Res() res: Response,
|
||||
@Request() req: AuthenticatedRequest,
|
||||
) {
|
||||
await this.assertReadAccess(req, +id);
|
||||
const classEntity = await this.service.findOne(+id);
|
||||
const classStudents = await this.service.getStudents(+id);
|
||||
|
||||
@@ -192,17 +217,14 @@ export class ClassesController {
|
||||
|
||||
@Get(':id/students')
|
||||
@RequirePermission('class:view')
|
||||
getStudents(@Param('id') id: string) {
|
||||
async getStudents(@Param('id') id: string, @Request() req: AuthenticatedRequest) {
|
||||
await this.assertReadAccess(req, +id);
|
||||
return this.service.getStudents(+id);
|
||||
}
|
||||
|
||||
@Post(':id/students')
|
||||
@RequirePermission('class:edit')
|
||||
async addStudents(
|
||||
@Param('id') id: string,
|
||||
@Body() dto: AddStudentsDto,
|
||||
@Request() req: any,
|
||||
) {
|
||||
async addStudents(@Param('id') id: string, @Body() dto: AddStudentsDto, @Request() req: any) {
|
||||
const { ipAddress, userAgent } = extractRequestInfo(req);
|
||||
const result = await this.service.addStudents(+id, dto.studentIds);
|
||||
await this.logService.log({
|
||||
@@ -255,17 +277,14 @@ export class ClassesController {
|
||||
|
||||
@Get(':id/teachers')
|
||||
@RequirePermission('class:view')
|
||||
getTeachers(@Param('id') id: string) {
|
||||
async getTeachers(@Param('id') id: string, @Request() req: AuthenticatedRequest) {
|
||||
await this.assertReadAccess(req, +id);
|
||||
return this.service.getTeachers(+id);
|
||||
}
|
||||
|
||||
@Post(':id/teachers')
|
||||
@RequirePermission('class:edit')
|
||||
async addTeacher(
|
||||
@Param('id') id: string,
|
||||
@Body() dto: AddTeacherDto,
|
||||
@Request() req: any,
|
||||
) {
|
||||
async addTeacher(@Param('id') id: string, @Body() dto: AddTeacherDto, @Request() req: any) {
|
||||
const { ipAddress, userAgent } = extractRequestInfo(req);
|
||||
const result = await this.service.addTeacher(+id, dto);
|
||||
await this.logService.log({
|
||||
@@ -290,6 +309,29 @@ export class ClassesController {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Delete(':id/teacher-assignments/:assignmentId')
|
||||
@RequirePermission('class:edit')
|
||||
async removeTeacherAssignment(
|
||||
@Param('id') id: string,
|
||||
@Param('assignmentId') assignmentId: string,
|
||||
@Request() req: any,
|
||||
) {
|
||||
const { ipAddress, userAgent } = extractRequestInfo(req);
|
||||
const result = await this.service.removeTeacherAssignment(+id, +assignmentId);
|
||||
await this.logService.log({
|
||||
userId: req.user?.id,
|
||||
username: req.user?.username,
|
||||
module: '班级管理',
|
||||
action: '移除教师角色',
|
||||
targetId: +id,
|
||||
targetType: 'class',
|
||||
detail: `移除教师分配${assignmentId}`,
|
||||
ipAddress,
|
||||
userAgent,
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@Delete(':id/teachers/:userId')
|
||||
@RequirePermission('class:edit')
|
||||
async removeTeacher(
|
||||
|
||||
Reference in New Issue
Block a user