136 lines
3.8 KiB
TypeScript
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 }
|
|
}
|