diff --git a/src/api/mes/prodReport/index.ts b/src/api/mes/prodReport/index.ts index 950917d..c949020 100644 --- a/src/api/mes/prodReport/index.ts +++ b/src/api/mes/prodReport/index.ts @@ -157,3 +157,59 @@ export const exportHourlyOutputByHour = (query) => { responseType: 'blob' }); }; + +/** + * 工序生产统计(按工序聚合):完成数量、未完成数量与完成率 + */ +export const processWorkOrderStats = (query): AxiosPromise<[]> => { + return request({ + url: '/mes/prodReport/processWorkOrderStats', + method: 'get', + params: query + }); +}; + +/** + * 工序生产统计(分页,按工序聚合) + */ +export const processWorkOrderStatsPage = (query): AxiosPromise<[]> => { + return request({ + url: '/mes/prodReport/processWorkOrderStats/page', + method: 'get', + params: query + }); +}; + +/** + * 工序生产统计导出(按工序聚合) + */ +export const exportProcessWorkOrderStats = (query) => { + return request({ + url: '/mes/prodReport/processWorkOrderStats/export', + method: 'post', + params: query, + responseType: 'blob' + }); +}; + +/** + * 工序下的计划子节点查询:按 plan_code + process_id 过滤 + */ +export const planProcessChildren = (query): AxiosPromise<[]> => { + return request({ + url: '/mes/prodReport/planProcessChildren', + method: 'get', + params: query + }); +}; + +/** + * 按工序查询计划列表(不分页) + */ +export const processPlanList = (query): AxiosPromise<[]> => { + return request({ + url: '/mes/prodReport/processPlanList', + method: 'get', + params: query + }); +}; diff --git a/src/views/mes/wipTrackingReport/backup.vue b/src/views/mes/wipTrackingReport/backup.vue index 9bb782a..6bacd7f 100644 --- a/src/views/mes/wipTrackingReport/backup.vue +++ b/src/views/mes/wipTrackingReport/backup.vue @@ -106,6 +106,18 @@ + + + + + +
+
+
+
+ @@ -126,7 +138,7 @@ - + @@ -225,7 +237,7 @@ let processStatsChart: echarts.ECharts | null = null; // 列显隐信息 const columns = ref([ - { key: 0, label: '生产订单号', visible: true }, + { key: 0, label: '派工单号', visible: true }, { key: 1, label: '物料编号', visible: false }, { key: 2, label: '物料名称', visible: true }, { key: 3, label: '规格型号', visible: true }, @@ -247,7 +259,7 @@ const columns = ref([ const queryParams = ref({ pageNum: 1, pageSize: 10, - orderCode: '', + planCode: '', materialCode: '', materialName: '', progressStatus: '', @@ -294,7 +306,7 @@ function resetQuery() { queryParams.value = { pageNum: 1, pageSize: 10, - orderCode: '', + planCode: '', materialCode: '', materialName: '', progressStatus: '', @@ -449,49 +461,49 @@ function updateProgressChart() { function updateProcessStatsChart() { if (!processStatsChart || !reportList.value.length) return; - const processStats = { - '已完成': 0, - '进行中': 0, - '未开始': 0 - }; + const nowTs = Date.now(); + const statsMap = new Map(); reportList.value.forEach(item => { - if (item.processProgressList) { - item.processProgressList.forEach(process => { - if (process.isCompleted) { - processStats['已完成']++; - } else if (process.isInProgress) { - processStats['进行中']++; - } else { - processStats['未开始']++; - } - }); - } + (item.processProgressList || []).forEach((proc: any) => { + const name = proc.processName || '未知工序'; + const rec = statsMap.get(name) || { total: 0, notStarted: 0, incomplete: 0, delayed: 0, completed: 0 }; + + rec.total += 1; + const isCompleted = proc.isCompleted === 1 || !!proc.isCompleted; + const planStatus = proc.planStatus; + if (!isCompleted) rec.incomplete += 1; else rec.completed += 1; + if (planStatus === '0') rec.notStarted += 1; + + const planEndTime = proc.planEndTime ? new Date(proc.planEndTime).getTime() : null; + if (planEndTime && planEndTime < nowTs && !isCompleted) rec.delayed += 1; + + statsMap.set(name, rec); + }); }); + const topEntries = Array.from(statsMap.entries()).sort((a, b) => b[1].total - a[1].total).slice(0, 10); + const processNames = topEntries.map(([n]) => n); + const notStartedData = topEntries.map(([, v]) => v.notStarted); + const incompleteData = topEntries.map(([, v]) => v.incomplete); + const delayedData = topEntries.map(([, v]) => v.delayed); + const completionRateData = topEntries.map(([, v]) => (v.total > 0 ? +(v.completed * 100 / v.total).toFixed(2) : 0)); + const option = { - title: { - text: '工序完成率统计', - left: 'center', - textStyle: { fontSize: 14 } - }, - tooltip: { - trigger: 'item', - formatter: '{a}
{b}: {c} ({d}%)' - }, + title: { text: '工序工单统计(Top10)', left: 'center', textStyle: { fontSize: 14 } }, + tooltip: { trigger: 'axis' }, + legend: { data: ['未开工', '未完成', '延期', '完成率%'], bottom: 0 }, + grid: { left: '3%', right: '6%', top: 40, bottom: 60, containLabel: true }, + xAxis: { type: 'category', data: processNames }, + yAxis: [ + { type: 'value', name: '工单数' }, + { type: 'value', name: '完成率%', min: 0, max: 100, position: 'right' } + ], series: [ - { - name: '工序状态', - type: 'pie', - radius: ['40%', '70%'], - data: Object.entries(processStats).map(([name, value]) => ({ name, value })), - itemStyle: { - color: function(params: any) { - const colors = ['#722ed1', '#52c41a', '#d9d9d9']; - return colors[params.dataIndex]; - } - } - } + { name: '未开工', type: 'bar', stack: 'count', data: notStartedData }, + { name: '未完成', type: 'bar', stack: 'count', data: incompleteData }, + { name: '延期', type: 'bar', stack: 'count', data: delayedData }, + { name: '完成率%', type: 'line', yAxisIndex: 1, data: completionRateData, smooth: true } ] }; diff --git a/src/views/mes/wipTrackingReport/index.vue b/src/views/mes/wipTrackingReport/index.vue index b78cfdb..2aa25fc 100644 --- a/src/views/mes/wipTrackingReport/index.vue +++ b/src/views/mes/wipTrackingReport/index.vue @@ -4,6 +4,34 @@
+ + + + + + + + + + + + - + @@ -148,80 +176,38 @@
{{ Number(scope.row.completionRateNum || 0) }}% + 超额 +{{ Number(scope.row.completionRateNum || 0) - 100 }}%