本体三支柱: 科目↔KPI↔OKR三层互联 + 追溯链API + OKR详情页签
- 新表 kpi_subject_map(89映射/24KPI) / objective_kpi(3O×5KPI) / krs(3O×3KR) - GET /api/cma/ontology/trace?objective_id=N O→KPI→科目逐层追溯 - GET /api/cma/ontology/objectives 三层链路概览 - OkrDetail.vue 新增本体追溯链页签(KR目标/当前值 + KPI→科目标签流) - 含并发已上线未提交的KPI多粒度列(target_monthly/quarterly/yearly) - 回归: pytest 409 passed
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
"""管理会计OS 数据模型"""
|
||||
from sqlalchemy import Column, Integer, String, Text, Float, DateTime, ForeignKey, Boolean, JSON, func, UniqueConstraint
|
||||
from sqlalchemy import Column, Integer, String, Text, Float, DateTime, ForeignKey, Boolean, JSON, func, UniqueConstraint, Numeric, Date
|
||||
from app.database import Base
|
||||
|
||||
from app.models.budget_plan import BudgetPlan
|
||||
@@ -75,7 +75,10 @@ class KPIDefinition(Base):
|
||||
data_owner = Column(String(100), default="待指定", comment="数据责任人")
|
||||
frequency = Column(String(20), default="monthly", comment="daily/weekly/monthly/quarterly/yearly")
|
||||
unit = Column(String(50), default="%", comment="单位")
|
||||
target_value = Column(Float, nullable=True, comment="目标值")
|
||||
target_value = Column(Float, nullable=True, comment="目标值(兼容旧字段)")
|
||||
target_monthly = Column(Float, nullable=True, comment="月度目标值")
|
||||
target_quarterly = Column(Float, nullable=True, comment="季度目标值")
|
||||
target_yearly = Column(Float, nullable=True, comment="年度目标值")
|
||||
threshold_green = Column(String(100), nullable=True, comment="绿灯阈值")
|
||||
threshold_yellow = Column(String(100), nullable=True, comment="黄灯阈值")
|
||||
threshold_red = Column(String(100), nullable=True, comment="红灯阈值")
|
||||
@@ -675,3 +678,45 @@ class SocialSecurity(Base):
|
||||
remark = Column(String(500), nullable=True, comment="备注")
|
||||
created_at = Column(DateTime, server_default=func.now())
|
||||
updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now())
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 本体三支柱: 科目↔KPI↔OKR 三层互联 (2026-08-19)
|
||||
# 追溯链: 目标(O) → 指标(KPI) → 科目(数据)
|
||||
# ============================================================
|
||||
|
||||
class KPISubjectMap(Base):
|
||||
"""科目↔KPI映射 — 指标计算依赖的底层会计科目"""
|
||||
__tablename__ = "kpi_subject_map"
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
kpi_id = Column(Integer, ForeignKey("kpi_definitions.id"), nullable=False, comment="KPI ID")
|
||||
subject_code = Column(String(20), nullable=False, comment="科目编码")
|
||||
calc_type = Column(String(20), default="sum", comment="sum/avg/ratio/other")
|
||||
weight = Column(Numeric(5, 2), default=1.00, comment="权重(负=扣减项)")
|
||||
remark = Column(String(200), nullable=True, comment="备注")
|
||||
__table_args__ = (UniqueConstraint("kpi_id", "subject_code", name="uk_kpi_subject"),)
|
||||
|
||||
|
||||
class ObjectiveKPI(Base):
|
||||
"""KPI↔O支撑 — 目标由哪些KPI度量"""
|
||||
__tablename__ = "objective_kpi"
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
objective_id = Column(Integer, ForeignKey("objectives.id"), nullable=False, comment="OKR目标ID")
|
||||
kpi_id = Column(Integer, ForeignKey("kpi_definitions.id"), nullable=False, comment="KPI ID")
|
||||
weight = Column(Numeric(5, 2), default=1.00, comment="支撑权重")
|
||||
__table_args__ = (UniqueConstraint("objective_id", "kpi_id", name="uk_obj_kpi"),)
|
||||
|
||||
|
||||
class KR(Base):
|
||||
"""关键结果KR — OKR完整化 (O→KR→KPI)"""
|
||||
__tablename__ = "krs"
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
objective_id = Column(Integer, ForeignKey("objectives.id"), nullable=False, comment="OKR目标ID")
|
||||
title = Column(String(200), nullable=False, comment="KR标题")
|
||||
metric_kpi_id = Column(Integer, ForeignKey("kpi_definitions.id"), nullable=True, comment="度量KPI ID")
|
||||
target_value = Column(Numeric(15, 2), nullable=True, comment="目标值")
|
||||
current_value = Column(Numeric(15, 2), nullable=True, comment="当前值")
|
||||
progress = Column(Integer, default=0, comment="完成进度 0-100")
|
||||
status = Column(String(20), default="pending", comment="pending/in_progress/completed/cancelled")
|
||||
due_date = Column(Date, nullable=True, comment="截止日期")
|
||||
created_at = Column(DateTime, server_default=func.now())
|
||||
|
||||
Reference in New Issue
Block a user