Files
FastapiAdmin/backend/app/api/v1/module_monitor/resource/controller.py
T
zhangtao 837d8a5aa7 feat: 优化代码生成器功能并修复多个问题
- 前端表格列添加溢出提示工具
- 后端登录IP归属地查询与设置统一处理
- 分页服务明确仅用于非SQL数据源场景
- 代码生成器添加字段筛选和帮助面板
- 修复菜单高亮和布局切换问题
- 更新文档中的BUG状态和解决方案
- 优化AI聊天界面样式和交互
- 添加数据库分页支持到多个模块
- 代码生成器表单校验和流程优化
- 修复PostgreSQL日期类型问题
2026-03-30 00:37:16 +08:00

276 lines
8.6 KiB
Python

from typing import Annotated
from fastapi import APIRouter, Body, Depends, Form, Query, Request, UploadFile
from fastapi.responses import FileResponse, JSONResponse, StreamingResponse
from app.common.request import PaginationService
from app.common.response import ResponseSchema, StreamResponse, SuccessResponse, UploadFileResponse
from app.core.base_params import PaginationQueryParam
from app.core.dependencies import AuthPermission
from app.core.logger import log
from app.core.router_class import OperationLogRoute
from app.utils.common_util import bytes2file_response
from .schema import (
ResourceCopySchema,
ResourceCreateDirSchema,
ResourceMoveSchema,
ResourceRenameSchema,
ResourceSearchQueryParam,
)
from .service import ResourceService
ResourceRouter = APIRouter(route_class=OperationLogRoute, prefix="/resource", tags=["资源管理"])
@ResourceRouter.get(
"/list",
summary="获取目录列表",
description="获取指定目录下的文件和子目录列表",
response_model=ResponseSchema[list[dict]],
dependencies=[Depends(AuthPermission(["module_monitor:resource:query"]))],
)
async def get_directory_list_controller(
request: Request,
page: Annotated[PaginationQueryParam, Depends()],
search: Annotated[ResourceSearchQueryParam, Depends()],
) -> JSONResponse:
"""
获取目录列表
参数:
- request (Request): FastAPI请求对象,用于获取基础URL。
- page (PaginationQueryParam): 分页查询参数模型。
- search (ResourceSearchQueryParam): 资源查询参数模型。
返回:
- JSONResponse: 包含目录列表的JSON响应。
"""
# 获取资源列表(与案例模块保持一致的分页实现)
result_dict_list = await ResourceService.get_resources_list_service(
search=search, base_url=str(request.base_url)
)
# 目录列表来自本地文件系统扫描,无 SQL 分页
result_dict = await PaginationService.paginate(
data_list=result_dict_list,
page_no=page.page_no,
page_size=page.page_size,
)
log.info(f"获取目录列表成功: {getattr(search, 'name', None) or ''}")
return SuccessResponse(data=result_dict, msg="获取目录列表成功")
@ResourceRouter.post(
"/upload",
summary="上传文件",
description="上传文件到指定目录",
response_model=ResponseSchema[dict],
dependencies=[Depends(AuthPermission(["module_monitor:resource:upload"]))],
)
async def upload_file_controller(
file: UploadFile,
request: Request,
target_path: Annotated[str | None, Form(description="目标目录路径")] = None,
) -> JSONResponse:
"""
上传文件
参数:
- file (UploadFile): 要上传的文件对象。
- request (Request): FastAPI请求对象,用于获取基础URL。
- target_path (str | None): 目标目录路径,默认为None。
返回:
- JSONResponse: 包含上传文件信息的JSON响应。
"""
result_dict = await ResourceService.upload_file_service(
file=file, target_path=target_path, base_url=str(request.base_url)
)
log.info(f"上传文件成功: {result_dict['filename']}")
return SuccessResponse(data=result_dict, msg="上传文件成功")
@ResourceRouter.get(
"/download",
summary="下载文件",
description="下载指定文件",
dependencies=[Depends(AuthPermission(["module_monitor:resource:download"]))],
)
async def download_file_controller(
request: Request, path: Annotated[str, Query(description="文件路径")]
) -> FileResponse:
"""
下载文件
参数:
- request (Request): FastAPI请求对象,用于获取基础URL。
- path (str): 文件路径。
返回:
- FileResponse: 包含文件内容的文件响应。
"""
file_path = await ResourceService.download_file_service(
file_path=path, base_url=str(request.base_url)
)
# 获取文件名
import os
filename = os.path.basename(file_path)
log.info(f"下载文件成功: {filename}")
return UploadFileResponse(
file_path=file_path,
filename=filename,
media_type="application/octet-stream",
)
@ResourceRouter.delete(
"/delete",
summary="删除文件",
description="删除指定文件或目录",
response_model=ResponseSchema[None],
dependencies=[Depends(AuthPermission(["module_monitor:resource:delete"]))],
)
async def delete_files_controller(
paths: Annotated[list[str], Body(description="文件路径列表")],
) -> JSONResponse:
"""
删除文件
参数:
- paths (list[str]): 文件路径列表。
返回:
- JSONResponse: 包含删除结果的JSON响应。
"""
await ResourceService.delete_file_service(paths=paths)
log.info(f"删除文件成功: {paths}")
return SuccessResponse(msg="删除文件成功")
@ResourceRouter.post(
"/move",
summary="移动文件",
description="移动文件或目录",
response_model=ResponseSchema[None],
dependencies=[Depends(AuthPermission(["module_monitor:resource:move"]))],
)
async def move_file_controller(data: ResourceMoveSchema) -> JSONResponse:
"""
移动文件
参数:
- data (ResourceMoveSchema): 移动文件参数模型。
返回:
- JSONResponse: 包含移动结果的JSON响应。
"""
await ResourceService.move_file_service(data=data)
log.info(f"移动文件成功: {data.source_path} -> {data.target_path}")
return SuccessResponse(msg="移动文件成功")
@ResourceRouter.post(
"/copy",
summary="复制文件",
description="复制文件或目录",
response_model=ResponseSchema[None],
dependencies=[Depends(AuthPermission(["module_monitor:resource:copy"]))],
)
async def copy_file_controller(data: ResourceCopySchema) -> JSONResponse:
"""
复制文件
参数:
- data (ResourceCopySchema): 复制文件参数模型。
返回:
- JSONResponse: 包含复制结果的JSON响应。
"""
await ResourceService.copy_file_service(data=data)
log.info(f"复制文件成功: {data.source_path} -> {data.target_path}")
return SuccessResponse(msg="复制文件成功")
@ResourceRouter.post(
"/rename",
summary="重命名文件",
description="重命名文件或目录",
response_model=ResponseSchema[None],
dependencies=[Depends(AuthPermission(["module_monitor:resource:rename"]))],
)
async def rename_file_controller(data: ResourceRenameSchema) -> JSONResponse:
"""
重命名文件
参数:
- data (ResourceRenameSchema): 重命名文件参数模型。
返回:
- JSONResponse: 包含重命名结果的JSON响应。
"""
await ResourceService.rename_file_service(data=data)
log.info(f"重命名文件成功: {data.old_path} -> {data.new_name}")
return SuccessResponse(msg="重命名文件成功")
@ResourceRouter.post(
"/create-dir",
summary="创建目录",
description="在指定路径创建新目录",
response_model=ResponseSchema[None],
dependencies=[Depends(AuthPermission(["module_monitor:resource:create_dir"]))],
)
async def create_directory_controller(
data: ResourceCreateDirSchema,
) -> JSONResponse:
"""
创建目录
参数:
- data (ResourceCreateDirSchema): 创建目录参数模型。
返回:
- JSONResponse: 包含创建目录结果的JSON响应。
"""
await ResourceService.create_directory_service(data=data)
log.info(f"创建目录成功: {data.parent_path}/{data.dir_name}")
return SuccessResponse(msg="创建目录成功")
@ResourceRouter.post(
"/export",
summary="导出资源列表",
description="导出资源列表",
response_model=ResponseSchema[None],
dependencies=[Depends(AuthPermission(["module_monitor:resource:export"]))],
)
async def export_resource_list_controller(
request: Request, search: Annotated[ResourceSearchQueryParam, Depends()]
) -> StreamingResponse:
"""
导出资源列表
参数:
- request (Request): FastAPI请求对象,用于获取基础URL。
- search (ResourceSearchQueryParam): 资源查询参数模型。
返回:
- StreamingResponse: 包含导出资源列表的流式响应。
"""
# 获取搜索结果
result_dict_list = await ResourceService.get_resources_list_service(
search=search, base_url=str(request.base_url)
)
export_result = await ResourceService.export_resource_service(data_list=result_dict_list)
log.info("导出资源列表成功")
return StreamResponse(
data=bytes2file_response(export_result),
media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
headers={"Content-Disposition": "attachment; filename=resource_list.xlsx"},
)