feat(admin): gate user/order/city delete behind assignable HQ permissions
CI / verify (pull_request) Has been cancelled

Add users_delete, orders_delete, cities_delete; default HQ (incl. super admin) has none until explicitly granted.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-28 14:01:18 +08:00
parent f4766d32ff
commit daeb24bbeb
10 changed files with 158 additions and 92 deletions
@@ -4,6 +4,7 @@ import {
HQ_ROLE_DEFAULT_PERMISSIONS,
LEGACY_SYSTEM_SETTINGS_KEY,
expandHqPermissionKeys,
hqBasePermissionKeys,
type HqPermissionKey,
} from '@dukang/shared-types';
import { PrismaService } from '../../common/prisma/prisma.module';
@@ -49,7 +50,7 @@ export class AdminHqPermissionsService {
async saveRolePermissions(role: string, permissionKeys: string[]) {
if (role === 'SUPER_ADMIN') {
throw new BadRequestException('超级管理员拥有全部权限,无需配置');
throw new BadRequestException('超级管理员基础权限固定,危险操作请按用户单独授权');
}
assertPermissionKeys(permissionKeys);
const normalized = expandHqPermissionKeys(permissionKeys);
@@ -73,24 +74,28 @@ export class AdminHqPermissionsService {
select: { id: true, name: true, phone: true, loginName: true, adminRole: true, status: true },
});
if (!account) throw new NotFoundException('HQ 账号不存在');
const userPerms = await this.prisma.hqAccountPermission.findMany({
where: { hqAccountId: accountId },
select: { permissionKey: true },
});
const userPermissionKeys = expandHqPermissionKeys(userPerms.map((p) => p.permissionKey));
if (account.adminRole === 'SUPER_ADMIN') {
const rolePermissionKeys = hqBasePermissionKeys();
const effectivePermissionKeys = [
...new Set([...rolePermissionKeys, ...userPermissionKeys]),
] as HqPermissionKey[];
return serializeBigInt({
account,
permissionKeys: HQ_PERMISSION_CATALOG.map((p) => p.key),
rolePermissionKeys: HQ_PERMISSION_CATALOG.map((p) => p.key),
userPermissionKeys: [],
effectivePermissionKeys: HQ_PERMISSION_CATALOG.map((p) => p.key),
permissionKeys: userPermissionKeys,
rolePermissionKeys,
userPermissionKeys,
effectivePermissionKeys,
});
}
const [rolePerms, userPerms] = await Promise.all([
this.getRolePermissions(account.adminRole),
this.prisma.hqAccountPermission.findMany({
where: { hqAccountId: accountId },
select: { permissionKey: true },
}),
]);
const userPermissionKeys = expandHqPermissionKeys(userPerms.map((p) => p.permissionKey));
const rolePerms = await this.getRolePermissions(account.adminRole);
const effectivePermissionKeys = [
...new Set([...rolePerms.permissionKeys, ...userPermissionKeys]),
] as HqPermissionKey[];
@@ -107,9 +112,6 @@ export class AdminHqPermissionsService {
async saveAccountPermissions(accountId: bigint, permissionKeys: string[]) {
const account = await this.prisma.hqAccount.findUnique({ where: { id: accountId } });
if (!account) throw new NotFoundException('HQ 账号不存在');
if (account.adminRole === 'SUPER_ADMIN') {
throw new BadRequestException('超级管理员拥有全部权限,无需配置');
}
assertPermissionKeys(permissionKeys);
const normalized = expandHqPermissionKeys(permissionKeys);
await this.prisma.$transaction([