Files
klp-mono/apps/hand-factory/components/lines/acidity.vue

1323 lines
42 KiB
Vue
Raw Normal View History

2025-10-27 13:21:43 +08:00
<template>
<view class="page-container">
2025-10-29 15:38:20 +08:00
<!-- 简洁标签栏 -->
<view class="tab-container">
<view
v-for="item in tabData"
2025-10-29 15:38:20 +08:00
:key="item.value"
@click="currentTab = item.value"
class="tab-item"
:class="{ 'tab-active': currentTab === item.value }"
>
<text class="tab-label">{{ item.text }}</text>
<view class="tab-indicator" v-if="currentTab === item.value"></view>
</view>
2025-10-27 13:21:43 +08:00
</view>
<!-- 刷新按钮固定在右下角所有tab都显示 -->
<view class="refresh-btn-fixed" @click="refreshData">
<text class="refresh-icon" :class="{ 'rotating': isRefreshing }"></text>
</view>
2025-12-07 12:54:39 +08:00
<!-- 快速导航菜单固定在左下角 -->
<view class="nav-menu-fixed" :class="{ 'nav-expanded': navMenuExpanded }">
<view class="nav-toggle" @click="navMenuExpanded = !navMenuExpanded">
<text class="nav-toggle-icon">{{ navMenuExpanded ? '✕' : '☰' }}</text>
</view>
<view class="nav-items" v-if="navMenuExpanded">
<view class="nav-item" @click="scrollToSection('speed-monitor')">
<text class="nav-label">速度监控</text>
</view>
<view class="nav-item" @click="scrollToSection('exit-speed-chart')">
<text class="nav-label">出口速度趋势</text>
</view>
<view class="nav-item" @click="scrollToSection('temp-chart')">
<text class="nav-label">酸槽温度趋势</text>
</view>
<view class="nav-item" @click="scrollToSection('looper-status')">
<text class="nav-label">活套运行状态</text>
</view>
<view class="nav-item" @click="scrollToSection('tank-concentration')">
<text class="nav-label">酸槽浓度监控</text>
</view>
<view class="nav-item" @click="scrollToSection('force-chart')">
<text class="nav-label">轧制力趋势</text>
</view>
<view class="nav-item" @click="scrollToSection('process-params')">
<text class="nav-label">工艺参数</text>
</view>
<view class="nav-item" @click="scrollToSection('roll-speed')">
<text class="nav-label">轧辊速度监控</text>
</view>
<view class="nav-item" @click="scrollToSection('reduc-rate')">
<text class="nav-label">机架压下率</text>
</view>
<view class="nav-item" @click="scrollToSection('tension-monitor')">
<text class="nav-label">带钢张力监控</text>
</view>
<view class="nav-item" @click="scrollToSection('power-ratio')">
<text class="nav-label">机架功率百分比</text>
</view>
<view class="nav-item" @click="scrollToSection('paint-speed')">
<text class="nav-label">涂装速度监控</text>
</view>
<view class="nav-item" @click="scrollToSection('tlv-params')">
<text class="nav-label">拉矫参数</text>
</view>
<view class="nav-item" @click="scrollToSection('paint-temp-chart')">
<text class="nav-label">烘干温度趋势</text>
</view>
</view>
</view>
<scroll-view scroll-y class="scroll-container" v-if="currentTab === 1" :scroll-into-view="scrollIntoView">
<!-- 顶部状态栏 -->
<view class="status-bar">
<view class="status-item">
<text class="status-label">网络状态</text>
<text class="status-value" :class="'status-' + webStatus[0].value">{{ webStatus[0].value }}</text>
</view>
<view class="status-divider"></view>
<view class="status-item">
<text class="status-label">当前班组</text>
<text class="status-value">{{ webStatus[1].value }}</text>
</view>
<view class="status-divider"></view>
<view class="status-item">
<text class="status-label">更新时间</text>
<text class="status-value status-time">{{ lastUpdateTime }}</text>
2025-10-27 13:21:43 +08:00
</view>
</view>
2025-10-27 13:21:43 +08:00
<!-- 速度监控 -->
2025-12-07 12:54:39 +08:00
<view class="section" id="speed-monitor">
<view class="section-title">速度监控</view>
<view class="metrics-grid-3">
<view class="metric-box" v-for="(item, index) in speedMetrics" :key="index">
<text class="metric-name">{{ item.label }}</text>
<text class="metric-value">{{ item.value }}</text>
<text class="metric-unit">{{ item.unit }}</text>
</view>
</view>
</view>
2025-12-07 12:54:39 +08:00
<!-- 出口速度趋势 -->
<view class="section" id="exit-speed-chart">
<view class="section-title">出口速度趋势</view>
<view class="chart-box">
<qiun-data-charts type="line" :chartData="exitSpeedChartData" :opts="lineChartOpts" />
</view>
</view>
<!-- 酸槽温度趋势 -->
2025-12-07 12:54:39 +08:00
<view class="section" id="temp-chart">
<view class="section-title">酸槽温度趋势</view>
<view class="chart-box">
<qiun-data-charts type="line" :chartData="tempChartData" :opts="lineChartOpts" />
2025-10-27 13:21:43 +08:00
</view>
</view>
<!-- 活套运行状态 -->
2025-12-07 12:54:39 +08:00
<view class="section" id="looper-status">
<view class="section-title">活套运行状态</view>
<view class="metrics-grid-3">
<view class="metric-box" v-for="(item, index) in looperMetrics" :key="index">
<text class="metric-name">{{ item.label }}</text>
<text class="metric-value">{{ item.value }}</text>
<text class="metric-unit">{{ item.unit }}</text>
</view>
</view>
2025-10-27 13:21:43 +08:00
</view>
<!-- 酸槽浓度监控 -->
2025-12-07 12:54:39 +08:00
<view class="section" id="tank-concentration">
<view class="section-title">酸槽浓度监控</view>
<view class="tank-grid">
<view class="tank-card" v-for="(tank, index) in tankConcentration" :key="index">
<view class="tank-header">{{ tank.name }}</view>
<view class="tank-data">
<view class="tank-row">
<text class="data-label">酸浓度</text>
<text class="data-value">{{ tank.hclCont }} <text class="data-unit">g/L</text></text>
</view>
<view class="tank-divider"></view>
<view class="tank-row">
<text class="data-label">铁盐浓度</text>
<text class="data-value">{{ tank.feCont }} <text class="data-unit">g/L</text></text>
</view>
</view>
</view>
2025-10-27 13:21:43 +08:00
</view>
</view>
2025-12-07 12:54:39 +08:00
<!-- 轧制力趋势 -->
<view class="section" id="force-chart">
<view class="section-title">轧制力趋势</view>
<view class="chart-box">
<qiun-data-charts type="line" :chartData="forceChartData" :opts="forceLineChartOpts" />
</view>
</view>
<!-- 工艺参数 -->
2025-12-07 12:54:39 +08:00
<view class="section" id="process-params">
<view class="section-title">工艺参数</view>
<view class="metrics-grid-2">
<view class="metric-box" v-for="(item, index) in processMetrics" :key="index">
<text class="metric-name">{{ item.label }}</text>
<text class="metric-value">{{ item.value }}</text>
<text class="metric-unit">{{ item.unit }}</text>
</view>
</view>
2025-10-27 13:21:43 +08:00
</view>
2025-12-07 12:54:39 +08:00
<!-- ============ 镀锌线数据 ============ -->
<view class="section-divider">
<text class="divider-text">镀锌线监控数据</text>
</view>
<!-- 轧辊速度监控 -->
<view class="section" id="roll-speed">
<view class="section-title">轧辊速度监控</view>
<view class="metrics-grid-3">
<view class="metric-box" v-for="(item, index) in rollSpeedMetrics" :key="index">
<text class="metric-name">{{ item.label }}</text>
<text class="metric-value">{{ item.value }}</text>
<text class="metric-unit">{{ item.unit }}</text>
</view>
</view>
</view>
<!-- 机架压下率 -->
<view class="section" id="reduc-rate">
<view class="section-title">机架压下率</view>
<view class="metrics-grid-3">
<view class="metric-box" v-for="(item, index) in reducMetrics" :key="index">
<text class="metric-name">{{ item.label }}</text>
<text class="metric-value">{{ item.value }}</text>
<text class="metric-unit">{{ item.unit }}</text>
</view>
</view>
</view>
<!-- 带钢张力监控 -->
<view class="section" id="tension-monitor">
<view class="section-title">带钢张力监控</view>
<view class="metrics-grid-3">
<view class="metric-box" v-for="(item, index) in tensionMetrics" :key="index">
<text class="metric-name">{{ item.label }}</text>
<text class="metric-value">{{ item.value }}</text>
<text class="metric-unit">{{ item.unit }}</text>
</view>
</view>
</view>
<!-- 机架功率百分比 -->
<view class="section" id="power-ratio">
<view class="section-title">机架功率百分比</view>
<view class="metrics-grid-3">
<view class="metric-box" v-for="(item, index) in powerMetrics" :key="index">
<text class="metric-name">{{ item.label }}</text>
<text class="metric-value">{{ item.value }}</text>
<text class="metric-unit">{{ item.unit }}</text>
</view>
</view>
</view>
<!-- ============ 涂装线数据 ============ -->
<view class="section-divider">
<text class="divider-text">涂装线监控数据</text>
</view>
<!-- 涂装速度监控 -->
<view class="section" id="paint-speed">
<view class="section-title">涂装速度监控</view>
<view class="metrics-grid-3">
<view class="metric-box" v-for="(item, index) in paintSpeedMetrics" :key="index">
<text class="metric-name">{{ item.label }}</text>
<text class="metric-value">{{ item.value }}</text>
<text class="metric-unit">{{ item.unit }}</text>
</view>
</view>
</view>
<!-- 拉矫参数 -->
<view class="section" id="tlv-params">
<view class="section-title">拉矫参数</view>
<view class="metrics-grid-2">
<view class="metric-box" v-for="(item, index) in tlvMetrics" :key="index">
<text class="metric-name">{{ item.label }}</text>
<text class="metric-value">{{ item.value }}</text>
<text class="metric-unit">{{ item.unit }}</text>
</view>
</view>
</view>
<!-- 烘干温度趋势 -->
<view class="section" id="paint-temp-chart">
<view class="section-title">烘干温度趋势</view>
<view class="chart-box">
<qiun-data-charts type="line" :chartData="paintTempChartData" :opts="paintLineChartOpts" />
</view>
</view>
2025-10-27 13:21:43 +08:00
</scroll-view>
<scroll-view scroll-y class="scroll-container" v-if="currentTab == 2">
2025-10-27 13:21:43 +08:00
<klp-product-statistic></klp-product-statistic>
</scroll-view>
<scroll-view scroll-y class="scroll-container" v-if="currentTab == 3">
2025-10-27 13:21:43 +08:00
<klp-shutdown-statistic></klp-shutdown-statistic>
</scroll-view>
<scroll-view scroll-y class="scroll-container" v-if="currentTab == 4">
2025-10-27 13:21:43 +08:00
<klp-team-performance></klp-team-performance>
</scroll-view>
</view>
</template>
<script>
import { getAllPlantStateDefines, listPlantStateHistory, getCurrentShift } from '@/api/pocket/plantState'
import config from '@/config'
2025-10-31 14:50:19 +08:00
2025-10-27 13:21:43 +08:00
export default {
data() {
return {
currentTab: 1,
2025-10-29 15:38:20 +08:00
tabData: [
{ text: "实时监控", value: 1 },
{ text: "生产统计", value: 2 },
{ text: "停机统计", value: 3 },
{ text: "班组绩效", value: 4 }
],
2025-10-27 13:21:43 +08:00
webStatus: [
{ label: '网络状态', value: '检测中...' },
{ label: '当前班组', value: '—' }
2025-10-27 13:21:43 +08:00
],
lastUpdateTime: '—', // 最后更新时间
isRefreshing: false, // 是否正在刷新
refreshTimer: null, // 定时器
2025-12-07 12:54:39 +08:00
navMenuExpanded: false, // 导航菜单是否展开
scrollIntoView: '', // 滚动目标
// 速度监控指标ID=1,2,3
speedMetrics: [
{ label: '出口带钢速度', value: '—', unit: 'm/min' },
{ label: '酸洗带钢速度', value: '—', unit: 'm/min' },
{ label: '圆盘剪速度', value: '—', unit: 'm/min' }
2025-10-27 13:21:43 +08:00
],
// 活套状态ID=8,9,10
looperMetrics: [
{ label: '入口活套', value: '—', unit: '%' },
{ label: '出口活套', value: '—', unit: '%' },
{ label: '联机活套', value: '—', unit: '%' }
],
// 酸槽浓度ID=11-16
tankConcentration: [
{ name: '1#酸槽', hclCont: '—', feCont: '—' },
{ name: '2#酸槽', hclCont: '—', feCont: '—' },
{ name: '3#酸槽', hclCont: '—', feCont: '—' }
],
// 其他工艺参数ID=7,17,18,19,20
processMetrics: [
{ label: '漂洗温度', value: '—', unit: '°C' },
{ label: '烘干温度', value: '—', unit: '°C' },
{ label: '漂洗电导率', value: '—', unit: 'g/L' },
{ label: '联机活套张力', value: '—', unit: 'kN' },
{ label: '拉矫机延伸率', value: '—', unit: '%' }
],
2025-12-07 12:54:39 +08:00
// 镀锌线数据
rollSpeedMetrics: [
{ label: '1#机架', value: '—', unit: 'm/min' },
{ label: '2#机架', value: '—', unit: 'm/min' },
{ label: '3#机架', value: '—', unit: 'm/min' },
{ label: '4#机架', value: '—', unit: 'm/min' },
{ label: '5#机架', value: '—', unit: 'm/min' },
{ label: '6#机架', value: '—', unit: 'm/min' }
],
reducMetrics: [
{ label: '1#机架', value: '—', unit: '%' },
{ label: '2#机架', value: '—', unit: '%' },
{ label: '3#机架', value: '—', unit: '%' },
{ label: '4#机架', value: '—', unit: '%' },
{ label: '5#机架', value: '—', unit: '%' },
{ label: '6#机架', value: '—', unit: '%' }
],
tensionMetrics: [
{ label: '0#张力', value: '—', unit: 'kN' },
{ label: '1#张力', value: '—', unit: 'kN' },
{ label: '2#张力', value: '—', unit: 'kN' },
{ label: '3#张力', value: '—', unit: 'kN' },
{ label: '4#张力', value: '—', unit: 'kN' },
{ label: '5#张力', value: '—', unit: 'kN' },
{ label: '6#张力', value: '—', unit: 'kN' }
],
powerMetrics: [
{ label: '1#机架', value: '—', unit: '%' },
{ label: '2#机架', value: '—', unit: '%' },
{ label: '3#机架', value: '—', unit: '%' },
{ label: '4#机架', value: '—', unit: '%' },
{ label: '5#机架', value: '—', unit: '%' },
{ label: '6#机架', value: '—', unit: '%' }
],
// 涂装线数据
paintSpeedMetrics: [
{ label: '出口带钢速度', value: '—', unit: 'm/min' },
{ label: '涂装带钢速度', value: '—', unit: 'm/min' },
{ label: '圆盘剪速度', value: '—', unit: 'm/min' }
],
tlvMetrics: [
{ label: '拉矫延伸率', value: '—', unit: '%' },
{ label: '破磷机插入量1', value: '—', unit: 'mm' },
{ label: '破磷机插入量2', value: '—', unit: 'mm' },
{ label: '破磷机插入量3', value: '—', unit: 'mm' }
],
// 温度趋势图数据ID=4,5,6
tempChartData: {},
2025-12-07 12:54:39 +08:00
// 出口速度趋势图数据ID=1
exitSpeedChartData: {},
// 轧制力趋势图数据ID=30-35
forceChartData: {},
// 涂装线温度趋势图数据ID=4-7, 17
paintTempChartData: {},
lineChartOpts: {
color: ["#0066cc", "#409eff", "#66b1ff"],
padding: [15, 15, 0, 15],
enableScroll: false,
2025-10-31 19:10:08 +08:00
legend: {
show: true,
position: "top",
fontSize: 10,
lineHeight: 14,
itemGap: 6
},
dataLabel: false, // 隐藏数据标签
dataPointShape: false, // 隐藏数据点
xAxis: {
disableGrid: true,
2025-10-31 19:10:08 +08:00
rotateLabel: true,
itemCount: 5, // 减少标签数量
labelCount: 5,
fontSize: 10
2025-10-27 13:21:43 +08:00
},
yAxis: {
gridType: "dash",
dashLength: 4,
gridColor: "#e4e7ed",
showTitle: true,
2025-10-31 19:10:08 +08:00
fontSize: 10,
data: [{ min: 0, title: "温度(°C)" }]
2025-10-31 19:10:08 +08:00
},
extra: {
line: {
type: "curve",
width: 2,
activeType: "hollow"
}
2025-10-27 13:21:43 +08:00
}
},
2025-12-07 12:54:39 +08:00
forceLineChartOpts: {
color: ["#0066cc", "#409eff", "#66b1ff", "#a0cfff", "#d9ecff", "#ecf5ff"],
padding: [15, 15, 0, 15],
enableScroll: false,
legend: {
show: true,
position: "top",
fontSize: 10,
lineHeight: 14,
itemGap: 6
},
dataLabel: false,
dataPointShape: false,
xAxis: {
disableGrid: true,
rotateLabel: true,
itemCount: 5,
labelCount: 5,
fontSize: 10
},
yAxis: {
gridType: "dash",
dashLength: 4,
gridColor: "#e4e7ed",
showTitle: true,
fontSize: 10,
data: [{ min: 0, title: "轧制力(kN)" }]
},
extra: {
line: {
type: "curve",
width: 2,
activeType: "hollow"
}
}
},
paintLineChartOpts: {
color: ["#0066cc", "#409eff", "#66b1ff", "#a0cfff", "#d9ecff"],
padding: [15, 15, 0, 15],
enableScroll: false,
legend: {
show: true,
position: "top",
fontSize: 10,
lineHeight: 14,
itemGap: 6
},
dataLabel: false,
dataPointShape: false,
xAxis: {
disableGrid: true,
rotateLabel: true,
itemCount: 5,
labelCount: 5,
fontSize: 10
},
yAxis: {
gridType: "dash",
dashLength: 4,
gridColor: "#e4e7ed",
showTitle: true,
fontSize: 10,
data: [{ min: 0, title: "温度(°C)" }]
},
extra: {
line: {
type: "curve",
width: 2,
activeType: "hollow"
}
}
},
plantStateDefines: [] // 缓存所有的状态定义
2025-10-27 13:21:43 +08:00
};
},
mounted() {
this.loadAllData() // 加载所有数据
this.startAutoRefresh() // 启动自动刷新
},
beforeDestroy() {
this.stopAutoRefresh() // 页面销毁时清除定时器
2025-10-27 13:21:43 +08:00
},
methods: {
// 启动自动刷新每30秒
startAutoRefresh() {
this.refreshTimer = setInterval(() => {
console.log('自动刷新数据...')
this.refreshData(true) // 静默刷新
}, 30000) // 30秒刷新一次
},
// 停止自动刷新
stopAutoRefresh() {
if (this.refreshTimer) {
clearInterval(this.refreshTimer)
this.refreshTimer = null
}
},
// 加载所有数据(初始化)
loadAllData() {
this.checkNetworkStatus() // 检测网络状态
this.loadCurrentShift() // 加载当前班组
this.initPlantStateDefines() // 加载所有定义
this.updateLastTime() // 更新时间
},
// 刷新数据(手动或自动)
refreshData(isSilent = false) {
if (this.isRefreshing) return // 防止重复刷新
this.isRefreshing = true
if (!isSilent) {
uni.showLoading({ title: '刷新中' })
}
// 依次刷新各个数据
Promise.all([
this.checkNetworkStatus(),
this.loadCurrentShift(),
this.initPlantStateDefines(isSilent)
]).finally(() => {
this.isRefreshing = false
if (!isSilent) {
uni.hideLoading()
uni.showToast({ title: '刷新成功', icon: 'success', duration: 1500 })
}
this.updateLastTime()
})
},
// 更新最后刷新时间
updateLastTime() {
const now = new Date()
const hour = String(now.getHours()).padStart(2, '0')
const minute = String(now.getMinutes()).padStart(2, '0')
const second = String(now.getSeconds()).padStart(2, '0')
this.lastUpdateTime = `${hour}:${minute}:${second}`
},
// 检测网络状态
checkNetworkStatus() {
return new Promise((resolve) => {
const startTime = Date.now()
uni.request({
url: config.baseUrl + '/pocket/proPlantStateDefine/allWithValues',
method: 'GET',
timeout: 5000,
success: (res) => {
const responseTime = Date.now() - startTime
if (responseTime < 500) {
this.webStatus[0].value = '通畅'
} else if (responseTime < 2000) {
this.webStatus[0].value = '卡顿'
} else {
this.webStatus[0].value = '异常'
}
resolve()
},
fail: () => {
this.webStatus[0].value = '异常'
resolve()
}
})
})
},
// 加载当前班组信息
loadCurrentShift() {
return getCurrentShift().then(response => {
if (response.code === 200 && response.data) {
const shiftData = response.data
// 格式化班组信息显示
const shiftName = this.getShiftName(shiftData.shift)
const crewName = this.getCrewName(shiftData.crew)
this.webStatus[1].value = `${crewName} / ${shiftName}`
2025-10-31 14:50:19 +08:00
}
}).catch(error => {
console.error('加载班组信息失败:', error)
2025-10-31 14:50:19 +08:00
})
},
// 获取班次名称
getShiftName(shift) {
const shiftMap = {
'A': '早班',
'B': '中班',
'C': '晚班'
}
return shiftMap[shift] || shift || '—'
},
// 获取班组名称
getCrewName(crew) {
const crewMap = {
1: '甲',
2: '乙',
3: '丙',
4: '丁'
2025-10-31 14:50:19 +08:00
}
return crewMap[crew] || crew || '—'
},
// 初始化:加载所有状态定义及其当前值
initPlantStateDefines(isSilent = false) {
if (!isSilent) {
uni.showLoading({ title: '加载中' })
2025-10-31 14:50:19 +08:00
}
return getAllPlantStateDefines().then(response => {
if (response.code === 200 && response.data) {
this.plantStateDefines = response.data
if (!isSilent) {
console.log('状态定义已加载:', this.plantStateDefines)
}
// 更新所有实时指标
this.updateCurrentMetrics()
// 加载温度趋势图
return this.loadTempTrend(isSilent)
} else {
if (!isSilent) {
uni.hideLoading()
}
}
}).catch(error => {
if (!isSilent) {
uni.hideLoading()
}
console.error('加载状态定义失败:', error)
})
},
// 更新所有实时指标
updateCurrentMetrics() {
2025-12-07 12:54:39 +08:00
// ===== 酸轧线数据 =====
// 1. 速度监控ID=1,2,3
const exitSpeed = this.getDefineById(1)
const plSpeed = this.getDefineById(2)
const trimSpeed = this.getDefineById(3)
this.speedMetrics = [
{
label: exitSpeed?.comments || '出口带钢速度',
value: this.formatValue(exitSpeed?.currentValue),
unit: exitSpeed?.units || 'm/min'
},
{
label: plSpeed?.comments || '酸洗带钢速度',
value: this.formatValue(plSpeed?.currentValue),
unit: plSpeed?.units || 'm/min'
},
{
label: trimSpeed?.comments || '圆盘剪速度',
value: this.formatValue(trimSpeed?.currentValue),
unit: trimSpeed?.units || 'm/min'
}
]
// 2. 活套状态ID=8,9,10
const celLooper = this.getDefineById(8)
const cxlLooper = this.getDefineById(9)
const telLooper = this.getDefineById(10)
this.looperMetrics = [
{
label: celLooper?.comments || '入口活套',
value: this.formatValue(celLooper?.currentValue),
unit: celLooper?.units || '%'
},
{
label: cxlLooper?.comments || '出口活套',
value: this.formatValue(cxlLooper?.currentValue),
unit: cxlLooper?.units || '%'
},
{
label: telLooper?.comments || '联机活套',
value: this.formatValue(telLooper?.currentValue),
unit: telLooper?.units || '%'
}
]
// 3. 酸槽浓度ID=11-16
this.tankConcentration = [
{
name: '1#酸槽',
hclCont: this.formatValue(this.getDefineById(11)?.currentValue),
feCont: this.formatValue(this.getDefineById(12)?.currentValue)
},
{
name: '2#酸槽',
hclCont: this.formatValue(this.getDefineById(13)?.currentValue),
feCont: this.formatValue(this.getDefineById(14)?.currentValue)
},
{
name: '3#酸槽',
hclCont: this.formatValue(this.getDefineById(15)?.currentValue),
feCont: this.formatValue(this.getDefineById(16)?.currentValue)
}
]
// 4. 其他工艺参数ID=7,17,18,19,20
const rinseTemp = this.getDefineById(7)
const windTemp = this.getDefineById(17)
const rinseFlow = this.getDefineById(18)
const telTension = this.getDefineById(19)
const tlvElong = this.getDefineById(20)
this.processMetrics = [
{
label: rinseTemp?.comments || '漂洗温度',
value: this.formatValue(rinseTemp?.currentValue),
unit: rinseTemp?.units || '°C'
},
{
label: windTemp?.comments || '烘干温度',
value: this.formatValue(windTemp?.currentValue),
unit: windTemp?.units || '°C'
},
{
label: rinseFlow?.comments || '漂洗电导率',
value: this.formatValue(rinseFlow?.currentValue),
unit: rinseFlow?.units || 'g/L'
},
{
label: telTension?.comments || '联机活套张力',
value: this.formatValue(telTension?.currentValue),
unit: telTension?.units || 'kN'
},
{
label: tlvElong?.comments || '拉矫机延伸率',
value: this.formatValue(tlvElong?.currentValue),
unit: tlvElong?.units || '%'
}
]
2025-12-07 12:54:39 +08:00
// ===== 镀锌线数据 =====
// 1. 轧辊速度ID=36-41
this.rollSpeedMetrics = [
{ label: '1#机架', value: this.formatValue(this.getDefineById(36)?.currentValue), unit: this.getDefineById(36)?.units || 'm/min' },
{ label: '2#机架', value: this.formatValue(this.getDefineById(37)?.currentValue), unit: this.getDefineById(37)?.units || 'm/min' },
{ label: '3#机架', value: this.formatValue(this.getDefineById(38)?.currentValue), unit: this.getDefineById(38)?.units || 'm/min' },
{ label: '4#机架', value: this.formatValue(this.getDefineById(39)?.currentValue), unit: this.getDefineById(39)?.units || 'm/min' },
{ label: '5#机架', value: this.formatValue(this.getDefineById(40)?.currentValue), unit: this.getDefineById(40)?.units || 'm/min' },
{ label: '6#机架', value: this.formatValue(this.getDefineById(41)?.currentValue), unit: this.getDefineById(41)?.units || 'm/min' }
]
// 2. 机架压下率ID=24-29
this.reducMetrics = [
{ label: '1#机架', value: this.formatValue(this.getDefineById(24)?.currentValue), unit: this.getDefineById(24)?.units || '%' },
{ label: '2#机架', value: this.formatValue(this.getDefineById(25)?.currentValue), unit: this.getDefineById(25)?.units || '%' },
{ label: '3#机架', value: this.formatValue(this.getDefineById(26)?.currentValue), unit: this.getDefineById(26)?.units || '%' },
{ label: '4#机架', value: this.formatValue(this.getDefineById(27)?.currentValue), unit: this.getDefineById(27)?.units || '%' },
{ label: '5#机架', value: this.formatValue(this.getDefineById(28)?.currentValue), unit: this.getDefineById(28)?.units || '%' },
{ label: '6#机架', value: this.formatValue(this.getDefineById(29)?.currentValue), unit: this.getDefineById(29)?.units || '%' }
]
// 3. 带钢张力ID=42-48
this.tensionMetrics = [
{ label: '0#张力', value: this.formatValue(this.getDefineById(42)?.currentValue), unit: this.getDefineById(42)?.units || 'kN' },
{ label: '1#张力', value: this.formatValue(this.getDefineById(43)?.currentValue), unit: this.getDefineById(43)?.units || 'kN' },
{ label: '2#张力', value: this.formatValue(this.getDefineById(44)?.currentValue), unit: this.getDefineById(44)?.units || 'kN' },
{ label: '3#张力', value: this.formatValue(this.getDefineById(45)?.currentValue), unit: this.getDefineById(45)?.units || 'kN' },
{ label: '4#张力', value: this.formatValue(this.getDefineById(46)?.currentValue), unit: this.getDefineById(46)?.units || 'kN' },
{ label: '5#张力', value: this.formatValue(this.getDefineById(47)?.currentValue), unit: this.getDefineById(47)?.units || 'kN' },
{ label: '6#张力', value: this.formatValue(this.getDefineById(48)?.currentValue), unit: this.getDefineById(48)?.units || 'kN' }
]
// 4. 功率百分比ID=49-54
this.powerMetrics = [
{ label: '1#机架', value: this.formatValue(this.getDefineById(49)?.currentValue), unit: this.getDefineById(49)?.units || '%' },
{ label: '2#机架', value: this.formatValue(this.getDefineById(50)?.currentValue), unit: this.getDefineById(50)?.units || '%' },
{ label: '3#机架', value: this.formatValue(this.getDefineById(51)?.currentValue), unit: this.getDefineById(51)?.units || '%' },
{ label: '4#机架', value: this.formatValue(this.getDefineById(52)?.currentValue), unit: this.getDefineById(52)?.units || '%' },
{ label: '5#机架', value: this.formatValue(this.getDefineById(53)?.currentValue), unit: this.getDefineById(53)?.units || '%' },
{ label: '6#机架', value: this.formatValue(this.getDefineById(54)?.currentValue), unit: this.getDefineById(54)?.units || '%' }
]
// ===== 涂装线数据 =====
// 1. 涂装速度ID=1-3与酸轧线相同
this.paintSpeedMetrics = [
{ label: '出口带钢速度', value: this.formatValue(this.getDefineById(1)?.currentValue), unit: this.getDefineById(1)?.units || 'm/min' },
{ label: '涂装带钢速度', value: this.formatValue(this.getDefineById(2)?.currentValue), unit: this.getDefineById(2)?.units || 'm/min' },
{ label: '圆盘剪速度', value: this.formatValue(this.getDefineById(3)?.currentValue), unit: this.getDefineById(3)?.units || 'm/min' }
]
// 2. 拉矫参数ID=20-23
this.tlvMetrics = [
{ label: '拉矫延伸率', value: this.formatValue(this.getDefineById(20)?.currentValue), unit: this.getDefineById(20)?.units || '%' },
{ label: '破磷机插入量1', value: this.formatValue(this.getDefineById(21)?.currentValue), unit: this.getDefineById(21)?.units || 'mm' },
{ label: '破磷机插入量2', value: this.formatValue(this.getDefineById(22)?.currentValue), unit: this.getDefineById(22)?.units || 'mm' },
{ label: '破磷机插入量3', value: this.formatValue(this.getDefineById(23)?.currentValue), unit: this.getDefineById(23)?.units || 'mm' }
]
},
2025-12-07 12:54:39 +08:00
// 加载历史趋势图数据(温度、出口速度、轧制力)
loadTempTrend(isSilent = false) {
return listPlantStateHistory({ pageNum: 1, pageSize: 30 }).then(response => {
if (!isSilent) {
uni.hideLoading()
}
2025-10-31 14:50:19 +08:00
if (response.code === 200 && response.rows && response.rows.length > 0) {
const categories = []
const tank1Data = []
const tank2Data = []
const tank3Data = []
2025-12-07 12:54:39 +08:00
const exitSpeedData = []
const force1Data = []
const force2Data = []
const force3Data = []
const force4Data = []
const force5Data = []
const force6Data = []
// 获取定义
const tank1Temp = this.getDefineById(4)
const tank2Temp = this.getDefineById(5)
const tank3Temp = this.getDefineById(6)
2025-12-07 12:54:39 +08:00
const exitSpeed = this.getDefineById(1)
2025-10-31 14:50:19 +08:00
response.rows.forEach(item => {
const dateStr = this.formatDate(item.insdate)
categories.push(dateStr)
2025-12-07 12:54:39 +08:00
// 温度数据
tank1Data.push(Number(item.value4) || 0)
tank2Data.push(Number(item.value5) || 0)
tank3Data.push(Number(item.value6) || 0)
// 出口速度数据
exitSpeedData.push(Number(item.value1) || 0)
// 轧制力数据
force1Data.push(Number(item.value30) || 0)
force2Data.push(Number(item.value31) || 0)
force3Data.push(Number(item.value32) || 0)
force4Data.push(Number(item.value33) || 0)
force5Data.push(Number(item.value34) || 0)
force6Data.push(Number(item.value35) || 0)
2025-10-31 14:50:19 +08:00
})
2025-12-07 12:54:39 +08:00
// 温度趋势
this.tempChartData = {
categories: categories.reverse(),
2025-10-31 14:50:19 +08:00
series: [
{ name: tank1Temp?.comments || '1#酸槽温度', data: tank1Data.reverse() },
{ name: tank2Temp?.comments || '2#酸槽温度', data: tank2Data.reverse() },
{ name: tank3Temp?.comments || '3#酸槽温度', data: tank3Data.reverse() }
2025-10-31 14:50:19 +08:00
]
}
2025-12-07 12:54:39 +08:00
// 出口速度趋势
this.exitSpeedChartData = {
categories: categories,
series: [
{ name: exitSpeed?.comments || '出口带钢速度', data: exitSpeedData.reverse() }
]
}
// 轧制力趋势
this.forceChartData = {
categories: categories,
series: [
{ name: '1#轧制力', data: force1Data.reverse() },
{ name: '2#轧制力', data: force2Data.reverse() },
{ name: '3#轧制力', data: force3Data.reverse() },
{ name: '4#轧制力', data: force4Data.reverse() },
{ name: '5#轧制力', data: force5Data.reverse() },
{ name: '6#轧制力', data: force6Data.reverse() }
]
}
// 涂装线温度趋势ID=4-7, 17
const paintTemp1Data = []
const paintTemp2Data = []
const paintTemp3Data = []
const paintTemp4Data = []
const paintTemp5Data = []
response.rows.forEach(item => {
paintTemp1Data.push(Number(item.value4) || 0) // ID=4
paintTemp2Data.push(Number(item.value5) || 0) // ID=5
paintTemp3Data.push(Number(item.value6) || 0) // ID=6
paintTemp4Data.push(Number(item.value7) || 0) // ID=7
paintTemp5Data.push(Number(item.value17) || 0) // ID=17
})
this.paintTempChartData = {
categories: categories,
series: [
{ name: '1#酸槽温度', data: paintTemp1Data.reverse() },
{ name: '2#酸槽温度', data: paintTemp2Data.reverse() },
{ name: '3#酸槽温度', data: paintTemp3Data.reverse() },
{ name: '漂洗温度', data: paintTemp4Data.reverse() },
{ name: '烘干温度', data: paintTemp5Data.reverse() }
]
}
2025-10-31 14:50:19 +08:00
}
}).catch(error => {
if (!isSilent) {
uni.hideLoading()
}
2025-12-07 12:54:39 +08:00
console.error('加载历史趋势失败:', error)
})
2025-10-31 14:50:19 +08:00
},
// 根据ID获取Define对象
getDefineById(id) {
return this.plantStateDefines.find(item => item.id == id)
2025-10-31 14:50:19 +08:00
},
2025-10-31 14:50:19 +08:00
// 格式化日期
formatDate(dateStr) {
if (!dateStr) return ''
const date = new Date(dateStr)
const hour = String(date.getHours()).padStart(2, '0')
const minute = String(date.getMinutes()).padStart(2, '0')
return `${hour}:${minute}`
2025-10-27 13:21:43 +08:00
},
// 格式化数值保留2位小数
formatValue(value) {
if (value === null || value === undefined || value === '') return '—'
const num = Number(value)
if (isNaN(num)) return '—'
return num.toFixed(2)
2025-12-07 12:54:39 +08:00
},
// 滚动到指定部分
scrollToSection(sectionId) {
this.scrollIntoView = sectionId
this.navMenuExpanded = false // 点击后关闭菜单
2025-10-27 13:21:43 +08:00
}
}
};
</script>
<style scoped lang="scss">
/* 页面容器 */
.page-container {
min-height: 100vh;
background: #f5f7fa;
}
/* 标签栏 */
2025-10-29 15:38:20 +08:00
.tab-container {
display: flex;
background: #fff;
border-bottom: 2rpx solid #e4e7ed;
2025-10-27 13:21:43 +08:00
}
2025-10-29 15:38:20 +08:00
.tab-item {
flex: 1;
text-align: center;
padding: 28rpx 0;
2025-10-29 15:38:20 +08:00
position: relative;
2025-10-29 15:38:20 +08:00
.tab-label {
font-size: 28rpx;
color: #606266;
2025-10-29 15:38:20 +08:00
font-weight: 400;
}
2025-10-29 15:38:20 +08:00
&.tab-active {
.tab-label {
color: #0066cc;
font-weight: 500;
2025-10-29 15:38:20 +08:00
}
}
2025-10-29 15:38:20 +08:00
.tab-indicator {
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 60rpx;
height: 3rpx;
background: #0066cc;
2025-10-29 15:38:20 +08:00
}
2025-10-27 13:21:43 +08:00
}
/* 刷新按钮(固定在右下角) */
.refresh-btn-fixed {
position: fixed;
right: 32rpx;
bottom: 120rpx;
width: 96rpx;
height: 96rpx;
background: #0066cc;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 8rpx 20rpx rgba(0, 102, 204, 0.4);
z-index: 999;
&:active {
opacity: 0.8;
transform: scale(0.95);
}
2025-10-27 13:21:43 +08:00
}
2025-12-07 12:54:39 +08:00
/* 快速导航菜单(固定在左下角) */
.nav-menu-fixed {
position: fixed;
left: 32rpx;
bottom: 120rpx;
z-index: 998;
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 12rpx;
}
.nav-toggle {
width: 96rpx;
height: 96rpx;
background: #409eff;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 8rpx 20rpx rgba(64, 158, 255, 0.4);
transition: all 0.3s ease;
&:active {
opacity: 0.8;
transform: scale(0.95);
}
}
.nav-toggle-icon {
font-size: 48rpx;
color: #fff;
display: block;
line-height: 1;
}
.nav-items {
display: flex;
flex-direction: column;
gap: 8rpx;
animation: slideUp 0.3s ease;
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(20rpx);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.nav-item {
background: #fff;
border: 2rpx solid #409eff;
border-radius: 8rpx;
padding: 16rpx 24rpx;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 12rpx rgba(64, 158, 255, 0.2);
transition: all 0.2s ease;
&:active {
background: #f0f9ff;
transform: scale(0.95);
}
}
.nav-label {
font-size: 26rpx;
color: #409eff;
font-weight: 500;
white-space: nowrap;
}
.refresh-icon {
font-size: 48rpx;
color: #fff;
display: block;
line-height: 1;
&.rotating {
animation: rotate 1s linear infinite;
}
2025-10-27 13:21:43 +08:00
}
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
/* 滚动容器 */
.scroll-container {
height: calc(100vh - 96rpx);
padding: 24rpx;
}
/* 顶部状态栏 */
.status-bar {
2025-10-27 13:21:43 +08:00
display: flex;
align-items: center;
background: #fff;
padding: 24rpx 32rpx;
2025-10-27 13:21:43 +08:00
margin-bottom: 24rpx;
border-radius: 8rpx;
border: 1rpx solid #e4e7ed;
2025-10-27 13:21:43 +08:00
}
.status-item {
flex: 1;
2025-10-27 13:21:43 +08:00
display: flex;
align-items: center;
justify-content: center;
gap: 16rpx;
2025-10-27 13:21:43 +08:00
}
.status-label {
2025-10-29 15:38:20 +08:00
font-size: 26rpx;
color: #909399;
2025-10-27 13:21:43 +08:00
}
.status-value {
2025-10-29 15:38:20 +08:00
font-size: 28rpx;
2025-10-27 13:21:43 +08:00
font-weight: 500;
color: #303133;
2025-10-27 13:21:43 +08:00
&.status-通畅 {
color: #67c23a;
2025-10-29 15:38:20 +08:00
}
&.status-卡顿 {
color: #e6a23c;
}
&.status-异常 {
color: #f56c6c;
}
&.status-time {
color: #909399;
2025-10-27 13:21:43 +08:00
font-size: 24rpx;
}
}
.status-divider {
width: 1rpx;
height: 40rpx;
background: #e4e7ed;
}
/* 区块样式 */
.section {
margin-bottom: 24rpx;
}
.section-title {
font-size: 30rpx;
font-weight: 500;
color: #303133;
margin-bottom: 20rpx;
padding-left: 16rpx;
border-left: 4rpx solid #0066cc;
}
2025-12-07 12:54:39 +08:00
/* 分隔符 */
.section-divider {
display: flex;
align-items: center;
margin: 40rpx 0 24rpx 0;
padding: 0 16rpx;
}
.divider-text {
font-size: 28rpx;
font-weight: 600;
color: #0066cc;
padding: 0 12rpx;
background: #f5f7fa;
border-left: 4rpx solid #0066cc;
padding-left: 16rpx;
}
/* 指标卡片 - 3列布局 */
.metrics-grid-3 {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20rpx;
}
/* 指标卡片 - 2列布局 */
.metrics-grid-2 {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20rpx;
}
.metric-box {
background: #fff;
border: 1rpx solid #e4e7ed;
border-radius: 8rpx;
padding: 28rpx 20rpx;
text-align: center;
}
.metric-name {
display: block;
font-size: 24rpx;
color: #909399;
margin-bottom: 16rpx;
}
.metric-value {
display: block;
font-size: 48rpx;
2025-10-29 15:38:20 +08:00
font-weight: 600;
color: #0066cc;
margin-bottom: 8rpx;
line-height: 1;
}
.metric-unit {
display: block;
font-size: 22rpx;
color: #909399;
}
/* 图表容器 */
.chart-box {
background: #fff;
border: 1rpx solid #e4e7ed;
border-radius: 8rpx;
padding: 24rpx 16rpx;
}
/* 酸槽监控网格 */
.tank-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20rpx;
}
.tank-card {
background: #fff;
border: 2rpx solid #0066cc;
border-radius: 8rpx;
overflow: hidden;
}
.tank-header {
background: #0066cc;
color: #fff;
font-size: 28rpx;
font-weight: 500;
padding: 20rpx;
text-align: center;
}
.tank-data {
padding: 24rpx 16rpx;
}
.tank-row {
display: flex;
flex-direction: column;
align-items: center;
padding: 12rpx 0;
}
.data-label {
font-size: 22rpx;
color: #909399;
margin-bottom: 8rpx;
}
.data-value {
font-size: 36rpx;
font-weight: 600;
color: #303133;
}
.data-unit {
font-size: 20rpx;
font-weight: 400;
color: #909399;
margin-left: 4rpx;
}
.tank-divider {
height: 1rpx;
background: #e4e7ed;
margin: 12rpx 0;
2025-10-27 13:21:43 +08:00
}
</style>