feat: 新增酸轧系统实时跟踪和实绩功能
- 添加实时跟踪页面,支持查询Gauge和Shape数据 - 新增实绩页面,展示钢卷生产数据和工艺图表 - 优化钢卷追踪结果展示,增加创建步骤卷号显示 - 调整酸轧系统菜单结构,新增"实绩"和"实时"选项 - 扩展工艺图表展示,增加开卷机、温度等参数 - 修改计划列表分页大小为10 - 移除无用代码和注释
This commit is contained in:
@@ -143,7 +143,7 @@ export default {
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 6,
|
||||
pageSize: 10,
|
||||
planDate: undefined,
|
||||
lineId: undefined,
|
||||
lineName: undefined,
|
||||
|
||||
483
klp-ui/src/views/micro/pages/acid/components/Performance.vue
Normal file
483
klp-ui/src/views/micro/pages/acid/components/Performance.vue
Normal file
@@ -0,0 +1,483 @@
|
||||
<template>
|
||||
<div class="app-container" style="width: 100%; height: 100%;">
|
||||
<div class="filter-bar">
|
||||
<el-input
|
||||
v-model="queryForm.coilId"
|
||||
placeholder="热卷号 / 成品卷号"
|
||||
clearable
|
||||
size="small"
|
||||
style="width: 220px"
|
||||
@keyup.enter.native="handleSearch"
|
||||
/>
|
||||
<el-button size="small" type="primary" :loading="loading" @click="handleSearch">查询</el-button>
|
||||
<el-button size="small" @click="handleReset">重置</el-button>
|
||||
</div>
|
||||
|
||||
<el-row :gutter="12" class="main-row">
|
||||
<!-- 左侧计划列表 -->
|
||||
<el-col :span="9">
|
||||
<div class="left-card">
|
||||
<el-table
|
||||
ref="planTable"
|
||||
:data="planRows"
|
||||
size="mini"
|
||||
highlight-current-row
|
||||
:height="tableHeight"
|
||||
@row-click="handlePlanRowClick"
|
||||
>
|
||||
<el-table-column prop="hot_coilid" label="热卷号" show-overflow-tooltip />
|
||||
<el-table-column prop="coilid" label="原料卷号" show-overflow-tooltip />
|
||||
<el-table-column label="状态">
|
||||
<template slot-scope="{ row }">
|
||||
<span :class="['status-dot', statusClass(row.status)]" />
|
||||
<span class="status-text">{{ row.status || '—' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="厚×宽">
|
||||
<template slot-scope="{ row }">{{ row.entry_thick }}×{{ row.entry_width }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="exit_thick" label="出口厚" />
|
||||
<el-table-column prop="entry_weight" label="重量(t)" />
|
||||
</el-table>
|
||||
|
||||
<div class="pagination-bar">
|
||||
<el-pagination
|
||||
small
|
||||
layout="total, prev, pager, next"
|
||||
:total="pagination.total"
|
||||
:page-size="pagination.pageSize"
|
||||
:current-page="pagination.page"
|
||||
@current-change="handlePageChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
<!-- 右侧详情 + 图表 -->
|
||||
<el-col :span="15">
|
||||
<div v-if="!selectedPlan" class="empty-hint">
|
||||
<el-empty description="选择左侧计划" />
|
||||
</div>
|
||||
|
||||
<template v-else>
|
||||
<div class="detail-grid">
|
||||
<div v-for="f in planFields" :key="f.key" class="detail-cell">
|
||||
<span class="cell-label">{{ f.label }}</span>
|
||||
<span class="cell-value">{{ selectedPlan[f.key] != null ? selectedPlan[f.key] : '—' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="perf-header">
|
||||
实轧实绩
|
||||
<span v-if="hasPerfData" class="perf-count">({{ perfSegCount }} 段)</span>
|
||||
<el-tag v-if="perfLoading" size="mini" type="info" style="margin-left:8px">加载中…</el-tag>
|
||||
</div>
|
||||
|
||||
<div v-if="hasPerfData" class="charts-wrap">
|
||||
<div ref="chartSpeed" class="chart-box" />
|
||||
<div ref="chartMillSpeed" class="chart-box" />
|
||||
<div ref="chartTension" class="chart-box" />
|
||||
<div ref="chartPorSpeed" class="chart-box" />
|
||||
<div ref="chartPorTens" class="chart-box" />
|
||||
<div ref="chartTrim" class="chart-box" />
|
||||
<div ref="chartTemp" class="chart-box" />
|
||||
<div ref="chartMesh" class="chart-box" />
|
||||
<div ref="chartElong" class="chart-box" />
|
||||
</div>
|
||||
|
||||
<el-empty v-else-if="!perfLoading" description="暂无实绩数据" :image-size="56" style="margin-top: 24px" />
|
||||
</template>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
import {
|
||||
getTimingPlanList,
|
||||
getTimingPlanCount,
|
||||
getTimingPlanDetail,
|
||||
getTimingSegByEncoilId
|
||||
} from '@/api/l2/timing'
|
||||
|
||||
const PLAN_FIELDS = [
|
||||
{ key: 'status', label: '状态' },
|
||||
{ key: 'process_code', label: '工艺编码' },
|
||||
{ key: 'entry_thick', label: '入口厚度(mm)' },
|
||||
{ key: 'entry_width', label: '入口宽度(mm)' },
|
||||
{ key: 'entry_weight', label: '入口重量(t)' },
|
||||
{ key: 'exit_thick', label: '出口厚度(mm)' },
|
||||
{ key: 'exit_width', label: '出口宽度(mm)' },
|
||||
{ key: 'exit_length', label: '出口长度(m)' }
|
||||
]
|
||||
|
||||
const STATUS_CLASS = {
|
||||
READY: 'status-ready',
|
||||
ONLINE: 'status-online',
|
||||
PRODUCING: 'status-producing',
|
||||
PRODUCT: 'status-product'
|
||||
}
|
||||
|
||||
function makeLine(name, data) {
|
||||
return { name, type: 'line', smooth: true, symbol: 'none', data }
|
||||
}
|
||||
|
||||
function baseOption(title, xData, series, yName) {
|
||||
return {
|
||||
title: { text: title, textStyle: { fontSize: 12, fontWeight: 'normal' }, top: 4, left: 8 },
|
||||
tooltip: { trigger: 'axis' },
|
||||
legend: { top: 4, right: 8, textStyle: { fontSize: 11 } },
|
||||
grid: { top: 36, bottom: 28, left: 8, right: 8, containLabel: true },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: xData,
|
||||
name: 'pos(m)',
|
||||
nameTextStyle: { fontSize: 10 },
|
||||
axisLabel: { fontSize: 10 }
|
||||
},
|
||||
yAxis: { type: 'value', name: yName, nameTextStyle: { fontSize: 10 }, axisLabel: { fontSize: 10 } },
|
||||
series
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'TimingAcidPage',
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
perfLoading: false,
|
||||
queryForm: { coilId: '' },
|
||||
planRows: [],
|
||||
selectedPlan: null,
|
||||
perfSeries: null,
|
||||
perfSegCount: 0,
|
||||
planFields: PLAN_FIELDS,
|
||||
pagination: { page: 1, pageSize: 50, total: 0 },
|
||||
tableHeight: 'calc(100vh - 210px)'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
hasPerfData() {
|
||||
return this.perfSeries && this.perfSegCount > 0
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// plain instance property — Vue 2 does NOT proxy underscore-prefixed names
|
||||
this.chartInstances = []
|
||||
this.resizeHandler = null
|
||||
this.loadPlanCount()
|
||||
this.loadPlanList()
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.disposeCharts()
|
||||
},
|
||||
methods: {
|
||||
statusClass(status) {
|
||||
return STATUS_CLASS[status] || 'status-default'
|
||||
},
|
||||
async loadPlanCount() {
|
||||
try {
|
||||
const res = await getTimingPlanCount()
|
||||
this.pagination.total = res?.data?.total ?? 0
|
||||
} catch (_) {}
|
||||
},
|
||||
async loadPlanList() {
|
||||
this.loading = true
|
||||
try {
|
||||
const { page, pageSize } = this.pagination
|
||||
const res = await getTimingPlanList(page, pageSize)
|
||||
this.planRows = res?.data?.rows || []
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
handlePageChange(page) {
|
||||
this.pagination.page = page
|
||||
this.loadPlanList()
|
||||
},
|
||||
async handleSearch() {
|
||||
if (!this.queryForm.coilId) return this.loadPlanList()
|
||||
this.loading = true
|
||||
try {
|
||||
const res = await getTimingPlanDetail(this.queryForm.coilId)
|
||||
const row = res?.data?.firstRow || null
|
||||
if (row) {
|
||||
this.selectedPlan = row
|
||||
await this.loadPerf(row)
|
||||
}
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
async handlePlanRowClick(row) {
|
||||
this.selectedPlan = row
|
||||
this.perfSeries = null
|
||||
this.perfSegCount = 0
|
||||
this.disposeCharts()
|
||||
await this.loadPerf(row)
|
||||
},
|
||||
async loadPerf(plan) {
|
||||
const encoilId = plan.encoilid || plan.coilid
|
||||
if (!encoilId) return
|
||||
this.perfLoading = true
|
||||
try {
|
||||
const res = await getTimingSegByEncoilId(encoilId)
|
||||
const keys = Object.keys(res?.data?.series || {})
|
||||
console.log(keys)
|
||||
|
||||
const series = res?.data?.series || null
|
||||
const rows = res?.data?.rows || []
|
||||
this.perfSegCount = rows.length
|
||||
this.perfSeries = series
|
||||
if (series && rows.length) {
|
||||
await this.$nextTick()
|
||||
this.renderCharts(series)
|
||||
}
|
||||
} catch (_) {
|
||||
this.perfSeries = null
|
||||
this.perfSegCount = 0
|
||||
} finally {
|
||||
this.perfLoading = false
|
||||
}
|
||||
},
|
||||
disposeCharts() {
|
||||
if (this.resizeHandler) {
|
||||
window.removeEventListener('resize', this.resizeHandler)
|
||||
this.resizeHandler = null
|
||||
}
|
||||
if (this.chartInstances && this.chartInstances.length) {
|
||||
this.chartInstances.forEach(c => { if (c) c.dispose() })
|
||||
this.chartInstances = []
|
||||
}
|
||||
},
|
||||
renderCharts(series) {
|
||||
this.disposeCharts()
|
||||
const pick = key => (series[key] || []).map(v => v == null ? null : Number(v).toFixed(2))
|
||||
const xData = (series.startpos || []).map(v => v == null ? '' : Number(v).toFixed(1))
|
||||
|
||||
const c1 = echarts.init(this.$refs.chartSpeed)
|
||||
c1.setOption(baseOption(
|
||||
'速度趋势 (m/min)', xData,
|
||||
[
|
||||
makeLine('轧制速度 plspeed', pick('plspeed')),
|
||||
makeLine('剪切速度 trimspeed', pick('trimspeed'))
|
||||
],
|
||||
'm/min'
|
||||
))
|
||||
|
||||
const c2 = echarts.init(this.$refs.chartMillSpeed)
|
||||
c2.setOption(baseOption(
|
||||
'轧机速度 (m/min)', xData,
|
||||
[
|
||||
makeLine('入口速度 millentryspeed', pick('millentryspeed')),
|
||||
makeLine('出口速度 millexitspeed', pick('millexitspeed'))
|
||||
],
|
||||
'm/min'
|
||||
))
|
||||
|
||||
const c3 = echarts.init(this.$refs.chartTension)
|
||||
c3.setOption(baseOption(
|
||||
'张力趋势 (N)', xData,
|
||||
[
|
||||
makeLine('出口张力 pltens', pick('pltens')),
|
||||
makeLine('入口张力 enltens', pick('enltens')),
|
||||
makeLine('cxltens', pick('cxltens'))
|
||||
],
|
||||
'N'
|
||||
))
|
||||
|
||||
const c4 = echarts.init(this.$refs.chartPorSpeed)
|
||||
c4.setOption(baseOption(
|
||||
'开卷机速度 (m/min)', xData,
|
||||
[
|
||||
makeLine('开卷速度 porspeed', pick('porspeed')),
|
||||
makeLine('最大 porspeedmax', pick('porspeedmax')),
|
||||
makeLine('最小 porspeedmin', pick('porspeedmin'))
|
||||
],
|
||||
'm/min'
|
||||
))
|
||||
|
||||
const c5 = echarts.init(this.$refs.chartPorTens)
|
||||
c5.setOption(baseOption(
|
||||
'开卷机张力 (N)', xData,
|
||||
[
|
||||
makeLine('开卷张力 portens', pick('portens')),
|
||||
makeLine('最大 portensmax', pick('portensmax')),
|
||||
makeLine('最小 portensmin', pick('portensmin'))
|
||||
],
|
||||
'N'
|
||||
))
|
||||
|
||||
const c6 = echarts.init(this.$refs.chartTrim)
|
||||
c6.setOption(baseOption(
|
||||
'剪切参数', xData,
|
||||
[
|
||||
makeLine('剪切张力 trimtens', pick('trimtens')),
|
||||
makeLine('剪切宽度 trimwidth', pick('trimwidth')),
|
||||
makeLine('trtens', pick('trtens'))
|
||||
],
|
||||
''
|
||||
))
|
||||
|
||||
const c7 = echarts.init(this.$refs.chartTemp)
|
||||
c7.setOption(baseOption(
|
||||
'温度趋势 (℃)', xData,
|
||||
[
|
||||
makeLine('1号测温 tk1temp', pick('tk1temp')),
|
||||
makeLine('2号测温 tk2temp', pick('tk2temp')),
|
||||
makeLine('3号测温 tk3temp', pick('tk3temp')),
|
||||
makeLine('4号测温 tk4temp', pick('tk4temp')),
|
||||
makeLine('漂洗温度 rinsetemp', pick('rinsetemp'))
|
||||
],
|
||||
'℃'
|
||||
))
|
||||
|
||||
const c8 = echarts.init(this.$refs.chartMesh)
|
||||
c8.setOption(baseOption(
|
||||
'轧辊参数', xData,
|
||||
[
|
||||
makeLine('轧辊1 tlmesh1', pick('tlmesh1')),
|
||||
makeLine('轧辊2 tlmesh2', pick('tlmesh2')),
|
||||
makeLine('轧辊3 tlmesh3', pick('tlmesh3'))
|
||||
],
|
||||
''
|
||||
))
|
||||
|
||||
const c9 = echarts.init(this.$refs.chartElong)
|
||||
c9.setOption(baseOption(
|
||||
'延伸率', xData,
|
||||
[
|
||||
makeLine('延伸率 tlelong', pick('tlelong')),
|
||||
makeLine('总张力 tltens', pick('tltens')),
|
||||
makeLine('teltens', pick('teltens'))
|
||||
],
|
||||
''
|
||||
))
|
||||
|
||||
this.chartInstances = [c1, c2, c3, c4, c5, c6, c7, c8, c9]
|
||||
this.resizeHandler = () => this.chartInstances.forEach(c => { if (c) c.resize() })
|
||||
window.addEventListener('resize', this.resizeHandler)
|
||||
},
|
||||
handleReset() {
|
||||
this.queryForm.coilId = ''
|
||||
this.selectedPlan = null
|
||||
this.perfSeries = null
|
||||
this.perfSegCount = 0
|
||||
this.disposeCharts()
|
||||
this.pagination.page = 1
|
||||
this.loadPlanList()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.filter-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.main-row {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.left-card {
|
||||
background: #fff;
|
||||
border: 1px solid #ebeef5;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.empty-hint {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding-top: 80px;
|
||||
}
|
||||
|
||||
.pagination-bar {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 6px 8px;
|
||||
border-top: 1px solid #ebeef5;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.detail-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
border-top: 1px solid #ebeef5;
|
||||
border-left: 1px solid #ebeef5;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.detail-cell {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 8px 10px;
|
||||
border-right: 1px solid #ebeef5;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
}
|
||||
|
||||
.cell-label {
|
||||
font-size: 11px;
|
||||
color: #909399;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.cell-value {
|
||||
font-size: 13px;
|
||||
color: #303133;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.perf-header {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: #606266;
|
||||
margin-bottom: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.perf-count {
|
||||
font-weight: normal;
|
||||
color: #909399;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.charts-wrap {
|
||||
/* display: flex; */
|
||||
/* flex-direction: column;
|
||||
gap: 12px; */
|
||||
overflow-y: auto;
|
||||
max-height: calc(100vh - 310px);
|
||||
}
|
||||
|
||||
.chart-box {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
/* 状态指示点 */
|
||||
.status-dot {
|
||||
display: inline-block;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-radius: 50%;
|
||||
margin-right: 4px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.status-text {
|
||||
font-size: 8px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.status-ready { background: #909399; }
|
||||
.status-online { background: #67c23a; }
|
||||
.status-producing { background: #e6a23c; }
|
||||
.status-product { background: #409eff; }
|
||||
.status-default { background: #c0c4cc; }
|
||||
</style>
|
||||
@@ -16,18 +16,31 @@
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="钢卷判级" name="gradeCoil">
|
||||
<div class="tab-content" v-if="activeTab === 'gradeCoil'">
|
||||
<el-tab-pane label="次品钢卷" name="defect">
|
||||
<div class="tab-content" v-if="activeTab === 'defect'">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="{
|
||||
dataType: 0,
|
||||
status: 1,
|
||||
dataType: 1,
|
||||
OnlyScrap: true,
|
||||
}"
|
||||
:hideType="false"
|
||||
:useWarehouseIds="useWarehouseIds"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="showMaterialType"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="O卷" name="oil">
|
||||
<div class="tab-content" v-if="activeTab === 'oil'">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="{
|
||||
dataType: 1,
|
||||
status: 0,
|
||||
qualityStatus: 'O'
|
||||
}"
|
||||
:hideType="false"
|
||||
:showControl="false"
|
||||
:showGrade="true"
|
||||
:showStatus="false"
|
||||
:useWarehouseIds="useWarehouseIds"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="showMaterialType"
|
||||
|
||||
103
klp-ui/src/views/micro/pages/acid/components/RealTime.vue
Normal file
103
klp-ui/src/views/micro/pages/acid/components/RealTime.vue
Normal file
@@ -0,0 +1,103 @@
|
||||
<template>
|
||||
<div class="timing-page realtime-page">
|
||||
<el-card shadow="never" class="page-card">
|
||||
<div slot="header" class="card-header">
|
||||
<span>实时跟踪页</span>
|
||||
<el-tag type="warning" size="mini">Gauge + Shape</el-tag>
|
||||
</div>
|
||||
|
||||
<el-form :inline="true" :model="queryForm" size="mini" class="query-form">
|
||||
<el-form-item label="MATID">
|
||||
<el-input v-model="queryForm.matId" placeholder="输入 MATID" clearable style="width: 240px;" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-refresh" :loading="loading" @click="handleQuery">获取实时数据</el-button>
|
||||
<el-button icon="el-icon-delete" @click="handleReset">清空</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-empty v-if="!realtimeData" description="请输入 MATID 后查询实时数据" />
|
||||
|
||||
<template v-else>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-card shadow="never" class="sub-card">
|
||||
<div slot="header">Gauge 厚度数据</div>
|
||||
<el-table :data="gaugeRows" size="mini" height="520" border>
|
||||
<el-table-column prop="XTIME" label="XTIME" width="120" />
|
||||
<el-table-column prop="XLOCATION" label="XLOCATION" width="100" />
|
||||
<el-table-column prop="THICK0" label="THICK0" width="90" />
|
||||
<el-table-column prop="THICK1" label="THICK1" width="90" />
|
||||
<el-table-column prop="THICK4" label="THICK4" width="90" />
|
||||
<el-table-column prop="THICK5" label="THICK5" width="90" />
|
||||
<el-table-column prop="EXIT_SPEED" label="EXIT_SPEED" width="100" />
|
||||
</el-table>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-card shadow="never" class="sub-card">
|
||||
<div slot="header">Shape 板形数据</div>
|
||||
<el-table :data="shapeRows" size="mini" height="520" border>
|
||||
<el-table-column prop="XTIME" label="XTIME" width="120" />
|
||||
<el-table-column prop="XLOCATION" label="XLOCATION" width="100" />
|
||||
<el-table-column prop="HIGHZONEID" label="HIGHZONEID" width="100" />
|
||||
<el-table-column prop="LOWZONEID" label="LOWZONEID" width="100" />
|
||||
<el-table-column prop="EXIT_SPEED" label="EXIT_SPEED" width="100" />
|
||||
<el-table-column prop="ROLLFORCE" label="ROLLFORCE" width="100" />
|
||||
<el-table-column prop="ABSDEVIATION" label="ABSDEVIATION" width="110" />
|
||||
</el-table>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getTimingRealtimeData } from '@/api/l2/timing'
|
||||
|
||||
export default {
|
||||
name: 'TimingRealtimePage',
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
queryForm: { matId: '' },
|
||||
realtimeData: null,
|
||||
gaugeRows: [],
|
||||
shapeRows: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async handleQuery() {
|
||||
if (!this.queryForm.matId) {
|
||||
this.$message.warning('请输入 MATID')
|
||||
return
|
||||
}
|
||||
this.loading = true
|
||||
try {
|
||||
const res = await getTimingRealtimeData(this.queryForm.matId)
|
||||
this.realtimeData = res && res.data ? res.data : res
|
||||
this.gaugeRows = this.realtimeData && this.realtimeData.gauge ? this.realtimeData.gauge.result || [] : []
|
||||
this.shapeRows = this.realtimeData && this.realtimeData.shape ? this.realtimeData.shape.result || [] : []
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
handleReset() {
|
||||
this.queryForm.matId = ''
|
||||
this.realtimeData = null
|
||||
this.gaugeRows = []
|
||||
this.shapeRows = []
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.timing-page { padding: 16px; }
|
||||
.page-card { border-radius: 12px; }
|
||||
.card-header { display: flex; align-items: center; justify-content: space-between; font-weight: 600; }
|
||||
.query-form { margin-bottom: 12px; }
|
||||
.sub-card { border-radius: 10px; }
|
||||
</style>
|
||||
@@ -12,7 +12,7 @@
|
||||
</el-menu-item>
|
||||
<el-menu-item index="processing">
|
||||
<i class="el-icon-s-operation"></i>
|
||||
<span slot="title">加工</span>
|
||||
<span slot="title">WIP</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="report">
|
||||
<i class="el-icon-document"></i>
|
||||
@@ -26,9 +26,17 @@
|
||||
<i class="el-icon-warning-outline"></i>
|
||||
<span slot="title">品质</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="performance">
|
||||
<i class="el-icon-coin"></i>
|
||||
<span slot="title">实绩</span>
|
||||
</el-menu-item>
|
||||
<!-- <el-menu-item index="realTime">
|
||||
<i class="el-icon-time"></i>
|
||||
<span slot="title">实时</span>
|
||||
</el-menu-item> -->
|
||||
</el-menu>
|
||||
</div>
|
||||
<div>
|
||||
<div style="flex: 1;">
|
||||
<component :is="currentComponent" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -40,6 +48,8 @@ import Processing from './components/Processing.vue';
|
||||
import Report from './components/Report.vue';
|
||||
import Shipping from './components/Shipping.vue';
|
||||
import Quality from './components/Quality.vue';
|
||||
import Performance from './components/Performance.vue';
|
||||
import RealTime from './components/RealTime.vue';
|
||||
|
||||
export default {
|
||||
name: 'AcidSystem',
|
||||
@@ -49,6 +59,8 @@ export default {
|
||||
Report,
|
||||
Shipping,
|
||||
Quality,
|
||||
Performance,
|
||||
RealTime
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -63,6 +75,8 @@ export default {
|
||||
report: 'Report',
|
||||
shipping: 'Shipping',
|
||||
quality: 'Quality',
|
||||
performance: 'Performance',
|
||||
realTime: 'RealTime',
|
||||
};
|
||||
return componentMap[this.activeMenu];
|
||||
},
|
||||
|
||||
@@ -293,10 +293,6 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.acid-view {
|
||||
padding: 12px 16px;
|
||||
}
|
||||
|
||||
.filter-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -62,33 +62,33 @@
|
||||
{value: '1988150380649967617', label: '镀锌分条成品'},
|
||||
{value: '1988151027466170370', label: '拉矫分条成品'},
|
||||
],
|
||||
'酸轧修复工序': [
|
||||
{value: '1988150044862377986', label: '酸连轧原料库'},
|
||||
{value: '1988150099140866050', label: '酸连轧成品库'},
|
||||
{value: '1988150263284953089', label: '镀锌原料库'},
|
||||
{value: '1988150545175736322', label: '脱脂原料库'},
|
||||
],
|
||||
'镀锌修复工序': [
|
||||
{value: '1988150263284953089', label: '镀锌原料库'},
|
||||
{value: '1988150323162836993', label: '镀锌成品库'},
|
||||
{value: '1988150487185289217', label: '镀锌纵剪分条原料库'},
|
||||
],
|
||||
'脱脂修复工序': [
|
||||
{value: '1988150545175736322', label: '脱脂原料库'},
|
||||
{value: '1988150586938421250', label: '脱脂成品库'},
|
||||
],
|
||||
'拉矫修复工序': [
|
||||
{value: '1988150854442741762', label: '拉矫原料库'},
|
||||
{value: '1988150915591499777', label: '拉矫成品库'},
|
||||
],
|
||||
'双机架修复工序': [
|
||||
{value: '1992873386047643650', label: '双机架原料库'},
|
||||
{value: '1992873437713080322', label: '双机架成品库'},
|
||||
],
|
||||
'镀铬修复工序': [
|
||||
{value: '1988151076996706306', label: '镀铬原料库'},
|
||||
{value: '1988151132361519105', label: '镀铬成品库'},
|
||||
],
|
||||
// '酸轧修复工序': [
|
||||
// {value: '1988150044862377986', label: '酸连轧原料库'},
|
||||
// {value: '1988150099140866050', label: '酸连轧成品库'},
|
||||
// {value: '1988150263284953089', label: '镀锌原料库'},
|
||||
// {value: '1988150545175736322', label: '脱脂原料库'},
|
||||
// ],
|
||||
// '镀锌修复工序': [
|
||||
// {value: '1988150263284953089', label: '镀锌原料库'},
|
||||
// {value: '1988150323162836993', label: '镀锌成品库'},
|
||||
// {value: '1988150487185289217', label: '镀锌纵剪分条原料库'},
|
||||
// ],
|
||||
// '脱脂修复工序': [
|
||||
// {value: '1988150545175736322', label: '脱脂原料库'},
|
||||
// {value: '1988150586938421250', label: '脱脂成品库'},
|
||||
// ],
|
||||
// '拉矫修复工序': [
|
||||
// {value: '1988150854442741762', label: '拉矫原料库'},
|
||||
// {value: '1988150915591499777', label: '拉矫成品库'},
|
||||
// ],
|
||||
// '双机架修复工序': [
|
||||
// {value: '1992873386047643650', label: '双机架原料库'},
|
||||
// {value: '1992873437713080322', label: '双机架成品库'},
|
||||
// ],
|
||||
// '镀铬修复工序': [
|
||||
// {value: '1988151076996706306', label: '镀铬原料库'},
|
||||
// {value: '1988151132361519105', label: '镀铬成品库'},
|
||||
// ],
|
||||
}
|
||||
|
||||
if (
|
||||
|
||||
@@ -741,6 +741,12 @@
|
||||
<div ref="chartSpeed" class="chart-box" />
|
||||
<div ref="chartMillSpeed" class="chart-box" />
|
||||
<div ref="chartTension" class="chart-box" />
|
||||
<div ref="chartPorSpeed" class="chart-box" />
|
||||
<div ref="chartPorTens" class="chart-box" />
|
||||
<div ref="chartTrim" class="chart-box" />
|
||||
<div ref="chartTemp" class="chart-box" />
|
||||
<div ref="chartMesh" class="chart-box" />
|
||||
<div ref="chartElong" class="chart-box" />
|
||||
</div>
|
||||
<el-empty v-else-if="!perfLoading" description="暂无生产工艺数据" :image-size="56" style="margin-top: 24px" />
|
||||
</div>
|
||||
@@ -1223,8 +1229,11 @@ export default {
|
||||
|
||||
const c2 = echarts.init(this.$refs.chartMillSpeed);
|
||||
c2.setOption(this.baseOption(
|
||||
'轧机出口速度 (m/min)', xData,
|
||||
[this.makeLine('millexitspeed', pick('millexitspeed'))],
|
||||
'轧机速度 (m/min)', xData,
|
||||
[
|
||||
this.makeLine('入口速度 millentryspeed', pick('millentryspeed')),
|
||||
this.makeLine('出口速度 millexitspeed', pick('millexitspeed'))
|
||||
],
|
||||
'm/min'
|
||||
));
|
||||
|
||||
@@ -1239,7 +1248,88 @@ export default {
|
||||
'N'
|
||||
));
|
||||
|
||||
this.chartInstances = [c1, c2, c3];
|
||||
let c4, c5, c6, c7, c8, c9;
|
||||
if (this.$refs.chartPorSpeed) {
|
||||
c4 = echarts.init(this.$refs.chartPorSpeed);
|
||||
c4.setOption(this.baseOption(
|
||||
'开卷机速度 (m/min)', xData,
|
||||
[
|
||||
this.makeLine('开卷速度 porspeed', pick('porspeed')),
|
||||
this.makeLine('最大 porspeedmax', pick('porspeedmax')),
|
||||
this.makeLine('最小 porspeedmin', pick('porspeedmin'))
|
||||
],
|
||||
'm/min'
|
||||
));
|
||||
}
|
||||
|
||||
if (this.$refs.chartPorTens) {
|
||||
c5 = echarts.init(this.$refs.chartPorTens);
|
||||
c5.setOption(this.baseOption(
|
||||
'开卷机张力 (N)', xData,
|
||||
[
|
||||
this.makeLine('开卷张力 portens', pick('portens')),
|
||||
this.makeLine('最大 portensmax', pick('portensmax')),
|
||||
this.makeLine('最小 portensmin', pick('portensmin'))
|
||||
],
|
||||
'N'
|
||||
));
|
||||
}
|
||||
|
||||
if (this.$refs.chartTrim) {
|
||||
c6 = echarts.init(this.$refs.chartTrim);
|
||||
c6.setOption(this.baseOption(
|
||||
'剪切参数', xData,
|
||||
[
|
||||
this.makeLine('剪切张力 trimtens', pick('trimtens')),
|
||||
this.makeLine('剪切宽度 trimwidth', pick('trimwidth')),
|
||||
this.makeLine('trtens', pick('trtens'))
|
||||
],
|
||||
''
|
||||
));
|
||||
}
|
||||
|
||||
if (this.$refs.chartTemp) {
|
||||
c7 = echarts.init(this.$refs.chartTemp);
|
||||
c7.setOption(this.baseOption(
|
||||
'温度趋势 (℃)', xData,
|
||||
[
|
||||
this.makeLine('1号测温 tk1temp', pick('tk1temp')),
|
||||
this.makeLine('2号测温 tk2temp', pick('tk2temp')),
|
||||
this.makeLine('3号测温 tk3temp', pick('tk3temp')),
|
||||
this.makeLine('4号测温 tk4temp', pick('tk4temp')),
|
||||
this.makeLine('漂洗温度 rinsetemp', pick('rinsetemp'))
|
||||
],
|
||||
'℃'
|
||||
));
|
||||
}
|
||||
|
||||
if (this.$refs.chartMesh) {
|
||||
c8 = echarts.init(this.$refs.chartMesh);
|
||||
c8.setOption(this.baseOption(
|
||||
'网纹辊参数', xData,
|
||||
[
|
||||
this.makeLine('网纹辊1 tlmesh1', pick('tlmesh1')),
|
||||
this.makeLine('网纹辊2 tlmesh2', pick('tlmesh2')),
|
||||
this.makeLine('网纹辊3 tlmesh3', pick('tlmesh3'))
|
||||
],
|
||||
''
|
||||
));
|
||||
}
|
||||
|
||||
if (this.$refs.chartElong) {
|
||||
c9 = echarts.init(this.$refs.chartElong);
|
||||
c9.setOption(this.baseOption(
|
||||
'延伸率', xData,
|
||||
[
|
||||
this.makeLine('延伸率 tlelong', pick('tlelong')),
|
||||
this.makeLine('总张力 tltens', pick('tltens')),
|
||||
this.makeLine('teltens', pick('teltens'))
|
||||
],
|
||||
''
|
||||
));
|
||||
}
|
||||
|
||||
this.chartInstances = [c1, c2, c3, c4, c5, c6, c7, c8, c9].filter(c => c);
|
||||
this.resizeHandler = () => this.chartInstances.forEach(c => { if (c) c.resize(); });
|
||||
window.addEventListener('resize', this.resizeHandler);
|
||||
},
|
||||
|
||||
@@ -27,6 +27,12 @@
|
||||
<el-col :span="16" class="detail-value">{{ step.time }}</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 新增步骤专属显示卷号 -->
|
||||
<el-row class="detail-row" v-if="step.action === '创建'">
|
||||
<el-col :span="8" class="detail-label">卷号:</el-col>
|
||||
<el-col :span="16" class="detail-value">{{ step.original.current_coil_no }}</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 旧钢卷关键信息(操作前)- 新增优化:展示核心字段,hover弹窗更多信息 -->
|
||||
<el-row class="detail-row" v-if="step.oldCoilInfoList && step.oldCoilInfoList.length">
|
||||
<el-col :span="8" class="detail-label">操作前钢卷:</el-col>
|
||||
|
||||
@@ -162,8 +162,6 @@ const DICT_SPEC_TYPE = 'wms_process_spec_type'
|
||||
const DICT_LINE = 'wms_process_spec_line'
|
||||
|
||||
const DEFAULT_SPEC_TYPES = [
|
||||
{ dictLabel: '工艺规程', dictValue: 'PROCESS', dictSort: 10 },
|
||||
{ dictLabel: '标准', dictValue: 'STANDARD', dictSort: 20 }
|
||||
]
|
||||
|
||||
export default {
|
||||
@@ -303,19 +301,19 @@ export default {
|
||||
}
|
||||
|
||||
let tableLines = []
|
||||
try {
|
||||
const res = await listProductionLine({ pageNum: 1, pageSize: 500 })
|
||||
tableLines = (res.rows || []).map(p => {
|
||||
const idStr = this.normalizeLineIdString(p.lineId) || (p.lineId != null ? String(p.lineId).trim() : '')
|
||||
return {
|
||||
lineId: idStr,
|
||||
lineName: p.lineName,
|
||||
lineCode: p.lineCode
|
||||
}
|
||||
}).filter(p => p.lineId)
|
||||
} catch (e2) {
|
||||
console.error('产线列表加载失败', e2)
|
||||
}
|
||||
// try {
|
||||
// const res = await listProductionLine({ pageNum: 1, pageSize: 500 })
|
||||
// tableLines = (res.rows || []).map(p => {
|
||||
// const idStr = this.normalizeLineIdString(p.lineId) || (p.lineId != null ? String(p.lineId).trim() : '')
|
||||
// return {
|
||||
// lineId: idStr,
|
||||
// lineName: p.lineName,
|
||||
// lineCode: p.lineCode
|
||||
// }
|
||||
// }).filter(p => p.lineId)
|
||||
// } catch (e2) {
|
||||
// console.error('产线列表加载失败', e2)
|
||||
// }
|
||||
|
||||
const tableIdSet = new Set(tableLines.map(l => String(l.lineId)))
|
||||
const next = []
|
||||
|
||||
Reference in New Issue
Block a user