xuhy
2025-02-20 298a6a7085823ec754762c39affe145bb47e4aaa
合同新增审批
7个文件已修改
3个文件已添加
385 ■■■■■ 已修改文件
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/enums/ProcessCategoryEnum.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/enums/SubmitStatusEnum.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/TContractService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FlowListenerService.java 245 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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();
    }
ruoyi-common/src/main/java/com/ruoyi/common/enums/ProcessCategoryEnum.java
New file
@@ -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;
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/enums/SubmitStatusEnum.java
New file
@@ -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;
    }
}
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);
}
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);
}
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);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FlowListenerService.java
New file
@@ -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("错误类型");
        }
    }
}
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);
    }
}
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);
    }
}
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(