From 1dabf231b1a6854c9e1c54a9daed324bc75d61fe Mon Sep 17 00:00:00 2001 From: aaron <> Date: Sun, 9 Mar 2025 23:37:33 +0800 Subject: [PATCH] update --- app/api/endpoints/community.py | 17 +- app/api/endpoints/community_set.py | 172 +++++++++++++++++++++ app/api/endpoints/community_set_mapping.py | 163 +++++++++++++++++++ app/api/endpoints/user.py | 20 +++ app/main.py | 4 +- app/models/community.py | 2 + app/models/community_set.py | 14 ++ app/models/community_set_mapping.py | 14 ++ app/models/user.py | 2 + 9 files changed, 406 insertions(+), 2 deletions(-) create mode 100644 app/api/endpoints/community_set.py create mode 100644 app/api/endpoints/community_set_mapping.py create mode 100644 app/models/community_set.py create mode 100644 app/models/community_set_mapping.py diff --git a/app/api/endpoints/community.py b/app/api/endpoints/community.py index c716f9c..9ed036b 100644 --- a/app/api/endpoints/community.py +++ b/app/api/endpoints/community.py @@ -164,4 +164,19 @@ async def delete_community( return error_response(code=404, message="社区不存在") db.commit() - return success_response(message="社区已删除") \ No newline at end of file + return success_response(message="社区已删除") + +#查询小区 +@router.get("/search_by_name/{name}", response_model=ResponseModel) +async def search_community_by_name( + name: str, + db: Session = Depends(get_db) +): + """通过小区名称搜索小区""" + communities = db.query(CommunityDB).filter(CommunityDB.name.ilike(f"%{name}%")).all() + + results=[] + for community in communities: + results.append(CommunityInfo.model_validate(community)) + + return success_response(data=results) \ No newline at end of file diff --git a/app/api/endpoints/community_set.py b/app/api/endpoints/community_set.py new file mode 100644 index 0000000..0460a64 --- /dev/null +++ b/app/api/endpoints/community_set.py @@ -0,0 +1,172 @@ +from fastapi import APIRouter, Depends, HTTPException, Query, Path +from sqlalchemy.orm import Session +from typing import List, Optional +from pydantic import BaseModel, Field +from app.models.database import get_db +from app.models.community_set import CommunitySet +from app.api.deps import get_current_user, get_admin_user +from app.models.user import UserDB +from app.models.community import CommunityDB +from app.models.community_set_mapping import CommunitySetMapping +from datetime import datetime +from app.core.response import success_response, error_response +router = APIRouter() + +# 请求和响应模型 +class CommunitySetCreate(BaseModel): + set_name: str = Field(..., min_length=1, max_length=100, description="集合名称") + user_id: int = Field(..., description="用户ID") +class CommunitySetUpdate(BaseModel): + set_name: str = Field(..., min_length=1, max_length=100, description="集合名称") + user_id: int = Field(..., description="用户ID") + +class CommunitySetInfo(BaseModel): + id: int + set_name: str + user_id: int + create_time: datetime + update_time: datetime + user_name: Optional[str] = None + + class Config: + from_attributes = True + +# 创建社区集合 +@router.post("/", response_model=CommunitySetInfo) +async def create_community_set( + community_set: CommunitySetCreate, + db: Session = Depends(get_db), + current_user: UserDB = Depends(get_admin_user) +): + """创建社区集合""" + new_set = CommunitySet( + set_name=community_set.set_name, + user_id=community_set.user_id + ) + db.add(new_set) + db.commit() + db.refresh(new_set) + return success_response(data=CommunitySetInfo.model_validate(new_set)) + +# 获取当前用户的所有社区集合 +@router.get("/list/user", response_model=List[CommunitySetInfo]) +async def get_user_community_sets( + db: Session = Depends(get_db), + current_user: UserDB = Depends(get_current_user), + skip: int = Query(0, ge=0), + limit: int = Query(100, ge=1, le=100) +): + """获取当前用户的所有社区集合""" + sets = db.query(CommunitySet).filter( + CommunitySet.user_id == current_user.userid + ).offset(skip).limit(limit).all() + + results = [CommunitySetInfo.model_validate(set) for set in sets] + + total = db.query(CommunitySet).filter( + CommunitySet.user_id == current_user.userid + ).count() + + return success_response(data={"total": total, "items": results}) + +# 获取特定社区集合 +@router.get("/{set_id}", response_model=CommunitySetInfo) +async def get_community_set( + set_id: int = Path(..., ge=1), + db: Session = Depends(get_db), + current_user: UserDB = Depends(get_current_user) +): + """获取特定社区集合""" + community_set = db.query(CommunitySet).filter( + CommunitySet.id == set_id, + CommunitySet.user_id == current_user.userid + ).first() + + if not community_set: + raise HTTPException(status_code=404, detail="社区集合不存在") + + result = CommunitySetInfo.model_validate(community_set) + + return success_response(data=result) + + +# 管理员获取所有社区集合 +@router.get("/list/all", response_model=List[CommunitySetInfo]) +async def get_all_community_sets( + skip: int = Query(0, ge=0), + limit: int = Query(20, ge=1, le=100), + db: Session = Depends(get_db), + current_user: UserDB = Depends(get_admin_user) +): + """管理员获取所有社区集合""" + + # 获取所有社区集合, join 社区名字和 用户名字 + sets = db.query(CommunitySet, UserDB.nickname.label("user_name")).join(UserDB, CommunitySet.user_id == UserDB.userid).offset(skip).limit(limit).all() + + results = [] + for set in sets: + + # 查询集合下有多少个社区 + community_count = db.query(CommunitySetMapping).filter( + CommunitySetMapping.set_id == set.CommunitySet.id + ).count() + + result= { + "id": set.CommunitySet.id, + "set_name": set.CommunitySet.set_name, + "user_id": set.CommunitySet.user_id, + "user_name": set.user_name, + "create_time": set.CommunitySet.create_time, + "update_time": set.CommunitySet.update_time, + "community_count": community_count + } + results.append(result) + + total = db.query(CommunitySet).count() + + return success_response(data={"total": total, "items": results}) + +# 更新社区集合 +@router.put("/{set_id}", response_model=CommunitySetInfo) +async def update_community_set( + community_set: CommunitySetUpdate, + set_id: int = Path(..., ge=1), + db: Session = Depends(get_db), + current_user: UserDB = Depends(get_admin_user) +): + """更新社区集合""" + db_set = db.query(CommunitySet).filter( + CommunitySet.id == set_id + ).first() + + if not db_set: + return error_response(code=404, message="社区集合不存在") + + db_set.set_name = community_set.set_name + db_set.user_id = community_set.user_id + + db.commit() + db.refresh(db_set) + + return success_response(data= CommunitySetInfo.model_validate(db_set)) + +# 删除社区集合 +@router.delete("/{set_id}", response_model=dict) +async def delete_community_set( + set_id: int = Path(..., ge=1), + db: Session = Depends(get_db), + current_user: UserDB = Depends(get_current_user) +): + """删除社区集合""" + db_set = db.query(CommunitySet).filter( + CommunitySet.id == set_id, + CommunitySet.user_id == current_user.userid + ).first() + + if not db_set: + return error_response(code=404, message="社区集合不存在") + + db.delete(db_set) + db.commit() + + return success_response(data={"message": "社区集合已删除"}) \ No newline at end of file diff --git a/app/api/endpoints/community_set_mapping.py b/app/api/endpoints/community_set_mapping.py new file mode 100644 index 0000000..f8172a0 --- /dev/null +++ b/app/api/endpoints/community_set_mapping.py @@ -0,0 +1,163 @@ +from fastapi import APIRouter, Depends, HTTPException, Query, Path +from sqlalchemy.orm import Session +from typing import List, Optional +from pydantic import BaseModel, Field +from app.models.database import get_db +from app.models.community_set_mapping import CommunitySetMapping +from app.models.community_set import CommunitySet +from app.models.community import CommunityDB +from app.api.deps import get_current_user, get_admin_user +from app.models.user import UserDB +from datetime import datetime +from app.core.response import success_response, error_response + +router = APIRouter() + +# 请求和响应模型 +class CommunitySetMappingCreate(BaseModel): + set_id: int = Field(..., ge=1, description="社区集合ID") + community_id: int = Field(..., ge=1, description="社区ID") + +class CommunitySetMappingResponse(BaseModel): + id: int + set_id: int + community_id: int + create_time: datetime + update_time: datetime + + # 包含社区集合名称和社区名称 + set_name: Optional[str] = None + community_name: Optional[str] = None + address: Optional[str] = None + class Config: + from_attributes = True + +# 创建社区集合映射 +@router.post("/", response_model=CommunitySetMappingResponse) +async def create_community_set_mapping( + mapping: CommunitySetMappingCreate, + db: Session = Depends(get_db), + current_user: UserDB = Depends(get_admin_user) +): + """创建社区集合映射""" + # 检查社区集合是否存在 + community_set = db.query(CommunitySet).filter(CommunitySet.id == mapping.set_id).first() + if not community_set: + return error_response(code=404, message="社区集合不存在") + + # 检查社区是否存在 + community = db.query(CommunityDB).filter(CommunityDB.id == mapping.community_id).first() + if not community: + return error_response(code=404, message="社区不存在") + + # 检查映射是否已存在 + existing_mapping = db.query(CommunitySetMapping).filter( + CommunitySetMapping.set_id == mapping.set_id, + CommunitySetMapping.community_id == mapping.community_id + ).first() + + if existing_mapping: + return error_response(code=400, message="该映射关系已存在") + + # 创建新映射 + new_mapping = CommunitySetMapping( + set_id=mapping.set_id, + community_id=mapping.community_id + ) + + db.add(new_mapping) + db.commit() + db.refresh(new_mapping) + + # 添加社区集合名称和社区名称 + result = CommunitySetMappingResponse.model_validate(new_mapping) + result.set_name = community_set.set_name + result.community_name = community.name + + return success_response(data=result) + +# 获取社区集合的所有社区 +@router.get("/set/{set_id}/communities", response_model=List[CommunitySetMappingResponse]) +async def get_communities_by_set( + set_id: int = Path(..., ge=1), + db: Session = Depends(get_db), + current_user: UserDB = Depends(get_current_user), + skip: int = Query(0, ge=0), + limit: int = Query(100, ge=1, le=100) +): + """获取社区集合的所有社区""" + # 检查社区集合是否存在 + community_set = db.query(CommunitySet).filter(CommunitySet.id == set_id).first() + if not community_set: + return error_response(code=404, message="社区集合不存在") + + # 获取映射 + mappings = db.query(CommunitySetMapping).filter( + CommunitySetMapping.set_id == set_id + ).offset(skip).limit(limit).all() + + # 添加社区集合名称和社区名称 + results = [] + for mapping in mappings: + community = db.query(CommunityDB).filter(CommunityDB.id == mapping.community_id).first() + result = CommunitySetMappingResponse.model_validate(mapping) + result.set_name = community_set.set_name + result.community_name = community.name if community else None + result.address = community.address if community else None + + results.append(result) + + total = db.query(CommunitySetMapping).filter( + CommunitySetMapping.set_id == set_id + ).count() + + return success_response(data={"total": total, "items": results}) + +# 获取社区所属的所有集合 +@router.get("/community/{community_id}/sets", response_model=List[CommunitySetMappingResponse]) +async def get_sets_by_community( + community_id: int = Path(..., ge=1), + db: Session = Depends(get_db), + current_user: UserDB = Depends(get_current_user), + skip: int = Query(0, ge=0), + limit: int = Query(100, ge=1, le=100) +): + """获取社区所属的所有集合""" + # 检查社区是否存在 + community = db.query(CommunityDB).filter(CommunityDB.id == community_id).first() + if not community: + return error_response(code=404, message="社区不存在") + + # 获取映射 + mappings = db.query(CommunitySetMapping).filter( + CommunitySetMapping.community_id == community_id + ).offset(skip).limit(limit).all() + + # 添加社区集合名称和社区名称 + results = [] + for mapping in mappings: + community_set = db.query(CommunitySet).filter(CommunitySet.id == mapping.set_id).first() + result = CommunitySetMappingResponse.model_validate(mapping) + result.set_name = community_set.set_name if community_set else None + result.community_name = community.name + results.append(result) + + return success_response(data=results) + +# 删除社区集合映射 +@router.delete("/{mapping_id}", response_model=dict) +async def delete_community_set_mapping( + mapping_id: int = Path(..., ge=1), + db: Session = Depends(get_db), + current_user: UserDB = Depends(get_admin_user) +): + """删除社区集合映射""" + mapping = db.query(CommunitySetMapping).filter(CommunitySetMapping.id == mapping_id).first() + + if not mapping: + return error_response(code=404, message="映射关系不存在") + + db.delete(mapping) + db.commit() + + return success_response(data={"message": "映射关系已删除"}) \ No newline at end of file diff --git a/app/api/endpoints/user.py b/app/api/endpoints/user.py index 9325684..d216e16 100644 --- a/app/api/endpoints/user.py +++ b/app/api/endpoints/user.py @@ -527,3 +527,23 @@ async def get_user_auth( auth_info.id_number = masked_id_number return success_response(data=auth_info) + +#通过手机号搜索用户 +@router.get("/search_by_phone/{phone}", response_model=ResponseModel) +async def search_user_by_phone( + phone: str, + role: Optional[str] = None, + db: Session = Depends(get_db) +): + """通过手机号搜索用户""" + user = db.query(UserDB).filter(UserDB.phone == phone).first() + if not user: + return error_response(code=404, message="用户不存在") + + if role: + user.roles = list(set(user.roles)) # 去重 + if role not in user.roles: + return error_response(code=404, message="该用户没有运营商权限") + + return success_response(data=UserInfo.model_validate(user)) + diff --git a/app/main.py b/app/main.py index 619481f..e7adaec 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 wechat,user, address, community, station, order, coupon, community_building, upload, merchant, merchant_product, merchant_order, point, config, merchant_category, log, account,merchant_pay_order, message, bank_card, withdraw, mp, point_product, point_product_order, coupon_activity, dashboard, wecom, feedback, timeperiod, community_timeperiod, order_additional_fee, ai +from app.api.endpoints import wechat,user, address, community, station, order, coupon, community_building, upload, merchant, merchant_product, merchant_order, point, config, merchant_category, log, account,merchant_pay_order, message, bank_card, withdraw, mp, point_product, point_product_order, coupon_activity, dashboard, wecom, feedback, timeperiod, community_timeperiod, order_additional_fee, ai, community_set, community_set_mapping from app.models.database import Base, engine from fastapi.exceptions import RequestValidationError from fastapi.responses import JSONResponse @@ -59,6 +59,8 @@ app.include_router(account.router, prefix="/api/account", 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(community_set.router, prefix="/api/community-sets", tags=["社区集合"]) +app.include_router(community_set_mapping.router, prefix="/api/community-set-mappings", tags=["社区集合映射"]) app.include_router(timeperiod.router, prefix="/api/time-periods", tags=["配送时段"]) app.include_router(community_timeperiod.router, prefix="/api/community-time-periods", tags=["社区配送时段"]) app.include_router(station.router, prefix="/api/station", tags=["驿站"]) diff --git a/app/models/community.py b/app/models/community.py index 6ebdc1f..ead8269 100644 --- a/app/models/community.py +++ b/app/models/community.py @@ -4,7 +4,9 @@ from sqlalchemy import Column, Integer, String, DECIMAL, DateTime, Enum from sqlalchemy.sql import func from pydantic import BaseModel, Field from .database import Base +from sqlalchemy.orm import relationship from app.core.imageprocessor import process_image, ImageFormat + class CommunityStatus(str, enum.Enum): UNOPEN = "UNOPEN" # 未运营 OPENING = "OPENING" # 已运营 diff --git a/app/models/community_set.py b/app/models/community_set.py new file mode 100644 index 0000000..7f1f225 --- /dev/null +++ b/app/models/community_set.py @@ -0,0 +1,14 @@ +from sqlalchemy import Column, Integer, String, ForeignKey, DateTime +from sqlalchemy.orm import relationship +from app.models.database import Base +import datetime + +class CommunitySet(Base): + """社区集合模型""" + __tablename__ = "community_sets" + + id = Column(Integer, primary_key=True, index=True, autoincrement=True) + set_name = Column(String(100), nullable=False, comment="集合名称") + user_id = Column(Integer, ForeignKey("users.userid"), nullable=False, comment="创建用户ID") + create_time = Column(DateTime, default=datetime.datetime.now, comment="创建时间") + update_time = Column(DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now, comment="更新时间") \ No newline at end of file diff --git a/app/models/community_set_mapping.py b/app/models/community_set_mapping.py new file mode 100644 index 0000000..3c9c73f --- /dev/null +++ b/app/models/community_set_mapping.py @@ -0,0 +1,14 @@ +from sqlalchemy import Column, Integer, String, ForeignKey, DateTime +from sqlalchemy.orm import relationship +from app.models.database import Base +import datetime + +class CommunitySetMapping(Base): + """社区集合映射模型,用于保存社区集合和社区的一对多关系""" + __tablename__ = "community_set_mappings" + + id = Column(Integer, primary_key=True, index=True, autoincrement=True) + set_id = Column(Integer, ForeignKey("community_sets.id"), nullable=False, comment="社区集合ID") + community_id = Column(Integer, ForeignKey("communities.id"), nullable=False, comment="社区ID") + create_time = Column(DateTime, default=datetime.datetime.now, comment="创建时间") + update_time = Column(DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now, comment="更新时间") diff --git a/app/models/user.py b/app/models/user.py index 31c263b..15d7ed2 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -9,6 +9,8 @@ import enum import random import string from app.core.imageprocessor import process_image, ImageFormat +from sqlalchemy.orm import relationship + class UserRole(str, enum.Enum): USER = "user" DELIVERYMAN = "deliveryman"