From 12acbbd1664bec328276a5bbf0bf199577ef9994 Mon Sep 17 00:00:00 2001 From: richarjiang Date: Mon, 29 Sep 2025 17:12:54 +0800 Subject: [PATCH] =?UTF-8?q?feat(challenges):=20=E6=96=B0=E5=A2=9E=E4=BB=8A?= =?UTF-8?q?=E6=97=A5=E6=89=93=E5=8D=A1=E7=8A=B6=E6=80=81=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E5=B9=B6=E6=9B=B4=E6=96=B0=E8=BF=9B=E5=BA=A6=E6=9E=84=E5=BB=BA?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 ChallengeProgressDto 中增加 checkedInToday 字段 - 修改 buildChallengeProgress 方法,支持传入 lastProgressAt 参数 - 所有调用处同步更新,确保返回包含今日打卡状态 - 使用 dayjs 判断最后进度时间是否为今日 --- src/challenges/challenges.service.ts | 21 +++++++++++++------- src/challenges/dto/challenge-progress.dto.ts | 1 + 2 files changed, 15 insertions(+), 7 deletions(-) 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 {