主线 1: rns1-customer-coach-api + 04-miniapp-core-business 后端实施
- 新增 GET /xcx/coaches/{id}/banner 轻量接口
- performance/records 加 coach_id 参数 + view_board_coach 权限分流
- coach/customer/performance/board/task 服务层重构
- fdw_queries 结算单粒度聚合 + consumption_summary 视图统一
- task_generator 回访宽限 72h + UPSERT 替代策略 + Step 5 保底清理
- recall_detector settle_type=3 双重限制 + 门店级 resolved
主线 2: 小程序权限分流 + 新增 coach-service-records 管理者视角业绩明细页
- perf-progress 共享模块去重 task-list/coach-detail 动画逻辑
- isScattered 散客标记端到端
- foodDetail/phoneFull/creator* 字段透传
主线 3: P19 指数回测框架 Phase 1+2
- 3 个指数表 stat_date 日快照模式
- 新增 DWS_INDEX_BACKFILL / DWS_TASK_SIMULATION 工具任务
- task_engine 升级 HTTP 实时 + 推演回测双模式
主线 4: Core 维度层启用
- 新增 CORE_DIM_SYNC 任务(DWD → core 4 维度表)
- 修复 app 视图空查询问题
主线 5: member_project_tag 改为 LAST_30_VISITS 消费次数窗口
主线 6: 2 个迁移 SQL 已执行(stat_date + member_project_tag 新窗口)
- schema 基线与 DDL 快照同步
主线 7: 开发机路径迁移 C:\NeoZQYY → C:\Project\NeoZQYY(约 95% 改动量)
附带: 新建运维脚本(churned_customer_report / simulate_historical_tasks /
backfill_index_snapshots)+ tools/task-analysis/ 任务分析工具
合计 157 文件。未包含中间产物(tmp/ .playwright-mcp/ inspect-* excel/sheet 分析 txt)。
审计记录见下一个 commit。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
180 lines
4.4 KiB
Markdown
180 lines
4.4 KiB
Markdown
# 微信开发者工具自动化工作流
|
||
|
||
## 连接策略
|
||
|
||
### 首次连接
|
||
```
|
||
connect_devtools(strategy: "auto")
|
||
```
|
||
auto 策略会依次尝试:发现已运行实例 → 通过 CLI 启动 → ws 直连。
|
||
|
||
### 连接失败排查
|
||
1. `check_environment` — 检查 CLI 路径、项目路径是否正确
|
||
2. `diagnose_connection` — 检查端口、进程状态
|
||
3. 确认开发者工具「设置 → 安全 → 服务端口」已开启
|
||
|
||
### 重连
|
||
```
|
||
reconnect_devtools // 复用上次参数
|
||
```
|
||
|
||
## 页面导航模式
|
||
|
||
### 普通页面跳转
|
||
```
|
||
navigate_to(url: "/pages/task/task-list/index", params: { status: "pending" })
|
||
```
|
||
|
||
### TabBar 页面
|
||
```
|
||
switch_tab(url: "/pages/index/index")
|
||
```
|
||
注意:`navigate_to` 无法跳转 TabBar 页面,必须用 `switch_tab`。
|
||
|
||
### 重启并跳转
|
||
```
|
||
relaunch(url: "/pages/index/index")
|
||
```
|
||
清空页面栈,适合需要干净状态的场景。
|
||
|
||
### 返回
|
||
```
|
||
navigate_back(delta: 1) // 返回上一页
|
||
navigate_back(delta: 2) // 返回两层
|
||
```
|
||
|
||
## 元素操作最佳实践
|
||
|
||
### 操作流程(必须遵循)
|
||
1. `get_page_snapshot` 获取当前页面所有元素的 uid
|
||
2. 从快照中找到目标元素的 uid
|
||
3. 用 uid 执行操作(click / input_text / get_value / assert_*)
|
||
|
||
### 快照格式选择
|
||
- `compact`(默认推荐):含 uid、标签、文本、位置、尺寸,token 用量减少 60-70%
|
||
- `minimal`:只含 uid、标签、文本,最省 token
|
||
- `json`:完整 JSON,需要属性详情时用
|
||
|
||
### CSS 选择器查找
|
||
```
|
||
$("view.container") // 类名
|
||
$("#myId") // ID
|
||
$("text=按钮") // 文本匹配
|
||
```
|
||
返回匹配元素的详细信息,适合精确定位。
|
||
|
||
### 输入文本
|
||
```
|
||
input_text(uid: "xxx", text: "测试内容")
|
||
input_text(uid: "xxx", text: "追加内容", append: true)
|
||
input_text(uid: "xxx", text: "新内容", clear: true) // 先清空再输入
|
||
```
|
||
|
||
### 表单控件
|
||
```
|
||
set_form_control(uid: "xxx", value: 2) // picker 选第3项
|
||
set_form_control(uid: "xxx", value: true) // switch 开启
|
||
set_form_control(uid: "xxx", value: 50) // slider 设为50
|
||
```
|
||
|
||
## 断言验证
|
||
|
||
### 文本断言
|
||
```
|
||
assert_text(uid: "xxx", text: "精确匹配")
|
||
assert_text(uid: "xxx", textContains: "包含")
|
||
assert_text(uid: "xxx", textMatches: "\\d{4}-\\d{2}-\\d{2}") // 正则
|
||
```
|
||
|
||
### 状态断言
|
||
```
|
||
assert_state(uid: "xxx", visible: true)
|
||
assert_state(uid: "xxx", enabled: false)
|
||
assert_state(uid: "xxx", checked: true)
|
||
```
|
||
|
||
### 属性断言
|
||
```
|
||
assert_attribute(uid: "xxx", attributeKey: "class", attributeValue: "active")
|
||
```
|
||
|
||
## JS 执行
|
||
|
||
### 读取页面数据
|
||
```javascript
|
||
evaluate_script({
|
||
function: "() => { const pages = getCurrentPages(); return pages[pages.length-1].data; }"
|
||
})
|
||
```
|
||
|
||
### 读取全局数据
|
||
```javascript
|
||
evaluate_script({
|
||
function: "() => { return getApp().globalData; }"
|
||
})
|
||
```
|
||
|
||
### 调用 wx API
|
||
```javascript
|
||
evaluate_script({
|
||
function: "() => { return wx.getSystemInfoSync(); }"
|
||
})
|
||
```
|
||
|
||
### 带参数执行
|
||
```javascript
|
||
evaluate_script({
|
||
function: "(key) => { return wx.getStorageSync(key); }",
|
||
args: ["userToken"]
|
||
})
|
||
```
|
||
|
||
## 截图与视觉验证
|
||
|
||
### 保存截图到文件
|
||
```
|
||
screenshot(path: "C:/Project/NeoZQYY/export/screenshots/task-list.png")
|
||
```
|
||
|
||
### 配合 pixel-audit Power 做视觉对比
|
||
1. H5 页面用 Playwright 截图
|
||
2. MP 页面用 `screenshot` 截图
|
||
3. 用 `image-compare`(已集成在 pixel-audit)对比差异
|
||
|
||
## 网络请求监控
|
||
|
||
### 查看请求
|
||
```
|
||
get_network_requests(urlPattern: "api/v1/tasks", limit: 10)
|
||
get_network_requests(type: "request", successOnly: true)
|
||
```
|
||
|
||
### 清空并重新监控
|
||
```
|
||
clear_network_requests → 执行操作 → get_network_requests
|
||
```
|
||
|
||
## 等待策略
|
||
|
||
### 等待元素出现
|
||
```
|
||
waitFor(selector: ".loading", disappear: true, timeout: 10000) // 等 loading 消失
|
||
waitFor(selector: ".task-card", timeout: 5000) // 等元素出现
|
||
waitFor(text: "加载完成", timeout: 5000) // 等文本出现
|
||
```
|
||
|
||
### 固定延时
|
||
```
|
||
waitFor(delay: 2000) // 等待 2 秒
|
||
```
|
||
|
||
## 常见问题
|
||
|
||
| 问题 | 解决方案 |
|
||
|------|----------|
|
||
| 连接超时 | 检查 9420 端口是否开启,`diagnose_connection` |
|
||
| 元素找不到 | 先 `get_page_snapshot` 确认页面已加载完成 |
|
||
| navigate_to 失败 | TabBar 页面必须用 `switch_tab` |
|
||
| evaluate_script 报错 | 函数不能引用外部闭包变量,必须自包含 |
|
||
| 截图空白 | 页面可能还在加载,先 `waitFor` |
|