"""用户偏好 API""" from fastapi import APIRouter, Depends, Query from pydantic import BaseModel from app.database import SessionLocalPMS router = APIRouter(prefix="/api/pms/preference", tags=["用户偏好"]) class PreferenceResponse(BaseModel): user_id: int default_bom_target_id: int | None favorite_target_ids: list[str] # 存储 bom_key 字符串列表 class PreferenceUpdate(BaseModel): default_bom_target_id: int | None favorite_target_ids: list[str] | None def _parse_fav(raw) -> list[str]: """从 JSON 字段安全解析字符串列表(支持旧格式纯数字字符串)""" if raw is None: return [] if isinstance(raw, list): return [str(x) for x in raw if x is not None] return [] def _get_or_create(db, user_id: int): from app.models import PmsUserPreference pref = db.query(PmsUserPreference).filter( PmsUserPreference.user_id == user_id ).first() if not pref: pref = PmsUserPreference(user_id=user_id) db.add(pref) db.commit() db.refresh(pref) return pref # ── 1. 获取偏好 ──────────────────────────────────────────────────────── @router.get("", response_model=PreferenceResponse) async def get_preference(user_id: int = Query(...)): from app.models import PmsUserPreference db = SessionLocalPMS() try: pref = db.query(PmsUserPreference).filter( PmsUserPreference.user_id == user_id ).first() if not pref: return PreferenceResponse(user_id=user_id, default_bom_target_id=None, favorite_target_ids=[]) return PreferenceResponse( user_id=pref.user_id, default_bom_target_id=pref.default_bom_target_id, favorite_target_ids=_parse_fav(pref.favorite_target_ids) ) finally: db.close() # ── 2. 完整更新偏好 ──────────────────────────────────────────────────── @router.put("", response_model=PreferenceResponse) async def put_preference(user_id: int = Query(...), data: PreferenceUpdate = ...): db = SessionLocalPMS() try: pref = _get_or_create(db, user_id) if data.default_bom_target_id is not None: pref.default_bom_target_id = data.default_bom_target_id if data.favorite_target_ids is not None: pref.favorite_target_ids = data.favorite_target_ids db.commit() db.refresh(pref) return PreferenceResponse( user_id=pref.user_id, default_bom_target_id=pref.default_bom_target_id, favorite_target_ids=_parse_fav(pref.favorite_target_ids) ) finally: db.close() # ── 3. 添加常看(bom_key)─────────────────────────────────────────────── @router.post("/favorite/add", response_model=PreferenceResponse) async def add_favorite(user_id: int = Query(...), target_id: str = Query(..., description="bom_key")): """ 添加 bom_key 到用户常看列表 路径: POST /api/pms/preference/favorite/add?user_id=1&target_id=181_v1_1 """ db = SessionLocalPMS() try: pref = _get_or_create(db, user_id) current: list[str] = _parse_fav(pref.favorite_target_ids) if target_id not in current: current.append(target_id) pref.favorite_target_ids = current db.commit() db.refresh(pref) return PreferenceResponse( user_id=pref.user_id, default_bom_target_id=pref.default_bom_target_id, favorite_target_ids=_parse_fav(pref.favorite_target_ids) ) finally: db.close() # ── 4. 移除常看(bom_key)─────────────────────────────────────────────── @router.post("/favorite/remove", response_model=PreferenceResponse) async def remove_favorite(user_id: int = Query(...), target_id: str = Query(..., description="bom_key")): """ 从用户常看列表移除 bom_key 路径: POST /api/pms/preference/favorite/remove?user_id=1&target_id=181_v1_1 """ db = SessionLocalPMS() try: pref = _get_or_create(db, user_id) current: list[str] = _parse_fav(pref.favorite_target_ids) if target_id in current: current.remove(target_id) pref.favorite_target_ids = current db.commit() db.refresh(pref) return PreferenceResponse( user_id=pref.user_id, default_bom_target_id=pref.default_bom_target_id, favorite_target_ids=_parse_fav(pref.favorite_target_ids) ) finally: db.close() # ── 5. 保存排序(替换全部顺序)──────────────────────────────────────── class ReorderRequest(BaseModel): favorite_keys: list[str] @router.post("/favorite/reorder") async def reorder_favorites(user_id: int = Query(...), data: ReorderRequest = ...): """ 用新数组完整替换用户常看列表的顺序 路径: POST /api/pms/preference/favorite/reorder?user_id=1 Body: {"favorite_keys": ["181_OF-L2_V1.0", "1784_KY*HPPA_V1.0"]} """ from sqlalchemy.orm.attributes import flag_modified db = SessionLocalPMS() try: pref = _get_or_create(db, user_id) pref.favorite_target_ids = data.favorite_keys flag_modified(pref, "favorite_target_ids") db.commit() db.refresh(pref) return { "user_id": pref.user_id, "default_bom_target_id": pref.default_bom_target_id, "favorite_target_ids": _parse_fav(pref.favorite_target_ids) } finally: db.close()