158 lines
7.3 KiB
JavaScript
158 lines
7.3 KiB
JavaScript
const { useState, useEffect, useRef } = React;
|
|
|
|
function DraggableTable({ drawingId, position, onPositionChange, children }) {
|
|
const tableRef = useRef(null);
|
|
const [isDragging, setIsDragging] = useState(false);
|
|
const [offset, setOffset] = useState({ x: 0, y: 0 });
|
|
|
|
const handleMouseDown = (e) => {
|
|
if (!tableRef.current) return;
|
|
setIsDragging(true);
|
|
const rect = tableRef.current.getBoundingClientRect();
|
|
setOffset({
|
|
x: e.clientX - rect.left,
|
|
y: e.clientY - rect.top,
|
|
});
|
|
e.preventDefault();
|
|
};
|
|
|
|
const handleMouseMove = (e) => {
|
|
if (!isDragging || !tableRef.current) return;
|
|
const parentRect = tableRef.current.parentElement.getBoundingClientRect();
|
|
|
|
// 计算新的 left 和 bottom
|
|
let newX = e.clientX - parentRect.left - offset.x;
|
|
let newY = parentRect.height - (e.clientY - parentRect.top) - tableRef.current.offsetHeight + offset.y;
|
|
|
|
// 边界检测
|
|
newX = Math.max(0, Math.min(newX, parentRect.width - tableRef.current.offsetWidth));
|
|
newY = Math.max(0, Math.min(newY, parentRect.height - tableRef.current.offsetHeight));
|
|
|
|
onPositionChange(drawingId, { x: newX, y: newY });
|
|
e.preventDefault();
|
|
};
|
|
|
|
const handleMouseUp = () => {
|
|
setIsDragging(false);
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (isDragging) {
|
|
document.addEventListener('mousemove', handleMouseMove);
|
|
document.addEventListener('mouseup', handleMouseUp);
|
|
} else {
|
|
document.removeEventListener('mousemove', handleMouseMove);
|
|
document.removeEventListener('mouseup', handleMouseUp);
|
|
}
|
|
|
|
return () => {
|
|
document.removeEventListener('mousemove', handleMouseMove);
|
|
document.removeEventListener('mouseup', handleMouseUp);
|
|
};
|
|
}, [isDragging, handleMouseMove, handleMouseUp]);
|
|
|
|
return React.createElement('div', {
|
|
ref: tableRef,
|
|
className: `absolute bg-white border border-gray-300 shadow-lg p-2 rounded-lg ${isDragging ? 'cursor-grabbing' : 'cursor-grab'}`,
|
|
style: { left: `${position.x}px`, bottom: `${position.y}px` },
|
|
onMouseDown: handleMouseDown
|
|
}, children);
|
|
}
|
|
|
|
function DrawingViewer({ drawing, item, items, tablePositions, setTablePositions, drawings, onItemUpdate, onBindDrawing, onItemRename, onCycleDrawing }) {
|
|
const [editedItemId, setEditedItemId] = React.useState('');
|
|
|
|
React.useEffect(() => {
|
|
if (item) {
|
|
setEditedItemId(item.id);
|
|
}
|
|
}, [item]);
|
|
|
|
if (!item) {
|
|
return React.createElement('div', { className: 'workspace-panel flex items-center justify-center h-full' },
|
|
React.createElement('p', { className: 'text-gray-500' }, '请在左侧选择一个件号')
|
|
);
|
|
}
|
|
|
|
if (!drawing) {
|
|
return React.createElement('div', { className: 'workspace-panel flex flex-col items-center justify-center h-full' },
|
|
React.createElement('p', { className: 'text-gray-500 mb-4' }, `件号 "${item.id}" 尚未绑定图纸`),
|
|
// 假设我们总是可以绑定到一张默认图纸上,或者需要一个图纸选择器
|
|
// 这里为了简化,我们假设绑定到 'drawing-1'
|
|
React.createElement('button', {
|
|
className: 'btn-primary',
|
|
onClick: () => onBindDrawing(item.id, 'drawing-1')
|
|
}, '为此件号绑定图纸')
|
|
);
|
|
}
|
|
|
|
const tablePos = tablePositions[drawing.id] || { x: 50, y: 50 };
|
|
|
|
// 获取子项
|
|
const childItems = item.children.map(childId => items[childId]);
|
|
|
|
const handleRenameItem = () => {
|
|
if (!editedItemId.trim() || editedItemId.trim() === item.id) return;
|
|
onItemRename(item.id, editedItemId.trim());
|
|
};
|
|
|
|
const isRoot = item && item.isRoot;
|
|
|
|
return React.createElement('div', { className: 'workspace-panel h-full p-4 relative bg-gray-50 overflow-hidden' },
|
|
!isRoot && React.createElement('div', { className: 'absolute top-4 left-4 z-10 bg-white p-2 rounded-lg shadow-md flex items-center gap-2' },
|
|
React.createElement('span', { className: 'text-sm font-medium mr-2' }, '修改件号:'),
|
|
React.createElement('input', {
|
|
type: 'text',
|
|
placeholder: '输入新件号',
|
|
className: 'form-input w-48',
|
|
value: editedItemId,
|
|
onChange: (e) => setEditedItemId(e.target.value),
|
|
onBlur: handleRenameItem, // 失去焦点时也触发
|
|
onKeyPress: (e) => { if (e.key === 'Enter') handleRenameItem() } // 回车触发
|
|
}),
|
|
React.createElement('button', { className: 'btn-primary', onClick: handleRenameItem }, '确认')
|
|
),
|
|
React.createElement('button', {
|
|
className: 'absolute left-4 top-1/2 -translate-y-1/2 z-10 p-3 bg-white/60 rounded-full hover:bg-white transition-colors shadow-md',
|
|
onClick: () => onCycleDrawing(-1)
|
|
}, React.createElement('i', { className: 'lucide lucide-chevron-left w-8 h-8' })),
|
|
React.createElement('button', {
|
|
className: 'absolute right-4 top-1/2 -translate-y-1/2 z-10 p-3 bg-white/60 rounded-full hover:bg-white transition-colors shadow-md',
|
|
onClick: () => onCycleDrawing(1)
|
|
}, React.createElement('i', { className: 'lucide lucide-chevron-right w-8 h-8' })),
|
|
drawing.url ?
|
|
React.createElement('img', { src: drawing.url, className: 'w-full h-full object-contain' }) :
|
|
React.createElement('div', { className: 'absolute inset-0 flex items-center justify-center' },
|
|
React.createElement('h2', {className: 'text-9xl font-bold text-gray-200 select-none'}, drawing.drawingNumber)
|
|
),
|
|
React.createElement(DraggableTable, {
|
|
drawingId: drawing.id,
|
|
position: tablePos,
|
|
onPositionChange: (drawingId, newPos) => {
|
|
setTablePositions(prev => ({...prev, [drawingId]: newPos}))
|
|
}
|
|
},
|
|
React.createElement('table', { className: 'w-full text-sm text-left' },
|
|
React.createElement('thead', {},
|
|
React.createElement('tr', { className: 'bg-gray-100' },
|
|
React.createElement('th', {className: 'p-2'}, '件号'),
|
|
React.createElement('th', {className: 'p-2'}, '名称'),
|
|
React.createElement('th', {className: 'p-2'}, '数量'),
|
|
React.createElement('th', {className: 'p-2'}, '重量'),
|
|
React.createElement('th', {className: 'p-2'}, '图号')
|
|
)
|
|
),
|
|
React.createElement('tbody', {},
|
|
childItems.map(child => React.createElement('tr', { key: child.id, className: 'border-b' },
|
|
React.createElement('td', {className: 'p-2'}, child.id),
|
|
React.createElement('td', {className: 'p-2'}, child.name),
|
|
React.createElement('td', {className: 'p-2'}, child.quantity),
|
|
React.createElement('td', {className: 'p-2'}, child.weight.toFixed(2)),
|
|
React.createElement('td', {className: 'p-2'}, drawings[child.drawingId]?.drawingNumber || 'N/A')
|
|
))
|
|
)
|
|
)
|
|
)
|
|
);
|
|
}
|