视频投票用java redis 实现
1业务背景
1.最近疫情当前,公司开发了一个全民健身的小程序,用户需要上传视频报名,然后可以通过投票来排名。排名靠前的有一些奖励,考虑到投票这种东西可能并发大,所以打算用redis来实现。
2. 每个人每天都有一票,分享出去也可以获取一票,每天最多4票。
3. 视频还跟类型有关,有的是体操,有的是羽毛球
4. 默认按照投票数量倒序,还可以根据发布时间倒序或者正序
2数据模型设计
1 对于列表中每条视频需要用hash去存储详情
每个视频的key 是 video:1 值是这个对象的详情
2 对于需要根据时间和投票数去排序,所以需要两个有序集合 zset
2.1 有序集合 time:
2.2 有序集合 score:
2.3 有序集合 type:videoType
这个是当选择某个类型的时候我们要根据这个过滤掉不属于这个类型的视频,也就是取交集
3 详情页里面,自己如果对这个视频投票,显示红色,若未投票,显示白色。
考虑到这种用户对某个视频是否已经点赞,我们需要一个set集合去重,key就是vote:videoId
4 分享还可以获取点赞数
由于每天分享还可以获取多余的票数,最多一天多获取三张票,所以需要一个存每天的点赞数
当然也需要一个每天的分享数
3 java代码实现
3.1 视频的发布
首先先获取视频对象,通过一个计数器counter执行INCR命令来创建一个新的视频ID
3.2 投票
public Map<String, Object> vote(VideoBo videoBo) {
Map<String, Object> returnMap = new HashMap<>(4);
// 1 判断自己今天投了多少票 Date
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String day = simpleDateFormat.format(new Date());
Object obj = redisTemplate.opsForValue().get("voteCount" + day + videoBo.getUserId());
Integer voteCount = 0;
if (obj != null) {
voteCount = (Integer) obj;
}
// 2 今天分享了多少票
Object obj1 = redisTemplate.opsForValue().get("shareCount" + day + videoBo.getUserId());
Integer shareCount = 0;
if (obj1 != null) {
shareCount = (Integer) obj1;
}
// 最多分享三次
if (shareCount >= 3) {
shareCount = 3;
}
// 3 判断今天是否有资格投票.
if (shareCount + 1 - voteCount <= 0) {
return ResultUtil.failResult("对不起您今天点赞数已用完");
}
// 4.1投票 记录用户对某个视频已经投票
redisTemplate.opsForSet().add("voted:" + videoBo.getId(), "user" + videoBo.getUserId());
// 4.2 某个视频的点赞加一
redisTemplate.opsForZSet().incrementScore("score:", "videoId:" + videoBo.getId(), 1);
// 4.3 记录今天用户点赞加一
redisTemplate.opsForValue().increment("voteCount" + day + videoBo.getUserId(), 1);
return ResultUtil.successResult("点赞成功");
}入代码片`
3.3 分享
@Override
public Map<String, Object> share(String id, String userId) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String day = simpleDateFormat.format(new Date());
redisTemplate.opsForValue().increment("shareCount" + day + userId);
return ResultUtil.successResult("分享成功");
}