|
|
|
|
@ -0,0 +1,208 @@
|
|
|
|
|
<template>
|
|
|
|
|
<div class="app-container">
|
|
|
|
|
<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="80px">
|
|
|
|
|
<el-form-item label="日期" prop="dateRange">
|
|
|
|
|
<el-date-picker v-model="dateRange" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<!-- 工序输入已移除,固定为常量2 -->
|
|
|
|
|
<el-form-item label="机台" prop="machineId">
|
|
|
|
|
<el-input v-model="queryParams.machineId" placeholder="可选:机台ID" clearable style="width: 180px" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item>
|
|
|
|
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
|
|
|
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-form>
|
|
|
|
|
|
|
|
|
|
<el-tabs v-model="activeTab">
|
|
|
|
|
<el-tab-pane label="日产量" name="daily">
|
|
|
|
|
<div class="chart-card">
|
|
|
|
|
<div ref="chartRefDaily" class="chart" />
|
|
|
|
|
</div>
|
|
|
|
|
</el-tab-pane>
|
|
|
|
|
<el-tab-pane label="良率趋势" name="yieldTrend">
|
|
|
|
|
<div class="chart-card">
|
|
|
|
|
<div ref="chartRefYieldTrend" class="chart" />
|
|
|
|
|
</div>
|
|
|
|
|
</el-tab-pane>
|
|
|
|
|
<el-tab-pane label="机台良率汇总" name="yieldMachine">
|
|
|
|
|
<div class="chart-card">
|
|
|
|
|
<div ref="chartRefYieldMachine" class="chart" />
|
|
|
|
|
</div>
|
|
|
|
|
</el-tab-pane>
|
|
|
|
|
</el-tabs>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts" name="ReportDailyOutput">
|
|
|
|
|
import * as echarts from 'echarts';
|
|
|
|
|
import { onMounted, onBeforeUnmount, ref, getCurrentInstance, watch, nextTick } from 'vue';
|
|
|
|
|
import { designDailyOutputInformation, yieldTrendByDate, yieldSummaryByMachine } from '@/api/mes/prodReport';
|
|
|
|
|
|
|
|
|
|
const { proxy } = getCurrentInstance() as any;
|
|
|
|
|
|
|
|
|
|
const queryFormRef = ref();
|
|
|
|
|
const dateRange = ref<string[] | null>(null);
|
|
|
|
|
const activeTab = ref<'daily' | 'yieldTrend' | 'yieldMachine'>('daily');
|
|
|
|
|
|
|
|
|
|
// 固定工序ID为常量 2,不展示在表单
|
|
|
|
|
const DEFAULT_PROCESS_ID = '2';
|
|
|
|
|
|
|
|
|
|
const queryParams = ref({
|
|
|
|
|
beginDate: '',
|
|
|
|
|
endDate: '',
|
|
|
|
|
processId: DEFAULT_PROCESS_ID,
|
|
|
|
|
machineId: ''
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// refs for three charts
|
|
|
|
|
const chartRefDaily = ref<HTMLElement | null>(null);
|
|
|
|
|
const chartRefYieldTrend = ref<HTMLElement | null>(null);
|
|
|
|
|
const chartRefYieldMachine = ref<HTMLElement | null>(null);
|
|
|
|
|
|
|
|
|
|
let chartDaily: echarts.ECharts | null = null;
|
|
|
|
|
let chartYieldTrend: echarts.ECharts | null = null;
|
|
|
|
|
let chartYieldMachine: echarts.ECharts | null = null;
|
|
|
|
|
|
|
|
|
|
const initChartDaily = () => {
|
|
|
|
|
if (!chartRefDaily.value) return;
|
|
|
|
|
chartDaily = echarts.init(chartRefDaily.value, 'macarons');
|
|
|
|
|
chartDaily.setOption({
|
|
|
|
|
tooltip: { trigger: 'axis' },
|
|
|
|
|
grid: { left: 40, right: 20, top: 30, bottom: 40 },
|
|
|
|
|
xAxis: { type: 'category', boundaryGap: false, data: [] },
|
|
|
|
|
yAxis: { type: 'value', name: '完成数量' },
|
|
|
|
|
series: [{ name: '日产量', type: 'line', smooth: true, data: [], areaStyle: {} }]
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const initChartYieldTrend = () => {
|
|
|
|
|
if (!chartRefYieldTrend.value) return;
|
|
|
|
|
chartYieldTrend = echarts.init(chartRefYieldTrend.value, 'macarons');
|
|
|
|
|
chartYieldTrend.setOption({
|
|
|
|
|
tooltip: { trigger: 'axis', formatter: (p: any) => `${p[0].axisValue}<br/>良率:${p[0].data || 0}%` },
|
|
|
|
|
grid: { left: 40, right: 20, top: 30, bottom: 40 },
|
|
|
|
|
xAxis: { type: 'category', boundaryGap: false, data: [] },
|
|
|
|
|
yAxis: { type: 'value', name: '良率(%)', min: 0, max: 100 },
|
|
|
|
|
series: [{ name: '良率(%)', type: 'line', smooth: true, data: [], areaStyle: {} }]
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const initChartYieldMachine = () => {
|
|
|
|
|
if (!chartRefYieldMachine.value) return;
|
|
|
|
|
chartYieldMachine = echarts.init(chartRefYieldMachine.value, 'macarons');
|
|
|
|
|
chartYieldMachine.setOption({
|
|
|
|
|
tooltip: { trigger: 'axis' },
|
|
|
|
|
grid: { left: 60, right: 20, top: 10, bottom: 60 },
|
|
|
|
|
xAxis: { type: 'category', axisLabel: { rotate: 30 }, data: [] },
|
|
|
|
|
yAxis: { type: 'value', name: '良率(%)', min: 0, max: 100 },
|
|
|
|
|
series: [{ name: '良率(%)', type: 'bar', data: [] }]
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const setChartDailyData = (list: Array<{ productionDate: string; completeAmount: number }>) => {
|
|
|
|
|
const x = list.map(i => i.productionDate);
|
|
|
|
|
const y = list.map(i => i.completeAmount);
|
|
|
|
|
chartDaily?.setOption({ xAxis: { data: x }, series: [{ data: y }] });
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const setChartYieldTrendData = (list: Array<{ productionDate: string; yield: number }>) => {
|
|
|
|
|
const x = list.map(i => i.productionDate);
|
|
|
|
|
const y = list.map(i => Number(i.yield || 0));
|
|
|
|
|
chartYieldTrend?.setOption({ xAxis: { data: x }, series: [{ data: y }] });
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const setChartYieldMachineData = (list: Array<{ machineName: string; yield: number }>) => {
|
|
|
|
|
const x = list.map(i => i.machineName);
|
|
|
|
|
const y = list.map(i => Number(i.yield || 0));
|
|
|
|
|
chartYieldMachine?.setOption({ xAxis: { data: x }, series: [{ data: y }] });
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getDailyData = async () => {
|
|
|
|
|
queryParams.value.beginDate = dateRange.value?.[0] || '';
|
|
|
|
|
queryParams.value.endDate = dateRange.value?.[1] || '';
|
|
|
|
|
queryParams.value.processId = DEFAULT_PROCESS_ID;
|
|
|
|
|
const res = await designDailyOutputInformation(queryParams.value);
|
|
|
|
|
setChartDailyData(res.data || []);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getYieldTrend = async () => {
|
|
|
|
|
queryParams.value.beginDate = dateRange.value?.[0] || '';
|
|
|
|
|
queryParams.value.endDate = dateRange.value?.[1] || '';
|
|
|
|
|
queryParams.value.processId = DEFAULT_PROCESS_ID;
|
|
|
|
|
const res = await yieldTrendByDate(queryParams.value);
|
|
|
|
|
setChartYieldTrendData(res.data || []);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getYieldMachine = async () => {
|
|
|
|
|
queryParams.value.beginDate = dateRange.value?.[0] || '';
|
|
|
|
|
queryParams.value.endDate = dateRange.value?.[1] || '';
|
|
|
|
|
queryParams.value.processId = DEFAULT_PROCESS_ID;
|
|
|
|
|
const res = await yieldSummaryByMachine(queryParams.value);
|
|
|
|
|
setChartYieldMachineData(res.data || []);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleQuery = () => {
|
|
|
|
|
if (activeTab.value === 'daily') return getDailyData();
|
|
|
|
|
if (activeTab.value === 'yieldTrend') return getYieldTrend();
|
|
|
|
|
if (activeTab.value === 'yieldMachine') return getYieldMachine();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const resetQuery = () => {
|
|
|
|
|
queryFormRef.value?.resetFields?.();
|
|
|
|
|
// 默认展示最近7天
|
|
|
|
|
const end = new Date();
|
|
|
|
|
const start = new Date();
|
|
|
|
|
start.setDate(end.getDate() - 6);
|
|
|
|
|
const fmt = (d: Date) => proxy?.parseTime(d, '{y}-{m}-{d}');
|
|
|
|
|
dateRange.value = [fmt(start), fmt(end)];
|
|
|
|
|
// 确保重置后仍固定工序ID
|
|
|
|
|
queryParams.value.processId = DEFAULT_PROCESS_ID;
|
|
|
|
|
handleQuery();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
onMounted(async () => {
|
|
|
|
|
await nextTick();
|
|
|
|
|
initChartDaily();
|
|
|
|
|
initChartYieldTrend();
|
|
|
|
|
initChartYieldMachine();
|
|
|
|
|
resetQuery();
|
|
|
|
|
window.addEventListener('resize', resizeChart);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const resizeChart = () => {
|
|
|
|
|
chartDaily?.resize();
|
|
|
|
|
chartYieldTrend?.resize();
|
|
|
|
|
chartYieldMachine?.resize();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
onBeforeUnmount(() => {
|
|
|
|
|
window.removeEventListener('resize', resizeChart);
|
|
|
|
|
chartDaily?.dispose();
|
|
|
|
|
chartYieldTrend?.dispose();
|
|
|
|
|
chartYieldMachine?.dispose();
|
|
|
|
|
chartDaily = chartYieldTrend = chartYieldMachine = null;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
watch(dateRange, () => {
|
|
|
|
|
// 自动刷新当前Tab
|
|
|
|
|
handleQuery();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
watch(activeTab, () => {
|
|
|
|
|
// 切换Tab时刷新对应图
|
|
|
|
|
handleQuery();
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
.chart-card {
|
|
|
|
|
background: #fff;
|
|
|
|
|
padding: 12px;
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
}
|
|
|
|
|
.chart {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 420px;
|
|
|
|
|
}
|
|
|
|
|
</style>
|