973 lines
66 KiB
HTML
973 lines
66 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
|
||
<meta name="format-detection" content="telephone=no">
|
||
<title>生娃计算器 · 到底要花多少钱</title>
|
||
<!-- 孕期专题 · 生娃计算器(孕期首页「其他妈妈也在搜」第 1 条入口)。
|
||
2026-10-31 v3:按 /tmp/pl/topic-spec-v3.md(在 v2 规范上加设计感)重做;主色 #18A058,浅底 #EAF7F0。
|
||
用户反馈「可选维度太少」→ 扩到 15 题(奶粉档次是条件题,母乳为主时自动跳过),分 3 组:
|
||
孕期与分娩:城市 / 产检方案 / 医院 / 分娩方式 / 医保类型 / 第几胎
|
||
月子与喂养:月子方式 / 喂养方式 / 奶粉档次(条件) / 待产包与婴儿用品档次 / 纸尿裤与洗护档次
|
||
0~3 岁养育:1~3 岁谁带(含 2 岁上托班) / 早教兴趣班 / 自费疫苗 / 商业保险
|
||
v2 的「花钱风格」已拆进各档次题里,不再单独问。
|
||
入口:30 秒快速估算(5 题,其余按常见)/ 详细估算(全部);每题可「跳过,按常见情况算」;结果页点选择标签单独改一题。
|
||
每个题都在 COST 表里有对应项目(见 calc() 的 item id),改价格只改脚本顶部 COST 表。
|
||
选择存 localStorage「mmbox.huafei.v3」(首次进来会兼容读取 v2 的旧选择)。
|
||
推荐工具走 ../_shared/tools.js;自成一页:不引 app.js;返回走 history.back 或相对路径 ../../ 并带回 search + hash。
|
||
v2 备份 /tmp/pl/huafei-v2-before-v3.html。 -->
|
||
<style>
|
||
:root{--c:#18A058;--cbg:#EAF7F0;--c4:#F5FBF8;--h:#1F2329;--t:#4E5969;--s:#86909C;--line:#EEF0F3;--gray:#F7F8FA}
|
||
*{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}
|
||
html,body{height:100%;overflow:hidden;background:#fff;color:var(--t);font:15px/1.75 -apple-system,BlinkMacSystemFont,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif}
|
||
#scroll{position:fixed;inset:0;overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;overscroll-behavior:none;padding-bottom:calc(28px + env(safe-area-inset-bottom))}
|
||
img{display:block;max-width:100%}
|
||
button{font:inherit;border:0;background:none;color:inherit;cursor:pointer}
|
||
.num{font-family:"DIN Alternate","Helvetica Neue",Arial,sans-serif;font-variant-numeric:tabular-nums}
|
||
.ic{width:20px;height:20px;flex:none;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
|
||
.hide{position:absolute;width:0;height:0;overflow:hidden}
|
||
.press{transition:transform .15s}
|
||
.press:active{transform:scale(.98)}
|
||
|
||
/* 顶栏 */
|
||
.bar{position:sticky;top:0;z-index:20;display:flex;align-items:center;gap:4px;height:48px;padding:0 8px;padding-top:env(safe-area-inset-top);background:rgba(255,255,255,0);border-bottom:1px solid transparent;transition:background .2s,border-color .2s}
|
||
.bar.on{background:#fff;border-bottom-color:var(--line)}
|
||
.bar .back{width:36px;height:36px;border-radius:50%;display:grid;place-items:center;color:var(--h)}
|
||
.bar .back .ic{width:22px;height:22px}
|
||
.bar .t{font-size:16px;font-weight:600;color:var(--h)}
|
||
|
||
/* 浅渐变背景 + 柔和大圆(开始屏、结果屏共用) */
|
||
.bg{position:absolute;left:0;right:0;top:0;height:520px;background:linear-gradient(160deg,var(--cbg) 0%,#fff 70%);overflow:hidden;pointer-events:none;z-index:0}
|
||
.bg i{position:absolute;border-radius:50%;background:rgba(24,160,88,.08)}
|
||
.bg i:nth-child(1){width:280px;height:280px;right:-100px;top:-90px}
|
||
.bg i:nth-child(2){width:130px;height:130px;left:-56px;top:240px;background:rgba(24,160,88,.06)}
|
||
|
||
.screen{display:none;position:relative;z-index:1;padding:0 20px}
|
||
.screen.on{display:block;animation:fd .35s ease both}
|
||
@keyframes fd{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
|
||
.fu{opacity:0;transform:translateY(12px);transition:opacity .45s ease,transform .45s ease}
|
||
.fu.in{opacity:1;transform:none}
|
||
@media (prefers-reduced-motion:reduce){.screen.on{animation:none}.fu{opacity:1;transform:none;transition:none}}
|
||
|
||
.btn{display:flex;align-items:center;justify-content:center;width:100%;height:46px;border-radius:99px;background:var(--c);color:#fff;font-size:16px;font-weight:600}
|
||
.btn.ghost{background:#fff;color:var(--c);border:1px solid var(--c)}
|
||
.chip{display:inline-block;font-size:12px;font-weight:600;line-height:22px;padding:0 10px;border-radius:99px;background:var(--cbg);color:var(--c)}
|
||
.mk{background:linear-gradient(transparent 62%,rgba(24,160,88,.2) 0)}
|
||
|
||
/* ============ 开始屏 ============ */
|
||
.hero{position:relative;padding-top:6px}
|
||
h1{margin-top:10px;font-size:28px;font-weight:800;line-height:1.32;color:var(--h)}
|
||
.lede{margin-top:8px;font-size:14px;color:var(--s);line-height:1.6}
|
||
.pic{position:relative;margin:18px -20px 0 26%;height:184px;border-radius:24px 0 0 24px;overflow:hidden;background:#fff}
|
||
.pic img{width:100%;height:100%;object-fit:cover;object-position:40% 60%}
|
||
.badge{position:absolute;left:0;top:150px;z-index:2;display:flex;align-items:center;gap:10px;padding:10px 14px 10px 10px;border-radius:16px;background:#fff;box-shadow:0 8px 24px rgba(24,160,88,.12)}
|
||
.badge .bi{flex:none;width:34px;height:34px;border-radius:11px;background:var(--cbg);color:var(--c);display:grid;place-items:center}
|
||
.badge b{display:block;font-size:20px;font-weight:800;line-height:1.1;color:var(--h)}
|
||
.badge span{display:block;font-size:11.5px;color:var(--s);line-height:1.4}
|
||
|
||
.ans{margin-top:22px;padding:16px 18px 18px;border-radius:20px;background:#fff;box-shadow:0 8px 24px rgba(24,160,88,.10)}
|
||
.ans p{margin-top:8px;font-size:17px;font-weight:700;line-height:1.6;color:var(--h)}
|
||
.ans p em{font-style:normal;color:var(--c)}
|
||
|
||
.entries{margin-top:22px;display:flex;flex-direction:column;gap:10px}
|
||
.entry{display:flex;align-items:center;gap:14px;width:100%;padding:16px 16px;border-radius:20px;text-align:left}
|
||
.entry .ei{flex:none;width:44px;height:44px;border-radius:14px;display:grid;place-items:center}
|
||
.entry .ei .ic{width:22px;height:22px}
|
||
.entry .ex{flex:1;min-width:0}
|
||
.entry b{display:block;font-size:17px;font-weight:800;line-height:1.35}
|
||
.entry small{display:block;margin-top:2px;font-size:13px;line-height:1.45}
|
||
.entry .ar{flex:none;width:18px;height:18px}
|
||
.entry.q{background:var(--c);color:#fff;box-shadow:0 8px 20px rgba(24,160,88,.22)}
|
||
.entry.q .ei{background:rgba(255,255,255,.18)}
|
||
.entry.q small{color:rgba(255,255,255,.85)}
|
||
.entry.d{background:#fff;border:1.5px solid var(--line);color:var(--h)}
|
||
.entry.d .ei{background:var(--cbg);color:var(--c)}
|
||
.entry.d small{color:var(--s)}
|
||
.entry.d .ar{color:#C0C5CC}
|
||
.last{display:none;margin:12px auto 0;padding:4px 10px;font-size:14px;color:var(--c);font-weight:600}
|
||
.last.on{display:block}
|
||
|
||
.sec-h{display:flex;align-items:baseline;gap:8px}
|
||
.sec-h .n{flex:none;font-size:13px;font-weight:800;color:var(--c);letter-spacing:.04em}
|
||
.sec-h h2{font-size:18px;font-weight:700;line-height:1.4;color:var(--h)}
|
||
.sec-h small{margin-left:auto;font-size:11px;letter-spacing:.14em;color:#C9CDD4;font-weight:600}
|
||
.groups{margin-top:40px}
|
||
.gg{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-top:12px}
|
||
.gc{padding:12px 10px 14px;border-radius:18px;background:var(--c4);border:1px solid #DDF0E5}
|
||
.gc .no{display:block;font-size:34px;font-weight:800;line-height:1;color:transparent;-webkit-text-stroke:1.4px var(--c)}
|
||
.gc b{display:block;margin-top:10px;font-size:14px;line-height:1.45;color:var(--h)}
|
||
.gc span{display:block;margin-top:4px;font-size:12px;color:var(--s);line-height:1.5}
|
||
.tiny{margin-top:18px;font-size:12.5px;color:var(--s);text-align:center;line-height:1.6}
|
||
|
||
/* ============ 问题屏 ============ */
|
||
.gp{display:flex;gap:6px;margin-top:6px}
|
||
.gp .seg{flex:1;min-width:0}
|
||
.gp .tr{height:5px;border-radius:9px;background:var(--line);overflow:hidden}
|
||
.gp .tr i{display:block;height:100%;width:0;border-radius:9px;background:var(--c);transition:width .3s}
|
||
.gp .gl{display:block;margin-top:5px;font-size:11.5px;color:#B5BAC2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:color .2s}
|
||
.gp .seg.cur .gl{color:var(--c);font-weight:700}
|
||
.gp .seg.off{opacity:.35}
|
||
.qn{margin-top:22px;display:flex;align-items:center;gap:8px;font-size:13px;color:var(--s)}
|
||
.qn b{font-size:13px;color:var(--c);font-weight:800}
|
||
.qh{margin-top:6px;font-size:23px;font-weight:800;line-height:1.35;color:var(--h)}
|
||
.qs{margin-top:4px;font-size:13.5px;color:var(--s)}
|
||
.opts{margin-top:18px;display:flex;flex-direction:column;gap:10px}
|
||
.opt{display:flex;align-items:center;gap:12px;width:100%;min-height:72px;padding:12px 14px;border-radius:18px;border:1.5px solid var(--line);background:#fff;text-align:left;transition:border-color .15s,background .15s,transform .15s}
|
||
.opt:active{transform:scale(.98)}
|
||
.opt .oi{flex:none;width:42px;height:42px;border-radius:13px;background:var(--c4);color:var(--c);display:grid;place-items:center;transition:background .15s,color .15s}
|
||
.opt .oi .ic{width:22px;height:22px}
|
||
.opt .ox{flex:1;min-width:0}
|
||
.opt b{display:block;font-size:16px;font-weight:700;color:var(--h);line-height:1.4}
|
||
.opt b em{display:inline-block;vertical-align:2px;margin-left:6px;font-style:normal;font-size:10.5px;font-weight:600;line-height:17px;padding:0 6px;border-radius:99px;background:var(--gray);color:var(--s)}
|
||
.opt small{display:block;margin-top:1px;font-size:12.5px;color:var(--s);line-height:1.45}
|
||
.opt .pp{display:block;margin-top:3px;font-size:12.5px;font-weight:700;color:var(--c);line-height:1.4;font-variant-numeric:tabular-nums}
|
||
.opt .rd{flex:none;width:22px;height:22px;border-radius:50%;border:1.5px solid #D5D9DE;display:grid;place-items:center}
|
||
.opt.on{border-color:var(--c);background:var(--c4)}
|
||
.opt.on .oi{background:var(--c);color:#fff}
|
||
.opt.on .rd{border-color:var(--c);background:var(--c)}
|
||
.opt.on .rd::after{content:"";width:8px;height:8px;border-radius:50%;background:#fff}
|
||
.qa{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:20px}
|
||
.prev{display:inline-flex;align-items:center;gap:2px;padding:8px 4px;font-size:14px;color:var(--s)}
|
||
.prev .ic{width:18px;height:18px}
|
||
.skip{height:36px;padding:0 14px;border-radius:99px;border:1px solid var(--line);font-size:13.5px;color:var(--t);background:#fff;white-space:nowrap}
|
||
.qtip{margin-top:12px;font-size:12px;color:#B5BAC2;text-align:center}
|
||
|
||
/* ============ 结果屏 ============ */
|
||
.r-top{display:flex;align-items:center;gap:8px;margin-top:6px}
|
||
.r-top .md{font-size:12.5px;color:var(--s)}
|
||
.r-t{margin-top:8px;font-size:26px;font-weight:800;line-height:1.3;color:var(--h)}
|
||
.sgc{position:relative;display:flex;margin-top:16px;padding:4px;border-radius:99px;background:rgba(255,255,255,.75);border:1px solid #DDF0E5}
|
||
.sgc .th{position:absolute;top:4px;bottom:4px;left:4px;width:calc((100% - 8px) / 4);border-radius:99px;background:var(--c);box-shadow:0 4px 10px rgba(24,160,88,.25);transition:transform .3s cubic-bezier(.3,.7,.4,1)}
|
||
.sgc button{position:relative;z-index:1;flex:1;min-width:0;height:36px;border-radius:99px;font-size:14px;color:var(--t);white-space:nowrap;transition:color .25s}
|
||
.sgc button.on{color:#fff;font-weight:700}
|
||
.tot{margin-top:14px;padding:20px 18px 16px;border-radius:24px;background:#fff;box-shadow:0 8px 24px rgba(24,160,88,.10)}
|
||
.tot .l{font-size:13px;color:var(--s)}
|
||
.tot .v{margin-top:4px;display:flex;align-items:baseline;flex-wrap:wrap;color:var(--h);line-height:1.15}
|
||
.tot .v .n{font-size:clamp(34px,10.4vw,42px);font-weight:800;letter-spacing:-.5px}
|
||
.tot .v .td{margin:0 4px;font-size:26px;font-weight:700;color:#C0C5CC}
|
||
.tot .v .u{margin-left:4px;font-size:16px;font-weight:700;color:var(--t)}
|
||
.tot .bar2{position:relative;height:8px;margin-top:14px;border-radius:9px;background:var(--gray);overflow:hidden}
|
||
.tot .bar2 i{position:absolute;top:0;bottom:0;border-radius:9px;background:linear-gradient(90deg,#79CC9E,var(--c));transition:left .5s,width .5s}
|
||
.tot .sc{display:flex;justify-content:space-between;margin-top:4px;font-size:11px;color:#B5BAC2}
|
||
.kv{display:grid;grid-template-columns:1fr 1fr;margin-top:12px;padding-top:12px;border-top:1px dashed var(--line)}
|
||
.kv div{min-width:0}
|
||
.kv div+div{padding-left:14px;border-left:1px solid var(--line)}
|
||
.kv span{display:block;font-size:12px;color:var(--s)}
|
||
.kv b{display:block;margin-top:2px;font-size:16px;font-weight:800;color:var(--h);white-space:nowrap}
|
||
.kv b.g{color:var(--c)}
|
||
.more{display:none;align-items:center;gap:10px;width:100%;margin-top:12px;padding:12px 14px;border-radius:18px;background:var(--cbg);text-align:left}
|
||
.more.on{display:flex}
|
||
.more .ic{color:var(--c)}
|
||
.more span{flex:1;min-width:0;font-size:13.5px;color:var(--t);line-height:1.5}
|
||
.more span b{color:var(--h)}
|
||
.more em{flex:none;font-style:normal;font-size:13px;font-weight:700;color:var(--c)}
|
||
|
||
.rs{margin-top:40px}
|
||
.panel{margin:14px -6px 0;padding:18px 16px;border-radius:24px;background:var(--gray)}
|
||
.panel.g{background:var(--c4)}
|
||
.donut{display:flex;align-items:center;gap:14px}
|
||
.donut svg{flex:none;width:136px;height:136px}
|
||
.donut circle{transition:stroke-dasharray .5s ease,stroke-dashoffset .5s ease,stroke .3s}
|
||
.donut .ct1{font-size:10px;fill:var(--s)}
|
||
.donut .ct2{font-size:15px;font-weight:800;fill:var(--h)}
|
||
.donut .ct3{font-size:12px;font-weight:700;fill:var(--c)}
|
||
.lg{flex:1;min-width:0;display:flex;flex-direction:column;gap:6px}
|
||
.lg div{display:flex;align-items:center;gap:7px;font-size:13px;color:var(--h);line-height:1.4}
|
||
.lg i{flex:none;width:9px;height:9px;border-radius:3px}
|
||
.lg span{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||
.lg b{font-size:13px;font-weight:700;font-variant-numeric:tabular-nums}
|
||
.lg .off{color:#C0C5CC}
|
||
.lg .off b{font-weight:400;font-size:12px}
|
||
.list{margin-top:14px;background:#fff;border-radius:18px;padding:0 14px}
|
||
.list details+details{border-top:1px solid var(--line)}
|
||
.list summary{list-style:none;display:flex;align-items:center;gap:10px;padding:13px 0;cursor:pointer}
|
||
.list summary::-webkit-details-marker{display:none}
|
||
.list .dot{flex:none;width:10px;height:10px;border-radius:3px}
|
||
.list .nm{flex:1;min-width:0;font-size:15px;color:var(--h)}
|
||
.list .rg{font-size:15px;font-weight:700;color:var(--h);white-space:nowrap;font-variant-numeric:tabular-nums}
|
||
.list .ar{flex:none;width:16px;height:16px;color:#C0C5CC;transition:transform .2s}
|
||
.list details[open] .ar{transform:rotate(180deg)}
|
||
.list .ds{padding:0 0 12px 20px}
|
||
.list .it{display:flex;justify-content:space-between;gap:10px;font-size:13px;color:var(--t);line-height:1.8}
|
||
.list .it b{font-weight:600;color:var(--h);white-space:nowrap;font-variant-numeric:tabular-nums}
|
||
.list .it.minus b{color:var(--c)}
|
||
.list details.off .nm,.list details.off .rg{color:#C0C5CC;font-weight:400}
|
||
.list details.off .rg{font-size:13px}
|
||
|
||
.mine{margin-top:14px}
|
||
.mg+.mg{margin-top:12px}
|
||
.mg .mh{font-size:12px;color:var(--s);font-weight:600}
|
||
.tags{margin-top:6px;display:flex;flex-wrap:wrap;gap:8px}
|
||
.tags button{display:inline-flex;align-items:center;gap:4px;height:32px;padding:0 12px;border-radius:99px;background:#fff;border:1px solid #CFEBDB;font-size:13px;color:var(--h);transition:transform .15s}
|
||
.tags button:active{transform:scale(.96)}
|
||
.tags button .ic{width:13px;height:13px;color:var(--c)}
|
||
.tags button.df{border-style:dashed;border-color:#D5D9DE;color:var(--s)}
|
||
.tags button.df .ic{color:#C0C5CC}
|
||
.tags button.df i{font-style:normal;font-size:11px;color:#B5BAC2}
|
||
|
||
.card{margin-top:14px;padding:16px;border-radius:20px;border:1px solid var(--line);background:#fff}
|
||
.row{display:flex;gap:12px;align-items:flex-start}
|
||
.row+.row{margin-top:14px;padding-top:14px;border-top:1px solid var(--line)}
|
||
.row .ri{flex:none;width:36px;height:36px;border-radius:12px;background:var(--cbg);color:var(--c);display:grid;place-items:center}
|
||
.row .rx{flex:1;min-width:0}
|
||
.row b{display:block;font-size:15px;color:var(--h);line-height:1.5}
|
||
.row b em{font-style:normal;color:var(--c)}
|
||
.row p{font-size:13.5px;color:var(--t);line-height:1.65}
|
||
.row ul{list-style:none}
|
||
.row li{position:relative;padding-left:12px;font-size:13.5px;color:var(--t);line-height:1.65}
|
||
.row li+li{margin-top:4px}
|
||
.row li::before{content:"";position:absolute;left:0;top:.72em;width:5px;height:5px;border-radius:50%;background:var(--c)}
|
||
.back-money{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:12px}
|
||
.back-money div{padding:10px 12px;border-radius:14px;background:var(--c4)}
|
||
.back-money span{display:block;font-size:11.5px;color:var(--s);line-height:1.4}
|
||
.back-money b{display:block;margin-top:2px;font-size:17px;font-weight:800;color:var(--c);white-space:nowrap}
|
||
.back-money small{display:block;font-size:11px;color:var(--s);line-height:1.4}
|
||
.fml{display:inline-block;margin-top:8px;padding:4px 10px;border-radius:10px;background:var(--gray);font-size:12px;color:var(--h);line-height:1.6}
|
||
.acts{margin-top:28px}
|
||
.note{margin-top:14px;font-size:12px;color:var(--s);line-height:1.6;text-align:center}
|
||
.note b{color:var(--t)}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<svg class="hide" aria-hidden="true" xmlns="http://www.w3.org/2000/svg">
|
||
<symbol id="i-back" viewBox="0 0 24 24"><path d="M15 5l-7 7 7 7"/></symbol>
|
||
<symbol id="i-right" viewBox="0 0 24 24"><path d="M9 5l7 7-7 7"/></symbol>
|
||
<symbol id="i-down" viewBox="0 0 24 24"><path d="M6 9l6 6 6-6"/></symbol>
|
||
<symbol id="i-edit" viewBox="0 0 24 24"><path d="M4 20h4L19 9l-4-4L4 16z"/><path d="M13.5 6.5l4 4"/></symbol>
|
||
<symbol id="i-bolt" viewBox="0 0 24 24"><path d="M13 3L5 13.5h6L10 21l8-10.5h-6z"/></symbol>
|
||
<symbol id="i-list" viewBox="0 0 24 24"><path d="M9 6h11M9 12h11M9 18h11"/><circle cx="4.5" cy="6" r="1"/><circle cx="4.5" cy="12" r="1"/><circle cx="4.5" cy="18" r="1"/></symbol>
|
||
<symbol id="i-coin" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><path d="M9 7.5l3 4 3-4M12 11.5V17M9 12.5h6M9 15h6"/></symbol>
|
||
<symbol id="i-bulb" viewBox="0 0 24 24"><path d="M9 18.5h6M10.2 21.5h3.6M12 3a6 6 0 0 0-4 10.5c.7.7 1 1.5 1 2.5h6c0-1 .3-1.8 1-2.5A6 6 0 0 0 12 3z"/></symbol>
|
||
<symbol id="i-gift" viewBox="0 0 24 24"><rect x="3.5" y="8" width="17" height="4" rx="1"/><path d="M5 12v8h14v-8M12 8v12M12 8c-1.5-3-5-3.5-5-1.2C7 8 9 8 12 8zM12 8c1.5-3 5-3.5 5-1.2C17 8 15 8 12 8z"/></symbol>
|
||
<!-- 选项图标 -->
|
||
<symbol id="o-bldg" viewBox="0 0 24 24"><path d="M3 21h18M5 21V9l5-3v15M10 21V3l9 4v14M13.5 9h2M13.5 12.5h2M13.5 16h2M7 12h1M7 15.5h1"/></symbol>
|
||
<symbol id="o-bldg2" viewBox="0 0 24 24"><path d="M3 21h18M5 21V10h6v11M11 21V6h8v15M14 9.5h2M14 13h2M14 16.5h2M7.5 13.5h1M7.5 17h1"/></symbol>
|
||
<symbol id="o-house" viewBox="0 0 24 24"><path d="M3.5 11L12 4l8.5 7M6 9.5V20h12V9.5"/><path d="M10 20v-5h4v5"/></symbol>
|
||
<symbol id="o-tree" viewBox="0 0 24 24"><path d="M2.5 13L8 8.5l5.5 4.5M4.5 11.5V20h7v-8.5"/><path d="M17.5 20v-5M17.5 4.5c-2.2 0-3.5 2.5-3.5 5 0 2.8 1.6 4.5 3.5 4.5s3.5-1.7 3.5-4.5c0-2.5-1.3-5-3.5-5zM2 20h20"/></symbol>
|
||
<symbol id="o-clip" viewBox="0 0 24 24"><rect x="5" y="4.5" width="14" height="16.5" rx="2"/><path d="M9 4.5V3.5h6v1M8.5 10h7M8.5 13.5h7M8.5 17h4"/></symbol>
|
||
<symbol id="o-dna" viewBox="0 0 24 24"><path d="M7 3c0 6 10 6 10 12 0 3-2 4.5-2 6M17 3c0 6-10 6-10 12 0 3 2 4.5 2 6M8.5 7h7M8.5 17h7"/></symbol>
|
||
<symbol id="o-scan" viewBox="0 0 24 24"><rect x="3" y="4" width="18" height="13" rx="2"/><path d="M8 21h8M12 17v4M6.5 12c1.5-3 3-3 4.5 0s3 3 4.5 0"/></symbol>
|
||
<symbol id="o-hosp" viewBox="0 0 24 24"><path d="M4 21V7l8-4 8 4v14M2.5 21h19"/><path d="M12 8v6M9 11h6M10 21v-3h4v3"/></symbol>
|
||
<symbol id="o-bed" viewBox="0 0 24 24"><path d="M3 6v13M3 15h18v4M21 15v-3a3 3 0 0 0-3-3h-7v6"/><circle cx="7" cy="11.5" r="2"/></symbol>
|
||
<symbol id="o-star" viewBox="0 0 24 24"><path d="M12 3.5l2.6 5.3 5.9.9-4.3 4.1 1 5.8L12 16.9l-5.2 2.7 1-5.8L3.5 9.7l5.9-.9z"/></symbol>
|
||
<symbol id="o-leaf" viewBox="0 0 24 24"><path d="M5 19c0-8 5-14 15-15-1 10-7 15-15 15z"/><path d="M5 19l8-8"/></symbol>
|
||
<symbol id="o-cut" viewBox="0 0 24 24"><path d="M4 12h16"/><path d="M6 9.5v5M10 9.5v5M14 9.5v5M18 9.5v5"/></symbol>
|
||
<symbol id="o-help" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><path d="M9.5 9.5a2.5 2.5 0 1 1 3.5 2.3c-.6.3-1 .9-1 1.6v.6M12 17h.01"/></symbol>
|
||
<symbol id="o-shield" viewBox="0 0 24 24"><path d="M12 3l7 3v5c0 5-3 8-7 10-4-2-7-5-7-10V6z"/><path d="M9 12l2 2 4-4"/></symbol>
|
||
<symbol id="o-card" viewBox="0 0 24 24"><rect x="3" y="5.5" width="18" height="13" rx="2"/><circle cx="8.5" cy="11" r="2"/><path d="M5.5 15.5c.6-1.4 1.7-2 3-2s2.4.6 3 2M14 10h4M14 13.5h3"/></symbol>
|
||
<symbol id="o-none" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><path d="M6 18L18 6"/></symbol>
|
||
<symbol id="o-one" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><path d="M10 9l2.5-1.5V16.5M10 16.5h5"/></symbol>
|
||
<symbol id="o-layers" viewBox="0 0 24 24"><path d="M12 3.5l9 4.5-9 4.5L3 8z"/><path d="M3 12l9 4.5 9-4.5M3 16l9 4.5 9-4.5"/></symbol>
|
||
<symbol id="o-home" viewBox="0 0 24 24"><path d="M3.5 11L12 4l8.5 7M6 9.5V20h12V9.5"/><path d="M12 17.5s-3-1.8-3-3.6c0-1 .8-1.7 1.6-1.7.6 0 1.1.3 1.4.8.3-.5.8-.8 1.4-.8.8 0 1.6.7 1.6 1.7 0 1.8-3 3.6-3 3.6z"/></symbol>
|
||
<symbol id="o-bowl" viewBox="0 0 24 24"><path d="M3.5 11h17c0 4.5-3.8 8-8.5 8s-8.5-3.5-8.5-8zM9 19.5h6"/><path d="M9 8c0-1.2 1-1.5 1-2.8M13 8c0-1.2 1-1.5 1-2.8"/></symbol>
|
||
<symbol id="o-nurse" viewBox="0 0 24 24"><circle cx="12" cy="8" r="3.5"/><path d="M5 20.5c.8-3.8 3.6-6 7-6s6.2 2.2 7 6"/><path d="M12 15.5v3.5M10.25 17.25h3.5"/></symbol>
|
||
<symbol id="o-moon" viewBox="0 0 24 24"><path d="M3 21h18M5 21V8l7-4.5L19 8v13"/><path d="M13.8 10.2a3 3 0 1 0 1.3 4.6 2.6 2.6 0 0 1-1.3-4.6z"/></symbol>
|
||
<symbol id="o-drop" viewBox="0 0 24 24"><path d="M12 3.5s-6 6.5-6 10.5a6 6 0 0 0 12 0c0-4-6-10.5-6-10.5z"/><path d="M9.5 14.5a2.5 2.5 0 0 0 2.5 2.5"/></symbol>
|
||
<symbol id="o-mix" viewBox="0 0 24 24"><path d="M7.5 6s-4 4.3-4 7a4 4 0 0 0 8 0c0-2.7-4-7-4-7z"/><path d="M15 9.5h4v10a1.5 1.5 0 0 1-1.5 1.5h-1a1.5 1.5 0 0 1-1.5-1.5zM15.8 9.5V7.5h2.4v2M17 4.5v3M15 13.5h1.5M15 16.5h1.5"/></symbol>
|
||
<symbol id="o-bottle" viewBox="0 0 24 24"><path d="M8 9h8v10.5A1.5 1.5 0 0 1 14.5 21h-5A1.5 1.5 0 0 1 8 19.5zM9.5 9V6.5h5V9M12 3v3.5M8 13h2.5M8 16.5h2.5"/></symbol>
|
||
<symbol id="o-t1" viewBox="0 0 24 24"><ellipse cx="12" cy="16" rx="7" ry="2.5"/><path d="M5 16v2c0 1.4 3.1 2.5 7 2.5s7-1.1 7-2.5v-2"/></symbol>
|
||
<symbol id="o-t2" viewBox="0 0 24 24"><ellipse cx="12" cy="11.5" rx="7" ry="2.5"/><path d="M5 11.5v2c0 1.4 3.1 2.5 7 2.5s7-1.1 7-2.5v-2M5 16v2c0 1.4 3.1 2.5 7 2.5s7-1.1 7-2.5v-2"/></symbol>
|
||
<symbol id="o-t3" viewBox="0 0 24 24"><ellipse cx="12" cy="6.5" rx="7" ry="2.5"/><path d="M5 6.5v2.5c0 1.4 3.1 2.5 7 2.5s7-1.1 7-2.5V6.5M5 11.5v2c0 1.4 3.1 2.5 7 2.5s7-1.1 7-2.5v-2M5 16v2c0 1.4 3.1 2.5 7 2.5s7-1.1 7-2.5v-2"/></symbol>
|
||
<symbol id="o-family" viewBox="0 0 24 24"><circle cx="8" cy="7.5" r="2.8"/><circle cx="16.5" cy="10" r="2.2"/><path d="M2.5 20c.5-3.6 2.7-5.8 5.5-5.8s5 2.2 5.5 5.8M13.5 20c.3-2.4 1.5-4 3-4s2.7 1.6 3 4"/></symbol>
|
||
<symbol id="o-flag" viewBox="0 0 24 24"><path d="M3.5 20.5h17M5.5 20.5V11L12 6.5l6.5 4.5v9.5M12 6.5V2.5l3.5 1.5L12 5.5"/><path d="M10 20.5v-4.5h4v4.5"/></symbol>
|
||
<symbol id="o-school" viewBox="0 0 24 24"><path d="M3 20.5h18M4.5 20.5V9.5h15v11M3 9.5L12 4l9 5.5"/><circle cx="12" cy="13" r="2"/><path d="M8 20.5v-3M16 20.5v-3"/></symbol>
|
||
<symbol id="o-book" viewBox="0 0 24 24"><path d="M3 5.5c3-1 6-.8 9 1v13c-3-1.8-6-2-9-1zM21 5.5c-3-1-6-.8-9 1v13c3-1.8 6-2 9-1z"/></symbol>
|
||
<symbol id="o-puzzle" viewBox="0 0 24 24"><path d="M4 8h4a2 2 0 1 1 4 0h4v4a2 2 0 1 1 0 4v4H4v-4a2 2 0 1 0 0-4z"/></symbol>
|
||
<symbol id="o-music" viewBox="0 0 24 24"><path d="M9 18V5.5l11-2V16"/><circle cx="6.5" cy="18" r="2.5"/><circle cx="17.5" cy="16" r="2.5"/></symbol>
|
||
<symbol id="o-syr" viewBox="0 0 24 24"><path d="M18 3l3 3M19.5 4.5L16 8M16.5 5.5l2 2"/><path d="M14 6l4 4-9 9H5v-4z"/><path d="M8.5 12.5l2 2M11 10l2 2"/></symbol>
|
||
<symbol id="o-syr2" viewBox="0 0 24 24"><path d="M14 4l3 3M15.5 5.5L12.5 8.5M13 6.5l1.5 1.5"/><path d="M10.5 7l3.5 3.5L7.5 17H4v-3.5z"/><path d="M19 13v6M16 16h6"/></symbol>
|
||
<symbol id="o-umb" viewBox="0 0 24 24"><path d="M3 12a9 9 0 0 1 18 0zM12 12v6.5a2 2 0 0 1-4 0M12 3v-.5"/></symbol>
|
||
</svg>
|
||
|
||
<div id="scroll">
|
||
<div class="bg" id="bgStart"><i></i><i></i></div>
|
||
<header class="bar" id="bar">
|
||
<button class="back" id="back" aria-label="返回"><svg class="ic"><use href="#i-back" xlink:href="#i-back"/></svg></button>
|
||
<span class="t">孕期专题</span>
|
||
</header>
|
||
|
||
<!-- 开始屏 -->
|
||
<section class="screen" id="sStart">
|
||
<div class="hero">
|
||
<span class="chip">生娃计算器</span>
|
||
<h1>生娃到底要<br><span class="mk">花多少钱</span>?</h1>
|
||
<p class="lede">从怀孕算到宝宝 3 岁,按你家的选择出区间。</p>
|
||
<div class="pic"><img src="img/hero.webp" alt="孕妈在桌前记账"></div>
|
||
<div class="badge">
|
||
<span class="bi"><svg class="ic"><use href="#i-list" xlink:href="#i-list"/></svg></span>
|
||
<span><b class="num" id="qCount">15</b><span>个选择 · 6 段费用</span></span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="ans">
|
||
<span class="chip">一句话答案</span>
|
||
<p id="ansTxt">多数家庭从怀孕到宝宝 3 岁花 <em>10~30 万</em>,差距最大的是坐月子和谁带娃。</p>
|
||
</div>
|
||
|
||
<div class="entries">
|
||
<button class="entry q press" id="goQuick">
|
||
<span class="ei"><svg class="ic"><use href="#i-bolt" xlink:href="#i-bolt"/></svg></span>
|
||
<span class="ex"><b>30 秒快速估算</b><small>只答 5 题,其余按常见情况</small></span>
|
||
<svg class="ic ar"><use href="#i-right" xlink:href="#i-right"/></svg>
|
||
</button>
|
||
<button class="entry d press" id="goFull">
|
||
<span class="ei"><svg class="ic"><use href="#i-list" xlink:href="#i-list"/></svg></span>
|
||
<span class="ex"><b>详细估算</b><small id="fullSub">全部 15 题,每题可跳过</small></span>
|
||
<svg class="ic ar"><use href="#i-right" xlink:href="#i-right"/></svg>
|
||
</button>
|
||
</div>
|
||
<button class="last" id="goLast">看上次的结果</button>
|
||
|
||
<div class="groups">
|
||
<div class="sec-h"><span class="n">算哪些钱</span><small>3 GROUPS</small></div>
|
||
<div class="gg" id="gg"></div>
|
||
</div>
|
||
<p class="tiny">不用填个人信息 · 选择只存在你的手机上</p>
|
||
</section>
|
||
|
||
<!-- 问题屏 -->
|
||
<section class="screen" id="sQ">
|
||
<div class="gp" id="gp"></div>
|
||
<div class="qn" id="qn"></div>
|
||
<h2 class="qh" id="qh"></h2>
|
||
<p class="qs" id="qs"></p>
|
||
<div class="opts" id="opts"></div>
|
||
<div class="qa">
|
||
<button class="prev" id="prev"><svg class="ic"><use href="#i-back" xlink:href="#i-back"/></svg><span id="prevT">上一题</span></button>
|
||
<button class="skip press" id="skip">跳过,按常见情况算</button>
|
||
</div>
|
||
<p class="qtip" id="qtip">金额按你选的城市估算,选完自动下一题</p>
|
||
</section>
|
||
|
||
<!-- 结果屏 -->
|
||
<section class="screen" id="sRes">
|
||
<div class="r-top"><span class="chip">估算结果</span><span class="md" id="mode"></span></div>
|
||
<h2 class="r-t">你家大概要花</h2>
|
||
<div class="sgc" id="tabs">
|
||
<span class="th" id="thumb"></span>
|
||
<button data-s="0">生下来</button><button data-s="1">养到1岁</button><button data-s="2">养到2岁</button><button data-s="3">养到3岁</button>
|
||
</div>
|
||
<div class="tot" aria-live="polite">
|
||
<div class="l" id="totL"></div>
|
||
<div class="v num" id="totV"></div>
|
||
<div class="bar2"><i id="totBar"></i></div>
|
||
<div class="sc"><span>0</span><span id="totMax"></span></div>
|
||
<div class="kv">
|
||
<div><span>平均每月</span><b class="num" id="totM"></b></div>
|
||
<div><span id="rbL">医保预计报销</span><b class="num g" id="totR"></b></div>
|
||
</div>
|
||
</div>
|
||
<button class="more press" id="more"><svg class="ic"><use href="#i-edit" xlink:href="#i-edit"/></svg><span id="moreT"></span><em>补全</em></button>
|
||
|
||
<div class="rs fu">
|
||
<div class="sec-h"><span class="n">01</span><h2>钱花在哪</h2><small>BREAKDOWN</small></div>
|
||
<div class="panel g">
|
||
<div class="donut"><svg viewBox="0 0 120 120" id="ring"></svg><div class="lg" id="lg"></div></div>
|
||
<div class="list" id="list"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="rs fu">
|
||
<div class="sec-h"><span class="n">02</span><h2>你的选择</h2><small>点哪项改哪项</small></div>
|
||
<div class="mine" id="mine"></div>
|
||
</div>
|
||
|
||
<div class="rs fu">
|
||
<div class="sec-h"><span class="n">03</span><h2>最花钱 · 能省的地方</h2></div>
|
||
<div class="card">
|
||
<div class="row"><span class="ri"><svg class="ic"><use href="#i-coin" xlink:href="#i-coin"/></svg></span><div class="rx"><b id="bigT"></b><p id="bigD"></p></div></div>
|
||
<div class="row"><span class="ri"><svg class="ic"><use href="#i-bulb" xlink:href="#i-bulb"/></svg></span><div class="rx"><b>能省的地方</b><ul id="save"></ul></div></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="rs fu">
|
||
<div class="sec-h"><span class="n">04</span><h2>能报 · 能领回来的钱</h2></div>
|
||
<div class="card">
|
||
<div class="row"><span class="ri"><svg class="ic"><use href="#o-shield" xlink:href="#o-shield"/></svg></span><div class="rx"><b id="insT"></b><p id="insD"></p><span class="fml" id="insF"></span></div></div>
|
||
<div class="back-money" id="bm"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="tools" class="fu"></div>
|
||
|
||
<div class="acts"><button class="btn ghost press" id="redo">重新估算</button></div>
|
||
<p class="note"><b>估算区间,仅供参考。</b>按 2025~2026 年国内常见公开价格粗算,各地各医院差别很大;不含孕期并发症、早产、住院等意外支出,报销和补贴以当地政策为准。</p>
|
||
</section>
|
||
</div>
|
||
|
||
<script src="../_shared/tools.js"></script>
|
||
<script>
|
||
(function () {
|
||
'use strict';
|
||
|
||
/* ================= 费用表(单位:元,[低, 高],2025~2026 国内常见公开行情,取整偏保守) =================
|
||
城市下标 c:0 一线 / 1 新一线及省会 / 2 普通地级市 / 3 县城及乡镇 */
|
||
var COST = {
|
||
// —— 孕期产检(约 10~13 次 + 常规筛查)[c][医院]:0 公立普通 / 1 公立特需或单间 / 2 私立 ——
|
||
check: [
|
||
[[5000, 9000], [12000, 25000], [18000, 40000]],
|
||
[[3500, 7000], [8000, 16000], [12000, 28000]],
|
||
[[2500, 5000], [5000, 10000], [7000, 16000]],
|
||
[[1800, 3500], [3500, 7000], [4500, 10000]]
|
||
],
|
||
checkAdd: [[0, 0], [1200, 2500], [3000, 6000]], // 产检自费加项 [方案]:0 常规 / 1 加无创 DNA / 2 无创+四维+早孕 B 超等
|
||
// 孕妇装、待产包 [c],× 用品档次 × 第几胎
|
||
pregGoods: [[2000, 5000], [1500, 4000], [1200, 3000], [1000, 2500]],
|
||
// 分娩住院 [c][医院][方式],方式 0 顺产 / 1 剖宫产;「还不确定」取两者合并区间
|
||
birth: [
|
||
[[[6000, 12000], [12000, 20000]], [[15000, 30000], [25000, 45000]], [[30000, 60000], [45000, 90000]]],
|
||
[[[4000, 8000], [8000, 15000]], [[10000, 20000], [15000, 30000]], [[18000, 40000], [28000, 60000]]],
|
||
[[[3000, 6000], [6000, 11000]], [[6000, 12000], [10000, 18000]], [[10000, 25000], [15000, 35000]]],
|
||
[[[2000, 4000], [4000, 8000]], [[4000, 8000], [6000, 12000]], [[6000, 15000], [10000, 22000]]]
|
||
],
|
||
// 医保报销(预估)[医保]:0 职工医保含生育保险 / 1 城乡居民医保 / 2 没有。产检、分娩分开;× 城市系数 × 医院系数,且不超过当项的 70%
|
||
rCheck: [[1000, 2500], [300, 800], [0, 0]],
|
||
rBirth: [[[2500, 5000], [4000, 8000]], [[800, 2000], [1500, 3500]], [[0, 0], [0, 0]]],
|
||
rCity: [1.3, 1, 0.85, 0.7],
|
||
rHosp: [1, 0.8, 0.5], // 特需、私立一般只按基本部分或定额报
|
||
// 坐月子 [c][方式]:0 家人照顾 / 1 家人+钟点工或月子餐 / 2 月嫂约 26 天 / 3 月子中心约 28 天
|
||
yuezi: [
|
||
[[3000, 8000], [8000, 15000], [15000, 30000], [40000, 100000]],
|
||
[[2500, 6000], [6000, 12000], [10000, 20000], [25000, 60000]],
|
||
[[2000, 5000], [4000, 8000], [7000, 14000], [15000, 35000]],
|
||
[[1500, 4000], [3000, 6000], [5000, 10000], [10000, 25000]]
|
||
],
|
||
// 奶粉 [年 0/1/2][喂养 0 母乳 / 1 混合 / 2 奶粉],× 奶粉档次
|
||
formula: [
|
||
[[300, 1200], [4000, 7000], [8000, 12000]],
|
||
[[1000, 2500], [3000, 6000], [5000, 8000]],
|
||
[[800, 2000], [1500, 3000], [2000, 4000]]
|
||
],
|
||
milk: [0.65, 1, 1.5], // 奶粉档次:国产平价约 150~220 元/罐 / 国产高端或进口常规 250~350 / 进口高端有机 400+
|
||
// 辅食与日常饮食 [年][c]
|
||
food: [
|
||
[[1000, 2500], [1000, 2500], [800, 2000], [600, 1800]],
|
||
[[3000, 6000], [2500, 5000], [2000, 4000], [1500, 3500]],
|
||
[[5000, 8000], [4000, 7000], [3500, 6000], [2500, 5000]]
|
||
],
|
||
diaper: [[3000, 5000], [2500, 4000], [800, 2000]], // 纸尿裤、湿巾、洗护 [年],× 档次
|
||
dia: [0.65, 1, 1.5],
|
||
// 衣物、推车、安全座椅、婴儿床、玩具等 [年][c],× 用品档次 × 第几胎
|
||
goods: [
|
||
[[5000, 10000], [4000, 8000], [3000, 6000], [2500, 5000]],
|
||
[[3000, 6000], [2500, 5000], [2000, 4000], [1500, 3500]],
|
||
[[3000, 6000], [2500, 5000], [2000, 4000], [1500, 3500]]
|
||
],
|
||
gear: [0.55, 1, 1.9],
|
||
reuse: [[1, 1, 1, 1], [0.7, 0.6, 0.75, 0.75]], // [头胎/二胎][孕期用品, 0~1, 1~2, 2~3]
|
||
// 看病、体检、少儿医保 [年][c]
|
||
med: [
|
||
[[1200, 4000], [1000, 3500], [800, 3000], [600, 2500]],
|
||
[[1000, 3500], [800, 3000], [600, 2500], [500, 2000]],
|
||
[[1000, 3000], [800, 2500], [600, 2000], [500, 1800]]
|
||
],
|
||
vac: [[0, 0], [4000, 7000], [8000, 12000]], // 自费疫苗总计 [档];按 70% / 20% / 10% 摊到三年
|
||
vacSplit: [0.7, 0.2, 0.1],
|
||
bx: [[0, 0], [300, 800], [3000, 6000]], // 商业保险每年 [档]
|
||
// 早教兴趣班每年 [档][c];2~3 岁 ×1.2
|
||
edu: [
|
||
[[800, 2000], [600, 1500], [500, 1200], [300, 1000]],
|
||
[[6000, 12000], [4000, 8000], [2500, 5000], [1500, 3500]],
|
||
[[15000, 30000],[10000, 20000],[6000, 12000],[3000, 8000]]
|
||
],
|
||
// 带娃(按年)[c]
|
||
sub: [[4800, 12000], [3600, 9600], [2400, 7200], [1200, 6000]], // 老人补贴,约 100~1000 元/月
|
||
nanny: [[84000, 120000], [60000, 90000], [48000, 72000], [36000, 54000]], // 育儿嫂月薪 × 12
|
||
daycare: [[44000, 88000], [27500, 55000], [19800, 38500], [13200, 27500]], // 全日托育园月费 × 11
|
||
tuoban: [[30000, 70000], [20000, 45000], [12000, 30000], [8000, 20000]], // 2 岁起托班月费 × 10
|
||
wage: [[11000, 16000], [8000, 11000], [6000, 8000], [4500, 6500]] // 生育津贴粗算用的当地月平均工资
|
||
};
|
||
|
||
/* ================= 问题(15 题,g 分组;if 条件题) ================= */
|
||
var GROUPS = ['孕期与分娩', '月子与喂养', '0~3 岁养育'];
|
||
var QS = [
|
||
{ k: 'city', g: 0, h: '你在哪类城市?', s: '各地价格差别最大的一项', o: [
|
||
['一线城市', '北京、上海、广州、深圳', 'bldg'], ['新一线及省会', '成都、杭州、武汉、各省会', 'bldg2'],
|
||
['普通地级市', '三四线城市', 'house'], ['县城及乡镇', '县城、镇上', 'tree']] },
|
||
{ k: 'check', g: 0, h: '产检打算怎么做?', s: '常规项目都一样,差在自费加项', ids: ['checkAdd'], o: [
|
||
['只做常规项目', '跟着医生的产检表走', 'clip'], ['常规 + 无创 DNA', '多花一项无创产前筛查', 'dna'],
|
||
['能加的都加', '无创、四维、早孕 B 超等', 'scan']] },
|
||
{ k: 'hosp', g: 0, h: '打算在哪家医院生?', s: '产检一般也在同一家', ids: ['check', 'birth'], pl: '产检+分娩', o: [
|
||
['公立医院普通病房', '多人间,大多数人的选择', 'hosp'], ['公立特需或单间', '单人间、特需门诊,部分自费', 'bed'],
|
||
['私立医院', '环境服务好,基本全自费', 'star']] },
|
||
{ k: 'way', g: 0, h: '分娩方式?', s: '最终听医生评估', ids: ['birth'], o: [
|
||
['顺产', '住院约 2~3 天', 'leaf'], ['剖宫产', '住院约 4~6 天', 'cut'], ['还不确定', '两种都算进去,区间宽一些', 'help']] },
|
||
{ k: 'ins', g: 0, h: '你有哪种医保?', s: '决定产检分娩能报多少', ids: ['reimb'], o: [
|
||
['职工医保(含生育保险)', '上班交社保,还能领生育津贴', 'shield'], ['城乡居民医保', '分娩能报一部分,没有津贴', 'card'],
|
||
['没有或不清楚', '先按全自费算', 'none']] },
|
||
{ k: 'first', g: 0, h: '这是第几个宝宝?', s: '老大的东西能接着用', o: [
|
||
['头胎', '用品都要新添置', 'one'], ['二胎及以上', '衣物、推车、婴儿床能复用', 'layers']] },
|
||
{ k: 'yz', g: 1, h: '月子怎么坐?', s: '这一项差距最大', ids: ['yz'], o: [
|
||
['家人照顾', '月子餐和产妇用品', 'home'], ['家人 + 钟点工或月子餐', '请人做饭打扫,家人陪护', 'bowl'],
|
||
['请月嫂', '上门照顾,一般 26 天', 'nurse'], ['月子中心', '一般 28 天套餐', 'moon']] },
|
||
{ k: 'feed', g: 1, h: '宝宝打算怎么喂?', s: '大概的打算就行', ids: ['formula'], pl: '3 年奶粉', o: [
|
||
['母乳为主', '奶粉钱很少', 'drop'], ['混合喂养', '母乳加一部分奶粉', 'mix'], ['奶粉为主', '奶粉是每月固定开销', 'bottle']] },
|
||
{ k: 'milk', g: 1, h: '奶粉打算买哪档?', s: '按 800 克一罐算', ids: ['formula'], pl: '3 年奶粉', if: function (s) { return s.feed > 0; }, o: [
|
||
['国产平价', '约 150~220 元一罐', 't1'], ['国产高端或进口常规', '约 250~350 元一罐', 't2'], ['进口高端或有机', '约 400 元以上一罐', 't3']] },
|
||
{ k: 'gear', g: 1, h: '待产包和婴儿用品买哪档?', s: '推车、安全座椅、婴儿床、衣物玩具', ids: ['pgoods', 'goods'], pl: '3 年用品', o: [
|
||
['实用够用', '平价款,能借能用二手', 't1'], ['中等品牌', '买点好的,不追高', 't2'], ['高端进口', '大件挑进口大牌', 't3']] },
|
||
{ k: 'diaper', g: 1, h: '纸尿裤和洗护用哪档?', s: '头一年每天要用 6~10 片', ids: ['diaper'], pl: '3 年', o: [
|
||
['平价国产', '约 1 元一片', 't1'], ['中端品牌', '约 1.5~2 元一片', 't2'], ['高端进口', '约 2.5 元以上一片', 't3']] },
|
||
{ k: 'care', g: 2, h: '1~3 岁白天谁带?', s: '产假结束后的安排', ids: ['care'], pl: '2 年', o: [
|
||
['老人或自己带', '给老人一点补贴,3 岁上幼儿园', 'family'], ['家里带,2 岁起上托班', '第 3 年交托班费', 'flag'],
|
||
['请育儿嫂或保姆', '按月薪算', 'nurse'], ['1 岁多就上托育园', '全日托,按月费算', 'school']] },
|
||
{ k: 'edu', g: 2, h: '早教和兴趣班呢?', s: '1~3 岁', ids: ['edu'], pl: '2 年', o: [
|
||
['在家玩为主', '绘本玩具、遛娃', 'book'], ['报一个早教班', '每周 1~2 节', 'puzzle'], ['早教 + 兴趣班', '再加游泳、音乐、美术等', 'music']] },
|
||
{ k: 'vac', g: 2, h: '自费疫苗打哪些?', s: '免费的国家疫苗都要打', ids: ['vac'], o: [
|
||
['只打免费的', '国家免疫规划疫苗', 'shield'], ['挑重点自费', '13 价肺炎、五联、轮状等', 'syr'],
|
||
['能打的自费都打', '再加手足口、流感等', 'syr2']] },
|
||
{ k: 'bx', g: 2, h: '给宝宝买商业保险吗?', s: '少儿医保已算在看病费里', ids: ['bx'], pl: '3 年', o: [
|
||
['先不买', '靠少儿医保', 'none'], ['医疗险 + 意外险', '每年几百元', 'umb'], ['再加重疾险', '每年约 3000~6000 元', 'shield']] }
|
||
];
|
||
var QK = {}; QS.forEach(function (q, i) { QK[q.k] = q; q.i = i; });
|
||
var QUICK = ['city', 'hosp', 'yz', 'feed', 'care'];
|
||
var DEF = { city: 1, check: 1, hosp: 0, way: 2, ins: 0, first: 0, yz: 0, feed: 1, milk: 1, gear: 1, diaper: 1, care: 0, edu: 0, vac: 1, bx: 1 };
|
||
var SHORT = { // 结果页标签
|
||
city: ['一线城市', '新一线/省会', '地级市', '县城乡镇'], check: ['常规产检', '加无创', '自费项全加'],
|
||
hosp: ['公立普通', '公立特需', '私立医院'], way: ['顺产', '剖宫产', '方式未定'],
|
||
ins: ['职工医保', '居民医保', '无医保'], first: ['头胎', '二胎'],
|
||
yz: ['家人坐月子', '家人+钟点工', '请月嫂', '月子中心'], feed: ['母乳为主', '混合喂养', '奶粉为主'],
|
||
milk: ['平价奶粉', '中档奶粉', '高端奶粉'], gear: ['用品实用', '用品中档', '用品高端'], diaper: ['平价纸尿裤', '中端纸尿裤', '高端纸尿裤'],
|
||
care: ['老人带', '2岁上托班', '育儿嫂', '托育园'], edu: ['在家玩', '一个早教班', '早教+兴趣班'],
|
||
vac: ['只打免费苗', '重点自费苗', '自费苗全打'], bx: ['不买商保', '医疗+意外险', '加重疾险']
|
||
};
|
||
var STAGES = ['孕期产检', '分娩住院', '坐月子', '0~1岁', '1~2岁', '2~3岁'];
|
||
var SHADES = ['#0B6E3A', '#18A058', '#45B779', '#79CC9E', '#A8DFC0', '#CFEFDD'];
|
||
var TAB_L = ['怀孕到坐完月子', '怀孕到宝宝 1 岁', '怀孕到宝宝 2 岁', '怀孕到宝宝 3 岁'];
|
||
var UPTO = [3, 4, 5, 6];
|
||
var MONTHS = [10, 22, 34, 46]; // 怀孕约 9 个月 + 月子 1 个月;之后每岁 12 个月
|
||
var KEY = 'mmbox.huafei.v3', KEY2 = 'mmbox.huafei.v2';
|
||
|
||
var $ = function (s) { return document.querySelector(s); };
|
||
var sc = $('#scroll');
|
||
var st = {}, ans = {}; // st 当前取值(没答的按常见),ans 用户亲自答过的题
|
||
var stage = 3, mode = 'full', cur = null, editing = false, flow = [], hasResult = false, fromRes = false;
|
||
for (var k0 in DEF) st[k0] = DEF[k0];
|
||
|
||
function add(a, b) { return [a[0] + b[0], a[1] + b[1]]; }
|
||
function mul(a, k) { return [a[0] * k, a[1] * k]; }
|
||
function mid(a) { return (a[0] + a[1]) / 2; }
|
||
|
||
/* 六段费用:返回 [{t:[低,高], it:[{id, n, v}]}] × 6;医保报销作为负项计入产检、分娩两段 */
|
||
function calc(s) {
|
||
var c = s.city, gk = COST.gear[s.gear], ru = COST.reuse[s.first], mk = s.feed > 0 ? COST.milk[s.milk] : 1, dk = COST.dia[s.diaper];
|
||
var b = COST.birth[c][s.hosp], rb = COST.rBirth[s.ins];
|
||
var birth = s.way === 2 ? [b[0][0], b[1][1]] : b[s.way];
|
||
var rbw = s.way === 2 ? [rb[0][0], rb[1][1]] : rb[s.way];
|
||
var rk = COST.rCity[c] * COST.rHosp[s.hosp];
|
||
var check = COST.check[c][s.hosp];
|
||
function cap(r, g) { return [Math.min(r[0] * rk, g[0] * 0.7), Math.min(r[1] * rk, g[1] * 0.7)]; }
|
||
var rC = cap(COST.rCheck[s.ins], check), rB = cap(rbw, birth);
|
||
function care(y) { // y = 1(1~2 岁)/ 2(2~3 岁)
|
||
if (s.care === 0) return COST.sub[c];
|
||
if (s.care === 1) return y === 1 ? COST.sub[c] : add(COST.tuoban[c], mul(COST.sub[c], 0.5));
|
||
if (s.care === 2) return COST.nanny[c];
|
||
return COST.daycare[c];
|
||
}
|
||
function year(y) {
|
||
var it = [
|
||
{ id: 'formula', n: '奶粉', v: mul(COST.formula[y][s.feed], mk) },
|
||
{ id: 'food', n: y ? '饮食' : '辅食', v: COST.food[y][c] },
|
||
{ id: 'diaper', n: '纸尿裤洗护', v: mul(COST.diaper[y], dk) },
|
||
{ id: 'goods', n: y ? '衣物玩具' : '衣物和推车床椅等', v: mul(COST.goods[y][c], gk * ru[y + 1]) },
|
||
{ id: 'med', n: '看病体检', v: COST.med[y][c] },
|
||
{ id: 'vac', n: '自费疫苗', v: mul(COST.vac[s.vac], COST.vacSplit[y]) },
|
||
{ id: 'bx', n: '商业保险', v: COST.bx[s.bx] }
|
||
];
|
||
if (y) {
|
||
it.push({ id: 'edu', n: '早教兴趣班', v: mul(COST.edu[s.edu][c], y === 2 && s.edu ? 1.2 : 1) });
|
||
it.push({ id: 'care', n: ['老人补贴', y === 2 ? '托班费' : '老人补贴', '育儿嫂工资', '托育园费'][s.care], v: care(y) });
|
||
}
|
||
return it;
|
||
}
|
||
var segs = [
|
||
[{ id: 'check', n: '常规产检和筛查', v: check }, { id: 'checkAdd', n: '自费加项', v: COST.checkAdd[s.check] },
|
||
{ id: 'pgoods', n: '孕妇装和待产包', v: mul(COST.pregGoods[c], gk * ru[0]) }, { id: 'reimb', n: '医保报销', v: mul(rC, -1) }],
|
||
[{ id: 'birth', n: ['顺产', '剖宫产', '顺产到剖宫产'][s.way] + '住院', v: birth }, { id: 'reimb', n: '医保报销', v: mul(rB, -1) }],
|
||
[{ id: 'yz', n: ['月子餐和产妇用品', '钟点工和月子餐', '月嫂约 26 天和产妇用品', '月子中心约 28 天套餐'][s.yz], v: COST.yuezi[c][s.yz] }],
|
||
year(0), year(1), year(2)
|
||
];
|
||
return segs.map(function (its) {
|
||
its = its.filter(function (x) { return x.v[1] !== 0; });
|
||
var t = its.reduce(function (a, x) { return add(a, x.v); }, [0, 0]);
|
||
if (t[0] > t[1]) t = [t[1], t[0]];
|
||
return { t: t, it: its };
|
||
});
|
||
}
|
||
// 某几类项目在全部 6 段里的合计(选项卡上的价格提示用)
|
||
function pick(s, ids) {
|
||
var r = [0, 0];
|
||
calc(s).forEach(function (sg) { sg.it.forEach(function (x) { if (ids.indexOf(x.id) >= 0) r = add(r, x.v); }); });
|
||
return r;
|
||
}
|
||
function reimb(s) { var r = pick(s, ['reimb']); return [-r[0], -r[1]]; }
|
||
|
||
function w1(n) { var v = Math.round(n / 1000) / 10; return (v >= 100 ? Math.round(v) : v) + ''; }
|
||
function wan(n) { return w1(n) + '万'; }
|
||
function yuan(n) { return String(Math.round(n / 100) * 100).replace(/\B(?=(\d{3})+(?!\d))/g, ','); }
|
||
function rng(a) {
|
||
var lo = Math.min(a[0], a[1]), hi = Math.max(a[0], a[1]);
|
||
if (hi < 10000) return yuan(lo) + '~' + yuan(hi) + ' 元';
|
||
return w1(lo) + '~' + wan(hi);
|
||
}
|
||
|
||
/* ================= 问题流 ================= */
|
||
function active(keys) { // 按条件过滤
|
||
return keys.filter(function (k) { var q = QK[k]; return !q.if || q.if(st); });
|
||
}
|
||
function seq() { return active(flow); }
|
||
|
||
function show(id) {
|
||
[].forEach.call(document.querySelectorAll('.screen'), function (el) { el.classList.toggle('on', el.id === id); });
|
||
var bg = $('#bgStart');
|
||
bg.style.display = id === 'sQ' ? 'none' : '';
|
||
bg.style.height = id === 'sRes' ? '420px' : '';
|
||
sc.scrollTop = 0;
|
||
}
|
||
|
||
function priceOf(q, v) {
|
||
if (q.k === 'city') return '';
|
||
var s = {}; for (var k in st) s[k] = st[k]; s[q.k] = v;
|
||
if (q.k === 'first') {
|
||
if (!v) return '';
|
||
var s0 = {}; for (var k2 in s) s0[k2] = s[k2]; s0.first = 0;
|
||
var a = pick(s0, ['pgoods', 'goods']), b2 = pick(s, ['pgoods', 'goods']);
|
||
return '用品约省 ' + rng([a[0] - b2[0], a[1] - b2[1]]);
|
||
}
|
||
if (q.k === 'ins') { var r = reimb(s); return r[1] ? '预计能报 ' + rng(r) : '全自费'; }
|
||
var p = pick(s, q.ids);
|
||
if (!p[1]) return q.k === 'vac' ? '免费' : q.k === 'bx' ? '不花钱' : q.k === 'check' ? '不额外花钱' : '';
|
||
return (q.pl ? q.pl + ' ' : '约 ') + rng(p);
|
||
}
|
||
|
||
function renderQ() {
|
||
var q = QK[cur], list = editing ? [cur] : seq(), idx = list.indexOf(cur);
|
||
// 分组进度:按当前流程里每组的题数
|
||
var html = '';
|
||
GROUPS.forEach(function (g, gi) {
|
||
var inG = list.filter(function (k) { return QK[k].g === gi; });
|
||
var done = inG.filter(function (k) { return list.indexOf(k) < idx; }).length;
|
||
var w = inG.length ? done / inG.length * 100 : 0;
|
||
html += '<div class="seg' + (QK[cur].g === gi ? ' cur' : '') + (inG.length ? '' : ' off') + '"><div class="tr"><i style="width:' + w + '%"></i></div><span class="gl">' + g + '</span></div>';
|
||
});
|
||
$('#gp').innerHTML = html;
|
||
$('#qn').innerHTML = editing ? '<b>修改这一项</b><span>· 改完回到结果</span>' :
|
||
'<span>第 <b class="num">' + (idx + 1) + '</b> / 共 ' + list.length + ' 题</span><span>· ' + GROUPS[q.g] + '</span>';
|
||
$('#qh').textContent = q.h;
|
||
$('#qs').textContent = q.s;
|
||
$('#opts').innerHTML = q.o.map(function (o, v) {
|
||
var p = priceOf(q, v), on = ans[q.k] && st[q.k] === v;
|
||
return '<button class="opt' + (on ? ' on' : '') + '" data-v="' + v + '"><span class="oi"><svg class="ic"><use href="#o-' + o[2] + '" xlink:href="#o-' + o[2] + '"/></svg></span>' +
|
||
'<span class="ox"><b>' + o[0] + (DEF[q.k] === v ? '<em>常见</em>' : '') + '</b><small>' + o[1] + '</small>' + (p ? '<span class="pp">' + p + '</span>' : '') + '</span><span class="rd"></span></button>';
|
||
}).join('');
|
||
$('#prevT').textContent = editing ? '取消' : (idx > 0 ? '上一题' : '返回');
|
||
$('#skip').textContent = editing ? '按常见情况算' : '跳过,按常见情况算';
|
||
$('#qtip').textContent = editing ? '选完直接回到结果页' : q.k === 'city' ? '后面的金额都按这里选的城市估算' : '金额按你前面的选择估算,选完自动下一题';
|
||
show('sQ');
|
||
}
|
||
|
||
function next() {
|
||
var list = editing ? [cur] : seq(), idx = list.indexOf(cur);
|
||
if (editing) {
|
||
// 改喂养:从母乳改成奶粉/混合,且没答过奶粉档次 → 顺带问一题
|
||
if (cur === 'feed' && st.feed > 0 && !ans.milk && mode === 'full') { cur = 'milk'; renderQ(); return; }
|
||
editing = false; finish(); return;
|
||
}
|
||
if (idx < list.length - 1) { cur = list[idx + 1]; renderQ(); }
|
||
else finish();
|
||
}
|
||
function finish() { hasResult = true; save(); renderRes(true); show('sRes'); observe(); }
|
||
|
||
$('#opts').addEventListener('click', function (e) {
|
||
var b = e.target.closest('.opt'); if (!b || this.dataset.lock) return;
|
||
[].forEach.call(this.children, function (x) { x.classList.toggle('on', x === b); });
|
||
st[cur] = +b.dataset.v; ans[cur] = 1;
|
||
this.dataset.lock = '1';
|
||
var self = this;
|
||
setTimeout(function () { delete self.dataset.lock; next(); }, 240);
|
||
});
|
||
$('#skip').addEventListener('click', function () { st[cur] = DEF[cur]; delete ans[cur]; next(); });
|
||
$('#prev').addEventListener('click', function () {
|
||
if (editing) { editing = false; renderRes(false); show('sRes'); observe(); return; }
|
||
var list = seq(), idx = list.indexOf(cur);
|
||
if (idx > 0) { cur = list[idx - 1]; renderQ(); }
|
||
else if (fromRes) { renderRes(false); show('sRes'); observe(); }
|
||
else { renderStart(); show('sStart'); }
|
||
});
|
||
function start(m) {
|
||
mode = m; editing = false; fromRes = false; stage = 3;
|
||
ans = {}; for (var k in DEF) st[k] = DEF[k]; // 重新估算:从常见情况起步
|
||
flow = m === 'quick' ? QUICK.slice() : QS.map(function (q) { return q.k; });
|
||
cur = seq()[0]; renderQ();
|
||
}
|
||
$('#goQuick').addEventListener('click', function () { start('quick'); });
|
||
$('#goFull').addEventListener('click', function () { start('full'); });
|
||
$('#goLast').addEventListener('click', function () { renderRes(true); show('sRes'); observe(); });
|
||
$('#redo').addEventListener('click', function () { renderStart(); show('sStart'); });
|
||
$('#more').addEventListener('click', function () { // 快速估算后补全剩下的题
|
||
mode = 'full'; editing = false; fromRes = true;
|
||
flow = QS.map(function (q) { return q.k; }).filter(function (k) { return !ans[k]; });
|
||
if (!seq().length) return;
|
||
cur = seq()[0]; renderQ();
|
||
});
|
||
|
||
/* ================= 开始屏 ================= */
|
||
function renderStart() {
|
||
var n = QS.length;
|
||
$('#qCount').textContent = n;
|
||
$('#fullSub').textContent = '全部 ' + n + ' 题,每题可跳过';
|
||
$('#gg').innerHTML = GROUPS.map(function (g, i) {
|
||
var qs = QS.filter(function (q) { return q.g === i; });
|
||
var eg = ['医院、分娩、医保', '月子、奶粉、用品', '谁带、早教、疫苗'][i];
|
||
return '<div class="gc"><span class="no num">0' + (i + 1) + '</span><b>' + g + '</b><span>' + qs.length + ' 题 · ' + eg + '</span></div>';
|
||
}).join('');
|
||
// 一句话答案:用常见选择现算,县城到新一线
|
||
var lo = calc(withCity(3)).reduce(function (a, x) { return a + x.t[0]; }, 0);
|
||
var hi = calc(withCity(1)).reduce(function (a, x) { return a + x.t[1]; }, 0);
|
||
// 补一句:请月嫂 + 2 岁送托班(省会到一线)
|
||
var up = withCity(1); up.yz = 2; up.care = 1;
|
||
var lo2 = calc(up).reduce(function (a, x) { return a + x.t[0]; }, 0);
|
||
up.city = 0;
|
||
var hi2 = calc(up).reduce(function (a, x) { return a + x.t[1]; }, 0);
|
||
$('#ansTxt').innerHTML = '按常见选择,从怀孕到宝宝 3 岁,县城到省会大约花 <em>' + Math.round(lo / 10000) + '~' + Math.round(hi / 10000) + ' 万</em>;请月嫂、送托班会到 <em>' + Math.round(lo2 / 10000) + '~' + Math.round(hi2 / 10000) + ' 万</em>。';
|
||
$('#goLast').classList.toggle('on', hasResult);
|
||
}
|
||
function withCity(c) { var s = {}; for (var k in DEF) s[k] = DEF[k]; s.city = c; return s; }
|
||
|
||
/* ================= 结果屏 ================= */
|
||
var shown = [0, 0]; // 数字滚动的起点
|
||
function fmtBig(a) {
|
||
var w = a[1] >= 10000;
|
||
return '<span class="n">' + (w ? w1(a[0]) : yuan(a[0])) + '</span><span class="td">~</span><span class="n">' + (w ? w1(a[1]) : yuan(a[1])) + '</span><span class="u">' + (w ? '万元' : '元') + '</span>';
|
||
}
|
||
function countTo(to) {
|
||
var from = shown.slice(), t0 = 0, dur = 650, el = $('#totV');
|
||
var reduce = window.matchMedia && matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||
shown = to.slice();
|
||
if (reduce || (from[0] === to[0] && from[1] === to[1])) { el.innerHTML = fmtBig(to); return; }
|
||
function step(ts) {
|
||
if (!t0) t0 = ts;
|
||
var p = Math.min(1, (ts - t0) / dur), e = 1 - Math.pow(1 - p, 3);
|
||
el.innerHTML = fmtBig([from[0] + (to[0] - from[0]) * e, from[1] + (to[1] - from[1]) * e]);
|
||
if (p < 1) requestAnimationFrame(step);
|
||
}
|
||
requestAnimationFrame(step);
|
||
}
|
||
|
||
function renderRes(fromZero) {
|
||
var segs = calc(st), n = UPTO[stage];
|
||
var tot = segs.slice(0, n).reduce(function (a, x) { return add(a, x.t); }, [0, 0]);
|
||
var full = segs.reduce(function (a, x) { return add(a, x.t); }, [0, 0]);
|
||
|
||
// 顶部
|
||
var nAns = QS.filter(function (q) { return ans[q.k] && (!q.if || q.if(st)); }).length;
|
||
var nAct = active(QS.map(function (q) { return q.k; })).length;
|
||
$('#mode').textContent = nAns >= nAct ? '已按 ' + nAct + ' 项选择计算' : '答了 ' + nAns + ' 项,其余 ' + (nAct - nAns) + ' 项按常见';
|
||
$('#more').classList.toggle('on', nAns < nAct);
|
||
$('#moreT').innerHTML = '还有 <b>' + (nAct - nAns) + ' 项</b>按常见情况算,补全后更准';
|
||
[].forEach.call($('#tabs').querySelectorAll('button'), function (b, i) { b.classList.toggle('on', i === stage); });
|
||
$('#thumb').style.transform = 'translateX(' + (stage * 100) + '%)';
|
||
|
||
// 大数字 + 刻度条(以养到 3 岁的上限为满格)
|
||
$('#totL').textContent = TAB_L[stage] + ',自付合计约';
|
||
if (fromZero) shown = [0, 0];
|
||
countTo(tot);
|
||
var bar = $('#totBar');
|
||
bar.style.left = (tot[0] / full[1] * 100).toFixed(1) + '%';
|
||
bar.style.width = Math.max(2, (tot[1] - tot[0]) / full[1] * 100).toFixed(1) + '%';
|
||
$('#totMax').textContent = '养到 3 岁最多约 ' + wan(full[1]);
|
||
$('#totM').textContent = yuan(mid(tot) / MONTHS[stage]) + ' 元';
|
||
var r = reimb(st);
|
||
$('#rbL').textContent = st.ins === 2 ? '医保报销' : '已扣医保预计报销';
|
||
$('#totR').textContent = r[1] ? rng(r) : '按全自费';
|
||
|
||
// 环形图(当前阶段的构成)
|
||
var mids = segs.map(function (x) { return Math.max(0, mid(x.t)); });
|
||
var actSum = mids.slice(0, n).reduce(function (a, b) { return a + b; }, 0) || 1;
|
||
var R = 46, C = 2 * Math.PI * R, off = 0, big = 0, svg = '<circle cx="60" cy="60" r="' + R + '" fill="none" stroke="#fff" stroke-width="14"/>';
|
||
for (var i = 0; i < 6; i++) {
|
||
var f = i < n ? mids[i] / actSum : 0, len = Math.max(0, f * C - (f > 0.015 ? 2 : 0));
|
||
svg += '<circle cx="60" cy="60" r="' + R + '" fill="none" stroke="' + SHADES[i] + '" stroke-width="14" stroke-dasharray="' + len.toFixed(2) + ' ' + C.toFixed(2) + '" stroke-dashoffset="' + (-off).toFixed(2) + '" transform="rotate(-90 60 60)"/>';
|
||
off += f * C;
|
||
if (i < n && mids[i] > mids[big]) big = i;
|
||
}
|
||
svg += '<text x="60" y="47" text-anchor="middle" class="ct1">最花钱</text><text x="60" y="66" text-anchor="middle" class="ct2">' + STAGES[big] + '</text>' +
|
||
'<text x="60" y="82" text-anchor="middle" class="ct3 num">' + Math.round(mids[big] / actSum * 100) + '%</text>';
|
||
$('#ring').innerHTML = svg;
|
||
$('#lg').innerHTML = segs.map(function (x, i) {
|
||
var on = i < n;
|
||
return '<div' + (on ? '' : ' class="off"') + '><i style="background:' + (on ? SHADES[i] : '#E5E8EC') + '"></i><span>' + STAGES[i] + '</span><b class="num">' + (on ? Math.round(mids[i] / actSum * 100) + '%' : '未计入') + '</b></div>';
|
||
}).join('');
|
||
|
||
// 明细(折叠,保留展开状态)
|
||
var open = {};
|
||
[].forEach.call(document.querySelectorAll('#list details'), function (d, i) { if (d.open) open[i] = 1; });
|
||
$('#list').innerHTML = segs.map(function (x, i) {
|
||
var on = i < n;
|
||
return '<details' + (on ? '' : ' class="off"') + (open[i] ? ' open' : '') + '><summary><span class="dot" style="background:' + (on ? SHADES[i] : '#E5E8EC') + '"></span>' +
|
||
'<span class="nm">' + STAGES[i] + '</span><span class="rg">' + (on ? rng(x.t) : '未计入') + '</span>' +
|
||
'<svg class="ic ar"><use href="#i-down" xlink:href="#i-down"/></svg></summary><div class="ds">' +
|
||
x.it.map(function (y) {
|
||
var neg = y.v[1] < 0;
|
||
return '<div class="it' + (neg ? ' minus' : '') + '"><span>' + y.n + (neg ? '(预估)' : '') + '</span><b>' + (neg ? '−' + rng([-y.v[0], -y.v[1]]) : rng(y.v)) + '</b></div>';
|
||
}).join('') + '</div></details>';
|
||
}).join('');
|
||
|
||
// 你的选择(可点标签)
|
||
$('#mine').innerHTML = GROUPS.map(function (g, gi) {
|
||
var t = QS.filter(function (q) { return q.g === gi && (!q.if || q.if(st)); }).map(function (q) {
|
||
var df = !ans[q.k];
|
||
return '<button class="' + (df ? 'df' : '') + '" data-k="' + q.k + '">' + SHORT[q.k][st[q.k]] + (df ? '<i>常见</i>' : '') +
|
||
'<svg class="ic"><use href="#i-edit" xlink:href="#i-edit"/></svg></button>';
|
||
}).join('');
|
||
return '<div class="mg"><div class="mh">' + g + '</div><div class="tags">' + t + '</div></div>';
|
||
}).join('');
|
||
|
||
// 最花钱 + 能省
|
||
var items = [];
|
||
segs.slice(0, n).forEach(function (x) { x.it.forEach(function (y) { if (y.v[1] > 0) items.push(y); }); });
|
||
var agg = {}; // 同类项合并(如 3 年的奶粉)
|
||
items.forEach(function (y) { if (!agg[y.id]) agg[y.id] = { id: y.id, n: y.n, v: [0, 0] }; agg[y.id].v = add(agg[y.id].v, y.v); });
|
||
var ranked = Object.keys(agg).map(function (k) { return agg[k]; }).sort(function (a, b) { return mid(b.v) - mid(a.v); });
|
||
$('#bigT').innerHTML = '最花钱的是<em>' + STAGES[big] + '</em>,<span style="white-space:nowrap">约 ' + rng(segs[big].t) + '</span>';
|
||
var top = segs[big].it.filter(function (y) { return y.v[1] > 0; }).sort(function (a, b) { return mid(b.v) - mid(a.v); })[0];
|
||
$('#bigD').textContent = '其中「' + top.n + '」' + (segs[big].it.length > 1 ? '占大头,约 ' + rng(top.v) : '') + (segs[big].it.length > 1 ? '。' : '是主要开销。') ;
|
||
var tips = [], seen = {};
|
||
ranked.forEach(function (y) { var t = tipOf(y.id); if (t && !seen[t] && tips.length < 3) { seen[t] = 1; tips.push(t); } });
|
||
$('#save').innerHTML = tips.map(function (t) { return '<li>' + t + '</li>'; }).join('');
|
||
|
||
renderIns();
|
||
renderTools();
|
||
}
|
||
|
||
/* 能省的地方(每条 ≤30 字),按花钱最多的几类项目给 */
|
||
function tipOf(id) {
|
||
var s = st;
|
||
switch (id) {
|
||
case 'check': return s.hosp ? '常规产检在公立医院做,只把分娩放在想去的医院。' : '跟着医生的产检表走,不额外加做没必要的项目。';
|
||
case 'checkAdd': return '无创、四维听医生建议做,不必为安心把自费项都加上。';
|
||
case 'pgoods': return '孕妇装两三套换着穿,待产包照清单买,不多囤。';
|
||
case 'birth': return s.ins === 2 ? '不少地方灵活就业也能交医保报生育费用,早点去问。' : s.hosp ? '公立普通病房也安全,单间按需再升级。' : '提前问清医保能否直接结算,出院少垫钱。';
|
||
case 'yz': return ['月子餐自己做,产妇用品按需买不囤货。', '钟点工只请做饭时段,打扫家人分担。', '月嫂可只请前 2 周,之后家人接手。', '月子中心可只住 2 周,后面换月嫂或家人接手。'][s.yz];
|
||
case 'formula': return '奶粉先买小罐试,宝宝喝着合适再按需补,别囤货。';
|
||
case 'diaper': return '纸尿裤趁大促按需囤,小码别一次囤太多。';
|
||
case 'goods': return s.first ? '老大的衣物推车先翻出来,缺什么再补。' : '大件能借就借,衣服各尺码几套够换洗就行。';
|
||
case 'vac': return '自费疫苗按医生建议排先后,不必一次全打。';
|
||
case 'bx': return '先配医疗险和意外险,重疾险保额够用就行。';
|
||
case 'edu': return '早教班不用早报,绘本玩具可以借阅轮换。';
|
||
case 'care': return ['给老人的补贴量力而行,换来的是安心。', '优先申请普惠托班,通常比私立便宜不少。', '老人能搭把手的话,育儿嫂可只请白天或半天。', '可以先上半日托,或等 2 岁后再上全日托。'][s.care];
|
||
case 'food': return '辅食自己做,少买小包装零食。';
|
||
case 'med': return '出生后尽快给宝宝办少儿医保,看病能报一部分。';
|
||
}
|
||
return '';
|
||
}
|
||
|
||
function renderIns() {
|
||
var c = st.city, r = reimb(st), rs = r[1] ? rng(r) : '';
|
||
var T = ['职工生育保险:能报还能领津贴', '城乡居民医保:分娩能报一部分', '还没有医保:先按全自费算'];
|
||
var D = [
|
||
'产检、分娩按当地标准报销,上面已扣掉约 ' + rs + '。产假期间还能领生育津贴。',
|
||
'住院分娩按居民医保报销或定额补助,上面已扣掉约 ' + rs + ';没有生育津贴。',
|
||
'灵活就业可以按当地规定参加医保,交费满一定时间才能报生育费用,越早问越好。'
|
||
];
|
||
$('#insT').textContent = T[st.ins];
|
||
$('#insD').textContent = D[st.ins];
|
||
var f = $('#insF');
|
||
f.style.display = st.ins === 0 ? '' : 'none';
|
||
f.textContent = '生育津贴 = 单位上年度职工月平均工资 ÷ 30 × 产假天数';
|
||
var w = COST.wage[c], jt = [w[0] / 30 * 158, w[1] / 30 * 158];
|
||
var bm = '';
|
||
if (st.ins === 0) bm += '<div><span>生育津贴(粗算)</span><b class="num">' + rng(jt) + '</b><small>按 158 天产假、当地平均工资</small></div>';
|
||
bm += '<div><span>国家育儿补贴</span><b class="num">1.08万</b><small>3 岁前每年 3600 元</small></div>';
|
||
if (st.ins !== 0) bm += '<div><span>少儿医保</span><b class="num">出生就办</b><small>宝宝看病住院能报一部分</small></div>';
|
||
$('#bm').innerHTML = bm;
|
||
}
|
||
|
||
function renderTools() {
|
||
if (!window.TopicTools) return;
|
||
var list = [
|
||
{ id: 'daichanqingdan', why: '列清单按需买,避免重复花钱', tag: '省钱' },
|
||
{ id: 'chanjianrili', why: '产检时间项目排好,自费项心里有数' },
|
||
{ id: 'bushui', why: '按需补,不跟风乱买补剂' }
|
||
];
|
||
if (st.feed === 0) list.push({ id: 'yunqinengbuchi', why: '备母乳从孕期吃对开始,不乱买补品' });
|
||
var el = $('#tools');
|
||
el.className = 'fu' + (el.classList.contains('in') ? ' in' : '');
|
||
TopicTools.render(el, list, { title: '帮你少花冤枉钱', color: '#18A058', bg: '#EAF7F0', wk: 0 });
|
||
}
|
||
|
||
$('#tabs').addEventListener('click', function (e) {
|
||
var b = e.target.closest('button'); if (!b) return;
|
||
stage = +b.dataset.s; save(); renderRes(false);
|
||
});
|
||
$('#mine').addEventListener('click', function (e) {
|
||
var b = e.target.closest('button'); if (!b) return;
|
||
cur = b.dataset.k; editing = true; renderQ();
|
||
});
|
||
|
||
/* 进场:结果屏各节 fade-up,60ms 错开 */
|
||
var io = 'IntersectionObserver' in window ? new IntersectionObserver(function (es) {
|
||
es.forEach(function (e) { if (e.isIntersecting) { e.target.classList.add('in'); io.unobserve(e.target); } });
|
||
}, { root: sc, threshold: .06 }) : null;
|
||
function observe() {
|
||
[].forEach.call(document.querySelectorAll('#sRes .fu'), function (el, i) {
|
||
el.style.transitionDelay = (i % 4) * 60 + 'ms';
|
||
if (io) io.observe(el); else el.classList.add('in');
|
||
});
|
||
}
|
||
|
||
/* ================= 存取 ================= */
|
||
function save() {
|
||
try {
|
||
var o = { v: {}, ans: Object.keys(ans), stage: stage, done: hasResult };
|
||
QS.forEach(function (q) { o.v[q.k] = st[q.k]; });
|
||
localStorage.setItem(KEY, JSON.stringify(o));
|
||
} catch (e) {}
|
||
}
|
||
function valid(k, v) { return typeof v === 'number' && v >= 0 && v < QK[k].o.length; }
|
||
function load() {
|
||
try {
|
||
var o = JSON.parse(localStorage.getItem(KEY) || 'null');
|
||
if (o && o.v) {
|
||
QS.forEach(function (q) { if (valid(q.k, o.v[q.k])) st[q.k] = o.v[q.k]; });
|
||
(o.ans || []).forEach(function (k) { if (QK[k]) ans[k] = 1; });
|
||
if (o.stage >= 0 && o.stage < 4) stage = o.stage;
|
||
return !!o.done;
|
||
}
|
||
// 兼容 v2:city/hosp/way/feed 原样;月子 0/1/2 → 0/2/3;带娃 0/1/2 → 0/2/3;花钱风格拆到用品、纸尿裤、早教
|
||
var p = JSON.parse(localStorage.getItem(KEY2) || 'null'); if (!p) return false;
|
||
var m = { city: p.city, hosp: p.hosp, way: p.way, feed: p.feed, yz: [0, 2, 3][p.yz], care: [0, 2, 3][p.care] };
|
||
if (p.style >= 0 && p.style < 3) { m.gear = p.style; m.diaper = p.style; m.edu = [0, 0, 2][p.style]; }
|
||
var n = 0;
|
||
for (var k in m) if (valid(k, m[k])) { st[k] = m[k]; ans[k] = 1; n++; }
|
||
if (p.stage >= 0 && p.stage < 4) stage = p.stage;
|
||
return n >= 5;
|
||
} catch (e) { return false; }
|
||
}
|
||
|
||
hasResult = load();
|
||
renderStart();
|
||
if (hasResult) { renderRes(true); show('sRes'); observe(); } else show('sStart');
|
||
|
||
/* 返回:从首页点进来就 back;直接打开(分享 / 刷新)就回同目录的首页,身份原样带回 */
|
||
$('#back').addEventListener('click', function () {
|
||
if (document.referrer && document.referrer.indexOf(location.host) >= 0 && history.length > 1) history.back();
|
||
else location.href = '../../' + location.search + location.hash;
|
||
});
|
||
|
||
sc.addEventListener('scroll', function () { $('#bar').classList.toggle('on', sc.scrollTop > 4); }, { passive: true });
|
||
|
||
/* 禁止下拉回弹:固定外壳 + 容器滚动 + 到顶/到底时拦 touchmove */
|
||
var y0 = 0;
|
||
sc.addEventListener('touchstart', function (e) { y0 = e.touches[0].clientY; }, { passive: true });
|
||
sc.addEventListener('touchmove', function (e) {
|
||
var dy = e.touches[0].clientY - y0;
|
||
if ((sc.scrollTop <= 0 && dy > 0) || (sc.scrollTop + sc.clientHeight >= sc.scrollHeight - 1 && dy < 0)) e.preventDefault();
|
||
}, { passive: false });
|
||
document.addEventListener('touchmove', function (e) { if (!sc.contains(e.target)) e.preventDefault(); }, { passive: false });
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|