forked from hangshuo652/aurak
fix: 代码整合修复 - Entity类型、题库生成、评估流程等14项修复
This commit is contained in:
@@ -526,6 +526,10 @@ private async getModel(tenantId: string): Promise<ChatOpenAI> {
|
||||
language,
|
||||
questions_json: questionsFromBank.length > 0 ? questionsFromBank : [],
|
||||
questionSource,
|
||||
startedAt: new Date(),
|
||||
currentQuestionStartedAt: new Date(),
|
||||
totalTimeLimit: template?.totalTimeLimit || 1800,
|
||||
perQuestionTimeLimit: template?.perQuestionTimeLimit || 300,
|
||||
};
|
||||
|
||||
const content = await this.getSessionContent(sessionData);
|
||||
@@ -1442,6 +1446,82 @@ const initialState: Partial<EvaluationState> = {
|
||||
};
|
||||
}
|
||||
|
||||
async getRadarStats(userId: string, tenantId: string, role: string, templateId?: string): Promise<any> {
|
||||
const isAdmin = role === 'super_admin' || role === 'admin';
|
||||
|
||||
const qb = this.sessionRepository.createQueryBuilder('session');
|
||||
qb.where('session.tenantId = :tenantId', { tenantId });
|
||||
qb.andWhere('session.status = :status', { status: AssessmentStatus.COMPLETED });
|
||||
|
||||
if (!isAdmin) {
|
||||
qb.andWhere('session.userId = :userId', { userId });
|
||||
}
|
||||
if (templateId) {
|
||||
qb.andWhere('session.templateId = :templateId', { templateId });
|
||||
}
|
||||
|
||||
const sessions = await qb.take(100).getMany();
|
||||
|
||||
const dimensionScores: Record<string, number[]> = {
|
||||
PROMPT: [],
|
||||
LLM: [],
|
||||
IDE: [],
|
||||
DEV_PATTERN: [],
|
||||
WORK_CAPABILITY: [],
|
||||
};
|
||||
|
||||
for (const session of sessions) {
|
||||
const messages = session.messages || [];
|
||||
for (const msg of messages) {
|
||||
if (msg.dimension && msg.score !== undefined) {
|
||||
dimensionScores[msg.dimension]?.push(msg.score);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const radarData: Record<string, number> = {};
|
||||
for (const [dim, scores] of Object.entries(dimensionScores)) {
|
||||
if (scores.length > 0) {
|
||||
radarData[dim] = Math.round((scores.reduce((a, b) => a + b, 0) / scores.length) * 10) / 10;
|
||||
} else {
|
||||
radarData[dim] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return { radarData, sampleCount: sessions.length };
|
||||
}
|
||||
|
||||
async getTrendStats(userId: string, tenantId: string, role: string, startDate?: string, endDate?: string): Promise<any> {
|
||||
const isAdmin = role === 'super_admin' || role === 'admin';
|
||||
|
||||
const qb = this.sessionRepository.createQueryBuilder('session');
|
||||
qb.where('session.tenantId = :tenantId', { tenantId });
|
||||
qb.andWhere('session.status = :status', { status: AssessmentStatus.COMPLETED });
|
||||
|
||||
if (!isAdmin) {
|
||||
qb.andWhere('session.userId = :userId', { userId });
|
||||
}
|
||||
if (startDate) {
|
||||
qb.andWhere('session.createdAt >= :startDate', { startDate: new Date(startDate) });
|
||||
}
|
||||
if (endDate) {
|
||||
qb.andWhere('session.createdAt <= :endDate', { endDate: new Date(endDate) });
|
||||
}
|
||||
|
||||
const sessions = await qb
|
||||
.orderBy('session.createdAt', 'ASC')
|
||||
.take(50)
|
||||
.getMany();
|
||||
|
||||
const trendData = sessions.map(session => ({
|
||||
date: session.createdAt,
|
||||
score: session.finalScore || 0,
|
||||
template: session.template?.name || '-',
|
||||
}));
|
||||
|
||||
return { trendData, count: sessions.length };
|
||||
}
|
||||
|
||||
async reviewAssessment(
|
||||
sessionId: string,
|
||||
newScore: number,
|
||||
@@ -1477,6 +1557,8 @@ const initialState: Partial<EvaluationState> = {
|
||||
}
|
||||
|
||||
session.finalScore = newScore;
|
||||
const passingScore = session.templateJson?.passingScore || 90;
|
||||
(session as any).passed = newScore >= passingScore;
|
||||
session.reviewedBy = reviewerId;
|
||||
session.reviewedAt = new Date();
|
||||
session.reviewComment = comment || null;
|
||||
@@ -1515,4 +1597,140 @@ const initialState: Partial<EvaluationState> = {
|
||||
this.logger.log(`[cleanupOldSessions] Deleted ${toDelete.length} old sessions for user ${userId}`);
|
||||
}
|
||||
}
|
||||
|
||||
async checkTimeLimits(sessionId: string): Promise<{
|
||||
totalTimeRemaining: number;
|
||||
questionTimeRemaining: number;
|
||||
isTotalTimeout: boolean;
|
||||
isQuestionTimeout: boolean;
|
||||
}> {
|
||||
const session = await this.sessionRepository.findOne({
|
||||
where: { id: sessionId },
|
||||
});
|
||||
|
||||
if (!session || session.status === AssessmentStatus.COMPLETED) {
|
||||
return {
|
||||
totalTimeRemaining: 0,
|
||||
questionTimeRemaining: 0,
|
||||
isTotalTimeout: true,
|
||||
isQuestionTimeout: true,
|
||||
};
|
||||
}
|
||||
|
||||
const now = new Date();
|
||||
const startTime = session.startedAt ? new Date(session.startedAt) : now;
|
||||
const questionStartTime = session.currentQuestionStartedAt ? new Date(session.currentQuestionStartedAt) : now;
|
||||
|
||||
const totalElapsed = Math.floor((now.getTime() - startTime.getTime()) / 1000);
|
||||
const questionElapsed = Math.floor((now.getTime() - questionStartTime.getTime()) / 1000);
|
||||
|
||||
const totalTimeRemaining = Math.max(0, session.totalTimeLimit - totalElapsed);
|
||||
const questionTimeRemaining = Math.max(0, session.perQuestionTimeLimit - questionElapsed);
|
||||
|
||||
return {
|
||||
totalTimeRemaining,
|
||||
questionTimeRemaining,
|
||||
isTotalTimeout: totalElapsed >= session.totalTimeLimit,
|
||||
isQuestionTimeout: questionElapsed >= session.perQuestionTimeLimit,
|
||||
};
|
||||
}
|
||||
|
||||
async updateQuestionStartTime(sessionId: string): Promise<void> {
|
||||
const session = await this.sessionRepository.findOne({
|
||||
where: { id: sessionId },
|
||||
});
|
||||
if (session) {
|
||||
session.currentQuestionStartedAt = new Date();
|
||||
await this.sessionRepository.save(session);
|
||||
}
|
||||
}
|
||||
|
||||
async verifyCertificate(certificateId: string): Promise<{
|
||||
valid: boolean;
|
||||
certificate?: {
|
||||
id: string;
|
||||
level: string;
|
||||
totalScore: number;
|
||||
passed: boolean;
|
||||
issuedAt: Date;
|
||||
userId: string;
|
||||
};
|
||||
message?: string;
|
||||
}> {
|
||||
const certificate = await this.certificateRepository.findOne({
|
||||
where: { id: certificateId },
|
||||
relations: ['user'],
|
||||
});
|
||||
|
||||
if (!certificate) {
|
||||
return { valid: false, message: 'Certificate not found' };
|
||||
}
|
||||
|
||||
return {
|
||||
valid: true,
|
||||
certificate: {
|
||||
id: certificate.id,
|
||||
level: certificate.level,
|
||||
totalScore: certificate.totalScore,
|
||||
passed: certificate.passed,
|
||||
issuedAt: certificate.issuedAt,
|
||||
userId: certificate.userId,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async getPublicCertificateInfo(sessionId: string): Promise<{
|
||||
exists: boolean;
|
||||
certificate?: {
|
||||
level: string;
|
||||
totalScore: number;
|
||||
passed: boolean;
|
||||
issuedAt: Date;
|
||||
dimensionScores: Record<string, number>;
|
||||
};
|
||||
message?: string;
|
||||
}> {
|
||||
const certificate = await this.certificateRepository.findOne({
|
||||
where: { sessionId },
|
||||
});
|
||||
|
||||
if (!certificate) {
|
||||
return { exists: false, message: 'Certificate not found for this session' };
|
||||
}
|
||||
|
||||
return {
|
||||
exists: true,
|
||||
certificate: {
|
||||
level: certificate.level,
|
||||
totalScore: certificate.totalScore,
|
||||
passed: certificate.passed,
|
||||
issuedAt: certificate.issuedAt,
|
||||
dimensionScores: certificate.dimensionScores || {},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async forceEndAssessment(sessionId: string): Promise<AssessmentSession> {
|
||||
const session = await this.sessionRepository.findOne({
|
||||
where: { id: sessionId },
|
||||
});
|
||||
|
||||
if (!session) {
|
||||
throw new NotFoundException('Assessment session not found');
|
||||
}
|
||||
|
||||
if (session.status === AssessmentStatus.COMPLETED) {
|
||||
return session;
|
||||
}
|
||||
|
||||
session.status = AssessmentStatus.COMPLETED;
|
||||
session.finalReport = '评估已被管理员强制结束';
|
||||
session.finalScore = 0;
|
||||
|
||||
await this.sessionRepository.save(session);
|
||||
|
||||
this.logger.log(`[forceEndAssessment] Session ${sessionId} force ended by admin`);
|
||||
|
||||
return session;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user