import json import logging from fastapi import APIRouter, HTTPException from pydantic import BaseModel from .. import config, db logger = logging.getLogger(__name__) router = APIRouter(prefix="/api/v1/survey", tags=["survey"]) def _fmt_row(row): if "answers" in row and isinstance(row["answers"], str): try: row["answers"] = json.loads(row["answers"]) except Exception: logger.exception("survey answers 解析失败") row["answers"] = {} for key in ("created_at", "submitted_at", "updated_at"): row[key] = str(row.get(key)) if row.get(key) else "" return row class SurveyResponseRequest(BaseModel): task_id: int group_id: str answers: dict = {} class AnswersRequest(BaseModel): answers: dict = {} @router.get("/tasks") def tasks(): rows = db.fetch_all("SELECT * FROM survey_tasks WHERE status='active' ORDER BY task_no", db=config.SURVEY_DB) return [_fmt_row(r) for r in rows] @router.get("/responses") def responses(task_id: int): rows = db.fetch_all("SELECT * FROM survey_responses WHERE task_id=%s ORDER BY group_id", (task_id,), db=config.SURVEY_DB) return [_fmt_row(r) for r in rows] @router.post("/response") def response(req: SurveyResponseRequest): if not req.task_id or not req.group_id or not req.answers: raise HTTPException(status_code=400, detail="missing fields") answers_json = json.dumps(req.answers, ensure_ascii=False) existing = db.fetch_one( "SELECT id FROM survey_responses WHERE task_id=%s AND group_id=%s", (req.task_id, req.group_id), db=config.SURVEY_DB, ) if existing: db.execute("UPDATE survey_responses SET answers=%s WHERE id=%s", (answers_json, existing["id"]), db=config.SURVEY_DB) rid = existing["id"] else: rid = db.execute( "INSERT INTO survey_responses (task_id,group_id,answers) VALUES (%s,%s,%s)", (req.task_id, req.group_id, answers_json), db=config.SURVEY_DB, ) row = db.fetch_one("SELECT * FROM survey_responses WHERE id=%s", (rid,), db=config.SURVEY_DB) return _fmt_row(row) @router.put("/response/{rid}") def update_response(rid: int, req: AnswersRequest): db.execute("UPDATE survey_responses SET answers=%s WHERE id=%s", (json.dumps(req.answers, ensure_ascii=False), rid), db=config.SURVEY_DB) row = db.fetch_one("SELECT * FROM survey_responses WHERE id=%s", (rid,), db=config.SURVEY_DB) if not row: raise HTTPException(status_code=404, detail="not found") return _fmt_row(row) @router.post("/task") def task(): return {"msg": "功能预留,后续开放"}