package jnpf.dmsService; import jnpf.dmsEntity.download.entity.DmsWenjianXiazaiShenqingDetailEntity; import jnpf.dmsEntity.download.entity.DmsWenjianXiazaiShenqingEntity; import jnpf.dmsEntity.download.form.DmsWorkflowDownloadAuthorizeForm; import jnpf.dmsEntity.download.vo.DmsWorkflowDownloadAuthorizationVO; import jnpf.dmsEntity.download.vo.DmsWorkflowDownloadFileVO; import jnpf.dmsEntity.permission.entity.DmsFilePermissionEntity; import jnpf.dmsIntegration.audit.DmsAuditRequestSignResolver; import jnpf.dmsMapper.DmsWenjianXiazaiShenqingDetailMapper; import jnpf.dmsMapper.DmsWenjianXiazaiShenqingMapper; import jnpf.exception.DataException; import jnpf.flowable.WorkFlowApi; import jnpf.flowable.entity.TaskEntity; import jnpf.flowable.enums.TaskStatusEnum; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; @Service @RequiredArgsConstructor public class DmsWorkflowDownloadAuthorizationService { private static final String SOURCE_PREFIX = "download-request:"; private final WorkFlowApi workFlowApi; private final DmsWenjianXiazaiShenqingMapper requestMapper; private final DmsWenjianXiazaiShenqingDetailMapper detailMapper; private final DmsWorkflowFileResolutionService fileResolutionService; private final DmsPermissionGrantService permissionGrantService; @Transactional(rollbackFor = Exception.class) public DmsWorkflowDownloadAuthorizationVO authorize( String tenantId, DmsWorkflowDownloadAuthorizeForm form, String serviceId) { String flowId = requiredText(form.getSourceId(), "流程ID不能为空"); String taskId = requiredText(form.getTaskId(), "流程任务ID不能为空"); TaskEntity task = requireApprovedTask(flowId, taskId); DmsWenjianXiazaiShenqingEntity request = uniqueRequest( requestMapper.selectByFlowForUpdate(tenantId, flowId, taskId)); if (!TaskStatusEnum.PASSED.getCode().equals(request.getFlowState())) { throw new DataException("文件下载申请尚未审批通过"); } if (trimToNull(form.getBizSign()) == null) { form.setBizSign(trimToNull(request.getBizSign())); } String applicantUserId = requiredText(request.getApplicantUserId(), "文件下载申请缺少申请人"); List details = detailMapper.selectByRequestForUpdate(tenantId, request.getId()); if (details == null || details.isEmpty()) { throw new DataException("文件下载申请没有可授权的文件明细"); } List files = new ArrayList<>(details.size()); for (DmsWenjianXiazaiShenqingDetailEntity detail : details) { files.add(new ResolvedDownloadFile(detail, fileResolutionService.resolve( tenantId, detail.getId(), detail.getFileReferenceId(), detail.getFileNumber(), detail.getFileName(), detail.getVersionLabel()))); } if (files.stream().map(value -> value.file.getFileVersion().getId()).distinct().count() != files.size()) { throw new DataException("下载申请包含重复文件版本"); } List permissions = new ArrayList<>(); for (ResolvedDownloadFile file : files) { permissions.addAll(permissionGrantService.ensureWorkflowDownloadPermissions( tenantId, SOURCE_PREFIX + request.getId() + ":" + file.detail.getId(), applicantUserId, java.util.Collections.singletonList(file.file.getFileVersion().getId()), DmsDownloadDeadline.resolve(file.detail.getXiazaiShixian(), file.detail.getId()), serviceId, DmsAuditRequestSignResolver.resolve(form))); } Map permissionIds = new HashMap<>(); for (DmsFilePermissionEntity permission : permissions) { permissionIds.put(permission.getResourceId(), permission.getId()); } DmsWorkflowDownloadAuthorizationVO result = new DmsWorkflowDownloadAuthorizationVO(); result.setTaskId(taskId); result.setFlowState(task.getStatus()); result.setFlowStatus(TaskStatusEnum.PASSED.getMessage()); result.setCompleted(Boolean.TRUE); result.setApplicantUserId(applicantUserId); for (ResolvedDownloadFile file : files) { DmsWorkflowDownloadFileVO item = new DmsWorkflowDownloadFileVO(); item.setRequestDetailId(file.detail.getId()); item.setBusinessFileId(file.file.getBusinessFile().getId()); item.setBusinessFileVersionId(file.file.getBusinessVersion().getId()); item.setDocumentId(file.file.getFileVersion().getDocumentId()); item.setFileVersionId(file.file.getFileVersion().getId()); item.setFileName(file.file.getFileVersion().getFileName()); item.setMimeType(file.file.getFileVersion().getMimeType()); item.setSizeBytes(file.file.getFileVersion().getSizeBytes()); item.setPermissionId(permissionIds.get(file.file.getFileVersion().getId())); item.setPermanent(Boolean.FALSE); result.getFiles().add(item); } return result; } private TaskEntity requireApprovedTask(String flowId, String taskId) { TaskEntity task = workFlowApi.getInfoSubmit(taskId); if (task == null || !taskId.equals(task.getId())) { throw new DataException("未找到与taskId匹配的流程任务"); } if (!flowId.equals(task.getFlowId()) && !flowId.equals(task.getTemplateId())) { throw new DataException("流程任务不属于指定flowID"); } if (!TaskStatusEnum.PASSED.getCode().equals(task.getStatus())) { throw new DataException("流程任务尚未审核通过,不能授予下载权限"); } return task; } private DmsWenjianXiazaiShenqingEntity uniqueRequest( List requests) { if (requests == null || requests.isEmpty()) { throw new DataException("未找到对应的文件下载申请"); } if (requests.size() != 1) { throw new DataException("流程任务关联了多条文件下载申请"); } return requests.get(0); } private String requiredText(String value, String message) { String normalized = trimToNull(value); if (normalized == null) { throw new DataException(message); } return normalized; } private String trimToNull(String value) { return value == null || value.trim().isEmpty() ? null : value.trim(); } private static final class ResolvedDownloadFile { private final DmsWenjianXiazaiShenqingDetailEntity detail; private final DmsWorkflowFileResolutionService.ResolvedFile file; private ResolvedDownloadFile(DmsWenjianXiazaiShenqingDetailEntity detail, DmsWorkflowFileResolutionService.ResolvedFile file) { this.detail = detail; this.file = file; } } }