Overview
运行概览
小程序四条产品线(解析 / 聊天 / 在线用户 / 3D 魔方)的整体运行水位与接口热度。
运行健康度
7 段对应项目真实子系统。任一段转为警戒/异常时,优先看对应的源码模块。
接口调用热度
后端 body.type 分发分支,共 34 个;下列为 Top 8。
解析趋势
按平台拆分 · 当前窗口内的真实记录
Parse
解析记录
只统计事件名 === parse 的日志条目(取自前端请求行的请求体 type)。
可按用户过滤(选用户后改读该用户自己的日志 wx:app:logs:<openid>,与「日志与链路」页同源);
右侧「刷新」只重取本页,不牵连整站其它端点。
平台徽标由关键词匹配得出;解析历史 URL 本体存于小程序本地 storage。
历史链接
—
| 平台 | 用户 | 域名 | 链接 | 解析时间 | 耗时 | 状态 | 详情 |
|---|
—
Orders
虚拟支付订单
订单来自 MySQL wx_vpay_orders,与小程序 /pay event=order_list 同一张表、同一份字段契约。
状态字段兼容字符串与 0–4 数字,此处按 normStatus() 归一化展示。
按用户过滤会把 openid 发到后端在 SQL 里筛 —— 不是对已取回的行做前端 filter,
否则会漏掉那个用户更早、已经掉出取数上限的订单。
订单明细
—
| 订单号 | 用户 | 商品 | 类型 | 数量 | 金额 | 状态 | 下单时间 | 支付时间 |
|---|
—
Scan
扫码记录
小程序「更多功能 → 扫一扫」成功后的原始结果:经 WebSocket 以
{ type:"scan", content, scanType, charSet } 上报,后端原样写入 Redis
wx:scan:log。本页只读 —— 不解析、不改写、不裁剪。
后端只存 openid,所以「用户」列的昵称与头像是前端从在线快照里补齐的;
content 一律原文透出,点「详情」看完整内容与全部字段。
扫码明细
—
| 类型 | 用户 | 内容 | 长度 | 扫码时间 | 详情 |
|---|
—
Permissions
用户与权限
本页按「先给人、再定规矩」排:顶部是 小程序在线用户 · 权限下发(给在线账号逐个下发权限位,
该面板自身的展示/可写由 global.CONSOLE_UI.permOnlinePanel 控制),往下依次是配置来源、越权提示文案、页面 × 权限位矩阵与权限位中文名。
页面映射以后端 global.APP_CONFIG 的 perm.pages 为唯一来源,
小程序由 PAGE_PERMISSION 下发、本地 PAGE_PERMISSION_MAP 兜底。
本页所有字段均可直接编辑,保存后业务节点在下一条消息即生效。
小程序在线用户 · 权限下发
「权限」列列出该账号当前已授权的全部权限位(含不对应任何页面的位);点「修改权限…」改一个人,先在左侧勾选再点「修改权限…」批量改;应用后入队 → wxService 递增 permRc(旧离线票据立即作废)。本面板的展示与可写由 global.CONSOLE_UI.permOnlinePanel 控制
global.CONSOLE_UI(未读到(按全开显示))
配置来源
运行时配置整体替换本地兜底表
- 当前生效来源
- 后端 APP_CONFIG · perm.pages
- 本地兜底
- PAGE_PERMISSION_MAP
- 静默窗口
- 60 000 ms
- 最近成功拉取
- —
- 缓存键
- PERMISSION_CONFIG
- 登记页面数
- —
_permCfgLoading 防并发;成功后进入 60s 静默窗口,
窗口内的广播风暴与反复进出页面不会重复请求。改了本页配置后,后端会主动广播
permission_config_updated,小程序立刻强制重拉 —— 不必等静默窗口过期。
越权提示文案
全站统一,改完保存即全站生效;正文支持换行
perm.revokedTitle/Content 与
perm.noPermTitle/Content,下发字段 PERM_REVOKED_* /
PERM_NO_PERM_*,小程序侧留空即回落到自身兜底文案。
morefeatures)不整体拦截,逐项在页面内自行校验;
PermissionManagement / virtualpay / payorders 属管理或支付流程,不做权限位拦截。
页面 × 权限位 矩阵
点格子即把该页面的权限位切成这一列;标题与路径可直接改。
列头显示的中文名可以随便改,title 里的字段名须与后端 permisionsList 的 key 逐字一致(不可改)。
权限位中文名
控制台与小程序「权限管理」页的显示名。name 是提交给后端的字段名,
改了等于把该权限位静默清零,所以这里只让改中文名。
Devices
设备与运行环境
系统信息统一由 utils/windowInfo.js 提供:模块加载期探测一次并冻结缓存,避免监听器累积。
设备档案
来自每次请求头 sys(getSystemInfo() 四片合并),
按用户存于 Redis wx:device:info
—
统一入口:三出口
调用方只认这三类出口,不再各自读 API
getSystemInfoSync 返回全字段对象,
若并入会在 device → window → base → setting 合并时覆盖前三片已取到的细分字段;
同时会让「有细分 API 时绝不调旧 API」的设计目标失效。
environment 仅由旧 getSystemInfoSync 返回,四件套细分 API 均不含它 ——
因此企业微信识别必须走 getEnvironment(),且只取值不判断,
=== 'wxwork' 的比较留在 platform.js。
端分布
请求头 sys.environment 随签名一起上报,后端据此区分请求来源端
Bluetooth
蓝牙打印
小程序蓝牙打印的两块后台数据:授权设备(哪些 MAC 允许打印)与
打印模板(小程序 type=get_print_templates 下发的模板整表)。
改动分别写入 Redis / global.APP_CONFIG,小程序下一条消息即生效。
授权 BLE 设备 0
Redis SET wx:ble_devices,与小程序 savemac/verifyDevice
同口径(多节点共享 db1)。MAC 大小写不敏感,统一存为全大写;当前共
0 台。
打印模板 0
配置键 print.templates。选一个模板编辑,保存后小程序
下一条消息即生效;「恢复默认」= 回退节点内置默认表。
—
Pages
页面配置
逐个页面配置:页面标题、是否启用分享,以及该页分享时用的
分享标题与分享图片。写入
global.APP_CONFIG["page.config"],后端下一条消息即生效;
小程序端在下次拉取导航栏配置时拿到新值(重进小程序,或切到「我的」页),无需发版。
本页还有第二块 底栏(tabBar)显示配置:整条底栏的显示/隐藏、每项的文案与图标、
以及浅色/深色两套底栏配色,写入 global.APP_CONFIG["tabbar.config"]。
不配置 = 完全接管前的现有观感(app.json + theme.json)。
底栏项分两类:写进 app.json 的 tabBar.list 的页是
真 tab(switchTab、有选中态),其余页是跳转项
(navigateTo、保留返回按钮、不限页面、图标还能填
https 图片链接)—— 两类都保存即可见、不必发版(见该面板的说明)。
逐页配置 0
配置键 page.config。页面标题留空 = 不接管,该页继续用它自己的标题
(每行底部标出该页 json 里的原生标题);分享标题 / 分享图片留空 = 用后端内置的默认分享配置。
关掉「启用分享」后,小程序端在该页会隐藏右上角「转发」入口。
默认只有首页 / 解析页 / 天气三个分享页开着 —— 打开它会调
wx.showShareMenu 把转发入口主动打开(页面自己没写
onShareAppMessage 也会因此多出一个入口)。
—
底栏(tabBar)显示配置 —
配置键 tabbar.config。不保存 = 不接管,底栏就是现在的原生观感
(app.json 的 tabBar + theme.json 的深浅两套色)。
保存后小程序端按当前主题档覆盖配色,并在回前台时拉新(60 秒节流)。
底栏项分两类,两类都保存即可见(不必发版):
真 tab —— 该页已写进 app.json 的 tabBar.list:
点它走 wx.switchTab、有选中态(微信规定 tab 页必须在主包内);
跳转项 —— 其余任何页面:点它走 wx.navigateTo,保留返回按钮,
代价是进到那一页后框架不再注入底栏(那页上看不到底栏、底栏也不高亮它)。
所以新配一个页面,保存后小程序回前台(60 秒节流)就能在底栏上看到它。
「导出 app.json 片段」是可选的升级动作:把跳转项写进
app.json 的 tabBar.list(→ 跑
node node-red/_gen-page-config.js → 发版),它才会变成真 tab
—— 有选中态,但那一页从此成为根页面(进去没有返回按钮)。
不需要发版、也不在意选中态的话,就不用导出。
导出的是整段 tabBar.list(= 上面配的那几项,微信要求 2..5 项);
原 tab 池里这次没被选中的页会一并移出,导出提示里会点出来。
「选页面」列全部页面(主包 7 个 + 两个分包,分三组标注)—— 因为
跳转项不限页面:主包页、分包页都能挂(navigateTo 正常)。
「必须在主包内」这条微信硬规则只约束真 tab,只影响能不能导出成
app.json 的 tabBar.list。
每项显示「页面名字 路径」,名字取小程序页面里填写的标题
(页面 json 的 navigationBarTitleText)。
每项的文案 / 图标可以留空,留空即沿用该页在 app.json 里的默认值;
没写进 app.json 的页(跳转项)没有默认值可继承,必须自己填文案。
图标两种写法都收:包内相对路径(如
images/home-noselect.png,现成可用的只有那 4 个),或
https 图片链接(自定义底栏渲染的是普通 <image>,
图床链接直接能用;http 会被微信拦,已在校验里挡掉)。
⚠ 链接图标只能用在跳转项上 —— 微信的 tabBar.list 只收包内
本地图片(≤40KB),所以「导出 app.json 片段」会把链接图标拦下来;
想升级成真 tab 就得先把图标换成相对路径。
—
Privacy
隐私政策
编辑小程序《隐私政策》页的全文,含顶部的联系方式(邮箱 / QQ 可点击复制)。
写入 global.APP_CONFIG["privacy.content"],后端下一条消息即生效;
小程序端收到变更信号会自己重新拉取,在线用户不必重进小程序。
⚠ 这是法律文本:内容形状非法时后端会回落代码里的出厂全文 —— 宁可显示旧版,也绝不空白。
正文 —
结构 = 页头 + 联系方式 + 若干章节(每章若干卡片,每卡若干内容块) + 页脚。内容块三种:段落 / 操作路径(等宽高亮底)/ 信息对照表(按行编辑)。 章节、卡片、内容块都能增删与上下移动。
—
整段 JSON 编辑。点「保存」或「返回表单模式」时才会解析; 语法错误会留在本模式里并给出原因,不会丢编辑。
Help
使用帮助
编辑小程序「使用帮助」页的全部文案,按页签分组:解析(使用步骤 / 支持平台 / 解析能力 / 小贴士)、
功能介绍(分组 + 功能条目)、常见问题(问答)、文章(文章列表,每条一个名称 + 链接)。写入
global.APP_CONFIG["help.content"],后端下一条消息即生效;
小程序端收到变更信号会自己重新拉取,不必发版、不必重进小程序。
文案 —
除文章列表外的六个数组分区都必须非空 —— 后端与小程序端都按「非空数组才覆盖」逐段兜底,
留空会出现「一半新一半旧」的页面,所以这里直接拦在保存前。
「支持平台」「小贴士」按一行一条编辑。
文章列表(最后一块)可以留空:留空时小程序端显示「文章暂未配置」占位;
每一条填一个名称(显示在列表里)与一个完整链接,可以加任意多条。
小程序端点列表项会跳进独立文章页(不内嵌,进去后随时能返回);
链接所在域名需在「小程序后台 → 开发 → 业务域名」白名单内
(公众号文章还需小程序与该公众号已关联),否则页面打不开。
—
整段 JSON 编辑(六个字段与小程序 help.js 的 data 同名)。 点「保存」或「返回表单模式」时才会解析;语法错误会留在本模式里,不会丢编辑。
Logs & Trace
日志与链路
三个子页按「看 → 查 → 改」排:日志流与级别是同一份读数的明细与分布,
登录链路是从 doLogin 到凭证落库的关键节点,
上报配置可直接改(写入 Node-RED global.APP_CONFIG,业务节点下一条消息即生效)。
日志流
不选用户 = 全局日志(wx:app:logs);选用户 = 该用户日志(wx:app:logs:<openid>)。
内容列放不下整行日志,点行末「详情」看该条的完整原文与全部字段。
| 级别 | 内容 | 时间 | 详情 |
|---|
—
级别分布
仅 reportLevel 白名单内的级别进入上报队列
pushRemote 触发恢复。
这两个阈值是 logger.js 里的代码常量(FAIL_THRESHOLD /
PAUSE_MS),不在上面的可配项里,改它们要改源码。
登录链路追踪
冷启动失败闭环:wx.login → 401 兜底 → reLogin → 补试
—
上报配置
global.APP_CONFIG,业务节点下一条消息就读到新值。
但生效时机分两类:log.ttlSec / maxGlobalCount / maxUserCount
/ traceMax 是后端写 Redis 时用的,保存后下一次写日志即按新值裁剪;
而 log.defaultConfig.* / reportLevel / adminReportLevel
是 get_logger_config 的下发值,
要等小程序下次调用该接口(冷启动 / 重进小程序)才拿到 —— 保存成功 ≠ 已下发到客户端。
WebSocket
WS 调试台
直连后端 WebSocket(node-red/server/ws/wsService.js):监听全部下行帧,
也能主动发送任意帧。登录控制台后本页自动连接并完成鉴权,无需手动操作。
刷新或关闭页面会销毁客户端 ——
停心跳 → 停重连 → 发 disconnect 让服务端立刻清会话 → 正常关闭。
连接设置
凭证只进本标签页的 sessionStorage,关标签即失效
主动发送
点任一指令填入模板;Ctrl+Enter 发送
事件流 0
后端 wsService 的全部下行帧,默认不过滤。最新帧在最上方。 缓冲上限 500 条(超出丢最旧)—— AI 流式回复是一 token 一帧,不限量会吃满内存。
| 时间 | 方向 | 类型 | 摘要 | 原文 |
|---|
Config
运行配置
后端 wxService.js / wsService.js 的可调参数集中在这里
(日志与上报参数已移到「日志与链路」页,在那边的「上报配置」里改)。
改动写入 Node-RED global.APP_CONFIG,业务节点在下一条消息就会读到新值 ——
不用重贴 function 节点、不用重启 Node-RED。
flow 只放「同一条 flow 内共享的业务表」
(appidList / authUserSet / help_content / ws_sessions …),
global 放「全局开关 / 密钥 / 跨 tab 的运行时状态」
(ws_sign_mode / admin_openids / qlgq_appid / ADMIN_PASSWORD …)。
配置项属于后者,所以与 ws_sign_mode 完全同一套写法。