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(); }
|
}
|