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
@@ -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();
}
/**