| | |
| | | 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; |
| | | 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 []; |
| | | } |
| | | |
| | |
| | | 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, |
| | | }; |
| | | } |
| | |
| | | } |
| | | |
| | | /** 按字段配置解析下拉 options(需传入已加载的缓存) */ |
| | | export function resolveFieldSelectOptions(field, caches = {}) { |
| | | 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 = {}) { |
| | | export function resolveSelectDisplayLabel(field, val, caches = {}, context = {}) { |
| | | if (val == null || val === "") return "—"; |
| | | const options = resolveFieldSelectOptions(field, caches); |
| | | 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 caches = { users: [], deptOptions: [] }; |
| | | const needEmployee = sources.includes(SELECT_OPTION_SOURCE.EMPLOYEE); |
| | | const caches = { users: [], deptOptions: [], employees: [] }; |
| | | |
| | | if (!needUser && !needDept) return caches; |
| | | if (!needUser && !needDept && !needEmployee) return caches; |
| | | |
| | | const tasks = []; |
| | | if (needUser) { |
| | |
| | | }) |
| | | ); |
| | | } |
| | | 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) { |
| | | 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]; |
| | | } |