Files
EST-DSX/src/components/scene/WorldSkill.js
2025-09-16 16:39:48 +08:00

361 lines
16 KiB
JavaScript

import React, { useState, useEffect } from 'react';
import useDeviceStore from '@/store/deviceStore';
import Image from 'next/image';
export default function WorldSkill({
onPortClick = () => {},
onPortHover = () => {},
selectedPort = null,
targetPort = null,
connections = {}
}) {
// 获取端口的连接状态样式
const getPortStyle = (portId) => {
if (selectedPort === portId) {
return 'bg-blue-300';
}
if (targetPort === portId) {
return 'bg-green-300';
}
if (connections && connections[portId]) {
return 'bg-[#00ff7f]';
}
return 'bg-gray-300';
};
const {faultScenarios,seatUUID,seatNumber,updateWorldSkillScenarios} = useDeviceStore();
// 从localStorage加载清洁状态
const loadCleanState = () => {
if (!seatUUID) return;
const lccleanStates = JSON.parse(localStorage.getItem(`cleanState_${seatUUID}_lc`) || '{}');
// 恢复LC端口状态
document.querySelectorAll('[lcclean]').forEach(el => {
const elementId = el.id;
if (elementId && lccleanStates[elementId] !== undefined) {
el.setAttribute('lcclean', lccleanStates[elementId].toString());
}
});
};
// 监听seatUUID变化
useEffect(() => {
if (seatUUID) {
// 使用setTimeout确保DOM元素已加载
setTimeout(loadCleanState, 500);
}
}, [seatUUID]);
return (
<div>
{/* 办公区域 */}
<div className="h-full w-full bg-black text-white flex z-index-100">
{/* Room */}
<div className="w-[12%] p-1 flex flex-col">
{/* Room 1 - 上半部分 */}
<div className="flex-1 flex flex-col">
<div className="text-center mb-1">Room1</div>
<div className="flex-1 bg-gray-900 flex items-center justify-center">
<div className="bg-gray-300 w-24 h-24 flex items-center justify-center">
<div className="flex space-x-2">
<div className="flex flex-col items-center">
<div
className={`rounded-full flex items-center justify-center transition-colors ${getPortStyle('Room1-TO-1')}`}
jstype="testport-copper"
id="Room1-TO-1"
onClick={() => onPortClick('Room1-TO-1')}
onMouseEnter={() => onPortHover('Room1-TO-1')}
>
<div className={`w-8 h-8 bg-[url('/rj45.png')] bg-contain bg-no-repeat bg-center`}></div>
</div>
<span className="text-xs mt-1 text-black">TO-1</span>
</div>
<div className="flex flex-col items-center">
<div
className={`rounded-full flex items-center justify-center transition-colors ${getPortStyle('Room1-TO-2')}`}
jstype="testport-copper"
id="Room1-TO-2"
onClick={() => onPortClick('Room1-TO-2')}
onMouseEnter={() => onPortHover('Room1-TO-2')}
>
<div className={`w-8 h-8 bg-[url('/rj45.png')] bg-contain bg-no-repeat bg-center`}></div>
</div>
<span className="text-xs mt-1 text-black">TO-2</span>
</div>
</div>
</div>
</div>
</div>
{/* Room 3 - 下半部分 */}
<div className="flex-1 flex flex-col">
<div className="text-center mb-1">Room3</div>
<div className="flex-1 bg-gray-900 flex items-center justify-center">
<div className="bg-gray-300 w-24 h-24 flex items-center justify-center">
<div className="flex space-x-2">
<div className="flex flex-col items-center">
<div
className={`rounded-full flex items-center justify-center transition-colors ${getPortStyle('Room3-TO-1')}`}
jstype="testport-copper"
id="Room3-TO-1"
onClick={() => onPortClick('Room3A-TO-1')}
onMouseEnter={() => onPortHover('Room3-TO-1')}
>
<div className={`w-8 h-8 bg-[url('/rj45.png')] bg-contain bg-no-repeat bg-center`}></div>
</div>
<span className="text-xs mt-1 text-black">TO-1</span>
</div>
<div className="flex flex-col items-center">
<div
className={`rounded-full flex items-center justify-center transition-colors ${getPortStyle('Room3-TO-2')}`}
jstype="testport-copper"
id="Room3-TO-2"
onClick={() => onPortClick('Room3-TO-2')}
onMouseEnter={() => onPortHover('Room3-TO-2')}
>
<div className={`w-8 h-8 bg-[url('/rj45.png')] bg-contain bg-no-repeat bg-center`}></div>
</div>
<span className="text-xs mt-1 text-black">TO-2</span>
</div>
</div>
</div>
</div>
</div>
</div>
{/* Room 4 */}
<div className="w-[12%] p-1 flex flex-col">
{/* Room 1A - 上半部分 */}
<div className="flex-1 flex flex-col">
<div className="text-center mb-1">Room4</div>
<div className="relative flex-1 bg-gray-900 flex items-center justify-center">
<div
className={`absolute top-[55%] left-[66%] w-6 h-6 z-100`}
jstype="testport-cam"
id="Room4-CAM"
onClick={() => onPortClick('Room4-CAM')}
onMouseEnter={() => onPortHover('Room4-CAM')}
>
</div>
<div className={`w-full h-full bg-[url('/cam.png')] bg-contain bg-no-repeat bg-center`}></div>
</div>
</div>
</div>
{/* 2F配线架 */}
<div className="w-[24%] p-1 flex flex-col">
<div className="text-center mb-1">2F-RackA</div>
<div className="h-[calc(100%-1.5rem)] rounded-md p-2 flex flex-col space-y-2">
{/* Row 1A - taking 1/2 of rack height */}
<div className="flex flex-col h-1/2 bg-gray-800 rounded-md p-2 relative">
<div className="absolute top-0 left-0 bg-white w-3 h-3 rounded-full"></div>
<div className="absolute top-0 right-0 bg-white w-3 h-3 rounded-full"></div>
<div className="absolute bottom-0 left-0 bg-white w-3 h-3 rounded-full"></div>
<div className="absolute bottom-0 right-0 bg-white w-3 h-3 rounded-full"></div>
<div className="flex-1 flex items-center">
<span className="text-xs mr-4">1A</span>
<div className="flex-1 flex items-center justify-center space-x-6">
{[...Array(3)].map((_, groupIndex) => (
<div key={groupIndex} className="flex">
{[0, 1].map((portIndex) => {
const portId = `2F-RackA-1A-${groupIndex * 2 + portIndex + 1}`;
const portNumber = groupIndex * 2 + portIndex + 1;
return (
<div key={portIndex} className="flex flex-col items-center">
<div
className={`mb-1 transition-colors flex items-center justify-center`}
>
<div
className={`w-8 h-8 bg-[url('/lc.png')] bg-contain bg-no-repeat bg-center cursor-pointer`}
jstype="testport-fiber"
lcclean="false"
id={portId}
onClick={() => onPortClick(portId)}
onMouseEnter={() => onPortHover(portId)}
></div>
</div>
<span className="text-xs">{portNumber}</span>
</div>
);
})}
</div>
))}
</div>
</div>
</div>
{/* Row 1B - taking 1/2 of rack height */}
<div className="flex flex-col h-1/2 bg-gray-800 rounded-md p-2 relative">
<div className="absolute top-0 left-0 bg-white w-3 h-3 rounded-full"></div>
<div className="absolute top-0 right-0 bg-white w-3 h-3 rounded-full"></div>
<div className="absolute bottom-0 left-0 bg-white w-3 h-3 rounded-full"></div>
<div className="absolute bottom-0 right-0 bg-white w-3 h-3 rounded-full"></div>
<div className="flex-1 flex items-center">
<span className="text-xs mr-4">1B</span>
<div className="flex-1 flex items-center justify-center space-x-6">
{[...Array(3)].map((_, groupIndex) => (
<div key={groupIndex} className="flex">
{[0, 1].map((portIndex) => {
const portId = `2F-RackA-1B-${groupIndex * 2 + portIndex + 1}`;
const portNumber = groupIndex * 2 + portIndex + 1;
return (
<div key={portIndex} className="flex flex-col items-center">
<div
className={`mb-1 transition-colors flex items-center justify-center`}
>
<div
className={`w-8 h-8 bg-[url('/lc.png')] bg-contain bg-no-repeat bg-center cursor-pointer`}
jstype="testport-fiber"
lcclean="false"
id={portId}
onClick={() => onPortClick(portId)}
onMouseEnter={() => onPortHover(portId)}
></div>
</div>
<span className="text-xs">{portNumber}</span>
</div>
);
})}
</div>
))}
</div>
</div>
</div>
</div>
</div>
{/* 1F DataCenter */}
<div className="w-[50%] p-1 flex flex-col">
<div className="text-center mb-1">1F-RackA</div>
<div className="h-[calc(100%-1.5rem)] rounded-md p-2 flex flex-col space-y-2">
{/* Row 1A - taking 1/2 of rack height */}
<div className="flex flex-col h-1/3 bg-gray-800 rounded-md p-2 relative">
<div className="absolute top-0 left-0 bg-white w-3 h-3 rounded-full"></div>
<div className="absolute top-0 right-0 bg-white w-3 h-3 rounded-full"></div>
<div className="absolute bottom-0 left-0 bg-white w-3 h-3 rounded-full"></div>
<div className="absolute bottom-0 right-0 bg-white w-3 h-3 rounded-full"></div>
<div className="flex-1 flex items-center">
<span className="text-xs mr-4">1A</span>
<div className="flex-1 flex items-center justify-center space-x-4">
{[...Array(12)].map((_, i) => (
<div key={i} className="flex flex-col items-center">
<div
className={`w-10 h-10 transition-colors flex items-center justify-center ${getPortStyle(`1F-RackA-1A-${i + 1}`)}`}
jstype="testport-copper"
id={`1F-RackA-1A-${i + 1}`}
onClick={() => onPortClick(`1F-RackA-1A-${i + 1}`)}
onMouseEnter={() => onPortHover(`1F-RackA-1A-${i + 1}`)}
>
<div className={`w-8 h-8 bg-[url('/rj45.png')] bg-contain bg-no-repeat bg-center`}></div>
</div>
<span className="text-xs">{i + 1}</span>
</div>
))}
</div>
</div>
</div>
{/* Row 1B - taking 1/2 of rack height */}
<div className="flex flex-col h-1/2 bg-gray-800 rounded-md p-2 relative">
<div className="absolute top-0 left-0 bg-white w-3 h-3 rounded-full"></div>
<div className="absolute top-0 right-0 bg-white w-3 h-3 rounded-full"></div>
<div className="absolute bottom-0 left-0 bg-white w-3 h-3 rounded-full"></div>
<div className="absolute bottom-0 right-0 bg-white w-3 h-3 rounded-full"></div>
<div className="flex-1 flex items-center">
<span className="text-xs mr-4">1B</span>
<div className="flex-1 flex items-center justify-center space-x-6">
{[...Array(6)].map((_, groupIndex) => (
<div key={groupIndex} className="flex">
{[0, 1].map((portIndex) => {
const portId = `1F-RackA-1B-${groupIndex * 2 + portIndex + 1}`;
const portNumber = groupIndex * 2 + portIndex + 1;
return (
<div key={portIndex} className="flex flex-col items-center">
<div
className={`mb-1 transition-colors flex items-center justify-center`}
>
<div
className={`w-8 h-8 bg-[url('/lc.png')] bg-contain bg-no-repeat bg-center cursor-pointer`}
jstype="testport-fiber"
lcclean="false"
id={portId}
onClick={() => onPortClick(portId)}
onMouseEnter={() => onPortHover(portId)}
></div>
</div>
<span className="text-xs">{portNumber}</span>
</div>
);
})}
</div>
))}
</div>
</div>
</div>
{/* Row 1C - taking 1/2 of rack height */}
<div className="flex flex-col h-1/2 bg-gray-800 rounded-md p-2 relative">
<div className="absolute top-0 left-0 bg-white w-3 h-3 rounded-full"></div>
<div className="absolute top-0 right-0 bg-white w-3 h-3 rounded-full"></div>
<div className="absolute bottom-0 left-0 bg-white w-3 h-3 rounded-full"></div>
<div className="absolute bottom-0 right-0 bg-white w-3 h-3 rounded-full"></div>
<div className="flex-1 flex items-center">
<span className="text-xs mr-4">1C</span>
<div className="flex-1 flex items-center justify-center space-x-6">
{[...Array(6)].map((_, groupIndex) => (
<div key={groupIndex} className="flex">
{[0, 1].map((portIndex) => {
const portId = `1F-RackA-1C-${groupIndex * 2 + portIndex + 1}`;
const portNumber = groupIndex * 2 + portIndex + 1;
return (
<div key={portIndex} className="flex flex-col items-center">
<div
className={`mb-1 transition-colors flex items-center justify-center`}
>
<div
className={`w-8 h-8 bg-[url('/lc.png')] bg-contain bg-no-repeat bg-center cursor-pointer`}
jstype="testport-fiber"
lcclean="false"
id={portId}
onClick={() => onPortClick(portId)}
onMouseEnter={() => onPortHover(portId)}
></div>
</div>
<span className="text-xs">{portNumber}</span>
</div>
);
})}
</div>
))}
</div>
</div>
</div>
</div>
</div>
{/* 竞技模式场景切换 */}
<div className="w-[2%] p-1 flex flex-col">
<button
className="bg-gradient-to-r from-blue-500 to-blue-700 hover:from-blue-600 hover:to-blue-800 text-white font-bold py-3 px-2 rounded-lg shadow-lg transform hover:scale-101 transition-all duration-200 text-sm flex flex-col items-center justify-center h-full min-h-[120px] border border-blue-400 hover:border-blue-300"
onClick={() => updateWorldSkillScenarios('WORKSHOP')}
>
<div className="text-xs leading-tight text-center">
前往<br/>车间
</div>
</button>
</div>
</div>
</div>
);
}