package jnpf.dmsService; import jnpf.dmsEntity.permission.entity.DmsFilePermissionEntity; import jnpf.dmsEntity.print.DmsWenjianDayinShenqingDetailEntity; import jnpf.dmsEntity.print.DmsWenjianDayinShenqingEntity; import jnpf.dmsEntity.print.form.DmsWorkflowPrintAuthorizeForm; import jnpf.dmsEntity.print.vo.DmsWorkflowPrintAuthorizationVO; import jnpf.dmsEntity.print.vo.DmsWorkflowPrintFileVO; import jnpf.dmsIntegration.audit.DmsAuditRequestSignResolver; import jnpf.dmsMapper.DmsWenjianDayinShenqingDetailMapper; import jnpf.dmsMapper.DmsWenjianDayinShenqingMapper; 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.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.stream.Collectors; @Service @RequiredArgsConstructor public class DmsWorkflowPrintAuthorizationService { private static final String SOURCE_PREFIX = "print-request:"; private final WorkFlowApi workFlowApi; private final DmsWenjianDayinShenqingMapper requestMapper; private final DmsWenjianDayinShenqingDetailMapper detailMapper; private final DmsWorkflowFileResolutionService fileResolutionService; private final DmsPermissionGrantService permissionGrantService; @Transactional(rollbackFor = Exception.class) public DmsWorkflowPrintAuthorizationVO authorize( String tenantId, DmsWorkflowPrintAuthorizeForm form, String serviceId) { String flowId = requiredText(form.getSourceId(), "流程ID不能为空"); String taskId = requiredText(form.getTaskId(), "流程任务ID不能为空"); TaskEntity task = requireApprovedTask(flowId, taskId); DmsWenjianDayinShenqingEntity 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 (DmsWenjianDayinShenqingDetailEntity detail : details) { DmsWorkflowFileResolutionService.ResolvedFile file = fileResolutionService.resolve( tenantId, detail.getId(), detail.getFileReferenceId(), detail.getFileNumber(), detail.getFileName(), detail.getVersionLabel()); files.add(new ResolvedPrintFile(detail, file, parseCopies(detail))); } List uniqueVersionIds = new ArrayList<>(new LinkedHashSet<>(files.stream() .map(value -> value.file.getFileVersion().getId()).collect(Collectors.toList()))); List permissions = permissionGrantService .ensureWorkflowPrintPermissions(tenantId, SOURCE_PREFIX + request.getId(), applicantUserId, uniqueVersionIds, serviceId, DmsAuditRequestSignResolver.resolve(form)); Map permissionIds = new HashMap<>(); for (DmsFilePermissionEntity permission : permissions) { permissionIds.put(permission.getResourceId(), permission.getId()); } DmsWorkflowPrintAuthorizationVO result = new DmsWorkflowPrintAuthorizationVO(); result.setTaskId(taskId); result.setFlowState(task.getStatus()); result.setFlowStatus(TaskStatusEnum.PASSED.getMessage()); result.setCompleted(Boolean.TRUE); result.setApplicantUserId(applicantUserId); for (ResolvedPrintFile file : files) { DmsWorkflowPrintFileVO item = new DmsWorkflowPrintFileVO(); 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.TRUE); item.setPrintCopies(file.copies); item.setPrintPages(trimToNull(file.detail.getPrintPages())); item.setPurpose(trimToNull(file.detail.getPurpose())); item.setReason(trimToNull(file.detail.getReason())); item.setOtherReason(trimToNull(file.detail.getOtherReason())); item.setApplicationType(trimToNull(file.detail.getApplicationType())); 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 DmsWenjianDayinShenqingEntity uniqueRequest( List requests) { if (requests == null || requests.isEmpty()) { throw new DataException("未找到对应的文件打印申请"); } if (requests.size() != 1) { throw new DataException("流程任务关联了多条文件打印申请"); } return requests.get(0); } private int parseCopies(DmsWenjianDayinShenqingDetailEntity detail) { String value = requiredText(detail.getPrintCopies(), "打印申请明细缺少打印数量:" + detail.getId()); try { int copies = Integer.parseInt(value); if (copies < 1 || copies > 999) { throw new NumberFormatException(); } return copies; } catch (NumberFormatException exception) { throw new DataException("打印申请明细的打印数量必须是 1 到 999 的整数:" + detail.getId()); } } 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 ResolvedPrintFile { private final DmsWenjianDayinShenqingDetailEntity detail; private final DmsWorkflowFileResolutionService.ResolvedFile file; private final int copies; private ResolvedPrintFile(DmsWenjianDayinShenqingDetailEntity detail, DmsWorkflowFileResolutionService.ResolvedFile file, int copies) { this.detail = detail; this.file = file; this.copies = copies; } } }