1852 lines
139 KiB
HTML
1852 lines
139 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:26100122 缓存版本标记:改 css/js 时同步 bump 该值(与 js/app.js 的 VER 同源),静态资源按 mtime 走 ETag 自动刷新 -->
|
||
<link rel="stylesheet" href="mama-box.css">
|
||
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
|
||
<!-- 共享助手:授权/跳商城/位置上报(分享卡片同步,见 docs/h5-auth-standard.md 第四节) -->
|
||
<script src="js/wx-auth.js"></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>
|
||
<nav class="tabbar" id="tabbar">
|
||
<button class="tab is-active" data-tab="home">
|
||
<span class="t-ico ic-home"></span><span class="t-txt">首页</span>
|
||
</button>
|
||
<button class="tab" data-tab="archive">
|
||
<span class="t-ico ic-archive"></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"></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 ic-letter"></span><span class="t-badge" id="tabBadge"></span><span class="t-txt">宝宝来信</span>
|
||
</button>
|
||
<button class="tab" data-tab="me">
|
||
<span class="t-ico ic-me"></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">
|
||
<div class="petals" id="petals"></div>
|
||
<!-- 2026-09-30:头图背景 = 孕 25 周动图(母婴作图 v7)的静帧,这里只叠一张截了羊水囊的同源 GIF .hero-kid:
|
||
镜头固定、同一帧起步,所以和背景严丝合缝;宝宝侧身闭眼睡、小手在嘴边自己动,囊和脐带不动。
|
||
GIF 没加载出来就停在背景那一帧。(v6 起嘴边的小气泡去掉了,v7 没加回来。)
|
||
2026-10-01 换 v8:静帧不变,动作加大——整体轻摇±1.8°+微浮、呼吸、点头、小手、每周期蹬一下脚,4 秒一圈。 -->
|
||
<div class="hero-baby" aria-hidden="true">
|
||
<img class="hero-kid" id="heroKid" src="assets/img/250bb167b0f1.gif" 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>
|
||
</div>
|
||
|
||
<div class="hero-main">
|
||
<div class="week-ring">
|
||
<svg viewBox="0 0 120 120" class="ring-svg">
|
||
<circle class="ring-bg" cx="60" cy="60" r="56"/>
|
||
<circle class="ring-fg" id="heroRing" cx="60" cy="60" r="56" data-ring="0.6"/>
|
||
</svg>
|
||
<div class="week-num"><b id="heroWeek">24</b><span>孕周</span></div>
|
||
</div>
|
||
<div class="week-plus" id="heroPlus">+3天</div>
|
||
</div>
|
||
|
||
<!-- 原来是一行干巴巴的白字浮在橙底上。改成一张毛玻璃小卡:
|
||
上行小名,下行天数(数字放大当主角)。卡片是 inline-flex,
|
||
宽度由内容撑开,两行排布让它窄到不会伸进右边气泡宝宝底下。 -->
|
||
<div class="hero-days">
|
||
<div class="hd-card">
|
||
<span class="hd-who">
|
||
<svg class="hd-heart" viewBox="0 0 24 24" width="12" height="12" aria-hidden="true">
|
||
<path d="M12 20.4S3.6 14.9 3.6 9.3a4.6 4.6 0 0 1 8.4-2.6 4.6 4.6 0 0 1 8.4 2.6c0 5.6-8.4 11.1-8.4 11.1z" fill="rgba(255,255,255,.92)"/>
|
||
</svg>
|
||
<b id="heroWho">小汤圆</b><span class="hd-where">在妈妈肚子里</span>
|
||
</span>
|
||
<!-- ⚠️ 这句话是**拆成两行**放的,别合成一行。
|
||
.hero-days 是 max-width:196px,.hd-tail 又是 white-space:nowrap,
|
||
「在妈妈肚子里已经生活了 188 天」整句 ≈ 182px + 卡内边 26px = 208px,
|
||
超出 196px 会溢出到插画上。
|
||
拆开后:第一行 ♥+小名+「在妈妈肚子里」≈ 163px,
|
||
第二行「已经生活了 188 天」≈ 133px,两行都放得下。 -->
|
||
<span class="hd-tail">已经生活了 <b id="heroDays">171</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"><img class="lc-env" src="assets/img/02cf420f0d07.png" alt="" aria-hidden="true"></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>
|
||
</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",
|
||
删掉任意一个另一个都还走得通。 -->
|
||
<!-- 孕期盲盒 · 首页细横幅(2026-10-01,需求文档 v1.0 三-7)。
|
||
放在顶部大图正下方(需求:顶部大图 → 盲盒横幅 → 孕育工具 → 此刻 → 消消乐)。
|
||
文案/状态全由 app.js renderBanner() 按 /blindbox 返回写入;访客态(无 openid)、孕 4 周前、接口失败 → 保持 .hide。
|
||
⚠️ 它是 #homeBody 的第一个孩子,吃的是 .home-body>:first-child 那条上间距;
|
||
隐藏时由 CSS「.bb-banner.hide + .tool-dock」把间距还给工具托盘。 -->
|
||
<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>
|
||
|
||
<section class="tool-dock">
|
||
<!-- 大字水印。aria-hidden:读屏念到这块该直接进标题,
|
||
不该先听见两声「妈妈」。样式和理由都在 css/style.css 的 .wm 上。 -->
|
||
<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 行 ——
|
||
① 标题行不变;② 「她们在做」两条进度条合成**一句**,只挑你今天还没做的那项(都做了就一句夸奖),去掉进度条;
|
||
③ 「今天别忘了」整行删(产检、盲盒在上面工具宫格和盲盒横幅里都有);④ 滚动动态去掉白底卡片,压成一行小字。 -->
|
||
<div class="pulse hide" id="pulse" role="region" aria-label="此刻,孕妈们在做什么">
|
||
<div class="pl-head">
|
||
<span class="pl-live"><i></i>此刻</span>
|
||
<span class="pp-avs" id="ppAvs" aria-hidden="true"></span>
|
||
<span class="pl-title" id="plTitle"></span>
|
||
</div>
|
||
<div class="pp-doing hide" id="ppDoing"></div>
|
||
<div class="pl-feed hide" id="plFeed"><div class="pl-track" id="plTrack"></div></div>
|
||
</div>
|
||
</section>
|
||
|
||
|
||
<!-- 宝宝消消乐 · 推广入口(2026-09-30)。用户原话:「做了一个消消乐小游戏(待产清单主题),
|
||
放到首页展示并推广,宝妈们业余时间玩,名字叫宝宝消消乐」。
|
||
放在工具托盘正下方:首屏滑一下就能看到。右侧 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">奶瓶、尿不湿、小衣服……<br>三个一样就消掉,边玩边备齐待产包</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>
|
||
<span class="gp-board" id="gpBoard" aria-hidden="true"></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>
|
||
|
||
<!-- 孕期小知识(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>
|
||
<!-- 2026-10-01 用户反馈「文字太多」:首页只留核心 —— 今天这条的标题 + 一行摘要,下面一排四个入口;
|
||
整段正文、7 天回看、宝宝/妈妈/饮食/留心四张卡全挪进详情页 #detailTips(点卡或点入口进去,入口会滚到对应那张)。 -->
|
||
<div class="pt-mini" id="ptMini" role="button" tabindex="0" aria-label="查看今日孕期小知识详情">
|
||
<span class="pt-float" id="ptMiniFloat" aria-hidden="true"></span>
|
||
<div class="pt-mini-t" id="ptMiniT"></div>
|
||
<div class="pt-mini-d" id="ptMiniD"></div>
|
||
<span class="pt-mini-go">看详情 ›</span>
|
||
</div>
|
||
<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 id="ptChipBabyT">宝宝这周</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>
|
||
</section>
|
||
|
||
<!-- 模块二 · 今天的动线。
|
||
上一版这里是两个各自独立的模块:「AI今日小结」一张渐变卡,
|
||
下面「今日成长脚印」一张白卡装的时间轴。可 AI 那句话总结的
|
||
就是脚印里这四条记录,中间隔着一整套抬头分开摆,两边都在自说自话。
|
||
现在合成一条线:起点是「今天」,中间四条记录,
|
||
末尾挂 AI 那句话当这一天的落款。
|
||
时间轴外面那张白卡也撤了 —— 结构改由 .today-line::before 那条
|
||
贯穿到底的竖线撑起来,不再靠一个方框圈出来,
|
||
这样它和上面的托盘、下面的卡带才真的是三种容器语言。
|
||
|
||
⚠️ .steps 仍是整卡可点的 role="button",里面**不能**再出现 <button>。
|
||
所以「查看全部 ›」挂在 .tl-head 上、AI 气泡是 .steps 的兄弟节点,
|
||
两者都在 .steps 外面。 -->
|
||
<section class="today-line">
|
||
<div class="tl-head">
|
||
<span class="tl-h-when">今天</span>
|
||
<span class="tl-h-dot"></span>
|
||
<h2 class="tl-h-title" id="tlTitle">宝宝的今日脚印</h2>
|
||
<button class="tl-h-all" data-goto="archive">查看全部 ›</button>
|
||
</div>
|
||
<!-- 这句是首页 slogan 挪走之后接手的那一句(用户点名要放这儿)。
|
||
⚠️ 全站现在只有这一处写着「把每次记录变成孩子一生的记忆」,
|
||
顶上 slogan 已经换成「每次记录都是一生记忆」了,别再抄回去 ——
|
||
两处贴着同一句话,等于把这句说废了。 -->
|
||
<p class="tl-h-note">把每次记录变成孩子一生的记忆</p>
|
||
<!-- 整张卡都能点。上面那颗「查看全部 ›」正好当成「这张能点」的提示
|
||
(整卡可点最大的毛病就是看不出来能点)。 -->
|
||
<!-- ⚠️ aria-label 里也有小名,所以它跟 #tlTitle 一起交给 syncBabyWords()
|
||
刷。标题跟着小名走、读屏却一直念旧名字,是最难被发现的那种不同步 ——
|
||
眼睛看不见它。 -->
|
||
<!-- ⚠️ 这里原来躺着 4 条**写死的演示行**(胎动 12 次 / 体重 58.2kg / 产检提醒 / 睡前散步)。
|
||
它们只在「接口读不到」时露出来 —— 也就是说,上游一抖动,页面就开始编数据。
|
||
2026-09-22 按产品口径删掉,换成一条中性占位;四种显示模式由下方 JS 的 fpApply() 决定:
|
||
· 有档案 + 拿到事件 → 渲染真实事件(覆盖 #tlSteps)
|
||
· 有档案 + 今天没记 → 「还没有足迹」
|
||
· 有档案 + 接口读不到 → **整块不显示**(不编数据)
|
||
· 无档案(上游查无此人)→ 显示 #tlGuide 引导占位
|
||
首次渲染时 `#tlSteps` 里是这条「正在获取…」,不是假数据;
|
||
JS 的 pendingFootprintStep() 会建一份**同构**的行,两处改文案要一起改。 -->
|
||
<div class="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>
|
||
<!-- 引导占位(fpApply('guide') 才显示,此时 #tlSteps 收起):
|
||
文案与应用**都来自接口** —— lead 是上游自己的引导语(如「宝妈,先从这几件事记起吧。」),
|
||
unused[] 是今天没用过的应用,能对上 App 表的会渲染成可点芯片(见 js 的 renderGuide)。
|
||
⚠️ 版式**沿用下面 AI 气泡那套语言**(左列 + 圆点 + 带尖角的气泡),只是底色用白 ——
|
||
用户反馈原来那张横跨整块的白卡「放在这有点突兀」;现在它与时间轴共用同一条竖线。
|
||
左边的空 .ab-badge 只是**占位**,宽度 = --tl-time,好让圆点落在竖线上(与 AI 行同列)。 -->
|
||
<div class="tl-guide" id="tlGuide" style="display:none">
|
||
<span class="ab-badge"></span>
|
||
<span class="ab-dot"></span>
|
||
<span class="ab-body">
|
||
<span class="tl-guide-bubble">
|
||
<span class="tl-guide-t" id="tlGuideTitle">还没有你的脚印</span>
|
||
<span class="tl-guide-s" id="tlGuideSub">去上面的工具记一笔,这里就会长出你今天的脚印</span>
|
||
<span class="tl-guide-apps" id="tlGuideApps"></span>
|
||
</span>
|
||
</span>
|
||
</div>
|
||
<!-- 这一天的收尾节点。三个直接子元素刻意和 .step 一样排
|
||
(42px 的左格 + 圆点 + 剩下的),点才落得进同一条竖线里。
|
||
模块名「AI今日小结」降级成气泡里的一枚小标签,
|
||
说明和「往期小结 ›」并成气泡底下的一行落款 ——
|
||
320px 视口下这三段挤在一行是塞不下的,所以标签得进气泡。 -->
|
||
<button class="ai-bubble ripple" data-open="detailAI">
|
||
<span class="ab-badge">AI</span>
|
||
<span class="ab-dot"></span>
|
||
<span class="ab-body">
|
||
<span class="ab-bubble">
|
||
<b class="ab-tag" id="abTag">宝宝今天想说</b>
|
||
<!-- 这句是 app.js 里 AI_LOGS[0].txt 的手写副本(这里要 <b> 和 <br> 排版,
|
||
没法直接共用那个字符串)。那边改口吻,这里必须跟着改,
|
||
否则首页气泡说「小家伙」、点进去小结说「我」,像两个人在写。
|
||
✅ 2026-09-23 已接真源:句子的数据来自 box_app 的 /footprint/today
|
||
(上游数胎动平台的用户面接口 /user/daily/footprint 的 `digest.text`),
|
||
由 fpRender() 写入;`digest.warn` 为真时整句标红(.ai-warn)。
|
||
⚠️ 但 AI 小结面板(详情页 renderAI → AI_LOGS)里那份仍是**演示文案**,
|
||
与这里是两套数据 —— 面板要一并用真数据,得先有 mood/stats/建议的字段。 -->
|
||
<!-- ⚠️ 文案由 js 的 fpRender() 从接口 `digest.text` 写入(今日脚印接口给的真文案)。
|
||
原来这里写死「妈妈,今天你数到我动了 3 次…」,任何用户都看到 —— 已删。
|
||
接口没给 digest(今天没活动 / 读不到)时整颗气泡由 .no-ai 收起,不留空壳。 -->
|
||
<span class="ab-say"></span>
|
||
</span>
|
||
<!-- 「AI自动汇总你每日记录」按用户要求删了,这行现在只剩右边的入口。
|
||
✅ 位置不用额外处理:.ab-foot em 本来就写着 margin-left:auto,
|
||
左边那截没了它照样贴右。(原来那条 .ab-foot i 的样式已成
|
||
死规则,一并删了。) -->
|
||
<span class="ab-foot"><em>往期小结 ›</em></span>
|
||
</span>
|
||
</button>
|
||
</section>
|
||
|
||
<!-- 树洞(2026-09-30)。用户原话:「宝妈们有任何情绪上的问题,都可以在这个树洞里扔进去」。
|
||
用户选定:**只存在她自己手机上**(localStorage 'mmbox.treehole.v1',不上传、后台也看不到),
|
||
扔进去后**只有「已收好」的动画,不做回应**。
|
||
⚠️ 唯一的例外是安全提示:内容里出现明显的轻生字眼时,收好之后在卡内显示一行援助热线
|
||
(12356 全国心理援助热线),这不是「回应心事」,是兜底,别删。
|
||
⚠️ 纸团飞进树洞的动画靠 Element.animate;不支持的老内核直接跳到「已收好」,不影响收存。 -->
|
||
<!-- 「妈妈的树洞」整块已删(2026-10-01 用户要求)。样式与 JS 一并删除,需要恢复看 git 历史 70c9786。 -->
|
||
|
||
<!-- 3D 婴儿房 · 「透过页面看到后面的房间」(2026-10-01 三版)。用户原话:
|
||
「把那个房间整体……铺到它的后边……两个模块中间,它不用点击,从外边其实就能看到这个里边是什么,
|
||
整个铺到这个背景的后边,有一个引导进入的按钮,我点进去再弹出这个新的页面」。
|
||
做法:这一块没有底色,是页面上开的一道「空隙」;房间图层(#nypLayer)由 JS 每次滚动都对齐到 .screen 的可视区,
|
||
所以页面往上滚时房间不跟着走,看起来就是铺在整页背后、从缝里露出来(视差)。上下两条内阴影 = 上下模块压在房间上面。
|
||
只有「进去布置」按钮能点(整块不点,免得滚动时误触)。
|
||
图: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 用户反馈过));里面摆的是演示布置,不是用户自己的房间。
|
||
底色必须和图边一致:白天 #FFECD8、夜间 #5A5890,否则缝里会露出图片边框。
|
||
位置:今天的动线 → 这道空隙 → 书架(首页后半段)。北京时间 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.jpg" alt="" decoding="async"></div>
|
||
<span class="nyp-chip">往里看看 · 3D 婴儿房</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>
|
||
|
||
<!-- 模块三 · 书架卡带。
|
||
上一版是「一张横排大卡 + 下面两张小卡」的老三段,和上面两个模块
|
||
一样都是往下堆。这里改成一条横向可滑的书架:三张等宽等高的**竖版**书
|
||
(封面在上、书名在下、免费标在底),右边故意露出下一张的边角,
|
||
不用画箭头也知道能往右滑。整页因此多了一段「可以往右读」的节奏 ——
|
||
这是最直观的一处排版变化。
|
||
资源这类内容对可发现性的要求低(不像工具是每天要点的),
|
||
收进横滑里是合适的;工具那一屏就没这么干。
|
||
|
||
⚠️ data-wk="n" 是从原来那条 h2 里搬过来的。app.js 用
|
||
$$('[data-wk]') 全局扫,属性一丢孕周就永远显示「—」。 -->
|
||
<section class="shelf">
|
||
<div class="shelf-bar">
|
||
<h2 class="sh-title">本周孕育指南 · 孕<span data-wk="n">—</span>周</h2>
|
||
<button class="sh-all" data-open="detailResList">全部 ›</button>
|
||
</div>
|
||
<p class="sh-note">适配孕周的专属孕育参考资料</p>
|
||
<!-- 三张卡的内部结构是**逐行对齐**的:封面 / 标题 / 简介 / 底行,一个不缺。
|
||
上一稿只有第一张有简介、也只有第一张有「立即领取」,另两张少两截,
|
||
于是三张卡的标题落在不同高度、底行也不齐 —— 这就是看着乱的原因。
|
||
封面给了固定高度(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">
|
||
<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">
|
||
<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">
|
||
<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"><b>128</b> 份孕育资料等你来领 · <a data-open="detailResList">查看全部 ›</a></p>
|
||
</section>
|
||
|
||
</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">
|
||
<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> 是下面的「已连续记录」,
|
||
谁要是把那行加回来,会把连续记录天数冲掉,而且是静默的。 -->
|
||
<p id="meRecordLine">已连续记录 <b>42</b> 天</p>
|
||
</div>
|
||
<i class="me-chev" aria-hidden="true">›</i>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="page-body no-top">
|
||
<!-- 授权完善资料:H5 → navigateTo → 小程序授权页(头像/昵称/手机号) → box_app /auth/profile 落库 -->
|
||
<div class="list-card" style="margin-top:12px" 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>
|
||
|
||
<!-- 退出登录已移到个人资料卡右上角的图标按钮(#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,宽裕。 -->
|
||
<h2 class="sec-title dark">孕期信息<span class="sec-req">(必填)</span> <button class="sec-more" data-modal="modalProfile">编辑 ›</button></h2>
|
||
<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="#FFFFFF" stroke-opacity=".3" stroke-width="3.2"/>
|
||
<circle id="pcRing" cx="16" cy="16" r="11.6" fill="none" stroke="#FFFFFF" 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="#FFFFFF"/>
|
||
<path d="M13.8 17.2c.3 3.6 3 5.1 6 4.1" fill="none" stroke="#FFFFFF" 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>
|
||
|
||
<!-- ================= 孕育顾问(企业微信入口) =================
|
||
常驻在孕期卡下面:上面那张卡讲「你走到哪儿了」,这张接着说
|
||
「路上有人陪你」,是同一段话的下一句;而「设置与服务」那组是
|
||
工具箱,把一个真人服务塞进去会被当成一行设置项划过去。
|
||
⚠️ 故意**不挂 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>
|
||
|
||
<h2 class="sec-title dark">甄选好物</h2>
|
||
<button class="wx-card ripple" id="meMallCard">
|
||
<!-- 「甄选好物」角标已按需求去掉(.wx-top 角标行整行移除;孕育顾问那条"限量福利"不受影响) -->
|
||
<span class="wx-body">
|
||
<!-- 逛商城入口:购物袋图标(同 .wx-fig 76×拉伸高) -->
|
||
<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="M19 25h26l-2.1 23.2a3.4 3.4 0 0 1-3.4 3H25.5a3.4 3.4 0 0 1-3.4-3L19 25z" fill="#fff" stroke="#E8A98C" stroke-width="1.7" stroke-linejoin="round"/>
|
||
<path d="M26 25a6 6 0 0 1 12 0" fill="none" stroke="#D85F38" stroke-width="1.9" stroke-linecap="round"/>
|
||
<path d="M27.5 35h9M27.5 41h9" stroke="#F2C7B3" stroke-width="1.8" stroke-linecap="round"/>
|
||
</svg>
|
||
</span>
|
||
<span class="wx-main">
|
||
<span class="wx-head">
|
||
<span class="wx-title">兜爸心选商城</span>
|
||
<span class="wx-lim">母婴 · 好物</span>
|
||
</span>
|
||
<span class="wx-sub">为宝宝甄选的母婴好物,值得认真挑一挑</span>
|
||
</span>
|
||
</span>
|
||
<span class="wx-cta">进入商城</span>
|
||
</button>
|
||
|
||
<h2 class="sec-title dark">设置与服务</h2>
|
||
<div class="list-card">
|
||
<!-- 「提醒设置」整项已按需求删除 -->
|
||
<!-- 孕期盲盒卡册的常驻入口(2026-10-01 用户反馈:开完盲盒后想回看,只认首页横幅不够)。
|
||
点击与首页横幅同一路径(app.js openBoxEntry);#meBoxV 显示「已收集 N/37」,未拿到数据时隐藏整行。 -->
|
||
<button class="li ripple hide" id="meBoxCard">
|
||
<span class="li-ico o"><svg viewBox="0 0 24 24" width="19" height="19" 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="li-t">我的孕期卡册</span><span class="li-v" id="meBoxV"></span><i class="chev">›</i></button>
|
||
<button class="li ripple" data-open="detailSetting" data-set="privacy">
|
||
<span class="li-ico p"><svg viewBox="0 0 24 24" width="19" height="19" 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="li-t">隐私与权限</span><i class="chev">›</i></button>
|
||
<button class="li ripple" data-open="detailSetting" data-set="help">
|
||
<span class="li-ico o"><svg viewBox="0 0 24 24" width="19" height="19" 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="li-t">帮助与反馈</span><i class="chev">›</i></button>
|
||
<button class="li ripple" data-open="detailSetting" data-set="about">
|
||
<span class="li-ico b"><svg viewBox="0 0 24 24" width="19" height="19" 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="li-t">关于兜爸心选</span><span class="li-v">v3.2.1</span><i class="chev">›</i></button>
|
||
<!-- 退出授权登录:仅已授权时显示(applyRemoteProfile 控制)。
|
||
调 box_app /auth/logout —— 只翻授权状态,不清昵称/头像/手机号等资料 -->
|
||
<button class="li ripple" id="meLogoutCard" style="display:none">
|
||
<span class="li-ico r"><svg viewBox="0 0 24 24" width="19" height="19" aria-hidden="true"><path d="M14 5h5a1.5 1.5 0 0 1 1.5 1.5v11A1.5 1.5 0 0 1 19 19h-5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/><path d="M10 12H3m0 0 3.5-3.5M3 12l3.5 3.5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
|
||
<span class="li-t" style="color:#C33A2E">退出授权登录</span>
|
||
<i class="chev">›</i></button>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
|
||
|
||
<!-- ================= 孕期小知识 详情页(2026-10-01)=================
|
||
首页 #pregTips 只放标题 + 一行摘要,完整内容都在这里:今天这条全文 + 本周 7 天回看 + 四张卡全文 + 免责。
|
||
各 id(ptT/ptD/ptDays/ptBaby…)仍由 renderTips()/showTip() 写,只是从首页搬到了这一页。 -->
|
||
<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">
|
||
<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>
|
||
<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>
|
||
<!-- ⚠️ 临时隐藏(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">✕</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>
|
||
|
||
<div class="apps-head for-all">全部孕期工具 <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>
|
||
|
||
<!-- 盲盒 · 分段集齐达成的庆祝弹层(内容由 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>
|
||
|
||
<section class="modal" id="modalProfile" 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>
|
||
|
||
<!-- 头像:点圆形区域直接唤起系统相册;file input 藏起来但不能 display:none,
|
||
否则部分安卓 WebView 点不动,所以用 0 尺寸 + opacity 的写法 -->
|
||
<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">
|
||
<div class="av-tip">点一下换张照片 · 只存在你自己的手机上</div>
|
||
</div>
|
||
|
||
<!-- ⚠️ 这里原来第二格是「一句话签名」#pfBio,本批按用户要求**删掉了**,别加回来。
|
||
连带删的还有「我的」页头像旁那行 #meBio 和 js 里的 syncBio() ——
|
||
必须一起走:只删输入框、留着展示行,那行就变成一句谁也改不动的死文案,
|
||
比没有更糟(用户会在资料页里翻来翻去找哪儿能改它)。
|
||
|
||
⚠️ 昵称(妈妈)和宝宝小名并成一行,是上面高度预算里省下的那 78px。
|
||
两格都是短文本,半行宽装得下:.fld input 左右内边 15×2 = 30,
|
||
半行宽 = (弹窗内容宽 - gap 12) / 2 ≈ (386-12)/2 = 187,
|
||
可写 157px ÷ 14px 字 ≈ 11 个汉字,而 maxlength 分别是 16 / 12 ——
|
||
填满会在框内横向滚动,不会破版。这是可接受的,别为此把它拆回两行。 -->
|
||
<div class="fld-row">
|
||
<!-- ⚠️ 不写死演示默认值(原 value="小满妈妈"/"小汤圆"已删):打开弹窗时由
|
||
fillProfileForm() 按服务端档案回填,新用户全空 + placeholder 提示 -->
|
||
<label class="fld"><span>昵称</span><input id="pfName" type="text" maxlength="16" placeholder="妈妈"></label>
|
||
<label class="fld"><span>宝宝小名</span><input id="pgName" type="text" maxlength="12" placeholder="宝宝"></label>
|
||
</div>
|
||
<div class="fld">
|
||
<span>宝宝性别</span>
|
||
<!-- 性别会随档案一起保存(PUT /profile 的 babySex 字段)。 -->
|
||
<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>
|
||
<!-- 预产期排在孕周前面:它是「源」,填了才解锁下面两格。
|
||
默认值不写死在标记里 —— 由 JS 按「打开这一刻 + 3 个月」现算 -->
|
||
<!-- 原生 date 空值时是一片空白(不支持 placeholder),叠一层文字占位:
|
||
有值由 JS 隐藏(fillProfileForm / pgDue change 都会调 syncDuePh) -->
|
||
<label class="fld fld-date"><span>预产期</span>
|
||
<span class="due-box"><input id="pgDue" type="date"><span class="date-ph" id="pgDuePh">- 年 - 月 - 日</span></span>
|
||
</label>
|
||
<div class="fld-row">
|
||
<!-- 孕周/天数由预产期自动算出,打开时按档案回填;新用户留空并锁定 -->
|
||
<label class="fld"><span>当前孕周</span><input id="pgWeek" type="number" min="0" max="42" placeholder="—" disabled></label>
|
||
<label class="fld"><span>额外天数</span><input id="pgDay" type="number" min="0" max="6" placeholder="—" disabled></label>
|
||
</div>
|
||
<p class="fld-hint" id="pgHint">填完预产期后自动算出,算得不准可以自己微调。</p>
|
||
<div class="modal-foot">
|
||
<button class="dl-btn ghost" data-modal="close">取消</button>
|
||
<!-- ⚠️ 只剩这一个保存按钮。原 #pgSave 已随 modalPreg 一起删除,
|
||
它那套逻辑(校验预产期、夹取孕周天数、写 state、调 syncPregnancy())
|
||
整段并进了 js 里的 #pfSave 处理器。 -->
|
||
<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/app.js"></script>
|
||
|
||
</body>
|
||
</html>
|