当前位置: 首页 > news >正文

3、食品包装控制系统 - /自动化与控制组件/food-packaging-control

76个工业组件库示例汇总

食品包装线控制系统

这是一个用于食品包装线控制系统的自定义组件,提供了食品包装生产线的可视化监控与控制界面。组件采用工业风格设计,包含生产流程控制、实时数据监控和逻辑编程三个主要功能区域。

功能特点

  1. 工业风格UI设计:深色主题,高对比度,符合工业控制系统的视觉风格
  2. 生产流程可视化:直观展示从上料到码垛的完整包装生产线工艺流程
  3. 实时数据监控:支持产量统计、质量数据和效率分析等多种数据可视化
  4. 逻辑控制编程:提供可视化编程、代码编辑和时序图三种逻辑开发方式
  5. 灵活的配置选项:可调整生产速度、包装规格等关键参数
  6. 告警系统:实时显示系统告警信息,支持告警确认和处理
  7. 系统状态监控:展示CPU负载、内存使用和通信状态等系统指标
  8. 响应式设计:适应不同屏幕尺寸,确保在各种设备上正常显示

主要区域说明

组件包含以下主要功能区域:

  1. 顶部控制栏:显示系统名称、状态和基本控制按钮(启动、停止、紧急停止)
  2. 生产流程控制区
    • 流程可视化:展示6个工站(上料、称重、包装、贴标、检测、码垛)的状态和连接
    • 生产参数控制:提供速度、包装规格和批次号等参数调整
  3. 实时数据监控区
    • 数据图表:多种图表类型,展示产量、质量和效率数据
    • 关键指标卡片:总产量、合格率、设备效率和运行时间等核心指标
  4. 逻辑编程控制区
    • 可视化编程:拖拽式逻辑流程创建
    • 代码编辑:支持梯形图、顺序功能图和结构化文本三种PLC编程语言
    • 时序图:工站操作的时序关系可视化
  5. 底部状态栏:显示告警信息、系统资源使用情况和当前时间

自定义选项

可以通过修改代码自定义以下内容:

  • 颜色主题:在CSS中修改:root中的颜色变量
  • 工站配置:在HTML的process-line区域添加或修改工站
  • 图表类型:在JavaScript的updateChart函数中修改图表样式和数据
  • 告警阈值:在JavaScript的checkAlarms函数中调整告警触发条件
  • 逻辑编程界面:修改工具箱中的逻辑元件和操作类型

连接实际设备

组件目前使用模拟数据进行演示。要连接实际的生产线设备,需要:

  1. 替换JavaScript中的数据模拟函数,连接到实际的数据源
  2. 调整控制按钮的事件处理函数,使其发送实际的控制命令
  3. 实现数据持久化存储,保存历史数据和生产记录

项目结构

在这里插入图片描述

效果展示

在这里插入图片描述

源码

index.html

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>食品包装线控制系统</title><link rel="stylesheet" href="styles.css"></head>
<body><div id="food-packaging-control"><!-- 顶部控制栏 --><div class="control-header"><div class="logo-section"><div class="system-logo">食品包装线控制系统</div><div class="system-version">v1.0</div></div><div class="control-status"><div class="status-item"><span class="status-label">系统状态:</span><span class="status-value" id="system-status">运行中</span><div class="status-indicator running"></div></div><div class="status-item"><span class="status-label">当前产量:</span><span class="status-value" id="current-output">1,245/小时</span></div><div class="control-actions"><button class="control-btn start-btn" id="start-system">启动系统</button><button class="control-btn stop-btn" id="stop-system">停止系统</button><button class="control-btn emergency-btn" id="emergency-stop">紧急停止</button></div></div></div><!-- 主内容区域 --><div class="main-content"><!-- 左侧:流程控制区 --><div class="panel process-panel"><div class="panel-header"><h3>生产流程控制</h3><div class="panel-actions"><button class="panel-btn" id="process-settings" title="流程设置"><i class="btn-icon"></i></button><button class="panel-btn" id="process-expand" title="展开视图"><i class="btn-icon"></i></button></div></div><div class="panel-body"><div class="process-visualization" id="process-visual"><!-- 包装流程可视化区域 --><div class="process-line"><div class="process-station" id="station-1"><div class="station-icon feeding"></div><div class="station-label">上料站</div><div class="station-status active" id="station-1-status"></div></div><div class="process-connection"><div class="process-flow" id="flow-1-2"></div></div><div class="process-station" id="station-2"><div class="station-icon weighing"></div><div class="station-label">称重站</div><div class="station-status active" id="station-2-status"></div></div><div class="process-connection"><div class="process-flow" id="flow-2-3"></div></div><div class="process-station" id="station-3"><div class="station-icon packaging"></div><div class="station-label">包装站</div><div class="station-status active" id="station-3-status"></div></div><div class="process-connection"><div class="process-flow" id="flow-3-4"></div></div><div class="process-station" id="station-4"><div class="station-icon labeling"></div><div class="station-label">贴标站</div><div class="station-status active" id="station-4-status"></div></div><div class="process-connection"><div class="process-flow" id="flow-4-5"></div></div><div class="process-station" id="station-5"><div class="station-icon inspection"></div><div class="station-label">检测站</div><div class="station-status active" id="station-5-status"></div></div><div class="process-connection"><div class="process-flow" id="flow-5-6"></div></div><div class="process-station" id="station-6"><div class="station-icon palletizing"></div><div class="station-label">码垛站</div><div class="station-status active" id="station-6-status"></div></div></div></div><div class="process-controls"><div class="control-group"><div class="control-label">生产速度:</div><div class="control-input"><input type="range" id="speed-control" min="50" max="150" value="100"><span id="speed-value">100%</span></div></div><div class="control-group"><div class="control-label">包装规格:</div><div class="control-input"><select id="package-type"><option value="small">小包装 (100g)</option><option value="medium" selected>中包装 (250g)</option><option value="large">大包装 (500g)</option><option value="bulk">散装 (1kg)</option></select></div></div><div class="control-group"><div class="control-label">批次号:</div><div class="control-input"><input type="text" id="batch-number" value="B202504091"></div></div></div></div></div><!-- 中间:实时数据与监控 --><div class="panel monitoring-panel"><div class="panel-header"><h3>实时数据监控</h3><div class="panel-actions"><select id="chart-selector"><option value="production">产量统计</option><option value="quality">质量数据</option><option value="efficiency">效率分析</option></select><button class="panel-btn" id="export-data" title="导出数据"><i class="btn-icon"></i></button></div></div><div class="panel-body"><div class="chart-container"><div class="chart-header"><span id="chart-title">当日产量数据</span><div class="chart-legend"><div class="legend-item"><span class="legend-color" style="background-color: #2196F3;"></span><span class="legend-text">实际产量</span></div><div class="legend-item"><span class="legend-color" style="background-color: #4CAF50;"></span><span class="legend-text">目标产量</span></div><div class="legend-item"><span class="legend-color" style="background-color: #FF5722;"></span><span class="legend-text">不良品率</span></div></div></div><div class="chart-wrapper" id="chart-area"><!-- 图表将由JavaScript渲染 --></div></div><div class="monitor-grid"><div class="monitor-card"><div class="card-label">总产量</div><div class="card-value" id="total-output">24,589</div><div class="card-unit">/</div></div><div class="monitor-card"><div class="card-label">合格率</div><div class="card-value" id="quality-rate">99.7%</div><div class="card-trend positive">0.2%</div></div><div class="monitor-card"><div class="card-label">设备效率</div><div class="card-value" id="equipment-efficiency">94.3%</div><div class="card-trend positive">1.5%</div></div><div class="monitor-card"><div class="card-label">运行时间</div><div class="card-value" id="running-time">06:42:15</div><div class="card-unit">::</div></div></div></div></div><!-- 右侧:逻辑编程区 --><div class="panel logic-panel"><div class="panel-header"><h3>逻辑控制编程</h3><div class="panel-actions"><button class="panel-btn" id="new-logic" title="新建"><i class="btn-icon">+</i></button><button class="panel-btn" id="save-logic" title="保存"><i class="btn-icon"></i></button><button class="panel-btn" id="deploy-logic" title="部署"><i class="btn-icon"></i></button></div></div><div class="panel-body"><div class="tab-header"><div class="tab active" data-tab="visual-programming">可视化编程</div><div class="tab" data-tab="code-editor">代码编辑</div><div class="tab" data-tab="sequence">时序图</div></div><div class="tab-content"><div class="tab-pane active" id="visual-programming-pane"><div class="logic-toolbox"><div class="toolbox-section"><div class="toolbox-title">控制元件</div><div class="toolbox-items"><div class="logic-item" draggable="true" data-type="start">开始</div><div class="logic-item" draggable="true" data-type="decision">判断</div><div class="logic-item" draggable="true" data-type="action">动作</div><div class="logic-item" draggable="true" data-type="delay">延时</div><div class="logic-item" draggable="true" data-type="parallel">并行</div><div class="logic-item" draggable="true" data-type="end">结束</div></div></div><div class="toolbox-section"><div class="toolbox-title">工站操作</div><div class="toolbox-items"><div class="logic-item" draggable="true" data-type="feeding">上料</div><div class="logic-item" draggable="true" data-type="weighing">称重</div><div class="logic-item" draggable="true" data-type="packaging">包装</div><div class="logic-item" draggable="true" data-type="labeling">贴标</div><div class="logic-item" draggable="true" data-type="inspection">检测</div><div class="logic-item" draggable="true" data-type="palletizing">码垛</div></div></div></div><div class="logic-canvas" id="logic-canvas"><!-- 逻辑流程图将由JavaScript渲染 --><div class="placeholder-text">拖放控制元件到此区域创建逻辑流程</div><div class="workflow-container" id="workflow-container"><!-- 工作流将在这里动态创建 --></div></div></div><div class="tab-pane" id="code-editor-pane"><div class="editor-toolbar"><select id="language-selector"><option value="ladder">梯形图</option><option value="sfc">顺序功能图</option><option value="st">结构化文本</option></select><button class="editor-btn" id="check-syntax">检查语法</button><button class="editor-btn" id="format-code">格式化</button></div><div class="code-editor" id="code-editor"><pre class="code-content" id="code-content">// 食品包装线控制逻辑// 以下为示例梯形图代码PROGRAM PackagingControlVARStartButton AT %I0.0: BOOL;StopButton AT %I0.1: BOOL;EmergencyStop AT %I0.2: BOOL;ConveyorRunning AT %Q0.0: BOOL;FeedingSystem AT %Q0.1: BOOL;WeighingSystem AT %Q0.2: BOOL;PackagingSystem AT %Q0.3: BOOL;LabelingSystem AT %Q0.4: BOOL;InspectionSystem AT %Q0.5: BOOL;PalletizingSystem AT %Q0.6: BOOL;SystemRunning: BOOL;ProductDetected AT %I0.3: BOOL;WeightOK AT %I0.4: BOOL;PackageSealed AT %I0.5: BOOL;LabelApplied AT %I0.6: BOOL;QualityCheck AT %I0.7: BOOL;END_VAR// 主控制逻辑SystemRunning := StartButton AND NOT StopButton AND NOT EmergencyStop;ConveyorRunning := SystemRunning;// 各工站控制逻辑FeedingSystem := SystemRunning AND (FeedingSystem OR NOT WeighingSystem);WeighingSystem := SystemRunning AND ProductDetected AND WeightOK;PackagingSystem := SystemRunning AND WeighingSystem AND WeightOK;LabelingSystem := SystemRunning AND PackageSealed;InspectionSystem := SystemRunning AND LabelApplied;PalletizingSystem := SystemRunning AND QualityCheck;END_PROGRAM</pre></div></div><div class="tab-pane" id="sequence-pane"><div class="sequence-diagram" id="sequence-diagram"><!-- 时序图将由JavaScript渲染 --><div class="placeholder-text">选择工站查看详细时序图</div></div><div class="sequence-controls"><div class="sequence-station-selector"><label for="station-selector">选择工站:</label><select id="station-selector"><option value="all">整体流程</option><option value="station-1">上料站</option><option value="station-2">称重站</option><option value="station-3">包装站</option><option value="station-4">贴标站</option><option value="station-5">检测站</option><option value="station-6">码垛站</option></select></div><div class="sequence-time-scale"><label for="time-scale">时间尺度:</label><select id="time-scale"><option value="1x">1x (实时)</option><option value="2x">2x (加速)</option><option value="0.5x">0.5x (减速)</option></select></div></div></div></div></div></div></div><!-- 底部状态栏 --><div class="footer-bar"><div class="alarm-section"><div class="alarm-icon" id="alarm-icon"></div><div class="alarm-count" id="alarm-count">0</div><div class="alarm-message" id="current-alarm">无告警信息</div></div><div class="system-metrics"><div class="metric"><span class="metric-label">CPU负载:</span><span class="metric-value" id="cpu-load">32%</span></div><div class="metric"><span class="metric-label">内存使用:</span><span class="metric-value" id="memory-usage">1.2GB/4GB</span></div><div class="metric"><span class="metric-label">通信状态:</span><span class="metric-value connected" id="comm-status">已连接</span></div></div><div class="system-time" id="system-time">2025-04-09 08:51:22</div></div><!-- 告警弹窗 --><div class="alarm-modal" id="alarm-modal"><div class="alarm-modal-header"><div class="alarm-modal-title">系统告警</div><div class="alarm-modal-close" id="close-alarm-modal">×</div></div><div class="alarm-modal-body"><div class="alarm-list" id="alarm-list"><!-- 告警列表将由JavaScript动态生成 --></div></div><div class="alarm-modal-footer"><button class="alarm-btn" id="acknowledge-all">确认所有</button><button class="alarm-btn" id="close-modal">关闭</button></div></div></div> <script src="script.js"></script>
</body>
</html> 

styles.css

/* 食品包装线控制系统 - 样式表 */
:root {/* 颜色变量 */--primary-dark: #1a2b42;  /* 主要深色背景 */--primary-medium: #253952; /* 次要深色背景 */--primary-light: #2d4263;  /* 浅色背景 */--accent-blue: #0288d1;    /* 蓝色强调 */--accent-green: #2e7d32;   /* 绿色强调 */--accent-red: #d32f2f;     /* 红色强调/告警 */--accent-orange: #f57c00;  /* 橙色强调/警告 */--text-primary: #ffffff;   /* 主要文本 */--text-secondary: #b0bec5; /* 次要文本 */--border-color: #37474f;   /* 边框颜色 */--hover-color: rgba(255, 255, 255, 0.08); /* 悬停效果 *//* 尺寸变量 */--header-height: 60px;--footer-height: 40px;--panel-gap: 12px;--border-radius: 4px;
}/* 基础样式 */
#food-packaging-control {font-family: 'Roboto', 'Arial', sans-serif;color: var(--text-primary);background-color: var(--primary-dark);display: flex;flex-direction: column;height: 100vh;overflow: hidden;box-sizing: border-box;margin: 0;padding: 0;user-select: none;
}#food-packaging-control * {box-sizing: border-box;
}/* 顶部控制栏 */
.control-header {height: var(--header-height);background-color: var(--primary-medium);border-bottom: 1px solid var(--border-color);display: flex;justify-content: space-between;align-items: center;padding: 0 16px;box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);z-index: 10;
}.logo-section {display: flex;flex-direction: column;align-items: flex-start;
}.system-logo {font-size: 1.2rem;font-weight: bold;letter-spacing: 0.5px;
}.system-version {font-size: 0.7rem;color: var(--text-secondary);
}.control-status {display: flex;align-items: center;gap: 24px;
}.status-item {display: flex;align-items: center;gap: 8px;
}.status-label {color: var(--text-secondary);font-size: 0.85rem;
}.status-value {font-weight: bold;font-size: 0.9rem;
}.status-indicator {width: 10px;height: 10px;border-radius: 50%;
}.status-indicator.running {background-color: var(--accent-green);box-shadow: 0 0 8px var(--accent-green);
}.status-indicator.warning {background-color: var(--accent-orange);box-shadow: 0 0 8px var(--accent-orange);
}.status-indicator.error {background-color: var(--accent-red);box-shadow: 0 0 8px var(--accent-red);
}.status-indicator.idle {background-color: var(--text-secondary);
}.control-actions {display: flex;gap: 8px;
}.control-btn {padding: 8px 12px;border: none;border-radius: var(--border-radius);font-weight: bold;font-size: 0.85rem;cursor: pointer;transition: all 0.2s;
}.start-btn {background-color: var(--accent-green);color: white;
}.start-btn:hover {background-color: #388e3c;
}.stop-btn {background-color: #455a64;color: white;
}.stop-btn:hover {background-color: #546e7a;
}.emergency-btn {background-color: var(--accent-red);color: white;
}.emergency-btn:hover {background-color: #e53935;
}/* 主内容区域 */
.main-content {flex: 1;display: flex;gap: var(--panel-gap);padding: var(--panel-gap);height: calc(100vh - var(--header-height) - var(--footer-height));overflow: hidden;
}/* 面板通用样式 */
.panel {background-color: var(--primary-medium);border-radius: var(--border-radius);box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);overflow: hidden;display: flex;flex-direction: column;
}.process-panel {flex: 1;
}.monitoring-panel {flex: 1.5;
}.logic-panel {flex: 1.5;
}.panel-header {display: flex;justify-content: space-between;align-items: center;padding: 12px 16px;background-color: var(--primary-light);border-bottom: 1px solid var(--border-color);
}.panel-header h3 {margin: 0;font-size: 1rem;font-weight: 500;letter-spacing: 0.5px;
}.panel-actions {display: flex;gap: 8px;align-items: center;
}.panel-btn {width: 30px;height: 30px;border: none;border-radius: 4px;background-color: var(--primary-medium);color: var(--text-primary);cursor: pointer;display: flex;align-items: center;justify-content: center;transition: background-color 0.2s;
}.panel-btn:hover {background-color: var(--hover-color);
}.btn-icon {font-style: normal;
}.panel-body {flex: 1;overflow: auto;padding: 16px;display: flex;flex-direction: column;gap: 16px;
}/* 流程控制面板 */
.process-visualization {background-color: var(--primary-dark);border-radius: var(--border-radius);padding: 16px;min-height: 180px;overflow: auto;
}.process-line {display: flex;align-items: center;justify-content: space-between;padding: 8px 0;
}.process-station {position: relative;width: 80px;display: flex;flex-direction: column;align-items: center;gap: 8px;z-index: 2;
}.station-icon {width: 50px;height: 50px;border-radius: 8px;background-color: var(--primary-light);border: 2px solid var(--border-color);display: flex;align-items: center;justify-content: center;position: relative;transition: all 0.3s;
}.station-icon::before {font-family: Arial, sans-serif;font-size: 24px;font-weight: bold;
}.station-icon.feeding::before { content: "F"; color: #64b5f6; }
.station-icon.weighing::before { content: "W"; color: #81c784; }
.station-icon.packaging::before { content: "P"; color: #ffb74d; }
.station-icon.labeling::before { content: "L"; color: #ba68c8; }
.station-icon.inspection::before { content: "I"; color: #4fc3f7; }
.station-icon.palletizing::before { content: "S"; color: #f06292; }.station-label {font-size: 0.8rem;text-align: center;
}.station-status {position: absolute;width: 10px;height: 10px;border-radius: 50%;top: -5px;right: 12px;
}.station-status.active {background-color: var(--accent-green);box-shadow: 0 0 5px var(--accent-green);
}.station-status.warning {background-color: var(--accent-orange);box-shadow: 0 0 5px var(--accent-orange);
}.station-status.error {background-color: var(--accent-red);box-shadow: 0 0 5px var(--accent-red);
}.station-status.idle {background-color: var(--text-secondary);
}.process-connection {flex: 1;display: flex;align-items: center;justify-content: center;padding: 0 4px;z-index: 1;
}.process-flow {height: 4px;background-color: var(--accent-blue);width: 100%;position: relative;overflow: hidden;
}.process-flow.active::after {content: '';position: absolute;top: 0;left: -20%;height: 100%;width: 20%;background-color: rgba(255, 255, 255, 0.7);animation: flow 1.5s linear infinite;
}@keyframes flow {0% { left: -20%; }100% { left: 100%; }
}.process-controls {display: flex;flex-direction: column;gap: 12px;margin-top: 16px;
}.control-group {display: flex;justify-content: space-between;align-items: center;
}.control-label {font-size: 0.85rem;color: var(--text-secondary);
}.control-input {flex: 1;max-width: 200px;display: flex;align-items: center;gap: 8px;
}input[type="range"] {flex: 1;cursor: pointer;
}input[type="text"], select {background-color: var(--primary-dark);border: 1px solid var(--border-color);border-radius: 4px;color: var(--text-primary);padding: 6px 10px;width: 100%;font-size: 0.85rem;
}select {appearance: none;background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23b0bec5' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat: no-repeat;background-position: right 8px center;padding-right: 30px;
}/* 监控面板 */
.chart-container {background-color: var(--primary-dark);border-radius: var(--border-radius);padding: 16px;min-height: 240px;display: flex;flex-direction: column;gap: 12px;
}.chart-header {display: flex;justify-content: space-between;align-items: center;flex-wrap: wrap;gap: 8px;
}#chart-title {font-weight: 500;font-size: 0.9rem;
}.chart-legend {display: flex;gap: 12px;
}.legend-item {display: flex;align-items: center;gap: 4px;font-size: 0.8rem;
}.legend-color {width: 12px;height: 12px;border-radius: 2px;
}.chart-wrapper {flex: 1;min-height: 180px;position: relative;display: flex;align-items: center;justify-content: center;
}.monitor-grid {display: grid;grid-template-columns: repeat(4, 1fr);gap: 12px;
}.monitor-card {background-color: var(--primary-dark);border-radius: var(--border-radius);padding: 12px;display: flex;flex-direction: column;align-items: center;text-align: center;
}.card-label {font-size: 0.8rem;color: var(--text-secondary);margin-bottom: 4px;
}.card-value {font-size: 1.5rem;font-weight: bold;line-height: 1;margin-bottom: 4px;
}.card-unit {font-size: 0.75rem;color: var(--text-secondary);
}.card-trend {font-size: 0.75rem;font-weight: 500;
}.card-trend.positive {color: var(--accent-green);
}.card-trend.negative {color: var(--accent-red);
}/* 逻辑编程面板 */
.tab-header {display: flex;border-bottom: 1px solid var(--border-color);margin-bottom: 16px;margin-top: -8px;
}.tab {padding: 8px 16px;font-size: 0.85rem;cursor: pointer;border-bottom: 2px solid transparent;transition: all 0.2s;
}.tab:hover {background-color: var(--hover-color);
}.tab.active {border-bottom: 2px solid var(--accent-blue);color: var(--accent-blue);
}.tab-content {flex: 1;overflow: hidden;display: flex;
}.tab-pane {flex: 1;display: none;flex-direction: column;height: 100%;overflow: hidden;
}.tab-pane.active {display: flex;
}/* 可视化编程区域 */
.logic-toolbox {background-color: var(--primary-dark);border-radius: var(--border-radius);padding: 12px;display: flex;flex-wrap: wrap;gap: 12px;margin-bottom: 12px;
}.toolbox-section {flex: 1;min-width: 150px;
}.toolbox-title {font-size: 0.8rem;color: var(--text-secondary);margin-bottom: 8px;
}.toolbox-items {display: flex;flex-wrap: wrap;gap: 8px;
}.logic-item {background-color: var(--primary-light);border: 1px solid var(--border-color);border-radius: var(--border-radius);padding: 6px 10px;font-size: 0.85rem;cursor: grab;transition: all 0.2s;
}.logic-item:hover {background-color: var(--hover-color);border-color: var(--accent-blue);
}.logic-canvas {flex: 1;background-color: var(--primary-dark);border-radius: var(--border-radius);overflow: auto;position: relative;min-height: 250px;
}.placeholder-text {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);color: var(--text-secondary);font-size: 0.9rem;text-align: center;opacity: 0.7;
}.workflow-container {padding: 20px;min-height: 100%;position: relative;
}/* 代码编辑区 */
.editor-toolbar {display: flex;gap: 8px;margin-bottom: 12px;
}.editor-btn {padding: 6px 12px;font-size: 0.85rem;border: none;background-color: var(--primary-dark);color: var(--text-primary);border-radius: var(--border-radius);cursor: pointer;transition: all 0.2s;
}.editor-btn:hover {background-color: var(--hover-color);
}.code-editor {flex: 1;background-color: var(--primary-dark);border-radius: var(--border-radius);overflow: auto;
}.code-content {font-family: 'Consolas', 'Monaco', monospace;font-size: 0.9rem;line-height: 1.5;padding: 12px;margin: 0;color: var(--text-primary);overflow: auto;tab-size: 4;
}/* 时序图区域 */
.sequence-diagram {flex: 1;background-color: var(--primary-dark);border-radius: var(--border-radius);overflow: auto;position: relative;min-height: 250px;
}.sequence-controls {display: flex;justify-content: space-between;margin-top: 12px;padding: 8px 12px;background-color: var(--primary-dark);border-radius: var(--border-radius);
}.sequence-station-selector,
.sequence-time-scale {display: flex;align-items: center;gap: 8px;font-size: 0.85rem;
}.sequence-station-selector label,
.sequence-time-scale label {color: var(--text-secondary);
}.sequence-station-selector select,
.sequence-time-scale select {width: auto;
}/* 底部状态栏 */
.footer-bar {height: var(--footer-height);background-color: var(--primary-medium);border-top: 1px solid var(--border-color);display: flex;justify-content: space-between;align-items: center;padding: 0 16px;font-size: 0.8rem;
}.alarm-section {display: flex;align-items: center;gap: 8px;
}.alarm-icon {color: var(--accent-orange);font-size: 1rem;
}.alarm-icon.active {animation: blink 1s infinite;
}@keyframes blink {0%, 100% { opacity: 1; }50% { opacity: 0.5; }
}.alarm-count {background-color: var(--accent-red);color: white;border-radius: 10px;padding: 0 6px;min-width: 18px;font-size: 0.7rem;text-align: center;display: inline-block;
}.alarm-message {color: var(--text-secondary);
}.system-metrics {display: flex;gap: 16px;
}.metric {display: flex;align-items: center;gap: 4px;
}.metric-label {color: var(--text-secondary);
}.metric-value {font-weight: 500;
}.connected {color: var(--accent-green);
}.disconnected {color: var(--accent-red);
}.system-time {color: var(--text-secondary);
}/* 告警弹窗 */
.alarm-modal {position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);background-color: var(--primary-medium);border-radius: var(--border-radius);box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);z-index: 1000;width: 500px;max-width: 90vw;max-height: 80vh;display: none;flex-direction: column;
}.alarm-modal.show {display: flex;
}.alarm-modal-header {padding: 12px 16px;background-color: var(--primary-light);border-bottom: 1px solid var(--border-color);display: flex;justify-content: space-between;align-items: center;
}.alarm-modal-title {font-weight: 500;font-size: 1rem;
}.alarm-modal-close {font-size: 1.2rem;cursor: pointer;width: 24px;height: 24px;display: flex;align-items: center;justify-content: center;border-radius: 50%;
}.alarm-modal-close:hover {background-color: var(--hover-color);
}.alarm-modal-body {padding: 16px;overflow-y: auto;flex: 1;
}.alarm-list {display: flex;flex-direction: column;gap: 8px;
}.alarm-item {display: flex;align-items: flex-start;gap: 12px;padding: 8px;border-radius: var(--border-radius);background-color: var(--primary-dark);
}.alarm-item-icon {font-size: 1.2rem;margin-top: 2px;
}.alarm-item-icon.critical {color: var(--accent-red);
}.alarm-item-icon.warning {color: var(--accent-orange);
}.alarm-item-icon.info {color: var(--accent-blue);
}.alarm-item-content {flex: 1;
}.alarm-item-title {font-weight: 500;font-size: 0.9rem;
}.alarm-item-desc {font-size: 0.8rem;color: var(--text-secondary);margin-top: 4px;
}.alarm-item-time {font-size: 0.75rem;color: var(--text-secondary);margin-top: 4px;
}.alarm-modal-footer {padding: 12px 16px;border-top: 1px solid var(--border-color);display: flex;justify-content: flex-end;gap: 8px;
}.alarm-btn {padding: 6px 12px;border: none;border-radius: var(--border-radius);font-size: 0.85rem;cursor: pointer;background-color: var(--primary-dark);color: var(--text-primary);transition: all 0.2s;
}.alarm-btn:hover {background-color: var(--hover-color);
}/* 响应式布局 */
@media (max-width: 1200px) {.main-content {flex-direction: column;overflow-y: auto;height: calc(100vh - var(--header-height) - var(--footer-height));}.process-panel, .monitoring-panel, .logic-panel {width: 100%;flex: none;}.panel {max-height: 600px;}.monitor-grid {grid-template-columns: repeat(2, 1fr);}.control-status {flex-wrap: wrap;}
}@media (max-width: 768px) {.control-header {flex-direction: column;height: auto;padding: 12px;gap: 12px;}.logo-section {align-items: center;}.control-status {width: 100%;justify-content: center;}.footer-bar {flex-direction: column;height: auto;padding: 8px;gap: 8px;text-align: center;}.system-metrics {flex-wrap: wrap;justify-content: center;}.monitor-grid {grid-template-columns: 1fr;}
} 

script.js

/*** 食品包装线控制系统 - JavaScript控制逻辑* 本文件实现了食品包装线控制系统的各项功能,包括:* - 系统状态管理* - 工站控制和状态监控* - 实时数据可视化* - 逻辑编程界面交互* - 告警管理*/// 全局变量
let systemRunning = true;          // 系统运行状态
let productionSpeed = 100;         // 生产速度(%)
let currentPackageType = 'medium'; // 当前包装类型
let batchNumber = 'B202504091';    // 当前批次号
let runningTime = 0;               // 运行时间(秒)
let totalProduction = 24589;       // 总产量
let alarmCount = 0;                // 告警数量
let alarms = [];                   // 告警列表
let stationStatus = {              // 各工站状态'station-1': 'active','station-2': 'active','station-3': 'active','station-4': 'active','station-5': 'active','station-6': 'active'
};
let flowStatus = {                 // 物料流状态'flow-1-2': true,'flow-2-3': true,'flow-3-4': true,'flow-4-5': true,'flow-5-6': true
};// 计时器
let runningTimeInterval;
let dataUpdateInterval;
let chartUpdateInterval;
let flowAnimationInterval;
let systemMetricsInterval;// 图表数据
let productionData = {labels: [...Array(12).keys()].map(i => `${8 + Math.floor(i/2)}:${i % 2 ? '30' : '00'}`),actual: [920, 1050, 1150, 1230, 1320, 1260, 1200, 1310, 1400, 1380, 1420, 1245],target: [1000, 1000, 1200, 1200, 1300, 1300, 1300, 1300, 1400, 1400, 1400, 1400],defects: [2.1, 1.8, 1.9, 0.8, 0.5, 0.7, 0.9, 0.6, 0.4, 0.5, 0.3, 0.3]
};let qualityData = {labels: ['100g', '250g', '500g', '1kg'],pass: [99.2, 99.7, 99.5, 99.1],weight: [99.5, 99.8, 99.6, 99.4],seal: [99.7, 99.9, 99.8, 99.5],label: [99.3, 99.6, 99.4, 99.2]
};let efficiencyData = {labels: [...Array(8).keys()].map(i => `${i + 8}:00`),oee: [91.2, 92.5, 93.8, 94.2, 94.5, 94.7, 94.3, 93.6],uptime: [97.5, 98.2, 98.5, 98.7, 98.8, 98.5, 98.1, 97.8],performance: [94.5, 95.2, 96.1, 96.3, 96.5, 96.7, 96.3, 95.8]
};// 工作流元素数据
let workflowElements = [];/*** 初始化函数 - 页面加载完成后执行*/
function initializeSystem() {// 绑定事件监听器bindEventListeners();// 启动系统模拟startSystemSimulation();// 初始化图表updateChart('production');// 初始化逻辑编程界面initializeLogicProgramming();// 更新系统时间updateSystemTime();console.log('食品包装线控制系统初始化完成');
}/*** 绑定所有UI元素的事件监听器*/
function bindEventListeners() {// 系统控制按钮document.getElementById('start-system').addEventListener('click', startSystem);document.getElementById('stop-system').addEventListener('click', stopSystem);document.getElementById('emergency-stop').addEventListener('click', emergencyStop);// 流程控制面板document.getElementById('process-settings').addEventListener('click', showProcessSettings);document.getElementById('process-expand').addEventListener('click', expandProcessView);document.getElementById('speed-control').addEventListener('input', updateSpeed);document.getElementById('package-type').addEventListener('change', updatePackageType);document.getElementById('batch-number').addEventListener('change', updateBatchNumber);// 监控面板document.getElementById('chart-selector').addEventListener('change', (e) => updateChart(e.target.value));document.getElementById('export-data').addEventListener('click', exportMonitoringData);// 逻辑编程面板document.querySelectorAll('.tab').forEach(tab => {tab.addEventListener('click', switchProgrammingTab);});document.getElementById('new-logic').addEventListener('click', createNewLogic);document.getElementById('save-logic').addEventListener('click', saveLogic);document.getElementById('deploy-logic').addEventListener('click', deployLogic);document.querySelectorAll('.logic-item').forEach(item => {item.addEventListener('dragstart', handleDragStart);});document.getElementById('logic-canvas').addEventListener('dragover', handleDragOver);document.getElementById('logic-canvas').addEventListener('drop', handleDrop);document.getElementById('check-syntax').addEventListener('click', checkCodeSyntax);document.getElementById('format-code').addEventListener('click', formatCode);document.getElementById('station-selector').addEventListener('change', updateSequenceDiagram);// 告警相关document.getElementById('alarm-icon').addEventListener('click', showAlarmModal);document.getElementById('close-alarm-modal').addEventListener('click', hideAlarmModal);document.getElementById('close-modal').addEventListener('click', hideAlarmModal);document.getElementById('acknowledge-all').addEventListener('click', acknowledgeAllAlarms);
}/*** 启动系统模拟*/
function startSystemSimulation() {// 设置运行时间计时器runningTimeInterval = setInterval(updateRunningTime, 1000);// 设置数据更新计时器dataUpdateInterval = setInterval(updateRealTimeData, 2000);// 设置图表更新计时器chartUpdateInterval = setInterval(() => {if (document.getElementById('chart-selector').value === 'production') {updateProductionData();updateChart('production');}}, 10000);// 设置流动动画flowAnimationInterval = setInterval(updateFlowAnimation, 5000);// 设置系统指标更新systemMetricsInterval = setInterval(updateSystemMetrics, 3000);
}/*** 停止系统模拟*/
function stopSystemSimulation() {clearInterval(runningTimeInterval);clearInterval(dataUpdateInterval);clearInterval(chartUpdateInterval);clearInterval(flowAnimationInterval);clearInterval(systemMetricsInterval);
}/*** 启动系统*/
function startSystem() {if (!systemRunning) {systemRunning = true;document.getElementById('system-status').textContent = '运行中';document.querySelector('.status-indicator').className = 'status-indicator running';startSystemSimulation();// 更新各工站状态Object.keys(stationStatus).forEach(station => {stationStatus[station] = 'active';document.getElementById(station + '-status').className = 'station-status active';});// 更新流动状态Object.keys(flowStatus).forEach(flow => {flowStatus[flow] = true;document.getElementById(flow).className = 'process-flow active';});addAlarm('info', '系统已启动', '操作员启动了系统');}
}/*** 停止系统*/
function stopSystem() {if (systemRunning) {systemRunning = false;document.getElementById('system-status').textContent = '已停止';document.querySelector('.status-indicator').className = 'status-indicator idle';stopSystemSimulation();// 更新各工站状态Object.keys(stationStatus).forEach(station => {stationStatus[station] = 'idle';document.getElementById(station + '-status').className = 'station-status idle';});// 更新流动状态Object.keys(flowStatus).forEach(flow => {flowStatus[flow] = false;document.getElementById(flow).className = 'process-flow';});addAlarm('info', '系统已停止', '操作员停止了系统');}
}/*** 紧急停止*/
function emergencyStop() {systemRunning = false;document.getElementById('system-status').textContent = '紧急停止';document.querySelector('.status-indicator').className = 'status-indicator error';stopSystemSimulation();// 更新各工站状态Object.keys(stationStatus).forEach(station => {stationStatus[station] = 'error';document.getElementById(station + '-status').className = 'station-status error';});// 更新流动状态Object.keys(flowStatus).forEach(flow => {flowStatus[flow] = false;document.getElementById(flow).className = 'process-flow';});addAlarm('critical', '系统紧急停止', '触发紧急停止按钮');
}/*** 显示流程设置*/
function showProcessSettings() {// 此处可实现流程设置弹窗console.log('显示流程设置');
}/*** 展开流程视图*/
function expandProcessView() {// 此处可实现流程图的全屏展示console.log('展开流程视图');
}/*** 更新速度设置*/
function updateSpeed(event) {productionSpeed = event.target.value;document.getElementById('speed-value').textContent = productionSpeed + '%';console.log('生产速度已更新:', productionSpeed + '%');
}/*** 更新包装类型*/
function updatePackageType(event) {currentPackageType = event.target.value;console.log('包装规格已更新:', currentPackageType);
}/*** 更新批次号*/
function updateBatchNumber(event) {batchNumber = event.target.value;console.log('批次号已更新:', batchNumber);
}/*** 导出监控数据*/
function exportMonitoringData() {console.log('导出监控数据');// 此处可实现数据导出功能
}/*** 更新图表显示*/
function updateChart(chartType) {const chartArea = document.getElementById('chart-area');let chartTitle = '';// 清空图表区域chartArea.innerHTML = '';// 根据图表类型显示不同的图表switch(chartType) {case 'production':chartTitle = '当日产量数据';renderProductionChart(chartArea);break;case 'quality':chartTitle = '产品质量数据';renderQualityChart(chartArea);break;case 'efficiency':chartTitle = '生产效率分析';renderEfficiencyChart(chartArea);break;}document.getElementById('chart-title').textContent = chartTitle;
}/*** 渲染产量图表*/
function renderProductionChart(container) {try {// 尝试使用Chart.js绘制图表if (typeof Chart !== 'undefined') {const canvas = document.createElement('canvas');container.appendChild(canvas);new Chart(canvas, {type: 'line',data: {labels: productionData.labels,datasets: [{label: '实际产量',data: productionData.actual,borderColor: '#2196F3',backgroundColor: 'rgba(33, 150, 243, 0.1)',tension: 0.3,fill: true},{label: '目标产量',data: productionData.target,borderColor: '#4CAF50',backgroundColor: 'transparent',borderDash: [5, 5],tension: 0.1},{label: '不良品率(%)',data: productionData.defects,borderColor: '#FF5722',backgroundColor: 'transparent',yAxisID: 'y1'}]},options: {scales: {y: {beginAtZero: false,title: {display: true,text: '产量 (件/小时)'}},y1: {position: 'right',beginAtZero: true,max: 5,title: {display: true,text: '不良品率 (%)'}}}}});} else {// 使用简单SVG绘制图表renderSimpleProductionChart(container);}} catch (error) {console.error('图表渲染失败:', error);renderSimpleProductionChart(container);}
}/*** 渲染简单SVG产量图表(当Chart.js不可用时)*/
function renderSimpleProductionChart(container) {const svgNS = "http://www.w3.org/2000/svg";const width = container.clientWidth;const height = 250;const svg = document.createElementNS(svgNS, "svg");svg.setAttribute("width", width);svg.setAttribute("height", height);svg.style.backgroundColor = "var(--primary-dark)";const maxValue = Math.max(...productionData.actual, ...productionData.target);const xStep = width / (productionData.labels.length - 1);const yScale = (height - 40) / maxValue;// 绘制坐标轴const axis = document.createElementNS(svgNS, "path");axis.setAttribute("d", `M 30 10 V ${height - 30} H ${width - 10}`);axis.setAttribute("stroke", "var(--border-color)");axis.setAttribute("fill", "none");svg.appendChild(axis);// 绘制实际产量线const actualLine = document.createElementNS(svgNS, "path");let path = `M ${30} ${height - 30 - productionData.actual[0] * yScale}`;for (let i = 1; i < productionData.actual.length; i++) {path += ` L ${30 + i * xStep} ${height - 30 - productionData.actual[i] * yScale}`;}actualLine.setAttribute("d", path);actualLine.setAttribute("stroke", "#2196F3");actualLine.setAttribute("stroke-width", "2");actualLine.setAttribute("fill", "none");svg.appendChild(actualLine);// 绘制目标产量线(虚线)const targetLine = document.createElementNS(svgNS, "path");path = `M ${30} ${height - 30 - productionData.target[0] * yScale}`;for (let i = 1; i < productionData.target.length; i++) {path += ` L ${30 + i * xStep} ${height - 30 - productionData.target[i] * yScale}`;}targetLine.setAttribute("d", path);targetLine.setAttribute("stroke", "#4CAF50");targetLine.setAttribute("stroke-width", "2");targetLine.setAttribute("stroke-dasharray", "5,5");targetLine.setAttribute("fill", "none");svg.appendChild(targetLine);container.appendChild(svg);
}/*** 渲染质量图表*/
function renderQualityChart(container) {try {// 尝试使用Chart.js绘制图表if (typeof Chart !== 'undefined') {const canvas = document.createElement('canvas');container.appendChild(canvas);new Chart(canvas, {type: 'bar',data: {labels: qualityData.labels,datasets: [{label: '合格率',data: qualityData.pass,backgroundColor: '#4CAF50'},{label: '重量合格',data: qualityData.weight,backgroundColor: '#2196F3'},{label: '密封合格',data: qualityData.seal,backgroundColor: '#FF9800'},{label: '标签合格',data: qualityData.label,backgroundColor: '#9C27B0'}]},options: {scales: {y: {min: 95,max: 100,title: {display: true,text: '合格率 (%)'}}}}});} else {// 使用简单SVG绘制图表renderSimpleQualityChart(container);}} catch (error) {console.error('图表渲染失败:', error);renderSimpleQualityChart(container);}
}/*** 渲染简单SVG质量图表(当Chart.js不可用时)*/
function renderSimpleQualityChart(container) {const svgNS = "http://www.w3.org/2000/svg";const width = container.clientWidth;const height = 250;const svg = document.createElementNS(svgNS, "svg");svg.setAttribute("width", width);svg.setAttribute("height", height);svg.style.backgroundColor = "var(--primary-dark)";const barWidth = 15;const groupWidth = barWidth * 4 + 20;const xStep = width / (qualityData.labels.length + 1);const yScale = (height - 40) / 5; // 5% scale (95-100%)// 绘制坐标轴const axis = document.createElementNS(svgNS, "path");axis.setAttribute("d", `M 30 10 V ${height - 30} H ${width - 10}`);axis.setAttribute("stroke", "var(--border-color)");axis.setAttribute("fill", "none");svg.appendChild(axis);// 绘制柱状图const colors = ['#4CAF50', '#2196F3', '#FF9800', '#9C27B0'];for (let i = 0; i < qualityData.labels.length; i++) {const x = 50 + i * xStep;// 绘制4种不同质量数据的柱状图for (let j = 0; j < 4; j++) {const dataKey = ['pass', 'weight', 'seal', 'label'][j];const value = qualityData[dataKey][i];const barHeight = (value - 95) * yScale;const bar = document.createElementNS(svgNS, "rect");bar.setAttribute("x", x + j * (barWidth + 5));bar.setAttribute("y", height - 30 - barHeight);bar.setAttribute("width", barWidth);bar.setAttribute("height", barHeight);bar.setAttribute("fill", colors[j]);svg.appendChild(bar);}// 绘制标签const text = document.createElementNS(svgNS, "text");text.setAttribute("x", x + groupWidth / 2 - 15);text.setAttribute("y", height - 10);text.setAttribute("fill", "var(--text-secondary)");text.setAttribute("font-size", "12");text.textContent = qualityData.labels[i];svg.appendChild(text);}container.appendChild(svg);
}/*** 渲染效率图表*/
function renderEfficiencyChart(container) {try {// 尝试使用Chart.js绘制图表if (typeof Chart !== 'undefined') {const canvas = document.createElement('canvas');container.appendChild(canvas);new Chart(canvas, {type: 'line',data: {labels: efficiencyData.labels,datasets: [{label: 'OEE',data: efficiencyData.oee,borderColor: '#2196F3',backgroundColor: 'rgba(33, 150, 243, 0.1)',tension: 0.3,fill: true},{label: '运行时间',data: efficiencyData.uptime,borderColor: '#4CAF50',backgroundColor: 'transparent',tension: 0.3},{label: '性能效率',data: efficiencyData.performance,borderColor: '#FF9800',backgroundColor: 'transparent',tension: 0.3}]},options: {scales: {y: {min: 85,max: 100,title: {display: true,text: '效率 (%)'}}}}});} else {// 使用简单SVG绘制图表renderSimpleEfficiencyChart(container);}} catch (error) {console.error('图表渲染失败:', error);renderSimpleEfficiencyChart(container);}
}/*** 渲染简单SVG效率图表(当Chart.js不可用时)*/
function renderSimpleEfficiencyChart(container) {const svgNS = "http://www.w3.org/2000/svg";const width = container.clientWidth;const height = 250;const svg = document.createElementNS(svgNS, "svg");svg.setAttribute("width", width);svg.setAttribute("height", height);svg.style.backgroundColor = "var(--primary-dark)";const xStep = width / (efficiencyData.labels.length + 1);const yScale = (height - 40) / 15; // 15% scale (85-100%)// 绘制坐标轴const axis = document.createElementNS(svgNS, "path");axis.setAttribute("d", `M 30 10 V ${height - 30} H ${width - 10}`);axis.setAttribute("stroke", "var(--border-color)");axis.setAttribute("fill", "none");svg.appendChild(axis);// 绘制OEE线const oeeLine = document.createElementNS(svgNS, "path");let path = `M ${50} ${height - 30 - (efficiencyData.oee[0] - 85) * yScale}`;for (let i = 1; i < efficiencyData.oee.length; i++) {path += ` L ${50 + i * xStep} ${height - 30 - (efficiencyData.oee[i] - 85) * yScale}`;}oeeLine.setAttribute("d", path);oeeLine.setAttribute("stroke", "#2196F3");oeeLine.setAttribute("stroke-width", "2");oeeLine.setAttribute("fill", "none");svg.appendChild(oeeLine);// 绘制运行时间线const uptimeLine = document.createElementNS(svgNS, "path");path = `M ${50} ${height - 30 - (efficiencyData.uptime[0] - 85) * yScale}`;for (let i = 1; i < efficiencyData.uptime.length; i++) {path += ` L ${50 + i * xStep} ${height - 30 - (efficiencyData.uptime[i] - 85) * yScale}`;}uptimeLine.setAttribute("d", path);uptimeLine.setAttribute("stroke", "#4CAF50");uptimeLine.setAttribute("stroke-width", "2");uptimeLine.setAttribute("fill", "none");svg.appendChild(uptimeLine);// 绘制性能效率线const perfLine = document.createElementNS(svgNS, "path");path = `M ${50} ${height - 30 - (efficiencyData.performance[0] - 85) * yScale}`;for (let i = 1; i < efficiencyData.performance.length; i++) {path += ` L ${50 + i * xStep} ${height - 30 - (efficiencyData.performance[i] - 85) * yScale}`;}perfLine.setAttribute("d", path);perfLine.setAttribute("stroke", "#FF9800");perfLine.setAttribute("stroke-width", "2");perfLine.setAttribute("fill", "none");svg.appendChild(perfLine);container.appendChild(svg);
}/*** 更新实时数据*/
function updateRealTimeData() {if (!systemRunning) return;// 模拟产量数据const hourlyRate = Math.floor(1200 * (productionSpeed / 100) * (Math.random() * 0.2 + 0.9));document.getElementById('current-output').textContent = hourlyRate.toLocaleString() + ' 件/小时';// 更新各工站状态updateStationStatus();// 模拟产品质量数据const qualityRate = (99.5 + Math.random() * 0.5).toFixed(1);document.getElementById('quality-rate').textContent = qualityRate + '%';const qualityTrend = Math.random() > 0.7 ? -0.1 : 0.2;const trendEl = document.getElementById('quality-rate').nextElementSibling;trendEl.textContent = (qualityTrend >= 0 ? '↑' : '↓') + Math.abs(qualityTrend).toFixed(1) + '%';trendEl.className = 'card-trend ' + (qualityTrend >= 0 ? 'positive' : 'negative');// 模拟设备效率数据const efficiency = (94.0 + Math.random() * 1.0).toFixed(1);document.getElementById('equipment-efficiency').textContent = efficiency + '%';const efficiencyTrend = Math.random() > 0.3 ? 1.5 : -0.8;const effTrendEl = document.getElementById('equipment-efficiency').nextElementSibling;effTrendEl.textContent = (efficiencyTrend >= 0 ? '↑' : '↓') + Math.abs(efficiencyTrend).toFixed(1) + '%';effTrendEl.className = 'card-trend ' + (efficiencyTrend >= 0 ? 'positive' : 'negative');// 更新总产量if (Math.random() > 0.7) {const increment = Math.floor(Math.random() * 20 + 10);totalProduction += increment;document.getElementById('total-output').textContent = totalProduction.toLocaleString();}// 检查是否需要产生告警checkAlarms();
}/*** 更新各工站状态*/
function updateStationStatus() {if (!systemRunning) return;// 随机选择一个工站可能出现临时警告if (Math.random() < 0.05) { // 5%概率出现警告const stationId = 'station-' + Math.ceil(Math.random() * 6);if (stationStatus[stationId] === 'active') {stationStatus[stationId] = 'warning';document.getElementById(stationId + '-status').className = 'station-status warning';// 添加警告信息const stationName = document.querySelector('#' + stationId + ' .station-label').textContent;addAlarm('warning', stationName + '状态异常', '检测到性能波动,请注意监控');// 2-5秒后自动恢复setTimeout(() => {if (systemRunning && stationStatus[stationId] === 'warning') {stationStatus[stationId] = 'active';document.getElementById(stationId + '-status').className = 'station-status active';}}, 2000 + Math.random() * 3000);}}
}/*** 更新流动动画*/
function updateFlowAnimation() {if (!systemRunning) return;// 更新流动状态动画Object.keys(flowStatus).forEach(flow => {if (flowStatus[flow]) {const el = document.getElementById(flow);// 切换动画状态来重启动画el.classList.remove('active');setTimeout(() => {if (systemRunning && flowStatus[flow]) {el.classList.add('active');}}, 50);}});
}/*** 更新系统时间*/
function updateSystemTime() {const now = new Date();const timeStr = now.toLocaleString('zh-CN', {year: 'numeric',month: '2-digit',day: '2-digit',hour: '2-digit',minute: '2-digit',second: '2-digit',hour12: false});document.getElementById('system-time').textContent = timeStr;setTimeout(updateSystemTime, 1000);
}/*** 更新运行时间*/
function updateRunningTime() {if (!systemRunning) return;runningTime++;const hours = Math.floor(runningTime / 3600).toString().padStart(2, '0');const minutes = Math.floor((runningTime % 3600) / 60).toString().padStart(2, '0');const seconds = (runningTime % 60).toString().padStart(2, '0');document.getElementById('running-time').textContent = `${hours}:${minutes}:${seconds}`;
}/*** 更新系统指标数据*/
function updateSystemMetrics() {if (!systemRunning) return;// 更新CPU负载const cpuLoad = Math.floor(20 + Math.random() * 25);document.getElementById('cpu-load').textContent = cpuLoad + '%';// 更新内存使用const memoryUsage = (1.0 + Math.random() * 0.5).toFixed(1);document.getElementById('memory-usage').textContent = memoryUsage + 'GB/4GB';// 更新通信状态if (Math.random() < 0.02) { // 2%概率通信状态变化const commStatus = document.getElementById('comm-status');if (commStatus.textContent === '已连接') {commStatus.textContent = '重连中...';commStatus.className = 'metric-value disconnected';// 添加通信中断告警addAlarm('warning', '通信状态异常', '系统正在尝试重新建立连接');// 1-3秒后恢复setTimeout(() => {if (systemRunning) {commStatus.textContent = '已连接';commStatus.className = 'metric-value connected';addAlarm('info', '通信已恢复', '系统通信连接已重新建立');}}, 1000 + Math.random() * 2000);}}
}/*** 更新产量数据(模拟数据变化)*/
function updateProductionData() {if (!systemRunning) return;// 移除第一个时间点数据productionData.labels.shift();productionData.actual.shift();productionData.target.shift();productionData.defects.shift();// 添加新的时间点数据const lastTime = productionData.labels[productionData.labels.length - 1];const [hour, minute] = lastTime.split(':').map(Number);let newHour = hour;let newMinute = minute + 30;if (newMinute >= 60) {newMinute = 0;newHour += 1;}const newTimeStr = `${newHour}:${newMinute === 0 ? '00' : '30'}`;productionData.labels.push(newTimeStr);// 添加新的产量数据const lastTarget = productionData.target[productionData.target.length - 1];const newTarget = lastTarget + (Math.random() > 0.7 ? 100 : 0);const baseProduction = newTarget * (productionSpeed / 100);const newProduction = Math.floor(baseProduction * (0.9 + Math.random() * 0.2));const newDefect = Math.max(0.1, Math.min(3.0, productionData.defects[productionData.defects.length - 1] + (Math.random() - 0.5))).toFixed(1);productionData.target.push(newTarget);productionData.actual.push(newProduction);productionData.defects.push(parseFloat(newDefect));
}/*** 检查是否产生告警*/
function checkAlarms() {if (!systemRunning) return;// 随机触发告警(低概率)if (Math.random() < 0.04) { // 4%概率产生新告警const alarmTypes = [{ level: 'info', title: '批次变更通知', desc: '系统已自动更新至新批次:' + batchNumber },{ level: 'info', title: '日常维护提醒', desc: '设备1号传送带已运行720小时,建议进行日常维护检查' },{ level: 'warning', title: '质量波动', desc: '最近30分钟内包装质量合格率出现轻微下降' },{ level: 'warning', title: '能耗异常', desc: '3号包装工位能耗高于正常值15%,建议检查' },{ level: 'warning', title: '备料不足', desc: '备料区原材料库存低于预警阈值,请及时补充' },{ level: 'critical', title: '设备故障', desc: '标签打印机5分钟内多次出现卡纸现象,需要检修' },{ level: 'critical', title: '温度超限', desc: '热封区温度超出工艺范围,当前值: 185°C (标准:160±10°C)' }];const alarm = alarmTypes[Math.floor(Math.random() * alarmTypes.length)];addAlarm(alarm.level, alarm.title, alarm.desc);}
}/*** 添加新告警*/
function addAlarm(level, title, description) {// 创建新告警const alarm = {id: Date.now(),level: level,title: title,description: description,time: new Date(),acknowledged: false};// 添加到告警列表alarms.unshift(alarm);// 限制告警列表最大长度if (alarms.length > 50) {alarms.pop();}// 更新告警计数updateAlarmCount();// 更新当前告警信息document.getElementById('current-alarm').textContent = title;// 更新告警图标状态const alarmIcon = document.getElementById('alarm-icon');alarmIcon.classList.add('active');// 如果是严重告警,弹出告警窗口if (level === 'critical') {showAlarmModal();}// 更新告警列表(如果弹窗已显示)if (document.querySelector('.alarm-modal.show')) {updateAlarmList();}
}/*** 更新告警计数*/
function updateAlarmCount() {// 统计未确认告警数量const unacknowledgedCount = alarms.filter(alarm => !alarm.acknowledged).length;alarmCount = unacknowledgedCount;// 更新告警计数显示document.getElementById('alarm-count').textContent = alarmCount;// 更新告警图标状态const alarmIcon = document.getElementById('alarm-icon');if (alarmCount > 0) {alarmIcon.classList.add('active');} else {alarmIcon.classList.remove('active');}
}/*** 显示告警弹窗*/
function showAlarmModal() {// 更新告警列表updateAlarmList();// 显示弹窗const alarmModal = document.getElementById('alarm-modal');alarmModal.classList.add('show');
}/*** 隐藏告警弹窗*/
function hideAlarmModal() {const alarmModal = document.getElementById('alarm-modal');alarmModal.classList.remove('show');
}/*** 更新告警列表*/
function updateAlarmList() {const alarmList = document.getElementById('alarm-list');alarmList.innerHTML = '';if (alarms.length === 0) {const emptyMessage = document.createElement('div');emptyMessage.className = 'empty-alarm';emptyMessage.textContent = '无告警信息';alarmList.appendChild(emptyMessage);return;}// 创建告警列表项alarms.forEach(alarm => {const alarmItem = document.createElement('div');alarmItem.className = `alarm-item ${alarm.level} ${alarm.acknowledged ? 'acknowledged' : ''}`;alarmItem.dataset.id = alarm.id;// 告警时间const time = document.createElement('div');time.className = 'alarm-time';time.textContent = formatTime(alarm.time);// 告警图标const icon = document.createElement('div');icon.className = 'alarm-icon';icon.innerHTML = alarm.level === 'critical' ? '⚠' : (alarm.level === 'warning' ? '⚠' : 'ℹ');// 告警内容const content = document.createElement('div');content.className = 'alarm-content';const title = document.createElement('div');title.className = 'alarm-title';title.textContent = alarm.title;const description = document.createElement('div');description.className = 'alarm-description';description.textContent = alarm.description;content.appendChild(title);content.appendChild(description);// 确认按钮const ackBtn = document.createElement('button');ackBtn.className = 'alarm-ack-btn';ackBtn.textContent = '确认';ackBtn.addEventListener('click', () => acknowledgeAlarm(alarm.id));if (!alarm.acknowledged) {alarmItem.appendChild(icon);alarmItem.appendChild(time);alarmItem.appendChild(content);alarmItem.appendChild(ackBtn);} else {alarmItem.appendChild(icon);alarmItem.appendChild(time);alarmItem.appendChild(content);const ackMark = document.createElement('div');ackMark.className = 'alarm-ack-mark';ackMark.textContent = '已确认';alarmItem.appendChild(ackMark);}alarmList.appendChild(alarmItem);});
}/*** 确认单个告警*/
function acknowledgeAlarm(id) {const alarm = alarms.find(a => a.id === id);if (alarm) {alarm.acknowledged = true;// 更新告警计数updateAlarmCount();// 更新告警列表updateAlarmList();}
}/*** 确认所有告警*/
function acknowledgeAllAlarms() {alarms.forEach(alarm => {alarm.acknowledged = true;});// 更新告警计数updateAlarmCount();// 更新告警列表updateAlarmList();// 如果没有未确认的告警,自动关闭弹窗setTimeout(hideAlarmModal, 500);
}/*** 格式化时间显示*/
function formatTime(date) {const hours = date.getHours().toString().padStart(2, '0');const minutes = date.getMinutes().toString().padStart(2, '0');const seconds = date.getSeconds().toString().padStart(2, '0');return `${hours}:${minutes}:${seconds}`;
}/*** 切换逻辑编程区域的Tab*/
function switchProgrammingTab(event) {// 获取当前点击的Tabconst clickedTab = event.currentTarget;// 获取目标Tab的IDconst targetTabId = clickedTab.dataset.tab;// 移除所有Tab的active类document.querySelectorAll('.tab').forEach(tab => {tab.classList.remove('active');});// 隐藏所有Tab内容document.querySelectorAll('.tab-pane').forEach(pane => {pane.classList.remove('active');});// 添加当前Tab的active类clickedTab.classList.add('active');// 显示对应的Tab内容document.getElementById(targetTabId + '-pane').classList.add('active');
}/*** 初始化逻辑编程界面*/
function initializeLogicProgramming() {// 设置Canvas的拖放区域setupDragAndDrop();// 初始化代码编辑器initializeCodeEditor();// 初始化时序图updateSequenceDiagram();
}/*** 设置拖放功能*/
function setupDragAndDrop() {const logicCanvas = document.getElementById('logic-canvas');// 添加提示文本const placeholderText = document.createElement('div');placeholderText.className = 'placeholder-text';placeholderText.textContent = '拖放控制元件到此区域创建逻辑流程';// 初始化工作流容器const workflowContainer = document.getElementById('workflow-container');if (!workflowContainer) {const container = document.createElement('div');container.id = 'workflow-container';container.className = 'workflow-container';logicCanvas.appendChild(container);}
}/*** 处理拖动开始事件*/
function handleDragStart(event) {// 存储被拖动元素的类型event.dataTransfer.setData('type', event.target.dataset.type);event.dataTransfer.effectAllowed = 'copy';
}/*** 处理拖动经过事件*/
function handleDragOver(event) {event.preventDefault();event.dataTransfer.dropEffect = 'copy';// 添加拖动经过的视觉效果event.currentTarget.classList.add('drag-over');
}/*** 处理拖放事件*/
function handleDrop(event) {event.preventDefault();// 移除拖动经过的视觉效果event.currentTarget.classList.remove('drag-over');// 获取被拖动元素的类型const type = event.dataTransfer.getData('type');// 获取放置位置const canvasRect = event.currentTarget.getBoundingClientRect();const x = event.clientX - canvasRect.left;const y = event.clientY - canvasRect.top;// 创建新的逻辑元素createLogicElement(type, x, y);
}/*** 创建新的逻辑元素*/
function createLogicElement(type, x, y) {// 元素配置const elementConfig = {start: { shape: 'circle', label: '开始', color: '#4CAF50' },decision: { shape: 'diamond', label: '判断', color: '#FF9800' },action: { shape: 'rect', label: '动作', color: '#2196F3' },delay: { shape: 'rect', label: '延时', color: '#9C27B0' },parallel: { shape: 'rect', label: '并行', color: '#00BCD4' },end: { shape: 'circle', label: '结束', color: '#F44336' },feeding: { shape: 'rect', label: '上料', color: '#2196F3' },weighing: { shape: 'rect', label: '称重', color: '#4CAF50' },packaging: { shape: 'rect', label: '包装', color: '#FF9800' },labeling: { shape: 'rect', label: '贴标', color: '#9C27B0' },inspection: { shape: 'rect', label: '检测', color: '#00BCD4' },palletizing: { shape: 'rect', label: '码垛', color: '#795548' }};const config = elementConfig[type] || { shape: 'rect', label: type, color: '#607D8B' };// 创建新元素const id = 'element-' + Date.now();const element = {id: id,type: type,label: config.label,shape: config.shape,color: config.color,x: x,y: y,connections: []};// 添加到元素列表workflowElements.push(element);// 渲染新元素renderLogicElement(element);
}/*** 渲染逻辑元素*/
function renderLogicElement(element) {const container = document.getElementById('workflow-container');// 创建元素DOMconst el = document.createElement('div');el.id = element.id;el.className = `workflow-element ${element.shape} ${element.type}`;el.style.left = element.x + 'px';el.style.top = element.y + 'px';el.style.backgroundColor = element.color;// 添加标签const label = document.createElement('div');label.className = 'element-label';label.textContent = element.label;el.appendChild(label);// 添加连接点const connectionPoints = document.createElement('div');connectionPoints.className = 'connection-points';['top', 'right', 'bottom', 'left'].forEach(position => {const point = document.createElement('div');point.className = `connection-point ${position}`;point.dataset.position = position;point.dataset.elementId = element.id;// 添加连接点的事件处理point.addEventListener('mousedown', startConnection);connectionPoints.appendChild(point);});el.appendChild(connectionPoints);// 添加拖动功能el.draggable = true;el.addEventListener('dragstart', handleElementDragStart);el.addEventListener('dragend', handleElementDragEnd);// 添加双击编辑功能el.addEventListener('dblclick', editElement);// 添加到容器container.appendChild(el);
}/*** 开始创建连接*/
function startConnection(event) {// 这里实现连接创建逻辑console.log('开始创建连接点,从元素:', event.target.dataset.elementId);
}/*** 处理元素拖动开始*/
function handleElementDragStart(event) {// 保存当前位置信息const elementId = event.target.id;const element = workflowElements.find(el => el.id === elementId);if (element) {event.dataTransfer.setData('elementId', elementId);// 设置拖动时的视觉效果event.target.classList.add('dragging');}
}/*** 处理元素拖动结束*/
function handleElementDragEnd(event) {// 移除拖动时的视觉效果event.target.classList.remove('dragging');
}/*** 编辑元素*/
function editElement(event) {const elementId = event.currentTarget.id;const element = workflowElements.find(el => el.id === elementId);if (element) {// 这里可以实现弹出编辑对话框等功能console.log('编辑元素:', element);}
}/*** 创建新的逻辑流程*/
function createNewLogic() {// 清空工作区const container = document.getElementById('workflow-container');container.innerHTML = '';// 清空元素列表workflowElements = [];console.log('创建新的逻辑流程');
}/*** 保存当前逻辑流程*/
function saveLogic() {// 这里可以实现保存逻辑,如导出JSON等console.log('保存逻辑流程:', workflowElements);
}/*** 部署逻辑流程*/
function deployLogic() {// 这里可以实现部署逻辑console.log('部署逻辑流程');// 显示部署成功消息addAlarm('info', '逻辑流程已部署', '新的控制逻辑已成功部署到系统');
}/*** 初始化代码编辑器*/
function initializeCodeEditor() {// 这里可以添加代码编辑器的高亮和自动完成等功能console.log('初始化代码编辑器');
}/*** 检查代码语法*/
function checkCodeSyntax() {const code = document.getElementById('code-content').textContent;// 这里可以实现语法检查逻辑console.log('检查代码语法');// 模拟语法检查结果const hasErrors = Math.random() < 0.3;if (hasErrors) {addAlarm('warning', '语法检查发现问题', '代码第25行可能存在语法错误,请检查');} else {addAlarm('info', '语法检查通过', '代码语法检查未发现问题');}
}/*** 格式化代码*/
function formatCode() {// 这里可以实现代码格式化逻辑console.log('格式化代码');// 添加操作提示addAlarm('info', '代码已格式化', '代码格式化操作已完成');
}/*** 更新时序图*/
function updateSequenceDiagram() {const selectedStation = document.getElementById('station-selector').value;const diagram = document.getElementById('sequence-diagram');// 清空时序图区域diagram.innerHTML = '';if (selectedStation === 'all') {renderFullSequenceDiagram(diagram);} else {renderStationSequenceDiagram(diagram, selectedStation);}
}/*** 渲染完整流程时序图*/
function renderFullSequenceDiagram(container) {// 这里可以实现完整流程时序图的渲染console.log('渲染完整流程时序图');// 示例简单时序图const svgNS = "http://www.w3.org/2000/svg";const width = container.clientWidth;const height = 300;const svg = document.createElementNS(svgNS, "svg");svg.setAttribute("width", width);svg.setAttribute("height", height);svg.style.backgroundColor = "var(--primary-dark)";// 绘制简单的时序线const stations = ['控制系统', '上料站', '称重站', '包装站', '贴标站', '检测站', '码垛站'];const xStep = width / (stations.length + 1);// 绘制垂直生命线stations.forEach((station, i) => {const x = (i + 1) * xStep;// 绘制站点标签const text = document.createElementNS(svgNS, "text");text.setAttribute("x", x);text.setAttribute("y", 20);text.setAttribute("text-anchor", "middle");text.setAttribute("fill", "var(--text-primary)");text.setAttribute("font-size", "12");text.textContent = station;svg.appendChild(text);// 绘制垂直线const line = document.createElementNS(svgNS, "line");line.setAttribute("x1", x);line.setAttribute("y1", 30);line.setAttribute("x2", x);line.setAttribute("y2", height - 10);line.setAttribute("stroke", "var(--border-color)");line.setAttribute("stroke-dasharray", "5,5");svg.appendChild(line);});// 绘制消息箭头const messages = [{ from: 0, to: 1, label: '启动指令', y: 60 },{ from: 1, to: 2, label: '物料传送', y: 90 },{ from: 2, to: 3, label: '重量数据', y: 120 },{ from: 3, to: 4, label: '包装完成', y: 150 },{ from: 4, to: 5, label: '贴标完成', y: 180 },{ from: 5, to: 6, label: '检测结果', y: 210 },{ from: 6, to: 0, label: '流程完成', y: 240 }];messages.forEach(msg => {const x1 = (msg.from + 1) * xStep;const x2 = (msg.to + 1) * xStep;const y = msg.y;// 绘制箭头线const arrow = document.createElementNS(svgNS, "line");arrow.setAttribute("x1", x1);arrow.setAttribute("y1", y);arrow.setAttribute("x2", x2);arrow.setAttribute("y2", y);arrow.setAttribute("stroke", "#4CAF50");arrow.setAttribute("stroke-width", "1.5");arrow.setAttribute("marker-end", "url(#arrow)");svg.appendChild(arrow);// 绘制消息标签const text = document.createElementNS(svgNS, "text");text.setAttribute("x", (x1 + x2) / 2);text.setAttribute("y", y - 5);text.setAttribute("text-anchor", "middle");text.setAttribute("fill", "var(--text-secondary)");text.setAttribute("font-size", "10");text.textContent = msg.label;svg.appendChild(text);});// 添加箭头标记定义const defs = document.createElementNS(svgNS, "defs");const marker = document.createElementNS(svgNS, "marker");marker.setAttribute("id", "arrow");marker.setAttribute("viewBox", "0 0 10 10");marker.setAttribute("refX", "9");marker.setAttribute("refY", "5");marker.setAttribute("markerWidth", "6");marker.setAttribute("markerHeight", "6");marker.setAttribute("orient", "auto");const path = document.createElementNS(svgNS, "path");path.setAttribute("d", "M 0 0 L 10 5 L 0 10 z");path.setAttribute("fill", "#4CAF50");marker.appendChild(path);defs.appendChild(marker);svg.appendChild(defs);container.appendChild(svg);
}/*** 渲染单个工站的时序图*/
function renderStationSequenceDiagram(container, stationId) {// 这里可以实现单个工站的时序图渲染console.log('渲染工站时序图:', stationId);// 添加提示信息const info = document.createElement('div');info.className = 'station-sequence-info';info.textContent = '显示 ' + document.querySelector('#' + stationId + ' .station-label').textContent + ' 的详细时序操作';container.appendChild(info);
}// 页面加载完成后初始化系统
document.addEventListener('DOMContentLoaded', initializeSystem); 

相关文章:

3、食品包装控制系统 - /自动化与控制组件/food-packaging-control

76个工业组件库示例汇总 食品包装线控制系统 这是一个用于食品包装线控制系统的自定义组件&#xff0c;提供了食品包装生产线的可视化监控与控制界面。组件采用工业风格设计&#xff0c;包含生产流程控制、实时数据监控和逻辑编程三个主要功能区域。 功能特点 工业风格UI设…...

AbMole的Calcein-AM/PI细胞双染试剂盒,精准区分细胞活死状态

在细胞生物学研究中&#xff0c;细胞活性检测是基础且关键的实验环节。然而&#xff0c;传统方法在检测活细胞和死细胞时常常面临诸多挑战&#xff1a;例如&#xff0c;检测过程复杂、耗时&#xff0c;容易受到细胞类型和实验条件的限制&#xff1b;荧光信号不稳定&#xff0c;…...

力扣刷题Day 37:LRU 缓存(146)

1.题目描述 2.思路 方法1&#xff1a;直接用Python封装好的数据结构OrderedDict&#xff08;兼具哈希表与双向链表的数据结构&#xff09;。 方法2&#xff1a;哈希表辅以双向链表。 3.代码&#xff08;Python3&#xff09; 方法1&#xff1a; class LRUCache(collections…...

动态规划之01背包——三道题助你理解01背包

目录 二维数组实现 一维数组实现 例一P1164 小A点菜 P1048 [NOIP 2005 普及组] 采药 P1802 5 倍经验日 首先做动规很好的一个办法就是卡哥提出的动规五部曲个人觉得很好用 确定dp数组&#xff08;dp table&#xff09;以及下标的含义 确定递推公式 dp数组如何初始化 确定遍…...

【前端笔记】CSS 选择器的常见用法

目录 1. CSS 的基本语法规范2. CSS 的引入方式3. CSS 选择器的种类3.1 标签选择器3.2 类选择器3.3 id 选择器3.4 复合选择器3.5 通配符选择器 4. 补充内容 1. CSS 的基本语法规范 选择器 {1 条 / n 条声明} 选择器决定的是修改谁声明决定的是怎么修改声明的属性是键值对&…...

电脑桌面悬浮窗便签,好用的电脑桌面便签工具

不知道大家有没有发现&#xff0c;我们每天要处理的事情越来越多&#xff1a;工作会议、项目截止日期、临时灵感、购物清单...光靠大脑记忆显然不够靠谱。你可能试过用手机备忘录&#xff0c;但工作时频繁切换设备又很影响效率。 这时候&#xff0c;一款好用的电脑桌面便签工具…...

Windows环境下maven的安装与配置

1.检查JAVA_HOME环境变量 Maven是使用java开发的&#xff0c;所以必须知道当前系统环境中的JDK的安装目录。 搜索栏直接输入“cmd” 或者 WinR 输入cmd 在打开的终端窗口输入“echo %JAVA_HOME”&#xff0c;就可以看到jdk的位置了。 如果没有的话&#xff0c;请参考我的文章&a…...

PyTorch 中如何针对 GPU 和 TPU 使用不同的处理方式

一个简单的矩阵乘法例子来演示在 PyTorch 中如何针对 GPU 和 TPU 使用不同的处理方式。 这个例子会展示核心的区别在于如何获取和指定计算设备&#xff0c;以及&#xff08;对于 TPU&#xff09;可能需要额外的库和同步操作。 示例代码&#xff1a; import torch import tim…...

数据库同步方案:构建企业数据流通的高速通道

在数字经济时代&#xff0c;数据已成为企业核心资产。根据Gartner统计&#xff0c;超过70%的企业因数据孤岛问题导致决策延迟&#xff0c;而高效可靠的数据库同步方案正是破解这一困局的关键技术。本文将深度解析数据库同步的核心逻辑、主流方案及实践策略&#xff0c;助企业构…...

微信小程序开发,登录注册实现

文章目录 1. 官方文档教程2. 注册实现3. 登录实现4. 关于作者其它项目视频教程介绍 1. 官方文档教程 https://developers.weixin.qq.com/miniprogram/dev/framework/路由跳转的几种方式&#xff1a; https://developers.weixin.qq.com/miniprogram/dev/api/route/wx.switchTab…...

VSCode怎么同时打开多个页面

VSCode中打开一个文件会把另一个文件覆盖&#xff0c;始终保持打开一个文件的状态&#xff0c;相对于其他IDE是不太习惯的&#xff0c;如果同时打开两个文件页面怎么去设置呢 1、禁用预览模式 2、快速分屏快捷键&#xff1a; Ctrl\ (Windows/Linux) 或 Cmd\ (macOS)...

【多种不同提交方式】通过springboot实现与前端网页数据交互(非常简洁快速)

【多种不同提交方式】通过springboot实现与前端网页数据交互 提示&#xff1a;帮帮志会陆续更新非常多的IT技术知识&#xff0c;希望分享的内容对您有用。本章分享的是springboot的使用。前后每一小节的内容是存在的有&#xff1a;学习and理解的关联性。【帮帮志系列文章】&am…...

Web 架构之负载均衡全解析

文章目录 一、引言二、思维导图三、负载均衡的定义与作用定义作用1. 提高可用性2. 增强性能3. 实现扩展性 四、负载均衡类型硬件负载均衡代表设备优缺点 软件负载均衡应用层负载均衡代表软件优缺点 网络层负载均衡代表软件优缺点 五、负载均衡算法轮询算法&#xff08;Round Ro…...

猫咪如厕检测与分类识别系统系列~进阶【一】视频流推流及网页实时展示

前情提要 家里养了三只猫咪&#xff0c;其中一只布偶猫经常出入厕所。但因为平时忙于学业&#xff0c;没法时刻关注牠的行为。我知道猫咪的如厕频率和时长与健康状况密切相关&#xff0c;频繁如厕可能是泌尿问题&#xff0c;停留过久也可能是便秘或不适。为了更科学地了解牠的如…...

DeepSeek全域智能革命:从量子纠缠到星际文明的认知跃迁引言:认知边界的坍缩与重构

一、认知架构的技术基石 1.1 混合专家系统的流形蒸馏 DeepSeek-R2的MoE架构采用微分流形蒸馏技术&#xff0c;将6710亿参数的教师模型&#xff08;如DeepSeek-Prover-V2&#xff09;的知识嵌入到动态路由网络中。通过辛几何约束下的参数投影&#xff0c;模型在保留数学证明能…...

Mkdocs页面如何嵌入PDF

嵌入PDF 嵌入PDF代码 &#xff0c;注意PDF的相对地址 <iframe src"../个人简历.pdf (相对地址)" width"100%" height"800px" style"border: 1px solid #ccc; overflow: auto;"></iframe>我的完整代码&#xff1a; <d…...

JS进阶DAY2 构造函数数据常用函数

深入对象 1.创建对象的三种方式 1.利用对象字面量创建对象 const o{ name:佩奇 } 2.利用 new Object 创建对象 const onew Object({ name:佩奇}) console.log(o) //{name:佩奇} 3.利用构造函数创建对象 2.构造函数 构造函数:是一种特殊的函数&#xff0c;主要用来初始…...

【ARM AMBA AHB 入门 3 -- AHB 总线介绍】

请阅读【ARM AMBA 总线 文章专栏导读】 文章目录 AHB Bus 简介AHB Bus 构成AHB BUS 工作机制AHB 传输阶段 AHB InterfacesAHB仲裁信号 AHB 数据访问零等待传输(no waitstatetransfer)等待传输(transfers with wait states)多重传送(multipletransfer)--Pipeline AHB 控制信号 A…...

计划评审技术PERT

计划评审技术&#xff08;Program Evaluation and Review Technique&#xff0c;PERT&#xff09;是一种用于项目管理和分析的工具&#xff0c;主要用于估算项目完成时间、识别关键路径以及评估项目进度风险。它最初是在20世纪50年代由美国海军开发的&#xff0c;用于管理复杂的…...

【Leetcode 每日一题 - 扩展】3342. 到达最后一个房间的最少时间 II

问题背景 有一个地窖&#xff0c;地窖中有 n m n \times m nm 个房间&#xff0c;它们呈网格状排布。 给你一个大小为 n m n \times m nm 的二维数组 m o v e T i m e moveTime moveTime&#xff0c;其中 m o v e T i m e [ i ] [ j ] moveTime[i][j] moveTime[i][j] 表…...

Linux57配置MYSQL YUM源

错了&#xff0c;弄错了下载地址 显示没MYSQL 刚才YUM包弄错了 下的是rpm文件 应该安装 通过yum install安装 .repo中的enabled需要修改 哪些能修改 哪些不改 配置特定软件的YUM仓库 nginx看教程有官方文档 将官方文档中YUM配置写入.repo文件然后yum clean all yum ma…...

Kafka是什么?典型应用场景有哪些? (消息队列、流处理平台;日志收集、实时分析、事件驱动架构等)

Kafka 核心解析与场景代码示例 一、Kafka核心概念 Apache Kafka 是分布式流处理平台&#xff0c;具备以下核心能力&#xff1a; 发布-订阅模型&#xff1a;支持多生产者/消费者并行处理持久化存储&#xff1a;消息默认保留7天&#xff08;可配置&#xff09;分区机制&#x…...

数据实验分析

数据分析数据分类与绘图数据分类方法&#xff1a;通过指定列名和函数&#xff08;如SUM&#xff09;来分类数据&#xff0c;确保数据集中包含所需列&#xff0c;否则会报错。嵌套柱形图应用&#xff1a;嵌套柱形图用于展示多层次分类的数据&#xff0c;如按店名和化妆品类别分类…...

PostgreSQL中“参数默认值实现伪重载“详解

什么是伪重载&#xff1f; "伪重载"指的是通过单一函数定义配合参数默认值和条件逻辑来模拟传统编程语言中方法重载的效果。与真正的函数重载&#xff08;PostgreSQL支持的多同名函数不同参数实现&#xff09;不同&#xff0c;伪重载是在一个函数内部处理不同参数组…...

在IDEA中编写Spark程序并运行

Spark是基于scala的&#xff0c;当然它也可以支持java和scala还有python语言&#xff0c;我们这里会使用scala。 1.在Idea中安装插件&#xff0c;使得Idea中可以编写scala代码。 2.使用Maven创建项目&#xff0c;并在pom.xml文件中配置相关的依赖。 3.设置maven依赖项。修改po…...

知识图谱:AI大脑中的“超级地图”如何炼成?

人类看到“苹果”一词&#xff0c;会瞬间联想到“iPhone”“乔布斯”“牛顿”&#xff0c;甚至“维生素C”——这种思维跳跃的背后&#xff0c;是大脑将概念连结成网的能力。而AI要模仿这种能力&#xff0c;需要一张动态的“数字地图”来存储和链接知识&#xff0c;这就是​知识…...

Facebook隐私设置详解:如何保护你的个人信息

在这个数字化时代&#xff0c;个人信息安全变得尤为重要。Facebook 作为全球最大的社交网络平台之一&#xff0c;拥有数十亿用户。然而&#xff0c;随着用户数量的增加&#xff0c;隐私问题也日益凸显。本文将详细介绍 Facebook 的隐私设置&#xff0c;帮助你更好地保护个人信息…...

【Hive入门】Hive数据导入与导出:批量操作与HDFS数据迁移完全指南

目录 引言 1 Hive数据导入概述 1.1 Hive数据导入方式分类 1.2 Hive数据模型与存储结构 2 LOAD DATA命令详解 2.1 基本语法与参数 2.2 LOAD DATA执行流程 2.3 案例分析 3 HDFS数据迁移技术 3.1 HDFS文件操作与Hive集成 3.2 外部表技术应用 3.3 分区表动态加载 4 性…...

深入浅出JSON:现代数据交换的基石

JSON&#xff08;JavaScript Object Notation&#xff09;已经成为当今互联网上最流行的数据交换格式之一。无论是Web API、配置文件还是NoSQL数据库&#xff0c;JSON都扮演着至关重要的角色。本文将带你全面了解JSON&#xff0c;从基础概念到高级应用。 什么是JSON&#xff1…...

C++ 日志系统实战第四步:设计与代码实现详解

全是通俗易懂的讲解&#xff0c;如果你本节之前的知识都掌握清楚&#xff0c;那就速速来看我的项目笔记吧~ 本文将加入项目代码编写&#xff01; 目录 日志系统框架设计 模块划分 模块关系图 代码设计 实用类设计 日志等级设计 日志消息类 日志输出格式 日志落地(L…...

DeepSeek API接口调用示例(开发语言C#,替换其中key值为自己的key值即可)

示例&#xff1a; DeepSeek官方接口说明文档&#xff1a;对话补全 | DeepSeek API Docs 官网暂未提供C#代码实现&#xff1a;&#xff08;以下为根据CURL接口C#代码调用&#xff09; using System; using System.Collections.Generic; using System.Linq; using System.Text; …...

PyTorch常用命令(可快速上手PyTorch的核心功能,涵盖从数据预处理到模型训练的全流程)

以下是PyTorch常用命令的分类整理&#xff0c;涵盖张量操作、模型构建、数据加载、训练流程等核心内容&#xff1a; 1. 张量操作 创建张量 x torch.tensor([1, 2, 3]) # 从数据创建 x torch.zeros(3, 3) # 全零张量 x torch.ones(3, 3) …...

软开错题(二)

SNMP的传输层协议是UDP Linux操作系统中通常使用apache作为web服务器&#xff0c;其默认的web站点的目录是 /var/www/html 归并排序不是原地排序 邻接表&#xff1a;包含n个头节点和e个表节点&#xff0c;其广度和深度遍历的时间复杂度都是O(ne) grant使用方式 grant 权限 …...

拉削丝锥,螺纹类加工的选择之一

在我们的日常生活中&#xff0c;螺纹连接无处不在&#xff0c;从简单的螺丝钉到复杂的机械设备&#xff0c;都离不开螺纹的精密加工。今天&#xff0c;给大家介绍一种的螺纹刀具——拉削丝锥&#xff1a; 一、拉削丝锥的工作原理 拉削丝锥&#xff0c;听起来有点陌生吧&#…...

【Python Number(数字)】

Python 中的数字类型是编程的基础元素&#xff0c;用于表示数值数据并进行数学运算。以下是 Python 数字类型的核心知识点&#xff1a; 一、基础数字类型 整数&#xff08;int&#xff09; 表示整数值&#xff0c;例如 42, -7, 0支持任意精度&#xff08;无大小限制&#xff09…...

​​大疆无人机SDR 链路​​

在大疆无人机或通信技术领域&#xff0c;​​SDR​​ 是 ​​Software-Defined Radio&#xff08;软件定义无线电&#xff09;​​ 的缩写&#xff0c;而 ​​SDR 链路​​ 指的是一种​​通过软件编程实现无线通信功能的技术链路​​。其核心是通过软件动态调整通信参数&#…...

linux基础学习--linux磁盘与文件管理系统

linux磁盘与文件管理系统 1.认识linux系统 1.1 磁盘组成与分区的复习 首先了解磁盘的物理组成,主要有: 圆形的碟片(主要记录数据的部分)。机械手臂,与在机械手臂上的磁头(可擦写碟片上的内容)。主轴马达,可以转动碟片,让机械手臂的磁头在碟片上读写数据。 数据存储…...

【Qt】Qt 构建系统详解:qmake 入门到项目实战

Qt 构建系统详解&#xff1a;qmake 入门到项目实战 本文将系统介绍 Qt 构建工具 qmake 的用法&#xff0c;并通过一个完整的项目结构示例&#xff0c;帮助你掌握 .pro 文件编写、子项目管理、模块依赖等核心技能。 &#x1f9ed; 一、什么是 qmake&#xff1f; qmake 是 Qt 提…...

Laravel 12 实现验证码功能

Laravel 12 实现验证码功能 在 Laravel 12 中实现验证码功能可以通过多种方式&#xff0c;以下是几种常见的方法&#xff1a; 方法一&#xff1a;使用 Captcha 包&#xff08;推荐&#xff09; 首先安装 mews/captcha 包&#xff1a; composer require mews/captcha发布配置…...

深入解析Http11AprProtocol:Tomcat高性能通信的底层原理

HTTP/1.1 协议作为 Web 通信的基础标准&#xff0c;其实现效率直接影响服务器性能。Apache Tomcat 作为 Java 生态中最流行的 Servlet 容器&#xff0c;提供了多种 HTTP 协议实现方案&#xff0c;其中基于 Apache Portable Runtime&#xff08;APR&#xff09;的 Http11AprProt…...

HTTP请求与缓存、页面渲染全流程

文章目录 前言**1. HTTP请求与缓存处理****缓存机制**• 强缓存&#xff08;Cache-Control / Expires&#xff09;• 协商缓存&#xff08;Last-Modified / ETag&#xff09; **2. 服务器响应与数据解析****3. HTML DOM 构建****4. CSSOM 构建****5. 渲染树&#xff08;Render …...

HTB - Eureka记录

HTB - Eurekahttps://mp.weixin.qq.com/s/r1WmZXNR6YkvnwP40liciA...

CentOS 7 基础环境安装脚本

&#x1f31f; CentOS 7 基础环境安装脚本使用文档 &#x1f9f0; 一键部署&#xff01;助你在 CentOS 7 系统上快速构建高效开发环境。 开源地址&#xff1a;https://github.com/hahaha-zsq/Shortcut-Script CentOS 7 基础环境安装脚本使用 &#x1f4e6; 项目结构一览 ./ ├…...

【Python 模块】

Python 中的模块&#xff08;Module&#xff09;是组织代码的核心方式&#xff0c;通过将相关函数、类和变量封装到独立文件中&#xff0c;实现代码复用和结构化管理。以下是模块的核心知识点&#xff1a; 一、基础概念 1. 模块定义 任何 .py 文件都是一个模块模块名即文件名…...

极狐Gitlab 如何创建并使用子群组?

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;关于中文参考文档和资料有&#xff1a; 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 子群组 (BASIC ALL) 您可以将极狐GitLab 群组组织成子群组。您可以使用子群组&#xff1a; 内部和外部组织分开。因为每个子…...

【MCP】服务端搭建(python和uv环境搭建、nodejs安装、pycharma安装)

【MCP】服务端搭建&#xff08;python和uv环境搭建、nodejs安装、pycharma安装&#xff09; 服务端搭建&#xff08;1&#xff09;python和uv环境搭建&#xff08;2&#xff09;nodejs安装&#xff08;3&#xff09;pycharm安装 服务端搭建 &#xff08;1&#xff09;python和…...

【疑难杂症2025-003】Java-mvn项目在gitlab-ci构建镜像时遇到的问题和解决方案

本文由Markdown语法编辑器编辑完成&#xff0e; 1.背景: 之前从同事手里接手了一个java的项目&#xff0c;是用maven构建项目的&#xff0e;由于我们的服务都是基于docker来部署的&#xff0c;因此这个java项目也是要编译成docker image然后发布&#xff0e;但是之前一直都是…...

AI与Web3.0:去中心化智能合约的未来

AI与Web3.0&#xff1a;去中心化智能合约的未来 系统化学习人工智能网站&#xff08;收藏&#xff09;&#xff1a;https://www.captainbed.cn/flu 文章目录 AI与Web3.0&#xff1a;去中心化智能合约的未来摘要引言1.1 技术演进背景1.2 行业格局分化 技术架构对比2.1 智能合约…...

记录学习的第三十五天

今天主攻单源最短路Dijkstra算法。不过&#xff0c;还是没有完全掌握。 首先是书本的例题我理解了一遍。 然后其实在力扣上做了三道题的&#xff0c;但是我看题解的情况就不太会。然后试着用上面的方法敲了一下↓的题&#xff0c;但是不对啊&#xff0c;我也不知道为什么呀。...

虚拟现实(VR)与增强现实(AR)在教育领域的应用:开启沉浸式学习新时代

前言 随着科技的飞速发展&#xff0c;虚拟现实&#xff08;VR&#xff09;和增强现实&#xff08;AR&#xff09;技术逐渐从游戏和娱乐领域走向教育领域。传统的教育模式主要依赖于书本、黑板和课堂讲解&#xff0c;这种模式虽然有效&#xff0c;但往往难以激发学生的学习兴趣和…...