815cbf9d8c
- 更新 .gitignore:全面覆盖环境变量、数据库、日志、缓存、上传文件 - 移除误跟踪的 server/venv/、crm_data.db、.env 文件 - 新增 server/.env.example 模板 - 新增合同管理、利润核算、AI教练等功能模块 - 新增 Playwright e2e 测试套件 - 前后端多项功能升级和 bug 修复
154 lines
4.9 KiB
Python
154 lines
4.9 KiB
Python
"""
|
||
销售日志 API 路由 — /api/sales-logs
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
import uuid
|
||
import asyncio
|
||
from fastapi import APIRouter, Depends, Body, HTTPException
|
||
from sqlalchemy import select
|
||
from sqlalchemy.ext.asyncio import AsyncSession
|
||
|
||
from app.api.deps import get_current_user, get_current_company_id
|
||
from app.db.database import get_db
|
||
from app.schemas.auth import CurrentUserPayload
|
||
from app.schemas.response import ok
|
||
from app.services import sales_log_service
|
||
|
||
router = APIRouter(prefix="/sales-logs", tags=["销售日志"])
|
||
|
||
|
||
@router.get("", summary="查询销售日志列表")
|
||
async def list_logs(
|
||
page: int = 1,
|
||
size: int = 20,
|
||
customer_id: str | None = None,
|
||
user_id: str | None = None,
|
||
start_date: str | None = None,
|
||
end_date: str | None = None,
|
||
db: AsyncSession = Depends(get_db),
|
||
current_user: CurrentUserPayload = Depends(get_current_user),
|
||
company_id: uuid.UUID = Depends(get_current_company_id),
|
||
):
|
||
result = await sales_log_service.list_logs(
|
||
db, current_user,
|
||
page=page, size=size,
|
||
customer_id=customer_id,
|
||
user_id=user_id,
|
||
start_date=start_date,
|
||
end_date=end_date,
|
||
company_id=company_id,
|
||
)
|
||
return ok(data=result)
|
||
|
||
|
||
async def _resolve_company_ids(
|
||
db: AsyncSession,
|
||
company_id: uuid.UUID,
|
||
customer_id: str | None,
|
||
company_ids: list[str] | None,
|
||
) -> list[uuid.UUID]:
|
||
"""
|
||
智能解析 involved_company_ids:
|
||
1. 如果前端显式传了 company_ids,使用它
|
||
2. 否则以当前视角公司为基础
|
||
3. 如果选了客户,自动查客户 owner 所属的公司,合并进来
|
||
"""
|
||
if company_ids:
|
||
resolved = set(uuid.UUID(cid) for cid in company_ids)
|
||
else:
|
||
resolved = {company_id}
|
||
|
||
# 自动关联客户 owner 所在公司
|
||
if customer_id:
|
||
from app.models.crm import CrmCustomer
|
||
from app.models.sys import SysUserCompany
|
||
cust = await db.get(CrmCustomer, uuid.UUID(customer_id))
|
||
if cust and cust.owner_id:
|
||
stmt = select(SysUserCompany.company_id).where(
|
||
SysUserCompany.user_id == cust.owner_id
|
||
)
|
||
rows = (await db.execute(stmt)).scalars().all()
|
||
for cid in rows:
|
||
resolved.add(cid)
|
||
|
||
# 确保当前公司始终在内
|
||
resolved.add(company_id)
|
||
return list(resolved)
|
||
|
||
|
||
@router.post("", summary="创建销售日志")
|
||
async def create_log(
|
||
content: str = Body(..., embed=True),
|
||
customer_id: str | None = Body(None, embed=True),
|
||
contact_ids: list[str] | None = Body(None, embed=True),
|
||
log_date: str | None = Body(None, embed=True),
|
||
company_ids: list[str] | None = Body(None, embed=True),
|
||
db: AsyncSession = Depends(get_db),
|
||
current_user: CurrentUserPayload = Depends(get_current_user),
|
||
company_id: uuid.UUID = Depends(get_current_company_id),
|
||
):
|
||
from datetime import date as date_type
|
||
|
||
parsed_date = None
|
||
if log_date:
|
||
parsed_date = date_type.fromisoformat(log_date)
|
||
|
||
# 智能解析公司关联
|
||
resolved_company_ids = await _resolve_company_ids(db, company_id, customer_id, company_ids)
|
||
|
||
result = await sales_log_service.create_log(
|
||
db, current_user,
|
||
content=content,
|
||
customer_id=customer_id,
|
||
contact_ids=contact_ids,
|
||
log_date=parsed_date,
|
||
company_ids=resolved_company_ids,
|
||
)
|
||
|
||
# 异步触发 Dify 画像提取工作流(仅当关联了客户时)
|
||
if customer_id:
|
||
asyncio.create_task(
|
||
sales_log_service.trigger_persona_workflow(
|
||
log_id=uuid.UUID(result["id"]),
|
||
customer_id=uuid.UUID(customer_id),
|
||
content=content,
|
||
salesperson_name=getattr(current_user, "real_name", ""),
|
||
contact_ids=contact_ids,
|
||
)
|
||
)
|
||
|
||
return ok(data=result, message="日志创建成功")
|
||
|
||
|
||
@router.put("/{log_id}", summary="编辑销售日志")
|
||
async def update_log(
|
||
log_id: uuid.UUID,
|
||
content: str | None = Body(None, embed=True),
|
||
customer_id: str | None = Body(None, embed=True),
|
||
contact_ids: list[str] | None = Body(None, embed=True),
|
||
log_date: str | None = Body(None, embed=True),
|
||
db: AsyncSession = Depends(get_db),
|
||
current_user: CurrentUserPayload = Depends(get_current_user),
|
||
company_id: uuid.UUID = Depends(get_current_company_id),
|
||
):
|
||
result = await sales_log_service.update_log(
|
||
db, current_user, log_id,
|
||
content=content,
|
||
customer_id=customer_id,
|
||
contact_ids=contact_ids,
|
||
log_date=log_date,
|
||
company_id=company_id,
|
||
)
|
||
return ok(data=result, message="日志更新成功")
|
||
|
||
|
||
@router.delete("/{log_id}", summary="删除销售日志(软删除)")
|
||
async def delete_log(
|
||
log_id: uuid.UUID,
|
||
db: AsyncSession = Depends(get_db),
|
||
current_user: CurrentUserPayload = Depends(get_current_user),
|
||
):
|
||
await sales_log_service.delete_log(db, current_user, log_id)
|
||
return ok(message="日志已删除")
|