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,