forked from xiangwang25/whale-town-end-v2
feat: integrate invitation access, world NPCs, and deployment
This commit is contained in:
@@ -23,12 +23,14 @@
|
||||
* @lastModified 2026-01-15
|
||||
*/
|
||||
|
||||
import { Injectable, Logger, Inject } from '@nestjs/common';
|
||||
import { Injectable, Logger, Inject, Optional } from '@nestjs/common';
|
||||
import { LoginCoreService, RegisterRequest } from '../../core/login_core/login_core.service';
|
||||
import { Users } from '../../core/db/users/users.entity';
|
||||
import { ZulipAccountService } from '../../core/zulip_core/services/zulip_account.service';
|
||||
import { ApiKeySecurityService } from '../../core/zulip_core/services/api_key_security.service';
|
||||
import { AccountProfilePayload, AccountProfileService } from './account_profile.service';
|
||||
import { InvitationCodesService } from '../invitation/invitation_codes.service';
|
||||
import { InvitationCode } from '../invitation/invitation_code.entity';
|
||||
|
||||
// Import the interface types we need
|
||||
interface IZulipAccountsService {
|
||||
@@ -112,6 +114,7 @@ export class RegisterService {
|
||||
@Inject('ZulipAccountsService') private readonly zulipAccountsService: IZulipAccountsService,
|
||||
private readonly apiKeySecurityService: ApiKeySecurityService,
|
||||
private readonly accountProfileService: AccountProfileService,
|
||||
@Optional() private readonly invitationCodesService?: InvitationCodesService,
|
||||
) {}
|
||||
|
||||
/**
|
||||
@@ -124,7 +127,12 @@ export class RegisterService {
|
||||
const startTime = Date.now();
|
||||
const operationId = `register_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
|
||||
|
||||
let reservation: InvitationCode | undefined;
|
||||
let userCreated = false;
|
||||
try {
|
||||
if (this.invitationCodesService) {
|
||||
reservation = await this.invitationCodesService.reserve(registerRequest.invitation_code || '');
|
||||
}
|
||||
this.logger.log(`开始用户注册流程`, {
|
||||
operation: 'register',
|
||||
operationId,
|
||||
@@ -146,6 +154,20 @@ export class RegisterService {
|
||||
|
||||
// 2. 调用核心服务进行注册
|
||||
const authResult = await this.loginCoreService.register(registerRequest);
|
||||
userCreated = true;
|
||||
if (reservation) {
|
||||
try {
|
||||
await this.invitationCodesService!.recordUsage(reservation.id, authResult.user.id, registerRequest.email || '');
|
||||
} catch (error) {
|
||||
this.logger.error('记录邀请码使用明细失败,不中断已完成的用户注册', {
|
||||
operation: 'register',
|
||||
operationId,
|
||||
invitationCodeId: reservation.id.toString(),
|
||||
gameUserId: authResult.user.id.toString(),
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 创建Zulip账号(使用相同的邮箱和密码)- 异步处理,不影响注册流程
|
||||
if (registerRequest.email && registerRequest.password && !zulipUnavailableForLocalDebug) {
|
||||
@@ -224,6 +246,9 @@ export class RegisterService {
|
||||
message: response.message
|
||||
};
|
||||
} catch (error) {
|
||||
if (reservation && !userCreated) {
|
||||
await this.invitationCodesService?.release(reservation.id).catch(() => undefined);
|
||||
}
|
||||
const duration = Date.now() - startTime;
|
||||
const err = error as Error;
|
||||
|
||||
@@ -251,8 +276,9 @@ export class RegisterService {
|
||||
* @param email 邮箱地址
|
||||
* @returns 响应结果
|
||||
*/
|
||||
async sendEmailVerification(email: string): Promise<ApiResponse<{ verification_code?: string; is_test_mode?: boolean }>> {
|
||||
async sendEmailVerification(email: string, invitationCode: string): Promise<ApiResponse<{ verification_code?: string; is_test_mode?: boolean }>> {
|
||||
try {
|
||||
if (this.invitationCodesService) await this.invitationCodesService.validate(invitationCode);
|
||||
this.logger.log(`发送邮箱验证码: ${email}`);
|
||||
|
||||
// 调用核心服务发送验证码
|
||||
|
||||
Reference in New Issue
Block a user