From bbf87b28057d70c4be2dd7db8881bc63c227f1c1 Mon Sep 17 00:00:00 2001 From: liuyun Date: Wed, 21 Oct 2026 14:59:22 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20tenant=5Fsuper=5Fadmin=20=E7=BA=B3?= =?UTF-8?q?=E5=85=A5=E8=BA=AB=E4=BB=BD=E8=AF=81=E6=98=8E=E6=96=87=E6=9F=A5?= =?UTF-8?q?=E7=9C=8B=E5=8F=A3=E5=BE=84=20+=20=E5=BB=BA=E6=A1=A3=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5=E6=B8=85=E7=90=86=E8=AF=84=E4=BC=B0=E5=89=AF=E6=9C=AC?= =?UTF-8?q?=E5=AD=A4=E5=84=BF=E5=AF=B9=E8=B1=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- src/elder/elder.service.ts | 40 ++++++++++++++++++++-------------- src/storage/storage.service.ts | 5 +++++ 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/elder/elder.service.ts b/src/elder/elder.service.ts index 16586a8..8106357 100644 --- a/src/elder/elder.service.ts +++ b/src/elder/elder.service.ts @@ -105,21 +105,29 @@ export class ElderService extends BaseCrudService { } const treatStatus = resolveInitialStatus(dto.benefitStart, dto.benefitEnd); const { idCardNo: _idCardNo, ...dtoRest } = dto; - const created = await super.create({ - ...dtoRest, - idCardNoHash: hash(idCardNo), - idCardNoEnc: encrypt(idCardNo), - birthDate: toDateOnly(birthDate), - treatStatus, - statusSource: 'manual', - benefitStart: toDateOnly(dto.benefitStart), - benefitEnd: toDateOnly(dto.benefitEnd), - assessDate: toDateOnly(dto.assessDate), - insurVerifyDate: toDateOnly(dto.insurVerifyDate), - hospStart: toDateOnly(dto.hospStart), - hospEnd: toDateOnly(dto.hospEnd), - }); - return this.presentIdCard(created, false); + try { + const created = await super.create({ + ...dtoRest, + idCardNoHash: hash(idCardNo), + idCardNoEnc: encrypt(idCardNo), + birthDate: toDateOnly(birthDate), + treatStatus, + statusSource: 'manual', + benefitStart: toDateOnly(dto.benefitStart), + benefitEnd: toDateOnly(dto.benefitEnd), + assessDate: toDateOnly(dto.assessDate), + insurVerifyDate: toDateOnly(dto.insurVerifyDate), + hospStart: toDateOnly(dto.hospStart), + hospEnd: toDateOnly(dto.hospEnd), + }); + return this.presentIdCard(created, false); + } catch (err) { + // 建档失败时清理已上传的评估结论副本(避免 MinIO 孤儿对象)。 + if (dto.assessEvidenceFile) { + await this.storage.delete(dto.assessEvidenceFile).catch(() => undefined); + } + throw err; + } } /** 详情:admin/qc(或平台超管)返回身份证明文并显式写审计;否则掩码。 */ @@ -202,7 +210,7 @@ export class ElderService extends BaseCrudService { where: { tenantCode: ctx.tenantCode, userId: ctx.userId }, select: { roleCode: true }, }); - return rows.some((r) => r.roleCode === 'admin' || r.roleCode === 'qc'); + return rows.some((r) => r.roleCode === 'admin' || r.roleCode === 'qc' || r.roleCode === 'tenant_super_admin'); } private async assertIdCardUnique(idCardNo: string) { diff --git a/src/storage/storage.service.ts b/src/storage/storage.service.ts index 0de5550..a80189d 100644 --- a/src/storage/storage.service.ts +++ b/src/storage/storage.service.ts @@ -32,4 +32,9 @@ export class StorageService { async presignGet(key: string, expiry = 3600): Promise { return this.client.presignedGetObject(this.bucket, key, expiry); } + + /** 删除对象(幂等:对象不存在不抛错)。 */ + async delete(key: string): Promise { + await this.client.removeObject(this.bucket, key).catch(() => undefined); + } }