头像按模块分配互不重复:js/ava-pool.js(375 个装饰头像分 12 段),评论区让出这些人设改同类替补(v26110440)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
deploy
2026-11-05 01:01:18 +00:00
parent 72fcdaeea5
commit 20613191f5
125 changed files with 243 additions and 220 deletions

View File

@@ -3,7 +3,7 @@
(function () {
'use strict';
/* 页面版本号(YYMMDD+序号):显示在「关于兜爸心选」页底部;bump 时同步 head 注释与 ?v= */
var VER = '26110439';
var VER = '26110440';
const $ = (s, c) => (c || document).querySelector(s);
const $$ = (s, c) => Array.from((c || document).querySelectorAll(s));
@@ -4199,11 +4199,12 @@
妈妈近脸从 22 张砍到 14 张(去掉最像的几张),优先半身 / 户外 / 孕肚(m18~m22),每 3 个里最多 1 张妈妈脸;
两池仍不相交:AVA_TOP 18 张、AVA_FEED 29 张。同日额度充上后补 14 张 p01~p14(孕妇全身、夫妻合照、一家三口、生活场景),
两池各约 1/3 是 p*,妈妈近脸 m* 退到一半以下;AVA_TOP 23 张、AVA_FEED 37 张,仍不相交。 */
const AVA_TOP = ['p01', 'k01', 's02', 'm20', 'p02', 'mom-03', 'k04', 'p03', 's05', 'baby-02', 'm13', 'p04', 'k06', 's09', 'p05', 'mom-11', 'k10', 'p06', 'm21', 's10', 'p07', 'baby-06', 'k12'];
const AVA_FEED = ['p08', 'k02', 's01', 'm01', 'p09', 'k03', 'mom-05', 'p10', 's03', 'm18', 'k05', 'p11', 's04', 'baby-04', 'm22', 'p12', 'k07', 's06', 'mom-08', 'p13', 'm03', 'k08', 's07', 'p14', 'm19', 'k09', 's08', 'mom-14', 'm09', 'k11', 'baby-09', 'm11', 'k13', 'mom-17', 'm14', 'm15', 'm17'];
/* 11-05 用户:各模块头像不要互相重复 → 改读 js/ava-pool.js 的分配表(pulseTop / pulseFeed),下面两行原表只作加载失败兜底 */
const AVA_TOP = (window.MB_AVA && MB_AVA.S.pulseTop) || ['p01', 'k01', 's02', 'm20', 'p02', 'mom-03', 'k04', 'p03', 's05', 'baby-02', 'm13', 'p04', 'k06', 's09', 'p05', 'mom-11', 'k10', 'p06', 'm21', 's10', 'p07', 'baby-06', 'k12'];
const AVA_FEED = (window.MB_AVA && MB_AVA.S.pulseFeed) || ['p08', 'k02', 's01', 'm01', 'p09', 'k03', 'mom-05', 'p10', 's03', 'm18', 'k05', 'p11', 's04', 'baby-04', 'm22', 'p12', 'k07', 's06', 'mom-08', 'p13', 'm03', 'k08', 's07', 'p14', 'm19', 'k09', 's08', 'mom-14', 'm09', 'k11', 'baby-09', 'm11', 'k13', 'mom-17', 'm14', 'm15', 'm17'];
/* mom-* / baby-* 取自统一头像库 /_bridge/avatars/(2026-10-11 用户:「可以适当调几个我库里预存的头像,妈妈和宝宝的」);
其余仍是 assets/img/mom/ 下的写实照片。库头像是 256px 透明底 PNG,底色由 .pr-ava / .pp-avs i 的 #FFE3D3 托住。 */
const avaSrc = n => /^(mom|baby)-\d+$/.test(n) ? 'https://mp.yizhezhe.com/_bridge/avatars/' + n + '.png' : 'assets/img/mom/' + n + '.jpg';
const avaSrc = n => /:|^\//.test(n) && window.MB_AVA ? MB_AVA.src(n, '') : /^(mom|baby)-\d+$/.test(n) ? 'https://mp.yizhezhe.com/_bridge/avatars/' + n + '.png' : 'assets/img/mom/' + n + '.jpg';
const avaImg = n => '<img src="' + avaSrc(n) + '" alt="" loading="lazy" decoding="async" width="48" height="48">';
const strSeed = t => { let x = 7; for (let i = 0; i < t.length; i++) x = (x * 31 + t.charCodeAt(i)) | 0; return Math.abs(x); };
/* ================= 孕妈广场 · 首页入口(2026-11-01 第一版,占位内容) =================
@@ -4235,7 +4236,7 @@
一块可横滑的地面,话题是一个个说话气泡、气泡下站着一位妈妈的头像,一高一低「之」字形排开、轻轻浮动;
背景一条虚线小路从每个头像脚下穿过,空地上零星散着几个在逛的小头像。隔一个气泡带照片(topics.js 的 ph);「全部」里都是热门,不再逐个挂「热」。 */
const CAT_CN = { family: '家庭婚姻', work: '职场', baby: '经验' };
const POOL = AVA_FEED.concat(AVA_TOP).filter(n => /^(p|m|mom-)\d/.test(n)); // 只用妈妈头像,k/s/baby 是孩子和风景
const POOL = (window.MB_AVA && MB_AVA.S.gbWalk) || AVA_FEED.concat(AVA_TOP).filter(n => /^(p|m|mom-)\d/.test(n)); // 11-05 改用分配表 gbWalk(不和「此刻」撞)
function bubble(t, i, allHot) {
const ph = i % 2 === 0 && t.ph;
return '<button type="button" class="gb-b' + (ph ? ' ph' : '') + (t.hot ? ' hot' : '') + '" data-t="' + esc(t.id) + '" style="--c1:' + t.c[0] + ';--c2:' + t.c[1] + ';--ink:' + t.ink + ';--d:' + (i % 5) * -.8 + 's">' +
@@ -5552,7 +5553,7 @@
if (!QA) loadQA().then(q => { if (q.length) renderSearch(wk, today, size); });
$('#msWk').textContent = '孕 ' + W + ' 周';
$('#msCnt').textContent = '孕 ' + W + ' 周的妈妈都在看';
const pool = AVA_TOP.concat(AVA_FEED), s0 = (W * 7) % pool.length;
const pool = (window.MB_AVA && MB_AVA.S.search) || AVA_TOP.concat(AVA_FEED), s0 = (W * 7) % pool.length; // 11-05 分配表 search
$('#msAvs').innerHTML = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(i => avaImg(pool[(s0 + i * 3) % pool.length])).join('');
const bank = QA || [];
let items;
@@ -5608,8 +5609,8 @@
const wan = n => n >= 1e4 ? (Math.round(n / 1e3) / 10) + '万' : String(Math.round(n));
$('#qaHeroW').textContent = band ? '孕 ' + state.week + ' 周' : '大家都在问';
$('#qaHeroT').textContent = '孕妈最常问的问题';
const s0 = ((state.week || 1) * 5) % AVA_TOP.length;
$('#qaHeroD').innerHTML = '<span class="qa-avs">' + [0, 1, 2, 3, 4].map(i => avaImg(AVA_TOP[(s0 + i * 2) % AVA_TOP.length])).join('') + '</span>' + wan(tot * 0.62) + ' 孕妈在这找答案';
const QH = (window.MB_AVA && MB_AVA.S.qaHero) || AVA_TOP, s0 = ((state.week || 1) * 5) % QH.length; // 11-05 分配表 qaHero
$('#qaHeroD').innerHTML = '<span class="qa-avs">' + [0, 1, 2, 3, 4].map(i => avaImg(QH[(s0 + i * 2) % QH.length])).join('') + '</span>' + wan(tot * 0.62) + ' 孕妈在这找答案';
const QA_BD = i => i < 1 ? ['爆', 'bao'] : i < 7 ? ['热', 're'] : i < 10 ? ['新', 'xin'] : null;
const QA_EM = { 身体: '🤰', 准备: '📋', 产检: '🩺', 宝宝: '👶', 生活: '🏠', 营养: '🥗', 职场: '💼', 花钱: '💰', 心情: '💗', 趣味: '🎈', 补剂: '💊', 专题: '📌' };
const QA_KW = {

11
js/ava-pool.js Normal file

File diff suppressed because one or more lines are too long

View File

@@ -8,15 +8,15 @@
.br-chip i{width:13px;height:13px;border-radius:50%;background:#E8735A;color:#fff;font-style:normal;font-size:8.5px;line-height:13px;text-align:center;font-weight:700}
.br-mark{position:absolute;right:12px;bottom:10px;font-size:10px;color:rgba(255,255,255,.75);letter-spacing:.06em;pointer-events:none;z-index:3}
.br-demo{position:fixed;left:10px;top:10px;z-index:9999;background:rgba(0,0,0,.55);color:#fff;font-size:11px;padding:3px 8px;border-radius:6px;pointer-events:none}
/* 11-04 用户:孕周福利卡「已领取」前的灰色人形占位 → 换成头像照片(同首页其他处的虚构头像池 assets/img/mom/,非真实用户),每张卡 3 个互不重复 */
/* 11-04 用户:孕周福利卡「已领取」前的灰色人形占位 → 头像照片;11-05 改用分配表 gift 的 9 个(js/ava-pool.js,由 alloc.py 生成,只在这里出现) */
.gift2 .sb-faces i{background-position:center;background-size:cover;background-repeat:no-repeat}
.gift2 .sb-faces i::before,.gift2 .sb-faces i::after{display:none}
.gift2 .sb-book .sb-faces i:nth-child(1){background-image:url(../../assets/img/mom/m02.jpg)}
.gift2 .sb-book .sb-faces i:nth-child(2){background-image:url(../../assets/img/mom/k03.jpg)}
.gift2 .sb-book .sb-faces i:nth-child(3){background-image:url(../../assets/img/mom/m07.jpg)}
.gift2 .sb-food .sb-faces i:nth-child(1){background-image:url(../../assets/img/mom/m11.jpg)}
.gift2 .sb-food .sb-faces i:nth-child(2){background-image:url(../../assets/img/mom/p05.jpg)}
.gift2 .sb-food .sb-faces i:nth-child(3){background-image:url(../../assets/img/mom/m15.jpg)}
.gift2 .shelf-book:nth-child(3) .sb-faces i:nth-child(1){background-image:url(../../assets/img/mom/k08.jpg)}
.gift2 .shelf-book:nth-child(3) .sb-faces i:nth-child(2){background-image:url(../../assets/img/mom/m17.jpg)}
.gift2 .shelf-book:nth-child(3) .sb-faces i:nth-child(3){background-image:url(../../assets/img/mom/m05.jpg)}
.gift2 .sb-book .sb-faces i:nth-child(1){background-image:url(../../guangchang/av/n302.webp)}
.gift2 .sb-book .sb-faces i:nth-child(2){background-image:url(../../guangchang/av/f045.webp)}
.gift2 .sb-book .sb-faces i:nth-child(3){background-image:url(../../guangchang/av/a014.webp)}
.gift2 .sb-food .sb-faces i:nth-child(1){background-image:url(../../guangchang/av/n026.webp)}
.gift2 .sb-food .sb-faces i:nth-child(2){background-image:url(../../guangchang/av/q010.webp)}
.gift2 .sb-food .sb-faces i:nth-child(3){background-image:url(../../guangchang/av/n252.webp)}
.gift2 .shelf-book:nth-child(3) .sb-faces i:nth-child(1){background-image:url(../../guangchang/av/c101.webp)}
.gift2 .shelf-book:nth-child(3) .sb-faces i:nth-child(2){background-image:url(../../guangchang/av/f018.webp)}
.gift2 .shelf-book:nth-child(3) .sb-faces i:nth-child(3){background-image:url(../../guangchang/av/n287.webp)}

View File

@@ -7,7 +7,7 @@
function init() {
var esc = function (s) { return String(s == null ? '' : s).replace(/[&<>"]/g, function (c) { return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[c]; }); };
var kfmt = function (n) { return n >= 10000 ? (n / 10000).toFixed(1).replace(/\.0$/, '') + '万' : n >= 1000 ? (n / 1000).toFixed(1).replace(/\.0$/, '') + 'k' : String(n); };
var ava = function (n) { return 'assets/img/mom/' + n + '.jpg'; };
var ava = function (n) { return /:|^\//.test(n) && window.MB_AVA ? MB_AVA.src(n, '') : 'assets/img/mom/' + n + '.jpg'; }; /* 11-05 支持分配表编码 */
var reduce = window.matchMedia && matchMedia('(prefers-reduced-motion: reduce)').matches;
var CAT_CN = { family: '家庭婚姻', work: '职场', baby: '经验分享' }; /* 11-03 卡上话题标签同广场:经验 → 经验分享 */
var TOP = {}; T.forEach(function (t) { TOP[t.id] = t; });
@@ -27,7 +27,7 @@
l.forEach(function (n) { var c = (TOP[n.t] || {}).cat; if (out.length < 7 && (cnt[c] || 0) < 3) { cnt[c] = (cnt[c] || 0) + 1; out.push(n); } });
l = out;
}
return l.slice(0, 7).map(function (n, i) { return { t: n.t, id: n.id, title: n.title, author: n.author, stage: n.stage, likes: n.likes, photo: n.photo, av: MOMS[(i * 5 + (cat ? cat.length : 0)) % MOMS.length] }; });
return l.slice(0, 7).map(function (n, i) { return { t: n.t, id: n.id, title: n.title, author: n.author, stage: n.stage, likes: n.likes, photo: n.photo, av: (window.MB_AVA && MB_AVA.S.author[n.id]) || MOMS[(i * 5 + (cat ? cat.length : 0)) % MOMS.length] }; /* 11-05 作者头像按帖子固定(同广场、同「大家都在关注」) */ });
}
function topics(cat) {
var l = T.filter(function (t) { return !cat || t.cat === cat; });
@@ -75,7 +75,7 @@
'<span class="g4-s-r"><span><b>¥30</b><i>现金</i></span><em>+</em><span><b>500</b><i>兜豆</i></span></span>' +
'<span class="g4-s-n">被选中即可获得</span>' +
'<span class="g4-s-go">去投稿 ›</span>' +
'<span class="g4-s-avs" aria-hidden="true">' + ['m02', 'p04', 'm09', 'p13', 'm18'].map(function (n) { return '<img src="' + ava(n) + '" alt="" loading="lazy" draggable="false">'; }).join('') + '<i>本周已有 326 位妈妈投稿</i></span></div>';
'<span class="g4-s-avs" aria-hidden="true">' + ((window.MB_AVA && MB_AVA.S.submit) || ['m02', 'p04', 'm09', 'p13', 'm18']).map(function (n) { return '<img src="' + ava(n) + '" alt="" loading="lazy" draggable="false">'; }).join('') + '<i>本周已有 326 位妈妈投稿</i></span></div>';
}
function paint(cat, first) {
cur = cat; idx = 0;
@@ -244,5 +244,5 @@
}
/* feed.js 首页默认不加载(index.html 只引了 topics.js),这里按需拉一次 */
if (window.GC_FEED) init();
else { var fs = document.createElement('script'); fs.src = 'guangchang/feed.js?v=26110439'; fs.onload = fs.onerror = init; document.body.appendChild(fs); }
else { var fs = document.createElement('script'); fs.src = 'guangchang/feed.js?v=26110440'; fs.onload = fs.onerror = init; document.body.appendChild(fs); }
})();

View File

@@ -6,9 +6,9 @@
(function () {
var sec = document.getElementById('gcHome');
if (!sec) return;
var l = document.createElement('link'); l.rel = 'stylesheet'; l.href = 'js/gch/v4.css?v=26110439';
var l = document.createElement('link'); l.rel = 'stylesheet'; l.href = 'js/gch/v4.css?v=26110440';
document.head.appendChild(l);
var s = document.createElement('script'); s.src = 'js/gch/v4.js?v=26110439';
var s = document.createElement('script'); s.src = 'js/gch/v4.js?v=26110440';
s.onload = function () { if (sec.querySelector('.g4-foot')) merge(); else sec.addEventListener('gc4-ready', merge, { once: true }); }; /* v4 要先拉 feed.js 才渲染 */
document.body.appendChild(s);
@@ -94,7 +94,7 @@
list.innerHTML = l6.map(function (x, i) {
/* 11-04 用户:一行放下 作者头像 + 名字 + 点赞头像(仅前 3 条)+ N 点赞;不要小心心、不换行;同日再改:名字后面的孕周删掉 */
var n = x.likes || 0,
au = x.author ? '<span class="g6-au"><img src="' + esc(x.avatar || auAv(x.author)) + '" alt="" loading="lazy" decoding="async" width="36" height="36"><b>' + esc(x.author) + '</b></span>' : '',
au = x.author ? '<span class="g6-au"><img src="' + esc(x.avatar || (window.MB_AVA && MB_AVA.S.author[x.id] ? MB_AVA.src(MB_AVA.S.author[x.id], '') : auAv(x.author))) + '" alt="" loading="lazy" decoding="async" width="36" height="36"><b>' + esc(x.author) + '</b></span>' : '',
heat = '<span class="g6-meta">' + au + '<span class="g6-rt">' + (i < 3 ? avs(i) : '') + '<span class="ms-h"><b>' + (n >= 1e4 ? Math.round(n / 1e3) / 10 + '万' : n) + ' 人点赞</b></span></span></span>'; /* 11-04 用户:作者在左;访客头像 + 点赞数一起靠最右(点赞数在头像右边) */
var q = new URLSearchParams(location.search); q.set('n', x.id);
return '<a class="ms-it ripple g6-nt" href="' + esc('guangchang/?' + q.toString() + location.hash) + '"><i class="ms-no">' + (i + 1) + '</i>' +
@@ -120,7 +120,8 @@
头像池用首页滚动动态同一批虚构照片(assets/img/mom/,非真实用户);页面在后台时不换。 */
/* 11-03 用户:「这 6 条的头像一定要都不相同」→ 池子扩到 assets/img/mom/ 全部 59 张,按 宝宝 / 妈妈 / 全身合照 / 风景 交错排,相邻不扎堆近脸;
换头像时只从「当前 6 行都没在显示」的里面挑,任何时刻页面上这些头像都互不重复。 */
var LIKE_AVA = (function () {
/* 11-05 用户:各模块头像不要互相重复 → 点赞头像改用分配表 likers(24 个,只在这里出现);原 mom 池仅作兜底 */
var LIKE_AVA = (window.MB_AVA && MB_AVA.S.likers) || (function () {
var g = { p: 14, k: 13, m: 22, s: 10 }, o = [], i;
for (i = 0; o.length < 59; i++) ['p', 'm', 'k', 'm', 's'].forEach(function (c, j) {
var n = c === 'm' ? i * 2 + (j === 1 ? 1 : 2) : i + 1;
@@ -129,7 +130,8 @@
return o;
})();
var avaAt = 0;
function avaEl(n) { return '<img src="assets/img/mom/' + n + '.jpg" alt="" loading="lazy" decoding="async" width="40" height="40">'; }
function lkSrc(n) { return /:|^\//.test(n) && window.MB_AVA ? MB_AVA.src(n, '') : 'assets/img/mom/' + n + '.jpg'; }
function avaEl(n) { return '<img src="' + lkSrc(n) + '" alt="" loading="lazy" decoding="async" width="40" height="40">'; }
/* 11-03 用户:「头像错落一下,不一定都是 3 个,3、4、5、6 个都有」→ 每行个数打乱(固定表,刷新不跳),头像按顺序不重复取 */
var AV_N = [5, 4, 6]; /* 11-04 三改:作者 + 孕周 + 点赞头像要挤一行,6~8 个放不下 → 4~6 个 */ /* 11-04 二改:只前 3 条带头像,每条 6~8 个、头像缩小 */
function avs(i) {
@@ -145,9 +147,9 @@
if (!ims.length) return;
var im = ims[Math.floor(Math.random() * ims.length)], on = {}, nx, t = 0;
list.querySelectorAll('.g6-avs img').forEach(function (m) { on[m.getAttribute('src')] = 1; });
do { nx = LIKE_AVA[avaAt++ % LIKE_AVA.length]; } while (on['assets/img/mom/' + nx + '.jpg'] && ++t < LIKE_AVA.length);
do { nx = LIKE_AVA[avaAt++ % LIKE_AVA.length]; } while (on[lkSrc(nx)] && ++t < LIKE_AVA.length);
im.className = 'sw-o';
setTimeout(function () { im.src = 'assets/img/mom/' + nx + '.jpg'; im.className = 'sw-i'; }, 220);
setTimeout(function () { im.src = lkSrc(nx); im.className = 'sw-i'; }, 220);
}
function likeTick() {
likeT.forEach(clearTimeout); likeT = [];

View File

@@ -9,7 +9,7 @@
if (/[?&]kit=0(?:&|$)/.test(location.search)) return;
var box = document.getElementById('kit'), sec = document.getElementById('kitHome');
if (!box || !sec) return;
var V = '26110439';
var V = '26110440';
var l = document.createElement('link'); l.rel = 'stylesheet'; l.href = 'js/kit.css?v=' + V; document.head.appendChild(l);
document.documentElement.classList.add('has-kit');
@@ -150,6 +150,8 @@
'团团圆圆', '小雨点', '西瓜太甜', '慢慢来'];
var LV_AV = ['p02', 'm05', 'p05', 'm12', 'k04', 'p09', 'm16', 'p11', 'm07', 'k10', 'p03', 'm19', 'p13', 'm02', 'k06', 'p06', 'm10', 'p12', 'm21', 'p07', 'm04', 'k12', 'p14', 'm15',
'p01', 'm01', 'k01', 'm03', 'p04', 'm06', 'k02', 'm08', 'p08', 'm09', 'k03', 'm11', 'p10', 'm13', 'k05', 'm14'];
/* 11-05 用户:各模块头像不要重复(之前这 40 人和测试页「刚测出」是同一批)→ 改用分配表 kitLive 的 24 个人设(昵称 + 头像),只在这里出现 */
if (window.MB_AVA && MB_AVA.S.kitLive) { LV_NM = MB_AVA.S.kitLive.map(function (x) { return x[0]; }); LV_AV = MB_AVA.S.kitLive.map(function (x) { return x[1]; }); }
var LV_RECENT = [];
function lvWho(el) {
var on = {};
@@ -160,7 +162,7 @@
var j = c[Math.floor(Math.random() * c.length)];
LV_RECENT.push(j); if (LV_RECENT.length > 16) LV_RECENT.shift();
el.dataset.w = j;
el.querySelector('img').src = 'assets/img/mom/' + LV_AV[j] + '.jpg';
el.querySelector('img').src = /:|^\//.test(LV_AV[j]) && window.MB_AVA ? MB_AVA.src(LV_AV[j], '') : 'assets/img/mom/' + LV_AV[j] + '.jpg';
el.querySelector('em').textContent = LV_NM[j];
}
var LV_JS = {

View File

@@ -8,7 +8,7 @@
postMessage 不是实时投递,微信在分享那一刻才派发,所以每次换内容都要再报一次;子页面没引 jweixin,这里按需加载。 */
(function (g) {
'use strict';
var V = '26110439';
var V = '26110440';
var isWx = /MicroMessenger/i.test(navigator.userAgent || '');
var waiting = [], loading = false;
function ready(cb) {