java后台管理系统中文章置顶、取消置顶如何实现

  • 借鉴微信的置顶与取消置顶的实现思路:

会看到这个微信的聊天记录的排序规则是以时间降序来进行排序的,如果要实现置顶与取消置顶? 一下子是想不到的,需要思路

由此可以确信的是,我们平时使用微信时,最新的聊天记录总是在前面的,多久不聊的聊天是在最后面的。

在项目中需要实现置顶与取消置顶的功能,刚开始没有思路,苦思冥想了半天,以前也没有做过类似的需求。

于是我一直在使用微信的置顶与取消置顶的功能,玩着玩着还挺好玩,我只要最后点击某条聊天记录置顶,那么这条记录就一定会在第一条显示,并且在它前面置顶的聊天记录会依次在它的下面显示。如果我取消了某条 (置顶过) 的聊天记录,那么它的位置就是在它(聊天记录)的 创建的时间点上。当时就特别好奇,这到底要怎么实现?

一直写SQL语句反复尝试还没有思路,整个人都快傻了,这应该是个很简单的功能,为什么就是写不出来,又想不对啊,怎么可能在一个字段中就 实现置顶与取消置顶,并且还要排序? 终于,我在测试表中仅有的字段又加了一个标记字段 is_top(是否置顶), 神奇的现象发生了, 我想要的结果出来了 ,哈哈哈

(这是类似于微信的,先以是否置顶降序排,再以排序字段降序排(盲猜我这个对应微信的聊天记录的创建时间,哈哈哈))
 SELECT * FROM tb_test ORDER BY is_top DESC,sort_num DESC

在这里插入图片描述
从结果可以看出来,这句SQL语句再执行的时候,先排第一个字段,再排第二个字段,所有从这个思路,思路逐渐清晰:

@Override
    public Map<Integer, String> stick(Long publishId) {
    
    

        // 1: 获取 is_top字段 的最大值
        Integer isTopMax = publishInfoMapper.getIsTopMax();
        
        // 2: 查询当前文稿
        PublishInfo publishInfoUpdate = new PublishInfo();
        publishInfoUpdate.setPublishId(publishId);

        // 创建查询对象
        QueryWrapper<PublishInfo> queryWrapper = Wrappers.query(publishInfoUpdate);
        PublishInfo publishInfo = null;
        try {
    
    
            publishInfo = publishInfoMapper.selectOne(queryWrapper);
        } catch (Exception e) {
    
    
            throw new RuntimeException(e);
        }

        Map<Integer, String> resultMap = new HashMap<>();
        if (ObjectUtils.isEmpty(publishInfo)) {
    
    
            throw new OperationException(OperationExEnum.ABSENT, "无法找到对应id的文稿,无法进行置顶显示,请确认id是否正确 !");
        } else {
    
    
            Integer isTop = publishInfo.getIsTop();
            
            if (isTop.equals(isTopMax)) {
    
    
                resultMap.put(OperationExEnum.MODIFICATION_FAILURE.getStatusCode(), "当前文稿已经置顶,请重新选择 !");
            } else if (isTop < 0) {
    
    
                // 说明数据发生了人为改变!
                throw new OperationException(OperationExEnum.ERROR.getStatusCode(), "数据错误,请联系工作人员 !");
            }

            if (!isTop.equals(isTopMax) && isTop >= 0) {
    
    

                // 更新
                UpdateWrapper<PublishInfo> updateWrapper = Wrappers.update();
                // 更新的字段 is_top字段值加一,当前的文档置顶!
                updateWrapper.set(OperationConst.IS_TOP, isTopMax + 1);
                // 指定条件
                updateWrapper.eq(OperationConst.PUBLISH_ID, publishInfo.getPublishId());

                int update = publishInfoMapper.update(publishInfoUpdate, updateWrapper);

                if (update != 1) {
    
    
                    throw new OperationException(OperationExEnum.MODIFICATION_FAILURE, "置顶文稿失败 ! 请稍后操作 !");
                } else {
    
    
                    resultMap.put(OperationExEnum.MODIFICATION_ACCESS.getStatusCode(), "置顶文稿成功 ! ~~~");
                }
            }
        }
        return resultMap;
    }

is_top 从前端传过来只是0或1的值, (0代表取消置顶按钮的点击事件,1代表当前置顶按钮的点击事件) 而数据库中is_top 是在业务层自己处理逻辑的,经过反复测试没有什么问题

取消文稿置顶:

@Override
    public Map<Integer, String> cancelStick(Long publishId) {
    
    

        // 1: 根据文稿id查询当前这个文稿是否置顶
        PublishInfo publishInfoUpdate = new PublishInfo();
        publishInfoUpdate.setPublishId(publishId);

        // 创建查询对象
        QueryWrapper<PublishInfo> queryWrapper = Wrappers.query(publishInfoUpdate);
        PublishInfo publishInfo = null;
        try {
    
    
            publishInfo = publishInfoMapper.selectOne(queryWrapper);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }

        Map<Integer, String> resultMap = new HashMap<>();
        if (ObjectUtils.isEmpty(publishInfo)) {
    
    
            throw new OperationException(OperationExEnum.ABSENT, "无法找到对应id的文稿,请确认再操作 !");
        } else {
    
    
            Integer isTop = publishInfo.getIsTop();
            if (isTop > 0) {
    
    

                // 更新
                UpdateWrapper<PublishInfo> updateWrapper = Wrappers.update();
                // 更新的字段
                updateWrapper.set(OperationConst.IS_TOP, 0);
                // 指定条件
                updateWrapper.eq(OperationConst.PUBLISH_ID, publishInfo.getPublishId());

                int update = publishInfoMapper.update(publishInfoUpdate, updateWrapper);

                if (update != 1) {
    
    
                    throw new OperationException(OperationExEnum.MODIFICATION_FAILURE, "取消置顶失败 ! 请稍后操作 !");
                } else {
    
    
                    resultMap.put(OperationExEnum.MODIFICATION_ACCESS.getStatusCode(), "取消置顶成功 ! ~~~");
                }
            }//如果就是0,说明该文稿本身就没有置顶!
            else if (isTop.equals(0)) {
    
    
                resultMap.put(OperationExEnum.ABSENT.getStatusCode(), "该文稿不是置顶显示,请重新选择 !");
            } else {
    
    
                // 说明数据发生了人为改变!
                throw new OperationException(OperationExEnum.ERROR.getStatusCode(), "数据错误,请联系工作人员 !");
            }
        }
        return resultMap;
    }

取消置顶的思路完全就是取决于置顶的思路, 只是把is_top的值改为不可再排序的默认值,

使用MybatisPlus 的API 拼接的分页排序语句:

// 1: 创建分页前的数据
        IPage<PublishInfo> pageNoAndPageSize = new Page<>(pageNo, pageSize);

        // 2: 封装查询条件 ,(如果该文稿置顶,就按照)is_top字段降序排序 然后再按照 指定sort_num字段 升序排序
        // (如果文稿不置顶就按照 它指定的sort_num 的值排序 ) 按照 指定sort_num字段 升序排序
        QueryWrapper<PublishInfo> query = Wrappers.query();
        query.orderByDesc(OperationConst.IS_TOP).orderByAsc(OperationConst.SORT_NUM);

        // 3: 查询
        IPage<PublishInfo> publishInfoPage = publishInfoMapper.selectPage(pageNoAndPageSize, query);
        
// ....................省略................................

如果在添加某个文稿的时候就需要 (置顶) 代码:

if (isTop.equals(1)) {
    
    
            // 拿到当前isTop的最大值
            Integer isTopMax = publishInfoMapper.getIsTopMax();

            // 如果当前isTop的最大值是0 , 说明还没有文稿置顶
            if (isTopMax.equals(0)) {
    
    
                // 当前文稿的isTop值为 1
                publishInfo.setIsTop(1);
            } else {
    
    
                // 否则当前文稿的isTop值就是最大值加1
                publishInfo.setIsTop(isTopMax + 1);
            }
        }
// ..............................省略..............................

(如果想让每个文稿sort_num的值不与数据库中的sort_num字段的重复代码):

// 3: 判断当前添加的文稿对象的sort_num 值 在数据库中是否存在
        Integer sortNum = publishInfo.getSortNum();
        // 拿到所有的sort_num的值 , 并升序排序
        ArrayList<Integer> sortNumList = publishInfoMapper.getSortNums();
        Collections.sort(sortNumList);

        Map<Integer, String> resultMap = new HashMap<>();
        // 4: 如果文稿的排序字段不为空, 则判断当前的数据库的sort_num中有没有 新加的文稿的排序字段,
        // 如果包含了, 就是 sort_num字段 最大值 + 1, 并返回友好提示信息, 如果没有就是添加的排序字段
        if (sortNum != null) {
    
    

            for (int i = 0; i < sortNumList.size(); i++) {
    
    

                if (sortNum.equals(sortNumList.get(i))) {
    
    
                    publishInfo.setSortNum(sortNumList.get(sortNumList.size() - 1) + 1);

                    if (isTop.equals(1)) {
    
    
                        resultMap.put(OperationExEnum.ALREADY_EXISTS.getStatusCode(), "您添加的排序字段已经存在,您的排序字段默认为末序,当前是置顶显示 ! ");
                        break;
                    } else {
    
    
                        resultMap.put(OperationExEnum.ALREADY_EXISTS.getStatusCode(), "您添加的排序字段已经存在,您的排序字段默认为末序 ! ");
                        break;
                    }
                }
            }
        } else {
    
    
            publishInfo.setSortNum(sortNumList.get(sortNumList.size() - 1) + 1);
            if (isTop.equals(1)) {
    
    
                resultMap.put(OperationExEnum.ABSENT.getStatusCode(), "您添加的排序字段为空(您未添加排序字段), 默认为末序, 当前是置顶显示 ! ");
            } else {
    
    
                resultMap.put(OperationExEnum.ABSENT.getStatusCode(), "您添加的排序字段为空(您未添加排序字段), 默认为末序 ! ");
            }
        }

Sum up:

1: 没有置顶的数据的is_top字段的值都是一样的(比如默认都是0,或者默认是一样的值)

2: 如果默认的是0,初始置顶值是1 , 或者是2 …

3: 如果默认的是1,初始置顶值是2 , 或者是3 …

4: 当前置顶的数据is_top字段的值永远是所有数据is_top字段中的最大值

5: 当前置顶的数据的is_top字段的值一定是比上一个置顶的数据 大1…, 或者大 2 …

6: 取消置顶那么就是设置为默认值就好了,使它不能再以is_top排序

7: order by is_top ASC|DESC , (sort_num ASC|DESC 或者create_time ASC|DESC ),以你的需求来定

8: is_top的值是随时都会变化的 , 建议使用 bigint 数据类型,对应Java的 Long | long类型

MybatisPlus生成的 SQL语句日志

 ==>  Preparing: SELECT publish_id,publisher,status,sort_num,title_detail,title,title_image_url,service_dir_ids,mountings_dir_ids,belong_category_name,is_top,belong_category_id,create_time,after_update_time FROM tb_publish_info ORDER BY is_top DESC , sort_num ASC LIMIT ?,? 
 ==> Parameters: 0(Long), 8(Long)
 
<==      Total: 8

猜你喜欢

转载自blog.csdn.net/Gabriel_wei/article/details/130743349
今日推荐