refactor(theme): 扩展AppTheme支持卡片样式和圆角风格动态配置 feat(services): 新增HapticService触觉反馈服务 feat(services): 实现ScreenWakeService屏幕常亮管理 feat(services): 添加SoundService音效播放服务 feat(services): 集成AppLockService应用锁功能 feat(services): 实现BatteryOptimizationService电池优化 feat(services): 新增NetworkProxyService网络代理 feat(services): 完善DataExportService数据导出 feat(services): 增强PermissionService权限管理 feat(tools): 工具中心新增拼音转换等多项功能 fix(localization): 修复时区初始化错误 docs: 更新工具中心开发清单和设置重构文档 chore: 更新依赖版本和CI配置
121 lines
4.9 KiB
Python
121 lines
4.9 KiB
Python
# ============================================================
|
||
# 闲言APP — 句子卡片数据永不更新根因验证
|
||
# 创建时间: 2026-05-01
|
||
# 作用: 验证 fetchMix 接口在相同参数下是否返回相同数据
|
||
# ============================================================
|
||
|
||
import requests
|
||
import json
|
||
import time
|
||
|
||
BASE = "https://tools.wktyl.com"
|
||
|
||
def fetch_mix(mode="random", limit=5, channels=None, sort="hottest"):
|
||
params = {"mode": mode, "limit": limit, "sort": sort}
|
||
if channels:
|
||
params["channels"] = ",".join(channels)
|
||
try:
|
||
r = requests.get(f"{BASE}/api/feed/mix", params=params, timeout=10)
|
||
data = r.json()
|
||
if data.get("code") == 1:
|
||
items = data.get("data", {}).get("list", [])
|
||
return items
|
||
except Exception as e:
|
||
print(f" ❌ fetchMix 请求失败: {e}")
|
||
return []
|
||
|
||
print("=" * 70)
|
||
print("根因验证: fetchMix 默认 sort=hottest 是否导致数据固定")
|
||
print("=" * 70)
|
||
|
||
# 测试1: 默认 sort=hottest 连续3次
|
||
print("\n📌 测试1: sort=hottest (默认) 连续3次请求")
|
||
all_ids_hottest = []
|
||
for i in range(3):
|
||
items = fetch_mix(mode="random", limit=5, sort="hottest")
|
||
ids = [f"{item.get('feed_type','?')}_{item.get('id')}" for item in items]
|
||
titles = [item.get("title", "")[:25] for item in items]
|
||
all_ids_hottest.extend(ids)
|
||
print(f" 第{i+1}次: ids={ids}")
|
||
for t in titles:
|
||
print(f" → {t}")
|
||
time.sleep(0.3)
|
||
|
||
unique_hottest = len(set(all_ids_hottest))
|
||
total_hottest = len(all_ids_hottest)
|
||
print(f" 📊 总ID数={total_hottest}, 去重后={unique_hottest}, 重复率={1-unique_hottest/total_hottest:.1%}")
|
||
|
||
# 测试2: sort=newest 连续3次
|
||
print("\n📌 测试2: sort=newest 连续3次请求")
|
||
all_ids_newest = []
|
||
for i in range(3):
|
||
items = fetch_mix(mode="random", limit=5, sort="newest")
|
||
ids = [f"{item.get('feed_type','?')}_{item.get('id')}" for item in items]
|
||
titles = [item.get("title", "")[:25] for item in items]
|
||
all_ids_newest.extend(ids)
|
||
print(f" 第{i+1}次: ids={ids}")
|
||
for t in titles:
|
||
print(f" → {t}")
|
||
time.sleep(0.3)
|
||
|
||
unique_newest = len(set(all_ids_newest))
|
||
total_newest = len(all_ids_newest)
|
||
print(f" 📊 总ID数={total_newest}, 去重后={unique_newest}, 重复率={1-unique_newest/total_newest:.1%}")
|
||
|
||
# 测试3: 对比 hottest vs newest
|
||
print("\n📌 测试3: hottest vs newest 对比")
|
||
hottest_items = fetch_mix(mode="random", limit=5, sort="hottest")
|
||
newest_items = fetch_mix(mode="random", limit=5, sort="newest")
|
||
hottest_ids = set(f"{item.get('feed_type','?')}_{item.get('id')}" for item in hottest_items)
|
||
newest_ids = set(f"{item.get('feed_type','?')}_{item.get('id')}" for item in newest_items)
|
||
overlap = hottest_ids & newest_ids
|
||
print(f" hottest: {hottest_ids}")
|
||
print(f" newest: {newest_ids}")
|
||
print(f" 重叠: {overlap}")
|
||
|
||
# 测试4: 客户端当前代码使用的参数
|
||
print("\n📌 测试4: 模拟客户端当前代码 (mode=random, limit=5, 无sort参数)")
|
||
all_ids_client = []
|
||
for i in range(5):
|
||
items = fetch_mix(mode="random", limit=5)
|
||
ids = [f"{item.get('feed_type','?')}_{item.get('id')}" for item in items]
|
||
all_ids_client.extend(ids)
|
||
print(f" 第{i+1}次: ids={ids}")
|
||
time.sleep(0.3)
|
||
|
||
unique_client = len(set(all_ids_client))
|
||
total_client = len(all_ids_client)
|
||
print(f" 📊 总ID数={total_client}, 去重后={unique_client}, 重复率={1-unique_client/total_client:.1%}")
|
||
|
||
# 测试5: 检查 FeedMixConfig.toQueryParameters 是否传了 sort
|
||
print("\n📌 测试5: FeedMixConfig.toQueryParameters 分析")
|
||
print(" 客户端代码 (feed_model.dart):")
|
||
print(" Map<String, dynamic> toQueryParameters() {")
|
||
print(" final params = <String, dynamic>{'mode': mode, 'limit': limit};")
|
||
print(" if (channels.isNotEmpty) params['channels'] = channels.join(',');")
|
||
print(" if (mode == 'ratio' && ratios.isNotEmpty) params['ratios'] = jsonEncode(ratios);")
|
||
print(" if (mode == 'group') params['group_size'] = groupSize;")
|
||
print(" return params;")
|
||
print(" }")
|
||
print(" ⚠️ 注意: toQueryParameters 没有传 sort 参数!")
|
||
print(" ⚠️ 后端默认 sort=hottest,按浏览量排序")
|
||
print(" ⚠️ hottest 模式下热门内容固定,导致每次返回相同数据!")
|
||
|
||
# 结论
|
||
print("\n" + "=" * 70)
|
||
print("🔍 根因分析")
|
||
print("=" * 70)
|
||
print()
|
||
print("问题: 句子卡片5个句子循环重复,永远不会出现新的")
|
||
print()
|
||
print("根因: FeedMixConfig.toQueryParameters() 没有传 sort 参数,")
|
||
print(" 后端默认 sort=hottest(按浏览量排序),")
|
||
print(" 热门内容排名稳定,导致每次请求返回相同的高浏览量句子。")
|
||
print()
|
||
print("修复方案: FeedMixConfig 添加 sort 字段,默认值 'random' 或 'newest',")
|
||
print(" toQueryParameters() 传入 sort 参数。")
|
||
print()
|
||
print("验证: 如果 hottest 重复率远高于 newest,则确认根因。")
|
||
print(f" hottest 重复率: {1-unique_hottest/total_hottest:.1%}")
|
||
print(f" newest 重复率: {1-unique_newest/total_newest:.1%}")
|