喜报处理 Web
按 config/xibao_logic.json 解析接龙文本,批量生成喜报图片并下载。
项目情况(2026-02-24)
- 线上域名:按部署自行配置
- Nginx 转发:
<your-domain> -> 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,无本机环境时回退 Dockerminidocks/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: 历史遗留文件,不参与线上页面加载
启动与运维
本地直接启动
cd /opt/xibao-web/app
/opt/xibao-web/venv/bin/python server.py --host 127.0.0.1 --port 8787
可选参数:
--prewarm-blocking: 启动前阻塞预热镜像(确保服务起来后镜像一定可用)--skip-prewarm: 跳过启动时预热
开发检查(推荐)
cd /opt/xibao-web/app
# 1) 语法/静态检查
make lint
# 2) 单元测试
make test
# 3) 接口烟雾回归(默认本机 127.0.0.1:8787)
make smoke
# 一键全跑
make check
前端工具脚本:
# 同步本地 Vue 运行时到 static/vendor
npm run sync:vue
systemd(线上)
systemctl status xibao-web.service
systemctl restart xibao-web.service
journalctl -u xibao-web.service -n 200 --no-pager
Nginx(线上)
cat /etc/nginx/sites-available/<your-site>.conf
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/parsePOST /api/generate
- 将结果回发微信:
- 文本:
/message/SendTextMessage - 图片:
/message/SendImageNewMessage
- 文本:
快速启动
cd /opt/xibao-web/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 http://127.0.0.1:8787
可选参数:
--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自动清空输出图片与历史记录(不会清空反馈记录)。
常用排查命令
# 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 示例
{
"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 小时过期。