Files
mokeeText/docs/README.md
2026-07-15 16:08:17 +08:00

346 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MoKeeText 项目文档
## 概述
**MoKeeText** 是一个 Web 端富文本笔记管理应用,同时具备网站账号密码管理功能,集成 Mokee Gateway 统一登录网关。
### 核心功能
| 模块 | 功能 |
|------|------|
| 📝 **笔记编辑** | 基于 Tiptap 的增强型富文本编辑器,支持文字颜色、图片粘贴/拖拽上传、表格、代码高亮、任务列表 |
| 🔐 **网站管理** | 按文件夹分类管理网站及其登录账号密码 |
| 🔗 **分享链接** | 笔记可生成分享链接,支持 7天/30天/1年/永久 四种有效期 |
| 📥 **智能导入** | 自动解析粘贴的网站账号信息,一键导入 |
| 🖼️ **图片上传** | 粘贴/拖拽图片自动上传,存数据库 LONGBLOB点击全屏预览 |
| 👤 **统一登录** | 接入 Mokee Gateway通过网关转发用户身份支持 API 级数据隔离 |
---
## 技术栈
| 层 | 技术 | 版本 |
|----|------|------|
| 后端框架 | FastAPI (Python) | ≥0.115 |
| 服务器 | Uvicorn | ≥0.30 |
| ORM | SQLAlchemy | ≥2.0 |
| 数据库 | MySQL | 8.0 |
| 前端框架 | Vue 3 + Vite | 3.5 / 8.x |
| 路由 | Vue Router | 4.6 |
| 编辑器 | Tiptap | 3.27 |
| 代码高亮 | highlight.js (lowlight) | - |
| HTTP 客户端 | Axios生产/ fetch本地开发 | 1.18 |
| 容器化 | Docker + Docker Compose | - |
| Web 服务器 | Nginx (Alpine) | - |
---
## 项目结构
```
mokeeText/
├── backend/ # 后端 — FastAPI 应用
│ ├── app.py # 入口CORS、中间件、路由注册
│ ├── models.py # SQLAlchemy 数据模型6 张表)
│ ├── config.py # 数据库连接配置(环境变量)
│ ├── logger.py # 日志系统(按天轮转,保留 30 天)
│ ├── init_db.py # 建表脚本
│ ├── requirements.txt # Python 依赖
│ ├── Dockerfile # 后端 Docker 镜像
│ ├── .dockerignore
│ ├── routes/ # API 路由
│ │ ├── notes.py # 笔记 CRUD + 分享 + 移动
│ │ ├── websites.py # 网站/账号/文件夹 CRUD + 排序
│ │ ├── import_api.py # 智能导入解析
│ │ ├── upload.py # 图片上传/读取
│ │ └── share.py # 公开分享查看页
│ └── middleware/
│ └── user_context.py # 网关用户上下文中间件
├── frontend/ # 前端 — Vue 3 SPA
│ ├── index.html # Vite 入口 HTML
│ ├── package.json # 前端依赖
│ ├── vite.config.js # Vite 构建配置
│ ├── nginx.conf # Nginx 配置
│ ├── Dockerfile.frontend # 前端 Nginx Docker 镜像
│ ├── .dockerignore
│ ├── .env / .env.production # 环境变量
│ ├── src/
│ │ ├── main.js # Vue 入口 → 挂载 Router + v-permission
│ │ ├── App.vue # 根组件:左导航 + 顶栏 + UserChip + 底栏
│ │ ├── router.js # Vue Router 配置 + 路由守卫
│ │ ├── utils/request.js # Axios 实例 + 拦截器
│ │ ├── composables/useApi.js # 双模式 APIdev fetch / prod axios
│ │ ├── directives/permission.js # v-permission 按钮权限指令
│ │ ├── views/
│ │ │ ├── NotesView.vue # 笔记:文件夹侧边栏 + 列表 + 编辑器
│ │ │ ├── WebsitesView.vue # 网站管理:列表 + CRUD 弹窗
│ │ │ └── SharesView.vue # 分享管理
│ │ └── components/
│ │ ├── NoteEditor.vue # Tiptap 增强编辑器
│ │ ├── Modal.vue # 通用弹窗组件
│ │ ├── ConfirmModal.vue
│ │ └── PromptModal.vue
│ └── static/
│ ├── dist/ # Vite 构建产物Nginx 托管)
│ ├── js/vendor/ # Tiptap UMD 扩展文件
│ ├── css/
│ └── uploads/
├── deploy/ # 部署
│ ├── docker-compose.yml # 双容器编排
│ ├── deploy.py # 日常部署脚本
│ └── migrate_server.py # 服务器迁移脚本(一次性)
├── docs/ # 文档
│ ├── README.md # 本文档
│ ├── DEPLOY.md # 部署文档
│ └── superpowers/ # 设计规范 + 实施计划
└── memory/ # 会话记忆
```
---
## 数据库设计
### ER 图
```
folders ──┬── notes ──┬── note_tags ── tags
└── websites ── accounts
uploads独立图片存 DB
```
### 表结构
#### folders — 文件夹(笔记和网站共用)
| 字段 | 类型 | 说明 |
|------|------|------|
| id | INT PK | 自增主键 |
| name | VARCHAR(100) | 文件夹名称 |
| type | ENUM('note','website') | 类型 |
| parent_id | INT FK→folders.id | 父文件夹(树形结构) |
| sort_order | INT | 排序 |
| created_by | VARCHAR(100) | 创建者账号 |
| created_at | DATETIME | 创建时间 |
#### notes — 笔记
| 字段 | 类型 | 说明 |
|------|------|------|
| id | INT PK | 自增主键 |
| title | VARCHAR(500) | 标题 |
| content | TEXT | Tiptap 输出的 HTML |
| folder_id | INT FK→folders.id | 所属文件夹 |
| created_by | VARCHAR(100) | 创建者 |
| updated_by | VARCHAR(100) | 最后修改者 |
| share_token | VARCHAR(64) UNIQUE | 分享令牌 |
| share_expires_at | DATETIME | 分享过期时间 |
| created_at / updated_at | DATETIME | 时间戳 |
#### tags — 标签
| 字段 | 类型 | 说明 |
|------|------|------|
| id | INT PK | 自增主键 |
| name | VARCHAR(50) UNIQUE | 标签名 |
| color | VARCHAR(20) | 颜色 |
#### note_tags — 笔记-标签关联(多对多)
| 字段 | 类型 | 说明 |
|------|------|------|
| note_id | INT FK | 笔记 ID |
| tag_id | INT FK | 标签 ID |
#### websites — 网站
| 字段 | 类型 | 说明 |
|------|------|------|
| id | INT PK | 自增主键 |
| name | VARCHAR(200) | 网站名称 |
| url | VARCHAR(500) | 网址 |
| folder_id | INT FK | 所属文件夹 |
| created_by / updated_by | VARCHAR(100) | 操作者 |
| created_at / updated_at | DATETIME | 时间戳 |
#### accounts — 账号
| 字段 | 类型 | 说明 |
|------|------|------|
| id | INT PK | 自增主键 |
| website_id | INT FK | 所属网站 |
| username | VARCHAR(500) | 用户名 |
| password | VARCHAR(500) | 密码(明文,待加密) |
| remark | TEXT | 备注 |
| sort_order | INT | 排序 |
| created_by / updated_by | VARCHAR(100) | 操作者 |
#### uploads — 上传文件
| 字段 | 类型 | 说明 |
|------|------|------|
| id | INT PK | 自增主键 |
| filename | VARCHAR(255) | 原始文件名 |
| content_type | VARCHAR(100) | MIME 类型 |
| data | LONGBLOB | 二进制数据(最大 4GB |
| size | INT | 文件大小(字节) |
| created_by | VARCHAR(100) | 上传者 |
| created_at | DATETIME | 上传时间 |
---
## API 接口
所有接口均以 `/api/` 为前缀。除分享页和图片读取外,所有操作需要网关注入用户身份。
### 笔记
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/notes` | 获取笔记列表(支持 `?folder_id=` 筛选) |
| POST | `/api/notes` | 创建笔记 |
| GET | `/api/notes/{id}` | 获取笔记详情 |
| PUT | `/api/notes/{id}` | 修改笔记 |
| DELETE | `/api/notes/{id}` | 删除笔记 |
| PUT | `/api/notes/{id}/move` | 移动笔记到文件夹 |
| POST | `/api/notes/{id}/share` | 生成分享链接 |
### 文件夹
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/folders` | 获取文件夹列表(支持 `?type=note\|website` |
| POST | `/api/folders` | 创建文件夹 |
| PUT | `/api/folders/{id}` | 重命名文件夹 |
| DELETE | `/api/folders/{id}` | 删除文件夹 |
### 网站与账号
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/websites` | 获取网站列表(支持 `?folder_id=` |
| POST | `/api/websites` | 创建网站 |
| PUT | `/api/websites/{id}` | 修改网站 |
| DELETE | `/api/websites/{id}` | 删除网站 |
| GET | `/api/websites/{id}/accounts` | 获取账号列表 |
| POST | `/api/websites/{id}/accounts` | 创建账号 |
| PUT | `/api/accounts/{id}` | 修改账号 |
| DELETE | `/api/accounts/{id}` | 删除账号 |
| PUT | `/api/accounts/sort` | 账号排序 |
### 文件
| 方法 | 路径 | 说明 |
|------|------|------|
| POST | `/api/upload/image` | 上传图片(网关鉴权) |
| GET | `/api/file/{id}` | 读取图片(公开,无需鉴权) |
### 分享
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/share/{token}` | 公开查看分享的笔记(不走网关) |
| GET | `/api/shares` | 获取我的分享列表 |
| DELETE | `/api/shares/{note_id}` | 取消分享 |
### 智能导入
| 方法 | 路径 | 说明 |
|------|------|------|
| POST | `/api/import/parse` | 解析粘贴的文本,提取网站+账号信息 |
---
## 认证架构
```
┌─────────┐ ┌──────────────┐ ┌─────────────┐ ┌──────────┐
│ 浏览器 │ ──→ │ 统一登录页 │ ──→ │ Mokee │ ──→ │ FastAPI │
│ │ │ login.user. │ │ Gateway │ │ 后端 │
│ │ │ zgitm.com │ │ gw.server. │ │ :4006 │
│ │ │ │ │ zgitm.com │ │ │
└─────────┘ └──────────────┘ └──────┬───────┘ └──────────┘
注入 X-User-* 头
X-User-Id, X-User-Account,
X-User-Roles, X-System-Code ...
```
### 请求流程
1. **用户访问** → 前端路由守卫检查 Cookie 中是否有 `token`
2. **无 Token** → 重定向到 `login.user.zgitm.com` 统一登录
3. **登录成功** → 网关设置 Cookie用户回到应用
4. **API 请求** → Axios 拦截器从 Cookie 取 Token 放入 Authorization 头
5. **网关转发** → 验证 Token 后注入 `X-User-*` 系列请求头
6. **后端中间件**`UserContextMiddleware` 提取请求头存入 `request.state.user`
7. **业务路由** → 通过 `UserContext.get_user_id()` 获取当前用户,按 `created_by` 过滤数据
### 本地开发模式
设置环境变量 `DEV_MODE=true` 或添加请求头 `X-Dev-Mock-User`,后端绕过网关认证,使用默认 admin 用户。
```bash
# 启动后端
cd backend
DEV_MODE=true uvicorn app:app --port 4006
# 启动前端(另一个终端)
cd frontend
npx vite
```
---
## 前端架构
### 路由
| 路径 | 组件 | 说明 |
|------|------|------|
| `/` | → 重定向 | 默认到 /notes |
| `/notes` | NotesView | 笔记编辑器(文件夹 + 列表 + 编辑器) |
| `/websites` | WebsitesView | 网站账号管理 |
| `/shares` | SharesView | 分享链接管理 |
### API 调用模式
前端通过 `useApi()` 组合式函数发起请求,自动适配环境:
- **生产环境**:使用 Axios 实例,拦截器自动携带 Token → 请求走网关
- **本地开发**:使用 fetch添加 `X-Dev-Mock-User` 头模拟用户
```js
// composables/useApi.js
import { useApi } from '@/composables/useApi'
const { get, post, put, del } = useApi()
const notes = await get('/api/notes')
```
### 图片处理
- **上传**:粘贴/拖拽 → `POST /api/upload/image`(走网关,带 Token
- **显示**`<img src="https://mokeetext.server.zgitm.com/api/file/{id}">`(走后端直连,公开读取)
- **预览**:点击图片 → 全屏灯箱,带关闭按钮
### UI 特性
- 左侧可收起导航栏(展开 "mokee编辑器",收起 "M"
- 文件夹侧边栏可收起
- 笔记列表 + 编辑器双栏布局
- Ctrl+S 保存,顶部 toast 提示
- 弹窗全部为 Vue 组件(非浏览器 alert/confirm
- 移动端响应式适配768px 断点)
- 顶栏右侧「切换系统」按钮 → 跳转网关系统选择页
---
## 生产环境
| 项目 | 值 |
|------|-----|
| 服务器 | 101.132.183.138 (腾讯云) |
| 前端地址 | https://mokeetext.zgitm.com |
| 后端地址 | https://mokeetext.server.zgitm.com |
| 数据库 | MySQL 10.20.1.122:3306/mokeetext |
| 日志路径 | /data/mokee/mokeetext/logs按天轮转保留 30 天) |
| ICP 备案 | 湘ICP备19021539号 |