Files
Neo-ZQYY/apps/backend/app/routers/member_retention_clue.py

103 lines
3.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
维客线索路由。
- POST /api/retention-clue — 提交维客线索UPSERT
- GET /api/retention-clue/{member_id} — 查询某会员的全部维客线索
- DELETE /api/retention-clue/{clue_id} — 删除单条线索
"""
import logging
from fastapi import APIRouter, HTTPException, status
from app.database import get_connection
from app.schemas.member_retention_clue import RetentionClueSubmit, RetentionClueOut
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/api", tags=["维客线索"])
@router.post("/retention-clue")
async def submit_retention_clue(body: RetentionClueSubmit):
"""
提交维客线索INSERT
同一会员可有多条不同大类的线索。
"""
sql = """
INSERT INTO member_retention_clue
(member_id, category, summary, detail,
recorded_by_assistant_id, recorded_by_name, site_id, source)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
RETURNING id
"""
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(sql, (
body.member_id,
body.category.value,
body.summary,
body.detail,
body.recorded_by_assistant_id,
body.recorded_by_name,
body.site_id,
body.source.value,
))
row = cur.fetchone()
conn.commit()
return {"status": "ok", "id": row[0] if row else None}
except Exception:
conn.rollback()
logger.exception("维客线索写入失败: member_id=%s", body.member_id)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="线索提交失败,请稍后重试",
)
finally:
conn.close()
@router.get("/retention-clue/{member_id}", response_model=list[RetentionClueOut])
async def get_retention_clues(member_id: int, site_id: int):
"""查询某会员的全部维客线索,按录入时间倒序。"""
sql = """
SELECT id, member_id, category, summary, detail,
recorded_by_assistant_id, recorded_by_name, recorded_at, site_id, source
FROM member_retention_clue
WHERE member_id = %s AND site_id = %s
ORDER BY recorded_at DESC
"""
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(sql, (member_id, site_id))
rows = cur.fetchall()
cols = [d[0] for d in cur.description]
return [dict(zip(cols, r)) for r in rows]
finally:
conn.close()
@router.delete("/retention-clue/{clue_id}")
async def delete_retention_clue(clue_id: int):
"""删除单条维客线索。"""
sql = "DELETE FROM member_retention_clue WHERE id = %s"
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(sql, (clue_id,))
if cur.rowcount == 0:
raise HTTPException(status_code=404, detail="线索不存在")
conn.commit()
return {"status": "ok"}
except HTTPException:
raise
except Exception:
conn.rollback()
logger.exception("维客线索删除失败: id=%s", clue_id)
raise HTTPException(status_code=500, detail="删除失败")
finally:
conn.close()