diff --git a/apps/admin/src/pages/Users/index.tsx b/apps/admin/src/pages/Users/index.tsx
index b6684d1..a4802b2 100644
--- a/apps/admin/src/pages/Users/index.tsx
+++ b/apps/admin/src/pages/Users/index.tsx
@@ -10,7 +10,7 @@ import {
Tag,
Popconfirm,
} from 'antd';
-import { PlusOutlined, EditOutlined, DeleteOutlined, KeyOutlined, IdcardOutlined, InboxOutlined } from '@ant-design/icons';
+import { PlusOutlined, EditOutlined, KeyOutlined, IdcardOutlined, InboxOutlined } from '@ant-design/icons';
import dayjs from 'dayjs';
import api from '../../api';
import PermissionButton from '../../components/PermissionButton';
@@ -141,18 +141,6 @@ const UsersPage: React.FC = () => {
}
};
- const handleDelete = async (id: number) => {
- try {
- await api.delete(`/rbac/users/${id}`);
- message.success('已删除');
- fetchData();
- } catch (e: unknown) {
- const err = e as { message?: string };
- message.error(err?.message || '删除失败');
- }
- };
-
-
const handleResetPwd = (record: any) => {
setResetTarget(record);
pwdForm.resetFields();
@@ -253,13 +241,6 @@ const UsersPage: React.FC = () => {
归档
)}
- {record.username !== 'admin' && (
- handleDelete(record.id)}>
- }>
- 删除
-
-
- )}
),
},
diff --git a/apps/admin/src/test/fixtures.ts b/apps/admin/src/test/fixtures.ts
index 9d54a01..fb0aa9f 100644
--- a/apps/admin/src/test/fixtures.ts
+++ b/apps/admin/src/test/fixtures.ts
@@ -220,6 +220,6 @@ export const PERMISSION_NODES = [
'report:generate',
'log:view',
'role:view', 'role:add', 'role:update', 'role:delete',
- 'user:view', 'user:add', 'user:update', 'user:delete',
+ 'user:view', 'user:add', 'user:update',
'dashboard:view',
] as const;
diff --git a/apps/server/src/rbac/rbac.controller.ts b/apps/server/src/rbac/rbac.controller.ts
index 95b022d..6aa95e2 100644
--- a/apps/server/src/rbac/rbac.controller.ts
+++ b/apps/server/src/rbac/rbac.controller.ts
@@ -198,28 +198,6 @@ export class RbacController {
}
}
- @Delete('users/:id')
- @RequirePermission('user:delete')
- async deleteUser(@Param('id') id: string, @Request() req: any) {
- const { ipAddress, userAgent } = extractRequestInfo(req);
- try {
- const result = await this.rbacService.deleteUser(+id);
- await this.logService.log({
- userId: req.user?.id,
- username: req.user?.username,
- module: '账号',
- action: '删除账号',
- targetId: +id,
- targetType: 'user',
- ipAddress,
- userAgent,
- });
- return result;
- } catch (e: any) {
- throw new BadRequestException(e.message);
- }
- }
-
@Put('users/:id/archive')
@RequirePermission('user:edit')
async archiveUser(@Param('id') id: string) {
diff --git a/apps/server/src/rbac/rbac.service.ts b/apps/server/src/rbac/rbac.service.ts
index 4343dda..efc3e79 100644
--- a/apps/server/src/rbac/rbac.service.ts
+++ b/apps/server/src/rbac/rbac.service.ts
@@ -70,7 +70,6 @@ const PRESET_PERMISSIONS: Array<{ code: string; name: string; group: string }> =
{ code: 'user:view', name: '查看用户', group: 'user' },
{ code: 'user:create', name: '创建用户', group: 'user' },
{ code: 'user:edit', name: '编辑用户', group: 'user' },
- { code: 'user:delete', name: '删除用户', group: 'user' },
{ code: 'user:reset-password', name: '重置密码', group: 'user' },
{ code: 'role:view', name: '查看角色', group: 'role' },
{ code: 'role:create', name: '创建角色', group: 'role' },
@@ -250,7 +249,12 @@ export class RbacService {
await this.permRepo.save(this.permRepo.create(p));
}
}
- const allPerms = await this.permRepo.find();
+ const deprecatedUserDeletePermission = await this.permRepo.findOne({
+ where: { code: 'user:delete' },
+ });
+ const allPerms = (await this.permRepo.find()).filter(
+ (permission) => permission.code !== 'user:delete',
+ );
// Step 2: 幂等插入预置角色
for (const r of PRESET_ROLES) {
@@ -271,6 +275,19 @@ export class RbacService {
}
const allRoles = await this.roleRepo.find({ relations: ['permissions', 'users'] });
+ if (deprecatedUserDeletePermission) {
+ for (const role of allRoles) {
+ const permissions = role.permissions ?? [];
+ if (permissions.some((permission) => permission.id === deprecatedUserDeletePermission.id)) {
+ role.permissions = permissions.filter(
+ (permission) => permission.id !== deprecatedUserDeletePermission.id,
+ );
+ await this.roleRepo.save(role);
+ }
+ }
+ await this.permRepo.remove(deprecatedUserDeletePermission);
+ }
+
// Step 3: 合并旧角色并构建新的职责权限矩阵
for (const preset of PRESET_ROLES) {
const matchesPreset = (role: Role) =>
@@ -564,15 +581,6 @@ export class RbacService {
return { message: '已恢复为学员' };
}
- async deleteUser(id: number) {
- const user = await this.userRepo.findOne({ where: { id } });
- if (!user) throw new Error('用户不存在');
- if (user.username === 'admin') throw new Error('不能删除默认管理员');
- if (!user.isArchived) throw new Error('请先归档再删除');
- await this.userRepo.remove(user);
- return { message: '用户已删除' };
- }
-
// ---- 用户资料 ----
async getUserProfile(id: number) {
diff --git a/技术文档.md b/技术文档.md
index cdf614c..13c3d69 100644
--- a/技术文档.md
+++ b/技术文档.md
@@ -169,7 +169,8 @@
| GET | /api/auth/users | 用户列表 |
| PUT | /api/auth/users/:id | 编辑用户 |
| PUT | /api/auth/users/:id/password | 重置密码 |
-| DELETE | /api/auth/users/:id | 删除用户 |
+| PUT | /api/rbac/users/:id/archive | 归档用户 |
+| PUT | /api/rbac/users/:id/restore | 恢复用户 |
### 业务模块
| 方法 | 路径 | 说明 |