iconsulting/packages/services/evolution-service/src/adapters/inbound/admin.controller.ts

273 lines
6.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {
Controller,
Get,
Post,
Put,
Body,
Param,
Query,
Headers,
HttpCode,
HttpStatus,
UnauthorizedException,
ForbiddenException,
} from '@nestjs/common';
import { AdminService } from '../../application/services/admin.service';
import { AdminRole } from '../../domain/value-objects/admin-role.enum';
import {
LoginDto,
CreateAdminDto,
UpdateAdminDto,
ChangePasswordDto,
ResetPasswordDto,
LoginResult,
} from '../../application/dtos/admin.dto';
@Controller('admin')
export class AdminController {
constructor(private adminService: AdminService) {}
/**
* 管理员登录
*/
@Post('login')
@HttpCode(HttpStatus.OK)
async login(@Body() dto: LoginDto): Promise<{ success: boolean; data: LoginResult }> {
try {
const result = await this.adminService.login(dto.username, dto.password);
return {
success: true,
data: result,
};
} catch (error) {
throw new UnauthorizedException((error as Error).message);
}
}
/**
* 验证Token
*/
@Get('verify')
async verifyToken(@Headers('authorization') auth: string) {
const token = auth?.replace('Bearer ', '');
if (!token) {
throw new UnauthorizedException('Missing token');
}
const result = await this.adminService.verifyToken(token);
if (!result.valid) {
throw new UnauthorizedException('Invalid token');
}
return {
success: true,
data: result.admin,
};
}
/**
* 获取当前管理员信息
*/
@Get('me')
async getCurrentAdmin(@Headers('authorization') auth: string) {
const token = auth?.replace('Bearer ', '');
const result = await this.adminService.verifyToken(token);
if (!result.valid) {
throw new UnauthorizedException('Invalid token');
}
return {
success: true,
data: result.admin,
};
}
/**
* 创建管理员需要ADMIN权限
*/
@Post('admins')
@HttpCode(HttpStatus.CREATED)
async createAdmin(
@Headers('authorization') auth: string,
@Body() dto: CreateAdminDto,
) {
await this.checkPermission(auth, 'admin:create');
try {
const admin = await this.adminService.createAdmin(dto);
return {
success: true,
data: {
id: admin.id,
username: admin.username,
name: admin.name,
role: admin.role,
},
};
} catch (error) {
return {
success: false,
error: (error as Error).message,
};
}
}
/**
* 获取管理员列表
*/
@Get('admins')
async listAdmins(
@Headers('authorization') auth: string,
@Query('role') role?: AdminRole,
@Query('isActive') isActive?: string,
@Query('page') page?: string,
@Query('pageSize') pageSize?: string,
) {
await this.checkPermission(auth, 'admin:read');
const result = await this.adminService.listAdmins({
role,
isActive: isActive === undefined ? undefined : isActive === 'true',
page: page ? parseInt(page) : 1,
pageSize: pageSize ? parseInt(pageSize) : 20,
});
return {
success: true,
data: {
items: result.items.map(a => ({
id: a.id,
username: a.username,
name: a.name,
email: a.email,
phone: a.phone,
role: a.role,
isActive: a.isActive,
lastLoginAt: a.lastLoginAt,
createdAt: a.createdAt,
})),
total: result.total,
},
};
}
/**
* 更新管理员
*/
@Put('admins/:id')
async updateAdmin(
@Headers('authorization') auth: string,
@Param('id') id: string,
@Body() dto: UpdateAdminDto,
) {
await this.checkPermission(auth, 'admin:update');
try {
const admin = await this.adminService.updateAdmin(id, dto);
return {
success: true,
data: {
id: admin.id,
username: admin.username,
name: admin.name,
role: admin.role,
isActive: admin.isActive,
},
};
} catch (error) {
return {
success: false,
error: (error as Error).message,
};
}
}
/**
* 修改密码(当前用户)
*/
@Post('change-password')
async changePassword(
@Headers('authorization') auth: string,
@Body() dto: ChangePasswordDto,
) {
const token = auth?.replace('Bearer ', '');
const result = await this.adminService.verifyToken(token);
if (!result.valid || !result.admin) {
throw new UnauthorizedException('Invalid token');
}
try {
await this.adminService.changePassword(
result.admin.id,
dto.oldPassword,
dto.newPassword,
);
return {
success: true,
message: '密码修改成功',
};
} catch (error) {
return {
success: false,
error: (error as Error).message,
};
}
}
/**
* 重置密码(超管功能)
*/
@Post('admins/:id/reset-password')
async resetPassword(
@Headers('authorization') auth: string,
@Param('id') id: string,
@Body() dto: ResetPasswordDto,
) {
// 只有超管可以重置密码
const token = auth?.replace('Bearer ', '');
const result = await this.adminService.verifyToken(token);
if (!result.valid || !result.admin) {
throw new UnauthorizedException('Invalid token');
}
if (result.admin.role !== AdminRole.SUPER_ADMIN) {
throw new ForbiddenException('Only super admin can reset passwords');
}
try {
await this.adminService.resetPassword(id, dto.newPassword);
return {
success: true,
message: '密码重置成功',
};
} catch (error) {
return {
success: false,
error: (error as Error).message,
};
}
}
/**
* 检查权限
*/
private async checkPermission(auth: string, permission: string): Promise<void> {
const token = auth?.replace('Bearer ', '');
if (!token) {
throw new UnauthorizedException('Missing token');
}
const result = await this.adminService.verifyToken(token);
if (!result.valid || !result.admin) {
throw new UnauthorizedException('Invalid token');
}
if (!this.adminService.hasPermission(result.admin.permissions, permission)) {
throw new ForbiddenException(`Permission denied: ${permission}`);
}
}
}