Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion backend/app/admin/api/v1/auth/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
router = APIRouter(prefix='/auth')

router.include_router(auth_router, tags=['授权'])
router.include_router(captcha_router, prefix='/captcha', tags=['验证码'])
router.include_router(captcha_router, tags=['验证码'])
19 changes: 13 additions & 6 deletions backend/app/admin/api/v1/auth/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@
from backend.app.admin.schema.user import AuthLoginParam
from backend.app.admin.service.auth_service import auth_service
from backend.common.response.response_schema import ResponseModel, ResponseSchemaModel, response_base
from backend.common.security.jwt import DependsJwtAuth

router = APIRouter()


@router.post('/login/swagger', summary='swagger 调试专用', description='用于快捷获取 token 进行 swagger 认证')
async def swagger_login(obj: Annotated[HTTPBasicCredentials, Depends()]) -> GetSwaggerToken:
async def login_swagger(obj: Annotated[HTTPBasicCredentials, Depends()]) -> GetSwaggerToken:
token, user = await auth_service.swagger_login(obj=obj)
return GetSwaggerToken(access_token=token, user=user) # type: ignore
return GetSwaggerToken(access_token=token, user=user)


@router.post(
Expand All @@ -27,20 +28,26 @@ async def swagger_login(obj: Annotated[HTTPBasicCredentials, Depends()]) -> GetS
description='json 格式登录, 仅支持在第三方api工具调试, 例如: postman',
dependencies=[Depends(RateLimiter(times=5, minutes=1))],
)
async def user_login(
async def login(
request: Request, response: Response, obj: AuthLoginParam, background_tasks: BackgroundTasks
) -> ResponseSchemaModel[GetLoginToken]:
data = await auth_service.login(request=request, response=response, obj=obj, background_tasks=background_tasks)
return response_base.success(data=data)


@router.post('/tokens/refresh', summary='刷新 token')
@router.get('/codes', summary='获取所有授权码', description='适配 vben admin v5', dependencies=[DependsJwtAuth])
async def get_codes(request: Request) -> ResponseSchemaModel[list[str]]:
codes = await auth_service.get_codes(request=request)
return response_base.success(data=codes)


@router.post('/tokens', summary='刷新 token')
async def refresh_token(request: Request) -> ResponseSchemaModel[GetNewToken]:
data = await auth_service.new_token(request=request)
data = await auth_service.refresh_token(request=request)
return response_base.success(data=data)


@router.post('/logout', summary='用户登出')
async def user_logout(request: Request, response: Response) -> ResponseModel:
async def logout(request: Request, response: Response) -> ResponseModel:
await auth_service.logout(request=request, response=response)
return response_base.success()
2 changes: 1 addition & 1 deletion backend/app/admin/api/v1/auth/captcha.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@


@router.get(
'',
'/captcha',
summary='获取登录验证码',
dependencies=[Depends(RateLimiter(times=5, seconds=10))],
)
Expand Down
10 changes: 5 additions & 5 deletions backend/app/admin/api/v1/log/login_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from fastapi import APIRouter, Depends, Query

from backend.app.admin.schema.login_log import GetLoginLogDetail
from backend.app.admin.schema.login_log import DeleteLoginLogParam, GetLoginLogDetail
from backend.app.admin.service.login_log_service import login_log_service
from backend.common.pagination import DependsPagination, PageData, paging_data
from backend.common.response.response_schema import ResponseModel, ResponseSchemaModel, response_base
Expand All @@ -24,7 +24,7 @@
DependsPagination,
],
)
async def get_pagination_login_logs(
async def get_login_logs_paged(
db: CurrentSession,
username: Annotated[str | None, Query(description='用户名')] = None,
status: Annotated[int | None, Query(description='状态')] = None,
Expand All @@ -43,8 +43,8 @@ async def get_pagination_login_logs(
DependsRBAC,
],
)
async def delete_login_log(pk: Annotated[list[int], Query(description='登录日志 ID 列表')]) -> ResponseModel:
count = await login_log_service.delete(pk=pk)
async def delete_login_logs(obj: DeleteLoginLogParam) -> ResponseModel:
count = await login_log_service.delete(obj=obj)
if count > 0:
return response_base.success()
return response_base.fail()
Expand All @@ -54,7 +54,7 @@ async def delete_login_log(pk: Annotated[list[int], Query(description='登录日
'/all',
summary='清空登录日志',
dependencies=[
Depends(RequestPermission('log:login:empty')),
Depends(RequestPermission('log:login:clear')),
DependsRBAC,
],
)
Expand Down
10 changes: 5 additions & 5 deletions backend/app/admin/api/v1/log/opera_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from fastapi import APIRouter, Depends, Query

from backend.app.admin.schema.opera_log import GetOperaLogDetail
from backend.app.admin.schema.opera_log import DeleteOperaLogParam, GetOperaLogDetail
from backend.app.admin.service.opera_log_service import opera_log_service
from backend.common.pagination import DependsPagination, PageData, paging_data
from backend.common.response.response_schema import ResponseModel, ResponseSchemaModel, response_base
Expand All @@ -24,7 +24,7 @@
DependsPagination,
],
)
async def get_pagination_opera_logs(
async def get_opera_logs_paged(
db: CurrentSession,
username: Annotated[str | None, Query(description='用户名')] = None,
status: Annotated[int | None, Query(description='状态')] = None,
Expand All @@ -43,8 +43,8 @@ async def get_pagination_opera_logs(
DependsRBAC,
],
)
async def delete_opera_log(pk: Annotated[list[int], Query(description='操作日志 ID 列表')]) -> ResponseModel:
count = await opera_log_service.delete(pk=pk)
async def delete_opera_logs(obj: DeleteOperaLogParam) -> ResponseModel:
count = await opera_log_service.delete(obj=obj)
if count > 0:
return response_base.success()
return response_base.fail()
Expand All @@ -54,7 +54,7 @@ async def delete_opera_log(pk: Annotated[list[int], Query(description='操作日
'/all',
summary='清空操作日志',
dependencies=[
Depends(RequestPermission('log:opera:empty')),
Depends(RequestPermission('log:opera:clear')),
DependsRBAC,
],
)
Expand Down
2 changes: 1 addition & 1 deletion backend/app/admin/api/v1/monitor/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@

router.include_router(redis_router, prefix='/redis', tags=['redis监控'])
router.include_router(server_router, prefix='/server', tags=['服务器监控'])
router.include_router(token_router, prefix='/online', tags=['在线用户'])
router.include_router(token_router, prefix='/sessions', tags=['会话监控'])
8 changes: 4 additions & 4 deletions backend/app/admin/api/v1/monitor/online.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@


@router.get('', summary='获取在线用户', dependencies=[DependsJwtAuth])
async def get_online(
async def get_sessions(
username: Annotated[str | None, Query(description='用户名')] = None,
) -> ResponseSchemaModel[list[GetTokenDetail]]:
token_keys = await redis_client.keys(f'{settings.TOKEN_REDIS_PREFIX}:*')
Expand Down Expand Up @@ -75,13 +75,13 @@ def append_token_detail() -> None:

@router.delete(
'/{pk}',
summary='踢下线',
summary='强制下线',
dependencies=[
Depends(RequestPermission('sys:token:kick')),
Depends(RequestPermission('sys:session:delete')),
DependsRBAC,
],
)
async def kick_out(
async def delete_session(
request: Request,
pk: Annotated[int, Path(description='用户 ID')],
session_uuid: Annotated[str, Query(description='会话 UUID')],
Expand Down
4 changes: 2 additions & 2 deletions backend/app/admin/api/v1/sys/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
from backend.app.admin.api.v1.sys.data_rule import router as data_rule_router
from backend.app.admin.api.v1.sys.data_scope import router as data_scope_router
from backend.app.admin.api.v1.sys.dept import router as dept_router
from backend.app.admin.api.v1.sys.files import router as file_router
from backend.app.admin.api.v1.sys.menu import router as menu_router
from backend.app.admin.api.v1.sys.plugin import router as plugin_router
from backend.app.admin.api.v1.sys.role import router as role_router
from backend.app.admin.api.v1.sys.upload import router as upload_router
from backend.app.admin.api.v1.sys.user import router as user_router

router = APIRouter(prefix='/sys')
Expand All @@ -19,5 +19,5 @@
router.include_router(user_router, prefix='/users', tags=['系统用户'])
router.include_router(data_rule_router, prefix='/data-rules', tags=['系统数据规则'])
router.include_router(data_scope_router, prefix='/data-scopes', tags=['系统数据范围'])
router.include_router(upload_router, prefix='/upload', tags=['系统上传'])
router.include_router(file_router, prefix='/files', tags=['系统文件'])
router.include_router(plugin_router, prefix='/plugins', tags=['系统插件'])
7 changes: 4 additions & 3 deletions backend/app/admin/api/v1/sys/data_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from backend.app.admin.schema.data_rule import (
CreateDataRuleParam,
DeleteDataRuleParam,
GetDataRuleColumnDetail,
GetDataRuleDetail,
UpdateDataRuleParam,
Expand Down Expand Up @@ -57,7 +58,7 @@ async def get_data_rule(
DependsPagination,
],
)
async def get_pagination_data_rules(
async def get_data_rules_paged(
db: CurrentSession, name: Annotated[str | None, Query(description='规则名称')] = None
) -> ResponseSchemaModel[PageData[GetDataRuleDetail]]:
data_rule_select = await data_rule_service.get_select(name=name)
Expand Down Expand Up @@ -103,8 +104,8 @@ async def update_data_rule(
DependsRBAC,
],
)
async def delete_data_rule(pk: Annotated[list[int], Query(description='数据规则 ID 列表')]) -> ResponseModel:
count = await data_rule_service.delete(pk=pk)
async def delete_data_rules(obj: DeleteDataRuleParam) -> ResponseModel:
count = await data_rule_service.delete(obj=obj)
if count > 0:
return response_base.success()
return response_base.fail()
7 changes: 4 additions & 3 deletions backend/app/admin/api/v1/sys/data_scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from backend.app.admin.schema.data_scope import (
CreateDataScopeParam,
DeleteDataScopeParam,
GetDataScopeDetail,
GetDataScopeWithRelationDetail,
UpdateDataScopeParam,
Expand Down Expand Up @@ -52,7 +53,7 @@ async def get_data_scope_rules(
DependsPagination,
],
)
async def get_pagination_data_scopes(
async def get_data_scopes_paged(
db: CurrentSession,
name: Annotated[str | None, Query(description='范围名称')] = None,
status: Annotated[int | None, Query(description='状态')] = None,
Expand Down Expand Up @@ -117,8 +118,8 @@ async def update_data_scope_rules(
DependsRBAC,
],
)
async def delete_data_scope(pk: Annotated[list[int], Query(description='数据范围 ID 列表')]) -> ResponseModel:
count = await data_scope_service.delete(pk=pk)
async def delete_data_scopes(obj: DeleteDataScopeParam) -> ResponseModel:
count = await data_scope_service.delete(obj=obj)
if count > 0:
return response_base.success()
return response_base.fail()
6 changes: 3 additions & 3 deletions backend/app/admin/api/v1/sys/dept.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ async def get_dept(pk: Annotated[int, Path(description='部门 ID')]) -> Respons
return response_base.success(data=data)


@router.get('', summary='获取所有部门展示树', dependencies=[DependsJwtAuth])
async def get_all_depts(
@router.get('', summary='获取部门树', dependencies=[DependsJwtAuth])
async def get_dept_tree(
request: Request,
name: Annotated[str | None, Query(description='部门名称')] = None,
leader: Annotated[str | None, Query(description='部门负责人')] = None,
phone: Annotated[str | None, Query(description='联系电话')] = None,
status: Annotated[int | None, Query(description='状态')] = None,
) -> ResponseSchemaModel[list[dict[str, Any]]]:
dept = await dept_service.get_dept_tree(request=request, name=name, leader=leader, phone=phone, status=status)
dept = await dept_service.get_tree(request=request, name=name, leader=leader, phone=phone, status=status)
return response_base.success(data=dept)


Expand Down
27 changes: 27 additions & 0 deletions backend/app/admin/api/v1/sys/files.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from typing import Annotated

from fastapi import APIRouter, Depends, File, UploadFile

from backend.common.dataclasses import UploadUrl
from backend.common.response.response_schema import ResponseSchemaModel, response_base
from backend.common.security.permission import RequestPermission
from backend.common.security.rbac import DependsRBAC
from backend.utils.file_ops import file_verify, upload_file

router = APIRouter()


@router.post(
'/upload',
summary='文件上传',
dependencies=[
Depends(RequestPermission('sys:file:upload')),
DependsRBAC,
],
)
async def upload_files(file: Annotated[UploadFile, File()]) -> ResponseSchemaModel[UploadUrl]:
file_verify(file)
filename = await upload_file(file)
return response_base.success(data={'url': f'/static/upload/{filename}'})
8 changes: 4 additions & 4 deletions backend/app/admin/api/v1/sys/menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
router = APIRouter()


@router.get('/sidebar', summary='获取用户菜单侧边栏', description='适配 vben5', dependencies=[DependsJwtAuth])
@router.get('/sidebar', summary='获取用户菜单侧边栏', description='已适配 vben admin v5', dependencies=[DependsJwtAuth])
async def get_user_sidebar(request: Request) -> ResponseSchemaModel[list[dict[str, Any] | None]]:
menu = await menu_service.get_sidebar(request=request)
return response_base.success(data=menu)
Expand All @@ -26,12 +26,12 @@ async def get_menu(pk: Annotated[int, Path(description='菜单 ID')]) -> Respons
return response_base.success(data=data)


@router.get('', summary='获取所有菜单展示树', dependencies=[DependsJwtAuth])
async def get_all_menus(
@router.get('', summary='获取菜单树', dependencies=[DependsJwtAuth])
async def get_menu_tree(
title: Annotated[str | None, Query(description='菜单标题')] = None,
status: Annotated[int | None, Query(description='状体')] = None,
) -> ResponseSchemaModel[list[dict[str, Any]]]:
menu = await menu_service.get_menu_tree(title=title, status=status)
menu = await menu_service.get_tree(title=title, status=status)
return response_base.success(data=menu)


Expand Down
Loading