海棉 4406a689f1 门店检测工作台 v2.3:规则引擎、账号权限、服务器部署 пре 1 недеља
..
backend 4406a689f1 门店检测工作台 v2.3:规则引擎、账号权限、服务器部署 пре 1 недеља
deploy 4406a689f1 门店检测工作台 v2.3:规则引擎、账号权限、服务器部署 пре 1 недеља
frontend 4406a689f1 门店检测工作台 v2.3:规则引擎、账号权限、服务器部署 пре 1 недеља
sync 4406a689f1 门店检测工作台 v2.3:规则引擎、账号权限、服务器部署 пре 1 недеља
tools 4406a689f1 门店检测工作台 v2.3:规则引擎、账号权限、服务器部署 пре 1 недеља
DEPLOY.md 4406a689f1 门店检测工作台 v2.3:规则引擎、账号权限、服务器部署 пре 1 недеља
README.md 4406a689f1 门店检测工作台 v2.3:规则引擎、账号权限、服务器部署 пре 1 недеља
start.sh 4406a689f1 门店检测工作台 v2.3:规则引擎、账号权限、服务器部署 пре 1 недеља
启动工作台.bat 4406a689f1 门店检测工作台 v2.3:规则引擎、账号权限、服务器部署 пре 1 недеља
启动工作台.command 4406a689f1 门店检测工作台 v2.3:规则引擎、账号权限、服务器部署 пре 1 недеља
开放局域网访问.bat 4406a689f1 门店检测工作台 v2.3:规则引擎、账号权限、服务器部署 пре 1 недеља

README.md

门店检测工作台(本地版 · 前后端分离)

怡呵美门店数据检测工作台。每天把门店后台导出的数据丢进来,工作台自动算出 「哪些门店超违规线 / 低于考核基准 / 零核销」,并给出整改建议与反馈文案。

目录结构

store-ops/
├── backend/            后端(Python 标准库,零依赖)
│   ├── server.py       HTTP 服务 + API 路由 + 收件箱自动导入
│   ├── db.py           SQLite 存储与月度聚合
│   ├── ingest.py       数据导入 CSV / Excel(编码自适应 / 表头别名 / 日·月双粒度)
│   ├── xlsx.py         .xlsx 解析(标准库 zipfile+XML,无需 openpyxl)
│   └── rules.py        考核指标默认值 + 检测规则(唯一规则源)
├── frontend/           前端(原生 HTML/CSS/JS + 本地 ECharts)
│   ├── index.html
│   ├── style.css       工作台主样式
│   ├── report.css      单店分析报告样式(A4 打印 + 移动端)
│   ├── app.js
│   └── vendor/echarts.min.js
├── data/
│   ├── app.db          SQLite 数据库(自动生成)
│   ├── inbox/          ★ 收件箱:CSV / Excel 丢进这里,20 秒内自动导入
│   └── processed/      已处理的文件(按时间戳归档)
├── 启动工作台.bat       双击启动(Windows)
├── 启动工作台.command   双击启动(macOS / Linux)
└── 开放局域网访问.bat   放行防火墙(Windows 管理员)

启动

Windows:双击 启动工作台.bat。

macOS / Linux:双击 启动工作台.command(首次若被系统拦下,右键 → 打开)。 或者终端里:

./启动工作台.command              # 默认 8787 端口并自动开浏览器
./启动工作台.command 9000         # 换端口
./启动工作台.command --local      # 只允许本机访问
./启动工作台.command --no-open    # 不自动开浏览器

任何系统都可以直接调后端:

python3 backend/server.py            # 默认监听 0.0.0.0:8787(本机 + 局域网都能访问)
python3 backend/server.py --local    # 只允许本机访问(127.0.0.1)
python3 backend/server.py --port 9000 --open   # 换端口并自动开浏览器

同一局域网的其他电脑 / 手机怎么访问

启动窗口会打印两行地址,把「局域网访问」那一行发给同事即可:

本机访问  : http://127.0.0.1:8787
局域网访问: http://192.168.10.232:8787

前提:两台设备连同一个 WiFi / 同一个路由器,并且本机防火墙放行 8787 端口。

  • 第一次用:双击 开放局域网访问.bat(会弹管理员授权,点「是」),只需做一次,之后一直有效。
  • 仍然打不开时排查:① 本机网络是否被识别为「公用网络」(服务端已按端口放行,不受影响); ② 公司 WiFi 是否开启了「AP 隔离 / 客户端隔离」(开了就无法互访,需找网管); ③ 手机用流量、或连的是另一个网段(如 5G 频段不同路由器)也不行。

⚠️ 该服务没有登录验证,同一内网内任何人打开链接都能看数据和改配置,只在公司办公网络内使用,不要在公共 WiFi(咖啡馆、酒店)上开放。想关闭局域网访问就用 --local 启动。

每天怎么用

  1. 从抖音来客后台导出门店数据(CSV 或 Excel .xlsx,日数据带「日期」列最好)
  2. 工作台左侧【导入数据】选文件导入(支持 .csv / .xlsx);或者直接把文件丢进 data/inbox/,后台自动导入
  3. 打开 http://127.0.0.1:8787 看 KPI、排查门店、点开详情、复制反馈文案给督导

数据口径

  • 核销率 = 核销券数 ÷ 门店页成交券数(分母为 0 时不判定)。2026-11-01 起统一用门店页成交券数,不再用意向成交券数
  • 差评率:新增评价 ≥10 用新增口径;否则累计评价 ≥20 用累计口径; 两者都不足时仍用累计口径判定,但最高只判到「预警线」,不会因一两条差评判成「非常严重」
  • 评分取周期内最近一次有值的数据;评分为 0 = 未开分,文案单独显示「未开分」,仍计入评分不达标的 KPI
  • 评价回复率:只在有新增评价时判定(没有新评价就没有回复义务)
  • 「待核销」是估算值(门店页成交券数 − 核销券数,未扣退款),只能作邀约优先级参考,不是后台真实未核销订单数
  • 同一文件内门店+日期重复的行只保留首行(其余跳过并提示)
  • 重复导入同门店同日期会覆盖,不会翻倍
  • 同一月份同时有日数据和月汇总时:日数据覆盖 ≥15 天才按日聚合,否则用月汇总

账号与权限

打开工作台需要登录。首次启动会自动创建管理员账号:

账号 初始密码
admin admin123

登录后会强制要求修改密码,改完才能正常使用。

三级角色

角色 查看 导出 导入 同步 改阈值/文案 账号管理
管理员 admin ✅ ✅ ✅ ✅ ✅ ✅
运营 editor ✅ ✅ ✅ ✅ ❌ ❌
查看 viewer ✅ ❌ ❌ ❌ ❌ ❌
  • 左侧栏【账号管理】可以新建账号、改角色、停用、重置密码、删除
  • 权限在前端隐藏入口,后端接口也会校验,直接调接口同样会被拒绝(403)
  • 会话有效期 30 天,Cookie 为 HttpOnly;密码用 PBKDF2-SHA256(12 万次迭代)加盐存储
  • 改密码或重置密码后,该账号的已有会话会失效

忘记密码怎么办

用另一个管理员账号重置。如果所有管理员都进不去:

cd store-ops
python3 - <<'EOF'
import sys; sys.path.insert(0, 'backend')
import db, auth
db.set_password(1, 'newpass123', must_change=1)
print('admin 密码已重置为 newpass123')
EOF

导出

导出入口统一在左侧栏【导入数据】面板里:

  • 下载当前周期最新一份 = 当前周期最近一次导入的原始文件
  • 每条历史记录右侧的【原始文件】 = 那一次导入的原件(同一周期导过多次时用来区分)

导出的都是生意经给的 xlsx 原件,40 列,不含任何计算。

  • 原始文件存放在 data/processed/,批次表用 file_path 记住对应关系
  • 早期从 Windows 迁过来的 CSV 批次没有留存原件,按钮置灰
  • 想按筛选条件导出一张表(含核销率等计算列),可以用 /api/export.csv

近30天数据自动同步

分析口径是近30天滚动窗口(今天往前 29 天到今天),不是自然月。数据每天自动从生意经拉取。

自动跑

  • 服务启动后内置调度:每天 01:00 自动同步
  • 启动补跑:距上次成功超过 20 小时,服务启动 90 秒后自动补一次
  • 服务窗口会打印「下次自动同步:2026-11-02 01:00」

手动跑

  • 工作台左侧 【同步数据】 按钮
  • 或 curl -X POST http://127.0.0.1:8787/api/sync
  • 查状态:GET /api/sync/status

它做了什么

  1. 用 ego 浏览器打开生意经(复用登录态)
  2. 调接口建「近30天、全部门店、41 个指标、按统计周期聚合」的导出任务
  3. 轮询约 3.5 分钟拿到签名下载地址
  4. 下载 xlsx 到 data/inbox/门店数据_<起>_<止>.xlsx
  5. 收件箱 20 秒内自动导入,文件名里的日期区间决定快照窗口

存成什么样

快照写入 metrics,granularity='snapshot',period 记「截至日」, window_start / window_end 记统计区间。周期下拉显示「近30天 · 截至 11-01」。 月汇总数据与快照共存,互不覆盖。

依赖与限制

  • 需要 ego 浏览器且生意经已登录(登录态通常几周过期,过期后需在 ego 里重新登录一次)
  • 同步期间会弹一下浏览器窗口,约 3-5 分钟
  • 生意经建任务有每日次数上限(一般在 30 次左右),脚本会先查剩余次数
  • 为什么不用 launchd:macOS 的 TCC 保护 ~/Documents,系统级定时任务读不到这个目录里的文件 (实测 head 都被拒)。所以定时器放在服务进程里,服务从终端启动时是有的权限。 sync/com.yhm.lifesync.plist 保留作参考,若要启用需在「系统设置 → 隐私与安全性 → 完全磁盘访问」 里把 /bin/bash 加进去。

诊断逻辑(v2)

规则唯一源是 backend/rules.py,设计依据见 项目记录/规则设计_v2_思维导图.html。

  • 4 层并行:流量 / 转化 / 履约 / 口碑各自独立判定、互不压制(共 17 条规则); 只有履约层内部「成交未核销 → 核销率低」按根因去重
  • 5 档:R 违规红线 / B 考核未达标 / T 运营提升 / N 样本不足
  • 核销链内部去重:零成交 > 成交未核销 > 核销率低,只报最上游一条
  • 核销金额独立判定:只要金额 < 基准就报,不受核销率约束(2026-11-01 定)
  • 诊断树选主因:按层级顺序取第一个命中,只用于生成「一句话结论」,不影响问题清单
  • 问题全列、每条给动作:命中几个问题就列几个,每个问题对应一条整改动作,不做截断
  • 每家门店输出:一句话结论 + 全部命中问题 + 对应整改动作

考核指标(可自定义)

默认值来自飞书《门店考核指标》官方基准线。左侧【指标配置】面板可改, 改完点【应用到工作台】即可生效。

改面板 = 直接改代码

改完不只是存库,还会同步写回 backend/rules.py 的 DEFAULT_THRESHOLDS, 所以不会出现「界面上是 10、代码里还是 30」这种两套数字打架:

场景 结果
面板改完保存 立即生效 + 写回代码默认值 + 重新加载
复制整个文件夹到别的电脑 改过的值跟着走
【恢复默认】 回到出厂值(首次运行时快照在 data/factory_thresholds.json),并同样写回代码
面板右上角标签 显示「出厂值」或「已自定义」(对照出厂值判断)

写回时只替换阈值数值,保留键名、缩进和行尾注释;写入前会生成 rules.py.bak 备份, 写入后清字节码缓存并重新加载模块。

注意:因为会改源码,如果这个目录放在 git 里,改阈值会产生一次文件变更。

除了官方基准线,面板里还能调这几条 v2 新增的判定门槛:

参数 默认 作用
访问过低线 100 次 低于此值判「访问过低」
成交转化率过低线 10% 成交人数 ÷ 访问 低于此值 → 「转化率低」
视频数下限 10 条 新发布视频少于此数 → 「视频量少」
点亮数下限 10 次 门店点亮少于此数 → 「点亮偏低」
新增评价数下限 10 条 新增评价少于此数 → 「新增评价少」
未核销积压提醒线 30 张 估算未核销券达到此数 → 提示集中邀约
核销率最小成交券数 5 张 成交券太少时核销率不稳定,不判定
客单价最小核销券数 5 张 核销券太少时不算客单价
差评率最小样本(新增/累计) 10 / 20 条 样本不足最高只判预警线
回复率最小新增评价数 1 条 没有新评价就不判回复率

API 一览(给后续自动化用)

方法 路径 说明
GET /api/meta 周期列表、阈值、导入历史、统计
GET /api/dashboard?period=2026-10 工作台全量数据
PUT /api/thresholds 保存自定义阈值
POST /api/thresholds/reset 恢复官方默认
POST /api/import?filename=&period=&date= 导入 CSV / Excel(body=文件字节)
GET /api/export.file?period= 导出原始文件(该周期最近一次导入的 xlsx/csv 原件)
GET /api/batch/<id>/file 导出指定批次的原始文件
GET /api/export.csv?period=&kpi=&city=&cat=&q= 筛选结果导出为 CSV(含核销率/待核销等计算列)
GET /api/history 导入批次

深链接

  • /#TH 直达考核指标面板
  • /#IM 直达导入面板
  • /#<门店ID> 直达该店详情抽屉

单店分析报告

点开任一门店的详情抽屉,底部两个按钮:

  • 【预览分析结果】 —— 按文案模板生成的反馈短文,可改完直接复制发给督导
  • 【导出报告】 —— 生成一页 A4 的门店检测分析报告

报告包含五段:关键指标(带基准/目标刻度的指标条)→ 风险与限流因素(问题 + 建议动作)→ 经营数据(客资 / 核销 / 退单 / 待核销 / 访问 / 成交 / 流失)→ 分析洞察 → 门店调整动作。

报告顶部有两个操作:

按钮 得到什么
打印 / 另存为 PDF 走系统打印对话框,目标选「另存为 PDF」即得 PDF 文件(macOS 选「存储为 PDF」)
下载 HTML 下载一个自包含的单文件 HTML(样式内联,不依赖服务),可直接发微信或存档
  • 报告内容全部来自当前【文案配置】的模板,改了文案报告跟着变,不用改代码
  • 手机宽度(375px)下报告自动改为单列排版,督导可以直接在手机上看
  • 报告里不出现「同城竞对」数据——那部分属于「对标试点」轨道 B,目前未接入本工作台

后续可做

  • 自动下载:接抖音来客/服务商 API 定时拉数,替代手动导出
  • 处理闭环:异常门店的整改动作记录与回填
  • 权限分层:区域经理/督导只看自己片区
  • 报告批量导出:按城市/督导一次导出多店 PDF

文案配置

左侧菜单【文案配置】可自定义门店分析反馈文案:反馈文案结构、问题文案、整改建议、严重档位名称。大括号变量生成时自动替换({门店名} {周期} {访问} {金额} {评分} {v} {base} {口径} {档} 等),未知变量原样保留。修改存库、立即对全部门店生效,【恢复默认】可一键还原。

每个字段右侧有「+ 变量」按钮,点开可点选变量直接插入,避免手写变量名出错。写错的变量会标红并在预览区顶部提示,不会静默原样输出。

反馈文案可用变量

短名 含义 等价的数据表列名(别名,可直接写)
{客资} 门店意向成交券数 {门店意向成交券数}
{核销} 核销券数
{核销券数} 核销券数 {门店核销券数}
{成交券数} 意向成交券数
{退单} 门店意向退款券数 {门店意向退款券数} {退款券数}
{访问} 门店页访问次数 {门店页访问次数} {门店页有效人数} {访问次数}
{成交} 实际成交人数 {门店实际成交人数} {成交人数}
{流失} 访问-成交 {流失人数}
{成交占比} {流失占比} 占访问比例 {流失人数占比}
{待核销} 成交券-核销券 {待核销订单数} {后台待核销订单}
{金额} 核销金额(元) {核销金额}
{评分} 团购评分 {门店评分} {团购评分}
{评分基准} {核销率} {核销目标} {回复率} {回复基准} {核销金额基准} 指标与基准值 {评价回复率} {核销率基准}
{门店名} {门店ID} {城市} {周期} 门店与周期 {门店名称} {门店城市} {统计周期}

问题文案另可用:{v} 实际值、{base} 基准值、{口径} 新增/累计、{档} 档位名;条目格式可用 {i} 序号、{问题}/{建议}/{洞察} 内容。