显示嵌入排行榜

时间:2020-03-09 19:42:33

标签: node.js discord.js better-sqlite3

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

    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;
    }

电流输出: Curent Output: 所需输出: Desired Output

2 个答案:

答案 0 :(得分:1)

通过阅读您的代码,我相信您在代码的结构方面犯了一个错误。从表面上看,您的代码获得了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;

答案 1 :(得分:0)

您的问题是,您仅将\n添加到js对象,因此没有任何作用。 作为varian,您可以使用数据创建3个arr,然后将db结果推送信息映射到数据。

最好使用message.guild.members.chache.get来检查服务器上的用户,因为bot.users.cache.get(data.user).tag将在机器人重新启动后(如果用户未在已处理的机器人通道中发送任何消息)返回undind。

    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);