连续登陆活动,或许大家都不会陌生,简单理解就是用户连续登陆了多少天之后,系统就会送一些礼品给相应的用户。最常见的
莫过于游戏和商城这些。游戏就送游戏币之类的东西,商城就送一些礼券。正值国庆,应该也有不少类似的活动。
下面就对这个的实现提供两个思路,并提供解决方案。
思路1(以用户为维度):
连续登陆活动,必然是要求连续登陆,不能有间隔。用1表示登陆,0表示没有登陆,这样我们可以为每个
用户创建
一个key去存储
他的登陆情况,就可以得到类似这样的一个二进制序列:1110111,如果是7个1,就表示连续7天,如果不是7个1就表示没有连续登
陆7天。所以就能实现这个登陆活动的要求了。
思路2(以天数为维度):
一天之内,用户要么是登陆过,要么是没有登陆过。同样的用1来表示登陆过,用0表示没有登陆过。假设我们连续登陆的活动是2天,
同时有3个用户,那么就要有2个key去存储这3个用户的登陆信息,这样就会得到类似这样的两个二进制序列:101(key1),111(key2)。
此时,对这两个key的每一位都进行逻辑与运算,就会得到101,就表明,用户1和用户3连续登陆了两天。从而达到活动的要求。
之前在string的基础教程中曾经说过关于二进制的相关操作会用
一个简单的案例来给大家讲解,现在是兑现这个诺言的时候了。
下面就简单模拟一下国庆7天假期连续登陆七天的活动。
方案1 :以用户为维度
先为每个
用户创建
一个key(holiday:
用户标识),对于我们的例子来说,每个key就会有7位二进制位。这时key会有这样的结构
这时我们就会得到每个
用户对应的二进制序列,然后就可以用bitcount命令去得到key含有的1的个数。如果等于7,就是连续登陆了
七天。这样就可以在第七天用户登陆的时间去处理了是否发送礼品了。处理的逻辑是十分简单的。控制器简单逻辑如下:
Random rd = tran =dis.GetTransaction();
( i = ; i < ; i++ ( j = ; j < ; j++ activity_key = .Format(
(rd.Next(,) > tran.StringSetBitAsync(activity_key,i,
List<> res = List<> ( i = ; i < ; i++ activity_key = .Format(
(_redis.BitCount(activity_key) == Json( { code = ,data = res,count = }
登陆的天数。这是一次性模拟操作,与正常情况的登陆操作还是有些许不同的。大致如下:
dis
activity_key = .Format(, _redis.SetBit(activity_key,currend day,
(currend day==&& _redis.BitCount(activity_key)== }
回到我们模拟的情况,在界面展示时,模拟登陆后会显示累计登陆用户的id。
演示中:38、103、234、264、412、529这6位
用户将得到连续登陆7天的礼品。
这样的话就要让我们的用户标识是数字才行,如果是用guid做的用户标识就要做一定的处理将其转化成数字,这样方便我们
在给用户设置是否登陆。现在假设我们的用户标识是从1~1000。用户标识对应的就是在key中的偏移量。这时我们就会得到每天
对应的二进制序列,然后就可以用bitop命令去得到逻辑与运算之后的key/value。如果这个key对应偏移量(用户标识)是1,就是
连续登陆了七天,处理的逻辑是十分简单的。控制器简单逻辑如下:
tran =dis.GetTransaction();
( i = ; i < ; i++ ( j = ; j < ; j++
dis.BitOP(_bitWise,_res,_redisKeys.ToArray());
IList<> res = List<> ( i = ; i < ; i++ (_redis.GetBit(_res,i) == Json( { code = ,count =
SetBit( day,dis.ITransaction tran)
(_rd.Next(,) > tran.StringSetBitAsync(_first,userId,
tran.StringSetBitAsync(_first, (_rd.Next(,) > tran.StringSetBitAsync(_second,
tran.StringSetBitAsync(_second, (_rd.Next(,) > tran.StringSetBitAsync(_thrid,
tran.StringSetBitAsync(_thrid, (_rd.Next(,) > tran.StringSetBitAsync(_fourth,
tran.StringSetBitAsync(_fourth, (_rd.Next(,) > tran.StringSetBitAsync(_fifth,
tran.StringSetBitAsync(_fifth, (_rd.Next(,) > tran.StringSetBitAsync(_sixth,