import { deptTreeSelect, userListNoPageByTenantId } from "@/api/system/user.js";
|
import { staffOnJobListPage } from "@/api/personnelManagement/staffOnJob.js";
|
|
/** 下拉选项来源(写入 formConfig,提交页按来源拉取数据) */
|
export const SELECT_OPTION_SOURCE = {
|
STATIC: "static",
|
USER: "user",
|
DEPT: "dept",
|
EMPLOYEE: "employee",
|
};
|
|
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" },
|
{ value: SELECT_OPTION_SOURCE.EMPLOYEE, label: "员工列表", desc: "从在职员工中选择,值为员工 ID" },
|
];
|
|
const EMPLOYEE_APPLICANT_MODULE_KEYS = new Set(["regular"]);
|
|
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 ||
|
source === SELECT_OPTION_SOURCE.EMPLOYEE
|
);
|
}
|
|
function unwrapArray(payload) {
|
if (Array.isArray(payload)) return payload;
|
if (Array.isArray(payload?.records)) return payload.records;
|
if (payload?.data && Array.isArray(payload.data)) return payload.data;
|
if (Array.isArray(payload?.data?.records)) return payload.data.records;
|
if (payload?.rows && Array.isArray(payload.rows)) return payload.rows;
|
if (Array.isArray(payload?.data?.rows)) return payload.data.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 mapEmployeeToSelectOption(u) {
|
const value = u.id ?? u.staffOnJobId ?? u.staffId;
|
return {
|
label: u.staffName || u.name || 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(需传入已加载的缓存) */
|
function isApplicantField(field) {
|
const key = String(field?.key || "").toLowerCase();
|
const label = String(field?.label || "");
|
return (
|
key === "applicant" ||
|
key === "applicantname" ||
|
label.includes("申请人")
|
);
|
}
|
|
export function resolveFieldSelectOptions(field, caches = {}, context = {}) {
|
const source = field?.optionSource || SELECT_OPTION_SOURCE.STATIC;
|
if (
|
source === SELECT_OPTION_SOURCE.USER &&
|
EMPLOYEE_APPLICANT_MODULE_KEYS.has(context.moduleKey) &&
|
isApplicantField(field)
|
) {
|
return (caches.employees || []).map(mapEmployeeToSelectOption);
|
}
|
if (source === SELECT_OPTION_SOURCE.USER) {
|
return (caches.users || []).map(mapUserToSelectOption);
|
}
|
if (source === SELECT_OPTION_SOURCE.DEPT) {
|
return caches.deptOptions || [];
|
}
|
if (source === SELECT_OPTION_SOURCE.EMPLOYEE) {
|
return (caches.employees || []).map(mapEmployeeToSelectOption);
|
}
|
return (field?.options || []).filter((o) => o.value !== "" && o.value != null);
|
}
|
|
/** 根据已解析的 options 反查展示文本 */
|
export function resolveSelectDisplayLabel(field, val, caches = {}, context = {}) {
|
if (val == null || val === "") return "—";
|
const options = resolveFieldSelectOptions(field, caches, context);
|
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 needEmployee = sources.includes(SELECT_OPTION_SOURCE.EMPLOYEE);
|
const caches = { users: [], deptOptions: [], employees: [] };
|
|
if (!needUser && !needDept && !needEmployee) 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 = [];
|
})
|
);
|
}
|
if (needEmployee) {
|
tasks.push(
|
staffOnJobListPage({ current: -1, size: -1, staffState: 1 })
|
.then((res) => {
|
caches.employees = unwrapArray(res);
|
})
|
.catch(() => {
|
caches.employees = [];
|
})
|
);
|
}
|
|
await Promise.all(tasks);
|
return caches;
|
}
|
|
/** 从字段列表收集需要预加载的动态来源 */
|
export function collectOptionSourcesFromFields(fields, context = {}) {
|
const set = new Set();
|
(fields || []).forEach((f) => {
|
if (f?.type === "select" && isDynamicOptionSource(f.optionSource)) {
|
if (
|
EMPLOYEE_APPLICANT_MODULE_KEYS.has(context.moduleKey) &&
|
f.optionSource === SELECT_OPTION_SOURCE.USER &&
|
isApplicantField(f)
|
) {
|
set.add(SELECT_OPTION_SOURCE.EMPLOYEE);
|
} else {
|
set.add(f.optionSource);
|
}
|
}
|
});
|
return [...set];
|
}
|