Compare commits
4 Commits
b3f13468a9
...
02ac6a9a3d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
02ac6a9a3d | ||
|
|
b32bda8375 | ||
|
|
ef73ea7463 | ||
|
|
77296cd1c4 |
10
index.html
10
index.html
@@ -7,7 +7,7 @@
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<title>兜爸心选 · 孕育陪伴</title>
|
||||
<!-- V:26101025 缓存版本标记:改 css/js 时同步 bump 该值(与 js/app.js 的 VER 同源),静态资源按 mtime 走 ETag 自动刷新 -->
|
||||
<!-- V:26101029 缓存版本标记:改 css/js 时同步 bump 该值(与 js/app.js 的 VER 同源),静态资源按 mtime 走 ETag 自动刷新 -->
|
||||
<link rel="stylesheet" href="mama-box.css">
|
||||
<link rel="stylesheet" href="night.css">
|
||||
<!-- 夜晚模式:首屏绘制前就按上次的选择加 class,避免先白后黑闪一下(开关在首页右上角 #nightBtn,逻辑见 app.js) -->
|
||||
@@ -1016,8 +1016,10 @@
|
||||
#meExchDrop 已删,renderDrop() 里有 if (box) 判空,不用改 JS。 -->
|
||||
<button class="mall-strip exch ripple" id="meExchCard">
|
||||
<span class="ms-ico" aria-hidden="true"><img src="assets/img/dou-coin.svg?v=20261002" width="28" height="28" alt=""></span>
|
||||
<span class="ms-main"><b>兜豆兑好物</b><span id="meExchSub">攒兜豆,好物免费兑</span></span>
|
||||
<span class="ms-go">去兑换<i>›</i></span>
|
||||
<span class="ms-main"><b>兜豆兑换</b><span id="meExchSub">攒兜豆,好物免费兑</span></span>
|
||||
<!-- 2026-10-11 用户:兜豆余额要明显,不放副标题小字 → 右侧大号数字;拿到余额前 / 访客显示「去兑换」 -->
|
||||
<span class="ms-bal hide" id="meDouBal"><b id="meDouN">0</b><small>兜豆</small></span>
|
||||
<span class="ms-go" id="meExchGo">去兑换<i>›</i></span>
|
||||
</button>
|
||||
|
||||
|
||||
@@ -2036,6 +2038,8 @@
|
||||
加载失败/离线时 window.wx 为 undefined,goMall() 会降级为 toast 提示,
|
||||
不影响应用其余功能。 -->
|
||||
|
||||
<!-- 统一头像面板(预设妈妈/宝宝头像 + 从相册上传 + 用微信头像),孕期档案点头像用 -->
|
||||
<script src="/_bridge/avatar-picker.js?v=26101104"></script>
|
||||
<script src="js/zodiac-art.js"></script>
|
||||
<script src="js/app.js"></script>
|
||||
<!-- 2026-10-03 首页彩蛋:宝宝在肚皮底下动(独立文件,删掉这一行即整体下线;开关在「隐私权限」) -->
|
||||
|
||||
63
js/app.js
63
js/app.js
@@ -3,7 +3,7 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
/* 页面版本号(YYMMDD+序号):显示在「关于兜爸心选」页底部;bump 时同步 head 注释与 ?v= */
|
||||
var VER = '26101025';
|
||||
var VER = '26101029';
|
||||
const $ = (s, c) => (c || document).querySelector(s);
|
||||
const $$ = (s, c) => Array.from((c || document).querySelectorAll(s));
|
||||
|
||||
@@ -1214,6 +1214,7 @@
|
||||
};
|
||||
}
|
||||
|
||||
let pickedAvatar = ''; /* 孕期档案里从头像面板选中的正式 URL,见 openAvatarPanel */
|
||||
const pgName = $('#pgName'), pgDue = $('#pgDue'),
|
||||
pgWeek = $('#pgWeek'), pgDay = $('#pgDay'), pgHint = $('#pgHint');
|
||||
|
||||
@@ -1255,6 +1256,7 @@
|
||||
/* 打开资料弹窗时的表单回填:全部以服务端档案为准(最后写入者胜)。
|
||||
新用户(未完善资料):昵称/小名/预产期/孕周全空 + 孕周锁定,只留 placeholder。 */
|
||||
function fillProfileForm() {
|
||||
pickedAvatar = '';
|
||||
$('#pfName').value = state.userName || '';
|
||||
/* 方案A(2026-10-10):未授权 → 妈妈栏换成授权提示,旧昵称/头像不露出 */
|
||||
var _ua = state.authorized === false;
|
||||
@@ -1870,12 +1872,38 @@
|
||||
/* 点大圆 → 转交给隐藏的 file input。openModal 里会 focus 第一个输入框,
|
||||
这里 avFile 排在 pfName 前面,所以 openModal 用的选择器只取 .modal-ta/input
|
||||
可能命中 file input——用 :not([type=file]) 排除掉,见 openModal */
|
||||
avBig.addEventListener('click', e => { e.stopPropagation(); avFile.click(); });
|
||||
/* 2026-10-11 用户:点头像弹预设选项,也能从相册上传、用微信头像 → 走统一头像面板 avatarPicker
|
||||
(/_bridge/avatar-picker.js:选完自己上传、派发 mmbox:avatar;共享资料改到保存时写)。
|
||||
选中的是正式 URL,记在 pickedAvatar,保存时一起 PUT 进首页档案;面板没加载上才退回系统选图。 */
|
||||
function openAvatarPanel() {
|
||||
if (window.avatarPicker && window.avatarPicker.open) {
|
||||
window.avatarPicker.open({
|
||||
current: avBig.classList.contains('has-img') ? avPreview.src : '',
|
||||
accent: '#F4593C', accentSoft: '#FDECE7',
|
||||
onPick: function (url) {
|
||||
/* 2026-10-11 用户:点「保存资料」后才让所有应用同步头像。面板 done() 里紧接着 onPick
|
||||
会同步调 syncShared → wxAuth.identity(),这里让那一次拿到空身份,面板就不写共享资料;
|
||||
真正的共享写入放到 #pfSave 里(syncSharedAvatar)。 */
|
||||
var wa = window.wxAuth;
|
||||
if (wa && wa.identity) {
|
||||
var _id = wa.identity, _back = function () { wa.identity = _id; };
|
||||
wa.identity = function () { _back(); return {}; };
|
||||
setTimeout(_back, 0);
|
||||
}
|
||||
pickedAvatar = url;
|
||||
avFile.value = '';
|
||||
avPreview.src = url; avBig.classList.add('has-img');
|
||||
haptic();
|
||||
}
|
||||
});
|
||||
} else avFile.click();
|
||||
}
|
||||
avBig.addEventListener('click', e => { e.stopPropagation(); openAvatarPanel(); });
|
||||
/* 孕期档案里头像是一整行,点行上任何地方都换头像 */
|
||||
const pfMeRow = $('#pfMe');
|
||||
if (pfMeRow) {
|
||||
pfMeRow.addEventListener('click', e => { if (e.target !== avFile) avFile.click(); });
|
||||
pfMeRow.addEventListener('keydown', e => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); avFile.click(); } });
|
||||
pfMeRow.addEventListener('click', e => { if (e.target !== avFile) openAvatarPanel(); });
|
||||
pfMeRow.addEventListener('keydown', e => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); openAvatarPanel(); } });
|
||||
}
|
||||
|
||||
avFile.addEventListener('change', () => {
|
||||
@@ -1885,6 +1913,7 @@
|
||||
if (f.size > 8 * 1024 * 1024) { toast('图片太大了,换一张小于 8MB 的'); return; }
|
||||
const r = new FileReader();
|
||||
/* 读成 data URI 就地预览:产物是单文件、没有后端,不做真正的上传 */
|
||||
pickedAvatar = '';
|
||||
r.onload = () => { avPreview.src = r.result; avBig.classList.add('has-img'); haptic(); };
|
||||
r.onerror = () => toast('这张图读不出来,换一张试试');
|
||||
r.readAsDataURL(f);
|
||||
@@ -1935,6 +1964,14 @@
|
||||
上传失败则跳过头像字段(昵称/孕育照存)。断网/接口失败静默,本地已生效。 ---- */
|
||||
var _oid = hashParam('openid');
|
||||
var _wasEmpty = state.pregEmpty; /* 新用户完善资料后 → 重载拉真实孕周 */
|
||||
/* 保存时才把头像写进共享资料(auth/profile),其它应用读 user-center/info 就会跟着换 */
|
||||
function syncSharedAvatar(url) {
|
||||
var id = (window.wxAuth && wxAuth.identity && wxAuth.identity()) || {};
|
||||
if (!url || !id.openid) return;
|
||||
var q = '?openid=' + encodeURIComponent(id.openid) + (id.unionid ? '&unionid=' + encodeURIComponent(id.unionid) : '');
|
||||
fetch('/api/mp/public/auth/profile' + q + '&avatar=' + encodeURIComponent(url), { method: 'POST' }).catch(function () {});
|
||||
try { window.dispatchEvent(new CustomEvent('mmbox:avatar', { detail: { url: url, source: 'save', for: 'mom' } })); } catch (e) {}
|
||||
}
|
||||
function _putProfile(avatarUrl) {
|
||||
if (!_oid) return;
|
||||
var body = {
|
||||
@@ -1967,7 +2004,13 @@
|
||||
});
|
||||
}
|
||||
var newAvatarFile = (avFile.files && avFile.files[0]) || null;
|
||||
if (newAvatarFile && avBig.classList.contains('has-img')) {
|
||||
if (pickedAvatar && !_unauth) {
|
||||
/* 头像面板选的已经是正式 URL(预设图 / 面板自己上传过),直接写 */
|
||||
$('#meAvatar').classList.add('has-img');
|
||||
_putProfile(pickedAvatar);
|
||||
syncSharedAvatar(pickedAvatar);
|
||||
pickedAvatar = '';
|
||||
} else if (newAvatarFile && avBig.classList.contains('has-img')) {
|
||||
var fd = new FormData();
|
||||
fd.append('file', newAvatarFile, newAvatarFile.name || 'avatar.png');
|
||||
fetch('/api/upload', { method: 'POST', body: fd })
|
||||
@@ -1975,6 +2018,7 @@
|
||||
.then(function (res) {
|
||||
var url = res && res.result && res.result.url;
|
||||
_putProfile(url || '');
|
||||
if (!_unauth) syncSharedAvatar(url);
|
||||
})
|
||||
.catch(function () { _putProfile(''); });
|
||||
} else {
|
||||
@@ -5507,6 +5551,15 @@
|
||||
if (!sum.balance) setExchSub('攒兜豆,好物免费兑');
|
||||
else if (!d) setExchSub('兜豆 ' + sum.balance);
|
||||
else setExchSub('兜豆 ' + sum.balance + (n ? ' · 可兑 ' + n + ' 件' : ' · 再攒攒就能兑'));
|
||||
/* 「我的」页:余额放右侧大号数字(2026-10-11 用户),副标题只说能兑几件 */
|
||||
const bal = $('#meDouBal');
|
||||
if (bal) {
|
||||
$('#meDouN').textContent = String(sum.balance).replace(/\B(?=(\d{3})+$)/g, ',');
|
||||
bal.classList.remove('hide');
|
||||
const go = $('#meExchGo'); if (go) go.classList.add('hide');
|
||||
const sub = $('#meExchSub');
|
||||
if (sub) sub.textContent = !sum.balance ? '做孕期任务就能攒兜豆' : !d ? '去看看能兑什么' : n ? '现在可兑 ' + n + ' 件好物' : '再攒攒就能兑好物';
|
||||
}
|
||||
});
|
||||
}).catch(function () {});
|
||||
}
|
||||
|
||||
19
mama-box.css
19
mama-box.css
@@ -4837,3 +4837,22 @@ a.skip:focus{left:16px;top:16px}
|
||||
.pk-ok{display:block;width:100%;margin-top:16px}
|
||||
.pk-alt{margin-top:12px;font-size:12.5px;color:var(--muted);text-decoration:underline;text-underline-offset:3px}
|
||||
|
||||
/* 「我的」页兜豆兑换条:余额右侧大号显示(2026-10-11),数字用品牌橘、单位淡色小字,后面跟箭头 */
|
||||
/* 兜豆条是半透明磨砂卡,压在「我的」页暖粉渐变上,橘色数字直接写会和底色糊在一起 →
|
||||
放进一颗实心品牌橘胶囊、白字,和背景拉开(2026-10-11 用户:「跟后面的背景色靠色了」) */
|
||||
.ms-bal{flex:none;display:flex;align-items:center;gap:4px;padding:6px 8px 6px 12px;border-radius:99px;
|
||||
background:linear-gradient(135deg,#FF7A55,var(--brand));color:#fff;box-shadow:0 6px 14px rgba(244,89,60,.28)}
|
||||
.ms-bal b{font-size:19px;font-weight:900;letter-spacing:-.3px;line-height:1;font-variant-numeric:tabular-nums}
|
||||
.ms-bal small{font-size:11.5px;font-weight:700;color:rgba(255,255,255,.88)}
|
||||
.ms-bal::after{content:"›";margin-left:2px;font-size:17px;line-height:1;color:rgba(255,255,255,.9)}
|
||||
.ms-bal.hide,.ms-go.hide{display:none}
|
||||
|
||||
/* 统一头像面板(/_bridge/avatar-picker.js)在首页的样式补丁(2026-10-11 用户):
|
||||
首页全局 button{text-align:left} 把面板两颗按钮的字挤到了左边 → 居中;
|
||||
右上角关闭叉原来是浅灰底浅灰字,看不清 → 加大、深色叉、白底描边 */
|
||||
.avp-btn{text-align:center;display:flex;align-items:center;justify-content:center}
|
||||
.avp-x{width:36px!important;height:36px!important;display:grid;place-items:center;padding:0;
|
||||
background:#fff!important;color:var(--ink)!important;font-size:24px!important;font-weight:500;line-height:1;
|
||||
box-shadow:0 0 0 1.5px #E7DCD5,0 3px 10px rgba(90,50,35,.12)}
|
||||
.avp-x:active{transform:scale(.92)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user