首次提交

This commit is contained in:
2026-09-23 13:56:49 +08:00
parent 7c235aab6e
commit 0e47b1bba4
12 changed files with 364 additions and 176 deletions
+8
View File
@@ -0,0 +1,8 @@
"""
蓝图统一导出模块
- 当蓝图数量增多时,在此集中管理,简化 __init__.py 中的注册逻辑
- 新增蓝图后只需在此添加一行 import
"""
from app.routes.user import user_bp
__all__ = ['user_bp']
+64
View File
@@ -0,0 +1,64 @@
"""
用户 API 路由模块
- 使用 Blueprint 实现模块化路由,避免单文件膨胀
- 包含参数校验、异常处理和分页查询的生产级实现
- 所有数据库写操作均包裹在 try/except 中,失败时自动回滚
"""
from flask import Blueprint, request, jsonify
from app import db
from app.models.user import User
# 创建蓝图,名称用于 url_for() 反向解析,__name__ 用于定位模板/静态文件
user_bp = Blueprint('user', __name__)
@user_bp.route('', methods=['POST'])
def create_user():
"""
创建新用户
- POST /api/users
- Body: {"username": "string", "email": "string"}
- Returns: 201 + 用户JSON / 400 + 错误信息 / 500 + 服务器错误
"""
# silent=True 使得非 JSON 请求体返回 None 而非抛出 400 异常
data = request.get_json(silent=True)
# ✅ 入参校验:永远不要信任客户端输入
if not data or 'username' not in data or 'email' not in data:
return jsonify({'error': 'Missing required fields: username, email'}), 400
try:
user = User(username=data['username'], email=data['email'])
db.session.add(user)
# commit 同时完成 flush(发送SQL)和事务提交
db.session.commit()
return jsonify(user.to_dict()), 201
except Exception as e:
# ✅ 异常时必须回滚,否则后续请求复用该 session 会持续报错
db.session.rollback()
# 生产环境应记录日志而非直接返回异常详情,此处为模板演示
return jsonify({'error': str(e)}), 500
@user_bp.route('', methods=['GET'])
def get_users():
"""
分页获取用户列表
- GET /api/users?page=1&per_page=20
- Returns: 分页结果 JSON,包含 items、total、pages、current_page
"""
# type=int 确保参数被转换为整数,非法值回退到默认值
page = request.args.get('page', 1, type=int)
per_page = request.args.get('per_page', 20, type=int)
# paginate() 自动处理 LIMIT/OFFSET,error_out=False 避免页码越界时抛异常
pagination = User.query.order_by(User.created_at.desc()).paginate(
page=page, per_page=per_page, error_out=False
)
return jsonify({
'items': [u.to_dict() for u in pagination.items],
'total': pagination.total, # 总记录数
'pages': pagination.pages, # 总页数
'current_page': page, # 当前页码
})