feat: 学生档案与报告生成
This commit is contained in:
@@ -74,15 +74,15 @@ export class ArchiveService {
|
||||
attendances,
|
||||
] = await Promise.all([
|
||||
this.profileRepo.findOne({ where: { studentId } }),
|
||||
this.enrollmentRepo.find({ where: { studentId, status: 'active' }, order: { createdAt: 'DESC' } }),
|
||||
this.enrollmentRepo.find({ where: { studentId }, order: { createdAt: 'DESC' } }),
|
||||
this.examScoreRepo.find({
|
||||
where: { studentId, status: 'active' },
|
||||
where: { studentId },
|
||||
relations: ['exam', 'exam.class'],
|
||||
order: { examDate: 'DESC' },
|
||||
}),
|
||||
this.learningRecordRepo.find({ where: { studentId, status: 'active' }, order: { recordDate: 'DESC' } }),
|
||||
this.learningRecordRepo.find({ where: { studentId }, order: { recordDate: 'DESC' } }),
|
||||
this.resultRepo.findOne({ where: { studentId } }),
|
||||
this.attachmentRepo.find({ where: { studentId, status: 'active' }, order: { createdAt: 'DESC' } }),
|
||||
this.attachmentRepo.find({ where: { studentId }, order: { createdAt: 'DESC' } }),
|
||||
this.attendanceRepo.find({
|
||||
where: { studentId },
|
||||
relations: ['schedule', 'class'],
|
||||
@@ -138,6 +138,20 @@ export class ArchiveService {
|
||||
return { message: '已归档' };
|
||||
}
|
||||
|
||||
async purgeEnrollment(id: number) {
|
||||
const entity = await this.enrollmentRepo.findOne({ where: { id } });
|
||||
if (!entity) throw new NotFoundException('报名记录不存在');
|
||||
if (entity.status !== 'archived') {
|
||||
throw new BadRequestException('仅已归档报名记录可以永久删除,请先归档');
|
||||
}
|
||||
const scoreCount = await this.examScoreRepo.count({ where: { enrollmentId: id } });
|
||||
if (scoreCount > 0) {
|
||||
throw new BadRequestException('该报名记录已被考试成绩引用,无法永久删除');
|
||||
}
|
||||
await this.enrollmentRepo.delete(id);
|
||||
return { message: '已永久删除报名记录(不可恢复)' };
|
||||
}
|
||||
|
||||
private async assertEnrollmentBelongsToStudent(studentId: number, enrollmentId?: number) {
|
||||
if (enrollmentId === undefined) return;
|
||||
const enrollment = await this.enrollmentRepo.findOne({
|
||||
@@ -173,6 +187,16 @@ export class ArchiveService {
|
||||
return { message: '已归档' };
|
||||
}
|
||||
|
||||
async purgeExamScore(id: number) {
|
||||
const entity = await this.examScoreRepo.findOne({ where: { id } });
|
||||
if (!entity) throw new NotFoundException('考试成绩不存在');
|
||||
if (entity.status !== 'archived') {
|
||||
throw new BadRequestException('仅已归档考试成绩可以永久删除,请先归档');
|
||||
}
|
||||
await this.examScoreRepo.delete(id);
|
||||
return { message: '已永久删除考试成绩(不可恢复)' };
|
||||
}
|
||||
|
||||
async addLearningRecord(studentId: number, dto: CreateLearningRecordDto) {
|
||||
const student = await this.studentRepo.findOne({ where: { id: studentId } });
|
||||
if (!student) throw new NotFoundException('学生不存在');
|
||||
@@ -196,6 +220,16 @@ export class ArchiveService {
|
||||
return { message: '已归档' };
|
||||
}
|
||||
|
||||
async purgeLearningRecord(id: number) {
|
||||
const entity = await this.learningRecordRepo.findOne({ where: { id } });
|
||||
if (!entity) throw new NotFoundException('学习记录不存在');
|
||||
if (entity.status !== 'archived') {
|
||||
throw new BadRequestException('仅已归档学习记录可以永久删除,请先归档');
|
||||
}
|
||||
await this.learningRecordRepo.delete(id);
|
||||
return { message: '已永久删除学习记录(不可恢复)' };
|
||||
}
|
||||
|
||||
async upsertResult(studentId: number, dto: UpsertResultDto) {
|
||||
const student = await this.studentRepo.findOne({ where: { id: studentId } });
|
||||
if (!student) throw new NotFoundException('学生不存在');
|
||||
@@ -257,4 +291,23 @@ export class ArchiveService {
|
||||
await this.attachmentRepo.update(id, { status: 'archived' });
|
||||
return { message: '已归档' };
|
||||
}
|
||||
|
||||
async purgeAttachment(id: number) {
|
||||
const entity = await this.attachmentRepo.findOne({ where: { id } });
|
||||
if (!entity) throw new NotFoundException('附件不存在');
|
||||
if (entity.status !== 'archived') {
|
||||
throw new BadRequestException('仅已归档附件可以永久删除,请先归档');
|
||||
}
|
||||
if (entity.filePath) {
|
||||
try {
|
||||
const fullPath = this.resolveAttachmentPath(entity.filePath);
|
||||
if (fs.existsSync(fullPath)) fs.unlinkSync(fullPath);
|
||||
} catch (error) {
|
||||
// 磁盘文件删除失败仅告警,不阻塞数据库删除
|
||||
console.warn(`[ArchiveService] 附件文件删除失败: ${entity.filePath}`, error);
|
||||
}
|
||||
}
|
||||
await this.attachmentRepo.delete(id);
|
||||
return { message: '已永久删除附件(不可恢复)' };
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user