Skip to content

Commit

Permalink
Merge pull request #14 from pylover7/develop
Browse files Browse the repository at this point in the history
✨feat(superAdmin): 超管面板
  • Loading branch information
pylover7 authored May 6, 2024
2 parents 8a6baef + a0e335b commit a51bb19
Show file tree
Hide file tree
Showing 121 changed files with 15,971 additions and 4,676 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# backend
*.yml
*.toml
.env.*
.env
*.pyc
Expand All @@ -20,6 +22,7 @@ npm-debug.log*
.pnpm-error.log*
.pnpm-debug.log
tests/**/coverage/
/**/static/

# Editor directories and files
.idea
Expand Down
14 changes: 8 additions & 6 deletions backend/app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
from pathlib import Path

from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles

from app.core.exceptions import SettingNotFound
from app.core.init_app import (
init_menus,
init_superuser,
make_middlewares,
register_db,
register_exceptions,
register_routers,
)
from app.core.init_db import init_db
from app.log import logger

try:
from app.settings.config import settings
Expand All @@ -24,9 +26,10 @@ def create_app() -> FastAPI:
openapi_url="/openapi.json",
middleware=make_middlewares(),
)
register_db(app)
register_exceptions(app)
register_routers(app, prefix="/api")
static_path = Path.joinpath(Path(__file__).parent, "static")
app.mount("/static", StaticFiles(directory=static_path), name="static")
return app


Expand All @@ -35,5 +38,4 @@ def create_app() -> FastAPI:

@app.on_event("startup")
async def startup_event():
await init_superuser()
await init_menus()
await init_db(app)
16 changes: 10 additions & 6 deletions backend/app/api/v1/__init__.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
from fastapi import APIRouter

from app.core.dependency import DependPermisson
from app.core.dependency import DependPermission, DependAuth

from .apis import apis_router
from .base import base_router
from .menus import menus_router
from .roles import roles_router
from .users import users_router
from .material import material_router
from .admin import admin_router
from .superAdmin import depart_router

v1_router = APIRouter()

v1_router.include_router(base_router, prefix="/base")
v1_router.include_router(users_router, prefix="/user", dependencies=[DependPermisson])
v1_router.include_router(roles_router, prefix="/role", dependencies=[DependPermisson])
v1_router.include_router(menus_router, prefix="/menu", dependencies=[DependPermisson])
v1_router.include_router(apis_router, prefix="/api", dependencies=[DependPermisson])
v1_router.include_router(material_router, prefix="/material", dependencies=[DependPermisson])
v1_router.include_router(users_router, prefix="/user", dependencies=[DependPermission])
v1_router.include_router(roles_router, prefix="/role", dependencies=[DependPermission])
v1_router.include_router(menus_router, prefix="/menu", dependencies=[DependPermission])
v1_router.include_router(apis_router, prefix="/api", dependencies=[DependPermission])
v1_router.include_router(material_router, prefix="/material", dependencies=[DependPermission])
v1_router.include_router(admin_router, prefix="/admin", dependencies=[DependAuth])
v1_router.include_router(depart_router, prefix="/depart", dependencies=[DependPermission])
12 changes: 12 additions & 0 deletions backend/app/api/v1/admin/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# coding=utf-8
# @FileName :__init__.py.py
# @Time :2024/4/16 下午9:30
# @Author :dayezi
from fastapi import APIRouter

from .admin import router

admin_router = APIRouter()
admin_router.include_router(router, tags=["管理员模块"])

__all__ = ["admin_router"]
37 changes: 37 additions & 0 deletions backend/app/api/v1/admin/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# coding=utf-8
# @FileName :users.py
# @Time :2024/4/16 下午9:31
# @Author :dayezi
from fastapi import APIRouter, Request

from app.settings import settings
from app.core.init_db import test_db, set_db
from app.log import logger
from app.schemas import Success, Fail
from app.schemas.admin import DbInfo

router = APIRouter()


@router.get("/get_db_info")
async def get_db_info():
data = settings.DATABASE_INFO.model_dump()
return Success(data=data)


@router.post("/test_db_info", summary="测试数据库连接")
async def test_db_conn(data: DbInfo):
if test_db(data):
return Success(msg="数据库链接成功!")
else:
return Fail(msg="数据库链接失败!")


@router.post("/set_db_info", summary="设置数据库连接")
async def set_db_conn(data: DbInfo, request: Request):
try:
await set_db(data, request.app)
return Success(msg="数据库设置成功!")
except Exception as e:
logger.error(e)
return Fail(msg="数据库设置失败!")
6 changes: 3 additions & 3 deletions backend/app/api/v1/apis/apis.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from app.controllers.api import api_controller
from app.log import logger
from app.models.admin import Api
from app.models.users import Api
from app.schemas import Success, SuccessExtra
from app.schemas.apis import *

Expand All @@ -14,7 +14,7 @@
@router.get("/list", summary="查看API列表")
async def list_api(
page: int = Query(1, description="页码"),
page_size: int = Query(10, description="每页数量"),
page_size: int = Query(1000, description="每页数量"),
path: str = Query(None, description="API路径"),
summary: str = Query(None, description="API简介"),
tags: str = Query(None, description="API模块"),
Expand All @@ -28,7 +28,7 @@ async def list_api(
q &= Q(tags__contains=tags)
total, api_objs = await api_controller.list(page=page, page_size=page_size, search=q, order=["tags", "id"])
data = [await obj.to_dict() for obj in api_objs]
return SuccessExtra(data=data, total=total, page=page, page_size=page_size)
return SuccessExtra(data=data, total=total, currentPage=page, pageSize=page_size)


@router.get("/get", summary="查看Api")
Expand Down
30 changes: 20 additions & 10 deletions backend/app/api/v1/base/base.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
from datetime import datetime, timedelta
from datetime import timedelta

from fastapi import APIRouter
from jwt.exceptions import ExpiredSignatureError

from app.controllers.user import UserController, user_controller
from app.controllers.user import user_controller
from app.core.ctx import CTX_USER_ID
from app.core.dependency import DependAuth
from app.models.admin import Api, Menu, Role, User
from app.models.users import Api, Menu, Role, User
from app.schemas.base import Fail, Success, FailAuth
from app.schemas.login import *
from app.schemas.users import UpdatePassword
from app.schemas.users import UpdatePassword, UserPydantic
from app.settings import settings
from app.utils.jwtt import create_access_token, decode_access_token
from app.utils.password import get_password_hash, verify_password
Expand All @@ -19,17 +19,28 @@

@router.post("/accessToken", summary="获取token")
async def login_access_token(credentials: CredentialsSchema):
user: User = await user_controller.authenticate(credentials)
await user_controller.update_last_login(user.id)
if (settings.DATABASE_START is None and credentials.username == settings.SUPER_USER["username"]
and credentials.password == settings.SUPER_USER_PWD):
user = UserPydantic.parse_obj(settings.SUPER_USER)
roles = user.roles
depart = user.depart
else:
user: User = await user_controller.authenticate(credentials)
await user_controller.update_last_login(user.id)
roles = await user.roles.all().values_list("code", flat=True)
try:
depart = await user.depart.all().values_list("name", flat=True)
except Exception as e:
depart = ""
access_token_expires = timedelta(minutes=settings.JWT_ACCESS_TOKEN_EXPIRE_MINUTES)
refresh_token_expires = timedelta(minutes=settings.JWT_REFRESH_TOKEN_EXPIRE_MINUTES)
expire = datetime.now() + access_token_expires
expire_refresh = datetime.now() + refresh_token_expires

data = JWTOut(
username=user.username,
depart=user.depart,
roles=["admin"],
depart=depart,
roles=roles,
accessToken=create_access_token(
data=JWTPayload(
user_id=user.id,
Expand Down Expand Up @@ -139,9 +150,8 @@ async def get_user_api():
return Success(data=apis)


@router.post("/update_password", summary="更新用户密码", dependencies=[DependAuth])
@router.post("/updatePwd", summary="更新用户密码", dependencies=[DependAuth])
async def update_user_password(req_in: UpdatePassword):
user_controller = UserController()
user = await user_controller.get(req_in.id)
verified = verify_password(req_in.old_password, user.password)
if not verified:
Expand Down
4 changes: 2 additions & 2 deletions backend/app/api/v1/material/material.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from app.schemas.dutyLog import DutyOverInfo
from app.utils.onDutyInfo import OnDutyInfo
from app.schemas.material import MaterialCreate, MaterialUpdate
from app.utils.password import generate_uuid
from app.utils import generate_uuid

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -52,7 +52,7 @@ async def add_meta(data: MaterialCreate | MaterialUpdate):
if hasattr(data, "id"):
result: Material = await materialController.update(data.id, data.update_dict())
else:
data: MaterialCreate = data.create_dict()
data: dict = data.model_dump()
data["uuid"] = generate_uuid(data["name"])
result: Material = await materialController.create(data)
result = await result.to_dict()
Expand Down
36 changes: 21 additions & 15 deletions backend/app/api/v1/menus/menus.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,51 +11,57 @@
router = APIRouter()


@router.get("/list", summary="查看菜单列表")
async def list_menu(
page: int = Query(1, description="页码"),
page_size: int = Query(10, description="每页数量"),
):
@router.get("/tree", summary="查看菜单树")
async def menu_tree():
parent_menus = await menu_controller.model.filter(parent_id=0).order_by("order")
res_menu = []
for menu in parent_menus:
child_menu = await menu_controller.model.filter(parent_id=menu.id).order_by("order")
menu_dict = await menu.to_dict()
menu_dict["children"] = [await obj.to_dict() for obj in child_menu]
res_menu.append(menu_dict)
return SuccessExtra(data=res_menu, total=len(res_menu), page=page, page_size=page_size)
return Success(data=res_menu)


@router.get("/list", summary="查看菜单列表")
async def menu_list():
_, menus_objs = await menu_controller.list(page=1, page_size=1000)
menu = [await obj.to_dict() for obj in menus_objs]
return Success(data=menu)


@router.get("/get", summary="查看菜单")
@router.get("/get", summary="查看单个菜单")
async def get_menu(
menu_id: int = Query(..., description="菜单id"),
menu_id: int = Query(..., description="菜单id"),
):
result = await menu_controller.get(id=menu_id)
return Success(data=result)


@router.post("/create", summary="创建菜单")
@router.post("/add", summary="创建菜单")
async def create_menu(
menu_in: MenuCreate,
data: MenuCreate,
):
await menu_controller.create(obj_in=menu_in)
return Success(msg="Created Success")
await menu_controller.create(obj_in=data)
return Success(msg="菜单新增成功")


@router.post("/update", summary="更新菜单")
async def update_menu(
menu_in: MenuUpdate,
):
await menu_controller.update(id=menu_in.id, obj_in=menu_in.update_dict())
return Success(msg="Updated Success")
return Success(msg=f"菜单【{menu_in.name}】更新成功")


@router.delete("/delete", summary="删除菜单")
async def delete_menu(
id: int = Query(..., description="菜单id"),
id: int = Query(..., description="菜单id"),
name: str = Query(..., description="菜单名称"),
):
child_menu_count = await menu_controller.model.filter(parent_id=id).count()
child_menu_count = await menu_controller.model.filter(parentId=id).count()
if child_menu_count > 0:
return Fail(msg="Cannot delete a menu with child menus")
await menu_controller.remove(id=id)
logger.info(f"删除菜单【{name}】成功")
return Success(msg="Deleted Success")
Loading

0 comments on commit a51bb19

Please sign in to comment.