刘光辉
5 小时以前 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
package jnpf.flowable.service;
 
import jnpf.flowable.model.filepermission.FilePermissionView;
import jnpf.flowable.util.filepermission.FilePermissionRuntime;
import jnpf.flowable.util.filepermission.FilePermissionSnapshot;
import jnpf.util.UserProvider;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.stereotype.Service;
import java.util.Objects;
 
/** 详情与实际动作使用相同的实例权限出口;无快照才可回到旧行为。 */
@Service
@RequiredArgsConstructor
@Slf4j
public class FilePermissionRuntimeService implements jnpf.flowable.model.filepermission.FilePermissionReader {
    private final FilePermissionSnapshotService snapshots;
    private final ObjectProvider<FilePermissionRuntimeSource> source;
 
    public FilePermissionView current(String taskId, String formId) {
        return currentWithPublishedForm(taskId, formId, null);
    }
 
    @Override
    public FilePermissionView currentWithPublishedForm(String taskId, String formId, String formData) {
        FilePermissionView view = resolve(taskId, formId, formData);
        if (!"ready".equals(view.getStatus()) && !"TASK_NOT_FOUND".equals(view.getReason())) {
            // 暂存原生表单尚未建实例是正常情形;其他失败记录原因,不输出规则/令牌/文件地址。
            log.warn("Workflow file permission unavailable: taskId={}, formId={}, reason={}",
                    taskId, formId, view.getReason());
        }
        return view;
    }
 
    private FilePermissionView resolve(String taskId, String formId, String formData) {
        if (blank(taskId) || blank(formId)) return FilePermissionView.unavailable(taskId, formId, "INVALID_CONTEXT");
        try {
            FilePermissionSnapshot snapshot = snapshots.find(taskId);
            if (snapshot == null) return FilePermissionView.legacy(taskId, formId);
            FilePermissionRuntimeSource runtime = source.getIfAvailable();
            if (runtime == null) return FilePermissionView.unavailable(taskId, formId, "RUNTIME_UNAVAILABLE");
            String tenant = UserProvider.getUser().getTenantId();
            tenant = blank(tenant) ? "0" : tenant;
            String user = UserProvider.getLoginUserId();
            if (blank(user)) return FilePermissionView.unavailable(taskId, formId, "INVALID_CONTEXT");
            FilePermissionRuntime.Facts facts = formData == null ? runtime.read(tenant, taskId, formId, user, snapshot)
                    : runtime.readWithPublishedForm(tenant, taskId, formId, user, snapshot, formData);
            if (facts == null || !Objects.equals(tenant, facts.tenantId) || !Objects.equals(taskId, facts.taskId)
                    || !Objects.equals(formId, facts.formId) || !Objects.equals(user, facts.userId)) {
                return FilePermissionView.unavailable(taskId, formId, "INVALID_CONTEXT");
            }
            return FilePermissionRuntime.resolve(snapshot.getRules(), facts);
        } catch (FilePermissionSnapshotService.TaskNotFoundException e) {
            // 不直接返回legacy;附件调用方还必须用原生持久化记录证明尚未发起流程。
            return FilePermissionView.unavailable(taskId, formId, "TASK_NOT_FOUND");
        } catch (RuntimeException e) {
            StackTraceElement[] stack = e.getStackTrace();
            log.warn("Workflow file permission read failed: taskId={}, formId={}, errorType={}, origin={}",
                    taskId, formId, e.getClass().getSimpleName(), stack.length == 0 ? "unknown" : stack[0]);
            // 故障/损坏快照不能作为“老流程”放行;不把内部错误或其他人员信息下发。
            return FilePermissionView.unavailable(taskId, formId, "PERMISSION_UNAVAILABLE");
        }
    }
 
    private static boolean blank(String value) { return value == null || value.trim().isEmpty(); }
}