微信小程序页面迁移校验之前 P5任务处理之前

This commit is contained in:
Neo
2026-03-09 01:19:21 +08:00
parent 263bf96035
commit 6e20987d2f
1112 changed files with 153824 additions and 219694 deletions

View File

@@ -0,0 +1,102 @@
"""
维客线索路由。
- 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()