@@ -315,6 +319,8 @@ import BEPBreakEvenCard from '../components/BEPBreakEvenCard.vue'
import MyDialog from '../components/MyDialog.vue'
// 预估区标签(财务裁定 2026-10-02:预估行单列展示,不与实测相加/同线)
import ForecastTag from '../components/ForecastTag.vue'
+import CaliberBadge from '../components/CaliberBadge.vue'
+import { caliberGapFor, currentCaliberEntityId, isCaliberKpiCode, type CaliberGapFacts } from '../constants/caliber'
const router = useRouter()
@@ -365,6 +371,8 @@ const yellowKpis = computed(() => kpis.value.filter((k: any) => k.alert_level ==
const myKpis = ref
([])
const finKpis = ref([])
const finSummary = ref({})
+// 缺票期标识:毛利率只显示现值 + 「测算/待票」,不按实账发票重算(仅登记账套挂载)
+const caliberFacts = ref(caliberGapFor(currentCaliberEntityId()))
// 预估区(单列,不计入实测汇总;财务裁定 2026-10-02)
const forecastList = ref([])
const enabledChannels = ref(0)
@@ -495,6 +503,7 @@ function onCustomRangeChange(val: any) {
async function loadData() {
try {
const entityId = Number(localStorage.getItem('cma_entity_id') || 1)
+ caliberFacts.value = caliberGapFor(entityId)
const params = { ...getPeriodParams(), entity_id: entityId }
// include_forecast=true:预估行**单列返回**(forecast 字段),实测取值不受影响
if (userRole.value === 'ceo') {
diff --git a/frontend/src/views/MapCanvas.vue b/frontend/src/views/MapCanvas.vue
index 654cf07c..58d6420a 100644
--- a/frontend/src/views/MapCanvas.vue
+++ b/frontend/src/views/MapCanvas.vue
@@ -54,6 +54,11 @@
@completeness="showCompleteness = true"
/>
+
+
+
+
+
@@ -316,6 +321,8 @@ import MapCompleteness from "../components/strategy-map/MapCompleteness.vue"
import ConnectionLines from "../components/strategy/ConnectionLines.vue"
import MapCanvasToolbar from "../components/map-canvas/MapCanvasToolbar.vue"
import MapDimensionFilter from "../components/map-canvas/MapDimensionFilter.vue"
+import CaliberBadge from "../components/CaliberBadge.vue"
+import { caliberGapFor, currentCaliberEntityId } from "../constants/caliber"
import MapCanvasDialogs from "../components/map-canvas/MapCanvasDialogs.vue"
import ConnectionManagerDialog from "../components/map-canvas/ConnectionManagerDialog.vue"
import MyDialog from "../components/MyDialog.vue"
@@ -351,6 +358,8 @@ const kpiNameMap = reactive>({})
// 维度数据(对应backend的dimensions)
const dimensions = reactive([])
const loading = ref(true)
+// 口径标识:仅登记过缺票事实的账套(当前为 entity 2 陕西博海)才挂「科目口径 · 缺票」
+const caliberFacts = ref(caliberGapFor(currentCaliberEntityId()))
// ── 仪表盘视图状态(2026-10-18 V1+V3 合版) ──
/** 四层视觉色(本页按设计规范呈现,不改动地图存储的颜色值) */
@@ -790,6 +799,7 @@ watch(zoomLevel, () => {
// ── 画布加载 ──
function loadCanvas() {
+ caliberFacts.value = caliberGapFor(currentCaliberEntityId())
if (!selectedMap.value) return
dimensions.splice(0, dimensions.length)
connections.value = []
@@ -2053,6 +2063,9 @@ onUnmounted(() => {
/* ── 页面布局 ── */
.map-canvas-page { padding: 16px; height: 100vh; display: flex; flex-direction: column; position: relative; overflow: hidden; }
+/* 口径标识条:常驻首屏,右侧对齐,不占画布高度(flex-shrink: 0) */
+.caliber-strip { display: flex; justify-content: flex-end; align-items: center; margin: -4px 0 8px; flex-shrink: 0; }
+
.linking-bar {
display: flex; align-items: center; gap: 12px;
padding: 8px 16px; background: #fdf6ec; border: 1px solid #f5dab1;
diff --git a/frontend/src/views/StrategyMap.vue b/frontend/src/views/StrategyMap.vue
index d9f915a8..8feaa14c 100644
--- a/frontend/src/views/StrategyMap.vue
+++ b/frontend/src/views/StrategyMap.vue
@@ -27,6 +27,8 @@