feat: integrate invitation access, world NPCs, and deployment

This commit is contained in:
2026-09-08 22:22:38 +08:00
parent 2a3125075f
commit 513a3eba31
75 changed files with 9566 additions and 1070 deletions

View File

@@ -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}`);
// 调用核心服务发送验证码