主页新增设备,传输线分析仪,可以分析双对线缆,根据自定义线缆长度,材质,线芯直径,绝缘厚度,绞距,节距等参数,了解影响IL,RL,NEXT等影响规律
This commit is contained in:
@@ -1,65 +1,35 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { getAssetUrl } from '@/utils/asset';
|
||||
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';
|
||||
import { useAudio } from '@/components/AudioProvider';
|
||||
import React from 'react';
|
||||
import useDeviceStore from '@/store/deviceStore';
|
||||
import DSXDisplay from './DisplayMainPage/dsx';
|
||||
import EstAnalyzerDisplay from './DisplayMainPage/est-analyzer';
|
||||
import WiFiDisplay from './DisplayMainPage/wifi';
|
||||
|
||||
export default function DisPlay() {
|
||||
|
||||
const { navigation, navigateTo, toastMessage} = useDisplayStore();
|
||||
const { play } = useAudio();
|
||||
const { installedDevices } = useDeviceStore();
|
||||
|
||||
|
||||
|
||||
const renderPage = () => {
|
||||
const pageName = navigation?.current?.name || 'home';
|
||||
// 根据安装的主设备ID渲染不同的主页
|
||||
const renderMainPage = () => {
|
||||
const mainDeviceId = installedDevices?.main?.id;
|
||||
|
||||
switch (pageName) {
|
||||
case 'home':
|
||||
return <HomePage />;
|
||||
case 'project':
|
||||
return <Project />;
|
||||
case 'operators':
|
||||
return <Operators />;
|
||||
case 'cableId':
|
||||
return <CableId />;
|
||||
case 'result':
|
||||
return <Result />;
|
||||
case 'tools':
|
||||
return <Tools />;
|
||||
case 'testConfig':
|
||||
return <TestConfig />;
|
||||
case 'menulist':
|
||||
return <MenuList/>
|
||||
case 'testing':
|
||||
return <Testing/>
|
||||
case 'resultinfo':
|
||||
return <ResultInfo/>
|
||||
case 'copperperformance':
|
||||
return <CopperPerformance/>
|
||||
|
||||
// 可以添加更多页面
|
||||
switch (mainDeviceId) {
|
||||
case 'dsx':
|
||||
return <DSXDisplay />;
|
||||
case 'est-analyzer':
|
||||
return <EstAnalyzerDisplay />;
|
||||
case 'wifi':
|
||||
return <WiFiDisplay />;
|
||||
default:
|
||||
return <HomePage />;
|
||||
// 如果没有安装主设备,显示默认页面
|
||||
return (
|
||||
<div className="w-[480px] h-[640px] flex flex-col overflow-hidden items-center justify-center">
|
||||
<div className="text-center">
|
||||
<h1 className="text-xl font-bold text-[#0ff] mb-4">请安装设备</h1>
|
||||
<p className="text-gray-600">请从左侧拖拽一个主设备到工作区域</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const handleClick = () => {
|
||||
if (touchSound) {
|
||||
touchSound.currentTime = 0;
|
||||
touchSound.play();
|
||||
play('keyClick');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className="w-[480px] h-[640px] bg-[#fff] flex flex-col overflow-hidden"
|
||||
onClick={handleClick}
|
||||
>
|
||||
{toastMessage && <Toast />}
|
||||
{renderPage()}
|
||||
</div>
|
||||
);
|
||||
return renderMainPage();
|
||||
}
|
||||
|
||||
504
src/components/DisplayMainPage/ILData.js
Normal file
504
src/components/DisplayMainPage/ILData.js
Normal file
@@ -0,0 +1,504 @@
|
||||
const ILData = {
|
||||
1: 0.4,
|
||||
2: 0.4,
|
||||
3: 0.5,
|
||||
4: 0.6,
|
||||
5: 0.7,
|
||||
6: 0.7,
|
||||
7: 0.8,
|
||||
8: 0.9,
|
||||
9: 0.9,
|
||||
10: 1.0,
|
||||
11: 1.0,
|
||||
12: 1.1,
|
||||
13: 1.1,
|
||||
14: 1.2,
|
||||
15: 1.2,
|
||||
16: 1.2,
|
||||
17: 1.3,
|
||||
18: 1.3,
|
||||
19: 1.4,
|
||||
20: 1.4,
|
||||
21: 1.4,
|
||||
22: 1.5,
|
||||
23: 1.5,
|
||||
24: 1.5,
|
||||
25: 1.6,
|
||||
26: 1.6,
|
||||
27: 1.6,
|
||||
28: 1.7,
|
||||
29: 1.7,
|
||||
30: 1.7,
|
||||
31: 1.7,
|
||||
32: 1.8,
|
||||
33: 1.8,
|
||||
34: 1.8,
|
||||
35: 1.9,
|
||||
36: 1.9,
|
||||
37: 1.9,
|
||||
38: 1.9,
|
||||
39: 2.0,
|
||||
40: 2.0,
|
||||
41: 2.0,
|
||||
42: 2.0,
|
||||
43: 2.1,
|
||||
44: 2.1,
|
||||
45: 2.1,
|
||||
46: 2.1,
|
||||
47: 2.2,
|
||||
48: 2.2,
|
||||
49: 2.2,
|
||||
50: 2.2,
|
||||
51: 2.3,
|
||||
52: 2.3,
|
||||
53: 2.3,
|
||||
54: 2.3,
|
||||
55: 2.3,
|
||||
56: 2.4,
|
||||
57: 2.4,
|
||||
58: 2.4,
|
||||
59: 2.4,
|
||||
60: 2.5,
|
||||
61: 2.5,
|
||||
62: 2.5,
|
||||
63: 2.5,
|
||||
64: 2.5,
|
||||
65: 2.6,
|
||||
66: 2.6,
|
||||
67: 2.6,
|
||||
68: 2.6,
|
||||
69: 2.6,
|
||||
70: 2.7,
|
||||
71: 2.7,
|
||||
72: 2.7,
|
||||
73: 2.7,
|
||||
74: 2.7,
|
||||
75: 2.8,
|
||||
76: 2.8,
|
||||
77: 2.8,
|
||||
78: 2.8,
|
||||
79: 2.8,
|
||||
80: 2.8,
|
||||
81: 2.9,
|
||||
82: 2.9,
|
||||
83: 2.9,
|
||||
84: 2.9,
|
||||
85: 2.9,
|
||||
86: 3.0,
|
||||
87: 3.0,
|
||||
88: 3.0,
|
||||
89: 3.0,
|
||||
90: 3.0,
|
||||
91: 3.1,
|
||||
92: 3.1,
|
||||
93: 3.1,
|
||||
94: 3.1,
|
||||
95: 3.1,
|
||||
96: 3.1,
|
||||
97: 3.2,
|
||||
98: 3.2,
|
||||
99: 3.2,
|
||||
100: 3.2,
|
||||
101: 3.2,
|
||||
102: 3.2,
|
||||
103: 3.3,
|
||||
104: 3.3,
|
||||
105: 3.3,
|
||||
106: 3.3,
|
||||
107: 3.3,
|
||||
108: 3.3,
|
||||
109: 3.4,
|
||||
110: 3.4,
|
||||
111: 3.4,
|
||||
112: 3.4,
|
||||
113: 3.4,
|
||||
114: 3.4,
|
||||
115: 3.4,
|
||||
116: 3.5,
|
||||
117: 3.5,
|
||||
118: 3.5,
|
||||
119: 3.5,
|
||||
120: 3.5,
|
||||
121: 3.5,
|
||||
122: 3.6,
|
||||
123: 3.6,
|
||||
124: 3.6,
|
||||
125: 3.6,
|
||||
126: 3.6,
|
||||
127: 3.6,
|
||||
128: 3.6,
|
||||
129: 3.7,
|
||||
130: 3.7,
|
||||
131: 3.7,
|
||||
132: 3.7,
|
||||
133: 3.7,
|
||||
134: 3.7,
|
||||
135: 3.7,
|
||||
136: 3.8,
|
||||
137: 3.8,
|
||||
138: 3.8,
|
||||
139: 3.8,
|
||||
140: 3.8,
|
||||
141: 3.8,
|
||||
142: 3.9,
|
||||
143: 3.9,
|
||||
144: 3.9,
|
||||
145: 3.9,
|
||||
146: 3.9,
|
||||
147: 3.9,
|
||||
148: 4.0,
|
||||
149: 4.0,
|
||||
150: 4.0,
|
||||
151: 4.0,
|
||||
152: 4.0,
|
||||
153: 4.0,
|
||||
154: 4.0,
|
||||
155: 4.0,
|
||||
156: 4.1,
|
||||
157: 4.1,
|
||||
158: 4.1,
|
||||
159: 4.1,
|
||||
160: 4.2,
|
||||
161: 4.2,
|
||||
162: 4.2,
|
||||
163: 4.2,
|
||||
164: 4.2,
|
||||
165: 4.2,
|
||||
166: 4.2,
|
||||
167: 4.2,
|
||||
168: 4.2,
|
||||
169: 4.3,
|
||||
170: 4.3,
|
||||
171: 4.3,
|
||||
172: 4.3,
|
||||
173: 4.3,
|
||||
174: 4.3,
|
||||
175: 4.3,
|
||||
176: 4.3,
|
||||
177: 4.3,
|
||||
178: 4.4,
|
||||
179: 4.4,
|
||||
180: 4.4,
|
||||
181: 4.4,
|
||||
182: 4.4,
|
||||
183: 4.4,
|
||||
184: 4.5,
|
||||
185: 4.5,
|
||||
186: 4.5,
|
||||
187: 4.5,
|
||||
188: 4.5,
|
||||
189: 4.5,
|
||||
190: 4.5,
|
||||
191: 4.6,
|
||||
192: 4.6,
|
||||
193: 4.6,
|
||||
194: 4.7,
|
||||
195: 4.7,
|
||||
196: 4.6,
|
||||
197: 4.6,
|
||||
198: 4.7,
|
||||
199: 4.7,
|
||||
200: 4.7,
|
||||
201: 4.7,
|
||||
202: 4.7,
|
||||
203: 4.8,
|
||||
204: 4.8,
|
||||
205: 4.8,
|
||||
206: 4.8,
|
||||
207: 4.8,
|
||||
208: 4.8,
|
||||
209: 4.8,
|
||||
210: 4.8,
|
||||
211: 4.8,
|
||||
212: 4.8,
|
||||
213: 4.9,
|
||||
214: 4.9,
|
||||
215: 4.9,
|
||||
216: 4.9,
|
||||
217: 4.9,
|
||||
218: 4.9,
|
||||
219: 4.9,
|
||||
220: 4.9,
|
||||
221: 4.9,
|
||||
222: 4.9,
|
||||
223: 4.9,
|
||||
224: 5.0,
|
||||
225: 5.0,
|
||||
226: 5.0,
|
||||
227: 5.0,
|
||||
228: 5.0,
|
||||
229: 5.0,
|
||||
230: 5.0,
|
||||
231: 5.0,
|
||||
232: 5.0,
|
||||
233: 5.0,
|
||||
234: 5.1,
|
||||
235: 5.1,
|
||||
236: 5.1,
|
||||
237: 5.1,
|
||||
238: 5.1,
|
||||
239: 5.1,
|
||||
240: 5.1,
|
||||
241: 5.1,
|
||||
242: 5.1,
|
||||
243: 5.2,
|
||||
244: 5.2,
|
||||
245: 5.2,
|
||||
246: 5.2,
|
||||
247: 5.2,
|
||||
248: 5.2,
|
||||
249: 5.3,
|
||||
250: 5.3,
|
||||
251: 5.3,
|
||||
252: 5.3,
|
||||
253: 5.3,
|
||||
254: 5.3,
|
||||
255: 5.3,
|
||||
256: 5.3,
|
||||
257: 5.3,
|
||||
258: 5.3,
|
||||
259: 5.4,
|
||||
260: 5.4,
|
||||
261: 5.4,
|
||||
262: 5.4,
|
||||
263: 5.4,
|
||||
264: 5.4,
|
||||
265: 5.5,
|
||||
266: 5.5,
|
||||
267: 5.4,
|
||||
268: 5.4,
|
||||
269: 5.4,
|
||||
270: 5.4,
|
||||
271: 5.5,
|
||||
272: 5.4,
|
||||
273: 5.4,
|
||||
274: 5.5,
|
||||
275: 5.5,
|
||||
276: 5.5,
|
||||
277: 5.5,
|
||||
278: 5.5,
|
||||
279: 5.5,
|
||||
280: 5.5,
|
||||
281: 5.5,
|
||||
282: 5.5,
|
||||
283: 5.5,
|
||||
284: 5.5,
|
||||
285: 5.5,
|
||||
286: 5.5,
|
||||
287: 5.5,
|
||||
288: 5.5,
|
||||
289: 5.6,
|
||||
290: 5.6,
|
||||
291: 5.6,
|
||||
292: 5.6,
|
||||
293: 5.6,
|
||||
294: 5.6,
|
||||
295: 5.6,
|
||||
296: 5.7,
|
||||
297: 5.7,
|
||||
298: 5.7,
|
||||
299: 5.7,
|
||||
300: 5.7,
|
||||
301: 5.7,
|
||||
302: 5.7,
|
||||
303: 5.7,
|
||||
304: 5.7,
|
||||
305: 5.8,
|
||||
306: 5.8,
|
||||
307: 5.8,
|
||||
308: 5.7,
|
||||
309: 5.8,
|
||||
310: 5.8,
|
||||
311: 5.8,
|
||||
312: 5.8,
|
||||
313: 5.8,
|
||||
314: 5.8,
|
||||
315: 5.8,
|
||||
316: 5.9,
|
||||
317: 5.9,
|
||||
318: 5.9,
|
||||
319: 5.9,
|
||||
320: 5.9,
|
||||
321: 6.0,
|
||||
322: 6.0,
|
||||
323: 6.0,
|
||||
324: 6.0,
|
||||
325: 5.9,
|
||||
326: 5.9,
|
||||
327: 6.0,
|
||||
328: 6.0,
|
||||
329: 6.0,
|
||||
330: 6.0,
|
||||
331: 6.0,
|
||||
332: 6.0,
|
||||
333: 6.0,
|
||||
334: 6.0,
|
||||
335: 6.0,
|
||||
336: 6.0,
|
||||
337: 6.0,
|
||||
338: 6.0,
|
||||
339: 6.0,
|
||||
340: 6.0,
|
||||
341: 6.0,
|
||||
342: 6.0,
|
||||
343: 6.0,
|
||||
344: 6.1,
|
||||
345: 6.1,
|
||||
346: 6.1,
|
||||
347: 6.1,
|
||||
348: 6.1,
|
||||
349: 6.1,
|
||||
350: 6.1,
|
||||
351: 6.1,
|
||||
352: 6.1,
|
||||
353: 6.2,
|
||||
354: 6.2,
|
||||
355: 6.2,
|
||||
356: 6.2,
|
||||
357: 6.2,
|
||||
358: 6.2,
|
||||
359: 6.2,
|
||||
360: 6.3,
|
||||
361: 6.3,
|
||||
362: 6.3,
|
||||
363: 6.3,
|
||||
364: 6.3,
|
||||
365: 6.3,
|
||||
366: 6.3,
|
||||
367: 6.3,
|
||||
368: 6.4,
|
||||
369: 6.4,
|
||||
370: 6.3,
|
||||
371: 6.4,
|
||||
372: 6.4,
|
||||
373: 6.4,
|
||||
374: 6.4,
|
||||
375: 6.4,
|
||||
376: 6.4,
|
||||
377: 6.4,
|
||||
378: 6.4,
|
||||
379: 6.4,
|
||||
380: 6.4,
|
||||
381: 6.4,
|
||||
382: 6.4,
|
||||
383: 6.4,
|
||||
384: 6.4,
|
||||
385: 6.4,
|
||||
386: 6.4,
|
||||
387: 6.4,
|
||||
388: 6.4,
|
||||
389: 6.5,
|
||||
390: 6.5,
|
||||
391: 6.4,
|
||||
392: 6.4,
|
||||
393: 6.5,
|
||||
394: 6.5,
|
||||
395: 6.5,
|
||||
396: 6.5,
|
||||
397: 6.5,
|
||||
398: 6.5,
|
||||
399: 6.5,
|
||||
400: 6.5,
|
||||
401: 6.5,
|
||||
402: 6.5,
|
||||
403: 6.5,
|
||||
404: 6.5,
|
||||
405: 6.5,
|
||||
406: 6.5,
|
||||
407: 6.6,
|
||||
408: 6.6,
|
||||
409: 6.6,
|
||||
410: 6.6,
|
||||
411: 6.6,
|
||||
412: 6.6,
|
||||
413: 6.6,
|
||||
414: 6.6,
|
||||
415: 6.6,
|
||||
416: 6.6,
|
||||
417: 6.6,
|
||||
418: 6.7,
|
||||
419: 6.7,
|
||||
420: 6.7,
|
||||
421: 6.7,
|
||||
422: 6.7,
|
||||
423: 6.7,
|
||||
424: 6.7,
|
||||
425: 6.7,
|
||||
426: 6.7,
|
||||
427: 6.7,
|
||||
428: 6.7,
|
||||
429: 6.7,
|
||||
430: 6.7,
|
||||
431: 6.7,
|
||||
432: 6.7,
|
||||
433: 6.7,
|
||||
434: 6.8,
|
||||
435: 6.8,
|
||||
436: 6.8,
|
||||
437: 6.8,
|
||||
438: 6.7,
|
||||
439: 6.7,
|
||||
440: 6.8,
|
||||
441: 6.8,
|
||||
442: 6.8,
|
||||
443: 6.8,
|
||||
444: 6.8,
|
||||
445: 6.8,
|
||||
446: 6.8,
|
||||
447: 6.8,
|
||||
448: 6.8,
|
||||
449: 6.8,
|
||||
450: 6.8,
|
||||
451: 6.8,
|
||||
452: 6.8,
|
||||
453: 6.8,
|
||||
454: 6.9,
|
||||
455: 6.9,
|
||||
456: 6.9,
|
||||
457: 6.9,
|
||||
458: 6.9,
|
||||
459: 6.9,
|
||||
460: 6.9,
|
||||
461: 7.0,
|
||||
462: 7.0,
|
||||
463: 7.0,
|
||||
464: 7.0,
|
||||
465: 7.0,
|
||||
466: 7.0,
|
||||
467: 7.0,
|
||||
468: 7.0,
|
||||
469: 7.1,
|
||||
470: 7.1,
|
||||
471: 7.1,
|
||||
472: 7.1,
|
||||
473: 7.1,
|
||||
474: 7.2,
|
||||
475: 7.2,
|
||||
476: 7.2,
|
||||
477: 7.2,
|
||||
478: 7.2,
|
||||
479: 7.2,
|
||||
480: 7.2,
|
||||
481: 7.2,
|
||||
482: 7.3,
|
||||
483: 7.3,
|
||||
484: 7.3,
|
||||
485: 7.3,
|
||||
486: 7.4,
|
||||
487: 7.4,
|
||||
488: 7.4,
|
||||
489: 7.4,
|
||||
490: 7.4,
|
||||
491: 7.4,
|
||||
492: 7.4,
|
||||
493: 7.4,
|
||||
494: 7.4,
|
||||
495: 7.5,
|
||||
496: 7.5,
|
||||
497: 7.5,
|
||||
498: 7.5,
|
||||
499: 7.5,
|
||||
500: 7.5,
|
||||
};
|
||||
|
||||
export default ILData;
|
||||
504
src/components/DisplayMainPage/NEXTData.js
Normal file
504
src/components/DisplayMainPage/NEXTData.js
Normal file
@@ -0,0 +1,504 @@
|
||||
const NEXTData = {
|
||||
1: 99.1,
|
||||
2: 89.5,
|
||||
3: 84.4,
|
||||
4: 79.7,
|
||||
5: 78.1,
|
||||
6: 77.9,
|
||||
7: 82.2,
|
||||
8: 94.6,
|
||||
9: 79.5,
|
||||
10: 73.2,
|
||||
11: 69.4,
|
||||
12: 67.9,
|
||||
13: 67.5,
|
||||
14: 68.5,
|
||||
15: 70.8,
|
||||
16: 75.6,
|
||||
17: 82.0,
|
||||
18: 85.5,
|
||||
19: 85.4,
|
||||
20: 80.5,
|
||||
21: 74.9,
|
||||
22: 70.7,
|
||||
23: 68.6,
|
||||
24: 67.7,
|
||||
25: 68.6,
|
||||
26: 71.1,
|
||||
27: 76.8,
|
||||
28: 80.7,
|
||||
29: 74.7,
|
||||
30: 72.0,
|
||||
31: 73.0,
|
||||
32: 78.9,
|
||||
33: 82.2,
|
||||
34: 70.6,
|
||||
35: 65.9,
|
||||
36: 63.9,
|
||||
37: 63.5,
|
||||
38: 64.9,
|
||||
39: 69.0,
|
||||
40: 74.7,
|
||||
41: 67.9,
|
||||
42: 63.6,
|
||||
43: 61.8,
|
||||
44: 62.0,
|
||||
45: 64.7,
|
||||
46: 71.7,
|
||||
47: 74.9,
|
||||
48: 64.9,
|
||||
49: 61.2,
|
||||
50: 60.0,
|
||||
51: 60.6,
|
||||
52: 61.9,
|
||||
53: 61.8,
|
||||
54: 59.6,
|
||||
55: 57.3,
|
||||
56: 55.9,
|
||||
57: 55.8,
|
||||
58: 57.3,
|
||||
59: 60.3,
|
||||
60: 63.0,
|
||||
61: 61.4,
|
||||
62: 58.5,
|
||||
63: 56.9,
|
||||
64: 57.1,
|
||||
65: 59.2,
|
||||
66: 64.0,
|
||||
67: 68.1,
|
||||
68: 64.4,
|
||||
69: 61.7,
|
||||
70: 61.6,
|
||||
71: 64.9,
|
||||
72: 72.0,
|
||||
73: 63.7,
|
||||
74: 58.9,
|
||||
75: 56.6,
|
||||
76: 55.9,
|
||||
77: 57.0,
|
||||
78: 60.4,
|
||||
79: 66.1,
|
||||
80: 61.8,
|
||||
81: 57.7,
|
||||
82: 55.8,
|
||||
83: 55.6,
|
||||
84: 57.3,
|
||||
85: 62.3,
|
||||
86: 68.3,
|
||||
87: 60.4,
|
||||
88: 56.4,
|
||||
89: 54.9,
|
||||
90: 55.1,
|
||||
91: 57.0,
|
||||
92: 61.9,
|
||||
93: 77.8,
|
||||
94: 67.1,
|
||||
95: 62.4,
|
||||
96: 61.7,
|
||||
97: 65.3,
|
||||
98: 79.1,
|
||||
99: 63.0,
|
||||
100: 57.6,
|
||||
101: 55.2,
|
||||
102: 54.7,
|
||||
103: 55.5,
|
||||
104: 58.0,
|
||||
105: 64.2,
|
||||
106: 75.9,
|
||||
107: 62.8,
|
||||
108: 59.6,
|
||||
109: 58.9,
|
||||
110: 60.2,
|
||||
111: 65.0,
|
||||
112: 100.7,
|
||||
113: 64.4,
|
||||
114: 59.4,
|
||||
115: 57.2,
|
||||
116: 55.9,
|
||||
117: 55.4,
|
||||
118: 55.4,
|
||||
119: 55.1,
|
||||
120: 54.8,
|
||||
121: 55.5,
|
||||
122: 57.8,
|
||||
123: 59.7,
|
||||
124: 59.3,
|
||||
125: 57.8,
|
||||
126: 56.3,
|
||||
127: 55.8,
|
||||
128: 57.2,
|
||||
129: 61.2,
|
||||
130: 70.5,
|
||||
131: 68.7,
|
||||
132: 61.2,
|
||||
133: 59.2,
|
||||
134: 60.2,
|
||||
135: 59.8,
|
||||
136: 55.9,
|
||||
137: 53.3,
|
||||
138: 51.4,
|
||||
139: 50.5,
|
||||
140: 50.8,
|
||||
141: 53.1,
|
||||
142: 57.5,
|
||||
143: 56.8,
|
||||
144: 53.4,
|
||||
145: 51.3,
|
||||
146: 50.5,
|
||||
147: 51.2,
|
||||
148: 53.7,
|
||||
149: 56.0,
|
||||
150: 55.5,
|
||||
151: 54.6,
|
||||
152: 54.3,
|
||||
153: 54.8,
|
||||
154: 56.4,
|
||||
155: 56.7,
|
||||
156: 54.0,
|
||||
157: 52.2,
|
||||
158: 52.3,
|
||||
159: 54.0,
|
||||
160: 57.3,
|
||||
161: 60.2,
|
||||
162: 57.2,
|
||||
163: 54.0,
|
||||
164: 53.1,
|
||||
165: 54.4,
|
||||
166: 57.0,
|
||||
167: 58.0,
|
||||
168: 56.7,
|
||||
169: 54.9,
|
||||
170: 53.7,
|
||||
171: 55.0,
|
||||
172: 59.3,
|
||||
173: 61.9,
|
||||
174: 56.9,
|
||||
175: 53.7,
|
||||
176: 51.5,
|
||||
177: 50.4,
|
||||
178: 50.9,
|
||||
179: 53.0,
|
||||
180: 57.3,
|
||||
181: 68.1,
|
||||
182: 62.0,
|
||||
183: 54.9,
|
||||
184: 52.7,
|
||||
185: 53.2,
|
||||
186: 55.9,
|
||||
187: 59.0,
|
||||
188: 55.4,
|
||||
189: 51.0,
|
||||
190: 48.9,
|
||||
191: 49.3,
|
||||
192: 52.7,
|
||||
193: 61.4,
|
||||
194: 60.8,
|
||||
195: 52.8,
|
||||
196: 49.7,
|
||||
197: 49.4,
|
||||
198: 52.3,
|
||||
199: 61.7,
|
||||
200: 57.0,
|
||||
201: 50.6,
|
||||
202: 48.2,
|
||||
203: 48.1,
|
||||
204: 50.5,
|
||||
205: 57.9,
|
||||
206: 58.4,
|
||||
207: 51.1,
|
||||
208: 48.6,
|
||||
209: 48.3,
|
||||
210: 49.8,
|
||||
211: 54.1,
|
||||
212: 56.3,
|
||||
213: 51.3,
|
||||
214: 49.1,
|
||||
215: 48.9,
|
||||
216: 49.9,
|
||||
217: 51.5,
|
||||
218: 51.5,
|
||||
219: 49.3,
|
||||
220: 47.8,
|
||||
221: 47.9,
|
||||
222: 49.8,
|
||||
223: 53.2,
|
||||
224: 56.6,
|
||||
225: 54.7,
|
||||
226: 51.5,
|
||||
227: 50.3,
|
||||
228: 50.3,
|
||||
229: 49.9,
|
||||
230: 48.7,
|
||||
231: 48.0,
|
||||
232: 47.5,
|
||||
233: 46.4,
|
||||
234: 45.1,
|
||||
235: 44.5,
|
||||
236: 44.6,
|
||||
237: 45.6,
|
||||
238: 47.7,
|
||||
239: 49.8,
|
||||
240: 48.6,
|
||||
241: 47.3,
|
||||
242: 47.3,
|
||||
243: 47.3,
|
||||
244: 47.7,
|
||||
245: 48.2,
|
||||
246: 46.9,
|
||||
247: 45.3,
|
||||
248: 45.3,
|
||||
249: 47.1,
|
||||
250: 50.1,
|
||||
251: 52.0,
|
||||
252: 48.3,
|
||||
253: 44.8,
|
||||
254: 43.7,
|
||||
255: 44.7,
|
||||
256: 46.7,
|
||||
257: 47.4,
|
||||
258: 46.3,
|
||||
259: 44.5,
|
||||
260: 43.3,
|
||||
261: 43.8,
|
||||
262: 46.0,
|
||||
263: 48.7,
|
||||
264: 47.8,
|
||||
265: 45.2,
|
||||
266: 43.6,
|
||||
267: 43.4,
|
||||
268: 45.0,
|
||||
269: 48.5,
|
||||
270: 53.9,
|
||||
271: 52.7,
|
||||
272: 48.5,
|
||||
273: 46.4,
|
||||
274: 45.8,
|
||||
275: 46.5,
|
||||
276: 47.6,
|
||||
277: 47.5,
|
||||
278: 46.2,
|
||||
279: 45.3,
|
||||
280: 45.1,
|
||||
281: 46.1,
|
||||
282: 48.3,
|
||||
283: 50.4,
|
||||
284: 49.0,
|
||||
285: 46.6,
|
||||
286: 45.5,
|
||||
287: 45.6,
|
||||
288: 46.8,
|
||||
289: 48.6,
|
||||
290: 48.7,
|
||||
291: 47.2,
|
||||
292: 46.6,
|
||||
293: 47.6,
|
||||
294: 50.8,
|
||||
295: 60.9,
|
||||
296: 55.9,
|
||||
297: 48.3,
|
||||
298: 45.6,
|
||||
299: 45.3,
|
||||
300: 46.7,
|
||||
301: 50.4,
|
||||
302: 55.8,
|
||||
303: 49.8,
|
||||
304: 45.8,
|
||||
305: 44.5,
|
||||
306: 44.6,
|
||||
307: 45.2,
|
||||
308: 45.7,
|
||||
309: 45.2,
|
||||
310: 43.4,
|
||||
311: 42.1,
|
||||
312: 41.8,
|
||||
313: 42.4,
|
||||
314: 43.7,
|
||||
315: 45.2,
|
||||
316: 44.9,
|
||||
317: 43.2,
|
||||
318: 42.0,
|
||||
319: 41.8,
|
||||
320: 42.4,
|
||||
321: 44.1,
|
||||
322: 47.4,
|
||||
323: 51.4,
|
||||
324: 52.4,
|
||||
325: 52.8,
|
||||
326: 54.2,
|
||||
327: 51.9,
|
||||
328: 48.7,
|
||||
329: 46.2,
|
||||
330: 44.8,
|
||||
331: 45.0,
|
||||
332: 46.5,
|
||||
333: 47.8,
|
||||
334: 47.2,
|
||||
335: 46.0,
|
||||
336: 45.2,
|
||||
337: 45.3,
|
||||
338: 46.1,
|
||||
339: 46.2,
|
||||
340: 44.4,
|
||||
341: 42.2,
|
||||
342: 40.8,
|
||||
343: 40.1,
|
||||
344: 39.9,
|
||||
345: 40.0,
|
||||
346: 40.4,
|
||||
347: 41.0,
|
||||
348: 41.9,
|
||||
349: 43.2,
|
||||
350: 44.5,
|
||||
351: 45.6,
|
||||
352: 47.6,
|
||||
353: 51.0,
|
||||
354: 51.7,
|
||||
355: 48.4,
|
||||
356: 45.5,
|
||||
357: 43.8,
|
||||
358: 44.0,
|
||||
359: 46.1,
|
||||
360: 47.9,
|
||||
361: 45.2,
|
||||
362: 42.1,
|
||||
363: 40.2,
|
||||
364: 39.7,
|
||||
365: 40.6,
|
||||
366: 42.8,
|
||||
367: 44.6,
|
||||
368: 43.1,
|
||||
369: 41.3,
|
||||
370: 40.9,
|
||||
371: 42.3,
|
||||
372: 46.0,
|
||||
373: 51.8,
|
||||
374: 48.1,
|
||||
375: 44.6,
|
||||
376: 44.1,
|
||||
377: 45.8,
|
||||
378: 49.3,
|
||||
379: 49.1,
|
||||
380: 45.1,
|
||||
381: 43.4,
|
||||
382: 44.6,
|
||||
383: 49.5,
|
||||
384: 51.6,
|
||||
385: 43.7,
|
||||
386: 39.6,
|
||||
387: 37.8,
|
||||
388: 37.5,
|
||||
389: 38.4,
|
||||
390: 39.9,
|
||||
391: 40.8,
|
||||
392: 40.4,
|
||||
393: 39.5,
|
||||
394: 38.9,
|
||||
395: 39.0,
|
||||
396: 39.6,
|
||||
397: 40.3,
|
||||
398: 41.1,
|
||||
399: 42.0,
|
||||
400: 42.9,
|
||||
401: 43.7,
|
||||
402: 44.3,
|
||||
403: 44.7,
|
||||
404: 45.4,
|
||||
405: 47.4,
|
||||
406: 51.5,
|
||||
407: 59.4,
|
||||
408: 68.2,
|
||||
409: 63.1,
|
||||
410: 58.6,
|
||||
411: 50.9,
|
||||
412: 45.7,
|
||||
413: 42.8,
|
||||
414: 41.7,
|
||||
415: 42.2,
|
||||
416: 44.9,
|
||||
417: 49.0,
|
||||
418: 46.8,
|
||||
419: 42.5,
|
||||
420: 40.3,
|
||||
421: 40.0,
|
||||
422: 41.7,
|
||||
423: 44.6,
|
||||
424: 43.8,
|
||||
425: 40.6,
|
||||
426: 38.8,
|
||||
427: 38.6,
|
||||
428: 40.6,
|
||||
429: 45.5,
|
||||
430: 47.4,
|
||||
431: 41.6,
|
||||
432: 38.6,
|
||||
433: 37.7,
|
||||
434: 38.5,
|
||||
435: 41.2,
|
||||
436: 45.2,
|
||||
437: 43.2,
|
||||
438: 39.7,
|
||||
439: 37.9,
|
||||
440: 37.6,
|
||||
441: 38.7,
|
||||
442: 41.7,
|
||||
443: 46.4,
|
||||
444: 46.4,
|
||||
445: 43.8,
|
||||
446: 42.5,
|
||||
447: 42.6,
|
||||
448: 43.8,
|
||||
449: 45.1,
|
||||
450: 44.5,
|
||||
451: 43.6,
|
||||
452: 43.8,
|
||||
453: 45.4,
|
||||
454: 47.0,
|
||||
455: 45.7,
|
||||
456: 42.4,
|
||||
457: 39.8,
|
||||
458: 38.5,
|
||||
459: 38.2,
|
||||
460: 38.9,
|
||||
461: 40.5,
|
||||
462: 43.2,
|
||||
463: 46.6,
|
||||
464: 48.5,
|
||||
465: 49.1,
|
||||
466: 48.4,
|
||||
467: 45.0,
|
||||
468: 41.6,
|
||||
469: 39.3,
|
||||
470: 37.8,
|
||||
471: 37.4,
|
||||
472: 38.3,
|
||||
473: 40.8,
|
||||
474: 45.6,
|
||||
475: 51.6,
|
||||
476: 46.2,
|
||||
477: 42.4,
|
||||
478: 41.3,
|
||||
479: 41.8,
|
||||
480: 42.5,
|
||||
481: 40.9,
|
||||
482: 38.3,
|
||||
483: 36.3,
|
||||
484: 35.4,
|
||||
485: 35.8,
|
||||
486: 37.5,
|
||||
487: 40.6,
|
||||
488: 45.5,
|
||||
489: 47.8,
|
||||
490: 44.4,
|
||||
491: 43.0,
|
||||
492: 44.2,
|
||||
493: 47.0,
|
||||
494: 45.7,
|
||||
495: 41.7,
|
||||
496: 39.0,
|
||||
497: 37.8,
|
||||
498: 38.1,
|
||||
499: 39.6,
|
||||
500: 41.7,
|
||||
};
|
||||
|
||||
export default NEXTData;
|
||||
504
src/components/DisplayMainPage/RLData.js
Normal file
504
src/components/DisplayMainPage/RLData.js
Normal file
@@ -0,0 +1,504 @@
|
||||
const RLData = {
|
||||
1: 26.4,
|
||||
2: 25.4,
|
||||
3: 27.7,
|
||||
4: 36.2,
|
||||
5: 37.1,
|
||||
6: 30.3,
|
||||
7: 28.3,
|
||||
8: 28.7,
|
||||
9: 32.0,
|
||||
10: 36.8,
|
||||
11: 35.5,
|
||||
12: 31.7,
|
||||
13: 30.2,
|
||||
14: 30.7,
|
||||
15: 32.6,
|
||||
16: 35.6,
|
||||
17: 36.7,
|
||||
18: 34.1,
|
||||
19: 32.0,
|
||||
20: 31.8,
|
||||
21: 33.1,
|
||||
22: 37.4,
|
||||
23: 44.6,
|
||||
24: 39.8,
|
||||
25: 36.2,
|
||||
26: 35.5,
|
||||
27: 37.5,
|
||||
28: 43.6,
|
||||
29: 50.9,
|
||||
30: 40.9,
|
||||
31: 38.0,
|
||||
32: 37.8,
|
||||
33: 40.0,
|
||||
34: 45.6,
|
||||
35: 55.8,
|
||||
36: 45.0,
|
||||
37: 40.6,
|
||||
38: 39.1,
|
||||
39: 39.0,
|
||||
40: 40.7,
|
||||
41: 44.7,
|
||||
42: 53.2,
|
||||
43: 48.6,
|
||||
44: 42.9,
|
||||
45: 40.8,
|
||||
46: 41.2,
|
||||
47: 43.7,
|
||||
48: 47.0,
|
||||
49: 45.0,
|
||||
50: 41.5,
|
||||
51: 39.8,
|
||||
52: 40.0,
|
||||
53: 42.6,
|
||||
54: 47.7,
|
||||
55: 47.2,
|
||||
56: 41.1,
|
||||
57: 38.2,
|
||||
58: 37.1,
|
||||
59: 38.1,
|
||||
60: 40.9,
|
||||
61: 45.1,
|
||||
62: 45.0,
|
||||
63: 41.5,
|
||||
64: 40.2,
|
||||
65: 41.4,
|
||||
66: 45.6,
|
||||
67: 52.7,
|
||||
68: 45.8,
|
||||
69: 41.1,
|
||||
70: 39.2,
|
||||
71: 38.8,
|
||||
72: 39.4,
|
||||
73: 40.8,
|
||||
74: 43.1,
|
||||
75: 46.7,
|
||||
76: 51.9,
|
||||
77: 49.0,
|
||||
78: 45.2,
|
||||
79: 44.0,
|
||||
80: 44.2,
|
||||
81: 43.8,
|
||||
82: 41.0,
|
||||
83: 37.9,
|
||||
84: 36.2,
|
||||
85: 35.9,
|
||||
86: 37.4,
|
||||
87: 41.6,
|
||||
88: 60.0,
|
||||
89: 42.6,
|
||||
90: 36.6,
|
||||
91: 33.9,
|
||||
92: 33.0,
|
||||
93: 33.5,
|
||||
94: 35.5,
|
||||
95: 39.1,
|
||||
96: 40.6,
|
||||
97: 37.1,
|
||||
98: 34.1,
|
||||
99: 32.7,
|
||||
100: 32.6,
|
||||
101: 33.8,
|
||||
102: 36.1,
|
||||
103: 40.4,
|
||||
104: 49.5,
|
||||
105: 47.7,
|
||||
106: 41.9,
|
||||
107: 39.6,
|
||||
108: 39.0,
|
||||
109: 39.5,
|
||||
110: 40.7,
|
||||
111: 43.2,
|
||||
112: 46.4,
|
||||
113: 46.6,
|
||||
114: 40.7,
|
||||
115: 36.3,
|
||||
116: 33.6,
|
||||
117: 32.3,
|
||||
118: 32.3,
|
||||
119: 33.9,
|
||||
120: 38.1,
|
||||
121: 47.2,
|
||||
122: 40.6,
|
||||
123: 35.4,
|
||||
124: 34.0,
|
||||
125: 34.6,
|
||||
126: 37.0,
|
||||
127: 38.2,
|
||||
128: 35.1,
|
||||
129: 32.5,
|
||||
130: 31.9,
|
||||
131: 33.3,
|
||||
132: 38.1,
|
||||
133: 50.1,
|
||||
134: 37.2,
|
||||
135: 32.8,
|
||||
136: 31.8,
|
||||
137: 33.4,
|
||||
138: 40.1,
|
||||
139: 42.3,
|
||||
140: 32.5,
|
||||
141: 28.7,
|
||||
142: 27.3,
|
||||
143: 27.8,
|
||||
144: 30.3,
|
||||
145: 35.6,
|
||||
146: 41.0,
|
||||
147: 34.4,
|
||||
148: 31.6,
|
||||
149: 31.3,
|
||||
150: 33.4,
|
||||
151: 38.4,
|
||||
152: 48.1,
|
||||
153: 43.6,
|
||||
154: 42.1,
|
||||
155: 45.1,
|
||||
156: 41.3,
|
||||
157: 35.2,
|
||||
158: 32.0,
|
||||
159: 30.7,
|
||||
160: 30.7,
|
||||
161: 31.0,
|
||||
162: 29.9,
|
||||
163: 28.1,
|
||||
164: 27.0,
|
||||
165: 26.9,
|
||||
166: 28.2,
|
||||
167: 30.8,
|
||||
168: 33.1,
|
||||
169: 31.9,
|
||||
170: 30.1,
|
||||
171: 29.9,
|
||||
172: 31.7,
|
||||
173: 36.3,
|
||||
174: 44.3,
|
||||
175: 38.1,
|
||||
176: 34.9,
|
||||
177: 35.2,
|
||||
178: 39.2,
|
||||
179: 45.7,
|
||||
180: 39.2,
|
||||
181: 36.4,
|
||||
182: 38.2,
|
||||
183: 48.8,
|
||||
184: 39.2,
|
||||
185: 32.2,
|
||||
186: 29.4,
|
||||
187: 29.2,
|
||||
188: 32.0,
|
||||
189: 41.9,
|
||||
190: 35.6,
|
||||
191: 28.4,
|
||||
192: 25.6,
|
||||
193: 24.9,
|
||||
194: 26.2,
|
||||
195: 29.5,
|
||||
196: 34.2,
|
||||
197: 32.5,
|
||||
198: 29.4,
|
||||
199: 29.1,
|
||||
200: 31.9,
|
||||
201: 42.6,
|
||||
202: 35.5,
|
||||
203: 28.8,
|
||||
204: 26.4,
|
||||
205: 26.2,
|
||||
206: 28.0,
|
||||
207: 32.4,
|
||||
208: 37.3,
|
||||
209: 34.2,
|
||||
210: 32.8,
|
||||
211: 34.7,
|
||||
212: 36.1,
|
||||
213: 30.7,
|
||||
214: 26.8,
|
||||
215: 24.9,
|
||||
216: 25.1,
|
||||
217: 27.4,
|
||||
218: 33.1,
|
||||
219: 38.1,
|
||||
220: 30.6,
|
||||
221: 27.9,
|
||||
222: 28.2,
|
||||
223: 31.4,
|
||||
224: 38.6,
|
||||
225: 33.9,
|
||||
226: 28.9,
|
||||
227: 28.3,
|
||||
228: 30.3,
|
||||
229: 34.4,
|
||||
230: 33.2,
|
||||
231: 28.7,
|
||||
232: 26.3,
|
||||
233: 26.1,
|
||||
234: 28.4,
|
||||
235: 35.9,
|
||||
236: 40.2,
|
||||
237: 31.2,
|
||||
238: 29.1,
|
||||
239: 30.0,
|
||||
240: 37.5,
|
||||
241: 41.2,
|
||||
242: 30.7,
|
||||
243: 27.7,
|
||||
244: 28.1,
|
||||
245: 31.9,
|
||||
246: 56.8,
|
||||
247: 31.6,
|
||||
248: 26.4,
|
||||
249: 24.7,
|
||||
250: 25.2,
|
||||
251: 28.7,
|
||||
252: 39.7,
|
||||
253: 35.1,
|
||||
254: 28.7,
|
||||
255: 27.5,
|
||||
256: 30.0,
|
||||
257: 39.7,
|
||||
258: 32.1,
|
||||
259: 25.9,
|
||||
260: 23.5,
|
||||
261: 23.8,
|
||||
262: 27.0,
|
||||
263: 38.2,
|
||||
264: 31.1,
|
||||
265: 24.6,
|
||||
266: 22.5,
|
||||
267: 22.5,
|
||||
268: 24.8,
|
||||
269: 30.9,
|
||||
270: 37.7,
|
||||
271: 28.5,
|
||||
272: 25.2,
|
||||
273: 24.9,
|
||||
274: 26.2,
|
||||
275: 28.1,
|
||||
276: 28.3,
|
||||
277: 27.7,
|
||||
278: 28.2,
|
||||
279: 30.9,
|
||||
280: 32.9,
|
||||
281: 29.0,
|
||||
282: 25.9,
|
||||
283: 24.9,
|
||||
284: 26.3,
|
||||
285: 30.0,
|
||||
286: 31.1,
|
||||
287: 26.6,
|
||||
288: 24.6,
|
||||
289: 24.8,
|
||||
290: 27.7,
|
||||
291: 33.9,
|
||||
292: 29.0,
|
||||
293: 24.2,
|
||||
294: 22.6,
|
||||
295: 22.9,
|
||||
296: 25.8,
|
||||
297: 31.8,
|
||||
298: 30.3,
|
||||
299: 25.4,
|
||||
300: 23.6,
|
||||
301: 24.1,
|
||||
302: 27.2,
|
||||
303: 32.5,
|
||||
304: 30.8,
|
||||
305: 27.0,
|
||||
306: 26.5,
|
||||
307: 28.9,
|
||||
308: 35.6,
|
||||
309: 34.4,
|
||||
310: 28.4,
|
||||
311: 26.6,
|
||||
312: 27.5,
|
||||
313: 32.6,
|
||||
314: 36.9,
|
||||
315: 28.8,
|
||||
316: 25.3,
|
||||
317: 25.3,
|
||||
318: 28.5,
|
||||
319: 37.9,
|
||||
320: 29.5,
|
||||
321: 24.1,
|
||||
322: 22.1,
|
||||
323: 22.1,
|
||||
324: 24.2,
|
||||
325: 28.7,
|
||||
326: 31.0,
|
||||
327: 27.0,
|
||||
328: 25.3,
|
||||
329: 26.0,
|
||||
330: 28.5,
|
||||
331: 28.6,
|
||||
332: 25.1,
|
||||
333: 23.0,
|
||||
334: 22.6,
|
||||
335: 23.5,
|
||||
336: 25.6,
|
||||
337: 25.9,
|
||||
338: 24.7,
|
||||
339: 24.3,
|
||||
340: 25.8,
|
||||
341: 28.4,
|
||||
342: 27.4,
|
||||
343: 23.8,
|
||||
344: 21.7,
|
||||
345: 21.5,
|
||||
346: 23.3,
|
||||
347: 28.3,
|
||||
348: 35.1,
|
||||
349: 30.2,
|
||||
350: 27.5,
|
||||
351: 28.8,
|
||||
352: 33.6,
|
||||
353: 32.6,
|
||||
354: 26.2,
|
||||
355: 23.5,
|
||||
356: 23.6,
|
||||
357: 26.5,
|
||||
358: 39.6,
|
||||
359: 30.0,
|
||||
360: 23.4,
|
||||
361: 21.1,
|
||||
362: 21.4,
|
||||
363: 24.3,
|
||||
364: 29.0,
|
||||
365: 25.4,
|
||||
366: 21.1,
|
||||
367: 19.6,
|
||||
368: 19.9,
|
||||
369: 22.0,
|
||||
370: 23.6,
|
||||
371: 22.0,
|
||||
372: 19.7,
|
||||
373: 18.7,
|
||||
374: 19.5,
|
||||
375: 21.7,
|
||||
376: 24.6,
|
||||
377: 23.5,
|
||||
378: 21.2,
|
||||
379: 20.3,
|
||||
380: 21.1,
|
||||
381: 23.1,
|
||||
382: 24.3,
|
||||
383: 23.0,
|
||||
384: 21.4,
|
||||
385: 21.7,
|
||||
386: 24.2,
|
||||
387: 30.3,
|
||||
388: 32.6,
|
||||
389: 26.3,
|
||||
390: 23.8,
|
||||
391: 23.8,
|
||||
392: 25.4,
|
||||
393: 26.2,
|
||||
394: 24.4,
|
||||
395: 22.8,
|
||||
396: 22.5,
|
||||
397: 23.8,
|
||||
398: 25.0,
|
||||
399: 24.1,
|
||||
400: 22.4,
|
||||
401: 22.0,
|
||||
402: 22.4,
|
||||
403: 24.8,
|
||||
404: 26.5,
|
||||
405: 25.1,
|
||||
406: 23.3,
|
||||
407: 23.2,
|
||||
408: 25.5,
|
||||
409: 29.8,
|
||||
410: 27.7,
|
||||
411: 23.0,
|
||||
412: 20.5,
|
||||
413: 20.5,
|
||||
414: 22.2,
|
||||
415: 25.2,
|
||||
416: 25.3,
|
||||
417: 22.6,
|
||||
418: 21.3,
|
||||
419: 21.7,
|
||||
420: 24.2,
|
||||
421: 28.4,
|
||||
422: 30.2,
|
||||
423: 26.1,
|
||||
424: 24.3,
|
||||
425: 25.3,
|
||||
426: 29.3,
|
||||
427: 42.8,
|
||||
428: 33.8,
|
||||
429: 27.9,
|
||||
430: 26.8,
|
||||
431: 29.0,
|
||||
432: 34.0,
|
||||
433: 31.9,
|
||||
434: 27.3,
|
||||
435: 25.5,
|
||||
436: 26.0,
|
||||
437: 29.0,
|
||||
438: 34.4,
|
||||
439: 31.7,
|
||||
440: 27.6,
|
||||
441: 26.0,
|
||||
442: 26.4,
|
||||
443: 27.4,
|
||||
444: 27.3,
|
||||
445: 26.0,
|
||||
446: 25.2,
|
||||
447: 25.3,
|
||||
448: 26.2,
|
||||
449: 26.7,
|
||||
450: 26.3,
|
||||
451: 25.9,
|
||||
452: 26.5,
|
||||
453: 27.7,
|
||||
454: 27.8,
|
||||
455: 25.8,
|
||||
456: 24.2,
|
||||
457: 23.8,
|
||||
458: 24.9,
|
||||
459: 26.6,
|
||||
460: 26.5,
|
||||
461: 24.4,
|
||||
462: 23.0,
|
||||
463: 22.9,
|
||||
464: 24.4,
|
||||
465: 27.2,
|
||||
466: 28.7,
|
||||
467: 27.1,
|
||||
468: 25.6,
|
||||
469: 25.5,
|
||||
470: 26.1,
|
||||
471: 25.4,
|
||||
472: 23.4,
|
||||
473: 21.8,
|
||||
474: 21.5,
|
||||
475: 22.6,
|
||||
476: 25.8,
|
||||
477: 31.6,
|
||||
478: 32.8,
|
||||
479: 28.6,
|
||||
480: 27.6,
|
||||
481: 29.2,
|
||||
482: 32.0,
|
||||
483: 29.2,
|
||||
484: 25.1,
|
||||
485: 22.8,
|
||||
486: 22.2,
|
||||
487: 22.5,
|
||||
488: 23.5,
|
||||
489: 24.2,
|
||||
490: 24.4,
|
||||
491: 24.2,
|
||||
492: 24.2,
|
||||
493: 24.1,
|
||||
494: 23.6,
|
||||
495: 22.9,
|
||||
496: 22.6,
|
||||
497: 22.8,
|
||||
498: 23.4,
|
||||
499: 24.2,
|
||||
500: 25.2,
|
||||
};
|
||||
|
||||
export default RLData;
|
||||
65
src/components/DisplayMainPage/dsx.js
Normal file
65
src/components/DisplayMainPage/dsx.js
Normal file
@@ -0,0 +1,65 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { getAssetUrl } from '@/utils/asset';
|
||||
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';
|
||||
import { useAudio } from '@/components/AudioProvider';
|
||||
|
||||
export default function DSXDisplay() {
|
||||
|
||||
const { navigation, navigateTo, toastMessage} = useDisplayStore();
|
||||
const { play } = useAudio();
|
||||
|
||||
|
||||
|
||||
const renderPage = () => {
|
||||
const pageName = navigation?.current?.name || 'home';
|
||||
|
||||
switch (pageName) {
|
||||
case 'home':
|
||||
return <HomePage />;
|
||||
case 'project':
|
||||
return <Project />;
|
||||
case 'operators':
|
||||
return <Operators />;
|
||||
case 'cableId':
|
||||
return <CableId />;
|
||||
case 'result':
|
||||
return <Result />;
|
||||
case 'tools':
|
||||
return <Tools />;
|
||||
case 'testConfig':
|
||||
return <TestConfig />;
|
||||
case 'menulist':
|
||||
return <MenuList/>
|
||||
case 'testing':
|
||||
return <Testing/>
|
||||
case 'resultinfo':
|
||||
return <ResultInfo/>
|
||||
case 'copperperformance':
|
||||
return <CopperPerformance/>
|
||||
|
||||
// 可以添加更多页面
|
||||
default:
|
||||
return <HomePage />;
|
||||
}
|
||||
};
|
||||
|
||||
const handleClick = () => {
|
||||
if (touchSound) {
|
||||
touchSound.currentTime = 0;
|
||||
touchSound.play();
|
||||
play('keyClick');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className="w-[480px] h-[640px] bg-[#fff] flex flex-col overflow-hidden"
|
||||
onClick={handleClick}
|
||||
>
|
||||
{toastMessage && <Toast />}
|
||||
{renderPage()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
1097
src/components/DisplayMainPage/est-analyzer.js
Normal file
1097
src/components/DisplayMainPage/est-analyzer.js
Normal file
File diff suppressed because it is too large
Load Diff
32
src/components/DisplayMainPage/wifi.js
Normal file
32
src/components/DisplayMainPage/wifi.js
Normal file
@@ -0,0 +1,32 @@
|
||||
import React from 'react';
|
||||
import { useAudio } from '@/components/AudioProvider';
|
||||
|
||||
export default function WiFiDisplay() {
|
||||
const { play } = useAudio();
|
||||
|
||||
const handleClick = () => {
|
||||
play('keyClick');
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className="w-[480px] h-[640px] bg-[#fff] flex flex-col overflow-hidden items-center justify-center"
|
||||
onClick={handleClick}
|
||||
>
|
||||
<div className="text-center">
|
||||
<h1 className="text-2xl font-bold text-gray-800 mb-4">WiFi 测试仪</h1>
|
||||
<p className="text-gray-600 mb-8">无线网络测试设备主页</p>
|
||||
<div className="bg-green-100 p-6 rounded-lg">
|
||||
<h2 className="text-lg font-semibold text-green-800 mb-2">连接状态</h2>
|
||||
<p className="text-green-600">WiFi 信号正常</p>
|
||||
<div className="mt-4">
|
||||
<div className="flex items-center justify-center space-x-2">
|
||||
<div className="w-3 h-3 bg-green-500 rounded-full animate-pulse"></div>
|
||||
<span className="text-sm text-green-700">扫描中...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -241,6 +241,11 @@ export default function JsPlumbInit() {
|
||||
const testMPOBOXPortElements = document.querySelectorAll('[jstype="mpo-fiberbox-mpo"]');
|
||||
const testMPOLCBOXPortElements = document.querySelectorAll('[jstype="mpo-fiberbox-lc"]');
|
||||
|
||||
const cableAnalyzerCopperElements = document.querySelectorAll('[jstype="cal-copper"]');
|
||||
const cableAnalyzerCopperOutElements = document.querySelectorAll('[jstype="cal-copper-out"]');
|
||||
|
||||
|
||||
|
||||
|
||||
// 为connector类型元素添加端点(只能作为目标)
|
||||
connectorLeftElements.forEach((element) => {
|
||||
@@ -644,6 +649,34 @@ export default function JsPlumbInit() {
|
||||
});
|
||||
});
|
||||
|
||||
// 为线缆分析铜端口添加端点
|
||||
cableAnalyzerCopperElements.forEach((element) => {
|
||||
const id = element.getAttribute('id');
|
||||
instance.addEndpoint(element, {
|
||||
anchor: 'Center',
|
||||
isSource: false,
|
||||
isTarget: true,
|
||||
maxConnections: 1,
|
||||
connectorStyle: { stroke: '#0ff', strokeWidth: 2 },
|
||||
connectorHoverStyle: { stroke: '#00ff7f', strokeWidth: 3 },
|
||||
paintStyle: { fill: '#0ff', },
|
||||
hoverPaintStyle: { fill: '#00ff7f' }
|
||||
});
|
||||
});
|
||||
cableAnalyzerCopperOutElements.forEach((element) => {
|
||||
const id = element.getAttribute('id');
|
||||
instance.addEndpoint(element, {
|
||||
anchor: 'Center',
|
||||
isSource: true,
|
||||
isTarget: true,
|
||||
maxConnections: 1,
|
||||
connectorStyle: { stroke: '#0ff', strokeWidth: 2 },
|
||||
connectorHoverStyle: { stroke: '#00ff7f', strokeWidth: 3 },
|
||||
paintStyle: { fill: '#0ff', },
|
||||
hoverPaintStyle: { fill: '#00ff7f' }
|
||||
});
|
||||
});
|
||||
|
||||
// 添加连接事件监听
|
||||
instance.bind('connection', (info) => {
|
||||
const sourceId = info.sourceId;
|
||||
|
||||
766
src/components/scene/CopperAnalyzer.js
Normal file
766
src/components/scene/CopperAnalyzer.js
Normal file
@@ -0,0 +1,766 @@
|
||||
import React, { useState, useEffect, useRef, useMemo } from 'react';
|
||||
import useDeviceStore from '@/store/deviceStore';
|
||||
|
||||
const CopperAnalyzer = () => {
|
||||
// 组件会自动响应参数变化重新渲染SVG
|
||||
|
||||
// 获取 deviceStore 中的方法
|
||||
const { updateCableParams } = useDeviceStore();
|
||||
|
||||
// 6个核心物理参数
|
||||
const [params, setParams] = useState({
|
||||
cableType: 'twisted_dual', // 线缆类别
|
||||
spliceMethod: 'none', // 接续方式
|
||||
conductorMaterial: 'copper', // 导体材质
|
||||
coreDiameter: 0.57, // 线芯直径 (mm)
|
||||
insulationMaterial: 'pe', // 绝缘材料
|
||||
insulationThickness: 0.2, // 绝缘厚度 (mm)
|
||||
twistPitch: 12, // 绞距 (mm)
|
||||
cableLength: 100, // 线缆长度 (m)
|
||||
pair2TwistRatio: 1.0 // 第二对绞距比例 (相对于第一对)
|
||||
});
|
||||
|
||||
// 正在拖拽滑块标记 & 防抖定时器
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
const commitTimerRef = useRef(null);
|
||||
|
||||
// 导体材质选项
|
||||
const conductorMaterials = [
|
||||
{ value: 'copper', label: '铜 (Cu)', resistivity: 1.68e-8, color: '#CD7F32' },
|
||||
{ value: 'silver', label: '银 (Ag)', resistivity: 1.59e-8, color: '#C0C0C0' },
|
||||
{ value: 'aluminum', label: '铝 (Al)', resistivity: 2.82e-8, color: '#A8A8A8' },
|
||||
{ value: 'gold', label: '金 (Au)', resistivity: 2.44e-8, color: '#FFD700' }
|
||||
];
|
||||
|
||||
// 绝缘材料选项
|
||||
const insulationMaterials = [
|
||||
{ value: 'pe', label: 'PE (聚乙烯)', dielectric: 2.3, tanDelta: 0.0002, color: '#FF8C42' },
|
||||
{ value: 'pvc', label: 'PVC (聚氯乙烯)', dielectric: 3.5, tanDelta: 0.02, color: '#FFB366' },
|
||||
{ value: 'ptfe', label: 'PTFE (聚四氟乙烯)', dielectric: 2.1, tanDelta: 0.0001, color: '#FFA500' },
|
||||
{ value: 'pp', label: 'PP (聚丙烯)', dielectric: 2.2, tanDelta: 0.0003, color: '#FF7F50' }
|
||||
];
|
||||
|
||||
// AWG线径选项
|
||||
const awgSizes = [
|
||||
{ awg: 18, diameter: 1.024 },
|
||||
{ awg: 20, diameter: 0.812 },
|
||||
{ awg: 22, diameter: 0.644 },
|
||||
{ awg: 24, diameter: 0.511 },
|
||||
{ awg: 26, diameter: 0.405 },
|
||||
{ awg: 28, diameter: 0.321 }
|
||||
];
|
||||
|
||||
// 计算电气特性参数 R′/L′/C′/G′
|
||||
const calculateElectricalParams = () => {
|
||||
const conductorMat = conductorMaterials.find(m => m.value === params.conductorMaterial);
|
||||
const insulationMat = insulationMaterials.find(m => m.value === params.insulationMaterial);
|
||||
|
||||
if (!conductorMat || !insulationMat) return { R: 0, L: 0, C: 0, G: 0 };
|
||||
|
||||
const r = params.coreDiameter / 2000; // 半径,转换为米
|
||||
const t = params.insulationThickness / 1000; // 绝缘厚度,转换为米
|
||||
const s = (params.coreDiameter + 2 * params.insulationThickness) / 1000; // 中心距,转换为米
|
||||
|
||||
// R′ - 单位长度电阻 (Ω/m)
|
||||
const R_prime = conductorMat.resistivity / (Math.PI * r * r);
|
||||
|
||||
// L′ - 单位长度电感 (H/m)
|
||||
const mu0 = 4 * Math.PI * 1e-7; // 真空磁导率
|
||||
const L_prime = (mu0 / Math.PI) * Math.log(s / r);
|
||||
|
||||
// C′ - 单位长度电容 (F/m)
|
||||
const epsilon0 = 8.854e-12; // 真空介电常数
|
||||
const C_prime = (Math.PI * epsilon0 * insulationMat.dielectric) / Math.log(s / r);
|
||||
|
||||
// G′ - 单位长度电导 (S/m)
|
||||
const G_prime = 2 * Math.PI * epsilon0 * insulationMat.dielectric * insulationMat.tanDelta / Math.log(s / r);
|
||||
|
||||
return {
|
||||
R: R_prime,
|
||||
L: L_prime * 1e9, // 转换为 nH/m
|
||||
C: C_prime * 1e12, // 转换为 pF/m
|
||||
G: G_prime * 1e9 // 转换为 nS/m
|
||||
};
|
||||
};
|
||||
|
||||
// 计算电气参数使用 useMemo,避免每次轻微变动都重算
|
||||
const electricalParams = useMemo(() => calculateElectricalParams(), [
|
||||
params.conductorMaterial,
|
||||
params.insulationMaterial,
|
||||
params.coreDiameter,
|
||||
params.insulationThickness
|
||||
]);
|
||||
|
||||
// 同步参数到 deviceStore
|
||||
// 将更新到全局 store 的操作做防抖,拖拽中降低更新频率,提升滑动顺滑度
|
||||
useEffect(() => {
|
||||
if (commitTimerRef.current) {
|
||||
clearTimeout(commitTimerRef.current);
|
||||
}
|
||||
commitTimerRef.current = setTimeout(() => {
|
||||
updateCableParams({
|
||||
conductorMaterial: params.conductorMaterial,
|
||||
coreDiameter: params.coreDiameter,
|
||||
insulationMaterial: params.insulationMaterial,
|
||||
insulationThickness: params.insulationThickness,
|
||||
twistPitch: params.twistPitch,
|
||||
cableLength: params.cableLength,
|
||||
pair2TwistRatio: params.pair2TwistRatio,
|
||||
R: electricalParams.R,
|
||||
L: electricalParams.L,
|
||||
C: electricalParams.C,
|
||||
G: electricalParams.G
|
||||
});
|
||||
}, isDragging ? 120 : 60);
|
||||
return () => {
|
||||
if (commitTimerRef.current) {
|
||||
clearTimeout(commitTimerRef.current);
|
||||
}
|
||||
};
|
||||
}, [
|
||||
params.conductorMaterial,
|
||||
params.coreDiameter,
|
||||
params.insulationMaterial,
|
||||
params.insulationThickness,
|
||||
params.twistPitch,
|
||||
params.cableLength,
|
||||
params.pair2TwistRatio,
|
||||
electricalParams.R,
|
||||
electricalParams.L,
|
||||
electricalParams.C,
|
||||
electricalParams.G,
|
||||
isDragging,
|
||||
updateCableParams
|
||||
]);
|
||||
|
||||
// 将复杂 SVG 路径计算做 useMemo,减少拖拽时的重算
|
||||
const leftSplitPath0 = useMemo(() => generateWireSplitPath(0, 800, 300, true, 0, 1), [params.coreDiameter, params.twistPitch]);
|
||||
const leftSplitPath1 = useMemo(() => generateWireSplitPath(1, 800, 300, true, 0, 1), [params.coreDiameter, params.twistPitch]);
|
||||
const rightSplitPath0 = useMemo(() => generateWireSplitPath(0, 800, 300, false, 0, 1), [params.coreDiameter, params.twistPitch]);
|
||||
const rightSplitPath1 = useMemo(() => generateWireSplitPath(1, 800, 300, false, 0, 1), [params.coreDiameter, params.twistPitch]);
|
||||
const twistedPath0 = useMemo(() => generateTwistedPairPath(0, 800, 300, 0, 1), [params.coreDiameter, params.twistPitch]);
|
||||
const twistedPath1 = useMemo(() => generateTwistedPairPath(1, 800, 300, 0, 1), [params.coreDiameter, params.twistPitch]);
|
||||
|
||||
// 第二条双绞线的垂直偏移(视图坐标)
|
||||
const dualYOffset = 60;
|
||||
|
||||
// 第二条双绞线路径(按偏移生成)
|
||||
const leftSplitPath0_2 = useMemo(() => generateWireSplitPath(0, 800, 300, true, dualYOffset, params.pair2TwistRatio), [params.coreDiameter, params.twistPitch, params.pair2TwistRatio]);
|
||||
const leftSplitPath1_2 = useMemo(() => generateWireSplitPath(1, 800, 300, true, dualYOffset, params.pair2TwistRatio), [params.coreDiameter, params.twistPitch, params.pair2TwistRatio]);
|
||||
const rightSplitPath0_2 = useMemo(() => generateWireSplitPath(0, 800, 300, false, dualYOffset, params.pair2TwistRatio), [params.coreDiameter, params.twistPitch, params.pair2TwistRatio]);
|
||||
const rightSplitPath1_2 = useMemo(() => generateWireSplitPath(1, 800, 300, false, dualYOffset, params.pair2TwistRatio), [params.coreDiameter, params.twistPitch, params.pair2TwistRatio]);
|
||||
const twistedPath0_2 = useMemo(() => generateTwistedPairPath(0, 800, 300, dualYOffset, params.pair2TwistRatio), [params.coreDiameter, params.twistPitch, params.pair2TwistRatio]);
|
||||
const twistedPath1_2 = useMemo(() => generateTwistedPairPath(1, 800, 300, dualYOffset, params.pair2TwistRatio), [params.coreDiameter, params.twistPitch, params.pair2TwistRatio]);
|
||||
const crossSectionSVG = useMemo(() => generateCrossSectionSVG(), [
|
||||
params.coreDiameter,
|
||||
params.insulationThickness,
|
||||
params.insulationMaterial
|
||||
]);
|
||||
|
||||
// AWG下拉选项(毫米)
|
||||
const awgDropdownOptions = [
|
||||
{ label: 'AWG 22', value: 0.644 },
|
||||
{ label: 'AWG 23', value: 0.573 },
|
||||
{ label: 'AWG 24', value: 0.511 },
|
||||
{ label: 'AWG 25', value: 0.455 },
|
||||
{ label: 'AWG 26', value: 0.405 },
|
||||
];
|
||||
|
||||
// 动态计算左右分叉端点在容器中的百分比位置(与路径生成保持一致)
|
||||
const vbWidth = 800; // SVG viewBox 宽度
|
||||
const vbHeight = 150; // SVG viewBox 高度
|
||||
const svgHeightForPaths = 300; // 传入路径函数的高度(用于计算中心Y)
|
||||
const splitOffset = 12.5; // 分叉偏移,与 generateWireSplitPath 保持一致
|
||||
const leftX = 30; // 左侧分叉外端 X
|
||||
const rightX = vbWidth - 30; // 右侧分叉外端 X
|
||||
const centerYForPaths = svgHeightForPaths * 0.1; // 与路径函数相同的中心Y
|
||||
|
||||
const splitMarkerPositions = {
|
||||
leftTop: {
|
||||
leftPct: (leftX / vbWidth) * 100,
|
||||
topPct: ((centerYForPaths - splitOffset + 10) / vbHeight) * 100,
|
||||
},
|
||||
leftBottom: {
|
||||
leftPct: (leftX / vbWidth) * 100,
|
||||
topPct: ((centerYForPaths + splitOffset + 10) / vbHeight) * 100,
|
||||
},
|
||||
rightTop: {
|
||||
leftPct: (rightX / vbWidth) * 100,
|
||||
topPct: ((centerYForPaths - splitOffset + 10) / vbHeight) * 100,
|
||||
},
|
||||
rightBottom: {
|
||||
leftPct: (rightX / vbWidth) * 100,
|
||||
topPct: ((centerYForPaths + splitOffset + 10) / vbHeight) * 100,
|
||||
},
|
||||
};
|
||||
|
||||
// 第二条双绞线的分叉端点位置(按偏移计算)
|
||||
const centerYForPaths2 = centerYForPaths + dualYOffset;
|
||||
const splitMarkerPositions2 = {
|
||||
leftTop: {
|
||||
leftPct: (leftX / vbWidth) * 100,
|
||||
topPct: ((centerYForPaths2 - splitOffset + 10) / vbHeight) * 90,
|
||||
},
|
||||
leftBottom: {
|
||||
leftPct: (leftX / vbWidth) * 100,
|
||||
topPct: ((centerYForPaths2 + splitOffset + 10) / vbHeight) * 90,
|
||||
},
|
||||
rightTop: {
|
||||
leftPct: (rightX / vbWidth) * 100,
|
||||
topPct: ((centerYForPaths2 - splitOffset + 10) / vbHeight) * 90,
|
||||
},
|
||||
rightBottom: {
|
||||
leftPct: (rightX / vbWidth) * 100,
|
||||
topPct: ((centerYForPaths2 + splitOffset + 10) / vbHeight) * 90,
|
||||
},
|
||||
};
|
||||
|
||||
// 生成双绞线SVG路径
|
||||
function generateTwistedPairPath(wireIndex, svgWidth, svgHeight, centerYOffset = 0, twistPitchScale = 1) {
|
||||
const startX = 60; // 减少左边距,为较短分叉留空间
|
||||
const endX = svgWidth - 60; // 减少右边距,为较短分叉留空间
|
||||
const centerY = svgHeight * 0.1 + centerYOffset; // 中心Y可按偏移调整
|
||||
const amplitude = 15; // 调整振幅为15
|
||||
|
||||
// 根据实际绞距参数计算频率
|
||||
const canvasLengthMm = 30; // 调整为30mm显示长度
|
||||
const actualTwistPitch = params.twistPitch * (twistPitchScale || 1); // mm,按比例缩放
|
||||
|
||||
// 如果绞距为0,显示平行线
|
||||
if (actualTwistPitch === 0) {
|
||||
const parallelOffset = 3; // 平行线之间的垂直间距
|
||||
const y = centerY + (wireIndex === 0 ? -parallelOffset : parallelOffset);
|
||||
return `M ${startX} ${y} L ${endX} ${y}`;
|
||||
}
|
||||
|
||||
let twistCycles = canvasLengthMm / actualTwistPitch; // 实际的绞距周期数
|
||||
|
||||
// 限制显示周期数,确保视觉效果合适
|
||||
if (twistCycles > 20) {
|
||||
twistCycles = Math.min(twistCycles, 20);
|
||||
} else if (twistCycles < 1) {
|
||||
twistCycles = Math.max(twistCycles, 1);
|
||||
}
|
||||
|
||||
const frequency = (twistCycles * 2 * Math.PI) / (endX - startX);
|
||||
|
||||
let path = '';
|
||||
for (let x = startX; x <= endX; x += 2) {
|
||||
const angle = frequency * (x - startX) + wireIndex * Math.PI;
|
||||
const y = centerY + amplitude * Math.sin(angle);
|
||||
|
||||
if (x === startX) {
|
||||
path += `M ${x} ${y}`;
|
||||
} else {
|
||||
path += ` L ${x} ${y}`;
|
||||
}
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
// 生成线芯分叉路径
|
||||
function generateWireSplitPath(wireIndex, svgWidth, svgHeight, isStart = true, centerYOffset = 0, twistPitchScale = 1) {
|
||||
const centerY = svgHeight * 0.1 + centerYOffset; // 与双绞线中心位置保持一致,可偏移
|
||||
const amplitude = 15; // 与双绞线振幅保持一致
|
||||
const splitOffset = 12; // 减少分叉偏移距离
|
||||
|
||||
// 计算双绞线在端点的Y坐标
|
||||
const canvasLengthMm = 30;
|
||||
const actualTwistPitch = params.twistPitch * (twistPitchScale || 1);
|
||||
|
||||
// 如果绞距为0,使用平行线的连接逻辑
|
||||
if (actualTwistPitch === 0) {
|
||||
const parallelOffset = 3; // 平行线之间的垂直间距
|
||||
const wireY = centerY + (wireIndex === 0 ? -parallelOffset : parallelOffset);
|
||||
|
||||
if (isStart) {
|
||||
// 左侧分叉 - 从分离状态连接到平行线起点
|
||||
const startX = 30;
|
||||
const endX = 60;
|
||||
const startY = centerY + (wireIndex === 0 ? -splitOffset : splitOffset);
|
||||
|
||||
return `M ${startX} ${startY} L ${endX} ${wireY}`;
|
||||
} else {
|
||||
// 右侧分叉 - 从平行线终点连接到分离状态
|
||||
const startX = svgWidth - 60;
|
||||
const endX = svgWidth - 30;
|
||||
const endY = centerY + (wireIndex === 0 ? -splitOffset : splitOffset);
|
||||
|
||||
return `M ${startX} ${wireY} L ${endX} ${endY}`;
|
||||
}
|
||||
}
|
||||
|
||||
let twistCycles = canvasLengthMm / actualTwistPitch;
|
||||
if (twistCycles > 20) twistCycles = Math.min(twistCycles, 20);
|
||||
else if (twistCycles < 1) twistCycles = Math.max(twistCycles, 1);
|
||||
|
||||
if (isStart) {
|
||||
// 左侧分叉 - 从分离状态连接到双绞线起点
|
||||
const startX = 30; // 缩短分叉长度
|
||||
const endX = 60;
|
||||
const startY = centerY + (wireIndex === 0 ? -splitOffset : splitOffset);
|
||||
// 双绞线起点的Y坐标
|
||||
const angle = wireIndex * Math.PI;
|
||||
const endY = centerY + amplitude * Math.sin(angle);
|
||||
|
||||
return `M ${startX} ${startY} L ${endX} ${endY}`;
|
||||
} else {
|
||||
// 右侧分叉 - 从双绞线终点连接到分离状态
|
||||
const startX = svgWidth - 60;
|
||||
const endX = svgWidth - 30; // 缩短分叉长度
|
||||
// 双绞线终点的Y坐标
|
||||
const frequency = (twistCycles * 2 * Math.PI) / (svgWidth - 120);
|
||||
const totalLength = svgWidth - 120;
|
||||
const angle = frequency * totalLength + wireIndex * Math.PI;
|
||||
const startY = centerY + amplitude * Math.sin(angle);
|
||||
const endY = centerY + (wireIndex === 0 ? -splitOffset : splitOffset);
|
||||
|
||||
return `M ${startX} ${startY} L ${endX} ${endY}`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 生成横截面SVG组件
|
||||
function generateCrossSectionSVG() {
|
||||
const svgxSize = 150;
|
||||
const svgySize = 250;
|
||||
const centerX = svgxSize / 2;
|
||||
const centerY = svgySize / 2;
|
||||
const scale = 60;
|
||||
const coreRadius = (params.coreDiameter / 2) * scale;
|
||||
const insulationThickness = params.insulationThickness * scale;
|
||||
const wireRadius = coreRadius + insulationThickness;
|
||||
|
||||
const conductorMat = conductorMaterials.find(m => m.value === params.conductorMaterial);
|
||||
const insulationMat = insulationMaterials.find(m => m.value === params.insulationMaterial);
|
||||
|
||||
// 两根导线的位置(上下紧密接触)
|
||||
const positions = [
|
||||
{ x: centerX, y: centerY - wireRadius },
|
||||
{ x: centerX, y: centerY + wireRadius }
|
||||
];
|
||||
|
||||
const coreColors = [conductorMat?.color || '#CD7F32', '#FF6B35'];
|
||||
const insulationColors = [insulationMat?.color || '#FF8C42', insulationMat?.color || '#FFB366'];
|
||||
|
||||
return (
|
||||
<svg
|
||||
viewBox={`0 0 ${svgxSize} ${svgySize}`}
|
||||
className="w-full h-full"
|
||||
style={{ minHeight: '100px', minWidth: '100px' }}
|
||||
>
|
||||
{/* 背景 */}
|
||||
<rect width="100%" height="90%" fill="transparent" />
|
||||
|
||||
{/* 绘制两根导线 */}
|
||||
{positions.map((pos, index) => (
|
||||
<g key={index}>
|
||||
{/* 绝缘层(外圆) */}
|
||||
<circle
|
||||
cx={pos.x}
|
||||
cy={pos.y}
|
||||
r={wireRadius}
|
||||
fill={insulationColors[index]}
|
||||
stroke="#333"
|
||||
strokeWidth="1"
|
||||
style={{
|
||||
filter: 'drop-shadow(1px 1px 2px rgba(0, 0, 0, 0.1))'
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* 导体线芯(内圆) */}
|
||||
<circle
|
||||
cx={pos.x}
|
||||
cy={pos.y}
|
||||
r={coreRadius}
|
||||
fill={coreColors[index]}
|
||||
stroke="#333"
|
||||
strokeWidth="1"
|
||||
style={{
|
||||
filter: 'drop-shadow(0.5px 0.5px 1px rgba(0, 0, 0, 0.2))'
|
||||
}}
|
||||
/>
|
||||
</g>
|
||||
))}
|
||||
|
||||
{/* 尺寸标注 */}
|
||||
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div className="w-full h-full flex">
|
||||
{/* 左侧参数控制面板 - 20% */}
|
||||
<div className="w-2/10 p-4 border-r border-[#0ff]/20 overflow-y-auto no-scrollbar h-full text-[#0ff]">
|
||||
<div className="grid grid-cols-3 grid-rows-3 gap-3">
|
||||
{/* 第一行:线缆类别、接续方式、占位 */}
|
||||
<div>
|
||||
<label className="block text-xs font-semibold text-[#0ff] mb-1">线缆类别</label>
|
||||
<select
|
||||
value={params.cableType}
|
||||
onChange={(e) => setParams({ ...params, cableType: e.target.value })}
|
||||
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_dual">双绞线(两对)</option>
|
||||
{/* <option value="fiber">光纤</option> */}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-xs font-semibold text-[#0ff] mb-1">接续方式</label>
|
||||
<select
|
||||
value={params.spliceMethod}
|
||||
onChange={(e) => setParams({ ...params, spliceMethod: e.target.value })}
|
||||
className="w-full p-2 border rounded text-xs bg-[#1E293B] text-[#0ff] border-[#0ff]/30 focus:border-[#0ff] focus:outline-none"
|
||||
>
|
||||
<option value="none">无</option>
|
||||
</select>
|
||||
</div>
|
||||
{/* 占位取消注释 */}
|
||||
{/* <div aria-hidden="true" /> */}
|
||||
|
||||
{/* 导体材质(仅双绞线显示) */}
|
||||
{(params.cableType === 'twisted_single' || params.cableType === 'twisted_dual') && (
|
||||
<div>
|
||||
<label className="block text-xs font-semibold text-[#0ff] mb-1">导体材质</label>
|
||||
<select
|
||||
value={params.conductorMaterial}
|
||||
onChange={(e) => setParams({ ...params, conductorMaterial: e.target.value })}
|
||||
className="w-full p-2 border rounded text-xs bg-[#1E293B] text-[#0ff] border-[#0ff]/30 focus:border-[#0ff] focus:outline-none"
|
||||
>
|
||||
<option value="copper">铜</option>
|
||||
<option value="aluminum">铝</option>
|
||||
<option value="silver">银</option>
|
||||
</select>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 线芯直径(AWG下拉) */}
|
||||
<div>
|
||||
<label className="block text-xs font-semibold text-[#0ff] mb-1">线芯直径</label>
|
||||
<select
|
||||
value={params.coreDiameter}
|
||||
onChange={(e) => setParams({ ...params, coreDiameter: parseFloat(e.target.value) })}
|
||||
className="w-full p-2 border rounded text-xs bg-[#1E293B] text-[#0ff] border-[#0ff]/30 focus:border-[#0ff] focus:outline-none"
|
||||
>
|
||||
{awgDropdownOptions.map(opt => (
|
||||
<option key={opt.label} value={opt.value}>{opt.label}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* 绝缘材料(PP/PE) */}
|
||||
<div>
|
||||
<label className="block text-xs font-semibold text-[#0ff] mb-1">绝缘材料</label>
|
||||
<select
|
||||
value={params.insulationMaterial}
|
||||
onChange={(e) => setParams({ ...params, insulationMaterial: e.target.value })}
|
||||
className="w-full p-2 border rounded text-xs bg-[#1E293B] text-[#0ff] border-[#0ff]/30 focus:border-[#0ff] focus:outline-none"
|
||||
>
|
||||
<option value="pp">PP</option>
|
||||
<option value="pe">PE</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* 绝缘厚度(滑块 0.1~0.5mm) */}
|
||||
<div>
|
||||
<label className="block text-xs font-semibold text-[#0ff] mb-1">
|
||||
绝缘厚度:
|
||||
<span className="block text-[#0ff] font-bold">{params.insulationThickness}mm</span>
|
||||
</label>
|
||||
<input
|
||||
type="range"
|
||||
min={0.1}
|
||||
max={0.5}
|
||||
step={0.01}
|
||||
value={params.insulationThickness}
|
||||
onChange={(e) => setParams({ ...params, insulationThickness: parseFloat(e.target.value) })}
|
||||
className="w-full h-2 bg-[#0ff]/20 rounded appearance-none cursor-pointer"
|
||||
style={{ accentColor: '#0ff' }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 绞距(滑块 5~20mm) */}
|
||||
<div>
|
||||
<label className="block text-xs font-semibold text-[#0ff] mb-1">
|
||||
线缆绞距:
|
||||
<span className="block text-[#0ff] font-bold">{params.twistPitch}mm</span>
|
||||
</label>
|
||||
<input
|
||||
type="range"
|
||||
min={0}
|
||||
max={20}
|
||||
step={1}
|
||||
value={params.twistPitch}
|
||||
onChange={(e) => setParams({ ...params, twistPitch: parseFloat(e.target.value) })}
|
||||
className="w-full h-2 bg-[#0ff]/20 rounded appearance-none cursor-pointer"
|
||||
style={{ accentColor: '#0ff' }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 第二对绞距比例(滑块 0.5~2.0,仅两对时显示) */}
|
||||
{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
|
||||
type="range"
|
||||
min={1}
|
||||
max={2.5}
|
||||
step={0.05}
|
||||
value={params.pair2TwistRatio}
|
||||
onChange={(e) => setParams({ ...params, pair2TwistRatio: parseFloat(e.target.value) })}
|
||||
className="w-full h-2 bg-[#0ff]/20 rounded appearance-none cursor-pointer"
|
||||
style={{ accentColor: '#0ff' }}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 线缆长度(滑块 1~305m) */}
|
||||
<div>
|
||||
<label className="block text-xs font-semibold text-[#0ff] mb-1">
|
||||
线缆长度:
|
||||
<span className="block text-[#0ff] font-bold">{params.cableLength}m</span>
|
||||
</label>
|
||||
<input
|
||||
type="range"
|
||||
min={1}
|
||||
max={305}
|
||||
step={1}
|
||||
value={params.cableLength}
|
||||
onChange={(e) => setParams({ ...params, cableLength: parseInt(e.target.value) })}
|
||||
className="w-full h-2 bg-[#0ff]/20 rounded appearance-none cursor-pointer"
|
||||
style={{ accentColor: '#0ff' }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 中间双绞线可视化 - 60% */}
|
||||
<div className="w-7/10 p-0 flex flex-col h-full">
|
||||
|
||||
{/* 双绞线示意图 - 100% */}
|
||||
<div className="h-full rounded-xl shadow-2xl p-2 overflow-hidden border mb-0">
|
||||
<div className="w-full h-full flex flex-col">
|
||||
<div className="flex-1 relative flex items-center justify-center min-h-0">
|
||||
<svg
|
||||
viewBox="0 0 800 150"
|
||||
className="w-full h-full rounded-lg"
|
||||
style={{ minHeight: '200px' }}
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
>
|
||||
{/* 背景网格 */}
|
||||
<defs>
|
||||
{/* <pattern id="grid" width="20" height="20" patternUnits="userSpaceOnUse">
|
||||
<path d="M 20 0 L 0 0 0 20" fill="none" stroke="#f0f0f0" strokeWidth="1"/>
|
||||
</pattern> */}
|
||||
{/* 橙白相间条纹图案 */}
|
||||
<pattern id="orangeWhiteStripes" width="8" height="8" patternUnits="userSpaceOnUse">
|
||||
<rect width="4" height="8" fill="#ff6600"/>
|
||||
<rect x="4" width="4" height="8" fill="#ffffff"/>
|
||||
</pattern>
|
||||
{/* 蓝白相间条纹图案 */}
|
||||
<pattern id="blueWhiteStripes" width="8" height="8" patternUnits="userSpaceOnUse">
|
||||
<rect width="4" height="8" fill="#0066ff"/>
|
||||
<rect x="4" width="4" height="8" fill="#ffffff"/>
|
||||
</pattern>
|
||||
{/* 箭头标记 */}
|
||||
<marker id="arrowhead" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
||||
<polygon points="0 0, 10 3.5, 0 7" fill="#666" />
|
||||
</marker>
|
||||
</defs>
|
||||
<rect width="100%" height="100%" fill="url(#grid)" />
|
||||
|
||||
{/* 左侧分叉 */}
|
||||
<path
|
||||
d={leftSplitPath0}
|
||||
fill="none"
|
||||
stroke="#ff6600"
|
||||
strokeWidth={Math.max(3, params.coreDiameter * 8)}
|
||||
strokeLinecap="round"
|
||||
style={{
|
||||
filter: 'drop-shadow(2px 2px 4px rgba(255, 102, 0, 0.3))'
|
||||
}}
|
||||
/>
|
||||
<path
|
||||
d={leftSplitPath1}
|
||||
fill="none"
|
||||
stroke="url(#orangeWhiteStripes)"
|
||||
strokeWidth={Math.max(3, params.coreDiameter * 8)}
|
||||
strokeLinecap="round"
|
||||
style={{
|
||||
filter: 'drop-shadow(2px 2px 4px rgba(255, 102, 0, 0.3))'
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* 双绞线路径 */}
|
||||
<path
|
||||
d={twistedPath0}
|
||||
fill="none"
|
||||
stroke="#ff6600"
|
||||
strokeWidth={Math.max(3, params.coreDiameter * 8)}
|
||||
strokeLinecap="round"
|
||||
style={{
|
||||
filter: 'drop-shadow(2px 2px 4px rgba(255, 102, 0, 0.3))'
|
||||
}}
|
||||
/>
|
||||
<path
|
||||
d={twistedPath1}
|
||||
fill="none"
|
||||
stroke="url(#orangeWhiteStripes)"
|
||||
strokeWidth={Math.max(3, params.coreDiameter * 8)}
|
||||
strokeLinecap="round"
|
||||
style={{
|
||||
filter: 'drop-shadow(2px 2px 4px rgba(255, 102, 0, 0.3))'
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* 右侧分叉 */}
|
||||
<path
|
||||
d={rightSplitPath0}
|
||||
fill="none"
|
||||
stroke="#ff6600"
|
||||
strokeWidth={Math.max(3, params.coreDiameter * 8)}
|
||||
strokeLinecap="round"
|
||||
style={{
|
||||
filter: 'drop-shadow(2px 2px 4px rgba(255, 102, 0, 0.3))'
|
||||
}}
|
||||
/>
|
||||
<path
|
||||
d={rightSplitPath1}
|
||||
fill="none"
|
||||
stroke="url(#orangeWhiteStripes)"
|
||||
strokeWidth={Math.max(3, params.coreDiameter * 8)}
|
||||
strokeLinecap="round"
|
||||
style={{
|
||||
filter: 'drop-shadow(2px 2px 4px rgba(255, 102, 0, 0.3))'
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* 第二条双绞线(当选择两对时渲染) */}
|
||||
{params.cableType === 'twisted_dual' && (
|
||||
<>
|
||||
{/* 左侧分叉 - 第二对 */}
|
||||
<path
|
||||
d={leftSplitPath0_2}
|
||||
fill="none"
|
||||
stroke="#0066ff"
|
||||
strokeWidth={Math.max(3, params.coreDiameter * 8)}
|
||||
strokeLinecap="round"
|
||||
style={{
|
||||
filter: 'drop-shadow(2px 2px 4px rgba(255, 102, 0, 0.3))'
|
||||
}}
|
||||
/>
|
||||
<path
|
||||
d={leftSplitPath1_2}
|
||||
fill="none"
|
||||
stroke="url(#blueWhiteStripes)"
|
||||
strokeWidth={Math.max(3, params.coreDiameter * 8)}
|
||||
strokeLinecap="round"
|
||||
style={{
|
||||
filter: 'drop-shadow(2px 2px 4px rgba(255, 102, 0, 0.3))'
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* 双绞线路径 - 第二对 */}
|
||||
<path
|
||||
d={twistedPath0_2}
|
||||
fill="none"
|
||||
stroke="#0066ff"
|
||||
strokeWidth={Math.max(3, params.coreDiameter * 8)}
|
||||
strokeLinecap="round"
|
||||
style={{
|
||||
filter: 'drop-shadow(2px 2px 4px rgba(255, 102, 0, 0.3))'
|
||||
}}
|
||||
/>
|
||||
<path
|
||||
d={twistedPath1_2}
|
||||
fill="none"
|
||||
stroke="url(#blueWhiteStripes)"
|
||||
strokeWidth={Math.max(3, params.coreDiameter * 8)}
|
||||
strokeLinecap="round"
|
||||
style={{
|
||||
filter: 'drop-shadow(2px 2px 4px rgba(255, 102, 0, 0.3))'
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* 右侧分叉 - 第二对 */}
|
||||
<path
|
||||
d={rightSplitPath0_2}
|
||||
fill="none"
|
||||
stroke="#0066ff"
|
||||
strokeWidth={Math.max(3, params.coreDiameter * 8)}
|
||||
strokeLinecap="round"
|
||||
style={{
|
||||
filter: 'drop-shadow(2px 2px 4px rgba(255, 102, 0, 0.3))'
|
||||
}}
|
||||
/>
|
||||
<path
|
||||
d={rightSplitPath1_2}
|
||||
fill="none"
|
||||
stroke="url(#blueWhiteStripes)"
|
||||
strokeWidth={Math.max(3, params.coreDiameter * 8)}
|
||||
strokeLinecap="round"
|
||||
style={{
|
||||
filter: 'drop-shadow(2px 2px 4px rgba(255, 102, 0, 0.3))'
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</svg>
|
||||
{/* 隐藏测试端口标记(左右分叉两头,共4处) */}
|
||||
{/* 左侧分叉外端两个点(动态计算) */}
|
||||
<div id="pair1-line1-left" jstype="cal-copper-out" className="absolute" style={{ left: `${splitMarkerPositions.leftTop.leftPct}%`, top: `${splitMarkerPositions.leftTop.topPct}%`, width: '0px', height: '0px', opacity: 0 }} />
|
||||
<div id="pair1-line2-left" jstype="cal-copper-out" className="absolute" style={{ left: `${splitMarkerPositions.leftBottom.leftPct}%`, top: `${splitMarkerPositions.leftBottom.topPct}%`, width: '0px', height: '0px', opacity: 0 }} />
|
||||
{/* 右侧分叉外端两个点(动态计算) */}
|
||||
<div id="pair1-line1-right" jstype="cal-copper-out" className="absolute" style={{ left: `${splitMarkerPositions.rightTop.leftPct}%`, top: `${splitMarkerPositions.rightTop.topPct}%`, width: '0px', height: '0px', opacity: 0 }} />
|
||||
<div id="pair1-line2-right" jstype="cal-copper-out" className="absolute" style={{ left: `${splitMarkerPositions.rightBottom.leftPct}%`, top: `${splitMarkerPositions.rightBottom.topPct}%`, width: '0px', height: '0px', opacity: 0 }} />
|
||||
{params.cableType === 'twisted_dual' && (
|
||||
<>
|
||||
{/* 第二对隐藏测试端口标记 */}
|
||||
<div id="pair2-line1-left" jstype="cal-copper-out" className="absolute" style={{ left: `${splitMarkerPositions2.leftTop.leftPct}%`, top: `${splitMarkerPositions2.leftTop.topPct}%`, width: '0px', height: '0px', opacity: 0 }} />
|
||||
<div id="pair2-line2-left" jstype="cal-copper-out" className="absolute" style={{ left: `${splitMarkerPositions2.leftBottom.leftPct}%`, top: `${splitMarkerPositions2.leftBottom.topPct}%`, width: '0px', height: '0px', opacity: 0 }} />
|
||||
<div id="pair2-line1-right" jstype="cal-copper-out" className="absolute" style={{ left: `${splitMarkerPositions2.rightTop.leftPct}%`, top: `${splitMarkerPositions2.rightTop.topPct}%`, width: '0px', height: '0px', opacity: 0 }} />
|
||||
<div id="pair2-line2-right" jstype="cal-copper-out" className="absolute" style={{ left: `${splitMarkerPositions2.rightBottom.leftPct}%`, top: `${splitMarkerPositions2.rightBottom.topPct}%`, width: '0px', height: '0px', opacity: 0 }} />
|
||||
</>
|
||||
)}
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{/* 右侧横截面和电气参数 - 20% */}
|
||||
<div className="w-1/10 p-0 flex flex-col h-full">
|
||||
{/* <div className="mb-6">
|
||||
<h3 className="text-xl font-bold text-gray-800 mb-2">横截面图</h3>
|
||||
<div className="w-12 h-1 bg-orange-500 rounded"></div>
|
||||
</div> */}
|
||||
|
||||
<div className="w-full ">
|
||||
{crossSectionSVG}
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CopperAnalyzer;
|
||||
|
||||
98
src/components/scene/CopperAnalyzerTask.js
Normal file
98
src/components/scene/CopperAnalyzerTask.js
Normal file
@@ -0,0 +1,98 @@
|
||||
import React from 'react';
|
||||
|
||||
// 纯文字版任务描述:插入损耗(IL)与回波损耗(RL)系列实验
|
||||
export default function CopperAnalyzerTask() {
|
||||
return (
|
||||
<div className="bg-gradient-to-br from-[#1E293B] to-[#0F172A] p-6 rounded-lg w-full h-[80vh] overflow-y-auto no-scrollbar flex flex-col gap-6 shadow-2xl border border-[#334155]">
|
||||
<div className="border-b border-cyan-700 pb-3 mb-3">
|
||||
<p className="text-sm font-semibold text-cyan-400 uppercase tracking-wider">实验任务页</p>
|
||||
<h1 className="text-2xl md:text-3xl font-bold text-gray-100 mt-1">铜缆分析任务:插入损耗与回波损耗</h1>
|
||||
<p className="text-xs text-gray-400">本任务通过测量铜缆在不同参数下的插入损耗(IL)与回波损耗(RL),来分析影响信号衰减与反射的关键物理参数及其随频率的变化规律。</p>
|
||||
</div>
|
||||
|
||||
<section className="space-y-2">
|
||||
<h2 className="text-lg font-semibold text-cyan-300">任务概述</h2>
|
||||
<ul className="list-disc list-inside text-gray-300 space-y-1">
|
||||
<li>主题:铜缆的插入损耗(IL)与回波损耗(RL)实验</li>
|
||||
<li>目的:理解影响信号衰减与反射的关键物理参数及其随频率的变化规律</li>
|
||||
<li>记录项:导体材质 / 线径 / 长度 / 频点 / IL(dB) / RL(dB) / Z0(Ω)</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section className="space-y-2">
|
||||
<h2 className="text-lg font-semibold text-cyan-300">通用准备(A0/B0)</h2>
|
||||
<ul className="list-disc list-inside text-gray-300 space-y-1">
|
||||
<li>对照默认值:材质铜、AWG24(0.511mm)、PE、厚度0.2mm、绞距12mm、长度20m、频点1/10/100MHz</li>
|
||||
<li>原则:每次只改变一个变量,其余保持不变</li>
|
||||
<li>记录项:材质 / 线径 / 长度 / 频点 / IL(dB) / RL(dB) / Z0(Ω)</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section className="space-y-2">
|
||||
<h2 className="text-lg font-semibold text-cyan-300">A. 插入损耗(Insertion Loss)系列实验</h2>
|
||||
<div>
|
||||
<h3 className="text-cyan-200 font-semibold">A1 长度对插入损耗的影响</h3>
|
||||
<p className="text-gray-300 text-sm">固定对照参数,长度依次:1/10/50/100m;记录 1/10/100 MHz 的插损。</p>
|
||||
<ul className="list-disc list-inside text-[#0ff]/80 text-sm mt-1">
|
||||
<li>插损随长度近似线性增加:同频点下 10m ≈ 1m 的 10 倍</li>
|
||||
<li>曲线随频率上升整体上移(高频衰减更严重)</li>
|
||||
<li>讨论:为何工程上存在 100m 长度限制?</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-cyan-200 font-semibold">A2 线芯直径对插入损耗的影响</h3>
|
||||
<p className="text-gray-300 text-sm">AWG 26/24/22;固定其它参数;在 1/10/100 MHz 记录插损。</p>
|
||||
<ul className="list-disc list-inside text-[#0ff]/80 text-sm mt-1">
|
||||
<li>直径越粗,插损越小(电阻更低)</li>
|
||||
<li>高频差异更明显(趋肤效应)</li>
|
||||
<li>讨论:为何粗导线电阻小?趋肤效应如何影响?</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-cyan-200 font-semibold">A3 导体材质对插入损耗的影响</h3>
|
||||
<p className="text-gray-300 text-sm">材质:铜/铝/银;固定其它参数;在三频点记录插损。</p>
|
||||
<ul className="list-disc list-inside text-[#0ff]/80 text-sm mt-1">
|
||||
<li>插损趋势:银 < 铜 < 铝(银最好,铜次之,铝衰减最大)</li>
|
||||
<li>讨论:为何实际多用铜而非银(成本/加工/氧化)?</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-cyan-200 font-semibold">A4 频率对插入损耗的影响(观察频谱)</h3>
|
||||
<p className="text-gray-300 text-sm">固定对照参数,绘制或读取 1–100 MHz 的 IL 曲线或在指定频点记录值。</p>
|
||||
<ul className="list-disc list-inside text-[#0ff]/80 text-sm mt-1">
|
||||
<li>插损随频率单调增加,曲线平滑上升(高频损耗更大)</li>
|
||||
<li>讨论:为什么频率越高损耗越大?(趋肤效应 + 介质损耗)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="space-y-2">
|
||||
<h2 className="text-lg font-semibold text-cyan-300">B. 回波损耗(Return Loss)系列实验</h2>
|
||||
<div>
|
||||
<h3 className="text-cyan-200 font-semibold">B1 阻抗偏离对回波损耗的影响</h3>
|
||||
<p className="text-gray-300 text-sm">先观察对照组 Z0;修改参数使 Z0 逐步偏离 100Ω;分别记录特性阻抗与 1/10/100 MHz 的 RL。</p>
|
||||
<ul className="list-disc list-inside text-[#0ff]/80 text-sm mt-1">
|
||||
<li>Z0 越接近 100Ω,RL 越高;偏离越多,RL 下降</li>
|
||||
<li>讨论:RL 低时通信的影响(反射增大、眼图闭合、误码率上升)</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-cyan-200 font-semibold">B2 绝缘材料/厚度对回波损耗的影响</h3>
|
||||
<p className="text-gray-300 text-sm">固定其余参数,依次改变绝缘材料(PE / PVC / PTFE)或绝缘厚度(0.1–0.5mm),记录 Z0 与各频点 RL。</p>
|
||||
<ul className="list-disc list-inside text-[#0ff]/80 text-sm mt-1">
|
||||
<li>εr 越高或绝缘越薄 → Z0 越低 → 若远离 100Ω → RL 变差</li>
|
||||
<li>讨论:为什么绝缘材料的 εr 会影响阻抗?(电容变化影响 Z0)</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-cyan-200 font-semibold">B3 TDR 波形观察</h3>
|
||||
<p className="text-gray-300 text-sm">观察不同参考阻抗下变化 TDR 曲线的趋势,定位不匹配位置。</p>
|
||||
<ul className="list-disc list-inside text-[#0ff]/80 text-sm mt-1">
|
||||
<li>阻抗偏离越大,TDR 曲线振幅越大</li>
|
||||
<li>讨论:如何根据 TDR 波形定位阻抗不匹配的位置?</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import useDisplayStore from '@/store/displayStore';
|
||||
import ContextMenu from '@/components/ContextMenu';
|
||||
import JsPlumbInit from '@/components/JsPlumbInit';
|
||||
import ConnectionAnalyzer from '@/components/ConnectionAnalyzer';
|
||||
import CopperAnalyzer from '@/components/scene/CopperAnalyzer';
|
||||
import Office from '@/components/scene/Office';
|
||||
import Industry from '@/components/scene/Industry';
|
||||
import DataCenter from '@/components/scene/DataCenter';
|
||||
@@ -15,6 +16,7 @@ import OfficeTask from '@/components/scene/OfficeTask';
|
||||
import DataCenterTask from '@/components/scene/DataCenterTask';
|
||||
import IndustryTask from '@/components/scene/IndustryTask';
|
||||
import WorldSkillTask from '@/components/scene/WorldSkillTask';
|
||||
import CopperAnalyzerTask from '@/components/scene/CopperAnalyzerTask';
|
||||
import DisPlay from '@/components/DisPlay';
|
||||
import Cursors from '@/components/Cursors';
|
||||
import SourceCheck from '@/components/SourceCheck';
|
||||
@@ -60,6 +62,9 @@ export default function Home() {
|
||||
|
||||
const {
|
||||
devices, // 所有设备列表
|
||||
installedDevices, // 已安装的设备
|
||||
installDevice, // 安装设备的方法
|
||||
uninstallDevice, // 卸载设备的方法
|
||||
mainUnitModules, // 主机已安装的模块
|
||||
remoteUnitModules, // 远端已安装的模块
|
||||
mainUnitAdapter, // 主机已安装的适配器
|
||||
@@ -95,9 +100,34 @@ export default function Home() {
|
||||
const [isFromUrl, setIsFromUrl] = useState(false);
|
||||
const [showConfirmDialog, setShowConfirmDialog] = useState(false);
|
||||
const [confirmDialogMessage, setConfirmDialogMessage] = useState('');
|
||||
const [selectedTabIndex, setSelectedTabIndex] = useState(0); // 配件区域选中的标签页索引
|
||||
const [confirmDialogCallback, setConfirmDialogCallback] = useState(null);
|
||||
const { play } = useAudio();
|
||||
|
||||
// 监听设备变化,当设备被移除时自动切换回设备标签页
|
||||
useEffect(() => {
|
||||
const mainDevice = installedDevices.main;
|
||||
let allowedCategories = ['设备']; // 默认显示设备
|
||||
|
||||
if (mainDevice) {
|
||||
if (mainDevice.id === 'dsx') {
|
||||
allowedCategories = ['设备', '模块', '适配器', '跳线', '连接器', '工具'];
|
||||
} else if (mainDevice.id === 'est-analyzer') {
|
||||
allowedCategories = ['设备', '夹具', '基准'];
|
||||
} else if (mainDevice.id === 'wifi') {
|
||||
allowedCategories = ['设备'];
|
||||
}
|
||||
}
|
||||
|
||||
// 获取当前可用的设备类别
|
||||
const availableCategories = Object.keys(devices).filter(category => allowedCategories.includes(category));
|
||||
|
||||
// 如果当前选中的标签页索引超出了可用范围,则重置为0(设备标签页)
|
||||
if (selectedTabIndex >= availableCategories.length) {
|
||||
setSelectedTabIndex(0);
|
||||
}
|
||||
}, [installedDevices.main, selectedTabIndex, devices]);
|
||||
|
||||
// iframe内嵌检测
|
||||
|
||||
useEffect(() => {
|
||||
@@ -288,10 +318,39 @@ function classNames(...classes) {
|
||||
|
||||
const item = JSON.parse(e.dataTransfer.getData('text/plain'));
|
||||
|
||||
// 处理设备的安装
|
||||
if (item.type === 'device') {
|
||||
const currentDevice = installedDevices[target];
|
||||
|
||||
// 检查是否已安装设备
|
||||
if (currentDevice) {
|
||||
if (currentDevice.id === item.id) {
|
||||
// alert('该设备已经安装,不能重复安装!');
|
||||
} else {
|
||||
// alert('该位置已安装了设备,请先卸载后再安装新设备!');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
installDevice(item, target);
|
||||
}
|
||||
// 处理模块的安装
|
||||
if (item.type === 'module') {
|
||||
else if (item.type === 'module') {
|
||||
const currentDevice = installedDevices[target];
|
||||
const targetModules = target === 'main' ? mainUnitModules : remoteUnitModules;
|
||||
|
||||
// 检查是否已安装设备
|
||||
if (!currentDevice) {
|
||||
// alert('请先安装设备,再安装模块!');
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查设备是否为dsx
|
||||
if (currentDevice.id !== 'dsx' && currentDevice.id !== 'est-analyzer') {
|
||||
// alert('模块只能安装到DSX认证测试仪或EST分析仪设备上!');
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否已安装模块
|
||||
if (targetModules.length > 0) {
|
||||
// alert('该设备已安装了测试模块,请先卸载后再安装新模块!');
|
||||
@@ -304,9 +363,22 @@ function classNames(...classes) {
|
||||
}
|
||||
// 处理适配器的安装
|
||||
else if (item.type === 'adapter') {
|
||||
const currentDevice = installedDevices[target];
|
||||
const targetModules = target === 'main' ? mainUnitModules : remoteUnitModules;
|
||||
const targetAdapter = target === 'main' ? mainUnitAdapter : remoteUnitAdapter;
|
||||
|
||||
// 检查是否已安装设备
|
||||
if (!currentDevice) {
|
||||
// alert('请先安装设备,再安装适配器!');
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查设备是否为dsx
|
||||
if (currentDevice.id !== 'dsx') {
|
||||
// alert('适配器只能安装到DSX认证测试仪设备上!');
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否正确安装模块
|
||||
if (!targetModules.some(m => m.id === '8000')) {
|
||||
// alert('请先安装铜缆测试模块,再安装适配器!');
|
||||
@@ -359,7 +431,7 @@ function classNames(...classes) {
|
||||
|
||||
// 检查是否安装了OTDR模块(用于控制远端区域的显示)
|
||||
const hasOtdrModule = mainUnitModules.some(m => m.id === 'ofp');
|
||||
|
||||
const hasWiFiModule = installedDevices.main && installedDevices.main.id === 'wifi';
|
||||
//鼠标元素穿透检测显示到鼠标元素穿透检测显示到StatusToast
|
||||
const [portTooltip, setPortTooltip] = useState('');
|
||||
|
||||
@@ -439,14 +511,14 @@ 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 */}
|
||||
@@ -661,6 +733,7 @@ function classNames(...classes) {
|
||||
faultScenarios === 'Industry' ? <IndustryTask /> :
|
||||
faultScenarios === 'DataCenter' ? <DataCenterTask /> :
|
||||
faultScenarios === 'WorldSkill' ? <WorldSkillTask /> :
|
||||
faultScenarios === 'CopperAnalyzer' ? <CopperAnalyzerTask /> :
|
||||
<WorldSkillTask />}
|
||||
|
||||
</div>
|
||||
@@ -684,7 +757,9 @@ function classNames(...classes) {
|
||||
<div className="h-screen bg-[#0F172A] p-6 overflow-hidden">
|
||||
{/* 故障箱区域 */}
|
||||
<div className="h-[30vh] bg-[#0F172A] shadow-lg p-2 mb-4 border border-[#0ff]/20 rounded-lg">
|
||||
{faultScenarios === 'Office' ? <Office key={useDeviceStore.getState().reloadKey} /> :
|
||||
{
|
||||
faultScenarios === 'CopperAnalyzer' ? <CopperAnalyzer /> :
|
||||
faultScenarios === 'Office' ? <Office key={useDeviceStore.getState().reloadKey} /> :
|
||||
faultScenarios === 'Industry' ? <Industry key={useDeviceStore.getState().reloadKey} /> :
|
||||
faultScenarios === 'DataCenter' ? <DataCenter key={useDeviceStore.getState().reloadKey} /> :
|
||||
faultScenarios === 'WorldSkill' ? (
|
||||
@@ -1067,19 +1142,39 @@ function classNames(...classes) {
|
||||
</p>
|
||||
</div>
|
||||
{/* 隐藏的左侧端点元素 */}
|
||||
{item.portType === 'cal-copper-out' ? (
|
||||
<div
|
||||
id={`benchmark-${index + 1}-left`}
|
||||
jstype={item.portType}
|
||||
lcclean={item.portType === 'fiber' ? 'false' : undefined}
|
||||
className="absolute -left-4 -bottom-4 w-6 h-6 opacity-0"
|
||||
/>
|
||||
) : (
|
||||
<div
|
||||
id={`${item.id}-${index + 1}-left`}
|
||||
jstype={`cable-${item.portType}-left`}
|
||||
lcclean={item.portType === 'fiber' ? 'false' : undefined}
|
||||
className="absolute -left-4 -bottom-4 w-6 h-6 opacity-0"
|
||||
/>
|
||||
{/* 隐藏的右侧端点元素 */}
|
||||
)}
|
||||
|
||||
{/* 隐藏的右侧端点元素 */}
|
||||
{item.portType === 'cal-copper-out' ? (
|
||||
<div
|
||||
id={`benchmark-${index + 1}-right`}
|
||||
jstype={item.portType}
|
||||
lcclean={item.portType === 'fiber' ? 'false' : undefined}
|
||||
className="absolute -right-4 -bottom-4 w-6 h-6 opacity-0"
|
||||
/>
|
||||
) : (
|
||||
<div
|
||||
id={`${item.id}-${index + 1}-right`}
|
||||
jstype={`cable-${item.portType}-right`}
|
||||
lcclean={item.portType === 'fiber' ? 'false' : undefined}
|
||||
className="absolute -right-4 -top-4 w-6 h-6 opacity-0"
|
||||
/>
|
||||
)}
|
||||
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
@@ -1116,62 +1211,78 @@ function classNames(...classes) {
|
||||
}
|
||||
}}
|
||||
>
|
||||
{/* 设备安装容器 */}
|
||||
<div className="relative w-[50%] top-8 aspect-[2/3] mt-8">
|
||||
{/* 适配器安装框 */}
|
||||
{mainUnitModules.some(m => m.id === '8000') && (
|
||||
<div className="absolute -top-14 left-1/2 transform -translate-x-1/2 w-28 h-20 border-2 border-dashed border-[#0ff]/30 rounded-lg flex items-center justify-center">
|
||||
{mainUnitAdapter ? (
|
||||
<div className="relative w-full h-full">
|
||||
<div
|
||||
className="relative w-full h-full"
|
||||
onContextMenu={(e) => handleContextMenu(e, 'main', { type: 'adapter' })}
|
||||
>
|
||||
<Image
|
||||
src={getAssetUrl(mainUnitAdapter.image)}
|
||||
alt={mainUnitAdapter.name}
|
||||
fill
|
||||
sizes={"auto"}
|
||||
className="object-contain p-1"
|
||||
/>
|
||||
</div>
|
||||
{/* 适配器顶部的连线框 */}
|
||||
<div
|
||||
className="absolute -top-0 h-10 rounded-lg group"
|
||||
id={`main-${mainUnitAdapter.port.id}`}
|
||||
jstype={`${mainUnitAdapter.jstype}`}
|
||||
>
|
||||
</div>
|
||||
{installedDevices.main ? (
|
||||
<div
|
||||
className="relative w-full h-full"
|
||||
onContextMenu={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
handleContextMenu(e, 'main', { type: 'device', device: installedDevices.main });
|
||||
}}
|
||||
>
|
||||
{/* 适配器安装框 */}
|
||||
{mainUnitModules.some(m => m.id === '8000') && (
|
||||
<div className="absolute -top-14 left-1/2 transform -translate-x-1/2 w-28 h-20 border-2 border-dashed border-[#0ff]/30 rounded-lg flex items-center justify-center">
|
||||
{mainUnitAdapter ? (
|
||||
<div className="relative w-full h-full">
|
||||
<div
|
||||
className="relative w-full h-full"
|
||||
onContextMenu={(e) => handleContextMenu(e, 'main', { type: 'adapter' })}
|
||||
>
|
||||
<Image
|
||||
src={getAssetUrl(mainUnitAdapter.image)}
|
||||
alt={mainUnitAdapter.name}
|
||||
fill
|
||||
sizes={"auto"}
|
||||
className="object-contain p-1"
|
||||
/>
|
||||
</div>
|
||||
{/* 适配器顶部的连线框 */}
|
||||
<div
|
||||
className="absolute -top-0 h-10 rounded-lg group"
|
||||
id={`main-${mainUnitAdapter.port.id}`}
|
||||
jstype={`${mainUnitAdapter.jstype}`}
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<span className="text-[#0ff] text-xs">适配器插槽</span>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<span className="text-[#0ff] text-xs">适配器插槽</span>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 接口框 */}
|
||||
{mainUnitPorts.length > 0 && (
|
||||
<div className="absolute -top-7 left-0 right-0 flex justify-center gap-3">
|
||||
{mainUnitPorts.map((port, index,) => (
|
||||
<div
|
||||
key={index}
|
||||
id={`main-${port.id}`}
|
||||
jstype={`modelport-${port.module === '8000' ? 'copper' : 'fiber'}`}
|
||||
className="w-6 h-8 border-2 border-dashed border-[#0ff]/30 rounded-lg relative group"
|
||||
lcclean={['cfp', 'ofp'].includes(port.module) ? 'false' : undefined}
|
||||
>
|
||||
{/* 接口框 */}
|
||||
{mainUnitPorts.length > 0 && (
|
||||
<div className="absolute -top-7 left-0 right-0 flex justify-center gap-3">
|
||||
{mainUnitPorts.map((port, index,) => (
|
||||
<div
|
||||
key={index}
|
||||
id={`main-${port.id}`}
|
||||
jstype={port.type === 'cal-copper' ? 'cal-copper' : `modelport-${port.module === '8000' ? 'copper' : 'fiber'}`}
|
||||
className="w-6 h-8 border-2 border-dashed border-[#0ff]/30 rounded-lg relative group"
|
||||
lcclean={['cfp', 'ofp'].includes(port.module) ? 'false' : undefined}
|
||||
>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
)}
|
||||
|
||||
<Image
|
||||
src={getAssetUrl(installedDevices.main.image)}
|
||||
alt={installedDevices.main.name}
|
||||
sizes={"auto"}
|
||||
fill
|
||||
className="object-contain"
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className="w-full h-full border-2 border-dashed border-[#0ff]/30 rounded-lg flex items-center justify-center">
|
||||
<span className="text-[#0ff] text-sm">拖拽设备到此处安装</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Image
|
||||
src={getAssetUrl("/DSX-MA.png")}
|
||||
alt="DSX 主机"
|
||||
sizes={"auto"}
|
||||
fill
|
||||
className="object-contain"
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 已安装模块列表 */}
|
||||
@@ -1191,7 +1302,7 @@ function classNames(...classes) {
|
||||
</div>
|
||||
|
||||
{/* 远端区域 */}
|
||||
{!hasOtdrModule ? (
|
||||
{!hasOtdrModule && !hasWiFiModule ? (
|
||||
<div className="w-[calc(50%-0.5rem)] bg-[#0F172A] shadow-lg p-4 border border-[#0ff]/20 rounded-lg">
|
||||
<div
|
||||
className="rounded-lg h-[calc(100%-3rem)] p-4 flex flex-col items-center justify-center relative"
|
||||
@@ -1217,62 +1328,78 @@ function classNames(...classes) {
|
||||
}
|
||||
}}
|
||||
>
|
||||
{/* 设备安装容器 */}
|
||||
<div className="relative w-[50%] top-8 aspect-[2/3] mt-8">
|
||||
{/* 远端适配器安装框 */}
|
||||
{remoteUnitModules.some(m => m.id === '8000') && (
|
||||
<div className="absolute -top-14 left-1/2 transform -translate-x-1/2 w-28 h-20 border-2 border-dashed border-[#0ff]/30 rounded-lg flex items-center justify-center">
|
||||
{remoteUnitAdapter ? (
|
||||
<div className="relative w-full h-full">
|
||||
<div
|
||||
className="relative w-full h-full"
|
||||
onContextMenu={(e) => handleContextMenu(e, 'remote', { type: 'adapter' })}
|
||||
>
|
||||
<Image
|
||||
src={getAssetUrl(remoteUnitAdapter.image)}
|
||||
alt={remoteUnitAdapter.name}
|
||||
sizes={"auto"}
|
||||
fill
|
||||
className="object-contain p-1"
|
||||
/>
|
||||
</div>
|
||||
{/* 适配器顶部的连线框 */}
|
||||
<div
|
||||
className="absolute -top-0 h-10 rounded-lg group"
|
||||
id={`remote-${remoteUnitAdapter.port.id}`}
|
||||
jstype={`${remoteUnitAdapter.jstype}`}
|
||||
>
|
||||
</div>
|
||||
{installedDevices.remote ? (
|
||||
<div
|
||||
className="relative w-full h-full"
|
||||
onContextMenu={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
handleContextMenu(e, 'remote', { type: 'device', device: installedDevices.remote });
|
||||
}}
|
||||
>
|
||||
{/* 远端适配器安装框 */}
|
||||
{remoteUnitModules.some(m => m.id === '8000') && (
|
||||
<div className="absolute -top-14 left-1/2 transform -translate-x-1/2 w-28 h-20 border-2 border-dashed border-[#0ff]/30 rounded-lg flex items-center justify-center">
|
||||
{remoteUnitAdapter ? (
|
||||
<div className="relative w-full h-full">
|
||||
<div
|
||||
className="relative w-full h-full"
|
||||
onContextMenu={(e) => handleContextMenu(e, 'remote', { type: 'adapter' })}
|
||||
>
|
||||
<Image
|
||||
src={getAssetUrl(remoteUnitAdapter.image)}
|
||||
alt={remoteUnitAdapter.name}
|
||||
sizes={"auto"}
|
||||
fill
|
||||
className="object-contain p-1"
|
||||
/>
|
||||
</div>
|
||||
{/* 适配器顶部的连线框 */}
|
||||
<div
|
||||
className="absolute -top-0 h-10 rounded-lg group"
|
||||
id={`remote-${remoteUnitAdapter.port.id}`}
|
||||
jstype={`${remoteUnitAdapter.jstype}`}
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<span className="text-[#0ff] text-xs">适配器插槽</span>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<span className="text-[#0ff] text-xs">适配器插槽</span>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 远端接口框 */}
|
||||
{remoteUnitPorts.length > 0 && (
|
||||
<div className="absolute -top-7 left-0 right-0 flex justify-center gap-3">
|
||||
{remoteUnitPorts.map((port, index) => (
|
||||
<div
|
||||
key={index}
|
||||
id={`remote-${port.id}`}
|
||||
jstype={`modelport-${port.module === '8000' ? 'copper' : 'fiber'}`}
|
||||
className="w-6 h-8 border-2 border-dashed border-[#0ff]/30 rounded-lg relative group"
|
||||
lcclean={['cfp', 'ofp'].includes(port.module) ? 'false' : undefined}
|
||||
>
|
||||
{/* 远端接口框 */}
|
||||
{remoteUnitPorts.length > 0 && (
|
||||
<div className="absolute -top-7 left-0 right-0 flex justify-center gap-3">
|
||||
{remoteUnitPorts.map((port, index) => (
|
||||
<div
|
||||
key={index}
|
||||
id={`remote-${port.id}`}
|
||||
jstype={port.type === 'cal-copper' ? 'cal-copper' : `modelport-${port.module === '8000' ? 'copper' : 'fiber'}`}
|
||||
className="w-6 h-8 border-2 border-dashed border-[#0ff]/30 rounded-lg relative group"
|
||||
lcclean={['cfp', 'ofp'].includes(port.module) ? 'false' : undefined}
|
||||
>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
)}
|
||||
|
||||
<Image
|
||||
src={getAssetUrl(installedDevices.remote.image)}
|
||||
alt={installedDevices.remote.name}
|
||||
sizes={"auto"}
|
||||
fill
|
||||
className="object-contain"
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className="w-full h-full border-2 border-dashed border-[#0ff]/30 rounded-lg flex items-center justify-center">
|
||||
<span className="text-[#0ff] text-sm">拖拽设备到此处安装</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Image
|
||||
src={getAssetUrl("/DSX-RE.png")}
|
||||
alt="DSX 远端"
|
||||
sizes={"auto"}
|
||||
fill
|
||||
className="object-contain"
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 已安装模块列表 */}
|
||||
@@ -1294,76 +1421,119 @@ function classNames(...classes) {
|
||||
<div className="w-[calc(50%-0.5rem)]"></div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{/* 配件区域 */}
|
||||
<div className="w-[23%] bg-[#0F172A] shadow-lg p-4 border border-[#0ff]/20 flex flex-col h-full rounded-lg">
|
||||
<div className="flex flex-col flex-1">
|
||||
<Tab.Group as="div" className="flex flex-col flex-1">
|
||||
<Tab.Group as="div" className="flex flex-col flex-1" selectedIndex={selectedTabIndex} onChange={setSelectedTabIndex}>
|
||||
<Tab.List className="flex space-x-1 rounded-xl bg-[#0ff]/10 p-1 flex-shrink-0">
|
||||
{Object.keys(devices).map((category) => (
|
||||
<Tab
|
||||
key={category}
|
||||
className={({ selected }) =>
|
||||
classNames(
|
||||
'w-full rounded-lg py-2.5 text-sm font-medium leading-5',
|
||||
'ring-[#0ff] ring-opacity-60 ring-offset-2 ring-offset-[#0F172A] focus:outline-none focus:ring-2',
|
||||
selected
|
||||
? 'bg-[#0F172A] shadow text-[#00ff7f]'
|
||||
: 'text-[#0ff] hover:bg-[#0ff]/[0.12] hover:text-[#00ff7f]'
|
||||
)
|
||||
{(() => {
|
||||
// 根据主机安装的设备类型过滤显示的设备类别
|
||||
const mainDevice = installedDevices.main;
|
||||
let allowedCategories = ['设备']; // 默认显示设备
|
||||
|
||||
if (mainDevice) {
|
||||
if (mainDevice.id === 'dsx') {
|
||||
// 如果安装了dsx,显示设备、模块、适配器、跳线、连接器、工具
|
||||
allowedCategories = ['设备', '模块', '适配器', '跳线', '连接器', '工具'];
|
||||
} else if (mainDevice.id === 'est-analyzer') {
|
||||
// 如果安装了est-analyzer,显示设备和夹具
|
||||
allowedCategories = ['设备', '夹具', '基准'];
|
||||
} else if (mainDevice.id === 'wifi') {
|
||||
// 如果安装了wifi,只显示设备
|
||||
allowedCategories = ['设备'];
|
||||
}
|
||||
>
|
||||
{category}
|
||||
</Tab>
|
||||
))}
|
||||
}
|
||||
|
||||
return Object.keys(devices)
|
||||
.filter(category => allowedCategories.includes(category))
|
||||
.map((category) => (
|
||||
<Tab
|
||||
key={category}
|
||||
className={({ selected }) =>
|
||||
classNames(
|
||||
'w-full rounded-lg py-2.5 text-sm font-medium leading-5',
|
||||
'ring-[#0ff] ring-opacity-60 ring-offset-2 ring-offset-[#0F172A] focus:outline-none focus:ring-2',
|
||||
selected
|
||||
? 'bg-[#0F172A] shadow text-[#00ff7f]'
|
||||
: 'text-[#0ff] hover:bg-[#0ff]/[0.12] hover:text-[#00ff7f]'
|
||||
)
|
||||
}
|
||||
>
|
||||
{category}
|
||||
</Tab>
|
||||
));
|
||||
})()}
|
||||
</Tab.List>
|
||||
<Tab.Panels className="flex-1 mt-2 relative">
|
||||
{Object.entries(devices).map(([category, categoryDevices], idx) => (
|
||||
<Tab.Panel
|
||||
key={idx}
|
||||
className="absolute inset-0 overflow-y-auto custom-scrollbar"
|
||||
>
|
||||
<div className="grid grid-cols-2 gap-3 p-2">
|
||||
{categoryDevices.map((device) => {
|
||||
const isSelected = category === '工具' && device.id === useDeviceStore.getState().selectedTool?.id;
|
||||
return (
|
||||
<div
|
||||
key={device.id}
|
||||
className={`bg-[#0F172A] p-2 rounded shadow border ${isSelected ? 'border-[#00ff7f]' : 'border-[#0ff]/20 hover:border-[#0ff]/40'} transition-colors cursor-pointer z-3000`}
|
||||
draggable={category !== '工具'}
|
||||
onDragStart={(e) => handleDragStart(e, device)}
|
||||
onClick={() => {
|
||||
if (category === '工具') {
|
||||
if (isSelected) {
|
||||
useDeviceStore.getState().clearSelectedTool();
|
||||
} else {
|
||||
useDeviceStore.getState().selectTool(device);
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
{device.image && (
|
||||
<div className="relative w-full aspect-[1/1] mb-2">
|
||||
<Image
|
||||
src={getAssetUrl(device.image)}
|
||||
alt={device.name}
|
||||
sizes={"auto"}
|
||||
fill
|
||||
className="object-contain p-1"
|
||||
/>
|
||||
{(() => {
|
||||
// 根据主机安装的设备类型过滤显示的设备类别
|
||||
const mainDevice = installedDevices.main;
|
||||
let allowedCategories = ['设备']; // 默认显示设备
|
||||
|
||||
if (mainDevice) {
|
||||
if (mainDevice.id === 'dsx') {
|
||||
// 如果安装了dsx,显示设备、模块、适配器、跳线、连接器、工具
|
||||
allowedCategories = ['设备', '模块', '适配器', '跳线', '连接器', '工具'];
|
||||
} else if (mainDevice.id === 'est-analyzer') {
|
||||
// 如果安装了est-analyzer,显示设备和夹具
|
||||
allowedCategories = ['设备', '夹具', '基准'];
|
||||
} else if (mainDevice.id === 'wifi') {
|
||||
// 如果安装了wifi,只显示设备
|
||||
allowedCategories = ['设备'];
|
||||
}
|
||||
}
|
||||
|
||||
return Object.entries(devices)
|
||||
.filter(([category]) => allowedCategories.includes(category))
|
||||
.map(([category, categoryDevices], idx) => (
|
||||
<Tab.Panel
|
||||
key={idx}
|
||||
className="absolute inset-0 overflow-y-auto custom-scrollbar"
|
||||
>
|
||||
<div className="grid grid-cols-2 gap-3 p-2">
|
||||
{categoryDevices.map((device) => {
|
||||
const isSelected = category === '工具' && device.id === useDeviceStore.getState().selectedTool?.id;
|
||||
return (
|
||||
<div
|
||||
key={device.id}
|
||||
className={`bg-[#0F172A] p-2 rounded shadow border ${isSelected ? 'border-[#00ff7f]' : 'border-[#0ff]/20 hover:border-[#0ff]/40'} transition-colors cursor-pointer z-3000`}
|
||||
draggable={category !== '工具'}
|
||||
onDragStart={(e) => handleDragStart(e, device)}
|
||||
onClick={() => {
|
||||
if (category === '工具') {
|
||||
if (isSelected) {
|
||||
useDeviceStore.getState().clearSelectedTool();
|
||||
} else {
|
||||
useDeviceStore.getState().selectTool(device);
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
{device.image && (
|
||||
<div className="relative w-full aspect-[1/1] mb-2">
|
||||
<Image
|
||||
src={getAssetUrl(device.image)}
|
||||
alt={device.name}
|
||||
sizes={"auto"}
|
||||
fill
|
||||
className="object-contain p-1"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<p className={`font-medium ${isSelected ? 'text-[#00ff7f]' : 'text-[#0ff]'} text-sm truncate`}>{device.name}</p>
|
||||
{device.description && (
|
||||
<p className="text-xs text-[#0ff] mt-1 line-clamp-2">{device.description}</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<p className={`font-medium ${isSelected ? 'text-[#00ff7f]' : 'text-[#0ff]'} text-sm truncate`}>{device.name}</p>
|
||||
{device.description && (
|
||||
<p className="text-xs text-[#0ff] mt-1 line-clamp-2">{device.description}</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</Tab.Panel>
|
||||
))}
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</Tab.Panel>
|
||||
));
|
||||
})()}
|
||||
</Tab.Panels>
|
||||
</Tab.Group>
|
||||
</div>
|
||||
@@ -1398,7 +1568,28 @@ function classNames(...classes) {
|
||||
setContextMenu(null);
|
||||
}
|
||||
}
|
||||
] : contextMenu.item?.type === 'adapter' ? [
|
||||
] : contextMenu.item?.type === 'device' ? (
|
||||
((contextMenu.target === 'main' ? mainUnitModules.length : remoteUnitModules.length) > 0)
|
||||
? [
|
||||
{
|
||||
label: '卸载模块',
|
||||
onClick: () => {
|
||||
const modules = contextMenu.target === 'main' ? mainUnitModules : remoteUnitModules;
|
||||
handleUninstall(modules[modules.length - 1].id, contextMenu.target);
|
||||
setContextMenu(null);
|
||||
}
|
||||
}
|
||||
]
|
||||
: [
|
||||
{
|
||||
label: '卸载设备',
|
||||
onClick: () => {
|
||||
uninstallDevice(contextMenu.target);
|
||||
setContextMenu(null);
|
||||
}
|
||||
}
|
||||
]
|
||||
) : contextMenu.item?.type === 'adapter' ? [
|
||||
{
|
||||
label: '卸载适配器',
|
||||
onClick: () => {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { devtools } from 'zustand/middleware';
|
||||
|
||||
|
||||
const useDeviceStore = create(
|
||||
// devtools(
|
||||
devtools(
|
||||
(set, get) => ({
|
||||
// 版本控制
|
||||
estmodel: 'general',
|
||||
@@ -12,6 +12,29 @@ const useDeviceStore = create(
|
||||
|
||||
// 各个类别的设备
|
||||
devices: {
|
||||
'设备': [
|
||||
{
|
||||
id: 'dsx',
|
||||
name: '认证测试仪',
|
||||
type: 'device',
|
||||
image: '/DSX-MA.png',
|
||||
description: '认证分析测试仪仪'
|
||||
},
|
||||
{
|
||||
id: 'est-analyzer',
|
||||
name: '线缆分析仪',
|
||||
type: 'device',
|
||||
image: '/cableanalyzer.png',
|
||||
description: '平衡/不平衡分析仪'
|
||||
},
|
||||
{
|
||||
id: 'wifi',
|
||||
name: '无线分析仪',
|
||||
type: 'device',
|
||||
image: '/wifi.png',
|
||||
description: '无线信号分析仪'
|
||||
}
|
||||
],
|
||||
'模块': [
|
||||
{
|
||||
id: '8000',
|
||||
@@ -201,6 +224,35 @@ const useDeviceStore = create(
|
||||
description: '音频探棒'
|
||||
}
|
||||
],
|
||||
|
||||
'夹具': [
|
||||
{
|
||||
id: 'cal-2p',
|
||||
name: '测试夹具-2芯',
|
||||
type: 'module',
|
||||
portType: 'copper',
|
||||
image: '/CAL-2P.png',
|
||||
description: '插座测试夹具2芯'
|
||||
},
|
||||
{
|
||||
id: 'cal-4p',
|
||||
name: '测试夹具-4芯',
|
||||
type: 'module',
|
||||
portType: 'copper',
|
||||
image: '/CAL-4P.png',
|
||||
description: '插座测试夹具4芯'
|
||||
}
|
||||
],
|
||||
'基准': [
|
||||
{
|
||||
id: 'pachcode-copper',
|
||||
name: '基准连接器',
|
||||
type: 'cable',
|
||||
portType: 'cal-copper-out',
|
||||
image: '/benchmark.png',
|
||||
description: '基准连接'
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
@@ -210,6 +262,7 @@ const useDeviceStore = create(
|
||||
// faultScenarios: "WorldSkill",
|
||||
// faultScenarios: "Industry",
|
||||
// faultScenarios: "DataCenter",
|
||||
// faultScenarios: "CopperAnalyzer",
|
||||
WorldSkillScenarios: "OFFICE",
|
||||
// 赛位号
|
||||
seatNumber: "",
|
||||
@@ -219,6 +272,8 @@ const useDeviceStore = create(
|
||||
seatStartTime:null,
|
||||
// 表单记录
|
||||
reports:[],
|
||||
// 当前安装设备 - 格式: { main: device, remote: device }
|
||||
installedDevices: { main: null, remote: null },
|
||||
// 主机已安装模块
|
||||
mainUnitModules: [],
|
||||
// 远端已安装模块
|
||||
@@ -239,6 +294,21 @@ const useDeviceStore = create(
|
||||
connectionPaths: [],
|
||||
// 连接状态分析结果
|
||||
connectionStatus: [],
|
||||
|
||||
// 线缆参数
|
||||
cableParams: {
|
||||
conductorMaterial: 'copper',
|
||||
coreDiameter: 0.57,
|
||||
insulationMaterial: 'pe',
|
||||
insulationThickness: 0.2,
|
||||
twistPitch: 12, // 绞距 (mm)
|
||||
pair2TwistRatio: 1.0, // 第二对绞距比例 (相对于第一对)
|
||||
cableLength: 100, // 线缆长度 (m)
|
||||
R: 0, // 电阻 R′ (Ω/m)
|
||||
L: 0, // 电感 L′ (nH/m)
|
||||
C: 0, // 电容 C′ (pF/m)
|
||||
G: 0 // 电导 G′ (nS/m)
|
||||
},
|
||||
|
||||
// 选择工具
|
||||
selectTool: (tool) => {
|
||||
@@ -249,6 +319,43 @@ const useDeviceStore = create(
|
||||
set({ selectedTool: null });
|
||||
},
|
||||
|
||||
// 安装设备
|
||||
installDevice: (device, target) => {
|
||||
set((state) => ({
|
||||
installedDevices: {
|
||||
...state.installedDevices,
|
||||
[target]: device
|
||||
}
|
||||
}));
|
||||
},
|
||||
|
||||
// 卸载设备
|
||||
uninstallDevice: (target) => {
|
||||
set((state) => {
|
||||
// 卸载设备时,同时清除该设备上的所有模块和适配器
|
||||
const updates = {
|
||||
installedDevices: {
|
||||
...state.installedDevices,
|
||||
[target]: null
|
||||
}
|
||||
};
|
||||
|
||||
// 清除对应的模块和适配器
|
||||
if (target === 'main') {
|
||||
updates.mainUnitModules = [];
|
||||
updates.mainUnitAdapter = null;
|
||||
updates.mainUnitFixture = null;
|
||||
updates.mainUnitPorts = [];
|
||||
} else {
|
||||
updates.remoteUnitModules = [];
|
||||
updates.remoteUnitAdapter = null;
|
||||
updates.remoteUnitPorts = [];
|
||||
}
|
||||
|
||||
return updates;
|
||||
});
|
||||
},
|
||||
|
||||
// 安装模块
|
||||
installModule: (module, target) => {
|
||||
set((state) => {
|
||||
@@ -267,6 +374,18 @@ const useDeviceStore = create(
|
||||
{ id: 'ofp-mm-out', type: 'modelport', module: 'ofp' },
|
||||
{ id: 'vfl', type: 'modelport', module: 'ofp' }
|
||||
];
|
||||
} else if (module.id === 'cal-2p') {
|
||||
ports = [
|
||||
{ id: 'cal-1p-1', type: 'cal-copper', module: 'cal-2p' },
|
||||
{ id: 'cal-1p-2', type: 'cal-copper', module: 'cal-2p' }
|
||||
];
|
||||
} else if (module.id === 'cal-4p') {
|
||||
ports = [
|
||||
{ id: 'cal-2p-1', type: 'cal-copper', module: 'cal-4p' },
|
||||
{ id: 'cal-2p-2', type: 'cal-copper', module: 'cal-4p' },
|
||||
{ id: 'cal-2p-3', type: 'cal-copper', module: 'cal-4p' },
|
||||
{ id: 'cal-2p-4', type: 'cal-copper', module: 'cal-4p' }
|
||||
];
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -282,6 +401,18 @@ const useDeviceStore = create(
|
||||
{ id: 'cfp-mm-out', type: 'modelport', module: 'cfp' },
|
||||
{ id: 'vfl', type: 'modelport', module: 'cfp' }
|
||||
];
|
||||
} else if (module.id === 'cal-2p') {
|
||||
ports = [
|
||||
{ id: 'cal-1p-1', type: 'cal-copper', module: 'cal-2p' },
|
||||
{ id: 'cal-1p-2', type: 'cal-copper', module: 'cal-2p' }
|
||||
];
|
||||
} else if (module.id === 'cal-4p') {
|
||||
ports = [
|
||||
{ id: 'cal-2p-1', type: 'cal-copper', module: 'cal-4p' },
|
||||
{ id: 'cal-2p-2', type: 'cal-copper', module: 'cal-4p' },
|
||||
{ id: 'cal-2p-3', type: 'cal-copper', module: 'cal-4p' },
|
||||
{ id: 'cal-2p-4', type: 'cal-copper', module: 'cal-4p' }
|
||||
];
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -331,6 +462,7 @@ const useDeviceStore = create(
|
||||
[target === 'main' ? 'mainUnitAdapter' : 'remoteUnitAdapter']: null
|
||||
}));
|
||||
},
|
||||
|
||||
|
||||
// 更新故障场景
|
||||
updateFaultScenarios: (status) => {
|
||||
@@ -431,11 +563,51 @@ const useDeviceStore = create(
|
||||
setShowTotalToast: (show) => set({ showTotalToast: show }),
|
||||
setTotalToastMessage: (message) => set({ totalToastMessage: message }),
|
||||
|
||||
// ---***线缆参数管理***---
|
||||
|
||||
// 更新线缆参数
|
||||
updateCableParams: (params) =>
|
||||
set((state) => ({
|
||||
cableParams: {
|
||||
...state.cableParams,
|
||||
...params
|
||||
}
|
||||
})),
|
||||
|
||||
// 更新单个线缆参数
|
||||
updateSingleCableParam: (key, value) =>
|
||||
set((state) => ({
|
||||
cableParams: {
|
||||
...state.cableParams,
|
||||
[key]: value
|
||||
}
|
||||
})),
|
||||
|
||||
// 重置线缆参数
|
||||
resetCableParams: () =>
|
||||
set(() => ({
|
||||
cableParams: {
|
||||
conductorMaterial: 'copper',
|
||||
coreDiameter: 0.57,
|
||||
insulationMaterial: 'pe',
|
||||
insulationThickness: 0.2,
|
||||
twistPitch: 12,
|
||||
pair2TwistRatio: 1.0,
|
||||
cableLength: 100,
|
||||
R: 0,
|
||||
L: 0,
|
||||
C: 0,
|
||||
G: 0
|
||||
}
|
||||
})),
|
||||
|
||||
// 初始化数据
|
||||
|
||||
// 重置到默认状态
|
||||
resetdeviceStore: () => {
|
||||
set(() => ({
|
||||
// 当前安装设备
|
||||
installedDevices: { main: null, remote: null },
|
||||
// 主机已安装模块
|
||||
mainUnitModules: [],
|
||||
// 远端已安装模块
|
||||
@@ -458,6 +630,20 @@ const useDeviceStore = create(
|
||||
connectionStatus: [],
|
||||
// 报告数据
|
||||
reports: [],
|
||||
// 线缆参数
|
||||
cableParams: {
|
||||
conductorMaterial: 'copper',
|
||||
coreDiameter: 0.57,
|
||||
insulationMaterial: 'pe',
|
||||
insulationThickness: 0.2,
|
||||
twistPitch: 12,
|
||||
pair2TwistRatio: 1.0,
|
||||
cableLength: 100,
|
||||
R: 0,
|
||||
L: 0,
|
||||
C: 0,
|
||||
G: 0
|
||||
}
|
||||
}));
|
||||
},
|
||||
|
||||
@@ -466,7 +652,8 @@ const useDeviceStore = create(
|
||||
})
|
||||
|
||||
//devtools
|
||||
// )
|
||||
)
|
||||
|
||||
);
|
||||
|
||||
|
||||
|
||||
@@ -52,3 +52,14 @@ img {
|
||||
outline-color: rgba(0, 255, 255, 0.8);
|
||||
}
|
||||
}
|
||||
|
||||
/* 隐藏滚动条但保留滚动功能 */
|
||||
.no-scrollbar {
|
||||
-ms-overflow-style: none; /* IE and old Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
.no-scrollbar::-webkit-scrollbar {
|
||||
display: none; /* Chrome, Safari, new Edge */
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user