diff --git a/src/devices/b-devices/b-devices.controller.ts b/src/devices/b-devices/b-devices.controller.ts index 5a0458f..82321b9 100644 --- a/src/devices/b-devices/b-devices.controller.ts +++ b/src/devices/b-devices/b-devices.controller.ts @@ -160,7 +160,13 @@ export class BDevicesController { * 删除设备。 */ @Delete(':id') - @Roles(Role.SYSTEM_ADMIN, Role.HOSPITAL_ADMIN) + @Roles( + Role.SYSTEM_ADMIN, + Role.HOSPITAL_ADMIN, + Role.DIRECTOR, + Role.LEADER, + Role.DOCTOR, + ) @ApiOperation({ summary: '删除设备' }) @ApiParam({ name: 'id', description: '设备 ID' }) remove( diff --git a/src/devices/devices.service.ts b/src/devices/devices.service.ts index 581215b..feb01f1 100644 --- a/src/devices/devices.service.ts +++ b/src/devices/devices.service.ts @@ -177,7 +177,7 @@ export class DevicesService { * 删除设备:若设备已被任务明细引用,则返回 409。 */ async remove(actor: ActorContext, id: number) { - const current = await this.findOne(actor, id); + const current = await this.findRemovableDevice(actor, id); try { return await this.prisma.device.delete({ @@ -538,6 +538,74 @@ export class DevicesService { /** * 管理员角色校验:仅系统管理员与院管可操作患者植入实例。 */ + private async findRemovableDevice(actor: ActorContext, id: number) { + const deviceId = this.toInt(id, 'id'); + const device = await this.prisma.device.findUnique({ + where: { id: deviceId }, + select: { + id: true, + patient: { + select: { + hospitalId: true, + doctorId: true, + doctor: { + select: { + departmentId: true, + groupId: true, + }, + }, + }, + }, + }, + }); + + if (!device) { + throw new NotFoundException(MESSAGES.DEVICE.NOT_FOUND); + } + + this.assertDeviceRemovableScope(actor, device.patient); + return device; + } + + private assertDeviceRemovableScope( + actor: ActorContext, + patient: { + hospitalId: number; + doctorId: number; + doctor: { departmentId: number | null; groupId: number | null }; + }, + ) { + switch (actor.role) { + case Role.SYSTEM_ADMIN: + return; + case Role.HOSPITAL_ADMIN: + if (patient.hospitalId !== this.requireActorHospitalId(actor)) { + throw new ForbiddenException(MESSAGES.DEFAULT_FORBIDDEN); + } + return; + case Role.DIRECTOR: + if ( + !actor.departmentId || + patient.doctor.departmentId !== actor.departmentId + ) { + throw new ForbiddenException(MESSAGES.DEFAULT_FORBIDDEN); + } + return; + case Role.LEADER: + if (!actor.groupId || patient.doctor.groupId !== actor.groupId) { + throw new ForbiddenException(MESSAGES.DEFAULT_FORBIDDEN); + } + return; + case Role.DOCTOR: + if (patient.doctorId !== actor.id) { + throw new ForbiddenException(MESSAGES.DEFAULT_FORBIDDEN); + } + return; + default: + throw new ForbiddenException(MESSAGES.DEFAULT_FORBIDDEN); + } + } + private assertAdmin(actor: ActorContext) { if ( actor.role !== Role.SYSTEM_ADMIN &&