159 lines
5.9 KiB
Python
159 lines
5.9 KiB
Python
"""用户偏好 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() |