79 lines
1.9 KiB
TypeScript
Executable File
79 lines
1.9 KiB
TypeScript
Executable File
import {
|
|
ConflictException,
|
|
Injectable,
|
|
NotFoundException,
|
|
} from '@nestjs/common';
|
|
import { BaseService } from '../base/base.service';
|
|
import {
|
|
UserProfile,
|
|
db,
|
|
ObjectType,
|
|
Prisma,
|
|
EnrollmentStatus,
|
|
} from '@nice/common';
|
|
import { z } from 'zod';
|
|
import { EnrollSchema, UnenrollSchema } from './enroll.schema';
|
|
import EventBus, { CrudOperation } from '@server/utils/event-bus';
|
|
|
|
@Injectable()
|
|
export class EnrollmentService extends BaseService<Prisma.EnrollmentDelegate> {
|
|
constructor() {
|
|
super(db, ObjectType.COURSE);
|
|
}
|
|
async enroll(params: z.infer<typeof EnrollSchema>) {
|
|
const { studentId, postId } = params;
|
|
const result = await db.$transaction(async (tx) => {
|
|
// 检查是否已经报名
|
|
const existing = await tx.enrollment.findUnique({
|
|
where: {
|
|
studentId_postId: {
|
|
studentId: studentId,
|
|
postId: postId,
|
|
},
|
|
},
|
|
});
|
|
if (existing) {
|
|
throw new ConflictException('Already enrolled in this post');
|
|
}
|
|
// 创建报名记录
|
|
const enrollment = await tx.enrollment.create({
|
|
data: {
|
|
studentId: studentId,
|
|
postId: postId,
|
|
status: EnrollmentStatus.ACTIVE,
|
|
},
|
|
});
|
|
|
|
return enrollment;
|
|
});
|
|
|
|
EventBus.emit('dataChanged', {
|
|
type: ObjectType.ENROLLMENT,
|
|
operation: CrudOperation.CREATED,
|
|
data: result,
|
|
});
|
|
return result;
|
|
}
|
|
async unenroll(params: z.infer<typeof UnenrollSchema>) {
|
|
const { studentId, postId } = params;
|
|
const result = await db.enrollment.update({
|
|
where: {
|
|
studentId_postId: {
|
|
studentId,
|
|
postId,
|
|
},
|
|
},
|
|
data: {
|
|
status: EnrollmentStatus.CANCELLED,
|
|
},
|
|
});
|
|
|
|
EventBus.emit('dataChanged', {
|
|
type: ObjectType.ENROLLMENT,
|
|
operation: CrudOperation.UPDATED,
|
|
data: result,
|
|
});
|
|
return result;
|
|
}
|
|
}
|