Build lightweight AI agent admin
This commit is contained in:
@@ -0,0 +1,241 @@
|
||||
from typing import List
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.database import get_db
|
||||
from app.base_schema import ResponseModel
|
||||
from core.region.service import RegionService
|
||||
from core.region.model import Province, City, Area, Street, Village
|
||||
from core.region.schema import (
|
||||
ProvinceResponse, CityResponse, AreaResponse,
|
||||
StreetResponse, VillageResponse
|
||||
)
|
||||
|
||||
router = APIRouter(prefix="/regions", tags=["行政区划管理"])
|
||||
|
||||
|
||||
@router.get("/tree", summary="获取行政区划树形数据")
|
||||
async def get_region_tree(
|
||||
level: int = Query(default=3, ge=1, le=5, description="级联层级:1=省,2=省市,3=省市区,4=省市区街道,5=省市区街道村"),
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
获取行政区划树形结构数据,用于级联选择器
|
||||
|
||||
- level: 1=仅省份,2=省市两级,3=省市区三级,4=省市区街道四级,5=省市区街道村五级
|
||||
"""
|
||||
tree_data = await RegionService.get_tree(db, level=level)
|
||||
return tree_data
|
||||
|
||||
|
||||
@router.get("/provinces", response_model=List[ProvinceResponse], summary="获取省份列表")
|
||||
async def get_provinces(db: AsyncSession = Depends(get_db)):
|
||||
"""获取所有省份列表"""
|
||||
provinces = await RegionService.get_provinces(db)
|
||||
return provinces
|
||||
|
||||
|
||||
@router.post("/provinces", response_model=ProvinceResponse, summary="创建省份")
|
||||
async def create_province(data: dict, db: AsyncSession = Depends(get_db)):
|
||||
"""创建省份"""
|
||||
province = await RegionService.create_province(db, data)
|
||||
return province
|
||||
|
||||
|
||||
@router.put("/provinces/{province_id}", response_model=ProvinceResponse, summary="更新省份")
|
||||
async def update_province(province_id: str, data: dict, db: AsyncSession = Depends(get_db)):
|
||||
"""更新省份"""
|
||||
province = await RegionService.update_province(db, province_id, data)
|
||||
if not province:
|
||||
from fastapi import HTTPException
|
||||
raise HTTPException(status_code=404, detail="省份不存在")
|
||||
return province
|
||||
|
||||
|
||||
@router.delete("/provinces/{province_id}", response_model=ResponseModel, summary="删除省份")
|
||||
async def delete_province(province_id: str, db: AsyncSession = Depends(get_db)):
|
||||
"""删除省份"""
|
||||
success = await RegionService.delete_province(db, province_id)
|
||||
if not success:
|
||||
from fastapi import HTTPException
|
||||
raise HTTPException(status_code=404, detail="省份不存在")
|
||||
return ResponseModel(message="删除成功")
|
||||
|
||||
|
||||
@router.get("/cities", response_model=List[CityResponse], summary="获取城市列表")
|
||||
async def get_cities(
|
||||
province_code: str = Query(None, description="省份代码"),
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""根据省份代码获取城市列表"""
|
||||
if province_code:
|
||||
cities = await RegionService.get_cities_by_province(db, province_code)
|
||||
else:
|
||||
stmt = select(City).order_by(City.sort, City.code)
|
||||
result = await db.execute(stmt)
|
||||
cities = result.scalars().all()
|
||||
return cities
|
||||
|
||||
|
||||
@router.post("/cities", response_model=CityResponse, summary="创建城市")
|
||||
async def create_city(data: dict, db: AsyncSession = Depends(get_db)):
|
||||
"""创建城市"""
|
||||
city = await RegionService.create_city(db, data)
|
||||
return city
|
||||
|
||||
|
||||
@router.put("/cities/{city_id}", response_model=CityResponse, summary="更新城市")
|
||||
async def update_city(city_id: str, data: dict, db: AsyncSession = Depends(get_db)):
|
||||
"""更新城市"""
|
||||
city = await RegionService.update_city(db, city_id, data)
|
||||
if not city:
|
||||
from fastapi import HTTPException
|
||||
raise HTTPException(status_code=404, detail="城市不存在")
|
||||
return city
|
||||
|
||||
|
||||
@router.delete("/cities/{city_id}", response_model=ResponseModel, summary="删除城市")
|
||||
async def delete_city(city_id: str, db: AsyncSession = Depends(get_db)):
|
||||
"""删除城市"""
|
||||
success = await RegionService.delete_city(db, city_id)
|
||||
if not success:
|
||||
from fastapi import HTTPException
|
||||
raise HTTPException(status_code=404, detail="城市不存在")
|
||||
return ResponseModel(message="删除成功")
|
||||
|
||||
|
||||
@router.get("/areas", response_model=List[AreaResponse], summary="获取区县列表")
|
||||
async def get_areas(
|
||||
city_code: str = Query(None, description="城市代码"),
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""根据城市代码获取区县列表"""
|
||||
if city_code:
|
||||
areas = await RegionService.get_areas_by_city(db, city_code)
|
||||
else:
|
||||
stmt = select(Area).order_by(Area.sort, Area.code)
|
||||
result = await db.execute(stmt)
|
||||
areas = result.scalars().all()
|
||||
return areas
|
||||
|
||||
|
||||
@router.post("/areas", response_model=AreaResponse, summary="创建区县")
|
||||
async def create_area(data: dict, db: AsyncSession = Depends(get_db)):
|
||||
"""创建区县"""
|
||||
area = await RegionService.create_area(db, data)
|
||||
return area
|
||||
|
||||
|
||||
@router.put("/areas/{area_id}", response_model=AreaResponse, summary="更新区县")
|
||||
async def update_area(area_id: str, data: dict, db: AsyncSession = Depends(get_db)):
|
||||
"""更新区县"""
|
||||
area = await RegionService.update_area(db, area_id, data)
|
||||
if not area:
|
||||
from fastapi import HTTPException
|
||||
raise HTTPException(status_code=404, detail="区县不存在")
|
||||
return area
|
||||
|
||||
|
||||
@router.delete("/areas/{area_id}", response_model=ResponseModel, summary="删除区县")
|
||||
async def delete_area(area_id: str, db: AsyncSession = Depends(get_db)):
|
||||
"""删除区县"""
|
||||
success = await RegionService.delete_area(db, area_id)
|
||||
if not success:
|
||||
from fastapi import HTTPException
|
||||
raise HTTPException(status_code=404, detail="区县不存在")
|
||||
return ResponseModel(message="删除成功")
|
||||
|
||||
|
||||
@router.get("/streets", response_model=List[StreetResponse], summary="获取街道列表")
|
||||
async def get_streets(
|
||||
area_code: str = Query(None, description="区县代码"),
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""根据区县代码获取街道列表"""
|
||||
if area_code:
|
||||
streets = await RegionService.get_streets_by_area(db, area_code)
|
||||
else:
|
||||
stmt = select(Street).order_by(Street.sort, Street.code).limit(1000)
|
||||
result = await db.execute(stmt)
|
||||
streets = result.scalars().all()
|
||||
return streets
|
||||
|
||||
|
||||
@router.post("/streets", response_model=StreetResponse, summary="创建街道")
|
||||
async def create_street(data: dict, db: AsyncSession = Depends(get_db)):
|
||||
"""创建街道"""
|
||||
street = await RegionService.create_street(db, data)
|
||||
return street
|
||||
|
||||
|
||||
@router.put("/streets/{street_id}", response_model=StreetResponse, summary="更新街道")
|
||||
async def update_street(street_id: str, data: dict, db: AsyncSession = Depends(get_db)):
|
||||
"""更新街道"""
|
||||
street = await RegionService.update_street(db, street_id, data)
|
||||
if not street:
|
||||
from fastapi import HTTPException
|
||||
raise HTTPException(status_code=404, detail="街道不存在")
|
||||
return street
|
||||
|
||||
|
||||
@router.delete("/streets/{street_id}", response_model=ResponseModel, summary="删除街道")
|
||||
async def delete_street(street_id: str, db: AsyncSession = Depends(get_db)):
|
||||
"""删除街道"""
|
||||
success = await RegionService.delete_street(db, street_id)
|
||||
if not success:
|
||||
from fastapi import HTTPException
|
||||
raise HTTPException(status_code=404, detail="街道不存在")
|
||||
return ResponseModel(message="删除成功")
|
||||
|
||||
|
||||
@router.get("/villages", response_model=List[VillageResponse], summary="获取村庄列表")
|
||||
async def get_villages(
|
||||
street_code: str = Query(None, description="街道代码"),
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""根据街道代码获取村庄列表"""
|
||||
if street_code:
|
||||
villages = await RegionService.get_villages_by_street(db, street_code)
|
||||
else:
|
||||
stmt = select(Village).order_by(Village.sort, Village.code).limit(1000)
|
||||
result = await db.execute(stmt)
|
||||
villages = result.scalars().all()
|
||||
return villages
|
||||
|
||||
|
||||
@router.post("/villages", response_model=VillageResponse, summary="创建村庄")
|
||||
async def create_village(data: dict, db: AsyncSession = Depends(get_db)):
|
||||
"""创建村庄"""
|
||||
village = await RegionService.create_village(db, data)
|
||||
return village
|
||||
|
||||
|
||||
@router.put("/villages/{village_id}", response_model=VillageResponse, summary="更新村庄")
|
||||
async def update_village(village_id: str, data: dict, db: AsyncSession = Depends(get_db)):
|
||||
"""更新村庄"""
|
||||
village = await RegionService.update_village(db, village_id, data)
|
||||
if not village:
|
||||
from fastapi import HTTPException
|
||||
raise HTTPException(status_code=404, detail="村庄不存在")
|
||||
return village
|
||||
|
||||
|
||||
@router.delete("/villages/{village_id}", response_model=ResponseModel, summary="删除村庄")
|
||||
async def delete_village(village_id: str, db: AsyncSession = Depends(get_db)):
|
||||
"""删除村庄"""
|
||||
success = await RegionService.delete_village(db, village_id)
|
||||
if not success:
|
||||
from fastapi import HTTPException
|
||||
raise HTTPException(status_code=404, detail="村庄不存在")
|
||||
return ResponseModel(message="删除成功")
|
||||
|
||||
|
||||
@router.get("/name/{code}", response_model=ResponseModel, summary="根据代码获取名称")
|
||||
async def get_region_name(
|
||||
code: str,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""根据区域代码获取区域名称"""
|
||||
name = await RegionService.get_region_name(db, code)
|
||||
return ResponseModel(data={"name": name})
|
||||
@@ -0,0 +1,77 @@
|
||||
from sqlalchemy import Column, String, Integer, ForeignKey
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
from app.base_model import BaseModel
|
||||
|
||||
|
||||
class Province(BaseModel):
|
||||
"""省份模型"""
|
||||
__tablename__ = "core_province"
|
||||
|
||||
code = Column(String(20), unique=True, nullable=False, index=True, comment="省份代码")
|
||||
name = Column(String(100), nullable=False, comment="省份名称")
|
||||
sort = Column(Integer, default=0, comment="排序")
|
||||
|
||||
# 关联关系
|
||||
cities = relationship("City", back_populates="province", cascade="all, delete-orphan")
|
||||
|
||||
|
||||
class City(BaseModel):
|
||||
"""城市模型"""
|
||||
__tablename__ = "core_city"
|
||||
|
||||
code = Column(String(20), unique=True, nullable=False, index=True, comment="城市代码")
|
||||
name = Column(String(100), nullable=False, comment="城市名称")
|
||||
province_code = Column(String(20), ForeignKey("core_province.code", ondelete="CASCADE"), nullable=False, comment="省份代码")
|
||||
sort = Column(Integer, default=0, comment="排序")
|
||||
|
||||
# 关联关系
|
||||
province = relationship("Province", back_populates="cities")
|
||||
areas = relationship("Area", back_populates="city", cascade="all, delete-orphan")
|
||||
|
||||
|
||||
class Area(BaseModel):
|
||||
"""区县模型"""
|
||||
__tablename__ = "core_area"
|
||||
|
||||
code = Column(String(20), unique=True, nullable=False, index=True, comment="区县代码")
|
||||
name = Column(String(100), nullable=False, comment="区县名称")
|
||||
province_code = Column(String(20), nullable=False, index=True, comment="省份代码")
|
||||
city_code = Column(String(20), ForeignKey("core_city.code", ondelete="CASCADE"), nullable=False, comment="城市代码")
|
||||
sort = Column(Integer, default=0, comment="排序")
|
||||
|
||||
# 关联关系
|
||||
city = relationship("City", back_populates="areas")
|
||||
streets = relationship("Street", back_populates="area", cascade="all, delete-orphan")
|
||||
|
||||
|
||||
class Street(BaseModel):
|
||||
"""街道/乡镇模型"""
|
||||
__tablename__ = "core_street"
|
||||
|
||||
code = Column(String(20), unique=True, nullable=False, index=True, comment="街道代码")
|
||||
name = Column(String(100), nullable=False, comment="街道名称")
|
||||
province_code = Column(String(20), nullable=False, index=True, comment="省份代码")
|
||||
city_code = Column(String(20), nullable=False, index=True, comment="城市代码")
|
||||
area_code = Column(String(20), ForeignKey("core_area.code", ondelete="CASCADE"), nullable=False, comment="区县代码")
|
||||
sort = Column(Integer, default=0, comment="排序")
|
||||
|
||||
# 关联关系
|
||||
area = relationship("Area", back_populates="streets")
|
||||
villages = relationship("Village", back_populates="street", cascade="all, delete-orphan")
|
||||
|
||||
|
||||
class Village(BaseModel):
|
||||
"""村/社区模型"""
|
||||
__tablename__ = "core_village"
|
||||
|
||||
code = Column(String(20), unique=True, nullable=False, index=True, comment="村庄代码")
|
||||
name = Column(String(100), nullable=False, comment="村庄名称")
|
||||
province_code = Column(String(20), nullable=False, index=True, comment="省份代码")
|
||||
city_code = Column(String(20), nullable=False, index=True, comment="城市代码")
|
||||
area_code = Column(String(20), nullable=False, index=True, comment="区县代码")
|
||||
street_code = Column(String(20), ForeignKey("core_street.code", ondelete="CASCADE"), nullable=False, comment="街道代码")
|
||||
sort = Column(Integer, default=0, comment="排序")
|
||||
|
||||
# 关联关系
|
||||
street = relationship("Street", back_populates="villages")
|
||||
@@ -0,0 +1,67 @@
|
||||
from typing import Optional, List
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
|
||||
|
||||
class RegionBase(BaseModel):
|
||||
"""区域基础 Schema"""
|
||||
code: str
|
||||
name: str
|
||||
|
||||
|
||||
class ProvinceResponse(RegionBase):
|
||||
"""省份响应 Schema"""
|
||||
id: str
|
||||
sort: int = 0
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class CityResponse(RegionBase):
|
||||
"""城市响应 Schema"""
|
||||
id: str
|
||||
province_code: str
|
||||
sort: int = 0
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class AreaResponse(RegionBase):
|
||||
"""区县响应 Schema"""
|
||||
id: str
|
||||
province_code: str
|
||||
city_code: str
|
||||
sort: int = 0
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class StreetResponse(RegionBase):
|
||||
"""街道响应 Schema"""
|
||||
id: str
|
||||
province_code: str
|
||||
city_code: str
|
||||
area_code: str
|
||||
sort: int = 0
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class VillageResponse(RegionBase):
|
||||
"""村庄响应 Schema"""
|
||||
id: str
|
||||
province_code: str
|
||||
city_code: str
|
||||
area_code: str
|
||||
street_code: str
|
||||
sort: int = 0
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class RegionTreeNode(BaseModel):
|
||||
"""区域树节点 Schema(用于级联选择器)"""
|
||||
code: str
|
||||
name: str
|
||||
children: Optional[List['RegionTreeNode']] = None
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
@@ -0,0 +1,376 @@
|
||||
from typing import List, Dict, Any, Optional
|
||||
from sqlalchemy import select, func
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import selectinload
|
||||
|
||||
from core.region.model import Province, City, Area, Street, Village
|
||||
from core.region.schema import RegionTreeNode
|
||||
|
||||
|
||||
class RegionService:
|
||||
"""省市区街道村五级行政区划服务类"""
|
||||
|
||||
# ========== 省份 CRUD ==========
|
||||
@classmethod
|
||||
async def create_province(cls, db: AsyncSession, data: Dict[str, Any]) -> Province:
|
||||
"""创建省份"""
|
||||
province = Province(**data)
|
||||
db.add(province)
|
||||
await db.commit()
|
||||
await db.refresh(province)
|
||||
return province
|
||||
|
||||
@classmethod
|
||||
async def update_province(cls, db: AsyncSession, province_id: str, data: Dict[str, Any]) -> Optional[Province]:
|
||||
"""更新省份"""
|
||||
stmt = select(Province).where(Province.id == province_id)
|
||||
result = await db.execute(stmt)
|
||||
province = result.scalar_one_or_none()
|
||||
if province:
|
||||
for key, value in data.items():
|
||||
setattr(province, key, value)
|
||||
await db.commit()
|
||||
await db.refresh(province)
|
||||
return province
|
||||
|
||||
@classmethod
|
||||
async def delete_province(cls, db: AsyncSession, province_id: str) -> bool:
|
||||
"""删除省份"""
|
||||
stmt = select(Province).where(Province.id == province_id)
|
||||
result = await db.execute(stmt)
|
||||
province = result.scalar_one_or_none()
|
||||
if province:
|
||||
await db.delete(province)
|
||||
await db.commit()
|
||||
return True
|
||||
return False
|
||||
|
||||
# ========== 城市 CRUD ==========
|
||||
@classmethod
|
||||
async def create_city(cls, db: AsyncSession, data: Dict[str, Any]) -> City:
|
||||
"""创建城市"""
|
||||
city = City(**data)
|
||||
db.add(city)
|
||||
await db.commit()
|
||||
await db.refresh(city)
|
||||
return city
|
||||
|
||||
@classmethod
|
||||
async def update_city(cls, db: AsyncSession, city_id: str, data: Dict[str, Any]) -> Optional[City]:
|
||||
"""更新城市"""
|
||||
stmt = select(City).where(City.id == city_id)
|
||||
result = await db.execute(stmt)
|
||||
city = result.scalar_one_or_none()
|
||||
if city:
|
||||
for key, value in data.items():
|
||||
setattr(city, key, value)
|
||||
await db.commit()
|
||||
await db.refresh(city)
|
||||
return city
|
||||
|
||||
@classmethod
|
||||
async def delete_city(cls, db: AsyncSession, city_id: str) -> bool:
|
||||
"""删除城市"""
|
||||
stmt = select(City).where(City.id == city_id)
|
||||
result = await db.execute(stmt)
|
||||
city = result.scalar_one_or_none()
|
||||
if city:
|
||||
await db.delete(city)
|
||||
await db.commit()
|
||||
return True
|
||||
return False
|
||||
|
||||
# ========== 区县 CRUD ==========
|
||||
@classmethod
|
||||
async def create_area(cls, db: AsyncSession, data: Dict[str, Any]) -> Area:
|
||||
"""创建区县"""
|
||||
area = Area(**data)
|
||||
db.add(area)
|
||||
await db.commit()
|
||||
await db.refresh(area)
|
||||
return area
|
||||
|
||||
@classmethod
|
||||
async def update_area(cls, db: AsyncSession, area_id: str, data: Dict[str, Any]) -> Optional[Area]:
|
||||
"""更新区县"""
|
||||
stmt = select(Area).where(Area.id == area_id)
|
||||
result = await db.execute(stmt)
|
||||
area = result.scalar_one_or_none()
|
||||
if area:
|
||||
for key, value in data.items():
|
||||
setattr(area, key, value)
|
||||
await db.commit()
|
||||
await db.refresh(area)
|
||||
return area
|
||||
|
||||
@classmethod
|
||||
async def delete_area(cls, db: AsyncSession, area_id: str) -> bool:
|
||||
"""删除区县"""
|
||||
stmt = select(Area).where(Area.id == area_id)
|
||||
result = await db.execute(stmt)
|
||||
area = result.scalar_one_or_none()
|
||||
if area:
|
||||
await db.delete(area)
|
||||
await db.commit()
|
||||
return True
|
||||
return False
|
||||
|
||||
# ========== 街道 CRUD ==========
|
||||
@classmethod
|
||||
async def create_street(cls, db: AsyncSession, data: Dict[str, Any]) -> Street:
|
||||
"""创建街道"""
|
||||
street = Street(**data)
|
||||
db.add(street)
|
||||
await db.commit()
|
||||
await db.refresh(street)
|
||||
return street
|
||||
|
||||
@classmethod
|
||||
async def update_street(cls, db: AsyncSession, street_id: str, data: Dict[str, Any]) -> Optional[Street]:
|
||||
"""更新街道"""
|
||||
stmt = select(Street).where(Street.id == street_id)
|
||||
result = await db.execute(stmt)
|
||||
street = result.scalar_one_or_none()
|
||||
if street:
|
||||
for key, value in data.items():
|
||||
setattr(street, key, value)
|
||||
await db.commit()
|
||||
await db.refresh(street)
|
||||
return street
|
||||
|
||||
@classmethod
|
||||
async def delete_street(cls, db: AsyncSession, street_id: str) -> bool:
|
||||
"""删除街道"""
|
||||
stmt = select(Street).where(Street.id == street_id)
|
||||
result = await db.execute(stmt)
|
||||
street = result.scalar_one_or_none()
|
||||
if street:
|
||||
await db.delete(street)
|
||||
await db.commit()
|
||||
return True
|
||||
return False
|
||||
|
||||
# ========== 村庄 CRUD ==========
|
||||
@classmethod
|
||||
async def create_village(cls, db: AsyncSession, data: Dict[str, Any]) -> Village:
|
||||
"""创建村庄"""
|
||||
village = Village(**data)
|
||||
db.add(village)
|
||||
await db.commit()
|
||||
await db.refresh(village)
|
||||
return village
|
||||
|
||||
@classmethod
|
||||
async def update_village(cls, db: AsyncSession, village_id: str, data: Dict[str, Any]) -> Optional[Village]:
|
||||
"""更新村庄"""
|
||||
stmt = select(Village).where(Village.id == village_id)
|
||||
result = await db.execute(stmt)
|
||||
village = result.scalar_one_or_none()
|
||||
if village:
|
||||
for key, value in data.items():
|
||||
setattr(village, key, value)
|
||||
await db.commit()
|
||||
await db.refresh(village)
|
||||
return village
|
||||
|
||||
@classmethod
|
||||
async def delete_village(cls, db: AsyncSession, village_id: str) -> bool:
|
||||
"""删除村庄"""
|
||||
stmt = select(Village).where(Village.id == village_id)
|
||||
result = await db.execute(stmt)
|
||||
village = result.scalar_one_or_none()
|
||||
if village:
|
||||
await db.delete(village)
|
||||
await db.commit()
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def get_tree(cls, db: AsyncSession, level: int = 3) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
获取行政区划树形结构数据
|
||||
|
||||
Args:
|
||||
db: 数据库会话
|
||||
level: 级联层级 1=省 2=省市 3=省市区 4=省市区街道 5=省市区街道村
|
||||
|
||||
Returns:
|
||||
树形结构数据列表
|
||||
"""
|
||||
# 查询所有省份
|
||||
stmt = select(Province).order_by(Province.sort, Province.code)
|
||||
result = await db.execute(stmt)
|
||||
provinces = result.scalars().all()
|
||||
|
||||
tree_data = []
|
||||
for province in provinces:
|
||||
province_node = {
|
||||
"code": province.code,
|
||||
"name": province.name,
|
||||
}
|
||||
|
||||
if level >= 2:
|
||||
# 查询该省份下的所有城市
|
||||
city_stmt = select(City).where(
|
||||
City.province_code == province.code
|
||||
).order_by(City.sort, City.code)
|
||||
city_result = await db.execute(city_stmt)
|
||||
cities = city_result.scalars().all()
|
||||
|
||||
city_nodes = []
|
||||
for city in cities:
|
||||
city_node = {
|
||||
"code": city.code,
|
||||
"name": city.name,
|
||||
}
|
||||
|
||||
if level >= 3:
|
||||
# 查询该城市下的所有区县
|
||||
area_stmt = select(Area).where(
|
||||
Area.city_code == city.code
|
||||
).order_by(Area.sort, Area.code)
|
||||
area_result = await db.execute(area_stmt)
|
||||
areas = area_result.scalars().all()
|
||||
|
||||
area_nodes = []
|
||||
for area in areas:
|
||||
area_node = {
|
||||
"code": area.code,
|
||||
"name": area.name,
|
||||
}
|
||||
|
||||
if level >= 4:
|
||||
# 查询该区县下的所有街道
|
||||
street_stmt = select(Street).where(
|
||||
Street.area_code == area.code
|
||||
).order_by(Street.sort, Street.code)
|
||||
street_result = await db.execute(street_stmt)
|
||||
streets = street_result.scalars().all()
|
||||
|
||||
street_nodes = []
|
||||
for street in streets:
|
||||
street_node = {
|
||||
"code": street.code,
|
||||
"name": street.name,
|
||||
}
|
||||
|
||||
if level >= 5:
|
||||
# 查询该街道下的所有村庄
|
||||
village_stmt = select(Village).where(
|
||||
Village.street_code == street.code
|
||||
).order_by(Village.sort, Village.code)
|
||||
village_result = await db.execute(village_stmt)
|
||||
villages = village_result.scalars().all()
|
||||
|
||||
village_nodes = [
|
||||
{
|
||||
"code": village.code,
|
||||
"name": village.name,
|
||||
}
|
||||
for village in villages
|
||||
]
|
||||
|
||||
if village_nodes:
|
||||
street_node["children"] = village_nodes
|
||||
|
||||
street_nodes.append(street_node)
|
||||
|
||||
if street_nodes:
|
||||
area_node["children"] = street_nodes
|
||||
|
||||
area_nodes.append(area_node)
|
||||
|
||||
if area_nodes:
|
||||
city_node["children"] = area_nodes
|
||||
|
||||
city_nodes.append(city_node)
|
||||
|
||||
if city_nodes:
|
||||
province_node["children"] = city_nodes
|
||||
|
||||
tree_data.append(province_node)
|
||||
|
||||
return tree_data
|
||||
|
||||
@classmethod
|
||||
async def get_provinces(cls, db: AsyncSession) -> List[Province]:
|
||||
"""获取所有省份"""
|
||||
stmt = select(Province).order_by(Province.sort, Province.code)
|
||||
result = await db.execute(stmt)
|
||||
return result.scalars().all()
|
||||
|
||||
@classmethod
|
||||
async def get_cities_by_province(cls, db: AsyncSession, province_code: str) -> List[City]:
|
||||
"""根据省份代码获取城市列表"""
|
||||
stmt = select(City).where(
|
||||
City.province_code == province_code
|
||||
).order_by(City.sort, City.code)
|
||||
result = await db.execute(stmt)
|
||||
return result.scalars().all()
|
||||
|
||||
@classmethod
|
||||
async def get_areas_by_city(cls, db: AsyncSession, city_code: str) -> List[Area]:
|
||||
"""根据城市代码获取区县列表"""
|
||||
stmt = select(Area).where(
|
||||
Area.city_code == city_code
|
||||
).order_by(Area.sort, Area.code)
|
||||
result = await db.execute(stmt)
|
||||
return result.scalars().all()
|
||||
|
||||
@classmethod
|
||||
async def get_streets_by_area(cls, db: AsyncSession, area_code: str) -> List[Street]:
|
||||
"""根据区县代码获取街道列表"""
|
||||
stmt = select(Street).where(
|
||||
Street.area_code == area_code
|
||||
).order_by(Street.sort, Street.code)
|
||||
result = await db.execute(stmt)
|
||||
return result.scalars().all()
|
||||
|
||||
@classmethod
|
||||
async def get_villages_by_street(cls, db: AsyncSession, street_code: str) -> List[Village]:
|
||||
"""根据街道代码获取村庄列表"""
|
||||
stmt = select(Village).where(
|
||||
Village.street_code == street_code
|
||||
).order_by(Village.sort, Village.code)
|
||||
result = await db.execute(stmt)
|
||||
return result.scalars().all()
|
||||
|
||||
@classmethod
|
||||
async def get_region_name(cls, db: AsyncSession, code: str) -> str:
|
||||
"""根据区域代码获取名称"""
|
||||
# 尝试从省份查找
|
||||
stmt = select(Province).where(Province.code == code)
|
||||
result = await db.execute(stmt)
|
||||
province = result.scalar_one_or_none()
|
||||
if province:
|
||||
return province.name
|
||||
|
||||
# 尝试从城市查找
|
||||
stmt = select(City).where(City.code == code)
|
||||
result = await db.execute(stmt)
|
||||
city = result.scalar_one_or_none()
|
||||
if city:
|
||||
return city.name
|
||||
|
||||
# 尝试从区县查找
|
||||
stmt = select(Area).where(Area.code == code)
|
||||
result = await db.execute(stmt)
|
||||
area = result.scalar_one_or_none()
|
||||
if area:
|
||||
return area.name
|
||||
|
||||
# 尝试从街道查找
|
||||
stmt = select(Street).where(Street.code == code)
|
||||
result = await db.execute(stmt)
|
||||
street = result.scalar_one_or_none()
|
||||
if street:
|
||||
return street.name
|
||||
|
||||
# 尝试从村庄查找
|
||||
stmt = select(Village).where(Village.code == code)
|
||||
result = await db.execute(stmt)
|
||||
village = result.scalar_one_or_none()
|
||||
if village:
|
||||
return village.name
|
||||
|
||||
return ""
|
||||
Reference in New Issue
Block a user