2094 lines
166 KiB
HTML
2094 lines
166 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
|
||
<meta name="theme-color" content="#F4593C">
|
||
<meta name="mobile-web-app-capable" content="yes">
|
||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||
<title>兜爸心选 · 孕育陪伴</title>
|
||
<!-- V:26101010 缓存版本标记:改 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) -->
|
||
<script>try{if(localStorage.getItem('mmbox.night.v1')==='1'){document.documentElement.classList.add('night');document.querySelector('meta[name=theme-color]').content='#2A2340'}}catch(e){}</script>
|
||
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
|
||
<!-- 共享助手:授权/跳商城/位置上报(分享卡片同步,见 docs/h5-auth-standard.md 第四节) -->
|
||
<script src="/common/wx-auth.js?v=26101001"></script>
|
||
</head>
|
||
<body>
|
||
<a class="skip" href="#screens">跳到内容</a>
|
||
<div class="phone" id="phone">
|
||
<!-- 身份未就绪提示(2026-09-20 新增)
|
||
⚠️ 数据源是「宿主有没有把 openid 注入进来」,由 app.js 的 showIdNotice()/hideIdNotice() 控制。
|
||
背景:小程序首页壳在拿不到 openid 时会**匿名加载**本页(见 js/app.js 的访客态分支),
|
||
此时页面看着能用、其实全是占位(孕周 `--`、查不到任何档案)。以前是静默的,
|
||
用户/测试者看不出异常 —— 从商城返回首页加载本页时尤其容易被误判成「数据丢了」。
|
||
所以这里给一条**可见**的提示,并提供重试;排查时也能一眼看出是身份问题而不是数据问题。 -->
|
||
<div class="id-notice hide" id="idNotice" role="status">
|
||
<span class="idn-ico" aria-hidden="true">!</span>
|
||
<span class="idn-txt" id="idNoticeTxt">未获取到微信身份,页面数据可能不完整</span>
|
||
<button class="idn-retry" id="idNoticeRetry">重试</button>
|
||
</div>
|
||
<!-- 2026-10-02 底部导航「推荐版」:内容滑到导航下面时淡出,而不是被白条硬切 -->
|
||
<div class="tab-fade" aria-hidden="true"></div>
|
||
<nav class="tabbar" id="tabbar">
|
||
<button class="tab is-active" data-tab="home">
|
||
<span class="t-ico t-line"><svg class="t-svg" viewBox="0 0 24 24" aria-hidden="true"><path class="tf" d="M4 10.4 12 4l8 6.4V18a2.4 2.4 0 0 1-2.4 2.4H6.4A2.4 2.4 0 0 1 4 18z"/><text class="td t-dou" x="12" y="17.4" text-anchor="middle">兜</text></svg></span><span class="t-txt">首页</span>
|
||
</button>
|
||
<button class="tab" data-tab="archive">
|
||
<span class="t-ico t-line"><svg class="t-svg" viewBox="0 0 24 24" aria-hidden="true"><path class="tf" d="M8.3 20.4c-1.9 0-2.9-1.5-2.6-3.4l.5-3c.3-1.9 1.4-3 2.9-3 1.6 0 2.5 1.3 2.2 3.2l-.5 3.1c-.3 1.9-1.1 3.1-2.5 3.1z"/><path class="tf" d="M15.9 14.4c-1.4 0-2.2-1.2-2.5-3.1l-.5-3.1c-.3-1.9.6-3.2 2.2-3.2 1.5 0 2.6 1.1 2.9 3l.5 3c.3 1.9-.7 3.4-2.6 3.4z"/><circle class="td" cx="6.6" cy="8.4" r=".95"/><circle class="td" cx="8.6" cy="7.6" r=".85"/><circle class="td" cx="10.4" cy="8.3" r=".75"/><circle class="td" cx="13.6" cy="2.9" r=".8"/><circle class="td" cx="15.5" cy="2.3" r=".85"/><circle class="td" cx="17.5" cy="3" r=".95"/></svg></span><span class="t-txt">档案</span>
|
||
</button>
|
||
<button class="tab tab-fab" data-sheet="open">
|
||
<span class="fab"><img src="assets/img/69818ea975da.png" alt="" aria-hidden="true"><b class="fab-w" aria-hidden="true"><i>记</i><em>一下</em><s>!</s></b></span><span class="t-txt">记一下</span>
|
||
</button>
|
||
<button class="tab" id="tabLetter">
|
||
<!-- ⚠️ 2026-09-19(9.19 需求第 2 条):这枚 tab 从「兜爸心选」商城入口改回「宝宝来信」。
|
||
2026-09-20:内置来信屏(#screen-letter)及其全部功能代码已删除 ——
|
||
来信功能整体由第三方 H5 承接,这枚 tab 是进「宝宝来信」的入口,
|
||
落点 = **第三方「宝宝来信」H5**(mp.yizhezhe.com/laixin/)。
|
||
⚠️ 因此依旧**不挂 data-tab**:它不参与 go() 的 tab 高亮切换。
|
||
点了走 jumpApp()(同页 location.href + query 带 openid/unionid),
|
||
与其它 H5 应用(宫格、工具卡)完全一致 —— 见 app.js 的 #tabLetter 绑定。
|
||
⚠️ 红点 #tabBadge 也挂在这枚 tab 上,数据源是 laixin 的
|
||
/api/mp/public/laixin/unread,owner 只有 syncLaixinReminder() 一处
|
||
(第九批曾把红点挪到「首页」,现已挪回)。 -->
|
||
<span class="t-ico t-line"><svg class="t-svg" viewBox="0 0 24 24" aria-hidden="true"><rect class="tf" x="3.4" y="5.6" width="17.2" height="13" rx="2.6"/><path class="tl" d="M4 7.2l8 5.6 8-5.6"/><path class="td" d="M12 15.9s-2-1.2-2-2.5a1 1 0 0 1 2-.3 1 1 0 0 1 2 .3c0 1.3-2 2.5-2 2.5z"/></svg></span><span class="t-badge" id="tabBadge"></span><span class="t-txt">宝宝来信</span>
|
||
</button>
|
||
<button class="tab" data-tab="me">
|
||
<span class="t-ico t-line"><svg class="t-svg" viewBox="0 0 24 24" aria-hidden="true"><circle class="tf" cx="12" cy="8.6" r="3.9"/><path class="tf" d="M4.8 20.2c.6-3.7 3.5-5.9 7.2-5.9s6.6 2.2 7.2 5.9z"/></svg><img class="t-ava" id="tabAva" alt=""></span><span class="t-txt">我的</span>
|
||
</button></nav>
|
||
|
||
<main class="screens" id="screens">
|
||
|
||
<section class="screen is-active" id="screen-home" data-screen="home">
|
||
<div class="home-hero no-letter">
|
||
<!-- 2026-10-04 头图改版(用户:宝宝按孕周换形态、孕囊跟着宝宝大小变、去掉飘落的花瓣、加阳光和水波纹):
|
||
背景换成「去掉羊水囊的空背景」,羊水囊 + 宝宝整体都在 .hero-baby 里,按孕周 9 个阶段换图(js/hero-fx.js)。
|
||
每阶段一张会动的 GIF(本地程序化形变:呼吸、轻浮、小手、蹬脚;脸不动,所以永远闭眼闭嘴)+ 一张同帧静图打底,
|
||
静图先出、GIF 加载完再盖上。孕囊大小 = .hero-baby 的 --k,由 JS 按阶段写。
|
||
.hero-fx 是阳光光束 + 水波焦散的画布,叠在宝宝之上、文字之下。 -->
|
||
<!-- 2026-10-04 七版:#heroWater = 参考页(YANG-bak)的 WebGL 羊水 + 光束 + 呼吸暖光,在宝宝下面;孕囊图透明底叠在上面 -->
|
||
<canvas class="hero-water" id="heroWater" aria-hidden="true"></canvas>
|
||
<div class="hero-baby" id="heroBaby">
|
||
<img class="hero-kid hero-kid-still" id="heroStill" alt="" decoding="async">
|
||
<img class="hero-kid" id="heroKid" alt="" decoding="async">
|
||
</div>
|
||
<!-- 右上角原来有个消息圆钮,点开只弹「暂无新消息」——一个永远没有内容的入口,
|
||
还顶着一颗红点天天提示。整个删掉;这一排现在只剩左边的品牌字。
|
||
.hero-top 本身留着:它的 height:32 + margin-top:10 撑着下面整列的起点
|
||
(现在这一排里除了品牌字还并排放着 slogan,见下面那段注释)。 -->
|
||
<!-- slogan 从「品牌字底下另起两行」挪到了「品牌字右边、同一行」。
|
||
|
||
⚠️ 它现在是 .hero-top 的**孩子**,而 .hero-top 是四个页面共用的
|
||
display:flex + justify-content:space-between —— 第二个孩子会被
|
||
space-between 甩到最右边去。这里**不动父级的对齐方式**
|
||
(动了会连着挪「我的 / 档案」两页右上角的按钮组),
|
||
改用 .hero-slogan{margin-right:auto} 把富余空间吃掉,让它贴着品牌字排。
|
||
这跟 .hero-actions{margin-left:auto} 是同一个路子,全站一致。
|
||
|
||
⚠️ 一行 10 个字放得下,是**先把气泡挪下去**换来的,不是本来就放得下。
|
||
320 宽(本版支持的最窄屏,CSS 里 max-width:359px 那条断点为证)横向账:
|
||
左内边距 16 + 品牌字 4×21 + 4×.5 = 86 → 品牌字排到 x=102
|
||
slogan 起点 102 + margin-left 9 → x=111
|
||
slogan 宽 10×13 + 9×.3 = 132.7 → 排到 x≈243.7
|
||
橙区右内边距 15,可用到 x=305 → 还余 61px ✓
|
||
真正卡住的是纵向:slogan 的行盒是 y 18..34(13px 字塞在 16px 行高里,
|
||
居中于 y10..42 那一排),而气泡原来 top:26 —— 圆顶正好戳在字底下。
|
||
量过 hero-art.png 的 alpha 通道:这幅画是**实心整圆、边缘是硬的**,
|
||
α≥8 和 α≥220 量出来的左缘只差 1px,没有可以压上去的透明薄边。
|
||
所以只能把气泡整体下移到 top:40,给字底留 6px。
|
||
气泡一动,橙区那笔竖列账要连着重算 —— 已经算过,见 style.css 的 .home-hero。
|
||
改字号 / 加字 / 挪气泡之前,把上面两笔账都重算一遍。 -->
|
||
<div class="hero-top">
|
||
<!-- 2026-10-01 左上角文字换成正式 LOGO(用户提供的红字原稿)。头图是橙红底,红色原稿压上去会糊,
|
||
所以抠成白色透明 PNG(按红色浓度转 alpha,3x 高清),和旁边白字 slogan、宝宝插画同一套白色语言。 -->
|
||
<h1 class="hero-brand"><img class="hero-logo" src="assets/img/db2f99232b39.png" alt="兜爸心选" width="107" height="30"></h1>
|
||
<p class="hero-slogan">全家都爱用的孕育平台</p>
|
||
<!-- 2026-10-05 夜晚模式开关(用户:「做一个夜晚模式,右上角有个切换按钮」) -->
|
||
<div class="hero-actions">
|
||
<button class="icon-btn glass night-btn" id="nightBtn" aria-label="切换夜晚模式" aria-pressed="false">
|
||
<svg class="nb-moon" viewBox="0 0 24 24" width="18" height="18"><path d="M20.2 14.6A8.3 8.3 0 0 1 9.4 3.8a8.3 8.3 0 1 0 10.8 10.8Z"/></svg>
|
||
<svg class="nb-sun" viewBox="0 0 24 24" width="19" height="19"><circle cx="12" cy="12" r="4.3"/><g stroke="currentColor" stroke-width="1.9" stroke-linecap="round"><path d="M12 2.6v2.2M12 19.2v2.2M2.6 12h2.2M19.2 12h2.2M5.4 5.4l1.5 1.5M17.1 17.1l1.5 1.5M5.4 18.6l1.5-1.5M17.1 6.9l1.5-1.5"/></g></svg>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 2026-10-01 头部左侧改版(用户:「LOGO 下边、小孩左边那块太单一,好好设计一下」)。
|
||
原来是「孕周圆环 + 一张天数玻璃卡」,信息只有两条、形状又都是圆/方块。现在四层,从情绪到数据:
|
||
① .hi-due 见面倒计时(2026-10-04 用户要求去掉前面的白色小心)—— 最有期待感的一句放最上面
|
||
② .hi-week 超大孕周数字「31 周 +6天」—— 主角,替代圆环
|
||
③ .hi-bar 孕程进度条,进度头上骑着「本周水果」(宝宝大小),右边写「像菠萝」
|
||
④ .hd-card 原来的玻璃卡,「小名在妈妈肚子里 / 已经生活了 N 天」原样保留
|
||
竖向账(橙区 250 不变):hero-top 止于 42 → ①顶 54 高 22 → ②顶 82 高 50 → ③顶 140 高 16 → ④顶 166 高 52 → 底 218,
|
||
离「宝宝来信」卡顶 234 留 16px(和旧版一样)。宽度不超过 x≈197(旧玻璃卡的右缘),不伸进宝宝插画。
|
||
JS 只认 id:heroLeft / heroWeek / heroWeekU / heroPlus / heroBar / heroFruit / heroSize / heroWho / heroDays。 -->
|
||
<div class="hero-pane">
|
||
<span class="hi-due" id="heroDue"><span id="heroDueT">距离见面还有 <b id="heroLeft">--</b> 天</span></span>
|
||
<div class="hi-week"><b id="heroWeek">--</b><span class="hi-unit"><em id="heroWeekU">周</em><span id="heroPlus"></span></span></div>
|
||
<div class="hi-prog">
|
||
<div class="hi-bar"><i class="hi-fill" id="heroBar"><span class="hi-knob" id="heroFruit" aria-hidden="true"></span></i></div>
|
||
<span class="hi-size" id="heroSize"></span>
|
||
</div>
|
||
<div class="hd-card">
|
||
<span class="hd-who">
|
||
<b id="heroWho">宝宝</b><span class="hd-where">在妈妈肚子里</span>
|
||
</span>
|
||
<span class="hd-tail">已经生活了 <b id="heroDays">--</b> 天</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 宝宝来信提醒卡。**数据源是 laixin(第三方「宝宝来信」应用)**,
|
||
由 js 里的 syncLaixinReminder()(拉数)→ renderLetterReminder()(渲染)唯一负责显隐与文案
|
||
(拉 /api/mp/public/laixin/unread;**未建档一律不提示**,建档后 unread > 0 才显示,
|
||
卡与底 tab 红点由同一次判定同时落 —— 2026-09-22 产品口径)。
|
||
点击 = 跳 laixin,与底 tab「宝宝来信」同落点(app.js 里绑的是 openLetterApp)。
|
||
|
||
⚠️ 2026-09-20:这张卡**默认就是收起的**(标记里直接带 .hide,
|
||
#homeBody 直接带 .no-letter)。卡的显隐要等未读接口回来才知道,
|
||
而首屏渲染远早于它 —— 默认显示的话会「先冒出一张假卡、数据回来再缩回去」
|
||
(商城↔首页来回切时特别明显)。
|
||
⚠️ 别把这里的 .hide / .no-letter 去掉,去掉就退回闪烁版。
|
||
⚠️ 这张卡 2026-09-20 之前读的是 box_app 自己的 /mama-box/letters(多数用户 0 封),
|
||
而底 tab 早已跳 laixin —— 两套数据导致「红点说有新信、卡里什么都没有」。
|
||
改数据源就是修这个,**别再把它接回本地信件数据**(内置来信屏已整体删除,这张卡只认 laixin)。 -->
|
||
<button class="letter-card ripple hide" id="homeLetter">
|
||
<span class="lc-envwrap"><svg class="lc-env lc-env-v" viewBox="0 0 64 48" aria-hidden="true"><rect x="2" y="4" width="60" height="42" rx="7" fill="#fff"/><path d="M4 9l28 20L60 9" fill="none" stroke="#F7C6D1" stroke-width="2.4" stroke-linejoin="round"/><path d="M4 44l20-17M60 44L40 27" stroke="#FBE1E7" stroke-width="2"/><circle cx="32" cy="29" r="8.5" fill="#E2456A"/><path d="M32 33.2c-2.6-1.6-4-3-4-4.4a2 2 0 0 1 4-.7 2 2 0 0 1 4 .7c0 1.4-1.4 2.8-4 4.4z" fill="#fff"/></svg><b class="lc-num" id="lcNum" aria-hidden="true"></b></span>
|
||
<span class="lc-stamp" aria-hidden="true"><i>♥</i></span>
|
||
<div class="lc-body">
|
||
<!-- ⚠️ 这段只是**兜底**(正常情况下用户看不到:卡默认 .hide,
|
||
有未读时由 renderLetterReminder() 改写成「宝宝来信」+ 通用提醒文案)。
|
||
改这几行时连着那边一起看,否则会出现「HTML 里写着一套、屏幕上是另一套」。
|
||
⚠️ 上一批这里短暂叫过「宝宝的新消息」,本批随整条线退回「来信」。 -->
|
||
<div class="lc-title" id="lcTitle">宝宝来信</div>
|
||
<div class="lc-desc" id="lcDesc">妈妈,今天我在你肚子里翻了个身……</div>
|
||
<div class="lc-link"><span id="lcLink">读读宝宝的话</span> <i>›</i></div>
|
||
</div>
|
||
<span class="lc-arrow" aria-hidden="true"><svg viewBox="0 0 24 24" width="16" height="16"><path d="M9 5l7 7-7 7" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
|
||
</button>
|
||
|
||
<!-- 来信卡收起来时由 hideLetterCard() / renderLetterReminder() 给 #homeBody 挂 .no-letter,
|
||
把下面第一块(.tool-dock)的上间距补回来。
|
||
⚠️ 2026-09-20:它**默认就带 .no-letter**(与 #homeLetter 默认带 .hide 配套,
|
||
首屏按「没有来信卡」排版,避免数据回来时布局跳一下)。
|
||
|
||
── 这一版首页正文换了骨架 ──
|
||
上一版是同一套「竖色条标题 + 灰色说明 + 一块内容」原样重复四遍
|
||
(工具 / AI 小结 / 脚印 / 指南),四处的字号、间距、列宽全一样,
|
||
只有色条颜色不同,往下扫就是「条-块-条-块-条-块-条-块」。
|
||
现在那套框架整个拆了:.sec-title / .sec-sub 在首页一处不留,
|
||
抬头改为长在各模块**内部**,四个模块收成三块,
|
||
靠三种完全不同的容器语言自己分段 ——
|
||
.tool-dock 通栏出血的浅米托盘
|
||
.today-line 没有容器,只有一条从早贯到晚的竖线
|
||
.shelf 横向可滑的书架卡带
|
||
页面也因此有了两种宽度节奏:文字型内容仍在 26px 栏内,
|
||
托盘和卡带出血到屏幕边缘。 -->
|
||
<div class="home-body no-letter" id="homeBody">
|
||
<!-- 模块一 · 工具托盘。
|
||
抬头进了托盘里面:标题独占一行,右端「所有工具」做成白底细边胶囊;
|
||
说明单独做成一枚浅色 chip,不再是标题底下一行贴边的灰字。
|
||
通往「记一下」弹层的门这一屏仍是两处,是故意的,不是漏删:
|
||
这颗胶囊是**导航**位(扫抬头找"看全部"时手先落在这儿),
|
||
宫格右下角那张 .mini-card.more 是**内容**位(顺带把第三列剩下的
|
||
44px 填平,而且是个够手指点的大靶子)。两个都指向 data-sheet="open",
|
||
删掉任意一个另一个都还走得通。 -->
|
||
<section class="tool-dock">
|
||
<!-- 大字水印。aria-hidden:读屏念到这块该直接进标题,
|
||
不该先听见两声「兜爸」。样式和理由都在 css/style.css 的 .wm 上。
|
||
2026-10-01 用户要求:水印字从「妈妈」改成品牌名「兜爸」。 -->
|
||
<span class="wm" aria-hidden="true">兜爸</span>
|
||
<div class="dock-head">
|
||
<h2 class="dock-title" id="dockTitle">宝宝的孕育工具</h2>
|
||
<button class="dock-all" data-sheet="open">所有工具 ›</button>
|
||
</div>
|
||
<p class="dock-note"><svg viewBox="0 0 24 24" width="11" height="11" aria-hidden="true"><path d="M11 2.6l1.9 5.2 5.2 1.9-5.2 1.9L11 16.8l-1.9-5.2L3.9 9.7l5.2-1.9L11 2.6z" fill="currentColor"/><path d="M18.4 14.6l.8 2.1 2.2.8-2.2.8-.8 2.1-.8-2.1-2.2-.8 2.2-.8.8-2.1z" fill="currentColor" opacity=".6"/></svg>妈妈每记录一次,宝宝就多一段成长记忆</p>
|
||
<!-- 2026-09-30 五张卡改版:白色粗标题 + 各工具 LOGO 里的图形(取自点进去那个工具页左上角的 LOGO,
|
||
只留里面的图形),做成白色单色半透明「水印」斜压在卡片右下角,只作装饰;assets/img/*.svg 矢量。卡底色跟点进去的工具页同色系、稍深一档。
|
||
只换皮:排布、高度账、data-mini 跳转和各 id 的数据回填一律没动。样式见 mama-box.css「参考图改版」。 -->
|
||
<!-- 五张工具卡 + 一个出口。宫格本身这一版没动:
|
||
不等宽三列 + 竖向堆叠本来就是这一屏最不传统的部分,
|
||
而且两列高度是硬凑齐的(见 style.css 里 .mini-card.curve 上面那段),
|
||
动它得整列重算,收益也不在这儿。 -->
|
||
<div class="bento">
|
||
<div class="bento-col">
|
||
<button class="mini-card kick ripple" data-mini="kick">
|
||
<div class="mc-head">
|
||
<div class="mc-title">数胎动</div>
|
||
<!-- ⚠️ 默认值必须是中性占位,**不能写演示数字**:访客态(无 openid)与
|
||
records 接口失败/超时这两种情况下没人会改它,写死 3 就是假数据。
|
||
真实值由 __applyRecords() 写入(未记录的新用户是 0)。
|
||
(2026-09-22 新用户实测:工具卡上的演示占位值一律归中性。) -->
|
||
<div class="mc-sub">今天 <b id="kickTodayHome">--</b> 次</div>
|
||
<!-- 第二行(上游 sub,如「2 段 · 最近 13:00」)——只有 kick 与 weight 两张卡
|
||
有富余竖向空间;fweight/cal/curve 是固定高度且列很窄,放不下第二行。 -->
|
||
<div class="mc-extra" id="kickExtra"></div>
|
||
</div>
|
||
<span class="mc-btn">记录</span>
|
||
<img class="mc-art" src="assets/img/6add0c9e5856.svg" alt="" aria-hidden="true">
|
||
</button>
|
||
<!-- 第五个工具。原来是「胎心记录」,本批换成「胎儿估重」——
|
||
后者是真正部署好的站点(beian1.douba.top),点了能用;
|
||
而胎心记录在这张卡上一直只是个弹 toast 的占位入口。
|
||
⚠️ 胎心记录**没有被删掉**:它还在「记一下」弹层里(快捷区 q3 +
|
||
全部工具宫格),档案页那两条「来自「胎心记录」」的历史记录也照旧。
|
||
这里换掉的只是首页宫格的一个坑位。
|
||
⚠️ 类名、结构、三个尺寸全部照搬原来那张卡:外层仍是 .mini-card
|
||
(.heart 只是改名成 .fweight,两条 CSS 跟着改),内部仍是
|
||
「名字 + 状态两行叠着 + 右下角插画」。所以左列 158 + 10 + 64 = 232
|
||
这笔账一个数都没动,右列(88 + 10 + 80 + 10 + 44)不用跟着补。
|
||
图标换成了内联 SVG 的表盘,理由见 patch 脚本里那段注释。 -->
|
||
<button class="mini-card fweight ripple" data-mini="fweight">
|
||
<div class="mc-title sm">胎儿估重</div>
|
||
<div class="mc-sub">去测算</div>
|
||
<img class="mc-art" src="assets/img/3c4cf0da356c.svg" alt="" aria-hidden="true">
|
||
</button>
|
||
</div>
|
||
<button class="mini-card weight ripple" data-mini="weight">
|
||
<img class="mc-art big" src="assets/img/fc0ab3d2e21a.svg" alt="" aria-hidden="true">
|
||
<div class="mc-title">孕期体重</div>
|
||
<!-- ⚠️ 这里原来是写死的演示值「58.2 kg」,任何用户都会看到(2026-09-22 演示数据泄漏)。
|
||
现在由 `applyRemoteCards()` 按 box_app 封装的卡片接口写入:
|
||
有值时写 `value` + 小字 `<small>unit</small>`,没有值时保持中性占位 `--`
|
||
(**不写 0**,0 是个看着像真的假值)。接口拿不到就保留这里的默认值。 -->
|
||
<div class="mc-big" id="weightVal">--</div>
|
||
<div class="mc-extra" id="weightExtra"></div>
|
||
</button>
|
||
<div class="bento-col">
|
||
<button class="mini-card cal ripple" data-mini="cal">
|
||
<div class="mc-title sm">孕检日历</div>
|
||
<div class="mc-sub" id="calNext">—</div>
|
||
<img class="mc-art" src="assets/img/a693b92f3239.svg" alt="" aria-hidden="true">
|
||
</button>
|
||
<!-- 生长曲线原来是 flex:1,把这一列剩下的高度全吃了(约 134px),
|
||
而它的内容和上面的孕检日历一模一样多。压到 80px,
|
||
省下的 54px 给下面那张「更多工具」。
|
||
⚠️ 本批(第九批)把这张卡从「生长曲线」换成「数宫缩」:
|
||
文案改这一行;落点改 app.js 的 MINI_APP_MAP.curve
|
||
(taiershengzhang → gongsuopinlv,指向已上架的「宫缩频率计算」)。
|
||
⚠️「生长曲线」工具本身**没被删**:App 表里 taiershengzhang /
|
||
taierquxian 都还在,仍会出现在「记一下」的全部工具列表里;
|
||
这里换掉的只是首页这一个坑位。
|
||
图标(2026-09-30)已换成秒表萌物,见下面五张卡的改版注释。
|
||
⚠️ 副标题仍是 data-wk="cn" 自动显示孕周,本批未要求改文案。 -->
|
||
<button class="mini-card curve ripple" data-mini="curve">
|
||
<div class="mc-title sm">数宫缩</div>
|
||
<div class="mc-sub" data-wk="cn">—</div>
|
||
<img class="mc-art" src="assets/img/ad7487f2e445.svg" alt="" aria-hidden="true">
|
||
</button>
|
||
<!-- 通往「记一下」弹层里那十几个工具。底部那颗 FAB 开的也是它。
|
||
故意不做成糖果色卡:它不是第六个工具,是个出口,
|
||
灰米底 + 一行小字,和上面五张分得开。 -->
|
||
<button class="mini-card more ripple" data-sheet="open">
|
||
<span class="mc-more-t">更多工具</span><i class="chev">›</i>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<!-- 此刻(2026-10-01 需求文档 v1.0 第二节;同日两次改版)。数据 GET /api/mp/public/mama-box/pulse,渲染在 app.js pulseCard()。
|
||
⚠️ 模拟数据是产品负责人 2026-10-01 拍板的例外(AGENTS.md §4.12),只限这一条。
|
||
用户 2026-10-01:「把此刻跟上面的孕育工具结合到一起……此刻相当于上面那个卡片的一个轻量化的展示」
|
||
→ 不再单独成卡,收进工具卡底部一条浅色带:一行人数 + 她们在做 / 和你比 + 今天别忘了 + 一行滚动动态。
|
||
「她们在聊」按用户要求删除;全站版(访客)的「今日三项」小卡也去掉(和上面工具宫格重复)。
|
||
show=false 或接口失败 → 整条保持 .hide,工具卡和以前一样。
|
||
同日三改(用户:「此刻有一点点不够清爽,文字太多了,密密麻麻的」):从 5 行减到 3 行 ——
|
||
① 标题行不变;② 「她们在做」两条进度条合成**一句**,只挑你今天还没做的那项(都做了就一句夸奖),去掉进度条;
|
||
③ 「今天别忘了」整行删(产检、盲盒在上面工具宫格和盲盒横幅里都有);④ 滚动动态去掉白底卡片,压成一行小字。 -->
|
||
<!-- 2026-10-02 陪伴版(用户:「改成陪伴的语气……头像展示 6 到 8 个……升级成同周妈妈的悄悄话……
|
||
不做复杂社区,只做一点陪伴」):
|
||
① 头像从标题行挪到第二行,一排 7 个,后面跟「今天 N 位同周妈妈陪宝宝数了胎动」——说人数不说百分比,不和你比;
|
||
② 「你今天还没数 ›」改成邀请:「小米粒在等你,陪它数一数 ›」,做过了就是「你今天也陪它数过啦 ✓」;
|
||
③ 同周悄悄话 #whWall:横滑的小纸条,只能「抱抱」不能评论,没有昵称头像。数据 GET /whisper(app.js whisperWall())。
|
||
拉到悄悄话时滚动动态 #plFeed 让位(一块地方只讲一件事),拉不到就还是滚动动态。 -->
|
||
<div class="pulse hide" id="pulse" role="region" aria-label="此刻,同孕周妈妈们">
|
||
<div class="pl-head">
|
||
<span class="pl-live"><i></i>此刻</span>
|
||
<span class="pl-title" id="plTitle"></span>
|
||
</div>
|
||
<div class="pp-crowd">
|
||
<span class="pp-avs" id="ppAvs" aria-hidden="true"></span>
|
||
<span class="pp-col">
|
||
<span class="pp-crowd-t" id="ppCrowd"></span>
|
||
<span class="pp-doing hide" id="ppDoing"></span>
|
||
</span>
|
||
</div>
|
||
<!-- 2026-10-02 用户:「此刻给我放 3 个使用应用记录」→ 动态从「一行滚动、有悄悄话就让位」改成常驻三行,
|
||
排在悄悄话入口上面;每 3 秒最上面一条淡出、底下补一条;点一行直接进对应工具(act → TODAY_GO)。 -->
|
||
<div class="pl-feed pl-feed3 hide" id="plFeed"><div class="pl-track" id="plTrack"></div></div>
|
||
<!-- 2026-10-02 二改(用户:「此刻有一点点乱……悄悄话点进去,前端一个很简洁、轻量化的入口,
|
||
点进去是整个悄悄话的大页面,设计炫酷一点、有创意、视觉有冲击力」):
|
||
首页只留一条入口(一句轮播的悄悄话 + 条数),横滑纸条带挪进全屏页 #whPage。 -->
|
||
<button class="wh-entry hide" id="whWall" type="button" aria-label="打开同孕周悄悄话">
|
||
<!-- 2026-10-02 用户:「入口那一小条里要有星空,星星一闪一闪,再划过几个流星,不要太多」 -->
|
||
<span class="we-sky" aria-hidden="true"><i class="tw" style="left:50%;top:12%;width:6px;height:6px;animation-delay:-1.2s;animation-duration:2.4s"></i><i style="left:60%;top:30%;width:4px;height:4px;animation-delay:-0.3s;animation-duration:2.0s"></i><i class="tw" style="left:73%;top:15%;width:5px;height:5px;animation-delay:-2.4s;animation-duration:2.8s"></i><i class="tw" style="left:93%;top:13%;width:4px;height:4px;animation-delay:-3.1s;animation-duration:2.2s"></i><i class="tw" style="left:21%;top:90%;width:4px;height:4px;animation-delay:-3.7s;animation-duration:2.6s"></i><i class="tw" style="left:45%;top:88%;width:5px;height:5px;animation-delay:-1.6s;animation-duration:3.2s"></i><i style="left:73%;top:80%;width:4px;height:4px;animation-delay:-2.2s;animation-duration:2.6s"></i><i class="tw" style="left:89%;top:88%;width:5px;height:5px;animation-delay:-0.8s;animation-duration:3.0s"></i><b class="we-mt"></b><b class="we-mt m2"></b></span>
|
||
<span class="we-ico" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M5 18.5V7.8A2.8 2.8 0 017.8 5h8.4A2.8 2.8 0 0119 7.8v5.4a2.8 2.8 0 01-2.8 2.8H9.2z" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linejoin="round"/><path d="M9 10.5h6" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"/></svg></span>
|
||
<span class="we-txt"><b id="weName">孕妈悄悄话</b><span class="we-topic"><em>本周话题</em><strong id="weTopic"></strong></span><span class="we-roll" id="weRoll"></span></span>
|
||
<span class="we-go" id="weGo"></span>
|
||
</button>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 孕期小知识(2026-09-30)。用户原话:「按她填写的孕周,比如孕 20 周 5 天,给她列出几个小模块,
|
||
设计一定要漂亮、匹配母婴用户,最好是动态的;小知识匹配每周的每一天」。
|
||
内容:assets/data/preg-tips.json(孕 4–40 周,每周 宝宝/妈妈/饮食/注意 四句 + 每天一条小知识,共 7 条),
|
||
首次需要时才 fetch,不进首屏。渲染在 app.js renderTips()。
|
||
⚠️ 默认 .hide:只有拿到**真实孕周**(state.pregEmpty === false 且非产后)才显示,
|
||
内置默认孕周(DEFAULT_DUE 推出来的 27 周上下)是假的,不能拿它配知识。
|
||
⚠️ 一周 7 个圆点 = 这一周的第 1–7 天。今天及以前可以点开回看;以后的几天锁着,
|
||
写「明天见」—— 让每天回来看一条,而不是一口气翻完。 -->
|
||
<section class="preg-tips hide" id="pregTips">
|
||
<!-- 2026-10-01 用户要求:标题前写明孕周 ——「孕 26 周 · 今日孕期小知识」,按她填的孕周自动取,每天换一条;整块压矮一些。
|
||
#ptWk 由 renderTips() 写;#ptWhen 改成「第 N 天」。下面四张小卡由 2×2 改成一行横滑,高度省一半。 -->
|
||
<div class="pt-head">
|
||
<h2 class="pt-title"><span class="pt-wk" id="ptWk">孕 — 周</span>今日孕期小知识</h2>
|
||
<span class="pt-when" id="ptWhen"></span>
|
||
</div>
|
||
<div class="pt-today" id="ptToday">
|
||
<span class="pt-float" id="ptFloat" aria-hidden="true"></span>
|
||
<span class="pt-badge" id="ptBadge">今日小知识</span>
|
||
<div class="pt-body" id="ptBody">
|
||
<div class="pt-t" id="ptT"></div>
|
||
<div class="pt-d" id="ptD"></div>
|
||
</div>
|
||
<div class="pt-days" id="ptDays" role="tablist" aria-label="本周每天的小知识"></div>
|
||
</div>
|
||
<!-- 2026-10-01 用户要求:四张卡不在首页放文字,只留图标 + 标题四个入口,点进详情页 #detailTips 看全文 -->
|
||
<div class="pt-chips" id="ptChips">
|
||
<button type="button" class="pt-chip pc-baby" data-pt="baby"><i id="ptChipBaby" aria-hidden="true">👶</i><span>宝宝这周</span></button>
|
||
<button type="button" class="pt-chip pc-mom" data-pt="mom"><i aria-hidden="true">🤰</i><span>妈妈身体</span></button>
|
||
<button type="button" class="pt-chip pc-eat" data-pt="eat"><i aria-hidden="true">🥗</i><span>吃点什么</span></button>
|
||
<button type="button" class="pt-chip pc-care" data-pt="care"><i aria-hidden="true">📋</i><span>这周留心</span></button>
|
||
</div>
|
||
<p class="pt-foot">仅供参考,身体有任何不适请以医生意见为准</p>
|
||
</section>
|
||
|
||
<!-- 3D 婴儿房 · 「透过页面看到后面的房间」(2026-10-01 三版)。用户原话:
|
||
「把那个房间整体……铺到它的后边……两个模块中间,它不用点击,从外边其实就能看到这个里边是什么,
|
||
整个铺到这个背景的后边,有一个引导进入的按钮,我点进去再弹出这个新的页面」。
|
||
做法:这一块没有底色,是页面上开的一道「空隙」;房间图层(#nypLayer)由 JS 每次滚动都对齐到 .screen 的可视区,
|
||
所以页面往上滚时房间不跟着走,看起来就是铺在整页背后、从缝里露出来(视差)。上下两条内阴影 = 上下模块压在房间上面。
|
||
整块都能点(2026-10-02 用户要求:点到房子 / 模块任意位置都直接进 3D 婴儿房,不必非点「进去布置」);滑动页面不会触发 click,不怕误触。
|
||
图:assets/img/nursery-day.jpg / nursery-night.jpg,由「3D 婴儿房」会话(33d6c837)导出的无 UI 渲染
|
||
(原图 yef/cover-day.png、cover-night.png,1125×1500,**原尺寸**存 JPG —— 375 宽 × 3 倍屏正好 1125 像素,别再缩,缩到 750 在 iPhone 上会糊(2026-10-01 用户反馈过));里面摆的是演示布置,不是用户自己的房间。
|
||
底色必须和图边一致:白天 #DCE5EC、夜间 #2C3350(2026-10-01 写实版,取图顶两角;旧卡通版是 #FFECD8 / #5A5890),否则缝里会露出图片边框。
|
||
2026-10-01 晚:3D 婴儿房会话把封面换成「整栋小别墅外景」(婴儿房是二楼剖开那一间),房子占画面中部偏下、上方约 20% 纯底色。
|
||
缝高 300→340、图宽 100%→88%(max 420)、上提 40px:缝滚到屏幕中间时屋顶到草坪整栋都露出来,草坪压在玻璃条下面;标题改「我们的家」。
|
||
位置:2026-10-01 用户要求和消消乐对调 —— 后又和孕期小知识对调 —— 现在在孕期小知识下面、今天的动线上面(原来在今天的动线和书架之间)。北京时间 19:00–6:00 换夜间图(开灯版)。JS 在 app.js nurseryRender()。 -->
|
||
<section class="ny-peek" id="nursery">
|
||
<div class="nyp-layer" id="nypLayer" aria-hidden="true"><img id="nypImg" src="assets/img/nursery-day-sky.jpg?v=20261006a" alt="" decoding="async"></div>
|
||
<span class="nyp-chip" id="nyChip">进去看看 · 宝宝的婴儿房</span>
|
||
<div class="nyp-bar">
|
||
<div class="nyp-txt"><b id="nyTitle">我们的家</b><span id="nySub">做孕期任务攒兜豆,一件件布置好</span></div>
|
||
<button class="nyp-btn" id="nyBtn" type="button">进去布置 <svg viewBox="0 0 24 24" width="11" height="11" aria-hidden="true"><path d="M8 5l8 7-8 7z" fill="currentColor"/></svg></button>
|
||
</div>
|
||
</section>
|
||
<!-- 首页 · 兜豆兑换商城模块(2026-10-01):紧跟婴儿房(那张卡写着「攒兜豆把它布置好」),
|
||
顺着「兜豆」这条线往下接。头部一条 + 下面一排可兑好物;点哪儿都 openExchange()。 -->
|
||
<!-- 外层 .exch-wrap 套上和其它模块同款的白色外壳(2026-10-01 用户:「应该有个底色,跟其他模块一样」),里面粉色卡不变 -->
|
||
<section class="exch-wrap" id="homeExchMod"><div class="exch-mod">
|
||
<button class="exch-strip ripple" id="homeExch">
|
||
<span class="es-coin" aria-hidden="true"><img src="assets/img/dou-coin.svg?v=20261002" width="36" height="36" alt=""></span>
|
||
<span class="es-main"><b>兜豆兑换</b><span id="homeExchSub">做孕期任务就能攒兜豆</span></span>
|
||
<span class="es-go">去兑换<i>›</i></span>
|
||
</button>
|
||
<!-- 本场可兑好物(/mall/drop:有库存且已开售,按 heat_30m 降序取前 6),横向滑动;拉不到数据整行隐藏 -->
|
||
<div class="ex-goods hide" id="homeExchGoods"></div>
|
||
</div></section>
|
||
|
||
<!-- 模块二 · 今天的动线。
|
||
上一版这里是两个各自独立的模块:「AI今日小结」一张渐变卡,
|
||
下面「今日成长脚印」一张白卡装的时间轴。可 AI 那句话总结的
|
||
就是脚印里这四条记录,中间隔着一整套抬头分开摆,两边都在自说自话。
|
||
现在合成一条线:起点是「今天」,中间四条记录,
|
||
末尾挂 AI 那句话当这一天的落款。
|
||
时间轴外面那张白卡也撤了 —— 结构改由 .today-line::before 那条
|
||
贯穿到底的竖线撑起来,不再靠一个方框圈出来,
|
||
这样它和上面的托盘、下面的卡带才真的是三种容器语言。
|
||
|
||
⚠️ .steps 仍是整卡可点的 role="button",里面**不能**再出现 <button>。
|
||
所以「查看全部 ›」挂在 .tl-head 上、AI 气泡是 .steps 的兄弟节点,
|
||
两者都在 .steps 外面。 -->
|
||
<!-- 今日脚印 2026-10-01 改版(用户:「对标其他模块,UI 要漂亮一些,内容文字也要有创意」):
|
||
· 头部左边一张撕页日历(日 / 月·周几),右边标题 + 一句小诗;
|
||
· 每条记录前的圆点换成**一左一右交替的小脚丫**,沿虚线往下走 —— 「脚印」两个字画出来;
|
||
· 每条记录是一张小卡:大字内容(数字加粗上色)+ 时间 + 来源小标签;
|
||
· 没记录时(guide)是一行脚丫插画 + 接口给的引导语(童趣字体)+ 带 logo 的应用芯片;
|
||
· AI 小结做成「宝宝写给妈妈的一张便签」:信纸横线 + 宝宝口吻 + 落款小名。
|
||
⚠️ 「AI」角标必须保留(唯一的机器生成提示,见 syncBabyWords 那段注释)。
|
||
JS 依赖的 id / class(.today-line / #tlSteps / .step 系列 / #tlGuide* / .ai-bubble / .ab-say / #abTag / #tlTitle)都沿用。 -->
|
||
<section class="today-line fp2">
|
||
<!-- 2026-10-05 祈福树入口(用户:「放到今日脚印的右上角,把右上角掀开一点,露出祈福树」):
|
||
卡片右上角像纸一样折起一角(.pl-flap 是翻过来的纸背),底下那块(.pl-hole)露出祈福树;点它跳祈福树(js/app.js #fpQifu)。
|
||
之前放在工具卡右上角 / 头图底边的版本已撤,工具卡恢复「所有工具 ›」。样式见 mama-box.css「祈福树入口 · 今日脚印掀角」。 -->
|
||
<a class="fp-peel" id="fpQifu" href="/qifu-shu/" aria-label="宝宝祈福树"><span class="pl-hole"><img src="assets/img/qifu-tree.png" alt="" width="31" height="30"></span><span class="pl-flapw"><span class="pl-flap"></span></span><span class="pl-t">祈福</span></a>
|
||
<div class="fp-head">
|
||
<div class="fp-cal" aria-hidden="true"><i class="fc-ring"></i><b id="fpCalD">--</b><span id="fpCalM">--</span></div>
|
||
<div class="fp-ht">
|
||
<h2 class="tl-h-title" id="tlTitle">宝宝的今日脚印</h2>
|
||
<p class="fp-poem fp-date" id="fpDate"></p>
|
||
</div>
|
||
<!-- 2026-10-05 用户:「祈福树左侧那个『全部』取消掉」→ 删了「全部 ›」。进档案仍可点脚印列表(#tlSteps data-goto=archive)或底部「档案」tab。 -->
|
||
</div>
|
||
<div class="steps fp-steps ripple" id="tlSteps" data-goto="archive" role="button" tabindex="0" aria-label="宝宝的今日脚印,查看完整档案">
|
||
<div class="step"><span class="st-time">今天</span><span class="st-dot"></span><span class="st-txt">正在获取今天的脚印…</span><span class="st-from"></span></div>
|
||
</div>
|
||
<!-- 2026-10-02 用户要求:今天还没用任何工具时,不再放示例/引导语,改成「今日待办」清单,提醒她今天该做什么。
|
||
条目 = 接口 unused(今天还没用的、已上架的应用),文案由 app.js FP_TODO 按应用名配成一句动作。 -->
|
||
<div class="tl-guide fp-guide fp-todo" id="tlGuide" style="display:none">
|
||
<div class="td-head"><b>今日待办</b><span class="td-cnt" id="tdCnt"></span></div>
|
||
<p class="tl-guide-t td-lead" id="tlGuideTitle"></p>
|
||
<div class="tl-guide-apps td-list" id="tlGuideApps"></div>
|
||
<p class="tl-guide-s td-foot" id="tlGuideSub"></p>
|
||
</div>
|
||
<button class="ai-bubble fp-note ripple" data-open="detailAI">
|
||
<span class="fn-top"><b class="ab-tag" id="abTag">宝宝今天想说</b></span>
|
||
<span class="ab-say"></span>
|
||
<span class="fn-foot"><span class="fn-sign" id="fpSign">—— 宝宝</span><em>往期小结 ›</em></span>
|
||
</button>
|
||
</section>
|
||
|
||
<!-- 树洞(2026-09-30)。用户原话:「宝妈们有任何情绪上的问题,都可以在这个树洞里扔进去」。
|
||
用户选定:**只存在她自己手机上**(localStorage 'mmbox.treehole.v1',不上传、后台也看不到),
|
||
扔进去后**只有「已收好」的动画,不做回应**。
|
||
⚠️ 唯一的例外是安全提示:内容里出现明显的轻生字眼时,收好之后在卡内显示一行援助热线
|
||
(12356 全国心理援助热线),这不是「回应心事」,是兜底,别删。
|
||
⚠️ 纸团飞进树洞的动画靠 Element.animate;不支持的老内核直接跳到「已收好」,不影响收存。 -->
|
||
<!-- 「妈妈的树洞」整块已删(2026-10-01 用户要求)。样式与 JS 一并删除,需要恢复看 git 历史 70c9786。 -->
|
||
|
||
<!-- 宝宝消消乐 · 推广入口(2026-09-30)。用户原话:「做了一个消消乐小游戏(待产清单主题),
|
||
放到首页展示并推广,宝妈们业余时间玩,名字叫宝宝消消乐」。
|
||
2026-10-09 用户改名「宝贝消消乐」(游戏页同步改了)。
|
||
2026-10-01 用户要求和 3D 婴儿房对调位置:现在在「今天的动线」和书架之间(原来在工具托盘正下方)。右侧 3×3 小棋盘是纯装饰动画
|
||
(每隔几秒一行三个同样的待产用品闪一下「消掉」再换新),JS 在 app.js gamePromo()。
|
||
游戏地址在 app.js 的 GAME_URL;为空时整块隐藏(.hide 默认)。点击走 jumpApp(),带身份跳转。 -->
|
||
<section class="game-promo hide" id="gamePromo">
|
||
<button class="gp-card ripple" id="gpCard" type="button" aria-label="开始玩宝贝消消乐">
|
||
<span class="gp-new">兜爸旗下小游戏</span>
|
||
<span class="gp-text">
|
||
<span class="gp-name">宝贝消消乐</span>
|
||
<span class="gp-sub">三消攒待产好物,兜豆兑好礼</span>
|
||
</span>
|
||
<span class="gp-board" id="gpBoard" aria-hidden="true"></span>
|
||
<span class="gp-cta">开始玩 <svg viewBox="0 0 24 24" width="12" height="12" aria-hidden="true"><path d="M8 5l8 7-8 7z" fill="currentColor"/></svg></span>
|
||
<span class="gp-spark s1" aria-hidden="true">✦</span><span class="gp-spark s2" aria-hidden="true">✦</span><span class="gp-spark s3" aria-hidden="true">✦</span>
|
||
</button>
|
||
</section>
|
||
|
||
<!-- 模块三 · 书架卡带。
|
||
上一版是「一张横排大卡 + 下面两张小卡」的老三段,和上面两个模块
|
||
一样都是往下堆。这里改成一条横向可滑的书架:三张等宽等高的**竖版**书
|
||
(封面在上、书名在下、免费标在底),右边故意露出下一张的边角,
|
||
不用画箭头也知道能往右滑。整页因此多了一段「可以往右读」的节奏 ——
|
||
这是最直观的一处排版变化。
|
||
资源这类内容对可发现性的要求低(不像工具是每天要点的),
|
||
收进横滑里是合适的;工具那一屏就没这么干。
|
||
|
||
⚠️ data-wk="n" 是从原来那条 h2 里搬过来的。app.js 用
|
||
$$('[data-wk]') 全局扫,属性一丢孕周就永远显示「—」。 -->
|
||
<section class="shelf gift2">
|
||
<!-- 2026-10-01 改版:用户要「资料免费送、是一种福利、针对这个孕周」的感觉。
|
||
抬头改成礼盒 + 「孕N周专属福利」,三张书卡改成「福利券」:左上孕周专属角标、
|
||
封面右上「免费」印章、中间一道撕券虚线、底行「免费领 ›」。
|
||
⚠️ data-wk 照旧(app.js $$('[data-wk]') 全局扫,角标里那两个也会被填上)。 -->
|
||
<div class="shelf-bar gb-bar">
|
||
<span class="gb-gift" aria-hidden="true"><svg viewBox="0 0 24 24" width="26" height="26"><rect x="4.5" y="10.5" width="15" height="9.5" rx="2" fill="#fff"/><rect x="3.2" y="7.4" width="17.6" height="4.2" rx="1.6" fill="#fff"/><rect x="11" y="7.4" width="2" height="12.6" fill="#F7745E"/><rect x="3.2" y="11" width="17.6" height="1" fill="#F7745E" opacity=".35"/><path d="M12 7.4C10.6 4.6 7.6 4.2 7.6 6.1c0 1.3 2.2 1.3 4.4 1.3zm0 0c1.4-2.8 4.4-3.2 4.4-1.3 0 1.3-2.2 1.3-4.4 1.3z" fill="none" stroke="#fff" stroke-width="1.6" stroke-linejoin="round"/><path d="M20 1.8l.5 1.3 1.3.5-1.3.5-.5 1.3-.5-1.3-1.3-.5 1.3-.5z" fill="#FFF3C4"/></svg></span>
|
||
<div class="gb-ht">
|
||
<h2 class="sh-title">孕<span data-wk="n">—</span>周专属福利</h2>
|
||
<p class="sh-note">这周用得上的孕育资料,<b>全部免费送</b></p>
|
||
</div>
|
||
<button class="sh-all" data-open="detailResList">全部 ›</button>
|
||
</div>
|
||
<!-- 三张卡的内部结构是**逐行对齐**的:封面 / 标题 / 简介 / 底行,一个不缺。
|
||
上一稿只有第一张有简介、也只有第一张有「立即领取」,另两张少两截,
|
||
于是三张卡的标题落在不同高度、底行也不齐 —— 这就是看着乱的原因。
|
||
封面给了固定高度(80px + object-fit:contain),底行靠
|
||
.sb-row{margin-top:auto} 顶到卡底,中间的简介统一截两行,
|
||
三张就自然等高、四段横着都成列了。
|
||
⚠️ 原来第一张那颗「立即领取」删掉了:整张卡本身就是个 <button>,
|
||
点哪儿都是进详情页,那颗 span 长得像按钮却并不真的领取,是个假承诺;
|
||
而且三张卡并列时三颗橙色大按钮也太吵。领取动作留在详情页底部。
|
||
|
||
底行读作一句话:「这些人领了 → 一共 12.8 万 → 而且免费」。
|
||
所以头像贴着人数(同一件事的两半,中间只留 7px),「免费」用
|
||
margin-left:auto 甩到最右,是另起的一件事。
|
||
.sb-faces 里那 6 个 <i> 是**装饰**,不是真实用户头像 ——
|
||
assets/ 里没有人像图,也不该为这点装饰新增二进制资源,
|
||
所以整叠头像是纯 CSS 画的(圆底 + ::before 头 + ::after 肩)。
|
||
aria-hidden:读屏念到这行应该只听见「12.8 万妈妈已领取」,
|
||
而不是六个没有内容的空节点。
|
||
|
||
⚠️ 上面那三个数(12.8 / 20.4 / 9.6 万)是**真实领取量**,不是编的 ——
|
||
2026-09-22 有人按「人气数看着像演示值」把它们连同头像叠一起删了,
|
||
属**误判**,已恢复。**别再删**。它们是**手工同步的静态文案**:
|
||
接口虽返回同源的 got(已领),但 __applyResources 明确「有意不读」
|
||
(9.19 起 H5 已无「已领」概念),所以更新领取量时要**手工改这三处**;
|
||
要改成读接口,得先把这个口径捋清再动。 -->
|
||
<div class="shelf-rail">
|
||
<button class="shelf-book sb-book ripple" data-open="detailRes" data-res="book">
|
||
<span class="sb-tag">孕<span data-wk="n">—</span>周专属</span>
|
||
<img class="sb-cover" src="assets/img/9f3fa8edf4aa.png" alt="" aria-hidden="true">
|
||
<span class="sb-title">《糖耐检查全攻略》</span>
|
||
<span class="sb-desc">孕24-28周必看 · 附检查前饮食清单</span>
|
||
<span class="sb-row"><span class="sb-faces" aria-hidden="true"><i></i><i></i><i></i><i></i><i></i><i></i></span><i class="sb-got">12.8 万妈妈已领取</i><span class="pill-free">免费领</span></span>
|
||
</button>
|
||
<button class="shelf-book sb-food ripple" data-open="detailRes" data-res="food">
|
||
<span class="sb-tag">孕<span data-wk="n">—</span>周专属</span>
|
||
<img class="sb-cover" src="assets/img/3657b1f76026.png" alt="" aria-hidden="true">
|
||
<span class="sb-title">孕期营养全书</span>
|
||
<span class="sb-desc">按孕周编排的一日三餐参考</span>
|
||
<span class="sb-row"><span class="sb-faces" aria-hidden="true"><i></i><i></i><i></i><i></i><i></i><i></i></span><i class="sb-got">20.4 万妈妈已领取</i><span class="pill-free">免费领</span></span>
|
||
</button>
|
||
<button class="shelf-book sb-music ripple" data-open="detailRes" data-res="music">
|
||
<span class="sb-tag">孕<span data-wk="n">—</span>周专属</span>
|
||
<img class="sb-cover" src="assets/img/67405412c52c.png" alt="" aria-hidden="true">
|
||
<span class="sb-title">胎教音乐合集</span>
|
||
<span class="sb-desc">30 首适合孕中期的舒缓曲目</span>
|
||
<span class="sb-row"><span class="sb-faces" aria-hidden="true"><i></i><i></i><i></i><i></i><i></i><i></i></span><i class="sb-got">9.6 万妈妈已领取</i><span class="pill-free">免费领</span></span>
|
||
</button>
|
||
</div>
|
||
<!-- ⚠️ 这句话现在是**静态文案**(2026-09-19 9.19 需求:兑换码闸门取消,
|
||
不再有「已解锁/未解锁」两版口径,原来那个给 syncUnlockCopy() 用的
|
||
#shelfLeadTxt 靶子和该函数一起删了)。
|
||
旁边「查看全部 ›」是个 <a data-open>,它的点击监听是 init 时一次性
|
||
绑上去的 —— 谁要是图省事对整个 <p> 写 innerHTML,链接会连同监听被静默
|
||
换掉(看着一模一样,就是点不动),别再引入这种写法。
|
||
|
||
⚠️ 128 是**后端准备好的资料总数**,不是「资源列表里当前有多少条」——
|
||
2026-09-22 有人按「数字与列表条数不符」把它改成 RES 的条数,属**误判**,已回退:
|
||
· 资料按孕周陆续发放,目前上架 8 份,其余会陆续跟进;
|
||
· 没上架的**并非拿不到** —— 扫码加小助手可以直接索要(见顾问二维码弹窗)。
|
||
所以「128 份等你来领」是邀请口径(含找小助手要的),跟「列表当前 8 条」
|
||
是两件事,**数字不一样是对的**,别再"修"。 -->
|
||
<p class="unlock"><i class="ul-gift" aria-hidden="true"></i>福利库还有 <b>128</b> 份资料等你领 · <a data-open="detailResList">查看全部 ›</a></p>
|
||
</section>
|
||
|
||
<!-- 孕期盲盒 · 首页细横幅(2026-10-01,需求文档 v1.0 三-7)。
|
||
放在顶部大图正下方(需求:顶部大图 → 盲盒横幅 → 孕育工具 → 此刻 → 消消乐)。
|
||
文案/状态全由 app.js renderBanner() 按 /blindbox 返回写入;访客态(无 openid)、孕 4 周前、接口失败 → 保持 .hide。
|
||
⚠️ 2026-10-02 用户:「把盲盒放到首页下边,给一个位置就行,不用太明显」→
|
||
挪到 #homeBody 最后(福利书架之后),样式收成一条低调细条(见 CSS「盲盒挪到页底」)。
|
||
工具托盘因此重新成为第一个孩子,.home-body>:first-child 间距直接作用在它身上。 -->
|
||
<button class="bb-banner hide" id="bbBanner" type="button">
|
||
<span class="bb-gift" id="bbGift" aria-hidden="true"></span>
|
||
<span class="bb-badge hide" id="bbBadge" aria-hidden="true"></span>
|
||
<span class="bb-txt"><b class="bb-t" id="bbTitle"></b><span class="bb-s" id="bbSub"></span></span>
|
||
<span class="bb-cta" id="bbCta"></span>
|
||
<i class="bb-shine" aria-hidden="true"></i>
|
||
</button>
|
||
|
||
|
||
</div>
|
||
</section>
|
||
|
||
<section class="screen" id="screen-archive" data-screen="archive">
|
||
<div class="page-hero">
|
||
<div class="hero-top">
|
||
<div class="hero-actions">
|
||
<button class="icon-btn glass" data-search="1" aria-label="搜索"><svg viewBox="0 0 24 24" width="19" height="19"><circle cx="11" cy="11" r="6.5" fill="none" stroke="currentColor" stroke-width="1.9"/><path d="M16 16l4.5 4.5" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"/></svg></button>
|
||
<button class="icon-btn glass" data-toast="更多操作" aria-label="更多"><svg viewBox="0 0 24 24" width="19" height="19"><circle cx="5" cy="12" r="1.7"/><circle cx="12" cy="12" r="1.7"/><circle cx="19" cy="12" r="1.7"/></svg></button>
|
||
</div>
|
||
</div>
|
||
<!-- 这一块整体重排过一次,改动的理由都写在下面各处 -->
|
||
<div class="hero-info ar-hero">
|
||
<!-- 页面名。上一版把它降成了 13px、opacity .78 的一行眉批 ——
|
||
当时的理由是「底部 tab 上就写着档案,别拿 27px 再说一遍」,
|
||
字号该让给孕周,这点现在还成立。但让过头了:
|
||
这行是整个页面唯一出现宝宝小名的地方,糊在橙底上基本读不到。
|
||
这一版不靠字号抢回来(25px 仍然归 .ar-week),改成一枚毛玻璃小牌:
|
||
半透明白底 + 一圈描边,从橙色里浮出来;小名单独拎出来加粗放大,
|
||
「的成长档案」压一档跟在后面 —— 重音落在名字上,而不是「档案」上。
|
||
⚠️ 小名现在写进 #arTitleName,不再是 #arTitle 本身。
|
||
syncPregnancy() 里那句赋值跟着改了,别再往 #arTitle 上写 textContent,
|
||
那会把牌子里的图标和「的成长档案」一起冲掉。 -->
|
||
<h1 class="ar-title" id="arTitle"><svg class="ar-t-ico" viewBox="0 0 24 24" width="13" height="13" aria-hidden="true"><path d="M4 4.5A1.5 1.5 0 015.5 3H10a3 3 0 013 3v13a2.5 2.5 0 00-2.5-2.5H4z" fill="currentColor" opacity=".5"/><path d="M20 4.5A1.5 1.5 0 0018.5 3H14a3 3 0 00-3 3v13a2.5 2.5 0 012.5-2.5H20z" fill="currentColor"/></svg><b class="ar-t-name" id="arTitleName">宝宝</b><span class="ar-t-rest">的成长档案</span></h1>
|
||
<!-- 这两行 + 左边那个大小图标 + 下面的孕程条,都由 syncPregnancy() 按孕期信息重算。
|
||
emoji 用 aria-hidden 挡掉:读屏念成「玉米」会和紧跟着的「像一根玉米了」重复 -->
|
||
<div class="ar-lines">
|
||
<span class="ar-size" id="arSizeArt" aria-hidden="true">🌽</span>
|
||
<div>
|
||
<p class="ar-week" id="arLine1">孕 24 周 +3 天</p>
|
||
<p class="hero-p sub" id="arLine2">像一根玉米了 · 约 600 克</p>
|
||
</div>
|
||
</div>
|
||
<!-- 孕程原来是右边一个 84px 的圆环,和首页 hero 那个环长得一模一样,
|
||
两页来回切像同一个组件贴了两遍;它还横着吃掉近三分之一宽度,
|
||
逼得旁边的字只能写得又短又挤,「已陪伴 171 天」当时就只能拿个「·」
|
||
硬接在孕周后面,两个不相干的单位读起来像一句话。
|
||
换成一条通栏细进度条:高 5px,信息一点没少,左右还各空出一个角,
|
||
「孕程」和「已陪伴」这才各站各的位置。 -->
|
||
<div class="ar-prog"><i id="arBar"></i></div>
|
||
<div class="ar-foot">
|
||
<span>孕程 <b id="arPct">60%</b></span>
|
||
<span>已陪伴 <b id="arDays">171</b> 天</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="page-body">
|
||
<!-- ========== 正在自动归档 + 生成档案(合成一张卡) ==========
|
||
顺序:标题 → 两个生成入口 → 归档条数统计。
|
||
周档案:每周一张长图,保存到相册或分享朋友圈;
|
||
完整档案:从记录第一天到今天,排成一本 A4 分页的册子,打印出来能直接装订。
|
||
两者都是 canvas 现画出来的,不依赖任何外部库。 -->
|
||
<div class="auto-card">
|
||
<div class="ac-head">
|
||
<span class="ac-h-l"><span class="live-dot"></span> 正在自动归档</span>
|
||
<span class="gen-badge" id="genWeekTag">第 24 周</span>
|
||
</div>
|
||
<!-- 说明文字拆进了下面两个入口各自的副标题:
|
||
谁能干什么写在谁身上,比笼统一句更好读。
|
||
「可打印」原本在这里的角标和按钮里各出现一次,现在只留按钮那处 -->
|
||
<div class="gen-btns">
|
||
<button class="gen-btn ripple" data-poster="week">
|
||
<svg viewBox="0 0 24 24" width="21" height="21" aria-hidden="true">
|
||
<rect x="3.5" y="4.5" width="17" height="16" rx="3" fill="none" stroke="currentColor" stroke-width="1.8"/>
|
||
<path d="M3.5 9.5h17M8 2.8v3.4M16 2.8v3.4" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/>
|
||
<rect x="7" y="12.5" width="5" height="4" rx="1.2" fill="currentColor"/>
|
||
</svg>
|
||
<span><b>本周档案</b><em>存相册 · 发朋友圈</em></span>
|
||
</button>
|
||
<button class="gen-btn ripple" data-poster="all">
|
||
<svg viewBox="0 0 24 24" width="21" height="21" aria-hidden="true">
|
||
<path d="M7 3.5h7.5L19 8v12.5H7z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/>
|
||
<path d="M14 3.5V8h5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/>
|
||
<path d="M10 12h6M10 15.5h6M10 19h3.5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/>
|
||
</svg>
|
||
<span><b>完整档案</b><em>A4 分页 · 可装订</em></span>
|
||
</button>
|
||
</div>
|
||
<div class="ac-chips">
|
||
<span class="chip-stat">今日已归档 <b>4</b> 条</span>
|
||
<span class="chip-stat">累计 <b>386</b> 条</span>
|
||
<span class="chip-stat">来自 <b>9</b> 个孕期工具</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="segmented" id="archiveSeg">
|
||
<span class="seg-thumb" id="segThumb"></span>
|
||
<!-- ⚠️ 这三个按钮的顺序必须和下面 .seg-panel 的 DOM 顺序一一对应。
|
||
initSegmented() 是按 .is-active 在兄弟节点里的**序号**算 #segThumb 的 x 偏移,
|
||
只改按钮不改面板 → 高亮停在「成长数据」、底下却显示时光轴。 -->
|
||
<button class="seg-btn is-active" data-seg="data">成长数据</button>
|
||
<button class="seg-btn" data-seg="timeline">时光轴</button>
|
||
<!-- 收藏数原本在下面那行 sec-title 里,那行整条删了,
|
||
数字搬到标签上(和分段控件里其它计数同一种写法),#favCount 仍由 JS 更新。
|
||
⚠️ 这里原来写死 18,而屏幕上点亮的星标只有 6 个 —— 数字与内容对不上。
|
||
现在默认 0,由 app.js 启动时按 DOM 里 `.star.is-on` 的**实际个数**回填
|
||
(档案页不是首屏,用户看不到中间态;点星标时再 ±1)。 -->
|
||
<button class="seg-btn" data-seg="moment">珍贵时刻 <i id="favCount">0</i></button>
|
||
</div>
|
||
|
||
<!-- 成长数据 -->
|
||
<div class="seg-panel is-active" data-panel="data">
|
||
<!-- ⚠️ 空态(未建档 / pregEmpty):syncPregnancy 会给本面板加 .is-empty,
|
||
把下面三块**全无数据源**的演示内容整块隐藏,改显示这行引导。
|
||
三块里没有一个数字来自接口:58.2kg / 31 次 / 600g / 双顶径 6.1cm 都是设计稿数字,
|
||
未建档用户看到就是纯假数据(2026-09-22 实测)。 -->
|
||
<div class="data-empty">还没有可统计的记录<br>去「数胎动」或「孕期体重」记一笔,这里会生成趋势</div>
|
||
<div class="stat-row data-demo">
|
||
<div class="stat-card">
|
||
<div class="sc-label">体重</div>
|
||
<div class="sc-value">58.2<small>kg</small></div>
|
||
<div class="sc-trend up">↑ 7.7kg</div>
|
||
<svg class="spark" viewBox="0 0 100 34"><polyline points="2,30 26,24 50,17 74,10 98,4" fill="none" stroke="#F4593C" stroke-width="2.6" stroke-linecap="round"/></svg>
|
||
</div>
|
||
<div class="stat-card">
|
||
<div class="sc-label">日均胎动</div>
|
||
<div class="sc-value">31<small>次</small></div>
|
||
<div class="sc-trend ok">正常</div>
|
||
<svg class="spark" viewBox="0 0 100 34"><polyline points="2,20 20,8 38,24 56,10 74,26 98,14" fill="none" stroke="#7FA86A" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||
</div>
|
||
<div class="stat-card">
|
||
<div class="sc-label">估计体重</div>
|
||
<div class="sc-value">600<small>g</small></div>
|
||
<div class="sc-trend purple">P55</div>
|
||
<svg class="spark" viewBox="0 0 100 34"><polyline points="2,29 26,23 50,17 74,11 98,4" fill="none" stroke="#8B6FE0" stroke-width="2.6" stroke-linecap="round"/></svg>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="chart-card data-demo">
|
||
<div class="cc-title">妈妈体重 · 孕12–24周</div>
|
||
<svg class="chart" viewBox="0 0 320 150">
|
||
<line class="grid" x1="4" y1="20" x2="316" y2="20"/>
|
||
<line class="grid" x1="4" y1="66" x2="316" y2="66"/>
|
||
<line class="grid" x1="4" y1="112" x2="316" y2="112"/>
|
||
<path class="band" d="M8,138 L83,120 L158,100 L234,76 L310,54 L310,14 L234,36 L158,60 L83,80 L8,98 Z"/>
|
||
<path class="area" d="M8,124 L83,106 L158,86 L234,62 L310,40 L310,146 L8,146 Z"/>
|
||
<polyline class="line" points="8,124 83,106 158,86 234,62 310,40"/>
|
||
<circle class="pt" cx="83" cy="106" r="6"/><circle class="pt" cx="158" cy="86" r="6"/><circle class="pt" cx="234" cy="62" r="6"/>
|
||
<circle class="pt fill" cx="310" cy="40" r="7"/>
|
||
</svg>
|
||
<div class="cc-x"><span>12周</span><span>16周</span><span>20周</span><span>24周</span></div>
|
||
<div class="cc-legend"><span class="lg lg-line">我的体重</span><span class="lg lg-band">推荐区间</span></div>
|
||
</div>
|
||
|
||
<div class="meas-card data-demo">
|
||
<div class="meas"><span class="m-name">双顶径</span><div class="m-bar" style="--p:54%"><i></i></div><div class="m-val">6.1<small>cm</small><em>P58</em></div></div>
|
||
<div class="meas"><span class="m-name">股骨长</span><div class="m-bar" style="--p:50%"><i></i></div><div class="m-val">4.4<small>cm</small><em>P52</em></div></div>
|
||
<div class="meas"><span class="m-name">腹围</span><div class="m-bar" style="--p:60%"><i></i></div><div class="m-val">19.6<small>cm</small><em>P61</em></div></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 时光轴 -->
|
||
<!-- 这里原来还压着一排分类 chips(全部/胎动/产检/来信/手记)。删了:
|
||
上面刚有一排「时光轴 / 成长数据 / 珍贵时刻」的分段,紧接着再来一排样子
|
||
几乎一样的标签,两排叠在一起谁管谁根本看不出来。
|
||
而且时光轴统共五条,一条一个分类,筛完最多剩两条 —— 为了从五条里挑两条
|
||
先读五个标签,不划算。每条底下本来就写着「来自「数胎动」」,
|
||
要认哪一类,读那行就够了。 -->
|
||
<div class="seg-panel" data-panel="timeline">
|
||
<div class="tl-card">
|
||
<div class="tl-item" data-cat="胎动">
|
||
<div class="tl-date" data-ga="now"></div>
|
||
<p class="tl-text">早上 9 点 10 分,他动了 <b>12 次</b>。你说那感觉像有人在里面轻轻敲门。</p>
|
||
<span class="tl-from">来自「数胎动」</span>
|
||
</div>
|
||
<div class="tl-item" data-cat="产检">
|
||
<div class="tl-date" data-ga="20"></div>
|
||
<p class="tl-text">大排畸那天,你第一次看清了他的侧脸。医生说「一切都好」,你在诊室外站了很久。</p>
|
||
<span class="tl-from">来自「孕检日历」+「B超影像」</span>
|
||
</div>
|
||
<div class="tl-item" data-cat="胎动">
|
||
<div class="tl-date" data-ga="18"></div>
|
||
<p class="tl-text">傍晚散步时,肚子里忽然有一下轻轻的翻涌 —— <b>第一次胎动</b>。你愣在原地,然后笑了。</p>
|
||
<span class="tl-from">来自「胎动记录」</span>
|
||
</div>
|
||
<div class="tl-item" data-cat="产检">
|
||
<div class="tl-date" data-ga="8"></div>
|
||
<p class="tl-text">第一次听见心跳,很快,像小火车。你把那 12 秒录了下来。</p>
|
||
<span class="tl-from">来自「胎心记录」</span>
|
||
</div>
|
||
<div class="tl-item" data-cat="手记">
|
||
<div class="tl-date" data-ga="1"></div>
|
||
<p class="tl-text">那两条线出现的早晨,你把它拍下来,发给了他。你们谁都没说话,笑了很久。</p>
|
||
<span class="tl-from">来自「妈妈手记」</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 珍贵时刻 -->
|
||
<!-- 同样删掉了一排分类 chips(全部/第一次/影像/声音/手写)。
|
||
六个格子的九宫格,本身一眼就扫完了,再给它配五个筛选标签是本末倒置。 -->
|
||
<div class="seg-panel" data-panel="moment">
|
||
<!-- 珍贵时刻的封面图标:原来是 emoji(🖼️💌👣🎧🤰✍️),
|
||
各系统渲染成的样子完全不同(拟物、彩色、还带阴影),
|
||
这里统一换成同一套线性扁平 SVG,颜色跟着各自的渐变底走 -->
|
||
<div class="moment-grid">
|
||
<button class="moment ripple" data-cat="影像 第一次" data-toast="第一张B超 · 孕8周">
|
||
<div class="mo-art a1">
|
||
<svg viewBox="0 0 48 48" aria-hidden="true">
|
||
<rect x="7" y="9" width="34" height="26" rx="5" class="f"/>
|
||
<rect x="7" y="9" width="34" height="26" rx="5" class="s"/>
|
||
<path d="M16 29a12 12 0 0 1 12-12" class="s"/>
|
||
<path d="M16 29a7 7 0 0 1 7-7" class="s"/>
|
||
<circle cx="16" cy="29" r="2.4" class="d"/>
|
||
<path d="M24 35v4M20 39h8" class="s"/>
|
||
</svg>
|
||
<i class="star is-on">★</i>
|
||
</div>
|
||
<div class="mo-title">第一张B超</div><div class="mo-meta" data-ga="8"></div><span class="mo-from">来自「B超影像」</span>
|
||
</button>
|
||
<!-- ⚠️ `.mo-from` 引的是**底 tab 的名字**,不是随便一句出处。
|
||
tab 叫什么,这里就必须写什么 —— 指过去的地方得真的存在。
|
||
上一批 tab 改叫「宝宝消息」时这三处跟着改过(标题「第一条消息」、
|
||
出处「来自「宝宝消息」」、data-toast),本批 tab 退回「宝宝来信」,
|
||
三处一起退。
|
||
⚠️ 宽度:来回都是等字数替换(5 字换 5 字、8 字换 8 字),
|
||
.mo-title / .mo-from 的排版账不用重算。
|
||
⚠️ data-toast 那句是点上去弹的提示,和标题同源,一起改,别只改一处 ——
|
||
它藏在属性里,只扫 textContent 的检查看不见它。 -->
|
||
<button class="moment ripple" data-cat="第一次" data-toast="第一封来信 · 孕12周">
|
||
<div class="mo-art a2">
|
||
<svg viewBox="0 0 48 48" aria-hidden="true">
|
||
<rect x="6" y="11" width="36" height="26" rx="5" class="f"/>
|
||
<rect x="6" y="11" width="36" height="26" rx="5" class="s"/>
|
||
<path d="M8.5 14.5l14 11a2.4 2.4 0 0 0 3 0l14-11" class="s"/>
|
||
</svg>
|
||
<i class="star is-on">★</i>
|
||
</div>
|
||
<div class="mo-title">第一封来信</div><div class="mo-meta" data-ga="12"></div><span class="mo-from">来自「宝宝来信」</span>
|
||
</button>
|
||
<button class="moment ripple" data-cat="第一次" data-toast="第一次胎动 · 孕18周">
|
||
<div class="mo-art a3">
|
||
<svg viewBox="0 0 48 48" aria-hidden="true">
|
||
<path d="M27 17c0 6-2.8 8.8-2.8 12.8 0 4-2.4 6.7-5.9 6.7s-6.3-2.7-6.3-6.7c0-5 2.9-7.9 2.9-12.8 0-4.1 2.6-7 5.9-7s6.2 2.9 6.2 7z" class="f"/>
|
||
<path d="M27 17c0 6-2.8 8.8-2.8 12.8 0 4-2.4 6.7-5.9 6.7s-6.3-2.7-6.3-6.7c0-5 2.9-7.9 2.9-12.8 0-4.1 2.6-7 5.9-7s6.2 2.9 6.2 7z" class="s"/>
|
||
<circle cx="31.5" cy="14.5" r="3" class="d"/>
|
||
<circle cx="35.6" cy="20.4" r="2.6" class="d"/>
|
||
<circle cx="36.8" cy="27" r="2.2" class="d"/>
|
||
</svg>
|
||
<i class="star is-on">★</i>
|
||
</div>
|
||
<div class="mo-title">第一次胎动</div><div class="mo-meta" data-ga="18"></div><span class="mo-from">来自「胎动记录」</span>
|
||
</button>
|
||
<button class="moment ripple" data-cat="声音" data-toast="正在播放 胎心录音 ♪">
|
||
<div class="mo-art a4">
|
||
<svg viewBox="0 0 48 48" aria-hidden="true">
|
||
<path d="M24 39S8 30.2 8 19.8C8 14.6 12 11.2 16.2 11.2c3.2 0 6 1.8 7.8 4.4 1.8-2.6 4.6-4.4 7.8-4.4 4.2 0 8.2 3.4 8.2 8.6C40 30.2 24 39 24 39z" class="f"/>
|
||
<path d="M24 39S8 30.2 8 19.8C8 14.6 12 11.2 16.2 11.2c3.2 0 6 1.8 7.8 4.4 1.8-2.6 4.6-4.4 7.8-4.4 4.2 0 8.2 3.4 8.2 8.6C40 30.2 24 39 24 39z" class="s"/>
|
||
<path d="M12.5 22.5h5.2l3-5.4 3.9 10.4 2.8-5h6.1" class="s"/>
|
||
</svg>
|
||
<i class="star is-on">★</i>
|
||
</div>
|
||
<div class="mo-title">胎心录音 12秒</div><div class="mo-meta" data-ga="20"></div><span class="mo-from">来自「胎心记录」</span>
|
||
</button>
|
||
<button class="moment ripple" data-cat="影像 第一次" data-toast="第一张孕肚照 · 孕22周">
|
||
<div class="mo-art a5">
|
||
<svg viewBox="0 0 48 48" aria-hidden="true">
|
||
<path d="M6 17a4 4 0 0 1 4-4h5l2.6-4.2h12.8L33 13h5a4 4 0 0 1 4 4v17a4 4 0 0 1-4 4H10a4 4 0 0 1-4-4z" class="f"/>
|
||
<path d="M6 17a4 4 0 0 1 4-4h5l2.6-4.2h12.8L33 13h5a4 4 0 0 1 4 4v17a4 4 0 0 1-4 4H10a4 4 0 0 1-4-4z" class="s"/>
|
||
<circle cx="24" cy="25.5" r="7" class="s"/>
|
||
<circle cx="24" cy="25.5" r="2.6" class="d"/>
|
||
</svg>
|
||
<i class="star is-on">★</i>
|
||
</div>
|
||
<div class="mo-title">第一张孕肚照</div><div class="mo-meta" data-ga="22"></div><span class="mo-from">来自「孕肚照」</span>
|
||
</button>
|
||
<button class="moment ripple" data-cat="手写" data-toast="给宝宝的回信 · 孕23周">
|
||
<div class="mo-art a6">
|
||
<svg viewBox="0 0 48 48" aria-hidden="true">
|
||
<path d="M31.4 8.6a4 4 0 0 1 5.7 5.7L17.6 33.8l-8.2 2.5 2.5-8.2z" class="f"/>
|
||
<path d="M31.4 8.6a4 4 0 0 1 5.7 5.7L17.6 33.8l-8.2 2.5 2.5-8.2z" class="s"/>
|
||
<path d="M28.5 11.5l5.7 5.7" class="s"/>
|
||
<path d="M14 41h22" class="s"/>
|
||
</svg>
|
||
<i class="star is-on">★</i>
|
||
</div>
|
||
<div class="mo-title">给宝宝的回信</div><div class="mo-meta" data-ga="23"></div><span class="mo-from">来自「我的回信」</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<button class="album-card ripple" data-toast="纪念册第 2 册编纂中……">
|
||
<div class="al-book"><span class="al-leaf">🌱</span><span class="al-tag">孕早期<br>1–13周</span></div>
|
||
<div class="al-body">
|
||
<div class="al-title">纪念册 <em>交给未来的孩子</em></div>
|
||
<p class="al-desc">第 1 册已成册(32 页)· 第 2 册编纂中<br>等他长大,这些会替你把话说完。</p>
|
||
<div class="al-bar"><i style="--p:62%"></i></div>
|
||
<div class="al-meta">孕中期 62% · 预计孕28周可成册</div>
|
||
</div>
|
||
</button>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="screen" id="screen-me" data-screen="me">
|
||
<div class="me-top me-v2">
|
||
<!-- 2026-10-01「我的」页改版:头部从实心橘渐变 + 白卡,改成蜜桃 → 珊瑚的柔光渐变,
|
||
用户信息直接压在渐变上(白字),下面一张金色「兜豆兑换商城」卡半压在头部边缘。
|
||
装饰:两团柔光 + 几颗小星星,纯 CSS/SVG,不加图片请求。 -->
|
||
<i class="mt-glow g1" aria-hidden="true"></i><i class="mt-glow g2" aria-hidden="true"></i>
|
||
<svg class="mt-stars" viewBox="0 0 120 60" aria-hidden="true"><path d="M20 14l1.6 4.2 4.4 1.6-4.4 1.6L20 25.6l-1.6-4.2-4.4-1.6 4.4-1.6z" fill="#fff" opacity=".75"/><path d="M92 8l1 2.6 2.6 1-2.6 1L92 15.2l-1-2.6-2.6-1 2.6-1z" fill="#fff" opacity=".6"/><circle cx="64" cy="22" r="1.6" fill="#fff" opacity=".55"/><circle cx="108" cy="40" r="1.2" fill="#fff" opacity=".5"/></svg>
|
||
<div class="hero-top">
|
||
<!-- (商城图标已移除:进商城统一走下方「兜爸心选」模块 meMallCard)
|
||
<button class="icon-btn plain" id="btnMall" aria-label="进商城">
|
||
<svg viewBox="0 0 24 24" width="22" height="22" aria-hidden="true">
|
||
<path d="M5 8h14l-1.2 11a2 2 0 0 1-2 1.8H8.2a2 2 0 0 1-2-1.8z" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linejoin="round"/>
|
||
<path d="M8.6 10V6.8a3.4 3.4 0 0 1 6.8 0V10" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/>
|
||
</svg>
|
||
</button>
|
||
-->
|
||
<!-- 扁平化齿轮:描边式矢量,替换原本的 ⚙️ emoji -->
|
||
<button class="icon-btn plain" data-modal="modalProfile" aria-label="设置">
|
||
<svg viewBox="0 0 24 24" width="22" height="22" aria-hidden="true">
|
||
<path d="M12 15.2a3.2 3.2 0 1 0 0-6.4 3.2 3.2 0 0 0 0 6.4z" fill="none" stroke="currentColor" stroke-width="1.7"/>
|
||
<path d="M19.4 13.5a1.5 1.5 0 0 0 .3 1.65l.06.05a1.8 1.8 0 1 1-2.55 2.55l-.05-.06a1.5 1.5 0 0 0-1.65-.3 1.5 1.5 0 0 0-.91 1.37v.14a1.8 1.8 0 1 1-3.6 0v-.07a1.5 1.5 0 0 0-.98-1.37 1.5 1.5 0 0 0-1.65.3l-.05.06a1.8 1.8 0 1 1-2.55-2.55l.06-.05a1.5 1.5 0 0 0 .3-1.65 1.5 1.5 0 0 0-1.37-.91h-.14a1.8 1.8 0 1 1 0-3.6h.07a1.5 1.5 0 0 0 1.37-.98 1.5 1.5 0 0 0-.3-1.65l-.06-.05A1.8 1.8 0 1 1 8.5 4.01l.05.06a1.5 1.5 0 0 0 1.65.3h.07a1.5 1.5 0 0 0 .91-1.37v-.14a1.8 1.8 0 1 1 3.6 0v.07a1.5 1.5 0 0 0 .91 1.37 1.5 1.5 0 0 0 1.65-.3l.05-.06a1.8 1.8 0 1 1 2.55 2.55l-.06.05a1.5 1.5 0 0 0-.3 1.65v.07a1.5 1.5 0 0 0 1.37.91h.14a1.8 1.8 0 1 1 0 3.6h-.07a1.5 1.5 0 0 0-1.37.91z" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
<!-- 整张卡可点:点它和点右上角齿轮都会打开「我的资料」弹窗。
|
||
这里保持 div 而不是 button——里面还嵌着头像的编辑角标,
|
||
button 套 button 是非法结构,浏览器会把 DOM 拆开 -->
|
||
<div class="me-card ripple" data-modal="modalProfile" role="button" tabindex="0">
|
||
<div class="me-avatar" id="meAvatar">
|
||
<svg viewBox="0 0 40 40" width="34" height="34" aria-hidden="true">
|
||
<!-- 卡片改成白底后,写死的 #fff 剪影会直接看不见,改由 .me-avatar 的 color 决定 -->
|
||
<circle cx="20" cy="14.5" r="7" fill="currentColor"/>
|
||
<path d="M6.5 35c0-7.2 6-11.5 13.5-11.5S33.5 27.8 33.5 35z" fill="currentColor"/>
|
||
</svg>
|
||
<img id="meAvatarImg" alt="">
|
||
<i class="av-edit" aria-hidden="true">
|
||
<svg viewBox="0 0 24 24" width="11" height="11">
|
||
<path d="M4 20h16" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/>
|
||
<path d="M15.6 4.4a2.3 2.3 0 0 1 3.3 3.3L9.7 16.9l-4.3 1 1-4.3z" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linejoin="round"/>
|
||
</svg>
|
||
</i>
|
||
</div>
|
||
<div class="me-info">
|
||
<div class="me-name" id="meName">未登录</div>
|
||
<!-- ⚠️ 这里先后住过两样东西,两样都已经删了,别再往回搬:
|
||
① 最早是「孕 24 周 +3 天 · 预产期 12月22日」,由 syncPregnancy() 刷。
|
||
删它是因为**重复**:往下滚一屏就是孕期卡,孕周、预产期、
|
||
剩余天数在那儿写得更全。
|
||
② 然后换成了一句话签名 <p class="me-bio" id="meBio">,
|
||
本批按用户要求(「我的资料里的一句话签名可以去掉」)连同
|
||
弹窗里的 #pfBio 输入框、js 里的 syncBio()、state.userBio 一起删。
|
||
⚠️ 必须一起删:只删输入框、留下这行展示,它就成了一句
|
||
谁也改不动的死文案 —— 用户会在资料弹窗里翻来翻去找哪儿能改。
|
||
⚠️ syncPregnancy() 里那行 $('.me-info p') 早就删掉了(它取的是
|
||
**第一个** <p>)。现在第一个 <p> 是下面的「已连续记录」,
|
||
谁要是把那行加回来,会把连续记录天数冲掉,而且是静默的。 -->
|
||
<span class="me-tag hide" id="meTag"></span>
|
||
<p id="meRecordLine">已连续记录 <b>42</b> 天</p>
|
||
<!-- 2026-10-10 用户:未授权时说明「数据还在」,避免误以为记录丢了。用 div 不用 p:别占「第一个 <p>」 -->
|
||
<div class="me-saved" id="meSaved" style="display:none">孕期资料已保存在本微信</div>
|
||
</div>
|
||
<i class="me-chev" aria-hidden="true">›</i>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="page-body no-top">
|
||
<!-- 毛玻璃底下的彩色光斑(2026-10-04 用户:「卡片毛玻璃一点,现在白底平铺不好看」)。
|
||
卡片是半透明 + backdrop-filter,必须垫点颜色才透得出玻璃感;纯 CSS,不加图片请求。 -->
|
||
<i class="me-orbs" aria-hidden="true"><b class="o1"></b><b class="o2"></b><b class="o3"></b><b class="o4"></b></i>
|
||
<!-- 退出登录已移到个人资料卡右上角的图标按钮(#meLogoutBtn) -->
|
||
<!-- ⚠️ 这两处的 data-modal 从 modalPreg 改成了 modalProfile:
|
||
「编辑孕期信息」那张弹窗已整个并进「我的资料」(见文件末尾那段说明)。
|
||
小名 / 性别 / 预产期现在只有一处能改,改完照样 syncPregnancy() 回刷这张卡。 -->
|
||
<!-- ⚠️ 「(必填)」是独立的 <span class="sec-req">,**不能**塞进 .sec-more 那颗按钮里 ——
|
||
.sec-more 是「编辑 ›」的可点区域,把「必填」并进去等于扩大了热区,
|
||
用户想读一眼提示、结果弹出了编辑窗。它也不能只是写进标题文本里:
|
||
要单独一个元素才能上品牌色。
|
||
⚠️ 用品牌色不用灰:「必填」是一句**要求**,写成灰小字就退成了附注,没人会去填。
|
||
宽度账(.page-body 左右各 18 → 可用 284,.sec-title 是 flex、gap 8):
|
||
竖条 4 + 8 + 「孕期信息」4×17.5=70 + 8 + 「(必填)」4×12=48 + 8 + 「编辑 ›」≈34
|
||
= 180 ≤ 284 ✓,余 104px,宽裕。 -->
|
||
<!-- 2026-10-01:按用户要求孕期卡和兜豆卡对调 —— 孕期卡现在半压在头部底边上,所以去掉了上方的
|
||
「孕期信息(必填)· 编辑 ›」标题行(标题压在渐变上很乱);整卡本身就点开资料弹窗,
|
||
「必填」挪进弹窗里那张「孕期信息」卡的角标。 -->
|
||
<button class="preg-card ripple" data-modal="modalProfile">
|
||
<div class="pc-row">
|
||
<!-- 孕周进度环 + 蜷着的宝宝。
|
||
上一版是一个细线条的孕妇侧影:笔画太细、那条「腿」像根多余的杂线,
|
||
肚子里那颗浅色小点在 52px 上几乎看不见,凑近才认得出画的是什么。
|
||
换掉的理由不只是好看 —— 这张卡讲的就是「走到哪儿了」
|
||
(孕 24 周 +3 天 / 还有 110 天 / 一条进度条 / 早中晚期三段),
|
||
所以图标本身就画成一圈进度:外圈是整个孕期,实心那段是已经走过的,
|
||
中间蜷着的是宝宝。图标和卡片说的是同一件事。
|
||
⚠️ 这一圈是**活的**:syncPregnancy() 按真实孕周重写 #pcRing 的
|
||
stroke-dasharray,和下面那条 .pc-bar 同源(同一个 pct)。
|
||
这里写死的 "45 73" 只是 JS 跑起来之前的占位(≈62%,对应 r=11.6
|
||
的周长 72.9),不是设计值 —— 要改进度去改 syncPregnancy,别调这里。
|
||
⚠️ 下面这几处颜色跟着 .preg-card 的配色走
|
||
(橘 → 雾蓝 → 紫粉 → 现在的深紫渐变 + 白)。
|
||
它们是 SVG presentation attribute,不在 style.css 里,
|
||
改配色时最容易漏掉的就是这一块 —— 上一版深紫 #7B5BD6 在这儿出现
|
||
**三次**(进度环 stroke、宝宝头 fill、身子 stroke),
|
||
只改第一处就会得到「紫环配蓝宝宝」。
|
||
⚠️ 卡片现在是深底,整个图标就是**一色白**,上面那个「三处」的坑
|
||
因此暂时看不出来了 —— 但它随时会回来:下次谁把配色改回浅底,
|
||
就得重新给这三处各挑一个深色。smoke 里钉着「图标里所有颜色一致」,
|
||
漏改一处就会红。
|
||
⚠️ 底环用 stroke-opacity 调暗,**不能**和进度环一样是实白 ——
|
||
两圈一样白就等于没有进度环,那一圈永远看着是满的。
|
||
用 stroke-opacity 而不是 rgba():presentation attribute 里
|
||
rgba 各家浏览器支持不一,stroke-opacity 是 SVG 1.1 的正经属性。 -->
|
||
<div class="pc-ico">
|
||
<svg viewBox="0 0 32 32" width="27" height="27" aria-hidden="true">
|
||
<circle cx="16" cy="16" r="11.6" fill="none" stroke="#F0704F" stroke-opacity=".3" stroke-width="3.2"/>
|
||
<circle id="pcRing" cx="16" cy="16" r="11.6" fill="none" stroke="#F0704F" stroke-width="3.2"
|
||
stroke-linecap="round" stroke-dasharray="45 73" transform="rotate(-90 16 16)"/>
|
||
<circle cx="17" cy="12.9" r="3.2" fill="#F0704F"/>
|
||
<path d="M13.8 17.2c.3 3.6 3 5.1 6 4.1" fill="none" stroke="#F0704F" stroke-width="3.4" stroke-linecap="round"/>
|
||
</svg>
|
||
</div>
|
||
<div class="pc-main"><div class="pc-title" id="pcTitle">孕 24 周 +3 天</div><div class="pc-sub" id="pcSub">预产期 2024年12月22日 · 还有 110 天</div></div>
|
||
<i class="chev">›</i>
|
||
</div>
|
||
<div class="pc-bar"><i id="pcBar" style="--p:60%"></i></div>
|
||
<div class="pc-stage"><span>孕早期</span><span class="cur" id="pcStage">孕中期 · 当前</span><span>孕晚期</span></div>
|
||
</button>
|
||
|
||
<!-- 兜豆兑换商城主卡(2026-10-01):半压在头部渐变边缘,是「我的」页最跳的一张。
|
||
点击走 openExchange()(app.js)—— 链接优先取应用后台,取不到再用写死的兜底地址。
|
||
#meExchSub 未登录写「攒兜豆,好物免费兑」,拿到余额后改成「兜豆 N · 可兑 M 件」(loadDou())。 -->
|
||
<!-- 授权完善资料:H5 → navigateTo → 小程序授权页(头像/昵称/手机号) → box_app /auth/profile 落库 -->
|
||
<div class="list-card" style="margin-top:14px" id="meAuthBox">
|
||
<button class="li ripple" id="meAuthCard">
|
||
<span class="li-ico o"><svg viewBox="0 0 24 24" width="19" height="19" aria-hidden="true"><rect x="5" y="10.5" width="14" height="9.5" rx="2.5" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M8.5 10.5V8a3.5 3.5 0 0 1 7 0v2.5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/><path d="M12 15v2" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg></span>
|
||
<span class="li-t">授权完善资料</span>
|
||
<span class="li-v">获取手机号 / 昵称 / 头像</span>
|
||
<i class="chev">›</i>
|
||
</button>
|
||
</div>
|
||
|
||
<!-- 兜豆兑换:2026-10-04 用户要求「收起来,不要这么大地展示」—— 原来的大卡(标题+热门 3 件好物)收成一条横条,
|
||
和下面「兜爸心选商城」同款。#meExchCard / #meExchSub 不变(openExchange、loadDou 照旧);
|
||
#meExchDrop 已删,renderDrop() 里有 if (box) 判空,不用改 JS。 -->
|
||
<button class="mall-strip exch ripple" id="meExchCard">
|
||
<span class="ms-ico" aria-hidden="true"><img src="assets/img/dou-coin.svg?v=20261002" width="28" height="28" alt=""></span>
|
||
<span class="ms-main"><b>兜豆兑好物</b><span id="meExchSub">攒兜豆,好物免费兑</span></span>
|
||
<span class="ms-go">去兑换<i>›</i></span>
|
||
</button>
|
||
|
||
|
||
|
||
|
||
<!-- ================= 孕育顾问(企业微信入口) =================
|
||
常驻在孕期卡下面:上面那张卡讲「你走到哪儿了」,这张接着说
|
||
「路上有人陪你」,是同一段话的下一句;而「设置与服务」那组是
|
||
工具箱,把一个真人服务塞进去会被当成一行设置项划过去。
|
||
⚠️ 故意**不挂 data-modal="modalWx"**。那条通用通道直接调 openModal,
|
||
会绕过 openWx() —— 弹窗的模式类名、引导语、上次残留的红字和
|
||
输入内容、还有 wxPending 全都不会被重置。这里必须走 JS 那条路。
|
||
⚠️ 这张卡历史上**不随解锁状态隐藏**(资源库顶部那条 banner 会),
|
||
定位是「我的」页的常驻入口。本批(第九批)按用户要求把整块
|
||
「专属福利」先隐藏 —— 见下面 #meWelfareHidden 那段注释;
|
||
上面这条「常驻」的旧约定随之暂停,恢复时把该容器的 display:none 去掉即可。 -->
|
||
<!-- ⚠️ 本批(第九批)按用户要求**先隐藏**「专属福利」整块(标题 + 孕育顾问卡)。
|
||
用外层容器 display:none 而不是删 DOM,原因有二:
|
||
① #meWxCard 的点击绑定(app.js openWx('gift'))、syncBabyWords() 对
|
||
#meWxTitle/#meWxSub 的写入都还引用它们,删了会当场报错;
|
||
② 保留 DOM 便于随时一键恢复(去掉这里的 display:none 即可)。
|
||
⚠️ 隐藏的只是这一块。下面「甄选好物 / 进入商城」(#meMallCard)**不动** ——
|
||
它是另一张卡,用户没要求藏。
|
||
⚠️ 资源库顶部那条 #rlGift banner 不在这一块里,本次未动。 -->
|
||
<div id="meWelfareHidden" style="display:none">
|
||
<h2 class="sec-title dark">专属福利</h2>
|
||
<button class="wx-card ripple" id="meWxCard">
|
||
<!-- ⚠️ 这一版是**三段竖排**:角标行 / 图文行 / 通栏 CTA。
|
||
上一版是四段(角标 / 标题 / 图文 / CTA),本批按用户要求
|
||
「商品名放到到手价上边、跟到手价对齐」,把整个标题行搬进了右列
|
||
.wx-main —— 商品名和价格从此共用同一条左缘,这就是「对齐」的实现。
|
||
同时「每人领取一份放到商品名右边、左边整个位置留给图片」。
|
||
|
||
卡内净宽 = 320 − 页边 36 − 卡内边 36 = **248px**(下面所有账都对着它)
|
||
|
||
① 图文行:.wx-fig 76 + gap 12 → 右列 .wx-main = 248 − 76 − 12 = **160px**
|
||
|
||
② 标题行(住在 160px 的右列里;本批起两件**竖排**,各占一整行):
|
||
「可心柔婴儿纸巾」7 字 × 16 = 112 ≤ 160 ✓ 余 48px
|
||
「限领一份」 4 字 × 11.5 = 46 ≤ 160 ✓ 余 114px
|
||
⚠️ 上一版是横排:105 + gap 5 + 42 = 152 ≤ 160,**只余 8px**,
|
||
而且那 8px 是按 15px 字号死算的。微信有一个全局字体大小
|
||
滑块,用户一调大,105px 的商品名当场涨到 130+,余量瞬间
|
||
蒸发、ellipsis 真的触发 —— 商品名被啃成「可心柔婴儿纸…」。
|
||
**这就是用户本批报的那个 bug**(原话「把限领一份儿放到
|
||
可心柔婴儿纸巾的后边」,追问后确认他看到的是被切断的商品名)。
|
||
⚠️ 竖排把「两件抢同一条 160px」这个根子问题去掉了,不是把
|
||
临界点往后推。所以字号也一并回到 16 / 11.5,不再需要压字号。
|
||
**别为了省一行高度改回横排。**
|
||
|
||
③ 右列其余两行(都在 160px 里):
|
||
「到手价 ¥0」= 3×11.5 + gap 5 + ¥0 ≈ 26 → 65.5 ✓
|
||
副文「加小汤圆的孕育顾问领取」11 × 12.5 = 137.5 ✓ 一行;
|
||
小名满 12 字时 20 字 = 250 → 折两行,line-clamp:2 兜住
|
||
|
||
④ 高度账 —— 这就是「左边整个的位置都留给图片」:
|
||
.wx-main 高 = 19.5(head) + 5 + 26(price) + 5 + 18.1(sub 一行) ≈ 73.6
|
||
sub 折两行时 ≈ 91.8
|
||
所以 .wx-fig **不写死高度**,用 align-self:stretch + min-height:92 ——
|
||
图片永远填满左列整个高度:短文案时由 92 撑住卡高,
|
||
长小名把右列顶到 91.8 时也不会被超过。
|
||
|
||
⑤ CTA 通栏 248px。 -->
|
||
|
||
<!-- 角标行:只有一枚角标,右对齐 = 卡的右上角。
|
||
⚠️ 这一行**故意是空的**,只装角标。看着浪费了 18px 高,但角标并回
|
||
别处必然挤爆某一行,而挤爆的表现是商品名被省略号啃掉。
|
||
⚠️ 角标**仍然是正常流里的一枚标签**,绝不能改回 position:absolute
|
||
骑在卡边上:.wx-card 挂着 .ripple,overflow:hidden 会把它裁掉半截。
|
||
那正是用户早先说的「限量福利被切了」,已经犯过一次,别再犯。 -->
|
||
<span class="wx-top">
|
||
<!-- ⚠️ 文案「限量福利」是刻意避开「免费领」的:下面 CTA 已经写了
|
||
「立即免费领取」,角标再写一遍「免费领」是同一张卡里重复吆喝。 -->
|
||
<span class="wx-badge">限量福利</span>
|
||
</span>
|
||
|
||
<span class="wx-body">
|
||
<!-- 左边这块是**商品占位插画**(一包抽纸),不是最终图。
|
||
⚠️ 类名是 .wx-fig,**绝不能**叫 .wx-qr —— 那个类是弹窗里的
|
||
企业微信二维码,测试里有一条「全页只有一处二维码」的断言,
|
||
蹭上去会当场红。
|
||
⚠️ 「示例图 · 待替换」这行字画在 svg **内部**,换成真实商品图时
|
||
它跟着一起消失,不会留下一行孤零零的说明。
|
||
⚠️ svg 的 width/height 从写死的 88 改成了 100%:现在框是
|
||
76 宽 × 拉伸高,写死 88 会顶出去。换真图时也照此办理。
|
||
⚠️ 里面是**内联 svg**,object-fit 对它**不生效** —— 生效的是
|
||
preserveAspectRatio(默认 xMidYMid meet = contain)。
|
||
64×64 的方图放进 76×92 的框会上下各留 8px 空条,
|
||
露出卡的橙色渐变;.wx-fig 的 background:#FFF1E6 就是来堵这个的
|
||
(取的是下面那张 <rect> 自己的颜色,所以看不出接缝)。
|
||
别改成 slice(cover)—— 那会把抽纸盒裁掉头尾。 -->
|
||
<span class="wx-fig" aria-hidden="true">
|
||
<svg viewBox="0 0 64 64" width="100%" height="100%">
|
||
<rect x="2" y="2" width="60" height="60" rx="14" fill="#FFF1E6"/>
|
||
<!-- 抽纸软包 -->
|
||
<path d="M17 22h30v26a3 3 0 0 1-3 3H20a3 3 0 0 1-3-3V22z" fill="#fff" stroke="#E8A98C" stroke-width="1.6" stroke-linejoin="round"/>
|
||
<path d="M17 22c0-3.6 3-6.4 7-6.4h16c4 0 7 2.8 7 6.4" fill="#FFE1D2" stroke="#E8A98C" stroke-width="1.6" stroke-linejoin="round"/>
|
||
<!-- 抽出来的那一张 -->
|
||
<path d="M27.5 22c0-2.6 2-4.6 4.5-4.6s4.5 2 4.5 4.6" fill="none" stroke="#D85F38" stroke-width="1.8" stroke-linecap="round"/>
|
||
<path d="M23 33h18M23 39h13" stroke="#F2C7B3" stroke-width="1.8" stroke-linecap="round"/>
|
||
<text x="32" y="59.5" text-anchor="middle" font-size="6.4" fill="#B79C90">示例图 · 待替换</text>
|
||
</svg>
|
||
</span>
|
||
<span class="wx-main">
|
||
<!-- 标题行:商品名独占一行,「限领一份」排在它**下面**。
|
||
⚠️⚠️ 本批(第八批)把这两件从横排改成竖排,方向和上一批**相反**。
|
||
上一批是「限领在商品名右侧」,可右列只有 160px,两件抢同一条宽度,
|
||
当时那笔账只余 8px —— 于是商品名被省略号啃成「可心柔婴儿纸…」。
|
||
用户这次报的就是这个现象(原话「把限领一份儿放到可心柔婴儿纸巾的
|
||
后边」,问过之后确认他看到的是被切断的商品名)。
|
||
竖排之后标题独占整行 160px,7 字 × 16 = 112,宽度争抢从根上消失。
|
||
⚠️ 别为了「省一行高度」改回 flex-direction:row —— 那等于把这个
|
||
bug 原样装回来,而且它在短商品名下不复现,测不出来。
|
||
⚠️ .wx-head 仍必须是 .wx-main 的**第一件**、排在 .wx-price 前面 ——
|
||
用户早先的原话是「商品名放到到手价上边」,两批要求叠加在一起。
|
||
⚠️ 别把「限领一份」合回 .wx-title 凑成一个字符串:合成一个字符串
|
||
就只剩一个字号,「限领」不再是商品名底下那行灰色小字,
|
||
用户要的那个视觉层级整个没了。 -->
|
||
<span class="wx-head">
|
||
<span class="wx-title" id="meWxTitle">可心柔婴儿纸巾</span>
|
||
<!-- ⚠️ 文案「限领一份」和资源库 banner 的 .rlg-lim **必须逐字相同**
|
||
(用户早先要求两张卡「一模一样」,smoke 里有一条断言钉着)。
|
||
改这句就得同时改 .rlg-lim,只改一边会当场红。
|
||
⚠️ 「(每人限领一份)」砍成「限领一份」是**第七批**被 8px 余量逼的
|
||
(那时它和商品名横排、抢同一条 160px)。第八批改竖排之后
|
||
它独占整行,8 字 × 11.5 = 92 ≤ 160,其实又放得下了。
|
||
仍然保持 4 字,理由换成「用户没要求改字」+ 两张卡必须逐字相同。
|
||
别拿「现在放得下」当作可以随手改回长文案的依据。 -->
|
||
<span class="wx-lim">限领一份</span>
|
||
</span>
|
||
<!-- 价格行 —— 这一版「电商化」的主角。
|
||
⚠️ 这里**只写到手价,不写划掉的原价**。原价是编出来的数字,
|
||
而这是一个真实品牌的真实商品:划线价属于价格宣称,
|
||
编一个就成了虚假标价。「¥0」不是新承诺,它就是这张卡
|
||
从第一版起一直写着的「立即免费领取」换个说法 ——
|
||
同一件事用电商的排版语言再说一遍,没有多承诺任何东西。
|
||
⚠️ 「免费领」这个商务承诺本身仍未获确认(第四批提出,见 CHANGELOG
|
||
的「已知不做」)。要撤这个承诺的话,撤的是整张卡,不是这一行。 -->
|
||
<span class="wx-price"><i>到手价</i><b>¥0</b></span>
|
||
<!-- 静态兜底写「宝宝的」,不写「小汤圆」:用户还没填小名时,
|
||
屏幕上不该出现一个他从没输入过的名字。填了之后
|
||
syncBabyWords() 会把这里换掉。
|
||
⚠️ 小名的挂点在这一行,不在上面的标题里,也不在下面的 CTA 里。
|
||
改 syncBabyWords() 时别找错行。 -->
|
||
<span class="wx-sub" id="meWxSub">加宝宝的孕育顾问领取</span>
|
||
</span>
|
||
</span>
|
||
|
||
<!-- CTA 现在是**通栏**的(上一版只占右列 159px)。整卡 248px 的实心按钮
|
||
是电商卡的标准收尾,也是这张卡唯一的动作。
|
||
⚠️ 必须是 <span> 不能是 <button>:外层 .wx-card 本身就是
|
||
<button>,按钮套按钮是非法 HTML。 -->
|
||
<span class="wx-cta">立即免费领取</span>
|
||
</button>
|
||
</div>
|
||
|
||
<!-- 心选商城:改成一条横幅(原来是带大按钮的电商卡,和上面的兑换卡抢主角)。id/点击逻辑不变(goMall)。 -->
|
||
<button class="mall-strip ripple" id="meMallCard">
|
||
<span class="ms-ico" aria-hidden="true">
|
||
<svg viewBox="0 0 24 24" width="22" height="22"><path d="M5 8h14l-1.2 11a2 2 0 0 1-2 1.8H8.2a2 2 0 0 1-2-1.8z" fill="#fff" stroke="currentColor" stroke-width="1.7" stroke-linejoin="round"/><path d="M8.6 10V6.8a3.4 3.4 0 0 1 6.8 0V10" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/></svg>
|
||
</span>
|
||
<span class="ms-main"><b>兜爸心选商城</b><span>为宝宝甄选的母婴好物</span></span>
|
||
<span class="ms-go">逛一逛<i>›</i></span>
|
||
</button>
|
||
|
||
<h2 class="sec-title dark">常用服务</h2>
|
||
<!-- 设置与服务:列表改成四宫格。按钮的 id / data-open / data-set 全部沿用,JS 不用动。
|
||
#meBoxCard 2026-10-05 起一律隐藏(用户要求删掉孕期卡册入口,见 app.js renderBanner);#meBoxV 显示成右上角小角标。 -->
|
||
<div class="svc-grid">
|
||
<button class="svc ripple hide" id="meBoxCard"><span class="sv-ico o"><svg viewBox="0 0 24 24" width="22" height="22" aria-hidden="true"><rect x="4.5" y="10.5" width="15" height="9.5" rx="2" fill="none" stroke="currentColor" stroke-width="1.8"/><rect x="3.3" y="7.2" width="17.4" height="3.6" rx="1.3" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M12 7.2V20M12 7.2C10.4 3.8 7 4.3 8 6.4c.6 1 2.4.9 4 .8zM12 7.2c1.6-3.4 5-2.9 4-.8-.6 1-2.4.9-4 .8z" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round"/></svg></span><span class="sv-t">孕期卡册</span><span class="sv-badge" id="meBoxV"></span></button>
|
||
<button class="svc ripple" data-open="detailSetting" data-set="privacy"><span class="sv-ico p"><svg viewBox="0 0 24 24" width="22" height="22" aria-hidden="true"><rect x="4.5" y="10" width="15" height="10.5" rx="3" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M8.2 10V7.6a3.8 3.8 0 0 1 7.6 0V10" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/><circle cx="12" cy="15.2" r="1.5" fill="currentColor"/></svg></span><span class="sv-t">隐私权限</span></button>
|
||
<button class="svc ripple" data-open="detailSetting" data-set="help"><span class="sv-ico o"><svg viewBox="0 0 24 24" width="22" height="22" aria-hidden="true"><path d="M12 4.2c4.5 0 7.8 2.8 7.8 6.4s-3.3 6.4-7.8 6.4c-.7 0-1.3-.06-1.9-.18l-3.6 2.3a.4.4 0 0 1-.6-.45l.8-2.9c-1.5-1.16-2.3-2.7-2.3-4.4 0-3.6 3.1-6.4 7.6-6.4z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M9.9 9.4a2.2 2.2 0 0 1 4.2.8c0 1.5-2.1 1.6-2.1 3" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/></svg></span><span class="sv-t">帮助反馈</span></button>
|
||
<!-- 2026-10-04 意见反馈(用户:「我的页面里加一个客服反馈,功能上的反馈、功能上的建议」)→ #modalFeedback,提交到 box_app /api/mp/public/mama-box/feedback -->
|
||
<!-- 2026-10-05 用户:「『我的』里加一个兑换记录,就是商城兑换的记录」→ 跳兜豆兑换商城 ?page=orders(商城会话 cc4ca879 提供,直接弹「兑换记录」,× 回首页);
|
||
#meOrdersV 角标 = 待发货笔数(/api/dou/summary 的 orders_pending,0 不显示)。 -->
|
||
<button class="svc ripple" id="meExchOrders"><span class="sv-ico o"><svg viewBox="0 0 24 24" width="22" height="22" aria-hidden="true"><path d="M6.5 3.8h11a1.2 1.2 0 0 1 1.2 1.2v15.1l-2.3-1.5-2.2 1.5-2.2-1.5-2.2 1.5-2.2-1.5-2.3 1.5V5a1.2 1.2 0 0 1 1.2-1.2z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M8.6 8.6h6.8M8.6 12h6.8M8.6 15.4h4" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg></span><span class="sv-t">兑换记录</span><span class="sv-badge" id="meOrdersV"></span></button>
|
||
<button class="svc ripple" id="meFeedback"><span class="sv-ico g"><svg viewBox="0 0 24 24" width="22" height="22" aria-hidden="true"><path d="M5.5 4.8h13a1.7 1.7 0 0 1 1.7 1.7v8.6a1.7 1.7 0 0 1-1.7 1.7H11l-4.1 3a.4.4 0 0 1-.64-.32V16.8H5.5a1.7 1.7 0 0 1-1.7-1.7V6.5a1.7 1.7 0 0 1 1.7-1.7z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M8.2 9.3h7.6M8.2 12.5h4.8" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg></span><span class="sv-t">意见反馈</span></button>
|
||
<button class="svc ripple" data-open="detailSetting" data-set="about"><span class="sv-ico b"><svg viewBox="0 0 24 24" width="22" height="22" aria-hidden="true"><circle cx="12" cy="12" r="8.2" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M12 11v5.4" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"/><circle cx="12" cy="7.9" r="1.15" fill="currentColor"/></svg></span><span class="sv-t">关于我们</span></button>
|
||
</div>
|
||
<!-- 退出授权登录:仅已授权时显示(applyRemoteProfile 控制 style.display)。
|
||
调 box_app /auth/logout —— 只翻授权状态,不清昵称/头像/手机号等资料 -->
|
||
<button class="me-logout ripple" id="meLogoutCard" style="display:none">退出登录</button>
|
||
<p class="me-ver">兜爸心选 · v3.2.1</p>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
|
||
|
||
<!-- ================= 孕期小知识 · 这一周 详情页(2026-10-01)=================
|
||
首页 #pregTips 下面四个入口点进来:宝宝 / 妈妈 / 饮食 / 留心 四张卡竖排、全文不截断;
|
||
点哪个入口就滚到哪张并闪一下。内容由 renderTips() 写入 ptBaby/ptMom/ptEat/ptCare。 -->
|
||
<section class="detail" id="detailTips">
|
||
<div class="detail-bar">
|
||
<button class="dt-back" data-detail="close">‹</button>
|
||
<span class="dt-title" id="ptDtTitle">孕期小知识</span>
|
||
</div>
|
||
<div class="detail-body pt-page">
|
||
<!-- 本周每日小知识:第 1 天到今天,今天在最上面;以后的几天锁着(与首页 7 个圆点同一口径) -->
|
||
<h3 class="pt-sub">本周每日小知识</h3>
|
||
<div class="pt-list" id="ptList"></div>
|
||
<h3 class="pt-sub">这一周</h3>
|
||
<div class="pt-grid" id="ptGrid">
|
||
<div class="pt-card pc-baby" data-pt="baby"><span class="pt-ico" id="ptBabyIco" aria-hidden="true">👶</span><b>宝宝这周</b><p id="ptBaby"></p></div>
|
||
<div class="pt-card pc-mom" data-pt="mom"><span class="pt-ico" aria-hidden="true">🤰</span><b>妈妈身体</b><p id="ptMom"></p></div>
|
||
<div class="pt-card pc-eat" data-pt="eat"><span class="pt-ico" aria-hidden="true">🥗</span><b>吃点什么</b><p id="ptEat"></p></div>
|
||
<div class="pt-card pc-care" data-pt="care"><span class="pt-ico" aria-hidden="true">📋</span><b>这周留心</b><p id="ptCare"></p></div>
|
||
</div>
|
||
<p class="pt-foot">仅供参考,身体有任何不适请以医生意见为准</p>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ================= AI 小结 内容页 ================= -->
|
||
<section class="detail" id="detailAI">
|
||
<div class="detail-bar">
|
||
<button class="dt-back" data-detail="close">‹</button>
|
||
<span class="dt-title">AI 孕育小结</span>
|
||
<button class="dt-plain" data-toast="小结每天 21:00 自动生成">⋯</button>
|
||
</div>
|
||
<!-- 这一页原来是「大卡 + 三条 li + 一串行」,从上到下全是罗列,没有层次。
|
||
重做成三段式:今日卡(深色,一眼看完今天)→ 三张建议卡(分类色 + 一句标题
|
||
一句正文)→ 往期时间轴(左边一条线串起来)。每段之间用带序号的小标题隔开。 -->
|
||
<div class="detail-body ai-body">
|
||
<!-- ① 今日卡:整页唯一的深色块,越往下越浅,视线自然从这里开始 -->
|
||
<section class="ai-today">
|
||
<span class="ai-glow" aria-hidden="true"></span>
|
||
<span class="ai-glow b" aria-hidden="true"></span>
|
||
<div class="ai-t-top">
|
||
<span class="ai-week" id="aiWeek">孕24周+3</span>
|
||
<span class="ai-date" id="aiDate">9月3日 周二</span>
|
||
</div>
|
||
<!-- 一句话概括今天,字号最大;右上角那枚小圆点是「今日状态」 -->
|
||
<span class="ai-mood" id="aiMood">安心</span>
|
||
<!-- renderAI() 会用 AI_LOGS[0].txt 覆盖这句,这里写的是渲染前的兜底。
|
||
口吻同样是宝宝第一人称,别让它在渲染前闪一句第三人称的旧话 -->
|
||
<p class="ai-hero-txt" id="aiTxt">妈妈,今天你数到我动了 3 次。我今天精神特别好,这是踏实的一天。</p>
|
||
<div class="ai-stats" id="aiStats"></div>
|
||
</section>
|
||
|
||
<div class="ai-sec">
|
||
<span class="ai-sec-n">01</span>
|
||
<!-- 原来叫「今天想对你说」。这三张卡的内容是「固定这两个时段陪他待一会儿」
|
||
「按平时胃口来就行」这类可执行的动作,是建议不是抒情,标题得对上 -->
|
||
<h3>今日小建议</h3>
|
||
<i class="ai-sec-line"></i>
|
||
</div>
|
||
<div class="ai-tips" id="aiTips"></div>
|
||
|
||
<div class="ai-sec">
|
||
<span class="ai-sec-n">02</span>
|
||
<h3>往期小结</h3>
|
||
<i class="ai-sec-line"></i>
|
||
<button class="sec-more" data-toast="已加载全部 30 天小结">近 30 天 ›</button>
|
||
</div>
|
||
<div class="ai-logs" id="aiLogs"></div>
|
||
|
||
<p class="unlock">小结由 AI 依据你的记录生成,是陪你一起看记录的伙伴,不代替医生的判断。</p>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ================= 资源库 列表页 ================= -->
|
||
<section class="detail" id="detailResList">
|
||
<div class="detail-bar">
|
||
<button class="dt-back" data-detail="close">‹</button>
|
||
<span class="dt-title">孕育资源库</span>
|
||
<!-- 原来是 🔍 emoji(各系统渲染成实物放大镜),换成和档案页一致的扁平线性图标 -->
|
||
<button class="dt-plain" data-search="1" aria-label="搜索"><svg viewBox="0 0 24 24" width="20" height="20"><circle cx="11" cy="11" r="6.5" fill="none" stroke="currentColor" stroke-width="1.9"/><path d="M16 16l4.5 4.5" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"/></svg></button>
|
||
</div>
|
||
<div class="detail-body">
|
||
<!-- ================= 试用装福利 banner =================
|
||
排在最前面(在那句 rl-lead 之前):它是这一页最想被看见的东西。
|
||
⚠️ 和服务卡同样的理由,故意**不挂 data-open / data-modal**。
|
||
那条通用通道直接调 openModal,会绕过 openWx() —— 模式类名、
|
||
引导语、上次残留的红字和输入内容、还有 wxPending 都不会被重置。
|
||
⚠️ 里面这张示意图**绝不能带 .wx-qr 类**。冒烟测试有一条钉着
|
||
「全页只有一处二维码」,蹭了那个类名会当场变红 —— 而且它也确实
|
||
不是二维码。用独立的 .rlg-fig。
|
||
⚠️ 2026-09-19:兑换码闸门取消后不再有「已解锁」状态,所以这条 banner
|
||
**恒显示**(原来 syncUnlockCopy() 会按解锁态给它挂 .hide,已删除)。
|
||
换真图:把 .rlg-fig 整个 <svg> 换成一个 img,类名照旧写 rlg-fig,
|
||
CSS 一行不用动(.rlg-fig 同时管 svg 和 img)。
|
||
⚠️ 这里**不要**写出图片路径的字面量 —— build.js 的 ASSET_RE
|
||
连 HTML 注释一起扫,写了就当场报「缺少资源文件」。 -->
|
||
<button class="rl-gift ripple" id="rlGift">
|
||
<!-- ⚠️ 这条 banner 和「我的」页那张 .wx-card 是**同一件商品的同一张卡**,
|
||
所以这一版跟着改成同样的三段竖排:标题行 / 图文行 / 通栏 CTA。
|
||
用户上一批的原话是两处「一模一样」;只改一边,同一个商品在两个
|
||
页面上又会长成两个样子 —— 上一版商品名写岔(那边「可心柔试用装」、
|
||
这边「免费领可心柔试用装」)就是这么来的。
|
||
⚠️ 但**比例刻意比那边小一号**(图 68×60 不跟着放大到 88、字号各降一档)。
|
||
这不是偷懒:那边是「我的」页上的一张独立卡,四周是空的;
|
||
这条 banner 上面是标题栏、下面紧跟着 128 条资源列表,
|
||
照搬 88px 的图 + 22px 的价格会把整条撑到 200px 上下,
|
||
把真正的资源列表整个顶到首屏外 —— banner 抢了主内容的位置。
|
||
⚠️ 宽度账(320 屏):320 − 页边 44(.detail-body 左右各 22)
|
||
− 卡内边 28 = 248,和那边一样宽。
|
||
本批标题行改成**竖排**(跟 .wx-card 同步),所以「标题和限领抢
|
||
同一行」那笔账整个不存在了:
|
||
商品名独占一行:「可心柔婴儿纸巾」7 字 × 16 = 112 ≤ 248 ✓ 余 136px
|
||
「限领一份」另起一行:4 字 × 11.5 = 46 ✓
|
||
⚠️ 这边**本来就排得下**(上一版横排是 7×15 + gap 6 + 4×11.5 = 157
|
||
≤ 248,余 91px)。跟着改成竖排纯粹是为了两张卡保持同构 ——
|
||
真正被挤爆的是「我的」页那张:它的右列只有 160px。
|
||
所以别拿「这边明明放得下」当理由把这边改回横排,
|
||
那只会让同一件商品在两个页面上又长成两个样子。 -->
|
||
<span class="rlg-head">
|
||
<!-- 标题和「我的」页 #meWxTitle 保持**同一个字符串**「可心柔婴儿纸巾」。
|
||
测试里有一条拿同一个变量同时比对两处,写岔了会红。
|
||
⚠️ 和 .wx-title 一样:标题只放商品名,不许把括号那半句并进来。
|
||
.rlg-title 是 nowrap + ellipsis,并进来 16 字 ≈ 264px > 248,
|
||
会被省略号从「(」处齐根切掉,而 textContent 照样是全的。 -->
|
||
<span class="rlg-title">可心柔婴儿纸巾</span>
|
||
<!-- ⚠️ 「限领一份」只是文案,前端**不记状态**:真正的把关在顾问
|
||
那边人工做。前端记了也挡不住换设备/清缓存,不假装能管住。
|
||
别看到这行就以为漏了个 localStorage。
|
||
⚠️ 「(每人限领一份)」砍成「限领一份」是**第七批**的事,
|
||
**这边一直排得下** —— 砍它纯粹是为了和「我的」页 .wx-lim
|
||
保持逐字相同(用户早先要求两张卡「一模一样」,smoke 有断言钉着)。
|
||
当时被宽度逼的是那边:标题行横排、右列 160px、余量只剩 8px。
|
||
⚠️ 第八批那边也改成竖排了,8px 那笔账已经不存在,两边**都**放得下。
|
||
仍保持 4 字是因为用户没要求改字,不是因为放不下。
|
||
这两句必须**一起改**,只改一边会当场红。 -->
|
||
<span class="rlg-lim">限领一份</span>
|
||
</span>
|
||
<span class="rlg-body">
|
||
<!-- 「示例图 · 待替换」这几个字写在 svg **内部**:换成真图时它跟着
|
||
一起消失,不会剩一句「待替换」孤零零挂在真图旁边。 -->
|
||
<svg class="rlg-fig" viewBox="0 0 68 60" role="img" aria-label="示例图,待替换为可心柔婴儿纸巾实物图">
|
||
<rect x="6" y="14" width="56" height="34" rx="6" fill="#FFD9C6"/>
|
||
<rect x="6" y="14" width="56" height="12" rx="6" fill="#FFC3A8"/>
|
||
<path d="M20 26c0-5 4-9 9-9h10c5 0 9 4 9 9" fill="none" stroke="#E8724C" stroke-width="2.4"/>
|
||
<path d="M26 33h16M26 39h11" stroke="#E8724C" stroke-width="2.4" stroke-linecap="round"/>
|
||
<text x="34" y="57" text-anchor="middle" font-size="7" fill="#B0907F">示例图 · 待替换</text>
|
||
</svg>
|
||
<span class="rlg-main">
|
||
<!-- ⚠️ 角标从卡外边缘(position:absolute;top:-7px)挪进了右列顶部。
|
||
原因和「我的」页那张卡一样:.rl-gift 挂着 .ripple,
|
||
.ripple 的 overflow:hidden 把负偏移的角标裁掉一半,
|
||
「福利」两个字只露下半截。这是本项目里**最早**的那处裁切。
|
||
别改回绝对定位。 -->
|
||
<span class="rlg-badge">福利</span>
|
||
<!-- 价格行,和「我的」页 .wx-price 同一件事、同样只写到手价。
|
||
⚠️ 一样**不编划线价**:可心柔是真实品牌,划线价属于价格宣称。
|
||
「¥0」只是把这张卡一直写着的「立即免费领取」换个说法。 -->
|
||
<span class="rlg-price"><i>到手价</i><b>¥0</b></span>
|
||
<!-- ⚠️ 这行原来是写死的静态文本,没有小名。用户要求两处「一模一样」,
|
||
所以给了 id 并纳入 syncBabyWords() 一起刷 —— 否则改完小名,
|
||
「我的」页说「加小汤圆的孕育顾问领取」、这里说「加顾问领取」,
|
||
同一句话又变成两个说法。静态兜底同样写「宝宝的」。 -->
|
||
<span class="rlg-sub" id="rlgSub">加宝宝的孕育顾问领取</span>
|
||
</span>
|
||
</span>
|
||
<!-- 实心 CTA,现在是 .rl-gift 的直接子元素、通栏 248px
|
||
(上一版收在右列里只有 170px)。
|
||
原来这里只有一个 .rlg-chev「›」,尖括号在这一页的语义是
|
||
「还有下一层可以翻」,而这条 banner 是要人**领东西**。
|
||
⚠️ 「›」已删除:一张卡上同时摆按钮和尖括号 = 两个「点我」信号打架。
|
||
⚠️ 必须是 <span>:外层 .rl-gift 本身是 <button>,按钮套按钮非法。 -->
|
||
<span class="rlg-cta">立即免费领取</span>
|
||
</button>
|
||
<!-- 静态文案(原「还没解锁 / 已解锁」两版已随闸门一起取消)。
|
||
「首次领取需添加顾问微信」这句必须提前说:让人一路读到底、点了
|
||
「立即领取」才撞上二维码,是把条件藏到最后一步才亮出来。 -->
|
||
<p class="rl-lead"><b>128</b> 份资源按孕周持续更新 · 首次领取需添加顾问微信</p>
|
||
<div class="chips-row" id="resChips">
|
||
<button class="chip is-active" data-rescat="all">全部</button>
|
||
<button class="chip" data-rescat="产检">产检</button>
|
||
<button class="chip" data-rescat="营养">营养</button>
|
||
<button class="chip" data-rescat="胎教">胎教</button>
|
||
<button class="chip" data-rescat="运动">运动</button>
|
||
<button class="chip" data-rescat="心理">心理</button>
|
||
<!-- 收藏不是分类而是筛选,所以默认排在最后。但一旦用户有了收藏,
|
||
renderResList() 会把它挪到「全部」后面并带上数量 —— 常用的东西
|
||
不该让人横向滑到头才找得着。这里写的是「还没收藏过」时的样子。
|
||
⚠️ 原来的「✓ 已领」chip 已删除:9.19 需求取消了「立即领取即到手」
|
||
这个动作(资料由顾问在微信里发),H5 侧没有「已领」这个概念了。 -->
|
||
<button class="chip chip-fav" data-rescat="fav">★ 收藏</button>
|
||
</div>
|
||
<div class="res-list" id="resList"></div>
|
||
<p class="unlock" id="resEmptyHint"></p>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ================= 资源 内容页 ================= -->
|
||
<section class="detail" id="detailRes">
|
||
<div class="detail-bar">
|
||
<button class="dt-back" data-detail="close">‹</button>
|
||
<span class="dt-title">资源详情</span>
|
||
<button class="dt-star" id="resStar">☆</button>
|
||
</div>
|
||
<div class="detail-body">
|
||
<div class="rd-cover" id="rdCover"><img id="rdImg" src="assets/img/9f3fa8edf4aa.png" alt=""></div>
|
||
<span class="rd-cat" id="rdCat">产检</span>
|
||
<h1 class="rd-title" id="rdTitle">《糖耐检查全攻略》</h1>
|
||
<p class="rd-desc" id="rdDesc">孕24-28周必看 · 附检查前饮食清单</p>
|
||
<div class="rd-meta" id="rdMeta"></div>
|
||
<div class="rd-body" id="rdBody"></div>
|
||
<h3 class="d-sec">相关推荐</h3>
|
||
<div class="res-list slim" id="rdMore"></div>
|
||
</div>
|
||
<!-- 其他资源 / 立即领取吸底浮动:移出 .detail-body,怎么滑都跟着。
|
||
左边这颗原来是「★ 收藏」,和右上角星星功能完全重复(它就是转发点击给星星)。
|
||
收藏保留在星星上,这个位置让给「去看看别的」这个真正缺的出口。
|
||
文案用「其他资源」而不是「资源库」:用户此刻就在一份资源里,
|
||
「其他」说的是和手上这份的关系,比页面名更能说清点下去会看到什么。 -->
|
||
<div class="rd-cta" id="rdCta">
|
||
<button class="dl-btn ghost" id="rdLib">其他资源</button>
|
||
<button class="dl-btn main" id="rdGet">立即领取</button>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ================= 档案图片 预览页 =================
|
||
周档案 / 完整档案共用这一个壳。图是进来时用 canvas 现画的,
|
||
画完顺手存成 data URI —— 「保存图片」直接下载它,
|
||
「分享朋友圈」把它交给系统分享面板(不支持就提示长按图片),
|
||
「打印」走 window.print(),样式表里 @media print 只留这张图。 -->
|
||
<section class="detail" id="detailPoster">
|
||
<div class="detail-bar">
|
||
<button class="dt-back" data-detail="close">‹</button>
|
||
<span class="dt-title" id="pstBar">本周档案</span>
|
||
</div>
|
||
<div class="detail-body">
|
||
<!-- 抬头卡:图标 + 档案名 + 一句说明,比孤零零一行灰字有分量 -->
|
||
<div class="pst-hero">
|
||
<span class="pst-ico" aria-hidden="true">
|
||
<svg viewBox="0 0 24 24" width="24" height="24">
|
||
<path d="M7 3.5h7.5L19 8v12.5H7z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/>
|
||
<path d="M14 3.5V8h5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/>
|
||
<path d="M10 12h6M10 15.5h6M10 19h3.5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/>
|
||
</svg>
|
||
</span>
|
||
<div class="pst-h-txt">
|
||
<h2 class="pst-h-title" id="pstName">本周档案</h2>
|
||
<p class="pst-lead" id="pstLead">这一周的记录已经排好版了。</p>
|
||
</div>
|
||
</div>
|
||
<!-- 这张图里都装了什么,用几粒胶囊先交代清楚 -->
|
||
<div class="pst-chips" id="pstChips"></div>
|
||
<!-- 由 JS 往里塞 N 个 .pst-frame(白卡纸 + 一道虚线裁切位,像待打印的样张)。
|
||
本周档案是一张长图,完整档案是一页一张 A4 —— 屏幕上就按纸的样子一张张往下排。
|
||
画布都按 2 倍图给(750 宽),按 375 显示在手机上不糊。 -->
|
||
<div class="pst-pages" id="pstPages"></div>
|
||
<p class="pst-tip" id="pstTip">图片已生成。在微信里也可以长按上面这张图,直接保存或转发。</p>
|
||
</div>
|
||
<div class="rd-cta pst-cta" id="pstCta">
|
||
<!-- data-export 是委托用的:这三颗按钮不逐个绑监听,统一走 app.js 的
|
||
$$('[data-export]') 委托 → exportAct。id 还留着,
|
||
renderPoster() 要按「本周/完整」换这两颗的主次样式。 -->
|
||
<button class="dl-btn ghost" id="pstPrint" data-export="print">打印</button>
|
||
<button class="dl-btn ghost" id="pstSave" data-export="save">保存图片</button>
|
||
<button class="dl-btn main" id="pstShare" data-export="share">分享朋友圈</button>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ================= 设置与服务 二级页 =================
|
||
隐私与权限 / 帮助与反馈 / 关于兜爸心选 三项共用这一个壳,
|
||
内容由 js 里的 SETTINGS 表渲染进 #stBody,避免写四份几乎一样的结构 -->
|
||
<section class="detail" id="detailSetting">
|
||
<div class="detail-bar">
|
||
<button class="dt-back" data-detail="close">‹</button>
|
||
<span class="dt-title" id="stTitle">隐私与权限</span>
|
||
<button class="dt-plain" id="stMore" aria-label="更多">⋯</button>
|
||
</div>
|
||
<div class="detail-body">
|
||
<div id="stHero"></div>
|
||
<p class="st-lead" id="stLead"></p>
|
||
<div id="stBody"></div>
|
||
<p class="unlock" id="stFoot"></p>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ================= 孕期盲盒(2026-10-01,需求文档 v1.0 第三节) =================
|
||
上半是「开盒舞台」,下半是卡册(按孕早/中/晚期分三组)+ 规则与概率说明(合规:公示每档概率)。
|
||
.bx-reveal 是开盒后的翻卡层,盖在本页之上。全部渲染在 app.js 的 blindBox 段。 -->
|
||
<section class="detail bx" id="detailBox">
|
||
<div class="detail-bar">
|
||
<button class="dt-back" data-detail="close">‹</button>
|
||
<span class="dt-title">孕期盲盒</span>
|
||
<button class="dt-plain bx-rule-btn" id="bxRuleBtn" type="button">规则</button>
|
||
</div>
|
||
<div class="detail-body bx-body">
|
||
<div class="bx-stage" id="bxStage">
|
||
<span class="bx-rays" aria-hidden="true"></span>
|
||
<span class="bx-sp s1" aria-hidden="true">✦</span><span class="bx-sp s2" aria-hidden="true">✦</span><span class="bx-sp s3" aria-hidden="true">✦</span><span class="bx-sp s4" aria-hidden="true">✦</span>
|
||
<div class="bx-week" id="bxWeek"></div>
|
||
<div class="bx-hint" id="bxHint"></div>
|
||
<button class="bx-box" id="bxBox" type="button" aria-label="开启盲盒"></button>
|
||
<button class="bx-mini hide" id="bxMini" type="button" aria-label="查看这张宝宝卡"></button>
|
||
<span class="bx-shadow" aria-hidden="true"></span>
|
||
<button class="bx-open" id="bxOpen" type="button"></button>
|
||
<div class="bx-misc" id="bxMisc"></div>
|
||
</div>
|
||
<!-- 下周预告:下一孕周卡片的剪影 + 倒计时(营造等待感)。本周已开、且还没到 40 周时显示 -->
|
||
<div class="bx-next hide" id="bxNext">
|
||
<div class="bx-next-img" id="bxNextImg" aria-hidden="true"></div>
|
||
<div class="bx-next-t"><b id="bxNextW"></b><span id="bxNextS"></span></div>
|
||
<div class="bx-next-cd"><b id="bxNextD"></b><span>天后开启</span></div>
|
||
</div>
|
||
<!-- 待解锁(2026-10-01 价值感改造):参与之后漏开的周不再白送,完成一个孕期工具任务解锁一周。
|
||
任务是否完成由服务端查数胎动每日足迹核验(GET /blindbox 的 tasks),解锁 POST /blindbox/unlock -->
|
||
<div class="bx-lock hide" id="bxLock">
|
||
<div class="bx-lock-h"><span class="bx-lock-ico" aria-hidden="true">🔒</span>
|
||
<div><b>错过的 <em id="bxLockN"></em> 周待解锁</b><p>用一次孕期小工具,就能解锁一周补开</p></div></div>
|
||
<div class="bx-chips" id="bxLockChips"></div>
|
||
<div class="bx-tasks" id="bxTasks"></div>
|
||
</div>
|
||
<div class="bx-pend hide" id="bxPend">
|
||
<div class="bx-pend-t">还有 <b id="bxPendN"></b> 个盲盒等你打开 <em>错过的周会一直保留到孕 40 周</em></div>
|
||
<div class="bx-chips" id="bxChips"></div>
|
||
</div>
|
||
<section class="bx-album">
|
||
<div class="bx-ah">
|
||
<h3>我的宝宝卡册</h3>
|
||
<span class="bx-cnt"><b id="bxGot">0</b>/<span id="bxAll">37</span></span>
|
||
</div>
|
||
<div class="bx-prog"><i id="bxBar"></i></div>
|
||
<!-- 分段集齐奖励:孕早/中/晚期各一段 + 37 张全集。达成即记账,兜豆系统上线前由工作人员人工发放 -->
|
||
<div class="bx-goal" id="bxGoal"></div>
|
||
<p class="bx-anote" id="bxAnote"></p>
|
||
<div id="bxGroups"></div>
|
||
</section>
|
||
<details class="bx-rules" id="bxRules">
|
||
<summary>规则与概率说明</summary>
|
||
<div class="bx-rules-b" id="bxRulesBody"></div>
|
||
</details>
|
||
</div>
|
||
<div class="bx-reveal" id="bxReveal" aria-hidden="true">
|
||
<span class="bx-glow" aria-hidden="true"></span>
|
||
<span class="bx-flash" aria-hidden="true"></span>
|
||
<div class="bx-confetti" id="bxConfetti" aria-hidden="true"></div>
|
||
<div class="bx-rv-in">
|
||
<div class="bx-tag" id="bxTag"></div>
|
||
<div class="bx-persp">
|
||
<div class="bx-card3d" id="bxCard3d">
|
||
<div class="bx-face bx-back" id="bxBack"></div>
|
||
<div class="bx-face bx-front" id="bxFront"></div>
|
||
</div>
|
||
</div>
|
||
<p class="bx-dev" id="bxDev"></p>
|
||
<div class="bx-diary" id="bxDiary"></div>
|
||
<div class="bx-reward" id="bxReward"></div>
|
||
<button class="bx-keep" id="bxKeep" type="button"></button>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ================= 记一下 底部弹层 ================= -->
|
||
<div class="scrim" id="scrim"></div>
|
||
<section class="sheet" id="sheet">
|
||
<div class="sheet-grip" id="sheetGrip"><span></span></div>
|
||
<div class="sheet-head">
|
||
<div>
|
||
<h2>记一下</h2>
|
||
<p class="sk-sub" id="skSub"></p>
|
||
<!-- ⚠️ 临时隐藏(2026-09-22):「今天已记 N 条」依赖记录/统计功能,尚未实现 -->
|
||
<p class="tbd-hide"><span id="noteWhen">—</span> · 今天已记 <b id="todayCount">4</b> 条</p>
|
||
</div>
|
||
<button class="sheet-close" data-sheet="close" aria-label="关闭"><svg viewBox="0 0 16 16" width="12" height="12" aria-hidden="true"><path d="M3.5 3.5l9 9M12.5 3.5l-9 9" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg></button>
|
||
</div>
|
||
<div class="sheet-scroll">
|
||
<!-- ⚠️ 临时隐藏整块(2026-09-22):「今天已使用」快捷区 + 下方 .quick-row 的功能还没实现
|
||
(数据是写死的演示值 58.2kg / 待记录)。
|
||
**只挂 .tbd-hide,不要删 DOM**:JS 里 $('#quickKick') 没有判空,
|
||
还有 #kickCount / #todayCount / #noteWhen 会被回填,删掉会直接抛错。
|
||
恢复:去掉这三处 .tbd-hide 即可(含 <p> 那处),dedupeApps 会自动重新生效。 -->
|
||
<div class="apps-head first tbd-hide">今天已使用 <button class="sec-more" data-toast="点一下可直接补记">点一下直接记录 ›</button></div>
|
||
<div class="quick-row tbd-hide">
|
||
<button class="quick q1 ripple" id="quickKick"><img class="q-ico" src="assets/img/df905dcf3a1c.png" alt="" aria-hidden="true"><span class="q-t">数胎动</span><span class="q-v">+<b id="kickCount">1</b> 次</span></button>
|
||
<button class="quick q2 ripple" data-toast="已记录体重 58.2kg"><img class="q-ico" src="assets/img/a9e3b27a4a23.png" alt="" aria-hidden="true"><span class="q-t">孕期体重</span><span class="q-v">58.2kg</span></button>
|
||
<button class="quick q3 ripple" data-toast="开始测量胎心……"><img class="q-ico" src="assets/img/30de43bbc9aa.png" alt="" aria-hidden="true"><span class="q-t">胎心记录</span><span class="q-v">待记录</span></button>
|
||
<!-- 「今日心情」已按需求删除:记一下里只放工具,不放心情打卡。
|
||
删掉后 .quick-row 由 4 列改成 3 列,见 style.css -->
|
||
</div>
|
||
|
||
<!-- 2026-10-02 用户:「记一下弹窗有点单薄」→ 工具宫格上面加两层,数据都来自今日脚印接口(_fpData),不编数据:
|
||
① 今天卡:日期 + 孕周 + 一圈「今天记了几项」进度环 + 已记的工具小胶囊;
|
||
② 「先记这件」:今天还没用的前 2 个工具,配一句该做的事(todoLine),大卡可点。
|
||
接口没回来 / 访客 → 这两块保持隐藏,只剩副标题 + 宫格(和原来一样)。 -->
|
||
<!-- 2026-10-02 二改:用户要求弹窗别超过半屏 → 「今天卡」和「先记这件」合成一条:进度环 + 今天记了几项 + 下一件该做的事(去记),
|
||
已记的工具改成宫格图标上的小勾。整个弹窗 max-height 50%,工具多了宫格内部滚动。 -->
|
||
<div class="sk-today hide" id="skToday">
|
||
<div class="sk-ring" id="skRing" aria-hidden="true"><svg viewBox="0 0 44 44"><circle cx="22" cy="22" r="18"/><circle class="sk-arc" id="skArc" cx="22" cy="22" r="18"/></svg><b id="skNum">0</b></div>
|
||
<div class="sk-tt"><b id="skLine"></b><span id="skDone"></span></div>
|
||
<button class="sk-go hide" id="skGo" type="button">去记</button>
|
||
</div>
|
||
<div class="apps-head for-all tbd-hide">全部孕期工具 <button class="sec-more" data-toast="共 16 个孕期工具">共 16 个 ›</button></div>
|
||
<div class="apps-grid" id="appsGrid">
|
||
<button class="app ripple"><img class="a-ico" src="assets/img/505ace532176.png" alt="" aria-hidden="true">数胎动</button>
|
||
<button class="app ripple"><img class="a-ico" src="assets/img/8b0f0a53938b.png" alt="" aria-hidden="true">孕期体重</button>
|
||
<button class="app ripple"><img class="a-ico" src="assets/img/9a2e7fa472dc.png" alt="" aria-hidden="true">孕检日历</button>
|
||
<!-- ⚠️ 下面这十几枚是**接口数据到达前的静态占位**:loadPublishedApps() 拉到
|
||
/api/mp/apps 后会用 renderAppGrid() 整个 innerHTML 覆盖。所以这里改不改
|
||
只影响首帧闪现;本批把「生长曲线」同步改成「数宫缩」,与首页卡口径一致。 -->
|
||
<button class="app ripple"><img class="a-ico" src="assets/img/f989a64fe960.png" alt="" aria-hidden="true">数宫缩</button>
|
||
<button class="app ripple"><img class="a-ico" src="assets/img/fd875eb78785.png" alt="" aria-hidden="true">胎心记录</button>
|
||
<button class="app ripple"><img class="a-ico" src="assets/img/97c33531806b.png" alt="" aria-hidden="true">孕肚照</button>
|
||
<button class="app ripple"><img class="a-ico" src="assets/img/de0bc9e250f2.png" alt="" aria-hidden="true">B超影像</button>
|
||
<button class="app ripple"><img class="a-ico" src="assets/img/b855b45df1f3.png" alt="" aria-hidden="true">产检报告</button>
|
||
<button class="app ripple"><img class="a-ico" src="assets/img/c2ae6e98283b.png" alt="" aria-hidden="true">血压血糖</button>
|
||
<button class="app ripple"><img class="a-ico" src="assets/img/4657f50f42c8.png" alt="" aria-hidden="true">用药记录</button>
|
||
<button class="app ripple"><img class="a-ico" src="assets/img/72910df66ee3.png" alt="" aria-hidden="true">运动记录</button>
|
||
<button class="app ripple"><img class="a-ico" src="assets/img/dd5639fde61d.png" alt="" aria-hidden="true">饮食记录</button>
|
||
<button class="app ripple"><img class="a-ico" src="assets/img/f0d5e062f11a.png" alt="" aria-hidden="true">睡眠记录</button>
|
||
<button class="app ripple"><img class="a-ico" src="assets/img/056212807d86.png" alt="" aria-hidden="true">胎教音乐</button>
|
||
<button class="app ripple"><img class="a-ico" src="assets/img/7b7d81e02f42.png" alt="" aria-hidden="true">妈妈手记</button>
|
||
<button class="app ripple"><img class="a-ico" src="assets/img/f34fb7fdeea5.png" alt="" aria-hidden="true">更多工具</button>
|
||
</div>
|
||
</div>
|
||
|
||
</section>
|
||
|
||
<!-- ================= 搜索层 ================= -->
|
||
<section class="search-layer" id="searchLayer">
|
||
<div class="sl-bar">
|
||
<!-- ⚠️ 占位符里列的是可搜的东西。来信已整块移出本站(第三方 H5),
|
||
别再把它写回这句 —— 搜索框不该教用户搜一个界面上不存在的东西。
|
||
⚠️ 这句是 placeholder **属性**,不是文字节点 —— 只扫 textContent 的检查
|
||
抓不到它,改口时别忘了它。 -->
|
||
<div class="sl-input"><span>🔍</span><input id="searchInput" placeholder="搜索档案、记录……"></div>
|
||
<button class="sl-cancel" data-search="close">取消</button>
|
||
</div>
|
||
<div class="sl-body">
|
||
<div class="sl-sec">最近搜索</div>
|
||
<div class="chips-row wrap">
|
||
<button class="chip">第一次胎动</button><button class="chip">大排畸</button><button class="chip">体重</button><button class="chip">胎心</button>
|
||
</div>
|
||
<div class="sl-sec">大家都在搜</div>
|
||
<div class="sl-hot">
|
||
<button class="hot"><i>1</i>糖耐检查怎么准备</button>
|
||
<button class="hot"><i>2</i>孕<span data-wk="n">—</span>周胎动多少正常</button>
|
||
<button class="hot"><i>3</i>孕中期体重增长标准</button>
|
||
<button class="hot"><i>4</i>数胎动的正确方法</button>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
|
||
|
||
<!-- ================= 通用弹窗(往期小结 / 企业微信 / 我的资料) ================= -->
|
||
<div class="modal-scrim" id="modalScrim"></div>
|
||
|
||
<!-- ================= 往期小结 =================
|
||
原来点往期列表是把 AI 小结页顶上的今日卡整个换掉,看完想回到「今天」没有出口。
|
||
改成在原页上浮一层:内容只读,看完点底下的叉就走。
|
||
叉放在最下面而不是右上角 —— 这一屏是一路往下读完的,
|
||
读完手指就停在底部,再让人抬回右上角去关不合理。 -->
|
||
<section class="modal" id="modalAiLog" role="dialog" aria-modal="true" aria-labelledby="alogTitle">
|
||
<div class="alog-head">
|
||
<span class="alog-week" id="alogWeek">孕24周+2</span>
|
||
<span class="alog-mood" id="alogMood">安心</span>
|
||
</div>
|
||
<h3 class="alog-date" id="alogTitle">9月2日 周一</h3>
|
||
<p class="alog-txt" id="alogTxt"></p>
|
||
<!-- 只留这组数(胎动 / 体重 / 睡眠)—— 这是当天从小程序里真取到的记录。
|
||
下面本来还跟着一组 1/2/3 的建议卡(.alog-tips),删了:
|
||
那是 AI 当天现写的话,隔了几天再翻出来看已经没有用了,
|
||
而且它和上面那句 alogTxt 说的是同一件事,等于把结论又铺开讲三遍。
|
||
往期该回答的只有一个问题——那天的数是多少。建议留在「今日小建议」里。 -->
|
||
<div class="ai-stats alog-stats" id="alogStats"></div>
|
||
<button class="modal-x modal-x-btm" data-modal="close" aria-label="关闭">
|
||
<svg viewBox="0 0 24 24" width="16" height="16" aria-hidden="true">
|
||
<path d="M6 6l12 12M18 6L6 18" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"/>
|
||
</svg>
|
||
</button>
|
||
</section>
|
||
|
||
<!-- ================= 百度网盘领取(已下线) =================
|
||
⚠️ 2026-09-19(9.19 需求 1.2 + 需求方确认):资料改由企业微信顾问**直接发放**,
|
||
H5 不再发网盘链接和提取码 —— 原来这个 #modalPan 弹窗、js 里的 PAN/PAN_DEFAULT
|
||
链接表、givePan()、「已领」标记已整块删除。要恢复「H5 自己发链接」,
|
||
得先回问需求方(那等于把「解锁」概念加回来)。
|
||
⚠️ 后端 /api/mp/public/mama-box/config 里的 pan / panDefault / wxCode 三个字段
|
||
也随之失效(box_app 侧后续清理)。 -->
|
||
|
||
<!-- ================= 加企业微信顾问 =================
|
||
⚠️ 2026-09-19(9.19 需求 1.1 / 1.2):这个弹窗从「兑换码闸门」简化成**纯提示**。
|
||
改动前后:
|
||
· 删掉兑换码输入框 + 「以后再说」「解锁全部资料」两颗按钮(需求 1.2);
|
||
· 原来的 is-gate / is-gift / is-done 三模式**合并成单态** —— 不再有「解锁」
|
||
这个状态,弹窗只负责把人引导到顾问那儿,资料由顾问在微信里直接发(需求方确认);
|
||
· 二维码下方文案改成需求指定的「请添加资料小助手,回复『领资料』」(需求 1.1)。
|
||
三个入口(资料详情「立即领取」、「我的」页服务卡、资源库试用装 banner)
|
||
共用这一个壳、同一句话,openWx() 不再按入口改写文案。
|
||
⚠️ data-autofocus="off":这个弹窗的主角是中间那张二维码,用户第一件事
|
||
是举起另一台手机去扫它。默认的自动聚焦会把输入法键盘顶起来,
|
||
正好盖住二维码下半截 —— 人得先把键盘收掉才能扫。
|
||
⚠️ 弹窗**没有底部按钮**:唯一出口是右上角 .modal-x(外加遮罩 / Esc)。
|
||
别把「优化掉没有按钮的头部」这种想法落到这颗叉上 —— 那会把人关在弹窗里。 -->
|
||
<section class="modal wx-modal" id="modalWx" data-autofocus="off"
|
||
role="dialog" aria-modal="true" aria-labelledby="wxTitle">
|
||
<div class="modal-head">
|
||
<!-- 兜底写「宝宝的」;填过小名的由 syncBabyWords() 刷成小名。
|
||
⚠️ 这行藏在弹窗里,改完小名不点开就看不见 —— 属于肉眼巡查
|
||
永远扫不到的挂点,只能靠 smoke 里那条断言守着。 -->
|
||
<h3 id="wxTitle">宝宝的孕育顾问</h3>
|
||
<button class="modal-x" data-modal="close" aria-label="关闭">
|
||
<svg viewBox="0 0 24 24" width="15" height="15" aria-hidden="true">
|
||
<path d="M6 6l12 12M18 6L6 18" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"/>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
<!-- 单态文案:说清「加顾问 → 说一句领资料 → 她直接发」,不要求用户填任何东西。
|
||
⚠️ 称呼是「顾问」(与标题一致);二维码下方那句按需求原文写「资料小助手」。
|
||
这一处不一致是需求方明确保留的(见改动清单 D3),别顺手「统一」。 -->
|
||
<p class="modal-lead" id="wxLead">扫码添加顾问,说一句「领资料」,她会把资料直接发给你。</p>
|
||
<div class="wx-qr-box">
|
||
<!-- 真实企业微信顾问二维码(2026-09-22 换上,替换掉原来的占位 svg)。
|
||
文件 assets/img/4834fe8d686a.png ,396×396 PNG,
|
||
md5 = 4834fe8d686a6ca129c8e51e87fe62f8(**前 12 位就是文件名**)。
|
||
|
||
⚠️ 换码时的几条规矩:
|
||
① 文件名取**文件内容 md5 的前 12 位**(md5sum 新图 | cut -c1-12)。
|
||
该目录下 35 张图全按这个规则,别起描述性名字 —— 内容一变 URL 就变,
|
||
天然不会被上一版二维码的缓存顶住。
|
||
② 只动下面这一行。.wx-qr 挂在元素本身、svg 与 img 通吃(见 mama-box.css),
|
||
CSS 一个字都不用改:168×168、14px 圆角都是现成的。
|
||
14px 圆角只吃掉四角极角的**白色静默区**(本图静默区 13/396 → 显示约 5.5px,
|
||
对角裁切 4.1px < 到黑色模块的 7.8px),切不到码点,不影响扫码。
|
||
③ 注释里除了上面那条**真实存在**的路径,别再写别的图片路径字面量 ——
|
||
构建脚本连 HTML 注释一起扫,写了不存在的就报「缺少资源文件」。 -->
|
||
<img class="wx-qr" src="assets/img/4834fe8d686a.png" alt="企业微信顾问二维码">
|
||
<!-- 需求 1.1 指定的文案,逐字照抄(直角引号沿用站内习惯) -->
|
||
<p class="wx-qr-cap">请添加资料小助手,回复「领资料」</p>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ================= 我的资料(妈妈 + 宝宝,可换头像) =================
|
||
⚠️ 这里原来有**两个**弹窗:这张「我的资料」(头像 / 昵称 / 一句话签名)
|
||
和它上面一张 #modalPreg「编辑孕期信息」(小名 / 性别 / 预产期 / 孕周)。
|
||
本批按用户要求「我的资料里加上宝宝小名、性别、预产期」,
|
||
做法是把 #modalPreg **整个并进来**,而不是把三个字段抄一份过来。
|
||
|
||
为什么不抄一份:抄完这三个字段就有两套输入框写同一份 state。
|
||
两套控件迟早会漂 —— 一边加了校验另一边没加、一边保存后调了
|
||
syncPregnancy() 另一边忘了调,而且这种不一致在两个弹窗**分别**
|
||
打开时都看不出来,只有用户在 A 改完去 B 看才暴露。
|
||
合并之后 pgName/pgSex/pgDue/pgWeek/pgDay 这五个 id 一个没改,
|
||
原来挂在它们身上的联动(改预产期→算孕周、改孕周→反推预产期)
|
||
原样继续生效,只是保存按钮从 #pgSave 并进了 #pfSave。
|
||
|
||
⚠️ 「孕期信息」那一节的「编辑 ›」和整张孕期卡现在都指向这个弹窗
|
||
(data-modal 从 modalPreg 改成了 modalProfile),别再找 modalPreg 了。
|
||
|
||
⚠️ 高度预算(.modal 是 max-height:92% + overflow-y:auto,撑爆不会破版、
|
||
只会要用户滚一下才够得着「保存」,但那已经算体验问题了):
|
||
22 内边 + 30 头 + 头像块 121 + 昵称/小名同行 78 + 性别 77
|
||
+ 预产期 78 + 孕周行 78 + 提示 43 + 底部按钮 68 + 20 内边 ≈ 615px
|
||
设计稿机身 932px × 92% = 857 ✓;最窄的 iPhone SE 667 × 92% = 613 ——
|
||
**贴着线**。所以下面做了两件省高度的事,别随手退回去:
|
||
① 昵称和宝宝小名并成一行 .fld-row(省 78px);
|
||
② 这个弹窗里的大头像从 92px 收到 76px(见 css 的 #modalProfile .av-big)。
|
||
再往里加字段之前,先回来把这笔账重算一遍。 -->
|
||
<!-- 盲盒 · 集齐全集的实物奖励:收货信息。POST /api/mp/public/mama-box/blindbox/claim -->
|
||
<section class="modal" id="modalBxAddr" role="dialog" aria-modal="true" aria-labelledby="modalBxAddrTitle">
|
||
<div class="modal-head">
|
||
<h3 id="modalBxAddrTitle">领取孕期纪念礼</h3>
|
||
<button class="modal-x" data-modal="close" aria-label="关闭">
|
||
<svg viewBox="0 0 24 24" width="15" height="15" aria-hidden="true"><path d="M6 6l12 12M18 6L6 18" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"/></svg>
|
||
</button>
|
||
</div>
|
||
<p class="bx-addr-tip">恭喜集齐 37 张宝宝卡!填好收货信息,工作人员会在 7 个工作日内为你寄出。</p>
|
||
<div class="fld-row">
|
||
<label class="fld"><span>收货人</span><input id="bxAddrName" type="text" maxlength="20" placeholder="姓名"></label>
|
||
<label class="fld"><span>手机号</span><input id="bxAddrPhone" type="tel" maxlength="20" placeholder="手机号"></label>
|
||
</div>
|
||
<label class="fld"><span>收货地址</span><input id="bxAddrAddr" type="text" maxlength="120" placeholder="省市区 + 详细地址"></label>
|
||
<div class="modal-foot"><button class="dl-btn main" id="bxAddrSave">提交</button></div>
|
||
</section>
|
||
|
||
<!-- 星座宝宝(2026-10-04):点头图孕囊旁的「xx宝宝」小牌打开(js/hero-fx.js 派发 mb-zodiac → app.js 填内容 + openModal)。
|
||
幸运色 → 性格 → 适合的职业;预产期落在星座交界时顶部给两个可切换的小标签。内容是星座小趣味,底部写明。 -->
|
||
<section class="modal zd-modal" id="modalZodiac" data-autofocus="off" role="dialog" aria-modal="true" aria-labelledby="zdName">
|
||
<!-- 2026-10-04 二版(用户:「弹出的页面重新设计,要有针对星座的设计感,背景色按火象、水象这些」):
|
||
顶部一条按四象配色的头带(火 / 土 / 风 / 水),右上角淡淡画出这个星座的星图(星星会闪),
|
||
正中玻璃圆里是星座符号;头带底边是元素纹样(火焰 / 山脊 / 云 / 水波),最下一层用正文底色填,头带「长」进正文。
|
||
素材在 js/zodiac-art.js。 -->
|
||
<div class="zd-band" id="zdBand">
|
||
<svg class="zd-sky" id="zdSky" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet" aria-hidden="true"></svg>
|
||
<button class="modal-x" data-modal="close" aria-label="关闭">
|
||
<svg viewBox="0 0 24 24" width="15" height="15" aria-hidden="true"><path d="M6 6l12 12M18 6L6 18" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"/></svg>
|
||
</button>
|
||
<span class="zd-glyph" id="zdGlyph" aria-hidden="true"></span>
|
||
<h3 id="zdName"></h3>
|
||
<p class="zd-range"><span class="zd-el" id="zdEl"></span><span id="zdRange"></span></p>
|
||
<div class="zd-switch" id="zdSwitch" hidden></div>
|
||
<svg class="zd-motif" id="zdMotif" viewBox="0 0 375 56" preserveAspectRatio="none" aria-hidden="true"></svg>
|
||
</div>
|
||
<p class="zd-words" id="zdWords"></p>
|
||
<div class="zd-sec zd-color">
|
||
<i class="zd-sw" aria-hidden="true"></i>
|
||
<div><span class="zd-label">宝宝幸运色</span><b id="zdColor"></b><p id="zdColorTip"></p></div>
|
||
</div>
|
||
<div class="zd-sec">
|
||
<span class="zd-label">宝宝的性格</span>
|
||
<div class="zd-tags" id="zdTraits"></div>
|
||
<p class="zd-para" id="zdPara"></p>
|
||
</div>
|
||
<div class="zd-sec">
|
||
<span class="zd-label">长大后可能会喜欢的职业</span>
|
||
<div class="zd-jobs" id="zdJobs"></div>
|
||
</div>
|
||
<p class="zd-foot">星座小趣味,听听就好 —— 每个宝宝都是独一无二的小宇宙</p>
|
||
</section>
|
||
|
||
<!-- 意见反馈(2026-10-04)。类型 → 描述 → 截图(选填,最多 3 张,走 /api/upload)→ 联系方式(选填)→ 提交。
|
||
底部「我提交过的」列出最近几条和处理状态 / 回复(运营在管理端 PUT /api/mama-box/feedbacks/{id} 标记)。 -->
|
||
<section class="modal fb-modal" id="modalFeedback" data-autofocus="off" role="dialog" aria-modal="true" aria-labelledby="fbTitle">
|
||
<div class="modal-head">
|
||
<h3 id="fbTitle">意见反馈</h3>
|
||
<button class="modal-x" data-modal="close" aria-label="关闭">
|
||
<svg viewBox="0 0 24 24" width="15" height="15" aria-hidden="true"><path d="M6 6l12 12M18 6L6 18" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"/></svg>
|
||
</button>
|
||
</div>
|
||
<p class="fb-lead">哪里不好用、想要什么新功能,都可以告诉我们,每一条都会认真看。</p>
|
||
<div class="fb-kinds" id="fbKinds" role="radiogroup" aria-label="反馈类型">
|
||
<button type="button" class="fb-kind" data-kind="bug" role="radio" aria-checked="false">功能问题</button>
|
||
<button type="button" class="fb-kind on" data-kind="idea" role="radio" aria-checked="true">功能建议</button>
|
||
<button type="button" class="fb-kind" data-kind="other" role="radio" aria-checked="false">其他</button>
|
||
</div>
|
||
<div class="fb-ta-wrap">
|
||
<textarea class="fb-ta" id="fbText" maxlength="500" placeholder="说说你遇到的问题或想法…"></textarea>
|
||
<span class="fb-count" id="fbCount">0/500</span>
|
||
</div>
|
||
<div class="fb-imgs" id="fbImgs">
|
||
<label class="fb-add" id="fbAdd"><input type="file" accept="image/*" id="fbFile" hidden><svg viewBox="0 0 24 24" width="22" height="22" aria-hidden="true"><path d="M12 6v12M6 12h12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg><span>截图</span></label>
|
||
<span class="fb-imgs-tip">选填,最多 3 张</span>
|
||
</div>
|
||
<label class="fld fb-contact"><span>联系方式(选填)</span><input id="fbContact" type="text" maxlength="40" placeholder="手机号或微信号,方便我们回复你"></label>
|
||
<div class="modal-foot"><button class="dl-btn main" id="fbSubmit">提交</button></div>
|
||
<div class="fb-mine" id="fbMine" hidden>
|
||
<h4>我提交过的</h4>
|
||
<div id="fbMineList"></div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 同周悄悄话 · 全屏页(2026-10-02 二改)。「深夜星河」:深靛紫夜空 + 星点,悄悄话是一盏盏漂浮的玻璃泡,
|
||
抱抱越多越亮越大;最上面是今晚抱抱最多的一句,大字。底部一颗发光的「说一句悄悄话」。
|
||
层级 z 110:盖住 tabbar(60),低于说一句弹窗(modal 120+),所以在这页里点「说一句」弹窗能盖在上面。 -->
|
||
<section class="wh-page" id="whPage" role="dialog" aria-modal="true" aria-labelledby="whpTitle" aria-hidden="true">
|
||
<div class="whp-sky" aria-hidden="true"><i class="s1"></i><i class="s2"></i><i class="s3"></i><i class="moon"></i></div>
|
||
<!-- 2026-10-02 五改(用户:「打开页面夜空里特别多星星;点开一颗,它像流星一样滑落,白色的头往下滑,
|
||
尾巴就是这句话的字;先保证看清,刚开始慢一点,说完了唰地就快了;同时把对应内容呈现出来」):
|
||
夜空 = 每句一颗可点的亮星 + 一百多颗装饰小星(偶尔有无字的小流星划过);点亮星 → 流星 + 底部内容卡。 -->
|
||
<div class="whv-aura" id="whvAura" aria-hidden="true"><i></i><i></i></div>
|
||
<div class="wsk" id="wsk">
|
||
<div class="wsk-deco" id="wskStars" aria-hidden="true"></div>
|
||
<i class="wsk-shoot" aria-hidden="true"></i><i class="wsk-shoot s2" aria-hidden="true"></i>
|
||
<div class="wsk-bright" id="wskBright" role="group" aria-label="夜空里的星星,每颗是一句悄悄话"></div>
|
||
</div>
|
||
<header class="whv-top">
|
||
<button class="whp-back" id="whpBack" type="button" aria-label="返回">
|
||
<svg viewBox="0 0 24 24" width="20" height="20"><path d="M15 5l-7 7 7 7" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||
</button>
|
||
<span class="whp-tag" id="whpTag"></span>
|
||
<button class="whv-snd" id="whvSnd" type="button" aria-label="关闭声音"><svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 9.5h3.5L12 5.5v13l-4.5-4H4z" fill="currentColor" stroke="none"/><path class="on" d="M15.5 9a4 4 0 010 6M18 6.5a7.5 7.5 0 010 11"/><path class="off" d="M16 9.5l5 5M21 9.5l-5 5"/></svg></button>
|
||
<button class="whv-all" id="whvAll" type="button">全部</button>
|
||
</header>
|
||
<div class="wsk-title" id="wskTitle"></div>
|
||
<p class="wsk-tip" id="wskTip"><i></i>点一下小星星,听听她们说了什么</p>
|
||
<div class="wsk-done" id="wskDone"><p>星星都落下来啦<br><span>她们的话,你都听到了</span></p><button type="button" id="wskBack">让星星回来</button></div>
|
||
<div class="wsc" id="wsc" aria-live="polite"></div>
|
||
<h2 class="sr-only" id="whpTitle">同孕周悄悄话</h2>
|
||
<div class="whd" id="whDrawer" aria-hidden="true">
|
||
<div class="whd-panel" role="dialog" aria-label="全部悄悄话">
|
||
<div class="whd-head"><b>全部悄悄话</b><span id="whpCount"></span><button type="button" class="whd-x" id="whdX" aria-label="收起"><svg viewBox="0 0 24 24" width="14" height="14"><path d="M6 6l12 12M18 6L6 18" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/></svg></button></div>
|
||
<div class="whp-list" id="whpList"></div>
|
||
</div>
|
||
</div>
|
||
<div class="whp-bar">
|
||
<button class="whp-say" id="whSay" type="button"><span>说一句悄悄话</span></button>
|
||
<p class="whp-left" id="whpLeft"></p>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 此刻 · 说一句悄悄话(2026-10-02)。预设句点一下就填进输入框;自由输入由服务端过微信内容安全审核 -->
|
||
<section class="modal wh-modal" id="modalWhisper" data-autofocus="off" role="dialog" aria-modal="true" aria-labelledby="whMTitle">
|
||
<div class="modal-head">
|
||
<h3 id="whMTitle">说一句悄悄话</h3>
|
||
<button class="modal-x" data-modal="close" aria-label="关闭">
|
||
<svg viewBox="0 0 24 24" width="15" height="15" aria-hidden="true"><path d="M6 6l12 12M18 6L6 18" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"/></svg>
|
||
</button>
|
||
</div>
|
||
<p class="wh-m-topic" id="whMTopic" style="display:none"></p>
|
||
<p class="wh-m-lead" id="whMLead">不显示昵称和头像,只有同孕期的妈妈能看到。她们会给你一个抱抱。</p>
|
||
<div class="wh-ta-box">
|
||
<textarea class="wh-ta" id="whTa" maxlength="40" rows="2" placeholder="今天想对谁说点什么?"></textarea>
|
||
<span class="wh-cnt" id="whCnt">0/40</span>
|
||
</div>
|
||
<div class="wh-m-sub">不知道说什么?点一句</div>
|
||
<div class="wh-presets" id="whPresets"></div>
|
||
<div class="modal-foot">
|
||
<button class="dl-btn main" id="whSend" type="button">悄悄发出</button>
|
||
<p class="wh-left" id="whLeft"></p>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 盲盒 · 分段集齐达成的庆祝弹层(内容由 app.js showPrize() 填) -->
|
||
<section class="modal bx-prize" id="modalBxPrize" role="dialog" aria-modal="true" aria-labelledby="bxPrizeT">
|
||
<div class="bx-prize-ico" aria-hidden="true">🏆</div>
|
||
<h3 id="bxPrizeT"></h3>
|
||
<p id="bxPrizeP"></p>
|
||
<div class="modal-foot"><button class="dl-btn main" id="bxPrizeOk">太好了</button></div>
|
||
</section>
|
||
|
||
<!-- 新人欢迎礼(2026-10-10):统一兜豆账本 welcome 规则首次发放时弹一次;豆数用接口返回的 granted -->
|
||
<section class="modal bx-prize wg-modal" id="modalWelcome" role="dialog" aria-modal="true" aria-labelledby="wgT">
|
||
<div class="bx-prize-ico" aria-hidden="true">🎁</div>
|
||
<h3 id="wgT">新人欢迎礼 <b class="wg-n">+<span id="wgN">50</span></b> 兜豆</h3>
|
||
<p>已经存进你的兜豆账户,可以去兑换好物啦</p>
|
||
<div class="modal-foot">
|
||
<button class="dl-btn ghost" data-modal="close">收下了</button>
|
||
<button class="dl-btn main" id="wgGo">去看看</button>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 2026-10-10 用户:退出登录前二次确认,写清只清授权信息、孕育数据保留 -->
|
||
<section class="modal bx-prize lg-modal" id="modalLogout" data-autofocus="off" role="dialog" aria-modal="true" aria-labelledby="lgT">
|
||
<h3 id="lgT">确定退出登录?</h3>
|
||
<p>退出后不再显示你的昵称、头像和手机号。孕期资料和各项记录仍保存在这个微信上,重新授权就能继续使用。</p>
|
||
<div class="modal-foot">
|
||
<button class="dl-btn ghost" data-modal="close">再想想</button>
|
||
<button class="dl-btn main" id="lgOk">退出登录</button>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="modal pf-modal" id="modalProfile" data-autofocus="off" role="dialog" aria-modal="true" aria-labelledby="modalProfileTitle">
|
||
<div class="modal-head">
|
||
<h3 id="modalProfileTitle">我的资料</h3>
|
||
<button class="modal-x" data-modal="close" aria-label="关闭">
|
||
<svg viewBox="0 0 24 24" width="15" height="15" aria-hidden="true">
|
||
<path d="M6 6l12 12M18 6L6 18" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"/>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
|
||
<!-- 2026-10-01 资料弹窗改版(用户:「现在填写比较困难,让用户很轻松地就能填写完」):
|
||
① 顶部一条实时结果「孕 N 周 +D 天 · 还有 X 天见面」—— 填的每一步都立刻看到算出了什么;
|
||
② 预产期三种填法(分段切换):知道预产期 / 按当前孕周(大号 −/+ 步进,不用敲键盘)/ 按末次月经;
|
||
三种最后都落到 #pgDue(唯一的数据源),保存逻辑一行没改;
|
||
③ 头像缩到昵称左边,和昵称同一行;宝宝小名下面给几个一点即填的小名;
|
||
④ 弹窗不再自动聚焦昵称(data-autofocus="off")—— 一打开就弹键盘,正好盖住要填的预产期。 -->
|
||
<p class="pf-lead">填好预产期,孕周和倒计时都会自动算好</p>
|
||
|
||
<div class="pf-sum" id="pgSum">
|
||
<span class="ps-ico" aria-hidden="true">
|
||
<svg viewBox="0 0 24 24" width="22" height="22"><path d="M12 20.5s-7.5-4.4-7.5-10A4.3 4.3 0 0 1 12 8a4.3 4.3 0 0 1 7.5 2.5c0 5.6-7.5 10-7.5 10z" fill="currentColor"/></svg>
|
||
</span>
|
||
<span class="ps-main"><b id="pgSumT">还没填预产期</b><span id="pgSumS">选一种方式填一下,马上就好</span></span>
|
||
</div>
|
||
|
||
<div class="pf-card">
|
||
<div class="pf-ct">孕期信息<em>必填</em></div>
|
||
<div class="seg" id="pgMode" role="tablist">
|
||
<button type="button" class="seg-b is-active" data-mode="due">知道预产期</button>
|
||
<button type="button" class="seg-b" data-mode="week">按当前孕周</button>
|
||
<button type="button" class="seg-b" data-mode="lmp">按末次月经</button>
|
||
</div>
|
||
|
||
<div class="pg-pane is-on" data-pane="due">
|
||
<label class="date-btn">
|
||
<span class="db-ico" aria-hidden="true"><svg viewBox="0 0 24 24" width="20" height="20"><rect x="4" y="5.5" width="16" height="14.5" rx="3" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M4 10h16M8.5 3.5v4M15.5 3.5v4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg></span>
|
||
<span class="db-txt" id="pgDueTxt">点这里选预产期</span>
|
||
<i class="chev">›</i>
|
||
<input id="pgDue" type="date" aria-label="预产期">
|
||
</label>
|
||
<p class="pg-tip">产检单 / B 超单上写的「预产期」</p>
|
||
</div>
|
||
|
||
<div class="pg-pane" data-pane="week">
|
||
<div class="stp-row">
|
||
<div class="stp">
|
||
<span class="stp-l">孕周</span>
|
||
<div class="stp-ctl">
|
||
<button type="button" class="stp-b" data-stp="w" data-d="-1" aria-label="孕周减一">−</button>
|
||
<input id="pgWeek" type="number" inputmode="numeric" min="0" max="42" placeholder="—">
|
||
<button type="button" class="stp-b" data-stp="w" data-d="1" aria-label="孕周加一">+</button>
|
||
</div>
|
||
</div>
|
||
<div class="stp">
|
||
<span class="stp-l">又几天</span>
|
||
<div class="stp-ctl">
|
||
<button type="button" class="stp-b" data-stp="d" data-d="-1" aria-label="天数减一">−</button>
|
||
<input id="pgDay" type="number" inputmode="numeric" min="0" max="6" placeholder="—">
|
||
<button type="button" class="stp-b" data-stp="d" data-d="1" aria-label="天数加一">+</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p class="pg-tip" id="pgHint">比如「孕 24 周 +3 天」,就选 24 和 3</p>
|
||
</div>
|
||
|
||
<div class="pg-pane" data-pane="lmp">
|
||
<label class="date-btn">
|
||
<span class="db-ico" aria-hidden="true"><svg viewBox="0 0 24 24" width="20" height="20"><rect x="4" y="5.5" width="16" height="14.5" rx="3" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M4 10h16M8.5 3.5v4M15.5 3.5v4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg></span>
|
||
<span class="db-txt" id="pgLmpTxt">点这里选末次月经第一天</span>
|
||
<i class="chev">›</i>
|
||
<input id="pgLmp" type="date" aria-label="末次月经第一天">
|
||
</label>
|
||
<p class="pg-tip">按末次月经第一天 + 280 天推算预产期</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="pf-card">
|
||
<!-- 2026-10-05 用户:「小名」这行字挪到「宝宝」后面、放进括号 → 标题写成「宝宝(小名)」,输入框上方不再单独一行「小名」(读屏仍念「宝宝小名」) -->
|
||
<div class="pf-ct">宝宝(小名)</div>
|
||
<label class="fld pf-fld"><span class="sr-only">宝宝小名</span><input id="pgName" type="text" maxlength="12" placeholder="给宝宝起个小名"></label>
|
||
<div class="nm-chips" id="pgNameChips">
|
||
<button type="button" class="nm-c">小汤圆</button><button type="button" class="nm-c">豆豆</button><button type="button" class="nm-c">糖糖</button><button type="button" class="nm-c">小米粒</button><button type="button" class="nm-c">乐乐</button>
|
||
</div>
|
||
<div class="fld pf-fld">
|
||
<span>性别</span>
|
||
<div class="pick-row" id="pgSex">
|
||
<button type="button" class="pick is-active" data-sex="unknown">还不知道</button>
|
||
<button type="button" class="pick" data-sex="boy">男孩</button>
|
||
<button type="button" class="pick" data-sex="girl">女孩</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="pf-card">
|
||
<div class="pf-ct">妈妈</div>
|
||
<!-- 2026-10-10 方案A:未授权(含退出登录后)不显示旧昵称/头像,换成授权提示;点它去授权。宝宝那栏不受影响 -->
|
||
<button type="button" class="pf-unauth ripple" id="pfUnauth" style="display:none">授权登录后显示你的昵称和头像<b>去授权 ›</b></button>
|
||
<div class="pf-me" id="pfMe">
|
||
<div class="av-pick">
|
||
<button class="av-big" id="avPick" aria-label="更换头像">
|
||
<svg viewBox="0 0 40 40" aria-hidden="true">
|
||
<circle cx="20" cy="14.5" r="7" fill="#fff"/>
|
||
<path d="M6.5 35c0-7.2 6-11.5 13.5-11.5S33.5 27.8 33.5 35z" fill="#fff"/>
|
||
</svg>
|
||
<img id="avPreview" alt="">
|
||
<span class="av-cam">
|
||
<svg viewBox="0 0 24 24" width="15" height="15" aria-hidden="true">
|
||
<path d="M3 8.6A2.6 2.6 0 0 1 5.6 6h1.9l1.3-2h6.4L16.5 6h1.9A2.6 2.6 0 0 1 21 8.6v8.8a2.6 2.6 0 0 1-2.6 2.6H5.6A2.6 2.6 0 0 1 3 17.4z" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linejoin="round"/>
|
||
<circle cx="12" cy="13" r="3.6" fill="none" stroke="currentColor" stroke-width="1.9"/>
|
||
</svg>
|
||
</span>
|
||
</button>
|
||
<input type="file" id="avFile" accept="image/*" class="av-file">
|
||
<!-- file input 藏起来但不能 display:none,否则部分安卓 WebView 点不动(0 尺寸 + opacity) -->
|
||
<input type="file" id="avFile" accept="image/*" class="av-file">
|
||
</div>
|
||
<label class="fld pf-fld"><span>怎么称呼你</span><input id="pfName" type="text" maxlength="16" placeholder="妈妈"></label>
|
||
</div>
|
||
<p class="pg-tip" id="pfMeTip">点头像换张照片</p>
|
||
</div>
|
||
|
||
<!-- 2026-10-10 用户:「我的资料」里也要有「退出登录」。显示规则同「我的」页 #meLogoutCard(已授权才显示),共用 doLogout -->
|
||
<button type="button" class="pf-logout ripple" id="pfLogout" style="display:none">退出登录</button>
|
||
|
||
<div class="modal-foot pf-foot">
|
||
<button class="dl-btn ghost" data-modal="close">取消</button>
|
||
<button class="dl-btn main" id="pfSave">保存</button>
|
||
</div>
|
||
</section>
|
||
|
||
<div class="toast" id="toast"></div>
|
||
</div>
|
||
|
||
<!-- 微信 JS-SDK:仅在 web-view 内给 wx.miniProgram 用(「进商城」跳原生页)。
|
||
加载失败/离线时 window.wx 为 undefined,goMall() 会降级为 toast 提示,
|
||
不影响应用其余功能。 -->
|
||
|
||
<script src="js/zodiac-art.js"></script>
|
||
<script src="js/app.js"></script>
|
||
<!-- 2026-10-03 首页彩蛋:宝宝在肚皮底下动(独立文件,删掉这一行即整体下线;开关在「隐私权限」) -->
|
||
<script src="js/bump.js"></script>
|
||
<!-- 2026-10-04 首页头图:按孕周换宝宝 + 阳光水波(独立文件) -->
|
||
<script src="js/hero-fx.js"></script>
|
||
<!-- 2026-10-05 首页头图:宝宝时不时动一动小手小脚(独立文件,删掉这一行即下线) -->
|
||
<script src="js/baby-limbs.js"></script>
|
||
|
||
</body>
|
||
</html>
|