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