from datetime import datetime from flask import Blueprint, request from flask_jwt_extended import jwt_required from app.extensions import db from app.models import DietStatus from app.utils.auth import current_user from app.utils.response import fail, ok diet_bp = Blueprint("diet", __name__) def _parse_status_payload(payload: dict) -> dict: return { "weight": float(payload.get("weight", 0)), "body_fat": float(payload.get("body_fat", 0)), "exercise_kcal": float(payload.get("exercise_kcal", 0)), "intake_kcal": float(payload.get("intake_kcal", 0)), "sleep_hours": float(payload.get("sleep_hours", 7)), "note": (payload.get("note") or "").strip(), } @diet_bp.post("/status") @jwt_required() def create_status(): user = current_user() if not user: return fail("用户不存在", 404) payload = request.get_json(silent=True) or {} data = _parse_status_payload(payload) if data["weight"] <= 0 or data["body_fat"] <= 0: return fail("体重和体脂率必须大于0", 400) status = DietStatus(user_id=user.id, **data) if payload.get("recorded_at"): status.recorded_at = datetime.fromisoformat(payload["recorded_at"]) db.session.add(status) db.session.commit() return ok(status.to_dict(), "饮食状态记录成功") @diet_bp.put("/status/latest") @jwt_required() def update_latest_status(): user = current_user() if not user: return fail("用户不存在", 404) latest = ( DietStatus.query.filter_by(user_id=user.id) .order_by(DietStatus.recorded_at.desc(), DietStatus.id.desc()) .first() ) if not latest: return fail("暂无可编辑的饮食状态", 404) payload = request.get_json(silent=True) or {} data = _parse_status_payload(payload) for key, value in data.items(): setattr(latest, key, value) db.session.commit() return ok(latest.to_dict(), "最新饮食状态已更新") @diet_bp.get("/status/latest") @jwt_required() def get_latest_status(): user = current_user() if not user: return fail("用户不存在", 404) latest = ( DietStatus.query.filter_by(user_id=user.id) .order_by(DietStatus.recorded_at.desc(), DietStatus.id.desc()) .first() ) if not latest: return ok({}) return ok(latest.to_dict()) @diet_bp.get("/history") @jwt_required() def history(): user = current_user() if not user: return fail("用户不存在", 404) limit = min(max(int(request.args.get("limit", 30) or 30), 1), 200) rows = ( DietStatus.query.filter_by(user_id=user.id) .order_by(DietStatus.recorded_at.desc(), DietStatus.id.desc()) .limit(limit) .all() ) return ok([item.to_dict() for item in rows]) @diet_bp.delete("/history/") @jwt_required() def delete_history(status_id: int): user = current_user() if not user: return fail("用户不存在", 404) row = DietStatus.query.filter_by(id=status_id, user_id=user.id).first() if not row: return fail("记录不存在", 404) db.session.delete(row) db.session.commit() return ok({}, "记录已删除")