在嵌入中显示排行榜

Displaying leaderboard in embed

我正在尝试为我的 Discord 机器人创建排行榜命令,但在显示数据时遇到了一些问题,我当前的代码仅显示排名靠前的用户,您可以在图像中看到有 4 行,这是因为数据库中有 4 个条目,因此它获取信息但不显示所有数据。有人可以指出我在做什么 wrong/what 我需要更改才能解决此问题。 (照片中被遮挡的部分是我的用户名) 代码:

    const top10 = db
      .prepare(
        'SELECT * FROM scores WHERE guild = ? ORDER BY points DESC LIMIT 10;',
      )
      .all(message.guild.id);
    if (!top10) {
      return;
    }

    for (const data of top10) {
      let userNames = '';
      for (let i = 0; i < top10.length; i++) {
        const user = bot.users.cache.get(data.user).tag;
        userNames += `\`${i + 1}\` ${user}\n`;
      }

      const level = `\`${data.level}\`\n`;
      const xp = `\`${data.points.toLocaleString('en')}\`\n`;

      const embed = new MessageEmbed()
        .setAuthor(`Leaderboard for ${message.guild.name}`, message.guild.iconURL({ dynamic: true }))
        .setColor(0x51267)
        .addFields({ name: 'Top 10', value: userNames, inline: true },
          { name: 'Level', value: level, inline: true },
          { name: 'XP', value: xp, inline: true });

      message.channel.send(embed);
      return;
    }

当前输出: 期望的输出:

通过阅读您的代码,我相信您在代码结构方面犯了错误。从表面上看,您的代码获取 top10 中的第一项,然后将其添加到字符串中的次数与 top10 数组的长度一样多。然后它获取第一个用户的级别和 xp,将其添加到一个字符串中,然后将其构建到一个嵌入中。 这是经过修改的代码,因此它应该可以按您的预期工作:

    let userNames = '';
    let levels = '';
    let xp = '';
    for (let i = 0; i < top10.length; i++) {
      const data = top10[i];
      const user = (await bot.users.fetch(data.user)).tag;

      userNames += `\`${i + 1}\` ${user}\n`;
      levels += `\`${data.level}\`\n`;
      xp += `\`${data.points.toLocaleString('en')}\`\n`;
    }

    const embed = new MessageEmbed()
      .setAuthor(`Leaderboard for ${message.guild.name}`, message.guild.iconURL({ dynamic: true }))
      .setColor(0x51267)
      .addFields({ name: 'Top 10', value: userNames, inline: true },
        { name: 'Level', value: levels, inline: true },
        { name: 'XP', value: xp, inline: true });

    message.channel.send(embed);
    return;

你的问题是,你只是将 \n 添加到 js 对象,所以它不起作用。 作为 varian,您可以使用数据创建 3 个 arr,然后将 db 结果推送信息映射到数据。

最好使用 message.guild.members.chache.get 来检查用户是否在服务器上,因为如果用户不在已处理的机器人中发送任何消息,bot.users.cache.get(data.user).tag 将在机器人重启后 return 失效频道。

    const top10 = db.prepare('SELECT * FROM scores WHERE guild = ? ORDER BY points DESC LIMIT 10;').all(message.guild.id);
    if (!top10) {
        return;
    }

    let usersArr = [];
    let levelArr = [];
    let xpArr = [];

    top10.forEach(dataUser, index => {
        let findUser = message.guild.members.cache.get(dataUser.user);
        if (findUser) {
            usersArr.push(`\`${index + 1}\` ${user.tag}`);
            levelArr.push(dataUser.level);
            xpArr.push(dataUser.points.toLocaleString('en'));
        }
    });

    const embed = new MessageEmbed()
        .setAuthor(`Leaderboard for ${message.guild.name}`, message.guild.iconURL({ dynamic: true }))
        .setColor(0x51267)
        .addFields({ name: 'Top 10', value: usersArr.join('\n'), inline: true }, { name: 'Level', value: levelArr.join('\n'), inline: true }, { name: 'XP', value: xpArr.join('\n'), inline: true });
    message.channel.send(embed);