悄悄话留言:赞数前 26 条已变星,其余 0~2 赞(够 3 赞本机变星+特效);早孕留言也按内容限定孕周
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -1053,7 +1053,7 @@ html.night .gtg button.on{background:#F2725B;border-color:#F2725B;color:#fff}
|
||||
var CMD = null, CMERR = false;
|
||||
/* 头像编码:数字 = av/NNNN.webp(旧代码头像);'av:c012' = av/c012.webp(卡通/可爱卡通);'/…' = 站内绝对路径(内置头像库 /_bridge/avatars/);其余 = assets/img/mom/xxx.jpg */
|
||||
var avP = function (a) { return typeof a === 'number' ? 'av/' + ('000' + a).slice(-4) + '.webp' : a.indexOf('av:') === 0 ? 'av/' + a.slice(3) + '.webp' : a.charAt(0) === '/' ? a : '../assets/img/mom/' + a + '.jpg'; };
|
||||
fetch('cm.json?v=26110628').then(function (r) { return r.json(); }).then(function (j) {
|
||||
fetch('cm.json?v=26110629').then(function (r) { return r.json(); }).then(function (j) {
|
||||
CMD = j; if (openId && NBY[openId]) { renderComments(NBY[openId]); syncBar(NBY[openId]); }
|
||||
}).catch(function () { CMERR = true; if (openId && NBY[openId]) renderComments(NBY[openId]); });
|
||||
function commentsOf(n) {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<title>兜爸心选 · 孕育陪伴</title>
|
||||
<!-- 11-04 UGC 总开关(孕妈广场 + 测一测,后台 /box_bm/plaza 顶部切换),见 js/ugc.js -->
|
||||
<script src="js/ugc.js?v=26110487"></script>
|
||||
<!-- V:26110628 缓存版本标记:改 css/js 时同步 bump 该值(与 js/app.js 的 VER 同源),静态资源按 mtime 走 ETag 自动刷新 -->
|
||||
<!-- V:26110629 缓存版本标记:改 css/js 时同步 bump 该值(与 js/app.js 的 VER 同源),静态资源按 mtime 走 ETag 自动刷新 -->
|
||||
<link rel="stylesheet" href="mama-box.css">
|
||||
<link rel="stylesheet" href="night.css?v=26110608">
|
||||
<link rel="stylesheet" href="js/wh-cm.css?v=26110625">
|
||||
@@ -2680,7 +2680,7 @@ html.night .rs-pan .rp-card{background:rgba(255,255,255,.06);border-color:rgba(2
|
||||
<script src="guangchang/topics.js?v=26110487"></script>
|
||||
<script src="js/ava-pool.js?v=26110487"></script> <!-- 11-05 装饰头像分配表(各模块互不重复) -->
|
||||
<script src="js/wh-themes.js?v=26110609"></script>
|
||||
<script src="js/wh-cm.js?v=26110628" defer></script>
|
||||
<script src="js/wh-cm.js?v=26110629" defer></script>
|
||||
<script src="js/app.js"></script>
|
||||
<script src="js/kit.js?v=26110605"></script>
|
||||
<!-- 11-05 用户:孕期百问加上跟趣味小测试一样的底部 Tab(孕期百问 / 记一下 / 返回首页)。挂在 #detailQA 里,面板关着时跟着滑出屏外;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
/* 页面版本号(YYMMDD+序号):显示在「关于兜爸心选」页底部;bump 时同步 head 注释与 ?v= */
|
||||
var VER = '26110628';
|
||||
var VER = '26110629';
|
||||
const $ = (s, c) => (c || document).querySelector(s);
|
||||
const $$ = (s, c) => Array.from((c || document).querySelectorAll(s));
|
||||
|
||||
|
||||
16
js/wh-cm.js
16
js/wh-cm.js
@@ -61,11 +61,11 @@
|
||||
function repOf(c, me) { return { p: c.parent, n: me ? '我' : (c.nickname || '孕妈'), me: me, to: c.parentName, t: c.text, ts: c.at, st: me ? c.status : '' }; }
|
||||
function load() {
|
||||
if (loading || SIM) return; loading = true;
|
||||
fetch('guangchang/cm.json?v=26110628').then(function (r) { return r.json(); }).then(function (j) {
|
||||
fetch('guangchang/cm.json?v=26110629').then(function (r) { return r.json(); }).then(function (j) {
|
||||
var PP = j.p;
|
||||
SIM = (j.c[PID] || []).map(function (c, k) {
|
||||
var p = PP[c[0]];
|
||||
return { key: PID + '#' + k, n: p[0], av: avP(p[1]), s: p[2], t: c[1], likes: c[2],
|
||||
return { key: PID + '#' + k, n: p[0], av: avP(p[1]), s: p[2], t: c[1], likes: c[2], st0: !!c[4],
|
||||
r: c[3].map(function (x) { var q = x[0] < 0 ? null : PP[x[0]]; return { n: q ? q[0] : '孕妈悄悄话', t: x[1] }; }) };
|
||||
});
|
||||
build(); paintGo(); focusWc();
|
||||
@@ -149,6 +149,8 @@
|
||||
}, 600);
|
||||
}
|
||||
var wkOf = function (c) { var x = /孕\s*(\d+)\s*周/.exec(c.s || ''); return x ? +x[1] : 0; };
|
||||
/* 11-07 方案 A:模拟留言 = cm.json 标了已变星的 + 赞数(含我本机这一赞)够 STAR_N 的 */
|
||||
function simStar(c) { c.star = c.st0 || likesOf(c) >= STAR_N; }
|
||||
var likesOf = function (c) { return c.real ? c.likes : c.likes + (LIKE[c.key] ? 1 : 0); };
|
||||
var likedOf = function (c) { return c.real ? c.liked : !!LIKE[c.key]; };
|
||||
/* 最热:挂了星的在前,再按赞;最新:真实留言按时间,模拟的接在后面;同孕周:和我差 ±1 周的,按最热。我自己发的永远在最上面 */
|
||||
@@ -171,6 +173,7 @@
|
||||
}
|
||||
function build() {
|
||||
if (!SIM || !REAL) return;
|
||||
SIM.forEach(simStar);
|
||||
ALL = sorted(); shown = 0; ls.innerHTML = '';
|
||||
paintGo();
|
||||
if (!ALL.length) {
|
||||
@@ -231,9 +234,14 @@
|
||||
var b = e.target.closest('[data-wcl]'); if (!b) return;
|
||||
var k = b.dataset.wcl, c = ALL.filter(function (x) { return x.key === k; })[0]; if (!c) return;
|
||||
if (!c.real) {
|
||||
if (LIKE[k]) delete LIKE[k]; else LIKE[k] = 1;
|
||||
/* 跟真实留言一样:赞了就不能取消;这一赞让它够了 STAR_N → 变星特效 */
|
||||
if (LIKE[k]) { toast('你已经赞过啦'); return; }
|
||||
LIKE[k] = 1;
|
||||
try { localStorage.setItem(LK, JSON.stringify(LIKE)); } catch (e2) {}
|
||||
paintLk(b, c); if (LIKE[k] && navigator.vibrate) navigator.vibrate(8);
|
||||
var was0 = c.star; simStar(c);
|
||||
paintLk(b, c); b.classList.add('pop'); setTimeout(function () { b.classList.remove('pop'); }, 500);
|
||||
if (navigator.vibrate) navigator.vibrate(8);
|
||||
if (c.star && !was0) { rerender(c); starFx(c.t, false); }
|
||||
return;
|
||||
}
|
||||
/* 真实留言:服务端计数,赞了就不能取消(同星星的抱抱) */
|
||||
|
||||
@@ -71,6 +71,14 @@ for t in [l.strip() for l in open('tools/whcm/early_rep.txt', encoding='utf-8')
|
||||
hit = [c for c in out if c[1].startswith(head)]
|
||||
assert len(hit) == 1, head
|
||||
hit[0][3].append([early_p[ei], txt]); ei += 1
|
||||
ERULES = [(r'两道杠|还没跟你爸说|验孕棒|小黑圈|胎心胎芽', 6, 8), (r'孕酮|查血|出血', 6, 10), (r'约了NT', 10, 12),
|
||||
(r'葡萄|裤子有点紧|肚子还是平的', 10, 13)]
|
||||
eleft = early_p[ei:]
|
||||
def epick(t):
|
||||
lo, hi = next(((a, b) for pat, a, b in ERULES if re.search(pat, t)), (6, 13))
|
||||
for i in eleft:
|
||||
if lo <= wk(d['p'][i]) <= hi: eleft.remove(i); return i
|
||||
raise SystemExit('没有合适早孕人设:' + t)
|
||||
early = [l.strip() for l in open('tools/whcm/early.txt', encoding='utf-8') if l.strip()]
|
||||
eo = []
|
||||
for k, l in enumerate(early):
|
||||
@@ -78,7 +86,7 @@ for k, l in enumerate(early):
|
||||
rr = []
|
||||
for t in parts[1:]:
|
||||
rr.append([reps[ri], t]); ri += 1
|
||||
eo.append([early_p[ei], parts[0], 0, rr]); ei += 1
|
||||
eo.append([epick(parts[0]), parts[0], 0, rr])
|
||||
# 定赞数:从第 3 条起每隔约 2~3 条放一条早孕的,赞数取前后两条之间
|
||||
merged = []
|
||||
step = len(out) / len(eo)
|
||||
@@ -92,6 +100,15 @@ for e in eo[j:]: e[2] = 3
|
||||
# 追加在最后(模拟留言的 key 是「帖子#下标」,插在中间会让原来那 100 条下标错位,真实回复/本机点赞挂错楼);
|
||||
# 赞数已按插入位置取好,「最热」排序时自然穿插在中间
|
||||
out = out + eo
|
||||
# 11-07 用户定(方案 A):「被赞 3 次变星星」要和赞数对得上 → 赞数最高的 26 条标成已变星(第 5 位 = 1),
|
||||
# 赞数压到几十~个位(不再几百);其余 0~2 个赞,看着就是「还差一点」,有人帮着点一下就能变星(前端本机算)
|
||||
order = sorted(range(len(out)), key=lambda k: -out[k][2])
|
||||
NS = 26
|
||||
for r, k in enumerate(order):
|
||||
if r < NS:
|
||||
out[k][2] = max(4, int(168 * (0.88 ** r)) + rnd.randint(-5, 5)); out[k].append(1)
|
||||
else:
|
||||
out[k][2] = rnd.choice([0, 0, 1, 1, 1, 2, 2])
|
||||
d['c'][TARGET] = out
|
||||
json.dump(d, open(P, 'w', encoding='utf-8'), ensure_ascii=False, separators=(',', ':'))
|
||||
print('ok', len(out), 'replies', ri, 'early', len(eo), 'early-replies', ei - len(eo))
|
||||
print('ok', len(out), 'replies', ri, 'early', len(eo), 'early-replies', ei)
|
||||
|
||||
Reference in New Issue
Block a user