From 24fa2e63f7c155c87457980e6c656f3891132a47 Mon Sep 17 00:00:00 2001
From: ludc
Date: 星期三, 14 八月 2024 16:28:26 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/attributePool/option.js                         |   14 
 Source/plt-web/plt-web-ui/src/views/system/role/index.vue                                                 |   38 
 Source/plt-web/plt-web-ui/src/views/modelingMenu/ui/formDefine/index.vue                                  |   92 +
 Source/plt-web/plt-web-ui/src/components/flow-cycle/components/EditorMinimap.vue                          |   11 
 Source/plt-web/plt-web-ui/src/components/flow-cycle/flowchartEditor.vue                                   |  294 +++
 Source/plt-web/plt-web-ui/src/views/authority/ui/dataAuthorization/index.vue                              |   92 +
 Source/plt-web/plt-web-ui/src/views/modelingMenu/ui/uiDefine/index.vue                                    |   92 +
 Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/linkType/index.vue                              |  550 ++++++
 Source/plt-web/plt-web-ui/src/components/flow-cycle/components/ContextMenuItem.vue                        |   35 
 Source/plt-web/plt-web-ui/src/views/modelingMenu/queryTemplate/businessTypeQuery/index.vue                |   83 
 Source/plt-web/plt-web-ui/src/views/modelingMenu/queryTemplate/queryDefine/index.vue                      |   85 
 Source/plt-web/plt-web-ui/src/views/authority/function/fuctionView/index.vue                              |   92 +
 Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/controller/OsQueryTemplateController.java |   84 
 Source/plt-web/plt-web-ui/src/components/flow-cycle/components/ContextMenu.vue                            |   79 
 Source/plt-web/plt-web-ui/src/store/modules/LifeFlow.js                                                   |   38 
 Source/plt-web/plt-web-ui/src/page/index/logo.vue                                                         |    7 
 Source/plt-web/plt-web-ui/src/views/authority/ui/typeAction/index.vue                                     |   92 +
 Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/enumType/index.vue                              |   12 
 Source/plt-web/plt-web-ui/src/views/authority/secure/machineClassification/index.vue                      |   92 +
 Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/businessType/index.vue                          |  276 +++
 Source/plt-web/plt-web-ui/src/views/modelingMenu/ui/Action/index.vue                                      |   92 +
 Source/plt-web/plt-web-ui/src/api/modeling/businessType/api.js                                            |   10 
 Source/plt-web/plt-web-ui/src/components/flow-cycle/components/DetailPanel.vue                            |  209 ++
 Source/plt-web/plt-web-ui/src/api/modeling/lifeCycle/api.js                                               |   64 
 Source/plt-web/plt-web-ui/src/util/func.js                                                                |   23 
 Source/plt-web/plt-web-ui/src/components/flow-cycle/components/Icon.vue                                   |   15 
 Source/plt-web/plt-web-ui/src/components/flow-cycle/components/Toolbar.vue                                |  169 +
 Source/plt-web/plt-web-ui/src/components/flow-cycle/components/CustomCommand.vue                          |   67 
 Source/plt-web/plt-web-ui/src/components/flow-cycle/components/ItemPanel.vue                              |  121 +
 Source/plt-web/plt-web-ui/src/components/flow-cycle/iconfont.js                                           |    1 
 Source/plt-web/plt-web-ui/src/store/index.js                                                              |    4 
 Source/plt-web/plt-web-ui/src/views/authority/ui/uiAuthorization/index.vue                                |   92 +
 Source/plt-web/plt-web-ui/package.json                                                                    |    1 
 Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/versioning/index.vue                            |   16 
 Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/lifeCycle/index.vue                             |  451 +++++
 Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/OsQuereyTemplateServiceI.java     |   35 
 Source/plt-web/plt-web-ui/src/components/flow-cycle/components/DetailForm.vue                             |  216 ++
 Source/plt-web/plt-web-ui/src/views/modelingMenu/queryTemplate/linkTypeQuery/index.vue                    |   83 
 Source/plt-web/plt-web-parent/plt-web-api/src/main/java/com/vci/dto/QTInfoDTO.java                        |   38 
 Source/plt-web/plt-web-ui/src/views/system/user/index.vue                                                 |   12 
 Source/plt-web/plt-web-ui/src/views/authority/secure/classification/index.vue                             |   92 +
 Source/plt-web/plt-web-ui/src/api/modeling/linkType/api.js                                                |   38 
 Source/plt-web/plt-web-ui/src/router/router.js                                                            |    2 
 Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/attributePool/index.vue                         |   39 
 Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/impl/OsQueryTemplateImpl.java     |  779 ++++++++
 Source/plt-web/plt-web-ui/src/api/modeling/statusPool/api.js                                              |   15 
 Source/plt-web/plt-web-ui/src/components/flow-cycle/components/ToolbarButton.vue                          |   28 
 Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/statusPool/index.vue                            |  275 +-
 48 files changed, 4,879 insertions(+), 266 deletions(-)

diff --git a/Source/plt-web/plt-web-parent/plt-web-api/src/main/java/com/vci/dto/QTInfoDTO.java b/Source/plt-web/plt-web-parent/plt-web-api/src/main/java/com/vci/dto/QTInfoDTO.java
new file mode 100644
index 0000000..094b3db
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-api/src/main/java/com/vci/dto/QTInfoDTO.java
@@ -0,0 +1,38 @@
+package com.vci.dto;
+
+
+import com.vci.common.qt.object.QueryTemplate;
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * 鏌ヨ妯℃澘鍒楄〃浼犺緭瀵硅薄
+ * @author yuxc
+ * @date 2024/8/7
+ */
+@Data
+public class QTInfoDTO {
+    //鏌ヨ妯℃澘鍚�
+    private String qtName;
+    //绫诲瀷鍚�
+    private String btmName;
+    //鍒涘缓浜�
+    private String creator;
+    //鍒涘缓鏃堕棿
+    private long createTime;
+    private String createTimeText;
+    //"0:鏅�氭煡璇㈡ā鏉�; 1:楂樼骇鏌ヨ妯℃澘"
+    private short levelFlag;
+    //鏌ヨ妯℃澘鐣岄潰锛岃繖鏄珮绾ф煡璇㈢殑
+    private String qtUIText;
+    //鏌ヨ妯℃澘鍚�
+    private String qtText;
+    //鏌ヨ妯℃澘淇℃伅
+    private QueryTemplate queryTemplate;
+    //鏌ヨ鏉′欢锛屽悗绔繘琛岀浉鍏宠В鏋�
+    private List<HashMap<String,String>> condition;
+    private HashMap<String,Object> tree = new HashMap<>();
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/controller/OsQueryTemplateController.java b/Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/controller/OsQueryTemplateController.java
index a346399..7eaabfb 100644
--- a/Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/controller/OsQueryTemplateController.java
+++ b/Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/controller/OsQueryTemplateController.java
@@ -3,6 +3,7 @@
 import com.vci.corba.common.PLException;
 import com.vci.corba.omd.ltm.LinkType;
 import com.vci.corba.omd.qtm.QTD;
+import com.vci.dto.QTInfoDTO;
 import com.vci.pagemodel.OsBtmTypeAttributeVO;
 import com.vci.pagemodel.OsBtmTypeVO;
 import com.vci.pagemodel.OsLinkTypeAttributeVO;
@@ -17,6 +18,7 @@
 import com.vci.web.service.OsLinkTypeServiceI;
 import com.vci.web.service.OsQuereyTemplateServiceI;
 import org.apache.commons.lang3.StringUtils;
+import org.dom4j.DocumentException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -27,6 +29,7 @@
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -118,4 +121,85 @@
             return objectBaseResult;
         }
     }
+
+    /**
+     * 鏌ヨ鏉′欢鐨勬煡璇㈡寜閽煡璇is鍒楄〃
+     * @param dataMap 浼犺緭鐨勬暟鎹璞★細
+     *                linkTypeName 閾炬帴绫诲瀷鍚嶇О銆�
+     *                rdPositive 鏂瑰悜锛宼rue姝e悜锛宖alse鍙嶅悜
+     *                btmName 涓氬姟绫诲瀷鍚嶇О
+     *                combRelaType 涓氬姟绫诲瀷閫夋嫨鍊�
+     *                versionValue 鐗堟湰鐝鍊�
+     *                isQueryIsLeaf 鏄惁閫夋嫨涓嬬骇
+     *                level 瀛愯妭鐐瑰眰鏁�
+     * @return 鏌ヨ缁撴灉
+     */
+    @GetMapping("/getCriteria")
+    public BaseResult getCriteria(@RequestBody HashMap<String,Object> dataMap){
+        try {
+            return quereyTemplateServiceI.getCriteria(dataMap);
+        } catch (PLException e) {
+            BaseResult objectBaseResult = new BaseResult<>();
+            objectBaseResult.setCode(Integer.parseInt(e.code));
+            objectBaseResult.setMsg(Arrays.toString(e.messages));
+            return objectBaseResult;
+        }
+    }
+
+    /**
+     * 鏌ヨ妯℃澘鍒楄〃
+     * @param btName 绫诲瀷鍚嶇О
+     * @return 鏌ヨ缁撴灉
+     */
+    @GetMapping("/getObjTypeQTs")
+    public BaseResult getObjTypeQTs(String btName){
+        try {
+            return quereyTemplateServiceI.getObjTypeQTs(btName);
+        } catch (PLException e) {
+            BaseResult objectBaseResult = new BaseResult<>();
+            objectBaseResult.setCode(Integer.parseInt(e.code));
+            objectBaseResult.setMsg(Arrays.toString(e.messages));
+            return objectBaseResult;
+        } catch (DocumentException e) {
+            e.printStackTrace();
+            BaseResult objectBaseResult = new BaseResult<>();
+            objectBaseResult.setCode(500);
+            objectBaseResult.setMsg(Arrays.toString(e.getMessage().toCharArray()));
+            return objectBaseResult;
+        }
+    }
+
+    /**
+     * 妫�鏌ユ煡璇㈡ā鏉垮悕瀛楁槸鍚﹀瓨鍦�
+     * @param name 鏌ヨ妯℃澘鍚嶅瓧
+     * @return 鏌ヨ缁撴灉
+     */
+    @GetMapping("/isExistsQT")
+    public BaseResult isExistsQT(String name){
+        try {
+            return quereyTemplateServiceI.isExistsQT(name);
+        } catch (PLException e) {
+            BaseResult objectBaseResult = new BaseResult<>();
+            objectBaseResult.setCode(Integer.parseInt(e.code));
+            objectBaseResult.setMsg(Arrays.toString(e.messages));
+            return objectBaseResult;
+        }
+    }
+
+    /**
+     * 閾炬帴绫诲瀷鏌ヨ妯℃澘淇濆瓨
+     * @param qtInfoDTO 淇濆瓨浼犺緭瀵硅薄
+     * @return 淇濆瓨缁撴灉
+     */
+    @PostMapping("/linkSave")
+    public BaseResult linkSave(@RequestBody QTInfoDTO qtInfoDTO){
+        try {
+            return quereyTemplateServiceI.linkSave(qtInfoDTO);
+        } catch (PLException e) {
+            BaseResult objectBaseResult = new BaseResult<>();
+            objectBaseResult.setCode(Integer.parseInt(e.code));
+            objectBaseResult.setMsg(Arrays.toString(e.messages));
+            return objectBaseResult;
+        }
+    }
 }
diff --git a/Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/OsQuereyTemplateServiceI.java b/Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/OsQuereyTemplateServiceI.java
index c966f1c..4cd367d 100644
--- a/Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/OsQuereyTemplateServiceI.java
+++ b/Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/OsQuereyTemplateServiceI.java
@@ -3,17 +3,20 @@
 import com.vci.corba.common.PLException;
 import com.vci.corba.omd.ltm.LinkType;
 import com.vci.corba.omd.qtm.QTD;
+import com.vci.dto.QTInfoDTO;
 import com.vci.pagemodel.OsBtmTypeAttributeVO;
 import com.vci.pagemodel.OsLinkTypeAttributeVO;
 import com.vci.pagemodel.OsLinkTypeVO;
 import com.vci.starter.web.pagemodel.BaseQueryObject;
 import com.vci.starter.web.pagemodel.BaseResult;
 import com.vci.starter.web.pagemodel.DataGrid;
+import org.dom4j.DocumentException;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -48,4 +51,36 @@
      * @return 淇濆瓨缁撴灉
      */
     BaseResult deleteTemplate(String name) throws PLException;
+    /**
+     *
+     * @param dataMap 浼犺緭鐨勬暟鎹璞★細
+     *                linkTypeName 閾炬帴绫诲瀷銆�
+     *                rdPositive 鏂瑰悜锛宼rue姝e悜锛宖alse鍙嶅悜
+     *                btmName 涓氬姟绫诲瀷鍚嶇О
+     *                combRelaType 涓氬姟绫诲瀷閫夋嫨鍊�
+     *                versionValue 鐗堟湰鐝鍊�
+     *                isQueryIsLeaf 鏄惁閫夋嫨涓嬬骇
+     *                level 瀛愯妭鐐瑰眰鏁�
+     * @return 鏌ヨ缁撴灉
+     */
+    BaseResult getCriteria(HashMap<String,Object> dataMap) throws PLException;
+    /**
+     * 鏌ヨ妯℃澘鍒楄〃
+     * @param btName 绫诲瀷鍚嶇О
+     * @return 鏌ヨ缁撴灉
+     */
+    BaseResult getObjTypeQTs(String btName) throws PLException, DocumentException;
+    /**
+     * 妫�鏌ユ煡璇㈡ā鏉垮悕瀛楁槸鍚﹀瓨鍦�
+     * @param name 鏌ヨ妯℃澘鍚嶅瓧
+     * @return 鏌ヨ缁撴灉
+     */
+    BaseResult isExistsQT(String name) throws PLException;
+
+    /**
+     * 閾炬帴绫诲瀷鏌ヨ妯℃澘淇濆瓨
+     * @param qtInfoDTO 淇濆瓨浼犺緭瀵硅薄
+     * @return 淇濆瓨缁撴灉
+     */
+    BaseResult linkSave(QTInfoDTO qtInfoDTO) throws PLException;
 }
diff --git a/Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/impl/OsQueryTemplateImpl.java b/Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/impl/OsQueryTemplateImpl.java
index 50b8418..44d39ff 100644
--- a/Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/impl/OsQueryTemplateImpl.java
+++ b/Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/impl/OsQueryTemplateImpl.java
@@ -1,50 +1,29 @@
 package com.vci.web.service.impl;
 
-import cn.hutool.core.io.FileUtil;
-import cn.hutool.core.util.ZipUtil;
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.vci.constant.FrameWorkLangCodeConstant;
+import com.alibaba.fastjson.JSONObject;
+import com.vci.client.common.oq.OQTool;
+import com.vci.common.qt.object.*;
 import com.vci.corba.common.PLException;
 import com.vci.corba.omd.atm.AttributeDef;
-import com.vci.corba.omd.btm.BizType;
-import com.vci.corba.omd.data.BusinessObject;
-import com.vci.corba.omd.ltm.LinkType;
+import com.vci.corba.omd.data.LinkObject;
 import com.vci.corba.omd.qtm.QTD;
-import com.vci.model.OsLinkTypeDO;
-import com.vci.omd.utils.ObjectTool;
-import com.vci.pagemodel.*;
-import com.vci.po.OsLinkTypePO;
-import com.vci.starter.poi.bo.ReadExcelOption;
-import com.vci.starter.poi.bo.WriteExcelData;
-import com.vci.starter.poi.bo.WriteExcelOption;
-import com.vci.starter.poi.constant.ExcelLangCodeConstant;
-import com.vci.starter.poi.util.ExcelUtil;
-import com.vci.starter.web.annotation.log.VciUnLog;
-import com.vci.starter.web.enumpck.VciFieldTypeEnum;
-import com.vci.starter.web.exception.VciBaseException;
-import com.vci.starter.web.pagemodel.BaseQueryObject;
+import com.vci.corba.omd.qtm.QTInfo;
+import com.vci.dto.QTInfoDTO;
+import com.vci.omd.objects.OtherInfo;
 import com.vci.starter.web.pagemodel.BaseResult;
-import com.vci.starter.web.pagemodel.DataGrid;
 import com.vci.starter.web.util.*;
 import com.vci.web.service.*;
-import com.vci.web.util.Func;
+import com.vci.web.util.DateUtil;
 import com.vci.web.util.PlatformClientUtil;
 import com.vci.web.util.WebUtil;
 import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.commons.lang3.time.DateFormatUtils;
+import org.dom4j.DocumentException;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
-import org.springframework.util.CollectionUtils;
-import org.springframework.web.multipart.MultipartFile;
-
-import javax.servlet.http.HttpServletResponse;
-import java.io.File;
-import java.io.IOException;
 import java.util.*;
-import java.util.stream.Collectors;
 
 /**
  * 鏌ヨ妯℃澘鏈嶅姟
@@ -60,6 +39,18 @@
      */
     @Autowired
     private PlatformClientUtil platformClientUtil;
+
+    private final String EQUAL = "=";
+    private final String UNEQUAL = "!=";
+    private final String CONTAINS = "鍖呭惈";
+    private final String IN = "in";
+    private final String NOTIN = "not in";
+    private final String GT = ">";
+    private final String GTE = ">=";
+    private final String LT = "<";
+    private final String LTE = "<=";
+    private final String AND = "骞朵笖";
+    private final String OR = "鎴栬��";
 
     /**
      * 鏌ヨ妯℃澘鐨勫垪琛�
@@ -138,6 +129,728 @@
             return BaseResult.fail("鍒犻櫎鏌ヨ妯℃澘澶辫触");
         }
     }
+    /**
+     *
+     * @param dataMap 浼犺緭鐨勬暟鎹璞★細
+     *                linkTypeName 閾炬帴绫诲瀷銆�
+     *                rdPositive 鏂瑰悜锛宼rue姝e悜锛宖alse鍙嶅悜
+     *                btmName 涓氬姟绫诲瀷鍚嶇О
+     *                combRelaType 涓氬姟绫诲瀷閫夋嫨鍊�
+     *                versionValue 鐗堟湰鐝鍊�
+     *                isQueryIsLeaf 鏄惁閫夋嫨涓嬬骇
+     *                level 瀛愯妭鐐瑰眰鏁�
+     * @return 鏌ヨ缁撴灉
+     */
+    @Override
+    public BaseResult getCriteria(HashMap<String,Object> dataMap) throws PLException {
+        QueryTemplate qt = getQT(dataMap);
+        String checkInfo = OQTool.checkQT(qt);
+        if(!checkInfo.equals("OK")){
+            throw new PLException("500", new String[]{checkInfo});
+        }
+        qt.setId("qt1");
+        LinkObject[] result = platformClientUtil.getQueryService().findLTObjects(qt.getId(), OQTool.qtTOXMl(qt).asXML());
+        return BaseResult.dataList(Arrays.asList(result));
+    }
+
+    /**
+     * 鏌ヨ妯℃澘鍒楄〃
+     * @param btName 绫诲瀷鍚嶇О
+     * @return 鏌ヨ缁撴灉
+     */
+    @Override
+    public BaseResult getObjTypeQTs(String btName) throws PLException, DocumentException {
+        VciBaseUtil.alertNotNull(btName,"绫诲瀷鍚�");
+        QTInfo[] objTypeQTs = platformClientUtil.getQTDService().getObjTypeQTs(btName);
+        List<QTInfoDTO> dtos = new ArrayList<>();
+        for (QTInfo obj : objTypeQTs) {
+            QTInfoDTO qtInfoDTO = new QTInfoDTO();
+            qtInfoDTO.setCreator(obj.creator);
+            qtInfoDTO.setBtmName(obj.btmName);
+            qtInfoDTO.setQtName(obj.qtName);
+            qtInfoDTO.setLevelFlag(obj.levelFlag);
+//            qtInfoDTO.setQtText(obj.qtText);
+            qtInfoDTO.setQtUIText(obj.qtUIText);
+            if(StringUtils.isNotBlank(obj.qtUIText)){
+                //灏嗙粰瀹氱殑String鏂囨湰瑙f瀽涓篨ML鏂囨。骞惰繑鍥炴柊鍒涘缓鐨刣ocument
+                qtInfoDTO.setTree(analysisXml(obj));
+            }
+            qtInfoDTO.setQueryTemplate(OQTool.getQTByDoc(DocumentHelper.parseText(obj.qtText), obj.qtName));
+            qtInfoDTO.setCreateTimeText(DateFormatUtils.format(new Date(obj.createTime), DateUtil.PATTERN_DATETIME));
+            dtos.add(qtInfoDTO);
+        }
+        return BaseResult.dataList(dtos);
+    }
+
+    /**
+     * 灏嗗鏈嶇鐣岄潰鏄剧ず鐨剎ml杞负hashMap
+     * @param obj 鐣岄潰瀵硅薄
+     * @return
+     * @throws DocumentException
+     */
+    private HashMap<String,Object> analysisXml(QTInfo obj) throws DocumentException {
+        org.dom4j.Document document = DocumentHelper.parseText(obj.qtUIText);
+        if(document == null){
+            return null;
+        }
+        //鑾峰彇鏍硅妭鐐�,鍦ㄤ緥瀛愪腑灏辨槸responsedata鑺傜偣
+        Element root = document.getRootElement();
+        List<HashMap<String,Object>> treeList = new ArrayList<>();
+        HashMap<String,Object> treeMap = new HashMap<>();
+        treeMap.put("connector",root.getText());
+        List<Element> children = root.elements();
+        List<Object> childList = new ArrayList<>();
+        for(Iterator<Element> i = children.iterator(); i.hasNext();){
+            Element child = i.next();
+            if(AND.equals(child.getText()) || OR.equals(child.getText())){
+                childList.add(addDefaultMutableTree(child));
+            }else {
+                childList.add(child.getText().trim());
+            }
+        }
+        treeMap.put("child",childList);
+        return treeMap;
+    }
+
+    /**
+     * 灏嗗瓙鑺傜偣杞负map缁撴瀯
+     * @param element
+     */
+    public Map<String, Object> addDefaultMutableTree(Element element){
+        List<Object> childList = new ArrayList<>();
+        List<Element> children = element.elements();
+        HashMap<String,Object> treeMap = new HashMap<>();
+        treeMap.put("connector",element.getText());
+        for(Iterator<Element> i = children.iterator(); i.hasNext();){
+            Element child = i.next();
+            if(AND.equals(child.getText()) || OR.equals(child.getText())){
+                childList.add(addDefaultMutableTree(child));
+            }else {
+                childList.add(child.getText().trim());
+            }
+        }
+        treeMap.put("child",childList);
+        return treeMap;
+    }
+
+    /**
+     * 妫�鏌ユ煡璇㈡ā鏉垮悕瀛楁槸鍚﹀瓨鍦�
+     * @param name 鏌ヨ妯℃澘鍚嶅瓧
+     * @return 鏌ヨ缁撴灉
+     */
+    @Override
+    public BaseResult isExistsQT(String name) throws PLException {
+        VciBaseUtil.alertNotNull(name,"璇㈡ā鏉垮悕");
+        return BaseResult.success(platformClientUtil.getQTDService().isExistsQT(name));
+    }
+
+    /**
+     * 閾炬帴绫诲瀷鏌ヨ妯℃澘淇濆瓨
+     * @param qtInfoDTO 淇濆瓨浼犺緭瀵硅薄
+     * @return 淇濆瓨缁撴灉
+     */
+    @Override
+    public BaseResult linkSave(QTInfoDTO qtInfoDTO) throws PLException {
+        QueryTemplate qt = getQT(qtInfoDTO);
+        String checkInfo = OQTool.checkQT(qt);
+        if(!checkInfo.equals("OK")){
+            throw new PLException("500", new String[]{checkInfo});
+        }
+        boolean saveFlag ;
+        qt.setId(qtInfoDTO.getQtName());
+        qt.setOrderInfoList(qtInfoDTO.getQueryTemplate().getOrderInfoList());
+        QTInfo qtWrapper = new QTInfo();
+        qtWrapper.qtName = qt.getId();
+        qtWrapper.btmName = qt.getLinkType();
+        qtWrapper.creator = WebUtil.getCurrentUserId();
+        qtWrapper.createTime = System.currentTimeMillis();
+        if(qtInfoDTO.getTree() == null){
+            qtWrapper.qtUIText = "";
+        }else{
+            qtWrapper.qtUIText = getSeniorXML(qtInfoDTO);
+        }
+        qtWrapper.levelFlag = qtInfoDTO.getLevelFlag();
+        qtWrapper.qtText = OQTool.qtTOXMl(qt).asXML();
+        saveFlag = platformClientUtil.getQTDService().saveQT(qtWrapper);
+        if(saveFlag){
+            return BaseResult.success();
+        }else{
+            return BaseResult.fail("淇濆瓨鏌ヨ妯℃澘澶辫触");
+        }
+    }
+
+    private String getSeniorXML(QTInfoDTO qtInfoDTO){
+        HashMap<String, Object> tree = qtInfoDTO.getTree();
+        if(tree.isEmpty()){
+            return "";
+        }
+        StringBuilder xmlStr = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root>");
+        xmlStr.append(tree.get("connector"));
+        List<Object> childrens = (List<Object>) tree.get("child");
+        Iterator<Object> children = childrens.iterator();
+        while (children.hasNext()) {
+            Object obj = children.next();
+            if(obj instanceof JSONObject && (((JSONObject) obj).get("connector").equals(AND)
+                    || ((JSONObject) obj).get("connector").equals(OR))){
+                xmlStr.append(getSeniorChildXML((JSONObject) obj));
+            }else{
+                xmlStr.append("<child>").append(obj).append("</child>");
+            }
+        }
+        return xmlStr.append("</root>").toString();
+
+    }
+    private String getSeniorChildXML(JSONObject childs){
+
+        StringBuilder xmlStr = new StringBuilder("<child>" + childs.get("connector"));
+        List<Object> childrens = (List<Object>) childs.get("child");
+        if(childrens == null){
+            return "";
+        }
+        Iterator<Object> child = childrens.iterator();
+        while (child.hasNext()) {
+            Object obj = child.next();
+            if(obj instanceof JSONObject && (((JSONObject) obj).get("connector").equals(AND)
+                    || ((JSONObject) obj).get("connector").equals(OR))){
+                xmlStr.append(getSeniorChildXML((JSONObject) obj));
+            }else{
+                xmlStr.append("<child>").append(obj).append("</child>");
+            }
+        }
+        return xmlStr.append("</child>").toString();
+    }
+
+    /**
+     * 缁勮鏌ヨ妯℃澘
+     * @return
+     */
+    public QueryTemplate getQT(QTInfoDTO qtInfoDTO) throws PLException {
+        QueryTemplate qt = new QueryTemplate();
+        qt.setType(QTConstants.TYPE_LINK);
+        //TODO String qtId =
+        qt.setLinkType(qtInfoDTO.getBtmName());
+        qt.setDirection(qtInfoDTO.getQueryTemplate().getDirection());
+        qt.setBtmType(qtInfoDTO.getQueryTemplate().getBtmType());
+
+        qt.setVersion(qtInfoDTO.getQueryTemplate().getVersion());
+        qt.setQueryISLeaf(qtInfoDTO.getQueryTemplate().isQueryISLeaf());
+        qt.setLevel(qtInfoDTO.getQueryTemplate().getLevel());
+        List<String> clauseList = new ArrayList<String>();
+        //TODO 鏌ヨ鍒� 鏄剧ず鍒�
+        clauseList.add("*");
+        qt.setClauseList(clauseList);
+        Condition con = new Condition();
+        qt.setCondition(con);
+        HashMap<String, ConditionItem> ciMap = getCIMap(qtInfoDTO);
+        con.setCIMap(ciMap);
+        con.setRootCIName(con.getRootCINameByCIMap(ciMap));
+        return qt;
+    }
+
+    /**
+     * 鑾峰彇鏌ヨ鏉′欢
+     * @return
+     */
+    private HashMap<String, ConditionItem> getCIMap(QTInfoDTO qtInfoDTO) throws PLException {
+        HashMap<String, ConditionItem> ciMap = new HashMap<>();
+        //鏅�氭煡璇㈡潯浠�
+        if(qtInfoDTO.getLevelFlag() == 0){
+            /**
+             * 鍔犲叆鍙跺瓙鑺傜偣
+             */
+            for(int i = 0; i < qtInfoDTO.getCondition().size(); i++){
+                ConditionItem ci = new ConditionItem();
+                String id = "ci" + (i + 1);
+                ci.setId(id);
+                ci.setLeafFlag(true);
+                HashMap<String, String> condition = qtInfoDTO.getCondition().get(i);
+                String clause = condition.get("clause");
+                String operator = condition.get("operator");
+                String ordinaryValue = condition.get("ordinaryValue");
+                //add by zhangweiwei 2014/12/09  end  鍥犲鍔犻�夋嫨鏌ヨ妯℃澘鎸夐挳灏嗘瘡琛岀粍浠舵暟鐢�4鏀规垚5
+                LeafInfo leafInfo = new LeafInfo();
+                if(clause.contains("T_OID.") || clause.contains("F_OID.")){
+                    //鍘绘帀T_OID.鎴栬�匜_OID.
+                    String clause_ = clause.substring(6);
+                    //灞炴�т负鍙傜収灞炴��
+                    if(clause_.contains(".")){
+                        int fpIndex = clause_.indexOf(".");
+                        String refAbName = clause.substring(0, fpIndex + 6);
+                        clause = clause.substring(fpIndex + 6 + 1);
+                        leafInfo.setClause(refAbName);
+                        //鍘绘帀T_OID.鎴栬�匜_OID.
+                        refAbName = refAbName.substring(6);
+                        leafInfo.setOperator(Operator.IN);
+                        QueryTemplate qt = getRefQT(refAbName, clause, operator, ordinaryValue);
+                        LeafValue lValue = new LeafValue();
+                        lValue.setQueryTemplate(qt);
+                        leafInfo.setValue(lValue);
+                        //灞炴�т负闈炲弬鐓у睘鎬�
+                    }else{
+                        leafInfo.setClause(clause);
+                        leafInfo.setOperator(operator);
+                        LeafValue lValue = new LeafValue();
+                        leafInfo.setValue(lValue);
+                        //add by zhangweiwei 2014/12/09 start
+                        //濡傛灉宓屽Link
+                        if(ordinaryValue.contains(";")){
+                            leafInfo.setOperator(Operator.IN);
+                            String[] values = ordinaryValue.split(";");
+                            String  QTname = values[0];
+                            String  attr = values[1].substring(0, values[1].length());
+                            try {
+                                QTInfo qt = platformClientUtil.getQTDService().getQT(QTname);
+                                String qtText = qt.qtText;
+                                QueryTemplate qt_ = OQTool.getQTByQTText(qt.qtName, qtText);
+                                List<String> clauseList = new ArrayList<String>();
+                                clauseList.add(attr);
+                                qt_.setClauseList(clauseList);
+                                lValue.setQueryTemplate(qt_);
+                                //lValue.setAttr(attr);
+                            } catch (PLException e) {
+                                e.printStackTrace();
+                            }
+                            catch (DocumentException e1) {
+                                e1.printStackTrace();
+                            }
+                        }else{
+                            lValue.setOrdinaryValue(ordinaryValue);
+                        }
+                        //add by zhangweiwei 2014/12/09 end
+                    }
+                }else{
+                    //灞炴�т负鍙傜収灞炴��
+                    if(clause.contains(".")){
+                        int fpIndex = clause.indexOf(".");
+                        String refAbName = clause.substring(0, fpIndex);
+                        clause = clause.substring(fpIndex + 1);
+                        leafInfo.setClause(refAbName);
+                        leafInfo.setOperator(Operator.IN);
+                        QueryTemplate qt = getRefQT(refAbName, clause, operator, ordinaryValue);
+                        LeafValue lValue = new LeafValue();
+                        lValue.setQueryTemplate(qt);
+                        leafInfo.setValue(lValue);
+                        //灞炴�т负闈炲弬鐓у睘鎬�
+                    }else{
+                        leafInfo.setClause(clause);
+                        leafInfo.setOperator(operator);
+                        LeafValue lValue = new LeafValue();
+                        leafInfo.setValue(lValue);
+                        //add by zhangweiwei 2014/12/09 start
+                        //濡傛灉宓屽Link
+                        if(ordinaryValue.contains(";")){
+                            leafInfo.setOperator(Operator.IN);
+                            String[] values = ordinaryValue.split(";");
+                            String  QTname = values[0];
+                            String  attr = values[1].substring(0, values[1].length());
+                            try {
+                                QTInfo qt = platformClientUtil.getQTDService().getQT(QTname);
+                                String qtText = qt.qtText;
+                                QueryTemplate qt_ = OQTool.getQTByQTText(qt.qtName, qtText);
+                                List<String> clauseList = new ArrayList<String>();
+                                clauseList.add(attr);
+                                qt_.setClauseList(clauseList);
+                                lValue.setQueryTemplate(qt_);
+                                //lValue.setAttr(attr);
+                            } catch (PLException e) {
+                                e.printStackTrace();
+                            } catch (DocumentException e1) {
+                                e1.printStackTrace();
+                            }
+
+                        }else{
+                            lValue.setOrdinaryValue(ordinaryValue);
+                        }
+                        //add by zhangweiwei 2014/12/09 end
+                    }
+                }
+
+                ci.setLeafInfo(leafInfo);
+                ciMap.put(ci.getId(), ci);
+            }
+
+            Iterator<String> iterator = ciMap.keySet().iterator();
+            ArrayList<ConditionItem> ciList = new ArrayList<ConditionItem>();
+            String lCIId = null;
+            while(iterator.hasNext()){
+                lCIId = iterator.next();
+                break;
+            }
+            int count = ciMap.size();
+            while(iterator.hasNext()){
+                String rCIId = iterator.next();
+                ConditionItem pCI = new ConditionItem();
+                String pId = "ci" + ++count;
+                pCI.setId(pId);
+                pCI.setLeafFlag(false);
+                ChildrenInfo pChildrenInfo = new ChildrenInfo();
+                pChildrenInfo.setLeftCIName(lCIId);
+                pChildrenInfo.setConnector(Connector.AND);
+                pChildrenInfo.setRightCIName(rCIId);
+                pCI.setChildrenInfo(pChildrenInfo);
+                ciList.add(pCI);
+                lCIId = pId;
+            }
+            for(Iterator<ConditionItem> i = ciList.iterator(); i.hasNext();){
+                ConditionItem ci = i.next();
+                ciMap.put(ci.getId(), ci);
+            }
+            //楂樼骇鏌ヨ鏉′欢
+        }else if(qtInfoDTO.getLevelFlag() == 1){
+            ciMap = getCIMapForSeniorTree(qtInfoDTO);
+
+//            OQTool.parseTreeToDoc(seniorTree);
+        }
+        return ciMap;
+    }
+
+    /**
+     * 鑾峰彇楂樼骇鏌ヨ鐨勬煡璇㈡潯浠堕泦鍚�
+     * @return
+     */
+    private HashMap<String, ConditionItem> getCIMapForSeniorTree(QTInfoDTO qtInfoDTO) throws PLException {
+        HashMap<String, ConditionItem> ciMap = new HashMap<>();
+        HashMap<String, Object> tree = qtInfoDTO.getTree();
+        if (tree.isEmpty()) {
+            // 鏃犳煡璇㈡潯浠剁殑鏌ヨ
+            return null;
+        }
+        ArrayList<ConditionItem> ciList = new ArrayList<ConditionItem>();
+        String connector = String.valueOf(tree.get("connector"));
+        List<Object> childrens = (List<Object>) tree.get("child");
+        Iterator<Object> children = childrens.iterator();
+        while (children.hasNext()) {
+            Object obj = children.next();
+            if(obj instanceof JSONObject && (((JSONObject) obj).get("connector").equals(AND)
+                    || ((JSONObject) obj).get("connector").equals(OR))){
+                List<ConditionItem> subCIList = getCIList((JSONObject) obj, ciList.size() + 1);
+                if(subCIList == null){
+                    continue;
+                }
+                if(ciList.size() > 0){
+                    ConditionItem leftCI = ciList.get(ciList.size() - 1);
+                    ConditionItem rightCI = subCIList.get(subCIList.size() - 1);
+                    ciList.addAll(subCIList);
+                    ConditionItem pCI = new ConditionItem();
+                    pCI.setId("ci" + (ciList.size() + 1));
+                    ciList.add(pCI);
+                    pCI.setLeafFlag(false);
+                    ChildrenInfo cInfo = new ChildrenInfo();
+                    pCI.setChildrenInfo(cInfo);
+                    cInfo.setLeftCIName(leftCI.getId());
+                    cInfo.setConnector(connector);
+                    cInfo.setRightCIName(rightCI.getId());
+                }else{
+                    ciList.addAll(subCIList);
+                }
+            }else{
+                String text = String.valueOf(obj);
+                if(text == null || text.equals("")){
+                    continue;
+                }
+                if(!text.contains(Operator.EQUAL) && !text.contains(Operator.UNEQUAL) && !text.contains(Operator.CONTAINS)
+                        && !text.contains(Operator.IN) && !text.contains(Operator.NOTIN) &&!text.contains(Operator.GTE) && !text.contains(Operator.GT)
+                        && !text.contains(Operator.LTE) && !text.contains(Operator.LT)){
+                    continue;
+                }
+                if(ciList.size() > 0){
+                    ConditionItem leftCI = ciList.get(ciList.size() - 1);
+                    ConditionItem rightCI = getCIByNode(text, ciList.size() + 1);
+                    ciList.add(rightCI);
+                    ConditionItem pCI = new ConditionItem();
+                    pCI.setId("ci" + (ciList.size() + 1));
+                    ciList.add(pCI);
+                    pCI.setLeafFlag(false);
+                    ChildrenInfo cInfo = new ChildrenInfo();
+                    pCI.setChildrenInfo(cInfo);
+                    cInfo.setLeftCIName(leftCI.getId());
+                    cInfo.setConnector(connector);
+                    cInfo.setRightCIName(rightCI.getId());
+                }else{
+                    ConditionItem ci = getCIByNode(text, ciList.size() + 1);
+                    ciList.add(ci);
+                }
+            }
+        }
+
+        for(int i = 0; i < ciList.size(); i++){
+            ConditionItem ci = ciList.get(i);
+            ciMap.put(ci.getId(), ci);
+        }
+        return ciMap;
+    }
+    /**
+     * 鏍戝寲涓�涓煡璇㈡潯浠剁粍鑺傜偣
+     * @param children
+     * @param beginId
+     * @return
+     */
+    private List<ConditionItem> getCIList(JSONObject children, int beginId) throws PLException {
+        List<ConditionItem> ciList = new ArrayList<>();
+        String connector = String.valueOf(children.get("connector"));
+        List<Object> childrens = (List<Object>) children.get("child");
+        if(childrens == null){
+            return null;
+        }
+        Iterator<Object> child = childrens.iterator();
+        while (child.hasNext()) {
+            Object obj = child.next();
+            if(obj instanceof JSONObject && (((JSONObject) obj).get("connector").equals(AND)
+                    || ((JSONObject) obj).get("connector").equals(OR))){
+                List<ConditionItem> subCIList = getCIList((JSONObject) obj, beginId);
+                if(ciList.size() > 0){
+                    ConditionItem leftCI = ciList.get(ciList.size() - 1);
+                    ConditionItem rightCI = subCIList.get(subCIList.size() - 1);
+                    ciList.addAll(subCIList);
+                    beginId = beginId + subCIList.size();
+                    ConditionItem pCI = new ConditionItem();
+                    pCI.setId("ci" + beginId);
+                    ciList.add(pCI);
+                    beginId = beginId + 1;
+                    pCI.setLeafFlag(false);
+                    ChildrenInfo cInfo = new ChildrenInfo();
+                    pCI.setChildrenInfo(cInfo);
+                    cInfo.setLeftCIName(leftCI.getId());
+                    cInfo.setConnector(connector);
+                    cInfo.setRightCIName(rightCI.getId());
+                }else{
+                    ciList.addAll(subCIList);
+                    beginId = beginId + subCIList.size();
+                }
+            }else{
+                String text = String.valueOf(obj);
+                if(text == null || text.equals("")){
+                    continue;
+                }
+                if(!text.contains(Operator.EQUAL) && !text.contains(Operator.UNEQUAL) && !text.contains(Operator.CONTAINS)
+                        && !text.contains(Operator.IN) && !text.contains(Operator.NOTIN) &&!text.contains(Operator.GTE) && !text.contains(Operator.GT)
+                        && !text.contains(Operator.LTE) && !text.contains(Operator.LT)){
+                    continue;
+                }
+                if(ciList.size() > 0){
+                    ConditionItem leftCI = ciList.get(ciList.size() - 1);
+                    ConditionItem rightCI = getCIByNode(text, beginId);
+                    ciList.add(rightCI);
+                    beginId = beginId + 1;
+                    ConditionItem pCI = new ConditionItem();
+                    pCI.setId("ci" + beginId);
+                    ciList.add(pCI);
+                    beginId = beginId + 1;
+                    pCI.setLeafFlag(false);
+                    ChildrenInfo cInfo = new ChildrenInfo();
+                    pCI.setChildrenInfo(cInfo);
+                    cInfo.setLeftCIName(leftCI.getId());
+                    cInfo.setConnector(connector);
+                    cInfo.setRightCIName(rightCI.getId());
+                }else{
+                    ConditionItem ci = getCIByNode(text, beginId);
+                    ciList.add(ci);
+                    beginId = beginId + 1;
+                }
+            }
+        }
+        return ciList;
+    }
+    /**
+     * 楂樼骇鏌ヨ
+     * 鎶奛ode鍐呭瑙f瀽鎴怌onditionItem
+     * @param text
+     * @param id
+     * @return
+     */
+    private ConditionItem getCIByNode(String text, int id) throws PLException {
+        ConditionItem ci = new ConditionItem();
+        ci.setId("ci" + id);
+        ci.setLeafFlag(true);
+        LeafInfo leafInfo = new LeafInfo();
+        ci.setLeafInfo(leafInfo);
+        String operator = null;
+        if(text.contains(Operator.EQUAL)){
+            operator = Operator.EQUAL;
+        }else if(text.contains(Operator.CONTAINS)){
+            operator = Operator.CONTAINS;
+        }else if(text.contains(Operator.UNEQUAL)){
+            operator = Operator.UNEQUAL;
+        }else if(text.contains(Operator.IN)){
+            operator = Operator.IN;
+        }else if(text.contains(Operator.NOTIN)){
+            operator = Operator.NOTIN;
+        }else if(text.contains(Operator.GTE)){
+            operator = Operator.GTE;
+        }else if(text.contains(Operator.GT)){
+            operator = Operator.GT;
+        }else if(text.contains(Operator.LTE)){
+            operator = Operator.LTE;
+        }else if(text.contains(Operator.LT)){
+            operator = Operator.LT;
+        }
+        int operatorIndex = text.indexOf(operator);
+        String clause = text.substring(0, operatorIndex).trim();
+        String ordinaryValue = text.substring(operatorIndex + 2).trim();
+        if(clause.contains("T_OID.") || clause.contains("F_OID.")){
+            //鍘绘帀T_OID.鎴栬�匜_OID.
+            String clause_ = clause.substring(6);
+            //灞炴�т负鍙傜収灞炴��
+            if(clause_.contains(".")){
+                int fpIndex = clause_.indexOf(".");
+                String refAbName = clause.substring(0, fpIndex + 6);
+                clause = clause.substring(fpIndex + 6 + 1);
+                leafInfo.setClause(refAbName);
+                //鍘绘帀T_OID.鎴栬�匜_OID.
+                refAbName = refAbName.substring(6);
+                leafInfo.setOperator(Operator.IN);
+                QueryTemplate qt = getRefQT(refAbName, clause, operator, ordinaryValue);
+                LeafValue lValue = new LeafValue();
+                lValue.setQueryTemplate(qt);
+                leafInfo.setValue(lValue);
+                //灞炴�т负闈炲弬鐓у睘鎬�
+            }else{
+                leafInfo.setClause(clause);
+                leafInfo.setOperator(operator);
+                LeafValue lValue = new LeafValue();
+                leafInfo.setValue(lValue);
+                lValue.setOrdinaryValue(ordinaryValue);
+            }
+        }else{
+            //灞炴�т负鍙傜収灞炴��
+            if(clause.contains(".")){
+                int fpIndex = clause.indexOf(".");
+                String refAbName = clause.substring(0, fpIndex);
+                clause = clause.substring(fpIndex + 1);
+                leafInfo.setClause(refAbName);
+                leafInfo.setOperator(Operator.IN);
+                QueryTemplate qt = getRefQT(refAbName, clause, operator, ordinaryValue);
+                LeafValue lValue = new LeafValue();
+                lValue.setQueryTemplate(qt);
+                leafInfo.setValue(lValue);
+                //灞炴�т负闈炲弬鐓у睘鎬�
+            }else{
+                leafInfo.setClause(clause);
+                leafInfo.setOperator(operator);
+                LeafValue lValue = new LeafValue();
+                leafInfo.setValue(lValue);
+                lValue.setOrdinaryValue(ordinaryValue);
+            }
+        }
+
+        return ci;
+    }
+
+
+
+    /**
+     * 鑾峰彇鍙傜収鐨勬煡璇㈡ā鏉�
+     * @param refAbName: 鍙傜収灞炴�у悕
+     * @param clause: 灞炴�у弬鐓х殑涓氬姟绫诲瀷涓殑灞炴��
+     * @param operator
+     * @param ordinaryValue
+     * @return
+     */
+    private QueryTemplate getRefQT(String refAbName, String clause,
+                                   String operator, String ordinaryValue) throws PLException {
+        QueryTemplate qt = new QueryTemplate();
+        List<String> clauseList = new ArrayList<String>();
+        clauseList.add("OID");
+        qt.setClauseList(clauseList);
+        AttributeDef refAb = platformClientUtil.getAttributeService().getAttributeDefByName(refAbName);
+        OtherInfo otherInfo = OtherInfo.getOtherInfoByText(refAb.other);
+        int refFlag = otherInfo.getRefFlag();
+        String type = otherInfo.getRefTypeName();
+        if(refFlag == 0){
+            qt.setType(QTConstants.TYPE_BTM);
+            qt.setBtmType(type);
+        }else if(refFlag == 1){
+            qt.setType(QTConstants.TYPE_LINK);
+            qt.setLinkType(type);
+        }
+        Condition condition = new Condition();
+        qt.setCondition(condition);
+        condition.setRootCIName("ci1");
+        HashMap<String, ConditionItem> ciMap = new HashMap<String, ConditionItem>();
+        condition.setCIMap(ciMap);
+        ConditionItem ci = new ConditionItem();
+        ci.setId("ci1");
+        ciMap.put(ci.getId(), ci);
+        ci.setLeafFlag(true);
+        LeafInfo leafInfo = new LeafInfo();
+        if(clause.contains(".")){
+            int fpIndex = clause.indexOf(".");
+            String refAbName_ = clause.substring(0, fpIndex);
+            clause = clause.substring(fpIndex + 1);
+            leafInfo.setClause(refAbName_);
+            leafInfo.setOperator(Operator.IN);
+            QueryTemplate qt_ = getRefQT(refAbName_, clause, operator, ordinaryValue);
+            LeafValue lValue = new LeafValue();
+            lValue.setQueryTemplate(qt_);
+            leafInfo.setValue(lValue);
+            qt.setId("qt_" + refAbName + "_" + refAbName_);
+        }else{
+            leafInfo.setClause(clause);
+            leafInfo.setOperator(operator);
+            LeafValue lValue = new LeafValue();
+            lValue.setOrdinaryValue(ordinaryValue);
+            leafInfo.setValue(lValue);
+            qt.setId("qt_" + refAbName + "_" + clause);
+        }
+        ci.setLeafInfo(leafInfo);
+        condition.setCIMap(ciMap);
+        return qt;
+    }
+
+    /**
+     * 缁勮鏌ヨ妯℃澘
+     * @return
+     */
+    public QueryTemplate getQT(HashMap<String,Object> dataMap){
+        QueryTemplate qt = new QueryTemplate();
+        qt.setType(QTConstants.TYPE_LINK);
+        //TODO String qtId =
+        qt.setLinkType((String) dataMap.get("linkTypeName"));
+        qt.setDirection( (Boolean)dataMap.get("rdPositive") ? QTConstants.DIRECTION_POSITIVE : QTConstants.DIRECTION_OPPOSITE);
+        qt.setBtmType((String) dataMap.get("btmName"));
+        if("鎵�鏈夌被鍨�".equals(dataMap.get("combRelaType"))){
+            qt.setBtmType("*");
+        }
+        qt.setVersion(getVersion((String) dataMap.get("versionValue")));
+        qt.setQueryISLeaf((Boolean) dataMap.get("isQueryIsLeaf"));
+        qt.setLevel(StringUtils.isBlank((CharSequence) dataMap.get("level")) ? 1 : Integer.valueOf(String.valueOf(dataMap.get("level"))));
+        List<String> clauseList = new ArrayList<String>();
+        //TODO 鏌ヨ鍒� 鏄剧ず鍒�
+        clauseList.add("*");
+        qt.setClauseList(clauseList);
+//        Condition con = new Condition();
+//        qt.setCondition(con);
+//        HashMap<String, ConditionItem> ciMap = getCIMap();
+//        con.setCIMap(ciMap);
+//        con.setRootCIName(con.getRootCINameByCIMap(ciMap));
+        return qt;
+    }
+
+
+    /**
+     * 杩斿洖鏌ヨ鐨勭増鏈�
+     * @return
+     */
+    public int getVersion(String versionValue){
+        int version = 0;
+        if(versionValue.equals("褰撳墠鐗堟湰褰撳墠鐗堟")){
+            version = 1;
+        }else if(versionValue.equals("褰撳墠鐗堟湰鏈�鏂扮増娆�")){
+            version = 2;
+        }else if(versionValue.equals("鏈�鏂扮増鏈渶鏂扮増娆�")){
+            version = 3;
+        }else if(versionValue.equals("褰撳墠鐗堟")){
+            version = 4;
+        }else if(versionValue.equals("褰撳墠鐗堟湰")){
+            version = 5;
+        }else if(versionValue.equals("褰撳墠鍛藉悕瀵硅薄")){
+            version = 6;
+        }else if(versionValue.equals("宸插彂甯冪殑鏈�鏂扮増鏈�")){
+            version = 7;
+        }
+        return version;
+    }
+
 
     /**
      * 鏍¢獙鍙傛暟
diff --git a/Source/plt-web/plt-web-ui/package.json b/Source/plt-web/plt-web-ui/package.json
index a8b7304..c505ca9 100644
--- a/Source/plt-web/plt-web-ui/package.json
+++ b/Source/plt-web/plt-web-ui/package.json
@@ -28,6 +28,7 @@
     "script-loader": "^0.7.2",
     "vue": "^2.6.10",
     "vue-axios": "^2.1.2",
+    "vue-flowchart-editor": "1.0.2",
     "vue-i18n": "^8.7.0",
     "vue-quill-editor": "^3.0.6",
     "vue-router": "^3.0.1",
diff --git a/Source/plt-web/plt-web-ui/src/api/modeling/businessType/api.js b/Source/plt-web/plt-web-ui/src/api/modeling/businessType/api.js
new file mode 100644
index 0000000..1b64d2b
--- /dev/null
+++ b/Source/plt-web/plt-web-ui/src/api/modeling/businessType/api.js
@@ -0,0 +1,10 @@
+import request from '@/router/axios';
+
+// 鍒楄〃鏌ヨ
+export function getBizTypes(params) {
+  return request({
+    url: "/api/btmTypeController/getTreeBizTypes",
+    method: "get",
+    params
+  });
+}
diff --git a/Source/plt-web/plt-web-ui/src/api/modeling/lifeCycle/api.js b/Source/plt-web/plt-web-ui/src/api/modeling/lifeCycle/api.js
new file mode 100644
index 0000000..c22a3d9
--- /dev/null
+++ b/Source/plt-web/plt-web-ui/src/api/modeling/lifeCycle/api.js
@@ -0,0 +1,64 @@
+import request from '@/router/axios';
+
+// 鍒楄〃鏌ヨ
+export function gridLifeCycle() {
+  return request({
+    url: "/api/lifeCycleController/gridLifeCycle",
+    method: "get",
+  });
+}
+
+// 璺冭縼浜嬩欢鏌ヨ
+export function getLCEventKeys() {
+  return request({
+    url: "/api/lifeCycleController/getLCEventKeys",
+    method: "get",
+  });
+}
+
+// 鍒涘缓
+export function addLifeCycle(params) {
+  return request({
+    url: "/api/lifeCycleController/addLifeCycle",
+    method: "post",
+    data:params
+  });
+}
+
+// 淇敼
+export function updateLifeCycle(params) {
+  return request({
+    url: "/api/lifeCycleController/updateLifeCycle",
+    method: "put",
+    data:params
+  });
+}
+
+// 鍒犻櫎
+export function deleteLifeCycles(data) {
+  return request({
+    url: "/api/lifeCycleController/deleteLifeCycles",
+    method: "delete",
+    data:data
+  });
+}
+
+// 瀵煎叆
+export function exportLifeCycles (params) {
+  return request({
+    url: '/api/lifeCycleController/exportLifeCycles',
+    method: 'get',
+    headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'},
+    responseType: 'blob',
+    params
+  })
+}
+
+// 鏌ョ湅閫傜敤鑼冨洿
+export function getUsedLifeCycleList(params) {
+  return request({
+    url: "/api/lifeCycleController/getUsedLifeCycleList",
+    method: "get",
+    params
+  });
+}
diff --git a/Source/plt-web/plt-web-ui/src/api/modeling/linkType/api.js b/Source/plt-web/plt-web-ui/src/api/modeling/linkType/api.js
index 73921ce..0500f79 100644
--- a/Source/plt-web/plt-web-ui/src/api/modeling/linkType/api.js
+++ b/Source/plt-web/plt-web-ui/src/api/modeling/linkType/api.js
@@ -26,6 +26,15 @@
   });
 }
 
+// 淇
+export function repairTable(params) {
+  return request({
+    url: "/api/linkTypeController/repairTable",
+    method: "post",
+    data:params
+  });
+}
+
 // 鍒涘缓瑙嗗浘
 export function createView() {
   return request({
@@ -35,17 +44,18 @@
 }
 
 // 鏌ヤ笟鍔$被鍨嬫帴鍙�
-export function getBizTypes() {
+export function getBizTypes(params) {
   return request({
-    url: "/api/linkTypeController/expData",
-    method: "post",
+    url: "/api/btmTypeController/getBizTypes",
+    method: "get",
+    params
   });
 }
 
 // 瀵煎嚭
-export function exportStatus  (params) {
+export function expData (params) {
   return request({
-    url: '/api/statusController/exportStatus',
+    url: '/api/linkTypeController/expData',
     method: 'get',
     headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'},
     responseType: 'blob',
@@ -53,3 +63,21 @@
   })
 }
 
+// 淇濆瓨 淇敼 鎺ュ彛
+export function addAndEditLink(addFlag,params) {
+  return request({
+    url: `/api/linkTypeController/addAndEditLink?addFlag=${addFlag}`,
+    method: "post",
+    data:params
+  });
+}
+
+// 鍒犻櫎鎺ュ彛
+export function deleteLink(params) {
+  return request({
+    url: '/api/linkTypeController/deleteLink',
+    method: "delete",
+    data:params
+  });
+}
+
diff --git a/Source/plt-web/plt-web-ui/src/api/modeling/statusPool/api.js b/Source/plt-web/plt-web-ui/src/api/modeling/statusPool/api.js
index 6e8c6f3..583d3aa 100644
--- a/Source/plt-web/plt-web-ui/src/api/modeling/statusPool/api.js
+++ b/Source/plt-web/plt-web-ui/src/api/modeling/statusPool/api.js
@@ -1,11 +1,14 @@
 import request from '@/router/axios';
 
 // 鍒楄〃鏌ヨ
-export function gridStatus(params) {
+export function gridStatus(page, limit) {
   return request({
     url: "/api/statusController/gridStatus",
     method: "get",
-    params
+    params: {
+      page,
+      limit,
+    }
   });
 }
 
@@ -14,7 +17,7 @@
   return request({
     url: "/api/statusController/addSave",
     method: "post",
-    data:params
+    data: params
   });
 }
 
@@ -23,7 +26,7 @@
   return request({
     url: "/api/statusController/editSave",
     method: "put",
-    data:params
+    data: params
   });
 }
 
@@ -32,12 +35,12 @@
   return request({
     url: "/api/statusController/deleteStatus",
     method: "delete",
-    data:params
+    data: params
   });
 }
 
 // 瀵煎嚭
-export function exportStatus  (params) {
+export function exportStatus(params) {
   return request({
     url: '/api/statusController/exportStatus',
     method: 'get',
diff --git a/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/ContextMenu.vue b/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/ContextMenu.vue
new file mode 100644
index 0000000..1b66514
--- /dev/null
+++ b/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/ContextMenu.vue
@@ -0,0 +1,79 @@
+<template>
+  <context-menu class="contextMenu">
+    <node-menu>
+<!--      <menu-li command="copy" text="鎷疯礉" />-->
+      <menu-li command="delete" text="鍒犻櫎" />
+    </node-menu>
+    <edge-menu>
+      <menu-li command="delete" text="鍒犻櫎" />
+    </edge-menu>
+    <canvas-menu>
+      <menu-li command="undo" text="鎾ら攢" />
+      <menu-li command="redo" text="閲嶅仛" />
+<!--      <menu-li command="pasteHere" icon="paste" text="绮樿创鍒拌繖閲�" />-->
+    </canvas-menu>
+  </context-menu>
+</template>
+
+<script>
+import {
+  NodeMenu,
+  EdgeMenu,
+  GroupMenu,
+  MultiMenu,
+  CanvasMenu,
+  ContextMenu,
+} from 'vue-flowchart-editor'
+import MenuLi from './ContextMenuItem'
+
+export default {
+  name: 'EditorContextMenu',
+  components: {
+    NodeMenu,
+    EdgeMenu,
+    GroupMenu,
+    MultiMenu,
+    CanvasMenu,
+    ContextMenu,
+    MenuLi,
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+.contextMenu {
+  display: none;
+  overflow: hidden;
+  font-size: 12px;
+  background: #fff;
+  border-radius: 4px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
+}
+
+.contextMenu .command.disable .item {
+  color: rgba(0, 0, 0, 0.25);
+  cursor: auto;
+}
+
+.contextMenu .command.disable .item:hover {
+  background: #fff;
+}
+
+.contextMenu .item {
+  display: flex;
+  align-items: center;
+  padding: 5px 12px;
+  cursor: pointer;
+  transition: all 0.3s;
+  user-select: none;
+}
+
+.contextMenu .item:hover {
+  background: #e6f7ff;
+}
+
+.contextMenu .item i {
+  margin-right: 8px;
+  margin-top: 3px;
+}
+</style>
diff --git a/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/ContextMenuItem.vue b/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/ContextMenuItem.vue
new file mode 100644
index 0000000..c94ccd6
--- /dev/null
+++ b/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/ContextMenuItem.vue
@@ -0,0 +1,35 @@
+<template>
+  <command :name="command">
+    <div class="item">
+      <icon :type="iconType" :title="text" />
+      <span>{{ label }}</span>
+    </div>
+  </command>
+</template>
+
+<script>
+import { Command } from 'vue-flowchart-editor'
+import Icon from './Icon'
+import upperFirst from 'lodash/upperFirst'
+
+export default {
+  name: 'EditorContextMenuItem',
+
+  components: {
+    Command,
+    Icon,
+  },
+
+  props: ['command', 'icon', 'text'],
+
+  computed: {
+    iconType() {
+      return `icon${this.icon || this.command}`
+    },
+
+    label() {
+      return this.text || upperFirst(this.command)
+    },
+  },
+}
+</script>
diff --git a/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/CustomCommand.vue b/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/CustomCommand.vue
new file mode 100644
index 0000000..a797ec9
--- /dev/null
+++ b/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/CustomCommand.vue
@@ -0,0 +1,67 @@
+<template>
+  <div>
+    <register-command
+      name="generateData"
+      :config="generateDataCommandConfig"
+      extend="copy"
+    />
+    <register-command
+      name="downloadImage"
+      :config="downloadImageCommandConfig"
+      extend="copy"
+    />
+  </div>
+</template>
+
+<script>
+import { RegisterCommand } from 'vue-flowchart-editor'
+
+export default {
+  name: 'CustomCommand',
+
+  components: {
+    RegisterCommand,
+  },
+
+  inject: ['root'],
+
+  props: ['save', 'download'],
+
+  data() {
+    const { propsAPI } = this.root
+    const { save, download } = this
+    return {
+      generateDataCommandConfig: {
+        queue: false, // 鏄惁杩涘叆鍒楅槦锛岄粯璁や负 true
+        enable(/* editor */) {
+          // 鍛戒护鏄惁鍙敤
+          return true
+        },
+        execute(/* editor */) {
+          // 姝e悜鍛戒护閫昏緫
+          console.log('鎵ц姝e悜鍛戒护')
+          const data = propsAPI.save()
+          console.log(data)
+          console.log(JSON.stringify(data))
+          save(data)
+          alert(JSON.stringify(data))
+        },
+        back(/* editor */) {
+          // 鍙嶅悜鍛戒护閫昏緫
+          console.log('鎵ц鍙嶅悜鍛戒护')
+        },
+      },
+      downloadImageCommandConfig: {
+        queue: false,
+        enable() {
+          return true
+        },
+        execute() {
+          download()
+        },
+        back() {},
+      },
+    }
+  },
+}
+</script>
diff --git a/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/DetailForm.vue b/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/DetailForm.vue
new file mode 100644
index 0000000..b78c6e4
--- /dev/null
+++ b/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/DetailForm.vue
@@ -0,0 +1,216 @@
+<template>
+  <div class="right_box">
+    <hr/>
+    <div v-if="type === 'node'">
+      <el-form
+        ref="form"
+        :model="formModel"
+        :rules="rules"
+        label-width="80px"
+        size="mini"
+      >
+        <el-form-item label="鍚嶇О" prop="label">
+          <el-input v-model.trim="formModel.label" :maxLength="20" disabled/>
+        </el-form-item>
+        <el-form-item label="褰㈢姸">
+          <el-select
+            v-model="formModel.shape"
+            :disabled="!disabledBtn"
+            placeholder="璇烽�夋嫨褰㈢姸"
+            style="width: 100%"
+          >
+            <el-option
+              v-for="item in shapeTypeList"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="棰滆壊">
+          <el-input v-model.trim="formModel.color" :disabled="!disabledBtn" clearable/>
+        </el-form-item>
+        <el-form-item label="瀹藉害" prop="width">
+          <el-input v-model.trim.number="formModel.width" :disabled="!disabledBtn" clearable>
+            <template slot="prepend">瀹�</template>
+          </el-input>
+        </el-form-item>
+        <el-form-item label="楂樺害" prop="height">
+          <el-input v-model.trim.number="formModel.height" :disabled="!disabledBtn" clearable>
+            <template slot="prepend">楂�</template>
+          </el-input>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div v-else-if="type === 'edge'">
+      <el-form
+        :model="formModel"
+        :rules="rules"
+        label-width="80px"
+        size="small"
+      >
+        <el-form-item label="璧峰鐘舵��">
+          <el-input v-model.trim="formModel.source" disabled/>
+        </el-form-item>
+        <el-form-item label="鐩爣鐘舵��">
+          <el-input v-model.trim="formModel.target" disabled/>
+        </el-form-item>
+        <el-form-item label="鍚嶇О">
+          <el-input v-model.trim="formModel.label" :disabled="!disabledBtn"/>
+        </el-form-item>
+        <el-form-item label="褰㈢姸">
+          <el-select
+            v-model="formModel.shape"
+            :disabled="!disabledBtn"
+            placeholder="璇烽�夋嫨褰㈢姸"
+            style="width: 100%"
+          >
+            <el-option
+              v-for="item in lineTypeList"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div class="btn_box">
+      <el-button :disabled="!disabledBtn" size="mini" type="primary" @click="handleSubmit"
+      >鏇存柊灞炴��
+      </el-button
+      >
+    </div>
+  </div>
+</template>
+
+<script>
+import {cloneDeep} from 'lodash'
+
+export default {
+  name: 'EditorDetailForm',
+
+  inject: ['root'],
+
+  props: ['type', 'readOnly'],
+
+  data() {
+    return {
+      formModel: {},
+      fontSize: 12,
+      shapeTypeList: [
+        {label: '鐭╁舰', value: 'flow-rect'},
+        {label: '妞渾', value: 'flow-circle'},
+        {label: '鑿卞舰', value: 'flow-rhombus'},
+        {label: '鑳跺泭', value: 'flow-capsule'},
+      ],
+      lineTypeList: [
+        {label: '鏇茬嚎', value: 'flow-smooth'},
+        {label: '鎶樼嚎', value: 'flow-polyline'},
+        {label: '鍦嗚鎶樼嚎', value: 'flow-polyline-round'},
+      ],
+      rules: {
+        label: [{required: true, message: '鍚嶇О涓嶈兘涓虹┖', trigger: 'blur'}],
+        width: [
+          {required: true, message: '瀹藉害涓嶈兘涓虹┖', trigger: 'blur'},
+          {pattern: /^[0-9]+$/, message: '瀹藉害鍙兘涓烘暟瀛�', trigger: 'blur'},
+        ],
+        height: [
+          {required: true, message: '楂樺害涓嶈兘涓虹┖', trigger: 'blur'},
+          {pattern: /^[0-9]+$/, message: '楂樺害鍙兘涓烘暟瀛�', trigger: 'blur'},
+        ],
+      },
+    }
+  },
+
+  created() {
+    const formModel = this.root.propsAPI.getSelected()[0].getModel()
+    this.formModel = Object.assign(
+      {width: 80, height: 48},
+      {shape: 'flow-smooth'},
+      cloneDeep(formModel) // 闃叉璇紪杈�
+    )
+  },
+  computed: {
+    disabledBtn() {
+      return this.$store.state.flow.methodBtn;
+    }
+  },
+
+  methods: {
+    async handleSubmit() {
+      if (this.type === 'node') {
+        await this.$refs.form.validate()
+      }
+      const {getSelected, executeCommand, update} = this.root.propsAPI
+      const {formModel} = this
+      setTimeout(() => {
+        const item = getSelected()[0]
+        if (!item) return
+
+        // 鑷姩璋冩暣灏哄
+        const adjustSize = (model) => {
+          // if (model.type !== 'node' || model.shape !== 'flow-rect') {
+          //   return model
+          // }
+          const canvas = document.createElement('canvas')
+          const canvasContext = canvas.getContext('2d')
+          canvasContext.font = this.fontSize + 'px System'
+          let label = model.label.replace('\n', '')
+          let sourceWidth = this.formModel.width
+          let sourceHeight = this.formModel.height
+          const spacing = 10
+          // 鑾峰彇鏂囧瓧瀹藉害
+          const widthWithSpacing = canvasContext.measureText(label).width + spacing
+          model.size = `${sourceWidth}*${sourceHeight}` // 鍏堟仮澶嶉粯璁ゅ昂瀵�
+
+          if (widthWithSpacing <= sourceWidth) {
+            return model
+          }
+
+          // 鑷姩鎶樿
+          let multilineText = ''
+          let multilineCount = 1
+          let multilineTextWidth = 0
+
+          for (const char of label) {
+            const {width} = canvasContext.measureText(char)
+            console.log(multilineTextWidth + width + spacing, 'multilineTextWidth');
+            if (multilineTextWidth + width + spacing >= sourceWidth) {
+              multilineText += '\n'
+              multilineTextWidth = 0
+              multilineCount++
+            }
+            multilineText += char
+            multilineTextWidth += width
+          }
+
+          return {
+            ...model,
+            label: multilineText,
+            size: `${sourceWidth}*${Math.max(
+              sourceHeight,
+              this.fontSize * multilineCount * 1.2 + spacing
+            )}`,
+          }
+        }
+
+        const newFormModel = adjustSize(formModel)
+        console.log(newFormModel, 'newFormModel')
+        executeCommand(() => {
+          update(item, newFormModel)
+        })
+      }, 0)
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+.btn_box {
+  text-align: center;
+}
+
+</style>
diff --git a/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/DetailPanel.vue b/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/DetailPanel.vue
new file mode 100644
index 0000000..4a616a4
--- /dev/null
+++ b/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/DetailPanel.vue
@@ -0,0 +1,209 @@
+<template>
+  <div>
+    <div class="tree_data_box">
+      <el-form
+        ref="form"
+        :model="newRowData"
+        :rules="rules"
+        label-width="80px"
+        size="mini"
+      >
+        <el-form-item label="鍚嶇О" prop="id">
+          <el-input v-model.trim="newRowData.id" :disabled="!disabledBtn" :maxLength="20" clearable/>
+        </el-form-item>
+        <el-form-item label="鏍囩" prop="name">
+          <el-input v-model.trim="newRowData.name" :disabled="!disabledBtn" clearable/>
+        </el-form-item>
+        <el-form-item label="璧峰鐘舵��" prop="startStatus">
+          <el-select
+            v-model="newRowData.startStatus"
+            :disabled="!disabledBtn"
+            placeholder="璇烽�夋嫨璧峰鐘舵��"
+            style="width: 100%"
+          >
+            <el-option
+              v-for="item in existNodes"
+              :key="item.id"
+              :label="item.id"
+              :value="item.id"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="鎻忚堪">
+          <el-input v-model.trim="newRowData.description" :disabled="!disabledBtn" type="textarea"></el-input>
+        </el-form-item>
+      </el-form>
+    </div>
+    <detail-panel>
+      <template v-slot="{ status }">
+        <node-panel :status="status">
+          <detail-form ref="detailFrom" type="node"/>
+        </node-panel>
+        <edge-panel :status="status">
+          <detail-form type="edge"/>
+        </edge-panel>
+        <group-panel :status="status">
+          <detail-form type="group"/>
+        </group-panel>
+
+        <div v-if="status === 'edge-selected'" class="event">
+          <hr/>
+          <h4>璺冭縼浜嬩欢</h4>
+          <el-select
+            ref="mySelect"
+            v-model="currentSelectedLine.events"
+            :disabled="!disabledBtn"
+            multiple
+            size="mini"
+            style="width: 100%"
+            value-key="oid"
+            @change="handleChange"
+          >
+            <el-option
+              v-for="(item,index) in newRowData.eventList"
+              :key="index"
+              :label="item"
+              :value="item"
+            ></el-option>
+          </el-select>
+        </div>
+      </template>
+    </detail-panel>
+  </div>
+</template>
+
+<script>
+// import API from "@/api/modeling/cycle";
+
+import {
+  NodePanel,
+  EdgePanel,
+  GroupPanel,
+  MultiPanel,
+  CanvasPanel,
+  DetailPanel,
+} from "vue-flowchart-editor";
+import DetailForm from "./DetailForm";
+
+export default {
+  name: "EditorDetailPanel",
+  components: {
+    NodePanel,
+    EdgePanel,
+    GroupPanel,
+    MultiPanel,
+    CanvasPanel,
+    DetailPanel,
+    DetailForm,
+  },
+  props: ["rowData", "existNodes", "existEdges", "type", "currentSelectedLine"],
+  data() {
+    return {
+      newRowData: {
+        startStatus: undefined,
+        name: undefined,
+        id: undefined,
+        remark: undefined,
+        saveEventList: []
+      },
+      rules: {
+        name: [{required: true, message: "鍚嶇О涓嶈兘涓虹┖", trigger: "blur"}],
+        id: [
+          {required: true, message: "鏍囩涓嶈兘涓虹┖", trigger: "blur"},
+          {
+            pattern: /^[A-z]+$/g,
+            message: "鏍囩鍙兘杈撳叆鑻辨枃",
+            trigger: "blur",
+          },
+        ],
+        startStatus: [
+          {required: true, message: "璧峰鐘舵�佷笉鑳戒负绌�", trigger: "change"},
+        ],
+      },
+      eventList: [
+        {
+          oid: '1',
+          value: 'xxx',
+          eventShowName: 'xxx'
+        }
+      ],
+      edgeEventList: {},
+      currentActive: 0,
+    };
+  },
+  created() {
+  },
+  computed: {
+    disabledBtn() {
+      return this.$store.state.flow.methodBtn;
+    }
+  },
+  methods: {
+    async getNewRowDate() {
+      return new Promise((resolve) => {
+        this.$refs.form.validate((flag) => {
+          if (!flag) {
+            resolve(false);
+          } else {
+            resolve(this.newRowData);
+          }
+        });
+      });
+    },
+    handleChange(val) {
+    }
+
+  },
+  watch: {
+    rowData: {
+      deep: true,
+      immediate: true,
+      handler(newV) {
+        if (
+          typeof newV === "object" &&
+          newV !== null &&
+          Object.keys(this.rowData).length > 0
+        ) {
+          this.newRowData = Object.assign({}, newV);
+        }
+      },
+    },
+    existNodes(newV) {
+      const flag = newV.some((item) => item.id === this.newRowData.startStatus);
+      if (!flag) {
+        this.newRowData.startStatus = undefined;
+      }
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+
+::v-deep {
+  .el-tag.el-tag--info {
+    color: #409eff;
+    background-color: #ecf5ff;
+  }
+
+}
+
+.event {
+  margin-top: 20px;
+  text-align: center;
+}
+
+.flex {
+  margin-top: 10px;
+  display: flex;
+  justify-content: space-between;
+}
+
+.red {
+  color: red;
+}
+
+.active {
+  // box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.4)
+}
+</style>
diff --git a/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/EditorMinimap.vue b/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/EditorMinimap.vue
new file mode 100644
index 0000000..12f7d82
--- /dev/null
+++ b/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/EditorMinimap.vue
@@ -0,0 +1,11 @@
+<template>
+  <minimap :height="200" />
+</template>
+
+<script>
+import { Minimap } from 'vue-flowchart-editor'
+export default {
+  name: 'EditorMinimap',
+  components: { Minimap },
+}
+</script>
diff --git a/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/Icon.vue b/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/Icon.vue
new file mode 100644
index 0000000..05b7abd
--- /dev/null
+++ b/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/Icon.vue
@@ -0,0 +1,15 @@
+<template>
+  <i class="action" :title="text">
+    <svg width="1em" height="1em" fill="currentColor">
+      <use :xlink:href="'#' + type" />
+    </svg>
+  </i>
+</template>
+
+<script>
+import '../iconfont'
+export default {
+  name: 'EditorIcon',
+  props: ['type', 'text'],
+}
+</script>
diff --git a/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/ItemPanel.vue b/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/ItemPanel.vue
new file mode 100644
index 0000000..7a76262
--- /dev/null
+++ b/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/ItemPanel.vue
@@ -0,0 +1,121 @@
+<template>
+  <div class="item_panel_box">
+    <el-input size="mini" placeholder="杈撳叆鍏抽敭瀛楄繘琛岃繃婊�" v-model="filterText">
+    </el-input>
+    <div class="box_item">
+      <item-panel class="item-panel" v-loading="loading">
+        <template v-for="(item, index) in nodeItems">
+          <item
+            :key="index"
+            :type="item.type || 'node'"
+            :size="item.size || '72*43'"
+            :shape="item.shape || 'flow-rect'"
+            :model="{
+              // must have model property
+              color: item.color || '#1890FF',
+              label: item.id || '鑺傜偣'
+            }"
+          >
+            <template v-if="item.src">
+              <div class="item item-img">
+                <img :src="item.src" :alt="item.id" />
+              </div>
+            </template>
+            <template v-else>
+              <div :class="'item item-' + (item.shape || 'flow-rect')">
+                <span>{{ item.id }}</span>
+              </div>
+            </template>
+          </item>
+        </template>
+      </item-panel>
+    </div>
+  </div>
+</template>
+
+<script>
+import { Item, ItemPanel } from 'vue-flowchart-editor'
+// import { getPage } from '../../../api/omd/status'
+
+export default {
+  name: 'EditorItemPanel',
+  components: { ItemPanel, Item },
+  props: {
+    nodeItems:{
+      type:Array,
+      default:() => [],
+    }
+  },
+  data() {
+    return {
+      filterText: '',
+      loading: false,
+    }
+  },
+  created() {
+    this.loading = false
+
+  },
+  computed: {
+    filterNode() {
+      return this.nodeItems.filter(item => item.id.includes(this.filterText))
+    }
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+.item-panel {
+  width: 210px;
+  height: 77vh;
+  text-align: center;
+  overflow-y: scroll;
+  display: flex;
+  flex-wrap: wrap; /* 鍏佽鎹㈣ */
+  justify-content: center; /* 灞呬腑瀵归綈椤圭洰 */
+  align-items: flex-start; /* 纭繚椤圭洰鍦ㄥ鍣ㄩ《閮ㄥ榻� */
+}
+
+.item {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  font-size: 12px;
+  margin: 10px; /* 璁惧畾澶栬竟璺濅互纭繚椤圭洰闂存湁闂撮殧 */
+  user-select: none;
+}
+
+/* 椤圭洰绫诲瀷鐨勬牱寮� */
+.item-flow-rect {
+  width: 75px;
+  padding: 6px;
+  box-sizing: border-box;
+  border: 1px solid rgb(24, 144, 255);
+  background-color: rgba(24, 144, 255, 0.2);
+}
+
+.item-flow-circle {
+  width: 70px;
+  height: 70px;
+  border-radius: 60px;
+  border: 1px solid rgb(250, 140, 22);
+  background-color: rgba(250, 140, 22, 0.2);
+}
+
+.item-flow-rhombus {
+  width: 70px;
+  height: 70px;
+  border: 1px solid rgb(19, 194, 194);
+  background-color: rgba(19, 194, 194, 0.2);
+  transform: rotate(45deg);
+  margin: 25px auto;
+
+  span {
+    transform: rotate(-45deg);
+  }
+}
+
+.item-img {
+  max-width: 100px;
+}
+</style>
diff --git a/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/Toolbar.vue b/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/Toolbar.vue
new file mode 100644
index 0000000..f656817
--- /dev/null
+++ b/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/Toolbar.vue
@@ -0,0 +1,169 @@
+<template>
+  <toolbar class="toolbar">
+    <template>
+      <toolbar-button command="undo" text="鎾ら攢"/>
+      <toolbar-button command="redo" text="閲嶅仛"/>
+<!--      <toolbar-button command="copy" text="澶嶅埗"/>-->
+<!--      <toolbar-button command="paste" text="绮樿创"/>-->
+      <div class="split"></div>
+    </template>
+    <toolbar-button command="zoomIn" icon="zoom-in" text="鏀惧ぇ"/>
+    <toolbar-button command="zoomOut" icon="zoom-out" text="缂╁皬"/>
+    <toolbar-button command="autoZoom" icon="fit" text="鑷�傚簲"/>
+    <toolbar-button command="resetZoom" icon="actual-size" text="瀹為檯灏哄"/>
+    <template>
+      <div class="split"></div>
+      <!-- <toolbar-button command="toBack" icon="to-back" text="鍚戜笅涓�灞�" /> -->
+      <!-- <toolbar-button command="toFront" icon="to-front" text="鍚戜笂涓�灞�" /> -->
+      <!-- <toolbar-button command="addGroup" icon="group" text="缂栫粍" /> -->
+      <!-- <toolbar-button command="unGroup" icon="ungroup" text="鍙栨秷缂栫粍" /> -->
+      <toolbar-button command="selectAll" icon="select-all" text="鍏ㄩ��"/>
+      <toolbar-button command="multiSelect" icon="select" text="妗嗛��"/>
+      <div v-if="disabledBtn" class="split"></div>
+      <toolbar-button  command="delete" text="鍒犻櫎"/>
+      <toolbar-button  command="clear" icon="clear" text="娓呯┖鐢诲竷"/>
+    </template>
+    <template>
+      <div class="split"></div>
+      <toolbar-button
+        command="downloadImage"
+        icon="image"
+        text="涓嬭浇鍥惧儚"
+      />
+    </template>
+    <!--    <el-button>{{this.$store}}</el-button>-->
+    <el-button :disabled="!disabledBtn" icon="el-icon-check" plain size="small" type="success"
+               @click="saveClickHandler">淇濆瓨
+    </el-button>
+    <el-button :disabled="!disabledBtn" icon="el-icon-close" plain size="small" type="danger"
+               @click="removeClickHandler">鍙栨秷
+    </el-button>
+    <!-- right toolbar button -->
+    <!--  <div class="pull-right">-->
+    <!--      <toolbar-button-->
+    <!--        command="generateData"-->
+    <!--        icon="save"-->
+    <!--        text="鐢熸垚鏁版嵁"-->
+    <!--        label="淇濆瓨鏁版嵁"-->
+    <!--      />-->
+    <!--    </div>-->
+  </toolbar>
+</template>
+
+<script>
+import {Toolbar} from 'vue-flowchart-editor'
+import ToolbarButton from './ToolbarButton'
+
+export default {
+  name: 'FlowToolbar',
+
+  components: {
+    Toolbar,
+    ToolbarButton,
+  },
+
+  props: ['chartData', 'toggleReadOnly'],
+  created() {
+
+  },
+  computed: {
+    disabledBtn() {
+      return this.$store.state.flow.methodBtn;
+    }
+  },
+
+  methods: {
+    // 鍙栨秷鎸夐挳鐐瑰嚮
+    removeClickHandler() {
+      this.$confirm("鎮ㄧ‘璁ゆ墽琛屽彇娑堟搷浣�?", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning",
+      }).then(() => {
+        this.$store.dispatch('updateMethodBtn', false);
+        this.$store.dispatch('typeChange', '');
+        console.log(this.$s)
+        // this.$emit('reset-tree'); // 瑙﹀彂鐖剁粍浠堕噸缃�
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '宸插彇娑�'
+        });
+      });
+    },
+
+    // 淇濆瓨鎸夐挳鐐瑰嚮浜嬩欢
+    saveClickHandler(){
+      this.$emit('handler-save');
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+.toolbar {
+  display: flex;
+  align-items: center;
+  height: 27px;
+
+  .split {
+    width: 10px;
+    height: 100%;
+    border-right: 1px solid #eee;
+    margin-right: 10px;
+  }
+
+  .pull-right {
+    display: flex;
+    align-items: center;
+    margin-left: auto;
+  }
+
+  .command {
+    margin-right: 15px;
+    display: flex;
+    color: #333;
+
+    i {
+      display: block;
+      width: 27px;
+      height: 27px;
+      margin: 0 6px;
+      padding-top: 10px;
+      text-align: center;
+      border: 1px solid #fff;
+      cursor: pointer;
+    }
+
+    span {
+      display: block;
+      font-size: 12px;
+      padding-top: 10px;
+      margin-left: -6px;
+      padding-right: 6px;
+      line-height: 20px;
+      cursor: pointer;
+    }
+
+    &:hover {
+      color: #1890ff;
+    }
+  }
+
+  .disable {
+    color: rgba(0, 0, 0, 0.25);
+
+    i {
+      cursor: not-allowed;
+    }
+
+    span {
+      cursor: not-allowed;
+    }
+
+    &:hover {
+      color: rgba(0, 0, 0, 0.25);
+    }
+  }
+}
+</style>
diff --git a/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/ToolbarButton.vue b/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/ToolbarButton.vue
new file mode 100644
index 0000000..05ee2b0
--- /dev/null
+++ b/Source/plt-web/plt-web-ui/src/components/flow-cycle/components/ToolbarButton.vue
@@ -0,0 +1,28 @@
+<template>
+  <command :name="command">
+    <icon :type="iconType" :title="text" />
+    <span v-if="label">{{ label }}</span>
+  </command>
+</template>
+
+<script>
+import { Command } from 'vue-flowchart-editor'
+import Icon from './Icon'
+
+export default {
+  name: 'EditorToolbarButton',
+
+  props: ['command', 'icon', 'text', 'label'],
+
+  computed: {
+    iconType() {
+      return `icon${this.icon || this.command}`
+    },
+  },
+
+  components: {
+    Command,
+    Icon,
+  },
+}
+</script>
diff --git a/Source/plt-web/plt-web-ui/src/components/flow-cycle/flowchartEditor.vue b/Source/plt-web/plt-web-ui/src/components/flow-cycle/flowchartEditor.vue
new file mode 100644
index 0000000..2555966
--- /dev/null
+++ b/Source/plt-web/plt-web-ui/src/components/flow-cycle/flowchartEditor.vue
@@ -0,0 +1,294 @@
+<template>
+  <vue-flowchart-editor ref="flowChart" class="vue-flowchart-editor">
+    <div class="vfe-chart">
+      <!-- 椤堕儴鑿滃崟 -->
+      <div v-if="type !== 'detail'" class="vfe-chart-header">
+        <editor-toolbar @handler-save="handlerSave" @reset-tree="handleResetTree"  :chart-data="chartData"/>
+      </div>
+      <div class="vfe-chart-container">
+        <!-- 宸︿晶椤圭洰鏍� -->
+        <div v-if="disabledBtn" class="vfe-chart-sidebar">
+          <editor-item-panel  :node-items="chartDataNodeItems"/>
+        </div>
+        <!-- 涓诲浘琛� -->
+        <div class="vfe-chart-main">
+          <flow
+            :data="chartData"
+            :onAfterChange="onAfterChange"
+            :onAfterItemSelected="onAfterItemSelected"
+          />
+          <!-- 鎻愮ず妗� -->
+          <div class="tooltip">
+            <template v-for="item in tooltipData">
+              <p>{{ item.name }}: {{ item.value }}</p>
+            </template>
+          </div>
+        </div>
+
+        <div v-if="type !== 'detail'" class="vfe-chart-panel">
+          <div class="vfe-chart-panel-detail">
+            <editor-detail-panel
+              ref="EditorDetailPanel"
+              :currentSelectedLine="currentSelectedLine"
+              :existEdges="existEdges"
+              :existNodes="existNodes"
+              :rowData="rowData"
+              :type="type"
+            />
+          </div>
+        </div>
+
+      </div>
+    </div>
+
+    <!-- 鍙抽敭鑿滃崟 -->
+    <editor-context-menu v-if="type !== 'detail'"/>
+    <!-- 鑷畾涔夎竟閰嶇疆 -->
+    <register-edge
+      :config="customEdgeConfig"
+      extend="flow-polyline"
+      name="custom-polyline"
+    />
+    <!-- 鑷畾涔夊懡浠ょ粍浠� -->
+    <custom-command :download="downloadImage"/>
+  </vue-flowchart-editor>
+</template>
+
+<script>
+import VueFlowchartEditor, {Flow, RegisterEdge} from "vue-flowchart-editor";
+import EditorToolbar from "./components/Toolbar";
+import EditorItemPanel from "./components/ItemPanel";
+import EditorDetailPanel from "./components/DetailPanel";
+import EditorMinimap from "./components/EditorMinimap";
+import EditorContextMenu from "./components/ContextMenu";
+import CustomCommand from "./components/CustomCommand";
+
+export default {
+  name: "FlowchartEditor",
+
+  components: {
+    VueFlowchartEditor,
+    Flow,
+    EditorToolbar,
+    EditorItemPanel,
+    EditorDetailPanel,
+    EditorMinimap,
+    EditorContextMenu,
+    CustomCommand,
+    RegisterEdge,
+  },
+
+  props: ["chartData", "chartDataNodeItems", "saveData", "rowData", "type"],
+
+  data() {
+    return {
+      // 褰撳墠鍥捐〃鐨勬暟鎹�
+      flowChartData: {},
+      // 鑷畾涔夎竟鐨勯厤缃�
+      customEdgeConfig: {
+        getActivedStyle(/*item*/) {
+          return {
+            lineWidth: 3, // 娲昏穬鐘舵�佷笅鐨勮竟鏍峰紡
+          };
+        },
+        getSelectedStyle(/*item*/) {
+          return {
+            lineWidth: 3, // 閫変腑鐘舵�佷笅鐨勮竟鏍峰紡
+          };
+        },
+      },
+      // 宸ュ叿鎻愮ず鏄剧ず寮�鍏�
+      tooltipShow: true,
+      // 宸ュ叿鎻愮ず鏁版嵁
+      tooltipData: [],
+      // 宸插瓨鍦ㄧ殑鑺傜偣鍜岃竟
+      existNodes: this.chartData.nodes || [],
+      existEdges: this.chartData.edges || [],
+      // 褰撳墠閫変腑鐨勮竟
+      currentSelectedLine: {}
+    };
+  },
+  computed: {
+    disabledBtn() {
+      return this.$store.state.flow.methodBtn;
+    }
+  },
+
+  mounted() {
+    // 缁勪欢鎸傝浇瀹屾垚鍚庯紝鑷姩缂╂斁鐢诲竷锛堜粎鍦ㄦ坊鍔犳ā寮忎笅锛�
+    if (this.type === "add") {
+      this.$nextTick(() => {
+        this.$refs.flowChart.propsAPI.executeCommand("autoZoom");
+      });
+    }
+  },
+
+  methods: {
+    update(){
+      this.$refs.flowChart.propsAPI.read(this.flowChartData);
+    },
+    // 澶勭悊鍥捐〃鏁版嵁鏇存敼鐨勪簨浠�
+    onAfterChange(e) {
+      console.log(e)
+      try {
+        if('edit' === this.$store.state.flow.type){
+          this.$refs.flowChart.propsAPI.remove(e.item);
+          if(e.action === 'remove'){
+            this.$message.error('缂栬緫鐘舵�佷笅涓嶈兘鍒囨崲閫変腑椤癸紒');
+          }
+          return;
+        }
+        // 濡傛灉娣诲姞浜嗚妭鐐逛笖鑺傜偣娌℃湁琚洿鏀硅繃
+        if (e.action === "add" && e.model.type === "node") {
+          if (!e.model.change) {
+            this.$refs.flowChart.propsAPI.remove(e.item); // 绉婚櫎鍘熸湁鐨勮妭鐐�
+            e.model.id = e.model.label; // 浣跨敤鏍囩浣滀负鑺傜偣鐨� ID
+            e.model.change = true;
+            this.$refs.flowChart.propsAPI.add("node", e.model); // 娣诲姞鏂扮殑鑺傜偣
+          }
+        }
+      } catch (err) {
+        console.log(err)
+        // 澶勭悊鑺傜偣 ID 鍐茬獊閿欒
+        if (
+          err.message ===
+          `id:${e.model.label} has already been set, please set new one`
+        ) {
+          this.$message.error("涓嶈兘娣诲姞宸插瓨鍦ㄧ殑鑺傜偣锛�");
+        }
+      }
+      // 淇濆瓨褰撳墠鐨勮妭鐐瑰拰杈规暟鎹�
+      const {nodes, edges} = this.$refs.flowChart.propsAPI.save();
+      this.existNodes = nodes || [];
+      this.existEdges = edges || [];
+    },
+    // 澶勭悊閫変腑绾垮彉鍖栫殑浜嬩欢 鍥炲~褰撳墠绾夸俊鎭�
+    onAfterItemSelected({item}) {
+      if (item.target) {
+        // 鏌ユ壘褰撳墠閫変腑鐨勮竟
+        const currentEdge = this.existEdges.filter(itm => itm.id === item.id)[0] || {};
+        if (!Array.isArray(currentEdge.events)) {
+          currentEdge.events = []
+        }
+        this.currentSelectedLine = currentEdge;
+      }
+    },
+
+    // 涓嬭浇鍥剧墖
+    _downloadImage(data, filename = "flowchart.png") {
+      const a = document.createElement("a");
+      a.href = data;
+      a.download = filename;
+      document.body.appendChild(a);
+      a.click();
+    },
+
+    // 璋冪敤涓嬭浇鍥剧墖鏂规硶
+    downloadImage() {
+      const page = this.$refs["flowChart"].propsAPI.editor.getCurrentPage();
+      this._downloadImage(page.saveImage().toDataURL("image/png"));
+    },
+    // 鑾峰彇鏂扮殑琛屾暟鎹紙浠庤缁嗛潰鏉夸腑锛�
+    getNewRowData() {
+      return this.$refs.EditorDetailPanel.getNewRowDate();
+    },
+    // 鑾峰彇褰撳墠鍥捐〃鐨勬暟鎹�
+    getFlowData() {
+      return this.$refs.flowChart.propsAPI.save();
+    },
+    // 鑾峰彇杈逛簨浠跺垪琛紙浠庤缁嗛潰鏉夸腑锛�
+    getEdgesEvents() {
+      return this.$refs.EditorDetailPanel.edgeEventList;
+    },
+
+    // 璋冪敤鐖剁粍浠堕噸缃�
+    handleResetTree(){
+      this.$emit('reset-tree');
+    },
+    handlerSave(){
+      this.$emit('handler-save')
+    }
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.vue-flowchart-editor {
+  display: flex;
+  flex: 1;
+  flex-direction: column;
+  width: 100%;
+  height: 100%;
+  background: #fff;
+}
+
+.vfe-chart {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+
+  .vfe-chart-header {
+    border: 1px solid #e6e9ed;
+    padding: 8px;
+  }
+
+  .vfe-chart-container {
+    flex: 1;
+    display: flex;
+    height: 550px;
+    overflow: hidden;
+
+    .vfe-chart-main {
+      position: relative;
+      flex: 1;
+      height: 80vh; // fix scroll show
+      width: 65%;
+
+      .tooltip {
+        position: absolute;
+        display: none;
+        top: 0;
+        left: 0;
+        width: 100px;
+        height: auto;
+        padding: 15px;
+        border-radius: 10px;
+        z-index: 999;
+        opacity: 0.8;
+        color: #ffffff;
+        font-size: 12px;
+        background-color: #000;
+
+        p {
+          margin: 0;
+        }
+      }
+    }
+
+    .vfe-chart-sidebar {
+      margin-top: 10px;
+      position: relative;
+      display: flex;
+      justify-content: center;
+      width: 210px;
+      background-color: #fafafa;
+      border-right: 1px solid #e6e9ed;
+    }
+
+    .vfe-chart-panel {
+      position: relative;
+      width: 260px;
+      background-color: #fafafa;
+      border-left: 1px solid #e6e9ed;
+      overflow-y: scroll;
+
+      .vfe-chart-panel-detail {
+        box-sizing: border-box;
+        padding: 10px;
+      }
+    }
+  }
+}
+</style>
diff --git a/Source/plt-web/plt-web-ui/src/components/flow-cycle/iconfont.js b/Source/plt-web/plt-web-ui/src/components/flow-cycle/iconfont.js
new file mode 100644
index 0000000..a780a0b
--- /dev/null
+++ b/Source/plt-web/plt-web-ui/src/components/flow-cycle/iconfont.js
@@ -0,0 +1 @@
+!function(v){var c,h='<svg><symbol id="iconto-back" viewBox="0 0 1024 1024"><path d="M640 726.016l0-86.016 86.016 0 0 86.016-86.016 0zM640 214.016l0-86.016 86.016 0 0 86.016-86.016 0zM214.016 297.984l0 512 512 0 0 86.016-512 0q-36.010667 0-61.013333-25.984t-25.002667-59.989333l0-512 86.016 0zM809.984 726.016l0-86.016 86.016 0q0 34.005333-25.984 59.989333t-59.989333 25.984zM809.984 384l0-86.016 86.016 0 0 86.016-86.016 0zM809.984 553.984l0-84.010667 86.016 0 0 84.010667-86.016 0zM384 726.016q-36.010667 0-61.013333-25.984t-25.002667-59.989333l86.016 0 0 86.016zM553.984 128l0 86.016-84.010667 0 0-86.016 84.010667 0zM809.984 128q34.005333 0 59.989333 25.984t25.984 59.989333l-86.016 0 0-86.016zM553.984 640l0 86.016-84.010667 0 0-86.016 84.010667 0zM384 128l0 86.016-86.016 0q0-34.005333 25.002667-59.989333t61.013333-25.984zM384 470.016l0 84.010667-86.016 0 0-84.010667 86.016 0zM384 297.984l0 86.016-86.016 0 0-86.016 86.016 0z"  ></path></symbol><symbol id="iconfit" viewBox="0 0 1024 1024"><path d="M597.333333 405.376c0-0.128 0.085333-0.256 0.085333-0.384C597.418667 404.821333 597.333333 404.650667 597.333333 404.522667L597.333333 192.768C597.333333 180.522667 606.933333 170.538667 618.666667 170.666667c11.733333-0.042667 21.376 9.813333 21.376 22.144L640.042667 384l191.189333 0c12.16 0 22.186667 9.6 22.101333 21.333333 0 11.733333-9.813333 21.333333-22.186667 21.333333l-211.754667 0c-0.128 0-0.256-0.085333-0.384-0.085333S618.837333 426.666667 618.709333 426.666667c-4.821333 0-9.045333-1.962667-12.629333-4.736-0.853333-0.64-1.749333-0.981333-2.432-1.706667-0.213333-0.213333-0.298667-0.469333-0.512-0.725333C599.68 415.744 597.333333 410.837333 597.333333 405.376zM362.666667 170.666667C350.933333 170.624 341.290667 180.48 341.290667 192.810667L341.290667 384 150.101333 384C137.898667 384 127.914667 393.6 128 405.333333 128 417.066667 137.813333 426.666667 150.186667 426.666667l211.754667 0c0.128 0 0.256-0.085333 0.384-0.085333S362.496 426.666667 362.624 426.666667c4.821333 0 9.045333-1.962667 12.629333-4.736 0.853333-0.64 1.749333-0.981333 2.432-1.706667 0.213333-0.213333 0.298667-0.469333 0.512-0.725333C381.653333 415.744 384 410.837333 384 405.376c0-0.128-0.085333-0.256-0.085333-0.384C383.914667 404.821333 384 404.650667 384 404.522667L384 192.768C384 180.522667 374.4 170.538667 362.666667 170.666667zM831.146667 640l-211.754667 0c-0.128 0-0.256 0.085333-0.384 0.085333S618.837333 640 618.709333 640c-4.821333 0-9.088 2.005333-12.672 4.778667-0.810667 0.597333-1.706667 0.938667-2.389333 1.664-0.213333 0.213333-0.298667 0.469333-0.512 0.725333C599.68 650.922667 597.333333 655.829333 597.333333 661.290667c0 0.128 0.085333 0.256 0.085333 0.384 0 0.170667-0.085333 0.341333-0.085333 0.469333l0 211.797333c0 12.202667 9.6 22.229333 21.333333 22.101333 11.733333 0.042667 21.376-9.813333 21.376-22.144L640.042667 682.666667l191.189333 0c12.16 0 22.186667-9.6 22.101333-21.333333C853.333333 649.6 843.52 640 831.146667 640zM378.154667 647.168c-0.213333-0.256-0.298667-0.512-0.512-0.725333-0.682667-0.725333-1.578667-1.066667-2.389333-1.664C371.712 642.005333 367.445333 640 362.624 640c-0.128 0-0.213333 0.085333-0.341333 0.085333S362.026667 640 361.898667 640L150.186667 640C137.813333 640 128 649.6 128 661.333333 127.914667 673.066667 137.898667 682.666667 150.101333 682.666667l191.189333 0 0 191.189333c0 12.288 9.642667 22.186667 21.376 22.144C374.4 896.128 384 886.144 384 873.898667l0-211.797333c0-0.128-0.085333-0.298667-0.085333-0.469333C383.914667 661.546667 384 661.418667 384 661.290667 384 655.829333 381.653333 650.922667 378.154667 647.168zM490.666667 469.333333c-35.328 0-64 28.672-64 64s28.672 64 64 64 64-28.672 64-64S525.994667 469.333333 490.666667 469.333333z"  ></path></symbol><symbol id="iconpaste" viewBox="0 0 1024 1024"><path d="M776 248 704 248 704 192l99.968 0C819.392 192 832 204.608 832 220.032l0 98.88-56 0L776 248zM255.104 904 184 904 184 248 256 248 256 192 156.032 192C140.608 192 128 204.608 128 220.032l0 712C128 947.392 140.608 960 156.032 960l99.136 0L255.168 904zM640 320 320 320 320 192l64 0L384 120C384 89.216 409.216 64 440 64l72.064 0c30.784 0 56 25.216 56 56L568.064 192 640 192 640 320zM512.128 120.128C512.064 120.064 512 120 512 120L440.064 120.064c0 0 0 0.064-0.064 0.064L440 192l72.064 0 0.064 0L512.128 120.128zM888.256 995.776 888.256 578.88l-182.4-192L351.488 386.88c-18.624 0-31.232 12.608-31.232 28.032l0 580.864c0 15.36 12.608 28.032 28.032 28.032l512 0C875.648 1023.744 888.256 1011.136 888.256 995.776zM824.256 586.88l-129.6 0L694.656 450.88 824.256 586.88zM832.256 970.88 376.256 970.88 376.256 442.88l265.6 0 0 196.864 190.4 0L832.256 970.88z"  ></path></symbol><symbol id="iconactual-size" viewBox="0 0 1024 1024"><path d="M829.013333 810.666667l-640 0c-58.794667 0-106.666667-47.829333-106.666667-106.666667l0-469.333333c0-58.794667 47.872-106.666667 106.666667-106.666667l640 0c58.837333 0 106.666667 47.872 106.666667 106.666667l0 469.333333C935.68 762.837333 887.850667 810.666667 829.013333 810.666667zM189.013333 170.666667c-35.285333 0-64 28.714667-64 64l0 469.333333c0 35.285333 28.714667 64 64 64l640 0c35.285333 0 64-28.714667 64-64l0-469.333333c0-35.285333-28.714667-64-64-64L189.013333 170.666667zM338.346667 640.256c0 11.733333-9.557333 21.333333-21.333333 21.333333s-21.333333-9.6-21.333333-21.333333l0-341.333333c0-11.818667 9.557333-21.333333 21.333333-21.333333s21.333333 9.514667 21.333333 21.333333L338.346667 640.256zM722.346667 640.256c0 11.733333-9.557333 21.333333-21.333333 21.333333s-21.333333-9.6-21.333333-21.333333l0-341.333333c0-11.818667 9.557333-21.333333 21.333333-21.333333s21.333333 9.514667 21.333333 21.333333L722.346667 640.256zM509.013333 341.333333c-23.594667 0-42.666667 19.072-42.666667 42.666667s19.072 42.666667 42.666667 42.666667 42.666667-19.072 42.666667-42.666667S532.565333 341.333333 509.013333 341.333333zM509.013333 512c-23.594667 0-42.666667 19.072-42.666667 42.666667s19.072 42.666667 42.666667 42.666667 42.666667-19.072 42.666667-42.666667S532.565333 512 509.013333 512z"  ></path></symbol><symbol id="iconredo" viewBox="0 0 1024 1024"><path d="M708.16 635.904c-39.36 35.968-48.32 41.344-50.496-25.856-3.968-49.152 0-103.552 0-103.552-1.408-3.072-86.464-35.008-227.072 25.856C290.048 593.28 195.2 783.36 178.432 842.88 177.088 877.248 132.288 943.616 128 841.472c-0.576-166.656 64.512-341.12 230.336-441.152 154.624-93.248 283.264-83.776 297.408-78.848 0.256 1.344 0.64 1.856 1.344 1.024 0.192-0.256-0.384-0.64-1.344-1.024-1.216-6.208 2.496-38.272 2.88-98.56-2.368-54.144 12.096-55.808 49.536-26.944 68.544 56.32 251.776 231.36 251.776 231.36S776.768 580.608 708.16 635.904z"  ></path></symbol><symbol id="iconundo" viewBox="0 0 1024 1024"><path d="M379.776 635.904c39.36 35.968 48.32 41.344 50.496-25.856 3.968-49.152 0-103.552 0-103.552 1.408-3.072 86.464-35.008 227.072 25.856 140.544 60.928 235.456 251.008 252.16 310.528 1.344 34.368 46.144 100.736 50.432-1.344 0.576-166.656-64.512-341.12-230.336-441.152C574.976 307.072 446.4 316.608 432.192 321.472c-0.256 1.344-0.64 1.856-1.344 1.024-0.192-0.256 0.384-0.64 1.344-1.024 1.216-6.208-2.496-38.272-2.88-98.56 2.368-54.144-12.096-55.808-49.536-26.944C311.168 252.288 128 427.264 128 427.264S311.168 580.608 379.776 635.904z"  ></path></symbol><symbol id="icondelete" viewBox="0 0 1024 1024"><path d="M677.647059 256l0-90.352941c0-37.436235-23.461647-60.235294-61.771294-60.235294L408.094118 105.411765c-38.249412 0-61.741176 22.799059-61.741176 60.235294l0 90.352941-180.705882 0 0 60.235294 60.235294 0 0 512c0 54.272 33.972706 90.352941 90.352941 90.352941l391.529412 0c55.085176 0 90.352941-33.490824 90.352941-90.352941l0-512 60.235294 0 0-60.235294L677.647059 256zM406.588235 165.647059l210.823529 0-1.264941 90.352941L406.588235 256 406.588235 165.647059zM737.882353 858.352941l-451.764706 0 0-542.117647 451.764706 0L737.882353 858.352941zM466.823529 376.470588l-58.729412 0-1.505882 391.529412 60.235294 0L466.823529 376.470588zM617.411765 376.470588l-60.235294 0 0 391.529412 60.235294 0L617.411765 376.470588z"  ></path></symbol><symbol id="iconzoom-in" viewBox="0 0 1024 1024"><path d="M1000.146824 957.500235l-311.597176-311.597176c58.729412-68.487529 94.509176-157.214118 94.509176-254.373647 0-215.883294-175.646118-391.529412-391.529412-391.529412-104.628706 0-202.932706 40.719059-276.901647 114.688-73.968941 73.908706-114.627765 172.272941-114.627765 276.841412 0 215.883294 175.646118 391.529412 391.529412 391.529412 97.099294 0 185.886118-35.779765 254.433882-94.509176l311.597176 311.597176 42.586353-42.646588zM391.529412 722.823529c-182.693647 0-331.294118-148.600471-331.294118-331.294118 0-88.545882 34.394353-171.730824 96.978824-234.315294 62.584471-62.524235 145.769412-96.978824 234.315294-96.978824 182.693647 0 331.294118 148.600471 331.294118 331.294118 0 182.693647-148.600471 331.294118-331.294118 331.294118zM421.647059 361.411765l120.470588 0 0 60.235294-120.470588 0 0 120.470588-60.235294 0 0-120.470588-120.470588 0 0-60.235294 120.470588 0 0-120.470588 60.235294 0 0 120.470588z"  ></path></symbol><symbol id="iconzoom-out" viewBox="0 0 1024 1024"><path d="M999.344139 955.925769l-311.084802-311.084802c58.63284-68.374912 94.35377-157.015739 94.35377-253.955368 0-215.528306-175.357294-390.8856-390.8856-390.8856-104.396523 0-202.599013 40.652102-276.50646 114.439276-73.787174 73.84731-114.439276 172.0498-114.37914 276.446324 0 215.528306 175.357294 390.8856 390.8856 390.8856 96.939629 0 185.640592-35.72093 254.015504-94.35377l311.084802 311.084802 42.516326-42.576462zM391.727508 721.634954c-182.333098 0-330.749354-148.356119-330.749354-330.749354-0.060136-88.400282 34.337797-171.448438 96.819356-233.869861 62.421424-62.48156 145.529716-96.879493 233.929998-96.879493 182.333098 0 330.749354 148.356119 330.749354 330.749354 0 182.333098-148.416256 330.749354-330.749354 330.749354zM241.386892 360.817477l300.681231 0 0 60.136246-300.681231 0 0-60.136246z"  ></path></symbol><symbol id="iconcopy" viewBox="0 0 1024 1024"><path d="M880 247.008l-162.016-166.016Q700.992 64 677.984 64h-316.992q-26.016 0-46.016 18.016-16.992 15.008-23.008 36.992H231.968q-43.008 0-73.504 31.008t-30.496 76v627.008q0 44 30.496 75.488T231.968 960h508q43.008 0 73.504-31.488t30.496-75.488v-63.008q23.008-6.016 37.504-25.504t14.496-44.512V287.008q0-24-16-40z m-168-160.992l-3.008-3.008z m98.016 177.984L744 196z m-126.016-116.992l108 110.016h-108V147.008zM676.992 128zM204.992 948q4 0.992 4.992 2.016-2.016-0.992-4.992-2.016z m27.008 4q-6.016 0-12-0.992 4.992 0.992 12 0.992z m543.008-99.008q0 15.008-10.016 25.504t-24.992 10.496H232q-14.016 0-24.512-10.496t-10.496-25.504V225.984q0-15.008 10.496-25.504t24.512-10.496h58.016v531.008q0 30.016 20.992 51.008t50.016 20.992H775.04v60z m52-132.992q0 2.016-2.016 2.016h-464q-2.016 0-2.016-2.016V136.992q0-2.016 2.016-2.016h251.008v156.992q0 15.008 10.016 24.992t24 10.016h180.992v392.992z m9.984 64q4-0.992 8.992-2.016-4.992 0.992-8.992 2.016z m-244-168.992h-107.008q-15.008 0-24.992 10.496t-10.016 24.992 10.016 24.992 24.992 10.496h107.008q14.016 0 24.512-10.496t10.496-24.992-10.496-24.992-24.512-10.496z m107.008-111.008h-214.016q-14.016 0-24.512 10.496t-10.496 24.992 10.496 24.992 24.512 10.496h214.016q14.016 0 24-10.496t10.016-24.992-10.016-24.992-24-10.496z m-240.992 36q0 4 0.992 8-0.992-4-0.992-8zM700 512z m12 52l4-2.016z m-260.992-135.488q0 14.496 10.496 24.992t24.512 10.496h214.016q14.016 0 24-10.496t10.016-24.992-10.016-24.992-24-10.496h-214.016q-14.016 0-24.512 10.496t-10.496 24.992z m8 1.504z"  ></path></symbol><symbol id="iconsave" viewBox="0 0 1024 1024"><path d="M886.4 265.6l-128-128c-6.4-6.4-12.8-9.6-22.4-9.6H160c-19.2 0-32 12.8-32 32v704c0 19.2 12.8 32 32 32h704c19.2 0 32-12.8 32-32V288c0-9.6-3.2-16-9.6-22.4zM352 192h320v256H352V192z m480 640H192V192h96v288c0 19.2 12.8 32 32 32h384c19.2 0 32-12.8 32-32V204.8l96 96V832z"  ></path><path d="M576 256c-19.2 0-32 12.8-32 32v64c0 19.2 12.8 32 32 32s32-12.8 32-32V288c0-19.2-12.8-32-32-32z"  ></path></symbol><symbol id="iconselect-all" viewBox="0 0 1024 1024"><path d="M128 213.333333h85.333333V128c-47.146667 0-85.333333 38.186667-85.333333 85.333333z m0 341.333334h85.333333v-85.333334H128v85.333334z m170.666667 341.333333h85.333333v-85.333333h-85.333333v85.333333zM128 384h85.333333v-85.333333H128v85.333333zM554.666667 128h-85.333334v85.333333h85.333334V128z m256 0v85.333333h85.333333c0-47.146667-38.186667-85.333333-85.333333-85.333333zM213.333333 896v-85.333333H128c0 47.146667 38.186667 85.333333 85.333333 85.333333z m-85.333333-170.666667h85.333333v-85.333333H128v85.333333zM384 128h-85.333333v85.333333h85.333333V128z m85.333333 768h85.333334v-85.333333h-85.333334v85.333333z m341.333334-341.333333h85.333333v-85.333334h-85.333333v85.333334z m0 341.333333c47.146667 0 85.333333-38.186667 85.333333-85.333333h-85.333333v85.333333z m0-512h85.333333v-85.333333h-85.333333v85.333333z m0 341.333333h85.333333v-85.333333h-85.333333v85.333333z m-170.666667 170.666667h85.333333v-85.333333h-85.333333v85.333333z m0-682.666667h85.333333V128h-85.333333v85.333333zM298.666667 725.333333h426.666666V298.666667H298.666667v426.666666z m85.333333-341.333333h256v256H384V384z" fill="" ></path></symbol><symbol id="iconselect" viewBox="0 0 1024 1024"><path d="M324.266667 34.133333h-102.4c-10.24 0-17.066667 6.826667-17.066667 17.066667s6.826667 17.066667 17.066667 17.066667h102.4c10.24 0 17.066667-6.826667 17.066666-17.066667S334.506667 34.133333 324.266667 34.133333zM597.333333 34.133333h-102.4c-10.24 0-17.066667 6.826667-17.066666 17.066667s6.826667 17.066667 17.066666 17.066667h102.4c10.24 0 17.066667-6.826667 17.066667-17.066667s-6.826667-17.066667-17.066667-17.066667zM324.266667 716.8h-102.4c-10.24 0-17.066667 6.826667-17.066667 17.066667s6.826667 17.066667 17.066667 17.066666h102.4c10.24 0 17.066667-6.826667 17.066666-17.066666s-6.826667-17.066667-17.066666-17.066667zM563.2 716.8h-68.266667c-10.24 0-17.066667 6.826667-17.066666 17.066667s6.826667 17.066667 17.066666 17.066666h68.266667c10.24 0 17.066667-6.826667 17.066667-17.066666s-6.826667-17.066667-17.066667-17.066667zM34.133333 597.333333c0 10.24 6.826667 17.066667 17.066667 17.066667s17.066667-6.826667 17.066667-17.066667v-102.4c0-10.24-6.826667-17.066667-17.066667-17.066666s-17.066667 6.826667-17.066667 17.066666v102.4zM51.2 341.333333c10.24 0 17.066667-6.826667 17.066667-17.066666v-102.4c0-10.24-6.826667-17.066667-17.066667-17.066667s-17.066667 6.826667-17.066667 17.066667v102.4c0 10.24 6.826667 17.066667 17.066667 17.066666zM768 477.866667c-10.24 0-17.066667 6.826667-17.066667 17.066666v68.266667c0 10.24 6.826667 17.066667 17.066667 17.066667s17.066667-6.826667 17.066667-17.066667v-68.266667c0-10.24-6.826667-17.066667-17.066667-17.066666zM785.066667 221.866667c0-10.24-6.826667-17.066667-17.066667-17.066667s-17.066667 6.826667-17.066667 17.066667v102.4c0 10.24 6.826667 17.066667 17.066667 17.066666s17.066667-6.826667 17.066667-17.066666v-102.4zM733.866667 102.4h68.266666c10.24 0 17.066667-6.826667 17.066667-17.066667v-68.266666c0-10.24-6.826667-17.066667-17.066667-17.066667h-68.266666c-10.24 0-17.066667 6.826667-17.066667 17.066667v68.266666c0 10.24 6.826667 17.066667 17.066667 17.066667zM85.333333 0h-68.266666C6.826667 0 0 6.826667 0 17.066667v68.266666c0 10.24 6.826667 17.066667 17.066667 17.066667h68.266666c10.24 0 17.066667-6.826667 17.066667-17.066667v-68.266666c0-10.24-6.826667-17.066667-17.066667-17.066667zM85.333333 682.666667h-68.266666c-10.24 0-17.066667 6.826667-17.066667 17.066666v68.266667c0 10.24 6.826667 17.066667 17.066667 17.066667h68.266666c10.24 0 17.066667-6.826667 17.066667-17.066667v-68.266667c0-10.24-6.826667-17.066667-17.066667-17.066666zM1013.76 788.48l-375.466667-204.8c-6.826667-3.413333-13.653333-3.413333-20.48 3.413333-3.413333 3.413333-3.413333 10.24-3.413333 17.066667l170.666667 409.6c3.413333 6.826667 6.826667 10.24 13.653333 10.24s13.653333-3.413333 13.653333-10.24l64.853334-133.12 133.12-64.853333c6.826667-3.413333 10.24-10.24 10.24-13.653334 3.413333-6.826667 0-10.24-6.826667-13.653333z" fill="" ></path></symbol><symbol id="iconto-front" viewBox="0 0 1024 1024"><path d="M128 554.666667h85.333333v-85.333334H128v85.333334z m0 170.666666h85.333333v-85.333333H128v85.333333z m85.333333 170.666667v-85.333333H128c0 47.146667 38.186667 85.333333 85.333333 85.333333zM128 384h85.333333v-85.333333H128v85.333333z m512 512h85.333333v-85.333333h-85.333333v85.333333z m170.666667-768H384c-47.146667 0-85.333333 38.186667-85.333333 85.333333v426.666667c0 47.146667 38.186667 85.333333 85.333333 85.333333h426.666667c47.146667 0 85.333333-38.186667 85.333333-85.333333V213.333333c0-47.146667-38.186667-85.333333-85.333333-85.333333z m0 512H384V213.333333h426.666667v426.666667zM469.333333 896h85.333334v-85.333333h-85.333334v85.333333z m-170.666666 0h85.333333v-85.333333h-85.333333v85.333333z"  ></path></symbol><symbol id="iconimage" viewBox="0 0 1024 1024"><path d="M847.657 64.016H175.703c-61.766 0-111.993 50.227-111.993 111.992v671.954c0 61.765 50.226 111.993 111.993 111.993h671.954c61.765 0 111.992-50.228 111.992-111.993V176.01c0-61.765-50.227-111.993-111.992-111.993z m55.995 783.946c0 30.87-25.127 55.997-55.996 55.997H175.703c-30.87 0-55.996-25.127-55.996-55.997V176.01c0-30.87 25.128-55.996 55.996-55.996h671.954c30.87 0 55.996 25.127 55.996 55.996v671.953zM835.19 544.686l-83.995-55.996c-10.444-6.945-23.54-5.688-32.782 1.722l-0.246-0.3-133.184 106.551-197.435-135.752c-0.083-0.055-0.164-0.055-0.218-0.11-2.297-1.53-4.895-2.379-7.52-3.199-0.874-0.273-1.666-0.875-2.57-1.04-2.378-0.492-4.811-0.218-7.273-0.081-1.121 0.082-2.27-0.218-3.363 0-1.23 0.218-2.35 0.984-3.554 1.394-2.27 0.739-4.566 1.367-6.616 2.707-0.083 0.055-0.192 0.055-0.274 0.11L188.17 572.684c-12.878 8.585-16.35 25.946-7.765 38.824 5.386 8.094 14.273 12.47 23.323 12.47 5.332 0 10.718-1.533 15.503-4.704L371.444 517.81 803.8 815.042a27.793 27.793 0 0 0 15.831 4.923c8.913 0 17.663-4.238 23.105-12.14 8.749-12.74 5.523-30.156-7.219-38.934L633.214 629.802l103.956-83.147 66.959 44.621c4.786 3.172 10.171 4.704 15.503 4.704 9.05 0 17.937-4.374 23.323-12.469 8.584-12.877 5.112-30.24-7.766-38.825zM581.674 427.991c69.476 0 125.992-56.516 125.992-125.99 0-69.477-56.516-125.993-125.992-125.993-69.475 0-125.99 56.516-125.99 125.992s56.516 125.991 125.99 125.991z m0-195.985c38.607 0 69.995 31.387 69.995 69.994s-31.388 69.995-69.995 69.995c-38.606 0-69.995-31.39-69.995-69.995 0-38.607 31.39-69.994 69.995-69.994z"  ></path></symbol><symbol id="iconclear" viewBox="0 0 1024 1024"><path d="M686.464 452.821333c5.461333-15.274667 20.394667-43.690667 40.533333-77.952 14.549333-24.746667 39.466667-55.978667 64.810667-87.466666 6.4-7.978667 13.909333-17.152 22.357333-27.562667l34.304 19.456c-8.533333 10.752-15.914667 19.968-22.186666 27.733333-25.770667 31.914667-50.261333 62.165333-65.024 87.296-8.576 14.634667-15.872 27.562667-21.76 38.741334l116.906666 66.304a77.013333 77.013333 0 0 1 28.970667 106.24l-197.973333 336.810666a80 80 0 0 1-108.245334 28.458667l-411.562666-233.344a77.013333 77.013333 0 0 1-28.970667-106.24l197.973333-336.810667a80 80 0 0 1 108.245334-28.501333l116.821333 66.261333c6.912-10.624 14.634667-23.253333 23.253333-37.888 14.762667-25.173333 29.226667-61.056 44.501334-98.986666 3.712-9.173333 8.106667-20.053333 13.354666-32.725334l34.304 19.456-13.141333 32.853334c-15.061333 37.248-30.165333 74.069333-44.714667 98.816-20.138667 34.261333-37.717333 61.184-48.469333 73.429333l-118.229333-67.029333c-33.152-18.773333-73.301333-11.989333-92.074667 19.882666l-167.552 285.056c-18.773333 31.914667-6.826667 73.088 26.325333 91.904l352.554667 199.893334c33.109333 18.773333 75.050667 8.106667 93.781333-23.765334l167.594667-285.056c18.773333-31.914667 5.034667-69.248-28.117333-88.021333l-118.613334-67.242667z m-43.690667-290.133333c22.613333-36.906667 90.026667-47.786667 146.432-15.786667 56.405333 32 80.554667 94.762667 59.306667 132.437334l-34.304-19.456c9.984-18.944-7.68-57.728-45.056-78.890667-37.290667-21.162667-80.341333-16.810667-92.074667 1.109333l-34.304-19.456zM314.112 418.858667l472.704 267.989333-21.888 37.248L292.224 456.106667l21.888-37.205334z"  ></path></symbol><symbol id="icongroup" viewBox="0 0 1024 1024"><path d="M912 820.1V203.9c28-9.9 48-36.6 48-67.9 0-39.8-32.2-72-72-72-31.3 0-58 20-67.9 48H203.9C194 84 167.3 64 136 64c-39.8 0-72 32.2-72 72 0 31.3 20 58 48 67.9v616.2C84 830 64 856.7 64 888c0 39.8 32.2 72 72 72 31.3 0 58-20 67.9-48h616.2c9.9 28 36.6 48 67.9 48 39.8 0 72-32.2 72-72 0-31.3-20-58-48-67.9zM888 112c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zM136 912c-13.3 0-24-10.7-24-24s10.7-24 24-24 24 10.7 24 24-10.7 24-24 24z m0-752c-13.3 0-24-10.7-24-24s10.7-24 24-24 24 10.7 24 24-10.7 24-24 24z m704 680H184V184h656v656z m48 72c-13.3 0-24-10.7-24-24s10.7-24 24-24 24 10.7 24 24-10.7 24-24 24z"  ></path><path d="M288 474h448c8.8 0 16-7.2 16-16V282c0-8.8-7.2-16-16-16H288c-8.8 0-16 7.2-16 16v176c0 8.8 7.2 16 16 16z m56-136h336v64H344v-64zM288 758h448c8.8 0 16-7.2 16-16V566c0-8.8-7.2-16-16-16H288c-8.8 0-16 7.2-16 16v176c0 8.8 7.2 16 16 16z m56-136h336v64H344v-64z"  ></path></symbol><symbol id="iconungroup" viewBox="0 0 1024 1024"><path d="M736 550H288c-8.8 0-16 7.2-16 16v176c0 8.8 7.2 16 16 16h448c8.8 0 16-7.2 16-16V566c0-8.8-7.2-16-16-16z m-56 136H344v-64h336v64zM888 816c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z m0 96c-13.3 0-24-10.7-24-24s10.7-24 24-24 24 10.7 24 24-10.7 24-24 24zM736 266H288c-8.8 0-16 7.2-16 16v176c0 8.8 7.2 16 16 16h448c8.8 0 16-7.2 16-16V282c0-8.8-7.2-16-16-16z m-56 136H344v-64h336v64zM888 208c39.8 0 72-32.2 72-72s-32.2-72-72-72-72 32.2-72 72 32.2 72 72 72z m0-96c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zM136 64c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z m0 96c-13.3 0-24-10.7-24-24s10.7-24 24-24 24 10.7 24 24-10.7 24-24 24zM136 816c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z m0 96c-13.3 0-24-10.7-24-24s10.7-24 24-24 24 10.7 24 24-10.7 24-24 24z"  ></path></symbol></svg>',l=(c=document.getElementsByTagName("script"))[c.length-1].getAttribute("data-injectcss");if(l&&!v.__iconfont__svg__cssinject__){v.__iconfont__svg__cssinject__=!0;try{document.write("<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>")}catch(c){console&&console.log(c)}}!function(c){if(document.addEventListener)if(~["complete","loaded","interactive"].indexOf(document.readyState))setTimeout(c,0);else{var l=function(){document.removeEventListener("DOMContentLoaded",l,!1),c()};document.addEventListener("DOMContentLoaded",l,!1)}else document.attachEvent&&(o=c,e=v.document,z=!1,(h=function(){try{e.documentElement.doScroll("left")}catch(c){return void setTimeout(h,50)}t()})(),e.onreadystatechange=function(){"complete"==e.readyState&&(e.onreadystatechange=null,t())});function t(){z||(z=!0,o())}var o,e,z,h}(function(){var c,l,t,o,e,z;(c=document.createElement("div")).innerHTML=h,h=null,(l=c.getElementsByTagName("svg")[0])&&(l.setAttribute("aria-hidden","true"),l.style.position="absolute",l.style.width=0,l.style.height=0,l.style.overflow="hidden",t=l,(o=document.body).firstChild?(e=t,(z=o.firstChild).parentNode.insertBefore(e,z)):o.appendChild(t))})}(window);
diff --git a/Source/plt-web/plt-web-ui/src/page/index/logo.vue b/Source/plt-web/plt-web-ui/src/page/index/logo.vue
index 4553c2e..cedb042 100644
--- a/Source/plt-web/plt-web-ui/src/page/index/logo.vue
+++ b/Source/plt-web/plt-web-ui/src/page/index/logo.vue
@@ -4,7 +4,7 @@
       <span v-if="keyCollapse"
             class="avue-logo_subtitle"
             key="0">
-        {{ website.logo }}
+       <img class="imgTop" :src=imgurl>
       </span>
     </transition>
     <transition-group name="fade">
@@ -94,4 +94,9 @@
   top: 15px;
   left: 37px;
 }
+.imgTop{
+  position: absolute;
+  top: 15px;
+  left: 12px;
+}
 </style>
diff --git a/Source/plt-web/plt-web-ui/src/router/router.js b/Source/plt-web/plt-web-ui/src/router/router.js
index 798a1b0..a2240de 100644
--- a/Source/plt-web/plt-web-ui/src/router/router.js
+++ b/Source/plt-web/plt-web-ui/src/router/router.js
@@ -16,7 +16,7 @@
 Vue.use(VueRouter)
 //鍒涘缓璺敱
 export const createRouter = () => new VueRouter({
-  mode:"history", //淇敼涓� history 妯″紡 榛樿涓嶅甫#鍙�
+  mode:"hash", //淇敼涓� history 妯″紡 榛樿涓嶅甫#鍙�
   routes: [...PageRouter, ...ViewsRouter],
 })
 const Router = createRouter() // 鑾峰緱 route 瀹炰緥
diff --git a/Source/plt-web/plt-web-ui/src/store/index.js b/Source/plt-web/plt-web-ui/src/store/index.js
index 805b864..bb38457 100644
--- a/Source/plt-web/plt-web-ui/src/store/index.js
+++ b/Source/plt-web/plt-web-ui/src/store/index.js
@@ -6,6 +6,7 @@
 import logs from './modules/logs'
 import dict from './modules/dict'
 import getters from './getters'
+import flow from './modules/LifeFlow'
 
 Vue.use(Vuex)
 const store = new Vuex.Store({
@@ -14,7 +15,8 @@
     common,
     logs,
     tags,
-    dict
+    dict,
+    flow
   },
   getters,
 })
diff --git a/Source/plt-web/plt-web-ui/src/store/modules/LifeFlow.js b/Source/plt-web/plt-web-ui/src/store/modules/LifeFlow.js
new file mode 100644
index 0000000..10ca382
--- /dev/null
+++ b/Source/plt-web/plt-web-ui/src/store/modules/LifeFlow.js
@@ -0,0 +1,38 @@
+import {setStore, getStore} from '@/util/store'
+import user from "@/store/modules/user";
+
+const flow = {
+  state: {
+    methodBtn: false,
+    editMethodBtn:false,
+    type:"",
+  },
+  mutations: {
+    setMethodBtn(state, value) {
+      state.methodBtn = value;
+    },
+
+    setEditMethodBtn(state, value) {
+      state.methodBtn = value;
+    },
+
+    setTypeChange(state,value){
+      state.type = value;
+    }
+  },
+  actions: {
+    // 鏇存柊淇濆瓨 鍙栨秷鎸夐挳
+    updateMethodBtn({commit}, value) {
+      commit('setMethodBtn', value);
+    },
+
+    editNodesStatus({commit}, value){
+      commit('setEditMethodBtn', value);
+    },
+
+    typeChange({commit}, value){
+      commit('setTypeChange', value);
+    }
+  }
+}
+export default flow
diff --git a/Source/plt-web/plt-web-ui/src/util/func.js b/Source/plt-web/plt-web-ui/src/util/func.js
index 32bf2bd..03c02d3 100644
--- a/Source/plt-web/plt-web-ui/src/util/func.js
+++ b/Source/plt-web/plt-web-ui/src/util/func.js
@@ -4,6 +4,29 @@
 import CryptoJS from 'crypto-js'
 
 export default class func {
+
+  /**
+   * 鍗曢�夎〃鏍艰
+   * row 褰撳墠琛屾暟鎹�
+   * CrudRef 琛ㄦ牸ref缁戝畾鍊�
+   * lastIndex 鍒ゆ柇浜屾鐐瑰嚮index鏄惁鍜岀涓�娆$偣鍑讳竴鑷�
+   * setLastIndex 鏇存柊lastIndex鍊�
+   * setSelectList 灏嗕笅鎷夋淇濆瓨鏁扮粍缃┖
+   */
+
+  static rowClickHandler(row, CrudRef, lastIndex, setLastIndex, setSelectList) {
+    if (lastIndex === row.$index) {
+      setSelectList();
+      CrudRef.clearSelection();
+    } else {
+      setSelectList();
+      CrudRef.clearSelection();
+      CrudRef.toggleRowSelection(row);
+    }
+
+    setLastIndex(row.$index);
+  }
+
   /**
    * 涓嶄负绌�
    * @param val
diff --git a/Source/plt-web/plt-web-ui/src/views/authority/function/fuctionView/index.vue b/Source/plt-web/plt-web-ui/src/views/authority/function/fuctionView/index.vue
new file mode 100644
index 0000000..308c333
--- /dev/null
+++ b/Source/plt-web/plt-web-ui/src/views/authority/function/fuctionView/index.vue
@@ -0,0 +1,92 @@
+<template>
+  <el-container>
+
+    <el-aside>
+      <basic-container>
+        <div ref="TreeBox" style="height: calc(100vh - 144px);!important;">
+          <div class="headerCon">
+            <el-button icon="el-icon-plus" plain size="small" type="primary" @click="addClickHandler">鍒涘缓
+            </el-button>
+            <el-button icon="el-icon-edit" plain size="small" type="primary" @click="editClickHandler">淇敼
+            </el-button>
+            <el-button icon="el-icon-delete" plain size="small" type="danger" @click="delClickHandler">鍒犻櫎
+            </el-button>
+            <el-button icon="el-icon-download" plain size="small" type="primary" @click="exportClickHandler">瀵煎嚭
+            </el-button>
+            <el-button icon="el-icon-upload2" plain size="small" type="primary" @click="uploadClickHandler">瀵煎叆
+            </el-button>
+            <el-button class="smallBtn" plain size="small" type="primary"
+                       @click="checkViewClickHandler">鏌ョ湅浣跨敤鑼冨洿
+            </el-button>
+          </div>
+          <!-- 宸︿晶鏍�         -->
+          <div style="height:  calc(100vh - 280px);">
+            <avue-tree :data="treeData" :option="treeOption" @node-click="nodeClick">
+          <span slot-scope="{ node, data }" class="el-tree-node__label">
+           <span style="font-size: 15px">
+              <i class="el-icon-s-promotion"></i>
+                {{ (node || {}).label }}
+            </span>
+          </span>
+            </avue-tree>
+          </div>
+        </div>
+      </basic-container>
+    </el-aside>
+
+    <el-main>
+      <basic-container>
+      </basic-container>
+    </el-main>
+
+  </el-container>
+</template>
+
+<script>
+export default {
+  name: "index"
+}
+</script>
+
+<style lang="scss" scoped>
+::v-deep {
+  .el-scrollbar__wrap {
+    overflow: auto !important;
+  }
+  .headerCon{
+    .el-button{
+      width: 82px;
+    }
+  }
+}
+
+.headerCon {
+  display: flex;
+  flex-wrap: wrap;
+  margin-bottom: 5px;
+
+  .el-button + .el-button {
+    margin-left: 5px;
+  }
+
+  .el-button {
+    margin-top: 5px;
+  }
+}
+
+.headerCon > .el-button:nth-child(4) {
+  margin-left: 0;
+}
+
+.headerCon > .el-button:nth-child(7) {
+  margin-left: 0;
+}
+
+
+.smallBtn {
+  width: 82px;
+  text-align: center;
+  padding-left: 4.5px;
+}
+
+</style>
diff --git a/Source/plt-web/plt-web-ui/src/views/authority/secure/classification/index.vue b/Source/plt-web/plt-web-ui/src/views/authority/secure/classification/index.vue
new file mode 100644
index 0000000..308c333
--- /dev/null
+++ b/Source/plt-web/plt-web-ui/src/views/authority/secure/classification/index.vue
@@ -0,0 +1,92 @@
+<template>
+  <el-container>
+
+    <el-aside>
+      <basic-container>
+        <div ref="TreeBox" style="height: calc(100vh - 144px);!important;">
+          <div class="headerCon">
+            <el-button icon="el-icon-plus" plain size="small" type="primary" @click="addClickHandler">鍒涘缓
+            </el-button>
+            <el-button icon="el-icon-edit" plain size="small" type="primary" @click="editClickHandler">淇敼
+            </el-button>
+            <el-button icon="el-icon-delete" plain size="small" type="danger" @click="delClickHandler">鍒犻櫎
+            </el-button>
+            <el-button icon="el-icon-download" plain size="small" type="primary" @click="exportClickHandler">瀵煎嚭
+            </el-button>
+            <el-button icon="el-icon-upload2" plain size="small" type="primary" @click="uploadClickHandler">瀵煎叆
+            </el-button>
+            <el-button class="smallBtn" plain size="small" type="primary"
+                       @click="checkViewClickHandler">鏌ョ湅浣跨敤鑼冨洿
+            </el-button>
+          </div>
+          <!-- 宸︿晶鏍�         -->
+          <div style="height:  calc(100vh - 280px);">
+            <avue-tree :data="treeData" :option="treeOption" @node-click="nodeClick">
+          <span slot-scope="{ node, data }" class="el-tree-node__label">
+           <span style="font-size: 15px">
+              <i class="el-icon-s-promotion"></i>
+                {{ (node || {}).label }}
+            </span>
+          </span>
+            </avue-tree>
+          </div>
+        </div>
+      </basic-container>
+    </el-aside>
+
+    <el-main>
+      <basic-container>
+      </basic-container>
+    </el-main>
+
+  </el-container>
+</template>
+
+<script>
+export default {
+  name: "index"
+}
+</script>
+
+<style lang="scss" scoped>
+::v-deep {
+  .el-scrollbar__wrap {
+    overflow: auto !important;
+  }
+  .headerCon{
+    .el-button{
+      width: 82px;
+    }
+  }
+}
+
+.headerCon {
+  display: flex;
+  flex-wrap: wrap;
+  margin-bottom: 5px;
+
+  .el-button + .el-button {
+    margin-left: 5px;
+  }
+
+  .el-button {
+    margin-top: 5px;
+  }
+}
+
+.headerCon > .el-button:nth-child(4) {
+  margin-left: 0;
+}
+
+.headerCon > .el-button:nth-child(7) {
+  margin-left: 0;
+}
+
+
+.smallBtn {
+  width: 82px;
+  text-align: center;
+  padding-left: 4.5px;
+}
+
+</style>
diff --git a/Source/plt-web/plt-web-ui/src/views/authority/secure/machineClassification/index.vue b/Source/plt-web/plt-web-ui/src/views/authority/secure/machineClassification/index.vue
new file mode 100644
index 0000000..308c333
--- /dev/null
+++ b/Source/plt-web/plt-web-ui/src/views/authority/secure/machineClassification/index.vue
@@ -0,0 +1,92 @@
+<template>
+  <el-container>
+
+    <el-aside>
+      <basic-container>
+        <div ref="TreeBox" style="height: calc(100vh - 144px);!important;">
+          <div class="headerCon">
+            <el-button icon="el-icon-plus" plain size="small" type="primary" @click="addClickHandler">鍒涘缓
+            </el-button>
+            <el-button icon="el-icon-edit" plain size="small" type="primary" @click="editClickHandler">淇敼
+            </el-button>
+            <el-button icon="el-icon-delete" plain size="small" type="danger" @click="delClickHandler">鍒犻櫎
+            </el-button>
+            <el-button icon="el-icon-download" plain size="small" type="primary" @click="exportClickHandler">瀵煎嚭
+            </el-button>
+            <el-button icon="el-icon-upload2" plain size="small" type="primary" @click="uploadClickHandler">瀵煎叆
+            </el-button>
+            <el-button class="smallBtn" plain size="small" type="primary"
+                       @click="checkViewClickHandler">鏌ョ湅浣跨敤鑼冨洿
+            </el-button>
+          </div>
+          <!-- 宸︿晶鏍�         -->
+          <div style="height:  calc(100vh - 280px);">
+            <avue-tree :data="treeData" :option="treeOption" @node-click="nodeClick">
+          <span slot-scope="{ node, data }" class="el-tree-node__label">
+           <span style="font-size: 15px">
+              <i class="el-icon-s-promotion"></i>
+                {{ (node || {}).label }}
+            </span>
+          </span>
+            </avue-tree>
+          </div>
+        </div>
+      </basic-container>
+    </el-aside>
+
+    <el-main>
+      <basic-container>
+      </basic-container>
+    </el-main>
+
+  </el-container>
+</template>
+
+<script>
+export default {
+  name: "index"
+}
+</script>
+
+<style lang="scss" scoped>
+::v-deep {
+  .el-scrollbar__wrap {
+    overflow: auto !important;
+  }
+  .headerCon{
+    .el-button{
+      width: 82px;
+    }
+  }
+}
+
+.headerCon {
+  display: flex;
+  flex-wrap: wrap;
+  margin-bottom: 5px;
+
+  .el-button + .el-button {
+    margin-left: 5px;
+  }
+
+  .el-button {
+    margin-top: 5px;
+  }
+}
+
+.headerCon > .el-button:nth-child(4) {
+  margin-left: 0;
+}
+
+.headerCon > .el-button:nth-child(7) {
+  margin-left: 0;
+}
+
+
+.smallBtn {
+  width: 82px;
+  text-align: center;
+  padding-left: 4.5px;
+}
+
+</style>
diff --git a/Source/plt-web/plt-web-ui/src/views/authority/ui/dataAuthorization/index.vue b/Source/plt-web/plt-web-ui/src/views/authority/ui/dataAuthorization/index.vue
new file mode 100644
index 0000000..308c333
--- /dev/null
+++ b/Source/plt-web/plt-web-ui/src/views/authority/ui/dataAuthorization/index.vue
@@ -0,0 +1,92 @@
+<template>
+  <el-container>
+
+    <el-aside>
+      <basic-container>
+        <div ref="TreeBox" style="height: calc(100vh - 144px);!important;">
+          <div class="headerCon">
+            <el-button icon="el-icon-plus" plain size="small" type="primary" @click="addClickHandler">鍒涘缓
+            </el-button>
+            <el-button icon="el-icon-edit" plain size="small" type="primary" @click="editClickHandler">淇敼
+            </el-button>
+            <el-button icon="el-icon-delete" plain size="small" type="danger" @click="delClickHandler">鍒犻櫎
+            </el-button>
+            <el-button icon="el-icon-download" plain size="small" type="primary" @click="exportClickHandler">瀵煎嚭
+            </el-button>
+            <el-button icon="el-icon-upload2" plain size="small" type="primary" @click="uploadClickHandler">瀵煎叆
+            </el-button>
+            <el-button class="smallBtn" plain size="small" type="primary"
+                       @click="checkViewClickHandler">鏌ョ湅浣跨敤鑼冨洿
+            </el-button>
+          </div>
+          <!-- 宸︿晶鏍�         -->
+          <div style="height:  calc(100vh - 280px);">
+            <avue-tree :data="treeData" :option="treeOption" @node-click="nodeClick">
+          <span slot-scope="{ node, data }" class="el-tree-node__label">
+           <span style="font-size: 15px">
+              <i class="el-icon-s-promotion"></i>
+                {{ (node || {}).label }}
+            </span>
+          </span>
+            </avue-tree>
+          </div>
+        </div>
+      </basic-container>
+    </el-aside>
+
+    <el-main>
+      <basic-container>
+      </basic-container>
+    </el-main>
+
+  </el-container>
+</template>
+
+<script>
+export default {
+  name: "index"
+}
+</script>
+
+<style lang="scss" scoped>
+::v-deep {
+  .el-scrollbar__wrap {
+    overflow: auto !important;
+  }
+  .headerCon{
+    .el-button{
+      width: 82px;
+    }
+  }
+}
+
+.headerCon {
+  display: flex;
+  flex-wrap: wrap;
+  margin-bottom: 5px;
+
+  .el-button + .el-button {
+    margin-left: 5px;
+  }
+
+  .el-button {
+    margin-top: 5px;
+  }
+}
+
+.headerCon > .el-button:nth-child(4) {
+  margin-left: 0;
+}
+
+.headerCon > .el-button:nth-child(7) {
+  margin-left: 0;
+}
+
+
+.smallBtn {
+  width: 82px;
+  text-align: center;
+  padding-left: 4.5px;
+}
+
+</style>
diff --git a/Source/plt-web/plt-web-ui/src/views/authority/ui/typeAction/index.vue b/Source/plt-web/plt-web-ui/src/views/authority/ui/typeAction/index.vue
new file mode 100644
index 0000000..308c333
--- /dev/null
+++ b/Source/plt-web/plt-web-ui/src/views/authority/ui/typeAction/index.vue
@@ -0,0 +1,92 @@
+<template>
+  <el-container>
+
+    <el-aside>
+      <basic-container>
+        <div ref="TreeBox" style="height: calc(100vh - 144px);!important;">
+          <div class="headerCon">
+            <el-button icon="el-icon-plus" plain size="small" type="primary" @click="addClickHandler">鍒涘缓
+            </el-button>
+            <el-button icon="el-icon-edit" plain size="small" type="primary" @click="editClickHandler">淇敼
+            </el-button>
+            <el-button icon="el-icon-delete" plain size="small" type="danger" @click="delClickHandler">鍒犻櫎
+            </el-button>
+            <el-button icon="el-icon-download" plain size="small" type="primary" @click="exportClickHandler">瀵煎嚭
+            </el-button>
+            <el-button icon="el-icon-upload2" plain size="small" type="primary" @click="uploadClickHandler">瀵煎叆
+            </el-button>
+            <el-button class="smallBtn" plain size="small" type="primary"
+                       @click="checkViewClickHandler">鏌ョ湅浣跨敤鑼冨洿
+            </el-button>
+          </div>
+          <!-- 宸︿晶鏍�         -->
+          <div style="height:  calc(100vh - 280px);">
+            <avue-tree :data="treeData" :option="treeOption" @node-click="nodeClick">
+          <span slot-scope="{ node, data }" class="el-tree-node__label">
+           <span style="font-size: 15px">
+              <i class="el-icon-s-promotion"></i>
+                {{ (node || {}).label }}
+            </span>
+          </span>
+            </avue-tree>
+          </div>
+        </div>
+      </basic-container>
+    </el-aside>
+
+    <el-main>
+      <basic-container>
+      </basic-container>
+    </el-main>
+
+  </el-container>
+</template>
+
+<script>
+export default {
+  name: "index"
+}
+</script>
+
+<style lang="scss" scoped>
+::v-deep {
+  .el-scrollbar__wrap {
+    overflow: auto !important;
+  }
+  .headerCon{
+    .el-button{
+      width: 82px;
+    }
+  }
+}
+
+.headerCon {
+  display: flex;
+  flex-wrap: wrap;
+  margin-bottom: 5px;
+
+  .el-button + .el-button {
+    margin-left: 5px;
+  }
+
+  .el-button {
+    margin-top: 5px;
+  }
+}
+
+.headerCon > .el-button:nth-child(4) {
+  margin-left: 0;
+}
+
+.headerCon > .el-button:nth-child(7) {
+  margin-left: 0;
+}
+
+
+.smallBtn {
+  width: 82px;
+  text-align: center;
+  padding-left: 4.5px;
+}
+
+</style>
diff --git a/Source/plt-web/plt-web-ui/src/views/authority/ui/uiAuthorization/index.vue b/Source/plt-web/plt-web-ui/src/views/authority/ui/uiAuthorization/index.vue
new file mode 100644
index 0000000..308c333
--- /dev/null
+++ b/Source/plt-web/plt-web-ui/src/views/authority/ui/uiAuthorization/index.vue
@@ -0,0 +1,92 @@
+<template>
+  <el-container>
+
+    <el-aside>
+      <basic-container>
+        <div ref="TreeBox" style="height: calc(100vh - 144px);!important;">
+          <div class="headerCon">
+            <el-button icon="el-icon-plus" plain size="small" type="primary" @click="addClickHandler">鍒涘缓
+            </el-button>
+            <el-button icon="el-icon-edit" plain size="small" type="primary" @click="editClickHandler">淇敼
+            </el-button>
+            <el-button icon="el-icon-delete" plain size="small" type="danger" @click="delClickHandler">鍒犻櫎
+            </el-button>
+            <el-button icon="el-icon-download" plain size="small" type="primary" @click="exportClickHandler">瀵煎嚭
+            </el-button>
+            <el-button icon="el-icon-upload2" plain size="small" type="primary" @click="uploadClickHandler">瀵煎叆
+            </el-button>
+            <el-button class="smallBtn" plain size="small" type="primary"
+                       @click="checkViewClickHandler">鏌ョ湅浣跨敤鑼冨洿
+            </el-button>
+          </div>
+          <!-- 宸︿晶鏍�         -->
+          <div style="height:  calc(100vh - 280px);">
+            <avue-tree :data="treeData" :option="treeOption" @node-click="nodeClick">
+          <span slot-scope="{ node, data }" class="el-tree-node__label">
+           <span style="font-size: 15px">
+              <i class="el-icon-s-promotion"></i>
+                {{ (node || {}).label }}
+            </span>
+          </span>
+            </avue-tree>
+          </div>
+        </div>
+      </basic-container>
+    </el-aside>
+
+    <el-main>
+      <basic-container>
+      </basic-container>
+    </el-main>
+
+  </el-container>
+</template>
+
+<script>
+export default {
+  name: "index"
+}
+</script>
+
+<style lang="scss" scoped>
+::v-deep {
+  .el-scrollbar__wrap {
+    overflow: auto !important;
+  }
+  .headerCon{
+    .el-button{
+      width: 82px;
+    }
+  }
+}
+
+.headerCon {
+  display: flex;
+  flex-wrap: wrap;
+  margin-bottom: 5px;
+
+  .el-button + .el-button {
+    margin-left: 5px;
+  }
+
+  .el-button {
+    margin-top: 5px;
+  }
+}
+
+.headerCon > .el-button:nth-child(4) {
+  margin-left: 0;
+}
+
+.headerCon > .el-button:nth-child(7) {
+  margin-left: 0;
+}
+
+
+.smallBtn {
+  width: 82px;
+  text-align: center;
+  padding-left: 4.5px;
+}
+
+</style>
diff --git a/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/attributePool/index.vue b/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/attributePool/index.vue
index 4842e75..2fdceb0 100644
--- a/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/attributePool/index.vue
+++ b/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/attributePool/index.vue
@@ -347,13 +347,13 @@
                 </el-form-item>
                 <el-form-item v-if="!form.enumSwitch" label="杩愮畻绗︼細">
                   <div>
-                    <el-button size="mini" @click="operationHandler('>')"> > </el-button>
-                    <el-button size="mini" @click="operationHandler('<')"> < </el-button>
-                    <el-button size="mini" @click="operationHandler('>=')"> >= </el-button>
-                    <el-button size="mini" @click="operationHandler('<=')"> <= </el-button>
-                    <el-button size="mini" @click="operationHandler('=')"> = </el-button>
-                    <el-button size="mini" @click="operationHandler('!=')"> != </el-button>
-                    <el-button size="mini" @click="operationHandler('()')"> () </el-button>
+                    <el-button size="mini" @click="operationHandler('>')"> ></el-button>
+                    <el-button size="mini" @click="operationHandler('<')"> <</el-button>
+                    <el-button size="mini" @click="operationHandler('>=')"> >=</el-button>
+                    <el-button size="mini" @click="operationHandler('<=')"> <=</el-button>
+                    <el-button size="mini" @click="operationHandler('=')"> =</el-button>
+                    <el-button size="mini" @click="operationHandler('!=')"> !=</el-button>
+                    <el-button size="mini" @click="operationHandler('()')"> ()</el-button>
                   </div>
                 </el-form-item>
                 <el-form-item :label="form.enumSwitch ? '褰撳墠鏋氫妇鍊硷細' : '褰撳墠鍊煎煙锛�'" prop="rangeValue">
@@ -371,16 +371,16 @@
                 </el-form-item>
                 <el-form-item label="杩愮畻绗︼細">
                   <div>
-                    <el-button size="mini" @click="operationHandler('>')"> > </el-button>
-                    <el-button size="mini" @click="operationHandler('<')"> < </el-button>
-                    <el-button size="mini" @click="operationHandler('>=')"> >= </el-button>
-                    <el-button size="mini" @click="operationHandler('<=')"> <= </el-button>
-                    <el-button size="mini" @click="operationHandler('=')"> = </el-button>
-                    <el-button size="mini" @click="operationHandler('!=')"> != </el-button>
-                    <el-button size="mini" @click="operationHandler('()')"> () </el-button>
+                    <el-button size="mini" @click="operationHandler('>')"> ></el-button>
+                    <el-button size="mini" @click="operationHandler('<')"> <</el-button>
+                    <el-button size="mini" @click="operationHandler('>=')"> >=</el-button>
+                    <el-button size="mini" @click="operationHandler('<=')"> <=</el-button>
+                    <el-button size="mini" @click="operationHandler('=')"> =</el-button>
+                    <el-button size="mini" @click="operationHandler('!=')"> !=</el-button>
+                    <el-button size="mini" @click="operationHandler('()')"> ()</el-button>
                   </div>
                 </el-form-item>
-                <el-form-item :label="form.enumSwitch ? '褰撳墠鏋氫妇鍊硷細' : '褰撳墠鍊煎煙锛�'"  prop="rangeValue">
+                <el-form-item :label="form.enumSwitch ? '褰撳墠鏋氫妇鍊硷細' : '褰撳墠鍊煎煙锛�'" prop="rangeValue">
                   <textarea v-model="form.rangeValue"
                             style="width: 330px; height: 80px; border: 1px solid #DCDFE6; overflow: auto; text-align: left;resize: none;">
                   </textarea>
@@ -649,6 +649,7 @@
       ],
       upFileType: ['xls', 'xlsx'],
       fileUrl: 'api/attributeController/importAttributes',
+      lastIndex: null
     }
   },
   computed: {
@@ -732,7 +733,13 @@
 
     // 鐐瑰嚮琛�
     rowClickHandler(row) {
-      this.$refs.userCrud.toggleRowSelection(row);
+      func.rowClickHandler(
+        row,
+        this.$refs.userCrud,
+        this.lastIndex,
+        (newIndex) => { this.lastIndex = newIndex; },
+        () => { this.selectList = []; }
+      );
     },
 
     // 鏉℃暟
diff --git a/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/attributePool/option.js b/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/attributePool/option.js
index e2d889d..695bd5a 100644
--- a/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/attributePool/option.js
+++ b/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/attributePool/option.js
@@ -2,21 +2,27 @@
   {
     label: '灞炴�у悕',
     prop: 'id',
-    search:true,
-    sortable:true,
+    search: true,
+    sortable: true,
+  },
+  {
+    label: '鏍囩',
+    prop: 'name',
+    sortable: true,
   },
   {
     label: '绫诲瀷',
     prop: 'attributeDataTypeText',
-    sortable:true,
+    sortable: true,
   },
   {
     label: '榛樿鍊�',
     prop: 'defaultValue',
-    sortable:true,
+    sortable: true,
   },
   {
     label: '鎻忚堪',
     prop: 'description',
+    overHidden:true,
   },
 ];
diff --git a/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/businessType/index.vue b/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/businessType/index.vue
index 53e5dd8..c137fde 100644
--- a/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/businessType/index.vue
+++ b/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/businessType/index.vue
@@ -1,13 +1,283 @@
 <template>
-  <p>涓氬姟绫诲瀷</p>
+  <el-container>
+    <el-aside>
+      <basic-container>
+        <div ref="TreeBox" style="height: calc(100vh - 144px);!important;">
+          <div class="headerCon">
+            <el-button icon="el-icon-plus" plain size="small" type="primary" @click="addClickHandler">鍒涘缓
+            </el-button>
+            <el-button icon="el-icon-edit" plain size="small" type="primary" @click="editClickHandler">淇敼
+            </el-button>
+            <el-button icon="el-icon-delete" plain size="small" type="danger" @click="deleteClickHandler">鍒犻櫎
+            </el-button>
+            <el-button icon="el-icon-download" plain size="small" type="primary" @click="exportClickHandler">瀵煎嚭
+            </el-button>
+            <el-button icon="el-icon-upload2" plain size="small" type="primary" @click="upLoadClickHandler">瀵煎叆
+            </el-button>
+            <el-button class="miniBtn" icon="el-icon-circle-plus-outline" plain size="small"
+                       type="primary" @click="createViewClickHandler">鍒涘缓瑙嗗浘
+            </el-button>
+            <el-button class="miniBtn" icon="el-icon-circle-plus-outline" plain size="small"
+                       type="primary" @click="checkClickHandler">鍒涘缓绱㈠紩
+            </el-button>
+            <el-button icon="el-icon-menu" plain size="small" style="width: 82px;text-align: center;padding-left: 1px"
+                       type="primary" @click="checkClickHandler">涓�鑷存�ф鏌�
+            </el-button>
+            <el-button class="miniBtn" icon="el-icon-delete" plain size="small"
+                       type="danger" @click="checkClickHandler">鍒犻櫎鏁版嵁
+            </el-button>
+            <el-button class="smallBtn" plain size="small"
+                       type="danger" @click="checkClickHandler">鍒犻櫎鍏ㄩ儴绫诲瀷
+            </el-button>
+            <el-button class="smallBtn" plain size="small" type="primary">鏌ョ湅浣跨敤鑼冨洿
+            </el-button>
+          </div>
+          <!-- 宸︿晶鏍� -->
+          <div style="height:  calc(100vh - 330px);">
+            <avue-tree :data="treeData" :option="treeOption" @node-click="nodeClick">
+          <span slot-scope="{ node, data }" class="el-tree-node__label">
+           <span style="font-size: 15px">
+              <i class="el-icon-s-promotion"></i>
+                {{ (node || {}).label }}
+            </span>
+          </span>
+            </avue-tree>
+          </div>
+        </div>
+      </basic-container>
+    </el-aside>
+    <el-main>
+      <basic-container>
+        <div style="display: flex;justify-content: center">
+          <div class="descBox">
+            <el-descriptions  :column="1" border class="margin-top" size="medium" title="灞炴�т俊鎭�">
+              <el-descriptions-item :contentStyle="descriptionOption.contentStyle"
+                                    :labelStyle="descriptionOption.labelStyle">
+                <template slot="label">
+                  <i :class="icons.name"></i>
+                  鍚嶇О
+                </template>
+                <el-tag v-if="nodeRow.name">{{ nodeRow.name }}</el-tag>
+              </el-descriptions-item>
+              <el-descriptions-item :contentStyle="descriptionOption.contentStyle"
+                                    :labelStyle="descriptionOption.labelStyle">
+                <template slot="label">
+                  <i :class="icons.label"></i>
+                  鏍囩
+                </template>
+                <el-tag v-if="nodeRow.label">{{ nodeRow.label }}</el-tag>
+              </el-descriptions-item>
+              <el-descriptions-item :contentStyle="descriptionOption.contentStyle"
+                                    :labelStyle="descriptionOption.labelStyle">
+                <template slot="label">
+                  <i :class="icons.implClass"></i>
+                  瀹炵幇绫�
+                </template>
+                <el-tooltip class="item" effect="dark" :content="nodeRow.implClass" placement="top-start">
+                  <el-tag v-if="nodeRow.implClass">{{ nodeRow.implClass }}</el-tag>
+                </el-tooltip>
+              </el-descriptions-item>
+              <el-descriptions-item :contentStyle="descriptionOption.contentStyle"
+                                    :labelStyle="descriptionOption.labelStyle">
+                <template slot="label">
+                  <i :class="icons.desc"></i>
+                  鎻忚堪
+                </template>
+                <el-tag v-if="nodeRow.description">{{ nodeRow.description }}</el-tag>
+              </el-descriptions-item>
+            </el-descriptions>
+          </div>
+          <div class="descBox">
+            <el-descriptions  :column="1" border class="margin-top" size="medium" title="灞炴�т俊鎭�">
+              <el-descriptions-item :contentStyle="descriptionOption.contentStyle"
+                                    :labelStyle="descriptionOption.labelStyle">
+                <template slot="label">
+                  <i :class="icons.name"></i>
+                  鍚嶇О
+                </template>
+                <el-tag v-if="nodeRow.name">{{ nodeRow.name }}</el-tag>
+              </el-descriptions-item>
+              <el-descriptions-item :contentStyle="descriptionOption.contentStyle"
+                                    :labelStyle="descriptionOption.labelStyle">
+                <template slot="label">
+                  <i :class="icons.label"></i>
+                  鏍囩
+                </template>
+                <el-tag v-if="nodeRow.label">{{ nodeRow.label }}</el-tag>
+              </el-descriptions-item>
+              <el-descriptions-item :contentStyle="descriptionOption.contentStyle"
+                                    :labelStyle="descriptionOption.labelStyle">
+                <template slot="label">
+                  <i :class="icons.implClass"></i>
+                  瀹炵幇绫�
+                </template>
+                <el-tag v-if="nodeRow.implClass">{{ nodeRow.implClass }}</el-tag>
+              </el-descriptions-item>
+              <el-descriptions-item :contentStyle="descriptionOption.contentStyle"
+                                    :labelStyle="descriptionOption.labelStyle">
+                <template slot="label">
+                  <i :class="icons.desc"></i>
+                  鎻忚堪
+                </template>
+                <el-tag v-if="nodeRow.description">{{ nodeRow.description }}</el-tag>
+              </el-descriptions-item>
+            </el-descriptions>
+          </div>
+          <div class="descBox">
+            <el-descriptions  :column="1" border class="margin-top" size="medium" title="灞炴�т俊鎭�">
+              <el-descriptions-item :contentStyle="descriptionOption.contentStyle"
+                                    :labelStyle="descriptionOption.labelStyle">
+                <template slot="label">
+                  <i :class="icons.name"></i>
+                  鍚嶇О
+                </template>
+                <el-tag v-if="nodeRow.name">{{ nodeRow.name }}</el-tag>
+              </el-descriptions-item>
+              <el-descriptions-item :contentStyle="descriptionOption.contentStyle"
+                                    :labelStyle="descriptionOption.labelStyle">
+                <template slot="label">
+                  <i :class="icons.label"></i>
+                  鏍囩
+                </template>
+                <el-tag v-if="nodeRow.label">{{ nodeRow.label }}</el-tag>
+              </el-descriptions-item>
+              <el-descriptions-item :contentStyle="descriptionOption.contentStyle"
+                                    :labelStyle="descriptionOption.labelStyle">
+                <template slot="label">
+                  <i :class="icons.implClass"></i>
+                  瀹炵幇绫�
+                </template>
+                <el-tag v-if="nodeRow.implClass">{{ nodeRow.implClass }}</el-tag>
+              </el-descriptions-item>
+              <el-descriptions-item :contentStyle="descriptionOption.contentStyle"
+                                    :labelStyle="descriptionOption.labelStyle">
+                <template slot="label">
+                  <i :class="icons.desc"></i>
+                  鎻忚堪
+                </template>
+                <el-tag v-if="nodeRow.description">{{ nodeRow.description }}</el-tag>
+              </el-descriptions-item>
+            </el-descriptions>
+          </div>
+        </div>
+
+      </basic-container>
+    </el-main>
+  </el-container>
 </template>
 
 <script>
+import {getBizTypes} from "@/api/modeling/businessType/api"
+
 export default {
-  name: "index"
+  name: "index",
+  data() {
+    return {
+      form:{
+
+      },
+      nodeRow:{},
+      treeOption: {
+        height: 'auto',
+        defaultExpandAll: false,
+        menu: false,
+        addBtn: false,
+        props: {
+          label: 'name',
+          value: 'name',
+          children: 'children'
+        }
+      },
+      treeData: [],
+      descriptionOption: {
+        labelStyle: 'text-align:center;min-width:80px;',
+        contentStyle: 'width:200px;text-align:center;word-break;break-all;'
+      },
+      icons: {
+        id: 'el-icon-finished',
+        name: 'el-icon-tickets',
+        desc: 'el-icon-chat-line-square'
+      },
+    }
+  },
+  created() {
+    this.getTreeList();
+  },
+  methods: {
+    getTreeList() {
+      getBizTypes().then(res => {
+        const data = res.data.data.map(item => {
+          return item.attributes;
+        });
+        this.treeData = data;
+      })
+    },
+
+    // 鏍戠偣鍑�
+    nodeClick(row){
+      console.log(row);
+      this.nodeRow = row;
+    },
+  }
 }
 </script>
 
-<style scoped>
+<style lang="scss" scoped>
+::v-deep {
+  .el-scrollbar__wrap {
+    overflow: auto !important;
+  }
 
+  .el-form-item .el-select {
+    width: 100%;
+  }
+
+  .headerCon {
+    .el-button {
+      width: 82px;
+    }
+  }
+}
+
+.headerCon {
+  display: flex;
+  flex-wrap: wrap;
+  margin-bottom: 5px;
+
+  .el-button + .el-button {
+    margin-left: 5px;
+  }
+
+  .el-button {
+    margin-top: 5px;
+  }
+}
+
+.headerCon > .el-button:nth-child(4) {
+  margin-left: 0;
+}
+
+.headerCon > .el-button:nth-child(7) {
+  margin-left: 0;
+}
+
+.headerCon > .el-button:nth-child(10) {
+  margin-left: 0;
+}
+
+.miniBtn {
+  width: 82px;
+  text-align: center;
+  padding-left: 7px;
+}
+
+.smallBtn {
+  width: 82px;
+  text-align: center;
+  padding-left: 4.5px;
+}
+.descBox{
+  width: 32%;
+  margin-left: 20px;
+}
 </style>
diff --git a/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/enumType/index.vue b/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/enumType/index.vue
index 3908720..48f06c3 100644
--- a/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/enumType/index.vue
+++ b/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/enumType/index.vue
@@ -320,7 +320,8 @@
       },
       tableLoading: false,
       selectList: [],
-      searchParams: {}
+      searchParams: {},
+      lastIndex: null
     }
   },
   computed: {
@@ -366,13 +367,18 @@
 
     // 閫夋嫨妗�
     selectChange(row) {
-      console.log(row)
       this.selectList = row;
     },
 
     // 鐐瑰嚮琛�
     rowClickHandler(row) {
-      this.$refs.userCrud.toggleRowSelection(row);
+      func.rowClickHandler(
+        row,
+        this.$refs.userCrud,
+        this.lastIndex,
+        (newIndex) => { this.lastIndex = newIndex; },
+        () => { this.selectList = []; }
+      );
     },
 
     // 鍏抽棴瀵硅瘽妗�
diff --git a/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/lifeCycle/index.vue b/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/lifeCycle/index.vue
index d3ee2bc..719c75d 100644
--- a/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/lifeCycle/index.vue
+++ b/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/lifeCycle/index.vue
@@ -1,13 +1,458 @@
 <template>
-  <p>鐢熷懡鍛ㄦ湡</p>
+  <el-container>
+    <el-aside width="15.7%">
+      <basic-container>
+        <div ref="TreeBox" style="height: calc(100vh - 144px);!important;">
+          <div class="headerCon">
+            <el-button icon="el-icon-plus" plain size="small" type="primary" @click="addClickHandler">鍒涘缓
+            </el-button>
+            <el-button icon="el-icon-edit" plain size="small" type="primary" @click="editClickHandler">淇敼
+            </el-button>
+            <el-button icon="el-icon-delete" plain size="small" type="danger" @click="delClickHandler">鍒犻櫎
+            </el-button>
+            <el-button icon="el-icon-download" plain size="small" type="primary" @click="exportClickHandler">瀵煎嚭
+            </el-button>
+            <el-button icon="el-icon-upload2" plain size="small" type="primary" @click="uploadClickHandler">瀵煎叆
+            </el-button>
+            <el-button class="smallBtn" plain size="small" type="primary"
+                       @click="checkViewClickHandler">鏌ョ湅浣跨敤鑼冨洿
+            </el-button>
+          </div>
+          <!-- 宸︿晶鏍� -->
+          <div style="height:  calc(100vh - 300px);">
+            <avue-tree ref="tree" :data="treeData" :option="treeOption" @node-click="nodeClick">
+          <span slot-scope="{ node, data }" class="el-tree-node__label">
+           <span style="font-size: 15px">
+              <i class="el-icon-s-promotion"></i>
+                {{ (node || {}).label }}
+            </span>
+          </span>
+            </avue-tree>
+          </div>
+        </div>
+      </basic-container>
+    </el-aside>
+    <el-main>
+      <basic-container>
+        <CycleFlow
+          :key="Reload"
+          ref="vueFlowchartEditor"
+          :chart-data="nodesEdgesData"
+          :chart-data-node-items="flowChartNodeItems"
+          :rowData="rowData"
+          :type="type"
+          class="cycle_flow"
+          @save-data="save"
+          @reset-tree="handleResetTree"
+          @handler-save="handlerSave"
+        />
+      </basic-container>
+    </el-main>
+    <upload-file ref="upload" :fileType="upFileType" :fileUrl="fileUrl" :tipList="tipList" title="瀵煎叆"
+                 @updata="getTableList"></upload-file>
+
+    <el-dialog
+      v-dialogDrag
+      v-loading="checkViewLoading"
+      :visible.sync="checkViewVisible"
+      append-to-body="true"
+      class="avue-dialog"
+      title="鏌ョ湅浣跨敤鑼冨洿"
+      width="60%"
+    >
+      <avue-crud
+        ref="checkViewCrud"
+        :data="checkViewData"
+        :option="checkViewOption"
+        @search-change="checkHandleSearch"
+        @search-reset="checkHandleReset"
+      >
+
+      </avue-crud>
+    </el-dialog>
+  </el-container>
 </template>
 
 <script>
+import {
+  gridLifeCycle,
+  getLCEventKeys,
+  addLifeCycle,
+  updateLifeCycle,
+  deleteLifeCycles,
+  exportLifeCycles,
+  getUsedLifeCycleList
+} from '@/api/modeling/lifeCycle/api';
+import {gridStatus} from '@/api/modeling/statusPool/api'
+import CycleFlow from "@/components/flow-cycle/flowchartEditor.vue";
+import func from "@/util/func";
+import basicOption from "@/util/basic-option";
+
 export default {
-  name: "index"
+  name: "index",
+  components: {CycleFlow},
+  data() {
+    return {
+      checkViewOption: {
+        ...basicOption,
+        addBtn: false,
+        menu: false,
+        searchMenuSpan: 8,
+        refreshBtn: false,
+        selection: false,
+        column: [
+          {
+            label: '鍚嶇О',
+            prop: 'lifeCycleName',
+            sortable: true,
+          },
+          {
+            label: '鏉ユ簮',
+            prop: 'source',
+            sortable: true,
+            search: true
+          },
+          {
+            label: '璇存槑',
+            prop: 'desc',
+          }
+        ]
+      },
+      checkViewData: [],
+      checkViewDataSearch: [],
+      checkViewVisible: false,
+      checkViewLoading: false,
+      tipList: [
+        "鍚嶇О銆佹爣绛俱�佽捣濮嬬姸鎬佷笉鑳戒负绌猴紝涓斿悕绉板彧鑳戒负鑻辨枃瀛楃",
+        "娉ㄦ剰閰嶇疆杩炴帴绾胯捣濮嬬姸鎬佷互鍙婄洰鏍囩姸鎬佸悕绉�",
+      ],
+      upFileType: ['xls', 'xlsx'],
+      fileUrl: 'api/lifeCycleController/importLifeCycles',
+      eventList: [],
+      Reload: Math.random(),
+      flowKey: null,
+      visible: false,
+      type: 'edit',
+      nodesEdgesData: {},
+      flowChartNodeItems: [], // 娴佺▼鑺傜偣鏁版嵁
+      rowData: {},
+      treeData: [],
+      treeOption: {
+        height: 'auto',
+        defaultExpandAll: false,
+        menu: false,
+        addBtn: false,
+        props: {
+          label: 'id',
+          value: 'id',
+          children: 'children'
+        }
+      },
+    }
+  },
+  created() {
+    this.createdHandler();
+  },
+  methods: {
+    // 宸︿晶鏍戞煡璇�
+    getTreeList() {
+      gridLifeCycle().then(res => {
+        const data = res.data.data;
+        this.treeData = data;
+      }).catch(err => {
+        this.$message.error(err)
+      });
+    },
+
+    // 鐢熷懡鍛ㄦ湡鐘舵�佹煡璇�
+    getStatusList() {
+      gridStatus().then(res => {
+        const data = res.data.data.map(item => {
+          return {
+            id: item.id,
+            name: item.name
+          }
+        })
+        this.flowChartNodeItems = data;
+      }).catch(err => {
+        this.$message.error(err)
+      });
+    },
+
+    // 璺冭縼浜嬩欢鏌ヨ
+    getEventsSelect() {
+      getLCEventKeys().then(res => {
+        const data = res.data.data;
+        this.eventList = data;
+      }).catch(err => {
+        this.$message.error(err)
+      });
+    },
+
+    // 鍒锋柊鏁翠釜椤甸潰鏁版嵁
+    createdHandler() {
+      this.getTreeList(); // 鏍戞煡璇�
+      this.getStatusList(); // tag鐘舵�佹睜鏌ヨ
+      this.getEventsSelect(); // 璺冭縼浜嬩欢鏌ヨ
+    },
+
+    // 琛岀偣鍑�
+    nodeClick(row) {
+      console.log(row);
+      this.nodesEdgesData = {
+        nodes: this.transformNodeData(row.bounds),
+        edges: this.transformEdgeData(row.lines)
+      };
+      this.rowData = {...row, eventList: {...this.eventList}};
+      this.$store.dispatch('updateMethodBtn', false);
+      this.Reload = Math.random(); // 鍒锋柊flow鍥捐〃
+    },
+
+    // node鑺傜偣鏁版嵁杞崲
+    transformNodeData(nodes) {
+      return nodes.map(item => ({
+        ...item,
+        label: item.name,
+        id: item.name,
+        color: '#1890FF',
+        shape: "flow-rect",
+        x: Number(item.cellx),
+        y: Number(item.celly),
+        width: Number(item.cellw),
+        height: Number(item.cellh)
+      }));
+    },
+
+    // line杩炴帴绾挎暟鎹浆鎹�
+    transformEdgeData(edges) {
+      return edges.map(item => ({
+        ...item,
+        events: item.events.map(item => item.oid), // 璺冭縼浜嬩欢涓嬫媺妗嗙粦瀹氾紝鍦‵lowchartEditor缁勪欢onAfterItemSelected鏂规硶閲屾煡鎵惧埌瀵瑰簲杩炴帴绾跨殑淇℃伅
+        label: item.name, // 鐢ㄤ簬鍙充晶璇︾粏淇℃伅鍚嶇О
+        source: item.sourceLifeStatus,
+        target: item.targetLifeStatus
+      }));
+    },
+
+    // 鍒涘缓鎸夐挳
+    addClickHandler() {
+      this.$store.dispatch('updateMethodBtn', true);
+      this.handleResetTree();
+      this.$store.dispatch('typeChange', 'add');
+    },
+
+    // 淇敼鎸夐挳
+    editClickHandler() {
+      if (func.isEmptyObject(this.rowData)) {
+        this.$message.error('璇疯嚦灏戦�夋嫨涓�鏉℃暟鎹�');
+        return;
+      }
+      this.$store.dispatch('updateMethodBtn', Object.keys(this.rowData).length > 0);
+      this.$store.dispatch('editNodesStatus', true);
+      this.$store.dispatch('typeChange', 'edit');
+    },
+
+    // 鍒犻櫎鎸夐挳
+    delClickHandler() {
+      if (func.isEmptyObject(this.rowData)) {
+        this.$message.error('璇疯嚦灏戦�夋嫨涓�鏉℃暟鎹�');
+        return;
+      }
+      const {id, oid, ts} = this.rowData;
+
+      const data = [{id, oid, ts}];
+      deleteLifeCycles(data).then(res => {
+        if (res.data.code === 200) {
+          this.$message.success(res.data.obj);
+          this.handleResetTree();
+          this.createdHandler();
+          this.$store.dispatch('updateMethodBtn', Object.keys(this.rowData).length > 0);
+        }
+      });
+    },
+
+    // 瀵煎嚭鎸夐挳
+    exportClickHandler(){
+      if (func.isEmptyObject(this.rowData)) {
+        this.$message.error('璇疯嚦灏戦�夋嫨涓�鏉℃暟鎹�');
+        return;
+      }
+      exportLifeCycles({lcNames:this.rowData.id}).then(res => {
+        func.downloadFileByBlobHandler(res);
+        this.$message.success('瀵煎嚭鎴愬姛');
+      }).catch(err => {
+        this.$message.error(err);
+      })
+    },
+
+    // 瀵煎叆鎸夐挳
+    uploadClickHandler(){
+      this.$refs.upload.visible = true;
+    },
+
+    // 鏌ョ湅浣跨敤鑼冨洿鎸夐挳
+    checkViewClickHandler(){
+      if (func.isEmptyObject(this.rowData)) {
+        this.$message.error('璇疯嚦灏戦�夋嫨涓�鏉℃暟鎹�');
+        return;
+      }
+
+      getUsedLifeCycleList({lifeCycleName:this.rowData.id}).then(res => {
+        if (res.data.code === 200) {
+          this.checkViewVisible = true;
+          this.checkViewData = res.data.data;
+          this.checkViewDataSearch = res.data.data;
+        }
+      })
+    },
+
+    // 鏌ョ湅浣跨敤鑼冨洿鏌ヨ
+    checkHandleSearch(params, done) {
+      const {source} = params;
+
+      if (!params.source) {
+        this.checkViewData = this.checkViewDataSearch;
+        return done();
+      }
+      ;
+
+      this.checkViewData = this.checkViewData.filter(item => {
+        return item.source && item.source.includes(source);
+      });
+
+      done();
+
+    },
+
+    // 鏌ョ湅浣跨敤鑼冨洿閲嶇疆
+    checkHandleReset() {
+      this.checkViewData = this.checkViewDataSearch;
+    },
+
+    // 瀛愮粍浠跺洖璋冧繚瀛�
+    async handlerSave() {
+      const newRowData = await this.$refs.vueFlowchartEditor.getNewRowData();
+      if (!newRowData) {
+        return;
+      }
+
+      const flowData = await this.$refs.vueFlowchartEditor.getFlowData() || {};
+
+      const nodes = flowData.nodes || [];
+      const edges = flowData.edges || [];
+
+      // 妫�鏌ユ槸鍚︾粯鍒朵簡鑷冲皯涓�涓浘褰�
+      if (nodes.length <= 0) {
+        this.$message.error('璇疯嚦灏戠粯鍒朵竴涓浘褰紒');
+        return;
+      }
+
+      // 妫�鏌ユ槸鍚︾粯鍒朵簡杩炴帴绾�
+      if (nodes.length > 1 && !edges.length) {
+        this.$message.error('璇锋鏌ユ槸鍚︾粯鍒惰繛鎺ョ嚎锛�');
+        return;
+      }
+
+      // 妫�鏌ユ墍鏈夎繛鎺ョ嚎鐨勫悕绉版槸鍚﹀~鍐�
+      const hasValidLabels = edges.every(item => item.label && item.label.trim() !== "");
+      if (!hasValidLabels) {
+        this.$message.error('璇锋鏌ユ槸鍚︽湁杩炴帴绾垮悕绉版湭濉啓锛�');
+        return;
+      }
+
+      // 妫�鏌ユ槸鍚︽湁閬楁紡鐨勮繛鎺ョ嚎
+      if (edges.length + 1 < nodes.length) {
+        this.$message.error('璇锋鏌ユ槸鍚﹀叏閮ㄧ粯鍒惰繛鎺ョ嚎锛�');
+        return;
+      }
+
+
+      let params = {...newRowData, ...flowData};
+      const transformedData = {
+        id: params.id,
+        name: params.name,
+        startStatus: params.startStatus,
+        startStatusName: params.startStatusName,
+        description: params.description,
+        bounds: params.nodes.map(node => ({
+          name: node.id,
+          cellx: String(node.x),
+          celly: String(node.y),
+          cellw: String(node.width),
+          cellh: String(node.height),
+        })),
+        lines: !params.edges ? [] : params.edges.map(edge => ({
+          sourceLifeStatus: edge.source,
+          targetLifeStatus: edge.target,
+          saveEventList: edge.saveEventList,
+          name: edge.label
+        }))
+      };
+      const getFunction = Object.keys(this.rowData).length > 0 ? () => updateLifeCycle(transformedData)
+        : () => addLifeCycle(transformedData);
+
+      getFunction().then(res => {
+        if (res.data.code === 200) {
+          this.$message.success(res.data.obj);
+          this.createdHandler();
+          // this.handleResetTree();
+          this.$store.dispatch('updateMethodBtn', Object.keys(this.rowData).length > 0);
+        }
+      });
+    },
+
+    // 閲嶇疆鏍戝拰鍥捐〃
+    handleResetTree() {
+      this.$refs.tree.setCurrentKey(null);
+      this.rowData = {};
+      this.nodesEdgesData = {};
+      this.Reload = Math.random();
+    }
+  }
 }
 </script>
 
-<style scoped>
+<style lang="scss" scoped>
+::v-deep {
+  .el-scrollbar__wrap {
+    overflow: auto !important;
+  }
+  .headerCon{
+    .el-button {
+      width: 65px;
+      padding-left: 9.5px;
+    }
+  }
+}
+
+.headerCon {
+  display: flex;
+  flex-wrap: wrap;
+  margin-bottom: 5px;
+
+  .el-button + .el-button {
+    margin-left: 5px;
+  }
+
+  .el-button {
+    margin-top: 5px;
+  }
+}
+
+.headerCon > .el-button:nth-child(4) {
+  margin-left: 0;
+}
+
+//.headerCon > .el-button:nth-child(6) {
+//  margin-left: 0;
+//}
+
+.smallBtn {
+  width: 77px !important;
+  //font-size: 11px !important;
+  text-align: center  !important;
+  padding-left: 1px  !important;
+}
 
 </style>
+
diff --git a/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/linkType/index.vue b/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/linkType/index.vue
index c1a4f57..706fd41 100644
--- a/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/linkType/index.vue
+++ b/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/linkType/index.vue
@@ -6,24 +6,25 @@
           <div class="headerCon">
             <el-button icon="el-icon-plus" plain size="small" type="primary" @click="addClickHandler">鍒涘缓
             </el-button>
-            <el-button icon="el-icon-edit" plain size="small" type="primary">淇敼
+            <el-button icon="el-icon-edit" plain size="small" type="primary" @click="editClickHandler">淇敼
             </el-button>
-            <el-button icon="el-icon-delete" plain size="small" type="danger">鍒犻櫎
+            <el-button icon="el-icon-delete" plain size="small" type="danger" @click="deleteClickHandler">鍒犻櫎
             </el-button>
             <el-button icon="el-icon-view" plain size="small" type="primary">鏌ョ湅
             </el-button>
-            <el-button icon="el-icon-download" plain size="small" type="primary">瀵煎嚭
+            <el-button icon="el-icon-download" plain size="small" type="primary" @click="exportClickHandler">瀵煎嚭
             </el-button>
-            <el-button icon="el-icon-upload2" plain size="small" type="primary">瀵煎叆
+            <el-button icon="el-icon-upload2" plain size="small" type="primary" @click="upLoadClickHandler">瀵煎叆
             </el-button>
-            <el-button icon="el-icon-circle-plus-outline" plain size="small"
+            <el-button class="smallBtn" icon="el-icon-circle-plus-outline" plain size="small"
+                       style="padding-left: 7px !important;"
                        type="primary" @click="createViewClickHandler">鍒涘缓瑙嗗浘
             </el-button>
-            <el-button icon="el-icon-menu" plain size="small"
+            <el-button class="smallBtn" icon="el-icon-menu" plain size="small" style="padding-left: 1px"
                        type="primary" @click="checkClickHandler">涓�鑷存�ф鏌�
             </el-button>
           </div>
-          <!-- 宸︿晶鏍�         -->
+          <!-- 宸︿晶鏍� -->
           <div style="height:  calc(100vh - 300px);">
             <avue-tree :data="treeData" :option="treeOption" @node-click="nodeClick">
           <span slot-scope="{ node, data }" class="el-tree-node__label">
@@ -164,26 +165,27 @@
       </basic-container>
     </el-main>
 
-    <!-- 鍒涘缓 && 缂栬緫   -->
+    <!-- 鍒涘缓 && 缂栬緫 -->
     <el-dialog
       v-dialogDrag
+      :title="title === 'add' ? '鍒涘缓' : '淇敼'"
       :visible.sync="visible"
       append-to-body="true"
       class="avue-dialog"
-      title="鍒涘缓"
       width="70%"
+      @close="addDialogClose"
     >
       <el-form ref="form" :model="form" :rules="rules" label-width="90px">
         <div class="dialogForm">
           <div class="leftForm">
             <el-form-item label="鍚嶇О锛�" prop="name">
-              <el-input v-model="form.name"></el-input>
+              <el-input v-model="form.name" :readOnly="title === 'edit'"></el-input>
             </el-form-item>
             <el-form-item label="鏍囩锛�">
               <el-input v-model="form.tag"></el-input>
             </el-form-item>
             <el-form-item label="瀹炵幇绫伙細">
-              <el-input v-model="form.impClass"></el-input>
+              <el-input v-model="form.implClass"></el-input>
             </el-form-item>
             <el-form-item label="褰㈢姸">
               <el-input v-model="form.shape"></el-input>
@@ -195,7 +197,42 @@
 
           <div class="centerForm">
             <el-form-item label="Form绔被鍨嬶細" label-width="110px">
-              <el-input v-model="form.btmItemsFrom"></el-input>
+              <!--              <el-button v-if="!form.btmItemsFrom" plain size="mini" type="success"-->
+              <!--                         @click="FormItemReferChange('form')">娣诲姞-->
+              <!--              </el-button>-->
+              <!--              <el-input v-if="form.btmItemsFrom" v-model="form.btmItemsFrom"></el-input>-->
+              <div style="display: flex; align-items: center">
+                <div style="height: 200px; width: 280px; border: 1px solid #bdbbbb;overflow-y: auto">
+                  <!-- 鍐呭 -->
+                  <el-table
+                    :data="bizFormData"
+                    :show-header="false"
+                    style="width: 100%">
+                    <el-table-column
+                      align="center"
+                      prop="name">
+                    </el-table-column>
+                    <el-table-column
+                      fixed="right"
+                      label="鎿嶄綔"
+                      width="60">
+                      <template slot-scope="scope">
+                        <el-button
+                          size="small"
+                          style="color:#F56C6C;"
+                          type="text"
+                          @click.native.prevent="bizTypeDeleteRow('form',scope.$index)">
+                          绉婚櫎
+                        </el-button>
+                      </template>
+                    </el-table-column>
+                  </el-table>
+                </div>
+                <el-button plain size="mini" style="margin-left: 5px" type="success"
+                           @click="FormItemReferChange('form')">娣诲姞
+                </el-button>
+
+              </div>
             </el-form-item>
             <el-form-item label="瀵瑰簲鍏崇郴锛�" label-width="110px">
               <el-select v-model="form.relationFrom">
@@ -204,13 +241,47 @@
               </el-select>
             </el-form-item>
             <el-form-item label="涓荤被鍨嬶細" label-width="110px">
-              <el-input v-model="form.primitivesFrom"></el-input>
+              <el-select v-model="form.primitivesFrom">
+                <el-option v-for="(item,index) in bizFormData" :key="index" :label="item.name"
+                           :value="item.name"></el-option>
+              </el-select>
             </el-form-item>
           </div>
 
           <div class="rightForm">
             <el-form-item label="To绔被鍨嬶細" label-width="110px">
-              <el-input v-model="form.btmItemsTo"></el-input>
+              <div style="display: flex; align-items: center">
+                <div style="height: 200px; width: 280px; border: 1px solid #bdbbbb;overflow-y: auto">
+                  <!-- 鍐呭 -->
+                  <el-table
+                    :data="bizToData"
+                    :show-header="false"
+                    style="width: 100%">
+                    <el-table-column
+                      align="center"
+                      prop="name">
+                    </el-table-column>
+                    <el-table-column
+                      fixed="right"
+                      label="鎿嶄綔"
+                      width="60">
+                      <template slot-scope="scope">
+                        <el-button
+                          size="small"
+                          style="color:#F56C6C;"
+                          type="text"
+                          @click.native.prevent="bizTypeDeleteRow('to',scope.$index)">
+                          绉婚櫎
+                        </el-button>
+                      </template>
+                    </el-table-column>
+                  </el-table>
+                </div>
+                <el-button plain size="mini" style="margin-left: 5px" type="success"
+                           @click="FormItemReferChange('to')">娣诲姞
+                </el-button>
+
+              </div>
             </el-form-item>
             <el-form-item label="瀵瑰簲鍏崇郴锛�" label-width="110px">
               <el-select v-model="form.relationTo">
@@ -219,7 +290,10 @@
               </el-select>
             </el-form-item>
             <el-form-item label="涓荤被鍨嬶細" label-width="110px">
-              <el-input v-model="form.primitivesTo"></el-input>
+              <el-select v-model="form.primitivesTo">
+                <el-option v-for="(item,index) in bizToData" :key="index" :label="item.name"
+                           :value="item.name"></el-option>
+              </el-select>
             </el-form-item>
           </div>
         </div>
@@ -230,6 +304,7 @@
         <avue-crud
           :data="dialogBottomData"
           :option="dialogBottomOption"
+          @row-del="dialogBottomAttrDel"
         >
           <template slot="menuLeft" slot-scope="scope">
             <el-button icon="el-icon-plus" plain size="small" type="primary" @click="dialogAddClickHandler">澧� 鍔�
@@ -288,19 +363,119 @@
         :option="conCheckOption"
         :table-loading="conCheckLoading">
       </avue-crud>
+      <span slot="footer" class="dialog-footer">
+         <el-button @click="conCheckVisible = false">鍙� 娑�</el-button>
+         <el-button type="primary" @click="repairClickHandler">淇� 澶�</el-button>
+        </span>
     </el-dialog>
+
+    <!-- form to 绔被鍨嬪璇濇琛ㄦ牸 -->
+    <el-dialog
+      v-dialogDrag
+      :title="bizTypeTitle === 'form' ? 'Form绔被鍨�' : 'To绔被鍨�'"
+      :visible.sync="bizTypeVisible"
+      append-to-body="true"
+      class="avue-dialog"
+      width="70%"
+    >
+      <avue-crud
+        :key="bizTypeReload"
+        ref="bizTypeCrud"
+        :data="bizTypeData"
+        :option="bizTypeOption"
+        :table-loading="bizTypeLoading"
+        @search-change="bizTypeHandleSearch"
+        @search-reset="bizTypeHandleReset"
+        @selection-change="bizTypeSelection"
+        @row-click="bizTypeRowClick">
+      </avue-crud>
+
+      <span slot="footer" class="dialog-footer">
+         <el-button @click="bizTypeVisible = false">鍙� 娑�</el-button>
+         <el-button type="primary" @click="bizTypeAddHandler">纭� 瀹�</el-button>
+        </span>
+    </el-dialog>
+
+    <!-- 瀵煎叆 -->
+    <upload-file ref="upload" :fileType="upFileType" :fileUrl="fileUrl" :tipList="tipList" title="瀵煎叆"
+                 @updata="getTreeList"></upload-file>
   </el-container>
 </template>
 
 <script>
-import {gridLink, getByAttributeNames, checkLinkType, createView} from "@/api/modeling/linkType/api";
+import {
+  gridLink,
+  getByAttributeNames,
+  checkLinkType,
+  createView,
+  getBizTypes,
+  addAndEditLink,
+  expData,
+  repairTable,
+  deleteLink
+} from "@/api/modeling/linkType/api";
 import basicOption from '@/util/basic-option'
 import {gridAttribute} from "@/api/modeling/attributePool/api";
+import func from "@/util/func";
 
 export default {
   name: "index",
   data() {
     return {
+      tipList: [
+        "瀵煎叆閾炬帴鍚嶇О涓嶅彲涓虹┖涓旈摼鎺ョ被鍨嬪悕绉板彧鑳戒负鑻辨枃瀛楁瘝",
+        "瀵煎叆鐨勬枃浠跺寘鎷睘鎬с�佷笟鍔$被鍨嬨�佺敓鍛藉懆鏈熺瓑鏂囦欢",
+        "涓婁紶鐨勬枃浠朵负鍘嬬缉鏂囦欢锛屼笖鍘嬬缉鏍煎紡浠呰兘涓簔ip鏍煎紡"
+      ],
+      upFileType: ['zip'],
+      fileUrl: 'api/linkTypeController/impData',
+      title: '',
+      bizTypeReload: null,
+      bizToData: [],
+      bizFormData: [],
+      bizTypeList: [],
+      bizTypeLoading: false,
+      bizTypeData: [],
+      bizTypeOption: {
+        ...basicOption,
+        menu: false,
+        addBtn: false,
+        index: false,
+        refreshBtn: false,
+        highlightCurrentRow: true,
+        searchMenuSpan: 8,
+        searchLabelWidth: 100,
+        column: [
+          {
+            label: '涓氬姟绫诲瀷鍚�',
+            prop: 'name',
+            sortable: true,
+            search: true,
+          },
+          {
+            label: '鏍囩',
+            prop: 'label',
+            sortable: true,
+          },
+          {
+            label: '鐖剁被',
+            prop: 'fName',
+            sortable: true,
+          },
+          {
+            label: '鐗堟湰瑙勫垯',
+            prop: 'revRuleName',
+            sortable: true,
+          },
+          {
+            label: '鐢熷懡鍛ㄦ湡',
+            prop: 'lifeCycle',
+            sortable: true,
+          },
+        ]
+      },
+      bizTypeVisible: false,
+      bizTypeTitle: "",
       conDefaultCheckData: [], // 淇濈暀涓婁釜鎺ュ彛杩斿洖鐨勬暟鎹�
       conCheckLoading: false,
       conCheckOption: {
@@ -309,7 +484,21 @@
         addBtn: false,
         index: false,
         selection: false,
-        refreshBtn: false
+        refreshBtn: false,
+        column: [
+          {
+            label: '绫诲瀷鍚�',
+            prop: 'id',
+          },
+          {
+            label: '鎿嶄綔',
+            prop: 'methods',
+          },
+          {
+            label: '鐘舵��',
+            prop: 'status',
+          }
+        ]
       },
       conCheckData: [],
       conCheckVisible: false,
@@ -370,7 +559,7 @@
       form: {
         name: '', // 鍚嶇О
         tag: '', // 鏍囩
-        impClass: '', // 瀹炵幇绫�
+        implClass: '', // 瀹炵幇绫�
         shape: '', // 褰㈢姸
         description: '', // 鎻忚堪
         btmItemsFrom: '', // From绔被鍨嬪垪琛�
@@ -378,7 +567,8 @@
         primitivesFrom: '', // form绔富绫诲瀷
         btmItemsTo: '', // to绔被鍨嬪垪琛�
         relationTo: 'N', // to绔搴斿叧绯�
-        primitivesTo: '', // to绔富绫诲瀷
+        primitivesTo: '', // to绔富绫诲瀷,
+        attributes: []
       },
       dialogBottomOption: {
         ...basicOption,
@@ -470,6 +660,8 @@
         main: 'el-icon-warning-outline',
         desc: 'el-icon-chat-line-square'
       },
+      bizLastIndex: null,
+      attrLastIndex:null
     }
   },
   created() {
@@ -486,12 +678,18 @@
         this.treeData = data;
         this.tableLoading = false;
       }).catch(err => {
-        this.$message.error(err)
+        this.$message.error(err);
       });
+    },
+
+    // 瀵煎叆
+    upLoadClickHandler() {
+      this.$refs.upload.visible = true;
     },
 
     // 鏍戠偣鍑讳簨浠�
     nodeClick(row) {
+      console.log(row);
       this.nodeRow = row;
       this.getAttrPollData(row); // 鑾峰彇灞炴�ф睜鍒楄〃
     },
@@ -506,8 +704,55 @@
       })
     },
 
+    // 鍒犻櫎鎸夐挳
+    deleteClickHandler() {
+      if (func.isEmptyObject(this.nodeRow)) {
+        this.$message.error('璇疯嚦灏戦�夋嫨涓�鏉℃暟鎹�');
+        return;
+      }
+      deleteLink(this.nodeRow).then(res => {
+        if (res.data.code === 200) {
+          this.$message.success('鍒犻櫎鎴愬姛');
+          this.getTreeList();
+        }
+      })
+    },
+
     // 鍒涘缓鎸夐挳
     addClickHandler() {
+      this.visible = true;
+      this.title = 'add';
+    },
+
+    // 缂栬緫鎸夐挳
+    editClickHandler() {
+      this.title = 'edit';
+      if (func.isEmptyObject(this.nodeRow)) {
+        this.$message.error('璇疯嚦灏戦�夋嫨涓�鏉℃暟鎹�');
+        return;
+      }
+      this.form = {...this.nodeRow}; // 娴呮嫹璐� 瑙e喅寮曠敤澶嶅埗
+      console.log(this.nodeRow);
+      this.bizFormData = this.form.btmItemsFrom.length > 0 && this.form.btmItemsFrom.map(item => {
+        return {
+          name: item
+        };
+      });
+
+      this.bizToData = this.form.btmItemsTo.length > 0 && this.form.btmItemsTo.map(item => {
+        return {
+          name: item
+        };
+      });
+
+      if (this.form.attributes.length > 0) {
+        let value = this.form.attributes.join(',');
+        getByAttributeNames({attrNames: value}).then(res => {
+          if (res.data.code === 200) {
+            this.dialogBottomData = res.data.data;
+          }
+        })
+      }
       this.visible = true;
     },
 
@@ -518,18 +763,70 @@
       checkLinkType().then(res => {
         if (res.data.code === 200) {
           const data = res.data.data;
-          this.conDefaultCheckData = data;
-          data.map(item => {
-            // 鑾峰彇 btmCheckMap 瀵硅薄鐨勫睘鎬у悕
-            const keys = Object.keys(item.btmCheckMap);
+          this.conDefaultCheckData = data; // 淇濈暀涓�浠藉師濮嬫暟鎹�
+          this.conCheckLoading = false;
 
-            return {
-              id: keys[0],
-            }
-          })
+          const outputData = [];
+
+          data.forEach(item => {
+            Object.entries(item.btmCheckMap).forEach(([id, methodsArray]) => {
+              methodsArray.forEach(methods => {
+                // 鍒ゆ柇鍓嶇紑
+                const action = methods.startsWith('F_') ? '绉婚櫎form绔笟鍔$被鍨�' : '绉婚櫎to绔笟鍔$被鍨�';
+                const detail = methods.split('_')[1]; // 鑾峰彇 _ 鍚庨潰鐨勫唴瀹�
+                outputData.push({
+                  id: id,
+                  methods: `${action}:${detail}`,
+                  status: '鏈慨澶�'
+                });
+              });
+            });
+
+            // 澶勭悊 dbCheckMap
+            Object.entries(item.dbCheckMap).forEach(([id, methods]) => {
+              const splitMethods = methods.split('(');
+              // 鍒ゆ柇绗竴涓鍙峰墠闈㈢殑鍊�
+              if (splitMethods[0].startsWith('_ADD')) {
+                outputData.push({
+                  id: id,
+                  methods: '澧炲姞鍒�(' + splitMethods[1].slice(0, -1) + ')', // 缁撴潫浣嶇疆鍑忓幓)鐨勫瓧绗�
+                  status: '鏈慨澶�'
+                });
+              } else if (splitMethods[0].startsWith('_CREATE')) {
+                outputData.push({
+                  id: id,
+                  methods: '鍒涘缓琛�(' + splitMethods[1].slice(0, -1) + ')',
+                  status: '鏈慨澶�'
+                });
+              } else if (splitMethods[0].startsWith('_DROP')) {
+                outputData.push({
+                  id: id,
+                  methods: '绉婚櫎鍒�(' + splitMethods[1].slice(0, -1) + ')',
+                  status: '鏈慨澶�'
+                });
+              } else {
+                this.$message.error("涓嶆敮鎸佺殑 dbCheckMap 绫诲瀷锛� " + methods)
+              }
+            });
+          });
+          this.conCheckData = outputData;
         }
       }).catch(err => {
-        this.$message.error(err)
+        this.$message.error(err);
+      })
+    },
+
+    // 淇涓�鑷存�ф鏌�
+    repairClickHandler() {
+      console.log(this.conDefaultCheckData)
+      const params = this.conDefaultCheckData[0];
+      repairTable(params).then(res => {
+        if (func.isEmptyObject(res.data.obj[0])) {
+          this.$message.success('淇鎴愬姛');
+        } else {
+          this.$message.error('淇澶辫触锛岃閲嶆柊灏濊瘯锛�');
+        }
+        this.conCheckVisible = false;
       })
     },
 
@@ -539,7 +836,7 @@
       createView().then(res => {
         if (res.data.code === 200) {
           this.createViewLoading = false;
-          this.$message.success(res.data.obj)
+          this.$message.success(res.data.obj);
         }
       })
     },
@@ -549,7 +846,7 @@
       this.dialogAttrLoading = true;
       this.attrPollDialogVisible = true;
       this.dialogAttrReload = Math.random(); // 寮哄埗鍒锋柊琛ㄦ牸 瑙e喅琛ㄦ牸閿欒
-      this.getAttrDialogDta()
+      this.getAttrDialogDta();
     },
 
     // 鏌ヨ灞炴�ф睜鍒楄〃鏁版嵁
@@ -560,7 +857,7 @@
         this.attrPage.total = res.data.total;
         this.dialogAttrLoading = false;
       }).catch(err => {
-        this.$message.error(err)
+        this.$message.error(err);
       });
     },
 
@@ -571,13 +868,44 @@
 
     // 娣诲姞灞炴�ф睜 琛岀偣鍑�
     dialogAttrRowClickHandler(row) {
-      this.$refs.dialogAttrCrud.toggleRowSelection(row);
+
+      func.rowClickHandler(
+        row,
+        this.$refs.dialogAttrCrud,
+        this.attrLastIndex,
+        (newIndex) => { this.attrLastIndex = newIndex; },
+        () => { this.selectList = []; }
+      );
     },
 
     // 娣诲姞灞炴�ф睜 鍏抽棴瀵硅瘽妗�
     dialogAttrClose() {
       this.attrPollDialogVisible = false;
       this.searchAttrParams = {};
+    },
+
+    // 娓呯┖form琛ㄥ崟
+    resetForm() {
+      const form = {
+        name: '', // 鍚嶇О
+        tag: '', // 鏍囩
+        implClass: '', // 瀹炵幇绫�
+        shape: '', // 褰㈢姸
+        description: '', // 鎻忚堪
+        btmItemsFrom: '', // From绔被鍨嬪垪琛�
+        relationFrom: 'N', // form绔搴斿叧绯�
+        primitivesFrom: '', // form绔富绫诲瀷
+        btmItemsTo: '', // to绔被鍨嬪垪琛�
+        relationTo: 'N', // to绔搴斿叧绯�
+        primitivesTo: '', // to绔富绫诲瀷
+      };
+      this.form = form;
+      this.$refs.form.resetFields();
+      this.bizFormData = [];
+      this.bizToData = [];
+      this.dialogBottomData = [];
+      console.log(this.form);
+      console.log('--', this.nodeRow)
     },
 
     // 娣诲姞灞炴�ф睜 淇濆瓨
@@ -640,15 +968,152 @@
       this.getAttrDialogDta();
     },
 
+    // 灞炴�ф睜鍒犻櫎
+    dialogBottomAttrDel(form, index) {
+      this.dialogBottomData.splice(index, 1);
+    },
+
     // 鍒涘缓 缂栬緫 瀵硅瘽妗嗗叧闂�
     addDialogClose() {
       this.visible = false;
       this.dialogBottomData = [];
+      this.resetForm();
+    },
+
+    // form to 绫诲瀷blur鍙傜収瀵硅瘽妗�
+    FormItemReferChange(val) {
+      this.bizTypeTitle = val;
+      this.bizTypeLoading = true;
+      this.getBizTypeHandler();
+      this.bizTypeVisible = true;
+      this.bizTypeReload = Math.random(); // 寮哄埗鍒锋柊琛ㄦ牸 瑙e喅琛ㄦ牸閿欒
+    },
+
+    // form to 绫诲瀷琛ㄦ牸鏌ヨ
+    getBizTypeHandler(params) {
+      getBizTypes(params).then(res => {
+        if (res.data.code === 200) {
+          const data = res.data.data;
+          this.bizTypeData = data;
+          this.bizTypeLoading = false;
+        }
+      })
+    },
+
+    // form to 绫诲瀷閫夋嫨妗�
+    bizTypeSelection(row) {
+      this.bizTypeList = row;
+    },
+
+    // form to 绫诲瀷琛岀偣鍑�
+    bizTypeRowClick(row) {
+      func.rowClickHandler(
+        row,
+        this.$refs.bizTypeCrud,
+        this.bizLastIndex,
+        (newIndex) => { this.bizLastIndex = newIndex; },
+        () => { this.selectList = []; }
+      );
+    },
+
+    // form to 绫诲瀷淇濆瓨
+    bizTypeAddHandler() {
+      if (this.bizTypeList.length === 0) {
+        this.$message.error('璇疯嚦灏戦�夋嫨涓�鏉℃暟鎹�');
+        return;
+      }
+
+      const data = this.bizTypeList.map(item => ({name: item.name}));
+
+      const dataName = this.bizTypeTitle === 'form' ? 'bizFormData' : 'bizToData';
+
+      let hasDuplicate = false;
+      // 鍏堝垱寤轰竴涓复鏃舵暟缁勬潵瀛樺偍涓嶉噸澶嶇殑椤�
+      const newItems = [];
+      this.bizTypeList.forEach(item => {
+        const exists = this[dataName].some(existingItem => existingItem.name === item.name);
+
+        if (exists) {
+          hasDuplicate = true;
+          return;
+        }
+
+        // 濡傛灉娌℃湁閲嶅椤癸紝鍒欏皢璇ラ」娣诲姞鍒颁复鏃舵暟缁勪腑
+        newItems.push({
+          name: item.name,
+        });
+      });
+
+      if (hasDuplicate) {
+        this.$message.error('璇锋鏌ユ槸鍚︽湁娣诲姞閲嶅椤癸紒');
+      } else {
+        // 濡傛灉娌℃湁閲嶅椤癸紝灏嗘柊椤规坊鍔犲埌 dialogBottomData
+        this[dataName].push(...newItems);
+        this.bizTypeVisible = false;
+      }
+    },
+
+    // form to 绫诲瀷鎼滅储
+    bizTypeHandleSearch(params, done) {
+      console.log(params);
+      let obj = {
+        btmName: params.name
+      };
+      this.getBizTypeHandler(obj);
+
+      done();
+    },
+
+    // form to 绫诲瀷閲嶇疆
+    bizTypeHandleReset() {
+      this.getBizTypeHandler();
+    },
+
+    // form to 绔〃鏍肩Щ闄�
+    bizTypeDeleteRow(val, index) {
+      const dataName = val === 'form' ? 'bizFormData' : 'bizToData';
+      const primitivesName = val === 'form' ? 'primitivesFrom' : 'primitivesTo';
+
+      this[dataName].splice(index, 1);
+
+      if (this[dataName].length === 0) {
+        this.form[primitivesName] = "";
+      }
     },
 
     // 鍒涘缓缂栬緫 淇濆瓨
     addDialogSavaHandler() {
+      if (this.bizFormData.length <= 0 || this.bizToData.length <= 0) {
+        this.$message.error('form绔笟鍔$被鍨嬪拰to绔被鍨嬪潎涓嶈兘涓虹┖锛�')
+        return;
+      }
+      this.form.btmItemsFrom = this.bizFormData.map(item => item.name);
+      this.form.btmItemsTo = this.bizToData.map(item => item.name);
+      this.form.attributes = this.dialogBottomData.map(item => item.id);
+      let flag = this.title === 'add' ? true : false;
+      addAndEditLink(flag, this.form).then(res => {
+        if (res.data.code === 200) {
+          this.visible = false;
+          this.$message.success(res.data.msg);
+          this.resetForm();
+          this.getTreeList();
+        }
+      });
+    },
 
+    // 瀵煎嚭
+    exportClickHandler() {
+      if (func.isEmptyObject(this.nodeRow)) {
+        this.$message.error('璇疯嚦灏戦�夋嫨涓�鏉℃暟鎹�');
+        return;
+      }
+      let name = this.nodeRow.name;
+      expData({name: name}).then(res => {
+        func.downloadFileByBlobHandler(res);
+        this.$message.success('瀵煎嚭鎴愬姛');
+      }).catch(err => {
+        this.$message.error(err);
+      });
     }
   }
 }
@@ -662,6 +1127,12 @@
 
   .el-form-item .el-select {
     width: 100%;
+  }
+
+  .headerCon {
+    .el-button {
+      width: 82px;
+    }
   }
 }
 
@@ -693,9 +1164,20 @@
 }
 
 .dialogForm > div {
-  width: 28%;
+  width: 34%;
   border: 1px solid #eee;
   padding: 25px 20px 5px 10px; /* 涓� 鍙� 涓� 宸� */
   box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2); /* 娣诲姞闃村奖鏁堟灉 */
 }
+
+.leftForm {
+  width: 19% !important;
+  padding: 25px 20px 5px 0px !important;
+}
+
+.smallBtn {
+  width: 82px !important;
+  text-align: center !important;
+  padding-left: 0px !important;
+}
 </style>
diff --git a/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/statusPool/index.vue b/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/statusPool/index.vue
index 424bdb9..41fe5ec 100644
--- a/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/statusPool/index.vue
+++ b/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/statusPool/index.vue
@@ -1,71 +1,42 @@
 <template>
-  <el-container>
+  <basic-container>
+    <avue-crud
+      ref="useCrud"
+      :table-loading="loading"
+      :data="data"
+      :option="option"
+      :page.sync="page"
+      @selection-change="selectChange"
+      @row-click="rowClickHandler"
+      @refresh-change="handleRefresh"
+      @size-change="sizeChange"
+      @current-change="currentChange"
+    >
+      <template slot="menuLeft">
+        <el-button icon="el-icon-plus" plain size="small" type="primary" @click="addClickHandler">鍒涘缓
+        </el-button>
+        <el-button icon="el-icon-delete" plain size="small" type="danger" @click="delClickHandler">鍒犻櫎
+        </el-button>
+        <el-button icon="el-icon-download" plain size="small" type="primary" @click="exportClickHandler">瀵煎嚭
+        </el-button>
+        <el-button icon="el-icon-upload2" plain size="small" type="primary" @click="uploadClickHandler">瀵煎叆
+        </el-button>
+        <el-button icon="el-icon-check" plain size="small" type="primary"
+                   @click="checkViewClickHandler">鏌ョ湅浣跨敤鑼冨洿
+        </el-button>
+      </template>
 
-    <el-aside>
-      <basic-container>
-        <div ref="TreeBox" style="height: calc(100vh - 144px);!important;">
-          <div class="headerCon">
-            <el-button icon="el-icon-plus" plain size="small" type="primary" @click="addClickHandler">鍒涘缓
-            </el-button>
-            <el-button icon="el-icon-edit" plain size="small" type="primary" @click="editClickHandler">淇敼
-            </el-button>
-            <el-button icon="el-icon-delete" plain size="small" type="danger" @click="delClickHandler">鍒犻櫎
-            </el-button>
-            <el-button icon="el-icon-download" plain size="small" type="primary" @click="exportClickHandler">瀵煎嚭
-            </el-button>
-            <el-button icon="el-icon-upload2" plain size="small" type="primary" @click="uploadClickHandler">瀵煎叆
-            </el-button>
-            <el-button plain size="small" style="width: 100px;text-align: center" type="primary"
-                       @click="checkViewClickHandler">鏌ョ湅浣跨敤鑼冨洿
-            </el-button>
-          </div>
-          <!-- 宸︿晶鏍�         -->
-          <div style="height:  calc(100vh - 280px);">
-            <avue-tree :data="treeData" :option="treeOption" @node-click="nodeClick">
-          <span slot-scope="{ node, data }" class="el-tree-node__label">
-           <span style="font-size: 15px">
-              <i class="el-icon-s-promotion"></i>
-                {{ (node || {}).label }}
-            </span>
-          </span>
-            </avue-tree>
-          </div>
-        </div>
-      </basic-container>
-    </el-aside>
+      <template slot="menu" slot-scope="{row,index}">
+        <el-button icon="el-icon-edit" plain size="small" type="text" @click="editClickHandler(row)">淇敼
+        </el-button>
+        <el-button icon="el-icon-delete" plain size="small" type="text" @click="delRowClickHandler(row)">鍒犻櫎
+        </el-button>
+      </template>
 
-    <el-main>
-      <basic-container>
-        <el-descriptions :column="1" border class="margin-top" size="medium" title="灞炴�т俊鎭�">
-          <el-descriptions-item :contentStyle="descriptionOption.contentStyle"
-                                :labelStyle="descriptionOption.labelStyle">
-            <template slot="label">
-              <i :class="icons.id"></i>
-              鍚嶇О
-            </template>
-            <el-tag v-if="nodeRow.id">{{ nodeRow.id }}</el-tag>
-          </el-descriptions-item>
-          <el-descriptions-item :contentStyle="descriptionOption.contentStyle"
-                                :labelStyle="descriptionOption.labelStyle">
-            <template slot="label">
-              <i :class="icons.name"></i>
-              鏍囩
-            </template>
-            <el-tag v-if="nodeRow.name">{{ nodeRow.name }}</el-tag>
-          </el-descriptions-item>
-          <el-descriptions-item :contentStyle="descriptionOption.contentStyle"
-                                :labelStyle="descriptionOption.labelStyle">
-            <template slot="label">
-              <i :class="icons.desc"></i>
-              鎻忚堪
-            </template>
-            <el-tag v-if="nodeRow.description">{{ nodeRow.description }}</el-tag>
-          </el-descriptions-item>
-        </el-descriptions>
-      </basic-container>
-    </el-main>
 
-    <!-- 鏂板 淇敼   -->
+    </avue-crud>
+
+    <!-- 鏂板 淇敼 -->
     <el-dialog
       v-dialogDrag
       :title="dialogTitle === 'add' ? '鍒涘缓' : '淇敼'"
@@ -100,11 +71,11 @@
         </span>
     </el-dialog>
 
-    <!-- 瀵煎叆    -->
+    <!-- 瀵煎叆 -->
     <upload-file ref="upload" :fileType="upFileType" :fileUrl="fileUrl" :tipList="tipList" title="瀵煎叆"
                  @updata="getTreeList"></upload-file>
 
-    <!-- 鏌ョ湅浣跨敤鑼冨洿    -->
+    <!-- 鏌ョ湅浣跨敤鑼冨洿 -->
     <el-dialog
       v-dialogDrag
       :visible.sync="checkViewVisible"
@@ -123,8 +94,7 @@
       >
       </avue-crud>
     </el-dialog>
-
-  </el-container>
+  </basic-container>
 
 </template>
 
@@ -137,6 +107,31 @@
   name: "index",
   data() {
     return {
+      loading:false,
+      data: [],
+      option: {
+        ...basicOption,
+        addBtn: false,
+        editBtn: false,
+        delBtn: false,
+        calcHeight: -60,
+        column: [
+          {
+            label: '鍚嶇О',
+            prop: 'id',
+            sortable: true,
+          },
+          {
+            label: '鏍囩',
+            prop: 'name',
+            sortable: true,
+          },
+          {
+            label: '鎻忚堪',
+            prop: 'description',
+          },
+        ]
+      },
       checkViewVisible: false,
       checkViewData: [],
       checkViewDataSearch: [],
@@ -183,27 +178,13 @@
         ]
       },
       visible: false,
-      treeOption: {
-        height: 'auto',
-        defaultExpandAll: false,
-        menu: false,
-        addBtn: false,
-        props: {
-          label: 'id',
-          value: 'id',
-          children: 'children'
-        }
-      },
-      treeData: [],
-      nodeRow: {},
-      descriptionOption: {
-        labelStyle: 'text-align:center;width:120px',
-        contentStyle: 'width:240px;text-align:center;word-break;break-all;'
-      },
-      icons: {
-        id: 'el-icon-finished',
-        name: 'el-icon-tickets',
-        desc: 'el-icon-chat-line-square'
+      selectList:[],
+      lastIndex:null,
+      page: {
+        currentPage: 1,
+        pageSize: 15,
+        total: 0,
+        pageSizes: [15, 30, 50, 100],
       },
     }
   },
@@ -213,17 +194,47 @@
   methods: {
     // 宸︿晶鏍戣姹�
     getTreeList() {
-      gridStatus({page: 1, limit: -1}).then(res => {
+      gridStatus(this.page.currentPage, this.page.pageSize).then(res => {
         const data = res.data.data;
-        this.treeData = data;
+        this.data = data;
+        this.page.total = res.data.total;
+        this.loading = false;
       }).catch(err => {
-        this.$message.error(err)
+        this.$message.error(err);
       });
     },
 
-    // 鏍戣妭鐐圭偣鍑讳簨浠�
-    nodeClick(row) {
-      this.nodeRow = row;
+    // 琛ㄦ牸鍒锋柊
+    handleRefresh(){
+      this.getTreeList();
+    },
+
+    // 琛ㄦ牸澶氶��
+    selectChange(row){
+      this.selectList = row;
+    },
+
+    //  鏉℃暟
+    sizeChange(val) {
+      this.page.pageSize = val;
+      this.getTreeList();
+    },
+
+    // 椤电爜
+    currentChange(val) {
+      this.page.currentPage = val;
+      this.getTreeList();
+    },
+
+    // 琛屽崟閫�
+    rowClickHandler(row) {
+      func.rowClickHandler(
+        row,
+        this.$refs.useCrud,
+        this.lastIndex,
+        (newIndex) => { this.lastIndex = newIndex; },
+        () => { this.selectList = []; }
+      );
     },
 
     // 鍒涘缓鎸夐挳
@@ -233,19 +244,15 @@
     },
 
     // 缂栬緫鎸夐挳
-    editClickHandler() {
-      if (func.isEmptyObject(this.nodeRow)) {
-        this.$message.error('璇疯嚦灏戦�夋嫨涓�鏉℃暟鎹紒');
-        return;
-      }
+    editClickHandler(row) {
       this.visible = true;
       this.dialogTitle = 'edit';
-      this.form = this.nodeRow;
+      this.form = {...row};
     },
 
     // 鍒犻櫎
     delClickHandler() {
-      if (func.isEmptyObject(this.nodeRow)) {
+      if (this.selectList.length <= 0) {
         this.$message.error('璇疯嚦灏戦�夋嫨涓�鏉℃暟鎹紒');
         return;
       }
@@ -254,12 +261,34 @@
         cancelButtonText: '鍙栨秷',
         type: 'warning'
       }).then(() => {
-        const list = [this.nodeRow];
+        this.loading = true;
+        deleteStatus(this.selectList).then(res => {
+          if (res.data.code === 200) {
+            this.$message.success(res.data.obj);
+            this.getTreeList();
+          }
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '宸插彇娑堝垹闄�'
+        });
+      });
+    },
+
+    // 琛屽崟涓垹闄�
+    delRowClickHandler(row){
+      this.$confirm('鎮ㄧ‘瀹氳鍒犻櫎鎵�閫夋嫨鐨勬暟鎹悧锛�', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        const list = [row];
+        this.loading = true;
         deleteStatus(list).then(res => {
           if (res.data.code === 200) {
             this.$message.success(res.data.obj);
             this.getTreeList();
-            this.nodeRow = {};
           }
         })
       }).catch(() => {
@@ -290,6 +319,7 @@
       saveFunction(this.form).then(res => {
         if (res.data.code === 200) {
           this.$message.success(res.data.obj);
+          this.loading = true;
           this.getTreeList();
           this.visible = false;
         } else {
@@ -302,12 +332,12 @@
 
     // 瀵煎嚭
     exportClickHandler() {
-      if (func.isEmptyObject(this.nodeRow)) {
+      if (this.selectList.length <= 0) {
         this.$message.error('璇疯嚦灏戦�夋嫨涓�鏉℃暟鎹紒');
         return;
       }
 
-      exportStatus({statusOids: this.nodeRow.oid}).then(res => {
+      exportStatus({statusOids: this.selectList.map(item => item.oid).join(',')}).then(res => {
         func.downloadFileByBlobHandler(res);
         this.$message.success('瀵煎嚭鎴愬姛');
       }).catch(err => {
@@ -322,17 +352,22 @@
 
     // 鏌ョ湅浣跨敤鑼冨洿
     checkViewClickHandler() {
-      if (func.isEmptyObject(this.nodeRow)) {
+      if (this.selectList.length <= 0) {
         this.$message.error('璇疯嚦灏戦�夋嫨涓�鏉℃暟鎹紒');
         return;
       }
-      listUsed({oid: this.nodeRow.oid}).then(res => {
+
+      if (this.selectList.length > 1) {
+        this.$message.error('鍙兘閫夋嫨涓�鏉℃暟鎹紒');
+        return;
+      }
+      listUsed({oid: this.selectList[0].oid}).then(res => {
         if (res.data.code === 200) {
           this.checkViewVisible = true;
           const data = res.data.data;
           data.forEach(item => {
             item.name = item.id + `( ${item.name} )`;
-            item.TreeId = this.nodeRow.id;
+            item.TreeId = this.selectList[0].oid;
           })
           this.checkViewData = res.data.data;
           this.checkViewDataSearch = res.data.data;
@@ -371,31 +406,11 @@
   .el-scrollbar__wrap {
     overflow: auto !important;
   }
-}
 
-.headerCon {
-  display: flex;
-  flex-wrap: wrap;
-  margin-bottom: 5px;
-
-  .el-button + .el-button {
-    margin-left: 5px;
-  }
-
-  .el-button {
-    margin-top: 5px;
-  }
-}
-
-.headerCon > .el-button:nth-child(4) {
-  margin-left: 0;
-}
-
-.headerCon > .el-button:nth-child(7) {
-  margin-left: 0;
 }
 
 .upload-demo {
   margin-left: 20px;
 }
+
 </style>
diff --git a/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/versioning/index.vue b/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/versioning/index.vue
index cecfaa4..14234ef 100644
--- a/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/versioning/index.vue
+++ b/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/versioning/index.vue
@@ -14,7 +14,7 @@
             </el-button>
             <el-button icon="el-icon-upload2" plain size="small" type="primary" @click="uploadClickHandler">瀵煎叆
             </el-button>
-            <el-button plain size="small" style="width: 100px;text-align: center" type="primary"
+            <el-button class="smallBtn" plain size="small" type="primary"
                        @click="checkViewClickHandler">鏌ョ湅浣跨敤鑼冨洿
             </el-button>
           </div>
@@ -305,7 +305,6 @@
     //宸︿晶鏍戞煡璇�
     getTreeList() {
       getVersionRuleAllList().then(res => {
-        console.log(res);
         const data = res.data.data;
         this.treeData = data;
       }).catch(err => {
@@ -463,6 +462,13 @@
   .el-scrollbar__wrap {
     overflow: auto !important;
   }
+
+  .headerCon {
+    .el-button {
+      width: 82px;
+    }
+  }
+
 }
 
 .headerCon {
@@ -487,4 +493,10 @@
   margin-left: 0;
 }
 
+.smallBtn {
+  width: 82px;
+  text-align: center;
+  padding-left: 4.5px;
+}
+
 </style>
diff --git a/Source/plt-web/plt-web-ui/src/views/modelingMenu/queryTemplate/businessTypeQuery/index.vue b/Source/plt-web/plt-web-ui/src/views/modelingMenu/queryTemplate/businessTypeQuery/index.vue
index 35e0ed5..308c333 100644
--- a/Source/plt-web/plt-web-ui/src/views/modelingMenu/queryTemplate/businessTypeQuery/index.vue
+++ b/Source/plt-web/plt-web-ui/src/views/modelingMenu/queryTemplate/businessTypeQuery/index.vue
@@ -1,5 +1,45 @@
 <template>
-  <p>涓氬姟绫诲瀷鏌ヨ</p>
+  <el-container>
+
+    <el-aside>
+      <basic-container>
+        <div ref="TreeBox" style="height: calc(100vh - 144px);!important;">
+          <div class="headerCon">
+            <el-button icon="el-icon-plus" plain size="small" type="primary" @click="addClickHandler">鍒涘缓
+            </el-button>
+            <el-button icon="el-icon-edit" plain size="small" type="primary" @click="editClickHandler">淇敼
+            </el-button>
+            <el-button icon="el-icon-delete" plain size="small" type="danger" @click="delClickHandler">鍒犻櫎
+            </el-button>
+            <el-button icon="el-icon-download" plain size="small" type="primary" @click="exportClickHandler">瀵煎嚭
+            </el-button>
+            <el-button icon="el-icon-upload2" plain size="small" type="primary" @click="uploadClickHandler">瀵煎叆
+            </el-button>
+            <el-button class="smallBtn" plain size="small" type="primary"
+                       @click="checkViewClickHandler">鏌ョ湅浣跨敤鑼冨洿
+            </el-button>
+          </div>
+          <!-- 宸︿晶鏍�         -->
+          <div style="height:  calc(100vh - 280px);">
+            <avue-tree :data="treeData" :option="treeOption" @node-click="nodeClick">
+          <span slot-scope="{ node, data }" class="el-tree-node__label">
+           <span style="font-size: 15px">
+              <i class="el-icon-s-promotion"></i>
+                {{ (node || {}).label }}
+            </span>
+          </span>
+            </avue-tree>
+          </div>
+        </div>
+      </basic-container>
+    </el-aside>
+
+    <el-main>
+      <basic-container>
+      </basic-container>
+    </el-main>
+
+  </el-container>
 </template>
 
 <script>
@@ -8,6 +48,45 @@
 }
 </script>
 
-<style scoped>
+<style lang="scss" scoped>
+::v-deep {
+  .el-scrollbar__wrap {
+    overflow: auto !important;
+  }
+  .headerCon{
+    .el-button{
+      width: 82px;
+    }
+  }
+}
+
+.headerCon {
+  display: flex;
+  flex-wrap: wrap;
+  margin-bottom: 5px;
+
+  .el-button + .el-button {
+    margin-left: 5px;
+  }
+
+  .el-button {
+    margin-top: 5px;
+  }
+}
+
+.headerCon > .el-button:nth-child(4) {
+  margin-left: 0;
+}
+
+.headerCon > .el-button:nth-child(7) {
+  margin-left: 0;
+}
+
+
+.smallBtn {
+  width: 82px;
+  text-align: center;
+  padding-left: 4.5px;
+}
 
 </style>
diff --git a/Source/plt-web/plt-web-ui/src/views/modelingMenu/queryTemplate/linkTypeQuery/index.vue b/Source/plt-web/plt-web-ui/src/views/modelingMenu/queryTemplate/linkTypeQuery/index.vue
index c5677bc..308c333 100644
--- a/Source/plt-web/plt-web-ui/src/views/modelingMenu/queryTemplate/linkTypeQuery/index.vue
+++ b/Source/plt-web/plt-web-ui/src/views/modelingMenu/queryTemplate/linkTypeQuery/index.vue
@@ -1,5 +1,45 @@
 <template>
-  <p>閾炬帴绫诲瀷鏌ヨ</p>
+  <el-container>
+
+    <el-aside>
+      <basic-container>
+        <div ref="TreeBox" style="height: calc(100vh - 144px);!important;">
+          <div class="headerCon">
+            <el-button icon="el-icon-plus" plain size="small" type="primary" @click="addClickHandler">鍒涘缓
+            </el-button>
+            <el-button icon="el-icon-edit" plain size="small" type="primary" @click="editClickHandler">淇敼
+            </el-button>
+            <el-button icon="el-icon-delete" plain size="small" type="danger" @click="delClickHandler">鍒犻櫎
+            </el-button>
+            <el-button icon="el-icon-download" plain size="small" type="primary" @click="exportClickHandler">瀵煎嚭
+            </el-button>
+            <el-button icon="el-icon-upload2" plain size="small" type="primary" @click="uploadClickHandler">瀵煎叆
+            </el-button>
+            <el-button class="smallBtn" plain size="small" type="primary"
+                       @click="checkViewClickHandler">鏌ョ湅浣跨敤鑼冨洿
+            </el-button>
+          </div>
+          <!-- 宸︿晶鏍�         -->
+          <div style="height:  calc(100vh - 280px);">
+            <avue-tree :data="treeData" :option="treeOption" @node-click="nodeClick">
+          <span slot-scope="{ node, data }" class="el-tree-node__label">
+           <span style="font-size: 15px">
+              <i class="el-icon-s-promotion"></i>
+                {{ (node || {}).label }}
+            </span>
+          </span>
+            </avue-tree>
+          </div>
+        </div>
+      </basic-container>
+    </el-aside>
+
+    <el-main>
+      <basic-container>
+      </basic-container>
+    </el-main>
+
+  </el-container>
 </template>
 
 <script>
@@ -8,6 +48,45 @@
 }
 </script>
 
-<style scoped>
+<style lang="scss" scoped>
+::v-deep {
+  .el-scrollbar__wrap {
+    overflow: auto !important;
+  }
+  .headerCon{
+    .el-button{
+      width: 82px;
+    }
+  }
+}
+
+.headerCon {
+  display: flex;
+  flex-wrap: wrap;
+  margin-bottom: 5px;
+
+  .el-button + .el-button {
+    margin-left: 5px;
+  }
+
+  .el-button {
+    margin-top: 5px;
+  }
+}
+
+.headerCon > .el-button:nth-child(4) {
+  margin-left: 0;
+}
+
+.headerCon > .el-button:nth-child(7) {
+  margin-left: 0;
+}
+
+
+.smallBtn {
+  width: 82px;
+  text-align: center;
+  padding-left: 4.5px;
+}
 
 </style>
diff --git a/Source/plt-web/plt-web-ui/src/views/modelingMenu/queryTemplate/queryDefine/index.vue b/Source/plt-web/plt-web-ui/src/views/modelingMenu/queryTemplate/queryDefine/index.vue
index 00df313..308c333 100644
--- a/Source/plt-web/plt-web-ui/src/views/modelingMenu/queryTemplate/queryDefine/index.vue
+++ b/Source/plt-web/plt-web-ui/src/views/modelingMenu/queryTemplate/queryDefine/index.vue
@@ -1,13 +1,92 @@
 <template>
-  <p>鏌ヨ妯℃澘瀹氫箟</p>
+  <el-container>
+
+    <el-aside>
+      <basic-container>
+        <div ref="TreeBox" style="height: calc(100vh - 144px);!important;">
+          <div class="headerCon">
+            <el-button icon="el-icon-plus" plain size="small" type="primary" @click="addClickHandler">鍒涘缓
+            </el-button>
+            <el-button icon="el-icon-edit" plain size="small" type="primary" @click="editClickHandler">淇敼
+            </el-button>
+            <el-button icon="el-icon-delete" plain size="small" type="danger" @click="delClickHandler">鍒犻櫎
+            </el-button>
+            <el-button icon="el-icon-download" plain size="small" type="primary" @click="exportClickHandler">瀵煎嚭
+            </el-button>
+            <el-button icon="el-icon-upload2" plain size="small" type="primary" @click="uploadClickHandler">瀵煎叆
+            </el-button>
+            <el-button class="smallBtn" plain size="small" type="primary"
+                       @click="checkViewClickHandler">鏌ョ湅浣跨敤鑼冨洿
+            </el-button>
+          </div>
+          <!-- 宸︿晶鏍�         -->
+          <div style="height:  calc(100vh - 280px);">
+            <avue-tree :data="treeData" :option="treeOption" @node-click="nodeClick">
+          <span slot-scope="{ node, data }" class="el-tree-node__label">
+           <span style="font-size: 15px">
+              <i class="el-icon-s-promotion"></i>
+                {{ (node || {}).label }}
+            </span>
+          </span>
+            </avue-tree>
+          </div>
+        </div>
+      </basic-container>
+    </el-aside>
+
+    <el-main>
+      <basic-container>
+      </basic-container>
+    </el-main>
+
+  </el-container>
 </template>
 
 <script>
 export default {
-name: "index"
+  name: "index"
 }
 </script>
 
-<style scoped>
+<style lang="scss" scoped>
+::v-deep {
+  .el-scrollbar__wrap {
+    overflow: auto !important;
+  }
+  .headerCon{
+    .el-button{
+      width: 82px;
+    }
+  }
+}
+
+.headerCon {
+  display: flex;
+  flex-wrap: wrap;
+  margin-bottom: 5px;
+
+  .el-button + .el-button {
+    margin-left: 5px;
+  }
+
+  .el-button {
+    margin-top: 5px;
+  }
+}
+
+.headerCon > .el-button:nth-child(4) {
+  margin-left: 0;
+}
+
+.headerCon > .el-button:nth-child(7) {
+  margin-left: 0;
+}
+
+
+.smallBtn {
+  width: 82px;
+  text-align: center;
+  padding-left: 4.5px;
+}
 
 </style>
diff --git a/Source/plt-web/plt-web-ui/src/views/modelingMenu/ui/Action/index.vue b/Source/plt-web/plt-web-ui/src/views/modelingMenu/ui/Action/index.vue
new file mode 100644
index 0000000..308c333
--- /dev/null
+++ b/Source/plt-web/plt-web-ui/src/views/modelingMenu/ui/Action/index.vue
@@ -0,0 +1,92 @@
+<template>
+  <el-container>
+
+    <el-aside>
+      <basic-container>
+        <div ref="TreeBox" style="height: calc(100vh - 144px);!important;">
+          <div class="headerCon">
+            <el-button icon="el-icon-plus" plain size="small" type="primary" @click="addClickHandler">鍒涘缓
+            </el-button>
+            <el-button icon="el-icon-edit" plain size="small" type="primary" @click="editClickHandler">淇敼
+            </el-button>
+            <el-button icon="el-icon-delete" plain size="small" type="danger" @click="delClickHandler">鍒犻櫎
+            </el-button>
+            <el-button icon="el-icon-download" plain size="small" type="primary" @click="exportClickHandler">瀵煎嚭
+            </el-button>
+            <el-button icon="el-icon-upload2" plain size="small" type="primary" @click="uploadClickHandler">瀵煎叆
+            </el-button>
+            <el-button class="smallBtn" plain size="small" type="primary"
+                       @click="checkViewClickHandler">鏌ョ湅浣跨敤鑼冨洿
+            </el-button>
+          </div>
+          <!-- 宸︿晶鏍�         -->
+          <div style="height:  calc(100vh - 280px);">
+            <avue-tree :data="treeData" :option="treeOption" @node-click="nodeClick">
+          <span slot-scope="{ node, data }" class="el-tree-node__label">
+           <span style="font-size: 15px">
+              <i class="el-icon-s-promotion"></i>
+                {{ (node || {}).label }}
+            </span>
+          </span>
+            </avue-tree>
+          </div>
+        </div>
+      </basic-container>
+    </el-aside>
+
+    <el-main>
+      <basic-container>
+      </basic-container>
+    </el-main>
+
+  </el-container>
+</template>
+
+<script>
+export default {
+  name: "index"
+}
+</script>
+
+<style lang="scss" scoped>
+::v-deep {
+  .el-scrollbar__wrap {
+    overflow: auto !important;
+  }
+  .headerCon{
+    .el-button{
+      width: 82px;
+    }
+  }
+}
+
+.headerCon {
+  display: flex;
+  flex-wrap: wrap;
+  margin-bottom: 5px;
+
+  .el-button + .el-button {
+    margin-left: 5px;
+  }
+
+  .el-button {
+    margin-top: 5px;
+  }
+}
+
+.headerCon > .el-button:nth-child(4) {
+  margin-left: 0;
+}
+
+.headerCon > .el-button:nth-child(7) {
+  margin-left: 0;
+}
+
+
+.smallBtn {
+  width: 82px;
+  text-align: center;
+  padding-left: 4.5px;
+}
+
+</style>
diff --git a/Source/plt-web/plt-web-ui/src/views/modelingMenu/ui/formDefine/index.vue b/Source/plt-web/plt-web-ui/src/views/modelingMenu/ui/formDefine/index.vue
new file mode 100644
index 0000000..308c333
--- /dev/null
+++ b/Source/plt-web/plt-web-ui/src/views/modelingMenu/ui/formDefine/index.vue
@@ -0,0 +1,92 @@
+<template>
+  <el-container>
+
+    <el-aside>
+      <basic-container>
+        <div ref="TreeBox" style="height: calc(100vh - 144px);!important;">
+          <div class="headerCon">
+            <el-button icon="el-icon-plus" plain size="small" type="primary" @click="addClickHandler">鍒涘缓
+            </el-button>
+            <el-button icon="el-icon-edit" plain size="small" type="primary" @click="editClickHandler">淇敼
+            </el-button>
+            <el-button icon="el-icon-delete" plain size="small" type="danger" @click="delClickHandler">鍒犻櫎
+            </el-button>
+            <el-button icon="el-icon-download" plain size="small" type="primary" @click="exportClickHandler">瀵煎嚭
+            </el-button>
+            <el-button icon="el-icon-upload2" plain size="small" type="primary" @click="uploadClickHandler">瀵煎叆
+            </el-button>
+            <el-button class="smallBtn" plain size="small" type="primary"
+                       @click="checkViewClickHandler">鏌ョ湅浣跨敤鑼冨洿
+            </el-button>
+          </div>
+          <!-- 宸︿晶鏍�         -->
+          <div style="height:  calc(100vh - 280px);">
+            <avue-tree :data="treeData" :option="treeOption" @node-click="nodeClick">
+          <span slot-scope="{ node, data }" class="el-tree-node__label">
+           <span style="font-size: 15px">
+              <i class="el-icon-s-promotion"></i>
+                {{ (node || {}).label }}
+            </span>
+          </span>
+            </avue-tree>
+          </div>
+        </div>
+      </basic-container>
+    </el-aside>
+
+    <el-main>
+      <basic-container>
+      </basic-container>
+    </el-main>
+
+  </el-container>
+</template>
+
+<script>
+export default {
+  name: "index"
+}
+</script>
+
+<style lang="scss" scoped>
+::v-deep {
+  .el-scrollbar__wrap {
+    overflow: auto !important;
+  }
+  .headerCon{
+    .el-button{
+      width: 82px;
+    }
+  }
+}
+
+.headerCon {
+  display: flex;
+  flex-wrap: wrap;
+  margin-bottom: 5px;
+
+  .el-button + .el-button {
+    margin-left: 5px;
+  }
+
+  .el-button {
+    margin-top: 5px;
+  }
+}
+
+.headerCon > .el-button:nth-child(4) {
+  margin-left: 0;
+}
+
+.headerCon > .el-button:nth-child(7) {
+  margin-left: 0;
+}
+
+
+.smallBtn {
+  width: 82px;
+  text-align: center;
+  padding-left: 4.5px;
+}
+
+</style>
diff --git a/Source/plt-web/plt-web-ui/src/views/modelingMenu/ui/uiDefine/index.vue b/Source/plt-web/plt-web-ui/src/views/modelingMenu/ui/uiDefine/index.vue
new file mode 100644
index 0000000..308c333
--- /dev/null
+++ b/Source/plt-web/plt-web-ui/src/views/modelingMenu/ui/uiDefine/index.vue
@@ -0,0 +1,92 @@
+<template>
+  <el-container>
+
+    <el-aside>
+      <basic-container>
+        <div ref="TreeBox" style="height: calc(100vh - 144px);!important;">
+          <div class="headerCon">
+            <el-button icon="el-icon-plus" plain size="small" type="primary" @click="addClickHandler">鍒涘缓
+            </el-button>
+            <el-button icon="el-icon-edit" plain size="small" type="primary" @click="editClickHandler">淇敼
+            </el-button>
+            <el-button icon="el-icon-delete" plain size="small" type="danger" @click="delClickHandler">鍒犻櫎
+            </el-button>
+            <el-button icon="el-icon-download" plain size="small" type="primary" @click="exportClickHandler">瀵煎嚭
+            </el-button>
+            <el-button icon="el-icon-upload2" plain size="small" type="primary" @click="uploadClickHandler">瀵煎叆
+            </el-button>
+            <el-button class="smallBtn" plain size="small" type="primary"
+                       @click="checkViewClickHandler">鏌ョ湅浣跨敤鑼冨洿
+            </el-button>
+          </div>
+          <!-- 宸︿晶鏍�         -->
+          <div style="height:  calc(100vh - 280px);">
+            <avue-tree :data="treeData" :option="treeOption" @node-click="nodeClick">
+          <span slot-scope="{ node, data }" class="el-tree-node__label">
+           <span style="font-size: 15px">
+              <i class="el-icon-s-promotion"></i>
+                {{ (node || {}).label }}
+            </span>
+          </span>
+            </avue-tree>
+          </div>
+        </div>
+      </basic-container>
+    </el-aside>
+
+    <el-main>
+      <basic-container>
+      </basic-container>
+    </el-main>
+
+  </el-container>
+</template>
+
+<script>
+export default {
+  name: "index"
+}
+</script>
+
+<style lang="scss" scoped>
+::v-deep {
+  .el-scrollbar__wrap {
+    overflow: auto !important;
+  }
+  .headerCon{
+    .el-button{
+      width: 82px;
+    }
+  }
+}
+
+.headerCon {
+  display: flex;
+  flex-wrap: wrap;
+  margin-bottom: 5px;
+
+  .el-button + .el-button {
+    margin-left: 5px;
+  }
+
+  .el-button {
+    margin-top: 5px;
+  }
+}
+
+.headerCon > .el-button:nth-child(4) {
+  margin-left: 0;
+}
+
+.headerCon > .el-button:nth-child(7) {
+  margin-left: 0;
+}
+
+
+.smallBtn {
+  width: 82px;
+  text-align: center;
+  padding-left: 4.5px;
+}
+
+</style>
diff --git a/Source/plt-web/plt-web-ui/src/views/system/role/index.vue b/Source/plt-web/plt-web-ui/src/views/system/role/index.vue
index 06c3d4a..ab98e39 100644
--- a/Source/plt-web/plt-web-ui/src/views/system/role/index.vue
+++ b/Source/plt-web/plt-web-ui/src/views/system/role/index.vue
@@ -53,14 +53,15 @@
       </avue-crud>
       <div slot="footer" class="dialog-footer" style="display: flex;gap: 20px;justify-content: center">
         <div>
-          <el-tag>褰撳墠瑙掕壊鎬讳汉鏁�: {{this.countData.length}}</el-tag>
+          <el-tag>褰撳墠瑙掕壊鎬讳汉鏁�: {{ this.countData.length }}</el-tag>
         </div>
-        <el-button size="small" @click="statisticsVisible = false" icon="el-icon-close" type="danger">鍏� 闂�</el-button>
+        <el-button icon="el-icon-close" size="small" type="danger" @click="statisticsVisible = false">鍏� 闂�</el-button>
       </div>
     </el-dialog>
 
     <!-- 瀵煎叆瑙掕壊  -->
-    <upload-file ref="upload" :tipList="tipList" :fileType="upFileType" :fileUrl="fileUrl" @updata="getTableList" title="瀵煎叆瑙掕壊"></upload-file>
+    <upload-file ref="upload" :fileType="upFileType" :fileUrl="fileUrl" :tipList="tipList" title="瀵煎叆瑙掕壊"
+                 @updata="getTableList"></upload-file>
 
   </basic-container>
 </template>
@@ -77,6 +78,7 @@
 } from '@/api/system/role/api'
 import basicOption from "@/util/basic-option";
 import {column} from "@/views/system/role/option";
+import func from "@/util/func";
 
 export default {
   name: "index",
@@ -107,10 +109,10 @@
       countData: [],
       countOption: {
         ...basicOption,
-        selection:false,
+        selection: false,
         refreshBtn: false,
-        addBtn:false,
-        menu:false,
+        addBtn: false,
+        menu: false,
         column: [
           {
             label: '閮ㄩ棬',
@@ -137,7 +139,7 @@
       },
       upFileType: ['xls', 'xlsx'],
       fileUrl: 'api/roleQueryController/importRole',
-      tipList:["瑙掕壊瀵煎叆鍙湁 鍚嶇О 鍜� 鎻忚堪 涓ゅ垪锛屼笖鍚嶇О涓哄繀杈撻」涓嶈兘涓虹┖"]
+      tipList: ["瑙掕壊瀵煎叆鍙湁 鍚嶇О 鍜� 鎻忚堪 涓ゅ垪锛屼笖鍚嶇О涓哄繀杈撻」涓嶈兘涓虹┖"]
     }
   },
   methods: {
@@ -174,11 +176,17 @@
 
     // 琛屽崟閫�
     rowClickHandler(row) {
-      this.$refs.roleCrud.toggleRowSelection(row);
+      func.rowClickHandler(
+        row,
+        this.$refs.roleCrud,
+        this.lastIndex,
+        (newIndex) => { this.lastIndex = newIndex; },
+        () => { this.selectList = []; }
+      );
     },
 
     // 娣诲姞
-    rowSaveHandler(row, done,loading) {
+    rowSaveHandler(row, done, loading) {
       delete row.roleClassifyText;
       addRole(row).then(res => {
         console.log(res)
@@ -187,14 +195,14 @@
           this.getTableList();
           done();
         }
-      }).catch(err =>{
+      }).catch(err => {
         console.log(err);
         loading();
       })
     },
 
     // 缂栬緫
-    rowUpdateHandler(row, index, done,loading) {
+    rowUpdateHandler(row, index, done, loading) {
       delete row.roleClassifyText;
       updateRole(row).then(res => {
         if (res.data.code === 200) {
@@ -326,9 +334,9 @@
           this.countData = data.map(item => {
             return {
               pkDepartmentName: item.pkDepartmentName,
-              name:item.name,
-              id:item.id,
-              pkPersonName:this.selectList[0].name
+              name: item.name,
+              id: item.id,
+              pkPersonName: this.selectList[0].name
             }
           });
           this.statisticsVisible = true;
@@ -339,7 +347,7 @@
     },
 
     // 瀵煎叆瑙掕壊
-    upLoadRole(){
+    upLoadRole() {
       this.$refs.upload.visible = true;
     }
   }
diff --git a/Source/plt-web/plt-web-ui/src/views/system/user/index.vue b/Source/plt-web/plt-web-ui/src/views/system/user/index.vue
index 619ebf1..ee786da 100644
--- a/Source/plt-web/plt-web-ui/src/views/system/user/index.vue
+++ b/Source/plt-web/plt-web-ui/src/views/system/user/index.vue
@@ -172,6 +172,7 @@
           {
             label: '鍚嶇О',
             prop: 'name',
+            align:'left'
           },
           {
             label: '缂栧彿',
@@ -213,7 +214,8 @@
       leftRoleData: [],  // 鍒嗛厤瑙掕壊绌挎妗嗗乏渚у垵濮嬫暟鎹�
       rightRoleData: [], // 鍒嗛厤瑙掕壊绌挎妗嗗彸渚у垵濮嬫暟鎹�
       transferTitle: ['鐜版湁瑙掕壊', '鎷ユ湁瑙掕壊'],
-      tipList:["瀵煎叆妯℃澘涓爣鏄庣孩鑹插瓧浣撶殑涓哄繀杈撻」","閮ㄩ棬鍒椾笂涓嬬骇鍏崇郴蹇呴』鎸夌収鍙嶆枩鏉犻殧寮�(/)"]
+      tipList:["瀵煎叆妯℃澘涓爣鏄庣孩鑹插瓧浣撶殑涓哄繀杈撻」","閮ㄩ棬鍒椾笂涓嬬骇鍏崇郴蹇呴』鎸夌収鍙嶆枩鏉犻殧寮�(/)"],
+      lastIndex:null,
     }
   },
   created() {
@@ -311,7 +313,13 @@
 
     // 鐐瑰嚮琛�
     rowClickHandler(row) {
-      this.$refs.userCrud.toggleRowSelection(row);
+      func.rowClickHandler(
+        row,
+        this.$refs.userCrud,
+        this.lastIndex,
+        (newIndex) => { this.lastIndex = newIndex; },
+        () => { this.selectList = []; }
+      );
     },
 
     // 鍒嗛厤瑙掕壊

--
Gitblit v1.9.3