新增AI教练模块,包括控制器、服务、模型及数据传输对象,更新应用模块以引入新模块,同时在打卡模块中添加按时间范围返回每日打卡状态的功能
This commit is contained in:
@@ -25,6 +25,7 @@ import { DeleteAccountDto, DeleteAccountResponseDto } from './dto/delete-account
|
||||
import { GuestLoginDto, GuestLoginResponseDto, RefreshGuestTokenDto, RefreshGuestTokenResponseDto } from './dto/guest-login.dto';
|
||||
import { AppStoreServerNotificationDto, ProcessNotificationResponseDto, NotificationType } from './dto/app-store-notification.dto';
|
||||
import { RevenueCatEvent } from './models/revenue-cat-event.model';
|
||||
import { UserProfile } from './models/user-profile.model';
|
||||
import { RevenueCatWebhookDto, RevenueCatEventType } from './dto/revenue-cat-webhook.dto';
|
||||
import { RestorePurchaseDto, RestorePurchaseResponseDto, RestoredPurchaseInfo, ActiveEntitlement, NonSubscriptionTransaction } from './dto/restore-purchase.dto';
|
||||
import { PurchaseRestoreLog, RestoreStatus, RestoreSource } from './models/purchase-restore-log.model';
|
||||
@@ -49,6 +50,8 @@ export class UsersService {
|
||||
private applePurchaseService: ApplePurchaseService,
|
||||
@InjectModel(BlockedTransaction)
|
||||
private blockedTransactionModel: typeof BlockedTransaction,
|
||||
@InjectModel(UserProfile)
|
||||
private userProfileModel: typeof UserProfile,
|
||||
@InjectConnection()
|
||||
private sequelize: Sequelize,
|
||||
) { }
|
||||
@@ -77,10 +80,18 @@ export class UsersService {
|
||||
};
|
||||
}
|
||||
|
||||
const profile = await this.userProfileModel.findByPk(existingUser.id);
|
||||
const returnData = {
|
||||
...existingUser.toJSON(),
|
||||
maxUsageCount: DEFAULT_FREE_USAGE_COUNT,
|
||||
isVip: existingUser.isVip,
|
||||
profile: profile ? {
|
||||
dailyStepsGoal: profile.dailyStepsGoal,
|
||||
dailyCaloriesGoal: profile.dailyCaloriesGoal,
|
||||
pilatesPurposes: profile.pilatesPurposes,
|
||||
weight: profile.weight,
|
||||
height: profile.height,
|
||||
} : undefined,
|
||||
}
|
||||
|
||||
this.logger.log(`getProfile returnData: ${JSON.stringify(returnData, null, 2)}`);
|
||||
@@ -107,7 +118,7 @@ export class UsersService {
|
||||
|
||||
// 更新用户昵称、头像
|
||||
async updateUser(updateUserDto: UpdateUserDto): Promise<UpdateUserResponseDto> {
|
||||
const { userId, name, avatar, gender, birthDate } = updateUserDto;
|
||||
const { userId, name, avatar, gender, birthDate, dailyStepsGoal, dailyCaloriesGoal, pilatesPurposes, weight, height } = updateUserDto;
|
||||
|
||||
this.logger.log(`updateUser: ${JSON.stringify(updateUserDto, null, 2)}`);
|
||||
|
||||
@@ -136,7 +147,19 @@ export class UsersService {
|
||||
|
||||
await user.save();
|
||||
|
||||
|
||||
// 更新或创建扩展信息
|
||||
if (dailyStepsGoal !== undefined || dailyCaloriesGoal !== undefined || pilatesPurposes !== undefined || weight !== undefined || height !== undefined) {
|
||||
const [profile] = await this.userProfileModel.findOrCreate({
|
||||
where: { userId },
|
||||
defaults: { userId },
|
||||
});
|
||||
if (dailyStepsGoal !== undefined) profile.dailyStepsGoal = dailyStepsGoal as any;
|
||||
if (dailyCaloriesGoal !== undefined) profile.dailyCaloriesGoal = dailyCaloriesGoal as any;
|
||||
if (pilatesPurposes !== undefined) profile.pilatesPurposes = pilatesPurposes as any;
|
||||
if (weight !== undefined) profile.weight = weight as any;
|
||||
if (height !== undefined) profile.height = height as any;
|
||||
await profile.save();
|
||||
}
|
||||
|
||||
return {
|
||||
code: ResponseCode.SUCCESS,
|
||||
@@ -192,6 +215,9 @@ export class UsersService {
|
||||
isNewUser = true;
|
||||
this.logger.log(`创建新的Apple用户: ${userId}`);
|
||||
|
||||
// 创建默认扩展记录
|
||||
await this.userProfileModel.findOrCreate({ where: { userId }, defaults: { userId } });
|
||||
|
||||
} else {
|
||||
// 更新现有用户的登录时间
|
||||
user.lastLogin = new Date();
|
||||
@@ -204,11 +230,19 @@ export class UsersService {
|
||||
const refreshToken = this.appleAuthService.generateRefreshToken(userId);
|
||||
|
||||
// 构造用户数据
|
||||
const profileForLogin = await this.userProfileModel.findByPk(user.id);
|
||||
const userData = {
|
||||
...user.toJSON(),
|
||||
isNew: isNewUser,
|
||||
isVip: user.isVip,
|
||||
maxUsageCount: DEFAULT_FREE_USAGE_COUNT,
|
||||
profile: profileForLogin ? {
|
||||
dailyStepsGoal: profileForLogin.dailyStepsGoal,
|
||||
dailyCaloriesGoal: profileForLogin.dailyCaloriesGoal,
|
||||
pilatesPurposes: profileForLogin.pilatesPurposes,
|
||||
weight: profileForLogin.weight,
|
||||
height: profileForLogin.height,
|
||||
} : undefined,
|
||||
};
|
||||
|
||||
return {
|
||||
@@ -295,6 +329,12 @@ export class UsersService {
|
||||
transaction,
|
||||
});
|
||||
|
||||
// 2. 删除用户扩展信息
|
||||
await this.userProfileModel.destroy({
|
||||
where: { userId },
|
||||
transaction,
|
||||
});
|
||||
|
||||
// 最后删除用户本身
|
||||
await this.userModel.destroy({
|
||||
where: { id: userId },
|
||||
@@ -364,6 +404,8 @@ export class UsersService {
|
||||
isNewUser = true;
|
||||
this.logger.log(`创建新的游客用户: ${guestUserId}`);
|
||||
|
||||
await this.userProfileModel.findOrCreate({ where: { userId: guestUserId }, defaults: { userId: guestUserId } });
|
||||
|
||||
} else {
|
||||
// 更新现有游客用户的登录时间和设备信息
|
||||
user.lastLogin = new Date();
|
||||
@@ -378,12 +420,20 @@ export class UsersService {
|
||||
const refreshToken = this.appleAuthService.generateRefreshToken(guestUserId);
|
||||
|
||||
// 构造用户数据
|
||||
const profileForGuest = await this.userProfileModel.findByPk(user.id);
|
||||
const userData = {
|
||||
...user.toJSON(),
|
||||
isNew: isNewUser,
|
||||
isVip: user.membershipExpiration ? dayjs(user.membershipExpiration).isAfter(dayjs()) : false,
|
||||
isGuest: true,
|
||||
maxUsageCount: DEFAULT_FREE_USAGE_COUNT,
|
||||
profile: profileForGuest ? {
|
||||
dailyStepsGoal: profileForGuest.dailyStepsGoal,
|
||||
dailyCaloriesGoal: profileForGuest.dailyCaloriesGoal,
|
||||
pilatesPurposes: profileForGuest.pilatesPurposes,
|
||||
weight: profileForGuest.weight,
|
||||
height: profileForGuest.height,
|
||||
} : undefined,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user