From 1090ab6ddb72a93174b323f4beaaacd698ea72da Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 8 Jul 2026 15:06:13 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E7=94=B5=E7=AB=99?= =?UTF-8?q?=E6=9D=83=E9=99=90=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/vo/DataScopeApplyResult.java | 29 ++++ .../service/IDataScopeFilterService.java | 33 ++++ .../impl/DataScopeFilterServiceImpl.java | 154 ++++++++++++++++++ .../service/impl/SdEngInfoBHServiceImpl.java | 25 +-- 4 files changed, 225 insertions(+), 16 deletions(-) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_base/domain/vo/DataScopeApplyResult.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_base/service/IDataScopeFilterService.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_base/service/impl/DataScopeFilterServiceImpl.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/domain/vo/DataScopeApplyResult.java b/backend/src/main/java/com/yfd/platform/qgc_base/domain/vo/DataScopeApplyResult.java new file mode 100644 index 00000000..7e6319ed --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_base/domain/vo/DataScopeApplyResult.java @@ -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; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/service/IDataScopeFilterService.java b/backend/src/main/java/com/yfd/platform/qgc_base/service/IDataScopeFilterService.java new file mode 100644 index 00000000..cbdd76c3 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_base/service/IDataScopeFilterService.java @@ -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 paramMap, String columnName); + + /** + * 追加当前用户流域权限 SQL 条件 + */ + DataScopeApplyResult appendCurrentUserRvcdScope(StringBuilder sql, Map paramMap, String columnName); + + /** + * 追加当前用户电站权限 Wrapper 条件 + */ + DataScopeApplyResult applyCurrentUserStationScope(LambdaQueryWrapper wrapper, SFunction column); + + /** + * 追加当前用户流域权限 Wrapper 条件 + */ + DataScopeApplyResult applyCurrentUserRvcdScope(LambdaQueryWrapper wrapper, SFunction column); +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/DataScopeFilterServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/DataScopeFilterServiceImpl.java new file mode 100644 index 00000000..9fab46f3 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/DataScopeFilterServiceImpl.java @@ -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 paramMap, String columnName) { + CurrentUserDataScopeVo scopeVo = currentUserDataScopeService.getCurrentUserDataScope(); + return appendScopeCondition(sql, paramMap, columnName, scopeVo, scopeVo.getStationCodes(), "stationScope"); + } + + @Override + public DataScopeApplyResult appendCurrentUserRvcdScope(StringBuilder sql, Map paramMap, String columnName) { + CurrentUserDataScopeVo scopeVo = currentUserDataScopeService.getCurrentUserDataScope(); + return appendScopeCondition(sql, paramMap, columnName, scopeVo, scopeVo.getRvcdCodes(), "rvcdScope"); + } + + @Override + public DataScopeApplyResult applyCurrentUserStationScope(LambdaQueryWrapper wrapper, SFunction column) { + CurrentUserDataScopeVo scopeVo = currentUserDataScopeService.getCurrentUserDataScope(); + return applyScopeCondition(wrapper, column, scopeVo, scopeVo.getStationCodes()); + } + + @Override + public DataScopeApplyResult applyCurrentUserRvcdScope(LambdaQueryWrapper wrapper, SFunction column) { + CurrentUserDataScopeVo scopeVo = currentUserDataScopeService.getCurrentUserDataScope(); + return applyScopeCondition(wrapper, column, scopeVo, scopeVo.getRvcdCodes()); + } + + private DataScopeApplyResult appendScopeCondition(StringBuilder sql, + Map paramMap, + String columnName, + CurrentUserDataScopeVo scopeVo, + Set scopeValues, + String paramPrefix) { + DataScopeApplyResult result = initResult(scopeVo, scopeValues); + if (result.isManagedAdmin() || result.isEmptyResult()) { + return result; + } + if (!StringUtils.hasText(columnName)) { + return result; + } + + List> 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 batch = batches.get(i); + List 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 DataScopeApplyResult applyScopeCondition(LambdaQueryWrapper wrapper, + SFunction column, + CurrentUserDataScopeVo scopeVo, + Set scopeValues) { + DataScopeApplyResult result = initResult(scopeVo, scopeValues); + if (result.isManagedAdmin() || result.isEmptyResult()) { + return result; + } + + List> 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 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> splitValues(Collection values) { + List> batches = new ArrayList<>(); + if (CollectionUtils.isEmpty(values)) { + return batches; + } + + List 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 paramMap, String paramPrefix, int batchIndex, int itemIndex) { + String key = paramPrefix + "_" + batchIndex + "_" + itemIndex; + while (paramMap.containsKey(key)) { + key = key + "_n"; + } + return key; + } +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdEngInfoBHServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdEngInfoBHServiceImpl.java index 0776145e..9575cea8 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdEngInfoBHServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdEngInfoBHServiceImpl.java @@ -20,10 +20,10 @@ import com.yfd.platform.common.DataSourceResult; import com.yfd.platform.common.GroupHelper; import com.yfd.platform.common.GroupingInfo; 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.mapper.SysUserDataScopeMapper; 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.vo.EngBaseInfoVo; 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.EngVmsstbprptVo; 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.ISdEngInfoBHService; import com.yfd.platform.system.service.IAdminAuthService; @@ -64,7 +65,7 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl ENG_CODE_NAME_FIELD_MAP = new LinkedHashMap<>(); @Resource - private ICurrentUserDataScopeService currentUserDataScopeService; + private IDataScopeFilterService dataScopeFilterService; static { ENG_CODE_NAME_FIELD_MAP.put("baseId", "baseName"); @@ -2765,21 +2766,13 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl stationCodes = currentUserDataScopeService.getCurrentUserDataScope().getStationCodes(); - if (!stationCodes.isEmpty()) { - // 每个值加单引号,并用逗号连接 - 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.setTotal(0L); - return result; - } - } Map paramMap = new HashMap<>(); + DataScopeApplyResult scopeApplyResult = dataScopeFilterService.appendCurrentUserStationScope(sql, paramMap, "t.STCD"); + if (scopeApplyResult.isEmptyResult()) { + result.setData(new ArrayList<>()); + result.setTotal(0L); + return result; + } String filterSql = buildEngPointFilterCondition(dataSourceRequest.getFilter(), paramMap, new int[]{0}); if (StrUtil.isNotBlank(filterSql)) { sql.append(" AND ").append(filterSql);