前言
大家好,我是雪荷,在我的厚米匹配项目(厚米匹配系统)中利用 Vant 自带的日历组件和 Redisson BitSet 实现了一个签到日历,其效果图如下。

思路
实现其实很简单,我们先思考后端该如何实现。记录用户每天是否签到可以通过 Redis 的 BitMap(位图)来实现,其是一个位数组,每个元素占一个比特大小,值只能为 0 或者 1。假如用户今天签到了,那么对应一年的天数即位图对应的索引为 1,未签到的话就为 0。到此大致方案已经基本成型,剩下还有几个小问题。
-
如何设计 BitMap 的 key
-
如何计算今日至每年 1 月 1 号的天数
-
如何查询用户哪些天签到/未签到
对于以上难点该如何解决呢?其实不难,主要难的是第一点和第三点。
我是用的是 Redisson 的 BitSet 实现的,其与 BitMap 都是基于 Redis String 类型实现的,但是 BitSet 类似 Java 自带的 BitSet,API 更多并且还支持位运算操作,并且 BitSet 除了存储 0/1 还能存储 boolean 类型(true/false)。
如何设计 BitMap 的 key
对于第一点,我们该如何设计 BitMap 的 key 呢?往深一步说就是,该如何设计 key 来区分每个用户某一年的签到记录呢?我的方案是这样的,系统名 + 业务名 + 用户 ID + 年份 ID。仔细想想是不是解决了呢,想要查询某个用户某一年的签到记录直接拼接用户 ID 和年份不就好了吗。
如何查询用户哪些天签到/未签到
BitSet 支持遍历操作,直接判断值是否为 1 即可,为 1 的话算出对应的日期。我们存储的索引位置是按照签到日与 1.1 日距离的天数来存的,反过来根据天数来算日期岂不是易如反掌。将已签到的日期存到一个 List 中返回给前端,前端根据 List 进行渲染,不在 List 的日期就代表未签到。
Calendar 组件介绍
Calendar 是 Vant 的一个日历组件,其支持很多 API 和属性,这里我就不一一介绍了,我们只说重要的。Calendar 日历组件显示的日期、属性啥的都是提前渲染好的,那我们该如何渲染和标记已签到和未签到的日期呢?幸好官方给我们提供了一个异步渲染示例——通过计算属性实现。

另外再提一嘴,日历组件的日期数据结构为 Day,可以根据 formatter 属性来自定义 Day 对象属性,如显示“已签到”,“未签到”啥的,具体属性如下:



1622

被折叠的 条评论
为什么被折叠?



