This commit is contained in:
eric
2026-03-18 02:01:48 -05:00
parent 742c293e14
commit bf10b5d7e4
11 changed files with 415 additions and 138 deletions

55
app/lib/joiners.ts Normal file
View File

@@ -0,0 +1,55 @@
/** 报名者项mock 用 nameDB 用 nickname */
export type JoinerItem = {
name?: string;
nickname?: string;
avatar?: string;
xiaohongshu_url?: string;
};
/** 去重 key小红书 url 相同视为 1 人,无 url 时用 avatar再 fallback nickname */
function dedupeKey(j: JoinerItem, useAvatarForMock: boolean): string {
const xh = (j.xiaohongshu_url || "").trim();
if (xh && !useAvatarForMock) return `xh:${xh}`;
const avatar = (j.avatar || "").trim();
if (avatar) return `av:${avatar}`;
return `_${(j.nickname || j.name || "").trim()}`;
}
/**
* 合并 mock 与数据库报名者mock 固定 3 个在左DB 在右
* 小红书 url 相同视为 1 人avatar 相同也只显示 1 个
* 最多显示 8 个,保证 PC/H5 排版合理
*/
export function mergeJoiners(
mock: JoinerItem[],
db: JoinerItem[] | undefined
): JoinerItem[] {
const seen = new Set<string>();
const result: JoinerItem[] = [];
mock.forEach((j) => {
const key = dedupeKey(j, true);
if (!seen.has(key)) {
seen.add(key);
result.push(j);
}
});
(db || []).forEach((j) => {
const key = dedupeKey(j, false);
if (!seen.has(key)) {
seen.add(key);
result.push(j);
}
});
return result.slice(0, 8);
}
/** 数据库报名者按小红书 url 去重后的数量(用于显示报名人数) */
export function getUniqueDbCount(db: JoinerItem[] | undefined): number {
if (!db?.length) return 0;
const seen = new Set<string>();
for (const j of db) {
const key = dedupeKey(j, false);
seen.add(key);
}
return seen.size;
}