文章目录
- 1、需求分析
- 2、表设计
- 3、接口设计
- 4、业务层
- 5、数据层
整理个需求的实现思路。
1、需求分析
列表展示了一系列产品,现要支持通过拖动来给产品排序,也要支持单个产品的置顶、删除。类似CSDN的专栏文章管理。
2、表设计
现要支持对列表的产品进行拖动排序,考虑新增个hot_sort字段,代表产品的先后顺序(或者热门程度)。关于表设计,可在原来的 t_product表中直接新加个hot_sort字段。如果有其他业务字段,也可新建个中间表,核心字段:t_product表的product_id
、热门排序字段hot_sort
、其余业务字段。
//示例
ALTER TABLE t_product ADD hot_sort INT;
//值越小越靠前
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;}
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));}
4、业务层
Service层,直接写实现类:
@Resource
private ProductMapper mapper;public class ServiceImpl implements Service {@Overridepublic 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)){//移动目标点的产品IDProductPo 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());//被移动的产品放到目标位置的产品之后,但此时目标位置的产品已经前进一步,这里不再需要+1updatePo.setHotSort(afterPo.getHotSort());return mapper.updateById(updatePo); }} else {//置顶mapper.moveTop(targetPo.getHotSort); //处理因置顶产品而受影响的其他产品的sort值updatePo.setHotSort(0); //赋0,置顶return mapper.updateById(updatePo);}return 1; //如果两个Id都一样,也不用处理,直接返回个操作成功也无所谓}@Overridepublic 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);}}
5、数据层
Mapper接口略,相关SQL:
<update id="moveBack" parameterType="int">update t_productset hot_sort = hot_sort + 1where hot_sort > #{beforeSort}and hot_sort < #{moveSort}
</update><update id="moveBefore" parameterType="int">update t_productset hot_sort = hot_sort - 1where hot_sort > #{moveSort}and hot_sort <= #{beforeSort}
</update><update id="moveTop" parameterType="int">update t_productset hot_sort = hot_sort + 1where hot_sort < #{moveSort}
</update>