【项目实训(个人5)】

继续进行项目的开发

在本次项目的持续迭代过程中,围绕悬浮AI工具、智能体交互、文档详情返回等多项功能进行了开发与优化。与此同时,也发现了若干在组件导入、数据库使用、状态管理、路径处理、测试覆盖及错误提示等方面存在的共性问题。为了提升后续开发的稳健性与可维护性,现将这些实践经验整理为系统性的反思内容,供团队内部参考与改进。

这些教训并非针对某一次具体故障的追责,而是对开发过程中频繁出现、且具有一定隐蔽性的技术细节的客观总结。希望通过归纳这些典型问题及其应对策略,逐步形成一套可复用的开发规范与检查清单,从而降低同类错误的重复发生率,提高整体工程交付质量。

新功能

1.悬浮AI工具

加入类似飞书的悬浮的AI工具,能解释和翻译等

步骤1: 在文档阅读区域,按住鼠标左键拖动选择一段文字

步骤2: 松开鼠标左键

步骤3: 选区正上方自动弹出AI工具栏

步骤4: 点击任意功能按钮(如"解释")

后端 AI API

创建 `backend/app/api/ai_tools.py`

  • 实现 `POST /api/ai/explain` 端点

  • 实现 `POST /api/ai/translate` 端点(支持 zh2en/en2zh/auto)

  • 实现 `POST /api/ai/summarize` 端点

  • 实现 `POST /api/ai/chat` 端点(支持多轮对话上下文)

  • 复用 `LLMService.chat()` 方法

  • 定义 Prompt 模板常量

在 `backend/app/main.py` 中注册 `ai_tools` router

  • 添加 `from app.api.ai_tools import router as ai_router`

  • `app.include_router(ai_router)`

创建 `frontend/src/api/ai-tools.ts`

  • `explain(text, context?)` → POST /ai/explain

  • `translate(text, direction)` → POST /ai/translate

  • `summarize(text, context?)` → POST /ai/summarize

  • `chat(message, docId, selectedText?, history?)` → POST /ai/chat (支持流式)

核心UI组件

创建 `frontend/src/components/AiFloatingToolbar.vue`

  • Props: `visible`, `position{top,left}`, `selectedText`, `docId`

  • Emits: `explain`, `translate`, `summarize`, `chat`, `close`

  • 4个图标按钮:解释(🤖)、翻译(🌐)、总结(📝)、对话(💬)

  • 关闭按钮(✕)

  • CSS: fixed定位、毛玻璃效果、淡入动画、阴影

  • 自动位置计算(选区上方/下方自适应)

创建 `frontend/src/components/AiResultCard.vue`

  • Props: `type('explain'|'translate'|'summarize')`, `content`, `loading`, `error`

  • 功能:

  • Markdown内容渲染

  • 加载状态(骨架屏/脉冲动画)

  • 错误状态 + 重试按钮

  • 复制结果到剪贴板

  • 翻译方向切换(仅 translate 类型)

创建 `frontend/src/components/AiChatPopover.vue`

  • Props: `visible`, `docId`, `selectedText`, `position`

  • 功能:

  • 聊天消息列表(用户+AI交替显示)

  • 输入框 + 发送按钮

  • 流式输出渲染(打字机效果)

  • 多轮对话历史维护

  • 可拖拽调整大小

  • 关闭按钮

集成到 ReaderView

修改 `ReaderView.vue`

  • 导入 AiFloatingToolbar 组件

  • 新增 ref 状态: `toolbarVisible`, `toolbarPosition`, `selectedTextForAi`

  • 修改 `handleMouseUp()` 或新增文本选择监听:

  • 获取选中文本内容

  • 计算选区位置Rect

  • 设置 toolbarVisible = true

  • 计算工具栏位置

  • 新增事件处理:

  • `@explain`: 调用API → 显示 AiResultCard

  • `@translate`: 调用API → 显示 AiResultCard

  • `@summarize`: 调用API → 显示 AiResultCard

  • `@chat`: 打开 AiChatPopover

  • `@close-toolbar`: 隐藏工具栏

  • 新增键盘快捷键监听 (Ctrl+E/T/S/I, Esc)

样式适配

  • 工具栏与批注面板共存时的布局调整

  • 移动端响应式样式

  • 暗色模式适配

  • 动画性能优化(will-change/transform)

演示功能默认是阅读功能,但是如果打开编辑模式,这些智能摘要的内容,以及结构化信息、类案推荐、关键词分析等功能也能看见

也就是说,把阅读和详情放在一个页面,或者是先展示详情,详情中有编辑按钮,退出编辑模式后编辑的结果能重新显示在详情的文书的内容

有没有必要将示例界面与文书管理界面合并呢

2.跳转逻辑

文档的详情和阅读之间能相互跳转

重新完善了一下详情页面,不再从右侧划出,而是更加自然

3.智能体交互

加入AI交互界面,能够回答用户的一些其他问题

这个AI能够读取文档管理中的文书,并能根据用户提供的文书名称找到到对应的文书,或是根据用户的需求找到文档管理中的文书(如果可以的话,也可以加入联网搜索功能,能够搜索互联网中公开的文书),还可以将用户选择的几个文档管理中的文书进行对比分析

形式:单独设置一个网页

后端实现

assistant.py - 新增5个API端点:

端点 功能 说明 POST /api/assistant/chat 智能问答 通用AI对话,支持多轮历史 POST /api/assistant/rag-chat 文档增强问答 基于ChromaDB向量检索的RAG问答,返回参考文书来源 POST /api/assistant/search-docs 文档检索 支持混合/精确/语义三种检索模式 GET /api/assistant/doc-list 文档列表 获取所有文书供对比选择 POST /api/assistant/compare 文书对比 AI生成结构化对比分析报告(2-5份文书)

main.py - 注册了assistant路由

前端实现

assistant.ts - API客户端,包含完整的类型定义

AssistantView.vue - 核心页面组件,包含三大功能模块:

1. 智能问答 - 聊天式界面,支持:

  • 两种回答模式:文档增强(RAG)和 通用问答

  • 多轮对话历史

  • 快捷问题推荐

  • 参考文书来源标签(可点击跳转)

  • Markdown渲染(标题、表格、列表、加粗等)

  • 打字动画加载指示器

  • Enter发送 / Shift+Enter换行
    2. 文档检索 - 搜索界面,支持:

  • 三种检索模式:混合检索、精确匹配、语义搜索

  • 搜索结果卡片展示(文件名、案号、法院、匹配类型、相关度)

  • 一键跳转查看详情或阅读文书
    3. 文书对比 - 对比分析界面,支持:

  • 左侧文书选择面板(带筛选、多选2-5份)

  • 关注重点输入

  • AI生成结构化对比分析报告

  • 已选文书标签展示

  • Markdown格式化报告渲染

main.ts - 添加 /assistant 路由

App.vue - 侧边栏新增"法智助手"导航项(使用ChatDotRound图标),面包屑支持

优化功能

1.文档详情返回设置

历史记录返回时到文档管理并定位到相应位置,示例的文书也是(示例文书在一开始就要展示在文档管理的文件中)

能够返回并高亮到相关的位置

场景1: 从历史记录返回

  1. 用户在首页/阅读页查看过某份文档

  2. 系统自动记录到历史记录

  3. 用户点击历史记录中的条目

  4. 系统执行:

├── 导航至 /documents?highlight=xxx

├── 文档列表自动加载

├── 平滑滚动到目标文档行

├── 添加高亮边框 + 脉冲动画(3秒)

└── 清除URL参数,恢复正常状态

场景2: 首次访问/示例展示

  1. 用户访问首页 (/)

  2. 系统展示:

├── 统计数据横幅

├── 上传区域

├── 示例文书区域(渐变背景,醒目)

│ ├── 民事判决书(可点击)

│ ├── 刑事判决书(可点击)

│ └── 行政判决书(可点击)

├── 快捷入口(上传/搜索/历史)

└── 近期记录面板

  1. 用户点击示例文书:

├── 加载示例内容到数据库

├── 跳转到阅读页面 (/reader/builtin_xxx)

└── 显示完整AI分析界面

2.颜色切换

矛盾点 :

  1. 模式数量不一致 : 左侧栏只有深色/浅色,阅读页有亮色/暗色/护眼

  2. UI风格不同 : 一个是文字按钮,一个是图标组

  3. 状态可能不同步 : 用户在阅读页选了"护眼"模式,左侧栏仍显示"深色/浅色"

左栏侧边的深色浅色模式与文书管理界面右上角的阅读颜色模式有些矛盾,整合一下这里的模式切换

两个入口都使用同一个 useThemeStore()

都调用 themeStore.setTheme(t.key)

都读取 themeStore.theme 判断当前状态

localStorage 统一存储

遇到的问题

1.删除按钮异常

数据库路径不一致 : config.py 中 data_dir 使用相对路径 data ,uvicorn 不同工作目录下连接到不同数据库文件 改为基于 BACKEND_DIR 的绝对路径

2 外键约束冲突 : annotation_history 表有级联引用,删除批注时未先清理关联数据导致 IntegrityError 删除前先清理 replies/mentions/history

3 DELETE HTTP 方法路由异常 :uvicorn --reload 对 DELETE 方法的路由存在缓存问题,同样的代码在 GET 中正常但在 DELETE 中返回 404 改用 POST /delete 端点(业界常见模式)

修改的文件:

后端 (3 个文件) :

  • config.py --- 路径改为绝对路径

  • database.py --- 新增线程/回复/历史/用户表、迁移逻辑、级联删除

  • storage.py --- 清理重写,POST 替代 DELETE

前端 (2 个文件) :

  • annotations.ts --- delete 改为 post

  • AnnotationPanel.vue --- 错误信息增强

2.关键词分析无法正常显示

发生场景 在DocumentView详情页面点击" 关键词分析"Tab,显示空白

影响范围 DocumentView关键词分析功能

根本原因 模板中使用了 <KeywordCloud> 组件,但在 <script> 部分 未导入 该组件 已尝试方案 检查后端API(正常)→ 检查组件代码(正常)→ 检查导入(发现缺失)

最终处理 在DocumentView.vue中添加 import KeywordCloud from '../components/KeywordCloud.vue'

反思

在项目开发与迭代过程中,我们总结出若干具有普遍意义的经验教训,现整理如下,以供后续改进参考。

1.组件导入缺失的隐蔽性

在实际开发中发现,Vue 模板中使用的组件若未在脚本中正确导入,框架并不会给出明确的错误提示,而是静默失败。此类问题在开发初期容易被忽略,排查成本较高。为降低此类风险,建议建立模板组件的使用检查清单,并优先采用 <script setup> 配合 TypeScript 的写法,借助编译器进行更早的静态检查。在开发早期阶段,应完成所有组件导入的完整性验证。

2.SQLite 使用中的易忽略限制

SQLite 作为轻量级数据库虽然上手简单,但在实际使用中存在若干易被忽视的约束:

  • ALTER TABLE 操作能力有限,例如无法直接添加带有非约束默认值的列;

  • 外键约束在删除记录时顺序敏感,容易引发完整性错误;

  • 不支持原生 Python 类型(如字典、列表),需要手动进行 JSON 序列化;

  • 相对路径在多环境下可能解析失败。

针对上述问题,建议优先使用 SQLAlchemy ORM 来封装底层差异,制定详细的数据库迁移操作检查清单,统一使用绝对路径并自动创建所需目录。

3.状态管理的一致性问题

主题模式、用户登录状态等全局信息若由多个入口独立管理,容易出现不同步的异常。实践中需要尽早引入统一的状态管理方案(如 Pinia 或 Vuex),确保每一个状态只有一个可信来源,其他入口仅能读取状态或通过统一的 API 进行变更。所有状态修改都应经过相同的方法调用,避免出现分散自治的控制逻辑。

4.相对路径的不可靠性

在代码中硬编码相对路径会导致程序运行环境与预期不一致时出现文件找不到等错误,且排查困难。应避免在任何代码中直接使用相对路径,推荐使用 Path(__file__).resolve() 计算出绝对路径,或通过环境变量进行配置,而非硬编码形式。

5.用户流程测试的重要性

单元测试仅能保证单个组件或函数的正确性,但多个功能组合后的用户流程可能存在断点。例如,从首页进入示例文书详情页,再返回列表并高亮对应文档这一完整链路中,单个环节正常不代表整体流畅。因此,需要编写覆盖完整"用户故事"的流程测试,重点验证"从哪里来,要回哪里去"的导航闭环是否通畅。

6.错误信息的友好化设计

直接将底层异常(如 sqlite3.OperationalError)抛给用户既不安全也不友好。应当建立三层异常处理链:

  • 底层捕获原始异常;

  • 中间层转换为业务可理解的错误类型;

  • 最上层向用户展示友好的提示信息。

例如,在关键词云功能中,应根据具体情况分别显示"加载中..."、"文档不存在"、"服务错误"或"无关键词"等明确且适当的提示,避免用户看到技术细节异常。

总结

本次项目暴露出的问题大多集中在看似简单但易忽略的环节------如组件导入、相对路径、数据库迁移顺序、用户流程测试等。这些问题单独看影响范围有限,但叠加在一起会显著增加调试成本,并影响用户体验。通过建立统一的组件导入检查清单、采用绝对路径管理文件、引入中心化状态管理、完善三层异常处理链等措施,可以有效规避上述风险。

在后续开发中,我们将进一步推进端到端测试,确保每个功能模块在组合场景下仍能正常工作;同时继续完善AI工具链与智能体交互的稳定性,优化文档检索和对比分析的响应体验。最终目标是构建一个既能快速响应业务需求,又具备良好可维护性与扩展性的法律文书智能辅助系统。

相关推荐
z4424753262 小时前
新买的电脑装哪个HTML函数工具最匹配_开箱即用教程【教程】
jvm·数据库·python
测试员周周2 小时前
【踩坑系列3】飞书机器人集体“失联“?3 个 Gateway 进程让我差点崩溃!一个测试老兵的排查实录
java·python
m0_734949792 小时前
如何结合计划任务实现自动定时备份任务配置_全自动化运维管理
jvm·数据库·python
zhangzeyuaaa2 小时前
深入理解 Python GIL:从机制到释放时机
java·网络·python
PSLoverS2 小时前
c++如何读取和修改可执行文件的PE头信息_IMAGE_NT_HEADERS解析【进阶】
jvm·数据库·python
gmaajt2 小时前
React Native 单元测试中第三方依赖的正确 Mock 策略
jvm·数据库·python
a9511416422 小时前
宝塔面板数据库查询响应慢_利用慢查询日志进行优化
jvm·数据库·python
zhangzeyuaaa2 小时前
深入理解 Python 进程间通信:Queue 与 Pipe 实战解析
网络·python·中间件
2401_831419442 小时前
如何用 http 模块创建一个基础的 Web 服务器处理请求
jvm·数据库·python