From ea39d92364240724d3ccc52876fadbb3ef7aade2 Mon Sep 17 00:00:00 2001 From: wangyu <823267011@qq.com> Date: Fri, 26 Jun 2026 14:22:06 +0800 Subject: [PATCH] =?UTF-8?q?refactor(material):=20=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=E7=BB=9F=E4=B8=80=E7=93=A6=E7=89=87=E7=BD=91=E6=A0=BC=E5=B8=83?= =?UTF-8?q?=E5=B1=80=EF=BC=8C=E5=BD=BB=E5=BA=95=E6=B6=88=E9=99=A4=E6=BA=A2?= =?UTF-8?q?=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除所有 section/sub-card/tank-card 嵌套结构 - 全部 47 个参数(入口/酸洗/清洗/烘干/出口)统一为 tile 瓦片 - tile-grid 用 auto-fit minmax(170px, 1fr),浏览器自动排版 - 每个 tile 左边 3px 色边 + 顶部段位标签,颜色与产线总图一致 - 在线计划区改为行卡片列表,跟踪表保留独立卡片 Co-Authored-By: Claude Opus 4.7 --- frontend/src/views/Material.vue | 396 +++++++++++++++----------------- 1 file changed, 184 insertions(+), 212 deletions(-) diff --git a/frontend/src/views/Material.vue b/frontend/src/views/Material.vue index f2450f8..38280b5 100644 --- a/frontend/src/views/Material.vue +++ b/frontend/src/views/Material.vue @@ -240,183 +240,80 @@ - -
-
- 入口段 - 在线 {{ onlinePlans.length }} / 生产中 {{ producingPlan ? 1 : 0 }} + +
+
+ 入口段·在线计划 + 生产中 {{ producingPlan.cold_coil_no || producingPlan.plan_no }} + 无在线生产 + {{ onlinePlans.length }} 卷待入
-
- -
- 生产中 - 冷卷号{{ producingPlan.cold_coil_no || producingPlan.plan_no }} - 钢种{{ producingPlan.steel_grade || '—' }} - 规格{{ fmt(producingPlan.product_thickness) }}×{{ fmt(producingPlan.product_width, 0) }} -
-
- - - - - - - - - - - - -
冷卷号钢种厚度宽度分卷移动
{{ p.cold_coil_no || p.plan_no }}{{ p.steel_grade || '—' }}{{ fmt(p.product_thickness) }}{{ fmt(p.product_width, 0) }}{{ p.split_count || 1 }}
-
暂无在线计划
-
- -
-
-
{{ it.label }}
-
{{ it.val }}{{ it.unit }}
-
+
+
+ 在线 + {{ p.cold_coil_no || p.plan_no }} + {{ p.steel_grade || '—' }} + {{ fmt(p.product_thickness) }}×{{ fmt(p.product_width, 0) }} + 分{{ p.split_count || 1 }} +
+
暂无队列
-
+ - -
-
- 酸洗段 - 5 槽串联 + +
+
+
{{ t.section }}
+
{{ t.label }}
+
{{ t.val }}{{ t.unit }}
-
-
-
-
{{ i+1 }}# 酸洗槽
-
-
槽温度
{{ fix(a.temp,1) }}°C
-
罐液位
{{ fix(a.level,2) }}m
-
槽浓度
{{ fix(a.conc,1) }}g/L
-
槽电导率
{{ fix(a.cond,1) }}mS/cm
-
罐浓度
{{ fix(a.tank_conc,1) }}g/L
-
罐电导率
{{ fix(a.tank_cond,1) }}mS/cm
-
-
-
-
-
酸雾塔 PH
{{ fix(acid_mist.ph,2) }}
-
雾塔变频频率
{{ fix(acid_mist.vfd_speed,1) }}Hz
-
雾塔变频电流
{{ fix(acid_mist.vfd_current,1) }}A
-
冷凝罐液位
{{ fix(acid_cond.level,2) }}m
-
冷凝罐温度
{{ fix(acid_cond.temp,1) }}°C
-
冷凝电导率
{{ fix(acid_cond.cond,1) }}μS/cm
-
-
-
+ - -
-
- 清洗段 - 烘干段 - 5 级逆流 + 3 段热风 + +
+
+ 物料跟踪表 + {{ equipments.length }} 台设备 · 焊缝 {{ (weld.position*100).toFixed(1) }}%
-
-
-
-
{{ i+1 }}# 漂洗
-
-
槽温度
{{ fix(rinse_tank_temp[i],1) }}°C
-
罐液位
{{ fix(r.level,2) }}m
-
槽浓度
{{ fix(r.conc,2) }}g/L
-
槽电导率
{{ fix(r.cond,2) }}μS/cm
-
罐浓度
{{ fix(r.tank_conc,2) }}g/L
-
罐电导率
{{ fix(r.tank_cond,2) }}μS/cm
-
-
-
-
-
漂洗雾塔 PH
{{ fix(rinse_mist.ph,2) }}
-
雾塔变频频率
{{ fix(rinse_mist.vfd_speed,1) }}Hz
-
雾塔变频电流
{{ fix(rinse_mist.vfd_current,1) }}A
-
冷凝液位
{{ fix(rinse_cond.level,2) }}m
-
冷凝温度
{{ fix(rinse_cond.temp,1) }}°C
-
冷凝电导率
{{ fix(rinse_cond.cond,2) }}μS/cm
-
烘干 1 段
{{ fix(dryer.t1,0) }}°C
-
烘干 2 段
{{ fix(dryer.t2,0) }}°C
-
烘干 3 段
{{ fix(dryer.t3,0) }}°C
-
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
#设备状态当前钢卷辊缝速度辅助
{{ i + 1 }} + {{ eq.section }} + {{ eq.label }} + 加工中 + 已过 + 待入 + {{ rowOf(eq, i).coil }}{{ rowOf(eq, i).gap }}{{ rowOf(eq, i).speed }}{{ rowOf(eq, i).aux }}
-
+ - -
-
- 出口段 - 三辊张力 + 平整 + 涂油 + 收卷 -
-
-
-
-
三辊 VFD-{{ i+1 }} 速度
-
{{ fix(v.speed,1) }}m/min
-
-
-
三辊 VFD-{{ i+1 }} 电流
-
{{ fix(v.current,0) }}A
-
-
-
三辊 VFD-{{ i+1 }} 扭矩
-
{{ fix(v.torque,2) }}kN·m
-
-
平整辊缝
{{ fix(leveler.gap,2) }}mm
-
平整轧制力
{{ fix(leveler.force,0) }}kN
-
平整延伸率
{{ fix(leveler.elongation,2) }}%
-
收卷张力
{{ fix(recoiler.tension,1) }}kN
-
收卷直径
{{ fix(recoiler.diameter,0) }}mm
-
收卷速度
{{ fix(recoiler.speed,1) }}m/min
-
-
-
- -
-
物料跟踪表 {{ equipments.length }} 台设备
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - -
#设备状态当前钢卷辊缝 mm速度张力/温度
{{ i + 1 }} - {{ eq.section }} - {{ eq.label }} - 加工中 - 已过 - 待入 - {{ rowOf(eq, i).coil }}{{ rowOf(eq, i).gap }}{{ rowOf(eq, i).speed }}{{ rowOf(eq, i).aux }}
-
-
-
@@ -516,6 +413,73 @@ 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 [ @@ -811,64 +775,72 @@ export default { .line-body { padding: 6px 10px 10px; background: #0a1218; } .line-svg { width: 100%; height: 310px; display: block; } -.sec { - background: $bg-card; border: 1px solid $border; border-radius: 6px; - overflow: hidden; min-width: 0; -} -.sec-title-bar { - display: flex; align-items: center; gap: 8px; - padding: 7px 12px; font-size: 12px; color: $text-muted; font-weight: 500; - background: #161d24; border-bottom: 1px solid $border; - border-left: 3px solid transparent; -} .sec-pill { display: inline-block; padding: 2px 10px; font-size: 11.5px; font-weight: 700; color: #0a1218; border-radius: 3px; letter-spacing: 1px; } -.pane { padding: 10px 12px; min-width: 0; } -.kpi-row { - display: grid; gap: 6px 8px; - grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); +/* ─── 在线计划卡 ─── */ +.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; } -.kpi-row.two { grid-template-columns: repeat(2, minmax(0, 1fr)); } -.kpi-row.tight { - margin-top: 8px; padding-top: 8px; - border-top: 1px dashed $border; - grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); +.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; } } -.kpi { display: flex; flex-direction: column; gap: 2px; min-width: 0; } -.kpi-label { color: #8b9aab; font-size: 10.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } -.kpi-value { - color: #00c8ff; font-family: monospace; font-size: 13.5px; font-weight: 600; - background: #0a1218; border: 1px solid #2a3540; border-radius: 3px; - padding: 3px 8px; text-align: right; + +/* ─── 统一瓦片网格 ─── */ +.tile-grid { + display: grid; gap: 6px; + grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); + min-width: 0; +} +.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; } -.kpi-unit { color: #6b7c8d; font-size: 10px; font-weight: 400; margin-left: 4px; } - -.tank-row { - display: grid; gap: 8px; - grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); - margin-bottom: 4px; +.tile-label { + font-size: 11px; color: #8b9aab; + white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } -.tank-card { background: #0f161c; border: 1px solid $border; border-radius: 4px; padding: 6px 8px; min-width: 0; } -.tank-title { font-size: 11.5px; font-weight: 600; margin-bottom: 5px; } - -.tbl-scroll { width: 100%; overflow-x: auto; margin-bottom: 8px; } -.tbl-scroll:last-child { margin-bottom: 0; } - -.producing-row { - display: flex; align-items: center; gap: 8px; flex-wrap: wrap; - padding: 4px 4px 8px; font-size: 12px; - border-bottom: 1px dashed $border; margin-bottom: 6px; - .kv-label { color: $text-muted; font-size: 11px; margin-left: 4px; } - .kv-value { color: $sms-highlight; font-weight: 600; } +.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; } + +/* ─── 跟踪表卡 ─── */ +.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; } + .empty-row { text-align: center; padding: 10px; font-size: 12px; } -.btn-sm { padding: 2px 10px; font-size: 11px; } -.hd-cnt { font-size: 11px; color: #6b7c8d; font-weight: 400; } +.btn-sm { padding: 2px 10px; font-size: 11px; white-space: nowrap; } .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); }