1. 调整侧边栏菜单的路由标题与图标,交换入口跟踪和物料跟踪的配置 2. 重构Material.vue页面:移除原有计划队列和产线跟踪总图,改为按设备分组的实时参数仪表盘 3. 简化页面脚本逻辑,移除多余的API调用和定时器 4. 统一页面样式类名,调整布局样式
451 lines
21 KiB
Vue
451 lines
21 KiB
Vue
<template>
|
||
<div class="param-page">
|
||
<!-- 顶部状态条 -->
|
||
<div class="status-bar">
|
||
<div class="status-item">
|
||
<span class="kv-label">工艺段速度</span>
|
||
<span class="kv-value">{{ current.speed.toFixed(1) }} <span class="kv-unit">m/min</span></span>
|
||
</div>
|
||
<div class="status-item">
|
||
<span class="kv-label">焊缝位置</span>
|
||
<span class="kv-value">{{ (weld.position * 100).toFixed(1) }} <span class="kv-unit">%</span></span>
|
||
</div>
|
||
<div class="status-item">
|
||
<span class="kv-label">当前设备</span>
|
||
<span class="kv-value">{{ currentEquipment.label }}</span>
|
||
</div>
|
||
<div class="status-item">
|
||
<span class="kv-label">开卷张力</span>
|
||
<span class="kv-value">{{ uncoiler.tension.toFixed(1) }} <span class="kv-unit">kN</span></span>
|
||
</div>
|
||
<div class="status-item">
|
||
<span class="kv-label">收卷张力</span>
|
||
<span class="kv-value">{{ recoiler.tension.toFixed(1) }} <span class="kv-unit">kN</span></span>
|
||
</div>
|
||
<div class="status-item" style="margin-left:auto;">
|
||
<span :class="['badge', l1Online ? 'badge-green' : 'badge-yellow']">{{ l1Online ? 'L1 在线' : '模拟数据' }}</span>
|
||
<span class="kv-label" style="margin-left:8px;">{{ rtItems.length }} 测点</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 数据仪表盘:按设备/工艺段分组 -->
|
||
<div class="card">
|
||
<div class="card-header">
|
||
实时参数总览
|
||
<span class="hd-cnt">{{ rtItems.length }} 项</span>
|
||
<span style="margin-left:auto;">
|
||
<button class="btn btn-primary btn-xs" @click="expanded = !expanded">{{ expanded ? '折叠全部' : '展开全部' }}</button>
|
||
</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<!-- 开卷机 -->
|
||
<div class="param-group">
|
||
<div class="pg-header" @click="toggleGroup('uncoiler')">
|
||
<span :class="['pg-arrow', { open: groups.uncoiler }]">▶</span>
|
||
开卷机
|
||
<span class="pg-badge">4 项</span>
|
||
</div>
|
||
<div v-show="groups.uncoiler" class="pg-body">
|
||
<div class="dg">
|
||
<div v-for="it in filterItems('u_')" :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>
|
||
<!-- 九辊矫直机 -->
|
||
<div class="param-group">
|
||
<div class="pg-header" @click="toggleGroup('straightener')">
|
||
<span :class="['pg-arrow', { open: groups.straightener }]">▶</span>
|
||
九辊矫直机
|
||
<span class="pg-badge">3 项</span>
|
||
</div>
|
||
<div v-show="groups.straightener" class="pg-body">
|
||
<div class="dg">
|
||
<div v-for="it in filterItems('st_')" :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>
|
||
<!-- 夹送辊 -->
|
||
<div class="param-group">
|
||
<div class="pg-header" @click="toggleGroup('pinch')">
|
||
<span :class="['pg-arrow', { open: groups.pinch }]">▶</span>
|
||
夹送辊(1#/2#/3#)
|
||
<span class="pg-badge">9 项</span>
|
||
</div>
|
||
<div v-show="groups.pinch" class="pg-body">
|
||
<div class="dg">
|
||
<div v-for="it in filterItems(['br1_','br2_','br3_'])" :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>
|
||
<!-- 三辊张力 -->
|
||
<div class="param-group">
|
||
<div class="pg-header" @click="toggleGroup('tension')">
|
||
<span :class="['pg-arrow', { open: groups.tension }]">▶</span>
|
||
三辊张力装置
|
||
<span class="pg-badge">9 项</span>
|
||
</div>
|
||
<div v-show="groups.tension" class="pg-body">
|
||
<div class="dg">
|
||
<div v-for="it in filterItems('tv')" :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>
|
||
<!-- 收卷机 -->
|
||
<div class="param-group">
|
||
<div class="pg-header" @click="toggleGroup('recoiler')">
|
||
<span :class="['pg-arrow', { open: groups.recoiler }]">▶</span>
|
||
收卷机
|
||
<span class="pg-badge">1 项</span>
|
||
</div>
|
||
<div v-show="groups.recoiler" class="pg-body">
|
||
<div class="dg">
|
||
<div v-for="it in filterItems('r_t')" :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>
|
||
<!-- 酸洗段 -->
|
||
<div class="param-group">
|
||
<div class="pg-header" @click="toggleGroup('acid')">
|
||
<span :class="['pg-arrow', { open: groups.acid }]">▶</span>
|
||
酸洗段
|
||
<span class="pg-badge">12 项</span>
|
||
</div>
|
||
<div v-show="groups.acid" class="pg-body">
|
||
<div class="dg">
|
||
<div v-for="it in filterItems(['at','al','ac','ae','atc','ate','amp','ams','amc','acl','act','acc'])" :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>
|
||
<!-- 漂洗段 -->
|
||
<div class="param-group">
|
||
<div class="pg-header" @click="toggleGroup('rinse')">
|
||
<span :class="['pg-arrow', { open: groups.rinse }]">▶</span>
|
||
漂洗段
|
||
<span class="pg-badge">12 项</span>
|
||
</div>
|
||
<div v-show="groups.rinse" class="pg-body">
|
||
<div class="dg">
|
||
<div v-for="it in filterItems(['rt','rl','rc','re','rtc','rte','rmp','rms','rmc','rcl','rct','rcc'])" :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>
|
||
<!-- 平整机 -->
|
||
<div class="param-group">
|
||
<div class="pg-header" @click="toggleGroup('leveler')">
|
||
<span :class="['pg-arrow', { open: groups.leveler }]">▶</span>
|
||
平整机
|
||
<span class="pg-badge">3 项</span>
|
||
</div>
|
||
<div v-show="groups.leveler" class="pg-body">
|
||
<div class="dg">
|
||
<div v-for="it in filterItems('lv')" :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>
|
||
<!-- 烘干段 -->
|
||
<div class="param-group">
|
||
<div class="pg-header" @click="toggleGroup('dryer')">
|
||
<span :class="['pg-arrow', { open: groups.dryer }]">▶</span>
|
||
热风烘干段
|
||
<span class="pg-badge">3 项</span>
|
||
</div>
|
||
<div v-show="groups.dryer" class="pg-body">
|
||
<div class="dg">
|
||
<div v-for="it in filterItems('dt')" :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>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
function rnd(base, amp) { return base + (Math.random() - 0.5) * amp }
|
||
function fix(v, n = 1) { return Number(v).toFixed(n) }
|
||
|
||
const EQUIPMENTS = [
|
||
{ k:'uncoiler', label:'开卷机', type:'coiler', section:'入口段' },
|
||
{ k:'straightener', label:'九辊矫直机', type:'rolls9', section:'入口段' },
|
||
{ k:'crop_shear', label:'切头剪', type:'shear', section:'入口段' },
|
||
{ k:'acid1', label:'酸洗槽1', type:'acid', idx:0, section:'酸洗段' },
|
||
{ k:'acid2', label:'酸洗槽2', type:'acid', idx:1, section:'酸洗段' },
|
||
{ k:'acid3', label:'酸洗槽3', type:'acid', idx:2, section:'酸洗段' },
|
||
{ k:'acid4', label:'酸洗槽4', type:'acid', idx:3, section:'酸洗段' },
|
||
{ k:'acid5', label:'酸洗槽5', type:'acid', idx:4, section:'酸洗段' },
|
||
{ k:'rinse', label:'漂洗段', type:'rinse', section:'清洗段' },
|
||
{ k:'dryer', label:'热风烘干段', type:'dryer', section:'烘干段' },
|
||
{ k:'br1', label:'1号夹送辊', type:'pinch', code:'BR-1', section:'出口段' },
|
||
{ k:'loop', label:'活套坑', type:'loop', section:'出口段' },
|
||
{ k:'br2', label:'2号夹送辊', type:'pinch', code:'BR-2', section:'出口段' },
|
||
{ k:'br3', label:'3号夹送辊', type:'pinch', code:'BR-3', section:'出口段' },
|
||
{ k:'tension', label:'三辊张力装置', type:'tension3', code:'TEN-3', section:'出口段' },
|
||
{ k:'leveler', label:'平整机', type:'leveler', code:'SPM', section:'出口段' },
|
||
{ k:'tail_shear', label:'切尾剪', type:'shear', code:'TLS', section:'出口段' },
|
||
{ k:'oiler', label:'静电涂油机', type:'oiler', code:'EOL', section:'出口段' },
|
||
{ k:'recoiler', label:'卷取机', type:'recoiler', code:'REC-1', section:'出口段' },
|
||
]
|
||
|
||
export default {
|
||
name: 'Material',
|
||
data() {
|
||
return {
|
||
l1Online: false,
|
||
now: Date.now(),
|
||
expanded: true,
|
||
groups: {
|
||
uncoiler: true, straightener: true, pinch: true, tension: true,
|
||
recoiler: true, acid: true, rinse: true, leveler: true, dryer: true,
|
||
},
|
||
current: { speed: 95.0 },
|
||
weld: { position: 0.08 },
|
||
|
||
uncoiler: { tension: 18.5, speed: 92.0, current: 240, torque: 1.8, diameter: 1450 },
|
||
straightener: { speed: 92.0, current: 165, torque: 1.5, gap: 4.20 },
|
||
br1: { speed: 92.0, current: 145, torque: 1.3, gap: 3.80 },
|
||
br2: { speed: 92.0, current: 142, torque: 1.3, gap: 3.80 },
|
||
br3: { speed: 92.0, current: 140, torque: 1.3, gap: 3.80 },
|
||
tension_vfd: [
|
||
{ speed: 92.0, current: 158, torque: 1.6 },
|
||
{ speed: 92.0, current: 156, torque: 1.5 },
|
||
{ speed: 92.0, current: 154, torque: 1.5 },
|
||
],
|
||
leveler: { gap: 3.50, force: 280, elongation: 0.45 },
|
||
recoiler: { tension: 22.4 },
|
||
|
||
acid: [
|
||
{ temp: 82, conc: 198, level: 0.97, cond: 215, tank_conc: 195, tank_cond: 210 },
|
||
{ temp: 81, conc: 188, level: 1.03, cond: 205, tank_conc: 185, tank_cond: 200 },
|
||
{ temp: 81, conc: 175, level: 0.94, cond: 192, tank_conc: 172, tank_cond: 188 },
|
||
{ temp: 80, conc: 162, level: 0.74, cond: 178, tank_conc: 158, tank_cond: 175 },
|
||
{ temp: 74, conc: 148, level: 0.71, cond: 162, tank_conc: 145, tank_cond: 160 },
|
||
],
|
||
acid_mist: { ph: 6.8, vfd_speed: 48.5, vfd_current: 32.6 },
|
||
acid_cond: { level: 1.85, temp: 42.5, cond: 12.5 },
|
||
|
||
rinse_tank_temp: [65, 62, 58, 54, 48],
|
||
rinse: [
|
||
{ conc: 0.5, cond: 18.5, level: 0.45, tank_conc: 0.4, tank_cond: 17.5 },
|
||
{ conc: 0.3, cond: 12.2, level: 0.54, tank_conc: 0.3, tank_cond: 11.8 },
|
||
{ conc: 0.2, cond: 6.8, level: 0.18, tank_conc: 0.2, tank_cond: 6.5 },
|
||
{ conc: 0.1, cond: 2.5, level: 0.77, tank_conc: 0.1, tank_cond: 2.4 },
|
||
{ conc: 0.0, cond: 0.8, level: 0.81, tank_conc: 0.0, tank_cond: 0.7 },
|
||
],
|
||
rinse_mist: { ph: 7.0, vfd_speed: 45.2, vfd_current: 28.4 },
|
||
rinse_cond: { level: 2.10, temp: 38.6, cond: 4.5 },
|
||
|
||
dryer: { t1: 145, t2: 168, t3: 152 },
|
||
}
|
||
},
|
||
computed: {
|
||
currentEquipment() {
|
||
const n = EQUIPMENTS.length
|
||
const idx = Math.max(0, Math.min(n - 1, Math.floor(this.weld.position * n)))
|
||
return { ...EQUIPMENTS[idx], idx }
|
||
},
|
||
rtItems() {
|
||
const items = []
|
||
const push = (k, label, val, unit) => items.push({ k, label, val, unit })
|
||
|
||
push('u_t', '开卷机 开卷张力', fix(this.uncoiler.tension, 1), 'kN')
|
||
push('u_s', '开卷机 速度反馈', fix(this.uncoiler.speed, 1), 'm/min')
|
||
push('u_c', '开卷机 电流反馈', fix(this.uncoiler.current, 0), 'A')
|
||
push('u_q', '开卷机 扭矩反馈', fix(this.uncoiler.torque, 2), 'kN·m')
|
||
|
||
push('st_s', '九辊矫直机 速度反馈',fix(this.straightener.speed, 1), 'm/min')
|
||
push('st_c', '九辊矫直机 电流反馈',fix(this.straightener.current, 0), 'A')
|
||
push('st_q', '九辊矫直机 扭矩反馈',fix(this.straightener.torque, 2), 'kN·m')
|
||
|
||
for (const [k, name] of [['br1','1号夹送辊'], ['br2','2号夹送辊'], ['br3','3号夹送辊']]) {
|
||
push(k+'_s', `${name} 速度反馈`, fix(this[k].speed, 1), 'm/min')
|
||
push(k+'_c', `${name} 电流反馈`, fix(this[k].current, 0), 'A')
|
||
push(k+'_q', `${name} 扭矩反馈`, fix(this[k].torque, 2), 'kN·m')
|
||
}
|
||
|
||
this.tension_vfd.forEach((v, i) => {
|
||
push(`tv${i}s`, `三辊张力 变频器${i+1} 速度反馈`, fix(v.speed, 1), 'm/min')
|
||
push(`tv${i}c`, `三辊张力 变频器${i+1} 电流反馈`, fix(v.current, 0), 'A')
|
||
push(`tv${i}q`, `三辊张力 变频器${i+1} 扭矩反馈`, fix(v.torque, 2), 'kN·m')
|
||
})
|
||
|
||
push('r_t', '收卷机 收卷张力', fix(this.recoiler.tension, 1), 'kN')
|
||
|
||
const avg = (arr, k) => arr.reduce((s, x) => s + x[k], 0) / arr.length
|
||
push('at', '酸洗 槽温度均值', fix(avg(this.acid, 'temp'), 1), '°C')
|
||
push('al', '酸洗 罐液位均值', fix(avg(this.acid, 'level'), 2), 'm')
|
||
push('ac', '酸洗 槽浓度均值', fix(avg(this.acid, 'conc'), 1), 'g/L')
|
||
push('ae', '酸洗 槽电导率均值',fix(avg(this.acid, 'cond'), 1), 'mS/cm')
|
||
push('atc','酸洗 罐浓度均值', fix(avg(this.acid, 'tank_conc'), 1), 'g/L')
|
||
push('ate','酸洗 罐电导率均值',fix(avg(this.acid, 'tank_cond'), 1), 'mS/cm')
|
||
push('amp', '酸雾塔 PH', fix(this.acid_mist.ph, 2), '')
|
||
push('ams', '酸雾塔 变频器频率', fix(this.acid_mist.vfd_speed, 1), 'Hz')
|
||
push('amc', '酸雾塔 变频器电流', fix(this.acid_mist.vfd_current,1),'A')
|
||
push('acl', '酸侧冷凝水罐 液位', fix(this.acid_cond.level, 2), 'm')
|
||
push('act', '酸侧冷凝水罐 温度', fix(this.acid_cond.temp, 1), '°C')
|
||
push('acc', '酸侧冷凝水罐 电导率', fix(this.acid_cond.cond, 1), 'μS/cm')
|
||
|
||
const rtAvg = this.rinse_tank_temp.reduce((s, x) => s + x, 0) / this.rinse_tank_temp.length
|
||
push('rt', '漂洗 槽温度均值', fix(rtAvg, 1), '°C')
|
||
push('rl', '漂洗 罐液位均值', fix(avg(this.rinse, 'level'), 2), 'm')
|
||
push('rc', '漂洗 槽浓度均值', fix(avg(this.rinse, 'conc'), 2), 'g/L')
|
||
push('re', '漂洗 槽电导率均值',fix(avg(this.rinse, 'cond'), 2), 'μS/cm')
|
||
push('rtc','漂洗 罐浓度均值', fix(avg(this.rinse, 'tank_conc'), 2), 'g/L')
|
||
push('rte','漂洗 罐电导率均值',fix(avg(this.rinse, 'tank_cond'), 2), 'μS/cm')
|
||
push('rmp', '漂洗酸雾塔 PH', fix(this.rinse_mist.ph, 2), '')
|
||
push('rms', '漂洗酸雾塔 变频器频率', fix(this.rinse_mist.vfd_speed, 1), 'Hz')
|
||
push('rmc', '漂洗酸雾塔 变频器电流', fix(this.rinse_mist.vfd_current,1),'A')
|
||
push('rcl', '漂洗冷凝水罐 液位', fix(this.rinse_cond.level, 2), 'm')
|
||
push('rct', '漂洗冷凝水罐 温度', fix(this.rinse_cond.temp, 1), '°C')
|
||
push('rcc', '漂洗冷凝水罐 电导率', fix(this.rinse_cond.cond, 2), 'μS/cm')
|
||
|
||
push('lvg', '平整机 辊缝', fix(this.leveler.gap, 2), 'mm')
|
||
push('lvf', '平整机 轧制力', fix(this.leveler.force, 0), 'kN')
|
||
push('lve', '平整机 延伸率', fix(this.leveler.elongation,2), '%')
|
||
|
||
push('dt1','烘干1段温度', fix(this.dryer.t1, 0), '°C')
|
||
push('dt2','烘干2段温度', fix(this.dryer.t2, 0), '°C')
|
||
push('dt3','烘干3段温度', fix(this.dryer.t3, 0), '°C')
|
||
|
||
return items
|
||
},
|
||
},
|
||
methods: {
|
||
toggleGroup(name) { this.groups[name] = !this.groups[name] },
|
||
filterItems(prefixes) {
|
||
if (typeof prefixes === 'string') prefixes = [prefixes]
|
||
return this.rtItems.filter(it => prefixes.some(p => it.k.startsWith(p)))
|
||
},
|
||
tick() {
|
||
this.now = Date.now()
|
||
// 模拟焊缝前进
|
||
if (this.weld.position < 1) {
|
||
this.weld.position = Math.min(1, this.weld.position + 0.005)
|
||
} else {
|
||
this.weld.position = 0
|
||
}
|
||
this.current.speed = 92 + Math.random() * 6
|
||
|
||
const wig = (o, key, amp) => { o[key] = rnd(o[key], amp) }
|
||
wig(this.uncoiler, 'tension', 0.4); wig(this.uncoiler, 'speed', 2)
|
||
wig(this.uncoiler, 'current', 6); wig(this.uncoiler, 'torque', 0.1)
|
||
wig(this.straightener, 'speed', 2); wig(this.straightener, 'current', 5)
|
||
wig(this.straightener, 'torque', 0.1)
|
||
;['br1','br2','br3'].forEach(k => {
|
||
wig(this[k], 'speed', 2); wig(this[k], 'current', 5)
|
||
wig(this[k], 'torque', 0.1)
|
||
})
|
||
this.tension_vfd.forEach(v => { wig(v, 'speed', 2); wig(v, 'current', 5); wig(v, 'torque', 0.1) })
|
||
wig(this.leveler, 'gap', 0.005); wig(this.leveler, 'force', 8); wig(this.leveler, 'elongation', 0.02)
|
||
wig(this.recoiler, 'tension', 0.4)
|
||
this.acid.forEach(a => {
|
||
wig(a, 'temp', 0.3); wig(a, 'conc', 1); wig(a, 'cond', 0.8); wig(a, 'level', 0.02)
|
||
wig(a, 'tank_conc', 1); wig(a, 'tank_cond', 0.8)
|
||
})
|
||
wig(this.acid_mist, 'ph', 0.05); wig(this.acid_mist, 'vfd_speed', 0.6); wig(this.acid_mist, 'vfd_current', 0.4)
|
||
wig(this.acid_cond, 'level', 0.02); wig(this.acid_cond, 'temp', 0.3); wig(this.acid_cond, 'cond', 0.2)
|
||
this.rinse.forEach(r => {
|
||
wig(r, 'conc', 0.05); wig(r, 'cond', 0.3); wig(r, 'level', 0.02)
|
||
wig(r, 'tank_conc', 0.05); wig(r, 'tank_cond', 0.3)
|
||
})
|
||
for (let i = 0; i < this.rinse_tank_temp.length; i++) this.rinse_tank_temp[i] = rnd(this.rinse_tank_temp[i], 0.4)
|
||
wig(this.rinse_mist, 'ph', 0.05); wig(this.rinse_mist, 'vfd_speed', 0.6); wig(this.rinse_mist, 'vfd_current', 0.4)
|
||
wig(this.rinse_cond, 'level', 0.02); wig(this.rinse_cond, 'temp', 0.3); wig(this.rinse_cond, 'cond', 0.1)
|
||
wig(this.dryer, 't1', 2); wig(this.dryer, 't2', 2); wig(this.dryer, 't3', 2)
|
||
},
|
||
},
|
||
created() {
|
||
this.tick()
|
||
this._timer = setInterval(this.tick, 2000)
|
||
},
|
||
beforeDestroy() {
|
||
if (this._timer) clearInterval(this._timer)
|
||
},
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
@import '@/assets/styles/variables';
|
||
|
||
.param-page { display: flex; flex-direction: column; gap: 10px; }
|
||
|
||
.status-bar {
|
||
display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
|
||
padding: 8px 16px;
|
||
background: $bg-card; border: 1px solid $border; border-radius: 6px;
|
||
}
|
||
.status-item { display: flex; align-items: center; gap: 6px; font-size: 12px; }
|
||
.status-item .kv-label { color: $text-muted; font-size: 11px; }
|
||
.status-item .kv-value { color: $sms-highlight; font-weight: 600; }
|
||
.status-item .kv-unit { color: $text-muted; font-size: 10px; margin-left: 2px; }
|
||
|
||
.card-body { padding: 10px 14px; }
|
||
|
||
// ─── 可折叠分组 ───
|
||
.param-group {
|
||
margin-bottom: 2px;
|
||
&:last-child { margin-bottom: 0; }
|
||
}
|
||
.pg-header {
|
||
display: flex; align-items: center; gap: 8px;
|
||
padding: 5px 8px; font-size: 12px; font-weight: 600;
|
||
color: $text-primary; background: $bg-panel;
|
||
border: 1px solid $border; border-radius: 4px;
|
||
cursor: pointer; user-select: none;
|
||
&:hover { background: darken($bg-panel, 2%); }
|
||
}
|
||
.pg-arrow { font-size: 9px; color: $text-muted; transition: transform .15s; &.open { transform: rotate(90deg); } }
|
||
.pg-badge { font-size: 10px; font-weight: 400; color: $text-muted; margin-left: 4px; }
|
||
.pg-body {
|
||
padding: 6px 8px 10px;
|
||
border: 1px solid $border; border-top: none; border-radius: 0 0 4px 4px;
|
||
}
|
||
|
||
.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: $text-primary; padding: 2px 0; }
|
||
.dg-item .lbl { color: $text-muted; flex: 1; min-width: 140px; }
|
||
.dg-item .vbox {
|
||
background: $bg-panel; border: 1px solid $border; padding: 1px 8px;
|
||
min-width: 70px; text-align: right; font-family: monospace;
|
||
color: $sms-teal; border-radius: 2px;
|
||
}
|
||
.dg-item .unit { color: $text-muted; font-size: 11px; min-width: 44px; }
|
||
|
||
.btn-xs { padding: 1px 10px; font-size: 11px; }
|
||
</style>
|