| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- import {
- calcLeaveHours,
- DEFAULT_LEAVE_WORK_HOURS,
- type LeaveWorkHours
- } from '@/utils/oa-leave-hours'
- export const LEAVE_MANUAL_PREFIX = '__manual_'
- export type LeaveKitBinding = {
- startField: string
- endField: string
- durationField: string
- workHours: LeaveWorkHours
- }
- function asRules(schema: unknown): Record<string, unknown>[] {
- if (Array.isArray(schema)) return schema.filter((r) => r && typeof r === 'object') as any
- if (schema && typeof schema === 'object') {
- const s = schema as any
- const rules = s.rule || s.rules || s.fields
- if (Array.isArray(rules)) return rules.filter((r: any) => r && typeof r === 'object')
- if (s.type || s.field) return [s]
- }
- return []
- }
- function walk(rules: Record<string, unknown>[], out: Record<string, unknown>[]) {
- for (const r of rules) {
- out.push(r)
- const children = r.children
- if (Array.isArray(children)) {
- walk(
- children.filter((c) => c && typeof c === 'object') as Record<string, unknown>[],
- out
- )
- }
- const props = r.props as Record<string, unknown> | undefined
- if (props && Array.isArray(props.rule)) {
- walk(
- props.rule.filter((c) => c && typeof c === 'object') as Record<string, unknown>[],
- out
- )
- }
- }
- }
- function resolveFields(kit: Record<string, unknown>): LeaveKitBinding | null {
- const props = (kit.props && typeof kit.props === 'object' ? kit.props : {}) as Record<
- string,
- any
- >
- let startField = props.startField as string | undefined
- let endField = props.endField as string | undefined
- let durationField = props.durationField as string | undefined
- const children = (
- Array.isArray(kit.children)
- ? kit.children
- : Array.isArray(props.rule)
- ? props.rule
- : []
- ) as Record<string, any>[]
- if (!startField || !endField || !durationField) {
- const dateFields: string[] = []
- let dur: string | undefined
- for (const c of children) {
- if (!c?.field) continue
- const t = String(c.type || '')
- if (t === 'datePicker' || t === 'date' || t === 'timePicker' || t === 'time') {
- dateFields.push(String(c.field))
- } else if ((t === 'inputNumber' || t === 'number') && !dur) {
- dur = String(c.field)
- }
- }
- startField = startField || dateFields[0]
- endField = endField || dateFields[1]
- durationField = durationField || dur
- }
- if (!startField || !endField || !durationField) return null
- return {
- startField,
- endField,
- durationField,
- workHours: {
- morningStart: String(props.morningStart || DEFAULT_LEAVE_WORK_HOURS.morningStart),
- morningEnd: String(props.morningEnd || DEFAULT_LEAVE_WORK_HOURS.morningEnd),
- afternoonStart: String(props.afternoonStart || DEFAULT_LEAVE_WORK_HOURS.afternoonStart),
- afternoonEnd: String(props.afternoonEnd || DEFAULT_LEAVE_WORK_HOURS.afternoonEnd)
- }
- }
- }
- export function listLeaveKitBindings(schema: unknown): LeaveKitBinding[] {
- const flat: Record<string, unknown>[] = []
- walk(asRules(schema), flat)
- const out: LeaveKitBinding[] = []
- for (const r of flat) {
- if (String(r.type || '') !== 'leaveKit') continue
- const b = resolveFields(r)
- if (b) out.push(b)
- }
- return out
- }
- /** 未手改时写回时长;返回是否有变更 */
- export function applyLeaveKitDurationsToFormData(
- schema: unknown,
- formData: Record<string, unknown>
- ): { data: Record<string, unknown>; changed: boolean } {
- const data = { ...formData }
- let changed = false
- for (const kit of listLeaveKitBindings(schema)) {
- const manualKey = LEAVE_MANUAL_PREFIX + kit.durationField
- if (data[manualKey]) continue
- const hours = calcLeaveHours(
- String(data[kit.startField] || ''),
- String(data[kit.endField] || ''),
- kit.workHours
- )
- if (hours == null) continue
- if (data[kit.durationField] !== hours) {
- data[kit.durationField] = hours
- changed = true
- }
- }
- return { data, changed }
- }
- export function markLeaveDurationManual(
- formData: Record<string, unknown>,
- durationField: string,
- manual = true
- ) {
- const data = { ...formData }
- const key = LEAVE_MANUAL_PREFIX + durationField
- if (manual) data[key] = true
- else delete data[key]
- return data
- }
- export function isLeaveDurationField(schema: unknown, field: string): boolean {
- return listLeaveKitBindings(schema).some((k) => k.durationField === field)
- }
- export function findLeaveKitByStartOrEnd(
- schema: unknown,
- field: string
- ): LeaveKitBinding | null {
- return (
- listLeaveKitBindings(schema).find(
- (k) => k.startField === field || k.endField === field
- ) || null
- )
- }
- /**
- * 运行时补齐请假套件子规则:时长数字框默认左对齐(覆盖 Element Plus 默认居中)。
- * 对已发布且未带 align 的旧 schema 同样生效。
- */
- export function ensureLeaveKitRuleProps(rules: unknown): any[] {
- if (!Array.isArray(rules)) return []
- return rules.map((raw) => {
- if (!raw || typeof raw !== 'object') return raw
- const rule: any = { ...(raw as object) }
- if (String(rule.type || '') === 'leaveKit') {
- const binding = resolveFields(rule)
- const patchChildren = (list: any[]): any[] =>
- list.map((c) => {
- if (!c || typeof c !== 'object') return c
- const child: any = { ...c }
- const t = String(child.type || '')
- const isDuration =
- (binding && child.field === binding.durationField) ||
- ((t === 'inputNumber' || t === 'number') &&
- String(child.title || '').includes('时长'))
- if (isDuration) {
- child.props = { ...(child.props || {}), align: 'left' }
- const cls = String(child.class || child.className || '')
- if (!cls.includes('oa-leave-duration')) {
- child.class = (cls ? cls + ' ' : '') + 'oa-leave-duration'
- }
- }
- if (Array.isArray(child.children)) {
- child.children = patchChildren(child.children)
- }
- return child
- })
- if (Array.isArray(rule.children)) {
- rule.children = patchChildren(rule.children)
- }
- if (Array.isArray(rule.props?.rule)) {
- rule.props = {
- ...rule.props,
- rule: patchChildren(rule.props.rule)
- }
- }
- }
- if (Array.isArray(rule.children)) {
- rule.children = ensureLeaveKitRuleProps(rule.children)
- }
- if (Array.isArray(rule.props?.rule)) {
- rule.props = {
- ...rule.props,
- rule: ensureLeaveKitRuleProps(rule.props.rule)
- }
- }
- return rule
- })
- }
|