ソースを参照

仿钉钉设计流程:增加发起人、条件分支节点

jason 1 年間 前
コミット
4f839136c7

+ 30 - 27
src/components/SimpleProcessDesigner/src/addNode.vue

@@ -24,6 +24,12 @@
             <p>条件分支</p>
           </a>
           -->
+          <a class="add-node-popover-item condition" @click="addType(4)">
+            <div class="item-wrapper">
+              <span class="iconfont"></span>
+            </div>
+            <p>条件分支</p>
+          </a>
         </div>
         <template #reference>
           <button class="btn" type="button">
@@ -36,6 +42,7 @@
 </template>
 <script lang="ts" setup>
 import { ref } from 'vue'
+import { generateUUID } from '@/utils'
 let props = defineProps({
   childNodeP: {
     type: Object,
@@ -89,7 +96,8 @@ const addType = (type) => {
     emits('update:childNodeP', {
       name: '路由',
       type: 4,
-      childNode: null,
+      id : 'GateWay_'+ generateUUID(),
+      childNode: props.childNodeP,
       conditionNodes: [
         {
           name: '条件1',
@@ -97,15 +105,13 @@ const addType = (type) => {
           type: 3,
           priorityLevel: 1,
           conditionList: [],
-          nodeUserList: [],
-          // childNode: props.childNodeP
+          childNode: null
         },
         {
-          name: '条件2',
+          name: '其它情况',
           type: 3,
           priorityLevel: 2,
           conditionList: [],
-          nodeUserList: [],
           childNode: null
         }
       ]
@@ -115,55 +121,52 @@ const addType = (type) => {
 </script>
 <style scoped lang="scss">
 .add-node-btn-box {
-  width: 240px;
+  position: relative;
   display: inline-flex;
+  width: 240px;
   -ms-flex-negative: 0;
   flex-shrink: 0;
   -webkit-box-flex: 1;
   -ms-flex-positive: 1;
-  position: relative;
 
-  &:before {
-    content: '';
+  &::before {
     position: absolute;
-    top: 0;
-    left: 0;
-    right: 0;
-    bottom: 0;
+    inset: 0;
     z-index: -1;
-    margin: auto;
     width: 2px;
     height: 100%;
+    margin: auto;
     background-color: #cacaca;
+    content: '';
   }
 
   .add-node-btn {
-    user-select: none;
+    display: flex;
     width: 240px;
     padding: 20px 0 32px;
-    display: flex;
-    -webkit-box-pack: center;
     justify-content: center;
     flex-shrink: 0;
     -webkit-box-flex: 1;
+    -webkit-box-pack: center;
+    user-select: none;
     flex-grow: 1;
 
     .btn {
-      outline: none;
-      box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
+      position: relative;
       width: 30px;
       height: 30px;
+      line-height: 30px;
       background: #3296fa;
-      border-radius: 50%;
-      position: relative;
       border: none;
-      line-height: 30px;
+      border-radius: 50%;
+      outline: none;
+      box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
       -webkit-transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
       transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
-
+  
       .iconfont {
-        color: #fff;
         font-size: 16px;
+        color: #fff;
       }
 
       &:hover {
@@ -172,8 +175,8 @@ const addType = (type) => {
       }
 
       &:active {
-        transform: none;
         background: #1e83e9;
+        transform: none;
         box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
       }
     }
@@ -191,7 +194,6 @@ const addType = (type) => {
     color: #191f25 !important;
 
     .item-wrapper {
-      user-select: none;
       display: inline-block;
       width: 80px;
       height: 80px;
@@ -200,6 +202,7 @@ const addType = (type) => {
       border: 1px solid #e2e2e2;
       border-radius: 50%;
       transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
+      user-select: none;
 
       .iconfont {
         font-size: 35px;
@@ -238,8 +241,8 @@ const addType = (type) => {
 
     &:active {
       .item-wrapper {
-        box-shadow: none;
         background: #eaeaea;
+        box-shadow: none;
       }
 
       .iconfont {

+ 5 - 5
src/components/SimpleProcessDesigner/src/consts.ts

@@ -1,5 +1,6 @@
 export enum NodeType {
-  //// 0 发起人 1审批 2抄送 3条件 4路由
+  //// -1 根节点流程开始节点 0 发起人 1审批 2抄送 3条件 4路由
+  ROOT_NODE = -1,
   /**
    * 发起人节点
    */
@@ -37,11 +38,10 @@ NODE_TITLE.set(NodeType.CC_USER_NODE, '抄送人')
 
 export type WorkFlowNode = {
   id: string,
-  parentId: string,
   type: NodeType,
   name: string,
-  attributes: Map<string,any>,
+  attributes: Object | undefined,
   // 操作人
-  childNode: WorkFlowNode,
-  conditionNodes: WorkFlowNode[]
+  childNode?: WorkFlowNode | undefined,
+  conditionNodes: WorkFlowNode[] | undefined
 }

+ 4 - 48
src/components/SimpleProcessDesigner/src/drawer/approverDrawer.vue

@@ -156,7 +156,7 @@
 </template>
 <script lang="ts" setup>
 import { ref, watch, computed, toRaw } from 'vue'
-import { approveMethods, setApproverStr } from '../util'
+import { approveMethods } from '../util'
 import { useWorkFlowStoreWithOut } from '@/store/modules/simpleWorkflow'
 import { DICT_TYPE, getIntDictOptions, getDictLabel } from '@/utils/dict'
 import { defaultProps, handleTree } from '@/utils/tree'
@@ -165,7 +165,7 @@ import * as DeptApi from '@/api/system/dept'
 import * as PostApi from '@/api/system/post'
 import * as UserApi from '@/api/system/user'
 import * as UserGroupApi from '@/api/bpm/userGroup'
-let props = defineProps({
+defineProps({
   directorMaxLevel: {
     type: Number,
     default: 0
@@ -182,12 +182,8 @@ const candidateConfig = ref({
   approveMethod: undefined
 })
 let approverConfig = ref({})
-let approverVisible = ref(false)
-let approverRoleVisible = ref(false)
-let checkedRoleList = ref([])
-let checkedList = ref([])
 let store = useWorkFlowStoreWithOut()
-let { setApproverConfig, setApprover, setUserTaskConfig } = store
+let { setApprover, setUserTaskConfig } = store
 let approverConfig1 = computed(() => store.approverConfig1)
 let approverDrawer = computed(() => store.approverDrawer)
 const userTaskConfig = computed(() => store.userTaskConfig)
@@ -220,47 +216,7 @@ watch(userTaskConfig, (val) => {
 watch(approverConfig1, (val) => {
   approverConfig.value = val.value
 })
-let changeRange = () => {
-  approverConfig.value.nodeUserList = []
-}
-const changeType = (val) => {
-  approverConfig.value.nodeUserList = []
-  approverConfig.value.examineMode = 1
-  approverConfig.value.noHanderAction = 2
-  if (val == 2) {
-    approverConfig.value.directorLevel = 1
-  } else if (val == 4) {
-    approverConfig.value.selectMode = 1
-    approverConfig.value.selectRange = 1
-  } else if (val == 7) {
-    approverConfig.value.examineEndDirectorLevel = 1
-  }
-}
-const addApprover = () => {
-  approverVisible.value = true
-  checkedList.value = approverConfig.value.nodeUserList
-}
-const addRoleApprover = () => {
-  approverRoleVisible.value = true
-  checkedRoleList.value = approverConfig.value.nodeUserList
-}
-const sureApprover = (data) => {
-  approverConfig.value.nodeUserList = data
-  approverVisible.value = false
-}
-const sureRoleApprover = (data) => {
-  approverConfig.value.nodeUserList = data
-  approverRoleVisible.value = false
-}
-const saveApprover = () => {
-  approverConfig.value.error = !setApproverStr(approverConfig.value)
-  setApproverConfig({
-    value: approverConfig.value,
-    flag: true,
-    id: approverConfig1.value.id
-  })
-  closeDrawer()
-}
+
 const saveConfig = () => {
   const rawConfig = toRaw(userTaskConfig.value)
   const { approveMethod, candidateStrategy , candidateParam} = toRaw(candidateConfig.value);

+ 91 - 91
src/components/SimpleProcessDesigner/src/nodeWrap.vue

@@ -6,21 +6,16 @@
  * @FilePath: /Workflow-Vue3/src/components/nodeWrap.vue
 -->
 <template>
- 
   <div class="node-wrap" v-if="nodeConfig.type < 3">
-    <div class="start-event-node" v-if="nodeConfig.type === -1">
-        <div class="start-event-node-text">{{ nodeConfig.name }}</div>
-        <div class="start-event-node-circle"></div>
-    </div>
     <div
       class="node-wrap-box"
       :class="
         (nodeConfig.type == 0 ? 'start-node ' : '') +
         (isTried && nodeConfig.error ? 'active error' : '')
       "
-      v-else>
+    >
       <div class="title" :style="`background: rgb(${bgColors[nodeConfig.type]});`">
-        <span v-if="nodeConfig.type == 0">{{ nodeConfig.name }}</span>
+        <span v-if="nodeConfig.type == 0">发起人</span>
         <template v-else>
           <span class="iconfont">{{ nodeConfig.type == 1 ? '' : '' }}</span>
           <input
@@ -39,7 +34,7 @@
       <div class="content" @click="setPerson">
         <div class="text">
           <span class="placeholder" v-if="!showText">请选择{{ defaultText }}</span>
-          <span v-html="showText" class="ellipsis-text"  v-else></span>
+          <span v-html="showText" class="ellipsis-text" v-else></span>
         </div>
         <div class="icon-box">
           <i class="anticon anticon-edit" @click="editNode"></i>
@@ -59,31 +54,36 @@
         <div class="col-box" v-for="(item, index) in nodeConfig.conditionNodes" :key="index">
           <div class="condition-node">
             <div class="condition-node-box">
+              <div class="title-wrapper" :style="`background: rgb(${bgColors[nodeConfig.type]});`">
+                <input
+                  v-if="isInputList[index]"
+                  type="text"
+                  class="ant-input editable-title-input"
+                  @blur="blurEvent(index)"
+                  @focus="$event.currentTarget.select()"
+                  v-model="item.name"
+                />
+                <span v-else class="editable-title" @click="clickEvent(index)">{{
+                  item.name
+                }}</span>
+                <!-- <span class="priority-title" @click="setPerson(item.priorityLevel)"
+                      >优先级{{ index + 1 }}</span
+                    > -->
+                <i
+                  class="anticon anticon-close close"
+                  @click="delTerm(index)"
+                  v-if="index != nodeConfig.conditionNodes?.length - 1"
+                ></i>
+              </div>
               <div class="auto-judge" :class="isTried && item.error ? 'error active' : ''">
-                <div class="sort-left" v-if="index != 0" @click="arrTransfer(index, -1)">&lt;</div>
-                <div class="title-wrapper">
-                  <input
-                    v-if="isInputList[index]"
-                    type="text"
-                    class="ant-input editable-title-input"
-                    @blur="blurEvent(index)"
-                    @focus="$event.currentTarget.select()"
-                    v-model="item.name"
-                  />
-                  <span v-else class="editable-title" @click="clickEvent(index)">{{
-                    item.name
-                  }}</span>
-                  <span class="priority-title" @click="setPerson(item.priorityLevel)"
-                    >优先级{{ item.priorityLevel }}</span
-                  >
-                  <i class="anticon anticon-close close" @click="delTerm(index)"></i>
-                </div>
-                <div
+                <!-- <div class="sort-left" v-if="index != 0" @click="arrTransfer(index, -1)">&lt;</div> -->
+
+                <!-- <div
                   class="sort-right"
                   v-if="index != nodeConfig.conditionNodes.length - 1"
                   @click="arrTransfer(index)"
                   >&gt;</div
-                >
+                > -->
                 <div class="content" @click="setPerson(item.priorityLevel)">{{
                   conditionStr(nodeConfig, index)
                 }}</div>
@@ -121,18 +121,14 @@ import {
   placeholderList,
   getApproverShowText
 } from './util'
+import { WorkFlowNode } from './consts'
 import { useWorkFlowStoreWithOut } from '@/store/modules/simpleWorkflow'
 let _uid = getCurrentInstance().uid
 
 let props = defineProps({
   nodeConfig: {
-    type: Object,
-    default: () => ({})
-  },
-  flowPermission: {
-    type: Object,
-    // eslint-disable-next-line vue/require-valid-default-prop
-    default: () => []
+    type: Object as () => WorkFlowNode,
+    default: () => ({}) as WorkFlowNode
   }
 })
 
@@ -161,14 +157,13 @@ onMounted(() => {
     resetConditionNodesErr()
   }
 })
-let emits = defineEmits(['update:flowPermission', 'update:nodeConfig'])
+let emits = defineEmits(['update:nodeConfig'])
 let store = useWorkFlowStoreWithOut()
 let {
   setPromoter,
   setApprover,
   setCopyer,
   setCondition,
-  setFlowPermission,
   setCopyerConfig,
   setConditionsConfig,
   setUserTaskConfig
@@ -176,15 +171,17 @@ let {
 // 审批节点的配置
 const userTaskConfig = computed(() => store.userTaskConfig)
 let isTried = computed(() => store.isTried)
-let flowPermission1 = computed(() => store.flowPermission1)
 let approverConfig1 = computed(() => store.approverConfig1)
 let copyerConfig1 = computed(() => store.copyerConfig1)
 let conditionsConfig1 = computed(() => store.conditionsConfig1)
 const showText = computed(() => {
   if (props.nodeConfig.type == 0) return '发起人'
   if (props.nodeConfig.type == 1) {
-    if(props.nodeConfig.attributes){
-      return getApproverShowText(props.nodeConfig.attributes.approveMethod, props.nodeConfig.attributes.candidateStrategy)
+    if (props.nodeConfig.attributes) {
+      return getApproverShowText(
+        props.nodeConfig.attributes.approveMethod,
+        props.nodeConfig.attributes.candidateStrategy
+      )
     } else {
       return ''
     }
@@ -196,11 +193,6 @@ watch(userTaskConfig, (approver) => {
     emits('update:nodeConfig', approver.value)
   }
 })
-watch(flowPermission1, (flow) => {
-  if (flow.flag && flow.id === _uid) {
-    emits('update:flowPermission', flow.value)
-  }
-})
 watch(approverConfig1, (approver) => {
   if (approver.flag && approver.id === _uid) {
     emits('update:nodeConfig', approver.value)
@@ -240,38 +232,42 @@ const delNode = () => {
   emits('update:nodeConfig', props.nodeConfig.childNode)
 }
 const addTerm = () => {
-  let len = props.nodeConfig.conditionNodes.length + 1
+  const len = props.nodeConfig.conditionNodes.length
+  let lastIndex = props.nodeConfig.conditionNodes.length - 1
   // eslint-disable-next-line vue/no-mutating-props
-  props.nodeConfig.conditionNodes.push({
+  props.nodeConfig.conditionNodes.splice(lastIndex, 0, {
     name: '条件' + len,
     type: 3,
     priorityLevel: len,
     conditionList: [],
-    nodeUserList: [],
     childNode: null
   })
   resetConditionNodesErr()
   emits('update:nodeConfig', props.nodeConfig)
 }
 const delTerm = (index) => {
-  // eslint-disable-next-line vue/no-mutating-props
-  props.nodeConfig.conditionNodes.splice(index, 1)
-  props.nodeConfig.conditionNodes.map((item, index) => {
-    item.priorityLevel = index + 1
-    item.name = `条件${index + 1}`
-  })
-  resetConditionNodesErr()
-  emits('update:nodeConfig', props.nodeConfig)
-  if (props.nodeConfig.conditionNodes.length == 1) {
-    if (props.nodeConfig.childNode) {
-      if (props.nodeConfig.conditionNodes[0].childNode) {
-        reData(props.nodeConfig.conditionNodes[0].childNode, props.nodeConfig.childNode)
-      } else {
-        // eslint-disable-next-line vue/no-mutating-props
-        props.nodeConfig.conditionNodes[0].childNode = props.nodeConfig.childNode
+  if (props.nodeConfig.conditionNodes) {
+    // eslint-disable-next-line vue/no-mutating-props
+    props.nodeConfig.conditionNodes.splice(index, 1)
+    props.nodeConfig.conditionNodes.map((item, index) => {
+      // item.priorityLevel = index + 1
+      if (index !== props.nodeConfig.conditionNodes.length - 1) {
+        item.name = `条件${index + 1}`
+      }
+    })
+    resetConditionNodesErr()
+    emits('update:nodeConfig', props.nodeConfig)
+    if (props.nodeConfig.conditionNodes.length == 1) {
+      if (props.nodeConfig.childNode) {
+        if (props.nodeConfig.conditionNodes[0].childNode) {
+          reData(props.nodeConfig.conditionNodes[0].childNode, props.nodeConfig.childNode)
+        } else {
+          // eslint-disable-next-line vue/no-mutating-props
+          props.nodeConfig.conditionNodes[0].childNode = props.nodeConfig.childNode
+        }
       }
+      emits('update:nodeConfig', props.nodeConfig.conditionNodes[0].childNode)
     }
-    emits('update:nodeConfig', props.nodeConfig.conditionNodes[0].childNode)
   }
 }
 const reData = (data, addData) => {
@@ -285,21 +281,16 @@ const setPerson = (priorityLevel) => {
   var { type } = props.nodeConfig
   if (type == 0) {
     setPromoter(true)
-    setFlowPermission({
-      value: props.flowPermission,
-      flag: false,
-      id: _uid
-    })
   } else if (type == 1) {
     setApprover(true)
-    let showText = undefined;
-    if(_uid === userTaskConfig.value.id) {
+    let showText = undefined
+    if (_uid === userTaskConfig.value.id) {
       showText = userTaskConfig.value.showText
     }
     setUserTaskConfig({
       value: {
         ...JSON.parse(JSON.stringify(props.nodeConfig)),
-        id: 'Activity_'+_uid,
+        id: 'Activity_' + _uid
       },
       flag: false,
       id: _uid,
@@ -315,27 +306,30 @@ const setPerson = (priorityLevel) => {
   } else {
     setCondition(true)
     setConditionsConfig({
-      value: JSON.parse(JSON.stringify(props.nodeConfig)),
+      value: {
+        ...JSON.parse(JSON.stringify(props.nodeConfig)),
+        id: 'Gateway_' + _uid
+      },
       priorityLevel,
       flag: false,
       id: _uid
     })
   }
 }
-const arrTransfer = (index, type = 1) => {
-  //向左-1,向右1
-  // eslint-disable-next-line vue/no-mutating-props
-  props.nodeConfig.conditionNodes[index] = props.nodeConfig.conditionNodes.splice(
-    index + type,
-    1,
-    props.nodeConfig.conditionNodes[index]
-  )[0]
-  props.nodeConfig.conditionNodes.map((item, index) => {
-    item.priorityLevel = index + 1
-  })
-  resetConditionNodesErr()
-  emits('update:nodeConfig', props.nodeConfig)
-}
+// const arrTransfer = (index, type = 1) => {
+//   //向左-1,向右1
+//   // eslint-disable-next-line vue/no-mutating-props
+//   props.nodeConfig.conditionNodes[index] = props.nodeConfig.conditionNodes.splice(
+//     index + type,
+//     1,
+//     props.nodeConfig.conditionNodes[index]
+//   )[0]
+//   props.nodeConfig.conditionNodes.map((item, index) => {
+//     item.priorityLevel = index + 1
+//   })
+//   resetConditionNodesErr()
+//   emits('update:nodeConfig', props.nodeConfig)
+// }
 </script>
 <style lang="scss" scoped>
 .ellipsis-text {
@@ -351,10 +345,16 @@ const arrTransfer = (index, type = 1) => {
 }
 
 .start-event-node-circle {
-  width: 10px;
-  height: 10px;
-  margin: auto;
-  background: #dbdcdc;
+  display: flex;
+  width: 40px;
+  height: 40px;
+  align-items: center;
+  justify-content: center;
+  // margin: auto;
+  // background: #dbdcdc;
+  font-size: 16px;
+  color: #f8f8fa;
+  background-image: linear-gradient(90deg, #ff6a00, #f78b3e), linear-gradient(#ff6a00, #ff6a00);
   border-radius: 50%;
 }
 

+ 17 - 5
src/components/SimpleProcessDesigner/src/util.ts

@@ -92,10 +92,22 @@ export const copyerStr = (nodeConfig: any) => {
 export const conditionStr = (nodeConfig, index) => {
   const { conditionList, nodeUserList } = nodeConfig.conditionNodes[index]
   if (conditionList.length == 0) {
-    return index == nodeConfig.conditionNodes.length - 1 &&
-      nodeConfig.conditionNodes[0].conditionList.length != 0
-      ? '其他条件进入此流程'
-      : '请设置条件'
+    // return index == nodeConfig.conditionNodes.length - 1 &&
+    //   nodeConfig.conditionNodes[0].conditionList.length != 0
+    //   ? '其他条件进入此流程'
+    //   : '请设置条件'
+    // return index == nodeConfig.conditionNodes.length - 1 &&
+    //   nodeConfig.conditionNodes[0].conditionList.length != 0
+    //   ? '其他条件进入此流程'
+    //   : '请设置条件'
+    console.log('index===>', index);
+    console.log('nodeConfig.conditionNodes.length===>', nodeConfig.conditionNodes.length);
+    if( index === nodeConfig.conditionNodes.length - 1) {
+      return '其它情况将进入该分支'
+    } else {
+      return '请设置条件'
+    }
+    
   } else {
     let str = ''
     for (let i = 0; i < conditionList.length; i++) {
@@ -163,7 +175,7 @@ export const removeEle = (arr, elem, key = 'id') => {
   arr.splice(includesIndex, 1)
 }
 
-export const bgColors = ['87, 106, 149', '255, 148, 62', '50, 150, 250']
+export const bgColors = ['87, 106, 149', '255, 148, 62', '50, 150, 250','50, 150, 250','248, 107, 248']
 export const placeholderList = ['发起人', '审核人', '抄送人']
 export const setTypes = [
   { value: 1, label: '指定成员' },

+ 36 - 4
src/components/SimpleProcessDesigner/theme/workflow.css

@@ -1174,15 +1174,47 @@ html {
     box-shadow: 0 2px 5px 0 rgba(0, 0, 0, .1)
 }
 
-.dingflow-design .auto-judge .title-wrapper {
+/* .dingflow-design .auto-judge .title-wrapper {
     position: relative;
     font-size: 12px;
     color: #15bc83;
     text-align: left;
-    line-height: 16px
+    height: 24px;
+    line-height: 24px;
+    width: 258px;
+} */
+.dingflow-design  .title-wrapper {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    position: relative;
+    font-size: 12px;
+    border-radius: 4px 4px 0 0;
+    text-align: left;
+    height: 24px;
+    line-height: 24px;
+    width: 220px;
+    color: #fff;
+}
+.dingflow-design  .title-wrapper .editable-title {
+    max-width: 120px;
+    padding-left: 10px;
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis
+}
+.dingflow-design  .title-wrapper .close {
+    padding-right: 10px;
 }
 
-.dingflow-design .auto-judge .title-wrapper .editable-title {
+/* .dingflow-design  .title-wrapper .priority-title {
+    display: inline-block;
+    float: right;
+    margin-right: 10px;
+    color: rgba(25, 31, 37, .56)
+} */
+
+/* .dingflow-design .auto-judge .title-wrapper .editable-title {
     display: inline-block;
     max-width: 120px;
     overflow: hidden;
@@ -1195,7 +1227,7 @@ html {
     float: right;
     margin-right: 10px;
     color: rgba(25, 31, 37, .56)
-}
+} */
 
 .dingflow-design .auto-judge .placeholder {
     color: #bfbfbf

+ 86 - 30
src/views/bpm/simpleWorkflow/index.vue

@@ -8,31 +8,17 @@
         </el-col>
       </el-row>
       <div class="box-scale">
-        <!-- <div class="start-event-node">
-          <div class="start-event-node-text">流程开始</div>
-          <div class="start-event-node-circle"></div>
-          <div class="start-event-node-flow">
-            <el-popover placement="right-start" width="auto">
-              <div class="add-node-popover-body">
-                <a class="add-node-popover-item approver" @click="addType(1)">
-                  <div class="item-wrapper">
-                    <span class="iconfont"></span>
-                  </div>
-                  <p>审批人</p>
-                </a>
-              </div>
-              <template #reference>
-                <button class="btn" type="button">
-                  <span class="iconfont"></span>
-                </button>
-              </template>
-            </el-popover>
-          </div>
-        </div> -->
+        <div class="start-event-node">
+          <div class="start-event-node-circle">开始</div>
+        </div>
+        <div class="start-event-node-line"></div>
         <nodeWrap v-model:nodeConfig="nodeConfig" />
-        <div class="end-node">
+        <!-- <div class="end-node">
           <div class="end-node-circle"></div>
           <div class="end-node-text">流程结束</div>
+        </div> -->
+        <div class="end-event">
+          <div class="end-event-circle">结束</div>
         </div>
       </div>
     </section>
@@ -41,8 +27,8 @@
 </template>
 <script lang="ts" setup>
 import nodeWrap from '@/components/SimpleProcessDesigner/src/nodeWrap.vue'
-import addNode from '@/components/SimpleProcessDesigner/src/addNode.vue'
 import approverDrawer from '@/components/SimpleProcessDesigner/src/drawer/approverDrawer.vue'
+import { WorkFlowNode } from '@/components/SimpleProcessDesigner/src/consts'
 import { ref } from 'vue'
 import { saveBpmSimpleModel, getBpmSimpleModel } from '@/api/bpm/simple'
 defineOptions({ name: 'SimpleWorkflowDesignEditor' })
@@ -51,23 +37,34 @@ const router = useRouter() // 路由
 const { query } = useRoute() // 路由的查询
 const modelId = query.modelId
 const message = useMessage() // 国际化
-const nodeConfig = ref({
-  name: '流程开始',
-  type: -1,
-  id: 'StartEvent_' + uid,
-  childNode: undefined
-})
+const nodeConfig = ref<WorkFlowNode>({
+    name: '发起人',
+    type: 0,
+    id: 'StartEvent_' + uid,
+    childNode: undefined,
+    attributes: undefined,
+    conditionNodes: undefined
+  }
+)
 const test = async () => {
   if (!modelId) {
     message.error('缺少模型 modelId 编号')
     return
   }
+  const test = nodeConfig.value;
+  console.log('test is ', test)
+  console.log('nodeConfig.value ', nodeConfig.value)
   const data = {
     modelId: modelId,
     simpleModelBody: toRaw(nodeConfig.value)
   }
+  const data1 = {
+    modelId: modelId,
+    simpleModelBody: nodeConfig.value
+  }
   console.log('request json data is ', data)
-  const result = await saveBpmSimpleModel(data)
+  console.log('request json data1 is ', data1)
+  const result = await saveBpmSimpleModel(data1)
   console.log('save the result is ', result)
   if (result) {
     message.success('修改成功')
@@ -91,4 +88,63 @@ onMounted(async () => {
 </script>
 <style>
 @import url('@/components/SimpleProcessDesigner/theme/workflow.css');
+
+.end-event {
+  display: flex;
+  direction: columns;
+  justify-content: center;
+  align-items: center;
+}
+
+.end-event-circle {
+  display: flex;
+  width: 40px;
+  height: 40px;
+  font-size: 14px;
+  color: #f8f8fa;
+  background-image: linear-gradient(-30deg,#bbbbc4,#d5d5de),linear-gradient(#bcbcc5,#bcbcc5);
+  border-radius: 50%;
+  justify-content: center;
+  align-items: center;
+}
+
+/* .start-event-node {
+  color: #191f2566;
+  text-align: left;
+  border-radius: 50%;
+} */
+.start-event-node {
+  display: flex;
+  direction: columns;
+  justify-content: center;
+  align-items: center;
+}
+
+.start-event-node-circle {
+  display: flex;
+  width: 40px;
+  height: 40px;
+  align-items: center;
+  justify-content: center;
+  font-size: 14px;
+  color: #f8f8fa;
+  background-image: linear-gradient(90deg,#ff6a00,#f78b3e),linear-gradient(#ff6a00,#ff6a00);
+  border-radius: 50%;
+}
+
+.start-event-node-line::before {
+    position: absolute;
+    inset: 0;
+    z-index: -1;
+    width: 2px;
+    height: 100%;
+    margin: auto;
+    background-color: #cacaca;
+    content: "";
+}
+
+.start-event-node-line {
+  position: relative;
+  padding: 20px 0 32px;
+}
 </style>