feat(site): 方案 C - 「我常访问」个人榜(匿名 ID + localStorage 合并)
- NavClick 加 anon_id 字段(已为历史表自动迁移) - 后端静默下发 wk_anon cookie(uuid4,1 年,HttpOnly) - 点击埋点写入 anon_id;新增 GET /site/api/my-top 与 POST /site/api/my-clear - 首页服务端渲染「我常访问」区(时间衰减加权分),与「热门网址」共显 - 前端 localStorage 累计 + 与服务端榜取 max 合并;冷启动阈值 2 个网址 - 一键清除:清 localStorage + 服务端删该匿名 ID 的全部记录 - 移动端抽屉、顶部导航同步加「我常访问」入口 - 底部隐私说明更新
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
"""验证「我常访问」:服务端匿名榜 + localStorage 合并 + 清除按钮。
|
||||
|
||||
用法:先启动 Flask(python app.py),再 PYTHONPATH=. python scripts/verify_mine_section.py
|
||||
"""
|
||||
from playwright.sync_api import sync_playwright
|
||||
|
||||
BASE = 'http://127.0.0.1:5000'
|
||||
LS_KEY = 'wk_mine_clicks'
|
||||
|
||||
with sync_playwright() as p:
|
||||
browser = p.chromium.launch()
|
||||
ctx = browser.new_context(viewport={'width': 1280, 'height': 900})
|
||||
page = ctx.new_page()
|
||||
|
||||
# ---- 1) 全新访客:没有点击记录,不该出现个人区 ----
|
||||
page.goto(BASE + '/site/', wait_until='networkidle')
|
||||
print('1) 新访客 #cat-mine 存在:', page.locator('#cat-mine').count())
|
||||
anon = [c for c in ctx.cookies() if c['name'] == 'wk_anon']
|
||||
print(' 匿名 cookie:', (anon[0]['value'][:8] + '...') if anon else '无')
|
||||
|
||||
# 取页面上真实存在的几个 nav id
|
||||
ids = page.eval_on_selector_all(
|
||||
'.section:not(#cat-mine) .card[data-nav-id]',
|
||||
'els => els.slice(0, 5).map(e => e.getAttribute("data-nav-id"))'
|
||||
)
|
||||
print(' 可用 nav id:', ids)
|
||||
|
||||
# ---- 2) 只写 localStorage(模拟 cookie 被禁 / 服务端还没同步)----
|
||||
page.evaluate(
|
||||
"""([k, a, b]) => localStorage.setItem(k, JSON.stringify({[a]: 4, [b]: 2}))""",
|
||||
[LS_KEY, ids[0], ids[1]]
|
||||
)
|
||||
page.reload(wait_until='networkidle')
|
||||
n = page.locator('#cat-mine .card').count()
|
||||
print('2) localStorage 驱动后 #cat-mine 卡片数:', n)
|
||||
print(' 顶部导航入口:', page.locator('.cat-nav-mine').count(),
|
||||
'| 抽屉入口:', page.locator('.cat-drawer-mine').count())
|
||||
if n:
|
||||
print(' 首卡文案:', page.locator('#cat-mine .card').first.inner_text().replace('\n', ' | ')[:90])
|
||||
|
||||
# ---- 3) 只点 1 个网址:冷启动阈值,不该展示 ----
|
||||
page.evaluate("k => localStorage.setItem(k, JSON.stringify({}))", LS_KEY)
|
||||
page.reload(wait_until='networkidle')
|
||||
print('3) 清空 localStorage 后 #cat-mine 可见:',
|
||||
page.locator('#cat-mine').count() and page.locator('#cat-mine').is_visible())
|
||||
|
||||
# ---- 4) 清除按钮 ----
|
||||
page.evaluate(
|
||||
"""([k, a, b]) => localStorage.setItem(k, JSON.stringify({[a]: 3, [b]: 1}))""",
|
||||
[LS_KEY, ids[0], ids[1]]
|
||||
)
|
||||
page.reload(wait_until='networkidle')
|
||||
print('4) 清除前 #cat-mine 数:', page.locator('#cat-mine').count())
|
||||
clears = []
|
||||
page.on('request', lambda r: clears.append(r.url) if '/site/api/my-clear' in r.url else None)
|
||||
page.locator('#clear-mine').first.click()
|
||||
page.wait_for_timeout(600)
|
||||
print(' 清除后 #cat-mine 数:', page.locator('#cat-mine').count(),
|
||||
'| localStorage:', page.evaluate("k => localStorage.getItem(k)", LS_KEY),
|
||||
'| 请求:', clears)
|
||||
|
||||
browser.close()
|
||||
print('DONE')
|
||||
Reference in New Issue
Block a user