yyb
7 小时以前 5b248a9716688d8132cfb02b4ba0abecd4060b06
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
import { deptTreeSelect, userListNoPageByTenantId } from "@/api/system/user.js";
 
/** 下拉选项来源(写入 formConfig,提交页按来源拉取数据) */
export const SELECT_OPTION_SOURCE = {
  STATIC: "static",
  USER: "user",
  DEPT: "dept",
};
 
export const SELECT_OPTION_SOURCE_OPTIONS = [
  { value: SELECT_OPTION_SOURCE.STATIC, label: "手动配置", desc: "在模板中自定义选项文本与值" },
  { value: SELECT_OPTION_SOURCE.USER, label: "人员列表", desc: "从系统用户中选择,值为用户 ID" },
  { value: SELECT_OPTION_SOURCE.DEPT, label: "部门列表", desc: "从组织架构中选择,值为部门 ID" },
];
 
export function selectOptionSourceLabel(source) {
  return SELECT_OPTION_SOURCE_OPTIONS.find((x) => x.value === source)?.label || "—";
}
 
export function isDynamicOptionSource(source) {
  return source === SELECT_OPTION_SOURCE.USER || source === SELECT_OPTION_SOURCE.DEPT;
}
 
function unwrapArray(payload) {
  if (Array.isArray(payload)) return payload;
  if (payload?.data && Array.isArray(payload.data)) return payload.data;
  if (payload?.rows && Array.isArray(payload.rows)) return payload.rows;
  return [];
}
 
function isActiveUser(u) {
  if (u.delFlag === "2" || u.delFlag === 2) return false;
  if (u.status == null) return true;
  return String(u.status) === "0";
}
 
/** 用户 → 下拉 option */
export function mapUserToSelectOption(u) {
  const value = u.userId ?? u.id;
  return {
    label: u.nickName || u.userName || `用户${value}`,
    value,
  };
}
 
/** 部门树拍平为下拉 option */
export function flattenDeptToSelectOptions(nodes, result = []) {
  (nodes || []).forEach((node) => {
    const value = node.id ?? node.deptId ?? node.value;
    if (value != null && value !== "") {
      result.push({
        label: node.label ?? node.deptName ?? node.name ?? String(value),
        value,
      });
    }
    if (node.children?.length) flattenDeptToSelectOptions(node.children, result);
  });
  return result;
}
 
function filterDisabledDept(deptList) {
  if (!Array.isArray(deptList)) return [];
  return deptList.filter((dept) => {
    if (dept.disabled) return false;
    if (dept.children?.length) {
      dept.children = filterDisabledDept(dept.children);
    }
    return true;
  });
}
 
/** 按字段配置解析下拉 options(需传入已加载的缓存) */
export function resolveFieldSelectOptions(field, caches = {}) {
  const source = field?.optionSource || SELECT_OPTION_SOURCE.STATIC;
  if (source === SELECT_OPTION_SOURCE.USER) {
    return (caches.users || []).map(mapUserToSelectOption);
  }
  if (source === SELECT_OPTION_SOURCE.DEPT) {
    return caches.deptOptions || [];
  }
  return (field?.options || []).filter((o) => o.value !== "" && o.value != null);
}
 
/** 根据已解析的 options 反查展示文本 */
export function resolveSelectDisplayLabel(field, val, caches = {}) {
  if (val == null || val === "") return "—";
  const options = resolveFieldSelectOptions(field, caches);
  const hit = options.find((o) => String(o.value) === String(val));
  return hit?.label || String(val);
}
 
/** 加载人员 / 部门缓存(多处复用) */
export async function fetchSelectOptionCaches(sources = []) {
  const needUser = sources.includes(SELECT_OPTION_SOURCE.USER);
  const needDept = sources.includes(SELECT_OPTION_SOURCE.DEPT);
  const caches = { users: [], deptOptions: [] };
 
  if (!needUser && !needDept) return caches;
 
  const tasks = [];
  if (needUser) {
    tasks.push(
      userListNoPageByTenantId()
        .then((res) => {
          caches.users = unwrapArray(res).filter(isActiveUser);
        })
        .catch(() => {
          caches.users = [];
        })
    );
  }
  if (needDept) {
    tasks.push(
      deptTreeSelect()
        .then((res) => {
          let tree = unwrapArray(res);
          tree = tree.length ? filterDisabledDept(JSON.parse(JSON.stringify(tree))) : [];
          if (!tree.length) tree = unwrapArray(res);
          caches.deptOptions = flattenDeptToSelectOptions(tree);
        })
        .catch(() => {
          caches.deptOptions = [];
        })
    );
  }
 
  await Promise.all(tasks);
  return caches;
}
 
/** 从字段列表收集需要预加载的动态来源 */
export function collectOptionSourcesFromFields(fields) {
  const set = new Set();
  (fields || []).forEach((f) => {
    if (f?.type === "select" && isDynamicOptionSource(f.optionSource)) {
      set.add(f.optionSource);
    }
  });
  return [...set];
}