1338 lines
45 KiB
JavaScript
1338 lines
45 KiB
JavaScript
/**
|
||
* 2D可视化监控系统 - 主要业务逻辑
|
||
* 负责设备渲染、拖拽交互、配置管理等核心功能
|
||
*/
|
||
|
||
// ==================== 全局变量定义 ====================
|
||
|
||
/**
|
||
* 当前系统配置对象
|
||
* @type {Object|null} 包含所有系统配置信息
|
||
*/
|
||
let config = null;
|
||
|
||
/**
|
||
* 视图拖拽和缩放状态管理
|
||
*/
|
||
const viewState = {
|
||
isDragging: false, // 是否正在拖拽视图
|
||
lastMouseX: 0, // 上次鼠标X坐标
|
||
lastMouseY: 0, // 上次鼠标Y坐标
|
||
currentScale: 1, // 当前缩放比例
|
||
currentX: 0, // 当前X偏移量
|
||
currentY: 0 // 当前Y偏移量
|
||
};
|
||
|
||
/**
|
||
* 系统默认配置
|
||
* @type {Object} 当配置文件加载失败时使用的默认值
|
||
*/
|
||
const DEFAULT_CONFIG = {
|
||
deviceDraggable: false, // 设备是否可拖拽
|
||
boxRows: [ // 方块行配置
|
||
{
|
||
id: 'row1',
|
||
boxWidth: 20,
|
||
boxHeight: 20,
|
||
boxCount: 45,
|
||
rowGap: 30
|
||
},
|
||
{
|
||
id: 'row2',
|
||
boxWidth: 20,
|
||
boxHeight: 20,
|
||
boxCount: 45,
|
||
rowGap: 30
|
||
},
|
||
{
|
||
id: 'row3',
|
||
boxWidth: 20,
|
||
boxHeight: 20,
|
||
boxCount: 45,
|
||
rowGap: 30
|
||
},
|
||
{
|
||
id: 'row4',
|
||
boxWidth: 20,
|
||
boxHeight: 20,
|
||
boxCount: 45,
|
||
rowGap: 30
|
||
}
|
||
]
|
||
};
|
||
|
||
// ==================== 视图交互功能 ====================
|
||
|
||
/**
|
||
* 初始化视图拖拽和缩放功能
|
||
* 支持右键拖拽移动视图和滚轮缩放
|
||
*/
|
||
function initDragAndZoom() {
|
||
const mainElement = document.getElementById('main');
|
||
if (!mainElement) return;
|
||
|
||
// 右键拖拽事件处理
|
||
mainElement.addEventListener('mousedown', handleMouseDown);
|
||
document.addEventListener('mousemove', handleMouseMove);
|
||
document.addEventListener('mouseup', handleMouseUp);
|
||
|
||
// 禁用右键菜单
|
||
mainElement.addEventListener('contextmenu', e => e.preventDefault());
|
||
|
||
// 滚轮缩放事件处理
|
||
mainElement.addEventListener('wheel', handleWheel);
|
||
}
|
||
|
||
/**
|
||
* 处理鼠标按下事件(开始拖拽)
|
||
* @param {MouseEvent} e 鼠标事件对象
|
||
*/
|
||
function handleMouseDown(e) {
|
||
if (e.button === 2) { // 右键点击
|
||
e.preventDefault();
|
||
viewState.isDragging = true;
|
||
viewState.lastMouseX = e.clientX;
|
||
viewState.lastMouseY = e.clientY;
|
||
document.getElementById('main').classList.add('dragging');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 处理鼠标移动事件(拖拽过程)
|
||
* @param {MouseEvent} e 鼠标事件对象
|
||
*/
|
||
function handleMouseMove(e) {
|
||
if (viewState.isDragging) {
|
||
const deltaX = e.clientX - viewState.lastMouseX;
|
||
const deltaY = e.clientY - viewState.lastMouseY;
|
||
viewState.currentX += deltaX;
|
||
viewState.currentY += deltaY;
|
||
viewState.lastMouseX = e.clientX;
|
||
viewState.lastMouseY = e.clientY;
|
||
updateMainTransform();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 处理鼠标释放事件(结束拖拽)
|
||
* @param {MouseEvent} e 鼠标事件对象
|
||
*/
|
||
function handleMouseUp(e) {
|
||
if (e.button === 2) { // 右键释放
|
||
viewState.isDragging = false;
|
||
document.getElementById('main').classList.remove('dragging');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 处理滚轮事件(缩放视图)
|
||
* @param {WheelEvent} e 滚轮事件对象
|
||
*/
|
||
function handleWheel(e) {
|
||
e.preventDefault();
|
||
const zoomFactor = e.deltaY > 0 ? 0.9 : 1.1;
|
||
viewState.currentScale *= zoomFactor;
|
||
// 限制缩放范围在0.1到5倍之间
|
||
viewState.currentScale = Math.min(Math.max(0.1, viewState.currentScale), 5);
|
||
updateMainTransform();
|
||
}
|
||
|
||
/**
|
||
* 更新主容器的变换(位移和缩放)
|
||
* 根据当前的视图状态更新主容器的CSS transform属性
|
||
*/
|
||
function updateMainTransform() {
|
||
const mainElement = document.getElementById('main');
|
||
if (mainElement) {
|
||
mainElement.style.transform =
|
||
`translate(${viewState.currentX}px, ${viewState.currentY}px) scale(${viewState.currentScale})`;
|
||
}
|
||
}
|
||
|
||
// ==================== 页面样式管理 ====================
|
||
|
||
/**
|
||
* 更新页面标题样式
|
||
* @param {Object} titleSettings 标题配置对象
|
||
* @param {string} titleSettings.content 标题内容
|
||
* @param {number} titleSettings.fontSize 字体大小
|
||
* @param {string} titleSettings.color 字体颜色
|
||
* @param {number} titleSettings.shadowSize 阴影大小
|
||
* @param {string} titleSettings.shadowColor 阴影颜色
|
||
*/
|
||
function updatePageTitleStyle(titleSettings) {
|
||
if (!titleSettings) return;
|
||
|
||
const pageTitle = document.getElementById('pageTitle');
|
||
if (pageTitle) {
|
||
pageTitle.textContent = titleSettings.content;
|
||
pageTitle.style.fontSize = `${titleSettings.fontSize}px`;
|
||
pageTitle.style.color = titleSettings.color;
|
||
pageTitle.style.textShadow =
|
||
`${titleSettings.shadowSize}px ${titleSettings.shadowSize}px ${titleSettings.shadowColor}`;
|
||
}
|
||
}
|
||
|
||
// ==================== 标签管理功能 ====================
|
||
|
||
/**
|
||
* 全局标签拖拽状态管理
|
||
*/
|
||
const labelDragState = {
|
||
isDragging: false,
|
||
currentLabel: null,
|
||
currentLabelId: null,
|
||
startX: 0,
|
||
startY: 0,
|
||
originalX: 0,
|
||
originalY: 0
|
||
};
|
||
|
||
/**
|
||
* 初始化全局标签拖拽事件监听器
|
||
* 只绑定一次,避免重复绑定导致的冲突
|
||
*/
|
||
function initGlobalLabelDragListeners() {
|
||
if (window.labelDragListenersInitialized) return;
|
||
|
||
document.addEventListener('mousemove', handleGlobalLabelMouseMove);
|
||
document.addEventListener('mouseup', handleGlobalLabelMouseUp);
|
||
|
||
window.labelDragListenersInitialized = true;
|
||
}
|
||
|
||
/**
|
||
* 初始化标签拖拽功能
|
||
* 为指定标签元素添加拖拽交互能力
|
||
* @param {HTMLElement} labelElement 标签DOM元素
|
||
* @param {string} labelId 标签唯一标识符
|
||
*/
|
||
function initLabelDrag(labelElement, labelId) {
|
||
// 确保全局事件监听器已初始化
|
||
initGlobalLabelDragListeners();
|
||
|
||
// 只绑定mousedown事件到具体标签
|
||
labelElement.addEventListener('mousedown', (e) => handleLabelMouseDown(e, labelElement, labelId));
|
||
}
|
||
|
||
/**
|
||
* 处理标签鼠标按下事件
|
||
* @param {MouseEvent} e 鼠标事件对象
|
||
* @param {HTMLElement} labelElement 标签元素
|
||
* @param {string} labelId 标签ID
|
||
*/
|
||
function handleLabelMouseDown(e, labelElement, labelId) {
|
||
// 安全检查:确保config存在且允许拖拽
|
||
if (!config || !config.deviceDraggable) {
|
||
return;
|
||
}
|
||
|
||
// 设置全局拖拽状态
|
||
labelDragState.isDragging = true;
|
||
labelDragState.currentLabel = labelElement;
|
||
labelDragState.currentLabelId = labelId;
|
||
labelDragState.startX = e.clientX;
|
||
labelDragState.startY = e.clientY;
|
||
labelDragState.originalX = parseInt(labelElement.style.left) || 0;
|
||
labelDragState.originalY = parseInt(labelElement.style.top) || 0;
|
||
|
||
// 添加拖拽样式
|
||
labelElement.style.zIndex = '1000';
|
||
labelElement.style.userSelect = 'none';
|
||
|
||
|
||
// 防止事件冒泡到主容器
|
||
e.stopPropagation();
|
||
e.preventDefault();
|
||
}
|
||
|
||
/**
|
||
* 处理全局标签鼠标移动事件
|
||
* @param {MouseEvent} e 鼠标事件对象
|
||
*/
|
||
function handleGlobalLabelMouseMove(e) {
|
||
// 安全检查:确保所有必要条件都满足
|
||
if (!labelDragState.isDragging ||
|
||
!config ||
|
||
!config.deviceDraggable ||
|
||
!labelDragState.currentLabel ||
|
||
!labelDragState.currentLabelId) {
|
||
return;
|
||
}
|
||
|
||
const deltaX = e.clientX - labelDragState.startX;
|
||
const deltaY = e.clientY - labelDragState.startY;
|
||
const newX = labelDragState.originalX + deltaX;
|
||
const newY = labelDragState.originalY + deltaY;
|
||
|
||
// 更新元素位置
|
||
labelDragState.currentLabel.style.left = newX + 'px';
|
||
labelDragState.currentLabel.style.top = newY + 'px';
|
||
|
||
// 同步更新配置中的标签位置
|
||
updateLabelPositionInConfig(labelDragState.currentLabelId, newX, newY);
|
||
|
||
// 防止文本选择
|
||
e.preventDefault();
|
||
}
|
||
|
||
/**
|
||
* 处理全局标签鼠标释放事件
|
||
* @param {MouseEvent} e 鼠标事件对象
|
||
*/
|
||
function handleGlobalLabelMouseUp(e) {
|
||
if (!labelDragState.isDragging) return;
|
||
|
||
// 恢复标签样式
|
||
if (labelDragState.currentLabel) {
|
||
labelDragState.currentLabel.style.zIndex = '100';
|
||
labelDragState.currentLabel.style.userSelect = 'none';
|
||
}
|
||
|
||
// 保存标签位置到服务器
|
||
if (labelDragState.currentLabelId) {
|
||
saveLabelPosition(labelDragState.currentLabelId);
|
||
}
|
||
|
||
// 重置拖拽状态
|
||
labelDragState.isDragging = false;
|
||
labelDragState.currentLabel = null;
|
||
labelDragState.currentLabelId = null;
|
||
}
|
||
|
||
/**
|
||
* 更新配置中的标签位置
|
||
* @param {string} labelId 标签ID
|
||
* @param {number} x X坐标
|
||
* @param {number} y Y坐标
|
||
*/
|
||
function updateLabelPositionInConfig(labelId, x, y) {
|
||
if (!config.labels) return;
|
||
|
||
const labelIndex = config.labels.findIndex(label => label.id === labelId);
|
||
if (labelIndex !== -1) {
|
||
config.labels[labelIndex].x = x;
|
||
config.labels[labelIndex].y = y;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 保存标签位置到服务器
|
||
* @param {string} labelId 标签ID
|
||
*/
|
||
function saveLabelPosition(labelId) {
|
||
$.ajax({
|
||
url: 'http://localhost:3000/api/config',
|
||
type: 'GET',
|
||
success: function(currentConfig) {
|
||
// 只更新指定标签的位置
|
||
const labelIndex = currentConfig.labels.findIndex(label => label.id === labelId);
|
||
if (labelIndex !== -1) {
|
||
// 获取当前标签的实际位置
|
||
const labelElement = document.querySelector(`[data-label-id="${labelId}"]`);
|
||
if (labelElement) {
|
||
currentConfig.labels[labelIndex].x = parseInt(labelElement.style.left) || 0;
|
||
currentConfig.labels[labelIndex].y = parseInt(labelElement.style.top) || 0;
|
||
}
|
||
|
||
// 添加时间戳,确保配置文件变化能被检测到
|
||
currentConfig.lastUpdated = new Date().getTime();
|
||
|
||
// 保存更新后的配置
|
||
$.ajax({
|
||
url: 'http://localhost:3000/api/config',
|
||
type: 'PUT',
|
||
contentType: 'application/json',
|
||
data: JSON.stringify(currentConfig),
|
||
success: function () {
|
||
|
||
// 通知about页面刷新标签列表
|
||
notifyAboutPageRefresh();
|
||
},
|
||
error: function (error) {
|
||
console.error('更新标签位置失败:', error);
|
||
}
|
||
});
|
||
}
|
||
},
|
||
error: function (error) {
|
||
console.error('获取配置失败:', error);
|
||
}
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 通知about页面刷新标签列表
|
||
*/
|
||
function notifyAboutPageRefresh() {
|
||
// 发送消息通知about页面刷新
|
||
localStorage.setItem('refreshAbout', new Date().getTime().toString());
|
||
|
||
// 如果about页面在同一个窗口的不同标签页中打开,尝试通过广播通道通知刷新
|
||
if (window.BroadcastChannel) {
|
||
const bc = new BroadcastChannel('about_refresh_channel');
|
||
bc.postMessage({ refresh: true, timestamp: new Date().getTime() });
|
||
setTimeout(() => bc.close(), 1000); // 发送后关闭通道
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 创建并显示标签元素
|
||
* @param {Object} label 标签配置对象
|
||
* @param {string} label.id 标签ID
|
||
* @param {string} label.content 标签内容
|
||
* @param {number} label.x X坐标
|
||
* @param {number} label.y Y坐标
|
||
* @param {number} label.fontSize 字体大小
|
||
* @param {string} label.fontColor 字体颜色
|
||
* @param {string} label.bgColor 背景颜色
|
||
* @param {number} label.borderRadius 边框圆角
|
||
*/
|
||
function createLabel(label) {
|
||
const labelElement = document.createElement('div');
|
||
labelElement.className = 'custom-label';
|
||
labelElement.setAttribute('data-label-id', label.id);
|
||
|
||
// 设置标签样式
|
||
labelElement.style.cssText = `
|
||
position: absolute;
|
||
left: ${label.x}px;
|
||
top: ${label.y}px;
|
||
padding: 5px 10px;
|
||
background-color: ${label.bgColor};
|
||
color: ${label.fontColor};
|
||
font-size: ${label.fontSize}px;
|
||
border-radius: ${label.borderRadius}px;
|
||
cursor: default;
|
||
user-select: none;
|
||
z-index: 100;
|
||
white-space: nowrap;
|
||
display: inline-block;
|
||
`;
|
||
labelElement.textContent = label.content;
|
||
|
||
// 初始化拖拽功能
|
||
initLabelDrag(labelElement, label.id);
|
||
|
||
// 设置初始拖拽状态样式
|
||
updateLabelDragStyle(labelElement);
|
||
|
||
return labelElement;
|
||
}
|
||
|
||
/**
|
||
* 更新标签的拖拽样式
|
||
* @param {HTMLElement} labelElement 标签元素
|
||
*/
|
||
function updateLabelDragStyle(labelElement) {
|
||
if (!labelElement) return;
|
||
|
||
const isDraggable = config && config.deviceDraggable;
|
||
labelElement.style.cursor = isDraggable ? 'move' : 'default';
|
||
|
||
// 添加视觉提示
|
||
if (isDraggable) {
|
||
labelElement.title = '可拖拽移动位置';
|
||
} else {
|
||
labelElement.title = '当前为演示模式,无法拖拽';
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 更新所有标签显示
|
||
* 智能更新策略:拖拽时不重新创建标签,避免位置跳回
|
||
*/
|
||
function updateLabels() {
|
||
const container = document.getElementById('main');
|
||
if (!container || !config || !config.labels) return;
|
||
|
||
// 如果正在拖拽标签,跳过更新以避免位置跳回
|
||
if (labelDragState.isDragging) {
|
||
return;
|
||
}
|
||
|
||
|
||
// 获取现有标签
|
||
const existingLabels = container.querySelectorAll('.custom-label');
|
||
const existingLabelIds = Array.from(existingLabels).map(label => label.getAttribute('data-label-id'));
|
||
|
||
// 获取配置中的标签ID
|
||
const configLabelIds = config.labels.map(label => label.id);
|
||
|
||
// 删除配置中不存在的标签
|
||
existingLabels.forEach(labelElement => {
|
||
const labelId = labelElement.getAttribute('data-label-id');
|
||
if (!configLabelIds.includes(labelId)) {
|
||
labelElement.remove();
|
||
}
|
||
});
|
||
|
||
// 添加或更新标签
|
||
config.labels.forEach(label => {
|
||
const existingLabel = container.querySelector(`[data-label-id="${label.id}"]`);
|
||
|
||
if (existingLabel) {
|
||
// 更新现有标签的位置和样式
|
||
updateExistingLabel(existingLabel, label);
|
||
} else {
|
||
// 创建新标签
|
||
const labelElement = createLabel(label);
|
||
container.appendChild(labelElement);
|
||
}
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 更新现有标签的属性
|
||
* @param {HTMLElement} labelElement 标签DOM元素
|
||
* @param {Object} labelConfig 标签配置
|
||
*/
|
||
function updateExistingLabel(labelElement, labelConfig) {
|
||
// 更新位置
|
||
labelElement.style.left = labelConfig.x + 'px';
|
||
labelElement.style.top = labelConfig.y + 'px';
|
||
|
||
// 更新内容和样式
|
||
labelElement.textContent = labelConfig.content;
|
||
labelElement.style.backgroundColor = labelConfig.bgColor;
|
||
labelElement.style.color = labelConfig.fontColor;
|
||
labelElement.style.fontSize = labelConfig.fontSize + 'px';
|
||
labelElement.style.borderRadius = labelConfig.borderRadius + 'px';
|
||
|
||
// 更新拖拽样式
|
||
updateLabelDragStyle(labelElement);
|
||
}
|
||
|
||
// ==================== 配置管理功能 ====================
|
||
|
||
/**
|
||
* 加载系统配置文件
|
||
* 从服务器获取配置信息并初始化系统各个组件
|
||
*/
|
||
function loadConfig() {
|
||
$.ajax({
|
||
url: 'json/config.json',
|
||
type: 'GET',
|
||
dataType: 'json',
|
||
success: handleConfigLoadSuccess,
|
||
error: handleConfigLoadError
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 处理配置加载成功
|
||
* @param {Object} data 配置数据
|
||
*/
|
||
function handleConfigLoadSuccess(data) {
|
||
config = data;
|
||
|
||
// 确保必要的配置项存在
|
||
validateAndSetDefaults();
|
||
|
||
// 更新全局config引用
|
||
window.config = config;
|
||
|
||
// 初始化系统组件
|
||
initializeComponents();
|
||
|
||
}
|
||
|
||
/**
|
||
* 处理配置加载失败
|
||
* @param {Object} xhr XMLHttpRequest对象
|
||
* @param {string} status 状态信息
|
||
* @param {string} error 错误信息
|
||
*/
|
||
function handleConfigLoadError(xhr, status, error) {
|
||
console.error('加载配置失败:', error);
|
||
|
||
// 使用默认配置
|
||
config = { ...DEFAULT_CONFIG };
|
||
config.deviceDraggable = false;
|
||
window.config = config;
|
||
|
||
// 仅创建基础组件
|
||
createBoxes();
|
||
}
|
||
|
||
/**
|
||
* 验证配置并设置默认值
|
||
*/
|
||
function validateAndSetDefaults() {
|
||
if (typeof config.deviceDraggable === 'undefined') {
|
||
config.deviceDraggable = false;
|
||
}
|
||
|
||
// 确保必要的数组存在
|
||
if (!config.labels) config.labels = [];
|
||
if (!config.conveyors) config.conveyors = [];
|
||
if (!config.stackers) config.stackers = [];
|
||
if (!config.tracks) config.tracks = [];
|
||
if (!config.rollerConveyors) config.rollerConveyors = [];
|
||
|
||
// 验证并设置 boxRows 配置
|
||
if (!config.boxRows || !Array.isArray(config.boxRows)) {
|
||
config.boxRows = [
|
||
{
|
||
id: 'row1',
|
||
boxWidth: 20,
|
||
boxHeight: 20,
|
||
boxCount: 45,
|
||
rowGap: 30
|
||
},
|
||
{
|
||
id: 'row2',
|
||
boxWidth: 20,
|
||
boxHeight: 20,
|
||
boxCount: 45,
|
||
rowGap: 30
|
||
},
|
||
{
|
||
id: 'row3',
|
||
boxWidth: 20,
|
||
boxHeight: 20,
|
||
boxCount: 45,
|
||
rowGap: 30
|
||
},
|
||
{
|
||
id: 'row4',
|
||
boxWidth: 20,
|
||
boxHeight: 20,
|
||
boxCount: 45,
|
||
rowGap: 30
|
||
}
|
||
];
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 初始化系统组件
|
||
*/
|
||
function initializeComponents() {
|
||
// 创建网格背景
|
||
createBoxes();
|
||
|
||
// 更新页面标题样式
|
||
updatePageTitleStyle(config.titleSettings);
|
||
|
||
// 更新标签显示
|
||
updateLabels();
|
||
|
||
// 更新设备拖拽状态
|
||
updateDevicesDraggableState();
|
||
|
||
// 初始化拖拽按钮状态
|
||
initializeDragButtons();
|
||
}
|
||
|
||
/**
|
||
* 初始化拖拽按钮状态
|
||
*/
|
||
function initializeDragButtons() {
|
||
const enableDragBtn = document.getElementById('enableDragBtn');
|
||
const disableDragBtn = document.getElementById('disableDragBtn');
|
||
|
||
if (enableDragBtn) enableDragBtn.disabled = config.deviceDraggable;
|
||
if (disableDragBtn) disableDragBtn.disabled = !config.deviceDraggable;
|
||
}
|
||
|
||
// 创建并布局小方块和链条输送机
|
||
function createBoxes() {
|
||
if (!config || !config.boxRows) return;
|
||
|
||
const mainDiv = document.getElementById('main');
|
||
// 检查mainDiv是否存在
|
||
if (!mainDiv) {
|
||
console.error('未找到id为main的元素,无法创建方块');
|
||
return;
|
||
}
|
||
|
||
// 保存现有的标签
|
||
const existingLabels = Array.from(mainDiv.querySelectorAll('.custom-label'));
|
||
mainDiv.innerHTML = ''; // 清空现有的方块
|
||
// 恢复标签
|
||
existingLabels.forEach(label => mainDiv.appendChild(label));
|
||
|
||
// 计算所有行的总高度
|
||
let totalHeight = 0;
|
||
let maxWidth = 0;
|
||
|
||
// 创建行偏移数组,计算每行的垂直位置
|
||
let rowOffsets = [0]; // 第一行偏移量为0
|
||
let currentOffset = 0;
|
||
|
||
// 计算每行的偏移量和总高度
|
||
for (let i = 0; i < config.boxRows.length - 1; i++) {
|
||
const currentRow = config.boxRows[i];
|
||
const nextRow = config.boxRows[i + 1];
|
||
currentOffset += (currentRow.boxHeight + 4) + nextRow.rowGap; // 当前行高度 + 边框 + 下一行的间距
|
||
rowOffsets.push(currentOffset);
|
||
|
||
// 更新最大宽度
|
||
const rowWidth = (currentRow.boxWidth + 4) * currentRow.boxCount;
|
||
maxWidth = Math.max(maxWidth, rowWidth);
|
||
}
|
||
|
||
// 计算最后一行的宽度
|
||
const lastRow = config.boxRows[config.boxRows.length - 1];
|
||
const lastRowWidth = (lastRow.boxWidth + 4) * lastRow.boxCount;
|
||
maxWidth = Math.max(maxWidth, lastRowWidth);
|
||
|
||
// 更新总高度
|
||
totalHeight = currentOffset + (lastRow.boxHeight + 4);
|
||
|
||
// 计算起始位置,使所有行在屏幕中水平和垂直居中
|
||
const startX = (1920 - maxWidth) / 2;
|
||
const startY = (1080 - totalHeight) / 2;
|
||
|
||
// 创建多排方块
|
||
config.boxRows.forEach((rowConfig, rowIndex) => {
|
||
const boxWidth = rowConfig.boxWidth + 4; // 包含边框的总宽度
|
||
const boxHeight = rowConfig.boxHeight + 4; // 包含边框的总高度
|
||
const rowWidth = boxWidth * rowConfig.boxCount;
|
||
const rowStartX = (1920 - rowWidth) / 2; // 每行单独居中
|
||
|
||
for (let i = 0; i < rowConfig.boxCount; i++) {
|
||
const box = document.createElement('div');
|
||
box.className = 'small-box';
|
||
box.dataset.row = rowConfig.id; // 使用行ID标记方块所属的行
|
||
box.dataset.column = i; // 标记方块所属的列
|
||
|
||
// 设置方块的样式
|
||
box.style.width = rowConfig.boxWidth + 'px';
|
||
box.style.height = rowConfig.boxHeight + 'px';
|
||
box.style.backgroundColor = '#006666'; // 使用默认颜色
|
||
const boxLeft = rowStartX + i * boxWidth;
|
||
box.style.left = boxLeft + 'px';
|
||
box.style.top = (startY + rowOffsets[rowIndex]) + 'px';
|
||
|
||
mainDiv.appendChild(box);
|
||
}
|
||
});
|
||
|
||
// 创建堆垛机轨道
|
||
if (config.tracks && Array.isArray(config.tracks)) {
|
||
config.tracks.forEach(track => {
|
||
// 创建轨道容器
|
||
const trackDiv = document.createElement('div');
|
||
trackDiv.className = 'track';
|
||
trackDiv.id = track.id;
|
||
trackDiv.style.width = track.width + 'px';
|
||
trackDiv.style.height = track.height + 'px';
|
||
trackDiv.style.left = track.x + 'px';
|
||
trackDiv.style.top = track.y + 'px';
|
||
trackDiv.style.transform = `rotate(${track.rotation}deg)`;
|
||
|
||
// 添加拖动功能
|
||
let isDraggingTrack = false;
|
||
let startX, startY;
|
||
|
||
trackDiv.addEventListener('mousedown', function (e) {
|
||
if (e.button === 0 && config.deviceDraggable) { // 左键点击且允许拖动
|
||
e.preventDefault();
|
||
e.stopPropagation();
|
||
isDraggingTrack = true;
|
||
startX = e.clientX - parseInt(trackDiv.style.left);
|
||
startY = e.clientY - parseInt(trackDiv.style.top);
|
||
trackDiv.style.cursor = 'grabbing';
|
||
}
|
||
});
|
||
|
||
document.addEventListener('mousemove', function (e) {
|
||
if (isDraggingTrack && config.deviceDraggable) {
|
||
const newX = e.clientX - startX;
|
||
const newY = e.clientY - startY;
|
||
trackDiv.style.left = newX + 'px';
|
||
trackDiv.style.top = newY + 'px';
|
||
}
|
||
});
|
||
|
||
document.addEventListener('mouseup', function (e) {
|
||
if (isDraggingTrack) {
|
||
isDraggingTrack = false;
|
||
trackDiv.style.cursor = 'grab';
|
||
|
||
// 只有在允许拖动时才保存位置
|
||
if (config.deviceDraggable) {
|
||
// 更新配置中的位置
|
||
const trackIndex = config.tracks.findIndex(t => t.id === track.id);
|
||
if (trackIndex !== -1) {
|
||
config.tracks[trackIndex].x = parseInt(trackDiv.style.left);
|
||
config.tracks[trackIndex].y = parseInt(trackDiv.style.top);
|
||
|
||
// 保存更新后的配置
|
||
saveTrackPosition(track.id, parseInt(trackDiv.style.left), parseInt(trackDiv.style.top));
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
mainDiv.appendChild(trackDiv);
|
||
});
|
||
}
|
||
|
||
// 创建滚筒输送机
|
||
if (config.rollerConveyors && Array.isArray(config.rollerConveyors)) {
|
||
config.rollerConveyors.forEach(rollerConveyor => {
|
||
// 创建滚筒输送机容器
|
||
const rollerConveyorDiv = document.createElement('div');
|
||
rollerConveyorDiv.className = 'roller-conveyor';
|
||
rollerConveyorDiv.id = rollerConveyor.id;
|
||
rollerConveyorDiv.style.width = rollerConveyor.width + 'px';
|
||
rollerConveyorDiv.style.height = rollerConveyor.height + 'px';
|
||
rollerConveyorDiv.style.left = rollerConveyor.x + 'px';
|
||
rollerConveyorDiv.style.top = rollerConveyor.y + 'px';
|
||
rollerConveyorDiv.style.transform = `rotate(${rollerConveyor.rotation}deg)`;
|
||
|
||
// 创建中心小方块
|
||
const centerDiv = document.createElement('div');
|
||
centerDiv.className = 'roller-conveyor-center';
|
||
rollerConveyorDiv.appendChild(centerDiv);
|
||
|
||
// 添加点击事件处理
|
||
rollerConveyorDiv.addEventListener('click', function(e) {
|
||
if (!config.deviceDraggable) {
|
||
e.stopPropagation();
|
||
showDeviceInfo('rollerConveyor', rollerConveyor.id, rollerConveyor);
|
||
}
|
||
});
|
||
|
||
// 添加拖动功能
|
||
let isDraggingRollerConveyor = false;
|
||
let startX, startY;
|
||
|
||
rollerConveyorDiv.addEventListener('mousedown', function (e) {
|
||
if (e.button === 0 && config.deviceDraggable) { // 左键点击且允许拖动
|
||
e.preventDefault();
|
||
e.stopPropagation();
|
||
isDraggingRollerConveyor = true;
|
||
startX = e.clientX - parseInt(rollerConveyorDiv.style.left);
|
||
startY = e.clientY - parseInt(rollerConveyorDiv.style.top);
|
||
rollerConveyorDiv.style.cursor = 'grabbing';
|
||
}
|
||
});
|
||
|
||
document.addEventListener('mousemove', function (e) {
|
||
if (isDraggingRollerConveyor && config.deviceDraggable) {
|
||
const newX = e.clientX - startX;
|
||
const newY = e.clientY - startY;
|
||
rollerConveyorDiv.style.left = newX + 'px';
|
||
rollerConveyorDiv.style.top = newY + 'px';
|
||
}
|
||
});
|
||
|
||
document.addEventListener('mouseup', function (e) {
|
||
if (isDraggingRollerConveyor) {
|
||
isDraggingRollerConveyor = false;
|
||
rollerConveyorDiv.style.cursor = 'grab';
|
||
|
||
// 只有在允许拖动时才保存位置
|
||
if (config.deviceDraggable) {
|
||
// 更新配置中的位置
|
||
const rollerConveyorIndex = config.rollerConveyors.findIndex(rc => rc.id === rollerConveyor.id);
|
||
if (rollerConveyorIndex !== -1) {
|
||
config.rollerConveyors[rollerConveyorIndex].x = parseInt(rollerConveyorDiv.style.left);
|
||
config.rollerConveyors[rollerConveyorIndex].y = parseInt(rollerConveyorDiv.style.top);
|
||
|
||
// 保存更新后的配置
|
||
saveRollerConveyorPosition(rollerConveyor.id, parseInt(rollerConveyorDiv.style.left), parseInt(rollerConveyorDiv.style.top));
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
mainDiv.appendChild(rollerConveyorDiv);
|
||
});
|
||
}
|
||
|
||
// 创建堆垛机
|
||
if (config.stackers && Array.isArray(config.stackers)) {
|
||
config.stackers.forEach(stacker => {
|
||
// 创建堆垛机容器
|
||
const stackerDiv = document.createElement('div');
|
||
stackerDiv.className = 'stacker';
|
||
stackerDiv.id = stacker.id;
|
||
stackerDiv.style.width = stacker.width + 'px';
|
||
stackerDiv.style.height = stacker.height + 'px';
|
||
stackerDiv.style.left = stacker.x + 'px';
|
||
stackerDiv.style.top = stacker.y + 'px';
|
||
stackerDiv.style.transform = `rotate(${stacker.rotation}deg)`;
|
||
|
||
// 创建中心蓝色方块
|
||
const centerDiv = document.createElement('div');
|
||
centerDiv.className = 'stacker-center';
|
||
stackerDiv.appendChild(centerDiv);
|
||
|
||
// 添加点击事件处理
|
||
stackerDiv.addEventListener('click', function(e) {
|
||
if (!config.deviceDraggable) {
|
||
e.stopPropagation();
|
||
showDeviceInfo('stacker', stacker.id, stacker);
|
||
}
|
||
});
|
||
|
||
// 添加拖动功能
|
||
let isDraggingStacker = false;
|
||
let startX, startY;
|
||
|
||
stackerDiv.addEventListener('mousedown', function (e) {
|
||
if (e.button === 0 && config.deviceDraggable) { // 左键点击且允许拖动
|
||
e.preventDefault();
|
||
e.stopPropagation();
|
||
isDraggingStacker = true;
|
||
startX = e.clientX - parseInt(stackerDiv.style.left);
|
||
startY = e.clientY - parseInt(stackerDiv.style.top);
|
||
stackerDiv.style.cursor = 'grabbing';
|
||
}
|
||
});
|
||
|
||
document.addEventListener('mousemove', function (e) {
|
||
if (isDraggingStacker && config.deviceDraggable) {
|
||
const newX = e.clientX - startX;
|
||
const newY = e.clientY - startY;
|
||
stackerDiv.style.left = newX + 'px';
|
||
stackerDiv.style.top = newY + 'px';
|
||
}
|
||
});
|
||
|
||
document.addEventListener('mouseup', function (e) {
|
||
if (isDraggingStacker) {
|
||
isDraggingStacker = false;
|
||
stackerDiv.style.cursor = 'grab';
|
||
|
||
// 只有在允许拖动时才保存位置
|
||
if (config.deviceDraggable) {
|
||
// 更新配置中的位置
|
||
const stackerIndex = config.stackers.findIndex(s => s.id === stacker.id);
|
||
if (stackerIndex !== -1) {
|
||
config.stackers[stackerIndex].x = parseInt(stackerDiv.style.left);
|
||
config.stackers[stackerIndex].y = parseInt(stackerDiv.style.top);
|
||
|
||
// 保存更新后的配置
|
||
saveStackerPosition(stacker.id, parseInt(stackerDiv.style.left), parseInt(stackerDiv.style.top));
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
mainDiv.appendChild(stackerDiv);
|
||
});
|
||
}
|
||
|
||
// 创建RGV
|
||
if (config.rgvs && Array.isArray(config.rgvs)) {
|
||
config.rgvs.forEach(rgv => {
|
||
// 创建RGV容器
|
||
const rgvDiv = document.createElement('div');
|
||
rgvDiv.className = 'rgv';
|
||
rgvDiv.id = rgv.id;
|
||
rgvDiv.style.width = rgv.width + 'px';
|
||
rgvDiv.style.height = rgv.height + 'px';
|
||
rgvDiv.style.left = rgv.x + 'px';
|
||
rgvDiv.style.top = rgv.y + 'px';
|
||
rgvDiv.style.transform = `rotate(${rgv.rotation}deg)`;
|
||
|
||
// 创建中心方块
|
||
const centerDiv = document.createElement('div');
|
||
centerDiv.className = 'rgv-center';
|
||
rgvDiv.appendChild(centerDiv);
|
||
|
||
// 添加点击事件处理
|
||
rgvDiv.addEventListener('click', function(e) {
|
||
if (!config.deviceDraggable) {
|
||
e.stopPropagation();
|
||
showDeviceInfo('rgv', rgv.id, rgv);
|
||
}
|
||
});
|
||
|
||
// 添加拖动功能
|
||
let isDraggingRgv = false;
|
||
let startX, startY;
|
||
|
||
rgvDiv.addEventListener('mousedown', function (e) {
|
||
if (e.button === 0 && config.deviceDraggable) { // 左键点击且允许拖动
|
||
e.preventDefault();
|
||
e.stopPropagation();
|
||
isDraggingRgv = true;
|
||
startX = e.clientX - parseInt(rgvDiv.style.left);
|
||
startY = e.clientY - parseInt(rgvDiv.style.top);
|
||
rgvDiv.style.cursor = 'grabbing';
|
||
}
|
||
});
|
||
|
||
document.addEventListener('mousemove', function (e) {
|
||
if (isDraggingRgv && config.deviceDraggable) {
|
||
const newX = e.clientX - startX;
|
||
const newY = e.clientY - startY;
|
||
rgvDiv.style.left = newX + 'px';
|
||
rgvDiv.style.top = newY + 'px';
|
||
}
|
||
});
|
||
|
||
document.addEventListener('mouseup', function (e) {
|
||
if (isDraggingRgv) {
|
||
isDraggingRgv = false;
|
||
rgvDiv.style.cursor = config.deviceDraggable ? 'grab' : 'default';
|
||
|
||
// 保存新位置到配置
|
||
if (config.deviceDraggable) {
|
||
const rgvIndex = config.rgvs.findIndex(r => r.id === rgv.id);
|
||
if (rgvIndex !== -1) {
|
||
config.rgvs[rgvIndex].x = parseInt(rgvDiv.style.left);
|
||
config.rgvs[rgvIndex].y = parseInt(rgvDiv.style.top);
|
||
|
||
// 保存更新后的配置
|
||
saveRgvPosition(rgv.id, parseInt(rgvDiv.style.left), parseInt(rgvDiv.style.top));
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
mainDiv.appendChild(rgvDiv);
|
||
});
|
||
}
|
||
|
||
// 创建链条输送机
|
||
if (config.conveyors && Array.isArray(config.conveyors)) {
|
||
config.conveyors.forEach(conveyor => {
|
||
// 创建输送机容器
|
||
const conveyorDiv = document.createElement('div');
|
||
conveyorDiv.className = 'conveyor';
|
||
conveyorDiv.id = conveyor.id;
|
||
conveyorDiv.style.width = conveyor.width + 'px';
|
||
conveyorDiv.style.height = conveyor.height + 'px';
|
||
conveyorDiv.style.left = conveyor.x + 'px';
|
||
conveyorDiv.style.top = conveyor.y + 'px';
|
||
conveyorDiv.style.transform = `rotate(${conveyor.rotation}deg)`;
|
||
|
||
// 创建中心蓝色方块
|
||
const centerDiv = document.createElement('div');
|
||
centerDiv.className = 'conveyor-center';
|
||
conveyorDiv.appendChild(centerDiv);
|
||
|
||
// 添加点击事件处理
|
||
conveyorDiv.addEventListener('click', function(e) {
|
||
if (!config.deviceDraggable) {
|
||
e.stopPropagation();
|
||
showDeviceInfo('conveyor', conveyor.id, conveyor);
|
||
}
|
||
});
|
||
|
||
// 添加拖动功能
|
||
let isDraggingConveyor = false;
|
||
let startX, startY;
|
||
|
||
conveyorDiv.addEventListener('mousedown', function (e) {
|
||
if (e.button === 0 && config.deviceDraggable) { // 左键点击且允许拖动
|
||
e.preventDefault();
|
||
e.stopPropagation();
|
||
isDraggingConveyor = true;
|
||
startX = e.clientX - parseInt(conveyorDiv.style.left);
|
||
startY = e.clientY - parseInt(conveyorDiv.style.top);
|
||
conveyorDiv.style.cursor = 'grabbing';
|
||
}
|
||
});
|
||
|
||
document.addEventListener('mousemove', function (e) {
|
||
if (isDraggingConveyor && config.deviceDraggable) {
|
||
const newX = e.clientX - startX;
|
||
const newY = e.clientY - startY;
|
||
conveyorDiv.style.left = newX + 'px';
|
||
conveyorDiv.style.top = newY + 'px';
|
||
}
|
||
});
|
||
|
||
document.addEventListener('mouseup', function (e) {
|
||
if (isDraggingConveyor) {
|
||
isDraggingConveyor = false;
|
||
conveyorDiv.style.cursor = 'grab';
|
||
|
||
// 只有在允许拖动时才保存位置
|
||
if (config.deviceDraggable) {
|
||
// 更新配置中的位置
|
||
const conveyorIndex = config.conveyors.findIndex(c => c.id === conveyor.id);
|
||
if (conveyorIndex !== -1) {
|
||
config.conveyors[conveyorIndex].x = parseInt(conveyorDiv.style.left);
|
||
config.conveyors[conveyorIndex].y = parseInt(conveyorDiv.style.top);
|
||
|
||
// 保存更新后的配置
|
||
saveConveyorPosition(conveyor.id, parseInt(conveyorDiv.style.left), parseInt(conveyorDiv.style.top));
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
mainDiv.appendChild(conveyorDiv);
|
||
});
|
||
}
|
||
}
|
||
|
||
// 切换设备拖动状态
|
||
function toggleDeviceDrag(enable) {
|
||
config.deviceDraggable = enable;
|
||
|
||
// 更新按钮状态
|
||
updateDragButtons(enable);
|
||
|
||
|
||
// 更新设备的拖动状态
|
||
updateDevicesDraggableState();
|
||
|
||
// 保存配置到服务器
|
||
$.ajax({
|
||
url: 'http://localhost:3000/api/config',
|
||
type: 'PUT',
|
||
contentType: 'application/json',
|
||
data: JSON.stringify(config),
|
||
success: function (response) {
|
||
},
|
||
error: function (xhr, status, error) {
|
||
console.error('更新设备拖动状态失败:', error);
|
||
}
|
||
});
|
||
}
|
||
|
||
// 更新所有设备和标签的拖动状态
|
||
function updateDevicesDraggableState() {
|
||
// 安全检查:确保config存在
|
||
if (!config) {
|
||
return;
|
||
}
|
||
|
||
|
||
// 更新设备的拖动状态
|
||
const devices = document.querySelectorAll('.conveyor, .roller-conveyor, .stacker, .rgv');
|
||
devices.forEach(device => {
|
||
device.style.cursor = config.deviceDraggable ? 'grab' : 'default';
|
||
});
|
||
|
||
// 更新标签的拖动状态
|
||
const labels = document.querySelectorAll('.custom-label');
|
||
labels.forEach(label => {
|
||
updateLabelDragStyle(label);
|
||
});
|
||
}
|
||
|
||
// 将函数和变量暴露到全局作用域
|
||
window.updateDevicesDraggableState = updateDevicesDraggableState;
|
||
window.config = config;
|
||
|
||
// 保存轨道位置到服务器
|
||
function saveTrackPosition(trackId, x, y) {
|
||
// 先获取最新的配置,确保不覆盖其他设置
|
||
$.ajax({
|
||
url: 'http://localhost:3000/api/config',
|
||
type: 'GET',
|
||
success: function(currentConfig) {
|
||
// 只更新指定轨道的位置
|
||
const trackIndex = currentConfig.tracks.findIndex(t => t.id === trackId);
|
||
if (trackIndex !== -1) {
|
||
currentConfig.tracks[trackIndex].x = x;
|
||
currentConfig.tracks[trackIndex].y = y;
|
||
|
||
// 保存更新后的配置
|
||
$.ajax({
|
||
url: 'http://localhost:3000/api/config',
|
||
type: 'PUT',
|
||
contentType: 'application/json',
|
||
data: JSON.stringify(currentConfig),
|
||
success: function (response) {
|
||
},
|
||
error: function (xhr, status, error) {
|
||
console.error('保存轨道位置失败:', error);
|
||
}
|
||
});
|
||
}
|
||
},
|
||
error: function (xhr, status, error) {
|
||
console.error('获取配置失败:', error);
|
||
}
|
||
});
|
||
}
|
||
|
||
// 保存堆垛机位置
|
||
function saveStackerPosition(stackerId, x, y) {
|
||
// 先获取最新的配置,确保不覆盖其他设置
|
||
$.ajax({
|
||
url: 'http://localhost:3000/api/config',
|
||
type: 'GET',
|
||
success: function(currentConfig) {
|
||
// 只更新指定堆垛机的位置
|
||
const stackerIndex = currentConfig.stackers.findIndex(s => s.id === stackerId);
|
||
if (stackerIndex !== -1) {
|
||
currentConfig.stackers[stackerIndex].x = x;
|
||
currentConfig.stackers[stackerIndex].y = y;
|
||
|
||
// 保存更新后的配置
|
||
$.ajax({
|
||
url: 'http://localhost:3000/api/config',
|
||
type: 'PUT',
|
||
contentType: 'application/json',
|
||
data: JSON.stringify(currentConfig),
|
||
success: function (response) {
|
||
},
|
||
error: function (xhr, status, error) {
|
||
console.error('更新堆垛机位置失败:', error);
|
||
}
|
||
});
|
||
}
|
||
},
|
||
error: function (xhr, status, error) {
|
||
console.error('获取配置失败:', error);
|
||
}
|
||
});
|
||
}
|
||
|
||
// 保存滚筒输送机位置
|
||
function saveRollerConveyorPosition(rollerConveyorId, x, y) {
|
||
// 先获取最新的配置,确保不覆盖其他设置
|
||
$.ajax({
|
||
url: 'http://localhost:3000/api/config',
|
||
type: 'GET',
|
||
success: function(currentConfig) {
|
||
// 只更新指定滚筒输送机的位置
|
||
const rollerConveyorIndex = currentConfig.rollerConveyors.findIndex(rc => rc.id === rollerConveyorId);
|
||
if (rollerConveyorIndex !== -1) {
|
||
currentConfig.rollerConveyors[rollerConveyorIndex].x = x;
|
||
currentConfig.rollerConveyors[rollerConveyorIndex].y = y;
|
||
|
||
// 保存更新后的配置
|
||
$.ajax({
|
||
url: 'http://localhost:3000/api/config',
|
||
type: 'PUT',
|
||
contentType: 'application/json',
|
||
data: JSON.stringify(currentConfig),
|
||
success: function (response) {
|
||
},
|
||
error: function (xhr, status, error) {
|
||
console.error('更新滚筒输送机位置失败:', error);
|
||
}
|
||
});
|
||
}
|
||
},
|
||
error: function (xhr, status, error) {
|
||
console.error('获取配置失败:', error);
|
||
}
|
||
});
|
||
}
|
||
|
||
// 保存输送机位置到服务器
|
||
function saveConveyorPosition(id, x, y) {
|
||
// 先获取最新的配置,确保不覆盖其他设置
|
||
$.ajax({
|
||
url: 'http://localhost:3000/api/config',
|
||
type: 'GET',
|
||
success: function(currentConfig) {
|
||
// 只更新指定输送机的位置
|
||
const conveyorIndex = currentConfig.conveyors.findIndex(c => c.id === id);
|
||
if (conveyorIndex !== -1) {
|
||
currentConfig.conveyors[conveyorIndex].x = x;
|
||
currentConfig.conveyors[conveyorIndex].y = y;
|
||
|
||
// 保存更新后的配置
|
||
$.ajax({
|
||
url: 'http://localhost:3000/api/config',
|
||
type: 'PUT',
|
||
contentType: 'application/json',
|
||
data: JSON.stringify(currentConfig),
|
||
success: function (response) {
|
||
},
|
||
error: function (xhr, status, error) {
|
||
console.error('保存输送机位置失败:', error);
|
||
}
|
||
});
|
||
}
|
||
},
|
||
error: function (xhr, status, error) {
|
||
console.error('获取配置失败:', error);
|
||
}
|
||
});
|
||
}
|
||
|
||
// 保存RGV位置
|
||
function saveRgvPosition(rgvId, x, y) {
|
||
$.ajax({
|
||
url: 'http://localhost:3000/api/config',
|
||
type: 'GET',
|
||
dataType: 'json',
|
||
success: function(currentConfig) {
|
||
// 更新RGV位置
|
||
if (currentConfig.rgvs) {
|
||
const rgvIndex = currentConfig.rgvs.findIndex(r => r.id === rgvId);
|
||
if (rgvIndex !== -1) {
|
||
currentConfig.rgvs[rgvIndex].x = x;
|
||
currentConfig.rgvs[rgvIndex].y = y;
|
||
|
||
// 保存更新后的配置
|
||
$.ajax({
|
||
url: 'http://localhost:3000/api/config',
|
||
type: 'PUT',
|
||
contentType: 'application/json',
|
||
data: JSON.stringify(currentConfig),
|
||
success: function(response) {
|
||
console.log(`RGV ${rgvId} 位置已更新: (${x}, ${y})`);
|
||
},
|
||
error: function(xhr, status, error) {
|
||
console.error('保存RGV位置失败:', error);
|
||
}
|
||
});
|
||
}
|
||
}
|
||
},
|
||
error: function(xhr, status, error) {
|
||
console.error('获取配置失败:', error);
|
||
}
|
||
});
|
||
}
|
||
|
||
// 更新拖动按钮状态
|
||
function updateDragButtons(isDraggable) {
|
||
const enableBtn = document.getElementById('enableDragBtn');
|
||
const disableBtn = document.getElementById('disableDragBtn');
|
||
if (enableBtn) enableBtn.disabled = isDraggable;
|
||
if (disableBtn) disableBtn.disabled = !isDraggable;
|
||
}
|
||
|
||
// 设备信息弹框功能已移至 index.js 中
|
||
|
||
// 页面加载完成后初始化
|
||
$(document).ready(function () {
|
||
// 初始加载配置并创建方块
|
||
loadConfig();
|
||
|
||
// 只在 index.html 页面初始化拖动和缩放功能
|
||
if (document.getElementById('main')) {
|
||
initDragAndZoom();
|
||
}
|
||
|
||
|
||
|
||
// **********************定期检查配置文件更新**********************
|
||
setInterval(function () {
|
||
$.ajax({
|
||
url: 'json/config.json',
|
||
type: 'GET',
|
||
dataType: 'json',
|
||
cache: false, // 禁用缓存,确保每次都获取最新的配置
|
||
success: function (data) {
|
||
// 如果配置有变化,更新显示(不论editMode状态)
|
||
if (JSON.stringify(data) !== JSON.stringify(config)) {
|
||
config = data;
|
||
// 确保deviceDraggable默认为false
|
||
if (typeof config.deviceDraggable === 'undefined') {
|
||
config.deviceDraggable = false;
|
||
}
|
||
// 更新全局config引用
|
||
window.config = config;
|
||
createBoxes();
|
||
// 更新设备拖动状态
|
||
updateDevicesDraggableState();
|
||
}
|
||
},
|
||
error: function (xhr, status, error) {
|
||
console.error('检查配置更新失败:', error);
|
||
}
|
||
});
|
||
}, 1000); // 每秒检查一次
|
||
});
|