From a5fc9d3b377c3915ca7a0e881575ffba84ebc943 Mon Sep 17 00:00:00 2001 From: tangwei Date: Fri, 31 Jul 2026 13:59:43 +0800 Subject: [PATCH 01/10] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fp/controller/FishPassageController.java | 7 + .../qgc_env/fp/service/FpRunService.java | 2 + .../fp/service/impl/FpRunServiceImpl.java | 264 ++++++++++++++++++ .../src/main/resources/application-prod.yml | 2 +- 4 files changed, 274 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fp/controller/FishPassageController.java b/backend/src/main/java/com/yfd/platform/qgc_env/fp/controller/FishPassageController.java index a256f281..be3b1a60 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fp/controller/FishPassageController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fp/controller/FishPassageController.java @@ -46,6 +46,13 @@ public class FishPassageController { return ResponseResult.successData(fpRunService.processQgcFpssrlQueryKendoList(dataSourceRequest)); } + @PostMapping("/query/qgc/GetKendoListCustAI") + @Operation(summary = "全过程过鱼自动(AI设备)与人工监测数据查询") + public ResponseResult getQgcFpssrlAiRQueryKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(fpRunService.processQgcFpssrlAiRQueryKendoList(dataSourceRequest)); + } + + @PostMapping("/fpssTable/qgc/GetKendoListCust") @Operation(summary = "过鱼设施监测数据查询") public ResponseResult getQgcFpssTableKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/FpRunService.java b/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/FpRunService.java index a3706df7..42b1054d 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/FpRunService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/FpRunService.java @@ -23,6 +23,8 @@ public interface FpRunService { DataSourceResult processQgcFpssrlQueryKendoList(DataSourceRequest dataSourceRequest); + DataSourceResult processQgcFpssrlAiRQueryKendoList(DataSourceRequest dataSourceRequest); + DataSourceResult processQgcFpssTableKendoList(DataSourceRequest dataSourceRequest); DataSourceResult getAnalysisData(DataSourceRequest dataSourceRequest); diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/impl/FpRunServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/impl/FpRunServiceImpl.java index cdaec94d..1cf4c621 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/impl/FpRunServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/impl/FpRunServiceImpl.java @@ -220,6 +220,15 @@ public class FpRunServiceImpl implements FpRunService { return queryQgcFpssrlGroupList(dataSourceRequest, loadOptions); } + @Override + public DataSourceResult processQgcFpssrlAiRQueryKendoList(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + if (CollUtil.isEmpty(dataSourceRequest == null ? null : dataSourceRequest.getGroup())) { + return queryQgcFpssrlAiRDetailList(dataSourceRequest, loadOptions); + } + return queryQgcFpssrlAiRGroupList(dataSourceRequest, loadOptions); + } + @Override public DataSourceResult processQgcFpssTableKendoList(DataSourceRequest dataSourceRequest) { DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); @@ -1211,6 +1220,33 @@ public class FpRunServiceImpl implements FpRunService { return result; } + private DataSourceResult queryQgcFpssrlAiRDetailList(DataSourceRequest dataSourceRequest, + DataSourceLoadOptionsBase loadOptions) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append(buildQgcFpssrlDetailSelectSql(dataSourceRequest == null ? null : dataSourceRequest.getSelect())) + .append(" FROM (") + .append(buildQgcFpssrlAiRCoreSql()) + .append(") t WHERE 1 = 1 "); + + Map paramMap = new HashMap<>(); + String filterSql = buildQgcFpssrlFilterCondition(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, new int[]{0}); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + sql.append(buildQgcFpssrlOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort())); + + Page page = loadOptions == null ? null : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + List list = microservicDynamicSQLMapper.pageAllListWithResultType( + page, sql.toString(), paramMap, FpFpssrlQueryVo.class + ); + DataSourceResult result = new DataSourceResult<>(); + result.setData(list); + result.setTotal(page != null ? page.getTotal() : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + private DataSourceResult queryQgcFpssrlGroupList(DataSourceRequest dataSourceRequest, DataSourceLoadOptionsBase loadOptions) { List groups = dataSourceRequest.getGroup(); @@ -1284,6 +1320,79 @@ public class FpRunServiceImpl implements FpRunService { return result; } + private DataSourceResult queryQgcFpssrlAiRGroupList(DataSourceRequest dataSourceRequest, + DataSourceLoadOptionsBase loadOptions) { + List groups = dataSourceRequest.getGroup(); + GroupingInfo[] groupInfos = loadOptions == null ? new GroupingInfo[0] : loadOptions.getGroup(); + + StringBuilder sql = new StringBuilder("SELECT "); + List selectItems = new ArrayList<>(); + for (DataSourceRequest.GroupDescriptor descriptor : groups) { + if (descriptor == null || StrUtil.isBlank(descriptor.getField())) { + continue; + } + String column = mapQgcFpssrlColumn(descriptor.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + selectItems.add(column + " AS " + descriptor.getField().toUpperCase()); + selectItems.add("COUNT(*) AS COUNT_" + descriptor.getField().toUpperCase()); + if (CollUtil.isNotEmpty(descriptor.getAggregates())) { + for (DataSourceRequest.AggregateDescriptor aggregate : descriptor.getAggregates()) { + String aggregateColumn = mapQgcFpssrlColumn(aggregate.getField()); + if (StrUtil.isBlank(aggregateColumn) || StrUtil.isBlank(aggregate.getAggregate())) { + continue; + } + String aggregateSql = buildAggregateSql(aggregate.getAggregate(), aggregateColumn, aggregate.getField()); + if (StrUtil.isNotBlank(aggregateSql)) { + selectItems.add(aggregateSql); + } + } + } + } + if (selectItems.isEmpty()) { + selectItems.add("t.STCD AS STCD"); + selectItems.add("COUNT(*) AS COUNT_STCD"); + } + + sql.append(String.join(", ", selectItems)) + .append(" FROM (") + .append(buildQgcFpssrlCoreSql()) + .append(") t WHERE 1 = 1 "); + + Map paramMap = new HashMap<>(); + String filterSql = buildQgcFpssrlFilterCondition(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, new int[]{0}); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + + List groupByColumns = new ArrayList<>(); + for (DataSourceRequest.GroupDescriptor descriptor : groups) { + if (descriptor == null || StrUtil.isBlank(descriptor.getField())) { + continue; + } + String column = mapQgcFpssrlColumn(descriptor.getField()); + if (StrUtil.isNotBlank(column)) { + groupByColumns.add(column); + } + } + if (!groupByColumns.isEmpty()) { + sql.append(" GROUP BY ").append(String.join(", ", groupByColumns)).append(" "); + } + sql.append(buildQgcFpssrlGroupOrderBySql(groups)); + + List> rows = microservicDynamicSQLMapper.pageAllList(null, sql.toString(), paramMap); + DataSourceResult result = new DataSourceResult<>(); + if (Boolean.TRUE.equals(dataSourceRequest.getGroupResultFlat())) { + result.setData((List) (List) new GroupHelper().faltGroup(rows, Arrays.asList(groupInfos))); + } else { + result.setData((List) (List) new GroupHelper().group(rows, Arrays.asList(groupInfos))); + } + result.setTotal(0L); + result.setAggregates(new HashMap<>()); + return result; + } + private DataSourceResult queryQgcSdfpssrGroupList(DataSourceRequest dataSourceRequest, DataSourceLoadOptionsBase loadOptions) { List groups = dataSourceRequest.getGroup(); @@ -1566,6 +1675,161 @@ public class FpRunServiceImpl implements FpRunService { ") src"; } + + private String buildQgcFpssrlAiRCoreSql() { + return "SELECT " + + "src.ID AS id, " + + "src.STCD AS stcd, " + + "src.STNM AS stnm, " + + "src.BASEID AS baseId, " + + "src.BASENAME AS baseName, " + + "src.RSTCD AS rstcd, " + + "src.ENNM AS ennm, " + + "src.HBRVCD AS hbrvcd, " + + "src.BASESTEPSORT AS baseStepSort, " + + "src.RVCDSTEPSORT AS rvcdStepSort, " + + "src.SITESTEPSORT AS siteStepSort, " + + "src.RSTCDSTEPSORT AS rstcdStepSort, " + + "src.TM AS tm, " + + "src.YR AS yr, " + + "src.FTP AS ftp, " + + "src.FISHID AS fishId, " + + "src.FSZ AS fsz, " + + "src.LENGTH AS length, " + + "src.WIDTH AS width, " + + "src.FISHSPEED AS fishspeed, " + + "src.DIRECTION AS direction, " + + "src.TEMPERATURE AS temperature, " + + "src.SPEED AS speed, " + + "src.CHANNELNO AS channelno, " + + "src.FCNT AS fcnt, " + + "src.FIRSTIMGURL AS firstimgurl, " + + "src.VIDEOURL AS videourl, " + + "src.MWAY AS mway, " + + "src.STRDT AS strdt, " + + "src.ENDDT AS enddt, " + + "src.STCODE AS stCode, " + + "src.STNAME AS stName " + + "FROM ( " + + " SELECT t.ID AS ID, " + + " t.STCD AS STCD, " + + " fp.STNM AS STNM, " + + " eng.BASE_ID AS BASEID, " + + " hb.BASENAME AS BASENAME, " + + " fp.RSTCD AS RSTCD, " + + " eng.ENNM AS ENNM, " + + " eng.HBRVCD AS HBRVCD, " + + " NVL(hb.ORDER_INDEX, 999999) AS BASESTEPSORT, " + + " NVL(hbrv.ORDER_INDEX, 999999) AS RVCDSTEPSORT, " + + " NVL(fp.ORDER_INDEX, 999999) AS SITESTEPSORT, " + + " NVL(eng.ORDER_INDEX, 999999) AS RSTCDSTEPSORT, " + + " t.TM AS TM, " + + " TO_CHAR(t.TM, 'YYYY') AS YR, " + + " COALESCE(fishRv.NAME, relRv.FISH_NAME, fishZy.NAME, relZy.FISH_NAME, fishDirect.NAME, t.FTP) AS FTP, " + + " t.FTP AS FISHID, " + + " t.FSZ AS FSZ, " + + " TO_CHAR(t.LENGTH) AS LENGTH, " + + " TO_CHAR(t.WIDTH) AS WIDTH, " + + " TO_CHAR(t.FISHSPEED) AS FISHSPEED, " + + " TO_CHAR(t.DIRECTION) AS DIRECTION, " + + " TO_CHAR(t.TEMPERATURE) AS TEMPERATURE, " + + " TO_CHAR(t.SPEED) AS SPEED, " + + " t.CHANNELNO AS CHANNELNO, " + + " TO_CHAR(t.FCNT) AS FCNT, " + + " t.FIRSTIMGURL AS FIRSTIMGURL, " + + " t.VIDEOURL AS VIDEOURL, " + + " 2 AS MWAY, " + + " CAST(NULL AS DATE) AS STRDT, " + + " CAST(NULL AS DATE) AS ENDDT, " + + " fp.STTP AS STCODE, " + + " sttp.STTP_NAME AS STNAME " + + " FROM SD_FPSSRL_AI_R t " + + " INNER JOIN V_MS_STBPRP_T fp ON fp.STCD = t.STCD " + + " LEFT JOIN SD_STTP_B sttp ON sttp.STTP_CODE = fp.STTP AND NVL(sttp.IS_DELETED, 0) = 0 AND NVL(sttp.ENABLE, 1) = 1 " + + " LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = fp.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " + + " LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eng.BASE_ID AND NVL(hb.IS_DELETED, 0) = 0 " + + " LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = eng.HBRVCD " + + " AND hbrv.BASEID = eng.BASE_ID " + + " AND NVL(hbrv.IS_DELETED, 0) = 0 " + + " AND NVL(hbrv.ENABLED, 1) = 1 " + + " LEFT JOIN SD_FISHDICTORY_RLTN_B relRv ON relRv.FISH_ID = t.FTP " + + " AND relRv.RVCD = eng.HBRVCD " + + " AND NVL(relRv.IS_DELETED, 0) = 0 " + + " LEFT JOIN SD_FISHDICTORY_B fishRv ON fishRv.ID = relRv.ZY_FISH_ID " + + " AND NVL(fishRv.IS_DELETED, 0) = 0 " + + " AND NVL(fishRv.ENABLE, 1) = 1 " + + " LEFT JOIN SD_FISHDICTORY_RLTN_B relZy ON relZy.FISH_ID = t.FTP " + + " AND relZy.RVCD = 'ZY' " + + " AND NVL(relZy.IS_DELETED, 0) = 0 " + + " LEFT JOIN SD_FISHDICTORY_B fishZy ON fishZy.ID = relZy.ZY_FISH_ID " + + " AND NVL(fishZy.IS_DELETED, 0) = 0 " + + " AND NVL(fishZy.ENABLE, 1) = 1 " + + " LEFT JOIN SD_FISHDICTORY_B fishDirect ON fishDirect.ID = t.FTP " + + " AND NVL(fishDirect.IS_DELETED, 0) = 0 " + + " AND NVL(fishDirect.ENABLE, 1) = 1 " + + " WHERE NVL(t.IS_DELETED, 0) = 0 " + + " UNION ALL " + + " SELECT t.ID AS ID, " + + " t.STCD AS STCD, " + + " fp.STNM AS STNM, " + + " eng.BASE_ID AS BASEID, " + + " hb.BASENAME AS BASENAME, " + + " fp.RSTCD AS RSTCD, " + + " eng.ENNM AS ENNM, " + + " eng.HBRVCD AS HBRVCD, " + + " NVL(hb.ORDER_INDEX, 999999) AS BASESTEPSORT, " + + " NVL(hbrv.ORDER_INDEX, 999999) AS RVCDSTEPSORT, " + + " NVL(fp.ORDER_INDEX, 999999) AS SITESTEPSORT, " + + " NVL(eng.ORDER_INDEX, 999999) AS RSTCDSTEPSORT, " + + " t.STRDT AS TM, " + + " TO_CHAR(t.STRDT, 'YYYY') AS YR, " + + " COALESCE(fishRv.NAME, relRv.FISH_NAME, fishZy.NAME, relZy.FISH_NAME, fishDirect.NAME, t.FTP) AS FTP, " + + " t.FTP AS FISHID, " + + " t.FSZ AS FSZ, " + + " CAST(NULL AS VARCHAR2(50)) AS LENGTH, " + + " CAST(NULL AS VARCHAR2(50)) AS WIDTH, " + + " CAST(NULL AS VARCHAR2(50)) AS FISHSPEED, " + + " TO_CHAR(t.DIRECTION) AS DIRECTION, " + + " CAST(NULL AS VARCHAR2(50)) AS TEMPERATURE, " + + " CAST(NULL AS VARCHAR2(50)) AS SPEED, " + + " CAST(NULL AS VARCHAR2(100)) AS CHANNELNO, " + + " TO_CHAR(t.FCNT) AS FCNT, " + + " t.PICPTH AS FIRSTIMGURL, " + + " t.VDPTH AS VIDEOURL, " + + " 1 AS MWAY, " + + " t.STRDT AS STRDT, " + + " t.ENDDT AS ENDDT, " + + " fp.STTP AS STCODE, " + + " sttp.STTP_NAME AS STNAME " + + " FROM SD_FPSS_R t " + + " INNER JOIN SD_FPSS_B_H fp ON fp.STCD = t.STCD " + + " LEFT JOIN SD_STTP_B sttp ON sttp.STTP_CODE = fp.STTP AND NVL(sttp.IS_DELETED, 0) = 0 AND NVL(sttp.ENABLE, 1) = 1 " + + " LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = fp.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " + + " LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eng.BASE_ID AND NVL(hb.IS_DELETED, 0) = 0 " + + " LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = eng.HBRVCD " + + " AND hbrv.BASEID = eng.BASE_ID " + + " AND NVL(hbrv.IS_DELETED, 0) = 0 " + + " AND NVL(hbrv.ENABLED, 1) = 1 " + + " LEFT JOIN SD_FISHDICTORY_RLTN_B relRv ON relRv.FISH_ID = t.FTP " + + " AND relRv.RVCD = eng.HBRVCD " + + " AND NVL(relRv.IS_DELETED, 0) = 0 " + + " LEFT JOIN SD_FISHDICTORY_B fishRv ON fishRv.ID = relRv.ZY_FISH_ID " + + " AND NVL(fishRv.IS_DELETED, 0) = 0 " + + " AND NVL(fishRv.ENABLE, 1) = 1 " + + " LEFT JOIN SD_FISHDICTORY_RLTN_B relZy ON relZy.FISH_ID = t.FTP " + + " AND relZy.RVCD = 'ZY' " + + " AND NVL(relZy.IS_DELETED, 0) = 0 " + + " LEFT JOIN SD_FISHDICTORY_B fishZy ON fishZy.ID = relZy.ZY_FISH_ID " + + " AND NVL(fishZy.IS_DELETED, 0) = 0 " + + " AND NVL(fishZy.ENABLE, 1) = 1 " + + " LEFT JOIN SD_FISHDICTORY_B fishDirect ON fishDirect.ID = t.FTP " + + " AND NVL(fishDirect.IS_DELETED, 0) = 0 " + + " AND NVL(fishDirect.ENABLE, 1) = 1 " + + " WHERE NVL(t.IS_DELETED, 0) = 0 " + +// " AND (t.TASK_STATUS = 'Approved' OR t.TASK_STATUS IS NULL) " + + ") src"; + } + private String buildQgcSdfpssrDetailSelectSql(List selectFields) { Map selectMap = new LinkedHashMap<>(); selectMap.put("stcd", "t.stcd AS stcd"); diff --git a/backend/src/main/resources/application-prod.yml b/backend/src/main/resources/application-prod.yml index a87887d5..98127603 100644 --- a/backend/src/main/resources/application-prod.yml +++ b/backend/src/main/resources/application-prod.yml @@ -197,7 +197,7 @@ logging: level: root: info com.yfd.platform: info - com.yfd.platform.common.MicroservicDynamicSQLMapper: debug + com.yfd.platform.common.MicroservicDynamicSQLMapper: info # ... existing code ... # com.yfd.platform.*.mapper: trace From 7ba5c1b1db83594b34802a55d8f277ec29c025e5 Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 3 Aug 2026 10:05:56 +0800 Subject: [PATCH 02/10] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../qgc_base/mapper/SdFpssBHMapper.java | 3 +- .../system/controller/LoginController.java | 13 +++- .../controller/SmsVerifyCodeController.java | 15 +++- .../system/controller/SysMenuController.java | 2 +- .../system/controller/UserController.java | 57 +++++++++++++- .../yfd/platform/system/domain/LoginUser.java | 29 ++++++- .../platform/system/domain/SysUserTenant.java | 30 ++++++++ .../platform/system/mapper/SysMenuMapper.java | 2 +- .../system/mapper/SysUserTenantMapper.java | 47 ++++++++++++ .../platform/system/service/IUserService.java | 19 +++++ .../service/impl/AdminAuthServiceImpl.java | 16 ++-- .../impl/SmsVerifyCodeServiceImpl.java | 4 +- .../service/impl/UserDetailsServiceImpl.java | 70 +++++++++++++---- .../system/service/impl/UserServiceImpl.java | 75 +++++++++++++++++-- .../com/yfd/platform/utils/SecurityUtils.java | 37 +++++++++ .../resources/mapper/system/SysMenuMapper.xml | 7 +- .../resources/mapper/system/SysUserMapper.xml | 3 +- .../mapper/system/SysUserTenantMapper.xml | 57 ++++++++++++++ 18 files changed, 439 insertions(+), 47 deletions(-) create mode 100644 backend/src/main/java/com/yfd/platform/system/domain/SysUserTenant.java create mode 100644 backend/src/main/java/com/yfd/platform/system/mapper/SysUserTenantMapper.java create mode 100644 backend/src/main/resources/mapper/system/SysUserTenantMapper.xml diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/mapper/SdFpssBHMapper.java b/backend/src/main/java/com/yfd/platform/qgc_base/mapper/SdFpssBHMapper.java index e12224c6..941f39ee 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/mapper/SdFpssBHMapper.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/mapper/SdFpssBHMapper.java @@ -17,7 +17,8 @@ public interface SdFpssBHMapper extends BaseMapper { "WHERE 1=1 " + " AND E.BASE_ID = #{baseId} " + " AND F.RSTCD = #{rstcd} " + - " AND E.REACHCD = #{rvcd} " + + " AND E.RVCD = #{rvcd} " + + " AND E.REACHCD = #{reachcd} " + // " AND F.RSTCD = #{rstcd} " + " AND F.STNM LIKE '%' || #{stnm} || '%' " + "ORDER BY F.ORDER_INDEX DESC" + diff --git a/backend/src/main/java/com/yfd/platform/system/controller/LoginController.java b/backend/src/main/java/com/yfd/platform/system/controller/LoginController.java index 82ed2e6f..d341fcbd 100644 --- a/backend/src/main/java/com/yfd/platform/system/controller/LoginController.java +++ b/backend/src/main/java/com/yfd/platform/system/controller/LoginController.java @@ -37,6 +37,7 @@ import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletRequest; import java.sql.Timestamp; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -100,8 +101,12 @@ public class LoginController { Integer status = loginUser.getUser().getStatus(); String regStatus = loginUser.getUser().getRegStatus(); - if (StrUtil.isNotBlank(tenantId)&&!tenantId.equals(loginUser.getUser().getTenantId())) { - return ResponseResult.error("账号不存在或密码错误"); + // 多门户:验证用户是否有权限访问指定门户 + if (!loginUser.isSuperAdmin() && StrUtil.isNotBlank(tenantId)) { + List accessibleIds = loginUser.getAccessibleTenantIds(); + if (accessibleIds == null || !accessibleIds.contains(tenantId)) { + return ResponseResult.error("账号不存在或密码错误"); + } } if (StrUtil.isNotBlank(regStatus)&&"REJECTED".equals(regStatus)) { @@ -149,6 +154,10 @@ public class LoginController { String token = JWTUtil.createToken(map, "12345678".getBytes()); map.put("token", token); + // 返回可访问门户列表和超级管理员标识 + map.put("accessibleTenantIds", loginUser.getAccessibleTenantIds()); + map.put("superAdmin", loginUser.isSuperAdmin()); + map.put("currentTenantId", tenantId); //把完整的用户信息存入到HuTool缓存中,userId作为key String jsonStr = JSONUtil.toJsonStr(loginUser); webConfig.loginuserCache().put("login:" + userId, jsonStr); diff --git a/backend/src/main/java/com/yfd/platform/system/controller/SmsVerifyCodeController.java b/backend/src/main/java/com/yfd/platform/system/controller/SmsVerifyCodeController.java index 5bf84847..8680affe 100644 --- a/backend/src/main/java/com/yfd/platform/system/controller/SmsVerifyCodeController.java +++ b/backend/src/main/java/com/yfd/platform/system/controller/SmsVerifyCodeController.java @@ -11,6 +11,7 @@ import com.yfd.platform.qgc_base.service.ISdEngInfoBHService; import com.yfd.platform.qgc_base.service.ISdHbrvDicService; import com.yfd.platform.system.domain.*; import com.yfd.platform.system.mapper.SysMenuMapper; +import com.yfd.platform.system.mapper.SysUserTenantMapper; import com.yfd.platform.system.service.ISmsVerifyCodeService; import com.yfd.platform.system.service.ISysLogService; import com.yfd.platform.system.service.IUserService; @@ -66,6 +67,10 @@ public class SmsVerifyCodeController { @Resource private ISdEngInfoBHService engInfoBHService; + @Resource + private SysUserTenantMapper sysUserTenantMapper; + + @Resource private ISdHbrvDicService hbrvDicService; @@ -441,8 +446,14 @@ public class SmsVerifyCodeController { loginUser.setUser(user); loginUser.setUsername(user.getUsername()); //Todo 根据用户查询权限信息 添加到LoginUser中 - List permissions = - sysMenuMapper.selectPermsByUserId(user.getId()); + // 加载权限:超级管理员加载全部权限,普通用户按门户过滤 + boolean isSuperAdmin = userService.isSuperAdmin(user.getId()); + List permissions; + if (isSuperAdmin) { + permissions = sysMenuMapper.selectPermsByUserId(user.getId(), null); + } else { + permissions = sysMenuMapper.selectPermsByUserId(user.getId(), tenantId); + } loginUser.setPermissions( permissions); HttpServletRequest request = RequestHolder.getHttpServletRequest(); SysLog sysLog = new SysLog(); diff --git a/backend/src/main/java/com/yfd/platform/system/controller/SysMenuController.java b/backend/src/main/java/com/yfd/platform/system/controller/SysMenuController.java index bb4f90c6..4ffe9fed 100644 --- a/backend/src/main/java/com/yfd/platform/system/controller/SysMenuController.java +++ b/backend/src/main/java/com/yfd/platform/system/controller/SysMenuController.java @@ -115,7 +115,7 @@ public class SysMenuController { if (0 != userInfo.getUsertype()) { id = userInfo.getId(); } - return sysMenuService.getMenuTree(id, StrUtil.isNotBlank(tenantId) ? StrUtil.trimToNull(tenantId) : userInfo.getTenantId()); + return sysMenuService.getMenuTree(id, tenantId); } /*********************************** diff --git a/backend/src/main/java/com/yfd/platform/system/controller/UserController.java b/backend/src/main/java/com/yfd/platform/system/controller/UserController.java index ce4945b4..4e0838cc 100644 --- a/backend/src/main/java/com/yfd/platform/system/controller/UserController.java +++ b/backend/src/main/java/com/yfd/platform/system/controller/UserController.java @@ -17,6 +17,7 @@ import org.springframework.web.multipart.MultipartFile; import jakarta.annotation.Resource; import java.sql.Timestamp; +import java.util.List; import java.util.Map; /** @@ -60,7 +61,7 @@ public class UserController { if (StrUtil.isEmpty(user.getId())) { return ResponseResult.error("没有用户ID"); } - user.setTenantId(StrUtil.trimToNull(tenantId)); +// user.setTenantId(StrUtil.trimToNull(tenantId)); //填写 当前用户名称 user.setLastmodifier(userService.getUsername()); //填写 当前日期 @@ -115,8 +116,8 @@ public class UserController { public ResponseResult queryUserById(String id, @RequestHeader(value = "Tenant_id", required = false) String tenantId) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(SysUser::getId, id) - .eq(StrUtil.isNotBlank(tenantId), SysUser::getTenantId, StrUtil.trim(tenantId)); + queryWrapper.eq(SysUser::getId, id); +// .eq(StrUtil.isNotBlank(tenantId), SysUser::getTenantId, StrUtil.trim(tenantId)); SysUser user = userService.getOne(queryWrapper); return ResponseResult.successData(user); } @@ -251,4 +252,54 @@ public class UserController { Page result = userService.queryPendingAuditUsers(page, name, regStatus, StrUtil.trimToNull(tenantId)); return ResponseResult.successData(result); } + + // ==================== 多门户管理 ==================== + + /*********************************** + * 用途说明:为用户分配门户 + * 参数说明 userId 用户ID, tenantIds 门户ID列表(逗号分隔) + ************************************/ + @Log(module = "系统用户", value = "分配门户") + @PostMapping("/assignTenant") + @Operation(summary = "为用户分配门户") + @ResponseBody + public ResponseResult assignTenant(String userId, String tenantIds) { + if (StrUtil.isBlank(userId) || StrUtil.isBlank(tenantIds)) { + return ResponseResult.error("用户ID和门户ID不能为空"); + } + List tenantIdList = List.of(tenantIds.split(",")); + userService.assignTenantsToUser(userId, tenantIdList); + return ResponseResult.success(); + } + + /*********************************** + * 用途说明:移除用户的门户关联 + * 参数说明 userId 用户ID, tenantId 门户ID + ************************************/ + @Log(module = "系统用户", value = "移除门户") + @PostMapping("/removeTenant") + @Operation(summary = "移除用户的门户关联") + @ResponseBody + public ResponseResult removeTenant(String userId, String tenantId) { + if (StrUtil.isBlank(userId) || StrUtil.isBlank(tenantId)) { + return ResponseResult.error("用户ID和门户ID不能为空"); + } + userService.removeTenantFromUser(userId, tenantId); + return ResponseResult.success(); + } + + /*********************************** + * 用途说明:获取用户关联的门户列表 + * 参数说明 userId 用户ID + ************************************/ + @GetMapping("/getUserTenants") + @Operation(summary = "获取用户关联的门户列表") + @ResponseBody + public ResponseResult getUserTenants(String userId) { + if (StrUtil.isBlank(userId)) { + return ResponseResult.error("用户ID不能为空"); + } + List tenants = userService.getUserTenants(userId); + return ResponseResult.successData(tenants); + } } diff --git a/backend/src/main/java/com/yfd/platform/system/domain/LoginUser.java b/backend/src/main/java/com/yfd/platform/system/domain/LoginUser.java index baf4258a..95c37a01 100644 --- a/backend/src/main/java/com/yfd/platform/system/domain/LoginUser.java +++ b/backend/src/main/java/com/yfd/platform/system/domain/LoginUser.java @@ -22,19 +22,44 @@ public class LoginUser implements UserDetails { private String username; - private List permissions=new ArrayList<>(); + private List permissions = new ArrayList<>(); + + /** + * 当前登录的门户ID + */ + private String currentTenantId; + + /** + * 用户可访问的门户ID列表(用于门户切换) + */ + private List accessibleTenantIds; + + /** + * 是否超级管理员(LEVEL=1) + */ + private boolean superAdmin; /** * 自定义构造函数(如果需要特殊逻辑) */ public LoginUser(SysUser user, List permissions) { this.user = user; - // 4. 增加非空判断,确保 permissions 永远不为 null if (permissions != null) { this.permissions = permissions; } } + public LoginUser(SysUser user, List permissions, + String currentTenantId, List accessibleTenantIds, boolean superAdmin) { + this.user = user; + if (permissions != null) { + this.permissions = permissions; + } + this.currentTenantId = currentTenantId; + this.accessibleTenantIds = accessibleTenantIds; + this.superAdmin = superAdmin; + } + @JSONField(serialize = false) private List authorities; diff --git a/backend/src/main/java/com/yfd/platform/system/domain/SysUserTenant.java b/backend/src/main/java/com/yfd/platform/system/domain/SysUserTenant.java new file mode 100644 index 00000000..b5b8cfac --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/system/domain/SysUserTenant.java @@ -0,0 +1,30 @@ +package com.yfd.platform.system.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 用户-门户关联表 + *

+ */ +@Data +@TableName("SYS_USER_TENANT") +public class SysUserTenant implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 主键 */ + @TableId(type = IdType.ASSIGN_UUID) + private String id; + + /** 用户ID */ + private String userId; + + /** 门户ID */ + private String tenantId; +} diff --git a/backend/src/main/java/com/yfd/platform/system/mapper/SysMenuMapper.java b/backend/src/main/java/com/yfd/platform/system/mapper/SysMenuMapper.java index 9ea863fa..ab657e45 100644 --- a/backend/src/main/java/com/yfd/platform/system/mapper/SysMenuMapper.java +++ b/backend/src/main/java/com/yfd/platform/system/mapper/SysMenuMapper.java @@ -44,7 +44,7 @@ public interface SysMenuMapper extends BaseMapper { @Param("tenantId") String tenantId); - List selectPermsByUserId(String userId); + List selectPermsByUserId(@Param("userId") String userId, @Param("tenantId") String tenantId); //List selectMenuByUserId(String userId); List selectMenuByUserId(@Param("userId") String userId, @Param("tenantId") String tenantId); diff --git a/backend/src/main/java/com/yfd/platform/system/mapper/SysUserTenantMapper.java b/backend/src/main/java/com/yfd/platform/system/mapper/SysUserTenantMapper.java new file mode 100644 index 00000000..f7961522 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/system/mapper/SysUserTenantMapper.java @@ -0,0 +1,47 @@ +package com.yfd.platform.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.yfd.platform.system.domain.SysUserTenant; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 用户-门户关联表 Mapper 接口 + *

+ */ +@Mapper +public interface SysUserTenantMapper extends BaseMapper { + + /** + * 查询用户可访问的门户ID列表 + */ + List getTenantIdsByUserId(@Param("userId") String userId); + + /** + * 批量删除用户-门户关联 + */ + int deleteByUserId(@Param("userId") String userId); + + /** + * 批量新增用户-门户关联 + */ + int batchInsert(@Param("userId") String userId, @Param("tenantIds") List tenantIds); + + /** + * 查询某门户下的所有用户ID + */ + List getUserIdsByTenantId(@Param("tenantId") String tenantId); + + /** + * 删除指定用户和指定门户的关联 + */ + int deleteByUserIdAndTenantId(@Param("userId") String userId, @Param("tenantId") String tenantId); + + /** + * 批量查询用户-门户关联(用于用户列表展示) + */ + List> getTenantIdsByUserIds(@Param("userIds") List userIds); +} diff --git a/backend/src/main/java/com/yfd/platform/system/service/IUserService.java b/backend/src/main/java/com/yfd/platform/system/service/IUserService.java index 863fa04c..99d8c4f3 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/IUserService.java +++ b/backend/src/main/java/com/yfd/platform/system/service/IUserService.java @@ -184,4 +184,23 @@ public interface IUserService extends IService { Page queryPendingAuditUsers(Page page, String name, String regStatus, String tenantId); List queryUsersList(String name, String tenantId); + + // ==================== 多门户管理 ==================== + + /** + * 为用户分配门户 + */ + void assignTenantsToUser(String userId, List tenantIds); + + /** + * 移除用户的某个门户关联 + */ + void removeTenantFromUser(String userId, String tenantId); + + /** + * 获取用户关联的门户ID列表 + */ + List getUserTenants(String userId); + + boolean isSuperAdmin(String userId); } diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/AdminAuthServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/AdminAuthServiceImpl.java index 046de510..3b6579f9 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/AdminAuthServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/AdminAuthServiceImpl.java @@ -38,17 +38,17 @@ public class AdminAuthServiceImpl implements IAdminAuthService { public List getSuperAdminUsernames() { // 获取当前请求 - ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); +// ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(SysUser::getUsertype, 0).select(SysUser::getUsername); //根据用户名称或手机号查询用户信息 - if (attributes != null) { - HttpServletRequest request = attributes.getRequest(); - String tenantId = request.getHeader("Tenant_Id"); - if(StrUtil.isNotBlank(tenantId)){ - queryWrapper.eq(SysUser::getTenantId, tenantId); - } - } +// if (attributes != null) { +// HttpServletRequest request = attributes.getRequest(); +// String tenantId = request.getHeader("Tenant_Id"); +// if(StrUtil.isNotBlank(tenantId)){ +// queryWrapper.eq(SysUser::getTenantId, tenantId); +// } +// } List userList = userMapper.selectList(queryWrapper); if (CollUtil.isEmpty(userList)) { return new ArrayList<>(); diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/SmsVerifyCodeServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/SmsVerifyCodeServiceImpl.java index 4331f80a..390ada64 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/SmsVerifyCodeServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/SmsVerifyCodeServiceImpl.java @@ -48,7 +48,7 @@ public class SmsVerifyCodeServiceImpl extends ServiceImpl queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(SmsVerifyCode::getPhone, phone) .eq(SmsVerifyCode::getType, type) - .gt(SmsVerifyCode::getTenantId, tenantId) + .eq(SmsVerifyCode::getTenantId, tenantId) .eq(SmsVerifyCode::getStatus, SmsVerifyCode.STATUS_UNUSED); this.remove(queryWrapper); @@ -161,7 +161,7 @@ public class SmsVerifyCodeServiceImpl extends ServiceImpl ids = userIds.stream().distinct().toList(); List sysUsers = sysUserMapper.selectList(new LambdaQueryWrapper().in(SysUser::getId, ids) - .eq(SysUser::getRegStatus, "APPROVED").eq(SysUser::getTenantId, tenantId).eq(SysUser::getStatus,1).select(SysUser::getPhone)); + .eq(SysUser::getRegStatus, "APPROVED").eq(SysUser::getStatus,1).select(SysUser::getPhone)); if (sysUsers.isEmpty()) { log.warn("催促短信发送失败:未找到有效的手机号,userIds: {}", ids); diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/UserDetailsServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/UserDetailsServiceImpl.java index b860f0bd..c1c9c6d6 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/UserDetailsServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/UserDetailsServiceImpl.java @@ -3,12 +3,12 @@ package com.yfd.platform.system.service.impl; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.yfd.platform.datasource.DataSource; -import com.yfd.platform.datasource.DataSourceKeys; import com.yfd.platform.datasource.TargetDataSource; import com.yfd.platform.system.domain.LoginUser; import com.yfd.platform.system.domain.SysUser; import com.yfd.platform.system.mapper.SysMenuMapper; +import com.yfd.platform.system.mapper.SysUserMapper; +import com.yfd.platform.system.mapper.SysUserTenantMapper; import com.yfd.platform.system.service.IUserService; import jakarta.servlet.http.HttpServletRequest; import org.springframework.security.core.userdetails.UserDetails; @@ -20,11 +20,14 @@ import jakarta.annotation.Resource; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; +import java.util.ArrayList; import java.util.List; /** *

* 用户服务实现类 继承UserDetailsService 实现接口 + * 支持多门户登录:用户可关联多个门户,登录时选择其中一个门户 + * 超级管理员(LEVEL=1)拥有跨所有门户的权限 *

* * @author zhengsl @@ -39,31 +42,68 @@ public class UserDetailsServiceImpl implements UserDetailsService { @Resource private SysMenuMapper sysMenuMapper; + @Resource + private SysUserTenantMapper sysUserTenantMapper; + + @Resource + private SysUserMapper sysUserMapper; + @Override @TargetDataSource() public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // 获取当前请求 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); - //根据用户名称或手机号查询用户信息 + + // 根据用户名称或手机号查询用户信息(不加tenantId过滤,支持跨门户登录) QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.and(wrapper -> wrapper.eq("username", username).or().eq("phone", username)); - if (attributes != null) { - HttpServletRequest request = attributes.getRequest(); - String tenantId = request.getHeader("Tenant_Id"); - if(StrUtil.isNotBlank(tenantId)){ - queryWrapper.eq("TENANT_ID", tenantId); - } - } SysUser user = userService.getOne(queryWrapper); if (ObjectUtil.isEmpty(user)) { throw new RuntimeException("用户账号不存在!"); } - //Todo 根据用户查询权限信息 添加到LoginUser中 - List permissions = - sysMenuMapper.selectPermsByUserId(user.getId()); - //封装成UserDetails对象返回 - return new LoginUser(user,permissions); + // 获取请求中的门户ID + String tenantId = null; + if (attributes != null) { + HttpServletRequest request = attributes.getRequest(); + tenantId = request.getHeader("Tenant_Id"); + } + + // 判断是否为超级管理员(LEVEL=1) + boolean isSuperAdmin = isSuperAdmin(user.getId()); + + // 查询用户可访问的门户列表 + List accessibleTenantIds = sysUserTenantMapper.getTenantIdsByUserId(user.getId()); + + // 非超级管理员必须指定门户,且必须在可访问列表中 + if (!isSuperAdmin) { + if (StrUtil.isBlank(tenantId)) { + throw new RuntimeException("普通用户登录必须指定门户(Tenant_Id)"); + } + if (accessibleTenantIds == null || !accessibleTenantIds.contains(tenantId)) { + throw new RuntimeException("用户无权限访问该门户"); + } + } + + // 加载权限:超级管理员加载全部权限,普通用户按门户过滤 + List permissions; + if (isSuperAdmin) { + permissions = sysMenuMapper.selectPermsByUserId(user.getId(), null); + } else { + permissions = sysMenuMapper.selectPermsByUserId(user.getId(), tenantId); + } + + // 封装成UserDetails对象返回,包含当前门户和可访问门户列表 + return new LoginUser(user, permissions, tenantId, accessibleTenantIds, isSuperAdmin); + } + + /** + * 判断用户是否为超级管理员(拥有LEVEL=1的角色) + */ + private boolean isSuperAdmin(String userId) { + String maxLevel = sysUserMapper.getMaxLevel(userId); + return "1".equals(maxLevel); } } + diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java index a50a6d83..0226eea6 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java @@ -22,6 +22,7 @@ import com.yfd.platform.system.domain.SysRole; import com.yfd.platform.system.domain.SysUser; import com.yfd.platform.system.mapper.SysRoleMapper; import com.yfd.platform.system.mapper.SysUserMapper; +import com.yfd.platform.system.mapper.SysUserTenantMapper; import com.yfd.platform.system.service.IAdminAuthService; import com.yfd.platform.system.service.IUserService; import com.yfd.platform.utils.FileUtil; @@ -81,6 +82,9 @@ public class UserServiceImpl extends ServiceImpl impleme @Resource private SysUserDataScopeMapper sysUserDataScopeMapper; + @Resource + private SysUserTenantMapper sysUserTenantMapper; + @Resource private IAdminAuthService adminAuthService; @@ -169,7 +173,7 @@ public class UserServiceImpl extends ServiceImpl impleme //账号有效 sysUser.setStatus(1); //判断注册的登录账号是否存在 - if (isExistAccount(sysUser.getUsername(),sysUser.getTenantId() )) { + if (isExistAccount(sysUser.getUsername())) { //新增用户 boolean ok = this.save(sysUser); //新增用户分配权限 @@ -185,6 +189,13 @@ public class UserServiceImpl extends ServiceImpl impleme } //判断新增是否成功 消息提示 if (ok) { + // 插入用户-门户关联 + String tenantId = sysUser.getTenantId(); + if (StrUtil.isNotBlank(tenantId)) { + List tenantIds = new ArrayList<>(); + tenantIds.add(tenantId); + sysUserTenantMapper.batchInsert(sysUser.getId(), tenantIds); + } result.put("status", "sucess"); result.put("msg", "新增用户成功!"); @@ -434,6 +445,8 @@ public class UserServiceImpl extends ServiceImpl impleme if (isOk) { //根据用户id 删除该用户角色关联 sysUserMapper.delRoleUsersByUserid(id); + // 删除用户-门户关联 + sysUserTenantMapper.deleteByUserId(id); //判断是否存在 账号头像 存在删除 if (StrUtil.isNotEmpty(sysUser.getAvatar())) { FileUtil.del(imgName); @@ -636,6 +649,10 @@ public class UserServiceImpl extends ServiceImpl impleme } // 根据ID删除用户与角色的关联信息 sysUserMapper.delRoleUsersByUserIds(ids); + // 删除用户-门户关联 + for (String userId : ids) { + sysUserTenantMapper.deleteByUserId(userId); + } List avatars = sysUsers.stream().map(SysUser::getAvatar).collect(Collectors.toList()); if (avatars.size() > 0) { @@ -654,7 +671,7 @@ public class UserServiceImpl extends ServiceImpl impleme public SysUser getUserByPhone(String phone,String tenantId) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(SysUser::getPhone, phone); - queryWrapper.eq(SysUser::getTenantId, tenantId); +// queryWrapper.eq(SysUser::getTenantId, tenantId); return this.getOne(queryWrapper); } @@ -893,15 +910,14 @@ public class UserServiceImpl extends ServiceImpl impleme } /*********************************** - * 用途说明:比较登录名称是否有重复 + * 用途说明:比较登录名称是否有重复(全局唯一,不区分门户) * 参数说明 * account 登录名称 * 返回值说明: 重复返回 false 否则返回 true ************************************/ - private boolean isExistAccount(String username,String tenantId) { + private boolean isExistAccount(String username) { QueryWrapper queryWrapper = new QueryWrapper<>(); - if (this.list(queryWrapper.eq("username", username).eq("TENANT_ID", tenantId)).size() > 0) { - //判断 查询登录账号 结果集是否为null 重复返回 false 否则返回 tree + if (this.list(queryWrapper.eq("username", username)).size() > 0) { return false; } else { return true; @@ -912,7 +928,7 @@ public class UserServiceImpl extends ServiceImpl impleme @Override public List queryUsersList(String name, String tenantId) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysUser::getTenantId, tenantId); +// queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysUser::getTenantId, tenantId); queryWrapper.eq(SysUser::getStatus, 1); queryWrapper.and(StrUtil.isNotBlank(name), wrapper -> wrapper.like(SysUser::getNickname, name) @@ -923,4 +939,49 @@ public class UserServiceImpl extends ServiceImpl impleme List sysUserList = this.list( queryWrapper); return sysUserList; } + + // ==================== 多门户管理 ==================== + + /** + * 为用户分配门户 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void assignTenantsToUser(String userId, List tenantIds) { + if (StrUtil.isBlank(userId) || tenantIds == null || tenantIds.isEmpty()) { + throw new RuntimeException("用户ID和门户ID列表不能为空"); + } + sysUserTenantMapper.batchInsert(userId, tenantIds); + } + + /** + * 移除用户的某个门户关联 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void removeTenantFromUser(String userId, String tenantId) { + if (StrUtil.isBlank(userId) || StrUtil.isBlank(tenantId)) { + throw new RuntimeException("用户ID和门户ID不能为空"); + } + sysUserTenantMapper.deleteByUserIdAndTenantId(userId, tenantId); + } + + /** + * 获取用户关联的门户ID列表 + */ + @Override + public List getUserTenants(String userId) { + if (StrUtil.isBlank(userId)) { + return new ArrayList<>(); + } + return sysUserTenantMapper.getTenantIdsByUserId(userId); + } + + + public boolean isSuperAdmin(String userId) { +// String maxLevel = sysUserMapper.getMaxLevel(userId); + SysUser sysUser = sysUserMapper.selectById(userId); + return sysUser!=null && sysUser.getUsertype()==0; + } + } diff --git a/backend/src/main/java/com/yfd/platform/utils/SecurityUtils.java b/backend/src/main/java/com/yfd/platform/utils/SecurityUtils.java index 8d667c15..8c90a931 100644 --- a/backend/src/main/java/com/yfd/platform/utils/SecurityUtils.java +++ b/backend/src/main/java/com/yfd/platform/utils/SecurityUtils.java @@ -19,6 +19,7 @@ import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.yfd.platform.exception.BadRequestException; +import com.yfd.platform.system.domain.LoginUser; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.security.core.Authentication; @@ -105,4 +106,40 @@ public class SecurityUtils { .anyMatch(auth -> permission.equals(auth.getAuthority())); } + /** + * 获取当前登录用户的门户ID + * @return 门户ID,超级管理员可能返回null + */ + public static String getCurrentTenantId() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication == null || !(authentication.getPrincipal() instanceof LoginUser)) { + return null; + } + LoginUser loginUser = (LoginUser) authentication.getPrincipal(); + return loginUser.getCurrentTenantId(); + } + + /** + * 判断当前用户是否为超级管理员 + */ + public static boolean isSuperAdmin() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication == null || !(authentication.getPrincipal() instanceof LoginUser)) { + return false; + } + LoginUser loginUser = (LoginUser) authentication.getPrincipal(); + return loginUser.isSuperAdmin(); + } + + /** + * 获取当前用户可访问的门户ID列表 + */ + public static List getAccessibleTenantIds() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication == null || !(authentication.getPrincipal() instanceof LoginUser)) { + return null; + } + LoginUser loginUser = (LoginUser) authentication.getPrincipal(); + return loginUser.getAccessibleTenantIds(); + } } diff --git a/backend/src/main/resources/mapper/system/SysMenuMapper.xml b/backend/src/main/resources/mapper/system/SysMenuMapper.xml index a65f0c7f..797c7314 100644 --- a/backend/src/main/resources/mapper/system/SysMenuMapper.xml +++ b/backend/src/main/resources/mapper/system/SysMenuMapper.xml @@ -27,7 +27,7 @@ diff --git a/backend/src/main/resources/mapper/system/SysUserTenantMapper.xml b/backend/src/main/resources/mapper/system/SysUserTenantMapper.xml new file mode 100644 index 00000000..ce2a99c8 --- /dev/null +++ b/backend/src/main/resources/mapper/system/SysUserTenantMapper.xml @@ -0,0 +1,57 @@ + + + + + + + + + + DELETE FROM SYS_USER_TENANT WHERE USER_ID = #{userId} + + + + + MERGE INTO SYS_USER_TENANT T + USING ( + + SELECT + #{userId, jdbcType=VARCHAR} AS USER_ID, + #{tenantId, jdbcType=VARCHAR} AS TENANT_ID + FROM DUAL + + ) S + ON (T.USER_ID = S.USER_ID AND T.TENANT_ID = S.TENANT_ID) + WHEN NOT MATCHED THEN + INSERT (ID, USER_ID, TENANT_ID) + VALUES (SYS_GUID(), S.USER_ID, S.TENANT_ID) + + + + + DELETE FROM SYS_USER_TENANT WHERE USER_ID = #{userId} AND TENANT_ID = #{tenantId} + + + + + + + + + From 30abebea604d302e051c9f6fa1ad940b7575259a Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 3 Aug 2026 11:17:38 +0800 Subject: [PATCH 03/10] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E9=97=A8=E6=88=B7=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/controller/SysMenuController.java | 32 +++++++------- .../controller/SysOrganizationController.java | 42 +++++++++---------- .../system/controller/SysRoleController.java | 36 +++++++--------- .../system/controller/UserController.java | 6 +-- .../impl/SysOrganizationServiceImpl.java | 11 +++-- .../resources/mapper/system/SysUserMapper.xml | 3 +- 6 files changed, 60 insertions(+), 70 deletions(-) diff --git a/backend/src/main/java/com/yfd/platform/system/controller/SysMenuController.java b/backend/src/main/java/com/yfd/platform/system/controller/SysMenuController.java index 4ffe9fed..f6aaa2c1 100644 --- a/backend/src/main/java/com/yfd/platform/system/controller/SysMenuController.java +++ b/backend/src/main/java/com/yfd/platform/system/controller/SysMenuController.java @@ -148,7 +148,7 @@ public class SysMenuController { @ResponseBody public ResponseResult addMenu(@RequestBody SysMenu sysMenu, @RequestHeader(value = "Tenant_id", required = false) String tenantId) { - sysMenu.setTenantId(StrUtil.trimToNull(tenantId)); +// sysMenu.setTenantId(StrUtil.trimToNull(tenantId)); if(StrUtil.isBlank(sysMenu.getTenantId())){ sysMenu.setTenantId(sysMenu.getSystemcode()); } @@ -178,7 +178,7 @@ public class SysMenuController { if (sysMenuService.getOne(queryWrapper) == null) { return ResponseResult.error("未找到对应租户的菜单"); } - sysMenu.setTenantId(StrUtil.trimToNull(tenantId)); +// sysMenu.setTenantId(StrUtil.trimToNull(tenantId)); if(StrUtil.isBlank(sysMenu.getTenantId())){ sysMenu.setTenantId(sysMenu.getSystemcode()); } @@ -206,8 +206,8 @@ public class SysMenuController { public ResponseResult deleteIcon(@RequestParam String id, @RequestHeader(value = "Tenant_id", required = false) String tenantId) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(SysMenu::getId, id) - .eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId)); + queryWrapper.eq(SysMenu::getId, id); +// queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId)); if (sysMenuService.getOne(queryWrapper) == null) { return ResponseResult.error("未找到对应租户的菜单"); } @@ -234,7 +234,7 @@ public class SysMenuController { @RequestHeader(value = "Tenant_id", required = false) String tenantId) { UpdateWrapper updateWrapper = new UpdateWrapper<>(); //根据id 修改是否显示 ,最近修改人,最近修改时间 - updateWrapper.eq("id", id).eq(StrUtil.isNotBlank(tenantId), "tenant_id", StrUtil.trim(tenantId)).set("isdisplay", isdisplay).set( + updateWrapper.eq("id", id).set("isdisplay", isdisplay).set( "lastmodifier", userService.getUsername()).set( "lastmodifydate", new Timestamp(System.currentTimeMillis())); @@ -262,12 +262,12 @@ public class SysMenuController { @RequestParam int orderno, @RequestHeader(value = "Tenant_id", required = false) String tenantId) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(SysMenu::getId, id) - .eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId)); + queryWrapper.eq(SysMenu::getId, id); +// queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId)); if (sysMenuService.getOne(queryWrapper) == null) { return ResponseResult.error("未找到对应租户的菜单"); } - boolean ok = sysMenuService.moveOrderno(parentid, id, orderno, StrUtil.trimToNull(tenantId)); + boolean ok = sysMenuService.moveOrderno(parentid, id, orderno, null); if (ok) { return ResponseResult.success(); } else { @@ -288,8 +288,8 @@ public class SysMenuController { public ResponseResult deleteById(@RequestParam String id, @RequestHeader(value = "Tenant_id", required = false) String tenantId) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(SysMenu::getId, id) - .eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId)); + queryWrapper.eq(SysMenu::getId, id); +// queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId)); if (sysMenuService.getOne(queryWrapper) == null) { return ResponseResult.error("未找到对应租户的菜单"); } @@ -321,11 +321,11 @@ public class SysMenuController { return ResponseResult.error("切换失败!"); } LambdaQueryWrapper fromWrapper = new LambdaQueryWrapper<>(); - fromWrapper.eq(SysMenu::getId, fromId) - .eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId)); + fromWrapper.eq(SysMenu::getId, fromId); +// fromWrapper.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId)); LambdaQueryWrapper toWrapper = new LambdaQueryWrapper<>(); - toWrapper.eq(SysMenu::getId, toId) - .eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId)); + toWrapper.eq(SysMenu::getId, toId); +// toWrapper.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId)); if (sysMenuService.getOne(fromWrapper) == null || sysMenuService.getOne(toWrapper) == null) { return ResponseResult.error("存在不属于当前租户的菜单"); } @@ -350,8 +350,8 @@ public class SysMenuController { @RequestHeader(value = "Tenant_id", required = false) String tenantId) throws FileNotFoundException { if (StrUtil.isNotBlank(menuId)) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(SysMenu::getId, menuId) - .eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId)); + queryWrapper.eq(SysMenu::getId, menuId); +// queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId)); SysMenu sysMenu = sysMenuService.getOne(queryWrapper); if (sysMenu == null) { return ResponseResult.error("未找到对应租户的菜单"); diff --git a/backend/src/main/java/com/yfd/platform/system/controller/SysOrganizationController.java b/backend/src/main/java/com/yfd/platform/system/controller/SysOrganizationController.java index 907aaa1f..f0315668 100644 --- a/backend/src/main/java/com/yfd/platform/system/controller/SysOrganizationController.java +++ b/backend/src/main/java/com/yfd/platform/system/controller/SysOrganizationController.java @@ -53,7 +53,7 @@ public class SysOrganizationController { @ResponseBody public List> getOrgScopeTree(String roleId, @RequestHeader(value = "Tenant_id", required = false) String tenantId) { - return organizationService.getOrgScopeTree(roleId, StrUtil.trimToNull(tenantId)); + return organizationService.getOrgScopeTree(roleId, null); } /*********************************** @@ -67,7 +67,7 @@ public class SysOrganizationController { public List> getOrgTree(String parentid, String params, @RequestHeader(value = "Tenant_id", required = false) String tenantId) { - return organizationService.getOrgTree(parentid, params, StrUtil.trimToNull(tenantId)); + return organizationService.getOrgTree(parentid, params, null); } /*********************************** @@ -85,7 +85,7 @@ public class SysOrganizationController { return ResponseResult.error("查询失败!"); } List sysOrganizations = - organizationService.getOrganizationById(id, orgName, StrUtil.trimToNull(tenantId)); + organizationService.getOrganizationById(id, orgName, null); return ResponseResult.successData(sysOrganizations); } @@ -102,8 +102,8 @@ public class SysOrganizationController { @RequestHeader(value = "Tenant_id", required = false) String tenantId) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(SysOrganization::getId, id) - .eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId)); + queryWrapper.eq(SysOrganization::getId, id); +// queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId)); SysOrganization sysOrganization = organizationService.getOne(queryWrapper); return ResponseResult.successData(sysOrganization); } @@ -127,7 +127,7 @@ public class SysOrganizationController { if("".equals(sysOrganization.getId())){ sysOrganization.setId(null); } - sysOrganization.setTenantId(StrUtil.trimToNull(tenantId)); +// sysOrganization.setTenantId(StrUtil.trimToNull(tenantId)); //填写 当前用户名称 sysOrganization.setLastmodifier(userService.getUsername()); //填写 当前日期 @@ -155,12 +155,12 @@ public class SysOrganizationController { @RequestHeader(value = "Tenant_id", required = false) String tenantId) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(SysOrganization::getId, sysOrganization.getId()) - .eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId)); + queryWrapper.eq(SysOrganization::getId, sysOrganization.getId()); +// queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId)); if (organizationService.getOne(queryWrapper) == null) { return ResponseResult.error("未找到对应租户的组织"); } - sysOrganization.setTenantId(StrUtil.trimToNull(tenantId)); +// sysOrganization.setTenantId(StrUtil.trimToNull(tenantId)); //填写 当前用户名称 sysOrganization.setLastmodifier(userService.getUsername()); //填写 当前日期 @@ -189,7 +189,7 @@ public class SysOrganizationController { @RequestHeader(value = "Tenant_id", required = false) String tenantId) { UpdateWrapper updateWrapper = new UpdateWrapper<>(); //根据id 修改是否有效,最近修改人,最近修改时间 - updateWrapper.eq("id", id).eq(StrUtil.isNotBlank(tenantId), "tenant_id", StrUtil.trim(tenantId)).set("isvaild", isvaild).set("lastmodifier" + updateWrapper.eq("id", id).set("isvaild", isvaild).set("lastmodifier" , userService.getUsername()).set("lastmodifydate", new Timestamp(System.currentTimeMillis())); boolean isOk = organizationService.update(updateWrapper); @@ -216,28 +216,24 @@ public class SysOrganizationController { for (String orgId : orgIds) { LambdaQueryWrapper currentWrapper = new LambdaQueryWrapper<>(); - currentWrapper.eq(SysOrganization::getId, orgId) - .eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId)); + currentWrapper.eq(SysOrganization::getId, orgId); +// currentWrapper.eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId)); if (organizationService.getOne(currentWrapper) == null) { - return ResponseResult.error("存在不属于当前租户的组织"); + return ResponseResult.error("不存在对应组织"); } - LambdaQueryWrapper queryWrapper = - new LambdaQueryWrapper<>(); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); +// queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId)); List list = - organizationService.list(queryWrapper.eq(SysOrganization::getParentid, orgId) - .eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId))); + organizationService.list(queryWrapper.eq(SysOrganization::getParentid, orgId)); List ids = - list.stream().map(SysOrganization::getId).collect(Collectors.toList()); + list.stream().map(SysOrganization::getId).toList(); boolean isOk = organizationService.remove(new LambdaQueryWrapper() - .eq(SysOrganization::getId, orgId) - .eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId))); + .eq(SysOrganization::getId, orgId)); if (!isOk) { continue; } for (String oid : ids) { - organizationService.remove(new LambdaQueryWrapper() - .eq(SysOrganization::getId, oid) - .eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId))); + organizationService.remove(new LambdaQueryWrapper().eq(SysOrganization::getId, oid)); } } return ResponseResult.success(); diff --git a/backend/src/main/java/com/yfd/platform/system/controller/SysRoleController.java b/backend/src/main/java/com/yfd/platform/system/controller/SysRoleController.java index fbb0bbc1..444e6837 100644 --- a/backend/src/main/java/com/yfd/platform/system/controller/SysRoleController.java +++ b/backend/src/main/java/com/yfd/platform/system/controller/SysRoleController.java @@ -55,7 +55,7 @@ public class SysRoleController { @ResponseBody public List list(@RequestParam(required = false) String rolename, @RequestHeader(value = "Tenant_id", required = false) String tenantId) { - return roleService.selectRoleList(rolename, StrUtil.trimToNull(tenantId)); + return roleService.selectRoleList(rolename, null); } /*********************************** @@ -70,8 +70,8 @@ public class SysRoleController { public ResponseResult getOneById(String id, @RequestHeader(value = "Tenant_id", required = false) String tenantId) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(SysRole::getId, id) - .eq(StrUtil.isNotBlank(tenantId), SysRole::getTenantId, StrUtil.trim(tenantId)); + queryWrapper.eq(SysRole::getId, id); + queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysRole::getTenantId, StrUtil.trim(tenantId)); SysRole sysRole = roleService.getOne(queryWrapper); return ResponseResult.successData(sysRole); } @@ -88,7 +88,7 @@ public class SysRoleController { @ResponseBody public ResponseResult addRole(@RequestBody SysRole sysRole, @RequestHeader(value = "Tenant_id", required = false) String tenantId) { - sysRole.setTenantId(StrUtil.trimToNull(tenantId)); +// sysRole.setTenantId(StrUtil.trimToNull(tenantId)); boolean isOk = roleService.addRole(sysRole); if (isOk) { return ResponseResult.success(); @@ -113,7 +113,7 @@ public class SysRoleController { @RequestHeader(value = "Tenant_id", required = false) String tenantId) { UpdateWrapper updateWrapper = new UpdateWrapper<>(); //根据id 更新权限,最近修改人,最近修改时间 - updateWrapper.eq("id", id).eq(StrUtil.isNotBlank(tenantId), "tenant_id", StrUtil.trim(tenantId)).set("optscope", optscope).set( + updateWrapper.eq("id", id).set("optscope", optscope).set( "lastmodifier", userService.getUsername()).set( "lastmodifydate", LocalDateTime.now()); boolean ok = roleService.update(updateWrapper); @@ -141,8 +141,7 @@ public class SysRoleController { return ResponseResult.error("参数为空"); } LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(SysRole::getId, id) - .eq(StrUtil.isNotBlank(tenantId), SysRole::getTenantId, StrUtil.trim(tenantId)); + queryWrapper.eq(SysRole::getId, id); if (roleService.getOne(queryWrapper) == null) { return ResponseResult.error("未找到对应租户的角色"); } @@ -158,8 +157,7 @@ public class SysRoleController { return ResponseResult.success(); } long menuCount = sysMenuService.count(new LambdaQueryWrapper() - .in(SysMenu::getId, menuIdList) - .eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId))); + .in(SysMenu::getId, menuIdList)); if (menuCount != menuIdList.size()) { return ResponseResult.error("存在不属于当前租户的菜单"); } @@ -188,7 +186,7 @@ public class SysRoleController { @RequestHeader(value = "Tenant_id", required = false) String tenantId) { UpdateWrapper updateWrapper = new UpdateWrapper<>(); //根据id 更新组织范围,最近修改人,最近修改时间 - updateWrapper.eq("id", id).eq(StrUtil.isNotBlank(tenantId), "tenant_id", StrUtil.trim(tenantId)).set("orgscope", orgscope).set( + updateWrapper.eq("id", id).set("orgscope", orgscope).set( "lastmodifier", userService.getUsername()).set( "lastmodifydate", LocalDateTime.now()); boolean ok = roleService.update(updateWrapper); @@ -215,7 +213,7 @@ public class SysRoleController { @RequestHeader(value = "Tenant_id", required = false) String tenantId) { UpdateWrapper updateWrapper = new UpdateWrapper<>(); //根据id 更新业务范围,最近修改人,最近修改时间 - updateWrapper.eq("id", id).eq(StrUtil.isNotBlank(tenantId), "tenant_id", StrUtil.trim(tenantId)).set("busscope", busscope).set( + updateWrapper.eq("id", id).set("busscope", busscope).set( "lastmodifier", userService.getUsername()).set( "lastmodifydate", LocalDateTime.now()); boolean ok = roleService.update(updateWrapper); @@ -240,8 +238,7 @@ public class SysRoleController { public ResponseResult setRoleUsers(String roleid, String userids, @RequestHeader(value = "Tenant_id", required = false) String tenantId) { LambdaQueryWrapper roleWrapper = new LambdaQueryWrapper<>(); - roleWrapper.eq(SysRole::getId, roleid) - .eq(StrUtil.isNotBlank(tenantId), SysRole::getTenantId, StrUtil.trim(tenantId)); + roleWrapper.eq(SysRole::getId, roleid); if (roleService.getOne(roleWrapper) == null) { return ResponseResult.error("未找到对应租户的角色"); } @@ -270,8 +267,7 @@ public class SysRoleController { @RequestParam String userids, @RequestHeader(value = "Tenant_id", required = false) String tenantId) { LambdaQueryWrapper roleWrapper = new LambdaQueryWrapper<>(); - roleWrapper.eq(SysRole::getId, roleid) - .eq(StrUtil.isNotBlank(tenantId), SysRole::getTenantId, StrUtil.trim(tenantId)); + roleWrapper.eq(SysRole::getId, roleid); if (roleService.getOne(roleWrapper) == null) { return ResponseResult.error("未找到对应租户的角色"); } @@ -298,7 +294,7 @@ public class SysRoleController { @RequestHeader(value = "Tenant_id", required = false) String tenantId) { UpdateWrapper updateWrapper = new UpdateWrapper<>(); //根据id 更新业务范围,最近修改人,最近修改时间 - updateWrapper.eq("id", id).eq(StrUtil.isNotBlank(tenantId), "tenant_id", StrUtil.trim(tenantId)).set("isvaild", isvaild).set("lastmodifier" + updateWrapper.eq("id", id).set("isvaild", isvaild).set("lastmodifier" , userService.getUsername()).set("lastmodifydate", LocalDateTime.now()); boolean ok = roleService.update(updateWrapper); @@ -321,8 +317,7 @@ public class SysRoleController { public ResponseResult updateById(@RequestBody SysRole sysRole, @RequestHeader(value = "Tenant_id", required = false) String tenantId) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(SysRole::getId, sysRole.getId()) - .eq(StrUtil.isNotBlank(tenantId), SysRole::getTenantId, StrUtil.trim(tenantId)); + queryWrapper.eq(SysRole::getId, sysRole.getId()); if (roleService.getOne(queryWrapper) == null) { return ResponseResult.error("未找到对应租户的角色"); } @@ -354,8 +349,7 @@ public class SysRoleController { String[] roleIds = id.split(","); for (String roleId : roleIds) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(SysRole::getId, roleId) - .eq(StrUtil.isNotBlank(tenantId), SysRole::getTenantId, StrUtil.trim(tenantId)); + queryWrapper.eq(SysRole::getId, roleId); if (roleService.getOne(queryWrapper) == null) { return ResponseResult.error("存在不属于当前租户的角色"); } @@ -383,7 +377,7 @@ public class SysRoleController { String rolename, String isvaild, @RequestHeader(value = "Tenant_id", required = false) String tenantId) { return roleService.listRoleUsers(orgid, username, status, level, - rolename, isvaild, StrUtil.trimToNull(tenantId)); + rolename, isvaild, null); } } diff --git a/backend/src/main/java/com/yfd/platform/system/controller/UserController.java b/backend/src/main/java/com/yfd/platform/system/controller/UserController.java index 4e0838cc..6ba65552 100644 --- a/backend/src/main/java/com/yfd/platform/system/controller/UserController.java +++ b/backend/src/main/java/com/yfd/platform/system/controller/UserController.java @@ -46,7 +46,7 @@ public class UserController { public ResponseResult addUser(@RequestBody SysUser user, String roleids, @RequestHeader(value = "Tenant_id", required = false) String tenantId) { - user.setTenantId(StrUtil.trimToNull(tenantId)); +// user.setTenantId(StrUtil.trimToNull(tenantId)); Map reslut = userService.addUser(user, roleids); return ResponseResult.successData(reslut); } @@ -80,7 +80,7 @@ public class UserController { @RequestHeader(value = "Tenant_id", required = false) String tenantId) { Page mapPage = userService.queryUsers(orgid, - username, StrUtil.trimToNull(tenantId), page); + username, null, page); return ResponseResult.successData(mapPage); } @@ -249,7 +249,7 @@ public class UserController { String name, String regStatus, @RequestHeader(value = "Tenant_id", required = false) String tenantId) { - Page result = userService.queryPendingAuditUsers(page, name, regStatus, StrUtil.trimToNull(tenantId)); + Page result = userService.queryPendingAuditUsers(page, name, regStatus, null); return ResponseResult.successData(result); } diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/SysOrganizationServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/SysOrganizationServiceImpl.java index dcf3e8b6..e7681f67 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/SysOrganizationServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/SysOrganizationServiceImpl.java @@ -81,8 +81,7 @@ public class SysOrganizationServiceImpl extends ServiceImpl list = sysOrganizationMapper.selectList( new LambdaQueryWrapper() - .in(SysOrganization::getId, stringList) - .eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, tenantId)); + .in(SysOrganization::getId, stringList)); for (SysOrganization org : list) { if (org.getParentid() != null) { allowedOrgIds.add(org.getParentid()); @@ -97,9 +96,9 @@ public class SysOrganizationServiceImpl extends ServiceImpl queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(SysOrganization::getParentid, id); - queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, tenantId); +// queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, tenantId); if (StrUtil.isNotBlank(orgName)) { queryWrapper.like(SysOrganization::getOrgname, orgName); diff --git a/backend/src/main/resources/mapper/system/SysUserMapper.xml b/backend/src/main/resources/mapper/system/SysUserMapper.xml index dbda0bfe..c6b90b81 100644 --- a/backend/src/main/resources/mapper/system/SysUserMapper.xml +++ b/backend/src/main/resources/mapper/system/SysUserMapper.xml @@ -77,7 +77,8 @@ WHERE 1 = 1 AND ( ( u.REG_STATUS != 'PENDING' AND u.REG_STATUS != 'REJECTED' ) OR u.REG_STATUS IS NULL ) - AND u.usertype != 0 +-- AND u.usertype != 0 + AND u.username != 'admin' and u.orgid = #{orgid} From ae57efdae2a1bb3d9ad2d5f3c656f69a7c23fbb1 Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 3 Aug 2026 13:41:20 +0800 Subject: [PATCH 04/10] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E9=97=A8=E6=88=B7=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/controller/SmsVerifyCodeController.java | 9 +++++++-- .../system/service/impl/AdminAuthServiceImpl.java | 4 +++- .../system/service/impl/UserDetailsServiceImpl.java | 9 ++++++--- .../src/main/resources/mapper/system/SysUserMapper.xml | 2 +- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/backend/src/main/java/com/yfd/platform/system/controller/SmsVerifyCodeController.java b/backend/src/main/java/com/yfd/platform/system/controller/SmsVerifyCodeController.java index 8680affe..7795dacf 100644 --- a/backend/src/main/java/com/yfd/platform/system/controller/SmsVerifyCodeController.java +++ b/backend/src/main/java/com/yfd/platform/system/controller/SmsVerifyCodeController.java @@ -70,7 +70,8 @@ public class SmsVerifyCodeController { @Resource private SysUserTenantMapper sysUserTenantMapper; - + @Resource + private SysUserTenantMapper userTenantMapper; @Resource private ISdHbrvDicService hbrvDicService; @@ -184,7 +185,7 @@ public class SmsVerifyCodeController { */ @PostMapping("/register") @Operation(summary = "注册用户") - @Transactional + @Transactional(rollbackFor = Exception.class) public ResponseResult register(@RequestHeader(value = "Tenant_id", required = false) String tenantId,@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { String code = smsVerifyCodeRequest.getCode(); if (smsVerifyCodeRequest.getPhone() == null || smsVerifyCodeRequest.getPhone().isEmpty()) { @@ -233,6 +234,10 @@ public class SmsVerifyCodeController { // 给注册用户加上默认权限 SysUser savedUser = userService.getUserByPhone(smsVerifyCodeRequest.getPhone(),tenantId); if (savedUser != null) { + SysUserTenant sysUserTenant = new SysUserTenant(); + sysUserTenant.setTenantId(tenantId); + sysUserTenant.setUserId(user.getId()); + userTenantMapper.insert(sysUserTenant); this.addDefaultRole(savedUser.getId(), smsVerifyCodeRequest); } if (success) { diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/AdminAuthServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/AdminAuthServiceImpl.java index 3b6579f9..4f75a0aa 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/AdminAuthServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/AdminAuthServiceImpl.java @@ -74,6 +74,8 @@ public class AdminAuthServiceImpl implements IAdminAuthService { @Override public boolean isCurrentManagedAdmin() { - return isManagedAdminUsername(SecurityUtils.getCurrentUsername()); + String maxLevel = userMapper.getMaxLevel(SecurityUtils.getUserId()); + boolean adminRole = "1".equals(maxLevel); + return adminRole||isManagedAdminUsername(SecurityUtils.getCurrentUsername()); } } diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/UserDetailsServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/UserDetailsServiceImpl.java index c1c9c6d6..45735c42 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/UserDetailsServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/UserDetailsServiceImpl.java @@ -9,6 +9,7 @@ import com.yfd.platform.system.domain.SysUser; import com.yfd.platform.system.mapper.SysMenuMapper; import com.yfd.platform.system.mapper.SysUserMapper; import com.yfd.platform.system.mapper.SysUserTenantMapper; +import com.yfd.platform.system.service.IAdminAuthService; import com.yfd.platform.system.service.IUserService; import jakarta.servlet.http.HttpServletRequest; import org.springframework.security.core.userdetails.UserDetails; @@ -38,6 +39,8 @@ public class UserDetailsServiceImpl implements UserDetailsService { @Resource private IUserService userService; + @Resource + private IAdminAuthService adminAuthService; @Resource private SysMenuMapper sysMenuMapper; @@ -71,7 +74,7 @@ public class UserDetailsServiceImpl implements UserDetailsService { } // 判断是否为超级管理员(LEVEL=1) - boolean isSuperAdmin = isSuperAdmin(user.getId()); + boolean isSuperAdmin = (isSuperAdmin(user.getId())||user.getUsertype()==0); // 查询用户可访问的门户列表 List accessibleTenantIds = sysUserTenantMapper.getTenantIdsByUserId(user.getId()); @@ -79,10 +82,10 @@ public class UserDetailsServiceImpl implements UserDetailsService { // 非超级管理员必须指定门户,且必须在可访问列表中 if (!isSuperAdmin) { if (StrUtil.isBlank(tenantId)) { - throw new RuntimeException("普通用户登录必须指定门户(Tenant_Id)"); + throw new RuntimeException("用户无权限访问该平台"); } if (accessibleTenantIds == null || !accessibleTenantIds.contains(tenantId)) { - throw new RuntimeException("用户无权限访问该门户"); + throw new RuntimeException("用户无权限访问该平台"); } } diff --git a/backend/src/main/resources/mapper/system/SysUserMapper.xml b/backend/src/main/resources/mapper/system/SysUserMapper.xml index c6b90b81..1e63e72f 100644 --- a/backend/src/main/resources/mapper/system/SysUserMapper.xml +++ b/backend/src/main/resources/mapper/system/SysUserMapper.xml @@ -83,7 +83,7 @@ and u.orgid = #{orgid} - and u.username LIKE '%' || #{username} || '%' + and (u.username LIKE '%' || #{username} || '%' OR u.nickname LIKE '%' || #{username} || '%' OR u.phone LIKE '%' || #{username} || '%') and (ut.TENANT_ID = #{tenantId} OR u.tenant_id = #{tenantId}) From 57cc61f1c0f40f2ceb5081750af8cad77ff5019d Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 3 Aug 2026 15:41:21 +0800 Subject: [PATCH 05/10] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E9=97=A8=E6=88=B7=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yfd/platform/config/ResponseResult.java | 16 ++-- .../yfd/platform/config/SecurityConfig.java | 1 + .../controller/SdFishDictoryBController.java | 3 +- .../system/controller/LoginController.java | 2 +- .../system/controller/SysMenuController.java | 15 ++++ .../system/controller/SysRoleController.java | 6 +- .../system/service/ISysMenuService.java | 9 +++ .../platform/system/service/IUserService.java | 2 +- .../service/impl/SysMenuServiceImpl.java | 81 +++++++++++++++++++ .../system/service/impl/UserServiceImpl.java | 5 +- 10 files changed, 124 insertions(+), 16 deletions(-) diff --git a/backend/src/main/java/com/yfd/platform/config/ResponseResult.java b/backend/src/main/java/com/yfd/platform/config/ResponseResult.java index 9638fcf3..6e543fbd 100644 --- a/backend/src/main/java/com/yfd/platform/config/ResponseResult.java +++ b/backend/src/main/java/com/yfd/platform/config/ResponseResult.java @@ -22,29 +22,29 @@ public class ResponseResult extends HashMap { public static ResponseResult error(String msg) { ResponseResult json = new ResponseResult(); - json.put((String)"code", "1");//错误 - json.put((String)"msg", msg); + json.put("code", "1");//错误 + json.put("msg", msg); return json; } public static ResponseResult message(String code, String msg) { ResponseResult json = new ResponseResult(); - json.put((String)"code", code); - json.put((String)"msg", msg); + json.put("code", code); + json.put("msg", msg); return json; } public static ResponseResult success(String msg) { ResponseResult json = new ResponseResult(); - json.put((String)"code", "0");//正常 - json.put((String)"msg", msg); + json.put("code", "0");//正常 + json.put("msg", msg); return json; } public static ResponseResult successData(Object obj) { ResponseResult json = new ResponseResult(); - json.put((String)"code", "0");//正常 - json.put((String)"msg", "操作成功"); + json.put("code", "0");//正常 + json.put("msg", "操作成功"); json.put("data", obj); return json; } diff --git a/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java b/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java index 3c457b73..0833307f 100644 --- a/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java +++ b/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java @@ -67,6 +67,7 @@ public class SecurityConfig { .requestMatchers("/dict/cache/**").permitAll() .requestMatchers("/sys/psbmodulelbb/**").permitAll() .requestMatchers("/base/operationLog/**").permitAll() + .requestMatchers("/system/**").permitAll() // .requestMatchers("/eng/**").permitAll() // .requestMatchers("/eq/**").permitAll() // .requestMatchers("/env/**").permitAll() diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/controller/SdFishDictoryBController.java b/backend/src/main/java/com/yfd/platform/qgc_base/controller/SdFishDictoryBController.java index 69c6f0be..981752a2 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/controller/SdFishDictoryBController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/controller/SdFishDictoryBController.java @@ -12,6 +12,7 @@ import com.yfd.platform.qgc_base.domain.SdEngInfoBHOperateRequest; import com.yfd.platform.qgc_base.domain.SdFishDictoryB; import com.yfd.platform.qgc_base.service.ISdFishDictoryBService; import com.yfd.platform.qgc_data.service.AttachmentUploadService; +import com.yfd.platform.utils.DataSourceRequestUtil; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; @@ -55,7 +56,7 @@ public class SdFishDictoryBController { @PostMapping("/list") @Operation(summary = "查询鱼类字典列表(支持动态过滤和排序,不分页)") public ResponseResult list(@RequestBody DataSourceRequest request) { - List list = sdFishDictoryBService.list(); + List list = DataSourceRequestUtil.executeList(request, SdFishDictoryB.class, sdFishDictoryBService); return ResponseResult.successData(list); } diff --git a/backend/src/main/java/com/yfd/platform/system/controller/LoginController.java b/backend/src/main/java/com/yfd/platform/system/controller/LoginController.java index d341fcbd..689fa3c8 100644 --- a/backend/src/main/java/com/yfd/platform/system/controller/LoginController.java +++ b/backend/src/main/java/com/yfd/platform/system/controller/LoginController.java @@ -241,7 +241,7 @@ public class LoginController { @Operation(summary = "查询当前用户信息") @ResponseBody public ResponseResult getUserInfo() { - ResponseResult responseResult = userService.getLoginUserInfo(); + Map responseResult = userService.getLoginUserInfo(); return ResponseResult.successData(responseResult); } diff --git a/backend/src/main/java/com/yfd/platform/system/controller/SysMenuController.java b/backend/src/main/java/com/yfd/platform/system/controller/SysMenuController.java index f6aaa2c1..1ea0dede 100644 --- a/backend/src/main/java/com/yfd/platform/system/controller/SysMenuController.java +++ b/backend/src/main/java/com/yfd/platform/system/controller/SysMenuController.java @@ -101,6 +101,21 @@ public class SysMenuController { return sysMenuService.permissionAssignment(code, roleId, StrUtil.trimToNull(tenantId)); } + /*********************************** + * 用途说明:权限分配(按系统分组,附带系统标识和名称) + * 参数说明 + * roleId 角色ID + * 返回值说明: [{"systemCode":"1","systemName":"Web端","menus":[...]}, ...] + * 系统名称通过字典 PLATFORM_TENANT 获取 + ***********************************/ + @PostMapping("/permissionAssignmentGrouped") + @Operation(summary = "获取分配权限-按系统分组(含系统标识和名称)") + @ResponseBody + public List> permissionAssignmentGrouped(String roleId, + String tenantId) { + return sysMenuService.permissionAssignmentGrouped(roleId, StrUtil.trimToNull(tenantId)); + } + /********************************** * 用途说明: 获取当前用户菜单结构树 * 参数说明 diff --git a/backend/src/main/java/com/yfd/platform/system/controller/SysRoleController.java b/backend/src/main/java/com/yfd/platform/system/controller/SysRoleController.java index 444e6837..3570aef8 100644 --- a/backend/src/main/java/com/yfd/platform/system/controller/SysRoleController.java +++ b/backend/src/main/java/com/yfd/platform/system/controller/SysRoleController.java @@ -54,8 +54,8 @@ public class SysRoleController { @Operation(summary = "查询所有角色") @ResponseBody public List list(@RequestParam(required = false) String rolename, - @RequestHeader(value = "Tenant_id", required = false) String tenantId) { - return roleService.selectRoleList(rolename, null); + @RequestParam(required = false) String tenantId) { + return roleService.selectRoleList(rolename, tenantId); } /*********************************** @@ -71,7 +71,7 @@ public class SysRoleController { @RequestHeader(value = "Tenant_id", required = false) String tenantId) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(SysRole::getId, id); - queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysRole::getTenantId, StrUtil.trim(tenantId)); +// queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysRole::getTenantId, StrUtil.trim(tenantId)); SysRole sysRole = roleService.getOne(queryWrapper); return ResponseResult.successData(sysRole); } diff --git a/backend/src/main/java/com/yfd/platform/system/service/ISysMenuService.java b/backend/src/main/java/com/yfd/platform/system/service/ISysMenuService.java index 3dad368d..d9d73db2 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/ISysMenuService.java +++ b/backend/src/main/java/com/yfd/platform/system/service/ISysMenuService.java @@ -97,5 +97,14 @@ public interface ISysMenuService extends IService { ***********************************/ List> permissionAssignment(String code, String roleId, String tenantId); + /*********************************** + * 用途说明:权限分配(按系统分组,附带系统标识和名称) + * 参数说明 + * roleId 角色ID + * tenantId 门户ID + * 返回值说明: [{"systemCode":"1","systemName":"Web端","menus":[...]}, ...] + ***********************************/ + List> permissionAssignmentGrouped(String roleId, String tenantId); + String uploadIcon(MultipartFile icon) throws FileNotFoundException; } diff --git a/backend/src/main/java/com/yfd/platform/system/service/IUserService.java b/backend/src/main/java/com/yfd/platform/system/service/IUserService.java index 99d8c4f3..a3c10ff2 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/IUserService.java +++ b/backend/src/main/java/com/yfd/platform/system/service/IUserService.java @@ -33,7 +33,7 @@ public interface IUserService extends IService { ************************************/ Map getNameInfo(); //获取当前用户信息带权限 - ResponseResult getLoginUserInfo(); + Map getLoginUserInfo(); /*********************************** * 用途说明:新增用户 diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/SysMenuServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/SysMenuServiceImpl.java index b3531c9e..7fe25ef3 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/SysMenuServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/SysMenuServiceImpl.java @@ -7,10 +7,14 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.yfd.platform.system.domain.SysDictionary; +import com.yfd.platform.system.domain.SysDictionaryItems; import com.yfd.platform.system.domain.SysMenu; import com.yfd.platform.system.domain.SysRole; import com.yfd.platform.system.mapper.SysMenuMapper; import com.yfd.platform.system.mapper.SysRoleMapper; +import com.yfd.platform.system.service.ISysDictionaryItemsService; +import com.yfd.platform.system.service.ISysDictionaryService; import com.yfd.platform.system.service.ISysMenuService; import com.yfd.platform.utils.FileUtil; import com.yfd.platform.config.FileSpaceProperties; @@ -47,6 +51,12 @@ public class SysMenuServiceImpl extends ServiceImpl impl @Resource private UserServiceImpl currentUser; + @Resource + private ISysDictionaryService sysDictionaryService; + + @Resource + private ISysDictionaryItemsService sysDictionaryItemsService; + @Resource private SysRoleMapper sysRoleMapper; @@ -502,6 +512,77 @@ public class SysMenuServiceImpl extends ServiceImpl impl return listTree; } + /*********************************** + * 用途说明:权限分配(按系统分组,附带系统标识和名称) + * 参数说明 + * roleId 角色ID + * tenantId 门户ID + * 返回值说明: [{"systemCode":"1","systemName":"Web端","menus":[...]}, ...] + ***********************************/ + @Override + public List> permissionAssignmentGrouped(String roleId, String tenantId) { + // 1. 查询 PLATFORM_TENANT 字典项,构建 systemCode → systemName 映射 + Map systemNameMap = new HashMap<>(); + SysDictionary tenantDict = sysDictionaryService.getByDictCode("PLATFORM_TENANT"); + if (tenantDict != null) { + List items = sysDictionaryItemsService.listByDictId(tenantDict.getId()); + if (items != null) { + for (SysDictionaryItems item : items) { + if (StrUtil.isNotBlank(item.getItemCode())) { + systemNameMap.put(item.getItemCode(), item.getDictName()); + } + } + } + } + + // 2. 查询所有菜单(不按 systemcode 过滤,按租户过滤) + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.select(SysMenu::getId, SysMenu::getParentid, SysMenu::getName, + SysMenu::getSystemcode, SysMenu::getOrderno) + .eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, tenantId) + .orderByAsc(SysMenu::getSystemcode, SysMenu::getOrderno); + List> mapList = sysMenuMapper.selectMaps(queryWrapper); + List> listAll = ObjectConverterUtil.convertMapFieldsToEntityFormat(SysMenu.class, mapList); + + // 3. 获取角色已有的菜单ID列表 + List listRole = sysMenuMapper.selectMenuByRoleId(roleId, tenantId); + + // 4. 标记 checkinfo + for (Map map : listAll) { + String id = (String) map.get("id"); + map.put("checkinfo", listRole != null && listRole.contains(id)); + } + + // 5. 按 systemcode 分组 + Map>> groupedBySystem = new LinkedHashMap<>(); + for (Map menu : listAll) { + String sysCode = (String) menu.get("systemcode"); + if (StrUtil.isBlank(sysCode)) { + sysCode = "1"; // 默认归属到 web 系统 + } + groupedBySystem.computeIfAbsent(sysCode, k -> new ArrayList<>()).add(menu); + } + + // 6. 按系统分组构建树,并附加 systemCode 和 systemName + List> result = new ArrayList<>(); + for (Map.Entry>> entry : groupedBySystem.entrySet()) { + String sysCode = entry.getKey(); + List> sysMenuList = entry.getValue(); + + // 构建菜单树 + List> menuTree = buildTrees(sysMenuList); + + // 组装结果 + Map systemGroup = new HashMap<>(); + systemGroup.put("systemCode", sysCode); + systemGroup.put("systemName", systemNameMap.getOrDefault(sysCode, sysCode)); + systemGroup.put("menus", menuTree); + result.add(systemGroup); + } + + return result; + } + // 另一种方法 /*public List> permissionAssignment(String roleId) { diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java index 0226eea6..a53bc58f 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java @@ -126,7 +126,7 @@ public class UserServiceImpl extends ServiceImpl impleme } @Override - public ResponseResult getLoginUserInfo() { + public Map getLoginUserInfo() { UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); LoginUser loginuser = (LoginUser) authentication.getPrincipal(); @@ -142,7 +142,8 @@ public class UserServiceImpl extends ServiceImpl impleme if(user.getUsertype()==0){ collect.add("超级管理员"); } - ResponseResult responseResult = new ResponseResult(); + // 新写法(推荐) + Map responseResult = new HashMap<>(); responseResult.put("userInfo", userInfo); responseResult.put("roles", collect); responseResult.put("permissions", loginuser.getPermissions()); From d14b6d6eba9d44359644ec94d4f23af73583c069 Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 3 Aug 2026 17:51:33 +0800 Subject: [PATCH 06/10] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/SmsVerifyCodeController.java | 2 + .../system/controller/SysMenuController.java | 3 +- .../platform/system/domain/SysUserTenant.java | 9 ++++ .../platform/system/mapper/SysUserMapper.java | 2 +- .../system/mapper/SysUserTenantMapper.java | 2 +- .../impl/SysOrganizationServiceImpl.java | 6 ++- .../system/service/impl/UserServiceImpl.java | 40 +++++++++++------ .../platform/utils/DataSourceRequestUtil.java | 45 +++++++++++++++++++ .../resources/mapper/system/SysRoleMapper.xml | 3 +- .../resources/mapper/system/SysUserMapper.xml | 2 +- .../mapper/system/SysUserTenantMapper.xml | 5 ++- 11 files changed, 96 insertions(+), 23 deletions(-) diff --git a/backend/src/main/java/com/yfd/platform/system/controller/SmsVerifyCodeController.java b/backend/src/main/java/com/yfd/platform/system/controller/SmsVerifyCodeController.java index 7795dacf..4b58e319 100644 --- a/backend/src/main/java/com/yfd/platform/system/controller/SmsVerifyCodeController.java +++ b/backend/src/main/java/com/yfd/platform/system/controller/SmsVerifyCodeController.java @@ -237,6 +237,8 @@ public class SmsVerifyCodeController { SysUserTenant sysUserTenant = new SysUserTenant(); sysUserTenant.setTenantId(tenantId); sysUserTenant.setUserId(user.getId()); + sysUserTenant.setId(user.getId()); +// sysUserTenant.setOperateTime(new Date()); userTenantMapper.insert(sysUserTenant); this.addDefaultRole(savedUser.getId(), smsVerifyCodeRequest); } diff --git a/backend/src/main/java/com/yfd/platform/system/controller/SysMenuController.java b/backend/src/main/java/com/yfd/platform/system/controller/SysMenuController.java index 1ea0dede..5575de40 100644 --- a/backend/src/main/java/com/yfd/platform/system/controller/SysMenuController.java +++ b/backend/src/main/java/com/yfd/platform/system/controller/SysMenuController.java @@ -126,8 +126,9 @@ public class SysMenuController { @ResponseBody public List> getMenuTreeByUser(@RequestHeader(value = "Tenant_id", required = false) String tenantId) { SysUser userInfo = userService.getUserInfo(); + boolean superAdmin = userService.isSuperAdmin(userInfo.getId()); String id = ""; - if (0 != userInfo.getUsertype()) { + if (0 != userInfo.getUsertype() && !superAdmin) { id = userInfo.getId(); } return sysMenuService.getMenuTree(id, tenantId); diff --git a/backend/src/main/java/com/yfd/platform/system/domain/SysUserTenant.java b/backend/src/main/java/com/yfd/platform/system/domain/SysUserTenant.java index b5b8cfac..6ac24062 100644 --- a/backend/src/main/java/com/yfd/platform/system/domain/SysUserTenant.java +++ b/backend/src/main/java/com/yfd/platform/system/domain/SysUserTenant.java @@ -1,11 +1,13 @@ package com.yfd.platform.system.domain; import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.io.Serializable; +import java.util.Date; /** *

@@ -27,4 +29,11 @@ public class SysUserTenant implements Serializable { /** 门户ID */ private String tenantId; + + @TableField("OPERATOR") + private String operator; + + @TableField("OPERATE_TIME") + private Date operateTime; + } diff --git a/backend/src/main/java/com/yfd/platform/system/mapper/SysUserMapper.java b/backend/src/main/java/com/yfd/platform/system/mapper/SysUserMapper.java index e9ac1f55..a9a45137 100644 --- a/backend/src/main/java/com/yfd/platform/system/mapper/SysUserMapper.java +++ b/backend/src/main/java/com/yfd/platform/system/mapper/SysUserMapper.java @@ -29,7 +29,7 @@ public interface SysUserMapper extends BaseMapper { * userid 用户id * 返回值说明: ************************************/ - boolean addUserRoles(@Param("id")String id,@Param("roleid") String roleid,@Param("userid") String userid); + boolean addUserRoles(@Param("operator") String operator,@Param("id")String id,@Param("roleid") String roleid,@Param("userid") String userid); /*********************************** * 用途说明:根据用户id 和角色id 查询 系统角色用户对照表 diff --git a/backend/src/main/java/com/yfd/platform/system/mapper/SysUserTenantMapper.java b/backend/src/main/java/com/yfd/platform/system/mapper/SysUserTenantMapper.java index f7961522..51365611 100644 --- a/backend/src/main/java/com/yfd/platform/system/mapper/SysUserTenantMapper.java +++ b/backend/src/main/java/com/yfd/platform/system/mapper/SysUserTenantMapper.java @@ -28,7 +28,7 @@ public interface SysUserTenantMapper extends BaseMapper { /** * 批量新增用户-门户关联 */ - int batchInsert(@Param("userId") String userId, @Param("tenantIds") List tenantIds); + int batchInsert(@Param("operator") String operator,@Param("userId") String userId, @Param("tenantIds") List tenantIds); /** * 查询某门户下的所有用户ID diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/SysOrganizationServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/SysOrganizationServiceImpl.java index e7681f67..c45d7c1a 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/SysOrganizationServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/SysOrganizationServiceImpl.java @@ -66,7 +66,8 @@ public class SysOrganizationServiceImpl extends ServiceImpl allowedOrgIds = new HashSet<>(); - if (userInfo.getUsertype() != 0) { + boolean superAdmin = userService.isSuperAdmin(userInfo.getId()); + if (userInfo.getUsertype() != 0 && !superAdmin) { List roleByUserId = sysRoleMapper.getRoleByUserId(userInfo.getId()); for (SysRole sysRole : roleByUserId) { String orgscope = sysRole.getOrgscope(); @@ -253,7 +254,8 @@ public class SysOrganizationServiceImpl extends ServiceImpl allowedOrgIds = new HashSet<>(); - if (userInfo.getUsertype() != 0) { + boolean superAdmin = userService.isSuperAdmin(userInfo.getId()); + if (userInfo.getUsertype() != 0 && !superAdmin) { List roleByUserId = sysRoleMapper.getRoleByUserId(userInfo.getId()); for (SysRole sysRole : roleByUserId) { String orgscope = sysRole.getOrgscope(); diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java index a53bc58f..3d59f975 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java @@ -20,6 +20,7 @@ import com.yfd.platform.qgc_base.mapper.SdRvcdDicMapper; import com.yfd.platform.system.domain.LoginUser; import com.yfd.platform.system.domain.SysRole; import com.yfd.platform.system.domain.SysUser; +import com.yfd.platform.system.domain.SysUserTenant; import com.yfd.platform.system.mapper.SysRoleMapper; import com.yfd.platform.system.mapper.SysUserMapper; import com.yfd.platform.system.mapper.SysUserTenantMapper; @@ -184,19 +185,24 @@ public class UserServiceImpl extends ServiceImpl impleme //系统生成id String id = IdUtil.fastSimpleUUID(); //新增sys_role_users表数据 - ok = ok && sysUserMapper.addUserRoles(id, roleid, - sysUser.getId()); + ok = ok && sysUserMapper.addUserRoles(SecurityUtils.getUserId(),id, roleid, sysUser.getId()); } } //判断新增是否成功 消息提示 if (ok) { // 插入用户-门户关联 - String tenantId = sysUser.getTenantId(); - if (StrUtil.isNotBlank(tenantId)) { - List tenantIds = new ArrayList<>(); - tenantIds.add(tenantId); - sysUserTenantMapper.batchInsert(sysUser.getId(), tenantIds); + List ids = StrUtil.split(roleids, ","); + if(!ids.isEmpty()) { + List selectedList = sysRoleMapper.selectList(new LambdaQueryWrapper().in(SysRole::getId, ids).select(SysRole::getTenantId)); + List tenantIds = selectedList.stream().map(SysRole::getTenantId).distinct().toList(); + sysUserTenantMapper.batchInsert(SecurityUtils.getUserId(), sysUser.getId(), tenantIds); } +// String tenantId = sysUser.getTenantId(); +// if (StrUtil.isNotBlank(tenantId)) { +// List tenantIds = new ArrayList<>(); +// tenantIds.add(tenantId); +// sysUserTenantMapper.batchInsert(SecurityUtils.getUserId(),sysUser.getId(), tenantIds); +// } result.put("status", "sucess"); result.put("msg", "新增用户成功!"); @@ -282,6 +288,14 @@ public class UserServiceImpl extends ServiceImpl impleme return result; } + // 根据角色给用户分配门户 + sysUserTenantMapper.deleteByUserId(sysUser.getId()); + if(StrUtil.isNotBlank(roleids)) { + List ids = StrUtil.split(roleids, ","); + List selectedList = sysRoleMapper.selectList(new LambdaQueryWrapper().in(SysRole::getId, ids).select(SysRole::getTenantId)); + List tenantIds = selectedList.stream().map(SysRole::getTenantId).distinct().toList(); + sysUserTenantMapper.batchInsert(SecurityUtils.getUserId(), sysUser.getId(), tenantIds); + } // 处理角色分配 String userId = sysUser.getId(); if (StrUtil.isNotEmpty(roleids)) { @@ -362,7 +376,7 @@ public class UserServiceImpl extends ServiceImpl impleme for (String roleId : newRoles) { if (!currentRoleSet.contains(roleId)) { String id = IdUtil.fastSimpleUUID(); - sysUserMapper.addUserRoles(id, roleId, userId); + sysUserMapper.addUserRoles(SecurityUtils.getUserId(),id, roleId, userId); } } @@ -419,7 +433,7 @@ public class UserServiceImpl extends ServiceImpl impleme //系统生成id String id = IdUtil.fastSimpleUUID(); //新增sys_role_users表数据 - isOk = isOk && sysUserMapper.addUserRoles(id, roleid, userid); + isOk = isOk && sysUserMapper.addUserRoles(SecurityUtils.getUserId(),id, roleid, userid); } } return isOk; @@ -594,7 +608,7 @@ public class UserServiceImpl extends ServiceImpl impleme //系统生成id String id = IdUtil.fastSimpleUUID(); //新增sys_role_users表数据 - isOk = sysUserMapper.addUserRoles(id, roleid, userid); + isOk = sysUserMapper.addUserRoles(SecurityUtils.getUserId(),id, roleid, userid); } return isOk; } @@ -952,7 +966,7 @@ public class UserServiceImpl extends ServiceImpl impleme if (StrUtil.isBlank(userId) || tenantIds == null || tenantIds.isEmpty()) { throw new RuntimeException("用户ID和门户ID列表不能为空"); } - sysUserTenantMapper.batchInsert(userId, tenantIds); + sysUserTenantMapper.batchInsert(SecurityUtils.getUserId(),userId, tenantIds); } /** @@ -980,9 +994,9 @@ public class UserServiceImpl extends ServiceImpl impleme public boolean isSuperAdmin(String userId) { -// String maxLevel = sysUserMapper.getMaxLevel(userId); + String maxLevel = sysUserMapper.getMaxLevel(userId); SysUser sysUser = sysUserMapper.selectById(userId); - return sysUser!=null && sysUser.getUsertype()==0; + return (sysUser!=null && sysUser.getUsertype()==0) || "1".equals(maxLevel); } } diff --git a/backend/src/main/java/com/yfd/platform/utils/DataSourceRequestUtil.java b/backend/src/main/java/com/yfd/platform/utils/DataSourceRequestUtil.java index 25b78886..1de686a1 100644 --- a/backend/src/main/java/com/yfd/platform/utils/DataSourceRequestUtil.java +++ b/backend/src/main/java/com/yfd/platform/utils/DataSourceRequestUtil.java @@ -92,6 +92,8 @@ public class DataSourceRequestUtil { List excludes = excludeFields != null ? excludeFields : new ArrayList<>(); + applySelect(request, wrapper, entityClass, fieldMapping, excludes); + applyFilters(request.getFilter(), wrapper, entityClass, fieldMapping, excludes, "and"); applySort(request.getSort(), wrapper, entityClass); @@ -145,6 +147,49 @@ public class DataSourceRequestUtil { return service.list(wrapper); } + /** + * 应用查询字段(select / distinctSelect) + * distinctSelect 优先于 select,并附带 DISTINCT 去重 + */ + private static void applySelect(DataSourceRequest request, + QueryWrapper wrapper, + Class entityClass, + Map fieldMapping, + List excludeFields) { + List selectFields = request.getSelect(); + boolean distinct = false; + if (CollectionUtil.isNotEmpty(request.getDistinctSelect())) { + selectFields = request.getDistinctSelect(); + distinct = true; + } + + if (CollectionUtil.isEmpty(selectFields)) { + return; + } + + List columns = new ArrayList<>(); + for (String field : selectFields) { + if (StrUtil.isBlank(field) || excludeFields.contains(field)) { + continue; + } + String columnName = getColumnName(field, entityClass, fieldMapping); + if (columnName != null) { + columns.add(columnName); + } + } + + if (columns.isEmpty()) { + return; + } + + String[] columnArray = columns.toArray(new String[0]); + if (distinct) { + // MyBatis-Plus 3.5.16 无 wrapper.distinct() 方法,在首个查询列前加 DISTINCT 关键字实现去重 + columnArray[0] = "DISTINCT " + columnArray[0]; + } + wrapper.select(columnArray); + } + private static void applyFilters(DataSourceRequest.FilterDescriptor filter, QueryWrapper wrapper, Class entityClass, diff --git a/backend/src/main/resources/mapper/system/SysRoleMapper.xml b/backend/src/main/resources/mapper/system/SysRoleMapper.xml index 8e56ec4f..63671f85 100644 --- a/backend/src/main/resources/mapper/system/SysRoleMapper.xml +++ b/backend/src/main/resources/mapper/system/SysRoleMapper.xml @@ -123,7 +123,7 @@ FROM sys_role_users WHERE userid = #{id} - + diff --git a/backend/src/main/resources/mapper/system/SysUserMapper.xml b/backend/src/main/resources/mapper/system/SysUserMapper.xml index 1e63e72f..a7c0bed3 100644 --- a/backend/src/main/resources/mapper/system/SysUserMapper.xml +++ b/backend/src/main/resources/mapper/system/SysUserMapper.xml @@ -29,7 +29,7 @@ - insert into sys_role_users values (#{id},#{roleid},#{userid}) + insert into sys_role_users(operator,id,roleid,userid) values (#{operator},#{id},#{roleid},#{userid}) diff --git a/backend/src/main/resources/mapper/system/SysUserTenantMapper.xml b/backend/src/main/resources/mapper/system/SysUserTenantMapper.xml index ce2a99c8..326a0a35 100644 --- a/backend/src/main/resources/mapper/system/SysUserTenantMapper.xml +++ b/backend/src/main/resources/mapper/system/SysUserTenantMapper.xml @@ -22,14 +22,15 @@ SELECT #{userId, jdbcType=VARCHAR} AS USER_ID, + #{operator} AS OPERATOR, #{tenantId, jdbcType=VARCHAR} AS TENANT_ID FROM DUAL ) S ON (T.USER_ID = S.USER_ID AND T.TENANT_ID = S.TENANT_ID) WHEN NOT MATCHED THEN - INSERT (ID, USER_ID, TENANT_ID) - VALUES (SYS_GUID(), S.USER_ID, S.TENANT_ID) + INSERT (ID, USER_ID, TENANT_ID, OPERATOR) + VALUES (SYS_GUID(), S.USER_ID, S.TENANT_ID, S.OPERATOR) From e29aea6b25aeaf3b0f3890977c60ca2925ee4858 Mon Sep 17 00:00:00 2001 From: tangwei Date: Tue, 4 Aug 2026 08:42:19 +0800 Subject: [PATCH 07/10] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yfd/platform/system/service/impl/SysMenuServiceImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/SysMenuServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/SysMenuServiceImpl.java index 7fe25ef3..32c2229b 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/SysMenuServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/SysMenuServiceImpl.java @@ -453,6 +453,9 @@ public class SysMenuServiceImpl extends ServiceImpl impl } else { sysMenuList = sysMenuMapper.selectMenuByUserId(id, tenantId); } + if (sysMenuList==null||sysMenuList.isEmpty()) { + throw new RuntimeException("无菜单"); + } // 将 SysMenu 转换为 Map 并构建树 List> list = sysMenuList.stream() .map(menu -> { From e49bdd2992c2c3dc6a8201d5894c0f4737a7f716 Mon Sep 17 00:00:00 2001 From: tangwei Date: Tue, 4 Aug 2026 10:56:13 +0800 Subject: [PATCH 08/10] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yfd/platform/config/SecurityConfig.java | 1 + .../controller/SmsVerifyCodeController.java | 67 +++++++++++-------- .../system/controller/SysRoleController.java | 15 +++++ .../system/service/ISysRoleService.java | 9 +++ .../service/impl/SysRoleServiceImpl.java | 66 +++++++++++++++++- .../system/service/impl/UserServiceImpl.java | 13 +++- .../resources/mapper/system/SysUserMapper.xml | 2 +- 7 files changed, 140 insertions(+), 33 deletions(-) diff --git a/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java b/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java index 0833307f..7a0f3060 100644 --- a/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java +++ b/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java @@ -63,6 +63,7 @@ public class SecurityConfig { .requestMatchers("/data/fishDraft/previewFile").permitAll() .requestMatchers("/tempFile/**").permitAll() .requestMatchers("/system/user/auditUser").permitAll() + .requestMatchers("/register/accessToken").permitAll() .requestMatchers("/api/oauth2/oauth/token").permitAll() .requestMatchers("/dict/cache/**").permitAll() .requestMatchers("/sys/psbmodulelbb/**").permitAll() diff --git a/backend/src/main/java/com/yfd/platform/system/controller/SmsVerifyCodeController.java b/backend/src/main/java/com/yfd/platform/system/controller/SmsVerifyCodeController.java index 4b58e319..f3f93d22 100644 --- a/backend/src/main/java/com/yfd/platform/system/controller/SmsVerifyCodeController.java +++ b/backend/src/main/java/com/yfd/platform/system/controller/SmsVerifyCodeController.java @@ -2,6 +2,7 @@ package com.yfd.platform.system.controller; import cn.hutool.json.JSONUtil; import cn.hutool.jwt.JWTUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.yfd.platform.config.ResponseResult; import com.yfd.platform.config.WebConfig; import com.yfd.platform.qgc_data.domain.SysUserDataScope; @@ -11,6 +12,8 @@ import com.yfd.platform.qgc_base.service.ISdEngInfoBHService; import com.yfd.platform.qgc_base.service.ISdHbrvDicService; import com.yfd.platform.system.domain.*; import com.yfd.platform.system.mapper.SysMenuMapper; +import com.yfd.platform.system.mapper.SysOrganizationMapper; +import com.yfd.platform.system.mapper.SysRoleMapper; import com.yfd.platform.system.mapper.SysUserTenantMapper; import com.yfd.platform.system.service.ISmsVerifyCodeService; import com.yfd.platform.system.service.ISysLogService; @@ -61,6 +64,12 @@ public class SmsVerifyCodeController { @Resource private SysMenuMapper sysMenuMapper; + @Resource + private SysOrganizationMapper organizationMapper; + + @Resource + private SysRoleMapper roleMapper; + @Resource private ISysUserDataScopeService sysUserDataScopeService; @@ -77,14 +86,14 @@ public class SmsVerifyCodeController { @Value("${rsa.private_key}") private String privateKey; - private static final String URGE_CONTENT ="根据生态环境部要求,请贵电站尽快完成过鱼数据的报送工作,感谢支持。"; + private static final String URGE_CONTENT = "根据生态环境部要求,请贵电站尽快完成过鱼数据的报送工作,感谢支持。"; /** * 发送验证码 */ @PostMapping("/sendCode") @Operation(summary = "发送验证码") - public ResponseResult sendVerifyCode(@RequestHeader(value = "Tenant_id", required = false) String tenantId,@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { + public ResponseResult sendVerifyCode(@RequestHeader(value = "Tenant_id", required = false) String tenantId, @RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { String phone = smsVerifyCodeRequest.getPhone(); Integer type = smsVerifyCodeRequest.getType(); @@ -97,21 +106,21 @@ public class SmsVerifyCodeController { // 1. 注册验证码校验 if (type.equals(SmsVerifyCode.TYPE_REGISTER)) { - SysUser existUser = userService.getUserByPhone(phone,tenantId); + SysUser existUser = userService.getUserByPhone(phone, tenantId); if (existUser != null) { return ResponseResult.error("该手机号已注册"); } } // 2. 找回密码验证码校验 else if (type.equals(SmsVerifyCode.TYPE_FIND_PASSWORD)) { - SysUser existUser = userService.getUserByPhone(phone,tenantId); + SysUser existUser = userService.getUserByPhone(phone, tenantId); if (existUser == null) { return ResponseResult.error("该手机号未注册"); } } // 3. 登录验证码校验(新增) else if (type.equals(SmsVerifyCode.TYPE_LOGIN)) { - SysUser existUser = userService.getUserByPhone(phone,tenantId); + SysUser existUser = userService.getUserByPhone(phone, tenantId); if (existUser == null) { return ResponseResult.error("该手机号未注册,请先注册"); } @@ -119,12 +128,11 @@ public class SmsVerifyCodeController { // if (existUser.getStatus() == 0) { // return ResponseResult.error("账号已被禁用"); // } - } - else { + } else { return ResponseResult.error("类型错误:1-注册 2-找回密码 3-登录"); } - String code = smsVerifyCodeService.sendVerifyCode(phone, type,tenantId); + String code = smsVerifyCodeService.sendVerifyCode(phone, type, tenantId); if (code == null) { return ResponseResult.error("验证码发送失败,请稍后重试"); } @@ -138,10 +146,10 @@ public class SmsVerifyCodeController { */ @PostMapping("/batchSendContent") @Operation(summary = "批量发送短信") - public ResponseResult batchSendContent(@RequestHeader(value = "Tenant_id", required = false) String tenantId,@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { + public ResponseResult batchSendContent(@RequestHeader(value = "Tenant_id", required = false) String tenantId, @RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { List phoneList = smsVerifyCodeRequest.getPhoneList(); - if(phoneList==null){ + if (phoneList == null) { return ResponseResult.error("手机号不能为空"); } @@ -154,7 +162,7 @@ public class SmsVerifyCodeController { */ @PostMapping("/batchUrgeContent") @Operation(summary = "催促") - public ResponseResult batchUrgeContent(@RequestHeader(value = "Tenant_id", required = false) String tenantId,@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { + public ResponseResult batchUrgeContent(@RequestHeader(value = "Tenant_id", required = false) String tenantId, @RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { List userIds = smsVerifyCodeRequest.getUserIds(); String content = smsVerifyCodeRequest.getContent(); @@ -167,7 +175,7 @@ public class SmsVerifyCodeController { } try { - int successCount = smsVerifyCodeService.urgeByUserIds(tenantId,userIds, content); + int successCount = smsVerifyCodeService.urgeByUserIds(tenantId, userIds, content); Map result = new HashMap<>(); // result.put("successCount", successCount); result.put("totalCount", userIds.size()); @@ -179,14 +187,13 @@ public class SmsVerifyCodeController { } - /** * 注册用户 */ @PostMapping("/register") @Operation(summary = "注册用户") @Transactional(rollbackFor = Exception.class) - public ResponseResult register(@RequestHeader(value = "Tenant_id", required = false) String tenantId,@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { + public ResponseResult register(@RequestHeader(value = "Tenant_id", required = false) String tenantId, @RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { String code = smsVerifyCodeRequest.getCode(); if (smsVerifyCodeRequest.getPhone() == null || smsVerifyCodeRequest.getPhone().isEmpty()) { return ResponseResult.error("手机号不能为空"); @@ -201,12 +208,12 @@ public class SmsVerifyCodeController { return ResponseResult.error("验证码不能为空"); } - boolean verified = smsVerifyCodeService.verifyCode(smsVerifyCodeRequest.getPhone(), code, SmsVerifyCode.TYPE_REGISTER,tenantId); + boolean verified = smsVerifyCodeService.verifyCode(smsVerifyCodeRequest.getPhone(), code, SmsVerifyCode.TYPE_REGISTER, tenantId); if (!verified) { return ResponseResult.error("验证码错误或已过期"); } - SysUser existUser = userService.getUserByPhone(smsVerifyCodeRequest.getPhone(),tenantId); + SysUser existUser = userService.getUserByPhone(smsVerifyCodeRequest.getPhone(), tenantId); if (existUser != null) { return ResponseResult.error("该手机号已注册"); } @@ -218,13 +225,15 @@ public class SmsVerifyCodeController { } catch (Exception e) { return ResponseResult.error("密码解密失败"); } + SysOrganization aDefault = organizationMapper.selectOne(new LambdaQueryWrapper().eq(SysOrganization::getCustom1, "default")); + String orgid = aDefault == null ? null : aDefault.getId(); user.setRegStatus("PENDING"); user.setPhone(smsVerifyCodeRequest.getPhone()); user.setBelongingUnit(smsVerifyCodeRequest.getBelongingUnit()); user.setRegTime(new Date()); user.setNickname(smsVerifyCodeRequest.getRealName()); user.setStatus(0); - user.setOrgid("e90063ced25e3d469860e88d920c082f"); + user.setOrgid(orgid); user.setUsertype(1); user.setTenantId(tenantId); user.setUsername(smsVerifyCodeRequest.getUsername()); @@ -232,7 +241,7 @@ public class SmsVerifyCodeController { user.setCompanyCode(smsVerifyCodeRequest.getCompanyCode()); boolean success = userService.save(user); // 给注册用户加上默认权限 - SysUser savedUser = userService.getUserByPhone(smsVerifyCodeRequest.getPhone(),tenantId); + SysUser savedUser = userService.getUserByPhone(smsVerifyCodeRequest.getPhone(), tenantId); if (savedUser != null) { SysUserTenant sysUserTenant = new SysUserTenant(); sysUserTenant.setTenantId(tenantId); @@ -340,8 +349,10 @@ public class SmsVerifyCodeController { // sysUserDataScopeService.addDataScope(scope); // } SysUser user = new SysUser(); + SysRole aDefault = roleMapper.selectOne(new LambdaQueryWrapper().eq(SysRole::getCustom1, "default")); + String roleids = aDefault == null ? null : aDefault.getId(); user.setId(userId); - userService.updateUserRoles( user,"c13481a486c9ee559cf305284df4d207"); + userService.updateUserRoles(user, roleids); // 加上角色权限 return true; } @@ -351,7 +362,7 @@ public class SmsVerifyCodeController { */ @PostMapping("/resetPassword") @Operation(summary = "找回密码") - public ResponseResult resetPassword(@RequestHeader(value = "Tenant_id", required = false) String tenantId,@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { + public ResponseResult resetPassword(@RequestHeader(value = "Tenant_id", required = false) String tenantId, @RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { String password = smsVerifyCodeRequest.getPassword(); String phone = smsVerifyCodeRequest.getPhone(); String code = smsVerifyCodeRequest.getCode(); @@ -365,12 +376,12 @@ public class SmsVerifyCodeController { return ResponseResult.error("新密码不能为空"); } - boolean verified = smsVerifyCodeService.verifyCode(phone, code, SmsVerifyCode.TYPE_FIND_PASSWORD,tenantId); + boolean verified = smsVerifyCodeService.verifyCode(phone, code, SmsVerifyCode.TYPE_FIND_PASSWORD, tenantId); if (!verified) { return ResponseResult.error("验证码错误或已过期"); } - SysUser existUser = userService.getUserByPhone(phone,tenantId); + SysUser existUser = userService.getUserByPhone(phone, tenantId); if (existUser == null) { return ResponseResult.error("该手机号未注册"); } @@ -395,11 +406,11 @@ public class SmsVerifyCodeController { */ @PostMapping("/verifyCode") @Operation(summary = "验证验证码") - public ResponseResult verifyCode(@RequestHeader(value = "Tenant_id", required = false) String tenantId,@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { + public ResponseResult verifyCode(@RequestHeader(value = "Tenant_id", required = false) String tenantId, @RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { String phone = smsVerifyCodeRequest.getPhone(); String code = smsVerifyCodeRequest.getCode(); Integer type = smsVerifyCodeRequest.getType(); - boolean valid = smsVerifyCodeService.verifyCode(phone, code, type,tenantId); + boolean valid = smsVerifyCodeService.verifyCode(phone, code, type, tenantId); if (valid) { return ResponseResult.success(); } else { @@ -412,7 +423,7 @@ public class SmsVerifyCodeController { */ @PostMapping("/login") @Operation(summary = "短信验证码登录") - public ResponseResult smsLogin(@RequestHeader(value = "Tenant_id", required = false) String tenantId,@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { + public ResponseResult smsLogin(@RequestHeader(value = "Tenant_id", required = false) String tenantId, @RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { String phone = smsVerifyCodeRequest.getPhone(); String code = smsVerifyCodeRequest.getCode(); if (phone == null || phone.isEmpty()) { @@ -422,12 +433,12 @@ public class SmsVerifyCodeController { return ResponseResult.error("验证码不能为空"); } - boolean verified = smsVerifyCodeService.verifyCode(phone, code, SmsVerifyCode.TYPE_LOGIN,tenantId); + boolean verified = smsVerifyCodeService.verifyCode(phone, code, SmsVerifyCode.TYPE_LOGIN, tenantId); if (!verified) { return ResponseResult.error("验证码错误或已过期"); } - SysUser user = userService.getUserByPhone(phone,tenantId); + SysUser user = userService.getUserByPhone(phone, tenantId); if (user == null) { return ResponseResult.error("该手机号未注册"); } @@ -461,7 +472,7 @@ public class SmsVerifyCodeController { } else { permissions = sysMenuMapper.selectPermsByUserId(user.getId(), tenantId); } - loginUser.setPermissions( permissions); + loginUser.setPermissions(permissions); HttpServletRequest request = RequestHolder.getHttpServletRequest(); SysLog sysLog = new SysLog(); sysLog.setUsercode(user.getUsername()); diff --git a/backend/src/main/java/com/yfd/platform/system/controller/SysRoleController.java b/backend/src/main/java/com/yfd/platform/system/controller/SysRoleController.java index 3570aef8..cf264e46 100644 --- a/backend/src/main/java/com/yfd/platform/system/controller/SysRoleController.java +++ b/backend/src/main/java/com/yfd/platform/system/controller/SysRoleController.java @@ -58,6 +58,21 @@ public class SysRoleController { return roleService.selectRoleList(rolename, tenantId); } + /*********************************** + * 用途说明:按门户分组查询角色(门户 → 角色两层结构) + * 参数说明 + * rolename 角色名称(可选,模糊搜索) + * 返回值说明: [{"tenantId":"...","tenantName":"水利门户","roles":[...]}, ...] + * 门户中文名通过字典 PLATFORM_TENANT 获取 + ***********************************/ + @PostMapping("/listGroupedByTenant") + @Operation(summary = "按门户分组查询角色(含门户中文名)") + @ResponseBody + public List> listGroupedByTenant(@RequestParam(required = false) String rolename, + @RequestParam(required = false) String tenantId) { + return roleService.selectRoleListGroupedByTenant(tenantId,rolename); + } + /*********************************** * 用途说明:根据Id获取当个角色 * 参数说明 diff --git a/backend/src/main/java/com/yfd/platform/system/service/ISysRoleService.java b/backend/src/main/java/com/yfd/platform/system/service/ISysRoleService.java index 244983bf..1b6f25e1 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/ISysRoleService.java +++ b/backend/src/main/java/com/yfd/platform/system/service/ISysRoleService.java @@ -67,4 +67,13 @@ public interface ISysRoleService extends IService { List selectRoleList(String rolename, String tenantId); List queryRolesList(String roleName, String tenantId); + + /*********************************** + * 用途说明:按门户分组查询角色(门户 → 角色两层结构) + * 参数说明 + * rolename 角色名称(可选,模糊搜索) + * 返回值说明: [{"tenantId":"...","tenantName":"水利门户","roles":[...]}, ...] + * 门户中文名通过字典 PLATFORM_TENANT 获取 + ***********************************/ + List> selectRoleListGroupedByTenant(String tenantId,String rolename); } diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/SysRoleServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/SysRoleServiceImpl.java index 97908d08..5135292e 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/SysRoleServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/SysRoleServiceImpl.java @@ -6,8 +6,12 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.yfd.platform.config.ResponseResult; +import com.yfd.platform.system.domain.SysDictionary; +import com.yfd.platform.system.domain.SysDictionaryItems; import com.yfd.platform.system.domain.SysRole; import com.yfd.platform.system.mapper.SysRoleMapper; +import com.yfd.platform.system.service.ISysDictionaryItemsService; +import com.yfd.platform.system.service.ISysDictionaryService; import com.yfd.platform.system.service.ISysRoleService; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; @@ -16,8 +20,7 @@ import org.springframework.transaction.annotation.Transactional; import jakarta.annotation.Resource; import java.sql.Timestamp; import java.text.DecimalFormat; -import java.util.List; -import java.util.Map; +import java.util.*; /** *

@@ -37,6 +40,12 @@ public class SysRoleServiceImpl extends ServiceImpl impl @Resource private UserServiceImpl currentuser; + @Resource + private ISysDictionaryService sysDictionaryService; + + @Resource + private ISysDictionaryItemsService sysDictionaryItemsService; + /*********************************** * 用途说明:新增角色 * 参数说明 @@ -185,4 +194,57 @@ public class SysRoleServiceImpl extends ServiceImpl impl return sysRoleList; } + /*********************************** + * 用途说明:按门户分组查询角色(门户 → 角色两层结构) + * 参数说明 + * rolename 角色名称(可选,模糊搜索) + * 返回值说明: [{"tenantId":"...","tenantName":"水利门户","roles":[...]}, ...] + * 门户中文名通过字典 PLATFORM_TENANT 获取 + ***********************************/ + @Override + public List> selectRoleListGroupedByTenant(String tenantId,String rolename) { + // 1. 查询所有角色(排除超级管理员级别,支持角色名称模糊搜索) + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysRole::getTenantId, tenantId); + queryWrapper.like(StrUtil.isNotBlank(rolename), SysRole::getRolename, rolename); +// queryWrapper.ne(SysRole::getLevel, "1"); + queryWrapper.orderByAsc(SysRole::getTenantId).orderByAsc(SysRole::getLevel); + List roleList = this.list(queryWrapper); + + // 2. 查询 PLATFORM_TENANT 字典项,构建 tenantId → tenantName 映射 + Map tenantNameMap = new HashMap<>(); + SysDictionary tenantDict = sysDictionaryService.getByDictCode("PLATFORM_TENANT"); + if (tenantDict != null) { + List items = sysDictionaryItemsService.list(new LambdaQueryWrapper().eq(SysDictionaryItems::getDictId, tenantDict.getId()).eq(StrUtil.isNotBlank(tenantId),SysDictionaryItems::getItemCode, tenantId).select(SysDictionaryItems::getItemCode, SysDictionaryItems::getDictName)); + if (items != null) { + for (SysDictionaryItems item : items) { + if (StrUtil.isNotBlank(item.getItemCode())) { + tenantNameMap.put(item.getItemCode(), item.getDictName()); + } + } + } + } + + // 3. 按 tenantId 分组(跳过无门户的角色) + Map> grouped = new LinkedHashMap<>(); + for (SysRole role : roleList) { + String code = role.getTenantId(); + if (StrUtil.isBlank(code)) { + continue; + } + grouped.computeIfAbsent(code, k -> new ArrayList<>()).add(role); + } + + // 4. 组装两层结构:门户 → 角色 + List> result = new ArrayList<>(); + for (Map.Entry> entry : grouped.entrySet()) { + Map group = new HashMap<>(); + group.put("tenantId", entry.getKey()); + group.put("tenantName", tenantNameMap.getOrDefault(entry.getKey(), entry.getKey())); + group.put("roles", entry.getValue()); + result.add(group); + } + return result; + } + } diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java index 3d59f975..96172af7 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java @@ -371,12 +371,21 @@ public class UserServiceImpl extends ServiceImpl impleme // 解析新角色列表 String[] newRoles = roleIds.split(","); - + String operator; + try { + operator = SecurityUtils.getUserId(); + } catch (Exception e) { + // 记录日志,方便排查 + log.error("获取当前用户ID失败", e); + // 根据业务需求处理:可返回默认值、抛出业务异常或置空 + operator = null; // 或 "anonymous" 等默认值 + } // 需要新增的角色(新角色 - 当前角色) for (String roleId : newRoles) { if (!currentRoleSet.contains(roleId)) { String id = IdUtil.fastSimpleUUID(); - sysUserMapper.addUserRoles(SecurityUtils.getUserId(),id, roleId, userId); + + sysUserMapper.addUserRoles(operator,id, roleId, userId); } } diff --git a/backend/src/main/resources/mapper/system/SysUserMapper.xml b/backend/src/main/resources/mapper/system/SysUserMapper.xml index a7c0bed3..8ba9cf6e 100644 --- a/backend/src/main/resources/mapper/system/SysUserMapper.xml +++ b/backend/src/main/resources/mapper/system/SysUserMapper.xml @@ -88,7 +88,7 @@ and (ut.TENANT_ID = #{tenantId} OR u.tenant_id = #{tenantId}) - ORDER BY u.lastmodifydate DESC + ORDER BY u.username