• 拖动排序与置顶的Java实现


    整理个需求的实现思路。

    1、需求分析

    列表展示了一系列产品,现要支持通过拖动来给产品排序,也要支持单个产品的置顶、删除。类似CSDN的专栏文章管理。

    在这里插入图片描述

    2、表设计

    现要支持对列表的产品进行拖动排序,考虑新增个hot_sort字段,代表产品的先后顺序(或者热门程度)。关于表设计,可在原来的 t_product表中直接新加个hot_sort字段。如果有其他业务字段,也可新建个中间表,核心字段:t_product表的product_id、热门排序字段hot_sort、其余业务字段。

    //示例
    ALTER TABLE t_product ADD hot_sort INT;
    //值越小越靠前
    
    • 1
    • 2
    • 3

    3、接口设计

    关于接口实现,考虑让前端传两个productId,一个是被移动的产品的ID(productId),一个则是移动目标点的产品的ID(afterProductId)。如此,通过比较这两个ID对应产品的hot_sort字段值的大小关系,就可一个接口实现前移、后移、置顶:

    • targetProductId传空,置顶
    • afterProductId > productId,后移
    • afterProductId < productId,前移

    以下为示意代码:

    //Dto类
    @Data
    @ToString
    public class SortDto {
    
    	private String afterProductId;
    
    	private String productId;
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Controller:

    @Resource
    private Service service;
    
    /**
     * 拖动排序:前移、后移、置顶
     */
    @PostMapping("/update/sort")
    public Result updateSort(@RequestBody SortDto dto) {
    
    	return Result.success(service.updateProductSort(dto));
    	
    }
    
    
    /**
     * 删除产品
     */
     @GetMapping("/delete")
    public Result updateSort(String productId) {
    
    	return Result.success(service.deleteProduct(productId));
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    4、业务层

    Service层,直接写实现类:

    @Resource
    private ProductMapper mapper;
    
    public class ServiceImpl implements Service {
    	
    	@Override
    	public int updateProductSort(SortDto dto) {
    		//必要的参数和权限校验,略...
    		//被移动的产品
    		ProductPo targetPo = mapper.selectById(dto.getProductId);
    		Assert.notNull(targetPo);
    		//用于更新的产品对象
    		ProductPo updatePo = new ProductPo();
    		updatePo.setId(targetPo.getProductId);   //其他属性略,可直接BeanUtils.copyProperties()
    		//afterProductId为空,代表置顶操作
    		//非置顶
    		if (StringUtils.isNotEmpty(dto.getAfterProductId)){
    			//移动目标点的产品ID
    			ProductPo afterPo = mapper.selectById(dto.getAfterProductId);
    			Assert.notNull(afterPo);
    			//前移
    			if (afterPo.getHotSort() < targetPo.getHotSort() && targetPo.getHotSort() - afterPo.getHotSort() > 1) {
    				//产品前移,受影响的产品要后移
    				mapper.moveBack(afterPo.getHotSort(), targetPo.getHotSort());
    				//被移动的产品放到目标位置的产品之后
    				updatePo.setHotSort(afterPo.getHotSort() + 1 );
    				return mapper.updateById(updatePo);
    			//后移
    			} else if (afterPo.getHotSort() > targetPo.getHotSort() && afterPo.getHotSort() - targetPo.getHotSort() > 1) {
    				//产品后移,受影响的产品要前移
    				mapper.moveBefore(afterPo.getHotSort(), targetPo.getHotSort());
    				//被移动的产品放到目标位置的产品之后,但此时目标位置的产品已经前进一步,这里不再需要+1
    				updatePo.setHotSort(afterPo.getHotSort());
    				return mapper.updateById(updatePo);			
    			}
    		} else {
    			//置顶
    			mapper.moveTop(targetPo.getHotSort);   //处理因置顶产品而受影响的其他产品的sort值
    			updatePo.setHotSort(0);  //赋0,置顶
    			return mapper.updateById(updatePo);
    		}
    		return 1;  //如果两个Id都一样,也不用处理,直接返回个操作成功也无所谓
    
    	}
    
    
    	@Override
    	public int deleteProduct(String productId) {
    		//必要的业务和权限校验,略
    		ProductPo po = mapper.selectById(productId);
    		Assert.notNull(po);
    		int size = mapper.selectCount(new QueryWrapper<>());
    		//让被删产品后面的产品全部前进一格
    		mapper.moveBefore(size,po.getHotSort());
    		return mapper.deleteById(productId);
    		
    	}
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    5、数据层

    Mapper接口略,相关SQL:

    在这里插入图片描述

    <update id="moveBack" parameterType="int">
        update t_product
        set hot_sort = hot_sort + 1
        where hot_sort > #{beforeSort}
          and hot_sort < #{moveSort}
    update>
    
    <update id="moveBefore" parameterType="int">
        update t_product
        set hot_sort = hot_sort - 1
        where hot_sort > #{moveSort}
          and hot_sort <= #{beforeSort}
    update>
    
    <update id="moveTop" parameterType="int">
        update t_product
        set hot_sort = hot_sort + 1
        where hot_sort < #{moveSort}
    update>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
  • 相关阅读:
    精讲java中的CAS
    第27集丨为人格补钙,让心灵吸氧
    互联网商业模式设计方案
    三、stm32-USART串口通讯(重定向、接发通信、控制LED亮灭)
    大学生川菜网页制作教程 学生HTML静态美食菜品网页设计作业成品 简单网页制作代码 学生美食网页作品免费设计
    处理uniapp打包后有广告的问题
    Redis 的大 Key 对持久化有什么影响?
    docker swarm下部署的spring cloud,时不时就会取到ingress网络的ip
    C3P0和Druid数据库连接池的使用
    恕我直言,大模型对齐可能无法解决安全问题,我们都被表象误导了
  • 原文地址:https://blog.csdn.net/llg___/article/details/136687088