/** 展示格式化工具:时间、字节、OCID 截断 */ export function fmtTime(iso: string | null | undefined): string { if (!iso) return '—' const d = new Date(iso) if (Number.isNaN(d.getTime())) return '—' const pad = (n: number) => String(n).padStart(2, '0') return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}` } export function fmtRelative(iso: string | null | undefined): string { if (!iso) return '—' const diff = Date.now() - new Date(iso).getTime() if (Number.isNaN(diff)) return '—' const min = Math.floor(diff / 60000) if (min < 1) return '刚刚' if (min < 60) return `${min} 分钟前` const hr = Math.floor(min / 60) if (hr < 24) return `${hr} 小时前` return `${Math.floor(hr / 24)} 天前` } export function fmtBytes(n: number): string { if (n <= 0) return '0 B' const units = ['B', 'KB', 'MB', 'GB', 'TB'] const i = Math.min(Math.floor(Math.log2(n) / 10), units.length - 1) return `${(n / 2 ** (10 * i)).toFixed(1)} ${units[i]}` } /** 金额展示:千分位 + 2 位小数,常见币种转符号前缀,其余保留币种码 */ export function fmtMoney(n: number, currency = 'USD'): string { const sym: Record = { USD: '$', EUR: '€', GBP: '£', JPY: '¥', CNY: '¥' } const s = n.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) const p = sym[currency] return p ? p + s : `${currency} ${s}`.trim() } /** OCID 中段省略:ocid1.instance.oc1..aaaa…mc25a */ export function truncOcid(ocid: string, head = 24, tail = 6): string { if (!ocid || ocid.length <= head + tail + 1) return ocid return `${ocid.slice(0, head)}…${ocid.slice(-tail)}` } /** 可用域展示:RssO:EU-FRANKFURT-1-AD-1 → AD-1 */ export function shortAd(ad: string): string { const m = ad.match(/AD-\d+$/) return m ? m[0] : ad } /** 区域友好名中括号内的城市短名:Germany Central (Frankfurt) → Frankfurt */ export function regionCity(label: string): string { const m = /\(([^)]+)\)/.exec(label) return m ? m[1] : label } /** 块存储 VPU/GB 档位:0 低成本 / 10 均衡 / 20 高性能 / 30-120 超高性能 */ export function vpusLabel(vpus: number): string { if (vpus >= 30) return `${vpus} · 超高性能` if (vpus >= 20) return `${vpus} · 高性能` if (vpus >= 10) return `${vpus} · 均衡` return `${vpus} · 低成本` } /** Oracle 官方风格默认资源名:instance-20260703-2136 / vcn-20260509-0252 */ export function defaultResourceName(prefix: string): string { const now = new Date() const pad = (n: number) => String(n).padStart(2, '0') const date = `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}` return `${prefix}-${date}-${pad(now.getHours())}${pad(now.getMinutes())}` }