更新服务器地址和项目名称,移除不必要的客户端日志相关代码,添加阻止交易模型,调整端口号及相关文档内容
This commit is contained in:
@@ -12,32 +12,18 @@ import { InjectModel, InjectConnection } from '@nestjs/sequelize';
|
||||
import { Gender, User } from './models/user.model';
|
||||
import { UserResponseDto } from './dto/user-response.dto';
|
||||
import { ResponseCode } from 'src/base.dto';
|
||||
import { UserRelationInfo } from './models/user-relation-info.model';
|
||||
import { UserRelationInfoDto, UserRelationInfoResponseDto } from './dto/user-relation-info.dto';
|
||||
import { TopicLibrary } from './models/topic-library.model';
|
||||
import { Transaction, Op } from 'sequelize';
|
||||
import { Sequelize } from 'sequelize-typescript';
|
||||
import { UpdateUserDto, UpdateUserResponseDto } from './dto/update-user.dto';
|
||||
|
||||
import { TopicCategory } from './models/topic-category.model';
|
||||
import { UserPurchase, PurchaseType, PurchaseStatus, PurchasePlatform } from './models/user-purchase.model';
|
||||
import { ApplePurchaseService } from './services/apple-purchase.service';
|
||||
import * as dayjs from 'dayjs';
|
||||
import { UpdateMembershipDto, UpdateMembershipResponseDto } from './dto/membership.dto';
|
||||
import { ClientLog } from './models/client-log.model';
|
||||
import {
|
||||
CreateClientLogDto,
|
||||
CreateBatchClientLogDto,
|
||||
CreateClientLogResponseDto,
|
||||
CreateBatchClientLogResponseDto,
|
||||
} from './dto/client-log.dto';
|
||||
import { EncryptionService } from 'src/common/encryption.service';
|
||||
import { AccessTokenPayload, AppleAuthService, AppleTokenPayload } from './services/apple-auth.service';
|
||||
import { AppleLoginDto, AppleLoginResponseDto, RefreshTokenDto, RefreshTokenResponseDto } from './dto/apple-login.dto';
|
||||
import { DeleteAccountDto, DeleteAccountResponseDto } from './dto/delete-account.dto';
|
||||
import { GuestLoginDto, GuestLoginResponseDto, RefreshGuestTokenDto, RefreshGuestTokenResponseDto } from './dto/guest-login.dto';
|
||||
import { AppStoreServerNotificationDto, ProcessNotificationResponseDto, NotificationType } from './dto/app-store-notification.dto';
|
||||
import { TopicService } from './topic.service';
|
||||
import { RevenueCatEvent } from './models/revenue-cat-event.model';
|
||||
import { RevenueCatWebhookDto, RevenueCatEventType } from './dto/revenue-cat-webhook.dto';
|
||||
import { RestorePurchaseDto, RestorePurchaseResponseDto, RestoredPurchaseInfo, ActiveEntitlement, NonSubscriptionTransaction } from './dto/restore-purchase.dto';
|
||||
@@ -53,26 +39,16 @@ export class UsersService {
|
||||
@Inject(WINSTON_MODULE_PROVIDER) private readonly winstonLogger: WinstonLogger,
|
||||
@InjectModel(User)
|
||||
private userModel: typeof User,
|
||||
@InjectModel(UserRelationInfo)
|
||||
private userRelationInfoModel: typeof UserRelationInfo,
|
||||
@InjectModel(TopicLibrary)
|
||||
private topicLibraryModel: typeof TopicLibrary,
|
||||
@InjectModel(TopicCategory)
|
||||
private topicCategoryModel: typeof TopicCategory,
|
||||
@InjectModel(UserPurchase)
|
||||
private userPurchaseModel: typeof UserPurchase,
|
||||
@InjectModel(ClientLog)
|
||||
private clientLogModel: typeof ClientLog,
|
||||
@InjectModel(RevenueCatEvent)
|
||||
private revenueCatEventModel: typeof RevenueCatEvent,
|
||||
@InjectModel(PurchaseRestoreLog)
|
||||
private purchaseRestoreLogModel: typeof PurchaseRestoreLog,
|
||||
@InjectModel(BlockedTransaction)
|
||||
private blockedTransactionModel: typeof BlockedTransaction,
|
||||
private encryptionService: EncryptionService,
|
||||
private appleAuthService: AppleAuthService,
|
||||
private applePurchaseService: ApplePurchaseService,
|
||||
private topicService: TopicService,
|
||||
@InjectModel(BlockedTransaction)
|
||||
private blockedTransactionModel: typeof BlockedTransaction,
|
||||
@InjectConnection()
|
||||
private sequelize: Sequelize,
|
||||
) { }
|
||||
@@ -101,13 +77,9 @@ export class UsersService {
|
||||
};
|
||||
}
|
||||
|
||||
// 查询已收藏的话题数量
|
||||
const favoriteTopicCount = await this.topicService.getFavoriteTopicCount(existingUser.id);
|
||||
|
||||
const returnData = {
|
||||
...existingUser.toJSON(),
|
||||
maxUsageCount: DEFAULT_FREE_USAGE_COUNT,
|
||||
favoriteTopicCount,
|
||||
isVip: existingUser.isVip,
|
||||
}
|
||||
|
||||
@@ -176,192 +148,6 @@ export class UsersService {
|
||||
};
|
||||
}
|
||||
|
||||
async updateOrCreateRelationInfo(relationInfoDto: UserRelationInfoDto): Promise<UserRelationInfoResponseDto> {
|
||||
try {
|
||||
this.logger.log(`updateOrCreateRelationInfo: ${JSON.stringify(relationInfoDto, null, 2)}`);
|
||||
// 检查userId是否存在于用户表中
|
||||
const user = await this.userModel.findByPk(relationInfoDto.userId);
|
||||
if (!user) {
|
||||
return {
|
||||
code: ResponseCode.ERROR,
|
||||
message: `ID为${relationInfoDto.userId}的用户不存在`,
|
||||
data: null as any,
|
||||
};
|
||||
}
|
||||
|
||||
// 查找是否已存在关系信息
|
||||
const existingInfo = await this.userRelationInfoModel.findOne({
|
||||
where: { userId: relationInfoDto.userId },
|
||||
});
|
||||
|
||||
if (existingInfo) {
|
||||
// 存在则更新
|
||||
await existingInfo.update(relationInfoDto, {
|
||||
where: { userId: relationInfoDto.userId },
|
||||
});
|
||||
return {
|
||||
code: ResponseCode.SUCCESS,
|
||||
message: 'success',
|
||||
data: existingInfo,
|
||||
};
|
||||
} else {
|
||||
// 不存在则创建
|
||||
const newRelationInfo = await this.userRelationInfoModel.create({
|
||||
...relationInfoDto,
|
||||
});
|
||||
return {
|
||||
code: ResponseCode.SUCCESS,
|
||||
message: 'success',
|
||||
data: newRelationInfo,
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error(`更新或创建关系信息失败: ${error instanceof Error ? error.message : '未知错误'}`);
|
||||
if (error instanceof NotFoundException) {
|
||||
throw error;
|
||||
}
|
||||
return {
|
||||
code: ResponseCode.ERROR,
|
||||
message: `更新或创建关系信息失败: ${error instanceof Error ? error.message : '未知错误'}`,
|
||||
data: null as any,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async getRelationInfo(userId: string): Promise<UserRelationInfoResponseDto> {
|
||||
try {
|
||||
const relationInfos = await this.userRelationInfoModel.findAll({
|
||||
where: { userId },
|
||||
});
|
||||
|
||||
if (!relationInfos.length) {
|
||||
const newRelationInfo = await this.userRelationInfoModel.create({
|
||||
userId,
|
||||
});
|
||||
return {
|
||||
code: ResponseCode.ERROR,
|
||||
message: '关系信息不存在',
|
||||
data: newRelationInfo,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
code: ResponseCode.SUCCESS,
|
||||
message: 'success',
|
||||
data: relationInfos[0],
|
||||
};
|
||||
} catch (error) {
|
||||
this.logger.error(`获取关系信息失败: ${error instanceof Error ? error.message : '未知错误'}`);
|
||||
return {
|
||||
code: ResponseCode.ERROR,
|
||||
message: `获取关系信息失败: ${error instanceof Error ? error.message : '未知错误'}`,
|
||||
data: null as any,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// 内部方法:计算订阅过期时间, 根据会员当前的有效期累加新的有效期
|
||||
private calculateExpirationDate(purchaseType: PurchaseType, currentExpiration: Date): Date {
|
||||
this.logger.log(`calculateExpirationDate purchaseType: ${purchaseType}, currentExpiration: ${currentExpiration}`);
|
||||
switch (purchaseType) {
|
||||
case PurchaseType.WEEKLY:
|
||||
return dayjs(currentExpiration ?? new Date()).add(7, 'day').toDate();
|
||||
case PurchaseType.QUARTERLY:
|
||||
return dayjs(currentExpiration ?? new Date()).add(90, 'day').toDate();
|
||||
case PurchaseType.LIFETIME:
|
||||
return dayjs(currentExpiration ?? new Date()).add(365 * 100, 'day').toDate();
|
||||
default:
|
||||
throw new BadRequestException('无效的购买类型');
|
||||
}
|
||||
}
|
||||
|
||||
// 创建客户端日志
|
||||
async createClientLog(createClientLogDto: CreateClientLogDto): Promise<CreateClientLogResponseDto> {
|
||||
try {
|
||||
this.logger.log(`createClientLog: ${JSON.stringify(createClientLogDto, null, 2)}`);
|
||||
|
||||
const { userId, logContent, logLevel, clientVersion, deviceModel, iosVersion, clientTimestamp } = createClientLogDto;
|
||||
|
||||
// 检查用户是否存在
|
||||
const user = await this.userModel.findByPk(userId);
|
||||
if (!user) {
|
||||
return {
|
||||
code: ResponseCode.ERROR,
|
||||
message: `ID为${userId}的用户不存在`,
|
||||
data: null as any,
|
||||
};
|
||||
}
|
||||
|
||||
// 创建日志记录
|
||||
const clientLog = await this.clientLogModel.create({
|
||||
userId,
|
||||
logContent,
|
||||
logLevel,
|
||||
clientVersion,
|
||||
deviceModel,
|
||||
iosVersion,
|
||||
clientTimestamp: clientTimestamp ? new Date(clientTimestamp) : null,
|
||||
});
|
||||
|
||||
return {
|
||||
code: ResponseCode.SUCCESS,
|
||||
message: 'success',
|
||||
data: clientLog.toJSON(),
|
||||
};
|
||||
} catch (error) {
|
||||
this.logger.error(`创建客户端日志失败: ${error instanceof Error ? error.message : '未知错误'}`);
|
||||
return {
|
||||
code: ResponseCode.ERROR,
|
||||
message: `创建客户端日志失败: ${error instanceof Error ? error.message : '未知错误'}`,
|
||||
data: null as any,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// 批量创建客户端日志
|
||||
async createBatchClientLog(createBatchClientLogDto: CreateBatchClientLogDto): Promise<CreateBatchClientLogResponseDto> {
|
||||
try {
|
||||
this.logger.log(`createBatchClientLog: ${JSON.stringify(createBatchClientLogDto, null, 2)}`);
|
||||
|
||||
const { userId, logs } = createBatchClientLogDto;
|
||||
|
||||
// 检查用户是否存在
|
||||
const user = await this.userModel.findByPk(userId);
|
||||
if (!user) {
|
||||
return {
|
||||
code: ResponseCode.ERROR,
|
||||
message: `ID为${userId}的用户不存在`,
|
||||
data: null as any,
|
||||
};
|
||||
}
|
||||
|
||||
// 批量创建日志记录
|
||||
const clientLogs = await this.clientLogModel.bulkCreate(
|
||||
logs.map(log => ({
|
||||
userId,
|
||||
logContent: log.logContent,
|
||||
logLevel: log.logLevel,
|
||||
clientVersion: log.clientVersion,
|
||||
deviceModel: log.deviceModel,
|
||||
iosVersion: log.iosVersion,
|
||||
clientTimestamp: log.clientTimestamp ? new Date(log.clientTimestamp) : null,
|
||||
}))
|
||||
);
|
||||
|
||||
return {
|
||||
code: ResponseCode.SUCCESS,
|
||||
message: 'success',
|
||||
data: clientLogs.map(log => log.toJSON()),
|
||||
};
|
||||
} catch (error) {
|
||||
this.logger.error(`批量创建客户端日志失败: ${error instanceof Error ? error.message : '未知错误'}`);
|
||||
return {
|
||||
code: ResponseCode.ERROR,
|
||||
message: `批量创建客户端日志失败: ${error instanceof Error ? error.message : '未知错误'}`,
|
||||
data: null as any,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apple 登录
|
||||
@@ -406,8 +192,6 @@ export class UsersService {
|
||||
isNewUser = true;
|
||||
this.logger.log(`创建新的Apple用户: ${userId}`);
|
||||
|
||||
// 创建三条话题,不消耗次数
|
||||
await this.topicService.generateTopic('初识破冰', userId, false, true, 3);
|
||||
} else {
|
||||
// 更新现有用户的登录时间
|
||||
user.lastLogin = new Date();
|
||||
@@ -415,8 +199,6 @@ export class UsersService {
|
||||
this.logger.log(`Apple用户登录: ${userId}`);
|
||||
}
|
||||
|
||||
const favoriteTopicCount = await this.topicService.getFavoriteTopicCount(userId);
|
||||
|
||||
// 生成访问令牌和刷新令牌
|
||||
const accessToken = this.appleAuthService.generateAccessToken(userId, user.mail);
|
||||
const refreshToken = this.appleAuthService.generateRefreshToken(userId);
|
||||
@@ -427,7 +209,6 @@ export class UsersService {
|
||||
isNew: isNewUser,
|
||||
isVip: user.isVip,
|
||||
maxUsageCount: DEFAULT_FREE_USAGE_COUNT,
|
||||
favoriteTopicCount,
|
||||
};
|
||||
|
||||
return {
|
||||
@@ -508,41 +289,19 @@ export class UsersService {
|
||||
}
|
||||
|
||||
// 开始删除用户相关数据(使用事务确保数据一致性)
|
||||
// 1. 删除用户关系信息
|
||||
await this.userRelationInfoModel.destroy({
|
||||
where: { userId },
|
||||
transaction,
|
||||
});
|
||||
|
||||
// 2. 删除用户购买记录
|
||||
// 1. 删除用户购买记录
|
||||
await this.userPurchaseModel.destroy({
|
||||
where: { userId },
|
||||
transaction,
|
||||
});
|
||||
|
||||
// 3. 删除用户客户端日志
|
||||
await this.clientLogModel.destroy({
|
||||
where: { userId },
|
||||
transaction,
|
||||
});
|
||||
|
||||
// 4. 删除用户的个人话题
|
||||
// 删除收藏
|
||||
await this.topicService.deleteFavoriteTopics(userId, transaction);
|
||||
|
||||
await this.topicLibraryModel.destroy({
|
||||
where: { userId },
|
||||
transaction,
|
||||
});
|
||||
|
||||
// 5. 最后删除用户本身
|
||||
// 最后删除用户本身
|
||||
await this.userModel.destroy({
|
||||
where: { id: userId },
|
||||
transaction,
|
||||
});
|
||||
|
||||
|
||||
|
||||
// 提交事务
|
||||
await transaction.commit();
|
||||
|
||||
@@ -605,8 +364,6 @@ export class UsersService {
|
||||
isNewUser = true;
|
||||
this.logger.log(`创建新的游客用户: ${guestUserId}`);
|
||||
|
||||
// 创建三条话题,不消耗次数
|
||||
await this.topicService.generateTopic('初识破冰', guestUserId, false, true, 3);
|
||||
} else {
|
||||
// 更新现有游客用户的登录时间和设备信息
|
||||
user.lastLogin = new Date();
|
||||
@@ -627,7 +384,6 @@ export class UsersService {
|
||||
isVip: user.membershipExpiration ? dayjs(user.membershipExpiration).isAfter(dayjs()) : false,
|
||||
isGuest: true,
|
||||
maxUsageCount: DEFAULT_FREE_USAGE_COUNT,
|
||||
favoriteTopicCount: 0,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user