Files
Lottery/deploy/DEPLOY.md
vincent 462adcc424 docs(deploy): BIZ-105 v1.2 部署记录(严维序 2026-08-31)
- 部署时间/版本/分支记录
- smoke 测试结果 + waiting 契约确认
- 已知后续验证项(2026-09-01 开奖后 e2e)
2026-08-31 07:15:01 +08:00

307 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 双色球系统部署文档
## 部署信息
| 项目 | 值 |
|------|-----|
| 项目名称 | 双色球自动化系统 |
| 部署时间 | 2026-07-04 |
| 开发人员 | 徐聪 (costcodev) |
| 部署人员 | 严维序 (opengineer) |
| 服务地址 | http://192.168.1.99:8085 |
| 代码仓库 | http://192.168.1.99:12299/vincent/Lottery.git |
| 宿主服务器 | Ubuntu-OpenClaw (192.168.1.99) |
---
## 一、项目结构
```
/home/vincent/Studio/lottoData/
├── venv/ # Python 虚拟环境
├── app.py # Flask 统一 Web 服务 (监听 0.0.0.0:8085)
├── index.html # 前端 UI (响应式,4 Tab 页面)
├── lottery.py # 双色球号码生成器核心逻辑
├── fetch_data.py # 历史数据抓取脚本
├── web_console.html # 数据抓取控制台前端页面
├── web_executor.py # [已废弃] 旧版独立抓取服务,功能已整合到 app.py
├── requirements.txt # Python 依赖清单
├── 双色球历史数据.xlsx # 历史数据文件 (不纳入 git)
├── lottery/ # 号码生成结果输出目录 (不纳入 git)
├── .generation_records.json # 生成记录索引 (不纳入 git)
├── .fetch_status.json # 抓取状态文件 (不纳入 git)
├── docs/ # 文档目录
│ ├── PRD-双色球 WebUI-v1.0.md
│ └── 开发文档-双色球WebUI-v1.0.md
└── deploy/ # 部署文件
├── DEPLOY.md # 本文档
├── lotto-app.service # systemd 服务文件 (统一入口)
├── fetch_daily.sh # 每日定时抓取脚本
├── backup.sh # 备份脚本 (30天保留)
├── cron.log # Cron 执行日志
└── fetch_YYYYMMDD.log # 每日抓取详细日志
```
**说明**: `app.py` 是统一入口,整合了号码生成、历史数据、生成记录、统计数据抓取等全部功能。`web_executor.py` 已废弃,不需独立部署。
---
## 二、依赖清单
| 包 | 用途 |
|----|------|
| Flask | Web 服务框架 |
| pandas | 数据处理 |
| openpyxl | Excel 读写 |
| numpy | 数值计算 |
| requests | HTTP 请求 (数据抓取) |
| beautifulsoup4 | HTML 解析 (数据抓取) |
安装命令:
```bash
python3 -m venv venv
./venv/bin/pip install -r requirements.txt
```
---
## 三、systemd 服务配置
### 服务文件
`/etc/systemd/system/lotto-app.service`
```ini
[Unit]
Description=双色球号码生成 Web 服务 (app.py :8085)
After=network.target
[Service]
Type=simple
User=vincent
WorkingDirectory=/home/vincent/Studio/lottoData
ExecStart=/home/vincent/Studio/lottoData/venv/bin/python3 /home/vincent/Studio/lottoData/app.py
ExecStartPre=/home/vincent/Studio/lottoData/venv/bin/python3 -c "import flask; import pandas; import openpyxl; import numpy"
Restart=on-failure
RestartSec=5
KillMode=control-group
Environment=PYTHONUNBUFFERED=1
[Install]
WantedBy=multi-user.target
```
### 管理命令
```bash
# 安装/启用
sudo cp deploy/lotto-app.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable lotto-app
sudo systemctl start lotto-app
# 日常管理
sudo systemctl status lotto-app # 查看状态
sudo systemctl restart lotto-app # 重启
sudo systemctl stop lotto-app # 停止
sudo journalctl -u lotto-app -f # 查看实时日志
```
### 生产部署建议
建议使用 gunicorn 替代 Flask 内置服务器:
```bash
./venv/bin/pip install gunicorn
# 修改 ExecStart 为:
# /home/vincent/Studio/lottoData/venv/bin/gunicorn -w 4 -b 0.0.0.0:8085 app:app
```
---
## 四、Cron 定时任务
### Cron 配置
```
30 2 * * * /home/vincent/Studio/lottoData/deploy/fetch_daily.sh >> /home/vincent/Studio/lottoData/deploy/cron.log 2>&1
0 3 * * * /home/vincent/Studio/lottoData/deploy/backup.sh >> /home/vincent/Studio/lottoData/deploy/cron.log 2>&1
```
- 每天 02:30 自动抓取双色球历史数据
- 每天 03:00 自动备份数据(保留 30 天)
### 手动执行
```bash
/home/vincent/Studio/lottoData/deploy/fetch_daily.sh
# 或通过 Web 控制台触发: http://192.168.1.99:8085/fetch
```
---
## 五、Web 接口清单
| 路径 | 方法 | 说明 |
|------|------|------|
| `/` | GET | 双色球 Web UI 首页(号码生成) |
| `/fetch` | GET | 数据抓取控制台 |
| `/api/generate` | POST | 生成号码(参数: num_tickets, strategy |
| `/api/history` | GET | 获取历史开奖数据(参数: page, page_size, search |
| `/api/records` | GET | 获取生成记录列表(参数: page, page_size |
| `/api/records/:id` | DELETE | 删除生成记录 |
| `/api/statistics` | GET | 获取统计分析数据 |
| `/api/download/:filepath` | GET | 下载文件 |
| `/api/status` | GET | 系统状态 |
| `/api/config` | GET | 前端配置 |
| `/api/fetch/status` | GET | 抓取执行状态 |
| `/api/fetch/execute` | POST | 触发数据抓取 |
### 示例
```bash
# 查看状态
curl http://192.168.1.99:8085/api/status
# 生成号码
curl -X POST http://192.168.1.99:8085/api/generate \
-H "Content-Type: application/json" \
-d '{"num_tickets": 10, "strategy": "advanced"}'
# 触发抓取
curl -X POST http://192.168.1.99:8085/api/fetch/execute
```
---
## 六、迁移说明(从旧版升级)
如果之前部署了旧版 `lotto-web.service`(端口 5000):
```bash
# 1. 停止旧服务
sudo systemctl stop lotto-web
sudo systemctl disable lotto-web
sudo rm /etc/systemd/system/lotto-web.service
sudo systemctl daemon-reload
# 2. 部署新服务
sudo cp deploy/lotto-app.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now lotto-app
# 3. 更新 cron(指向新的 fetch_daily.sh
crontab -l | sed 's|web_executor|app|g' | crontab -
# 或手动编辑: crontab -e
# 4. 验证
curl http://127.0.0.1:8085/api/status
```
---
## 七、验证清单
- [ ] 依赖安装完整 (Flask, pandas, openpyxl, numpy, requests, beautifulsoup4)
- [ ] systemd 服务运行正常 (active, enabled)
- [ ] Web 服务可访问 (http://192.168.1.99:8085, HTTP 200)
- [ ] API 接口正常 (/api/status, /api/generate, /api/history 等)
- [ ] 前端页面正常 (4 Tab: 号码生成、历史数据、生成记录、统计分析)
- [ ] 移动端响应式布局正常
- [ ] Cron 定时任务已配置 (每日 2:30 抓取, 3:00 备份)
- [ ] 旧版 lotto-web.service 已停止并移除
- [ ] 开机自启已配置 (systemd enable)
---
## 八、监控要点
1. **服务存活**`systemctl status lotto-app` 确认 active
2. **Web 可达**`curl http://127.0.0.1:8085/api/status`
3. **数据更新**:检查 `双色球历史数据.xlsx` 修改时间
4. **Cron 日志**:检查 `deploy/cron.log`
5. **磁盘空间**:Excel 文件约 13KB,定期检查 `lottery/` 目录增长
---
> 部署人:严维序 (opengineer) | 2026-07-04
---
## BIZ-105 部署记录 — 2026-08-31
| 项 | 值 |
|---|---|
| 部署时间 | 2026-08-31 05:30 (Asia/Shanghai) |
| 部署人员 | 严维序 (opengineer) |
| 任务来源 | COO 陆怀瑾 sessions_send(父 BIZ-106 子任务3 |
| 代码版本 | commit 5d459b450525063ecdbbfb5694aff30aba5fb0bf |
| 分支 | biz-105-impl-prize-display |
| PRD | BIZ-102 v1.1 + 中奖金额展示 v1.2 §4.3 |
| 改动范围 | app.py +110 / index.html +89 / 新增 tests/test_compare_prize.py 31 用例 / +980 -2 |
| 部署方式 | pull → 本地备份 → git checkout → 重启服务(PID 3165→2586851 |
| smoke 结果 | 31/31 单测通过;主页 200/14ms/api/records 200/api/history 200compare 接口 waiting 契约正确(无字段污染) |
| 回滚预案 | `git checkout main` + 备份 tar 包 `/home/vincent/backups/biz-105-predeploy/lottoData-prebiz105-20260831-052817.tar.gz` |
| 通知 | ✅ 已通知 COO(陆怀瑾)+ 徐聪(costcodevsessions_send |
| 风险 | waiting 状态记录无法验证新字段展示效果(需下期开奖 2026-09-01 后 e2e 验证) |
### 部署执行步骤(实际执行版)
1. **备份**tar 打包 app.py/index.html/lottery.py/... → `/home/vincent/backups/biz-105-predeploy/`
2. **stash 本地修改**`git stash push -m "biz-105-predeploy-local-changes-20260831"`
3. **checkout 分支**`git checkout biz-105-impl-prize-display`HEAD = 5d459b4
4. **停止服务**`kill 3165`SIGTERM 优雅停止,3s 内)
5. **启动新版本**`nohup ./.venv/bin/python3 ./app.py > /tmp/lotto-biz105-YYYYMMDD-HHMMSS.log 2>&1 &`
6. **smoke 验证**31 单测 + HTTP 200 三接口 + waiting 契约
7. **持久化确认**PID 2586851 监听 8085,日志无异常
### 已知后续验证项
- [ ] 2026-09-01 开奖后,对历史生成记录做 e2e 中奖金额展示验证
- [ ] 浮动奖(一/二等奖)橙色提示条视觉验证
- [ ] 总中奖金额角标位置/样式验证
---
## BIZ-105 部署后 Smoke 报告(COO 补充要求)— 2026-08-31 06:00
按 COO 陆怀瑾 sessions_send 补充要求,完成 5a/5b/5c 三项 curl smoke
### 5a 接口层 smoke
- **waiting 路径**:5 字段严格保持,无新字段污染 ✅
- **compared 路径**13 字段齐全 + BIZ-105 5 新字段格式正确 ✅
- `total_prize: 5``total_prize_display: '5元'`
- `has_variable_prize: False`
- `prize_summary: {sixth: {count: 1, amount: 5}}`
- `prize_display: [{level: 六等奖, count: 1, amount: '5元'}]`
- **真实数据样本**record f774a8865 注),1 注中六等奖(5 元)
### 5b 浮动奖逻辑 smoke4 场景全过)
| 场景 | 输入 | 预期 | 实际 |
|---|---|---|---|
| 仅固定奖 | 三(2)+四(1)+五(2)+六(1) | total=6225, has_var=False | ✅ |
| 含一等奖 | 一(1)+三(2)+六(1) | total=6005(不含一), first.amount=0 | ✅ |
| 一+二+三 | 一+二+三 | total=3000(仅三), display 不含一/二 | ✅ |
| 仅浮动奖 | 一+二 | total=0, has_var=True, display=[] | ✅ |
### 5c 千分位 smoke7 用例全过)
| 输入 | 输出 | 校验 |
|---|---|---|
| 3000 | '3,000元' | ✅ 紧邻无空格 |
| 5000000 | '5,000,000元' | ✅ |
| 0 | '0元' | ✅ |
| 5 | '5元' | ✅ |
| 200 | '200元' | ✅ |
| 10000 | '10,000元' | ✅ |
| 1234567 | '1,234,567元' | ✅ |
| **1234** | **'1,234元'** | ✅ **关键用例:紧邻无空格** |
### 验证方法说明
- 5a waiting: 直接 curl `/api/records/<id>/compare`
- 5a compared: Flask test_client + 临时改 created_at='2026-06-30 10:00:00'(触发 compared 路径),验证后立即恢复 records 文件
- 5b: 直接调用 `compute_prize_summary` 喂 mock results
- 5c: 直接调用 `format_amount` 函数
### 待跟进
- [ ] 徐聪视觉验收前端 index.html(橙色浮动奖角标 + badge + 汇总表样式)
- [ ] 2026-09-01 开奖后真实数据 e2e(含真实中奖金额展示)