通用版本分离
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { getAssetUrl } from '@/utils/asset';
|
||||
import React from 'react';
|
||||
import { HomePage, Project, Operators, CableId, Tools, Result, TestConfig, MenuList, Testing, ResultInfo, CopperPerformance } from '@/components/dsxpage';
|
||||
import Toast from '../lib/Toast';
|
||||
import useDisplayStore from '@/store/displayStore';
|
||||
@@ -46,11 +45,7 @@ export default function DSXDisplay() {
|
||||
};
|
||||
|
||||
const handleClick = () => {
|
||||
if (touchSound) {
|
||||
touchSound.currentTime = 0;
|
||||
touchSound.play();
|
||||
play('keyClick');
|
||||
}
|
||||
play('keyClick');
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -62,4 +57,4 @@ export default function DSXDisplay() {
|
||||
{renderPage()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ const LineChart = ({ title, x, y, y2 = null, accent = '#12f7ff', accent2 = '#f28
|
||||
// 独立的 EST-Analyzer 页面内容组件(不复用现有标题/状态栏/图表组件)
|
||||
// 父容器尺寸为 w-[480px] h-[640px],本组件内部使用响应式布局,不溢出
|
||||
export default function EstAnalyzerDisplay() {
|
||||
const { cableParams, mainUnitModules, updateReports, reports, connectionPaths } = useDeviceStore();
|
||||
const { cableParams, mainUnitModules, updateReports, reports, connectionPaths,hasBenchmarkModule } = useDeviceStore();
|
||||
|
||||
// 页面步骤:config -> benchmark -> progress -> result -> save -> saved
|
||||
const [step, setStep] = useState('config');
|
||||
@@ -296,9 +296,17 @@ export default function EstAnalyzerDisplay() {
|
||||
gold: 1.45,
|
||||
aluminum: 1.68
|
||||
};
|
||||
|
||||
// 频谱(用于曲线展示)——1MHz 采样:1,2,...,500
|
||||
const frequencies = useMemo(() => Array.from({ length: 500 }, (_, i) => i + 1), []);
|
||||
|
||||
// maxFrequencyMHz 最大频率(MHz)
|
||||
const maxFrequencyMHz = useMemo(() => {
|
||||
const t = (config?.cableType || '').toLowerCase();
|
||||
if (t.includes('6a')) return 500;
|
||||
if (t.includes('5e')) return 100;
|
||||
if (t.includes('6')) return 250;
|
||||
return 500;
|
||||
}, [config.cableType]);
|
||||
// 频谱(用于曲线展示)
|
||||
const frequencies = useMemo(() => Array.from({ length: maxFrequencyMHz }, (_, i) => i + 1), [maxFrequencyMHz]);
|
||||
|
||||
// 基于 cableParams 和 config.frequency 计算摘要与曲线
|
||||
const { summary, curves } = useMemo(() => {
|
||||
@@ -334,13 +342,13 @@ export default function EstAnalyzerDisplay() {
|
||||
const Z0Scale = Math.min(1.06, Math.max(0.94, Z0TwistAdj * Z0EpsAdj));
|
||||
Z0 *= Z0Scale;
|
||||
|
||||
// 插入损耗 IL 曲线:按 1–500MHz 从 ILData 采样
|
||||
// 插入损耗 IL 曲线:按 1–maxFrequencyMHzMHz 从 ILData 采样
|
||||
const sampleIL = (f) => {
|
||||
const fi = Math.round(Math.max(1, Math.min(500, f)));
|
||||
const fi = Math.round(Math.max(1, Math.min(maxFrequencyMHz, f)));
|
||||
const v = ILData[fi];
|
||||
return typeof v === 'number' ? v : 0;
|
||||
};
|
||||
// IL 基线(1-500MHz)
|
||||
// IL 基线(1-maxFrequencyMHzMHz)
|
||||
const IL_base = frequencies.map(f => sampleIL(f));
|
||||
// 物理影响参数(以 20m、pe、twistPitch=10mm、coreDia=0.51mm 为参考)
|
||||
const L0 = 20; // m,基线长度
|
||||
@@ -378,7 +386,7 @@ export default function EstAnalyzerDisplay() {
|
||||
let val = vLen + addSqrt * wSqrt(f) + addLinF * wLinF(f);
|
||||
// 噪声(随频率略增)
|
||||
const sigma0 = 0.02, sigma1 = 0.06; // dB
|
||||
const noiseAmp = sigma0 + sigma1 * (f / 500);
|
||||
const noiseAmp = sigma0 + sigma1 * (f / maxFrequencyMHz);
|
||||
const r = Math.sin((idx + 1) * 37.7 + (lenScale + tightness) * 11.3) * 0.5 + Math.cos((idx + 1) * 19.1) * 0.5;
|
||||
val += r * noiseAmp;
|
||||
return Math.max(0, val);
|
||||
@@ -397,20 +405,20 @@ export default function EstAnalyzerDisplay() {
|
||||
const n = (prng(seedBase * 0.83 + i * 5.21) - 0.5) * 2; // [-1,1]
|
||||
const ripple = (prng(seedBase * 0.67 + i * 2.19) - 0.5) * 2 * 1.2; // ±1.2MHz
|
||||
const df = phaseStrength * f * (1 - Math.exp(-f / Math.max(f0, 1))) * n + ripple;
|
||||
return Math.max(1, Math.min(500, f + df));
|
||||
return Math.max(1, Math.min(maxFrequencyMHz, f + df));
|
||||
};
|
||||
IL2 = frequencies.map((f, i) => {
|
||||
// 频轴挪动后线性插值 IL
|
||||
const f2 = warp(f, i);
|
||||
const fi0 = Math.floor(f2);
|
||||
const fi1 = Math.min(500, fi0 + 1);
|
||||
const fi1 = Math.min(maxFrequencyMHz, fi0 + 1);
|
||||
const t = f2 - fi0;
|
||||
const vWarp = ((IL[fi0 - 1] ?? IL_base[fi0 - 1] ?? 0) * (1 - t)) + ((IL[fi1 - 1] ?? IL_base[fi1 - 1] ?? 0) * t);
|
||||
// 幅度偏置
|
||||
const n1 = (prng(seedBase + i * 13.37) - 0.5) * 2; // [-1,1]
|
||||
const n2 = (prng(seedBase + i * 7.11) - 0.5); // [-0.5,0.5]
|
||||
const pos = 0.15 + 0.20 * (f / 500); // +0.15→+0.35 dB
|
||||
const neg = 0.10 + 0.10 * (f / 500); // -0.10→-0.20 dB
|
||||
const pos = 0.15 + 0.20 * (f / maxFrequencyMHz); // +0.15→+0.35 dB
|
||||
const neg = 0.10 + 0.10 * (f / maxFrequencyMHz); // -0.10→-0.20 dB
|
||||
const rel = 0.02; // ±2% 相对偏移
|
||||
const add = (n1 >= 0 ? (n1 * pos) : (n1 * neg));
|
||||
const val = Math.max(0, vWarp * (1 + rel * n1) + (n2 * 0.18) + add);
|
||||
@@ -418,11 +426,11 @@ export default function EstAnalyzerDisplay() {
|
||||
});
|
||||
}
|
||||
|
||||
// 基准回波损耗 RL 曲线:直接使用 RLData(1–500MHz 的基准值)
|
||||
// 基准回波损耗 RL 曲线:直接使用 RLData(1–maxFrequencyMHzMHz 的基准值)
|
||||
const Zref = 100; // 供 TDR 使用
|
||||
const lenLog = Math.max(0, Math.log1p(lengthM || 0)); // 供 TDR 使用
|
||||
const sampleRL = (f) => {
|
||||
const fi = Math.round(Math.max(1, Math.min(500, f)));
|
||||
const fi = Math.round(Math.max(1, Math.min(maxFrequencyMHz, f)));
|
||||
const v = RLData[fi];
|
||||
return typeof v === 'number' ? v : 0;
|
||||
};
|
||||
@@ -445,7 +453,7 @@ export default function EstAnalyzerDisplay() {
|
||||
let val = v - fall + ripple;
|
||||
// 噪声
|
||||
const sigma0 = 0.08, sigma1 = 0.12;
|
||||
const noiseAmp = sigma0 + sigma1 * (f / 500);
|
||||
const noiseAmp = sigma0 + sigma1 * (f / maxFrequencyMHz);
|
||||
const r = Math.sin((idx + 1) * 23.4 + phi * 0.5) * 0.5 + Math.cos((idx + 1) * 9.7) * 0.5;
|
||||
val += r * noiseAmp;
|
||||
// 边界:允许为负值,仅限制上限以避免不现实的大值
|
||||
@@ -464,27 +472,27 @@ export default function EstAnalyzerDisplay() {
|
||||
const n = (prng2(seed2 * 0.77 + i * 3.91) - 0.5) * 2;
|
||||
const ripple = (prng2(seed2 * 0.55 + i * 2.41) - 0.5) * 2 * 1.0; // ±1.0MHz
|
||||
const df = phaseStrength * f * (1 - Math.exp(-f / Math.max(f0, 1))) * n + ripple;
|
||||
return Math.max(1, Math.min(500, f + df));
|
||||
return Math.max(1, Math.min(maxFrequencyMHz, f + df));
|
||||
};
|
||||
RL2 = frequencies.map((f, i) => {
|
||||
const f2 = warp(f, i);
|
||||
const fi0 = Math.floor(f2);
|
||||
const fi1 = Math.min(500, fi0 + 1);
|
||||
const fi1 = Math.min(maxFrequencyMHz, fi0 + 1);
|
||||
const t = f2 - fi0;
|
||||
const vWarp = ((RL[fi0 - 1] ?? RL_base[fi0 - 1] ?? 0) * (1 - t)) + ((RL[fi1 - 1] ?? RL_base[fi1 - 1] ?? 0) * t);
|
||||
const n1 = (prng2(seed2 + i * 17.3) - 0.5) * 2; // [-1,1]
|
||||
const n2 = (prng2(seed2 + i * 5.9) - 0.5); // [-0.5,0.5]
|
||||
const pos = 0.20 + 0.40 * (f / 500); // +0.2→+0.6 dB
|
||||
const neg = 0.40 + 0.80 * (f / 500); // -0.4→-1.2 dB
|
||||
const pos = 0.20 + 0.40 * (f / maxFrequencyMHz); // +0.2→+0.6 dB
|
||||
const neg = 0.40 + 0.80 * (f / maxFrequencyMHz); // -0.4→-1.2 dB
|
||||
const add = (n1 >= 0 ? (n1 * pos) : (n1 * neg));
|
||||
const val = vWarp + (n2 * 1.2) + add;
|
||||
return Math.min(100, val);
|
||||
});
|
||||
}
|
||||
|
||||
// NEXT 曲线:按 1–500MHz 从 NEXTData 采样
|
||||
// NEXT 曲线:按 1–maxFrequencyMHzMHz 从 NEXTData 采样
|
||||
const sampleNEXT = (f) => {
|
||||
const fi = Math.round(Math.max(1, Math.min(500, f)));
|
||||
const fi = Math.round(Math.max(1, Math.min(maxFrequencyMHz, f)));
|
||||
const v = NEXTData[fi];
|
||||
return typeof v === 'number' ? v : 0;
|
||||
};
|
||||
@@ -512,7 +520,7 @@ export default function EstAnalyzerDisplay() {
|
||||
let val = v + (-h_len * lenDelta * w) - (h_twist_bad * pitchBadness * w) + (h_diff * ratioImprove * w);
|
||||
// 噪声
|
||||
const sigma0 = 0.06, sigma1 = 0.10;
|
||||
const noiseAmp = sigma0 + sigma1 * (f / 500);
|
||||
const noiseAmp = sigma0 + sigma1 * (f / maxFrequencyMHz);
|
||||
const r = Math.sin((idx + 1) * 13.9 + twistDiff * 5.7) * 0.5 + Math.cos((idx + 1) * 7.3) * 0.5;
|
||||
val += r * noiseAmp;
|
||||
// 边界夹限
|
||||
@@ -531,7 +539,7 @@ export default function EstAnalyzerDisplay() {
|
||||
const n = (prng3(seed3 * 0.93 + i * 4.29) - 0.5) * 2;
|
||||
const ripple = (prng3(seed3 * 0.69 + i * 2.11) - 0.5) * 2 * 1.0;
|
||||
const df = phaseStrength * f * (1 - Math.exp(-f / Math.max(f0, 1))) * n + ripple;
|
||||
return Math.max(1, Math.min(500, f + df));
|
||||
return Math.max(1, Math.min(maxFrequencyMHz, f + df));
|
||||
};
|
||||
// 次曲线也应受绞距与节距比影响(轻度,但可见)
|
||||
const k_tw2 = 0.55; // 次曲线绞距劣化权重(弱于主曲线)
|
||||
@@ -539,13 +547,13 @@ export default function EstAnalyzerDisplay() {
|
||||
NEXT2 = frequencies.map((f, i) => {
|
||||
const f2 = warp(f, i);
|
||||
const fi0 = Math.floor(f2);
|
||||
const fi1 = Math.min(500, fi0 + 1);
|
||||
const fi1 = Math.min(maxFrequencyMHz, fi0 + 1);
|
||||
const t = f2 - fi0;
|
||||
const vWarp = ((NEXT[fi0 - 1] ?? NEXT_base[fi0 - 1] ?? 0) * (1 - t)) + ((NEXT[fi1 - 1] ?? NEXT_base[fi1 - 1] ?? 0) * t);
|
||||
const n1 = (prng3(seed3 + i * 11.9) - 0.5) * 2; // [-1,1]
|
||||
const n2 = (prng3(seed3 + i * 3.7) - 0.5); // [-0.5,0.5]
|
||||
const pos = 0.15 + 0.35 * (f / 500); // +0.15→+0.50 dB
|
||||
const neg = 0.30 + 0.50 * (f / 500); // -0.30→-0.80 dB
|
||||
const pos = 0.15 + 0.35 * (f / maxFrequencyMHz); // +0.15→+0.50 dB
|
||||
const neg = 0.30 + 0.50 * (f / maxFrequencyMHz); // -0.30→-0.80 dB
|
||||
const add = (n1 >= 0 ? (n1 * pos) : (n1 * neg));
|
||||
const w2 = W(f);
|
||||
const shift = (-k_tw2 * pitchBadness * w2) + (k_df2 * ratioImprove * w2);
|
||||
@@ -802,9 +810,9 @@ export default function EstAnalyzerDisplay() {
|
||||
<input
|
||||
type="range"
|
||||
min={1}
|
||||
max={500}
|
||||
max={maxFrequencyMHz}
|
||||
step={1}
|
||||
value={config.frequency}
|
||||
value={Math.min(config.frequency || 1, maxFrequencyMHz)}
|
||||
onChange={e => setConfig({ ...config, frequency: parseInt(e.target.value) })}
|
||||
className="w-full h-2 bg-[#12f7ff]/20 rounded appearance-none cursor-pointer" style={{ accentColor: '#12f7ff' }}
|
||||
/>
|
||||
@@ -814,7 +822,12 @@ export default function EstAnalyzerDisplay() {
|
||||
<label className="text-[12px] text-[#7bdbe3]">线缆类型</label>
|
||||
<select
|
||||
value={config.cableType}
|
||||
onChange={e => setConfig({ ...config, cableType: e.target.value })}
|
||||
onChange={e => {
|
||||
const v = e.target.value;
|
||||
const t = (v || '').toLowerCase();
|
||||
const m = t.includes('6a') ? 500 : (t.includes('5e') ? 100 : (t.includes('6') ? 250 : 500));
|
||||
setConfig(prev => ({ ...prev, cableType: v, frequency: Math.min(prev.frequency || 1, m) }));
|
||||
}}
|
||||
className="w-full p-2 rounded bg-[#0c1319] text-[#c9f9ff] border border-[#12f7ff]/20 text-[13px]"
|
||||
>
|
||||
<option>Cat6A U/UTP</option>
|
||||
@@ -875,10 +888,10 @@ export default function EstAnalyzerDisplay() {
|
||||
<div className="flex flex-col items-center gap-3 py-2">
|
||||
<div className="text-[13px] text-[#c9f9ff]">请将主机与远端分别连接到 基准适配器 </div>
|
||||
<div className="text-[12px] text-[#7bdbe3]">连接完成后将出现“完成基准设置”按钮</div>
|
||||
<img src={getAssetUrl('/benchmark-ref.png')} alt="benchmark" className="w-[200px] h-[200px] object-contain" />
|
||||
<img src={getAssetUrl('/benchmark-ref.png')} alt="benchmark" className="w-[80%] object-contain" />
|
||||
</div>
|
||||
</Card>
|
||||
{canCompleteBenchmark && (
|
||||
{hasBenchmarkModule && (
|
||||
<div className="flex justify-center">
|
||||
<button
|
||||
className="h-[32px] px-4 rounded bg-[#12f7ff]/20 text-[#12f7ff] text-[13px] hover:bg-[#12f7ff]/30"
|
||||
@@ -1094,4 +1107,4 @@ export default function EstAnalyzerDisplay() {
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import StatusBar from '@/components/lib//StatusBar';
|
||||
import ResultTitleBar from '@/components/lib//ResultTitleBar';
|
||||
import StatusBar from '@/components/lib/StatusBar';
|
||||
import ResultTitleBar from '@/components/lib/ResultTitleBar';
|
||||
import useDisplayStore from '@/store/displayStore';
|
||||
import FrequencyChart from '@/components/lib//FrequencyChart';
|
||||
import HDTDChart from '@/components/lib//HDTDChart';
|
||||
import useDeviceStore from '@/store/deviceStore';
|
||||
import FrequencyChart from '@/components/lib/FrequencyChart';
|
||||
import HDTDChart from '@/components/lib/HDTDChart';
|
||||
|
||||
export default function CopperPerformance( ) {
|
||||
const { estmodel } = useDeviceStore();
|
||||
const { navigation, navigateTo,goBack } = useDisplayStore();
|
||||
const { view } = navigation.current;
|
||||
const curtitle = navigation.current.params.curtitle;
|
||||
const testResult = navigation.current.params.testResult;
|
||||
const CopperResultStatus = testResult.CopperResultStatus;
|
||||
const limitValue = testResult.testconfig.params.limitValue;
|
||||
const [limitdata, setLimitdata] = useState(null);
|
||||
const wireOrder = testResult?.testconfig?.params?.wireOrder;
|
||||
@@ -37,6 +40,26 @@ export default function CopperPerformance( ) {
|
||||
|
||||
const [poeTab, setPoeTab] = useState('回路');
|
||||
|
||||
const getDisplayTitle = (key) => {
|
||||
const map = {
|
||||
'长度': '长度',
|
||||
'电阻': '电阻',
|
||||
'插入损耗': '插入损耗',
|
||||
'回波损耗': '回波损耗',
|
||||
'NEXT': '近端串音',
|
||||
'PS NEXT': '近端串音功率和',
|
||||
'ACR-N': '衰减近端串音比',
|
||||
'PS ACR-N': '衰减近端串音比功率和',
|
||||
'ACR-F': '衰减远端串音比',
|
||||
'PS ACR-F': '衰减远端串音比功率和',
|
||||
'CDNEXT': '共模转差模近端串音',
|
||||
'CMRL': '共模回波损耗',
|
||||
'TCL': '横向转换损耗',
|
||||
'ELTCTL': '两端等效横向转换损耗'
|
||||
};
|
||||
return map[key] || key;
|
||||
};
|
||||
|
||||
const renderResultTitleBar = () => {
|
||||
const handleBack = () => {
|
||||
goBack();
|
||||
@@ -56,7 +79,7 @@ export default function CopperPerformance( ) {
|
||||
title = '图表';
|
||||
break;
|
||||
};
|
||||
return <ResultTitleBar title={curtitle} onBack={handleBack} />;
|
||||
return <ResultTitleBar title={getDisplayTitle(curtitle)} onBack={handleBack} />;
|
||||
};
|
||||
|
||||
const renderContent = () => {
|
||||
@@ -303,9 +326,11 @@ export default function CopperPerformance( ) {
|
||||
{limitdata && (
|
||||
<FrequencyChart
|
||||
curtitle={curtitle}
|
||||
displayTitle={getDisplayTitle(curtitle)}
|
||||
limitValue={limitValue}
|
||||
limitdata={limitdata}
|
||||
wireOrder={wireOrder}
|
||||
CopperResultStatus={CopperResultStatus}
|
||||
data={testResult?.resultdata?.performance?.data}
|
||||
/>
|
||||
)}
|
||||
@@ -331,9 +356,27 @@ export default function CopperPerformance( ) {
|
||||
};
|
||||
|
||||
const renderFooter = () => {
|
||||
const showHDTDR = estmodel === 'general' && testResult?.CopperResultStatus === 'fail' && view === 'DRAW' && curtitle === '回波损耗';
|
||||
const showHDTDX = estmodel === 'general' && testResult?.CopperResultStatus === 'fail' && view === 'DRAW' && curtitle === 'NEXT';
|
||||
console.log(estmodel, CopperResultStatus, view, curtitle, showHDTDR, showHDTDX);
|
||||
return (
|
||||
<div className="h-[60px] bg-[#132843] flex items-center justify-end px-8">
|
||||
|
||||
<div className="h-[60px] bg-[#132843] flex items-center justify-end px-8 gap-4">
|
||||
{showHDTDR && (
|
||||
<button
|
||||
className="px-4 h-[40px] bg-gradient-to-b from-[#b6dae7] to-[#65dfff] transition-colors duration-200 rounded-lg flex items-center justify-center text-black font-bold shadow-lg"
|
||||
onClick={() => navigateTo('copperperformance', 'HDTD', { testResult, curtitle: 'HDTDR' })}
|
||||
>
|
||||
时域反射分析
|
||||
</button>
|
||||
)}
|
||||
{showHDTDX && (
|
||||
<button
|
||||
className="px-4 h-[40px] bg-gradient-to-b from-[#b6dae7] to-[#65dfff] transition-colors duration-200 rounded-lg flex items-center justify-center text-black font-bold shadow-lg"
|
||||
onClick={() => navigateTo('copperperformance', 'HDTD', { testResult, curtitle: 'HDTDX' })}
|
||||
>
|
||||
时域串音分析
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -346,4 +389,4 @@ export default function CopperPerformance( ) {
|
||||
{renderFooter()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import Image from 'next/image';
|
||||
import { FolderIcon, SwatchIcon, TagIcon, UserIcon, PuzzlePieceIcon } from '@heroicons/react/24/solid';
|
||||
import StatusBar from '@/components/lib//StatusBar';
|
||||
import TitleBar from '@/components/lib//TitleBar';
|
||||
import useDisplayStore from '@/store/displayStore';
|
||||
@@ -114,7 +115,7 @@ export default function HomePage() {
|
||||
case 'cfp':
|
||||
return (
|
||||
<div className="flex flex-col justify-center h-full space-y-0.2 text-sm">
|
||||
<div className="text-black text-sm">智能远端</div>
|
||||
<div className="text-black text-sm">光纤损耗测试</div>
|
||||
<div className="text-black text-sm">{currentConfig.params.limitValue}</div>
|
||||
<div className="text-black text-sm">{currentConfig.params.cableType}</div>
|
||||
<div className="text-black text-sm">{currentConfig.params.refJumper} 跳线参照</div>
|
||||
@@ -152,19 +153,19 @@ export default function HomePage() {
|
||||
<div className="flex justify-between items-start">
|
||||
{mainUnitModules?.[0]?.id === '8000' ? (
|
||||
<div>
|
||||
<div className="text-lg font-bold text-[#132843] ">当前安装模块:铜缆分析模块</div>
|
||||
<div className=" font-bold text-[#132843] flex items-center gap-1"><PuzzlePieceIcon className="w-5 h-5 text-[#132843]" />当前安装模块:铜缆分析模块</div>
|
||||
</div>
|
||||
) : mainUnitModules?.[0]?.id === 'cfp' ? (
|
||||
<div>
|
||||
<div className="text-lg font-bold text-[#132843]">当前安装模块:光纤损耗模块</div>
|
||||
<div className=" font-bold text-[#132843] flex items-center gap-1"><PuzzlePieceIcon className="w-5 h-5 text-[#132843]" />当前安装模块:光纤损耗模块</div>
|
||||
</div>
|
||||
) : mainUnitModules?.[0]?.id === 'ofp' ? (
|
||||
<div>
|
||||
<div className="text-lg font-bold text-[#132843]">当前安装模块:光时域反射模块</div>
|
||||
<div className=" font-bold text-[#132843] flex items-center gap-1"><PuzzlePieceIcon className="w-5 h-5 text-[#132843]" />当前安装模块:光时域反射模块</div>
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<div className="text-lg font-bold text-[#132843]">请安装模块</div>
|
||||
<div className=" font-bold text-[#132843] flex items-center gap-1"><PuzzlePieceIcon className="w-5 h-5 text-[#132843]" /> 请安装模块</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -174,7 +175,7 @@ export default function HomePage() {
|
||||
<div className="bg-[#F8F6F7] rounded-lg p-4 shadow-md hover:shadow-lg transition-shadow duration-200 cursor-pointer"
|
||||
onClick={handleProjectClick}>
|
||||
|
||||
<div className="text-[#132843] font-bold mb-1">项目</div>
|
||||
<div className="text-[#132843] font-bold mb-1 flex items-center gap-1"><FolderIcon className="w-4 h-4 text-[#132843]" /> 项目</div>
|
||||
<div className="flex justify-between items-start">
|
||||
<div>
|
||||
<div className="text-[#132843] text-sm pt-2">{currentProject?.name}</div>
|
||||
@@ -224,7 +225,7 @@ export default function HomePage() {
|
||||
onClick={() => navigateTo('testConfig', 'main')}
|
||||
>
|
||||
<div className="flex flex-col">
|
||||
<div className="text-[#132843] font-bold mb-1">测试极限值</div>
|
||||
<div className="text-[#132843] font-bold mb-1 flex items-center gap-1"><SwatchIcon className="w-4 h-4 text-[#132843]" /> 测试极限值</div>
|
||||
|
||||
<div className="flex-1">{renderTestConfigContent()}</div>
|
||||
</div>
|
||||
@@ -252,7 +253,7 @@ export default function HomePage() {
|
||||
>
|
||||
<div className="flex justify-between items-start">
|
||||
<div className="flex flex-col">
|
||||
<div className="text-[#132843] font-bold mb-1">下一条记录</div>
|
||||
<div className="text-[#132843] font-bold mb-1 flex items-center gap-1"><TagIcon className="w-4 h-4 text-[#132843]" /> 下一条记录</div>
|
||||
{currentConfig?.moduleType === 'cfp' ? (
|
||||
<>
|
||||
<div className="text-[#132843] text-sm">输入:<span className="font-medium">{currentCableId?.name || ''}</span></div>
|
||||
@@ -283,7 +284,7 @@ export default function HomePage() {
|
||||
>
|
||||
<div className="flex justify-between items-start">
|
||||
<div className="flex flex-col">
|
||||
<div className="text-[#132843] font-bold mb-1">操作员</div>
|
||||
<div className="text-[#132843] font-bold mb-1 flex items-center gap-1"><UserIcon className="w-4 h-4 text-[#132843]" /> 操作员</div>
|
||||
<div className="text-[#132843] text-sm">
|
||||
<span className="font-medium">{currentOperator?.name || ''}</span>
|
||||
</div>
|
||||
@@ -509,4 +510,4 @@ export default function HomePage() {
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,222 +18,204 @@ const menuData = {
|
||||
title: '电缆类型',
|
||||
subTitle: '电缆类型',
|
||||
items: [
|
||||
{ value: 'custom', label: '定制', disabled: true },
|
||||
{
|
||||
value: 'general',
|
||||
label: '通用',
|
||||
children: [
|
||||
// { value: 'Cat8 S/FTP', label: 'Cat8 S/FTP' },
|
||||
// { value: 'Cat7A S/FTP', label: 'Cat7A S/FTP' },
|
||||
// { value: 'Cat7 S/FTP', label: 'Cat7 S/FTP' },
|
||||
// { value: 'Cat6A S/FTP', label: 'Cat6A S/FTP' },
|
||||
{ value: 'Cat6A U/UTP', label: 'Cat6A U/UTP' },
|
||||
{ value: 'Cat6A F/UTP', label: 'Cat6A F/UTP' },
|
||||
{ value: 'Cat6 U/UTP', label: 'Cat6 U/UTP' },
|
||||
{ value: 'Cat6 F/UTP', label: 'Cat6 F/UTP' },
|
||||
// { value: 'Cat6 U/FTP', label: 'Cat6 U/FTP' },
|
||||
{ value: 'Cat5e U/UTP', label: 'Cat5e U/UTP' },
|
||||
{ value: 'Cat5e F/UTP', label: 'Cat5e F/UTP' },
|
||||
// { value: 'Cat5 U/UTP', label: 'Cat5 U/UTP' },
|
||||
// { value: 'Cat5 F/UTP', label: 'Cat5 F/UTP' }
|
||||
]
|
||||
},
|
||||
{ value: 'coaxial', label: '通用同轴电缆', disabled: true },
|
||||
{ value: 'manufacturer', label: '制造商', disabled: true }
|
||||
]
|
||||
},
|
||||
LIMIT_VALUE: {
|
||||
title: '测试极限值',
|
||||
subTitle: '极限值组',
|
||||
items: [
|
||||
// {
|
||||
// value: 'TIA',
|
||||
// label: 'TIA',
|
||||
// children: {
|
||||
// // Cat8: {
|
||||
// // label: 'Cat8',
|
||||
// // children: [
|
||||
// // { value: 'TIA Cat 8 Perm.Link', label: 'TIA Cat 8 Perm.Link' },
|
||||
// // { value: 'TIA Cat 8 Perm.Link (+ALL)', label: 'TIA Cat 8 Perm.Link (+ALL)' },
|
||||
// // { value: 'TIA Cat 8 Perm.Link (+PoE)', label: 'TIA Cat 8 Perm.Link (+PoE)' },
|
||||
// // { value: 'TIA Cat 8 Channel', label: 'TIA Cat 8 Channel' },
|
||||
// // { value: 'TIA Cat 8 Channel (+ALL)', label: 'TIA Cat 8 Channel (+ALL)' },
|
||||
// // { value: 'TIA Cat 8 Channel (+PoE)', label: 'TIA Cat 8 Channel (+PoE)' }
|
||||
// // ]
|
||||
// // },
|
||||
// Cat6A: {
|
||||
// label: 'Cat6A',
|
||||
// children: [
|
||||
// { value: 'TIA Cat 6A Perm.Link', label: 'TIA Cat 6A Perm.Link' },
|
||||
// { value: 'TIA Cat 6A Perm.Link (+ALL)', label: 'TIA Cat 6A Perm.Link (+ALL)' },
|
||||
// { value: 'TIA Cat 6A Perm.Link (+PoE)', label: 'TIA Cat 6A Perm.Link (+PoE)' },
|
||||
// { value: 'TIA Cat 6A Channel', label: 'TIA Cat 6A Channel' },
|
||||
// { value: 'TIA Cat 6A Channel (+ALL)', label: 'TIA Cat 6A Channel (+ALL)' },
|
||||
// { value: 'TIA Cat 6A Channel (+PoE)', label: 'TIA Cat 6A Channel (+PoE)' },
|
||||
// { value: 'TIA Cat 6A MPTL', label: 'TIA Cat 6A MPTL' },
|
||||
// { value: 'TIA Cat 6A MPTL (+PoE)', label: 'TIA Cat 6A MPTL (+PoE)' },
|
||||
// // { value: 'TIA 1005 Cat 6A Perm.Link', label: 'TIA 1005 Cat 6A Perm.Link' },
|
||||
// // { value: 'TIA 1005 Cat 6A Channel', label: 'TIA 1005 Cat 6A Channel' },
|
||||
// { value: 'TIA 1005 Cat 6A Channel E1 (+ALL)', label: 'TIA 1005 Cat 6A Channel E1 (+ALL)' },
|
||||
// // { value: 'TIA 1005 Cat 6A Channel E1 (+PoE)', label: 'TIA 1005 Cat 6A Channel E1 (+PoE)' },
|
||||
// { value: 'TIA 1005 Cat 6A Channel E2 (+ALL)', label: 'TIA 1005 Cat 6A Channel E2 (+ALL)' },
|
||||
// // { value: 'TIA 1005 Cat 6A Channel E2 (+PoE)', label: 'TIA 1005 Cat 6A Channel E2 (+PoE)' },
|
||||
// { value: 'TIA 1005 Cat 6A Channel E3 (+ALL)', label: 'TIA 1005 Cat 6A Channel E3 (+ALL)' },
|
||||
// // { value: 'TIA 1005 Cat 6A Channel E3 (+PoE)', label: 'TIA 1005 Cat 6A Channel E3 (+PoE)' }
|
||||
// ]
|
||||
// },
|
||||
// Cat6: {
|
||||
// label: 'Cat6',
|
||||
// children: [
|
||||
// { value: 'TIA Cat 6 Perm.Link', label: 'TIA Cat 6 Perm.Link' },
|
||||
// { value: 'TIA Cat 6 Perm.Link (+ALL)', label: 'TIA Cat 6 Perm.Link (+ALL)' },
|
||||
// { value: 'TIA Cat 6 Perm.Link (+PoE)', label: 'TIA Cat 6 Perm.Link (+PoE)' },
|
||||
// { value: 'TIA Cat 6 Channel', label: 'TIA Cat 6 Channel' },
|
||||
// { value: 'TIA Cat 6 Channel (+ALL)', label: 'TIA Cat 6 Channel (+ALL)' },
|
||||
// { value: 'TIA Cat 6 Channel (+PoE)', label: 'TIA Cat 6 Channel (+PoE)' },
|
||||
// { value: 'TIA Cat 6 MPTL', label: 'TIA Cat 6 MPTL' },
|
||||
// { value: 'TIA Cat 6 MPTL (+PoE)', label: 'TIA Cat 6 MPTL (+PoE)' },
|
||||
// // { value: 'TIA 1005 Cat 6 Perm.Link', label: 'TIA 1005 Cat 6 Perm.Link' },
|
||||
// // { value: 'TIA 1005 Cat 6 Channel', label: 'TIA 1005 Cat 6 Channel' },
|
||||
// // { value: 'TIA 1005 Cat 6 Channel (+ALL)', label: 'TIA 1005 Cat 6 Channel (+ALL)' },
|
||||
// // { value: 'TIA 1005 Cat 6 Channel (+PoE)', label: 'TIA 1005 Cat 6 Channel (+PoE)' },
|
||||
// { value: 'TIA 1005 Cat 6 Channel E1 (+ALL)', label: 'TIA 1005 Cat 6 Channel E1 (+ALL)' },
|
||||
// // { value: 'TIA 1005 Cat 6 Channel E1 (+PoE)', label: 'TIA 1005 Cat 6 Channel E1 (+PoE)' },
|
||||
// { value: 'TIA 1005 Cat 6 Channel E2 (+ALL)', label: 'TIA 1005 Cat 6 Channel E2 (+ALL)' },
|
||||
// // { value: 'TIA 1005 Cat 6 Channel E2 (+PoE)', label: 'TIA 1005 Cat 6 Channel E2 (+PoE)' },
|
||||
// { value: 'TIA 1005 Cat 6 Channel E3 (+ALL)', label: 'TIA 1005 Cat 6 Channel E3 (+ALL)' },
|
||||
// // { value: 'TIA 1005 Cat 6 Channel E3 (+PoE)', label: 'TIA 1005 Cat 6 Channel E3 (+PoE)' }
|
||||
// ]
|
||||
// },
|
||||
// Cat5e: {
|
||||
// label: 'Cat5e',
|
||||
// children: [
|
||||
// { value: 'TIA Cat 5e Perm.Link', label: 'TIA Cat 5e Perm.Link' },
|
||||
// { value: 'TIA Cat 5e Perm.Link (+ALL)', label: 'TIA Cat 5e Perm.Link (+ALL)' },
|
||||
// { value: 'TIA Cat 5e Perm.Link (+PoE)', label: 'TIA Cat 5e Perm.Link (+PoE)' },
|
||||
// { value: 'TIA Cat 5e Channel', label: 'TIA Cat 5e Channel' },
|
||||
// { value: 'TIA Cat 5e Channel (+ALL)', label: 'TIA Cat 5e Channel (+ALL)' },
|
||||
// { value: 'TIA Cat 5e Channel (+PoE)', label: 'TIA Cat 5e Channel (+PoE)' },
|
||||
// { value: 'TIA Cat 5e MPTL', label: 'TIA Cat 5e MPTL' },
|
||||
// { value: 'TIA Cat 5e MPTL (+PoE)', label: 'TIA Cat 5e MPTL (+PoE)' },
|
||||
// // { value: 'TIA 1005 Cat 5e Perm.Link', label: 'TIA 1005 Cat 5e Perm.Link' },
|
||||
// // { value: 'TIA 1005 Cat 5e Channel', label: 'TIA 1005 Cat 5e Channel' },
|
||||
// // { value: 'TIA 1005 Cat 5e Channel (+ALL)', label: 'TIA 1005 Cat 5e Channel (+ALL)' },
|
||||
// // { value: 'TIA 1005 Cat 5e Channel (+PoE)', label: 'TIA 1005 Cat 5e Channel (+PoE)' },
|
||||
// { value: 'TIA 1005 Cat 5e Channel E1 (+ALL)', label: 'TIA 1005 Cat 5e Channel E1 (+ALL)' },
|
||||
// // { value: 'TIA 1005 Cat 5e Channel E1 (+PoE)', label: 'TIA 1005 Cat 5e Channel E1 (+PoE)' },
|
||||
// { value: 'TIA 1005 Cat 5e Channel E2 (+ALL)', label: 'TIA 1005 Cat 5e Channel E2 (+ALL)' },
|
||||
// // { value: 'TIA 1005 Cat 5e Channel E2 (+PoE)', label: 'TIA 1005 Cat 5e Channel E2 (+PoE)' },
|
||||
// { value: 'TIA 1005 Cat 5e Channel E3 (+ALL)', label: 'TIA 1005 Cat 5e Channel E3 (+ALL)' },
|
||||
// // { value: 'TIA 1005 Cat 5e Channel E3 (+PoE)', label: 'TIA 1005 Cat 5e Channel E3 (+PoE)' }
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// value: 'ISO',
|
||||
// label: 'ISO',
|
||||
// children: {
|
||||
// // 'Class Ⅱ': {
|
||||
// // label: 'Class Ⅱ',
|
||||
// // children: [
|
||||
// // { value: 'ISO11801 PL Class Ⅱ', label: 'ISO11801 PL Class Ⅱ' },
|
||||
// // { value: 'ISO11801 PL Class Ⅱ (+ALL)', label: 'ISO11801 PL Class Ⅱ (+ALL)' },
|
||||
// // { value: 'ISO11801 PL Class Ⅱ (+PoE)', label: 'ISO11801 PL Class Ⅱ (+PoE)' },
|
||||
// // { value: 'ISO11801 Channel Class Ⅱ', label: 'ISO11801 Channel Class Ⅱ' },
|
||||
// // { value: 'ISO11801 Channel Class Ⅱ (+ALL)', label: 'ISO11801 Channel Class Ⅱ (+ALL)' },
|
||||
// // { value: 'ISO11801 Channel Class Ⅱ (+PoE)', label: 'ISO11801 Channel Class Ⅱ (+PoE)' }
|
||||
// // ],
|
||||
// // disabled: true
|
||||
// // },
|
||||
// // 'Class Ⅰ': {
|
||||
// // label: 'Class Ⅰ',
|
||||
// // children: [
|
||||
// // { value: 'ISO11801 PL Class Ⅰ', label: 'ISO11801 PL Class Ⅰ' },
|
||||
// // { value: 'ISO11801 PL Class Ⅰ (+ALL)', label: 'ISO11801 PL Class Ⅰ (+ALL)' },
|
||||
// // { value: 'ISO11801 PL Class Ⅰ (+PoE)', label: 'ISO11801 PL Class Ⅰ (+PoE)' },
|
||||
// // { value: 'ISO11801 Channel Class Ⅰ', label: 'ISO11801 Channel Class Ⅰ' },
|
||||
// // { value: 'ISO11801 Channel Class Ⅰ (+ALL)', label: 'ISO11801 Channel Class Ⅰ (+ALL)' },
|
||||
// // { value: 'ISO11801 Channel Class Ⅰ (+PoE)', label: 'ISO11801 Channel Class Ⅰ (+PoE)' }
|
||||
// // ],
|
||||
// // disabled: true
|
||||
// // },
|
||||
// // 'Class Fa': {
|
||||
// // label: 'Class Fa',
|
||||
// // children: [
|
||||
// // { value: 'ISO11801 PL2 Class Fa', label: 'ISO11801 PL2 Class Fa' },
|
||||
// // { value: 'ISO11801 PL2 Class Fa (+ALL)', label: 'ISO11801 PL2 Class Fa (+ALL)' },
|
||||
// // { value: 'ISO11801 PL2 Class Fa (+PoE)', label: 'ISO11801 PL2 Class Fa (+PoE)' },
|
||||
// // { value: 'ISO11801 PL3 Class Fa', label: 'ISO11801 PL3 Class Fa' },
|
||||
// // { value: 'ISO11801 PL3 Class Fa (+ALL)', label: 'ISO11801 PL3 Class Fa (+ALL)' },
|
||||
// // { value: 'ISO11801 PL3 Class Fa (+PoE)', label: 'ISO11801 PL3 Class Fa (+PoE)' },
|
||||
// // { value: 'ISO11801 Channel Class Fa', label: 'ISO11801 Channel Class Fa' },
|
||||
// // { value: 'ISO11801 Channel Class Fa (+ALL)', label: 'ISO11801 Channel Class Fa (+ALL)' },
|
||||
// // { value: 'ISO11801 Channel Class Fa (+PoE)', label: 'ISO11801 Channel Class Fa (+PoE)' }
|
||||
// // ],
|
||||
// // disabled: true
|
||||
// // },
|
||||
// // 'Class F': {
|
||||
// // label: 'Class F',
|
||||
// // children: [
|
||||
// // { value: 'ISO11801 PL Class F', label: 'ISO11801 PL Class F' },
|
||||
// // { value: 'ISO11801 PL Class F (+ALL)', label: 'ISO11801 PL Class F (+ALL)' },
|
||||
// // { value: 'ISO11801 PL Class F (+PoE)', label: 'ISO11801 PL Class F (+PoE)' },
|
||||
// // { value: 'ISO11801 Channel Class F', label: 'ISO11801 Channel Class F' },
|
||||
// // { value: 'ISO11801 Channel Class F (+ALL)', label: 'ISO11801 Channel Class F (+ALL)' },
|
||||
// // { value: 'ISO11801 Channel Class F (+PoE)', label: 'ISO11801 Channel Class F (+PoE)' }
|
||||
// // ],
|
||||
// // disabled: true
|
||||
// // },
|
||||
// 'Class Ea': {
|
||||
// label: 'Class Ea',
|
||||
// children: [
|
||||
// { value: 'ISO11801 PL2 Class Ea', label: 'ISO11801 PL2 Class Ea' },
|
||||
// { value: 'ISO11801 PL2 Class Ea (+ALL)', label: 'ISO11801 PL2 Class Ea (+ALL)' },
|
||||
// { value: 'ISO11801 PL2 Class Ea (+PoE)', label: 'ISO11801 PL2 Class Ea (+PoE)' },
|
||||
// { value: 'ISO11801 PL3 Class Ea', label: 'ISO11801 PL3 Class Ea' },
|
||||
// { value: 'ISO11801 PL3 Class Ea (+ALL)', label: 'ISO11801 PL3 Class Ea (+ALL)' },
|
||||
// { value: 'ISO11801 PL3 Class Ea (+PoE)', label: 'ISO11801 PL3 Class Ea (+PoE)' },
|
||||
// { value: 'ISO11801 Channel Class Ea', label: 'ISO11801 Channel Class Ea' },
|
||||
// { value: 'ISO11801 Channel Class Ea (+ALL)', label: 'ISO11801 Channel Class Ea (+ALL)' },
|
||||
// { value: 'ISO11801 Channel Class Ea (+PoE)', label: 'ISO11801 Channel Class Ea (+PoE)' },
|
||||
// { value: 'ISO MPTL Class Ea', label: 'ISO MPTL Class Ea' },
|
||||
// { value: 'ISO MPTL Class Ea (+PoE)', label: 'ISO MPTL Class Ea (+PoE)' }
|
||||
// ]
|
||||
// },
|
||||
// 'Class E': {
|
||||
// label: 'Class E',
|
||||
// children: [
|
||||
// { value: 'ISO11801 PL Class E', label: 'ISO11801 PL Class E' },
|
||||
// { value: 'ISO11801 PL Class E (+ALL)', label: 'ISO11801 PL Class E (+ALL)' },
|
||||
// { value: 'ISO11801 PL Class E (+PoE)', label: 'ISO11801 PL Class E (+PoE)' },
|
||||
// { value: 'ISO11801 Channel Class E', label: 'ISO11801 Channel Class E' },
|
||||
// { value: 'ISO11801 Channel Class E (+ALL)', label: 'ISO11801 Channel Class E (+ALL)' },
|
||||
// { value: 'ISO11801 Channel Class E (+PoE)', label: 'ISO11801 Channel Class E (+PoE)' },
|
||||
// { value: 'ISO MPTL Class E', label: 'ISO MPTL Class E' },
|
||||
// { value: 'ISO MPTL Class E (+PoE)', label: 'ISO MPTL Class E (+PoE)' }
|
||||
// ]
|
||||
// },
|
||||
// 'Class D': {
|
||||
// label: 'Class D',
|
||||
// children: [
|
||||
// { value: 'ISO11801 PL Class D', label: 'ISO11801 PL Class D' },
|
||||
// { value: 'ISO11801 PL Class D (+ALL)', label: 'ISO11801 PL Class D (+ALL)' },
|
||||
// { value: 'ISO11801 PL Class D (+PoE)', label: 'ISO11801 PL Class D (+PoE)' },
|
||||
// { value: 'ISO11801 Channel Class D', label: 'ISO11801 Channel Class D' },
|
||||
// { value: 'ISO11801 Channel Class D (+ALL)', label: 'ISO11801 Channel Class D (+ALL)' },
|
||||
// { value: 'ISO11801 Channel Class D (+PoE)', label: 'ISO11801 Channel Class D (+PoE)' },
|
||||
// { value: 'ISO MPTL Class D', label: 'ISO MPTL Class D' },
|
||||
// { value: 'ISO MPTL Class D (+PoE)', label: 'ISO MPTL Class D (+PoE)' }
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
{
|
||||
value: 'TIA',
|
||||
label: 'TIA',
|
||||
children: {
|
||||
// Cat8: {
|
||||
// label: 'Cat8',
|
||||
// children: [
|
||||
// { value: 'TIA Cat 8 Perm.Link', label: 'TIA Cat 8 Perm.Link' },
|
||||
// { value: 'TIA Cat 8 Perm.Link (+ALL)', label: 'TIA Cat 8 Perm.Link (+ALL)' },
|
||||
// { value: 'TIA Cat 8 Perm.Link (+PoE)', label: 'TIA Cat 8 Perm.Link (+PoE)' },
|
||||
// { value: 'TIA Cat 8 Channel', label: 'TIA Cat 8 Channel' },
|
||||
// { value: 'TIA Cat 8 Channel (+ALL)', label: 'TIA Cat 8 Channel (+ALL)' },
|
||||
// { value: 'TIA Cat 8 Channel (+PoE)', label: 'TIA Cat 8 Channel (+PoE)' }
|
||||
// ]
|
||||
// },
|
||||
Cat6A: {
|
||||
label: 'Cat6A',
|
||||
children: [
|
||||
{ value: 'TIA Cat 6A Perm.Link', label: 'TIA Cat 6A Perm.Link' },
|
||||
{ value: 'TIA Cat 6A Perm.Link (+ALL)', label: 'TIA Cat 6A Perm.Link (+ALL)' },
|
||||
{ value: 'TIA Cat 6A Perm.Link (+PoE)', label: 'TIA Cat 6A Perm.Link (+PoE)' },
|
||||
{ value: 'TIA Cat 6A Channel', label: 'TIA Cat 6A Channel' },
|
||||
{ value: 'TIA Cat 6A Channel (+ALL)', label: 'TIA Cat 6A Channel (+ALL)' },
|
||||
{ value: 'TIA Cat 6A Channel (+PoE)', label: 'TIA Cat 6A Channel (+PoE)' },
|
||||
{ value: 'TIA Cat 6A MPTL', label: 'TIA Cat 6A MPTL' },
|
||||
{ value: 'TIA Cat 6A MPTL (+PoE)', label: 'TIA Cat 6A MPTL (+PoE)' },
|
||||
// { value: 'TIA 1005 Cat 6A Perm.Link', label: 'TIA 1005 Cat 6A Perm.Link' },
|
||||
// { value: 'TIA 1005 Cat 6A Channel', label: 'TIA 1005 Cat 6A Channel' },
|
||||
{ value: 'TIA 1005 Cat 6A Channel E1 (+ALL)', label: 'TIA 1005 Cat 6A Channel E1 (+ALL)' },
|
||||
// { value: 'TIA 1005 Cat 6A Channel E1 (+PoE)', label: 'TIA 1005 Cat 6A Channel E1 (+PoE)' },
|
||||
{ value: 'TIA 1005 Cat 6A Channel E2 (+ALL)', label: 'TIA 1005 Cat 6A Channel E2 (+ALL)' },
|
||||
// { value: 'TIA 1005 Cat 6A Channel E2 (+PoE)', label: 'TIA 1005 Cat 6A Channel E2 (+PoE)' },
|
||||
{ value: 'TIA 1005 Cat 6A Channel E3 (+ALL)', label: 'TIA 1005 Cat 6A Channel E3 (+ALL)' },
|
||||
// { value: 'TIA 1005 Cat 6A Channel E3 (+PoE)', label: 'TIA 1005 Cat 6A Channel E3 (+PoE)' }
|
||||
]
|
||||
},
|
||||
Cat6: {
|
||||
label: 'Cat6',
|
||||
children: [
|
||||
{ value: 'TIA Cat 6 Perm.Link', label: 'TIA Cat 6 Perm.Link' },
|
||||
{ value: 'TIA Cat 6 Perm.Link (+ALL)', label: 'TIA Cat 6 Perm.Link (+ALL)' },
|
||||
{ value: 'TIA Cat 6 Perm.Link (+PoE)', label: 'TIA Cat 6 Perm.Link (+PoE)' },
|
||||
{ value: 'TIA Cat 6 Channel', label: 'TIA Cat 6 Channel' },
|
||||
{ value: 'TIA Cat 6 Channel (+ALL)', label: 'TIA Cat 6 Channel (+ALL)' },
|
||||
{ value: 'TIA Cat 6 Channel (+PoE)', label: 'TIA Cat 6 Channel (+PoE)' },
|
||||
{ value: 'TIA Cat 6 MPTL', label: 'TIA Cat 6 MPTL' },
|
||||
{ value: 'TIA Cat 6 MPTL (+PoE)', label: 'TIA Cat 6 MPTL (+PoE)' },
|
||||
// { value: 'TIA 1005 Cat 6 Perm.Link', label: 'TIA 1005 Cat 6 Perm.Link' },
|
||||
// { value: 'TIA 1005 Cat 6 Channel', label: 'TIA 1005 Cat 6 Channel' },
|
||||
// { value: 'TIA 1005 Cat 6 Channel (+ALL)', label: 'TIA 1005 Cat 6 Channel (+ALL)' },
|
||||
// { value: 'TIA 1005 Cat 6 Channel (+PoE)', label: 'TIA 1005 Cat 6 Channel (+PoE)' },
|
||||
{ value: 'TIA 1005 Cat 6 Channel E1 (+ALL)', label: 'TIA 1005 Cat 6 Channel E1 (+ALL)' },
|
||||
// { value: 'TIA 1005 Cat 6 Channel E1 (+PoE)', label: 'TIA 1005 Cat 6 Channel E1 (+PoE)' },
|
||||
{ value: 'TIA 1005 Cat 6 Channel E2 (+ALL)', label: 'TIA 1005 Cat 6 Channel E2 (+ALL)' },
|
||||
// { value: 'TIA 1005 Cat 6 Channel E2 (+PoE)', label: 'TIA 1005 Cat 6 Channel E2 (+PoE)' },
|
||||
{ value: 'TIA 1005 Cat 6 Channel E3 (+ALL)', label: 'TIA 1005 Cat 6 Channel E3 (+ALL)' },
|
||||
// { value: 'TIA 1005 Cat 6 Channel E3 (+PoE)', label: 'TIA 1005 Cat 6 Channel E3 (+PoE)' }
|
||||
]
|
||||
},
|
||||
Cat5e: {
|
||||
label: 'Cat5e',
|
||||
children: [
|
||||
{ value: 'TIA Cat 5e Perm.Link', label: 'TIA Cat 5e Perm.Link' },
|
||||
{ value: 'TIA Cat 5e Perm.Link (+ALL)', label: 'TIA Cat 5e Perm.Link (+ALL)' },
|
||||
{ value: 'TIA Cat 5e Perm.Link (+PoE)', label: 'TIA Cat 5e Perm.Link (+PoE)' },
|
||||
{ value: 'TIA Cat 5e Channel', label: 'TIA Cat 5e Channel' },
|
||||
{ value: 'TIA Cat 5e Channel (+ALL)', label: 'TIA Cat 5e Channel (+ALL)' },
|
||||
{ value: 'TIA Cat 5e Channel (+PoE)', label: 'TIA Cat 5e Channel (+PoE)' },
|
||||
{ value: 'TIA Cat 5e MPTL', label: 'TIA Cat 5e MPTL' },
|
||||
{ value: 'TIA Cat 5e MPTL (+PoE)', label: 'TIA Cat 5e MPTL (+PoE)' },
|
||||
// { value: 'TIA 1005 Cat 5e Perm.Link', label: 'TIA 1005 Cat 5e Perm.Link' },
|
||||
// { value: 'TIA 1005 Cat 5e Channel', label: 'TIA 1005 Cat 5e Channel' },
|
||||
// { value: 'TIA 1005 Cat 5e Channel (+ALL)', label: 'TIA 1005 Cat 5e Channel (+ALL)' },
|
||||
// { value: 'TIA 1005 Cat 5e Channel (+PoE)', label: 'TIA 1005 Cat 5e Channel (+PoE)' },
|
||||
{ value: 'TIA 1005 Cat 5e Channel E1 (+ALL)', label: 'TIA 1005 Cat 5e Channel E1 (+ALL)' },
|
||||
// { value: 'TIA 1005 Cat 5e Channel E1 (+PoE)', label: 'TIA 1005 Cat 5e Channel E1 (+PoE)' },
|
||||
{ value: 'TIA 1005 Cat 5e Channel E2 (+ALL)', label: 'TIA 1005 Cat 5e Channel E2 (+ALL)' },
|
||||
// { value: 'TIA 1005 Cat 5e Channel E2 (+PoE)', label: 'TIA 1005 Cat 5e Channel E2 (+PoE)' },
|
||||
{ value: 'TIA 1005 Cat 5e Channel E3 (+ALL)', label: 'TIA 1005 Cat 5e Channel E3 (+ALL)' },
|
||||
// { value: 'TIA 1005 Cat 5e Channel E3 (+PoE)', label: 'TIA 1005 Cat 5e Channel E3 (+PoE)' }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
value: 'ISO',
|
||||
label: 'ISO',
|
||||
children: {
|
||||
// 'Class Ⅱ': {
|
||||
// label: 'Class Ⅱ',
|
||||
// children: [
|
||||
// { value: 'ISO11801 PL Class Ⅱ', label: 'ISO11801 PL Class Ⅱ' },
|
||||
// { value: 'ISO11801 PL Class Ⅱ (+ALL)', label: 'ISO11801 PL Class Ⅱ (+ALL)' },
|
||||
// { value: 'ISO11801 PL Class Ⅱ (+PoE)', label: 'ISO11801 PL Class Ⅱ (+PoE)' },
|
||||
// { value: 'ISO11801 Channel Class Ⅱ', label: 'ISO11801 Channel Class Ⅱ' },
|
||||
// { value: 'ISO11801 Channel Class Ⅱ (+ALL)', label: 'ISO11801 Channel Class Ⅱ (+ALL)' },
|
||||
// { value: 'ISO11801 Channel Class Ⅱ (+PoE)', label: 'ISO11801 Channel Class Ⅱ (+PoE)' }
|
||||
// ],
|
||||
// disabled: true
|
||||
// },
|
||||
// 'Class Ⅰ': {
|
||||
// label: 'Class Ⅰ',
|
||||
// children: [
|
||||
// { value: 'ISO11801 PL Class Ⅰ', label: 'ISO11801 PL Class Ⅰ' },
|
||||
// { value: 'ISO11801 PL Class Ⅰ (+ALL)', label: 'ISO11801 PL Class Ⅰ (+ALL)' },
|
||||
// { value: 'ISO11801 PL Class Ⅰ (+PoE)', label: 'ISO11801 PL Class Ⅰ (+PoE)' },
|
||||
// { value: 'ISO11801 Channel Class Ⅰ', label: 'ISO11801 Channel Class Ⅰ' },
|
||||
// { value: 'ISO11801 Channel Class Ⅰ (+ALL)', label: 'ISO11801 Channel Class Ⅰ (+ALL)' },
|
||||
// { value: 'ISO11801 Channel Class Ⅰ (+PoE)', label: 'ISO11801 Channel Class Ⅰ (+PoE)' }
|
||||
// ],
|
||||
// disabled: true
|
||||
// },
|
||||
// 'Class Fa': {
|
||||
// label: 'Class Fa',
|
||||
// children: [
|
||||
// { value: 'ISO11801 PL2 Class Fa', label: 'ISO11801 PL2 Class Fa' },
|
||||
// { value: 'ISO11801 PL2 Class Fa (+ALL)', label: 'ISO11801 PL2 Class Fa (+ALL)' },
|
||||
// { value: 'ISO11801 PL2 Class Fa (+PoE)', label: 'ISO11801 PL2 Class Fa (+PoE)' },
|
||||
// { value: 'ISO11801 PL3 Class Fa', label: 'ISO11801 PL3 Class Fa' },
|
||||
// { value: 'ISO11801 PL3 Class Fa (+ALL)', label: 'ISO11801 PL3 Class Fa (+ALL)' },
|
||||
// { value: 'ISO11801 PL3 Class Fa (+PoE)', label: 'ISO11801 PL3 Class Fa (+PoE)' },
|
||||
// { value: 'ISO11801 Channel Class Fa', label: 'ISO11801 Channel Class Fa' },
|
||||
// { value: 'ISO11801 Channel Class Fa (+ALL)', label: 'ISO11801 Channel Class Fa (+ALL)' },
|
||||
// { value: 'ISO11801 Channel Class Fa (+PoE)', label: 'ISO11801 Channel Class Fa (+PoE)' }
|
||||
// ],
|
||||
// disabled: true
|
||||
// },
|
||||
// 'Class F': {
|
||||
// label: 'Class F',
|
||||
// children: [
|
||||
// { value: 'ISO11801 PL Class F', label: 'ISO11801 PL Class F' },
|
||||
// { value: 'ISO11801 PL Class F (+ALL)', label: 'ISO11801 PL Class F (+ALL)' },
|
||||
// { value: 'ISO11801 PL Class F (+PoE)', label: 'ISO11801 PL Class F (+PoE)' },
|
||||
// { value: 'ISO11801 Channel Class F', label: 'ISO11801 Channel Class F' },
|
||||
// { value: 'ISO11801 Channel Class F (+ALL)', label: 'ISO11801 Channel Class F (+ALL)' },
|
||||
// { value: 'ISO11801 Channel Class F (+PoE)', label: 'ISO11801 Channel Class F (+PoE)' }
|
||||
// ],
|
||||
// disabled: true
|
||||
// },
|
||||
'Class Ea': {
|
||||
label: 'Class Ea',
|
||||
children: [
|
||||
{ value: 'ISO11801 PL2 Class Ea', label: 'ISO11801 PL2 Class Ea' },
|
||||
{ value: 'ISO11801 PL2 Class Ea (+ALL)', label: 'ISO11801 PL2 Class Ea (+ALL)' },
|
||||
{ value: 'ISO11801 PL2 Class Ea (+PoE)', label: 'ISO11801 PL2 Class Ea (+PoE)' },
|
||||
{ value: 'ISO11801 PL3 Class Ea', label: 'ISO11801 PL3 Class Ea' },
|
||||
{ value: 'ISO11801 PL3 Class Ea (+ALL)', label: 'ISO11801 PL3 Class Ea (+ALL)' },
|
||||
{ value: 'ISO11801 PL3 Class Ea (+PoE)', label: 'ISO11801 PL3 Class Ea (+PoE)' },
|
||||
{ value: 'ISO11801 Channel Class Ea', label: 'ISO11801 Channel Class Ea' },
|
||||
{ value: 'ISO11801 Channel Class Ea (+ALL)', label: 'ISO11801 Channel Class Ea (+ALL)' },
|
||||
{ value: 'ISO11801 Channel Class Ea (+PoE)', label: 'ISO11801 Channel Class Ea (+PoE)' },
|
||||
{ value: 'ISO MPTL Class Ea', label: 'ISO MPTL Class Ea' },
|
||||
{ value: 'ISO MPTL Class Ea (+PoE)', label: 'ISO MPTL Class Ea (+PoE)' }
|
||||
]
|
||||
},
|
||||
'Class E': {
|
||||
label: 'Class E',
|
||||
children: [
|
||||
{ value: 'ISO11801 PL Class E', label: 'ISO11801 PL Class E' },
|
||||
{ value: 'ISO11801 PL Class E (+ALL)', label: 'ISO11801 PL Class E (+ALL)' },
|
||||
{ value: 'ISO11801 PL Class E (+PoE)', label: 'ISO11801 PL Class E (+PoE)' },
|
||||
{ value: 'ISO11801 Channel Class E', label: 'ISO11801 Channel Class E' },
|
||||
{ value: 'ISO11801 Channel Class E (+ALL)', label: 'ISO11801 Channel Class E (+ALL)' },
|
||||
{ value: 'ISO11801 Channel Class E (+PoE)', label: 'ISO11801 Channel Class E (+PoE)' },
|
||||
{ value: 'ISO MPTL Class E', label: 'ISO MPTL Class E' },
|
||||
{ value: 'ISO MPTL Class E (+PoE)', label: 'ISO MPTL Class E (+PoE)' }
|
||||
]
|
||||
},
|
||||
'Class D': {
|
||||
label: 'Class D',
|
||||
children: [
|
||||
{ value: 'ISO11801 PL Class D', label: 'ISO11801 PL Class D' },
|
||||
{ value: 'ISO11801 PL Class D (+ALL)', label: 'ISO11801 PL Class D (+ALL)' },
|
||||
{ value: 'ISO11801 PL Class D (+PoE)', label: 'ISO11801 PL Class D (+PoE)' },
|
||||
{ value: 'ISO11801 Channel Class D', label: 'ISO11801 Channel Class D' },
|
||||
{ value: 'ISO11801 Channel Class D (+ALL)', label: 'ISO11801 Channel Class D (+ALL)' },
|
||||
{ value: 'ISO11801 Channel Class D (+PoE)', label: 'ISO11801 Channel Class D (+PoE)' },
|
||||
{ value: 'ISO MPTL Class D', label: 'ISO MPTL Class D' },
|
||||
{ value: 'ISO MPTL Class D (+PoE)', label: 'ISO MPTL Class D (+PoE)' }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
value: '区域',
|
||||
label: '区域',
|
||||
children: {
|
||||
'中国': {
|
||||
|
||||
value: '中国',
|
||||
label: '中国',
|
||||
children: [
|
||||
// { value: 'GBT 50312-2016 Cat 7A PL no CP', label: 'GB/T 50312-2016 Cat 7A PL no CP' },
|
||||
@@ -273,36 +255,35 @@ const menuData = {
|
||||
{ value: 'GBT 50312-2016 Cat 5e Ch (+ALL)', label: 'GB/T 50312-2016 Cat 5e Ch (+ALL)' },
|
||||
{ value: 'GBT 50312-2016 Cat 5e Ch (+PoE)', label: 'GB/T 50312-2016 Cat 5e Ch (+PoE)' }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
value: '跳线',
|
||||
label: '跳线',
|
||||
disabled: true,
|
||||
children: {
|
||||
'Cat6A Patch Cords': {
|
||||
label: 'Cat6A Patch Cords',
|
||||
disabled: true,
|
||||
children: []
|
||||
},
|
||||
'Cat6 Patch Cords': {
|
||||
label: 'Cat6 Patch Cords',
|
||||
disabled: true,
|
||||
children: []
|
||||
},
|
||||
'Cat5e Patch Cords': {
|
||||
label: 'Cat5e Patch Cords',
|
||||
disabled: true,
|
||||
children: []
|
||||
},
|
||||
'M12 Patch Cords': {
|
||||
label: 'M12 Patch Cords',
|
||||
disabled: true,
|
||||
children: []
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
// {
|
||||
// value: '跳线',
|
||||
// label: '跳线',
|
||||
// disabled: true,
|
||||
// children: {
|
||||
// 'Cat6A Patch Cords': {
|
||||
// label: 'Cat6A Patch Cords',
|
||||
// disabled: true,
|
||||
// children: []
|
||||
// },
|
||||
// 'Cat6 Patch Cords': {
|
||||
// label: 'Cat6 Patch Cords',
|
||||
// disabled: true,
|
||||
// children: []
|
||||
// },
|
||||
// 'Cat5e Patch Cords': {
|
||||
// label: 'Cat5e Patch Cords',
|
||||
// disabled: true,
|
||||
// children: []
|
||||
// },
|
||||
// 'M12 Patch Cords': {
|
||||
// label: 'M12 Patch Cords',
|
||||
// disabled: true,
|
||||
// children: []
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
{
|
||||
value: '应用',
|
||||
label: '应用',
|
||||
@@ -310,7 +291,18 @@ const menuData = {
|
||||
children: [
|
||||
{ value: 'Profinet', label: 'Profinet' },
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
value: '模块化插头',
|
||||
label: '模块化插头',
|
||||
disabled: false,
|
||||
children: [
|
||||
{ value: 'ISO MPTL Class Ea', label: 'ISO MPTL Class Ea' },
|
||||
{ value: 'ISO MPTL Class Ea (+PoE)', label: 'ISO MPTL Class Ea (+PoE)' },
|
||||
{ value: 'ISO MPTL Class E', label: 'ISO MPTL Class E' },
|
||||
{ value: 'ISO MPTL Class E (+PoE)', label: 'ISO MPTL Class E (+PoE)' }
|
||||
]
|
||||
},
|
||||
]
|
||||
},
|
||||
WIRE_ORDER: {
|
||||
@@ -326,16 +318,7 @@ const menuData = {
|
||||
title: '光纤类型',
|
||||
subTitle: '电缆组',
|
||||
items: [
|
||||
{
|
||||
value: '定制',
|
||||
label: '定制',
|
||||
disabled: true,
|
||||
children: {}
|
||||
},
|
||||
{
|
||||
value: 'general',
|
||||
label: '通用',
|
||||
children: [
|
||||
|
||||
{ value: 'OM1 Mulitmode 62.5', label: 'OM1 Mulitmode 62.5' },
|
||||
{ value: 'OM2 Mulitmode 50', label: 'OM2 Mulitmode 50' },
|
||||
{ value: 'OM3 Mulitmode 50', label: 'OM3 Mulitmode 50' },
|
||||
@@ -343,32 +326,26 @@ const menuData = {
|
||||
{ value: 'OM5 Mulitmode 50', label: 'OM5 Mulitmode 50' },
|
||||
{ value: 'OS1 Singlemode', label: 'OS1 Singlemode' },
|
||||
{ value: 'OS2 Singlemode', label: 'OS2 Singlemode' }
|
||||
]
|
||||
},
|
||||
{
|
||||
value: '制造商',
|
||||
label: '制造商',
|
||||
disabled: true,
|
||||
children: {}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
]
|
||||
},
|
||||
|
||||
CFP_LIMIT: {
|
||||
title: '测试极限值',
|
||||
subTitle: '极限值组',
|
||||
items: [
|
||||
{
|
||||
value: 'TIA',
|
||||
label: 'TIA',
|
||||
children: [
|
||||
{ value: 'TIA-568.3-E Multimode (STD)', label: 'TIA-568.3-E Multimode (STD)' },
|
||||
{ value: 'TIA-568.3-E Multimode (REF)', label: 'TIA-568.3-E Multimode (REF)' },
|
||||
{ value: 'TIA-568.3-E Singlemode ISP (STD)', label: 'TIA-568.3-E Singlemode ISP (STD)' },
|
||||
{ value: 'TIA-568.3-E Singlemode OSP (STD)', label: 'TIA-568.3-E Singlemode OSP (STD)' },
|
||||
{ value: 'TIA-568.3-E Singlemode ISP (REF)', label: 'TIA-568.3-E Singlemode ISP (REF)' },
|
||||
{ value: 'TIA-568.3-E Singlemode OSP (REF)', label: 'TIA-568.3-E Singlemode OSP (REF)' }
|
||||
]
|
||||
},
|
||||
// {
|
||||
// value: 'TIA',
|
||||
// label: 'TIA',
|
||||
// children: [
|
||||
// { value: 'TIA-568.3-E Multimode (STD)', label: 'TIA-568.3-E Multimode (STD)' },
|
||||
// { value: 'TIA-568.3-E Multimode (REF)', label: 'TIA-568.3-E Multimode (REF)' },
|
||||
// { value: 'TIA-568.3-E Singlemode ISP (STD)', label: 'TIA-568.3-E Singlemode ISP (STD)' },
|
||||
// { value: 'TIA-568.3-E Singlemode OSP (STD)', label: 'TIA-568.3-E Singlemode OSP (STD)' },
|
||||
// { value: 'TIA-568.3-E Singlemode ISP (REF)', label: 'TIA-568.3-E Singlemode ISP (REF)' },
|
||||
// { value: 'TIA-568.3-E Singlemode OSP (REF)', label: 'TIA-568.3-E Singlemode OSP (REF)' }
|
||||
// ]
|
||||
// },
|
||||
{
|
||||
value: 'China',
|
||||
label: '中国',
|
||||
@@ -379,34 +356,34 @@ const menuData = {
|
||||
{ value: 'GB/T 50312-2016 OF-2000 Ch', label: 'GB/T 50312-2016 OF-2000 Ch' }
|
||||
]
|
||||
},
|
||||
{
|
||||
value: 'ISO',
|
||||
label: 'ISO',
|
||||
children: [
|
||||
{ value: 'ISO/IEC 11801-2002 Fibre Link', label: 'ISO/IEC 11801-2002 Fibre Link' },
|
||||
{ value: 'ISO/IEC 11801-2002 OF-300 CH', label: 'ISO/IEC 11801-2002 OF-300 CH' },
|
||||
{ value: 'ISO/IEC 11801-2002 OF-500 CH', label: 'ISO/IEC 11801-2002 OF-500 CH' },
|
||||
{ value: 'ISO/IEC 11801-2002 OF-2000 CH', label: 'ISO/IEC 11801-2002 OF-2000 CH' },
|
||||
{ value: 'ISO/IEC 14763-3:2024 (Draft)', label: 'ISO/IEC 14763-3:2024 (Draft)' },
|
||||
{ value: 'ISO/IEC 14763-3:2014', label: 'ISO/IEC 14763-3:2014' },
|
||||
{ value: 'ISO/IEC 14763-3', label: 'ISO/IEC 14763-3' }
|
||||
]
|
||||
}
|
||||
// {
|
||||
// value: 'ISO',
|
||||
// label: 'ISO',
|
||||
// children: [
|
||||
// { value: 'ISO/IEC 11801-2002 Fibre Link', label: 'ISO/IEC 11801-2002 Fibre Link' },
|
||||
// { value: 'ISO/IEC 11801-2002 OF-300 CH', label: 'ISO/IEC 11801-2002 OF-300 CH' },
|
||||
// { value: 'ISO/IEC 11801-2002 OF-500 CH', label: 'ISO/IEC 11801-2002 OF-500 CH' },
|
||||
// { value: 'ISO/IEC 11801-2002 OF-2000 CH', label: 'ISO/IEC 11801-2002 OF-2000 CH' },
|
||||
// { value: 'ISO/IEC 14763-3:2024 (Draft)', label: 'ISO/IEC 14763-3:2024 (Draft)' },
|
||||
// { value: 'ISO/IEC 14763-3:2014', label: 'ISO/IEC 14763-3:2014' },
|
||||
// { value: 'ISO/IEC 14763-3', label: 'ISO/IEC 14763-3' }
|
||||
// ]
|
||||
// }
|
||||
]
|
||||
},
|
||||
OFP_LIMIT: {
|
||||
title: 'OFP极限值',
|
||||
items: [
|
||||
{
|
||||
value: 'TIA',
|
||||
label: 'TIA',
|
||||
children: [
|
||||
{ value: 'ANSI/TIA-568.3-E', label: 'ANSI/TIA-568.3-E' },
|
||||
{ value: 'ANSI/TIA-568.3-E RL = 20 dB', label: 'ANSI/TIA-568.3-E RL = 20 dB' },
|
||||
{ value: 'ANSI/TIA-568.3-E RL = 35 dB', label: 'ANSI/TIA-568.3-E RL = 35 dB' },
|
||||
{ value: 'ANSI/TIA-568.3-E RL = 55 dB', label: 'ANSI/TIA-568.3-E RL = 55 dB' }
|
||||
]
|
||||
},
|
||||
// {
|
||||
// value: 'TIA',
|
||||
// label: 'TIA',
|
||||
// children: [
|
||||
// { value: 'ANSI/TIA-568.3-E', label: 'ANSI/TIA-568.3-E' },
|
||||
// { value: 'ANSI/TIA-568.3-E RL = 20 dB', label: 'ANSI/TIA-568.3-E RL = 20 dB' },
|
||||
// { value: 'ANSI/TIA-568.3-E RL = 35 dB', label: 'ANSI/TIA-568.3-E RL = 35 dB' },
|
||||
// { value: 'ANSI/TIA-568.3-E RL = 55 dB', label: 'ANSI/TIA-568.3-E RL = 55 dB' }
|
||||
// ]
|
||||
// },
|
||||
{
|
||||
value: 'China',
|
||||
label: '中国',
|
||||
@@ -417,22 +394,22 @@ const menuData = {
|
||||
{ value: 'GB/T 50312-2016 OF-2000 Ch', label: 'GB/T 50312-2016 OF-2000 Ch' }
|
||||
]
|
||||
},
|
||||
{
|
||||
value: 'ISO',
|
||||
label: 'ISO',
|
||||
children: [
|
||||
{ value: 'ISO/IEC 11801-2002 Fibre Link', label: 'ISO/IEC 11801-2002 Fibre Link' },
|
||||
{ value: 'ISO/IEC 11801-2002 OF-300 CH', label: 'ISO/IEC 11801-2002 OF-300 CH' },
|
||||
{ value: 'ISO/IEC 11801-2002 OF-500 CH', label: 'ISO/IEC 11801-2002 OF-500 CH' },
|
||||
{ value: 'ISO/IEC 11801-2002 OF-2000 CH', label: 'ISO/IEC 11801-2002 OF-2000 CH' },
|
||||
{ value: 'ISO/IEC 14763-3:2024 (Draft)', label: 'ISO/IEC 14763-3:2024 (Draft)' },
|
||||
{ value: 'ISO/IEC 14763-3:2024 RL = 20 (Draft)', label: 'ISO/IEC 14763-3:2024 RL = 20 (Draft)' },
|
||||
{ value: 'ISO/IEC 14763-3:2024 RL = 35 (Draft)', label: 'ISO/IEC 14763-3:2024 RL = 35 (Draft)' },
|
||||
{ value: 'ISO/IEC 14763-3:2024 RL = 60 (Draft)', label: 'ISO/IEC 14763-3:2024 RL = 60 (Draft)' },
|
||||
{ value: 'ISO/IEC 14763-3:2014', label: 'ISO/IEC 14763-3:2014' },
|
||||
{ value: 'ISO/IEC 14763-3', label: 'ISO/IEC 14763-3' }
|
||||
]
|
||||
}
|
||||
// {
|
||||
// value: 'ISO',
|
||||
// label: 'ISO',
|
||||
// children: [
|
||||
// { value: 'ISO/IEC 11801-2002 Fibre Link', label: 'ISO/IEC 11801-2002 Fibre Link' },
|
||||
// { value: 'ISO/IEC 11801-2002 OF-300 CH', label: 'ISO/IEC 11801-2002 OF-300 CH' },
|
||||
// { value: 'ISO/IEC 11801-2002 OF-500 CH', label: 'ISO/IEC 11801-2002 OF-500 CH' },
|
||||
// { value: 'ISO/IEC 11801-2002 OF-2000 CH', label: 'ISO/IEC 11801-2002 OF-2000 CH' },
|
||||
// { value: 'ISO/IEC 14763-3:2024 (Draft)', label: 'ISO/IEC 14763-3:2024 (Draft)' },
|
||||
// { value: 'ISO/IEC 14763-3:2024 RL = 20 (Draft)', label: 'ISO/IEC 14763-3:2024 RL = 20 (Draft)' },
|
||||
// { value: 'ISO/IEC 14763-3:2024 RL = 35 (Draft)', label: 'ISO/IEC 14763-3:2024 RL = 35 (Draft)' },
|
||||
// { value: 'ISO/IEC 14763-3:2024 RL = 60 (Draft)', label: 'ISO/IEC 14763-3:2024 RL = 60 (Draft)' },
|
||||
// { value: 'ISO/IEC 14763-3:2014', label: 'ISO/IEC 14763-3:2014' },
|
||||
// { value: 'ISO/IEC 14763-3', label: 'ISO/IEC 14763-3' }
|
||||
// ]
|
||||
// }
|
||||
]
|
||||
}
|
||||
};
|
||||
@@ -490,9 +467,9 @@ export default function MenuList() {
|
||||
updatedConfig.params.cableType = item.value;
|
||||
if (updatedConfig.moduleType === 'cfp') {
|
||||
if (item.value.includes('OM')) {
|
||||
updatedConfig.params.limitValue = 'TIA-568.3-E Multimode (STD)';
|
||||
updatedConfig.params.limitValue = 'GB/T 50312-2016 Fiber Link';
|
||||
} else {
|
||||
updatedConfig.params.limitValue = 'TIA-568.3-E Singlemode ISP (STD)';
|
||||
updatedConfig.params.limitValue = 'GB/T 50312-2016 Fiber Link';
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -512,7 +489,7 @@ export default function MenuList() {
|
||||
moduleType: '8000',
|
||||
modulelable: '铜缆测试仪',
|
||||
params: {
|
||||
limitValue: 'TIA Cat 6 Channel',
|
||||
limitValue: 'GBT 50312-2016 Cat 6 Ch',
|
||||
cableType: 'Cat6 U/UTP',
|
||||
wireOrder: 'T568B'
|
||||
}
|
||||
@@ -524,7 +501,7 @@ export default function MenuList() {
|
||||
moduleType: 'cfp',
|
||||
modulelable: '光损耗测试仪',
|
||||
params: {
|
||||
limitValue: 'TIA-568.3-E Multimode (STD)',
|
||||
limitValue: 'GB/T 50312-2016 Fiber Link',
|
||||
cableType: 'OM3 Multimode 50',
|
||||
refJumper: '1',
|
||||
spliceCount: '0',
|
||||
@@ -538,7 +515,7 @@ export default function MenuList() {
|
||||
moduleType: 'ofp',
|
||||
modulelable: 'OTDR测试仪',
|
||||
params: {
|
||||
limitValue: 'General Fiber RL = 35 dB',
|
||||
limitValue: 'GB/T 50312-2016 Fiber Link',
|
||||
cableType: 'OM3 Multimode 50'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@ import SubTitleBar from '@/components/lib//SubTitleBar';
|
||||
import Keyboard from '@/components/lib//Keyboard';
|
||||
import useDisplayStore from '@/store/displayStore';
|
||||
import { getAssetUrl } from '@/utils/asset';
|
||||
import { UserIcon, TagIcon, ChartBarIcon, SwatchIcon } from '@heroicons/react/24/solid';
|
||||
|
||||
export default function Project() {
|
||||
const [inputValue, setInputValue] = useState('');
|
||||
@@ -238,7 +239,7 @@ export default function Project() {
|
||||
moduleType: '8000',
|
||||
modulelable: '铜缆测试仪',
|
||||
params: {
|
||||
limitValue: 'TIA Cat 6 Channel',
|
||||
limitValue: 'GBT 50312-2016 Cat 6 Ch',
|
||||
cableType: 'Cat6 U/UTP',
|
||||
wireOrder: 'T568B'
|
||||
}
|
||||
@@ -284,224 +285,211 @@ export default function Project() {
|
||||
case 'main':
|
||||
default:
|
||||
return (
|
||||
<div className="flex-1 bg-[#D5DFEB] p-4 space-y-4">
|
||||
{/* 操作员信息 */}
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('operators', 'main')}
|
||||
<div className="flex-1 bg-[#D5DFEB] p-4 flex gap-4 overflow-hidden">
|
||||
{/* 左侧区域:操作员、结果命名、结果统计 */}
|
||||
<div className="w-1/3 flex flex-col gap-2 overflow-y-auto">
|
||||
{/* 操作员信息 */}
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm text-black flex items-center gap-1"><UserIcon className="w-4 h-4 text-black" /> 操作人员</span>
|
||||
</div>
|
||||
<div
|
||||
className="h-[70px] bg-[#F8F6F7] rounded-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('operators', 'main')}
|
||||
>
|
||||
<div className="text-black text-sm"> {currentProject?.operators[useDisplayStore.getState().selectedIndexes.operatorIndex]?.name}</div>
|
||||
|
||||
</div>
|
||||
|
||||
{/* 结果命名 */}
|
||||
<div className="space-y-1">
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm text-black flex items-center gap-1"><TagIcon className="w-4 h-4 text-black" /> 下一条记录</span>
|
||||
</div>
|
||||
<div
|
||||
className="h-[70px] bg-[#F8F6F7] rounded-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('cableId', 'main')}
|
||||
>
|
||||
<div className="text-black text-sm">操作员: {currentProject?.operators[useDisplayStore.getState().selectedIndexes.operatorIndex]?.name}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image
|
||||
src={getAssetUrl('/arrow.png')}
|
||||
alt="箭头"
|
||||
fill
|
||||
className="object-contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 结果统计 */}
|
||||
<div className="space-y-1">
|
||||
<div className="text-sm text-gray-400">
|
||||
结果 {currentProject?.testResults[0]?.date} - {currentProject?.testResults[currentProject.testResults.length - 1]?.date}
|
||||
</div>
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('result', 'main')}
|
||||
>
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="flex items-center gap-1">
|
||||
<span className="text-green-500">{passCount|| 0}</span>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image
|
||||
src={getAssetUrl('/pass.png')}
|
||||
alt="通过"
|
||||
sizes={"auto"}
|
||||
fill
|
||||
className="object-contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
<span className="text-red-500">{failCount|| 0}</span>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image
|
||||
src={getAssetUrl('/fail.png')}
|
||||
alt="失败"
|
||||
sizes={"auto"}
|
||||
fill
|
||||
className="object-contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-black text-sm">
|
||||
{currentProject?.cableIds?.[0]?.name || '001'}
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image
|
||||
src={getAssetUrl('/arrow.png')}
|
||||
alt="箭头"
|
||||
fill
|
||||
className="object-contain"
|
||||
/>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 测试设置 */}
|
||||
<div className="space-y-1 flex-1 overflow-hidden">
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm text-gray-400">测试设置</span>
|
||||
<button
|
||||
className="bg-[#404040] text-white px-3 py-1 rounded-sm text-sm"
|
||||
onClick={() => {
|
||||
// 生成唯一ID
|
||||
const generateId = () => Math.random().toString(36).substr(2, 9);
|
||||
|
||||
// 创建新的测试配置
|
||||
const newConfig = {
|
||||
id: generateId(),
|
||||
name: '新测试配置',
|
||||
moduleType: '8000',
|
||||
modulelable: '铜缆测试仪',
|
||||
params: {
|
||||
limitValue: 'TIA Cat 6 Channel',
|
||||
cableType: 'Cat6 U/UTP',
|
||||
wireOrder: 'T568B',
|
||||
refJumper: '1',
|
||||
spliceCount: '0',
|
||||
connectorCount: '2'
|
||||
}
|
||||
};
|
||||
|
||||
// 更新项目,添加新的测试配置
|
||||
const currentProjectIndex = useDisplayStore.getState().selectedIndexes.projectIndex;
|
||||
const updatedProject = {
|
||||
...currentProject,
|
||||
testConfigs: [...currentProject.testConfigs, newConfig]
|
||||
};
|
||||
updateProject(currentProjectIndex, updatedProject);
|
||||
|
||||
// 设置新配置为选中状态
|
||||
const newConfigIndex = updatedProject.testConfigs.length - 1;
|
||||
setSelectedIndexes({ testConfigIndex: newConfigIndex });
|
||||
|
||||
// 跳转到测试配置页面并进入编辑视图
|
||||
navigateTo('testConfig', 'setup');
|
||||
}}
|
||||
>
|
||||
新测试
|
||||
</button>
|
||||
</div>
|
||||
<div className="h-[100px] overflow-y-auto space-y-2 pr-2">
|
||||
{currentProject?.testConfigs.map((config, index) => (
|
||||
<div
|
||||
key={config.id}
|
||||
className="h-[100px] bg-[#F8F6F7] rounded-sm p-4 shadow-lg cursor-pointer"
|
||||
onClick={() => navigateTo('testConfig', 'main')}
|
||||
>
|
||||
<div className="flex justify-between">
|
||||
<div className="space-y-0.2">
|
||||
{config.moduleType === '8000' && (
|
||||
<>
|
||||
<div className="text-black text-sm">{config.params.limitValue}</div>
|
||||
<div className="text-black text-sm">{config.params.cableType}</div>
|
||||
<div className="text-black text-sm">{config.params.wireOrder}</div>
|
||||
</>
|
||||
)}
|
||||
{config.moduleType === 'cfp' && (
|
||||
<>
|
||||
<div className="text-black text-sm">智能远端</div>
|
||||
<div className="text-black text-sm">{config.params.limitValue}</div>
|
||||
<div className="text-black text-sm">{config.params.cableType}</div>
|
||||
<div className="text-black text-sm">{config.params.refJumper} 跳线参照</div>
|
||||
</>
|
||||
)}
|
||||
{config.moduleType === 'ofp' && (
|
||||
<>
|
||||
<div className="text-black text-sm">自动OTDR</div>
|
||||
<div className="text-black text-sm">{config.params.limitValue}</div>
|
||||
<div className="text-black text-sm">{config.params.cableType}</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-col items-end justify-between">
|
||||
<span className="text-gray-500 text-sm">{config.modulelable}</span>
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
className="w-6 h-6 bg-[#404040] rounded-sm flex items-center justify-center"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation(); // 阻止事件冒泡
|
||||
const currentProjectIndex = useDisplayStore.getState().selectedIndexes.projectIndex;
|
||||
const currentTestConfigIndex = useDisplayStore.getState().selectedIndexes.testConfigIndex;
|
||||
const selectedConfigId = currentProject.testConfigs[currentTestConfigIndex]?.id;
|
||||
|
||||
// 禁止删除最后一项配置
|
||||
if (currentProject.testConfigs.length <= 1) {
|
||||
setToastMessage('不能删除最后一项配置');
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新项目,删除选中的测试配置
|
||||
const updatedProject = {
|
||||
...currentProject,
|
||||
testConfigs: currentProject.testConfigs.filter(
|
||||
testConfig => testConfig.id !== config.id
|
||||
)
|
||||
};
|
||||
updateProject(currentProjectIndex, updatedProject);
|
||||
|
||||
// 更新选中索引
|
||||
const newIndex = updatedProject.testConfigs.findIndex(
|
||||
testConfig => testConfig.id === selectedConfigId
|
||||
);
|
||||
|
||||
// 如果删除的是当前选中的配置,或者找不到选中的配置ID,则设置索引为0
|
||||
setSelectedIndexes({
|
||||
testConfigIndex: newIndex === -1 ? 0 : newIndex
|
||||
});
|
||||
}}
|
||||
>
|
||||
<div className="w-4 h-4 relative">
|
||||
{/* 结果统计 */}
|
||||
<div className="space-y-1">
|
||||
<div className="text-sm text-black flex items-center gap-1 ">
|
||||
<ChartBarIcon className="w-4 h-4 text-black" /> 结果统计 {currentProject?.testResults[0]?.date} - {currentProject?.testResults[currentProject.testResults.length - 1]?.date}
|
||||
</div>
|
||||
<div
|
||||
className="h-[70px] bg-[#F8F6F7] rounded-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('result', 'main')}
|
||||
>
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="flex items-center gap-1">
|
||||
<span className="text-green-500">{passCount|| 0}</span>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image
|
||||
src={getAssetUrl('/delete.png')}
|
||||
alt="删除"
|
||||
src={getAssetUrl('/pass.png')}
|
||||
alt="通过"
|
||||
sizes={"auto"}
|
||||
fill
|
||||
className="object-contain"
|
||||
/>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
<span className="text-red-500">{failCount|| 0}</span>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image
|
||||
src={getAssetUrl('/fail.png')}
|
||||
alt="失败"
|
||||
sizes={"auto"}
|
||||
fill
|
||||
className="object-contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 电缆ID集 */}
|
||||
<div className="space-y-1">
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm text-gray-400">电缆ID集</span>
|
||||
</div>
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('cableId', 'main')}
|
||||
{/* 右侧区域:测试设置 */}
|
||||
<div className="w-2/3 flex flex-col h-full overflow-hidden">
|
||||
<div className="space-y-1 flex-1 flex flex-col overflow-hidden">
|
||||
<div className="flex justify-between items-center shrink-0">
|
||||
<span className="text-sm text-black flex items-center gap-1"><SwatchIcon className="w-4 h-4 text-black" /> 测试设置</span>
|
||||
</div>
|
||||
<div className="flex-1 overflow-y-auto space-y-2 pr-2 mt-1">
|
||||
{currentProject?.testConfigs.map((config, index) => (
|
||||
<div
|
||||
key={config.id}
|
||||
className="h-[90px] bg-[#F8F6F7] rounded-sm p-4 shadow-lg cursor-pointer"
|
||||
onClick={() => navigateTo('testConfig', 'main')}
|
||||
>
|
||||
<div className="flex justify-between">
|
||||
<div className="space-y-0.2">
|
||||
{config.moduleType === '8000' && (
|
||||
<>
|
||||
<div className="text-black text-xs">{config.params.limitValue}</div>
|
||||
<div className="text-black text-xs">{config.params.cableType}</div>
|
||||
<div className="text-black text-xs">{config.params.wireOrder}</div>
|
||||
</>
|
||||
)}
|
||||
{config.moduleType === 'cfp' && (
|
||||
<>
|
||||
<div className="text-black text-xs">光纤损耗测试</div>
|
||||
<div className="text-black text-xs">{config.params.limitValue}</div>
|
||||
<div className="text-black text-xs">{config.params.cableType}</div>
|
||||
<div className="text-black text-xs">{config.params.refJumper} 跳线参照</div>
|
||||
</>
|
||||
)}
|
||||
{config.moduleType === 'ofp' && (
|
||||
<>
|
||||
<div className="text-black text-xs">自动OTDR</div>
|
||||
<div className="text-black text-xs">{config.params.limitValue}</div>
|
||||
<div className="text-black text-xs">{config.params.cableType}</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-col items-end justify-between">
|
||||
<span className="text-gray-500 text-[0.65rem]">{config.modulelable}</span>
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
className="w-6 h-6 bg-[#404040] rounded-sm flex items-center justify-center"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation(); // 阻止事件冒泡
|
||||
const currentProjectIndex = useDisplayStore.getState().selectedIndexes.projectIndex;
|
||||
const currentTestConfigIndex = useDisplayStore.getState().selectedIndexes.testConfigIndex;
|
||||
const selectedConfigId = currentProject.testConfigs[currentTestConfigIndex]?.id;
|
||||
|
||||
// 禁止删除最后一项配置
|
||||
if (currentProject.testConfigs.length <= 1) {
|
||||
setToastMessage('不能删除最后一项配置');
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新项目,删除选中的测试配置
|
||||
const updatedProject = {
|
||||
...currentProject,
|
||||
testConfigs: currentProject.testConfigs.filter(
|
||||
testConfig => testConfig.id !== config.id
|
||||
)
|
||||
};
|
||||
updateProject(currentProjectIndex, updatedProject);
|
||||
|
||||
// 更新选中索引
|
||||
const newIndex = updatedProject.testConfigs.findIndex(
|
||||
testConfig => testConfig.id === selectedConfigId
|
||||
);
|
||||
|
||||
// 如果删除的是当前选中的配置,或者找不到选中的配置ID,则设置索引为0
|
||||
setSelectedIndexes({
|
||||
testConfigIndex: newIndex === -1 ? 0 : newIndex
|
||||
});
|
||||
}}
|
||||
>
|
||||
<div className="w-4 h-4 relative">
|
||||
<Image
|
||||
src={getAssetUrl('/delete.png')}
|
||||
alt="删除"
|
||||
fill
|
||||
className="object-contain"
|
||||
/>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<button
|
||||
className="bg-[#404040] text-white px-3 py-1 rounded-sm text-sm "
|
||||
onClick={() => {
|
||||
// 生成唯一ID
|
||||
const generateId = () => Math.random().toString(36).substr(2, 9);
|
||||
|
||||
// 创建新的测试配置
|
||||
const newConfig = {
|
||||
id: generateId(),
|
||||
name: '新测试配置',
|
||||
moduleType: '8000',
|
||||
modulelable: '铜缆测试仪',
|
||||
params: {
|
||||
limitValue: 'GBT 50312-2016 Cat 6 Ch',
|
||||
cableType: 'Cat6 U/UTP',
|
||||
wireOrder: 'T568B',
|
||||
refJumper: '1',
|
||||
spliceCount: '0',
|
||||
connectorCount: '2'
|
||||
}
|
||||
};
|
||||
|
||||
// 更新项目,添加新的测试配置
|
||||
const currentProjectIndex = useDisplayStore.getState().selectedIndexes.projectIndex;
|
||||
const updatedProject = {
|
||||
...currentProject,
|
||||
testConfigs: [...currentProject.testConfigs, newConfig]
|
||||
};
|
||||
updateProject(currentProjectIndex, updatedProject);
|
||||
|
||||
// 设置新配置为选中状态
|
||||
const newConfigIndex = updatedProject.testConfigs.length - 1;
|
||||
setSelectedIndexes({ testConfigIndex: newConfigIndex });
|
||||
|
||||
// 跳转到测试配置页面并进入编辑视图
|
||||
navigateTo('testConfig', 'setup');
|
||||
}}
|
||||
>
|
||||
<div className="text-black text-sm">
|
||||
下一个ID: {currentProject?.cableIds?.[0]?.name || '001'}
|
||||
</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image
|
||||
src={getAssetUrl('/arrow.png')}
|
||||
alt="箭头"
|
||||
fill
|
||||
className="object-contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
新测试
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -627,4 +615,4 @@ export default function Project() {
|
||||
{renderFooter()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import useDisplayStore from '@/store/displayStore';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import MenuList from './MenuList.js';
|
||||
import { getAssetUrl } from '@/utils/asset';
|
||||
import { TagIcon, SwatchIcon, Bars3Icon, SignalIcon } from '@heroicons/react/24/solid';
|
||||
|
||||
|
||||
|
||||
@@ -90,7 +91,7 @@ export default function TestConfig() {
|
||||
)}
|
||||
{config.moduleType === 'cfp' && (
|
||||
<>
|
||||
<div className="text-black text-sm">智能远端</div>
|
||||
<div className="text-black text-sm">光纤损耗测试</div>
|
||||
<div className="text-black text-sm">{config.params.limitValue}</div>
|
||||
<div className="text-black text-sm">{config.params.cableType}</div>
|
||||
<div className="text-black text-sm">{config.params.refJumper} 跳线参照</div>
|
||||
@@ -136,29 +137,35 @@ export default function TestConfig() {
|
||||
<div className="space-y-2">
|
||||
<div className="space-y-0">
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-t-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('menulist', 'setup', {
|
||||
menuType: 'CABLE_TYPE',
|
||||
selectedConfigId: selectedConfigId,
|
||||
backTo: 'testconfig',
|
||||
backView: 'setup'
|
||||
})}
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-t-sm p-4 shadow-lg flex justify-between items-center"
|
||||
|
||||
>
|
||||
<div className="text-black text-l font-bold">电缆类型:{currentConfig.params.cableType}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
<div className="text-black text-l font-bold flex items-center gap-1"><TagIcon className="w-4 h-4 text-black" /> 电缆类型</div>
|
||||
</div>
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] rounded-b-sm p-4 shadow-lg flex justify-between items-center">
|
||||
<div className="text-black text-l">NVP:根据电缆类型生成</div>
|
||||
<div
|
||||
className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] rounded-b-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('menulist', 'setup', {
|
||||
menuType: 'CABLE_TYPE',
|
||||
selectedConfigId: selectedConfigId,
|
||||
backTo: 'testconfig',
|
||||
backView: 'setup'
|
||||
})}
|
||||
>
|
||||
|
||||
<div className="text-black text-l">{currentConfig.params.cableType}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-0">
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-t-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-t-sm p-4 shadow-lg flex justify-between items-center"
|
||||
>
|
||||
<div className="text-black text-l font-bold flex items-center gap-1"><SwatchIcon className="w-4 h-4 text-black" /> 测试极限值</div>
|
||||
</div>
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] rounded-b-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('menulist', 'setup', {
|
||||
menuType: 'LIMIT_VALUE',
|
||||
selectedConfigId: selectedConfigId,
|
||||
@@ -166,74 +173,72 @@ export default function TestConfig() {
|
||||
backView: 'setup'
|
||||
})}
|
||||
>
|
||||
<div className="text-black text-l font-bold">测试极限值:{currentConfig.params.limitValue}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] p-4 shadow-lg flex justify-between items-center">
|
||||
<div className="text-black text-l">存储测试数据:开</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] rounded-b-sm p-4 shadow-lg flex justify-between items-center">
|
||||
<div className="text-black text-l">TDR/TDX:仅失败</div>
|
||||
<div className="text-black text-l">{currentConfig.params.limitValue}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('menulist', 'setup', {
|
||||
menuType: 'WIRE_ORDER',
|
||||
selectedConfigId: selectedConfigId,
|
||||
backTo: 'testconfig',
|
||||
backView: 'setup'
|
||||
})}
|
||||
>
|
||||
<div className="text-black text-l font-bold">插座配置:{currentConfig.params.wireOrder}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
|
||||
<div className="space-y-0">
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-t-sm p-4 shadow-lg flex justify-between items-center"
|
||||
>
|
||||
<div className="text-black text-l font-bold flex items-center gap-1"><Bars3Icon className="w-4 h-4 text-black" /> 线缆线序</div>
|
||||
</div>
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] rounded-b-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('menulist', 'setup', {
|
||||
menuType: 'WIRE_ORDER',
|
||||
selectedConfigId: selectedConfigId,
|
||||
backTo: 'testconfig',
|
||||
backView: 'setup'
|
||||
})}
|
||||
>
|
||||
<div className="text-black text-l">{currentConfig.params.wireOrder}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
);
|
||||
case 'cfp':
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
|
||||
<div className="space-y-0">
|
||||
<div className="h-[50px] bg-[#F8F6F7] rounded-t-sm p-4 shadow-lg flex justify-between items-center">
|
||||
<div className="text-black text-l font-bold">测试类型:智能远端</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-t-sm p-4 shadow-lg flex justify-between items-center"
|
||||
>
|
||||
<div className="text-black text-l font-bold flex items-center gap-1"><TagIcon className="w-4 h-4 text-black" /> 光纤类型</div>
|
||||
</div>
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] rounded-b-sm p-4 shadow-lg flex justify-between items-center">
|
||||
<div className="text-black text-l">双向:关</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] rounded-b-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('menulist', 'setup', {
|
||||
menuType: 'FIBER_TYPE',
|
||||
selectedConfigId: selectedConfigId,
|
||||
backTo: 'testconfig',
|
||||
backView: 'setup'
|
||||
})}
|
||||
>
|
||||
<div className="text-black text-l font-bold">光纤类型:{currentConfig.params.cableType}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
>
|
||||
<div className="text-black text-l">{currentConfig.params.cableType}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div className="space-y-0">
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-t-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-t-sm p-4 shadow-lg flex justify-between items-center "
|
||||
>
|
||||
<div className="text-black text-l font-bold flex items-center gap-1"><SwatchIcon className="w-4 h-4 text黑色" /> 测试极限值</div>
|
||||
</div>
|
||||
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] p-4 shadow-lg flex justify-between items-center cursor-pointer "
|
||||
onClick={() => navigateTo('menulist', 'setup', {
|
||||
menuType: 'CFP_LIMIT',
|
||||
selectedConfigId: selectedConfigId,
|
||||
@@ -241,29 +246,31 @@ export default function TestConfig() {
|
||||
backView: 'setup'
|
||||
})}
|
||||
>
|
||||
<div className="text-black text-l font-bold">测试极限值:{currentConfig.params.limitValue}</div>
|
||||
<div className="text-black text-l" >{currentConfig.params.limitValue}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] p-4 shadow-lg flex justify-between items-center">
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] p-4 shadow-lg flex justify-between items-center cursor-pointer " onClick={() => updateCurrentView('cfp-conunt')}>
|
||||
<div className="text-black text-l ">参照方法:{currentConfig.params.refJumper} 跳线</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] p-4 shadow-lg flex justify-between items-center">
|
||||
<div className="text-black text-l">连接器类型:LC</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] p-4 shadow-lg flex justify-between items-center cursor-pointer " onClick={() => updateCurrentView('cfp-conunt')}>
|
||||
<div className="text-black text-l ">连接器的数量:{currentConfig.params.connectorCount}个</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] rounded-b-sm p-4 shadow-lg flex justify-between items-center cursor-pointer " onClick={() => updateCurrentView('cfp-conunt')}>
|
||||
<div className="text-black text-l" >接线/接头的数量:{currentConfig.params.connectorCount}/{currentConfig.params.spliceCount}</div>
|
||||
<div className="text-black text-l" >熔接点的数量:{currentConfig.params.spliceCount}个</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -272,26 +279,23 @@ export default function TestConfig() {
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-0">
|
||||
<div className="h-[50px] bg-[#F8F6F7] rounded-t-sm p-4 shadow-lg flex justify-between items-center">
|
||||
<div className="text-black text-l font-bold">测试类型:自动OTDR</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] p-4 shadow-lg flex justify-between items-center">
|
||||
<div className="text-black text-l ">前导补偿:开</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
{/* <Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" /> */}
|
||||
</div>
|
||||
<div className="text-black text-l font-bold flex items-center gap-1"><SignalIcon className="w-4 h-4 text-black" />测试波长</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] rounded-b-sm p-4 shadow-lg flex justify-between items-center">
|
||||
<div className="text-black text-l ">波长:{currentConfig.params.cableType.includes('OM') ? '850 nm、1310nm' : '1310nm、1550nm'}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
{/* <Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" /> */}
|
||||
<div className="text-black text-l ">{currentConfig.params.cableType.includes('OM') ? '850 nm、1310nm' : '1310nm、1550nm'}</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-0">
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-t-sm p-4 shadow-lg flex justify-between items-center"
|
||||
>
|
||||
<div className="text-black text-l font-bold flex items-center gap-1"><TagIcon className="w-4 h-4 text黑色" /> 光纤类型</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] rounded-b-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('menulist', 'setup', {
|
||||
menuType: 'FIBER_TYPE',
|
||||
selectedConfigId: selectedConfigId,
|
||||
@@ -299,13 +303,21 @@ export default function TestConfig() {
|
||||
backView: 'setup'
|
||||
})}
|
||||
>
|
||||
<div className="text-black text-l font-bold">光纤类型:{currentConfig.params.cableType}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
<div className="text-black text-l">{currentConfig.params.cableType}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
|
||||
|
||||
<div className="space-y-0">
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-t-sm p-4 shadow-lg flex justify-between items-center"
|
||||
>
|
||||
<div className="text-black text-l font-bold flex items-center gap-1"><SwatchIcon className="w-4 h-4 text黑色" /> 测试极限值</div>
|
||||
</div>
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] rounded-b-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('menulist', 'setup', {
|
||||
menuType: 'OFP_LIMIT',
|
||||
selectedConfigId: selectedConfigId,
|
||||
@@ -313,11 +325,14 @@ export default function TestConfig() {
|
||||
backView: 'setup'
|
||||
})}
|
||||
>
|
||||
<div className="text-black text-l font-bold">测试极限值:{currentConfig.params.limitValue}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
<div className="text-black text-l">{currentConfig.params.limitValue}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
);
|
||||
default:
|
||||
@@ -410,7 +425,7 @@ export default function TestConfig() {
|
||||
moduleType: '8000',
|
||||
modulelable: '铜缆测试仪',
|
||||
params: {
|
||||
limitValue: 'TIA Cat 6 Channel',
|
||||
limitValue: 'GBT 50312-2016 Cat 6 Ch',
|
||||
cableType: 'Cat6 U/UTP',
|
||||
wireOrder: 'T568B',
|
||||
refJumper: '1',
|
||||
@@ -659,4 +674,4 @@ export default function TestConfig() {
|
||||
{renderFooter()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import TitleBar from '@/components/lib//TitleBar';
|
||||
import useDisplayStore from '@/store/displayStore';
|
||||
import useDeviceStore from '@/store/deviceStore';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { getAssetUrl } from '@/utils/asset';
|
||||
|
||||
// 计算电阻余量的函数
|
||||
function calculateResistanceMargin(data, limitdata, limitValue) {
|
||||
@@ -722,7 +723,7 @@ export default function Testing() {
|
||||
{/* 背景图片 */}
|
||||
<div
|
||||
className="absolute inset-0 bg-cover bg-center bg-no-repeat"
|
||||
style={{ backgroundImage: 'url(/testing.gif)' }}
|
||||
style={{ backgroundImage: `url(${getAssetUrl('/testing.gif')})` }}
|
||||
/>
|
||||
|
||||
{/* 测试配置limit值 */}
|
||||
|
||||
@@ -663,9 +663,9 @@ export default function Tools() {
|
||||
/>
|
||||
</div>
|
||||
<div className="relative flex items-end justify-end px-20">
|
||||
<div className="relative flex flex-col items-start space-y-20">
|
||||
<div className="relative flex flex-col items-start space-y-20 pt-10">
|
||||
<div className="flex flex-col space-y-4 mb-4">
|
||||
<label className="text-white text-xl flex items-center">
|
||||
<label className="text-black text-xl flex items-center">
|
||||
<input
|
||||
type="radio"
|
||||
name="compensation"
|
||||
@@ -677,7 +677,7 @@ export default function Tools() {
|
||||
仅前导
|
||||
</label>
|
||||
{faultScenario !== 'DataCenter' && (
|
||||
<label className="text-white text-xl flex items-center">
|
||||
<label className="text-black text-xl flex items-center">
|
||||
<input
|
||||
type="radio"
|
||||
name="compensation"
|
||||
@@ -689,7 +689,7 @@ export default function Tools() {
|
||||
</label>
|
||||
)}
|
||||
</div>
|
||||
<div className="text-white text-m mb-4">
|
||||
<div className="text-black text-m mb-4">
|
||||
光纤类型:{currentConfig?.params?.cableType}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -150,7 +150,17 @@ export default function CopperResultMain({ testResult: initialTestResult }) {
|
||||
useEffect(() => {
|
||||
navigateTo(navigation.current.name, navigation.current.view, { ...navigation.current.params, activeTab });
|
||||
}, [activeTab]);
|
||||
const tabs = testResult?.CopperWiremapResultStatus === 'pass' ? (testResult?.resultdata?.result === 'pass' ? ['布线图', '性能'] : ['布线图', '性能', '诊断']) : ['布线图'];
|
||||
const tabs = (() => {
|
||||
if (estmodel === 'general') {
|
||||
if (testResult?.CopperWiremapResultStatus === 'pass') {
|
||||
return testResult?.resultdata?.result === 'pass' ? ['布线图', '性能'] : ['布线图', '性能'];
|
||||
}
|
||||
return ['布线图'];
|
||||
}
|
||||
return testResult?.CopperWiremapResultStatus === 'pass'
|
||||
? (testResult?.resultdata?.result === 'pass' ? ['布线图', '性能'] : ['布线图', '性能', '诊断'])
|
||||
: ['布线图'];
|
||||
})();
|
||||
|
||||
//console.log(testResult);
|
||||
const renderContent = () => {
|
||||
|
||||
@@ -11,16 +11,28 @@ export default function DiagnosticView({ testResult }) {
|
||||
navigateTo('copperperformance', 'HDTD', { testResult, curtitle });
|
||||
};
|
||||
|
||||
const renderRow = (title) => (
|
||||
<div
|
||||
className="w-full flex items-center justify-between p-3 mb-2 rounded-md bg-[#F8F6F7] shadow-md cursor-pointer"
|
||||
onClick={() => handleRowClick(title)}
|
||||
>
|
||||
<span className="text-lg font-medium text-black">
|
||||
{title === 'HDTDR' ? '回波损耗分析' : title === 'HDTDX' ? '串扰分析' : title}
|
||||
</span>
|
||||
const renderRow = (title) => (
|
||||
estmodel === 'general' ? (
|
||||
<div
|
||||
className="w-full flex items-center justify-between p-3 mb-2 rounded-md bg-[#F8F6F7] shadow-md cursor-pointer"
|
||||
onClick={() => handleRowClick(title)}
|
||||
>
|
||||
<span className="text-lg font-medium text-black">
|
||||
{title === 'HDTDR' ? '时域反射分析' : title === 'HDTDX' ? '串扰分析' : title}
|
||||
</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
className="w-full flex items-center justify-between p-3 mb-2 rounded-md bg-gradient-to-b from-[#dedede] via-[#b5b5b5] to-[#8b898b] shadow-md cursor-pointer"
|
||||
onClick={() => handleRowClick(title)}
|
||||
>
|
||||
<span className="text-lg font-medium text-black">
|
||||
{title}
|
||||
</span>
|
||||
|
||||
</div>
|
||||
)
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
import React, { useState, useEffect, useMemo, useCallback } from 'react';
|
||||
import useDisplayStore from '@/store/displayStore';
|
||||
import useDeviceStore from '@/store/deviceStore';
|
||||
import Image from 'next/image';
|
||||
import { useRef } from 'react';
|
||||
import { getAssetUrl } from '@/utils/asset';
|
||||
import EventTable from './EventTable';
|
||||
|
||||
export default function EventMapView({ testResult }) {
|
||||
|
||||
const { estmodel } = useDeviceStore();
|
||||
const connectionStatus = testResult.ofpConnectionStatus;
|
||||
const { view } = useDisplayStore.getState().navigation.current;
|
||||
const currentCableId = useDisplayStore.getState().getCurrentCableId();
|
||||
@@ -12,7 +16,7 @@ export default function EventMapView({ testResult }) {
|
||||
const [eventData, setEventData] = useState({});
|
||||
const eventRefs = useRef({});
|
||||
const isMultiMode = testResult?.testconfig?.params?.cableType.includes('OM');
|
||||
|
||||
const tempTestResult = testResult;
|
||||
// 加载事件数据
|
||||
useEffect(() => {
|
||||
const loadTraceData = async () => {
|
||||
@@ -454,7 +458,7 @@ const renderEventComponent = useCallback((event, status) => {
|
||||
</div>
|
||||
|
||||
);
|
||||
};
|
||||
};
|
||||
//末导样式
|
||||
const EndRef = () => {
|
||||
return (
|
||||
@@ -477,8 +481,8 @@ const renderEventComponent = useCallback((event, status) => {
|
||||
</div>
|
||||
);
|
||||
};
|
||||
// 无光纤
|
||||
const EndNoFiber = () => {
|
||||
// 无光纤
|
||||
const EndNoFiber = () => {
|
||||
return (
|
||||
// <div className=" w-full h-[3px] bg-[#cc0000] top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 rounded-[1.5px] -rotate-45" />
|
||||
|
||||
@@ -490,9 +494,9 @@ const renderEventComponent = useCallback((event, status) => {
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
};
|
||||
// 熔接点样式
|
||||
const SplicePoint = ({ status = 'normal' }) => {
|
||||
const SplicePoint = ({ status = 'normal' }) => {
|
||||
return (
|
||||
<div className={`w-4 h-4 rounded-full relative
|
||||
${status === 'fail' ? 'bg-gradient-to-r from-[#8b0000] to-[#cc0000]' :
|
||||
@@ -506,7 +510,7 @@ const renderEventComponent = useCallback((event, status) => {
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
};
|
||||
// 弯曲事件样式
|
||||
const BendEvent = () => {
|
||||
return (
|
||||
@@ -514,7 +518,7 @@ const renderEventComponent = useCallback((event, status) => {
|
||||
-mr-0.5 flex-shrink-0"
|
||||
style={{ clipPath: 'inset(0 50% 0 0)' }} />
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full h-full flex flex-row bg-[#f0f0f0]"> {/* Changed to flex-row and added background */}
|
||||
@@ -522,49 +526,218 @@ const renderEventComponent = useCallback((event, status) => {
|
||||
<div className="w-1/3 h-full flex flex-col">
|
||||
<div className="w-full h-[100%] bg-white p-2 flex items-end justify-center"> {/* 改为items-end使内容底部对齐 */}
|
||||
<div className="w-full h-[90%] bg-white p-2 flex flex-col items-center justify-end relative">
|
||||
{processedEvents.map(([key, event], index, array) => {
|
||||
const nextEvent = array[index + 1]?.[1];
|
||||
const prevEvent = array[index - 1]?.[1];
|
||||
const distance = nextEvent ?
|
||||
(event.distance - nextEvent.distance).toFixed(1) :
|
||||
(eventData.summary.totalDistance - event.distance).toFixed(1);
|
||||
const status = getEventStatus(event, nextEvent, prevEvent);
|
||||
|
||||
return (
|
||||
<div key={key} className="flex flex-col items-center">
|
||||
<div
|
||||
ref={el => eventRefs.current[key] = el}
|
||||
onClick={() => setSelectedEvent(event)}
|
||||
className="cursor-pointer"
|
||||
>
|
||||
{renderEventComponent(event, status)}
|
||||
</div>
|
||||
|
||||
{index < array.length - 1 && (
|
||||
<div className="flex items-center relative">
|
||||
<div className="absolute left-[-65px] text-sm text-black whitespace-nowrap">
|
||||
{distance} m
|
||||
</div>
|
||||
<div
|
||||
className={`w-[2px] ${nextEvent?.type === 'StartRef' || event.type === 'EndRef' ? 'bg-gray-400' : 'bg-black'}`}
|
||||
style={{ height: getConnectionLineHeight(array.length) }}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
<Image
|
||||
src={getAssetUrl('/otdr-start.png')}
|
||||
alt="OTDR Start"
|
||||
width={40}
|
||||
height={40}
|
||||
/>
|
||||
</div>
|
||||
{processedEvents.map(([key, event], index, array) => {
|
||||
const nextEvent = array[index + 1]?.[1];
|
||||
const prevEvent = array[index - 1]?.[1];
|
||||
const distance = nextEvent ?
|
||||
(event.distance - nextEvent.distance).toFixed(1) :
|
||||
(eventData.summary.totalDistance - event.distance).toFixed(1);
|
||||
const status = getEventStatus(event, nextEvent, prevEvent);
|
||||
|
||||
return (
|
||||
<div key={key} className="flex flex-col items-center">
|
||||
<div
|
||||
ref={el => eventRefs.current[key] = el}
|
||||
onClick={() => setSelectedEvent(event)}
|
||||
className="cursor-pointer"
|
||||
>
|
||||
{renderEventComponent(event, status)}
|
||||
</div>
|
||||
|
||||
{index < array.length - 1 && (
|
||||
<div className="flex items-center relative">
|
||||
<div className="absolute left-[-65px] text-sm text-black whitespace-nowrap">
|
||||
{distance} m
|
||||
</div>
|
||||
<div
|
||||
className={`w-[2px] ${nextEvent?.type === 'StartRef' || event.type === 'EndRef' ? 'bg-gray-400' : 'bg-black'}`}
|
||||
style={{ height: getConnectionLineHeight(array.length) }}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
<Image
|
||||
src={getAssetUrl('/otdr-start.png')}
|
||||
alt="OTDR Start"
|
||||
width={40}
|
||||
height={40}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right Area (2/3 width) */}
|
||||
{estmodel === 'general' ? (
|
||||
|
||||
<div className="w-2/3 h-full flex flex-col bg-[#F8F6F7]"> {/* Added right column */}
|
||||
<div className="h-[20%] bg-white p-3 flex flex-col">
|
||||
<div className="flex justify-between items-start">
|
||||
<div>
|
||||
<div className="flex items-center">
|
||||
<span className="text-black font-bold text-sm">光纤长度:</span>
|
||||
<span className="text-black ml-1 text-sm">{eventData?.summary?.totalDistance || '0'} m</span>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<span className="text-black font-bold text-sm">总体损耗:</span>
|
||||
<span className="text-black ml-1 text-sm">{eventData?.summary?.totalLoss || 'N/A'} dB</span>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<span className="text-black font-bold text-sm">光纤类型:</span>
|
||||
<span className="text-black ml-1 text-sm">{testResult?.testconfig?.params?.cableType || null}</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div className="flex flex-col items-start">
|
||||
|
||||
|
||||
|
||||
{view === 'nosave' && (
|
||||
<div className="flex items-center">
|
||||
<span className="text-black font-bold text-sm">下一个ID:</span>
|
||||
<span className="text-black ml-1 text-sm">{currentCableId?.name || 'OTDR-02'}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<span className="text-black font-bold text-sm">测试极限值: </span>
|
||||
<span className="text-black ml-1 text-sm">{testResult?.testconfig?.params?.limitValue || null}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right Middle (60%) */}
|
||||
<div className="h-[45%] bg-white p-2 relative"> {/* Adjusted padding */}
|
||||
{/* 事件简要框 */}
|
||||
{selectedEvent && (
|
||||
<div className="absolute p-4 rounded-lg shadow-lg bg-gradient-to-b from-gray-200 to-gray-300 border-2"
|
||||
style={{
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: 'translate(-50%, -50%)',
|
||||
width: '80%',
|
||||
maxWidth: '350px',
|
||||
zIndex: 10,
|
||||
borderColor: selectedEvent.type === 'StartRef' || selectedEvent.type === 'Start' ? '#1a9850' :
|
||||
selectedEvent.type === 'EndRef' || selectedEvent.type === 'End' ? '#1a365d' :
|
||||
selectedEvent.spliceLoss > 0.75 || selectedEvent.spliceLoss > 0.35 ? '#cc0000' : '#1a365d'
|
||||
}}
|
||||
>
|
||||
{/* 小尾巴 - 指向左侧事件 */}
|
||||
<div className="absolute w-0 h-0 border-solid"
|
||||
style={{
|
||||
left: '-20px',
|
||||
top: '50%',
|
||||
transform: 'translateY(-50%)',
|
||||
borderWidth: '10px 20px 10px 0',
|
||||
borderColor: 'transparent ' +
|
||||
(selectedEvent.type === 'StartRef' || selectedEvent.type === 'Start' ? '#1a9850' :
|
||||
selectedEvent.type === 'EndRef' || selectedEvent.type === 'End' ? '#1a365d' :
|
||||
selectedEvent.spliceLoss > 0.75 || selectedEvent.spliceLoss > 0.35 ? '#cc0000' : '#1a365d') +
|
||||
' transparent transparent'
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* 标题 */}
|
||||
<div className="text-center font-bold text-xl mb-4">
|
||||
{selectedEvent.type === 'StartRef' ? 'OTDR端口' :
|
||||
selectedEvent.type === 'EndRef' ? '末尾事件' :
|
||||
selectedEvent.type === 'EndNoRef' ? '未找到末尾事件' :
|
||||
selectedEvent.type === 'Start' ? 'OTDR端口' :
|
||||
selectedEvent.type === 'End' ? '端点' :
|
||||
selectedEvent.type === 'Reflector' ? '反射器' :
|
||||
selectedEvent.type === 'Hidden' ? '隐藏事件' :
|
||||
selectedEvent.type === 'Splice' ? '熔接点' :
|
||||
selectedEvent.type === 'Bend' ? '弯曲事件' : '事件'}
|
||||
</div>
|
||||
|
||||
{/* 事件信息 */}
|
||||
<div className="mb-2">
|
||||
<div className="text-center mb-2">在{selectedEvent.distance.toFixed(2)} m</div>
|
||||
|
||||
{/* 根据事件类型显示不同信息 */}
|
||||
{(selectedEvent.type === 'Reflector' ||
|
||||
selectedEvent.type === 'Hidden' ||
|
||||
selectedEvent.type === 'EndRef') && (
|
||||
<div>
|
||||
<div className="flex justify-between items-center mb-2">
|
||||
<div className="flex items-center">
|
||||
<img
|
||||
src={selectedEvent.spliceLoss > 0.75 ? getAssetUrl('/fail.png') : getAssetUrl('/pass.png')}
|
||||
alt="status"
|
||||
className="w-4 h-4 mr-2"
|
||||
/>
|
||||
<span className="font-bold">损耗:</span>
|
||||
</div>
|
||||
<span>{selectedEvent.spliceLoss ? selectedEvent.spliceLoss.toFixed(2) : '0'} dB</span>
|
||||
</div>
|
||||
<div className="flex justify-between items-center mb-2">
|
||||
<div className="flex items-center">
|
||||
<div className="w-4 h-4 mr-2"></div>
|
||||
<span className="font-bold">反射率:</span>
|
||||
</div>
|
||||
<span>{selectedEvent.reflLoss ? selectedEvent.reflLoss.toFixed(2) : '0'} dB</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{(selectedEvent.type === 'Splice' || selectedEvent.type === 'Bend') && (
|
||||
<div className="flex justify-between items-center mb-2">
|
||||
<div className="flex items-center">
|
||||
<img
|
||||
src={selectedEvent.type === 'Splice' ?
|
||||
(selectedEvent.spliceLoss > 0.35 ? getAssetUrl('/fail.png') : getAssetUrl('/pass.png')) :
|
||||
(selectedEvent.spliceLoss > 0.75 ? getAssetUrl('/fail.png') : getAssetUrl('/pass.png'))}
|
||||
alt="status"
|
||||
className="w-4 h-4 mr-2"
|
||||
/>
|
||||
<span className="font-bold">损耗:</span>
|
||||
</div>
|
||||
<span>{selectedEvent.spliceLoss ? selectedEvent.spliceLoss.toFixed(2) : '0'} dB</span>
|
||||
</div>
|
||||
)}
|
||||
{(selectedEvent.type === 'StartRef' ||
|
||||
selectedEvent.type === 'Start' ||
|
||||
selectedEvent.type === 'End') && (
|
||||
<div className="flex justify-between items-center mb-2">
|
||||
<div className="flex items-center">
|
||||
<div className="w-4 h-4 mr-2"></div>
|
||||
<span className="font-bold">反射率:</span>
|
||||
</div>
|
||||
<span>{selectedEvent.reflLoss ? selectedEvent.reflLoss.toFixed(2) : '0'} dB</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 连接质量指示器 - 仅对某些事件类型显示 */}
|
||||
{(selectedEvent.type === 'Start' || selectedEvent.type === 'StartRef') && (
|
||||
<div className="mt-4">
|
||||
<div className="text-center mb-2">端口连接质量</div>
|
||||
<div className="relative h-4 bg-gray-200 rounded-full overflow-hidden">
|
||||
<div className="absolute top-0 left-0 h-full w-full flex">
|
||||
<div className="h-full bg-red-600" style={{width: '33%'}}></div>
|
||||
<div className="h-full bg-yellow-400" style={{width: '33%'}}></div>
|
||||
<div className="h-full bg-green-500" style={{width: '34%'}}></div>
|
||||
</div>
|
||||
<div className="absolute top-0 right-4 h-full flex items-center">
|
||||
<div className="w-3 h-3 bg-black transform rotate-45"></div>
|
||||
</div>
|
||||
<div className="absolute bottom-[-20px] right-4 text-xs">良好</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Right Bottom (20%) */}
|
||||
<div className="h-[35%] bg-white p-2 flex flex-col items-start justify-center"> {/* Adjusted padding and alignment */}
|
||||
<EventTable testResult={tempTestResult} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
):(
|
||||
<div className="w-2/3 h-full flex flex-col"> {/* Added right column */}
|
||||
{/* Right Top (20%) */}
|
||||
<div className="h-[20%] bg-white p-3 flex justify-between items-start ">
|
||||
@@ -714,6 +887,9 @@ const renderEventComponent = useCallback((event, status) => {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ export default function EventTable({ testResult }) {
|
||||
const [eventData, setEventData] = useState(null);
|
||||
const [currentWavelength, setCurrentWavelength] = useState(null);
|
||||
const [wavelengthData, setWavelengthData] = useState({});
|
||||
const { estmodel } = useDeviceStore();
|
||||
|
||||
// 判断是否为多模光纤
|
||||
const isMultiMode = testResult?.testconfig?.params?.cableType.includes('OM');
|
||||
@@ -374,76 +375,151 @@ export default function EventTable({ testResult }) {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full h-full flex flex-col bg-white p-4">
|
||||
{/* 表头 */}
|
||||
<div className="flex border-b border-gray-300 py-2 font-bold text-black">
|
||||
<div className="w-24 text-center">(m)</div>
|
||||
<div className="w-24 text-center">损耗</div>
|
||||
<div className="w-24 text-center">反射</div>
|
||||
<div className="flex-1 text-center">类型</div>
|
||||
<div className="w-16 text-center"></div>
|
||||
</div>
|
||||
estmodel === 'general' ? (
|
||||
<div className="w-full h-full flex flex-col bg-white">
|
||||
{/* 表头 */}
|
||||
<div className="flex border-b border-gray-300 font-bold text-black">
|
||||
<div className="w-[20%] text-center text-sm">(m)</div>
|
||||
<div className="w-[20%] text-center text-sm">损耗</div>
|
||||
<div className="w-[20%] text-center text-sm">反射</div>
|
||||
<div className="w-[30%] text-center text-sm">类型</div>
|
||||
<div className="w-[10%] text-center text-sm"></div>
|
||||
</div>
|
||||
|
||||
{/* 表格内容 */}
|
||||
<div className="flex-1 overflow-y-auto">
|
||||
{eventData && Object.entries(eventData.events)
|
||||
.sort((a, b) => b[1].distance - a[1].distance)
|
||||
.map(([key, event]) => (
|
||||
<div key={key} className="flex items-center border-b border-gray-200 py-2">
|
||||
<div className="w-24 text-center text-black">
|
||||
{event.distance.toFixed(2)}
|
||||
</div>
|
||||
<div className="w-24 text-center text-black">
|
||||
{event.spliceLoss ? event.spliceLoss.toFixed(2) : 'N/A'}
|
||||
</div>
|
||||
<div className="w-24 text-center text-black">
|
||||
{event.reflLoss ? event.reflLoss.toFixed(2) : 'N/A'}
|
||||
</div>
|
||||
<div className="flex-1 text-center text-black">
|
||||
{getEventTypeName(event.type)}
|
||||
</div>
|
||||
<div className="w-16 flex justify-center">
|
||||
<div className="w-5 h-5 relative">
|
||||
<Image
|
||||
src={getAssetUrl(getEventStatusIcon(event))}
|
||||
alt="status"
|
||||
fill
|
||||
className="object-contain"
|
||||
/>
|
||||
{/* 表格内容 */}
|
||||
<div className="flex-1 overflow-y-auto">
|
||||
{eventData && Object.entries(eventData.events)
|
||||
.sort((a, b) => b[1].distance - a[1].distance)
|
||||
.map(([key, event]) => (
|
||||
<div key={key} className="flex items-center border-b border-gray-200 ">
|
||||
<div className="w-[20%] text-center text-black text-sm">
|
||||
{event.distance.toFixed(2)}
|
||||
</div>
|
||||
<div className="w-[20%] text-center text-black text-sm">
|
||||
{event.spliceLoss ? event.spliceLoss.toFixed(2) : 'N/A'}
|
||||
</div>
|
||||
<div className="w-[20%] text-center text-black text-sm">
|
||||
{event.reflLoss ? event.reflLoss.toFixed(2) : 'N/A'}
|
||||
</div>
|
||||
<div className="w-[30%] text-center text-black text-sm">
|
||||
{getEventTypeName(event.type)}
|
||||
</div>
|
||||
<div className="w-[10%] flex justify-center text-sm">
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image
|
||||
src={getAssetUrl(getEventStatusIcon(event))}
|
||||
alt="status"
|
||||
fill
|
||||
className="object-contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* 底部控制区 */}
|
||||
<div className="h-[10%] flex items-center justify-center space-x-4">
|
||||
<button
|
||||
onClick={() => {
|
||||
const wavelengths = Object.keys(wavelengthData);
|
||||
const currentIndex = wavelengths.indexOf(currentWavelength);
|
||||
const prevWavelength = wavelengths[(currentIndex - 1 + wavelengths.length) % wavelengths.length];
|
||||
setCurrentWavelength(prevWavelength);
|
||||
setEventData(wavelengthData[prevWavelength]);
|
||||
}}
|
||||
className="p-2 rounded-full bg-gray-300 hover:bg-gray-400"
|
||||
>
|
||||
◀
|
||||
</button>
|
||||
<span className="text-lg font-semibold">{currentWavelength}nm</span>
|
||||
<button
|
||||
onClick={() => {
|
||||
const wavelengths = Object.keys(wavelengthData);
|
||||
const currentIndex = wavelengths.indexOf(currentWavelength);
|
||||
const nextWavelength = wavelengths[(currentIndex + 1) % wavelengths.length];
|
||||
setCurrentWavelength(nextWavelength);
|
||||
setEventData(wavelengthData[nextWavelength]);
|
||||
}}
|
||||
className="p-2 rounded-full bg-gray-300 hover:bg-gray-400"
|
||||
>
|
||||
▶
|
||||
</button>
|
||||
{/* 底部控制区 */}
|
||||
<div className="h-[10%] flex items-center justify-center space-x-4">
|
||||
<button
|
||||
onClick={() => {
|
||||
const wavelengths = Object.keys(wavelengthData);
|
||||
const currentIndex = wavelengths.indexOf(currentWavelength);
|
||||
const prevWavelength = wavelengths[(currentIndex - 1 + wavelengths.length) % wavelengths.length];
|
||||
setCurrentWavelength(prevWavelength);
|
||||
setEventData(wavelengthData[prevWavelength]);
|
||||
}}
|
||||
className="w-6 h-6 rounded-full bg-gray-300 hover:bg-gray-400 flex items-center justify-center text-xs"
|
||||
>
|
||||
◀
|
||||
</button>
|
||||
<span className="text-sm font-semibold">{currentWavelength}nm</span>
|
||||
<button
|
||||
onClick={() => {
|
||||
const wavelengths = Object.keys(wavelengthData);
|
||||
const currentIndex = wavelengths.indexOf(currentWavelength);
|
||||
const nextWavelength = wavelengths[(currentIndex + 1) % wavelengths.length];
|
||||
setCurrentWavelength(nextWavelength);
|
||||
setEventData(wavelengthData[nextWavelength]);
|
||||
}}
|
||||
className="w-6 h-6 rounded-full bg-gray-300 hover:bg-gray-400 flex items-center justify-center text-xs"
|
||||
>
|
||||
▶
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
):(
|
||||
<div className="w-full h-full flex flex-col bg-white p-4">
|
||||
{/* 表头 */}
|
||||
<div className="flex border-b border-gray-300 py-2 font-bold text-black">
|
||||
<div className="w-[20%] text-center">(m)</div>
|
||||
<div className="w-[20%] text-center">损耗</div>
|
||||
<div className="w-[20%] text-center">反射</div>
|
||||
<div className="w-[20%] text-center">类型</div>
|
||||
<div className="w-[20%] text-center"></div>
|
||||
</div>
|
||||
|
||||
{/* 表格内容 */}
|
||||
<div className="flex-1 overflow-y-auto">
|
||||
{eventData && Object.entries(eventData.events)
|
||||
.sort((a, b) => b[1].distance - a[1].distance)
|
||||
.map(([key, event]) => (
|
||||
<div key={key} className="flex items-center border-b border-gray-200 py-2">
|
||||
<div className="w-[20%] text-center text-black">
|
||||
{event.distance.toFixed(2)}
|
||||
</div>
|
||||
<div className="w-[20%] text-center text-black">
|
||||
{event.spliceLoss ? event.spliceLoss.toFixed(2) : 'N/A'}
|
||||
</div>
|
||||
<div className="w-[20%] text-center text-black">
|
||||
{event.reflLoss ? event.reflLoss.toFixed(2) : 'N/A'}
|
||||
</div>
|
||||
<div className="w-[20%] text-center text-black">
|
||||
{getEventTypeName(event.type)}
|
||||
</div>
|
||||
<div className="w-[20%] flex justify-center">
|
||||
<div className="w-5 h-5 relative">
|
||||
<Image
|
||||
src={getAssetUrl(getEventStatusIcon(event))}
|
||||
alt="status"
|
||||
fill
|
||||
className="object-contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* 底部控制区 */}
|
||||
<div className="h-[10%] flex items-center justify-center space-x-4">
|
||||
<button
|
||||
onClick={() => {
|
||||
const wavelengths = Object.keys(wavelengthData);
|
||||
const currentIndex = wavelengths.indexOf(currentWavelength);
|
||||
const prevWavelength = wavelengths[(currentIndex - 1 + wavelengths.length) % wavelengths.length];
|
||||
setCurrentWavelength(prevWavelength);
|
||||
setEventData(wavelengthData[prevWavelength]);
|
||||
}}
|
||||
className="p-2 rounded-full bg-gray-300 hover:bg-gray-400"
|
||||
>
|
||||
◀
|
||||
</button>
|
||||
<span className="text-lg font-semibold">{currentWavelength}nm</span>
|
||||
<button
|
||||
onClick={() => {
|
||||
const wavelengths = Object.keys(wavelengthData);
|
||||
const currentIndex = wavelengths.indexOf(currentWavelength);
|
||||
const nextWavelength = wavelengths[(currentIndex + 1) % wavelengths.length];
|
||||
setCurrentWavelength(nextWavelength);
|
||||
setEventData(wavelengthData[nextWavelength]);
|
||||
}}
|
||||
className="p-2 rounded-full bg-gray-300 hover:bg-gray-400"
|
||||
>
|
||||
▶
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
);
|
||||
}
|
||||
@@ -31,7 +31,9 @@ const FrequencyChart = ({
|
||||
limitdata,
|
||||
limitValue,
|
||||
HDTD,
|
||||
CopperResultStatus,
|
||||
curtitle,
|
||||
displayTitle,
|
||||
wireOrder // 添加 wireOrder 参数
|
||||
}) => {
|
||||
const chartRef = useRef(null);
|
||||
@@ -407,7 +409,7 @@ const FrequencyChart = ({
|
||||
return (
|
||||
<div className="flex justify-between p-2 w-full">
|
||||
<div className="space-y-2">
|
||||
<div className="font-bold">{curtitle} : {mouseInfo.values.worstValue} dB </div>
|
||||
<div className="font-bold">{displayTitle || curtitle} : {mouseInfo.values.worstValue} dB </div>
|
||||
<div className="font-bold">余量 : {mouseInfo.values.margin} dB</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -415,11 +417,11 @@ const FrequencyChart = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full flex flex-col"> {/* 移除h-full */}
|
||||
<div className="w-full flex flex-col">
|
||||
{renderChart()}
|
||||
{renderParameters()}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default FrequencyChart;
|
||||
export default FrequencyChart;
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import React from 'react';
|
||||
import useDisplayStore from '@/store/displayStore';
|
||||
import { getAssetUrl } from '@/utils/asset';
|
||||
import useDeviceStore from '@/store/deviceStore';
|
||||
|
||||
|
||||
export default function OLTSResultMain({ testResult }) {
|
||||
const { estmodel } = useDeviceStore();
|
||||
const { getCurrentTestConfig } = useDisplayStore.getState();
|
||||
const { view } = useDisplayStore.getState().navigation.current;
|
||||
const currentConfig = getCurrentTestConfig();
|
||||
@@ -44,79 +47,173 @@ export default function OLTSResultMain({ testResult }) {
|
||||
};
|
||||
|
||||
return (
|
||||
estmodel === 'general' ? (
|
||||
<div className="w-full h-[490px] flex flex-col overflow-hidden">
|
||||
{/* 背景图片层 */}
|
||||
|
||||
<div className="w-full h-full relative">
|
||||
{/* 背景图片层 */}
|
||||
<div
|
||||
className="absolute inset-0 bg-cover bg-center bg-no-repeat"
|
||||
style={{ backgroundImage: `url(${getAssetUrl(getBackgroundImage())})` }}
|
||||
/>
|
||||
|
||||
{/* 数据显示层 */}
|
||||
<div className="absolute inset-0 flex items-center justify-center pl-66 pb-24">
|
||||
<div className="flex flex-col gap-6 ">
|
||||
{/* 上方数据显示框 */}
|
||||
<div className="bg-gradient-to-b w-48 from-[#e6e3e6] to-[#7b797b] p-2 rounded-lg">
|
||||
<div className="flex flex-col gap-0">
|
||||
{/* 损耗显示 */}
|
||||
{view !== 'nosave' ? (
|
||||
<div className="text-black pb-3 font-bold whitespace-nowrap overflow-hidden text-ellipsis">{testResult.inputname}</div>
|
||||
) : (
|
||||
<div className="text-black pb-3 font-bold">未保存的结果</div>
|
||||
)}
|
||||
<div className="flex items-center">
|
||||
{testResult.isLossValidOut ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">损耗:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainOut.wavelength1.loss}dB</div>
|
||||
</div>
|
||||
|
||||
{/* 长度显示 */}
|
||||
<div className="flex items-center">
|
||||
{testResult.isLengthValidOut ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">长度:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainOut.wavelength1.distance}m</div>
|
||||
{/* 测试结果显示 */}
|
||||
<div className="absolute inset-0 flex items-center justify-center pb-24">
|
||||
<div className="flex flex-row gap-30 ">
|
||||
<div className={`w-40 bg-[#F8F6F7] p-2 rounded-lg border-2 ${testResult.isLossValidOut ? 'border-[#00A65A]' : 'border-[#ce1d31]'}`}>
|
||||
<div className="flex flex-col gap-0">
|
||||
{/* 损耗显示 */}
|
||||
{view !== 'nosave' ? (
|
||||
<div className="text-black pb-3 font-bold whitespace-nowrap overflow-hidden text-ellipsis">{testResult.inputname}</div>
|
||||
) : (
|
||||
<div className="text-black pb-3 font-bold">未保存的结果</div>
|
||||
)}
|
||||
<div className="flex items-center">
|
||||
{testResult.isLossValidOut ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">{`λ${isMultiMode ? '850' : '1310'}`}:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainOut.wavelength1.loss}dB</div>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
{testResult.isLossValidOut ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">{`λ${isMultiMode ? '1300' : '1550'}`}:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainOut.wavelength2.loss}dB</div>
|
||||
</div>
|
||||
|
||||
{/* 长度显示 */}
|
||||
<div className="flex items-center">
|
||||
{testResult.isLengthValidOut ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">长度:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainOut.wavelength1.distance}m</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 下方数据显示框 */}
|
||||
<div className="bg-gradient-to-b w-48 from-[#e6e3e6] to-[#7b797b] p-2 rounded-lg">
|
||||
<div className="flex flex-col gap-0">
|
||||
{/* 损耗显示 */}
|
||||
{view !== 'nosave' ? (
|
||||
<div className="text-black pb-3 font-bold whitespace-nowrap overflow-hidden text-ellipsis">{testResult.outname}</div>
|
||||
) : (
|
||||
<div className="text-black pb-3 font-bold">未保存的结果</div>
|
||||
)}
|
||||
<div className="flex items-center">
|
||||
{testResult.isLossValidIn ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">损耗:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainIn.wavelength1.loss}dB</div>
|
||||
</div>
|
||||
|
||||
{/* 长度显示 */}
|
||||
<div className="flex items-center">
|
||||
{testResult.isLengthValidIn ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">长度:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainIn.wavelength1.distance}m</div>
|
||||
<div className={`w-40 bg-[#F8F6F7] p-2 rounded-lg border-2 ${testResult.isLossValidIn ? 'border-[#00A65A]' : 'border-[#ce1d31]'}`}>
|
||||
<div className="flex flex-col gap-0">
|
||||
{/* 损耗显示 */}
|
||||
{view !== 'nosave' ? (
|
||||
<div className="text-black pb-3 font-bold whitespace-nowrap overflow-hidden text-ellipsis">{testResult.outname}</div>
|
||||
) : (
|
||||
<div className="text-black pb-3 font-bold">未保存的结果</div>
|
||||
)}
|
||||
<div className="flex items-center">
|
||||
{testResult.isLossValidIn ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">{`λ${isMultiMode ? '850' : '1310'}`}:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainIn.wavelength1.loss}dB</div>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
{testResult.isLossValidIn ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">{`λ${isMultiMode ? '1300' : '1550'}`}:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainIn.wavelength2.loss}dB</div>
|
||||
</div>
|
||||
|
||||
{/* 长度显示 */}
|
||||
<div className="flex items-center">
|
||||
{testResult.isLengthValidIn ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">长度:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainIn.wavelength1.distance}m</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
):(
|
||||
<div className="w-full h-[490px] flex flex-col overflow-hidden">
|
||||
|
||||
<div className="w-full h-full relative">
|
||||
{/* 背景图片层 */}
|
||||
<div
|
||||
className="absolute inset-0 bg-cover bg-center bg-no-repeat"
|
||||
style={{ backgroundImage: `url(${getAssetUrl(getBackgroundImage())})` }}
|
||||
/>
|
||||
{/* 测试结果显示 */}
|
||||
<div className="absolute inset-0 flex items-center justify-center pl-66 pb-24">
|
||||
<div className="flex flex-col gap-6 ">
|
||||
{/* 上方数据显示框 */}
|
||||
<div className="bg-gradient-to-b w-48 from-[#e6e3e6] to-[#7b797b] p-2 rounded-lg">
|
||||
<div className="flex flex-col gap-0">
|
||||
{/* 损耗显示 */}
|
||||
{view !== 'nosave' ? (
|
||||
<div className="text-black pb-3 font-bold whitespace-nowrap overflow-hidden text-ellipsis">{testResult.inputname}</div>
|
||||
) : (
|
||||
<div className="text-black pb-3 font-bold">未保存的结果</div>
|
||||
)}
|
||||
<div className="flex items-center">
|
||||
{testResult.isLossValidOut ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">损耗:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainOut.wavelength1.loss}dB</div>
|
||||
</div>
|
||||
|
||||
{/* 长度显示 */}
|
||||
<div className="flex items-center">
|
||||
{testResult.isLengthValidOut ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">长度:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainOut.wavelength1.distance}m</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 下方数据显示框 */}
|
||||
<div className="bg-gradient-to-b w-48 from-[#e6e3e6] to-[#7b797b] p-2 rounded-lg">
|
||||
<div className="flex flex-col gap-0">
|
||||
{/* 损耗显示 */}
|
||||
{view !== 'nosave' ? (
|
||||
<div className="text-black pb-3 font-bold whitespace-nowrap overflow-hidden text-ellipsis">{testResult.outname}</div>
|
||||
) : (
|
||||
<div className="text-black pb-3 font-bold">未保存的结果</div>
|
||||
)}
|
||||
<div className="flex items-center">
|
||||
{testResult.isLossValidIn ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">损耗:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainIn.wavelength1.loss}dB</div>
|
||||
</div>
|
||||
|
||||
{/* 长度显示 */}
|
||||
<div className="flex items-center">
|
||||
{testResult.isLengthValidIn ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">长度:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainIn.wavelength1.distance}m</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,14 @@ import EventTable from './EventTable';
|
||||
import CurveChart from './CurveChart';
|
||||
import useDeviceStore from '@/store/deviceStore';
|
||||
|
||||
|
||||
export default function OTDRResultMain({ testResult }) {
|
||||
const [activeTab, setActiveTab] = useState('EventMap');
|
||||
const tabs = ['EventMap', '表', '曲线'];
|
||||
const tempTestResult = testResult;
|
||||
|
||||
const { estmodel } = useDeviceStore();
|
||||
const [activeTab, setActiveTab] = useState('EventMap');
|
||||
|
||||
const tabs = estmodel === 'general' ? ['EventMap', '曲线'] : ['EventMap', '表', '曲线'];
|
||||
const tempTestResult = testResult;
|
||||
|
||||
const renderContent = () => {
|
||||
switch (activeTab) {
|
||||
@@ -48,7 +51,7 @@ export default function OTDRResultMain({ testResult }) {
|
||||
? 'bg-gradient-to-b from-[#d5dfeb] via-[#f8f6f7] to-[#d5dfeb] text-black'
|
||||
: 'bg-[#132843] text-[#fffe92]'}`}
|
||||
>
|
||||
{tab}
|
||||
{estmodel === 'general' && tab === 'EventMap' ? '链路图' : tab}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
@@ -79,4 +82,4 @@ export default function OTDRResultMain({ testResult }) {
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,8 @@ export default function PerformanceView({ testResult }) {
|
||||
}
|
||||
|
||||
let minMargin = Infinity;
|
||||
let worstIndex = null;
|
||||
const frequencies = testResult?.resultdata?.performance?.data?.frequencies || [];
|
||||
const data = testResult.resultdata.performance.data[dataGroup];
|
||||
const limitValues = limitdata[dataGroup]?.['PAIRLimit (dB)'] || [];
|
||||
|
||||
@@ -72,12 +74,21 @@ export default function PerformanceView({ testResult }) {
|
||||
const margin = paramTitle === '插入损耗' ?
|
||||
Math.abs(limitValue) - Math.abs(actualValue) : // 插入损耗:极限值 - 参数值
|
||||
Math.abs(actualValue) - limitValue; // 其他参数:参数值 - 极限值
|
||||
minMargin = Math.min(minMargin, margin);
|
||||
if (margin < minMargin) {
|
||||
minMargin = margin;
|
||||
worstIndex = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return minMargin !== Infinity ? minMargin.toFixed(1) : null;
|
||||
if (minMargin === Infinity) return null;
|
||||
const freqVal = Number(frequencies?.[worstIndex]);
|
||||
return {
|
||||
value: minMargin.toFixed(1),
|
||||
index: worstIndex,
|
||||
freq: Number.isFinite(freqVal) ? Math.round(freqVal) : undefined
|
||||
};
|
||||
};
|
||||
|
||||
// 计算长度余量和状态
|
||||
@@ -234,8 +245,8 @@ export default function PerformanceView({ testResult }) {
|
||||
const lengthStatus = calculateLengthStatus();
|
||||
isPass = lengthStatus.isPass;
|
||||
} else {
|
||||
// 其他参数保持原有逻辑
|
||||
isPass = parseFloat(value) >= 0;
|
||||
const numeric = typeof value === 'object' && value !== null ? parseFloat(value.value) : parseFloat(value);
|
||||
isPass = numeric >= 0;
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -273,27 +284,96 @@ export default function PerformanceView({ testResult }) {
|
||||
}
|
||||
};
|
||||
|
||||
const renderRow = (title, value, unit = '') => (
|
||||
const getDisplayTitle = (key) => {
|
||||
const map = {
|
||||
'长度': '长度',
|
||||
'电阻': '电阻',
|
||||
'插入损耗': '插入损耗',
|
||||
'回波损耗': '回波损耗',
|
||||
'NEXT': '近端串音',
|
||||
'PS NEXT': '近端串音功率和',
|
||||
'ACR-N': '衰减近端串音比',
|
||||
'PS ACR-N': '衰减近端串音比功率和',
|
||||
'ACR-F': '衰减远端串音比',
|
||||
'PS ACR-F': '衰减远端串音比功率和',
|
||||
'CDNEXT': '共模转差模近端串音',
|
||||
'CMRL': '共模回波损耗',
|
||||
'TCL': '横向转换损耗',
|
||||
'ELTCTL': '两端等效横向转换损耗'
|
||||
};
|
||||
return map[key] || key;
|
||||
};
|
||||
|
||||
const renderRow = (key, value, unit = '') => (
|
||||
estmodel === 'general' ? (
|
||||
<div
|
||||
className="w-full flex items-center justify-between p-3 mb-2 rounded-md bg-[#F8F6F7] shadow-md cursor-pointer"
|
||||
onClick={() => handleRowClick(title)}
|
||||
onClick={() => handleRowClick(key)}
|
||||
>
|
||||
<span className="text-lg font-medium text-black">{title}</span>
|
||||
<div className="flex items-center">
|
||||
<span className="text-lg text-black">{title === '电阻' ? '' : (value ? `(${value}${unit})` : '')}</span>
|
||||
{getStatusIcon(value, title)}
|
||||
<span className="text-lg font-medium text-black min-w-[220px]">{getDisplayTitle(key)}</span>
|
||||
<div className="grid grid-cols-3 gap-3 items-center ">
|
||||
|
||||
<span className="text-lg text-black text-right">
|
||||
|
||||
{(() => {
|
||||
if (key === '长度') {
|
||||
// 长度显示原始value
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
return `${value.value}${unit}`; // 若长度返回对象,取value字段
|
||||
}
|
||||
return `${value}${unit}`;
|
||||
}
|
||||
if (key === '电阻' || key === '长度') return '';
|
||||
if (!value) return '';
|
||||
const unitText = (unit || '').trim();
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
return `${value.value}${unitText}`;
|
||||
}
|
||||
return `${value}${unitText}`;
|
||||
})()}
|
||||
</span>
|
||||
<span className="text-lg text-black text-right">
|
||||
{(() => {
|
||||
if (key === '电阻' || key === '长度') return '';
|
||||
if (!value) return '';
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
const freq = value.freq !== undefined ? value.freq : (Number.isFinite(value.index) ? value.index : undefined);
|
||||
return freq !== undefined ? `@${freq}MHz` : '';
|
||||
}
|
||||
return '';
|
||||
})()}
|
||||
</span>
|
||||
<div className="flex justify-end">
|
||||
{getStatusIcon(value, key)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
):(
|
||||
<div
|
||||
className="w-full flex items-center justify-between p-3 mb-2 rounded-md bg-gradient-to-b from-[#dedede] via-[#b5b5b5] to-[#8b898b] shadow-md cursor-pointer"
|
||||
onClick={() => handleRowClick(title)}
|
||||
onClick={() => handleRowClick(key)}
|
||||
>
|
||||
<span className="text-lg font-medium text-black">{title}</span>
|
||||
<span className="text-lg font-medium text-black">{key}</span>
|
||||
<div className="flex items-center">
|
||||
<span className="text-lg text-black">{title === '电阻' ? '' : (value ? `(${value}${unit})` : '')}</span>
|
||||
{getStatusIcon(value, title)}
|
||||
<span className="text-lg text-black">
|
||||
{(() => { if (key === '电阻') return '';
|
||||
if (!value) return '';
|
||||
if (key === '长度') {
|
||||
// 长度显示原始value
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
return `(${value.value}${unit})`; // 若长度返回对象,取value字段
|
||||
}
|
||||
return `(${value}${unit})`;
|
||||
}
|
||||
// 其他参数显示对象的value
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
return `(${value.value}${unit})`;
|
||||
}
|
||||
return `(${value}${unit})`;
|
||||
})()}
|
||||
|
||||
</span>
|
||||
{getStatusIcon(value, key)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
@@ -346,4 +426,4 @@ export default function PerformanceView({ testResult }) {
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,27 +2,42 @@ import React from 'react';
|
||||
import Image from 'next/image';
|
||||
import useDisplayStore from '@/store/displayStore';
|
||||
import { getAssetUrl } from '@/utils/asset';
|
||||
import useDeviceStore from '@/store/deviceStore';
|
||||
|
||||
export default function ResultTitleBar({ title, backTo, view, onBack, testResult, result }) {
|
||||
const { navigateTo, goBack, updateCurrentView, navigation } = useDisplayStore();
|
||||
|
||||
const { estmodel } = useDeviceStore();
|
||||
|
||||
// 根据结果获取背景颜色
|
||||
const getBgColor = () => {
|
||||
// 如果存在CopperWiremapResultStatus,使用铜缆测试逻辑
|
||||
if (estmodel === 'general') {
|
||||
if (testResult?.CopperResultStatus) {
|
||||
return testResult.CopperResultStatus === 'pass'
|
||||
? 'bg-gradient-to-r from-[#003366] to-[#00A65A]'
|
||||
: 'bg-gradient-to-r from-[#003366] to-[#ce1d31]';
|
||||
}
|
||||
if (testResult?.CFPResultStatus) {
|
||||
return testResult.CFPResultStatus === 'pass'
|
||||
? 'bg-gradient-to-r from-[#003366] to-[#00A65A]'
|
||||
: 'bg-gradient-to-r from-[#003366] to-[#ce1d31]';
|
||||
}
|
||||
if (testResult?.ofpResultStatus) {
|
||||
return testResult.ofpResultStatus === 'pass'
|
||||
? 'bg-gradient-to-r from-[#003366] to-[#00A65A]'
|
||||
: 'bg-gradient-to-r from-[#003366] to-[#ce1d31]';
|
||||
}
|
||||
return 'bg-[#003366]';
|
||||
}
|
||||
if (testResult?.CopperResultStatus) {
|
||||
if (testResult.CopperResultStatus !== 'pass') return 'bg-[#ce1d31]';
|
||||
return testResult.CopperResultStatus === 'pass' ? 'bg-[#00A65A]' : 'bg-[#ce1d31]';
|
||||
}
|
||||
// 如果存在OFPStatus,使用光纤测试逻辑
|
||||
if (testResult?.CFPResultStatus) {
|
||||
return testResult.CFPResultStatus === 'pass' ? 'bg-[#00A65A]' : 'bg-[#ce1d31]';
|
||||
}
|
||||
// 如果存在OFPStatus,使用光纤测试逻辑
|
||||
if (testResult?.ofpResultStatus) {
|
||||
return testResult.ofpResultStatus === 'pass' ? 'bg-[#00A65A]' : 'bg-[#ce1d31]';
|
||||
}
|
||||
// 默认蓝色
|
||||
return 'bg-[#003366]';
|
||||
};
|
||||
|
||||
@@ -96,4 +111,4 @@ export default function ResultTitleBar({ title, backTo, view, onBack, testResult
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -409,7 +409,7 @@ const CopperAnalyzer = () => {
|
||||
className="w-full p-2 border rounded text-xs bg-[#1E293B] text-[#0ff] border-[#0ff]/30 focus:border-[#0ff] focus:outline-none"
|
||||
>
|
||||
{/* <option value="coaxial">同轴线</option> */}
|
||||
<option value="twisted_single">双绞线(单对)</option>
|
||||
{/* <option value="twisted_single">双绞线(单对)</option> */}
|
||||
<option value="twisted_dual">双绞线(两对)</option>
|
||||
{/* <option value="fiber">光纤</option> */}
|
||||
</select>
|
||||
@@ -511,7 +511,7 @@ const CopperAnalyzer = () => {
|
||||
{params.cableType === 'twisted_dual' && (
|
||||
<div>
|
||||
<label className="block text-xs font-semibold text-[#0ff] mb-1">
|
||||
节距比例:
|
||||
线对节距:
|
||||
<span className="block text-[#0ff] font-bold">{params.pair2TwistRatio.toFixed(2)}×</span>
|
||||
</label>
|
||||
<input
|
||||
|
||||
@@ -15,13 +15,32 @@ export default function AdminPage() {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState(null);
|
||||
const [currentScene, setCurrentScene] = useState('WorldSkill');
|
||||
const [availableScenes, setAvailableScenes] = useState(['Office', 'Industry', 'WorldSkill']);
|
||||
const [showModal, setShowModal] = useState(false);
|
||||
const [showhistoryModal, setShowhistoryModal] = useState(false);
|
||||
const [uuid, setUuid] = useState(null);
|
||||
const [showConfirmDialog, setShowConfirmDialog] = useState(false);
|
||||
const [confirmDialogMessage, setConfirmDialogMessage] = useState('');
|
||||
const [confirmDialogCallback, setConfirmDialogCallback] = useState(null);
|
||||
|
||||
|
||||
// 场景标签映射
|
||||
const sceneLabels = { Office: '办公场景', Industry: '工业场景', WorldSkill: '竞赛模式' };
|
||||
const buildScenesFromModel = (model) => {
|
||||
if (!model) return ['Office', 'Industry', 'WorldSkill'];
|
||||
const m = model.match(/EST-(\d+)([A-Za-z]*)/i);
|
||||
const num = m?.[1] || '';
|
||||
const letter = (m?.[2] || '').toUpperCase();
|
||||
const scenes = [];
|
||||
if (num === '05') {
|
||||
scenes.push('Office');
|
||||
} else if (num === '10' || num === '100') {
|
||||
scenes.push('Office', 'Industry');
|
||||
}
|
||||
if (letter.includes('C')) {
|
||||
scenes.push('WorldSkill');
|
||||
}
|
||||
return [...new Set(scenes.length ? scenes : ['Office'])];
|
||||
};
|
||||
// 检查比赛状态
|
||||
const checkCompetitionStatus = async () => {
|
||||
try {
|
||||
@@ -45,6 +64,7 @@ export default function AdminPage() {
|
||||
const currentUrl = window.location.href;
|
||||
const urlParams = new URLSearchParams(currentUrl.split('?')[1] || '');
|
||||
const token = urlParams.get('token');
|
||||
const model = urlParams.get('model');
|
||||
if (!token) {
|
||||
router.push('/');
|
||||
return;
|
||||
@@ -57,6 +77,9 @@ export default function AdminPage() {
|
||||
const data = await response.json();
|
||||
if (data.isAdmin) {
|
||||
setIsAdmin(true);
|
||||
const scenes = buildScenesFromModel(model);
|
||||
setAvailableScenes(scenes);
|
||||
setCurrentScene((prev) => (scenes.includes(prev) ? prev : scenes[0]));
|
||||
// 通过鉴权后再触发后续初始化逻辑
|
||||
checkCompetitionStatus();
|
||||
fetchConnectionMap();
|
||||
@@ -70,7 +93,7 @@ export default function AdminPage() {
|
||||
}
|
||||
};
|
||||
verifyAdmin();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
|
||||
}, []);
|
||||
|
||||
// 从API获取连接配置
|
||||
@@ -407,9 +430,9 @@ export default function AdminPage() {
|
||||
onChange={(e) => setCurrentScene(e.target.value)}
|
||||
className="px-4 py-2 bg-[#1F2937] text-[#0ff] rounded-lg border border-[#0ff]/20"
|
||||
>
|
||||
<option value="Office">办公场景</option>
|
||||
<option value="Industry">工业场景</option>
|
||||
<option value="WorldSkill">竞赛模式</option>
|
||||
{availableScenes.map((s) => (
|
||||
<option key={s} value={s}>{sceneLabels[s]}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -429,9 +429,10 @@ function classNames(...classes) {
|
||||
play('uninstall');
|
||||
};
|
||||
|
||||
// 检查是否安装了OTDR模块(用于控制远端区域的显示)
|
||||
// 检查是否安装了特殊模块(用于控制远端区域的显示)
|
||||
const hasOtdrModule = mainUnitModules.some(m => m.id === 'ofp');
|
||||
const hasWiFiModule = installedDevices.main && installedDevices.main.id === 'wifi';
|
||||
const hasBenchmarkModule = useDeviceStore.getState().hasBenchmarkModule;
|
||||
//鼠标元素穿透检测显示到鼠标元素穿透检测显示到StatusToast
|
||||
const [portTooltip, setPortTooltip] = useState('');
|
||||
|
||||
@@ -511,15 +512,17 @@ function classNames(...classes) {
|
||||
<>
|
||||
|
||||
{/* 开发环境切换型号按钮 */}
|
||||
{/* <div className="fixed bottom-4 right-4 z-50">
|
||||
<button
|
||||
onClick={() => updateEstmodel(estmodel === 'fluke' ? 'general' : 'fluke')}
|
||||
className="px-3 py-2 text-sm rounded bg-blue-600 text-white hover:bg-blue-700"
|
||||
>
|
||||
切换型号:{estmodel}
|
||||
</button>
|
||||
</div> */}
|
||||
|
||||
|
||||
{/* <div className="fixed bottom-4 right-4 z-50">
|
||||
<button
|
||||
onClick={() => updateEstmodel(estmodel === 'fluke' ? 'general' : 'fluke')}
|
||||
className="px-3 py-2 text-sm rounded bg-blue-600 text-white hover:bg-blue-700"
|
||||
>
|
||||
切换型号:{estmodel}
|
||||
</button>
|
||||
</div> */}
|
||||
|
||||
|
||||
<style>{scrollbarStyles}</style>
|
||||
{/* 比赛ID */}
|
||||
{seatUUID && faultScenarios === 'WorldSkill' && (
|
||||
@@ -1185,6 +1188,25 @@ function classNames(...classes) {
|
||||
|
||||
{/* 主机和远端区域 */}
|
||||
<div className="h-[45%] flex-1 flex gap-4">
|
||||
{hasBenchmarkModule ? (
|
||||
<div
|
||||
className="w-full bg-[#0F172A] shadow-lg p-4 border border-[#0ff]/20 rounded-lg flex flex-col items-center justify-center relative"
|
||||
onContextMenu={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
handleContextMenu(e, 'benchmark');
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
src={getAssetUrl('/benchmark-copperanalyer.png')}
|
||||
alt="基准参考"
|
||||
sizes={"auto"}
|
||||
fill
|
||||
className="object-contain p-10"
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{/* 主机区域 */}
|
||||
<div className="w-[calc(50%-0.5rem)] bg-[#0F172A] shadow-lg p-4 border border-[#0ff]/20 rounded-lg">
|
||||
<div
|
||||
@@ -1420,6 +1442,8 @@ function classNames(...classes) {
|
||||
) : (
|
||||
<div className="w-[calc(50%-0.5rem)]"></div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -1560,6 +1584,20 @@ function classNames(...classes) {
|
||||
y={contextMenu.y}
|
||||
onClose={() => setContextMenu(null)}
|
||||
items={[
|
||||
...(contextMenu.target === 'benchmark' ? [
|
||||
{
|
||||
label: '卸载传输线基准模块',
|
||||
onClick: () => {
|
||||
if (mainUnitModules.some(m => m.id === 'benchmark-copper')) {
|
||||
handleUninstall('benchmark-copper', 'main');
|
||||
}
|
||||
if (remoteUnitModules.some(m => m.id === 'benchmark-copper')) {
|
||||
handleUninstall('benchmark-copper', 'remote');
|
||||
}
|
||||
setContextMenu(null);
|
||||
}
|
||||
}
|
||||
] : []),
|
||||
...(contextMenu.target === 'connection' && contextMenu.item ? [
|
||||
{
|
||||
label: '移除物品',
|
||||
|
||||
@@ -241,18 +241,17 @@ devtools(
|
||||
portType: 'copper',
|
||||
image: '/CAL-4P.png',
|
||||
description: '插座测试夹具4芯'
|
||||
}
|
||||
],
|
||||
'基准': [
|
||||
},
|
||||
{
|
||||
id: 'pachcode-copper',
|
||||
id: 'benchmark-copper',
|
||||
name: '基准连接器',
|
||||
type: 'cable',
|
||||
type: 'module',
|
||||
portType: 'cal-copper-out',
|
||||
image: '/benchmark.png',
|
||||
description: '基准连接'
|
||||
},
|
||||
],
|
||||
|
||||
},
|
||||
|
||||
|
||||
@@ -295,6 +294,8 @@ devtools(
|
||||
// 连接状态分析结果
|
||||
connectionStatus: [],
|
||||
|
||||
// 传输线基准状态
|
||||
hasBenchmarkModule: false,
|
||||
// 线缆参数
|
||||
cableParams: {
|
||||
conductorMaterial: 'copper',
|
||||
@@ -346,10 +347,12 @@ devtools(
|
||||
updates.mainUnitAdapter = null;
|
||||
updates.mainUnitFixture = null;
|
||||
updates.mainUnitPorts = [];
|
||||
updates.hasBenchmarkModule = false;
|
||||
} else {
|
||||
updates.remoteUnitModules = [];
|
||||
updates.remoteUnitAdapter = null;
|
||||
updates.remoteUnitPorts = [];
|
||||
updates.hasBenchmarkModule = false;
|
||||
}
|
||||
|
||||
return updates;
|
||||
@@ -388,9 +391,12 @@ devtools(
|
||||
];
|
||||
}
|
||||
|
||||
const newMainModules = [...state.mainUnitModules, module];
|
||||
const newRemoteModules = state.remoteUnitModules;
|
||||
return {
|
||||
mainUnitModules: [...state.mainUnitModules, module],
|
||||
mainUnitPorts: ports
|
||||
mainUnitModules: newMainModules,
|
||||
mainUnitPorts: ports,
|
||||
hasBenchmarkModule: newMainModules.some(m => m.id === 'benchmark-copper') && newRemoteModules.some(m => m.id === 'benchmark-copper')
|
||||
};
|
||||
} else {
|
||||
let ports = [];
|
||||
@@ -415,9 +421,12 @@ devtools(
|
||||
];
|
||||
}
|
||||
|
||||
const newRemoteModules = [...state.remoteUnitModules, module];
|
||||
const newMainModules = state.mainUnitModules;
|
||||
return {
|
||||
remoteUnitModules: [...state.remoteUnitModules, module],
|
||||
remoteUnitPorts: ports
|
||||
remoteUnitModules: newRemoteModules,
|
||||
remoteUnitPorts: ports,
|
||||
hasBenchmarkModule: newMainModules.some(m => m.id === 'benchmark-copper') && newRemoteModules.some(m => m.id === 'benchmark-copper')
|
||||
};
|
||||
}
|
||||
});
|
||||
@@ -427,16 +436,22 @@ devtools(
|
||||
uninstallModule: (moduleId, target) => {
|
||||
set((state) => {
|
||||
if (target === 'main') {
|
||||
const newMainModules = state.mainUnitModules.filter(m => m.id !== moduleId);
|
||||
const newRemoteModules = state.remoteUnitModules;
|
||||
return {
|
||||
mainUnitModules: state.mainUnitModules.filter(m => m.id !== moduleId),
|
||||
mainUnitModules: newMainModules,
|
||||
mainUnitPorts: [],
|
||||
mainUnitAdapter: null
|
||||
mainUnitAdapter: null,
|
||||
hasBenchmarkModule: newMainModules.some(m => m.id === 'benchmark-copper') && newRemoteModules.some(m => m.id === 'benchmark-copper')
|
||||
};
|
||||
} else {
|
||||
const newRemoteModules = state.remoteUnitModules.filter(m => m.id !== moduleId);
|
||||
const newMainModules = state.mainUnitModules;
|
||||
return {
|
||||
remoteUnitModules: state.remoteUnitModules.filter(m => m.id !== moduleId),
|
||||
remoteUnitModules: newRemoteModules,
|
||||
remoteUnitPorts: [],
|
||||
remoteUnitAdapter: null
|
||||
remoteUnitAdapter: null,
|
||||
hasBenchmarkModule: newMainModules.some(m => m.id === 'benchmark-copper') && newRemoteModules.some(m => m.id === 'benchmark-copper')
|
||||
};
|
||||
}
|
||||
});
|
||||
@@ -564,6 +579,11 @@ devtools(
|
||||
setTotalToastMessage: (message) => set({ totalToastMessage: message }),
|
||||
|
||||
// ---***线缆参数管理***---
|
||||
// 更新传输线基准状态
|
||||
updateHasBenchmarkModule: (status) =>
|
||||
set(() => ({
|
||||
hasBenchmarkModule: status
|
||||
})),
|
||||
|
||||
// 更新线缆参数
|
||||
updateCableParams: (params) =>
|
||||
@@ -630,6 +650,8 @@ devtools(
|
||||
connectionStatus: [],
|
||||
// 报告数据
|
||||
reports: [],
|
||||
// 传输线基准状态
|
||||
hasBenchmarkModule: false,
|
||||
// 线缆参数
|
||||
cableParams: {
|
||||
conductorMaterial: 'copper',
|
||||
@@ -660,4 +682,4 @@ devtools(
|
||||
|
||||
|
||||
|
||||
export default useDeviceStore;
|
||||
export default useDeviceStore;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { create } from 'zustand';
|
||||
import { devtools } from 'zustand/middleware';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import useDeviceStore from '@/store/deviceStore';
|
||||
|
||||
|
||||
// 默认项目配置
|
||||
const defaultProject = {
|
||||
// 默认项目配置(根据设备模型动态设置)
|
||||
const createDefaultProject = (estmodel) => ({
|
||||
id: 'default',
|
||||
name: 'DEFAULT',
|
||||
testResults: [],
|
||||
@@ -15,7 +16,7 @@ const defaultProject = {
|
||||
moduleType: '8000',
|
||||
modulelable: '铜缆测试仪',
|
||||
params: {
|
||||
limitValue: 'TIA Cat 6 Channel',
|
||||
limitValue: estmodel === 'general' ? 'GBT 50312-2016 Cat 6 Ch' : 'TIA Cat 6 Channel',
|
||||
cableType: 'Cat6 U/UTP',
|
||||
wireOrder: 'T568B'
|
||||
}
|
||||
@@ -25,7 +26,7 @@ const defaultProject = {
|
||||
moduleType: 'cfp',
|
||||
modulelable: '光损耗测试仪',
|
||||
params: {
|
||||
limitValue: 'TIA-568.3-E Multimode (STD)',
|
||||
limitValue: estmodel === 'general' ? 'GB/T 50312-2016 Fiber Link' : 'TIA-568.3-E Multimode (STD)',
|
||||
cableType: 'OM3 Multimode 50',
|
||||
refJumper: '1',
|
||||
spliceCount: '0',
|
||||
@@ -37,7 +38,7 @@ const defaultProject = {
|
||||
moduleType: 'ofp',
|
||||
modulelable: 'OTDR测试仪',
|
||||
params: {
|
||||
limitValue: 'General Fiber RL = 35 dB',
|
||||
limitValue: estmodel === 'general' ? 'GB/T 50312-2016 Fiber Link' : 'General Fiber RL = 35 dB',
|
||||
cableType: 'OM3 Multimode 50'
|
||||
}
|
||||
}
|
||||
@@ -55,7 +56,9 @@ const defaultProject = {
|
||||
operators: [
|
||||
{ id: uuidv4(), name: 'Bob' }
|
||||
],
|
||||
};
|
||||
});
|
||||
|
||||
const defaultProject = createDefaultProject(useDeviceStore.getState().estmodel);
|
||||
|
||||
// 默认状态
|
||||
const defaultState = {
|
||||
@@ -302,7 +305,7 @@ const useDisplayStore = create(devtools((set, get) => ({
|
||||
resetToDefaultState: () => {
|
||||
set(() => ({
|
||||
...defaultState,
|
||||
projects: [defaultProject]
|
||||
projects: [createDefaultProject(useDeviceStore.getState().estmodel)]
|
||||
}));
|
||||
},
|
||||
|
||||
@@ -324,4 +327,46 @@ const useDisplayStore = create(devtools((set, get) => ({
|
||||
|
||||
})));
|
||||
|
||||
export default useDisplayStore;
|
||||
useDeviceStore.subscribe(
|
||||
(state) => state.estmodel,
|
||||
(estmodel) => {
|
||||
const ds = useDisplayStore.getState();
|
||||
const idx = ds.selectedIndexes.projectIndex;
|
||||
const proj = ds.projects[idx];
|
||||
if (!proj) return;
|
||||
const testConfigs = proj.testConfigs.map((tc) => {
|
||||
if (tc.moduleType === '8000') {
|
||||
return {
|
||||
...tc,
|
||||
params: {
|
||||
...tc.params,
|
||||
limitValue: estmodel === 'general' ? 'GBT 50312-2016 Cat 6 Ch' : 'TIA Cat 6 Channel'
|
||||
}
|
||||
};
|
||||
}
|
||||
if (tc.moduleType === 'cfp') {
|
||||
return {
|
||||
...tc,
|
||||
params: {
|
||||
...tc.params,
|
||||
limitValue: estmodel === 'general' ? 'GB/T 50312-2016 Fiber Link' : 'TIA-568.3-E Multimode (STD)'
|
||||
}
|
||||
};
|
||||
}
|
||||
if (tc.moduleType === 'ofp') {
|
||||
return {
|
||||
...tc,
|
||||
params: {
|
||||
...tc.params,
|
||||
limitValue: estmodel === 'general' ? 'GB/T 50312-2016 Fiber Link' : 'General Fiber RL = 35 dB'
|
||||
}
|
||||
};
|
||||
}
|
||||
return tc;
|
||||
});
|
||||
const projects = ds.projects.map((p, i) => (i === idx ? { ...p, testConfigs } : p));
|
||||
useDisplayStore.setState({ projects });
|
||||
}
|
||||
);
|
||||
|
||||
export default useDisplayStore;
|
||||
|
||||
Reference in New Issue
Block a user