| | |
| | | return hit?.value ?? hit?.defaultValue ?? ""; |
| | | } |
| | | |
| | | function pickDateRange(searchForm) { |
| | | const range = |
| | | searchForm?.createTimeRange ?? |
| | | searchForm?.applyDateRange ?? |
| | | searchForm?.transferDateRange; |
| | | if (!Array.isArray(range) || !range[0]) return {}; |
| | | const out = { createTimeStart: range[0] }; |
| | | if (range[1]) out.createTimeEnd = range[1]; |
| | | /** 扁平化为 Spring GET 可绑定的 query(approvalInstanceDto.xxx,勿用方括号) */ |
| | | export function appendDotNotationQuery(target, prefix, fields) { |
| | | if (!fields || typeof fields !== "object") return; |
| | | for (const [key, value] of Object.entries(fields)) { |
| | | if (value == null || value === "") continue; |
| | | target[`${prefix}.${key}`] = value; |
| | | } |
| | | } |
| | | |
| | | function pickApplicantFromSearchForm(searchForm = {}) { |
| | | const out = {}; |
| | | const sf = searchForm || {}; |
| | | const name = (sf.applicantName || "").trim(); |
| | | const kw = (sf.applicantKeyword || "").trim(); |
| | | const id = sf.applicantId; |
| | | |
| | | if (name) out.applicantName = name; |
| | | if (kw) { |
| | | out.applicantName = kw; |
| | | if (/^\d+$/.test(kw)) out.applicantId = Number(kw); |
| | | } |
| | | if (id != null && id !== "") { |
| | | out.applicantId = typeof id === "number" ? id : Number(id) || id; |
| | | } |
| | | return out; |
| | | } |
| | | |
| | | /** 各模块默认查询表单(与 Web searchForm 字段一致) */ |
| | | export function createModuleSearchForm(moduleKey) { |
| | | switch (moduleKey) { |
| | | case APPROVAL_MODULE_KEYS.REGULAR: |
| | | return { applicantName: "", applyDateRange: null }; |
| | | case APPROVAL_MODULE_KEYS.TRANSFER: |
| | | return { applicantId: "", transferDateRange: null }; |
| | | case APPROVAL_MODULE_KEYS.WORK_HANDOVER: |
| | | return { applicantId: "", handoverStatus: "", handoverType: "" }; |
| | | case APPROVAL_MODULE_KEYS.LEAVE: |
| | | return { applicantKeyword: "", leaveType: "" }; |
| | | case APPROVAL_MODULE_KEYS.OVERTIME: |
| | | return { applicantKeyword: "", overtimeType: "" }; |
| | | case APPROVAL_MODULE_KEYS.TRAVEL_REIMBURSE: |
| | | case APPROVAL_MODULE_KEYS.COST_REIMBURSE: |
| | | case APPROVAL_MODULE_KEYS.ENTERPRISE_NEWS: |
| | | return { applicantKeyword: "" }; |
| | | default: |
| | | return {}; |
| | | } |
| | | function pickInstanceNoFromSearchForm(searchForm = {}) { |
| | | const no = (searchForm?.instanceNo || "").trim(); |
| | | return no ? { instanceNo: no } : {}; |
| | | } |
| | | |
| | | /** 服务端 listPage DTO 片段(与 Web buildExtraListParams + buildApprovalInstanceListParams 一致) */ |
| | | export function buildModuleListDto(moduleKey, searchForm = {}) { |
| | | const sf = searchForm || {}; |
| | | const dto = { ...pickDateRange(sf) }; |
| | | /** 支持审批单号查询的审批申请模块 */ |
| | | export const INSTANCE_NO_SEARCH_MODULE_KEYS = new Set([ |
| | | APPROVAL_MODULE_KEYS.REGULAR, |
| | | APPROVAL_MODULE_KEYS.TRANSFER, |
| | | APPROVAL_MODULE_KEYS.WORK_HANDOVER, |
| | | APPROVAL_MODULE_KEYS.LEAVE, |
| | | APPROVAL_MODULE_KEYS.OVERTIME, |
| | | ]); |
| | | |
| | | switch (moduleKey) { |
| | | case APPROVAL_MODULE_KEYS.REGULAR: { |
| | | const name = (sf.applicantName || "").trim(); |
| | | if (name) dto.applicantName = name; |
| | | break; |
| | | } |
| | | case APPROVAL_MODULE_KEYS.TRANSFER: |
| | | break; |
| | | case APPROVAL_MODULE_KEYS.WORK_HANDOVER: |
| | | break; |
| | | case APPROVAL_MODULE_KEYS.LEAVE: |
| | | case APPROVAL_MODULE_KEYS.OVERTIME: |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | const INSTANCE_NO_SEARCH_FIELD = { |
| | | key: "instanceNo", |
| | | type: "input", |
| | | label: "审批单号", |
| | | placeholder: "请输入审批单号", |
| | | }; |
| | | |
| | | /** 组装 approvalInstanceDto 查询片段(申请人 + 审批单号) */ |
| | | export function buildApprovalInstanceSearchDto(searchForm = {}, extraParams = {}) { |
| | | const dto = { |
| | | ...(extraParams && typeof extraParams === "object" ? extraParams : {}), |
| | | }; |
| | | Object.assign(dto, pickApplicantFromSearchForm(searchForm)); |
| | | Object.assign(dto, pickInstanceNoFromSearchForm(searchForm)); |
| | | delete dto.createTime; |
| | | delete dto.createTimeStart; |
| | | delete dto.createTimeEnd; |
| | | return dto; |
| | | } |
| | | |
| | | function pickDateRange(searchForm) { |
| | | return buildApprovalInstanceSearchDto(searchForm); |
| | | } |
| | | |
| | | /** 各模块默认查询表单(与 Web searchForm 字段一致) */ |
| | | const APPLICANT_ONLY_MODULE_KEYS = new Set([ |
| | | APPROVAL_MODULE_KEYS.REGULAR, |
| | | APPROVAL_MODULE_KEYS.TRANSFER, |
| | | APPROVAL_MODULE_KEYS.WORK_HANDOVER, |
| | | APPROVAL_MODULE_KEYS.LEAVE, |
| | | APPROVAL_MODULE_KEYS.OVERTIME, |
| | | APPROVAL_MODULE_KEYS.TRAVEL_REIMBURSE, |
| | | APPROVAL_MODULE_KEYS.COST_REIMBURSE, |
| | | ]); |
| | | |
| | | function withInstanceNoSearch(moduleKey, base) { |
| | | if (INSTANCE_NO_SEARCH_MODULE_KEYS.has(moduleKey)) { |
| | | return { instanceNo: "", ...base }; |
| | | } |
| | | return base; |
| | | } |
| | | |
| | | function applicantOnlySearchForm(moduleKey) { |
| | | if (moduleKey === APPROVAL_MODULE_KEYS.REGULAR) { |
| | | return withInstanceNoSearch(moduleKey, { applicantName: "" }); |
| | | } |
| | | if ( |
| | | moduleKey === APPROVAL_MODULE_KEYS.TRANSFER || |
| | | moduleKey === APPROVAL_MODULE_KEYS.WORK_HANDOVER |
| | | ) { |
| | | return withInstanceNoSearch(moduleKey, { applicantId: "" }); |
| | | } |
| | | if (APPLICANT_ONLY_MODULE_KEYS.has(moduleKey)) { |
| | | return withInstanceNoSearch(moduleKey, { applicantKeyword: "" }); |
| | | } |
| | | return {}; |
| | | } |
| | | |
| | | export function createModuleSearchForm(moduleKey) { |
| | | if (APPLICANT_ONLY_MODULE_KEYS.has(moduleKey)) { |
| | | return applicantOnlySearchForm(moduleKey); |
| | | } |
| | | if (moduleKey === APPROVAL_MODULE_KEYS.ENTERPRISE_NEWS) { |
| | | return { applicantKeyword: "" }; |
| | | } |
| | | return {}; |
| | | } |
| | | |
| | | /** 服务端 listPage DTO 片段(与 Web buildApprovalInstanceListParams 一致) */ |
| | | export function buildModuleListDto(moduleKey, searchForm = {}) { |
| | | return buildApprovalInstanceSearchDto(searchForm); |
| | | } |
| | | |
| | | function matchInstanceNo(row, instanceNo) { |
| | | const kw = (instanceNo || "").trim().toLowerCase(); |
| | | if (!kw) return true; |
| | | const parts = [row?.instanceNo, row?.bizId] |
| | | .filter(v => v != null && v !== "") |
| | | .map(v => String(v).toLowerCase()); |
| | | return parts.some(p => p.includes(kw)); |
| | | } |
| | | |
| | | export function hasActiveModuleSearch(moduleKey, searchForm = {}) { |
| | | const sf = searchForm || {}; |
| | | if ((sf.instanceNo || "").trim()) return true; |
| | | if ((sf.applicantKeyword || "").trim()) return true; |
| | | if ((sf.applicantName || "").trim()) return true; |
| | | return sf.applicantId != null && sf.applicantId !== ""; |
| | | } |
| | | |
| | | function matchApplicantKeyword(row, keyword) { |
| | |
| | | }); |
| | | } |
| | | |
| | | /** 前端筛选(Web 未下发接口的字段与 Web 行为一致) */ |
| | | /** 按申请人、审批单号做前端兜底筛选 */ |
| | | export function filterRowsByModuleSearch(moduleKey, rows, searchForm = {}) { |
| | | const sf = searchForm || {}; |
| | | const list = Array.isArray(rows) ? rows : []; |
| | | if (!hasActiveModuleSearch(moduleKey, sf)) return list; |
| | | |
| | | switch (moduleKey) { |
| | | case APPROVAL_MODULE_KEYS.TRANSFER: |
| | | return list.filter( |
| | | row => |
| | | matchApplicantId(row, sf.applicantId) && |
| | | matchApplicantKeyword(row, sf.applicantKeyword) |
| | | ); |
| | | case APPROVAL_MODULE_KEYS.WORK_HANDOVER: |
| | | return list.filter( |
| | | row => |
| | | matchApplicantId(row, sf.applicantId) && |
| | | matchSelectValue(row, ["handoverStatus", "交接状态"], sf.handoverStatus) && |
| | | matchSelectValue(row, ["handoverType", "交接类型"], sf.handoverType) |
| | | ); |
| | | case APPROVAL_MODULE_KEYS.LEAVE: |
| | | return list.filter( |
| | | row => |
| | | matchApplicantKeyword(row, sf.applicantKeyword) && |
| | | matchSelectValue(row, ["leaveType", "请假类型"], sf.leaveType) |
| | | ); |
| | | case APPROVAL_MODULE_KEYS.OVERTIME: |
| | | return list.filter( |
| | | row => |
| | | matchApplicantKeyword(row, sf.applicantKeyword) && |
| | | matchSelectValue(row, ["overtimeType", "加班类型"], sf.overtimeType) |
| | | ); |
| | | case APPROVAL_MODULE_KEYS.TRAVEL_REIMBURSE: |
| | | case APPROVAL_MODULE_KEYS.COST_REIMBURSE: |
| | | case APPROVAL_MODULE_KEYS.ENTERPRISE_NEWS: |
| | | return list.filter(row => matchApplicantKeyword(row, sf.applicantKeyword)); |
| | | default: |
| | | return list; |
| | | } |
| | | return list.filter( |
| | | row => |
| | | matchInstanceNo(row, sf.instanceNo) && |
| | | matchApplicantId(row, sf.applicantId) && |
| | | matchApplicantKeyword(row, sf.applicantKeyword || sf.applicantName) |
| | | ); |
| | | } |
| | | |
| | | function prependInstanceNoField(fields, moduleKey) { |
| | | if (!INSTANCE_NO_SEARCH_MODULE_KEYS.has(moduleKey)) return fields; |
| | | return [INSTANCE_NO_SEARCH_FIELD, ...fields]; |
| | | } |
| | | |
| | | /** 模块筛选 UI 配置 */ |
| | | export function getModuleSearchMeta(moduleKey) { |
| | | switch (moduleKey) { |
| | | case APPROVAL_MODULE_KEYS.REGULAR: |
| | | return { |
| | | fields: [ |
| | | if (moduleKey === APPROVAL_MODULE_KEYS.REGULAR) { |
| | | return { |
| | | fields: prependInstanceNoField( |
| | | [ |
| | | { key: "applicantName", type: "input", label: "申请人", placeholder: "请输入申请人" }, |
| | | { key: "applyDateRange", type: "daterange", label: "申请日期" }, |
| | | ], |
| | | }; |
| | | case APPROVAL_MODULE_KEYS.TRANSFER: |
| | | return { |
| | | fields: [ |
| | | { key: "applicantId", type: "user", label: "申请人", placeholder: "请选择申请人" }, |
| | | { key: "transferDateRange", type: "daterange", label: "转岗时间" }, |
| | | ], |
| | | }; |
| | | case APPROVAL_MODULE_KEYS.WORK_HANDOVER: |
| | | return { |
| | | fields: [ |
| | | { key: "applicantId", type: "user", label: "申请人", placeholder: "请选择申请人" }, |
| | | { |
| | | key: "handoverStatus", |
| | | type: "select", |
| | | label: "交接状态", |
| | | options: HANDOVER_STATUS_OPTIONS, |
| | | }, |
| | | { |
| | | key: "handoverType", |
| | | type: "select", |
| | | label: "交接类型", |
| | | options: HANDOVER_TYPE_OPTIONS, |
| | | }, |
| | | ], |
| | | }; |
| | | case APPROVAL_MODULE_KEYS.LEAVE: |
| | | return { |
| | | fields: [ |
| | | { |
| | | key: "applicantKeyword", |
| | | type: "input", |
| | | label: "申请人", |
| | | placeholder: "姓名或编号", |
| | | }, |
| | | { |
| | | key: "leaveType", |
| | | type: "select", |
| | | label: "请假类型", |
| | | options: LEAVE_TYPE_OPTIONS, |
| | | }, |
| | | ], |
| | | }; |
| | | case APPROVAL_MODULE_KEYS.OVERTIME: |
| | | return { |
| | | fields: [ |
| | | { |
| | | key: "applicantKeyword", |
| | | type: "input", |
| | | label: "申请人", |
| | | placeholder: "姓名或编号", |
| | | }, |
| | | { |
| | | key: "overtimeType", |
| | | type: "select", |
| | | label: "加班类型", |
| | | options: OVERTIME_TYPE_OPTIONS, |
| | | }, |
| | | ], |
| | | }; |
| | | case APPROVAL_MODULE_KEYS.TRAVEL_REIMBURSE: |
| | | case APPROVAL_MODULE_KEYS.COST_REIMBURSE: |
| | | case APPROVAL_MODULE_KEYS.ENTERPRISE_NEWS: |
| | | return { |
| | | fields: [ |
| | | { |
| | | key: "applicantKeyword", |
| | | type: "input", |
| | | label: "申请人", |
| | | placeholder: "姓名或编号", |
| | | }, |
| | | ], |
| | | }; |
| | | default: |
| | | return { fields: [] }; |
| | | moduleKey |
| | | ), |
| | | }; |
| | | } |
| | | if ( |
| | | moduleKey === APPROVAL_MODULE_KEYS.TRANSFER || |
| | | moduleKey === APPROVAL_MODULE_KEYS.WORK_HANDOVER |
| | | ) { |
| | | return { |
| | | fields: prependInstanceNoField( |
| | | [ |
| | | { key: "applicantId", type: "user", label: "申请人", placeholder: "请选择申请人" }, |
| | | ], |
| | | moduleKey |
| | | ), |
| | | }; |
| | | } |
| | | if (APPLICANT_ONLY_MODULE_KEYS.has(moduleKey)) { |
| | | return { |
| | | fields: prependInstanceNoField( |
| | | [ |
| | | { |
| | | key: "applicantKeyword", |
| | | type: "input", |
| | | label: "申请人", |
| | | placeholder: "姓名或编号", |
| | | }, |
| | | ], |
| | | moduleKey |
| | | ), |
| | | }; |
| | | } |
| | | return { fields: [] }; |
| | | } |
| | | |
| | | export function resetModuleSearchForm(moduleKey, target) { |