From 298a6a7085823ec754762c39affe145bb47e4aaa Mon Sep 17 00:00:00 2001
From: xuhy <3313886187@qq.com>
Date: 星期四, 20 二月 2025 18:08:30 +0800
Subject: [PATCH] 合同新增审批

---
 ruoyi-common/src/main/java/com/ruoyi/common/enums/ProcessCategoryEnum.java         |   51 +++++++
 ruoyi-common/src/main/java/com/ruoyi/common/enums/SubmitStatusEnum.java            |   33 ++++
 ruoyi-system/src/main/java/com/ruoyi/system/service/TContractService.java          |    3 
 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java           |    2 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java    |   25 +++
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FlowListenerService.java  |  245 +++++++++++++++++++++++++++++++++++
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java |    8 +
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java   |    5 
 ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml                    |   11 +
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java              |    2 
 10 files changed, 381 insertions(+), 4 deletions(-)

diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java
index 391f5dc..c0e4618 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java
@@ -3,6 +3,7 @@
 
 import cn.afterturn.easypoi.excel.ExcelExportUtil;
 import cn.afterturn.easypoi.excel.entity.ExportParams;
+import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.ruoyi.common.annotation.Log;
 import com.ruoyi.common.basic.PageInfo;
@@ -10,10 +11,9 @@
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.common.enums.BusinessType;
-import com.ruoyi.common.utils.DateUtils;
-import com.ruoyi.common.utils.DictUtils;
-import com.ruoyi.common.utils.StringUtils;
-import com.ruoyi.common.utils.WebUtils;
+import com.ruoyi.common.enums.ProcessCategoryEnum;
+import com.ruoyi.common.utils.*;
+import com.ruoyi.system.bo.ProcessStartBO;
 import com.ruoyi.system.dto.*;
 import com.ruoyi.system.export.ContractExport;
 import com.ruoyi.system.export.OpticalInspectionExport;
@@ -71,6 +71,8 @@
     private TBillService billService;
     @Autowired
     private TCheckAcceptRecordService checkAcceptRecordService;
+    @Autowired
+    private StateProcessTemplateService stateProcessTemplateService;
 
     @ApiOperation(value = "测试生成账单")
     @PostMapping(value = "/testBill")
@@ -197,6 +199,21 @@
             tContractRentType.setChangeTime(dto.getChangeTime());
             tContractRentType.setCycleTime(dto.getCycleTime());
             contractRentTypeService.save(tContractRentType);
+
+            //发起合同新增审批
+            ProcessStartBO processStartBO = new ProcessStartBO();
+            processStartBO.setCategory(ProcessCategoryEnum.CATEGORY1.getValue().toString());
+            processStartBO.setModuleName("合同新增审批");
+            processStartBO.setName(dto.getContractName());
+            //需要显示发起申请人所在单位
+//            String cedName = SecurityUtils.getLoginUser().getUser().getDept().getDeptName();
+//            String remark = String.format("【镇/街】:%s,【征收实施单位】:%s,【申请金额】:%s万元", stateProject.getStreet(), cedName, stateApplyRecord.getAmount());
+            processStartBO.setRemark("");
+            Map<String, Object> variable = new HashMap<>();
+            variable.put("projectId", dto.getId());
+            processStartBO.setVariable(variable);
+            //开启工作流程
+            stateProcessTemplateService.start(processStartBO);
         }
         return R.ok();
     }
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/ProcessCategoryEnum.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/ProcessCategoryEnum.java
new file mode 100644
index 0000000..0b27e26
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/ProcessCategoryEnum.java
@@ -0,0 +1,51 @@
+package com.ruoyi.common.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 1. 入户调查
+ * 2. 价格评估
+ * 3. 协议签订
+ * 固定对应表 state_process_module
+ */
+@Getter
+@AllArgsConstructor
+public enum ProcessCategoryEnum {
+    CATEGORY0(0, "错误分类"),
+    CATEGORY1(1, "入户调查"),
+    CATEGORY2(2, "价格评估"),
+    CATEGORY3(3, "协议签订"),
+    ;
+
+
+    private final Integer value;
+    private final String text;
+
+    public static Integer getValue(String text) {
+        for (ProcessCategoryEnum v : ProcessCategoryEnum.values()) {
+            if (v.text.equals(text)) {
+                return v.value;
+            }
+        }
+        return 0;
+    }
+
+    public static String getValueByKey(Integer key) {
+        for (ProcessCategoryEnum v : ProcessCategoryEnum.values()) {
+            if (v.getValue().equals(key)) {
+                return v.getText();
+            }
+        }
+        return "";
+    }
+
+    public static ProcessCategoryEnum getEnumByKey(Integer key) {
+        for (ProcessCategoryEnum v : ProcessCategoryEnum.values()) {
+            if (v.getValue().equals(key)) {
+                return v;
+            }
+        }
+        return CATEGORY0;
+    }
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/SubmitStatusEnum.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/SubmitStatusEnum.java
new file mode 100644
index 0000000..9e231f3
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/SubmitStatusEnum.java
@@ -0,0 +1,33 @@
+package com.ruoyi.common.enums;
+
+import lombok.Getter;
+
+import java.util.Objects;
+
+@Getter
+public enum SubmitStatusEnum {
+    SUBMITTED(-1, ""),
+    REJECT(0, "已退回"),
+    PENDING_REVIEW(1, "待审核"),
+    ACCEPT(3, "已接收");
+
+    private final int value;
+    private final String text;
+
+    public static String getTextByValue(Integer value) {
+        if (Objects.isNull(value)) {
+            return "";
+        }
+        for (SubmitStatusEnum v : SubmitStatusEnum.values()) {
+            if (v.getValue() == (value)) {
+                return v.getText();
+            }
+        }
+        return "";
+    }
+
+    SubmitStatusEnum(int value, String text) {
+        this.text = text;
+        this.value = value;
+    }
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java
index 9d66e47..ada62eb 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java
@@ -127,4 +127,6 @@
 
     List<SysRole> selectPageList(@Param("query")SysRoleQuery query,@Param("pageInfo") PageInfo<SysRole> pageInfo);
 
+    List<SysRole> selectRoleByUserIds(@Param("roleIds")List<String> roleIds);
+
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java
index 7a50061..063e8a5 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java
@@ -232,4 +232,6 @@
      * @return 结果
      */
     public int editRole(SysRoleDTO dto);
+
+    List<SysRole> selectRoleByUserIds(List<String> roleIds);
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/TContractService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/TContractService.java
index 5139836..00b2a31 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/TContractService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/TContractService.java
@@ -40,4 +40,7 @@
     void export(TContractQuery query);
 
     List<TContract> contractExportList(TContractQuery query);
+
+    Boolean updateContractAuditStatus(String projectId, Integer submitStatus);
+
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FlowListenerService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FlowListenerService.java
new file mode 100644
index 0000000..6ee462d
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FlowListenerService.java
@@ -0,0 +1,245 @@
+package com.ruoyi.system.service.impl;
+
+
+import cn.hutool.core.util.ObjectUtil;
+import com.aizuda.bpm.engine.FlowLongEngine;
+import com.aizuda.bpm.engine.assist.ObjectUtils;
+import com.aizuda.bpm.engine.core.FlowCreator;
+import com.aizuda.bpm.engine.core.FlowLongContext;
+import com.aizuda.bpm.engine.core.enums.EventType;
+import com.aizuda.bpm.engine.core.enums.NodeApproveSelf;
+import com.aizuda.bpm.engine.core.enums.NodeSetType;
+import com.aizuda.bpm.engine.core.enums.TaskType;
+import com.aizuda.bpm.engine.entity.FlwExtInstance;
+import com.aizuda.bpm.engine.entity.FlwHisTask;
+import com.aizuda.bpm.engine.entity.FlwTask;
+import com.aizuda.bpm.engine.entity.FlwTaskActor;
+import com.aizuda.bpm.engine.listener.TaskListener;
+import com.aizuda.bpm.engine.model.NodeAssignee;
+import com.aizuda.bpm.engine.model.NodeModel;
+import com.aizuda.bpm.engine.model.ProcessModel;
+import com.aizuda.bpm.mybatisplus.mapper.FlwExtInstanceMapper;
+import com.aizuda.bpm.mybatisplus.mapper.FlwHisTaskMapper;
+import com.aizuda.bpm.mybatisplus.mapper.FlwTaskActorMapper;
+import com.aizuda.bpm.mybatisplus.mapper.FlwTaskMapper;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.ruoyi.common.core.domain.entity.SysRole;
+import com.ruoyi.common.enums.ProcessCategoryEnum;
+import com.ruoyi.common.enums.SubmitStatusEnum;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.system.service.ISysRoleService;
+import com.ruoyi.system.service.TContractService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+
+
+/**
+ * 工作流程全局任务监听 同步方式  只监听流程完成、流程中断类型,修改拒绝状态
+ * <p>
+ * 1. 入户调查
+ * 2. 价格评估
+ * 3. 协议签订
+ * 4. 资金管理-预算资金
+ * 5. 住宅临时安置补助费
+ * 6. 停产停业经济损失补助费
+ * 7. 安置情况(流程图中叫做录入货币补偿金额信息)
+ * 固定对应表 state_process_module
+ */
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class FlowListenerService implements TaskListener {
+
+    private final FlwExtInstanceMapper flwExtInstanceMapper;
+    private final FlowLongEngine flowLongEngine;
+    private final FlwTaskActorMapper flwTaskActorMapper;
+    private final FlwHisTaskMapper flwHisTaskMapper;
+    private final ISysRoleService sysRoleService;
+    private final FlwTaskMapper flwTaskMapper;
+    private final TContractService contractService;
+
+
+    @Override
+    public boolean notify(EventType eventType, Supplier<FlwTask> supplier, NodeModel nodeModel, FlowCreator flowCreator) {
+        FlwTask flwTask = supplier.get();
+        if (ObjectUtil.isNull(flwTask)) {
+            return true;
+        }
+        // 创建任务时候,判断是否自动审批通过
+        if (EventType.create.eq(eventType)) {
+            Integer approveSelf = nodeModel.getApproveSelf();
+            if (NodeApproveSelf.AutoSkip.eq(approveSelf)) {
+                // 普通成员情况
+                List<NodeAssignee> nodeAssigneeList = null;
+                if (NodeSetType.specifyMembers.eq(nodeModel.getSetType())) {
+                    nodeAssigneeList = nodeModel.getNodeAssigneeList();
+                    if (ObjectUtil.isEmpty(nodeAssigneeList)) {
+                        return true;
+                    }
+                    //查询发起人
+                    LambdaQueryWrapper<FlwHisTask> flwHisTaskLambdaQueryWrapper = new LambdaQueryWrapper<>();
+                    flwHisTaskLambdaQueryWrapper.eq(FlwTask::getTaskType, TaskType.major.getValue());
+                    flwHisTaskLambdaQueryWrapper.eq(FlwTask::getInstanceId, flwTask.getInstanceId());
+                    FlwHisTask flwHisTask = flwHisTaskMapper.selectOne(flwHisTaskLambdaQueryWrapper);
+                    if (ObjectUtil.isEmpty(flwHisTask)) {
+                        return true;
+                    }
+                    //对比发起人和节点审批人
+                    if (nodeAssigneeList.stream().noneMatch(t -> Objects.equals(t.getId(), flwHisTask.getCreateId()))) {
+                        return true;
+                    }
+                    //查询当前节点审核人是否与创建人一致
+                    List<FlwTaskActor> flwTaskActor = flwTaskActorMapper.selectListByTaskId(flwTask.getId());
+                    if (ObjectUtil.isNotEmpty(flwTaskActor)) {
+                        for (FlwTaskActor flwTaskActor1 : flwTaskActor) {
+                            if (flwTaskActor1.getActorId().equals(flwHisTask.getCreateId())) {
+                                return flowLongEngine.autoJumpTask(flwTask.getId(), flowCreator);
+                            }
+                        }
+                    }
+                } else if (NodeSetType.role.eq(nodeModel.getSetType())) {
+                    //角色任务跳过
+                    nodeAssigneeList = nodeModel.getNodeAssigneeList();
+                    //获取角色下的用户
+                    List<String> roleIds = nodeAssigneeList.stream().map(NodeAssignee::getId).collect(Collectors.toList());
+                    List<SysRole> actorList = sysRoleService.selectRoleByUserIds(roleIds);
+                    List<FlwTaskActor> flwTaskActors = new ArrayList<>();
+                    if(ObjectUtils.isNotEmpty(actorList)) {
+                        for (SysRole sysRole : actorList) {
+                            if(ObjectUtil.isEmpty(sysRole.getRoleName())) {
+                                continue;
+                            }
+                            NodeAssignee nodeAssignee = new NodeAssignee();
+                            nodeAssignee.setId(String.valueOf(sysRole.getRoleId()));
+                            nodeAssignee.setName(sysRole.getRoleName());
+                            flwTaskActors.add(FlwTaskActor.of(nodeAssignee, 0));
+                        }
+                    }
+                    if (ObjectUtil.isEmpty(flwTaskActors)) {
+                        return true;
+                    }
+                    //查询发起人
+                    LambdaQueryWrapper<FlwHisTask> flwHisTaskLambdaQueryWrapper = new LambdaQueryWrapper<>();
+                    flwHisTaskLambdaQueryWrapper.eq(FlwTask::getTaskType, TaskType.major.getValue());
+                    flwHisTaskLambdaQueryWrapper.eq(FlwTask::getInstanceId, flwTask.getInstanceId());
+                    FlwHisTask flwHisTask = flwHisTaskMapper.selectOne(flwHisTaskLambdaQueryWrapper);
+                    if (ObjectUtil.isEmpty(flwHisTask)) {
+                        return true;
+                    }
+                    //对比发起人和节点审批人
+                    if (flwTaskActors.stream().noneMatch(t -> Objects.equals(t.getActorId(), flwHisTask.getCreateId()))) {
+                        return true;
+                    }
+                    //查询当前节点审核人是否与创建人一致
+                    List<FlwTaskActor> flwTaskActor = flwTaskActorMapper.selectListByTaskId(flwTask.getId());
+                    if (ObjectUtil.isNotEmpty(flwTaskActor)) {
+                        for (FlwTaskActor flwTaskActor1 : flwTaskActor) {
+                            if (flwTaskActor1.getActorId().equals(flwHisTask.getCreateId())) {
+                                return flowLongEngine.autoJumpTask(flwTask.getId(), flowCreator);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        if (eventType.equals(EventType.reject) || eventType.equals(EventType.autoReject)) {
+            System.out.println("流程失败:" + flwTask.getVariable());
+            handlerBusiness(flwTask.getVariable(), 2);
+        } else if (eventType.equals(EventType.complete)) {
+            // 查询流程模型
+            FlwExtInstance flwExtInstance = flwExtInstanceMapper.selectById(flwTask.getInstanceId());
+            String modelContent = flwExtInstance.getModelContent();
+            ProcessModel processModel = FlowLongContext.parseProcessModel(modelContent, null, false);
+            NodeModel node = processModel.getNode(flwTask.getTaskKey());
+            if (ObjectUtil.isEmpty(node)) {
+                log.error("节点不存在 TaskName:{} InstanceId:{}", flwTask.getTaskName(), flwTask.getInstanceId());
+                return true;
+            }
+            long count = flwTaskMapper.selectCount(new LambdaQueryWrapper<FlwTask>().eq(FlwTask::getInstanceId,flwTask.getInstanceId()));
+            if(count > 0){
+                return true;
+            }
+            //最后一个节点
+            if (ObjectUtil.isEmpty(node.getChildNode()) || ObjectUtil.isEmpty(node.getChildNode().getNodeName())) {
+                System.out.println("流程完成:" + flwTask.getVariable());
+                handlerBusiness(flwTask.getVariable(), 1);
+            }
+        } else if (eventType.eq(EventType.cc)) {
+            // 查询流程模型//抄送
+            FlwExtInstance flwExtInstance = flwExtInstanceMapper.selectById(flwTask.getInstanceId());
+            String modelContent = flwExtInstance.getModelContent();
+            ProcessModel processModel = FlowLongContext.parseProcessModel(modelContent, null, false);
+            NodeModel node = processModel.getNode(flwTask.getTaskKey());
+            if (ObjectUtil.isEmpty(node)) {
+                log.error("节点不存在 TaskName:{} InstanceId:{}", flwTask.getTaskName(), flwTask.getInstanceId());
+                return true;
+            }
+            //抄送是最后一个节点
+            if (ObjectUtil.isEmpty(node.getChildNode()) || ObjectUtil.isEmpty(node.getChildNode().getNodeName())) {
+                System.out.println("流程完成:" + flwTask.getVariable());
+                handlerBusiness(flwTask.getVariable(), 1);
+            }
+        } else if(eventType.eq(EventType.autoJump)){
+            // 查询流程模型 自动跳转
+            FlwExtInstance flwExtInstance = flwExtInstanceMapper.selectById(flwTask.getInstanceId());
+            String modelContent = flwExtInstance.getModelContent();
+            ProcessModel processModel = FlowLongContext.parseProcessModel(modelContent, null, false);
+            NodeModel node = processModel.getNode(flwTask.getTaskKey());
+            if (ObjectUtil.isEmpty(node)) {
+                log.error("节点不存在 TaskName:{} InstanceId:{}", flwTask.getTaskName(), flwTask.getInstanceId());
+                return true;
+            }
+            long count = flwTaskMapper.selectCount(new LambdaQueryWrapper<FlwTask>().eq(FlwTask::getInstanceId,flwTask.getInstanceId()));
+            if(count > 0){
+                return true;
+            }
+            //最后一个节点
+            if (ObjectUtil.isEmpty(node.getChildNode()) || ObjectUtil.isEmpty(node.getChildNode().getNodeName())) {
+                System.out.println("流程完成:" + flwTask.getVariable());
+                handlerBusiness(flwTask.getVariable(), 1);
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 业务状态变更
+     */
+    private void handlerBusiness(String variable, Integer status) {
+        JSONObject processParameter = JSON.parseObject(variable);
+        //必须参数,肯定有不判断null
+        Integer category = processParameter.getInteger("category");
+        //状态 暂定:0待审核 1审核通过 2审核拒绝
+        ProcessCategoryEnum categoryEnum = ProcessCategoryEnum.getEnumByKey(category);
+        switch (categoryEnum) {
+            case CATEGORY1: {
+                // 合同新增审批
+                int submitStatus = status==0?2:(status==1?3:5);
+                contractService.updateContractAuditStatus(processParameter.getString("projectId"), submitStatus);
+                break;
+            }
+            case CATEGORY2: {
+                // 合同签订审批
+                break;
+            }
+            case CATEGORY3: {
+                // 合同提前终止审批
+                break;
+            }
+            default:
+                throw new ServiceException("错误类型");
+        }
+
+    }
+
+}
\ No newline at end of file
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java
index 86924f1..a310cf7 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java
@@ -606,4 +606,9 @@
 
         return roleMenuMapper.batchRoleMenu(sysRoleMenus);
     }
+
+    @Override
+    public List<SysRole> selectRoleByUserIds(List<String> roleIds) {
+        return roleMapper.selectRoleByUserIds(roleIds);
+    }
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java
index cbfbde3..61c5b1f 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java
@@ -1,6 +1,7 @@
 package com.ruoyi.system.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.ruoyi.common.basic.PageInfo;
 import com.ruoyi.common.constant.DictConstants;
 import com.ruoyi.common.core.domain.R;
@@ -638,4 +639,11 @@
 
         return list;
     }
+
+    @Override
+    public Boolean updateContractAuditStatus(String projectId, Integer status) {
+        LambdaUpdateWrapper<TContract> contractLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+        contractLambdaUpdateWrapper.eq(TContract::getId, projectId).set(TContract::getStatus, status);
+        return this.update(contractLambdaUpdateWrapper);
+    }
 }
diff --git a/ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml
index f24c54f..f3dfeeb 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml
@@ -148,6 +148,17 @@
 		left join sys_role t2 on t1.role_id = t2.role_id
 		where t1.user_id = #{userId}
 	</select>
+    <select id="selectRoleByUserIds" resultType="com.ruoyi.common.core.domain.entity.SysRole">
+		select
+		a.user_id as role_id,
+		b.nick_name as role_name
+		from sys_user_role a
+		left join sys_user b on a.user_id = b.user_id
+		where a.role_id in
+		<foreach item="item" index="index" collection="roleIds" open="(" separator="," close=")">
+			#{item}
+		</foreach>
+	</select>
 
     <insert id="insertRole" parameterType="SysRole" useGeneratedKeys="true" keyProperty="roleId">
  		insert into sys_role(

--
Gitblit v1.7.1