feat: 完善前后端核心功能模块
后端: - 新增认证(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 数据库迁移配置 - 添加初始化示例数据脚本 - 更新项目文档
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
"""
|
||||
导出 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,
|
||||
}
|
||||
Reference in New Issue
Block a user