Files
zkxw/web-admin/src/utils/oa-trip-kit-runtime.ts
T
2026-07-30 20:02:33 +08:00

136 lines
3.8 KiB
TypeScript

import { calcTripLegDays, sumTripLegDays } from '@/utils/oa-trip-days'
export const TRIP_MANUAL_PREFIX = '__manual_'
export type TripKitRef = {
listField: string
daysField: string
}
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 resolveTripKitFields(kit: Record<string, unknown>): TripKitRef | null {
const props = (kit.props && typeof kit.props === 'object' ? kit.props : {}) as Record<
string,
any
>
let listField = props.tripListField as string | undefined
let daysField = props.tripDaysField as string | undefined
if (listField && daysField) {
return { listField: String(listField), daysField: String(daysField) }
}
const children = (
Array.isArray(kit.children)
? kit.children
: Array.isArray(props.rule)
? props.rule
: []
) as Record<string, any>[]
for (const c of children) {
if (!c?.field) continue
const kitKey = String(c.props?._fc_kit_field || '')
if (kitKey === 'tripList') listField = String(c.field)
else if (kitKey === 'tripDays') daysField = String(c.field)
}
if (!listField || !daysField) return null
return { listField, daysField }
}
export function listTripKits(schema: unknown): TripKitRef[] {
const flat: Record<string, unknown>[] = []
walk(asRules(schema), flat)
const out: TripKitRef[] = []
for (const r of flat) {
if (String(r.type || '') !== 'tripKit') continue
const ref = resolveTripKitFields(r)
if (ref) out.push(ref)
}
return out
}
/** 未手改时重算行程时长与出差天数;返回是否有变更 */
export function applyTripKitDaysToFormData(
schema: unknown,
formData: Record<string, unknown>
): { data: Record<string, unknown>; changed: boolean } {
const data = { ...formData }
let changed = false
for (const kit of listTripKits(schema)) {
const legsRaw = data[kit.listField]
if (!Array.isArray(legsRaw)) continue
const prevLegsJson = JSON.stringify(data[kit.listField])
const legs: Record<string, unknown>[] = []
for (const leg of legsRaw) {
if (!leg || typeof leg !== 'object') {
legs.push(leg as Record<string, unknown>)
continue
}
const row = { ...(leg as Record<string, unknown>) }
if (!row.durationManual) {
const days = calcTripLegDays(
String(row.startDate || ''),
String(row.startHalf || ''),
String(row.endDate || ''),
String(row.endHalf || '')
)
if (days != null && row.duration !== days) {
row.duration = days
}
}
legs.push(row)
}
data[kit.listField] = legs
if (JSON.stringify(legs) !== prevLegsJson) {
changed = true
}
const manualKey = TRIP_MANUAL_PREFIX + kit.daysField
if (data[manualKey]) continue
const sum = sumTripLegDays(legs)
if (data[kit.daysField] !== sum) {
data[kit.daysField] = sum
changed = true
}
}
return { data, changed }
}