feat: 多租户联动 — CMA切换企业注入tenant_id + a2a_dispatch分发
This commit is contained in:
@@ -216,7 +216,7 @@ def plan_stats(db: Session = Depends(get_db), current_user: User = Depends(requi
|
||||
in_progress = query.filter(ActionPlan.status == "in_progress").count()
|
||||
completed = query.filter(ActionPlan.status == "completed").count()
|
||||
from datetime import datetime
|
||||
overdue = query.filter(ActionPlan.status.in_(["pending", "in_progress"]), ActionPlan.deadline < datetime.now()).count()
|
||||
overdue = query.filter(ActionPlan.status.in_(["pending", "in_progress"]), ActionPlan.due_date < datetime.now()).count()
|
||||
return {
|
||||
"total": total,
|
||||
"pending": pending,
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
"""租户状态API — CMA系统切换公司时记录当前tenant,供项目Bot分发A2A任务"""
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy.orm import Session
|
||||
from app.database import get_db
|
||||
from app.models import SystemConfig, Entity
|
||||
|
||||
router = APIRouter(prefix="/api/cma/tenant", tags=["多租户"])
|
||||
|
||||
TENANT_KEY = "current_tenant"
|
||||
|
||||
class TenantSwitchRequest(BaseModel):
|
||||
entity_id: int
|
||||
source: str = "cma-system"
|
||||
|
||||
|
||||
def _tenant_name(entity_id: int) -> str:
|
||||
"""entity_id → tenant_id"""
|
||||
return "company_b" if entity_id == 2 else "company_a"
|
||||
|
||||
|
||||
@router.get("/current")
|
||||
def get_current_tenant(db: Session = Depends(get_db)):
|
||||
"""查询当前租户"""
|
||||
cfg = db.query(SystemConfig).filter(SystemConfig.config_key == TENANT_KEY).first()
|
||||
if cfg and cfg.config_value:
|
||||
import json
|
||||
try:
|
||||
return json.loads(cfg.config_value)
|
||||
except:
|
||||
pass
|
||||
return {"tenant_id": "company_a", "entity_id": 1, "name": "陕西酣客文化传媒"}
|
||||
|
||||
|
||||
@router.post("/switch")
|
||||
def switch_tenant(data: TenantSwitchRequest, db: Session = Depends(get_db)):
|
||||
"""切换当前租户(CMA前端企业切换器调用)"""
|
||||
ent = db.query(Entity).filter(Entity.id == data.entity_id).first()
|
||||
if not ent:
|
||||
raise HTTPException(404, "企业不存在")
|
||||
|
||||
import json
|
||||
state = {
|
||||
"tenant_id": _tenant_name(data.entity_id),
|
||||
"entity_id": data.entity_id,
|
||||
"name": ent.name,
|
||||
"short_name": ent.short_name,
|
||||
"source": data.source,
|
||||
"switched_at": __import__("datetime").datetime.now().isoformat(),
|
||||
}
|
||||
|
||||
cfg = db.query(SystemConfig).filter(SystemConfig.config_key == TENANT_KEY).first()
|
||||
if cfg:
|
||||
cfg.config_value = json.dumps(state, ensure_ascii=False)
|
||||
else:
|
||||
db.add(SystemConfig(
|
||||
config_key=TENANT_KEY,
|
||||
config_value=json.dumps(state, ensure_ascii=False),
|
||||
description="当前租户状态(CMA企业切换联动)",
|
||||
))
|
||||
db.commit()
|
||||
|
||||
return {"success": True, "current": state}
|
||||
+2
-1
@@ -5,7 +5,7 @@ from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.responses import JSONResponse
|
||||
from dotenv import load_dotenv
|
||||
from app.database import init_db
|
||||
from app.api import auth, kpis, templates, maps, dashboard, data, alerts, ai_analysis, alert_rules, users, thresholds, notifications, permissions, action_plans, alignment, org, objectives, versions, budget, cost, predict, reports, security, knowledge, bot_bridge, bot_bridge_v2, lead, customer_dashboard, deviation_push, budget_generate, knowledge_articles, kpi_causality, data_quality, bi_reports, entities, bsc_layers, okr, okr_templates, subjects, driver_budget, bot_kpis, bot_iron_law, analysis_results, expenses, cash, tax_compliance
|
||||
from app.api import auth, kpis, templates, maps, dashboard, data, alerts, ai_analysis, alert_rules, users, thresholds, notifications, permissions, action_plans, alignment, org, objectives, versions, budget, cost, predict, reports, security, knowledge, bot_bridge, bot_bridge_v2, lead, tenant, customer_dashboard, deviation_push, budget_generate, knowledge_articles, kpi_causality, data_quality, bi_reports, entities, bsc_layers, okr, okr_templates, subjects, driver_budget, bot_kpis, bot_iron_law, analysis_results, expenses, cash, tax_compliance
|
||||
from app.utils.cache import clear_all as clear_cache, delete as delete_cache
|
||||
from scripts.erp_sync import run_sync as run_erp_sync
|
||||
from app.auth_middleware import require_auth
|
||||
@@ -57,6 +57,7 @@ app.include_router(knowledge.router)
|
||||
app.include_router(bot_bridge.router)
|
||||
app.include_router(bot_bridge_v2.router)
|
||||
app.include_router(lead.router)
|
||||
app.include_router(tenant.router)
|
||||
app.include_router(customer_dashboard.router)
|
||||
app.include_router(deviation_push.router)
|
||||
app.include_router(budget_generate.router)
|
||||
|
||||
Reference in New Issue
Block a user