fix: 亮灯表权限控制 — 客户经理只看自己

get_light_board 新增 user_id/role 参数:
- director/leader: 看全部经理 + 未分配客户
- manager: 只看自己, 不显示未分配客户
- API 层从 current_user 提取身份信息透传
This commit is contained in:
2026-06-24 17:22:05 +08:00
parent a8ed71fbff
commit 1d0f412e4a
2 changed files with 43 additions and 28 deletions
+2 -2
View File
@@ -60,6 +60,6 @@ async def light_board(
current_user: dict = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
):
"""Get customer visit coverage matrix (light board). Director/leader only."""
"""Get customer visit coverage matrix. Managers see only themselves."""
ref = date.fromisoformat(reference_date) if reference_date else None
return await get_light_board(db, ref)
return await get_light_board(db, ref, uuid.UUID(current_user["user_id"]), current_user["role"])
+21 -6
View File
@@ -53,13 +53,26 @@ def classify(last_visit_date: date | None, ref: date) -> tuple[str, int]:
return ("red", missed)
async def get_light_board(db: AsyncSession, reference_date: date | None = None) -> dict:
"""Get per-manager customer visit coverage for the light board."""
async def get_light_board(
db: AsyncSession,
reference_date: date | None = None,
user_id: UUID | None = None,
role: str = "manager",
) -> dict:
"""Get per-manager customer visit coverage for the light board.
Directors/leaders see all managers; managers see only themselves.
"""
ref = reference_date or today_cst()
# ── All managers ──
# ── Managers (filtered by role) ──
managers_result = await db.execute(select(User).where(User.role == "manager"))
managers = managers_result.scalars().all()
all_managers = managers_result.scalars().all()
# Filter: managers only see themselves
visible_managers = all_managers if role in ("director", "leader") else [
m for m in all_managers if m.id == user_id
]
manager_map: dict[UUID, dict] = {
m.id: {
"manager_id": str(m.id),
@@ -71,7 +84,7 @@ async def get_light_board(db: AsyncSession, reference_date: date | None = None)
"coverage_rate": 0.0,
"customers": [],
}
for m in managers
for m in visible_managers
}
# ── All customers with their last visit per manager ──
@@ -153,6 +166,9 @@ async def get_light_board(db: AsyncSession, reference_date: date | None = None)
manager_list = sorted(manager_map.values(), key=lambda m: m["coverage_rate"])
# ── Unassigned customers (no primary manager) ──
# Only visible to directors/leaders — not actionable for individual managers
unassigned = []
if role in ("director", "leader"):
unassigned_rows = await db.execute(
select(Customer)
.outerjoin(CustomerAssignment, and_(
@@ -162,7 +178,6 @@ async def get_light_board(db: AsyncSession, reference_date: date | None = None)
.where(CustomerAssignment.id == None)
.order_by(Customer.name)
)
unassigned = []
for c in unassigned_rows.scalars():
unassigned.append({
"customer_id": str(c.id),