diff --git a/src/challenges/challenges.service.ts b/src/challenges/challenges.service.ts index 9d4b2e5..66475c2 100644 --- a/src/challenges/challenges.service.ts +++ b/src/challenges/challenges.service.ts @@ -75,7 +75,7 @@ export class ChallengesService { const completionTarget = challenge.minimumCheckInDays const participation = participationMap.get(challenge.id); const progress = participation - ? this.buildChallengeProgress(participation.progressValue, completionTarget) + ? this.buildChallengeProgress(participation.progressValue, completionTarget, participation.lastProgressAt) : undefined; return { @@ -167,7 +167,7 @@ export class ChallengesService { const completionTarget = challenge.minimumCheckInDays const progress = participation - ? this.buildChallengeProgress(participation.progressValue, completionTarget) + ? this.buildChallengeProgress(participation.progressValue, completionTarget, participation.lastProgressAt) : undefined; const rankings: RankingItemDto[] = rankingsRaw.map((item, index) => { @@ -245,7 +245,7 @@ export class ChallengesService { existing.leftAt = null; existing.lastProgressAt = null; await existing.save(); - return this.buildChallengeProgress(existing.progressValue, completionTarget); + return this.buildChallengeProgress(existing.progressValue, completionTarget, existing.lastProgressAt); } const participant = await this.participantModel.create({ @@ -257,7 +257,7 @@ export class ChallengesService { joinedAt: new Date(), }); - return this.buildChallengeProgress(participant.progressValue, completionTarget); + return this.buildChallengeProgress(participant.progressValue, completionTarget, participant.lastProgressAt); } async leaveChallenge(userId: string, challengeId: string): Promise { @@ -392,21 +392,28 @@ export class ChallengesService { }); - return this.buildChallengeProgress(participant.progressValue, participant.targetValue); + return this.buildChallengeProgress(participant.progressValue, participant.targetValue, participant.lastProgressAt); } catch (error) { if (error instanceof UniqueConstraintError) { - return this.buildChallengeProgress(participant.progressValue, participant.targetValue); + return this.buildChallengeProgress(participant.progressValue, participant.targetValue, participant.lastProgressAt); } throw error; } } - private buildChallengeProgress(completed: number, target: number, unit = '天'): ChallengeProgressDto { + private buildChallengeProgress( + completed: number, + target: number, + lastProgressAt?: Date | string | null, + unit = '天', + ): ChallengeProgressDto { const remaining = Math.max(target - completed, 0); + const checkedInToday = lastProgressAt ? dayjs(lastProgressAt).isSame(dayjs(), 'day') : false; return { completed, target, remaining, + checkedInToday, }; } diff --git a/src/challenges/dto/challenge-progress.dto.ts b/src/challenges/dto/challenge-progress.dto.ts index deb5fc3..8a5eac1 100644 --- a/src/challenges/dto/challenge-progress.dto.ts +++ b/src/challenges/dto/challenge-progress.dto.ts @@ -2,6 +2,7 @@ export interface ChallengeProgressDto { completed: number; target: number; remaining: number; + checkedInToday: boolean; } export interface RankingItemDto {