package jnpf.dmsService; import jnpf.dmsEntity.storage.approval.*; import jnpf.dmsMapper.DmsApprovedBatchMapper; import jnpf.exception.DataException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.*; @Service @RequiredArgsConstructor public class DmsApprovedFileActivationService { private final DmsApprovedBatchMapper receipts; private final jnpf.dmsService.center.DmsCenterActivationService center; private final DmsApprovedAuditSource source; private final DmsQianpiyeRenderSnapshotService qianpiyeSnapshots; private final DmsApprovedReadAccessService readAccess; private final DmsBusinessLifecycleGuard businessOccupancy; @Transactional(rollbackFor = Exception.class) public DmsApprovedBatch activate(String tenantId, UUID id) { DmsApprovedBatch batch = receipts.lock(tenantId, id); if (batch == null) throw new DataException("批准文件接收回执不存在"); if (!"WAITING".equals(batch.getStatus()) && !"FAILED".equals(batch.getStatus())) return batch; DmsApprovedAuditSource.Source externalSource = "wailai_wenjian_xinzeng_shenhe".equals(batch.getAuditType()) ? source.load(tenantId, batch.getFlowId(), batch.getTaskId(), batch.getAuditType(), batch.getActorId(), batch.getApprovedAt()) : null; var businessReceipts = externalSource != null ? businessOccupancy.requireExternalCreation(tenantId, batch.getAuditId(), batch.getTaskId(), externalSource.batch().getItems().get(0).getDocumentNo()) : "xiuding_shenhe".equals(batch.getAuditType()) ? businessOccupancy.requireRevision(tenantId,batch.getAuditId()) : businessOccupancy.requireCreation(tenantId,batch.getAuditId()); // DB clock is authoritative. An early callback leaves WAITING unchanged. if (receipts.activate(tenantId, id) != 1) return batch; DmsApprovedBatch activated = receipts.lock(tenantId, id); if (activated.getEffectiveTo() != null && !activated.getEffectiveTo().after(activated.getActivatedAt())) throw new DataException("文件有效期已结束,不能激活"); DmsApprovedAuditSource.Source nativeSource = externalSource != null ? externalSource : source.load(tenantId, batch.getFlowId(), batch.getTaskId(), batch.getAuditType(), batch.getActorId(), batch.getApprovedAt()); DmsApprovedBatch currentSource = nativeSource.batch(); // Activation must not introduce a new render snapshot into files registered before // original-document tag filling was enabled; their stored content is already frozen. if (batch.getApprovalRenderSnapshot() != null) { qianpiyeSnapshots.attach(currentSource, batch.getApprovalRenderSnapshot(), nativeSource.preparedBy(), nativeSource.preparedOn()); } if (!Objects.equals(batch.getSourceDigest(), currentSource.getSourceDigest())) throw new DataException("批准后审核内容已改变,不能按旧回执生效"); List items = receipts.items(tenantId, id); if (items.size() != currentSource.getItems().size()) throw new DataException("文件接收项目不完整"); if(businessOccupancy.isEnabled()) DmsBusinessLifecycleGuard.verifySourceCoverage(businessReceipts,currentSource.getItems()); center.activate(tenantId, batch.getActorId(), items.stream().map(item -> new jnpf.dmsEntity.center.DmsCenterActivation(item.getDocumentId(), item.getFileVersionId(), item.getBaseFileVersionId(), item.getChangeType(), item.getChecksumSha256())).toList()); readAccess.apply(activated, items, currentSource.getItems()); return activated; } }