This commit is contained in:
mizhexiaoxiao 2024-06-06 15:19:18 +08:00
parent 0ee84fad87
commit 279ca78340
8 changed files with 113 additions and 53 deletions

View File

@ -1,11 +1,13 @@
from contextlib import asynccontextmanager
from fastapi import FastAPI
from tortoise import Tortoise
from app.core.exceptions import SettingNotFound
from app.core.init_app import (
init_menus,
init_superuser,
make_middlewares,
register_db,
register_exceptions,
register_routers,
)
@ -16,6 +18,16 @@ except ImportError:
raise SettingNotFound("Can not import settings")
@asynccontextmanager
async def lifespan(app: FastAPI):
await Tortoise.init(config=settings.TORTOISE_ORM)
await Tortoise.generate_schemas()
await init_superuser()
await init_menus()
yield
await Tortoise.close_connections()
def create_app() -> FastAPI:
app = FastAPI(
title=settings.APP_TITLE,
@ -23,17 +35,11 @@ def create_app() -> FastAPI:
version=settings.VERSION,
openapi_url="/openapi.json",
middleware=make_middlewares(),
lifespan=lifespan,
)
register_db(app)
register_exceptions(app)
register_routers(app, prefix="/api")
return app
app = create_app()
@app.on_event("startup")
async def startup_event():
await init_superuser()
await init_menus()

View File

@ -4,10 +4,10 @@ from app.core.dependency import DependPermisson
from .apis import apis_router
from .base import base_router
from .depts import depts_router
from .menus import menus_router
from .roles import roles_router
from .users import users_router
from .depts import depts_router
v1_router = APIRouter()

View File

@ -10,6 +10,7 @@ from app.schemas.apis import *
router = APIRouter()
@router.get("/list", summary="查看API列表")
async def list_api(
page: int = Query(1, description="页码"),

View File

@ -1,8 +1,7 @@
from fastapi import APIRouter, Query
from app.controllers.dept import dept_controller
from app.log import logger
from app.schemas import Success, SuccessExtra
from app.schemas import Success
from app.schemas.depts import *
router = APIRouter()
@ -46,4 +45,4 @@ async def delete_dept(
dept_id: int = Query(..., description="部门ID"),
):
await dept_controller.delete_dept(dept_id=dept_id)
return Success(msg="Deleted Success")
return Success(msg="Deleted Success")

View File

@ -4,10 +4,10 @@ from fastapi import APIRouter, Query
from fastapi.exceptions import HTTPException
from tortoise.expressions import Q
from app.controllers.dept import dept_controller
from app.controllers.user import UserController
from app.schemas.base import Success, SuccessExtra
from app.schemas.users import *
from app.controllers.dept import dept_controller
logger = logging.getLogger(__name__)
@ -20,7 +20,7 @@ async def list_user(
page_size: int = Query(10, description="每页数量"),
username: str = Query("", description="用户名称,用于搜索"),
email: str = Query("", description="邮箱地址"),
dept_id: int = Query(None, description="部门ID")
dept_id: int = Query(None, description="部门ID"),
):
user_controller = UserController()
q = Q()

View File

@ -1,8 +1,9 @@
from tortoise.expressions import Q
from tortoise.transactions import atomic
from app.core.crud import CRUDBase
from app.models.admin import Dept, DeptClosure
from app.schemas.depts import DeptCreate, DeptUpdate
from tortoise.transactions import atomic
from tortoise.expressions import Q
class DeptController(CRUDBase[Dept, DeptCreate, DeptUpdate]):
@ -15,19 +16,21 @@ class DeptController(CRUDBase[Dept, DeptCreate, DeptUpdate]):
q &= Q(is_deleted=False)
if name:
q &= Q(name__contains=name)
all_depts = await self.model.filter(q).order_by('order')
all_depts = await self.model.filter(q).order_by("order")
# 辅助函数,用于递归构建部门树
def build_tree(parent_id):
return [
{
'id': dept.id,
'name': dept.name,
'desc': dept.desc,
'order': dept.order,
'parent_id': dept.parent_id,
'children': build_tree(dept.id) # 递归构建子部门
"id": dept.id,
"name": dept.name,
"desc": dept.desc,
"order": dept.order,
"parent_id": dept.parent_id,
"children": build_tree(dept.id), # 递归构建子部门
}
for dept in all_depts if dept.parent_id == parent_id
for dept in all_depts
if dept.parent_id == parent_id
]
# 从顶级部门parent_id=0开始构建部门树
@ -36,7 +39,7 @@ class DeptController(CRUDBase[Dept, DeptCreate, DeptUpdate]):
async def get_dept_info(self):
pass
async def update_dept_closure(self, obj: Dept):
parent_depts = await DeptClosure.filter(descendant=obj.parent_id)
for i in parent_depts:
@ -44,21 +47,9 @@ class DeptController(CRUDBase[Dept, DeptCreate, DeptUpdate]):
dept_closure_objs: list[DeptClosure] = []
# 插入父级关系
for item in parent_depts:
dept_closure_objs.append(
DeptClosure(
ancestor=item.ancestor,
descendant=obj.id,
level=item.level + 1
)
)
dept_closure_objs.append(DeptClosure(ancestor=item.ancestor, descendant=obj.id, level=item.level + 1))
# 插入自身x
dept_closure_objs.append(
DeptClosure(
ancestor=obj.id,
descendant=obj.id,
level=0
)
)
dept_closure_objs.append(DeptClosure(ancestor=obj.id, descendant=obj.id, level=0))
# 创建关系
await DeptClosure.bulk_create(dept_closure_objs)
@ -69,7 +60,6 @@ class DeptController(CRUDBase[Dept, DeptCreate, DeptUpdate]):
await self.get(id=obj_in.parent_id)
new_obj = await self.create(obj_in=obj_in)
await self.update_dept_closure(new_obj)
@atomic()
async def update_dept(self, obj_in: DeptUpdate):
@ -87,9 +77,10 @@ class DeptController(CRUDBase[Dept, DeptCreate, DeptUpdate]):
async def delete_dept(self, dept_id: int):
# 删除部门
obj = await self.get(id=dept_id)
obj.is_deleted = True
obj.is_deleted = True
await obj.save()
# 删除关系
await DeptClosure.filter(descendant=dept_id).delete()
dept_controller = DeptController()

View File

@ -1,7 +1,6 @@
from fastapi import FastAPI
from fastapi.middleware import Middleware
from fastapi.middleware.cors import CORSMiddleware
from tortoise.contrib.fastapi import register_tortoise
from app.api import api_router
from app.controllers.user import UserCreate, user_controller
@ -38,16 +37,6 @@ def make_middlewares():
return middleware
def register_db(app: FastAPI, db_url=None):
register_tortoise(
app,
# db_url='sqlite://db.sqlite3',
# modules={'models':['app.models', "aerich.models"]},
config=settings.TORTOISE_ORM,
generate_schemas=True,
)
def register_exceptions(app: FastAPI):
app.add_exception_handler(DoesNotExist, DoesNotExistHandle)
app.add_exception_handler(HTTPException, HttpExcHandle)
@ -169,4 +158,4 @@ async def init_menus():
is_hidden=False,
component="/top-menu",
keepalive=True,
)
)

74
requirements.txt Normal file
View File

@ -0,0 +1,74 @@
aiosqlite==0.17.0
annotated-types==0.6.0
anyio==4.3.0
argon2-cffi==23.1.0
argon2-cffi-bindings==21.2.0
black==23.12.1
blinker==1.7.0
certifi==2024.2.2
cffi==1.16.0
click==8.1.7
dep-logic==0.2.0
distlib==0.3.8
dnspython==2.6.1
email_validator==2.1.1
fastapi==0.111.0
fastapi-cli==0.0.4
filelock==3.13.4
findpython==0.6.0
gunicorn==21.2.0
h11==0.14.0
hishel==0.0.26
httpcore==1.0.5
httptools==0.6.1
httpx==0.27.0
idna==3.7
installer==0.7.0
iso8601==1.1.0
isort==5.13.2
Jinja2==3.1.4
loguru==0.7.2
markdown-it-py==3.0.0
MarkupSafe==2.1.5
mdurl==0.1.2
msgpack==1.0.8
mypy-extensions==1.0.0
orjson==3.10.3
packaging==24.0
passlib==1.7.4
pathspec==0.12.1
pbs-installer==2024.4.1
pdm==2.14.0
platformdirs==4.2.2
pycparser==2.22
pydantic==2.7.1
pydantic-settings==2.2.1
pydantic_core==2.18.2
Pygments==2.18.0
PyJWT==2.8.0
pypika-tortoise==0.1.6
pyproject_hooks==1.0.0
python-dotenv==1.0.1
python-multipart==0.0.9
pytz==2024.1
PyYAML==6.0.1
resolvelib==1.0.1
rich==13.7.1
ruff==0.0.281
shellingham==1.5.4
sniffio==1.3.1
socksio==1.0.0
starlette==0.37.2
tomlkit==0.12.4
tortoise-orm==0.20.1
truststore==0.8.0
typer==0.12.3
typing_extensions==4.11.0
ujson==5.10.0
unearth==0.15.1
uvicorn==0.23.2
uvloop==0.19.0
virtualenv==20.25.1
watchfiles==0.21.0
websockets==12.0
zstandard==0.22.0