feat: AI事前预警 — 现金流预测+预警扩展+准确率+情景建议

This commit is contained in:
Hermes CI Fix
2026-07-21 18:22:04 +08:00
parent 270d7758f8
commit c4e91f28ef
9 changed files with 1101 additions and 6 deletions
+40 -4
View File
@@ -39,11 +39,11 @@
</div>
<el-table :data="alerts" v-loading="loading" style="width:100%" border stripe size="small">
<el-table-column prop="alert_message" label="预警信息" min-width="320">
<el-table-column prop="alert_message" label="预警信息" min-width="300">
<template #default="{ row }">
<div style="display:flex;align-items:center;gap:4px;">
<el-tag v-if="isTrendAlert(row.alert_message)" size="small" type="info" effect="plain">趋势</el-tag>
<el-tag v-else size="small" type="primary" effect="plain">静态</el-tag>
<el-tag v-if="row.alert_type === 'forecast'" size="small" type="warning" effect="plain">🔮预测</el-tag>
<el-tag v-else size="small" type="primary" effect="plain">实际</el-tag>
<span>{{ row.alert_message }}</span>
</div>
</template>
@@ -147,6 +147,8 @@
<el-option label="已禁用" :value="0" />
</el-select>
<el-button type="primary" size="small" @click="loadRules">查询</el-button>
<el-button size="small" @click="checkForecastAlerts" :loading="fcLoading">🔮 检查预测值</el-button>
<el-button size="small" @click="generateAlertSuggestions" :loading="sgLoading">💡 生成情景建议</el-button>
</div>
<el-table :data="rules" v-loading="rulesLoading" style="width:100%" border stripe size="small">
@@ -254,7 +256,7 @@
</el-dialog>
<!-- 编辑预警规则弹窗 -->
<el-dialog v-model="showRuleForm" title="编辑预警规则" width="500px">
<el-dialog v-model="showRuleForm" title="编辑预警规则" width="520px">
<el-form :model="ruleForm" label-width="110px" size="small">
<el-form-item label="规则类型">
<el-select v-model="ruleForm.rule_type" style="width:100%">
@@ -264,6 +266,14 @@
<el-option label="下降趋势预警" value="trend_down" />
</el-select>
</el-form-item>
<el-form-item label="触发条件">
<el-select v-model="ruleForm.trigger_on" style="width:100%">
<el-option label="实际值超限" value="actual" />
<el-option label="预测值超限" value="forecast" />
<el-option label="两者都触发" value="both" />
</el-select>
<span style="color:#909399;font-size:12px;margin-top:2px;display:block;">预测值超限时系统会检查未来7天现金流预测是否触及阈值</span>
</el-form-item>
<el-form-item label="是否启用">
<el-switch v-model="ruleForm.enabled" :active-value="1" :inactive-value="0" />
</el-form-item>
@@ -366,6 +376,7 @@ const calcLoading = ref(false)
const ruleForm = ref({
kpi_id: null as number | null,
rule_type: 'static',
trigger_on: 'actual',
enabled: 1,
params: { green: '', yellow: '', red: '', sensitivity: 1.0, threshold_pct: 10 },
})
@@ -467,6 +478,7 @@ function editRule(row: any) {
ruleForm.value = {
kpi_id: row.kpi_id,
rule_type: row.rule_type,
trigger_on: row.trigger_on || 'actual',
enabled: row.enabled,
params: { green: '', yellow: '', red: '', sensitivity: 1.0, threshold_pct: 10, ...(params || {}) },
}
@@ -478,6 +490,7 @@ async function saveRule() {
try {
const data = {
rule_type: ruleForm.value.rule_type,
trigger_on: ruleForm.value.trigger_on,
enabled: ruleForm.value.enabled,
params: ruleForm.value.params,
}
@@ -514,6 +527,29 @@ async function generateRules() {
generating.value = false
}
async function checkForecastAlerts() {
fcLoading.value = true
try {
const r: any = await alertRulesApi.checkForecast()
ElMessage.success(r.message || '预测值检查完成')
loadAlerts()
} catch (e) { ElMessage.error('检查失败') }
fcLoading.value = false
}
async function generateAlertSuggestions() {
sgLoading.value = true
try {
const r: any = await alertRulesApi.generateSuggestions()
ElMessage.success(r.message || '情景建议已生成')
loadAlerts()
} catch (e) { ElMessage.error('生成失败') }
sgLoading.value = false
}
const fcLoading = ref(false)
const sgLoading = ref(false)
async function calcDynamic() {
calcLoading.value = true
try {