commit
2851c32b7c
@ -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()
|
||||
|
||||
@ -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()
|
||||
|
||||
|
||||
@ -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="页码"),
|
||||
|
||||
@ -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")
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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
74
requirements.txt
Normal 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
|
||||
Loading…
x
Reference in New Issue
Block a user