diff --git a/src/main/java/com/yunhai/userbase/controller/oapi/UserController.java b/src/main/java/com/yunhai/userbase/controller/oapi/UserController.java
index fe7c534..7cb6226 100644
--- a/src/main/java/com/yunhai/userbase/controller/oapi/UserController.java
+++ b/src/main/java/com/yunhai/userbase/controller/oapi/UserController.java
@@ -10,6 +10,7 @@ import com.yunhai.platform.utils.model.BoaUser;
import com.yunhai.userbase.common.annotation.OapiLog;
import com.yunhai.userbase.common.validation.ValidationGroups;
import com.yunhai.userbase.config.Config;
+import com.yunhai.userbase.entity.ApplicationInfo;
import com.yunhai.userbase.model.sysuser.BatchChangeStatusRequest;
import com.yunhai.userbase.model.sysuser.SysUserChangeStatusRequest;
import com.yunhai.userbase.model.sysuser.SysUserContactRequest;
@@ -91,30 +92,49 @@ public class UserController {
}
/**
- * 查询用户在调用方应用下、指定学校(上下文)里的已授权模块列表。
+ * 查询用户在指定应用下、指定学校(上下文)里的已授权模块列表。
*
- * 与管理端「权限一览」返回全应用聚合不同,本方法严格按调用方应用维度过滤:
- * ① 通过 {@link AppAuthFilter#APP_AUTH_ATTR} 拿到验签时的 appKey(RequireAppSignFilter
- * 已保证非空);
- * ② 查 application_info 映射到具体 appId;
+ * 与管理端「权限一览」返回全应用聚合不同,本方法严格按单一应用维度过滤。应用来源两态:
+ * ① 传了可选参数 appCode → 按 application_info.app_code 解析目标应用(供托管型应用
+ * 如 form-center 代快应用渲染导航时查询目标应用的模块清单;查不到返回空列表并 warn,
+ * 口径同现有兜底);
+ * ② 未传 appCode → 现行为不变:通过 {@link AppAuthFilter#APP_AUTH_ATTR} 拿到验签时的
+ * appKey(RequireAppSignFilter 已保证非空),查 application_info 映射到具体 appId;
* ③ 调 Service 专用方法:所有 SQL/集合构建均限定在该 appId 范围内(数据库层面过滤)。
*
- * 边界:调用方 appKey 查不到对应应用 → 直接返回空列表(安全优先,禁止意外返回其他应用的模块)。
+ * 边界:应用解析失败(appCode/appKey 查不到对应应用)→ 直接返回空列表(安全优先,禁止意外
+ * 返回其他应用的模块)。
+ * 记账:本参数暴露面=模块名/路径/图标级低敏数据;如需收紧可后续限定仅 BASE 应用调用
+ * (暂放开,表单中心建设方案 §6.2 已记)。参数用 appCode(字符串)而非整数 appKey:
+ * 跨环境稳定,与 form-center 分发路由 /app/{appCode}/ 同键。
*
- * @param request 用于取 AppAuthFilter 设置的 appKey
+ * @param request 用于取 AppAuthFilter 设置的 appKey(未传 appCode 时使用)
* @param userId 用户ID(必填)
* @param schId 学校ID/组ID(可选;用于限定「学校上下文」:非空时仅取该学校子树内的真实归属组参与判定,
* 为空时取用户全部真实归属组,与权限一览一致)
+ * @param appCode 目标应用技术标识(可选;传=查该应用的模块树,不传=按签名调用方解析)
* @return 该应用下用户已授权模块(扁平化;无权限时返回空列表)
*/
@GetMapping("modules")
public List modules(HttpServletRequest request,
@RequestParam("userId") Integer userId,
- @RequestParam(value = "schId", required = false) Integer schId) {
+ @RequestParam(value = "schId", required = false) Integer schId,
+ @RequestParam(value = "appCode", required = false) String appCode) {
if (userId == null) {
return Collections.emptyList();
}
- Integer appId = resolveCallerAppId(request);
+ Integer appId;
+ if (appCode != null && !appCode.trim().isEmpty()) {
+ ApplicationInfo app = applicationInfoService.getByAppCode(appCode.trim());
+ if (app == null) {
+ log.warn("[oapi:user:modules] appCode={} not found in application_info, uri={}",
+ appCode, request.getRequestURI());
+ return Collections.emptyList();
+ }
+ appId = app.getId();
+ } else {
+ appId = resolveCallerAppId(request);
+ }
if (appId == null) {
return Collections.emptyList();
}