悄悄话留言身份与首页打通:openid 读 hash+query+同源缓存,退出登录算访客;广场/专题页也加缓存兜底 (v26110633)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
deploy
2026-11-07 05:01:16 +00:00
parent 53652c481c
commit 91f29e05c9
5 changed files with 22 additions and 14 deletions

View File

@@ -1007,7 +1007,7 @@ html.night .gtg button.on{background:#F2725B;border-color:#F2725B;color:#fff}
return m ? decodeURIComponent(m[1]).split('?')[0] : ''; return m ? decodeURIComponent(m[1]).split('?')[0] : '';
} catch (e) { return ''; } } catch (e) { return ''; }
} }
var OPENID = (window.mbGate && window.mbGate.out) ? '' : param('openid'); /* 11-07 退出登录后按访客(不拉「我的评论」、不认头像) */ var OPENID = (window.mbGate && window.mbGate.out) ? '' : (param('openid') || (function(){try{var c=JSON.parse(sessionStorage.getItem('mmbox.identity')||'null');return c&&c.openid&&(!c.at||Date.now()-c.at<432e5)?c.openid:'';}catch(e){return '';}})()); /* 11-07 URL 没带身份时用首页存的同源缓存(同 wx-auth.js identity) */ /* 11-07 退出登录后按访客(不拉「我的评论」、不认头像) */
var MYNAME = param('nickname') || '孕妈'; /* 授权回填的昵称在 hash 里;没有就叫「孕妈」,后面另挂「我」标 */ var MYNAME = param('nickname') || '孕妈'; /* 授权回填的昵称在 hash 里;没有就叫「孕妈」,后面另挂「我」标 */
/* ---------- 头像:沿用首页 assets/img/mom/ 写实头像 ---------- */ /* ---------- 头像:沿用首页 assets/img/mom/ 写实头像 ---------- */
@@ -1053,7 +1053,7 @@ html.night .gtg button.on{background:#F2725B;border-color:#F2725B;color:#fff}
var CMD = null, CMERR = false; var CMD = null, CMERR = false;
/* 头像编码:数字 = av/NNNN.webp(旧代码头像);'av:c012' = av/c012.webp(卡通/可爱卡通);'/…' = 站内绝对路径(内置头像库 /_bridge/avatars/);其余 = assets/img/mom/xxx.jpg */ /* 头像编码:数字 = av/NNNN.webp(旧代码头像);'av:c012' = av/c012.webp(卡通/可爱卡通);'/…' = 站内绝对路径(内置头像库 /_bridge/avatars/);其余 = assets/img/mom/xxx.jpg */
var avP = function (a) { return typeof a === 'number' ? 'av/' + ('000' + a).slice(-4) + '.webp' : a.indexOf('av:') === 0 ? 'av/' + a.slice(3) + '.webp' : a.charAt(0) === '/' ? a : '../assets/img/mom/' + a + '.jpg'; }; var avP = function (a) { return typeof a === 'number' ? 'av/' + ('000' + a).slice(-4) + '.webp' : a.indexOf('av:') === 0 ? 'av/' + a.slice(3) + '.webp' : a.charAt(0) === '/' ? a : '../assets/img/mom/' + a + '.jpg'; };
fetch('cm.json?v=26110632').then(function (r) { return r.json(); }).then(function (j) { fetch('cm.json?v=26110633').then(function (r) { return r.json(); }).then(function (j) {
CMD = j; if (openId && NBY[openId]) { renderComments(NBY[openId]); syncBar(NBY[openId]); } CMD = j; if (openId && NBY[openId]) { renderComments(NBY[openId]); syncBar(NBY[openId]); }
}).catch(function () { CMERR = true; if (openId && NBY[openId]) renderComments(NBY[openId]); }); }).catch(function () { CMERR = true; if (openId && NBY[openId]) renderComments(NBY[openId]); });
function commentsOf(n) { function commentsOf(n) {

View File

@@ -9,10 +9,10 @@
<title>兜爸心选 · 孕育陪伴</title> <title>兜爸心选 · 孕育陪伴</title>
<!-- 11-04 UGC 总开关(孕妈广场 + 测一测,后台 /box_bm/plaza 顶部切换),见 js/ugc.js --> <!-- 11-04 UGC 总开关(孕妈广场 + 测一测,后台 /box_bm/plaza 顶部切换),见 js/ugc.js -->
<script src="js/ugc.js?v=26110487"></script> <script src="js/ugc.js?v=26110487"></script>
<!-- V:26110632 缓存版本标记:改 css/js 时同步 bump 该值(与 js/app.js 的 VER 同源),静态资源按 mtime 走 ETag 自动刷新 --> <!-- V:26110633 缓存版本标记:改 css/js 时同步 bump 该值(与 js/app.js 的 VER 同源),静态资源按 mtime 走 ETag 自动刷新 -->
<link rel="stylesheet" href="mama-box.css"> <link rel="stylesheet" href="mama-box.css">
<link rel="stylesheet" href="night.css?v=26110608"> <link rel="stylesheet" href="night.css?v=26110608">
<link rel="stylesheet" href="js/wh-cm.css?v=26110632"> <link rel="stylesheet" href="js/wh-cm.css?v=26110633">
<!-- 11-04 用户:「顶部图片上的倒计时先删除掉」→ 不加载 hero-cd.css / hero-cd.js(文件留着,加回这两行即恢复),头图回到原样式 --> <!-- 11-04 用户:「顶部图片上的倒计时先删除掉」→ 不加载 hero-cd.css / hero-cd.js(文件留着,加回这两行即恢复),头图回到原样式 -->
<!-- 夜晚模式:首屏绘制前就按上次的选择加 class,避免先白后黑闪一下(开关在首页右上角 #nightBtn,逻辑见 app.js) --> <!-- 夜晚模式:首屏绘制前就按上次的选择加 class,避免先白后黑闪一下(开关在首页右上角 #nightBtn,逻辑见 app.js) -->
<script>try{if(localStorage.getItem('mmbox.night.v1')==='1'){document.documentElement.classList.add('night');document.querySelector('meta[name=theme-color]').content='#2A2340'}}catch(e){}</script> <script>try{if(localStorage.getItem('mmbox.night.v1')==='1'){document.documentElement.classList.add('night');document.querySelector('meta[name=theme-color]').content='#2A2340'}}catch(e){}</script>
@@ -2680,7 +2680,7 @@ html.night .rs-pan .rp-card{background:rgba(255,255,255,.06);border-color:rgba(2
<script src="guangchang/topics.js?v=26110487"></script> <script src="guangchang/topics.js?v=26110487"></script>
<script src="js/ava-pool.js?v=26110487"></script> <!-- 11-05 装饰头像分配表(各模块互不重复) --> <script src="js/ava-pool.js?v=26110487"></script> <!-- 11-05 装饰头像分配表(各模块互不重复) -->
<script src="js/wh-themes.js?v=26110609"></script> <script src="js/wh-themes.js?v=26110609"></script>
<script src="js/wh-cm.js?v=26110632" defer></script> <script src="js/wh-cm.js?v=26110633" defer></script>
<script src="js/app.js"></script> <script src="js/app.js"></script>
<script src="js/kit.js?v=26110605"></script> <script src="js/kit.js?v=26110605"></script>
<!-- 11-05 用户:孕期百问加上跟趣味小测试一样的底部 Tab(孕期百问 / 记一下 / 返回首页)。挂在 #detailQA 里,面板关着时跟着滑出屏外; <!-- 11-05 用户:孕期百问加上跟趣味小测试一样的底部 Tab(孕期百问 / 记一下 / 返回首页)。挂在 #detailQA 里,面板关着时跟着滑出屏外;

View File

@@ -3,7 +3,7 @@
(function () { (function () {
'use strict'; 'use strict';
/* 页面版本号(YYMMDD+序号):显示在「关于兜爸心选」页底部;bump 时同步 head 注释与 ?v= */ /* 页面版本号(YYMMDD+序号):显示在「关于兜爸心选」页底部;bump 时同步 head 注释与 ?v= */
var VER = '26110632'; var VER = '26110633';
const $ = (s, c) => (c || document).querySelector(s); const $ = (s, c) => (c || document).querySelector(s);
const $$ = (s, c) => Array.from((c || document).querySelectorAll(s)); const $$ = (s, c) => Array.from((c || document).querySelectorAll(s));

View File

@@ -18,7 +18,15 @@
if (!page || !bar || !window.MB_WH_THEME) return; if (!page || !bar || !window.MB_WH_THEME) return;
var TH = MB_WH_THEME(), PID = 'wh-' + TH.from.replace(/-/g, ''); var TH = MB_WH_THEME(), PID = 'wh-' + TH.from.replace(/-/g, '');
var esc = function (s) { return String(s == null ? '' : s).replace(/[&<>"']/g, function (c) { return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c]; }); }; var esc = function (s) { return String(s == null ? '' : s).replace(/[&<>"']/g, function (c) { return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c]; }); };
var m = ((location.hash || '') + '&').match(/[#&]openid=([^&]*)/), OID = m ? decodeURIComponent(m[1]) : ''; /* 11-07 修:原来只读 hash 里的 openid —— 小程序里身份常在 query 或同源缓存里(应用间跳回、转发卡片落地),
首页显示已登录、这里却提示「登录后就能留言」。改成和首页 hashParam 同一套:hash + query → wxAuth 同源缓存,退出登录算访客;每次用时现读。 */
function oid() {
if (window.mbGate && window.mbGate.out) return '';
var h = (location.hash.slice(1) || '') + '&' + (location.search.slice(1) || ''), m = h.match(/(?:^|[&#])openid=([^&#]*)/);
var v = m ? decodeURIComponent(m[1]).split('?')[0] : '';
if (!v) try { var id = window.wxAuth && wxAuth.identity ? wxAuth.identity() : null; v = id && id.openid || ''; } catch (e) {}
return v;
}
var HEART = '<svg viewBox="0 0 24 24"><path d="M12 20.5s-7.5-4.6-7.5-10.2A4.3 4.3 0 0112 7.6a4.3 4.3 0 017.5 2.7c0 5.6-7.5 10.2-7.5 10.2z"/></svg>'; var HEART = '<svg viewBox="0 0 24 24"><path d="M12 20.5s-7.5-4.6-7.5-10.2A4.3 4.3 0 0112 7.6a4.3 4.3 0 017.5 2.7c0 5.6-7.5 10.2-7.5 10.2z"/></svg>';
var WC = (location.search.match(/[?&]wc=([A-Za-z0-9]{1,40})/) || [])[1] || ''; /* 别人转发来请我点赞的那条 */ var WC = (location.search.match(/[?&]wc=([A-Za-z0-9]{1,40})/) || [])[1] || ''; /* 别人转发来请我点赞的那条 */
@@ -61,7 +69,7 @@
function repOf(c, me) { return { p: c.parent, n: me ? '我' : (c.nickname || '孕妈'), me: me, to: c.parentName, t: c.text, ts: c.at, st: me ? c.status : '' }; } function repOf(c, me) { return { p: c.parent, n: me ? '我' : (c.nickname || '孕妈'), me: me, to: c.parentName, t: c.text, ts: c.at, st: me ? c.status : '' }; }
function load() { function load() {
if (loading || SIM) return; loading = true; if (loading || SIM) return; loading = true;
fetch('guangchang/cm.json?v=26110632').then(function (r) { return r.json(); }).then(function (j) { fetch('guangchang/cm.json?v=26110633').then(function (r) { return r.json(); }).then(function (j) {
var PP = j.p; var PP = j.p;
SIM = (j.c[PID] || []).map(function (c, k) { SIM = (j.c[PID] || []).map(function (c, k) {
var p = PP[c[0]]; var p = PP[c[0]];
@@ -73,7 +81,7 @@
fetchReal(); fetchReal();
} }
function fetchReal() { function fetchReal() {
return fetch('/api/mp/public/mama-box/plaza/comments?kind=post&target=' + encodeURIComponent(PID) + (OID ? '&openid=' + encodeURIComponent(OID) : '')) return fetch('/api/mp/public/mama-box/plaza/comments?kind=post&target=' + encodeURIComponent(PID) + (oid() ? '&openid=' + encodeURIComponent(oid()) : ''))
.then(function (r) { return r.json(); }).then(function (j) { .then(function (r) { return r.json(); }).then(function (j) {
var R = j && j.code === 200 && j.result || {}; var R = j && j.code === 200 && j.result || {};
if (R.starLikes) STAR_N = R.starLikes; if (R.starLikes) STAR_N = R.starLikes;
@@ -247,11 +255,11 @@
return; return;
} }
/* 真实留言:服务端计数,赞了就不能取消(同星星的抱抱) */ /* 真实留言:服务端计数,赞了就不能取消(同星星的抱抱) */
if (!OID) { toast('登录后就能点赞啦'); return; } if (!oid()) { toast('登录后就能点赞啦'); return; }
if (c.liked) { toast('你已经赞过啦'); return; } if (c.liked) { toast('你已经赞过啦'); return; }
c.liked = true; c.likes++; paintLk(b, c); b.classList.add('pop'); setTimeout(function () { b.classList.remove('pop'); }, 500); c.liked = true; c.likes++; paintLk(b, c); b.classList.add('pop'); setTimeout(function () { b.classList.remove('pop'); }, 500);
if (navigator.vibrate) navigator.vibrate(8); if (navigator.vibrate) navigator.vibrate(8);
fetch('/api/mp/public/mama-box/plaza/comment/like?openid=' + encodeURIComponent(OID) + '&id=' + encodeURIComponent(c.id), { method: 'POST' }) fetch('/api/mp/public/mama-box/plaza/comment/like?openid=' + encodeURIComponent(oid()) + '&id=' + encodeURIComponent(c.id), { method: 'POST' })
.then(function (x) { return x.json(); }).then(function (j) { .then(function (x) { return x.json(); }).then(function (j) {
if (!j || j.code !== 200) throw j; if (!j || j.code !== 200) throw j;
c.likes = j.result.likes; var was = c.star; c.star = !!j.result.star; paintLk(b, c); c.likes = j.result.likes; var was = c.star; c.star = !!j.result.star; paintLk(b, c);
@@ -266,10 +274,10 @@
}); });
function post(text, week, reply) { function post(text, week, reply) {
if (!OID) return Promise.resolve('登录后就能留言啦'); if (!oid()) return Promise.resolve('登录后就能留言啦');
var body = { kind: 'post', target: PID, title: '孕妈悄悄话 · ' + TH.name, text: text, stage: week ? '孕 ' + week + ' 周' : '' }; var body = { kind: 'post', target: PID, title: '孕妈悄悄话 · ' + TH.name, text: text, stage: week ? '孕 ' + week + ' 周' : '' };
if (reply) { body.parent = reply.key; body.parentName = reply.n; } if (reply) { body.parent = reply.key; body.parentName = reply.n; }
return fetch('/api/mp/public/mama-box/plaza/comment?openid=' + encodeURIComponent(OID), { return fetch('/api/mp/public/mama-box/plaza/comment?openid=' + encodeURIComponent(oid()), {
method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body)
}).then(function (r) { return r.json(); }).then(function (j) { }).then(function (r) { return r.json(); }).then(function (j) {
if (!j || j.code !== 200 || !j.result) return (j && j.message) || '没发出去,再试一次'; if (!j || j.code !== 200 || !j.result) return (j && j.message) || '没发出去,再试一次';

View File

@@ -65,7 +65,7 @@
if (SLUG) (function () { var s = document.createElement('script'); s.src = '../../js/share-card.js?v=26110464'; s.onload = function () { window.mbShare('../../assets/share/t/' + SLUG + '.jpg'); }; document.head.appendChild(s); })(); if (SLUG) (function () { var s = document.createElement('script'); s.src = '../../js/share-card.js?v=26110464'; s.onload = function () { window.mbShare('../../assets/share/t/' + SLUG + '.jpg'); }; document.head.appendChild(s); })();
/* 11-07 退出登录后只看不写(js/login-gate.js):点赞、评论、发图都弹「登录后才能使用」 */ /* 11-07 退出登录后只看不写(js/login-gate.js):点赞、评论、发图都弹「登录后才能使用」 */
if (!window.mbGate) (function () { var s = document.createElement('script'); s.src = '../../js/login-gate.js?v=26110610'; document.head.appendChild(s); })(); if (!window.mbGate) (function () { var s = document.createElement('script'); s.src = '../../js/login-gate.js?v=26110610'; document.head.appendChild(s); })();
var SK = 'mmbox.tp.v1', UK = (function () { var m = ((location.hash || '') + '&' + (location.search || '')).match(/[#?&]openid=([^&]*)/); return m ? decodeURIComponent(m[1]) : '_guest'; })(); var SK = 'mmbox.tp.v1', UK = (function () { var m = ((location.hash || '') + '&' + (location.search || '')).match(/[#?&]openid=([^&]*)/); return m ? decodeURIComponent(m[1]).split('?')[0] : ((function(){try{var c=JSON.parse(sessionStorage.getItem('mmbox.identity')||'null');return c&&c.openid&&(!c.at||Date.now()-c.at<432e5)?c.openid:'';}catch(e){return '';}})() || '_guest'); })(); /* 11-07 URL 没带身份时用首页存的同源缓存 */
function loadMe() { try { var a = JSON.parse(localStorage.getItem(SK) || '{}') || {}; var m = a[UK] || {}; m.cm = m.cm || {}; m.lk = m.lk || {}; return { a: a, m: m }; } catch (e) { return { a: {}, m: { cm: {}, lk: {} } }; } } function loadMe() { try { var a = JSON.parse(localStorage.getItem(SK) || '{}') || {}; var m = a[UK] || {}; m.cm = m.cm || {}; m.lk = m.lk || {}; return { a: a, m: m }; } catch (e) { return { a: {}, m: { cm: {}, lk: {} } }; } }
function saveMe(st) { try { st.a[UK] = st.m; localStorage.setItem(SK, JSON.stringify(st.a)); } catch (e) {} } function saveMe(st) { try { st.a[UK] = st.m; localStorage.setItem(SK, JSON.stringify(st.a)); } catch (e) {} }
/* 11-02 用户:自己发的评论带上孕周(首页写进 mmbox.gcwk.v1) */ /* 11-02 用户:自己发的评论带上孕周(首页写进 mmbox.gcwk.v1) */