docs: publish open-source guides and MIT license
This commit is contained in:
1 parent
1f01140b1d
commit
b1faab339e
10 files changed
+530
-86
No files matched your search
+7
-2
@@ -1,6 +1,11 @@
|
|||||||
# 本地交接文件与设计文档不入库
|
# 本地交接文件与历史设计文档不入库;公开文档单独放行
|
||||||
CONTEXT.md
|
CONTEXT.md
|
||||||
docs/
|
docs/*
|
||||||
|
!docs/guide.md
|
||||||
|
!docs/deployment.md
|
||||||
|
!docs/development.md
|
||||||
|
!docs/api.md
|
||||||
|
!docs/images/
|
||||||
|
|
||||||
# 前端
|
# 前端
|
||||||
node_modules/
|
node_modules/
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 eezd
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -1,103 +1,76 @@
|
|||||||
# RawMark
|
<div align="center">
|
||||||
|
<img src="web/public/icon.svg" width="80" height="80" alt="RawMark logo" />
|
||||||
|
<h1>RawMark</h1>
|
||||||
|
<p><strong>A space of your own. A place to write.</strong></p>
|
||||||
|
<p>A self-hosted Markdown workspace for your personal notes. Your files, your server, ready in your browser.</p>
|
||||||
|
<p><strong>English</strong> · <a href="README.zh-CN.md">简体中文</a></p>
|
||||||
|
<p>
|
||||||
|
<a href="#quick-start">Quick start</a> ·
|
||||||
|
<a href="docs/guide.md">User guide</a> ·
|
||||||
|
<a href="docs/deployment.md">Deployment</a> ·
|
||||||
|
<a href="https://github.com/eezd/RawMark/issues">Report an issue</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
纯 Markdown 笔记网页编辑器:所见即所得(类 Obsidian Live Preview)、文件即真源、Docker 部署、浏览器访问。
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="docs/images/workspace-dark.png" />
|
||||||
|
<img src="docs/images/workspace-light.png" alt="RawMark workspace with a file tree on the left, Markdown live preview and tabs in the center, and a document outline on the right" width="1440" />
|
||||||
|
</picture>
|
||||||
|
|
||||||
## 部署
|
<p align="center"><sub>Actual workspace with sample notes · <a href="docs/images/workspace-light.png">Light mode</a> · <a href="docs/images/workspace-dark.png">Dark mode</a></sub></p>
|
||||||
|
|
||||||
本机部署沿用 `/srv/AlphaPulse/deploy` 的目录约定,端口按 `/docker/main/.env` 的个人项目范围(21000–21999)分配为 `RAWMARK_PORT=21000`:
|
## Made for your notes
|
||||||
|
|
||||||
|
RawMark is for people who want to keep their notes on their own server. Organize knowledge, track projects, and collect ideas, then pick up where you left off in a browser on your computer, tablet, or phone.
|
||||||
|
|
||||||
|
Notes are ordinary `.md` files, with images stored in an `assets/` folder alongside them. Access your files directly or export them whenever you like, and open them with the Markdown tools you already use.
|
||||||
|
|
||||||
|
- **Focus on writing.** Switch between Markdown live preview and source mode, with support for tables, task lists, math, Mermaid diagrams, and syntax highlighting.
|
||||||
|
- **Keep things organized.** Folders, tags, full-text search, and document outlines, with drag-and-drop moves, bulk actions, and custom file icons.
|
||||||
|
- **Continue where you left off.** Multiple tabs and pinned notes survive refreshes and browser restarts. Changes save automatically, and external file edits sync to the page.
|
||||||
|
- **Keep images with your notes.** Paste, upload, or import images in bulk. View references, rename, move, replace, and clean up unreferenced images in the image manager.
|
||||||
|
- **Make it feel familiar.** Light and dark modes, separate interface, text, and code fonts, font imports, customizable shortcuts, themes, and CSS snippets.
|
||||||
|
- **Take your data with you.** Import Markdown or ZIP archives and export notes with attachments. Use the recycle bin, full-instance backups, settings migration, API automation, and frontend plugins.
|
||||||
|
|
||||||
|
RawMark is built for **single-user, self-hosted use**. It currently does not offer collaboration or public sharing.
|
||||||
|
|
||||||
|
## Quick start
|
||||||
|
|
||||||
|
With Git and Docker installed, build and run locally:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cd deploy
|
git clone https://github.com/eezd/RawMark.git
|
||||||
install -d -m 750 -o 65532 -g 65532 data
|
cd RawMark
|
||||||
docker compose --env-file /docker/main/.env up -d --build --wait
|
|
||||||
```
|
|
||||||
|
|
||||||
持久化数据位于 `deploy/data/`,与 `.dev-data/` 独立。首次打开网页时直接设置登录密码。
|
|
||||||
升级已有实例移除分享时,先备份数据与旧镜像、停止旧服务,再对 `rawmark.db` 执行一次 `scripts/remove-sharing.sql`,然后启动新版本。脚本删除分享表、专用密钥及分享快捷键;不会删除笔记或图片。旧分享页面和接口返回 404。回滚必须配套恢复数据库和旧镜像,不能只恢复旧程序。
|
|
||||||
|
|
||||||
升级到 Typora 默认快捷键时,先停止服务并备份数据与旧镜像,再对 `rawmark.db` 执行一次 `scripts/reset-shortcuts.sql`。该脚本按本次需求清空已有快捷键覆盖,其他设置保留;程序启动不会再次重置快捷键。
|
|
||||||
宿主机 Nginx 配置为 `deploy/nginx/raw.134333.xyz.conf`,复用现有通配证书及 WebSocket 升级映射;安装到 `/etc/nginx/conf.d/134333.xyz/` 后,先执行 `nginx -t` 再重载。
|
|
||||||
域名 `raw.134333.xyz` 在 DNSPod 设置 CNAME 指向 `cdn.134333.xyz`(与 AlphaPulse 一致);还需在 Cloudflare for SaaS 的 `unino.top` 区域添加该自定义域名,并等待域名与托管证书均为 `active`。仅设置 CNAME 或旧区域中的 A 记录不足以完成 CDN 接入。访问地址为 `https://raw.134333.xyz`。修改端口时需同步端口登记和 Nginx 上游。
|
|
||||||
|
|
||||||
其他服务器也可直接构建并运行:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
mkdir -p ~/rawmark-data
|
|
||||||
docker build -t rawmark .
|
docker build -t rawmark .
|
||||||
docker run -d --name rawmark \
|
docker run -d --name rawmark --restart unless-stopped \
|
||||||
--user "$(id -u):$(id -g)" \
|
-p 127.0.0.1:21000:8080 \
|
||||||
-p 8080:8080 \
|
-v rawmark-data:/data \
|
||||||
-v ~/rawmark-data:/data \
|
|
||||||
--restart unless-stopped \
|
|
||||||
rawmark
|
rawmark
|
||||||
```
|
```
|
||||||
|
|
||||||
- 首次打开直接设置登录密码,之后凭密码与图片验证码登录;请在将新实例开放给他人访问前完成初始化。
|
Open **http://localhost:21000**, set your password on first use, and create your first note. Data lives in the Docker volume `rawmark-data` and persists when you recreate the container with the same volume.
|
||||||
- 笔记以普通 `.md` 文件保存在 `数据目录/vault/`,粘贴、上传和导入的图片统一存放在笔记同级的 `assets/`,链接使用 `./assets/文件名`,同目录相同内容去重。笔记跨目录移动时图片跟随,仍被其他笔记引用的原图保留;删除单篇笔记不会删除共享图片。旧 `笔记名.assets/` 仍可读取、移动与恢复;外部修改会实时同步到网页。
|
|
||||||
- 知识工具:标准 Markdown 链接构成图谱,支持正文 `#标签` 与 YAML `tags`。笔记或文件夹在应用内改名、移动时维护入链和相对出链;公式和代码示例不参与关系提取。
|
|
||||||
- 外观:浅色玻璃工作台与深色模式,默认字体为 Maple Mono Normal NL NF CN v7.9(界面、正文与代码),字体资源随应用本地提供,文字在所需字体加载完成后显示,加载失败会提示刷新;代码块使用 highlight.js,固定采用官网的 Atom One Dark 配色,与页面明暗模式独立;界面、正文与代码字体可分别选择,各字体下拉均支持导入 TTF/OTF/WOFF/WOFF2(单个不超过30 MB)及删除;Maple为不可删除的默认字体,删除正在使用的字体会恢复Maple,导入字体保存在服务器数据目录的fonts/并跨设备共用。界面字号默认 14px,可输入 14–20px 并单独重置,与编辑器及阅读字号独立;排版、玻璃透明度、选中文本工具栏均可在设置中调整并即时保存。
|
|
||||||
- 选区格式:电脑与触屏选中文字后提供外观、加粗、斜体、下划线、删除线、高亮和链接。外观可设置配色、字体、局部字号与效果;下划线及外观以受限的标准 HTML 行内标签保存在 Markdown 中,源码与导出保留标签,其他软件的显示取决于其 HTML 支持。清除样式只重置局部外观;底部不再显示格式栏。
|
|
||||||
- 图片管理:侧栏默认隐藏 `assets` 和 `笔记名.assets`;右键文件夹选择「图片管理」,查看当前目录及直属附件目录的图片,支持检索、排序、网格/列表、批量上传、引用查看及预览、重命名、移动、替换。可切换整个知识库;清理孤立图片须确认候选,服务端再次核对全库引用后移入回收站,可恢复。上传至所选目录的 `assets/`,相同内容自动去重。根目录可在侧栏空白处右键或通过命令面板打开。图片改名/移动会更新笔记中的本地引用;替换保留路径,选择相同扩展名的图片(最大 50 MB),旧图片不进回收站。
|
|
||||||
- `--user` 让容器以宿主机用户身份读写数据目录;不指定时容器以 UID 65532 运行,需要该用户对目录有写权限。
|
|
||||||
- 请通过 HTTPS 反向代理(Caddy、Nginx 等)访问,并转发 WebSocket(浏览器使用 `/api/v1/resources/<ticket>/events/`,脚本可使用 Bearer 连接 `/api/v1/events`)。
|
|
||||||
- 多选与导出:Ctrl/Cmd 点击切换选择,Shift 点击选择可见范围;右键批量删除、移动或导出 Markdown。单篇无附件直接下载 `.md`,其他情况下载包含 Markdown 与本地附件的 ZIP;重名目标不会被覆盖,批量操作会汇报单项失败。
|
|
||||||
- 设置:桌面使用居中窗口,手机使用分类与内容两级布局;支持搜索设置并定位、常用排版项单独重置,自动保存状态与失败提示可见。外观与编辑器分别管理,安装入口位于「关于」。
|
|
||||||
- 回收站与存储:回收站支持清空全部;默认按原删除时间保留 30 天,0 表示永不自动删除,服务启动及每小时执行清理,修改期限同样影响已有条目。设置「存储空间」进入即统计数据目录、外置笔记库及内置可选字体(不含默认 Maple),支持刷新和字体明细;不跟随内部符号链接,附件与回收站包含在笔记库总量中。
|
|
||||||
- 快捷键:支持按命令名称、ID 或组合键搜索,添加、逐条移除和单项/全部重置,并拒绝冲突绑定。默认跟随 [Typora](https://support.typora.io/Shortcut-Keys/) 的 Windows/Linux 或 macOS 组合,无对应项和插件默认留空;浏览器保留键可自行重新绑定。Ctrl/Cmd+1~6 设置标题,同级再次触发恢复正文;字号可直接输入,编辑器字号随有效输入即时生效。
|
|
||||||
- 备份与维护:设置「存储空间」提供完整实例、普通 Markdown 笔记库、设置与资源三种迁移入口。完整实例含数据库、登录信息、回收站与资源,恢复会替换当前业务数据并要求重新登录;设置包含偏好、插件数据及字体/主题/插件,保留包外资源,同 ID 资源替换。两者应用前均在数据目录 `backups/` 保存恢复包;不包含运维环境配置、派生索引或临时文件。普通笔记导出保留目录与原文,即使仓库与应用目录重合或嵌套也不包含应用数据库、资源与暂存文件;缺失附件记录于 `.rawmark-export/missing-assets.json`,导回时忽略该报告并导入新文件夹。
|
|
||||||
- 维护边界:备份恢复只接受本程序的版本化 ZIP,顺序分块上传,每块 8 MiB,压缩上限 2 GiB、展开上限 8 GiB/100000 项;完整恢复前需停止外部程序直接改写仓库。维护期间暂时暂停 API 操作,实例恢复在关闭数据库和后台任务后执行,中断时回退操作前备份。优化/重建仅作用于派生索引;临时清理不删除用户文件、活动上传或恢复备份。重置偏好保留插件存储、账户、资源和本机标签页。日志保存于 `logs/`,三份、每份至多 10 MiB,可导出日志及版本运行摘要,不补录历史日志。
|
|
||||||
|
|
||||||
- 文件目录操作:右键「文件目录」标题或目录空白处,可搜索、打开标签索引、新建笔记、新建目录、导入文档及管理图片;也可点击标题打开菜单。文件夹右键操作以所选文件夹为目标。
|
These commands listen on localhost only. For a remote server, complete the initial setup before configuring HTTPS access. See the [deployment guide](docs/deployment.md) for Docker Compose, existing note folders, backups, and upgrades.
|
||||||
- 导入:文件目录或文件夹右键菜单选择「导入」,支持多选 UTF-8 `.md` 文件或单个 ZIP(总上传上限 100 MB)。ZIP 新建同名文件夹并保留笔记层级,本地图片归入各笔记同级 `assets/`;全部改链后移除已迁移且无引用的重复原图,其他附件和未使用图片保留。同名不同内容不覆盖,缺失的本地链接会提示,外部图片不会自动下载。
|
|
||||||
- 自动化:在设置「账户与安全 → API 令牌」中创建只读或读写令牌,以 `Authorization: Bearer <令牌>` 调用 REST API,接口说明见 `/api/v1/openapi.json`。
|
|
||||||
|
|
||||||
| 环境变量 | 默认值 | 说明 |
|
## Documentation
|
||||||
| --- | --- | --- |
|
|
||||||
| `RAWMARK_DATA` | `/data` | 数据目录(数据库、可重建的搜索索引 `index.db`、默认笔记仓库) |
|
|
||||||
| `RAWMARK_VAULT` | `$RAWMARK_DATA/vault` | 笔记仓库目录,可指向已有的笔记文件夹 |
|
|
||||||
| `RAWMARK_ADDR` | `:8080` | 监听地址 |
|
|
||||||
|
|
||||||
文件树默认使用 📂 / 📄,可点击图标或右键“修改图标”,选择表情或内置线性图标。自定义属性存于仓库的 `.rawmark/tree-icons.json`,随应用内移动、重命名及回收站恢复保留,不改动或导出到 Markdown 正文;外部文件操作不保证跟随。
|
Detailed guides are currently available in Simplified Chinese.
|
||||||
|
|
||||||
## 开发
|
| What you want to do | Start here |
|
||||||
|
| --- | --- |
|
||||||
|
| Write, organize notes, manage images, and customize the workspace | [User guide](docs/guide.md) |
|
||||||
|
| Deploy, configure storage, back up, and upgrade | [Deployment and maintenance](docs/deployment.md) |
|
||||||
|
| Develop locally, understand the project structure, and run checks | [Development guide](docs/development.md) |
|
||||||
|
| Write scripts, authenticate, and call the API | [API and authentication](docs/api.md) |
|
||||||
|
|
||||||
需要 Go 1.27+、Node 24+ 与 pnpm 12.11.2(可通过 Corepack 启用)。开发时不必构建前端或 Docker 镜像,一键启动:
|
## Help and contributing
|
||||||
|
|
||||||
```sh
|
Bug reports and suggestions are welcome in [Issues](https://github.com/eezd/RawMark/issues). Include your version, deployment method, browser, and steps to reproduce. Remove passwords, tokens, and private note content from logs and screenshots.
|
||||||
scripts/dev.sh # 后端 go run -tags dev + 前端 Vite 热更新,Ctrl+C 同时退出
|
|
||||||
scripts/dev.sh --host # 前端监听所有网卡,手机访问 http://<电脑 IP>:5173
|
|
||||||
```
|
|
||||||
|
|
||||||
浏览器打开 http://localhost:5173 ,首次使用直接设置登录密码。端口与数据目录可用 `API_PORT`、`WEB_PORT`、`RAWMARK_DATA` 覆盖,详见 `scripts/dev.sh --help`。
|
Before contributing, read [AGENTS.md](AGENTS.md) and the [development guide](docs/development.md), both currently in Simplified Chinese. RawMark prioritizes simplicity and clarity; please discuss substantial features or architectural changes in an issue first.
|
||||||
开发模式从源码统计可选字体,日志导出的版本标为 `dev`,不读取已有 `web/dist`;生产模式使用前端构建清单与页面构建版本。
|
|
||||||
|
|
||||||
检查:
|
## Acknowledgments and license
|
||||||
|
|
||||||
```sh
|
Built with projects including [CodeMirror](https://codemirror.net/), [Vue](https://vuejs.org/), [Element Plus](https://element-plus.org/), [highlight.js](https://highlightjs.org/), and [Maple Mono](https://github.com/subframe7536/maple-font). The frontend structure draws on [vue3-starter](https://github.com/eezd/vue3-starter), whose [MIT license](web/LICENSE) is retained. [Maple Mono](web/src/common/appearance/fonts/maple/LICENSE.txt) and other third-party assets retain their respective licenses.
|
||||||
pnpm -C web install --frozen-lockfile
|
|
||||||
pnpm -C web lint:check
|
|
||||||
pnpm -C web typecheck
|
|
||||||
pnpm -C web test
|
|
||||||
pnpm -C web build
|
|
||||||
go vet -tags dev ./...
|
|
||||||
go test ./internal/...
|
|
||||||
go test -tags dev ./web
|
|
||||||
```
|
|
||||||
|
|
||||||
字体资源已入库,普通构建无需下载或转换。重新生成时,在独立 Python 环境安装 `fonttools[woff]`,下载 [v7.9 指定字体包](https://github.com/subframe7536/maple-font/releases/download/v7.9/MapleMonoNormalNL-NF-CN.zip),运行 `python3 scripts/prepare-maple-font.py /path/to/MapleMonoNormalNL-NF-CN.zip`;生成 WOFF2 与 `maple-font.css`,保留上游许可。
|
RawMark is open source under the [MIT License](LICENSE). Third-party code and fonts retain their own license and copyright notices.
|
||||||
|
|
||||||
## 前端结构与接口升级
|
|
||||||
|
|
||||||
前端以 [vue3-starter](https://github.com/eezd/vue3-starter/tree/fd41d62ce3f1c8338a478e0be3e2f31b53b7ea5e) 为结构基线,保留 RawMark 的编辑器、主题与布局;模板许可在 `web/LICENSE`。`web/src/pages/workspace/` 管理笔记、目录、编辑器与图片,`pages/settings/` 管理设置及维护,`pages/login/` 管理初始化与验证码登录;页面私有组件、类型和组合函数跟随模块。全部资源 API 统一位于 `common/apis/<resource>/index.ts` 与 `type.ts`,API 函数直接调用 `request<ResponseData>({ url, method, data, params })` 并返回完整 `{ code, data, message }`,调用方读取 `.data`;原文及下载用 `returnResponse: true` 保留 Axios 响应和响应头,204 为 void,事件连接也归资源 API。实际共享的外观、Markdown、插件 SDK 位于 `common/`;请求、路由、共享状态分别由 `http/`、`router/`、`pinia/` 管理。唯一前端构建入口为 `web/`,使用 pnpm 锁文件。此次 API 目录与普通页面调整复用已部署的统一后端协议,不新增数据库迁移。
|
|
||||||
|
|
||||||
本次协议升级需前后端一起发布,旧页面与旧 Cookie 会话不能继续使用,需要重新登录。升级前备份数据库和旧镜像;启动新程序时沿用现有 SQLite 初始化流程新增 `resource_tickets` 表及过期索引,保留笔记、设置、密码和 API 令牌。生产迁移与部署须另行授权,不手动运行历史清理 SQL。回滚使用配套数据库和旧镜像;新前端不能连接旧后端。
|
|
||||||
|
|
||||||
登录流程先 `POST /api/v1/auth/captcha`,取得 `{captchaId,imageDataUrl,expiresAt}`;刷新传 `replaceId` 使旧挑战失效。再提交 `POST /api/v1/auth/login` 的 `{password,captchaId,captchaCode}`,后端校验六位数字,挑战绑定来源、五分钟过期且一次性消费(密码或验证码失败也会消费)。保留登录防暴力破解与签发限流。首次 `POST /auth/setup` 直接设置密码,不需要已有登录挑战。
|
|
||||||
|
|
||||||
登录/初始化返回 `{token,expiresAt}`。浏览器将 `rms_` 会话 Token 保存于 localStorage `rawmark.token`,所有受保护请求带 `Authorization: Bearer <token>`;服务端只存哈希、固定三十天有效,不滑动续期。`GET /auth/me` 返回真实权限及到期时间,`POST /auth/logout` 服务端撤销会话后返回 204;注销失败保留本地身份并明确报错。401 清除当前身份及动态路由,403 保留身份;旧请求或排队写入不能覆盖或注销新会话。localStorage 属于同源脚本可读的凭据,管理员安装的前端插件仍为全权限插件,不能承诺隔离。
|
|
||||||
|
|
||||||
普通 JSON 响应统一为 `{code,data,message}`,code=0 成功,message 表示成功或明确失败原因;错误保留 400/401/403/404/409/412/429/500/503 等 HTTP 状态。维护接口中,无效输入或备份内容返回 400,维护占用或磁盘空间不足返回 503,文件系统/数据库内部故障返回 500。通用错误码为 HTTP 状态乘 100,40001 验证码错误/已使用、40002 验证码过期、40003 当前密码错误、40101 密码错误、41200 版本冲突;冲突版本位于 `data.rev`。文件原文、下载、WebSocket、204 和 OpenAPI 文档不包装。旧 JSON 客户端必须更新解包方式,不提供双格式兼容。
|
|
||||||
|
|
||||||
`rm_` API 令牌无需重新创建,read/write 权限不变;令牌不能管理账户、令牌、维护或资源票据。只读令牌仍可 POST 导出。第三方脚本只需保留 Bearer 请求头并按新 JSON 协议解包,文件/导出原始字节不变;WebSocket 客户端可继续以 Bearer 请求头连接 `/api/v1/events`。
|
|
||||||
|
|
||||||
浏览器原生图片、字体、插件相对模块导入及 WebSocket 无法统一设置认证头,使用 `POST /auth/tickets` 签发的受限资源 URL。图片/字体票据不超过父会话期限,插件另绑定 ID 和版本;每次读取都核对父会话,注销后立即不可读。事件握手票据一分钟有效、只能使用一次,已连接事件在发送与心跳时检查父凭据。主 Token 不放在 URL,不使用 Cookie 兜底;私有响应 no-store、Referrer-Policy=no-referrer,PWA 仅缓存静态外壳。部署代理也须避免记录票据 URL,仓库 Nginx 配置已提供脱敏日志格式;CDN/其他代理需按同样规则配置。
|
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
<div align="center">
|
||||||
|
<img src="web/public/icon.svg" width="80" height="80" alt="RawMark 标志" />
|
||||||
|
<h1>RawMark</h1>
|
||||||
|
<p><strong>在自己的空间,安心写作。</strong></p>
|
||||||
|
<p>自托管的个人 Markdown 笔记工作台。文件属于你,打开浏览器就能继续写。</p>
|
||||||
|
<p><a href="README.md">English</a> · <strong>简体中文</strong></p>
|
||||||
|
<p>
|
||||||
|
<a href="#快速开始">快速开始</a> ·
|
||||||
|
<a href="docs/guide.md">使用指南</a> ·
|
||||||
|
<a href="docs/deployment.md">部署文档</a> ·
|
||||||
|
<a href="https://github.com/eezd/RawMark/issues">反馈问题</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="docs/images/workspace-dark.png" />
|
||||||
|
<img src="docs/images/workspace-light.png" alt="RawMark 主界面:左侧文件目录,中间 Markdown 即时预览编辑器和标签页,右侧文章大纲" width="1440" />
|
||||||
|
</picture>
|
||||||
|
|
||||||
|
<p align="center"><sub>真实工作区,使用示例笔记 · <a href="docs/images/workspace-light.png">浅色界面</a> · <a href="docs/images/workspace-dark.png">深色界面</a></sub></p>
|
||||||
|
|
||||||
|
## 为记录而设计
|
||||||
|
|
||||||
|
RawMark 适合想把笔记保存在自己服务器上的个人用户:整理知识、记录项目、收集灵感,在电脑、平板或手机的浏览器中继续写作。
|
||||||
|
|
||||||
|
笔记就是普通的 `.md` 文件,图片放在笔记旁的 `assets/` 文件夹。你可以直接访问文件,也可以随时导出,用熟悉的 Markdown 工具打开。
|
||||||
|
|
||||||
|
- **专注写作**:Markdown 即时预览与源码模式切换,支持表格、任务列表、数学公式、Mermaid 和代码高亮。
|
||||||
|
- **有条理地整理**:文件夹、标签、全文搜索与文章大纲;拖动移动、批量操作、自定义文件图标,让笔记各归其位。
|
||||||
|
- **延续工作状态**:多标签页与固定标签,刷新或重启后恢复;自动保存,外部文件修改同步到页面。
|
||||||
|
- **让图片跟着笔记走**:粘贴、上传与批量导入图片;图片管理支持引用查看、重命名、移动、替换及孤立图片清理。
|
||||||
|
- **按自己的习惯调整**:浅色与深色模式,独立的界面、正文及代码字体,可导入字体、自定义快捷键、主题和 CSS 片段。
|
||||||
|
- **数据可带走**:导入 Markdown 或 ZIP,导出笔记与附件;回收站、完整实例备份与设置迁移,支持 API 自动化及前端插件扩展。
|
||||||
|
|
||||||
|
RawMark 面向**单用户、自托管**场景。目前不提供多人协作或公开分享。
|
||||||
|
|
||||||
|
## 快速开始
|
||||||
|
|
||||||
|
需要 Git 和 Docker。在本地构建镜像并启动:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git clone https://github.com/eezd/RawMark.git
|
||||||
|
cd RawMark
|
||||||
|
docker build -t rawmark .
|
||||||
|
docker run -d --name rawmark --restart unless-stopped \
|
||||||
|
-p 127.0.0.1:21000:8080 \
|
||||||
|
-v rawmark-data:/data \
|
||||||
|
rawmark
|
||||||
|
```
|
||||||
|
|
||||||
|
打开 **http://localhost:21000**,首次访问设置登录密码,即可创建第一篇笔记。数据保存在 Docker 卷 `rawmark-data` 中,重建容器不会丢失。
|
||||||
|
|
||||||
|
以上命令仅监听本机。部署到服务器时,请先完成初始化,再配置 HTTPS 访问;Docker Compose、已有笔记目录接入、备份与升级见[部署文档](docs/deployment.md)。
|
||||||
|
|
||||||
|
## 文档
|
||||||
|
|
||||||
|
| 想做什么 | 从这里开始 |
|
||||||
|
| --- | --- |
|
||||||
|
| 写作、整理笔记、管理图片与个性化设置 | [使用指南](docs/guide.md) |
|
||||||
|
| 部署、配置存储、备份和升级 | [部署与维护](docs/deployment.md) |
|
||||||
|
| 本地开发、了解目录职责和运行检查 | [开发指南](docs/development.md) |
|
||||||
|
| 编写脚本、接入认证和调用接口 | [API 与认证](docs/api.md) |
|
||||||
|
|
||||||
|
## 参与项目
|
||||||
|
|
||||||
|
欢迎通过 [Issues](https://github.com/eezd/RawMark/issues) 报告问题或提出建议。报告问题时,请附上版本、部署方式、浏览器和复现步骤;日志与截图中请移除密码、令牌及私人笔记内容。
|
||||||
|
|
||||||
|
提交改动前请阅读 [AGENTS.md](AGENTS.md) 和[开发指南](docs/development.md)。RawMark 优先保持简单、清晰,较大的功能或架构调整建议先通过 Issue 讨论。
|
||||||
|
|
||||||
|
## 致谢与许可
|
||||||
|
|
||||||
|
感谢 [CodeMirror](https://codemirror.net/)、[Vue](https://vuejs.org/)、[Element Plus](https://element-plus.org/)、[highlight.js](https://highlightjs.org/) 和 [Maple Mono](https://github.com/subframe7536/maple-font) 等项目。前端结构参考 [vue3-starter](https://github.com/eezd/vue3-starter),其 [MIT 许可](web/LICENSE) 保留;[Maple 字体许可](web/src/common/appearance/fonts/maple/LICENSE.txt)及其他第三方许可遵循各自文件。
|
||||||
|
|
||||||
|
RawMark 采用 [MIT License](LICENSE) 开源;第三方代码与字体保留各自的许可和版权声明。
|
||||||
+86
@@ -0,0 +1,86 @@
|
|||||||
|
# API 与认证
|
||||||
|
|
||||||
|
[返回项目首页](../README.zh-CN.md) · [开发指南](development.md)
|
||||||
|
|
||||||
|
API 基础路径为 `/api/v1`。完整端点、请求字段、权限和响应以 [OpenAPI 源文件](../internal/api/openapi.json)为准,运行中的实例在 `GET /api/v1/openapi.json` 提供同一文档。测试 `TestOpenAPICoversRoutes` 核对路由覆盖。
|
||||||
|
|
||||||
|
## 脚本接入
|
||||||
|
|
||||||
|
在「设置 → 账户与安全 → API 令牌」创建只读或读写令牌。受保护 API 只接受 `Authorization: Bearer <token>`,不接受 Cookie,也不要将主令牌放进 URL。
|
||||||
|
|
||||||
|
以下只读示例从环境变量读取凭据:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# 先在本机环境中设置 RAWMARK_URL 和 RAWMARK_TOKEN,不要提交真实值。
|
||||||
|
curl --fail-with-body \
|
||||||
|
-H "Authorization: Bearer $RAWMARK_TOKEN" \
|
||||||
|
"$RAWMARK_URL/api/v1/tree"
|
||||||
|
```
|
||||||
|
|
||||||
|
`rm_` API 令牌在服务端只存哈希,保留 read/write 权限。只读令牌可读取笔记、搜索和执行只读 POST 导出,不能写入;API 令牌不能管理账户、令牌、维护或资源票据,不能为自身扩权。管理操作需要浏览器登录会话。
|
||||||
|
|
||||||
|
## JSON 与 HTTP 语义
|
||||||
|
|
||||||
|
普通 JSON 成功响应:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 0,
|
||||||
|
"data": { "ok": true },
|
||||||
|
"message": "成功"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`code = 0` 表示成功,非零表示失败;失败时 `message` 是可展示的原因。保留真实 HTTP 状态,不把错误全部转为 200。通用错误码为 HTTP 状态乘 100,特定业务码如下:
|
||||||
|
|
||||||
|
| HTTP | code | 含义 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 400 | 40001 | 验证码错误、无效或已使用 |
|
||||||
|
| 400 | 40002 | 验证码过期 |
|
||||||
|
| 400 | 40003 | 修改密码时当前密码错误,不清理身份 |
|
||||||
|
| 401 | 40101 | 登录密码错误 |
|
||||||
|
| 412 | 41200 | 文件版本冲突,当前版本在 `data.rev` |
|
||||||
|
|
||||||
|
401 表示需要重新认证;403 表示当前身份没有权限,不能据此注销用户。维护输入或备份内容无效返回 400,占用或空间不足返回 503,文件系统/数据库内部故障返回 500。
|
||||||
|
|
||||||
|
**文件原文、下载、WebSocket、204 及 OpenAPI 文档不包 JSON 外壳**。`GET /files/{path}` 返回 Markdown 原文和 `ETag`;`PUT /files/{path}` 接收原文,成功返回包含 `rev` 的 JSON。用 `If-Match: "rev"` 防止覆盖新版本,或 `If-None-Match: *` 要求目标不存在;都不带会直接覆盖,不适合需要冲突保护的写入。
|
||||||
|
|
||||||
|
## 浏览器登录
|
||||||
|
|
||||||
|
实例没有用户名、注册或角色系统。尚未初始化时,`POST /auth/setup` 使用 `{ password }` 设置密码并返回会话;已经初始化的实例不能再次初始化。
|
||||||
|
|
||||||
|
正常登录流程:
|
||||||
|
|
||||||
|
1. `POST /auth/captcha` 获取 `{ captchaId, imageDataUrl, expiresAt }`。
|
||||||
|
2. 展示图片,用户填写密码与六位数字验证码。
|
||||||
|
3. `POST /auth/login` 提交 `{ password, captchaId, captchaCode }`。
|
||||||
|
4. 成功返回 `{ token, expiresAt }`,再通过 `GET /auth/me` 恢复真实身份与权限。
|
||||||
|
|
||||||
|
以上字段均位于普通响应的 `data` 中。刷新验证码时传 `{ replaceId }` 使旧挑战失效。挑战绑定来源,五分钟过期;每次登录提交一次性消费,即使密码或验证码错误也不能重用,失败必须刷新。签发与登录均保留限流。
|
||||||
|
|
||||||
|
`rms_` 浏览器会话 Token 保存在 localStorage 的 `rawmark.token`,固定三十天有效、不滑动续期,服务端仅存哈希。退出调用 `POST /auth/logout`,服务端撤销成功返回 204 后才清理本地身份;请求失败时保留身份并提示错误,不能仅删除本地 Token 宣称注销完成。
|
||||||
|
|
||||||
|
localStorage 可被同源脚本读取;有完整前端权限的插件必须视为可信代码,不能承诺凭据隔离。
|
||||||
|
|
||||||
|
## 原生资源与事件
|
||||||
|
|
||||||
|
原生图片、字体、插件模块与浏览器 WebSocket 不能统一设置认证头,通过 `POST /auth/tickets` 获取受限资源 URL;主 Token 不进入 URL。票据服务端只保存哈希,每次读取检查父会话,父会话退出后即失效。
|
||||||
|
|
||||||
|
- 图片/字体票据不超过父会话有效期。
|
||||||
|
- 插件票据额外绑定插件 ID 和版本,支持相对模块导入。
|
||||||
|
- 事件握手票据一分钟有效、仅消费一次;已连接事件仍会检查父凭据。
|
||||||
|
- 脚本 WebSocket 客户端可以通过 Bearer 请求头继续连接 `/api/v1/events`。
|
||||||
|
|
||||||
|
私有响应使用 `Cache-Control: no-store` 与 `Referrer-Policy: no-referrer`,API 和私有资源不进入 PWA 静态缓存。代理日志也需脱敏,见[部署文档](deployment.md#https-与反向代理)。
|
||||||
|
|
||||||
|
## 前端请求责任
|
||||||
|
|
||||||
|
请求处理、认证与路由守卫分别位于 `http/`、`pinia/` 和 `router/`。匿名跳登录并保留合法站内回跳,拒绝外部地址与循环跳转。401 清理当前身份、权限与动态路由,403 保留身份。
|
||||||
|
|
||||||
|
每次替换或退出会话更新代号、取消旧请求。用户信息、路由安装、异步响应与排队写入均须检查所属会话;旧结果按 Axios 取消语义拒绝,不能覆盖或注销新身份,也不提示取消错误。
|
||||||
|
|
||||||
|
同一错误只由一个责任层提示。请求默认负责展示,已有行内状态、保存重试或批量汇总的 API 使用 `errorOwner: 'caller'`;失败依然 reject,不以空列表或默认值伪装成功。
|
||||||
|
|
||||||
|
## 旧客户端迁移
|
||||||
|
|
||||||
|
统一协议需要前后端同时更新,不保留 Cookie/Bearer 或两种 JSON 格式兜底。旧 `rm_` API 令牌无需重建,但调用方要改为读取 `{ code, data, message }` 中的 `data`;文件及导出字节语义不变。旧浏览器页面需重新登录,不能连接新旧混用的后端。
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
# 部署与维护
|
||||||
|
|
||||||
|
[返回项目首页](../README.zh-CN.md) · [使用指南](guide.md) · [开发指南](development.md)
|
||||||
|
|
||||||
|
RawMark 将前端嵌入 Go 服务,运行时使用 SQLite 与文件系统,不需要额外数据库服务。目前从源码构建 Docker 镜像;以下命令不依赖预先发布的镜像仓库。
|
||||||
|
|
||||||
|
## Docker 快速启动
|
||||||
|
|
||||||
|
安装 Git、Docker 后:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git clone https://github.com/eezd/RawMark.git
|
||||||
|
cd RawMark
|
||||||
|
docker build -t rawmark .
|
||||||
|
docker run -d --name rawmark --restart unless-stopped \
|
||||||
|
-p 127.0.0.1:21000:8080 \
|
||||||
|
-v rawmark-data:/data \
|
||||||
|
rawmark
|
||||||
|
```
|
||||||
|
|
||||||
|
访问 http://localhost:21000 完成首次密码设置。命名卷 `rawmark-data` 保存应用数据,重新创建容器时应继续挂载同一个卷,不要删除它。服务器上的本机端口可通过 SSH 隧道访问,再完成初始化:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ssh -L 21000:127.0.0.1:21000 user@your-server
|
||||||
|
```
|
||||||
|
|
||||||
|
容器默认以 UID/GID `65532:65532` 运行,Docker 新建命名卷会继承镜像数据目录的权限。
|
||||||
|
|
||||||
|
## Docker Compose
|
||||||
|
|
||||||
|
仓库提供 [deploy/docker-compose.yml](../deploy/docker-compose.yml),使用宿主机的 `deploy/data/` 持久化。Linux 上首次部署可执行:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
mkdir -p deploy/data
|
||||||
|
sudo chown 65532:65532 deploy/data
|
||||||
|
docker compose -f deploy/docker-compose.yml up -d --build --wait
|
||||||
|
```
|
||||||
|
|
||||||
|
该配置默认发布到所有网卡的 **21000** 端口。对公网开放前完成初始化并设置访问边界;使用反向代理时,可将 Compose 端口绑定改为 `127.0.0.1:${RAWMARK_PORT:-21000}:8080`。自定义端口可使用 `RAWMARK_PORT=21001 docker compose -f deploy/docker-compose.yml up -d --build --wait`。
|
||||||
|
|
||||||
|
不要把快速开始中的容器与 Compose 实例同时指向同一份数据库或笔记库;切换部署方式前先停止旧实例、备份并确认数据位置。
|
||||||
|
|
||||||
|
## 存储与配置
|
||||||
|
|
||||||
|
| 环境变量 | 默认值 | 说明 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `RAWMARK_DATA` | `/data` | 应用数据库、索引、资源与默认笔记库所在目录 |
|
||||||
|
| `RAWMARK_VAULT` | `$RAWMARK_DATA/vault` | Markdown 笔记库,可以单独挂载已有目录 |
|
||||||
|
| `RAWMARK_ADDR` | `:8080` | 容器或二进制内部的监听地址 |
|
||||||
|
|
||||||
|
主要数据:
|
||||||
|
|
||||||
|
| 路径 | 内容 |
|
||||||
|
| --- | --- |
|
||||||
|
| `vault/` | Markdown 文件、附件与笔记库元数据;设定外置笔记库时位于对应目录 |
|
||||||
|
| `rawmark.db` | 密码、会话、API 令牌、设置等应用状态 |
|
||||||
|
| `index.db` | 可重建的搜索索引 |
|
||||||
|
| `fonts/`、`themes/`、`plugins/` | 用户导入的字体、主题和插件 |
|
||||||
|
| `backups/` | 导入或恢复操作前生成的回退备份 |
|
||||||
|
| `logs/` | 运行日志 |
|
||||||
|
|
||||||
|
要接入已有文件夹,可额外挂载它并设置 `RAWMARK_VAULT`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker run -d --name rawmark --restart unless-stopped \
|
||||||
|
--user "$(id -u):$(id -g)" \
|
||||||
|
-p 127.0.0.1:21000:8080 \
|
||||||
|
-v "$HOME/rawmark-data:/data" \
|
||||||
|
-v "$HOME/notes:/vault" \
|
||||||
|
-e RAWMARK_VAULT=/vault \
|
||||||
|
rawmark
|
||||||
|
```
|
||||||
|
|
||||||
|
先创建 `$HOME/rawmark-data` 和 `$HOME/notes`,确保所选用户可写。此例以宿主机当前用户运行,适合管理自己的已有目录;不设置 `--user` 时须给容器默认用户写权限。RawMark 会修改笔记和链接,首次接入前请备份已有目录。
|
||||||
|
|
||||||
|
## HTTPS 与反向代理
|
||||||
|
|
||||||
|
远程访问使用 HTTPS。代理到 RawMark 时需要转发 Host、协议与来源地址,并启用 WebSocket 升级和长连接;浏览器事件连接使用 `/api/v1/resources/<ticket>/events/`。代理上传限制也应满足实际导入需求。
|
||||||
|
|
||||||
|
[仓库 Nginx 配置](../deploy/nginx/raw.134333.xyz.conf)包含 WebSocket 和票据日志脱敏示例,但其中域名、证书 include、反爬 include、端口及日志路径属于原部署环境,**需要按自己的服务器调整,不能原样安装**。`$connection_upgrade` 的 map 也需要在 Nginx 的 `http` 上下文定义。
|
||||||
|
|
||||||
|
资源票据是凭据:代理、CDN 和访问日志不得记录明文票据、查询参数或携带凭据的 Referer;应用的 `no-store` 不能代替代理日志脱敏。Nginx 错误日志也可能包含原始请求路径,仓库示例对票据资源路径关闭错误日志,保留脱敏访问日志及应用错误日志。
|
||||||
|
|
||||||
|
若使用 CDN,需独立完成自定义域名与 TLS 证书配置,并确认 API、私有资源和 WebSocket 不被错误缓存;仅配置 DNS 不代表 HTTPS 接入已完成。
|
||||||
|
|
||||||
|
## 备份与恢复
|
||||||
|
|
||||||
|
在「设置 → 存储空间」选择所需导出类型:
|
||||||
|
|
||||||
|
| 类型 | 适合用途 | 恢复行为 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 普通 Markdown 笔记库 | 迁移到其他笔记工具 | 导入到新文件夹,不替换实例 |
|
||||||
|
| 设置与资源 | 迁移偏好、插件数据、字体/主题/插件 | 合并资源,同 ID 替换,包外资源保留 |
|
||||||
|
| 完整实例 | 迁移或恢复 RawMark | 替换业务数据,包含登录信息、回收站和资源,完成后重新登录 |
|
||||||
|
|
||||||
|
设置导入与完整恢复只接受本程序的版本化 ZIP,应用前会在 `backups/` 保留回退包。上传顺序分块,每块 8 MiB,压缩包上限 2 GiB,展开上限 8 GiB、100000 项。不包含运维环境配置、派生索引或临时文件。
|
||||||
|
|
||||||
|
完整恢复前停止其他程序直接改写笔记库。维护时暂时暂停 API 操作,关闭数据库和后台任务后恢复,中断时回退操作前备份。导出的完整包包含账户和笔记等敏感数据,应妥善保管,不提交到仓库或附在公开 Issue 中。
|
||||||
|
|
||||||
|
独立于应用备份,升级前建议停止服务后备份完整数据目录、外置笔记库、部署配置与旧镜像。SQLite 运行时可能有 WAL 文件,不要只复制正在写入的 `rawmark.db` 来冒充一致备份。
|
||||||
|
|
||||||
|
## 升级与回退
|
||||||
|
|
||||||
|
1. 确认目标版本的行为和数据兼容性,保留当前镜像及部署配置。
|
||||||
|
2. 停止旧服务,备份应用数据与外置笔记库。
|
||||||
|
3. 更新源码并重新构建,使用同一份挂载启动新实例;不要并行运行新旧服务。
|
||||||
|
4. 核对容器健康、登录、笔记与附件。回退时使用配套的旧镜像与数据备份。
|
||||||
|
|
||||||
|
Bearer 认证升级需要前后端一起发布。旧 Cookie 页面不能继续使用,需重新登录;启动程序会沿现有 SQLite 初始化流程创建资源票据表和索引,笔记、密码、设置与已有 API 令牌保留。第三方客户端的 JSON 解包方式须遵循[当前协议](api.md)。
|
||||||
|
|
||||||
|
`scripts/remove-sharing.sql` 和 `scripts/reset-shortcuts.sql` 是历史版本的一次性迁移:前者移除旧分享数据,后者清空旧快捷键覆盖。**新部署无需运行,已执行过的实例不要重跑**;只有确认来自对应旧版本且需要该迁移时,才在停服并备份后单独执行。
|
||||||
|
|
||||||
|
## 日常维护与排查
|
||||||
|
|
||||||
|
- 容器自带健康检查,也可访问 `GET /api/v1/health`;健康不代表所有业务流程已验证。
|
||||||
|
- 设置内的优化/重建仅处理派生索引;清理临时文件不删除用户文件、活动上传或恢复备份。
|
||||||
|
- 重置设置保留账户、资源、插件存储和本机标签页。
|
||||||
|
- 日志位于 `logs/`,轮转保留三份,每份至多 10 MiB;可在设置中导出日志及版本摘要。该功能不补录历史日志。
|
||||||
|
- 更新后界面异常先核对前后端是否来自同一构建,再查看浏览器网络请求和应用日志;插件与外观恢复入口见[使用指南](guide.md#插件与界面恢复)。
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
# 开发指南
|
||||||
|
|
||||||
|
[返回项目首页](../README.zh-CN.md) · [API 与认证](api.md) · [项目约束](../AGENTS.md)
|
||||||
|
|
||||||
|
## 工具链
|
||||||
|
|
||||||
|
- Go 1.27.2 或更高版本,具体要求见 [go.mod](../go.mod)。
|
||||||
|
- Node.js 24+、pnpm **12.11.2**;前端依赖以 [pnpm-lock.yaml](../web/pnpm-lock.yaml) 为准。
|
||||||
|
- Docker 仅在验证容器构建或部署时需要,本地开发不强制使用。
|
||||||
|
|
||||||
|
前端采用 Vue 3、TypeScript、Vite、Router、Pinia、Element Plus、Axios、SCSS 与 UnoCSS;编辑器使用 CodeMirror 6。服务端使用 Go 标准库 HTTP、SQLite 与文件系统;Markdown 文件是真源,搜索索引可以重建。
|
||||||
|
|
||||||
|
## 启动本地开发
|
||||||
|
|
||||||
|
```sh
|
||||||
|
corepack enable
|
||||||
|
corepack prepare [email protected] --activate
|
||||||
|
scripts/dev.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
脚本使用锁文件安装前端依赖,同时启动 Go 开发服务和 Vite 热更新。打开 http://localhost:5173,首次访问初始化密码;Ctrl+C 同时退出。
|
||||||
|
|
||||||
|
```sh
|
||||||
|
scripts/dev.sh --host # 允许局域网设备访问前端
|
||||||
|
scripts/dev.sh --help
|
||||||
|
```
|
||||||
|
|
||||||
|
`RAWMARK_DATA` 默认指向仓库的 `.dev-data/`,`API_PORT` 默认 8080,`WEB_PORT` 默认 5173。可通过环境变量覆盖,例如 `API_PORT=18080 WEB_PORT=15173 scripts/dev.sh`。不要将开发服务指向生产数据;初始化、恢复、导入和删除测试只使用合成数据。
|
||||||
|
|
||||||
|
开发模式从源码统计可选字体,日志版本显示为 `dev`,不读取旧 `web/dist`。生产模式使用嵌入的前端构建、字体清单和构建版本。
|
||||||
|
|
||||||
|
## 目录职责
|
||||||
|
|
||||||
|
```text
|
||||||
|
cmd/rawmark/ 服务入口
|
||||||
|
internal/
|
||||||
|
api/ HTTP 路由、授权、协议及 OpenAPI
|
||||||
|
auth/ 密码、会话与 API 凭据
|
||||||
|
store/ 应用 SQLite
|
||||||
|
vault/ 真源笔记、附件与文件操作
|
||||||
|
search/ 可重建的派生索引
|
||||||
|
web/
|
||||||
|
src/
|
||||||
|
pages/login/ 初始化与验证码登录
|
||||||
|
pages/workspace/ 笔记、目录、编辑器与图片管理
|
||||||
|
pages/settings/ 设置、账户与维护
|
||||||
|
common/apis/ 全部资源 API
|
||||||
|
common/components/ 跨模块公共组件
|
||||||
|
common/ 共享外观、Markdown、插件 SDK 与工具
|
||||||
|
http/ Axios、认证头、统一响应与错误
|
||||||
|
router/ 路由与守卫
|
||||||
|
pinia/ 实例及共享认证、权限、设置状态
|
||||||
|
types/auto/ 自动生成的导入声明
|
||||||
|
deploy/ 容器与代理配置
|
||||||
|
scripts/ 开发、资源生成及历史迁移脚本
|
||||||
|
```
|
||||||
|
|
||||||
|
页面私有组件、类型、状态、组合函数和资源跟随 `pages/<module>/`,确实跨模块复用的能力才进入 `common`;公共代码不得依赖页面私有实现。模块内优先相对导入,跨职责用 `@`(`web/src`)与 `@@`(`web/src/common`)。
|
||||||
|
|
||||||
|
全部资源接口位于 `common/apis/<resource>/index.ts` 和 `type.ts`。函数直接调用 `request<ResponseData>({ url, method, data, params })`,返回完整 `{ code, data, message }`,调用方显式读取 `.data`。原文/下载设置 `returnResponse: true` 保留 Axios 响应与响应头,204 返回 void,事件连接也归资源 API。不增加页面私有请求入口或多格式 fallback。
|
||||||
|
|
||||||
|
公共组件放在 `common/components/<PascalCaseName>/index.vue`。SFC 使用 Composition API 与 TypeScript,其他文件使用 kebab-case。自动声明应修改生成配置后重新构建,不手工编辑。更完整的执行约束以根 [AGENTS.md](../AGENTS.md) 为准,不另维护一套规范。
|
||||||
|
|
||||||
|
## 验证
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pnpm -C web install --frozen-lockfile
|
||||||
|
pnpm -C web lint:check
|
||||||
|
pnpm -C web typecheck
|
||||||
|
pnpm -C web test
|
||||||
|
pnpm -C web build
|
||||||
|
go vet -tags dev ./...
|
||||||
|
go test ./internal/...
|
||||||
|
go test -tags dev ./web
|
||||||
|
```
|
||||||
|
|
||||||
|
前端使用 Vitest,测试随模块存放;Go 使用标准 `testing`。生产构建需先生成 `web/dist`,Go 再将其嵌入二进制。`-tags dev` 保留无需嵌入产物的开发和对应测试边界。
|
||||||
|
|
||||||
|
按改动风险补充 Go race、Docker 构建及真实浏览器验收。认证与请求变更应覆盖验证码成功/失败/过期、401 与 403、服务端注销以及旧会话响应隔离;编辑器与文件操作应核对原文保存、版本冲突、附件及移动/导入/导出。不用空数据或模拟成功掩盖失败。
|
||||||
|
|
||||||
|
## 主题、字体与插件
|
||||||
|
|
||||||
|
内置默认、白色与黑色主题,保留独立明暗模式和 CSS 片段。自定义主题位于数据目录 `themes/<id>/`,包含 `manifest.json` 与 `theme.css`;清单包含 `id`、`name`、`version`,ID 与目录一致,不能覆盖保留的 `default`、`white`、`black`。在外观设置刷新列表后选择。
|
||||||
|
|
||||||
|
默认字体资源已入库,常规构建无需下载或转换。重新生成时,在独立 Python 环境安装 `fonttools[woff]`,下载 [Maple v7.9 指定字体包](https://github.com/subframe7536/maple-font/releases/download/v7.9/MapleMonoNormalNL-NF-CN.zip),执行:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
python3 scripts/prepare-maple-font.py /path/to/MapleMonoNormalNL-NF-CN.zip
|
||||||
|
```
|
||||||
|
|
||||||
|
脚本生成 WOFF2 和 `maple-font.css`,保留上游许可。代码块使用 highlight.js 的固定 Atom One Dark,不能在更新主题时顺带恢复旧高亮实现或配色。
|
||||||
|
|
||||||
|
插件 SDK 类型见 [common/plugin-api/index.d.ts](../web/src/common/plugin-api/index.d.ts),加载与生命周期实现位于 `common/plugins/`。插件仅在前端运行,安装者必须信任其代码;命名空间、停用及资源版本管理不等于权限沙箱。编辑器扩展故障时保留正文并停用当前页相关扩展。
|
||||||
|
|
||||||
|
## 提交改动
|
||||||
|
|
||||||
|
先阅读 [AGENTS.md](../AGENTS.md),聚焦实际需求,保留必要契约,不机械照搬模板示例。前端目录以 [vue3-starter 固定基线](https://github.com/eezd/vue3-starter/tree/fd41d62ce3f1c8338a478e0be3e2f31b53b7ea5e) 为参考,RawMark 的编辑器、主题和专用交互按业务保留。
|
||||||
|
|
||||||
|
提交前运行适用检查,说明实际验证与未验证范围。Commit 使用清晰英文,按功能拆分;不要提交真实笔记、账户数据、密钥或本地交接文件。
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
# 使用指南
|
||||||
|
|
||||||
|
[返回项目首页](../README.zh-CN.md) · [部署与维护](deployment.md) · [API 与认证](api.md)
|
||||||
|
|
||||||
|
RawMark 是单用户笔记工作台,笔记保存在服务器上。多个浏览器可以访问同一个实例;它不是多人协作系统,目前没有公开分享功能。
|
||||||
|
|
||||||
|
## 开始写作
|
||||||
|
|
||||||
|
首次访问设置密码,之后通过密码和图片验证码登录。在侧栏「文件目录」标题或空白处右键,可以搜索、新建笔记、新建目录、导入文档、打开标签索引或管理图片;点击标题同样可以打开菜单,便于触屏使用。
|
||||||
|
|
||||||
|
编辑器默认使用即时预览,点击右上角图标切换源码模式、打开大纲或进入专注写作。支持标准 Markdown、表格、任务列表、代码块、数学公式、Mermaid、脚注和 YAML 元数据。
|
||||||
|
|
||||||
|
正文修改自动保存,保存失败或版本冲突会明确提示。外部程序修改笔记时会同步到页面;出现冲突时请核对内容,不要直接覆盖仍需保留的版本。
|
||||||
|
|
||||||
|
选中文字后可使用外观、加粗、斜体、下划线、删除线、高亮与链接。局部外观和下划线以受限的标准 HTML 标签存入 Markdown,源码和导出会保留;其他阅读器是否呈现这些样式取决于其 HTML 支持。
|
||||||
|
|
||||||
|
## 整理笔记
|
||||||
|
|
||||||
|
- **文件与文件夹**:右键重命名、移动、删除或导出。拖到文件夹行会移入该文件夹,拖到笔记行会移入该笔记所在目录。
|
||||||
|
- **多选**:Ctrl/Cmd 点击切换选择,Shift 点击选择可见范围,再通过右键菜单批量操作。部分操作失败会逐项报告。
|
||||||
|
- **标签页**:支持固定和关闭其他标签;固定标签不会被「关闭其他标签页」关闭。打开的标签及固定状态在当前浏览器保存,刷新或重启后恢复。
|
||||||
|
- **图标**:文件夹默认 📂、文件默认 📄,点击图标或右键「修改图标」选择表情或内置图标。
|
||||||
|
- **标签和搜索**:正文 `#标签`、YAML `tags` 可用于归类;全文搜索用于查找笔记。文章标题生成右侧大纲。
|
||||||
|
|
||||||
|
应用内重命名和移动会维护笔记中的本地链接与图片引用。直接在文件系统中操作时,不保证链接、图标等元数据跟随;这些操作优先在 RawMark 内完成。
|
||||||
|
|
||||||
|
## 导入与导出
|
||||||
|
|
||||||
|
在目录或文件夹菜单选择「导入」,支持多个 UTF-8 `.md` 文件或单个 ZIP,总上传上限为 100 MiB。
|
||||||
|
|
||||||
|
ZIP 会导入到同名新文件夹,保留笔记层级。本地图片归入各笔记同级的 `assets/`,并改写引用;同名不同内容不会覆盖。缺失的本地链接会提示,远程图片不会自动下载。可以用思源笔记等工具导出的 Markdown ZIP 迁入,具体排版仍取决于其 Markdown 内容。
|
||||||
|
|
||||||
|
导出时,单篇无附件笔记直接下载 `.md`;其他情况下载保留层级、原文与本地附件的 ZIP,不下载远程资源。选中项存在缺失附件时会报错,便于先修复再导出。
|
||||||
|
|
||||||
|
整个笔记库的普通 Markdown 导出在「设置 → 存储空间」,缺失附件记录于导出包的 `.rawmark-export/missing-assets.json`。这个报告不会在重新导入时成为笔记。
|
||||||
|
|
||||||
|
## 图片管理
|
||||||
|
|
||||||
|
粘贴、上传和导入的图片默认保存在笔记同级的 `assets/`,同目录相同内容去重,正文使用相对路径。侧栏隐藏附件目录,右键文件夹选择「图片管理」即可查看,也可切换整个知识库。
|
||||||
|
|
||||||
|
图片管理提供检索、排序、网格/列表、批量上传、预览、引用查看、重命名、移动和替换。重命名或移动会更新笔记引用;替换保留路径,要求相同扩展名、最大 50 MiB,旧图片不会进入回收站。
|
||||||
|
|
||||||
|
笔记跨目录移动时图片跟随,仍被其他笔记引用的原图保留。**删除单篇笔记不会顺便删除共享图片**。清理孤立图片会先展示候选,再核对全库引用,将符合条件的图片移入回收站。旧版 `笔记名.assets/` 附件目录仍可读取、移动与恢复。
|
||||||
|
|
||||||
|
## 外观、字体与快捷键
|
||||||
|
|
||||||
|
在「设置 → 外观」切换明暗模式、主题,调整界面字体和字号、玻璃透明度或 CSS 片段;正文与代码字体、正文宽度、行高等位于编辑器设置。设置保存在服务器,多个设备共享;标签页等本机状态单独保存。
|
||||||
|
|
||||||
|
默认字体为 Maple Mono Normal NL NF CN v7.9,不可删除。界面、正文和代码可分别选择字体,各字体选择器支持导入 TTF、OTF、WOFF、WOFF2(单个不超过 30 MiB)及删除导入字体。页面等待所需字体加载后显示,失败会提示刷新。代码块固定使用 highlight.js 的 Atom One Dark,与页面明暗模式独立。
|
||||||
|
|
||||||
|
快捷键默认参考 Typora 的 Windows/Linux 或 macOS 组合,无对应项及插件命令默认留空。可以搜索、添加、逐条删除、单项或全部重置,冲突绑定会被拒绝。Ctrl/Cmd+1~6 设置对应标题,再次触发同级标题恢复正文;浏览器保留键可自行改绑。
|
||||||
|
|
||||||
|
手机设置采用分类和内容两级布局。应用安装入口位于「设置 → 关于」;PWA 缓存静态外壳,**不代表支持离线编辑与离线同步**。
|
||||||
|
|
||||||
|
## 回收站与存储空间
|
||||||
|
|
||||||
|
删除的内容进入回收站,支持恢复和清空全部。默认保留 30 天,设置为 0 则不自动删除;修改期限同样影响已有条目,清理在启动时及每小时执行。
|
||||||
|
|
||||||
|
「存储空间」自动展示数据目录、外置笔记库和可选字体占用;字体统计不含默认 Maple,附件与回收站计入笔记库。这里还可导出/导入完整实例、笔记和设置,优化/重建索引、清理临时文件、重置设置及导出日志。
|
||||||
|
|
||||||
|
完整实例恢复会替换当前业务数据并要求重新登录;替换前请先备份,具体范围、限制与恢复注意事项见[部署与维护](deployment.md#备份与恢复)。
|
||||||
|
|
||||||
|
## 插件与界面恢复
|
||||||
|
|
||||||
|
插件由实例管理者安装,属于有完整前端权限的扩展,请只安装可信来源;不提供沙箱隔离保证。开发入口见[开发指南](development.md#主题字体与插件)。
|
||||||
|
|
||||||
|
插件导致界面异常时,可在地址后加 `?disable-plugins` 暂停插件并进入管理。主题或 CSS 片段导致界面不可用时,可加 `?reset-appearance` 临时停用自定义外观,再进入设置恢复默认。这些入口不自动删除笔记或丢弃编辑内容。
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 108 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 109 KiB |
Reference in new issue
Block a user