Files
xb/app/README.md

295 lines
12 KiB
Markdown
Raw 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.
# 喜报处理 Web
`config/xibao_logic.json` 解析接龙文本,批量生成喜报图片并下载。
## 项目情况2026-02-24
- 线上域名:`https://zc.workyai.cn`
- Nginx 转发:`zc.workyai.cn -> 127.0.0.1:8787`
- 运行服务:`xibao-web.service`
- 代码目录:`/opt/xibao-web/app`
- Python 环境:`/opt/xibao-web/venv`
## 当前能力
- 根据 `#接龙` 文本逐行解析。
- 支持一条文本拆分多个产品(如同一行里的定期 + 理财)。
- 支持别名映射(如 `中心所 -> 潇水南路``营江路所 -> 营江路`)。
- 只保留 13 个白名单网点,不在名单内自动跳过。
- 保险默认期交(`page_3`),若未写明年限会要求选择 `3年交 / 5年交`
- 仅“微信提现12万”这类未写明确期限的记录按活期场景处理默认不生成。
- 金额识别支持阿拉伯数字和常见中文写法。
- 中文金额口语兼容:`十万``两万五``一万二``两万五千``二点五万`
- 金额统一按现有规则向下取整到 `N万`(例如 `2.5万 -> 2万``7.8万 -> 7万`)。
- 去重策略:有序号时优先按“序号+行内产品序位+行内容指纹”去重;无序号时回退 `branch+amount+type`(历史去重 + 本次输入去重)。
- 每条数据生成独立 PPT并按其 `page_x` 只导出对应页 PNG。
- 多张 PNG 前端逐图下载(无需解压)。
- 每天 00:00 自动清理 `output/` 下历史截图任务。
- 支持手工强制清理截图(与 00:00 自动清理同逻辑)。
- 支持复盘日志(手工标记识别错/生成错、自动记录解析跳过与异常)。
- 标记识别错/生成错时支持填写备注(前端弹窗输入)。
- 支持“已标识错误”列表查看、编辑、删除。
- 手动“修正并生成”成功后,会自动清除同原始行的活跃标识(转为已解决)。
- 重复记录支持直接预览与下载(若历史图片仍存在)。
- 生成时可查看实时进度解析、生成PPT、转PDF、导图、收尾
- 刷新页面后可查看历史记录并继续标注(支持历史图预览/下载)。
- 生成阶段支持低配模式:默认单任务单并发(同一时刻只允许一个生成任务)。
- 生成策略支持“页面模板缓存”(默认):多条生成时先按 `page_x` 预构建单页模板,单线程落盘以降低峰值内存。
- 生成完成后启用内存回收(`gc.collect + malloc_trim`,可配置开关)。
- 字体保护不变:仍按 run 级别替换文本,仅改数字/状态/网点目标 run不改字体样式与字号。
- 预览图按顺序逐张加载(前面的先加载),避免大批量并发请求导致预览异常。
- 图片下载接口支持限速(默认 `300KB/s`),可在 `performance.image_delivery.max_kbps` 调整。
- 跳过明细支持“屏蔽”单条(屏蔽后不再展示,清空历史时一并清空屏蔽)。
## 最近修复
- 修复“识别正确但生成网点变成潇水南路”的问题。
- 原因是模板不同页面的网点文本框索引不一致,旧逻辑固定 `shape_index=3`
- 现逻辑会优先定位包含“营业所”的文本段再替换,避免错位替换。
- 修复中文金额 `amount_not_found`(例如 `蚣坝揽收十万现金定期一年`)。
- 新增中文金额解析后,补充了兼容保护,避免把单独“万/亿”误识别成 `0万`
- 状态识别增强:支持“关键词中间夹金额/文本”的句式(如 `揽收十万现金``揽收16万礼金``微信17万提现``商户20万提现``揽收20万商户`)。
- 理财页文案调整为 `两三年期理财`,并在生成时对标题文本关闭自动换行,避免多字后折行。
## 技术实现
- PPT 文本替换:`python-pptx`
- PPT 转 PDF、PDF 按页转 PNG优先本机 `libreoffice + pdftoppm`,无本机环境时回退 Docker `minidocks/libreoffice`
- 生成链路:`解析 -> 页面模板缓存(可配置) -> 生成PPT(默认单线程) -> 批量转PDF -> PDF导图(默认单线程)`
- 前端迁移策略:主页面已直接接入 Vue`static/js/main.js`),不再依赖 legacy 保底脚本。
- Vue 运行时采用本地静态文件:`static/vendor/vue.global.prod.js`(由 `npm run sync:vue` 同步)。
默认会在启动时后台预热转换镜像;若已完成部署初始化,首次生成通常不会再等待拉取镜像。
## 目录
- `server.py`: 后端(标准库 HTTP API + 生成逻辑)
- `api_get_routes.py`: GET 接口路由分发(从 `server.py` 抽离)
- `api_post_routes.py`: POST 接口路由分发(从 `server.py` 抽离)
- `services/workflows.py`: 解析/生成/修正业务流程服务层
- `services/post_ops.py`: 标识/历史/清理等通用 POST 业务服务层
- `repositories/history_repository.py`: 历史读写仓储层
- `static/index.html`: 前端页面
- `static/app.js`: 前端加载入口(仅负责加载脚本)
- `static/js/core/state.js`: 前端共享状态与常量
- `static/js/main.js`: 主前端脚本Vue + 业务逻辑)
- `static/vendor/vue.global.prod.js`: 本地 Vue 运行时
- `static/styles.css`: 页面样式
- `config/xibao_logic.json`: 处理规则配置
- `data/generated_history.json`: 去重历史
- `data/manual_rules.json`: 手工规则
- `data/review_logs/review_YYYY-MM-DD.jsonl`: 当日复盘日志
- `output/`: 生成输出目录(每次任务图片)
- `tests/`: 自动化单元测试
- `scripts/smoke_api.sh`: 接口烟雾测试脚本
- `package.json`: 前端工具脚本(`lint/test/smoke/sync:vue`
- `Makefile`: 一键检查入口(`make check`
- `app.js`: 历史遗留文件,不参与线上页面加载
## 启动与运维
### 本地直接启动
```bash
cd /opt/xibao-web/app
/opt/xibao-web/venv/bin/python server.py --host 127.0.0.1 --port 8787
```
可选参数:
- `--prewarm-blocking`: 启动前阻塞预热镜像(确保服务起来后镜像一定可用)
- `--skip-prewarm`: 跳过启动时预热
### 开发检查(推荐)
```bash
cd /opt/xibao-web/app
# 1) 语法/静态检查
make lint
# 2) 单元测试
make test
# 3) 线上接口烟雾回归(默认 zc.workyai.cn
make smoke
# 一键全跑
make check
```
前端工具脚本:
```bash
# 同步本地 Vue 运行时到 static/vendor
npm run sync:vue
```
### systemd线上
```bash
systemctl status xibao-web.service
systemctl restart xibao-web.service
journalctl -u xibao-web.service -n 200 --no-pager
```
### Nginx线上
```bash
cat /etc/nginx/sites-available/zc.workyai.cn
nginx -t
systemctl reload nginx
```
## API核心
- `GET /api/config`: 获取配置摘要
- `POST /api/parse`: 仅解析预览
- `POST /api/generate`: 解析 + 生成 + 返回图片下载地址
- `GET /api/download/{token}`: 下载单张图片
- `GET /api/progress/{token}`: 查询本次生成进度
- `POST /api/output/clear`: 强制清理输出目录截图/任务文件
- `GET /api/history/view?limit=500`: 获取可预览/下载的历史记录视图
- `POST /api/log/mark`: 标记识别错误/生成错误到复盘日志(支持 `note` 备注)
- `GET /api/issues?status=active|resolved|all&limit=500`: 查看标识列表
- `POST /api/issues/update`: 修改标识(类型/原始行/备注)
- `POST /api/issues/delete`: 删除标识
- `GET /api/log/today`: 查看今日日志
- `POST /api/history/clear`: 清空历史
## 微信机器人接入(新增)
项目内置桥接脚本:`wechat_bot_bridge.py`,用于把微信消息接入到本项目:
- 拉取微信新消息:`/message/HttpSyncMsg`
- 识别指令后调用:
- `POST /api/parse`
- `POST /api/generate`
- 将结果回发微信:
- 文本:`/message/SendTextMessage`
- 图片:`/message/SendImageNewMessage`
### 快速启动
```bash
cd /root/zc.workyai.cn/app
python3 wechat_bot_bridge.py \
--wechat-base-url http://127.0.0.1:18238 \
--wechat-session-file /root/WeChatPadPro_test_20260227/webui/.session.json \
--xibao-base-url https://zc.workyai.cn
```
可选参数:
- `--wechat-auth-key`:直接指定 authKey不走 session 文件)
- `--allow-from wxid_a,wxid_b`:仅处理白名单发送者
- `--max-images 3`:每次最多回发几张图
- `--dry-run`:只打印,不实际回消息
- `--once`:只轮询一次(调试用)
### 微信指令
- `/喜报 帮助`
- `/喜报 解析 + 文本`
- `/喜报 生成 + 文本`
- `跳过N`(例如 `跳过3` / `跳过(3)`,当天自动跳过前 N 条序号内容)
- `跳过0`(取消当天自动跳过)
- `反馈+序号+说明`(记录到复盘/问题列表)
- 直接发送包含 `#接龙` 的文本也会触发生成
说明:
- 仅处理私聊文本消息(不处理群聊)。
- 跳过/屏蔽项不单独发送通知,识别与过滤完全使用本项目现有逻辑。
- 每日按 `--daily-cleanup-time` 自动清空输出图片与历史记录(不会清空反馈记录)。
## 常用排查命令
```bash
# 1) 服务是否存活
systemctl status xibao-web.service
ss -lntp | rg ':8787'
# 2) 配置是否正常
curl -sS http://127.0.0.1:8787/api/config
# 3) 单条解析复现
curl -sS -X POST http://127.0.0.1:8787/api/parse \
-H 'Content-Type: application/json' \
--data '{"raw_text":"2、 蚣坝揽收十万现金定期一年"}'
# 4) 查看复盘日志(识别错/生成错/skip/异常)
tail -n 200 /opt/xibao-web/app/data/review_logs/review_$(date +%F).jsonl
# 5) 查看活跃标识
curl -sS 'http://127.0.0.1:8787/api/issues?status=active&limit=200'
# 6) 查看手工规则(是否有误命中)
cat /opt/xibao-web/app/data/manual_rules.json
# 7) 查看历史去重(为什么没新生成)
cat /opt/xibao-web/app/data/generated_history.json
```
## 故障排除指南
### 问题 1识别正确但图片里网点不对例如固定变成“潇水南路”
- 先确认 `api/parse` 输出的 `branch` 是否正确。
- 若解析正确但图错,重点检查模板页网点文本是否包含“营业所”字样。
- 当前替换逻辑按“营业所”文本段定位;模板若不含该标记,可能回退到配置索引。
- 模板调整后建议先用一条数据做小流量验证。
### 问题 2`amount_not_found`
- 先用 `api/parse` 复现并看 `skipped` 原因。
- 已支持常见中文金额:`十万``两万五``一万二``二点五万`
- 若仍失败,先看原文是否存在金额信息,再检查是否被特殊格式拆断。
### 问题 3点“生成”后没有新图
- 查看返回里的 `duplicate_records``summary.duplicate`
- 常见原因是去重命中(有序号时按序号键,无序号时按 `branch+amount+type`)。
- 需要重生成可清历史后再生成:`POST /api/history/clear`
### 问题 4日志里出现 `demand_deposit_not_generate`
- 这是预期策略:只出现活期类关键词且未写明确期限时默认不生成。
- 解决方式是补上产品期限或类型例如“存一年”“理财”“保险5年交”
### 问题 5转换失败Docker 镜像拉取/转换异常)
- 先执行 `docker info` 确认 Docker 可用。
- 执行 `docker pull minidocks/libreoffice` 预热镜像。
- 查看服务日志:`journalctl -u xibao-web.service -n 300 --no-pager`
### 问题 6需要回溯某次“识别错/生成错”
- 进入 `data/review_logs/review_YYYY-MM-DD.jsonl``manual_mark`
- 字段 `mark_type` 区分识别错/生成错,`source_line` 是原句,`note` 是备注。
- 结合同文件内的 `parse_skip``manual_correction_apply` 可还原完整过程。
### 问题 7标识想改备注或删掉
- 页面“已标识错误”面板可直接编辑或删除。
- 或调用接口:
- `POST /api/issues/update`(按 `id` 修改)
- `POST /api/issues/delete`(按 `id` 删除)
## /api/generate 示例
```json
{
"raw_text": "#接龙\n1、营江路张三30万存一年\n2、潇水南路保险2万",
"insurance_year": "5",
"template_file": "/opt/xibao-web/templates/黄金三十天喜报模版(余额、保险、理财)(1).pptx",
"output_dir": "/opt/xibao-web/app/output",
"save_history": true
}
```
## 注意
- 需要本机 Docker 可用(`docker info` 正常)。
- 当前下载 token 默认 1 小时过期。