首页宫格换正式应用图标;其他妈妈也在搜6问各配专题页(花费计算器/测一测/营养/补剂/职场维权)+热度设计 v26103111
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
90
js/app.js
90
js/app.js
@@ -3,7 +3,7 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
/* 页面版本号(YYMMDD+序号):显示在「关于兜爸心选」页底部;bump 时同步 head 注释与 ?v= */
|
||||
var VER = '26103110';
|
||||
var VER = '26103111';
|
||||
const $ = (s, c) => (c || document).querySelector(s);
|
||||
const $$ = (s, c) => Array.from((c || document).querySelectorAll(s));
|
||||
|
||||
@@ -421,6 +421,20 @@
|
||||
function swapArt(id) {
|
||||
return '<svg class="sw-art" viewBox="2 2 20 20" aria-hidden="true" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">' + (SWAP_ART[id] || '') + '</svg>';
|
||||
}
|
||||
/* 首页宫格图标 = 各应用在 App 表里的正式 logo(2026-10-31 用户定);替补坑位取替补应用的 logo,拿不到就保留现有图形 */
|
||||
function toolLogo(id) { const a = APP_BY_ID[id]; return a && (a.logo || a.icon) || ''; }
|
||||
function applyToolLogos() {
|
||||
try { MINI_APP_MAP; } catch (e) { return; } /* 早于 MINI_APP_MAP 定义被调用(替补首次计算)时先跳过,应用列表回来会再调 */
|
||||
$$('.tg[data-mini]').forEach(b => {
|
||||
const u = toolLogo(b.dataset.swap || MINI_APP_MAP[b.dataset.mini]);
|
||||
const ic = b.querySelector('.tg-ic');
|
||||
if (!u || !ic) return;
|
||||
let im = ic.querySelector('img');
|
||||
if (!im || ic.querySelector('svg')) { ic.innerHTML = '<img alt="" aria-hidden="true">'; im = ic.querySelector('img'); }
|
||||
ic.classList.add('lg');
|
||||
if (im.getAttribute('src') !== u) im.src = u;
|
||||
});
|
||||
}
|
||||
function swapHomeCards() {
|
||||
const used = new Set();
|
||||
let restored = false;
|
||||
@@ -446,6 +460,7 @@
|
||||
el.innerHTML = '<i class="tg-ic">' + swapArt(sub.id) + '</i><span class="tg-n">' + sub.name + '</span><span class="tg-s">' + sub.btn + '</span>';
|
||||
});
|
||||
if (restored && lastCards) applyRemoteCards(lastCards);
|
||||
applyToolLogos();
|
||||
}
|
||||
|
||||
/* 跳转到其它 H5 应用。identifier 可选(来自 App 表),用于 last_app 上报的服务端在架校验;
|
||||
@@ -501,6 +516,7 @@
|
||||
.filter(a => a.url && a.category === '孕期工具')
|
||||
.sort((x, y) => (y.seq || 0) - (x.seq || 0) || (y.no || 0) - (x.no || 0));
|
||||
apps.forEach(a => { APP_BY_ID[a.identifier] = a; }); /* 供首页工具卡按 identifier 取 URL */
|
||||
applyToolLogos();
|
||||
renderAppGrid(apps);
|
||||
})
|
||||
.catch(function () { /* 拉不到就保留弹层原有占位,不影响其余页面 */ });
|
||||
@@ -4556,7 +4572,7 @@
|
||||
if (whLoad) whLoad(w);
|
||||
return fetch('/api/mp/public/mama-box/pulse' + (w ? '?week=' + w : ''))
|
||||
.then(r => (r.ok ? r.json() : null))
|
||||
.then(j => { if (j && j.code === 200 && j.result) { last = j.result; paint(); } })
|
||||
.then(j => { if (j && j.code === 200 && j.result) { last = j.result; window.__mbPulse = last; paint(); if (window.__mbHeat) window.__mbHeat(); } })
|
||||
.catch(() => { /* 静默:保持现状(首次失败即一直隐藏) */ });
|
||||
}
|
||||
/* 档案回来孕周才可信 → 孕周变了重拉;否则只是足迹 / 盲盒状态变了,就地重画「和你比」「今日待办」 */
|
||||
@@ -5069,6 +5085,15 @@
|
||||
return qaLoading;
|
||||
}
|
||||
const qaHref = h => h + location.search + location.hash;
|
||||
const MS_FIRE = '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12.6 2.5c.4 3-1.6 4.6-3 6.2C8 10.4 7 12 7 14.3A5 5 0 0012 19.5a5 5 0 005-5.2c0-2-1-3.6-1.9-4.6-.2 1.3-.9 2.2-1.9 2.6.6-3.4-.2-7-.6-9.8z" fill="currentColor"/><path d="M12 19.5a2.6 2.6 0 01-2.6-2.6c0-1.6 1.3-2.5 2-3.6.3 1 .9 1.6 1.6 1.9.9.4 1.6 1.2 1.6 2.1A2.6 2.6 0 0112 19.5z" fill="#FFD36B"/></svg>';
|
||||
function msHeat() {
|
||||
const p = window.__mbPulse, tot = (p && p.total && +p.total.value) || 1510000;
|
||||
$$('#msList .ms-h').forEach(h => {
|
||||
const n = tot * (+h.dataset.heat || 0);
|
||||
h.querySelector('b').textContent = (n >= 1e4 ? (Math.round(n / 1e3) / 10) + '万' : Math.round(n)) + ' 人看过';
|
||||
});
|
||||
}
|
||||
window.__mbHeat = msHeat;
|
||||
function renderSearch(wk, today, size) {
|
||||
const W = state.week, L = $('#msList');
|
||||
if (!L) return;
|
||||
@@ -5080,7 +5105,7 @@
|
||||
const bank = QA || [];
|
||||
let items;
|
||||
if (bank.length) {
|
||||
items = bank.slice(0, 6).map((x, i) => ({ q: x.q, href: x.href ? qaHref(x.href) : '', qa: i }));
|
||||
items = bank.slice(0, 6).map((x, i) => ({ q: x.q, href: x.href ? qaHref(x.href) : '', qa: i, badge: x.badge, heat: x.heat }));
|
||||
} else {
|
||||
const q = t => /[??吗呢]$/.test(t) ? t : t + (/怎么办|什么|多少|怎么|几/.test(t) ? '?' : '');
|
||||
const d0 = wk.days[today];
|
||||
@@ -5098,55 +5123,23 @@
|
||||
if (it.href) el.href = it.href;
|
||||
else { el.type = 'button'; el.addEventListener('click', () => (it.qa != null ? openQA(it.qa) : openTips(it.pt))); }
|
||||
const no = document.createElement('i'); no.className = 'ms-no'; no.textContent = i + 1;
|
||||
const m = document.createElement('span'); m.className = 'ms-m';
|
||||
const t = document.createElement('span'); t.className = 'ms-q'; t.textContent = it.q;
|
||||
const go = document.createElement('i'); go.className = 'ms-go'; go.textContent = '›';
|
||||
el.appendChild(no); el.appendChild(t); el.appendChild(go);
|
||||
m.appendChild(t);
|
||||
/* 热度行:火苗 + 「N 万人看过」。人数 = 「此刻」同一个总人数(后台 pulseBase)× 每条固定比例,和首页其它人数同一口径 */
|
||||
if (it.heat) { const h = document.createElement('span'); h.className = 'ms-h'; h.dataset.heat = it.heat; h.innerHTML = MS_FIRE + '<b></b>'; m.appendChild(h); }
|
||||
el.appendChild(no); el.appendChild(m);
|
||||
if (it.badge) { const g = document.createElement('span'); g.className = 'ms-bd' + (it.badge === '爆' ? ' bao' : it.badge === '新' ? ' new' : ''); g.textContent = it.badge; el.appendChild(g); }
|
||||
const go = document.createElement('i'); go.className = 'ms-go'; go.textContent = '›'; el.appendChild(go);
|
||||
L.appendChild(el);
|
||||
});
|
||||
msHeat();
|
||||
const all = $('#msAll');
|
||||
if (all) {
|
||||
all.classList.toggle('hide', bank.length <= 6);
|
||||
all.textContent = '查看全部 ' + bank.length + ' 个问题 ›';
|
||||
}
|
||||
}
|
||||
/* 「测一测你是什么样的妈妈」:5 题,每个选项记一种类型,选得最多的就是结果。纯娱乐,不存数据 */
|
||||
const QUIZ = [
|
||||
['宝宝哭了,你的第一反应是?', ['马上抱起来哄', '先看看是饿了还是尿了', '等一等,看他能不能自己安静', '先拍下来发家庭群']],
|
||||
['准备待产包,你会怎么做?', ['早早列清单,反复核对', '对照医院和过来人的清单买', '想到什么买什么', '和姐妹们一起逛一起买']],
|
||||
['孕期刷手机,你最常看?', ['宝宝发育和护理知识', '好物测评和攻略', '搞笑视频,放松一下', '晒孕照、看别人的孕期日记']],
|
||||
['宝宝以后上什么兴趣班?', ['从小做好规划', '先了解每种的利弊再定', '他喜欢什么就学什么', '和朋友家孩子一起报']],
|
||||
['理想的周末是?', ['在家布置婴儿房', '去听一场孕妈课堂', '睡到自然醒', '约朋友吃饭拍照']],
|
||||
];
|
||||
const QUIZ_R = [
|
||||
['暖心守护型妈妈', '你的爱藏在每一个细节里,宝宝一有动静你就在身边。记得也照顾好自己,累了就让家人搭把手。'],
|
||||
['理性学习型妈妈', '你相信知识带来的安全感,凡事先了解清楚再行动。别被信息淹没,抓大放小,相信自己的判断。'],
|
||||
['松弛自在型妈妈', '你心态稳、不焦虑,这份松弛感会传递给宝宝。孕期的产检和关键时间点,记得设个提醒。'],
|
||||
['热情分享型妈妈', '你乐于分享,身边总有一群好姐妹。多和过来人交流,但遇到问题以医生的意见为准。'],
|
||||
];
|
||||
function buildQuiz(box) {
|
||||
box.textContent = '';
|
||||
const pick = [];
|
||||
const draw = () => {
|
||||
box.textContent = '';
|
||||
const i = pick.length;
|
||||
if (i >= QUIZ.length) {
|
||||
const cnt = [0, 0, 0, 0]; pick.forEach(k => cnt[k]++);
|
||||
const r = QUIZ_R[cnt.indexOf(Math.max.apply(null, cnt))];
|
||||
box.innerHTML = '<div class="qz-r"><span>你是</span><b></b><p></p><button type="button" class="qz-again">再测一次</button></div>';
|
||||
box.querySelector('b').textContent = r[0]; box.querySelector('p').textContent = r[1];
|
||||
box.querySelector('.qz-again').addEventListener('click', () => { pick.length = 0; draw(); });
|
||||
return;
|
||||
}
|
||||
const h = document.createElement('div'); h.className = 'qz-h'; h.textContent = (i + 1) + ' / ' + QUIZ.length + ' ' + QUIZ[i][0];
|
||||
box.appendChild(h);
|
||||
QUIZ[i][1].forEach((o, k) => {
|
||||
const b = document.createElement('button'); b.type = 'button'; b.className = 'qz-o'; b.textContent = o;
|
||||
b.addEventListener('click', () => { haptic(); pick.push(k); draw(); });
|
||||
box.appendChild(b);
|
||||
});
|
||||
};
|
||||
draw();
|
||||
}
|
||||
/* 全部问题页:focus = 从首页点的那条的下标(展开 + 滚到它);不传 = 从「查看全部」进来 */
|
||||
function openQA(focus) {
|
||||
const bank = QA || [];
|
||||
@@ -5177,14 +5170,13 @@
|
||||
const h = document.createElement('button'); h.type = 'button'; h.className = 'qa-q';
|
||||
const no = document.createElement('i'); no.className = 'qa-no'; no.textContent = i + 1;
|
||||
const t = document.createElement('span'); t.className = 'qa-tx'; t.textContent = x.q;
|
||||
const g = document.createElement('span'); g.className = 'qa-tag' + (x.hot ? ' hot' : ''); g.textContent = x.tag || '';
|
||||
const g = document.createElement('span'); g.className = 'qa-tag' + (x.badge ? ' hot' : ''); g.textContent = x.href ? '专题' : (x.tag || '');
|
||||
const ch = document.createElement('i'); ch.className = 'qa-ch'; ch.textContent = '›';
|
||||
h.appendChild(no); h.appendChild(t); if (g.textContent) h.appendChild(g); h.appendChild(ch);
|
||||
const a = document.createElement('div'); a.className = 'qa-a';
|
||||
if (x.quiz) { const p = document.createElement('p'); p.className = 'qz-lead'; p.textContent = x.a || ''; a.appendChild(p); const qz = document.createElement('div'); qz.className = 'qz'; a.appendChild(qz); buildQuiz(qz); }
|
||||
else a.textContent = x.a || '';
|
||||
if (x.href) { const go = document.createElement('a'); go.className = 'qa-go'; go.href = qaHref(x.href); go.textContent = '进专题页看完整内容 ›'; a.appendChild(go); }
|
||||
h.addEventListener('click', () => { it.classList.toggle('open'); haptic(); });
|
||||
a.textContent = x.a || '';
|
||||
/* 有专题页的条目(首页那 6 个)点了直接进专题页 */
|
||||
h.addEventListener('click', () => { if (x.href) { haptic(); location.href = qaHref(x.href); return; } it.classList.toggle('open'); haptic(); });
|
||||
it.appendChild(h); it.appendChild(a);
|
||||
L.appendChild(it);
|
||||
});
|
||||
@@ -5192,7 +5184,7 @@
|
||||
openPanel('detailQA');
|
||||
const body = $('#detailQA .detail-body');
|
||||
body.scrollTop = 0;
|
||||
if (focus != null && L.children[focus]) {
|
||||
if (focus != null && L.children[focus] && !bank[focus].href) {
|
||||
const c = L.children[focus];
|
||||
c.classList.add('open');
|
||||
setTimeout(() => {
|
||||
|
||||
Reference in New Issue
Block a user