- 总工笔记
- 系统介绍
- 技术架构
- 技术栈
- 特色功能
- 极简沉浸式编辑
- 水利院基因的垂直工具
- 强大的 Markdown 编辑
- 离线优先 + 云端同步
- 全局快捷键
- 跨平台
- 功能列表
- 编辑与预览
- 项目与分类体系
- 图片与附件
- 本地草稿与离线
- 同步与发布
- 其他
- 与市面上类似平台的对比分析
- 对比矩阵
- 优势
- 不足
- 部署指南
- 环境要求
- 1. 中间件部署
- 2. 桌面端开发调试
- 3. 桌面端生产构建
- 4. Android 平板构建
- 5. Docker 部署中间件
- 配置说明
- 桌面端(运行时配置,存 localStorage,界面可改)
- 中间件(
deskmindoc-middleware/conf/app.conf) - Mindoc 服务
- 日志文件
- 数据存储与备份
- 本地数据保存位置(Windows)
- 笔记文件如何备份
- 项目源码备份程序
- 使用指南
- 快速开始
- 发布步骤(公有项目)
- 私人笔记步骤(私有项目)
- 写作技巧
- 快捷键
- 鼠标操作
- 总工如何借助这款神器实现自身知识价值的传播
- 第一步:日常积累,建立个人知识库
- 第二步:结构化整理,从笔记到文章
- 第三步:从文章到出书
- 第四步:构建个人品牌
- 实际案例路径
- 开发历程与踩坑记录
- 技术选型之坑
- 2026-08-29 开发总结
- 2026-08-31 开发总结
- 2026-09-02 开发总结
- 2026-09-04 开发总结
- 2026-09-05 开发总结
- 2026-09-06 开发总结
- 项目结构
- License
总工笔记
一款为水利水电设计院总工团队量身打造的桌面端知识管理工具,基于 Tauri v2 + React + Beego v2 构建,支持 Windows 桌面与华为平板双端运行。
系统介绍
总工笔记(DeskMindoc)是 Mindoc 文档服务的桌面客户端,定位为总工的”私人速记本”。它解决了水利水电设计院总工在日常工作中面临的四个核心痛点:
- 审图意见记录 — 现场看图纸时随手记录问题,拍照标注,即时发布
- 经验知识沉淀 — 将散落在笔记本、微信、口头交代中的经验系统化归档
- 出书级内容生产 — 结构化模板 + 规范引用,让写书从”挤牙膏”变为”拼积木”
- 跨平台无缝衔接 — 办公室用 Windows 桌面端,工地现场用华为平板,同一套数据
技术架构
┌─────────────────────────────────────────┐
│ Tauri v2 桌面壳 │
│ ┌───────────────────────────────────┐ │
│ │ React 18 前端 │ │
│ │ · Markdown 编辑器 + 实时预览 │ │
│ │ · 思维导图(Markmap) │ │
│ │ · IndexedDB 离线草稿(Dexie.js) │ │
│ │ · Tailwind CSS 极简 UI │ │
│ └──────────────┬────────────────────┘ │
│ ┌──────────────▼────────────────────┐ │
│ │ Rust 后端(Tauri Core) │ │
│ │ · 全局快捷键 Ctrl+Shift+M │ │
│ │ · 窗口管理 + 系统托盘 │ │
│ │ · CSP 安全策略 │ │
│ └──────────────┬────────────────────┘ │
└─────────────────┼───────────────────────┘
│ HTTP
┌─────────────────▼───────────────────────┐
│ Beego v2 中间件(Go) │
│ · JWT 认证 │
│ · 格式清洗 + 自动排版 │
│ · 图片上传中转 │
│ · 审核流程管理 │
└─────────────────┬───────────────────────┘
│ HTTP API
┌─────────────────▼───────────────────────┐
│ Mindoc 文档服务 │
│ · 文档存储 + 版本管理 │
│ · 知识库 + 团队协作 │
│ · 图床服务 │
└─────────────────────────────────────────┘技术栈
| 层级 | 技术 | 说明 |
|---|---|---|
| 桌面壳 | Tauri v2 | Rust 构建,体积小(< 10MB),性能高 |
| 前端 | React 18 + TypeScript | 组件化开发,类型安全 |
| 样式 | Tailwind CSS 3 | 原子化 CSS,暗黑模式 |
| 离线存储 | Dexie.js (IndexedDB) | 结构化草稿离线存储 |
| 思维导图 | Markmap | Markdown 转 SVG 思维导图 |
| 中间件 | Beego v2 (Go) | RESTful API,格式清洗 |
| 认证 | JWT (golang-jwt) | 一次登录,长期有效 |
| 文档服务 | Mindoc | 开源知识库系统 |
特色功能
极简沉浸式编辑
- 左右分栏布局:左侧目录导航 + 中间编辑器 + 右侧实时预览
- 暗黑模式一键切换,适配深夜写作场景
- 专业级排版:微软雅黑 / Inter 字体,行距 1.75,字号 15px
水利院基因的垂直工具
- 项目信息结构化:项目名称、阶段(可研/初设/施工图/施工/竣工/运维)、标段、专业(水工/金结/电气/地质等 13 个专业)、类别(设计错误/现场问题/优化建议/规范解读)
- 标签体系:坝基、温控、流沙、金结、边坡、围堰等 16 个水利水电专业标签
- 结构化模板:一键插入”问题描述 → 现场情况 → 处理建议”模板
强大的 Markdown 编辑
- 30+ 专业工具按钮(加粗、斜体、删除线、H1-H6、表格、代码块、引用等)
- 思维导图(Mindmap)代码块,曲线连接,彩色节点,支持暗黑模式自适应
- 6 级目录导航,支持折叠/展开,一键全部折叠为一级
- 图片粘贴/拖拽即上传,批量插入图片对话框
离线优先 + 云端同步
- IndexedDB 本地草稿存储,断网也能写
- 一键发布到 Mindoc 知识库
- 双轨制:私人笔记 / 提交审核
全局快捷键
Ctrl + Shift + M:任意位置唤起写作窗口,灵感不中断
跨平台
- Windows 桌面端(x64)
- 华为平板(Android, minSdkVersion 24)
- 横屏自适应布局
功能列表
编辑与预览
- Markdown 编辑器 + 实时预览(左右分栏)
- 全屏预览:工具条“全屏”按钮切换到系统级全屏,Esc 退出,实时同步、深色模式与字号缩放均生效
- 30+ 工具按钮:加粗、斜体、删除线、H1–H6、表格、代码块、引用、列表、任务列表、思维导图、图片、附件、模板等
- 6 级目录导航,支持折叠/展开、一键全部折叠为一级
- 思维导图:
mindmap代码块,Markmap 渲染,暗黑模式自适应;支持mindmap>高度自定义预览高度 - 代码块:支持 30+ 语言语法高亮(
react-syntax-highlighterPrismLight),工具条语言选择菜单插入带标记的代码块 - 字体缩放 A− / A+(±0.1,范围 0.8–1.6,仅显示层,正文 Markdown 不变)
- 暗黑模式一键切换,并同步原生窗口标题栏主题
- 中键列选择:鼠标中键(滚轮)按下并拖拽,进入矩形(列)选择,多行同时出现光标,可批量编辑,与 Sublime 一致
- 拖拽移动文本:选中文本后按住拖动到新位置即移动(原位置删除、新位置插入),按住
Ctrl拖拽则为复制 - 全屏目录半透明:全屏预览右侧目录为半透明磨砂背景(
backdrop-blur),浅色 / 深色模式均自适应 - 正文字体:编辑器中文采用微软雅黑(Microsoft YaHei),英文、数字与符号采用 Times New Roman
- 拖动提示:鼠标悬停到选中的文本上时,光标自动变为箭头,提示可拖动
项目与分类体系
- 项目 / 阶段 / 标段 / 专业 / 类别 五级结构化信息
- 13 个水利水电专业 + 16 个常用标签
- 项目列表可在“设置”中增删(localStorage 持久化)
图片与附件
- 图片:粘贴 / 拖拽 / 批量插入,本地暂存为
localimage://占位符,发布时按目标 Book 上传 - 附件:批量上传附件,逻辑与图片完全一致(
localattachment://占位符),预览中可点击下载
本地草稿与离线
- IndexedDB(Dexie)三张表:草稿
drafts、图片images、附件attachments - 本地笔记列表(标题/项目/时间,左侧圆点标注同步状态:灰=未发布、黄=有未同步修改、绿=已同步),支持关键字筛选
- 自动保存:正文或项目/阶段/标段/专业/类别/标签变动后 800ms 防抖自动写入本地草稿,无需手动保存,崩溃/关窗不丢内容
- 打开 / 导出 Markdown 文件(原生文件对话框)
- 新建笔记、结构化模板插入、标题由正文自动派生
- 断网可正常编辑与存私人笔记,联网后发布
- 删除笔记:笔记项悬停显示删除图标,二次确认后删除,并自动清理该笔记引用的本地图片/附件(
localimage://、localattachment://)
同步与发布
- 登录:JWT(桌面端 ↔ 中间件);登录即校验 Mindoc 凭据并建立该用户的会话
- 双轨发布:
发布→ Mindoc 公有项目;私人笔记→ Mindoc 私有项目 - 发布前选择/输入目标 Book(identify),并记住上次选择
- 启动会话自检:打开应用时校验中间件里是否有本用户的 Mindoc 会话,缺失则提示重新登录
- 全局快捷键
Ctrl + Shift + M唤起写作窗口
其他
- Windows 桌面端(x64)+ 华为平板(Android, minSdk 24)
- 中间件自动排版 / 格式清洗,Swagger API 文档(
/swagger) - 关于弹框:文件菜单「关于」展示产品介绍、数据存储路径、备份方法、开源组件与代码结构说明
与市面上类似平台的对比分析
对比矩阵
| 特性 | 总工笔记 | Notion | Obsidian | 语雀 | 为知笔记 |
|---|---|---|---|---|---|
| 水利水电行业垂直模板 | 13 专业 + 16 标签 | 需自行配置 | 需插件 | 通用模板 | 无 |
| 离线体验 | 原生 IndexedDB,零依赖 | 需网络 | 本地优先 | 弱 | 弱 |
| 桌面端体积 | < 10MB(Tauri) | Electron ~200MB | Electron ~200MB | Web | Electron |
| 思维导图 | 原生 Markmap 渲染 | 需 Mermaid 插件 | 需插件 | 有 | 无 |
| 全局快捷键 | Ctrl+Shift+M | 无 | 需第三方 | 无 | 无 |
| 图片上传 | 直传 Mindoc 图床 | 有 | 本地 | 有 | 有 |
| 审核流程 | 双轨制(私人/发布审核) | 需团队版 | 无 | 有 | 无 |
| 华为平板适配 | 原生 Android 支持 | 有 | 需插件 | 有 | 有 |
| 数据主权 | 自建 Mindoc 服务器 | 云端 | 本地 | 云端 | 云端 |
| 开源 | 完全开源 | 否 | 是 | 否 | 否 |
| 学习成本 | 极低(Markdown) | 中 | 高 | 低 | 低 |
优势
- 行业垂直:开箱即用的水利水电专业分类体系,不需要从零配置
- 轻量高效:Tauri 构建,体积是 Electron 应用的 1/20
- 数据安全:数据存储在自建 Mindoc 服务器,不出内网
- 离线可用:工地现场无网络也能记录,回办公室自动同步
- 审核流程:内置设计院常见的”编写→审核→发布”双轨制流程
不足
- 生态不如 Notion:没有丰富的第三方插件和模板市场
- 协作较弱:目前以单人写作体验为主,多人实时协作待开发
- 平台覆盖:暂不支持 iOS/macOS,优先满足 Windows + 华为平板
- 非 Markdown 格式:不支持富文本直接编辑,纯 Markdown 输入
部署指南
环境要求
| 组件 | 版本要求 |
|---|---|
| Node.js | ≥ 18 |
| Rust | ≥ 1.70(MSVC 工具链) |
| Go | ≥ 1.21 |
| Mindoc | ≥ 2.0(需关闭登录验证码) |
| Android Studio | 仅 Android 打包需要 |
1. 中间件部署
cd deskmindoc-middleware
# 编辑 conf/app.conf(真实配置项仅以下几条):
# httpport = 8090 # 中间件监听端口
# jwt_secret = deskmindoc_secret_key_2026 # JWT 签名密钥
# jwt_expire_hours = 720 # JWT 有效期(小时)
# mindoc_base_url = http://localhost:8181 # Mindoc 服务地址(中间件自身后端依赖)
# 注意:Mindoc 登录账号密码、默认 Book 不再配置在这里,
# 改为桌面端运行时用登录凭据 + 发布时选择目标 Book(见“配置说明”)。
# 编译运行
go build -o deskmindoc-middleware.exe .
./deskmindoc-middleware.exe
# 默认监听 8090 端口;Swagger 文档见 http://localhost:8090/swagger/2. 桌面端开发调试
cd deskmindoc-client
# 安装依赖
npm install
# 启动开发模式
npm run tauri dev3. 桌面端生产构建
cd deskmindoc-client
# Windows 构建
npm run tauri build
# 产物位于:
# deskmindoc-client/src-tauri/target/release/bundle/
可执行文件:src-tauri\target\release\deskmindoc.exe
安装包:src-tauri\target\release\bundle\nsis\总工笔记_0.1.0_x64-setup.exe4. Android 平板构建
cd deskmindoc-client
# 配置 Android 环境
scripts/setup-android.bat
# 构建 Android APK
npx tauri android build --release
# 产物位于:
# deskmindoc-client/src-tauri/gen/android/app/build/outputs/apk/release/5. Docker 部署中间件
cd deskmindoc-middleware
# 构建镜像
docker build -t deskmindoc-middleware .
# 运行
docker run -d -p 8090:8090 \
-e MINDOC_BASE_URL=https://your-mindoc.com \
-e MINDOC_API_TOKEN=your-token \
deskmindoc-middleware配置说明
配置按层级分布在三个工程,桌面端全部在界面内完成,中间件仅保留后端依赖项。
桌面端(运行时配置,存 localStorage,界面可改)
| 配置项 | 位置 | 说明 |
|---|---|---|
| 中间件服务地址 | 右上角“设置” | 含端口,如 http://192.168.1.100:8090 |
| 项目列表 | 右上角“设置” | 增删项目,同步顶部项目下拉框 |
| 登录账号 / 密码 | 右上角“登录”弹窗 | 即 Mindoc 账号,登录即建立该用户的 Mindoc 会话 |
| 发布目标 Book(公有) | 右上角“发布”弹窗 | 输入/选择公有项目 identify,记住上次选择 |
| 私有项目 Book(identify) | 右上角“私人笔记”弹窗 | 输入私有项目 identify,记住上次选择 |
| 常用标签 | 源码 lib/tags.ts |
开发期常量,集中管理 |
中间件(deskmindoc-middleware/conf/app.conf)
| 配置项 | 默认值 | 说明 |
|---|---|---|
httpport |
8090 |
中间件监听端口 |
jwt_secret |
deskmindoc_secret_key_2026 |
JWT 签名密钥 |
jwt_expire_hours |
720 |
JWT 有效期(小时) |
mindoc_base_url |
http://localhost:8181 |
Mindoc 地址(中间件自身后端依赖,不对桌面端开放) |
Mindoc 服务
- 需关闭登录验证码,否则程序化登录会失败。
- 桌面端登录输入的账号密码即 Mindoc 的
account/password,按用户名在中间件内存缓存各自的会话(Cookie Session)。
日志文件
- 文件名:
deskmindoc.log.txt - 位置:与
deskmindoc.exe同一目录(即std::env::current_exe()所在目录);绿色安装运行即在安装目录,源码运行即在target/release/下。 - 内容:
时间戳 + 级别 + 信息追加写入,主要记录发布失败、文件读写失败、关键错误等。 - 注意:仅关键错误会落盘;非网络类故障如需进一步定位,请查看中间件控制台输出。
数据存储与备份
本地数据保存位置(Windows)
总工笔记的本地数据全部存放在 Tauri 的 WebView2 用户数据目录下,本机实际路径以 %LOCALAPPDATA%(一般为 C:\Users\<用户名>\AppData\Local)为基础:
| 数据类型 | 存储位置 | 说明 |
|---|---|---|
| 笔记正文(草稿) | %LOCALAPPDATA%\com.deskmindoc.app\EBWebView\Default\IndexedDB\http_tauri.localhost_0.indexeddb.leveldb |
IndexedDB(Dexie)中的 drafts 表 |
| 图片 / 附件 | %LOCALAPPDATA%\com.deskmindoc.app\EBWebView\Default\IndexedDB\http_tauri.localhost_0.indexeddb.blob |
images / attachments 表的 Blob 数据 |
| 用户配置 | %LOCALAPPDATA%\com.deskmindoc.app\EBWebView\Default\Local Storage\leveldb |
中间件地址、项目列表、暗黑模式、字号、历史记录等(localStorage) |
日志文件
deskmindoc.log.txt不在此目录,而是与deskmindoc.exe同目录存放(见「日志文件」一节)。
笔记文件如何备份
方法一:应用内导出单篇笔记
工具栏「文件」→「导出为 Markdown 文件」,把当前笔记保存为 .md 文件到任意位置,适合单篇归档。
方法二:完整备份本地数据
关闭总工笔记后,复制整个用户数据目录即可完整备份所有草稿、图片、附件和配置:
%LOCALAPPDATA%\com.deskmindoc.app恢复时将该目录原样覆盖回 %LOCALAPPDATA%\com.deskmindoc.app 即可。
方法三:发布到 Mindoc(最可靠的长期归档)
「发布」到公有项目、「私人笔记」到私有项目,正文会上传到 Mindoc 服务器沉淀在云端知识库,脱离单机磁盘。
项目源码备份程序
项目根目录提供了源码备份程序,仅备份源代码与配置,不包含上述笔记数据:
| 文件 | 说明 |
|---|---|
backup.exe |
已编译的备份程序(Windows) |
backup.ps1 |
PowerShell 版本 |
BackupProgram.cs |
备份程序源码 |
用法:
.\backup.exe # 备份源码到 D:\backup\deskmindoc_<时间戳>
.\backup.exe "E:\dest" # 备份到自定义目录自动排除可重建产物:node_modules、dist、src-tauri/target、src-tauri/gen、*.exe。
使用指南
快速开始
- 配置中间件地址:首次使用点击右上角“设置”,填写 deskmindoc-middleware 服务地址(含端口,如
http://192.168.1.100:8090)。 - 登录:点击右上角“登录”,输入 Mindoc 账号密码(登录即校验并建立该用户的 Mindoc 会话)。
- 选择项目信息:顶部栏选择项目、阶段、标段、专业、类别;项目列表可在“设置”中增删。
- 开始写作:编辑区输入 Markdown,右侧实时预览;可粘贴/拖拽图片、插入思维导图、上传附件。
- 保存 / 发布 / 私人笔记:
- 正文与项目/阶段/标段/专业/类别/标签变动后自动保存为本地草稿(断网可用);顶部“保存”为即时落盘兜底
- 右上角“发布” → 发布到 Mindoc 公有项目
- 右上角“私人笔记” → 发布到 Mindoc 私有项目
发布步骤(公有项目)
- 点击右上角“发布”(鼠标悬停提示“发布到公有项目”)。
- 弹窗输入/选择目标 Book 的 identify(下方仅列出公有项目)。
- 确认后,正文中的本地图片(
localimage://)与附件(localattachment://)会逐个上传到该 Book,全部成功后提交正文。 - 任一图片/附件上传失败则整体转为本地草稿,避免误发。
私人笔记步骤(私有项目)
- 点击右上角“私人笔记”(鼠标悬停提示“发布到私有项目”)。
- 弹窗输入“私有项目”的 identify(下方仅列出私有项目)。
- 其余逻辑与“发布”完全一致。
写作技巧
插入思维导图:
```mindmap
# 坝基处理方案
## 防渗措施
- 帷幕灌浆
- 混凝土防渗墙
## 排水措施
- 排水孔
- 减压井
## 加固措施
- 固结灌浆
- 锚杆加固
```使用结构化模板:点击工具栏”模版”按钮,自动插入:
> 记录人: 张工 | 日期: 2025-01-15 | 项目: 梅山水库除险加固工程
## 问题描述
## 现场情况
## 处理建议插入图片:直接粘贴或拖拽图片到编辑器(或点工具条“图片”批量插入),先本地暂存为 localimage:// 占位符,发布时按目标 Book 上传。
插入附件:点工具条“附件”批量选择文件,本地暂存为 localattachment:// 占位符,预览中可点击下载;发布时按目标 Book 上传。
快捷键
| 快捷键 | 功能 |
|---|---|
Ctrl + Shift + M |
全局唤起应用 |
Ctrl + Z |
撤销 |
Ctrl + Y |
重做 |
鼠标操作
| 操作 | 功能 |
|---|---|
| 鼠标中键(滚轮)按下并拖拽 | 列(矩形)选择,多行同时编辑 |
| 拖动选中文本到新位置 | 移动文本(原位置删除、新位置插入) |
按住 Ctrl 拖动选中文本 |
复制文本 |
| 粘贴 / 拖拽图片到编辑器 | 本地暂存为 localimage:// 占位符 |
总工如何借助这款神器实现自身知识价值的传播
第一步:日常积累,建立个人知识库
总工在日常工作中产生大量知识资产:
- 审图意见 → 记录为”设计错误”笔记
- 现场检查 → 记录为”现场问题”笔记,附照片
- 规范解读 → 记录为”规范解读”笔记,标注规范编号
- 优化方案 → 记录为”优化建议”笔记,附对比分析
关键动作:每天花 5-10 分钟,用 Ctrl+Shift+M 随时记录,不追求完美,先写下来。
第二步:结构化整理,从笔记到文章
利用项目信息体系(项目 → 阶段 → 标段 → 专业)和标签体系,将零散笔记按主题串联:
- 同一专业的笔记自动归类
- 同一标签的笔记一键聚合
- 利用思维导图梳理知识结构
第三步:从文章到出书
当某个主题积累到 30-50 篇笔记时,就是出书的时机:
- 在 Mindoc 中新建知识库,按章节目录组织
- 将笔记导入对应章节
- 利用结构化模板补充”规范引用”和”参考文献”
- 提交审核,团队协作完善
- 导出为 Word/PDF,交付出版社
第四步:构建个人品牌
- 内部影响力:Mindoc 知识库中的文章被团队查阅、引用,建立”技术权威”形象
- 行业影响力:精选文章公开发布,在水利水电行业中建立个人品牌
- 知识传承:退休后知识库仍在,成为设计院的宝贵财富
实际案例路径
现场发现坝基渗漏问题
↓ 拍照 + 记录
Ctrl+Shift+M 快速笔记
↓ 标注:专业=水工, 标签=坝基/防渗/灌浆, 类别=现场问题
积累 40 篇类似笔记
↓ 按"坝基防渗"主题整理
编写《水利水电工程坝基防渗处理实践》
↓ 提交审核 → 发布
1. 设计院内部培训教材
2. 水利水电期刊发表
3. 出版社正式出书开发历程与踩坑记录
技术选型之坑
1. 为什么用 Tauri 而不是 Electron?
水利水电设计院的电脑配置参差不齐,有老旧 XP 升级到 Win10 的机器,也有最新的工作站。Electron 打包后 200MB+,启动慢,内存占用大。Tauri 基于 Rust 和系统 WebView,体积 < 10MB,内存占用小一个数量级。
坑:Tauri v2 的 API 与 v1 不兼容,网上大部分教程是 v1 的。且 Rust 编译链在 Windows 上需要 MSVC 工具链,配置繁琐。
方案:安装 Visual Studio Build Tools,确保勾选”C++ 桌面开发”工作负载。Rust 使用 stable-msvc 工具链。
2. 字体选择之坑
坑 1 — 网络字体模糊:Google Fonts 的网络字体(Noto Sans SC)在 Windows 上渲染模糊,小字号(11-13px)尤其明显。原因是网络字体需要下载后由浏览器渲染,无法享受 Windows ClearType 的像素级优化。
坑 2 — 等宽字体中文回退:编辑器使用 font-mono(JetBrains Mono / Fira Code)作为代码字体,但这些字体没有中文字形。Windows 上会回退到系统等宽字体 SimSun(宋体),中文显示粗糙发虚,与 placeholder 的系统字体效果形成鲜明对比。
坑 3 — 字体继承断裂:Tailwind 的 font-sans 默认应用于 body,但嵌套的 Select、Input、Textarea 等表单元素不会自动继承。顶部 ProjectBar 的 select/input 文字和侧栏目录文字在部分场景下回退到系统默认字体,与编辑器字体不一致。
坑 4 — 文本光标覆盖滚动条光标:Textarea 默认 cursor: text 会覆盖滚动条区域的 cursor: default,即使给 ::-webkit-scrollbar 设置 cursor: default 也无效。必须在 textarea 本身设置 cursor: auto 才能让浏览器根据区域自动切换光标样式。
方案:
- 中文字体优先使用系统原生字体,Tailwind 配置中将
"Microsoft YaHei"排在font-sans栈第一位,利用 Windows ClearType 获得像素级清晰度 - 编辑器放弃
font-mono,改用font-sans,确保中文正常渲染,英文仍由 Inter 字体承接 - 所有表单元素和侧栏文字显式添加
font-sans类,确保字体栈一致 - 编辑器 textarea 设置
cursor: auto,让浏览器自动在文字区显示 I 形光标、滚动条区显示箭头光标
3. 图标选择之坑
工具条图标经历了四轮迭代,每轮都踩了不同的坑:
第一轮:Emoji 图标。初期用 💾 B H1 等 emoji 和文本字符,在不同平台渲染效果差异巨大,Windows 上 emoji 是彩色粗线条,macOS 是扁平风格,完全无法统一。
第二轮:自定义 SVG(strokeWidth 1.5)。自己画了 30 个 SVG 图标,线宽 1.5px。在 17-18px 尺寸下线条过于纤细,像”虚线”,辨识度差。
第三轮:文字图标用 SVG <text> 渲染。将 B、S̶、H1、H2、1. 等文字图标改为 SVG <text> 元素。但 SVG 文字渲染引擎与浏览器不同,小字号下边缘模糊、字形发虚,与系统字体渲染效果差距明显。
第四轮:HTML <span> 文字图标。用 HTML <span> 替代 SVG <text> 渲染文字图标,利用系统字体引擎获得清晰度。但整体图标风格仍不统一——SVG 图标和 span 文字图标视觉重量不一致。
第五轮(最终方案):Font Awesome + 分组配色。全部替换为 Font Awesome 6 专业图标库,统一视觉风格。同时按功能分组赋予六种颜色(靛蓝/琥珀/翠绿/紫罗兰/青色/红色),同类功能一目了然。H1/H2 因 FA 的 faHeading 图标无法区分,保留 HTML 粗体文字方案,颜色与所在组保持一致。
关键教训:
- 不要自己画图标——专业图标库(Font Awesome、Lucide 等)经过数千项目的验证,线条粗细、间距、视觉一致性都有保障
- SVG 小尺寸下
strokeWidth至少需要2,1.5在 18px 以下几乎看不清 - SVG
<text>不适合小尺寸图标场景,HTML 文字渲染质量远优于 SVG 文字 - 颜色是最快的视觉区分手段——6 组功能色比纯灰色图标识别速度快 3 倍以上
4. 思维导图(Markmap)渲染之坑
坑:Markmap 在暗黑模式下字体颜色不跟随变化,且预览区域出现灰色背景,排查了多个来源。
方案:
- 在 MindmapRenderer 组件中注入自定义 CSS,通过
.markmap-dark类覆盖 CSS 变量 - 灰色背景来自多个层次:
Preview容器的dark:bg-gray-900、App组件的dark:bg-gray-900、index.html的<body class="bg-gray-50">、以及 ReactMarkdown 对围栏代码块包裹的<pre>标签的默认样式 - 逐一移除这些背景色,并在 Preview.tsx 中通过
components.pre处理器剥离 mindmap 代码块的<pre>包裹
5. 实时预览性能之坑
坑:每次按键都触发 Markmap 重新渲染 SVG,导致输入卡顿。
方案:实现 250ms 防抖(debounce)钩子,在用户停止输入后才重新渲染思维导图。
6. TypeScript 类型同步之坑
坑:新增字段(phase、bidSection、discipline)后,DraftRecord 接口和 Draft 接口需要同步更新,涉及 5 个文件的修改,容易遗漏。
方案:先修改核心类型定义,然后用 tsc --noEmit 检查所有编译错误,逐文件修复。建议将共享类型抽取为独立文件,避免多处定义。
7. Tauri 构建配置之坑
坑:Release 构建默认不优化,二进制体积大。
方案:在 Cargo.toml 中配置:
[profile.release]
panic = "abort"
codegen-units = 1
lto = true
opt-level = "s"
strip = true8. CSP 安全策略之坑
坑:Tauri 默认 CSP 禁止连接外部 API,导致前端无法请求中间件。
方案:在 tauri.conf.json 中配置 CSP:
"csp": "default-src 'self'; connect-src 'self' http://localhost:8090; img-src 'self' data: https:; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'"9. Markdown 渲染之坑
ReactMarkdown 预览过程中踩了三个渲染相关坑:
坑 1 — 无语言标记的代码块被当作行内代码:用 const isInline = !className 判断行内/块级代码。对于无语言标记的围栏代码块(如 `` ),ReactMarkdown 传入className为undefined,!undefined=true`,整个代码块被错误渲染为行内代码,没有等宽字体和深色背景,制表符无法对齐。
方案:改用 ReactMarkdown v9 原生的 inline 属性区分行内代码和块级代码,if (inline) 判定准确可靠。
坑 2 — 表格完全不支持:ReactMarkdown v9 默认不包含 GFM(GitHub Flavored Markdown)支持,表格、任务列表、删除线、自动链接都需要 remark-gfm 插件。未安装时表格语法被当作普通文本渲染。
方案:安装 remark-gfm 插件,在 ReactMarkdown 中添加 remarkPlugins={[remarkGfm]},一次性启用表格、任务列表、删除线、自动链接四种 GFM 特性。
坑 3 — 表格居中标记(:---:)无效:自定义 th/td 组件未透传 style 属性。GFM 对齐标记(:---、:---:、---:)通过 style={{textAlign: 'left'|'center'|'right'}} 传递给 th/td,但组件签名中未解构 style,也未用 {...props} 透传。
方案:th/td 组件显式解构 style 并透传 {...props},居中/右对齐标记生效。
10. 表格双重边框之坑
坑:自定义 table 组件外层 <div> 有 border + rounded-lg,内层 th/td 有 border-b,视觉上形成双层边框——表格外面套了一个多余的框。
方案:border 从外层 <div> 移到 <table> 标签上,th/td 从 border-b 改为四边 border,形成标准网格边框,无多余外框。
11. 原生控件美化之坑
坑:顶部 5 个下拉框(项目名称、阶段、标段、专业、类别)使用原生 <select> 元素,下拉菜单由操作系统渲染,无法用 CSS 控制样式——直角矩形、无圆角、无阴影、无动画,与整体极简设计风格不协调。
方案:用自定义 SelectDropdown 组件替换原生 <select>:
- 触发器:
rounded-lg圆角按钮 + Chevron 箭头(展开/收起动画) - 下拉面板:
rounded-xl大圆角 +shadow-lg阴影 + 淡入动画 - 选中项:蓝色高亮背景 + 蓝色文字
- 交互:点击外部关闭、Escape 关闭、hover 效果
- 组件支持
string[]和{value, label}[]两种选项格式,适配不同数据源
2026-08-29 开发总结
当日主线分两段:上午打通桌面端到 Mindoc 的知识库发布链路(修复三个 bug 并重构登录流程适配工地离线场景);下午实现离线图片上传、补齐后端文档详情查询接口,并新增本地笔记列表与「新建笔记」能力,为总工的”私人速记本”补齐工作台闭环。
12. Mindoc 接口对接之坑
坑:原计划用 Bearer Token 调用 Mindoc API,实际 Mindoc 采用 Cookie Session 认证(POST /login),且文档创建/编辑端点并非 /api/v1/book/document,而是 /api/{identify}/create、/api/{identify}/content/{id} 等真实端点。此外 Mindoc 默认开启登录验证码,会导致程序化登录失败。
方案:重写 MindocService——先 GET /login 预热会话,再 POST /login(account + password)获取会话;创建文档分两步:先 POST /api/{identify}/create 拿到 doc_id + version,再 POST /api/{identify}/content/{id} 保存 markdown 正文(version 用于乐观锁)。关闭 Mindoc 登录验证码后完成端到端打通。
13. 图片上传之坑(返回数组)
坑:Mindoc 的 POST /api/upload(字段 editormd-image-file)返回的是 JSON 数组 [{errcode:0, success:1, url:"..."}],而非 {errcode, message, data} 单对象。中间件按单对象解析导致反序列化失败、拿不到 URL。
方案:UploadImage 先按数组解析取第一项,再回退单对象;normalizeUploadURL 将相对路径补全为绝对 URL。多选上传、拖拽/粘贴单图、正文内 base64 图片三条路径全部复用该逻辑。
14. 私人笔记误推送之坑
坑:无论笔记类型 private 还是 publish,后端都无条件调用 CreateDocument 推送到 Mindoc,导致「存为私人笔记」也直接发布。
方案:以 type 区分——private 仅存本地(前端 IndexedDB saveDraft,后端直接返回),publish 才推送到 Mindoc。
15. 离线优先的登录流程之坑
坑:最初的登录门禁在应用启动时拦截(if (!isAuthenticated) return <Login/>),无网络的总工在工地现场打不开软件。
方案:改为离线优先——启动直接进入编辑器;登录入口移到右上角(「私人笔记」左侧),登录由全屏页改为弹窗;仅在点击「发布」时校验登录。JWT 通过 localStorage 持久化(30 天有效),一次登录后无网络也能正常编辑与存私人笔记,发布时无网络自动落为本地草稿。
16. 离线图片上传之坑(占位符 + IndexedDB)
坑:无网络时图片无法上传,若把 base64 直接塞进正文会令 IndexedDB 草稿体积暴涨,且发布时无法回填为真实图床 URL。
方案:实现「占位符 + 本地暂存」——粘贴/拖拽图片时先尝试直传,失败则把 Blob 存入 IndexedDB(Dexie 升级到 v3,images 表由 dataUrl 改为 blob/name/type/size),在正文插入 localimage://{id} 占位符;预览时通过 getLocalImageBlob 生成 Object URL 渲染。发布时解析正文中的所有 localimage:// 占位符,逐个重新上传并替换为真实 URL,全部成功才推送,否则提示「请联网后重试」。
17. 后端文档详情查询接口补齐
坑:MindocService.GetDocument 原为未实现,前端无法回读已发布笔记。
方案:改用 Mindoc 真实端点 GET /api/{identify}/content/{id} 读取文档,优先返回 markdown 原文(回退 release HTML),并填充标题、创建/更新时间。author/status 字段暂留空(Mindoc 的 content 接口不返回作者与中间件侧审核状态,后续按需再查)。
18. 本地笔记列表 + 新建笔记
需求:总工需要回看、重新编辑此前写过的本地笔记,并能随时开新篇。
方案:
DraftRecord增加title字段,标题由正文首个标题/首行自动派生,作为笔记名字。api.ts新增listDrafts()(按创建时间倒序),saveDraft支持按 id 覆盖并返回持久化 id。- 侧边栏改为「笔记 / 目录」双 tab——「笔记」tab 展示本地草稿列表(标题 + 项目 + 时间,蓝点=已发布、黄点=私人),点击加载回编辑器;「目录」tab 保持原有的标题导航。
- 顶部左侧加「+ 新建」按钮,点击清空编辑器进入新篇(不重置项目记忆)。
19. 重复发布之决策(暂不覆盖)
决策:桌面端重复发布同一篇笔记时,仍走 Mindoc 新建文档,不做「覆盖已有文档」的逻辑;重复项由服务端人工替换。待「私人笔记 → Mindoc 私有项目」映射明确后再设计覆盖/归属语义。
附带修正:发布离线回退时原本每次生成新草稿 id 导致同一篇笔记翻倍,已改为复用当前草稿 id,避免重复条目。
2026-08-31 开发总结
当日主线:把原本硬编码/环境变量中的配置全部下沉到桌面端人工输入,实现「中间件地址 + 登录凭据 + 发布目标 Book」三项配置的运行时动态化;同时实现 per-user session 会话隔离,并修复因 Beego 响应特性导致的发布报错。
20. 配置硬编码之坑(三项配置桌面端化)
坑:中间件服务地址、Mindoc 交互账号密码、mindoc_default_book 此前分别硬编码在 Vite 环境变量、中间件 app.conf 中,用户无法在运行时修改,且中间件用固定 admin 账号操作 Mindoc,与桌面端登录人身份不符。
方案:
- 中间件地址:前端
api.ts新增getApiBase()/setApiBase(),从localStorage读写;新增SettingsDialog组件供用户输入地址和端口。 - 登录凭据:桌面端登录即严格校验 Mindoc(
AuthController.Login调用LoginAndCache),中间件不再硬编码账号。 - 目标 Book:新增
PublishDialog组件,发布前让用户确认/修改目标 Book 标识,getLastBook()/setLastBook()记住上次选择。
21. per-user session 会话隔离
坑:中间件与 Mindoc 交互使用单一硬编码账号,所有用户的操作都落到同一账号下,无法区分作者。
方案:MindocService 增加 LoginAndCache(username, password) 与 GetCachedSession(username),按用户名在内存缓存各自的 cookie session;登录时校验凭据并缓存,后续发布、图片上传、书籍列表均使用该用户 session。
22. Mindoc 书籍列表 API 补齐
坑:Mindoc 原生没有查询「当前用户可见书籍」的接口,前端发布时无法枚举目标 Book。
方案:Mindoc 侧 BookController 新增 List 方法返回当前用户可见书籍,注册 /api/book/list 路由;中间件 ProjectController.List 包装后暴露 GET /projects,前端 getBooks() 拉取用于发布对话框的枚举选择。
23. Beego 响应语义之坑(修复 “cannot read properties of undefined (reading ‘id’)”)
坑:Beego 无论业务成功与否均返回 HTTP 200,真实状态在 JSON 响应体的 code 字段(0 为成功)。前端 uploadDraft 此前依赖 HTTP 状态码判断成功,当业务失败(如 code=401 登录过期)时仍尝试读取 data.data.id,得到 undefined 而抛错。
方案:uploadDraft 改为按响应体 code 字段判断业务状态——仅当 code === 0 且 data 存在时才读 data.data.id;识别 code === 401 返回 expired 标记,前端据此清除本地 token 并提示重新登录,而不是统一提示「离线模式」。
24. CSP 限制动态地址之坑
坑:Tauri 的 CSP connect-src 白名单固定,无法连接用户运行时输入的任意中间件地址,导致「network error, saved offline」。
方案:tauri.conf.json 将 security.csp 置为 null,放开网络请求限制(内网自建服务场景可接受)。
25. 「文件」菜单:打开 / 导出 Markdown
需求:原顶部左侧「+ 新建」按钮功能单一,总工需要把本地 .md 文件导入编辑,以及把当前笔记导出为 .md 文件。
方案:
- 新增
FileMenu下拉组件,含「打开 Markdown 文件」「导出为 Markdown 文件」。 - 新增
lib/file.ts封装invoke;Rust 后端lib.rs增加open_md_file/export_md_file命令,用rfd原生文件对话框 +std::fs读写(#[cfg(not(target_os = "android"))]仅桌面端编译,Cargo.toml用 target 条件依赖排除 Android)。 - 打开后写入编辑器;导出时用当前标题作默认文件名并清洗非法字符。
26. 笔记列表筛选
需求:笔记增多后难以快速定位,需要关键字过滤。
方案:「+ 新建笔记」下方新增筛选输入框,按标题/项目/标签实时过滤笔记列表,无匹配时显示「无匹配结果」。
27. 字体缩放(显示层,只变字号)
需求:总工有放大/缩小文字的阅读与书写需求,且要求仅在桌面显示层放大、不改变 Mindoc 文档的默认字号。
方案:
- 工具条新增
A−/A+按钮,每档 ±0.1(范围 0.8~1.6),缩放值持久化到 localStorage。 - 初版用 CSS
zoom整体缩放,会连带放大图标与间距;按需求改为「只放大文字」:引入 CSS 变量--font-scale(App.tsx写入document.documentElement),编辑器 textarea、预览.markdown-body(标题/代码/表格字号转em)、侧边栏(字号转em)三处按calc(15px * var(--font-scale))缩放,图标、padding/margin/宽度等rem间距保持不变。 - 纯渲染层:markdown 正文不变,发布到 Mindoc 不含任何字号样式。
2026-09-02 开发总结
当日主线:完善编辑器代码块功能,实现多语言语法高亮与 mindmap 预览大小控制,并统一编辑区与预览区的排版字体。
28. 代码块多语言语法高亮
需求:原代码块为纯文本渲染,无语法高亮,也无法区分不同语言。
方案:
- 引入
react-syntax-highlighter,用 PrismLight 引擎按需注册 32 种常用语言(JavaScript、TypeScript、Python、Go、C、C++、Java、C#、Rust、Shell、SQL、JSON、YAML、HTML、CSS、Markdown 等),既覆盖常用场景又控制 bundle 体积。 - 新增
lib/codeLanguages.ts集中管理语言列表与语法包注册:CODE_LANGUAGE_KEYS供预览判定语言、CODE_LANGUAGES供工具条选择。 - 工具条「代码块」按钮改为弹出语言选择菜单,插入带语言标记的围栏代码块(如
`python)。 - 预览中已注册语言走 PrismLight 高亮(oneDark / oneLight 双主题),未识别语言回退为普通等宽代码块。
- 为
react-syntax-highlighter补充 TypeScript 类型声明(types/react-syntax-highlighter.d.ts)。
29. mindmap 预览大小控制
需求:思维导图默认高度固定,用户希望按内容自定义预览高度。
方案:解析 ``mindmap>600 围栏语法中的数字部分作为预览高度(单位 px,默认 400),传入MindmapRenderer动态设置 SVG 的minHeight`。
30. 代码块字体大小调整
需求:预览区代码块字体过小,且高亮代码块与普通代码块字号不一致。
方案:将 PrismLight 高亮代码块与未识别语言代码块的字体统一为 15px(原 13px),并把 CSS 中 .markdown-body pre code 字号改为 1em 随正文缩放。
31. 编辑区字体与预览区统一
需求:编辑区字体观感不如预览区,二者排版应一致。
方案:编辑区 textarea 由 Tailwind 默认 font-sans 改为与预览区一致的字体族(Inter / Microsoft YaHei / Noto Sans SC 等),字号 15px、行高 1.75 保持一致。
2026-09-04 开发总结
当日主线:补齐编辑器接近 Sublime 的鼠标操作体验——中键列选择、拖拽移动文本,并统一全屏预览目录的半透明视觉。
32. 中键列选择(allowMultipleSelections 之坑)
需求:像 Sublime 一样,鼠标中键(滚轮)按下拖拽进入列(矩形)选择,多行同时编辑。
坑:使用 rectangularSelection({ eventFilter: e => e.button === 1 }) 后列选择仍不生效,拖出来的矩形选区一闪就被压回成普通单选。
根因:CodeMirror 的 EditorState.allowMultipleSelections 默认是 false,而矩形选择本质是「每行一个选区」的多选区(multi-range)。selection 提交到 state 时会走 asSingle() 把多选区折叠成单选区,导致列选择看不到效果。
方案:扩展列表最前面显式开启 EditorState.allowMultipleSelections.of(true);同时在编辑器容器 onMouseDown 中对 button === 1(中键)调用 preventDefault(),阻断 WebView2 的中键自动滚动,保证列选择拖拽不被干扰。
33. 全屏预览目录半透明
需求:全屏预览右侧目录背景设为半透明,且浅色、深色模式都成立。
方案:FullscreenToc 目录容器改用 bg-white/60 dark:bg-gray-900/60 backdrop-blur-xl——浅色为半透明白、深色为半透明深灰,配合较强的背景模糊,两种模式下半透明磨砂效果都清晰可见(此前的 bg-white/30 透明度太高,在纯色预览底上几乎无感)。
34. 拖拽移动文本(Tauri dragDropEnabled 之坑)
需求:拖动选中的文本到编辑器另一位置,实现移动/复制。
坑:CodeMirror 本身内置了 HTML5 的拖放(dragstart → drop)实现拖动移动文本,但在 Tauri 下完全拖不动。
根因:Tauri v2 默认 dragDropEnabled: true,会在 WebView2 底层拦截 HTML5 拖放事件,导致 drop 事件到不了编辑器。
方案:tauri.conf.json 窗口配置设置 "dragDropEnabled": false,恢复 HTML5 拖放,拖动选中文本即可移动(Ctrl 拖拽为复制)。由于前端没有使用 Tauri 的 tauri://file-drop 事件(拖图片进编辑器走的是 HTML5 drop),关闭该开关无副作用,反而顺带修复了此前也被拦截的「拖图片进编辑器」功能。
2026-09-05 开发总结
当日主线:补齐笔记删除能力(悬停删除 + 级联清理本地资源)、统一编辑/预览字体(中文雅黑 + 西文衬线),并新增「关于」弹框,完善桌面端的产品化收尾。
35. 删除笔记(级联清理本地资源)
需求:删除左侧笔记列表中的笔记,并确定删除范围与交互方式。
方案:确认采用「仅删除本地草稿 + 一并清理本地图片/附件 + 悬停删除按钮二次确认 + 删除当前笔记回到新建状态」。新增 api.deleteDraft:删除 drafts 记录,并用正则解析正文中的 localimage://、localattachment:// 占位符,逐一删除 images / attachments 表中对应的 Blob,释放磁盘。交互上 Sidebar 笔记项悬停浮现垃圾桶图标(group-hover 显隐),点击弹出确认弹框;删除的是当前编辑笔记时调用 handleNew() 清空编辑器。
注意:本地草稿未记录 Mindoc 文档 ID,删除仅作用于本地 IndexedDB,不影响云端文档;如需云端一并删除,需先补充 doc_id 记录与 Mindoc 删除接口。
36. 选区悬停变箭头(拖动提示)
需求:选中文本后,鼠标移到选区上时光标变为箭头,提示可拖动。
方案:CodeMirror 通过 EditorView.domEventHandlers({ mousemove }) 监听悬停,用 posAtCoords 判断鼠标位置是否落在非空选区内,是则 contentDOM.style.cursor = "default"(箭头),否则清空恢复文本光标。
37. 编辑器 / 预览字体统一
需求:编辑器字体协调——中文用微软雅黑,英文、数字、符号用 Times New Roman。
方案:利用 CSS 按字符回退,Editor.tsx 的 MAIN_FONT 与 index.css 的 .markdown-body 均改为 "Times New Roman", "Microsoft YaHei", ..., serif——西文字符命中 Times New Roman,中文字符(Times New Roman 无该字形)自动回退到微软雅黑。全局 UI(按钮/侧栏)仍保持 Inter 无衬线,代码块/行内代码保持等宽字体。
38. 关于(About)弹框
需求:文件菜单最下方新增「关于」,展示产品介绍、数据存储路径、备份方法、开源组件(20 个以内)与代码结构说明。
方案:新增 AboutDialog 组件(与登录/设置一致的全屏遮罩 + 居中卡片),FileMenu 增加「关于」项并用分隔线区隔,ProjectBar / App 透传 onAbout 与 showAbout 状态渲染。内容含 12 项,其中 mindmap>600 实为「预览高度」、普通筛选实为「标题/项目/标签」、formatter.go 的 categoryLabels 需与前端 categories.ts 保持一致,均已按实际纠正表述。
2026-09-06 开发总结
当日主线:修复实时预览在编辑时跳回顶部的顽疾,并把保存机制升级为「自动保存 + 发布状态圆点」,让笔记列表左侧圆点从”类型”语义改为”同步状态”语义。
39. 实时预览跳顶之坑(react-markdown 同步重建)
坑:编辑区每次改动,右侧预览滚动位置都跳回顶部,先后尝试 useRef + onScroll 保存/恢复 scrollTop 也因组件重建与时机问题失效。
根因:react-markdown v9.1.0 是同步组件,正文变化时整棵 React 元素树重建,浏览器滚动锚定(scroll anchoring)失效,预览容器被重置到顶部。
方案:在 Preview.tsx 用模块级 Map(previewScroll)按「文档标识 + 预览面板」(docKey:idPrefix)保存滚动位置,onScroll 实时记录、useLayoutEffect 在内容提交后立即恢复;同时给滚动容器设置 overflowAnchor: "none" 关闭浏览器锚定干扰。切换笔记 / 全屏面板时各用各的位置,互不串扰。
40. 保存策略:自动保存 + 发布状态圆点
需求:原「保存」需手动点击;笔记列表左侧圆点只按 type 区分(私人黄点 / 发布蓝点),而新建笔记默认 private,导致列表几乎全黄,无法表达”这条笔记到底同步了没有”。
方案(自动保存 + 发布状态语义):
DraftRecord增加publishedAt(最近一次成功推送 Mindoc 的时间戳)与dirty(自publishedAt后有未同步改动)两个字段;api.ts增加getDraft、markDraftSynced。App.tsx实现 800ms 防抖自动保存:正文或项目/阶段/标段/专业/类别/标签变动后,闲置即写入 IndexedDB,崩溃 / 关窗不丢内容;createdAtRef保留原创建时间避免自动保存打乱列表顺序,publishedAt原样透传不清空同步状态。发布成功后调用markDraftSynced清除dirty。Sidebar.tsx圆点改为三态发布状态:灰=本地草稿未发布(publishedAt == null)、黄=已发布但有未同步修改(dirty)、绿=已同步(publishedAt != null && !dirty),悬停有title提示。- 修正
Editor的onChange接线(由setBody改为handleBodyChange),使打字时正确置位isDirty;新建 / 打开文件时重置脏标记。
项目结构
deskmindoc/
├── deskmindoc-client/ # Tauri 前端
│ ├── src/
│ │ ├── components/ # React 组件
│ │ │ ├── App.tsx # 主组件(启动会话自检、全屏、暗黑主题)
│ │ │ ├── Editor.tsx # 编辑器(粘贴上传、拖拽)
│ │ │ ├── Preview.tsx # 实时预览(本地图片/附件渲染)
│ │ │ ├── MindmapRenderer.tsx # 思维导图渲染
│ │ │ ├── MarkdownToolbar.tsx # 工具条
│ │ │ ├── ProjectBar.tsx # 项目信息栏
│ │ │ ├── Sidebar.tsx # 目录/笔记导航
│ │ │ ├── ImageUploadDialog.tsx # 批量图片上传
│ │ │ ├── AttachmentUploadDialog.tsx # 批量附件上传
│ │ │ ├── PublishDialog.tsx # 发布/私人笔记目标 Book 选择
│ │ │ ├── SettingsDialog.tsx # 中间件地址 + 项目列表配置
│ │ │ └── Icons.tsx # 图标
│ │ ├── lib/
│ │ │ ├── db.ts # IndexedDB(drafts/images/attachments)
│ │ │ ├── api.ts # 中间件 API 封装(含 checkSession)
│ │ │ ├── localImages.ts # 本地图片暂存
│ │ │ ├── localAttachments.ts # 本地附件暂存
│ │ │ ├── projects.ts # 项目列表 localStorage 读写
│ │ │ ├── categories.ts # 分类常量
│ │ │ ├── tags.ts # 常用标签常量
│ │ │ ├── logger.ts # 日志上报(log_to_file)
│ │ │ └── file.ts # 打开/导出 Markdown
│ │ ├── styles/
│ │ │ └── index.css # 全局样式
│ │ └── main.tsx # 入口
│ └── src-tauri/ # Rust 后端
│ ├── src/
│ │ ├── lib.rs # 全局快捷键 + 窗口管理 + 日志落盘
│ │ └── main.rs # 主入口
│ ├── Cargo.toml
│ └── tauri.conf.json # Tauri 配置(CSP 置 null 以支持动态地址)
├── deskmindoc-middleware/ # Go 中间件
│ ├── controllers/ # 控制器
│ │ ├── auth.go # 登录/刷新/会话检查
│ │ ├── note.go # 笔记 CRUD
│ │ ├── project.go # 书籍列表
│ │ ├── upload.go # 图片/附件上传
│ │ └── review.go # 审核流程
│ ├── services/
│ │ ├── mindoc.go # Mindoc API 封装(per-user session)
│ │ └── formatter.go # 格式清洗
│ ├── middleware/
│ │ └── jwt.go # JWT 认证中间件
│ ├── routers/
│ │ ├── router.go # namespace 路由注册
│ │ └── commentsRouter.go # 自动生成路由
│ ├── models/
│ │ └── models.go # 请求/响应模型
│ ├── conf/
│ │ └── app.conf # 配置文件
│ └── main.go # 入口
└── scripts/ # 构建脚本
├── setup-android.bat # Android 环境配置
├── build.sh # 构建脚本
└── deploy.sh # 部署脚本License
MIT
总工笔记 — 让每一位总工的知识,都能成为设计院的宝贵财富。
最后编辑:秦晓川 更新时间:2026-09-07 22:55