You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord.js抽奖购票命令金额扣除异常问题求助

解决Discord.js抽奖券购买命令的金额扣除错误

哎,你这个问题一看就是完全没处理用户输入的购买数量,不管用户想买几张,代码都硬抠1张的钱、加1张券,咱们一步步拆解问题然后修复:

原代码的核心错误点

  • 重复查询用户余额:author、money、conta都是同一个值,纯纯浪费数据库查询资源
  • 完全忽略了用户输入的购买数量args[0],全程硬编码成1张
  • 余额判断只检查够不够单张价格,没算「数量×单价」的总金额
  • 扣除余额和添加抽奖券的逻辑彻底错了:用了用户的余额author而不是实际要扣的总金额/要加的券数

修复后的完整代码

async (bot, message, args) => { 
  // 先检查机器人权限
  if (!message.guild.member(bot.user).hasPermission("ADMINISTRATOR")) { 
    return message.channel.send("我没有足够的权限。"); 
  } 

  // 解析并验证购买数量
  const quantity = parseInt(args[0]);
  if (isNaN(quantity) || quantity <= 0 || !Number.isInteger(quantity)) {
    return message.reply("请输入有效的正整数作为购买数量!格式:!buyraffle <数量>");
  }
  if (quantity.toString().includes("-")) { // 防负数滥用
    return message.reply("你在尝试滥用命令吗?"); 
  }

  // 定义单张券价格,计算总花费
  const ticketPrice = 5000;
  const totalCost = ticketPrice * quantity;

  // 获取用户余额(只查一次就够)
  const userId = message.author.id;
  const guildId = message.guild.id;
  const userBalance = await db.get(`money_${userId}_${guildId}`) || 0; // 处理余额为null的情况

  // 检查余额是否足够支付总金额
  if (userBalance < totalCost) { 
    return message.reply(`你金币不够呀!买${quantity}张需要${totalCost}金币,你现在只有${userBalance}金币。`); 
  }

  // 执行数据库操作:扣钱+加券
  await db.subtract(`money_${userId}_${guildId}`, totalCost); 
  await db.add(`rifa_761171065006456833_${guildId}`, quantity); 

  // 发送公共通知
  const publicEmbed = new MessageEmbed() 
    .setColor("RANDOM") 
    .setDescription( 
      `**<@${userId}>** 花了${totalCost}金币买了\`${quantity}张抽奖券\`!` 
    ); 
  const announcementChannel = bot.channels.cache.get("763752044464439311");
  if (announcementChannel) {
    announcementChannel.send("<@&759003907879206935>"); 
    announcementChannel.send(publicEmbed);
  } else {
    console.error("找不到指定的通知频道!");
  }

  // 发送个人确认消息
  const confirmEmbed = new MessageEmbed() 
    .setDescription( 
      `<@${userId}>,你已经成功买到\`${quantity}张抽奖券\`啦!` 
    ) 
    .setColor("GREEN") 
    .setFooter("买得越多,中奖几率越高哦!"); 
  const msg = await message.channel.send({ embed: confirmEmbed });
  msg.react("✅"); 

  // 表情过滤器(留着给你后续扩展用)
  const filter = (reaction, user) => reaction.emoji.name === "✅" && user.id === userId; 
};

关键修改说明

  1. 处理购买数量:解析args[0]为整数,验证是不是正整数,避免无效输入
  2. 计算总金额:用「单价×数量」算出实际要扣的钱,再也不会固定扣5000了
  3. 优化数据库查询:只查一次用户余额,减少不必要的数据库交互
  4. 修正余额判断:检查余额够不够付总金额,而不是只看单张价格
  5. 修复数据库操作:扣总金额、加对应数量的券,逻辑完全对齐需求
  6. 动态内容展示:Embed里的购买数量、花费金额会跟着用户输入变
  7. 容错处理:检查通知频道是否存在,避免报错;处理用户余额为null的边界情况

这样改完后,用户买2张就会扣10000金币、加2张券,完全符合预期啦!

内容的提问来源于stack exchange,提问作者Syntax

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 13:17:42