docs(uiux): UIUX 设计方案大改 + 5 份作业指导书对齐 + 开发任务文档

- UIUX 文档:填充 19 个缺口(多主体画像/健康度/AI+看板/增长域/洞察域/创始人端/OODA/助推/商密)
- UIUX 文档:插入 6 个新章节(十四~十九),旧章节重编号为二十~三十一,更新目录和交叉引用
- 作业指导书 x5:导航改为 6 域分组,新增 Context Bar/工作模式/Insight Rail/决策线程/多工作区等 UI 概念
- 新建 docs/2-task-uiux.md:50 个代码落地开发任务,按 P0-P6 分优先级 + 8 Sprint 规划
- 后端/前端:大量新增模型、路由、组件(来自之前 Phase 开发)
This commit is contained in:
selfrelease
2026-07-19 11:53:38 +08:00
parent 734a16a7f3
commit fad458b2a7
243 changed files with 19898 additions and 658 deletions
+45 -1
View File
@@ -3,7 +3,7 @@
import json
from datetime import datetime, timezone
from fastapi import APIRouter, Depends, HTTPException, Query, status
from fastapi import APIRouter, Depends, HTTPException, Query, UploadFile, File, status
from fastapi.responses import StreamingResponse
from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession
@@ -24,7 +24,9 @@ from app.schemas.report import (
)
from app.services.ai_parser import parse_report
from app.services.health_calculator import calculate_health_score, determine_trend
from app.services.report_tracker import compute_timeliness
from app.services.risk_engine import detect_risks
from app.services.file_parser import parse_file
router = APIRouter(prefix="/reports", tags=["reports"])
@@ -369,3 +371,45 @@ async def parse_report_stream(
"X-Accel-Buffering": "no",
},
)
@router.get("/timeliness", response_model=ApiResponse[list])
async def get_timeliness(
company_id: str | None = Query(default=None),
db: AsyncSession = Depends(get_db),
user: User = Depends(get_current_user),
):
"""获取月报提交及时性和数据质量评分。"""
items = await compute_timeliness(db, user.tenant_id, company_id)
return success(data=items)
@router.post("/upload", response_model=ApiResponse[dict])
async def upload_report_file(
file: UploadFile = File(...),
user: User = Depends(get_current_user),
):
"""上传月报文件 — 自动解析提取文本内容。
支持 .xlsx、.pdf、.txt、.md、.csv 格式。
"""
if not file.filename:
raise HTTPException(status_code=400, detail="文件名不能为空")
allowed_extensions = {".xlsx", ".xls", ".pdf", ".txt", ".md", ".csv"}
ext = file.filename.rsplit(".", 1)[-1].lower() if "." in file.filename else ""
if f".{ext}" not in allowed_extensions:
raise HTTPException(status_code=400, detail=f"不支持的文件格式: .{ext}")
content = await file.read()
if len(content) > 10 * 1024 * 1024:
raise HTTPException(status_code=400, detail="文件大小不能超过 10MB")
extracted_text = await parse_file(content, file.filename)
return success(data={
"filename": file.filename,
"file_type": ext,
"extracted_text": extracted_text[:10000],
"char_count": len(extracted_text),
})