解决林木木老师哔哔广场中同一Memos实例下多用户头像昵称显示错误问题
目录
问题描述
非常感谢
林木木
老师编写的
哔哔广场
,日常用于调取Memos网站的内容,并实现了同步订阅其他Memos用户及发表 memos 等功能。
但是,我这里有一个较为小众的需求,就是在使用 Memos 广场功能时,如下图界面:
当多个用户来自同一个 Memos 实例时,其动态内容能够正常显示,但用户信息(头像和昵称)却全部显示为同一个用户的信息。
例如,在我的订阅列表中:
- 小十 (ID: 1, 头像: avatar.png)
- 泥鳅胡子 (ID: 3, 头像: myh.jpg)
上述两个用户都使用同一个 Memos 实例 https://memos.xiaoten.com
,但在广场模式下,所有动态都显示为泥鳅胡子的头像和昵称,即使这些动态实际上是小十发布的。
原因分析
主要原因
用户信息映射逻辑未覆盖这种特殊情况,在原始的代码实现中:
获取用户动态时,代码使用了同一个 Memos 实例下的第一个用户信息来覆盖所有用户的动态信息。
最初使用
creatorName
作为映射键,但当多个用户有相同的显示名时会导致冲突。在合并用户信息和动态数据时,属性覆盖的顺序问题,会使用户信息被动态数据中的空值覆盖。
技术细节
在 Promise 内部处理动态数据时,原始代码使用了 matchedMemo
而不是当前用户 u
的信息:
// 原因
for (let key in matchedMemo) {
if (matchedMemo.hasOwnProperty(key)) {
item[key] = matchedMemo[key];
}
}
这会使同一个 Memos 实例下的所有用户都使用了第一个匹配的用户信息。
解决方式
1. 修改 Promise 内部的用户信息赋值
在获取每个用户的动态时,使用当前用户 u
的信息而不是 matchedMemo
:
memosData.forEach(item => {
if (matchedV1 && item.createTime) {
item.createdTs = Math.floor(new Date(item.createTime).getTime() / 1000);
}
// 使用当前用户 u 的信息,避免覆盖核心属性
for (let key in u) {
if (u.hasOwnProperty(key) && key !== 'createdTs' && key !== 'id' && key !== 'content') {
item[key] = u[key];
}
}
});
2. 创建覆盖这种特殊需求的用户映射表
使用 link + creatorId
组合作为唯一键来创建用户映射表:
const userMap = {};
memoList.forEach(user => {
const key = `${user.link}-${user.creatorId}`;
userMap[key] = user;
});
这样,对于同一个 Memos 实例下的不同用户,可以通过不同的 creatorId 来区分:
- 小十:
https://memos.xiaoten.com-1
- 泥鳅胡子:
https://memos.xiaoten.com-3
3. 属性覆盖顺序
在合并用户信息和动态数据时,让用户信息优先,动态的核心属性得到保留:
memoData = memoData.map(memo => {
if (!memo || !memo.creatorId || !memo.link) {
return memo;
}
const memoKey = `${memo.link}-${memo.creatorId}`;
const correctUser = userMap[memoKey];
if (correctUser) {
return {
...correctUser, // 用户信息(头像、昵称等)
id: memo.id, // 保留动态ID
content: memo.content, // 保留动态内容
createdTs: memo.createdTs, // 保留创建时间
// ... 其他核心属性
};
}
return memo;
});
完整代码实现
以下是修改后的 getMemos
函数:
async function getMemos(search) {
// ... 初始化代码
if(search && search != "" && search != null ){
// ... 搜索逻辑
}else{
results = await Promise.allSettled(memoList.map(async(u) => {
// ... 获取动态数据的逻辑
memosData.forEach(item => {
if (matchedV1 && item.createTime) {
item.createdTs = Math.floor(new Date(item.createTime).getTime() / 1000);
}
// 使用当前用户 u 的信息
for (let key in u) {
if (u.hasOwnProperty(key) && key !== 'createdTs' && key !== 'id' && key !== 'content') {
item[key] = u[key];
}
}
});
return memosData;
}));
}
// ... 处理结果
// 创建用户映射表
const userMap = {};
memoList.forEach(user => {
const key = `${user.link}-${user.creatorId}`;
userMap[key] = user;
});
// 确保每个动态都有正确的用户信息
memoData = memoData.map(memo => {
if (!memo || !memo.creatorId || !memo.link) return memo;
const memoKey = `${memo.link}-${memo.creatorId}`;
const correctUser = userMap[memoKey];
if (correctUser) {
return {
...correctUser,
id: memo.id,
content: memo.content,
createdTs: memo.createdTs,
creatorId: memo.creatorId,
creatorName: memo.creatorName,
link: memo.link,
resourceList: memo.resourceList,
visibility: memo.visibility
};
}
return memo;
});
// ... 剩余代码
}
© 转载需附带本文链接,依据 CC BY-NC-SA 4.0 发布。
猜你喜欢
评论