yxk-20260729

改善提案
新增流程表达式getRequiredUsersListByRole
根据角色找人
This commit is contained in:
ye1023
2026-07-29 09:38:52 +08:00
parent 58da0788bb
commit 3343d66093
8 changed files with 89 additions and 2 deletions
@@ -6,6 +6,7 @@ import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.flowable.engine.RuntimeService; import org.flowable.engine.RuntimeService;
import org.flowable.engine.delegate.DelegateExecution; import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.runtime.Execution; import org.flowable.engine.runtime.Execution;
@@ -276,6 +277,28 @@ public class FlowNodeExpression {
return sysbase.getUserByRoleIdLocalApi(roleId); return sysbase.getUserByRoleIdLocalApi(roleId);
} }
/**
* Get required usernames for a Flowable multi-instance task.
* An empty collection would otherwise make Flowable skip the task, so fail fast instead.
* Example: ${flowNodeExpression.getRequiredUsersListByRole('roleIdValue')}
*
* @param roleId system role id
* @return non-empty username list
*/
public List<String> getRequiredUsersListByRole(String roleId) {
if (StringUtils.isBlank(roleId)) {
throw new JeecgBootException("流程角色ID不能为空");
}
List<String> usernames = ISysBaseAPI.getUsernamesByRoleIdLocalApi(roleId);
log.info("流程多实例按角色取人,roleId={}, usernames={}, count={}", roleId, usernames,
usernames == null ? 0 : usernames.size());
if (CollectionUtils.isEmpty(usernames)) {
throw new JeecgBootException("角色[" + roleId + "]未配置有效用户,流程无法继续");
}
return usernames;
}
/** /**
* Get subprocess variable. * Get subprocess variable.
* Example: ${flowNodeExpression.getSonProcessVariable(execution, 'subApproveUser')} * Example: ${flowNodeExpression.getSonProcessVariable(execution, 'subApproveUser')}
@@ -10,6 +10,7 @@ import org.jeecg.common.constant.enums.EmailTemplateEnum;
import org.jeecg.common.system.api.ISysBaseAPI; import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.*; import org.jeecg.common.system.vo.*;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@@ -24,6 +25,12 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
@Setter @Setter
private Throwable cause; private Throwable cause;
@Override
public List<String> getUsernamesByRoleIdLocalApi(String roleId) {
log.error("Query usernames by role failed, roleId={}", roleId, cause);
return Collections.emptyList();
}
@Override @Override
public void sendSysAnnouncement(MessageDTO message) { public void sendSysAnnouncement(MessageDTO message) {
log.error("发送消息失败 {}", cause); log.error("发送消息失败 {}", cause);
@@ -575,4 +575,13 @@ public interface ISysBaseAPI extends CommonAPI {
List<String> getUsersListByDeptIdAndRoleIdLocalApi(String deptId, String roleId); List<String> getUsersListByDeptIdAndRoleIdLocalApi(String deptId, String roleId);
List<String> getUserByRoleIdLocalApi(String roleId); List<String> getUserByRoleIdLocalApi(String roleId);
}
/**
* Query active usernames by role for Flowable multi-instance tasks.
* This method intentionally uses an independent query path so existing role queries remain unchanged.
*
* @param roleId system role id
* @return active username list
*/
List<String> getUsernamesByRoleIdLocalApi(String roleId);
}
@@ -251,4 +251,13 @@ public interface SysUserMapper extends BaseMapper<SysUser> {
* @return * @return
*/ */
List<SysUser> getUserByRoleId(String roleId); List<SysUser> getUserByRoleId(String roleId);
/**
* Query active usernames by role through a dedicated statement.
* It must not reuse the overloaded getUserByRoleId statement used by the user management page.
*
* @param roleId role id
* @return username list
*/
List<String> getUsernamesByRoleId(@Param("roleId") String roleId);
} }
@@ -59,6 +59,17 @@
</if> </if>
</select> </select>
<!-- Multi-instance flow task query. Keep it separate from the overloaded getUserByRoleId statement. -->
<select id="getUsernamesByRoleId" resultType="java.lang.String">
select distinct u.username
from sys_user u
inner join sys_user_role ur on ur.user_id = u.id
where u.del_flag = 0
and ur.role_id = #{roleId}
and u.username is not null
and u.username != ''
</select>
<select id="getUserByRoleIdWithDeptIds" resultType="org.jeecg.modules.system.vo.SysUserRoleDeptsVo"> <select id="getUserByRoleIdWithDeptIds" resultType="org.jeecg.modules.system.vo.SysUserRoleDeptsVo">
SELECT SELECT
u.id as user_id, u.id as user_id,
@@ -498,4 +498,13 @@ public interface ISysUserService extends IService<SysUser> {
List<String> queryUserByDeptAndROle(@NotBlank(message = "deptId不为空") String deptId, @NotBlank(message = "角色id不为空") String roleId, @NotBlank(message = "secretLevel不为空") Integer secretLevel); List<String> queryUserByDeptAndROle(@NotBlank(message = "deptId不为空") String deptId, @NotBlank(message = "角色id不为空") String roleId, @NotBlank(message = "secretLevel不为空") Integer secretLevel);
List<String> getUserByRoleId(String roleId); List<String> getUserByRoleId(String roleId);
/**
* Query active usernames by role for Flowable multi-instance task assignment.
* This is separate from the legacy role-user query to avoid changing its behavior.
*
* @param roleId system role id
* @return active username list
*/
List<String> getUsernamesByRoleId(String roleId);
} }
@@ -2161,4 +2161,15 @@ public class SysBaseApiImpl implements ISysBaseAPI {
.stream() .stream()
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@Override
public List<String> getUsernamesByRoleIdLocalApi(String roleId) {
List<String> usernames = sysUserService.getUsernamesByRoleId(roleId);
return Optional.ofNullable(usernames)
.orElse(Collections.emptyList())
.stream()
.filter(StringUtils::isNotBlank)
.distinct()
.collect(Collectors.toList());
}
} }
@@ -2424,4 +2424,12 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
public List<String> getUserByRoleId(String roleId){ public List<String> getUserByRoleId(String roleId){
return sysUserMapper.getUserByRoleId(roleId).stream().map(SysUser::getUsername).collect(Collectors.toList()) ; return sysUserMapper.getUserByRoleId(roleId).stream().map(SysUser::getUsername).collect(Collectors.toList()) ;
} }
@Override
public List<String> getUsernamesByRoleId(String roleId) {
if (StringUtils.isBlank(roleId)) {
return Collections.emptyList();
}
return sysUserMapper.getUsernamesByRoleId(roleId);
}
} }