refactor:重构业务层服务架构
- 重构共享模块,移除冗余DTO定义 - 优化Zulip服务模块,重新组织控制器结构 - 更新用户管理和认证服务 - 移除过时的登录服务测试文件
This commit is contained in:
581
src/business/zulip/zulip_accounts.controller.ts
Normal file
581
src/business/zulip/zulip_accounts.controller.ts
Normal file
@@ -0,0 +1,581 @@
|
||||
/**
|
||||
* Zulip账号关联管理控制器
|
||||
*
|
||||
* 功能描述:
|
||||
* - 提供Zulip账号关联管理的REST API接口
|
||||
* - 支持CRUD操作和批量管理
|
||||
* - 提供账号验证和统计功能
|
||||
*
|
||||
* @author angjustinl
|
||||
* @version 1.0.0
|
||||
* @since 2025-01-07
|
||||
*/
|
||||
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Put,
|
||||
Delete,
|
||||
Body,
|
||||
Param,
|
||||
Query,
|
||||
UseGuards,
|
||||
HttpStatus,
|
||||
HttpCode,
|
||||
Inject,
|
||||
} from '@nestjs/common';
|
||||
import {
|
||||
ApiTags,
|
||||
ApiOperation,
|
||||
ApiResponse,
|
||||
ApiBearerAuth,
|
||||
ApiParam,
|
||||
ApiQuery,
|
||||
} from '@nestjs/swagger';
|
||||
import { JwtAuthGuard } from '../auth/jwt_auth.guard';
|
||||
import { ZulipAccountsService } from '../../core/db/zulip_accounts/zulip_accounts.service';
|
||||
import { ZulipAccountsMemoryService } from '../../core/db/zulip_accounts/zulip_accounts_memory.service';
|
||||
import {
|
||||
CreateZulipAccountDto,
|
||||
UpdateZulipAccountDto,
|
||||
QueryZulipAccountDto,
|
||||
ZulipAccountResponseDto,
|
||||
ZulipAccountListResponseDto,
|
||||
ZulipAccountStatsResponseDto,
|
||||
BatchUpdateStatusDto,
|
||||
BatchUpdateResponseDto,
|
||||
VerifyAccountDto,
|
||||
VerifyAccountResponseDto,
|
||||
} from '../../core/db/zulip_accounts/zulip_accounts.dto';
|
||||
|
||||
@ApiTags('zulip-accounts')
|
||||
@Controller('zulip-accounts')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth('JWT-auth')
|
||||
export class ZulipAccountsController {
|
||||
constructor(
|
||||
@Inject('ZulipAccountsService')
|
||||
private readonly zulipAccountsService: ZulipAccountsService | ZulipAccountsMemoryService,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* 创建Zulip账号关联
|
||||
*/
|
||||
@Post()
|
||||
@ApiOperation({
|
||||
summary: '创建Zulip账号关联',
|
||||
description: '为游戏用户创建与Zulip账号的关联关系'
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 201,
|
||||
description: '创建成功',
|
||||
type: ZulipAccountResponseDto,
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 400,
|
||||
description: '请求参数错误',
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 409,
|
||||
description: '关联已存在',
|
||||
})
|
||||
@HttpCode(HttpStatus.CREATED)
|
||||
async create(@Body() createDto: CreateZulipAccountDto): Promise<ZulipAccountResponseDto> {
|
||||
return this.zulipAccountsService.create(createDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有Zulip账号关联
|
||||
*/
|
||||
@Get()
|
||||
@ApiOperation({
|
||||
summary: '查询Zulip账号关联列表',
|
||||
description: '根据条件查询Zulip账号关联列表'
|
||||
})
|
||||
@ApiQuery({
|
||||
name: 'gameUserId',
|
||||
required: false,
|
||||
description: '游戏用户ID',
|
||||
example: '12345'
|
||||
})
|
||||
@ApiQuery({
|
||||
name: 'zulipUserId',
|
||||
required: false,
|
||||
description: 'Zulip用户ID',
|
||||
example: 67890
|
||||
})
|
||||
@ApiQuery({
|
||||
name: 'zulipEmail',
|
||||
required: false,
|
||||
description: 'Zulip邮箱地址',
|
||||
example: 'user@example.com'
|
||||
})
|
||||
@ApiQuery({
|
||||
name: 'status',
|
||||
required: false,
|
||||
description: '账号状态',
|
||||
enum: ['active', 'inactive', 'suspended', 'error']
|
||||
})
|
||||
@ApiQuery({
|
||||
name: 'includeGameUser',
|
||||
required: false,
|
||||
description: '是否包含游戏用户信息',
|
||||
type: Boolean,
|
||||
example: false
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: '查询成功',
|
||||
type: ZulipAccountListResponseDto,
|
||||
})
|
||||
async findMany(@Query() queryDto: QueryZulipAccountDto): Promise<ZulipAccountListResponseDto> {
|
||||
return this.zulipAccountsService.findMany(queryDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ID获取Zulip账号关联
|
||||
*/
|
||||
@Get(':id')
|
||||
@ApiOperation({
|
||||
summary: '根据ID获取Zulip账号关联',
|
||||
description: '根据关联记录ID获取详细信息'
|
||||
})
|
||||
@ApiParam({
|
||||
name: 'id',
|
||||
description: '关联记录ID',
|
||||
example: '1'
|
||||
})
|
||||
@ApiQuery({
|
||||
name: 'includeGameUser',
|
||||
required: false,
|
||||
description: '是否包含游戏用户信息',
|
||||
type: Boolean,
|
||||
example: false
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: '获取成功',
|
||||
type: ZulipAccountResponseDto,
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 404,
|
||||
description: '记录不存在',
|
||||
})
|
||||
async findById(
|
||||
@Param('id') id: string,
|
||||
@Query('includeGameUser') includeGameUser?: boolean,
|
||||
): Promise<ZulipAccountResponseDto> {
|
||||
return this.zulipAccountsService.findById(id, includeGameUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据游戏用户ID获取Zulip账号关联
|
||||
*/
|
||||
@Get('game-user/:gameUserId')
|
||||
@ApiOperation({
|
||||
summary: '根据游戏用户ID获取Zulip账号关联',
|
||||
description: '根据游戏用户ID获取关联的Zulip账号信息'
|
||||
})
|
||||
@ApiParam({
|
||||
name: 'gameUserId',
|
||||
description: '游戏用户ID',
|
||||
example: '12345'
|
||||
})
|
||||
@ApiQuery({
|
||||
name: 'includeGameUser',
|
||||
required: false,
|
||||
description: '是否包含游戏用户信息',
|
||||
type: Boolean,
|
||||
example: false
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: '获取成功',
|
||||
type: ZulipAccountResponseDto,
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 404,
|
||||
description: '关联不存在',
|
||||
})
|
||||
async findByGameUserId(
|
||||
@Param('gameUserId') gameUserId: string,
|
||||
@Query('includeGameUser') includeGameUser?: boolean,
|
||||
): Promise<ZulipAccountResponseDto | null> {
|
||||
return this.zulipAccountsService.findByGameUserId(gameUserId, includeGameUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据Zulip用户ID获取账号关联
|
||||
*/
|
||||
@Get('zulip-user/:zulipUserId')
|
||||
@ApiOperation({
|
||||
summary: '根据Zulip用户ID获取账号关联',
|
||||
description: '根据Zulip用户ID获取关联的游戏账号信息'
|
||||
})
|
||||
@ApiParam({
|
||||
name: 'zulipUserId',
|
||||
description: 'Zulip用户ID',
|
||||
example: '67890'
|
||||
})
|
||||
@ApiQuery({
|
||||
name: 'includeGameUser',
|
||||
required: false,
|
||||
description: '是否包含游戏用户信息',
|
||||
type: Boolean,
|
||||
example: false
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: '获取成功',
|
||||
type: ZulipAccountResponseDto,
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 404,
|
||||
description: '关联不存在',
|
||||
})
|
||||
async findByZulipUserId(
|
||||
@Param('zulipUserId') zulipUserId: string,
|
||||
@Query('includeGameUser') includeGameUser?: boolean,
|
||||
): Promise<ZulipAccountResponseDto | null> {
|
||||
return this.zulipAccountsService.findByZulipUserId(parseInt(zulipUserId), includeGameUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据Zulip邮箱获取账号关联
|
||||
*/
|
||||
@Get('zulip-email/:zulipEmail')
|
||||
@ApiOperation({
|
||||
summary: '根据Zulip邮箱获取账号关联',
|
||||
description: '根据Zulip邮箱地址获取关联的游戏账号信息'
|
||||
})
|
||||
@ApiParam({
|
||||
name: 'zulipEmail',
|
||||
description: 'Zulip邮箱地址',
|
||||
example: 'user@example.com'
|
||||
})
|
||||
@ApiQuery({
|
||||
name: 'includeGameUser',
|
||||
required: false,
|
||||
description: '是否包含游戏用户信息',
|
||||
type: Boolean,
|
||||
example: false
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: '获取成功',
|
||||
type: ZulipAccountResponseDto,
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 404,
|
||||
description: '关联不存在',
|
||||
})
|
||||
async findByZulipEmail(
|
||||
@Param('zulipEmail') zulipEmail: string,
|
||||
@Query('includeGameUser') includeGameUser?: boolean,
|
||||
): Promise<ZulipAccountResponseDto | null> {
|
||||
return this.zulipAccountsService.findByZulipEmail(zulipEmail, includeGameUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新Zulip账号关联
|
||||
*/
|
||||
@Put(':id')
|
||||
@ApiOperation({
|
||||
summary: '更新Zulip账号关联',
|
||||
description: '根据ID更新Zulip账号关联信息'
|
||||
})
|
||||
@ApiParam({
|
||||
name: 'id',
|
||||
description: '关联记录ID',
|
||||
example: '1'
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: '更新成功',
|
||||
type: ZulipAccountResponseDto,
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 404,
|
||||
description: '记录不存在',
|
||||
})
|
||||
async update(
|
||||
@Param('id') id: string,
|
||||
@Body() updateDto: UpdateZulipAccountDto,
|
||||
): Promise<ZulipAccountResponseDto> {
|
||||
return this.zulipAccountsService.update(id, updateDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据游戏用户ID更新关联
|
||||
*/
|
||||
@Put('game-user/:gameUserId')
|
||||
@ApiOperation({
|
||||
summary: '根据游戏用户ID更新关联',
|
||||
description: '根据游戏用户ID更新Zulip账号关联信息'
|
||||
})
|
||||
@ApiParam({
|
||||
name: 'gameUserId',
|
||||
description: '游戏用户ID',
|
||||
example: '12345'
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: '更新成功',
|
||||
type: ZulipAccountResponseDto,
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 404,
|
||||
description: '关联不存在',
|
||||
})
|
||||
async updateByGameUserId(
|
||||
@Param('gameUserId') gameUserId: string,
|
||||
@Body() updateDto: UpdateZulipAccountDto,
|
||||
): Promise<ZulipAccountResponseDto> {
|
||||
return this.zulipAccountsService.updateByGameUserId(gameUserId, updateDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除Zulip账号关联
|
||||
*/
|
||||
@Delete(':id')
|
||||
@ApiOperation({
|
||||
summary: '删除Zulip账号关联',
|
||||
description: '根据ID删除Zulip账号关联记录'
|
||||
})
|
||||
@ApiParam({
|
||||
name: 'id',
|
||||
description: '关联记录ID',
|
||||
example: '1'
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: '删除成功',
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
success: { type: 'boolean', example: true },
|
||||
message: { type: 'string', example: '删除成功' }
|
||||
}
|
||||
}
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 404,
|
||||
description: '记录不存在',
|
||||
})
|
||||
async delete(@Param('id') id: string): Promise<{ success: boolean; message: string }> {
|
||||
await this.zulipAccountsService.delete(id);
|
||||
return { success: true, message: '删除成功' };
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据游戏用户ID删除关联
|
||||
*/
|
||||
@Delete('game-user/:gameUserId')
|
||||
@ApiOperation({
|
||||
summary: '根据游戏用户ID删除关联',
|
||||
description: '根据游戏用户ID删除Zulip账号关联记录'
|
||||
})
|
||||
@ApiParam({
|
||||
name: 'gameUserId',
|
||||
description: '游戏用户ID',
|
||||
example: '12345'
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: '删除成功',
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
success: { type: 'boolean', example: true },
|
||||
message: { type: 'string', example: '删除成功' }
|
||||
}
|
||||
}
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 404,
|
||||
description: '关联不存在',
|
||||
})
|
||||
async deleteByGameUserId(@Param('gameUserId') gameUserId: string): Promise<{ success: boolean; message: string }> {
|
||||
await this.zulipAccountsService.deleteByGameUserId(gameUserId);
|
||||
return { success: true, message: '删除成功' };
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要验证的账号列表
|
||||
*/
|
||||
@Get('management/verification-needed')
|
||||
@ApiOperation({
|
||||
summary: '获取需要验证的账号列表',
|
||||
description: '获取超过指定时间未验证的账号列表'
|
||||
})
|
||||
@ApiQuery({
|
||||
name: 'maxAge',
|
||||
required: false,
|
||||
description: '最大验证间隔(毫秒),默认24小时',
|
||||
example: 86400000
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: '获取成功',
|
||||
type: ZulipAccountListResponseDto,
|
||||
})
|
||||
async findAccountsNeedingVerification(
|
||||
@Query('maxAge') maxAge?: number,
|
||||
): Promise<ZulipAccountListResponseDto> {
|
||||
return this.zulipAccountsService.findAccountsNeedingVerification(maxAge);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取错误状态的账号列表
|
||||
*/
|
||||
@Get('management/error-accounts')
|
||||
@ApiOperation({
|
||||
summary: '获取错误状态的账号列表',
|
||||
description: '获取处于错误状态的账号列表'
|
||||
})
|
||||
@ApiQuery({
|
||||
name: 'maxRetryCount',
|
||||
required: false,
|
||||
description: '最大重试次数,默认3次',
|
||||
example: 3
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: '获取成功',
|
||||
type: ZulipAccountListResponseDto,
|
||||
})
|
||||
async findErrorAccounts(
|
||||
@Query('maxRetryCount') maxRetryCount?: number,
|
||||
): Promise<ZulipAccountListResponseDto> {
|
||||
return this.zulipAccountsService.findErrorAccounts(maxRetryCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新账号状态
|
||||
*/
|
||||
@Put('management/batch-status')
|
||||
@ApiOperation({
|
||||
summary: '批量更新账号状态',
|
||||
description: '批量更新多个账号的状态'
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: '更新成功',
|
||||
type: BatchUpdateResponseDto,
|
||||
})
|
||||
async batchUpdateStatus(@Body() batchDto: BatchUpdateStatusDto): Promise<BatchUpdateResponseDto> {
|
||||
return this.zulipAccountsService.batchUpdateStatus(batchDto.ids, batchDto.status);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取账号状态统计
|
||||
*/
|
||||
@Get('management/statistics')
|
||||
@ApiOperation({
|
||||
summary: '获取账号状态统计',
|
||||
description: '获取各种状态的账号数量统计'
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: '获取成功',
|
||||
type: ZulipAccountStatsResponseDto,
|
||||
})
|
||||
async getStatusStatistics(): Promise<ZulipAccountStatsResponseDto> {
|
||||
return this.zulipAccountsService.getStatusStatistics();
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证账号有效性
|
||||
*/
|
||||
@Post('management/verify')
|
||||
@ApiOperation({
|
||||
summary: '验证账号有效性',
|
||||
description: '验证指定游戏用户的Zulip账号关联是否有效'
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: '验证完成',
|
||||
type: VerifyAccountResponseDto,
|
||||
})
|
||||
async verifyAccount(@Body() verifyDto: VerifyAccountDto): Promise<VerifyAccountResponseDto> {
|
||||
return this.zulipAccountsService.verifyAccount(verifyDto.gameUserId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查邮箱是否已存在
|
||||
*/
|
||||
@Get('validation/email-exists/:email')
|
||||
@ApiOperation({
|
||||
summary: '检查邮箱是否已存在',
|
||||
description: '检查指定的Zulip邮箱是否已被其他账号使用'
|
||||
})
|
||||
@ApiParam({
|
||||
name: 'email',
|
||||
description: 'Zulip邮箱地址',
|
||||
example: 'user@example.com'
|
||||
})
|
||||
@ApiQuery({
|
||||
name: 'excludeId',
|
||||
required: false,
|
||||
description: '排除的记录ID(用于更新时检查)',
|
||||
example: '1'
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: '检查完成',
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
exists: { type: 'boolean', example: false },
|
||||
email: { type: 'string', example: 'user@example.com' }
|
||||
}
|
||||
}
|
||||
})
|
||||
async checkEmailExists(
|
||||
@Param('email') email: string,
|
||||
@Query('excludeId') excludeId?: string,
|
||||
): Promise<{ exists: boolean; email: string }> {
|
||||
const exists = await this.zulipAccountsService.existsByEmail(email, excludeId);
|
||||
return { exists, email };
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查Zulip用户ID是否已存在
|
||||
*/
|
||||
@Get('validation/zulip-user-exists/:zulipUserId')
|
||||
@ApiOperation({
|
||||
summary: '检查Zulip用户ID是否已存在',
|
||||
description: '检查指定的Zulip用户ID是否已被其他账号使用'
|
||||
})
|
||||
@ApiParam({
|
||||
name: 'zulipUserId',
|
||||
description: 'Zulip用户ID',
|
||||
example: '67890'
|
||||
})
|
||||
@ApiQuery({
|
||||
name: 'excludeId',
|
||||
required: false,
|
||||
description: '排除的记录ID(用于更新时检查)',
|
||||
example: '1'
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: '检查完成',
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
exists: { type: 'boolean', example: false },
|
||||
zulipUserId: { type: 'number', example: 67890 }
|
||||
}
|
||||
}
|
||||
})
|
||||
async checkZulipUserIdExists(
|
||||
@Param('zulipUserId') zulipUserId: string,
|
||||
@Query('excludeId') excludeId?: string,
|
||||
): Promise<{ exists: boolean; zulipUserId: number }> {
|
||||
const zulipUserIdNum = parseInt(zulipUserId);
|
||||
const exists = await this.zulipAccountsService.existsByZulipUserId(zulipUserIdNum, excludeId);
|
||||
return { exists, zulipUserId: zulipUserIdNum };
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user