Browse Source

页面更新

sr 4 years ago
parent
commit
3d6da0ba95

+ 1 - 0
ruoyi-ui/package.json

@@ -38,6 +38,7 @@
   "dependencies": {
     "@riophae/vue-treeselect": "0.4.0",
     "axios": "0.21.0",
+    "burgeon-ui": "^1.0.56",
     "clipboard": "2.0.6",
     "core-js": "3.8.1",
     "echarts": "4.9.0",

+ 123 - 0
ruoyi-ui/src/api/layoutAlgorithm.js

@@ -0,0 +1,123 @@
+
+// 查找数组中最后一个不为空的值,获取可使用空位,为了找出这一行是否能够存放当前元素。
+// 返回值为该行可放的空格数
+function getLastNotNull(array) {
+  let canUseLength = array.length;
+  // 数组取反,获取到第一个不为空的值,则判断出该行可放的空格数量
+  array.reverse().every((item, index) => {
+    if (item) {
+      canUseLength = index;
+      return false;
+    }
+    return true;
+  });
+  return canUseLength;
+}
+
+
+// 判断从当前空格开始填,是否所有空格都能够放入
+// currentRow:当前开始填充行
+// currentCol:当前开始填充列
+// pointer:当前元素的数据,宽高
+// ListsMap:当前整个填充块的
+// defaultColumn:默认一列的行数
+function checkAllSpace(currentRow, currentCol, pointer, ListsMap, defaultColumn) {
+  const rowArray = Array(pointer.row).fill(null);
+  const colArray = Array(pointer.col).fill(null);
+  
+  let flag = true;
+  rowArray.map((item, row) => {
+    colArray.map((temp, col) => {
+      if (ListsMap[row + currentRow][col + currentCol]) {
+        flag = false;
+      }
+    });
+  });
+  if ((currentCol + pointer.col) > defaultColumn) {
+    flag = false;
+  }
+  return flag;
+}
+
+
+// defaultColumn:默认每行的列数
+// lists:[{  //每一个item的行和宽
+//   row:,
+//   col:
+// }]
+// type:fill  填充  newline  换行
+// 返回值是在lists的item中添加x,y属性:
+// {
+//   y:i+1,  //列
+//   x:j+1,  //行
+//   row:pointer.row, //行高
+//   col:pointer.col  //宽高
+// }
+function layoutAlgorithm(defaultColumn, lists, type = 'fill') {
+  // 定义每一行的空数据defaultRow
+  const defaultRow = Array(defaultColumn).fill(null);
+  // 定义最大行数
+  const num = lists.reduce((sum, current) => { sum += (!current.row || current.row < 1) ? 1 : current.row; return sum; }, 0);
+  const sumArray = Array(num).fill(null);
+
+  // 定义map模型 默认 50*defaultColumn的布局
+  const ListsMap = sumArray.concat([]).reduce((currentValue) => {
+    currentValue.push(defaultRow.concat([]));
+    return currentValue;
+  }, []);
+
+
+  const coordinateMap = {};
+  // 遍历配置文件的行列数,获取对应的grid布局坐标
+  lists.every((pointer, pointerIndex) => {
+    // 对初始化数据进行判断处理
+    // 当列数大于默认分列时,将当前元素列改为默认的分列数
+    // 当当前项没有设置宽高,默认设为1
+    if (pointer.show === false) { // 当属性show为false时,则默认返回位置(-1,-1)即不显示该节点
+      if (!coordinateMap[pointerIndex]) { // 记录起始的行列以及宽高,作为function返回值
+        pointer.x = -1;
+        pointer.y = -1;
+        coordinateMap[pointerIndex] = pointer;
+      }
+      return true;
+    }
+    pointer.col = (!pointer.col || pointer.col < 1) ? 1 : pointer.col;
+    pointer.col = pointer.col > defaultColumn ? defaultColumn : pointer.col;
+    pointer.row = (!pointer.row || pointer.row < 1) ? 1 : pointer.row;
+    ListsMap.every((item, i) => item.every((temp, j) => {
+      // 当类型为换行时,判断该行是否可放入,不可放入时则换行
+      if (type === 'newline') {
+        if (getLastNotNull([].concat(item)) < pointer.col) {
+          return true;
+        }
+      }
+      // 当类型为填充时,才执行checkAllSpace,对对应的所有空格进行可填充判断
+      if (!temp && (type === 'fill' ? checkAllSpace(i, j, pointer, ListsMap, defaultColumn) : true)) { // 为空时可放
+        if (!coordinateMap[pointerIndex]) { // 记录起始的行列以及宽高,作为function返回值
+          pointer.x = j + 1;
+          pointer.y = i + 1;
+          coordinateMap[pointerIndex] = pointer;
+        }
+        // 将对应的点打上标记
+        const rowArray = Array(pointer.row).fill(null);
+        const colArray = Array(pointer.col).fill(null);
+        rowArray.map((item, row) => {
+          colArray.map((temp, col) => {
+            ListsMap[i + row][j + col] = `k${pointerIndex}`;
+            return true;
+          });
+          return true;
+        });
+
+        return false;
+      }
+      return true;
+    }));
+    return true;
+  });
+
+  return coordinateMap;
+} 
+
+
+export default layoutAlgorithm;

BIN
ruoyi-ui/src/assets/images/success.mp4


+ 1200 - 0
ruoyi-ui/src/components/DynamicProcessNodeConfig/index.vue

@@ -0,0 +1,1200 @@
+<template>
+  <!-- 过程节点配置 -->
+  <div class="DynamicProcessNodeConfig">
+    <div>
+      <div class="splitItem">节点配置</div>
+      <div class="nodeSetbox">
+        <Form>
+          <!-- 节点名称 -->
+          <FormItem label="节点名称:" :label-width="100">
+            <Input v-model="configData.name" placeholder="请输入" :disabled="readOnly"/>
+          </FormItem>
+
+          <!-- 单据类型选择 -->
+          <FormItem label="单据类型:" :label-width="100" >
+            <DropDownSelectFilter
+              :disabled="readOnly"
+              v-bind="tableConfig.props"
+              v-on="tableConfig.event"
+            >
+
+            </DropDownSelectFilter>
+          </FormItem>
+
+          <!-- 可见按钮 -->
+          <FormItem label="可见按钮:" :label-width="100">
+            <Select v-model="configData.visibleBt" :disabled="readOnly" multiple @on-change="visibleBtChange" >
+              <Option v-for="(item,index) in visibleButtons" :key="index" :value="item.ID">{{item.Label}}</Option>
+            </Select>
+          </FormItem>
+
+          <!-- 节点必经 -->
+          <FormItem label="节点必经:" :label-width="100">
+            <Select v-model="configData.inevitable" :disabled="readOnly" >
+              <Option  :value="0" :key="0">是</Option>
+              <Option  :value="1" :key="1">否</Option>
+              <Option  :value="2" :key="2">扩展</Option>
+            </Select>
+          </FormItem>
+          <FormItem  :label-width="100" v-if="configData.inevitable === 2">
+            <label slot="label"><i class="requireStyle">*</i>规则配置:</label>
+            <RuleConfig headTitle="节点必经规则" :tableConfig="{tableId:configData.nodeFormId,tableName:configData.nodeForm}" :defaultData="configData.inevitableExts" @getResult="inevitableResult"></RuleConfig>
+          </FormItem>
+
+          <!-- 节点指派 -->
+          <FormItem label="节点必指派:" :label-width="100">
+            <Select v-model="configData.assignNode" :disabled="readOnly" >
+              <Option  :value="0" :key="0">是</Option>
+              <Option  :value="1" :key="1">否</Option>
+            </Select>
+          </FormItem>
+
+          <!-- 审批人 -->
+          <FormItem  :label-width="100">
+            <label slot="label"><i class="requireStyle">*</i>选择操作人:</label>
+            <Select v-model="configData.approverStyle" :disabled="readOnly" @on-change="approverStyleChange">
+              <Option  :value="0" :key="0">直接选择</Option>
+              <Option  :value="1" :key="1">扩展程序</Option>
+            </Select>
+          </FormItem>
+          <FormItem  :label-width="100" v-if="configData.approverStyle === 0">
+            <label slot="label"><i class="requireStyle">*</i>操作人:</label>
+            <complexPop :title="'选择操作人'" :resultData="resultData" :disabled="readOnly" @getTotalResult="getResult"></complexPop>
+          </FormItem>
+          <FormItem  :label-width="100" v-if="configData.approverStyle === 1">
+            <label slot="label"><i class="requireStyle">*</i>扩展程序:</label>
+            <Input v-model="configData.actionConfig[0].handleValue" placeholder="请输入" :disabled="readOnly" />
+          </FormItem>
+
+          <!-- 动态指派操作人 -->
+          <FormItem label="动态指派操作人:" :label-width="110">
+            <!-- <Select v-model="configData.assignApprover" :disabled="readOnly" >
+              <Option  :value="0" :key="0">动态指派节点操作人</Option>
+              <Option  :value="1" :key="1">默认操作人</Option>
+            </Select> -->
+            <i-switch class="switchPage" v-model="configData.assignApprover" :true-value="0" :false-value="1" :disabled="readOnly" />
+          </FormItem>
+
+          <!-- 审批条件 -->
+          <FormItem label="审批条件:" :label-width="100" v-if="configData.category === 'Approval'">
+            <Select v-model="configData.approveCondition" :disabled="readOnly" >
+              <Option  :value="0" :key="0">自定义人数配置</Option>
+              <Option  :value="1" :key="1">会签</Option>
+              <Option  :value="2" :key="2">或签</Option>
+            </Select>
+          </FormItem>
+          <FormItem v-if="configData.approveCondition === 0 && configData.category === 'Approval'">
+              <Row>
+                  <Col span="24" style="display:flex">
+                    <span>
+                      <i class="requireStyle">*</i>
+                      <Icon
+                        v-if="pageBtnData[0].color"
+                        :type="pageBtnData[0].icontype===1?'ios-checkmark-circle':'ios-close-circle'"
+                        :color="pageBtnData[0].color"
+                      />
+                      {{pageBtnData[0].label}}:
+                    </span>
+                    <Input v-model="pageBtnData[0].value"  :regx="/^[0-9]*$/" @on-blur="onBlur(...arguments,0)" style="flex:1" :disabled="readOnly" />
+                  </Col>
+              </Row>
+          </FormItem>
+          <FormItem v-if="configData.approveCondition === 0 && configData.category === 'Approval'">
+              <Row>
+                  <Col span="24" style="display:flex">
+                    <span>
+                      <i class="requireStyle">*</i>
+                      <Icon
+                        v-if="pageBtnData[2].color"
+                        :type="pageBtnData[2].icontype===1?'ios-checkmark-circle':'ios-close-circle'"
+                        :color="pageBtnData[2].color"
+                      />
+                      {{pageBtnData[2].label}}:
+                    </span>
+                    <Input v-model="pageBtnData[2].value"  :regx="/^[0-9]*$/" @on-blur="onBlur(...arguments,2)" style="flex:1" :disabled="readOnly" />
+                  </Col>
+              </Row>
+          </FormItem>
+
+          <!-- 当前可为驳回节点 -->
+          <FormItem label="可为驳回节点:" :label-width="100">
+            <Select v-model="configData.whetherBack" :disabled="readOnly" >
+              <Option  :value="0" :key="0">是</Option>
+              <Option  :value="1" :key="1">否</Option>
+            </Select>
+          </FormItem>
+
+          <!-- 驳回按钮 -->
+          <FormItem label="驳回按钮:" :label-width="100">
+            <i-switch class="switchPage" v-model="configData.nodeBack" :true-value="0" :false-value="1" :disabled="readOnly" />
+          </FormItem>
+
+          <!-- 驳回操作 -->
+          <FormItem label="驳回操作:" :label-width="100" v-if="configData.category === 'Approval'">
+
+            <Select v-model="configData.assignBack" :disabled="readOnly" >
+              <Option  :value="0" :key="0">动态指派(在流程中手动指派节点)</Option>
+              <Option  :value="1" :key="1">指定驳回节点</Option>
+            </Select>
+          </FormItem>
+          <FormItem :label-width="100" v-if="configData.assignBack === 1 && configData.category === 'Approval'">
+            <label slot="label"><i class="requireStyle">*</i>驳回节点:</label>
+            <Select v-model="configData.backId" :disabled="readOnly">
+                <Option v-for="item in rejectedNodes" :value="item.value" :key="item.value">{{ item.label }}</Option>
+            </Select>
+          </FormItem>
+          <!-- <FormItem label="操作人:" :label-width="100" v-if="(configData.assignBack === 0 || configData.assignBack === 1) && configData.category === 'Approval'">
+            <Select v-model="configData.assignApprover" :disabled="readOnly" >
+              <Option  :value="0" :key="0">动态指派(手动指派驳回节点的操作人)</Option>
+              <Option  :value="1" :key="1">默认(下一阶段设置的操作人)</Option>
+            </Select>
+          </FormItem> -->
+
+          <!-- 同意按钮 -->
+          <FormItem label="同意操作:" :label-width="100" v-if="configData.category === 'Approval'">
+            <i-switch class="switchPage" v-model="configData.nodeAgree" :true-value="0" :false-value="1" :disabled="readOnly" />
+          </FormItem>
+
+          <!-- 直接结束流程 -->
+          <FormItem label="直接结束流程:"  :label-width="100" v-if="configData.category === 'Approval'">
+            <i-switch class="switchPage" v-model="configData.manualConfig" :true-value="'1'" :false-value="'0'" :disabled="readOnly" />
+          </FormItem>
+
+
+          <!-- 跳转路径 -->
+          <FormItem label="跳转路径:" :label-width="100">
+            <Input v-model="configData.nodeUrl" placeholder="请输入" :disabled="readOnly"/>
+          </FormItem>
+
+          <!-- 前置事件 -->
+          <FormItem label="前置事件:" :label-width="100">
+            <!-- <Input v-model="configData.nodeUrl" placeholder="请输入" :disabled="readOnly"/> -->
+            <RuleConfig headTitle="前置事件规则" :tableConfig="{tableId:configData.nodeFormId,tableName:configData.nodeForm}" :defaultData="configData.preEvent" @getResult="preEventResult"></RuleConfig>
+          </FormItem>
+
+          <!-- 后置事件 -->
+          <FormItem label="后置事件:" :label-width="100">
+            <!-- <Input v-model="configData.nodeUrl" placeholder="请输入" :disabled="readOnly"/> -->
+            <RuleConfig headTitle="后置事件规则" :tableConfig="{tableId:configData.nodeFormId,tableName:configData.nodeForm}" :defaultData="configData.behindEvent" @getResult="behindEventResult"></RuleConfig>
+          </FormItem>
+
+
+        </Form>
+      </div>
+
+      <div class="splitItem">节点操作权限</div>
+      <div class="nodeSetbox">
+        <Form>
+          <!-- 显示字段 -->
+          <FormItem label="显示字段:" :label-width="100">
+            <Row>
+                <Col span="19">
+                    <DropMultiSelectFilter
+                      :disabled="readOnly"
+                      :single="false"
+                      :totalRowCount="modifyField.totalRowCount"
+                      :pageSize="modifyField.pageSize"
+                      @on-page-change="changePage"
+                      :dataEmptyMessage="modifyField.dataEmptyMessage"
+                      @on-input-value-change="inputChange"
+                      @on-fkrp-selected="OnFkrpSelected"
+                      @on-popper-show="onPopperShow"
+                      @on-clear="onClear"
+                      :data="modifyField.data"
+                      :hidecolumns="modifyField.columns"
+                      :AutoData="modifyField.AutoData"
+                      :default-selected="modifyField.defaultSelected"
+                      :columnsKey="modifyField.columnsKey"
+                    ></DropMultiSelectFilter>
+                </Col>
+                <Col span="4" offset="1">
+                  <span style="color:#5B85E4;cursor:pointer" v-if="configData.modifiableField.length > 0" @click="modifiableFieldClick">{{modifyTableShow?'关闭修改':'更改权限'}}</span>
+                  <span style="color:#ccc;cursor:pointer" v-if="configData.modifiableField.length === 0">更改权限</span>
+                </Col>
+            </Row>
+          </FormItem>
+          <FormItem v-if="modifyTableShow && configData.modifiableField.length > 0">
+            <Row>
+              <Table border height="200" :columns="modifyColumns" :data="configData.modifiableField"></Table>
+            </Row>
+          </FormItem>
+
+          <!-- 作废操作 -->
+          <FormItem label="作废操作:" :label-width="100">
+            <Select v-model="configData.nodeCancle" :disabled="readOnly" >
+              <Option  :value="0" :key="0">直接作废</Option>
+              <Option  :value="1" :key="1">发起作废(提交作废申请)</Option>
+              <Option  :value="2" :key="2">否(不显示作废按钮)</Option>
+            </Select>
+          </FormItem>
+          <FormItem  :label-width="100" v-if="configData.nodeCancle === 1">
+            <label slot="label"><i class="requireStyle">*</i>申请地址:</label>
+            <Input v-model="configData.cancleUrl" placeholder="请输入" :disabled="readOnly"/>
+          </FormItem>
+
+          <!-- 指派流转节点 -->
+          <FormItem label="指派流转节点:" :label-width="100">
+            <Select v-model="configData.assignNext" :disabled="readOnly" >
+              <Option  :value="0" :key="0">是(可批量指派接下来几节点的审批人)</Option>
+              <Option  :value="1" :key="1">否(节点不需要流转)</Option>
+            </Select>
+          </FormItem>
+          <FormItem  :label-width="100" v-if="configData.assignNext === 0">
+            <label slot="label"><i class="requireStyle">*</i>节点范围:</label>
+            <Select v-model="configData.assignRange" multiple :disabled="readOnly" >
+              <Option v-for="item in assignedNodes" :value="item.value" :key="item.value">{{ item.label }}</Option>
+            </Select>
+          </FormItem>
+
+
+        </Form>
+      </div>
+
+      <div class="splitItem">超时设置</div>
+      <div class="nodeSetbox">
+        <div class="boxItem">
+          <Form>
+            <FormItem label="超时提醒:" :label-width="100">
+              <i-switch v-model="status1" @on-change="change1" :disabled="readOnly" />
+            </FormItem>
+            <FormItem label="超时阀值:" :label-width="100" :required="status1" v-if="status1">
+              <Input v-model="setOvertime.threshold" :regx="/^[1-9]\d*$/" :disabled="readOnly">
+                <Select v-model="setOvertime.sources" slot="append" style="width:70px" :disabled="readOnly">
+                  <Option :value="0">小时</Option>
+                  <Option :value="1">天</Option>
+                </Select>
+              </Input>
+            </FormItem>
+            <FormItem label="邮箱接口:" :label-width="100" :required="status1" v-if="status1">
+              <Input v-model="setOvertime.handleValue" :disabled="readOnly" />
+              <!-- <Select v-model="setOvertime.handle_type" slot="prepend" style="width: 90px;dispaly:none">
+                  <Option :value="11">邮箱</Option>
+                  <Option :value="12">钉钉消息</Option>
+              </Select>-->
+              <!-- <span class="tipMessage">超过这个时间段系统将自动发送提醒消息</span> -->
+            </FormItem>
+          </Form>
+        </div>
+        <div class="boxItem" v-if="configData.category === 'Approval'">
+          <Form>
+            <FormItem label="自动处理:" :label-width="100">
+              <i-switch v-model="status2" @on-change="change2" :disabled="readOnly" />
+            </FormItem>
+            <FormItem label="自动处理阀值:" :label-width="100" :required="status2" v-if="status2">
+              <Input v-model="autoDetail.threshold" :regx="/^[1-9]\d*$/" :disabled="readOnly">
+                <Select v-model="autoDetail.sources" slot="append" style="width: 70px" :disabled="readOnly">
+                  <Option :value="0">小时</Option>
+                  <Option :value="1">天</Option>
+                </Select>
+              </Input>
+            </FormItem>
+            <FormItem label="自动处理方式:" :label-width="100" :required="status2" v-if="status2">
+              <Select v-model="autoDetail.handleType" :disabled="readOnly">
+                <Option :value="20">同意</Option>
+                <Option :value="21">驳回</Option>
+              </Select>
+            </FormItem>
+          </Form>
+        </div>
+      </div>
+    </div>
+    <p>
+      <Button type="fcdefault" @click="closeDrawer">取消</Button>
+      <Button type="primary" @click="saveConfig" v-if="!readOnly">确定</Button>
+    </p>
+  </div>
+</template>
+<script>
+import complexPop from "@/components/complexPop";
+import RuleConfig from "@/components/RuleConfig"
+export default {
+  name: "DynamicProcessNodeConfig",
+  components: { complexPop, RuleConfig },
+  props: {
+    configData: {
+      type: Object,
+      default() {
+        return {};
+      }
+    },
+    TABLE_ID: {
+    }, //模版第一步配置表数据
+    node:{},  //当前节点
+    status:null,
+    rejectedNodes:{
+      type: Array,
+      default: () => {
+        return []
+      }
+    },
+    assignedNodes:{
+      type: Array,
+      default: () => {
+        return []
+      }
+    },
+    readOnly:{
+      type:Boolean,
+      default:false
+    }
+  },
+  data() {
+    return {
+      //节点表的配置
+      tableConfig:{
+        props:{
+          columnsKey: ['NAME'],
+          AutoData: [],
+          hidecolumns: ['id'],
+          data: {},
+          totalRowCount: 0,
+          defaultSelected: [],
+          isBackRowItem: true
+        },
+        event:{
+          'on-input-value-change': (value) => {
+              // 外键的模糊搜索
+              this.tableConfig.props.AutoData = []
+              this.$network.post('/p/c/meta/table/list',{DESCRIPTION:value}).then(res => {
+                if(res.data.code === 0){
+                  // this.row = res.data.data.row.concat([])
+                  this.tableConfig.props.AutoData = res.data.data.row.reduce((arr,item) => {
+                    arr.push({
+                      value:item.NAME.val,
+                      id:item.ID.val,
+                      NAME:item.DESCRIPTION.val
+                    })
+                    return arr
+                  },[]);
+                }
+
+              })
+          },
+          'on-popper-show': ($this) => {
+            // 当外键下拉站开始去请求数据
+            // this.freshDropDownSelectFilterData($this)
+            this.$network.post('/p/c/meta/table/list',{
+              pageSize:$this.pageSize,
+              page:1
+            }).then(res => {
+              if(res.data.code === 0){
+                res.data.data.tabth.forEach(item => {
+                  if(item.colname === 'DESCRIPTION'){
+                    item.isak = true
+                  }
+                  return item
+                })
+                this.tableConfig.props.data = res.data.data;
+                this.tableConfig.props.totalRowCount = res.data.data.totalRowCount;
+              }
+
+            })
+          },
+          'on-page-change': (currentPage, $this) => {
+            // 外键的分页查询
+            // this.freshDropDownSelectFilterData($this,currentPage)
+            this.$network.post('/p/c/meta/table/list',{
+              pageSize:$this.pageSize,
+              page:currentPage
+            }).then(res => {
+              if(res.data.code === 0){
+                res.data.data.tabth.forEach(item => {
+                  if(item.colname === 'DESCRIPTION'){
+                    item.isak = true
+                  }
+                  return item
+                })
+                this.tableConfig.props.data = res.data.data;
+                this.tableConfig.props.totalRowCount = res.data.data.totalRowCount;
+              }
+
+            })
+          },
+          'on-blur':(event,instance) => {
+            // if(Object.prototype.toString.call(this.data.businessType) !== '[object Array]' || this.data.businessType.length === 0){
+            //   instance.inputValue = ''
+
+            //   /*
+            //     todo
+            //     清空所有和主表有关的数据
+            //   */
+
+            // }
+          },
+          'on-fkrp-selected': (value) => {
+            if(value.length > 0){
+              this.configData.nodeForm = value[0].rowItem.NAME.val?value[0].rowItem.NAME.val:value[0].rowItem.NAME
+              this.configData.nodeFormId = value[0].ID
+              this.configData.nodeFormName = value[0].Label
+
+              this.getVisibleButtons()
+            }else{
+              this.configData.nodeForm = null
+              this.configData.nodeFormId = null
+              this.configData.nodeFormName = null
+            }
+
+            // 清除有关字段数据
+            this.onClear()
+            this.modifyField.defaultSelected = []
+            this.configData.behindEvent = []
+            this.configData.preEvent = []
+            this.configData.inevitableExts = []
+            this.configData.visibleBt = []
+          },
+          'on-clear': () => {
+            // 清除有关字段数据
+            this.onClear()
+            this.modifyField.defaultSelected = []
+            this.configData.behindEvent = []
+            this.configData.preEvent = []
+            this.configData.inevitableExts = []
+            this.configData.visibleBt = []
+
+            this.configData.nodeForm = null
+            this.configData.nodeFormId = null
+            this.configData.nodeFormName = null
+            this.tableConfig.props.AutoData = []
+              this.$network.post('/p/c/meta/table/list',{DESCRIPTION:''}).then(res => {
+                if(res.data.code === 0){
+                  this.tableConfig.props.AutoData = res.data.data.row.reduce((arr,item) => {
+                    arr.push({
+                      value:item.NAME.val,
+                      id:item.ID.val,
+                      NAME:item.DESCRIPTION.val
+                    })
+                    return arr
+                  },[]);
+                }
+              })
+          }
+        }
+      },
+
+      visibleButtons:[], // 可见按钮
+
+
+      //修改字段配置
+
+      // 可显示字段
+      modifyField: {
+        modifiable_field: "选中的字段",
+        modifiable_field_name: "", //选中的字段名称1
+        totalRowCount: 0, //数据总条数
+        pageSize: 10, //每页数据条数
+        dataEmptyMessage: "数据为空", //没数据时的提示
+        data: {}, //表格数据
+        columnsKey: ["value"], //input显示的字段
+        columns: ["id"], //模糊搜索隐藏的列
+        AutoData: [],
+        defaultSelected: []
+      },
+      modifyTableShow: false,
+      modifyColumns:[
+        {
+          title: '序号',
+          render: (h, params) => {
+              return h('span', {},params.index + 1);
+          }
+        },
+        {
+          title: '字段名',
+          key: 'Label'
+        },
+        // {
+        //   title: '必填',
+        //   key: 'isnotnull',
+        //   render: (h, params) => {
+        //       return h('Checkbox', {
+        //         props:{
+        //           'value':params.row.isnotnull
+        //         },
+        //         on:{
+        //           'on-change': (value) => {
+        //             this.configData.modifiableField[params.index].isnotnull = value
+        //           }
+        //         }
+        //       });
+        //   }
+        // },
+        {
+          title: '只读',
+          key: 'readonly',
+          render: (h, params) => {
+              return h('Checkbox', {
+                props:{
+                  'value':params.row.readonly
+                },
+                on:{
+                  'on-change': (value) => {
+                    this.configData.modifiableField[params.index].readonly = value
+                  }
+                }
+              });
+          }
+        },
+        {
+          title:'操作',
+          render:(h,params) => {
+            return h('span',{
+              style:{
+                color:'rgba(16, 142, 233, 1)',
+                cursor:'pointer'
+              },
+              on:{
+                click:() => {
+                  this.configData.modifiableField = this.configData.modifiableField.filter((item,index) => index !== params.index)
+                  this.modifyField.defaultSelected = this.configData.modifiableField
+                  if(this.modifyField.defaultSelected.length === 0){
+                    this.modifyTableShow = false
+                  }
+                }
+              }
+            },'删除')
+          }
+        }
+      ],
+
+      pageBtnData: [
+        {
+          label: "最少同意人数",
+          icontype: 1,
+          color: "#09A155",
+          value: ""
+        },
+        {
+          label: "同意状态别名",
+          icontype: 1,
+          color: "#09A155",
+          value: ""
+        },
+        {
+          label: "最少拒绝人数",
+          icontype: 2,
+          color: "#ED4014",
+          value: ""
+        },
+        {
+          label: "拒绝状态别名",
+          icontype: 2,
+          color: "#ED4014",
+          value: ""
+        }
+      ],
+      status1: false, //超时提醒
+      status2: false, //自动处理
+      openControl: false, //控制弹框是否显示
+      loading: false, // z最大loading
+      resultData: {}, // 选中结果
+      open: false, // 是否打开
+      obj: {}, //传给table的对象
+      saveObj: {}, //存储的每次节点的对象
+      selectRow: [], //弹框多选单击一行的数据
+      approves: "", //审批相关数据
+      setOvertime: {
+        threshold: "",
+        sources: 0,
+        status: 1,
+        handleValue: "",
+        handleType: 11,
+        extraMsg: ""
+      },
+      autoDetail: {
+        threshold: "",
+        sources: 0,
+        status: 1,
+        handleType: 20,
+        extraMsg: "",
+        handleValue: ""
+      },
+      approvelList: [], //存放审批相关的数据
+      closeType: false, //控制审批确定取消显示状态
+      isCallInterface: false,
+
+      defaultObj:{},  //默认数据
+
+
+
+    };
+  },
+  computed: {
+    tableInfo () {
+      return {tableId:this.configData.nodeFormId,tableName:this.configData.nodeForm}
+    },
+    actServiceS() {
+      return [this.setOvertime, this.autoDetail];
+    }
+  },
+  watch: {
+    pageBtnData: {
+      handler(newVal) {
+
+        let temArr = [
+          {
+            actType: 0,
+            actName: newVal[1].value,
+            actLimit: newVal[0].value
+          },
+          {
+            actType: 1,
+            actName: newVal[3].value,
+            actLimit: newVal[2].value
+          }
+        ];
+        if (this.configData.ruleList.length < 1) {
+          this.configData.ruleList = temArr;
+        } else {
+          this.configData.ruleList.map((item) => {
+            temArr.map(inner => {
+              if (item.actType === inner.actType) {
+                item = Object.assign(item, inner);
+              }
+            });
+          });
+        }
+      },
+      deep: true
+    },
+    actServiceS: {
+      handler(newVal) {
+        this.configData.actServiceS = newVal;
+      },
+      deep: true
+    },
+    approvelList: {
+      handler(newVal) {
+        this.configData.approvelList = newVal;
+      },
+      deep: true
+    }
+  },
+  methods: {
+    onBlur(event, ins, key) {
+      let res = /^[0-9]*$/;
+      if (res.test(key)) {
+        if (this.pageBtnData[key].value === "" && key == 0) {
+          this.$Message.warning("最少同意人数不能为空");
+        }
+        if (this.pageBtnData[key].value === "" && key == 1) {
+          this.$Message.warning("同意状态别名不能为空");
+        }
+        if (this.pageBtnData[key].value === "" && key == 2) {
+          this.$Message.warning("最少拒绝人数不能为空");
+        }
+        if (this.pageBtnData[key].value === "" && key == 3) {
+          this.$Message.warning("拒绝状态别名不能为空");
+        }
+      }
+    },
+    //可显字段下拉多选事件
+    OnFkrpSelected(selected) {
+      if(selected.length === 0){
+        this.modifyTableShow = false
+      }
+      selected.map(item => {
+        // item.isnotnull = false
+        item.readonly = false
+        return item
+      })
+      this.modifyField.modifiableField = selected;
+      this.configData.modifiableField = selected;
+    },
+    onPopperShow() {
+      //下拉多选
+      this.findField({ AD_TABLE_ID: this.configData.nodeFormId });
+    },
+    changePage(val) {
+      this.findField({
+        pageSize: this.modifyField.pageSize,
+        page: val,
+        AD_TABLE_ID: this.configData.nodeFormId
+      });
+    },
+    modifiableFieldClick () {  //可显字段只读/必填控制
+      if(this.modifyTableShow){  //保存权限
+
+      }else{  //更改权限
+
+      }
+
+      this.modifyTableShow = !this.modifyTableShow
+    },
+    //模糊查找input事件
+    inputChange(val) {
+      this.findField({ DESCRIPTION: val, AD_TABLE_ID: this.configData.nodeFormId });
+    },
+    onClear() {
+      this.modifyTableShow = false
+      this.modifyField.modifiableField = [];
+      this.configData.modifiableField = [];
+    }, //可显字段清除事件
+    change1(val) {
+      this.status1 = val;
+      this.setOvertime = {
+        threshold: "",
+        sources: 0,
+        status: 1,
+        handleValue: "",
+        handleType: 11,
+        extraMsg: "",
+        id:this.setOvertime.id
+      }
+
+      if (val) {
+        this.setOvertime.status = 0;
+      } else {
+        this.setOvertime.status = 1;
+      }
+    },
+    change2(val) {
+      this.status2 = val;
+      this.autoDetail = {
+        threshold: "",
+        sources: 0,
+        status: 1,
+        handleType: 20,
+        extraMsg: "",
+        handleValue: "",
+        id:this.autoDetail.id
+      }
+      if (val) {
+        this.autoDetail.status = 0;
+      } else {
+        this.autoDetail.status = 1;
+      }
+    },
+    getResult(data) {
+      this.resultData = Object.assign({}, data);
+      if (this.resultData.list.length > 0) {
+        this.approvelList = this.resultData.list.map(item => {
+          let tem = Object.assign({}, item);
+          delete tem.string;
+          return tem;
+        });
+      } else {
+        this.approvelList = [];
+      }
+    },
+    //获取可修改字段
+    findField(param) {
+      this.$network.post("/p/c/meta/column/list", param).then(res => {
+        if (res.data.code === 0) {
+          if (param.hasOwnProperty("DESCRIPTION")) {
+            this.modifyField.AutoData = [];
+            this.modifyField.AutoData = res.data.data.row.reduce(
+              (arr, item) => {
+                arr.push({
+                  value: item.DESCRIPTION.val,
+                  id: item.ID.val
+                });
+                return arr;
+              },
+              []
+            );
+          }
+          res.data.data.tabth.map(item => {
+            if (item.colname === "DESCRIPTION") {
+              item.isak = true;
+            } else {
+              item.isak = false;
+            }
+          });
+          this.modifyField.data = res.data.data;
+          this.modifyField.totalRowCount = res.data.data.totalRowCount;
+        }
+      });
+    },
+
+    saveConfig () {  //确定按钮点击
+
+      // 节点必经
+      if(this.configData.inevitable === 2 && (!this.configData.inevitableExts || this.configData.inevitableExts.length === 0)){
+        this.$Modal.fcError({
+            title: '错误',
+            content: '规则配置不能为空',
+            mask: true
+          })
+          return
+      }
+
+      // 操作人
+      if(this.configData.approverStyle === 0){  //直接选择
+        // 审批人为空
+        if(this.configData.approvelList && this.configData.approvelList.length === 0){
+          this.$Modal.fcError({
+            title: '错误',
+            content: '审批人不能为空',
+            mask: true
+          })
+
+          return
+        }
+      }else{  //扩展程序
+        // 扩展程序为空
+        if(this.configData.actionConfig[0] && !this.configData.actionConfig[0].handleValue){
+          this.$Modal.fcError({
+            title: '错误',
+            content: '扩展程序不能为空',
+            mask: true
+          })
+          return
+        }
+      }
+
+      // 审批条件
+      if(this.configData.approveCondition === 0){
+        // 最少同意人数
+        if(!this.pageBtnData[0].value){
+          this.$Modal.fcError({
+              title: '错误',
+              content: '最少同意人数不能为空',
+              mask: true
+            })
+          return
+        }
+        // 最少拒绝人数
+        if(!this.pageBtnData[2].value){
+          this.$Modal.fcError({
+              title: '错误',
+              content: '最少拒绝人数不能为空',
+              mask: true
+            })
+          return
+        }
+      }
+
+
+      // 驳回节点
+      if(this.configData.assignBack === 1 && !this.configData.backId){
+        this.$Modal.fcError({
+            title: '错误',
+            content: '驳回节点不能为空',
+            mask: true
+          })
+        return
+      }
+
+      // 作废操作 --发起作废申请
+      if(this.configData.nodeCancle === 1 && !this.configData.cancleUrl){
+        this.$Modal.fcError({
+            title: '错误',
+            content: '作废申请地址不能为空',
+            mask: true
+          })
+        return
+      }
+
+      // 指派流转节点
+      if(this.configData.assignNext === 0 && (!this.configData.assignRange || this.configData.assignRange.length === 0)){
+        this.$Modal.fcError({
+            title: '错误',
+            content: '节点范围不能为空',
+            mask: true
+          })
+        return
+      }
+
+      // 超时提醒
+      if(this.status1 && (!this.setOvertime.threshold || !this.setOvertime.handleValue)){
+        this.$Modal.fcError({
+            title: '错误',
+            content: '请填写完善超时提醒信息',
+            mask: true
+          })
+        return
+      }
+      //自动处理
+      if(this.status2 && (!this.autoDetail.threshold)){
+        this.$Modal.fcError({
+            title: '错误',
+            content: '请填写完善自动处理信息',
+            mask: true
+          })
+        return
+      }
+
+      // 控制自动处理时间大于超时提醒时间
+      if(this.status1 && this.status2){
+        let start = this.setOvertime.sources === 0?Number(this.setOvertime.threshold):Number(this.setOvertime.threshold)*24
+        let end = this.autoDetail.sources === 0?Number(this.autoDetail.threshold):Number(this.autoDetail.threshold)*24
+
+        if(start >= end){
+          this.$Modal.fcError({
+              title: '错误',
+              content: '超时提醒时间不能大于自动处理时间',
+              mask: true
+            })
+          return
+        }
+      }
+
+      let guiStyle = JSON.parse(this.$parent.$parent.myDesigner.getFlowData())
+      guiStyle.nodeDataArray.map(item => {
+        if(this.configData.key === item.key){
+          item.text = this.configData.name
+        }
+        return item
+      })
+
+
+      if((this.defaultObj.nodeFormId !== this.configData.nodeFormId) && this.defaultObj.nodeFormId){
+        this.$Modal.fcError({
+          title: '错误',
+          content: '当前节点的表单已修改,节点后的连线配置将会清空,是否确认保存?',
+          mask: true,
+          showCancel: true,
+          onOk: () => {
+            this.node.findLinksOutOf().map(item => {
+              delete this.$parent.$parent.pathMsg[item.data.key]
+
+              let guiStyle = JSON.parse(this.$parent.$parent.myDesigner.getFlowData())
+              guiStyle.linkDataArray = guiStyle.linkDataArray.filter(temp => temp.key !== item.data.key)
+            })
+            this.$parent.$parent.data.guiStyle = JSON.stringify(guiStyle)
+            this.$parent.$parent.init()
+            this.$emit('closeDrawer')
+          }
+        })
+        return
+      }else{
+        this.$parent.$parent.data.guiStyle = JSON.stringify(guiStyle)
+        this.$parent.$parent.init()
+        this.$emit('closeDrawer')
+      }
+
+    },
+    closeDrawer () {  //取消按钮点击
+      this.$parent.$parent.nodeMsg[Number(this.configData.key)] = this.defaultObj
+      this.$emit('closeDrawer')
+    },
+    approverStyleChange () {  //选择审批人类型切换
+      this.configData.actionConfig[0].handleValue = null
+      this.resultData = {}
+      this.approvelList = [];
+    },
+
+    // 审批条件 扩展
+    inevitableResult (value) {
+      this.configData.inevitableExts = value
+    },
+    preEventResult (value) {  //前置事件处理
+      this.configData.preEvent = value
+    },
+    behindEventResult (value) { //后置事件处理
+      this.configData.behindEvent = value
+    },
+    getVisibleButtons () { //获取可见按钮
+      this.$network.post('/p/cs/node/define/bt',{
+        id: this.configData.nodeFormId,
+        vueDispaly: 0
+      })
+      .then(res => {
+        if(res.data.resultCode === 0){
+          this.visibleButtons = res.data.data.difineData
+        }else{
+          this.visibleButtons = []
+        }
+      })
+    },
+    visibleBtChange (value) {  //可见按钮选择
+      if(value[0] === 'bSelect-all'){
+        this.configData.visibleBt = this.visibleButtons.reduce((arr,current) => {
+          arr.push(current.ID)
+          return arr
+        },[])
+      }
+    }
+  },
+  created() {
+    // 保存默认值
+    this.defaultObj = JSON.parse(JSON.stringify(this.configData))
+
+    if (this.configData.actionConfig.length === 0) {
+      this.configData.actionConfig = [
+        {
+          id: null,
+          handleType: 33,
+          handleValue: null,
+          extraMsg: null
+        }
+      ];
+    } else {
+      this.configData.actionConfig = [
+        {
+          id: this.configData.actionConfig[0].id,
+          handleType: 33,
+          handleValue: this.configData.actionConfig[0].handleValue,
+          extraMsg: this.configData.actionConfig[0].extraMsg
+        }
+      ];
+    }
+
+    if (this.configData.modifiableField) {
+      this.modifyField.defaultSelected = this.configData.modifiableField
+    }
+
+
+    if (
+      this.configData.approvelList &&
+      this.configData.approvelList.length > 0
+    ) {
+      this.configData.approvelList.map(item => {
+        let temObj = Object.assign({}, item);
+        this.approves += item.approveValueName?item.approveValueName:item.approve_value_name + ",";
+        temObj.approve_type = temObj.approveType?temObj.approveType:temObj.approve_type;
+        temObj.approve_value = temObj.approveValue?temObj.approveValue:temObj.approve_value;
+        temObj.approve_value_name = item.approveValueName?item.approveValueName:item.approve_value_name;
+        delete temObj.approveType;
+        delete temObj.approveValue;
+        delete temObj.approveValueName;
+
+        let temL = Object.assign({}, temObj);
+        this.approvelList.push(temObj);
+        temL.string = item.approveValueName?item.approveValueName:item.approve_value_name;
+        this.resultData.list
+          ? this.resultData.list.push(temL)
+          : this.$set(this.resultData, "list", [temL]);
+      });
+      this.resultData.total
+        ? (this.resultData.total = this.resultData.list.length)
+        : this.$set(this.resultData, "total", this.resultData.list.length);
+      if (this.approves.length > 0) {
+        this.approves = this.approves.substring(0, this.approves.length - 1);
+      }
+    }
+
+    if (
+      this.configData.ruleList &&
+      this.configData.ruleList.length > 0
+    ) {
+      this.configData.ruleList.map(item => {
+        if (item.actType === 0) {
+          this.pageBtnData[1].value = item.actName;
+          this.pageBtnData[0].value = item.actLimit;
+        }
+        if (item.actType === 1) {
+          this.pageBtnData[3].value = item.actName;
+          this.pageBtnData[2].value = item.actLimit;
+        }
+      });
+    }
+
+    if (
+      this.configData.actServiceS &&
+      this.configData.actServiceS.length > 0
+    ) {
+      this.configData.actServiceS.map(item => {
+        if (item.handleType >= 20) {
+          this.autoDetail = item;
+        } else {
+          this.setOvertime = item;
+        }
+      });
+      this.setOvertime.status === 0
+        ? (this.status1 = true)
+        : (this.status1 = false);
+      this.autoDetail.status === 0
+        ? (this.status2 = true)
+        : (this.status2 = false);
+    } else {
+      this.configData.actServiceS = [
+        {
+          threshold: "",
+          sources: 0,
+          status: 1,
+          handleValue: "",
+          handleType: 11
+        },
+        {
+          threshold: "",
+          sources: 0,
+          status: 1,
+          handleType: 20,
+          handleValue: ""
+        }
+      ];
+    }
+
+    // 处理节点表配置默认值
+    if(this.configData.nodeFormId){
+      this.tableConfig.props.defaultSelected = [
+        {
+          ID: this.configData.nodeFormId,
+          Label: this.configData.nodeFormName
+        }
+      ]
+    }
+
+    // 可见按钮
+    if(this.configData.nodeFormId){
+      this.getVisibleButtons()
+    }
+  },
+  mounted() {
+    //this.getTreeData();
+    /**/
+  }
+};
+</script>
+<style lang="scss">
+.DynamicProcessNodeConfig {
+  overflow-y: hidden;
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+  >p{
+      text-align: right;
+      margin-top: 16px;
+
+      >button:first-child{
+        margin-right: 10px;
+      }
+    }
+  >div{
+    flex: 1;
+    overflow: auto;
+  }
+  .nodeSetbox {
+    padding: 16px;
+    border: 1px solid #dcdee2;
+    .boxItem {
+      padding: 16px 40px;
+      border-bottom: 1px solid #dcdee2;
+      &:last-child {
+        border-bottom: none;
+      }
+    }
+    .tipMessage {
+      color: #929292;
+      line-height: 16px;
+    }
+    .burgeon-form-item {
+      margin-bottom: 16px;
+      &:last-child {
+        margin-bottom: 0px;
+      }
+    }
+    &:last-child {
+      padding: 0;
+    }
+  }
+  .requireStyle {
+    font-size: 14px;
+    vertical-align: middle;
+    color: red;
+    padding-top: 5px;
+    display: inline-block;
+  }
+  .splitItem {
+    font-size: 14px;
+    line-height: 40px;
+    color: #929292;
+    &:first-child{
+      margin-top: -10px;
+    }
+  }
+  .burgeon-fkrp-select-icon {
+    top: 2px;
+  }
+}
+</style>

+ 559 - 0
ruoyi-ui/src/components/FlowChartComponent/index.vue

@@ -0,0 +1,559 @@
+<template>
+  <div class="FlowChartComponent">
+    <!-- <Alert show-icon closable v-if="currentSteps === 1">双击空白区域即可直接新增一个中间节点,双击节点可编辑</Alert> -->
+    <div class="chartContent">
+      <div id="paletteDiv"></div>
+      <div id="goChart" v-show="currentSteps === 1">
+      </div>
+      <div id="showChart" v-show="currentSteps === 2">
+      </div>
+    </div>
+
+    <!-- 全局侧滑模块 -->
+    <Drawer
+      v-model="drawerObject.show"
+      transfer
+      :title="drawerObject.title"
+      :width="472"
+      :mask-closable="false"
+      :closable="false"
+      scrollable
+    >
+      <components
+        v-if="drawerObject.show"
+        :configData="drawerObject.configData"
+        :data="drawerObject.configData"
+        :is="drawerObject.component"
+        :TABLE_ID="drawerObject.TABLE_ID"
+        :node="drawerObject.node"
+        :status="drawerObject.status"
+        :rejectedNodes="rejectedNodes"
+        :assignedNodes="assignedNodes"
+        :readOnly="readOnly"
+        :moduleType="data.moduleType"
+        @closeDrawer="closeDrawer"
+      >
+      </components>
+    </Drawer>
+  </div>
+</template>
+<script>
+// import '../__utils__/go'
+// import FlowDesinger from '../__utils__/flow-desinger';
+import startNodeInfo from '@/components/startNodeInfo'
+import endNodeInfo from '@/components/endNodeInfo'
+import linkInfo from '@/components/linkInfo'
+import ProcessNodeConfig from '@/components/ProcessNodeConfig'
+import DynamicProcessNodeConfig from '@/components/DynamicProcessNodeConfig'
+import ServiceNodeConfig from '@/components/ServiceNodeConfig'
+// import FlowDisplay from '../__utils__/flow-display';
+export default {
+  components:{
+    startNodeInfo, endNodeInfo, linkInfo, ProcessNodeConfig, DynamicProcessNodeConfig, ServiceNodeConfig
+  },
+  props:{
+    editable:{  //是否可编辑
+      type:Boolean,
+      default:true
+    },
+    fresh:{
+      type:Boolean,
+      default:false
+    },
+    currentSteps:{
+      type:Number,
+      default:null
+    },
+    noFreshFlag:{
+      type:Boolean,
+      default:false
+    },
+    readOnly:{
+      type:Boolean,
+      default:false
+    },
+    data:{
+      type:Object,
+      default () {
+        return {
+            }
+      }
+    }
+  },
+  data () {
+    return {
+      myDesigner:null,  //画布实例
+      drawerObject:{
+        show:false
+      },
+      nodeMsg:{},  //存放节点数据
+      pathMsg:{},  //存放路径数据
+      rejectedNodes:[],  //驳回节点
+      assignedNodes: [],  //指派节点
+    }
+  },
+  activated () {
+    if(!this.noFreshFlag){
+      this.init()
+    }
+  },
+  deactivated () { //keep-alive 组件停用时调用
+    if(this.currentSteps === 1 && this.myDesigner){
+      this.data.guiStyle = JSON.parse(this.myDesigner.getFlowData())
+    }
+  },
+  methods:{
+    init () {
+        if(!Array.isArray(this.data.nodeMsg)){
+            let nodeMsg = []
+            Object.keys(this.data.nodeMsg).map(item => {
+              nodeMsg.push(this.data.nodeMsg[item])
+              return item
+            })
+
+            this.data.nodeMsg = nodeMsg
+
+            let pathMsg = []
+            Object.keys(this.data.pathMsg).map(item => {
+              pathMsg.push(this.data.pathMsg[item])
+              return item
+            })
+            this.data.pathMsg = pathMsg
+        }
+
+        this.dataProcessing()
+        if(this.currentSteps === 1){
+          // 流程图设计器
+          if(!this.myDesigner){
+            // this.myDesigner= new FlowDesinger('goChart',{
+            //   showEditNode:this.showEditNode,  //节点双击编辑
+            //   SelectionDeleted:this.SelectionDeleted,  //删除事件
+            //   LinkDrawn:this.LinkDrawn,  //线的生成
+            //   externalobjectsdropped:this.externalobjectsdropped,  //节点生成
+            //   LinkRelinked: this.LinkRelinked  //连线修改
+            // });
+
+          }
+
+          this.initToolbar = this.myDesigner.initToolbar('paletteDiv',this.data.moduleType)
+          this.myDesigner.displayFlow(JSON.parse(JSON.stringify(this.data.guiStyle)));// 在设计面板中显示流程图
+          this.data.myDisplay = this.myDesigner.diagram
+        }else{
+          if(this.myDisplay){
+            this.myDisplay.loadFlow(JSON.parse(JSON.stringify(this.data.guiStyle)))
+          }else{
+            this.myDisplay = new FlowDisplay('showChart',{
+              showEditNode:this.showEditNode,  //节点双击编辑
+            });
+            this.myDisplay.loadFlow(JSON.parse(JSON.stringify(this.data.guiStyle)))
+          }
+
+          // this.data.myDisplay = this.myDisplay.diagram
+
+        }
+
+
+    },
+    compare (property) {
+      return function(a,b) {
+        var value1 = a[property];
+        var value2 = b[property];
+        return value1 - value2
+      }
+    },
+    dataProcessing () {  //处理后端返回节点数据和路径数据
+      if(this.data.nodeMsg){
+
+        this.data.nodeMsg.forEach(item => {
+          this.nodeMsg[item.key] = item
+          if(item.type === 2){  //结束节点对数据排序,区分执行程序还是抄送人
+            this.nodeMsg[item.key].actionConfig.sort(this.compare('handleType'))
+          }
+        })
+        this.data.nodeMsg = this.nodeMsg
+      }
+
+      if(this.data.pathMsg){
+        this.data.pathMsg.forEach(item => {
+          this.pathMsg[item.key] = item
+        })
+        this.data.pathMsg = this.pathMsg
+      }
+
+      this.data.removePath = []
+      this.data.removeNode = []
+
+    },
+    showEditNode (node) {  //双击编辑
+
+      // node.findNodesOutOf()
+      if(node.data.type === 1){
+        let defaultObj = {
+          conditionType: 0,
+          ruleList: [],
+          priority: null,
+          defaultPriority: null,
+          modifyId: null,
+          id:null,
+          triggerBt:[],
+          visibleBt:[]
+        }
+        if(!node.data.id){
+          this.nodeMsg[node.data.key] = Object.assign(defaultObj,this.nodeMsg[node.data.key])
+        }
+
+        this.drawerObject = {
+          show: true,
+          component: 'startNodeInfo',
+          configData: this.nodeMsg[node.data.key],
+          title:'开始节点配置'
+        }
+      }
+      if(node.data.type === 2){
+        let defaultObj = {
+          id:null,
+          manualConfig:null,
+          actionConfig:[]
+        }
+        if(!node.data.id){
+          this.nodeMsg[node.data.key] = Object.assign(defaultObj,this.nodeMsg[node.data.key])
+        }
+        this.drawerObject = {
+          show: true,
+          component: 'endNodeInfo',
+          configData: this.nodeMsg[node.data.key],
+          title:'结束节点配置'
+        }
+      }
+
+      // 审批节点和操作节点用同一个配置界面,根据参数控制展示项
+      if(node.data.category === "Approval" || node.data.category === "Operation"){
+        this.rejectedNodes = []
+        this.assignedNodes = []
+        this.findNodesInto(node)
+        this.findNodesOutOf(node)
+        // 默认节点配置
+        let defaultObj = {
+          actServiceS:[],
+          actionConfig:[],
+          approvelList:[],
+          backId:null,
+          id:null,
+          manualConfig:0,
+          modifiableField:[],
+          moduleId:null,
+          name:'中间节点',
+          nodeType:0,
+          ruleList:[],
+          inevitable: 1,  //节点必经
+          approveCondition: 0,  //审批条件
+          assignBack: 0,  //驳回操作
+          whetherBack: 0, //可为驳回节点
+          nodeCancle: 0,  //作废操作
+          assignNext: 1, //指派流转节点
+          assignNode: 1,  //节点是否是必需指派
+          assignApprover: 1,  //是否动态指派操作人
+          visibleBt:[],  //可见按钮
+          nodeBack: 0,  //驳回按钮开关
+          nodeAgree: 0, //同意按钮
+
+        }
+
+        if(this.data.moduleType === 0){
+          defaultObj = {
+            actServiceS:[],
+            actionConfig:[],
+            approvelList:[],
+            backId:null,
+            id:null,
+            manualConfig:0,
+            modifiableField:'',
+            modifiableFieldName:'',
+            moduleId:null,
+            name:'审批节点',
+            nodeType:0,
+            ruleList:[]
+          }
+        }
+
+        if(!node.data.id){
+          this.nodeMsg[node.data.key] = Object.assign(defaultObj,this.nodeMsg[node.data.key])
+        }
+        this.drawerObject = {
+          show: true,
+          component: this.data.moduleType === 0?'ProcessNodeConfig':'DynamicProcessNodeConfig',
+          configData: this.nodeMsg[node.data.key],
+          node: node,
+          title:node.data.category === "Approval"?'审批节点配置':'操作节点'
+        }
+      }
+
+      // 服务节点
+      if(node.data.category === 'Service'){
+        let defaultObj = {
+          id:null,
+          actionConfig:[{
+            "id":null,	    //新增不传,修改传
+            "handleValue":null,	    //具体的关于请求状态,url之类的json
+            "handleType":null,	//51:rest服务实现,52:消息系统
+            "extraMsg":null	//相关参数
+          }]
+        }
+        if(!node.data.id){
+          this.nodeMsg[node.data.key] = Object.assign(defaultObj,this.nodeMsg[node.data.key])
+        }
+        this.drawerObject = {
+          show: true,
+          component: 'ServiceNodeConfig',
+          configData: this.nodeMsg[node.data.key],
+          title:'服务节点配置'
+        }
+      }
+
+      if(node.data.from !== undefined){
+        if(this.nodeMsg[node.data.from].category === 'Service' && this.data.moduleType === 1){
+          return
+        }
+        // 默认连线配置
+        let defaultObj = {
+          endNode:null,
+          moduleId:null,
+          name:null,
+          ruleList:[],
+          sources:null,
+          startNode:null,
+          status:null
+        }
+        if(!node.data.moduleId){
+          this.pathMsg[node.data.key] = Object.assign(defaultObj,this.pathMsg[node.data.key])
+        }
+
+        let tableConfig = [{
+            ID: this.nodeMsg[node.data.from].nodeFormId,
+            value: this.nodeMsg[node.data.from].nodeForm
+          }]
+
+        if(this.nodeMsg[node.data.from].category === 'Start'){
+          tableConfig = [{
+            ID: this.nodeMsg[node.data.from].businessType,
+            value: this.nodeMsg[node.data.from].businessTypeName
+          }]
+        }
+
+        this.drawerObject = {
+          show: true,
+          component: 'linkInfo',
+          configData: this.pathMsg[node.data.key],
+          TABLE_ID: this.data.moduleType === 1?tableConfig:this.data.businessType,
+          title:'连接线配置'
+        }
+      }
+    },
+    findNodesInto (node) {  //查找父节点
+      let parents = node.findNodesInto()
+
+      if(parents.count > 0){
+        node.findNodesInto().map(item => {
+          this.rejectedNodes.push({
+            value:item.data.key,
+            label:item.data.text
+          })
+          this.findNodesInto(item)
+        })
+      }else{
+        return
+      }
+    },
+    findNodesOutOf (node) {  //查找子节点
+      let childrens = node.findNodesOutOf()
+
+      if(childrens.count > 0){
+        node.findNodesOutOf().map(item => {
+          if(item.data.key != -2){
+            this.assignedNodes.push({
+              value:item.data.key,
+              label:item.data.text
+            })
+            this.findNodesOutOf(item)
+          }
+
+        })
+      }else{
+        return
+      }
+    },
+    SelectionDeleted (node) {  //删除节点或者线
+
+      if(node.fromPort !== undefined){  //线的删除
+        delete this.pathMsg[node.key]
+        if(node.id){  //已保存的线
+          this.data.removePath.push(node.id)
+        }
+      }else{  //节点删除
+        delete this.nodeMsg[node.key]
+        if(node.id){
+          this.data.removeNode.push({
+            id:node.id,
+            type:node.type
+          })
+        }
+      }
+    },
+    LinkDrawn (node) {  //连线生成
+      if(!this.judgeLoop()){
+        this.$Modal.fcWarning({
+          title:'警告',
+          content:'流程图中存在回路,请重新设置!!',
+          mask:true
+        })
+
+        this.data.guiStyle = JSON.parse(this.myDesigner.getFlowData())
+        let linkDataArray = this.data.guiStyle.linkDataArray
+        linkDataArray = linkDataArray.filter(item => {
+          return item.key !== node.key
+        })
+
+        this.data.guiStyle.linkDataArray = linkDataArray
+        this.init()
+        // reject()
+        return
+      }else{
+        this.pathMsg[node.key] = node
+        this.pathMsg[node.key].ruleList = []
+      }
+
+    },
+    LinkRelinked (node) {  //连线修改
+      this.pathMsg[node.key].from = node.from
+      this.pathMsg[node.key].to = node.to
+      this.pathMsg[node.key].fromPort = node.fromPort
+      this.pathMsg[node.key].toPort = node.toPort
+    },
+    judgeLoop () {  //判断是否存在闭环  true为没有闭环  false有闭环
+        // 获取所有的节点
+        let data = JSON.parse(this.myDesigner.getFlowData())
+        const edges = data.linkDataArray?data.linkDataArray:JSON.parse(data).linkDataArray;
+        const nodes = [];
+        const list = {}; // 邻接表
+        const queue = []; // 入度为0的节点集合
+        const indegree = {};
+        edges.forEach(e => {
+            const { from, to } = e;
+            if (!nodes.includes(from)) {
+                nodes.push(from);
+            }
+            if (!nodes.includes(to)) {
+                nodes.push(to);
+            }
+            addEdge(from, to);
+        });
+        const V = nodes.length;
+
+        nodes.forEach(node => {
+            if (!indegree[node]) indegree[node] = 0;
+            if (!list[node]) list[node] = [];
+        });
+
+        function addEdge(source, target) {
+            if (!list[source]) list[source] = [];
+            if (!indegree[target]) indegree[target] = 0;
+            list[source].push(target);
+            indegree[target] += 1;
+        }
+        function sort() {
+            Object.keys(indegree).forEach(id => {
+                if (indegree[id] === 0) {
+                    queue.push(id);
+                }
+            });
+            let count = 0;
+            while (queue.length) {
+                ++count;
+                const currentNode = queue.pop();
+                const nodeTargets = list[currentNode];
+                for (let i = 0; i < nodeTargets.length; i++) {
+                    const target = nodeTargets[i];
+                    indegree[target] -= 1;
+                    if (indegree[target] === 0) {
+                        queue.push(target);
+                    }
+                }
+            }
+            // false 没有输出全部顶点,有向图中有回路
+            return !(count < V);
+        }
+
+        return sort();
+    },
+    externalobjectsdropped (node) {  //节点生成
+
+      if(node.category === 'Service' || node.category === 'Subprocesses'){
+        this.nodeMsg[node.key] = node
+        this.nodeMsg[node.key].name = node.text
+        return
+      }
+      this.nodeMsg[node.key] = node
+      this.nodeMsg[node.key].ruleList = []
+      this.nodeMsg[node.key].actServiceS =[
+        {
+          status:1,
+          handleValue:null,
+          handleType:11
+        },
+        {
+          status:1,
+          handleValue:null,
+          handleType:20
+        }
+      ]
+      this.nodeMsg[node.key].actionConfig =[]
+      this.nodeMsg[node.key].approvelList = []
+      this.nodeMsg[node.key].approverStyle = 0
+      this.nodeMsg[node.key].name = node.text
+    },
+    closeDrawer () {  //关闭策划块
+      this.drawerObject = {
+        show: false
+      }
+    }
+  }
+}
+</script>
+<style lang=scss" >
+.FlowChartComponent{
+  width: 100%;
+  height: 100%;
+  overflow: hidden;
+  display: flex;
+  position: relative;
+  flex-direction: column;
+
+  .burgeon-alert{
+    margin-bottom: 0;
+  }
+
+  .chartContent{
+    flex: 1;
+    display: flex;
+  }
+
+  #paletteDiv{
+    padding: 5px;
+    width: 160px;
+    height: 100%;
+    display: inline-block;
+    border-right: 1px solid #dcdee2;
+  }
+
+
+  canvas{
+    outline: none;
+  }
+
+  #goChart,#showChart{
+    flex-grow: 1;
+    flex: 1;
+    // border: solid 1px black
+  }
+}
+</style>

+ 25 - 0
ruoyi-ui/src/components/FlowSuccess/index.vue

@@ -0,0 +1,25 @@
+<template>
+  <div class="FlowSuccess">
+    <video playsinline="" autoplay="" muted="" loop="" width="100%">
+      <source src="@/assets/images/success.mp4" type="video/mp4">
+    </video>
+    <p>模板设置成功啦~</p>
+  </div>
+</template>
+<script>
+export default {
+
+}
+</script>
+<style lang=scss" scoped>
+  .FlowSuccess{
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    video{
+      width:464px;
+      height:407px;
+    }
+  }
+</style>

+ 8 - 8
ruoyi-ui/src/components/FormItemComponent/index.vue

@@ -28,7 +28,7 @@
 </template>
 <script>
 import Vue from "vue";
-// import layoutAlgorithm from "../__utils__/layoutAlgorithm";
+import layoutAlgorithm from "@/api/layoutAlgorithm";
 export default {
   name: "FormItemComponent",
   props: {
@@ -56,13 +56,13 @@ export default {
   computed: {
     // 通过layoutAlgorithm算法得到对应的位置坐标
     dataColRol() {
-      // const list = layoutAlgorithm(this.defaultColumn, this.currentFormList);
-      // return Object.keys(list).reduce((temp, current) => {
-      //   // 计算显示行数
-      //   list[current].component = Vue.extend(list[current].component);
-      //   temp.push(list[current]);
-      //   return temp;
-      // }, []);
+      const list = layoutAlgorithm(this.defaultColumn, this.currentFormList);
+      return Object.keys(list).reduce((temp, current) => {
+        // 计算显示行数
+        list[current].component = Vue.extend(list[current].component);
+        temp.push(list[current]);
+        return temp;
+      }, []);
     },
     // 计算属性的 div 的坐标起始点
     setDiv() {

+ 1027 - 0
ruoyi-ui/src/components/MutipleSelectPop/index.vue

@@ -0,0 +1,1027 @@
+<template>
+  <div class="MutipleSelectPop">
+    <div class="dialog_left">
+      <div class="left_top">
+        <Input
+          @on-change="inputchange"
+          @on-keydown="inputkeydown"
+          search
+          @on-search="inputsearch"
+          :placeholder="tree.placeholder"
+          v-model="tree.search"
+        ></Input>
+      </div>
+      <div class="left_center">
+        <div class="complex-spin-fix" v-if="treeLoading">
+          <Spin fix>
+            <Icon type="ios-loading" size="30" class="demo-spin-icon-load"></Icon>
+          </Spin>
+        </div>
+        <Tree
+          :data="treeLists"
+          show-checkbox
+          ref="Tree"
+          :query="tree.search"
+          :queryStyle="queryStyle"
+          @on-select-change="getSelectedNodes"
+          @on-check-change="getCheckedNodes"
+        ></Tree>
+      </div>
+    </div>
+    <div class="dialog_center">
+      <div class="complex-spin-fix" v-if="tableLoading">
+        <Spin fix>
+          <Icon type="ios-loading" size="30" class="demo-spin-icon-load"></Icon>
+        </Spin>
+      </div>
+      <div class="dialog_center_top">
+        <div class="dialog_center_top_fix">
+          <Input
+            @on-change="inputchange"
+            @on-keydown="inputkeydown"
+            search
+            @on-search="inputsearch"
+            :placeholder="table.placeholder"
+            v-model="table.search"
+          ></Input>
+        </div>
+      </div>
+      <div>
+        <Tabs size="small" @on-click="tabClick" :animated="false">
+          <TabPane v-for="(item,key) in TabPaneData" :key="key" :label="item.tab">
+            <div class="dialog_center_page">
+              <div class="dialog_p10">
+                <Page
+                  :total="item.total"
+                  :page-size="item.pageSize"
+                  :current="item.pageNum"
+                  @on-change="pageChange"
+                  :page-size-opts="item.pageOptions"
+                  show-total
+                  size="small"
+                />
+              </div>
+              <div>
+                <Table
+                  border
+                  :columns="item.columns"
+                  ref="Table"
+                  :highlight-row="true"
+                  :clickTimerTask="300"
+                  :height="item.height"
+                  @on-select="Onselect"
+                  @on-select-cancel="onSelectCancel"
+                  @on-select-all="onSelectAll"
+                  @on-select-all-cancel="onSelectAllCancel"
+                  @on-selection-change="onSelectChange"
+                  @on-row-dblclick="rowdbClick"
+                  @on-row-click="rowClick"
+                  :data="item.list"
+                ></Table>
+              </div>
+            </div>
+          </TabPane>
+        </Tabs>
+      </div>
+    </div>
+    <div class="dialog-operation" v-if="index === 0">
+      <div>
+        <Button v-if="isUse" class="operatebtn" type="primary" ghost @click="operationTwo">选择部门</Button>
+        <Button class="operatebtn" type="primary" ghost @click="operation">选择人员</Button>
+      </div>
+    </div>
+    <div class="dialog_right">
+      <div class="left_top right_top">
+        <div>已选中({{resultMessage.total || 0 }})</div>
+        <div>
+          <i class="iconfont iconios-trash-outline" @click="delecFun"></i>
+        </div>
+      </div>
+      <div class="right_center">
+        <ul v-if="resultMessage.list.length>0">
+          <li v-for="(item,index) in resultMessage.list" :key="index">
+            <p>{{item.string}}</p>
+            <i class="iconfont iconbj_delete2" @click="deleteLi(index,item)"></i>
+          </li>
+        </ul>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+export default {
+  name: "Mutiple",
+  props: {
+    // treedata: {
+    //   type: Array,
+    //   default() {
+    //     return [];
+    //   }
+    // },
+    // componentData: {
+    //   type: Array,
+    //   default() {
+    //     return [];
+    //   }
+    // },
+    resultData: {
+      type: Object,
+      default() {
+        return {};
+      }
+    },
+    loading: {
+      type: Boolean,
+      default: false
+    },
+    // treeLoading: {
+    //   type: Boolean,
+    //   default: false
+    // },
+    // tableLoading: {
+    //   type: Boolean,
+    //   default: false
+    // },
+    open: {
+      type: Boolean,
+      default: false
+    },
+    icon_delect: {
+      type: String,
+      default: "iconfont  icon-bj_delete"
+    },
+    checkedList: {
+      type: Array,
+      default() {
+        return [];
+      }
+    },
+    // tableSearch: {
+    //   type: String,
+    //   default: ""
+    // },
+    isUse: {
+      type: Boolean,
+      default: true
+    },
+    isMutiple: {
+      //是否多选
+      type: Boolean,
+      default: true
+    },
+    // isResultShow: {
+    //   //result.list是否反显
+    //   type: Boolean,
+    //   default: true
+    // },
+    isCallInterface: {
+      //用来控制调用接口拿到数据 //也可以理解为弹框关闭状态
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      tableLoading: false,
+      treeLoading: false,
+      tree: {
+        placeholder: "可搜索店仓/部门",
+        search: ""
+      },
+      table: {
+        //表格显示部分搜索
+        placeholder: "直接输入人员姓名搜索",
+        search: ""
+      },
+      columns: [],
+      treeNewData: [],
+      showTree: this.open,
+      component: [
+        {
+          tab: "筛选结果",
+          columns: [
+            { key: "NAME", title: "用户名" },
+            { key: "ENAME", title: "用户姓名" }
+          ],
+          list: [],
+          total: 0,
+          pageSize: 10,
+          pageNum: 1, //当前页码
+          pageOptions: [10, 20, 50, 100],
+          height: 340
+        }
+      ],
+      resultRightData: {
+        total: 0,
+        list: []
+      },
+      templateName: "",
+      index: 0,
+      queryStyle: {
+        color: "#fd6442"
+      },
+      selectRow: [], //表格选中的数据
+      selectDatas: {}, //单行选中
+      obj: {} //
+    };
+  },
+  computed: {
+    treeLists() {
+      // this.treeNewData = this.treedata;
+      return this.treeNewData;
+    },
+    TabPaneData() {
+      // let data = Object.assign(this.component, this.componentData);
+      // return data;
+      if (this.isMutiple) {
+        this.component[0].columns.unshift({
+          type: "selection",
+          align: "center",
+          fixed: "left",
+          width: 30
+        });
+      }
+      return this.component;
+    },
+    resultMessage() {
+      // let data = Object.assign(this.resultRightData, this.resultData);
+      return this.resultRightData;
+    }
+  },
+  watch: {
+    isCallInterface: {
+      handler(newValue, oldValue) {
+        if (newValue) {
+          //执行请求
+          this.component[0].pageNum = 1
+          this.getTreeData();
+          if (this.resultData.list) {
+            this.resultRightData = this.deepCopy(this.resultData);
+          }
+        } else {
+          if (this.selectRow.length > 0) {
+            this.selectRow = [];
+          }
+          if (Object.keys(this.selectDatas).length > 0) {
+            this.selectDatas = {};
+          }
+          if (this.table.search) {
+            this.table.search = "";
+          }
+        }
+      }
+    }
+  },
+  methods: {
+    deepCopy(obj) {
+      //兑现深拷贝
+      var result = Array.isArray(obj) ? [] : {};
+      for (var key in obj) {
+        if (obj.hasOwnProperty(key)) {
+          if (typeof obj[key] === "object" && obj[key] !== null) {
+            result[key] = this.deepCopy(obj[key]); //递归复制
+          } else {
+            result[key] = obj[key];
+          }
+        }
+      }
+      return result;
+    },
+    getSelectedNodes(val) {
+      // if (this.isMutiple) {
+      if (val.length > 0) {
+        this.obj = {};
+        this.saveObj = val[0];
+        let self = this;
+        let valID = "";
+        if (val[0].ID.indexOf(".") !== -1) {
+          valID = val[0].ID.split(".")[1];
+          valID = parseInt(valID);
+        } else {
+          valID = parseInt(val[0].ID);
+        }
+
+        if (val[0].CP_C_ORGUP_ID === null) {
+          //根节点
+          this.findUser({});
+        } else {
+          //当item的TYPE为店仓时
+          if (val[0].TYPE === "CP_C_STORE_ID") {
+            this.obj.CP_C_STORE_ID = "in(" + valID + ")";
+            self.findUser(self.obj);
+          }
+          //当item的TYPE为供应商时
+          //  当item的TYPE为组织时
+          if (val[0].TYPE === "CP_C_HRORG_ID") {
+            this.$network
+              .post("/p/c/identity/org/treequery", { CP_C_ORGUP_ID: valID })
+              .then(res => {
+                if (res.data.resultCode === 0) {
+                  let HRORG = "in ("; //储存键名为CP_C_HRORG_ID对象的ID
+                  let STORE = "in ("; //储存键名为CP_C_STORE_ID对象的ID
+
+                  if (
+                    res.data.data.CP_C_HRORG &&
+                    res.data.data.CP_C_HRORG.length > 0
+                  ) {
+                    res.data.data.CP_C_HRORG.forEach(item => {
+                      HRORG += item.ID + ","; // in 1,2,3,5,6,87,8,6
+                    });
+                    if (res.data.data.CP_C_HRORG.length > 0) {
+                      self.obj.CP_C_HRORG_ID =
+                        HRORG.substring(0, HRORG.length - 1) + ")";
+                    }
+                  }
+                  if (
+                    res.data.data.CP_C_STORE &&
+                    res.data.data.CP_C_STORE.length > 0
+                  ) {
+                    res.data.data.CP_C_STORE.forEach(item => {
+                      STORE += item.ID + ",";
+                    });
+                    if (res.data.data.CP_C_STORE.length > 0) {
+                      self.obj.CP_C_STORE_ID =
+                        STORE.substring(0, STORE.length - 1) + ")";
+                    }
+                  }
+                  self.findUser(self.obj);
+                } else {
+                  this.$Modal.fcError({
+                    title: "错误提示",
+                    content: res.data.resultMsg
+                  });
+                }
+              });
+          }
+          // setTimeout(function() {
+          //   self.findUser(self.obj);
+          // });
+        }
+      }
+      // }
+      this.$emit("on-select-tree", val, this);
+    },
+    getCheckedNodes(obj) {
+      this.$emit("on-change-tree", obj, this);
+    },
+    tabClick(index) {
+      this.index = index;
+      this.$emit("on-click-tab", index, this);
+    },
+    pageChange(index) {
+      this.$emit("on-change-page", index, this);
+      this.component[0].pageNum = index;
+      let param = Object.assign(this.obj, { page: index, pageSize: 10 });
+      if (this.table.search !== "") {
+        param.ENAME = this.table.search;
+      }
+      this.findUser(param);
+    },
+    pageChangeSize(index) {
+      this.$emit("on-change-pageSize", index, this);
+      this.component[0].pageSize = index;
+      let param = Object.assign(this.obj, { page: 1, pageSize: index });
+      if (this.table.search !== "") {
+        param.ENAME = this.table.search;
+      }
+      this.findUser(param);
+    },
+    rowdbClick(row, index) {
+      let selectObj = Object.assign({}, row);
+      if (!this.isMutiple) {
+        selectObj.string = selectObj.ENAME;
+        if (this.resultRightData.list) {
+          this.resultRightData.list = [];
+          this.resultRightData.list.push(selectObj);
+        } else {
+          this.$set(this.resultRightData, "list", [selectObj]);
+        }
+      } else {
+        let selectObj = Object.assign({ approve_type: 4 }, row);
+        selectObj.string = selectObj.ENAME;
+        if (this.resultRightData.list && this.resultRightData.list.length > 0) {
+          let flagIndex = this.resultRightData.list.findIndex(inner => {
+            return (
+              selectObj.ID === inner.ID || selectObj.ID === Number(inner.approve_value)
+            );
+          });
+          if (flagIndex === -1) {
+            //没有找到相同的就加入
+            this.resultRightData.list.push(selectObj);
+          } else {
+            this.$Message.warning(
+              selectObj.ENAME + "已经选择过了,请不要重复选择!"
+            );
+          }
+        } else {
+          this.$set(this.resultRightData, "list", [selectObj]);
+        }
+      }
+      this.resultRightData.total
+        ? (this.resultRightData.total = this.resultRightData.list.length)
+        : this.$set(
+            this.resultRightData,
+            "total",
+            this.resultRightData.list.length
+          );
+      this.$emit("getResult", this.resultRightData);
+      this.$refs.Table[0].clearCurrentRow();
+      this.$emit("on-row-dblclick", row, index, this);
+    },
+    rowClick(row, index) {
+      if (!this.isMutiple) {
+        this.selectDatas = Object.assign(this.selectDatas, row);
+      }
+      this.$emit("on-row-click", row, index, this);
+    },
+    Onselect(selection, row) {
+      if (this.isMutiple) {
+        this.component[0].list.map(item => {
+          if (row.ID === item.ID) {
+            item._checked = true;
+          }
+        });
+        this.selectRow = [];
+        this.selectRow = selection;
+      }
+
+      this.$emit("on-select", selection, row);
+    },
+    onSelectCancel(selection, row) {
+      this.component[0].list.map(item => {
+        if (row.ID === item.ID) {
+          item._checked = false;
+        }
+      });
+      this.selectRow = [];
+      this.selectRow = selection;
+      this.$emit("on-select-cancel", selection, row);
+    },
+    onSelectAll(selection) {
+      this.selectRow = [];
+      this.component[0].list.map(item => {
+        item._checked = true;
+      });
+      this.selectRow = selection;
+      this.$emit("on-select-all", selection);
+    },
+    onSelectAllCancel(selection) {
+      this.component[0].list.map(item => {
+        item._checked = false;
+      });
+      this.selectRow = [];
+      this.$emit("on-select-all-cancel", selection);
+    },
+    onSelectChange(selection) {
+      this.$emit("on-select-change", selection);
+    },
+    inputchange(event) {
+      // if(!this.isUse&&!this.isMutiple){
+      this.table.search = event.target.value;
+      // }
+      this.$emit("on-change", event, this);
+    },
+    inputkeydown(event) {
+      this.$emit("on-keydown", event, this);
+    },
+    inputsearch(event) {
+      let param = Object.assign(this.obj, {
+        page: 1,
+        pageSize: 10,
+        ENAME: event
+      });
+      this.findUser(param);
+      this.$emit("on-search", event, this);
+    },
+    operationTwo() {
+      let selectNode = this.$refs.Tree.getCheckedNodes();
+      selectNode = selectNode.filter(item => item.title !=='全部')
+      if (this.isMutiple) {
+        if (selectNode.length > 0) {
+          this.resultRightData.total
+            ? this.$set(this.resultRightData, "total", this.resultData.total + selectNode.length)
+            : this.$set(this.resultRightData, "total", selectNode.length);
+          selectNode.map(item => {
+            let selectObj = Object.assign({ approve_type: 2 }, item);
+            selectObj.string = item.ENAME;
+            if (
+              this.resultRightData.list &&
+              this.resultRightData.list.length > 0
+            ) {
+              let flagIndex = this.resultRightData.list.findIndex(inner => {
+                return item.ID === inner.ID || item.ID === Number(inner.approve_value);
+              });
+              if (flagIndex === -1) {
+                //没有找到相同的就加入
+                this.resultRightData.list.push(selectObj);
+              } else {
+                this.$Message.warning(
+                  item.ENAME + "已经选择过了,请不要重复选择!"
+                );
+              }
+            } else {
+              this.$set(this.resultRightData, "list", [selectObj]);
+            }
+          });
+        } else {
+          this.$Message.warning("请选择部门");
+        }
+        this.getTreeData();
+      }
+      if (this.selectRow.length > 0) {
+        //选中状态的清除
+        this.selectRow = [];
+      }
+      if (Object.keys(this.selectDatas).length > 0) {
+        this.selectDatas = {};
+      }
+      this.$emit("getResult", this.resultRightData);
+      this.$emit("on-transfer-two", selectNode, this);
+    },
+    operation() {
+      if (!this.isMutiple) {
+        //单选逻辑
+        if (Object.keys(this.selectDatas).length === 0) {
+          this.$Message.warning("请选择人员");
+          return;
+        }
+        this.resultRightData.total
+          ? (this.resultRightData.total = 1)
+          : this.$set(this.resultRightData, "total", 1);
+        let selectObj = Object.assign({}, this.selectDatas);
+        selectObj.string = selectObj.ENAME;
+        if (this.resultRightData.list) {
+          this.resultRightData.list = [];
+          this.resultRightData.list.push(selectObj);
+        } else {
+          this.$set(this.resultRightData, "list", [selectObj]);
+        }
+      } else {
+        //多选逻辑
+        if (this.selectRow.length > 0) {
+          this.selectRow.map(item => {
+            let selectObj = Object.assign({ approve_type: 4 }, item);
+            selectObj.string = item.ENAME;
+            if (
+              this.resultRightData.list &&
+              this.resultRightData.list.length > 0
+            ) {
+              let flagIndex = this.resultRightData.list.findIndex(inner => {
+                return item.ID === inner.ID || item.ID === Number(inner.approve_value);
+              });
+              if (flagIndex === -1) {
+                //没有找到相同的就加入
+                this.resultRightData.list.push(selectObj);
+              } else {
+                this.$Message.warning(
+                  item.ENAME + "已经选择过了,请不要重复选择!"
+                );
+              }
+            } else {
+              this.$set(this.resultRightData, "list", [selectObj]);
+            }
+          });
+          this.resultRightData.total
+            ? (this.resultRightData.total = this.resultRightData.list.length)
+            : this.$set(
+                this.resultRightData,
+                "total",
+                this.resultRightData.list.length
+              );
+        } else {
+          this.$Message.warning("请选择人员");
+        }
+      }
+      //刷新表格数据
+      this.component[0].list.map(item => {
+        item._checked = false;
+      });
+      this.component[0].list = this.component[0].list.concat([]);
+      if (this.selectRow.length > 0) {
+        //选中状态的清除
+        this.selectRow = [];
+      }
+      if (Object.keys(this.selectDatas).length > 0) {
+        this.selectDatas = {};
+      }
+      this.$emit("getResult", this.resultRightData);
+      this.$emit("on-transfer", this);
+    },
+    deleteLi(index, tem) {
+      let selectNode = this.$refs.Tree.getCheckedNodes();
+      if (selectNode && selectNode.length > 0) {
+        selectNode.map(inItem => {
+          if (inItem.ID === tem.ID) {
+            this.$refs.Tree.handleCheck({
+              checked: false,
+              nodeKey: inItem.nodeKey
+            });
+          }
+        });
+      }
+      let selectrow = this.TabPaneData[0].list; //表格数据
+      selectrow.map((row, Index) => {
+        if (row.ID === tem.ID) {
+          row._checked = false;
+        }
+      });
+      this.resultRightData.list.splice(index, 1);
+      this.resultRightData.total = this.resultRightData.list.length;
+      this.$emit("getResult", this.resultRightData);
+      this.$emit("on-delectli", index, tem, this);
+    },
+    treeOpen(checked) {
+      this.showTree = !checked;
+      this.treeNewData.forEach(item => {
+        item.expand = !item.expand;
+      });
+    },
+    delecFun() {
+      let selectNode = this.$refs.Tree.getCheckedNodes();
+      if (selectNode && selectNode.length > 0) {
+        selectNode.map(inItem => {
+          this.$refs.Tree.handleCheck({
+            checked: false,
+            nodeKey: inItem.nodeKey
+          });
+        });
+      }
+      let selectrow = this.TabPaneData[0].list; //表格数据
+      if (selectrow && selectrow.length > 0) {
+        selectrow.map((row, Index) => {
+          row._checked = false;
+        });
+      }
+      this.$emit("on-deleBtn", this);
+      this.resultRightData.total = 0;
+      this.resultRightData.list = [];
+      this.component[0].list.map(item => {
+        item._checked = false;
+      });
+      this.component[0].list = this.component[0].list.concat([]);
+      this.$emit("getResult", this.resultRightData);
+    },
+    //查找用户信息
+    findUser(param) {
+      this.tableLoading = true;
+      this.$network.post("/p/c/identity/user/list", param).then(res => {
+        this.tableLoading = false;
+        let data = res.data;
+        if (data.code === 0) {
+          if (data.data) {
+            this.transferTbody(data.data);
+          }
+          if (data.datas) {
+            this.transferTbody(data.datas);
+          }
+        }
+      });
+    },
+    //表格体数据转化
+    transferTbody(data) {
+      this.component[0].total = data.totalRowCount;
+      this.component[0].pageOptions = data.selectrange;
+      this.component[0].list = [];
+      data.row.map(item => {
+        let tem = {};
+        let temval = {};
+        Object.keys(item).map(inner => {
+          tem[inner] = item[inner].val;
+        });
+        temval = Object.assign({}, tem);
+        this.component[0].list.push(tem);
+      });
+    },
+    //获取树数据
+     getTreeData() {
+      this.tree_loading = true;
+      this.$network.post("/p/c/identity/org/treeload", {}).then(res => {
+        this.tree_loading = false;
+        if (res.data.resultCode === 0) {
+          this.treeNewData = [];
+          let newArr = [];
+          let root = {};
+          if (res.data.data.records.length > 0) {
+            res.data.data.records.forEach(item => {
+              let tem = Object.assign(item);
+              newArr.push(tem);
+              if (
+                item["CP_C_ORGUP_ID"] === null ||
+                item["CP_C_ORGUP_ID"] === ""
+              ) {
+                root = Object.assign({}, item);
+              }
+            });
+            this.treeNewData = this.arrayTransTree(newArr, "CP_C_ORGUP_ID");
+          }
+          this.findUser({}); //显示所有的用户
+        }
+      });
+    },
+
+    //改造树数据的结构
+    arrayTransTree(list, key) {
+      let parent = [];
+      let children = [];
+      list.map(item => {
+        item.expand = false;
+        item.title = item.ENAME;
+        if (
+          !item[key]||
+          (item[key].indexOf('.')!==-1&&!item[key].split(".")[1])
+        ) {
+          //根节点
+          parent.push(item);
+        } else {
+          //有父节点的
+          children.push(item);
+        }
+      });
+      if (parent.length < 1) {
+        //没有根节点
+        let newParent = this.findTreeRootFirstChild(list, key); //拿到一级节点
+        let rootArr = newParent.map(item => {
+          return item[key];
+        });
+        let rootTem = Array.from(new Set([...rootArr]));
+        if (rootTem.length === 1) {
+          parent = [
+            {
+              CP_C_ORGUP_ID: null,
+              ECODE: "00000",
+              ENAME: "全部",
+              ID: rootTem[0],
+              MIXNAME: "[00000]全部",
+              ORGTYPE: "IN",
+              TYPE: "CP_C_HRORG_ID",
+              title:'全部'
+            }
+          ];
+          this.translator(parent, children, key);
+          return parent;
+        } else {
+          this.$Message.warning("数据有问题,请检查...");
+          return;
+        }
+      } else {
+        this.translator(parent, children, key);
+
+        return parent;
+      }
+    },
+    translator(parents, children, key) {
+      let temp = [];
+      children.map(item => {
+        //对子节点数据进行深复制,这里只支持部分类型的数据深复制
+        let temItem = Object.assign({}, item);
+        temp.push(temItem);
+      });
+      //遍历父节点数据
+      parents.map(parent => {
+        //遍历子节点数据
+        children.map((current, index) => {
+          //此时找到父节点对应的一个子节点
+          if (current[key] === parent.ID) {
+            //让当前子节点从temp中移除,temp作为新的子节点数据,这里是为了让递归时,子节点的遍历次数更少,如果父子关系的层级越多,越有利
+            temp.splice(index, 1);
+            //让当前子节点作为唯一的父节点,去递归查找其对应的子节点
+            this.translator([current], temp, key);
+            //把找到子节点放入父节点的children属性中
+            parent.children
+              ? parent.children.push(current)
+              : (parent.children = [current]);
+          }
+        });
+      });
+    },
+    treeTransArray(tree, key) {
+      return tree
+        .reduce(function iteration(con, item) {
+          con.push(item);
+          if (item[key] && item[key].length > 0)
+            item[key].reduce(iteration, con);
+          return con;
+        }, [])
+        .map(function(item) {
+          item[key] = [];
+          return item;
+        });
+    },
+    findTreeRootFirstChild(Arr, key) {
+      let idArr = [];
+      let result = [];
+      idArr = Arr.map(item => {
+        return item["ID"];
+      });
+      Arr.map(item => {
+        if (!idArr.includes(item[key])) {
+          //一级节点的特点是存在父节点 但是已父节点为ID的节点是不存在的
+          result.push(item);
+        }
+      });
+      return result;
+    },
+  },
+  mounted() {
+    // if(this.isCallInterface){
+    //   this.getTreeData();
+    //   if (this.resultData.list) {
+    //     this.resultRightData = this.deepCopy(this.resultData);
+    //   }
+    // }else{
+    //    if (this.selectRow.length > 0) {
+    //       this.selectRow = [];
+    //     }
+    //     if (Object.keys(this.selectDatas).length > 0) {
+    //       this.selectDatas = {};
+    //     }
+    //     if (this.table.search) {
+    //       this.table.search = "";
+    //     }
+    // }
+    
+  },
+  destroyed() {
+    if (this.selectRow.length > 0) {
+      this.selectRow = [];
+    }
+    if (Object.keys(this.selectDatas).length > 0) {
+      this.selectDatas = {};
+    }
+    if (this.table.search) {
+      this.table.search = "";
+    }
+  }
+};
+</script>
+<style lang="scss">
+.MutipleSelectPop {
+  width: 800px;
+  display: flex;
+  height: 484px;
+  position: relative;
+  .demo-spin-icon-load {
+    animation: ani-demo-spin 1s linear infinite;
+  }
+  .complex-spin-fix {
+    z-index: 20;
+  }
+  @keyframes ani-demo-spin {
+    from {
+      transform: rotate(0deg);
+    }
+    50% {
+      transform: rotate(180deg);
+    }
+    to {
+      transform: rotate(360deg);
+    }
+  }
+  overflow: hidden;
+  .dialog_left {
+    width: 170px;
+    display: -ms-flexbox;
+    display: flex;
+    -ms-flex-direction: column;
+    flex-direction: column;
+    padding: 10px;
+    border: 1px solid #dcdee2;
+    border-right: none;
+    .left_top {
+      height: 32px;
+      line-height: 32px;
+      box-sizing: border-box;
+      border-bottom: 1px solid #e8eaec;
+      font-size: 12px;
+      color: #575757;
+      display: flex;
+      input {
+        line-height: 32px;
+        height: 32px;
+      }
+
+      div:first-child {
+        flex: 1;
+      }
+      i {
+        margin-right: 10px;
+      }
+    }
+    .left_center {
+      flex: 1;
+      padding-top: 10px;
+      position: relative;
+      height: 390px;
+      padding-bottom: 10px;
+      width: 156px;
+      overflow-y: auto;
+    }
+  }
+  .dialog_center {
+    width: 400px;
+    position: relative;
+    height: 484px;
+    border: 1px solid #dcdee2;
+    border-right: none;
+    //box-shadow: 2px -2px 9px @shadow-color;
+    padding: 10px;
+    display: -ms-flexbox;
+    display: flex;
+    -ms-flex-direction: column;
+    flex-direction: column;
+    .dialog_p10 {
+      padding: 10px 0;
+    }
+    .dialog_center_top {
+      display: flex;
+      line-height: 32px;
+      vertical-align: middle;
+      box-sizing: border-box;
+      .dialog_center_top_fix {
+        width: 270px;
+        box-sizing: border-box;
+        padding-right: 20px;
+        input {
+          line-height: 32px;
+          height: 32px;
+        }
+      }
+    }
+  }
+  .dialog-operation {
+    width: 92px;
+    padding: 0px;
+    border-left: 1px solid #dcdee2;
+    background-color: #fff;
+    position: relative;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    div {
+      text-align: center;
+      .operatebtn {
+        margin-bottom: 10px;
+        padding: 8px 12px;
+        &:last-child {
+          margin-bottom: 0;
+        }
+      }
+    }
+  }
+  .dialog_right {
+    width: 220px;
+    padding: 10px;
+    border: 1px solid #dcdee2;
+    box-sizing: border-box;
+    display: -ms-flexbox;
+    display: flex;
+    -ms-flex-direction: column;
+    flex-direction: column;
+    .left_top {
+      height: 30px;
+      line-height: 30px;
+      box-sizing: border-box;
+      border-bottom: 1px solid #e8eaec;
+      font-size: 12px;
+      color: #575757;
+      display: flex;
+      div:first-child {
+        flex: 1;
+      }
+      i {
+        margin-right: 10px;
+      }
+    }
+    ul {
+      height: 390px;
+      overflow: auto;
+      li {
+        margin-bottom: 4px;
+        display: -ms-flexbox;
+        display: flex;
+        -ms-flex-align: center;
+        align-items: center;
+        background-color: #f8f8f8;
+        border-radius: 2px;
+        font-size: 12px;
+        p {
+          flex: 1;
+          line-height: 18px;
+          margin-left: 4px;
+          box-sizing: border-box;
+          border-radius: 4px;
+          padding: 4px 6px;
+          color: #0f8ee9;
+          word-wrap: break-word;
+          word-break: break-all;
+        }
+      }
+    }
+  }
+  .right_center {
+    flex: 1;
+    padding-top: 10px;
+  }
+}
+</style>
+

+ 514 - 0
ruoyi-ui/src/components/ParameterConfiguration/index.vue

@@ -0,0 +1,514 @@
+//参数配置界面
+<template>
+  <div class="ParameterConfiguration">
+    <FormItemComponent
+      class="form"
+      :formItemLists="formLists"
+      :buttonType="false"
+      :defaultColumn="1"
+      @formChange="formChange"
+    ></FormItemComponent>
+  </div>
+</template>
+<script>
+import FormItemComponent from '@/components/FormItemComponent';
+import ItemComponent from '@/components/ItemComponent';
+export default {
+  components:{FormItemComponent},
+  props:{
+    data:{
+      type:Object
+    }
+  },
+  watch:{
+    data:{
+      handler () {
+        this.formLists = [
+            {
+              row:1,
+              col:1,
+              component:ItemComponent,
+              item:{
+                type:'select',
+                title:'模版类型',
+                filed:'moduleType',
+                value:this.data.moduleType,
+                props:{
+                  disabled:this.disabled,
+                  clearable: false,
+                },
+                options:[
+                  {
+                    value: 0,
+                    label: '固定模版'
+                  },
+                  {
+                    value: 1,
+                    label: '动态模版'
+                  }
+                ]
+              }
+            },
+            {
+              row:1,
+              col:1,
+              component:ItemComponent,
+              item:{
+                type:'DropDownSelectFilter',
+                title:'单据类型',
+                filed:'businessType',
+                required:true,
+                hidden: this.data.moduleType === 1,
+                props:{
+                  columnsKey:['NAME'],
+                  AutoData:[],
+                  hidecolumns:['id'],
+                  data:{},
+                  totalRowCount:0,
+                  defaultSelected:this.data.businessType,
+                  disabled:this.disabled
+                },
+                event:{
+                  inputValueChange: (value) => {
+                      // 外键的模糊搜索
+                      this.fkFuzzyquerybyak(value)
+                  },
+                  'on-show': ($this) => {
+                    // 当外键下拉站开始去请求数据
+                    this.freshDropDownSelectFilterData($this)
+                  },
+                  pageChange: (currentPage, $this) => {
+                    // 外键的分页查询
+                    this.freshDropDownSelectFilterData($this,currentPage)
+                  },
+                  blur:(event,instance) => {
+                    if(Object.prototype.toString.call(this.data.businessType) !== '[object Array]' || this.data.businessType.length === 0){
+                      this.data.businessType = []
+                      instance.inputValue = ''
+                    }
+
+                  }
+                }
+              }
+            },
+            {
+              row:1,
+              col:1,
+              component:ItemComponent,
+              item:{
+                type:'input',
+                title:'模版名称',
+                filed:'name',
+                required:true,
+                value:this.data.name,
+                props:{
+                  // disabled:this.data.status === 1
+                }
+              }
+            },
+            {
+              row:1,
+              col:1,
+              component:ItemComponent,
+              item:{
+                type:'DropDownSelectFilter',
+                title:'查询索引',
+                filed:'businessNumber',
+                hidden: this.data.moduleType === 1,
+                props:{
+                  columnsKey:['NAME'],
+                  AutoData:[],
+                  hidecolumns:['id'],
+                  data:{},
+                  totalRowCount:0,
+                  defaultSelected:this.data.businessNumber,
+                  // disabled:this.data.status === 1
+                },
+                event:{
+                  inputValueChange: (value,instance) => {
+                      if(!this.data.businessType || this.data.businessType.lengt == 0 || !this.data.businessType[0].ID){
+                        this.$Modal.fcWarning({
+                          title:'警告',
+                          content:'请先选择单据类型!'
+                        })
+                        this.data.businessNumber = []
+                        instance.inputValue = ''
+                        return
+                      }
+                      // 外键的模糊搜索
+                      this.fkFuzzyquerybyakcolumn(value)
+                  },
+                  'on-show': ($this) => {
+                    // 当外键下拉站开始去请求数据
+                    if(!this.data.businessType || this.data.businessType.lengt == 0 || !this.data.businessType[0].ID){
+                      this.$Modal.fcWarning({
+                        title:'警告',
+                        content:'请先选择单据类型!'
+                      })
+                      this.data.businessNumber = []
+                      $this.inputValue = ''
+                      return
+                    }
+                    this.freshDropDownSelectFilterDataColumn($this)
+                  },
+                  pageChange: (currentPage, $this) => {
+                    // 外键的分页查询
+                    this.freshDropDownSelectFilterDataColumn($this,currentPage)
+                  },
+                  blur:(event,instance) => {
+                    if(Object.prototype.toString.call(this.data.businessNumber) !== '[object Array]' || this.data.businessNumber.length === 0){
+                      this.data.businessNumber = []
+                      instance.inputValue = ''
+                    }
+
+                  }
+                }
+              }
+            },
+            {
+              row:1,
+              col:1,
+              component:ItemComponent,
+              item:{
+                type:'input',
+                title:'模版描述',
+                filed:'description',
+                value:this.data.description,
+                props:{
+                  type:'textarea',
+                  // disabled:this.data.status === 1
+                }
+              }
+            },
+            {
+              row:1,
+              col:1,
+              component:ItemComponent,
+              item:{
+                type:'Switch',
+                title:'开启自动处理',
+                filed:'autoClose',
+                value:this.data.autoClose,
+              }
+            },
+            {
+              row:1,
+              col:1,
+              component:ItemComponent,
+              item:{
+                type:'input',
+                title:'业务数据检查',
+                filed:'businessCheckUrl',
+                value:this.data.businessCheckUrl
+              }
+            }
+          ]
+      },
+      deep:true
+    }
+  },
+  data () {
+    return {
+      formLists:[
+        {
+          row:1,
+          col:1,
+          component:ItemComponent,
+          item:{
+            type:'select',
+            title:'模版类型',
+            filed:'moduleType',
+            value: 0,
+            props:{
+              disabled:false,
+              clearable: false
+            },
+            options:[
+              {
+                value: 0,
+                label: '固定模版'
+              },
+              {
+                value: 1,
+                label: '动态模版'
+              }
+            ]
+          }
+        },
+        {
+          row:1,
+          col:1,
+          component:ItemComponent,
+          item:{
+            type:'DropDownSelectFilter',
+            title:'单据类型',
+            filed:'businessType',
+            required:true,
+            hidden: this.data.moduleType === 1,
+            props:{
+              columnsKey:['NAME'],
+              AutoData:[],
+              hidecolumns:['id'],
+              data:{},
+              totalRowCount:0
+            },
+            event:{
+              inputValueChange: (value) => {
+                  // 外键的模糊搜索
+                  this.fkFuzzyquerybyak(value)
+              },
+              'on-show': ($this) => {
+                // 当外键下拉站开始去请求数据
+                this.freshDropDownSelectFilterData($this)
+              },
+              pageChange: (currentPage, $this) => {
+                // 外键的分页查询
+                this.freshDropDownSelectFilterData($this,currentPage)
+              },
+              blur:(event,instance) => {
+                if(Object.prototype.toString.call(this.data.businessType) !== '[object Array]' || this.data.businessType.length === 0){
+                  this.data.businessType = []
+                  instance.inputValue = ''
+                }
+
+              }
+            }
+          }
+        },
+        {
+          row:1,
+          col:1,
+          component:ItemComponent,
+          item:{
+            type:'input',
+            title:'模版名称',
+            filed:'name',
+            required:true,
+            value:this.data.name
+          }
+        },
+        {
+          row:1,
+          col:1,
+          component:ItemComponent,
+          item:{
+            type:'DropDownSelectFilter',
+            title:'查询索引',
+            filed:'businessNumber',
+            hidden: this.data.moduleType === 1,
+            props:{
+              columnsKey:['NAME'],
+              AutoData:[],
+              hidecolumns:['id'],
+              data:{},
+              totalRowCount:0
+            },
+            event:{
+              inputValueChange: (value,instance) => {
+                  if(!this.data.businessType || this.data.businessType.lengt == 0 || !this.data.businessType[0].ID){
+                    this.$Modal.fcWarning({
+                      title:'警告',
+                      content:'请先选择单据类型!'
+                    })
+                    this.data.businessNumber = []
+                    instance.inputValue = ''
+                    return
+                  }
+                  // 外键的模糊搜索
+                  this.fkFuzzyquerybyakcolumn(value)
+              },
+              'on-show': ($this) => {
+                // 当外键下拉站开始去请求数据
+                if(!this.data.businessType || this.data.businessType.lengt == 0 || !this.data.businessType[0].ID){
+                  this.$Modal.fcWarning({
+                    title:'警告',
+                    content:'请先选择单据类型!'
+                  })
+                  this.data.businessNumber = []
+                  $this.inputValue = ''
+                  return
+                }
+                this.freshDropDownSelectFilterDataColumn($this)
+              },
+              pageChange: (currentPage, $this) => {
+                // 外键的分页查询
+                this.freshDropDownSelectFilterDataColumn($this,currentPage)
+              },
+              blur:(event,instance) => {
+
+                if(Object.prototype.toString.call(this.data.businessNumber) !== '[object Array]' || this.data.businessNumber.length === 0){
+                  this.data.businessNumber = []
+                  instance.inputValue = ''
+                }
+
+              }
+            }
+          }
+        },
+        {
+          row:1,
+          col:1,
+          component:ItemComponent,
+          item:{
+            type:'input',
+            title:'模版描述',
+            filed:'description',
+            value:this.data.description,
+            props:{
+              type:'textarea',
+            }
+          }
+        },
+        {
+          row:1,
+          col:1,
+          component:ItemComponent,
+          item:{
+            type:'Switch',
+            title:'开启自动处理',
+            filed:'autoClose',
+            value:true,
+          }
+        },
+        {
+          row:1,
+          col:1,
+          component:ItemComponent,
+          item:{
+            type:'input',
+            title:'业务数据检查',
+            filed:'businessCheckUrl',
+            value:this.data.businessCheckUrl
+          }
+        }
+      ],
+      formData:{},
+      row:[],
+      disabled: false
+    }
+  },
+  methods:{
+    formChange (data) {  //数据修改
+      if(data.businessType && data.businessType.length > 0){
+        this.row.map(item => {
+          if(item.ID.val === data.businessType[0].ID){
+            data.businessType[0].val = item.DESCRIPTION.val
+            data.businessType[0].Label = item.NAME.val
+          }
+          return item
+        })
+      }
+
+      if(data.businessNumber && data.businessNumber.length > 0){
+        this.row.map(item => {
+          if(item.ID.val === data.businessNumber[0].ID){
+            data.businessNumber[0].val = item.DESCRIPTION.val
+            data.businessNumber[0].Label = item.NAME.val
+          }
+          return item
+        })
+      }
+
+      this.formData = Object.assign(this.formData,data)
+      this.$emit('dataChange',this.formData)
+    },
+    fkFuzzyquerybyak (value) {  //单据类型模糊搜素
+      this.formLists[1].item.props.AutoData = []
+      this.$network.post('/p/c/meta/table/list',{DESCRIPTION:value}).then(res => {
+        if(res.data.code === 0){
+          this.row = res.data.data.row.concat([])
+          this.formLists[1].item.props.AutoData = res.data.data.row.reduce((arr,item) => {
+            arr.push({
+              value:item.NAME.val,
+              id:item.ID.val,
+              NAME:item.DESCRIPTION.val
+            })
+            return arr
+          },[]);
+        }
+
+      })
+    },
+    freshDropDownSelectFilterData (instance,currentPage) {  //外键列表查询
+        this.$network.post('/p/c/meta/table/list',{
+          pageSize:instance.pageSize,
+          page:currentPage?currentPage:1
+        }).then(res => {
+          if(res.data.code === 0){
+            this.row = res.data.data.row.concat([])
+            res.data.data.tabth.forEach(item => {
+              if(item.colname === 'DESCRIPTION'){
+                item.isak = true
+              }
+              return item
+            })
+            // res.data.datas.row.forEach(item => {
+            //   item.ID.val = item.NAME.val
+            //   return item
+            // })
+            this.formLists[1].item.props.data = res.data.data;
+            this.formLists[1].item.props.totalRowCount = res.data.data.totalRowCount;
+          }
+
+        })
+    },
+    fkFuzzyquerybyakcolumn (value) {  //单据类型模糊搜素
+      this.formLists[3].item.props.AutoData = []
+      this.$network.post('/p/c/meta/column/list',{ DESCRIPTION: value, AD_TABLE_ID: this.data.businessType[0].ID}).then(res => {
+        if(res.data.code === 0){
+          this.row = res.data.data.row.concat([])
+          this.formLists[3].item.props.AutoData = res.data.data.row.reduce((arr,item) => {
+            arr.push({
+              value:item.NAME.val,
+              id:item.ID.val,
+              NAME:item.DESCRIPTION.val
+            })
+            return arr
+          },[]);
+        }
+
+      })
+    },
+    freshDropDownSelectFilterDataColumn (instance,currentPage) {  //外键列表查询
+
+        this.$network.post('/p/c/meta/column/list',{
+          pageSize:instance.pageSize,
+          page:currentPage?currentPage:1,
+          AD_TABLE_ID: this.data.businessType[0].ID
+        }).then(res => {
+          if(res.data.code === 0){
+            this.row = res.data.data.row.concat([])
+            res.data.data.tabth.forEach(item => {
+              if(item.colname === 'DESCRIPTION'){
+                item.isak = true
+              }
+              return item
+            })
+            // res.data.datas.row.forEach(item => {
+            //   item.ID.val = item.NAME.val
+            //   return item
+            // })
+            this.formLists[3].item.props.data = res.data.data;
+            this.formLists[3].item.props.totalRowCount = res.data.data.totalRowCount;
+          }
+
+        })
+    }
+  },
+  created () {
+    this.$route.params.id !== '-1'?this.disabled = true:this.disabled = false
+  }
+}
+</script>
+<style lang=scss" scoped>
+.ParameterConfiguration{
+  padding-top:50px;
+  display: flex;
+  justify-content:center;
+
+  .form{
+    border: none;
+    width: 420px;
+  }
+}
+</style>

+ 748 - 0
ruoyi-ui/src/components/ProcessNodeConfig/index.vue

@@ -0,0 +1,748 @@
+<template>
+  <!-- 过程节点配置 -->
+  <div class="ProcessNodeConfig">
+    <div>
+      <div class="splitItem">节点配置</div>
+      <div class="nodeSetbox">
+        <Form>
+          <FormItem label="节点名称:" :label-width="100">
+            <Input v-model="configData.name" placeholder="请输入" :disabled="readOnly"/>
+          </FormItem>
+          <FormItem  :label-width="100" >
+            <label slot="label"><i class="requireStyle">*</i>选择操作人:</label>
+            <Select v-model="configData.approverStyle" :disabled="readOnly" @on-change="approverStyleChange">
+              <Option  :value="0" :key="0">直接选择</Option>
+              <Option  :value="1" :key="1">扩展程序</Option>
+            </Select>
+          </FormItem>
+          <FormItem  :label-width="100" v-if="configData.approverStyle === 0">
+            <label slot="label"><i class="requireStyle">*</i>操作人:</label>
+            <complexPop :title="'选择操作人'" :resultData="resultData" :disabled="readOnly" @getTotalResult="getResult"></complexPop>
+          </FormItem>
+          <FormItem  :label-width="100" v-if="configData.approverStyle === 1">
+            <label slot="label"><i class="requireStyle">*</i>扩展程序:</label>
+            <Input v-model="configData.actionConfig[0].handleValue" placeholder="请输入" :disabled="readOnly" />
+          </FormItem>
+          <FormItem>
+              <Row>
+                  <Col span="12" style="display:flex">
+                    <span>
+                      <i class="requireStyle">*</i>
+                      <Icon
+                        v-if="pageBtnData[0].color"
+                        :type="pageBtnData[0].icontype===1?'ios-checkmark-circle':'ios-close-circle'"
+                        :color="pageBtnData[0].color"
+                      />
+                      {{pageBtnData[0].label}}:
+                    </span>
+                    <Input v-model="pageBtnData[0].value"  :regx="/^[0-9]*$/" @on-blur="onBlur(...arguments,0)" style="flex:1" :disabled="readOnly" />
+                  </Col>
+                  <!-- <Col span="12" offset="2" style="display:flex" v-show="false">
+                    <span>
+                      <Icon
+                        v-if="pageBtnData[1].color"
+                        :type="pageBtnData[1].icontype===1?'ios-checkmark-circle':'ios-close-circle'"
+                        :color="pageBtnData[1].color"
+                      />
+                      {{pageBtnData[1].label}}:
+                    </span>
+                    <Input v-model="pageBtnData[1].value"  style="flex:1" />
+                  </Col> -->
+              </Row>
+          </FormItem>
+          <FormItem>
+              <Row>
+                  <Col span="12" style="display:flex">
+                    <span>
+                      <i class="requireStyle">*</i>
+                      <Icon
+                        v-if="pageBtnData[2].color"
+                        :type="pageBtnData[2].icontype===1?'ios-checkmark-circle':'ios-close-circle'"
+                        :color="pageBtnData[2].color"
+                      />
+                      {{pageBtnData[2].label}}:
+                    </span>
+                    <Input v-model="pageBtnData[2].value"  :regx="/^[0-9]*$/" @on-blur="onBlur(...arguments,2)" style="flex:1" :disabled="readOnly" />
+                  </Col>
+                  <!-- <Col span="12" offset="2" style="display:flex"  v-show="false">
+                    <span>
+                      <Icon
+                        v-if="pageBtnData[3].color"
+                        :type="pageBtnData[3].icontype===1?'ios-checkmark-circle':'ios-close-circle'"
+                        :color="pageBtnData[3].color"
+                      />
+                      {{pageBtnData[3].label}}:
+                    </span>
+                    <Input v-model="pageBtnData[3].value"  style="flex:1" />
+                  </Col> -->
+              </Row>
+          </FormItem>
+          <FormItem label="直接结束流程:"  :label-width="100" >
+            <i-switch class="switchPage" v-model="configData.manualConfig" :true-value="'1'" :false-value="'0'" :disabled="readOnly" />
+          </FormItem>
+          <FormItem label="驳回流程:" :label-width="100">
+            <Select v-model="configData.backId" :disabled="readOnly">
+                <Option v-for="item in rejectedNodes" :value="item.value" :key="item.value">{{ item.label }}</Option>
+            </Select>
+          </FormItem>
+        </Form>
+      </div>
+      <div class="splitItem">审批人可修改字段配置</div>
+      <div class="nodeSetbox">
+        <Form>
+          <FormItem label="可修改字段:" :label-width="90">
+            <DropDownSelectFilter
+              :disabled="readOnly"
+              :single="false"
+              :totalRowCount="modifyField.totalRowCount"
+              :pageSize="modifyField.pageSize"
+              @on-page-change="changePage"
+              :dataEmptyMessage="modifyField.dataEmptyMessage"
+              @on-input-value-change="inputChange"
+              @on-fkrp-selected="OnFkrpSelected"
+              @on-popper-show="onPopperShow"
+              @on-clear="onClear"
+              :data="modifyField.data"
+              :hidecolumns="modifyField.columns"
+              :AutoData="modifyField.AutoData"
+              :default-selected="modifyField.defaultSelected"
+              :columnsKey="modifyField.columnsKey"
+            ></DropDownSelectFilter>
+          </FormItem>
+        </Form>
+      </div>
+      <div class="splitItem">超时设置</div>
+      <div class="nodeSetbox">
+        <div class="boxItem">
+          <Form>
+            <FormItem label="超时提醒:" :label-width="100">
+              <i-switch v-model="status1" @on-change="change1" :disabled="readOnly" />
+            </FormItem>
+            <FormItem label="超时阀值:" :label-width="100" :required="status1" v-if="status1">
+              <Input v-model="setOvertime.threshold" :regx="/^[1-9]\d*$/" :disabled="readOnly">
+                <Select v-model="setOvertime.sources" slot="append" style="width:70px" :disabled="readOnly">
+                  <Option :value="0">小时</Option>
+                  <Option :value="1">天</Option>
+                </Select>
+              </Input>
+            </FormItem>
+            <FormItem label="邮箱接口:" :label-width="100" :required="status1" v-if="status1">
+              <Input v-model="setOvertime.handleValue" :disabled="readOnly" />
+              <!-- <Select v-model="setOvertime.handle_type" slot="prepend" style="width: 90px;dispaly:none">
+                  <Option :value="11">邮箱</Option>
+                  <Option :value="12">钉钉消息</Option>
+              </Select>-->
+              <!-- <span class="tipMessage">超过这个时间段系统将自动发送提醒消息</span> -->
+            </FormItem>
+          </Form>
+        </div>
+        <div class="boxItem">
+          <Form>
+            <FormItem label="自动处理:" :label-width="100">
+              <i-switch v-model="status2" @on-change="change2" :disabled="readOnly" />
+            </FormItem>
+            <FormItem label="自动处理阀值:" :label-width="100" :required="status2" v-if="status2">
+              <Input v-model="autoDetail.threshold" :regx="/^[1-9]\d*$/" :disabled="readOnly">
+                <Select v-model="autoDetail.sources" slot="append" style="width: 70px" :disabled="readOnly">
+                  <Option :value="0">小时</Option>
+                  <Option :value="1">天</Option>
+                </Select>
+              </Input>
+            </FormItem>
+            <FormItem label="自动处理方式:" :label-width="100" :required="status2" v-if="status2">
+              <Select v-model="autoDetail.handleType" :disabled="readOnly">
+                <Option :value="20">同意</Option>
+                <Option :value="21">驳回</Option>
+              </Select>
+            </FormItem>
+          </Form>
+        </div>
+      </div>
+    </div>
+    <p>
+      <Button type="fcdefault" @click="closeDrawer">取消</Button>
+      <Button type="primary" @click="saveConfig" v-if="!readOnly">确定</Button>
+    </p>
+  </div>
+</template>
+<script>
+import complexPop from "@/components/complexPop";
+export default {
+  name: "ProcessNodeConfig",
+  components: { complexPop },
+  props: {
+    configData: {
+      type: Object,
+      default() {
+        return {};
+      }
+    },
+    TABLE_ID: {
+    }, //主表数据
+    status:null,
+    rejectedNodes:{
+      type: Array,
+      default: () => {
+        return []
+      }
+    },
+    readOnly:{
+      type:Boolean,
+      default:false
+    }
+  },
+  data() {
+    return {
+      //修改字段配置
+      modifyField: {
+        modifiable_field: "选中的字段",
+        modifiable_field_name: "", //选中的字段名称1
+        totalRowCount: 0, //数据总条数
+        pageSize: 10, //每页数据条数
+        dataEmptyMessage: "数据为空", //没数据时的提示
+        data: {}, //表格数据
+        columnsKey: ["value"], //input显示的字段
+        columns: ["id"], //模糊搜索隐藏的列
+        AutoData: [],
+        defaultSelected: []
+      },
+      pageBtnData: [
+        {
+          label: "最少同意人数",
+          icontype: 1,
+          color: "#09A155",
+          value: ""
+        },
+        {
+          label: "同意状态别名",
+          icontype: 1,
+          color: "#09A155",
+          value: ""
+        },
+        {
+          label: "最少拒绝人数",
+          icontype: 2,
+          color: "#ED4014",
+          value: ""
+        },
+        {
+          label: "拒绝状态别名",
+          icontype: 2,
+          color: "#ED4014",
+          value: ""
+        }
+      ],
+      status1: false, //超时提醒
+      status2: false, //自动处理
+      openControl: false, //控制弹框是否显示
+      loading: false, // z最大loading
+      resultData: {}, // 选中结果
+      open: false, // 是否打开
+      obj: {}, //传给table的对象
+      saveObj: {}, //存储的每次节点的对象
+      selectRow: [], //弹框多选单击一行的数据
+      approves: "", //审批相关数据
+      setOvertime: {
+        threshold: "",
+        sources: 0,
+        status: 1,
+        handleValue: "",
+        handleType: 11,
+        extraMsg: ""
+      },
+      autoDetail: {
+        threshold: "",
+        sources: 0,
+        status: 1,
+        handleType: 20,
+        extraMsg: "",
+        handleValue: ""
+      },
+      approvelList: [], //存放审批相关的数据
+      closeType: false, //控制审批确定取消显示状态
+      isCallInterface: false,
+      
+      defaultObj:{}  //默认数据
+    };
+  },
+  computed: {
+    actServiceS() {
+      return [this.setOvertime, this.autoDetail];
+    }
+  },
+  watch: {
+    pageBtnData: {
+      handler(newVal) {
+
+        let temArr = [
+          {
+            actType: 0,
+            actName: newVal[1].value,
+            actLimit: newVal[0].value
+          },
+          {
+            actType: 1,
+            actName: newVal[3].value,
+            actLimit: newVal[2].value
+          }
+        ];
+        if (this.configData.ruleList.length < 1) {
+          this.configData.ruleList = temArr;
+        } else {
+          this.configData.ruleList.map((item) => {
+            temArr.map(inner => {
+              if (item.actType === inner.actType) {
+                item = Object.assign(item, inner);
+              }
+            });
+          });
+        }
+      },
+      deep: true
+    },
+    actServiceS: {
+      handler(newVal) {
+        this.configData.actServiceS = newVal;
+      },
+      deep: true
+    },
+    approvelList: {
+      handler(newVal) {
+        this.configData.approvelList = newVal;
+      },
+      deep: true
+    }
+  },
+  methods: {
+    onBlur(event, ins, key) {
+      let res = /^[0-9]*$/;
+      if (res.test(key)) {
+        if (this.pageBtnData[key].value === "" && key == 0) {
+          this.$Message.warning("最少同意人数不能为空");
+        }
+        if (this.pageBtnData[key].value === "" && key == 1) {
+          this.$Message.warning("同意状态别名不能为空");
+        }
+        if (this.pageBtnData[key].value === "" && key == 2) {
+          this.$Message.warning("最少拒绝人数不能为空");
+        }
+        if (this.pageBtnData[key].value === "" && key == 3) {
+          this.$Message.warning("拒绝状态别名不能为空");
+        }
+      }
+    },
+    //可修改字段下拉多选事件
+    OnFkrpSelected(selected) {
+      this.modifyField.modifiableField = "";
+      this.modifyField.modifiableFieldName = "";
+      let str = "";
+      let name = "";
+      selected.map(item => {
+        str += item.ID + ",";
+        name += item.Label + ",";
+      });
+      if (str.length > 0) {
+        str = str.substring(0, str.length - 1);
+      }
+      if (selected.length > 0) {
+        name = name.substring(0, name.length - 1);
+      }
+      this.modifyField.modifiableField = str.trim();
+      this.configData.modifiableField = str.trim();
+      this.modifyField.modifiableFieldName = name.trim();
+      this.configData.modifiableFieldName = name.trim();
+    },
+    onPopperShow() {
+      //下拉多选
+      this.findField({ AD_TABLE_ID: this.TABLE_ID[0].ID });
+    },
+    changePage(val) {
+      this.findField({
+        pageSize: this.modifyField.pageSize,
+        page: val,
+        AD_TABLE_ID: this.TABLE_ID[0].ID
+      });
+    },
+    //模糊查找input事件
+    inputChange(val) {
+      this.findField({ DESCRIPTION: val, AD_TABLE_ID: this.TABLE_ID[0].ID });
+    },
+    onClear() {
+      this.modifyField.modifiableField = "";
+      this.configData.modifiableField = "";
+      this.modifyField.modifiableFieldName = "";
+      this.configData.modifiableFieldName = "";
+    }, //可修改字段清除事件
+    change1(val) {
+      this.status1 = val;
+      this.setOvertime = {
+        threshold: "",
+        sources: 0,
+        status: 1,
+        handleValue: "",
+        handleType: 11,
+        extraMsg: "",
+        id:this.setOvertime.id
+      }
+      
+      if (val) {
+        this.setOvertime.status = 0;
+      } else {
+        this.setOvertime.status = 1;
+      }
+    },
+    change2(val) {
+      this.status2 = val;
+      this.autoDetail = {
+        threshold: "",
+        sources: 0,
+        status: 1,
+        handleType: 20,
+        extraMsg: "",
+        handleValue: "",
+        id:this.autoDetail.id
+      }
+      if (val) {
+        this.autoDetail.status = 0;
+      } else {
+        this.autoDetail.status = 1;
+      }
+    },
+    getResult(data) {
+      this.resultData = Object.assign({}, data);
+      if (this.resultData.list.length > 0) {
+        this.approvelList = this.resultData.list.map(item => {
+          let tem = Object.assign({}, item);
+          delete tem.string;
+          return tem;
+        });
+      } else {
+        this.approvelList = [];
+      }
+    },
+    //获取可修改字段
+    findField(param) {
+      this.$network.post("/p/c/meta/column/list", param).then(res => {
+        if (res.data.code === 0) {
+          if (param.hasOwnProperty("DESCRIPTION")) {
+            this.modifyField.AutoData = [];
+            this.modifyField.AutoData = res.data.data.row.reduce(
+              (arr, item) => {
+                arr.push({
+                  value: item.DESCRIPTION.val,
+                  id: item.ID.val
+                });
+                return arr;
+              },
+              []
+            );
+          }
+          res.data.data.tabth.map(item => {
+            if (item.colname === "DESCRIPTION") {
+              item.isak = true;
+            } else {
+              item.isak = false;
+            }
+          });
+          this.modifyField.data = res.data.data;
+          this.modifyField.totalRowCount = res.data.data.totalRowCount;
+        }
+      });
+    },
+
+    saveConfig () {  //确定按钮点击
+      if(this.configData.approverStyle === 0){  //直接选择
+        // 审批人为空
+        if(this.configData.approvelList && this.configData.approvelList.length === 0){
+          this.$Modal.fcError({
+            title: '错误',
+            content: '审批人不能为空',
+            mask: true
+          })
+
+          return
+        }
+      }else{  //扩展程序
+        // 扩展程序为空
+        if(this.configData.actionConfig[0] && !this.configData.actionConfig[0].handleValue){
+          this.$Modal.fcError({
+            title: '错误',
+            content: '扩展程序不能为空',
+            mask: true
+          })
+          return
+        }
+      }
+      // 最少同意人数
+      if(!this.pageBtnData[0].value){
+        this.$Modal.fcError({
+            title: '错误',
+            content: '最少同意人数不能为空',
+            mask: true
+          })
+        return
+      }
+      // 最少拒绝人数
+      if(!this.pageBtnData[2].value){
+        this.$Modal.fcError({
+            title: '错误',
+            content: '最少拒绝人数不能为空',
+            mask: true
+          })
+        return
+      }
+
+      // 驳回节点
+      // if(!this.backId){
+      //   this.$Modal.fcError({
+      //       title: '错误',
+      //       content: '驳回节点不能为空',
+      //       mask: true
+      //     })
+      //   return
+      // }
+
+      // 超时提醒
+      if(this.status1 && (!this.setOvertime.threshold || !this.setOvertime.handleValue)){
+        this.$Modal.fcError({
+            title: '错误',
+            content: '请填写完善超时提醒信息',
+            mask: true
+          })
+        return
+      }
+      //自动处理
+      if(this.status2 && (!this.autoDetail.threshold)){
+        this.$Modal.fcError({
+            title: '错误',
+            content: '请填写完善自动处理信息',
+            mask: true
+          })
+        return
+      }
+
+      // 控制自动处理时间大于超时提醒时间
+      if(this.status1 && this.status2){
+        let start = this.setOvertime.sources === 0?Number(this.setOvertime.threshold):Number(this.setOvertime.threshold)*24
+        let end = this.autoDetail.sources === 0?Number(this.autoDetail.threshold):Number(this.autoDetail.threshold)*24
+
+        if(start >= end){
+          this.$Modal.fcError({
+              title: '错误',
+              content: '超时提醒时间不能大于自动处理时间',
+              mask: true
+            })
+          return
+        }
+      }
+      
+      let guiStyle = JSON.parse(this.$parent.$parent.myDesigner.getFlowData())
+      guiStyle.nodeDataArray.map(item => {
+        if(this.configData.key === item.key){
+          item.text = this.configData.name
+        }
+        return item
+      })
+      this.$parent.$parent.data.guiStyle = JSON.stringify(guiStyle)
+      this.$parent.$parent.init()
+      this.$emit('closeDrawer')
+    },
+    closeDrawer () {  //取消按钮点击
+      this.$parent.$parent.nodeMsg[Number(this.configData.key)] = this.defaultObj
+      this.$emit('closeDrawer')
+    },
+    approverStyleChange () {  //选择审批人类型切换
+      this.configData.actionConfig[0].handleValue = null
+      this.resultData = {}
+      this.approvelList = [];
+    }
+  },
+  created() {
+    // 保存默认值
+    this.defaultObj = JSON.parse(JSON.stringify(this.configData))
+
+    if (this.configData.actionConfig.length === 0) {
+      this.configData.actionConfig = [
+        {
+          id: null,
+          handleType: 33,
+          handleValue: null,
+          extraMsg: null
+        }
+      ];
+    } else {
+      this.configData.actionConfig = [
+        {
+          id: this.configData.actionConfig[0].id,
+          handleType: 33,
+          handleValue: this.configData.actionConfig[0].handleValue,
+          extraMsg: this.configData.actionConfig[0].extraMsg
+        }
+      ];
+    }
+
+    if (this.configData.modifiableField) {
+      this.configData.modifiableField.split(",").map((item, index) => {
+        this.modifyField.defaultSelected.push({ ID: item });
+      });
+    }
+    if (this.configData.modifiableFieldName) {
+      this.configData.modifiableFieldName.split(",").map((item, index) => {
+        this.modifyField.defaultSelected[index].Label = item;
+      });
+    }
+
+    if (
+      this.configData.approvelList &&
+      this.configData.approvelList.length > 0
+    ) {
+      this.configData.approvelList.map(item => {
+        let temObj = Object.assign({}, item);
+        this.approves += item.approveValueName?item.approveValueName:item.approve_value_name + ",";
+        temObj.approve_type = temObj.approveType?temObj.approveType:temObj.approve_type;
+        temObj.approve_value = temObj.approveValue?temObj.approveValue:temObj.approve_value;
+        temObj.approve_value_name = item.approveValueName?item.approveValueName:item.approve_value_name;
+        delete temObj.approveType;
+        delete temObj.approveValue;
+        delete temObj.approveValueName;
+
+        let temL = Object.assign({}, temObj);
+        this.approvelList.push(temObj);
+        temL.string = item.approveValueName?item.approveValueName:item.approve_value_name;
+        this.resultData.list
+          ? this.resultData.list.push(temL)
+          : this.$set(this.resultData, "list", [temL]);
+      });
+      this.resultData.total
+        ? (this.resultData.total = this.resultData.list.length)
+        : this.$set(this.resultData, "total", this.resultData.list.length);
+      if (this.approves.length > 0) {
+        this.approves = this.approves.substring(0, this.approves.length - 1);
+      }
+    }
+
+    if (
+      this.configData.ruleList &&
+      this.configData.ruleList.length > 0
+    ) {
+      this.configData.ruleList.map(item => {
+        if (item.actType === 0) {
+          this.pageBtnData[1].value = item.actName;
+          this.pageBtnData[0].value = item.actLimit;
+        }
+        if (item.actType === 1) {
+          this.pageBtnData[3].value = item.actName;
+          this.pageBtnData[2].value = item.actLimit;
+        }
+      });
+    }
+
+    if (
+      this.configData.actServiceS &&
+      this.configData.actServiceS.length > 0
+    ) {
+      this.configData.actServiceS.map(item => {
+        if (item.handleType >= 20) {
+          this.autoDetail = item;
+        } else {
+          this.setOvertime = item;
+        }
+      });
+      this.setOvertime.status === 0
+        ? (this.status1 = true)
+        : (this.status1 = false);
+      this.autoDetail.status === 0
+        ? (this.status2 = true)
+        : (this.status2 = false);
+    } else {
+      this.configData.actServiceS = [
+        {
+          threshold: "",
+          sources: 0,
+          status: 1,
+          handleValue: "",
+          handleType: 11
+        },
+        {
+          threshold: "",
+          sources: 0,
+          status: 1,
+          handleType: 20,
+          handleValue: ""
+        }
+      ];
+    }
+    
+    // this.getTreeData();
+    // this.findField({ AD_TABLE_ID: this.TABLE_ID });
+  },
+  mounted() {
+    //this.getTreeData();
+    /**/
+  }
+};
+</script>
+<style lang="scss">
+.ProcessNodeConfig {
+  overflow-y: hidden;
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+  >p{
+      text-align: right;
+      margin-top: 16px;
+
+      >button:first-child{
+        margin-right: 10px;
+      }
+    }
+  >div{
+    flex: 1;
+    overflow: auto;
+  }
+  .nodeSetbox {
+    padding: 16px;
+    border: 1px solid #dcdee2;
+    .boxItem {
+      padding: 16px 40px;
+      border-bottom: 1px solid #dcdee2;
+      &:last-child {
+        border-bottom: none;
+      }
+    }
+    .tipMessage {
+      color: #929292;
+      line-height: 16px;
+    }
+    .burgeon-form-item {
+      margin-bottom: 16px;
+      &:last-child {
+        margin-bottom: 0px;
+      }
+    }
+    &:last-child {
+      padding: 0;
+    }
+  }
+  .requireStyle {
+    font-size: 14px;
+    vertical-align: middle;
+    color: red;
+    padding-top: 5px;
+    display: inline-block;
+  }
+  .splitItem {
+    font-size: 14px;
+    line-height: 40px;
+    color: #929292;
+    &:first-child{
+      margin-top: -10px;
+    }
+  }
+  .burgeon-fkrp-select-icon {
+    top: 2px;
+  }
+}
+</style>
+
+

+ 190 - 0
ruoyi-ui/src/components/RuleConfig/index.vue

@@ -0,0 +1,190 @@
+/* 规则配置 */
+<template>
+  <div class="rule-config">
+    <Input
+      v-model="showValue"
+      placeholder="请输入"
+      icon="ios-funnel-outline"
+      @on-click="onIconclick"
+      disabled
+    />
+    <Modal
+      v-model="openControl"
+      :title="modalTitle"
+      :mask="true"
+      :mask-closable="false"
+      :width="472"
+      @on-ok="ok"
+      @on-cancel="cancel"
+    >
+      <div class="modalCotent">
+        <div class="content-head">
+          <span class="head-tip">{{headTitle}}</span>
+          <span class="head-operate" @click="addRule">添加事件</span>
+        </div>
+        <div class="rule-item" v-for="(item,index) in ruleLists" :key="index">
+          <i class="iconfont iconmd-settings clear-item" @click="clickItem(index)"></i>
+          <div class="setting" v-if="item.showTip">
+            <div v-bind:class="[isActive?'active':'normal']" @click="up(index)">上移</div>
+            <div v-bind:class="[isActive?'active':'normal']" @click="Top(index)">置顶</div>
+            <div v-bind:class="[isActive?'active':'normal']" @click="deleteItem(index)">删除</div>
+          </div>
+          <URLAndField :item="item.config" :tableConfig="tableConfig" />
+        </div>
+      </div>
+    </Modal>
+  </div>
+</template>
+<script>
+import URLAndField from "@/components/URLAndField";
+export default {
+  components: { URLAndField },
+  props: {
+    modalTitle: {
+      type: String,
+      default: "规则配置"
+    },
+    headTitle: {
+      type: String,
+      default: "节点必经规则"
+    },
+    defaultData: {
+      type: Array,
+      default: () => {
+        return [];
+      }
+    },
+    tableConfig: {
+      type: Object,
+      default: () => {
+        return {};
+      }
+    }
+  },
+  data() {
+    return {
+      showValue: "", //输入框绑定值
+      openControl: false, //控制弹框打开还是关闭
+      ruleLists: [
+        {
+          showTip: false,
+          config: {}
+        }
+      ],
+      isActive: false, //是否激活
+    };
+  },
+  methods: {
+    onIconclick() {
+      this.openControl = true;
+    }, //输入框图标点击事件
+    ok() {
+      this.$emit("getResult");
+    }, //确定
+    cancel() {}, //取消
+    addRule() {
+      this.ruleLists.push({
+        showTip: false,
+        config: {}
+      });
+    }, //添加规则
+    clickItem(index) {
+      this.ruleLists[index].showTip = !this.ruleLists[index].showTip;
+    }, //清除规则
+    up(index) {
+      let current = this.ruleLists[index];
+      this.ruleLists.splice(index - 1, 1, current);
+      this.ruleLists.splice(index + 1, 1);
+    }, //上移
+    Top(index) {
+      let current = this.ruleLists[index];
+      this.ruleLists.splice(index, 1);
+      this.ruleLists.unshift(current);
+    }, //置顶
+    deleteItem(index) {
+      this.ruleLists.splice(index, 1);
+    } //删除
+  },
+  mounted() {}
+};
+</script>
+<style lang="scss">
+.rule-config {
+}
+.modalCotent {
+  width: 440px;
+  .content-head {
+    padding: 0 10px 10px;
+    box-sizing: border-box;
+    display: flex;
+    justify-content: space-between;
+    .head-tip {
+      font-size: 14px;
+      font-family: PingFangSC-Regular, PingFang SC;
+      font-weight: 400;
+      color: rgba(146, 146, 146, 1);
+      line-height: 20px;
+    }
+    .head-operate {
+      font-size: 14px;
+      font-family: PingFangSC-Regular, PingFang SC;
+      font-weight: 400;
+      color: rgba(16, 142, 233, 1);
+      line-height: 20px;
+    }
+  }
+  .rule-item {
+    width: 440px;
+    background: rgba(255, 255, 255, 1);
+    border: 1px solid rgba(220, 222, 226, 1);
+    padding: 8px 40px 8px 0px;
+    position: relative;
+    margin-bottom: 10px;
+    .setting {
+      width: 100px;
+      height: 112px;
+      background: rgba(255, 255, 255, 1);
+      box-shadow: 0px 1px 6px 0px rgba(0, 0, 0, 0.2);
+      border-radius: 4px;
+      position: absolute;
+      right: 10px;
+      top: 38px;
+      z-index: 100;
+    }
+
+    .clear-item {
+      position: absolute;
+      right: 10px;
+      top: 16px;
+      width: 14px;
+      height: 14px;
+      color: rgba(16, 142, 233, 1);
+    }
+    .normal {
+      height: 34px;
+      font-size: 14px;
+      font-family: PingFangSC-Regular, PingFang SC;
+      font-weight: 400;
+      color: rgba(81, 90, 110, 1);
+      line-height: 34px;
+      padding-left: 16px;
+    }
+    .active {
+      height: 34px;
+      font-size: 14px;
+      font-family: PingFangSC-Regular, PingFang SC;
+      font-weight: 400;
+      color: rgba(16, 142, 233, 1);
+      height: 34px;
+      background: rgba(243, 243, 243, 1);
+      padding-left: 16px;
+    }
+    .url-and-field .showDetail {
+      margin-top: 10px;
+      margin-left: 10px;
+      /* margin-right: -10px; */
+      width: 420px;
+    }
+  }
+}
+</style>

+ 515 - 0
ruoyi-ui/src/components/RuleConfigurationComponent/index.vue

@@ -0,0 +1,515 @@
+//参数配置界面
+<template>
+  <div class="ParameterConfiguration">
+    <FormItemComponent
+      class="form"
+      :formItemLists="formLists"
+      :buttonType="false"
+      :defaultColumn="1"
+      @formChange="formChange"
+    ></FormItemComponent>
+  </div>
+</template>
+<script>
+import FormItemComponent from '@/components/FormItemComponent';
+import ItemComponent from '@/components/ItemComponent';
+export default {
+  components:{FormItemComponent},
+  props:{
+    data:{
+      type:Object
+    }
+  },
+  watch:{
+    data:{
+      handler () {
+        this.formLists = [
+            {
+              row:1,
+              col:1,
+              component:ItemComponent,
+              item:{
+                type:'select',
+                title:'模版类型',
+                filed:'moduleType',
+                value:this.data.moduleType,
+                props:{
+                  disabled:this.disabled,
+                  clearable: false,
+                },
+                options:[
+                  {
+                    value: 0,
+                    label: '固定模版'
+                  },
+                  {
+                    value: 1,
+                    label: '动态模版'
+                  }
+                ]
+              }
+            },
+            {
+              row:1,
+              col:1,
+              component:ItemComponent,
+              item:{
+                type:'DropDownSelectFilter',
+                title:'单据类型',
+                filed:'businessType',
+                required:true,
+                hidden: this.data.moduleType === 1,
+                props:{
+                  columnsKey:['NAME'],
+                  AutoData:[],
+                  hidecolumns:['id'],
+                  data:{},
+                  totalRowCount:0,
+                  defaultSelected:this.data.businessType,
+                  disabled:this.disabled
+                },
+                event:{
+                  inputValueChange: (value) => {
+                      // 外键的模糊搜索
+                      this.fkFuzzyquerybyak(value)
+                  },
+                  'on-show': ($this) => {
+                    // 当外键下拉站开始去请求数据
+                    this.freshDropDownSelectFilterData($this)
+                  },
+                  pageChange: (currentPage, $this) => {
+                    // 外键的分页查询
+                    this.freshDropDownSelectFilterData($this,currentPage)
+                  },
+                  blur:(event,instance) => {
+                    if(Object.prototype.toString.call(this.data.businessType) !== '[object Array]' || this.data.businessType.length === 0){
+                      this.data.businessType = []
+                      instance.inputValue = ''
+                    }
+                    
+                  }
+                }
+              }
+            },
+            {
+              row:1,
+              col:1,
+              component:ItemComponent,
+              item:{
+                type:'input',
+                title:'模版名称',
+                filed:'name',
+                required:true,
+                value:this.data.name,
+                props:{
+                  // disabled:this.data.status === 1
+                }
+              }
+            },
+            {
+              row:1,
+              col:1,
+              component:ItemComponent,
+              item:{
+                type:'DropDownSelectFilter',
+                title:'查询索引',
+                filed:'businessNumber',
+                hidden: this.data.moduleType === 1,
+                props:{
+                  columnsKey:['NAME'],
+                  AutoData:[],
+                  hidecolumns:['id'],
+                  data:{},
+                  totalRowCount:0,
+                  defaultSelected:this.data.businessNumber,
+                  // disabled:this.data.status === 1
+                },
+                event:{
+                  inputValueChange: (value,instance) => {
+                      if(!this.data.businessType || this.data.businessType.lengt == 0 || !this.data.businessType[0].ID){
+                        this.$Modal.fcWarning({
+                          title:'警告',
+                          content:'请先选择单据类型!'
+                        })
+                        this.data.businessNumber = []
+                        instance.inputValue = ''
+                        return
+                      }
+                      // 外键的模糊搜索
+                      this.fkFuzzyquerybyakcolumn(value)
+                  },
+                  'on-show': ($this) => {
+                    // 当外键下拉站开始去请求数据
+                    if(!this.data.businessType || this.data.businessType.lengt == 0 || !this.data.businessType[0].ID){
+                      this.$Modal.fcWarning({
+                        title:'警告',
+                        content:'请先选择单据类型!'
+                      })
+                      this.data.businessNumber = []
+                      $this.inputValue = ''
+                      return
+                    }
+                    this.freshDropDownSelectFilterDataColumn($this)
+                  },
+                  pageChange: (currentPage, $this) => {
+                    // 外键的分页查询
+                    this.freshDropDownSelectFilterDataColumn($this,currentPage)
+                  },
+                  blur:(event,instance) => {
+                    if(Object.prototype.toString.call(this.data.businessNumber) !== '[object Array]' || this.data.businessNumber.length === 0){
+                      this.data.businessNumber = []
+                      instance.inputValue = ''
+                    }
+                    
+                  }
+                }
+              }
+            },
+            {
+              row:1,
+              col:1,
+              component:ItemComponent,
+              item:{
+                type:'input',
+                title:'模版描述',
+                filed:'description',
+                value:this.data.description,
+                props:{
+                  type:'textarea',
+                  // disabled:this.data.status === 1
+                }
+              }
+            },
+            {
+              row:1,
+              col:1,
+              component:ItemComponent,
+              item:{
+                type:'Switch',
+                title:'开启自动处理',
+                filed:'autoClose',
+                value:this.data.autoClose,
+              }
+            },
+            {
+              row:1,
+              col:1,
+              component:ItemComponent,
+              item:{
+                type:'input',
+                title:'业务数据检查',
+                filed:'businessCheckUrl',
+                value:this.data.businessCheckUrl
+              }
+            }
+          ]
+      },
+      deep:true
+    }
+  },
+  data () {
+    return {
+      formLists:[
+        {
+          row:1,
+          col:1,
+          component:ItemComponent,
+          item:{
+            type:'select',
+            title:'模版类型',
+            filed:'moduleType',
+            value: 0,
+            props:{
+              disabled:false,
+              clearable: false
+            },
+            options:[
+              {
+                value: 0,
+                label: '固定模版'
+              },
+              {
+                value: 1,
+                label: '动态模版'
+              }
+            ]
+          }
+        },
+        {
+          row:1,
+          col:1,
+          component:ItemComponent,
+          item:{
+            type:'DropDownSelectFilter',
+            title:'单据类型',
+            filed:'businessType',
+            required:true,
+            hidden: this.data.moduleType === 1,
+            props:{
+              columnsKey:['NAME'],
+              AutoData:[],
+              hidecolumns:['id'],
+              data:{},
+              totalRowCount:0
+            },
+            event:{
+              inputValueChange: (value) => {
+                  // 外键的模糊搜索
+                  this.fkFuzzyquerybyak(value)
+              },
+              'on-show': ($this) => {
+                // 当外键下拉站开始去请求数据
+                this.freshDropDownSelectFilterData($this)
+              },
+              pageChange: (currentPage, $this) => {
+                // 外键的分页查询
+                this.freshDropDownSelectFilterData($this,currentPage)
+              },
+              blur:(event,instance) => {
+                if(Object.prototype.toString.call(this.data.businessType) !== '[object Array]' || this.data.businessType.length === 0){
+                  this.data.businessType = []
+                  instance.inputValue = ''
+                }
+                
+              }
+            }
+          }
+        },
+        {
+          row:1,
+          col:1,
+          component:ItemComponent,
+          item:{
+            type:'input',
+            title:'模版名称',
+            filed:'name',
+            required:true,
+            value:this.data.name
+          }
+        },
+        {
+          row:1,
+          col:1,
+          component:ItemComponent,
+          item:{
+            type:'DropDownSelectFilter',
+            title:'查询索引',
+            filed:'businessNumber',
+            hidden: this.data.moduleType === 1,
+            props:{
+              columnsKey:['NAME'],
+              AutoData:[],
+              hidecolumns:['id'],
+              data:{},
+              totalRowCount:0
+            },
+            event:{
+              inputValueChange: (value,instance) => {
+                  if(!this.data.businessType || this.data.businessType.lengt == 0 || !this.data.businessType[0].ID){
+                    this.$Modal.fcWarning({
+                      title:'警告',
+                      content:'请先选择单据类型!'
+                    })
+                    this.data.businessNumber = []
+                    instance.inputValue = ''
+                    return
+                  }
+                  // 外键的模糊搜索
+                  this.fkFuzzyquerybyakcolumn(value)
+              },
+              'on-show': ($this) => {
+                // 当外键下拉站开始去请求数据
+                if(!this.data.businessType || this.data.businessType.lengt == 0 || !this.data.businessType[0].ID){
+                  this.$Modal.fcWarning({
+                    title:'警告',
+                    content:'请先选择单据类型!'
+                  })
+                  this.data.businessNumber = []
+                  $this.inputValue = ''
+                  return
+                }
+                this.freshDropDownSelectFilterDataColumn($this)
+              },
+              pageChange: (currentPage, $this) => {
+                // 外键的分页查询
+                this.freshDropDownSelectFilterDataColumn($this,currentPage)
+              },
+              blur:(event,instance) => {
+
+                if(Object.prototype.toString.call(this.data.businessNumber) !== '[object Array]' || this.data.businessNumber.length === 0){
+                  this.data.businessNumber = []
+                  instance.inputValue = ''
+                }
+                
+              }
+            }
+          }
+        },
+        {
+          row:1,
+          col:1,
+          component:ItemComponent,
+          item:{
+            type:'input',
+            title:'模版描述',
+            filed:'description',
+            value:this.data.description,
+            props:{
+              type:'textarea',
+            }
+          }
+        },
+        {
+          row:1,
+          col:1,
+          component:ItemComponent,
+          item:{
+            type:'Switch',
+            title:'开启自动处理',
+            filed:'autoClose',
+            value:true,
+          }
+        },
+        {
+          row:1,
+          col:1,
+          component:ItemComponent,
+          item:{
+            type:'input',
+            title:'业务数据检查',
+            filed:'businessCheckUrl',
+            value:this.data.businessCheckUrl
+          }
+        }
+      ],
+      formData:{},
+      row:[],
+      disabled: false
+    }
+  },
+  methods:{
+    formChange (data) {  //数据修改
+      if(data.businessType && data.businessType.length > 0){
+        this.row.map(item => {
+          if(item.ID.val === data.businessType[0].ID){
+            data.businessType[0].val = item.DESCRIPTION.val
+            data.businessType[0].Label = item.NAME.val
+          }
+          return item
+        })
+      }
+
+      if(data.businessNumber && data.businessNumber.length > 0){
+        this.row.map(item => {
+          if(item.ID.val === data.businessNumber[0].ID){
+            data.businessNumber[0].val = item.DESCRIPTION.val
+            data.businessNumber[0].Label = item.NAME.val
+          }
+          return item
+        })
+      }
+
+      this.formData = Object.assign(this.formData,data)
+      this.$emit('dataChange',this.formData)
+    },
+    fkFuzzyquerybyak (value) {  //单据类型模糊搜素
+      this.formLists[1].item.props.AutoData = []
+      this.$network.post('/p/c/meta/table/list',{DESCRIPTION:value}).then(res => {
+        if(res.data.code === 0){
+          this.row = res.data.data.row.concat([])
+          this.formLists[1].item.props.AutoData = res.data.data.row.reduce((arr,item) => {
+            arr.push({
+              value:item.NAME.val,
+              id:item.ID.val,
+              NAME:item.DESCRIPTION.val
+            })
+            return arr
+          },[]);
+        }
+        
+      })
+    },
+    freshDropDownSelectFilterData (instance,currentPage) {  //外键列表查询
+        this.$network.post('/p/c/meta/table/list',{
+          pageSize:instance.pageSize,
+          page:currentPage?currentPage:1
+        }).then(res => {
+          if(res.data.code === 0){
+            this.row = res.data.data.row.concat([])
+            res.data.data.tabth.forEach(item => {
+              if(item.colname === 'DESCRIPTION'){
+                item.isak = true
+              }
+              return item
+            })
+            // res.data.datas.row.forEach(item => {
+            //   item.ID.val = item.NAME.val
+            //   return item
+            // })
+            this.formLists[1].item.props.data = res.data.data;
+            this.formLists[1].item.props.totalRowCount = res.data.data.totalRowCount;
+          }
+          
+        })
+    },
+    fkFuzzyquerybyakcolumn (value) {  //单据类型模糊搜素
+      this.formLists[3].item.props.AutoData = []
+      this.$network.post('/p/c/meta/column/list',{ DESCRIPTION: value, AD_TABLE_ID: this.data.businessType[0].ID}).then(res => {
+        if(res.data.code === 0){
+          this.row = res.data.data.row.concat([])
+          this.formLists[3].item.props.AutoData = res.data.data.row.reduce((arr,item) => {
+            arr.push({
+              value:item.NAME.val,
+              id:item.ID.val,
+              NAME:item.DESCRIPTION.val
+            })
+            return arr
+          },[]);
+        }
+        
+      })
+    },
+    freshDropDownSelectFilterDataColumn (instance,currentPage) {  //外键列表查询
+        
+        this.$network.post('/p/c/meta/column/list',{
+          pageSize:instance.pageSize,
+          page:currentPage?currentPage:1,
+          AD_TABLE_ID: this.data.businessType[0].ID
+        }).then(res => {
+          if(res.data.code === 0){
+            this.row = res.data.data.row.concat([])
+            res.data.data.tabth.forEach(item => {
+              if(item.colname === 'DESCRIPTION'){
+                item.isak = true
+              }
+              return item
+            })
+            // res.data.datas.row.forEach(item => {
+            //   item.ID.val = item.NAME.val
+            //   return item
+            // })
+            this.formLists[3].item.props.data = res.data.data;
+            this.formLists[3].item.props.totalRowCount = res.data.data.totalRowCount;
+          }
+          
+        })
+    }
+  },
+  created () {
+    this.$route.params.id !== '-1'?this.disabled = true:this.disabled = false
+  }
+}
+</script>
+<style lang="scss" scoped>
+.ParameterConfiguration{
+  padding-top:50px;
+  display: flex;
+  justify-content:center;
+
+  .form{
+    border: none;
+    width: 420px;
+  }
+}
+</style>
+

+ 453 - 0
ruoyi-ui/src/components/ServiceNodeConfig/index.vue

@@ -0,0 +1,453 @@
+/* 服务节点配置 */
+<template>
+  <div class="service-node-config">
+    <div class="node-name">节点配置</div>
+    <FormItemComponent
+      class="node-config-content"
+      :formItemLists="formLists"
+      :buttonType="false"
+      :defaultColumn="1"
+      @formChange="formChange"
+    ></FormItemComponent>
+    <div class="btnArea">
+      <Button type="text" class="cancel" @click="cancel">取消</Button>
+      <Button type="primary" @click="ok">确定</Button>
+    </div>
+  </div>
+</template>
+<script>
+import FormItemComponent from "@/components/FormItemComponent";
+import ItemComponent from "@/components/ItemComponent";
+export default {
+  components: { FormItemComponent },
+  props: {
+    configData: {
+      type: Object,
+      default: () => {
+        return {};
+      }
+    }
+  },
+  data() {
+    return {
+      formLists: [
+        {
+          row: 1,
+          col: 1,
+          component: ItemComponent,
+          item: {
+            type: "select",
+            title: "服务实现",
+            filed: "handleType",
+            value: "",
+            required: true,
+            // show: true, //控制组件是否显示
+            props: {
+              clearable: false
+            },
+            options: [
+              // {
+              //   value: 51,
+              //   label: "RESET"
+              // },
+              // {
+              //   value: 52,
+              //   label: "消息系统"
+              // }
+            ],
+            event: {
+              change: val => {
+                this.onChange(val);
+              }
+            }
+          }
+        },
+        {
+          row: 1,
+          col: 1,
+          component: ItemComponent,
+          item: {
+            type: "select",
+            title: "请求状态",
+            filed: "requestStaus",
+            required: true,
+            value: "",
+            hidden: true, //是否隐藏该字段
+            props: {
+              regx: /^[0-9]*$/
+            },
+            options: [
+              {
+                value: 1,
+                label: "异步"
+              },
+              {
+                value: 2,
+                label: "同步"
+              }
+            ],
+            event: {
+              change: val => {
+                this.statusChange(val);
+              }
+            }
+          }
+        },
+        {
+          row: 1,
+          col: 1,
+          component: ItemComponent,
+          item: {
+            type: "selectInput",
+            title: "重试次数",
+            filed: "tryNum",
+            required: true,
+            hidden: true,
+            value: "",
+            slot: true,
+            slotValue: "",
+            slotfiled: "tryType",
+            props: {
+              readonly: false
+            }
+          }
+        },
+        {
+          row: 1,
+          col: 1,
+          component: ItemComponent,
+          item: {
+            type: "Switch",
+            title: "阻塞",
+            filed: "block",
+            value: false,
+            hidden: true
+          }
+        },
+        {
+          row: 1,
+          col: 1,
+          component: ItemComponent,
+          item: {
+            type: "input",
+            title: "URL",
+            filed: "url",
+            required: true,
+            hidden: true
+            // props: {
+            //   regx: /^[0-9]*$/
+            // }
+          }
+        },
+        {
+          row: 1,
+          col: 1,
+          component: ItemComponent,
+          item: {
+            type: "select",
+            title: "消息类型",
+            filed: "msgType",
+            value: null,
+            required: true,
+            hidden: true, //控制组件是否显示
+            props: {
+            },
+            options: [],
+            event: {
+              change: val => {
+                
+              }
+            }
+          }
+        },
+        {
+          row: 1,
+          col: 1,
+          component: ItemComponent,
+          item: {
+            type: "input",
+            title: "服务参数",
+            filed: "extraMsg",
+            value: "",
+            required: true,
+            // show: true, //控制组件是否显示
+            props: {
+              
+            }
+          }
+        }
+      ],
+      defaultData: {}, //默认值
+      resultData: {}, //最终的结果
+      verifyMessage: "" //提示信息
+    };
+  },
+  computed: {
+    tryType: function() {
+      return this.formLists[2].item.slotValue;
+    }
+  },
+  watch: {
+    tryType: {
+      handler: function(newVal) {
+        if (newVal === 1) {
+          this.formLists[2].item.value = "不限次数";
+          this.formLists[2].item.props.readonly = true;
+          if(this.formLists[2].item.props.number){
+            this.formLists[2].item.props.number=false;
+          }
+          if(this.formLists[2].item.props.regx){
+            delete this.formLists[2].item.props.regx
+          }
+        } else {
+          this.formLists[2].item.props.readonly = false;
+          this.formLists[2].item.value=''
+          this.formLists[2].item.props.number?this.formLists[2].item.props.number=true:this.$set(this.formLists[2].item.props, "number", true);
+          this.$set(this.formLists[2].item.props,'regx',/^[0-9]*$/);
+        }
+      },
+      deep: true
+    }
+  },
+  methods: {
+    getTypes () {
+      this.$network.post('/p/cs/node/service/type',{})
+        .then(res => {
+          if(res.data.resultCode === 0){
+            this.formLists = this.formLists.map(temp => {
+              if(temp.item.filed === 'handleType'){
+                temp.item.options = res.data.data.serviceType
+              }
+
+              if(temp.item.filed === 'msgType'){
+                temp.item.options = res.data.data.msgType
+              }
+
+              return temp
+            })
+          }
+        })
+    },
+    statusChange(val) {
+      if (val === 2) {
+        this.formLists = this.formLists.map(item => {
+          if (item.item.filed === "requestStaus") {
+            item.item.value = val;
+          }
+          if (item.item.filed === "tryNum") {
+            delete item.item.hidden;
+          }
+          if (item.item.filed === "block") {
+            delete item.item.hidden;
+          }
+          return item;
+        });
+      } else {
+        this.formLists = this.formLists.map(item => {
+          if (item.item.filed === "requestStaus") {
+            item.item.value = val;
+          }
+          if (item.item.filed === "tryNum") {
+            item.item.hidden = true;
+            item.item.value='';
+            item.item.slotValue='';
+          }
+          if (item.item.filed === "block") {
+            item.item.hidden = true;
+            item.item.value='';
+          }
+          return item;
+        });
+      }
+    }, //请求状态change事件
+    onChange(val) {
+      if (val === 51) {
+        this.formLists = this.formLists.map(item => {
+          if (item.item.filed === "handleType") {
+            item.item.value = val;
+          }
+          if (item.item.filed === "requestStaus") {
+            delete item.item.hidden;
+          }
+          if (item.item.filed === "url") {
+            delete item.item.hidden;
+          }
+
+          if (item.item.filed === "msgType") {
+            item.item.hidden = true;
+            item.item.value='';
+          }
+          return item;
+        });
+      } else {
+        this.formLists = this.formLists.map(item => {
+          if (item.item.filed === "handleType") {
+            item.item.value = val;
+          }
+          if (item.item.filed === "requestStaus") {
+            item.item.hidden = true;
+            item.item.value='';
+          }
+          if (item.item.filed === "url") {
+            item.item.hidden = true;
+            item.item.value='';
+          }
+          if (item.item.filed === "tryNum") {
+            item.item.hidden = true;
+            item.item.value='';
+            item.item.slotValue='';
+          }
+          if (item.item.filed === "block") {
+            item.item.hidden = true;
+            item.item.value='';
+          }
+
+          if (item.item.filed === "msgType") {
+            item.item.hidden = false;
+            item.item.value='';
+          }
+          return item;
+        });
+      }
+    }, //服务实现change事件
+    formChange(data) {
+      let result = Object.assign({}, data);
+      Object.keys(result).forEach(item => {
+        this.formLists.forEach(inner => {
+          if (item === inner.item.filed) {
+            inner.item.value = result[item];
+          }
+          if (inner.item.type === "selectInput") {
+            if (item === inner.item.slotfiled) {
+              inner.item.slotValue = result[item];
+            }
+          }
+        });
+      });
+    },
+    checkMessage(item, title) {
+      let tipMessage = "";
+      if (item.type !== "selectInput") {
+        tipMessage = item.rexMessage || "请输入" + title;
+      } else {
+        tipMessage = "尝试类型与尝试次数都不能为空";
+      }
+      this.verifyMessage = tipMessage;
+      return this.verifyMessage;
+    }, //提示信息
+    verifyCheck(item, required,hidden) {
+      if (required && required === true && (!item.item.value && item.item.value !== 0) && !hidden) {
+        if (item.item.type === "selectInput") {
+          if (!item.item.value || !item.item.slotValue) {
+            this.checkMessage(item.item, item.item.title);
+          }
+        } else {
+          this.checkMessage(item.item, item.item.title);
+        }
+        return true;
+      } else {
+        return false;
+      }
+    },
+    verify() {
+      this.verifyMessage = "";
+      this.formLists.some(item => {
+        return this.verifyCheck(item, item.item.required,item.item.hidden);
+      });
+      return this.verifyMessage;
+    }, //调用校验函数
+    ok() {
+      if (this.verify() !== "") {
+        this.$Message.warning(this.verify());
+        return false;
+      }
+      let handleValue = {};
+      this.formLists.forEach(item => {
+        if (item.item.filed == "handleType" || item.item.filed === "extraMsg") {
+          this.$set(this.resultData, item.item.filed, item.item.value);
+        } else {
+          handleValue[item.item.filed] = item.item.value;
+          if (item.item.type === "selectInput") {
+            handleValue[item.item.slotfiled] = item.item.slotValue;
+          }
+        }
+      });
+      this.$set(this.resultData, "handleValue", handleValue);
+      this.configData.actionConfig[0] = this.resultData
+      this.$emit('closeDrawer')
+    }, //确定
+    cancel() {
+      this.$parent.$parent.nodeMsg[Number(this.configData.key)] = this.defaultData
+      this.$emit('closeDrawer')
+    } //取消
+  },
+  created () {
+    this.getTypes()
+  },
+  mounted() {
+    this.defaultData = JSON.parse(JSON.stringify(this.configData))
+    if (this.configData.actionConfig[0]) {
+      Object.keys(this.configData.actionConfig[0]).forEach(key => {
+        this.formLists.forEach(item => {
+          if (key === item.item.filed) {
+            item.item.value = this.configData.actionConfig[0][key];
+          }
+        });
+      });
+      if (this.configData.actionConfig[0].handleValue) {
+        Object.keys(this.configData.actionConfig[0].handleValue).forEach(key => {
+          this.formLists.forEach(item => {
+            if (key === item.item.filed) {
+              item.item.value = this.configData.actionConfig[0].handleValue[key];
+              if(this.configData.actionConfig[0].handleValue[key]){
+                item.item.hidden=false;
+              }
+            }
+            if (key === item.item.slotfiled) {
+              item.item.slotValue = this.configData.actionConfig[0].handleValue[key];
+            }
+          });
+        });
+      }
+    }
+  }
+};
+</script>
+<style lang="scss">
+.service-node-config {
+  position: relative;
+  width: 440px;
+  .node-name {
+    font-size: 14px;
+    font-family: PingFangSC-Regular, PingFang SC;
+    font-weight: 400;
+    color: rgba(146, 146, 146, 1);
+    line-height: 20px;
+    margin-bottom: 10px;
+  }
+  .node-config-content {
+    width: 440px;
+    height: 513px;
+    background: rgba(255, 255, 255, 1);
+    border: 1px solid rgba(220, 222, 226, 1);
+    box-sizing: border-box;
+    padding: 1px 39px 17px;
+    .ItemComponentRoot {
+      padding-top: 16px;
+      .itemComponent {
+        overflow: visible;
+      }
+    }
+  }
+  .btnArea {
+    margin-top: 16px;
+    position: absolute;
+    right: 0;
+    .cancel {
+      border: 1px solid rgba(91, 133, 228, 1);
+      color: rgba(91, 133, 228, 1);
+      margin-right: 10px;
+    }
+  }
+}
+</style>

+ 298 - 0
ruoyi-ui/src/components/URLAndField/index.vue

@@ -0,0 +1,298 @@
+<template>
+  <div class="url-and-field">
+    <div class="rule-component-item">
+      <span class="itemLabel">
+        <span v-if="true" class="label-tip">*</span>
+        扩展字段:
+      </span>
+      <div class="itemComponent">
+        <Input v-model="item.handleValue" />
+      </div>
+    </div>
+    <div class="rule-component-item">
+      <span class="itemLabel">字段名称:</span>
+      <div class="itemComponent">
+        <DropMultiSelectFilter
+          :single="false"
+          :data="dropSelectConfig.data"
+          :totalRowCount="dropSelectConfig.totalRowCount"
+          :pageSize="dropSelectConfig.pageSize"
+          :dataEmptyMessage="dropSelectConfig.dataEmptyMessage"
+          :columns="dropSelectConfig.columns"
+          :AutoData="dropSelectConfig.AutoData"
+          :defaultSelected="dropSelectConfig.defaultSelected"
+          :isBackRowItem="true"
+          @on-fkrp-selected="fkrpSelected"
+          @on-page-change="pageChange"
+          @on-input-value-change="inputValueChange"
+          @on-popper-show="fkrpSelectedPopperShow"
+          @on-clear="fkrpSelectedClear"
+        ></DropMultiSelectFilter>
+          <span
+            class="controlTip"
+            style="color:#5B85E4;cursor:pointer"
+            v-if="item.fornt_presentation_value&&item.fornt_presentation_value.length > 0"
+            @click="controlTable"
+          >{{selectDetail?'关闭修改':'更改权限'}}</span>
+          <span
+            class="controlTip"
+            style="color:#ccc;cursor:pointer"
+            v-if="!item.fornt_presentation_value||item.fornt_presentation_value&&item.fornt_presentation_value.length === 0"
+          >更改权限</span>
+      </div>
+    </div>
+    <Table
+      v-if="selectDetail"
+      border
+      :columns="table.columns"
+      :data="table.data"
+      class="showDetail"
+    ></Table>
+  </div>
+</template>
+<script>
+export default {
+  props: {
+    item: {
+      type: Object,
+      default: () => {
+        return {};
+      }
+    },
+    tableConfig: {
+      type: Object,
+      default: () => {
+        return {
+          tableId: "14443",
+          tableName: "AD_SUBSYSTEM"
+        };
+      }
+    }
+  },
+  data() {
+    return {
+      controlMessage: "修改规则",
+      dropSelectConfig: {
+        data: {},
+        totalRowCount: 1,
+        pageSize: 10,
+        dataEmptyMessage: "数据为空",
+        AutoData: [],
+        columnsKey: ["value"], //input显示的字段
+        columns: ["id"], //模糊搜索隐藏的列
+        defaultSelected: []
+      },
+      selectDetail: false, //控制表格是否显示
+      table: {
+        columns: [
+          {
+            title: "常量名",
+            key: "keyName"
+          },
+          {
+            title: "常量值",
+            key: "keyValue",
+            render: (h, params) => {
+              return h(
+                "Input",
+                {
+                  class: "isNone",
+                  style: {
+                    width: "100%",
+                    height: "100%"
+                  },
+                  props: {
+                    value: params.row.keyValue,
+                    autosize: true
+                  },
+                  on: {
+                    input: val => {
+                      if (!this.item.fornt_data) {
+                        this.item.fornt_data = {};
+                      }
+                      this.item.fornt_data[params.row.name] = val;
+                    }
+                  }
+                },
+                params.row.keyValue
+              );
+            }
+          },
+          {
+            title: "操作",
+            render: (h, params) => {
+              return h(
+                "span",
+                {
+                  style: {
+                    color: "rgba(91,133,228,1)"
+                  },
+                  on: {
+                    click: () => {
+                      this.table.data.splice(params.index, 1);
+                      let findIndex = this.item.fornt_presentation_value.findIndex(
+                        itemE => {
+                          return params.row.ID === itemE.ID;
+                        }
+                      );
+                      if (findIndex !== -1) {
+                        this.item.fornt_presentation_value.splice(findIndex, 1);
+                      }
+                      this.dropSelectConfig.defaultSelected = this.item.fornt_presentation_value;
+                    }
+                  }
+                },
+                "删除"
+              );
+            }
+          }
+        ],
+        data: []
+      }
+    };
+  },
+  methods: {
+    fkrpSelected(selected) {
+      this.item.fornt_presentation_value = selected;
+      this.table.data = this.item.fornt_presentation_value.map(value => {
+        let keyValue = "";
+        return {
+          ID: value.rowItem.ID.val,
+          name: value.rowItem.NAME.val,
+          keyName: value.rowItem.DESCRIPTION.val,
+          keyValue: keyValue
+        };
+      });
+    },
+    inputValueChange(value) {
+      this.findField({
+        DESCRIPTION: value,
+        AD_TABLE_ID: this.tableConfig.tableId
+      });
+    },
+    fkrpSelectedClear() {
+      this.item.fornt_presentation_value = [];
+      this.table.data = [];
+      this.selectDetail=false;
+    }, //下拉多选清除事件
+    pageChange(value) {
+      this.findField({
+        pageSize: this.dropSelectConfig.pageSize,
+        page: value,
+        AD_TABLE_ID: this.tableConfig.tableId
+      });
+    },
+
+    fkrpSelectedPopperShow() {
+      this.findField({ AD_TABLE_ID: this.tableConfig.tableId });
+    },
+    //获取字段名
+    findField(param) {
+      this.$network.post("/p/c/meta/column/list", param).then(res => {
+        if (res.data.code === 0) {
+          if (param.hasOwnProperty("DESCRIPTION")) {
+            this.dropSelectConfig.AutoData = [];
+            this.dropSelectConfig.AutoData = res.data.data.row.reduce(
+              (arr, item) => {
+                arr.push({
+                  value: item.DESCRIPTION.val,
+                  id: item.ID.val
+                });
+                return arr;
+              },
+              []
+            );
+          }
+          res.data.data.tabth.map(item => {
+            if (item.colname === "DESCRIPTION") {
+              item.isak = true;
+            } else {
+              item.isak = false;
+            }
+            return item;
+          });
+          this.dropSelectConfig.data = res.data.data;
+          this.dropSelectConfig.totalRowCount = res.data.data.totalRowCount;
+        }
+      });
+    },
+    controlTable() {
+      this.selectDetail = !this.selectDetail;
+    } //控制表格是否显示
+  },
+  created() {
+    if (
+      this.item.fornt_presentation_value &&
+      this.item.fornt_presentation_value.lenth > 0 &&
+      this.item.fornt_data &&
+      Object.keys(this.item.fornt_data).length > 0
+    ) {
+      this.dropSelectConfig.defaultSelected = this.item.fornt_presentation_value;
+      this.table.data = this.item.fornt_presentation_value.map(value => {
+        let keyValue = "";
+        Object.keys(this.item.fornt_data).forEach(inner => {
+          if (inner === value.rowItem.Name.val) {
+            keyValue = this.item.fornt_data[inner];
+          }
+        });
+        return {
+          ID: value.rowItem.ID.val,
+          name: value.rowItem.NAME.val,
+          keyName: value.rowItem.DESCRIPTION.val,
+          keyValue: keyValue
+        };
+      });
+      this.selectDetail = true;
+    }
+  }
+};
+</script>
+<style lang="scss">
+.url-and-field {
+  width: 100%;
+  .rule-component-item {
+    width: 100%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    padding-top: 8px;
+
+    .itemLabel {
+      width: 100px;
+      margin-right: 8px;
+      text-align: right;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+      display: inline-block;
+    }
+
+    .itemComponent {
+      flex: 1;
+      overflow: hidden;
+      &:last-child {
+        display: flex;
+      }
+      #dropDownSelectFilter {
+        flex: 1;
+      }
+      .controlTip {
+        width: 49px;
+        // color: rgba(91, 133, 228, 1);
+        margin-left: 10px;
+        line-height: 32px;
+      }
+    }
+    .label-tip {
+      color: red;
+      font-size: 16px;
+      vertical-align: middle;
+      position: relative;
+      top: -1px;
+      right: 3px;
+    }
+  }
+  .showDetail {
+    margin-top: 10px;
+  }
+}
+</style>

+ 266 - 0
ruoyi-ui/src/components/complexPop/index.vue

@@ -0,0 +1,266 @@
+<template>
+  <div class="complexBox">
+    <Input
+      v-model="approves"
+      placeholder="请输入"
+      icon="ios-funnel-outline"
+      @on-click="onIconclick"
+      disabled
+    />
+    <Modal
+      v-model="openControl"
+      :title="title"
+      :mask="true"
+      :mask-closable="false"
+      :width="835"
+      @on-ok="ok"
+      @on-cancel="cancel"
+    >
+      <div class="modalCotent">
+        <mutipleSelectPop
+          ref="dialogtest"
+          :loading="loading"
+          :resultData="resultMessage"
+          :isUse="isUse"
+          :isMutiple="isMutiple"
+          :isCallInterface="isCallInterface"
+          @getResult="getResult"
+          @on-delectli="deleteLi"
+          @delecFun="delecFun"
+          @on-select="Onselect"
+          @on-select-cancel="onSelectCancel"
+          @on-select-all="onSelectAll"
+          @on-select-all-cancel="onSelectAllCancel"
+          @on-selection-change="onSelectChange"
+          @on-row-dblclick="rowdbClick"
+          @on-row-click="rowClick"
+          @on-change="inputchange"
+          @on-keydown="inputkeydown"
+          @on-search="inputsearch"
+          @on-select-change="getSelectedNodes"
+          @on-check-change="getCheckedNodes"
+        ></mutipleSelectPop>
+      </div>
+    </Modal>
+  </div>
+</template>
+<script>
+import mutipleSelectPop from "@/components/MutipleSelectPop";
+export default {
+  name: "complexBox",
+  components: { mutipleSelectPop },
+  props: {
+    title: {
+      type: String,
+      default: ""
+    },
+    defaultValue: {
+      type: String,
+      default: ""
+    },
+    resultData: {
+      type: Object,
+      default: () => {
+        return {}
+      }
+    },
+    isUse: {
+      type: Boolean,
+      default: true
+    },
+    isMutiple: {
+      type: Boolean,
+      default: true
+    },
+    disabled:{
+      type:Boolean,
+      default:false
+    }
+  },
+  data() {
+    return {
+      loading: false,
+      openControl: false,
+      isCallInterface: false,
+      approves: "",
+      resultObj: {
+        total: 0,
+        list: []
+      },
+      result: {
+        //结果备份
+        total: 0,
+        list: []
+      }
+    };
+  },
+  computed: {
+    resultMessage() {
+      // let data = Object.assign(this.resultObj, this.resultData);
+      return this.resultObj;
+    }
+  },
+  methods: {
+    onIconclick() {
+      if(this.disabled){
+        return
+      }
+      this.openControl = true;
+      this.isCallInterface = true;
+      this.resultObj = this.deepCopy(this.result);
+      this.resultObj.total = this.resultObj.list.length;
+    },
+    getResult(data) {
+      //组件的结果
+      this.resultObj = this.deepCopy(data);
+    },
+    ok() {
+      if (this.resultObj.list.length > 0) {
+              this.result.list=[];
+
+          //增加
+          //新增
+          this.resultObj.list.map(item => {
+            if (this.result.list.length > 0) {
+              //修改
+              let flagIndex = this.result.list.findIndex(inner => {
+                return (
+                  item.approve_value === inner.approve_value|| item.ID === Number(inner.approve_value)
+                );
+              });
+              if (flagIndex === -1) {
+                //没有相同的
+                this.result.list.push({
+                  approve_type: item.approve_type,
+                  approve_value: item.approve_value?item.approve_value:item.ID,
+                  approve_value_name: item.string,
+                  string: item.string
+                });
+              }
+            } else {
+              //新增
+              this.result.list.push({
+                approve_type: item.approve_type,
+                approve_value: item.approve_value?item.approve_value:item.ID,
+                approve_value_name: item.string,
+                string: item.string
+              });
+            }
+          });
+        
+      } else {
+        //清空
+        this.result.list = [];
+      }
+      this.result.total = this.result.list.length;
+      this.formatString(this.result);
+      this.$emit("getTotalResult", this.result);
+      this.openControl = false;
+      this.isCallInterface = false;
+    },
+    cancel() {
+      this.resultObj = this.deepCopy(this.result);
+      // this.$emit("getTotalResult", this.arr);
+      this.openControl = false;
+      this.isCallInterface = false;
+    },
+    formatString(data) {
+      //input内容显示处理
+      this.approves = "";
+      if (data.list && data.list.length > 0) {
+        data.list.forEach(item => {
+          this.approves += item.string + ",";
+        });
+        if (this.approves.length > 0) {
+          this.approves = this.approves.substring(0, this.approves.length - 1);
+        } else {
+          this.approves = "";
+        }
+      }
+    },
+    getSelectedNodes(obj, vm) {
+      this.$emit("on-select-tree", obj, vm, this);
+    },
+    getCheckedNodes(obj, vm) {
+      this.$emit("on-change-tree", obj, vm, this);
+    },
+    tabClick(index, vm) {
+      this.index = index;
+      this.$emit("on-click-tab", index, vm, this);
+    },
+    pageChange(index, vm) {
+      this.$emit("on-change-page", index, vm);
+    },
+    pageChangeSize(index, vm) {
+      this.$emit("on-change-pageSize", index, vm, this);
+    },
+    rowdbClick(index, row, vm) {
+      this.$emit("on-row-dblclick", index, row, vm, this);
+    },
+    rowClick(index, row, vm) {
+      this.$emit("on-row-click", index, row, vm, this);
+    },
+    Onselect(selection, row, vm) {
+      this.$emit("on-select", selection, row);
+    },
+    onSelectCancel(selection, row) {
+      this.$emit("on-select-cancel", selection, row);
+    },
+    onSelectAll(selection) {
+      this.$emit("on-select-all", selection);
+    },
+    onSelectAllCancel(selection) {
+      this.$emit("on-select-all-cancel", selection);
+    },
+    onSelectChange(selection) {
+      this.$emit("on-select-change", selection);
+    },
+    inputchange(event, vm) {
+      this.$emit("on-change", event, vm);
+    },
+    inputkeydown(event, vm) {
+      this.$emit("on-keydown", event, vm);
+    },
+    inputsearch(event) {
+      this.$emit("on-search", event);
+    },
+    operationTwo() {
+      let selectNode = this.$refs.Tree.getCheckedNodes();
+      this.$emit("on-transfer-two", selectNode, this);
+    },
+    operation() {
+      this.$emit("on-transfer");
+    },
+    deleteLi(index, tem) {
+      this.$emit("on-delectli", index, tem);
+    },
+    delecFun() {
+      this.$emit("on-deleBtn");
+    },
+    deepCopy(obj) {
+      var result = Array.isArray(obj) ? [] : {};
+      for (var key in obj) {
+        if (obj.hasOwnProperty(key)) {
+          if (typeof obj[key] === "object" && obj[key] !== null) {
+            result[key] = this.deepCopy(obj[key]); //递归复制
+          } else {
+            result[key] = obj[key];
+          }
+        }
+      }
+      return result;
+    }
+  },
+  created() {
+    if (this.resultData && Object.keys(this.resultData).length > 0) {
+      this.resultObj = this.deepCopy(this.resultData);
+      this.result = this.deepCopy(this.resultData);
+      this.formatString(this.resultObj);
+    }
+  }
+};
+</script>
+<style lang="scss">
+.complexBox {
+}
+</style>

+ 264 - 0
ruoyi-ui/src/components/endNodeInfo/index.vue

@@ -0,0 +1,264 @@
+// 结束节点配置界面
+/* eslint-disable vue/no-side-effects-in-computed-properties */
+<template>
+  <div class="InformationBlock">
+    <div class="content">
+      <div  :class="`form_content`">
+        <div  class="form">
+          <p>
+            <span class="label">结束状态名称:</span>
+            <Input type="text" v-model="configData.manualConfig" :disabled="readOnly"  />
+          </p>
+          <p>
+            <span class="label">执行程序URL:</span>
+            <Input type="text" v-model="configData.actionConfig[0].handleValue" :disabled="readOnly"  />
+          </p>
+          <p>
+            <span class="label">抄送人:</span>
+            <complexPop :title="'选择抄送人'" :isUse='false' :isMutiple='true' :disabled="readOnly" :resultData="JSON.parse(configData.actionConfig[1].handleValue)" @getTotalResult="getResult(...arguments)" ></complexPop>
+          </p>
+          <p v-if="(Object.keys(JSON.parse(configData.actionConfig[1].handleValue)).length > 0) && JSON.parse(configData.actionConfig[1].handleValue).list.length > 0">
+            <span class="label">抄送类型:</span>
+            <Select  v-model="configData.actionConfig[1].handleType" :disabled="readOnly" clearable>
+              <Option  :value="41" :key="41">钉钉抄送人</Option>
+              <Option  :value="42" :key="42">微信抄送人</Option>
+            </Select>
+          </p>
+        </div>
+      </div>
+      
+    </div>
+    <p>
+      <Button type="fcdefault" @click="closeDrawer">取消</Button>
+      <Button type="primary" @click="saveConfig" v-if="!readOnly">确定</Button>
+    </p>
+  </div>
+</template>
+<script>
+import ProcessNodeConfig from '@/components/ProcessNodeConfig'
+import complexPop from "@/components/complexPop";
+import {  mapState,mapMutations } from 'vuex';
+export default {
+  name:'endNodeInfo',
+  components:{complexPop},
+  props:{
+    configData:{
+    },
+    TABLE_ID:{},  //主表数据
+    status:null,
+    readOnly:{
+      type:Boolean,
+      default:false
+    }
+  },
+  computed: {
+    defaultData () {
+      // eslint-disable-next-line vue/no-side-effects-in-computed-properties
+      this.infoData = this.configData
+      return this.configData
+    },
+    ...mapState({
+      drawerObject:(state) => {
+        return state.drawerObject
+      }
+    }),
+    currentComponent () {
+      return ProcessNodeConfig
+    }
+  },
+  watch:{
+    defaultData:{
+      handler () {
+        this.infoData = this.defaultData
+      },
+      deep:true
+    }
+  },
+  data () {
+    return {
+      infoData:[],
+      defaultObj:{}
+    }
+  },
+  created () {
+    if(this.configData.actionConfig.length === 0){
+      this.configData.actionConfig = [{						//结束节点绑定的业务动作
+        "id":null,					//执行动作id,新增为空,修改必传
+        "handleValue":null,		//执行的动作,如具体的url
+        "handleType":31,			//31:业务系统接口调用,41:钉钉抄送人,42:微信抄送人
+        "extra_msg":{}		//动作额外的参数,比如接口调用的入参,抄送人:"[{"csPerson":123,"csPersonName":"ABBCCSS"}]
+        }]
+    }
+    this.defaultObj = JSON.parse(JSON.stringify(this.configData))
+  },
+  methods:{
+    ...mapMutations(['drawerObjectChange']),
+    addRule () {  //添加规则
+        let index = 0
+        if(this.infoData.length > 1){
+          index = 1
+        }else{
+          index = 0
+        }
+        this.infoData[index].config.push({
+          name: null,
+          rule: null,
+          threshold: {
+            id:'',
+            label:''
+          }
+        })
+    },
+    delectRule (itemIndex) { //删除规则
+      let index = 0
+      if(this.infoData.length > 1){
+        index = 1
+      }else{
+        index = 0
+      }
+      this.infoData[index].config.splice(itemIndex, 1)
+      this.$set(this.infoData,index,this.infoData[index])
+    },
+    ruleConfigChange (data,itemIndex) {  //数据修改时
+      let index = 0
+      if(this.infoData.length > 1){
+        index = 1
+      }else{
+        index = 0
+      }
+      this.infoData[index].config[itemIndex] = data
+    },
+    getResult(data){
+      this.configData.actionConfig[1].handleValue = JSON.stringify(data)
+    },
+    saveConfig () {  //确定按钮点击
+      this.$emit('closeDrawer')
+    },
+    closeDrawer () {  //取消按钮点击
+      this.$parent.$parent.nodeMsg[Number(this.configData.key)] = this.defaultObj
+      this.$emit('closeDrawer')
+    },
+    nodeRuleConfigChange (configData) {  //中间节点数据修改
+      console.log(configData)
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+
+  
+  .InformationBlock{
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    overflow: hidden;
+
+    >p{
+      text-align: right;
+      margin-top: 16px;
+
+      >button:first-child{
+        margin-right: 10px;
+      }
+    }
+    .content{
+      flex:1;
+      display: flex;
+      flex-direction: column;
+      overflow: auto;
+
+      
+
+      .rule_content{
+        flex: 1;
+        overflow: auto;
+        display: flex;
+        flex-direction: column;
+        .rule{
+          flex: 1;
+          display: flex;
+          flex-direction: column;
+
+          >.title{
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            margin-bottom: 10px;
+
+            span:first-child{
+              font-size:14px;
+              font-family:PingFangSC-Regular;
+              font-weight:400;
+              color:rgba(146,146,146,1);
+              line-height:20px;
+            }
+            span:last-child{
+              font-size:14px;
+              font-family:PingFangSC-Regular;
+              font-weight:400;
+              color:rgba(16,142,233,1);
+              line-height:20px;
+              cursor: pointer;
+            }
+          }
+
+          >.ruleContent{
+            border:1px solid rgba(220,222,226,1);
+            overflow: auto;
+            max-height: 100%;
+
+            >.RuleConfigurationComponent{
+              border-top:1px solid rgba(220,222,226,1);
+              &:first-child{
+                border-top: none;
+              }
+            }
+          }
+        }
+      }
+    }
+
+    .form{
+      background:rgba(255,255,255,1);
+      border:1px solid rgba(220,222,226,1);
+      padding: 16px 40px 16px 0;
+      margin-bottom: 16px;
+
+      >p{
+        display: flex;
+        align-items: center;
+        width: 100%;
+        margin-bottom: 10px;
+
+        &:last-child{
+          margin-bottom: 0;
+        }
+
+        >.label{
+          display: inline-block;
+          width: 100px;
+          text-align: right;
+          margin-right: 8px;
+        }
+
+        >div{
+          flex:1;
+        }
+
+        span.tips{
+          font-size:12px;
+          font-family:PingFangSC-Regular;
+          font-weight:400;
+          color:rgba(146,146,146,1);
+          line-height:16px;
+        }
+
+        &.tips{
+          margin-top: 4px;
+        }
+      }
+    }
+
+    
+  }
+</style>

+ 247 - 0
ruoyi-ui/src/components/linkInfo/index.vue

@@ -0,0 +1,247 @@
+// 连线规则配置界面
+/* eslint-disable vue/no-side-effects-in-computed-properties */
+<template>
+  <div class="InformationBlock">
+    <div  class="content">
+      <div  :class="`rule_content`">
+        <div  class="rule">
+          <p class="title">
+            <span>配置规则</span>
+            <span @click="addRule" v-if="!readOnly">添加规则</span>
+          </p>
+          <div class="ruleContent" v-if="configData.ruleList.length > 0">
+            <RuleConfigurationComponent
+              v-for="(rule,index) in configData.ruleList"
+              v-bind:key="Math.random()"
+              :data="rule"
+              :index="index"
+              :TABLE_ID="TABLE_ID"
+              :readOnly="readOnly"
+            >
+            <span slot="delete" class="deleteIcon" @click.stop="delectRule(index)" v-if="!readOnly">
+              <i class="iconfont iconbj_delete"></i>
+            </span>
+            </RuleConfigurationComponent>
+          </div>
+        </div>
+      </div>
+      
+    </div>
+    <p>
+      <Button type="fcdefault" @click="closeDrawer">取消</Button>
+      <Button type="primary" @click="saveConfig" v-if="!readOnly">确定</Button>
+    </p>
+  </div>
+</template>
+<script>
+import ProcessNodeConfig from '@/components/ProcessNodeConfig'
+import RuleConfigurationComponent from '@/components/RuleConfigurationComponent'
+export default {
+  name:'linkInfo',
+  components:{RuleConfigurationComponent},
+  props:{
+    configData:{
+    },
+    TABLE_ID:{},  //主表数据
+    status:null,
+    readOnly:{
+      type:Boolean,
+      default:false
+    }
+  },
+  computed: {
+    defaultData () {
+      // eslint-disable-next-line vue/no-side-effects-in-computed-properties
+      return this.configData
+    },
+    currentComponent () {
+      return ProcessNodeConfig
+    }
+  },
+  data () {
+    return {
+      defaultObj:{}
+    }
+  },
+  created () {
+    
+    this.defaultObj = JSON.parse(JSON.stringify(this.configData))
+  },
+  methods:{
+    addRule () {  //添加规则
+        this.configData.ruleList.push({
+          name: null,
+          rule: null,
+          ruleType: 0,
+          threshold: {
+            id:'',
+            label:''
+          }
+        })
+    },
+    delectRule (itemIndex) { //删除规则
+      this.configData.ruleList.splice(itemIndex, 1)
+    },
+    saveConfig () {  //确定按钮点击
+      // 存在配置规则,校验各项是否必填
+        let errorFlag = false //判断标志
+        if(this.configData.ruleList && this.configData.ruleList.length > 0){
+          this.configData.ruleList.map(item => {
+            if(item.ruleType === 0 && (!item.fTableInfo || !item.rule || !item.threshold.id)){  //直接选择
+              this.$Modal.fcError({
+                title:'错误',
+                content:'请完善规则配置'
+              })
+              errorFlag = true
+              return
+            }
+
+            if(item.ruleType === 1 && !item.businessExpansion){
+              this.$Modal.fcError({
+                title:'错误',
+                content:'请完善规则配置'
+              })
+
+              errorFlag = true
+              return
+            }
+          })
+        }
+
+        if(!errorFlag){
+          this.$emit('closeDrawer')
+        }
+    },
+    closeDrawer () {  //取消按钮点击
+      this.$parent.$parent.pathMsg[Number(this.configData.key)] = this.defaultObj
+      this.$emit('closeDrawer')
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+
+  
+  .InformationBlock{
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    overflow: hidden;
+
+    >p{
+      text-align: right;
+      margin-top: 16px;
+
+      >button:first-child{
+        margin-right: 10px;
+      }
+    }
+    .content{
+      flex:1;
+      display: flex;
+      flex-direction: column;
+      overflow: auto;
+
+      
+
+      .rule_content{
+        flex: 1;
+        overflow: auto;
+        display: flex;
+        flex-direction: column;
+        .rule{
+          flex: 1;
+          display: flex;
+          flex-direction: column;
+
+          >.title{
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            margin-bottom: 10px;
+
+            span:first-child{
+              font-size:14px;
+              font-family:PingFangSC-Regular;
+              font-weight:400;
+              color:rgba(146,146,146,1);
+              line-height:20px;
+            }
+            span:last-child{
+              font-size:14px;
+              font-family:PingFangSC-Regular;
+              font-weight:400;
+              color:rgba(16,142,233,1);
+              line-height:20px;
+              cursor: pointer;
+            }
+          }
+
+          >.form{
+            height:64px;
+            background:rgba(255,255,255,1);
+            border:1px solid rgba(220,222,226,1);
+            border-bottom: 0;
+            margin-bottom: 0;
+          }
+
+          >.ruleContent{
+            border:1px solid rgba(220,222,226,1);
+            overflow: auto;
+            max-height: 100%;
+
+            >.RuleConfigurationComponent{
+              border-top:1px solid rgba(220,222,226,1);
+              &:first-child{
+                border-top: none;
+              }
+            }
+          }
+        }
+      }
+    }
+
+    .form{
+      background:rgba(255,255,255,1);
+      border:1px solid rgba(220,222,226,1);
+      padding: 16px 40px 16px 0;
+      margin-bottom: 16px;
+
+      >p{
+        display: flex;
+        align-items: center;
+        width: 100%;
+        margin-bottom: 10px;
+
+        &:last-child{
+          margin-bottom: 0;
+        }
+
+        >.label{
+          display: inline-block;
+          width: 100px;
+          text-align: right;
+          margin-right: 8px;
+        }
+
+        >div{
+          flex:1;
+        }
+
+        span.tips{
+          font-size:12px;
+          font-family:PingFangSC-Regular;
+          font-weight:400;
+          color:rgba(146,146,146,1);
+          line-height:16px;
+        }
+
+        &.tips{
+          margin-top: 4px;
+        }
+      }
+    }
+
+    
+  }
+</style>

+ 699 - 0
ruoyi-ui/src/components/startNodeInfo/index.vue

@@ -0,0 +1,699 @@
+// 开始节点配置界面
+/* eslint-disable vue/no-side-effects-in-computed-properties */
+<template>
+  <div class="InformationBlock">
+    <div  class="content">
+      <div :class="`form_content rule_content`">
+        <div  class="form">
+          <p >
+            <span class="label">优先级:</span>
+            <Input type="text" :disabled="readOnly" v-model="configData.priority" :regx="/^[0-9]*$/"   />
+          </p>
+          <p v-if="moduleType === 1">
+            <span class="label"><i class="requireStyle">*</i>单据类型:</span>
+            <DropDownSelectFilter
+              :disabled="readOnly"
+              v-bind="tableConfig.props"
+              v-on="tableConfig.event"
+            >
+            </DropDownSelectFilter>
+          </p>
+          <p v-if="moduleType === 1">
+            <span class="label">查询索引:</span>
+            <DropDownSelectFilter
+              :disabled="readOnly"
+              v-bind="indexQuery.props"
+              v-on="indexQuery.event"
+            >
+            </DropDownSelectFilter>
+          </p>
+          <p v-if="moduleType === 1">
+            <span class="label">触发按钮:</span>
+            <Select v-model="configData.triggerBt" :disabled="readOnly" multiple @on-change="triggerBtChange">
+              <Option v-for="(item,index) in triggerButtons" :key="index" :value="item.ID">{{item.Label}}</Option>
+            </Select>
+          </p>
+          <p v-if="moduleType === 1">
+            <span class="label">可见按钮:</span>
+            <Select v-model="configData.visibleBt" :disabled="readOnly" multiple @on-change="visibleBtChange">
+              <Option v-for="(item,index) in visibleButtons" :key="index" :value="item.ID">{{item.Label}}</Option>
+            </Select>
+          </p>
+          
+        </div>
+        <div  class="rule">
+          <p class="title">
+            <span>配置规则</span>
+            <span @click="addRule" v-if="!readOnly">添加规则</span>
+          </p>
+          <div class="form" v-if="configData.ruleList.length >= 2">
+            <p >
+              <span class="label">规则并行条件:</span>
+              <Select v-model="configData.conditionType" >
+                <Option :value="0" :key="0">且</Option>
+                <Option :value="1" :key="1">或</Option>
+              </Select>
+            </p>
+          </div>
+          <div class="ruleContent" v-if="configData.ruleList.length > 0">
+            <RuleConfigurationComponent
+              v-for="(rule,index) in configData.ruleList"
+              v-bind:key="Math.random()"
+              :data="rule"
+              :index="index"
+              :TABLE_ID="[{ID:configData.businessType,Label:configData.businessTypeName}]"
+              :readOnly="readOnly"
+            >
+            <span slot="delete" class="deleteIcon" @click.stop="delectRule(index)" v-if="!readOnly">
+              <i class="iconfont iconbj_delete"></i>
+            </span>
+            </RuleConfigurationComponent>
+          </div>
+        </div>
+      </div>
+      
+    </div>
+    <p>
+      <Button type="fcdefault" @click="closeDrawer">取消</Button>
+      <Button type="primary" @click="saveConfig" v-if="!readOnly">确定</Button>
+    </p>
+  </div>
+</template>
+<script>
+import ProcessNodeConfig from '@/components/ProcessNodeConfig'
+import RuleConfigurationComponent from '@/components/RuleConfigurationComponent'
+export default {
+  name:'startNodeInfo',
+  components:{RuleConfigurationComponent},
+  props:{
+    configData:{
+    },
+    TABLE_ID:{},  //主表数据
+    status:null,
+    readOnly:{
+      type:Boolean,
+      default:false
+    },
+    moduleType:{
+      type: Number,
+      default: 0
+    }
+  },
+  computed: {
+    defaultData () {
+      // eslint-disable-next-line vue/no-side-effects-in-computed-properties
+      this.infoData = this.configData
+      return this.configData
+    },
+    currentComponent () {
+      return ProcessNodeConfig
+    }
+  },
+  watch:{
+    defaultData:{
+      handler () {
+        this.infoData = this.defaultData
+      },
+      deep:true
+    }
+  },
+  data () {
+    return {
+      infoData:[],
+      defaultObj:{},
+
+      
+      triggerButtons:[],// 触发按钮
+      visibleButtons:[], // 可见按钮
+
+      //节点表的配置
+      tableConfig:{
+        props:{
+          columnsKey: ['NAME'],
+          AutoData: [],
+          hidecolumns: ['id'],
+          data: {},
+          totalRowCount: 0,
+          defaultSelected: [],
+          isBackRowItem: true
+        },
+        event:{
+          'on-input-value-change': (value) => {
+              // 外键的模糊搜索
+              this.tableConfig.props.AutoData = []
+              this.$network.post('/p/c/meta/table/list',{DESCRIPTION:value}).then(res => {
+                if(res.data.code === 0){
+                  // this.row = res.data.data.row.concat([])
+                  this.tableConfig.props.AutoData = res.data.data.row.reduce((arr,item) => {
+                    arr.push({
+                      value:item.NAME.val,
+                      id:item.ID.val,
+                      NAME:item.DESCRIPTION.val
+                    })
+                    return arr
+                  },[]);
+                }
+                
+              })
+          },
+          'on-popper-show': ($this) => {
+            // 当外键下拉站开始去请求数据
+            // this.freshDropDownSelectFilterData($this)
+            this.$network.post('/p/c/meta/table/list',{
+              pageSize:$this.pageSize,
+              page:1
+            }).then(res => {
+              if(res.data.code === 0){
+                res.data.data.tabth.forEach(item => {
+                  if(item.colname === 'DESCRIPTION'){
+                    item.isak = true
+                  }
+                  return item
+                })
+                this.tableConfig.props.data = res.data.data;
+                this.tableConfig.props.totalRowCount = res.data.data.totalRowCount;
+              }
+              
+            })
+          },
+          'on-page-change': (currentPage, $this) => {
+            // 外键的分页查询
+            // this.freshDropDownSelectFilterData($this,currentPage)
+            this.$network.post('/p/c/meta/table/list',{
+              pageSize:$this.pageSize,
+              page:currentPage
+            }).then(res => {
+              if(res.data.code === 0){
+                res.data.data.tabth.forEach(item => {
+                  if(item.colname === 'DESCRIPTION'){
+                    item.isak = true
+                  }
+                  return item
+                })
+                this.tableConfig.props.data = res.data.data;
+                this.tableConfig.props.totalRowCount = res.data.data.totalRowCount;
+              }
+              
+            })
+          },
+          'on-blur':(event,instance) => {
+            // if(Object.prototype.toString.call(this.data.businessType) !== '[object Array]' || this.data.businessType.length === 0){
+            //   instance.inputValue = ''
+
+            //   /* 
+            //     todo
+            //     清空所有和主表有关的数据
+            //   */
+
+            // }
+          },
+          'on-fkrp-selected': (value) => {
+            if(value.length > 0){
+              this.configData.businessTypeName = value[0].rowItem.NAME.val?value[0].rowItem.NAME.val:value[0].rowItem.NAME
+              this.configData.businessType= value[0].ID
+              this.configData.businessTypeText = value[0].Label
+              this.getTriggerButtons()
+              this.getVisibleButtons()
+            }else{
+              this.configData.businessTypeName = null
+              this.configData.businessType = null
+              this.configData.businessTypeText = null
+            }
+
+            
+
+            // 清除可显示字段数据
+            // this.onClear()
+            this.configData.visibleBt = []
+            this.configData.triggerBt = []
+            this.configData.businessKeyId = null
+            this.configData.businessKey = null
+            this.configData.businessKeyName = null
+            this.indexQuery.defaultSelected = []
+          },
+          'on-clear': () => {
+            // 清除可显示字段数据
+            // this.onClear()
+            this.configData.visibleBt = []
+            this.configData.triggerBt = []
+            this.configData.businessKeyId = null
+            this.configData.businessKey = null
+            this.configData.businessKeyName = null
+            this.indexQuery.defaultSelected = []
+
+
+            this.configData.businessTypeName = null
+            this.configData.businessType = null
+            this.configData.businessTypeText = null
+            this.tableConfig.props.AutoData = []
+              this.$network.post('/p/c/meta/table/list',{DESCRIPTION:''}).then(res => {
+                if(res.data.code === 0){
+                  this.tableConfig.props.AutoData = res.data.data.row.reduce((arr,item) => {
+                    arr.push({
+                      value:item.NAME.val,
+                      id:item.ID.val,
+                      NAME:item.DESCRIPTION.val
+                    })
+                    return arr
+                  },[]);
+                }
+              })
+          }
+        }
+      },
+
+      // 查询索引
+      indexQuery:{
+        props:{
+          columnsKey: ['NAME'],
+          AutoData: [],
+          hidecolumns: ['id'],
+          data: {},
+          totalRowCount: 0,
+          defaultSelected: [],
+          isBackRowItem: true
+        },
+        event:{
+          'on-input-value-change': (value,instance) => {
+              if(!this.configData.businessType){
+                this.$Modal.fcWarning({
+                  title:'警告',
+                  content:'请先选择节点表!'
+                })
+                this.configData.businessKeyId = null
+                this.configData.businessKey = null
+                this.configData.businessKeyName = null
+                instance.inputValue = ''
+                return
+              }
+              // 外键的模糊搜索
+              this.indexQuery.props.AutoData = []
+              this.$network.post('/p/c/meta/column/list',{DESCRIPTION:value,AD_TABLE_ID:this.configData.businessType}).then(res => {
+                if(res.data.code === 0){
+                  // this.row = res.data.data.row.concat([])
+                  this.indexQuery.props.AutoData = res.data.data.row.reduce((arr,item) => {
+                    arr.push({
+                      value:item.NAME.val,
+                      id:item.ID.val,
+                      NAME:item.DESCRIPTION.val
+                    })
+                    return arr
+                  },[]);
+                }
+                
+              })
+          },
+          'on-popper-show': ($this) => {
+            if(!this.configData.businessType){
+              this.$Modal.fcWarning({
+                title:'警告',
+                content:'请先选择节点表!'
+              })
+              this.configData.businessKeyId = null
+              this.configData.businessKey = null
+              this.configData.businessKeyName = null
+              $this.inputValue = ''
+              return
+            }
+            // 当外键下拉站开始去请求数据
+            // this.freshDropDownSelectFilterData($this)
+            this.$network.post('/p/c/meta/column/list',{
+              pageSize:$this.pageSize,
+              page:1,
+              AD_TABLE_ID:this.configData.businessType
+            }).then(res => {
+              if(res.data.code === 0){
+                res.data.data.tabth.forEach(item => {
+                  if(item.colname === 'DESCRIPTION'){
+                    item.isak = true
+                  }
+                  return item
+                })
+                this.indexQuery.props.data = res.data.data;
+                this.indexQuery.props.totalRowCount = res.data.data.totalRowCount;
+              }
+              
+            })
+          },
+          'on-page-change': (currentPage, $this) => {
+            // 外键的分页查询
+            // this.freshDropDownSelectFilterData($this,currentPage)
+            this.$network.post('/p/c/meta/column/list',{
+              pageSize:$this.pageSize,
+              page:1,
+              AD_TABLE_ID:this.configData.businessType
+            }).then(res => {
+              if(res.data.code === 0){
+                res.data.data.tabth.forEach(item => {
+                  if(item.colname === 'DESCRIPTION'){
+                    item.isak = true
+                  }
+                  return item
+                })
+                this.indexQuery.props.data = res.data.data;
+                this.indexQuery.props.totalRowCount = res.data.data.totalRowCount;
+              }
+            })
+          },
+          'on-blur':(event,instance) => {
+            // if(Object.prototype.toString.call(this.data.businessType) !== '[object Array]' || this.data.businessType.length === 0){
+            //   instance.inputValue = ''
+
+            //   /* 
+            //     todo
+            //     清空所有和主表有关的数据
+            //   */
+
+            // }
+          },
+          'on-fkrp-selected': (value) => {
+            this.configData.businessKey = value[0].rowItem.NAME.val?value[0].rowItem.NAME.val:value[0].rowItem.NAME
+            this.configData.businessKeyId= value[0].ID
+            this.configData.businessKeyName = value[0].Label
+          },
+          'on-clear': () => {
+            // 清除可显示字段数据
+            // this.onClear()
+
+            this.configData.businessKey = null
+            this.configData.businessKeyId= null
+            this.configData.businessKeyName = null
+            this.indexQuery.props.AutoData = []
+            this.$network.post('/p/c/meta/column/list',{DESCRIPTION:''}).then(res => {
+              if(res.data.code === 0){
+                this.indexQuery.props.AutoData = res.data.data.row.reduce((arr,item) => {
+                  arr.push({
+                    value:item.NAME.val,
+                    id:item.ID.val,
+                    NAME:item.DESCRIPTION.val
+                  })
+                  return arr
+                },[]);
+              }
+            })
+          }
+        }
+      },
+    }
+  },
+  created () {
+    this.defaultObj = JSON.parse(JSON.stringify(this.configData))
+
+    if(this.TABLE_ID){  //如果为固定模版
+      this.configData.businessType = this.TABLE_ID[0].ID
+      this.configData.businessTypeName = this.TABLE_ID[0].Label
+    }
+
+    if(this.configData.businessType){
+      this.tableConfig.props.defaultSelected= [
+        {
+          ID: this.configData.businessType,
+          Label: this.configData.businessTypeName
+        }
+      ]
+      this.getTriggerButtons()
+      this.getVisibleButtons()
+    }
+
+    if(this.configData.businessKeyId){
+      this.indexQuery.props.defaultSelected= [
+        {
+          ID: this.configData.businessKeyId,
+          Label: this.configData.businessKey
+        }
+      ]
+    }
+  },
+  methods:{
+    addRule () {  //添加规则
+        this.configData.ruleList.push({
+          name: null,
+          rule: null,
+          ruleType: 0,
+          threshold: {
+            id:'',
+            label:''
+          }
+        })
+    },
+    delectRule (itemIndex) { //删除规则
+      console.log(itemIndex)
+      this.configData.ruleList.splice(itemIndex, 1)
+      this.configData.ruleList.concat([])
+      this.$set(this.configData.ruleList,this.configData.ruleList)
+    },
+    async saveConfig () {  //确定按钮点击
+      await this.inputChange().then(() => {  //判断完优先级
+        // 存在配置规则,校验各项是否必填
+        let errorFlag = false //判断标志
+
+        // 判断单据类型是否必填
+        if(!this.configData.businessType){
+          this.$Modal.fcError({
+            title:'错误',
+            content:'单据类型不能为空!',
+            mask: true
+          })
+          errorFlag = true
+          return
+        }
+
+        if(this.configData.ruleList && this.configData.ruleList.length > 0){
+          this.configData.ruleList.map(item => {
+            if(item.ruleType === 0 && (!item.fTableInfo || !item.rule || !item.threshold.id)){  //直接选择
+              this.$Modal.fcError({
+                title:'错误',
+                content:'请完善规则配置',
+                mask: true
+              })
+              errorFlag = true
+              return
+            }
+
+            if(item.ruleType === 1 && !item.businessExpansion){
+              this.$Modal.fcError({
+                title:'错误',
+                content:'请完善规则配置',
+                mask: true
+              })
+
+              errorFlag = true
+              return
+            }
+          })
+        }
+
+        if(!errorFlag){
+          this.$emit('closeDrawer')
+        }
+        
+      })
+    },
+    closeDrawer () {  //取消按钮点击
+      this.$parent.$parent.nodeMsg[Number(this.configData.key)] = this.defaultObj
+      this.$emit('closeDrawer')
+    },
+    async inputChange () {  //优先级失去焦点判断
+      return new Promise((resolve) => {
+        this.$network.post('/p/cs/node/priority',{
+          defaultPriority:this.configData.priority,
+          BUSINESS_TYPE:this.configData.businessType,
+          id:this.configData.id
+        }).then(res => {
+          if(res.data.resultCode === -1){
+            this.$Modal.fcError({
+              title:'错误',
+              content:res.data.resultMsg,
+              mask:true
+            })
+          }
+
+          if(res.data.resultCode === 0){
+            resolve(res)
+          }
+
+          
+        })
+      })
+    },
+    
+    getTriggerButtons () {  //获取触发按钮
+      this.$network.post('/p/cs/node/define/bt',{
+        id: this.configData.businessType,
+        vueDispaly: 1
+      })
+      .then(res => {
+        if(res.data.resultCode === 0){
+          this.triggerButtons = res.data.data.difineData
+        }else{
+          this.triggerButtons = []
+        }
+      })
+    },
+    triggerBtChange (value) {  //触发按钮选择
+      if(value[0] === 'bSelect-all'){
+        this.configData.triggerBt = this.triggerButtons.reduce((arr,current) => {
+          arr.push(current.ID)
+          return arr
+        },[])
+      }
+    },
+    getVisibleButtons () { //获取可见按钮
+      this.$network.post('/p/cs/node/define/bt',{
+        id: this.configData.businessType,
+        vueDispaly: 0
+      })
+      .then(res => {
+        if(res.data.resultCode === 0){
+          this.visibleButtons = res.data.data.difineData
+        }else{
+          this.visibleButtons = []
+        }
+      })
+    },
+    visibleBtChange (value) {  //可见按钮选择
+      if(value[0] === 'bSelect-all'){
+        this.configData.visibleBt = this.visibleButtons.reduce((arr,current) => {
+          arr.push(current.ID)
+          return arr
+        },[])
+      }
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+
+  
+  .InformationBlock{
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    overflow: hidden;
+
+    >p{
+      text-align: right;
+      margin-top: 16px;
+
+      >button:first-child{
+        margin-right: 10px;
+      }
+    }
+    .content{
+      flex:1;
+      display: flex;
+      flex-direction: column;
+      overflow: auto;
+
+      
+
+      .rule_content{
+        flex: 1;
+        overflow: auto;
+        display: flex;
+        flex-direction: column;
+        .rule{
+          flex: 1;
+          display: flex;
+          flex-direction: column;
+
+          >.title{
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            margin-bottom: 10px;
+
+            span:first-child{
+              font-size:14px;
+              font-family:PingFangSC-Regular;
+              font-weight:400;
+              color:rgba(146,146,146,1);
+              line-height:20px;
+            }
+            span:last-child{
+              font-size:14px;
+              font-family:PingFangSC-Regular;
+              font-weight:400;
+              color:rgba(16,142,233,1);
+              line-height:20px;
+              cursor: pointer;
+            }
+          }
+
+          >.form{
+            height:64px;
+            background:rgba(255,255,255,1);
+            border:1px solid rgba(220,222,226,1);
+            border-bottom: 0;
+            margin-bottom: 0;
+          }
+
+          >.ruleContent{
+            border:1px solid rgba(220,222,226,1);
+            overflow: auto;
+            max-height: 100%;
+
+            >.RuleConfigurationComponent{
+              border-top:1px solid rgba(220,222,226,1);
+              &:first-child{
+                border-top: none;
+              }
+            }
+          }
+        }
+      }
+    }
+
+    .form{
+      background:rgba(255,255,255,1);
+      border:1px solid rgba(220,222,226,1);
+      padding: 16px 40px 16px 0;
+      margin-bottom: 16px;
+
+      >p{
+        display: flex;
+        align-items: center;
+        width: 100%;
+        margin-bottom: 10px;
+
+        &:last-child{
+          margin-bottom: 0;
+        }
+
+        >.label{
+          display: inline-block;
+          width: 100px;
+          text-align: right;
+          margin-right: 8px;
+
+          .requireStyle {
+            font-size: 14px;
+            vertical-align: middle;
+            color: red;
+            padding-top: 5px;
+            display: inline-block;
+          }
+        }
+
+        >div{
+          flex:1;
+          overflow: hidden;
+        }
+
+        span.tips{
+          font-size:12px;
+          font-family:PingFangSC-Regular;
+          font-weight:400;
+          color:rgba(146,146,146,1);
+          line-height:16px;
+        }
+
+        &.tips{
+          margin-top: 4px;
+        }
+      }
+    }
+
+    
+  }
+</style>

+ 4 - 2
ruoyi-ui/src/main.js

@@ -23,8 +23,10 @@ import Pagination from "@/components/Pagination";
 import RightToolbar from "@/components/RightToolbar"
 import DynamicForm from "@/components/DynamicForm"
 import DynamicForms from "@/components/DynamicForms"
-import MemoranDum from "@/components/MemoranDum"
-
+import MemoranDum from "@/components/MemoranDum"
+import 'burgeon-ui/dist/styles/burgeon-ui.css';
+import BurgeonUi from 'burgeon-ui';
+Vue.use(BurgeonUi);
 // 全局方法挂载
 Vue.prototype.getDicts = getDicts
 Vue.prototype.getConfigKey = getConfigKey

+ 576 - 0
ruoyi-ui/src/views/activiti/TemplateManagementNew/index.vue

@@ -0,0 +1,576 @@
+<template>
+  <div class="TemplateManagementNew">
+    <Breadcrumb separator=">" class="breadcrumb">
+        <BreadcrumbItem to="/TemplateManagementLists">模版管理</BreadcrumbItem>
+        <BreadcrumbItem>{{$route.params.id != '-1'?'编辑模版':'新建模版'}}</BreadcrumbItem>
+
+    </Breadcrumb>
+
+
+    <!-- 预览状态 -->
+    <div class="content" v-if="this.readOnly">
+      <div class="tips" v-if="currentSteps === 2">
+        <p>
+          <span>单据类型:</span><span>{{data.businessTypeText}}</span>
+        </p>
+        <p>
+          <span>模版名称:</span><span>{{data.name}}</span>
+        </p>
+        <p>
+          <span>查询索引:</span><span>{{data.businessKey}}</span>
+        </p>
+        <p>
+          <span>模版描述:</span><span>{{data.description}}</span>
+        </p>
+        <p>
+          <span>自动处理:</span><span>{{data.autoClose?'开':'关'}}</span>
+        </p>
+        <p>
+          <span>业务数据检查:</span><span>{{data.businessCheckUrl}}</span>
+        </p>
+      </div>
+      <FlowChartComponent
+        v-if="currentSteps === 2"
+        :data="data"
+        :currentSteps="2"
+        :readOnly="readOnly"
+        ref="component_2"
+      >
+      </FlowChartComponent>
+      <p class="buttonGroups" v-if="currentSteps === 2">
+        <Button type="primary" @click="close">关闭</Button>
+      </p>
+    </div>
+
+    <!-- 编辑状态 -->
+    <Steps :current="currentSteps" class="steps" v-if="!this.readOnly">
+        <Step title="参数配置" ></Step>
+        <Step title="流程设计器" ></Step>
+        <Step title="保存发布模版" ></Step>
+    </Steps>
+
+    <div class="content" v-if="!this.readOnly">
+      <keep-alive exclude="component_2" >
+        <component
+          :is="currentComponent"
+          :ref="currentComponent"
+          class="block"
+          :editable="currentSteps === 1?true:false"
+          :data="data"
+          :currentSteps="currentSteps"
+          :noFreshFlag="noFreshFlag"
+          @dataChange=dataChange
+          >
+        </component>
+      </keep-alive>
+      <p class="buttonGroups">
+        <Button type="primary" v-if="currentSteps > 0" @click="previousSteps">上一步</Button>
+        <Button type="primary" v-if="currentSteps < 2" @click="nextSteps">下一步</Button>
+        <Button type="primary" v-if="(currentSteps === 2 && this.data.status !== 1)" @click="confirm(false)">保存</Button>
+        <Button type="primary" v-if="(currentSteps === 2 && this.data.status !== 1)" @click="confirmAndPublish()">保存并发布</Button>
+      </p>
+    </div>
+  </div>
+</template>
+<script>
+// import '../__utils__/go'
+import Vue from 'vue'
+import ParameterConfiguration from '@/components/ParameterConfiguration'
+import FlowChartComponent from '@/components/FlowChartComponent'
+import FlowSuccess from '@/components/FlowSuccess'
+import {  mapMutations } from 'vuex';
+import { setTimeout } from 'timers';
+export default {
+  name:'TemplateManagementNew',
+  components:{ParameterConfiguration,FlowChartComponent,FlowSuccess},
+  data () {
+    return {
+      currentSteps:0,
+      currentComponent:null,
+      imgBase:'',
+      defaultData:{
+        guiStyle:JSON.stringify({
+          "class": "NewGraphLinksModel",
+          "linkFromPortIdProperty": "fromPort",
+          "linkToPortIdProperty": "toPort",
+          "nodeDataArray": [
+            {"key":-1, "category":"Start", "loc":"175 0", "text":"开始", "type": 1},
+            {"key":0, "loc":"175 100", "text":"审批节点","type": 0, "category": 'Approval'},
+            {"key":-2, "category":"End", "loc":"175 200", "text":"结束", "type": 2}
+          ],
+          "linkDataArray": [
+            {"from":-1, "to":0, "fromPort":"B", "toPort":"T","key":0},
+            {"from":0, "to":-2, "fromPort":"B", "toPort":"T","key":1}
+          ]
+        }),
+        nodeMsg:[
+          {"key":-1, "category":"Start", "loc":"175 0", "text":"开始", "name":"开始", "type": 1,"ruleList":[]},
+          {"key":0, "loc":"175 100", "text":"审批节点",  "name":"审批节点", "category": 'Approval',"type": 0,"ruleList":[],"actServiceS":[],"actionConfig":[],"approvelList":[],"approverStyle":0},
+          {"key":-2, "category":"End", "loc":"175 200", "text":"结束",  "name":"结束", "type": 2,"actionConfig":[{
+              handleValue:null,
+              extra_msg:{},
+              handleType:31
+            },
+            {
+              handleValue:'{}',
+              extra_msg:{},
+              handleType:41
+            }]}
+        ],
+        pathMsg:[
+          {"from":-1, "to":0, "fromPort":"B", "toPort":"T","ruleList":[],"key":0},
+          {"from":0, "to":-2, "fromPort":"B", "toPort":"T","ruleList":[],"key":1}
+        ],
+        removeNode:[],
+        removePath:[],
+      },
+      data:{
+        guiStyle:JSON.stringify({
+          "class": "NewGraphLinksModel",
+          "linkFromPortIdProperty": "fromPort",
+          "linkToPortIdProperty": "toPort",
+          "nodeDataArray": [
+            {"key":-1, "category":"Start", "loc":"175 0", "text":"开始", "type": 1},
+            {"key":0, "loc":"175 100", "text":"审批节点","type": 0, "category": 'Approval'},
+            {"key":-2, "category":"End", "loc":"175 200", "text":"结束", "type": 2}
+          ],
+          "linkDataArray": [
+            {"from":-1, "to":0, "fromPort":"B", "toPort":"T","key":0},
+            {"from":0, "to":-2, "fromPort":"B", "toPort":"T","key":1}
+          ]
+        }),
+        nodeMsg:[
+          {"key":-1, "category":"Start", "loc":"175 0", "text":"开始", "name":"开始", "type": 1,"ruleList":[]},
+          {"key":0, "loc":"175 100", "text":"审批节点",  "name":"审批节点", "category": 'Approval',"type": 0,"ruleList":[],"actServiceS":[],"actionConfig":[],"approvelList":[],"approverStyle":0},
+          {"key":-2, "category":"End", "loc":"175 200", "text":"结束",  "name":"结束", "type": 2,"actionConfig":[{
+              handleValue:null,
+              extra_msg:{},
+              handleType:31
+            },
+            {
+              handleValue:'{}',
+              extra_msg:{},
+              handleType:41
+            }]}
+        ],
+        pathMsg:[
+          {"from":-1, "to":0, "fromPort":"B", "toPort":"T","ruleList":[],"key":0},
+          {"from":0, "to":-2, "fromPort":"B", "toPort":"T","ruleList":[],"key":1}
+        ],
+        removeNode:[],
+        removePath:[],
+        autoClose: true,
+        moduleType: 0
+      },
+      noFreshFlag:false,
+
+      readOnly:false,  //是否只读为预览模式
+      //存放三步骤的数据
+
+
+      defaultModuleType: null,  //暂存模版类型
+
+    }
+  },
+  watch:{
+    currentSteps (val) {
+      if(this.readOnly){
+        return
+      }
+      let componentName = `component_${val}`
+      if(Vue.component(componentName) === undefined){
+        if(val === 0 ){
+          Vue.component(componentName,ParameterConfiguration)
+        }else if(val === 1){
+
+          Vue.component(componentName,FlowChartComponent)
+        }else if(val === 2){
+          Vue.component(componentName,FlowSuccess)
+        }
+      }
+
+      this.currentComponent = componentName
+
+
+    }
+  },
+  methods:{
+    ...mapMutations(['currentChange']),
+    getModuleInfo (id) {
+      this.$network.post('/p/cs/module/load', {id:id}).then((res) => {
+        if(res.data.resultCode === 0){
+          res.data.data.businessType = [{
+            ID:res.data.data.businessType,
+            Label:res.data.data.businessTypeName,
+            val:res.data.data.businessTypeText
+          }]
+
+          res.data.data.businessNumber = [{
+            ID:String(res.data.data.businessKeyId),
+            Label:res.data.data.businessKey,
+            val:res.data.data.businessKeyName
+          }]
+          this.data = res.data.data
+          this.data.guiStyle = JSON.parse(res.data.data.guiStyle)
+          this.data.moduleId = res.data.data.id
+
+          this.$nextTick(() => {
+            if(this.readOnly){
+              this.currentSteps = 2
+              this.noFreshFlag = false
+            }else{
+              this.$refs.component_1.init()
+              this.noFreshFlag = false
+            }
+
+          })
+        }
+      });
+    },
+    async nextSteps () {  //下一步
+      if(await this.checkModuleName()){
+        return false
+      }
+
+      if(this.currentSteps === 0 && (this.defaultModuleType != this.data.moduleType) && this.defaultModuleType !== null){
+        this.$Modal.fcWarning({
+          title:'警告',
+          content:'您已修改模板类型/单据类型,这将导致下一步的流程设计器内所有设置恢复初始化,是否确定更改?',
+          showCancel: true,
+          mask: true,
+          onOk: () => {
+            this.defaultModuleType = this.data.moduleType
+            this.data = Object.assign(this.data,JSON.parse(JSON.stringify(this.defaultData)))
+            if(this.data.businessType && this.data.businessType.length > 0 && this.data.name){
+              this.defaultModuleType = this.data.moduleType
+              ++this.currentSteps
+            }else{
+              this.$Modal.fcWarning({
+                title:'警告',
+                content:'请填写必填项!',
+                mask:true
+              })
+            }
+          },
+          onCancel: () => {
+          }
+        })
+        return
+      }
+
+
+      if( this.data.name && (this.data.moduleType === 0?(this.data.businessType && this.data.businessType.length > 0):true) ){
+        this.defaultModuleType = this.data.moduleType
+        ++this.currentSteps
+      }else{
+        this.$Modal.fcWarning({
+          title:'警告',
+          content:'请填写必填项!',
+          mask:true
+        })
+      }
+
+
+
+    },
+    async checkModuleName () {
+      await new Promise((resolve, reject) => {
+        let jsonObject = {
+          ID:this.data.moduleId,
+          NAME:this.data.name
+        }
+        this.$network.post('/p/cs/module/duplicate',jsonObject).then(res => {
+            if(res.data.resultCode !== 0){
+              this.$Modal.fcWarning({
+                title:'警告',
+                content:res.data.resultMsg,
+                mask:true
+              })
+              reject()
+            }
+
+            resolve(res)
+        })
+      })
+    },
+    previousSteps () {  //上一步
+      --this.currentSteps
+    },
+    async confirm (flag) {  //确定
+
+      return await new Promise((resolve,reject) => {
+
+        var svg = this.data.myDisplay.makeImage({
+                                          scale: 2
+                                        });
+        this.imgBase = svg.getAttribute('src')
+
+        let nodeMsg = []
+        Object.keys(this.data.nodeMsg).map(item => {
+          nodeMsg.push(this.data.nodeMsg[item])
+          return item
+        })
+
+        let pathMsg = []
+        Object.keys(this.data.pathMsg).map(item => {
+          pathMsg.push(this.data.pathMsg[item])
+          return item
+        })
+        let jsonObject = {
+          id:this.data.moduleId,
+          name:this.data.name,
+          description:this.data.description,
+          GUI_STYLE:this.data.guiStyle,
+          url:svg.getAttribute('src'),
+          moduleType: this.data.moduleType,
+          BUSINESS_TYPE:this.data.businessType?this.data.businessType[0].ID:null,
+          BUSINESS_TYPE_NAME:this.data.businessType?this.data.businessType[0].Label:null,
+          businessTypeText:this.data.businessType?this.data.businessType[0].val:null,
+          businessKeyId:(this.data.businessNumber && this.data.businessNumber.length > 0)?this.data.businessNumber[0].ID:null,
+          businessKey:(this.data.businessNumber && this.data.businessNumber.length > 0)?this.data.businessNumber[0].Label:null,
+          businessKeyName:(this.data.businessNumber && this.data.businessNumber.length > 0)?this.data.businessNumber[0].val:null,
+          autoClose:this.data.autoClose,
+          businessCheckUrl:this.data.businessCheckUrl,
+          nodeMsg: nodeMsg,
+          pathMsg: pathMsg,
+          removeNode: this.data.removeNode,
+          removePath: this.data.removePath
+        }
+        this.$network.post('/p/cs/module/commit',jsonObject).then(res => {
+            if(res.data.resultCode === 0){
+              // this.data = {
+              //   guiStyle:{
+              //     "class": "go.GraphLinksModel",
+              //     "linkFromPortIdProperty": "fromPort",
+              //     "linkToPortIdProperty": "toPort",
+              //     "nodeDataArray": [],
+              //     "linkDataArray": []
+              //   }
+              // }
+              if(!flag){
+                window.flag = true
+                this.$router.push('/TemplateManagementLists')
+                this.currentChange({
+                  path:'/TemplateManagementLists'
+                });
+              }
+
+              resolve(res)
+            }
+
+        })
+      })
+
+
+    },
+    async formatGuiStyle () {  //format整个流程图
+      await new Promise((resolve) => {
+        let startNode = {}  //获取开始节点
+        this.data.guiStyle.nodeDataArray.map(item => {
+          if(item.key === -1){
+            startNode = item
+          }
+        })
+
+        let startlink = {}
+        //获取第一根线的数据
+        this.data.guiStyle.linkDataArray.map(item => {
+          if(item.from === -1){
+            startlink = item
+          }
+        })
+
+        //获取连线的正确排序
+        let linkMap = []
+        new Array(this.data.guiStyle.linkDataArray.length).fill(null).map(() => {
+          this.data.guiStyle.linkDataArray.map(item => {
+            if(linkMap.length === 0 && item.from === -1){
+              linkMap.push(item)
+            }
+            if(linkMap.length > 0 && item.from === linkMap[linkMap.length-1].to){
+              linkMap.push(item)
+            }
+          })
+        })
+        this.data.guiStyle.linkDataArray = linkMap
+
+
+        //获取节点的正确顺序
+        // let nodeMap = [startNode]
+        this.data.guiStyle.nodeDataArray = this.data.guiStyle.linkDataArray.reduce((sum,item) => {
+          sum.push(this.data.Diagram.model.findNodeDataForKey(item.to))
+          return sum
+        },[startNode])
+
+
+        //将所有节点的x轴与开始节点对齐
+        this.data.guiStyle.nodeDataArray.map((item,index) => {
+          let loc = item.loc.split(' ')
+          loc[0] = startNode.loc.split(' ')[0]
+          loc[1] = Number(startNode.loc.split(' ')[1]) + index*80
+          item.loc = loc.join(' ')
+        })
+
+        //将所有连线的x轴与开始节点对齐
+        this.data.guiStyle.linkDataArray.map((item,index) => {
+          item.points.j.map(temp => {
+            temp.F = startlink.points.j[0].F
+          })
+
+          item.points.j.map((temp,j) => {
+            if(index === 0){
+              if(j !== item.points.j.length-1){
+                temp.G = Number(this.data.guiStyle.nodeDataArray[index].loc.split(' ')[1])+20
+              }else{
+                temp.G = Number(this.data.guiStyle.nodeDataArray[index+1].loc.split(' ')[1])-20
+              }
+            }else if(index === this.data.guiStyle.linkDataArray.length - 1){
+              if(j !== item.points.j.length-1){
+                temp.G = Number(this.data.guiStyle.nodeDataArray[index].loc.split(' ')[1])+20
+              }else{
+                temp.G = Number(this.data.guiStyle.nodeDataArray[index+1].loc.split(' ')[1])-20
+              }
+            }else{
+              if(j !== item.points.j.length-1){
+                temp.G = Number(this.data.guiStyle.nodeDataArray[index].loc.split(' ')[1])+20
+              }else{
+                temp.G = Number(this.data.guiStyle.nodeDataArray[index+1].loc.split(' ')[1])-20
+              }
+            }
+
+          })
+        })
+
+        this.data.Diagram.model = go.Model.fromJson(this.data.guiStyle)
+
+        setTimeout(() => {
+          resolve()
+        },100)
+      })
+    },
+    dataChange (data) {  //每一步中的数据变化
+      this.data = Object.assign(this.data,data)
+    },
+    close () {
+      this.$router.push('/TemplateManagementLists')
+      this.currentChange({
+        path:'/TemplateManagementLists'
+      });
+    },
+    confirmAndPublish () {  //保存并发布
+      this.confirm(true).then(res => {
+        this.$network.post('/p/cs/module/publish', {id:res.data.data.id}).then((response) => {
+          if(response.data.resultCode === 0){
+            this.$router.push('/TemplateManagementLists')
+            this.currentChange({
+              path:'/TemplateManagementLists'
+            });
+          }
+        })
+      })
+    }
+  },
+  created () {
+    Vue.component(`component_${this.currentSteps}`,Vue.extend(Object.assign({isKeepAliveModel:true},ParameterConfiguration)))
+    this.currentComponent = `component_${this.currentSteps}`
+    if(this.$route.params.flag === '1'){
+      this.readOnly = true
+      this.noFreshFlag = true
+      this.getModuleInfo(this.$route.params.id)
+      return
+    }
+    if(this.$route.params.id === '-1'){  //新增
+
+    }else{  //编辑
+      this.noFreshFlag = true
+      this.currentSteps = 1
+      this.getModuleInfo(this.$route.params.id)
+    }
+  },
+  beforeDestroy () {
+
+  }
+}
+</script>
+<style lang=scss" >
+.TemplateManagementNew{
+  padding:16px;
+  background: white;
+  display: flex;
+  flex-direction: column;
+
+  .breadcrumb{
+    margin-bottom: 30px;
+    font-size: 18px;
+  }
+
+  .steps{
+    width: 75%;
+    margin-left: 12.5%;
+    margin-bottom: 30px;
+  }
+
+  .content{
+    flex:1;
+    border:1px solid rgba(220,222,226,1);
+    display: flex;
+    flex-direction: column;
+    position: relative;
+    // 预览tips
+    .tips{
+      width:260px;
+      height:204px;
+      background:rgba(236,236,236,1);
+      padding: 16px;
+      box-sizing: border-box;
+      display: inline-block;
+      position: absolute;
+      top: 0;
+      left: 0;
+      z-index: 99;
+      >p{
+        font-weight:400;
+        color:rgba(52,52,52,1);
+        line-height:16px;
+        margin-bottom: 12px;
+        display: flex;
+
+        >span:first-child{
+          margin-right: 8px;
+          white-space: nowrap;
+        }
+
+        >span:last-child{
+          word-break: break-all;
+        }
+      }
+    }
+
+    .block{
+      flex: 1;
+    }
+
+    .buttonGroups{
+      text-align: right;
+      padding-bottom: 16px;
+
+      button{
+        margin-right: 10px;
+
+        &:last-child{
+          margin-right:16px;
+        }
+      }
+    }
+  }
+
+  .burgeon-steps-item.burgeon-steps-status-finish .burgeon-steps-head-inner > .burgeon-steps-icon, .burgeon-steps-item.burgeon-steps-status-finish .burgeon-steps-head-inner span{
+    color: white;
+  }
+
+  .burgeon-steps-item.burgeon-steps-status-finish .burgeon-steps-head-inner{
+    border-color: #09A155;
+    background: #09A155;
+  }
+}
+</style>

+ 24 - 24
ruoyi-ui/src/views/activiti/modeler/index.vue

@@ -225,31 +225,31 @@ export default {
       let obj = Object.assign({},this.searchData)
       delete obj.createTime
       delete obj.status
-      this.$network.post('/p/cs/module/search', obj).then((res) => {
-        if(res.data.resultCode !== 0){
-          return
-        }
-        let data = res.data.data
-        this.total = data.total
+      // this.$network.post('/p/cs/module/search', obj).then((res) => {
+      //   if(res.data.resultCode !== 0){
+      //     return
+      //   }
+      //   let data = res.data.data
+      //   this.total = data.total
 
-        this.listsConfig = data.records.reduce((arr,item) => {
-          let items = {
-            event:{
-              queryLists:() => {
-                this.queryLists()
-              }
-            }
-          }
-          items = Object.assign(items,item)
-          arr.push({
-            row:1,
-            col:1,
-            component:listModalComponent,
-            item:items
-          })
-          return arr
-        },[])
-      });
+      //   this.listsConfig = data.records.reduce((arr,item) => {
+      //     let items = {
+      //       event:{
+      //         queryLists:() => {
+      //           this.queryLists()
+      //         }
+      //       }
+      //     }
+      //     items = Object.assign(items,item)
+      //     arr.push({
+      //       row:1,
+      //       col:1,
+      //       component:listModalComponent,
+      //       item:items
+      //     })
+      //     return arr
+      //   },[])
+      // });
     },
     addTemplate () {  //新建模版
       this.changeKeepAliveArray(['TemplateManagementLists'])

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

@@ -125,7 +125,6 @@
       this.tabName = items.sysTableName
       this.queryParams.table = items.sysTableName
       this.form.table = items.sysTableName
-      console.log(this.sidebarRouters,items,path,998812111)
       this.init();
       this.getList();
     },

+ 14 - 6
ruoyi-ui/src/views/tool/gen/editTable.vue

@@ -147,14 +147,14 @@
                     <el-option v-for="dict in columList" :key="dict.columnId" :label="dict.columnName" :value="dict.columnId" />
                   </el-select> -->
                   <div style="cursor: pointer;" @click="fkzdFn">
-                    <el-input readonly style="width: 100%;" v-model="ForeName" placeholder="请选择外键(FK)" />
+                    <el-input readonly style="width: 100%;" clearable v-model="ForeName" placeholder="请选择外键(FK)" />
                   </div>
                 </el-form-item>
               </el-col>
               <el-col :span="8">
                 <el-form-item label="关联HR字段:" prop="hrParentId">
                   <el-select style="width: 100%;" v-model="formZd.hrParentId" placeholder="请选择关联HR字段" clearable>
-                    <el-option v-for="dict in columHRList" :key="dict.columnId" :label="dict.columnName" :value="dict.columnId" />
+                    <el-option v-for="dict in columHRList" :key="dict.id" :label="dict.columnName" :value="dict.id" />
                   </el-select>
                 </el-form-item>
               </el-col>
@@ -879,8 +879,8 @@
       /** 提交按钮 */
       submitForm() {
         let isInFlag = 0
-        let isOutFlag = 0
-        console.log(this.cloumns,333)
+        let isOutFlag = 0
+
         for(let item of this.cloumns){
           if(item.isIn=='Y'){
             isInFlag++
@@ -897,7 +897,8 @@
           this.msgError('"显示字段"最多只能选择一个!')
           return
         }
-        const basicForm = this.$refs.basicInfo.$refs.basicInfoForm;
+        const basicForm = this.$refs.basicInfo.$refs.basicInfoForm;
+
         // const genForm = this.$refs.genInfo.$refs.genInfoForm;
         Promise.all([basicForm].map(this.getFormPromise)).then(res => {
           const validateResult = res.every(item => !!item);
@@ -909,7 +910,14 @@
             //   treeName: genTable.treeName,
             //   treeParentCode: genTable.treeParentCode,
             //   parentMenuId: genTable.parentMenuId
-            // };
+            // };
+            console.log(genTable)
+            if(this.activeName=='basic'){
+              genTable.updateType ='1'
+            }
+            if(this.activeName=='cloum'){
+              genTable.updateType ='2'
+            }
             updateGenTable(genTable).then(res => {
               this.msgSuccess(res.msg);
               if (res.code === 200) {