diff --git a/app/api/endpoints/point.py b/app/api/endpoints/point.py new file mode 100644 index 0000000..63c7d1f --- /dev/null +++ b/app/api/endpoints/point.py @@ -0,0 +1,55 @@ +from fastapi import APIRouter, Depends +from sqlalchemy.orm import Session +from app.models.point import PointRecordDB, PointRecordCreate, PointRecordInfo +from app.models.user import UserDB +from app.models.database import get_db +from app.api.deps import get_current_user, get_admin_user +from app.core.response import success_response, error_response, ResponseModel +from typing import List +from decimal import Decimal + +router = APIRouter() + +@router.post("", response_model=ResponseModel) +async def add_points( + record: PointRecordCreate, + db: Session = Depends(get_db), + current_user: UserDB = Depends(get_admin_user) # 仅管理员可操作 +): + """增加用户积分""" + user = db.query(UserDB).filter(UserDB.userid == current_user.userid).first() + + # 创建积分记录 + point_record = PointRecordDB( + user_id=user.userid, + points=record.points, + description=record.description + ) + db.add(point_record) + + # 更新用户积分 + user.points = user.points + Decimal(str(record.points)) + + try: + db.commit() + db.refresh(point_record) + return success_response(data=PointRecordInfo.model_validate(point_record)) + except Exception as e: + db.rollback() + return error_response(code=500, message=f"操作失败: {str(e)}") + +@router.get("/records", response_model=ResponseModel) +async def get_point_records( + db: Session = Depends(get_db), + current_user: UserDB = Depends(get_current_user) +): + """获取积分明细""" + records = db.query(PointRecordDB).filter( + PointRecordDB.user_id == current_user.userid + ).order_by( + PointRecordDB.create_time.desc() + ).all() + + return success_response(data=[ + PointRecordInfo.model_validate(r) for r in records + ]) \ No newline at end of file diff --git a/app/main.py b/app/main.py index 549b292..5948594 100644 --- a/app/main.py +++ b/app/main.py @@ -1,6 +1,6 @@ from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware -from app.api.endpoints import user, address, community, station, order, coupon, community_building, upload, merchant, merchant_product, merchant_product_category, merchant_order +from app.api.endpoints import user, address, community, station, order, coupon, community_building, upload, merchant, merchant_product, merchant_product_category, merchant_order, point from app.models.database import Base, engine from fastapi.exceptions import RequestValidationError from fastapi.responses import JSONResponse @@ -38,6 +38,7 @@ app.include_router(merchant.router, prefix="/api/merchant", tags=["商家"]) app.include_router(merchant_product.router, prefix="/api/merchant/product", tags=["商家产品"]) app.include_router(merchant_product_category.router, prefix="/api/merchant/category", tags=["商品分类"]) app.include_router(merchant_order.router, prefix="/api/merchant/order", tags=["商家订单"]) +app.include_router(point.router, prefix="/api/point", tags=["用户积分"]) @app.get("/") async def root(): diff --git a/app/models/point.py b/app/models/point.py new file mode 100644 index 0000000..845f276 --- /dev/null +++ b/app/models/point.py @@ -0,0 +1,29 @@ +from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, DECIMAL +from sqlalchemy.sql import func +from pydantic import BaseModel, Field +from typing import Optional +from datetime import datetime +from .database import Base + +class PointRecordDB(Base): + __tablename__ = "point_records" + + id = Column(Integer, primary_key=True, autoincrement=True) + user_id = Column(Integer, ForeignKey("users.userid"), nullable=False) + points = Column(DECIMAL(10,1), nullable=False) + description = Column(String(200), nullable=False) + create_time = Column(DateTime(timezone=True), server_default=func.now()) + +class PointRecordCreate(BaseModel): + points: float = Field(..., description="积分变动值,可为正或负") + description: str = Field(..., min_length=1, max_length=200) + +class PointRecordInfo(BaseModel): + id: int + user_id: int + points: float + description: str + create_time: datetime + + class Config: + from_attributes = True \ No newline at end of file diff --git a/app/models/user.py b/app/models/user.py index 76f470e..f80699f 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -1,4 +1,4 @@ -from sqlalchemy import Column, String, DateTime, Integer, Boolean, Enum, ForeignKey +from sqlalchemy import Column, String, DateTime, Integer, Boolean, Enum, ForeignKey, DECIMAL from sqlalchemy.sql import func from sqlalchemy.dialects.mysql import JSON from pydantic import BaseModel, Field @@ -31,6 +31,7 @@ class UserDB(Base): password = Column(String(128), nullable=True) # 加密后的密码 avatar = Column(String(200), nullable=True) # 头像URL地址 gender = Column(Enum(Gender), nullable=False, default=Gender.UNKNOWN) + points = Column(DECIMAL(10,1), nullable=False, default=0.0) roles = Column(JSON, default=lambda: [UserRole.USER]) # 存储角色列表 create_time = Column(DateTime(timezone=True), server_default=func.now()) update_time = Column(DateTime(timezone=True), onupdate=func.now()) @@ -49,6 +50,7 @@ class UserInfo(BaseModel): referral_code: Optional[str] avatar: Optional[str] = None gender: Gender + points: float roles: List[UserRole] class Config: