endTime then redis.call('HSET', redpacketKey, 'status', 2) return {0, "红包已结束", 0} end -- 检查是否已经抢过 local hasGrabbed = redis.call('SISMEMBER', userSetKey, userId) if hasGrabbed == 1 then return {0, "已经抢过该红包", 0} end -- 检查是否还有剩余 local leftAmount = tonumber(redpacket['left_amount']) local leftCount = tonumber(redpacket['left_count']) if leftCount <= 0 or leftAmount <= 0 then return {0, "红包已抢完", 0} end -- 计算红包金额(核心修改:适配整数金币,避免0) local amount = 0 local isFinished = 0 if leftCount == 1 then -- 最后一个红包,获得剩余所有金额(确保至少1) amount = leftAmount isFinished = 1 else -- 随机算法:二倍均值法(适配整数,保证最低1) -- 1. 计算二倍均值(整数处理,向下取整) local avg = leftAmount / leftCount local maxAmount = math.floor(avg * 2) -- 2. 确保最大金额至少为1,且不超过剩余金额-(剩余个数-1)(避免后续红包无金额可分) -- 剩余金额-(剩余个数-1):保证剩下的每个红包至少能分1个金币 local safeMax = leftAmount - (leftCount - 1) maxAmount = math.min(maxAmount, safeMax) maxAmount = math.max(maxAmount, 1) -- 确保最小可随机值为1 -- 3. 随机生成1到maxAmount之间的整数(避免0) amount = math.random(1, maxAmount) -- 4. 检查是否抢完(整数判断,无需浮点数误差处理) if leftCount - 1 == 1 or (leftAmount - amount) <= 0 then isFinished = 1 end end -- 更新红包数据(整数处理,无小数) local newLeftAmount = leftAmount - amount local newLeftCount = leftCount - 1 redis.call('HSET', redpacketKey, 'left_amount', newLeftAmount) redis.call('HSET', redpacketKey, 'left_count', newLeftCount) -- 标记用户已抢 redis.call('SADD', userSetKey, userId) -- 如果抢完了,更新状态为已结束(2) if isFinished == 1 then redis.call('HSET', redpacketKey, 'status', 2) end return {1, tostring(amount), isFinished} LUA; } }