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') )) ) ) ) ); }