1097 lines
33 KiB
Vue
1097 lines
33 KiB
Vue
|
|
<template>
|
|||
|
|
<div class="workshop-board">
|
|||
|
|
<div class="board-header">
|
|||
|
|
<div class="header-cell">
|
|||
|
|
<div class="header-label">看板编号</div>
|
|||
|
|
<div class="header-value">HY-CJKB-001</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="header-cell">
|
|||
|
|
<div class="header-label">管理责任人</div>
|
|||
|
|
<div class="header-value">张主管</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="header-cell">
|
|||
|
|
<div class="header-label">更新时间</div>
|
|||
|
|
<div class="header-value">{{ updateTime }}</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="board-body">
|
|||
|
|
<section class="board-main">
|
|||
|
|
<div class="board-stats">
|
|||
|
|
<div class="stats-title">设备列表</div>
|
|||
|
|
<div class="stats-item">设备总数: <span class="stats-value">{{ summary.total }}</span></div>
|
|||
|
|
<div class="stats-item">在线数量: <span class="stats-value">{{ summary.online }}</span></div>
|
|||
|
|
<div class="stats-item">运行数量: <span class="stats-value">{{ summary.running }}</span></div>
|
|||
|
|
<div class="stats-item">停止数量: <span class="stats-value">{{ summary.stop }}</span></div>
|
|||
|
|
<div class="stats-item">开机率: <span class="stats-value">{{ summary.startRate }}</span></div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="machine-grid">
|
|||
|
|
<article
|
|||
|
|
v-for="item in orderedMachineList"
|
|||
|
|
:key="item.id"
|
|||
|
|
class="machine-card"
|
|||
|
|
@click="openDetail(item)"
|
|||
|
|
>
|
|||
|
|
<span
|
|||
|
|
v-if="item.id === 5 || item.id === 6"
|
|||
|
|
class="fold-mark fold-mark--card"
|
|||
|
|
aria-hidden="true"
|
|||
|
|
/>
|
|||
|
|
<div class="machine-card__title">
|
|||
|
|
<span class="status-dot" :class="item.statusClass" />
|
|||
|
|
<span>({{ item.statusText }})</span>
|
|||
|
|
<span class="machine-no">{{ item.name }}</span>
|
|||
|
|
<span>{{ item.model }}</span>
|
|||
|
|
<span>{{ item.mode }}模式</span>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="machine-sections">
|
|||
|
|
<section class="machine-panel machine-panel--primary">
|
|||
|
|
<div class="machine-fields machine-fields--primary">
|
|||
|
|
<div class="machine-field machine-field--accent">
|
|||
|
|
<span class="machine-field__label">今日<br/>开机时间</span>
|
|||
|
|
<span class="machine-field__value">{{ item.runtime }}</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="machine-field machine-field--accent">
|
|||
|
|
<span class="machine-field__label">今日<br/>计件数</span>
|
|||
|
|
<span class="machine-field__value">{{ item.output }}</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="machine-field machine-field--accent">
|
|||
|
|
<span class="machine-field__label">任务<br/>进度</span>
|
|||
|
|
<span class="machine-field__value">{{ item.progress }}</span>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section class="machine-panel machine-panel--secondary">
|
|||
|
|
<div class="machine-fields machine-fields--secondary">
|
|||
|
|
<div class="machine-field">
|
|||
|
|
<span class="machine-field__label">工单日期</span>
|
|||
|
|
<span class="machine-field__value">{{ item.workDate }}</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="machine-field">
|
|||
|
|
<span class="machine-field__label">批次号</span>
|
|||
|
|
<span class="machine-field__value">{{ item.batchNo }}</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="machine-field">
|
|||
|
|
<span class="machine-field__label">计划产量</span>
|
|||
|
|
<span class="machine-field__value">{{ item.planQty }}</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="machine-field">
|
|||
|
|
<span class="machine-field__label">型号</span>
|
|||
|
|
<span class="machine-field__value">{{ item.productModel }}</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="machine-field">
|
|||
|
|
<span class="machine-field__label">颜色</span>
|
|||
|
|
<span class="machine-field__value">{{ item.color }}</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="machine-field">
|
|||
|
|
<span class="machine-field__label">备注</span>
|
|||
|
|
<span class="machine-field__value">{{ item.remark }}</span>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
</div>
|
|||
|
|
</article>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<aside class="board-side">
|
|||
|
|
<section class="side-panel fault-panel">
|
|||
|
|
<span class="fold-mark fold-mark--panel" aria-hidden="true" />
|
|||
|
|
<div class="side-panel__title">今日故障记录:</div>
|
|||
|
|
<table class="side-table">
|
|||
|
|
<colgroup>
|
|||
|
|
<col style="width: 16%">
|
|||
|
|
<col style="width: 17%">
|
|||
|
|
<col style="width: 27%">
|
|||
|
|
<col style="width: 14%">
|
|||
|
|
<col style="width: 26%">
|
|||
|
|
</colgroup>
|
|||
|
|
<thead>
|
|||
|
|
<tr>
|
|||
|
|
<th>设备<br/>编号</th>
|
|||
|
|
<th>故障<br/>时间</th>
|
|||
|
|
<th>故障<br/>描述</th>
|
|||
|
|
<th>责任<br/>人</th>
|
|||
|
|
<th>预计<br/>恢复时间</th>
|
|||
|
|
</tr>
|
|||
|
|
</thead>
|
|||
|
|
<tbody>
|
|||
|
|
<tr v-for="item in faultList" :key="item.deviceNo + item.faultTime">
|
|||
|
|
<td>{{ item.deviceNo }}</td>
|
|||
|
|
<td>{{ item.faultTime }}</td>
|
|||
|
|
<td>{{ item.faultDesc }}</td>
|
|||
|
|
<td>{{ item.owner }}</td>
|
|||
|
|
<td>{{ item.recoverTime }}</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr v-for="index in Math.max(0, faultTableRows - faultList.length)" :key="'fault-empty-' + index" class="is-empty">
|
|||
|
|
<td> </td>
|
|||
|
|
<td />
|
|||
|
|
<td />
|
|||
|
|
<td />
|
|||
|
|
<td />
|
|||
|
|
</tr>
|
|||
|
|
</tbody>
|
|||
|
|
</table>
|
|||
|
|
<div class="side-panel__time">更新时间: {{ updateTime }}</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section class="side-panel plan-panel">
|
|||
|
|
<span class="fold-mark fold-mark--panel" aria-hidden="true" />
|
|||
|
|
<div class="side-panel__title">设备维护计划:</div>
|
|||
|
|
<table class="side-table">
|
|||
|
|
<colgroup>
|
|||
|
|
<col style="width: 18%">
|
|||
|
|
<col style="width: 30%">
|
|||
|
|
<col style="width: 32%">
|
|||
|
|
<col style="width: 20%">
|
|||
|
|
</colgroup>
|
|||
|
|
<thead>
|
|||
|
|
<tr>
|
|||
|
|
<th>设备<br/>编号</th>
|
|||
|
|
<th>维护<br/>项目</th>
|
|||
|
|
<th>计划<br/>时间</th>
|
|||
|
|
<th>维护<br/>状态</th>
|
|||
|
|
</tr>
|
|||
|
|
</thead>
|
|||
|
|
<tbody>
|
|||
|
|
<tr v-for="item in maintenanceList" :key="item.deviceNo + item.planTime">
|
|||
|
|
<td>{{ item.deviceNo }}</td>
|
|||
|
|
<td>{{ item.project }}</td>
|
|||
|
|
<td>{{ item.planTime }}</td>
|
|||
|
|
<td>{{ item.status }}</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr v-for="index in Math.max(0, planTableRows - maintenanceList.length)" :key="'plan-empty-' + index" class="is-empty">
|
|||
|
|
<td> </td>
|
|||
|
|
<td />
|
|||
|
|
<td />
|
|||
|
|
<td />
|
|||
|
|
</tr>
|
|||
|
|
</tbody>
|
|||
|
|
</table>
|
|||
|
|
<div class="side-panel__time">更新时间: {{ updateTime }}</div>
|
|||
|
|
</section>
|
|||
|
|
</aside>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<el-dialog
|
|||
|
|
:visible.sync="detailVisible"
|
|||
|
|
width="88%"
|
|||
|
|
top="4vh"
|
|||
|
|
custom-class="board-dialog"
|
|||
|
|
:append-to-body="true"
|
|||
|
|
>
|
|||
|
|
<template slot="title">
|
|||
|
|
<div class="dialog-title">
|
|||
|
|
<span>{{ activeMachine.name }} 详细信息</span>
|
|||
|
|
<span class="dialog-subtitle">实时数据 / 设定参数 / 生产参数</span>
|
|||
|
|
</div>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<div class="dialog-body">
|
|||
|
|
<section class="dialog-section">
|
|||
|
|
<div class="section-head">
|
|||
|
|
<span>实时数据(定时发送)</span>
|
|||
|
|
<span>更新时间:{{ updateTime }}</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="detail-table-wrap">
|
|||
|
|
<table class="detail-table">
|
|||
|
|
<thead>
|
|||
|
|
<tr>
|
|||
|
|
<th>点位名称</th>
|
|||
|
|
<th>实时数据</th>
|
|||
|
|
<th>更新时间</th>
|
|||
|
|
<th>设定值</th>
|
|||
|
|
<th>设定时间</th>
|
|||
|
|
<th>工单给定值</th>
|
|||
|
|
<th>工单时间</th>
|
|||
|
|
<th>历史曲线</th>
|
|||
|
|
</tr>
|
|||
|
|
</thead>
|
|||
|
|
<tbody>
|
|||
|
|
<tr v-for="item in detailRealtime" :key="item.name">
|
|||
|
|
<td>{{ item.name }}</td>
|
|||
|
|
<td>{{ item.current }}</td>
|
|||
|
|
<td>{{ item.currentTime }}</td>
|
|||
|
|
<td>{{ item.target }}</td>
|
|||
|
|
<td>{{ item.targetTime }}</td>
|
|||
|
|
<td>{{ item.orderValue }}</td>
|
|||
|
|
<td>{{ item.orderTime }}</td>
|
|||
|
|
<td><span class="curve-tag">一图三曲线</span></td>
|
|||
|
|
</tr>
|
|||
|
|
</tbody>
|
|||
|
|
</table>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section class="dialog-grid">
|
|||
|
|
<div class="dialog-section">
|
|||
|
|
<div class="section-head">
|
|||
|
|
<span>全部设定参数(变化上报)</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="detail-table-wrap small">
|
|||
|
|
<table class="detail-table">
|
|||
|
|
<thead>
|
|||
|
|
<tr>
|
|||
|
|
<th>点位名称</th>
|
|||
|
|
<th>设定数据</th>
|
|||
|
|
<th>设定时间</th>
|
|||
|
|
<th>工单给定值</th>
|
|||
|
|
<th>工单时间</th>
|
|||
|
|
<th>历史曲线</th>
|
|||
|
|
</tr>
|
|||
|
|
</thead>
|
|||
|
|
<tbody>
|
|||
|
|
<tr v-for="item in detailSetting" :key="item.name">
|
|||
|
|
<td>{{ item.name }}</td>
|
|||
|
|
<td>{{ item.setting }}</td>
|
|||
|
|
<td>{{ item.settingTime }}</td>
|
|||
|
|
<td>{{ item.orderValue }}</td>
|
|||
|
|
<td>{{ item.orderTime }}</td>
|
|||
|
|
<td><span class="curve-tag">趋势</span></td>
|
|||
|
|
</tr>
|
|||
|
|
</tbody>
|
|||
|
|
</table>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="dialog-section">
|
|||
|
|
<div class="section-head">
|
|||
|
|
<span>生产参数(一模一次)</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="detail-table-wrap small">
|
|||
|
|
<table class="detail-table">
|
|||
|
|
<thead>
|
|||
|
|
<tr>
|
|||
|
|
<th>点位名称</th>
|
|||
|
|
<th>数据值</th>
|
|||
|
|
<th>采集时间</th>
|
|||
|
|
<th>历史曲线</th>
|
|||
|
|
</tr>
|
|||
|
|
</thead>
|
|||
|
|
<tbody>
|
|||
|
|
<tr v-for="item in detailProduction" :key="item.name">
|
|||
|
|
<td>{{ item.name }}</td>
|
|||
|
|
<td>{{ item.value }}</td>
|
|||
|
|
<td>{{ item.collectTime }}</td>
|
|||
|
|
<td><span class="curve-tag">趋势</span></td>
|
|||
|
|
</tr>
|
|||
|
|
</tbody>
|
|||
|
|
</table>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
</div>
|
|||
|
|
</el-dialog>
|
|||
|
|
</div>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
function createMachine(id, name, model, statusText, statusClass, mode, runtime, output, workDate, batchNo, planQty, progress, productModel, color, remark, nextModel) {
|
|||
|
|
return {
|
|||
|
|
id,
|
|||
|
|
name,
|
|||
|
|
model,
|
|||
|
|
statusText,
|
|||
|
|
statusClass,
|
|||
|
|
mode,
|
|||
|
|
runtime,
|
|||
|
|
output,
|
|||
|
|
workDate,
|
|||
|
|
batchNo,
|
|||
|
|
planQty,
|
|||
|
|
progress,
|
|||
|
|
productModel,
|
|||
|
|
color,
|
|||
|
|
remark,
|
|||
|
|
nextModel
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export default {
|
|||
|
|
name: 'WorkshopBoard',
|
|||
|
|
computed: {
|
|||
|
|
orderedMachineList() {
|
|||
|
|
return [...this.machineList].sort((a, b) => a.id - b.id)
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
data() {
|
|||
|
|
return {
|
|||
|
|
detailVisible: false,
|
|||
|
|
updateTime: '',
|
|||
|
|
clockTimer: null,
|
|||
|
|
previousTitle: '',
|
|||
|
|
activeMachine: {},
|
|||
|
|
faultTableRows: 8,
|
|||
|
|
planTableRows: 8,
|
|||
|
|
summary: {
|
|||
|
|
total: 17,
|
|||
|
|
online: 15,
|
|||
|
|
running: 15,
|
|||
|
|
stop: 2,
|
|||
|
|
startRate: '88.2%'
|
|||
|
|
},
|
|||
|
|
faultList: [
|
|||
|
|
{ deviceNo: '8#', faultTime: '09:25', faultDesc: '模温异常', owner: '李工', recoverTime: '10:10' },
|
|||
|
|
{ deviceNo: '16#', faultTime: '11:40', faultDesc: '液压压力波动', owner: '王工', recoverTime: '13:00' },
|
|||
|
|
{ deviceNo: '5#', faultTime: '13:18', faultDesc: '送料传感器告警', owner: '赵工', recoverTime: '13:45' }
|
|||
|
|
],
|
|||
|
|
maintenanceList: [
|
|||
|
|
{ deviceNo: '2#', project: '保养润滑系统', planTime: '2026-03-23 16:00', status: '待执行' },
|
|||
|
|
{ deviceNo: '11#', project: '校验温控模块', planTime: '2026-03-23 18:00', status: '待执行' },
|
|||
|
|
{ deviceNo: '14#', project: '更换过滤组件', planTime: '2026-03-24 09:00', status: '已排期' }
|
|||
|
|
],
|
|||
|
|
machineList: [
|
|||
|
|
createMachine(6, '6#', 'MA2500/1000G', '状态', 'is-running', '运行', '13小时', '600个', '2026.3.16-3.18', '25110914', '5000个', '30%', '23W 中间盖', '7037C 灰', '重点订单', '159BB'),
|
|||
|
|
createMachine(12, '12#', 'MA1600/540G', '状态', 'is-running', '运行', '8小时', '305个', '2026.3.23-3.25', '25110953', '2800个', '27%', '中盖件', '灰色', '正常生产', 'J20R'),
|
|||
|
|
createMachine(5, '5#', 'MA2500 2S/1000', '状态', 'is-running', '运行', '6小时', '210个', '2026.3.22-3.24', '25110937', '3600个', '19%', '卡扣件', '7035 灰', '待维修', '32QR'),
|
|||
|
|
createMachine(11, '11#', 'MA3600/2250G', '状态', 'is-running', '运行', '15小时', '720个', '2026.3.23-3.25', '25110950', '6500个', '33%', '大型壳体', '深蓝', '计划保养', 'LT9X'),
|
|||
|
|
createMachine(17, '17#', 'MA1600/540G', '状态', 'is-running', '运行', '12小时', '510个', '2026.3.23-3.25', '25110961', '3600个', '53%', '面框件', '冷白', '正常生产', 'AA17'),
|
|||
|
|
createMachine(4, '4#', 'MA2500/1000G', '状态', 'is-running', '运行', '10小时', '488个', '2026.3.21-3.22', '25110931', '4500个', '61%', '28W 外壳', '米白', '正常生产', '26WA'),
|
|||
|
|
createMachine(10, '10#', 'MA2500/1000G', '状态', 'is-running', '运行', '13小时', '610个', '2026.3.23-3.24', '25110946', '5100个', '44%', '挡板件', '黑色', '正常生产', 'M22A'),
|
|||
|
|
createMachine(16, '16#', '570', '状态', 'is-running', '运行', '5小时', '190个', '2026.3.23-3.25', '25110959', '2400个', '18%', '小型卡件', '浅灰', '液压检修', 'Q30E'),
|
|||
|
|
createMachine(3, '3#', 'MA2500/1000G', '状态', 'is-running', '运行', '8小时', '360个', '2026.3.20-3.22', '25110925', '3000个', '58%', '17W 支架', '银色', '等待换模', '90KT'),
|
|||
|
|
createMachine(9, '9#', 'MA2500/1000G', '状态', 'is-running', '运行', '14小时', '680个', '2026.3.23-3.24', '25110945', '5400个', '52%', '导流板', '银灰', '正常生产', 'C88L'),
|
|||
|
|
createMachine(15, '15#', 'MA1600/540G', '状态', 'is-running', '运行', '11小时', '460个', '2026.3.23-3.25', '25110957', '3500个', '41%', '转接件', '深灰', '正常生产', 'UV06'),
|
|||
|
|
createMachine(2, '2#', 'MA2500/1000G', '状态', 'is-running', '运行', '11小时', '520个', '2026.3.18-3.20', '25110918', '4200个', '42%', '26W 面板', '黑色', '夜班优先', '188AX'),
|
|||
|
|
createMachine(8, '8#', 'MA2500/1000G', '状态', 'is-running', '运行', '9小时', '430个', '2026.3.22-3.24', '25110941', '4600个', '36%', '封边件', '白色', '温控波动', 'B71S'),
|
|||
|
|
createMachine(14, '14#', 'MA1600/540G', '状态', 'is-running', '运行', '10小时', '395个', '2026.3.23-3.25', '25110955', '3200个', '38%', '扣合件', '亮黑', '正常生产', 'R81N'),
|
|||
|
|
createMachine(1, '1#', 'MA2500/1000G', '状态', 'is-running', '运行', '13小时', '600个', '2026.3.16-3.18', '25110914', '5000个', '30%', '23W 中间盖', '7037C 灰', '重点订单', '159BB'),
|
|||
|
|
createMachine(7, '7#', 'MA2500/1000G', '状态', 'is-running', '运行', '4小时', '120个', '2026.3.22-3.24', '25110940', '3000个', '12%', '结构件', '深灰', '人工调试', 'X09M'),
|
|||
|
|
createMachine(13, '13#', 'MA1600/540G', '状态', 'is-running', '运行', '7小时', '280个', '2026.3.23-3.25', '25110954', '2600个', '31%', '面罩件', '暖白', '待料', 'PK11')
|
|||
|
|
],
|
|||
|
|
detailRealtime: [
|
|||
|
|
{ name: '温度一段(A15)', current: '186℃', currentTime: '14:20:15', target: '185℃', targetTime: '14:05:00', orderValue: '188℃', orderTime: '08:30:00' },
|
|||
|
|
{ name: '温度二段(A16)', current: '192℃', currentTime: '14:20:15', target: '190℃', targetTime: '14:05:00', orderValue: '192℃', orderTime: '08:30:00' },
|
|||
|
|
{ name: '射胶压力(A243)', current: '12.3MPa', currentTime: '14:20:10', target: '12.0MPa', targetTime: '14:00:00', orderValue: '12.5MPa', orderTime: '08:30:00' }
|
|||
|
|
],
|
|||
|
|
detailSetting: [
|
|||
|
|
{ name: '开模行程(A060)', setting: '320mm', settingTime: '13:15:00', orderValue: '325mm', orderTime: '08:30:00' },
|
|||
|
|
{ name: '锁模压力(A061)', setting: '86%', settingTime: '13:15:00', orderValue: '85%', orderTime: '08:30:00' },
|
|||
|
|
{ name: '保压时间(A062)', setting: '4.5s', settingTime: '13:15:00', orderValue: '4.8s', orderTime: '08:30:00' }
|
|||
|
|
],
|
|||
|
|
detailProduction: [
|
|||
|
|
{ name: '上模循环时(A37)', value: '28.6s', collectTime: '14:20:11' },
|
|||
|
|
{ name: '一模产出数', value: '2', collectTime: '14:20:11' },
|
|||
|
|
{ name: '累计良品数', value: '598', collectTime: '14:20:11' }
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
created() {
|
|||
|
|
this.refreshClock()
|
|||
|
|
this.clockTimer = setInterval(this.refreshClock, 1000)
|
|||
|
|
this.activeMachine = this.machineList[0]
|
|||
|
|
},
|
|||
|
|
mounted() {
|
|||
|
|
this.applyDisplayTitle()
|
|||
|
|
this.tryEnterFullscreen()
|
|||
|
|
},
|
|||
|
|
beforeDestroy() {
|
|||
|
|
if (this.clockTimer) {
|
|||
|
|
clearInterval(this.clockTimer)
|
|||
|
|
this.clockTimer = null
|
|||
|
|
}
|
|||
|
|
this.restoreTitle()
|
|||
|
|
},
|
|||
|
|
methods: {
|
|||
|
|
applyDisplayTitle() {
|
|||
|
|
const mode = this.$route && this.$route.query ? this.$route.query.displayMode : ''
|
|||
|
|
if (mode !== 'fullscreen') {
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
this.previousTitle = document.title
|
|||
|
|
document.title = ''
|
|||
|
|
},
|
|||
|
|
restoreTitle() {
|
|||
|
|
if (this.previousTitle !== '') {
|
|||
|
|
document.title = this.previousTitle
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
async tryEnterFullscreen() {
|
|||
|
|
const mode = this.$route && this.$route.query ? this.$route.query.displayMode : ''
|
|||
|
|
if (mode !== 'fullscreen') {
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const element = document.documentElement
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
if (element.requestFullscreen) {
|
|||
|
|
await element.requestFullscreen()
|
|||
|
|
} else if (element.webkitRequestFullscreen) {
|
|||
|
|
await element.webkitRequestFullscreen()
|
|||
|
|
} else if (element.msRequestFullscreen) {
|
|||
|
|
await element.msRequestFullscreen()
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
// 全屏能力受浏览器安全策略限制,失败时保留铺满窗口的展示模式。
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (window.outerWidth < window.screen.availWidth || window.outerHeight < window.screen.availHeight) {
|
|||
|
|
try {
|
|||
|
|
window.moveTo(0, 0)
|
|||
|
|
window.resizeTo(window.screen.availWidth, window.screen.availHeight)
|
|||
|
|
} catch (error) {
|
|||
|
|
// 某些浏览器会阻止脚本调整窗口尺寸,忽略即可。
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
refreshClock() {
|
|||
|
|
const now = new Date()
|
|||
|
|
const year = now.getFullYear()
|
|||
|
|
const month = String(now.getMonth() + 1).padStart(2, '0')
|
|||
|
|
const date = String(now.getDate()).padStart(2, '0')
|
|||
|
|
const hours = String(now.getHours()).padStart(2, '0')
|
|||
|
|
const minutes = String(now.getMinutes()).padStart(2, '0')
|
|||
|
|
const seconds = String(now.getSeconds()).padStart(2, '0')
|
|||
|
|
this.updateTime = `${year}-${month}-${date} ${hours}:${minutes}:${seconds}`
|
|||
|
|
},
|
|||
|
|
openDetail(machine) {
|
|||
|
|
this.activeMachine = machine
|
|||
|
|
this.detailVisible = true
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style lang="scss" scoped>
|
|||
|
|
.workshop-board {
|
|||
|
|
position: relative;
|
|||
|
|
min-height: 100vh;
|
|||
|
|
height: 100vh;
|
|||
|
|
padding: 8px;
|
|||
|
|
background:
|
|||
|
|
radial-gradient(circle at top left, rgba(60, 160, 255, 0.12), transparent 22%),
|
|||
|
|
radial-gradient(circle at top right, rgba(0, 214, 170, 0.07), transparent 18%),
|
|||
|
|
linear-gradient(180deg, #050a12 0%, #0a111a 48%, #060d15 100%);
|
|||
|
|
color: #e8edf5;
|
|||
|
|
overflow: hidden;
|
|||
|
|
font-family: "Microsoft YaHei", "PingFang SC", sans-serif;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.workshop-board::before {
|
|||
|
|
content: '';
|
|||
|
|
position: absolute;
|
|||
|
|
top: 0;
|
|||
|
|
left: -30%;
|
|||
|
|
width: 30%;
|
|||
|
|
height: 2px;
|
|||
|
|
background: linear-gradient(90deg, transparent, rgba(111, 223, 255, 0.9), transparent);
|
|||
|
|
box-shadow: 0 0 12px rgba(83, 207, 255, 0.45);
|
|||
|
|
animation: topScanner 7s linear infinite;
|
|||
|
|
pointer-events: none;
|
|||
|
|
z-index: 3;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.board-header {
|
|||
|
|
position: relative;
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: repeat(3, 1fr);
|
|||
|
|
border: 1px solid #2d6e97;
|
|||
|
|
background:
|
|||
|
|
linear-gradient(180deg, rgba(11, 24, 38, 0.97), rgba(8, 18, 30, 0.98)),
|
|||
|
|
linear-gradient(90deg, rgba(91, 217, 255, 0.06), transparent 36%, rgba(41, 99, 181, 0.06));
|
|||
|
|
box-shadow:
|
|||
|
|
inset 0 0 0 1px rgba(124, 208, 255, 0.06),
|
|||
|
|
0 0 18px rgba(37, 125, 191, 0.18);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.board-header::after {
|
|||
|
|
content: '';
|
|||
|
|
position: absolute;
|
|||
|
|
inset: 0;
|
|||
|
|
background: linear-gradient(90deg, transparent, rgba(92, 208, 255, 0.08), transparent);
|
|||
|
|
pointer-events: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.fold-mark {
|
|||
|
|
position: absolute;
|
|||
|
|
pointer-events: none;
|
|||
|
|
z-index: 4;
|
|||
|
|
opacity: 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.fold-mark::before,
|
|||
|
|
.fold-mark::after {
|
|||
|
|
content: '';
|
|||
|
|
position: absolute;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.header-cell {
|
|||
|
|
min-height: 42px;
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: row;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
gap: 10px;
|
|||
|
|
padding: 0 10px;
|
|||
|
|
white-space: nowrap;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.header-label {
|
|||
|
|
flex: 0 0 auto;
|
|||
|
|
font-size: 14px;
|
|||
|
|
font-weight: 700;
|
|||
|
|
color: #dff6ff;
|
|||
|
|
text-shadow: 0 0 10px rgba(84, 194, 255, 0.18);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.header-value {
|
|||
|
|
min-width: 0;
|
|||
|
|
font-size: 13px;
|
|||
|
|
color: #7fd4ff;
|
|||
|
|
font-family: "DIN Alternate", "Bahnschrift", "Consolas", monospace;
|
|||
|
|
letter-spacing: 1px;
|
|||
|
|
text-shadow: 0 0 10px rgba(76, 196, 255, 0.22);
|
|||
|
|
overflow: hidden;
|
|||
|
|
text-overflow: ellipsis;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.board-body {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: minmax(0, 1fr) 360px;
|
|||
|
|
gap: 0;
|
|||
|
|
height: calc(100vh - 58px);
|
|||
|
|
margin-top: 6px;
|
|||
|
|
background: linear-gradient(180deg, rgba(6, 13, 22, 0.99), rgba(4, 10, 17, 0.99));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.board-main {
|
|||
|
|
position: relative;
|
|||
|
|
border: 0;
|
|||
|
|
padding: 0 6px 6px;
|
|||
|
|
overflow: hidden;
|
|||
|
|
background:
|
|||
|
|
linear-gradient(180deg, rgba(8, 16, 26, 0.97), rgba(6, 13, 22, 0.98)),
|
|||
|
|
linear-gradient(90deg, rgba(70, 183, 255, 0.03) 1px, transparent 1px),
|
|||
|
|
linear-gradient(rgba(70, 183, 255, 0.03) 1px, transparent 1px);
|
|||
|
|
background-size: auto, 22px 22px, 22px 22px;
|
|||
|
|
box-shadow: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.board-main::before {
|
|||
|
|
content: '';
|
|||
|
|
position: absolute;
|
|||
|
|
top: 0;
|
|||
|
|
left: 0;
|
|||
|
|
right: 0;
|
|||
|
|
height: 1px;
|
|||
|
|
background: linear-gradient(90deg, transparent, rgba(82, 208, 255, 0.5), transparent);
|
|||
|
|
pointer-events: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.board-stats {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: 1.4fr repeat(5, 1fr);
|
|||
|
|
align-items: center;
|
|||
|
|
min-height: 34px;
|
|||
|
|
font-size: 15px;
|
|||
|
|
font-weight: 700;
|
|||
|
|
column-gap: 12px;
|
|||
|
|
color: #d8f1ff;
|
|||
|
|
text-shadow: 0 0 10px rgba(56, 150, 255, 0.12);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.stats-title,
|
|||
|
|
.stats-item {
|
|||
|
|
white-space: nowrap;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.stats-value {
|
|||
|
|
display: inline-block;
|
|||
|
|
min-width: 28px;
|
|||
|
|
margin-left: 2px;
|
|||
|
|
padding: 0 4px;
|
|||
|
|
border: 1px solid rgba(85, 191, 255, 0.28);
|
|||
|
|
border-radius: 2px;
|
|||
|
|
background: linear-gradient(180deg, rgba(20, 69, 107, 0.55), rgba(10, 35, 58, 0.5));
|
|||
|
|
color: #8ee5ff;
|
|||
|
|
font-family: "DIN Alternate", "Bahnschrift", "Consolas", monospace;
|
|||
|
|
letter-spacing: 1px;
|
|||
|
|
text-shadow: 0 0 8px rgba(91, 218, 255, 0.28);
|
|||
|
|
box-shadow: inset 0 0 8px rgba(70, 173, 255, 0.08);
|
|||
|
|
text-align: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-grid {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: repeat(6, minmax(0, 1fr));
|
|||
|
|
gap: 6px 8px;
|
|||
|
|
align-content: start;
|
|||
|
|
height: calc(100% - 36px);
|
|||
|
|
overflow: auto;
|
|||
|
|
padding-right: 2px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-card {
|
|||
|
|
position: relative;
|
|||
|
|
border: 1px solid rgba(117, 205, 255, 0.42);
|
|||
|
|
border-radius: 16px;
|
|||
|
|
background:
|
|||
|
|
linear-gradient(180deg, rgba(12, 37, 59, 0.98), rgba(6, 17, 30, 0.99)),
|
|||
|
|
linear-gradient(135deg, rgba(121, 220, 255, 0.05), transparent 55%);
|
|||
|
|
padding: 8px 8px 10px;
|
|||
|
|
cursor: pointer;
|
|||
|
|
box-shadow:
|
|||
|
|
inset 0 1px 0 rgba(204, 240, 255, 0.08),
|
|||
|
|
0 10px 24px rgba(5, 17, 30, 0.28),
|
|||
|
|
0 0 0 1px rgba(67, 150, 201, 0.14);
|
|||
|
|
overflow: hidden;
|
|||
|
|
transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-card::before {
|
|||
|
|
content: '';
|
|||
|
|
position: absolute;
|
|||
|
|
inset: 0;
|
|||
|
|
background: linear-gradient(180deg, rgba(154, 232, 255, 0.12), transparent 34%);
|
|||
|
|
pointer-events: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-card::after {
|
|||
|
|
content: '';
|
|||
|
|
position: absolute;
|
|||
|
|
inset: 1px;
|
|||
|
|
border-radius: 15px;
|
|||
|
|
border: 1px solid rgba(135, 219, 255, 0.1);
|
|||
|
|
pointer-events: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.fold-mark--card {
|
|||
|
|
right: 1px;
|
|||
|
|
bottom: 1px;
|
|||
|
|
width: 66px;
|
|||
|
|
height: 48px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.fold-mark--card::before {
|
|||
|
|
right: 0;
|
|||
|
|
bottom: 0;
|
|||
|
|
width: 0;
|
|||
|
|
height: 0;
|
|||
|
|
border-bottom: 22px solid rgba(216, 0, 11, 0.52);
|
|||
|
|
border-left: 22px solid transparent;
|
|||
|
|
border-bottom-right-radius: 14px;
|
|||
|
|
filter: drop-shadow(0 0 12px rgba(216, 0, 11, 0.62));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.fold-mark--card::after {
|
|||
|
|
display: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-card:hover {
|
|||
|
|
box-shadow:
|
|||
|
|
inset 0 1px 0 rgba(204, 240, 255, 0.1),
|
|||
|
|
0 16px 28px rgba(5, 17, 30, 0.34),
|
|||
|
|
0 0 0 1px rgba(93, 190, 244, 0.22);
|
|||
|
|
border-color: rgba(131, 216, 255, 0.58);
|
|||
|
|
transform: translateY(-2px);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-card__title {
|
|||
|
|
position: relative;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 4px;
|
|||
|
|
min-height: 24px;
|
|||
|
|
font-size: 12px;
|
|||
|
|
font-weight: 700;
|
|||
|
|
white-space: nowrap;
|
|||
|
|
overflow: hidden;
|
|||
|
|
color: #dff7ff;
|
|||
|
|
text-shadow: 0 0 6px rgba(102, 215, 255, 0.12);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-no {
|
|||
|
|
margin-left: 2px;
|
|||
|
|
color: #8ce9ff;
|
|||
|
|
font-size: 14px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-sections {
|
|||
|
|
display: grid;
|
|||
|
|
gap: 6px;
|
|||
|
|
margin-top: 6px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-panel {
|
|||
|
|
position: relative;
|
|||
|
|
padding: 0;
|
|||
|
|
border-radius: 0;
|
|||
|
|
border: 0;
|
|||
|
|
background: transparent;
|
|||
|
|
box-shadow: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-panel--primary {
|
|||
|
|
background: transparent;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-fields {
|
|||
|
|
display: grid;
|
|||
|
|
gap: 5px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-fields--primary {
|
|||
|
|
grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr) minmax(0, 0.82fr);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-fields--secondary {
|
|||
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-field {
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
align-items: flex-start;
|
|||
|
|
justify-content: center;
|
|||
|
|
gap: 3px;
|
|||
|
|
min-height: 38px;
|
|||
|
|
padding: 5px 7px;
|
|||
|
|
border: 1px solid rgba(104, 159, 193, 0.52);
|
|||
|
|
border-radius: 8px;
|
|||
|
|
background: linear-gradient(180deg, rgba(6, 22, 35, 0.86), rgba(4, 15, 26, 0.92));
|
|||
|
|
font-size: 10px;
|
|||
|
|
line-height: 1.2;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-field__label {
|
|||
|
|
width: 100%;
|
|||
|
|
color: #89c8ec;
|
|||
|
|
font-size: 9px;
|
|||
|
|
line-height: 1.15;
|
|||
|
|
white-space: nowrap;
|
|||
|
|
overflow: hidden;
|
|||
|
|
text-overflow: ellipsis;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-field__value {
|
|||
|
|
width: 100%;
|
|||
|
|
min-width: 0;
|
|||
|
|
color: #f4fbff;
|
|||
|
|
font-size: 12px;
|
|||
|
|
font-weight: 700;
|
|||
|
|
font-family: "DIN Alternate", "Bahnschrift", "Consolas", monospace;
|
|||
|
|
white-space: nowrap;
|
|||
|
|
overflow: hidden;
|
|||
|
|
text-overflow: ellipsis;
|
|||
|
|
text-shadow: 0 0 10px rgba(128, 225, 255, 0.16);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-field--accent {
|
|||
|
|
border-color: rgba(84, 220, 255, 0.5);
|
|||
|
|
background: linear-gradient(180deg, rgba(12, 78, 102, 0.68), rgba(5, 35, 54, 0.94));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-field--accent .machine-field__label {
|
|||
|
|
color: #b8f2ff;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-field--accent .machine-field__value {
|
|||
|
|
color: #fff3a6;
|
|||
|
|
font-size: 13px;
|
|||
|
|
text-shadow: 0 0 12px rgba(255, 218, 109, 0.22);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.status-dot {
|
|||
|
|
width: 10px;
|
|||
|
|
height: 10px;
|
|||
|
|
flex: 0 0 10px;
|
|||
|
|
border-radius: 50%;
|
|||
|
|
border: 1px solid #52d88d;
|
|||
|
|
background: radial-gradient(circle at 35% 35%, #7df3a6, #1fb36e 70%);
|
|||
|
|
box-shadow: 0 0 6px rgba(63, 228, 132, 0.45);
|
|||
|
|
animation: statusPulseGreen 2.4s ease-in-out infinite;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.status-dot.is-stop {
|
|||
|
|
background: radial-gradient(circle at 35% 35%, #ffe18d, #d0a33d 72%);
|
|||
|
|
border-color: #e6bf66;
|
|||
|
|
box-shadow: 0 0 6px rgba(240, 191, 83, 0.35);
|
|||
|
|
animation-name: statusPulseYellow;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.status-dot.is-standby {
|
|||
|
|
background: radial-gradient(circle at 35% 35%, #8fd2ff, #3b86da 72%);
|
|||
|
|
border-color: #7db4f0;
|
|||
|
|
box-shadow: 0 0 6px rgba(90, 176, 255, 0.35);
|
|||
|
|
animation-name: statusPulseBlue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.status-dot.is-fault {
|
|||
|
|
background: radial-gradient(circle at 35% 35%, #ff9f9f, #ce5b5b 72%);
|
|||
|
|
border-color: #e48c8c;
|
|||
|
|
box-shadow: 0 0 6px rgba(232, 106, 106, 0.35);
|
|||
|
|
animation-name: statusPulseRed;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.status-dot.is-offline {
|
|||
|
|
background: radial-gradient(circle at 35% 35%, #b9c1cc, #74808e 72%);
|
|||
|
|
border-color: #aab2bd;
|
|||
|
|
box-shadow: 0 0 5px rgba(149, 160, 175, 0.25);
|
|||
|
|
animation-name: statusPulseGray;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.side-table,
|
|||
|
|
.detail-table {
|
|||
|
|
width: 100%;
|
|||
|
|
border-collapse: collapse;
|
|||
|
|
table-layout: fixed;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.side-table th,
|
|||
|
|
.side-table td,
|
|||
|
|
.detail-table th,
|
|||
|
|
.detail-table td {
|
|||
|
|
border: 1px solid rgba(104, 159, 193, 0.8);
|
|||
|
|
padding: 1px 4px;
|
|||
|
|
line-height: 1.08;
|
|||
|
|
word-break: break-all;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.board-side {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-rows: 1fr 1fr;
|
|||
|
|
gap: 10px;
|
|||
|
|
padding-left: 10px;
|
|||
|
|
background: linear-gradient(180deg, rgba(6, 13, 22, 0.99), rgba(4, 10, 17, 0.99));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.side-panel {
|
|||
|
|
position: relative;
|
|||
|
|
padding: 8px 8px 6px;
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-rows: auto auto 1fr auto;
|
|||
|
|
background:
|
|||
|
|
linear-gradient(180deg, rgba(10, 21, 34, 0.97), rgba(7, 15, 25, 0.98)),
|
|||
|
|
linear-gradient(90deg, rgba(104, 211, 255, 0.025) 1px, transparent 1px),
|
|||
|
|
linear-gradient(rgba(104, 211, 255, 0.02) 1px, transparent 1px);
|
|||
|
|
background-size: auto, 18px 18px, 18px 18px;
|
|||
|
|
border: 0;
|
|||
|
|
box-shadow: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.fold-mark--panel {
|
|||
|
|
right: 4px;
|
|||
|
|
bottom: 2px;
|
|||
|
|
width: 84px;
|
|||
|
|
height: 62px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.fold-mark--panel::before {
|
|||
|
|
right: 0;
|
|||
|
|
bottom: 0;
|
|||
|
|
width: 0;
|
|||
|
|
height: 0;
|
|||
|
|
border-bottom: 32px solid rgba(216, 0, 11, 0.44);
|
|||
|
|
border-left: 32px solid transparent;
|
|||
|
|
filter: drop-shadow(0 0 14px rgba(216, 0, 11, 0.52));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.fold-mark--panel::after {
|
|||
|
|
display: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.side-panel__title {
|
|||
|
|
font-size: 17px;
|
|||
|
|
font-weight: 700;
|
|||
|
|
margin-bottom: 8px;
|
|||
|
|
color: #dff7ff;
|
|||
|
|
text-shadow: 0 0 8px rgba(88, 207, 255, 0.12);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.side-table th,
|
|||
|
|
.side-table td {
|
|||
|
|
font-size: 12px;
|
|||
|
|
text-align: center;
|
|||
|
|
height: 28px;
|
|||
|
|
color: #cae5f6;
|
|||
|
|
white-space: nowrap;
|
|||
|
|
word-break: normal;
|
|||
|
|
overflow: hidden;
|
|||
|
|
text-overflow: ellipsis;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.side-table tbody tr.is-empty td {
|
|||
|
|
color: rgba(202, 229, 246, 0.28);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.side-table th {
|
|||
|
|
color: #dff7ff;
|
|||
|
|
background: rgba(36, 93, 129, 0.28);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.side-panel__time {
|
|||
|
|
align-self: end;
|
|||
|
|
font-size: 14px;
|
|||
|
|
font-weight: 700;
|
|||
|
|
padding-top: 6px;
|
|||
|
|
color: #82cfff;
|
|||
|
|
font-family: "DIN Alternate", "Bahnschrift", "Consolas", monospace;
|
|||
|
|
letter-spacing: 1px;
|
|||
|
|
text-shadow: 0 0 10px rgba(76, 196, 255, 0.18);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.fault-panel .side-table {
|
|||
|
|
margin-bottom: 8px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.plan-panel .side-table {
|
|||
|
|
margin-top: 8px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.dialog-title {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: baseline;
|
|||
|
|
gap: 12px;
|
|||
|
|
font-weight: 700;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.dialog-subtitle {
|
|||
|
|
color: #666666;
|
|||
|
|
font-size: 12px;
|
|||
|
|
font-weight: 400;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.dialog-body {
|
|||
|
|
display: grid;
|
|||
|
|
gap: 16px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.dialog-section {
|
|||
|
|
border: 1px solid #dcdfe6;
|
|||
|
|
border-radius: 8px;
|
|||
|
|
padding: 16px;
|
|||
|
|
background: #ffffff;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.section-head {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
gap: 12px;
|
|||
|
|
margin-bottom: 12px;
|
|||
|
|
font-size: 14px;
|
|||
|
|
font-weight: 700;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.dialog-grid {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|||
|
|
gap: 16px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.detail-table-wrap {
|
|||
|
|
overflow: auto;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.detail-table th,
|
|||
|
|
.detail-table td {
|
|||
|
|
border: 1px solid #dcdfe6;
|
|||
|
|
padding: 8px 10px;
|
|||
|
|
font-size: 12px;
|
|||
|
|
text-align: left;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.curve-tag {
|
|||
|
|
color: #409eff;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@keyframes statusPulseGreen {
|
|||
|
|
0%, 100% {
|
|||
|
|
box-shadow: 0 0 4px rgba(63, 228, 132, 0.2);
|
|||
|
|
transform: scale(1);
|
|||
|
|
}
|
|||
|
|
50% {
|
|||
|
|
box-shadow: 0 0 8px rgba(63, 228, 132, 0.48);
|
|||
|
|
transform: scale(1.06);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@keyframes topScanner {
|
|||
|
|
0% {
|
|||
|
|
left: -30%;
|
|||
|
|
opacity: 0;
|
|||
|
|
}
|
|||
|
|
8% {
|
|||
|
|
opacity: 1;
|
|||
|
|
}
|
|||
|
|
50% {
|
|||
|
|
opacity: 1;
|
|||
|
|
}
|
|||
|
|
100% {
|
|||
|
|
left: 100%;
|
|||
|
|
opacity: 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@keyframes statusPulseYellow {
|
|||
|
|
0%, 100% {
|
|||
|
|
box-shadow: 0 0 4px rgba(240, 191, 83, 0.18);
|
|||
|
|
transform: scale(1);
|
|||
|
|
}
|
|||
|
|
50% {
|
|||
|
|
box-shadow: 0 0 8px rgba(240, 191, 83, 0.42);
|
|||
|
|
transform: scale(1.06);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@keyframes statusPulseBlue {
|
|||
|
|
0%, 100% {
|
|||
|
|
box-shadow: 0 0 4px rgba(90, 176, 255, 0.18);
|
|||
|
|
transform: scale(1);
|
|||
|
|
}
|
|||
|
|
50% {
|
|||
|
|
box-shadow: 0 0 8px rgba(90, 176, 255, 0.42);
|
|||
|
|
transform: scale(1.06);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@keyframes statusPulseRed {
|
|||
|
|
0%, 100% {
|
|||
|
|
box-shadow: 0 0 4px rgba(232, 106, 106, 0.18);
|
|||
|
|
transform: scale(1);
|
|||
|
|
}
|
|||
|
|
50% {
|
|||
|
|
box-shadow: 0 0 8px rgba(232, 106, 106, 0.42);
|
|||
|
|
transform: scale(1.06);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@keyframes statusPulseGray {
|
|||
|
|
0%, 100% {
|
|||
|
|
box-shadow: 0 0 3px rgba(149, 160, 175, 0.15);
|
|||
|
|
transform: scale(1);
|
|||
|
|
}
|
|||
|
|
50% {
|
|||
|
|
box-shadow: 0 0 6px rgba(149, 160, 175, 0.3);
|
|||
|
|
transform: scale(1.05);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
::v-deep .board-dialog {
|
|||
|
|
border-radius: 12px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@media (max-width: 1600px) {
|
|||
|
|
.board-body {
|
|||
|
|
grid-template-columns: minmax(0, 1fr) 330px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.board-stats {
|
|||
|
|
grid-template-columns: 1.2fr repeat(5, 1fr);
|
|||
|
|
font-size: 13px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-card__title {
|
|||
|
|
font-size: 11px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-no {
|
|||
|
|
font-size: 13px;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
</style>
|