签到模块的简单设计思路
什么是签到功能?
和上班打卡一样,用户每天可以在应用内进行一次“签到”,用来表明用户今天已经登录且使用了该应用,同时签到后很能获取一定的奖励。
为什么要做签到功能?
- 培养用户使用习惯,签到功能设置的目的在于吸引用户每天去完成签到动作,培养用户使用习惯。
- 满足用户荣誉感,签到的奖励措施可加入勋章体系(指的是授给有功者的荣誉证章或者标志)。满足用户用户签到后获得勋章的荣誉感。
- 增加用户活跃度,对于企业来说,用户养成长期的签到习惯,使得用户活跃度更强,刺激沉默用户,使得其在活跃过程中驻足产品。促进活跃用户更加活跃,产生正向反馈。
- 提高企业一定的收入,签到后用户获取的奖励,一定程度上能提高企业的收入,优惠券的形式可以促使用户下单,提高订单量。积分+现金的形式可以增加礼品道具的收入。开屏广告CPM收入。
签到规则
- 需要连续签到(其实就是累计签满),用户需要在某一周期内完成连续的签到行为,单次的签到行为奖励较少,而连续的签到行为,会使得用户获利程度更大,刺激用户养成连续签到习惯。如果是连续签到的情况下,要考虑用户中途断签如何处理。
一般两种选择,重新开始计算或进行断签,多数采用的是补签策略,重新计算的情况下,用户容易丧失信心,可能会选择放弃。而断签情况下,要考虑到补签策略,补签对于用户来说付出的成本应小于补签后获利成本,这样更容易让用户完成补签动作,养成连续签到行为。 - 不需要连续签到,用户只需要完成一定的签到次数,不需要有连贯性。一般不需要连续签到次数最高限定次数为当月天数(或是某一周期),次月则重新进行计算,达到一定的天数(累计签到)即可获得奖励。
以上2中的签到方式中,可以考虑增加签到提醒功能,特别是需要连续签到,目的是培养用户养成签到习惯,减少漏签的意外。当用户当天忘记签到时进行消息推送的提醒。
设计思路
我们以实际应用中的案例为例。
七天累计签到
这里我们其实只需要一张【签到表】即可,里面包括6个必要的字段(id,用户id,签到情况,起始签到日期,上一次签到日期,签到次数),其中:
- 【签到情况】,用来直观展示是否签到,我们可以采用0和1表示是否签到,如果需要签到7天,那么默认值设为0000000共7个0,如果第三天签到了,那么就找到下标为2设为1,此时的值就变成0010000,接着第四天没签到,第五天签到了,那么值就变成0010100。
即需要连续签到几天,就默认设为几个0,签到了就将下标设为1。 - 【起始签到日期】,用来记录第一天签到的日期,便于计算查询。
- 【上一次签到日期】,用于判断是否能够签到。
- 【签到次数】,用来记录本次签到周期的累计次数,便于计算查询。
签到步骤:
- 上一次签到日期 如果等于 当前日期 那么返回已签到。
- 日期间隔 = 当前日期 - 起始签到日期。
- 日期间隔 >= 7天,那么就需要重新开始签到,起始签到日期 = 当前日期。
- 日期间隔 < 7天,可以签到,将【签到情况】中下标为日期间隔的值设为1,签到次数累加。
- 上一次签到日期 = 当前日期
按月累计签到
同样,我们其实只需要一张【签到表】即可,里面包括6个必要的字段(id,用户id,签到情况,上一次签到日期,签到次数,补签次数,补签卡数),其中:
- 由于已知其实结束日期,所以去掉了相关字段。
- 补签次数、补签卡数,是根据业务扩展的字段,用于补签获取更多奖励。
签到操作:
- 上一次签到日期 如果等于 当前日期 那么返回已签到。
- 上一次签到日期不在当前月份,重新开始计算。
- 日期间隔 = 当前日期 - 1。
- 将【签到情况】中下标为日期间隔的值设为1,签到次数累加。
- 上一次签到日期 = 当前日期
至于补签操作:
- 判断是否有补签卡。
- 补签次数+1,累计次数+1,补签卡数-1
借助redis
基于redis的bitmap,我们可以快捷高效的存储【签到情况】。
redis给bitmap数据结构提供了三个方法
BITCOUNT key [start] [end]
计算给定字符串中,被设置为 1 的比特位的数量。
GETBIT key offset
对 key 所储存的字符串值,获取指定偏移量上的位(bit)。
SETBIT key offset value
对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。
具体就不展开介绍了,有兴趣的同学可以看看redis官方文档。
总结
至此,我们基于一张签到表设计了一个简单的签到模块,在实际场景中,我们还需要根据业务需求进一步设计,例如签到日志,签到配置,奖励设置等等。更进一步的,还可以提炼出一套高度自定义的签到服务,提供外部接入。
参考
http://www.woshipm.com/pd/771177.html
https://redis.io/commands/setbit
我不怕千万人阻挡,只怕自己投降。