修改推送日志功能
This commit is contained in:
@@ -96,7 +96,8 @@ public class UserController {
|
||||
*
|
||||
* @param request 用于取 AppAuthFilter 设置的 appKey
|
||||
* @param userId 用户ID(必填)
|
||||
* @param schId 学校ID/组ID(可选;为 null 时按"主学校→主归属组"规则推断)
|
||||
* @param schId 学校ID/组ID(可选;用于限定「学校上下文」:非空时仅取该学校子树内的真实归属组参与判定,
|
||||
* 为空时取用户全部真实归属组,与权限一览一致)
|
||||
* @return 该应用下用户已授权模块(扁平化;无权限时返回空列表)
|
||||
*/
|
||||
@GetMapping("modules")
|
||||
|
||||
@@ -38,6 +38,8 @@ public class SysOapiLogListVo {
|
||||
private String operationDesc;
|
||||
/** 请求参数JSON(脱敏后) */
|
||||
private String requestParams;
|
||||
/** 响应结果(GZIP 解压后原文,脱敏后;随列表带出,详情弹窗直接展示) */
|
||||
private String responseData;
|
||||
/** HTTP 状态码 */
|
||||
private Integer statusCode;
|
||||
/** 耗时(ms) */
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
package com.yunhai.userbase.service.impl;
|
||||
|
||||
import com.yunhai.platform.utils.exception.DException;
|
||||
import com.yunhai.platform.utils.model.BoaGroup;
|
||||
import com.yunhai.platform.utils.model.BoaModule;
|
||||
import com.yunhai.platform.utils.model.BoaUser;
|
||||
import com.yunhai.userbase.entity.*;
|
||||
import com.yunhai.userbase.enums.GroupTypeEnum;
|
||||
import com.yunhai.platform.utils.enums.IEnum;
|
||||
@@ -104,9 +102,6 @@ public class GroupAuthzService implements IGroupAuthzService {
|
||||
@Autowired
|
||||
private SysUserAppRoleRelRepository sysUserAppRoleRelRepository;
|
||||
|
||||
@Autowired
|
||||
private UserCenterService userCenterService;
|
||||
|
||||
// ===================== 新增:沿祖先链收集「本组+所有祖先组开通的应用ID并集」(应用池联动GetSchoolAppId)
|
||||
// =====================
|
||||
|
||||
@@ -523,23 +518,43 @@ public class GroupAuthzService implements IGroupAuthzService {
|
||||
}
|
||||
// 3. 收集该用户启用角色下=属于目标应用的模块ID(角色授权并集,不要求组先开通应用)
|
||||
Set<Integer> roleModuleIdsInApp = collectEnabledRoleModuleIdsForApp(userId, appId);
|
||||
// 4. 上下文组解析(schId 非空=只认这一条链路;schId 空=按"主学校→主归属组"规则推断)
|
||||
Integer effectiveGroupId = resolveEffectiveGroupId(userId, schId);
|
||||
// 5. 若上下文组有效=构建其祖先链,并判定:该祖先链开通池里是否包含目标 appId(应用开通闸门)
|
||||
// 上下文组无效(用户无学校/无组)时,仍可能因角色授权而返回模块,不能直接返回空
|
||||
Set<Integer> selfGroupIds = new LinkedHashSet<>();
|
||||
// 4. 归属组集合解析(与权限一览 findUserPermissionTree 语义对齐,修复"只返回学校节点"的 bug):
|
||||
// - schId 非空:只取用户真实归属组中「位于该学校子树内」的组(含直接挂学校组本身),
|
||||
// 每个组独立建链向上判定;子树内无任何归属组 → 保留空 selfGroupIds(方案A:仅靠角色授权拿模块,
|
||||
// 不把 schId 冒充本组,否则会绕过子组继承闸门、丢本组数据);
|
||||
// - schId 空:取用户全部真实归属组(与权限一览「用户全局模式」一致)。
|
||||
List<SysUserGroupRel> userRels = sysUserGroupRelRepository.findByUserId(userId);
|
||||
Map<Integer, SysGroup> allGroupMap = buildAllGroupMap();
|
||||
Set<Integer> selfGroupIds = new LinkedHashSet<>();
|
||||
if (schId != null) {
|
||||
for (SysUserGroupRel rel : userRels) {
|
||||
Integer gid = rel.getGroupId();
|
||||
if (gid == null) {
|
||||
continue;
|
||||
}
|
||||
if (gid.equals(schId) || ancestorChain(gid, allGroupMap).contains(schId)) {
|
||||
selfGroupIds.add(gid);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (SysUserGroupRel rel : userRels) {
|
||||
if (rel.getGroupId() != null) {
|
||||
selfGroupIds.add(rel.getGroupId());
|
||||
}
|
||||
}
|
||||
}
|
||||
// 5. 构建各归属组的祖先链与开通池,并判定:任意归属组开通池里是否包含目标 appId(应用开通闸门)。
|
||||
// 归属组为空(该学校子树内无组 / 无学校无组)时仍可能因角色授权而返回模块,不能直接返回空。
|
||||
Map<Integer, List<Integer>> chainMap = new HashMap<>();
|
||||
Set<Integer> allChainIds = new LinkedHashSet<>();
|
||||
Map<Integer, Set<Integer>> groupToApps = new HashMap<>();
|
||||
boolean appOpened = false;
|
||||
if (effectiveGroupId != null) {
|
||||
selfGroupIds.add(effectiveGroupId);
|
||||
List<Integer> chain = ancestorChain(effectiveGroupId, allGroupMap);
|
||||
chainMap.put(effectiveGroupId, chain);
|
||||
for (Integer gid : selfGroupIds) {
|
||||
List<Integer> chain = ancestorChain(gid, allGroupMap);
|
||||
chainMap.put(gid, chain);
|
||||
allChainIds.addAll(chain);
|
||||
Set<Integer> openedApps = collectAppIdsForAuthzScope(effectiveGroupId);
|
||||
groupToApps.put(effectiveGroupId, openedApps);
|
||||
Set<Integer> openedApps = collectAppIdsForAuthzScope(gid);
|
||||
groupToApps.put(gid, openedApps);
|
||||
if (openedApps.contains(appId)) {
|
||||
appOpened = true;
|
||||
}
|
||||
@@ -612,33 +627,6 @@ public class GroupAuthzService implements IGroupAuthzService {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上下文组解析(与开放接口 modules 语义严格一致):
|
||||
* - schId 非空:直接用其作为唯一 selfGroupId;
|
||||
* - schId 为空:取用户主学校组(BoaUser.school.id);
|
||||
* - 仍空:取用户主归属组 id(groups 第 0 个);
|
||||
* - 全空:返回 null(此时只能靠角色授权拿模块)。
|
||||
*/
|
||||
private Integer resolveEffectiveGroupId(Integer userId, Integer schId) {
|
||||
if (schId != null) {
|
||||
return schId;
|
||||
}
|
||||
BoaUser boa = userCenterService.getUserInfoWithDeptById(userId);
|
||||
if (boa == null) {
|
||||
return null;
|
||||
}
|
||||
BoaGroup school = boa.getSchool();
|
||||
if (school != null && school.getId() != null) {
|
||||
return school.getId();
|
||||
}
|
||||
List<BoaGroup> groups = boa.getGroups();
|
||||
if (groups != null && !groups.isEmpty()) {
|
||||
BoaGroup main = groups.get(0);
|
||||
return main == null ? null : main.getId();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Map<Integer, AppModule> buildAppModuleMap(List<AppModule> appModules) {
|
||||
Map<Integer, AppModule> map = new HashMap<>();
|
||||
for (AppModule m : appModules) {
|
||||
|
||||
@@ -65,9 +65,9 @@ public class SysGroupService implements ISysGroupService {
|
||||
// 区域组:只能挂在根节点下(由根节点的白名单约束),其下可挂 学段组/学校组/普通组
|
||||
ALLOWED_CHILDREN.put(GroupTypeEnum.AREA_GROUP, EnumSet.of(
|
||||
GroupTypeEnum.STAGE_GROUP, GroupTypeEnum.SCHOOL_GROUP, GroupTypeEnum.NORMAL_GROUP));
|
||||
// 学段组(高中/初中/小学):学校组的上级,可含 学校组/普通组
|
||||
// 学段组(高中/初中/小学):学校组的上级,可含 学校组/年级组
|
||||
ALLOWED_CHILDREN.put(GroupTypeEnum.STAGE_GROUP, EnumSet.of(
|
||||
GroupTypeEnum.SCHOOL_GROUP, GroupTypeEnum.NORMAL_GROUP));
|
||||
GroupTypeEnum.SCHOOL_GROUP, GroupTypeEnum.GRADE_GROUP));
|
||||
// 学校组:可含 教师组/学生组/普通组
|
||||
ALLOWED_CHILDREN.put(GroupTypeEnum.SCHOOL_GROUP, EnumSet.of(
|
||||
GroupTypeEnum.TEACHER_GROUP, GroupTypeEnum.STUDENT_GROUP, GroupTypeEnum.NORMAL_GROUP));
|
||||
|
||||
@@ -89,6 +89,10 @@ public class SysOapiLogServiceImpl implements ISysOapiLogService {
|
||||
typed.setFirstResult((pageIndex - 1) * pageSize);
|
||||
typed.setMaxResults(pageSize);
|
||||
List<SysOapiLogListVo> content = typed.getResultList();
|
||||
// 响应结果随列表带出(GZIP 解压后),供详情弹窗直接展示,无需再单独请求
|
||||
for (SysOapiLogListVo vo : content) {
|
||||
vo.setResponseData(getResponseData(vo.getId()));
|
||||
}
|
||||
|
||||
int totalPages = (int) Math.ceil((double) total / pageSize);
|
||||
boolean hasNext = pageIndex < totalPages;
|
||||
@@ -165,9 +169,11 @@ public class SysOapiLogServiceImpl implements ISysOapiLogService {
|
||||
}
|
||||
if (StringUtils.isNotBlank(query.getKeyword())) {
|
||||
String kw = "%" + query.getKeyword().trim() + "%";
|
||||
// 单输入框同时匹配:请求路径(requestUri) / 应用名(callerAppName) / appKey(callerAppKey)
|
||||
predicates.add(cb.or(
|
||||
cb.like(root.get("requestUri"), kw),
|
||||
cb.like(root.get("callerAppName"), kw)));
|
||||
cb.like(root.get("callerAppName"), kw),
|
||||
cb.like(cb.toString(root.get("callerAppKey")), kw)));
|
||||
}
|
||||
if (query.getStartTime() != null) {
|
||||
predicates.add(cb.greaterThanOrEqualTo(root.get("createTime"), query.getStartTime()));
|
||||
|
||||
Reference in New Issue
Block a user