独立 item AI 分析

master
huangjinysf 3 months ago
parent b81fe7b641
commit 02b846b1e1

@ -7,6 +7,7 @@ export const API_CONFIG = {
// API端点 // API端点
ENDPOINTS: { ENDPOINTS: {
HELLO: '/api/hello', HELLO: '/api/hello',
PARETO_ANALYSIS: '/api/qc/pareto' PARETO_ANALYSIS: '/api/qc/pareto',
WORKBENCH_BADNESS: '/api/qc/badness/workbench'
} }
} }

@ -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>
Loading…
Cancel
Save