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.

210 lines
5.7 KiB
Vue

<template>
<div class="pareto-analysis-container">
<!-- 帕累托分析按钮 -->
<div style="margin-bottom: 10px;">
<el-button
type="success"
icon="ChatDotRound"
@click="handleAIAnalysis"
:loading="aiAnalysisLoading"
>
AI分析
</el-button>
</div>
<!-- 帕累托数据表格 -->
<el-table
v-if="paretoData.length > 0"
:data="paretoData"
border
style="width: 100%"
stripe
>
<el-table-column prop="item_name" label="检测项" width="180" />
<el-table-column prop="defect_count" label="缺陷数" width="100" />
<el-table-column prop="defect_percentage" label="缺陷百分比" width="120">
<template #default="scope">
{{ scope.row.defect_percentage }}%
</template>
</el-table-column>
<el-table-column prop="cumulative_percentage" label="累计百分比" width="120">
<template #default="scope">
{{ scope.row.cumulative_percentage }}%
</template>
</el-table-column>
<el-table-column label="缺陷占比">
<template #default="scope">
<el-progress
:percentage="scope.row.defect_percentage"
:show-text="false"
:color="getProgressColor(scope.row.defect_percentage)"
/>
</template>
</el-table-column>
</el-table>
<!-- 统计信息 -->
<div v-if="paretoData.length > 0" class="statistics-info">
<p>数据范围: {{ dateRange.start_date }} {{ dateRange.end_date }}</p>
<p>总计检测项: {{ paretoData.length }}</p>
</div>
<!-- AI分析结果对话框 -->
<el-dialog
v-model="aiDialogVisible"
title="AI分析结果"
width="60%"
:close-on-click-modal="false"
>
<div class="ai-analysis-content">
<el-input
v-model="aiAnalysisResult"
type="textarea"
:rows="15"
placeholder="AI分析结果将显示在这里"
readonly
/>
</div>
</el-dialog>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { AI_CONFIG, CURRENT_AI_MODEL } from "@/config/ai"
const props = defineProps({
selectedTimeRange: {
type: String,
default: '近1年'
},
paretoData: {
type: Array,
default: () => []
},
dateRange: {
type: Object,
default: () => ({
start_date: '',
end_date: ''
})
},
apiKey: {
type: String,
default: AI_CONFIG[CURRENT_AI_MODEL].API_KEY
}
})
const emit = defineEmits(['ai-analysis-complete'])
// AI分析相关状态
const aiDialogVisible = ref(false)
const aiAnalysisResult = ref("")
const aiAnalysisLoading = ref(false)
// 根据缺陷百分比设置进度条颜色
function getProgressColor(percentage) {
if (percentage >= 30) return '#f56c6c'; // 红色 - 高缺陷率
if (percentage >= 15) return '#e6a23c'; // 橙色 - 中等缺陷率
if (percentage >= 5) return '#409eff'; // 蓝色 - 低缺陷率
return '#67c23a'; // 绿色 - 很低缺陷率
}
// AI分析功能
async function handleAIAnalysis() {
if (props.paretoData.length === 0) {
emit('ai-analysis-complete', '请先获取帕累托分析数据')
return
}
aiAnalysisLoading.value = true
aiDialogVisible.value = true
aiAnalysisResult.value = '正在分析中,请稍候...'
try {
// 准备分析提示词
const prompt = `请分析以下帕累托分析数据,提供专业的质量控制见解:
数据范围: ${props.dateRange.start_date} ${props.dateRange.end_date}
检测项目总数: ${props.paretoData.length}
详细数据:
${props.paretoData.map(item =>
`- ${item.item_name}: 缺陷数 ${item.defect_count}, 缺陷占比 ${item.defect_percentage}%, 累计占比 ${item.cumulative_percentage}%`
).join('\n')}
请从以下角度进行分析
1. 主要缺陷项及其影响程度
2. 帕累托原理(80/20法则)在此数据中的体现
3. 针对高缺陷率项的改进建议
4. 质量控制重点优化方向`
// 获取当前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.1,
max_tokens: 2000
})
})
if (!response.ok) {
throw new Error(`API调用失败: ${response.status}`)
}
const data = await response.json()
const analysisResult = data.choices[0].message.content
aiAnalysisResult.value = analysisResult
// 发送分析结果完成事件
emit('ai-analysis-complete', analysisResult)
} catch (error) {
console.error('AI分析失败:', error)
const errorMessage = `AI分析失败: ${error.message}\n\n请检查网络连接或稍后再试。`
aiAnalysisResult.value = errorMessage
// 发送分析结果失败事件
emit('ai-analysis-complete', errorMessage)
} finally {
aiAnalysisLoading.value = false
}
}
</script>
<style scoped>
.pareto-analysis-container {
width: 100%;
}
.statistics-info {
margin-top: 10px;
padding: 10px;
background-color: #f5f7fa;
border-radius: 4px;
}
.statistics-info p {
margin: 5px 0;
font-size: 14px;
}
.ai-analysis-content {
padding: 10px 0;
}
</style>