import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common'; import { HQ_PERMISSION_CATALOG, HQ_ROLE_DEFAULT_PERMISSIONS, LEGACY_SYSTEM_SETTINGS_KEY, expandHqPermissionKeys, type HqPermissionKey, } from '@dukang/shared-types'; import { PrismaService } from '../../common/prisma/prisma.module'; import { serializeBigInt } from '../../common/decorators/current-user.decorator'; const VALID_PERMISSION_KEYS = new Set([ ...HQ_PERMISSION_CATALOG.map((p) => p.key), LEGACY_SYSTEM_SETTINGS_KEY, ]); function assertPermissionKeys(keys: string[]) { const invalid = keys.filter((key) => !VALID_PERMISSION_KEYS.has(key)); if (invalid.length) { throw new BadRequestException(`无效权限项: ${invalid.join(', ')}`); } } @Injectable() export class AdminHqPermissionsService { constructor(private readonly prisma: PrismaService) {} catalog() { return { permissions: HQ_PERMISSION_CATALOG, roles: Object.entries(HQ_ROLE_DEFAULT_PERMISSIONS).map(([role, permissionKeys]) => ({ role, permissionKeys, })), }; } async getRolePermissions(role: string) { const rows = await this.prisma.hqRolePermission.findMany({ where: { adminRole: role as 'SUPER_ADMIN' | 'OPS' | 'FINANCE' | 'CUSTOMER_SERVICE' }, select: { permissionKey: true }, }); const permissionKeys = rows.length > 0 ? expandHqPermissionKeys(rows.map((r) => r.permissionKey)) : [...(HQ_ROLE_DEFAULT_PERMISSIONS[role] ?? [])]; return { role, permissionKeys }; } async saveRolePermissions(role: string, permissionKeys: string[]) { if (role === 'SUPER_ADMIN') { throw new BadRequestException('超级管理员基础权限固定,危险操作请按用户单独授权'); } assertPermissionKeys(permissionKeys); const normalized = expandHqPermissionKeys(permissionKeys); const adminRole = role as 'OPS' | 'FINANCE' | 'CUSTOMER_SERVICE'; await this.prisma.$transaction([ this.prisma.hqRolePermission.deleteMany({ where: { adminRole } }), ...(normalized.length ? [ this.prisma.hqRolePermission.createMany({ data: normalized.map((permissionKey) => ({ adminRole, permissionKey })), }), ] : []), ]); return this.getRolePermissions(role); } async getAccountPermissions(accountId: bigint) { const account = await this.prisma.hqAccount.findUnique({ where: { id: accountId }, 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 = HQ_PERMISSION_CATALOG.map( (p) => p.key, ) as HqPermissionKey[]; const effectivePermissionKeys = [ ...new Set([...rolePermissionKeys, ...userPermissionKeys]), ] as HqPermissionKey[]; return serializeBigInt({ account, permissionKeys: userPermissionKeys, rolePermissionKeys, userPermissionKeys, effectivePermissionKeys, }); } const rolePerms = await this.getRolePermissions(account.adminRole); const effectivePermissionKeys = [ ...new Set([...rolePerms.permissionKeys, ...userPermissionKeys]), ] as HqPermissionKey[]; return serializeBigInt({ account, permissionKeys: userPermissionKeys, rolePermissionKeys: rolePerms.permissionKeys, userPermissionKeys, effectivePermissionKeys, }); } async saveAccountPermissions(accountId: bigint, permissionKeys: string[]) { const account = await this.prisma.hqAccount.findUnique({ where: { id: accountId } }); if (!account) throw new NotFoundException('HQ 账号不存在'); assertPermissionKeys(permissionKeys); const normalized = expandHqPermissionKeys(permissionKeys); await this.prisma.$transaction([ this.prisma.hqAccountPermission.deleteMany({ where: { hqAccountId: accountId } }), ...(normalized.length ? [ this.prisma.hqAccountPermission.createMany({ data: normalized.map((permissionKey) => ({ hqAccountId: accountId, permissionKey })), }), ] : []), ]); return this.getAccountPermissions(accountId); } }