wucl vor 6 Monaten
Ursprung
Commit
bea085f9aa

+ 7 - 1
dao/src/main/resources/mapper/PersonalMapper.xml

@@ -440,7 +440,8 @@
             cc2.NAME AS clientSubName,
             cl1.NAME AS contactName,
             cl1.mobile AS contactTel,
-            u.NAME AS clientManager
+            u.NAME AS clientManager,
+        c.comments
         FROM
             ( SELECT wf.id as currentNodeId, wn.name as currentNodeName,wf.node_id, wf.business_id as id, wf.business_sub_id as orderId FROM work_flow_node_instance wf
                                                                                                                                                  left join work_node wn on (wn.id = wf.node_id and wf.flow_id = wn.flow_id)
@@ -450,6 +451,11 @@
                 LEFT JOIN customer_company cc2 ON cc2.id = p.clientele_sub_id
                 LEFT JOIN customer_linkman cl1 ON cl1.id = p.clientele_contact_id
                 LEFT JOIN `user` u ON u.id = p.client_manager_id
+        left join (
+        select business_id,comments from work_flow_log where concat(business_id,created) in (
+        select concat(business_id,max(created)) from work_flow_log where business_type = 'PERSONAL_BUSINESS' and comments is not null  group BY business_id
+        )
+        ) c on c.business_id = p.id
         WHERE
             p.deleted = 0
         <if test="keyword!=null and keyword!='' ">

+ 6 - 0
domain/src/main/java/com/dayou/enums/ProductionEnum.java

@@ -19,6 +19,12 @@ public enum ProductionEnum implements CodeMsgEnumInterface<String,String>{
 
     CONSULT("CONSULT","咨询报告"),
 
+    CHANGE_STATEMENT("CHANGE_STATEMENT","修改意见书"),
+
+    CHANGE_REPORT("CHANGE_REPORT","修改报告"),
+
+    CHANGE_LETTER("CHANGE_LETTER","修改复评函"),
+
     NONE("NONE","NONE")
     ;
 

+ 2 - 2
domain/src/main/java/com/dayou/enums/workflow/CallbackEnum.java

@@ -109,14 +109,14 @@ public enum CallbackEnum {
             //报告在校验产品类型时节点
             NecessaryNode report = new NecessaryNode();
             report.setProduction(ProductionEnum.REPORT);
-            WorkflowNodeEnum[] workflowNodeEnums1 = {WRITE_REPORT, CHECK_REPORT,REPORT_BOOKBINDING_STAMP,REPORT_IN,REPORT_OUT_APPLY,REPORT_OUT_DEPARTMENT_CHECK,REPORT_OUT};
+            WorkflowNodeEnum[] workflowNodeEnums1 = {WRITE_REPORT, CHECK_REPORT,REPORT_BOOKBINDING_STAMP,REPORT_IN,REPORT_OUT_APPLY,REPORT_OUT_DEPARTMENT_CHECK,REPORT_OUT,REPORT_FEEDBACK};
             report.setNecessaryNodes(workflowNodeEnums1);
             this.necessaryNodes.add(report);
 
             //意见函在校验产品类型时的节点
             NecessaryNode letter = new NecessaryNode();
             letter.setProduction(ProductionEnum.LETTER);
-            WorkflowNodeEnum[] workflowNodeEnums2 = {WRITE_LETTER, CHECK_LETTER,LETTER_BOOKBINDING_STAMP,LETTER_IN,LETTER_OUT_APPLY,LETTER_OUT_DEPARTMENT_CHECK,LETTER_OUT};
+            WorkflowNodeEnum[] workflowNodeEnums2 = {WRITE_LETTER, CHECK_LETTER,LETTER_BOOKBINDING_STAMP,LETTER_IN,LETTER_OUT_APPLY,LETTER_OUT_DEPARTMENT_CHECK,LETTER_OUT,LETTER_FEEDBACK};
             letter.setNecessaryNodes(workflowNodeEnums2);
             this.necessaryNodes.add(letter);
         }

+ 2 - 0
domain/src/main/java/com/dayou/enums/workflow/WorkflowNodeEnum.java

@@ -30,6 +30,8 @@ public enum WorkflowNodeEnum implements CodeMsgEnumInterface<String,String>{
         STATEMENT_OUT("意见书出库","STATEMENT_OUT"),
         STATEMENT_DELIVERY("意见书送达","STATEMENT_DELIVERY"),
         STATEMENT_FEEDBACK("意见书送达反馈","STATEMENT_FEEDBACK"),
+        REPORT_FEEDBACK("报告送达反馈","REPORT_FEEDBACK"),
+        LETTER_FEEDBACK("复评函送达反馈","LETTER_FEEDBACK"),
         WRITE_REPORT("撰写报告","WRITE_REPORT"),
         CHECK_REPORT("审核报告","CHECK_REPORT"),
         LAND_REPORT_NOT_RECORD_CHECK("不备案审核","LAND_REPORT_NOT_RECORD_CHECK"),

+ 5 - 0
pom.xml

@@ -213,6 +213,11 @@
                 <artifactId>jsoup</artifactId>
                 <version>1.11.3</version>
             </dependency>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-starter-websocket</artifactId>
+                <version>2.4.9</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 

+ 5 - 0
service/pom.xml

@@ -113,6 +113,11 @@
             <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-websocket</artifactId>
+        </dependency>
+
     </dependencies>
     <build>
         <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->

+ 6 - 0
service/src/main/java/com/dayou/aspect/SendMessageAOP.java

@@ -2,6 +2,7 @@ package com.dayou.aspect;
 
 import com.dayou.dto.OrderReportDTO;
 import com.dayou.dto.WareHouseDTO;
+import com.dayou.dto.WorkNodeCommit;
 import com.dayou.enums.ProductionEnum;
 import com.dayou.message.MessageTypeEnum;
 import com.dayou.message.annotation.SendMessage;
@@ -59,6 +60,11 @@ public class SendMessageAOP {
             OrderReportDTO orderReportDTO = (OrderReportDTO) arg;
             messageService.packagingMajorAllotCommissionRemind1(orderReportDTO);
         }
+        if (messageTypeEnum.equals(NODE_TODO_REMINDER) && (Boolean) proceed){
+            Object arg = joinPoint.getArgs()[0];
+            WorkNodeCommit commit = (WorkNodeCommit) arg;
+            messageService.packagingNodeTodoReminder(commit);
+        }
         return proceed;
     }
 }

+ 3 - 1
service/src/main/java/com/dayou/message/MessageTypeEnum.java

@@ -21,7 +21,9 @@ public enum MessageTypeEnum {
 
     MAJOR_ALLOT_COMMISSION_REMIND1("MAJOR_ALLOT_COMMISSION_REMIND1","大中型产品提成分配提醒"),
 
-    MAJOR_ALLOT_COMMISSION_REMIND2("MAJOR_ALLOT_COMMISSION_REMIND2","大中型产品提成分配提醒")
+    MAJOR_ALLOT_COMMISSION_REMIND2("MAJOR_ALLOT_COMMISSION_REMIND2","大中型产品提成分配提醒"),
+
+    NODE_TODO_REMINDER("NODE_TODO_REMINDER","待办提醒")
     ;
 
     private String code;

+ 3 - 0
service/src/main/java/com/dayou/service/IMessageService.java

@@ -1,6 +1,7 @@
 package com.dayou.service;
 import com.dayou.dto.OrderReportDTO;
 import com.dayou.dto.WareHouseDTO;
+import com.dayou.dto.WorkNodeCommit;
 import com.dayou.entity.BusinessReply;
 import com.dayou.entity.Message;
 import com.baomidou.mybatisplus.extension.service.IService;
@@ -45,4 +46,6 @@ public interface IMessageService extends IService<Message> {
     void packagingMajorAllotCommissionRemind(List<OrderReportDTO> list);
 
     void packagingMajorAllotCommissionRemind1(OrderReportDTO orderReportDTO);
+
+    void packagingNodeTodoReminder(WorkNodeCommit commit);
 }

+ 10 - 0
service/src/main/java/com/dayou/service/impl/MessageServiceImpl.java

@@ -6,6 +6,7 @@ import com.dayou.common.BaseEntity;
 import com.dayou.dto.OrderReportDTO;
 import com.dayou.dto.ReportDTO;
 import com.dayou.dto.WareHouseDTO;
+import com.dayou.dto.WorkNodeCommit;
 import com.dayou.entity.*;
 import com.dayou.enums.MainBusinessEnum;
 import com.dayou.enums.UserTypeEnum;
@@ -22,6 +23,7 @@ import com.dayou.utils.LoginContext;
 import com.dayou.vo.CommissionDeclareVO;
 import com.dayou.vo.ItemVO;
 import com.dayou.vo.MajorProductionVO;
+import com.dayou.websocket.WebSocketServer;
 import org.apache.commons.collections4.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -88,6 +90,9 @@ public class MessageServiceImpl extends ServiceImpl<MessageMapper, Message> impl
     @Autowired
     private IMajorProductionAllotService majorProductionAllotService;
 
+    @Autowired
+    private WebSocketServer webSocketServer;
+
     @Override
     public Boolean packagingBusinessMessage(BusinessReply originalBO) {
         BusinessMessageBO messageBO = new BusinessMessageBO();
@@ -272,4 +277,9 @@ public class MessageServiceImpl extends ServiceImpl<MessageMapper, Message> impl
 
 
     }
+
+    @Override
+    public void packagingNodeTodoReminder(WorkNodeCommit commit) {
+
+    }
 }

+ 4 - 0
service/src/main/java/com/dayou/service/workflow/IWorkNodeService.java

@@ -4,6 +4,7 @@ import com.dayou.entity.WorkNode;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.dayou.enums.MainBusinessEnum;
+import com.dayou.enums.ProductionEnum;
 import com.dayou.enums.workflow.WorkflowNodeEnum;
 import com.dayou.vo.NameCodeVO;
 
@@ -93,4 +94,7 @@ public interface IWorkNodeService extends IService<WorkNode> {
     void removeNodeCache(Long flowId);
 
     WorkNodeDTO getUniqueNodeByFlowNameAndNodeName(MainBusinessEnum personalBusiness, WorkflowNodeEnum determinePrice);
+
+    //修改产品退回到撰写节点
+    WorkNodeDTO changeProductionRetNextNode(String nodeCode, List<ProductionEnum> production,Long businessId);
 }

+ 3 - 0
service/src/main/java/com/dayou/service/workflow/WorkFlowServiceImpl.java

@@ -18,6 +18,7 @@ import com.dayou.exception.ErrorCode;
 import com.dayou.mapper.WorkFlowMapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.dayou.mapper.WorkTaskRecordMapper;
+import com.dayou.message.annotation.SendMessage;
 import com.dayou.utils.LoginContext;
 import com.dayou.vo.NameCodeVO;
 import com.dayou.workflow.handler.AssetsNodeHandler;
@@ -36,6 +37,7 @@ import java.util.stream.Collectors;
 
 import static com.dayou.enums.MainBusinessEnum.*;
 import static com.dayou.enums.workflow.NodeLogEnum.*;
+import static com.dayou.message.MessageTypeEnum.NODE_TODO_REMINDER;
 
 /**
  * <p>
@@ -114,6 +116,7 @@ public class WorkFlowServiceImpl extends ServiceImpl<WorkFlowMapper, WorkFlow> i
     }
 
     @Override
+    @SendMessage(messageType = NODE_TODO_REMINDER)
     public Boolean commit(WorkNodeCommit workNodeCommit) {
         WorkFlowNodeInstance instanceNode = workFlowNodeInstanceService.getById(workNodeCommit.getInstanceNodeId());
         if (instanceNode==null){

+ 39 - 8
service/src/main/java/com/dayou/service/workflow/WorkNodeServiceImpl.java

@@ -1,12 +1,14 @@
 package com.dayou.service.workflow;
 
 import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.dayou.common.BaseEntity;
 import com.dayou.dto.HandlerPermissionDTO;
 import com.dayou.dto.WorkNodeDTO;
+import com.dayou.entity.PersonalTarget;
 import com.dayou.entity.WorkFlow;
 import com.dayou.entity.WorkNode;
 import com.dayou.entity.WorkNodeTask;
@@ -17,6 +19,7 @@ import com.dayou.enums.workflow.NodeTaskVersion;
 import com.dayou.mapper.WorkFlowMapper;
 import com.dayou.mapper.WorkNodeMapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.dayou.service.IPersonalTargetService;
 import com.dayou.vo.NameCodeVO;
 import com.dayou.enums.workflow.WorkflowNodeEnum;
 import com.google.common.cache.Cache;
@@ -28,12 +31,10 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
+import java.util.*;
 import java.util.stream.Collectors;
 
+import static com.dayou.enums.ProductionEnum.*;
 import static com.dayou.enums.workflow.WorkflowNodeEnum.*;
 
 /**
@@ -58,6 +59,9 @@ public class WorkNodeServiceImpl extends ServiceImpl<WorkNodeMapper, WorkNode> i
     private WorkFlowMapper workFlowMapper;
 
     @Autowired
+    private IPersonalTargetService personalTargetService;
+
+    @Autowired
     @Qualifier("workflowCache")
     private Cache<Long, List<WorkNodeDTO>> workflowCache;
 
@@ -259,10 +263,10 @@ public class WorkNodeServiceImpl extends ServiceImpl<WorkNodeMapper, WorkNode> i
                 //大中型业务 :归档审核
                 return flowNodes.stream().filter(x -> x.getCode().equals(WorkflowNodeEnum.CHECK_ARCHIVING.name())).findFirst().get();
             }
-            if (mainBusinessEnum.equals(MainBusinessEnum.PERSONAL_BUSINESS)) {
-                //个贷业务 :归档
-                return flowNodes.stream().filter(x -> x.getCode().equals(WorkflowNodeEnum.BUSINESS_ARCHIVING.name())).findFirst().get();
-            }
+//            if (mainBusinessEnum.equals(MainBusinessEnum.PERSONAL_BUSINESS)) {
+//                //个贷业务 :归档
+//                return flowNodes.stream().filter(x -> x.getCode().equals(WorkflowNodeEnum.BUSINESS_ARCHIVING.name())).findFirst().get();
+//            }
 
         }
         return null;
@@ -365,10 +369,37 @@ public class WorkNodeServiceImpl extends ServiceImpl<WorkNodeMapper, WorkNode> i
         return workNodeMapper.getUniqueNodeByFlowNameAndNodeName(businessEnum.name(),nodeEnum.name());
     }
 
+    @Override
+    public WorkNodeDTO changeProductionRetNextNode(String nodeCode, List<ProductionEnum> production,Long businessId) {
+        if (STATEMENT_FEEDBACK.name().equals(nodeCode) && production.contains(CHANGE_STATEMENT)){
+            production.remove(CHANGE_STATEMENT);
+            String feed = JSON.toJSONString(production);
+            personalTargetService.update(new LambdaUpdateWrapper<PersonalTarget>().eq(PersonalTarget::getPersonalId,businessId).set(PersonalTarget::getFeedback,feed));
+            return this.getUniqueNodeByFlowNameAndNodeName(MainBusinessEnum.PERSONAL_BUSINESS,GENERATE_STATEMENT);
+        }
+        if (REPORT_FEEDBACK.name().equals(nodeCode) && production.contains(CHANGE_REPORT)){
+            production.remove(CHANGE_REPORT);
+            String feed = JSON.toJSONString(production);
+            personalTargetService.update(new LambdaUpdateWrapper<PersonalTarget>().eq(PersonalTarget::getPersonalId,businessId).set(PersonalTarget::getFeedback,feed));
+            return this.getUniqueNodeByFlowNameAndNodeName(MainBusinessEnum.PERSONAL_BUSINESS,WRITE_REPORT);
+        }
+        if (LETTER_FEEDBACK.name().equals(nodeCode) && production.contains(CHANGE_LETTER)){
+            production.remove(CHANGE_LETTER);
+            String feed = JSON.toJSONString(production);
+            personalTargetService.update(new LambdaUpdateWrapper<PersonalTarget>().eq(PersonalTarget::getPersonalId,businessId).set(PersonalTarget::getFeedback,feed));
+            return this.getUniqueNodeByFlowNameAndNodeName(MainBusinessEnum.PERSONAL_BUSINESS,WRITE_LETTER);
+        }
+        if (production.contains(NONE)){
+            return this.getUniqueNodeByFlowNameAndNodeName(MainBusinessEnum.PERSONAL_BUSINESS,BUSINESS_ARCHIVING);
+        }
+        return null;
+    }
+
 
     private WorkNodeDTO findNext(Long priviousId, List<WorkNodeDTO> nodes) {
         Optional<WorkNodeDTO> target = nodes.stream().filter(n -> n.getPriviousNodeId() != null)
                 .filter(x -> (x.getPriviousNodeId().equals(priviousId))).findFirst();
         return target.orElse(null);
     }
+
 }

+ 21 - 0
service/src/main/java/com/dayou/websocket/WebSocketConfig.java

@@ -0,0 +1,21 @@
+package com.dayou.websocket;
+
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+import javax.websocket.server.ServerEndpointConfig;
+
+@Configuration
+public class WebSocketConfig extends ServerEndpointConfig.Configurator {
+
+    /**
+     * 注入ServerEndpointExporter,@Bean会自动注册使用@ServerEndpoint注解声明的websocket端点endpoint
+     * @return
+     */
+    @Bean
+    public ServerEndpointExporter serverEndpointExporter(){
+        return new ServerEndpointExporter();
+    }
+}

+ 104 - 0
service/src/main/java/com/dayou/websocket/WebSocketServer.java

@@ -0,0 +1,104 @@
+package com.dayou.websocket;
+
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+
+import javax.websocket.*;
+import javax.websocket.server.ServerEndpoint;
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/20
+ * created with IntelliJ IDEA.
+ */
+@Component
+@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
+@ServerEndpoint(value="/ws",configurator = WebSocketConfig.class)
+public class WebSocketServer {
+
+    private static AtomicInteger atomicInteger = new AtomicInteger(0);
+
+    private static ConcurrentHashMap<String,WebSocketServer> webSocketMap = new ConcurrentHashMap<>();
+
+    private Session session;
+
+    private static final String MSG = "{\"data\":\"*\"}";
+
+    /**
+     * 连接建立成功调用的方法
+     * @param session
+     */
+    @OnOpen
+    public void onOpen(Session session){
+        atomicInteger.incrementAndGet();
+        String sessionId = session.getId();
+        this.session = session;
+        System.out.println("建立连接成功 onOpen 线程数量:"+atomicInteger.get()+" sessionID:"+ session.getId());
+        System.out.println("当前socket连接数量:" + webSocketMap.size());
+        webSocketMap.put(sessionId,this);
+        sendSocket("userSize");
+    }
+
+    /**
+     * 连接关闭调用的方法
+     * @param session
+     */
+    @OnClose
+    public void onClose(Session session){
+        System.out.println("一个客户端断开连接:" + session.getId());
+        atomicInteger.incrementAndGet();
+        webSocketMap.remove(session.getId());
+        sendSocket("userSize");
+
+    }
+
+    /**
+     * 接收到客户端消息后调用的方法
+     * @param msg 客户端发送的消息
+     * @param session
+     */
+    @OnMessage
+    public void onMessage(String msg, Session session) throws IOException {
+        atomicInteger.incrementAndGet();
+        System.out.println("接收到客户端发送的消息 onMessage:"+ msg+" 线程数量:"+atomicInteger.get()+" sessionID:"+session.getId());
+        session.getBasicRemote().sendText(msg);
+    }
+
+    /**
+     * 出现错误时调用的方法
+     * @param session
+     * @param throwable
+     */
+    @OnError
+    public void onError(Session session, Throwable throwable){
+        atomicInteger.incrementAndGet();
+        System.out.println("错误 onError 线程数量:"+atomicInteger.get()+" sessionID:"+session.getId());
+        throwable.printStackTrace();
+    }
+
+    public void sendSocket(String key){
+        System.out.println("sessions:"+webSocketMap.size());
+        if (webSocketMap.size()>0){
+            for(Map.Entry<String, WebSocketServer> map : webSocketMap.entrySet()){
+                try {
+                    if (key.equals("data")){
+                        map.getValue().session.getBasicRemote().sendText(MSG);
+                    }
+                    else {
+                        String userSize = "{\"userSize\":"+webSocketMap.size()+"}";
+                        map.getValue().session.getBasicRemote().sendText(userSize);
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+}

+ 19 - 6
service/src/main/java/com/dayou/workflow/handler/PersonalNodeHandler.java

@@ -84,11 +84,20 @@ public class PersonalNodeHandler extends WorkNodeProcessable {
                     List<ProductionEnum> production = workNodeCommit.getProduction();
                     switch (callback) {
                         case CHECK_PERSONAL_PRODUCTION_TYPE:
-                            //1. 获取业务上出具的产品类型。
-                            //2.根据出具的产品类型 确定需要哪些节点
-                            Map<String, List<WorkflowNodeEnum>> personalNecessaryNodes = CallbackEnum.NecessaryNode.getByProduction(PERSONAL_BUSINESS.name(),
-                                    production);
-                            nextWorkNode = workNodeService.getNextWorkNodeByBusiness(currentInstanceNode.getFlowId(), PERSONAL_BUSINESS, currentInstanceNode.getNodeCode(), personalNecessaryNodes,null);
+                            //检查是否需要修改产品
+                            WorkNodeDTO workNodeDTO = workNodeService.changeProductionRetNextNode(currentInstanceNode.getNodeCode(), production, currentInstanceNode.getBusinessId());
+                            if (workNodeDTO==null){
+                                //1. 获取业务上出具的产品类型。
+                                //2.根据出具的产品类型 确定需要哪些节点
+                                Map<String, List<WorkflowNodeEnum>> personalNecessaryNodes = CallbackEnum.NecessaryNode.getByProduction(PERSONAL_BUSINESS.name(),
+                                        production);
+                                WorkNodeDTO next = workNodeService.getNextWorkNodeByBusiness(currentInstanceNode.getFlowId(), PERSONAL_BUSINESS, currentInstanceNode.getNodeCode(), personalNecessaryNodes, null);
+                                if (next != null) {
+                                    nextWorkNode = next;
+                                }
+                            }else{
+                                nextWorkNode = workNodeDTO;
+                            }
                             break;
                         case CHECK_FEEDBACK:
                             if (workNodeCommit.getIfFeedback()!=null && !workNodeCommit.getIfFeedback()) {
@@ -101,7 +110,11 @@ public class PersonalNodeHandler extends WorkNodeProcessable {
                             Long ccId = workNodeCommit.getCcId();
                             if (ccId !=null){
                                 if (customerCompanyService.avoidWareHouseApply(ccId)){
-                                    nextWorkNode = workNodeService.getUniqueNodeByFlowNameAndNodeName(PERSONAL_BUSINESS,REPORT_OUT);
+                                    if (currentInstanceNode.getNodeCode().equals(REPORT_IN.name())){
+                                        nextWorkNode = workNodeService.getUniqueNodeByFlowNameAndNodeName(PERSONAL_BUSINESS,REPORT_OUT);
+                                    }else {
+                                        nextWorkNode = workNodeService.getUniqueNodeByFlowNameAndNodeName(PERSONAL_BUSINESS,LETTER_OUT);
+                                    }
                                 }
                             }
                     }