studytime-analysis: 新增留存状态判定 — 最近14天无完课标记为流失,否则正常
This commit is contained in:
parent
ed6c864197
commit
cde77e762d
@ -7,4 +7,4 @@ lark_wiki_operate_as_bot 2a37701f568849f03eb46dd938baeda171380fe252b698ac8bda69c
|
||||
vala_git_workspace_backup 4cf352bec88fe84af065ba1ffcbb06647b77df0e01860faaf0bca9fd64b968ec
|
||||
cron-schedule b1879fa59d60e3d99cea1138674f7abac84a4aecd32743b801d41bfd6ed7181d
|
||||
study-analysis 33217dc132073ecd47b921800834f6df89494da9e7708fa90f15b3de7742e37f
|
||||
studytime-analysis 042178f9f7e97eeef366fd619403f4d0c8e0dce290abf17af662dddfa67c4e83
|
||||
studytime-analysis a3b2570583717cf5af2720f047de23752ee42cba8ff4a3f859d216e0580026ae
|
||||
|
||||
@ -13,7 +13,7 @@ import sys
|
||||
import psycopg2
|
||||
import psycopg2.extras
|
||||
import pymysql
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from collections import defaultdict, OrderedDict
|
||||
|
||||
# ── 配置 ──────────────────────────────────────────────
|
||||
@ -148,6 +148,21 @@ def fetch_role_info(role_id):
|
||||
}
|
||||
|
||||
|
||||
def check_retention(records, cutoff_days=14):
|
||||
"""
|
||||
检查角色留存状态
|
||||
- 最近 cutoff_days 天内有完课记录 → "正常"
|
||||
- 否则 → "流失"
|
||||
当无任何完课记录时,返回 "无完课记录"
|
||||
"""
|
||||
if not records:
|
||||
return "无完课记录"
|
||||
# 用本地时间比较(与 PG 存储时区一致 UTC+8)
|
||||
cutoff = datetime.now() - timedelta(days=cutoff_days)
|
||||
has_recent = any(r["updated_at"].replace(tzinfo=None) >= cutoff for r in records)
|
||||
return "正常" if has_recent else "流失"
|
||||
|
||||
|
||||
def fetch_completion_records(role_id):
|
||||
"""查询指定角色全部完课记录(包含寒暑假)"""
|
||||
params = {}
|
||||
@ -321,7 +336,7 @@ def analyze_weekly_trend(records):
|
||||
|
||||
# ── 输出格式化 ────────────────────────────────────────
|
||||
|
||||
def format_report(role_id, role_info, all_records, non_holiday_records, holiday_count, day_counts, weekday_periods, weeks_data, analysis):
|
||||
def format_report(role_id, role_info, retention_status, all_records, non_holiday_records, holiday_count, day_counts, weekday_periods, weeks_data, analysis):
|
||||
"""生成 Markdown 格式分析报告
|
||||
|
||||
Args:
|
||||
@ -352,6 +367,8 @@ def format_report(role_id, role_info, all_records, non_holiday_records, holiday_
|
||||
lines.append(f"| 年龄 | {role_info['age']} 岁 |")
|
||||
if role_info['phone_tail']:
|
||||
lines.append(f"| 账号手机号后4位 | {role_info['phone_tail']} |")
|
||||
if retention_status:
|
||||
lines.append(f"| 最近留存状态 | {retention_status} |")
|
||||
lines.append(f"")
|
||||
|
||||
# ── 数据概况 ──
|
||||
@ -566,12 +583,15 @@ def main():
|
||||
# 角色基本信息(MySQL)
|
||||
role_info = fetch_role_info(role_id)
|
||||
|
||||
# 留存状态判定
|
||||
retention_status = check_retention(all_records)
|
||||
|
||||
# 一周分布分析:仅用非寒暑假数据
|
||||
day_counts, weekday_periods = analyze_weekly_distribution(non_holiday_records)
|
||||
# 跨周趋势分析:用全部数据
|
||||
weeks_data, analysis = analyze_weekly_trend(all_records)
|
||||
|
||||
report = format_report(role_id, role_info, all_records, non_holiday_records, holiday_count, day_counts, weekday_periods, weeks_data, analysis)
|
||||
report = format_report(role_id, role_info, retention_status, all_records, non_holiday_records, holiday_count, day_counts, weekday_periods, weeks_data, analysis)
|
||||
|
||||
print(report)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user