Files
2026-06-25 17:41:06 +08:00

96 lines
3.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from fastapi import APIRouter, File, UploadFile, Query
from fastapi.responses import FileResponse
from app.schemas import Success, SuccessExtra, Fail
from app.controllers.finance_parse import task_controller, parse_finance_data
import os, time
from app.schemas.task import DecodeTaskParams, DecodeTaskResult, TaskResponse
from app.models.automation import TaskStatus, TaskType
from datetime import datetime
router = APIRouter()
import shutil
from pathlib import Path
from app.utils.excel_utils import get_sheets_and_headers
@router.post("/upload", summary="上传文件")
async def upload_file(file: UploadFile = File(...)):
# file.filename: 原始文件名
# file.content_type: MIME 类型
# file.file: 类文件对象(SpooledTemporaryFile
# 保存文件到本地(示例:保存到 ./uploads/)
upload_dir = Path("uploads")
upload_dir.mkdir(exist_ok=True)
filename = f"{datetime.now().strftime('%Y%m%d%H%M%S')}_{file.filename}"
file_path = upload_dir / filename
with open(file_path, "wb") as buffer:
shutil.copyfileobj(file.file, buffer)
# 获取所有 sheet 名称及其表头
sheets_headers = get_sheets_and_headers(file_path)
# # 打印结果
# for sheet_name, headers in sheets_headers.items():
# print(f"Sheet: {sheet_name}")
# print(f"Headers: {headers}\n")
data = {
"filename": filename,
"data": sheets_headers,
}
return Success(data=data)
@router.post("/parse", summary="解析文件")
async def parse_file(data: dict):
upload_dir = Path("uploads")
filename = upload_dir / data["filename"]
sheet = data["sheet"]
header = data["header"]
parse_type = data["parse_type"]
taskname = data["filename"] + "_" + sheet
print(filename, sheet, header, parse_type)
task, task_obj = await task_controller.create_task(name=taskname, obj_in=DecodeTaskParams(filename=str(filename), sheet_name=sheet, header=header, decode_type=parse_type))
total_amount = 0
start = time.time()
try:
result_file_path, total_amount = parse_finance_data(
filename,
target_index=header,
is_horizontal=(parse_type == "horizontal"),
sheet_name=sheet
)
except Exception as e:
return Fail(msg=f"解析失败: {str(e)}", code=400)
if not os.path.exists(result_file_path):
return Fail(msg=f"解析结果文件未生成", code=404)
# 提取原始文件名(不含路径),用于下载时的默认文件名
download_filename = os.path.basename(result_file_path)
await task_controller.update_task(task_obj, task.id, TaskStatus.SUCCESS, DecodeTaskResult(
filename=str(result_file_path),
spend=time.time() - start,
rows=total_amount,
))
return FileResponse(
path=result_file_path,
filename=download_filename, # 浏览器下载时显示的文件名
media_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' # .xlsx
)
@router.get("/list", summary="获取任务列表")
async def get_tasks(page: int = Query(1, description="页码"),
page_size: int = Query(10, description="每页数量"),
name: str = Query("", description="任务名称,用于查询"),
type: TaskType = Query(None, description="任务类型,用于查询")):
total, tasks = await task_controller.list(name, type, page, page_size)
data = [TaskResponse.from_orm(task).model_dump() for task in tasks]
return SuccessExtra(data=data, total=total, page=page, page_size=page_size)