local userId = ARGV[1] localtype = tostring(ARGV[2]) local invalid = {} -- 循环所有的活动判断库存 for kIndex = 1, #KEYS do repeat local kName = KEYS[kIndex]
-- 不存在则忽略此key,并记录 if (redis.call('exists', kName) == 0) then invalid[kName] = true break end -- 不是incr则跳过 if ('incr' ~= type) then break end
local pId = string.sub(kName, string.find(kName, '}:') + 2) -- 判断总参与数 local promotionTotal = tonumber(redis.call('hget', kName, 'promotion:total')) or-1 if (promotionTotal > -1) then local soldPromotionTotal = tonumber(redis.call('hget', kName, 'sold:promotion:total')) or0 if (soldPromotionTotal + 1 > promotionTotal) then return'促销' .. pId .. '超出总限购'; end end -- 判断个人参与数 local perPromotionTotal = tonumber(redis.call('hget', kName, 'promotion:per')) or-1 if (perPromotionTotal > -1) then local perSoldPromotionTotal = tonumber(redis.call('hget', kName, 'sold:promotion:per:' .. userId)) or0 if (perSoldPromotionTotal + 1 > perPromotionTotal) then return'会员参与促销' .. pId .. '超出限购'; end end
-- 判断当前促销下的商品的库存 for skuId_skuNum instring.gmatch(ARGV[kIndex + 2], '[^' .. ';' .. ']+') do local i = string.find(skuId_skuNum, ':'); local skuId = string.sub(skuId_skuNum, 0, i - 1) local skuNum = tonumber(string.sub(skuId_skuNum, i + 1)) local skuTotal = tonumber(redis.call('hget', kName, 'sku:total:' .. skuId)) or-1 if (skuTotal > -1) then local soldSkuTotal = tonumber(redis.call('hget', kName, 'sold:sku:total:' .. skuId)) or0 if (skuNum + soldSkuTotal > skuTotal) then return'促销' .. pId .. '中的商品' .. skuId .. '超出限购'; end end local skuPer = tonumber(redis.call('hget', kName, 'sku:per:' .. skuId)) or-1 if (skuPer > -1) then local soldSkuTotal = tonumber(redis.call('hget', kName, 'sold:sku:per:' .. skuId .. ':' .. userId)) or0 if (skuNum + soldSkuTotal > skuPer) then return'会员参与促销' .. pId .. '中的商品' .. skuId .. '超出限购'; end end end untiltrue end
-- 扣减库存 for kIndex = 1, #KEYS do repeat local kName = KEYS[kIndex] -- 如果不存在则忽略此key if (invalid[kName]) then break end
-- 活动总参与次数 local promotionNum = type == 'decr'and-1or1 redis.call('hincrby', kName, 'sold:promotion:total', promotionNum) -- 活动个人参与次数 redis.call('hincrby', kName, 'sold:promotion:per:' .. userId, promotionNum) -- sku库存 for skuId_skuNum instring.gmatch(ARGV[kIndex + 2], '[^' .. ';' .. ']+') do local i = string.find(skuId_skuNum, ':'); local skuId = string.sub(skuId_skuNum, 0, i - 1) local skuNum = tonumber(string.sub(skuId_skuNum, i + 1)) skuNum = type == 'decr'and -skuNum or skuNum -- sku总库存 redis.call('hincrby', kName, 'sold:sku:total:' .. skuId, skuNum) -- 活动总售卖sku数量(统计的时候用) redis.call('hincrby', kName, 'sold:promotion:sku:total', skuNum) -- sku个人库存 redis.call('hincrby', kName, 'sold:sku:per:' .. skuId .. ':' .. userId, skuNum) end untiltrue end return'"1"'