"""CRM 数据权限辅助(负责人 owner_user_id + 标准 create_by/create_dept_id)。""" from __future__ import annotations from typing import Any, Dict, Optional from sqlalchemy.orm import Session from app.core.data_scope import apply_data_scope, row_in_data_scope CRM_OWNER_FIELD = "owner_user_id" def crm_user_info(user: Optional[dict]) -> Optional[Dict[str, Any]]: if not user: return None uid = (user.get("user_id") or user.get("id") or "").strip() return { "user_id": uid or None, "role": user.get("role"), "dept_id": user.get("dept_id") or user.get("region_id"), "region_id": user.get("region_id") or user.get("dept_id"), } def apply_crm_owner_scope(query, model, user_info, db: Session, tenant_no: str): if not user_info: return query return apply_data_scope( query, model, user_info, db, tenant_no, owner_field=CRM_OWNER_FIELD ) def apply_crm_create_by_scope(query, model, user_info, db: Session, tenant_no: str): if not user_info: return query return apply_data_scope(query, model, user_info, db, tenant_no) def ensure_crm_owner_row_in_scope( db: Session, row, user_info, tenant_no: str, *, message: str = "无权访问该数据" ) -> None: if not user_info or row is None: return if not row_in_data_scope(db, row, user_info, tenant_no, owner_field=CRM_OWNER_FIELD): raise ValueError(message) def ensure_crm_create_by_row_in_scope( db: Session, row, user_info, tenant_no: str, *, message: str = "无权访问该数据" ) -> None: if not user_info or row is None: return if not row_in_data_scope(db, row, user_info, tenant_no): raise ValueError(message) def ensure_crm_contact_row_in_scope( db: Session, row, user_info, tenant_no: str, *, message: str = "无权访问该联系人" ) -> None: """联系人:create_by 在范围内,或关联客户在 owner 范围内。""" if not user_info or row is None: return if row_in_data_scope(db, row, user_info, tenant_no): return customer_id = getattr(row, "customer_id", None) or "" if customer_id: from app.crud.crm.customer import get_customer customer = get_customer(db, customer_id) if customer and customer.tenant_no == tenant_no: if row_in_data_scope( db, customer, user_info, tenant_no, owner_field=CRM_OWNER_FIELD ): return raise ValueError(message) def ensure_crm_customer_linked_row_in_scope( db: Session, row, user_info, tenant_no: str, *, customer_id: str = None, message: str = "无权访问该数据", ) -> None: """客户子表(开票信息等):先校验关联客户 owner scope,否则校验 create_by。""" if not user_info or row is None: return cid = customer_id or getattr(row, "customer_id", None) or "" if cid: from app.crud.crm.customer import get_customer customer = get_customer(db, cid) if customer and customer.tenant_no == tenant_no: if row_in_data_scope( db, customer, user_info, tenant_no, owner_field=CRM_OWNER_FIELD ): return if row_in_data_scope(db, row, user_info, tenant_no): return raise ValueError(message)