瀏覽代碼

feat: 转办人列表,各种权限问题修复

wuwenyi 2 周之前
父節點
當前提交
fad9ad8f58

+ 0 - 2
src/main/java/com/qqflow/engine/domain/flow/mapper/ApprovalTaskMapper.java

@@ -38,8 +38,6 @@ public interface ApprovalTaskMapper extends BaseMapper<ApprovalTask> {
     com.baomidou.mybatisplus.extension.plugins.pagination.Page<ApprovalTask> selectHandledList(
             com.baomidou.mybatisplus.extension.plugins.pagination.Page<ApprovalTask> page,
             @Param("assigneeId") Long assigneeId,
-            @Param("assigneeType") String assigneeType,
-            @Param("roleIds") List<Long> roleIds,
             @Param("processName") String processName);
 
     com.baomidou.mybatisplus.extension.plugins.pagination.Page<ApprovalTask> selectCcList(

+ 1 - 2
src/main/java/com/qqflow/engine/domain/flow/service/impl/ApprovalTaskServiceImpl.java

@@ -109,9 +109,8 @@ public class ApprovalTaskServiceImpl implements ApprovalTaskService {
 
     @Override
     public PageResult<ApprovalTaskDTO> handledList(Long assigneeId, String assigneeType, String processName, Integer pageNum, Integer pageSize) {
-        List<Long> roleIds = loadRoleIdsIfSystemUser(assigneeId, assigneeType);
         Page<ApprovalTask> page = new Page<>(pageNum, pageSize);
-        this.approvalTaskMapper.selectHandledList(page, assigneeId, assigneeType, roleIds, processName);
+        this.approvalTaskMapper.selectHandledList(page, assigneeId, processName);
         List<ApprovalTaskDTO> records = page.getRecords().stream()
                 .map(ApprovalTaskDTO::of)
                 .collect(Collectors.toList());

+ 16 - 3
src/main/java/com/qqflow/engine/domain/flow/service/impl/ProcessInstanceServiceImpl.java

@@ -35,7 +35,9 @@ import com.qqflow.engine.domain.flow.po.ProcessInstance;
 import com.qqflow.engine.domain.flow.service.FlowEngineService;
 import com.qqflow.engine.domain.flow.service.ProcessInstanceService;
 import com.qqflow.engine.domain.system.entity.SysUser;
+import com.qqflow.engine.domain.system.entity.SysUserRole;
 import com.qqflow.engine.domain.system.mapper.SysUserMapper;
+import com.qqflow.engine.domain.system.mapper.SysUserRoleMapper;
 import lombok.RequiredArgsConstructor;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -74,6 +76,7 @@ public class ProcessInstanceServiceImpl implements ProcessInstanceService {
     private final AttachmentMapper attachmentMapper;
     private final ObjectMapper objectMapper;
     private final SysUserMapper sysUserMapper;
+    private final SysUserRoleMapper sysUserRoleMapper;
 
     @Override
     @Transactional
@@ -340,11 +343,14 @@ public class ProcessInstanceServiceImpl implements ProcessInstanceService {
         // 任务处理人可见
         List<ApprovalTask> tasks = this.approvalTaskMapper.selectByInstanceId(instance.getId());
         for (ApprovalTask task : tasks) {
-            if (userId.equals(task.getAssigneeId())) {
-                if (USER_TYPE_ROLE.equals(userType) && ASSIGNEE_TYPE_ROLE.equals(task.getAssigneeType())) {
+            if (ASSIGNEE_TYPE_ROLE.equals(task.getAssigneeType())) {
+                // ROLE 任务:检查当前用户是否拥有该角色
+                if (this.hasRole(userId, task.getAssigneeId())) {
                     return;
                 }
-                if (!USER_TYPE_ROLE.equals(userType) && !ASSIGNEE_TYPE_ROLE.equals(task.getAssigneeType())) {
+            } else {
+                // USER/SELF/LEADER 任务:直接匹配用户ID
+                if (userId.equals(task.getAssigneeId())) {
                     return;
                 }
             }
@@ -442,4 +448,11 @@ public class ProcessInstanceServiceImpl implements ProcessInstanceService {
         }
         return List.of(trimmed);
     }
+
+    private boolean hasRole(Long userId, Long roleId) {
+        return this.sysUserRoleMapper.exists(
+                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<SysUserRole>()
+                        .eq(SysUserRole::getUserId, userId)
+                        .eq(SysUserRole::getRoleId, roleId));
+    }
 }

+ 36 - 0
src/main/java/com/qqflow/engine/domain/system/controller/SysRoleController.java

@@ -4,10 +4,16 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.qqflow.engine.common.PageResult;
 import com.qqflow.engine.common.Result;
 import com.qqflow.engine.domain.system.assembler.RoleAssembler;
+import com.qqflow.engine.domain.system.assembler.UserAssembler;
 import com.qqflow.engine.domain.system.dto.BindWeComDTO;
 import com.qqflow.engine.domain.system.dto.RoleDTO;
+import com.qqflow.engine.domain.system.dto.UserDTO;
 import com.qqflow.engine.domain.system.entity.SysDept;
 import com.qqflow.engine.domain.system.entity.SysRole;
+import com.qqflow.engine.domain.system.entity.SysUser;
+import com.qqflow.engine.domain.system.entity.SysUserRole;
+import com.qqflow.engine.domain.system.mapper.SysUserMapper;
+import com.qqflow.engine.domain.system.mapper.SysUserRoleMapper;
 import com.qqflow.engine.domain.system.service.SysDeptService;
 import com.qqflow.engine.domain.system.service.SysRoleService;
 import io.swagger.v3.oas.annotations.Operation;
@@ -40,6 +46,12 @@ public class SysRoleController {
     @Resource
     private SysDeptService sysDeptService;
 
+    @Resource
+    private SysUserRoleMapper sysUserRoleMapper;
+
+    @Resource
+    private SysUserMapper sysUserMapper;
+
     @Operation(summary = "分页查询角色")
     @GetMapping("/list")
     public Result<PageResult<RoleDTO>> list(
@@ -78,6 +90,30 @@ public class SysRoleController {
         return Result.ok(dto);
     }
 
+    @Operation(summary = "查询拥有某角色的用户列表(转办选人用)")
+    @GetMapping("/{roleId}/users")
+    @PreAuthorize("isAuthenticated()")
+    public Result<List<UserDTO>> listUsersByRoleId(@PathVariable Long roleId) {
+        List<Long> userIds = sysUserRoleMapper.selectList(
+                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<SysUserRole>()
+                        .eq(SysUserRole::getRoleId, roleId)
+        ).stream().map(SysUserRole::getUserId).distinct().toList();
+        if (userIds.isEmpty()) {
+            return Result.ok(java.util.Collections.emptyList());
+        }
+        List<SysUser> users = sysUserMapper.selectBatchIds(userIds);
+        List<UserDTO> dtos = users.stream()
+                .filter(u -> u.getStatus() == null || u.getStatus() == 0)
+                .map(u -> {
+                    UserDTO dto = new UserDTO();
+                    dto.setId(u.getId());
+                    dto.setUsername(u.getUsername());
+                    dto.setRealName(u.getRealName());
+                    return dto;
+                }).collect(java.util.stream.Collectors.toList());
+        return Result.ok(dtos);
+    }
+
     @Operation(summary = "查询用户角色列表")
     @GetMapping("/user/{userId}")
     public Result<List<RoleDTO>> listByUserId(@PathVariable Long userId) {

+ 2 - 16
src/main/resources/mapper/flow/ApprovalTaskMapper.xml

@@ -55,28 +55,14 @@
     </select>
 
     <select id="selectHandledList" resultMap="BaseResultMap">
-        SELECT t.*, pi.title as instance_title, pi.instance_no as instance_no, pd.process_name as process_name
+        SELECT DISTINCT t.*, pi.title as instance_title, pi.instance_no as instance_no, pd.process_name as process_name
         FROM bpm_approval_task t
         INNER JOIN bpm_process_instance pi ON t.instance_id = pi.id
         LEFT JOIN bpm_process_definition pd ON pi.process_definition_id = pd.id
+        INNER JOIN bpm_approval_record r ON r.task_id = t.id AND r.operator_id = #{assigneeId}
         WHERE t.deleted = 0
           AND t.task_status IN (1, 2, 4)
           AND t.node_type != 'cc'
-          AND (
-            <choose>
-              <when test="assigneeType == 'ROLE'">
-                  (t.assignee_type = 'ROLE' AND t.assignee_id = #{assigneeId})
-              </when>
-              <when test="roleIds != null and roleIds.size() > 0">
-                  ((t.assignee_type != 'ROLE' AND t.assignee_id = #{assigneeId})
-                   OR (t.assignee_type = 'ROLE' AND t.assignee_id IN
-                       <foreach collection="roleIds" item="roleId" open="(" close=")" separator=",">#{roleId}</foreach>))
-              </when>
-              <otherwise>
-                  (t.assignee_id = #{assigneeId} AND (t.assignee_type IS NULL OR t.assignee_type = '' OR t.assignee_type = 'USER'))
-              </otherwise>
-            </choose>
-          )
         <if test="processName != null and processName != ''">
             AND pd.process_name LIKE CONCAT('%', #{processName}, '%')
         </if>