- 移除多个文件中的无用参数如sortOrder、keyword、limit等 - 优化日期处理逻辑,使用DateTime(year)替代DateTime(year,1,1) - 修复颜色和边框样式的一致性 - 更新API调用参数,移除冗余的limit和page参数 - 新增SessionPopupMenu组件和ChatSession模型 - 优化笔记模型的时间显示和类型转换 - 修复验证码发送逻辑和加载状态 - 更新文档和脚本文件
137 lines
4.8 KiB
Python
137 lines
4.8 KiB
Python
# ============================================================
|
|
# 闲言APP — 句子卡片修复后数据流验证
|
|
# 创建时间: 2026-05-01
|
|
# 作用: 验证修复后 fetchMix+sort=newest 的数据唯一性
|
|
# ============================================================
|
|
|
|
import requests
|
|
import json
|
|
import time
|
|
|
|
BASE = "https://tools.wktyl.com"
|
|
|
|
def fetch_mix(mode="random", limit=5, channels=None, sort="newest"):
|
|
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" ❌ 请求失败: {e}")
|
|
return []
|
|
|
|
def make_id(item):
|
|
return f"{item.get('feed_type','?')}_{item.get('id')}"
|
|
|
|
print("=" * 70)
|
|
print("验证1: 修复后 fetchMix(mode=random, sort=newest) 数据唯一性")
|
|
print("=" * 70)
|
|
|
|
all_ids = []
|
|
for i in range(10):
|
|
items = fetch_mix(mode="random", limit=5, sort="newest")
|
|
ids = [make_id(item) for item in items]
|
|
all_ids.extend(ids)
|
|
print(f" 第{i+1}次: {ids}")
|
|
time.sleep(0.3)
|
|
|
|
unique = len(set(all_ids))
|
|
total = len(all_ids)
|
|
print(f"\n 📊 总ID数={total}, 去重后={unique}, 重复率={1-unique/total:.1%}")
|
|
print(f" ✅ 修复后API每次返回不同数据" if unique == total else f" ❌ 仍有重复!")
|
|
|
|
print("\n" + "=" * 70)
|
|
print("验证2: 模拟修复后 refreshDailySentences 完整流程")
|
|
print("=" * 70)
|
|
|
|
existing_ids = set()
|
|
for i in range(5):
|
|
items = fetch_mix(mode="random", limit=5, sort="newest")
|
|
if not items:
|
|
print(f" 第{i+1}轮: ❌ API返回空")
|
|
continue
|
|
|
|
daily_list = [make_id(item) for item in items]
|
|
unique = [sid for sid in daily_list if sid not in existing_ids]
|
|
|
|
if not unique and existing_ids:
|
|
retry_items = fetch_mix(mode="random", limit=15, sort="newest")
|
|
if retry_items:
|
|
retry_list = [make_id(item) for item in retry_items]
|
|
unique = [sid for sid in retry_list if sid not in existing_ids]
|
|
|
|
final_list = unique if unique else daily_list
|
|
existing_ids = set(final_list)
|
|
|
|
overlap = set(daily_list) & set([sid for sid in existing_ids if sid in daily_list])
|
|
print(f" 第{i+1}轮: API={daily_list}, unique={len(unique)}, final={len(final_list)}")
|
|
|
|
print(f"\n 📊 5轮后共看到 {len(existing_ids)} 个不同句子")
|
|
|
|
print("\n" + "=" * 70)
|
|
print("验证3: 对比修复前(sort=hottest) vs 修复后(sort=newest)")
|
|
print("=" * 70)
|
|
|
|
for sort_mode in ["hottest", "newest"]:
|
|
ids_set = []
|
|
for i in range(5):
|
|
items = fetch_mix(mode="random", limit=5, sort=sort_mode)
|
|
ids = [make_id(item) for item in items]
|
|
ids_set.extend(ids)
|
|
time.sleep(0.2)
|
|
unique = len(set(ids_set))
|
|
total = len(ids_set)
|
|
rate = 1 - unique/total
|
|
status = "❌ 高重复" if rate > 0.3 else "✅ 低重复"
|
|
print(f" sort={sort_mode:8s}: 总={total}, 去重={unique}, 重复率={rate:.1%} {status}")
|
|
|
|
print("\n" + "=" * 70)
|
|
print("验证4: mode=specific + sort=newest 数据变化性")
|
|
print("=" * 70)
|
|
|
|
all_ids = []
|
|
for i in range(5):
|
|
items = fetch_mix(mode="specific", limit=5,
|
|
channels=["poetry", "wisdom", "story"],
|
|
sort="newest")
|
|
ids = [make_id(item) for item in items]
|
|
all_ids.extend(ids)
|
|
print(f" 第{i+1}次: {ids}")
|
|
time.sleep(0.3)
|
|
|
|
unique = len(set(all_ids))
|
|
total = len(all_ids)
|
|
print(f" 📊 总ID={total}, 去重={unique}, 重复率={1-unique/total:.1%}")
|
|
|
|
print("\n" + "=" * 70)
|
|
print("📋 修复总结")
|
|
print("=" * 70)
|
|
print()
|
|
print("修复内容:")
|
|
print(" 1. FeedMixConfig 添加 sort 字段, 默认 'newest'")
|
|
print(" - 修复前: 不传sort → 后端默认hottest → 热门数据固定")
|
|
print(" - 修复后: 传sort=newest → 每次获取最新数据")
|
|
print()
|
|
print(" 2. refreshDailySentences 添加防重入锁")
|
|
print(" - 防止并发调用导致竞态条件")
|
|
print()
|
|
print(" 3. _fetchDailySentence 初始化不再使用existingIds过滤")
|
|
print(" - 初始化时直接使用API返回的数据")
|
|
print(" - refreshDailySentences 保留去重逻辑确保新内容")
|
|
print()
|
|
print(" 4. DailyCard 只在onEnd时触发onLoadMore")
|
|
print(" - 修复前: 每3次滑动就刷新 → 中途重建CardSwiper")
|
|
print(" - 修复后: 滑完所有卡片才刷新 → 体验更流畅")
|
|
print()
|
|
print(" 5. didUpdateWidget 始终重置卡片状态")
|
|
print(" - 修复前: hasNewContent为false时不重置 → 加载态卡死")
|
|
print(" - 修复后: 始终重置_dataVersion/_frontCardIndex/_allCardsSwiped")
|
|
print()
|
|
print(" 6. refresh() 清空dailySentences")
|
|
print(" - 修复前: refresh不清空 → _fetchDailySentence用旧ID过滤")
|
|
print(" - 修复后: clearDaily=true → 确保获取全新数据")
|