revert(material): 物料跟踪页恢复到 9cf422e 布局,仅保留段位区分
回退所有 Tab / 扁平化 / 瓦片网格重构(45abd35..ea39d92)。 保留两项: - SVG 总图顶部段位色带(5 段不同色) - 物料跟踪表新增「段」列 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -32,34 +32,69 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 在线计划队列 + 入口移动 -->
|
||||
<div class="card" style="margin-bottom:8px;">
|
||||
<div class="card-header">
|
||||
在线计划(入口队列)
|
||||
<span class="ch-badge">在线 {{ onlinePlans.length }} / 生产中 {{ producingPlan ? 1 : 0 }}</span>
|
||||
<span style="margin-left:auto;font-size:11px;color:var(--text-muted);">点击「移动」把队列卷推到入口并开始生产</span>
|
||||
</div>
|
||||
<div style="padding:8px 14px;">
|
||||
<div v-if="producingPlan" class="producing-row">
|
||||
<span class="badge badge-yellow">生产中</span>
|
||||
<span class="kv-label">冷卷号</span><span class="kv-value">{{ producingPlan.cold_coil_no || producingPlan.plan_no }}</span>
|
||||
<span class="kv-label">钢种</span><span class="kv-value">{{ producingPlan.steel_grade || '—' }}</span>
|
||||
<span class="kv-label">规格</span><span class="kv-value">{{ fmt(producingPlan.product_thickness) }}×{{ fmt(producingPlan.product_width, 0) }}</span>
|
||||
<span class="kv-label">分卷</span><span class="kv-value">{{ producingPlan.split_count || 1 }}</span>
|
||||
</div>
|
||||
<table class="data-table compact" v-if="onlinePlans.length">
|
||||
<thead><tr><th>冷卷号</th><th>钢种</th><th>厚度</th><th>宽度</th><th>分卷</th><th>下达时间</th><th>操作</th></tr></thead>
|
||||
<tbody>
|
||||
<tr v-for="p in onlinePlans" :key="p.id">
|
||||
<td class="td-num">{{ p.cold_coil_no || p.plan_no }}</td>
|
||||
<td>{{ p.steel_grade || '—' }}</td>
|
||||
<td class="td-num">{{ fmt(p.product_thickness) }}</td>
|
||||
<td class="td-num">{{ fmt(p.product_width, 0) }}</td>
|
||||
<td class="td-num">{{ p.split_count || 1 }}</td>
|
||||
<td class="td-muted">{{ fmtTime(p.plan_date) }}</td>
|
||||
<td>
|
||||
<button class="btn btn-primary btn-sm" :disabled="moving" @click="movePlan(p)">移动 →</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div v-else-if="!producingPlan" class="td-muted" style="text-align:center;padding:10px;font-size:12px;">暂无在线计划</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 产线总图 -->
|
||||
<div class="line-wrap card">
|
||||
<div class="card-header">推拉酸洗线 - 物料跟踪总图</div>
|
||||
<div class="line-body">
|
||||
<svg viewBox="0 0 1900 310" preserveAspectRatio="xMidYMid meet" class="line-svg">
|
||||
<rect x="0" y="0" width="1900" height="310" fill="#0a1218" />
|
||||
<svg viewBox="0 0 1900 305" preserveAspectRatio="xMidYMid meet" class="line-svg">
|
||||
<rect x="0" y="0" width="1900" height="305" fill="#0a1218" />
|
||||
|
||||
<!-- 段位标签带 -->
|
||||
<g v-for="s in sections" :key="'sec-'+s.name">
|
||||
<rect :x="s.bandX" y="4" :width="s.bandW" height="22" :fill="s.color" opacity="0.18" rx="3"/>
|
||||
<rect :x="s.bandX" y="4" :width="s.bandW" height="22" fill="none" :stroke="s.color" stroke-width="1" opacity="0.7" rx="3"/>
|
||||
<text :x="s.labelX" y="19" text-anchor="middle" font-size="12" font-weight="bold" :fill="s.color"
|
||||
<rect :x="s.bandX" y="2" :width="s.bandW" height="20" :fill="s.color" opacity="0.18" rx="3"/>
|
||||
<rect :x="s.bandX" y="2" :width="s.bandW" height="20" fill="none" :stroke="s.color" stroke-width="1" opacity="0.7" rx="3"/>
|
||||
<text :x="s.labelX" y="16" text-anchor="middle" font-size="11" font-weight="bold" :fill="s.color"
|
||||
font-family="Arial,sans-serif">{{ s.name }}</text>
|
||||
</g>
|
||||
|
||||
<!-- 顶部设备标签 -->
|
||||
<!-- 顶部标签 -->
|
||||
<g v-for="eq in equipments" :key="'lab-'+eq.k" font-family="Arial,sans-serif">
|
||||
<text :x="eq.x" y="44" text-anchor="middle" font-size="10.5" fill="#c8d4e0">{{ eq.label }}</text>
|
||||
<text :x="eq.x" y="40" text-anchor="middle" font-size="10.5" fill="#c8d4e0">{{ eq.label }}</text>
|
||||
</g>
|
||||
|
||||
<!-- 主带钢线 -->
|
||||
<path d="M 40 190 L 1860 190" stroke="#5a6a75" stroke-width="3" fill="none"/>
|
||||
<path d="M 40 190 L 1860 190" stroke="#aabbcc" stroke-width="1.2" fill="none" stroke-dasharray="6 10">
|
||||
<path d="M 40 185 L 1860 185" stroke="#5a6a75" stroke-width="3" fill="none"/>
|
||||
<path d="M 40 185 L 1860 185" stroke="#aabbcc" stroke-width="1.2" fill="none" stroke-dasharray="6 10">
|
||||
<animate attributeName="stroke-dashoffset" from="16" to="0" dur="0.7s" repeatCount="indefinite"/>
|
||||
</path>
|
||||
|
||||
<!-- 各设备图形 -->
|
||||
<g v-for="eq in equipments" :key="eq.k" :transform="`translate(${eq.x}, 190)`">
|
||||
<g v-for="eq in equipments" :key="eq.k" :transform="`translate(${eq.x}, 185)`">
|
||||
<!-- 开卷机 -->
|
||||
<template v-if="eq.type==='coiler'">
|
||||
<circle r="38" fill="#1a232c" stroke="#3a4a55" stroke-width="2"/>
|
||||
@@ -213,7 +248,7 @@
|
||||
</g>
|
||||
|
||||
<!-- 焊缝标记 -->
|
||||
<g :transform="`translate(${weldX}, 190)`">
|
||||
<g :transform="`translate(${weldX}, 185)`">
|
||||
<circle r="11" fill="#ffdd00" opacity="0.35">
|
||||
<animate attributeName="r" values="9;22;9" dur="1.0s" repeatCount="indefinite"/>
|
||||
<animate attributeName="opacity" values="0.7;0.05;0.7" dur="1.0s" repeatCount="indefinite"/>
|
||||
@@ -225,7 +260,7 @@
|
||||
</g>
|
||||
|
||||
<!-- 图例 -->
|
||||
<g transform="translate(20,295)" font-size="10" fill="#8b949e">
|
||||
<g transform="translate(20,290)" font-size="10" fill="#8b949e">
|
||||
<circle cx="6" cy="-3" r="5" fill="#ffee44"/>
|
||||
<text x="18" y="0">焊缝位置 {{ (weld.position * 100).toFixed(1) }}%</text>
|
||||
<rect x="160" y="-7" width="12" height="8" fill="#ffaa44" opacity="0.5"/>
|
||||
@@ -240,80 +275,60 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 在线计划 / 移动按钮 -->
|
||||
<div class="card plan-card">
|
||||
<div class="plan-head">
|
||||
<span class="sec-pill" :style="{ background: sectionColor('入口段') }">入口段·在线计划</span>
|
||||
<span v-if="producingPlan" class="badge badge-yellow" style="margin-left:6px;">生产中 {{ producingPlan.cold_coil_no || producingPlan.plan_no }}</span>
|
||||
<span v-else class="td-muted" style="margin-left:6px;font-size:11px;">无在线生产</span>
|
||||
<span class="td-muted" style="margin-left:auto;font-size:11px;">{{ onlinePlans.length }} 卷待入</span>
|
||||
</div>
|
||||
<div class="plan-list">
|
||||
<div v-for="p in onlinePlans" :key="p.id" class="plan-item">
|
||||
<span class="badge badge-gray">在线</span>
|
||||
<span class="pi-coil">{{ p.cold_coil_no || p.plan_no }}</span>
|
||||
<span class="pi-grade">{{ p.steel_grade || '—' }}</span>
|
||||
<span class="pi-spec">{{ fmt(p.product_thickness) }}×{{ fmt(p.product_width, 0) }}</span>
|
||||
<span class="pi-split">分{{ p.split_count || 1 }}</span>
|
||||
<button class="btn btn-primary btn-sm" :disabled="moving" @click="movePlan(p)">移动 →</button>
|
||||
<!-- 下半: 左 跟踪表 | 右 实时数据 -->
|
||||
<div class="split-row">
|
||||
<div class="card split-left">
|
||||
<div class="card-header">物料跟踪表 <span class="hd-cnt">共 {{ equipments.length }} 台设备</span></div>
|
||||
<div class="card-body" style="padding:0;">
|
||||
<div class="track-scroll">
|
||||
<table class="data-table compact tracking-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:32px;">#</th>
|
||||
<th style="width:72px;">段</th>
|
||||
<th>设备</th>
|
||||
<th style="width:64px;">状态</th>
|
||||
<th>当前钢卷</th>
|
||||
<th style="width:80px;">辊缝 (mm)</th>
|
||||
<th style="width:78px;">速度</th>
|
||||
<th style="width:78px;">张力/温度</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(eq, i) in equipments" :key="eq.k"
|
||||
:class="{ 'row-active': eq.k === currentEquipment.k, 'row-passed': i < currentEquipment.idx, 'row-pending': i > currentEquipment.idx }">
|
||||
<td class="td-num">{{ i + 1 }}</td>
|
||||
<td><span class="sec-tag" :style="{ color: sectionColor(eq.section), borderColor: sectionColor(eq.section) }">{{ eq.section }}</span></td>
|
||||
<td>{{ eq.label }}</td>
|
||||
<td>
|
||||
<span v-if="eq.k === currentEquipment.k" class="badge badge-yellow">加工中</span>
|
||||
<span v-else-if="i < currentEquipment.idx" class="badge badge-blue">已过</span>
|
||||
<span v-else class="badge badge-gray">待入</span>
|
||||
</td>
|
||||
<td class="td-num">{{ rowOf(eq, i).coil }}</td>
|
||||
<td class="td-num">{{ rowOf(eq, i).gap }}</td>
|
||||
<td class="td-num">{{ rowOf(eq, i).speed }}</td>
|
||||
<td class="td-num">{{ rowOf(eq, i).aux }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card split-right">
|
||||
<div class="card-header">实时数据 <span class="hd-cnt">{{ rtItems.length }} 项</span></div>
|
||||
<div class="card-body sec-body">
|
||||
<div class="dg">
|
||||
<div v-for="it in rtItems" :key="it.k" class="dg-item">
|
||||
<span class="lbl">{{ it.label }}</span>
|
||||
<span class="vbox">{{ it.val }}</span>
|
||||
<span v-if="it.unit" class="unit">{{ it.unit }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!onlinePlans.length" class="td-muted" style="text-align:center;padding:6px;font-size:11px;">暂无队列</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 全段参数:统一瓦片网格 -->
|
||||
<div class="tile-grid">
|
||||
<div v-for="t in allTiles" :key="t.k" class="tile" :style="{ borderLeftColor: t.color }">
|
||||
<div class="tile-tag" :style="{ color: t.color }">{{ t.section }}</div>
|
||||
<div class="tile-label">{{ t.label }}</div>
|
||||
<div class="tile-value">{{ t.val }}<span v-if="t.unit" class="tile-unit">{{ t.unit }}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 物料跟踪表 -->
|
||||
<div class="card track-card">
|
||||
<div class="card-header">
|
||||
<span class="sec-pill" style="background:#5a6a78;">物料跟踪表</span>
|
||||
<span class="td-muted" style="margin-left:auto;font-size:11px;">{{ equipments.length }} 台设备 · 焊缝 {{ (weld.position*100).toFixed(1) }}%</span>
|
||||
</div>
|
||||
<div class="tbl-scroll" style="max-height:280px;">
|
||||
<table class="data-table compact tracking-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:32px;">#</th>
|
||||
<th style="width:78px;">段</th>
|
||||
<th>设备</th>
|
||||
<th style="width:64px;">状态</th>
|
||||
<th>当前钢卷</th>
|
||||
<th style="width:72px;">辊缝</th>
|
||||
<th style="width:70px;">速度</th>
|
||||
<th style="width:78px;">辅助</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(eq, i) in equipments" :key="eq.k"
|
||||
:class="{ 'row-active': eq.k === currentEquipment.k, 'row-passed': i < currentEquipment.idx, 'row-pending': i > currentEquipment.idx }">
|
||||
<td class="td-num">{{ i + 1 }}</td>
|
||||
<td>
|
||||
<span class="sec-tag" :style="{ color: sectionColor(eq.section), borderColor: sectionColor(eq.section) }">{{ eq.section }}</span>
|
||||
</td>
|
||||
<td>{{ eq.label }}</td>
|
||||
<td>
|
||||
<span v-if="eq.k === currentEquipment.k" class="badge badge-yellow">加工中</span>
|
||||
<span v-else-if="i < currentEquipment.idx" class="badge badge-blue">已过</span>
|
||||
<span v-else class="badge badge-gray">待入</span>
|
||||
</td>
|
||||
<td class="td-num">{{ rowOf(eq, i).coil }}</td>
|
||||
<td class="td-num">{{ rowOf(eq, i).gap }}</td>
|
||||
<td class="td-num">{{ rowOf(eq, i).speed }}</td>
|
||||
<td class="td-num">{{ rowOf(eq, i).aux }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -413,92 +428,6 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
allTiles() {
|
||||
const f = (v, n=1) => Number(v).toFixed(n)
|
||||
const c = (s) => SECTION_COLORS[s] || '#9aa8b6'
|
||||
const out = []
|
||||
const push = (section, label, val, unit) => out.push({
|
||||
k: section + ':' + label, section, color: c(section), label, val, unit,
|
||||
})
|
||||
// 入口段
|
||||
push('入口段', '开卷张力', f(this.uncoiler.tension, 1), 'kN')
|
||||
push('入口段', '工艺段速度', f(this.current.speed, 1), 'm/min')
|
||||
push('入口段', '开卷机速度', f(this.uncoiler.speed, 1), 'm/min')
|
||||
push('入口段', '开卷机卷径', f(this.uncoiler.diameter, 0),'mm')
|
||||
push('入口段', '开卷机电流', f(this.uncoiler.current, 0), 'A')
|
||||
push('入口段', '开卷机扭矩', f(this.uncoiler.torque, 2), 'kN·m')
|
||||
push('入口段', '矫直机速度', f(this.straightener.speed, 1), 'm/min')
|
||||
push('入口段', '矫直机辊缝', f(this.straightener.gap, 2), 'mm')
|
||||
push('入口段', '矫直机电流', f(this.straightener.current, 0),'A')
|
||||
push('入口段', '矫直机扭矩', f(this.straightener.torque, 2), 'kN·m')
|
||||
push('入口段', '1#夹送辊速度', f(this.br1.speed, 1), 'm/min')
|
||||
push('入口段', '1#夹送辊辊缝', f(this.br1.gap, 2), 'mm')
|
||||
// 酸洗段:5 槽
|
||||
this.acid.forEach((a, i) => {
|
||||
const t = (i+1) + '#酸槽 '
|
||||
push('酸洗段', t + '温度', f(a.temp, 1), '°C')
|
||||
push('酸洗段', t + '浓度', f(a.conc, 1), 'g/L')
|
||||
push('酸洗段', t + '液位', f(a.level, 2), 'm')
|
||||
push('酸洗段', t + '电导率', f(a.cond, 1), 'mS/cm')
|
||||
})
|
||||
push('酸洗段', '酸雾塔 PH', f(this.acid_mist.ph, 2), '')
|
||||
push('酸洗段', '酸雾变频频率', f(this.acid_mist.vfd_speed, 1), 'Hz')
|
||||
push('酸洗段', '酸雾变频电流', f(this.acid_mist.vfd_current, 1), 'A')
|
||||
push('酸洗段', '冷凝罐液位', f(this.acid_cond.level, 2), 'm')
|
||||
push('酸洗段', '冷凝罐温度', f(this.acid_cond.temp, 1), '°C')
|
||||
push('酸洗段', '冷凝电导率', f(this.acid_cond.cond, 1), 'μS/cm')
|
||||
// 清洗段:5 级
|
||||
this.rinse.forEach((r, i) => {
|
||||
const t = (i+1) + '#漂洗 '
|
||||
push('清洗段', t + '温度', f(this.rinse_tank_temp[i], 1), '°C')
|
||||
push('清洗段', t + '浓度', f(r.conc, 2), 'g/L')
|
||||
push('清洗段', t + '液位', f(r.level, 2), 'm')
|
||||
push('清洗段', t + '电导率', f(r.cond, 2), 'μS/cm')
|
||||
})
|
||||
push('清洗段', '漂洗雾塔 PH', f(this.rinse_mist.ph, 2), '')
|
||||
push('清洗段', '雾塔变频频率', f(this.rinse_mist.vfd_speed, 1), 'Hz')
|
||||
push('清洗段', '雾塔变频电流', f(this.rinse_mist.vfd_current, 1), 'A')
|
||||
push('清洗段', '冷凝液位', f(this.rinse_cond.level, 2), 'm')
|
||||
push('清洗段', '冷凝温度', f(this.rinse_cond.temp, 1), '°C')
|
||||
push('清洗段', '冷凝电导率', f(this.rinse_cond.cond, 2), 'μS/cm')
|
||||
// 烘干段
|
||||
push('烘干段', '烘干1段', f(this.dryer.t1, 0), '°C')
|
||||
push('烘干段', '烘干2段', f(this.dryer.t2, 0), '°C')
|
||||
push('烘干段', '烘干3段', f(this.dryer.t3, 0), '°C')
|
||||
// 出口段
|
||||
this.tension_vfd.forEach((v, i) => {
|
||||
const t = '三辊VFD-' + (i+1) + ' '
|
||||
push('出口段', t + '速度', f(v.speed, 1), 'm/min')
|
||||
push('出口段', t + '电流', f(v.current, 0), 'A')
|
||||
push('出口段', t + '扭矩', f(v.torque, 2), 'kN·m')
|
||||
})
|
||||
push('出口段', '平整辊缝', f(this.leveler.gap, 2), 'mm')
|
||||
push('出口段', '平整轧制力', f(this.leveler.force, 0), 'kN')
|
||||
push('出口段', '平整延伸率', f(this.leveler.elongation, 2), '%')
|
||||
push('出口段', '收卷张力', f(this.recoiler.tension, 1), 'kN')
|
||||
push('出口段', '收卷直径', f(this.recoiler.diameter, 0), 'mm')
|
||||
push('出口段', '收卷速度', f(this.recoiler.speed, 1), 'm/min')
|
||||
return out
|
||||
},
|
||||
entryItems() {
|
||||
const f = (v, n=1) => Number(v).toFixed(n)
|
||||
return [
|
||||
{ k:'u_t', label:'开卷机张力', val: f(this.uncoiler.tension, 1), unit:'kN' },
|
||||
{ k:'p_s', label:'工艺段速度', val: f(this.current.speed, 1), unit:'m/min' },
|
||||
{ k:'u_s', label:'开卷机速度', val: f(this.uncoiler.speed, 1), unit:'m/min' },
|
||||
{ k:'u_d', label:'开卷机卷径', val: f(this.uncoiler.diameter, 0),unit:'mm' },
|
||||
{ k:'u_c', label:'开卷机电流', val: f(this.uncoiler.current, 0), unit:'A' },
|
||||
{ k:'u_q', label:'开卷机扭矩', val: f(this.uncoiler.torque, 2), unit:'kN·m' },
|
||||
{ k:'st_s',label:'九辊矫直机 速度', val: f(this.straightener.speed, 1), unit:'m/min' },
|
||||
{ k:'st_g',label:'九辊矫直机 辊缝', val: f(this.straightener.gap, 2), unit:'mm' },
|
||||
{ k:'st_c',label:'九辊矫直机 电流', val: f(this.straightener.current, 0),unit:'A' },
|
||||
{ k:'st_q',label:'九辊矫直机 扭矩', val: f(this.straightener.torque, 2), unit:'kN·m' },
|
||||
{ k:'b1s', label:'1号夹送辊 速度', val: f(this.br1.speed, 1), unit:'m/min' },
|
||||
{ k:'b1g', label:'1号夹送辊 辊缝', val: f(this.br1.gap, 2), unit:'mm' },
|
||||
{ k:'b1c', label:'1号夹送辊 电流', val: f(this.br1.current, 0), unit:'A' },
|
||||
{ k:'b1q', label:'1号夹送辊 扭矩', val: f(this.br1.torque, 2), unit:'kN·m' },
|
||||
]
|
||||
},
|
||||
onlinePlans() { return this.plans.filter(p => p.status === 'online') },
|
||||
producingPlan() { return this.plans.find(p => p.status === 'producing') || null },
|
||||
equipments() {
|
||||
@@ -509,20 +438,18 @@ export default {
|
||||
},
|
||||
sections() {
|
||||
const eqs = this.equipments
|
||||
if (!eqs.length) return []
|
||||
const groups = []
|
||||
let cur = null
|
||||
eqs.forEach((e, i) => {
|
||||
if (!cur || cur.name !== e.section) {
|
||||
if (cur) groups.push(cur)
|
||||
cur = { name: e.section, color: SECTION_COLORS[e.section] || '#9aa8b6',
|
||||
startIdx: i, endIdx: i, x0: e.x, x1: e.x }
|
||||
} else {
|
||||
cur.endIdx = i
|
||||
cur.x1 = e.x
|
||||
}
|
||||
x0: e.x, x1: e.x }
|
||||
} else { cur.x1 = e.x }
|
||||
})
|
||||
if (cur) groups.push(cur)
|
||||
const half = (eqs[1].x - eqs[0].x) / 2
|
||||
const half = eqs.length > 1 ? (eqs[1].x - eqs[0].x) / 2 : 30
|
||||
return groups.map(g => ({
|
||||
...g,
|
||||
bandX: g.x0 - half + 4,
|
||||
@@ -567,7 +494,7 @@ export default {
|
||||
push('r_t', '收卷机 收卷张力', fix(this.recoiler.tension, 1), 'kN')
|
||||
|
||||
this.acid.forEach((a, i) => {
|
||||
push(`at${i}`, `酸洗${i+1}# 槽温度`, fix(a.temp, 1), '°C')
|
||||
push(`at${i}`, `酸洗${i+1}# 槽/罐温度(公用)`, fix(a.temp, 1), '°C')
|
||||
push(`al${i}`, `酸洗${i+1}# 罐液位`, fix(a.level, 2), 'm')
|
||||
push(`ac${i}`, `酸洗${i+1}# 槽浓度`, fix(a.conc, 1), 'g/L')
|
||||
push(`ae${i}`, `酸洗${i+1}# 槽电导率`, fix(a.cond, 1), 'mS/cm')
|
||||
@@ -583,7 +510,7 @@ export default {
|
||||
|
||||
this.rinse.forEach((r, i) => {
|
||||
const t = this.rinse_tank_temp[i]
|
||||
push(`rt${i}`, `漂洗${i+1}# 槽温度`, fix(t, 1), '°C')
|
||||
push(`rt${i}`, `漂洗${i+1}# 槽/罐温度(公用)`, fix(t, 1), '°C')
|
||||
push(`rl${i}`, `漂洗${i+1}# 罐液位`, fix(r.level, 2), 'm')
|
||||
push(`rc${i}`, `漂洗${i+1}# 槽浓度`, fix(r.conc, 2), 'g/L')
|
||||
push(`re${i}`, `漂洗${i+1}# 槽电导率`, fix(r.cond, 2), 'μS/cm')
|
||||
@@ -610,7 +537,6 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
fmt(v, n = 2) { return v != null && v !== '' ? Number(v).toFixed(n) : '—' },
|
||||
fix(v, n = 1) { return Number(v).toFixed(n) },
|
||||
sectionColor(s) { return SECTION_COLORS[s] || '#9aa8b6' },
|
||||
fmtTime(t) { return t ? t.slice(0, 16).replace('T', ' ') : '—' },
|
||||
async loadPlans() {
|
||||
@@ -754,12 +680,7 @@ export default {
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/styles/variables';
|
||||
|
||||
.mat-page { display: flex; flex-direction: column; gap: 10px; min-width: 0; overflow-x: hidden; }
|
||||
.sec-tag {
|
||||
display: inline-block; font-size: 10.5px; padding: 1px 6px;
|
||||
border: 1px solid; border-radius: 3px; background: rgba(0,0,0,.25);
|
||||
font-weight: 600; letter-spacing: 0.5px;
|
||||
}
|
||||
.mat-page { display: flex; flex-direction: column; gap: 10px; }
|
||||
|
||||
.status-bar {
|
||||
display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
|
||||
@@ -773,78 +694,40 @@ export default {
|
||||
|
||||
.line-wrap { padding: 0; }
|
||||
.line-body { padding: 6px 10px 10px; background: #0a1218; }
|
||||
.line-svg { width: 100%; height: 310px; display: block; }
|
||||
.line-svg { width: 100%; height: 305px; display: block; }
|
||||
|
||||
.sec-pill {
|
||||
display: inline-block; padding: 2px 10px;
|
||||
font-size: 11.5px; font-weight: 700; color: #0a1218;
|
||||
border-radius: 3px; letter-spacing: 1px;
|
||||
}
|
||||
.split-row { display: grid; grid-template-columns: 1.05fr 1fr; gap: 10px; align-items: stretch; }
|
||||
.split-left, .split-right { display: flex; flex-direction: column; min-height: 540px; }
|
||||
.split-right .card-body { flex: 1; overflow-y: auto; }
|
||||
|
||||
/* ─── 在线计划卡 ─── */
|
||||
.plan-card { padding: 0; }
|
||||
.plan-head {
|
||||
display: flex; align-items: center; gap: 6px;
|
||||
padding: 7px 12px; font-size: 12px;
|
||||
background: #161d24; border-bottom: 1px solid $border;
|
||||
}
|
||||
.plan-list { padding: 6px 10px; display: flex; flex-direction: column; gap: 4px; }
|
||||
.plan-item {
|
||||
display: flex; align-items: center; gap: 10px;
|
||||
padding: 4px 8px;
|
||||
background: #0f161c; border: 1px solid $border; border-radius: 3px;
|
||||
font-size: 12px;
|
||||
.pi-coil { color: $sms-highlight; font-weight: 600; font-family: monospace; min-width: 110px; }
|
||||
.pi-grade { color: #c8d4e0; min-width: 60px; }
|
||||
.pi-spec { color: #8b9aab; min-width: 90px; font-family: monospace; }
|
||||
.pi-split { color: #8b9aab; min-width: 40px; }
|
||||
button { margin-left: auto; }
|
||||
}
|
||||
.track-scroll { max-height: 640px; overflow-y: auto; }
|
||||
|
||||
/* ─── 统一瓦片网格 ─── */
|
||||
.tile-grid {
|
||||
display: grid; gap: 6px;
|
||||
grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
|
||||
min-width: 0;
|
||||
.producing-row { display: flex; align-items: center; gap: 10px; padding: 6px 4px 10px; font-size: 12px; border-bottom: 1px dashed $border; margin-bottom: 6px;
|
||||
.kv-label { color: $text-muted; font-size: 11px; margin-left: 6px; }
|
||||
.kv-value { color: $sms-highlight; font-weight: 600; }
|
||||
}
|
||||
.tile {
|
||||
display: flex; flex-direction: column; gap: 1px;
|
||||
padding: 5px 8px 6px;
|
||||
background: $bg-card; border: 1px solid $border;
|
||||
border-left: 3px solid transparent;
|
||||
border-radius: 3px;
|
||||
min-width: 0;
|
||||
}
|
||||
.tile-tag {
|
||||
font-size: 9px; font-weight: 700; letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||
}
|
||||
.tile-label {
|
||||
font-size: 11px; color: #8b9aab;
|
||||
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||
}
|
||||
.tile-value {
|
||||
font-family: monospace; font-size: 15px; font-weight: 700;
|
||||
color: #00c8ff; text-align: right; margin-top: 1px;
|
||||
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||
}
|
||||
.tile-unit { font-size: 10px; color: #6b7c8d; font-weight: 400; margin-left: 4px; }
|
||||
.btn-sm { padding: 2px 10px; font-size: 11px; }
|
||||
|
||||
/* ─── 跟踪表卡 ─── */
|
||||
.track-card { padding: 0; }
|
||||
.track-card .card-header {
|
||||
display: flex; align-items: center; padding: 7px 12px;
|
||||
background: #161d24; border-bottom: 1px solid $border; font-size: 12px;
|
||||
}
|
||||
.tbl-scroll { width: 100%; overflow: auto; }
|
||||
.hd-cnt { font-size: 11px; color: #6b7c8d; margin-left: 8px; font-weight: 400; }
|
||||
|
||||
.empty-row { text-align: center; padding: 10px; font-size: 12px; }
|
||||
.btn-sm { padding: 2px 10px; font-size: 11px; white-space: nowrap; }
|
||||
.sec-body { padding: 10px 14px; background: #161d24; }
|
||||
|
||||
.dg { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 4px 18px; }
|
||||
.dg-item { display: flex; align-items: center; gap: 6px; font-size: 12px; color: #c8d4e0; padding: 2px 0; }
|
||||
.dg-item .lbl { color: #8b9aab; flex: 1; min-width: 140px; }
|
||||
.dg-item .vbox {
|
||||
background: #0e1418; border: 1px solid #2a3540; padding: 1px 8px;
|
||||
min-width: 70px; text-align: right; font-family: monospace;
|
||||
color: #00c8ff; border-radius: 2px;
|
||||
}
|
||||
.dg-item .unit { color: #6b7c8d; font-size: 11px; min-width: 44px; }
|
||||
|
||||
.data-table.compact th, .data-table.compact td { padding: 5px 8px; font-size: 11.5px; }
|
||||
.tracking-table tr.row-active { background: rgba(255, 221, 68, 0.10); }
|
||||
.tracking-table tr.row-active td { color: #ffdd44 !important; font-weight: 600; }
|
||||
.tracking-table tr.row-passed td { color: #6b8aaa; }
|
||||
.tracking-table tr.row-pending td { color: #5a6a78; }
|
||||
.sec-tag { display: inline-block; font-size: 10.5px; padding: 1px 6px;
|
||||
border: 1px solid; border-radius: 3px; background: rgba(0,0,0,.25);
|
||||
font-weight: 600; letter-spacing: 0.5px; }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user