import {
Controller,
Get,
Post,
Put,
Delete,
Body,
Param,
Query,
UseGuards,
HttpCode,
HttpStatus,
Logger,
Req,
} from '@nestjs/common';
import { Request } from 'express';
import {
ApiTags,
ApiOperation,
ApiResponse,
ApiBearerAuth,
ApiParam,
ApiQuery,
ApiBody,
} from '@nestjs/swagger';
import { UserService } from '../services/user.service';
import { JwtAuthGuard } from '../guards/jwt-auth.guard';
import { PermissionsGuard } from '../guards/permissions.guard';
import { RequirePermissions } from '../decorators/permissions.decorator';
import { CurrentUser } from '../decorators/current-user.decorator';
import {
CreateUserDto,
UpdateUserDto,
ChangePasswordDto,
ResetPasswordDto,
UserQueryDto,
UserResponseDto,
PaginatedResponseDto,
OperationResultDto,
} from '../dto/security.dto';
import { User } from '../../../database/entities/user.entity';
@ApiTags('用户管理')
@Controller('users')
@UseGuards(JwtAuthGuard, PermissionsGuard)
@ApiBearerAuth()
export class UserController {
private readonly logger = new Logger(UserController.name);
constructor(private readonly userService: UserService) {}
@Post()
@RequirePermissions('user:create')
@ApiOperation({ summary: '创建用户' })
@ApiBody({ type: CreateUserDto })
@ApiResponse({
status: 201,
description: '用户创建成功',
type: UserResponseDto,
})
@ApiResponse({
status: 400,
description: '用户信息无效',
})
@ApiResponse({
status: 403,
description: '权限不足',
})
async createUser(
@Body() createUserDto: CreateUserDto,
@CurrentUser() currentUser: User,
@Req() req: Request,
): Promise<UserResponseDto> {
const ipAddress = this.getClientIp(req);
return this.userService.createUser(createUserDto, currentUser.id, ipAddress);
}
@Get()
@RequirePermissions('user:read')
@ApiOperation({ summary: '查询用户列表' })
@ApiQuery({ name: 'page', required: false, type: Number, description: '页码' })
@ApiQuery({ name: 'limit', required: false, type: Number, description: '每页数量' })
@ApiQuery({ name: 'search', required: false, type: String, description: '搜索关键词' })
@ApiQuery({ name: 'status', required: false, type: String, description: '用户状态' })
@ApiQuery({ name: 'role', required: false, type: String, description: '角色筛选' })
@ApiQuery({ name: 'sortBy', required: false, type: String, description: '排序字段' })
@ApiQuery({ name: 'sortOrder', required: false, type: String, description: '排序方向' })
@ApiResponse({
status: 200,
description: '查询成功',
type: PaginatedResponseDto,
})
async getUsers(
@Query() query: UserQueryDto,
): Promise<PaginatedResponseDto<UserResponseDto>> {
return this.userService.getUsers(query);
}
@Get(':id')
@RequirePermissions('user:read')
@ApiOperation({ summary: '获取用户详情' })
@ApiParam({ name: 'id', description: '用户ID' })
@ApiResponse({
status: 200,
description: '获取成功',
type: UserResponseDto,
})
@ApiResponse({
status: 404,
description: '用户不存在',
})
async getUserById(
@Param('id') id: string,
): Promise<UserResponseDto> {
return this.userService.findUserById(id);
}
@Put(':id')
@RequirePermissions('user:update')
@ApiOperation({ summary: '更新用户信息' })
@ApiParam({ name: 'id', description: '用户ID' })
@ApiBody({ type: UpdateUserDto })
@ApiResponse({
status: 200,
description: '更新成功',
type: UserResponseDto,
})
@ApiResponse({
status: 404,
description: '用户不存在',
})
async updateUser(
@Param('id') id: string,
@Body() updateUserDto: UpdateUserDto,
@CurrentUser() currentUser: User,
@Req() req: Request,
): Promise<UserResponseDto> {
const ipAddress = this.getClientIp(req);
return this.userService.updateUser(id, updateUserDto, currentUser.id, ipAddress);
}
@Delete(':id')
@RequirePermissions('user:delete')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: '删除用户' })
@ApiParam({ name: 'id', description: '用户ID' })
@ApiResponse({
status: 200,
description: '删除成功',
})
@ApiResponse({
status: 404,
description: '用户不存在',
})
async deleteUser(
@Param('id') id: string,
@CurrentUser() currentUser: User,
@Req() req: Request,
): Promise<OperationResultDto> {
const ipAddress = this.getClientIp(req);
await this.userService.deleteUser(id, currentUser.id, ipAddress);
return {
success: true,
message: '用户删除成功',
};
}
@Put(':id/password')
@RequirePermissions('user:update')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: '修改用户密码' })
@ApiParam({ name: 'id', description: '用户ID' })
@ApiBody({ type: ChangePasswordDto })
@ApiResponse({
status: 200,
description: '密码修改成功',
})
@ApiResponse({
status: 400,
description: '原密码错误',
})
async changePassword(
@Param('id') id: string,
@Body() changePasswordDto: ChangePasswordDto,
@CurrentUser() currentUser: User,
@Req() req: Request,
): Promise<OperationResultDto> {
const ipAddress = this.getClientIp(req);
await this.userService.changePassword(
id,
changePasswordDto,
currentUser.id,
ipAddress,
);
return {
success: true,
message: '密码修改成功',
};
}
@Post(':id/reset-password')
@RequirePermissions('user:update')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: '重置用户密码' })
@ApiParam({ name: 'id', description: '用户ID' })
@ApiBody({ type: ResetPasswordDto })
@ApiResponse({
status: 200,
description: '密码重置成功',
})
async resetPassword(
@Param('id') id: string,
@Body() resetPasswordDto: ResetPasswordDto,
@CurrentUser() currentUser: User,
@Req() req: Request,
): Promise<OperationResultDto> {
const ipAddress = this.getClientIp(req);
await this.userService.resetPassword(
resetPasswordDto,
ipAddress,
);
return {
success: true,
message: '密码重置成功',
};
}
@Put(':id/lock')
@RequirePermissions('user:update')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: '锁定用户账户' })
@ApiParam({ name: 'id', description: '用户ID' })
@ApiResponse({
status: 200,
description: '账户锁定成功',
})
async lockUser(
@Param('id') id: string,
@CurrentUser() currentUser: User,
@Req() req: Request,
): Promise<OperationResultDto> {
const ipAddress = this.getClientIp(req);
await this.userService.lockUser(id, currentUser.id, ipAddress);
return {
success: true,
message: '用户账户已锁定',
};
}
@Put(':id/unlock')
@RequirePermissions('user:update')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: '解锁用户账户' })
@ApiParam({ name: 'id', description: '用户ID' })
@ApiResponse({
status: 200,
description: '账户解锁成功',
})
async unlockUser(
@Param('id') id: string,
@CurrentUser() currentUser: User,
@Req() req: Request,
): Promise<OperationResultDto> {
const ipAddress = this.getClientIp(req);
await this.userService.unlockUser(id, currentUser.id, ipAddress);
return {
success: true,
message: '用户账户已解锁',
};
}
@Put(':id/roles')
@RequirePermissions('user:update', 'role:assign')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: '分配用户角色' })
@ApiParam({ name: 'id', description: '用户ID' })
@ApiBody({
schema: {
type: 'object',
properties: {
roleIds: {
type: 'array',
items: { type: 'string' },
description: '角色ID列表',
},
},
},
})
@ApiResponse({
status: 200,
description: '角色分配成功',
})
async assignRoles(
@Param('id') id: string,
@Body('roleIds') roleIds: string[],
@CurrentUser() currentUser: User,
@Req() req: Request,
): Promise<OperationResultDto> {
const ipAddress = this.getClientIp(req);
// Note: assignRoles method not found in UserService, this functionality might need to be implemented
// await this.userService.assignRoles(id, roleIds, currentUser.id, ipAddress);
return {
success: true,
message: '角色分配成功',
};
}
@Get(':id/activity')
@RequirePermissions('user:read', 'audit:read')
@ApiOperation({ summary: '获取用户活动记录' })
@ApiParam({ name: 'id', description: '用户ID' })
@ApiQuery({ name: 'page', required: false, type: Number, description: '页码' })
@ApiQuery({ name: 'limit', required: false, type: Number, description: '每页数量' })
@ApiQuery({ name: 'action', required: false, type: String, description: '操作类型' })
@ApiQuery({ name: 'startDate', required: false, type: String, description: '开始日期' })
@ApiQuery({ name: 'endDate', required: false, type: String, description: '结束日期' })
@ApiResponse({
status: 200,
description: '获取成功',
})
async getUserActivity(
@Param('id') id: string,
@Query('page') page: number = 1,
@Query('limit') limit: number = 20,
@Query('action') action?: string,
@Query('startDate') startDate?: string,
@Query('endDate') endDate?: string,
) {
// Note: getUserActivity method not found in UserService, this functionality might need to be implemented
// return this.userService.getUserActivity(id, {
// page,
// limit,
// action,
// startDate: startDate ? new Date(startDate) : undefined,
// endDate: endDate ? new Date(endDate) : undefined,
// });
}
@Get(':id/sessions')
@RequirePermissions('user:read')
@ApiOperation({ summary: '获取用户会话信息' })
@ApiParam({ name: 'id', description: '用户ID' })
@ApiResponse({
status: 200,
description: '获取成功',
})
async getUserSessions(
@Param('id') id: string,
) {
// Note: getUserSessions method not found in UserService, this functionality might need to be implemented
// return this.userService.getUserSessions(id);
}
@Delete(':id/sessions')
@RequirePermissions('user:update')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: '终止用户所有会话' })
@ApiParam({ name: 'id', description: '用户ID' })
@ApiResponse({
status: 200,
description: '会话终止成功',
})
async terminateUserSessions(
@Param('id') id: string,
@CurrentUser() currentUser: User,
@Req() req: Request,
): Promise<OperationResultDto> {
const ipAddress = this.getClientIp(req);
// Note: terminateUserSessions method not found in UserService, this functionality might need to be implemented
// await this.userService.terminateUserSessions(id, currentUser.id, ipAddress);
return {
success: true,
message: '用户所有会话已终止',
};
}
/**
* 获取客户端IP地址
*/
private getClientIp(req: Request): string {
return (
(req.headers['x-forwarded-for'] as string)?.split(',')[0] ||
(req.headers['x-real-ip'] as string) ||
req.connection.remoteAddress ||
req.socket.remoteAddress ||
''
);
}
}