项目名称: Axonix 文本编辑器后端系统
版本: 2.0.0
封档日期: 2026-07-14
项目状态: 已完成阶段 0 核心功能
Axonix 文本编辑器后端系统是一个基于 SQLite Block 存储 的高性能文档管理系统,旨在支持:
✅ 高性能 - SQLite Block 存储,O(1) 单块更新
✅ 富文本支持 - 完整的样式系统(字体、颜色、对齐等)
✅ 精确编辑 - Block 级别的增删改查
✅ 格式保真 - Word ↔ Block 完全可逆转换
✅ 清晰架构 - 分层设计,易于扩展和维护
支持三种插入模式:
{
"content": [
{"text": "普通文字", "style": {}},
{"text": "红色加粗", "style": {"color": "FF0000", "bold": true}}
]
}
is_empty 标记)| 层次 | 技术 | 版本 |
|---|---|---|
| 后端框架 | FastAPI | 0.115.5 |
| Web 服务器 | Uvicorn | 0.32.1 |
| ORM | SQLAlchemy | 2.0.36 |
| 数据库 | PostgreSQL + SQLite | - |
| 异步驱动 | asyncpg | 0.30.0 |
| 数据库迁移 | Alembic | 1.14.0 |
| 数据校验 | Pydantic | 2.10.3 |
| Word 处理 | python-docx | 1.1.2 |
| 模板渲染 | docxtpl | 0.19.0 |
┌─────────────────────────────────────────────────────────┐
│ FastAPI │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Documents │ │ Blocks │ │ Export │ │
│ │ API │ │ API │ │ API │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │
│ ┌──────┴─────────────────┴─────────────────┴───────┐ │
│ │ Service Layer │ │
│ │ DocumentService | ContentDB | ExportService │ │
│ └──────┬─────────────────┬─────────────────┬───────┘ │
└─────────┼─────────────────┼─────────────────┼─────────┘
│ │ │
┌──────┴──────┐ ┌─────┴──────┐ ┌─────┴──────┐
│ PostgreSQL │ │ SQLite │ │ File │
│ (Metadata) │ │ (Blocks) │ │ System │
└─────────────┘ └────────────┘ └────────────┘
tmp/{user_id}/sqlite/{doc_id}.dbdocument_blocks 表tmp/{user_id}/{date}/{filename}ax-backend-v1/
├── app/
│ ├── api/v1/ # API 路由层
│ │ ├── documents.py # 文档管理 API(4 个端点)
│ │ ├── blocks.py # Block 管理 API(5 个端点)
│ │ ├── export.py # 导出 API(1 个端点)
│ │ ├── export_records.py # 导出记录 API(4 个端点)
│ │ └── __init__.py
│ ├── core/ # 核心配置
│ │ ├── database.py # 数据库连接池
│ │ ├── dependencies.py # 依赖注入
│ │ ├── exceptions.py # 自定义异常
│ │ └── __init__.py
│ ├── models/ # ORM 模型
│ │ ├── document.py # Document 表
│ │ ├── export_record.py # ExportRecord 表
│ │ └── __init__.py
│ ├── schemas/ # Pydantic Schema
│ │ ├── document.py # 文档相关 Schema
│ │ ├── block.py # Block 相关 Schema
│ │ ├── export.py # 导出相关 Schema
│ │ └── __init__.py
│ ├── services/ # 业务逻辑层
│ │ ├── content_db.py # SQLite 操作封装
│ │ ├── document_service.py # 文档服务
│ │ ├── export_service.py # 导出服务
│ │ ├── export_record_service.py # 导出记录服务
│ │ ├── word_parser.py # Word 解析器
│ │ ├── image_service.py # 图片处理
│ │ ├── storage_monitor.py # 存储监控
│ │ └── __init__.py
│ ├── config.py # 配置文件
│ └── main.py # FastAPI 应用入口
├── migrations/ # 数据库迁移
│ ├── versions/
│ │ └── 001_init_database.py
│ └── env.py
├── docs/ # 项目文档
│ ├── features/ # 功能设计文档
│ │ ├── document-management-design.md
│ │ ├── text-editor-feature-design.md
│ │ ├── INSERT_BLOCK_COMPLETE_GUIDE.md
│ │ ├── toc-complete-guide.md
│ │ └── export-doc-content-mapping.md
│ ├── content-sqlite-design.md
│ ├── text-editor-architecture.md
│ ├── text-editor-backend-api.md
│ ├── sqlite-implementation-plan.md
│ └── environment-setup.md
├── tmp/ # 临时文件存储
│ ├── {user_id}/
│ │ ├── sqlite/ # SQLite 数据库
│ │ └── {date}/ # 导出文件
│ └── default.json # 默认样式文件
├── .env # 环境变量
├── alembic.ini # Alembic 配置
├── requirements.txt # 依赖清单
├── PROJECT_SUMMARY.md # 项目总结
└── PROJECT_CLOSURE_REPORT.md # 封档报告(本文档)
| 端点 | 方法 | 功能 | 状态 |
|---|---|---|---|
/api/v1/documents |
POST | 创建文档(从 Word 解析) | ✅ |
/api/v1/documents |
GET | 获取文档列表(分页) | ✅ |
/api/v1/documents/{id} |
GET | 获取文档详情(可选包含 blocks) | ✅ |
/api/v1/documents/{sessionId} |
DELETE | 删除会话的所有文档 | ✅ |
| 端点 | 方法 | 功能 | 状态 |
|---|---|---|---|
/api/v1/documents/{id}/blocks |
POST | 创建 Block(插入) | ✅ |
/api/v1/documents/{id}/blocks |
GET | 获取所有 Blocks | ✅ |
/api/v1/documents/{id}/blocks/{blockId} |
GET | 获取单个 Block | ✅ |
/api/v1/documents/{id}/blocks/{blockId} |
PUT | 更新 Block | ✅ |
/api/v1/documents/{id}/blocks/{blockId} |
DELETE | 删除 Block | ✅ |
/api/v1/documents/{id}/blocks/search |
GET | 搜索 Blocks | ✅ |
/api/v1/documents/{id}/blocks/toc |
GET | 获取目录树 | ✅ |
/api/v1/documents/{id}/blocks/stats |
GET | 获取统计信息 | ✅ |
| 端点 | 方法 | 功能 | 状态 |
|---|---|---|---|
/api/v1/export |
POST | 导出为 Word 文档 | ✅ |
| 端点 | 方法 | 功能 | 状态 |
|---|---|---|---|
/api/v1/export-records |
GET | 获取导出记录列表 | ✅ |
/api/v1/export-records/{recordId}/download |
GET | 下载导出文件 | ✅ |
/api/v1/export-records/{recordId} |
DELETE | 删除导出记录 | ✅ |
/api/v1/admin/storage |
GET | 查看存储使用情况 | ✅ |
API 总计: 18 个端点,全部已实现并测试 ✅
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | VARCHAR(64) | PRIMARY KEY | 文档 ID,格式:doc-{uuid[:12]} |
| content_db_path | VARCHAR(512) | NOT NULL | SQLite 数据库文件路径 |
| session_id | VARCHAR(128) | NOT NULL | 关联会话 ID |
| created_by | VARCHAR(128) | NULL | 创建者用户 ID |
| created_at | TIMESTAMPTZ | NOT NULL | 创建时间 |
| updated_at | TIMESTAMPTZ | NOT NULL | 更新时间 |
索引:
idsession_idcreated_by| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | VARCHAR(64) | PRIMARY KEY | 记录 ID,格式:export-{uuid[:12]} |
| user_id | VARCHAR(128) | NOT NULL | 用户 ID |
| file_name | VARCHAR(512) | NOT NULL | 文件名(含扩展名) |
| file_path | VARCHAR(1024) | NOT NULL | 磁盘存储路径 |
| file_size | INTEGER | NOT NULL | 文件大小(字节) |
| download_url | VARCHAR(1024) | NOT NULL | 下载链接 |
| document_id | VARCHAR(64) | NULL | 关联文档 ID |
| style_id | VARCHAR(64) | NULL | 使用的样式 ID |
| created_at | TIMESTAMPTZ | NOT NULL | 创建时间 |
索引:
iduser_iddocument_id| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | TEXT | PRIMARY KEY | Block ID |
| block_order | INTEGER | NOT NULL | 排序序号(稀疏排序) |
| type | TEXT | NOT NULL | Block 类型:heading/paragraph/table/image |
| level | INTEGER | NULL | 标题级别(1-6,仅 heading) |
| index | INTEGER | NULL | 同级标题序号 |
| content | TEXT | NULL | 内容(JSON 格式) |
| word_style | TEXT | NULL | Word 样式名称 |
| style | TEXT | NULL | Block 样式(JSON) |
| metadata | TEXT | NULL | 元数据(JSON) |
索引:
idblock_ordertypelevel功能: 将 Word 文档解析为 Block 结构
支持的元素:
样式提取:
处理流程:
Word 文档 → python-docx 解析 → 遍历段落/表格/图片
↓
提取样式 → 构建 Block 对象 → 分配 block_order
↓
返回 Block 列表
ContentDB 类: SQLite 操作封装
核心方法:
get_blocks(): 获取所有 blocks(按 block_order 排序)get_block(block_id): 获取单个 blockinsert_block(block): 插入新 blockupdate_block(block_id, updates): 更新 blockdelete_block(block_id): 删除 blocksearch_blocks(keyword): 全文搜索get_toc(): 生成目录树get_stats(): 统计信息稀疏排序实现:
# 插入到两个 blocks 之间
prev_order = 100
next_order = 200
new_order = (prev_order + next_order) / 2 # 150
# 间隙耗尽时重排
if next_order - prev_order < 1:
rebalance_orders() # 局部重排
功能: Block → Word 文档
核心流程:
Block 列表 → 遍历每个 block
↓
根据 type 渲染对应元素(标题/段落/表格/图片)
↓
应用样式(三层继承)
↓
python-docx 保存 → 返回字节流
样式应用策略:
INSERT_BLOCK_COMPLETE_GUIDE.md 详细说明了三种插入模式:
原结构:
A (order=100)
B (order=200)
插入 X before B:
A (order=100)
X (order=150) ← 新
B (order=200)
原结构:
A (order=100)
B (order=200)
插入 X after A:
A (order=100)
X (order=150) ← 新
B (order=200)
原结构:
# H1 (order=100, level=1)
## H2 (order=200, level=2)
插入 X as child of H1:
# H1 (order=100, level=1)
## X (order=150, level=2) ← 新
## H2 (order=200, level=2)
自动重排触发条件:
TOC_COMPLETE_GUIDE.md 说明了目录树构建算法:
def build_toc(blocks):
root = []
stack = [root] # 栈顶为当前可插入位置
for block in blocks:
if block.type != 'heading':
continue
level = block.level
# 退栈到合适位置
while len(stack) > level:
stack.pop()
# 创建节点
node = {
"id": block.id,
"title": block.content,
"level": level,
"children": []
}
# 插入到栈顶
stack[-1].append(node)
# 入栈
stack.append(node["children"])
return root
复杂度: O(n),单次遍历
功能描述: 提供样式存储、管理和应用能力
API 端点设计:
POST /api/v1/styles/extract - 从 Word 文档提取样式GET /api/v1/styles - 获取样式列表(分页)GET /api/v1/styles/{styleId} - 获取样式详情PUT /api/v1/styles/{styleId} - 更新样式DELETE /api/v1/styles/{styleId} - 删除样式POST /api/v1/styles/{styleId}/preview - 生成样式预览图核心服务逻辑:
StyleService.extract_from_word() - 解析 Word 样式StyleService.apply_to_document() - 将样式应用到文档StyleService.generate_preview() - 生成预览图预计工时: 3-4 天
功能描述: 记录和管理聊天会话及消息历史,支持文档与会话关联
API 端点设计:
POST /api/v1/sessions - 创建聊天会话GET /api/v1/sessions - 获取会话列表(分页)GET /api/v1/sessions/{sessionId} - 获取会话详情PUT /api/v1/sessions/{sessionId} - 更新会话信息(标题、标签等)DELETE /api/v1/sessions/{sessionId} - 删除会话(级联删除文档和消息)POST /api/v1/sessions/{sessionId}/messages - 添加消息到会话GET /api/v1/sessions/{sessionId}/messages - 获取会话消息历史(分页)GET /api/v1/sessions/{sessionId}/documents - 获取会话关联的所有文档核心服务逻辑:
SessionService.create_session(user_id, title) - 创建新会话SessionService.add_message(session_id, role, content) - 添加消息SessionService.get_messages(session_id, page, limit) - 获取消息历史SessionService.update_summary(session_id) - 自动更新会话摘要SessionService.delete_session(session_id) - 删除会话及关联数据SessionService.get_session_documents(session_id) - 获取会话文档列表功能特性:
预计工时: 3-4 天
功能描述: 支持 Block → PDF 导出
API 端点设计:
POST /api/v1/export/pdf - 导出为 PDF(与 Word 导出接口并列)GET /api/v1/export/pdf/{recordId} - 下载 PDF 文件核心服务逻辑:
PDFExportService.export(document_id, style_id) - 导出 PDFPDFExportService.render_block(block) - 渲染单个 BlockPDFExportService.apply_styles(pdf, styles) - 应用样式技术选型:
方案 1: weasyprint - HTML → PDF(推荐)
方案 2: reportlab - 直接生成 PDF
实现流程:
Blocks → HTML 模板 → 应用 CSS 样式 → weasyprint 渲染 → PDF 文件
预计工时: 3-4 天
功能描述: 支持文档版本快照、历史记录和回滚
API 端点设计:
POST /api/v1/documents/{id}/versions - 创建版本快照GET /api/v1/documents/{id}/versions - 获取版本历史列表GET /api/v1/documents/{id}/versions/{versionId} - 获取版本详情POST /api/v1/documents/{id}/versions/{versionId}/restore - 恢复到指定版本GET /api/v1/documents/{id}/versions/compare - 比较两个版本差异核心服务逻辑:
VersionService.create_snapshot(document_id) - 创建快照(复制 SQLite 文件)VersionService.restore(version_id) - 恢复版本(替换 SQLite 文件)VersionService.compare(version1, version2) - 比较差异(Block diff)VersionService.auto_snapshot() - 自动快照(定时任务)版本策略:
预计工时: 4-5 天
功能描述: 支持多人实时协同编辑(基于 CRDT)
API 端点设计:
WS /api/v1/collab/documents/{id} - 协同编辑 WebSocket 连接GET /api/v1/collab/documents/{id}/users - 获取在线用户列表POST /api/v1/collab/documents/{id}/lock - 锁定 Block(防止冲突)POST /api/v1/collab/documents/{id}/unlock - 解锁 Block核心服务逻辑:
CollabService.join(document_id, user_id) - 加入协同会话CollabService.leave(document_id, user_id) - 离开会话CollabService.broadcast_operation(op) - 广播操作(Yjs Operation)CollabService.apply_operation(op) - 应用远程操作CollabService.resolve_conflict(ops) - 冲突解决(CRDT 算法)技术选型:
pycrdt (Python 版 Yjs)实现流程:
用户 A 编辑 → 生成 Yjs Operation → WebSocket 广播
↓
用户 B 接收 → 应用 Operation → 更新本地状态
↓
持久化:定期将 CRDT 状态同步到 SQLite
预计工时: 7-10 天(复杂度高)
目标: 从本地磁盘迁移到对象存储(S3/MinIO)
改动范围:
ImageService - 图片存储迁移ExportService - 导出文件存储迁移ContentDB - SQLite 文件存储迁移(可选)配置支持:
STORAGE_BACKEND = "s3" # 'local' or 's3'
S3_ENDPOINT = "https://s3.amazonaws.com"
S3_BUCKET = "axonix-documents"
预计工时: 2-3 天
目标: 引入 Redis 缓存,减少数据库查询
缓存策略:
# 文档元数据缓存(TTL: 1 小时)
redis.setex(f"doc:{doc_id}", 3600, json.dumps(doc_data))
# 热点 Blocks 缓存(TTL: 30 分钟)
redis.setex(f"blocks:{doc_id}", 1800, json.dumps(blocks))
# 用户配额缓存(TTL: 10 分钟)
redis.setex(f"quota:{user_id}", 600, json.dumps(quota_info))
缓存失效策略:
预计工时: 2-3 天
目标: 完善监控指标和日志记录
监控指标:
日志增强:
# 结构化日志
logger.info("document_created", extra={
"document_id": doc_id,
"user_id": user_id,
"blocks_count": len(blocks),
"duration_ms": elapsed_time
})
工具选型:
预计工时: 3-4 天
当前: 本地磁盘
↓
短期: 本地磁盘 + 定期备份
↓
中期: S3/MinIO 对象存储
↓
长期: 分布式对象存储 + CDN
当前: 单体应用
↓
短期: 单体应用 + 监控
↓
中期: 微服务架构
↓
长期: 云原生架构(Kubernetes)
当前: PostgreSQL + SQLite
↓
短期: PostgreSQL + SQLite + Redis
↓
中期: PostgreSQL (主从) + Redis (集群)
↓
长期: 分库分表 + 读写分离