|
|
|
|
@ -113,6 +113,12 @@
|
|
|
|
|
<div class="right-panel">
|
|
|
|
|
<!-- 分析按钮 -->
|
|
|
|
|
<div class="analysis-button-container">
|
|
|
|
|
<el-button
|
|
|
|
|
type="success"
|
|
|
|
|
@click="analyzeWeibull"
|
|
|
|
|
:loading="weibullAnalyzing"
|
|
|
|
|
style="margin-left: 10px;"
|
|
|
|
|
>分段Weibull分析</el-button>
|
|
|
|
|
<el-button
|
|
|
|
|
type="primary"
|
|
|
|
|
@click="analyzeRepairRecords"
|
|
|
|
|
@ -120,16 +126,28 @@
|
|
|
|
|
>分析维修记录</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 分析结果显示区域 -->
|
|
|
|
|
<div class="analysis-result-container">
|
|
|
|
|
<el-input
|
|
|
|
|
v-model="analysisResult"
|
|
|
|
|
type="textarea"
|
|
|
|
|
:rows="20"
|
|
|
|
|
placeholder="点击分析维修记录按钮后,分析结果将显示在这里"
|
|
|
|
|
readonly
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<el-tabs type="border-card" v-model="analysisTab">
|
|
|
|
|
<el-tab-pane label="Weibull分析" name="weibullAnalysis">
|
|
|
|
|
<el-input
|
|
|
|
|
v-model="weibullResult"
|
|
|
|
|
type="textarea"
|
|
|
|
|
:rows="15"
|
|
|
|
|
placeholder="点击分段Weibull分析按钮后,分析结果将显示在这里"
|
|
|
|
|
readonly
|
|
|
|
|
/>
|
|
|
|
|
</el-tab-pane>
|
|
|
|
|
|
|
|
|
|
<el-tab-pane label="维修分析" name="repairAnalysis">
|
|
|
|
|
<el-input
|
|
|
|
|
v-model="analysisResult"
|
|
|
|
|
type="textarea"
|
|
|
|
|
:rows="15"
|
|
|
|
|
placeholder="点击分析维修记录按钮后,分析结果将显示在这里"
|
|
|
|
|
readonly
|
|
|
|
|
/>
|
|
|
|
|
</el-tab-pane>
|
|
|
|
|
|
|
|
|
|
</el-tabs>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<template #footer>
|
|
|
|
|
@ -175,6 +193,9 @@ const uniqueBreakdownNames = ref([])
|
|
|
|
|
// 分析相关状态
|
|
|
|
|
const analyzing = ref(false)
|
|
|
|
|
const analysisResult = ref('')
|
|
|
|
|
const weibullAnalyzing = ref(false)
|
|
|
|
|
const weibullResult = ref('')
|
|
|
|
|
const analysisTab = ref('repairAnalysis')
|
|
|
|
|
|
|
|
|
|
// 监听设备类型变化
|
|
|
|
|
watch(() => props.selectedEquipmentType, (newVal, oldVal) => {
|
|
|
|
|
@ -513,6 +534,177 @@ const analyzeRepairRecords = () => {
|
|
|
|
|
}
|
|
|
|
|
}, 1500) // 模拟分析过程耗时
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 分段Weibull分析
|
|
|
|
|
const analyzeWeibull = async () => {
|
|
|
|
|
if (!selectedEquipmentCode.value) {
|
|
|
|
|
weibullResult.value = '请先选择设备。'
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
weibullAnalyzing.value = true
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 构建API参数
|
|
|
|
|
const params = new URLSearchParams({
|
|
|
|
|
equipment_code: selectedEquipmentCode.value,
|
|
|
|
|
window_size: '5'
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// 添加日期范围参数
|
|
|
|
|
if (props.dateRange && props.dateRange.start_date) {
|
|
|
|
|
params.append('start_date', props.dateRange.start_date)
|
|
|
|
|
}
|
|
|
|
|
if (props.dateRange && props.dateRange.end_date) {
|
|
|
|
|
params.append('end_date', props.dateRange.end_date)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 添加故障名称筛选
|
|
|
|
|
if (selectedBreakdownName.value) {
|
|
|
|
|
params.append('breakdown_name_filter', selectedBreakdownName.value)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const apiUrl = `${API_CONFIG.BASE_URL}/api/eq-repair/weibull/analysis?${params.toString()}`
|
|
|
|
|
console.log('Weibull分析API URL:', apiUrl)
|
|
|
|
|
|
|
|
|
|
const response = await fetch(apiUrl)
|
|
|
|
|
const data = await response.json()
|
|
|
|
|
|
|
|
|
|
console.log('Weibull分析返回数据:', data)
|
|
|
|
|
|
|
|
|
|
if (data.code === 200 && data.data) {
|
|
|
|
|
if (data.data.original_count === 0 || data.data.valid_count === 0) {
|
|
|
|
|
weibullResult.value = `=== 设备 ${selectedEquipmentCode.value} 分段Weibull分析报告 ===\n\n` +
|
|
|
|
|
`【分析结果】\n` +
|
|
|
|
|
`- 在指定的时间范围内,该设备没有足够的维修记录数据进行分析。\n` +
|
|
|
|
|
`- 可能原因:\n` +
|
|
|
|
|
` 1. 该设备在所选日期范围内没有维修记录\n` +
|
|
|
|
|
` 2. 故障记录数据不完整\n` +
|
|
|
|
|
`- 建议:\n` +
|
|
|
|
|
` 1. 尝试扩大日期范围\n` +
|
|
|
|
|
` 2. 选择其他设备进行分析\n` +
|
|
|
|
|
` 3. 检查该设备的实际维修记录\n\n` +
|
|
|
|
|
`API返回信息: ${JSON.stringify(data.data, null, 2)}`
|
|
|
|
|
} else {
|
|
|
|
|
weibullResult.value = formatWeibullResult(data.data)
|
|
|
|
|
}
|
|
|
|
|
} else if (data.detail) {
|
|
|
|
|
weibullResult.value = `API错误: ${data.detail}`
|
|
|
|
|
} else if (data.message) {
|
|
|
|
|
weibullResult.value = `API消息: ${data.message}`
|
|
|
|
|
} else {
|
|
|
|
|
weibullResult.value = `未能获取到有效的分析结果。\n\n原始响应: ${JSON.stringify(data, null, 2)}`
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Weibull分析API调用失败:', error)
|
|
|
|
|
weibullResult.value = `分析失败: ${error.message}`
|
|
|
|
|
} finally {
|
|
|
|
|
weibullAnalyzing.value = false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 格式化Weibull分析结果
|
|
|
|
|
const formatWeibullResult = (data) => {
|
|
|
|
|
let result = `=== 设备 ${data.equipment_code || selectedEquipmentCode.value} 分段Weibull分析报告 ===\n`
|
|
|
|
|
result += `【消息】${data.message || '分析完成'}\n\n`
|
|
|
|
|
|
|
|
|
|
// 基本统计
|
|
|
|
|
result += `【基本统计】\n`
|
|
|
|
|
result += `- 设备编号: ${data.equipment_code || 'N/A'}\n`
|
|
|
|
|
result += `- 维修记录数: ${data.record_count || 0} 条\n`
|
|
|
|
|
result += `- 分析窗口大小: ${data.window_size || 'N/A'}\n`
|
|
|
|
|
result += `- 间隔数: ${data.interval_count || 0}\n`
|
|
|
|
|
result += `- 平均间隔天数: ${data.avg_interval_days?.toFixed(2) || 'N/A'} 天\n`
|
|
|
|
|
result += `- 标准差间隔天数: ${data.std_interval_days?.toFixed(2) || 'N/A'} 天\n`
|
|
|
|
|
result += `- 当前运行天数: ${data.current_runtime_days?.toFixed(2) || 'N/A'} 天\n\n`
|
|
|
|
|
|
|
|
|
|
// Weibull参数
|
|
|
|
|
result += `【Weibull分布参数】\n`
|
|
|
|
|
result += `- 模型类型: ${data.model_type || 'N/A'}\n`
|
|
|
|
|
result += `- 形状参数(β): ${data.current_weibull_beta?.toFixed(4) || 'N/A'}\n`
|
|
|
|
|
result += `- 尺度参数(η): ${data.current_weibull_eta?.toFixed(2) || 'N/A'} 天\n\n`
|
|
|
|
|
|
|
|
|
|
// 失效概率预测
|
|
|
|
|
if (data.predictions) {
|
|
|
|
|
result += `【失效概率预测】\n`
|
|
|
|
|
const pred = data.predictions
|
|
|
|
|
if (pred['7_days_failure_prob'] !== undefined) {
|
|
|
|
|
result += `- 7天失效概率: ${pred['7_days_failure_prob'].toFixed(2)}%\n`
|
|
|
|
|
}
|
|
|
|
|
if (pred['15_days_failure_prob'] !== undefined) {
|
|
|
|
|
result += `- 15天失效概率: ${pred['15_days_failure_prob'].toFixed(2)}%\n`
|
|
|
|
|
}
|
|
|
|
|
if (pred['30_days_failure_prob'] !== undefined) {
|
|
|
|
|
result += `- 30天失效概率: ${pred['30_days_failure_prob'].toFixed(2)}%\n`
|
|
|
|
|
}
|
|
|
|
|
if (pred['60_days_failure_prob'] !== undefined) {
|
|
|
|
|
result += `- 60天失效概率: ${pred['60_days_failure_prob'].toFixed(2)}%\n`
|
|
|
|
|
}
|
|
|
|
|
if (pred['90_days_failure_prob'] !== undefined) {
|
|
|
|
|
result += `- 90天失效概率: ${pred['90_days_failure_prob'].toFixed(2)}%\n`
|
|
|
|
|
}
|
|
|
|
|
result += `\n`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 分析结论
|
|
|
|
|
result += `【分析结论】\n`
|
|
|
|
|
|
|
|
|
|
if (data.current_weibull_beta !== undefined) {
|
|
|
|
|
const beta = data.current_weibull_beta
|
|
|
|
|
let reliabilityTrend = ''
|
|
|
|
|
let maintenanceAdvice = ''
|
|
|
|
|
|
|
|
|
|
if (beta < 1) {
|
|
|
|
|
reliabilityTrend = '设备处于"早期失效期",故障率随时间下降'
|
|
|
|
|
maintenanceAdvice = '建议:加强初期调试和磨合期监控,及时更换早期失效的部件'
|
|
|
|
|
} else if (beta >= 1 && beta < 1.5) {
|
|
|
|
|
reliabilityTrend = '设备处于"随机失效期",故障率相对稳定'
|
|
|
|
|
maintenanceAdvice = '建议:执行预防性维护,保持当前维护计划'
|
|
|
|
|
} else {
|
|
|
|
|
reliabilityTrend = '设备处于"磨损失效期",故障率随时间增加'
|
|
|
|
|
maintenanceAdvice = '建议:考虑预防性更换关键部件,制定大修计划'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result += `- 可靠性趋势: ${reliabilityTrend}\n`
|
|
|
|
|
result += `- 维护建议: ${maintenanceAdvice}\n`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (data.current_weibull_eta !== undefined) {
|
|
|
|
|
const eta = data.current_weibull_eta
|
|
|
|
|
result += `- 特征寿命(η): ${eta.toFixed(2)} 天,约 ${(eta / 30).toFixed(1)} 个月\n`
|
|
|
|
|
result += ` (表示63.2%设备预计在此时间内失效的时间点)\n`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (data.avg_interval_days !== undefined && data.std_interval_days !== undefined) {
|
|
|
|
|
result += `- 平均维修间隔: ${data.avg_interval_days.toFixed(2)} 天\n`
|
|
|
|
|
result += `- 间隔标准差: ${data.std_interval_days.toFixed(2)} 天\n`
|
|
|
|
|
|
|
|
|
|
const cv = (data.std_interval_days / data.avg_interval_days * 100).toFixed(1)
|
|
|
|
|
result += `- 变异系数: ${cv}%\n`
|
|
|
|
|
|
|
|
|
|
if (parseFloat(cv) < 30) {
|
|
|
|
|
result += `- 维修间隔较稳定,维护计划可预测性高\n`
|
|
|
|
|
} else {
|
|
|
|
|
result += `- 维修间隔波动较大,建议进一步分析影响维修间隔的因素\n`
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (data.current_runtime_days !== undefined) {
|
|
|
|
|
const eta = data.current_weibull_eta || 0
|
|
|
|
|
const runtime = data.current_runtime_days
|
|
|
|
|
if (eta > 0) {
|
|
|
|
|
const ratio = (runtime / eta * 100).toFixed(1)
|
|
|
|
|
result += `\n- 当前已运行: ${runtime.toFixed(2)} 天 (占特征寿命的 ${ratio}%)\n`
|
|
|
|
|
if (parseFloat(ratio) > 50) {
|
|
|
|
|
result += `- 警告:设备已超过特征寿命的50%,建议密切关注设备状态\n`
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result += `\n`
|
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|