import React, { useState, useEffect } from 'react';
import StatusBar from '../lib/StatusBar';
import ResultTitleBar from '../lib/ResultTitleBar';
import TitleBar from '../lib/TitleBar';
import CopperResultMain from '../lib/CopperResultMain';
import OLTSResultMain from '../lib/OLTSResultMain';
import OTDRResultMain from '../lib/OTDRResultMain';
import Keyboard from '../lib/Keyboard';
import useDisplayStore from '@/store/displayStore';
// 初始化测试结果音效对象
const testPassSound = typeof Audio !== 'undefined' ? new Audio('/sounds/test_pass.wav') : null;
const testFailSound = typeof Audio !== 'undefined' ? new Audio('/sounds/test_fail.wav') : null;
// 自定义确认弹窗组件
const ConfirmDialog = ({ message, onConfirm, onCancel }) => (
);
export default function ResultInfo() {
const [showKeyboard, setShowKeyboard] = useState(true);
const [cursorPosition, setCursorPosition] = useState(0);
const [inputValue, setInputValue] = useState('');
const [inputValue2, setInputValue2] = useState('');
const [activeInput, setActiveInput] = useState(1); // 1 表示第一个输入框,2 表示第二个输入框
const [showConfirmDialog, setShowConfirmDialog] = useState(false);
const [confirmDialogMessage, setConfirmDialogMessage] = useState('');
const [confirmDialogCallback, setConfirmDialogCallback] = useState(null);
const { navigation } = useDisplayStore.getState();
const tempTestResult = navigation.current.params;
// 根据测试结果播放音效
const { hasPlayedSound } = useDisplayStore.getState();
useEffect(() => {
// 只有从测试页面进入nosave视图时才播放声音
if (navigation.previous.name === 'testing' &&
tempTestResult &&
!hasPlayedSound) {
if (tempTestResult.CopperResultStatus === 'pass'||tempTestResult.CFPResultStatus === 'pass' ||tempTestResult.ofpResultStatus === 'pass') {
testPassSound?.play().catch(console.error);
} else {
testFailSound?.play().catch(console.error);
}
useDisplayStore.setState({ hasPlayedSound: true });
}
}, [navigation, tempTestResult, hasPlayedSound]);
// 从URL参数中获取临时测试结果
const {
getCurrentProject,
getCurrentCableId,
getCurrentCableId2,
updateCurrentView,
getCurrentTestConfig,
navigateTo,
setToastMessage,
updateProject
} = useDisplayStore();
const currentProject = getCurrentProject();
const { view } = useDisplayStore.getState().navigation.current;
// 获取当前的线缆ID
const currentCableId = getCurrentCableId().name || '';
const currentCableId2 = getCurrentCableId2().name || '';
// 计算下一个序号的ID
const getNextId = (currentId) => {
if (!currentId) return '';
// 检查是否以数字结尾
const numMatch = currentId.match(/^(.*?)(\d+)$/);
if (numMatch) {
const [, prefix, num] = numMatch;
const nextNum = String(Number(num) + 1).padStart(num.length, '0');
return prefix + nextNum;
}
// 检查是否以字母结尾
const letterMatch = currentId.match(/^(.*?)([a-zA-Z]+)$/);
if (letterMatch) {
const [, prefix, letters] = letterMatch;
// 将字母转换为数组以便处理
const letterArray = letters.split('');
let carry = true;
// 从右向左处理每个字母
for (let i = letterArray.length - 1; i >= 0 && carry; i--) {
if (letterArray[i] === 'z') {
letterArray[i] = 'a';
carry = true;
} else if (letterArray[i] === 'Z') {
letterArray[i] = 'A';
carry = true;
} else {
letterArray[i] = String.fromCharCode(letterArray[i].charCodeAt(0) + 1);
carry = false;
}
}
// 如果还有进位,说明需要在前面添加一个字母
if (carry) {
if (letters[0] >= 'a' && letters[0] <= 'z') {
letterArray.unshift('a');
} else {
letterArray.unshift('A');
}
}
return prefix + letterArray.join('');
}
// 如果既不是数字也不是字母结尾,直接返回原值
return currentId;
};
// 初始化输入值为当前的线缆ID
useEffect(() => {
setInputValue(currentCableId);
setInputValue2(currentCableId2);
}, [currentCableId, currentCableId2]);
// 当第一个输入框值变化时,仅在用户手动输入时自动更新第二个输入框
useEffect(() => {
if (tempTestResult?.testconfig?.moduleType === 'cfp' && inputValue && inputValue !== currentCableId) {
setInputValue2(getNextId(inputValue));
}
}, [inputValue, view, currentCableId]);
//创建保存结果存储逻辑
const handleComplete = () => {
const currentId = inputValue.trim();
// 检查是否存在重名的测试结果
const currentProject = getCurrentProject();
const existingResults = currentProject?.testResults || [];
// 检查两个ID是否重复
const isDuplicate = existingResults.some(result => result.name === currentId);
// 重名替换
if (isDuplicate) {
setConfirmDialogMessage('该线缆ID已使用,是否覆盖?');
setConfirmDialogCallback(() => () => {
// 更新临时测试结果的名称
const updatedTestResult = {
...tempTestResult,
name: currentId
};
// 更新当前项目的测试结果
const currentIndex = useDisplayStore.getState().projects.findIndex(p => p === currentProject);
if (currentIndex !== -1) {
// 移除旧的测试结果并添加新的
const newResults = existingResults.filter(result => result.name !== currentId);
updateProject(currentIndex, {
testResults: [...newResults, updatedTestResult]
});
// 更新navigation.current.params中的测试结果名称
useDisplayStore.setState({
navigation: {
...navigation,
current: {
...navigation.current,
params: updatedTestResult
}
}
});
}
updateCurrentView('save');
setShowConfirmDialog(false);
});
setShowConfirmDialog(true);
return;
}
// 更新临时测试结果的名称并保存到项目中
if (tempTestResult) {
const updatedTestResult = {
...tempTestResult,
name: currentId
};
// 更新当前项目的cableIds.name为下一个ID
const currentIndex = useDisplayStore.getState().projects.findIndex(p => p === currentProject);
if (currentIndex !== -1) {
//更新测试结果
updateProject(currentIndex, {
testResults: [...(currentProject.testResults || []), updatedTestResult]
});
// 更新navigation.current.params中的测试结果名称
const navigation = useDisplayStore.getState().navigation;
useDisplayStore.setState({
navigation: {
...navigation,
current: {
...navigation.current,
params: updatedTestResult
}
}
});
// 获取下一个ID
const nextId = (() => {
const currentId = inputValue.trim();
if (!currentId) return currentId;
// 获取最后一个字符
const lastChar = currentId.slice(-1);
const prefix = currentId.slice(0, -1);
// 如果最后一个字符是数字
if (/\d/.test(lastChar)) {
const match = currentId.match(/^(.*?)(\d+)$/);
if (match) {
const numPrefix = match[1];
const number = parseInt(match[2]) + 1;
return `${numPrefix}${number.toString().padStart(match[2].length, '0')}`;
}
}
// 如果最后一个字符是字母
if (/[A-Za-z]/.test(lastChar)) {
const nextChar = String.fromCharCode(lastChar.charCodeAt(0) + 1);
// 如果超过Z或z,回到A或a
if ((lastChar === 'Z' && nextChar > 'Z') || (lastChar === 'z' && nextChar > 'z')) {
const baseChar = lastChar === 'Z' ? 'A' : 'a';
return `${prefix}${baseChar}`;
}
return `${prefix}${nextChar}`;
}
return currentId;
})();
// 获取当前项目的所有cableIds
const currentCableIds = currentProject?.cableIds || [];
const selectedId = getCurrentCableId().id;
// 只更新选中的ID,保留其他ID不变
const updatedCableIds = currentCableIds.map(cable =>
cable.id === selectedId ? { ...cable, name: nextId } : cable
);
// 更新项目
updateProject(currentIndex, {
cableIds: updatedCableIds
});
}
updateCurrentView('save');
}
}
const handleComplete2 = () => {
const currentId = inputValue.trim();
const currentId2 = inputValue2.trim();
// 检查两个ID是否相同
if (currentId === currentId2) {
setConfirmDialogMessage('输入输出ID不能相同,请检查');
setConfirmDialogCallback(() => () => {
setShowConfirmDialog(false);
});
setShowConfirmDialog(true);
return;
}
// 检查是否存在重名的测试结果
const currentProject = getCurrentProject();
const existingResults = currentProject?.testResults || [];
// 检查两个ID是否重复
const isDuplicate1 = existingResults.some(result => result.name === currentId);
const isDuplicate2 = existingResults.some(result => result.name === currentId2);
const currentConfig = getCurrentTestConfig();
const cableType = currentConfig.params.cableType;
const isMultiMode = cableType.includes('OM');
if (isDuplicate1 || isDuplicate2) {
const message = [];
if (isDuplicate1) message.push(`线缆ID ${currentId}`);
if (isDuplicate2) message.push(`线缆ID ${currentId2}`);
setConfirmDialogMessage(`${message.join(' 和 ')}已使用,是否覆盖?`);
setConfirmDialogCallback(() => () => {
// 更新临时测试结果的名称
const updatedTestResult1 = {
...tempTestResult,
name: currentId,
inputname: isMultiMode ? currentId2 : currentId,
outname: isMultiMode ? currentId : currentId2,
};
const updatedTestResult2 = {
...tempTestResult,
name: currentId2,
inputname: isMultiMode ? currentId2 : currentId,
outname: isMultiMode ? currentId : currentId2,
};
// 更新当前项目的测试结果
const currentIndex = useDisplayStore.getState().projects.findIndex(p => p === currentProject);
if (currentIndex !== -1) {
// 移除旧的测试结果并添加新的
const newResults = existingResults.filter(result =>
result.name !== currentId && result.name !== currentId2
);
updateProject(currentIndex, {
testResults: [...newResults, updatedTestResult1, updatedTestResult2]
});
// 更新navigation.current.params中的测试结果名称
useDisplayStore.setState({
navigation: {
...navigation,
current: {
...navigation.current,
params: updatedTestResult1
}
}
});
}
updateCurrentView('save');
setShowConfirmDialog(false);
});
setShowConfirmDialog(true);
return;
}
// 更新临时测试结果的名称并保存到项目中
if (tempTestResult) {
// 创建两个测试结果
const updatedTestResult1 = {
...tempTestResult,
name: currentId,
inputname: isMultiMode ? currentId2 : currentId,
outname: isMultiMode ? currentId : currentId2,
};
const updatedTestResult2 = {
...tempTestResult,
name: currentId2,
inputname: isMultiMode ? currentId2 : currentId,
outname: isMultiMode ? currentId : currentId2,
};
// 更新当前项目的cableIds.name为下一个ID
const currentIndex = useDisplayStore.getState().projects.findIndex(p => p === currentProject);
if (currentIndex !== -1) {
//更新测试结果
updateProject(currentIndex, {
testResults: [...(currentProject.testResults || []), updatedTestResult1,updatedTestResult2]
});
// 更新navigation.current.params中的测试结果名称
const navigation = useDisplayStore.getState().navigation;
useDisplayStore.setState({
navigation: {
...navigation,
current: {
...navigation.current,
params: updatedTestResult1
}
}
});
// 获取下一个ID
const nextId = getNextId(getNextId(inputValue.trim()));
// 获取下一个ID2
const nextId2 = getNextId(getNextId(inputValue2.trim()));
// 获取当前项目的所有cableIds
const currentCableIds = currentProject?.cableIds || [];
const selectedId = getCurrentCableId().id;
const selectedId2 = getCurrentCableId2().id;
// 只更新选中的ID,保留其他ID不变
const updatedCableIds = currentCableIds.map(cable =>
cable.id === selectedId ? { ...cable, name: nextId } :
cable.id === selectedId2 ? { ...cable, name: nextId2 } :
cable
);
// 更新项目,添加两个测试结果
updateProject(currentIndex, {
cableIds: updatedCableIds,
});
}
updateCurrentView('save');
}
}
// 创建测试结果的视图
const renderContent = () => {
const renderResultMain = () => {
const moduleType = tempTestResult?.testconfig?.moduleType;
switch (moduleType) {
case '8000':
return ;
case 'cfp':
return ;
case 'ofp':
return ;
default:
return ;
}
};
const renderSetName = () => {
const moduleType = tempTestResult?.testconfig?.moduleType;
switch (moduleType) {
case 'cfp':
return(
{showKeyboard && (
{
if (activeInput === 1) {
setInputValue(newValue);
} else {
setInputValue2(newValue);
}
setCursorPosition(newPosition);
}}
onComplete={() => {
setShowKeyboard(false);
}}
/>
)}
);
default:
return (
);
}
};
switch (view) {
case 'nosave':
return (
{tempTestResult?.testconfig?.moduleType !== 'cfp' ? (
) : (
)}
{renderResultMain()}
);
case 'setname':
return (
{renderSetName()}
{tempTestResult?.testconfig?.moduleType === "cfp" ? (
!showKeyboard && (
)
) : (
!showKeyboard && (
)
)}
);
case 'save':
return (
{tempTestResult?.testconfig?.moduleType !== 'cfp' ? (
) : (
)}
{renderResultMain()}
);
default:
return null;
}
};
const content = renderContent();
return (
{content}
{showConfirmDialog && (
setShowConfirmDialog(false)}
/>
)}
);
}