Zn 1 년 전
부모
커밋
dc4cbc2cdc
43개의 변경된 파일1718개의 추가작업 그리고 1202개의 파일을 삭제
  1. 10 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysBpmNodeScriptController.java
  2. 29 44
      ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java
  3. 7 0
      ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysBpmNodeScriptMapper.java
  4. 7 0
      ruoyi-system/src/main/java/com/ruoyi/system/service/ISysBpmNodeScriptService.java
  5. 5 0
      ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysBpmNodeScriptServiceImpl.java
  6. 9 0
      ruoyi-system/src/main/resources/mapper/system/SysBpmNodeScriptMapper.xml
  7. 51 1
      ruoyi-system/src/main/resources/sql/initialize_sys_tenant_menu.json
  8. 1 17
      ruoyi-ui/src/api/bpmprocess/process.js
  9. 45 0
      ruoyi-ui/src/api/bpmprocess/run/executeMiddle.js
  10. 44 0
      ruoyi-ui/src/api/bpmprocess/run/executeNode.js
  11. 64 0
      ruoyi-ui/src/api/bpmprocess/run/executeProcess.js
  12. 18 0
      ruoyi-ui/src/api/bpmprocess/script.js
  13. 15 5
      ruoyi-ui/src/api/system/btn.js
  14. 1 1
      ruoyi-ui/src/api/tablelist/commonTable.js
  15. 23 5
      ruoyi-ui/src/components/kFormDesign/OptionsEdit.vue
  16. 0 779
      ruoyi-ui/src/components/updateModule/bpmn-js/lib/BaseViewer.js
  17. 17 16
      ruoyi-ui/src/components/updateModule/bpmn-js/lib/features/modeling/BpmnFactory.js
  18. 36 1
      ruoyi-ui/src/utils/bpmn/getNodeSequence.js
  19. 13 0
      ruoyi-ui/src/utils/bpmn/xml.js
  20. 4 0
      ruoyi-ui/src/utils/index.js
  21. 8 8
      ruoyi-ui/src/views/bpmprocess/scriptManage.vue
  22. 51 10
      ruoyi-ui/src/views/bussiness/components/TaskItem.vue
  23. 28 12
      ruoyi-ui/src/views/bussiness/components/taskList.vue
  24. 74 0
      ruoyi-ui/src/views/bussiness/dialogCompments/GY1.vue
  25. 276 4
      ruoyi-ui/src/views/bussiness/processMange.vue
  26. 64 3
      ruoyi-ui/src/views/bussiness/progressShow.vue
  27. 1 1
      ruoyi-ui/src/views/dataEngine/datamodeling/editTable.vue
  28. 87 11
      ruoyi-ui/src/views/system/bpmnPro/components/Panel/components/ElementAsyncContinuations.vue
  29. 80 0
      ruoyi-ui/src/views/system/bpmnPro/components/Panel/components/ElementExcuteType.vue
  30. 22 3
      ruoyi-ui/src/views/system/bpmnPro/components/Panel/components/ElementExecuteUser.vue
  31. 1 0
      ruoyi-ui/src/views/system/bpmnPro/components/Panel/components/ElementGenerations.vue
  32. 4 3
      ruoyi-ui/src/views/system/bpmnPro/components/Panel/components/ElementNormalTask.vue
  33. 13 7
      ruoyi-ui/src/views/system/bpmnPro/components/Panel/components/ElementUnusualTasks.vue
  34. 7 3
      ruoyi-ui/src/views/system/bpmnPro/components/Panel/index.vue
  35. 31 2
      ruoyi-ui/src/views/system/bpmnPro/components/bo-utils/asynchronousContinuationsUtil.js
  36. 20 4
      ruoyi-ui/src/views/system/bpmnPro/components/bo-utils/getNodeMsg.js
  37. 18 0
      ruoyi-ui/src/views/system/bpmnPro/components/bo-utils/myFieldUtil.js
  38. 374 178
      ruoyi-ui/src/views/system/excuteBtnMange/index.vue
  39. 1 1
      ruoyi-ui/src/views/system/fromModel/index.vue
  40. 104 76
      ruoyi-ui/src/views/system/tenant/code/index.vue
  41. 2 2
      ruoyi-ui/src/views/tableMange/index.vue
  42. 52 4
      ruoyi-ui/src/views/tablelist/commonTable/listInfo.vue
  43. 1 1
      ruoyi-ui/src/views/tool/datasheet/index.vue

+ 10 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysBpmNodeScriptController.java

@@ -1,5 +1,6 @@
 package com.ruoyi.web.controller.system;
 
+import java.util.ArrayList;
 import java.util.List;
 import javax.servlet.http.HttpServletResponse;
 
@@ -121,4 +122,13 @@ public class SysBpmNodeScriptController extends BaseController
     public AjaxResult selectSysBpmNodeScriptByScriptKey(@PathVariable("scriptKey") String scriptKey){
         return success(sysBpmNodeScriptService.selectSysBpmNodeScriptByScriptKey(scriptKey));
     }
+
+    /**
+     * 根据scriptKeys获取流程节点脚本详细信息
+     */
+    @PostMapping("/selectSysBpmNodeScriptByScriptKeys")
+    public AjaxResult selectSysBpmNodeScriptByScriptKeys(@RequestBody List<String> scriptKeys){
+        return AjaxResult.success(sysBpmNodeScriptService.selectSysBpmNodeScriptByScriptKeys(scriptKeys));
+    }
+
 }

+ 29 - 44
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java

@@ -4,6 +4,7 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
 import javax.servlet.http.HttpServletRequest;
+
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
@@ -27,8 +28,7 @@ import io.jsonwebtoken.SignatureAlgorithm;
  * @author ruoyi
  */
 @Component
-public class TokenService
-{
+public class TokenService {
     // 令牌自定义标识
     @Value("${token.header}")
     private String header;
@@ -55,23 +55,23 @@ public class TokenService
      *
      * @return 用户信息
      */
-    public LoginUser getLoginUser(HttpServletRequest request)
-    {
+    public LoginUser getLoginUser(HttpServletRequest request) {
         // 获取请求携带的令牌
         String token = getToken(request);
-        if (StringUtils.isNotEmpty(token))
-        {
-            try
-            {
-                Claims claims = parseToken(token);
-                // 解析对应的权限以及用户信息
-                String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
+        if (StringUtils.isNotEmpty(token)) {
+            try {
+                String uuid = "";
+                if (token.contains("XIAFA")) {  // 判断当前请求是否别的项目下发的
+                    uuid = token.replace("XIAFA", "");
+                } else {
+                    Claims claims = parseToken(token);
+                    // 解析对应的权限以及用户信息
+                    uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
+                }
                 String userKey = getTokenKey(uuid);
                 LoginUser user = redisCache.getCacheObject(userKey);
                 return user;
-            }
-            catch (Exception e)
-            {
+            } catch (Exception e) {
             }
         }
         return null;
@@ -80,10 +80,8 @@ public class TokenService
     /**
      * 设置用户身份信息
      */
-    public void setLoginUser(LoginUser loginUser)
-    {
-        if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken()))
-        {
+    public void setLoginUser(LoginUser loginUser) {
+        if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) {
             refreshToken(loginUser);
         }
     }
@@ -91,10 +89,8 @@ public class TokenService
     /**
      * 删除用户身份信息
      */
-    public void delLoginUser(String token)
-    {
-        if (StringUtils.isNotEmpty(token))
-        {
+    public void delLoginUser(String token) {
+        if (StringUtils.isNotEmpty(token)) {
             String userKey = getTokenKey(token);
             redisCache.deleteObject(userKey);
         }
@@ -106,8 +102,7 @@ public class TokenService
      * @param loginUser 用户信息
      * @return 令牌
      */
-    public String createToken(LoginUser loginUser)
-    {
+    public String createToken(LoginUser loginUser) {
         String token = IdUtils.fastUUID();
         loginUser.setToken(token);
         setUserAgent(loginUser);
@@ -124,12 +119,10 @@ public class TokenService
      * @param loginUser
      * @return 令牌
      */
-    public void verifyToken(LoginUser loginUser)
-    {
+    public void verifyToken(LoginUser loginUser) {
         long expireTime = loginUser.getExpireTime();
         long currentTime = System.currentTimeMillis();
-        if (expireTime - currentTime <= MILLIS_MINUTE_TEN)
-        {
+        if (expireTime - currentTime <= MILLIS_MINUTE_TEN) {
             refreshToken(loginUser);
         }
     }
@@ -139,8 +132,7 @@ public class TokenService
      *
      * @param loginUser 登录信息
      */
-    public void refreshToken(LoginUser loginUser)
-    {
+    public void refreshToken(LoginUser loginUser) {
         loginUser.setLoginTime(System.currentTimeMillis());
         loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
         // 根据uuid将loginUser缓存
@@ -153,8 +145,7 @@ public class TokenService
      *
      * @param loginUser 登录信息
      */
-    public void setUserAgent(LoginUser loginUser)
-    {
+    public void setUserAgent(LoginUser loginUser) {
         UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
         String ip = IpUtils.getIpAddr();
         loginUser.setIpaddr(ip);
@@ -169,8 +160,7 @@ public class TokenService
      * @param claims 数据声明
      * @return 令牌
      */
-    private String createToken(Map<String, Object> claims)
-    {
+    private String createToken(Map<String, Object> claims) {
         String token = Jwts.builder()
                 .setClaims(claims)
                 .signWith(SignatureAlgorithm.HS512, secret).compact();
@@ -183,8 +173,7 @@ public class TokenService
      * @param token 令牌
      * @return 数据声明
      */
-    private Claims parseToken(String token)
-    {
+    private Claims parseToken(String token) {
         return Jwts.parser()
                 .setSigningKey(secret)
                 .parseClaimsJws(token)
@@ -197,8 +186,7 @@ public class TokenService
      * @param token 令牌
      * @return 用户名
      */
-    public String getUsernameFromToken(String token)
-    {
+    public String getUsernameFromToken(String token) {
         Claims claims = parseToken(token);
         return claims.getSubject();
     }
@@ -209,18 +197,15 @@ public class TokenService
      * @param request
      * @return token
      */
-    private String getToken(HttpServletRequest request)
-    {
+    private String getToken(HttpServletRequest request) {
         String token = request.getHeader(header);
-        if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX))
-        {
+        if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX)) {
             token = token.replace(Constants.TOKEN_PREFIX, "");
         }
         return token;
     }
 
-    private String getTokenKey(String uuid)
-    {
+    private String getTokenKey(String uuid) {
         return CacheConstants.LOGIN_TOKEN_KEY + uuid;
     }
 }

+ 7 - 0
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysBpmNodeScriptMapper.java

@@ -65,4 +65,11 @@ public interface SysBpmNodeScriptMapper
      * @return
      */
     SysBpmNodeScript selectSysBpmNodeScriptByScriptKey(String scriptKey);
+
+    /**
+     * 根据scriptKey查询流程节点脚本
+     * @param scriptKeys 唯一标识
+     * @return
+     */
+    List<SysBpmNodeScript> selectSysBpmNodeScriptByScriptKeys(List<String> scriptKeys);
 }

+ 7 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysBpmNodeScriptService.java

@@ -65,4 +65,11 @@ public interface ISysBpmNodeScriptService
      * @return
      */
     SysBpmNodeScript selectSysBpmNodeScriptByScriptKey(String scriptKey);
+
+    /**
+     * 根据scriptKey查询流程节点脚本
+     * @param scriptKeys 唯一标识
+     * @return
+     */
+    List<SysBpmNodeScript> selectSysBpmNodeScriptByScriptKeys(List<String> scriptKeys);
 }

+ 5 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysBpmNodeScriptServiceImpl.java

@@ -103,4 +103,9 @@ public class SysBpmNodeScriptServiceImpl implements ISysBpmNodeScriptService
     public SysBpmNodeScript selectSysBpmNodeScriptByScriptKey(String scriptKey) {
         return sysBpmNodeScriptMapper.selectSysBpmNodeScriptByScriptKey(scriptKey);
     }
+
+    @Override
+    public List<SysBpmNodeScript> selectSysBpmNodeScriptByScriptKeys(List<String> scriptKeys) {
+        return sysBpmNodeScriptMapper.selectSysBpmNodeScriptByScriptKeys(scriptKeys);
+    }
 }

+ 9 - 0
ruoyi-system/src/main/resources/mapper/system/SysBpmNodeScriptMapper.xml

@@ -101,4 +101,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <include refid="selectSysBpmNodeScriptVo"/>
         where script_key = #{scriptKey}
     </select>
+
+    <select id="selectSysBpmNodeScriptByScriptKeys"  resultMap="SysBpmNodeScriptResult">
+        <include refid="selectSysBpmNodeScriptVo"/>
+        where del_flag = '0' and script_key in
+        <foreach collection="list" item="scriptKey" open="(" close=")" separator=",">
+            #{scriptKey}
+        </foreach>
+    </select>
+
 </mapper>

+ 51 - 1
ruoyi-system/src/main/resources/sql/initialize_sys_tenant_menu.json

@@ -1041,12 +1041,62 @@
         "isFrame": "1",
         "isCache": "0",
         "menuType": "C",
-        "visible": "1",
+        "visible": "0",
         "status": "0",
         "perms": "",
         "icon": "button",
         "children": [],
         "tenantName": null,
         "tenantId": null
+    },
+    {
+        "createBy": null,
+        "createTime": "2023-10-11 09:28:10",
+        "updateBy": null,
+        "updateTime": null,
+        "remark": null,
+        "menuId": 4216,
+        "menuName": "管道管理",
+        "parentName": null,
+        "parentId": 0,
+        "orderNum": 1,
+        "path": "processMange",
+        "component": null,
+        "query": null,
+        "isFrame": "1",
+        "isCache": "0",
+        "menuType": "M",
+        "visible": "0",
+        "status": "0",
+        "perms": "",
+        "icon": "bpmn-icon-end-event-error",
+        "children": [],
+        "tenantName": null,
+        "tenantId": null
+    },
+    {
+        "createBy": null,
+        "createTime": "2023-10-11 09:28:10",
+        "updateBy": null,
+        "updateTime": null,
+        "remark": null,
+        "menuId": 4218,
+        "menuName": "管道流程",
+        "parentName": null,
+        "parentId": 4216,
+        "orderNum": 1,
+        "path": "asd",
+        "component": "bussiness/processMange",
+        "query": null,
+        "isFrame": "1",
+        "isCache": "0",
+        "menuType": "C",
+        "visible": "0",
+        "status": "0",
+        "perms": "",
+        "icon": "bpmn-icon-intermediate-event-throw-link",
+        "children": [],
+        "tenantName": null,
+        "tenantId": null
     }
 ]

+ 1 - 17
ruoyi-ui/src/api/bpmprocess/process.js

@@ -101,6 +101,7 @@ export function updateConfiguration(data) {
     baseURL: process.env.VUE_APP_BASE_API4,
   })
 }
+
 // 查询流程节点详情
 export function getNodeData(processKey) {
   return request({
@@ -136,20 +137,3 @@ export function addScript(data) {
     data: data
   })
 }
-
-// 修改流程节点脚本
-export function updateScript(data) {
-  return request({
-    url: '/system/script',
-    method: 'put',
-    data: data
-  })
-}
-
-// 删除流程节点脚本
-export function delScript(id) {
-  return request({
-    url: '/system/script/' + id,
-    method: 'delete'
-  })
-}

+ 45 - 0
ruoyi-ui/src/api/bpmprocess/run/executeMiddle.js

@@ -0,0 +1,45 @@
+import request from '@/utils/request'
+
+// 查询执行流程用户、节点关联脚本中间表列表
+export function listMiddle(query) {
+  return request({
+    url: '/system/middle/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询执行流程用户、节点关联脚本中间表详细
+export function getMiddle(id) {
+  return request({
+    url: '/system/middle/' + id,
+    method: 'get'
+  })
+}
+
+// 新增执行流程用户、节点关联脚本中间表
+export function addMiddle(data) {
+  return request({
+    url: '/system/middle',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改执行流程用户、节点关联脚本中间表
+export function updateMiddle(data) {
+  return request({
+    url: '/system/middle',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除执行流程用户、节点关联脚本中间表
+export function delMiddle(id) {
+  return request({
+    url: '/system/middle/' + id,
+    method: 'delete'
+  })
+}
+

+ 44 - 0
ruoyi-ui/src/api/bpmprocess/run/executeNode.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询节点执行表(记录表)列表
+export function listNode(query) {
+  return request({
+    url: '/system/node/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询节点执行表(记录表)详细
+export function getNode(id) {
+  return request({
+    url: '/system/node/' + id,
+    method: 'get'
+  })
+}
+
+// 新增节点执行表(记录表)
+export function addNode(data) {
+  return request({
+    url: '/system/node',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改节点执行表(记录表)
+export function updateNode(data) {
+  return request({
+    url: '/system/node',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除节点执行表(记录表)
+export function delNode(id) {
+  return request({
+    url: '/system/node/' + id,
+    method: 'delete'
+  })
+}

+ 64 - 0
ruoyi-ui/src/api/bpmprocess/run/executeProcess.js

@@ -0,0 +1,64 @@
+import request from '@/utils/request'
+
+// 查询流程执行任务表列表
+export function listProcess(query) {
+  return request({
+    url: '/system/process/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询流程执行任务表详细
+export function getProcess(id) {
+  return request({
+    url: '/system/process/' + id,
+    method: 'get'
+  })
+}
+
+// 新增流程执行任务表
+export function addProcess(data) {
+  return request({
+    url: '/system/process',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改流程执行任务表
+export function updateProcess(data) {
+  return request({
+    url: '/system/process',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除流程执行任务表
+export function delProcess(id) {
+  return request({
+    url: '/system/process/' + id,
+    method: 'delete'
+  })
+}
+
+// 执行管道列表数据
+export function processList(query) {
+  return request({
+    url: '/system/execute/process/list',
+    method: 'get',
+    params: query,
+    baseURL: process.env.VUE_APP_BASE_API4,
+  })
+}
+
+// 运行节点
+export function runProcessNodeExecution(data) {
+  return request({
+    url: '/system/runbpm/process/processNodeExecution',
+    method: 'post',
+    data: data,
+    baseURL: process.env.VUE_APP_BASE_API4
+  })
+}

+ 18 - 0
ruoyi-ui/src/api/bpmprocess/script.js

@@ -0,0 +1,18 @@
+import request from '@/utils/request'
+
+// 修改流程节点脚本
+export function updateScript(data) {
+    return request({
+      url: '/system/script',
+      method: 'put',
+      data: data
+    })
+  }
+  
+  // 删除流程节点脚本
+  export function delScript(id) {
+    return request({
+      url: '/system/script/' + id,
+      method: 'delete'
+    })
+  }

+ 15 - 5
ruoyi-ui/src/api/system/btn.js

@@ -7,7 +7,7 @@ export function listBtn(query) {
     url: '/system/btn/list',
     method: 'get',
     params: query,
-    baseURL:process.env.VUE_APP_BASE_API3
+    baseURL: process.env.VUE_APP_BASE_API3
   })
 }
 
@@ -16,7 +16,7 @@ export function getBtn(id) {
   return request({
     url: '/system/btn/' + id,
     method: 'get',
-    baseURL:process.env.VUE_APP_BASE_API3
+    baseURL: process.env.VUE_APP_BASE_API3
   })
 }
 
@@ -26,7 +26,7 @@ export function addBtn(data) {
     url: '/system/btn',
     method: 'post',
     data: data,
-    baseURL:process.env.VUE_APP_BASE_API3
+    baseURL: process.env.VUE_APP_BASE_API3
   })
 }
 
@@ -36,7 +36,7 @@ export function updateBtn(data) {
     url: '/system/btn',
     method: 'put',
     data: data,
-    baseURL:process.env.VUE_APP_BASE_API3
+    baseURL: process.env.VUE_APP_BASE_API3
   })
 }
 
@@ -45,6 +45,16 @@ export function delBtn(id) {
   return request({
     url: '/system/btn/' + id,
     method: 'delete',
-    baseURL:process.env.VUE_APP_BASE_API3
+    baseURL: process.env.VUE_APP_BASE_API3
+  })
+}
+
+// 查询按钮组绑定的表格
+export function checkBtn(btnKey) {
+  return request({
+    url: '/system/btn/checkBtn',
+    method: 'get',
+    params: btnKey,
+    baseURL: process.env.VUE_APP_BASE_API3
   })
 }

+ 1 - 1
ruoyi-ui/src/api/tablelist/commonTable.js

@@ -216,4 +216,4 @@ export function btnCommonApi(data) {
     data: data,
     baseURL: process.env.VUE_APP_BASE_API3
   })
-}
+}

+ 23 - 5
ruoyi-ui/src/components/kFormDesign/OptionsEdit.vue

@@ -24,7 +24,8 @@
         size="small"
         icon="el-icon-edit"
         @click="editHandler(index)"
-      ></el-button>
+        >第{{ index + 1 }}级选项
+      </el-button>
       <el-button
         circle
         type="danger"
@@ -48,7 +49,7 @@
         label-width="140px"
       >
         <el-row type="flex" style="flex-wrap: wrap">
-          <el-col :span="12">
+          <!-- <el-col :span="12">
             <el-form-item label="选项数据名" prop="dynamicName">
               <el-input
                 v-model="formData.dynamicName"
@@ -56,7 +57,7 @@
                 size="normal"
               ></el-input>
             </el-form-item>
-          </el-col>
+          </el-col> -->
           <el-col :span="12">
             <el-form-item label="表名" prop="tableName">
               <el-select
@@ -230,11 +231,12 @@
       </template>
     </el-dialog>
     <el-dialog title="编辑参照值" :visible.sync="flagShow" width="30%">
+      <!-- :rules="rules" -->
       <el-form
         :model="flagFormData"
         ref="flagFormDataRef"
-        :rules="rules"
         label-width="100px"
+        :rules="flagRules"
         :inline="false"
         size="normal"
       >
@@ -401,7 +403,22 @@ export default {
       ],
       tableList: [],
       fieldList: [],
-      rules: {},
+      rules: {
+        tableName: [
+          { required: true, message: "请选择表格名称", trigger: "change" },
+        ],
+        optLabelData: [
+          { required: true, message: "请选择描述字段", trigger: "change" },
+        ],
+        optValueData: [
+          { required: true, message: "请选择值字段", trigger: "change" },
+        ],
+      },
+      flagRules: {
+        flagType: [
+          { required: true, message: "请选择参照值类型", trigger: "change" },
+        ],
+      },
       constFlagList: [
         {
           value: "#{USERID}",
@@ -606,5 +623,6 @@ export default {
 }
 .btn-list {
   display: flex;
+  flex-wrap: wrap;
 }
 </style>

+ 0 - 779
ruoyi-ui/src/components/updateModule/bpmn-js/lib/BaseViewer.js

@@ -35,785 +35,6 @@ import {
   wrapForCompatibility
 } from './util/CompatibilityUtil';
 
-/**
- * A base viewer for BPMN 2.0 diagrams.
- *
- * Have a look at {@link Viewer}, {@link NavigatedViewer} or {@link Modeler} for
- * bundles that include actual features.
- *
- * @param {Object} [options] configuration options to pass to the viewer
- * @param {DOMElement} [options.container] the container to render the viewer in, defaults to body.
- * @param {string|number} [options.width] the width of the viewer
- * @param {string|number} [options.height] the height of the viewer
- * @param {Object} [options.moddleExtensions] extension packages to provide
- * @param {Array<didi.Module>} [options.modules] a list of modules to override the default modules
- * @param {Array<didi.Module>} [options.additionalModules] a list of modules to use with the default modules
- */
-export default function BaseViewer(options) {
-
-  options = assign({}, DEFAULT_OPTIONS, options);
-
-  this._moddle = this._createModdle(options);
-
-  this._container = this._createContainer(options);
-
-  /* <project-logo> */
-
-  // addProjectLogo(this._container);
-
-  /* </project-logo> */
-
-  this._init(this._container, this._moddle, options);
-}
-
-inherits(BaseViewer, Diagram);
-
-/**
-* The importXML result.
-*
-* @typedef {Object} ImportXMLResult
-*
-* @property {Array<string>} warnings
-*/
-
-/**
-* The importXML error.
-*
-* @typedef {Error} ImportXMLError
-*
-* @property {Array<string>} warnings
-*/
-
-/**
- * Parse and render a BPMN 2.0 diagram.
- *
- * Once finished the viewer reports back the result to the
- * provided callback function with (err, warnings).
- *
- * ## Life-Cycle Events
- *
- * During import the viewer will fire life-cycle events:
- *
- *   * import.parse.start (about to read model from xml)
- *   * import.parse.complete (model read; may have worked or not)
- *   * import.render.start (graphical import start)
- *   * import.render.complete (graphical import finished)
- *   * import.done (everything done)
- *
- * You can use these events to hook into the life-cycle.
- *
- * @param {string} xml the BPMN 2.0 xml
- * @param {ModdleElement<BPMNDiagram>|string} [bpmnDiagram] BPMN diagram or id of diagram to render (if not provided, the first one will be rendered)
- *
- * Returns {Promise<ImportXMLResult, ImportXMLError>}
- */
-BaseViewer.prototype.importXML = wrapForCompatibility(function importXML(xml, bpmnDiagram) {
-
-  var self = this;
-
-  function ParseCompleteEvent(data) {
-
-    var event = self.get('eventBus').createEvent(data);
-
-    // TODO(nikku): remove with future bpmn-js version
-    Object.defineProperty(event, 'context', {
-      enumerable: true,
-      get: function () {
-
-        console.warn(new Error(
-          'import.parse.complete <context> is deprecated ' +
-          'and will be removed in future library versions'
-        ));
-
-        return {
-          warnings: data.warnings,
-          references: data.references,
-          elementsById: data.elementsById
-        };
-      }
-    });
-
-    return event;
-  }
-
-  return new Promise(function (resolve, reject) {
-
-    // hook in pre-parse listeners +
-    // allow xml manipulation
-    xml = self._emit('import.parse.start', { xml: xml }) || xml;
-
-    self._moddle.fromXML(xml, 'bpmn:Definitions').then(function (result) {
-      var definitions = result.rootElement;
-      var references = result.references;
-      var parseWarnings = result.warnings;
-      var elementsById = result.elementsById;
-
-      // hook in post parse listeners +
-      // allow definitions manipulation
-      definitions = self._emit('import.parse.complete', ParseCompleteEvent({
-        error: null,
-        definitions: definitions,
-        elementsById: elementsById,
-        references: references,
-        warnings: parseWarnings
-      })) || definitions;
-
-      self.importDefinitions(definitions, bpmnDiagram).then(function (result) {
-        var allWarnings = [].concat(parseWarnings, result.warnings || []);
-
-        self._emit('import.done', { error: null, warnings: allWarnings });
-
-        return resolve({ warnings: allWarnings });
-      }).catch(function (err) {
-        var allWarnings = [].concat(parseWarnings, err.warnings || []);
-
-        self._emit('import.done', { error: err, warnings: allWarnings });
-
-        return reject(addWarningsToError(err, allWarnings));
-      });
-    }).catch(function (err) {
-
-      self._emit('import.parse.complete', {
-        error: err
-      });
-
-      err = checkValidationError(err);
-
-      self._emit('import.done', { error: err, warnings: err.warnings });
-
-      return reject(err);
-    });
-  });
-});
-
-/**
-* The importDefinitions result.
-*
-* @typedef {Object} ImportDefinitionsResult
-*
-* @property {Array<string>} warnings
-*/
-
-/**
-* The importDefinitions error.
-*
-* @typedef {Error} ImportDefinitionsError
-*
-* @property {Array<string>} warnings
-*/
-
-/**
- * Import parsed definitions and render a BPMN 2.0 diagram.
- *
- * Once finished the viewer reports back the result to the
- * provided callback function with (err, warnings).
- *
- * ## Life-Cycle Events
- *
- * During import the viewer will fire life-cycle events:
- *
- *   * import.render.start (graphical import start)
- *   * import.render.complete (graphical import finished)
- *
- * You can use these events to hook into the life-cycle.
- *
- * @param {ModdleElement<Definitions>} definitions parsed BPMN 2.0 definitions
- * @param {ModdleElement<BPMNDiagram>|string} [bpmnDiagram] BPMN diagram or id of diagram to render (if not provided, the first one will be rendered)
- *
- * Returns {Promise<ImportDefinitionsResult, ImportDefinitionsError>}
- */
-BaseViewer.prototype.importDefinitions = wrapForCompatibility(function importDefinitions(definitions, bpmnDiagram) {
-
-  var self = this;
-
-  return new Promise(function (resolve, reject) {
-
-    self._setDefinitions(definitions);
-
-    self.open(bpmnDiagram).then(function (result) {
-
-      var warnings = result.warnings;
-
-      return resolve({ warnings: warnings });
-    }).catch(function (err) {
-
-      return reject(err);
-    });
-  });
-});
-
-/**
- * The open result.
- *
- * @typedef {Object} OpenResult
- *
- * @property {Array<string>} warnings
- */
-
-/**
-* The open error.
-*
-* @typedef {Error} OpenError
-*
-* @property {Array<string>} warnings
-*/
-
-/**
- * Open diagram of previously imported XML.
- *
- * Once finished the viewer reports back the result to the
- * provided callback function with (err, warnings).
- *
- * ## Life-Cycle Events
- *
- * During switch the viewer will fire life-cycle events:
- *
- *   * import.render.start (graphical import start)
- *   * import.render.complete (graphical import finished)
- *
- * You can use these events to hook into the life-cycle.
- *
- * @param {string|ModdleElement<BPMNDiagram>} [bpmnDiagramOrId] id or the diagram to open
- *
- * Returns {Promise<OpenResult, OpenError>}
- */
-BaseViewer.prototype.open = wrapForCompatibility(function open(bpmnDiagramOrId) {
-
-  var definitions = this._definitions;
-  var bpmnDiagram = bpmnDiagramOrId;
-
-  var self = this;
-
-  return new Promise(function (resolve, reject) {
-    if (!definitions) {
-      var err1 = new Error('no XML imported');
-
-      return reject(addWarningsToError(err1, []));
-    }
-
-    if (typeof bpmnDiagramOrId === 'string') {
-      bpmnDiagram = findBPMNDiagram(definitions, bpmnDiagramOrId);
-
-      if (!bpmnDiagram) {
-        var err2 = new Error('BPMNDiagram <' + bpmnDiagramOrId + '> not found');
-
-        return reject(addWarningsToError(err2, []));
-      }
-    }
-
-    // clear existing rendered diagram
-    // catch synchronous exceptions during #clear()
-    try {
-      self.clear();
-    } catch (error) {
-
-      return reject(addWarningsToError(error, []));
-    }
-
-    // perform graphical import
-    importBpmnDiagram(self, definitions, bpmnDiagram).then(function (result) {
-
-      var warnings = result.warnings;
-
-      return resolve({ warnings: warnings });
-    }).catch(function (err) {
-
-      return reject(err);
-    });
-  });
-});
-
-/**
- * The saveXML result.
- *
- * @typedef {Object} SaveXMLResult
- *
- * @property {string} xml
- */
-
-/**
- * Export the currently displayed BPMN 2.0 diagram as
- * a BPMN 2.0 XML document.
- *
- * ## Life-Cycle Events
- *
- * During XML saving the viewer will fire life-cycle events:
- *
- *   * saveXML.start (before serialization)
- *   * saveXML.serialized (after xml generation)
- *   * saveXML.done (everything done)
- *
- * You can use these events to hook into the life-cycle.
- *
- * @param {Object} [options] export options
- * @param {boolean} [options.format=false] output formatted XML
- * @param {boolean} [options.preamble=true] output preamble
- *
- * Returns {Promise<SaveXMLResult, Error>}
- */
-BaseViewer.prototype.saveXML = wrapForCompatibility(function saveXML(options) {
-
-  options = options || {};
-
-  var self = this;
-
-  var definitions = this._definitions;
-
-  return new Promise(function (resolve) {
-
-    if (!definitions) {
-      return resolve({
-        error: new Error('no definitions loaded')
-      });
-    }
-
-    // allow to fiddle around with definitions
-    definitions = self._emit('saveXML.start', {
-      definitions: definitions
-    }) || definitions;
-
-    self._moddle.toXML(definitions, options).then(function (result) {
-
-      var xml = result.xml;
-
-      xml = self._emit('saveXML.serialized', {
-        xml: xml
-      }) || xml;
-
-      return resolve({
-        xml: xml
-      });
-    });
-  }).catch(function (error) {
-    return { error: error };
-  }).then(function (result) {
-
-    self._emit('saveXML.done', result);
-
-    var error = result.error;
-
-    if (error) {
-      return Promise.reject(error);
-    }
-
-    return result;
-  });
-});
-
-/**
- * The saveSVG result.
- *
- * @typedef {Object} SaveSVGResult
- *
- * @property {string} svg
- */
-
-/**
- * Export the currently displayed BPMN 2.0 diagram as
- * an SVG image.
- *
- * ## Life-Cycle Events
- *
- * During SVG saving the viewer will fire life-cycle events:
- *
- *   * saveSVG.start (before serialization)
- *   * saveSVG.done (everything done)
- *
- * You can use these events to hook into the life-cycle.
- *
- * @param {Object} [options]
- *
- * Returns {Promise<SaveSVGResult, Error>}
- */
-BaseViewer.prototype.saveSVG = wrapForCompatibility(function saveSVG(options) {
-
-  options = options || {};
-
-  var self = this;
-
-  return new Promise(function (resolve, reject) {
-
-    self._emit('saveSVG.start');
-
-    var svg, err;
-
-    try {
-      var canvas = self.get('canvas');
-
-      var contentNode = canvas.getActiveLayer(),
-        defsNode = domQuery('defs', canvas._svg);
-
-      var contents = innerSVG(contentNode),
-        defs = defsNode ? '<defs>' + innerSVG(defsNode) + '</defs>' : '';
-
-      var bbox = contentNode.getBBox();
-
-      svg =
-        '<?xml version="1.0" encoding="utf-8"?>\n' +
-        '<!-- created with bpmn-js / http://bpmn.io -->\n' +
-        '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n' +
-        '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" ' +
-        'width="' + bbox.width + '" height="' + bbox.height + '" ' +
-        'viewBox="' + bbox.x + ' ' + bbox.y + ' ' + bbox.width + ' ' + bbox.height + '" version="1.1">' +
-        defs + contents +
-        '</svg>';
-    } catch (e) {
-      err = e;
-    }
-
-    self._emit('saveSVG.done', {
-      error: err,
-      svg: svg
-    });
-
-    if (!err) {
-      return resolve({ svg: svg });
-    }
-
-    return reject(err);
-  });
-});
-
-/**
- * Get a named diagram service.
- *
- * @example
- *
- * var elementRegistry = viewer.get('elementRegistry');
- * var startEventShape = elementRegistry.get('StartEvent_1');
- *
- * @param {string} name
- *
- * @return {Object} diagram service instance
- *
- * @method BaseViewer#get
- */
-
-/**
- * Invoke a function in the context of this viewer.
- *
- * @example
- *
- * viewer.invoke(function(elementRegistry) {
- *   var startEventShape = elementRegistry.get('StartEvent_1');
- * });
- *
- * @param {Function} fn to be invoked
- *
- * @return {Object} the functions return value
- *
- * @method BaseViewer#invoke
- */
-
-
-BaseViewer.prototype._setDefinitions = function (definitions) {
-  this._definitions = definitions;
-};
-
-BaseViewer.prototype.getModules = function () {
-  return this._modules;
-};
-
-/**
- * Remove all drawn elements from the viewer.
- *
- * After calling this method the viewer can still
- * be reused for opening another diagram.
- *
- * @method BaseViewer#clear
- */
-BaseViewer.prototype.clear = function () {
-  if (!this.getDefinitions()) {
-
-    // no diagram to clear
-    return;
-  }
-
-  // remove drawn elements
-  Diagram.prototype.clear.call(this);
-};
-
-/**
- * Destroy the viewer instance and remove all its
- * remainders from the document tree.
- */
-BaseViewer.prototype.destroy = function () {
-
-  // diagram destroy
-  Diagram.prototype.destroy.call(this);
-
-  // dom detach
-  domRemove(this._container);
-};
-
-/**
- * Register an event listener
- *
- * Remove a previously added listener via {@link #off(event, callback)}.
- *
- * @param {string} event
- * @param {number} [priority]
- * @param {Function} callback
- * @param {Object} [that]
- */
-BaseViewer.prototype.on = function (event, priority, callback, target) {
-  return this.get('eventBus').on(event, priority, callback, target);
-};
-
-/**
- * De-register an event listener
- *
- * @param {string} event
- * @param {Function} callback
- */
-BaseViewer.prototype.off = function (event, callback) {
-  this.get('eventBus').off(event, callback);
-};
-
-BaseViewer.prototype.attachTo = function (parentNode) {
-
-  if (!parentNode) {
-    throw new Error('parentNode required');
-  }
-
-  // ensure we detach from the
-  // previous, old parent
-  this.detach();
-
-  // unwrap jQuery if provided
-  if (parentNode.get && parentNode.constructor.prototype.jquery) {
-    parentNode = parentNode.get(0);
-  }
-
-  if (typeof parentNode === 'string') {
-    parentNode = domQuery(parentNode);
-  }
-
-  parentNode.appendChild(this._container);
-
-  this._emit('attach', {});
-
-  this.get('canvas').resized();
-};
-
-BaseViewer.prototype.getDefinitions = function () {
-  return this._definitions;
-};
-
-BaseViewer.prototype.detach = function () {
-
-  var container = this._container,
-    parentNode = container.parentNode;
-
-  if (!parentNode) {
-    return;
-  }
-
-  this._emit('detach', {});
-
-  parentNode.removeChild(container);
-};
-
-BaseViewer.prototype._init = function (container, moddle, options) {
-
-  var baseModules = options.modules || this.getModules(),
-    additionalModules = options.additionalModules || [],
-    staticModules = [
-      {
-        bpmnjs: ['value', this],
-        moddle: ['value', moddle]
-      }
-    ];
-
-  var diagramModules = [].concat(staticModules, baseModules, additionalModules);
-
-  var diagramOptions = assign(omit(options, ['additionalModules']), {
-    canvas: assign({}, options.canvas, { container: container }),
-    modules: diagramModules
-  });
-
-  // invoke diagram constructor
-  Diagram.call(this, diagramOptions);
-
-  if (options && options.container) {
-    this.attachTo(options.container);
-  }
-};
-
-/**
- * Emit an event on the underlying {@link EventBus}
- *
- * @param  {string} type
- * @param  {Object} event
- *
- * @return {Object} event processing result (if any)
- */
-BaseViewer.prototype._emit = function (type, event) {
-  return this.get('eventBus').fire(type, event);
-};
-
-BaseViewer.prototype._createContainer = function (options) {
-
-  var container = domify('<div class="bjs-container"></div>');
-
-  assignStyle(container, {
-    width: ensureUnit(options.width),
-    height: ensureUnit(options.height),
-    position: options.position
-  });
-
-  return container;
-};
-
-BaseViewer.prototype._createModdle = function (options) {
-  var moddleOptions = assign({}, this._moddleExtensions, options.moddleExtensions);
-
-  return new BpmnModdle(moddleOptions);
-};
-
-BaseViewer.prototype._modules = [];
-
-// helpers ///////////////
-
-function addWarningsToError(err, warningsAry) {
-  err.warnings = warningsAry;
-  return err;
-}
-
-function checkValidationError(err) {
-
-  // check if we can help the user by indicating wrong BPMN 2.0 xml
-  // (in case he or the exporting tool did not get that right)
-
-  var pattern = /unparsable content <([^>]+)> detected([\s\S]*)$/;
-  var match = pattern.exec(err.message);
-
-  if (match) {
-    err.message =
-      'unparsable content <' + match[1] + '> detected; ' +
-      'this may indicate an invalid BPMN 2.0 diagram file' + match[2];
-  }
-
-  return err;
-}
-
-var DEFAULT_OPTIONS = {
-  width: '100%',
-  height: '100%',
-  position: 'relative'
-};
-
-
-/**
- * Ensure the passed argument is a proper unit (defaulting to px)
- */
-function ensureUnit(val) {
-  return val + (isNumber(val) ? 'px' : '');
-}
-
-
-/**
- * Find BPMNDiagram in definitions by ID
- *
- * @param {ModdleElement<Definitions>} definitions
- * @param {string} diagramId
- *
- * @return {ModdleElement<BPMNDiagram>|null}
- */
-function findBPMNDiagram(definitions, diagramId) {
-  if (!diagramId) {
-    return null;
-  }
-
-  return find(definitions.diagrams, function (element) {
-    return element.id === diagramId;
-  }) || null;
-}
-
-
-/* <project-logo> */
-
-import {
-  open as openPoweredBy,
-  BPMNIO_IMG,
-  LOGO_STYLES,
-  LINK_STYLES
-} from './util/PoweredByUtil';
-
-import {
-  event as domEvent
-} from 'min-dom';
-
-/**
- * Adds the project logo to the diagram container as
- * required by the bpmn.io license.
- *
- * @see http://bpmn.io/license
- *
- * @param {Element} container
- */
-function addProjectLogo(container) {
-  var img = BPMNIO_IMG;
-
-  var linkMarkup = '';
-
-  var linkElement = domify(linkMarkup);
-
-  assignStyle(domQuery('svg', linkElement), LOGO_STYLES);
-  assignStyle(linkElement, LINK_STYLES, {
-    position: 'absolute',
-    bottom: '15px',
-    right: '15px',
-    zIndex: '100'
-  });
-
-  container.appendChild(linkElement);
-
-  domEvent.bind(linkElement, 'click', function (event) {
-    openPoweredBy();
-
-    event.preventDefault();
-  });
-}
-
-/* </project-logo> */
-/**
- * The code in the <project-logo></project-logo> area
- * must not be changed.
- *
- * @see http://bpmn.io/license for more information.
- */
-import {
-  assign,
-  find,
-  isNumber,
-  omit
-} from 'min-dash';
-
-import {
-  domify,
-  assignStyle,
-  query as domQuery,
-  remove as domRemove
-} from 'min-dom';
-
-import {
-  innerSVG
-} from 'tiny-svg';
-
-import Diagram from 'diagram-js';
-import BpmnModdle from 'bpmn-moddle';
-
-import inherits from 'inherits-browser';
-
-import {
-  importBpmnDiagram
-} from './import/Importer';
-
-import {
-  wrapForCompatibility
-} from './util/CompatibilityUtil';
-
 /**
  * A base viewer for BPMN 2.0 diagrams.
  *

+ 17 - 16
ruoyi-ui/src/components/updateModule/bpmn-js/lib/features/modeling/BpmnFactory.js

@@ -11,16 +11,16 @@ import {
 import {
   is
 } from '../../util/ModelUtil';
-
+import { v4 as uuidv4 } from "uuid";
 
 export default function BpmnFactory(moddle) {
   this._model = moddle;
 }
 
-BpmnFactory.$inject = [ 'moddle' ];
+BpmnFactory.$inject = ['moddle'];
 
 
-BpmnFactory.prototype._needsId = function(element) {
+BpmnFactory.prototype._needsId = function (element) {
   return isAny(element, [
     'bpmn:RootElement',
     'bpmn:FlowElement',
@@ -41,7 +41,7 @@ BpmnFactory.prototype._needsId = function(element) {
   ]);
 };
 
-BpmnFactory.prototype._ensureId = function(element) {
+BpmnFactory.prototype._ensureId = function (element) {
   if (element.id) {
     this._model.ids.claim(element.id, element);
     return;
@@ -57,7 +57,7 @@ BpmnFactory.prototype._ensureId = function(element) {
     prefix = 'Event';
   } else if (is(element, 'bpmn:Gateway')) {
     prefix = 'Gateway';
-  } else if (isAny(element, [ 'bpmn:SequenceFlow', 'bpmn:MessageFlow' ])) {
+  } else if (isAny(element, ['bpmn:SequenceFlow', 'bpmn:MessageFlow'])) {
     prefix = 'Flow';
   } else {
     prefix = (element.$type || '').replace(/^[^:]*:/g, '');
@@ -66,12 +66,13 @@ BpmnFactory.prototype._ensureId = function(element) {
   prefix += '_';
 
   if (!element.id && this._needsId(element)) {
-    element.id = this._model.ids.nextPrefixed(prefix, element);
+    // element.id = this._model.ids.nextPrefixed(prefix, element);
+    element.id = prefix + uuidv4();
   }
 };
 
 
-BpmnFactory.prototype.create = function(type, attrs) {
+BpmnFactory.prototype.create = function (type, attrs) {
   var element = this._model.create(type, attrs || {});
 
   this._ensureId(element);
@@ -80,14 +81,14 @@ BpmnFactory.prototype.create = function(type, attrs) {
 };
 
 
-BpmnFactory.prototype.createDiLabel = function() {
+BpmnFactory.prototype.createDiLabel = function () {
   return this.create('bpmndi:BPMNLabel', {
     bounds: this.createDiBounds()
   });
 };
 
 
-BpmnFactory.prototype.createDiShape = function(semantic, attrs) {
+BpmnFactory.prototype.createDiShape = function (semantic, attrs) {
   return this.create('bpmndi:BPMNShape', assign({
     bpmnElement: semantic,
     bounds: this.createDiBounds()
@@ -95,32 +96,32 @@ BpmnFactory.prototype.createDiShape = function(semantic, attrs) {
 };
 
 
-BpmnFactory.prototype.createDiBounds = function(bounds) {
+BpmnFactory.prototype.createDiBounds = function (bounds) {
   return this.create('dc:Bounds', bounds);
 };
 
 
-BpmnFactory.prototype.createDiWaypoints = function(waypoints) {
+BpmnFactory.prototype.createDiWaypoints = function (waypoints) {
   var self = this;
 
-  return map(waypoints, function(pos) {
+  return map(waypoints, function (pos) {
     return self.createDiWaypoint(pos);
   });
 };
 
-BpmnFactory.prototype.createDiWaypoint = function(point) {
-  return this.create('dc:Point', pick(point, [ 'x', 'y' ]));
+BpmnFactory.prototype.createDiWaypoint = function (point) {
+  return this.create('dc:Point', pick(point, ['x', 'y']));
 };
 
 
-BpmnFactory.prototype.createDiEdge = function(semantic, attrs) {
+BpmnFactory.prototype.createDiEdge = function (semantic, attrs) {
   return this.create('bpmndi:BPMNEdge', assign({
     bpmnElement: semantic,
     waypoint: this.createDiWaypoints([])
   }, attrs));
 };
 
-BpmnFactory.prototype.createDiPlane = function(semantic, attrs) {
+BpmnFactory.prototype.createDiPlane = function (semantic, attrs) {
   return this.create('bpmndi:BPMNPlane', assign({
     bpmnElement: semantic
   }, attrs));

+ 36 - 1
ruoyi-ui/src/utils/bpmn/getNodeSequence.js

@@ -1,4 +1,4 @@
-
+import { getProcessEngine } from "@packages/bpmn-utils/BpmnDesignerUtils";
 export default function getNodeSequence(xmlObj) {
   if (!xmlObj.childNodes[0].childNodes[0]) return [];
   let nodeList = Array.from(xmlObj.childNodes[0].childNodes[0].childNodes)
@@ -13,6 +13,7 @@ export default function getNodeSequence(xmlObj) {
     nodeId: startNode.id,
     preNodeId: null,
     nextNodeId: nextNodeId,
+    nodeInfo: getNodeInfo(startNode.id, nodeList)
   })
   while (nextNodeId) {
     if (!nextNodeId) break
@@ -25,6 +26,7 @@ export default function getNodeSequence(xmlObj) {
         nodeId: currentId,
         preNodeId,
         nextNodeId,
+        nodeInfo: getNodeInfo(currentId, nodeList)
       }
     )
   }
@@ -47,3 +49,36 @@ const getNodeId = (node, flag, nodeList) => {
   if (!targetId) return false;
   return targetId;
 }
+
+/**
+ * 
+ * @param {节点Id} nodeId 
+ * @param {节点列表} nodeList 
+ */
+function getNodeInfo(nodeId, nodeList) {
+  let targetNode = nodeList.find(item => item.id == nodeId)
+  let prefix = getProcessEngine() + ':';
+  let id = targetNode.getAttribute('id')
+  let localName = targetNode.localName
+  let name = targetNode.getAttribute('name');
+  let nodeDescription = targetNode.getAttribute(prefix + 'nodeDescription')
+  let industryType = targetNode.getAttribute(prefix + 'IndustryType')
+  let normalScriptKey = targetNode.getAttribute(prefix + 'NormalScriptKey')
+  let normalScriptTriggerType = targetNode.getAttribute(prefix + 'NormalScriptTriggerType')
+  let executeUserType = targetNode.getAttribute(prefix + 'executeUserType')
+  let executeUser = targetNode.getAttribute(prefix + 'executeUser');
+  let virtuallyRole = targetNode.getAttribute(prefix + 'virtuallyRole')
+  let res = {
+    localName,//节点类型
+    id,//节点ID
+    name,//节点名称
+    nodeDescription,//节点表述
+    industryType,
+    normalScriptKey,//正常节点key
+    normalScriptTriggerType,//正常节点触发类型
+    executeUserType,//执行用户类型
+    executeUser,//执行用户
+    virtuallyRole,//虚拟角色
+  };
+  return res
+}

+ 13 - 0
ruoyi-ui/src/utils/bpmn/xml.js

@@ -31,3 +31,16 @@ export async function createNewDiagram(modeler, newXml, settings) {
     catchError(e);
   }
 }
+
+// xml字符串转xml对象
+export function xmlStr2XmlObj(xmlStr) {
+  var xmlObj = {};
+  if (document.all) {
+    var xmlDom = new ActiveXObject("Microsoft.XMLDOM");
+    xmlDom.loadXML(xmlStr);
+    xmlObj = xmlDom;
+  } else {
+    xmlObj = new DOMParser().parseFromString(xmlStr, "text/xml");
+  }
+  return xmlObj;
+}

+ 4 - 0
ruoyi-ui/src/utils/index.js

@@ -406,6 +406,10 @@ export function titleCase(str) {
 export function camelCase(str = '') {
   return str.replace(/_[a-z]/g, str1 => str1.substr(-1).toUpperCase())
 }
+// 驼峰转下划线
+export function toUnderline(str = '') {
+  return str.replace(/([A-Z])/g, '_$1').toLowerCase()
+}
 
 export function isNumberStr(str) {
   return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str)

+ 8 - 8
ruoyi-ui/src/views/bpmprocess/scriptManage.vue

@@ -173,6 +173,7 @@
  
         <el-form-item label="脚本编码:" prop="scriptKey">
           <el-input v-model="form.scriptKey" placeholder="请输入脚本编码" :disabled="true"/>
+          <el-button icon="el-icon-document-copy"></el-button>
         </el-form-item>
         <el-form-item label="脚本名称:" prop="scriptName">
           <el-input v-model="form.scriptName" placeholder="请输入脚本名称" />
@@ -252,10 +253,9 @@
 import {
   listScript,
   getScript,
-  delScript,
   addScript,
-  updateScript,
 } from "@/api/bpmprocess/process";
+import {updateScript,delScript} from "@/api/bpmprocess/script"
 import uuid from "@/utils/bpmn/uuid";
 import Editor from "vue2-ace-editor";
 import {v4 as uuidv4} from 'uuid';
@@ -306,12 +306,12 @@ export default {
         scriptName: [
           { required: true, message: "请输入脚本名称", trigger: "blur" },
         ],
-        scriptFunctionName: [
-          { required: true, message: "请输入脚本函数名", trigger: "blur" },
-        ],
-        scriptFunctionCode: [
-          { required: true, message: "请输入脚本函数体", trigger: "blur" },
-        ],
+        // scriptFunctionName: [
+        //   { required: true, message: "请输入脚本函数名", trigger: "blur" },
+        // ],
+        // scriptFunctionCode: [
+        //   { required: true, message: "请输入脚本函数体", trigger: "blur" },
+        // ],
         scriptType: [
           { required: true, message: "请选择脚本类型", trigger: "change" },
         ],

+ 51 - 10
ruoyi-ui/src/views/bussiness/components/TaskItem.vue

@@ -1,20 +1,28 @@
 <template>
-  <div class="task-item-wrap">
+  <div
+    :class="{
+      'task-item-wrap': true,
+      'done-bg': cardData.isDone,
+      'now-border': cardData.isNow,
+    }"
+  >
     <div class="task-title">
-      <span>{{ itemData.index }}.</span>
-      <span>工艺校验</span>
+      <span class="mr5">{{ number }}.</span>
+      <span>{{ cardData.nodeInfo.name }}</span>
     </div>
     <div class="msg-list">
       <div class="msg-item">
-        <i class="el-icon-user-solid icon"></i>
-        <span>admin</span>
+        <i class="el-icon-s-tools icon"></i>
+        <span>{{ cardData.nodeInfo.name || "未命名节点" }}</span>
       </div>
       <div class="msg-item">
         <i class="el-icon-s-help icon"></i>
-        <span>任务类</span>
+        <span>{{ cardData.nodeInfo.localName || "未知类型" }}</span>
       </div>
       <div class="msg-item">
-        <i class="el-icon-success icon"></i>
+        <i v-if="cardData.isNow" class="el-icon-loading icon"></i>
+        <i v-else-if="cardData.isDone" class="el-icon-success icon"></i>
+        <i v-else class="el-icon-more icon"></i>
         <!-- <span>admin</span> -->
       </div>
     </div>
@@ -27,19 +35,46 @@ export default {
   props: ["itemData", "index"],
   components: {},
   data() {
-    return {};
+    return {
+      cardData: {},
+      number: "",
+    };
+  },
+  watch: {
+    myItemData: {
+      handler(nval) {
+        this.cardData = nval;
+      },
+      deep: true,
+      immediate: true,
+    },
+    myIndex: {
+      handler(nval) {
+        this.number = nval;
+      },
+      deep: true,
+      immediate: true,
+    },
+  },
+  computed: {
+    myItemData() {
+      return this.itemData;
+    },
+    myIndex() {
+      return this.index;
+    },
   },
-  computed: {},
   methods: {},
 };
 </script>
 
 <style scoped lang="scss">
 .task-item-wrap {
-  background-color: #cdf1e5 !important;
   padding: 12px 16px;
+  height: 130px;
   flex: 1;
   box-sizing: border-box;
+  background-color: #ebe6e6;
   // margin-right: 15px;
   .task-title {
     font-size: 14px;
@@ -58,4 +93,10 @@ export default {
     }
   }
 }
+.done-bg {
+  background-color: #cdf1e5 !important;
+}
+.now-border {
+  border: 5px solid rgb(167, 238, 171) !important;
+}
 </style>

+ 28 - 12
ruoyi-ui/src/views/bussiness/components/taskList.vue

@@ -3,23 +3,26 @@
     <div class="title-list">
       <div class="title-item">
         <span class="title-label">任务号:</span>
-        <span class="title-content">47AS04-51-1299_002</span>
+        <span class="title-content">{{ baseInfo.benTaskProcessKey }}</span>
       </div>
-      <div class="title-item">
+      <!-- <div class="title-item">
         <span class="title-label">图号:</span>
         <span class="title-content">1CG312-99</span>
-      </div>
+      </div> -->
       <div class="title-item">
         <span class="title-label">任务名称:</span>
-        <span class="title-content">支架</span>
+        <span class="title-content">{{ baseInfo.bepTaskName }}</span>
       </div>
-      <div class="title-item">
+      <!-- <div class="title-item">
         <span class="title-label">数量:</span>
         <span class="title-content">3</span>
-      </div>
+      </div> -->
       <div class="title-item">
-        <span class="title-label">完成时间:</span>
-        <span class="title-content">2023年11月1日</span>
+        <!-- <span class="title-label">完成时间:</span> -->
+        <span class="title-label">开始时间:</span>
+        <span class="title-content">{{
+          baseInfo.benCreateTime.replace("T", " ")
+        }}</span>
       </div>
     </div>
     <div class="card-list-wrap">
@@ -30,7 +33,7 @@
         <TaskItem
           class="card-item"
           v-for="(item, index) of tempList"
-          :key="item.taskKey"
+          :key="item.nodeId"
           :itemData="item"
           :index="index + 1"
         ></TaskItem>
@@ -48,10 +51,11 @@ import TaskItem from "./TaskItem.vue";
 import { start } from "nprogress";
 export default {
   name: "TaskList",
-  props: [],
+  props: ["cardData"],
   components: { TaskItem },
   data() {
     return {
+      baseInfo: {},
       start: 0,
       end: 5,
       taskItemList: [
@@ -140,13 +144,25 @@ export default {
   },
   computed: {
     tempList() {
-      return this.taskItemList.slice(this.start, this.end);
+      return this.baseInfo?.cardList.slice(this.start, this.end);
+    },
+    myCardData() {
+      return this.cardData;
+    },
+  },
+  watch: {
+    myCardData: {
+      handler(nval) {
+        this.baseInfo = nval;
+      },
+      deep: true,
+      immediate: true,
     },
   },
   methods: {
     prevOrNext(flag) {
       if (flag == 1) {
-        if (this.end >= this.taskItemList.length) return;
+        if (this.end >= this.baseInfo?.cardList.length) return;
         this.start++;
         this.end++;
       } else {

+ 74 - 0
ruoyi-ui/src/views/bussiness/dialogCompments/GY1.vue

@@ -0,0 +1,74 @@
+<template>
+  <div class="form-wrap">
+    <el-form
+      :model="form"
+      ref="form"
+      :rules="rules"
+      label-width="100px"
+      :inline="false"
+      size="normal"
+    >
+      <el-form-item prop="name" label="姓名:">
+        <el-input v-model="form.name"></el-input>
+      </el-form-item>
+      <el-form-item prop="number" label="运行数量:">
+        <el-input v-model="form.number"></el-input>
+      </el-form-item>
+      <el-form-item prop="remark" label="备注信息:">
+        <el-input v-model="form.remark"></el-input>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "GY1",
+  props: [],
+  components: {},
+  data() {
+    return {
+      form: {
+        name: "",
+        number: "",
+        remark: "",
+      },
+      rules: {
+        name: [{ required: true, message: "请输入姓名", trigger: "blur" }],
+        number: [
+          { required: true, message: "请输入运行数量", trigger: "blur" },
+        ],
+        remark: [
+          { required: true, message: "请输入备注信息", trigger: "blur" },
+        ],
+      },
+    };
+  },
+  computed: {},
+  methods: {
+    async getFormData() {
+      let formData = {
+        flag: false,
+        msg: "",
+      };
+      try {
+        let valid = await this.$refs.form.validate();
+        if (valid) {
+          formData.flag = true;
+          formData.data = this.form;
+          return formData;
+        } else {
+          formData.msg = "表单校验异常,请规范填写表单数据";
+          return formData;
+        }
+      } catch (error) {
+        // console.log(error);
+        formData.msg = "表单校验异常,请规范填写表单数据";
+        return formData;
+      }
+    },
+  },
+};
+</script>
+
+<style scoped></style>

+ 276 - 4
ruoyi-ui/src/views/bussiness/processMange.vue

@@ -47,30 +47,291 @@
           </div>
           <div class="search-input">
             <el-input placeholder="请输入..." v-model="queryString">
-              <el-button slot="append" icon="el-icon-search"></el-button>
+              <el-button
+                slot="append"
+                icon="el-icon-search"
+                @click="getList"
+              ></el-button>
             </el-input>
           </div>
         </div>
       </div>
-      <div class="show-body"></div>
+      <div class="show-body">
+        <!--    流程任务列表    -->
+        <el-table :data="tableData" border stripe>
+          <el-table-column type="selection" width="55" align="center" />
+          <el-table-column type="index" width="50" align="center" />
+          <el-table-column
+            v-for="col in columns"
+            :prop="col.prop"
+            :key="col.prop"
+            :label="col.label"
+            align="center"
+          >
+            <template slot-scope="scope">
+              <span v-if="col.prop == 'benCreateTime'">{{
+                scope.row.benCreateTime.replace("T", " ")
+              }}</span>
+              <span v-else-if="col.prop == 'bepTaskProcessType'">{{
+                getDictLabel(scope.row.bepTaskProcessType, dict.type.bpm_type)
+              }}</span>
+              <span v-else-if="col.prop == 'benTaskNodeState'">{{
+                scope.row.benTaskNodeState == "0" ? "已执行" : "未执行"
+              }}</span>
+              <span v-else>{{ scope.row[col.prop] }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="操作" align="center">
+            <template slot-scope="scope">
+              <div class="excute-wrap">
+                <el-button
+                  type="warning"
+                  plain
+                  size="small"
+                  class="mr10 mb5"
+                  @click="opneExecuteNode(scope.row)"
+                >
+                  运行
+                </el-button>
+                <el-dropdown>
+                  <el-button type="warning" plain size="small">
+                    处理<i class="el-icon-arrow-down el-icon--right"></i>
+                  </el-button>
+                  <el-dropdown-menu slot="dropdown">
+                    <!-- <el-dropdown-item>
+                      <el-button
+                        size="mini"
+                        type="text"
+                        icon="el-icon-edit"
+                        @click="excuteHandler(scope.row)"
+                        v-hasPermi="['system:user:edit']"
+                      >处理
+                      </el-button>
+                    </el-dropdown-item> -->
+                    <el-dropdown-item>
+                      <el-dropdown
+                        size="mini"
+                        @command="
+                          (command) => handleCommand(command, scope.row)
+                        "
+                      >
+                        <el-button
+                          size="mini"
+                          type="text"
+                          icon="el-icon-d-arrow-right"
+                          >触发异常
+                        </el-button>
+                        <el-dropdown-menu slot="dropdown"> </el-dropdown-menu>
+                      </el-dropdown>
+                    </el-dropdown-item>
+                  </el-dropdown-menu>
+                </el-dropdown>
+              </div>
+            </template>
+          </el-table-column>
+        </el-table>
+        <!--    分页    -->
+        <pagination
+          v-show="total > 0"
+          :total="total"
+          :page.sync="queryParams.pageNum"
+          :limit.sync="queryParams.pageSize"
+          @pagination="getList"
+        />
+      </div>
+      <div class="show-window">
+        <!-- 运行节点弹窗 -->
+        <el-dialog :title="nodeTitle" :visible.sync="open" width="50%">
+          <!-- <el-form label-width="100px" :model="commonData">
+            <h1>这里会引入当前节点需要处理的表单</h1>
+          </el-form> -->
+          <component v-if="myForm" :is="myForm" ref="myFormRef"></component>
+          <span slot="footer" class="dialog-footer">
+            <el-button @click="closeExecuteNode">取消</el-button>
+            <el-button type="primary" @click="executeNode">运行</el-button>
+          </span>
+        </el-dialog>
+      </div>
     </div>
   </div>
 </template>
 
 <script>
+import {
+  processList,
+  runProcessNodeExecution,
+} from "@/api/bpmprocess/run/executeProcess";
+import getNodeSequence from "@/utils/bpmn/getNodeSequence";
+import GY1 from "./dialogCompments/GY1.vue";
+
 export default {
   name: "processMange",
   props: [],
-  components: {},
+  components: { GY1 },
+  dicts: ["bpm_type"],
   data() {
     return {
+      row: {}, //当前操作行数据
+      myForm: "", //自定义表单组件名
+      // 节点弹窗title
+      nodeTitle: "节点弹窗",
+      open: false,
+      // 节点弹窗对应的formData
+      commonData: {},
       taskType: 1,
       queryString: "",
       taskStatus: 3,
+      tableData: [], //表格数据
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+      },
+      total: 0,
+      columns: [
+        {
+          prop: "bepTaskKey",
+          label: "任务编号",
+        },
+        {
+          prop: "bepTaskName",
+          label: "任务名称",
+        },
+        {
+          prop: "bepTaskProcessType",
+          label: "任务流程类型",
+        },
+        {
+          prop: "bepTaskProcessState",
+          label: "任务流程状态",
+        },
+        {
+          prop: "benTaskNodeName",
+          label: "节点名称",
+        },
+        {
+          prop: "benTaskNodeType",
+          label: "节点类型",
+        },
+        {
+          prop: "benTaskNodeState",
+          label: "节点状态",
+        },
+        {
+          prop: "benCreateBy",
+          label: "创建人",
+        },
+        {
+          prop: "benCreateTime",
+          label: "创建时间",
+        },
+      ],
     };
   },
   computed: {},
-  methods: {},
+  mounted() {
+    this.getList();
+  },
+  methods: {
+    // 获取列表数据
+    getList() {
+      processList(this.queryParams).then((res) => {
+        console.log(res);
+        if (res.code == 200) {
+          this.tableData = res.rows.map((item) => item.resultMap);
+          this.total = res.total;
+          console.log(this.tableData);
+        } else {
+          this.$message.error("网络异常,请稍后再试");
+        }
+      });
+    },
+    // 打开运行节点弹窗
+    opneExecuteNode(row) {
+      console.log(row);
+      this.myForm = row.benTaskNodeName.split("-")[0];
+      this.row = row; //记录当前行数据
+      this.open = true; // 打开弹窗
+      // 根据当前节点绑定的表单信息查询对应的表单进行展示
+    },
+    // 运行节点按钮
+    async executeNode() {
+      console.log(this.row);
+      let { benTaskNodeKey, bepTaskProcessXmlContent, implementationName } =
+        this.row;
+      let { nodeId, nextNodeId } = this.getNextNodeKey(
+        benTaskNodeKey,
+        bepTaskProcessXmlContent
+      );
+      let formData = {};
+      if (this.$refs.myFormRef) {
+        //获取自定义表单组件内容
+        formData = await this.$refs.myFormRef.getFormData();
+        if (!formData.flag) {
+          this.$message.error(formData.msg);
+          return;
+        }
+      }
+      // let payLoad = {
+      //   basicMap: {
+      //     taskNodeKey: nodeId,
+      //     nextNodeKey: nextNodeId,
+      //     // tableName: "",
+      //     implementationName: this.row.benmTaskAutomaticScriptTriggerType,
+      //     taskProcessKey: this.row.bepTaskKey,
+      //   },
+      //   commMap: {
+      //     //formData
+      //   },
+      // };
+
+      let payLoad = {
+        taskProcessKey: this.row.bepTaskKey, //当前任务流程编码
+        taskNodeKey: nodeId, //当前执行节点唯一编码
+        nextNodeKey: nextNodeId, //下一节点编码
+        implementationName: this.row.benmTaskAutomaticScriptTriggerType, //当前节点绑定的脚本名
+        taskProcessXmlContent: this.row.bepTaskProcessXmlContent, //当前流程xml
+        formDataMap: formData.data, //自定义表单组件收集的表单数据
+      };
+      runProcessNodeExecution(payLoad).then((res) => {
+        console.log(res);
+      });
+      console.log(payLoad);
+    },
+    // 关闭运行节点弹窗
+    closeExecuteNode(row) {
+      console.log(row);
+      this.open = false;
+    },
+    // 获取下一个节点的nodekey
+    getNextNodeKey(nodeKey, xmlStr) {
+      let xmlObj = this.xmlStr2XmlObj(xmlStr);
+      let nodeSequence = getNodeSequence(xmlObj);
+      return nodeSequence.find((item) => item.nodeId == nodeKey) || {};
+    },
+    // xml字符串转xml对象
+    xmlStr2XmlObj(xmlStr) {
+      var xmlObj = {};
+      if (document.all) {
+        var xmlDom = new ActiveXObject("Microsoft.XMLDOM");
+        xmlDom.loadXML(xmlStr);
+        xmlObj = xmlDom;
+      } else {
+        xmlObj = new DOMParser().parseFromString(xmlStr, "text/xml");
+      }
+      return xmlObj;
+    },
+    // 触发异常回调
+    handleCommand(command, row) {
+      console.log("触发异常");
+    },
+    // 获取字典对应label
+    getDictLabel(value, dictLsit = []) {
+      return dictLsit.find((item) => {
+        return item.value == value;
+      })?.label;
+    },
+  },
 };
 </script>
 
@@ -78,6 +339,7 @@ export default {
 .process-mange-wrap {
   background-color: #f2f3f8;
   padding: 20px;
+
   .col {
     background-color: #fff;
     border-right: 1px solid #ebedf2;
@@ -89,19 +351,23 @@ export default {
       align-items: center;
       padding: 10px 17px;
       justify-content: space-between;
+
       .discription {
         display: flex;
         flex-direction: column;
+
         .title {
           line-height: 20px;
           font-size: 18px;
           font-weight: 700;
           margin-bottom: 5px;
         }
+
         .sub-title {
           font-size: 14px;
         }
       }
+
       .data {
         font-size: 20px;
         font-weight: 700;
@@ -113,6 +379,7 @@ export default {
     margin-top: 30px;
     box-shadow: 0 1px 15px 1px rgb(69 65 78 / 8%);
     background-color: #fff;
+
     .show-header {
       border-bottom: 1px solid #ebedf2;
       display: flex;
@@ -120,18 +387,23 @@ export default {
       justify-content: space-between;
       padding: 0px 20px 0px 20px;
       height: 70px;
+
       .header {
       }
+
       .search-list {
         display: flex;
+
         .search-tab {
           margin-right: 20px;
+
           .btn-list-two {
             margin-left: 10px;
           }
         }
       }
     }
+
     .show-body {
       padding: 25px;
     }

+ 64 - 3
ruoyi-ui/src/views/bussiness/progressShow.vue

@@ -35,7 +35,11 @@
         </div>
       </div>
       <div class="show-body">
-        <TaskList v-for="i of 5" :key="i"></TaskList>
+        <TaskList
+          v-for="(item, index) of tableData"
+          :key="index + 1"
+          :cardData="item"
+        ></TaskList>
         <pagination
           v-show="total > 0"
           :total="total"
@@ -50,6 +54,9 @@
 
 <script>
 import TaskList from "./components/taskList.vue";
+import { processList } from "@/api/bpmprocess/run/executeProcess";
+import getNodeSequence from "@/utils/bpmn/getNodeSequence";
+import { xmlStr2XmlObj } from "@/utils/bpmn/xml";
 export default {
   name: "ProgressShow",
   props: [],
@@ -58,16 +65,70 @@ export default {
     return {
       processType: 1,
       queryString: "",
-      total: 1,
+      total: 0,
       queryParams: {
         pageNum: 1,
         pageSize: 5,
       },
+      tableData: [], //列表数据
     };
   },
   computed: {},
   methods: {
-    getList() {},
+    // 获取列表数据
+    getList() {
+      processList(this.queryParams).then((res) => {
+        if (res.code == 200) {
+          this.tableData = this.getTableData(
+            res.rows.map((item) => item.resultMap)
+          );
+          this.total = res.total;
+          console.log(this.tableData);
+        } else {
+          this.$message.error("网络异常,请稍后再试");
+        }
+      });
+    },
+    // 获取表格展示数据
+    getTableData(dataList) {
+      let res = [];
+      res = dataList.map((item) => {
+        let baseObj = {
+          benTaskProcessKey: item.bepTaskKey, //任务编号
+          bepTaskName: item.bepTaskName, //任务名称
+          benCreateTime: item.benCreateTime, //开始或结束时间  需要根据bepTaskProcessState状态 来判定
+          currentNodeKey: item.benTaskNodeKey, //当前节点key
+          cardList: [],
+        };
+        let xmlObj = xmlStr2XmlObj(item.bepTaskProcessXmlContent);
+        console.dir(xmlObj);
+        baseObj.cardList = getNodeSequence(xmlObj);
+        return baseObj;
+      });
+      res = this.setNodeState(res);
+      return res;
+    },
+    // 设置节点完成情况
+    setNodeState(res) {
+      res.forEach((re) => {
+        let nowKey = re.currentNodeKey;
+        let isDone = true;
+        re.cardList.forEach((item) => {
+          if (item.nodeId == nowKey) {
+            isDone = false;
+            item.isDone = isDone;
+            item.isNow = true;
+          } else {
+            item.isDone = isDone;
+            item.isNow = false;
+          }
+        });
+      });
+      return res;
+    },
+  },
+  mounted() {
+    this.getList();
   },
 };
 </script>

+ 1 - 1
ruoyi-ui/src/views/dataEngine/datamodeling/editTable.vue

@@ -82,7 +82,7 @@
           </template>
         </el-table-column>
 
-        <el-table-column prop="isPrimary" label="键" width="100">
+        <el-table-column prop="isPrimary" label="键" width="100">
           <template slot-scope="scope">
             <!-- <el-radio-group v-model="scope.row.isPrimary">
                 <el-radio :label="true">是</el-radio>

+ 87 - 11
ruoyi-ui/src/views/system/bpmnPro/components/Panel/components/ElementAsyncContinuations.vue

@@ -1,19 +1,59 @@
 <template>
   <el-collapse-item name="element-async-continuations">
     <template #title>
-      <collapse-title title="异步属性">
+      <collapse-title title="异步任务">
         <lucide-icon name="Shuffle" />
       </collapse-title>
     </template>
-    <edit-item label="执行前" :label-width="120">
-      <el-switch v-model="acBefore" @change="updateElementACBefore" />
+    <edit-item label="执行时机" :label-width="100">
+      <el-switch
+        v-model="acBefore"
+        active-text="节点前"
+        inactive-text="节点后"
+        @change="updateElementACBefore"
+      />
     </edit-item>
-    <edit-item label="执行后" :label-width="120">
-      <el-switch v-model="acAfter" @change="updateElementACAfter" />
+    <edit-item label="任务行业" :label-width="100">
+      <el-select
+        v-model="asyncIndustryType"
+        value-key="value"
+        placeholder="请选择行业类型"
+        filterable
+        @change="updateAsyncIndustryType"
+      >
+        <el-option
+          v-for="{ label, value } in dict.type.industry_type"
+          :label="label"
+          :value="value"
+          :key="value"
+        />
+      </el-select>
     </edit-item>
-    <edit-item v-if="showExclusive" label="可跳过" :label-width="120">
-      <el-switch v-model="acExclusive" @change="updateElementACExclusive" />
+    <edit-item label="选择任务" :label-width="100">
+      <el-select
+        v-model="asyncScriptKey"
+        :disabled="!asyncIndustryType"
+        value-key="value"
+        placeholder="请选择执行任务"
+        clearable
+        filterable
+        @change="updateAsyncScriptKey"
+      >
+        <el-option
+          v-for="{ value, label } in scriptList"
+          :key="value"
+          :label="label"
+          :value="value"
+        >
+        </el-option>
+      </el-select>
     </edit-item>
+    <!-- <edit-item label="执行后" :label-width="120">
+      <el-switch v-model="acAfter" @change="updateElementACAfter" />
+    </edit-item> -->
+    <!-- <edit-item v-if="showExclusive" label="可跳过" :label-width="120">
+      <el-switch v-model="acExclusive" @change="updateElementACExclusive" />
+    </edit-item> -->
   </el-collapse-item>
 </template>
 
@@ -25,17 +65,27 @@ import {
   setACAfter,
   setACBefore,
   setACExclusive,
+  getAsyncScriptKey,
+  setAsyncScriptKey,
+  getAsyncIndustryType,
+  setAsyncIndustryType,
 } from "@packages/bo-utils/asynchronousContinuationsUtil";
 import EventEmitter from "@utils/EventEmitter";
 import { getActive } from "@packages/bpmn-utils/BpmnDesignerUtils";
+import { listScript } from "@/api/bpmprocess/process";
 
 export default {
   name: "ElementAsyncContinuations",
+  dicts: ["industry_type"],
   data() {
     return {
-      acBefore: false,
+      acBefore: true,
       acAfter: false,
       acExclusive: false,
+      scriptList: [],
+      asyncIndustryType: "",
+      asyncScriptKey: "",
+      scriptTriggerType: "2",
     };
   },
   computed: {
@@ -50,8 +100,16 @@ export default {
   methods: {
     reloadACStatus() {
       this.acBefore = getACBefore(getActive());
-      this.acAfter = getACAfter(getActive());
-      this.acExclusive = getACExclusive(getActive());
+      // this.acAfter = getACAfter(getActive());
+      // this.acExclusive = getACExclusive(getActive());
+      // 脚本数据
+      if (!getAsyncIndustryType(getActive())) {
+        this.updateAsyncIndustryType(this.dict.type.industry_type[0]?.value);
+      } else {
+        this.getScriptList(getAsyncIndustryType(getActive()));
+      }
+      this.asyncIndustryType = getAsyncIndustryType(getActive());
+      this.asyncScriptKey = getAsyncScriptKey(getActive());
     },
     updateElementACBefore(value) {
       setACBefore(getActive(), value);
@@ -65,11 +123,29 @@ export default {
       setACExclusive(getActive(), value);
       this.reloadACStatus();
     },
+    updateAsyncScriptKey(value) {
+      setAsyncScriptKey(getActive(), value);
+    },
+    updateAsyncIndustryType(value) {
+      setAsyncIndustryType(getActive(), value);
+      this.getScriptList(value);
+      this.asyncScriptKey = "";
+    },
+    async getScriptList(industryType) {
+      let res = await listScript({
+        isEnablePaging: false,
+        industryType,
+      });
+      this.scriptList = res.rows.map((item) => ({
+        value: item.scriptKey,
+        label: item.scriptName,
+      }));
+    },
   },
 };
 </script>
 <style scoped lang="scss">
-::v-deep .edit-item_label{
+::v-deep .edit-item_label {
   width: 70px !important;
 }
 </style>

+ 80 - 0
ruoyi-ui/src/views/system/bpmnPro/components/Panel/components/ElementExcuteType.vue

@@ -0,0 +1,80 @@
+<template>
+  <el-collapse-item name="element-execute-type">
+    <template #title>
+      <collapse-title title="执行方式">
+        <lucide-icon name="FileSpreadsheet" />
+      </collapse-title>
+    </template>
+    <div class="element-execute-type">
+      <edit-item label="执行类型" :label-width="100">
+        <el-select
+          v-model="nodeExecuteType"
+          value-key="value"
+          placeholder="请选择节点执行类型"
+          clearable
+          filterable
+          @change="updateNodeExcuteType"
+        >
+          <el-option
+            v-for="item in excuteTypeList"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          >
+          </el-option>
+        </el-select>
+      </edit-item>
+    </div>
+  </el-collapse-item>
+</template>
+
+<script>
+import EventEmitter from "@utils/EventEmitter";
+import {
+  getNodeExecuteType,
+  setNodeExecuteType,
+} from "@packages/bo-utils/myFieldUtil";
+import { getActive } from "@packages/bpmn-utils/BpmnDesignerUtils";
+
+export default {
+  name: "ElementExecuteType",
+  data() {
+    return {
+      nodeExecuteType: "",
+      excuteTypeList: [
+        {
+          value: "true",
+          label: "自动执行",
+        },
+        {
+          value: "false",
+          label: "手动执行",
+        },
+      ],
+    };
+  },
+
+  mounted() {
+    this.initFormData();
+    EventEmitter.on("element-update", () => {
+      this.initFormData();
+    });
+  },
+  methods: {
+    async initFormData() {
+      if (!getNodeExecuteType(getActive())) {
+        this.updateNodeExcuteType("true");
+      }
+      this.nodeExecuteType = getNodeExecuteType(getActive());
+    },
+    updateNodeExcuteType(value) {
+      setNodeExecuteType(getActive(), value);
+    },
+  },
+};
+</script>
+<style scoped lang="scss">
+::v-deep .edit-item_label {
+  width: 80px !important;
+}
+</style>

+ 22 - 3
ruoyi-ui/src/views/system/bpmnPro/components/Panel/components/ElementExecuteUser.vue

@@ -37,7 +37,7 @@
           <el-select
             v-scroll="scrollHandler"
             v-model="exeUserValue"
-            placeholder="请选择执行人类型"
+            placeholder="请选择执行人"
             :multiple="exeUserType == 2"
             clearable
             filterable
@@ -110,6 +110,7 @@ export default {
         deptId: undefined,
       },
       isArriveBoottom: false,
+      isFirst: true,
     };
   },
 
@@ -129,8 +130,25 @@ export default {
   },
   methods: {
     initFormData() {
-      this.exeUserValue = getExecuteUser(getActive()) || "";
+      if (!getExecuteUserType(getActive())) {
+        //初始化数据时给流程绑定用户类型
+        this.updateExeUserType("1");
+      }
       this.exeUserType = getExecuteUserType(getActive()) || "1";
+      if (this.exeUserType == 2) {
+        let temp = getExecuteUser(getActive()) || "";
+        this.exeUserValue = temp ? temp.split(",") : [];
+      } else {
+        this.exeUserValue = getExecuteUser(getActive()) || "";
+      }
+      if (this.exeUserType && this.isFirst) {
+        if (this.exeUserType == 3) {
+          this.exeRoleListHandler();
+        } else {
+          this.exeUserListHandler();
+        }
+        this.isFirst = false;
+      }
       Object.assign(this.queryParams, {
         pageNum: 1,
         pageSize: 10,
@@ -163,10 +181,11 @@ export default {
           }
           res.rows.forEach((item) => {
             this.exeUserValueList.push({
-              value: item.userId,
+              value: item.userId.toString(),
               label: item.nickName,
             });
           });
+          console.log(this.exeUserValueList);
         }
       } catch (error) {
         console.log(error);

+ 1 - 0
ruoyi-ui/src/views/system/bpmnPro/components/Panel/components/ElementGenerations.vue

@@ -12,6 +12,7 @@
         <el-input
           v-model="elFormData.elementId"
           maxlength="32"
+          disabled
           @change="updateElementId"
         />
       </el-form-item>

+ 4 - 3
ruoyi-ui/src/views/system/bpmnPro/components/Panel/components/ElementNormalTask.vue

@@ -46,7 +46,7 @@
           </el-option>
         </el-select>
       </edit-item>
-      <edit-item label="触发方式" :label-width="100">
+      <edit-item v-if="false" label="触发方式" :label-width="100">
         <!-- <el-input
           v-model="industryType"
           maxlength="32"
@@ -93,7 +93,7 @@ export default {
       scriptList: [],
       industryType: "",
       normalScriptKey: "",
-      scriptTriggerType: "0",
+      scriptTriggerType: "1",
     };
   },
 
@@ -108,7 +108,7 @@ export default {
       this.industryType = getIndustryType(getActive());
       await this.getScriptList(this.industryType);
       this.normalScriptKey = getNormalScriptKey(getActive());
-      this.scriptTriggerType = getNormalScriptTriggerType(getActive());
+      // this.scriptTriggerType = getNormalScriptTriggerType(getActive());
     },
     updateIndustryType(value) {
       setIndustryType(getActive(), value);
@@ -128,6 +128,7 @@ export default {
     },
     updateScriptKey(value) {
       setNormalScriptKey(getActive(), value);
+      setNormalScriptTriggerType(getActive(), this.scriptTriggerType);
     },
     updateScriptTriggerType(value) {
       setNormalScriptTriggerType(getActive(), value);

+ 13 - 7
ruoyi-ui/src/views/system/bpmnPro/components/Panel/components/ElementUnusualTasks.vue

@@ -6,7 +6,7 @@
       </collapse-title>
       <number-tag :value="listeners.length" margin-left="12px" />
     </template>
-    <el-form label-width="110px" :model="scriptForm">
+    <el-form v-if="false" label-width="110px" :model="scriptForm">
       <el-form-item label="脚本执行时机:">
         <el-switch
           active-text="节点后"
@@ -23,6 +23,7 @@
           label="执行脚本"
           prop="scriptName"
           show-overflow-tooltip
+          align="center"
         >
           <!-- <template slot-scope="scope">
             {{ getDictLabel(scope.row.scriptType, dict.type.bpm_script_type) }}
@@ -31,6 +32,7 @@
         <el-table-column
           label="触发方式"
           prop="scriptTriggerType"
+          v-if="false"
           show-overflow-tooltip
         >
           <template slot-scope="scope">
@@ -105,7 +107,11 @@
             />
           </el-select>
         </el-form-item>
-        <el-form-item prop="scriptTriggerType" label="事件触发机制">
+        <el-form-item
+          v-if="false"
+          prop="scriptTriggerType"
+          label="事件触发机制"
+        >
           <el-select v-model="newUnusualTask.scriptTriggerType">
             <el-option
               v-for="item in dict.type.script_trigger_type"
@@ -157,11 +163,11 @@ export default {
           trigger: ["blur", "change"],
           message: "任务脚本不能为空",
         },
-        scriptTriggerType: {
-          required: true,
-          trigger: ["blur", "change"],
-          message: "事件触发机制不能为空",
-        },
+        // scriptTriggerType: {
+        //   required: true,
+        //   trigger: ["blur", "change"],
+        //   message: "事件触发机制不能为空",
+        // },
       },
       scriptKeyList: [],
       scriptTriggerTypeList: [

+ 7 - 3
ruoyi-ui/src/views/system/bpmnPro/components/Panel/index.vue

@@ -46,6 +46,7 @@ import ElementBeforeNode from "@packages/Panel/components/ElementBeforeNode";
 import ElementAfterNode from "@packages/Panel/components/ElementAfterNode";
 import ElementUnusualTasks from "@packages/Panel/components/ElementUnusualTasks";
 import ElementNormalTask from "@packages/Panel/components/ElementNormalTask";
+import ElementExcuteType from "@packages/Panel/components/ElementExcuteType";
 
 export default {
   name: "BpmnPanel",
@@ -65,6 +66,7 @@ export default {
     ElementBeforeNode,
     ElementAfterNode,
     ElementUnusualTasks,
+    ElementExcuteType,
   },
   data() {
     return {
@@ -154,17 +156,19 @@ export default {
       // isExecutable(element) &&
       //   this.renderComponents.push(ElementExecutionListeners);
       // isAsynchronous(element) &&
-      // this.renderComponents.push(ElementAsyncContinuations);
+      !isProcess(element) &&
+        this.renderComponents.push(ElementAsyncContinuations); //节点前后执行的数据
       // isStartInitializable(element) &&
       //   this.renderComponents.push(ElementStartInitiator);
       // this.renderComponents.push(ElementExtensionField);
       // 添加执行表单
       isTaskOrUserTask(element) &&
         this.renderComponents.push(ElementExecuteForm);
-      (isStartInitializable(element) || isTaskOrUserTask(element)) &&
-        this.renderComponents.push(ElementNormalTask);
+      !isProcess(element) && this.renderComponents.push(ElementNormalTask); //正常节点
       !isProcess(element) && this.renderComponents.push(ElementUnusualTasks); //可处理异常
       isUserTask(element) && this.renderComponents.push(ElementExecuteUser);
+      !isProcess(element) && this.renderComponents.push(ElementExcuteType);
+
       // !isProcess(element) && this.renderComponents.push(ElementBeforeNode);
       // !isProcess(element) && this.renderComponents.push(ElementAfterNode);
     },

+ 31 - 2
ruoyi-ui/src/views/system/bpmnPro/components/bo-utils/asynchronousContinuationsUtil.js

@@ -11,10 +11,39 @@ export function setACBefore(element, value) {
   const modeling = getModeler.get("modeling");
   // overwrite the legacy `async` property, we will use the more explicit `asyncBefore`
   modeling.updateModdleProperties(element, element.businessObject, {
-    [`${prefix}:asyncBefore`]: value,
-    [`${prefix}:async`]: undefined
+    [`${prefix}:asyncBefore`]: value
   });
 }
+/*                   脚本数据start                           */
+export function getAsyncScriptKey(element) {
+  const prefix = getProcessEngine();
+  return element.businessObject.get(`${prefix}:asyncScriptKey`);
+}
+export function setAsyncScriptKey(element, value) {
+  const prefix = getProcessEngine();
+  const modeling = getModeler.get("modeling");
+  // overwrite the legacy `async` property, we will use the more explicit `asyncBefore`
+  modeling.updateModdleProperties(element, element.businessObject, {
+    [`${prefix}:asyncScriptKey`]: value
+  });
+}
+export function getAsyncIndustryType(element) {
+  const prefix = getProcessEngine();
+  return element.businessObject.get(`${prefix}:asyncIndustryType`);
+}
+export function setAsyncIndustryType(element, value) {
+  const prefix = getProcessEngine();
+  const modeling = getModeler.get("modeling");
+  // overwrite the legacy `async` property, we will use the more explicit `asyncBefore`
+  modeling.updateModdleProperties(element, element.businessObject, {
+    [`${prefix}:asyncIndustryType`]: value
+  });
+}
+
+
+
+/*                   脚本数据end                           */
+
 
 export function getACAfter(element) {
   const prefix = getProcessEngine();

+ 20 - 4
ruoyi-ui/src/views/system/bpmnPro/components/bo-utils/getNodeMsg.js

@@ -38,7 +38,7 @@ export function getNodeMsg(xmlObj) {
   let prefix = getProcessEngine();
   let { attributes, childNodes } = xmlObj
     .getElementsByTagName("bpmn:process")[0];
-  let bpmProcessConfigurationList = [], bpmNodeHandleUserList = [], bpmNodeScriptRelevanceList = [], attributeArray = ['nodeKey', 'nodeFormKey', 'nodeProcessKey', 'nodeType', 'nodeRolePremission', 'spare1', 'spare2', 'spare3', 'createBy', 'updateBy', 'remark'];
+  let bpmProcessConfigurationList = [], bpmNodeHandleUserList = [], bpmNodeScriptRelevanceList = [], attributeArray = ['nodeKey', 'nodeFormKey', 'nodeProcessKey', 'nodeRolePremission', 'spare1', 'spare2', 'spare3', 'createBy', 'updateBy', 'remark', 'nodeExecuteType'];
   childNodes.forEach((node) => {
     // let uuid = uuidv4();
 
@@ -57,6 +57,7 @@ export function getNodeMsg(xmlObj) {
       createBy: '',  //创建者
       updateBy: '',  //修改者
       remark: '',    //节点描述
+      nodeExecuteType: '', //节点执行类型
     }
     nodeObj.nodeType = node.localName;
     if (nodeObj.nodeType == "sequenceFlow") return;
@@ -71,8 +72,16 @@ export function getNodeMsg(xmlObj) {
     nodeObj.nodeKey = node.id;
     nodeObj.nodeName = node.getAttribute('name');
     bpmNodeHandleUser.length && (nodeObj.nodeRolePermission = node.getAttribute(`${prefix}:virtuallyRole`));
-
+    let asyncBefore = node.getAttribute(`${prefix}:asyncBefore`)
+    if (asyncBefore == 'true') {
+      nodeObj.nodeBefore = 'true';
+      nodeObj.nodeAfter = 'false';
+    } else if (asyncBefore == 'false') {
+      nodeObj.nodeBefore = 'false';
+      nodeObj.nodeAfter = 'true';
+    }
     bpmProcessConfigurationList.push(nodeObj)
+    console.log(bpmProcessConfigurationList);
   })
   return {
     bpmProcessConfigurationList,
@@ -91,6 +100,12 @@ function getNodeException(node, nodeObj) {
       scriptTriggerType: node.getAttribute(`${prefix}:NormalScriptTriggerType`)
     })
   }
+  if (node.getAttribute(`${prefix}:asyncScriptKey`)) {
+    res.push({
+      scriptKey: node.getAttribute(`${prefix}:asyncScriptKey`),
+      scriptTriggerType: '2'
+    })
+  }
   if (children.length) {
     children = Array.from(children);//数组化
     let extensionElements = children.find((item) => item.nodeName == `bpmn:extensionElements`
@@ -141,7 +156,6 @@ function getBpmNodeHandleUser(node, nodeObj) {
     default:
       break;
   }
-
   return [res]
 }
 
@@ -210,7 +224,9 @@ const blackArr = [
   "waypoint",
   "BPMNEdge",
   "waypoint",
-  "waypoint"
+  "waypoint",
+  "property",
+  "properties"
 ]
 
 /**

+ 18 - 0
ruoyi-ui/src/views/system/bpmnPro/components/bo-utils/myFieldUtil.js

@@ -335,3 +335,21 @@ export function getNormalScriptTriggerType(element) {
 
   return businessObject.get(`${prefix}:NormalScriptTriggerType`);
 }
+
+/*          节点执行类型            */
+export function getNodeExecuteType(element) {
+  const prefix = getProcessEngine();
+  const businessObject = getBusinessObject(element);
+  console.log(businessObject.id, businessObject.get(`${prefix}:nodeExecuteType`));
+  return businessObject.get(`${prefix}:nodeExecuteType`);
+}
+
+export function setNodeExecuteType(element, value) {
+  const prefix = getProcessEngine();
+  const modeling = getModeler.getModeling();
+  const businessObject = getBusinessObject(element);
+  modeling.updateModdleProperties(element, businessObject, {
+    [`${prefix}:nodeExecuteType`]: value
+  });
+}
+

+ 374 - 178
ruoyi-ui/src/views/system/excuteBtnMange/index.vue

@@ -263,7 +263,7 @@
               </span>
             </el-form-item>
           </el-col>
-          <el-col :span="24">
+          <el-col :span="12">
             <el-form-item label="按钮类型" prop="btnType">
               <el-select
                 v-model="btnGroupFormData.btnType"
@@ -280,79 +280,86 @@
               </el-select>
             </el-form-item>
           </el-col>
+          <!-- 非目录 -->
           <div v-show="btnGroupFormData.btnType != 6">
-            <el-col :span="12">
-              <el-form-item label="绑定表单" prop="btnFormKey">
-                <el-select
-                  v-model="btnGroupFormData.btnFormKey"
-                  placeholder="请选择表单"
-                  clearable
-                  filterable
-                >
-                  <el-option
-                    v-for="item in formOptions"
-                    :key="item.fId"
-                    :label="item.dfName"
-                    :value="item.fId"
+            <div
+              v-show="
+                btnGroupFormData.btnType != 3 && btnGroupFormData.btnType != 7
+              "
+            >
+              <el-col :span="12">
+                <el-form-item label="绑定表单" prop="btnFormKey">
+                  <el-select
+                    v-model="btnGroupFormData.btnFormKey"
+                    placeholder="请选择表单"
+                    clearable
+                    filterable
                   >
-                  </el-option>
-                </el-select>
-              </el-form-item>
-            </el-col>
-            <el-col :span="12">
-              <el-form-item label="执行流程" prop="btnProcessKey">
-                <el-select
-                  v-model="btnGroupFormData.btnProcessKey"
-                  placeholder="请选择执行流程"
-                  clearable
-                  filterable
-                >
-                  <el-option
-                    v-for="item in processOptions"
-                    :key="item.processKey"
-                    :label="item.processName"
-                    :value="item.processKey"
+                    <el-option
+                      v-for="item in formOptions"
+                      :key="item.fId"
+                      :label="item.dfName"
+                      :value="item.fId"
+                    >
+                    </el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="执行流程" prop="btnProcessKey">
+                  <el-select
+                    v-model="btnGroupFormData.btnProcessKey"
+                    placeholder="请选择执行流程"
+                    clearable
+                    filterable
                   >
-                  </el-option>
-                </el-select>
-              </el-form-item>
-            </el-col>
-            <el-col :span="12">
-              <el-form-item label="绑定表格" prop="btnTableKey">
-                <el-select
-                  v-model="btnGroupFormData.btnTableKey"
-                  placeholder="请选择表格"
-                  clearable
-                  filterable
-                >
-                  <el-option
-                    v-for="item in tableOptions"
-                    :key="item.tableKey"
-                    :label="item.dtName"
-                    :value="item.tableKey"
+                    <el-option
+                      v-for="item in processOptions"
+                      :key="item.processKey"
+                      :label="item.processName"
+                      :value="item.processKey"
+                    >
+                    </el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="绑定表格" prop="btnTableKey">
+                  <el-select
+                    v-model="btnGroupFormData.btnTableKey"
+                    placeholder="请选择表格"
+                    clearable
+                    filterable
                   >
-                  </el-option>
-                </el-select>
-              </el-form-item>
-            </el-col>
-            <el-col :span="12">
-              <el-form-item label="绑定脚本" prop="btnScriptKey">
-                <el-select
-                  v-model="btnGroupFormData.btnScriptKey"
-                  placeholder="请选择绑定节点"
-                  clearable
-                  filterable
-                >
-                  <el-option
-                    v-for="item in scriptOptions"
-                    :key="item.scriptKey"
-                    :label="item.scriptName"
-                    :value="item.scriptKey"
+                    <el-option
+                      v-for="item in tableOptions"
+                      :key="item.tableKey"
+                      :label="item.dtName"
+                      :value="item.tableKey"
+                    >
+                    </el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="绑定脚本" prop="btnScriptKey">
+                  <el-select
+                    v-model="btnGroupFormData.btnScriptKey"
+                    placeholder="请选择绑定节点"
+                    clearable
+                    filterable
                   >
-                  </el-option>
-                </el-select>
-              </el-form-item>
-            </el-col>
+                    <el-option
+                      v-for="item in scriptOptions"
+                      :key="item.scriptKey"
+                      :label="item.scriptName"
+                      :value="item.scriptKey"
+                    >
+                    </el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+            </div>
             <el-col
               :span="24"
               v-show="
@@ -367,112 +374,153 @@
                 ></el-input>
               </el-form-item>
             </el-col>
-          </div>
-
-          <!-- <el-col :span="24">
-            <div class="btn-show-condition">
-              <span class="table-title">条件编辑</span>
-              <el-table :data="conditionBtnData" style="width: 100%">
-                <el-table-column label="序号" type="index" width="50">
-                </el-table-column>
-                <el-table-column prop="tableName" label="表名" width="150">
-                  <template slot-scope="scope">
-                    <el-select
-                      v-model="scope.row.tableName"
-                      @change="conditionTableChange(scope.row)"
-                      placeholder="请选择"
-                    >
-                      <el-option
-                        v-for="item in tableList"
-                        :key="item.tableName"
-                        :label="item.tableComment"
-                        :value="item.tableName"
-                      >
-                        <span style="float: left">{{ item.tableComment }}</span>
-                        <span
-                          style="float: right; color: #8492a6; font-size: 13px"
-                          >{{ item.tableName }}</span
-                        >
-                      </el-option>
-                    </el-select>
-                  </template>
-                </el-table-column>
-                <el-table-column prop="fieldName" label="字段名" width="150">
-                  <template slot-scope="scope">
-                    <el-select
-                      v-model="scope.row.fieldName"
-                      placeholder="请选择"
-                    >
-                      <el-option
-                        v-for="item in scope.row.fieldList"
-                        :key="item.fieldName"
-                        :label="item.fieldDescription"
-                        :value="item.fieldName"
-                      >
-                        <span style="float: left">{{
-                          item.fieldDescription
-                        }}</span>
-                        <span
-                          style="float: right; color: #8492a6; font-size: 13px"
-                          >{{ item.fieldName }}</span
-                        >
-                      </el-option>
-                    </el-select>
-                  </template>
-                </el-table-column>
-                <el-table-column prop="condition" label="条件" width="100">
-                  <template slot-scope="scope">
-                    <el-select
-                      v-model="scope.row.condition"
-                      placeholder="请选择"
-                    >
-                      <el-option
-                        v-for="item in conditionList"
-                        :key="item.value"
-                        :label="item.label"
-                        :value="item.value"
-                      >
-                      </el-option>
-                    </el-select>
-                  </template>
-                </el-table-column>
-                <el-table-column prop="flagValue" label="参照值" width="100">
+            <!-- <div class="table-wrap">
+              <span class="title mb10">添加query参数</span>
+              <el-table
+                :data="queryTableData"
+                border
+                stripe
+                style="width: 100%"
+              >
+                <el-table-column align="center" type="index" width="50" />
+                <el-table-column
+                  v-for="col in columns"
+                  :prop="col.prop"
+                  :key="col.prop"
+                  :label="col.label"
+                  width="150"
+                  align="center"
+                >
                   <template slot-scope="scope">
                     <el-input
-                      v-model="scope.row.flagValue"
-                      @input="
-                        scope.row.flagValue = scope.row.flagValue.replace(
-                          /^(0+)|[^\d]+/g,
-                          ''
-                        )
-                      "
+                      v-model="scope.row[col.prop]"
+                      placeholder=""
+                      size="normal"
+                      clearable
                     ></el-input>
                   </template>
                 </el-table-column>
-                <el-table-column label="操作">
+                <el-table-column label="操作" align="center">
                   <template slot-scope="scope">
                     <el-button
                       size="mini"
                       type="danger"
                       icon="el-icon-delete"
-                      @click="deleteConditionItem(scope.$index)"
+                      @click="deleteQueryItem(scope.$index)"
                       >删除
                     </el-button>
                   </template>
                 </el-table-column>
               </el-table>
-              <el-button
-                type="primary"
-                class="inline-large-button mb10"
-                icon="el-icon-plus"
-                size="mini"
-                style="width: 100%"
-                @click="addConditionHandler"
-              >
-                添加条件
-              </el-button>
-            </div>
-          </el-col> -->
+            </div> -->
+            <el-col :span="24">
+              <!-- 
+              v-show="
+                btnGroupFormData.btnType != 3 && btnGroupFormData.btnType != 7
+              " -->
+              <!-- <el-form-item label="" prop="btnParams"> -->
+              <div class="filter-table-wrap">
+                <span class="title mb10"
+                  >{{
+                    btnGroupFormData.btnType != 3 &&
+                    btnGroupFormData.btnType != 7
+                      ? "公共"
+                      : "query"
+                  }}参数</span
+                >
+                <el-table :data="commonFieldData" style="width: 100%">
+                  <el-table-column label="序号" type="index" width="50">
+                  </el-table-column>
+                  <el-table-column
+                    prop="fieldName"
+                    label="字段名"
+                    width="150"
+                    align="center"
+                  >
+                    <template slot-scope="scope">
+                      <el-select
+                        v-model="scope.row.fieldName"
+                        placeholder="请选择"
+                      >
+                        <el-option
+                          v-for="item in rootFieldInfo.fieldList"
+                          :key="item.value"
+                          :label="item.value"
+                          :value="item.key"
+                        >
+                          <span style="float: left">{{ item.value }}</span>
+                          <span
+                            style="
+                              float: right;
+                              color: #8492a6;
+                              font-size: 13px;
+                            "
+                            >{{ item.key }}</span
+                          >
+                        </el-option>
+                      </el-select>
+                    </template>
+                  </el-table-column>
+                  <el-table-column
+                    prop="flagValue"
+                    label="默认值"
+                    width="150"
+                    align="center"
+                  >
+                    <template slot="header" slot-scope="">
+                      默认值
+                      <el-tooltip
+                        class="item"
+                        effect="dark"
+                        content="不设置默认值时,默认为当前行的该字段"
+                        placement="top-start"
+                      >
+                        <i class="el-icon-info"></i>
+                      </el-tooltip>
+                    </template>
+                    <template slot-scope="scope">
+                      <!-- <el-button
+                          type="info"
+                          size="small"
+                          icon="el-icon-edit"
+                          @click="editFlagHandler(scope.row, scope.$index)"
+                        >
+                        </el-button> -->
+                      <el-input
+                        v-model="scope.row.fieldValue"
+                        placeholder="请输入默认值"
+                        size="normal"
+                        clearable
+                      >
+                      </el-input>
+                    </template>
+                  </el-table-column>
+                  <el-table-column label="操作" align="center">
+                    <template slot-scope="scope">
+                      <el-button
+                        size="mini"
+                        type="danger"
+                        icon="el-icon-delete"
+                        @click="deleteFilterItem(scope.$index)"
+                        >删除
+                      </el-button>
+                    </template>
+                  </el-table-column>
+                </el-table>
+                <el-button
+                  type="primary"
+                  class="inline-large-button mb10"
+                  icon="el-icon-plus"
+                  size="mini"
+                  style="width: 100%"
+                  @click="addFilterHandler"
+                >
+                  添加参数
+                </el-button>
+              </div>
+              <!-- </el-form-item> -->
+            </el-col>
+          </div>
         </el-row>
       </el-form>
       <div slot="footer" class="dialog-footer">
@@ -485,13 +533,13 @@
 
 <script>
 import {
-  listMenu,
-  getMenu,
-  delMenu,
-  addMenu,
-  updateMenu,
-} from "@/api/system/menu";
-import { listBtn, addBtn, getBtn, updateBtn, delBtn } from "@/api/system/btn";
+  listBtn,
+  addBtn,
+  getBtn,
+  updateBtn,
+  delBtn,
+  checkBtn,
+} from "@/api/system/btn";
 import { listForm } from "@/api/dragform/form";
 import { listProcess } from "@/api/bpmprocess/process";
 import { listTable } from "@/api/dragform/tableList";
@@ -500,7 +548,8 @@ import Treeselect from "@riophae/vue-treeselect";
 import "@riophae/vue-treeselect/dist/vue-treeselect.css";
 import IconSelect from "@/components/IconSelect";
 import { v4 as uuidv4 } from "uuid";
-
+import { dragTableInfo } from "@/api/tablelist/commonTable";
+import { camelCase } from "@/utils";
 export default {
   name: "ExcuteBtnMange",
   dicts: ["sys_show_hide", "sys_normal_disable"],
@@ -621,13 +670,109 @@ export default {
       tableOptions: [],
       processOptions: [],
       scriptOptions: [],
+      // 普遍字段参数
+      commonFieldData: [
+        // {
+        //   fieldName: "",
+        //   fieldValue: "",
+        // },
+      ],
+      rootFieldInfo: {
+        tableName: "",
+        fieldList: [],
+      },
+      queryTableData: [
+        {
+          key: "",
+          value: "",
+        },
+      ],
+      columns: [
+        {
+          label: "参数名",
+          prop: "key",
+        },
+        {
+          label: "值",
+          prop: "value",
+        },
+      ],
     };
   },
-  created() {
+  // created() {
+  //   this.getList();
+  //   this.initFormSubData();
+  // },
+  mounted() {
     this.getList();
     this.initFormSubData();
   },
   methods: {
+    // 删除公共传参
+    deleteFilterItem(index) {
+      this.commonFieldData.splice(index, 1);
+    },
+    // 删除query参数
+    deleteQueryItem(index) {
+      this.queryTableData.splice(index, index);
+    },
+    // 添加公共传参
+    addFilterHandler() {
+      if (this.rootFieldInfo.fieldList.length == 0) {
+        this.$message.error("请先将按钮组绑定给表格");
+        return;
+      }
+      this.commonFieldData.push({
+        fieldName: "",
+        fieldValue: "",
+      });
+    },
+    // 获取根节点绑定表格的字段数据
+    async getRootFieldInfo(btnKey) {
+      let res = await checkBtn({ btnKey });
+      if (res.code == 200) {
+        if (res.rows[0]?.tableKey) {
+          let tableInfo = await dragTableInfo({
+            queryMap: { tableKey: res.rows[0].tableKey },
+          });
+          this.rootFieldInfo.fieldList = this.columnsHandler(
+            JSON.parse(tableInfo.data.resultMap.template.dtColumnName)
+          );
+          console.log(this.rootFieldInfo.fieldList);
+        }
+      }
+    },
+    // 处理列表信息
+    columnsHandler(columns) {
+      let resArr = [];
+      columns.forEach((item) => {
+        for (const key in item) {
+          let tempObj = {};
+          tempObj.key = camelCase(key);
+          tempObj.value = item[key];
+          resArr.push(tempObj);
+        }
+      });
+      return resArr;
+    },
+    // 给所有节点设置根节点key
+    setRootBtnKey(rows, rootKey = "") {
+      if (rows.length == 0) {
+        return rows;
+      }
+      for (let i = 0; i < rows.length; i++) {
+        let row = rows[i];
+        if (row.btnParentId == 0) {
+          row.rootKey = row.btnKey;
+        } else {
+          row.rootKey = rootKey;
+        }
+        if (row.children.length != 0) {
+          row.children = this.setRootBtnKey(row.children, row.rootKey);
+        }
+      }
+      return rows;
+    },
     // 选择图标
     selected(name) {
       this.btnGroupFormData.btnIcon = name;
@@ -637,7 +782,9 @@ export default {
       this.loading = true;
 
       listBtn(this.queryParams).then((response) => {
-        this.btnList = response.rows;
+        let res = this.setRootBtnKey(response.rows);
+        console.log(res);
+        this.btnList = res;
         console.log("btnList", this.btnList);
         this.loading = false;
       });
@@ -714,6 +861,7 @@ export default {
         btnSort: 0, //按钮顺序
         btnKey: "",
       };
+      this.commonFieldData = [];
       this.resetForm("btnGroupFormRef");
     },
     /** 搜索按钮操作 */
@@ -726,21 +874,20 @@ export default {
       this.handleQuery();
     },
     /** 新增按钮操作 */
-    handleAdd(row) {
-      this.title = "新增按钮";
+    async handleAdd(row) {
       this.reset();
       this.getTreeselect();
-
       this.editType = row ? true : false;
       if (row != null && row.id) {
         //在已知节点下新增
+        await this.getRootFieldInfo(row.rootKey);
         this.btnGroupFormData.btnParentId = row.id;
+        this.title = "新增按钮";
       } else {
         this.btnGroupFormData.btnParentId = 0;
+        this.title = "添加按钮组";
       }
-      console.log(this.btnGroupFormData.btnParentId);
       this.open = true;
-      this.title = "添加按钮组";
     },
     /** 展开/折叠操作 */
     toggleExpandAll() {
@@ -751,14 +898,26 @@ export default {
       });
     },
     /** 修改按钮操作 */
-    handleUpdate(row) {
+    async handleUpdate(row) {
+      console.log(row);
       this.reset();
       this.getTreeselect();
       this.editType = false;
+      //在已知节点下新增
+      await this.getRootFieldInfo(row.rootKey);
       getBtn(row.id).then((response) => {
+        let { btnType, btnParams } = response.data;
+        if ((btnType == 3 || btnType == 7) && btnParams) {
+          //内链或外链
+          let tempObj = JSON.parse(btnParams);
+          response.data.btnParams = tempObj.url;
+          this.commonFieldData = JSON.parse(tempObj.commonFieldData) || [];
+        } else {
+          btnParams && (this.commonFieldData = JSON.parse(btnParams) || []);
+        }
         this.btnGroupFormData = response.data;
         this.open = true;
-        this.title = "修改菜单";
+        this.title = "修改按钮";
       });
     },
     // 校验复杂逻辑表单数据
@@ -774,6 +933,11 @@ export default {
       }
       return res;
     },
+    // 获取公共数据
+    // getCommonData(list) {
+    //   if (list.length == 0) return '';
+
+    // },
     /** 提交按钮 */
     submitForm() {
       this.$refs["btnGroupFormRef"].validate(async (valid) => {
@@ -783,6 +947,21 @@ export default {
             this.$message.error(validateRes.msg);
             return;
           }
+          // 获取公共参数
+          // let commonData=this.getCommonData(this.commonFieldData)
+          if (
+            this.btnGroupFormData.btnType != 3 &&
+            this.btnGroupFormData.btnType != 7
+          ) {
+            this.btnGroupFormData.btnParams = JSON.stringify(
+              this.commonFieldData
+            );
+          } else {
+            let tempObj = {};
+            tempObj.url = this.btnGroupFormData.btnParams;
+            tempObj.commonFieldData = JSON.stringify(this.commonFieldData);
+            this.btnGroupFormData.btnParams = JSON.stringify(tempObj);
+          }
           if (this.editType) {
             // 新增按钮组
             this.btnGroupFormData.btnKey = uuidv4();
@@ -857,7 +1036,9 @@ export default {
         } else {
           this.$message.error("网络异常请稍后再试");
         }
-      } catch (error) {}
+      } catch (error) {
+        console.log(error);
+      }
     },
     // 添加按钮条件
     addConditionHandler() {
@@ -879,4 +1060,19 @@ export default {
 .submenu-title-noDropdown:hover {
   background-color: linear-gradient(to right, blue, rgb(69, 118, 225));
 }
+
+.filter-table-wrap {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+.table-wrap {
+  width: 100%;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+.title {
+  font-weight: 600;
+}
 </style>

+ 1 - 1
ruoyi-ui/src/views/system/fromModel/index.vue

@@ -92,7 +92,7 @@ export default {
         // Object.assign(formSQL, item.options.sqlData);
         let sqlList = item.options.sqlData.sqls;
         formSQL[item.options.dynamicKey] = {};
-        formSQL[item.options.dynamicKey].sqls =
+        formSQL[item.options.dynamicKey] =
           item.type == "select" ? sqlList[0] : sqlList;
       });
 

+ 104 - 76
ruoyi-ui/src/views/system/tenant/code/index.vue

@@ -1,19 +1,32 @@
 <template>
   <div class="app-container">
     <div>
-      <el-form ref="form" :model="activationCode" :rules="rulesActivationCode" label-width="80px">
+      <el-form
+        ref="form"
+        :model="activationCode"
+        :rules="rulesActivationCode"
+        label-width="80px"
+      >
         <el-form-item label="租户信息" prop="tenantCode">
           <el-select v-model="activationCode.tenantCode" placeholder="请选择">
             <el-option
               v-for="item in tenantList"
               :key="item.tenantId"
               :label="item.tenantName"
-              :value="item.tenantId">
+              :value="item.tenantId"
+            >
             </el-option>
           </el-select>
         </el-form-item>
-        <el-form-item label="充值时间" prop="tenantExpirationDate" style="width: 300px">
-          <el-input v-model="activationCode.tenantExpirationDate" placeholder="请输入充值天数"></el-input>
+        <el-form-item
+          label="充值时间"
+          prop="tenantExpirationDate"
+          style="width: 300px"
+        >
+          <el-input
+            v-model="activationCode.tenantExpirationDate"
+            placeholder="请输入充值天数"
+          ></el-input>
         </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer">
@@ -21,16 +34,22 @@
         <el-button @click="cancel">取 消</el-button>
       </div>
       <!-- 激活码生成成功-->
-      <el-dialog :title="title" :visible.sync="activationCodeForm" width="500px" append-to-body>
+      <el-dialog
+        :title="title"
+        :visible.sync="activationCodeForm"
+        width="500px"
+        append-to-body
+      >
         <span v-html="actCode"></span>
         <div slot="footer" class="dialog-footer">
-          <el-button type="primary" @click="copyToClipboard">一键复制</el-button>
-          <el-button @click="cancel">取 消</el-button>
+          <el-button type="primary" @click="copyToClipboard"
+            >一键复制</el-button
+          >
+          <el-button @click="activationCodeForm = false">取 消</el-button>
         </div>
       </el-dialog>
     </div>
     <div style="margin-top: 30px">
-
       <!--搜索条件表单-->
       <el-form
         :model="queryParams"
@@ -45,7 +64,7 @@
             v-model="queryParams.ipAddress"
             placeholder="请输入登录地址"
             clearable
-            style="width: 240px;"
+            style="width: 240px"
             @keyup.enter.native="handleQuery"
           />
         </el-form-item>
@@ -77,10 +96,10 @@
             icon="el-icon-search"
             size="mini"
             @click="handleQuery"
-          >搜索</el-button
+            >搜索</el-button
           >
           <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
-          >重置</el-button
+            >重置</el-button
           >
         </el-form-item>
       </el-form>
@@ -95,7 +114,6 @@
         @sort-change="handleSortChange"
         style="margin-top: 20px"
       >
-
         <el-table-column type="selection" width="50" align="center" />
         <el-table-column label="日志编号" align="center" prop="logId" />
         <el-table-column label="操作人员" align="center" prop="operator" />
@@ -132,66 +150,65 @@
 </template>
 
 <script>
+import { listTenant, createTenantCode } from "@/api/system/tenant";
 import {
-  listTenant,
-  createTenantCode
-} from "@/api/system/tenant";
-import {list, delActivationLog, cleanActivationLog} from "@/api/monitor/activationcode";
+  list,
+  delActivationLog,
+  cleanActivationLog,
+} from "@/api/monitor/activationcode";
 
-import Clipboard from 'clipboard';
+import Clipboard from "clipboard";
 
 export default {
   name: "TenantCode",
   data() {
     return {
-        options: [],
-        //表单校验
-        rulesActivationCode: {
-          tenantCode: [
-            { required: true, message: "未选择租户信息", trigger: "blur" },
-          ],
-          tenantExpirationDate: [
-            { required: true, message: "租户到期时间为设置", trigger: "blur" },
-          ],
-        },
-        activationCode: {},
-        //租户信息表格数据
-        tenantList: [],
-        activationCodeForm: false,
-        actCode:"",
-        title:"激活码生成成功",
-        // 遮罩层
-        loading: true,
-        // 选中数组
-        ids: [],
-        // 非多个禁用
-        multiple: true,
-        // 显示搜索条件
-        showSearch: true,
-        // 总条数
-        total: 0,
-        // 表格数据
-        list: [],
-        // 是否显示弹出层
-        open: false,
-        // 日期范围
-        dateRange: [],
-        // 默认排序
-        defaultSort: { prop: "operTime", order: "descending" },
-        // 表单参数
-        form: {},
-        // 查询参数
-        queryParams: {
-          pageNum: 1,
-          pageSize: 10,
-          operator: undefined,
-          ipAddress: undefined
-        },
-    }
-  },
-  computed: {
-
+      options: [],
+      //表单校验
+      rulesActivationCode: {
+        tenantCode: [
+          { required: true, message: "未选择租户信息", trigger: "blur" },
+        ],
+        tenantExpirationDate: [
+          { required: true, message: "租户到期时间未设置", trigger: "blur" },
+        ],
+      },
+      activationCode: {},
+      //租户信息表格数据
+      tenantList: [],
+      activationCodeForm: false,
+      actCode: "",
+      title: "激活码生成成功",
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 表格数据
+      list: [],
+      // 是否显示弹出层
+      open: false,
+      // 日期范围
+      dateRange: [],
+      // 默认排序
+      defaultSort: { prop: "operTime", order: "descending" },
+      // 表单参数
+      form: {},
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        operator: undefined,
+        ipAddress: undefined,
+      },
+    };
   },
+  computed: {},
   created() {
     this.getList();
     this.getCodeLogList();
@@ -204,30 +221,40 @@ export default {
       });
     },
     //创建激活码
-    crateCode(){
-      createTenantCode(this.activationCode).then((response) => {
-         this.activationCodeForm=true;
-         this.actCode=response.msg;
+    crateCode() {
+      this.$refs.form.validate((valid) => {
+        if (valid) {
+          createTenantCode(this.activationCode).then((response) => {
+            this.activationCodeForm = true;
+            this.actCode = response.msg;
+          });
+        } else {
+          return false;
+        }
       });
     },
     //激活码复制操作
     copyToClipboard() {
       //创建一个新 Clipboard 实例,将目标元素和复制成功时的回调传递给它
-      const clipboard = new Clipboard('button', {
+      const clipboard = new Clipboard("button", {
         text: () => this.actCode, //在这里替换为你要复制的文本
       });
-      clipboard.on('success', () => {
-        this.activationCodeForm=false;
-        this.$message({showClose: true, message: '文本已成功复制到剪贴板', type: 'success'});
+      clipboard.on("success", () => {
+        this.activationCodeForm = false;
+        this.$message({
+          showClose: true,
+          message: "文本已成功复制到剪贴板",
+          type: "success",
+        });
         clipboard.destroy(); //清除 Clipboard 实例
       });
-      clipboard.on('error', () => {
-        console.error('复制失败');
+      clipboard.on("error", () => {
+        console.error("复制失败");
         clipboard.destroy(); //清除 Clipboard 实例
       });
       //触发按钮点击事件,开始复制操作
       clipboard.onClick({
-        action: 'copy',
+        action: "copy",
       });
     },
     //取消按钮
@@ -238,7 +265,8 @@ export default {
     //激活码日志信息
     getCodeLogList() {
       this.loading = true;
-      list(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
+      list(this.addDateRange(this.queryParams, this.dateRange)).then(
+        (response) => {
           this.list = response.rows;
           this.total = response.total;
           this.loading = false;

+ 2 - 2
ruoyi-ui/src/views/tableMange/index.vue

@@ -972,7 +972,7 @@ export default {
             disableRelaType: false,
             isShow: true,
             isSearch: false,
-            isExport: true,
+            isExport: false,
             relationTableList: this.relationTableList,
             tableName: this.tableName,
             tableComment,
@@ -1033,7 +1033,7 @@ export default {
           disableRelaType: false,
           isShow: true,
           isSearch: false,
-          isExport: true,
+          isExport: false,
           relationTableList,
           tableName: row.relationTable,
           tableComment,

+ 52 - 4
ruoyi-ui/src/views/tablelist/commonTable/listInfo.vue

@@ -293,7 +293,7 @@ import {
 import { listData } from "@/api/system/tenant/data";
 import { getToken } from "@/utils/auth";
 import Queryfrom from "@/views/tablelist/commonTable/queryfrom.vue";
-import { camelCase } from "@/utils";
+import { camelCase, toUnderline } from "@/utils";
 import { inputDisableComplete } from "@/utils/other";
 import Menu from "./BtnMenu.vue";
 import { checkRole } from "@/utils/permission";
@@ -404,6 +404,8 @@ export default {
       // 弹窗新增数据
       addLists:[],
       subTableName: '',
+      // 当前点击行的数据
+      currentRow: {},
     };
   },
 
@@ -667,6 +669,7 @@ export default {
         let str = modifiedTable.substring(nameTable.length+1)
         obj[str] = row[key];
       }
+      console.log("row", row);
 
       // 新的修改请求
       try {
@@ -847,7 +850,18 @@ export default {
         conditionMap: {
           // id: delIds,
         },
+        btnParametersMap: {},
       };
+      if (this.currentBtnData.btnParams) {
+        let btnParams = JSON.parse(this.currentBtnData.btnParams);
+        btnParams.forEach((item) => {
+          data.btnParametersMap[
+            this.formatField(item.fieldName, camelCase(this.tableName))
+          ] = item.fieldValue
+            ? item.fieldValue
+            : this.currentRow[item.fieldName];
+        });
+      }
       data.conditionMap[this.templateInfo.template?.primaryKey] = delIds;
       this.$modal
         .confirm('是否确认删除"' + delIds + '"的数据项?')
@@ -956,6 +970,12 @@ export default {
       //   console.log('弹窗确定', res);
       // })
     },
+    // 去掉表名 开头字母小写
+    formatField(field = "", tableName) {
+      console.log(field, tableName);
+      let temp = field.replace(tableName, "");
+      return toUnderline(temp[0].toLowerCase() + temp.slice(1));
+    },
     //提交编辑结果按钮回调
     editConfirmHandler() {
       this.$refs.addFromRef
@@ -970,7 +990,18 @@ export default {
             addListMap: [values],
             conditionMap: {},
             commMap: {},
+            btnParametersMap: {},
           };
+          if (this.currentBtnData.btnParams) {
+            let btnParams = JSON.parse(this.currentBtnData.btnParams);
+            btnParams.forEach((item) => {
+              data.btnParametersMap[
+                this.formatField(item.fieldName, camelCase(this.tableName))
+              ] = item.fieldValue
+                ? item.fieldValue
+                : this.currentRow[item.fieldName];
+            });
+          }
           if (Object.keys(this.defaultValue).length) {
             //修改
             // 后台接收需要是表中字段真实的名称,无所谓驼峰。
@@ -1170,11 +1201,27 @@ export default {
 
     // 内链页面跳转
     routerHandler(btnData, type) {
-      let link = btnData.btnParams;
+      let { url, commonFieldData } = JSON.parse(btnData.btnParams);
+      let tempArr = [];
+      if (commonFieldData) {
+        let queryArr = JSON.parse(commonFieldData);
+
+        tempArr = queryArr.map((item) => {
+          let key = this.formatField(item.fieldName, camelCase(this.tableName));
+          let value = item.fieldValue
+            ? item.fieldValue
+            : this.currentRow[item.fieldName];
+          return key + "=" + value;
+        });
+      }
+      if (tempArr.length) {
+        url += "?" + tempArr.join("&");
+      }
+      // let link = btnData.btnParams;
       if (type == "3") {
-        this.$router.push(link);
+        this.$router.push(url);
       } else {
-        window.open("http://" + link, "_blank");
+        window.open("http://" + url, "_blank");
       }
     },
 
@@ -1182,6 +1229,7 @@ export default {
     excuteHandler(btnData, row) {
       let { btnType, btnParams } = btnData;
       this.currentBtnData = btnData;
+      this.currentRow = JSON.parse(JSON.stringify(row));
       switch (
         btnType //3:内链  6:目录  7:外链  8:修改  9:删除
       ) {

+ 1 - 1
ruoyi-ui/src/views/tool/datasheet/index.vue

@@ -110,7 +110,7 @@
             </template>
           </el-table-column>
 
-          <el-table-column prop="isPrimary" label="键" width="100">
+          <el-table-column prop="isPrimary" label="键" width="100">
             <template slot-scope="scope">
               <el-checkbox
                 :disabled="!scope.row.fieldName"