| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- from fastapi import APIRouter, Request
- from fastapi.responses import JSONResponse
- from database import SessionLocal
- from models.user_data import UserData
- from models.total import User
- from models.points import PointsConsumptionLog
- from utils.logger import logger
- import time
- router = APIRouter()
- REQUIRED_POINTS = 10
- @router.get("/points/balance")
- async def get_balance(request: Request):
- """获取用户积分余额(支持本地用户和外部用户)"""
- user_info = request.state.user
- if not user_info:
- return JSONResponse(status_code=401, content={"statusCode": 401, "msg": "未认证"})
- db = SessionLocal()
- try:
- # 优先查询本地用户
- user = db.query(User).filter(
- User.id == user_info.user_id,
- User.is_deleted == 0
- ).first()
- if user:
- return JSONResponse(content={
- "statusCode": 200,
- "msg": "success",
- "data": {"points": user.points or 0}
- })
- # 查询外部用户
- user_data = db.query(UserData).filter(
- UserData.accountID == user_info.account
- ).first()
- if not user_data:
- return JSONResponse(content={"statusCode": 404, "msg": "未找到用户数据"})
- return JSONResponse(content={
- "statusCode": 200,
- "msg": "success",
- "data": {"points": user_data.points or 0}
- })
- except Exception as e:
- logger.error(f"获取积分余额失败: {e}")
- return JSONResponse(content={"statusCode": 500, "msg": f"获取积分余额失败: {str(e)}"})
- finally:
- db.close()
- @router.post("/points/consume")
- async def consume_points(request: Request):
- """消费积分下载文件(每次消耗10积分,支持本地用户和外部用户)"""
- user_info = request.state.user
- if not user_info:
- return JSONResponse(status_code=401, content={"statusCode": 401, "msg": "未认证"})
- try:
- body = await request.json()
- except Exception:
- return JSONResponse(content={"statusCode": 400, "msg": "JSON解析失败"})
- file_name = body.get("file_name", "")
- file_url = body.get("file_url", "")
- db = SessionLocal()
- try:
- # 优先查询本地用户
- user = db.query(User).filter(
- User.id == user_info.user_id,
- User.is_deleted == 0
- ).first()
- if user:
- current_points = user.points or 0
- if current_points < REQUIRED_POINTS:
- return JSONResponse(content={
- "statusCode": 400,
- "msg": "积分不足,下载需要10积分",
- "data": {
- "current_points": current_points,
- "required_points": REQUIRED_POINTS
- }
- })
- new_balance = current_points - REQUIRED_POINTS
- user.points = new_balance
- now = int(time.time())
- log = PointsConsumptionLog(
- user_id=str(user.id),
- file_name=file_name,
- file_url=file_url,
- points_consumed=REQUIRED_POINTS,
- balance_after=new_balance,
- created_at=now,
- updated_at=now,
- )
- db.add(log)
- db.commit()
- return JSONResponse(content={
- "statusCode": 200,
- "msg": "success",
- "data": {
- "new_balance": new_balance,
- "points_consumed": REQUIRED_POINTS
- }
- })
- # 查询外部用户
- user_data = db.query(UserData).filter(
- UserData.accountID == user_info.account
- ).first()
- if not user_data:
- return JSONResponse(content={"statusCode": 404, "msg": "未找到用户数据"})
- current_points = user_data.points or 0
- if current_points < REQUIRED_POINTS:
- return JSONResponse(content={
- "statusCode": 400,
- "msg": "积分不足,下载需要10积分",
- "data": {
- "current_points": current_points,
- "required_points": REQUIRED_POINTS
- }
- })
- new_balance = current_points - REQUIRED_POINTS
- user_data.points = new_balance
- now = int(time.time())
- log = PointsConsumptionLog(
- user_id=user_info.account,
- file_name=file_name,
- file_url=file_url,
- points_consumed=REQUIRED_POINTS,
- balance_after=new_balance,
- created_at=now,
- updated_at=now,
- )
- db.add(log)
- db.commit()
- return JSONResponse(content={
- "statusCode": 200,
- "msg": "success",
- "data": {
- "new_balance": new_balance,
- "points_consumed": REQUIRED_POINTS
- }
- })
- except Exception as e:
- db.rollback()
- logger.error(f"消费积分失败: {e}")
- return JSONResponse(content={"statusCode": 500, "msg": f"消费积分失败: {str(e)}"})
- finally:
- db.close()
- @router.post("/points/add")
- async def add_points(request: Request):
- """增加积分(仅管理员)"""
- user_info = request.state.user
- if not user_info:
- return JSONResponse(status_code=401, content={"statusCode": 401, "msg": "未认证"})
-
- # 检查管理员权限
- if user_info.role != "admin":
- return JSONResponse(status_code=403, content={"statusCode": 403, "msg": "权限不足"})
-
- try:
- body = await request.json()
- except Exception:
- return JSONResponse(content={"statusCode": 400, "msg": "JSON解析失败"})
-
- user_id = body.get("user_id")
- points = body.get("points", 0)
- reason = body.get("reason", "")
-
- if not user_id or points <= 0:
- return JSONResponse(content={"statusCode": 400, "msg": "参数错误"})
-
- db = SessionLocal()
- try:
- # 优先查询本地用户
- user = db.query(User).filter(
- User.id == user_id,
- User.is_deleted == 0
- ).first()
-
- if user:
- user.points = (user.points or 0) + points
- db.commit()
-
- logger.info(f"管理员 {user_info.username} 为用户 {user_id} 添加 {points} 积分,原因: {reason}")
- return JSONResponse(content={
- "statusCode": 200,
- "msg": "积分添加成功",
- "data": {"new_balance": user.points}
- })
-
- # 查询外部用户
- user_data = db.query(UserData).filter(UserData.id == user_id).first()
- if not user_data:
- return JSONResponse(content={"statusCode": 404, "msg": "用户不存在"})
-
- user_data.points = (user_data.points or 0) + points
- db.commit()
-
- logger.info(f"管理员 {user_info.username} 为外部用户 {user_id} 添加 {points} 积分,原因: {reason}")
- return JSONResponse(content={
- "statusCode": 200,
- "msg": "积分添加成功",
- "data": {"new_balance": user_data.points}
- })
-
- except Exception as e:
- db.rollback()
- logger.error(f"添加积分失败: {e}")
- return JSONResponse(content={"statusCode": 500, "msg": f"添加积分失败: {str(e)}"})
- finally:
- db.close()
- @router.get("/points/logs")
- @router.get("/points/history")
- async def get_consumption_history(request: Request, page: int = 1, pageSize: int = 10):
- """获取积分消费记录(支持本地用户和外部用户)"""
- user_info = request.state.user
- if not user_info:
- return JSONResponse(status_code=401, content={"statusCode": 401, "msg": "未认证"})
- db = SessionLocal()
- try:
- # 确定用户ID(本地用户用user_id,外部用户用account)
- user = db.query(User).filter(
- User.id == user_info.user_id,
- User.is_deleted == 0
- ).first()
- user_identifier = str(user.id) if user else user_info.account
- query = db.query(PointsConsumptionLog).filter(
- PointsConsumptionLog.user_id == user_identifier
- )
- total = query.count()
- logs = query.order_by(PointsConsumptionLog.id.desc()) \
- .offset((page - 1) * pageSize) \
- .limit(pageSize) \
- .all()
- items = [
- {
- "id": log.id,
- "file_name": log.file_name,
- "file_url": log.file_url,
- "points_consumed": log.points_consumed,
- "balance_after": log.balance_after,
- "created_at": log.created_at,
- }
- for log in logs
- ]
- return JSONResponse(content={
- "statusCode": 200,
- "msg": "success",
- "data": {
- "list": items,
- "total": total,
- "page": page,
- "pageSize": pageSize,
- }
- })
- except Exception as e:
- logger.error(f"获取消费记录失败: {e}")
- return JSONResponse(content={"statusCode": 500, "msg": f"获取消费记录失败: {str(e)}"})
- finally:
- db.close()
|