# MistakeNotebook **Repository Path**: codekpy/mistake-notebook ## Basic Information - **Project Name**: MistakeNotebook - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-25 - **Last Updated**: 2026-09-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # AI 错题本(mistake-notebook) AI 驱动的错题管理应用:拍照/手打录入错题 → AI 多模态识别(题目/答案/解析/图形)→ 按学科与知识点分类 → AI 生成同类题。 同一份前端同时支撑两种形态: | 形态 | 技术 | 账号 | 数据 | |---|---|---|---| | 桌面端 | Tauri 2 + Rust + SQLite | 无(单机) | 本机数据目录(%APPDATA%\com.mnb.app) | | 云端版 | Node + Express + MySQL(宝塔 VPS) | DuckSite OAuth 登录 | 服务端数据库 | ## 仓库结构 ``` frontend/ # 唯一前端:React 19 + Vite + TS + Tailwind v4 + shadcn/ui(双构建目标) src/platform/ # 平台适配层:desktop(Tauri invoke)/ cloud(HTTP + SSE) src/ai/ # AI 对话循环与 function call 工具(双端共用) src-tauri/ # 桌面壳(Rust,SQLite、密钥保护、SSE 代理、IPC) server/ # 云端后端(Express + mysql2 + JWT + DuckSite OAuth + SSE AI 代理) shared/ # 跨端共享类型与协议(数据模型、API DTO、AI 事件) docs/ # 需求与文档 ``` ## 常用命令 | 目的 | 命令 | |---|---| | 桌面开发(Vite + Tauri 窗口) | `.\dev.cmd`(或 `.\tools.ps1 dev`,端口随机 5173-5372) | | 桌面打包(NSIS + MSI) | `.\build.cmd`(先关闭运行中的 exe) | | 前端开发(浏览器,云端模式) | `pnpm --filter frontend dev:cloud` | | 云端后端开发 | `pnpm dev:server`(见 server/README 或 AGENTS.md) | | 构建 | `pnpm build:desktop` / `pnpm build:cloud` / `pnpm build:server` | | 检查 | `pnpm typecheck` · `pnpm lint` · `pnpm test` · `cargo test --lib --manifest-path src-tauri/Cargo.toml` | ## 本机环境约定(换机器需改) - `tools.ps1` 顶部固化 `CARGO_HOME=G:\go-build\cargo`、`RUSTUP_HOME=G:\mc-dev\rustup`(缓存不落 C 盘)。 - 依赖用 pnpm(store 在 G 盘全局配置中,包体不落 C 盘),在项目根执行 `pnpm install`; **不要给 `node_modules` 建 junction**(pnpm 会报 `ENOTDIR`)。 - `.ps1` 含中文必须 UTF-8 **with BOM**;`.cmd` 一律纯 ASCII。 - dev 运行中不要 `git commit`(Windows autocrlf 会触碰 Rust 文件触发重建)。 ## Linux 云端安装部署 云端版由 React 前端和 Node.js 后端组成。生产环境构建后,后端会同时提供: - 前端网页:`http://服务器地址:3002/` - API 接口:`http://服务器地址:3002/api/*` 云端 AI 用量按用户的 `total_tokens` 统计。管理员可在“后台管理 · 用户”中为每个用户设置 Token 上限和时间窗口(分钟);Token 上限设置为 `0` 表示不限额。上游 AI 未返回有效用量时, 该次请求不会计入配额。 学科名称在同一用户内会按“去首尾空格、忽略大小写”查重;云端不同用户可以创建同名学科。 桌面端本地数据库视为一个用户,重复名称会被阻止。 AI 生成的题目在用户确认“保存入库”后写入 `generated_questions`,可从左侧“AI 题库”查看全部 已保存题目。删除 AI 对话不会删除已入库题目,数据备份也会包含这些题目。 思考模式下,桌面端和云端都会保留工具列表但移除强制 `tool_choice`,避免 DeepSeek 返回 `Thinking mode does not support this tool_choice`;识别、绘图和出题流程会继续尝试解析文本 JSON 作为兜底。 ### 题库、打印与右侧 AI - **题库详情**:左侧进入“AI 题库”后点击题目,可打开 `/question-bank/:id` 详情页;刷新页面仍可直接读取,来源错题支持跳转。 - **批量打印**:在“错题本”或“AI 题库”勾选题目后,可以打印当前选择;打印页按 A4 排版,可在系统打印对话框选择“另存为 PDF”。 - **下载 PDF**:批量选择后点击“下载 PDF”,浏览器会生成单个 `.pdf` 文件;PDF 包含题干、公式、选项、答案和解析,GeoGebra 以静态说明占位。 - **右侧 AI 助教**:解析图片、生成 SVG、生成 GeoGebra 均从错题详情右侧 AI 面板触发,结果先进入待采用提案,采用后回填当前表单,仍需点击“保存”。 - **停止 AI**:右侧停止按钮会取消当前流式请求和工具循环;GGB/SVG 生成的重试流程也会检查取消状态。 - **GGB 编辑**:生成或打开 GeoGebra 图形后点击“编辑 GGB”,修改完成点击“保存 GGB 修改”;编辑结果以 `GgbSpec.base64` 保存,取消不会改动当前草稿。 ### 运行环境 - Node.js 22 或更高版本 - pnpm 9 或更高版本 - MySQL 8(或兼容版本) - Linux Shell ### 1. 获取代码 如果服务器目录已经是 Git 仓库: ```bash cd /www/wwwroot/mistake-notebook git remote set-url origin https://gitee.com/codekpy/mistake-notebook.git git fetch origin git checkout master git reset --hard origin/master ``` 如果服务器目录还不存在: ```bash cd /www/wwwroot git clone https://gitee.com/codekpy/mistake-notebook.git mistake-notebook cd mistake-notebook ``` ### 2. 安装 pnpm ```bash corepack enable corepack prepare pnpm@latest --activate pnpm --version ``` ### 3. 创建生产配置 复制示范配置: ```bash cd /www/wwwroot/mistake-notebook cp server/.env.production.example server/.env nano server/.env ``` 至少修改以下配置: ```dotenv HOST=0.0.0.0 PORT=3002 FRONTEND_DIR=frontend/dist APP_BASE_URL=http://服务器IP:3002 DB_HOST=127.0.0.1 DB_PORT=3306 DB_USER=数据库用户 DB_PASSWORD=数据库密码 DB_DATABASE=mnb JWT_SECRET=随机长字符串 OAUTH_CLIENT_ID=OAuth客户端ID OAUTH_CLIENT_SECRET=OAuth客户端密钥 OAUTH_CALLBACK_URL=http://服务器IP:3002/api/auth/oauth/callback ``` `JWT_SECRET` 必须使用随机长字符串,不能使用示例中的占位符。可以执行: ```bash node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" ``` ### 4. 安装依赖并构建 ```bash pnpm install --frozen-lockfile pnpm build:cloud pnpm --filter shared typecheck pnpm --filter server typecheck ``` 构建成功后,前端文件位于 `frontend/dist/`。 ### 5. 启动服务 项目提供了一键构建和启动脚本: ```bash chmod +x deploy-cloud.sh ./deploy-cloud.sh ``` 脚本会自动执行依赖安装、云端前端构建、类型检查,然后启动后端。也可以手动启动: ```bash HOST=0.0.0.0 PORT=3002 pnpm --filter server start ``` 启动后访问: ```text http://服务器IP:3002 ``` ### 6. 初始化数据库 服务启动后,另开一个 SSH 窗口执行一次: ```bash curl -X POST http://127.0.0.1:3002/api/install ``` 检查服务和前端: ```bash curl http://127.0.0.1:3002/api/health curl -I http://127.0.0.1:3002/ ``` ### 7. 使用 PM2 常驻运行 生产环境建议使用 PM2: ```bash npm install -g pm2 cd /www/wwwroot/mistake-notebook HOST=0.0.0.0 PORT=3002 pm2 start "pnpm --filter server start" --name mistake-notebook pm2 save pm2 startup ``` 根据 `pm2 startup` 输出的提示执行对应命令,使服务器重启后自动恢复服务。查看日志: ```bash pm2 status pm2 logs mistake-notebook ``` ### 8. 更新部署 更新前备份生产配置,然后拉取代码并重新构建: ```bash cd /www/wwwroot/mistake-notebook cp server/.env /tmp/mistake-notebook.env.backup git fetch origin git checkout master git reset --hard origin/master cp /tmp/mistake-notebook.env.backup server/.env pnpm install --frozen-lockfile pnpm build:cloud pm2 restart mistake-notebook --update-env ``` 如果服务器防火墙或宝塔安全组启用了端口限制,需要放行 TCP `3002`。使用域名和 HTTPS 时,建议再通过 Nginx 反向代理到 `127.0.0.1:3002`,并将 `APP_BASE_URL` 和 OAuth 回调地址改为 HTTPS 域名。 ## 文档 - [plan.md](plan.md):总体规划(架构、阶段、数据模型、验证) - [tasks.md](tasks.md):任务进度跟踪 - [docs/需求.md](docs/需求.md):原始需求 - [AGENTS.md](AGENTS.md):开发约定与关键坑(AI 协作必读)