perf: 支持分享提交答案的接口
This commit is contained in:
@@ -8,6 +8,14 @@ type ShareParticipantCountRow = {
|
||||
participantCount: string;
|
||||
};
|
||||
|
||||
export type ShareParticipantRankingRow = {
|
||||
shareConfigId: string;
|
||||
participantId: string;
|
||||
correctCount: number;
|
||||
totalTimeSpent: number;
|
||||
submittedAt: Date;
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
export class ShareParticipantRepository {
|
||||
constructor(
|
||||
@@ -55,6 +63,107 @@ export class ShareParticipantRepository {
|
||||
);
|
||||
}
|
||||
|
||||
async upsertSubmissionSummary(data: {
|
||||
shareConfigId: string;
|
||||
participantId: string;
|
||||
correctCount: number;
|
||||
totalTimeSpent: number;
|
||||
submittedAt: Date;
|
||||
}): Promise<void> {
|
||||
await this.repository
|
||||
.createQueryBuilder()
|
||||
.insert()
|
||||
.into(ShareParticipant)
|
||||
.values(data)
|
||||
.orUpdate(
|
||||
['correctCount', 'totalTimeSpent', 'submittedAt'],
|
||||
['shareConfigId', 'participantId'],
|
||||
)
|
||||
.execute();
|
||||
}
|
||||
|
||||
async countSubmittedByShareConfigId(shareConfigId: string): Promise<number> {
|
||||
return this.repository
|
||||
.createQueryBuilder('participant')
|
||||
.where('participant.shareConfigId = :shareConfigId', { shareConfigId })
|
||||
.andWhere('participant.submittedAt IS NOT NULL')
|
||||
.getCount();
|
||||
}
|
||||
|
||||
async countSubmittedByShareConfigIds(
|
||||
shareConfigIds: string[],
|
||||
): Promise<Map<string, number>> {
|
||||
if (shareConfigIds.length === 0) {
|
||||
return new Map();
|
||||
}
|
||||
|
||||
const rows = await this.repository
|
||||
.createQueryBuilder('participant')
|
||||
.select('participant.shareConfigId', 'shareConfigId')
|
||||
.addSelect('COUNT(*)', 'participantCount')
|
||||
.where('participant.shareConfigId IN (:...shareConfigIds)', {
|
||||
shareConfigIds,
|
||||
})
|
||||
.andWhere('participant.submittedAt IS NOT NULL')
|
||||
.groupBy('participant.shareConfigId')
|
||||
.getRawMany<ShareParticipantCountRow>();
|
||||
|
||||
return new Map(
|
||||
rows.map((row) => [row.shareConfigId, Number(row.participantCount)]),
|
||||
);
|
||||
}
|
||||
|
||||
async findSubmittedRankingsByShareConfigId(
|
||||
shareConfigId: string,
|
||||
): Promise<ShareParticipantRankingRow[]> {
|
||||
const rows = await this.repository
|
||||
.createQueryBuilder('participant')
|
||||
.where('participant.shareConfigId = :shareConfigId', { shareConfigId })
|
||||
.andWhere('participant.submittedAt IS NOT NULL')
|
||||
.orderBy('participant.correctCount', 'DESC')
|
||||
.addOrderBy('participant.totalTimeSpent', 'ASC')
|
||||
.addOrderBy('participant.submittedAt', 'ASC')
|
||||
.addOrderBy('participant.participantId', 'ASC')
|
||||
.getMany();
|
||||
|
||||
return rows.map((row) => ({
|
||||
shareConfigId: row.shareConfigId,
|
||||
participantId: row.participantId,
|
||||
correctCount: row.correctCount,
|
||||
totalTimeSpent: row.totalTimeSpent,
|
||||
submittedAt: row.submittedAt!,
|
||||
}));
|
||||
}
|
||||
|
||||
async findSubmittedRankingsByShareConfigIds(
|
||||
shareConfigIds: string[],
|
||||
): Promise<ShareParticipantRankingRow[]> {
|
||||
if (shareConfigIds.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const rows = await this.repository
|
||||
.createQueryBuilder('participant')
|
||||
.where('participant.shareConfigId IN (:...shareConfigIds)', {
|
||||
shareConfigIds,
|
||||
})
|
||||
.andWhere('participant.submittedAt IS NOT NULL')
|
||||
.orderBy('participant.shareConfigId', 'ASC')
|
||||
.addOrderBy('participant.correctCount', 'DESC')
|
||||
.addOrderBy('participant.totalTimeSpent', 'ASC')
|
||||
.addOrderBy('participant.submittedAt', 'ASC')
|
||||
.addOrderBy('participant.participantId', 'ASC')
|
||||
.getMany();
|
||||
|
||||
return rows.map((row) => ({
|
||||
shareConfigId: row.shareConfigId,
|
||||
participantId: row.participantId,
|
||||
correctCount: row.correctCount,
|
||||
totalTimeSpent: row.totalTimeSpent,
|
||||
submittedAt: row.submittedAt!,
|
||||
}));
|
||||
}
|
||||
|
||||
async existsByShareConfigAndParticipant(
|
||||
shareConfigId: string,
|
||||
participantId: string,
|
||||
|
||||
Reference in New Issue
Block a user