33b4c734aa
后端: - 新增认证(auth)、任务(tasks)、映射(mappings)、对账(reconciliation)、异常(exceptions)、导出(exports) API - 新增核心模块: database, security, permissions, tenant, exceptions, error_handlers - 新增数据模型: user, company, reconciliation_task, field_mapping, uploaded_file 等 - 新增服务层: ai_recognizer, file_parser, file_storage, mapping, reconciliation 等 - 添加数据库迁移脚本 前端: - 新增登录页面和仪表盘页面 - 新增任务列表、任务详情、字段映射页面 - 新增异常处理页面和规则设置页面 - 新增 API 代理路由 /api/[...path] - 新增 UI 组件库 (button, card, dialog, input, table 等) - 新增 auth 组件 (ProtectedRoute, PermissionGate) - 新增 layout 组件 (Header, Sidebar) - 新增 mapping 组件 (FieldMappingTable, AISuggestionPanel) - 新增 API 客户端和 hooks (useAsync, useToast, usePermission 等) - 新增状态管理 (auth-store, company-store, ui-store) - 集成 Tailwind CSS 和 shadcn/ui 组件库 其他: - 添加 Alembic 数据库迁移配置 - 添加初始化示例数据脚本 - 更新项目文档
95 lines
2.7 KiB
Python
95 lines
2.7 KiB
Python
"""
|
|
导出 API
|
|
|
|
提供对账结果导出、金蝶凭证导出等接口
|
|
"""
|
|
|
|
from typing import Any, Dict
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException, BackgroundTasks
|
|
from fastapi.responses import StreamingResponse
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.core.database import get_db
|
|
from app.core.tenant import get_current_company_id
|
|
from app.services.export_service import export_task_result, export_kingdee_voucher
|
|
|
|
|
|
router = APIRouter(prefix="/api/exports", tags=["导出"])
|
|
|
|
|
|
@router.get("/task/{task_id}")
|
|
async def export_task(
|
|
task_id: int,
|
|
db: AsyncSession = Depends(get_db),
|
|
company_id: int = Depends(get_current_company_id),
|
|
):
|
|
"""
|
|
导出任务对账结果
|
|
|
|
返回 Excel 文件,包含:
|
|
- 概览
|
|
- 异常列表
|
|
- 异常统计
|
|
"""
|
|
try:
|
|
data = await export_task_result(db, task_id)
|
|
|
|
return StreamingResponse(
|
|
iter([data]),
|
|
media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
headers={
|
|
"Content-Disposition": f"attachment; filename=对账结果_{task_id}.xlsx"
|
|
},
|
|
)
|
|
except ValueError as e:
|
|
raise HTTPException(status_code=404, detail=str(e))
|
|
except ImportError as e:
|
|
raise HTTPException(status_code=500, detail="导出功能未启用,请安装 openpyxl")
|
|
|
|
|
|
@router.get("/kingdee/{task_id}")
|
|
async def export_kingdee(
|
|
task_id: int,
|
|
db: AsyncSession = Depends(get_db),
|
|
company_id: int = Depends(get_current_company_id),
|
|
):
|
|
"""
|
|
导出金蝶凭证
|
|
|
|
返回 Excel 文件,可导入到金蝶系统
|
|
"""
|
|
try:
|
|
data = await export_kingdee_voucher(db, task_id)
|
|
|
|
return StreamingResponse(
|
|
iter([data]),
|
|
media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
headers={
|
|
"Content-Disposition": f"attachment; filename=金蝶凭证_{task_id}.xlsx"
|
|
},
|
|
)
|
|
except ValueError as e:
|
|
raise HTTPException(status_code=404, detail=str(e))
|
|
except ImportError as e:
|
|
raise HTTPException(status_code=500, detail="导出功能未启用,请安装 openpyxl")
|
|
|
|
|
|
@router.post("/task/{task_id}/async")
|
|
async def export_task_async(
|
|
task_id: int,
|
|
background_tasks: BackgroundTasks,
|
|
db: AsyncSession = Depends(get_db),
|
|
company_id: int = Depends(get_current_company_id),
|
|
):
|
|
"""
|
|
异步导出任务对账结果
|
|
|
|
适用于大数据量导出的场景,返回导出任务ID
|
|
"""
|
|
# TODO: 实现异步导出任务
|
|
return {
|
|
"success": True,
|
|
"message": "异步导出任务已创建",
|
|
"task_id": task_id,
|
|
} |