pv.js 同时上报数胎动后台(app_id=mama-box,仅正式站)(v26110652)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
/* 页面版本号(YYMMDD+序号):显示在「关于兜爸心选」页底部;bump 时同步 head 注释与 ?v= */
|
||||
var VER = '26110651';
|
||||
var VER = '26110652';
|
||||
const $ = (s, c) => (c || document).querySelector(s);
|
||||
const $$ = (s, c) => Array.from((c || document).querySelectorAll(s));
|
||||
|
||||
|
||||
76
js/pv.js
76
js/pv.js
@@ -5,7 +5,12 @@
|
||||
一次「看一页」= 一个 visitId:进来 0.8 秒后报一条(停留 0),之后每 15 秒、切到后台、离开时报一次停留时长(只算页面在前台的时间)。
|
||||
同一页里换内容也算新的一页:广场切笔记 / 话题 / 分类(pushState)、首页开关星空页(replaceState ?wh=1)—— 这里接管 history 自动识别,页面不用改。
|
||||
首页 + 孕妈广场 + 测一测 + 专题页 / 计算器都引本文件(和 js/last-sub.js 放一起);新子页面记得加 script。
|
||||
预览站 / 正式站由后端按路径分(/mama-box-preview/ → preview),这里不管。 */
|
||||
预览站 / 正式站由后端按路径分(/mama-box-preview/ → preview),这里不管。
|
||||
|
||||
11-07 同时报一份给数胎动后台(taidong.douba.top/admin「当天用户 / 全部用户」看每人逛了哪些页,375797cf 接的,app_id=mama-box):
|
||||
openid-login 拿令牌(存 sessionStorage)→ events/open 报一次进站(visit_id 同一会话共用,30 分钟没动静算新一次)
|
||||
→ 每离开一页 / 切到后台报一条 events(path /mama-box/…、中文 title、这段前台停留);每次离开页面再报一条不带 title 的
|
||||
「整次停留」(累计值,对方取最新)。只在有 openid、没退出登录时报;预览站不报(不混进正式数据)。 */
|
||||
(function () {
|
||||
'use strict';
|
||||
if (window.__mbPV) return;
|
||||
@@ -80,6 +85,65 @@
|
||||
}
|
||||
function vid() { return Date.now().toString(36) + Math.random().toString(36).slice(2, 10) + Math.random().toString(36).slice(2, 6); }
|
||||
|
||||
/* ---- 数胎动后台 ---- */
|
||||
var TD = '/taidong/api/', TD_ON = /^\/mama-box-v2\//.test(location.pathname) || (function () { try { return localStorage.getItem('mmbox.tdtest') === '1'; } catch (e) { return false; } })() /* 预览自测:本机手动置 mmbox.tdtest=1 才报 */, TDK = 'mmbox.td.v1';
|
||||
function tdState() {
|
||||
var st = null;
|
||||
try { st = JSON.parse(sessionStorage.getItem(TDK) || 'null'); } catch (e) {}
|
||||
var now = Date.now();
|
||||
if (!st || now - (st.seen || 0) > 30 * 60000) st = { vid: 'mb-' + now + '-' + Math.random().toString(36).slice(2, 8), start: now, acc: 0, opened: 0, tok: st && st.tok, oid: st && st.oid };
|
||||
st.seen = now;
|
||||
return st;
|
||||
}
|
||||
function tdSave(st) { try { sessionStorage.setItem(TDK, JSON.stringify(st)); } catch (e) {} }
|
||||
var tdTok = null;
|
||||
function tdToken() {
|
||||
if (!TD_ON) return Promise.resolve('');
|
||||
var w = who();
|
||||
if (!w.openid) return Promise.resolve('');
|
||||
var st = tdState();
|
||||
if (st.tok && st.oid === w.openid) return Promise.resolve(st.tok);
|
||||
if (tdTok) return tdTok;
|
||||
tdTok = fetch(TD + 'auth/openid-login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ app_id: 'mama-box', openid: w.openid, unionid: w.unionid || undefined }) })
|
||||
.then(function (r) { return r.json(); }).then(function (j) {
|
||||
var t = j && (j.token || (j.data && j.data.token)) || '';
|
||||
var s2 = tdState(); s2.tok = t; s2.oid = w.openid; tdSave(s2);
|
||||
return t;
|
||||
}).catch(function () { return ''; }).then(function (t) { tdTok = null; return t; });
|
||||
return tdTok;
|
||||
}
|
||||
function tdPost(path, body, tok) {
|
||||
if (!tok) return;
|
||||
try { fetch(TD + path, { method: 'POST', keepalive: true, headers: { 'Content-Type': 'application/json', Authorization: 'Bearer ' + tok }, body: JSON.stringify(body) }).catch(function () {}); } catch (e) {}
|
||||
}
|
||||
function tdTitle(r) {
|
||||
var t = r.page === 'home' ? '首页' : r.page === 'whisper' ? '孕妈悄悄话 · 星空页'
|
||||
: r.page === 'plaza/note' ? '帖子详情 · ' + (r.noteTitle || r.noteId)
|
||||
: r.page === 'plaza/topic' ? '话题 · ' + (r.topicTitle || r.topicId)
|
||||
: r.page === 'ceshi/test' ? '测一测 · ' + (r.testTitle || r.testId)
|
||||
: r.group === 'topic' ? '专题 · ' + r.title
|
||||
: String(r.title || '').replace('·', ' · ');
|
||||
return t.slice(0, 40);
|
||||
}
|
||||
function tdOpen() {
|
||||
tdToken().then(function (tok) {
|
||||
var st = tdState();
|
||||
if (!tok || st.opened) { tdSave(st); return; }
|
||||
st.opened = 1; tdSave(st);
|
||||
tdPost('events/open', { visit_id: st.vid, page: '/mama-box/', src: param('src') }, tok);
|
||||
});
|
||||
}
|
||||
/* 一段前台停留结束(离开这一页 / 切到后台):报这一页 + 整次累计 */
|
||||
function tdSeg(c, ms, leaving) {
|
||||
if (!TD_ON || !c || ms < 300) return;
|
||||
var st = tdState(); st.acc += ms; tdSave(st);
|
||||
var r = c.full || c.r, path = '/mama-box/' + (r.page === 'home' ? '' : r.page === 'whisper' ? 'whisper' : location.pathname.replace(/^\/[^/]+\//, '').replace(/index\.html$/, '').replace(/\/$/, ''));
|
||||
var ev = { visit_id: st.vid, path: path.replace(/\/$/, '') || '/mama-box/', title: tdTitle(r), duration_ms: ms, entered_at: c.segAt };
|
||||
if (ev.path === '/mama-box') ev.path = '/mama-box/';
|
||||
var site = { visit_id: st.vid, path: '/mama-box/', duration_ms: st.acc };
|
||||
tdToken().then(function (tok) { tdPost('events', ev, tok); if (leaving) tdPost('events', site, tok); });
|
||||
}
|
||||
|
||||
var cur = null, timer = 0;
|
||||
function dur() {
|
||||
if (!cur) return 0;
|
||||
@@ -98,7 +162,7 @@
|
||||
var r = where(); /* 晚 0.8 秒再取:专题页 / 测试页的标题、广场数据那时才就绪 */
|
||||
if (r.key !== c.r.key) r = c.r;
|
||||
var w = who();
|
||||
c.sent = true;
|
||||
c.sent = true; c.full = r;
|
||||
send({
|
||||
visitId: c.id, openid: w.openid, unionid: w.unionid, page: r.page, pageGroup: r.group, pageTitle: r.title,
|
||||
noteId: r.noteId || '', noteTitle: r.noteTitle || '', topicId: r.topicId || '', topicTitle: r.topicTitle || '',
|
||||
@@ -107,6 +171,7 @@
|
||||
}
|
||||
function close() {
|
||||
if (!cur) return;
|
||||
if (cur.shownAt) tdSeg(cur, Date.now() - cur.segAt, true);
|
||||
if (cur.sent) beat(); else if (dur() >= 800) first(cur);
|
||||
cur = null;
|
||||
}
|
||||
@@ -114,7 +179,7 @@
|
||||
var r = where();
|
||||
if (cur && cur.r.key === r.key) return;
|
||||
close();
|
||||
var c = cur = { id: vid(), r: r, at: Date.now(), acc: 0, shownAt: document.hidden ? 0 : Date.now(), sent: false, lastDur: 0 };
|
||||
var c = cur = { id: vid(), r: r, at: Date.now(), segAt: Date.now(), acc: 0, shownAt: document.hidden ? 0 : Date.now(), sent: false, lastDur: 0 };
|
||||
setTimeout(function () { first(c); }, 800);
|
||||
}
|
||||
|
||||
@@ -126,12 +191,13 @@
|
||||
window.addEventListener('popstate', function () { setTimeout(open, 0); });
|
||||
document.addEventListener('visibilitychange', function () {
|
||||
if (!cur) return;
|
||||
if (document.hidden) { if (cur.shownAt) { cur.acc += Date.now() - cur.shownAt; cur.shownAt = 0; } beat(); }
|
||||
else if (!cur.shownAt) cur.shownAt = Date.now();
|
||||
if (document.hidden) { if (cur.shownAt) { cur.acc += Date.now() - cur.shownAt; tdSeg(cur, Date.now() - cur.segAt, true); cur.shownAt = 0; } beat(); }
|
||||
else if (!cur.shownAt) { cur.shownAt = cur.segAt = Date.now(); tdOpen(); }
|
||||
});
|
||||
window.addEventListener('pagehide', close);
|
||||
window.addEventListener('pageshow', function (e) { if (e.persisted) open(); }); /* 从后退缓存回来 = 又看一次 */
|
||||
timer = setInterval(function () { if (!document.hidden) beat(); }, BEAT);
|
||||
|
||||
open();
|
||||
if (TD_ON) tdOpen();
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user