How to pin and unpin articles to the top in the Java backend management system

  • Learn from WeChat’s implementation ideas of pinning and canceling pinning:

You will see that the sorting rules of this WeChat chat record are sorted in descending order of time. What if you want to achieve pinning and unpinning? It's unexpected at once, I need some ideas

From this, we can be sure that when we usually use WeChat, the latest chat history is always at the front, and the chats that have not been chatted for a long time are at the end.

In the project, I needed to implement the functions of pinning and unpinning. I had no idea at first and I thought hard for a long time. I had never done anything similar before.

So I have been using WeChat’s pin and unpin functions. It’s quite fun to play with. I just need to click on a certain chat record to pin it to the top. Then this record will definitely be displayed as the first one and pin it in front of it. The chat history will be displayed below it. If I cancel a (pinned) chat record, its position will be at the time when it (chat record) was created. I was very curious at that time, how to achieve this?

I keep writing SQL statements and try again and again, but I still have no idea. I am almost stupid. This should be a very simple function. Why can't I write it? I don't think it right. How is it possible to achieve pinning and unpinning in a field? Still need to sort? Finally, I added a mark field is_top (whether to top or not) to the only field in the test table. A magical phenomenon happened, and the results I wanted came out, hahaha

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

Insert image description here
It can be seen from the results that when this SQL statement is executed again, the first field is sorted first, and then the second field is sorted. From this idea, the idea gradually becomes clear:

@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 is only a value of 0 or 1 passed from the front end, (0 represents the click event of canceling the pinned button, and 1 represents the click event of the current pinned button). In the database, is_top handles the logic at the business layer itself. After repeated testing, there is no problem.

Unpin the document to the 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;
    }

The idea of ​​canceling top is completely based on the idea of ​​​​sticking. It just changes the value of is_top to the default value that cannot be reordered.

Use the API of MybatisPlus to splice the paging sorting statement:

// 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 you need (top) code when adding a document:

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);
            }
        }
// ..............................省略..............................

(If you want the value of sort_num for each document not to be the same code as the sort_num field in the database):

// 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类型

SQL statement log generated by MybatisPlus

 ==>  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

Guess you like

Origin blog.csdn.net/Gabriel_wei/article/details/130743349