feat(users): 添加App版本号追踪功能,支持用户版本更新记录
This commit is contained in:
@@ -25,6 +25,7 @@ export interface UserWithPurchaseStatus {
|
|||||||
maxUsageCount: number;
|
maxUsageCount: number;
|
||||||
favoriteTopicCount: number;
|
favoriteTopicCount: number;
|
||||||
isVip: boolean;
|
isVip: boolean;
|
||||||
|
appVersion?: string;
|
||||||
profile?: Pick<UserProfile, 'dailyStepsGoal' | 'dailyCaloriesGoal' | 'pilatesPurposes' | 'weight' | 'initialWeight' | 'targetWeight' | 'height' | 'activityLevel'>;
|
profile?: Pick<UserProfile, 'dailyStepsGoal' | 'dailyCaloriesGoal' | 'pilatesPurposes' | 'weight' | 'initialWeight' | 'targetWeight' | 'height' | 'activityLevel'>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -126,6 +126,13 @@ export class User extends Model {
|
|||||||
})
|
})
|
||||||
declare language: string;
|
declare language: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: DataType.STRING,
|
||||||
|
allowNull: true,
|
||||||
|
comment: '用户当前使用的App版本号',
|
||||||
|
})
|
||||||
|
declare appVersion: string;
|
||||||
|
|
||||||
get isVip(): boolean {
|
get isVip(): boolean {
|
||||||
return this.membershipExpiration ? dayjs(this.membershipExpiration).isAfter(dayjs()) : false;
|
return this.membershipExpiration ? dayjs(this.membershipExpiration).isAfter(dayjs()) : false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,9 +68,12 @@ export class UsersController {
|
|||||||
@ApiOperation({ summary: '获取用户信息' })
|
@ApiOperation({ summary: '获取用户信息' })
|
||||||
@ApiBody({ type: CreateUserDto })
|
@ApiBody({ type: CreateUserDto })
|
||||||
@ApiResponse({ type: UserResponseDto })
|
@ApiResponse({ type: UserResponseDto })
|
||||||
async getProfile(@CurrentUser() user: AccessTokenPayload): Promise<UserResponseDto> {
|
async getProfile(
|
||||||
this.logger.log(`get profile: ${JSON.stringify(user)}`);
|
@CurrentUser() user: AccessTokenPayload,
|
||||||
return this.usersService.getProfile(user);
|
@AppVersion() appVersion: string | undefined,
|
||||||
|
): Promise<UserResponseDto> {
|
||||||
|
this.logger.log(`get profile: ${JSON.stringify(user)}, appVersion: ${appVersion}`);
|
||||||
|
return this.usersService.getProfile(user, appVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取历史体重记录
|
// 获取历史体重记录
|
||||||
|
|||||||
@@ -87,10 +87,10 @@ export class UsersService {
|
|||||||
private readonly configService: ConfigService,
|
private readonly configService: ConfigService,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
async getProfile(user: AccessTokenPayload): Promise<UserResponseDto> {
|
async getProfile(user: AccessTokenPayload, appVersion?: string): Promise<UserResponseDto> {
|
||||||
try {
|
try {
|
||||||
// 使用NestJS Logger (会通过winston输出)
|
// 使用NestJS Logger (会通过winston输出)
|
||||||
this.logger.log(`getProfile: ${JSON.stringify(user)}`);
|
this.logger.log(`getProfile: ${JSON.stringify(user)}, appVersion: ${appVersion}`);
|
||||||
|
|
||||||
// 也可以直接使用winston logger
|
// 也可以直接使用winston logger
|
||||||
this.winstonLogger.info('getProfile method called', {
|
this.winstonLogger.info('getProfile method called', {
|
||||||
@@ -111,8 +111,13 @@ export class UsersService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新用户最后登录时间
|
// 更新用户最后登录时间和版本信息
|
||||||
existingUser.lastLogin = new Date();
|
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();
|
await existingUser.save();
|
||||||
|
|
||||||
const [profile] = await this.userProfileModel.findOrCreate({
|
const [profile] = await this.userProfileModel.findOrCreate({
|
||||||
@@ -136,6 +141,7 @@ export class UsersService {
|
|||||||
maxUsageCount: DEFAULT_FREE_USAGE_COUNT,
|
maxUsageCount: DEFAULT_FREE_USAGE_COUNT,
|
||||||
isVip: existingUser.isVip,
|
isVip: existingUser.isVip,
|
||||||
gender: existingUser.gender,
|
gender: existingUser.gender,
|
||||||
|
appVersion: existingUser.appVersion,
|
||||||
dailyStepsGoal: profile?.dailyStepsGoal,
|
dailyStepsGoal: profile?.dailyStepsGoal,
|
||||||
dailyCaloriesGoal: profile?.dailyCaloriesGoal,
|
dailyCaloriesGoal: profile?.dailyCaloriesGoal,
|
||||||
pilatesPurposes: profile?.pilatesPurposes,
|
pilatesPurposes: profile?.pilatesPurposes,
|
||||||
|
|||||||
Reference in New Issue
Block a user