const { formatMagnitudeNumber, getOption, normalizeIndex, selectBestUnit } = require('../calculator-helpers.js') const KIND_OPTIONS = [ { key: 'resistor', label: '电阻' }, { key: 'capacitor', label: '电容' } ] const RESISTOR_FORMAT_OPTIONS = [ { key: '3digit', label: '3位' }, { key: '4digit', label: '4位' }, { key: 'eia96', label: 'EIA-96' } ] const CAPACITOR_FORMAT_OPTIONS = [ { key: '3digit', label: '3位' }, { key: '4digit', label: '4位' }, { key: 'eia198', label: 'EIA-198' } ] const RESISTOR_UNITS = [ { label: 'mΩ', factor: 1e-3 }, { label: 'Ω', factor: 1 }, { label: 'kΩ', factor: 1e3 }, { label: 'MΩ', factor: 1e6 }, { label: 'GΩ', factor: 1e9 } ] const CAPACITOR_UNITS = [ { label: 'pF', factor: 1e-12 }, { label: 'nF', factor: 1e-9 }, { label: 'μF', factor: 1e-6 }, { label: 'mF', factor: 1e-3 }, { label: 'F', factor: 1 } ] const EIA_96_VALUES = [ 100, 102, 105, 107, 110, 113, 115, 118, 121, 124, 127, 130, 133, 137, 140, 143, 147, 150, 154, 158, 162, 165, 169, 174, 178, 182, 187, 191, 196, 200, 205, 210, 215, 221, 226, 232, 237, 243, 249, 255, 261, 267, 274, 280, 287, 294, 301, 309, 316, 324, 332, 340, 348, 357, 365, 374, 383, 392, 402, 412, 422, 432, 442, 453, 464, 475, 487, 499, 511, 523, 536, 549, 562, 576, 590, 604, 619, 634, 649, 665, 681, 698, 715, 732, 750, 768, 787, 806, 825, 845, 866, 887, 909, 931, 953, 976 ] const EIA_96_MULTIPLIERS = { A: 1, B: 10, C: 100, D: 1000, E: 10000, F: 100000, H: 10, R: 0.01, S: 0.1, X: 0.1, Y: 0.01, Z: 0.001 } const EIA_198_VALUES = { A: 1.0, B: 1.1, C: 1.2, D: 1.3, E: 1.5, F: 1.6, G: 1.8, H: 2.0, J: 2.2, K: 2.4, a: 2.5, L: 2.7, M: 3.0, N: 3.3, b: 3.5, P: 3.6, Q: 3.9, d: 4.0, R: 4.3, e: 4.5, S: 4.7, f: 5.0, T: 5.1, U: 5.6, m: 6.0, V: 6.2, W: 6.8, n: 7.0, X: 7.5, t: 8.0, Y: 8.2, y: 9.0, Z: 9.1 } const EIA_198_MULTIPLIERS = { 0: 1, 1: 10, 2: 100, 3: 1000, 4: 10000, 5: 100000, 6: 1000000, 7: 10000000, 8: 0.01, 9: 0.1 } function formatNumber(value) { return formatMagnitudeNumber(value, { fallbackText: '' }) } function formatValue(baseValue, units, fallbackIndex = 0) { const unit = selectBestUnit(units, baseValue, fallbackIndex).unit return `${formatNumber(baseValue / unit.factor)} ${unit.label}` } function sanitizeCode(text) { return String(text === undefined || text === null ? '' : text).trim().replace(/\s+/g, '') } function parseDecimalCode(code, unitName) { if (!/^[0-9]*[Rr][0-9]+$/.test(code)) return null const normalized = code.replace(/[Rr]/, '.') const value = Number(normalized) if (!Number.isFinite(value)) throw new Error('编码格式无效') return { formula: `${code} = ${formatNumber(value)} ${unitName}`, value } } function parseDigitCode(code, significantDigits, unitName) { const decimalParsed = parseDecimalCode(code, unitName) if (decimalParsed) return decimalParsed if (!new RegExp(`^\\d{${significantDigits + 1}}$`).test(code)) { throw new Error(`请输入${significantDigits + 1}位数字编码`) } if (/^0+$/.test(code)) { return { formula: `${code} = 0 ${unitName}`, value: 0 } } const significant = Number(code.slice(0, significantDigits)) const multiplier = Number(code.slice(significantDigits)) const value = significant * Math.pow(10, multiplier) return { formula: `${significant} × 10^${multiplier} ${unitName}`, value } } function parseEia96(code) { const normalized = code.toUpperCase() const match = normalized.match(/^(\d{2})([A-Z])$/) if (!match) throw new Error('请输入2位数字加1位字母') const valueIndex = Number(match[1]) const multiplier = EIA_96_MULTIPLIERS[match[2]] if (valueIndex < 1 || valueIndex > 96 || multiplier === undefined) { throw new Error('EIA-96编码无效') } const baseValue = EIA_96_VALUES[valueIndex - 1] return { formula: `${match[1]}=${baseValue},${match[2]}=×${formatNumber(multiplier)}`, value: baseValue * multiplier } } function parseEia198(code) { const match = code.match(/^([A-Za-z])(\d)$/) || code.match(/^(\d)([A-Za-z])$/) if (!match) throw new Error('请输入1位字母加1位数字') const letter = Number.isNaN(Number(match[1])) ? match[1] : match[2] const digit = Number.isNaN(Number(match[1])) ? match[2] : match[1] const baseValue = EIA_198_VALUES[letter] const multiplier = EIA_198_MULTIPLIERS[digit] if (baseValue === undefined || multiplier === undefined) { throw new Error('EIA-198编码无效') } return { formula: `${letter}=${formatNumber(baseValue)},${digit}=×${formatNumber(multiplier)}pF`, value: baseValue * multiplier * 1e-12 } } function calculate(kindKey, formatKey, codeText) { const code = sanitizeCode(codeText) if (!code) { return { formulaText: '', resultText: '--', errorText: '' } } try { if (kindKey === 'capacitor') { const parsed = formatKey === 'eia198' ? parseEia198(code) : parseDigitCode(code, formatKey === '4digit' ? 3 : 2, 'pF') const value = formatKey === 'eia198' ? parsed.value : parsed.value * 1e-12 return { formulaText: parsed.formula, resultText: formatValue(value, CAPACITOR_UNITS), errorText: '' } } const parsed = formatKey === 'eia96' ? parseEia96(code) : parseDigitCode(code, formatKey === '4digit' ? 3 : 2, 'Ω') return { formulaText: parsed.formula, resultText: formatValue(parsed.value, RESISTOR_UNITS, 1), errorText: '' } } catch (error) { return { formulaText: '', resultText: '--', errorText: error.message || '编码格式无效' } } } function buildState(source = {}) { const kindIndex = normalizeIndex(source.smdKindIndex, KIND_OPTIONS, 0) const kind = getOption(KIND_OPTIONS, kindIndex) const formatOptions = kind.key === 'capacitor' ? CAPACITOR_FORMAT_OPTIONS : RESISTOR_FORMAT_OPTIONS const currentFormatKey = source.smdFormatKey || (source.smdFormatOptions && source.smdFormatOptions[source.smdFormatIndex || 0] && source.smdFormatOptions[source.smdFormatIndex || 0].key) let formatIndex = formatOptions.findIndex((item) => item.key === currentFormatKey) if (formatIndex < 0) formatIndex = normalizeIndex(source.smdFormatIndex, formatOptions, 0) const format = getOption(formatOptions, formatIndex) const codeText = sanitizeCode(source.smdCodeText) const result = calculate(kind.key, format.key, codeText) return { smdCodeText: codeText, smdErrorText: result.errorText, smdFormatIndex: formatIndex, smdFormatKey: format.key, smdFormatOptions: formatOptions, smdFormatText: format.label, smdFormulaText: result.formulaText, smdKindIndex: kindIndex, smdKindKey: kind.key, smdKindOptions: KIND_OPTIONS, smdKindText: kind.label, smdResultText: result.resultText } } function createInitialState() { return buildState({ smdCodeText: '', smdFormatIndex: 0, smdKindIndex: 0 }) } function updateState(state, changedData = {}) { return buildState({ ...state, ...changedData }) } module.exports = { CAPACITOR_FORMAT_OPTIONS, KIND_OPTIONS, RESISTOR_FORMAT_OPTIONS, createInitialState, updateState }