新增对象存储/账单/保留IP页面,成本今天视图与样式收敛
CI / test (push) Successful in 42s

This commit is contained in:
2026-07-21 12:11:22 +08:00
parent d813225ac4
commit ac457282ce
91 changed files with 6672 additions and 652 deletions
@@ -0,0 +1,26 @@
import type { SelectOption } from 'naive-ui'
import { h, type VNodeChild } from 'vue'
import type { ReservedIp } from '@/types/api'
export interface ReservedIpOption extends SelectOption {
label: string
value: string
name: string
}
/** 未绑定保留 IP → 下拉选项:label 仅 IP(回显紧凑不截断),名称在选项行内弱化展示 */
export function freeReservedIpOptions(ips: ReservedIp[]): ReservedIpOption[] {
return ips
.filter((r) => !r.assignedInstanceId)
.map((r) => ({ label: r.ipAddress || r.id.slice(-12), value: r.id, name: r.displayName }))
}
/** NSelect renderLabel:IP 等宽字体 + 名称灰字截断;配合 consistent-menu-width=false 使用 */
export function renderReservedIpLabel(option: SelectOption): VNodeChild {
const o = option as ReservedIpOption
return h('div', { class: 'flex min-w-0 items-baseline gap-2' }, [
h('span', { class: 'mono text-[13px]' }, o.label),
o.name ? h('span', { class: 'max-w-44 truncate text-xs text-ink-3' }, o.name) : null,
])
}