2026-05-30 07:23:33 +08:00
|
|
|
|
"""
|
|
|
|
|
|
客户数据访问层。
|
|
|
|
|
|
|
|
|
|
|
|
负责封装客户(Customer)模型的所有数据库查询操作,
|
|
|
|
|
|
提供按条件筛选、创建、更新等基础 CRUD 方法。
|
|
|
|
|
|
被 CustomerService、OrderService、AIService 调用。
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
2026-05-14 13:51:06 +08:00
|
|
|
|
from sqlalchemy import select
|
|
|
|
|
|
from sqlalchemy.orm import Session
|
|
|
|
|
|
|
|
|
|
|
|
from backend.app.models.business import Customer
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CustomerRepository:
|
2026-05-30 07:23:33 +08:00
|
|
|
|
"""客户数据访问层,封装客户表的数据库操作。
|
|
|
|
|
|
|
|
|
|
|
|
被 CustomerService、OrderService、AIService 调用。
|
|
|
|
|
|
"""
|
2026-05-14 13:51:06 +08:00
|
|
|
|
|
|
|
|
|
|
def find_by_name_and_mobile(self, session: Session, customer_name: str, mobile: str) -> Customer | None:
|
2026-05-30 07:23:33 +08:00
|
|
|
|
"""根据客户姓名和手机号精确查找客户(用于去重校验)。
|
|
|
|
|
|
|
|
|
|
|
|
:param session: 数据库会话
|
|
|
|
|
|
:param customer_name: 客户姓名
|
|
|
|
|
|
:param mobile: 手机号
|
|
|
|
|
|
:return: 匹配的客户对象,不存在则返回 None
|
|
|
|
|
|
被 CustomerService.create_customer 调用,用于创建前校验是否已存在同名同号客户。
|
|
|
|
|
|
"""
|
2026-05-14 13:51:06 +08:00
|
|
|
|
stmt = select(Customer).where(
|
|
|
|
|
|
Customer.customer_name == customer_name,
|
|
|
|
|
|
Customer.mobile == mobile,
|
|
|
|
|
|
Customer.deleted == 0,
|
|
|
|
|
|
)
|
|
|
|
|
|
return session.execute(stmt).scalar_one_or_none()
|
|
|
|
|
|
|
|
|
|
|
|
def list_customers_by_filters(self, session: Session, filters: dict) -> list[Customer]:
|
2026-05-30 07:23:33 +08:00
|
|
|
|
"""根据筛选条件查询客户列表,支持模糊匹配姓名/手机号、精确匹配类型/结算方式/业务员。
|
|
|
|
|
|
|
|
|
|
|
|
:param session: 数据库会话
|
|
|
|
|
|
:param filters: 筛选条件字典,可包含 customer_name、mobile、customer_type、
|
|
|
|
|
|
settlement_type、salesman_id 等键
|
|
|
|
|
|
:return: 符合条件的客户列表,按 id 降序排列
|
|
|
|
|
|
被 CustomerService.list_customers 调用。
|
|
|
|
|
|
"""
|
2026-05-14 13:51:06 +08:00
|
|
|
|
stmt = select(Customer).where(Customer.deleted == 0)
|
|
|
|
|
|
|
|
|
|
|
|
if filters.get("customer_name"):
|
|
|
|
|
|
stmt = stmt.where(Customer.customer_name.contains(filters["customer_name"]))
|
|
|
|
|
|
if filters.get("mobile"):
|
|
|
|
|
|
stmt = stmt.where(Customer.mobile.contains(filters["mobile"]))
|
|
|
|
|
|
if filters.get("customer_type"):
|
|
|
|
|
|
stmt = stmt.where(Customer.customer_type == filters["customer_type"])
|
|
|
|
|
|
if filters.get("settlement_type"):
|
|
|
|
|
|
stmt = stmt.where(Customer.settlement_type == filters["settlement_type"])
|
|
|
|
|
|
if filters.get("salesman_id") is not None:
|
|
|
|
|
|
stmt = stmt.where(Customer.salesman_id == filters["salesman_id"])
|
|
|
|
|
|
|
|
|
|
|
|
stmt = stmt.order_by(Customer.id.desc())
|
|
|
|
|
|
return list(session.execute(stmt).scalars())
|
|
|
|
|
|
|
|
|
|
|
|
def get_customer(self, session: Session, customer_id: int) -> Customer | None:
|
2026-05-30 07:23:33 +08:00
|
|
|
|
"""根据 ID 获取单个客户详情。
|
|
|
|
|
|
|
|
|
|
|
|
:param session: 数据库会话
|
|
|
|
|
|
:param customer_id: 客户主键 ID
|
|
|
|
|
|
:return: 客户对象,不存在则返回 None
|
|
|
|
|
|
被 CustomerService.get_customer 调用。
|
|
|
|
|
|
"""
|
2026-05-14 13:51:06 +08:00
|
|
|
|
stmt = select(Customer).where(Customer.id == customer_id, Customer.deleted == 0)
|
|
|
|
|
|
return session.execute(stmt).scalar_one_or_none()
|
|
|
|
|
|
|
|
|
|
|
|
def create_customer(self, session: Session, payload: dict) -> Customer:
|
2026-05-30 07:23:33 +08:00
|
|
|
|
"""创建新客户记录。
|
|
|
|
|
|
|
|
|
|
|
|
:param session: 数据库会话
|
|
|
|
|
|
:param payload: 客户字段字典,键名与 Customer 模型字段对应
|
|
|
|
|
|
:return: 新创建的客户对象(含自增 ID)
|
|
|
|
|
|
被 CustomerService.create_customer 调用。
|
|
|
|
|
|
"""
|
2026-05-14 13:51:06 +08:00
|
|
|
|
customer = Customer(**payload)
|
|
|
|
|
|
session.add(customer)
|
|
|
|
|
|
session.flush()
|
|
|
|
|
|
return customer
|
2026-05-15 10:47:04 +08:00
|
|
|
|
|
2026-05-15 12:18:50 +08:00
|
|
|
|
def update_customer(self, session: Session, customer: Customer, payload: dict) -> Customer:
|
2026-05-30 07:23:33 +08:00
|
|
|
|
"""更新已有客户的各字段信息。
|
|
|
|
|
|
|
|
|
|
|
|
:param session: 数据库会话
|
|
|
|
|
|
:param customer: 待更新的客户对象(已从数据库查出)
|
|
|
|
|
|
:param payload: 更新字段字典
|
|
|
|
|
|
:return: 更新后的客户对象
|
|
|
|
|
|
被 CustomerService.update_customer 调用。
|
|
|
|
|
|
"""
|
2026-05-15 12:18:50 +08:00
|
|
|
|
customer.customer_name = payload["customer_name"]
|
|
|
|
|
|
customer.mobile = payload["mobile"]
|
|
|
|
|
|
customer.address = payload.get("address")
|
|
|
|
|
|
customer.settlement_type = payload.get("settlement_type")
|
|
|
|
|
|
customer.settlement_days = payload.get("settlement_days", 0)
|
|
|
|
|
|
customer.customer_type = payload.get("customer_type")
|
|
|
|
|
|
customer.salesman_id = payload.get("salesman_id")
|
|
|
|
|
|
customer.credit_limit = payload.get("credit_limit", 0)
|
|
|
|
|
|
customer.remark = payload.get("remark")
|
|
|
|
|
|
session.add(customer)
|
|
|
|
|
|
session.flush()
|
|
|
|
|
|
return customer
|
|
|
|
|
|
|
2026-05-15 10:47:04 +08:00
|
|
|
|
def find_by_mobile(self, session: Session, mobile: str) -> Customer | None:
|
2026-05-30 07:23:33 +08:00
|
|
|
|
"""根据手机号精确查找客户(用于创建/编辑时的唯一性校验)。
|
|
|
|
|
|
|
|
|
|
|
|
:param session: 数据库会话
|
|
|
|
|
|
:param mobile: 手机号
|
|
|
|
|
|
:return: 匹配的客户对象,不存在则返回 None
|
|
|
|
|
|
被 CustomerService.create_customer、OrderService 创建订单时调用。
|
|
|
|
|
|
"""
|
2026-05-15 10:47:04 +08:00
|
|
|
|
stmt = select(Customer).where(
|
|
|
|
|
|
Customer.mobile == mobile,
|
|
|
|
|
|
Customer.deleted == 0,
|
|
|
|
|
|
)
|
|
|
|
|
|
return session.execute(stmt).scalar_one_or_none()
|