v26110459 广场帖子 / 专题页评论和回复可带图(最多 3 张,审核后公开)

This commit is contained in:
deploy
2026-11-05 09:50:56 +00:00
parent 4d1e5e95f1
commit 565a13eb60
26 changed files with 261 additions and 127 deletions

View File

@@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<!-- 11-04 UGC 总开关关着时本页不展示,直接回首页(js/ugc.js) --> <!-- 11-04 UGC 总开关关着时本页不展示,直接回首页(js/ugc.js) -->
<script src="../../js/ugc.js?v=26110458" data-guard></script> <script src="../../js/ugc.js?v=26110459" data-guard></script>
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover"> <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
<meta name="format-detection" content="telephone=no"> <meta name="format-detection" content="telephone=no">
<title>测一测 · 孕妈广场</title> <title>测一测 · 孕妈广场</title>
@@ -322,9 +322,9 @@ mark{background:linear-gradient(transparent 62%,var(--c20) 0);color:inherit;padd
</div> </div>
<div class="toast" id="toast"></div> <div class="toast" id="toast"></div>
<script src="../../js/share-card.js?v=26110458"></script> <script src="../../js/share-card.js?v=26110459"></script>
<script src="meta.js?v=26110458"></script> <script src="meta.js?v=26110459"></script>
<script src="tests.js?v=26110458"></script> <script src="tests.js?v=26110459"></script>
<script> <script>
(function () { (function () {
'use strict'; 'use strict';

View File

@@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<!-- 11-04 UGC 总开关关着时本页不展示,直接回首页(js/ugc.js) --> <!-- 11-04 UGC 总开关关着时本页不展示,直接回首页(js/ugc.js) -->
<script src="../js/ugc.js?v=26110458" data-guard></script> <script src="../js/ugc.js?v=26110459" data-guard></script>
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover"> <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
<meta name="format-detection" content="telephone=no"> <meta name="format-detection" content="telephone=no">
<title>孕妈广场</title> <title>孕妈广场</title>
@@ -668,6 +668,10 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
.bar .ib.pop .ic{animation:pop .35s ease} .bar .ib.pop .ic{animation:pop .35s ease}
.bar.typing .ib{display:none} .bar.typing .ib{display:none}
.bar:not(.typing) .send{display:none} .bar:not(.typing) .send{display:none}
/* 11-05 评论 / 回复带图(js/cm-pics.js):输入框里加图片按钮,选了图在底栏上方排一行缩略图 */
.bar{position:relative}
#cmPics{position:absolute;left:0;right:0;bottom:100%;padding:8px 14px 6px;background:#fff;border-top:1px solid var(--line)}
#cpic{width:28px;height:28px}
/* ---------- 投稿(11-01:用户可投稿 → 审核中 → 后台通过/不通过 → 下次打开提醒) ---------- */ /* ---------- 投稿(11-01:用户可投稿 → 审核中 → 后台通过/不通过 → 下次打开提醒) ---------- */
.nav .nsp{flex:none;width:36px} .nav .nsp{flex:none;width:36px}
@@ -872,7 +876,8 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
</div> </div>
<div id="dsc"></div> <div id="dsc"></div>
<div class="bar" id="bar"> <div class="bar" id="bar">
<label class="ip"><svg class="ic"><use href="#i-pen"/></svg><input id="cin" type="text" maxlength="200" placeholder="说点什么…" enterkeyhint="send"><button class="send" id="csend" type="button" disabled>发送</button></label> <label class="ip"><svg class="ic"><use href="#i-pen"/></svg><input id="cin" type="text" maxlength="200" placeholder="说点什么…" enterkeyhint="send"><button class="cmp-btn" id="cpic" type="button" aria-label="加图片"></button><button class="send" id="csend" type="button" disabled>发送</button></label>
<div class="cmp-strip" id="cmPics"></div>
<button class="ib lv" id="blk" type="button" aria-label="点赞"><svg class="ic"><use href="#i-heart"/></svg><span></span></button> <button class="ib lv" id="blk" type="button" aria-label="点赞"><svg class="ic"><use href="#i-heart"/></svg><span></span></button>
<button class="ib fv" id="bfv" type="button" aria-label="收藏"><svg class="ic"><use href="#i-star"/></svg><span></span></button> <button class="ib fv" id="bfv" type="button" aria-label="收藏"><svg class="ic"><use href="#i-star"/></svg><span></span></button>
<button class="ib" id="bcm" type="button" aria-label="评论"><svg class="ic"><use href="#i-chat"/></svg><span></span></button> <button class="ib" id="bcm" type="button" aria-label="评论"><svg class="ic"><use href="#i-chat"/></svg><span></span></button>
@@ -895,12 +900,13 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
<div id="sheet" role="dialog" aria-modal="true"><i class="sg"></i><div class="sbd" id="sbd"></div></div> <div id="sheet" role="dialog" aria-modal="true"><i class="sg"></i><div class="sbd" id="sbd"></div></div>
<div class="toast" id="toast"></div> <div class="toast" id="toast"></div>
<script src="topics.js?v=26110458"></script> <script src="topics.js?v=26110459"></script>
<script src="data.js?v=26110458"></script> <script src="data.js?v=26110459"></script>
<script src="feed.js?v=26110458"></script> <script src="feed.js?v=26110459"></script>
<script src="../js/ava-pool.js?v=26110458"></script> <!-- 11-05 装饰头像分配表(各模块互不重复) --> <script src="../js/ava-pool.js?v=26110459"></script> <!-- 11-05 装饰头像分配表(各模块互不重复) -->
<script src="ceshi/meta.js?v=26110458"></script> <script src="ceshi/meta.js?v=26110459"></script>
<script src="../js/share-card.js?v=26110458"></script> <script src="../js/share-card.js?v=26110459"></script>
<script src="../js/cm-pics.js?v=26110459"></script> <!-- 11-05 评论 / 回复带图 -->
<script> <script>
(function () { (function () {
'use strict'; 'use strict';
@@ -967,7 +973,7 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
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=26110458').then(function (r) { return r.json(); }).then(function (j) { fetch('cm.json?v=26110459').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) {
@@ -995,22 +1001,23 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
var RC = {}; var RC = {};
var myCm = function (id) { var myCm = function (id) {
var old = (ME.cm[id] || []).filter(function (c) { return !c.id; }).map(function (c) { return { t: c.t, ts: c.ts, s: c.s, st: 'local' }; }); var old = (ME.cm[id] || []).filter(function (c) { return !c.id; }).map(function (c) { return { t: c.t, ts: c.ts, s: c.s, st: 'local' }; });
var srv = RC[id] ? RC[id].mine.map(function (c) { return { id: c.id, t: c.text, ts: c.at, s: c.stage, st: c.status, why: c.reason, parent: c.parent, to: c.parentName }; }) : []; var srv = RC[id] ? RC[id].mine.map(function (c) { return { id: c.id, t: c.text, ts: c.at, s: c.stage, st: c.status, why: c.reason, parent: c.parent, to: c.parentName, img: c.images }; }) : [];
return old.concat(srv.reverse()); return old.concat(srv.reverse());
}; };
var realCm = function (id) { return RC[id] ? RC[id].list : []; }; var realCm = function (id) { return RC[id] ? RC[id].list : []; };
/* 11-03 用户:可以回复别人的评论。回复也先审核;楼里只有一层,回复回复也挂在同一楼,写「回复 XX」 */ /* 11-03 用户:可以回复别人的评论。回复也先审核;楼里只有一层,回复回复也挂在同一楼,写「回复 XX」 */
var REPLY = null; var REPLY = null;
function extraReplies(id, k) { function extraReplies(id, k) {
var o = realCm(id).filter(function (c) { return c.parent === k; }).map(function (c) { return { n: c.nickname || '孕妈', t: c.text, to: c.parentName, ts: c.at }; }); var o = realCm(id).filter(function (c) { return c.parent === k; }).map(function (c) { return { n: c.nickname || '孕妈', t: c.text, to: c.parentName, ts: c.at, img: c.images }; });
var m = myCm(id).filter(function (c) { return c.parent === k; }).map(function (c) { return { n: MYNAME, me: 1, t: c.t, to: c.to, st: c.st, why: c.why, ts: c.ts }; }); var m = myCm(id).filter(function (c) { return c.parent === k; }).map(function (c) { return { n: MYNAME, me: 1, t: c.t, to: c.to, st: c.st, why: c.why, ts: c.ts, img: c.img }; });
return o.concat(m).sort(function (x, y) { return x.ts - y.ts; }); /* 楼里按时间先后 */ return o.concat(m).sort(function (x, y) { return x.ts - y.ts; }); /* 楼里按时间先后 */
} }
var cpH = function (a) { return window.MBCmPics ? MBCmPics.html(a) : ''; }; /* 11-05 评论里的图 */
function stTag(c) { return c.st === 'pending' ? '<span class="ci-st pending">审核中 · 通过后大家才能看到</span>' : c.st === 'rejected' ? '<span class="ci-st rejected">未通过' + (c.why ? ':' + esc(c.why) : '') + '</span>' : c.st === 'local' ? '<span class="ci-st local">仅自己可见</span>' : ''; } function stTag(c) { return c.st === 'pending' ? '<span class="ci-st pending">审核中 · 通过后大家才能看到</span>' : c.st === 'rejected' ? '<span class="ci-st rejected">未通过' + (c.why ? ':' + esc(c.why) : '') + '</span>' : c.st === 'local' ? '<span class="ci-st local">仅自己可见</span>' : ''; }
function rpHTML(list, k, owner) { function rpHTML(list, k, owner) {
return list.length ? '<div class="rp">' + list.map(function (x) { return list.length ? '<div class="rp">' + list.map(function (x) {
return '<p' + (x.me ? ' class="rme' + (x.st === 'rejected' ? ' rej' : '') + '"' : ' data-rk="' + esc(k) + '" data-rn="' + esc(x.n) + '"') + '><b>' + esc(x.n) + '</b>' + (x.au ? '<span class="au">作者</span>' : '') + (x.me ? '<span class="au me">我</span>' : '') + return '<p' + (x.me ? ' class="rme' + (x.st === 'rejected' ? ' rej' : '') + '"' : ' data-rk="' + esc(k) + '" data-rn="' + esc(x.n) + '"') + '><b>' + esc(x.n) + '</b>' + (x.au ? '<span class="au">作者</span>' : '') + (x.me ? '<span class="au me">我</span>' : '') +
(x.to && x.to !== owner ? ' 回复 <b>' + esc(x.to) + '</b>' : '') + ':' + esc(x.t) + (x.me && x.st && x.st !== 'approved' ? '<br>' + stTag(x) : '') + '</p>'; (x.to && x.to !== owner ? ' 回复 <b>' + esc(x.to) + '</b>' : '') + ':' + esc(x.t) + cpH(x.img) + (x.me && x.st && x.st !== 'approved' ? '<br>' + stTag(x) : '') + '</p>';
}).join('') + '</div>' : ''; }).join('') + '</div>' : '';
} }
var cmN = function (n) { return commentsOf(n).length + realCm(n.id).length + myCm(n.id).filter(function (c) { return c.st !== 'rejected'; }).length; }; /* 含回复 */ var cmN = function (n) { return commentsOf(n).length + realCm(n.id).length + myCm(n.id).filter(function (c) { return c.st !== 'rejected'; }).length; }; /* 含回复 */
@@ -1807,13 +1814,13 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
var st = c.s || myStage(); var st = c.s || myStage();
var mk = c.id && c.st === 'approved' ? 'r:' + c.id : ''; /* 通过了的自己的评论,别人能回复,回复挂在这里 */ var mk = c.id && c.st === 'approved' ? 'r:' + c.id : ''; /* 通过了的自己的评论,别人能回复,回复挂在这里 */
return '<div class="ci mine' + (c.st === 'rejected' ? ' rejected' : '') + '"><span class="me">我</span><div class="ci-b"' + (mk ? ' data-rk="' + mk + '" data-rn="' + esc(MYNAME) + '"' : '') + '><div class="ci-n"><b>' + esc(MYNAME) + '</b><span class="mt">我</span>' + (st ? '<i class="stg">' + esc(st) + '</i>' : '') + '</div>' + return '<div class="ci mine' + (c.st === 'rejected' ? ' rejected' : '') + '"><span class="me">我</span><div class="ci-b"' + (mk ? ' data-rk="' + mk + '" data-rn="' + esc(MYNAME) + '"' : '') + '><div class="ci-n"><b>' + esc(MYNAME) + '</b><span class="mt">我</span>' + (st ? '<i class="stg">' + esc(st) + '</i>' : '') + '</div>' +
'<p class="ci-t">' + esc(c.t) + '</p>' + (mk ? '<div class="ci-s"><span class="rpy">回复</span></div>' : '') + stTag(c) + (mk ? rpHTML(extraReplies(openId, mk), mk, MYNAME) : '') + '</div></div>'; /* 11-02 自己的评论也不显示时间 */ (c.t ? '<p class="ci-t">' + esc(c.t) + '</p>' : '') + cpH(c.img) + (mk ? '<div class="ci-s"><span class="rpy">回复</span></div>' : '') + stTag(c) + (mk ? rpHTML(extraReplies(openId, mk), mk, MYNAME) : '') + '</div></div>'; /* 11-02 自己的评论也不显示时间 */
} }
var on = !!ME.cl[c.key], n = c.likes + (on ? 1 : 0); var on = !!ME.cl[c.key], n = c.likes + (on ? 1 : 0);
var rp = rpHTML(c.r.concat(extraReplies(openId, c.key)), c.key, c.n); var rp = rpHTML(c.r.concat(extraReplies(openId, c.key)), c.key, c.n);
return '<div class="ci"><img src="' + (c.av || avSrc(c.n)) + '" alt="" loading="lazy"><div class="ci-b" data-rk="' + esc(c.key) + '" data-rn="' + esc(c.n) + '"><div class="ci-n"><b>' + esc(c.n) + '</b>' + (c.s ? '<i class="stg">' + esc(c.s) + '</i>' : '') + return '<div class="ci"><img src="' + (c.av || avSrc(c.n)) + '" alt="" loading="lazy"><div class="ci-b" data-rk="' + esc(c.key) + '" data-rn="' + esc(c.n) + '"><div class="ci-n"><b>' + esc(c.n) + '</b>' + (c.s ? '<i class="stg">' + esc(c.s) + '</i>' : '') +
'<span class="lk' + (on ? ' on' : '') + '" data-cl="' + esc(c.key) + '" data-base="' + c.likes + '" role="button"><svg class="ic"><use href="#i-heart' + (on ? '-f' : '') + '"/></svg>' + n + '</span></div>' + '<span class="lk' + (on ? ' on' : '') + '" data-cl="' + esc(c.key) + '" data-base="' + c.likes + '" role="button"><svg class="ic"><use href="#i-heart' + (on ? '-f' : '') + '"/></svg>' + n + '</span></div>' +
'<p class="ci-t">' + esc(c.t) + '</p><div class="ci-s"><span class="rpy">回复</span></div>' /* 11-02 用户:评论时间先不显示 */ + rp + '</div></div>'; (c.t ? '<p class="ci-t">' + esc(c.t) + '</p>' : '') + cpH(c.img) + '<div class="ci-s"><span class="rpy">回复</span></div>' /* 11-02 用户:评论时间先不显示 */ + rp + '</div></div>';
} }
function agoOf(ts) { function agoOf(ts) {
var s = Math.max(0, (Date.now() - ts) / 1000); var s = Math.max(0, (Date.now() - ts) / 1000);
@@ -1827,7 +1834,7 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
$('#cmh').innerHTML = '评论 <small>共 ' + cmN(n) + ' 条</small>'; $('#cmh').innerHTML = '评论 <small>共 ' + cmN(n) + ' 条</small>';
if (!CMD && !n.real && !CMERR) { $('#cml').innerHTML = mine.map(function (c) { return commentHTML(c, true); }).join('') + '<div class="cm-ld">评论加载中…</div>'; return; } if (!CMD && !n.real && !CMERR) { $('#cml').innerHTML = mine.map(function (c) { return commentHTML(c, true); }).join('') + '<div class="cm-ld">评论加载中…</div>'; return; }
/* 别人发的、已审核通过的真实评论排在模拟评论前面 */ /* 别人发的、已审核通过的真实评论排在模拟评论前面 */
var rl = realCm(n.id).filter(function (c) { return !c.parent; }).map(function (c) { return { key: 'r:' + c.id, n: c.nickname || '孕妈', av: c.avatar || '', s: c.stage, t: c.text, likes: 0, r: [] }; }); var rl = realCm(n.id).filter(function (c) { return !c.parent; }).map(function (c) { return { key: 'r:' + c.id, n: c.nickname || '孕妈', av: c.avatar || '', s: c.stage, t: c.text, img: c.images, likes: 0, r: [] }; });
$('#cml').innerHTML = mine.map(function (c) { return commentHTML(c, true); }).join('') + rl.concat(cs).map(function (c) { return commentHTML(c); }).join(''); $('#cml').innerHTML = mine.map(function (c) { return commentHTML(c, true); }).join('') + rl.concat(cs).map(function (c) { return commentHTML(c); }).join('');
} }
function syncBar(n, popK) { function syncBar(n, popK) {
@@ -1858,7 +1865,7 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
'<div class="cm-in"><span class="me">我</span><button type="button" id="cmgo">留下你的温柔一句…</button></div>' + '<div class="cm-in"><span class="me">我</span><button type="button" id="cmgo">留下你的温柔一句…</button></div>' +
'<div id="cml"></div><div class="cm-end">— 没有更多评论了 —</div></div>'; '<div id="cml"></div><div class="cm-end">— 没有更多评论了 —</div></div>';
renderComments(n); syncBar(n); loadRC(n); renderComments(n); syncBar(n); loadRC(n);
$('#cin').value = ''; $('#bar').classList.remove('typing'); $('#csend').disabled = true; $('#cin').value = ''; if (CP) CP.clear(); $('#bar').classList.remove('typing'); $('#csend').disabled = true;
$('#dsc').scrollTop = 0; $('#dnav').classList.remove('on'); $('#dsc').scrollTop = 0; $('#dnav').classList.remove('on');
var dt = $('#dt'); dt.classList.add('show'); dt.setAttribute('aria-hidden', 'false'); var dt = $('#dt'); dt.classList.add('show'); dt.setAttribute('aria-hidden', 'false');
if (push) { history.pushState({ gcNote: id }, '', setQuery(cur, id)); pushed = true; } if (push) { history.pushState({ gcNote: id }, '', setQuery(cur, id)); pushed = true; }
@@ -1921,30 +1928,38 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
var w = $('#cmw'); if (w) $('#dsc').scrollTo({ top: w.offsetTop - 50, behavior: 'smooth' }); var w = $('#cmw'); if (w) $('#dsc').scrollTo({ top: w.offsetTop - 50, behavior: 'smooth' });
}); });
var cin = $('#cin'); var cin = $('#cin');
/* 11-05 评论 / 回复可带图(最多 3 张,js/cm-pics.js):选了图底栏保持展开,只有图没有字也能发 */
var CP = window.MBCmPics ? MBCmPics.picker({ strip: $('#cmPics'), toast: toast, onChange: function () { $('#csend').disabled = !canSend(); $('#cpic').classList.toggle('on', CP.count() > 0); if (CP.count()) $('#bar').classList.add('typing'); } }) : null;
var canSend = function () { return !!cin.value.trim() || !!(CP && CP.count()); };
if (CP) { $('#cpic').innerHTML = MBCmPics.ICON; $('#cpic').addEventListener('mousedown', function (e) { e.preventDefault(); }); $('#cpic').addEventListener('click', function (e) { e.preventDefault(); $('#bar').classList.add('typing'); CP.pick(); }); }
else $('#cpic').remove();
cin.addEventListener('focus', function () { $('#bar').classList.add('typing'); }); cin.addEventListener('focus', function () { $('#bar').classList.add('typing'); });
cin.addEventListener('blur', function () { setTimeout(function () { if (!cin.value.trim()) { $('#bar').classList.remove('typing'); REPLY = null; cin.placeholder = '说点什么…'; } }, 120); }); cin.addEventListener('blur', function () { setTimeout(function () { if (!canSend()) { $('#bar').classList.remove('typing'); REPLY = null; cin.placeholder = '说点什么…'; } }, 120); });
cin.addEventListener('input', function () { $('#csend').disabled = !cin.value.trim(); }); cin.addEventListener('input', function () { $('#csend').disabled = !canSend(); });
cin.addEventListener('keydown', function (e) { if (e.key === 'Enter') { e.preventDefault(); send(); } }); cin.addEventListener('keydown', function (e) { if (e.key === 'Enter') { e.preventDefault(); send(); } });
$('#csend').addEventListener('click', send); $('#csend').addEventListener('click', send);
function send() { function send() {
var n = NBY[openId], v = cin.value.trim(); var n = NBY[openId], v = cin.value.trim();
if (!n || !v || send.busy) return; if (!n || !canSend() || send.busy) return;
if (CP && CP.busy()) { toast('图片还在上传,稍等一下'); return; }
var imgs = CP ? CP.urls() : [];
if (!v && !imgs.length) { toast('图片没传上去,删掉重新选一下'); return; }
if (!OPENID) { toast('请在小程序里打开后再评论'); return; } if (!OPENID) { toast('请在小程序里打开后再评论'); return; }
/* 11-03:评论先交后台审核,通过后才公开;审核中只有自己看得到 */ /* 11-03:评论先交后台审核,通过后才公开;审核中只有自己看得到 */
send.busy = true; $('#csend').disabled = true; send.busy = true; $('#csend').disabled = true;
fetch(API + '/comment?' + idq(), { method: 'POST', headers: { 'Content-Type': 'application/json' }, fetch(API + '/comment?' + idq(), { method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ kind: 'post', target: n.id, title: n.title, text: v.slice(0, 200), stage: myStage(), parent: REPLY ? REPLY.k : '', parentName: REPLY ? REPLY.n : '' }) }) body: JSON.stringify({ kind: 'post', target: n.id, title: n.title, text: v.slice(0, 200), images: imgs, stage: myStage(), parent: REPLY ? REPLY.k : '', parentName: REPLY ? REPLY.n : '' }) })
.then(function (r) { return r.json(); }).then(function (j) { .then(function (r) { return r.json(); }).then(function (j) {
send.busy = false; send.busy = false;
if (!j || j.code !== 200) { $('#csend').disabled = !cin.value.trim(); toast((j && j.message) || '没发出去,稍后再试'); return; } if (!j || j.code !== 200) { $('#csend').disabled = !canSend(); toast((j && j.message) || '没发出去,稍后再试'); return; }
var rc = RC[n.id] || (RC[n.id] = { list: [], mine: [] }); rc.mine.unshift(j.result); var rc = RC[n.id] || (RC[n.id] = { list: [], mine: [] }); rc.mine.unshift(j.result);
var wasReply = !!REPLY; REPLY = null; cin.placeholder = '说点什么…'; var wasReply = !!REPLY; REPLY = null; cin.placeholder = '说点什么…';
haptic(); haptic();
cin.value = ''; $('#csend').disabled = true; cin.blur(); $('#bar').classList.remove('typing'); cin.value = ''; if (CP) CP.clear(); $('#csend').disabled = true; cin.blur(); $('#bar').classList.remove('typing');
if (openId === n.id) { renderComments(n); syncBar(n); } if (openId === n.id) { renderComments(n); syncBar(n); }
if (!wasReply) { var w = $('#cmw'); if (w) $('#dsc').scrollTo({ top: w.offsetTop - 50, behavior: 'smooth' }); } if (!wasReply) { var w = $('#cmw'); if (w) $('#dsc').scrollTo({ top: w.offsetTop - 50, behavior: 'smooth' }); }
toast(wasReply ? '回复已提交,审核通过后大家就能看到' : '已提交,审核通过后大家就能看到'); toast(wasReply ? '回复已提交,审核通过后大家就能看到' : '已提交,审核通过后大家就能看到');
}).catch(function () { send.busy = false; $('#csend').disabled = !cin.value.trim(); toast('网络不太好,稍后再试'); }); }).catch(function () { send.busy = false; $('#csend').disabled = !canSend(); toast('网络不太好,稍后再试'); });
} }
/* ================= 投稿(2026-11-01) ================= /* ================= 投稿(2026-11-01) =================

View File

@@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<!-- 11-04 UGC 总开关关着时本页不展示,直接回首页(js/ugc.js) --> <!-- 11-04 UGC 总开关关着时本页不展示,直接回首页(js/ugc.js) -->
<script src="../../js/ugc.js?v=26110458" data-guard></script> <script src="../../js/ugc.js?v=26110459" data-guard></script>
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover"> <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
<meta name="format-detection" content="telephone=no"> <meta name="format-detection" content="telephone=no">
<title>我的投稿</title> <title>我的投稿</title>
@@ -107,7 +107,7 @@ main{padding:6px 16px 0}
</div> </div>
<div class="wb"><button type="button" id="write"><svg class="ic" viewBox="0 0 24 24"><path d="M12 20h9M16.5 3.5a2.1 2.1 0 013 3L7 19l-4 1 1-4z"/></svg>写新的故事</button></div> <div class="wb"><button type="button" id="write"><svg class="ic" viewBox="0 0 24 24"><path d="M12 20h9M16.5 3.5a2.1 2.1 0 013 3L7 19l-4 1 1-4z"/></svg>写新的故事</button></div>
<script src="../topics.js?v=26110458"></script> <script src="../topics.js?v=26110459"></script>
<script> <script>
(function () { (function () {
'use strict'; 'use strict';

View File

@@ -8,8 +8,8 @@
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes">
<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=26110458"></script> <script src="js/ugc.js?v=26110459"></script>
<!-- V:26110458 缓存版本标记:改 css/js 时同步 bump 该值(与 js/app.js 的 VER 同源),静态资源按 mtime 走 ETag 自动刷新 --> <!-- V:26110459 缓存版本标记:改 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"> <link rel="stylesheet" href="night.css">
<!-- 11-04 用户:「顶部图片上的倒计时先删除掉」→ 不加载 hero-cd.css / hero-cd.js(文件留着,加回这两行即恢复),头图回到原样式 --> <!-- 11-04 用户:「顶部图片上的倒计时先删除掉」→ 不加载 hero-cd.css / hero-cd.js(文件留着,加回这两行即恢复),头图回到原样式 -->
@@ -2623,13 +2623,13 @@
<script src="/_bridge/avatar-picker.js?v=26101105"></script> <script src="/_bridge/avatar-picker.js?v=26101105"></script>
<script src="/_bridge/hand-icons.js?v=26101202"></script> <script src="/_bridge/hand-icons.js?v=26101202"></script>
<script src="js/zodiac-art.js"></script> <script src="js/zodiac-art.js"></script>
<script src="guangchang/topics.js?v=26110458"></script> <script src="guangchang/topics.js?v=26110459"></script>
<script src="js/ava-pool.js?v=26110458"></script> <!-- 11-05 装饰头像分配表(各模块互不重复) --> <script src="js/ava-pool.js?v=26110459"></script> <!-- 11-05 装饰头像分配表(各模块互不重复) -->
<script src="js/app.js"></script> <script src="js/app.js"></script>
<script src="js/kit.js?v=26110458"></script> <script src="js/kit.js?v=26110459"></script>
<!-- 11-05 用户:孕期百问加上跟趣味小测试一样的底部 Tab(孕期百问 / 记一下 / 返回首页)。挂在 #detailQA 里,面板关着时跟着滑出屏外; <!-- 11-05 用户:孕期百问加上跟趣味小测试一样的底部 Tab(孕期百问 / 记一下 / 返回首页)。挂在 #detailQA 里,面板关着时跟着滑出屏外;
「记一下」直接开首页自己的记一下弹层(z 95 盖在百问 z 80 上),「返回首页」= 关掉百问面板 --> 「记一下」直接开首页自己的记一下弹层(z 95 盖在百问 z 80 上),「返回首页」= 关掉百问面板 -->
<script src="js/mb-tabbar.js?v=26110458"></script> <script src="js/mb-tabbar.js?v=26110459"></script>
<script> <script>
(function () { (function () {
var d = document.getElementById('detailQA'); if (!d || !window.MBTab) return; var d = document.getElementById('detailQA'); if (!d || !window.MBTab) return;
@@ -2649,7 +2649,7 @@
if (gchDone || !window.__mbUgc) return; gchDone = true; if (gchDone || !window.__mbUgc) return; gchDone = true;
var m = location.search.match(/[?&]gcv=([1-6])(?:&|$)/); var m = location.search.match(/[?&]gcv=([1-6])(?:&|$)/);
if (!m) window.__gcDefault = 1; if (!m) window.__gcDefault = 1;
var n = m ? m[1] : '6', l = document.createElement('link'), s = document.createElement('script'), q = m ? Date.now() : 'v=26110458'; var n = m ? m[1] : '6', l = document.createElement('link'), s = document.createElement('script'), q = m ? Date.now() : 'v=26110459';
var dir = n === '4' || n === '6' ? 'js/gch/' : 'demo/gch/'; /* 11-03 上正式:定稿 V6(含它套的 V4)并进 js/gch/,其余效果稿仍在 demo/ */ var dir = n === '4' || n === '6' ? 'js/gch/' : 'demo/gch/'; /* 11-03 上正式:定稿 V6(含它套的 V4)并进 js/gch/,其余效果稿仍在 demo/ */
l.rel = 'stylesheet'; l.href = dir + 'v' + n + '.css?' + q; l.rel = 'stylesheet'; l.href = dir + 'v' + n + '.css?' + q;
s.src = dir + 'v' + n + '.js?' + q; s.src = dir + 'v' + n + '.js?' + q;
@@ -2664,19 +2664,19 @@
/* 11-02 品牌露出(用户定 4 处都要):默认加载,?brand=0 可关掉对比;11-03 已并进 js/gch/ */ /* 11-02 品牌露出(用户定 4 处都要):默认加载,?brand=0 可关掉对比;11-03 已并进 js/gch/ */
if (!/[?&]brand=0/.test(location.search)) { if (!/[?&]brand=0/.test(location.search)) {
var bl = document.createElement('link'), bs = document.createElement('script'); var bl = document.createElement('link'), bs = document.createElement('script');
bl.rel = 'stylesheet'; bl.href = 'js/gch/brand.css?v=26110458'; bs.src = 'js/gch/brand.js?v=26110458'; bl.rel = 'stylesheet'; bl.href = 'js/gch/brand.css?v=26110459'; bs.src = 'js/gch/brand.js?v=26110459';
document.head.appendChild(bl); document.body.appendChild(bs); document.head.appendChild(bl); document.body.appendChild(bs);
} }
})(); })();
</script> </script>
<!-- 2026-10-03 首页彩蛋:宝宝在肚皮底下动(独立文件,删掉这一行即整体下线;开关在「隐私权限」) --> <!-- 2026-10-03 首页彩蛋:宝宝在肚皮底下动(独立文件,删掉这一行即整体下线;开关在「隐私权限」) -->
<script src="js/bump.js?v=26110458"></script> <script src="js/bump.js?v=26110459"></script>
<!-- 2026-10-04 首页头图:按孕周换宝宝 + 阳光水波(独立文件) --> <!-- 2026-10-04 首页头图:按孕周换宝宝 + 阳光水波(独立文件) -->
<script src="js/hero-fx.js"></script> <script src="js/hero-fx.js"></script>
<!-- 2026-10-05 首页头图:宝宝时不时动一动小手小脚(独立文件,删掉这一行即下线) --> <!-- 2026-10-05 首页头图:宝宝时不时动一动小手小脚(独立文件,删掉这一行即下线) -->
<script src="js/baby-limbs.js?v=26110458"></script> <script src="js/baby-limbs.js?v=26110459"></script>
<script src="js/coach.js?v=26110458"></script> <script src="js/coach.js?v=26110459"></script>
<script src="js/birth-flow.js?v=26110458"></script> <script src="js/birth-flow.js?v=26110459"></script>
<!-- 禁止下拉回弹(2026-10-11 统一规则,与孕期体重同一段):竖向拖动时从手指下往上找还能朝该方向滚的容器,找不到才拦;横滑、双指、可滚列表不受影响 --> <!-- 禁止下拉回弹(2026-10-11 统一规则,与孕期体重同一段):竖向拖动时从手指下往上找还能朝该方向滚的容器,找不到才拦;横滑、双指、可滚列表不受影响 -->
<script> <script>

View File

@@ -3,7 +3,7 @@
(function () { (function () {
'use strict'; 'use strict';
/* 页面版本号(YYMMDD+序号):显示在「关于兜爸心选」页底部;bump 时同步 head 注释与 ?v= */ /* 页面版本号(YYMMDD+序号):显示在「关于兜爸心选」页底部;bump 时同步 head 注释与 ?v= */
var VER = '26110458'; var VER = '26110459';
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));

96
js/cm-pics.js Normal file
View File

@@ -0,0 +1,96 @@
/* 11-05 评论 / 回复带图(用户:「评论的时候,或者回复别人评论时候,可以加上上传图片功能」)
孕妈广场帖子详情(guangchang/index.html)和专题页评论区(topic/_shared/tools.js)共用。
· 每条最多 3 张;选图后先在本机压到长边 1600、JPEG 0.85,再传 /api/upload(同投稿),拿回本站地址随评论提交。
· 后端 /plaza/comment 带 images[](只认本站 /api/upload 地址),图片和文字一起进后台「评论审核」,通过后大家才看得到。
· 显示:评论文字下面一排小方图(最多 3 张),点开全屏看大图,点任意处关闭。
用法:
var P = MBCmPics.picker({ strip: 放缩略图的元素, onChange: fn })
P.pick() 打开相册 · P.urls() 已传好的地址 · P.busy() 还有没传完的 · P.count() 已选张数 · P.clear() 清空
MBCmPics.html(images) → 评论里那排图的 HTML(没有图返回 '') */
(function () {
if (window.MBCmPics) return;
var MAX = 3;
var st = document.createElement('style');
st.textContent =
'.cmp-strip{display:flex;gap:8px;padding:8px 2px 2px;overflow-x:auto}.cmp-strip:empty{display:none}' +
'.cmp-t{position:relative;flex:none;width:58px;height:58px;border-radius:10px;overflow:hidden;background:#F1E9E5}' +
'.cmp-t img{width:100%;height:100%;object-fit:cover;display:block}' +
'.cmp-t.up::after{content:"上传中";position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.38);color:#fff;font-size:11px}' +
'.cmp-t.bad::after{content:"失败";position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(200,40,40,.5);color:#fff;font-size:11px}' +
'.cmp-t button{position:absolute;right:2px;top:2px;z-index:1;width:18px;height:18px;border-radius:50%;background:rgba(0,0,0,.55);color:#fff;font-size:13px;line-height:18px;text-align:center;padding:0;border:0}' +
'.cmp-g{display:flex;gap:6px;margin-top:6px}' +
'.cmp-g img{width:76px;height:76px;border-radius:8px;object-fit:cover;background:#F1E9E5;cursor:zoom-in}' +
'.cmp-btn{flex:none;display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;padding:0;border:0;border-radius:50%;background:none;color:#9C8781}' +
'.cmp-btn svg{width:21px;height:21px}' +
'.cmp-btn.on{color:#F4593C}' +
'.cmp-lb{position:fixed;inset:0;z-index:10000;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.92)}' +
'.cmp-lb img{max-width:100%;max-height:100%;object-fit:contain}';
(document.head || document.documentElement).appendChild(st);
var ICON = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="5" width="18" height="15" rx="3"/><circle cx="9" cy="10.5" r="1.8"/><path d="M21 16l-5-5-8 8"/></svg>';
var esc = function (s) { return String(s).replace(/[&<>"']/g, function (c) { return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c]; }); };
function shrink(f) {
return new Promise(function (res) {
var u = URL.createObjectURL(f), im = new Image();
im.onload = function () {
var k = Math.min(1, 1600 / Math.max(im.width, im.height)), c = document.createElement('canvas');
c.width = Math.round(im.width * k); c.height = Math.round(im.height * k);
c.getContext('2d').drawImage(im, 0, 0, c.width, c.height); URL.revokeObjectURL(u);
c.toBlob(function (b) { res(b || f); }, 'image/jpeg', .85);
};
im.onerror = function () { URL.revokeObjectURL(u); res(f); };
im.src = u;
});
}
function picker(o) {
var pics = [], ups = 0, strip = o.strip;
var fi = document.createElement('input'); fi.type = 'file'; fi.accept = 'image/*'; fi.multiple = true; fi.hidden = true;
document.body.appendChild(fi);
var ch = function () { if (o.onChange) o.onChange(); };
fi.addEventListener('change', function () {
var fs = [].slice.call(fi.files || []); fi.value = '';
if (pics.length + fs.length > MAX && o.toast) o.toast('每条最多带 ' + MAX + ' 张图');
fs.slice(0, MAX - pics.length).forEach(function (f) {
var it = { url: null, el: document.createElement('span') };
it.el.className = 'cmp-t up';
it.el.innerHTML = '<img alt=""><button type="button" aria-label="删除这张">×</button>';
it.el.querySelector('img').src = URL.createObjectURL(f);
it.el.querySelector('button').addEventListener('mousedown', function (e) { e.preventDefault(); });
it.el.querySelector('button').onclick = function () { pics = pics.filter(function (x) { return x !== it; }); it.el.remove(); ch(); };
strip.appendChild(it.el); pics.push(it); ups++;
shrink(f).then(function (b) { var fd = new FormData(); fd.append('file', b, 'comment.jpg'); return fetch('/api/upload', { method: 'POST', body: fd }); })
.then(function (r) { return r.json(); }).then(function (j) { it.url = j && j.result && j.result.url || null; if (!it.url) throw 0; it.el.classList.remove('up'); })
.catch(function () { if (o.toast) o.toast('图片上传失败,可以删掉重新选'); it.el.classList.remove('up'); it.el.classList.add('bad'); })
.then(function () { ups--; ch(); });
});
ch();
});
return {
pick: function () { if (pics.length >= MAX) { if (o.toast) o.toast('每条最多带 ' + MAX + ' 张图'); return; } fi.click(); },
urls: function () { return pics.map(function (x) { return x.url; }).filter(Boolean); },
busy: function () { return ups > 0; },
count: function () { return pics.length; },
clear: function () { pics = []; strip.innerHTML = ''; ch(); }
};
}
function html(imgs) {
imgs = (imgs || []).filter(function (u) { return typeof u === 'string' && /^(https?:)?\/\//.test(u) || /^\//.test(u); }).slice(0, MAX);
return imgs.length ? '<div class="cmp-g">' + imgs.map(function (u) { return '<img src="' + esc(u) + '" alt="" loading="lazy" data-cmp="' + esc(u) + '">'; }).join('') + '</div>' : '';
}
/* 点评论里的图 → 全屏大图;点任意处关 */
document.addEventListener('click', function (e) {
var im = e.target.closest && e.target.closest('[data-cmp]');
if (!im) return;
e.preventDefault(); e.stopPropagation();
var lb = document.createElement('div'); lb.className = 'cmp-lb';
lb.innerHTML = '<img alt="" src="' + esc(im.dataset.cmp) + '">';
lb.addEventListener('click', function () { lb.remove(); });
document.body.appendChild(lb);
}, true);
window.MBCmPics = { picker: picker, html: html, ICON: ICON, MAX: MAX };
})();

View File

@@ -244,5 +244,5 @@
} }
/* feed.js 首页默认不加载(index.html 只引了 topics.js),这里按需拉一次 */ /* feed.js 首页默认不加载(index.html 只引了 topics.js),这里按需拉一次 */
if (window.GC_FEED) init(); if (window.GC_FEED) init();
else { var fs = document.createElement('script'); fs.src = 'guangchang/feed.js?v=26110458'; fs.onload = fs.onerror = init; document.body.appendChild(fs); } else { var fs = document.createElement('script'); fs.src = 'guangchang/feed.js?v=26110459'; fs.onload = fs.onerror = init; document.body.appendChild(fs); }
})(); })();

View File

@@ -6,9 +6,9 @@
(function () { (function () {
var sec = document.getElementById('gcHome'); var sec = document.getElementById('gcHome');
if (!sec) return; if (!sec) return;
var l = document.createElement('link'); l.rel = 'stylesheet'; l.href = 'js/gch/v4.css?v=26110458'; var l = document.createElement('link'); l.rel = 'stylesheet'; l.href = 'js/gch/v4.css?v=26110459';
document.head.appendChild(l); document.head.appendChild(l);
var s = document.createElement('script'); s.src = 'js/gch/v4.js?v=26110458'; var s = document.createElement('script'); s.src = 'js/gch/v4.js?v=26110459';
s.onload = function () { if (sec.querySelector('.g4-foot')) merge(); else sec.addEventListener('gc4-ready', merge, { once: true }); }; /* v4 要先拉 feed.js 才渲染 */ s.onload = function () { if (sec.querySelector('.g4-foot')) merge(); else sec.addEventListener('gc4-ready', merge, { once: true }); }; /* v4 要先拉 feed.js 才渲染 */
document.body.appendChild(s); document.body.appendChild(s);

View File

@@ -9,7 +9,7 @@
if (/[?&]kit=0(?:&|$)/.test(location.search)) return; if (/[?&]kit=0(?:&|$)/.test(location.search)) return;
var box = document.getElementById('kit'), sec = document.getElementById('kitHome'); var box = document.getElementById('kit'), sec = document.getElementById('kitHome');
if (!box || !sec) return; if (!box || !sec) return;
var V = '26110458'; var V = '26110459';
var l = document.createElement('link'); l.rel = 'stylesheet'; l.href = 'js/kit.css?v=' + V; document.head.appendChild(l); var l = document.createElement('link'); l.rel = 'stylesheet'; l.href = 'js/kit.css?v=' + V; document.head.appendChild(l);
document.documentElement.classList.add('has-kit'); document.documentElement.classList.add('has-kit');

View File

@@ -8,7 +8,7 @@
postMessage 不是实时投递,微信在分享那一刻才派发,所以每次换内容都要再报一次;子页面没引 jweixin,这里按需加载。 */ postMessage 不是实时投递,微信在分享那一刻才派发,所以每次换内容都要再报一次;子页面没引 jweixin,这里按需加载。 */
(function (g) { (function (g) {
'use strict'; 'use strict';
var V = '26110458'; var V = '26110459';
var isWx = /MicroMessenger/i.test(navigator.userAgent || ''); var isWx = /MicroMessenger/i.test(navigator.userAgent || '');
var waiting = [], loading = false; var waiting = [], loading = false;
function ready(cb) { function ready(cb) {

View File

@@ -44,6 +44,10 @@
'.tc-in label{flex:1;min-width:0;display:flex;padding:6px 14px;border-radius:20px;background:#F2F3F5}' + '.tc-in label{flex:1;min-width:0;display:flex;padding:6px 14px;border-radius:20px;background:#F2F3F5}' +
'.tc-in textarea{flex:1;min-width:0;border:0;background:transparent;resize:none;font-size:14px;line-height:1.6;font-family:inherit;color:#1F2329;height:24px;max-height:96px;outline:0;padding:0}' + '.tc-in textarea{flex:1;min-width:0;border:0;background:transparent;resize:none;font-size:14px;line-height:1.6;font-family:inherit;color:#1F2329;height:24px;max-height:96px;outline:0;padding:0}' +
'.tc-in button{flex:0 0 auto;height:36px;padding:0 16px;border:0;border-radius:99px;background:var(--tt-c,#18A058);color:#fff;font-size:13.5px;font-weight:700}.tc-in button:disabled{opacity:.35}' + '.tc-in button{flex:0 0 auto;height:36px;padding:0 16px;border:0;border-radius:99px;background:var(--tt-c,#18A058);color:#fff;font-size:13.5px;font-weight:700}.tc-in button:disabled{opacity:.35}' +
/* 11-05 评论带图:图片按钮 / 缩略图条(js/cm-pics.js)别吃到上面通用的绿色按钮样式;缩略图条浮在输入条上方,「回复 XX」条出来时再往上让一格 */
'.tc-in .cmp-btn{height:36px;width:32px;padding:0;background:none;color:#86909C;border-radius:50%}.tc-in .cmp-btn.on{color:var(--tt-c,#18A058)}.tc-in .cmp-btn[hidden]{display:none}' +
'.tc-in .cmp-t button{width:18px;height:18px;padding:0;border-radius:50%;background:rgba(0,0,0,.55);font-size:13px;font-weight:400;line-height:18px}' +
'.tc-in .cmp-strip{position:absolute;left:0;right:0;bottom:100%;padding:8px 14px 6px;background:#fff;border-top:1px solid #EEF0F3}.tc-rto:not([hidden]) ~ .cmp-strip{bottom:calc(100% + 38px)}' +
'.tc-it{display:flex;gap:10px;padding:14px 0;border-bottom:1px solid #F2F3F5}.tc-it:last-child{border-bottom:0}.tc-av{flex:0 0 34px;width:34px;height:34px;border-radius:50%;object-fit:cover;background:#F2F3F5}' + '.tc-it{display:flex;gap:10px;padding:14px 0;border-bottom:1px solid #F2F3F5}.tc-it:last-child{border-bottom:0}.tc-av{flex:0 0 34px;width:34px;height:34px;border-radius:50%;object-fit:cover;background:#F2F3F5}' +
/* 11-03 用户评论先审核:自己的评论挂状态 */ /* 11-03 用户评论先审核:自己的评论挂状态 */
'.tc-st{display:inline-block;margin-top:6px;padding:0 7px;border-radius:4px;font-size:11px;line-height:18px;font-weight:600;background:#F2F3F5;color:#86909C}.tc-st.pending{background:#FFF4E5;color:#E08A00}.tc-it.rej .tc-t{color:#A0A6AE}' + '.tc-st{display:inline-block;margin-top:6px;padding:0 7px;border-radius:4px;font-size:11px;line-height:18px;font-weight:600;background:#F2F3F5;color:#86909C}.tc-st.pending{background:#FFF4E5;color:#E08A00}.tc-it.rej .tc-t{color:#A0A6AE}' +
@@ -57,7 +61,7 @@
'.tc-more{display:block;width:100%;margin-top:6px;height:40px;border:0;border-radius:99px;background:#F7F8FA;color:#4E5969;font-size:13px;font-weight:600}'; '.tc-more{display:block;width:100%;margin-top:6px;height:40px;border:0;border-radius:99px;background:#F7F8FA;color:#4E5969;font-size:13px;font-weight:600}';
var SLUG = (location.pathname.match(/\/topic\/([^\/]+)\//) || [])[1] || ''; var SLUG = (location.pathname.match(/\/topic\/([^\/]+)\//) || [])[1] || '';
/* 11-04 微信转发图:每个专题一张 assets/share/t/<slug>.jpg(核心词大字 + logo),见 js/share-card.js */ /* 11-04 微信转发图:每个专题一张 assets/share/t/<slug>.jpg(核心词大字 + logo),见 js/share-card.js */
if (SLUG) (function () { var s = document.createElement('script'); s.src = '../../js/share-card.js?v=26110458'; 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=26110459'; s.onload = function () { window.mbShare('../../assets/share/t/' + SLUG + '.jpg'); }; 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]) : '_guest'; })();
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) {} }
@@ -70,7 +74,7 @@
function getJSON(u) { return fetch(u, { cache: 'no-cache' }).then(function (r) { if (!r.ok) throw r.status; return r.json(); }); } function getJSON(u) { return fetch(u, { cache: 'no-cache' }).then(function (r) { if (!r.ok) throw r.status; return r.json(); }); }
function related(box) { function related(box) {
getJSON('../_shared/idx.json?v=26110458').then(function (idx) { getJSON('../_shared/idx.json?v=26110459').then(function (idx) {
var me = null; idx.forEach(function (x) { if (x[0] === SLUG) me = x; }); var me = null; idx.forEach(function (x) { if (x[0] === SLUG) me = x; });
var tag = me ? me[2] : '', h = 0; for (var i = 0; i < SLUG.length; i++) h = (h * 31 + SLUG.charCodeAt(i)) >>> 0; var tag = me ? me[2] : '', h = 0; for (var i = 0; i < SLUG.length; i++) h = (h * 31 + SLUG.charCodeAt(i)) >>> 0;
var rest = idx.filter(function (x) { return x[0] !== SLUG && (window.__mbUgc || ['ceshi', 'duiyou'].indexOf(x[0]) < 0); }); /* UGC 关着不推两个测试 */ var rest = idx.filter(function (x) { return x[0] !== SLUG && (window.__mbUgc || ['ceshi', 'duiyou'].indexOf(x[0]) < 0); }); /* UGC 关着不推两个测试 */
@@ -92,19 +96,20 @@
var API = '/api/mp/public/mama-box/plaza'; var API = '/api/mp/public/mama-box/plaza';
function mine() { function mine() {
var old = (st.m.cm[SLUG] || []).map(function (c) { return { t: c.t, ts: c.ts, s: c.s, st: 'local' }; }); var old = (st.m.cm[SLUG] || []).map(function (c) { return { t: c.t, ts: c.ts, s: c.s, st: 'local' }; });
return old.concat(RC.mine.slice().reverse().map(function (c) { return { t: c.text, ts: c.at, s: c.stage, st: c.status, why: c.reason, id: c.id, parent: c.parent, to: c.parentName }; })); return old.concat(RC.mine.slice().reverse().map(function (c) { return { t: c.text, ts: c.at, s: c.stage, st: c.status, why: c.reason, id: c.id, parent: c.parent, to: c.parentName, img: c.images }; }));
} }
function real() { return RC.list.filter(function (c) { return !c.parent; }).map(function (c) { return [c.nickname || '孕妈', c.avatar || '', c.stage || '', c.text, 0, [], 'r:' + c.id]; }); } function real() { return RC.list.filter(function (c) { return !c.parent; }).map(function (c) { return [c.nickname || '孕妈', c.avatar || '', c.stage || '', c.text, 0, [], 'r:' + c.id, c.images]; }); }
var cpH = function (a) { return window.MBCmPics ? MBCmPics.html(a) : ''; }; /* 11-05 评论里的图 */
/* 11-03 用户:可以回复别人的评论。回复也先审核;楼里只有一层,回复回复也挂在同一楼,写「回复 XX」 */ /* 11-03 用户:可以回复别人的评论。回复也先审核;楼里只有一层,回复回复也挂在同一楼,写「回复 XX」 */
var REPLY = null, MYN = '我'; var REPLY = null, MYN = '我';
function stTag(c) { return c.st === 'pending' ? '<span class="tc-st pending">审核中 · 通过后大家才能看到</span>' : c.st === 'rejected' ? '<span class="tc-st">未通过' + (c.why ? ':' + esc(c.why) : '') + '</span>' : c.st === 'local' ? '<span class="tc-st">仅自己可见</span>' : ''; } function stTag(c) { return c.st === 'pending' ? '<span class="tc-st pending">审核中 · 通过后大家才能看到</span>' : c.st === 'rejected' ? '<span class="tc-st">未通过' + (c.why ? ':' + esc(c.why) : '') + '</span>' : c.st === 'local' ? '<span class="tc-st">仅自己可见</span>' : ''; }
function replies(base, k, owner) { function replies(base, k, owner) {
var L2 = (base || []).map(function (r) { return { n: r[0], t: r[3] }; }) var L2 = (base || []).map(function (r) { return { n: r[0], t: r[3] }; })
.concat(RC.list.filter(function (c) { return c.parent === k; }).map(function (c) { return { n: c.nickname || '孕妈', t: c.text, to: c.parentName, ts: c.at }; }) .concat(RC.list.filter(function (c) { return c.parent === k; }).map(function (c) { return { n: c.nickname || '孕妈', t: c.text, to: c.parentName, ts: c.at, img: c.images }; })
.concat(mine().filter(function (c) { return c.parent === k; }).map(function (c) { return { n: MYN, me: 1, t: c.t, to: c.to, st: c.st, why: c.why, ts: c.ts }; })) .concat(mine().filter(function (c) { return c.parent === k; }).map(function (c) { return { n: MYN, me: 1, t: c.t, to: c.to, st: c.st, why: c.why, ts: c.ts, img: c.img }; }))
.sort(function (x, y) { return x.ts - y.ts; })); /* 预置回复在前,真实回复按时间先后 */ .sort(function (x, y) { return x.ts - y.ts; })); /* 预置回复在前,真实回复按时间先后 */
return L2.length ? '<div class="tc-r">' + L2.map(function (r) { return L2.length ? '<div class="tc-r">' + L2.map(function (r) {
return '<p' + (r.me ? (r.st === 'rejected' ? ' class="rej"' : '') : ' data-rk="' + esc(k) + '" data-rn="' + esc(r.n) + '"') + '><b>' + esc(r.n) + '</b>' + (r.to && r.to !== owner ? ' 回复 <b>' + esc(r.to) + '</b>' : '') + '<b>:</b>' + esc(r.t) + return '<p' + (r.me ? (r.st === 'rejected' ? ' class="rej"' : '') : ' data-rk="' + esc(k) + '" data-rn="' + esc(r.n) + '"') + '><b>' + esc(r.n) + '</b>' + (r.to && r.to !== owner ? ' 回复 <b>' + esc(r.to) + '</b>' : '') + '<b>:</b>' + esc(r.t) + cpH(r.img) +
(r.me && r.st !== 'approved' ? '<br>' + stTag(r) : '') + '</p>'; (r.me && r.st !== 'approved' ? '<br>' + stTag(r) : '') + '</p>';
}).join('') + '</div>' : ''; }).join('') + '</div>' : '';
} }
@@ -114,14 +119,14 @@
var tag = c.me ? stTag(c) : ''; var tag = c.me ? stTag(c) : '';
return '<div class="tc-it' + (c.me && c.st === 'rejected' ? ' rej' : '') + '">' + (c.me ? '<span class="tc-av tc-me">我</span>' : '<img class="tc-av" src="' + esc(avP(c[1])) + '" alt="" loading="lazy">') + return '<div class="tc-it' + (c.me && c.st === 'rejected' ? ' rej' : '') + '">' + (c.me ? '<span class="tc-av tc-me">我</span>' : '<img class="tc-av" src="' + esc(avP(c[1])) + '" alt="" loading="lazy">') +
'<div class="tc-b"' + (rk ? ' data-rk="' + esc(rk) + '" data-rn="' + esc(rn) + '"' : '') + '><div class="tc-n"><b>' + esc(c.me ? '我' : c[0]) + '</b>' + (c.me ? '<i>' + esc(c.s || myStage() || '刚刚') + '</i>' : (c[2] ? '<i>' + esc(c[2]) + '</i>' : '')) + '</div>' + '<div class="tc-b"' + (rk ? ' data-rk="' + esc(rk) + '" data-rn="' + esc(rn) + '"' : '') + '><div class="tc-n"><b>' + esc(c.me ? '我' : c[0]) + '</b>' + (c.me ? '<i>' + esc(c.s || myStage() || '刚刚') + '</i>' : (c[2] ? '<i>' + esc(c[2]) + '</i>' : '')) + '</div>' +
'<div class="tc-t">' + esc(c.me ? c.t : c[3]) + '</div>' + tag + ((c.me ? c.t : c[3]) ? '<div class="tc-t">' + esc(c.me ? c.t : c[3]) + '</div>' : '') + cpH(c.me ? c.img : c[7]) + tag +
(rk ? replies(c.me ? [] : c[5], rk, rn) : '') + (rk ? replies(c.me ? [] : c[5], rk, rn) : '') +
'<div class="tc-f">' + (rk ? '<button type="button" class="tc-rpy">回复</button>' : '') + '<button type="button" class="tc-lk' + (lk ? ' on' : '') + '" data-k="' + esc(key) + '">' + HEART + '<span>' + ((c.me ? 0 : c[4]) + (lk ? 1 : 0) || '赞') + '</span></button></div></div></div>'; '<div class="tc-f">' + (rk ? '<button type="button" class="tc-rpy">回复</button>' : '') + '<button type="button" class="tc-lk' + (lk ? ' on' : '') + '" data-k="' + esc(key) + '">' + HEART + '<span>' + ((c.me ? 0 : c[4]) + (lk ? 1 : 0) || '赞') + '</span></button></div></div></div>';
} }
function paint() { function paint() {
var my = mine().filter(function (c) { return !c.parent; }).reverse(), A = real().concat(L), n = A.length + my.filter(function (c) { return c.st !== 'rejected'; }).length, show = open ? A : A.slice(0, 5); var my = mine().filter(function (c) { return !c.parent; }).reverse(), A = real().concat(L), n = A.length + my.filter(function (c) { return c.st !== 'rejected'; }).length, show = open ? A : A.slice(0, 5);
box.innerHTML = '<div class="tt-h"><b>大家怎么说</b><span>' + n + ' 条评论</span></div>' + box.innerHTML = '<div class="tt-h"><b>大家怎么说</b><span>' + n + ' 条评论</span></div>' +
'<div class="tc-list">' + my.map(function (c, i) { return item({ me: 1, t: c.t, s: c.s, st: c.st, why: c.why }, 'me' + c.ts); }).join('') + '<div class="tc-list">' + my.map(function (c, i) { return item({ me: 1, t: c.t, s: c.s, st: c.st, why: c.why, img: c.img }, 'me' + c.ts); }).join('') +
show.map(function (c, i) { return item(c, c[6] || SLUG + '#' + (i - (A.length - L.length))); }).join('') + '</div>' + show.map(function (c, i) { return item(c, c[6] || SLUG + '#' + (i - (A.length - L.length))); }).join('') + '</div>' +
(!open && A.length > 5 ? '<button type="button" class="tc-more">展开全部 ' + n + ' 条评论</button>' : ''); (!open && A.length > 5 ? '<button type="button" class="tc-more">展开全部 ' + n + ' 条评论</button>' : '');
[].forEach.call(box.querySelectorAll('[data-rk]'), function (el) { [].forEach.call(box.querySelectorAll('[data-rk]'), function (el) {
@@ -138,37 +143,50 @@
} }
/* 底部浮条:整页常驻,发完滚到评论区看到自己那条 */ /* 底部浮条:整页常驻,发完滚到评论区看到自己那条 */
var bar = document.createElement('div'); bar.className = 'tc-in'; var bar = document.createElement('div'); bar.className = 'tc-in';
bar.innerHTML = '<div class="tc-rto" hidden><span></span><button type="button" aria-label="取消回复">×</button></div><label><textarea rows="1" maxlength="200" placeholder="说说你的情况,和其他妈妈聊聊…"></textarea></label><button type="button" disabled>发布</button>'; bar.innerHTML = '<div class="tc-rto" hidden><span></span><button type="button" aria-label="取消回复">×</button></div><div class="cmp-strip"></div><label><textarea rows="1" maxlength="200" placeholder="说说你的情况,和其他妈妈聊聊…"></textarea></label><button type="button" class="cmp-btn" aria-label="加图片"></button><button type="button" class="tc-go" disabled>发布</button>';
bar.style.setProperty('--tt-c', box.style.getPropertyValue('--tt-c')); bar.style.setProperty('--tt-c', box.style.getPropertyValue('--tt-c'));
document.body.appendChild(bar); document.body.appendChild(bar);
var sc = box.parentNode; while (sc && sc !== document.body && !/(auto|scroll)/.test(getComputedStyle(sc).overflowY)) sc = sc.parentNode; var sc = box.parentNode; while (sc && sc !== document.body && !/(auto|scroll)/.test(getComputedStyle(sc).overflowY)) sc = sc.parentNode;
sc = sc || document.body; sc.style.paddingBottom = (parseFloat(getComputedStyle(sc).paddingBottom) || 0) + 64 + 'px'; sc = sc || document.body; sc.style.paddingBottom = (parseFloat(getComputedStyle(sc).paddingBottom) || 0) + 64 + 'px';
var ta = bar.querySelector('textarea'), bt = bar.querySelector('label + button'), PH = ta.placeholder, rto = bar.querySelector('.tc-rto'); var ta = bar.querySelector('textarea'), bt = bar.querySelector('.tc-go'), PH = ta.placeholder, rto = bar.querySelector('.tc-rto');
function setReply(r, tx) { function setReply(r, tx) {
REPLY = r; ta.placeholder = r ? '回复 ' + r.n + ':' : PH; rto.hidden = !r; REPLY = r; ta.placeholder = r ? '回复 ' + r.n + ':' : PH; rto.hidden = !r;
if (r) rto.querySelector('span').innerHTML = '回复 <b>' + esc(r.n) + '</b>' + (tx ? ':' + esc(String(tx).trim().slice(0, 40)) : ''); if (r) rto.querySelector('span').innerHTML = '回复 <b>' + esc(r.n) + '</b>' + (tx ? ':' + esc(String(tx).trim().slice(0, 40)) : '');
} }
rto.querySelector('button').addEventListener('mousedown', function (e) { e.preventDefault(); }); rto.querySelector('button').addEventListener('mousedown', function (e) { e.preventDefault(); });
rto.querySelector('button').addEventListener('click', function () { setReply(null); }); rto.querySelector('button').addEventListener('click', function () { setReply(null); });
ta.addEventListener('blur', function () { setTimeout(function () { if (!ta.value.trim()) setReply(null); }, 150); }); /* 11-05 评论 / 回复可带图(最多 3 张,js/cm-pics.js 加载好之后才出按钮);只有图没有字也能发 */
ta.addEventListener('input', function () { bt.disabled = !ta.value.trim(); ta.style.height = '24px'; ta.style.height = Math.min(96, ta.scrollHeight) + 'px'; }); var CP = null, pb = bar.querySelector('.cmp-btn');
var canSend = function () { return !!ta.value.trim() || !!(CP && CP.count()); };
pb.hidden = true;
pb.addEventListener('mousedown', function (e) { e.preventDefault(); });
pb.addEventListener('click', function () { if (CP) CP.pick(); });
cmPicsReady(function () {
CP = MBCmPics.picker({ strip: bar.querySelector('.cmp-strip'), toast: toast, onChange: function () { bt.disabled = !canSend(); pb.classList.toggle('on', CP.count() > 0); } });
pb.innerHTML = MBCmPics.ICON; pb.hidden = false; paint();
});
ta.addEventListener('blur', function () { setTimeout(function () { if (!canSend()) setReply(null); }, 150); });
ta.addEventListener('input', function () { bt.disabled = !canSend(); ta.style.height = '24px'; ta.style.height = Math.min(96, ta.scrollHeight) + 'px'; });
bt.addEventListener('click', function () { bt.addEventListener('click', function () {
var v = ta.value.trim(); if (!v || bt.busy) return; var v = ta.value.trim(); if (!canSend() || bt.busy) return;
if (CP && CP.busy()) { toast('图片还在上传,稍等一下'); return; }
var imgs = CP ? CP.urls() : [];
if (!v && !imgs.length) { toast('图片没传上去,删掉重新选一下'); return; }
if (!OID) { toast('请在小程序里打开后再评论'); return; } if (!OID) { toast('请在小程序里打开后再评论'); return; }
/* 11-03:先交后台审核,通过后才公开;审核中只有自己看得到 */ /* 11-03:先交后台审核,通过后才公开;审核中只有自己看得到 */
bt.busy = true; bt.disabled = true; bt.busy = true; bt.disabled = true;
var h1 = document.querySelector('h1'); var h1 = document.querySelector('h1');
fetch(API + '/comment?openid=' + encodeURIComponent(OID), { method: 'POST', headers: { 'Content-Type': 'application/json' }, fetch(API + '/comment?openid=' + encodeURIComponent(OID), { method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ kind: 'topic', target: SLUG, title: (h1 && h1.textContent.trim()) || document.title, text: v.slice(0, 200), stage: myStage(), parent: REPLY ? REPLY.k : '', parentName: REPLY ? REPLY.n : '' }) }) body: JSON.stringify({ kind: 'topic', target: SLUG, title: (h1 && h1.textContent.trim()) || document.title, text: v.slice(0, 200), images: imgs, stage: myStage(), parent: REPLY ? REPLY.k : '', parentName: REPLY ? REPLY.n : '' }) })
.then(function (r) { return r.json(); }).then(function (j) { .then(function (r) { return r.json(); }).then(function (j) {
bt.busy = false; bt.busy = false;
if (!j || j.code !== 200) { bt.disabled = !ta.value.trim(); toast((j && j.message) || '没发出去,稍后再试'); return; } if (!j || j.code !== 200) { bt.disabled = !canSend(); toast((j && j.message) || '没发出去,稍后再试'); return; }
RC.mine.unshift(j.result); RC.mine.unshift(j.result);
var wasReply = !!REPLY; setReply(null); var wasReply = !!REPLY; setReply(null);
ta.value = ''; ta.style.height = '24px'; bt.disabled = true; ta.blur(); paint(); ta.value = ''; if (CP) CP.clear(); ta.style.height = '24px'; bt.disabled = true; ta.blur(); paint();
if (!wasReply) box.scrollIntoView({ block: 'start', behavior: 'smooth' }); if (!wasReply) box.scrollIntoView({ block: 'start', behavior: 'smooth' });
toast(wasReply ? '回复已提交,审核通过后大家就能看到' : '已提交,审核通过后大家就能看到'); toast(wasReply ? '回复已提交,审核通过后大家就能看到' : '已提交,审核通过后大家就能看到');
}).catch(function () { bt.busy = false; bt.disabled = !ta.value.trim(); toast('网络不太好,稍后再试'); }); }).catch(function () { bt.busy = false; bt.disabled = !canSend(); toast('网络不太好,稍后再试'); });
}); });
function toast(m) { function toast(m) {
var t = document.createElement('div'); t.textContent = m; var t = document.createElement('div'); t.textContent = m;
@@ -177,13 +195,18 @@
} }
fetch(API + '/comments?kind=topic&target=' + encodeURIComponent(SLUG) + (OID ? '&openid=' + encodeURIComponent(OID) : '')) fetch(API + '/comments?kind=topic&target=' + encodeURIComponent(SLUG) + (OID ? '&openid=' + encodeURIComponent(OID) : ''))
.then(function (r) { return r.json(); }).then(function (j) { if (j && j.code === 200) { RC = j.result; paint(); } }).catch(function () {}); .then(function (r) { return r.json(); }).then(function (j) { if (j && j.code === 200) { RC = j.result; paint(); } }).catch(function () {});
getJSON('../_shared/cm/' + SLUG + '.json?v=26110458').then(function (d) { L = d.c || []; paint(); }).catch(function () { paint(); }); getJSON('../_shared/cm/' + SLUG + '.json?v=26110459').then(function (d) { L = d.c || []; paint(); }).catch(function () { paint(); });
} }
function cmPicsReady(cb) {
if (window.MBCmPics) return cb();
var s = document.createElement('script'); s.src = '../../js/cm-pics.js?v=26110459'; s.onload = function () { if (window.MBCmPics) cb(); };
document.head.appendChild(s);
}
function ugcReady() { function ugcReady() {
if (window.__mbUgcReady) return window.__mbUgcReady; if (window.__mbUgcReady) return window.__mbUgcReady;
return new Promise(function (res) { return new Promise(function (res) {
var u = document.createElement('script'); u.src = '../../js/ugc.js?v=26110458'; var u = document.createElement('script'); u.src = '../../js/ugc.js?v=26110459';
u.onload = function () { (window.__mbUgcReady || Promise.resolve(false)).then(res); }; u.onload = function () { (window.__mbUgcReady || Promise.resolve(false)).then(res); };
u.onerror = function () { res(false); }; u.onerror = function () { res(false); };
document.head.appendChild(u); document.head.appendChild(u);

View File

@@ -11,8 +11,8 @@
月数按「自然月」数:从 max(出生月, 2025-01) 起,到满 3 周岁那个月之前为止(结果标「约」,以当地核定为准)。 月数按「自然月」数:从 max(出生月, 2025-01) 起,到满 3 周岁那个月之前为止(结果标「约」,以当地核定为准)。
最多填 3 个孩子;还没出生的填预产期先算。地方另有加码的(如部分城市每孩另发)不在这里算。 最多填 3 个孩子;还没出生的填预产期先算。地方另有加码的(如部分城市每孩另发)不在这里算。
共用 ../_shared/calc.css + calc.js(返回 / 禁回弹 / 日期按北京时间 / 记住上次填的值);自成一页,不引 app.js。 --> 共用 ../_shared/calc.css + calc.js(返回 / 禁回弹 / 日期按北京时间 / 记住上次填的值);自成一页,不引 app.js。 -->
<link rel="stylesheet" href="../_shared/calc.css?v=26110458"> <link rel="stylesheet" href="../_shared/calc.css?v=26110459">
<link rel="stylesheet" href="../_shared/wizard.css?v=26110458"> <link rel="stylesheet" href="../_shared/wizard.css?v=26110459">
<style>:root{--c:#E25C5C;--c2:#FF9A8A;--cbg:#FFEFED}.kid{position:relative;margin-top:12px;padding:12px;border-radius:14px;background:#FAF7F8}.kid .lb{display:flex;justify-content:space-between}.kid .rm{font-size:12.5px;font-weight:700;color:var(--m)}.add{display:block;width:100%;height:42px;margin-top:12px;border-radius:12px;border:1.5px dashed var(--c);color:var(--c);font-size:14px;font-weight:800}.kid .seg{margin-top:8px}</style> <style>:root{--c:#E25C5C;--c2:#FF9A8A;--cbg:#FFEFED}.kid{position:relative;margin-top:12px;padding:12px;border-radius:14px;background:#FAF7F8}.kid .lb{display:flex;justify-content:space-between}.kid .rm{font-size:12.5px;font-weight:700;color:var(--m)}.add{display:block;width:100%;height:42px;margin-top:12px;border-radius:12px;border:1.5px dashed var(--c);color:var(--c);font-size:14px;font-weight:800}.kid .seg{margin-top:8px}</style>
</head> </head>
<body> <body>
@@ -46,7 +46,7 @@
<div class="tip"><b>地方可能另有补贴:</b>部分城市在国家 3600 元之外还另发生育补贴、育儿补贴,问一下当地卫健部门或看政务平台。</div> <div class="tip"><b>地方可能另有补贴:</b>部分城市在国家 3600 元之外还另发生育补贴、育儿补贴,问一下当地卫健部门或看政务平台。</div>
<p class="foot">依据《育儿补贴制度实施方案》(2025)估算,月数折算以当地核定为准。</p> <p class="foot">依据《育儿补贴制度实施方案》(2025)估算,月数折算以当地核定为准。</p>
</div> </div>
<script src="../_shared/calc.js?v=26110458"></script> <script src="../_shared/calc.js?v=26110459"></script>
<script> <script>
(function () { (function () {
'use strict'; 'use strict';
@@ -107,10 +107,10 @@
})(); })();
</script> </script>
<script src="../_shared/brand.js?v=26110203"></script> <script src="../_shared/brand.js?v=26110203"></script>
<script src="../../js/share-card.js?v=26110458"></script> <script src="../../js/share-card.js?v=26110459"></script>
<script>window.mbShare('../../assets/share/t/butie-js.jpg', '育儿补贴:每孩每年 3600 元,你家能领多少'); /* 11-04 微信转发图 */</script> <script>window.mbShare('../../assets/share/t/butie-js.jpg', '育儿补贴:每孩每年 3600 元,你家能领多少'); /* 11-04 微信转发图 */</script>
<!-- 11-04 分步模式:一步一题、最后出结果(同生娃计算器),见 ../_shared/wizard.js --> <!-- 11-04 分步模式:一步一题、最后出结果(同生娃计算器),见 ../_shared/wizard.js -->
<script src="../_shared/wizard.js?v=26110458"></script> <script src="../_shared/wizard.js?v=26110459"></script>
<script>CKW.init({ root: '.calc', res: '#res', after: '#scroll > section.calc ~ *' });</script> <script>CKW.init({ root: '.calc', res: '#res', after: '#scroll > section.calc ~ *' });</script>
</body> </body>
</html> </html>

View File

@@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<!-- 11-04 UGC 总开关关着时本页不展示,直接回首页(js/ugc.js) --> <!-- 11-04 UGC 总开关关着时本页不展示,直接回首页(js/ugc.js) -->
<script src="../../js/ugc.js?v=26110458" data-guard></script> <script src="../../js/ugc.js?v=26110459" data-guard></script>
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover"> <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
<meta name="format-detection" content="telephone=no"> <meta name="format-detection" content="telephone=no">
<title>测一测你是什么样的妈妈?</title> <title>测一测你是什么样的妈妈?</title>

View File

@@ -10,8 +10,8 @@
每次「查什么」只列常规项目,具体以产检医院安排为准。做完可以打勾(记在本机 mmbox.calc.chanjian)。 每次「查什么」只列常规项目,具体以产检医院安排为准。做完可以打勾(记在本机 mmbox.calc.chanjian)。
预产期优先用预产期计算器填过的值。 预产期优先用预产期计算器填过的值。
共用 ../_shared/calc.css + calc.js(返回 / 禁回弹 / 日期按北京时间 / 记住上次填的值);自成一页,不引 app.js。 --> 共用 ../_shared/calc.css + calc.js(返回 / 禁回弹 / 日期按北京时间 / 记住上次填的值);自成一页,不引 app.js。 -->
<link rel="stylesheet" href="../_shared/calc.css?v=26110458"> <link rel="stylesheet" href="../_shared/calc.css?v=26110459">
<link rel="stylesheet" href="../_shared/wizard.css?v=26110458"> <link rel="stylesheet" href="../_shared/wizard.css?v=26110459">
<style>:root{--c:#2F86C9;--c2:#6CB6F0;--cbg:#EAF5FF}.tl .ck{flex:none;align-self:flex-start;height:28px;padding:0 10px;margin-top:1px;border-radius:99px;background:#F4F6F8;color:var(--m);font-size:12px;font-weight:800}.tl li.ok .ck{background:var(--c);color:#fff}.tl li.ok .m{opacity:.55}.tl li.ok .d{border-color:var(--c);background:var(--c);box-shadow:none}.tl .m span.it{margin-top:3px;color:var(--t)}</style> <style>:root{--c:#2F86C9;--c2:#6CB6F0;--cbg:#EAF5FF}.tl .ck{flex:none;align-self:flex-start;height:28px;padding:0 10px;margin-top:1px;border-radius:99px;background:#F4F6F8;color:var(--m);font-size:12px;font-weight:800}.tl li.ok .ck{background:var(--c);color:#fff}.tl li.ok .m{opacity:.55}.tl li.ok .d{border-color:var(--c);background:var(--c);box-shadow:none}.tl .m span.it{margin-top:3px;color:var(--t)}</style>
</head> </head>
<body> <body>
@@ -37,7 +37,7 @@
<div class="tip"><b>要空腹的几次:</b>第一次建档抽血、糖耐(OGTT)一般要空腹,前一晚 10 点后别吃东西;具体看医院通知。<br><b>错过不能补的:</b>NT(11~13+6 周)、大排畸(20~24 周)、糖耐(24~28 周)都有时间窗口,提前预约。</div> <div class="tip"><b>要空腹的几次:</b>第一次建档抽血、糖耐(OGTT)一般要空腹,前一晚 10 点后别吃东西;具体看医院通知。<br><b>错过不能补的:</b>NT(11~13+6 周)、大排畸(20~24 周)、糖耐(24~28 周)都有时间窗口,提前预约。</div>
<p class="foot">按《孕前和孕期保健指南(2018)》常规时间排,具体项目和时间以产检医院安排为准。</p> <p class="foot">按《孕前和孕期保健指南(2018)》常规时间排,具体项目和时间以产检医院安排为准。</p>
</div> </div>
<script src="../_shared/calc.js?v=26110458"></script> <script src="../_shared/calc.js?v=26110459"></script>
<script> <script>
(function () { (function () {
'use strict'; 'use strict';
@@ -94,10 +94,10 @@
})(); })();
</script> </script>
<script src="../_shared/brand.js?v=26110203"></script> <script src="../_shared/brand.js?v=26110203"></script>
<script src="../../js/share-card.js?v=26110458"></script> <script src="../../js/share-card.js?v=26110459"></script>
<script>window.mbShare('../../assets/share/t/chanjian-js.jpg', '产检时间表:每次产检哪天去、查什么'); /* 11-04 微信转发图 */</script> <script>window.mbShare('../../assets/share/t/chanjian-js.jpg', '产检时间表:每次产检哪天去、查什么'); /* 11-04 微信转发图 */</script>
<!-- 11-04 分步模式:一步一题、最后出结果(同生娃计算器),见 ../_shared/wizard.js --> <!-- 11-04 分步模式:一步一题、最后出结果(同生娃计算器),见 ../_shared/wizard.js -->
<script src="../_shared/wizard.js?v=26110458"></script> <script src="../_shared/wizard.js?v=26110459"></script>
<script>CKW.init({ root: '.calc', res: '#res', after: '#scroll > section.calc ~ *' });</script> <script>CKW.init({ root: '.calc', res: '#res', after: '#scroll > section.calc ~ *' });</script>
</body> </body>
</html> </html>

View File

@@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<!-- 11-04 UGC 总开关关着时本页不展示,直接回首页(js/ugc.js) --> <!-- 11-04 UGC 总开关关着时本页不展示,直接回首页(js/ugc.js) -->
<script src="../../js/ugc.js?v=26110458" data-guard></script> <script src="../../js/ugc.js?v=26110459" data-guard></script>
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover"> <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
<meta name="format-detection" content="telephone=no"> <meta name="format-detection" content="telephone=no">
<title>测一测:你家准爸爸是哪种队友?</title> <title>测一测:你家准爸爸是哪种队友?</title>

View File

@@ -11,8 +11,8 @@
计算:综合所得年度税表(3%~45%,年减除 6 万);应纳税所得 = 12 ×(月薪 − 个人五险一金 − 其他专项附加)− 60000, 计算:综合所得年度税表(3%~45%,年减除 6 万);应纳税所得 = 12 ×(月薪 − 个人五险一金 − 其他专项附加)− 60000,
省的税 = 不扣宝宝那项的税 − 扣了之后的税。不含年终奖单独计税、劳务报酬等,结果为估算。 省的税 = 不扣宝宝那项的税 − 扣了之后的税。不含年终奖单独计税、劳务报酬等,结果为估算。
共用 ../_shared/calc.css + calc.js(返回 / 禁回弹 / 日期按北京时间 / 记住上次填的值);自成一页,不引 app.js。 --> 共用 ../_shared/calc.css + calc.js(返回 / 禁回弹 / 日期按北京时间 / 记住上次填的值);自成一页,不引 app.js。 -->
<link rel="stylesheet" href="../_shared/calc.css?v=26110458"> <link rel="stylesheet" href="../_shared/calc.css?v=26110459">
<link rel="stylesheet" href="../_shared/wizard.css?v=26110458"> <link rel="stylesheet" href="../_shared/wizard.css?v=26110459">
<style>:root{--c:#6C5BD6;--c2:#A595F2;--cbg:#F1EEFF}</style> <style>:root{--c:#6C5BD6;--c2:#A595F2;--cbg:#F1EEFF}</style>
</head> </head>
<body> <body>
@@ -49,7 +49,7 @@
<p class="foot">按现行个税政策估算,未含年终奖单独计税等情况,以个税 App 实际计算为准。</p> <p class="foot">按现行个税政策估算,未含年终奖单独计税等情况,以个税 App 实际计算为准。</p>
</div> </div>
<script src="../_shared/calc.js?v=26110458"></script> <script src="../_shared/calc.js?v=26110459"></script>
<script> <script>
(function () { (function () {
'use strict'; 'use strict';
@@ -82,10 +82,10 @@
})(); })();
</script> </script>
<script src="../_shared/brand.js?v=26110203"></script> <script src="../_shared/brand.js?v=26110203"></script>
<script src="../../js/share-card.js?v=26110458"></script> <script src="../../js/share-card.js?v=26110459"></script>
<script>window.mbShare('../../assets/share/t/geshui-js.jpg', '个税省多少:有宝宝一年能少交多少税'); /* 11-04 微信转发图 */</script> <script>window.mbShare('../../assets/share/t/geshui-js.jpg', '个税省多少:有宝宝一年能少交多少税'); /* 11-04 微信转发图 */</script>
<!-- 11-04 分步模式:一步一题、最后出结果(同生娃计算器),见 ../_shared/wizard.js --> <!-- 11-04 分步模式:一步一题、最后出结果(同生娃计算器),见 ../_shared/wizard.js -->
<script src="../_shared/wizard.js?v=26110458"></script> <script src="../_shared/wizard.js?v=26110459"></script>
<script>CKW.init({ root: '.calc', res: '#res', after: '#scroll > section.calc ~ *' });</script> <script>CKW.init({ root: '.calc', res: '#res', after: '#scroll > section.calc ~ *' });</script>
</body> </body>
</html> </html>

View File

@@ -11,8 +11,8 @@
本省延长的天数是否由生育保险基金支付各地不一样,结果同时给出「按国家 98 天起」和「按本省合计」两个数。 本省延长的天数是否由生育保险基金支付各地不一样,结果同时给出「按国家 98 天起」和「按本省合计」两个数。
津贴低于本人工资的,多数省份规定由单位补足差额 —— 填了本人月工资就算出差额。 津贴低于本人工资的,多数省份规定由单位补足差额 —— 填了本人月工资就算出差额。
共用 ../_shared/calc.css + calc.js(返回 / 禁回弹 / 日期按北京时间 / 记住上次填的值);自成一页,不引 app.js。 --> 共用 ../_shared/calc.css + calc.js(返回 / 禁回弹 / 日期按北京时间 / 记住上次填的值);自成一页,不引 app.js。 -->
<link rel="stylesheet" href="../_shared/calc.css?v=26110458"> <link rel="stylesheet" href="../_shared/calc.css?v=26110459">
<link rel="stylesheet" href="../_shared/wizard.css?v=26110458"> <link rel="stylesheet" href="../_shared/wizard.css?v=26110459">
<style>:root{--c:#E0812A;--c2:#FFB067;--cbg:#FFF3E6}select.in{appearance:none;-webkit-appearance:none;background-image:linear-gradient(45deg,transparent 50%,#999 50%),linear-gradient(135deg,#999 50%,transparent 50%);background-position:calc(100% - 20px) 50%,calc(100% - 15px) 50%;background-size:5px 5px;background-repeat:no-repeat}</style> <style>:root{--c:#E0812A;--c2:#FFB067;--cbg:#FFF3E6}select.in{appearance:none;-webkit-appearance:none;background-image:linear-gradient(45deg,transparent 50%,#999 50%),linear-gradient(135deg,#999 50%,transparent 50%);background-position:calc(100% - 20px) 50%,calc(100% - 15px) 50%;background-size:5px 5px;background-repeat:no-repeat}</style>
</head> </head>
<body> <body>
@@ -47,7 +47,7 @@
<div class="tip"><b>生育津贴 ≠ 生育医疗费:</b>产检、住院分娩的费用另外按生育保险报销,不在这个数里。</div> <div class="tip"><b>生育津贴 ≠ 生育医疗费:</b>产检、住院分娩的费用另外按生育保险报销,不在这个数里。</div>
<p class="foot">按《社会保险法》《女职工劳动保护特别规定》常用算法估算,实际以当地医保部门核定为准。</p> <p class="foot">按《社会保险法》《女职工劳动保护特别规定》常用算法估算,实际以当地医保部门核定为准。</p>
</div> </div>
<script src="../_shared/calc.js?v=26110458"></script> <script src="../_shared/calc.js?v=26110459"></script>
<script> <script>
(function () { (function () {
'use strict'; 'use strict';
@@ -86,10 +86,10 @@
})(); })();
</script> </script>
<script src="../_shared/brand.js?v=26110203"></script> <script src="../_shared/brand.js?v=26110203"></script>
<script src="../../js/share-card.js?v=26110458"></script> <script src="../../js/share-card.js?v=26110459"></script>
<script>window.mbShare('../../assets/share/t/jintie-js.jpg', '生育津贴计算器:产假期间能领多少钱'); /* 11-04 微信转发图 */</script> <script>window.mbShare('../../assets/share/t/jintie-js.jpg', '生育津贴计算器:产假期间能领多少钱'); /* 11-04 微信转发图 */</script>
<!-- 11-04 分步模式:一步一题、最后出结果(同生娃计算器),见 ../_shared/wizard.js --> <!-- 11-04 分步模式:一步一题、最后出结果(同生娃计算器),见 ../_shared/wizard.js -->
<script src="../_shared/wizard.js?v=26110458"></script> <script src="../_shared/wizard.js?v=26110459"></script>
<script>CKW.init({ root: '.calc', res: '#res', after: '#scroll > section.calc ~ *' });</script> <script>CKW.init({ root: '.calc', res: '#res', after: '#scroll > section.calc ~ *' });</script>
</body> </body>
</html> </html>

View File

@@ -138,9 +138,9 @@ button{font:inherit;border:0;background:none;color:inherit;cursor:pointer}
})(); })();
</script> </script>
<!-- 11-05 用户:底部加上跟趣味小测试一样的 Tab(孕期计算器 / 记一下 / 返回首页) --> <!-- 11-05 用户:底部加上跟趣味小测试一样的 Tab(孕期计算器 / 记一下 / 返回首页) -->
<script src="../../js/mb-tabbar.js?v=26110458"></script> <script src="../../js/mb-tabbar.js?v=26110459"></script>
<script>MBTab.init({ root: '../../', first: { t: '孕期计算器', ic: 'calc' } });</script> <script>MBTab.init({ root: '../../', first: { t: '孕期计算器', ic: 'calc' } });</script>
<script src="../../js/share-card.js?v=26110458"></script> <script src="../../js/share-card.js?v=26110459"></script>
<script>window.mbShare('../../assets/share/t/jisuan.jpg', '孕期计算器:生娃花费、预产期、产假天数,一算就知道'); /* 11-04 微信转发图 */</script> <script>window.mbShare('../../assets/share/t/jisuan.jpg', '孕期计算器:生娃花费、预产期、产假天数,一算就知道'); /* 11-04 微信转发图 */</script>
</body> </body>
</html> </html>

View File

@@ -10,8 +10,8 @@
对比用国家卫健委《中国居民营养与慢性病状况报告(2020 年)》18~44 岁平均身高:男 169.7 cm、女 158.0 cm。 对比用国家卫健委《中国居民营养与慢性病状况报告(2020 年)》18~44 岁平均身高:男 169.7 cm、女 158.0 cm。
身高约 70% 看遗传,营养、睡眠、运动影响剩下的部分 —— 结果只是参考范围。 身高约 70% 看遗传,营养、睡眠、运动影响剩下的部分 —— 结果只是参考范围。
共用 ../_shared/calc.css + calc.js(返回 / 禁回弹 / 日期按北京时间 / 记住上次填的值);自成一页,不引 app.js。 --> 共用 ../_shared/calc.css + calc.js(返回 / 禁回弹 / 日期按北京时间 / 记住上次填的值);自成一页,不引 app.js。 -->
<link rel="stylesheet" href="../_shared/calc.css?v=26110458"> <link rel="stylesheet" href="../_shared/calc.css?v=26110459">
<link rel="stylesheet" href="../_shared/wizard.css?v=26110458"> <link rel="stylesheet" href="../_shared/wizard.css?v=26110459">
<style>:root{--c:#1F9BA8;--c2:#5FCBD3;--cbg:#E6F7F8}.sx{display:flex;gap:10px;margin-top:12px}.sx div{flex:1;padding:10px;border-radius:12px;background:rgba(255,255,255,.18)}.sx b{display:block;font-size:22px;font-weight:900;line-height:1.3}</style> <style>:root{--c:#1F9BA8;--c2:#5FCBD3;--cbg:#E6F7F8}.sx{display:flex;gap:10px;margin-top:12px}.sx div{flex:1;padding:10px;border-radius:12px;background:rgba(255,255,255,.18)}.sx b{display:block;font-size:22px;font-weight:900;line-height:1.3}</style>
</head> </head>
<body> <body>
@@ -46,7 +46,7 @@
<p class="foot">按遗传靶身高公式估算,再按家族身高、作息和运动习惯小幅调整;实际身高受营养、睡眠、运动和疾病等影响,仅供参考。</p> <p class="foot">按遗传靶身高公式估算,再按家族身高、作息和运动习惯小幅调整;实际身高受营养、睡眠、运动和疾病等影响,仅供参考。</p>
</div> </div>
<script src="../_shared/calc.js?v=26110458"></script> <script src="../_shared/calc.js?v=26110459"></script>
<script> <script>
(function () { (function () {
'use strict'; 'use strict';
@@ -89,10 +89,10 @@
})(); })();
</script> </script>
<script src="../_shared/brand.js?v=26110203"></script> <script src="../_shared/brand.js?v=26110203"></script>
<script src="../../js/share-card.js?v=26110458"></script> <script src="../../js/share-card.js?v=26110459"></script>
<script>window.mbShare('../../assets/share/t/shengao-js.jpg', '宝宝身高预测:长大后大概多高'); /* 11-04 微信转发图 */</script> <script>window.mbShare('../../assets/share/t/shengao-js.jpg', '宝宝身高预测:长大后大概多高'); /* 11-04 微信转发图 */</script>
<!-- 11-04 分步模式:一步一题、最后出结果(同生娃计算器),见 ../_shared/wizard.js --> <!-- 11-04 分步模式:一步一题、最后出结果(同生娃计算器),见 ../_shared/wizard.js -->
<script src="../_shared/wizard.js?v=26110458"></script> <script src="../_shared/wizard.js?v=26110459"></script>
<script>CKW.init({ root: '.calc', res: '#res', after: '#scroll > section.calc ~ *' });</script> <script>CKW.init({ root: '.calc', res: '#res', after: '#scroll > section.calc ~ *' });</script>
</body> </body>
</html> </html>

View File

@@ -11,8 +11,8 @@
各地规定不一,页面写「以当地为准」。很多地方已开通「新生儿出生一件事」联办(出生证 + 户口 + 医保 + 社保卡一次办)。 各地规定不一,页面写「以当地为准」。很多地方已开通「新生儿出生一件事」联办(出生证 + 户口 + 医保 + 社保卡一次办)。
做完可以打勾(记在本机 mmbox.calc.shouxu);还没生的按预产期先排。 做完可以打勾(记在本机 mmbox.calc.shouxu);还没生的按预产期先排。
共用 ../_shared/calc.css + calc.js(返回 / 禁回弹 / 日期按北京时间 / 记住上次填的值);自成一页,不引 app.js。 --> 共用 ../_shared/calc.css + calc.js(返回 / 禁回弹 / 日期按北京时间 / 记住上次填的值);自成一页,不引 app.js。 -->
<link rel="stylesheet" href="../_shared/calc.css?v=26110458"> <link rel="stylesheet" href="../_shared/calc.css?v=26110459">
<link rel="stylesheet" href="../_shared/wizard.css?v=26110458"> <link rel="stylesheet" href="../_shared/wizard.css?v=26110459">
<style>:root{--c:#4E7FD8;--c2:#86AEF2;--cbg:#EDF3FF}.tl .ck{flex:none;align-self:flex-start;height:28px;padding:0 10px;margin-top:1px;border-radius:99px;background:#F4F6F8;color:var(--m);font-size:12px;font-weight:800}.tl li.ok .ck{background:var(--c);color:#fff}.tl li.ok .m{opacity:.55}.tl li.ok .d{border-color:var(--c);background:var(--c);box-shadow:none}.tl li.late .m b em{background:#FFE8E6;color:#E0453A}.tl .m span.w{color:var(--t)}</style> <style>:root{--c:#4E7FD8;--c2:#86AEF2;--cbg:#EDF3FF}.tl .ck{flex:none;align-self:flex-start;height:28px;padding:0 10px;margin-top:1px;border-radius:99px;background:#F4F6F8;color:var(--m);font-size:12px;font-weight:800}.tl li.ok .ck{background:var(--c);color:#fff}.tl li.ok .m{opacity:.55}.tl li.ok .d{border-color:var(--c);background:var(--c);box-shadow:none}.tl li.late .m b em{background:#FFE8E6;color:#E0453A}.tl .m span.w{color:var(--t)}</style>
</head> </head>
<body> <body>
@@ -37,7 +37,7 @@
<div class="tip"><b>先查有没有「出生一件事」:</b>很多城市在支付宝、微信或当地政务 App 上能把出生医学证明、上户口、医保参保、社保卡一次办完,不用一趟趟跑。<br><b>要准备的:</b>爸妈身份证、户口本、结婚证、出生医学证明(宝宝名字定好再办)。</div> <div class="tip"><b>先查有没有「出生一件事」:</b>很多城市在支付宝、微信或当地政务 App 上能把出生医学证明、上户口、医保参保、社保卡一次办完,不用一趟趟跑。<br><b>要准备的:</b>爸妈身份证、户口本、结婚证、出生医学证明(宝宝名字定好再办)。</div>
<p class="foot">各地规定和截止时间不完全一样,以当地公安、医保、卫健部门要求为准。</p> <p class="foot">各地规定和截止时间不完全一样,以当地公安、医保、卫健部门要求为准。</p>
</div> </div>
<script src="../_shared/calc.js?v=26110458"></script> <script src="../_shared/calc.js?v=26110459"></script>
<script> <script>
(function () { (function () {
'use strict'; 'use strict';
@@ -88,10 +88,10 @@
})(); })();
</script> </script>
<script src="../_shared/brand.js?v=26110203"></script> <script src="../_shared/brand.js?v=26110203"></script>
<script src="../../js/share-card.js?v=26110458"></script> <script src="../../js/share-card.js?v=26110459"></script>
<script>window.mbShare('../../assets/share/t/shouxu-js.jpg', '出生后手续时间线:每件事截止哪天'); /* 11-04 微信转发图 */</script> <script>window.mbShare('../../assets/share/t/shouxu-js.jpg', '出生后手续时间线:每件事截止哪天'); /* 11-04 微信转发图 */</script>
<!-- 11-04 分步模式:一步一题、最后出结果(同生娃计算器),见 ../_shared/wizard.js --> <!-- 11-04 分步模式:一步一题、最后出结果(同生娃计算器),见 ../_shared/wizard.js -->
<script src="../_shared/wizard.js?v=26110458"></script> <script src="../_shared/wizard.js?v=26110459"></script>
<script>CKW.init({ root: '.calc', res: '#res', after: '#scroll > section.calc ~ *' });</script> <script>CKW.init({ root: '.calc', res: '#res', after: '#scroll > section.calc ~ *' });</script>
</body> </body>
</html> </html>

View File

@@ -11,8 +11,8 @@
顺带提示两种溶血风险:妈妈 Rh 阴性 + 爸爸 Rh 阳性(Rh 溶血,要查抗 D 抗体);妈妈 O 型 + 爸爸非 O 型(ABO 溶血,多数轻)。 顺带提示两种溶血风险:妈妈 Rh 阴性 + 爸爸 Rh 阳性(Rh 溶血,要查抗 D 抗体);妈妈 O 型 + 爸爸非 O 型(ABO 溶血,多数轻)。
顺式 AB(cis-AB)、孟买型等罕见情况不算,页面写明。 顺式 AB(cis-AB)、孟买型等罕见情况不算,页面写明。
共用 ../_shared/calc.css + calc.js(返回 / 禁回弹 / 日期按北京时间 / 记住上次填的值);自成一页,不引 app.js。 --> 共用 ../_shared/calc.css + calc.js(返回 / 禁回弹 / 日期按北京时间 / 记住上次填的值);自成一页,不引 app.js。 -->
<link rel="stylesheet" href="../_shared/calc.css?v=26110458"> <link rel="stylesheet" href="../_shared/calc.css?v=26110459">
<link rel="stylesheet" href="../_shared/wizard.css?v=26110458"> <link rel="stylesheet" href="../_shared/wizard.css?v=26110459">
<style>:root{--c:#D9475A;--c2:#FF8A96;--cbg:#FFEDEF}.bars{margin-top:12px}.bars div{display:flex;align-items:center;gap:8px;margin-top:6px}.bars b{flex:none;width:44px;font-size:16px}.bars i{flex:1;height:12px;border-radius:99px;background:rgba(255,255,255,.25);overflow:hidden}.bars i u{display:block;height:100%;border-radius:99px;background:#fff}.bars span{flex:none;width:52px;text-align:right;font-size:14px;font-weight:800}.bars .no{opacity:.45}</style> <style>:root{--c:#D9475A;--c2:#FF8A96;--cbg:#FFEDEF}.bars{margin-top:12px}.bars div{display:flex;align-items:center;gap:8px;margin-top:6px}.bars b{flex:none;width:44px;font-size:16px}.bars i{flex:1;height:12px;border-radius:99px;background:rgba(255,255,255,.25);overflow:hidden}.bars i u{display:block;height:100%;border-radius:99px;background:#fff}.bars span{flex:none;width:52px;text-align:right;font-size:14px;font-weight:800}.bars .no{opacity:.45}</style>
</head> </head>
<body> <body>
@@ -44,7 +44,7 @@
<p class="foot">按常规遗传规律估算,不能用来做亲子鉴定;顺式 AB、孟买型等罕见血型不在计算范围。</p> <p class="foot">按常规遗传规律估算,不能用来做亲子鉴定;顺式 AB、孟买型等罕见血型不在计算范围。</p>
</div> </div>
<script src="../_shared/calc.js?v=26110458"></script> <script src="../_shared/calc.js?v=26110459"></script>
<script> <script>
(function () { (function () {
'use strict'; 'use strict';
@@ -98,10 +98,10 @@
})(); })();
</script> </script>
<script src="../_shared/brand.js?v=26110203"></script> <script src="../_shared/brand.js?v=26110203"></script>
<script src="../../js/share-card.js?v=26110458"></script> <script src="../../js/share-card.js?v=26110459"></script>
<script>window.mbShare('../../assets/share/t/xuexing-js.jpg', '宝宝血型推算:爸妈血型配宝宝会是什么型'); /* 11-04 微信转发图 */</script> <script>window.mbShare('../../assets/share/t/xuexing-js.jpg', '宝宝血型推算:爸妈血型配宝宝会是什么型'); /* 11-04 微信转发图 */</script>
<!-- 11-04 分步模式:一步一题、最后出结果(同生娃计算器),见 ../_shared/wizard.js --> <!-- 11-04 分步模式:一步一题、最后出结果(同生娃计算器),见 ../_shared/wizard.js -->
<script src="../_shared/wizard.js?v=26110458"></script> <script src="../_shared/wizard.js?v=26110459"></script>
<script>CKW.init({ root: '.calc', res: '#res', after: '#scroll > section.calc ~ *' });</script> <script>CKW.init({ root: '.calc', res: '#res', after: '#scroll > section.calc ~ *' });</script>
</body> </body>
</html> </html>

View File

@@ -71,7 +71,7 @@ button{cursor:pointer}
.tip b{color:var(--h)} .tip b{color:var(--h)}
.foot{margin:14px 20px 0;font-size:12px;color:var(--m);text-align:center;line-height:1.6} .foot{margin:14px 20px 0;font-size:12px;color:var(--m);text-align:center;line-height:1.6}
</style> </style>
<link rel="stylesheet" href="../_shared/wizard.css?v=26110458"> <link rel="stylesheet" href="../_shared/wizard.css?v=26110459">
</head> </head>
<body> <body>
<svg style="position:absolute;width:0;height:0" aria-hidden="true"><symbol id="i-back" viewBox="0 0 24 24"><path d="M15 5l-7 7 7 7"/></symbol></svg> <svg style="position:absolute;width:0;height:0" aria-hidden="true"><symbol id="i-back" viewBox="0 0 24 24"><path d="M15 5l-7 7 7 7"/></symbol></svg>
@@ -188,10 +188,10 @@ button{cursor:pointer}
})(); })();
</script> </script>
<script src="../_shared/brand.js?v=26110203"></script> <script src="../_shared/brand.js?v=26110203"></script>
<script src="../../js/share-card.js?v=26110458"></script> <script src="../../js/share-card.js?v=26110459"></script>
<script>window.mbShare('../../assets/share/t/yuchanqi-js.jpg', '预产期计算器:宝宝哪天到?还有几天见面'); /* 11-04 微信转发图 */</script> <script>window.mbShare('../../assets/share/t/yuchanqi-js.jpg', '预产期计算器:宝宝哪天到?还有几天见面'); /* 11-04 微信转发图 */</script>
<!-- 11-04 分步模式:一步一题、最后出结果(同生娃计算器),见 ../_shared/wizard.js --> <!-- 11-04 分步模式:一步一题、最后出结果(同生娃计算器),见 ../_shared/wizard.js -->
<script src="../_shared/wizard.js?v=26110458"></script> <script src="../_shared/wizard.js?v=26110459"></script>
<script>CKW.init({ root: '.calc', res: '#res', after: '#scroll > section.calc ~ *' });</script> <script>CKW.init({ root: '.calc', res: '#res', after: '#scroll > section.calc ~ *' });</script>
</body> </body>
</html> </html>

View File

@@ -9,8 +9,8 @@
价格是 2026 年市场行情的估算区间(月子中心 28 天套餐、金牌 / 普通月嫂 26 天、在家坐月子的食材营养 + 用品),按城市 × 档次取值,按天数折算; 价格是 2026 年市场行情的估算区间(月子中心 28 天套餐、金牌 / 普通月嫂 26 天、在家坐月子的食材营养 + 用品),按城市 × 档次取值,按天数折算;
不是报价,只帮用户比较三种方式的量级。改价格只改下面 P 表。 不是报价,只帮用户比较三种方式的量级。改价格只改下面 P 表。
共用 ../_shared/calc.css + calc.js(返回 / 禁回弹 / 日期按北京时间 / 记住上次填的值);自成一页,不引 app.js。 --> 共用 ../_shared/calc.css + calc.js(返回 / 禁回弹 / 日期按北京时间 / 记住上次填的值);自成一页,不引 app.js。 -->
<link rel="stylesheet" href="../_shared/calc.css?v=26110458"> <link rel="stylesheet" href="../_shared/calc.css?v=26110459">
<link rel="stylesheet" href="../_shared/wizard.css?v=26110458"> <link rel="stylesheet" href="../_shared/wizard.css?v=26110459">
<style>:root{--c:#C9658F;--c2:#F0A0C0;--cbg:#FCEEF4}</style> <style>:root{--c:#C9658F;--c2:#F0A0C0;--cbg:#FCEEF4}</style>
</head> </head>
<body> <body>
@@ -37,7 +37,7 @@
<div class="tip"><b>看月子中心记得问清:</b>价格含不含宝宝护理、产后修复、家属餐和陪护床;护士是否 24 小时、一对几;有没有医护资质和儿科医生定期巡房。<br><b>请月嫂:</b>看健康证、育婴师证,最好先面试、试工,合同写清休息和换人规则。</div> <div class="tip"><b>看月子中心记得问清:</b>价格含不含宝宝护理、产后修复、家属餐和陪护床;护士是否 24 小时、一对几;有没有医护资质和儿科医生定期巡房。<br><b>请月嫂:</b>看健康证、育婴师证,最好先面试、试工,合同写清休息和换人规则。</div>
<p class="foot">价格为 2026 年市场行情估算,各地差别很大,以实际报价为准。</p> <p class="foot">价格为 2026 年市场行情估算,各地差别很大,以实际报价为准。</p>
</div> </div>
<script src="../_shared/calc.js?v=26110458"></script> <script src="../_shared/calc.js?v=26110459"></script>
<script> <script>
(function () { (function () {
'use strict'; 'use strict';
@@ -71,10 +71,10 @@
})(); })();
</script> </script>
<script src="../_shared/brand.js?v=26110203"></script> <script src="../_shared/brand.js?v=26110203"></script>
<script src="../../js/share-card.js?v=26110458"></script> <script src="../../js/share-card.js?v=26110459"></script>
<script>window.mbShare('../../assets/share/t/yuezi-js.jpg', '月子花费:月子中心、月嫂、在家坐各花多少'); /* 11-04 微信转发图 */</script> <script>window.mbShare('../../assets/share/t/yuezi-js.jpg', '月子花费:月子中心、月嫂、在家坐各花多少'); /* 11-04 微信转发图 */</script>
<!-- 11-04 分步模式:一步一题、最后出结果(同生娃计算器),见 ../_shared/wizard.js --> <!-- 11-04 分步模式:一步一题、最后出结果(同生娃计算器),见 ../_shared/wizard.js -->
<script src="../_shared/wizard.js?v=26110458"></script> <script src="../_shared/wizard.js?v=26110459"></script>
<script>CKW.init({ root: '.calc', res: '#res', after: '#scroll > section.calc ~ *' });</script> <script>CKW.init({ root: '.calc', res: '#res', after: '#scroll > section.calc ~ *' });</script>
</body> </body>
</html> </html>

View File

@@ -10,8 +10,8 @@
孕月按 4 周一个月(孕 1~10 月);孕早期 < 14 周、孕中期 14~27+6 周、孕晚期 ≥ 28 周;37 周足月、42 周过期。 孕月按 4 周一个月(孕 1~10 月);孕早期 < 14 周、孕中期 14~27+6 周、孕晚期 ≥ 28 周;37 周足月、42 周过期。
宝宝像什么用全生态统一表 /common/baby-size.js(别自己维护)。预产期计算器填过的值直接拿来用。 宝宝像什么用全生态统一表 /common/baby-size.js(别自己维护)。预产期计算器填过的值直接拿来用。
共用 ../_shared/calc.css + calc.js(返回 / 禁回弹 / 日期按北京时间 / 记住上次填的值);自成一页,不引 app.js。 --> 共用 ../_shared/calc.css + calc.js(返回 / 禁回弹 / 日期按北京时间 / 记住上次填的值);自成一页,不引 app.js。 -->
<link rel="stylesheet" href="../_shared/calc.css?v=26110458"> <link rel="stylesheet" href="../_shared/calc.css?v=26110459">
<link rel="stylesheet" href="../_shared/wizard.css?v=26110458"> <link rel="stylesheet" href="../_shared/wizard.css?v=26110459">
<style>:root{--c:#E2668E;--c2:#FF9DB8;--cbg:#FFEEF3}.bs{display:flex;align-items:center;gap:12px;margin-top:12px;padding:10px 12px;border-radius:12px;background:rgba(255,255,255,.18)}.bs i{font-style:normal;font-size:30px;line-height:1}.bs b{display:block;font-size:15px}.chk{display:flex;align-items:center;gap:10px;margin-top:10px}.chk .in{flex:1;margin:0}.chk b{flex:none;min-width:120px;text-align:right;font-size:15px;color:var(--c)}</style> <style>:root{--c:#E2668E;--c2:#FF9DB8;--cbg:#FFEEF3}.bs{display:flex;align-items:center;gap:12px;margin-top:12px;padding:10px 12px;border-radius:12px;background:rgba(255,255,255,.18)}.bs i{font-style:normal;font-size:30px;line-height:1}.bs b{display:block;font-size:15px}.chk{display:flex;align-items:center;gap:10px;margin-top:10px}.chk .in{flex:1;margin:0}.chk b{flex:none;min-width:120px;text-align:right;font-size:15px;color:var(--c)}</style>
</head> </head>
<body> <body>
@@ -49,7 +49,7 @@
<div class="tip"><b>孕周以早孕 B 超为准:</b>月经不规律或记不清末次月经时,医生会按孕早期 B 超(头臀长)定孕周。这里算的是常规算法,仅供参考。</div> <div class="tip"><b>孕周以早孕 B 超为准:</b>月经不规律或记不清末次月经时,医生会按孕早期 B 超(头臀长)定孕周。这里算的是常规算法,仅供参考。</div>
<p class="foot">计算结果仅供参考,不能代替医生诊断。</p> <p class="foot">计算结果仅供参考,不能代替医生诊断。</p>
</div> </div>
<script src="../_shared/calc.js?v=26110458"></script> <script src="../_shared/calc.js?v=26110459"></script>
<script src="/common/baby-size.js?v=26101001"></script> <script src="/common/baby-size.js?v=26101001"></script>
<script> <script>
(function () { (function () {
@@ -109,10 +109,10 @@
})(); })();
</script> </script>
<script src="../_shared/brand.js?v=26110203"></script> <script src="../_shared/brand.js?v=26110203"></script>
<script src="../../js/share-card.js?v=26110458"></script> <script src="../../js/share-card.js?v=26110459"></script>
<script>window.mbShare('../../assets/share/t/yunzhou-js.jpg', '孕周计算器:今天孕几周几天,宝宝像什么'); /* 11-04 微信转发图 */</script> <script>window.mbShare('../../assets/share/t/yunzhou-js.jpg', '孕周计算器:今天孕几周几天,宝宝像什么'); /* 11-04 微信转发图 */</script>
<!-- 11-04 分步模式:一步一题、最后出结果(同生娃计算器),见 ../_shared/wizard.js --> <!-- 11-04 分步模式:一步一题、最后出结果(同生娃计算器),见 ../_shared/wizard.js -->
<script src="../_shared/wizard.js?v=26110458"></script> <script src="../_shared/wizard.js?v=26110459"></script>
<script>CKW.init({ root: '.calc', res: '#res', after: '#scroll > section.calc ~ *' });</script> <script>CKW.init({ root: '.calc', res: '#res', after: '#scroll > section.calc ~ *' });</script>
</body> </body>
</html> </html>

View File

@@ -12,8 +12,8 @@
某一孕周的推荐范围 = 孕早期 0~2 kg + (孕周 − 13) × 每周范围,封顶到总范围。双胎按 IOM 2009(标准没覆盖双胎)。 某一孕周的推荐范围 = 孕早期 0~2 kg + (孕周 − 13) × 每周范围,封顶到总范围。双胎按 IOM 2009(标准没覆盖双胎)。
只算范围不做记录(11-04 用户:记体重是另一个记录工具)。 只算范围不做记录(11-04 用户:记体重是另一个记录工具)。
共用 ../_shared/calc.css + calc.js(返回 / 禁回弹 / 日期按北京时间 / 记住上次填的值);自成一页,不引 app.js。 --> 共用 ../_shared/calc.css + calc.js(返回 / 禁回弹 / 日期按北京时间 / 记住上次填的值);自成一页,不引 app.js。 -->
<link rel="stylesheet" href="../_shared/calc.css?v=26110458"> <link rel="stylesheet" href="../_shared/calc.css?v=26110459">
<link rel="stylesheet" href="../_shared/wizard.css?v=26110458"> <link rel="stylesheet" href="../_shared/wizard.css?v=26110459">
<style>:root{--c:#2E9C6A;--c2:#6CCB9A;--cbg:#E8F7EF}.gauge{position:relative;height:10px;margin-top:14px;border-radius:99px;background:rgba(255,255,255,.28)}.gauge .ok{position:absolute;top:0;bottom:0;border-radius:99px;background:rgba(255,255,255,.65)}.gauge .me{position:absolute;top:50%;width:16px;height:16px;margin:-8px 0 0 -8px;border-radius:50%;background:#fff;box-shadow:0 0 0 3px rgba(0,0,0,.15)}.glab{display:flex;justify-content:space-between;margin-top:4px;font-size:11.5px;opacity:.85}</style> <style>:root{--c:#2E9C6A;--c2:#6CCB9A;--cbg:#E8F7EF}.gauge{position:relative;height:10px;margin-top:14px;border-radius:99px;background:rgba(255,255,255,.28)}.gauge .ok{position:absolute;top:0;bottom:0;border-radius:99px;background:rgba(255,255,255,.65)}.gauge .me{position:absolute;top:50%;width:16px;height:16px;margin:-8px 0 0 -8px;border-radius:50%;background:#fff;box-shadow:0 0 0 3px rgba(0,0,0,.15)}.glab{display:flex;justify-content:space-between;margin-top:4px;font-size:11.5px;opacity:.85}</style>
</head> </head>
<body> <body>
@@ -46,7 +46,7 @@
<div class="tip"><b>胖得太快或太慢都要留意:</b>增重过多容易妊娠糖尿病、巨大儿,过少可能影响宝宝发育。一周涨超过 1 公斤,或者突然腿脚、脸都肿,要尽快告诉医生。</div> <div class="tip"><b>胖得太快或太慢都要留意:</b>增重过多容易妊娠糖尿病、巨大儿,过少可能影响宝宝发育。一周涨超过 1 公斤,或者突然腿脚、脸都肿,要尽快告诉医生。</div>
<p class="foot">依据 WS/T 801—2022《妊娠期妇女体重增长推荐值标准》;双胎参考美国医学研究所 IOM 2009。仅供参考。</p> <p class="foot">依据 WS/T 801—2022《妊娠期妇女体重增长推荐值标准》;双胎参考美国医学研究所 IOM 2009。仅供参考。</p>
</div> </div>
<script src="../_shared/calc.js?v=26110458"></script> <script src="../_shared/calc.js?v=26110459"></script>
<script> <script>
(function () { (function () {
'use strict'; 'use strict';
@@ -95,10 +95,10 @@
})(); })();
</script> </script>
<script src="../_shared/brand.js?v=26110203"></script> <script src="../_shared/brand.js?v=26110203"></script>
<script src="../../js/share-card.js?v=26110458"></script> <script src="../../js/share-card.js?v=26110459"></script>
<script>window.mbShare('../../assets/share/t/zengzhong-js.jpg', '孕期增重范围:孕期胖多少才合适'); /* 11-04 微信转发图 */</script> <script>window.mbShare('../../assets/share/t/zengzhong-js.jpg', '孕期增重范围:孕期胖多少才合适'); /* 11-04 微信转发图 */</script>
<!-- 11-04 分步模式:一步一题、最后出结果(同生娃计算器),见 ../_shared/wizard.js --> <!-- 11-04 分步模式:一步一题、最后出结果(同生娃计算器),见 ../_shared/wizard.js -->
<script src="../_shared/wizard.js?v=26110458"></script> <script src="../_shared/wizard.js?v=26110459"></script>
<script>CKW.init({ root: '.calc', res: '#res', after: '#scroll > section.calc ~ *' });</script> <script>CKW.init({ root: '.calc', res: '#res', after: '#scroll > section.calc ~ *' });</script>
</body> </body>
</html> </html>

View File

@@ -203,8 +203,8 @@ html.cm .key{margin-top:26px}
html.cm:not(.cm-all) .cm-more{display:flex;align-items:center;justify-content:center;gap:4px;margin:22px 20px 0;height:46px;border-radius:99px;background:var(--cbg);color:var(--c);font-size:14.5px;font-weight:700;width:calc(100% - 40px)} html.cm:not(.cm-all) .cm-more{display:flex;align-items:center;justify-content:center;gap:4px;margin:22px 20px 0;height:46px;border-radius:99px;background:var(--cbg);color:var(--c);font-size:14.5px;font-weight:700;width:calc(100% - 40px)}
</style> </style>
<!-- 11-04 计算器模式(calc=1)走分步:一步一题、最后出结果,见 ../_shared/wizard.js --> <!-- 11-04 计算器模式(calc=1)走分步:一步一题、最后出结果,见 ../_shared/wizard.js -->
<link rel="stylesheet" href="../_shared/wizard.css?v=26110458"> <link rel="stylesheet" href="../_shared/wizard.css?v=26110459">
<script src="../_shared/wizard.js?v=26110458"></script> <script src="../_shared/wizard.js?v=26110459"></script>
</head> </head>
<body> <body>
<svg class="hide" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"> <svg class="hide" aria-hidden="true" xmlns="http://www.w3.org/2000/svg">