刘光辉
5 小时以前 cf11e63b659afcc9792ab3e395f1b45d844431a8
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
import type { FilePermissionView } from '#/components/Jnpf/upload/src/filePermissionContext';
 
import { inject, onBeforeUnmount, ref, watch } from 'vue';
 
import { getFlowFilePermissions } from '#/api/workFlow/task';
import { workflowFileSubmitPendingKey } from '#/components/Jnpf/upload/src/filePermissionContext';
 
/** 在流程状态原地切换后立即刷新权限,并隔离表单切换期间返回的旧响应。 */
export async function refreshConfiguredFilePermissions(config: () => any) {
  const currentConfig = config();
  const current = currentConfig?.filePermissions as FilePermissionView | undefined;
  if (!current?.enabled || !current.taskId || !currentConfig?.id) return false;
  const recordId = currentConfig.id;
  const taskId = current.taskId;
  const formId = currentConfig.formId;
  const response = await getFlowFilePermissions(taskId, { formId });
  const latestConfig = config();
  if (
    latestConfig !== currentConfig ||
    latestConfig?.id !== recordId ||
    latestConfig?.formId !== formId ||
    latestConfig?.filePermissions?.taskId !== taskId ||
    latestConfig?.filePermissions?.enabled !== true
  ) {
    return false;
  }
  const next = response.data as FilePermissionView;
  if (!next || next.taskId !== taskId || next.formId !== formId || next.enabled !== true) {
    throw new Error('file permission context changed');
  }
  latestConfig.filePermissions = next;
  return true;
}
 
/** 只刷新当前实例的文件权限;关闭、切换记录后不能采纳旧请求。 */
export function useFilePermissions(config: () => any) {
  const submitting = inject(workflowFileSubmitPendingKey, () => false);
  const permissions = ref<FilePermissionView>();
  let generation = 0;
  let pending = false;
  let disposed = false;
 
  watch(
    () => [config()?.id, config()?.formId, config()?.filePermissions],
    () => {
      generation++;
      pending = false;
      permissions.value = config()?.filePermissions ?? undefined;
    },
    { immediate: true },
  );
 
  watch(
    submitting,
    () => {
      if (!permissions.value?.enabled) return;
      generation++;
      pending = false;
      if (!submitting()) void refresh();
    },
    { flush: 'sync' },
  );
 
  async function refresh() {
    const current = permissions.value;
    if (disposed || pending || submitting() || !current?.enabled || !config()?.id) return;
    const request = generation;
    // 详情入口可能使用业务记录别名,刷新必须使用服务端确认的真实流程实例。
    const id = current.taskId;
    const formId = config().formId;
    pending = true;
    try {
      const response = await getFlowFilePermissions(id, { formId });
      if (disposed || request !== generation) return;
      const next = response.data as FilePermissionView;
      if (!next || next.taskId !== current.taskId || next.formId !== formId || next.enabled !== true) throw new Error('file permission context changed');
      permissions.value = next;
    } catch {
      if (!disposed && request === generation) permissions.value = { ...current, status: 'error', fields: {} };
    } finally {
      if (request === generation) pending = false;
    }
  }
 
  const timer = setInterval(() => {
    if (!document.hidden) void refresh();
  }, 15_000);
  window.addEventListener('focus', refresh);
  onBeforeUnmount(() => {
    disposed = true;
    generation++;
    clearInterval(timer);
    window.removeEventListener('focus', refresh);
  });
  return permissions;
}