# NexDocus 功能增强实现计划 ## Stage 1: 路由调整和项目成员管理 **Goal**: 调整路由结构,实现项目卡片上的成员管理功能 **Success Criteria**: - /projects/my 路由正常工作 - /projects/share 路由正常工作 - 项目卡片上可以打开成员管理弹窗 - 可以添加/删除项目成员 **Tests**: - 访问 /projects/my 显示我创建的项目 - 访问 /projects/share 显示我参与的项目 - 点击项目卡片的成员图标打开成员管理弹窗 - 成功添加用户到项目 - 成功从项目删除用户 **Status**: ✅ Completed --- ## Stage 2: 个人桌面统计增强 **Goal**: 在个人桌面增加"参加项目数"统计 **Success Criteria**: - 个人桌面显示参加项目数 - 统计数据准确(我创建的项目 + 我参与的项目) **Tests**: - 创建新项目后,个人项目数 +1 - 加入协作项目后,参加项目数 +1 - 统计卡片正确显示两个数值 **Status**: ✅ Completed --- ## Stage 3: 参与项目视图和权限控制 **Goal**: 实现参与项目单独视图,区分所有者和成员权限 **Success Criteria**: - /projects/share 页面单独展示我参与的项目(非所有者) - 项目卡片根据角色显示不同操作选项 - 成员不能删除项目(删除按钮不显示) - 成员可以编辑项目内文档 **Tests**: - 参与者打开 /projects/share 只看到协作项目 - 参与者看不到删除项目按钮 - 参与者可以正常编辑文档 **Status**: ✅ Completed --- ## Stage 4: 操作日志功能 **Goal**: 为文档编辑操作记录日志 **Success Criteria**: - 创建者编辑文档时记录到 operation_logs 表 - 参与者编辑文档时记录到 operation_logs 表 - 日志包含用户ID、操作类型、资源信息 **Tests**: - 编辑文档后,operation_logs 表有新记录 - 日志包含正确的用户ID和文档路径 - 不同用户编辑生成不同日志 **Status**: ✅ Completed --- ## Stage 5: 项目编辑功能 **Goal**: 在我的项目卡片上增加编辑功能 **Success Criteria**: - 项目卡片显示编辑按钮(仅所有者) - 点击编辑弹出表单 - 可以修改项目名称、描述、公开性 **Tests**: - 项目所有者看到编辑按钮 - 编辑项目信息成功保存 - 非所有者不显示编辑按钮 **Status**: ✅ Completed --- ## Stage 6: 全局搜索功能 **Goal**: 实现全局搜索文档内容 **Success Criteria**: - 后端提供搜索API(搜索文档元数据+内容) - 前端增加全局搜索框 - 搜索结果显示匹配的文档列表 - 点击结果跳转到对应文档 **Tests**: - 搜索文档标题能找到对应文档 - 搜索文档内容能找到包含关键词的文档 - 搜索结果高亮显示关键词 - 点击搜索结果正确跳转 **Status**: ✅ Completed --- ## 技术决策 ### 数据库变更 - 无需修改现有表结构(project_members 和 operation_logs 已存在) ### 后端API新增 1. `GET /projects/my` - 获取我创建的项目 2. `GET /projects/shared` - 获取我参与的项目 3. `POST /projects/{project_id}/members` - 添加项目成员(已存在,需测试) 4. `DELETE /projects/{project_id}/members/{user_id}` - 删除项目成员(需新增) 5. `POST /search/documents` - 全局文档搜索(需新增) 6. 修改 `POST /files/{project_id}/file` - 增加操作日志记录 ### 前端路由调整 - `/projects/my` - 我的项目(原 /projects) - `/projects/share` - 参与的项目(新增) - 保持 `/projects` 作为默认,重定向到 `/projects/my` ### 权限控制策略 - 项目所有者:完全控制(增删改查、成员管理、删除项目) - 项目管理员(ADMIN):文档管理、成员管理 - 项目编辑者(EDITOR):文档编辑 - 项目查看者(VIEWER):仅查看 ### 操作日志设计 ```json { "user_id": 1, "username": "admin", "operation_type": "update", "resource_type": "document", "resource_id": 123, "detail": { "project_id": 10, "file_path": "/docs/readme.md", "action": "edit", "changes": "content_modified" }, "ip_address": "192.168.1.1", "status": 1 } ``` ### 全局搜索实现方案 1. **基础版本(当前阶段)**: - 搜索 document_meta 表的 title 字段 - 读取磁盘文件内容进行关键词匹配 - 适用于小规模项目 2. **未来优化(可选)**: - 使用 Elasticsearch 全文检索 - 添加文档内容索引到数据库 - 实现增量索引更新 --- ## Stage 7: PDF文档混合模式 **Goal**: 支持项目中上传PDF文件,并在Markdown和浏览模式下查看PDF ### 7.1 后端PDF文件上传支持 **Goal**: 后端支持PDF文件上传并存储到_assets/files目录 **实现内容**: 1. 修改`/files/{project_id}/upload-file`接口,支持PDF格式(.pdf) 2. 扩展文件类型验证,允许`application/pdf` 3. PDF文件存储到`_assets/files/`目录 4. 返回PDF文件的访问路径 **Success Criteria**: - 可以通过API上传PDF文件 - PDF文件正确存储到_assets/files目录 - 返回可访问的文件路径 - 上传其他格式文件时报错 **Tests**: - 使用Postman上传PDF文件,验证返回路径 - 验证文件确实存储在正确目录 - 尝试上传非法格式,验证错误提示 **Status**: ✅ Completed --- ### 7.2 文件树显示PDF文件 **Goal**: 前端文件树能够识别和显示PDF文件 **实现内容**: 1. 修改`StorageService.generate_tree()`,包含_assets/files目录中的PDF文件 2. 前端文件树组件识别.pdf文件 3. PDF文件显示专用图标(FilePdfOutlined) 4. 文件树节点携带文件类型信息 **Success Criteria**: - 文件树中显示PDF文件节点 - PDF文件有独特的图标 - 点击PDF文件能触发相应事件 **Tests**: - 在项目中上传PDF后,刷新文件树查看是否显示 - 验证PDF文件图标是否正确 - 点击PDF文件查看是否有响应 **Status**: ✅ Completed --- ### 7.3 Markdown编辑器支持插入PDF链接 **Goal**: 在MD编辑器中可以方便地插入PDF文件链接 **实现内容**: 1. 编辑器工具栏添加"插入PDF"按钮 2. 点击按钮弹出上传对话框 3. 上传成功后自动在光标位置插入Markdown链接:`[文件名.pdf](/_assets/files/xxx.pdf)` 4. 支持拖拽PDF文件到编辑器(可选) **Success Criteria**: - 工具栏有"插入PDF"按钮 - 可以上传PDF并自动插入链接 - 插入的链接格式正确 - 编辑器预览时显示PDF链接 **Tests**: - 点击"插入PDF"按钮,上传文件 - 验证插入的Markdown链接格式 - 保存后重新打开,验证链接是否保留 **Status**: ✅ Completed --- ### 7.4 PDF文件预览功能 **Goal**: 浏览模式下点击PDF链接或文件树中的PDF文件时,可以在线预览PDF **实现内容**: 1. 安装PDF预览库(react-pdf) 2. 创建PDFViewer组件,支持: - 分页显示 - 缩放控制(放大/缩小/适应宽度) - 页码跳转 - 下载功能 3. 在浏览模式下,点击PDF链接时打开预览器 4. 从文件树点击PDF文件时也打开预览器 5. 后端提供PDF文件访问接口(权限校验) **Success Criteria**: - 可以在浏览器中预览PDF文件 - 支持翻页、缩放等基本操作 - 只有有权限的用户可以查看PDF - PDF预览界面美观易用 **Tests**: - 在浏览模式下点击PDF链接,验证能否打开 - 测试翻页、缩放、下载功能 - 测试权限:无权限用户访问PDF时返回403 - 测试不同大小的PDF文件加载速度 **Status**: ✅ Completed --- ### 7.5 搜索集成PDF文件名 **Goal**: 全局搜索时可以搜索到PDF文件名 **实现内容**: 1. 修改`/search/documents`接口,添加对PDF文件的搜索 2. 搜索结果中显示PDF文件,带"PDF文档"标签 3. 点击搜索结果中的PDF文件时打开预览 **Success Criteria**: - 搜索PDF文件名能返回结果 - 搜索结果中PDF文件有明确标识 - 点击搜索结果可以打开PDF预览 **Tests**: - 上传名为"产品说明书.pdf"的文件 - 搜索"说明书",验证是否出现在结果中 - 点击搜索结果,验证是否打开PDF预览 **Status**: ✅ Completed --- ## PDF功能技术选型 ### PDF预览库对比 **方案1: react-pdf** (推荐) - 优点: - 轻量级,基于pdf.js封装 - API简单易用 - 支持分页、缩放、搜索 - TypeScript支持良好 - 缺点: - 需要配置worker - 大文件可能需要优化 - 安装:`npm install react-pdf pdfjs-dist` **方案2: @react-pdf-viewer** - 优点: - 功能更强大(书签、注释、表单) - 开箱即用的工具栏 - 插件系统 - 缺点: - 包体积较大 - 可能功能过剩 **方案3: iframe直接嵌入** - 优点: - 最简单,无需额外依赖 - 浏览器原生支持 - 缺点: - 功能有限,样式难以自定义 - 移动端体验差 ### 推荐方案 **使用 react-pdf**,理由: 1. 轻量级,适合当前项目规模 2. 功能足够,易于扩展 3. 社区活跃,文档完善 ### 文件存储结构 ``` projects/ {storage_key}/ _assets/ images/ # 图片文件(现有) files/ # PDF等文档文件(新增) README.md 其他目录和文件 ``` ### API设计 **1. 上传PDF文件(扩展现有接口)** ``` POST /api/v1/files/{project_id}/upload-file ``` 请求参数: - `file`: 文件二进制 - `subfolder`: "files"(新增,默认"images") 返回: ```json { "code": 200, "data": { "filename": "abc123.pdf", "original_filename": "产品说明书.pdf", "path": "_assets/files/abc123.pdf", "size": 1024000 } } ``` **2. 访问PDF文件(新接口)** ``` GET /api/v1/files/{project_id}/asset?path={relative_path} ``` - 权限校验:检查用户是否有项目访问权限 - 返回:PDF文件流(Content-Type: application/pdf) ### Markdown链接格式 ```markdown # 项目文档 查看详细说明:[产品说明书](/_assets/files/abc123.pdf) ``` ### 待确认问题 1. **文件大小限制**:PDF文件最大允许多少MB?建议:20MB 2. **是否支持PDF注释/标注**:暂不支持,后续可扩展 3. **PDF缩略图**:是否需要在文件树显示PDF缩略图?建议:暂不支持 4. **PDF搜索文本内容**:是否需要搜索PDF内部文字?建议:暂不支持 5. **并发上传限制**:是否限制同时上传的PDF数量? 6. **历史版本**:PDF文件是否需要版本控制?建议:暂不支持