首页工具卡按孕周自动换:数胎动/胎儿估重/数宫缩没到孕周时换成能不能吃、补水补剂、血压等替补,到孕周自动换回 v26101014
Co-Authored-By: AI 助手
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<title>兜爸心选 · 孕育陪伴</title>
|
||||
<!-- V:26101013 缓存版本标记:改 css/js 时同步 bump 该值(与 js/app.js 的 VER 同源),静态资源按 mtime 走 ETag 自动刷新 -->
|
||||
<!-- V:26101014 缓存版本标记:改 css/js 时同步 bump 该值(与 js/app.js 的 VER 同源),静态资源按 mtime 走 ETag 自动刷新 -->
|
||||
<link rel="stylesheet" href="mama-box.css">
|
||||
<link rel="stylesheet" href="night.css">
|
||||
<!-- 夜晚模式:首屏绘制前就按上次的选择加 class,避免先白后黑闪一下(开关在首页右上角 #nightBtn,逻辑见 app.js) -->
|
||||
|
||||
73
js/app.js
73
js/app.js
@@ -3,7 +3,7 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
/* 页面版本号(YYMMDD+序号):显示在「关于兜爸心选」页底部;bump 时同步 head 注释与 ?v= */
|
||||
var VER = '26101013';
|
||||
var VER = '26101014';
|
||||
const $ = (s, c) => (c || document).querySelector(s);
|
||||
const $$ = (s, c) => Array.from((c || document).querySelectorAll(s));
|
||||
|
||||
@@ -384,13 +384,62 @@
|
||||
b.classList.toggle('is-locked', on);
|
||||
if (on) b.dataset.lock = g.wk + '周+'; else delete b.dataset.lock;
|
||||
});
|
||||
[['kick', 'taidong'], ['curve', 'gongsuopinlv'], ['fweight', 'taierguzhong']].forEach(([slot, id]) => {
|
||||
const el = $('.mini-card[data-mini="' + slot + '"]'), g = STAGE_GATE.find(x => x.id === id);
|
||||
swapHomeCards();
|
||||
}
|
||||
/* 首页工具卡按孕周自动换(2026-10-11 用户:「孕育工具卡片替换成其他几个能让用户用的,否则首页体验特别差,
|
||||
系统根据用户填写的孕周自动调用」)。
|
||||
· 数胎动 / 胎儿估重 / 数宫缩 三个坑位,孕周没到门槛就换成替补,到了自动换回原工具。
|
||||
· 替补按 SWAP_POOL 顺序依次填:能不能吃 → 补水补剂 → 血压 → 血糖 → 待产清单(孕早期最用得上的排前面),
|
||||
同一个替补不会出现两次;体重、孕检日历本来就在首页,不进池子。
|
||||
· 只换卡里的内容,坑位的尺寸和底色不动(五张卡的高度账、配色都是排好的,见 CSS .bento)。
|
||||
· 原内容存在 data 里,换回时原样放回,再用上一次卡片接口的数据补一遍(数胎动次数等)。 */
|
||||
const SWAP_SLOTS = [['kick', 'taidong'], ['fweight', 'taierguzhong'], ['curve', 'gongsuopinlv']];
|
||||
const SWAP_ART = { /* 白色线稿,和其余卡片插画同一套笔触 */
|
||||
yunqinengbuchi: '<path d="M4 12h16a8 8 0 01-16 0z"/><path d="M9 8.5c0-1.5 1-1.8 1-3.2M13 8.5c0-1.5 1-1.8 1-3.2"/>',
|
||||
bushui: '<path d="M7 4h10l-1.3 15a2 2 0 01-2 1.8h-3.4a2 2 0 01-2-1.8z"/><path d="M7.6 10h8.8"/>',
|
||||
yun: '<path d="M12 19.5s-7.5-4.6-7.5-10A4.2 4.2 0 0112 7a4.2 4.2 0 017.5 2.5c0 5.4-7.5 10-7.5 10z"/><path d="M6 12h3l1.5-2.5 2 4 1.5-1.5H18"/>',
|
||||
yunqixuetang: '<path d="M12 3.5s-5.5 6.2-5.5 10.2a5.5 5.5 0 0011 0C17.5 9.7 12 3.5 12 3.5z"/><path d="M9.8 14.2a2.3 2.3 0 002.2 2.1"/>',
|
||||
daichanqingdan: '<path d="M5.5 9h13l-1 11h-11z"/><path d="M9 9V7a3 3 0 016 0v2"/>',
|
||||
};
|
||||
const SWAP_POOL = [
|
||||
{ id: 'yunqinengbuchi', name: '能不能吃', sub: '馋了先查一下', btn: '去查查' },
|
||||
{ id: 'bushui', name: '补水补剂', sub: '叶酸吃了吗', btn: '去记录' },
|
||||
{ id: 'yun', name: '孕期血压', sub: '量一量更安心', btn: '去记录' },
|
||||
{ id: 'yunqixuetang', name: '孕期血糖', sub: '餐后记一笔', btn: '去记录' },
|
||||
{ id: 'daichanqingdan', name: '待产清单', sub: '提前备起来', btn: '去看看' },
|
||||
];
|
||||
let lastCards = null; /* 上一次 tool-cards 的结果:换回原卡后重放 */
|
||||
function swapArt(id) {
|
||||
return '<svg class="mc-art 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>';
|
||||
}
|
||||
function swapHomeCards() {
|
||||
const used = new Set();
|
||||
let restored = false;
|
||||
SWAP_SLOTS.forEach(([slot, id]) => {
|
||||
const el = $('.mini-card[data-mini="' + slot + '"]');
|
||||
if (!el) return;
|
||||
const on = stageLocked(g);
|
||||
el.classList.toggle('is-locked', on);
|
||||
if (on) el.dataset.lock = g.wk + '周+'; else delete el.dataset.lock;
|
||||
const g = STAGE_GATE.find(x => x.id === id);
|
||||
if (!stageLocked(g)) {
|
||||
if (el.dataset.swap) { el.innerHTML = el._orig; delete el.dataset.swap; el.classList.remove('is-swap'); el.removeAttribute('aria-label'); restored = true; }
|
||||
return;
|
||||
}
|
||||
const sub = SWAP_POOL.find(x => !used.has(x.id) && APP_BY_ID[x.id] && APP_BY_ID[x.id].url) ||
|
||||
SWAP_POOL.find(x => !used.has(x.id));
|
||||
if (!sub) return;
|
||||
used.add(sub.id);
|
||||
if (el.dataset.swap === sub.id) return;
|
||||
if (!el.dataset.swap) el._orig = el.innerHTML;
|
||||
el.dataset.swap = sub.id;
|
||||
el.classList.add('is-swap');
|
||||
el.classList.remove('is-warn');
|
||||
el.setAttribute('aria-label', sub.name + ',' + sub.sub);
|
||||
el.innerHTML = slot === 'kick'
|
||||
? '<div class="mc-head"><div class="mc-title">' + sub.name + '</div><div class="mc-sub">' + sub.sub + '</div>' +
|
||||
'<div class="mc-extra">孕 ' + g.wk + ' 周后这里换成' + g.name + '</div></div>' +
|
||||
'<span class="mc-btn">' + sub.btn + '</span>' + swapArt(sub.id)
|
||||
: '<div class="mc-title sm">' + sub.name + '</div><div class="mc-sub">' + sub.sub + '</div>' + swapArt(sub.id);
|
||||
});
|
||||
if (restored && lastCards) applyRemoteCards(lastCards);
|
||||
}
|
||||
|
||||
/* 跳转到其它 H5 应用。identifier 可选(来自 App 表),用于 last_app 上报的服务端在架校验;
|
||||
@@ -736,9 +785,10 @@
|
||||
const APP_BY_ID = {};
|
||||
$$('[data-mini]').forEach(b => b.addEventListener('click', () => {
|
||||
const map = { kick: '数胎动', weight: '孕期体重', cal: '孕检日历', curve: '数宫缩', fweight: '胎儿估重' };
|
||||
const app = APP_BY_ID[MINI_APP_MAP[b.dataset.mini]];
|
||||
const sw = b.dataset.swap; /* 孕周没到、坑位换成了替补(见 swapHomeCards) */
|
||||
const app = APP_BY_ID[sw || MINI_APP_MAP[b.dataset.mini]];
|
||||
if (app && app.url) { jumpApp(app.url, app.identifier); return; }
|
||||
toast('「' + map[b.dataset.mini] + '」即将上线');
|
||||
toast('「' + (sw ? (SWAP_POOL.find(x => x.id === sw) || {}).name : map[b.dataset.mini]) + '」即将上线');
|
||||
}));
|
||||
|
||||
/* 记一下弹层只保留「全部孕期工具」,不再提供输入框 */
|
||||
@@ -3420,8 +3470,13 @@
|
||||
const cardsOwned = { kick: false, cal: false }; // 卡片接口已接管哪些格(本地源据此让位)
|
||||
function applyRemoteCards(r) {
|
||||
if (!r || r.ok === false || !(r.cards || []).length) return; // 降级:保留现有值
|
||||
lastCards = r;
|
||||
const bySlot = {};
|
||||
r.cards.forEach(c => { if (c && c.slot) bySlot[c.slot] = c; });
|
||||
/* 换成替补的坑位(孕周没到)不吃原工具的数据,免得把「馋了先查一下」改成「今天 0 次」 */
|
||||
r.cards.forEach(c => {
|
||||
const el = c && c.slot ? $('.mini-card[data-mini="' + c.slot + '"]') : null;
|
||||
if (c && c.slot && !(el && el.dataset.swap)) bySlot[c.slot] = c;
|
||||
});
|
||||
const cardOf = slot => $('.mini-card[data-mini="' + slot + '"]');
|
||||
const mark = (slot, c) => { const el = cardOf(slot); if (el) el.classList.toggle('is-warn', !!c.warn); };
|
||||
const setText = (sel, v) => { const el = $(sel); if (el) el.textContent = v || ''; };
|
||||
|
||||
@@ -4776,4 +4776,6 @@ a.skip:focus{left:16px;top:16px}
|
||||
.sg-ends{display:flex;justify-content:space-between;margin-top:6px;font-size:11.5px;font-weight:700;color:var(--muted)}
|
||||
.sg-left{margin-top:10px;font-size:13px;font-weight:700;color:var(--ink-2)}
|
||||
.sg-modal .modal-foot{margin-top:18px}
|
||||
/* 首页工具卡自动换成替补(swapHomeCards):尺寸、底色沿用坑位原样,只换内容;插画是白色线稿 svg */
|
||||
.mini-card .sw-art{height:auto;aspect-ratio:1;opacity:.95}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user