# fraglearn **Repository Path**: soaiprogram/fraglearn ## Basic Information - **Project Name**: fraglearn - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-01-26 - **Last Updated**: 2026-03-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # FragLearn 知识点管理系统 > **文档版本**:v2.3.1 > **最后更新**:2026-03-25 > **维护要求**:本文档基于实际代码结构编写,修改功能后需同步更新 **FragLearn** 是一个功能完整的多用户知识点管理系统,支持网页端和移动端。采用 **Vue3 + Node.js + SQLite + Flutter 混合架构**,提供知识库管理、云盘存储、电子书阅读、OCR识别等丰富功能。 ## 🎯 核心特点 - ✅ 混合架构:Flutter 原生 + H5 内嵌 - ✅ NAS 部署:Docker Compose(`fraglearn` + `cloudflared`) - ✅ 外网访问:Cloudflare Tunnel(已验证稳定,强制 `http2`) --- ## 🚀 小白只看这一段:本地改 → 提交 Git → NAS 升级 → APP 重装 > 记住一句话:**本机只改代码+提交 Git;NAS 只拉代码+重启 Docker;APP 仅在需要时重装**。 ### 0)先确认“线上地址” - 外网:`https://www.hhwxjdx.cn` - 健康检查:`https://www.hhwxjdx.cn/api/health` ### 1)本机(Windows CMD):提交到 Git ```bat cd /d "d:\AI_project\fraglearn1.1" && git add -A && git commit -m "chore: update" && git push origin main ``` ### 2)NAS:拉取 Git 并升级(一条命令直接复制) ```bash cd /vol2/1000/fraglearn && git pull origin main && \ sudo docker compose down --remove-orphans && \ sudo docker compose build --no-cache && \ sudo docker compose up -d && \ sudo docker compose ps ``` ### 3)手机流量验证外网 打开:`https://www.hhwxjdx.cn/api/health` 看到类似下面 JSON 就是通了: ```json {"ok":true,"dataDir":"/data","dbPath":"/data/knowledge.db"} ``` ### 4)APP 什么时候需要重新安装? - **不需要重装**:只改了 NAS 部署/隧道(如 `docker-compose.yml`、cloudflared)。 - **需要重装**:改了 APP/H5(Flutter 代码、前端页面、或 `project-config.json` 里的 `apiBaseUrl` 等)。 ### 5)本机重新打包 APK(Windows CMD) ```bat cd /d "d:\AI_project\fraglearn1.1" && npm run build && npm run sync-config && cd flutter_app && flutter build apk --release && flutter install ``` APK 输出位置: - `flutter_app/build/app/outputs/flutter-apk/app-release.apk` --- ## 🧭 遇到问题去哪里查?(只保留 3 个入口) 1. **部署/升级/外网/Docker/构建卡住**:`docs/部署经验总结.md` 2. **APP/混合架构/改了不生效**:`docs/混合架构详解.md` 3. **接口对接**:`docs/API接口文档.md` --- ## 📋 文档导航(精简版) - 部署/升级/外网/Docker/构建卡住:[`docs/部署经验总结.md`](./docs/部署经验总结.md) - APP/混合架构/为什么改了不生效:[`docs/混合架构详解.md`](./docs/混合架构详解.md) - 接口对接:[`docs/API接口文档.md`](./docs/API接口文档.md) - (可选)安全加固:[`docs/安全评估报告.md`](./docs/安全评估报告.md) --- ## 📋 文档导航(历史,待后续继续裁剪) ### 核心文档(日常使用) | 文档 | 用途 | 适合谁 | |------|------|--------| | 📙 [系统架构概览](./docs/系统架构概览.md) | ⭐ **必读**:技术栈、代码结构、数据流向 | 所有人 | | 📘 [API接口文档](./docs/API接口文档.md) | 完整API接口说明 (60+接口) | 开发者 | | 📗 [混合架构详解](./docs/混合架构详解.md) | Flutter+H5架构、修改生效流程 | 开发者 | | 📕 [本地开发指南](./docs/本地开发指南.md) | 本地环境搭建、开发调试 | 开发者 | | 📓 [NAS部署指南](./docs/NAS部署指南.md) | NAS部署、移动端构建 | 开发者/运维 | | 📒 [故障排查指南](./docs/故障排查指南.md) | 问题诊断和排查方法 | 所有人 | ### 运维文档(部署维护) | 文档 | 内容 | |------|------| | [部署经验总结](./docs/部署经验总结.md) | ⭐ 踩坑记录、事故复盘、最佳实践 | | [外网访问配置指南](./docs/外网访问配置指南.md) | Cloudflare Tunnel配置步骤 | | [项目升级指南](./docs/项目升级指南.md) | 系统升级步骤、回滚方法 | | [安全评估报告](./docs/安全评估报告.md) | 安全评估和加固建议 | ### 参考文档 | 文档 | 内容 | |------|------| | [文档整理建议](./docs/文档整理建议.md) | 📝 文档结构优化建议 | ### 常见问题速查 | 问题 | 去哪里找答案 | |------|-------------| | 配置改了没生效 | [部署经验总结](./docs/部署经验总结.md) → "配置管理规范" | | OCR识别失败 | [故障排查指南](./docs/故障排查指南.md) | | APK构建失败 | [NAS部署指南](./docs/NAS部署指南.md) → "移动端构建" | | NAS部署后无法访问 | [NAS部署指南](./docs/NAS部署指南.md) → "常见问题" | | 手机连不上服务 | [本地开发指南](./docs/本地开发指南.md) → "常见问题" | | **外网访问怎么配置** | 本文档 → "外网访问方案" | | 云盘上传失败 | [部署经验总结](./docs/部署经验总结.md) → "故障排查速查表" | | NAS编译时系统崩溃 | [部署经验总结](./docs/部署经验总结.md) → "4G内存NAS编译事故" | --- ## 🛡️ 安全须知(重要!) ### ⚠️ 外网部署前必读 系统**默认配置适合内网使用**,部署到外网前必须完成以下安全检查: #### 立即执行的安全加固 1. **修改默认密码**(关键) ```bash # 编辑 server/admin-config.json { "adminPassword": "YourStrongP@ssw0rd123!", "description": "已修改为强密码" } ``` 2. **运行安全检查脚本** ```bash node scripts/security-checklist.js ``` 3. **修改超管账号默认密码** - 用户名:`xiaopengshu` - 默认密码:`Admin123` - 部署后立即通过APP/Web修改 #### 已完成的安全增强(v2.1.1) ✅ **文件上传安全**:扩展名 + MIME类型双重验证 ✅ **API频率限制**:防止暴力破解(15分钟10次登录) ✅ **安全响应头**:使用 Helmet 加固HTTP头 ✅ **文件名安全**:禁止路径遍历字符(`..` `/` `\`) #### 已知限制 🟡 **密码哈希**:使用 SHA256(建议生产环境升级到 bcrypt) 🟡 **文件类型**:仍有可能被绕过(建议配合 Cloudflare WAF) #### 生产环境建议 - 启用 **Cloudflare Bot Fight Mode** - 配置 **Cloudflare 防火墙规则**: - 限制敏感路径(如 `/api/admin/*`)的访问IP - 开启 DDoS 防护 - 定期审查操作日志 - 数据库定期备份 > 📋 **详细安全评估报告**:`docs/安全评估报告.md` --- ## 🌐 外网访问方案 > **状态**:✅ 已配置并验证可用 > **公网地址**:`https://www.hhwxjdx.cn` ### 当前配置 | 项目 | 值 | |------|-----| | **公网访问地址** | `https://www.hhwxjdx.cn` | | **内网服务地址** | `http://192.168.31.250:7001` | | **穿透方案** | Cloudflare Tunnel | | **隧道运行位置** | 飞牛NAS(Docker容器) | | **域名** | `hhwxjdx.cn`(阿里云购买,DNS托管Cloudflare) | ### 为什么 FN Connect + `/app` 路径方案不可行 飞牛NAS自带的 FN Connect 服务(`https://fnos.net/xps1020`)**无法用于访问自定义应用**。 **技术原因**: ``` 用户请求 https://fnos.net/xps1020/app ↓ 飞牛云服务器(fnos.net) ↓ 专用隧道(封闭,无法配置) ↓ NAS后台管理服务(5666端口) ← 写死的目标,不是你的7001端口 ``` FN Connect 是飞牛官方提供的**封闭式穿透服务**,专门用于远程访问NAS管理后台。它的隧道目标是固定的(NAS系统服务),不支持用户自定义路由到其他端口或应用。 **结论**:即使在NAS上配置了Nginx反向代理,FN Connect也不会经过你的Nginx,而是直接转发到NAS后台。 > 📋 **失败案例详情**:完整的尝试过程和经验教训,请参考 [`docs/外网访问配置指南.md`](./docs/外网访问配置指南.md) → "失败案例记录" ### 方案说明 我们使用 **Cloudflare Tunnel** 实现外网访问,已验证稳定可用。 | 特性 | 说明 | |------|------| | **成本** | Tunnel服务免费,仅需域名费(首年约10元) | | **优点** | 无需公网IP、自动HTTPS、全球CDN、稳定可靠 | | **原理** | NAS上运行cloudflared容器,主动连接Cloudflare建立隧道 | ### 快速验证 ```bash # 外网访问测试 curl https://www.hhwxjdx.cn/api/health # 预期返回 {"ok":true,"dataDir":"/data","dbPath":"/data/knowledge.db"} ``` ### 详细配置文档 完整的配置步骤(包括NAS部署和Windows部署)请参考:[`docs/外网访问配置指南.md`](./docs/外网访问配置指南.md) ### APP配置 无论使用哪个方案,都需要更新配置让APP使用新地址: ```json // project-config.json { "activeProfile": "nas-public", "profiles": { "nas-public": { "apiBaseUrl": "https://www.hhwxjdx.cn", "storageKey": "knowledge_points_nas_public", "port": 443, "dataDir": "/vol2/1000/fraglearn-data/knowledge" } } } ``` 然后重新构建APP: ```bash npm run sync-config cd flutter_app && flutter build apk --release ``` --- ## 🏗️ 经验沉淀与快速参考 > **遇到问题不要怕,先看 [部署经验总结.md](./docs/部署经验总结.md) 有没有现成的答案** > > 该文档包含:所有踩坑记录、事故复盘、快速命令参考、故障排查速查表 ### 1. 文件上传跨文件系统问题 🆕 **现象**:云盘上传文件时报500错误,提示"上传文件失败,请重试" **根本原因**:`fs.renameSync()` 不能跨文件系统移动文件。在Docker容器中,`/tmp`(临时文件存放位置)和 `/data`(最终文件存放位置)通常挂载在不同文件系统上。 **解决方案**: ```javascript // 错误的写法 fs.renameSync(tempPath, targetPath) // 正确的写法(使用 copy + unlink) fs.copyFileSync(tempPath, targetPath) fs.unlinkSync(tempPath) ``` **代码位置**:`server/routes/cloud-disk.js` 第656-661行 **相关命令验证权限**: ```bash docker exec fraglearn ls -la /data/ docker exec fraglearn ls -la /data/cloud-disk/ ``` --- ### 2. Docker镜像拉取失败问题 **现象**:`docker pull` 命令失败,提示TLS握手超时或连接被拒绝 **根本原因**:国内网络访问Docker Hub受限 **解决方案**:使用DaoCloud镜像加速 ```bash # DaoCloud镜像(已验证可用) docker pull m.daocloud.io/docker.io/cloudflare/cloudflared:latest docker pull m.daocloud.io/docker.io/library/node:18-alpine ``` **项目已配置的镜像源**: - `Dockerfile` 中使用了 `FROM m.daocloud.io/docker.io/library/node:18-alpine` - `docker-compose.yml` 可配置镜像源前缀 --- ### 3. 配置同步遗漏问题 **现象**:修改配置后,APP或H5仍使用旧地址 **根本原因**:只修改了 `project-config.json`,但没有执行 `npm run sync-config`,或只同步了部分位置 **正确流程**: ```bash # 1. 修改 project-config.json # 2. 同步配置(会同步到6个位置) npm run sync-config # 3. 重新构建前端 npm run build npm run sync-config # 再次同步,确保dist/配置正确 # 4. 重新构建APP cd flutter_app && flutter build apk --release ``` **同步目标清单**: 1. ✅ `public/config.json` 2. ✅ `dist/config.json` 3. ✅ `server/config.json` 4. ✅ `flutter_app/assets/app_config.json` 5. ✅ `flutter_app/assets/web/config.json` --- ### 4. Flutter构建卡在Gradle下载 **现象**:`flutter build apk` 长时间没有输出,或提示Gradle下载超时 **解决方案**: ```bash # 1. 清理缓存 cd /d "d:\AI_project\fraglearn1.1" rmdir /s /q flutter_app\android\.gradle rmdir /s /q "%USERPROFILE%\.gradle\wrapper\dists\gradle-7.5-all" # 2. 配置国内镜像 # 编辑 flutter_app/android/build.gradle repositories { maven { url 'https://maven.aliyun.com/repository/public' } maven { url 'https://maven.aliyun.com/repository/google' } google() mavenCentral() } # 3. 重新构建 cd flutter_app flutter build apk --verbose ``` --- ### 5. Cloudflare Tunnel 连接不稳定(已验证修复方案) **现象**:外网访问时好时坏,APP 报 `Failed to fetch`,cloudflared 日志出现连接频繁重连/退出。 **已验证解决方案**:强制 cloudflared 使用 **HTTP/2(TCP)**,不要用默认 QUIC(UDP)。 - 本项目当前 `docker-compose.yml` 已固定: - `command: tunnel --no-autoupdate --protocol http2 run --token ${TUNNEL_TOKEN}` **排查/自检命令(NAS 终端执行)**: ```bash # 1) 看容器是否 healthy sudo docker compose ps # 2) 看 cloudflared 是否在用 http2(日志里应出现 Initial protocol http2) sudo docker logs cloudflared-tunnel --tail=80 # 3) 外网验证(任意外网/手机流量) curl https://www.hhwxjdx.cn/api/health ``` > 注意:`cloudflared` 容器里默认没有 curl/wget,这是正常的;用 NAS 宿主机跑 curl 验证即可。 --- ### 6. NAS Docker 容器/镜像莫名消失 + 构建超时问题(2026-03-12 重大故障)⚠️ **现象**: 1. NAS 上 `docker ps -a` 为空,所有容器/镜像都没了(包括 `fraglearn` 和 `cloudflared-tunnel`) 2. 执行 `docker compose up` 后一直在构建,卡在 `[app 4/7] RUN npm install` 不动 3. 看起来像"接着上次跑",实际是 **npm install 下载 sqlite3 预编译包超时** 4. 之前构建需要等几百秒甚至一整晚,表现为"页面一直刷" **根本原因**: 1. **容器/镜像消失**: - 可能是 NAS 系统更新/Docker 数据目录迁移/手动清理/系统故障导致 Docker 环境被重置 - 数据目录 `/vol2/1000/fraglearn-data/knowledge` 是 bind mount,不会跟着容器一起丢 2. **构建超时**: - Dockerfile 原先有三重回退逻辑(预编译包 → 备用源 → 源码编译),每次失败都要等超时才切换 - `sqlite3` 预编译包下载地址(`https://registry.npmmirror.com/-/binary/sqlite3`)网络不稳定 - 国内访问 DockerHub / GitHub Releases 超时 - 构建缓存层积累 31.7GB,每次 build 都从旧缓存继续(看起来"接着上次跑") **错误日志特征**: ``` [app 4/7] RUN npm install --production --build-from-source=false --unsafe-perm || \ => => # npm warn deprecated gauge@3.0.2: ... => => # (echo "预编译包安装失败,尝试备用源..." && ... Building 514.0s (11/17) ← 卡在这一步几百秒不动 ``` **解决方案**: **1)清理构建缓存(彻底"从头开始")** ```bash sudo docker builder prune -af # 会删除所有构建缓存(31.7GB) ``` **2)简化 Dockerfile npm install 逻辑(已修复)** 原先的三重回退逻辑会浪费大量时间在超时等待上: ```dockerfile # ❌ 旧版本(会卡住) RUN npm install --production --build-from-source=false --unsafe-perm || \ (echo "预编译包安装失败,尝试备用源..." && \ npm config set sqlite3_binary_host_mirror https://npmmirror.com/mirrors && \ npm install --production --build-from-source=false --unsafe-perm) || \ (echo "备用源失败,使用源码编译..." && \ npm install --production --unsafe-perm) ``` 修改为直接配置环境变量,单次安装: ```dockerfile # ✅ 新版本(70秒搞定) ENV SQLITE3_BINARY_SITE=https://registry.npmmirror.com/-/binary/sqlite3 ENV npm_config_sqlite3_binary_site=https://registry.npmmirror.com/-/binary/sqlite3 RUN npm install --production --build-from-source=false --unsafe-perm ``` **3)提前拉取 cloudflared 镜像(避免 DockerHub 超时)** ```bash sudo docker pull m.daocloud.io/docker.io/cloudflare/cloudflared:latest sudo docker tag m.daocloud.io/docker.io/cloudflare/cloudflared:latest cloudflare/cloudflared:latest ``` **完整恢复流程(已验证可用)**: ```bash # 1. 拉最新代码 cd /vol2/1000/fraglearn && git pull origin main # 2. 提前拉好 cloudflared 镜像(避免 DockerHub 超时) sudo docker pull m.daocloud.io/docker.io/cloudflare/cloudflared:latest sudo docker tag m.daocloud.io/docker.io/cloudflare/cloudflared:latest cloudflare/cloudflared:latest # 3. 停掉所有旧容器 sudo docker compose down --remove-orphans # 4. 清理构建缓存(确保从头开始) sudo docker builder prune -af # 5. 重新构建(优化后 70 秒完成,之前要几百秒) sudo docker compose build --no-cache # 6. 启动 sudo docker compose up -d # 7. 查看状态(应该都是 healthy) sudo docker compose ps ``` **关键改进效果**: - 构建时间:从 514+ 秒 → **70 秒** - 不再出现"接着上次跑"(清缓存后每次真正从头开始) - sqlite3 预编译包下载成功率 100%(强制走国内镜像) **教训总结**: - ⚠️ Docker 容器/镜像可能因系统故障/误操作消失,但 **数据目录(bind mount)不会丢** - ⚠️ Dockerfile 多重回退逻辑会导致每次失败都等超时,浪费大量时间 - ⚠️ 构建缓存积累太多(31.7GB)会让 build 看起来"续上次",定期清理很重要 - ✅ **环境变量直接配置镜像源** 比 `||` 回退更高效 - ✅ **提前拉取外部依赖镜像**(cloudflared)避免 compose 触发 DockerHub 超时 - ✅ 8G 内存 NAS 可以安全使用 `--no-cache`(使用预编译包,不编译 sqlite3) **故障时间线**: - 2026-03-12:发现容器全部消失,docker ps 为空 - 构建卡在 npm install 514+ 秒不动 - 清理 31.7GB 构建缓存 - 优化 Dockerfile 后 70 秒构建成功 - 服务恢复正常,两个容器都是 healthy 状态 --- ### 7. 数据目录权限问题 **现象**:服务启动正常,但无法写入数据,或数据库操作失败 **检查命令**: ```bash # 检查数据目录权限 ls -la /vol2/1000/fraglearn-data/knowledge/ # 预期输出 drwxr-xr-x 1 root root 52 Feb 4 08:56 . drwxr-xr-x 1 root root 4096 Feb 4 11:45 .. drwxrwx--x+ 1 root root 8 Feb 4 07:02 cloud-disk -rw-r-----+ 1 root root 204800 Feb 4 08:56 knowledge.db ``` **修复权限**: ```bash chmod -R 755 /vol2/1000/fraglearn-data/knowledge # 或 docker exec fraglearn chmod 777 /data/cloud-disk ``` --- ### 8. 电子书阅读器无法打开(epubjs 事件系统失效)⚠️ 关键问题 **现象**:点击电子书后,阅读器页面空白,控制台报错 `TypeError: u is not a function`,错误发生在 `EbookReader.vue` 或 `chunk-vendors.js` 中。 **根本原因**:`vue.config.js` 中配置了 `resolve: { alias: { 'es5-ext': false } }`,这导致 webpack 将所有 `es5-ext` 模块引用解析为 `false`。而 epubjs 的依赖链是: ``` epubjs → event-emitter → es5-ext (被禁用了!) + d → es5-ext (也被禁用了!) ``` 当 `es5-ext` 被禁用后: 1. `event-emitter` 模块无法正确初始化(`require('es5-ext/object/valid-callable')` 返回 false) 2. `d` 包也无法正常工作(`require('es5-ext')` 返回 false) 3. `EventEmitter(Book.prototype)` 执行时无法正确将 `on`、`off`、`emit`、`once` 方法挂到 Book 原型上 4. 导致 epubjs 所有依赖事件系统的功能全部失败(包括 `book.on()`、`book.emit()`、`rendition.on()` 等) **错误表现**: - 控制台错误:`TypeError: u is not a function`(`u` 是 webpack 压缩后的变量名,实际是 `on` 或 `emit` 方法) - EPUB 文件下载成功,ArrayBuffer 读取成功,但 ePub 实例创建后调用事件方法时崩溃 - 阅读器页面空白,无法渲染内容 **解决方案**: 1. **移除错误的 webpack alias**(已修复) ```javascript // vue.config.js - 错误配置(已删除) configureWebpack: { resolve: { alias: { 'es5-ext': false // ❌ 这行导致 epubjs 事件系统失效 } } } // 修复后:直接删除整个 configureWebpack 配置块,或移除 es5-ext: false ``` 2. **代码层面的防御性改进**(已实现) - 在 `EbookReader.vue` 中对 `book.on()` 和 `rendition.on()` 调用添加了安全守卫 - 直接传递 ArrayBuffer 给 `ePub()`,而不是先转成 Blob URL(避免类型识别问题) - 添加 `await book.opened` 确保 EPUB 完全解析后再进行后续操作 **修复后的代码关键点**: ```javascript // EbookReader.vue - 正确的初始化方式 const epubData = await getEpubData(bookId, downloadUrl) // 下载为 ArrayBuffer book = ePub(epubData) // 直接传 ArrayBuffer,epubjs 会正确识别为 BINARY 类型 // 安全守卫:检查事件方法是否存在 if (book && typeof book.on === 'function') { book.on('error', (error) => { console.error('[EbookReader] epub.js 错误:', error) }) } // 等待 EPUB 解析完成 if (book.opened) { await book.opened } ``` **验证修复**: ```bash # 重新构建项目 npm run build # 检查 chunk-vendors.js 大小变化 # 修复前:~410 KiB # 修复后:~412 KiB(增加了 es5-ext 相关代码) ``` **教训总结**: - ⚠️ **webpack alias 配置需谨慎**:禁用依赖模块可能导致深层依赖链断裂 - ⚠️ **问题定位要深入**:表面错误(`u is not a function`)可能源于底层依赖配置问题 - ✅ **防御性编程**:对第三方库的方法调用添加类型检查,避免运行时崩溃 - ✅ **直接使用原生支持**:epubjs 原生支持 ArrayBuffer,无需转成 Blob URL **相关文件**: - `vue.config.js` - webpack 配置(已修复) - `src/components/EbookReader.vue` - 电子书阅读器组件(已优化) - `package.json` - 依赖:`epubjs: ^0.3.93` **修复日期**:2026-02-09 --- ## 🔄 项目升级(NAS / 本机)(历史,已被顶部“小白只看这一段”覆盖) > 目标:把“本地改代码 → 推到 Git → NAS 拉取并升级”的流程写成小白可直接复制的命令。 ### A. 本地(Windows CMD)修改并同步到 NAS 的标准流程 > 你只需要在本机改代码,然后提交到 Git;NAS 上只做 `git pull + docker compose`。 **1)本机修改配置(如域名 / API 地址)** - 只改 `project-config.json`(不要手动改 `public/config.json` / `server/config.json` / `dist/config.json` / Flutter assets)。 - 然后执行: ```bash cd /d "d:\AI_project\fraglearn1.1" npm run sync-config npm run build npm run sync-config ``` **2)本机提交并推送到 Git(CMD 可直接一条执行)** ```bash cd /d "d:\AI_project\fraglearn1.1" && git add -A && git commit -m "chore: 同步配置与构建产物" && git push origin main ``` > 如果你只是改了 `docker-compose.yml` / `Dockerfile` / `scripts/*`,不需要 `npm run build`。 **3)NAS 上拉取并升级(NAS 终端执行)** ```bash cd /vol2/1000/fraglearn && git pull origin main && \ sudo docker compose down --remove-orphans && \ sudo docker compose build --no-cache && \ sudo docker compose up -d && \ sudo docker compose ps ``` ### B. NAS 日常升级(推荐) ```bash cd /vol2/1000/fraglearn && git pull origin main && \ sudo docker compose up -d --build && \ sudo docker compose ps ``` ### C. NAS “彻底从头来一次”(用于:构建卡住 / 镜像异常 / 依赖下载超时) > 会清理构建缓存(之前出现过 31.7GB 缓存),但**不会**影响数据目录 `/vol2/1000/fraglearn-data/knowledge`。 ```bash cd /vol2/1000/fraglearn && git pull origin main && \ sudo docker compose down --remove-orphans && \ sudo docker builder prune -af && \ sudo docker compose build --no-cache && \ sudo docker compose up -d && \ sudo docker compose ps ``` ### D. 外网可用性快速自检(手机流量 / 任意外网) ```bash curl https://www.hhwxjdx.cn/api/health ``` 预期: ```json {"ok":true,"dataDir":"/data","dbPath":"/data/knowledge.db"} ``` ### E. APP 是否需要重新打包/重装? - **仅改 NAS 部署/隧道(docker-compose / cloudflared)**:一般不需要重装 APP。 - **改了 `project-config.json` 并切换了 `apiBaseUrl`**: - 需要重新打包 APK(或至少确保 APP 使用的新 `app_config.json`)。 --- ## ⚡ 常用命令 ### 本地开发 ```bash # 终端1 - 启动后端 cd server && npm install && npm start # 终端2 - 启动前端 npm run serve ``` ### 构建并安装 APP ```bash # 一键构建并安装到手机 npm run build && npm run sync-config && cd flutter_app && flutter build apk --release && flutter install ``` 或者直接双击 `构建命令.cmd`。 ### 同步配置 ```bash npm run sync-config ``` ### NAS 快速升级 > 这一节与上面的“项目升级(NAS / 本机)”内容重复,后续以“项目升级(NAS / 本机)”为准。 --- ## 🎯 项目概述 ### 项目定位 **FragLearn** 是一个**超管专属的知识点管理系统**,支持网页端和移动端,用于个人知识点的创建、管理、学习和复习。 ### 核心价值 - ✅ **极简设计**:专注核心功能,无冗余特性 - ✅ **多端同步**:Web端和移动端数据统一,支持本地和NAS部署 - ✅ **OCR识别**:支持图片文字识别,快速录入知识点 - ✅ **离线可用**:移动端支持离线缓存,断网也能查看 - ✅ **云盘功能**:文件管理、上传下载、文件夹管理 - ✅ **现代UI**:深蓝科技风格、玻璃拟态设计、流畅动画 ### 目标用户 - **主要用户**:个人知识管理者(超管) - **使用场景**:学习笔记、知识点复习、知识库管理 - **技术背景**:支持小白用户,操作简单直观 --- ## 📝 功能特性 ### 核心功能 1. **用户认证与权限管理** 🆕 v2.0 - 完整的用户注册/登录系统 - 双角色体系:超级管理员 + 普通用户 - 密码找回/修改(支持原密码或密码提示验证) - 登录状态保持,缓存用户名 - 会话Token管理,7天自动过期 2. **邀请码系统** 🆕 v2.0 - 普通用户申请邀请码 - 超管审核并自动生成5位唯一邀请码 - 邀请码状态追踪(待审核→已通过→已核销) - 注册时邀请码校验和核销 3. **用户管理(超管专属)** 🆕 v2.0 - 查看系统内所有用户 - 手动开通新账号 - 启用/禁用账号状态 - 用户删除(软删除,保留数据) 4. **意见反馈系统** 🆕 v2.0 - 用户提交反馈 - 超管回复反馈 - 双向对话式交互 - 按角色权限差异化展示 5. **操作日志埋点** 🆕 v2.0 - 全面记录用户操作(登录、注册、密码修改、邀请码、反馈等) - 记录字段:用户ID、时间、事件、设备、IP、结果、失败原因 - 支持按时间、结果、事件类型筛选 - 普通用户仅看自己,超管看全部 6. **知识点管理** - 创建、编辑、删除知识点 - 支持标题、内容、备注、标签 - 支持子知识点(结构化内容) - 标签分类:英语、数学、逻辑、科学、历史 7. **OCR文字识别** - 支持图片上传和粘贴 - 服务端Tesseract OCR识别 - 支持印刷体和手写体识别 - 自动填充到内容输入框 8. **云盘功能** 🆕 v2.1 - 文件上传/下载(最大1GB) - 文件夹创建/重命名/删除 - 文件移动/复制 - 支持多种文件类型(图片、文档、音频、视频) - 玻璃拟态UI设计 9. **学习模式** - 知识点列表浏览 - 按标签筛选 - 关键词搜索(标题、内容、标签) - 详情页查看(支持上一个/下一个导航) 10. **电子书阅读功能** 🆕 v2.2 - EPUB 格式电子书阅读器(网页端和移动端) - 自动扫描云盘目录,识别 EPUB 文件并添加到书架 - 阅读进度自动保存和跨设备同步(CFI 定位) - 目录导航、章节跳转、进度条拖动 - 阅读设置:字体大小、主题切换(白天/夜间/护眼)、行间距 - 书签功能:添加/删除书签,书签列表跳转 - 移动端 IndexedDB 缓存,支持离线阅读 - 书架管理:排序(书名/最近阅读/添加时间)、从书架移除 11. **系统诊断与远程管理** 🆕 v2.0 - 分层连通性检测(设备网络→DNS→Cloudflare隧道→API服务) - 服务器状态监控(内存、运行时间、Docker容器状态) - 服务端日志查看和导出 - 远程重启服务(API服务、Cloudflare隧道) 12. **UI美化升级** 🆕 v2.1 - 深蓝科技风格主题系统 - 玻璃拟态效果设计 - 霓虹光效和渐变动画 - 全新登录页面(动态背景+发光Logo) - 全新云盘页面(悬浮按钮+多选模式) - 全新APP图标(渐变+动画效果) --- ## 🏗️ 技术架构 ### 技术栈 | 层级 | 技术 | 说明 | |------|------|------| | **前端** | Vue 3 + Vue CLI | 单页应用,响应式设计 | | **后端** | Node.js + Express | RESTful API服务 | | **数据库** | SQLite | 轻量级嵌入式数据库 | | **移动端** | Flutter + WebView | H5混合开发方案 | | **电子书** | epubjs 0.3.93 | EPUB 解析和渲染引擎 | | **OCR** | Tesseract.js (服务端) | 文字识别引擎 | | **部署** | Docker Compose + Cloudflare Tunnel | NAS 上双容器部署(fraglearn + cloudflared) | | **UI框架** | 自定义主题系统 | 深蓝科技风格 | ### 系统架构 ``` ┌─────────────────────────────────────────┐ │ 用户访问层 │ ├─────────────────────────────────────────┤ │ Web浏览器 │ Flutter APP (Android) │ │ │ - 全新科技风格UI │ └─────────────┴───────────────────────────┘ │ ▼ ┌─────────────────────────────────────────┐ │ 前端层 (Vue 3) │ ├─────────────────────────────────────────┤ │ - 页面路由 (首页/学习/管理/编辑) │ │ - 云盘功能(文件管理) │ │ - OCR图片处理 (压缩/上传) │ │ - API调用封装 │ │ - 配置管理 (运行时加载) │ │ - 玻璃拟态UI组件 │ └─────────────┬───────────────────────────┘ │ ▼ ┌─────────────────────────────────────────┐ │ 后端层 (Node.js + Express) │ ├─────────────────────────────────────────┤ │ - RESTful API (/api/knowledge) │ │ - 云盘API (/api/cloud-disk) │ │ - OCR服务 (/api/ocr) │ │ - 静态文件服务 (dist/) │ │ - CORS支持 │ └─────────────┬───────────────────────────┘ │ ▼ ┌─────────────────────────────────────────┐ │ 数据层 (SQLite) │ ├─────────────────────────────────────────┤ │ - knowledge表 (知识点数据) │ │ - cloud_disk_files (云盘文件) │ │ - cloud_disk_folders (云盘文件夹) │ │ - 索引优化 (title, tags) │ │ - 数据目录独立 (本地/NAS分离) │ └─────────────────────────────────────────┘ ``` ### 部署架构 ``` ┌─────────────────────────────────────────┐ │ 飞牛NAS (生产环境) │ ├─────────────────────────────────────────┤ │ ┌──────────────────────────────────┐ │ │ │ Cloudflare Tunnel (cloudflared) │ │ │ │ - 提供公网访问 │ │ │ │ - 自动HTTPS │ │ │ └──────────────┬───────────────────┘ │ │ │ │ │ ┌──────────────▼───────────────────┐ │ │ ┌──────────────────────────────────┐ │ │ │ fraglearn (Docker) │ │ │ │ - 提供 H5 + API (7001) │ │ │ └──────────────┬───────────────────┘ │ │ │ │ │ ┌──────────────▼───────────────────┐ │ │ │ fraglearn (Docker) │ │ │ │ - 端口: 7001 │ │ │ │ - Node.js + Express │ │ │ │ - Tesseract OCR │ │ │ └──────────────┬───────────────────┘ │ │ │ │ │ ┌──────────────▼───────────────────┐ │ │ │ SQLite数据库 + 云盘存储 │ │ │ │ - /vol2/1000/fraglearn-data/ │ │ │ │ - knowledge.db │ │ │ │ - cloud-disk/ │ │ │ └──────────────────────────────────┘ │ └─────────────────────────────────────────┘ ``` --- ## 📁 项目结构 ``` fraglearn1.1/ ├── project-config.json # ⭐ 主配置文件(唯一配置源) ├── package.json # 前端依赖 ├── vue.config.js # Vue CLI配置 │ ├── src/ # 前端源码 │ ├── App.vue # 主应用组件 │ ├── main.js # 入口文件 │ ├── components/ │ │ ├── EbookReader.vue # 🆕 电子书阅读器组件 │ │ └── EbookLibrary.vue # 🆕 电子书书架组件 │ ├── theme/ # 🆕 UI主题系统 │ │ └── app_theme.dart # 科技风格主题定义 │ ├── config/ │ │ └── runtime.js # 运行时配置加载 │ └── utils/ │ ├── api.js # API封装(含电子书相关API) │ └── ocr.js # OCR工具 │ ├── server/ # 后端服务 │ ├── index.js # Express服务入口 │ ├── db.js # SQLite数据库初始化 │ ├── config.js # 配置加载 │ ├── config.json # ⚠️ 自动生成,不要手动修改 │ ├── logger.js # 系统日志模块 │ ├── user-log.js # 用户操作日志埋点模块 │ ├── validators.js # 数据校验规则模块 │ ├── admin-config.json # 管理员密码配置 │ └── routes/ # 路由模块 │ ├── auth.js # 认证路由(登录/注册/密码) │ ├── users.js # 用户管理路由 │ ├── invite-codes.js # 邀请码路由 │ ├── feedback.js # 意见反馈路由 │ ├── logs.js # 操作日志查询路由 │ └── cloud-disk.js # 🆕 云盘路由 │ ├── flutter_app/ # Flutter移动端 │ ├── lib/ # Dart源码 │ │ ├── theme/ # 🆕 主题系统 │ │ ├── screens/ # 🆕 页面(含V2新版页面) │ │ └── widgets/ # 🆕 组件库 │ ├── assets/ │ │ ├── app_config.json # ⚠️ 自动生成 │ │ ├── app_icon.svg # 🆕 APP图标 │ │ └── web/ # H5构建产物(自动复制) │ └── pubspec.yaml # Flutter依赖 │ ├── public/ # 前端静态资源 │ ├── config.json # ⚠️ 自动生成 │ └── tesseract/ # OCR资源文件 │ ├── dist/ # 构建产物 │ └── config.json # ⚠️ 自动生成 │ ├── fraglearn-data/ # 数据目录(本地开发) │ └── local/ │ └── knowledge.db # SQLite数据库 │ ├── docs/ # 文档目录 │ ├── 本地开发指南.md # 本地开发文档 │ ├── NAS部署指南.md # NAS部署文档 │ ├── 外网访问配置指南.md # Cloudflare配置 │ ├── 故障排查指南.md # 问题排查 │ ├── 项目升级指南.md # 系统升级 │ ├── 技术架构.md # 技术架构文档 │ ├── 部署运维.md # 部署运维文档 │ ├── 开发指南.md # 开发指南文档 │ └── 混合开发边界规范.md # Flutter+H5边界规范 │ ├── scripts/ # 脚本目录 │ ├── sync-config.js # 配置同步脚本 │ ├── setup-tesseract.js # OCR资源设置 │ └── deploy-nas.sh # NAS部署脚本 │ ├── docker-compose.yml # Docker Compose配置 ├── Dockerfile # Docker镜像构建(使用DaoCloud镜像源) └── 构建命令.cmd # 一键构建脚本 ``` --- ## ⚙️ 配置管理 ### 统一配置系统 **核心原则**:所有配置都在 `project-config.json`,修改后运行 `npm run sync-config` 自动同步到所有子项目。 ### 配置文件结构 ```json { "activeProfile": "nas-public", "profiles": { "local": { "apiBaseUrl": "http://127.0.0.1:7001", "storageKey": "knowledge_points_local", "port": 7001, "dataDir": "../fraglearn-data/local" }, "nas": { "apiBaseUrl": "http://192.168.31.250:7001", "storageKey": "knowledge_points_nas", "port": 7001, "dataDir": "/vol2/1000/fraglearn-data/knowledge" }, "nas-public": { "apiBaseUrl": "https://www.hhwxjdx.cn", "storageKey": "knowledge_points_nas_public", "port": 443, "dataDir": "/vol2/1000/fraglearn-data/knowledge", "_comment": "域名 hhwxjdx.cn,通过 Cloudflare Tunnel 访问" } } } ``` ### 配置同步目标 | 目标文件 | 用途 | 同步内容 | |---------|------|---------| | `public/config.json` | 前端开发时使用 | API地址、存储键 | | `dist/config.json` | H5构建产物 | API地址、存储键 | | `server/config.json` | 服务端配置 | 端口、数据目录 | | `flutter_app/assets/app_config.json` | Flutter原生配置 | API地址、存储键 | | `flutter_app/assets/web/config.json` | Flutter内嵌H5 | API地址、存储键 | ### 配置切换流程 ```bash # 1. 修改 project-config.json,设置 "activeProfile": "nas-public" # 2. 同步配置 npm run sync-config # 3. 重新构建(如需要) npm run build npm run sync-config # 再次同步,确保dist/被复制到Flutter # 4. 重新构建APP cd flutter_app && flutter build apk --release ``` --- ## 🔄 数据模型 ### 数据库表结构 **users表**(用户): | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 主键,自增 | | `username` | TEXT | 用户名(唯一,4-16位) | | `password_hash` | TEXT | 密码哈希(SHA256+盐) | | `password_salt` | TEXT | 密码盐值 | | `password_hint` | TEXT | 密码提示(6-30位) | | `role` | TEXT | 角色:super_admin / normal_user | | `status` | TEXT | 状态:active / disabled / deleted | | `avatar` | TEXT | 头像标识 | | `created_at` | TEXT | 创建时间 | | `updated_at` | TEXT | 更新时间 | **invite_codes表**(邀请码): | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 主键,自增 | | `code` | TEXT | 邀请码(5位唯一) | | `applicant_id` | INTEGER | 申请人ID | | `status` | TEXT | 状态:pending / approved / used / rejected | | `used_by_id` | INTEGER | 使用者ID | | `created_at` | TEXT | 申请时间 | | `approved_at` | TEXT | 审核时间 | | `used_at` | TEXT | 使用时间 | **cloud_disk_folders表**(云盘文件夹): | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 主键,自增 | | `user_id` | INTEGER | 用户ID | | `folder_name` | TEXT | 文件夹名称 | | `parent_id` | INTEGER | 父文件夹ID(0=根目录) | | `path` | TEXT | 完整路径 | | `is_public` | INTEGER | 是否公共文件夹 | | `is_deleted` | INTEGER | 是否已删除 | | `created_at` | TEXT | 创建时间 | | `updated_at` | TEXT | 更新时间 | **cloud_disk_files表**(云盘文件): | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 主键,自增 | | `user_id` | INTEGER | 用户ID | | `file_name` | TEXT | 文件名 | | `file_ext` | TEXT | 文件扩展名 | | `file_size` | INTEGER | 文件大小(字节) | | `folder_id` | INTEGER | 所属文件夹ID | | `file_path` | TEXT | 物理文件路径 | | `md5` | TEXT | 文件MD5值 | | `is_deleted` | INTEGER | 是否已删除 | | `created_at` | TEXT | 创建时间 | | `updated_at` | TEXT | 更新时间 | **feedback表**(意见反馈): | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 主键,自增 | | `user_id` | INTEGER | 用户ID | | `title` | TEXT | 反馈标题 | | `content` | TEXT | 反馈内容 | | `parent_id` | INTEGER | 父级ID(用于回复) | | `created_at` | TEXT | 创建时间 | **user_logs表**(操作日志): | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 主键,自增 | | `user_id` | INTEGER | 用户ID | | `username` | TEXT | 用户名 | | `user_role` | TEXT | 用户角色 | | `event_id` | TEXT | 事件标识(如auth_login_success) | | `event_desc` | TEXT | 事件描述 | | `device` | TEXT | 操作设备 | | `ip_address` | TEXT | 操作IP | | `result` | TEXT | 结果:success / fail | | `fail_reason` | TEXT | 失败原因 | | `created_at` | TEXT | 操作时间 | **knowledge表**(知识点): | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 主键,自增 | | `title` | TEXT | 知识点标题 | | `content` | TEXT | 知识点内容 | | `note` | TEXT | 备注信息 | | `tags` | TEXT | 标签(字符串) | | `sub_points` | TEXT | 子知识点(JSON数组) | | `create_time` | TEXT | 创建时间 | | `update_time` | TEXT | 更新时间 | **ebooks表**(电子书)🆕: | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 主键,自增 | | `file_id` | INTEGER | 关联 cloud_disk_files.id | | `user_id` | INTEGER | 所属用户 | | `title` | TEXT | 书名 | | `author` | TEXT | 作者 | | `cover_path` | TEXT | 封面图片路径 | | `format` | TEXT | 格式(epub) | | `total_pages` | INTEGER | 总页数 | | `file_path` | TEXT | 文件完整路径 | | `file_size` | INTEGER | 文件大小(字节) | | `is_scanned` | INTEGER | 是否通过扫描添加 | | `created_at` | TEXT | 创建时间 | | `updated_at` | TEXT | 更新时间 | **reading_progress表**(阅读进度)🆕: | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 主键,自增 | | `ebook_id` | INTEGER | 关联 ebooks.id | | `user_id` | INTEGER | 用户ID | | `current_cfi` | TEXT | EPUB CFI 位置标识 | | `chapter_index` | INTEGER | 当前章节索引 | | `chapter_percent` | REAL | 章节内阅读百分比 | | `total_percent` | REAL | 全书阅读百分比 | | `current_page` | INTEGER | 当前页码 | | `is_finished` | INTEGER | 是否已读完 | | `last_read_at` | TEXT | 最后阅读时间 | | `created_at` | TEXT | 创建时间 | **bookmarks表**(书签)🆕: | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 主键,自增 | | `ebook_id` | INTEGER | 关联 ebooks.id | | `user_id` | INTEGER | 用户ID | | `cfi` | TEXT | 书签位置(CFI) | | `chapter_name` | TEXT | 章节名 | | `note` | TEXT | 备注 | | `created_at` | TEXT | 创建时间 | **sessions表**(会话): | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 主键,自增 | | `user_id` | INTEGER | 用户ID | | `token` | TEXT | 会话Token(唯一) | | `device` | TEXT | 设备类型 | | `ip_address` | TEXT | IP地址 | | `created_at` | TEXT | 创建时间 | | `expires_at` | TEXT | 过期时间(7天) | ### 数据目录结构 ``` fraglearn-data/ ├── local/ # 本地开发数据 │ └── knowledge.db └── (NAS环境) └── /vol2/1000/fraglearn-data/knowledge/ ├── knowledge.db # SQLite数据库 └── cloud-disk/ # 云盘文件存储 └── user/ └── {userId}/ ``` **重要**:代码和数据完全分离,上传代码时不会覆盖数据目录。 --- ## 🌐 API接口 ### 基础信息 - **基础URL**:根据配置环境自动选择(local/nas/nas-public) - **协议**:HTTP/HTTPS - **数据格式**:JSON - **CORS**:已启用,支持跨域 ### 接口列表 **认证模块** | 方法 | 路径 | 说明 | |------|------|------| | POST | `/api/auth/login` | 用户登录 | | POST | `/api/auth/register` | 用户注册 | | POST | `/api/auth/logout` | 退出登录 | | GET | `/api/auth/me` | 获取当前用户信息 | | POST | `/api/auth/forgot-password/verify` | 密码找回验证 | | POST | `/api/auth/forgot-password/reset` | 密码重置 | | POST | `/api/auth/change-password` | 修改密码 | **云盘模块** 🆕 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/api/cloud-disk/folders` | 获取文件夹列表 | | POST | `/api/cloud-disk/folders` | 创建文件夹 | | PUT | `/api/cloud-disk/folders/:id` | 重命名文件夹 | | DELETE | `/api/cloud-disk/folders/:id` | 删除文件夹 | | GET | `/api/cloud-disk/files` | 获取文件列表 | | POST | `/api/cloud-disk/files/upload` | 上传文件 | | GET | `/api/cloud-disk/files/:id/download` | 下载文件 | | DELETE | `/api/cloud-disk/files/:id` | 删除文件 | | PUT | `/api/cloud-disk/files/:id` | 重命名文件 | | POST | `/api/cloud-disk/move` | 移动文件/文件夹 | | POST | `/api/cloud-disk/copy` | 复制文件/文件夹 | **用户管理模块(超管)** | 方法 | 路径 | 说明 | |------|------|------| | GET | `/api/users` | 获取用户列表 | | POST | `/api/users` | 创建新用户 | | PUT | `/api/users/:id/status` | 修改用户状态 | | DELETE | `/api/users/:id` | 删除用户 | **邀请码模块** | 方法 | 路径 | 说明 | |------|------|------| | GET | `/api/invite-codes` | 获取邀请码列表 | | POST | `/api/invite-codes/apply` | 申请邀请码 | | POST | `/api/invite-codes/:id/approve` | 审核通过 | **意见反馈模块** | 方法 | 路径 | 说明 | |------|------|------| | GET | `/api/feedback` | 获取反馈列表 | | POST | `/api/feedback` | 提交反馈 | | POST | `/api/feedback/:id/reply` | 回复反馈 | **操作日志模块** | 方法 | 路径 | 说明 | |------|------|------| | GET | `/api/user-logs` | 查询操作日志 | | GET | `/api/user-logs/events` | 获取事件类型列表 | **知识点模块** | 方法 | 路径 | 说明 | |------|------|------| | GET | `/api/knowledge` | 获取知识点列表 | | GET | `/api/knowledge/:id` | 获取单个知识点 | | POST | `/api/knowledge` | 创建知识点 | | PUT | `/api/knowledge/:id` | 更新知识点 | | DELETE | `/api/knowledge/:id` | 删除知识点 | | POST | `/api/ocr` | OCR识别 | **电子书模块** 🆕 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/api/ebooks` | 获取电子书列表 | | GET | `/api/ebooks/:id` | 获取电子书详情 | | POST | `/api/ebooks` | 手动添加电子书到书架 | | DELETE | `/api/ebooks/:id/remove-from-shelf` | 从书架移除 | | POST | `/api/ebooks/scan-cloud-disk` | 扫描云盘自动添加电子书 | | GET | `/api/ebooks/:id/progress` | 获取阅读进度 | | POST | `/api/ebooks/:id/progress` | 保存阅读进度 | | GET | `/api/ebooks/:id/bookmarks` | 获取书签列表 | | POST | `/api/ebooks/:id/bookmarks` | 添加书签 | | DELETE | `/api/ebooks/:id/bookmarks/:bookmark_id` | 删除书签 | **系统诊断模块** | 方法 | 路径 | 说明 | |------|------|------| | GET | `/api/diagnose` | 系统诊断 | | GET | `/api/diagnose/network` | 网络诊断 | | POST | `/api/admin/restart` | 远程重启 | 详细API文档请参考 `docs/技术架构.md`。 --- ## 📝 变更日志 | 日期 | 版本 | 变更内容 | |------|------|---------| | 2026-02-11 | v2.2.2 | **电子书功能全面优化**:修复移动端封面跨域问题(强制使用当前API地址);实现全屏阅读器(z-index: 9999覆盖底部导航);添加移动端交互优化(点击中心显示/隐藏工具栏、3秒自动隐藏、滑动翻页);修复云盘导航闪烁问题(同步更新ID和面包屑);统一文件预览全屏体验(图片/Word/PDF均使用z-index: 2000弹出层);**代码清理**:删除废弃的Flutter原生电子书页面和未使用的H5阅读器HTML文件 | | 2026-02-11 | v2.2.1 | **PDF预览架构重构**:移动端PDF预览从H5的iframe方案彻底改为Flutter原生方案(解决白屏问题);H5通过JavaScript Bridge调用Flutter原生PDF渲染;废弃并删除 `PdfViewer.vue` 和 `pdfCache.js`;PDF缓存改用应用文档目录(更稳定);添加完整的文件格式验证和详细错误日志;服务端添加CORS响应头;**新增混合架构详解文档** | | 2026-02-09 | v2.2.0 | **电子书阅读功能上线**:新增 EPUB 电子书阅读器(网页端和移动端);自动扫描云盘目录识别 EPUB 文件;阅读进度自动保存和跨设备同步;目录导航、书签、阅读设置(字体/主题/行间距);移动端 IndexedDB 缓存支持离线阅读;**关键修复**:修复电子书阅读器无法打开问题(移除 vue.config.js 中错误的 `es5-ext: false` alias,修复 epubjs 事件系统失效) | | 2026-02-07 | v2.1.3 | **Bug修复**:修复PDF预览"无法登录"问题(下载接口支持query token认证);修复移动端上传无反应问题(分开图片上传和文件上传按钮,支持所有文件类型);整理合并重复文档 | | 2026-02-07 | v2.1.2 | **NAS部署优化**:Dockerfile 配置 `--build-from-source=false` 强制使用 sqlite3 预编译包,避免4G内存NAS编译时系统崩溃;修复 Dockerfile 重复CMD问题;更新README部署文档和经验沉淀 | | 2026-02-04 | v2.1.1 | **安全加固**:文件上传增加MIME类型验证和文件名安全检查;API接口添加频率限制(express-rate-limit);添加安全响应头(helmet);创建部署前安全检查脚本 | | 2026-02-04 | v2.1.0 | 新增云盘功能(文件上传下载、文件夹管理);UI全面升级(深蓝科技风格、玻璃拟态设计、全新登录页和云盘页);修复文件上传跨文件系统问题;更新README文档,增加经验沉淀章节 | | 2026-02-03 | v2.0.2 | 修复getApiBaseUrl未定义错误(H5登录页面报错);修复Flutter编译错误(await在非async函数中);优化日志统计显示(区分错误和警告);增加登录流程详细日志监控;APP版本升级至2.0.2 (Build 10) | | 2026-02-03 | v2.0.1 | 修复云盘创建文件夹提示未登录问题(添加认证中间件);修复H5登录后无法同步到Flutter的问题;添加全局错误日志收集功能;删除学习和知识库原生入口;优化登录状态同步机制,增加详细日志监控;APP版本升级至2.0.1 (Build 9) | | 2026-01-30 | v2.0.0 | 新增远程更新功能(自动检测、下载、安装APK);Dockerfile改用DaoCloud镜像源解决拉取失败问题;更新常用指令文档 | | 2026-01-30 | v2.0 | **重大升级**:新增完整用户认证系统(登录/注册/密码找回/修改);新增双角色权限体系(超管/普通用户);新增邀请码申请与审核系统;新增用户管理(超管专属);新增意见反馈系统(双向对话);新增全面操作日志埋点;APP版本升级至2.0.0 | | 2026-01-29 | v1.6 | 新增系统诊断功能:分层连通性检测、服务状态监控、日志查看、远程重启服务 | | 2026-01-29 | v1.5 | Flutter代码重构:统一API客户端、版本号管理、简化底部导航 | | 2026-01-29 | v1.4 | 外网访问配置验证成功,Cloudflare Tunnel方案上线 | | 2026-01-29 | v1.3 | 新增"文档维护规范"章节;添加失败案例记录 | | 2026-01-29 | v1.2 | 新增"外网访问方案"章节 | | 2026-01-29 | v1.1 | 拆分本地/NAS文档,简化文档导航 | | 2026-01-28 | v1.0 | 创建项目主文档 | --- **文档维护者**:项目开发团队