/** 多供应商实例数据展示适配;基础数值以 null 区分缺值与 0,具体输出再按展示协议归一。 */ function e(e) { if (e == null || e === ``) return null; let t = Number(e); return Number.isFinite(t) ? t : null; } // 远控端口必须处于 TCP/UDP 有效范围,空值和非整数返回 null。 function t(t) { if (typeof t != `number` && typeof t != `string`) return null; let n = e(t); return n !== null && Number.isInteger(n) && n >= 1 && n <= 65535 ? n : null; } // 兼容接口返回对象或序列化对象,格式不符合时返回空对象供上层做缺值展示。 function n(e) { if (typeof e == `string`) try { return n(JSON.parse(e)); } catch { return {}; } return e && typeof e == `object` && !Array.isArray(e) ? e : {}; } function r(e) { if (typeof e == `string`) try { return r(JSON.parse(e)); } catch { return []; } return Array.isArray(e) ? e.filter((e) => e && typeof e == `object`) : []; } /** 将秒、毫秒或日期字符串归一为 Unix 秒;超过 10^12 的数值按毫秒处理。 */ function i(t) { let n = e(t); if (n !== null) return n > 0xe8d4a51000 ? Math.floor(n / 1e3) : n || void 0; let r = Date.parse(String(t ?? ``).replace(` `, `T`)); return Number.isFinite(r) ? Math.floor(r / 1e3) : void 0; } // 容量统一为 GB(1024 进制),无单位时使用 t;“不限”按既有展示协议返回 0。 function a(e, t = `GB`) { if (typeof e == `string` && /不限|unlimited/i.test(e)) return 0; let n = /^\s*(-?\d+(?:\.\d+)?(?:e[+-]?\d+)?)\s*([KMGT]?B)?\s*$/i.exec( String(e ?? ``), ); if (!n) return null; let r = (n[2] || t).toUpperCase(), i = Number(n[1]) * ({ B: 1 / 1024 ** 3, KB: 1 / 1024 ** 2, MB: 1 / 1024, GB: 1, TB: 1024, }[r] ?? 1); return Number.isFinite(i) ? i : null; } /** * t 为模块名,r 为实例详情,i 为实时流量/配额响应;区分总量、计量模式和小时统计。 * kky_ecs 的完整小时数据不冒充本周期累计量;配额是否加载与配额是否存在单独表达。 */ function o(t, r, i) { let o = n(r), s = n(i), c = n(o.host_data), l = n(s.billing), u = n(s.quota), d = t === `kky_ecs` ? l.mode === `traffic` || l.mode === `bandwidth` ? l.mode : Number(o.bill_method) === 1 ? `bandwidth` : Number(o.bill_method) === 2 ? `traffic` : `` : ``, f = t === `kky_ecs` ? e(l.unit_price) : null, p = f !== null && f >= 0 ? f : null, m = t === `kky_ecs` ? a(l.monthly_quota) : null, h = m !== null && m >= 0 ? m : null, g = a(u.total), _ = a(u.used), v = a(u.remaining), y = t === `kky_ecs` && g !== null && g >= 0 && _ !== null && _ >= 0 && v !== null && v >= 0 ? { total: g, used: _, remaining: v, percent: g > 0 ? Math.min(100, (_ / g) * 100) : null, start: String(u.start_time ?? ``), end: String(u.end_time ?? ``), } : null, b = t === `kky_ecs` && [`available`, `none`, `not_applicable`].includes( String(s.quota_status ?? ``), ), x = null, S = null, C = null, w = ``, T = !1, E = t === `kky_ecs` && !!s.start_time && !!s.end_time, D = E ? a(s.incoming) : null; if (t === `mf_cloud` || t === `remf_cloud`) ((x = a(s.total_num ?? s.total)), (S = a(s.used_num ?? s.used)), (C = a(s.leave)), (w = String(s.reset_flow_date ?? ``))); else if (t === `remf_finance`) ((x = a(c.bwlimit, String(c.bwunit ?? `GB`))), (S = a(c.bwusage, String(c.bwunit ?? `GB`))), (w = String(c.reset_flow_date ?? o.reset_flow_date ?? ``))); else { let e = n(o.traffic); ((x = a( o.traffic_total ?? o.total_traffic ?? e.total ?? (typeof o.traffic == `object` ? null : o.traffic), )), (S = a( E ? s.used : (o.traffic_used ?? o.used_traffic ?? o.traffic_usage ?? e.used), )), (C = a(o.traffic_remain ?? o.remain_traffic ?? e.remain)), (w = String(o.traffic_reset_time ?? o.reset_flow_date ?? ``)), (T = Number(o.bill_method) === 2 || Number(o.traffic_show) === 1 || /流量/.test(String(o.bill_method_name ?? ``))), (l.mode === `traffic` || l.mode === `bandwidth`) && (T = l.mode === `traffic`), d && (T = d === `traffic`)); } // 只有非小时统计才允许由总量和剩余量互推;否则不同时间口径不可直接相减。 return ( !E && x !== null && x > 0 && S === null && C !== null && (S = Math.max(0, x - C)), !E && x !== null && x > 0 && C === null && S !== null && (C = Math.max(0, x - S)), { total: x, used: S, remaining: C, reset: w, unlimited: !T && (x === null ? d === `bandwidth` : x <= 0), metered: T, incoming: D, quota: y, quotaLoaded: b, unitPrice: p, monthlyQuota: h, periodStart: E ? String(s.start_time) : ``, periodEnd: E ? String(s.end_time) : ``, usedLabel: E ? `最近完整小时出站流量` : `已用流量`, percent: !E && x !== null && x > 0 && S !== null ? Math.max(0, Math.min(100, (S / x) * 100)) : null, packageRemaining: t === `kky_ecs` && Number(o.traffic_show) !== 1 ? null : a(o.traffic_package_remain), } ); } // 大容量按 GB/TB 展示;null 用破折号,而不是把缺失值当作零。 function s(e) { return e === null ? `—` : Math.abs(e) >= 1024 ? `${(e / 1024).toFixed(2)} TB` : `${e.toFixed(2)} GB`; } // 小流量继续降为 MB/KB/B,避免低于 1 GB 的真实用量全部显示成 0.00 GB。 function c(e) { return e === null ? `—` : e === 0 ? `0 B` : Math.abs(e) >= 1 ? s(e) : Math.abs(e) >= 1 / 1024 ? `${(e * 1024).toFixed(2)} MB` : Math.abs(e) >= 1 / 1024 ** 2 ? `${(e * 1024 ** 2).toFixed(2)} KB` : `${(e * 1024 ** 3).toFixed(0)} B`; } /** 归一磁盘名称、容量和时间,保留 raw 供模块特有操作读取原始字段。 */ function l(t) { let o = n(t); return r(o.disk ?? o.disks ?? o.disk_list).map((t, n) => { let r = String(t.type2 ?? t.type ?? t.disk_property ?? ``).toLowerCase(), o = [`system`, `sys`, `1`].includes(r) || /系统/.test(String(t.name ?? ``)); return { ident: String(t.id ?? t.disk_id ?? t.identity ?? n), name: String(t.name ?? t.disk_name ?? (o ? `系统盘` : `数据盘`)), size: a(t.size ?? t.disk_size) ?? 0, type: String(t.fs_type ?? t.disk_type ?? `—`), type2: o ? `system` : `data`, status: e(t.status) ?? -1, createTime: i(t.create_time ?? t.created_at), raw: t, }; }); } // 镜像名称按接口字段优先级读取,最后使用财务模块 host_data 中的系统名。 function u(e) { let t = n(e), i = n(t.image), a = n(t.host_data), o = r(t.config_options).find((e) => Number(e.option_type) === 5); return { name: String( t.image_name ?? i.name ?? t.os_name ?? t.os ?? o?.sub_name ?? a.os ?? ``, ), icon: String(t.image_icon ?? i.icon ?? ``), url: String(t.image_icon_url ?? i.icon_url ?? ``), }; } // 操作日志存在多种字段命名;只归一数据,不在此层改变日志正文。 function d(e, t) { let r = n(e); return { id: String(r.id ?? r.log_id ?? t), description: String( r.description ?? r.content ?? r.detail ?? r.message ?? r.des ?? `—`, ), create_time: i(r.create_time ?? r.created_at ?? r.time ?? r.date), ip: String(r.ip ?? r.ip_address ?? ``), }; } export { u as a, t as c, o as d, r as i, n as l, s as n, d as o, c as r, e as s, l as t, i as u, };