From cdbe59e97fcec6c43b5b203791d4283f7c4f32b4 Mon Sep 17 00:00:00 2001 From: v6ole Date: Mon, 13 Jul 2026 00:55:43 +0800 Subject: [PATCH] =?UTF-8?q?feat:=205=E4=B8=AA=E5=88=97=E8=A1=A8API?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=90=9C=E7=B4=A2=E5=8F=82=E6=95=B0=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - visits: search沟通内容/客户需求/拜访人/客户名 - daily_notes: search内容 - work_plans: search计划内容/客户名 - mini_business: search产品/跟进/客户名 - key_visits: search描述/拜访人/客户名 Co-Authored-By: Claude --- backend/app/api/daily_notes.py | 3 +++ backend/app/api/key_visits.py | 7 ++++++- backend/app/api/mini_business.py | 7 ++++++- backend/app/api/visits.py | 7 ++++++- backend/app/api/work_plans.py | 7 ++++++- 5 files changed, 27 insertions(+), 4 deletions(-) diff --git a/backend/app/api/daily_notes.py b/backend/app/api/daily_notes.py index 4f836d1..dcbcd37 100644 --- a/backend/app/api/daily_notes.py +++ b/backend/app/api/daily_notes.py @@ -30,6 +30,7 @@ async def _enrich(note: DailyNote, db: AsyncSession) -> dict: async def list_notes( date_from: Optional[str] = Query(None), date_to: Optional[str] = Query(None), + search: Optional[str] = Query(None), current_user: dict = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): @@ -40,6 +41,8 @@ async def list_notes( query = query.where(DailyNote.note_date >= parse_date(date_from)) if date_to: query = query.where(DailyNote.note_date <= parse_date(date_to)) + if search: + query = query.where(DailyNote.content.ilike(f"%{search}%")) query = query.order_by(DailyNote.note_date.desc(), DailyNote.created_at.desc()).limit(100) result = await db.execute(query) return [await _enrich(n, db) for n in result.scalars().all()] diff --git a/backend/app/api/key_visits.py b/backend/app/api/key_visits.py index 388ebf0..228eb84 100644 --- a/backend/app/api/key_visits.py +++ b/backend/app/api/key_visits.py @@ -2,7 +2,7 @@ import uuid from typing import Optional from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.ext.asyncio import AsyncSession -from sqlalchemy import select +from sqlalchemy import select, or_ from app.database import get_db from app.middleware.auth import get_current_user, require_any_role from app.models.key_visit import KeyVisit @@ -37,6 +37,7 @@ async def _enrich(k: KeyVisit, db: AsyncSession) -> dict: async def list_key_visits( customer_id: Optional[str] = Query(None), customer_type: Optional[str] = Query(None), + search: Optional[str] = Query(None), current_user: dict = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): @@ -47,6 +48,10 @@ async def list_key_visits( query = query.where(KeyVisit.customer_id == uuid.UUID(customer_id)) if customer_type: query = query.join(Customer, KeyVisit.customer_id == Customer.id).where(Customer.customer_type == customer_type) + if search: + query = query.outerjoin(Customer, KeyVisit.customer_id == Customer.id).where( + or_(KeyVisit.description.ilike(f"%{search}%"), KeyVisit.planned_visitor.ilike(f"%{search}%"), Customer.name.ilike(f"%{search}%")) + ) query = query.order_by(KeyVisit.planned_date.desc()).limit(200) result = await db.execute(query) return [await _enrich(k, db) for k in result.scalars().all()] diff --git a/backend/app/api/mini_business.py b/backend/app/api/mini_business.py index aec4a49..58011d0 100644 --- a/backend/app/api/mini_business.py +++ b/backend/app/api/mini_business.py @@ -2,7 +2,7 @@ import uuid from typing import Optional from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.ext.asyncio import AsyncSession -from sqlalchemy import select +from sqlalchemy import select, or_ from app.database import get_db from app.middleware.auth import get_current_user, require_any_role from app.models.mini_business import MiniBusiness @@ -36,6 +36,7 @@ async def _enrich(m: MiniBusiness, db: AsyncSession) -> dict: async def list_mini_business( customer_id: Optional[str] = Query(None), customer_type: Optional[str] = Query(None), + search: Optional[str] = Query(None), current_user: dict = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): @@ -46,6 +47,10 @@ async def list_mini_business( query = query.where(MiniBusiness.customer_id == uuid.UUID(customer_id)) if customer_type: query = query.join(Customer, MiniBusiness.customer_id == Customer.id).where(Customer.customer_type == customer_type) + if search: + query = query.outerjoin(Customer, MiniBusiness.customer_id == Customer.id).where( + or_(MiniBusiness.product_type.ilike(f"%{search}%"), MiniBusiness.follow_up_detail.ilike(f"%{search}%"), Customer.name.ilike(f"%{search}%")) + ) query = query.order_by(MiniBusiness.expected_revenue_date.desc()).limit(200) result = await db.execute(query) return [await _enrich(m, db) for m in result.scalars().all()] diff --git a/backend/app/api/visits.py b/backend/app/api/visits.py index 48f89a1..112b7db 100644 --- a/backend/app/api/visits.py +++ b/backend/app/api/visits.py @@ -3,7 +3,7 @@ from datetime import date, datetime from typing import Optional from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.ext.asyncio import AsyncSession -from sqlalchemy import select, func +from sqlalchemy import select, func, or_ from app.database import get_db from app.middleware.auth import get_current_user, require_any_role from app.models.visit import Visit @@ -63,6 +63,7 @@ async def list_visits( date_to: Optional[str] = Query(None), customer_id: Optional[str] = Query(None), customer_type: Optional[str] = Query(None), + search: Optional[str] = Query(None), current_user: dict = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): @@ -80,6 +81,10 @@ async def list_visits( query = query.where(Visit.customer_id == uuid.UUID(customer_id)) if customer_type: query = query.join(Customer, Visit.customer_id == Customer.id).where(Customer.customer_type == customer_type) + if search: + query = query.outerjoin(Customer, Visit.customer_id == Customer.id).where( + or_(Visit.communication_content.ilike(f"%{search}%"), Visit.customer_demand.ilike(f"%{search}%"), Visit.visitor_name.ilike(f"%{search}%"), Customer.name.ilike(f"%{search}%")) + ) query = query.order_by(Visit.visit_date.desc(), Visit.created_at.desc()).limit(200) result = await db.execute(query) diff --git a/backend/app/api/work_plans.py b/backend/app/api/work_plans.py index c7bcd65..4fc614a 100644 --- a/backend/app/api/work_plans.py +++ b/backend/app/api/work_plans.py @@ -3,7 +3,7 @@ from datetime import date from typing import Optional from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.ext.asyncio import AsyncSession -from sqlalchemy import select +from sqlalchemy import select, or_ from app.database import get_db from app.middleware.auth import get_current_user, require_any_role from app.utils.timezone import parse_date @@ -36,6 +36,7 @@ async def _enrich(wp: WorkPlan, db: AsyncSession) -> dict: async def list_work_plans( customer_id: Optional[str] = Query(None), customer_type: Optional[str] = Query(None), + search: Optional[str] = Query(None), current_user: dict = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): @@ -46,6 +47,10 @@ async def list_work_plans( query = query.where(WorkPlan.customer_id == uuid.UUID(customer_id)) if customer_type: query = query.join(Customer, WorkPlan.customer_id == Customer.id).where(Customer.customer_type == customer_type) + if search: + query = query.outerjoin(Customer, WorkPlan.customer_id == Customer.id).where( + or_(WorkPlan.plan_content.ilike(f"%{search}%"), Customer.name.ilike(f"%{search}%")) + ) query = query.order_by(WorkPlan.plan_date.desc()).limit(200) result = await db.execute(query) return [await _enrich(w, db) for w in result.scalars().all()]