계층 구조 유효성 검사 및 그룹 이동 기능 구현
This commit is contained in:
parent
68e8e7b36b
commit
7994b2a72a
|
|
@ -657,13 +657,13 @@ export default function DigitalTwinEditor({ layoutId, layoutName, onBack }: Digi
|
|||
};
|
||||
|
||||
// 캔버스에 드롭
|
||||
const handleCanvasDrop = (x: number, z: number) => {
|
||||
const handleCanvasDrop = async (x: number, z: number) => {
|
||||
if (!draggedTool) return;
|
||||
|
||||
const defaults = getToolDefaults(draggedTool);
|
||||
|
||||
// Area는 바닥(y=0.05)에, 다른 객체는 중앙 정렬
|
||||
const yPosition = draggedTool === "area" ? 0.05 : (defaults.size?.y || 1) / 2;
|
||||
let yPosition = draggedTool === "area" ? 0.05 : (defaults.size?.y || 1) / 2;
|
||||
|
||||
// 외부 DB 데이터에서 드래그한 경우 해당 정보 사용
|
||||
let objectName = defaults.name || "새 객체";
|
||||
|
|
@ -697,12 +697,51 @@ export default function DigitalTwinEditor({ layoutId, layoutName, onBack }: Digi
|
|||
externalKey = draggedLocationData.LOCAKEY;
|
||||
}
|
||||
|
||||
// 기본 크기 설정
|
||||
let objectSize = defaults.size || { x: 5, y: 5, z: 5 };
|
||||
|
||||
// Location 배치 시 자재 개수에 따라 높이 자동 설정
|
||||
if (
|
||||
(draggedTool === "location-bed" ||
|
||||
draggedTool === "location-stp" ||
|
||||
draggedTool === "location-temp" ||
|
||||
draggedTool === "location-dest") &&
|
||||
locaKey &&
|
||||
selectedDbConnection &&
|
||||
hierarchyConfig?.material
|
||||
) {
|
||||
try {
|
||||
// 해당 Location의 자재 개수 조회
|
||||
const countsResponse = await getMaterialCounts(selectedDbConnection, hierarchyConfig.material.tableName, [
|
||||
locaKey,
|
||||
]);
|
||||
|
||||
if (countsResponse.success && countsResponse.data && countsResponse.data.length > 0) {
|
||||
const materialCount = countsResponse.data[0].count;
|
||||
|
||||
// 자재 개수에 비례해서 높이(Y축) 설정 (최소 5, 최대 30)
|
||||
// 자재 1개 = 높이 5, 자재 10개 = 높이 15, 자재 50개 = 높이 30
|
||||
const calculatedHeight = Math.min(30, Math.max(5, 5 + materialCount * 0.5));
|
||||
|
||||
objectSize = {
|
||||
...objectSize,
|
||||
y: calculatedHeight, // Y축이 높이!
|
||||
};
|
||||
|
||||
// 높이가 높아진 만큼 Y 위치도 올려서 바닥을 뚫지 않게 조정
|
||||
yPosition = calculatedHeight / 2;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("자재 개수 조회 실패, 기본 높이 사용:", error);
|
||||
}
|
||||
}
|
||||
|
||||
const newObject: PlacedObject = {
|
||||
id: nextObjectId,
|
||||
type: draggedTool,
|
||||
name: objectName,
|
||||
position: { x, y: yPosition, z },
|
||||
size: defaults.size || { x: 5, y: 5, z: 5 },
|
||||
size: objectSize,
|
||||
color: OBJECT_COLORS[draggedTool] || DEFAULT_COLOR, // 타입별 기본 색상
|
||||
areaKey,
|
||||
locaKey,
|
||||
|
|
|
|||
|
|
@ -442,20 +442,79 @@ function MaterialBox({
|
|||
</>
|
||||
)}
|
||||
|
||||
{/* Area 이름 텍스트 */}
|
||||
{/* Area 이름 텍스트 - 위쪽 (바닥) */}
|
||||
{placement.name && (
|
||||
<Text
|
||||
position={[0, 0.15, 0]}
|
||||
rotation={[-Math.PI / 2, 0, 0]}
|
||||
fontSize={Math.min(boxWidth, boxDepth) * 0.2}
|
||||
color={placement.color}
|
||||
anchorX="center"
|
||||
anchorY="middle"
|
||||
outlineWidth={0.05}
|
||||
outlineColor="#000000"
|
||||
>
|
||||
{placement.name}
|
||||
</Text>
|
||||
<>
|
||||
<Text
|
||||
position={[0, 0.15, 0]}
|
||||
rotation={[-Math.PI / 2, 0, 0]}
|
||||
fontSize={Math.min(boxWidth, boxDepth) * 0.2}
|
||||
color={placement.color}
|
||||
anchorX="center"
|
||||
anchorY="middle"
|
||||
outlineWidth={0.05}
|
||||
outlineColor="#000000"
|
||||
>
|
||||
{placement.name}
|
||||
</Text>
|
||||
|
||||
{/* 4면에 텍스트 표시 */}
|
||||
{/* 앞면 (+Z) */}
|
||||
<Text
|
||||
position={[0, boxHeight / 2, boxDepth / 2 + 0.01]}
|
||||
rotation={[0, 0, 0]}
|
||||
fontSize={Math.min(boxWidth, boxHeight) * 0.3}
|
||||
color="#ffffff"
|
||||
anchorX="center"
|
||||
anchorY="middle"
|
||||
outlineWidth={0.08}
|
||||
outlineColor="#000000"
|
||||
>
|
||||
{placement.name}
|
||||
</Text>
|
||||
|
||||
{/* 뒷면 (-Z) */}
|
||||
<Text
|
||||
position={[0, boxHeight / 2, -boxDepth / 2 - 0.01]}
|
||||
rotation={[0, Math.PI, 0]}
|
||||
fontSize={Math.min(boxWidth, boxHeight) * 0.3}
|
||||
color="#ffffff"
|
||||
anchorX="center"
|
||||
anchorY="middle"
|
||||
outlineWidth={0.08}
|
||||
outlineColor="#000000"
|
||||
>
|
||||
{placement.name}
|
||||
</Text>
|
||||
|
||||
{/* 왼쪽면 (-X) */}
|
||||
<Text
|
||||
position={[-boxWidth / 2 - 0.01, boxHeight / 2, 0]}
|
||||
rotation={[0, -Math.PI / 2, 0]}
|
||||
fontSize={Math.min(boxDepth, boxHeight) * 0.3}
|
||||
color="#ffffff"
|
||||
anchorX="center"
|
||||
anchorY="middle"
|
||||
outlineWidth={0.08}
|
||||
outlineColor="#000000"
|
||||
>
|
||||
{placement.name}
|
||||
</Text>
|
||||
|
||||
{/* 오른쪽면 (+X) */}
|
||||
<Text
|
||||
position={[boxWidth / 2 + 0.01, boxHeight / 2, 0]}
|
||||
rotation={[0, Math.PI / 2, 0]}
|
||||
fontSize={Math.min(boxDepth, boxHeight) * 0.3}
|
||||
color="#ffffff"
|
||||
anchorX="center"
|
||||
anchorY="middle"
|
||||
outlineWidth={0.08}
|
||||
outlineColor="#000000"
|
||||
>
|
||||
{placement.name}
|
||||
</Text>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in New Issue