93 lines
4.1 KiB
Markdown
93 lines
4.1 KiB
Markdown
# Session: 2026-05-20 10:26:42 GMT+8
|
||
|
||
- **Session Key**: agent:main:feishu:direct:ou_e63ce6b760ad39382852472f28fbe2a2
|
||
- **Session ID**: 50fddf8c-d5b4-4e50-96c7-bff257907bd4
|
||
- **Source**: feishu
|
||
|
||
## Conversation Summary
|
||
|
||
user: 我们来调整一下lead_user_analysis.py这个脚本,你先读取理解一下
|
||
assistant: 已经读完了,理解如下:
|
||
|
||
**脚本功能:** 销售线索用户分析报表
|
||
|
||
**输入:** Excel 文件,含「用户ID」「线索进线日期」「销售」三列
|
||
|
||
**输出:** `output/销售线索_用户分析.xlsx`,每个用户+角色一行
|
||
|
||
**执行流程:**
|
||
|
||
| 步骤 | 内容 |
|
||
|------|------|
|
||
| 1 | 读取输入 Excel,提取有效用户ID(过滤非数字) |
|
||
| 2 | 查 `bi_vala_app_account`(status=1)拿注册时间 |
|
||
| 3 | 查 `bi_vala_app_character`(nickname非空、未删除)拿角色 |
|
||
| 4 | 遍历 8 张 `bi_user_chapter_play_record_{0-7}` 分表,查 10 个序章 chapter 的首次完成时间(play_status=1, MIN(updated_at)) |
|
||
| 5 | 查 `bi_vala_order` 拿订单(购买时间/课包名称/金额/渠道/trade_no/order_status) |
|
||
| 6 | 查 `bi_refund_order`(status=3)拿退款金额 |
|
||
| 7 | 组装:用户基础信息 + 10 节课完成时间 + 购买/退款聚合 + 原始文件字段 |
|
||
| 8 | 输出 Excel |
|
||
|
||
**序章 chapter_id:**
|
||
- L1 U00: 343-346, 348(L01-L05)
|
||
- L2 U00: 55-59(L01-L05)
|
||
|
||
**已知注意点:**
|
||
- 体验课固定 10 节,不区分用户实际购买的课程等级
|
||
- 完成时间用 `play_status=1` 的最早 `updated_at`
|
||
- 分表用 user_id(角色ID)关联,未走 `bi_level_unit_lesson` 映射表
|
||
|
||
---
|
||
|
||
脚本理解完毕,请说具体要调整哪些地方?
|
||
user: 我们来调整对于输入excel的处理,先识别输入文件中是否有用户ID,如果有则直接用用户ID进行匹配,如果没有用户ID,则识别是否有用户手机号,如果有用户手机号,则采用phone_chapter_qyery这个skill里面手机号和用户ID的匹配规则进行匹配,然后再用用户ID查询后续数据。
|
||
assistant: 明白,我先看一下 `phone-chapter-query` 这个 skill 里手机号和用户ID的匹配规则。
|
||
assistant: 已经读完了 `phone_chapter_query.py`,核心匹配逻辑是:
|
||
|
||
- 扫描 Excel 中所有 `1` 开头的 11 位数字作为手机号
|
||
- 脱敏为 `前3****后4` 格式,匹配 `bi_vala_app_account.tel`(`status=1 AND deleted_at IS NULL`)
|
||
- 返回 `phone → account_id` 映射
|
||
|
||
现在来改 `lead_user_analysis.py`。主要改动:
|
||
|
||
1. 先检测输入文件是否有「用户ID」列
|
||
2. 有 → 直接走原逻辑
|
||
3. 没有 → 检测手机号 → 脱敏匹配账号ID → 用匹配到的用户ID走后续查询
|
||
assistant: 验证一下语法和逻辑完整性:
|
||
assistant: 看到了,第 41 行 `***` 其实应该是调用 `get_password()`,之前的显示被工具脱敏了。修复:
|
||
assistant: 语法检查通过。下面总结改动内容:
|
||
|
||
---
|
||
|
||
### 改动总结
|
||
|
||
**核心改动:输入文件智能识别**
|
||
|
||
```
|
||
输入Excel
|
||
├── 有「用户ID」列 → 原逻辑,直接用用户ID查询
|
||
└── 无「用户ID」列
|
||
├── 扫描全表找手机号(1开头的11位数字)
|
||
├── 脱敏 前3****后4 → 匹配 bi_vala_app_account.tel
|
||
├── 拿到 account_id 列表
|
||
└── 用 account_id 走后续查询(与用户ID路径一致)
|
||
```
|
||
|
||
**新增函数(3个):**
|
||
|
||
| 函数 | 用途 |
|
||
|------|------|
|
||
| `mask_phone()` | 手机号脱敏 `138****5678` |
|
||
| `extract_phones_from_df()` | 从任意列中提取 11 位手机号并去重 |
|
||
| `match_phones_to_accounts()` | 脱敏后 IN 匹配 `bi_vala_app_account.tel`,返回映射 |
|
||
|
||
**输出列差异:**
|
||
- 用户ID模式:`用户ID → 线索进线日期 → 销售 → 角色ID ...`(不变)
|
||
- 手机号模式:`用户ID → 手机号 → 线索进线日期 → 销售 → 角色ID ...`(多了「手机号」列)
|
||
|
||
**未匹配处理:** 手机号未匹配到账号的,在控制台打印警告,但不写入输出(与 `phone_chapter_query` 追加到表尾的策略不同,因为本报表是用户+角色一行,未匹配手机号没有后续数据可展示)。
|
||
|
||
---
|
||
|
||
有什么需要调整的随时说。
|