feat: 为批量归档补充批量恢复
This commit is contained in:
@@ -14,6 +14,8 @@ import {
|
||||
UploadedFile,
|
||||
Inject,
|
||||
ParseIntPipe,
|
||||
UsePipes,
|
||||
ValidationPipe,
|
||||
} from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
@@ -35,6 +37,7 @@ import {
|
||||
parseStudentImportWorkbook,
|
||||
STUDENT_EXPORT_COLUMNS,
|
||||
} from './student-import';
|
||||
import { BatchIdsDto } from '../common/batch-ids.dto';
|
||||
|
||||
interface AuthenticatedRequest {
|
||||
user: AuthenticatedUser;
|
||||
@@ -196,6 +199,24 @@ export class StudentsController {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Put('batch-restore')
|
||||
@RequirePermission('student:edit')
|
||||
@UsePipes(new ValidationPipe({ transform: true, whitelist: true, forbidNonWhitelisted: true }))
|
||||
async batchRestore(@Body() dto: BatchIdsDto, @Request() req: any) {
|
||||
const { ipAddress, userAgent } = extractRequestInfo(req);
|
||||
const result = await this.service.batchRestore(dto.ids);
|
||||
await this.logService.log({
|
||||
userId: req.user?.id,
|
||||
username: req.user?.username,
|
||||
module: '学生管理',
|
||||
action: '批量恢复学生',
|
||||
detail: `IDs: ${dto.ids.join(',')}`,
|
||||
ipAddress,
|
||||
userAgent,
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
@RequirePermission('student:edit')
|
||||
async update(@Param('id', ParseIntPipe) id: number, @Body() dto: UpdateStudentDto, @Request() req: any) {
|
||||
|
||||
@@ -219,6 +219,30 @@ export class StudentsService {
|
||||
return { message: '已恢复' };
|
||||
}
|
||||
|
||||
async batchRestore(ids: number[]) {
|
||||
const uniqueIds = [...new Set(ids || [])];
|
||||
if (uniqueIds.length === 0) throw new BadRequestException('请选择要恢复的学生');
|
||||
if (uniqueIds.some((id) => !Number.isInteger(id) || id <= 0)) {
|
||||
throw new BadRequestException('学生 ID 无效');
|
||||
}
|
||||
const students = await this.repo.find({ where: { id: In(uniqueIds) } });
|
||||
if (students.length !== uniqueIds.length) throw new NotFoundException('部分学生不存在');
|
||||
|
||||
const targetIds = students.filter((student) => student.status === 'archived').map((student) => student.id);
|
||||
const skipped = students.length - targetIds.length;
|
||||
let restored = 0;
|
||||
if (targetIds.length > 0) {
|
||||
const result = await this.repo
|
||||
.createQueryBuilder()
|
||||
.update()
|
||||
.set({ status: 'active' })
|
||||
.where('id IN (:...ids)', { ids: targetIds })
|
||||
.execute();
|
||||
restored = result.affected || 0;
|
||||
}
|
||||
return { message: `已批量恢复 ${restored} 名学生`, restored, skipped };
|
||||
}
|
||||
|
||||
async batchImport(importData: StudentWorkbookImport | StudentImportRow[]) {
|
||||
const data = this.normalizeImportData(importData);
|
||||
let imported = 0;
|
||||
|
||||
Reference in New Issue
Block a user