Files
shanxia2.0/backend/app/crud/crm/data_scope_helpers.py
T
zlwuandCursor bf73b6b2d8 feat(crm): 联系人、产品、报价与合同域接入数据权限过滤
补全 PR3 Phase 2.4–2.7,列表 apply_data_scope、详情/CUD assert_row_in_data_scope,合同/报价主表支持 owner_user_id。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-28 21:00:12 +08:00

103 lines
3.3 KiB
Python

"""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)