From e4ee26d6e5da074c5a682bed33d193974297537c Mon Sep 17 00:00:00 2001
From: xiangpei <xiangpei@timesnew.cn>
Date: 星期五, 13 十二月 2024 17:55:44 +0800
Subject: [PATCH] bug修改、任务驳回功能基础实现

---
 business/src/main/java/com/ycl/service/impl/ProjectProcessServiceImpl.java |   55 +++++++++----
 flowable/src/main/java/com/ycl/service/common/TaskCommonService.java       |   85 +++++++++++++++++++++
 flowable/src/main/java/com/ycl/service/impl/FlowTaskServiceImpl.java       |   32 ++++---
 business/src/main/java/com/ycl/controller/ProjectProcessController.java    |    8 ++
 business/src/main/java/com/ycl/domain/form/RejectTaskForm.java             |   36 +++++++++
 business/src/main/java/com/ycl/service/ProjectProcessService.java          |    9 ++
 6 files changed, 191 insertions(+), 34 deletions(-)

diff --git a/business/src/main/java/com/ycl/controller/ProjectProcessController.java b/business/src/main/java/com/ycl/controller/ProjectProcessController.java
index 1018841..ad52818 100644
--- a/business/src/main/java/com/ycl/controller/ProjectProcessController.java
+++ b/business/src/main/java/com/ycl/controller/ProjectProcessController.java
@@ -2,6 +2,7 @@
 
 import com.ycl.common.group.Update;
 import com.ycl.common.group.Add;
+import com.ycl.domain.form.RejectTaskForm;
 import com.ycl.domain.query.TaskQuery;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -81,6 +82,13 @@
         return projectProcessService.taskIsAuditing(processDefId, taskId);
     }
 
+    @PostMapping("/detail/task/reject")
+    @ApiOperation(value = "椹冲洖", notes = "椹冲洖")
+//    @PreAuthorize("@ss.hasPermi('projectProcess:detail')")
+    public Result rejectTask(@RequestBody RejectTaskForm form) {
+        return projectProcessService.rejectTask(form);
+    }
+
 
     @GetMapping("/to_do_task")
     @ApiOperation(value = "鍒嗛〉", notes = "鍒嗛〉")
diff --git a/business/src/main/java/com/ycl/domain/form/RejectTaskForm.java b/business/src/main/java/com/ycl/domain/form/RejectTaskForm.java
new file mode 100644
index 0000000..3abdbc2
--- /dev/null
+++ b/business/src/main/java/com/ycl/domain/form/RejectTaskForm.java
@@ -0,0 +1,36 @@
+package com.ycl.domain.form;
+
+import lombok.Data;
+
+/**
+ * @author锛歺p
+ * @date锛�2024/12/13 13:51
+ */
+@Data
+public class RejectTaskForm {
+
+    /**
+     * 褰撳墠浠诲姟id
+     *
+     */
+    private String taskId;
+
+    /**
+     * 琚┏鍥炵殑浠诲姟瀹氫箟id
+     *
+     */
+    private String rejectedTaskDefKey;
+
+    /**
+     * 瀹℃牳鎰忚
+     *
+     */
+    private String auditOpinion;
+
+    /**
+     * 娴佺▼瀹炰緥id
+     *
+     */
+    private String processInsId;
+
+}
diff --git a/business/src/main/java/com/ycl/service/ProjectProcessService.java b/business/src/main/java/com/ycl/service/ProjectProcessService.java
index ea82840..2beb75d 100644
--- a/business/src/main/java/com/ycl/service/ProjectProcessService.java
+++ b/business/src/main/java/com/ycl/service/ProjectProcessService.java
@@ -4,6 +4,7 @@
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.ycl.common.base.Result;
 import com.ycl.domain.form.ProjectProcessForm;
+import com.ycl.domain.form.RejectTaskForm;
 import com.ycl.domain.query.ProjectProcessQuery;
 import com.ycl.domain.query.TaskQuery;
 import com.ycl.domain.vo.CustomerTaskVO;
@@ -78,4 +79,12 @@
      * @return
      */
     Result taskIsAuditing(String processDefinitionId, String taskId);
+
+    /**
+     * 椹冲洖浠诲姟
+     *
+     * @param form
+     * @return
+     */
+    Result rejectTask(RejectTaskForm form);
 }
diff --git a/business/src/main/java/com/ycl/service/impl/ProjectProcessServiceImpl.java b/business/src/main/java/com/ycl/service/impl/ProjectProcessServiceImpl.java
index 71e3bcc..46d7ee4 100644
--- a/business/src/main/java/com/ycl/service/impl/ProjectProcessServiceImpl.java
+++ b/business/src/main/java/com/ycl/service/impl/ProjectProcessServiceImpl.java
@@ -19,6 +19,7 @@
 import com.ycl.domain.dto.FlowTaskDto;
 import com.ycl.domain.entity.ProjectInfo;
 import com.ycl.domain.entity.ProjectProcess;
+import com.ycl.domain.form.RejectTaskForm;
 import com.ycl.domain.vo.CustomerTaskVO;
 import com.ycl.domain.vo.ProjectProcessDetailVO;
 import com.ycl.mapper.ProjectInfoMapper;
@@ -358,6 +359,13 @@
         return Result.ok().data(needAuditing);
     }
 
+    @Override
+    public Result rejectTask(RejectTaskForm form) {
+        Task task = taskService.createTaskQuery().taskId(form.getTaskId()).singleResult();
+        taskCommonService.reject(form.getRejectedTaskDefKey(), task.getTaskDefinitionKey(), task.getProcessInstanceId(), form.getTaskId(), form.getAuditOpinion());
+        return Result.ok("椹冲洖鎴愬姛");
+    }
+
     /**
      * 鏌ヨ寰呭姙浠诲姟
      *
@@ -486,12 +494,14 @@
             Task task = taskService.createTaskQuery().processInstanceId(process.getId()).taskDefinitionKey(userTask.getId()).singleResult();
             if (Objects.isNull(task)) {
                 // 濡傛灉浠诲姟鍦ㄨ繍琛屾椂娌℃壘鍒帮紝閭d箞鍙兘涓烘湭寮�濮嬫垨鑰呭凡瀹屾垚锛岄渶瑕佷粠鍘嗗彶浠诲姟涓啀鎵句竴涓�
-                HistoricTaskInstance historicTask = historyService.createHistoricTaskInstanceQuery()
+                List<HistoricTaskInstance> historicTasks = historyService.createHistoricTaskInstanceQuery()
                         .processInstanceId(process.getProcessInstanceId())
                         .taskDefinitionKey(userTask.getId())
                         .includeIdentityLinks()
-                        .singleResult();
-                if (Objects.isNull(historicTask)) {
+                        .orderByHistoricTaskInstanceStartTime()
+                        .desc()
+                        .list();
+                if (CollectionUtils.isEmpty(historicTasks)) {
                     vo.setPromoterName("鏆傛棤");
                     vo.setPromoterUnitName("鏆傛棤");
                     // 鏈紑濮嬬殑浠诲姟锛屽叾鍏宠仈鐨勭敤鎴风粍杩欎簺閮藉彲浠ヤ粠UserTask涓嬁鍒帮紝鍥犱负鏈韩鏈紑濮嬬殑浠诲姟鏄病鏈塼ask鐨勶紝鎵�浠ヨ繖閲岀洿鎺ユ煡
@@ -534,18 +544,18 @@
                 } else {
                     vo.setTaskStatus(TaskStatusEnum.FINISHED);
                     // 濡傛灉鏄凡瀹屾垚鐨勶紝淇℃伅闇�瑕佸崟鐙祴鍊�
-                    vo.setTaskId(historicTask.getId());
-                    vo.setExecutionId(historicTask.getExecutionId());
-                    vo.setCreateTime(historicTask.getStartTime());
+                    vo.setTaskId(historicTasks.get(0).getId());
+                    vo.setExecutionId(historicTasks.get(0).getExecutionId());
+                    vo.setCreateTime(historicTasks.get(0).getStartTime());
                     // 鏌ヨ瀹為檯澶勭悊浜�
-                    long handlerUserId = Long.parseLong(historicTask.getAssignee());
+                    long handlerUserId = Long.parseLong(historicTasks.get(0).getAssignee());
                     SysUser handlerUser = sysUserService.selectUserById(handlerUserId);
                     if (Objects.nonNull(handlerUser)) {
                         vo.setHandlerId(handlerUserId);
                         vo.setHandlerName(handlerUser.getNickName());
                     }
-                    vo.setTaskDefinitionKey(historicTask.getTaskDefinitionKey());
-                    this.setPromoterAndHandler(vo, historicTask.getIdentityLinks());
+                    vo.setTaskDefinitionKey(historicTasks.get(0).getTaskDefinitionKey());
+                    this.setPromoterAndHandler(vo, historicTasks.get(0).getIdentityLinks());
                 }
             } else {
                 vo.setTaskStatus(TaskStatusEnum.TODO);
@@ -602,12 +612,14 @@
             Task task = taskService.createTaskQuery().processInstanceId(process.getId()).taskDefinitionKey(userTask.getId()).singleResult();
             if (Objects.isNull(task)) {
                 // 濡傛灉浠诲姟鍦ㄨ繍琛屾椂娌℃壘鍒帮紝閭d箞鍙兘涓烘湭寮�濮嬫垨鑰呭凡瀹屾垚锛屽彧鏌ヨ鏈紑濮嬬殑
-                HistoricTaskInstance historicTask = historyService.createHistoricTaskInstanceQuery()
+                List<HistoricTaskInstance> historicTasks = historyService.createHistoricTaskInstanceQuery()
                         .processInstanceId(process.getProcessInstanceId())
                         .taskDefinitionKey(userTask.getId())
                         .includeIdentityLinks()
-                        .singleResult();
-                if (Objects.isNull(historicTask)) {
+                        .orderByHistoricTaskInstanceStartTime()
+                        .desc()
+                        .list();
+                if (CollectionUtils.isEmpty(historicTasks)) {
                     // 鏈紑濮嬬殑浠诲姟锛屽叾鍏宠仈鐨勭敤鎴风粍杩欎簺閮藉彲浠ヤ粠UserTask涓嬁鍒帮紝鍥犱负鏈韩鏈紑濮嬬殑浠诲姟鏄病鏈塼ask鐨勶紝鎵�浠ヨ繖閲岀洿鎺ユ煡
                     if (StringUtils.isNotBlank(userTask.getAssignee())) {
                         vo.setHandlerType(HandlerTypeEnum.USER);
@@ -675,12 +687,14 @@
             Task task = taskService.createTaskQuery().processInstanceId(process.getId()).taskDefinitionKey(userTask.getId()).singleResult();
             if (Objects.isNull(task)) {
                 // 濡傛灉浠诲姟鍦ㄨ繍琛屾椂娌℃壘鍒帮紝閭d箞鍙兘涓烘湭寮�濮嬫垨鑰呭凡瀹屾垚锛屽彧鏌ヨ鏈紑濮嬬殑
-                HistoricTaskInstance historicTask = historyService.createHistoricTaskInstanceQuery()
+                List<HistoricTaskInstance> historicTasks = historyService.createHistoricTaskInstanceQuery()
                         .processInstanceId(process.getProcessInstanceId())
                         .taskDefinitionKey(userTask.getId())
                         .includeIdentityLinks()
-                        .singleResult();
-                if (Objects.isNull(historicTask)) {
+                        .orderByHistoricTaskInstanceStartTime()
+                        .desc()
+                        .list();
+                if (CollectionUtils.isEmpty(historicTasks)) {
                     num++;
                 }
             }
@@ -792,10 +806,15 @@
         // 鍙戣捣浜哄簲涓轰笂涓�鑺傜偣鐨勫鐞嗕汉
         List<String> beforeNodeKey = taskCommonService.getBeforeNodeInfo(taskVO.getProcessDefId(), taskVO.getTaskDefinitionKey());
         List<SysUser> userList = beforeNodeKey.stream().map(key -> {
-            HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskDefinitionKey(key).singleResult();
-            if (Objects.nonNull(historicTaskInstance)) {
+            List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery()
+                    .processInstanceId(taskVO.getProcessInsId())
+                    .taskDefinitionKey(key)
+                    .orderByHistoricTaskInstanceStartTime()
+                    .desc()
+                    .list(); // 涔嬫墍浠ョ敤list鏄洜涓哄鏋滄煇涓换鍔¤椹冲洖杩囷紝涓斿鏋滆浠诲姟鍐嶆鎵ц鏃朵細鏈夊鏉℃暟鎹紝鍙栨渶鏂扮殑涓�鏉�
+            if (! CollectionUtils.isEmpty(historicTaskInstances)) {
                 // 瀹為檯棰嗗彇杩欎釜浠诲姟鐨勪汉锛屼篃灏辨槸澶勭悊浜�
-                String assignee = historicTaskInstance.getAssignee();
+                String assignee = historicTaskInstances.get(0).getAssignee();
                 SysUser startUser = sysUserService.selectUserById(Long.parseLong(assignee));
                 return startUser;
             } else {
diff --git a/flowable/src/main/java/com/ycl/service/common/TaskCommonService.java b/flowable/src/main/java/com/ycl/service/common/TaskCommonService.java
index af2d729..f46627d 100644
--- a/flowable/src/main/java/com/ycl/service/common/TaskCommonService.java
+++ b/flowable/src/main/java/com/ycl/service/common/TaskCommonService.java
@@ -2,6 +2,7 @@
 
 import com.alibaba.fastjson2.JSONObject;
 import com.ycl.common.constant.ProcessConstants;
+import com.ycl.common.enums.FlowComment;
 import com.ycl.domain.entity.SysForm;
 import com.ycl.domain.vo.FormDetailVO;
 import com.ycl.flow.FindNextNodeUtil;
@@ -9,9 +10,13 @@
 import lombok.RequiredArgsConstructor;
 import org.flowable.bpmn.model.*;
 import org.flowable.bpmn.model.Process;
+import org.flowable.engine.HistoryService;
 import org.flowable.engine.RepositoryService;
 import org.flowable.engine.RuntimeService;
+import org.flowable.engine.TaskService;
 import org.flowable.engine.repository.ProcessDefinition;
+import org.flowable.task.api.Task;
+import org.flowable.task.api.history.HistoricTaskInstance;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.StringUtils;
@@ -29,9 +34,11 @@
 
     private final RuntimeService runtimeService;
     private final RepositoryService repositoryService;
+    private final TaskService taskService;
+    private final HistoryService historyService;
 
     /**
-     * 閫氳繃褰撳墠鑺傜偣瀹氫箟key锛岃幏鍙栧叾涓婁竴涓妭鐐逛互鍙婂綋鍓嶈妭鐐圭殑淇℃伅锛屽鏋滃墠闈㈡槸骞惰鐨勪細杩斿洖澶氫釜
+     * 閫氳繃褰撳墠鑺傜偣瀹氫箟key锛岃幏鍙栧叾涓婁竴涓妭鐐圭殑淇℃伅锛屽鏋滃墠闈㈡槸骞惰鐨勪細杩斿洖澶氫釜(鍖呭惈褰撳墠鑺傜偣)
      *
      * @param processDefId 娴佺▼瀹氫箟id
      * @param currentNodeDefId 褰撳墠鑺傜偣瀹氫箟id
@@ -91,6 +98,52 @@
 
             defKeys.add(formDetailVO);
         }
+        this.beforeNodeInfo(currentElement, defKeys);
+
+        return defKeys;
+    }
+
+
+    /**
+     * 鑾峰彇褰撳墠鑺傜偣鐨勫墠缃妭鐐癸紝涓嶅寘鍚綋鍓嶈妭鐐�
+     *
+     * @param processDefId
+     * @param currentNodeDefId
+     * @return
+     */
+    public List<FormDetailVO> getBeforeNodeList(String processDefId, String currentNodeDefId) {
+        // 鑾峰彇娴佺▼瀹氫箟
+        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
+                .processDefinitionId(processDefId)
+                .singleResult();
+
+        // 鑾峰彇娴佺▼妯″瀷
+        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefId);
+        if (bpmnModel == null) {
+            throw new RuntimeException("BpmnModel not found for processDefinitionId: " + processDefId);
+        }
+
+        // 鑾峰彇娴佺▼瀵硅薄
+        Process process = bpmnModel.getProcessById(processDefinition.getKey());
+        if (process == null) {
+            throw new RuntimeException("Process not found for processDefinitionId: " + processDefId);
+        }
+
+        // 閬嶅巻娴佺▼鍏冪礌锛屾壘鍒板搴旂殑浠诲姟鑺傜偣
+        Collection<FlowElement> flowElements = process.getFlowElements();
+        UserTask currentElement = null;
+        for (FlowElement flowElement : flowElements) {
+            if (flowElement instanceof UserTask && flowElement.getId().equals(currentNodeDefId)) {
+                currentElement = (UserTask) flowElement;
+                break;
+            }
+        }
+        if (Objects.isNull(currentElement)) {
+            throw new RuntimeException("鏈壘鍒拌浠诲姟鐨勬祦绋嬪畾涔夎妭鐐�");
+        }
+
+        List<FormDetailVO> defKeys = new ArrayList<>(2);
+
         this.beforeNodeInfo(currentElement, defKeys);
 
         return defKeys;
@@ -209,4 +262,34 @@
         return Boolean.FALSE;
     }
 
+
+    /**
+     * 椹冲洖浠诲姟
+     *
+     * @param rejectedTaskDefKey 琚┏鍥炵殑浠诲姟key
+     * @param rejectTaskDefKey 鎵ц椹冲洖鎿嶄綔鎵�鍦ㄧ殑浠诲姟key
+     * @param processInsId 娴佺▼瀹炰緥id
+     * @param taskId 褰撳墠浠诲姟id
+     * @param msg 瀹℃牳鎰忚
+     */
+    public void reject(String rejectedTaskDefKey, String rejectTaskDefKey, String processInsId, String taskId, String msg) {
+        // 椹冲洖鐨勬牳蹇僡pi锛歳untimeService.createChangeActivityStateBuilder().moveXXX 鐨刟pi锛屽彲浠ヨ缃粠褰撳墠鑺傜偣绉诲姩鍒扮洰鏍囪妭鐐�
+        // 椹冲洖鐨勬牳蹇冿細闇�瑕佹壘鍒板綋鍓嶈妭鐐广�佷互鍙婅娴佽浆鍒扮殑鐩爣鑺傜偣銆傚叾涓瘮杈冮夯鐑︾殑鏄鐞嗗苟琛岀瓑姣旇緝澶嶆潅鐨勬儏鍐�
+        /**
+         * 椹冲洖鐨勬儏鍐靛垎涓轰互涓嬩笁绉嶏細
+         *
+         * 1. 濡傛灉鎵ц椹冲洖鎿嶄綔鐨勪换鍔℃槸鍦ㄥ苟琛岀粨鏉熺殑鍚庝竴涓妭鐐癸紝閭d箞琚┏鍥炵殑浠诲姟灞炰簬骞惰涓殑鏌愪釜鍒嗘敮鐨勭粨鏉熻妭鐐�
+         * 2. 濡傛灉鎵ц椹冲洖鎿嶄綔鐨勮妭鐐规槸骞惰寮�濮嬪悗鐨勬煇涓�鍒嗘敮鐨勫紑濮嬭妭鐐癸紝閭d箞璇ヨ妭鐐瑰拰琚┏鍥炶妭鐐瑰疄闄呬笂灞炰簬涓茶锛�          鍙笉杩囬渶瑕佸悓鏃舵妸鍏跺畠骞惰鍒嗘敮涔熼┏鍥炰簡锛堣繖閲屽苟涓嶉渶瑕佹墜鍔ㄥ鐞嗭級
+         * 3. 濡傛灉 琚┏鍥炶妭鐐瑰拰椹冲洖鑺傜偣灞炰簬涓茶锛屽垯鐩存帴椹冲洖鏃犻渶鑰冭檻鍏跺畠
+         */
+        // 鎵�浠ラ噸瑕佺殑鏄垽鏂袱涓换鍔′箣闂存槸鍚﹀瓨鍦ㄧ壒娈婅妭鐐癸紝鐩墠鍙厛鑰冭檻骞惰缃戝叧
+
+        // 璁剧疆涓ゆ潯璇勮
+        List<HistoricTaskInstance> rejectedTaskList = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInsId).taskDefinitionKey(rejectedTaskDefKey).orderByHistoricTaskInstanceStartTime().desc().list();
+        String msg1 = "椹冲洖浜嗭細銆�" + rejectedTaskList.get(0).getName() + "銆戯紝椹冲洖鍘熷洜锛�";
+        taskService.addComment(taskId, processInsId,  FlowComment.REJECT.getType(), msg1 + msg);
+        // TODO 鐩存帴浣跨敤杩欎釜api濂藉儚鏈夐棶棰�
+        runtimeService.createChangeActivityStateBuilder().processInstanceId(processInsId).moveActivityIdTo(rejectTaskDefKey, rejectedTaskDefKey).changeState();
+    }
+
 }
diff --git a/flowable/src/main/java/com/ycl/service/impl/FlowTaskServiceImpl.java b/flowable/src/main/java/com/ycl/service/impl/FlowTaskServiceImpl.java
index cf45ee2..aff08d2 100644
--- a/flowable/src/main/java/com/ycl/service/impl/FlowTaskServiceImpl.java
+++ b/flowable/src/main/java/com/ycl/service/impl/FlowTaskServiceImpl.java
@@ -1215,26 +1215,28 @@
         // 杩欓噷鍙渶瑕佹煡鑷韩浠ュ強涓婁竴涓妭鐐�(濡傛灉骞惰鐨勬湁澶氫釜)鐨勮〃鍗曟暟鎹�
         List<FormDetailVO> beforeNodes = taskCommonService.getBeforeNodeDefInfo(processDefId, processDefKey, sysFormService, Boolean.TRUE);
         List<String> beforeNodeDefIds = beforeNodes.stream().filter(item -> !item.getCurrent() || currentNeedData).map(FormDetailVO::getBeforeNodeDefId).collect(Collectors.toList());
-        Map<String, Object> newP = new HashMap<>();
-        if (CollectionUtils.isNotEmpty(beforeNodeDefIds)) {
-            for (String key : parameters.keySet()) {
-                // 杩囨护鎷垮埌鐩爣鏁版嵁锛屽皢鐩爣琛ㄥ崟鏁版嵁鏀惧埌鏂癿ap涓�
-                if (beforeNodeDefIds.stream().anyMatch(defId -> key.startsWith(defId))) {
-                    if (key.contains(ProcessConstants.TASK_FORM_KEY)) {
-                        newP.put(key, parameters.get(key));
-                    }
-                    else {
-                        newP.put(key.split("&")[1], parameters.get(key));
-                    }
-                }
-            }
-        }
 
-        // 鎷垮埌鐩爣琛ㄥ崟鍚庯紝鍐嶅鐞嗘瘡涓〃鍗曠殑鏁版嵁
+        // 澶勭悊姣忎釜琛ㄥ崟鐨勬暟鎹�
         for (FormDetailVO formDetailVO : beforeNodes) {
             if (formDetailVO.getCurrent() && !currentNeedData) {
                 continue;  // 璺宠繃褰撳墠鑺傜偣锛屽洜涓哄綋鍓嶈妭鐐瑰湪鑾峰彇鍓嶇疆鑺傜偣鏃跺凡缁忚缃繃浜�(浣嗚〃鍗曟暟鎹病鏈夌粰)
             }
+
+            Map<String, Object> newP = new HashMap<>();
+            if (CollectionUtils.isNotEmpty(beforeNodeDefIds)) {
+                for (String key : parameters.keySet()) {
+                    // 杩囨护鎷垮埌鐩爣琛ㄥ崟鏁版嵁锛屽皢鐩爣琛ㄥ崟鏁版嵁鏀惧埌鏂癿ap涓�
+                    if (key.startsWith(formDetailVO.getBeforeNodeDefId())) {
+                        if (key.contains(ProcessConstants.TASK_FORM_KEY)) {
+                            newP.put(key, parameters.get(key));
+                        }
+                        else {
+                            newP.put(key.split("&")[1], parameters.get(key));
+                        }
+                    }
+                }
+            }
+
             Object form = newP.get(formDetailVO.getBeforeNodeDefId() + "&" + ProcessConstants.TASK_FORM_KEY);
             if (Objects.nonNull(form)) {
                 JSONObject formJson = JSONObject.parseObject(JSON.toJSONString(form));

--
Gitblit v1.8.0