This commit is contained in:
2026-08-19 16:43:18 +08:00
parent ac5a2d902e
commit d2321929c2
13 changed files with 326 additions and 105 deletions
@@ -42,7 +42,6 @@ import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* Created by wizzer on 2016/6/28.
@@ -555,12 +554,8 @@ public class SysRoleController {
@Ok("json:full")
@SaCheckLogin
public Result getRoleNames(){
// 首页只展示当前有效角色,历史教代会届次角色仍保留数据但不参与当前身份展示
String roleNames = sysUserService.getEffectiveRoles(SecurityUtil.getUserId()).stream()
.map(Sys_role::getName)
.filter(StrUtil::isNotBlank)
.distinct()
.collect(Collectors.joining(","));
// 首页身份与菜单、接口权限使用同一启用角色集合
String roleNames = sysUserService.getEnabledRoleNames(SecurityUtil.getUserId());
return Result.success(NutMap.NEW().addv("roleNames", roleNames));
}
@@ -16,6 +16,15 @@ public class Sys_user_role {
@ColDefine(type = ColType.VARCHAR, width = 32)
private String userId;
/**
* 用户角色关系是否启用。普通角色默认启用,教代会届次切换时按届次统一刷新。
*/
@Column
@Comment("是否启用:1启用,0禁用")
@ColDefine(type = ColType.BOOLEAN)
@Default("1")
private Boolean enable = true;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unitId;
@@ -33,13 +33,20 @@ public interface SysUserService extends BaseService<Sys_user> {
List<String> getRoleCodeList(Sys_user user);
/**
* 查询用户当前有效的角色。普通角色始终有效,教代会届次角色仅保留最新创建届次的数据
* 查询用户当前启用的角色关系对应角色,供菜单、接口权限和首页身份统一使用
*
* @param userId 用户ID
* @return 当前有效的系统角色列表,按角色排序倒序返回
* @return 当前启用且角色本身未禁用的角色列表
*/
List<Sys_role> getEffectiveRoles(String userId);
List<Sys_role> getEnabledRoles(String userId);
/**
* 查询用户当前启用角色的显示名称。
*
* @param userId 用户ID
* @return 去重并按角色顺序排列的角色名称
*/
String getEnabledRoleNames(String userId);
/**
* 获取用户的菜单
@@ -65,16 +65,12 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
private RedisService redisService;
@Override
@CacheResult(cacheKey = "${userId}_getPermissionList_currentSession")
@CacheResult(cacheKey = "${userId}_getPermissionList")
public List<String> getPermissionList(String userId) {
if (this.fetch(userId) == null) {
return new ArrayList<>();
}
List<String> permissionList = new ArrayList<String>();
for (Sys_role role : getEffectiveRoles(userId)) {
if (!role.isDisabled()) {
permissionList.addAll(sysRoleService.getPermissionList(role));
}
// Sa-Token接口权限只汇总启用的用户角色关系,历史届次角色不再参与鉴权。
for (Sys_role role : getEnabledRoles(userId)) {
permissionList.addAll(sysRoleService.getPermissionList(role));
}
// 追加public公共角色权限
permissionList.addAll(sysRoleService.getPermissionList(sysRoleService.fetch(Cnd.where("code", "=", "public"))));
@@ -87,45 +83,46 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
* @param user
* @return
*/
@CacheResult(cacheKey = "${user.id}_getRoleCodeList_currentSession")
@CacheResult(cacheKey = "${user.id}_getRoleCodeList")
public List<String> getRoleCodeList(Sys_user user) {
List<String> roleNameList = new ArrayList<String>();
for (Sys_role role : getEffectiveRoles(user.getId())) {
if (!role.isDisabled()) roleNameList.add(role.getCode());
if (user == null) {
return new ArrayList<>();
}
return roleNameList;
// AuthUtil.hasRole与Sa-Token角色判断共用启用角色集合。
return getEnabledRoles(user.getId()).stream()
.map(Sys_role::getCode)
.filter(StrUtil::isNotBlank)
.distinct()
.toList();
}
/**
* 查询用户当前有效角色。tcSessionId 为空的普通角色不受届次影响;教代会角色只认创建时间最新的届次
* 历史届次关系继续保存在 sys_user_role 中,以便删除最新届次后自动恢复上一届身份。
* 查询用户当前启用角色。用户角色关系和角色本身必须同时处于启用状态
*
* @param userId 用户ID
* @return 当前有效的角色实体列表
* @return 当前启用角色列表
*/
@Override
public List<Sys_role> getEffectiveRoles(String userId) {
@CacheResult(cacheKey = "${userId}_getEnabledRoles")
public List<Sys_role> getEnabledRoles(String userId) {
if (StrUtil.isBlank(userId) || fetch(userId) == null) {
return new ArrayList<>();
}
Sql sql = Sqls.create("""
SELECT DISTINCT
sr.*
role.*
FROM
sys_role sr
INNER JOIN sys_user_role userRole ON userRole.roleId = sr.id
sys_role role
INNER JOIN sys_user_role userRole ON userRole.roleId = role.id
WHERE
userRole.userId = @userId
AND (
userRole.tcSessionId IS NULL
OR userRole.tcSessionId = ''
OR userRole.tcSessionId = (
SELECT tcs.id
FROM teacher_congress_session tcs
ORDER BY tcs.createdAt DESC, tcs.id DESC
LIMIT 1
)
)
ORDER BY sr.sort DESC, sr.id
AND userRole.enable = @t
AND role.disabled = @f
ORDER BY role.sort DESC, role.id
""");
sql.setParam("userId", userId);
sql.setParam("t", true);
sql.setParam("f", false);
sql.setCallback(Sqls.callback.entities());
sql.setEntity(dao().getEntity(Sys_role.class));
dao().execute(sql);
@@ -133,16 +130,18 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
}
/**
* 查询用户当前有效且已启用角色ID,供菜单和按钮权限查询统一复用
* 汇总用户当前启用角色名称,首页展示与菜单及接口权限保持相同数据口径
*
* @param userId 用户ID
* @return 有效角色ID列表
* @return 逗号分隔的角色名称
*/
private List<String> getEnabledEffectiveRoleIds(String userId) {
return getEffectiveRoles(userId).stream()
.filter(role -> !role.isDisabled())
.map(Sys_role::getId)
.toList();
@Override
public String getEnabledRoleNames(String userId) {
return getEnabledRoles(userId).stream()
.map(Sys_role::getName)
.filter(StrUtil::isNotBlank)
.distinct()
.collect(Collectors.joining(","));
}
/**
@@ -204,12 +203,9 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
*/
// @CacheResult(cacheKey = "${userId}_getMenus")
public List<Sys_menu> getMenus(String userId) {
List<String> roleIds = getEnabledEffectiveRoleIds(userId);
if (roleIds.isEmpty()) {
return new ArrayList<>();
}
Sql sql = Sqls.create("select distinct a.* from sys_menu a,sys_role_menu b where a.id=b.menuId and " + " b.roleId in(@roleIds) and a.disabled=@f and a.showit=@t and a.type='menu' order by a.location ASC,a.path asc");
sql.params().set("roleIds", roleIds);
// 菜单仅使用启用的用户角色关系,普通角色与当前开启届次角色保持原有权限。
Sql sql = Sqls.create("select distinct a.* from sys_menu a,sys_role_menu b where a.id=b.menuId and " + " b.roleId in(select c.roleId from sys_user_role c,sys_role d where c.roleId=d.id and c.userId=@userId and c.enable=@t and d.disabled=@f) and a.disabled=@f and a.showit=@t and a.type='menu' order by a.location ASC,a.path asc");
sql.params().set("userId", userId);
sql.params().set("f", false);
sql.params().set("t", true);
return sysMenuService.listEntity(sql);
@@ -223,13 +219,10 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
*/
// @CacheResult(cacheKey = "${userId}_getMenusAndButtons")
public List<Sys_menu> getMenusAndButtons(String userId) {
List<String> roleIds = getEnabledEffectiveRoleIds(userId);
if (roleIds.isEmpty()) {
return new ArrayList<>();
}
Sql sql = Sqls.create("select distinct a.* from sys_menu a,sys_role_menu b where a.id=b.menuId and " + " b.roleId in(@roleIds) and a.disabled=@f order by a.location ASC,a.path asc");
sql.params().set("roleIds", roleIds);
Sql sql = Sqls.create("select distinct a.* from sys_menu a,sys_role_menu b where a.id=b.menuId and " + " b.roleId in(select c.roleId from sys_user_role c,sys_role d where c.roleId=d.id and c.userId=@userId and c.enable=@t and d.disabled=@f) and a.disabled=@f order by a.location ASC,a.path asc");
sql.params().set("userId", userId);
sql.params().set("f", false);
sql.params().set("t", true);
return sysMenuService.listEntity(sql);
}
@@ -244,15 +237,12 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
* @param userId
* @return
*/
@CacheResult(cacheKey = "${userId}_getDatas_currentSession")
@CacheResult(cacheKey = "${userId}_getDatas")
public List<Sys_menu> getDatas(String userId) {
List<String> roleIds = getEnabledEffectiveRoleIds(userId);
if (roleIds.isEmpty()) {
return new ArrayList<>();
}
Sql sql = Sqls.create("select distinct a.* from sys_menu a,sys_role_menu b where a.id=b.menuId and " + " b.roleId in(@roleIds) and a.disabled=@f and a.type='data' order by a.location ASC,a.path asc");
sql.params().set("roleIds", roleIds);
Sql sql = Sqls.create("select distinct a.* from sys_menu a,sys_role_menu b where a.id=b.menuId and " + " b.roleId in(select c.roleId from sys_user_role c,sys_role d where c.roleId=d.id and c.userId=@userId and c.enable=@t and d.disabled=@f) and a.disabled=@f and a.type='data' order by a.location ASC,a.path asc");
sql.params().set("userId", userId);
sql.params().set("f", false);
sql.params().set("t", true);
return sysMenuService.listEntity(sql);
}
@@ -285,15 +275,12 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
* @param pid
* @return
*/
@CacheResult(cacheKey = "${userId}_${pid}_getRoleMenus_currentSession")
@CacheResult(cacheKey = "${userId}_${pid}_getRoleMenus")
public List<Sys_menu> getRoleMenus(String userId, String pid) {
List<String> roleIds = getEnabledEffectiveRoleIds(userId);
if (roleIds.isEmpty()) {
return new ArrayList<>();
}
Sql sql = Sqls.create("select distinct a.* from sys_menu a,sys_role_menu b where a.id=b.menuId and " + "$m and b.roleId in(@roleIds) and a.disabled=@f order by a.location ASC,a.path asc");
sql.params().set("roleIds", roleIds);
Sql sql = Sqls.create("select distinct a.* from sys_menu a,sys_role_menu b where a.id=b.menuId and " + "$m and b.roleId in(select c.roleId from sys_user_role c,sys_role d where c.roleId=d.id and c.userId=@userId and c.enable=@t and d.disabled=@f) and a.disabled=@f order by a.location ASC,a.path asc");
sql.params().set("userId", userId);
sql.params().set("f", false);
sql.params().set("t", true);
if (Strings.isNotBlank(pid)) {
sql.vars().set("m", "a.parentId='" + pid + "'");
} else {
@@ -308,15 +295,12 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
* @param pid
* @return
*/
@CacheResult(cacheKey = "${userId}_${pid}_hasChildren_currentSession")
@CacheResult(cacheKey = "${userId}_${pid}_hasChildren")
public boolean hasChildren(String userId, String pid) {
List<String> roleIds = getEnabledEffectiveRoleIds(userId);
if (roleIds.isEmpty()) {
return false;
}
Sql sql = Sqls.create("select count(*) from sys_menu a,sys_role_menu b where a.id=b.menuId and " + "$m and b.roleId in(@roleIds) and a.disabled=@f order by a.location ASC,a.path asc");
sql.params().set("roleIds", roleIds);
Sql sql = Sqls.create("select count(*) from sys_menu a,sys_role_menu b where a.id=b.menuId and " + "$m and b.roleId in(select c.roleId from sys_user_role c,sys_role d where c.roleId=d.id and c.userId=@userId and c.enable=@t and d.disabled=@f) and a.disabled=@f order by a.location ASC,a.path asc");
sql.params().set("userId", userId);
sql.params().set("f", false);
sql.params().set("t", true);
if (Strings.isNotBlank(pid)) {
sql.vars().set("m", "a.parentId='" + pid + "'");
} else {
@@ -450,6 +434,8 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
user.setUnion(union);
}
user = this.fillMenu(user);
// 登录用户返回给前端的角色同样只保留启用关系,避免历史届次角色继续触发页面 hasRole 判断。
user.setRoles(this.getEnabledRoles(userId));
user.setPermissions(this.getPermissionList(userId));
return user;
}
@@ -85,9 +85,12 @@ public class UnionReimburseCollectController {
@Param(value = "reimburseProject") String reimburseProject) {
Sql sql = Sqls.create("""
SELECT
info.*
info.*,
ins.id AS instanceId,
ins.processDefineId AS instanceProcessDefineId
FROM
union_reimburse info
LEFT JOIN wf_process_instance ins ON ins.businessNo = info.id
$condition
""");
Cnd cnd = Cnd.NEW();
@@ -27,6 +27,7 @@ import com.budwk.app.zhgh.democratic.teachercongress.delegate.service.TeacherCon
import com.budwk.app.zhgh.democratic.teachercongress.delegation.models.Teacher_congress_delegation;
import com.budwk.app.zhgh.democratic.teachercongress.delegation.models.Teacher_congress_delegation_union;
import com.budwk.app.zhgh.democratic.teachercongress.delegation.models.Teacher_congress_delegation_unit;
import com.budwk.app.zhgh.democratic.teachercongress.prepare.service.TeacherCongressSessionService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
@@ -68,6 +69,8 @@ public class TeacherCongressDelegateManageController {
private SysRoleService sysRoleService;
@Inject
private TeacherCongressDelegateService teacherDelegateService;
@Inject
private TeacherCongressSessionService teacherCongressSessionService;
@At("")
@Ok("beetl:/platform/zhgh/democratic/teachercongress/delegate/manage/index.html")
@@ -123,12 +126,14 @@ public class TeacherCongressDelegateManageController {
.and(Sys_user_role::getTcSessionId, "=", param.getSessionId())
.and(Sys_user_role::getRoleId, "=", param.getRoleId()));
boolean roleEnable = teacherCongressSessionService.isSessionRoleEnabled(param.getSessionId());
List<Sys_user_role> userRoles = userIds.stream().map(userId -> {
Sys_user_role role = new Sys_user_role();
role.setUserId(userId);
role.setTcSessionId(param.getSessionId());
role.setTcDelegationId(param.getDelegationId());
role.setRoleId(param.getRoleId());
role.setEnable(roleEnable);
return role;
}).toList();
dao.insert(userRoles);
@@ -160,6 +165,7 @@ public class TeacherCongressDelegateManageController {
role.setTcSessionId(param.getSessionId());
role.setTcDelegationId(param.getDelegationId());
role.setRoleId(param.getRoleId());
teacherCongressSessionService.prepareSessionRole(role);
dao.insert(role);
sysUserService.clearCache();
@@ -330,12 +336,14 @@ public class TeacherCongressDelegateManageController {
dao.insert(delegates);
//插入权限
boolean roleEnable = teacherCongressSessionService.isSessionRoleEnabled(sessionId);
List<Sys_user_role> sysUserRoles = delegates.stream().map(delegate -> {
Sys_user_role sysUserRole = new Sys_user_role();
sysUserRole.setUserId(delegate.getUserId());
sysUserRole.setRoleId(delegate.getRoleId());
sysUserRole.setTcSessionId(sessionId);
sysUserRole.setTcDelegationId(delegate.getDelegationId());
sysUserRole.setEnable(roleEnable);
return sysUserRole;
}).toList();
dao.insert(sysUserRoles);
@@ -464,7 +472,12 @@ public class TeacherCongressDelegateManageController {
try {
dao.insert(delegate);
dao.insert("sys_user_role", Chain.make("userId", delegate.getUserId()).add("roleId", delegate.getRoleId()).add("tcSessionId", sessionId).add("tcDelegationId", delegate.getDelegationId()));
// Excel导入也必须继承届次启用状态,避免向历史届次导入代表后恢复旧权限。
dao.insert("sys_user_role", Chain.make("userId", delegate.getUserId())
.add("roleId", delegate.getRoleId())
.add("tcSessionId", sessionId)
.add("tcDelegationId", delegate.getDelegationId())
.add("enable", teacherCongressSessionService.isSessionRoleEnabled(sessionId)));
sysUserService.clearCache();
} catch (Exception e) {
log.error("导入代表失败:{}", e.getMessage());
@@ -512,6 +525,7 @@ public class TeacherCongressDelegateManageController {
userRole.setRoleId(sys_role2.getId());
}
userRole.setTcDelegationId(delegate.getDelegationId());
teacherCongressSessionService.prepareSessionRole(userRole);
dao.insert(userRole);
}
sysUserService.clearCache();
@@ -13,6 +13,7 @@ import com.budwk.app.zhgh.democratic.proposal.models.ProposalConfig;
import com.budwk.app.zhgh.democratic.teachercongress.delegate.models.Teacher_congress_delegate;
import com.budwk.app.zhgh.democratic.teachercongress.delegation.models.Teacher_congress_delegation_unit;
import com.budwk.app.zhgh.democratic.teachercongress.prepare.models.Teacher_congress_session;
import com.budwk.app.zhgh.democratic.teachercongress.prepare.service.TeacherCongressSessionService;
import com.budwk.app.zhgh.staffmanage.member.constant.MemberChangeType;
import org.nutz.aop.interceptor.async.Async;
import org.nutz.dao.Cnd;
@@ -38,6 +39,8 @@ public class TeacherCongressDelegateListener implements SysUserEventListener {
private SysUserService sysUserService;
@Inject
private SysRoleService sysRoleService;
@Inject
private TeacherCongressSessionService teacherCongressSessionService;
@Override
@Async
@@ -46,8 +49,10 @@ public class TeacherCongressDelegateListener implements SysUserEventListener {
return;
}
//查询当前最新届次
Teacher_congress_session session = dao.fetch(Teacher_congress_session.class, Cnd.NEW().desc(Teacher_congress_session::getStartDate));
// 人员单位变更只同步当前开启届次,防止误修改历史届次代表及角色关系。
Teacher_congress_session session = dao.fetch(Teacher_congress_session.class,
Cnd.where(Teacher_congress_session::getEnable, "=", true)
.desc(Teacher_congress_session::getStartDate));
if (session == null) {
return;
}
@@ -102,6 +107,7 @@ public class TeacherCongressDelegateListener implements SysUserEventListener {
sysUserRole.setTcSessionId(session.getId());
sysUserRole.setTcDelegationId(currentDelegate.getDelegationId());
sysUserRole.setRoleId(currentDelegate.getRoleId());
teacherCongressSessionService.prepareSessionRole(sysUserRole);
dao.insert(sysUserRole);
sysUserService.clearCache();
@@ -8,8 +8,10 @@ import com.budwk.app.sys.models.Sys_role;
import com.budwk.app.sys.models.Sys_user_role;
import com.budwk.app.sys.services.SysRoleService;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.zhgh.democratic.teachercongress.delegate.models.Teacher_congress_delegate;
import com.budwk.app.zhgh.democratic.teachercongress.delegation.models.Teacher_congress_delegation;
import com.budwk.app.zhgh.democratic.teachercongress.delegation.service.TeacherCongressDelegationService;
import com.budwk.app.zhgh.democratic.teachercongress.prepare.service.TeacherCongressSessionService;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
@@ -23,6 +25,8 @@ import org.nutz.lang.util.NutMap;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 教代会代表团业务服务实现。
@@ -36,6 +40,9 @@ public class TeacherCongressDelegationServiceImpl extends BaseServiceImpl<Teache
@Inject
private SysUserService sysUserService;
@Inject
private TeacherCongressSessionService teacherCongressSessionService;
public TeacherCongressDelegationServiceImpl(Dao dao) {
super(dao);
}
@@ -86,17 +93,23 @@ public class TeacherCongressDelegationServiceImpl extends BaseServiceImpl<Teache
@Override
@Aop(TransAop.READ_COMMITTED)
public void setHeadUsers(String sessionId, String delegationId, String userId, String[] viceUserIds, String contactUserId) {
String[] normalizedViceUserIds = normalizeUserIds(viceUserIds);
boolean roleEnable = teacherCongressSessionService.isSessionRoleEnabled(sessionId);
// 必须先校验候选人再清理旧角色,避免非法参数导致原副团长数据被误删。
validateViceHeadUsers(sessionId, delegationId, normalizedViceUserIds);
// 团长仍然保持单人设置。
Sys_role headRole = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_DELEGATION_HEAD);
replaceRoleUsers(sessionId, delegationId, headRole.getId(), new String[]{userId});
replaceRoleUsers(sessionId, delegationId, headRole.getId(), new String[]{userId}, roleEnable);
// 副团长支持多人设置,完整保留V3迁移后的多个副团长关系。
Sys_role viceHeadRole = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_VICE_DELEGATION_HEAD);
replaceRoleUsers(sessionId, delegationId, viceHeadRole.getId(), viceUserIds);
replaceRoleUsers(sessionId, delegationId, viceHeadRole.getId(), normalizedViceUserIds, roleEnable);
validateRoleUserCount(sessionId, delegationId, viceHeadRole.getId(), normalizedViceUserIds.length);
// 联络人保持单人设置,未选择时只清理旧联络人。
Sys_role contactRole = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_DELEGATION_CONTACT);
replaceRoleUsers(sessionId, delegationId, contactRole.getId(), new String[]{contactUserId});
replaceRoleUsers(sessionId, delegationId, contactRole.getId(), new String[]{contactUserId}, roleEnable);
sysUserService.clearCache();
}
@@ -145,8 +158,9 @@ public class TeacherCongressDelegationServiceImpl extends BaseServiceImpl<Teache
* @param delegationId 代表团ID
* @param roleId 角色ID
* @param userIds 用户ID数组
* @param roleEnable 角色关系是否启用
*/
private void replaceRoleUsers(String sessionId, String delegationId, String roleId, String[] userIds) {
private void replaceRoleUsers(String sessionId, String delegationId, String roleId, String[] userIds, boolean roleEnable) {
dao().clear(Sys_user_role.class, Cnd.where(Sys_user_role::getTcDelegationId, "=", delegationId)
.and(Sys_user_role::getTcSessionId, "=", sessionId)
.and(Sys_user_role::getRoleId, "=", roleId));
@@ -159,6 +173,66 @@ public class TeacherCongressDelegationServiceImpl extends BaseServiceImpl<Teache
.forEach(userId -> dao().insert("sys_user_role", Chain.make("userId", userId)
.add("roleId", roleId)
.add("tcDelegationId", delegationId)
.add("tcSessionId", sessionId)));
.add("tcSessionId", sessionId)
.add("enable", roleEnable)));
}
}
/**
* 清理并去重用户ID,统一后续校验与入库使用的数据口径。
*
* @param userIds 原始用户ID数组
* @return 去除空值和重复值后的用户ID数组
*/
private String[] normalizeUserIds(String[] userIds) {
if (userIds == null || userIds.length == 0) {
return new String[0];
}
return Arrays.stream(userIds)
.filter(StrUtil::isNotBlank)
.distinct()
.toArray(String[]::new);
}
/**
* 校验副团长候选人均为当前届次、当前代表团的正式代表。
*
* @param sessionId 届次ID
* @param delegationId 代表团ID
* @param viceUserIds 副团长用户ID数组
*/
private void validateViceHeadUsers(String sessionId, String delegationId, String[] viceUserIds) {
if (viceUserIds.length == 0) {
return;
}
Sys_role formalDelegateRole = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_DELEGATE_FORMAL);
List<Teacher_congress_delegate> delegates = dao().query(Teacher_congress_delegate.class,
Cnd.where(Teacher_congress_delegate::getSessionId, "=", sessionId)
.and(Teacher_congress_delegate::getDelegationId, "=", delegationId)
.and(Teacher_congress_delegate::getRoleId, "=", formalDelegateRole.getId())
.and(Teacher_congress_delegate::getUserId, "in", viceUserIds));
Set<String> validUserIds = delegates.stream()
.map(Teacher_congress_delegate::getUserId)
.collect(Collectors.toSet());
if (validUserIds.size() != viceUserIds.length) {
throw new BaseException("副团长必须从当前届次、当前代表团的正式代表中选择");
}
}
/**
* 校验角色关系的实际保存数量,防止接口在数据未完整写入时返回成功。
*
* @param sessionId 届次ID
* @param delegationId 代表团ID
* @param roleId 角色ID
* @param expected 预期保存数量
*/
private void validateRoleUserCount(String sessionId, String delegationId, String roleId, int expected) {
int actual = dao().count(Sys_user_role.class,
Cnd.where(Sys_user_role::getTcSessionId, "=", sessionId)
.and(Sys_user_role::getTcDelegationId, "=", delegationId)
.and(Sys_user_role::getRoleId, "=", roleId));
if (actual != expected) {
throw new BaseException("副团长设置失败,请刷新页面后重试");
}
}
}
@@ -10,6 +10,7 @@ import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.zhgh.democratic.teachercongress.institution.models.Teacher_congress_institution;
import com.budwk.app.zhgh.democratic.teachercongress.institution.models.Teacher_congress_institution_user;
import com.budwk.app.zhgh.democratic.teachercongress.institution.service.TeacherCongressInstitutionUserService;
import com.budwk.app.zhgh.democratic.teachercongress.prepare.service.TeacherCongressSessionService;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
@@ -25,6 +26,8 @@ public class TeacherCongressInstitutionUserServiceImpl extends BaseServiceImpl<T
private SysRoleService sysRoleService;
@Inject
private SysUserService sysUserService;
@Inject
private TeacherCongressSessionService teacherCongressSessionService;
public TeacherCongressInstitutionUserServiceImpl(Dao dao) {
super(dao);
@@ -66,6 +69,7 @@ public class TeacherCongressInstitutionUserServiceImpl extends BaseServiceImpl<T
insertSysUserRole.setRoleId(sysRole.getId());
insertSysUserRole.setUserId(userId);
insertSysUserRole.setTcSessionId(sessionId);
teacherCongressSessionService.prepareSessionRole(insertSysUserRole);
dao().insert(insertSysUserRole);
sysRoleService.clearCache();
sysUserService.clearCache();
@@ -84,6 +88,7 @@ public class TeacherCongressInstitutionUserServiceImpl extends BaseServiceImpl<T
insertSysUserRole.setRoleId(sysRole.getId());
insertSysUserRole.setUserId(userId);
insertSysUserRole.setTcSessionId(sessionId);
teacherCongressSessionService.prepareSessionRole(insertSysUserRole);
dao().insert(insertSysUserRole);
sysRoleService.clearCache();
sysUserService.clearCache();
@@ -111,6 +116,7 @@ public class TeacherCongressInstitutionUserServiceImpl extends BaseServiceImpl<T
insertSysUserRole.setRoleId(sysRole.getId());
insertSysUserRole.setUserId(userId);
insertSysUserRole.setTcSessionId(sessionId);
teacherCongressSessionService.prepareSessionRole(insertSysUserRole);
dao().insert(insertSysUserRole);
sysRoleService.clearCache();
sysUserService.clearCache();
@@ -198,6 +204,7 @@ public class TeacherCongressInstitutionUserServiceImpl extends BaseServiceImpl<T
insertSysUserRole.setRoleId(sysRole.getId());
insertSysUserRole.setUserId(userId);
insertSysUserRole.setTcSessionId(sessionId);
teacherCongressSessionService.prepareSessionRole(insertSysUserRole);
dao().insert(insertSysUserRole);
sysRoleService.clearCache();
sysUserService.clearCache();
@@ -1,6 +1,7 @@
package com.budwk.app.zhgh.democratic.teachercongress.prepare.service;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.sys.models.Sys_user_role;
import com.budwk.app.zhgh.democratic.teachercongress.prepare.controller.vo.TeacherCongressSessionProposalTypeVO;
import com.budwk.app.zhgh.democratic.teachercongress.prepare.models.Teacher_congress_session;
@@ -28,4 +29,28 @@ public interface TeacherCongressSessionService extends BaseService<Teacher_congr
void updateSession(Teacher_congress_session session);
void deleteSession(String id);
/**
* 根据届次当前开启状态设置待保存用户角色关系的启用状态。
*
* @param userRole 待保存的用户角色关系
*/
void prepareSessionRole(Sys_user_role userRole);
/**
* 查询指定届次的角色权限是否应当启用。
*
* @param sessionId 届次ID
* @return 届次存在且处于开启状态时返回 true
*/
boolean isSessionRoleEnabled(String sessionId);
/**
* 按届次开启状态统一刷新教代会届次及其用户角色关系。
* 开启时仅保留指定届次有效,关闭时禁用全部教代会届次角色。
*
* @param sessionId 届次ID
* @param enable 是否开启
*/
void refreshSessionRoleEnable(String sessionId, boolean enable);
}
@@ -100,10 +100,6 @@ public class TeacherCongressSessionServiceImpl extends BaseServiceImpl<Teacher_c
session.setFullName("" + session.getJ() + "" + session.getC());
insert(session);
// 新届次创建后立即清除角色缓存,使旧届次角色停止参与首页展示和权限判断。
sysUserService.clearCache();
sysRoleService.clearCache();
// 继承上届信息
if (isExtend) {
//代表团角色ID
@@ -113,13 +109,19 @@ public class TeacherCongressSessionServiceImpl extends BaseServiceImpl<Teacher_c
//查询本届上次的信息
int c_num = Convert.chineseToNumber(session.getC().replaceAll("", ""));
if (c_num == 1) return;
if (c_num == 1) {
finishInsertSessionRoleStatus(session);
return;
}
int last_c_num = c_num - 1;
String last_c = Convert.numberToChinese(last_c_num, false);
Teacher_congress_session lastSession = fetch(Cnd.where(Teacher_congress_session::getJ, "=", session.getJ())
.and(Teacher_congress_session::getC, "=", last_c + ""));
if (ObjectUtil.isEmpty(lastSession)) return;
if (ObjectUtil.isEmpty(lastSession)) {
finishInsertSessionRoleStatus(session);
return;
}
//机构及机构人员数据
List<Teacher_congress_institution> lastInstitutions = dao().query(Teacher_congress_institution.class, Cnd.where(Teacher_congress_institution::getSessionId, "=", lastSession.getId()));
@@ -143,6 +145,7 @@ public class TeacherCongressSessionServiceImpl extends BaseServiceImpl<Teacher_c
Sys_user_role newHeadUser = BeanUtil.copyProperties(lastHeadUser, Sys_user_role.class);
newHeadUser.setTcDelegationId(newDelegation.getId());
newHeadUser.setTcSessionId(session.getId());
newHeadUser.setEnable(Boolean.TRUE.equals(session.getEnable()));
dao().insert(newHeadUser);
}
//副团长角色权限继承
@@ -152,6 +155,7 @@ public class TeacherCongressSessionServiceImpl extends BaseServiceImpl<Teacher_c
Sys_user_role newViceHeadUser = BeanUtil.copyProperties(lastViceHeadUser, Sys_user_role.class);
newViceHeadUser.setTcDelegationId(newDelegation.getId());
newViceHeadUser.setTcSessionId(session.getId());
newViceHeadUser.setEnable(Boolean.TRUE.equals(session.getEnable()));
dao().insert(newViceHeadUser);
}
//联络人角色权限继承
@@ -161,6 +165,7 @@ public class TeacherCongressSessionServiceImpl extends BaseServiceImpl<Teacher_c
Sys_user_role newContactUser = BeanUtil.copyProperties(lastContactUser, Sys_user_role.class);
newContactUser.setTcDelegationId(newDelegation.getId());
newContactUser.setTcSessionId(session.getId());
newContactUser.setEnable(Boolean.TRUE.equals(session.getEnable()));
dao().insert(newContactUser);
}
@@ -247,6 +252,7 @@ public class TeacherCongressSessionServiceImpl extends BaseServiceImpl<Teacher_c
sysUserRole.setUserId(newDelegate.getUserId());
sysUserRole.setRoleId(newDelegate.getRoleId());
sysUserRole.setTcDelegationId(newDelegate.getDelegationId());
sysUserRole.setEnable(Boolean.TRUE.equals(session.getEnable()));
dao().insert(sysUserRole);
}
@@ -266,14 +272,14 @@ public class TeacherCongressSessionServiceImpl extends BaseServiceImpl<Teacher_c
sysUserRole.setTcSessionId(session.getId());
sysUserRole.setUserId(teacherCongressInstitutionUser.getUserId());
sysUserRole.setRoleId(committeeDoctorRole.getId());
sysUserRole.setEnable(Boolean.TRUE.equals(session.getEnable()));
dao().insert(sysUserRole);
}
}
}
sysRoleService.clearCache();
sysUserService.clearCache();
}
finishInsertSessionRoleStatus(session);
}
/**
@@ -294,6 +300,84 @@ public class TeacherCongressSessionServiceImpl extends BaseServiceImpl<Teacher_c
}
session.setFullName("" + session.getJ() + "" + session.getC());
dao().updateIgnoreNull(session);
Teacher_congress_session savedSession = fetch(session.getId());
if (savedSession == null) {
throw new BaseException("届次不存在");
}
// 编辑届次时以保存后的开启状态为准,统一刷新全部教代会届次角色权限。
refreshSessionRoleEnable(savedSession.getId(), Boolean.TRUE.equals(savedSession.getEnable()));
}
/**
* 完成新增届次后的角色状态收口。新增关闭届次不影响当前有效届次,新增开启届次则切换全部权限。
*
* @param session 新增的教代会届次
*/
private void finishInsertSessionRoleStatus(Teacher_congress_session session) {
if (Boolean.TRUE.equals(session.getEnable())) {
refreshSessionRoleEnable(session.getId(), true);
return;
}
dao().update(Sys_user_role.class, org.nutz.dao.Chain.make("enable", false),
Cnd.where(Sys_user_role::getTcSessionId, "=", session.getId()));
sysUserService.clearCache();
sysRoleService.clearCache();
}
/**
* 根据届次状态初始化待保存用户角色关系,避免在关闭届次新增人员后意外恢复历史权限。
*
* @param userRole 待保存的用户角色关系
*/
@Override
public void prepareSessionRole(Sys_user_role userRole) {
if (userRole == null) {
throw new BaseException("用户角色数据不能为空");
}
userRole.setEnable(isSessionRoleEnabled(userRole.getTcSessionId()));
}
/**
* 查询届次当前是否开启,供代表、代表团及机构角色写入时统一确定启用状态。
*
* @param sessionId 届次ID
* @return 届次存在且开启时返回 true
*/
@Override
public boolean isSessionRoleEnabled(String sessionId) {
if (StrUtil.isBlank(sessionId)) {
return false;
}
Teacher_congress_session session = fetch(sessionId);
return session != null && Boolean.TRUE.equals(session.getEnable());
}
/**
* 统一刷新教代会届次角色权限。开启时只启用目标届次,关闭时关闭全部届次及角色关系。
*
* @param sessionId 届次ID
* @param enable 是否开启
*/
@Override
@Aop(TransAop.READ_COMMITTED)
public void refreshSessionRoleEnable(String sessionId, boolean enable) {
if (enable && fetch(sessionId) == null) {
throw new BaseException("届次不存在");
}
// 先关闭全部届次角色,保证任意时刻最多只有一个届次提供权限。
dao().update(Sys_user_role.class, org.nutz.dao.Chain.make("enable", false),
Cnd.where(Sys_user_role::getTcSessionId, "is not", null)
.and(Sys_user_role::getTcSessionId, "!=", ""));
dao().update(Teacher_congress_session.class, org.nutz.dao.Chain.make("enable", false), Cnd.NEW());
if (enable) {
dao().update(Teacher_congress_session.class, org.nutz.dao.Chain.make("enable", true),
Cnd.where(Teacher_congress_session::getId, "=", sessionId));
dao().update(Sys_user_role.class, org.nutz.dao.Chain.make("enable", true),
Cnd.where(Sys_user_role::getTcSessionId, "=", sessionId));
}
// 届次切换会同时影响菜单、接口权限、角色判断和首页身份,必须统一清空缓存。
sysUserService.clearCache();
sysRoleService.clearCache();
}
/**