/** * Dynamic Unit System * * Handles dynamic unit conversion and display for product parameters. * Base units: storage=GB, bandwidth=Mbps, cpu=Core */ const UNIT_CONVERSIONS = { cpu: { Core: 1 }, bandwidth_up: { Mbps: 1, Gbps: 1000 }, bandwidth_down: { Mbps: 1, Gbps: 1000 }, storage: { GB: 1, TB: 1024 }, ipv4: { '个': 1 }, ipv6: { '个': 1 }, custom: {} } const BASE_UNITS = { cpu: 'Core', bandwidth_up: 'Mbps', bandwidth_down: 'Mbps', storage: 'GB', ipv4: '个', ipv6: '个', custom: '' } const DEFAULT_DISPLAY_UNITS = { cpu: 'Core', bandwidth_up: 'Mbps', bandwidth_down: 'Mbps', storage: 'GB', ipv4: '个', ipv6: '个', custom: '' } const ARG_KEY_OPTIONS = [ { label: 'CPU (cpu)', value: 'cpu' }, { label: 'IPv4', value: 'ipv4' }, { label: 'IPv6', value: 'ipv6' }, { label: '上行带宽 (bandwidth_up)', value: 'bandwidth_up' }, { label: '下行带宽 (bandwidth_down)', value: 'bandwidth_down' }, { label: '存储空间 (storage)', value: 'storage' }, { label: '自定义 (custom)', value: 'custom' } ] /** * Convert value between units * @param {number} value * @param {string} fromUnit * @param {string} toUnit * @param {string} argKey - e.g. 'storage', 'bandwidth_up' */ export function convertUnit(value, fromUnit, toUnit, argKey) { if (value === null || value === undefined || fromUnit === toUnit) return value const conversions = UNIT_CONVERSIONS[argKey] if (!conversions || !conversions[fromUnit] || !conversions[toUnit]) return value const baseValue = value * conversions[fromUnit] return baseValue / conversions[toUnit] } /** * Convert from display unit to base unit for storage/submission */ export function toBaseUnit(value, displayUnit, argKey) { const baseUnit = BASE_UNITS[argKey] if (!baseUnit || !displayUnit) return value return convertUnit(value, displayUnit, baseUnit, argKey) } /** * Convert from base unit to display unit for showing in UI */ export function fromBaseUnit(value, displayUnit, argKey) { const baseUnit = BASE_UNITS[argKey] if (!baseUnit || !displayUnit) return value return convertUnit(value, baseUnit, displayUnit, argKey) } /** * Get base unit string for a given argKey */ export function getBaseUnit(argKey) { return BASE_UNITS[argKey] || '' } /** * Get default display unit for a given argKey */ export function getDefaultDisplayUnit(argKey) { return DEFAULT_DISPLAY_UNITS[argKey] || '' } /** * Get all available units for a parameter type */ export function getAvailableUnits(argKey) { const conversions = UNIT_CONVERSIONS[argKey] return conversions ? Object.keys(conversions) : [] } /** * Get argKey select options */ export function getArgKeyOptions() { return ARG_KEY_OPTIONS } /** * Check if a parameter has dynamic unit enabled. * Returns true when arg_key maps to a known unit type with multiple selectable units. */ export function hasUnit(param) { if (!param) return false const argKey = param.argKey || param.arg_key || param.key || '' if (!argKey || !(argKey in UNIT_CONVERSIONS)) return false return Object.keys(UNIT_CONVERSIONS[argKey]).length > 1 } /** * Get the argKey from a parameter object (handles camelCase, snake_case, and plain key) */ export function getArgKey(param) { if (!param) return '' return param.argKey || param.arg_key || param.key || '' } /** * Get the available units from a parameter object */ export function getParamUnits(param) { if (!hasUnit(param)) return [] const argKey = getArgKey(param) const paramUnits = param.availableUnits || param.available_units if (paramUnits && paramUnits.length > 0) return paramUnits return getAvailableUnits(argKey) } /** * Get the default unit from a parameter object */ export function getParamDefaultUnit(param) { if (!hasUnit(param)) return '' const argKey = getArgKey(param) return param.defaultUnit || param.default_unit || getDefaultDisplayUnit(argKey) } /** * Validate if a unit is valid for a parameter type */ export function isValidUnit(unit, argKey) { const conversions = UNIT_CONVERSIONS[argKey] return conversions && Object.prototype.hasOwnProperty.call(conversions, unit) } export function formatValueWithUnit(value, unit) { if (value === null || value === undefined || value === '') return '-' return unit ? `${value} ${unit}` : String(value) }