fix: 优化电站权限逻辑

This commit is contained in:
tangwei 2026-07-08 15:06:13 +08:00
parent 5fcc7eca34
commit 1090ab6ddb
4 changed files with 225 additions and 16 deletions

View File

@ -0,0 +1,29 @@
package com.yfd.platform.qgc_base.domain.vo;
import lombok.Data;
import java.io.Serializable;
/**
* 数据权限条件应用结果
*/
@Data
public class DataScopeApplyResult implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 当前用户是否为管理员
*/
private boolean managedAdmin;
/**
* 当前权限是否命中空结果
*/
private boolean emptyResult;
/**
* 是否已向查询中追加权限条件
*/
private boolean conditionApplied;
}

View File

@ -0,0 +1,33 @@
package com.yfd.platform.qgc_base.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.yfd.platform.qgc_base.domain.vo.DataScopeApplyResult;
import java.util.Map;
/**
* 当前用户数据权限过滤公共服务
*/
public interface IDataScopeFilterService {
/**
* 追加当前用户电站权限 SQL 条件
*/
DataScopeApplyResult appendCurrentUserStationScope(StringBuilder sql, Map<String, Object> paramMap, String columnName);
/**
* 追加当前用户流域权限 SQL 条件
*/
DataScopeApplyResult appendCurrentUserRvcdScope(StringBuilder sql, Map<String, Object> paramMap, String columnName);
/**
* 追加当前用户电站权限 Wrapper 条件
*/
<T> DataScopeApplyResult applyCurrentUserStationScope(LambdaQueryWrapper<T> wrapper, SFunction<T, ?> column);
/**
* 追加当前用户流域权限 Wrapper 条件
*/
<T> DataScopeApplyResult applyCurrentUserRvcdScope(LambdaQueryWrapper<T> wrapper, SFunction<T, ?> column);
}

View File

@ -0,0 +1,154 @@
package com.yfd.platform.qgc_base.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.yfd.platform.qgc_base.domain.vo.CurrentUserDataScopeVo;
import com.yfd.platform.qgc_base.domain.vo.DataScopeApplyResult;
import com.yfd.platform.qgc_base.service.ICurrentUserDataScopeService;
import com.yfd.platform.qgc_base.service.IDataScopeFilterService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 当前用户数据权限过滤公共服务实现
*/
@Service
public class DataScopeFilterServiceImpl implements IDataScopeFilterService {
private static final int IN_BATCH_SIZE = 900;
@Resource
private ICurrentUserDataScopeService currentUserDataScopeService;
@Override
public DataScopeApplyResult appendCurrentUserStationScope(StringBuilder sql, Map<String, Object> paramMap, String columnName) {
CurrentUserDataScopeVo scopeVo = currentUserDataScopeService.getCurrentUserDataScope();
return appendScopeCondition(sql, paramMap, columnName, scopeVo, scopeVo.getStationCodes(), "stationScope");
}
@Override
public DataScopeApplyResult appendCurrentUserRvcdScope(StringBuilder sql, Map<String, Object> paramMap, String columnName) {
CurrentUserDataScopeVo scopeVo = currentUserDataScopeService.getCurrentUserDataScope();
return appendScopeCondition(sql, paramMap, columnName, scopeVo, scopeVo.getRvcdCodes(), "rvcdScope");
}
@Override
public <T> DataScopeApplyResult applyCurrentUserStationScope(LambdaQueryWrapper<T> wrapper, SFunction<T, ?> column) {
CurrentUserDataScopeVo scopeVo = currentUserDataScopeService.getCurrentUserDataScope();
return applyScopeCondition(wrapper, column, scopeVo, scopeVo.getStationCodes());
}
@Override
public <T> DataScopeApplyResult applyCurrentUserRvcdScope(LambdaQueryWrapper<T> wrapper, SFunction<T, ?> column) {
CurrentUserDataScopeVo scopeVo = currentUserDataScopeService.getCurrentUserDataScope();
return applyScopeCondition(wrapper, column, scopeVo, scopeVo.getRvcdCodes());
}
private DataScopeApplyResult appendScopeCondition(StringBuilder sql,
Map<String, Object> paramMap,
String columnName,
CurrentUserDataScopeVo scopeVo,
Set<String> scopeValues,
String paramPrefix) {
DataScopeApplyResult result = initResult(scopeVo, scopeValues);
if (result.isManagedAdmin() || result.isEmptyResult()) {
return result;
}
if (!StringUtils.hasText(columnName)) {
return result;
}
List<List<String>> batches = splitValues(scopeValues);
if (batches.isEmpty()) {
result.setEmptyResult(true);
return result;
}
sql.append(" AND (");
for (int i = 0; i < batches.size(); i++) {
if (i > 0) {
sql.append(" OR ");
}
List<String> batch = batches.get(i);
List<String> placeholders = new ArrayList<>();
for (int j = 0; j < batch.size(); j++) {
String key = buildParamKey(paramMap, paramPrefix, i, j);
paramMap.put(key, batch.get(j));
placeholders.add("#{map." + key + "}");
}
sql.append(columnName).append(" IN (").append(String.join(", ", placeholders)).append(")");
}
sql.append(") ");
result.setConditionApplied(true);
return result;
}
private <T> DataScopeApplyResult applyScopeCondition(LambdaQueryWrapper<T> wrapper,
SFunction<T, ?> column,
CurrentUserDataScopeVo scopeVo,
Set<String> scopeValues) {
DataScopeApplyResult result = initResult(scopeVo, scopeValues);
if (result.isManagedAdmin() || result.isEmptyResult()) {
return result;
}
List<List<String>> batches = splitValues(scopeValues);
if (batches.isEmpty()) {
result.setEmptyResult(true);
return result;
}
wrapper.and(innerWrapper -> {
for (int i = 0; i < batches.size(); i++) {
if (i > 0) {
innerWrapper.or();
}
innerWrapper.in(column, batches.get(i));
}
});
result.setConditionApplied(true);
return result;
}
private DataScopeApplyResult initResult(CurrentUserDataScopeVo scopeVo, Collection<String> scopeValues) {
DataScopeApplyResult result = new DataScopeApplyResult();
if (scopeVo != null && scopeVo.isManagedAdmin()) {
result.setManagedAdmin(true);
return result;
}
if (CollectionUtils.isEmpty(scopeValues)) {
result.setEmptyResult(true);
}
return result;
}
private List<List<String>> splitValues(Collection<String> values) {
List<List<String>> batches = new ArrayList<>();
if (CollectionUtils.isEmpty(values)) {
return batches;
}
List<String> valueList = new ArrayList<>(values);
for (int i = 0; i < valueList.size(); i += IN_BATCH_SIZE) {
int end = Math.min(i + IN_BATCH_SIZE, valueList.size());
batches.add(valueList.subList(i, end));
}
return batches;
}
private String buildParamKey(Map<String, Object> paramMap, String paramPrefix, int batchIndex, int itemIndex) {
String key = paramPrefix + "_" + batchIndex + "_" + itemIndex;
while (paramMap.containsKey(key)) {
key = key + "_n";
}
return key;
}
}

View File

@ -20,10 +20,10 @@ import com.yfd.platform.common.DataSourceResult;
import com.yfd.platform.common.GroupHelper; import com.yfd.platform.common.GroupHelper;
import com.yfd.platform.common.GroupingInfo; import com.yfd.platform.common.GroupingInfo;
import com.yfd.platform.common.MicroservicDynamicSQLMapper; import com.yfd.platform.common.MicroservicDynamicSQLMapper;
import com.yfd.platform.qgc_base.service.ICurrentUserDataScopeService;
import com.yfd.platform.qgc_data.domain.SysUserDataScope; import com.yfd.platform.qgc_data.domain.SysUserDataScope;
import com.yfd.platform.qgc_data.mapper.SysUserDataScopeMapper; import com.yfd.platform.qgc_data.mapper.SysUserDataScopeMapper;
import com.yfd.platform.qgc_base.domain.SdEngInfoBH; import com.yfd.platform.qgc_base.domain.SdEngInfoBH;
import com.yfd.platform.qgc_base.domain.vo.DataScopeApplyResult;
import com.yfd.platform.qgc_base.domain.SdEngInfoBHRequest; import com.yfd.platform.qgc_base.domain.SdEngInfoBHRequest;
import com.yfd.platform.qgc_base.domain.vo.EngBaseInfoVo; import com.yfd.platform.qgc_base.domain.vo.EngBaseInfoVo;
import com.yfd.platform.qgc_base.domain.vo.EngEiaapprovalVo; import com.yfd.platform.qgc_base.domain.vo.EngEiaapprovalVo;
@ -37,6 +37,7 @@ import com.yfd.platform.qgc_base.domain.vo.EngStBaseInfoVo;
import com.yfd.platform.qgc_base.domain.vo.EngStInfoResultVo; import com.yfd.platform.qgc_base.domain.vo.EngStInfoResultVo;
import com.yfd.platform.qgc_base.domain.vo.EngVmsstbprptVo; import com.yfd.platform.qgc_base.domain.vo.EngVmsstbprptVo;
import com.yfd.platform.qgc_base.mapper.SdEngInfoBHMapper; import com.yfd.platform.qgc_base.mapper.SdEngInfoBHMapper;
import com.yfd.platform.qgc_base.service.IDataScopeFilterService;
import com.yfd.platform.qgc_base.service.IMsOperationLogService; import com.yfd.platform.qgc_base.service.IMsOperationLogService;
import com.yfd.platform.qgc_base.service.ISdEngInfoBHService; import com.yfd.platform.qgc_base.service.ISdEngInfoBHService;
import com.yfd.platform.system.service.IAdminAuthService; import com.yfd.platform.system.service.IAdminAuthService;
@ -64,7 +65,7 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl<SdEngInfoBHMapper, SdEng
private static final Map<String, String> ENG_CODE_NAME_FIELD_MAP = new LinkedHashMap<>(); private static final Map<String, String> ENG_CODE_NAME_FIELD_MAP = new LinkedHashMap<>();
@Resource @Resource
private ICurrentUserDataScopeService currentUserDataScopeService; private IDataScopeFilterService dataScopeFilterService;
static { static {
ENG_CODE_NAME_FIELD_MAP.put("baseId", "baseName"); ENG_CODE_NAME_FIELD_MAP.put("baseId", "baseName");
@ -2765,21 +2766,13 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl<SdEngInfoBHMapper, SdEng
.append("AND NVL(t.USFL, 1) = 1 ") .append("AND NVL(t.USFL, 1) = 1 ")
.append("AND t.LGTD IS NOT NULL ") .append("AND t.LGTD IS NOT NULL ")
.append("AND t.LTTD IS NOT NULL "); .append("AND t.LTTD IS NOT NULL ");
if (!currentUserDataScopeService.getCurrentUserDataScope().isManagedAdmin()) { Map<String, Object> paramMap = new HashMap<>();
Set<String> stationCodes = currentUserDataScopeService.getCurrentUserDataScope().getStationCodes(); DataScopeApplyResult scopeApplyResult = dataScopeFilterService.appendCurrentUserStationScope(sql, paramMap, "t.STCD");
if (!stationCodes.isEmpty()) { if (scopeApplyResult.isEmptyResult()) {
// 每个值加单引号并用逗号连接
String inClause = stationCodes.stream()
.map(code -> "'" + code + "'") // 如果值本身不含单引号可简单处理更严谨需转义
.collect(Collectors.joining(","));
sql.append("AND t.STCD IN (").append(inClause).append(") ");
}else{
result.setData(new ArrayList<>()); result.setData(new ArrayList<>());
result.setTotal(0L); result.setTotal(0L);
return result; return result;
} }
}
Map<String, Object> paramMap = new HashMap<>();
String filterSql = buildEngPointFilterCondition(dataSourceRequest.getFilter(), paramMap, new int[]{0}); String filterSql = buildEngPointFilterCondition(dataSourceRequest.getFilter(), paramMap, new int[]{0});
if (StrUtil.isNotBlank(filterSql)) { if (StrUtil.isNotBlank(filterSql)) {
sql.append(" AND ").append(filterSql); sql.append(" AND ").append(filterSql);