v0.2.0: CRM/ERP 系统升级 - 清理 .gitignore 并移除误提交的 venv/env/db 文件
- 更新 .gitignore:全面覆盖环境变量、数据库、日志、缓存、上传文件 - 移除误跟踪的 server/venv/、crm_data.db、.env 文件 - 新增 server/.env.example 模板 - 新增合同管理、利润核算、AI教练等功能模块 - 新增 Playwright e2e 测试套件 - 前后端多项功能升级和 bug 修复
This commit is contained in:
@@ -3,11 +3,13 @@
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import uuid
|
||||
import asyncio
|
||||
from fastapi import APIRouter, Depends, Body
|
||||
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
|
||||
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
|
||||
@@ -26,6 +28,7 @@ async def list_logs(
|
||||
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,
|
||||
@@ -34,18 +37,56 @@ async def list_logs(
|
||||
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
|
||||
|
||||
@@ -53,17 +94,20 @@ async def create_log(
|
||||
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:
|
||||
import uuid
|
||||
asyncio.create_task(
|
||||
sales_log_service.trigger_persona_workflow(
|
||||
log_id=uuid.UUID(result["id"]),
|
||||
@@ -75,3 +119,35 @@ async def create_log(
|
||||
)
|
||||
|
||||
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="日志已删除")
|
||||
|
||||
Reference in New Issue
Block a user