# triple **Repository Path**: libingquan/triple ## Basic Information - **Project Name**: triple - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-31 - **Last Updated**: 2026-09-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Triple App 日历 + 待办 + Flomo 速记,自托管效率工具。Spring Boot + Vue 3 实现,移动端 PWA 免安装。 ## 功能 | 模块 | 功能 | |------|------| | 📅 日历 | 月/周/日三视图、事件 CRUD(含编辑)、颜色标签、全天事件、重复事件(每日/每周多选/每月/每年 + 间隔 + 结束日期)、当日面板一键完成待办 | | ✅ 待办 | 多列表(长按删除,级联清理)、优先级、截止日期、备注、筛选(全部/未完成/已完成/今天/高优先级)、快速添加、编辑、列表内拖拽排序、左滑完成/删除 | | 💡 Flomo | 快速记录、#标签、Markdown、链接自动识别与预览卡、时间线、搜索、每日回顾、一键复制(卡片图标 / 左滑)、左滑编辑/删除 | | 🌙 体验 | 深色模式(跟随系统/浅色/深色手动切换) | | 📊 看板 | 周期统计卡片 + 近 30 天 echarts 趋势图表 | | 🧾 物品 | 归物本:记录购买时间与价格,自动计算已用天数与每日成本,置顶总资产/日均成本(仅现役),预定义分类 + 现役/退役状态 + 名称模糊搜索 | | 🔗 分享 | 家庭共享的 HTML 攻略/计划列表(管理员放置文件到服务器目录或在 App 内粘贴发布,自动扫描 + `` 识别标题,新标签页公开打开),详见 [`SHARE-FEATURE.md`](./SHARE-FEATURE.md) | | 👤 用户 | JWT 认证、修改密码、数据隔离、管理员用户管理(生产关闭自助注册) | | 🔔 提醒 | 邮件提醒(R1:待办当天 09:00 / 事件提前 / 全天事件前一天,均可配置,「我的」页设置);iOS Web Push(R2:Safari 16.4+ 走 APNs,需配 VAPID 密钥,见 `ALIYUN-DEPLOY.md` §5.4;Android 走邮件兜底) | ## 技术栈 - **后端**: Spring Boot 3.4 + Spring Security + JPA + H2 - **前端**: Vue 3 + Vite + Vant UI + Pinia - **部署**: Caddy + systemd + 自有域名(自动 HTTPS) ## 快速开始(本地开发) ### 后端 ```bash cd backend ./mvnw spring-boot:run # 默认端口 8082,H2 控制台 http://localhost:8082/h2-console # 默认管理员: admin / admin123 ``` ### 前端 ```bash cd frontend pnpm install pnpm dev # 默认端口 5173,自动代理 /api → localhost:8082 ``` > 构建前端需要 Node.js ≥ 22.13(新版 pnpm 要求)。如果本机默认是 Node 18,请先执行 > `nvm use 22` 或 `nvm alias default 22`。 ## 生产部署 > 速查(现状 → 上线 → 运维,推荐先看):[`DEPLOY-QUICKSTART.md`](./DEPLOY-QUICKSTART.md) > 完整方案(地域选择、备案、OSS 异地备份〔可选层〕、探活告警、运维手册、事实核查):[`ALIYUN-DEPLOY.md`](./ALIYUN-DEPLOY.md)。以下为速查摘要。 ### 0. 前提 - 选择**海外免备案地域**;香港轻量部分规格已停售/缺货,可用**马来西亚(吉隆坡)**等替代。买一个**自有域名**(如 `triple.example.com`,解析子域名 A 记录到服务器公网 IP)。 - 服务器规格:阿里云轻量 2C2G / 40GB ESSD / 200Mbps 峰值 / 1 IPv4 / 无固定流量,Ubuntu 22.04 即可。 ### 1. 服务器初始化(一次性) ```bash # 1) Caddy 官方仓库(Ubuntu 22.04 官方源没有 caddy 包,勿用 apt install caddy) sudo apt update && sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl wget git unzip curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list sudo apt update && sudo apt install -y caddy openjdk-17-jdk-headless # 2) 应用专用用户(无登录 shell) sudo useradd -r -s /bin/false triple sudo timedatectl set-timezone Asia/Shanghai # 3) 初始化 Caddy 全局"导入壳"(一次性) # 全局 Caddyfile 是多项目共享的壳,只负责 import 各项目分片; # deploy.sh 只写本项目分片 /etc/caddy/sites.d/triple.caddy,绝不整体覆盖它。 # 若服务器已有多项目在用,先按 CADDY-MULTI-PROJECT.md 第二节做拆分迁移(备份→拆分片→写壳→validate→reload),勿直接覆盖! sudo mkdir -p /etc/caddy/sites.d sudo tee /etc/caddy/Caddyfile > /dev/null <<'EOF' # 全局 Caddy 配置壳:只导入各项目分片(勿整体覆盖本文件) # 如需全局选项(如 email you@example.com),在本文件顶部加 { ... } 块 import /etc/caddy/sites.d/*.caddy EOF ``` ### 2. 首次部署环境变量(仅首次) ```bash export JWT_SECRET="$(openssl rand -base64 48)" export ADMIN_PASSWORD="你的管理员密码" ``` > 首次部署写入 `/etc/triple/triple.env`(chmod 600)。**再次部署可省略**——脚本复用旧文件,避免轮换 JWT_SECRET 导致已登录用户全部掉线。 ### 3. 本地构建并上传(推荐,2G 内存不跑构建) ```bash # —— 开发机 —— cd backend && mvn clean package -DskipTests && cd .. cd frontend && pnpm install && pnpm build && cd .. ssh root@<IP> 'mkdir -p /root/triple-release/static' scp backend/target/triple-0.0.1.jar root@<IP>:/root/triple-release/triple.jar scp -r frontend/dist/* root@<IP>:/root/triple-release/static/ scp deploy.sh Caddyfile triple.service root@<IP>:/root/triple-release/ # —— 服务器 —— cd /root/triple-release ./deploy.sh triple.example.com --skip-build ``` > `deploy.sh <域名> [--skip-build]`:`--skip-build` 跳过构建,直接读取服务器 `/root/triple-release/triple.jar` 和 `/root/triple-release/static/`;不带参数则在服务器上全量构建(需 2G+ swap)。 > > `deploy.sh` 不再整体覆盖 `/etc/caddy/Caddyfile`,只写本项目分片 `/etc/caddy/sites.d/triple.caddy` 后 reload(多项目互不影响,详见 `CADDY-MULTI-PROJECT.md`);若服务器全局 Caddyfile 尚未初始化为导入壳,脚本会报错中止——按第 1 节步骤 3 初始化即可。 ### 4. 验证 ```bash sudo systemctl status triple # active (running) curl -sI https://triple.example.com | head -3 # HTTP/2 200 ``` 浏览器打开 `https://triple.example.com` → admin 登录 → **设置 → 用户管理** 给家人建号(自助注册已在生产关闭)。 > 如果域名刚注册仍处于实名审核中,HTTPS 证书暂时无法签发;等待审核通过并添加 A 记录后,执行 > `sudo systemctl reload caddy`,Caddy 会自动补齐证书。 ### 5. 备份(三重) - 应用内 `DatabaseBackupService` 每日 03:00 执行 H2 `BACKUP` → `/opt/triple/backup/triple-日期.zip`(保留 7 天) - OSS 异地(可选层):每日 03:30 cron 用 `ossutil` 上传最新 zip 到与服务器同地域的 Bucket(内网 endpoint 免流量,保留 30 天;不配不影响上线,可后置补) - 本地兜底:每月手动/NAS 拉一次全量 恢复:`sudo /opt/triple/restore.sh triple-日期.zip`(支持 zip 与 .mv.db;跨机迁移须连同 `/etc/triple/triple.env` 一起搬)。 ## 安全 - 所有流量通过 Caddy 自动 HTTPS 加密 - 密码 bcrypt 哈希(cost 12) - JWT 双 token:access(15min,仅前端内存)+ refresh(7d,httpOnly + Secure + SameSite Cookie,不落 localStorage),带类型声明互不混用,改密/登出即时失效 - 数据按用户隔离,从 JWT 提取 userId - 速记链接预览:服务器按内容首个链接抓取 og 元数据生成卡片,经**私网 IP 守卫(SSRF 防护)+ 每日配额**,仅 http/https、响应限长/超时;失败不影响速记保存,可关(`app.link-preview.enabled=false`) - 生产**关闭自助注册**(`app.registration.enabled=false`),账号由管理员在「用户管理」页创建;管理员可删除用户(不能删除自己) - SSH 建议密钥登录,防火墙只放行 22/80/443 ## 数据备份 - 数据库:H2 file 模式(详见 PRD 第七章选型分析) - 定时备份:每日凌晨 3 点自动执行 H2 `BACKUP` 生成 zip(`DatabaseBackupService` → `/opt/triple/backup/`),保留最近 7 天 - 异地备份(可选层):`ossutil` 上传至阿里云 OSS(详见 ALIYUN-DEPLOY.md;不配时保持每月手动拉取兜底) - 手动冷备:`backup.sh`(服务运行中会自动停服 → 拷贝 → 重启,保证 `.mv.db` 一致性) - 恢复:`restore.sh`,同时支持 `.zip`(应用内自动备份)与 `.mv.db`(冷备文件);恢复后自动 `chown triple` - 数据导出/导入:设置页「导出数据」一键导出全部 JSON;「导入数据」把导出的 JSON 重新导入当前账号(追加合并) - 生产 schema:`ddl-auto: validate` + Flyway 版本化迁移(V1 初始化),避免隐式改表 ## 项目结构 ``` triple-app/ ├── backend/ # Spring Boot │ ├── src/main/java/com/triple/ │ │ ├── config/ # Security, CORS, DataInit, 定时备份 │ │ ├── security/ # JWT, AuthFilter, Utils │ │ ├── user/ # User entity, service, controller │ │ ├── calendar/ # CalendarEvent entity, service, controller, Dashboard │ │ ├── task/ # TaskList, TaskItem entities, service, controller │ │ ├── memo/ # Memo entity, service, controller │ │ ├── reminder/ # 提醒:Planner/Scheduler、邮件+Web Push 通道、订阅、偏好 │ │ ├── share/ # 分享(攻略):扫描本地 HTML 生成列表 │ │ ├── item/ # 物品(归物本):购买/价格/日均成本/分类/状态 │ │ ├── export/ # 数据导出 / 导入 │ │ └── common/ # ApiResponse, ExceptionHandler │ ├── src/main/resources/ │ │ ├── application.yml │ │ ├── application-prod.yml │ │ └── db/migration/ # Flyway 版本化迁移 │ └── src/test/ # 集成 + 单元测试(211 用例) ├── frontend/ # Vue 3 + Vite │ ├── src/ │ │ ├── api/ # Axios client + module APIs │ │ ├── stores/ # Pinia stores │ │ ├── views/ # Page components(含 UserManagementView、ShareView、ItemsView) │ │ ├── components/ # Reusable components │ │ ├── utils/ # 工具(recurrence/push/renderMarkdown/links/date/priority/tags) │ │ ├── router/ # Vue Router │ │ ├── styles/ # Global CSS │ │ └── sw.js # 自定义 Service Worker(预缓存 + Web Push) │ ├── e2e/ # Playwright E2E 冒烟(8 步) │ └── public/ │ └── icons/ # App icons(manifest 由 VitePWA 生成) ├── Caddyfile # Caddy 站点分片模板(部署写入 /etc/caddy/sites.d/triple.caddy) ├── CADDY-MULTI-PROJECT.md # 多项目共享 Caddy 的分片化改造方案 ├── triple.service # systemd unit file ├── deploy.sh # One-click deployment script ├── backup.sh # Database backup script ├── restore.sh # Database restore script ├── healthcheck.sh # 探活脚本(4 探针 + 企业微信告警,--self-test 自测) ├── ALIYUN-DEPLOY.md # 阿里云部署完整方案 ├── DEPLOY-QUICKSTART.md # 部署速查(现状→上线→运维) ├── PRD.md # 产品需求文档 ├── TESTING.md # 测试方案与状态 ├── SHARE-FEATURE.md # 分享(攻略)功能说明 + 完整升级方案 └── generate-icons.sh # PWA icon generator ``` ## API 文档 详见 PRD 文档中的 API 设计章节。 ## License MIT