diff --git a/app/api/endpoints/community_building.py b/app/api/endpoints/community_building.py new file mode 100644 index 0000000..5d5c9fa --- /dev/null +++ b/app/api/endpoints/community_building.py @@ -0,0 +1,109 @@ +from fastapi import APIRouter, Depends +from sqlalchemy.orm import Session +from typing import List +from app.models.community_building import ( + CommunityBuildingDB, + CommunityBuildingCreate, + CommunityBuildingUpdate, + CommunityBuildingInfo +) +from app.models.database import get_db +from app.api.deps import get_admin_user +from app.models.user import UserDB +from app.core.response import success_response, error_response, ResponseModel + +router = APIRouter() + +@router.get("/list/{community_id}", response_model=ResponseModel) +async def get_community_buildings( + community_id: int, + skip: int = 0, + limit: int = 20, + db: Session = Depends(get_db) +): + """获取小区的楼栋列表""" + buildings = db.query(CommunityBuildingDB).filter( + CommunityBuildingDB.community_id == community_id + ).order_by( + CommunityBuildingDB.building_number + ).offset(skip).limit(limit).all() + + return success_response(data=[ + CommunityBuildingInfo.model_validate(b) for b in buildings + ]) + +@router.post("", response_model=ResponseModel) +async def create_building( + building: CommunityBuildingCreate, + db: Session = Depends(get_db), + admin: UserDB = Depends(get_admin_user) +): + """创建楼栋(管理员)""" + # 检查是否已存在相同编号的楼栋 + exists = db.query(CommunityBuildingDB).filter( + CommunityBuildingDB.community_id == building.community_id, + CommunityBuildingDB.building_number == building.building_number + ).first() + + if exists: + return error_response(code=400, message="该楼栋编号已存在") + + db_building = CommunityBuildingDB(**building.model_dump()) + db.add(db_building) + + try: + db.commit() + db.refresh(db_building) + return success_response(data=CommunityBuildingInfo.model_validate(db_building)) + except Exception as e: + db.rollback() + return error_response(code=500, message=f"创建失败: {str(e)}") + +@router.put("/{building_id}", response_model=ResponseModel) +async def update_building( + building_id: int, + building: CommunityBuildingUpdate, + db: Session = Depends(get_db), + admin: UserDB = Depends(get_admin_user) +): + """更新楼栋信息(管理员)""" + db_building = db.query(CommunityBuildingDB).filter( + CommunityBuildingDB.id == building_id + ).first() + + if not db_building: + return error_response(code=404, message="楼栋不存在") + + update_data = building.model_dump(exclude_unset=True) + for key, value in update_data.items(): + setattr(db_building, key, value) + + try: + db.commit() + db.refresh(db_building) + return success_response(data=CommunityBuildingInfo.model_validate(db_building)) + except Exception as e: + db.rollback() + return error_response(code=500, message=f"更新失败: {str(e)}") + +@router.delete("/{building_id}", response_model=ResponseModel) +async def delete_building( + building_id: int, + db: Session = Depends(get_db), + admin: UserDB = Depends(get_admin_user) +): + """删除楼栋(管理员)""" + db_building = db.query(CommunityBuildingDB).filter( + CommunityBuildingDB.id == building_id + ).first() + + if not db_building: + return error_response(code=404, message="楼栋不存在") + + try: + db.delete(db_building) + db.commit() + return success_response(message="删除成功") + except Exception as e: + db.rollback() + return error_response(code=500, message=f"删除失败: {str(e)}") \ No newline at end of file diff --git a/app/main.py b/app/main.py index f832a5f..4695dd5 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 +from app.api.endpoints import user, address, community, station, order, coupon, community_building from app.models.database import Base, engine from fastapi.exceptions import RequestValidationError from fastapi.responses import JSONResponse @@ -29,6 +29,7 @@ app.add_middleware( app.include_router(user.router, prefix="/api/user", tags=["用户"]) app.include_router(address.router, prefix="/api/address", tags=["配送地址"]) app.include_router(community.router, prefix="/api/community", tags=["社区"]) +app.include_router(community_building.router, prefix="/api/community/building", tags=["社区楼栋"]) app.include_router(station.router, prefix="/api/station", tags=["驿站"]) app.include_router(order.router, prefix="/api/order", tags=["订单"]) app.include_router(coupon.router, prefix="/api/coupon", tags=["优惠券"]) diff --git a/app/models/community_building.py b/app/models/community_building.py new file mode 100644 index 0000000..d59f670 --- /dev/null +++ b/app/models/community_building.py @@ -0,0 +1,40 @@ +from sqlalchemy import Column, Integer, String, ForeignKey, DateTime +from sqlalchemy.sql import func +from pydantic import BaseModel, Field +from typing import Optional +from datetime import datetime +from .database import Base + +# 数据库模型 +class CommunityBuildingDB(Base): + __tablename__ = "community_buildings" + + id = Column(Integer, primary_key=True, autoincrement=True) + community_id = Column(Integer, ForeignKey("communities.id"), index=True) + building_name = Column(String(50), nullable=False) # 楼栋名称,如"1号楼" + building_number = Column(String(20), nullable=False) # 楼栋编号,如"A1" + create_time = Column(DateTime(timezone=True), server_default=func.now()) + update_time = Column(DateTime(timezone=True), onupdate=func.now()) + + class Config: + unique_together = [("community_id", "building_number")] + +# Pydantic 模型 +class CommunityBuildingCreate(BaseModel): + community_id: int + building_name: str = Field(..., max_length=50) + building_number: str = Field(..., max_length=20) + +class CommunityBuildingUpdate(BaseModel): + building_name: Optional[str] = Field(None, max_length=50) + building_number: Optional[str] = Field(None, max_length=20) + +class CommunityBuildingInfo(BaseModel): + id: int + community_id: int + building_name: str + building_number: str + create_time: datetime + + class Config: + from_attributes = True \ No newline at end of file