聚合导航 (juheye-nav)
个人 / 小团队自托管的网址导航站, 集成收藏夹、备忘录、工具集、邀请码注册、和风天气面板。
✨ 功能一览
| 模块 | 说明 |
|---|---|
| 分类 + 链接 | 树状分类 + 卡片链接, 支持拖拽换位 (持久化到 DB) |
| 批量模式 | 多选链接后批量调整分类 |
| 搜索 | 百度/Google/Bing 切换, 本地搜索(在当前用户网址中查找) + 一键清除 |
| 备忘录 | Markdown 增删改查, 关键词搜索 |
| 实用工具 | /tools 收集的常用工具页 |
| 邀请码注册 | 模拟支付购买邀请码, 注册流程无需暴露邀请码 |
| 管理后台 | 用户/邀请码/订单/统计/Logo 上传/全局设置 |
| 天气面板 | 后端用 Ed25519 签名调用和风天气, 暴露代理 API |
| 收藏夹导入 | 解析 Chrome / Edge 导出的 Netscape HTML 一次性导入 |
🛠 技术栈
- 后端: Node.js + Express 4
- 数据库: MySQL 5.7+ (via
mysql2/promise连接池) - 文件上传: Multer 2.x (单文件 2MB, 仅图片)
- Markdown:
marked - 前端: 原生 HTML / CSS / JS, 无构建步骤
- 签名: 和风天气 Ed25519 (后端持有私钥, 前端只看到代理接口)
🚀 快速开始
1. 准备环境
- Node.js ≥ 14
- MySQL ≥ 5.7 (本地或远程都可)
- 一个和风天气账号 (天气功能用, 没有也不影响其它功能)
2. 克隆与安装
git clone <your-repo-url> juheye-nav
cd juheye-nav
npm install
3. 准备环境变量
cp .env.example .env
# 编辑 .env, 填入 DB 口令和和风天气配置 (可暂时留空跳过天气功能)
.env 中关键变量:
| 变量 | 必填 | 说明 |
|---|---|---|
DB_HOST / DB_USER / DB_PASSWORD / DB_NAME |
✅ | MySQL 连接信息 |
QWEATHER_HOST |
⛅ | 和风天气 API Host, 例 api.qweather.com |
QWEATHER_PROJECT_ID |
⛅ | 控制台项目 ID (JWT sub) |
QWEATHER_CREDENTIAL_ID |
⛅ | JWT 凭据 ID |
QWEATHER_PRIVATE_KEY |
⛅ | Ed25519 私钥 (PKCS8 PEM) |
PORT |
⛔ | 监听端口, 默认 3000 |
⚠️ 私钥不要提交到 git,
.env已被.gitignore忽略。
4. 初始化数据库
首次启动时, 服务会调用 initSchema() 自动建表 (用户/分类/链接/备忘录/邀请码/订单/设置等)。无需手动跑 SQL。
5. 启动
# 前台
node server.js
# 后台
nohup node server.js > server.log 2>&1 &
打开 http://localhost:3000 即可。
6. 创建管理员 (可选)
服务启动后, 数据库里第一个注册的用户默认是普通用户; 如需管理员, 在 MySQL 里手动改 users.is_admin=1 或者使用服务内置的 CLI:
node server.js add-user <username> <password>
node server.js list-users
📂 目录结构
juheye-nav/
├── server.js # Express 入口, 全部 API 路由
├── db.js # MySQL 封装 (CRUD / 迁移 / 用户认证)
├── package.json
├── .env / .env.example # 环境变量 (后者入库)
├── .gitignore
├── data/ # 运行时数据 (不入库)
├── public/
│ ├── index.html # 主导航页
│ ├── login.html # 登录 / 注册
│ ├── admin.html # 管理后台
│ ├── memo.html # 备忘录
│ ├── tools.html # 工具集合
│ ├── buy-invite.html # 邀请码购买
│ ├── app.js / style.css # 主导航页脚本与样式
│ └── uploads/ # 用户上传的 logo (运行时)
├── docs/ # 项目文档 (本 README 之外的详细文档)
│ ├── API.md # 全部后端 API
│ ├── DEPLOY.md # 部署 / 反代 / HTTPS
│ └── CHANGELOG.md # 版本与更新日志
└── backups/ # 本地备份归档 (不入库)
🔌 主要 API
| Method | Path | 鉴权 | 说明 |
|---|---|---|---|
POST |
/api/auth/register |
否 | 邀请码注册 |
POST |
/api/auth/login |
否 | 登录, 返回 token |
GET |
/api/links |
✅ | 当前用户全部链接 (按 sort_order 排序) |
POST |
/api/links |
✅ | 新增链接 |
PUT |
/api/links |
✅ | 整体替换 (导入用) |
PUT |
/api/links/batch |
✅ | 批量调整分类 |
PUT |
/api/links/order |
✅ | 拖拽排序持久化 |
GET/POST/PUT/DELETE |
/api/categories[/...] |
✅ | 分类 CRUD |
PUT |
/api/categories/order |
✅ | 拖拽分类顺序持久化 |
GET/POST/PUT/DELETE |
/api/memos[/:id] |
✅ | 备忘录 CRUD |
GET |
/api/memos/search?q= |
✅ | 备忘录关键词搜索 |
POST |
/api/admin/logo |
👑 | 上传 Logo (admin) |
GET |
/api/weather |
否 | 和风天气代理 (后端 Ed25519 签名) |
👑 = 管理员; 完整 API 见 docs/API.md
🧱 数据库表
| 表 | 用途 |
|---|---|
users |
用户, 头像/管理员标志/密码 hash |
categories |
分类, 颜色, sort_order |
links |
链接, 分类, sort_order |
memos |
备忘录, Markdown 内容 |
invite_codes |
邀请码, 状态, 创建/使用者 |
orders |
模拟支付订单 |
tokens |
登录 token (Bearer) |
settings |
全局设置 KV (site_name / logo 等) |
🔒 安全要点
- 密码使用
crypto.scrypt哈希 - Token 存 DB, 每次请求校验有效性, 注销即失效
- 上传限制 2MB + MIME 校验
- 所有用户数据按
user_id隔离, 越权访问返回 401/403 .env/node_modules/public/uploads/*不入库- Ed25519 私钥只在后端, 前端只能访问代理后的数据
🧰 常用运维
# 查看运行中的服务
ps aux | grep "node server.js"
# 看实时日志
tail -f server.log
# 备份 (自动排除 node_modules / .env)
./scripts/backup.sh
# 还原
tar -xzf backups/juheye-nav-YYYYMMDD-HHMM.tar.gz
📚 文档索引
📝 备注
- 本项目不依赖任何前端构建工具, 直接
node server.js即可 - 拖拽排序会调用
PUT /api/links/order, 后端写sort_order字段, 前端localStorage仅作离线容错 - 邀请码流程是模拟支付, 生产环境请对接真实支付网关
🤝 贡献
欢迎 PR / Issue, 提 PR 前请:
- 同步更新
docs/CHANGELOG.md对应章节 - 新增 API 同步更新
docs/API.md - 保持代码风格一致 (2 空格缩进, 单引号优先)
📄 许可证
MIT
聚合页开源站