package com.chinaztt.mes.common.wrapper; import cn.hutool.core.collection.CollectionUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.AllArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.math.BigDecimal; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; /** * @Author: zhangxy * @Date: 2020-09-12 10:25 */ @Component @AllArgsConstructor public class QueryWrapperUtil { private static final String ASC = "asc"; private static final String DIRECTION = "direction"; private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); private static final List EQ_CLAZZ = Arrays.asList(Long.class, Integer.class, Boolean.class, BigDecimal.class, Double.class); private static final List LIKE_CLAZZ = Arrays.asList(String.class); private ResultMapHelper resultMapHelper; private static ResultMapHelper staticResultMapHelper; /** * 生成mybatis-plus查询条件 * * @param entity * @param * @return */ public static QueryWrapper gen(T entity) { QueryWrapper qw = Wrappers.query(); try { Class cls = entity.getClass(); Field[] fields = getAllFields(entity); for (Field field : fields) { field.setAccessible(true); String name = field.getName(); if (Modifier.isStatic(field.getModifiers())) { continue; } Object value = field.get(entity); if (value != null && StringUtils.isNotEmpty(value.toString())) { if ("criteria".equals(name)) { JSONObject criteriaJo = (JSONObject) JSON.parse(value.toString()); if (criteriaJo.isEmpty()) { continue; } Iterator it = criteriaJo.keySet().iterator(); while (it.hasNext()) { String key = it.next(); if ("dateTimeFilters".equals(key)) { dateTimeWrapper(qw, criteriaJo.get(key), cls); } else if ("multiSearchFilter".equals(key)) { multiSearchWrapper(qw, criteriaJo.get(key), cls); } else if ("orderBy".equals(key)) { orderByWrapper(qw, criteriaJo.get(key), cls); } } } else { customWrapper(qw, field, value, name, cls); } } } } catch (Exception e) { e.printStackTrace(); } /** * 解决mybatis-plus bug :只有排序条件时,isEmptyOfWhere = true */ if (qw.isEmptyOfWhere() && StringUtils.isNotEmpty(qw.getSqlSegment())) { qw.eq("1", 1); } return qw; } /** * descColumn倒序排列 * * @param entity * @param descColumn * @param * @return */ public static QueryWrapper gen(T entity, String descColumn) { return gen(entity).orderByDesc(descColumn); } /** * 排序 * * @param qw * @param value * @param cls */ private static void orderByWrapper(QueryWrapper qw, Object value, Class cls) { JSONObject obj = (JSONObject) JSON.parse(value.toString()); if (obj.isEmpty()) { return; } String column = getColumnName(obj.getString("column"), cls); if (StringUtils.isEmpty(column)) { throw new RuntimeException("排序字段不存在,请检查拼写"); } if (ASC.equals(obj.getString(DIRECTION))) { qw.orderByAsc(column); } else { qw.orderByDesc(column); } } /** * 普通搜索 * * @param qw * @param field * @param value * @param fieldName */ private static void customWrapper(QueryWrapper qw, Field field, Object value, String fieldName, Class cls) { String columnName = getColumnName(fieldName, cls); Class type = field.getType(); if (EQ_CLAZZ.contains(type)) { qw.eq(columnName, value); } else if (LIKE_CLAZZ.contains(type)) { qw.like(columnName, value); } } /** * 时间搜索 * * @param qw * @param value * @param cls */ private static void dateTimeWrapper(QueryWrapper qw, Object value, Class cls) { JSONObject obj = (JSONObject) JSON.parse(value.toString()); Set keys = obj.keySet(); if (CollectionUtil.isNotEmpty(keys)) { for (String key : keys) { String columnName = getColumnName(key, cls); JSONArray timeRange = (JSONArray) obj.get(key); if (timeRange.get(0) != null) { qw.ge(columnName, LocalDateTime.parse((CharSequence) timeRange.get(0), FORMATTER)); } if (timeRange.get(1) != null) { qw.lt(columnName, LocalDateTime.parse((CharSequence) timeRange.get(1), FORMATTER)); } } } } /** * 高级搜索 * * @param qw * @param multiSearchFilter * @param cls * @param */ public static void multiSearchWrapper(QueryWrapper qw, Object multiSearchFilter, Class cls) { JSONObject filter = JSON.parseObject(multiSearchFilter.toString()); if (filter == null || filter.size() == 0) { return; } FilterOperator groupOperator = FilterOperator.valueOf(filter.getString("groupOp")); JSONArray rules = filter.getJSONArray("rules"); if (rules == null || rules.size() == 0) { return; } Iterator it = rules.iterator(); qw.and(multiQw -> { while (it.hasNext()) { iterateCondition(cls, groupOperator, it, multiQw); } }); } private static void iterateCondition(Class cls, FilterOperator groupOperator, Iterator it, QueryWrapper multiQw) { JSONObject rule = JSON.parseObject(it.next().toString()); String column = getColumnName(rule.getString("name"), cls); FilterOperator operator = FilterOperator.valueOf(rule.getString("op")); Object value = rule.get("value"); switch (operator) { case EQ: multiQw.eq(column, value); break; case NE: multiQw.ne(column, value); break; case LE: multiQw.le(column, value); break; case LT: multiQw.lt(column, value); break; case GE: multiQw.ge(column, value); break; case GT: multiQw.gt(column, value); break; case CN: multiQw.like(column, value); break; case BW: multiQw.likeRight(column, value); break; case EW: multiQw.likeLeft(column, value); break; case IN: multiQw.inSql(column, value.toString()); break; case ISNULL: multiQw.isNull(column); break; case NOTNULL: multiQw.isNotNull(column); break; default: throw new IllegalStateException("Unknown filter operator=" + operator); } if (it.hasNext() && groupOperator.equals(FilterOperator.OR)) { multiQw.or(); } } public static String getColumnName(String fieldName, Class clazz) { Map> map = staticResultMapHelper.getColumnMaps(); Map fieldMaps = map.get(clazz); if (fieldMaps == null) { throw new RuntimeException("没有找到对应的mapper映射,请检查!"); } return fieldMaps.get(fieldName); } private static Field[] getAllFields(T object) { Class clazz = object.getClass(); List fieldList = new ArrayList<>(); while (clazz != null) { fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields()))); clazz = clazz.getSuperclass(); } Field[] fields = new Field[fieldList.size()]; fieldList.toArray(fields); return fields; } @PostConstruct public void init() { QueryWrapperUtil.staticResultMapHelper = resultMapHelper; } }