/** * OA 表单值可读化(打印 / 摘要兜底) * 禁止把对象直接 JSON.stringify 到界面。 */ export function formatRegionLikeDisplay(value: unknown): string { if (value == null || value === '') return '' if (typeof value === 'string') return value.trim() if (Array.isArray(value)) { const parts = value .map((x) => { if (x == null || x === '') return '' if (typeof x === 'object') { const o = x as Record return String(o.label || o.name || o.text || o.value || '').trim() } return String(x).trim() }) .filter(Boolean) return parts.join(' / ') } if (typeof value === 'object') { const o = value as Record const path = [ String(o.province || o.provinceName || o.province_name || '').trim(), String(o.city || o.cityName || o.city_name || '').trim(), String( o.district || o.districtName || o.area || o.areaName || o.district_name || '' ).trim() ].filter(Boolean) if (path.length) return path.join(' / ') return formatUnknownObjectDisplay(o) } return String(value).trim() } export function formatUnknownObjectDisplay(raw: Record): string { const named = String(raw.label || raw.name || raw.text || raw.value || '').trim() if (named) return named if (raw.accountType || raw.accountNo || raw.accountName) { const parts = [ String(raw.accountType || '').trim(), String(raw.accountName || '').trim(), String(raw.accountNo || '').trim() ].filter(Boolean) return parts.join(' · ') } if (raw.fromCity || raw.toCity || raw.transport) { const fromCity = String(raw.fromCity || '').trim() || '-' const toCity = String(raw.toCity || '').trim() || '-' const transport = String(raw.transport || '').trim() const tripType = String(raw.tripType || '').trim() const bits = [ transport, tripType, `${fromCity} → ${toCity}` ].filter(Boolean) return bits.join(' · ') } const skip = new Set(['id', 'uuid', 'key', 'durationManual', 'manual']) const parts: string[] = [] for (const [k, v] of Object.entries(raw)) { if (skip.has(k) || k.startsWith('__') || /id$/i.test(k)) continue if (typeof v === 'boolean' || v == null || v === '') continue if (typeof v === 'string' || typeof v === 'number') { parts.push(String(v).trim()) } } return parts.filter(Boolean).join('、') } /** 标量/数组/对象统一可读化;对象绝不 JSON.stringify */ export function formatFormValueDisplay(value: unknown, sep = '、'): string { if (value == null || value === '') return '-' if (typeof value === 'boolean') return value ? '是' : '否' if (typeof value === 'number') return String(value) if (typeof value === 'string') return value.trim() || '-' if (Array.isArray(value)) { if (!value.length) return '-' const parts = value .map((v) => formatFormValueDisplay(v, sep)) .filter((s) => s && s !== '-') return parts.length ? parts.join(sep) : '-' } if (typeof value === 'object') { const text = formatUnknownObjectDisplay(value as Record) return text || '-' } return String(value) }