You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

304 lines
8.6 KiB
Vue

<template>
<div class="item-analysis-container">
<div class="item-select-section">
<el-form :model="analysisForm" label-width="100px">
<el-form-item label="项目名称">
<el-select
v-model="analysisForm.selectedItem"
placeholder="请选择要分析的项目"
style="width: 300px"
clearable
>
<el-option
v-for="item in itemList"
:key="item"
:label="item"
:value="item"
/>
</el-select>
<el-button
type="primary"
style="margin-left: 10px"
:disabled="!analysisForm.selectedItem"
@click="handleFetchData"
>
查询
</el-button>
<el-button
type="success"
style="margin-left: 10px"
:disabled="!analysisForm.selectedItem || workbenchData.length === 0"
@click="handleAnalyzeItem"
>
AI分析
</el-button>
</el-form-item>
</el-form>
</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>数据范围: {{ currentStartDate }} {{ currentEndDate }}</p>
<p>总计机台数: {{ workbenchData.length }}</p>
</div>
</div>
<!-- 分析结果显示区域 -->
<div v-if="analysisResult" class="analysis-result">
<h3>{{ analysisForm.selectedItem }} - 分析结果</h3>
<el-input
v-model="analysisResult"
type="textarea"
:rows="10"
readonly
/>
</div>
</div>
</template>
<script setup>
import { ref, reactive } from 'vue'
import { getDateRangeByTimeRange } from "@/utils/dateFormat"
import { AI_CONFIG, CURRENT_AI_MODEL } from "@/config/ai"
import { API_CONFIG } from "@/config/api"
const props = defineProps({
paretoData: {
type: Array,
default: () => []
},
selectedTimeRange: {
type: String,
default: '近1年'
}
})
const emit = defineEmits(['ai-analysis-complete'])
// 分析表单数据
const analysisForm = reactive({
selectedItem: ''
})
// 分析结果
const analysisResult = ref('')
// 机台不良数据
const workbenchData = ref([])
// 当前查询的日期范围
const currentStartDate = ref('')
const currentEndDate = ref('')
// 项目名称列表
const itemList = ref([
'漆膜厚度',
'击穿电压2(kv)',
'击穿电压5(kv)',
'击穿电压4(kv)',
'击穿电压3(kv)',
'回弹角(°)1',
'回弹角(°)2',
'击穿电压1(kv)',
'漆膜连续性(个)',
'最大外径',
'伸长率(%)1',
'导体f值',
'电阻值',
'预置伸长率',
'伸长率(%)2',
'平均单刮(N)',
'单向刮漆min(N)'
])
// 根据缺陷百分比设置进度条颜色
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) {
emit('ai-analysis-complete', '请先选择要分析的项目')
return
}
// 根据选择的时间范围计算开始和结束日期
const dateRange = getDateRangeByTimeRange(props.selectedTimeRange);
const { start_date: startDateStr, end_date: endDateStr } = dateRange;
// 保存当前查询的日期范围
currentStartDate.value = startDateStr;
currentEndDate.value = endDateStr;
// 调用机台不良分布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 prompt = `请对以下质检项目和机台不良分布进行详细分析:
项目名称: ${analysisForm.selectedItem}
数据范围: ${currentStartDate.value} ${currentEndDate.value}
帕累托分析数据:
${selectedItemData ?
`- 缺陷数量: ${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. 该项目缺陷对整体质量的影响
2. 产生缺陷的可能原因分析
3. 针对该项目的改进建议
4. 机台不良分布的规律分析
5. 该项目与其他项目的关联性分析`
try {
// 获取当前AI模型配置
const currentAIConfig = AI_CONFIG[CURRENT_AI_MODEL]
// 调用AI模型API进行分析
const response = await fetch(`${currentAIConfig.BASE_URL}/chat/completions`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${currentAIConfig.API_KEY}`
},
body: JSON.stringify({
model: currentAIConfig.MODEL,
messages: [
{
role: 'system',
content: '你是一位专业的质量控制专家,擅长分析具体质检项目并提供针对性的改进建议。'
},
{
role: 'user',
content: prompt
}
],
temperature: 0.3,
max_tokens: 1500
})
})
if (!response.ok) {
throw new Error(`API调用失败: ${response.status}`)
}
const data = await response.json()
const result = data.choices[0].message.content
analysisResult.value = result
// 发送分析结果完成事件
emit('ai-analysis-complete', result)
} catch (error) {
console.error('项目分析失败:', error)
const errorMessage = `项目分析失败: ${error.message}\n\n请检查网络连接或稍后再试。`
analysisResult.value = errorMessage
// 发送分析结果失败事件
emit('ai-analysis-complete', errorMessage)
}
}
</script>
<style scoped>
.item-analysis-container {
width: 100%;
padding: 20px;
}
.item-select-section {
margin-bottom: 20px;
padding: 15px;
background-color: #f5f7fa;
border-radius: 4px;
}
.analysis-result {
margin-top: 20px;
}
.analysis-result h3 {
margin-bottom: 15px;
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>