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<DmsWenjianXiazaiShenqingDetailEntity> details =
|
detailMapper.selectByRequestForUpdate(tenantId, request.getId());
|
if (details == null || details.isEmpty()) {
|
throw new DataException("文件下载申请没有可授权的文件明细");
|
}
|
|
List<ResolvedDownloadFile> 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<DmsFilePermissionEntity> 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<UUID, UUID> 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<DmsWenjianXiazaiShenqingEntity> 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;
|
}
|
}
|
}
|