docs: 更新阶段2设计文档
+216
-12
@@ -93,51 +93,255 @@
|
|||||||
|
|
||||||
### 阶段2 (Python 后端)
|
### 阶段2 (Python 后端)
|
||||||
|
|
||||||
1. **存储迁移**:IndexedDB → SQLite
|
#### 2.1 后端与存储
|
||||||
2. **REST API**:Flask/FastAPI 提供 CRUD 接口
|
|
||||||
3. **真实翻译**:接入 Google Translate API 或 DeepL API
|
- 使用 Python + Flask 提供 REST API,并直接托管前端静态文件
|
||||||
4. **部署**:前端静态文件由后端服务
|
- 使用 SQLite 数据库,表结构见下方“数据库设计”
|
||||||
|
- 密码使用 Werkzeug 哈希存储,禁止明文
|
||||||
|
- 使用服务端 Session 管理登录状态,Cookie 存储 session id
|
||||||
|
|
||||||
|
#### 2.2 用户管理
|
||||||
|
|
||||||
|
- 注册:用户名、密码、显示名
|
||||||
|
- 登录 / 登出
|
||||||
|
- 管理员用户可:
|
||||||
|
- 查看全部用户
|
||||||
|
- 添加用户
|
||||||
|
- 禁用 / 启用用户
|
||||||
|
- 删除用户(同时删除该用户日记、收藏单词等数据)
|
||||||
|
- 普通用户不能访问管理员接口
|
||||||
|
- 被禁用用户无法登录,已登录会话立即失效
|
||||||
|
|
||||||
|
#### 2.3 数据隔离
|
||||||
|
|
||||||
|
- 日记、统计、收藏单词、翻译配置全部按 `user_id` 隔离
|
||||||
|
- 所有查询必须带当前登录用户的 `user_id`
|
||||||
|
- 服务端校验资源归属,禁止通过修改 URL/ID 访问他人数据
|
||||||
|
|
||||||
|
#### 2.4 知识库共享
|
||||||
|
|
||||||
|
- 知识库为公共静态页面,所有用户共享
|
||||||
|
- 不要求登录即可浏览知识库
|
||||||
|
|
||||||
|
#### 2.5 翻译配置
|
||||||
|
|
||||||
|
- 每个用户可以配置自己的翻译方式:
|
||||||
|
- 本地词典
|
||||||
|
- MyMemory 免费接口
|
||||||
|
- 自定义 HTTP 翻译接口(可配置 URL、请求头、字段映射)
|
||||||
|
- 配置项保存在用户自己的 `settings` 表中
|
||||||
|
- 后端执行在线翻译,避免浏览器跨域限制,也便于统一记录配置
|
||||||
|
|
||||||
|
#### 2.6 日记统计
|
||||||
|
|
||||||
|
- 每个用户可查看自己的统计:
|
||||||
|
- 总日记数
|
||||||
|
- 本月日记数
|
||||||
|
- 本周日记数
|
||||||
|
- 连续写作天数(streak)
|
||||||
|
- 最近 7 天每日条数
|
||||||
|
- 总西语字符数 / 平均每天字数
|
||||||
|
|
||||||
|
#### 2.7 单词本
|
||||||
|
|
||||||
|
- 每个用户可收藏单词
|
||||||
|
- 单词来自 B1 词库或日记中出现的词
|
||||||
|
- 收藏内容包括:西语单词、英语释义、中文释义、主题分类
|
||||||
|
- 支持添加、删除、列表查询
|
||||||
|
|
||||||
|
#### 2.8 前端适配
|
||||||
|
|
||||||
|
- 桌面:三栏布局
|
||||||
|
- 平板(768px - 1024px):两栏或紧凑三栏
|
||||||
|
- 手机(< 768px):单栏,列表、编辑、翻译通过页面区域切换
|
||||||
|
- 按钮触控区域不小于 40px,滚动区域适配触摸
|
||||||
|
- 保留 Web Speech API 发音
|
||||||
|
|
||||||
|
#### 2.9 安全
|
||||||
|
|
||||||
|
- 密码哈希存储
|
||||||
|
- Session Cookie 使用 `HttpOnly`、`SameSite=Lax`
|
||||||
|
- API 输入校验,防止 SQL 注入和 XSS
|
||||||
|
- 删除用户为级联删除
|
||||||
|
- 生产部署建议使用反向代理 + HTTPS
|
||||||
|
|
||||||
## 技术方案
|
## 技术方案
|
||||||
|
|
||||||
### 阶段1 技术栈
|
### 阶段1 技术栈
|
||||||
|
|
||||||
- 纯 HTML + CSS + JavaScript
|
- 纯 HTML + CSS + JavaScript
|
||||||
- IndexedDB 使用 idb 库或原生 API
|
- IndexedDB 使用原生 API
|
||||||
- Web Speech API 用于发音
|
- Web Speech API 用于发音
|
||||||
- 无构建工具,无依赖
|
- 无构建工具,无依赖
|
||||||
|
|
||||||
### 项目文件结构 (阶段1)
|
### 阶段2 技术栈
|
||||||
|
|
||||||
|
- Python 3 + Flask
|
||||||
|
- SQLite(Python 内置 sqlite3)
|
||||||
|
- Werkzeug(Flask 自带密码哈希)
|
||||||
|
- Vanilla JS 前端,保持无构建工具
|
||||||
|
|
||||||
|
### 项目文件结构 (阶段2)
|
||||||
|
|
||||||
```
|
```
|
||||||
spanish-diary/
|
spanish-diary/
|
||||||
|
server/
|
||||||
|
app.py — Flask 应用入口与路由
|
||||||
|
db.py — SQLite 初始化与连接
|
||||||
|
auth.py — 登录/会话/管理员权限
|
||||||
|
entries_api.py — 日记 CRUD 与统计
|
||||||
|
vocab_api.py — 单词本接口
|
||||||
|
settings_api.py — 翻译配置接口
|
||||||
|
translate_service.py — 本地/MyMemory/自定义翻译
|
||||||
index.html — 主页面
|
index.html — 主页面
|
||||||
style.css — 样式
|
style.css — 样式
|
||||||
app.js — 应用逻辑
|
app.js — 应用逻辑
|
||||||
db.js — IndexedDB 操作封装
|
api.js — 后端 API 客户端
|
||||||
|
db.js — IndexedDB 操作封装(阶段1兼容)
|
||||||
translate.js — 翻译模块
|
translate.js — 翻译模块
|
||||||
speech.js — 发音模块
|
speech.js — 发音模块
|
||||||
|
knowledge.html — 知识库首页
|
||||||
|
knowledge/ — 知识库分类页
|
||||||
|
b1-vocab.js — B1 词库
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 数据库设计
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE users (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
username TEXT UNIQUE NOT NULL,
|
||||||
|
password_hash TEXT NOT NULL,
|
||||||
|
display_name TEXT NOT NULL,
|
||||||
|
is_admin INTEGER NOT NULL DEFAULT 0,
|
||||||
|
is_active INTEGER NOT NULL DEFAULT 1,
|
||||||
|
created_at TEXT NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE entries (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
date TEXT NOT NULL,
|
||||||
|
spanish TEXT NOT NULL,
|
||||||
|
english TEXT NOT NULL DEFAULT '',
|
||||||
|
chinese TEXT NOT NULL DEFAULT '',
|
||||||
|
created_at TEXT NOT NULL,
|
||||||
|
updated_at TEXT NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_entries_user_date ON entries(user_id, date);
|
||||||
|
|
||||||
|
CREATE TABLE vocabulary (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
word TEXT NOT NULL,
|
||||||
|
english TEXT NOT NULL DEFAULT '',
|
||||||
|
chinese TEXT NOT NULL DEFAULT '',
|
||||||
|
category TEXT NOT NULL DEFAULT '',
|
||||||
|
created_at TEXT NOT NULL,
|
||||||
|
UNIQUE(user_id, word)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE settings (
|
||||||
|
user_id INTEGER PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
translator TEXT NOT NULL DEFAULT 'local',
|
||||||
|
api_url TEXT NOT NULL DEFAULT '',
|
||||||
|
api_key TEXT NOT NULL DEFAULT '',
|
||||||
|
extra_config TEXT NOT NULL DEFAULT '{}',
|
||||||
|
updated_at TEXT NOT NULL
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### API 设计
|
||||||
|
|
||||||
|
#### 用户与认证
|
||||||
|
|
||||||
|
| 方法 | 路径 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| POST | /api/register | 注册 |
|
||||||
|
| POST | /api/login | 登录 |
|
||||||
|
| POST | /api/logout | 登出 |
|
||||||
|
| GET | /api/me | 当前用户信息 |
|
||||||
|
| GET | /api/admin/users | 管理员查看用户 |
|
||||||
|
| POST | /api/admin/users | 管理员添加用户 |
|
||||||
|
| PUT | /api/admin/users/<id>/status | 启用/禁用 |
|
||||||
|
| DELETE | /api/admin/users/<id> | 删除用户 |
|
||||||
|
|
||||||
|
#### 日记与统计
|
||||||
|
|
||||||
|
| 方法 | 路径 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| GET | /api/entries | 当前用户日记列表 |
|
||||||
|
| POST | /api/entries | 新建日记 |
|
||||||
|
| PUT | /api/entries/<id> | 编辑日记 |
|
||||||
|
| DELETE | /api/entries/<id> | 删除日记 |
|
||||||
|
| GET | /api/entries/stats | 当前用户统计 |
|
||||||
|
|
||||||
|
#### 单词本
|
||||||
|
|
||||||
|
| 方法 | 路径 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| GET | /api/vocabulary | 收藏列表 |
|
||||||
|
| POST | /api/vocabulary | 收藏单词 |
|
||||||
|
| DELETE | /api/vocabulary/<id> | 删除收藏 |
|
||||||
|
|
||||||
|
#### 翻译配置
|
||||||
|
|
||||||
|
| 方法 | 路径 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| GET | /api/settings/translation | 获取翻译配置 |
|
||||||
|
| PUT | /api/settings/translation | 更新翻译配置 |
|
||||||
|
| POST | /api/translate | 翻译接口 |
|
||||||
|
|
||||||
|
### 前端兼容性
|
||||||
|
|
||||||
|
- 桌面:三栏
|
||||||
|
- 平板 768-1024px:两栏,编辑区优先
|
||||||
|
- 手机 <768px:单栏,通过标签或底部导航切换“日记 / 编辑 / 翻译 / 我的”
|
||||||
|
- 使用 CSS Grid + Media Query
|
||||||
|
- 输入框和按钮适配触摸操作
|
||||||
|
- 所有页面在 Chrome、Edge、Safari 手机端可用
|
||||||
|
|
||||||
## 交互细节
|
## 交互细节
|
||||||
|
|
||||||
- 点击左侧列表中的记录 → 主编辑区加载该记录内容,右侧显示翻译
|
- 点击左侧列表中的记录 → 主编辑区加载该记录内容,右侧显示翻译
|
||||||
- 修改主编辑区内容后点击保存 → 更新 IndexedDB,刷新左侧列表和右侧翻译
|
- 阶段1:修改主编辑区内容后点击保存 → 更新 IndexedDB,刷新左侧列表和右侧翻译
|
||||||
|
- 阶段2:通过后端 API 保存,同一账号在不同设备可同步
|
||||||
- 点击 🔊 → 使用 Web Speech API 朗读文本(自动选择对应语言语音)
|
- 点击 🔊 → 使用 Web Speech API 朗读文本(自动选择对应语言语音)
|
||||||
- 选择日期与已有记录相同 → 打开该记录而非新建
|
- 选择日期与已有记录相同 → 打开该记录而非新建
|
||||||
|
|
||||||
## 成功标准
|
## 成功标准
|
||||||
|
|
||||||
|
### 阶段1
|
||||||
|
|
||||||
- 打开 HTML 文件即可使用,无需任何安装
|
- 打开 HTML 文件即可使用,无需任何安装
|
||||||
- 新建、编辑、删除操作流畅无刷新
|
- 新建、编辑、删除操作流畅无刷新
|
||||||
- 翻译在保存后即时显示
|
- 翻译在保存后即时显示
|
||||||
- 发音功能在主流浏览器(Chrome/Edge)正常工作
|
- 发音功能在主流浏览器(Chrome/Edge)正常工作
|
||||||
- 页面关闭后重新打开,数据完整保留
|
- 页面关闭后重新打开,数据完整保留
|
||||||
|
|
||||||
|
### 阶段2
|
||||||
|
|
||||||
|
- 用户可注册、登录、登出
|
||||||
|
- 管理员可添加、禁用、删除用户
|
||||||
|
- 不同用户日记数据完全隔离
|
||||||
|
- 知识库对所有用户共享
|
||||||
|
- 每个用户可配置翻译方式和在线翻译
|
||||||
|
- 每个用户可查看日记统计
|
||||||
|
- 每个用户可收藏和管理自己的单词
|
||||||
|
- 前端在手机、平板、桌面均可用
|
||||||
|
- 后端 API 启动后前端通过 API 读写数据
|
||||||
|
- 未登录时不能访问个人数据接口
|
||||||
|
- 被禁用用户无法登录且已有会话失效
|
||||||
|
- 密码不以明文保存
|
||||||
|
|
||||||
## 后续阶段
|
## 后续阶段
|
||||||
|
|
||||||
- 阶段2 将 IndexedDB 数据迁移到 SQLite,通过 REST API 操作
|
- 阶段3 可增加:
|
||||||
- 接入真实翻译 API
|
- 忘记密码与邮箱验证
|
||||||
- 用户认证(可选)
|
- 用户头像与个人资料
|
||||||
- 多设备同步(可选)
|
- 分享日记
|
||||||
|
- 导出/导入数据
|
||||||
|
- Docker 部署
|
||||||
|
- HTTPS 部署
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user