feat: 预算按战略地图隔离(map_id) — 切换地图数据区分
问题: 预算数据无map_id, 两地图共用KPI时预算无法区分(切地图数据均显示) 修复: - budget_plans 加 map_id 字段+索引 - list 支持 map_id 过滤(含NULL历史预算兼容迁移) - create 收 map_id + 去重键含map_id(同KPI不同地图可各自预算) - 前端: loadBudget/loadStrategyBudget 传 map_id, 保存带 map_id - 端到端验证: 地图51 F_REVENUE 300(map_id=51) 地图51显示/地图32不显示 ✓ pytest 35+11 passed, 部署
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
"""
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy import func
|
||||
from sqlalchemy import func, or_
|
||||
from typing import Optional
|
||||
from datetime import datetime
|
||||
|
||||
@@ -20,6 +20,7 @@ router = APIRouter(prefix="/api/cma/budget", tags=["预算管理"],
|
||||
@router.get("/plans")
|
||||
def list_budget_plans(
|
||||
kpi_id: Optional[int] = Query(None),
|
||||
map_id: Optional[int] = Query(None, description="按战略地图过滤预算"),
|
||||
period: Optional[str] = Query(None),
|
||||
year: Optional[int] = Query(None),
|
||||
version: Optional[str] = Query(None),
|
||||
@@ -32,6 +33,9 @@ def list_budget_plans(
|
||||
KPIDefinition, BudgetPlan.kpi_id == KPIDefinition.id
|
||||
).filter(KPIDefinition.entity_id == entity_id)
|
||||
|
||||
if map_id:
|
||||
# 按地图隔离: 显示该地图的预算 + 未绑定地图的历史预算(NULL, 兼容迁移)
|
||||
query = query.filter(or_(BudgetPlan.map_id == map_id, BudgetPlan.map_id.is_(None)))
|
||||
if kpi_id:
|
||||
query = query.filter(BudgetPlan.kpi_id == kpi_id)
|
||||
if period:
|
||||
@@ -51,6 +55,7 @@ def list_budget_plans(
|
||||
result.append({
|
||||
"id": p.id,
|
||||
"kpi_id": p.kpi_id,
|
||||
"map_id": p.map_id,
|
||||
"kpi_code": kpi.kpi_code if kpi else "",
|
||||
"kpi_name": kpi.kpi_name if kpi else "",
|
||||
"dimension": kpi.dimension if kpi else "",
|
||||
@@ -88,12 +93,14 @@ def create_budget_plan(
|
||||
|
||||
year, month = period.split("-")
|
||||
version = data.get("version", "v1.0")
|
||||
map_id = data.get("map_id") # 预算归属地图(2026-08-27: 按地图隔离)
|
||||
|
||||
# 检查是否已有记录(去重)
|
||||
# 检查是否已有记录(去重, 含map_id)
|
||||
existing = db.query(BudgetPlan).filter(
|
||||
BudgetPlan.kpi_id == kpi_id,
|
||||
BudgetPlan.period == period,
|
||||
BudgetPlan.version == version,
|
||||
BudgetPlan.map_id == map_id,
|
||||
BudgetPlan.status == "active",
|
||||
).first()
|
||||
|
||||
@@ -106,6 +113,7 @@ def create_budget_plan(
|
||||
else:
|
||||
plan = BudgetPlan(
|
||||
kpi_id=kpi_id,
|
||||
map_id=map_id,
|
||||
period=period,
|
||||
budget_value=budget_value,
|
||||
budget_year=int(year),
|
||||
|
||||
Reference in New Issue
Block a user