whj há 11 meses atrás
pai
commit
e38b5a1acf

+ 45 - 120
src/components/Jsplumb/index.vue

@@ -8,50 +8,48 @@
       </a-space>
     </div>
     <div ref="container" class="container" :style="{transform: `scale(${scale / 100})`}">
-      <slot name="default">
-
-      </slot>
+      <div v-for="item in details" :key="item.id" :id="item.id" :style="{position: 'absolute',left:item.x+'px',top:item.y+'px'}">
+        <slot name="default" :detail="item">
+          {{ item.x }}
+        </slot>
+      </div>
     </div>
   </div>
 </template>
 
 <script>
 // import jsPlumb from 'jsplumb'
-import Node from './modules/Node.vue'
 import { newInstance, EVENT_CONNECTION, EVENT_CONNECTION_DBL_CLICK, EVENT_DRAG_STOP } from '@jsplumb/browser-ui'
 export default {
-  components: {
-    Node,
-    BaseForm,
+  data() {
+    return {
+      jsPlumb: null,
+      instance: null,
+      scale: 100,
+    }
   },
   props: {
     details: {
       type: Array,
       default: () => [
         // {
-        //   name: '发起人',
         //   id: '1',
-        //   type: 1,
         //   y: 100,
         //   x: 500,
-        //   children: [],
         // },
       ],
     },
+    importDefaults: {
+      type: Object,
+      default: () => ({}),
+    },
+    config: {
+      type: Object,
+      default: () => ({}),
+    },
   },
-  data() {
-    return {
-      jsPlumb: null,
-      instance: null,
-      scale: 100,
-    }
-  },
-  mounted() {
-    this.init()
-  },
-  created() {},
   methods: {
-    init() {
+    init(details) {
       const that = this
       // 初始化节点
       this.instance = newInstance({
@@ -60,10 +58,12 @@ export default {
           containmentPadding: 10,
           grid: { w: 20, h: 20 },
         },
+        ...this.config,
       })
       this.instance.importDefaults({
-        anchor: 'Continuous',
+        anchors: ['Bottom', 'Top'],
         connectionsDetachable: false,
+        reattachConnections: true,
         // 连接器类型,这里设置为Flowchart
         connector: {
           type: 'Flowchart',
@@ -98,6 +98,7 @@ export default {
           //   }
           // }
         ],
+        ...this.importDefaults,
         // 添加两个标签和箭头
       })
       this.instance.addSourceSelector('.bottom')
@@ -107,11 +108,10 @@ export default {
           item.children.forEach((children) => {
             that.instance.connect({
               // 获取节点1和节点2的引用
-              source: this.$refs[item.id][0].$el,
-              target: this.$refs[children][0].$el,
+              source: document.getElementById(item.id),
+              target: document.getElementById(children),
               // 连接方式,这里设置为连续
               // paintStyle: { stroke: children.label == '同意' ? '#345' : 'red', strokeWidth: 3 },
-              anchor: 'AutoDefault',
               // 连接器类型,这里设置为Flowchart
               connector: 'Flowchart',
               // 添加两个标签和箭头
@@ -121,53 +121,22 @@ export default {
           // instance.addEndpoint(this.$refs[item.name][0].$el, { target: false, source: false })
         }
       })
-      // this.$refs.node.forEach((item) => {
-      //   console.log(item)
-      // })
-
-      // 连接三个端点
-      // instance.connect({
-      //   // 获取节点1和节点2的引用
-      //   source: this.$refs.node1,
-      //   target: this.$refs.node2,
-      //   // 连接方式,这里设置为连续
-      //   anchor: 'AutoDefault',
-      //   // 连接器类型,这里设置为Flowchart
-      //   connector: 'Flowchart',
-      //   // 添加两个标签和箭头
-      //   overlays: [
-      //     { type: 'Label', options: { label: 'Connection 1', location: 0.5 } },
-      //     { type: 'Arrow', options: { location: 1 } },
-      //   ],
-      // })
-      // instance.connect({
-      //   source: this.$refs.node2,
-      //   target: this.$refs.node3,
-      //   connector: 'Flowchart',
-      //   anchor: 'AutoDefault',
-      //   overlays: [
-      //     { type: 'Label', options: { label: 'Connection 2', location: 0.5 } },
-      //     { type: 'Arrow', options: { location: 1 } },
-      //   ],
-      // })
       //拖拽
       this.instance.bind(EVENT_DRAG_STOP, (val) => {
-        console.log(val.el.__vue__)
-        console.log(3)
-        val.el.__vue__.setPosition(val.elements[0].pos)
+        that.$emit('dragStop', val.elements[0].pos)
       })
       // 建立链接
       this.instance.bind(EVENT_CONNECTION, (val) => {
-        console.log(val)
-        console.log(2)
+        that.$emit('connection', {
+          source: val.source.__vue__,
+          target: val.target.__vue__,
+        })
       })
-      // 删除连接
+      // 双击连线
       this.instance.bind(EVENT_CONNECTION_DBL_CLICK, (conn) => {
-        this.$confirm({
-          title: '确定删除所点击的链接吗?',
-          onOk() {
-            that.instance.deleteConnection(conn)
-          },
+        that.$emit('connectionDblClick', {
+          source: conn.source.__vue__,
+          target: conn.target.__vue__,
         })
       })
       this.$forceUpdate()
@@ -184,65 +153,18 @@ export default {
       }
       this.instance.setZoom(this.scale / 100)
     },
-    add(record, type) {
-      const newVal = {
-        name: type === 2 ? '条件分支' : '审核人',
-        id: +new Date(),
-      }
-      if (record.children.length > 0) {
-        const children = this.details
-          .filter((detail) => {
-            return record.children.includes(detail.id)
-          })
-          .reduce((pre, item) => {
-            if (item.x > pre.x) {
-              pre = item
-            }
-            return pre
-          })
-        record.children.push(newVal.id)
-        this.details.push({
-          x: children.x + 240,
-          y: children.y,
-          type,
-          children: [],
-          ...newVal,
-        })
-      } else {
-        record.children.push(newVal.id)
-        this.details.push({
-          x: record.x,
-          y: record.y + 250,
-          type,
-          children: [],
-          ...newVal,
-        })
-      }
+    add(record) {
       this.$nextTick(() => {
         this.instance.connect({
-          // 获取节点1和节点2的引用
-          source: this.$refs[record.id][0].$el,
-          target: this.$refs[newVal.id][0].$el,
-          // 连接方式,这里设置为连续
-          // paintStyle: { stroke: children.label == '同意' ? '#345' : 'red', strokeWidth: 3 },
-          anchor: 'AutoDefault',
-          // 连接器类型,这里设置为Flowchart
+          source: document.getElementById(record.source.id),
+          target: document.getElementById(record.target.id),
           connector: 'Flowchart',
-          // 添加两个标签和箭头
         })
       })
-      // this.details.push()
     },
     //删除节点
-
-    handleDelete(record) {
-      this.instance.unmanage(this.$refs[record.id][0].$el, true)
-      this.details = this.details.filter((item) => {
-        return item.id !== record.id
-      })
-    },
-    edit(record) {
-      this.$refs.baseModal.base(record)
+    delete(record) {
+      this.instance.unmanage(document.getElementById(record.id), true)
     },
   },
 }
@@ -294,11 +216,14 @@ export default {
   position: relative;
   display: flex;
   flex-direction: column;
-  min-height: calc(100vh - 100px);
+  min-height: calc(100vh - 200px);
+  max-height: calc(100vh - 200px);
+  overflow-y: auto;
+
   width: 100%;
 }
 .scale {
-  position: absolute;
+  position: fixed;
   bottom: 20px;
   right: 30px;
   z-index: 9999;

+ 4 - 1
src/views/workflow/workflow/modules/BaseForm.vue

@@ -1,5 +1,5 @@
 <template>
-  <div v-if="visible">
+  <div v-if="visible" style="position: relative">
     <div class="title">
       <h3>{{modalTitle}}</h3>
       <a-space>
@@ -345,6 +345,9 @@ export default {
   display: flex;
   justify-content: space-between;
   align-items: center;
+  position: absolute;
+  z-index: 999;
+  top: 0;
   h3 {
     padding: 0;
     margin: 0;

+ 57 - 61
src/views/workflow/workflow/modules/Detail.vue

@@ -1,67 +1,63 @@
 <template>
-    <a-card :bordered="false" v-show="visible" class="card" :title="modalTitle">
-        <a-row :gutter="48" slot="extra">
-            <a-col :md="48" :sm="48">
-              <span class="table-page-search-submitButtons" style="float: right">
-                <a-button style="margin-left: 8px" type="default" @click="handleCancel()">返回</a-button>
-              </span>
-            </a-col>
-        </a-row>
-        <detail-list title="" :col="2">
-                                                                                                    <detail-list-item term="创建人ID">{{ model.createdUserId }}</detail-list-item>
-                                                                                                            <detail-list-item term="更新人ID">{{ model.updateUserId }}</detail-list-item>
-                                                                                                                                        <detail-list-item term="更新时间">{{ model.updateTime }}</detail-list-item>
-                                                                                                                                        <detail-list-item term="更新人">{{ model.updateUserName }}</detail-list-item>
-                                                                                                            <detail-list-item term="流程名称">{{ model.name }}</detail-list-item>
-                                                                                                            <detail-list-item term="流程总节点数">{{ model.totalNode }}</detail-list-item>
-                                                                                                            <detail-list-item term="层级节点数">{{ model.levelNode }}</detail-list-item>
-                                                        </detail-list>
-    </a-card>
+  <a-card :bordered="false" v-if="visible" class="card" :title="modalTitle">
+    <a-row :gutter="48" slot="extra">
+      <a-col :md="48" :sm="48">
+        <span class="table-page-search-submitButtons" style="float: right">
+          <a-button style="margin-left: 8px" type="default" @click="handleCancel()">返回</a-button>
+        </span>
+      </a-col>
+    </a-row>
+    <JsPlumb ref="JsPlumb" :details="details">
+      <template #default="record">
+        <!-- sdsd -->
+        <Node :detail="record.detail" :config="{}"></Node>
+      </template>
+    </JsPlumb>
+  </a-card>
 </template>
 
 <script>
-    import DetailList from '@/components/tools/DetailList'
-    const DetailListItem = DetailList.Item
-
-    export default {
-        name: 'WorkflowDetail',
-        components: {
-            DetailList,
-            DetailListItem
-        },
-        data () {
-            return {
-                confirmLoading: false,
-                mdl: {},
-                modalTitle: null,
-                visible: false,
-                // 下拉框map
-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            model: {
-                                                                                                                    'createdUserId': null,
-                                                                                                'updateUserId': null,
-                                                                                                                                            'updateTime': null,
-                                                                                                                                            'updateUserName': null,
-                                                                                                'name': null,
-                                                                                                'totalNode': null,
-                                                                                                'levelNode': null,
-                                                            }
-            }
-        },
-        created () {
-            // 下拉框map
-            
-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        },
-        methods: {
-            base (record) {
-                this.visible = true
-                this.modalTitle = '详情'
-                this.model = record
-            },
-            handleCancel () {
-                this.visible = false
-                this.confirmLoading = false
-                this.$emit('ok')
-            }
-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
+import DetailList from '@/components/tools/DetailList'
+const DetailListItem = DetailList.Item
+import JsPlumb from '@/components/Jsplumb'
+import Node from './modules/Node2.vue'
+export default {
+  name: 'WorkflowDetail',
+  components: {
+    DetailList,
+    DetailListItem,
+    JsPlumb,
+    Node,
+  },
+  data() {
+    return {
+      confirmLoading: false,
+      mdl: {},
+      modalTitle: null,
+      visible: false,
+      // 下拉框map
+      model: {},
+      details: [],
     }
+  },
+  created() {
+    // 下拉框map
+  },
+  methods: {
+    base(record) {
+      this.visible = true
+      this.modalTitle = '详情'
+      this.model = record
+      this.details = JSON.parse(record.json)
+      this.$nextTick(() => {
+        this.$refs.JsPlumb.init()
+      })
+    },
+    handleCancel() {
+      this.visible = false
+      this.confirmLoading = false
+      this.$emit('ok')
+    },
+  },
+}
 </script>

+ 1 - 0
src/views/workflow/workflow/modules/modules/Node.vue

@@ -117,6 +117,7 @@ export default {
   position: absolute;
   cursor: pointer;
   border-radius: 0 0 10px 10px;
+  box-shadow: 1px 3px 8px 0 rgba(102, 102, 102, 0.26);
   .top {
     position: absolute;
     top: 0;

+ 107 - 0
src/views/workflow/workflow/modules/modules/Node2.vue

@@ -0,0 +1,107 @@
+<template>
+  <div class="node">
+    <div v-if="detail.type===1" class="start">
+      <div class="title">
+        发起人
+      </div>
+      <div class="card-content">
+        {{ detail.name }}
+      </div>
+    </div>
+    <div v-else-if="detail.type===2" class="term">
+      <div class="top"></div>
+      <div class="bottom"></div>
+      <div class="title">
+        条件分支
+      </div>
+      <div class="card-content">
+        {{ detail.name }}
+      </div>
+    </div>
+    <div v-else-if="detail.type===3" class="verify">
+      <div class="top"></div>
+      <div class="bottom"></div>
+      <div class="title">
+        {{ detail.name }}
+      </div>
+      <div class="card-content">
+        <div>{{detail.userName}}</div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    detail: {
+      type: Object,
+      default: () => {},
+    },
+  },
+  watch: {
+    detail: {
+      handler(val) {
+        console.log(val)
+      },
+      deep: true,
+    },
+  },
+  data() {
+    return {}
+  },
+}
+</script>
+
+<style lang="less" scoped>
+.node {
+  width: 200px;
+  cursor: pointer;
+  box-shadow: 1px 3px 8px 0 rgba(102, 102, 102, 0.26);
+  border-radius: 0 0 10px 10px;
+  .title {
+    padding: 2px 5px;
+    overflow: hidden;
+    background: #9e9ebc;
+    color: #fff;
+    border-radius: 10px 10px 0 0;
+  }
+  .card-content {
+    background: #fff;
+    text-align: center;
+    padding: 10px;
+    min-height: 50px;
+  }
+  .term {
+    .title {
+      color: #0ab74c;
+      border-bottom: 1px solid #ccc;
+      background: #fff;
+    }
+  }
+  .verify {
+    .title {
+      background: #e99e09;
+    }
+  }
+}
+.action {
+  border-top: 1px solid #ccc;
+  font-size: 12px;
+  border-radius: 0 0 10px 10px;
+  background: #fff;
+  .btn {
+    padding: 5px;
+    text-align: center;
+  }
+}
+
+.audit {
+  background: #e99e09;
+  border: #e99e09 solid 1px;
+  &:hover {
+    background: #f7b737;
+    border: #f7b737 solid 1px;
+  }
+}
+</style>