perf: 优化所有接口的API文档响应模型显示

This commit is contained in:
insistence
2025-12-15 15:02:49 +08:00
parent d9a19ce3ee
commit 40ccb84922
24 changed files with 363 additions and 63 deletions
@@ -4,6 +4,7 @@ from fastapi import APIRouter, Path, Request, Response
from common.aspect.interface_auth import UserInterfaceAuthDependency
from common.aspect.pre_auth import PreAuthDependency
from common.vo import DataResponseModel, ResponseBaseModel
from module_admin.entity.vo.cache_vo import CacheInfoModel, CacheMonitorModel
from module_admin.service.cache_service import CacheService
from utils.log_util import logger
@@ -14,7 +15,7 @@ cache_controller = APIRouter(prefix='/monitor/cache', dependencies=[PreAuthDepen
@cache_controller.get(
'',
response_model=CacheMonitorModel,
response_model=DataResponseModel[CacheMonitorModel],
dependencies=[UserInterfaceAuthDependency('monitor:cache:list')],
)
async def get_monitor_cache_info(request: Request) -> Response:
@@ -27,7 +28,7 @@ async def get_monitor_cache_info(request: Request) -> Response:
@cache_controller.get(
'/getNames',
response_model=list[CacheInfoModel],
response_model=DataResponseModel[list[CacheInfoModel]],
dependencies=[UserInterfaceAuthDependency('monitor:cache:list')],
)
async def get_monitor_cache_name(request: Request) -> Response:
@@ -40,7 +41,7 @@ async def get_monitor_cache_name(request: Request) -> Response:
@cache_controller.get(
'/getKeys/{cache_name}',
response_model=list[str],
response_model=DataResponseModel[list[str]],
dependencies=[UserInterfaceAuthDependency('monitor:cache:list')],
)
async def get_monitor_cache_key(request: Request, cache_name: Annotated[str, Path(description='缓存名称')]) -> Response:
@@ -53,7 +54,7 @@ async def get_monitor_cache_key(request: Request, cache_name: Annotated[str, Pat
@cache_controller.get(
'/getValue/{cache_name}/{cache_key}',
response_model=CacheInfoModel,
response_model=DataResponseModel[CacheInfoModel],
dependencies=[UserInterfaceAuthDependency('monitor:cache:list')],
)
async def get_monitor_cache_value(
@@ -83,6 +84,7 @@ async def clear_monitor_cache_name(
@cache_controller.delete(
'/clearCacheKey/{cache_key}',
response_model= ResponseBaseModel,
dependencies=[UserInterfaceAuthDependency('monitor:cache:list')],
)
async def clear_monitor_cache_key(request: Request, cache_key: Annotated[str, Path(description='缓存键')]) -> Response:
@@ -94,6 +96,7 @@ async def clear_monitor_cache_key(request: Request, cache_key: Annotated[str, Pa
@cache_controller.delete(
'/clearCacheAll',
response_model= ResponseBaseModel,
dependencies=[UserInterfaceAuthDependency('monitor:cache:list')],
)
async def clear_monitor_cache_all(request: Request) -> Response:
@@ -4,6 +4,7 @@ from datetime import timedelta
from fastapi import APIRouter, Request, Response
from common.enums import RedisInitKeyConfig
from common.vo import DynamicResponseModel
from module_admin.entity.vo.login_vo import CaptchaCode
from module_admin.service.captcha_service import CaptchaService
from utils.log_util import logger
@@ -12,7 +13,10 @@ from utils.response_util import ResponseUtil
captcha_controller = APIRouter()
@captcha_controller.get('/captchaImage')
@captcha_controller.get(
'/captchaImage',
response_model=DynamicResponseModel[CaptchaCode],
)
async def get_captcha_image(request: Request) -> Response:
captcha_enabled = (
await request.app.state.redis.get(f'{RedisInitKeyConfig.SYS_CONFIG.key}:sys.account.captchaEnabled') == 'true'
@@ -1,8 +1,11 @@
from typing import Annotated
from fastapi import APIRouter, BackgroundTasks, File, Query, Request, Response, UploadFile
from fastapi.responses import StreamingResponse
from common.aspect.pre_auth import PreAuthDependency
from common.vo import DynamicResponseModel
from module_admin.entity.vo.common_vo import UploadResponseModel
from module_admin.service.common_service import CommonService
from utils.log_util import logger
from utils.response_util import ResponseUtil
@@ -10,7 +13,10 @@ from utils.response_util import ResponseUtil
common_controller = APIRouter(prefix='/common', dependencies=[PreAuthDependency()])
@common_controller.post('/upload')
@common_controller.post(
'/upload',
response_model=DynamicResponseModel[UploadResponseModel],
)
async def common_upload(request: Request, file: Annotated[UploadFile, File(...)]) -> Response:
upload_result = await CommonService.upload_service(request, file)
logger.info('上传成功')
@@ -18,7 +24,18 @@ async def common_upload(request: Request, file: Annotated[UploadFile, File(...)]
return ResponseUtil.success(model_content=upload_result.result)
@common_controller.get('/download')
@common_controller.get(
'/download',
response_class=StreamingResponse,
responses={
200: {
'description': '流式返回文件',
'content': {
'application/octet-stream': {},
},
}
},
)
async def common_download(
request: Request,
background_tasks: BackgroundTasks,
@@ -31,7 +48,18 @@ async def common_download(
return ResponseUtil.streaming(data=download_result.result)
@common_controller.get('/download/resource')
@common_controller.get(
'/download/resource',
response_class=StreamingResponse,
responses={
200: {
'description': '流式返回文件',
'content': {
'application/octet-stream': {},
},
}
},
)
async def common_download_resource(request: Request, resource: Annotated[str, Query()]) -> Response:
download_resource_result = await CommonService.download_resource_services(resource)
logger.info(download_resource_result.message)
@@ -2,6 +2,7 @@ from datetime import datetime
from typing import Annotated
from fastapi import APIRouter, Form, Path, Query, Request, Response
from fastapi.responses import StreamingResponse
from pydantic_validation_decorator import ValidateFields
from sqlalchemy.ext.asyncio import AsyncSession
@@ -146,6 +147,15 @@ async def query_system_config(request: Request, config_key: str) -> Response:
@config_controller.post(
'/export',
response_class=StreamingResponse,
responses={
200: {
'description': '流式返回参数列表excel文件',
'content': {
'application/octet-stream': {},
},
}
},
dependencies=[UserInterfaceAuthDependency('system:config:export')],
)
@Log(title='参数管理', business_type=BusinessType.EXPORT)
@@ -11,6 +11,7 @@ from common.aspect.db_seesion import DBSessionDependency
from common.aspect.interface_auth import UserInterfaceAuthDependency
from common.aspect.pre_auth import CurrentUserDependency, PreAuthDependency
from common.enums import BusinessType
from common.vo import DataResponseModel, ResponseBaseModel
from module_admin.entity.vo.dept_vo import DeleteDeptModel, DeptModel, DeptQueryModel
from module_admin.entity.vo.user_vo import CurrentUserModel
from module_admin.service.dept_service import DeptService
@@ -22,7 +23,7 @@ dept_controller = APIRouter(prefix='/system/dept', dependencies=[PreAuthDependen
@dept_controller.get(
'/list/exclude/{dept_id}',
response_model=list[DeptModel],
response_model=DataResponseModel[list[DeptModel]],
dependencies=[UserInterfaceAuthDependency('system:dept:list')],
)
async def get_system_dept_tree_for_edit_option(
@@ -40,7 +41,7 @@ async def get_system_dept_tree_for_edit_option(
@dept_controller.get(
'/list',
response_model=list[DeptModel],
response_model=DataResponseModel[list[DeptModel]],
dependencies=[UserInterfaceAuthDependency('system:dept:list')],
)
async def get_system_dept_list(
@@ -57,6 +58,7 @@ async def get_system_dept_list(
@dept_controller.post(
'',
response_model=ResponseBaseModel,
dependencies=[UserInterfaceAuthDependency('system:dept:add')],
)
@ValidateFields(validate_model='add_dept')
@@ -74,11 +76,12 @@ async def add_system_dept(
add_dept_result = await DeptService.add_dept_services(query_db, add_dept)
logger.info(add_dept_result.message)
return ResponseUtil.success(data=add_dept_result)
return ResponseUtil.success(msg=add_dept_result.message)
@dept_controller.put(
'',
response_model=ResponseBaseModel,
dependencies=[UserInterfaceAuthDependency('system:dept:edit')],
)
@ValidateFields(validate_model='edit_dept')
@@ -102,6 +105,7 @@ async def edit_system_dept(
@dept_controller.delete(
'/{dept_ids}',
response_model=ResponseBaseModel,
dependencies=[UserInterfaceAuthDependency('system:dept:remove')],
)
@Log(title='部门管理', business_type=BusinessType.DELETE)
@@ -128,7 +132,7 @@ async def delete_system_dept(
@dept_controller.get(
'/{dept_id}',
response_model=DeptModel,
response_model=DataResponseModel[DeptModel],
dependencies=[UserInterfaceAuthDependency('system:dept:query')],
)
async def query_detail_system_dept(
@@ -2,6 +2,7 @@ from datetime import datetime
from typing import Annotated
from fastapi import APIRouter, Form, Path, Query, Request, Response
from fastapi.responses import StreamingResponse
from pydantic_validation_decorator import ValidateFields
from sqlalchemy.ext.asyncio import AsyncSession
@@ -155,6 +156,15 @@ async def query_detail_system_dict_type(
@dict_controller.post(
'/type/export',
response_class=StreamingResponse,
responses={
200: {
'description': '流式返回字典类型列表excel文件',
'content': {
'application/octet-stream': {},
},
}
},
dependencies=[UserInterfaceAuthDependency('system:dict:export')],
)
@Log(title='字典类型', business_type=BusinessType.EXPORT)
@@ -290,6 +300,15 @@ async def query_detail_system_dict_data(
@dict_controller.post(
'/data/export',
response_class=StreamingResponse,
responses={
200: {
'description': '流式返回字典数据列表excel文件',
'content': {
'application/octet-stream': {},
},
}
},
dependencies=[UserInterfaceAuthDependency('system:dict:export')],
)
@Log(title='字典数据', business_type=BusinessType.EXPORT)
@@ -2,6 +2,7 @@ from datetime import datetime
from typing import Annotated
from fastapi import APIRouter, Form, Path, Query, Request, Response
from fastapi.responses import StreamingResponse
from pydantic_validation_decorator import ValidateFields
from sqlalchemy.ext.asyncio import AsyncSession
@@ -169,6 +170,15 @@ async def query_detail_system_job(
@job_controller.post(
'/job/export',
response_class=StreamingResponse,
responses={
200: {
'description': '流式返回定时任务列表excel文件',
'content': {
'application/octet-stream': {},
},
}
},
dependencies=[UserInterfaceAuthDependency('monitor:job:export')],
)
@Log(title='定时任务', business_type=BusinessType.EXPORT)
@@ -240,6 +250,15 @@ async def delete_system_job_log(
@job_controller.post(
'/jobLog/export',
response_class=StreamingResponse,
responses={
200: {
'description': '流式返回定时任务日志列表excel文件',
'content': {
'application/octet-stream': {},
},
}
},
dependencies=[UserInterfaceAuthDependency('monitor:job:export')],
)
@Log(title='定时任务调度日志', business_type=BusinessType.EXPORT)
@@ -1,6 +1,7 @@
from typing import Annotated
from fastapi import APIRouter, Form, Path, Query, Request, Response
from fastapi.responses import StreamingResponse
from sqlalchemy.ext.asyncio import AsyncSession
from common.annotation.log_annotation import Log
@@ -82,6 +83,15 @@ async def delete_system_operation_log(
@log_controller.post(
'/operlog/export',
response_class=StreamingResponse,
responses={
200: {
'description': '流式返回操作日志列表excel文件',
'content': {
'application/octet-stream': {},
},
}
},
dependencies=[UserInterfaceAuthDependency('monitor:operlog:export')],
)
@Log(title='操作日志', business_type=BusinessType.EXPORT)
@@ -174,6 +184,15 @@ async def unlock_system_user(
@log_controller.post(
'/logininfor/export',
response_class=StreamingResponse,
responses={
200: {
'description': '流式返回登录日志列表excel文件',
'content': {
'application/octet-stream': {},
},
}
},
dependencies=[UserInterfaceAuthDependency('monitor:logininfor:export')],
)
@Log(title='登录日志', business_type=BusinessType.EXPORT)
@@ -10,9 +10,9 @@ from common.annotation.log_annotation import Log
from common.aspect.db_seesion import DBSessionDependency
from common.aspect.pre_auth import CurrentUserDependency
from common.enums import BusinessType, RedisInitKeyConfig
from common.vo import CrudResponseModel
from common.vo import CrudResponseModel, DataResponseModel, DynamicResponseModel, ResponseBaseModel
from config.env import AppConfig, JwtConfig
from module_admin.entity.vo.login_vo import Token, UserLogin, UserRegister
from module_admin.entity.vo.login_vo import RouterModel, Token, UserLogin, UserRegister
from module_admin.entity.vo.user_vo import CurrentUserModel, EditUserModel
from module_admin.service.login_service import CustomOAuth2PasswordRequestForm, LoginService, oauth2_scheme
from module_admin.service.user_service import UserService
@@ -22,7 +22,10 @@ from utils.response_util import ResponseUtil
login_controller = APIRouter()
@login_controller.post('/login', response_model=Token)
@login_controller.post(
'/login',
response_model=DynamicResponseModel[Token],
)
@Log(title='用户登录', business_type=BusinessType.OTHER, log_type='login')
async def login(
request: Request,
@@ -78,7 +81,10 @@ async def login(
return ResponseUtil.success(msg='登录成功', dict_content={'token': access_token})
@login_controller.get('/getInfo', response_model=CurrentUserModel)
@login_controller.get(
'/getInfo',
response_model=DynamicResponseModel[CurrentUserModel],
)
async def get_login_user_info(
request: Request, current_user: Annotated[CurrentUserModel, CurrentUserDependency()]
) -> Response:
@@ -87,7 +93,10 @@ async def get_login_user_info(
return ResponseUtil.success(model_content=current_user)
@login_controller.get('/getRouters')
@login_controller.get(
'/getRouters',
response_model=DataResponseModel[list[RouterModel]],
)
async def get_login_user_routers(
request: Request,
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
@@ -99,7 +108,10 @@ async def get_login_user_routers(
return ResponseUtil.success(data=user_routers)
@login_controller.post('/register', response_model=CrudResponseModel)
@login_controller.post(
'/register',
response_model=DataResponseModel[CrudResponseModel],
)
async def register_user(
request: Request,
user_register: UserRegister,
@@ -141,7 +153,10 @@ async def register_user(
# return ResponseUtil.error(msg=str(e))
@login_controller.post('/logout')
@login_controller.post(
'/logout',
response_model=ResponseBaseModel,
)
async def logout(request: Request, token: Annotated[Optional[str], Depends(oauth2_scheme)]) -> Response:
payload = jwt.decode(
token, JwtConfig.jwt_secret_key, algorithms=[JwtConfig.jwt_algorithm], options={'verify_exp': False}
@@ -10,7 +10,9 @@ from common.aspect.db_seesion import DBSessionDependency
from common.aspect.interface_auth import UserInterfaceAuthDependency
from common.aspect.pre_auth import CurrentUserDependency, PreAuthDependency
from common.enums import BusinessType
from module_admin.entity.vo.menu_vo import DeleteMenuModel, MenuModel, MenuQueryModel
from common.vo import DataResponseModel, DynamicResponseModel, ResponseBaseModel
from module_admin.entity.vo.menu_vo import DeleteMenuModel, MenuModel, MenuQueryModel, MenuTreeModel
from module_admin.entity.vo.role_vo import RoleMenuQueryModel
from module_admin.entity.vo.user_vo import CurrentUserModel
from module_admin.service.menu_service import MenuService
from utils.log_util import logger
@@ -19,7 +21,10 @@ from utils.response_util import ResponseUtil
menu_controller = APIRouter(prefix='/system/menu', dependencies=[PreAuthDependency()])
@menu_controller.get('/treeselect')
@menu_controller.get(
'/treeselect',
response_model=DataResponseModel[list[MenuTreeModel]],
)
async def get_system_menu_tree(
request: Request,
query_db: Annotated[AsyncSession, DBSessionDependency()],
@@ -31,7 +36,10 @@ async def get_system_menu_tree(
return ResponseUtil.success(data=menu_query_result)
@menu_controller.get('/roleMenuTreeselect/{role_id}')
@menu_controller.get(
'/roleMenuTreeselect/{role_id}',
response_model=DynamicResponseModel[RoleMenuQueryModel],
)
async def get_system_role_menu_tree(
request: Request,
role_id: Annotated[int, Path(description='角色ID')],
@@ -46,7 +54,7 @@ async def get_system_role_menu_tree(
@menu_controller.get(
'/list',
response_model=list[MenuModel],
response_model=DataResponseModel[list[MenuModel]],
dependencies=[UserInterfaceAuthDependency('system:menu:list')],
)
async def get_system_menu_list(
@@ -63,6 +71,7 @@ async def get_system_menu_list(
@menu_controller.post(
'',
response_model=ResponseBaseModel,
dependencies=[UserInterfaceAuthDependency('system:menu:add')],
)
@ValidateFields(validate_model='add_menu')
@@ -85,6 +94,7 @@ async def add_system_menu(
@menu_controller.put(
'',
response_model=ResponseBaseModel,
dependencies=[UserInterfaceAuthDependency('system:menu:edit')],
)
@ValidateFields(validate_model='edit_menu')
@@ -105,6 +115,7 @@ async def edit_system_menu(
@menu_controller.delete(
'/{menu_ids}',
response_model=ResponseBaseModel,
dependencies=[UserInterfaceAuthDependency('system:menu:remove')],
)
@Log(title='菜单管理', business_type=BusinessType.DELETE)
@@ -122,7 +133,7 @@ async def delete_system_menu(
@menu_controller.get(
'/{menu_id}',
response_model=MenuModel,
response_model=DataResponseModel[MenuModel],
dependencies=[UserInterfaceAuthDependency('system:menu:query')],
)
async def query_detail_system_menu(
@@ -2,6 +2,7 @@ from datetime import datetime
from typing import Annotated
from fastapi import APIRouter, Form, Path, Query, Request, Response
from fastapi.responses import StreamingResponse
from pydantic_validation_decorator import ValidateFields
from sqlalchemy.ext.asyncio import AsyncSession
@@ -118,6 +119,15 @@ async def query_detail_system_post(
@post_controller.post(
'/export',
response_class=StreamingResponse,
responses={
200: {
'description': '流式返回岗位列表excel文件',
'content': {
'application/octet-stream': {},
},
}
},
dependencies=[UserInterfaceAuthDependency('system:post:export')],
)
@Log(title='岗位管理', business_type=BusinessType.EXPORT)
@@ -2,6 +2,7 @@ from datetime import datetime
from typing import Annotated
from fastapi import APIRouter, Form, Path, Query, Request, Response
from fastapi.responses import StreamingResponse
from pydantic_validation_decorator import ValidateFields
from sqlalchemy.ext.asyncio import AsyncSession
@@ -11,10 +12,16 @@ from common.aspect.db_seesion import DBSessionDependency
from common.aspect.interface_auth import UserInterfaceAuthDependency
from common.aspect.pre_auth import CurrentUserDependency, PreAuthDependency
from common.enums import BusinessType
from common.vo import DataResponseModel, PageResponseModel, ResponseBaseModel
from common.vo import DataResponseModel, DynamicResponseModel, PageResponseModel, ResponseBaseModel
from module_admin.entity.vo.dept_vo import DeptModel
from module_admin.entity.vo.role_vo import AddRoleModel, DeleteRoleModel, RoleModel, RolePageQueryModel
from module_admin.entity.vo.user_vo import CrudUserRoleModel, CurrentUserModel, UserModel, UserRolePageQueryModel
from module_admin.entity.vo.role_vo import (
AddRoleModel,
DeleteRoleModel,
RoleDeptQueryModel,
RoleModel,
RolePageQueryModel,
)
from module_admin.entity.vo.user_vo import CrudUserRoleModel, CurrentUserModel, UserInfoModel, UserRolePageQueryModel
from module_admin.service.dept_service import DeptService
from module_admin.service.role_service import RoleService
from module_admin.service.user_service import UserService
@@ -27,6 +34,7 @@ role_controller = APIRouter(prefix='/system/role', dependencies=[PreAuthDependen
@role_controller.get(
'/deptTree/{role_id}',
response_model=DynamicResponseModel[RoleDeptQueryModel],
dependencies=[UserInterfaceAuthDependency('system:role:query')],
)
async def get_system_role_dept_tree(
@@ -188,6 +196,15 @@ async def query_detail_system_role(
@role_controller.post(
'/export',
response_class=StreamingResponse,
responses={
200: {
'description': '流式返回角色列表excel文件',
'content': {
'application/octet-stream': {},
},
}
},
dependencies=[UserInterfaceAuthDependency('system:role:export')],
)
@Log(title='角色管理', business_type=BusinessType.EXPORT)
@@ -238,7 +255,7 @@ async def reset_system_role_status(
@role_controller.get(
'/authUser/allocatedList',
response_model=PageResponseModel[UserModel],
response_model=PageResponseModel[UserInfoModel],
dependencies=[UserInterfaceAuthDependency('system:role:list')],
)
async def get_system_allocated_user_list(
@@ -257,7 +274,7 @@ async def get_system_allocated_user_list(
@role_controller.get(
'/authUser/unallocatedList',
response_model=PageResponseModel[UserModel],
response_model=PageResponseModel[UserInfoModel],
dependencies=[UserInterfaceAuthDependency('system:role:list')],
)
async def get_system_unallocated_user_list(
@@ -2,6 +2,7 @@ from fastapi import APIRouter, Request, Response
from common.aspect.interface_auth import UserInterfaceAuthDependency
from common.aspect.pre_auth import PreAuthDependency
from common.vo import DataResponseModel
from module_admin.entity.vo.server_vo import ServerMonitorModel
from module_admin.service.server_service import ServerService
from utils.log_util import logger
@@ -12,7 +13,7 @@ server_controller = APIRouter(prefix='/monitor/server', dependencies=[PreAuthDep
@server_controller.get(
'',
response_model=ServerMonitorModel,
response_model=DataResponseModel[ServerMonitorModel],
dependencies=[UserInterfaceAuthDependency('monitor:server:list')],
)
async def get_monitor_server_info(request: Request) -> Response:
@@ -4,6 +4,7 @@ from typing import Annotated, Literal, Optional, Union
import aiofiles
from fastapi import APIRouter, File, Form, Path, Query, Request, Response, UploadFile
from fastapi.responses import StreamingResponse
from pydantic_validation_decorator import ValidateFields
from sqlalchemy.ext.asyncio import AsyncSession
@@ -15,9 +16,10 @@ from common.aspect.pre_auth import CurrentUserDependency, PreAuthDependency
from common.enums import BusinessType
from common.vo import DataResponseModel, DynamicResponseModel, PageResponseModel, ResponseBaseModel
from config.env import UploadConfig
from module_admin.entity.vo.dept_vo import DeptModel
from module_admin.entity.vo.dept_vo import DeptModel, DeptTreeModel
from module_admin.entity.vo.user_vo import (
AddUserModel,
AvatarModel,
CrudUserRoleModel,
CurrentUserModel,
DeleteUserModel,
@@ -31,6 +33,7 @@ from module_admin.entity.vo.user_vo import (
UserProfileModel,
UserRoleQueryModel,
UserRoleResponseModel,
UserRowModel,
)
from module_admin.service.dept_service import DeptService
from module_admin.service.role_service import RoleService
@@ -46,6 +49,7 @@ user_controller = APIRouter(prefix='/system/user', dependencies=[PreAuthDependen
@user_controller.get(
'/deptTree',
response_model=DataResponseModel[list[DeptTreeModel]],
dependencies=[UserInterfaceAuthDependency('system:user:list')],
)
async def get_system_dept_tree(
@@ -61,7 +65,7 @@ async def get_system_dept_tree(
@user_controller.get(
'/list',
response_model=PageResponseModel,
response_model=PageResponseModel[UserRowModel],
dependencies=[UserInterfaceAuthDependency('system:user:list')],
)
async def get_system_user_list(
@@ -247,12 +251,12 @@ async def query_detail_system_user_profile(
@user_controller.get(
'/{user_id}',
response_model=DataResponseModel[UserDetailModel],
response_model=DynamicResponseModel[UserDetailModel],
dependencies=[UserInterfaceAuthDependency('system:user:query')],
)
@user_controller.get(
'/',
response_model=UserDetailModel,
response_model=DynamicResponseModel[UserDetailModel],
dependencies=[UserInterfaceAuthDependency('system:user:query')],
)
async def query_detail_system_user(
@@ -270,7 +274,10 @@ async def query_detail_system_user(
return ResponseUtil.success(model_content=detail_user_result)
@user_controller.post('/profile/avatar')
@user_controller.post(
'/profile/avatar',
response_model=DynamicResponseModel[AvatarModel],
)
@Log(title='个人信息', business_type=BusinessType.UPDATE)
async def change_system_user_profile_avatar(
request: Request,
@@ -301,7 +308,7 @@ async def change_system_user_profile_avatar(
edit_user_result = await UserService.edit_user_services(query_db, edit_user)
logger.info(edit_user_result.message)
return ResponseUtil.success(dict_content={'imgUrl': edit_user.avatar}, msg=edit_user_result.message)
return ResponseUtil.success(model_content=AvatarModel(imgUrl=edit_user.avatar), msg=edit_user_result.message)
return ResponseUtil.failure(msg='上传图片异常,请联系管理员')
@@ -382,6 +389,15 @@ async def batch_import_system_user(
@user_controller.post(
'/importTemplate',
response_class=StreamingResponse,
responses={
200: {
'description': '流式返回导入用户模板excel文件',
'content': {
'application/octet-stream': {},
},
}
},
dependencies=[UserInterfaceAuthDependency('system:user:import')],
)
async def export_system_user_template(
@@ -395,6 +411,15 @@ async def export_system_user_template(
@user_controller.post(
'/export',
response_class=StreamingResponse,
responses={
200: {
'description': '流式返回用户列表excel文件',
'content': {
'application/octet-stream': {},
},
}
},
dependencies=[UserInterfaceAuthDependency('system:user:export')],
)
@Log(title='用户管理', business_type=BusinessType.EXPORT)
@@ -62,6 +62,19 @@ class DeptQueryModel(DeptModel):
end_time: Optional[str] = Field(default=None, description='结束时间')
class DeptTreeModel(BaseModel):
"""
部门树模型
"""
model_config = ConfigDict(alias_generator=to_camel)
id: int = Field(description='部门id')
label: str = Field(description='部门名称')
parent_id: int = Field(description='父部门id')
children: Optional[list['DeptTreeModel']] = Field(default=None, description='子部门树')
class DeleteDeptModel(BaseModel):
"""
删除部门模型
@@ -77,6 +77,19 @@ class MenuQueryModel(MenuModel):
end_time: Optional[str] = Field(default=None, description='结束时间')
class MenuTreeModel(BaseModel):
"""
菜单树模型
"""
model_config = ConfigDict(alias_generator=to_camel)
id: int = Field(description='菜单id')
label: str = Field(description='菜单名称')
parent_id: int = Field(description='父菜单id')
children: Optional[list['MenuTreeModel']] = Field(default=None, description='子菜单树')
class DeleteMenuModel(BaseModel):
"""
删除菜单模型
@@ -91,6 +91,14 @@ class UserModel(BaseModel):
self.get_phonenumber()
class UserRowModel(UserModel):
"""
用户列表行数据模型
"""
dept: Optional[DeptModel] = Field(default=None, description='部门信息')
class UserRoleModel(BaseModel):
"""
用户和角色关联表对应pydantic模型
@@ -156,6 +164,16 @@ class UserProfileModel(BaseModel):
role_group: Union[str, None] = Field(description='角色信息')
class AvatarModel(BaseModel):
"""
上传头像响应模型
"""
model_config = ConfigDict(alias_generator=to_camel)
img_url: str = Field(description='头像地址')
class UserQueryModel(UserModel):
"""
用户管理不分页查询模型
@@ -8,7 +8,7 @@ from common.vo import CrudResponseModel
from exceptions.exception import ServiceException, ServiceWarning
from module_admin.dao.dept_dao import DeptDao
from module_admin.entity.do.dept_do import SysDept
from module_admin.entity.vo.dept_vo import DeleteDeptModel, DeptModel
from module_admin.entity.vo.dept_vo import DeleteDeptModel, DeptModel, DeptTreeModel
from utils.common_util import CamelCaseUtil
@@ -20,7 +20,7 @@ class DeptService:
@classmethod
async def get_dept_tree_services(
cls, query_db: AsyncSession, page_object: DeptModel, data_scope_sql: str
) -> list[dict[str, Any]]:
) -> list[dict[str,Any]]:
"""
获取部门树信息service
@@ -30,7 +30,8 @@ class DeptService:
:return: 部门树信息对象
"""
dept_list_result = await DeptDao.get_dept_list_for_tree(query_db, page_object, data_scope_sql)
dept_tree_result = cls.list_to_tree(dept_list_result)
dept_tree_model_result = cls.list_to_tree(dept_list_result)
dept_tree_result = [dept.model_dump(exclude_unset=True, by_alias=True) for dept in dept_tree_model_result]
return dept_tree_result
@@ -205,7 +206,7 @@ class DeptService:
return result
@classmethod
def list_to_tree(cls, permission_list: Sequence[SysDept]) -> list[dict[str, Any]]:
def list_to_tree(cls, permission_list: Sequence[SysDept]) -> list[DeptTreeModel]:
"""
工具方法根据部门列表信息生成树形嵌套数据
@@ -213,25 +214,25 @@ class DeptService:
:return: 部门树形嵌套数据
"""
_permission_list = [
{'id': item.dept_id, 'label': item.dept_name, 'parentId': item.parent_id} for item in permission_list
DeptTreeModel(id=item.dept_id, label=item.dept_name, parentId=item.parent_id) for item in permission_list
]
# 转成id为key的字典
mapping: dict[int, dict[str, Any]] = dict(zip([i['id'] for i in _permission_list], _permission_list))
mapping: dict[int, DeptTreeModel] = dict(zip([i.id for i in _permission_list], _permission_list))
# 树容器
container: list[dict[str, Any]] = []
container: list[DeptTreeModel] = []
for d in _permission_list:
# 如果找不到父级项,则是根节点
parent = mapping.get(d['parentId'])
parent = mapping.get(d.parent_id)
if parent is None:
container.append(d)
else:
children: list[dict[str, Any]] = parent.get('children')
children: list[DeptTreeModel] = parent.children
if not children:
children = []
children.append(d)
parent.update({'children': children})
parent.children = children
return container
@@ -9,7 +9,7 @@ from exceptions.exception import ServiceException, ServiceWarning
from module_admin.dao.menu_dao import MenuDao
from module_admin.dao.role_dao import RoleDao
from module_admin.entity.do.menu_do import SysMenu
from module_admin.entity.vo.menu_vo import DeleteMenuModel, MenuModel, MenuQueryModel
from module_admin.entity.vo.menu_vo import DeleteMenuModel, MenuModel, MenuQueryModel, MenuTreeModel
from module_admin.entity.vo.role_vo import RoleMenuQueryModel
from module_admin.entity.vo.user_vo import CurrentUserModel
from utils.common_util import CamelCaseUtil
@@ -35,7 +35,8 @@ class MenuService:
menu_list_result = await MenuDao.get_menu_list_for_tree(
query_db, current_user.user.user_id, current_user.user.role
)
menu_tree_result = cls.list_to_tree(menu_list_result)
menu_tree_model_result = cls.list_to_tree(menu_list_result)
menu_tree_result = [menu.model_dump(exclude_unset=True, by_alias=True) for menu in menu_tree_model_result]
return menu_tree_result
@@ -185,7 +186,7 @@ class MenuService:
return result
@classmethod
def list_to_tree(cls, permission_list: Sequence[SysMenu]) -> list[dict[str, Any]]:
def list_to_tree(cls, permission_list: Sequence[SysMenu]) -> list[MenuTreeModel]:
"""
工具方法根据菜单列表信息生成树形嵌套数据
@@ -193,24 +194,24 @@ class MenuService:
:return: 菜单树形嵌套数据
"""
_permission_list = [
{'id': item.menu_id, 'label': item.menu_name, 'parentId': item.parent_id} for item in permission_list
MenuTreeModel(id=item.menu_id, label=item.menu_name, parentId=item.parent_id) for item in permission_list
]
# 转成id为key的字典
mapping: dict[int, dict[str, Any]] = dict(zip([i['id'] for i in _permission_list], _permission_list))
mapping: dict[int, MenuTreeModel] = dict(zip([i.id for i in _permission_list], _permission_list))
# 树容器
container: list[dict[str, Any]] = []
container: list[MenuTreeModel] = []
for d in _permission_list:
# 如果找不到父级项,则是根节点
parent = mapping.get(d['parentId'])
parent = mapping.get(d.parent_id)
if parent is None:
container.append(d)
else:
children: list[dict[str, Any]] = parent.get('children')
children: list[MenuTreeModel] = parent.children
if not children:
children = []
children.append(d)
parent.update({'children': children})
parent.children = children
return container
@@ -318,7 +318,7 @@ class RoleService:
query_user_list = await UserDao.get_user_role_allocated_list_by_role_id(
query_db, page_object, data_scope_sql, is_page
)
allocated_list = PageModel(
allocated_list = PageModel[UserInfoModel](
**{
**query_user_list.model_dump(by_alias=True),
'rows': [UserInfoModel(**row) for row in query_user_list.rows],
@@ -343,7 +343,7 @@ class RoleService:
query_user_list = await UserDao.get_user_role_unallocated_list_by_role_id(
query_db, page_object, data_scope_sql, is_page
)
unallocated_list = PageModel(
unallocated_list = PageModel[UserInfoModel](
**{
**query_user_list.model_dump(by_alias=True),
'rows': [UserInfoModel(**row) for row in query_user_list.rows],
@@ -29,6 +29,7 @@ from module_admin.entity.vo.user_vo import (
UserRoleModel,
UserRoleQueryModel,
UserRoleResponseModel,
UserRowModel,
)
from module_admin.service.config_service import ConfigService
from module_admin.service.dept_service import DeptService
@@ -47,7 +48,7 @@ class UserService:
@classmethod
async def get_user_list_services(
cls, query_db: AsyncSession, query_object: UserPageQueryModel, data_scope_sql: str, is_page: bool = False
) -> Union[PageModel, list[dict[str, Any]]]:
) -> Union[PageModel[UserRowModel], list[dict[str, Any]]]:
"""
获取用户列表信息service
@@ -59,7 +60,7 @@ class UserService:
"""
query_result = await UserDao.get_user_list(query_db, query_object, data_scope_sql, is_page)
if is_page:
user_list_result = PageModel(
user_list_result = PageModel[UserRowModel](
**{
**query_result.model_dump(by_alias=True),
'rows': [{**row[0], 'dept': row[1]} for row in query_result.rows],
@@ -2,6 +2,7 @@ from datetime import datetime
from typing import Annotated
from fastapi import APIRouter, Path, Query, Request, Response
from fastapi.responses import StreamingResponse
from pydantic_validation_decorator import ValidateFields
from sqlalchemy.ext.asyncio import AsyncSession
@@ -10,10 +11,17 @@ from common.aspect.db_seesion import DBSessionDependency
from common.aspect.interface_auth import RoleInterfaceAuthDependency, UserInterfaceAuthDependency
from common.aspect.pre_auth import CurrentUserDependency, PreAuthDependency
from common.enums import BusinessType
from common.vo import PageResponseModel
from common.vo import DataResponseModel, PageResponseModel, ResponseBaseModel
from config.env import GenConfig
from module_admin.entity.vo.user_vo import CurrentUserModel
from module_generator.entity.vo.gen_vo import DeleteGenTableModel, EditGenTableModel, GenTablePageQueryModel
from module_generator.entity.vo.gen_vo import (
DeleteGenTableModel,
EditGenTableModel,
GenTableDbRowModel,
GenTableDetailModel,
GenTablePageQueryModel,
GenTableRowModel,
)
from module_generator.service.gen_service import GenTableColumnService, GenTableService
from utils.common_util import bytes2file_response
from utils.log_util import logger
@@ -24,7 +32,7 @@ gen_controller = APIRouter(prefix='/tool/gen', dependencies=[PreAuthDependency()
@gen_controller.get(
'/list',
response_model=PageResponseModel,
response_model=PageResponseModel[GenTableRowModel],
dependencies=[UserInterfaceAuthDependency('tool:gen:list')],
)
async def get_gen_table_list(
@@ -41,7 +49,7 @@ async def get_gen_table_list(
@gen_controller.get(
'/db/list',
response_model=PageResponseModel,
response_model=PageResponseModel[GenTableDbRowModel],
dependencies=[UserInterfaceAuthDependency('tool:gen:list')],
)
async def get_gen_db_table_list(
@@ -58,6 +66,7 @@ async def get_gen_db_table_list(
@gen_controller.post(
'/importTable',
response_model=ResponseBaseModel,
dependencies=[UserInterfaceAuthDependency('tool:gen:import')],
)
@Log(title='代码生成', business_type=BusinessType.IMPORT)
@@ -77,6 +86,7 @@ async def import_gen_table(
@gen_controller.put(
'',
response_model=ResponseBaseModel,
dependencies=[UserInterfaceAuthDependency('tool:gen:edit')],
)
@ValidateFields(validate_model='edit_gen_table')
@@ -98,6 +108,7 @@ async def edit_gen_table(
@gen_controller.delete(
'/{table_ids}',
response_model=ResponseBaseModel,
dependencies=[UserInterfaceAuthDependency('tool:gen:remove')],
)
@Log(title='代码生成', business_type=BusinessType.DELETE)
@@ -115,6 +126,7 @@ async def delete_gen_table(
@gen_controller.post(
'/createTable',
response_model=ResponseBaseModel,
dependencies=[RoleInterfaceAuthDependency('admin')],
)
@Log(title='创建表', business_type=BusinessType.OTHER)
@@ -132,6 +144,15 @@ async def create_table(
@gen_controller.get(
'/batchGenCode',
response_class=StreamingResponse,
responses={
200: {
'description': '流式返回生成的代码文件',
'content': {
'application/octet-stream': {},
},
}
},
dependencies=[UserInterfaceAuthDependency('tool:gen:code')],
)
@Log(title='代码生成', business_type=BusinessType.GENCODE)
@@ -149,6 +170,7 @@ async def batch_gen_code(
@gen_controller.get(
'/genCode/{table_name}',
response_model=ResponseBaseModel,
dependencies=[UserInterfaceAuthDependency('tool:gen:code')],
)
@Log(title='代码生成', business_type=BusinessType.GENCODE)
@@ -168,6 +190,7 @@ async def gen_code_local(
@gen_controller.get(
'/{table_id}',
response_model=DataResponseModel[GenTableDetailModel],
dependencies=[UserInterfaceAuthDependency('tool:gen:query')],
)
async def query_detail_gen_table(
@@ -186,6 +209,7 @@ async def query_detail_gen_table(
@gen_controller.get(
'/preview/{table_id}',
response_model=DataResponseModel[dict[str, str]],
dependencies=[UserInterfaceAuthDependency('tool:gen:preview')],
)
async def preview_code(
@@ -201,6 +225,7 @@ async def preview_code(
@gen_controller.get(
'/synchDb/{table_name}',
response_model=DataResponseModel[str],
dependencies=[UserInterfaceAuthDependency('tool:gen:edit')],
)
@Log(title='代码生成', business_type=BusinessType.UPDATE)
@@ -81,6 +81,27 @@ class GenTableBaseModel(BaseModel):
self.get_function_author()
class GenTableRowModel(GenTableBaseModel):
"""
代码生成业务表行数据模型
"""
columns: Optional[list['GenTableColumnBaseModel']] = Field(default=None, description='表列信息')
class GenTableDbRowModel(BaseModel):
"""
代码生成业务表数据库行数据模型
"""
model_config = ConfigDict(alias_generator=to_camel)
table_name: Optional[str] = Field(default=None, description='表名称')
table_comment: Optional[str] = Field(default=None, description='表描述')
create_time: Optional[datetime] = Field(default=None, description='创建时间')
update_time: Optional[datetime] = Field(default=None, description='更新时间')
class GenTableModel(GenTableBaseModel):
"""
代码生成业务表模型
@@ -145,6 +166,18 @@ class GenTablePageQueryModel(GenTableQueryModel):
page_size: int = Field(default=10, description='每页记录数')
class GenTableDetailModel(BaseModel):
"""
代码生成业务表详情模型
"""
model_config = ConfigDict(alias_generator=to_camel)
info: Optional[GenTableModel] = Field(default=None, description='业务表信息')
rows: Optional[list['GenTableColumnModel']] = Field(default=None, description='表列信息')
tables: Optional[list['GenTableModel']] = Field(default=None, description='所有业务表信息')
class DeleteGenTableModel(BaseModel):
"""
删除代码生成业务表模型
@@ -14,6 +14,7 @@ from datetime import datetime
from typing import Annotated
from fastapi import APIRouter, Form, Path, Query, Request, Response
from fastapi.responses import StreamingResponse
from pydantic_validation_decorator import ValidateFields
from sqlalchemy.ext.asyncio import AsyncSession
@@ -150,6 +151,15 @@ async def query_detail_{{ moduleName }}_{{ businessName }}(
@{{ businessName }}_controller.post(
'/export',
response_class=StreamingResponse,
responses={
200: {
'description': '流式返回{{ functionName }}列表excel文件',
'content': {
'application/octet-stream': {},
},
}
},
dependencies=[UserInterfaceAuthDependency('{{ permissionPrefix }}:export')],
)
@Log(title='{{ functionName }}', business_type=BusinessType.EXPORT)