feat(qms): 添加质量报告模块:每周生产测试不良数据分析图表

- 新增报告 API 接口和相关类型定义
- 实现每周生产测试不良数据分析图表功能
- 添加日期选择、数据查询、表格展示和 ECharts 图表绘制功能
master
zangch@mesnac.com 3 months ago
parent 0a54320ada
commit a6f187125e

@ -0,0 +1,19 @@
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import { QcUnqualifiedReviewVO, QcUnqualifiedReviewForm, QcUnqualifiedReviewQuery, CompleteTaskRequest } from '@/api/qms/qcUnqualifiedReview/types';
export const getWeeklyTestReport = (params: { startTime: string, endTime: string }) => {
return request({
url: '/qms/report/weeklyTestReport',
method: 'get',
params
});
};
export const getDefectAnalysisReport = (params: { startTime: string, endTime: string }) => {
return request({
url: '/qms/report/defectAnalysisReport',
method: 'get',
params
});
};

@ -0,0 +1,234 @@
<template>
<div class="p-4">
<el-card shadow="hover">
<el-form :model="queryParams" :inline="true">
<el-form-item label="选择周">
<el-date-picker
v-model="selectedWeek"
type="week"
format="YYYY 第 ww 周"
placeholder="选择周"
@change="handleDateChange"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery"></el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="mt-4" shadow="never" v-loading="loading">
<template #header>
<div class="text-center text-xl font-bold">每周生产测试不良数据分析图表</div>
</template>
<!-- 动态数据表格 -->
<el-table :data="tableData" border style="width: 100%" :row-style="{ height: '50px' }">
<el-table-column prop="metric" label="数据" min-width="180" />
<el-table-column
v-for="col in dateColumns"
:key="col.prop"
:prop="col.prop"
align="center"
min-width="100"
>
<template #header>
<div>{{ col.date }}</div>
<div>{{ col.dayOfWeek }}</div>
</template>
<template #default="scope">
<span v-if="scope.row.metric.includes('不良率')">{{ formatValue(scope.row[col.prop]) }}%</span>
<span v-else>{{ formatValue(scope.row[col.prop]) }}</span>
</template>
</el-table-column>
<el-table-column prop="total" label="汇总" align="center" min-width="100">
<template #default="scope">
<span v-if="scope.row.metric.includes('不良率')">{{ formatValue(scope.row.total) }}%</span>
<span v-else>{{ formatValue(scope.row.total) }}</span>
</template>
</el-table-column>
</el-table>
<!-- ECharts 图表容器 -->
<div ref="chartRef" style="width: 100%; height: 400px;" class="mt-4"></div>
</el-card>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import * as echarts from 'echarts';
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
import weekOfYear from 'dayjs/plugin/weekOfYear';
import { getDefectAnalysisReport } from '@/api/qms/report';
// --- dayjs ---
dayjs.extend(weekOfYear);
dayjs.locale('zh-cn');
// --- ECharts ---
const chartRef = ref<HTMLElement | null>(null);
let chartInstance: echarts.ECharts | null = null;
// --- Vue ---
const loading = ref(false); //
const selectedWeek = ref(new Date()); //
const queryParams = ref({ // API
startTime: '',
endTime: ''
});
const reportData = ref<any>(null); // API
const tableData = ref<any[]>([]); //
const dateColumns = ref<any[]>([]); //
// --- ECharts ---
const initChart = () => {
if (chartRef.value) {
chartInstance = echarts.init(chartRef.value);
}
};
// --- ---
const handleQuery = async () => {
//
if (!queryParams.value.startTime || !queryParams.value.endTime) {
handleDateChange(new Date()); // 使
}
loading.value = true;
try {
//
const res = await getDefectAnalysisReport(queryParams.value);
if (res.code === 200) {
reportData.value = res.data;
// API
transformDataForTable();
updateChart();
}
} catch (error) {
console.error("获取报告数据失败:", error);
} finally {
loading.value = false;
}
};
// --- ---
const transformDataForTable = () => {
if (!reportData.value) {
tableData.value = [];
dateColumns.value = [];
return;
}
const { tableData: apiTableData, dateColumns: apiDateColumns } = reportData.value;
tableData.value = apiTableData || [];
dateColumns.value = apiDateColumns || [];
};
// --- ECharts ---
const updateChart = () => {
if (!chartInstance || !reportData.value || !reportData.value.chartData) return;
const { chartData } = reportData.value;
// ECharts option
const option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
crossStyle: { color: '#999' }
}
},
legend: {
data: ['检验数量', '不良数量', '不良率']
},
xAxis: [
{
type: 'category',
data: chartData.dates,
axisPointer: { type: 'shadow' }
}
],
yAxis: [
{
type: 'value',
name: '数量 (个)',
min: 0,
axisLabel: { formatter: '{value}' }
},
{
type: 'value',
name: '不良率 (%)',
min: 0,
axisLabel: { formatter: '{value} %' }
}
],
series: [
{
name: '检验数量',
type: 'bar',
tooltip: { valueFormatter: (value: number) => value + ' 个' },
data: chartData.inspectionData
},
{
name: '不良数量',
type: 'bar',
tooltip: { valueFormatter: (value: number) => value + ' 个' },
data: chartData.defectData
},
{
name: '不良率',
type: 'line',
yAxisIndex: 1, // y
tooltip: { valueFormatter: (value: number) => value + ' %' },
data: chartData.defectRateData
}
]
};
chartInstance.setOption(option);
};
// --- ---
const formatValue = (value: any) => {
if (value === null || value === undefined) return '0';
if (typeof value === 'number') {
return value.toLocaleString();
}
return value;
};
// --- ---
const handleDateChange = (date: Date) => {
//
const startOfWeek = dayjs(date).startOf('week');
const endOfWeek = dayjs(date).endOf('week');
queryParams.value.startTime = startOfWeek.format('YYYY-MM-DD');
queryParams.value.endTime = endOfWeek.format('YYYY-MM-DD');
};
// --- Vue ---
onMounted(() => {
// 1.
initChart();
// 2.
handleDateChange(selectedWeek.value);
handleQuery();
// 3.
window.addEventListener('resize', () => {
if (chartInstance) {
chartInstance.resize();
}
});
});
</script>
<style scoped>
/* 您可以在此添加自定义样式 */
.el-form-item {
margin-bottom: 0;
}
</style>
Loading…
Cancel
Save