From c775d5c6b02fc9ef093fa69a8fa908b37e374392 Mon Sep 17 00:00:00 2001 From: richarjiang Date: Wed, 8 Apr 2026 16:12:18 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/config/config.module.ts | 2 +- .../entities/share-level-progress.entity.ts | 5 +- src/modules/share/share.service.ts | 66 ++++++++++--------- 3 files changed, 37 insertions(+), 36 deletions(-) diff --git a/src/config/config.module.ts b/src/config/config.module.ts index a58c04f..2ea12b4 100644 --- a/src/config/config.module.ts +++ b/src/config/config.module.ts @@ -10,7 +10,7 @@ import { validateEnvironment } from './env.validation'; isGlobal: true, load: [databaseConfig], validate: validateEnvironment, - envFilePath: ['.env', '.env.local', '.env.production'], + envFilePath: ['.env.local', '.env.production', '.env'], }), ], exports: [ConfigModule], diff --git a/src/modules/share/entities/share-level-progress.entity.ts b/src/modules/share/entities/share-level-progress.entity.ts index e681dc1..c481441 100644 --- a/src/modules/share/entities/share-level-progress.entity.ts +++ b/src/modules/share/entities/share-level-progress.entity.ts @@ -2,7 +2,6 @@ import { Entity, PrimaryGeneratedColumn, Column, - CreateDateColumn, ManyToOne, JoinColumn, Index, @@ -39,6 +38,6 @@ export class ShareLevelProgress { @Column({ type: 'int', default: 0, name: 'time_spent' }) timeSpent!: number; - @CreateDateColumn({ name: 'completed_at' }) - completedAt!: Date; + @Column({ type: 'timestamp', name: 'completed_at', nullable: true, default: null }) + completedAt!: Date | null; } diff --git a/src/modules/share/share.service.ts b/src/modules/share/share.service.ts index 57529b2..dbf5ba7 100644 --- a/src/modules/share/share.service.ts +++ b/src/modules/share/share.service.ts @@ -114,73 +114,68 @@ export class ShareService { userId: string, dto: ReportLevelProgressDto, ): Promise { - // 1. 查找分享配置 - const config = await this.shareConfigRepository.findByShareCode( - dto.shareCode, - ); + const [config, level] = await Promise.all([ + this.shareConfigRepository.findByShareCode(dto.shareCode), + this.levelRepository.findById(dto.levelId), + ]); + if (!config) { throw new NotFoundException('分享不存在或已过期'); } - - // 2. 查找关卡获取时间限制(提前查找,后面会用到) - const level = await this.levelRepository.findById(dto.levelId); if (!level) { throw new NotFoundException('关卡不存在'); } - // 3. 查找或创建 ShareParticipant + if (!config.levelIds.includes(dto.levelId)) { + throw new BadRequestException('该关卡不属于此分享挑战'); + } + let participant = await this.shareParticipantRepository.findByShareConfigAndParticipant( config.id, userId, ); if (!participant) { - participant = await this.shareParticipantRepository.create({ + participant = this.shareParticipantRepository.create({ shareConfigId: config.id, participantId: userId, }); participant = await this.shareParticipantRepository.save(participant); } - // 4. 查找现有进度 - let progress = + const progress = await this.shareLevelProgressRepository.findByParticipantAndLevel( participant.id, dto.levelId, ); - // 5. 如果 passed=true 且已有通关记录,直接返回(不覆盖) if (dto.passed && progress?.passed) { - const wasWithinTimeLimit = - level.timeLimit === null || progress.timeSpent <= level.timeLimit; return { passed: true, timeLimit: level.timeLimit, - withinTimeLimit: wasWithinTimeLimit, + withinTimeLimit: this.isWithinTimeLimit(level.timeLimit, progress.timeSpent), }; } - // 6. 判断是否在时间限制内通过 const withinTimeLimit = dto.passed - ? level.timeLimit === null || dto.timeSpent <= level.timeLimit + ? this.isWithinTimeLimit(level.timeLimit, dto.timeSpent) : false; - // 7. 创建或更新进度 - if (progress) { - progress.passed = dto.passed; - progress.timeSpent = dto.timeSpent; - progress.completedAt = dto.passed ? new Date() : progress.completedAt; - } else { - progress = this.shareLevelProgressRepository.create({ - participantId: participant.id, - levelId: dto.levelId, - passed: dto.passed, - timeSpent: dto.timeSpent, - completedAt: dto.passed ? new Date() : undefined, - }); - } + const updatedProgress = progress + ? Object.assign(this.shareLevelProgressRepository.create(progress), { + passed: dto.passed, + timeSpent: dto.timeSpent, + completedAt: dto.passed ? new Date() : progress.completedAt, + }) + : this.shareLevelProgressRepository.create({ + participantId: participant.id, + levelId: dto.levelId, + passed: dto.passed, + timeSpent: dto.timeSpent, + completedAt: dto.passed ? new Date() : null, + }); - await this.shareLevelProgressRepository.save(progress); + await this.shareLevelProgressRepository.save(updatedProgress); return { passed: dto.passed, @@ -188,4 +183,11 @@ export class ShareService { withinTimeLimit, }; } + + private isWithinTimeLimit( + timeLimit: number | null, + timeSpent: number, + ): boolean { + return timeLimit === null || timeSpent <= timeLimit; + } }