孕妈广场投稿:写稿页(选话题/标题/正文/配图/草稿)、我的投稿、审核结果弹窗提醒、通过稿件以「精选投稿」展示;首页广场模块挂审核结果提示;接 box_app /plaza 接口;v26110116

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
deploy
2026-11-01 09:20:45 +00:00
parent cc8cc3e98a
commit d76c212f89
3 changed files with 306 additions and 18 deletions

View File

@@ -255,6 +255,74 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
.bar.typing .ib{display:none} .bar.typing .ib{display:none}
.bar:not(.typing) .send{display:none} .bar:not(.typing) .send{display:none}
/* ---------- 投稿(11-01:用户可投稿 → 审核中 → 后台通过/不通过 → 下次打开提醒) ---------- */
.nav .mine{position:relative;flex:none;height:30px;padding:0 10px;border-radius:99px;background:#fff;border:1px solid #F0E2DA;font-size:12.5px;font-weight:800;color:#6E5A55}
.nav .mine i{position:absolute;right:-2px;top:-3px;min-width:16px;height:16px;padding:0 4px;border-radius:99px;background:#F0453A;color:#fff;font-size:10px;font-style:normal;font-weight:800;line-height:16px;text-align:center;box-shadow:0 0 0 2px #F8F3EF}
#cp{position:fixed;inset:0;z-index:50;background:#FFFBF8;display:flex;flex-direction:column;transform:translateY(100%);transition:transform .3s cubic-bezier(.2,.8,.2,1)}
#cp.show{transform:none}
#cp .cph{flex:none;display:flex;align-items:center;gap:8px;height:calc(50px + env(safe-area-inset-top));padding:env(safe-area-inset-top) 12px 0 6px;border-bottom:1px solid var(--line);background:#fff}
#cp .cph .x{width:36px;height:36px;display:grid;place-items:center;border-radius:50%;color:var(--ink)}
#cp .cph .x .ic{width:18px;height:18px}
#cp .cph h2{flex:1;margin:0;font-size:16px;font-weight:900;text-align:center}
#cp .cph .ok{flex:none;height:32px;padding:0 16px;border-radius:99px;background:var(--btn);color:#fff;font-size:14px;font-weight:900}
#cp .cph .ok:disabled{opacity:.45}
#cp .cpb{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:none;padding:14px 16px calc(24px + var(--safe-b))}
.cp-t{display:flex;align-items:center;gap:8px;width:100%;min-height:46px;padding:8px 12px;border-radius:14px;background:var(--kl,#F6EEEA);text-align:left}
.cp-t .ct2{flex:1;min-width:0;font-size:14px;font-weight:800;color:var(--kt,#6E5C57);line-height:1.4}
.cp-t .ch{flex:none;font-size:12px;font-weight:700;color:var(--muted);display:inline-flex;align-items:center}
.cp-rw{margin-top:10px;padding:9px 12px;border-radius:12px;background:#FFF1EB;font-size:12.5px;color:#9A5A44}
.cp-rw em{font-style:normal;font-weight:900;color:#E8473A}
.cp-in{display:block;width:100%;margin-top:14px;padding:4px 2px 10px;border:0;border-bottom:1px solid var(--line);background:none;outline:none;font:inherit;font-size:19px;font-weight:900;color:var(--ink)}
.cp-in::placeholder,.cp-ta::placeholder{color:#C2B0AA;font-weight:600}
.cp-ta{display:block;width:100%;min-height:260px;margin-top:12px;padding:2px;border:0;background:none;outline:none;resize:none;font:inherit;font-size:15.5px;line-height:1.8;color:#3A302C}
.cp-cnt{margin-top:4px;font-size:12px;color:var(--muted);text-align:right}
.cp-cnt b{color:#E8473A}
.cp-cnt.ok b{color:#2E8A7C}
.cp-pics{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}
.cp-pics .pt,.cp-pics .add{position:relative;width:calc((100% - 16px) / 3);aspect-ratio:1;border-radius:12px;overflow:hidden;background:#F3EAE5}
.cp-pics .pt img{width:100%;height:100%;object-fit:cover}
.cp-pics .pt.up::after{content:"上传中…";position:absolute;inset:0;display:grid;place-items:center;background:rgba(255,255,255,.6);font-size:12px;color:#6E5C57}
.cp-pics .pt.bad::after{content:"上传失败";position:absolute;inset:0;display:grid;place-items:center;background:rgba(255,255,255,.75);font-size:12px;color:#E8473A}
.cp-pics .pt button{position:absolute;right:4px;top:4px;width:22px;height:22px;border-radius:50%;background:rgba(0,0,0,.5);color:#fff;font-size:15px;line-height:22px}
.cp-pics .add{display:grid;place-items:center;border:1.5px dashed #E2CFC7;background:#FFF8F4;color:#B8A49E;font-size:12px}
.cp-pics .add .ic{display:block;margin:0 auto 4px;width:22px;height:22px}
.cp-tip{margin-top:16px;font-size:12px;line-height:1.7;color:#B8A49E}
/* 我的投稿 */
.my-e{padding:26px 0 10px;text-align:center;color:var(--muted);font-size:13.5px}
.my-it{padding:12px 0;border-bottom:1px solid #F3E9E4}
.my-it:last-child{border-bottom:0}
.my-h{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--muted)}
.my-h .tn{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.st{flex:none;height:20px;padding:0 7px;border-radius:6px;font-size:11.5px;font-weight:800;line-height:20px}
.st.pending{background:#FFF1DE;color:#C27612}
.st.approved{background:#DDF2EE;color:#21705F}
.st.rejected{background:#F2ECEA;color:#8A7570}
.my-it b{display:block;margin-top:5px;font-size:15px;font-weight:800;color:#2A1E1E}
.my-it p{margin:4px 0 0;font-size:12.5px;line-height:1.6;color:#7A6663}
.my-it p.why{padding:7px 10px;border-radius:10px;background:#F6F0EE}
.my-it p.rw2{padding:7px 10px;border-radius:10px;background:#FFF1EB;color:#9A5A44}
.my-it p.rw2 em{font-style:normal;font-weight:900;color:#E8473A}
/* 审核结果 / 提交成功弹窗 */
#rs{position:fixed;inset:0;z-index:70;display:grid;place-items:center;padding:24px;background:rgba(30,20,18,.5);opacity:0;pointer-events:none;transition:opacity .2s}
#rs.show{opacity:1;pointer-events:auto}
#rs .rsb{width:100%;max-width:320px;padding:22px 20px 18px;border-radius:22px;background:#FFFBF8;text-align:center;transform:scale(.94);transition:transform .2s}
#rs.show .rsb{transform:none}
#rs .rsi{width:58px;height:58px;margin:0 auto;border-radius:50%;display:grid;place-items:center;background:#FFEDE6;color:#F4593C}
#rs .rsi .ic{width:30px;height:30px}
#rs .rsi.ok{background:#DDF2EE;color:#2E8A7C}
#rs .rsi.no{background:#F2ECEA;color:#8A7570}
#rs h3{margin:12px 0 0;font-size:18px;font-weight:900}
#rs .rst{margin:6px 0 0;font-size:13.5px;line-height:1.7;color:#6E5C57}
#rs .rst b{color:#2A1E1E}
#rs .rst em{font-style:normal;font-weight:900;color:#E8473A}
#rs .rsw{margin-top:10px;padding:8px 10px;border-radius:10px;background:#F6F0EE;font-size:12.5px;line-height:1.6;color:#7A6663;text-align:left}
#rs .rsk{display:block;width:100%;height:42px;margin-top:16px;border-radius:99px;background:var(--btn);color:#fff;font-size:15px;font-weight:900}
/* 真实投稿:封面「精选」角标、详情配图 */
.cv .jx{position:absolute;right:.7em;top:.8em;z-index:2;height:1.55em;padding:0 .55em;border-radius:.5em;background:linear-gradient(135deg,#FFB547,#F4803C);color:#fff;font-size:.85em;font-weight:800;line-height:1.55em}
.dbody .pics{display:grid;grid-template-columns:1fr 1fr;gap:6px;margin:0 0 14px}
.dbody .pics img{width:100%;aspect-ratio:1;object-fit:cover;border-radius:10px;background:#F3EAE5}
.dbody .pics img:only-child{grid-column:1/-1;aspect-ratio:auto}
.toast{position:fixed;left:50%;top:44%;z-index:80;max-width:280px;padding:10px 16px;border-radius:12px;background:rgba(40,30,28,.86);color:#fff;font-size:13.5px;line-height:1.6;text-align:center;transform:translate(-50%,8px);opacity:0;pointer-events:none;transition:opacity .2s,transform .2s} .toast{position:fixed;left:50%;top:44%;z-index:80;max-width:280px;padding:10px 16px;border-radius:12px;background:rgba(40,30,28,.86);color:#fff;font-size:13.5px;line-height:1.6;text-align:center;transform:translate(-50%,8px);opacity:0;pointer-events:none;transition:opacity .2s,transform .2s}
.toast.show{opacity:1;transform:translate(-50%,0)} .toast.show{opacity:1;transform:translate(-50%,0)}
</style> </style>
@@ -278,6 +346,8 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
<symbol id="i-ring" viewBox="0 0 24 24"><path d="M12 20.3s-7.6-4.6-9.2-9.4C1.7 7.6 3.9 4.5 7.2 4.5c2 0 3.6 1.1 4.8 2.8 1.2-1.7 2.8-2.8 4.8-2.8 3.3 0 5.5 3.1 4.4 6.4-1.6 4.8-9.2 9.4-9.2 9.4z" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round"/></symbol> <symbol id="i-ring" viewBox="0 0 24 24"><path d="M12 20.3s-7.6-4.6-9.2-9.4C1.7 7.6 3.9 4.5 7.2 4.5c2 0 3.6 1.1 4.8 2.8 1.2-1.7 2.8-2.8 4.8-2.8 3.3 0 5.5 3.1 4.4 6.4-1.6 4.8-9.2 9.4-9.2 9.4z" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round"/></symbol>
<symbol id="i-bag" viewBox="0 0 24 24"><path d="M4 8.5h16v10.5H4zM9 8.5V6.2c0-.9.7-1.7 1.7-1.7h2.6c.9 0 1.7.8 1.7 1.7v2.3M4 13h16" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round"/></symbol> <symbol id="i-bag" viewBox="0 0 24 24"><path d="M4 8.5h16v10.5H4zM9 8.5V6.2c0-.9.7-1.7 1.7-1.7h2.6c.9 0 1.7.8 1.7 1.7v2.3M4 13h16" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round"/></symbol>
<symbol id="i-baby" viewBox="0 0 24 24"><circle cx="12" cy="12" r="8" fill="none" stroke="currentColor" stroke-width="2"/><path d="M9.2 14.6c1.6 1.4 4 1.4 5.6 0" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><circle cx="9.3" cy="10.6" r="1.1" fill="currentColor"/><circle cx="14.7" cy="10.6" r="1.1" fill="currentColor"/></symbol> <symbol id="i-baby" viewBox="0 0 24 24"><circle cx="12" cy="12" r="8" fill="none" stroke="currentColor" stroke-width="2"/><path d="M9.2 14.6c1.6 1.4 4 1.4 5.6 0" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><circle cx="9.3" cy="10.6" r="1.1" fill="currentColor"/><circle cx="14.7" cy="10.6" r="1.1" fill="currentColor"/></symbol>
<symbol id="i-check" viewBox="0 0 24 24"><path d="M5 12.5l4.5 4.5L19 7.5" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/></symbol>
<symbol id="i-clock" viewBox="0 0 24 24"><circle cx="12" cy="12" r="8.5" fill="none" stroke="currentColor" stroke-width="2"/><path d="M12 7.5V12l3 2" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></symbol>
<symbol id="i-plus" viewBox="0 0 24 24"><path d="M12 5v14M5 12h14" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/></symbol> <symbol id="i-plus" viewBox="0 0 24 24"><path d="M12 5v14M5 12h14" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/></symbol>
</svg> </svg>
@@ -286,7 +356,7 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
<div class="nav"> <div class="nav">
<button class="bk" id="back" type="button" aria-label="返回"><svg class="ic"><use href="#i-back"/></svg></button> <button class="bk" id="back" type="button" aria-label="返回"><svg class="ic"><use href="#i-back"/></svg></button>
<h1><span>孕妈广场</span></h1> <h1><span>孕妈广场</span></h1>
<span class="sp"></span> <button class="mine" id="mineBtn" type="button">我的投稿<i id="mineDot" class="hide"></i></button>
</div> </div>
<div class="cats" id="cats" role="tablist" aria-label="分类"></div> <div class="cats" id="cats" role="tablist" aria-label="分类"></div>
</div> </div>
@@ -311,12 +381,25 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
<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>
</div> </div>
</div> </div>
<div id="cp" aria-hidden="true">
<div class="cph"><button class="x" id="cpX" type="button" aria-label="关闭"><svg class="ic"><use href="#i-x"/></svg></button><h2>写我的故事</h2><button class="ok" id="cpOk" type="button">提交</button></div>
<div class="cpb">
<button type="button" class="cp-t" id="cpT"></button>
<div class="cp-rw">投稿被选中,奖励 <em>¥30</em> 现金 + <em>500</em> 兜豆</div>
<input class="cp-in" id="cpTitle" type="text" maxlength="30" placeholder="起个标题(4~30 字)">
<textarea class="cp-ta" id="cpBody" maxlength="3000" placeholder="写下你的真实经历:发生了什么、当时怎么想、后来怎么做的……写得越具体,越容易被选中。"></textarea>
<div class="cp-cnt" id="cpCnt"></div>
<div class="cp-pics" id="cpPics"><label class="add" id="cpAdd"><span><svg class="ic"><use href="#i-plus"/></svg>配图(选填)</span><input id="cpFile" type="file" accept="image/*" hidden></label></div>
<div class="cp-tip">· 提交后进入审核,审核结果会在这里提醒你;通过的故事会展示在孕妈广场。<br>· 请写自己的真实经历,不要发广告、联系方式或别人的隐私。<br>· 草稿会自动保存在这台手机上。</div>
</div>
</div>
<div id="rs" role="dialog" aria-modal="true"><div class="rsb" id="rsb"></div></div>
<div id="mask"></div> <div id="mask"></div>
<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=26110115"></script> <script src="topics.js?v=26110116"></script>
<script src="data.js?v=26110115"></script> <script src="data.js?v=26110116"></script>
<script> <script>
(function () { (function () {
'use strict'; 'use strict';
@@ -346,9 +429,10 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
'p01','p02','p03','p04','p05','p06','p07','p08','p09','p10','p11','p12','p13','p14','s01','s02','s03','s04','s05','s06','s07','s08','s09','s10', 'p01','p02','p03','p04','p05','p06','p07','p08','p09','p10','p11','p12','p13','p14','s01','s02','s03','s04','s05','s06','s07','s08','s09','s10',
'k01','k02','k03','k04','k05','k06','k07','k08','k09','k10','k11','k12','k13']; 'k01','k02','k03','k04','k05','k06','k07','k08','k09','k10','k11','k12','k13'];
var avSrc = function (key) { return '../assets/img/mom/' + AV[seed(key) % AV.length] + '.jpg'; }; var avSrc = function (key) { return '../assets/img/mom/' + AV[seed(key) % AV.length] + '.jpg'; };
var avOf = function (n) { return n.avatar || avSrc(n.author); }; /* 真实投稿用本人头像,占位笔记用头像池 */
/* ---------- 笔记:data.js 的原始内容 + 确定性补字段(id / 封面样式 / 比例 / 评论) ---------- */ /* ---------- 笔记:data.js 的原始内容 + 确定性补字段(id / 封面样式 / 比例 / 评论) ---------- */
var NOTES = [], NBY = {}; var NOTES = [], NBY = {}; /* 真实投稿到达后会往前插(loadApproved),所以 NOTES / MIXED 用 var 可重赋值 */
var RATIO = [1.12, 0.94, 1.04, 0.88, 1.18, 0.98, 0.9]; var RATIO = [1.12, 0.94, 1.04, 0.88, 1.18, 0.98, 0.9];
T.forEach(function (t, ti) { T.forEach(function (t, ti) {
var d = D[t.id]; if (!d) return; var d = D[t.id]; if (!d) return;
@@ -374,6 +458,7 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
})(); })();
var AGO = ['3 分钟前', '18 分钟前', '1 小时前', '2 小时前', '5 小时前', '昨天 21:40', '昨天 08:12', '10-29', '10-27', '10-25']; var AGO = ['3 分钟前', '18 分钟前', '1 小时前', '2 小时前', '5 小时前', '昨天 21:40', '昨天 08:12', '10-29', '10-27', '10-25'];
function commentsOf(n) { function commentsOf(n) {
if (n.real) return []; /* 真实投稿不配占位评论 */
var pool = (D[n.t] && D[n.t].comments) || [], r = rng(n.id + 'c'); var pool = (D[n.t] && D[n.t].comments) || [], r = rng(n.id + 'c');
var idx = pool.map(function (_, k) { return k; }); var idx = pool.map(function (_, k) { return k; });
for (var k = idx.length - 1; k > 0; k--) { var j = Math.floor(r() * (k + 1)); var x = idx[k]; idx[k] = idx[j]; idx[j] = x; } for (var k = idx.length - 1; k > 0; k--) { var j = Math.floor(r() * (k + 1)); var x = idx[k]; idx[k] = idx[j]; idx[j] = x; }
@@ -418,7 +503,7 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
var kbHTML = function (cat) { return '<span class="kb k-' + cat + '"><svg class="ic"><use href="#' + CAT_IC[cat] + '"/></svg>' + CAT_SHORT[cat] + '</span>'; }; var kbHTML = function (cat) { return '<span class="kb k-' + cat + '"><svg class="ic"><use href="#' + CAT_IC[cat] + '"/></svg>' + CAT_SHORT[cat] + '</span>'; };
function coverHTML(n, h) { function coverHTML(n, h) {
var t = TBY[n.t], pl = PAL[t.cat], c = pl.c[n.tone]; var t = TBY[n.t], pl = PAL[t.cat], c = pl.c[n.tone];
return '<div class="cv" style="--c1:' + c[0] + ';--c2:' + c[1] + ';--tk:' + pl.ink + ';' + (h ? 'height:' + h : '') + '">' + kbHTML(t.cat) + return '<div class="cv" style="--c1:' + c[0] + ';--c2:' + c[1] + ';--tk:' + pl.ink + ';' + (h ? 'height:' + h : '') + '">' + kbHTML(t.cat) + (n.real ? '<span class="jx">精选投稿</span>' : '') +
'<div class="ct"><div class="t1">' + esc(n.cover) + '</div><div class="t2">' + esc(n.coverSub) + '</div></div><i class="wm" aria-hidden="true">' + esc(t.g) + '</i></div>'; '<div class="ct"><div class="t1">' + esc(n.cover) + '</div><div class="t2">' + esc(n.coverSub) + '</div></div><i class="wm" aria-hidden="true">' + esc(t.g) + '</i></div>';
} }
function likeHTML(n) { function likeHTML(n) {
@@ -429,7 +514,7 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
var t = TBY[n.t]; var t = TBY[n.t];
return '<button type="button" class="nc" data-id="' + n.id + '"><div class="cvw">' + return '<button type="button" class="nc" data-id="' + n.id + '"><div class="cvw">' +
coverHTML(n, 'calc(var(--cw) * ' + n.ratio + ')') + '</div>' + coverHTML(n, 'calc(var(--cw) * ' + n.ratio + ')') + '</div>' +
'<div class="nb"><h3>' + esc(n.title) + '</h3>' + (showTopic ? '<span class="tp k-' + t.cat + '"># ' + esc(t.name) + '</span>' : '') + '<div class="nf"><img src="' + avSrc(n.author) + '" alt="" loading="lazy"><span class="nm">' + esc(n.author) + '</span>' + likeHTML(n) + '</div></div></button>'; '<div class="nb"><h3>' + esc(n.title) + '</h3>' + (showTopic ? '<span class="tp k-' + t.cat + '"># ' + esc(t.name) + '</span>' : '') + '<div class="nf"><img src="' + esc(avOf(n)) + '" alt="" loading="lazy"><span class="nm">' + esc(n.author) + '</span>' + likeHTML(n) + '</div></div></button>';
} }
/* ---------- 列表 ---------- */ /* ---------- 列表 ---------- */
@@ -502,6 +587,7 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
if (t) q.set('t', t); else q.delete('t'); if (t) q.set('t', t); else q.delete('t');
if (!t && catF) q.set('c', catF); else q.delete('c'); /* 只选了分类没选话题时记在 ?c=,刷新 / 详情返回还在原分类 */ if (!t && catF) q.set('c', catF); else q.delete('c'); /* 只选了分类没选话题时记在 ?c=,刷新 / 详情返回还在原分类 */
if (n) q.set('n', n); else q.delete('n'); if (n) q.set('n', n); else q.delete('n');
q.delete('mine');
var s = q.toString(); var s = q.toString();
return location.pathname + (s ? '?' + s : '') + location.hash; /* hash(身份)原样保留 */ return location.pathname + (s ? '?' + s : '') + location.hash; /* hash(身份)原样保留 */
} }
@@ -532,6 +618,7 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
sheetOn = kind; $('#sbd').innerHTML = html; $('#sbd').scrollTop = 0; sheetOn = kind; $('#sbd').innerHTML = html; $('#sbd').scrollTop = 0;
$('#mask').classList.add('show'); $('#sheet').classList.add('show'); $('#mask').classList.add('show'); $('#sheet').classList.add('show');
} }
var pickFor = '';
function closeSheet() { sheetOn = ''; $('#mask').classList.remove('show'); $('#sheet').classList.remove('show'); } function closeSheet() { sheetOn = ''; $('#mask').classList.remove('show'); $('#sheet').classList.remove('show'); }
function openRule(tid) { function openRule(tid) {
var t = TBY[tid]; var t = TBY[tid];
@@ -542,8 +629,8 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
'<li><b>选一个话题</b><small>在「热门话题」或「全部话题」里挑你有话说的那个</small></li>' + '<li><b>选一个话题</b><small>在「热门话题」或「全部话题」里挑你有话说的那个</small></li>' +
'<li><b>写下你的真实经历</b><small>家里的暖事、踩过的坑、过来人的经验都可以</small></li>' + '<li><b>写下你的真实经历</b><small>家里的暖事、踩过的坑、过来人的经验都可以</small></li>' +
'<li><b>编辑挑选,被选中就发奖励</b><small>选中的故事会展示在孕妈广场,奖励发给作者</small></li></ol>' + '<li><b>编辑挑选,被选中就发奖励</b><small>选中的故事会展示在孕妈广场,奖励发给作者</small></li></ol>' +
'<button type="button" class="sbtn" data-write="' + (t ? t.id : '') + '">' + (t ? '写我的故事' : '去选话题') + '</button>' + '<button type="button" class="sbtn" data-write="' + (t ? t.id : '') + '">写我的故事</button>' +
'<div class="snote">投稿通道即将开放,开放后会在首页通知你</div>'); '<div class="snote">提交后进入审核,审核结果会在孕妈广场提醒你</div>');
} }
function openTopics() { function openTopics() {
var grp = function (cat) { var grp = function (cat) {
@@ -557,12 +644,11 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
$('#mask').addEventListener('click', closeSheet); $('#mask').addEventListener('click', closeSheet);
$('#sheet').addEventListener('click', function (e) { $('#sheet').addEventListener('click', function (e) {
var p = e.target.closest('[data-pick]'); var p = e.target.closest('[data-pick]');
if (p && pickFor === 'compose') { closeSheet(); pickFor = ''; if (p.dataset.pick) setCpTopic(p.dataset.pick); return; }
if (p) { closeSheet(); haptic(); if (!p.dataset.pick) catF = ''; selectTopic(p.dataset.pick); return; } if (p) { closeSheet(); haptic(); if (!p.dataset.pick) catF = ''; selectTopic(p.dataset.pick); return; }
var w = e.target.closest('[data-write]'); var w = e.target.closest('[data-write]');
if (w) { if (w) { closeSheet(); openCompose(w.dataset.write || cur); return; }
if (w.dataset.write) { toast('投稿通道即将开放,开放后会在首页通知你'); return; } if (e.target.closest('[data-mywrite]')) { closeSheet(); openCompose(cur); }
closeSheet(); if (openId) closeNote(); setTimeout(openTopics, 300);
}
}); });
/* 卡片:点心形就地点赞,点别处进详情 */ /* 卡片:点心形就地点赞,点别处进详情 */
@@ -628,16 +714,18 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
var n = NBY[id]; if (!n) return; var n = NBY[id]; if (!n) return;
var t = TBY[n.t]; var t = TBY[n.t];
openId = id; openId = id;
$('#dav').src = avSrc(n.author); $('#dav').src = avOf(n);
$('#dnm').textContent = n.author; $('#dnm').textContent = n.author;
$('#dst').textContent = n.stage || ''; $('#dst').textContent = n.stage || '';
var fo = $('#dfo'); fo.classList.toggle('on', !!ME.fo[n.author]); fo.textContent = ME.fo[n.author] ? '已关注' : '关注'; var fo = $('#dfo'); fo.classList.toggle('on', !!ME.fo[n.author]); fo.textContent = ME.fo[n.author] ? '已关注' : '关注';
var h = Math.round(window.innerWidth * .72); /* 详情封面统一矮一点,正文早点露出来 */ var h = Math.round(window.innerWidth * .72); /* 详情封面统一矮一点,正文早点露出来 */
var day = 26 + (seed(n.id) % 6), mon = day > 31 ? 11 : 10; var day = 26 + (seed(n.id) % 6), mon = day > 31 ? 11 : 10;
var when = n.real ? (function (d) { return (d.getMonth() + 1) + '-' + d.getDate(); })(new Date(n.at)) : mon + '-' + (day > 31 ? day - 31 : day);
$('#dsc').innerHTML = '<div class="dcv">' + coverHTML(n, h + 'px') + '</div>' + $('#dsc').innerHTML = '<div class="dcv">' + coverHTML(n, h + 'px') + '</div>' +
'<div class="dbody"><div class="dk">' + kbHTML(t.cat) + '<button type="button" class="k-' + t.cat + '" data-go="' + t.id + '"># ' + esc(t.name) + '</button></div>' + '<div class="dbody"><div class="dk">' + kbHTML(t.cat) + '<button type="button" class="k-' + t.cat + '" data-go="' + t.id + '"># ' + esc(t.name) + '</button></div>' +
'<h2>' + esc(n.title) + '</h2><div class="tx">' + bodyHTML(n.body) + '</div>' + '<h2>' + esc(n.title) + '</h2><div class="tx">' + bodyHTML(n.body) + '</div>' +
'<div class="tm">' + mon + '-' + (day > 31 ? day - 31 : day) + ' · ' + esc(n.stage || '') + '</div></div>' + ((n.images || []).length ? '<div class="pics">' + n.images.map(function (u) { return '<img src="' + esc(u) + '" alt="" loading="lazy">'; }).join('') + '</div>' : '') +
'<div class="tm">' + when + (n.stage ? ' · ' + esc(n.stage) : '') + (n.real ? ' · 妈妈投稿' : '') + '</div></div>' +
'<div class="pj k-' + t.cat + '"><span class="pt"><b>你也有类似的经历?</b><small>投稿被选中得 ' + REWARD + '</small></span><button type="button" data-join="' + t.id + '">参与话题</button></div>' + '<div class="pj k-' + t.cat + '"><span class="pt"><b>你也有类似的经历?</b><small>投稿被选中得 ' + REWARD + '</small></span><button type="button" data-join="' + t.id + '">参与话题</button></div>' +
'<div class="cm" id="cmw"><div class="cm-h" id="cmh"></div>' + '<div class="cm" id="cmw"><div class="cm-h" id="cmh"></div>' +
'<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>' +
@@ -719,6 +807,179 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
toast('评论已发出'); toast('评论已发出');
} }
/* ================= 投稿(2026-11-01) =================
用户原话:「用户的账号可以去投稿……提交之后会显示『正在被审核』。如果用户的稿件被通过,后台会给他一个提醒」。
接口 box_app /api/mp/public/mama-box/plaza/*(只认 openid):
POST post {topic,title,body,images[]} → 稿件(pending)· GET mine → {list, unread} · POST mine/seen {ids}
GET posts?limit= → 已通过的稿件(不含 openid),混进广场展示,封面标「精选投稿」。
审核在管理后台「孕妈广场投稿」页;通过 = 被选中,奖励 ¥30 现金 + 500 兜豆由运营线下发放、后台标记。
· 提醒:每次打开广场拉 mine,unread(审核有结果且没提醒过)逐条弹窗,关掉后 seen。首页广场模块也会挂一条提示(app.js initPlaza)。
· 草稿存本机 mmbox.gc.draft.v1(按 openid),关掉写稿页不丢。 */
var API = '/api/mp/public/mama-box/plaza', UNION = param('unionid');
var idq = function () { return 'openid=' + encodeURIComponent(OPENID) + (UNION ? '&unionid=' + encodeURIComponent(UNION) : ''); };
var getJ = function (u, opt) { return fetch(u, opt).then(function (r) { return r.json(); }); };
var ST_NAME = { pending: '审核中', approved: '已通过', rejected: '未通过' };
var MINE = [];
/* 已通过的稿件 → 混进笔记流(话题流和「全部」都排最前) */
function loadApproved() {
getJ(API + '/posts?limit=100').then(function (j) {
var l = (j && j.result && (j.result.list || j.result)) || [];
if (!Array.isArray(l) || !l.length) return;
var add = [];
l.forEach(function (p, k) {
if (!TBY[p.topic] || NBY['u-' + p.id]) return;
var o = { id: 'u-' + p.id, t: p.topic, real: true, title: p.title, cover: p.title.length > 9 ? p.title.slice(0, 8) + '…' : p.title, coverSub: '来自妈妈的真实投稿',
author: p.nickname || '孕妈', avatar: p.avatar || '', stage: p.stage || '', likes: 0, body: p.body || '', images: p.images || [],
at: p.approvedAt || p.at || Date.now(), ratio: RATIO[k % RATIO.length], tone: k % 3 };
NBY[o.id] = o; add.push(o);
});
if (!add.length) return;
NOTES = add.concat(NOTES); MIXED = add.concat(MIXED);
renderFeed();
if (deep && NBY[deep] && !openId) openNote(deep, false); /* 分享出去的真实投稿链接:稿件到了再开 */
}).catch(function () {});
}
/* 我的投稿 */
function loadMine(cb) {
if (!OPENID) return;
getJ(API + '/mine?' + idq()).then(function (j) {
var r = j && j.result; if (!r) return;
MINE = r.list || [];
var un = r.unread || [];
var d = $('#mineDot'); d.textContent = un.length || ''; d.classList.toggle('hide', !un.length);
if (cb) cb(); else if (un.length) showResults(un);
}).catch(function () {});
}
function fmtDay(ms) { var d = new Date(ms); return (d.getMonth() + 1) + '月' + d.getDate() + '日'; }
function openMine() {
var h = '<h3>我的投稿</h3>';
if (!OPENID) h += '<div class="my-e">请从小程序里打开孕妈广场,才能查看你的投稿</div>';
else if (!MINE.length) h += '<div class="my-e">还没有投稿,写下你的第一个故事吧</div>';
else h += MINE.map(function (p) {
var t = TBY[p.topic];
return '<div class="my-it"><div class="my-h"><span class="tn"># ' + esc(t ? t.name : p.topicName || '') + '</span><span>' + fmtDay(p.at) + '</span><span class="st ' + p.status + '">' + (ST_NAME[p.status] || '') + '</span></div>' +
'<b>' + esc(p.title) + '</b>' +
(p.status === 'pending' ? '<p>正在审核中,有结果会第一时间提醒你</p>' : '') +
(p.status === 'rejected' ? '<p class="why">没通过的原因:' + esc(p.reason || '暂不符合展示要求') + '</p>' : '') +
(p.status === 'approved' ? '<p class="rw2">已被选中,奖励 <em>¥30</em> 现金 + <em>500</em> 兜豆 · ' + (p.reward === 'paid' ? '已发放' : '待发放') + '</p>' : '') + '</div>';
}).join('');
h += '<button type="button" class="sbtn" data-mywrite="1" style="margin-top:16px">写新的故事</button>';
openSheet('mine', h);
}
$('#mineBtn').addEventListener('click', function () { haptic(); loadMine(openMine); openMine(); });
/* 审核结果弹窗:逐条弹,全部看完一次性 seen */
function showResults(list) {
var q = list.slice(), ids = list.map(function (p) { return p.id; });
(function next() {
var p = q.shift();
if (!p) {
fetch(API + '/mine/seen?' + idq(), { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ ids: ids }) }).catch(function () {});
$('#mineDot').classList.add('hide');
return;
}
var ok = p.status === 'approved';
showRs(ok ? 'ok' : 'no', ok ? '你的投稿通过啦' : '这篇投稿没有通过',
'《<b>' + esc(p.title) + '</b>》' + (ok ? '已被选中,将展示在孕妈广场。<br>奖励 <em>¥30</em> 现金 + <em>500</em> 兜豆,工作人员会尽快发放。' : '暂时没有通过审核,可以修改后重新投稿。'),
ok ? '' : '原因:' + esc(p.reason || '暂不符合展示要求'), q.length ? '下一条' : '知道了', next);
})();
}
function showRs(kind, title, text, why, btn, cb) {
$('#rsb').innerHTML = '<div class="rsi ' + kind + '"><svg class="ic"><use href="#' + (kind === 'ok' ? 'i-check' : kind === 'no' ? 'i-x' : 'i-clock') + '"/></svg></div>' +
'<h3>' + title + '</h3><p class="rst">' + text + '</p>' + (why ? '<div class="rsw">' + why + '</div>' : '') + '<button type="button" class="rsk" id="rsk">' + btn + '</button>';
$('#rs').classList.add('show');
$('#rsk').onclick = function () { $('#rs').classList.remove('show'); if (cb) setTimeout(cb, 220); };
}
/* 写稿页 */
var DK = 'mmbox.gc.draft.v1', cpTopic = '', pics = [], ups = 0;
function draft(v) {
try {
var all = JSON.parse(localStorage.getItem(DK) || '{}') || {};
if (v === undefined) return all[UK] || {};
if (v) all[UK] = v; else delete all[UK];
localStorage.setItem(DK, JSON.stringify(all));
} catch (e) { return {}; }
}
function setCpTopic(id) {
cpTopic = TBY[id] ? id : '';
var t = TBY[cpTopic], b = $('#cpT');
b.className = 'cp-t' + (t ? ' k-' + t.cat : '');
b.innerHTML = (t ? kbHTML(t.cat) + '<span class="ct2"># ' + esc(t.name) + '</span>' : '<span class="ct2">选择要参与的话题</span>') +
'<span class="ch">' + (t ? '换话题' : '去选') + '<svg class="ic" style="width:13px;height:13px"><use href="#i-right"/></svg></span>';
saveDraft();
}
function cnt() {
var n = $('#cpBody').value.trim().length, c = $('#cpCnt');
c.className = 'cp-cnt' + (n >= 300 ? ' ok' : '');
c.innerHTML = '已写 <b>' + n + '</b> 字 · ' + (n < 50 ? '至少 50 字' : n < 300 ? '写到 300 字以上更容易被选中' : '很棒,继续写也可以');
}
function saveDraft() { draft({ t: cpTopic, a: $('#cpTitle').value, b: $('#cpBody').value }); }
function openCompose(tid) {
if (!OPENID) { toast('请从小程序里打开孕妈广场再投稿'); return; }
if (openId) closeNote();
var d = draft();
$('#cpTitle').value = d.a || ''; $('#cpBody').value = d.b || '';
setCpTopic(tid || d.t || '');
cnt();
$('#cp').classList.add('show'); $('#cp').setAttribute('aria-hidden', 'false');
}
function closeCompose() { saveDraft(); $('#cp').classList.remove('show'); $('#cp').setAttribute('aria-hidden', 'true'); document.activeElement && document.activeElement.blur(); }
$('#cpX').addEventListener('click', closeCompose);
$('#cpT').addEventListener('click', function () { pickFor = 'compose'; openTopics(); });
$('#cpTitle').addEventListener('input', saveDraft);
$('#cpBody').addEventListener('input', function () { cnt(); saveDraft(); });
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;
});
}
var syncAdd = function () { $('#cpAdd').classList.toggle('hide', pics.length >= 6); };
$('#cpFile').addEventListener('change', function () {
var f = this.files && this.files[0]; this.value = '';
if (!f || pics.length >= 6) return;
var it = { url: null, el: document.createElement('span') };
it.el.className = 'pt up';
it.el.innerHTML = '<img alt=""><button type="button" aria-label="删除这张">×</button>';
it.el.querySelector('img').src = URL.createObjectURL(f);
it.el.querySelector('button').onclick = function () { pics = pics.filter(function (x) { return x !== it; }); it.el.remove(); syncAdd(); };
$('#cpPics').insertBefore(it.el, $('#cpAdd')); pics.push(it); syncAdd(); ups++;
shrink(f).then(function (b) { var fd = new FormData(); fd.append('file', b, 'plaza.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 () { toast('图片上传失败,可以删掉重新选'); it.el.classList.remove('up'); it.el.classList.add('bad'); })
.then(function () { ups--; });
});
$('#cpOk').addEventListener('click', function () {
var btn = this, title = $('#cpTitle').value.trim(), body = $('#cpBody').value.trim();
if (!cpTopic) { toast('先选一个要参与的话题'); return; }
if (title.length < 4) { toast('标题至少 4 个字'); return; }
if (body.length < 50) { toast('正文至少 50 个字,再多写一点吧'); return; }
if (ups > 0) { toast('图片还在上传,稍等一下'); return; }
btn.disabled = true; btn.textContent = '提交中';
getJ(API + '/post?' + idq(), { method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ topic: cpTopic, title: title, body: body, images: pics.map(function (x) { return x.url; }).filter(Boolean) }) })
.then(function (j) {
if (!j || j.code !== 200 || !j.result) { toast((j && j.message) || '提交失败,请稍后再试'); return; }
MINE.unshift(j.result);
draft(null); pics.forEach(function (x) { x.el.remove(); }); pics = []; syncAdd();
$('#cpTitle').value = ''; $('#cpBody').value = '';
closeCompose(); haptic();
showRs('wait', '已提交,正在审核中', '《<b>' + esc(title) + '</b>》已经交给编辑审核,<br>有结果会在这里提醒你。', '', '好的');
})
.catch(function () { toast('网络不太好,请稍后再试(草稿已保存)'); })
.then(function () { btn.disabled = false; btn.textContent = '提交'; });
});
/* ---------- 返回 ---------- */ /* ---------- 返回 ---------- */
function homeURL() { function homeURL() {
var q = new URLSearchParams(location.search); q.delete('t'); q.delete('n'); q.delete('c'); var q = new URLSearchParams(location.search); q.delete('t'); q.delete('n'); q.delete('c');
@@ -769,6 +1030,13 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
if (CAT_ORDER.indexOf(c0) >= 0) catF = c0; if (CAT_ORDER.indexOf(c0) >= 0) catF = c0;
selectTopic(param('t') && TBY[param('t')] ? param('t') : '', false); selectTopic(param('t') && TBY[param('t')] ? param('t') : '', false);
if (deep && NBY[deep]) openNote(deep, false); if (deep && NBY[deep]) openNote(deep, false);
loadApproved();
if (new URLSearchParams(location.search).get('mine') === '1') {
loadMine(function () {
var un = MINE.filter(function (p) { return !p.seen && p.status !== 'pending'; });
if (un.length) showResults(un); else openMine();
});
} else loadMine();
var rt; window.addEventListener('resize', function () { clearTimeout(rt); rt = setTimeout(renderFeed, 150); }); var rt; window.addEventListener('resize', function () { clearTimeout(rt); rt = setTimeout(renderFeed, 150); });
})(); })();
</script> </script>

View File

@@ -7,7 +7,7 @@
<meta name="mobile-web-app-capable" content="yes"> <meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes">
<title>兜爸心选 · 孕育陪伴</title> <title>兜爸心选 · 孕育陪伴</title>
<!-- V:26110115 缓存版本标记:改 css/js 时同步 bump 该值(与 js/app.js 的 VER 同源),静态资源按 mtime 走 ETag 自动刷新 --> <!-- V:26110116 缓存版本标记:改 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">
<!-- 夜晚模式:首屏绘制前就按上次的选择加 class,避免先白后黑闪一下(开关在首页右上角 #nightBtn,逻辑见 app.js) --> <!-- 夜晚模式:首屏绘制前就按上次的选择加 class,避免先白后黑闪一下(开关在首页右上角 #nightBtn,逻辑见 app.js) -->
@@ -520,6 +520,10 @@
.gch-head{flex-wrap:wrap;row-gap:10px} .gch-head{flex-wrap:wrap;row-gap:10px}
#gchCat{order:3;flex-basis:100%} #gchCat{order:3;flex-basis:100%}
#gchCat button{flex:1;height:28px;font-size:13px;white-space:nowrap} #gchCat button{flex:1;height:28px;font-size:13px;white-space:nowrap}
.gch-note{display:flex;align-items:center;gap:8px;width:100%;margin:10px 0 0;padding:9px 12px;border:0;border-radius:14px;background:#FFF1DE;font:inherit;font-size:13px;font-weight:800;color:#A86312;text-align:left}
.gch-note span{flex:1;min-width:0}
.gch-note i{flex:none;font-style:normal;font-size:12px;font-weight:800}
.gch-note.ok{background:linear-gradient(120deg,#FF8A5B,#F4593C);color:#fff;box-shadow:0 8px 16px -10px #F4593C}
.gch-title{flex:none;margin:0;font-size:21px;font-weight:900;letter-spacing:.5px;color:#2A1E1E} .gch-title{flex:none;margin:0;font-size:21px;font-weight:900;letter-spacing:.5px;color:#2A1E1E}
.gch-title span{background:linear-gradient(transparent 58%,#FFD0DC 58%,#FFD0DC 92%,transparent 92%);padding:0 3px} .gch-title span{background:linear-gradient(transparent 58%,#FFD0DC 58%,#FFD0DC 92%,transparent 92%);padding:0 3px}
.gch-cat{display:flex;padding:2px;border-radius:99px;background:rgba(240,222,214,.7)} .gch-cat{display:flex;padding:2px;border-radius:99px;background:rgba(240,222,214,.7)}
@@ -2400,7 +2404,7 @@
<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=26110115"></script> <script src="guangchang/topics.js?v=26110116"></script>
<script src="js/app.js"></script> <script src="js/app.js"></script>
<!-- 2026-10-03 首页彩蛋:宝宝在肚皮底下动(独立文件,删掉这一行即整体下线;开关在「隐私权限」) --> <!-- 2026-10-03 首页彩蛋:宝宝在肚皮底下动(独立文件,删掉这一行即整体下线;开关在「隐私权限」) -->
<script src="js/bump.js"></script> <script src="js/bump.js"></script>
@@ -2409,7 +2413,7 @@
<!-- 2026-10-05 首页头图:宝宝时不时动一动小手小脚(独立文件,删掉这一行即下线) --> <!-- 2026-10-05 首页头图:宝宝时不时动一动小手小脚(独立文件,删掉这一行即下线) -->
<script src="js/baby-limbs.js?v=26101201"></script> <script src="js/baby-limbs.js?v=26101201"></script>
<script src="js/coach.js?v=26101211"></script> <script src="js/coach.js?v=26101211"></script>
<script src="js/birth-flow.js?v=26110115"></script> <script src="js/birth-flow.js?v=26110116"></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 = '26110115'; var VER = '26110116';
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));
@@ -4224,6 +4224,22 @@
$('#gchCnt').innerHTML = '<b>' + fmtNum(talk) + '</b> 位妈妈正在聊'; $('#gchCnt').innerHTML = '<b>' + fmtNum(talk) + '</b> 位妈妈正在聊';
$('#gchAvs').innerHTML = ['p05', 'm07', 's03', 'k09', 'm16'].map(n => '<img src="' + avaSrc(n) + '" alt="" loading="lazy">').join(''); $('#gchAvs').innerHTML = ['p05', 'm07', 's03', 'k09', 'm16'].map(n => '<img src="' + avaSrc(n) + '" alt="" loading="lazy">').join('');
sec.classList.remove('hide'); sec.classList.remove('hide');
/* 投稿审核提醒(11-01):有结果且没看过 → 模块里挂一条提示,点进广场 ?mine=1 弹结果(广场页弹完才标已读) */
const oid = hashParam('openid');
if (oid) fetch('/api/mp/public/mama-box/plaza/mine?openid=' + encodeURIComponent(oid)).then(r => r.json()).then(j => {
const un = (j && j.result && j.result.unread) || [];
if (!un.length) return;
const ok = un.some(p => p.status === 'approved'), b = document.createElement('button');
b.type = 'button'; b.className = 'gch-note' + (ok ? ' ok' : '');
b.innerHTML = '<span>' + (ok ? '你的投稿通过啦!奖励 ¥30 现金 + 500 兜豆' : '你的投稿有审核结果了') + '</span><i>去看看 ›</i>';
b.addEventListener('click', () => {
haptic();
const url = 'guangchang/?mine=1' + location.hash;
reportHostLocation(new URL(url, location.href).href);
location.href = url;
});
$('.gch-who', sec).before(b);
}).catch(() => {});
row.addEventListener('click', e => { const b = e.target.closest('.gch-card'); if (b) go(b.dataset.t); }); row.addEventListener('click', e => { const b = e.target.closest('.gch-card'); if (b) go(b.dataset.t); });
$('#gchMore').addEventListener('click', () => go('')); $('#gchMore').addEventListener('click', () => go(''));
$('#gchCat').addEventListener('click', e => { $('#gchCat').addEventListener('click', e => {