依据:wecom-finance/reports/CMA_口径裁定_20260917.md(任总 2026-09-17 23:14「按建议执行」) 裁定1(现金流「投资活动净额=0」参与判定) - classify_enterprise():0 为合法输入;投资恒为 0 → 经营(±)×筹资(±) 二维映射出 2 个 候选类型(candidate_type_nos/candidates),不再整体判「未判定」;投资栏 investing_note 标注「本期无投资活动」;经营/筹资亦为 0 → 回退「未判定(无投资活动)」,不报错不静默 - /analysis 增 classification_dimension / investing_note / nets.investing.note;前端出 二维横幅 + 候选行高亮 + 投资栏「本期无投资活动」(不给单一类型名) - import_cashflow_statements.py:打印层修 2D(type_no=None)TypeError 崩溃;NA 措辞改为 「按 0 参与判定」(机读短语 NA_PHRASE_TMPL/parse_na_activities 未动) 裁定2a(比率类单位统一「百分比(%)」口径,先做) - 新增 app/utils/caliber_units.py:逐 KPI 对照表 RATIO_CALIBER_TABLE(唯一事实源)+ 判定侧 唯一入口 resolve_caliber();3 项需归一 ×100(流动/速动/毛利率),12 项取数已百分数不归一; 表外且命中「疑似错配」窄形态(阈值子句量级≥100 且 0<|实测|<10 且单位属比率类)→ dimension_suspect:不落预警、不推送(唯一规则,防 586/587 假红灯复发) - alert_generator:判定前归一,文案写「口径归一 ×100(原值 1.29 → 129%)」留审计线索 - 新增 scripts/kpi_unit_crosscheck.py(只读对照表产出器) 裁定2b(期间由「当月硬编码」→「最近可用期间」,后做) - resolve_latest_period():取该 KPI 自己的最新 YYYY-MM(禁全局 MAX,防演示账套劫持); 伪期间(2026-H1/H2、2025-FY)在 Python 侧过滤(保「单测=生产」语义) - 过渡期覆盖度自检扩展:记录回落后的期间分布 + 当月 0 条归因提示 - --dry-run(零写入零推送)作放行前抽查证据;generate_and_push/run_alert_check 支持 dry_run 测试:backend/tests/test_caliber_rulings_20260917.py 17 项;全量 1158 passed/1 xfailed
This commit is contained in:
@@ -25,14 +25,24 @@
|
||||
<el-card shadow="never" class="verdict-card">
|
||||
<div class="verdict-left" v-if="classification.classified">
|
||||
<div class="verdict-badge">
|
||||
<span class="verdict-type">类型{{ classification.type_no }}</span>
|
||||
<span class="verdict-name">{{ classification.health_emoji }} {{ classification.name }}</span>
|
||||
<span class="verdict-type" v-if="isTwoDim">二维判定</span>
|
||||
<span class="verdict-type" v-else>类型{{ classification.type_no }}</span>
|
||||
<span class="verdict-name" v-if="isTwoDim">🧭 按 经营(±) × 筹资(±) 二维映射</span>
|
||||
<span class="verdict-name" v-else>{{ classification.health_emoji }} {{ classification.name }}</span>
|
||||
</div>
|
||||
<div class="verdict-health">
|
||||
<el-tag :type="healthTagType" size="small">健康度:{{ classification.health_emoji }} {{ classification.health_label }}</el-tag>
|
||||
<el-tag v-if="isTwoDim" size="small" type="warning">投资活动为 0:{{ investingNote }}</el-tag>
|
||||
<el-tag v-else :type="healthTagType" size="small">健康度:{{ classification.health_emoji }} {{ classification.health_label }}</el-tag>
|
||||
<el-tag v-if="classification.lifecycle" size="small" type="info" effect="plain" style="margin-left:8px">生命周期:{{ classification.lifecycle }}</el-tag>
|
||||
<el-tag size="small" effect="plain" style="margin-left:8px">{{ source === 'official' ? '📄 官方现金流量表' : '✍️ 人工录入' }}</el-tag>
|
||||
</div>
|
||||
<!-- 裁定1:投资活动为 0 → 显式列出二维映射的候选类型(不得只给单一类型名) -->
|
||||
<div v-if="isTwoDim" style="margin-top:8px">
|
||||
<el-tag v-for="c in (classification.candidates || [])" :key="c.type_no"
|
||||
size="small" effect="plain" style="margin-right:8px">
|
||||
候选 类型{{ c.type_no }} {{ c.name }}(O{{ c.o_sign }} I{{ c.i_sign }} F{{ c.f_sign }})
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
<div class="verdict-left" v-else>
|
||||
<el-alert type="warning" :closable="false" :title="classification.reason || '净额数据不足,暂无法判定类型'" show-icon />
|
||||
@@ -47,6 +57,8 @@
|
||||
<div class="net-sign" :style="{ color: netColor(n) }">
|
||||
{{ n.sign === '+' ? '进钱 ▲' : n.sign === '-' ? '出钱 ▼' : '为0' }}
|
||||
</div>
|
||||
<!-- 裁定1:投资活动=0 的栏位显式标注「本期无投资活动」 -->
|
||||
<div class="net-note" v-if="n.note">{{ n.note }}</div>
|
||||
<div class="net-hint">{{ n.hint }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -67,6 +79,9 @@
|
||||
<el-col :span="9">
|
||||
<el-card shadow="never" header="判定说明(CMA P2 · 现金流量表分析)">
|
||||
<template v-if="classification.classified">
|
||||
<el-alert v-if="isTwoDim" type="warning" :closable="false" title="投资活动为 0(本期无投资活动)" show-icon style="margin-bottom:8px">
|
||||
<span>投资活动栏位显式标注「本期无投资活动」;按「经营(±) × 筹资(±)」二维映射到候选类型:{{ candidateLabel }}——投资活动无正负号,需结合业务实质在候选中确认。</span>
|
||||
</el-alert>
|
||||
<p class="desc-p">{{ classification.profile }}</p>
|
||||
<el-alert type="error" :closable="false" title="风险提示" show-icon>
|
||||
<span>{{ classification.risk }}</span>
|
||||
@@ -88,7 +103,7 @@
|
||||
<el-table :data="rules" size="small" stripe :row-class-name="ruleRowClass">
|
||||
<el-table-column prop="type_no" label="类型" width="60" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.type_no === currentType ? 'primary' : 'info'" size="small" effect="plain">
|
||||
<el-tag :type="isHighlighted(row.type_no) ? 'primary' : 'info'" size="small" effect="plain">
|
||||
{{ row.type_no }}
|
||||
</el-tag>
|
||||
</template>
|
||||
@@ -245,7 +260,22 @@ const netList = computed(() => {
|
||||
.map((k) => ({ key: k, ...meta[k], ...n[k] }))
|
||||
})
|
||||
|
||||
const currentType = computed(() => (classification.value?.classified ? classification.value.type_no : -1))
|
||||
// ── 裁定1(2026-09-17):投资活动=0 → 二维判定(候选 2 个 + 投资栏标注「本期无投资活动」)──
|
||||
const isTwoDim = computed(() => classification.value?.dimension === '2D' && !!classification.value?.classified)
|
||||
const investingNote = computed(() => classification.value?.investing_note || '本期无投资活动')
|
||||
const candidateLabel = computed(() =>
|
||||
(classification.value?.candidates || []).map((c: any) => `类型${c.type_no} ${c.name}`).join(' / ')
|
||||
)
|
||||
// 二维判定时高亮全部候选类型行(不给单一类型名)
|
||||
const highlightTypes = computed<number[]>(() => {
|
||||
if (!classification.value?.classified) return []
|
||||
return isTwoDim.value
|
||||
? (classification.value.candidate_type_nos || [])
|
||||
: [classification.value.type_no]
|
||||
})
|
||||
function isHighlighted(typeNo: number): boolean {
|
||||
return highlightTypes.value.includes(typeNo)
|
||||
}
|
||||
|
||||
const healthTagType = computed(() => {
|
||||
const label = classification.value?.health_label || ''
|
||||
@@ -267,7 +297,7 @@ function netColor(n: any): string {
|
||||
}
|
||||
|
||||
function ruleRowClass({ row }: any) {
|
||||
return row.type_no === currentType.value ? 'rule-row-current' : ''
|
||||
return isHighlighted(row.type_no) ? 'rule-row-current' : ''
|
||||
}
|
||||
|
||||
async function loadPeriods() {
|
||||
@@ -547,6 +577,13 @@ onMounted(async () => {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
}
|
||||
/* 裁定1:投资活动=0 → 「本期无投资活动」标注 */
|
||||
.net-note {
|
||||
font-size: 11px;
|
||||
color: #e6a23c;
|
||||
margin-top: 2px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.net-hint {
|
||||
font-size: 11px;
|
||||
color: #909399;
|
||||
|
||||
Reference in New Issue
Block a user