From 6cdd2bc137bff4d1ecfdbaf4043814b4efcdc636 Mon Sep 17 00:00:00 2001 From: richarjiang Date: Tue, 2 Dec 2025 14:40:59 +0800 Subject: [PATCH] =?UTF-8?q?feat(users):=20=E6=B7=BB=E5=8A=A0App=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=8F=B7=E8=BF=BD=E8=B8=AA=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E7=94=A8=E6=88=B7=E7=89=88=E6=9C=AC=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/users/dto/user-response.dto.ts | 1 + src/users/models/user.model.ts | 7 +++++++ src/users/users.controller.ts | 9 ++++++--- src/users/users.service.ts | 12 +++++++++--- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/users/dto/user-response.dto.ts b/src/users/dto/user-response.dto.ts index 1380bce..a3bbfee 100644 --- a/src/users/dto/user-response.dto.ts +++ b/src/users/dto/user-response.dto.ts @@ -25,6 +25,7 @@ export interface UserWithPurchaseStatus { maxUsageCount: number; favoriteTopicCount: number; isVip: boolean; + appVersion?: string; profile?: Pick; } diff --git a/src/users/models/user.model.ts b/src/users/models/user.model.ts index 8453b41..10f8411 100644 --- a/src/users/models/user.model.ts +++ b/src/users/models/user.model.ts @@ -126,6 +126,13 @@ export class User extends Model { }) declare language: string; + @Column({ + type: DataType.STRING, + allowNull: true, + comment: '用户当前使用的App版本号', + }) + declare appVersion: string; + get isVip(): boolean { return this.membershipExpiration ? dayjs(this.membershipExpiration).isAfter(dayjs()) : false; } diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index 11602a2..1bcd5bf 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -68,9 +68,12 @@ export class UsersController { @ApiOperation({ summary: '获取用户信息' }) @ApiBody({ type: CreateUserDto }) @ApiResponse({ type: UserResponseDto }) - async getProfile(@CurrentUser() user: AccessTokenPayload): Promise { - this.logger.log(`get profile: ${JSON.stringify(user)}`); - return this.usersService.getProfile(user); + async getProfile( + @CurrentUser() user: AccessTokenPayload, + @AppVersion() appVersion: string | undefined, + ): Promise { + this.logger.log(`get profile: ${JSON.stringify(user)}, appVersion: ${appVersion}`); + return this.usersService.getProfile(user, appVersion); } // 获取历史体重记录 diff --git a/src/users/users.service.ts b/src/users/users.service.ts index ac65a6d..72c7416 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -87,10 +87,10 @@ export class UsersService { private readonly configService: ConfigService, ) { } - async getProfile(user: AccessTokenPayload): Promise { + async getProfile(user: AccessTokenPayload, appVersion?: string): Promise { try { // 使用NestJS Logger (会通过winston输出) - this.logger.log(`getProfile: ${JSON.stringify(user)}`); + this.logger.log(`getProfile: ${JSON.stringify(user)}, appVersion: ${appVersion}`); // 也可以直接使用winston logger this.winstonLogger.info('getProfile method called', { @@ -111,8 +111,13 @@ export class UsersService { }; } - // 更新用户最后登录时间 + // 更新用户最后登录时间和版本信息 existingUser.lastLogin = new Date(); + if (appVersion && existingUser.appVersion !== appVersion) { + const oldVersion = existingUser.appVersion; + existingUser.appVersion = appVersion; + this.logger.log(`用户 ${existingUser.id} 版本更新: ${oldVersion || '无'} -> ${appVersion}`); + } await existingUser.save(); const [profile] = await this.userProfileModel.findOrCreate({ @@ -136,6 +141,7 @@ export class UsersService { maxUsageCount: DEFAULT_FREE_USAGE_COUNT, isVip: existingUser.isVip, gender: existingUser.gender, + appVersion: existingUser.appVersion, dailyStepsGoal: profile?.dailyStepsGoal, dailyCaloriesGoal: profile?.dailyCaloriesGoal, pilatesPurposes: profile?.pilatesPurposes,