# 智慧运营中台(淘宝闪购专业版) 智慧运营中台是一个本地 Web 应用,集「门店采集」「AI 视觉生成」「数据采集与智能分析」于一体:采集门店菜品并批量生成品牌视觉资产,同时从淘宝闪购商家客户端取数沉淀本地,形成可持续加工的经营数据中台。 ## 功能概览 ### 门店采集 - 通过淘宝闪购后台 Cookie 按店铺批量读取菜品图片和名称。 - 支持手动维护店铺清单、勾选店铺、开始/停止采集。 - 默认跳过已完成的店铺,可开启“强制全量抓取”重新下载。 - 提供进度列表、任务日志和系统日志,便于定位 Cookie 过期、下载失败等问题。 ### 视觉生成 - 自动扫描输出根目录下的门店,支持“全量扫描”或指定门店扫描。 - 按步骤生成 LOGO、海报、招牌、贴纸等门店视觉资产。 - 支持菜品商品图批量生成,可叠加门店 LOGO,并按菜品维护自定义提示词。 - 生成结果会下载到门店目录,同时保留 API 返回的远程地址。 ### 历史创作 - 以图片墙展示历史作品,默认一行 8 个。 - 支持悬浮放大预览和悬浮下载。 - 重复生成会追加记录;历史列表读取并保留最近 48 小时内的记录。 ### 数据采集与智能分析 淘宝闪购经营数据中台:从本机商家客户端取数、沉淀本地、多维报表。 - **取数通道**:附着本机淘宝闪购商家客户端调试端口(默认 `9669`),由客户端页面自身的登录态代发请求(非爬虫),数据中心接口自动补签名。首次使用需以 `--remote-debugging-port=9669` 启动商家客户端并登录。 - **多主体**:每登录一个商家账号并同步一次即形成一个主体 tab,可在多个主体之间切换查看;主体内支持全公司 / 连锁 / 单店三种粒度。 - **数据沉淀**:同步结果按「日期 × 门店」写入本地数据湖 `data/reports/`,反复同步自动去重合并,可用于二次加工。 - **BI 展示**:KPI 卡片 + 明细 / 按门店 / 按日期三种视图,列可自定义显示(列设置),支持排序、门店筛选、名称搜索与 CSV 导出。 - **趋势图表**(独立菜单):环比指标条(7 项指标 vs 上期 ±%)、主指标趋势(可叠加上期虚线对比)、门店排行 Top10、转化漏斗(曝光→进店→下单)、门店对比 Top5 折线;一键导出自包含 HTML 经营周报。 - **智能问数机器人**:仅经营分析相关页面显示的右下角悬浮助手,弹窗对话、支持上下文追问(如先问"上月营业额Top5门店"再问"那二店的单量呢"),回答可附图表并一键应用到数据采集报表。需在「系统设置 → API 设置 → 对话模型」选择对话模型(未保存时默认 deepseek-v4.1-flash,Key 留空复用生图 API Key)。 - **钉钉 AI 表格同步(三表单粒度)**:把数据湖增量推送到钉钉 AI 表格(在线主档案/共享层),云端按维度拆三张表——门店明细 / 连锁汇总 / 公司汇总,每张表内粒度唯一,钉钉 AI 问数或人工透视都不会跨维度把数字加翻倍;区间汇总行不上云(可由门店行推导)。其他电脑在「数据中台」页执行「云端拉取」即可补全本地数据(新账号自动注册主体),报表/图表/问数照常使用。需钉钉企业内部应用(开通 AI 表格 API 权限),配置 AppKey/AppSecret/Base ID/三张表名(留空用默认名)。定时自动同步完成后也会自动推送云端。 - **同步记录诊断**:每次同步的步骤记录会携带请求参数与返回概况(行数/非零行/订单与营业额合计),门店粒度返回全零时自动标记「⚠全零」,便于远程排查。 - **取数诊断脚本**:在装有商家客户端的电脑上运行 `node scripts/diagnose-napos.js [日期] [门店ID]`,对门店维度取数做参数对照实验并生成 JSON 诊断报告,拷回开发机即可定位取数异常。 - **MCP 工具**:`node reports-mcp.js` 启动 stdio MCP server(reports_list_entities / reports_summary / reports_query),注册到 `~/.workbuddy/mcp.json` 即可供 Agent 直接查数,与 napos-mcp(取数)形成闭环。 - **定时自动同步**:在「同步数据」弹窗开启后,每天到达设定时间(默认 06:00)且商家客户端在线时,自动把昨日经营数据补进本地数据湖(客户端离线则当天在线后补跑);默认关闭。同步记录照常进入同步记录列表。 - **任务中心**:生成任务与门店采集任务统一展示,采集任务显示各门店完成进度,服务重启后被中断的采集会标记「已中断」。 - **智能问数对话记忆**:问数对话按数据主体保存在浏览器本地,刷新或重开页面后可继续追问,「清空对话」同时清除本地记录。 - **字段**:日期、门店名称、有效订单、收入、营业额、曝光人数、下单人数、进店转化率、下单转化率、客单价、支出、活动订单、活动补贴等;「营业时长 / 异常关店时长 / 商品销售额」为预留列,待后续数据源接入后自动回填。 ### 店铺运营数据导入 采集之外的另一条数据入口:直接上传商家后台导出的人工统计表,不依赖商家客户端。 - **支持格式**(自动识别,两种可混着传): - **人工统计横表**:`学校名称 / 店铺名称 / ID / 上线状态` + 每天 4 列(订单量 / 营收 / 曝光量 / 进店转换率),日期列写成 `9.9订单量`,年份在上传时选。 - **平台导出全字段明细**:一行一店一天,含 `日期 / 门店编号 / 门店名称` 与 100+ 列指标(营业额、有效订单、曝光、评分等),全部原样入库。 - **重复校验**:平台明细按「日期 + 门店编号」判断——同一天同一店的相同数据自动跳过;内容有变化记为「冲突」不覆盖,勾选「覆盖已导入的文件」才覆盖。上传结果会显示「新增 N / 已存在 N / 冲突 N」。 - **报表展示**:一张表、一行一店一天,列 = 店铺 / 日期 / 勾选的指标(勾几个显示几列),按学校分组并带每日小计。平台明细同样进入「店铺运营」报表——有效订单→订单量、营业额→营收、曝光人数→曝光量、进店转化率→进店转化率;同一天同一店两种来源都有时,以人工表为准(人工优先、平台补位)。 - **经营驾驶舱**:一屏看经营大盘——6 个 KPI(营业额 / 有效订单 / 客单价 / 曝光人数 / 进店转化率 / 店铺评分,带环比)+ 营业额与订单趋势、门店营业额 Top10、转化漏斗(曝光→进店→下单)、收入结构(收入/支出/补贴)。支持日期、学校、店铺筛选,环比按「紧邻的等长区间」计算;下方「零单诊断」用平台字段区分未开业 / 当日闭店 / 无曝光 / 无进店 / 无转化。 - **报告中心**:报告页可「保存报告」,历史列表显示保存时间、区间、学校、店铺范围与来源(AI/规则),支持查看、下载 PDF(浏览器打印)、下载 JSON 与删除;保存的是完整 Report JSON 快照(含 AI 文字与当时数值),数据后续变化不影响已保存版本。 - **解读与报告同源**:驾驶舱的「经营解读」是经营报告 JSON 的摘要视图(同一份生成结果、同一缓存),卡片上可一键跳到同区间的完整报告;报告页「重新生成」会调用 AI 补齐文字,模型不可用时自动退回规则版并标注。 - **AI 经营解读**:点「生成解读」,把当前范围的 KPI、趋势、门店增减、漏斗与成本结构整理成上下文交给对话模型,输出 3~5 条结论与建议(引用具体数字);结果缓存 10 分钟,可复制。未配置对话模型时会明确提示去「系统设置 → API 设置」配置。 - **经营报告**:按统一 Report JSON 渲染,图表可交互(悬浮提示),支持日期/学校/店铺筛选、重新生成、浏览器打印导出 PDF(A4 打印样式已适配)。报告含管理层摘要(带证据)、核心指标、经营/门店/流量/费用四节图表、风险与行动计划、数据质量与方法论。 - **字段与店铺筛选**:字段下拉可勾选平台导出里的任意列(默认 4 个基础指标),勾几个就显示几列;店铺下拉可多选门店,只看选中的店;选择保存在浏览器本地。 - **学校归属**:平台表里没有学校列时,优先用上传时选的学校,其次从文件名识别(如「浙江工商桐庐校区20261018…」匹配到已登记学校);都匹配不到会要求先选学校。 - **原件存档**:每次上传的 xlsx 原样入库,可在「导入记录」里下载回;解析规则升级后可「重新解析」而不必重传。 - **指标矩阵**:行=店铺(按学校分组)、列=日期,可按指标分区块查看;也支持卡片视图(区间合计 + 迷你趋势)。学校、日期、指标都可筛选,支持导出 CSV。 - **脏数据容错**:`10..6%`、`12.3`(应为 12.3%)、`未开放`、空白等都会按规则清洗并带标记(表格里显示 ⚠,悬停看原始值),不会因为一格填错整批失败。 - **存储**:默认本地 SQLite(`data/ops.db`),不引入额外依赖。改 `config.json` 的 `storage.driver` 为 `postgres` 即可切到云端库(需 `npm i pg`、填连接串、`npm run db:init` 建表,`db:export` / `db:import` 搬迁数据)。 - **降级**:数据库不可用时只有本菜单提示不可用,采集、生成、问数等其它功能照常。 ## 环境要求 - Node.js 18 或更高版本。 - **店铺运营数据导入需要 Node.js 22.5 或更高版本**(依赖内置 `node:sqlite`);低版本时该菜单提示不可用,其余功能不受影响。 - 可访问图片生成服务的 API Key。 - 如需采集功能,需要具备淘宝闪购后台访问权限的有效 Cookie(必须包含 `ksid`)。 ## 快速开始 1. 安装依赖: ```bash npm install ``` 2. 创建本地配置: ```bash cp config.example.json config.json ``` 3. 编辑 `config.json`,至少填写 `apiKey`。也可以启动后在“系统设置”中填写。 4. 启动服务: ```bash npm start ``` 或使用平台脚本: - macOS:双击 `启动.command`,或执行 `./启动.command` - Windows:双击 `启动.bat` - Linux/macOS:执行 `./启动.sh` 5. 打开 `http://localhost:5177`。若修改了 `port`,请访问对应端口。 ## 系统设置 | 配置 | 说明 | | --- | --- | | `apiKey` | 图片生成服务密钥。界面中会脱敏显示,重新输入新值即可更新。 | | `apiBase` | 图片生成服务地址。当前固定为 `https://api.lk888.ai`,界面中不可修改。 | | `model` | 默认生成模型,例如 `gpt-image-2`。可在系统设置中切换。 | | `rootDir` | 门店数据与生成结果的输出根目录。默认使用项目上一级的 `workspace` 目录。 | | `pageSize` | 门店采集时每一页请求的菜品数量,范围 `1-200`。 | | `delayMs` | 采集下载间隔,范围 `0-60000` 毫秒。 | | `maxConcurrentJobs` | 同时进行的生成任务数量。 | | `requestTimeoutMs` | 生成服务请求超时时间,单位毫秒。 | | Cookie | 用于淘宝闪购后台采集,仅保存在本地 `session.json`。 | | `accessToken` | 局域网访问口令:设置后其他电脑访问本服务需输入口令(本机 127.0.0.1 不受影响)。留空保持不变,输入 `-` 清除。也可用环境变量 `ACCESS_TOKEN` 临时开关(不落盘)。 | | `autoSync` | 每日自动同步:`{ "enabled": true, "time": "06:00" }`,也可在「同步数据」弹窗里开关。 | | `aitable` | 钉钉 AI 表格同步:`{ "enabled": true, "appKey": "...", "appSecret": "...", "baseId": "...", "sheetDetail": "门店明细", "sheetChain": "连锁汇总", "sheetCompany": "公司汇总" }`,三张表名留空用默认值;也可在「系统设置 → 钉钉 AI 表格」配置。问数落地钉钉的实测问题清单见 `docs/钉钉问数上线指引.md`。 | `httpLog` | `true` 时在控制台打印每个 HTTP 请求(5xx 与超过 1 秒的慢请求始终打印)。 | API Key 获取与充值入口可在“系统设置 → API 设置”中打开。 ## 输出目录结构 默认输出根目录为: ```text <项目上一级>/workspace ``` 单个门店目录结构类似: ```text workspace/ 001_门店名称_店铺ID/ 菜品原图.jpg _菜品图爬取记录.json _生成图片/ logo.png 店内海报_1138x292.png 招牌头图_750x288.png 菜品图/ 菜品名称.png generation-history.json ``` 生成结果的本地文件可能因为重新生成被覆盖;`generation-history.json` 会追加保存远程结果地址,用于历史创作页恢复和下载。 生成任务会保存到输出根目录下的 `.genpic/tasks.json`。页面刷新或服务重启后,任务中心仍能看到任务状态;已经提交给模型服务且仍在运行的任务会恢复轮询。排队任务因原始图片数据不落盘,重启后会标记为失败并提示重新提交。 ## 使用流程 1. 进入 **系统设置**,配置 API Key、默认模型、输出根目录和采集 Cookie。 2. 进入 **门店采集**,添加店铺并勾选需要采集的门店。 3. 开始采集后,系统会把菜品原图保存到输出根目录。 4. 进入 **视觉生成**,选择全量扫描或指定门店扫描。 5. 按界面步骤先生成 LOGO,再生成其他视觉资产和菜品商品图。 6. 到 **历史创作** 中检索、预览和下载已生成的作品。 ## 支持的生成模型 - `gpt-image-2` - `gpt-image-2-guan` - `doubao-seedream-5-0-pro-260628` - `doubao-seedream-5-0-260128` - `doubao-seedream-4-5-251128` - `wan2.6-image` ## 项目结构 ```text . ├── server.js # 引导入口:装配状态 → 挂载路由 → 监听(含端口自动回收) ├── server/ # 服务端模块(路由 / 服务 / 中间件分层) │ ├── router.js # 迷你路由(零依赖):路径匹配、:参数、405、fallback │ ├── middleware.js # 标准错误边界:统一异常 → JSON 响应(含错误码映射) │ ├── context.js # 共享状态装配:config / session / 店铺清单 / 路径守卫 / 日志 │ ├── util.js # 无状态工具:响应、请求体、文件名、静态资源常量 │ ├── stores/ # 存储驱动(ops-sqlite.js / ops-pg.js) │ ├── services/xlsx.js # 零依赖 xlsx 读取器(ZIP + XML) │ ├── routes/ # 薄 HTTP 层(按业务域拆分) │ │ ├── health.js # 健康检查 / 默认根目录 │ │ ├── session.js # 采集 Cookie 会话 │ │ ├── crawl.js # 门店采集:店铺清单、抓取控制、日志 │ │ ├── settings.js # 系统设置 + 生图/对话 API 连通性测试 │ │ ├── generate.js # 视觉生成、任务中心(含采集任务)、画板保存、打开目录 │ │ ├── history.js # 门店扫描(图片尺寸缓存)、历史创作、图片文件服务 │ │ ├── reports.js # 数据采集 + 智能问数(同步/查询/导出/周报) │ │ ├── ops.js # 店铺运营数据:上传/解析/矩阵查询/原件下载 │ │ ├── static.js # 静态前端(精确白名单 + /assets/) │ │ └── index.js # 路由注册总入口 │ └── services/ # 有状态引擎 │ ├── crawl.js # 采集引擎:翻页抓取、下载、断点跳过、可取消任务循环、进度持久化 │ ├── generation.js # 生成引擎:任务队列、供应商 API、轮询、图片合成、任务持久化 │ └── auto-sync.js # 经营数据每日自动同步(默认关闭) ├── scripts/ │ └── smoke.js # 冒烟测试:零依赖拉起真实服务全量核对端点(node scripts/smoke.js) ├── napos-service.js # 数据采集:取数服务层(同步任务 / 查询聚合 / CSV) ├── reports-store.js # 数据采集:本地数据湖(多主体 / 日期×门店 upsert) ├── napos/ # napos-mcp 取数引擎(CDP 附着商家客户端,零第三方依赖) │ ├── cdp.js # CDP 客户端 + 子站路由(按域选执行上下文) │ ├── kit.js # 业务取数工具箱(组织树 / 经营数据 / 签名) │ ├── guard.js # 写操作防护(只放行只读接口) │ └── data/apis.json # 140 个后台接口目录(防护索引) ├── public/ │ ├── index.html # 应用外壳和页面结构 │ ├── app.js # 导航、启动画面和系统设置 │ ├── crawl.js # 门店采集界面逻辑 │ ├── gen.js # 视觉生成界面逻辑 │ ├── history.js # 历史创作界面逻辑 │ ├── tasks.js # 任务中心界面逻辑 │ ├── reports.js # 数据采集 + 智能分析界面逻辑 │ └── style.css # 统一视觉系统 ├── config.example.json # 配置模板 ├── 启动.command # macOS 启动脚本 ├── 启动.bat # Windows 启动脚本 └── 启动.sh # Linux/macOS 启动脚本 ``` ## 本地数据与安全 服务默认仅监听本机 `127.0.0.1`。如需局域网访问,可临时设置 `HOST=0.0.0.0`,但建议仅在可信网络中使用。 ### 局域网访问口令 在「系统设置」设置 `accessToken`(或以 `ACCESS_TOKEN=xxx` 环境变量临时开启)后,局域网内其他电脑访问 `/api/*` 与图片/文件接口都需要口令:浏览器首次访问会弹窗引导输入一次(保存在浏览器 Cookie),命令行可用 `curl -H 'X-Access-Token: xxx' …` 或在 URL 后加 `?token=xxx`。本机回环访问、健康检查与静态页面不受影响。 ### 凭据与数据的存储位置 | 文件 | 内容 | 说明 | | --- | --- | --- | | `config.json` | API Key、模型、端口等 | 系统设置保存时写入;首次启动若缺失会自动从模板生成 | | `session.json` | 淘宝闪购采集 Cookie(含 `ksid`) | 仅门店采集使用;界面保存后不回显 | | `data/reports/` | 经营数据本地数据湖 | 各主体经营数据,按「日期 × 门店」沉淀 | | `data/ops.db` | 店铺运营数据(上传解析) | SQLite;含原件与解析行,备份 `data/` 时一并保留 | | `manual-shops.json` | 手动店铺清单 | 门店采集用 | 以上文件均不进 Git;数据采集的取数不依赖 Cookie —— 它实时读取本机商家客户端的登录态(调试端口 9669)。 ### 发给别人部署(分发包) 双击 **打包分发.command**(macOS/Linux)或 **打包分发.bat**(Windows),会在项目上级目录生成 `智慧运营中台-分发包.zip`。包内只含代码、依赖和配置模板,**不含**你的 `config.json` / `session.json` / `manual-shops.json` / `data/`(API Key、Cookie、报表数据只留在你本机)。 对方解压后双击 `启动.command`(macOS)或 `启动.bat`(Windows)即可:首次启动自动生成其本机 `config.json`,在「系统设置」中填写自己的 API Key;数据采集页按提示以调试端口启动并登录自己的商家客户端后同步取数。 **升级已装过旧版的电脑**:把分发包解压覆盖到原目录即可(不要先删旧目录)。包内不含配置文件,覆盖不会动他们的历史 `config.json` / `session.json`;新版启动时会把历史配置与默认值合并读取 —— API Key、模型、Cookie 全部原样沿用,无需重填;若历史 `rootDir` 在本机不可用,启动时会提示到「系统设置」修改,不会崩溃。 健康检查: ```bash curl http://127.0.0.1:5177/healthz curl http://127.0.0.1:5177/readyz ``` 本地接口只允许访问当前配置的输出根目录。采集 Cookie 保存后不会在设置页回显;需要更换时重新粘贴完整 Cookie 并保存即可。 以下文件包含本机运行数据或密钥,默认不会被 Git 提交: ```text config.json session.json manual-shops.json output/ workspace/ data/ .genpic/ ``` 请勿将 API Key、后台 Cookie 或门店数据提交到 Git。采集功能只应操作你有权管理的店铺,并遵守平台条款与当地法规。 ## 常见问题 ### 采集提示 Cookie 过期或缺少 ksid 重新登录淘宝闪购后台,复制完整 Cookie,并到“系统设置 → 采集配置”更新。 ### 视觉生成页面找不到门店 确认“系统设置”中的输出根目录正确;门店目录必须直接位于该根目录下,并且目录内有菜品图片或已生成的 `_生成图片` 目录。 ### 生成任务一直排队 检查 `maxConcurrentJobs` 是否过小,或等待已有任务完成。生成服务也可能存在限流或临时不可用。 ### 历史作品消失 历史创作列表只显示最近 48 小时内的记录。本地文件被重新生成覆盖时,页面会优先使用 API 返回的远程地址。 ### 数据采集与智能分析提示「客户端未连接」 数据采集的取数通道依赖本机淘宝闪购商家客户端的调试端口。完全退出客户端后,用以下方式重新启动并登录: ```text 淘宝闪购商家客户端 --remote-debugging-port=9669 ``` 连接后进入「数据采集 → 同步数据」,选择范围与日期区间开始同步。 ### 数据采集与智能分析同步部分门店失败 单个门店取数失败不影响其他门店,失败项会计入「失败」计数并保留在同步步骤里。常见原因是登录态失效(客户端重新登录即可)或触发了后台风控(在客户端完成验证后重试)。