需求

1、用户登录状态只弹一次,未登录每次都弹

2、设置时间有效期

3、当运营对上架弹窗进行下架重新上架后进行弹窗

4、当新增弹窗并上架后重新弹窗

实现

1、时间有效期

这方面后台对时间做了限制,不允许时间有重叠,所以直接在数据库里查询即可:date BETWEEN START_TIME AND END_TIME
其中date改为now()也可,这里因为某些原因是在后台给的new Date()作为参数传入sql语句。

2、用户登录后每天只弹一次,未登录每次都弹

这方面一开始时是交由前端对cookie进行判断,但是会出现客户端登录注销后依旧弹窗的问题,所以后面交由后台处理返回标志位给前端来进行判断是否展示。
后台做的逻辑判断如下:
1:取出session中的户头号,判断是否为空。
2:若户头号为空,则返回给前台false。
3:若户头号不为空,进行之后的逻辑判断。
p.s.:对取得的弹窗信息进行判断,若没有取到值在最外层对flag设值不可见。以下不再重复。

3、当运营对上架弹窗进行下架重新上架后进行弹窗

这一块主要是对redis缓存进行操作,一开始想的是用数据库增加字段来记录,但是修改数据库表的流程比较麻烦,要提各种单,所以采用缓存的方式来解决。
首先流程是设置一个存相关信息的key,field采取弹窗id+”:”+户头号的方式,那么date的值其实可以随便存了,只要有值就好,我这边存的是户头号。
那么每次调用弹窗的方法时,会首先走户头号是否为空的逻辑。以下情景设置在户头号不为空的逻辑。
首先从redis中取key下面所有的field的set集合,进行遍历,比较field与当前的id+”:”+户头号的组合是否匹配,如果有匹配上的,那么就将flag返回false;如果未匹配上,就将flag返回true,并将id+”:”+户头号的field存入弹窗的key值下面,并设置有效期为今天剩余的时间。
那么我们怎么跟踪上下架的状态呢?
在后台进行下架处理时,对时间进行跟踪,如果下架,那么从redis中取key下面所有的field的set集合,进行遍历,对field进行分割,将所有id匹配的field删除掉。这样的话前台再调用弹窗的方法时,就没有这个field就会进行弹窗处理。

4、当新增弹窗并上架后重新弹窗

这块的逻辑和上面的一样,就是会对id进行判断,如果不同则重新弹窗。

//前台代码
 if(CollectionUtils.isNotEmpty(dmoList)){
             //只获取一个值
             //这块因为之前没有做时间的限制,所以还未修改
             FundPopupSuspendDmo fundPopupSuspendDmo = dmoList.get(0);
             //将数据存入dto中
             fundPopSuspendDto.setImgUrl(fundPopupSuspendDmo.getPicAddress());
             fundPopSuspendDto.setLink(fundPopupSuspendDmo.getPicLinkAddress());
             //判断户头号是否为空
             if (!StringUtils.isBlank(accountNo)) {
                 Set<String> fieldSet = new HashSet<>();
                 //获取key值下面的field集合
                 fieldSet = cacheService.getFieldSet(FswsCacheConstants.FSWS_POPUP_CODE);
                 for (String checkSet: fieldSet) {
                     //如果field集合中有field与户头号加id相同,则设置弹窗不可见并返回
                     if(checkSet.equals(fundPopupSuspendDmo.getId()+":"+accountNo)){
                         fundPopSuspendDto.setShowSwitch(false);
                         return fundPopSuspendDto;
                     }
                  }
                 //缓存field集合中无相同值,将其存入缓存,并设置弹窗可见走判断流程
                 cacheService.set(FswsCacheConstants.FSWS_POPUP_CODE, fundPopupSuspendDmo.getId()+":"+accountNo, accountNo, 86400 - (int)DateUtils.getFragmentInSeconds(Calendar.getInstance(),Calendar.DATE));
                 fundPopSuspendDto.setShowSwitch(true);
                 return fundPopSuspendDto;
             }else{
                 //弹窗数据不为空且未登录则每次都弹窗
                 fundPopSuspendDto.setShowSwitch(true);
             }
//后台代码
    String id = fundPopupSuspendDmo.getId()+"";
            Set<String> popupSet = new HashSet<>();
        popupSet = cacheService.getFieldSet(FswsCacheConstants.FSWS_POPUP_CODE);
        for (String s :popupSet) {
            String[] hSet = s.split(":");
            if (id.equals(hSet[0])) {
                cacheService.delete(FswsCacheConstants.FSWS_POPUP_CODE, s);
            }
        }

写在最后:想到的方法不是最好的,但是可以解决问题。
很多地方因为前面的设计问题还未优化 ,待解决//TO-DO