Files
track/backend/app/api/v1/endpoints/materials.py

146 lines
4.5 KiB
Python
Raw Normal View History

"""物料选择器 — 读 MOM material_base,按成品/半成品 category 手风琴分组"""
from fastapi import APIRouter, Query, HTTPException, status
from pydantic import BaseModel
from app.core.mom_database import MomSessionLocal
from sqlalchemy import text
router = APIRouter(prefix="/materials", tags=["物料选择"])
# 只展示成品 / 半成品(category 字段区分,如 IRIS/成品/… / IRIS/半成品/…)
TYPE_FILTER = "category ILIKE '%成品%' OR category ILIKE '%半成品%'"
# ============================================================
# 响应模型
# ============================================================
class MaterialGroup(BaseModel):
category: str
count: int
class MaterialItem(BaseModel):
id: int
name: str
spec: str
category: str
type: str
unit: str
is_enabled: bool
# ============================================================
# 端点
# ============================================================
@router.get("/groups", response_model=list[MaterialGroup])
def get_material_groups(
keyword: str = Query("", description="搜索(按名称/规格)"),
):
"""
按 category 分组汇总,前端渲染手风琴外层。
只返回成品/半成品分类。
"""
db = MomSessionLocal()
try:
if keyword.strip():
sql = text(
f"""
SELECT category, COUNT(*) AS count
FROM material_base
WHERE is_enabled = TRUE
AND ({TYPE_FILTER})
AND (name ILIKE :kw OR spec_model ILIKE :kw)
GROUP BY category
ORDER BY category
"""
)
result = db.execute(sql, {"kw": f"%{keyword.strip()}%"})
else:
sql = text(
f"""
SELECT category, COUNT(*) AS count
FROM material_base
WHERE is_enabled = TRUE
AND ({TYPE_FILTER})
GROUP BY category
ORDER BY category
"""
)
result = db.execute(sql)
rows = result.fetchall()
return [MaterialGroup(category=row.category, count=row.count) for row in rows]
except Exception as e:
raise HTTPException(
status_code=status.HTTP_502_BAD_GATEWAY,
detail=f"MOM material_base 查询失败: {str(e)}",
)
finally:
db.close()
@router.get("/items", response_model=list[MaterialItem])
def get_material_items(
category: str = Query(..., description="物料分类"),
keyword: str = Query("", description="分组内搜索"),
limit: int = Query(500, ge=1, le=9999),
):
"""
获取指定 category 下的物料条目,前端展开手风琴时懒加载。
"""
db = MomSessionLocal()
try:
if keyword.strip():
sql = text(
f"""
SELECT id, name, spec_model AS spec, category, material_type AS type,
COALESCE(unit, '') AS unit, is_enabled
FROM material_base
WHERE is_enabled = TRUE
AND ({TYPE_FILTER})
AND category = :cat
AND (name ILIKE :kw OR spec_model ILIKE :kw)
ORDER BY name
LIMIT :lim
"""
)
result = db.execute(
sql, {"cat": category, "kw": f"%{keyword.strip()}%", "lim": limit}
)
else:
sql = text(
f"""
SELECT id, name, spec_model AS spec, category, material_type AS type,
COALESCE(unit, '') AS unit, is_enabled
FROM material_base
WHERE is_enabled = TRUE
AND ({TYPE_FILTER})
AND category = :cat
ORDER BY name
LIMIT :lim
"""
)
result = db.execute(sql, {"cat": category, "lim": limit})
rows = result.fetchall()
return [
MaterialItem(
id=row.id,
name=row.name,
spec=row.spec,
category=row.category,
type=row.type,
unit=row.unit,
is_enabled=row.is_enabled,
)
for row in rows
]
except Exception as e:
raise HTTPException(
status_code=status.HTTP_502_BAD_GATEWAY,
detail=f"MOM material_base 查询失败: {str(e)}",
)
finally:
db.close()