|
|
@@ -52,13 +52,22 @@ public class DataScopeInterceptor implements Interceptor {
|
|
|
return invocation.proceed();
|
|
|
} else {
|
|
|
String sortBy = (String) dataScope.get("sortBy");
|
|
|
- if (StringUtils.isNotEmpty(sortBy)) {
|
|
|
+ String sortName = (String) dataScope.get("sortName");
|
|
|
+ // PageHelper 会为分页查询额外生成一条以 _COUNT 结尾的统计语句,
|
|
|
+ // 统计语句是聚合查询,不能拼接 ORDER BY,否则在 ONLY_FULL_GROUP_BY 模式下会报错
|
|
|
+ boolean isCountQuery = mappedStatement.getId().toUpperCase().endsWith("_COUNT");
|
|
|
+ if (!isCountQuery && StringUtils.isNotEmpty(sortBy) && StringUtils.isNotEmpty(sortName)) {
|
|
|
+ String[] sortBys = sortBy.split(",");
|
|
|
+ String[] sortNames = sortName.split(",");
|
|
|
+ // sortBy 与 sortName 数量可能不一致,取较小值防止数组越界
|
|
|
+ int sortSize = Math.min(sortBys.length, sortNames.length);
|
|
|
+ // 拆出 PageHelper 追加在末尾的 LIMIT 子句,ORDER BY 需要拼接在 LIMIT 之前
|
|
|
String selectSql = originalSql;
|
|
|
String limitSql = "";
|
|
|
- int index = originalSql.indexOf("LIMIT");
|
|
|
- if (index > 0) {
|
|
|
- selectSql = originalSql.substring(0, index - 1);
|
|
|
- limitSql = originalSql.substring(index - 1, originalSql.length() - 1);
|
|
|
+ int limitIndex = originalSql.toUpperCase().lastIndexOf("LIMIT");
|
|
|
+ if (limitIndex > 0) {
|
|
|
+ selectSql = originalSql.substring(0, limitIndex).trim();
|
|
|
+ limitSql = " " + originalSql.substring(limitIndex).trim();
|
|
|
}
|
|
|
// 去掉已有的外层 ORDER BY,避免拼接出两个 ORDER BY 导致 SQL 语法错误
|
|
|
int orderByIndex = selectSql.toUpperCase().lastIndexOf("ORDER BY");
|
|
|
@@ -69,17 +78,16 @@ public class DataScopeInterceptor implements Interceptor {
|
|
|
selectSql = selectSql.substring(0, selectSql.length() - 1).trim();
|
|
|
}
|
|
|
}
|
|
|
- String[] sortBys = sortBy.split(",");
|
|
|
- String[] sortNames = ((String) dataScope.get("sortName")).split(",");
|
|
|
- StringBuffer sortStr = new StringBuffer(" order by ");
|
|
|
- for (int i = 0; i < sortBys.length; i++) {
|
|
|
- String sort = sortBys[i];
|
|
|
- String sortName = sortNames[i];
|
|
|
- sortStr.append(sortName).append(" ").append(sort).append(",");
|
|
|
+ StringBuilder sortStr = new StringBuilder(" order by ");
|
|
|
+ for (int i = 0; i < sortSize; i++) {
|
|
|
+ if (i > 0) {
|
|
|
+ sortStr.append(",");
|
|
|
+ }
|
|
|
+ sortStr.append(sortNames[i].trim()).append(" ").append(sortBys[i].trim());
|
|
|
}
|
|
|
- originalSql = selectSql + sortStr.toString().substring(0, sortStr.length() - 1) + limitSql;
|
|
|
+ originalSql = selectSql + sortStr + limitSql;
|
|
|
+ metaObject.setValue("delegate.boundSql.sql", originalSql);
|
|
|
}
|
|
|
- metaObject.setValue("delegate.boundSql.sql", originalSql);
|
|
|
return invocation.proceed();
|
|
|
// String scopeName = dataScope.getScopeName();
|
|
|
// List<Integer> deptIds = dataScope.getDeptIds();
|
|
|
@@ -123,14 +131,32 @@ public class DataScopeInterceptor implements Interceptor {
|
|
|
* @return DataScope
|
|
|
*/
|
|
|
private HashMap findDataScopeObject(Object parameterObj) {
|
|
|
+ if (parameterObj == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
if (parameterObj instanceof DataScope) {
|
|
|
return (HashMap) parameterObj;
|
|
|
- } else if (parameterObj instanceof Map) {
|
|
|
+ }
|
|
|
+ if (parameterObj instanceof Map) {
|
|
|
for (Object val : ((Map<?, ?>) parameterObj).values()) {
|
|
|
if (val instanceof DataScope) {
|
|
|
return (HashMap) val;
|
|
|
}
|
|
|
}
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ // 单个 JavaBean(各类 DTO)作为 Mapper 参数时,MyBatis 不会将其包装成 Map,
|
|
|
+ // 需要反射读取其 dataScope 属性,否则前端传入的排序条件会被整体忽略
|
|
|
+ try {
|
|
|
+ MetaObject paramMetaObject = SystemMetaObject.forObject(parameterObj);
|
|
|
+ if (paramMetaObject.hasGetter("dataScope")) {
|
|
|
+ Object val = paramMetaObject.getValue("dataScope");
|
|
|
+ if (val instanceof DataScope) {
|
|
|
+ return (HashMap) val;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("读取参数 dataScope 属性失败: {}", e.getMessage());
|
|
|
}
|
|
|
return null;
|
|
|
}
|