|
|
|
@ -20,14 +20,55 @@
|
|
|
|
type="primary"
|
|
|
|
type="primary"
|
|
|
|
style="margin-left: 10px"
|
|
|
|
style="margin-left: 10px"
|
|
|
|
:disabled="!analysisForm.selectedItem"
|
|
|
|
:disabled="!analysisForm.selectedItem"
|
|
|
|
|
|
|
|
@click="handleFetchData"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
查询
|
|
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
|
|
<el-button
|
|
|
|
|
|
|
|
type="success"
|
|
|
|
|
|
|
|
style="margin-left: 10px"
|
|
|
|
|
|
|
|
:disabled="!analysisForm.selectedItem || workbenchData.length === 0"
|
|
|
|
@click="handleAnalyzeItem"
|
|
|
|
@click="handleAnalyzeItem"
|
|
|
|
>
|
|
|
|
>
|
|
|
|
分析
|
|
|
|
AI分析
|
|
|
|
</el-button>
|
|
|
|
</el-button>
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
</el-form>
|
|
|
|
</el-form>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 机台不良分布数据表格 -->
|
|
|
|
|
|
|
|
<div v-if="workbenchData.length > 0" class="workbench-data">
|
|
|
|
|
|
|
|
<h3>机台不良分布 - {{ analysisForm.selectedItem }}</h3>
|
|
|
|
|
|
|
|
<el-table
|
|
|
|
|
|
|
|
:data="workbenchData"
|
|
|
|
|
|
|
|
border
|
|
|
|
|
|
|
|
style="width: 100%"
|
|
|
|
|
|
|
|
stripe
|
|
|
|
|
|
|
|
:default-sort="{ prop: 'bad_count', order: 'descending' }"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<el-table-column prop="workbench" label="机台号" width="100" sortable />
|
|
|
|
|
|
|
|
<el-table-column prop="bad_count" label="不良数量" width="120" sortable />
|
|
|
|
|
|
|
|
<el-table-column prop="bad_percentage" label="不良占比" width="120" sortable>
|
|
|
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
|
|
|
{{ scope.row.bad_percentage }}%
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
|
|
<el-table-column label="不良占比可视化">
|
|
|
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
|
|
|
<el-progress
|
|
|
|
|
|
|
|
:percentage="scope.row.bad_percentage"
|
|
|
|
|
|
|
|
:show-text="false"
|
|
|
|
|
|
|
|
:color="getProgressColor(scope.row.bad_percentage)"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
|
|
</el-table>
|
|
|
|
|
|
|
|
<div class="statistics-info">
|
|
|
|
|
|
|
|
<p>数据范围: {{ props.dateRange.start_date }} 至 {{ props.dateRange.end_date }}</p>
|
|
|
|
|
|
|
|
<p>总计机台数: {{ workbenchData.length }}</p>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 分析结果显示区域 -->
|
|
|
|
<!-- 分析结果显示区域 -->
|
|
|
|
<div v-if="analysisResult" class="analysis-result">
|
|
|
|
<div v-if="analysisResult" class="analysis-result">
|
|
|
|
<h3>{{ analysisForm.selectedItem }} - 分析结果</h3>
|
|
|
|
<h3>{{ analysisForm.selectedItem }} - 分析结果</h3>
|
|
|
|
@ -44,6 +85,7 @@
|
|
|
|
<script setup>
|
|
|
|
<script setup>
|
|
|
|
import { ref, reactive } from 'vue'
|
|
|
|
import { ref, reactive } from 'vue'
|
|
|
|
import { AI_CONFIG, CURRENT_AI_MODEL } from "@/config/ai"
|
|
|
|
import { AI_CONFIG, CURRENT_AI_MODEL } from "@/config/ai"
|
|
|
|
|
|
|
|
import { API_CONFIG } from "@/config/api"
|
|
|
|
|
|
|
|
|
|
|
|
const props = defineProps({
|
|
|
|
const props = defineProps({
|
|
|
|
paretoData: {
|
|
|
|
paretoData: {
|
|
|
|
@ -69,6 +111,9 @@ const analysisForm = reactive({
|
|
|
|
// 分析结果
|
|
|
|
// 分析结果
|
|
|
|
const analysisResult = ref('')
|
|
|
|
const analysisResult = ref('')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 机台不良数据
|
|
|
|
|
|
|
|
const workbenchData = ref([])
|
|
|
|
|
|
|
|
|
|
|
|
// 项目名称列表
|
|
|
|
// 项目名称列表
|
|
|
|
const itemList = ref([
|
|
|
|
const itemList = ref([
|
|
|
|
'漆膜厚度',
|
|
|
|
'漆膜厚度',
|
|
|
|
@ -90,32 +135,98 @@ const itemList = ref([
|
|
|
|
'单向刮漆min(N)'
|
|
|
|
'单向刮漆min(N)'
|
|
|
|
])
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
// 项目分析功能
|
|
|
|
// 根据缺陷百分比设置进度条颜色
|
|
|
|
async function handleAnalyzeItem() {
|
|
|
|
function getProgressColor(percentage) {
|
|
|
|
|
|
|
|
if (percentage >= 10) return '#f56c6c'; // 红色 - 高缺陷率
|
|
|
|
|
|
|
|
if (percentage >= 5) return '#e6a23c'; // 橙色 - 中等缺陷率
|
|
|
|
|
|
|
|
if (percentage >= 2) return '#409eff'; // 蓝色 - 低缺陷率
|
|
|
|
|
|
|
|
return '#67c23a'; // 绿色 - 很低缺陷率
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 获取机台不良分布数据
|
|
|
|
|
|
|
|
async function handleFetchData() {
|
|
|
|
if (!analysisForm.selectedItem) {
|
|
|
|
if (!analysisForm.selectedItem) {
|
|
|
|
emit('ai-analysis-complete', '请先选择要分析的项目')
|
|
|
|
emit('ai-analysis-complete', '请先选择要分析的项目')
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 根据选择的时间范围计算开始和结束日期
|
|
|
|
|
|
|
|
const endDate = new Date();
|
|
|
|
|
|
|
|
const startDate = new Date();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (props.dateRange.end_date) {
|
|
|
|
|
|
|
|
// 如果有传入日期范围,使用传入的日期
|
|
|
|
|
|
|
|
const endParts = props.dateRange.end_date.split('-');
|
|
|
|
|
|
|
|
const startParts = props.dateRange.start_date.split('-');
|
|
|
|
|
|
|
|
endDate.setFullYear(parseInt(endParts[0]), parseInt(endParts[1])-1, parseInt(endParts[2]));
|
|
|
|
|
|
|
|
startDate.setFullYear(parseInt(startParts[0]), parseInt(startParts[1])-1, parseInt(startParts[2]));
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// 否则使用默认的近一年时间
|
|
|
|
|
|
|
|
startDate.setFullYear(endDate.getFullYear() - 1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 格式化日期为 YYYY-MM-DD
|
|
|
|
|
|
|
|
const formatDate = (date) => {
|
|
|
|
|
|
|
|
const year = date.getFullYear();
|
|
|
|
|
|
|
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
|
|
|
|
|
|
const day = String(date.getDate()).padStart(2, '0');
|
|
|
|
|
|
|
|
return `${year}-${month}-${day}`;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const startDateStr = formatDate(startDate);
|
|
|
|
|
|
|
|
const endDateStr = formatDate(endDate);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 调用机台不良分布API
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
const response = await fetch(`${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINTS.WORKBENCH_BADNESS}?item_name=${encodeURIComponent(analysisForm.selectedItem)}&start_date=${startDateStr}&end_date=${endDateStr}`);
|
|
|
|
|
|
|
|
const data = await response.json();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (data.code === 200 && data.data) {
|
|
|
|
|
|
|
|
workbenchData.value = data.data;
|
|
|
|
|
|
|
|
emit('ai-analysis-complete', `成功获取${analysisForm.selectedItem}的机台不良分布数据`);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
workbenchData.value = [];
|
|
|
|
|
|
|
|
emit('ai-analysis-complete', data.message || '获取机台不良分布数据失败');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
|
|
console.error('获取机台不良分布数据失败:', error);
|
|
|
|
|
|
|
|
workbenchData.value = [];
|
|
|
|
|
|
|
|
emit('ai-analysis-complete', '获取机台不良分布数据失败');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// AI分析功能
|
|
|
|
|
|
|
|
async function handleAnalyzeItem() {
|
|
|
|
|
|
|
|
if (!analysisForm.selectedItem || workbenchData.value.length === 0) {
|
|
|
|
|
|
|
|
emit('ai-analysis-complete', '请先选择项目并查询数据')
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 在帕累托数据中查找选中项目的数据
|
|
|
|
// 在帕累托数据中查找选中项目的数据
|
|
|
|
const selectedItemData = props.paretoData.find(item => item.item_name === analysisForm.selectedItem)
|
|
|
|
const selectedItemData = props.paretoData.find(item => item.item_name === analysisForm.selectedItem)
|
|
|
|
|
|
|
|
|
|
|
|
// 准备分析提示词
|
|
|
|
// 准备分析提示词
|
|
|
|
const prompt = `请对以下质检项目进行详细分析:
|
|
|
|
const prompt = `请对以下质检项目和机台不良分布进行详细分析:
|
|
|
|
|
|
|
|
|
|
|
|
项目名称: ${analysisForm.selectedItem}
|
|
|
|
项目名称: ${analysisForm.selectedItem}
|
|
|
|
数据范围: ${props.dateRange.start_date} 至 ${props.dateRange.end_date}
|
|
|
|
数据范围: ${props.dateRange.start_date} 至 ${props.dateRange.end_date}
|
|
|
|
|
|
|
|
|
|
|
|
该项目相关数据:
|
|
|
|
帕累托分析数据:
|
|
|
|
${selectedItemData ?
|
|
|
|
${selectedItemData ?
|
|
|
|
`- 缺陷数量: ${selectedItemData.defect_count}\n- 缺陷占比: ${selectedItemData.defect_percentage}%\n- 累计占比: ${selectedItemData.cumulative_percentage}%` :
|
|
|
|
`- 缺陷数量: ${selectedItemData.defect_count}\n- 缺陷占比: ${selectedItemData.defect_percentage}%\n- 累计占比: ${selectedItemData.cumulative_percentage}%` :
|
|
|
|
'该项目在当前帕累托分析数据中不存在'}
|
|
|
|
'该项目在当前帕累托分析数据中不存在'}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
机台不良分布数据:
|
|
|
|
|
|
|
|
${workbenchData.value.slice(0, 5).map(item =>
|
|
|
|
|
|
|
|
`- 机台${item.workbench}: 不良数量${item.bad_count}, 不良占比${item.bad_percentage}%`
|
|
|
|
|
|
|
|
).join('\n')}
|
|
|
|
|
|
|
|
|
|
|
|
请从以下角度进行分析:
|
|
|
|
请从以下角度进行分析:
|
|
|
|
1. 该项目缺陷对整体质量的影响
|
|
|
|
1. 该项目缺陷对整体质量的影响
|
|
|
|
2. 产生缺陷的可能原因分析
|
|
|
|
2. 产生缺陷的可能原因分析
|
|
|
|
3. 针对该项目的改进建议
|
|
|
|
3. 针对该项目的改进建议
|
|
|
|
4. 该项目与其他项目的关联性分析`
|
|
|
|
4. 机台不良分布的规律分析
|
|
|
|
|
|
|
|
5. 该项目与其他项目的关联性分析`
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
// 获取当前AI模型配置
|
|
|
|
// 获取当前AI模型配置
|
|
|
|
@ -185,4 +296,25 @@ ${selectedItemData ?
|
|
|
|
margin-bottom: 15px;
|
|
|
|
margin-bottom: 15px;
|
|
|
|
color: #409eff;
|
|
|
|
color: #409eff;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.workbench-data {
|
|
|
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.workbench-data h3 {
|
|
|
|
|
|
|
|
margin-bottom: 15px;
|
|
|
|
|
|
|
|
color: #409eff;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.statistics-info {
|
|
|
|
|
|
|
|
margin-top: 10px;
|
|
|
|
|
|
|
|
padding: 10px;
|
|
|
|
|
|
|
|
background-color: #f5f7fa;
|
|
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.statistics-info p {
|
|
|
|
|
|
|
|
margin: 5px 0;
|
|
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
|
|
}
|
|
|
|
</style>
|
|
|
|
</style>
|