122 lines
3.2 KiB
Python
122 lines
3.2 KiB
Python
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/<int:status_id>")
|
|
@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({}, "记录已删除")
|