from fastapi import APIRouter, Depends from sqlalchemy.orm import Session from typing import List from app.models.community import CommunityDB, CommunityCreate, CommunityUpdate, CommunityInfo 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.post("/", response_model=ResponseModel) async def create_community( community: CommunityCreate, db: Session = Depends(get_db), admin: UserDB = Depends(get_admin_user) ): """创建社区""" db_community = CommunityDB(**community.model_dump()) db.add(db_community) db.commit() db.refresh(db_community) return success_response(data=CommunityInfo.model_validate(db_community)) @router.get("/", response_model=ResponseModel) async def get_communities( latitude: float, longitude: float, db: Session = Depends(get_db) ): """获取社区列表""" communities = db.query(CommunityDB).all() # 计算距离并排序 community_list = [] for community in communities: # 使用 Haversine 公式计算两点之间的距离 distance = calculate_distance( latitude, longitude, community.latitude, community.longitude ) community_info = CommunityInfo.model_validate(community) community_info.distance = distance community_list.append(community_info) # 按距离排序 community_list.sort(key=lambda x: x.distance) return success_response(data=community_list) def calculate_distance(lat1: float, lon1: float, lat2: float, lon2: float) -> float: """计算两点之间的距离(米)""" from math import radians, sin, cos, sqrt, atan2 R = 6371000 # 地球半径(米) # 转换为弧度 lat1, lon1, lat2, lon2 = map(radians, [lat1, lon1, lat2, lon2]) # Haversine 公式 dlat = lat2 - lat1 dlon = lon2 - lon1 a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2 c = 2 * atan2(sqrt(a), sqrt(1-a)) distance = R * c return round(distance, 2) # 保留2位小数 @router.get("/{community_id}", response_model=ResponseModel) async def get_community( community_id: int, db: Session = Depends(get_db) ): """获取社区详情""" community = db.query(CommunityDB).filter(CommunityDB.id == community_id).first() if not community: return error_response(code=404, message="社区不存在") return success_response(data=CommunityInfo.model_validate(community)) @router.put("/{community_id}", response_model=ResponseModel) async def update_community( community_id: int, community: CommunityUpdate, db: Session = Depends(get_db), admin: UserDB = Depends(get_admin_user) ): """更新社区信息""" db_community = db.query(CommunityDB).filter(CommunityDB.id == community_id).first() if not db_community: return error_response(code=404, message="社区不存在") update_data = community.model_dump(exclude_unset=True) for key, value in update_data.items(): setattr(db_community, key, value) db.commit() db.refresh(db_community) return success_response(data=CommunityInfo.model_validate(db_community)) @router.delete("/{community_id}", response_model=ResponseModel) async def delete_community( community_id: int, db: Session = Depends(get_db), admin: UserDB = Depends(get_admin_user) ): """删除社区""" result = db.query(CommunityDB).filter(CommunityDB.id == community_id).delete() if not result: return error_response(code=404, message="社区不存在") db.commit() return success_response(message="社区已删除")