|
|
@@ -0,0 +1,74 @@
|
|
|
+package com.etotem.cfc.util;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import org.springframework.util.StringUtils;
|
|
|
+
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 通用排序工具:将前端 sort 参数注入 MyBatis-Plus 查询包装器。
|
|
|
+ * 支持 LambdaQueryWrapper 和 QueryWrapper。
|
|
|
+ */
|
|
|
+public class SortUtil {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 对 QueryWrapper 应用排序。如果 sortSpecs 为空则不修改排序(保留原有排序)。
|
|
|
+ *
|
|
|
+ * @param wrapper QueryWrapper 实例
|
|
|
+ * @param sortSpecs 前端传入的排序数组,每项 {column, order}
|
|
|
+ * @param snakeMap 驼峰属性名 → 数据库列名 映射(可为 null)
|
|
|
+ */
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ public static <T> void applySort(QueryWrapper<T> wrapper,
|
|
|
+ List<Map<String, String>> sortSpecs,
|
|
|
+ Map<String, String> snakeMap) {
|
|
|
+ if (sortSpecs == null || sortSpecs.isEmpty() || wrapper == null) return;
|
|
|
+ StringBuilder sb = new StringBuilder(" order by ");
|
|
|
+ for (int i = 0; i < sortSpecs.size(); i++) {
|
|
|
+ if (i > 0) sb.append(", ");
|
|
|
+ Map<String, String> spec = sortSpecs.get(i);
|
|
|
+ String col = spec.get("column");
|
|
|
+ if (!StringUtils.hasText(col)) continue;
|
|
|
+ boolean asc = !"desc".equalsIgnoreCase(spec.get("order"));
|
|
|
+ String dbCol = resolveDbColumn(col, snakeMap);
|
|
|
+ sb.append(dbCol).append(asc ? " asc" : " desc");
|
|
|
+ }
|
|
|
+ if (sb.length() > 11) {
|
|
|
+ wrapper.last(sb.toString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 对 LambdaQueryWrapper 应用排序(通过反射设置 last SQL)。
|
|
|
+ * 因为 LambdaQueryWrapper 没有通用的 orderBy 重载接受 db 列名字符串,
|
|
|
+ * 所以直接通过 last() 追加。
|
|
|
+ */
|
|
|
+ public static <T> void applySort(LambdaQueryWrapper<T> wrapper,
|
|
|
+ List<Map<String, String>> sortSpecs,
|
|
|
+ Map<String, String> snakeMap) {
|
|
|
+ if (sortSpecs == null || sortSpecs.isEmpty() || wrapper == null) return;
|
|
|
+ StringBuilder sb = new StringBuilder(" order by ");
|
|
|
+ for (int i = 0; i < sortSpecs.size(); i++) {
|
|
|
+ if (i > 0) sb.append(", ");
|
|
|
+ Map<String, String> spec = sortSpecs.get(i);
|
|
|
+ String col = spec.get("column");
|
|
|
+ if (!StringUtils.hasText(col)) continue;
|
|
|
+ boolean asc = !"desc".equalsIgnoreCase(spec.get("order"));
|
|
|
+ String dbCol = resolveDbColumn(col, snakeMap);
|
|
|
+ sb.append(dbCol).append(asc ? " asc" : " desc");
|
|
|
+ }
|
|
|
+ if (sb.length() > 11) {
|
|
|
+ wrapper.last(sb.toString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String resolveDbColumn(String camelCol, Map<String, String> snakeMap) {
|
|
|
+ if (snakeMap != null && snakeMap.containsKey(camelCol)) {
|
|
|
+ return snakeMap.get(camelCol);
|
|
|
+ }
|
|
|
+ // 默认:驼峰转下划线
|
|
|
+ return camelCol.replaceAll("([A-Z])", "_$1").toLowerCase();
|
|
|
+ }
|
|
|
+}
|