From 9da334adaa0457d4eb411f85d207b4dc592457e2 Mon Sep 17 00:00:00 2001 From: zy7y <13271962515@163.com> Date: Sat, 11 Mar 2023 23:59:51 +0800 Subject: [PATCH] chore: update backend lib version and update Dockerfile --- backend/Dockerfile | 16 +++++++++++++--- backend/core/exceptions.py | 1 - backend/core/log.py | 9 ++++++++- backend/core/service.py | 1 - backend/core/utils.py | 9 ++++----- backend/requirements.txt | 16 ++++++++-------- backend/router/auth.py | 4 ++-- backend/router/menu.py | 16 ++++++++-------- backend/router/role.py | 32 +++++++++++++++----------------- backend/router/user.py | 36 +++++++++++++++++------------------- backend/schemas/common.py | 8 ++++---- 11 files changed, 79 insertions(+), 69 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index 63aeb9b..49c6c67 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,5 +1,15 @@ -FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9 -COPY . /app +# 第一阶段:构建镜像 +FROM python:3.9-slim-buster AS build +WORKDIR /app +COPY requirements.txt . RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \ echo 'Asia/Shanghai' >/etc/timezone && \ - pip install --no-cache-dir --upgrade -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/ \ No newline at end of file + pip install --no-cache-dir --user -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/ +COPY . . +# 第二阶段:运行镜像 +FROM python:3.9-slim-buster +WORKDIR /app +COPY --from=build /root/.local /root/.local +COPY --from=build /app . +ENV PATH=/root/.local/bin:$PATH +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"] diff --git a/backend/core/exceptions.py b/backend/core/exceptions.py index cc05e55..9e9762f 100644 --- a/backend/core/exceptions.py +++ b/backend/core/exceptions.py @@ -4,7 +4,6 @@ from starlette.responses import JSONResponse class TokenAuthFailure(HTTPException): - pass diff --git a/backend/core/log.py b/backend/core/log.py index fcc3e27..abd9b05 100644 --- a/backend/core/log.py +++ b/backend/core/log.py @@ -1 +1,8 @@ -from loguru import logger +import logging + +logger = logging.getLogger(__name__) +logger.setLevel(logging.INFO) +handler = logging.StreamHandler() +formatter = logging.Formatter("[%(asctime)s] %(levelname)s %(message)s") +handler.setFormatter(formatter) +logger.addHandler(handler) diff --git a/backend/core/service.py b/backend/core/service.py index ef02b88..e7885f6 100644 --- a/backend/core/service.py +++ b/backend/core/service.py @@ -2,7 +2,6 @@ from core.dbhelper import DbHelper class Service: - filter_del = {"status__not": 9} def __init__(self, dao: DbHelper): diff --git a/backend/core/utils.py b/backend/core/utils.py index 344b049..ce7ae74 100644 --- a/backend/core/utils.py +++ b/backend/core/utils.py @@ -20,7 +20,6 @@ def list_to_tree( menu_map = {menu["id"]: menu for menu in menus} arr = [] for menu in menus: - # 有父级 if mid := menu.get(parent_flag): # 有 子项的情况 @@ -79,7 +78,7 @@ def load_routers( kwargs = dict(router=router_obj, dependencies=depends) app.include_router(**kwargs) - logger.info("开始扫描路由。") + logger.info("♻️开始扫描路由。") if depends is None: depends = [] if is_init: @@ -99,9 +98,9 @@ def load_routers( for route in app.routes: try: - logger.debug( - f"{route.path}, {route.methods}, {route.__dict__.get('summary')}" + logger.info( + f"🦌{route.path}, {route.methods}, {route.__dict__.get('summary')}" ) except AttributeError as e: logger.error(e) - logger.info("👌路由注册完成✅。") + logger.info("®️路由注册完成✅。") diff --git a/backend/requirements.txt b/backend/requirements.txt index 6c09b2b..a61cd3a 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -1,10 +1,10 @@ -bcrypt==4.0.0 -fastapi==0.85.0 +bcrypt==4.0.1 +fastapi==0.94.0 +gunicorn==20.1.0 passlib==1.7.4 -pytest==7.1.3 +pytest==7.2.2 python-jose==3.3.0 -requests==2.28.1 -tortoise-orm==0.19.2 -uvicorn==0.18.3 -websockets==10.3 -loguru==0.6.0 +requests==2.28.2 +tortoise-orm==0.19.3 +uvicorn==0.21.0 +websockets==10.4 diff --git a/backend/router/auth.py b/backend/router/auth.py index 694e3c0..8c53b9b 100644 --- a/backend/router/auth.py +++ b/backend/router/auth.py @@ -9,8 +9,8 @@ router = APIRouter(tags=["公共"]) LoginResult = BaseSchema.Response[BaseSchema.LoginResult] -@router.post("/login", summary="登录", response_model=LoginResult) -async def login(data: BaseSchema.LoginForm): +@router.post("/login", summary="登录") +async def login(data: BaseSchema.LoginForm) -> LoginResult: return await AuthService.user_login(data) diff --git a/backend/router/menu.py b/backend/router/menu.py index e2381f3..daa9c44 100644 --- a/backend/router/menu.py +++ b/backend/router/menu.py @@ -9,22 +9,22 @@ router = APIRouter(prefix="/menu", tags=["菜单管理"]) Response = BaseSchema.Response -@router.post("", summary="菜单新增", response_model=Response[MenuSchema.MenuRead]) -async def menu_add(data: MenuSchema.MenuIn): +@router.post("", summary="菜单新增") +async def menu_add(data: MenuSchema.MenuIn) -> Response[MenuSchema.MenuRead]: return await MenuService.create_item(data) -@router.get("", summary="菜单列表", response_model=Response) -async def menu_arr(): +@router.get("", summary="菜单列表") +async def menu_arr() -> Response: return await MenuService.get_items() -@router.delete("/{pk}", summary="菜单删除", response_model=Response) -async def menu_del(pk: int): +@router.delete("/{pk}", summary="菜单删除") +async def menu_del(pk: int) -> Response: return await MenuService.delete_item(pk) -@router.put("/{pk}", summary="菜单更新", response_model=Response) -async def menu_put(pk: int, data: MenuSchema.MenuIn): +@router.put("/{pk}", summary="菜单更新") +async def menu_put(pk: int, data: MenuSchema.MenuIn) -> Response: """更新菜单""" return await MenuService.update_item(pk, data) diff --git a/backend/router/role.py b/backend/router/role.py index ff643fe..1b3f269 100644 --- a/backend/router/role.py +++ b/backend/router/role.py @@ -1,7 +1,8 @@ -from fastapi import APIRouter, Query +from fastapi import APIRouter, Depends from schemas import common as BaseSchema from schemas import role as RoleSchema +from schemas.common import QueryData from service.role import service as RoleService router = APIRouter(prefix="/role", tags=["角色管理"]) @@ -12,35 +13,32 @@ ListAll = BaseSchema.ListAll role_list_schema = ListAll[list[RoleSchema.RoleRead]] -@router.get("", summary="角色列表", response_model=Response[role_list_schema]) -async def role_list( - offset: int = Query(default=1, description="偏移量-页码"), - limit: int = Query(default=10, description="数据量"), -): - return await RoleService.get_items(offset, limit) +@router.get("", summary="角色列表") +async def role_list(query: QueryData = Depends()) -> Response[role_list_schema]: + return await RoleService.get_items(query.offset, query.limit) -@router.post("/query", summary="角色查询", response_model=Response[role_list_schema]) -async def role_query(query: RoleSchema.RoleQuery): +@router.post("/query", summary="角色查询") +async def role_query(query: RoleSchema.RoleQuery) -> Response[role_list_schema]: return await RoleService.query_items(query) -@router.post("", summary="角色新增", response_model=Response[RoleSchema.RoleInfo]) -async def role_create(data: RoleSchema.RoleIn): +@router.post("", summary="角色新增") +async def role_create(data: RoleSchema.RoleIn) -> Response[RoleSchema.RoleInfo]: return await RoleService.create_item(data) -@router.get("/{rid}/menu", summary="查询角色拥有权限", response_model=Response) -async def role_has_menu(rid: int): +@router.get("/{rid}/menu", summary="查询角色拥有权限") +async def role_has_menu(rid: int) -> Response: return await RoleService.has_tree_menus(rid) -@router.delete("/{pk}", summary="角色删除", response_model=Response) -async def role_del(pk: int): +@router.delete("/{pk}", summary="角色删除") +async def role_del(pk: int) -> Response: return await RoleService.delete_item(pk) -@router.put("/{pk}", summary="角色更新", response_model=Response) -async def role_put(pk: int, data: RoleSchema.RoleIn): +@router.put("/{pk}", summary="角色更新") +async def role_put(pk: int, data: RoleSchema.RoleIn) -> Response: """更新角色""" return await RoleService.update_item(pk, data) diff --git a/backend/router/user.py b/backend/router/user.py index 896c28d..6745858 100644 --- a/backend/router/user.py +++ b/backend/router/user.py @@ -1,8 +1,9 @@ -from fastapi import APIRouter, Depends, Query +from fastapi import APIRouter, Depends from core.security import check_permissions from schemas import common as BaseSchema from schemas import user as UserSchema +from schemas.common import QueryData from service.user import service as UserService router = APIRouter(prefix="/user", tags=["用户管理"]) @@ -13,41 +14,38 @@ ListAll = BaseSchema.ListAll user_list_schema = ListAll[list[UserSchema.UserRead]] -@router.get("", summary="用户列表", response_model=Response[user_list_schema]) -async def user_list( - offset: int = Query(default=1, description="偏移量-页码"), - limit: int = Query(default=10, description="数据量"), -): - return await UserService.get_items(offset, limit) +@router.get("", summary="用户列表") +async def user_list(query: QueryData = Depends()) -> Response[user_list_schema]: + return await UserService.get_items(query.offset, query.limit) -@router.post("/query", summary="用户查询", response_model=Response[user_list_schema]) -async def user_query(query: UserSchema.UserQuery): +@router.post("/query", summary="用户查询") +async def user_query(query: UserSchema.UserQuery) -> Response[user_list_schema]: return await UserService.query_items(query) -@router.post("", summary="用户新增", response_model=Response[UserSchema.UserRead]) -async def user_create(data: UserSchema.UserAdd): +@router.post("", summary="用户新增") +async def user_create(data: UserSchema.UserAdd) -> Response[UserSchema.UserRead]: return await UserService.create_item(data) -@router.delete("/{pk}", summary="用户删除", response_model=Response) -async def user_delete(pk: int): +@router.delete("/{pk}", summary="用户删除") +async def user_delete(pk: int) -> Response: return await UserService.delete_item(pk) -@router.get("/{pk}", summary="用户信息", response_model=Response[UserSchema.UserInfo]) -async def user_info(pk: int): +@router.get("/{pk}", summary="用户信息") +async def user_info(pk: int) -> Response[UserSchema.UserInfo]: return await UserService.get_item(pk) -@router.put("/{pk}", summary="用户更新", response_model=Response) -async def user_update(pk: int, data: UserSchema.UserPut): +@router.put("/{pk}", summary="用户更新") +async def user_update(pk: int, data: UserSchema.UserPut) -> Response: return await UserService.update_item(pk, data) -@router.put("/role/{rid}", summary="用户切换角色", response_model=Response) +@router.put("/role/{rid}", summary="用户切换角色") async def user_change_role( rid: int, user: UserSchema.UserRead = Depends(check_permissions) -): +) -> Response: return await UserService.change_current_role(user.id, rid) diff --git a/backend/schemas/common.py b/backend/schemas/common.py index 57cd61e..83fda4f 100644 --- a/backend/schemas/common.py +++ b/backend/schemas/common.py @@ -26,8 +26,8 @@ class ReadBase(BaseModel): class LoginForm(BaseModel): """用户登录参数""" - username: str = Field(..., description="账号", max_length=12, min_length=3) - password: str = Field(..., description="密码", min_length=6, max_length=16) + username: str = Field("admin", description="账号", max_length=12, min_length=3) + password: str = Field("123456", description="密码", min_length=6, max_length=16) class LoginResult(BaseModel): @@ -41,8 +41,8 @@ class LoginResult(BaseModel): class QueryData(BaseModel): """分页查询基础数据""" - offset: int = 1 - limit: int = 10 + offset: int = Field(default=1, description="页码", ge=1) + limit: int = Field(default=10, description="数量", ge=1) class ListAll(GenericModel, Generic[T]):