You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SpringBoot后台管理面板中自定义调整分类排序?

SpringBoot实现产品分类自定义排序(上下箭头操作)

一、实体层改造

给产品分类实体(如ProductCategory)新增排序字段,用于存储优先级排序值:

@Entity
@Table(name = "product_category")
public class ProductCategory {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    // 排序字段,值越小展示越靠前,默认初始化0
    private Integer sort = 0;
    // 其他业务字段、getter/setter省略
}

新创建分类时,可将sort设为当前最大排序值+1,确保默认排在列表末尾。

二、DAO层(Repository)

实现核心数据操作方法,支持排序更新、相邻分类查询:

public interface ProductCategoryRepository extends JpaRepository<ProductCategory, Long> {
    // 根据ID更新排序值
    @Modifying
    @Query("UPDATE ProductCategory c SET c.sort = :sort WHERE c.id = :id")
    void updateSortById(@Param("id") Long id, @Param("sort") Integer sort);

    // 查询当前分类的上一个分类(取sort小于当前值的最大项)
    Optional<ProductCategory> findTopBySortLessThanOrderBySortDesc(Long currentSort);

    // 查询当前分类的下一个分类(取sort大于当前值的最小项)
    Optional<ProductCategory> findTopBySortGreaterThanOrderBySortAsc(Long currentSort);

    // 按排序值升序查询所有分类
    List<ProductCategory> findAllByOrderBySortAsc();
}

三、Service层排序逻辑

编写上下移动的业务逻辑,核心是交换当前分类与相邻分类的排序值:

@Service
public class ProductCategoryService {
    @Autowired
    private ProductCategoryRepository categoryRepository;

    // 分类上移
    public void moveUp(Long categoryId) {
        ProductCategory current = categoryRepository.findById(categoryId)
                .orElseThrow(() -> new RuntimeException("目标分类不存在"));
        Optional<ProductCategory> prevOpt = categoryRepository.findTopBySortLessThanOrderBySortDesc(current.getSort());
        if (prevOpt.isPresent()) {
            ProductCategory prev = prevOpt.get();
            // 交换排序值
            Integer temp = current.getSort();
            current.setSort(prev.getSort());
            prev.setSort(temp);
            categoryRepository.save(current);
            categoryRepository.save(prev);
        }
    }

    // 分类下移
    public void moveDown(Long categoryId) {
        ProductCategory current = categoryRepository.findById(categoryId)
                .orElseThrow(() -> new RuntimeException("目标分类不存在"));
        Optional<ProductCategory> nextOpt = categoryRepository.findTopBySortGreaterThanOrderBySortAsc(current.getSort());
        if (nextOpt.isPresent()) {
            ProductCategory next = nextOpt.get();
            // 交换排序值
            Integer temp = current.getSort();
            current.setSort(next.getSort());
            next.setSort(temp);
            categoryRepository.save(current);
            categoryRepository.save(next);
        }
    }
}

四、Controller层接口

按照你提到的/order-save设计统一接口,接收分类ID和移动方向:

@RestController
@RequestMapping("/admin/category")
public class ProductCategoryController {
    @Autowired
    private ProductCategoryService categoryService;

    @PostMapping("/order-save")
    public ResponseEntity<Void> saveOrder(@RequestParam Long categoryId, @RequestParam String direction) {
        if ("up".equals(direction)) {
            categoryService.moveUp(categoryId);
        } else if ("down".equals(direction)) {
            categoryService.moveDown(categoryId);
        } else {
            return ResponseEntity.badRequest().build();
        }
        return ResponseEntity.ok().build();
    }
}

五、前端上下箭头实现

在后台分类列表页面,给每个分类添加fas fa-arrow-up和fas fa-arrow-down按钮,点击时调用后端接口并刷新列表:

<!-- 以Thymeleaf模板为例渲染分类列表 -->
<table class="table">
    <thead>
        <tr>
            <th>分类名称</th>
            <th>排序操作</th>
        </tr>
    </thead>
    <tbody>
        <tr th:each="category : ${categories}">
            <td th:text="${category.name}"></td>
            <td>
                <button class="btn btn-sm btn-outline-primary" 
                        onclick="adjustSort([[${category.id}]], 'up')">
                    <i class="fas fa-arrow-up"></i>
                </button>
                <button class="btn btn-sm btn-outline-primary" 
                        onclick="adjustSort([[${category.id}]], 'down')">
                    <i class="fas fa-arrow-down"></i>
                </button>
            </td>
        </tr>
    </tbody>
</table>

<script>
function adjustSort(categoryId, direction) {
    fetch('/admin/category/order-save', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'X-CSRF-TOKEN': document.querySelector('meta[name="_csrf"]').content
        },
        body: `categoryId=${categoryId}&direction=${direction}`
    }).then(response => {
        if (response.ok) {
            window.location.reload();
        }
    }).catch(error => {
        console.error('排序失败:', error);
        alert('排序操作失败,请重试');
    });
}
</script>

注意事项

  • 权限控制:后台接口需添加管理员权限校验,防止非法访问
  • 排序初始化:新分类创建时,可通过查询当前最大排序值+1来设置初始sort
  • 异常处理:可根据业务需求自定义异常类型,替换示例中的RuntimeException

内容的提问来源于stack exchange,提问作者mattar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 11:17:42