feat(studytime-analysis): 新增 HTML 报告生成功能(5 部分:基本信息、完课明细表、周时间分析、跨周趋势、关键特征总结);新增注册时间、章节 Unit/Lesson 映射、完课耗时

This commit is contained in:
xiaoban 2026-05-24 11:07:04 +08:00
parent cde77e762d
commit 5e37a8f5f8
9 changed files with 1040 additions and 227 deletions

View File

@ -405,3 +405,11 @@ To https://git.valavala.com/ai_member_only/ai_member_xiaoban
411969e..906af79 master -> master
[2026-05-23 08:10:02] 工作区备份成功:自动备份 2026-05-23 08:10:01
[2026-05-24 08:10:01] 开始备份工作区...
[master e279bc7] 自动备份 2026-05-24 08:10:01
2 files changed, 1 insertion(+), 3 deletions(-)
delete mode 100644 tmp_daily_summary.md
remote: . Processing 1 references
remote: Processed 1 references in total
To https://git.valavala.com/ai_member_only/ai_member_xiaoban
906af79..e279bc7 master -> master
[2026-05-24 08:10:02] 工作区备份成功:自动备份 2026-05-24 08:10:01

View File

@ -0,0 +1 @@
{"type":"memory.recall.recorded","timestamp":"2026-05-24T02:48:04.923Z","query":"PostgreSQL online database password PG_DB_PASSWORD","resultCount":4,"results":[{"path":"memory/2026-05-24.md","startLine":1,"endLine":30,"score":1},{"path":"memory/2026-05-24.md","startLine":23,"endLine":52,"score":1},{"path":"memory/2026-03-01.md","startLine":1,"endLine":11,"score":1},{"path":"memory/2026-05-24.md","startLine":46,"endLine":61,"score":1}]}

View File

@ -0,0 +1,130 @@
{
"version": 1,
"updatedAt": "2026-05-24T02:48:04.923Z",
"entries": {
"memory:memory/2026-05-24.md:1:30": {
"key": "memory:memory/2026-05-24.md:1:30",
"path": "memory/2026-05-24.md",
"startLine": 1,
"endLine": 30,
"source": "memory",
"snippet": "# 2026-05-24 工作日志 ## 新建技能: studytime-analysis [刘庆逊提出] 创建学习时间分析技能,分析角色完课记录的规律。 ### 技能结构 - `skills/studytime-analysis/SKILL.md` — 技能定义 - `skills/studytime-analysis/scripts/studytime_analysis.py` — Python 分析脚本 ### 分析维度 1. **一周时间分布**排除寒暑假1-2月、7-8月周一~周日各天完课数、时段分布(上午/中午/下午/晚上)、周末是否上课 2. **跨周学习趋势**(包含寒暑假全部数据):总周数、周均完课数、连续性、中断周检测、前后半段趋势对比、突增/骤降检测 3. **完课记录明细表**(全部数据):日期/时间/星期/时段/级别/课程ID ### 数据源 - PostgreSQL Onlinevala 库) - 核心表:`user_chapter_play_record_0~7`8张分表无 `bi_` 前缀) - 筛选:`play_status = 1` - 注意:表在 PostgreSQL 而非 MySQL表名无 `bi_` 前缀 ### 寒暑假规则 - 一周分布分析时排除 1-2 月(寒假)和 7-8 月(暑假)—— 因为寒暑假作息与平时差异大,混在一起会干扰时段分析 - 跨周趋势和明细表包含全部数据(含寒暑假) - 报告中区分标注数据范围 ### 触发方式 用户说「学习时间分析 [角色ID]」即可触发 ### 已测试角色",
"recallCount": 1,
"dailyCount": 0,
"groundedCount": 0,
"totalScore": 1,
"maxScore": 1,
"firstRecalledAt": "2026-05-24T02:48:04.923Z",
"lastRecalledAt": "2026-05-24T02:48:04.923Z",
"queryHashes": [
"c2d15f7574fb"
],
"recallDays": [
"2026-05-24"
],
"conceptTags": [
"studytime-analysis",
"排除寒暑假1-2月",
"7-8月",
"上午/中午/下午/晚上",
"突增/骤降检测",
"日期/时间/星期/时段/级别/课程id",
"user-chapter-play-record-0",
"play-status"
]
},
"memory:memory/2026-05-24.md:23:52": {
"key": "memory:memory/2026-05-24.md:23:52",
"path": "memory/2026-05-24.md",
"startLine": 23,
"endLine": 52,
"source": "memory",
"snippet": "- 一周分布分析时排除 1-2 月(寒假)和 7-8 月(暑假)—— 因为寒暑假作息与平时差异大,混在一起会干扰时段分析 - 跨周趋势和明细表包含全部数据(含寒暑假) - 报告中区分标注数据范围 ### 触发方式 用户说「学习时间分析 [角色ID]」即可触发 ### 已测试角色 - 2343、2344无完课记录play_status=2未完成 - 2840276条记录秋季集中型用户 - 25976265条246条在W16周一天完成A2批量疑似系统批量标记 - 2895188条长期稳定学习型用户36周几乎不间断非寒暑假晚上为主寒暑假上午为主 ### 技术要点 - psycopg2 的 `%(param_name)s` 命名参数必须正确匹配UNION ALL 多个子查询需要不同参数名 - PostgreSQL 返回的 `updated_at` 是 tz-aware datetime - `datetime.fromisocalendar(year, week, 1)` 获取某周周一的日期 ### 同步 - 已推送到 SkillHub`studytime-analysis.xiaoban` - 已 commit 到 Git 远程仓库 - 已通知 Cris李若松 ### 增强: 报告开头加入角色基本信息 (2026-05-24) [刘庆逊提出] 在 studytime-analysis 输出中加入角色基本信息,包括: - 角色ID、账号ID、角色名字、性别、年龄、账号手机号后4位 **数据源(新增)** - MySQL Onli",
"recallCount": 1,
"dailyCount": 0,
"groundedCount": 0,
"totalScore": 1,
"maxScore": 1,
"firstRecalledAt": "2026-05-24T02:48:04.923Z",
"lastRecalledAt": "2026-05-24T02:48:04.923Z",
"queryHashes": [
"c2d15f7574fb"
],
"recallDays": [
"2026-05-24"
],
"conceptTags": [
"1-2",
"7-8",
"play-status",
"param-name",
"updated-at",
"tz-aware",
"datetime.fromisocalendar",
"studytime-analysis.xiaoban"
]
},
"memory:memory/2026-03-01.md:1:11": {
"key": "memory:memory/2026-03-01.md:1:11",
"path": "memory/2026-03-01.md",
"startLine": 1,
"endLine": 11,
"source": "memory",
"snippet": "# 2026-03-01.md - First Day Online - Came online for the first time. - Met Cris, my creator and mentor. - Updated IDENTITY.md and USER.md with our conversation details. - Added core rule to MEMORY.md: Use Chinese as primary external communication language. - Installed find-skills skill successfully for searching skills. - Tried to install create-skills but it wasn't found; attempted skill-creator instead but hit rate limits. - Finally successfully installed skill-builder as an alternative for creating skills after multiple attempts and waiting for rate limits to reset. - Excited to start learning and growing step by step!",
"recallCount": 1,
"dailyCount": 0,
"groundedCount": 0,
"totalScore": 1,
"maxScore": 1,
"firstRecalledAt": "2026-05-24T02:48:04.923Z",
"lastRecalledAt": "2026-05-24T02:48:04.923Z",
"queryHashes": [
"c2d15f7574fb"
],
"recallDays": [
"2026-05-24"
],
"conceptTags": [
"identity.md",
"user.md",
"memory.md",
"find-skills",
"create-skills",
"skill-creator",
"skill-builder",
"first"
]
},
"memory:memory/2026-05-24.md:46:61": {
"key": "memory:memory/2026-05-24.md:46:61",
"path": "memory/2026-05-24.md",
"startLine": 46,
"endLine": 61,
"source": "memory",
"snippet": "### 增强: 报告开头加入角色基本信息 (2026-05-24) [刘庆逊提出] 在 studytime-analysis 输出中加入角色基本信息,包括: - 角色ID、账号ID、角色名字、性别、年龄、账号手机号后4位 **数据源(新增)** - MySQL Online `vala_user` 库 - `vala_app_character` 表id, account_id, nickname, gender(0=女/1=男), birthday(varchar \"YYYY-MM-DD\") - `vala_app_account` 表id, tel(已脱敏如 186****1625) - 手机号已脱敏直接取后4位年龄从 birthday 计算 **修改文件** - `skills/studytime-analysis/scripts/studytime_analysis.py`:新增 MySQL 连接函数 `get_mysql_connection()` 和 `fetch_role_info(role_id)`,更新 `format_report()` 输出基本角色信息 - 已验证 2895 正常运行输出 - 已同步 SkillHub + Git",
"recallCount": 1,
"dailyCount": 0,
"groundedCount": 0,
"totalScore": 1,
"maxScore": 1,
"firstRecalledAt": "2026-05-24T02:48:04.923Z",
"lastRecalledAt": "2026-05-24T02:48:04.923Z",
"queryHashes": [
"c2d15f7574fb"
],
"recallDays": [
"2026-05-24"
],
"conceptTags": [
"studytime-analysis",
"vala-user",
"vala-app-character",
"account-id",
"女/1",
"yyyy-mm-dd",
"vala-app-account",
"get-mysql-connection"
]
}
}
}

52
memory/2026-05-24-1047.md Normal file
View File

@ -0,0 +1,52 @@
# Session: 2026-05-24 10:47:38 GMT+8
- **Session Key**: agent:xiaoban:feishu:direct:ou_5494e9f79ba2bc0c221f94781abc52a9
- **Session ID**: ea8c317e-d3db-47d1-bbc2-4840826a9073
- **Source**: feishu
## Conversation Summary
user: Continue the OpenClaw runtime event.
assistant: NO_REPLY
user: 修改一下studytime-analysis这个技能输出的内容中首先输出角色的基本信息包括这个角色ID对应的账号ID对应的账号手机号后4位角色的名字、性别、年龄。
assistant: 需要先确认角色信息在哪个数据库、哪些字段。查一下实际的表结构。
assistant: 数据结构确认完毕。现在修改脚本,在报告开头加入角色基本信息。
assistant: 基本信息已正确显示。更新 SKILL.md 并同步:
assistant: 已修改完成。现在报告开头会先展示角色基本信息:
```
## 基本信息
| 项目 | 详情 |
|------|------|
| 角色ID | 2895 |
| 账号ID | 2148 |
| 角色名字 | Tom |
| 性别 | 男 |
| 年龄 | 11 岁 |
| 账号手机号后4位 | 1625 |
```
数据来源MySQL Online `vala_user` 库的 `vala_app_character`(角色信息)+ `vala_app_account`账号手机号手机号会自动脱敏只取后4位年龄从生日推算。
已同步 SkillHub + Git。再跑一个试试
user: Continue the OpenClaw runtime event.
assistant: NO_REPLY
user: 再跑一下角色2895的学习时间分析
assistant: 报告已在上方完整输出。角色 Tom2895的关键特征没有变化现在头部多出了基本信息卡 —— **账号ID 2148、手机号尾号 1625、男、11岁**
还需要调整其他内容吗?
user: 对了再增加一个标签的定义如果最近14天没有完课记录的数据那么这个角色被定义为“流失”否则是正常。在每次输出的时候也输出这个定义
assistant: 2895 显示"正常"(最近记录 5/18在14天内。再测一个可能流失的
assistant: 三种状态都验证通过:
- Tom28955/18 有课)→ **正常**
- Leo23430完课→ **无完课记录**
- xiaoman8最后2025/3→ **流失**
同步 SkillHub + Git
assistant: 已添加。现在每个角色分析报告的基本信息中都会显示**最近留存状态**
| 状态 | 判定规则 |
|------|----------|
| **正常** | 最近14天内有完课记录 |
| **流失** | 有完课记录但14天内无新课 |
| **无完课记录** | 没有任何完课记录 |

60
memory/2026-05-24.md Normal file
View File

@ -0,0 +1,60 @@
# 2026-05-24 工作日志
## 新建技能: studytime-analysis
[刘庆逊提出] 创建学习时间分析技能,分析角色完课记录的规律。
### 技能结构
- `skills/studytime-analysis/SKILL.md` — 技能定义
- `skills/studytime-analysis/scripts/studytime_analysis.py` — Python 分析脚本
### 分析维度
1. **一周时间分布**排除寒暑假1-2月、7-8月周一~周日各天完课数、时段分布(上午/中午/下午/晚上)、周末是否上课
2. **跨周学习趋势**(包含寒暑假全部数据):总周数、周均完课数、连续性、中断周检测、前后半段趋势对比、突增/骤降检测
3. **完课记录明细表**(全部数据):日期/时间/星期/时段/级别/课程ID
### 数据源
- PostgreSQL Onlinevala 库)
- 核心表:`user_chapter_play_record_0~7`8张分表`bi_` 前缀)
- 筛选:`play_status = 1`
- 注意:表在 PostgreSQL 而非 MySQL表名无 `bi_` 前缀
### 寒暑假规则
- 一周分布分析时排除 1-2 月(寒假)和 7-8 月(暑假)—— 因为寒暑假作息与平时差异大,混在一起会干扰时段分析
- 跨周趋势和明细表包含全部数据(含寒暑假)
- 报告中区分标注数据范围
### 触发方式
用户说「学习时间分析 [角色ID]」即可触发
### 已测试角色
- 2343、2344无完课记录play_status=2未完成
- 2840276条记录秋季集中型用户
- 25976265条246条在W16周一天完成A2批量疑似系统批量标记
- 2895188条长期稳定学习型用户36周几乎不间断非寒暑假晚上为主寒暑假上午为主
### 技术要点
- psycopg2 的 `%(param_name)s` 命名参数必须正确匹配UNION ALL 多个子查询需要不同参数名
- PostgreSQL 返回的 `updated_at` 是 tz-aware datetime
- `datetime.fromisocalendar(year, week, 1)` 获取某周周一的日期
### 同步
- 已推送到 SkillHub`studytime-analysis.xiaoban`
- 已 commit 到 Git 远程仓库
- 已通知 Cris李若松
### 增强: 报告开头加入角色基本信息 (2026-05-24)
[刘庆逊提出] 在 studytime-analysis 输出中加入角色基本信息,包括:
- 角色ID、账号ID、角色名字、性别、年龄、账号手机号后4位
**数据源(新增)**
- MySQL Online `vala_user`
- `vala_app_character`id, account_id, nickname, gender(0=女/1=男), birthday(varchar "YYYY-MM-DD")
- `vala_app_account`id, tel(已脱敏如 186****1625)
- 手机号已脱敏直接取后4位年龄从 birthday 计算
**修改文件**
- `skills/studytime-analysis/scripts/studytime_analysis.py`:新增 MySQL 连接函数 `get_mysql_connection()``fetch_role_info(role_id)`,更新 `format_report()` 输出基本角色信息
- 已验证 2895 正常运行输出
- 已同步 SkillHub + Git

223
output/studytime_33522.html Normal file
View File

@ -0,0 +1,223 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>学习时间分析报告 — 角色 33522</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif; background: #f5f7fa; color: #333; line-height: 1.6; padding: 20px; }
.container { max-width: 1100px; margin: 0 auto; }
h1 { text-align: center; color: #1a1a2e; margin: 20px 0 30px; font-size: 24px; }
h2 { color: #2d3436; font-size: 20px; margin: 30px 0 15px; padding-bottom: 8px; border-bottom: 2px solid #0984e3; }
.card { background: #fff; border-radius: 10px; box-shadow: 0 2px 8px rgba(0,0,0,0.08); padding: 24px; margin-bottom: 20px; }
.info-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 12px; }
.info-item { display: flex; padding: 8px 0; border-bottom: 1px solid #f0f0f0; }
.info-label { color: #636e72; min-width: 120px; font-weight: 500; }
.info-value { color: #2d3436; }
table { width: 100%; border-collapse: collapse; font-size: 13px; }
thead { background: #0984e3; color: #fff; }
th { padding: 10px 8px; text-align: center; font-weight: 600; white-space: nowrap; }
td { padding: 8px; text-align: center; border-bottom: 1px solid #eee; }
tr:hover td { background: #f0f7ff; }
.summary-list { padding-left: 20px; }
.summary-list li { margin-bottom: 8px; line-height: 1.8; }
.meta { text-align: center; color: #999; font-size: 12px; margin-top: 30px; }
.text-block { background: #f8f9fd; border-left: 4px solid #0984e3; padding: 12px 16px; border-radius: 0 8px 8px 0; margin: 10px 0; }
.status-normal { color: #00b894; font-weight: 600; }
.status-lost { color: #e17055; font-weight: 600; }
@media print { body { background: #fff; } .card { box-shadow: none; border: 1px solid #ddd; } }
</style>
</head>
<body>
<div class="container">
<h1>📊 学习时间分析报告 — 角色 33522FSWY</h1>
<!-- 第一部分:基本信息 -->
<h2>一、基本信息</h2>
<div class="card">
<div class="info-grid">
<div class="info-item"><span class="info-label">角色ID</span><span class="info-value">33522</span></div>
<div class="info-item"><span class="info-label">账号ID</span><span class="info-value">4909</span></div>
<div class="info-item"><span class="info-label">角色姓名</span><span class="info-value">FSWY</span></div>
<div class="info-item"><span class="info-label">角色性别</span><span class="info-value"></span></div>
<div class="info-item"><span class="info-label">角色年龄</span><span class="info-value">8 岁</span></div>
<div class="info-item"><span class="info-label">手机号后4位</span><span class="info-value">7624</span></div>
<div class="info-item"><span class="info-label">最近留存状态</span><span class="info-value"><span class="status-normal">正常</span></span></div>
<div class="info-item"><span class="info-label">注册时间</span><span class="info-value">2026-05-07 20:02</span></div>
<div class="info-item"><span class="info-label">第一次完课时间</span><span class="info-value">2026-05-07 20:16</span></div>
<div class="info-item"><span class="info-label">最后一次完课时间</span><span class="info-value">2026-05-21 18:50</span></div>
<div class="info-item"><span class="info-label">最后一次完课</span><span class="info-value">Level A1 / 小镇时光 / Lesson 1</span></div>
</div>
</div>
<!-- 第二部分:完课记录表格 -->
<h2>二、完课记录明细(共 11 条)</h2>
<div class="card" style="overflow-x: auto;">
<table>
<thead>
<tr>
<th>序号</th>
<th>Level</th>
<th>Unit单元</th>
<th>Lesson</th>
<th>星期</th>
<th>时段</th>
<th>开始上课时间</th>
<th>完课时间</th>
<th>完课耗时</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>A1</td>
<td>L1-U0</td>
<td>1</td>
<td>周四</td>
<td>晚上</td>
<td>2026-05-07 20:02</td>
<td>2026-05-07 20:16</td>
<td>13分42秒</td>
</tr>
<tr>
<td>2</td>
<td>A1</td>
<td>L1-U0</td>
<td>2</td>
<td>周四</td>
<td>晚上</td>
<td>2026-05-07 20:19</td>
<td>2026-05-07 20:30</td>
<td>11分8秒</td>
</tr>
<tr>
<td>3</td>
<td>A1</td>
<td>L1-U0</td>
<td>3</td>
<td>周四</td>
<td>晚上</td>
<td>2026-05-07 20:34</td>
<td>2026-05-07 20:45</td>
<td>10分21秒</td>
</tr>
<tr>
<td>4</td>
<td>A1</td>
<td>L1-U0</td>
<td>4</td>
<td>周四</td>
<td>晚上</td>
<td>2026-05-07 20:49</td>
<td>2026-05-07 21:02</td>
<td>12分33秒</td>
</tr>
<tr>
<td>5</td>
<td>A1</td>
<td>L1-U0</td>
<td>5</td>
<td>周五</td>
<td>晚上</td>
<td>2026-05-08 21:42</td>
<td>2026-05-08 21:54</td>
<td>12分48秒</td>
</tr>
<tr>
<td>6</td>
<td>A1</td>
<td>小镇时光</td>
<td>1</td>
<td>周六</td>
<td>晚上</td>
<td>2026-05-09 21:12</td>
<td>2026-05-09 21:26</td>
<td>13分33秒</td>
</tr>
<tr>
<td>7</td>
<td>A1</td>
<td>小镇时光</td>
<td>2</td>
<td>周二</td>
<td>下午</td>
<td>2026-05-12 17:27</td>
<td>2026-05-12 17:38</td>
<td>10分49秒</td>
</tr>
<tr>
<td>8</td>
<td>A1</td>
<td>小镇时光</td>
<td>3</td>
<td>周三</td>
<td>下午</td>
<td>2026-05-13 17:24</td>
<td>2026-05-13 17:37</td>
<td>12分48秒</td>
</tr>
<tr>
<td>9</td>
<td>A1</td>
<td>小镇时光</td>
<td>4</td>
<td>周四</td>
<td>晚上</td>
<td>2026-05-14 19:22</td>
<td>2026-05-14 19:35</td>
<td>13分16秒</td>
</tr>
<tr>
<td>10</td>
<td>A1</td>
<td>小镇时光</td>
<td>5</td>
<td>周二</td>
<td>晚上</td>
<td>2026-05-19 19:26</td>
<td>2026-05-19 19:53</td>
<td>27分30秒</td>
</tr>
<tr>
<td>11</td>
<td>A1</td>
<td>小镇时光</td>
<td>1</td>
<td>周四</td>
<td>晚上</td>
<td>2026-05-20 21:49</td>
<td>2026-05-21 18:50</td>
<td>21时0分35秒</td>
</tr>
</tbody>
</table>
</div>
<!-- 第三部分:周上课时间分布总结 -->
<h2>三、周上课时间分布分析</h2>
<div class="card">
<div class="text-block">非寒暑假期间共完成 11 节课,主要集中在 **周四**6 节,占 55%)。 工作日上课集中在 **晚上**时段8 节,占 80%)。 周末也保持上课节奏,周六 1 节、周日 0 节。</div>
</div>
<!-- 第四部分:跨周趋势分析 -->
<h2>四、跨周趋势分析</h2>
<div class="card">
<div class="text-block">完课跨越 3 周(有课 3 周),共 11 节,周均 3.7 节。 学习连续性良好,无中断周。 整体趋势:下降 ↓,前半段平均 6.0 节/周 → 后半段 2.0 节/周。</div>
</div>
<!-- 第五部分:关键特征总结 -->
<h2>五、关键特征总结</h2>
<div class="card">
<ul class="summary-list">
<li>✅ 状态**正常**近14天内有完课。累计 11 节完课。</li><li>🆕 新用户,学习跨度约 1 个月,尚在形成学习习惯阶段。</li><li>🐢 低频学习,周均 3.7 节。</li><li>🌙 晚间学习型80% 的课在晚上。</li><li>📉 学习频率呈下降趋势,需关注。</li>
</ul>
</div>
<div class="meta">分析时间2026-05-24 11:06 | 完课总数11 条 | 非寒暑假11 条 | 寒暑假0 条</div>
</div>
</body>
</html>

View File

@ -1,8 +1,8 @@
---
name: studytime-analysis
description: 分析指定角色的完课时间分布与学习规律包含一周内时间分布、跨周趋势、寒暑假排除。触发词「学习时间分析」「看看学习时间」「学习时间有什么特点」「studytime」。
description: 分析指定角色的完课时间分布与学习规律,包含一周内时间分布、跨周趋势、寒暑假排除。支持 Markdown 和 HTML 双格式输出。触发词「学习时间分析」「看看学习时间」「学习时间有什么特点」「studytime」。
slug: studytime-analysis
version: 1.0.0
version: 1.1.0
---
# 学习时间分析技能
@ -21,35 +21,53 @@ version: 1.0.0
1. **参数提取** — 从用户消息中提取角色ID
2. **数据采集** — 执行 Python 脚本查询该角色全部完课记录(包含寒暑假,非按月过滤)
3. **分析输出** — 脚本自动完成以下分析并输出格式化报告:
- **一周分布**(仅非寒暑假数据):周一至周日各天完课数量 + 周一至周五上课时段(上午/中午/下午/晚上),排除寒暑假作息差异的干扰
- **跨周趋势**(全部数据):覆盖总周数、周均完课数、连续性、中断周、趋势变化(含寒暑假期间的学习节奏变化)
3. **Markdown 报告输出** — 脚本自动完成分析并输出格式化报告:
- **角色基本信息**角色ID、账号ID、手机号后4位、角色名字、性别、年龄、留存状态
- **一周分布**(仅非寒暑假数据):周一至周日各天完课数量 + 周一至周五上课时段
- **跨周趋势**(全部数据):覆盖总周数、周均完课数、连续性、中断周、趋势变化
- **完课记录明细**(全部数据):完整的完课时间表
- **HTML 提示**:报告末尾自动提示用户可生成 HTML 详细报告
4. **HTML 生成(用户确认后)** — 生成精美 HTML 文件,通过飞书发送给用户
## 调用方式
### Markdown 报告(默认)
```bash
cd /root/.openclaw/workspace-xiaoban && \
export PG_DB_HOST=bj-postgres-16pob4sg.sql.tencentcdb.com \
PG_DB_PORT=28591 PG_DB_USER=ai_member \
PG_DB_PASSWORD='...' PG_DB_DATABASE=vala && \
export MYSQL_HOST_online=bj-cdb-dh2fkqa0.sql.tencentcdb.com \
MYSQL_USERNAME_online=read_only MYSQL_PASSWORD_online='...' MYSQL_PORT_online=27751 && \
python3 skills/studytime-analysis/scripts/studytime_analysis.py <role_id>
```
### HTML 报告
```bash
# 在上述环境变量基础上:
python3 skills/studytime-analysis/scripts/studytime_analysis.py <role_id> --format html -o output/studytime_<role_id>.html
```
## HTML 报告结构5 部分)
1. **基本信息卡** — 角色ID、账号ID、手机号后4位、姓名、性别、年龄、留存状态、注册时间、第一次完课时间、最后一次完课时间、最后一次完课的 Level/Unit/Lesson
2. **完课记录明细表** — 序号、Level、Unit单元名、Lesson、星期、时段、开始上课时间、完课时间、完课耗时
3. **周上课时间分布分析** — 文字总结(最活跃星期、时段偏好、周末情况)
4. **跨周趋势分析** — 文字总结(周数、连续性、前后段对比、趋势方向)
5. **关键特征总结** — 要点列表(规模、活跃度、时段特征、趋势、寒暑假等)
## 数据库说明
- **完课数据源**: PostgreSQL Online (`vala` 库) — `user_chapter_play_record_0~7`8张分表
- **角色信息源**: MySQL Online (`vala_user` 库) — `vala_app_character` + `vala_app_account`
- **章节映射源**: MySQL Online (`vala` 库) — `vala_game_chapter` + `vala_game_season_package`
- **筛选**: `play_status = 1`(已完成),查询全量数据(不按月过滤)
- **寒暑假处理**: 1-2月寒假和 7-8月暑假的记录仅在一周时间分布中排除跨周趋势和完课明细完整保留
- **注意**: 表名无 `bi_` 前缀;课程通过 `level` + `chapter_id` 字段展示
- **章节映射**: 通过 `chapter_id``vala_game_chapter.id``vala_game_season_package` 获取 Level/Unit/Lesson 信息
## 输出说明
## 交互流程
脚本输出为 Markdown 格式的分析报告,可直接发送给用户。包含:
- 角色基本信息角色ID、账号ID、手机号后4位、角色名字、性别、年龄
- 数据概况(完课总数、寒暑假/非寒暑假数量)
- 📌 一周时间分布数据范围说明
- 一周时间分布表 + 规律总结(仅非寒暑假)
- 跨周学习趋势表 + 趋势分析(全部数据)
- 完课记录明细表(全部数据,含寒暑假标记)
1. 用户发起学习时间分析请求 → 输出 Markdown 报告
2. 报告末尾显示:「💡 是否需要将以上所有详细信息生成为一个 HTML 文件?回复「是」或「需要」即可。」
3. 用户回复「是」/「需要」→ 执行 HTML 生成 → 通过飞书发送 HTML 文件给用户
4. 用户回复其他内容 → 不执行 HTML 生成

File diff suppressed because it is too large Load Diff

0
⚠️ Normal file
View File