controller.py 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. # -*- coding: utf-8 -*-
  2. from fastapi import APIRouter, Body, Depends, Query, Request, UploadFile, Form
  3. from fastapi.responses import JSONResponse, StreamingResponse, FileResponse
  4. from app.common.response import StreamResponse, SuccessResponse
  5. from app.common.request import PaginationService
  6. from app.core.router_class import OperationLogRoute
  7. from app.utils.common_util import bytes2file_response
  8. from app.core.base_params import PaginationQueryParam
  9. from app.core.dependencies import AuthPermission
  10. from app.core.logger import log
  11. from .service import ResourceService
  12. from .schema import (
  13. ResourceMoveSchema,
  14. ResourceCopySchema,
  15. ResourceRenameSchema,
  16. ResourceCreateDirSchema,
  17. ResourceSearchQueryParam
  18. )
  19. ResourceRouter = APIRouter(route_class=OperationLogRoute, prefix="/resource", tags=["资源管理"])
  20. @ResourceRouter.get(
  21. "/list",
  22. summary="获取目录列表",
  23. description="获取指定目录下的文件和子目录列表",
  24. dependencies=[Depends(AuthPermission(["module_monitor:resource:query"]))]
  25. )
  26. async def get_directory_list_controller(
  27. request: Request,
  28. page: PaginationQueryParam = Depends(),
  29. search: ResourceSearchQueryParam = Depends(),
  30. ) -> JSONResponse:
  31. """
  32. 获取目录列表
  33. 参数:
  34. - request (Request): FastAPI请求对象,用于获取基础URL。
  35. - page (PaginationQueryParam): 分页查询参数模型。
  36. - search (ResourceSearchQueryParam): 资源查询参数模型。
  37. 返回:
  38. - JSONResponse: 包含目录列表的JSON响应。
  39. """
  40. # 获取资源列表(与案例模块保持一致的分页实现)
  41. result_dict_list = await ResourceService.get_resources_list_service(
  42. search=search,
  43. base_url=str(request.base_url)
  44. )
  45. # 使用分页服务进行分页处理(与案例模块保持一致)
  46. result_dict = await PaginationService.paginate(
  47. data_list=result_dict_list,
  48. page_no=page.page_no,
  49. page_size=page.page_size
  50. )
  51. log.info(f"获取目录列表成功: {getattr(search, 'name', None) or ''}")
  52. return SuccessResponse(data=result_dict, msg="获取目录列表成功")
  53. @ResourceRouter.post(
  54. "/upload",
  55. summary="上传文件",
  56. description="上传文件到指定目录",
  57. dependencies=[Depends(AuthPermission(["module_monitor:resource:upload"]))])
  58. async def upload_file_controller(
  59. file: UploadFile,
  60. request: Request,
  61. target_path: str | None = Form(None, description="目标目录路径")
  62. ) -> JSONResponse:
  63. """
  64. 上传文件
  65. 参数:
  66. - file (UploadFile): 要上传的文件对象。
  67. - request (Request): FastAPI请求对象,用于获取基础URL。
  68. - target_path (str | None): 目标目录路径,默认为None。
  69. 返回:
  70. - JSONResponse: 包含上传文件信息的JSON响应。
  71. """
  72. result_dict = await ResourceService.upload_file_service(
  73. file=file,
  74. target_path=target_path,
  75. base_url=str(request.base_url)
  76. )
  77. log.info(f"上传文件成功: {result_dict['filename']}")
  78. return SuccessResponse(data=result_dict, msg="上传文件成功")
  79. @ResourceRouter.get(
  80. "/download",
  81. summary="下载文件",
  82. description="下载指定文件",
  83. dependencies=[Depends(AuthPermission(["module_monitor:resource:download"]))]
  84. )
  85. async def download_file_controller(
  86. request: Request,
  87. path: str = Query(..., description="文件路径")
  88. ) -> FileResponse:
  89. """
  90. 下载文件
  91. 参数:
  92. - request (Request): FastAPI请求对象,用于获取基础URL。
  93. - path (str): 文件路径。
  94. 返回:
  95. - FileResponse: 包含文件内容的文件响应。
  96. """
  97. file_path = await ResourceService.download_file_service(
  98. file_path=path,
  99. base_url=str(request.base_url)
  100. )
  101. # 获取文件名
  102. import os
  103. filename = os.path.basename(file_path)
  104. log.info(f"下载文件成功: {filename}")
  105. return FileResponse(
  106. path=file_path,
  107. filename=filename,
  108. media_type='application/octet-stream'
  109. )
  110. @ResourceRouter.delete(
  111. "/delete",
  112. summary="删除文件",
  113. description="删除指定文件或目录",
  114. dependencies=[Depends(AuthPermission(["module_monitor:resource:delete"]))]
  115. )
  116. async def delete_files_controller(
  117. paths: list[str] = Body(..., description="文件路径列表")
  118. ) -> JSONResponse:
  119. """
  120. 删除文件
  121. 参数:
  122. - paths (list[str]): 文件路径列表。
  123. 返回:
  124. - JSONResponse: 包含删除结果的JSON响应。
  125. """
  126. await ResourceService.delete_file_service(paths=paths)
  127. log.info(f"删除文件成功: {paths}")
  128. return SuccessResponse(msg="删除文件成功")
  129. @ResourceRouter.post(
  130. "/move",
  131. summary="移动文件",
  132. description="移动文件或目录",
  133. dependencies=[Depends(AuthPermission(["module_monitor:resource:move"]))]
  134. )
  135. async def move_file_controller(
  136. data: ResourceMoveSchema
  137. ) -> JSONResponse:
  138. """
  139. 移动文件
  140. 参数:
  141. - data (ResourceMoveSchema): 移动文件参数模型。
  142. 返回:
  143. - JSONResponse: 包含移动结果的JSON响应。
  144. """
  145. await ResourceService.move_file_service(data=data)
  146. log.info(f"移动文件成功: {data.source_path} -> {data.target_path}")
  147. return SuccessResponse(msg="移动文件成功")
  148. @ResourceRouter.post(
  149. "/copy",
  150. summary="复制文件",
  151. description="复制文件或目录",
  152. dependencies=[Depends(AuthPermission(["module_monitor:resource:copy"]))]
  153. )
  154. async def copy_file_controller(
  155. data: ResourceCopySchema
  156. ) -> JSONResponse:
  157. """
  158. 复制文件
  159. 参数:
  160. - data (ResourceCopySchema): 复制文件参数模型。
  161. 返回:
  162. - JSONResponse: 包含复制结果的JSON响应。
  163. """
  164. await ResourceService.copy_file_service(data=data)
  165. log.info(f"复制文件成功: {data.source_path} -> {data.target_path}")
  166. return SuccessResponse(msg="复制文件成功")
  167. @ResourceRouter.post(
  168. "/rename",
  169. summary="重命名文件",
  170. description="重命名文件或目录",
  171. dependencies=[Depends(AuthPermission(["module_monitor:resource:rename"]))]
  172. )
  173. async def rename_file_controller(
  174. data: ResourceRenameSchema
  175. ) -> JSONResponse:
  176. """
  177. 重命名文件
  178. 参数:
  179. - data (ResourceRenameSchema): 重命名文件参数模型。
  180. 返回:
  181. - JSONResponse: 包含重命名结果的JSON响应。
  182. """
  183. await ResourceService.rename_file_service(data=data)
  184. log.info(f"重命名文件成功: {data.old_path} -> {data.new_name}")
  185. return SuccessResponse(msg="重命名文件成功")
  186. @ResourceRouter.post(
  187. "/create-dir",
  188. summary="创建目录",
  189. description="在指定路径创建新目录",
  190. dependencies=[Depends(AuthPermission(["module_monitor:resource:create_dir"]))]
  191. )
  192. async def create_directory_controller(
  193. data: ResourceCreateDirSchema
  194. ) -> JSONResponse:
  195. """
  196. 创建目录
  197. 参数:
  198. - data (ResourceCreateDirSchema): 创建目录参数模型。
  199. 返回:
  200. - JSONResponse: 包含创建目录结果的JSON响应。
  201. """
  202. await ResourceService.create_directory_service(data=data)
  203. log.info(f"创建目录成功: {data.parent_path}/{data.dir_name}")
  204. return SuccessResponse(msg="创建目录成功")
  205. @ResourceRouter.post(
  206. "/export",
  207. summary="导出资源列表",
  208. description="导出资源列表",
  209. dependencies=[Depends(AuthPermission(["module_monitor:resource:export"]))]
  210. )
  211. async def export_resource_list_controller(
  212. request: Request,
  213. search: ResourceSearchQueryParam = Depends()
  214. ) -> StreamingResponse:
  215. """
  216. 导出资源列表
  217. 参数:
  218. - request (Request): FastAPI请求对象,用于获取基础URL。
  219. - search (ResourceSearchQueryParam): 资源查询参数模型。
  220. 返回:
  221. - StreamingResponse: 包含导出资源列表的流式响应。
  222. """
  223. # 获取搜索结果
  224. result_dict_list = await ResourceService.get_resources_list_service(
  225. search=search,
  226. base_url=str(request.base_url)
  227. )
  228. export_result = await ResourceService.export_resource_service(data_list=result_dict_list)
  229. log.info("导出资源列表成功")
  230. return StreamResponse(
  231. data=bytes2file_response(export_result),
  232. media_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  233. headers={
  234. 'Content-Disposition': 'attachment; filename=resource_list.xlsx'
  235. }
  236. )