diff --git a/src/main/java/com/yunhai/userhome/controller/api/UserController.java b/src/main/java/com/yunhai/userhome/controller/api/UserController.java
index 8e3b649..b0540bd 100644
--- a/src/main/java/com/yunhai/userhome/controller/api/UserController.java
+++ b/src/main/java/com/yunhai/userhome/controller/api/UserController.java
@@ -78,13 +78,13 @@ public class UserController {
* 当前用户可访问的应用全集(跨仓 UserBase 实时拉取,按应用类型分组)。
* 前端据此:渲染分类 tab(含「全部」)+ 图标网格;常用区由 getUsedApp 独立提供。
*
- * @param schId 兼容旧前端入参(yh-platform getUserApp 当前按 userId 全局权限过滤,schId 暂不参与)
+ * @param schId 学校上下文:透传 UserBase 按该校单点开通集合收窄(为空则由服务端按当前身份/主归属学校兜底)
* @param userId 指定用户(缺省用登录用户)
*/
@GetMapping("GetUserApp")
public JsonNode getUserApp(BoaUser authUserWithDept, Integer schId,
@RequestParam(name = "userId", required = false) Integer userId) {
- return withIconKeys(appRemoteService.getUserApps(authUserWithDept));
+ return withIconKeys(appRemoteService.getUserApps(authUserWithDept, schId));
}
/**
@@ -119,10 +119,15 @@ public class UserController {
return root;
}
- /** 按应用ID取单个应用(在已拉取全集中查找,免额外跨仓请求)。 */
+ /**
+ * 按应用ID取单个应用(在已拉取全集中查找,免额外跨仓请求)。
+ * schId 透传(可选):与 GetUserApp 同口径按学校收窄全集,避免「列表已收窄、单个查询仍全集」的不一致;
+ * 为空则由 UserBase 按当前身份/主归属学校兜底。
+ */
@GetMapping("GetAppInfoById")
- public BoaApp getAppInfoById(BoaUser authUserWithDept, @RequestParam(name = "id", required = false) Integer id) {
- return appRemoteService.getAppById(authUserWithDept, id).orElse(null);
+ public BoaApp getAppInfoById(BoaUser authUserWithDept, Integer schId,
+ @RequestParam(name = "id", required = false) Integer id) {
+ return appRemoteService.getAppById(authUserWithDept, id, schId).orElse(null);
}
/** 当前用户角色身份列表(跨仓 UserBase,含 学校/角色/子节点)。 */
diff --git a/src/main/java/com/yunhai/userhome/service/AppRemoteService.java b/src/main/java/com/yunhai/userhome/service/AppRemoteService.java
index e9b4278..6dc3ee2 100644
--- a/src/main/java/com/yunhai/userhome/service/AppRemoteService.java
+++ b/src/main/java/com/yunhai/userhome/service/AppRemoteService.java
@@ -16,9 +16,31 @@ import java.util.Optional;
*/
public interface AppRemoteService {
- /** 取当前用户可访问的应用全集(按应用类型分组,BoaAppType.id/name/apps)。 */
+ /**
+ * 取当前用户可访问的应用全集(按应用类型分组,BoaAppType.id/name/apps)。
+ * 不带学校上下文:由 UserBase 侧按「当前激活身份学校 → 主归属学校」兜底推导生效学校。
+ */
List getUserApps(BoaUser user);
+ /**
+ * 按学校上下文取用户可访问应用全集(2026-10-12 学校单点开通硬闸门贯通)。
+ * {@code schoolId} 非空 → UserBase 按该校自身单点开通集合收窄;为空 → 服务端按身份/主归属兜底。
+ *
+ * @param user 登录用户
+ * @param schoolId 学校上下文(可为 null)
+ */
+ List getUserApps(BoaUser user, Integer schoolId);
+
/** 按应用ID取单个应用(在已拉取的全集中查找,避免额外跨仓请求)。 */
Optional getAppById(BoaUser user, Integer appId);
+
+ /**
+ * 按应用ID取单个应用,并按学校上下文收窄全集(与 {@link #getUserApps(BoaUser, Integer)} 同口径,
+ * 避免「列表已按校收窄、单个查询仍全集」的不一致)。
+ *
+ * @param user 登录用户
+ * @param appId 应用ID
+ * @param schoolId 学校上下文(可为 null)
+ */
+ Optional getAppById(BoaUser user, Integer appId, Integer schoolId);
}
diff --git a/src/main/java/com/yunhai/userhome/service/impl/OpenApiAppRemoteServiceImpl.java b/src/main/java/com/yunhai/userhome/service/impl/OpenApiAppRemoteServiceImpl.java
index 3817fb2..f6361a2 100644
--- a/src/main/java/com/yunhai/userhome/service/impl/OpenApiAppRemoteServiceImpl.java
+++ b/src/main/java/com/yunhai/userhome/service/impl/OpenApiAppRemoteServiceImpl.java
@@ -21,19 +21,29 @@ public class OpenApiAppRemoteServiceImpl implements AppRemoteService {
@Override
public List getUserApps(BoaUser user) {
+ return getUserApps(user, null);
+ }
+
+ @Override
+ public List getUserApps(BoaUser user, Integer schoolId) {
if (user == null || user.getId() == null) {
return Collections.emptyList();
}
- // PC 浏览器端;UserBase 侧已按 userId 权限过滤(组开通 ∪ 角色模块所属应用,超管全量)
- return YschBaseOpenApi.getUserApp(user.getId(), ClientEnum.PC_BROWSER);
+ // PC 浏览器端;schoolId 透传 UserBase 做学校单点开通收窄(为空则服务端按身份/主归属兜底)
+ return YschBaseOpenApi.getUserApp(user.getId(), ClientEnum.PC_BROWSER, schoolId);
}
@Override
public Optional getAppById(BoaUser user, Integer appId) {
+ return getAppById(user, appId, null);
+ }
+
+ @Override
+ public Optional getAppById(BoaUser user, Integer appId, Integer schoolId) {
if (appId == null) {
return Optional.empty();
}
- return getUserApps(user).stream()
+ return getUserApps(user, schoolId).stream()
.filter(t -> t.getApps() != null)
.flatMap(t -> t.getApps().stream())
.filter(a -> appId.equals(a.getId()))