刘光辉
4 小时以前 06f314545ac3514d7ce28939920866ae8188d31c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
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;
        }
    }
}