| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- from typing import Optional
- from fastapi import APIRouter, Depends, HTTPException, Query
- from sqlalchemy import text
- from sqlalchemy.ext.asyncio import AsyncSession
- from app.core.security import get_current_user
- from app.models.drug import get_db
- router = APIRouter(prefix="/drug", tags=["药品"])
- @router.get("/search")
- async def search_drug(
- keyword: Optional[str] = Query(None),
- category: Optional[str] = Query(None),
- page: int = Query(1, ge=1),
- page_size: int = Query(20, ge=1, le=100),
- user: dict = Depends(get_current_user),
- ):
- db = get_db()
- offset = (page - 1) * page_size
- conditions = ["is_active = TRUE"]
- params = {}
- if keyword:
- conditions.append("(name ILIKE :kw OR pinyin ILIKE :kw OR name_en ILIKE :kw)")
- params["kw"] = f"%{keyword}%"
- if category:
- conditions.append("category = :cat")
- params["cat"] = category
- where = "WHERE " + " AND ".join(conditions)
- count_query = f"SELECT COUNT(*) FROM drugs {where}"
- data_query = f"""
- SELECT drug_id, name, name_en, pinyin, category, subcategory,
- source_version, source_volume, source_page, is_active
- FROM drugs {where}
- ORDER BY name
- LIMIT :limit OFFSET :offset
- """
- params["limit"] = page_size
- params["offset"] = offset
- async with db() as session:
- total = (await session.execute(text(count_query), params)).scalar()
- rows = (await session.execute(text(data_query), params)).fetchall()
- items = []
- for row in rows:
- items.append({
- "drug_id": row.drug_id,
- "name": row.name,
- "name_en": row.name_en or "",
- "pinyin": row.pinyin or "",
- "category": row.category or "",
- "subcategory": row.subcategory or "",
- "source_version": row.source_version or "",
- "source_volume": row.source_volume or "",
- "source_page": row.source_page or "",
- "is_active": row.is_active,
- })
- total_pages = max(1, (total + page_size - 1) // page_size)
- return {
- "items": items,
- "total": total,
- "page": page,
- "page_size": page_size,
- "total_pages": total_pages,
- }
- @router.get("/{drug_id}")
- async def get_drug_detail(
- drug_id: str,
- user: dict = Depends(get_current_user),
- ):
- db = get_db()
- async with db() as session:
- row = (await session.execute(
- text("SELECT * FROM drugs WHERE drug_id = :drug_id"),
- {"drug_id": drug_id}
- )).fetchone()
- if not row:
- raise HTTPException(status_code=404, detail="Drug not found")
- return {
- "data": {
- "drug_id": row.drug_id,
- "name": row.name,
- "name_en": row.name_en or "",
- "pinyin": row.pinyin or "",
- "category": row.category or "",
- "subcategory": row.subcategory or "",
- "sections": row.sections or {},
- "source_version": row.source_version or "",
- "source_volume": row.source_volume or "",
- "source_page": row.source_page or "",
- "is_active": row.is_active,
- }
- }
- @router.get("/category/tree")
- async def get_category_tree(user: dict = Depends(get_current_user)):
- db = get_db()
- async with db() as session:
- rows = (await session.execute(
- text("SELECT DISTINCT category, subcategory FROM drugs WHERE category IS NOT NULL ORDER BY category, subcategory")
- )).fetchall()
- tree = {}
- for row in rows:
- cat = row.category
- sub = row.subcategory or ""
- if cat not in tree:
- tree[cat] = []
- if sub and sub not in tree[cat]:
- tree[cat].append(sub)
- return {"tree": [{"name": k, "children": v} for k, v in tree.items()]}
|