Files
cma-management/frontend/src/components/CaliberBadge.vue
T
wecom-fullstack a8c9b38fff
ci/woodpecker/push/main Pipeline was canceled
feat(caliber-label): 科目口径·缺票 常驻标识 + 测算/待票 数值标识(展示层 P2)
- 新增 constants/caliber.ts(文案单一真源)+ components/CaliberBadge.vue(常驻,非 hover)
- 经营看板/Dashboard:页头常驻「科目口径 · 缺票」(tooltip 含 四件套 0/4、invoice_check 0 行)+ 毛利率与 A 口径 KPI 卡「测算/待票」
- 战略地图看板/StrategyMap:meta-bar 常驻标识位 + 节点级测算标识(与 v4 §2/§4 共用同一组件)
- 战略地图画布/MapCanvas、KPI 列表 KPIListView 同步复用同一组件
- 只做展示层:不改库、不重算历史值、不静默按实账回填
2026-10-20 02:11:00 +08:00

82 lines
2.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<span
v-if="facts"
class="caliber-badge"
:class="`caliber-badge--${kind}`"
:data-caliber-badge="kind"
:data-caliber-tip="tipText"
:title="tipText"
role="note"
:aria-label="`${labelText}:${tipText}`"
>
{{ labelText }}
</span>
</template>
<script setup lang="ts">
/**
* 口径标识(常驻,非 hover 临时提示)
*
* - kind="account_invoice_gap":看板/战略地图首屏常驻「科目口径 · 缺票」
* - kind="estimate":缺票期数值旁「测算/待票」(只标现值,不重算)
*
* 文案一律取自 constants/caliber.ts,禁止页内另写。
* 使用原生 title 作为工具提示(与 ForecastTag 同惯例),常驻文本 + 长说明分离。
*/
import { computed } from 'vue'
import {
CALIBER_ACCOUNT_GAP_LABEL,
CALIBER_ESTIMATE_LABEL,
caliberEstimateTip,
caliberGapTip,
type CaliberGapFacts,
type CaliberGapKind,
} from '../constants/caliber'
const props = withDefaults(
defineProps<{
kind?: CaliberGapKind
/** 账套缺票事实;缺省时不渲染(避免把博海事实套到其它账套) */
facts?: CaliberGapFacts | null
/** 允许覆盖标签文案(默认取常量真源) */
label?: string
}>(),
{ kind: 'account_invoice_gap', facts: null, label: '' },
)
const labelText = computed(() => {
if (props.label) return props.label
return props.kind === 'estimate' ? CALIBER_ESTIMATE_LABEL : CALIBER_ACCOUNT_GAP_LABEL
})
const tipText = computed(() => {
if (!props.facts) return ''
return props.kind === 'estimate' ? caliberEstimateTip(props.facts) : caliberGapTip(props.facts)
})
</script>
<style scoped>
.caliber-badge {
display: inline-flex;
align-items: center;
height: 20px;
padding: 0 7px;
border-radius: 3px;
font-size: 12px;
line-height: 18px;
white-space: nowrap;
cursor: help;
vertical-align: middle;
}
.caliber-badge--account_invoice_gap {
color: var(--el-color-warning);
background: var(--el-color-warning-light-9);
border: 1px solid var(--el-color-warning-light-5);
}
.caliber-badge--estimate {
color: var(--el-text-color-secondary);
background: var(--el-fill-color-lighter);
border: 1px solid var(--el-border-color-lighter);
}
</style>