我的资料
diff --git a/js/app.js b/js/app.js
index 2d1e3aa..bf40b79 100644
--- a/js/app.js
+++ b/js/app.js
@@ -3,7 +3,7 @@
(function () {
'use strict';
/* 页面版本号(YYMMDD+序号):显示在「关于兜爸心选」页底部;bump 时同步 head 注释与 ?v= */
- var VER = '26100106';
+ var VER = '26100107';
const $ = (s, c) => (c || document).querySelector(s);
const $$ = (s, c) => Array.from((c || document).querySelectorAll(s));
@@ -3281,11 +3281,24 @@
return bbApi('blindbox').then(j => {
if (!j || j.code !== 200 || !j.result) return;
BB = j.result;
+ (BB.newRewards || []).forEach(g => bxPrizeQ.push(g));
renderBanner();
if (BB.backfilled > 0) setTimeout(() => toast('错过的 ' + BB.backfilled + ' 张宝宝卡已补给你,去卡册看看吧'), 1800);
- if ($('#detailBox').classList.contains('show')) renderBox();
+ if ($('#detailBox').classList.contains('show')) {
+ renderBox();
+ if (bxPrizeQ.length && !bbBusy && !$('#bxReveal').classList.contains('show')) setTimeout(showPrize, 400);
+ }
}).catch(() => { /* 静默:横幅保持现状 */ });
}
+ /* 最近的一个集齐目标:先看当前孕周所在的那段,集齐了再看全集。用于「离孕中期大奖还差 3 张」 */
+ function bxGoal() {
+ const ss = (BB && BB.stages) || [];
+ const cur = ss.find(x => x.key !== 'all' && BB.week >= x.from && BB.week <= x.to && !x.complete);
+ const g = cur || ss.find(x => x.key === 'all' && !x.complete);
+ return g && g.left > 0 ? g : null;
+ }
+ const BX_TASK_ICO = { kick3: '👶', weight: '⚖️', tool: '📅' };
+ let bxLockSel = null, bxPrizeQ = [];
function renderBanner() {
const ban = $('#bbBanner');
const set = (t, s, cta, ready, calm) => {
@@ -3309,8 +3322,13 @@
if (op.length > 1) { badge.textContent = op.length; badge.classList.remove('hide'); }
if (BB.ended) set('我的孕期卡册', got + ' 张宝宝卡,永久保留', '去看看', false, true);
else if (!BB.currentOpened && op.indexOf(BB.week) >= 0) set('孕 ' + BB.week + ' 周的盲盒到了', got + ' · 免费开启', '去开启', true);
- else if (op.length) set('还有 ' + op.length + ' 个盲盒没开', '错过的周也能补开 · ' + got, '去补开', true);
- else set(BB.nextIn ? '下一个盲盒 ' + BB.nextIn + ' 天后到' : '本周盲盒已开启', got + (BB.flash ? ' · 闪卡
' + BB.flash + ' 张' : ''), '看卡册', false, true);
+ else if (op.length) set('还有 ' + op.length + ' 个盲盒没开', '已解锁,随时补开 · ' + got, '去补开', true);
+ else if ((BB.locked || []).length && BB.credits) set('可以解锁 ' + BB.credits + ' 个错过的盲盒', '你完成了孕期小任务 · ' + got, '去解锁', true);
+ else {
+ const g = bxGoal();
+ set(BB.nextIn ? '下一个盲盒 ' + BB.nextIn + ' 天后到' : '本周盲盒已开启',
+ g ? '离' + g.name + '大奖还差
' + g.left + ' 张' : got + (BB.flash ? ' · 闪卡
' + BB.flash + ' 张' : ''), '看卡册', false, true);
+ }
}
/* 盲盒入口:首页横幅 + 「我的」页卡册行(#meBoxCard)走同一条路 */
function openBoxEntry() {
@@ -3319,6 +3337,7 @@
bbSel = null;
renderBox();
openPanel('detailBox');
+ if (bxPrizeQ.length) setTimeout(showPrize, 600);
}
$('#bbBanner').addEventListener('click', openBoxEntry);
$('#meBoxCard').addEventListener('click', openBoxEntry);
@@ -3349,6 +3368,43 @@
btn.textContent = '看看这张卡';
}
$('#bxMisc').textContent = (BB.weekOpeners >= 50) ? '本周已有 ' + fmtN(BB.weekOpeners) + ' 位妈妈开了盲盒' : '每周一个 · 完全免费';
+ /* 下周预告:剪影 + 倒计时(本周已开时才露出来,免得和「开启盲盒」抢视线) */
+ const nx = BB.next, nxEl = $('#bxNext');
+ nxEl.classList.toggle('hide', !(nx && !bbSel && !BB.ended));
+ if (nx && !bbSel && !BB.ended) {
+ $('#bxNextImg').innerHTML = cardImgHTML(nx.week);
+ $('#bxNextW').textContent = '孕 ' + nx.week + ' 周 · 下周预告';
+ $('#bxNextS').textContent = nx.size ? '宝宝会长到' + nx.size.name + '那么大' : '';
+ $('#bxNextD').textContent = nx.inDays;
+ }
+ /* 待解锁 + 任务 */
+ const lk = BB.locked || [], lkEl = $('#bxLock');
+ lkEl.classList.toggle('hide', !lk.length);
+ if (lk.length) {
+ if (lk.indexOf(bxLockSel) < 0) bxLockSel = lk[lk.length - 1];
+ $('#bxLockN').textContent = lk.length;
+ $('#bxLockChips').innerHTML = lk.map(w => '
').join('');
+ $('#bxTasks').innerHTML = (BB.tasks || []).map(t => {
+ const btn = t.ready ? '
'
+ : t.used ? '
' + (t.period === 'week' ? '本周已用' : '今天已用') + ''
+ : '
';
+ const prog = t.need > 1 ? '
' + t.progress + '/' + t.need + '' : '';
+ return '
' + (BX_TASK_ICO[t.id] || '✨') + '' +
+ '
' + bbEsc(t.title) + '' + bbEsc(t.desc) + '' + (prog ? '
' + prog + '
' : '') + '
' + btn + '
';
+ }).join('');
+ }
+ /* 集齐奖励 */
+ $('#bxGoal').innerHTML = (BB.stages || []).map(g => {
+ const e = g.earned, pct = Math.round(g.got / g.total * 100);
+ const prize = (g.doudou ? g.doudou + ' 兜豆' : '') + (g.gift ? (g.doudou ? ' + ' : '') + '实物纪念礼' : '');
+ let tail;
+ if (e) tail = e.needAddr ? '
'
+ : '
' + (e.status === 'sent' ? '已发放' : '待发放') + '';
+ else if (g.complete) tail = '
补发集齐';
+ else tail = '
差 ' + g.left + ' 张';
+ return '
' + g.name + '' + prize + '' + tail + '
' +
+ '
';
+ }).join('');
/* 待补开 */
const pend = $('#bxPend');
pend.classList.toggle('hide', op.length < 2);
@@ -3361,7 +3417,8 @@
$('#bxAll').textContent = BB.totalWeeks;
requestAnimationFrame(() => { $('#bxBar').style.width = Math.round(BB.collected / BB.totalWeeks * 100) + '%'; });
const nBack = (BB.album || []).filter(a => a.src === 'backfill').length;
- $('#bxAnote').textContent = (BB.flash ? '其中闪卡 ' + BB.flash + ' 张。' : '') + (nBack ? '标「补」的是来之前的孕周,已自动补发普通款。' : '');
+ $('#bxAnote').textContent = (BB.flash ? '其中闪卡 ' + BB.flash + ' 张。' : '') + (nBack ? '标「补」的是来之前的孕周,已自动补发普通款。' : '') +
+ (lk.length ? '标 🔒 的是错过的周,完成小任务即可解锁。' : '');
const byW = {};
(BB.album || []).forEach(a => { byW[a.week] = a; });
$('#bxGroups').innerHTML = BX_GROUPS.map(g => {
@@ -3373,6 +3430,8 @@
cells += '
';
+ } else if (lk.indexOf(w) >= 0) {
+ cells += '
';
} else if (op.indexOf(w) >= 0) {
cells += '
';
} else {
@@ -3402,13 +3461,69 @@
const t = e.target.closest('.bx-t');
if (!t || bbBusy) return;
if (t.dataset.op) { bbSel = +t.dataset.op; renderBox(); $('#detailBox .detail-body').scrollTo({ top: 0, behavior: 'smooth' }); return; }
+ if (t.dataset.lk) { bxLockSel = +t.dataset.lk; renderBox(); $('#bxLock').scrollIntoView({ behavior: 'smooth', block: 'center' }); return; }
const w = +t.dataset.w;
if (!w) return;
- /* 卡册里点开一张:大小来自本地 SIZE 表,发育说明取孕期小知识的「宝宝这周」 */
- const c = { week: w, v: t.dataset.v, size: babySize(w), say: '' };
+ /* 卡册里点开一张:大小来自本地 SIZE 表,发育说明取孕期小知识的「宝宝这周」;周记 / 宝宝的话由接口 album 带回 */
+ const a = (BB.album || []).find(x => x.week === w) || {};
+ const c = { week: w, v: t.dataset.v, size: babySize(w), say: a.say || '', diary: a.diary || [] };
showReveal(c, null, false);
loadTips().then(() => { const x = TIPS && TIPS[w]; if (x && x.baby && $('#bxReveal').classList.contains('show')) $('#bxDev').textContent = x.baby; });
});
+ $('#bxLockChips').addEventListener('click', e => {
+ const b = e.target.closest('.bx-chip');
+ if (!b || bbBusy) return;
+ bxLockSel = +b.dataset.w; haptic(); renderBox();
+ });
+ $('#bxTasks').addEventListener('click', e => {
+ const go = e.target.closest('[data-app]');
+ if (go) {
+ const app = APP_BY_ID[go.dataset.app];
+ if (app && app.url) jumpApp(app.url, app.identifier); else toast('这个工具暂时打不开,换一个任务试试');
+ return;
+ }
+ const u = e.target.closest('[data-unlock]');
+ if (!u || bbBusy || !bxLockSel) return;
+ bbBusy = true; u.disabled = true; u.textContent = '解锁中…';
+ const w = bxLockSel;
+ bbApi('blindbox/unlock?week=' + w + '&task=' + u.dataset.unlock, 'POST').catch(() => null).then(j => {
+ bbBusy = false;
+ if (!j || j.code !== 200) { toast((j && j.message) || '网络开小差了,再试一次'); loadBlindbox(); return; }
+ if (navigator.vibrate) navigator.vibrate([10, 30, 14]);
+ toast('孕 ' + w + ' 周的盲盒解锁啦,快打开看看');
+ bbSel = w;
+ loadBlindbox().then(() => { bbSel = w; renderBox(); $('#detailBox .detail-body').scrollTo({ top: 0, behavior: 'smooth' }); });
+ });
+ });
+ $('#bxGoal').addEventListener('click', e => { if (e.target.closest('[data-addr]')) openModal('modalBxAddr'); });
+ $('#bxAddrSave').addEventListener('click', () => {
+ const v = id => $('#' + id).value.trim();
+ const body = { name: v('bxAddrName'), phone: v('bxAddrPhone'), addr: v('bxAddrAddr') };
+ if (!body.name || !body.phone || !body.addr) { toast('请把收货人、电话、地址填完整'); return; }
+ if (!/^1\d{10}$/.test(body.phone)) { toast('手机号好像不对,再检查一下'); return; }
+ fetch('/api/mp/public/mama-box/blindbox/claim?openid=' + encodeURIComponent(hashParam('openid')), {
+ method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body)
+ }).then(r => r.json()).catch(() => null).then(j => {
+ if (!j || j.code !== 200) { toast((j && j.message) || '提交失败,再试一次'); return; }
+ closeModal(); toast('收到啦,工作人员会尽快寄出'); loadBlindbox();
+ });
+ });
+ /* 集齐庆祝:开盒 / 刷新时接口带回 newRewards(服务端只返回一次),排队逐个弹 */
+ function showPrize() {
+ const g = bxPrizeQ.shift();
+ if (!g) return;
+ $('#bxPrizeT').textContent = g.key === 'all' ? '37 张宝宝卡全部集齐!' : '集齐' + g.name + '!';
+ $('#bxPrizeP').textContent = (g.doudou ? g.doudou + ' 兜豆' : '') + (g.gift ? (g.doudou ? '和' : '') + g.gift : '') + '已为你记下,工作人员会在 7 个工作日内发放' +
+ (g.gift ? ',先填一下收货信息吧。' : '。');
+ $('#bxPrizeOk').textContent = g.gift ? '去填收货信息' : '太好了';
+ $('#bxPrizeOk').dataset.addr = g.gift ? '1' : '';
+ openModal('modalBxPrize');
+ }
+ $('#bxPrizeOk').addEventListener('click', () => {
+ const addr = $('#bxPrizeOk').dataset.addr;
+ closeModal();
+ if (addr) openModal('modalBxAddr'); else setTimeout(showPrize, 250);
+ });
$('#bxRuleBtn').addEventListener('click', () => {
const d = $('#bxRules'); d.open = true;
d.scrollIntoView({ behavior: 'smooth', block: 'start' });
@@ -3437,6 +3552,7 @@
st.classList.add('is-popping');
if (navigator.vibrate) navigator.vibrate([12, 40, 18]);
const r = j.result;
+ (r.newRewards || []).forEach(g => bxPrizeQ.push(g));
bbNew = r.card.week;
setTimeout(() => { showReveal(r.card, r.reward, true); bbBusy = false; }, 420);
loadBlindbox(); // 后台刷新横幅与卡册(翻卡层盖着,用户看不到重绘)
@@ -3462,6 +3578,8 @@
if (!$('#bxBack').firstChild) $('#bxBack').innerHTML = giftSVG() + '
兜爸心选 · 孕期盲盒';
$('#bxTag').textContent = fresh ? (flash ? '✦ 哇!开出了闪卡 ✦' : '新卡 · 孕 ' + card.week + ' 周') : (flash ? '✦ 闪卡 · 孕 ' + card.week + ' 周' : '孕 ' + card.week + ' 周');
$('#bxDev').textContent = card.dev || '';
+ const dl = card.diary || [];
+ $('#bxDiary').innerHTML = dl.length ? '
📖 宝宝周记 · 孕 ' + card.week + ' 周
' + dl.map(x => '
' + bbEsc(x) + '
').join('') : '';
let rw = '';
if (reward) {
const tj = reward.type === 'taijiao';
@@ -3493,7 +3611,7 @@
rv.classList.remove('show', 'is-done', 'is-burst');
rv.setAttribute('aria-hidden', 'true');
}
- $('#bxKeep').addEventListener('click', () => { hideReveal(); renderBox(); });
+ $('#bxKeep').addEventListener('click', () => { hideReveal(); renderBox(); if (bxPrizeQ.length) setTimeout(showPrize, 350); });
$('#detailBox .dt-back').addEventListener('click', hideReveal);
/* ================= 孕期小知识(2026-09-30) =================
diff --git a/mama-box.css b/mama-box.css
index 1eeb06f..b661cdd 100644
--- a/mama-box.css
+++ b/mama-box.css
@@ -2695,3 +2695,86 @@ a.skip:focus{left:16px;top:16px}
.pt-card b{font-size:14px}
.pt-card p{font-size:13px;line-height:1.6;margin-top:6px}
.pt-foot{font-size:11.5px}
+
+/* ============ 孕期盲盒 · 价值感改造(2026-10-01):下周预告 / 待解锁任务 / 集齐奖励 / 宝宝周记 ============ */
+/* 下周预告:卡片剪影(同一张插画压成纯色)+ 倒计时 */
+.bx-next{display:flex;align-items:center;gap:12px;margin-top:14px;padding:12px 14px;border-radius:20px;background:#fff;box-shadow:var(--sh)}
+.bx-next.hide{display:none}
+.bx-next-img{flex:none;width:46px;height:58px;border-radius:10px;overflow:hidden;background:#F4E9E3;display:grid;place-items:center}
+.bx-next-img img{width:100%;height:100%;object-fit:cover;filter:brightness(0) opacity(.18)}
+.bx-next-img .cf-fb{font-size:24px;filter:grayscale(1) opacity(.35)}
+.bx-next-t{flex:1;min-width:0}
+.bx-next-t b{display:block;font-size:14px;font-weight:800}
+.bx-next-t span{display:block;margin-top:3px;font-size:12px;color:var(--muted)}
+.bx-next-cd{flex:none;text-align:center;padding:6px 10px;border-radius:14px;background:#FFF0EA}
+.bx-next-cd b{display:block;font-size:20px;line-height:1.1;font-weight:900;color:var(--brand);font-variant-numeric:tabular-nums}
+.bx-next-cd span{font-size:10.5px;font-weight:700;color:#C4553E}
+
+/* 待解锁 */
+.bx-lock{margin-top:14px;padding:14px;border-radius:20px;background:#fff;box-shadow:var(--sh)}
+.bx-lock.hide{display:none}
+.bx-lock-h{display:flex;gap:10px;align-items:flex-start}
+.bx-lock-ico{flex:none;width:34px;height:34px;border-radius:12px;display:grid;place-items:center;font-size:17px;background:#F3EEFF}
+.bx-lock-h b{font-size:14.5px;font-weight:800}
+.bx-lock-h b em{font-style:normal;color:#7B61D9}
+.bx-lock-h p{margin-top:2px;font-size:12px;color:var(--muted)}
+.bx-chip.lk{color:#6A55B8;background:#F3EEFF}
+.bx-chip.lk.on{color:#fff;background:linear-gradient(135deg,#9A85F0,#7B61D9);box-shadow:0 4px 10px rgba(123,97,217,.28)}
+.bx-tasks{margin-top:12px;display:flex;flex-direction:column;gap:8px}
+.bx-tk{display:flex;align-items:center;gap:10px;padding:10px 10px 10px 11px;border-radius:16px;background:#FAF6F3}
+.bx-tk.is-ready{background:#FFF3EC;box-shadow:inset 0 0 0 1.5px #FFC9B5}
+.bx-tk-i{flex:none;width:32px;height:32px;border-radius:11px;display:grid;place-items:center;font-size:16px;background:#fff}
+.bx-tk-m{flex:1;min-width:0}
+.bx-tk-m b{display:block;font-size:13.5px;font-weight:800}
+.bx-tk-m>span{display:block;margin-top:2px;font-size:11.5px;color:var(--muted)}
+.bx-tk-pr{display:flex;align-items:center;gap:6px;margin-top:5px}
+.bx-tk-p{flex:1;max-width:110px;height:5px;border-radius:3px;background:#EEE3DC;overflow:hidden}
+.bx-tk-p s{display:block;height:100%;border-radius:3px;background:linear-gradient(90deg,#FFB08F,#F4593C)}
+.bx-tk-pr em{font-style:normal;font-size:11px;font-weight:700;color:#C4553E}
+.bx-tk-b{flex:none;border-radius:999px;padding:7px 12px;font-size:12px;font-weight:800;color:#C4553E;background:#fff;box-shadow:inset 0 0 0 1.2px #FFC9B5}
+.bx-tk-b.go{color:#fff;background:linear-gradient(135deg,#FF7A5C,#F4593C);box-shadow:0 4px 10px rgba(244,89,60,.28)}
+.bx-tk-b.done{color:#B9A296;background:none;box-shadow:none}
+.bx-tk-b:disabled{opacity:.6}
+
+/* 卡册里的待解锁格子 */
+.bx-t.lockd{background:#F6F2FF;border:1.5px dashed #CFC2F5}
+.bx-t.lockd .li{font-size:17px;line-height:1}
+.bx-t.lockd .wk{color:#7B61D9;background:none}
+
+/* 集齐奖励 */
+.bx-goal{margin-top:12px;display:grid;grid-template-columns:1fr 1fr;gap:8px}
+.bx-goal:empty{display:none}
+.bx-gl{padding:10px 11px;border-radius:14px;background:#FAF6F3}
+.bx-gl.all{grid-column:1/-1;background:linear-gradient(135deg,#FFF6E2,#FFEBD9)}
+.bx-gl.got{background:#FFF3EC}
+.bx-gl-h{display:flex;align-items:baseline;flex-wrap:wrap;gap:4px 6px}
+.bx-gl-h b{font-size:13px;font-weight:800}
+.bx-gl-h em{font-style:normal;font-size:11.5px;font-weight:700;color:#C98A1E}
+.bx-gl-l,.bx-gl-s{margin-left:auto;font-size:11.5px;color:var(--muted);white-space:nowrap}
+.bx-gl-l b{color:var(--brand);font-size:13px}
+.bx-gl-s{font-weight:800;color:#E07B2E}
+.bx-gl-s.sent{color:#3EA27A}
+.bx-gl-s.off{font-weight:600;color:#B9A296}
+.bx-gl-b{margin-left:auto;border-radius:999px;padding:4px 10px;font-size:11.5px;font-weight:800;color:#fff;background:linear-gradient(135deg,#FF7A5C,#F4593C)}
+.bx-gl-bar{display:block;margin-top:7px;height:5px;border-radius:3px;background:rgba(0,0,0,.06);overflow:hidden}
+.bx-gl-bar s{display:block;height:100%;border-radius:3px;background:linear-gradient(90deg,#FFD36E,#F4593C);transition:width .6s var(--ease)}
+
+/* 翻卡层里的宝宝周记 */
+.bx-diary{width:100%;max-width:300px;margin-top:12px;padding:12px 14px;border-radius:18px;background:rgba(255,255,255,.14);text-align:left;
+ opacity:0;transform:translateY(16px);transition:all .45s}
+.bx-diary:empty{display:none}
+.bx-reveal.is-done .bx-diary{opacity:1;transform:none;transition-delay:.22s}
+.bx-dy-h{font-size:12px;font-weight:800;color:#FFE3A6;margin-bottom:4px}
+.bx-diary p{font-size:13.5px;line-height:1.7;color:#fff;font-family:var(--font-kid)}
+
+/* 集齐庆祝弹层 + 收货表单 */
+.bx-prize{text-align:center}
+.bx-prize-ico{font-size:46px;line-height:1;margin:6px 0 8px}
+.bx-prize h3{font-size:18px;font-weight:900}
+.bx-prize p{margin:8px 4px 4px;font-size:14px;line-height:1.7;color:var(--ink-2)}
+.bx-addr-tip{margin:-2px 0 12px;font-size:13px;line-height:1.6;color:var(--ink-2)}
+/* 集齐奖励:三段一排(每格窄,名称 / 奖励 / 状态竖排),全集独占一行横排 */
+.bx-goal{grid-template-columns:repeat(3,1fr);gap:7px}
+.bx-gl:not(.all) .bx-gl-h{flex-direction:column;align-items:flex-start;gap:2px}
+.bx-gl:not(.all) .bx-gl-l,.bx-gl:not(.all) .bx-gl-s,.bx-gl:not(.all) .bx-gl-b{margin-left:0}
+.bx-gl:not(.all){padding:9px 10px}