diff --git a/src/router/index.ts b/src/router/index.ts index f073730..71d78ce 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -267,6 +267,45 @@ export const constantRoutes: RouteRecordRaw[] = [ meta: { title: '反向追溯详情', activeMenu: '/mes/mixTrace/show/backward1', noCache: true } } ] + }, + { + path: '/mes/mixTrace/show/tire1', + component: Layout, + hidden: true, + children: [ + { + path: '', + component: () => import('@/views/mes/mixTrace/show/tire1.vue'), + name: 'MixTraceTire1', + meta: { title: '轮胎全程追溯', activeMenu: '/mes/mixTrace/show', noCache: true } + } + ] + }, + { + path: '/mes/mixTrace/show/tire2', + component: Layout, + hidden: true, + children: [ + { + path: '', + component: () => import('@/views/mes/mixTrace/show/tire2.vue'), + name: 'MixTraceTire2', + meta: { title: '轮胎详情', activeMenu: '/mes/mixTrace/show/tire1', noCache: true } + } + ] + }, + { + path: '/mes/mixTrace/show/forward1', + component: Layout, + hidden: true, + children: [ + { + path: '', + component: () => import('@/views/mes/mixTrace/show/forward1.vue'), + name: 'MixTraceForward1', + meta: { title: '正向追溯', activeMenu: '/mes/mixTrace/show', noCache: true } + } + ] } ]; diff --git a/src/views/mes/mixTrace/show/backward2.vue b/src/views/mes/mixTrace/show/backward2.vue index c39f3d8..f0e1fc4 100644 --- a/src/views/mes/mixTrace/show/backward2.vue +++ b/src/views/mes/mixTrace/show/backward2.vue @@ -4,6 +4,7 @@ 追溯结构 + 返回列表 import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue'; -import { useRoute } from 'vue-router'; +import { useRoute, useRouter } from 'vue-router'; import { ArrowRight, Document, Folder } from '@element-plus/icons-vue'; import { ElMessage } from 'element-plus'; import * as echarts from 'echarts'; @@ -191,6 +192,7 @@ import backwardData from './data/backward2.json'; type BarcodeType = '1' | '2' | '3' | '4'; const route = useRoute(); +const router = useRouter(); const detailMap = (backwardData as any).detailMap || {}; const detailKeys = Object.keys(detailMap); @@ -208,6 +210,14 @@ const treeRef = ref(); const chartRef = ref(); let chartInstance: echarts.ECharts | null = null; +const goBack = () => { + if (window.history.length > 1) { + router.back(); + return; + } + router.push('/mes/mixTrace/show/backward1'); +}; + const productionInfo = computed(() => { return detailMap[detailId.value]?.production || {}; }); @@ -258,7 +268,86 @@ const loadData = () => { const initChart = () => { if (!chartRef.value) return; const cd = curveDataSource.value; - const xAxisData = cd.mixingTime || []; + const mixingRows = Array.isArray(mixingProcessData.value) ? mixingProcessData.value : []; + + const toNumberOrNull = (value: any): number | null => { + const num = Number(value); + return Number.isFinite(num) ? num : null; + }; + + const listLength = (value: any): number => { + return Array.isArray(value) ? value.length : 0; + }; + + const buildPositionFromAction = (row: any): number | null => { + const actionText = String(row?.action || row?.condition || ''); + if (actionText.includes('压上顶栓')) return 1; + if (actionText.includes('升上顶栓')) return 0; + return null; + }; + + let xAxisData: Array = []; + let temperatureData: Array = []; + let powerData: Array = []; + let energyData: Array = []; + let pressureData: Array = []; + let speedData: Array = []; + let positionData: Array = []; + + if (mixingRows.length > 0) { + xAxisData = mixingRows.map((row: any, idx: number) => row.step ?? idx + 1); + temperatureData = mixingRows.map((row: any) => toNumberOrNull(row.temperature)); + powerData = mixingRows.map((row: any) => toNumberOrNull(row.power)); + energyData = mixingRows.map((row: any) => toNumberOrNull(row.energy)); + pressureData = mixingRows.map((row: any) => toNumberOrNull(row.pressure)); + speedData = mixingRows.map((row: any) => toNumberOrNull(row.rpm)); + positionData = mixingRows.map((row: any) => buildPositionFromAction(row)); + } else { + const maxLen = Math.max( + listLength(cd.mixingTime), + listLength(cd.temperature), + listLength(cd.power), + listLength(cd.energy), + listLength(cd.pressure), + listLength(cd.speed), + listLength(cd.position) + ); + + xAxisData = + Array.isArray(cd.mixingTime) && cd.mixingTime.length > 0 + ? cd.mixingTime.map((v: any, i: number) => { + const num = Number(v); + return Number.isFinite(num) ? num : i + 1; + }) + : Array.from({ length: maxLen }, (_, i) => i + 1); + + const buildSeriesData = (source: any): Array => { + const arr = Array.isArray(source) ? source : []; + return xAxisData.map((_, idx) => toNumberOrNull(arr[idx])); + }; + + temperatureData = buildSeriesData(cd.temperature); + powerData = buildSeriesData(cd.power); + energyData = buildSeriesData(cd.energy); + pressureData = buildSeriesData(cd.pressure); + speedData = buildSeriesData(cd.speed); + positionData = buildSeriesData(cd.position); + } + + const calcRange = (arr: Array) => { + const nums = arr.filter((n): n is number => typeof n === 'number'); + if (!nums.length) return {}; + const min = Math.min(...nums); + const max = Math.max(...nums); + const pad = min === max ? Math.max(Math.abs(min) * 0.1, 1) : (max - min) * 0.1; + return { + min: Number((min - pad).toFixed(2)), + max: Number((max + pad).toFixed(2)) + }; + }; + + const leftAxisRange = calcRange(temperatureData); + const rightAxisRange = calcRange([...powerData, ...energyData, ...pressureData, ...speedData, ...positionData]); if (chartInstance) { chartInstance.dispose(); @@ -266,26 +355,47 @@ const initChart = () => { } chartInstance = echarts.init(chartRef.value); + + if (xAxisData.length === 0) { + chartInstance.setOption({ + graphic: { + type: 'text', + left: 'center', + top: 'middle', + style: { text: '暂无曲线数据', fill: '#909399', fontSize: 14 } + } + }); + return; + } + chartInstance.setOption({ + animation: false, grid: { left: '5%', right: '5%', top: '10%', bottom: '10%', containLabel: true }, tooltip: { trigger: 'axis' }, - xAxis: { type: 'category', data: xAxisData, boundaryGap: false, name: '时间(s)' }, + xAxis: { + type: 'category', + data: xAxisData, + boundaryGap: false, + name: mixingRows.length > 0 ? '混炼步骤' : '时间(s)' + }, yAxis: [ - { type: 'value', name: '温度(℃)', position: 'left', axisLine: { show: true } }, - { type: 'value', name: '其他参数', position: 'right', axisLine: { show: true } } + { type: 'value', name: '温度(℃)', position: 'left', axisLine: { show: true }, ...leftAxisRange }, + { type: 'value', name: '其他参数', position: 'right', axisLine: { show: true }, ...rightAxisRange } ], series: [ - { name: '温度', type: 'line', yAxisIndex: 0, data: cd.temperature || [], smooth: true, itemStyle: { color: '#ff4d4f' } }, - { name: '功率', type: 'line', yAxisIndex: 1, data: cd.power || [], smooth: true, itemStyle: { color: '#40a9ff' } }, - { name: '能量', type: 'line', yAxisIndex: 1, data: cd.energy || [], smooth: true, itemStyle: { color: '#36cfc9' } }, - { name: '压力', type: 'line', yAxisIndex: 1, data: cd.pressure || [], smooth: true, itemStyle: { color: '#95de64' } }, - { name: '转速', type: 'line', yAxisIndex: 1, data: cd.speed || [], smooth: true, itemStyle: { color: '#f7d13d' } }, + { name: '温度', type: 'line', yAxisIndex: 0, data: temperatureData, smooth: false, connectNulls: false, showSymbol: true, itemStyle: { color: '#ff4d4f' } }, + { name: '功率', type: 'line', yAxisIndex: 1, data: powerData, smooth: false, connectNulls: false, showSymbol: true, itemStyle: { color: '#40a9ff' } }, + { name: '能量', type: 'line', yAxisIndex: 1, data: energyData, smooth: false, connectNulls: false, showSymbol: true, itemStyle: { color: '#36cfc9' } }, + { name: '压力', type: 'line', yAxisIndex: 1, data: pressureData, smooth: false, connectNulls: false, showSymbol: true, itemStyle: { color: '#95de64' } }, + { name: '转速', type: 'line', yAxisIndex: 1, data: speedData, smooth: false, connectNulls: false, showSymbol: true, itemStyle: { color: '#f7d13d' } }, { name: '上顶栓', type: 'line', yAxisIndex: 1, - data: cd.position || [], + data: positionData, smooth: false, + connectNulls: false, + showSymbol: true, lineStyle: { type: 'dashed' }, itemStyle: { color: '#ffa07a' } } diff --git a/src/views/mes/mixTrace/show/data/tire1.json b/src/views/mes/mixTrace/show/data/tire1.json index 20ac689..8439819 100644 --- a/src/views/mes/mixTrace/show/data/tire1.json +++ b/src/views/mes/mixTrace/show/data/tire1.json @@ -13,5 +13,28 @@ { "label": "成型机台", "value": "CX402" }, { "label": "硫化操作人", "value": "马小平" }, { "label": "成型操作人", "value": "克一赛尔·克然木" } + ], + "treeData": [ + { + "id": "T1", + "label": "轮胎条码: 0G0AB38390", + "children": [ + { + "id": "T1-1", + "label": "胎胚条码: 226402001270", + "children": [ + { "id": "T1-1-1", "label": "KB110-F 胎面 01130052601040025" }, + { "id": "T1-1-2", "label": "N465A1005A 内衬层 260101N4600125" }, + { "id": "T1-1-3", "label": "RW032 胎侧 260101RW00010360" }, + { "id": "T1-1-4", "label": "K2A182K26 2#带束层 260101K2A00010195" }, + { "id": "T1-1-5", "label": "K1A190A26 1#带束层 260101K1A00010224" }, + { "id": "T1-1-6", "label": "E1D62090 1#胎体帘布 260101E1D00010087" }, + { "id": "T1-1-7", "label": "E2D50090 2#胎体帘布 260101E2D00010062" }, + { "id": "T1-1-8", "label": "RS001 冠带条 260101RS000010068" }, + { "id": "T1-1-9", "label": "GA4106D25AA 胎圈 260101GA400070003" } + ] + } + ] + } ] } diff --git a/src/views/mes/mixTrace/show/forward1.vue b/src/views/mes/mixTrace/show/forward1.vue index 2c7e76e..99a3734 100644 --- a/src/views/mes/mixTrace/show/forward1.vue +++ b/src/views/mes/mixTrace/show/forward1.vue @@ -234,6 +234,86 @@ const handleSearch = () => { const initChart = () => { if (!chartRef.value) return; const cd = curveDataSource.value; + const mixingRows = Array.isArray(mixingProcessData.value) ? mixingProcessData.value : []; + + const toNumberOrNull = (value: any): number | null => { + const num = Number(value); + return Number.isFinite(num) ? num : null; + }; + + const listLength = (value: any): number => { + return Array.isArray(value) ? value.length : 0; + }; + + const buildPositionFromAction = (row: any): number | null => { + const actionText = String(row?.action || row?.condition || ''); + if (actionText.includes('压上顶栓')) return 1; + if (actionText.includes('升上顶栓')) return 0; + return null; + }; + + let xAxisData: Array = []; + let temperatureData: Array = []; + let powerData: Array = []; + let energyData: Array = []; + let pressureData: Array = []; + let speedData: Array = []; + let positionData: Array = []; + + if (mixingRows.length > 0) { + xAxisData = mixingRows.map((row: any, idx: number) => row.step ?? idx + 1); + temperatureData = mixingRows.map((row: any) => toNumberOrNull(row.temperature)); + powerData = mixingRows.map((row: any) => toNumberOrNull(row.power)); + energyData = mixingRows.map((row: any) => toNumberOrNull(row.energy)); + pressureData = mixingRows.map((row: any) => toNumberOrNull(row.pressure)); + speedData = mixingRows.map((row: any) => toNumberOrNull(row.rpm)); + positionData = mixingRows.map((row: any) => buildPositionFromAction(row)); + } else { + const maxLen = Math.max( + listLength(cd.mixingTime), + listLength(cd.temperature), + listLength(cd.power), + listLength(cd.energy), + listLength(cd.pressure), + listLength(cd.speed), + listLength(cd.position) + ); + + xAxisData = + Array.isArray(cd.mixingTime) && cd.mixingTime.length > 0 + ? cd.mixingTime.map((v: any, i: number) => { + const num = Number(v); + return Number.isFinite(num) ? num : i + 1; + }) + : Array.from({ length: maxLen }, (_, i) => i + 1); + + const buildSeriesData = (source: any): Array => { + const arr = Array.isArray(source) ? source : []; + return xAxisData.map((_, idx) => toNumberOrNull(arr[idx])); + }; + + temperatureData = buildSeriesData(cd.temperature); + powerData = buildSeriesData(cd.power); + energyData = buildSeriesData(cd.energy); + pressureData = buildSeriesData(cd.pressure); + speedData = buildSeriesData(cd.speed); + positionData = buildSeriesData(cd.position); + } + + const calcRange = (arr: Array) => { + const nums = arr.filter((n): n is number => typeof n === 'number'); + if (!nums.length) return {}; + const min = Math.min(...nums); + const max = Math.max(...nums); + const pad = min === max ? Math.max(Math.abs(min) * 0.1, 1) : (max - min) * 0.1; + return { + min: Number((min - pad).toFixed(2)), + max: Number((max + pad).toFixed(2)) + }; + }; + + const leftAxisRange = calcRange(temperatureData); + const rightAxisRange = calcRange([...powerData, ...energyData, ...pressureData, ...speedData, ...positionData]); if (chartInstance) { chartInstance.dispose(); @@ -241,26 +321,47 @@ const initChart = () => { } chartInstance = echarts.init(chartRef.value); + + if (xAxisData.length === 0) { + chartInstance.setOption({ + graphic: { + type: 'text', + left: 'center', + top: 'middle', + style: { text: '暂无曲线数据', fill: '#909399', fontSize: 14 } + } + }); + return; + } + chartInstance.setOption({ + animation: false, grid: { left: '5%', right: '5%', top: '10%', bottom: '10%', containLabel: true }, tooltip: { trigger: 'axis' }, - xAxis: { type: 'category', data: cd.mixingTime || [], boundaryGap: false, name: '时间(s)' }, + xAxis: { + type: 'category', + data: xAxisData, + boundaryGap: false, + name: mixingRows.length > 0 ? '混炼步骤' : '时间(s)' + }, yAxis: [ - { type: 'value', name: '温度(℃)', position: 'left', axisLine: { show: true } }, - { type: 'value', name: '其他参数', position: 'right', axisLine: { show: true } } + { type: 'value', name: '温度(℃)', position: 'left', axisLine: { show: true }, ...leftAxisRange }, + { type: 'value', name: '其他参数', position: 'right', axisLine: { show: true }, ...rightAxisRange } ], series: [ - { name: '温度', type: 'line', yAxisIndex: 0, data: cd.temperature || [], smooth: true, itemStyle: { color: '#ff4d4f' } }, - { name: '功率', type: 'line', yAxisIndex: 1, data: cd.power || [], smooth: true, itemStyle: { color: '#40a9ff' } }, - { name: '能量', type: 'line', yAxisIndex: 1, data: cd.energy || [], smooth: true, itemStyle: { color: '#36cfc9' } }, - { name: '压力', type: 'line', yAxisIndex: 1, data: cd.pressure || [], smooth: true, itemStyle: { color: '#95de64' } }, - { name: '转速', type: 'line', yAxisIndex: 1, data: cd.speed || [], smooth: true, itemStyle: { color: '#f7d13d' } }, + { name: '温度', type: 'line', yAxisIndex: 0, data: temperatureData, smooth: false, connectNulls: false, showSymbol: true, itemStyle: { color: '#ff4d4f' } }, + { name: '功率', type: 'line', yAxisIndex: 1, data: powerData, smooth: false, connectNulls: false, showSymbol: true, itemStyle: { color: '#40a9ff' } }, + { name: '能量', type: 'line', yAxisIndex: 1, data: energyData, smooth: false, connectNulls: false, showSymbol: true, itemStyle: { color: '#36cfc9' } }, + { name: '压力', type: 'line', yAxisIndex: 1, data: pressureData, smooth: false, connectNulls: false, showSymbol: true, itemStyle: { color: '#95de64' } }, + { name: '转速', type: 'line', yAxisIndex: 1, data: speedData, smooth: false, connectNulls: false, showSymbol: true, itemStyle: { color: '#f7d13d' } }, { name: '上顶栓', type: 'line', yAxisIndex: 1, - data: cd.position || [], + data: positionData, smooth: false, + connectNulls: false, + showSymbol: true, lineStyle: { type: 'dashed' }, itemStyle: { color: '#ffa07a' } } diff --git a/src/views/mes/mixTrace/show/tire1.vue b/src/views/mes/mixTrace/show/tire1.vue index 411c7a0..9d741cc 100644 --- a/src/views/mes/mixTrace/show/tire1.vue +++ b/src/views/mes/mixTrace/show/tire1.vue @@ -3,71 +3,75 @@ 胎号: - + 查询 清空 - - - - - - - {{ step.name }} - - → - + + - + - 轮胎产品: {{ tireNo }} + 批次列表 - - - {{ item.label }}: - {{ item.value }} - - + + + + + + {{ node.label }} + + +