From 1c033cd8016dd17059fe2a0e14cc41dc383e2732 Mon Sep 17 00:00:00 2001 From: richarjiang Date: Sat, 15 Nov 2025 23:25:02 +0800 Subject: [PATCH] =?UTF-8?q?feat(badges):=20=E6=9B=B4=E6=96=B0=E5=8B=8B?= =?UTF-8?q?=E7=AB=A0=E7=B3=BB=E7=BB=9F=EF=BC=8C=E6=94=AF=E6=8C=81UUID?= =?UTF-8?q?=E4=BD=9C=E4=B8=BA=E5=8B=8B=E7=AB=A0ID=E7=B1=BB=E5=9E=8B=20feat?= =?UTF-8?q?(challenges):=20=E4=BC=98=E5=8C=96=E8=BF=9B=E5=BA=A6=E6=8A=A5?= =?UTF-8?q?=E5=91=8A=EF=BC=8C=E6=B7=BB=E5=8A=A0=E7=9D=A1=E7=9C=A0=E6=8C=91?= =?UTF-8?q?=E6=88=98=E5=8B=8B=E7=AB=A0=E6=8E=88=E4=BA=88=E9=80=BB=E8=BE=91?= =?UTF-8?q?=20fix(push-notifications):=20=E4=BF=AE=E5=A4=8D=E6=8E=A8?= =?UTF-8?q?=E9=80=81=E6=B5=8B=E8=AF=95=E6=9C=8D=E5=8A=A1=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=E8=BF=94=E5=9B=9E=E5=80=BC=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/challenges/challenges.service.ts | 69 ++++++++++++--------- src/push-notifications/push-test.service.ts | 2 +- src/users/models/user-badge.model.ts | 6 +- src/users/services/badge.service.ts | 2 +- 4 files changed, 46 insertions(+), 33 deletions(-) diff --git a/src/challenges/challenges.service.ts b/src/challenges/challenges.service.ts index 08630ee..9dd5dfa 100644 --- a/src/challenges/challenges.service.ts +++ b/src/challenges/challenges.service.ts @@ -473,38 +473,51 @@ export class ChallengesService { } } + this.winstonLogger.info('progress report updated', { + context: 'reportProgress', + userId, + challengeId, + reportDate, + reportedValue, + }) + + // 🎖️ 检查是否为睡眠挑战且完成了第一次打卡,授予 goodSleep 勋章 + if (challenge.type === ChallengeType.SLEEP) { + this.winstonLogger.info('检查是否为睡眠挑战且完成了第一次打卡,授予 goodSleep 勋章', { + context: 'reportProgress', + userId, + challengeId, + badgeCode: 'goodSleep', + }) + try { + await this.badgeService.awardBadge(userId, 'goodSleep', { + source: BadgeSource.CHALLENGE, + sourceId: challengeId, + metadata: { + challengeName: challenge.title, + challengeType: challenge.type, + }, + }); + this.winstonLogger.info('授予睡眠挑战勋章成功', { + context: 'reportProgress', + userId, + challengeId, + badgeCode: 'goodSleep', + }); + } catch (error) { + // 勋章授予失败不应影响主流程,仅记录日志 + this.winstonLogger.error('授予睡眠挑战勋章失败', { + context: 'reportProgress', + userId, + challengeId, + error: error instanceof Error ? error.message : '未知错误', + }); + } + } if (report.reportedValue >= reportCompletedValue && !dayjs(participant.lastProgressAt).isSame(dayjs(), 'd')) { participant.progressValue++ participant.lastProgressAt = now; - - // 🎖️ 检查是否为睡眠挑战且完成了第一次打卡,授予 goodSleep 勋章 - if (challenge.type === ChallengeType.SLEEP) { - try { - await this.badgeService.awardBadge(userId, 'goodSleep', { - source: BadgeSource.CHALLENGE, - sourceId: challengeId, - metadata: { - challengeName: challenge.title, - challengeType: challenge.type, - }, - }); - this.winstonLogger.info('授予睡眠挑战勋章成功', { - context: 'reportProgress', - userId, - challengeId, - badgeCode: 'goodSleep', - }); - } catch (error) { - // 勋章授予失败不应影响主流程,仅记录日志 - this.winstonLogger.error('授予睡眠挑战勋章失败', { - context: 'reportProgress', - userId, - challengeId, - error: error instanceof Error ? error.message : '未知错误', - }); - } - } } if (participant.progressValue >= (participant.challenge?.minimumCheckInDays || 0) && participant.status !== ChallengeParticipantStatus.COMPLETED) { diff --git a/src/push-notifications/push-test.service.ts b/src/push-notifications/push-test.service.ts index b5c94be..d3a6ef3 100644 --- a/src/push-notifications/push-test.service.ts +++ b/src/push-notifications/push-test.service.ts @@ -32,7 +32,7 @@ export class PushTestService implements OnModuleInit { async onModuleInit() { // 检查是否启用推送测试 const enablePushTest = this.configService.get('ENABLE_PUSH_TEST', false); - + return if (!enablePushTest) { this.logger.log('Push test is disabled. Skipping...'); return; diff --git a/src/users/models/user-badge.model.ts b/src/users/models/user-badge.model.ts index 221cd43..51d06b2 100644 --- a/src/users/models/user-badge.model.ts +++ b/src/users/models/user-badge.model.ts @@ -31,11 +31,11 @@ export enum BadgeSource { }) export class UserBadge extends Model { @Column({ - type: DataType.INTEGER, + type: DataType.CHAR(36), + defaultValue: DataType.UUIDV4, primaryKey: true, - autoIncrement: true, }) - declare id: number; + declare id: string; @ForeignKey(() => User) @Column({ diff --git a/src/users/services/badge.service.ts b/src/users/services/badge.service.ts index 4854fcc..d786fd0 100644 --- a/src/users/services/badge.service.ts +++ b/src/users/services/badge.service.ts @@ -78,7 +78,7 @@ export class BadgeService { * @param userId 用户ID */ async getUserBadges(userId: string): Promise