刘光辉
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
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<DmsWenjianDayinShenqingDetailEntity> details =
                detailMapper.selectByRequestForUpdate(tenantId, request.getId());
        if (details == null || details.isEmpty()) {
            throw new DataException("文件打印申请没有可授权的文件明细");
        }
 
        List<ResolvedPrintFile> 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<UUID> uniqueVersionIds = new ArrayList<>(new LinkedHashSet<>(files.stream()
                .map(value -> value.file.getFileVersion().getId()).collect(Collectors.toList())));
        List<DmsFilePermissionEntity> permissions = permissionGrantService
                .ensureWorkflowPrintPermissions(tenantId, SOURCE_PREFIX + request.getId(),
                        applicantUserId, uniqueVersionIds, serviceId,
                        DmsAuditRequestSignResolver.resolve(form));
        Map<UUID, UUID> 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<DmsWenjianDayinShenqingEntity> 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;
        }
    }
}