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:
freedakgmail
2026-07-07 09:04:47 +08:00
parent 8487f6eadf
commit 33b4c734aa
117 changed files with 22070 additions and 295 deletions
+95
View File
@@ -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,
}