装闭 RenoPit 源码解析(12):从AI分析结果到React避坑报告

设计分析、合同审查、增项预测和跨文档核查分别产生不同结构的数据,报告页却需要一次性展示它们。装闭 RenoPit 在开源仓库 fthux/RenoPit 中通过 /result 接口先统一后端数据,再由 React 按结果内容组合页面。

一、报告页只请求一个聚合接口

AnalysisPage.tsx 从路由参数取得项目 ID,调用:

tsx 复制代码
const res = await fetch(`${API}/projects/${projectId}/result`)
if (res.ok) setResult(await res.json())

页面不直接查询 Analysis、DocumentAnalysis 或交叉核查接口。数据拼装集中在后端,前端只消费 AnalysisResult。

get_analysis_result() 先确认项目存在,再按 Analysis.created_at 倒序获取最近一条分析。失败分析也会返回固定结构:评分和各级问题数量为零,summary_text 与 error_message 保存失败原因,使前端仍能进入统一的状态判断。

二、原始 AI JSON 如何变成 pitfalls

成功记录交给 _build_result_data()。它从 raw_result_json.problems 读取模型问题,再逐条转换成前端的 PitfallItem:

python 复制代码
pitfalls.append({
    "id": str(i + 1),
    "category": _infer_category(problem),
    "description": problem.get("title", ""),
    "severity": _infer_severity(problem),
    "location": problem.get("location"),
    "suggestion": problem.get("alternative", ""),
    "critique": problem.get("critique"),
    "trap_explanation": problem.get("trap_explanation"),
    "bbox": problem.get("bbox"),
})

严重程度通过标题和批判文本中的关键词推断。例如安全、坠落、火灾、漏电优先归为 critical;高额、陷阱、浪费归为 high;未命中时默认 medium。

类别同样采用关键词映射,依次识别卫生死角、空间压迫、安全健康、隐性成本和实用性伪需求,无法识别时返回"其他"。

三、评分和统计如何生成

如果模型返回的 summary 中带有 score,后端优先使用该值;否则根据问题数计算:

python 复制代码
score = 95 if problem_count == 0 else max(
    0, 100 - problem_count * 8
)

_count_severities() 再统计严重、高、中、低四类数量,组装 summary。因此前端无需遍历问题列表计算顶部统计卡。

页面将评分分为三个显示区间:80 分以上"优秀",60~79 分"待改进",低于 60 分"需重视"。这些标签只负责展示,原始分数仍来自后端结果。

四、文档结果如何合并

接口查询当前项目全部已完成的 DocumentAnalysis,按完成时间倒序交给 _serialize_document_analyses()。

序列化结果以 project_file_id 为键。同一文件如果被分析多次,只保留排序后的第一条,也就是最新结果。每条数据包含风险列表、分类置信度、总结、预估风险金额和可选的 extra_item_prediction。

最后,接口检查综合分析 JSON 中是否存在 cross_document_checks,存在就直接注入返回值。至此,一次响应已经包含报告页的全部章节。

五、React 如何决定显示哪些章节

AnalysisPage 根据数据动态创建导航项:

  • 总体评价、陷阱数、综合评分始终显示;
  • pitfalls 非空时显示问题详情;
  • 存在文档分析时显示合同与报价单;
  • 任一文档带增项预测时显示增项章节;
  • 存在差异项时显示跨文档核查。

页面使用 IntersectionObserver 观察这些章节,选择可见比例最高的部分更新 activeSection。桌面端显示可折叠的固定侧栏,移动端使用单独导航,点击后按照顶部偏移量平滑滚动。

六、问题详情如何渲染

每个 PitfallCard 根据 severityConfig 选择图标、颜色、背景和中文标签。卡片展示分类、位置、问题分析、套路说明与替代建议;后端没有提供的可选字段不会渲染空区域。

合同结果由文档风险区块展示,增项预测交给 ExtraPredictionPanel,跨文档结果交给 CrossCheckPanel。这些组件不再请求后端,只处理已经聚合到 result 中的数据。

加载、接口失败和分析失败也分别有独立页面状态。这样报告页不会在数据未准备好时尝试解构 summary 或 pitfalls。

七、报告数据链小结

RenoPit 的报告展示分成两层:后端把模型原始 JSON 转换为稳定的 AnalysisResult,React 再根据字段是否存在组合页面。评分、严重程度、最新文档结果和交叉核查都在 /result 这一条边界上汇合。

结果聚合函数、TypeScript 类型和报告组件可以在 fthux/RenoPit 中查看。下一篇将继续复用同一份结果数据,分析 RenoPit 如何使用 ReportLab 生成可下载的中文 PDF 报告。

相关推荐
桃西西呀10 分钟前
Laya 源码级原理拆解之一:整体架构与运行入口
人工智能·llm·ai编程
拉你进_教堂15 分钟前
小龙虾技能之【Intelligent Public Smoking Detection Skill | 公共场所吸烟行为智能检测技能】简介
人工智能·计算机视觉·多模态大模型·openclaw小龙虾技能
ShineWinsu19 分钟前
RAG 进阶:知识库构建优化全解析——从分块策略、元数据增强到层级索引与知识图谱
人工智能·知识图谱
吴佳浩33 分钟前
Agent 安全红线:越狱防御、间接注入与数据防泄漏实战
人工智能·agent·ai编程
miofly33 分钟前
Claude 自主发现类 CRISPR 结构的新型逆转录酶系统:Anthropic 生命科学实验室的早期成果
开源·github
前端的阶梯34 分钟前
AI Agent 之 深度解析上下文工程
人工智能
Omics Pro42 分钟前
Cell封面|衰老生物学开源AI工具包
数据库·人工智能·算法·机器学习·自然语言处理
hoLzwEge43 分钟前
把 WorkBuddy 每日签到搬上云端
人工智能·程序员
吴佳浩1 小时前
Claude Code 与 Hermes Agent 深度拆解:顶级 Coding Agent 为什么都放弃了纯 Chat 模式?
人工智能·agent·ai编程
Csvn1 小时前
前言与后记 · 全书完结
人工智能·aigc·agent