feat(challenges): 新增今日打卡状态字段并更新进度构建逻辑
- 在 ChallengeProgressDto 中增加 checkedInToday 字段 - 修改 buildChallengeProgress 方法,支持传入 lastProgressAt 参数 - 所有调用处同步更新,确保返回包含今日打卡状态 - 使用 dayjs 判断最后进度时间是否为今日
This commit is contained in:
@@ -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<boolean> {
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ export interface ChallengeProgressDto {
|
||||
completed: number;
|
||||
target: number;
|
||||
remaining: number;
|
||||
checkedInToday: boolean;
|
||||
}
|
||||
|
||||
export interface RankingItemDto {
|
||||
|
||||
Reference in New Issue
Block a user