forked from wangziqi/gongxue-base
feat: add student archive module with full CRUD APIs
This commit is contained in:
209
apps/server/src/archive/archive.service.ts
Normal file
209
apps/server/src/archive/archive.service.ts
Normal file
@@ -0,0 +1,209 @@
|
||||
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { CampusScope } from '../common/campus-scope';
|
||||
import { NotificationsService } from '../notifications/notifications.service';
|
||||
import { Student } from '../entities/student.entity';
|
||||
import { StudentProfile } from '../entities/student-profile.entity';
|
||||
import { StudentEnrollment } from '../entities/student-enrollment.entity';
|
||||
import { ExamScore } from '../entities/exam-score.entity';
|
||||
import { LearningRecord } from '../entities/learning-record.entity';
|
||||
import { ResultArchive } from '../entities/result-archive.entity';
|
||||
import { ArchiveAttachment } from '../entities/archive-attachment.entity';
|
||||
import {
|
||||
UpsertProfileDto,
|
||||
CreateEnrollmentDto,
|
||||
CreateExamScoreDto,
|
||||
CreateLearningRecordDto,
|
||||
UpsertResultDto,
|
||||
} from './dto/archive.dto';
|
||||
|
||||
@Injectable()
|
||||
export class ArchiveService {
|
||||
constructor(
|
||||
@InjectRepository(Student) private studentRepo: Repository<Student>,
|
||||
@InjectRepository(StudentProfile) private profileRepo: Repository<StudentProfile>,
|
||||
@InjectRepository(StudentEnrollment) private enrollmentRepo: Repository<StudentEnrollment>,
|
||||
@InjectRepository(ExamScore) private examScoreRepo: Repository<ExamScore>,
|
||||
@InjectRepository(LearningRecord) private learningRecordRepo: Repository<LearningRecord>,
|
||||
@InjectRepository(ResultArchive) private resultRepo: Repository<ResultArchive>,
|
||||
@InjectRepository(ArchiveAttachment) private attachmentRepo: Repository<ArchiveAttachment>,
|
||||
private readonly scope: CampusScope,
|
||||
private readonly notificationsService: NotificationsService,
|
||||
) {}
|
||||
|
||||
async getProfile(studentId: number) {
|
||||
const student = await this.studentRepo.findOne({ where: { id: studentId } });
|
||||
if (!student) throw new NotFoundException('学生不存在');
|
||||
|
||||
const [
|
||||
profileRaw,
|
||||
enrollments,
|
||||
examScores,
|
||||
learningRecords,
|
||||
resultArchive,
|
||||
attachments,
|
||||
] = await Promise.all([
|
||||
this.profileRepo.findOne({ where: await this.scope.filter({ studentId }) }),
|
||||
this.enrollmentRepo.find({
|
||||
where: await this.scope.filter({ studentId }),
|
||||
order: { createdAt: 'DESC' },
|
||||
}),
|
||||
this.examScoreRepo.find({
|
||||
where: await this.scope.filter({ studentId }),
|
||||
order: { examDate: 'DESC' },
|
||||
}),
|
||||
this.learningRecordRepo.find({
|
||||
where: await this.scope.filter({ studentId }),
|
||||
order: { recordDate: 'DESC' },
|
||||
}),
|
||||
this.resultRepo.findOne({ where: await this.scope.filter({ studentId }) }),
|
||||
this.attachmentRepo.find({
|
||||
where: await this.scope.filter({ studentId }),
|
||||
order: { createdAt: 'DESC' },
|
||||
}),
|
||||
]);
|
||||
|
||||
return {
|
||||
student,
|
||||
profile: profileRaw,
|
||||
enrollments,
|
||||
examScores,
|
||||
learningRecords,
|
||||
resultArchive,
|
||||
attachments,
|
||||
};
|
||||
}
|
||||
|
||||
async upsertProfile(studentId: number, dto: UpsertProfileDto) {
|
||||
const student = await this.studentRepo.findOne({ where: { id: studentId } });
|
||||
if (!student) throw new NotFoundException('学生不存在');
|
||||
|
||||
let profile = await this.profileRepo.findOne({ where: { studentId } });
|
||||
if (profile) {
|
||||
Object.assign(profile, dto);
|
||||
} else {
|
||||
profile = this.profileRepo.create({ ...dto, studentId });
|
||||
}
|
||||
return this.profileRepo.save(profile);
|
||||
}
|
||||
|
||||
async addEnrollment(studentId: number, dto: CreateEnrollmentDto) {
|
||||
const student = await this.studentRepo.findOne({ where: { id: studentId } });
|
||||
if (!student) throw new NotFoundException('学生不存在');
|
||||
|
||||
const entity = this.enrollmentRepo.create({ ...dto, studentId });
|
||||
return this.enrollmentRepo.save(entity);
|
||||
}
|
||||
|
||||
async updateEnrollment(id: number, dto: Partial<CreateEnrollmentDto>) {
|
||||
const entity = await this.enrollmentRepo.findOne({ where: { id } });
|
||||
if (!entity) throw new NotFoundException('报名记录不存在');
|
||||
Object.assign(entity, dto);
|
||||
return this.enrollmentRepo.save(entity);
|
||||
}
|
||||
|
||||
async deleteEnrollment(id: number) {
|
||||
const entity = await this.enrollmentRepo.findOne({ where: { id } });
|
||||
if (!entity) throw new NotFoundException('报名记录不存在');
|
||||
await this.enrollmentRepo.remove(entity);
|
||||
return { message: '已删除' };
|
||||
}
|
||||
|
||||
async addExamScore(studentId: number, dto: CreateExamScoreDto) {
|
||||
const student = await this.studentRepo.findOne({ where: { id: studentId } });
|
||||
if (!student) throw new NotFoundException('学生不存在');
|
||||
|
||||
const entity = this.examScoreRepo.create({ ...dto, studentId });
|
||||
return this.examScoreRepo.save(entity);
|
||||
}
|
||||
|
||||
async updateExamScore(id: number, dto: Partial<CreateExamScoreDto>) {
|
||||
const entity = await this.examScoreRepo.findOne({ where: { id } });
|
||||
if (!entity) throw new NotFoundException('考试成绩不存在');
|
||||
Object.assign(entity, dto);
|
||||
return this.examScoreRepo.save(entity);
|
||||
}
|
||||
|
||||
async deleteExamScore(id: number) {
|
||||
const entity = await this.examScoreRepo.findOne({ where: { id } });
|
||||
if (!entity) throw new NotFoundException('考试成绩不存在');
|
||||
await this.examScoreRepo.remove(entity);
|
||||
return { message: '已删除' };
|
||||
}
|
||||
|
||||
async addLearningRecord(studentId: number, dto: CreateLearningRecordDto) {
|
||||
const student = await this.studentRepo.findOne({ where: { id: studentId } });
|
||||
if (!student) throw new NotFoundException('学生不存在');
|
||||
|
||||
const entity = this.learningRecordRepo.create({ ...dto, studentId });
|
||||
return this.learningRecordRepo.save(entity);
|
||||
}
|
||||
|
||||
async updateLearningRecord(id: number, dto: Partial<CreateLearningRecordDto>) {
|
||||
const entity = await this.learningRecordRepo.findOne({ where: { id } });
|
||||
if (!entity) throw new NotFoundException('学习记录不存在');
|
||||
Object.assign(entity, dto);
|
||||
return this.learningRecordRepo.save(entity);
|
||||
}
|
||||
|
||||
async deleteLearningRecord(id: number) {
|
||||
const entity = await this.learningRecordRepo.findOne({ where: { id } });
|
||||
if (!entity) throw new NotFoundException('学习记录不存在');
|
||||
await this.learningRecordRepo.remove(entity);
|
||||
return { message: '已删除' };
|
||||
}
|
||||
|
||||
async upsertResult(studentId: number, dto: UpsertResultDto) {
|
||||
const student = await this.studentRepo.findOne({ where: { id: studentId } });
|
||||
if (!student) throw new NotFoundException('学生不存在');
|
||||
|
||||
let result = await this.resultRepo.findOne({ where: { studentId } });
|
||||
if (result) {
|
||||
Object.assign(result, dto);
|
||||
} else {
|
||||
result = this.resultRepo.create({ ...dto, studentId });
|
||||
}
|
||||
return this.resultRepo.save(result);
|
||||
}
|
||||
|
||||
async addAttachment(studentId: number, file: Express.Multer.File, category: string) {
|
||||
const student = await this.studentRepo.findOne({ where: { id: studentId } });
|
||||
if (!student) throw new NotFoundException('学生不存在');
|
||||
|
||||
const uploadDir = path.join(process.cwd(), 'uploads', 'archive');
|
||||
if (!fs.existsSync(uploadDir)) {
|
||||
fs.mkdirSync(uploadDir, { recursive: true });
|
||||
}
|
||||
|
||||
const ext = path.extname(file.originalname);
|
||||
const filename = `${studentId}_${Date.now()}${ext}`;
|
||||
const filePath = path.join(uploadDir, filename);
|
||||
fs.writeFileSync(filePath, file.buffer);
|
||||
|
||||
const entity = this.attachmentRepo.create({
|
||||
studentId,
|
||||
category,
|
||||
fileName: file.originalname,
|
||||
filePath: `uploads/archive/${filename}`,
|
||||
fileSize: file.size,
|
||||
mimeType: file.mimetype,
|
||||
});
|
||||
return this.attachmentRepo.save(entity);
|
||||
}
|
||||
|
||||
async deleteAttachment(id: number) {
|
||||
const entity = await this.attachmentRepo.findOne({ where: { id } });
|
||||
if (!entity) throw new NotFoundException('附件不存在');
|
||||
|
||||
const absPath = path.join(process.cwd(), entity.filePath);
|
||||
if (fs.existsSync(absPath)) {
|
||||
fs.unlinkSync(absPath);
|
||||
}
|
||||
|
||||
await this.attachmentRepo.remove(entity);
|
||||
return { message: '已删除' };
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user