feat: 洗车管理系统 v2.8 — 个人 detailer 单用户全栈应用

- 车辆 / 洗车 / 加油 / 充电 / 保养 / 保险 完整 CRUD + 软删
- AI 截图识别(5 类型 OCR schema):OpenAI 兼容 + MiniMax M3
- 化学品 / Grocy 实例对接 + 库存镜像同步
- 仪表盘:30 天频次 + 健康度 + 同比环比 + 油价趋势 + 年均养护
- 月度报表:Excel 6 sheet + PDF
- PWA:manifest / SW / 离线缓存 / iOS 引导
- 安全:bcrypt + CSRF + 登录锁定(IP/用户/全局三级)+ 401 自动跳登录 + 表单草稿
- 高 ROI 8 功能:里程/提醒/成本/搜索/标签/通知/同比/成就
- 3 个新 migration(0016/0017/0018)+ 18 个迁移全幂等
- 101/101 测试通过(含 ipRateLimit / CSRF / retry / stats / tags / notifications)
- 部署:宝塔面板文档 + PM2 + Nginx
This commit is contained in:
2026-06-20 21:11:54 +08:00
commit fe17886ac4
176 changed files with 40003 additions and 0 deletions
+180
View File
@@ -0,0 +1,180 @@
# 宝塔面板安装(Node.js 版)
> 适用:CentOS 7+ / Ubuntu 20+ / Debian 11+,宝塔 7.7+Node.js ≥ 20
## 0. 系统要求
- Node.js **20+**(宝塔「软件商店」→ Node.js 版本管理器 → 安装 20.x LTS)
- 内存 ≥ 512 MB,磁盘 ≥ 2 GB
- 一台已解析好的域名(可选,纯 IP 也能跑)
## 1. 宝塔安装 Node.js
「软件商店」搜索 **Node.js 版本管理器** → 安装 → 切换到 **20.x** → 设为默认。
SSH 验证:
```bash
node -v # 应显示 v20.x.x
npm -v # 应显示 10.x
```
## 2. 创建站点 + 上传代码
### 方式 A:直接上传 zip
1. 宝塔 → 网站 → **添加站点**(PHP 静态都无所谓,因为走 Node)→ 记下站点根目录,如 `/www/wwwroot/carwash.example.com`
2. 上传 `carwash-system-v2.zip` 到站点根目录
3. SSH 到服务器:
```bash
cd /www/wwwroot/carwash.example.com
unzip -o carwash-system-v2.zip
```
### 方式 Bgit 拉取
```bash
cd /www/wwwroot/carwash.example.com
git clone <your-repo-url> .
```
## 3. 安装依赖 + 构建前端
```bash
cd /www/wwwroot/carwash.example.com
npm run install:all
```
这会执行:
- `npm install --prefix server`(约 100 个包,含 better-sqlite3,需编译)
- `npm install --prefix client`(约 200 个包,纯 JS
- `npm run build --prefix client`Vite 打包到 `client/dist/`
> ⚠ **better-sqlite3 需要 Node-gyp 编译**。如遇 `node-gyp` 报错:
> ```bash
> # CentOS
> yum install -y python3 make gcc gcc-c++ nodejs
> # Ubuntu/Debian
> apt install -y python3 make g++ build-essential
> ```
## 4. 初始化数据库
```bash
cd /www/wwwroot/carwash.example.com
npm run migrate
```
期望输出:
```
✓ Migration 0001_init.sql
✓ Migration 0002_auth.sql
✓ Migration 0003_vehicles.sql
✓ 已创建默认管理员账号
用户名: admin
密码: carwash2026
⚠ 首次登录后请到「设置 → 账户」修改密码!
```
可选灌入演示数据:`npm run seed-demo`
## 5. 配置 .env
```bash
cp .env.example .env
nano .env
```
填天气 API key、Grocy 凭证等(全部可留空,留空不影响启动;只是相关功能不可用)。
## 6. 启动服务(PM2
宝塔「软件商店」搜索 **PM2 管理器** → 安装。
```bash
cd /www/wwwroot/carwash.example.com
pm2 start npm --name carwash -- run serve
pm2 save
pm2 startup # 设置开机启动(按提示复制粘贴输出的命令)
```
验证:
```bash
pm2 list # 看到 carwash status = online
curl http://127.0.0.1:8787/api/health
# → {"ok":true,...}
```
## 7. Nginx 反向代理
宝塔 → 网站 → 你的站点 → **设置** → **反向代理**:
- 代理名称:carwash
- 目标 URL`http://127.0.0.1:8787`
- 发送域名:留空
或在「配置文件」里把 `location /` 替换为:
```nginx
location / {
proxy_pass http://127.0.0.1:8787;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 60s;
}
# 上传大小限制(备份恢复可能上传大文件)
client_max_body_size 50M;
```
> 不需要 PHP,不需要伪静态规则。Node 直接吐 `index.html`。
## 8. 申请 HTTPS(强烈建议)
宝塔 → 站点 → **SSL** → Let's Encrypt → 申请 → 强制 HTTPS。
## 9. 备份与 cron
```bash
# 每天凌晨 3 点备份
crontab -e
0 3 * * * cd /www/wwwroot/carwash.example.com && npm run backup
```
备份保留 10 份,自动清理老的(`storage/backups/carwash-YYYYMMDDHHMM.tar.gz`)。
## 10. 升级
```bash
cd /www/wwwroot/carwash.example.com
git pull # 或重新上传新版 zip 后 unzip -o
npm run install:all
npm run migrate
pm2 restart carwash
```
数据库结构变更在 `server/migrations/0004_*.sql` 这种格式里加,`migrate` 会自动跳过已应用的。
## 11. 常见问题
**Q: 端口 8787 被占?**
A: 编辑 `.env` 改 `PORT=8788`,然后 `pm2 restart carwash` + 改 nginx 代理。
**Q: better-sqlite3 安装失败?**
A: 系统缺少编译工具链,安装 python3 + make + g++(见步骤 3)。
**Q: 忘记 admin 密码?**
A: SSH 跑 `npm run users -- passwd admin 新密码`。
**Q: 浏览器打开页面是空白?**
A: 检查 `pm2 logs carwash`;最常见是没跑 `npm run build:client` 或 nginx 配置没指向 Node。
**Q: SQLite 锁了?**
A: 检查 `server/data/` 下有没有遗留的 `-wal` / `-shm` 文件没被清理;正常 `pm2 stop` 会触发 checkpoint。
**Q: 多设备共享数据?**
A: 这是个人单机系统。如果要支持远程访问,**必须**走 HTTPS + 反向代理(本教程标准配置),不要直接暴露 8787 端口到公网。