Renxy преди 2 години
родител
ревизия
27d1c8f1a5

+ 2 - 2
src/components/AuditForm/FormContent.js

@@ -68,7 +68,7 @@ function FormContent(props) {
 
 function FormItem(props) {
   const { item, btns, active, onClick } = props;
-  const { label, placeholder, require } = item.props;
+  const { label, placeholder, required } = item.props;
   return (
     <div
       style={{
@@ -80,7 +80,7 @@ function FormItem(props) {
       onClick={onClick}
     >
       <div style={{ fontSzie: 24, color: '#000', fontWeight: 'bold', position: 'relative' }}>
-        {require && <i style={{ color: 'red' }}>*</i>}
+        {required && <i style={{ color: 'red' }}>*</i>}
         {label}
         <div style={{ position: 'absolute', right: 0, top: 0, padding: '5px 10px' }}>{btns}</div>
       </div>

+ 56 - 0
src/components/Flow/components/departSelect/index.tsx

@@ -0,0 +1,56 @@
+import { TreeSelect, TreeSelectProps } from 'antd';
+import React, { useState, useEffect } from 'react';
+import { queryDDdepList } from '@/services/boom';
+
+function DepartmentSelect(props) {
+  const { value, defaultValue, onChange } = props;
+
+  // const [value, setValue] = useState();
+  const [treeData, setTreeData] = useState([]);
+
+  const genTreeNode = dep => {
+    return {
+      id: dep.dept_id,
+      pId: dep.parent_id,
+      value: dep.dept_id,
+      title: dep.name,
+      isLeaf: false,
+    };
+  };
+
+  const onLoadData: TreeSelectProps['loadData'] = async ({ id }) => {
+    let depList = await queryDDdepList({ dept_id: id });
+
+    console.log(depList);
+    if (depList.length > 0) {
+      let nodes = depList.map(genTreeNode);
+      setTreeData([...treeData, ...nodes]);
+    }
+  };
+
+  useEffect(() => {
+    onLoadData({});
+  }, []);
+
+  return (
+    <TreeSelect
+      treeDataSimpleMode
+      multiple
+      style={{
+        width: '100%',
+      }}
+      defaultValue={defaultValue}
+      // value={value}
+      dropdownStyle={{
+        maxHeight: 400,
+        overflow: 'auto',
+      }}
+      placeholder="请选择部门"
+      onChange={onChange}
+      loadData={onLoadData}
+      treeData={treeData}
+    />
+  );
+}
+
+export default DepartmentSelect;

+ 116 - 0
src/components/Flow/components/judgeComponent/index.tsx

@@ -0,0 +1,116 @@
+import React, { useEffect, useState } from 'react';
+import { Checkbox, Select } from 'antd';
+import DepartmentSelect from '../departSelect';
+import { ComponentName, FormItem } from '../../node/judgeNode/mapServe';
+import { InputNumberFiled } from '../../node/fields';
+
+export interface JudgeType {
+  type: string;
+  id: string;
+  condition?: number;
+  values?: string[] | number[];
+}
+
+export const JudgeOptions = [
+  { label: '小于', value: 1 },
+  { label: '大于', value: 2 },
+  { label: '小于等于', value: 3 },
+  { label: '等于', value: 4 },
+  { label: '大于等于', value: 5 },
+  { label: '介于(两个数之间)', value: 6 },
+];
+
+const RenderJudge = (props: any) => {
+  const { formItems = '', onChange } = props;
+  let formData: FormItem[] = formItems ? JSON.parse(formItems) : [];
+
+  const handleChange = (values: string[] | number[], item: FormItem, condition?: number) => {
+    const itemCur = formData.find(cur => cur.props.id == item.props.id);
+    let judge: JudgeType = {
+      id: item.props.id,
+      values:
+        values.length == 0 && itemCur && itemCur.judge?.values ? itemCur.judge.values : values,
+      type: item.componentName,
+      condition:
+        !condition && itemCur && itemCur.judge?.condition ? itemCur.judge.condition : condition,
+    };
+    const newItem: FormItem = {
+      ...item,
+      judge,
+    };
+    const index = formData.findIndex(cur => cur.props.id == item.props.id);
+    if (index != -1) {
+      formData[index] = newItem;
+    } else {
+      formData.push(newItem);
+    }
+    onChange(formData);
+  };
+
+  const RenderComp = (item: FormItem) => {
+    let component;
+    switch (item.componentName) {
+      case ComponentName.Inner:
+        component = (
+          <div className="group">
+            <div>发起人</div>
+            <DepartmentSelect
+              defaultValue={item.judge?.values}
+              onChange={values => handleChange(values, item)}
+            />
+          </div>
+        );
+        break;
+      case ComponentName.Depart:
+        break;
+      case ComponentName.Money:
+        console.log(item);
+        component = (
+          <>
+            <div>{item.props.label}</div>
+            <Select
+              options={JudgeOptions}
+              defaultValue={item.judge?.values[0] || 1}
+              onChange={(value: number) => {
+                handleChange([value], item);
+              }}
+            />
+            <InputNumberFiled
+              value={item.judge?.condition}
+              onChange={value => {
+                handleChange([], item, value);
+              }}
+            />
+          </>
+        );
+        break;
+
+      case ComponentName.MultiSelect:
+      case ComponentName.Select:
+        const options = item.props.options;
+        component = (
+          <>
+            <div>{item.props.label}</div>
+            <Checkbox.Group
+              defaultValue={item.judge?.values}
+              onChange={(values: any) => handleChange(values, item)}
+            >
+              {options.map((cur: any, idx: number) => {
+                return (
+                  <Checkbox key={`${cur}_${idx}`} value={cur}>
+                    {cur}
+                  </Checkbox>
+                );
+              })}
+            </Checkbox.Group>
+          </>
+        );
+        break;
+    }
+    return component;
+  };
+
+  return <>{formData.map(item => RenderComp(item))}</>;
+};
+
+export default RenderJudge;

+ 77 - 0
src/components/Flow/components/judgeModal/index.tsx

@@ -0,0 +1,77 @@
+import { Button, Checkbox, Modal } from 'antd';
+import { PlusOutlined } from '@ant-design/icons';
+import React, { useEffect, useMemo, useState } from 'react';
+import { ComponentName, FormItem } from '../../node/judgeNode/mapServe';
+
+const AddCondition = (props: any) => {
+  const { items = [], formItems = '', onOk } = props;
+  const [visible, setVisible] = useState(false);
+  const [values, setValues] = useState([]);
+
+  let formData: FormItem[] = formItems ? JSON.parse(formItems) : [];
+  const data: FormItem[] = items
+    .filter((item: FormItem) => {
+      return (
+        (item.componentName == ComponentName.Inner ||
+          // item.componentName == 'DepartmentField' ||
+          item.componentName == ComponentName.Select ||
+          item.componentName == ComponentName.MultiSelect ||
+          item.componentName == ComponentName.Money) &&
+        item.props.required
+      );
+    })
+    .map(item => {
+      return {
+        label: item.props.label,
+        ...item,
+      };
+    });
+
+  console.log(data);
+
+  const onChange = (values: []) => {
+    console.log(values);
+    setValues(values);
+  };
+
+  const handleOk = () => {
+    let resultData: FormItem[] = [];
+    values.map(value => {
+      const item = formData.find(cur => cur.props.id == value);
+      if (item) {
+        resultData.push(item);
+      } else {
+        const item = items.find(cur => cur.props.id == value);
+        resultData.push(item);
+      }
+    });
+    onOk(resultData);
+    setVisible(false);
+  };
+
+  return (
+    <>
+      <div className={`group`}>
+        <Button icon={<PlusOutlined />} onClick={() => setVisible(true)}>
+          添加条件
+        </Button>
+        还有{data.length - values.length}组可用条件
+      </div>
+      <Modal title="选择条件" visible={visible} onOk={handleOk} onCancel={() => setVisible(false)}>
+        <p>请选择用来区分审批流程的条件字段 ,已选{values.length}个</p>
+        <Checkbox.Group defaultValue={formData.map(item => item.props.id)} onChange={onChange}>
+          {data.map((item: FormItem) => (
+            <Checkbox
+              key={item.props.id}
+              value={item.props.id}
+              checked={formData.findIndex(cur => cur.props.id == item.props.id) !== -1}
+            >
+              {item.props.label}
+            </Checkbox>
+          ))}
+        </Checkbox.Group>
+      </Modal>
+    </>
+  );
+};
+export default AddCondition;

+ 87 - 0
src/components/Flow/node/auditNode/index.tsx

@@ -0,0 +1,87 @@
+import React from 'react';
+AuditServe;
+import AuditServe, { TYPE } from './mapServe';
+// import { Badge } from 'antd';
+import { useXFlowApp, XFlowNodeCommands } from '@antv/xflow';
+export { AuditServe };
+
+export default function CustomRect(props) {
+  const { size = { width: 130, height: 50 }, data } = props;
+  const { width, height } = size;
+  const { label, stroke, fill, fontFill, fontSize, type } = data;
+  const app = useXFlowApp();
+  const handleClick = () => {
+    // console.log(data);
+    app.executeCommand(XFlowNodeCommands.SELECT_NODE.id, {
+      nodeId: data.id,
+    });
+    // console.log('XFlowNodeCommands.SELECT_NODE.id', data);
+    // message.success(`${XFlowNodeCommands.SELECT_NODE.label}: 命令执行成功`);
+  };
+
+  // const type: TYPE = 0;
+  const titleDom = () => {
+    let color = COLOR.AUDIT;
+    let text = label == '审批节点' ? TITLETEXT.AUDIT : label;
+    switch (type) {
+      case TYPE.AUDIT:
+        color = COLOR.AUDIT;
+        text = TITLETEXT.AUDIT;
+        break;
+      case TYPE.INITIATOR:
+        color = COLOR.INITIATOR;
+        text = TITLETEXT.INITIATOR;
+        break;
+      case TYPE.COPYMAN:
+        color = COLOR.COPYMAN;
+        text = TITLETEXT.COPYMAN;
+        break;
+    }
+    return (
+      <div
+        style={{
+          width: '100%',
+          height: `${fontSize + 16}px`,
+          paddingLeft: '6px',
+          backgroundColor: color,
+          color: 'white',
+          fontSize,
+        }}
+      >
+        {text}
+      </div>
+    );
+  };
+  return (
+    <div
+      style={{
+        width,
+        height,
+        boxShadow: '0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19)',
+      }}
+    >
+      {titleDom()}
+      <div
+        style={{
+          paddingLeft: '6px',
+          height: `${height - fontSize - 16}px`,
+          lineHeight: `${height - fontSize - 16}px`,
+          fontSize,
+        }}
+      >
+        哈哈哈哈哈哈哈哈
+      </div>
+    </div>
+  );
+}
+
+const enum COLOR {
+  AUDIT = '#FF943E',
+  INITIATOR = '#576A95',
+  COPYMAN = '#3296FA',
+}
+const enum TITLETEXT {
+  AUDIT = '审批人',
+  INITIATOR = '发起人',
+  COPYMAN = '抄送人',
+}

+ 165 - 0
src/components/Flow/node/auditNode/mapServe.tsx

@@ -0,0 +1,165 @@
+import React, { useState, useEffect } from 'react';
+import { FlowchartFormWrapper } from '@antv/xflow';
+import { Position, Size, ColorPicker, InputNumberFiled, InputFiled, SelectField } from '../fields';
+import { PREFIX } from '../constants';
+import { connect } from 'dva';
+import { UnityAction } from '@/utils/utils';
+import { Button } from 'antd';
+
+export const enum TYPE {
+  AUDIT,
+  INITIATOR,
+  COPYMAN,
+}
+
+export interface IConfig {
+  label?: string;
+  x?: number;
+  y?: number;
+  width?: number;
+  height?: number;
+  count?: number;
+  fontSize?: number;
+  fontFill?: string;
+  fill?: string;
+  stroke?: string;
+  flow_id?: string;
+  flow_node_id?: string;
+  process_code?: string;
+  type: TYPE;
+}
+
+const Component = (props: any) => {
+  const { config, plugin = {}, auditList } = props;
+  const { updateNode } = plugin;
+
+  const typeOption = [
+    { label: '审批人', value: TYPE.AUDIT },
+    { label: '发起人', value: TYPE.INITIATOR },
+    { label: '抄送人', value: TYPE.COPYMAN },
+  ];
+
+  const [nodeConfig, setNodeConfig] = useState<IConfig>({
+    ...config,
+  });
+  const onNodeConfigChange = (key: string, value: number | string | object) => {
+    console.log(key, value);
+    if (key) {
+      setNodeConfig({
+        ...nodeConfig,
+        [key]: value,
+      });
+      updateNode({
+        [key]: value,
+      });
+    } else if (value instanceof Object) {
+      setNodeConfig({
+        ...nodeConfig,
+        ...value,
+      });
+      updateNode({
+        ...value,
+      });
+    }
+  };
+
+  const onSave = () => {
+    UnityAction.emit('NODE_SAVE', nodeConfig);
+  };
+  useEffect(() => {
+    setNodeConfig({
+      ...config,
+    });
+  }, [config]);
+
+  return (
+    <div className={`${PREFIX}-panel-body`}>
+      <div className={`${PREFIX}-panel-group`}>
+        <h5>内容</h5>
+        <InputFiled
+          label="标题"
+          value={nodeConfig.label}
+          onChange={value => {
+            onNodeConfigChange('label', value);
+          }}
+        />
+        <SelectField
+          label="节点类型"
+          value={nodeConfig.type}
+          onChange={value => {
+            onNodeConfigChange('type', value);
+          }}
+          options={typeOption}
+        />
+      </div>
+      <div className={`${PREFIX}-panel-group`}>
+        <h5>样式</h5>
+        <Position
+          x={nodeConfig.x}
+          y={nodeConfig.y}
+          onChange={(key, value) => {
+            onNodeConfigChange(key, value);
+          }}
+        />
+        <Size
+          width={nodeConfig.width}
+          height={nodeConfig.height}
+          onChange={(key, value) => {
+            onNodeConfigChange(key, value);
+          }}
+        />
+        <ColorPicker
+          label="填充"
+          value={nodeConfig.fill}
+          onChange={(value: string) => {
+            onNodeConfigChange('fill', value);
+          }}
+        />
+        <ColorPicker
+          label="边框"
+          value={nodeConfig.stroke}
+          onChange={(value: string) => {
+            onNodeConfigChange('stroke', value);
+          }}
+        />
+        <InputNumberFiled
+          label="消息数量"
+          value={nodeConfig.count}
+          onChange={value => {
+            onNodeConfigChange('count', value);
+          }}
+        />
+      </div>
+
+      <div className={`${PREFIX}-node-text-style`}>
+        <InputNumberFiled
+          label="字号"
+          value={nodeConfig.fontSize}
+          width={68}
+          onChange={value => {
+            onNodeConfigChange('fontSize', value);
+          }}
+        />
+        <ColorPicker
+          value={nodeConfig.fontFill}
+          onChange={(value: string) => {
+            onNodeConfigChange('fontFill', value);
+          }}
+        />
+      </div>
+      <Button style={{ marginTop: 20 }} type="primary" onClick={onSave}>
+        保存
+      </Button>
+    </div>
+  );
+};
+
+function RecthServe(props: any) {
+  return (
+    <FlowchartFormWrapper {...props}>
+      {(config, plugin) => <Component {...props} plugin={plugin} config={config} />}
+    </FlowchartFormWrapper>
+  );
+}
+
+export default connect(({ xflow }) => ({ auditList: xflow.auditList }))(RecthServe);

+ 87 - 0
src/components/Flow/node/judgeNode/index.tsx

@@ -0,0 +1,87 @@
+import React from 'react';
+judgeServe;
+import judgeServe, { TYPE } from './mapServe';
+// import { Badge } from 'antd';
+import { useXFlowApp, XFlowNodeCommands } from '@antv/xflow';
+export { judgeServe };
+
+export default function CustomRect(props) {
+  const { size = { width: 130, height: 50 }, data } = props;
+  const { width, height } = size;
+  const { label, stroke, fill, fontFill, fontSize, type } = data;
+  const app = useXFlowApp();
+  const handleClick = () => {
+    // console.log(data);
+    app.executeCommand(XFlowNodeCommands.SELECT_NODE.id, {
+      nodeId: data.id,
+    });
+    // console.log('XFlowNodeCommands.SELECT_NODE.id', data);
+    // message.success(`${XFlowNodeCommands.SELECT_NODE.label}: 命令执行成功`);
+  };
+
+  // const type: TYPE = 0;
+  const titleDom = () => {
+    let color = COLOR.AUDIT;
+    let text = label == '审批节点' ? TITLETEXT.AUDIT : label;
+    switch (type) {
+      case TYPE.AUDIT:
+        color = COLOR.AUDIT;
+        text = TITLETEXT.AUDIT;
+        break;
+      case TYPE.INITIATOR:
+        color = COLOR.INITIATOR;
+        text = TITLETEXT.INITIATOR;
+        break;
+      case TYPE.COPYMAN:
+        color = COLOR.COPYMAN;
+        text = TITLETEXT.COPYMAN;
+        break;
+    }
+    return (
+      <div
+        style={{
+          width: '100%',
+          height: `${fontSize + 16}px`,
+          paddingLeft: '6px',
+          backgroundColor: color,
+          color: 'white',
+          fontSize,
+        }}
+      >
+        {text}
+      </div>
+    );
+  };
+  return (
+    <div
+      style={{
+        width,
+        height,
+        padding: '6px',
+        boxShadow: '0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19)',
+      }}
+    >
+      <span style={{ color: '#15BC83' }}>条件1</span>
+      <div
+        style={{
+          height: `${height - 32}px`,
+          overflow: 'hidden',
+          textOverflow: 'ellipsis',
+        }}
+      >
+        哈哈哈哈哈哈哈哈
+      </div>
+    </div>
+  );
+}
+
+const enum COLOR {
+  AUDIT = '#FF943E',
+  INITIATOR = '#576A95',
+  COPYMAN = '#3296FA',
+}
+const enum TITLETEXT {
+  AUDIT = '审批人',
+  INITIATOR = '发起人',
+  COPYMAN = '抄送人',
+}

+ 252 - 0
src/components/Flow/node/judgeNode/mapServe.tsx

@@ -0,0 +1,252 @@
+import React, { useState, useEffect, useMemo } from 'react';
+import { FlowchartFormWrapper } from '@antv/xflow';
+import { Position, Size, ColorPicker, InputNumberFiled, InputFiled, SelectField } from '../fields';
+import { PREFIX } from '../constants';
+import { connect } from 'dva';
+import { UnityAction } from '@/utils/utils';
+import { Button } from 'antd';
+import AddCondition from '../../components/judgeModal';
+import RenderJudge, { JudgeType } from '../../components/judgeComponent';
+
+export const enum TYPE {
+  AUDIT,
+  INITIATOR,
+  COPYMAN,
+}
+
+export const enum ComponentName {
+  Inner = 'InnerContactField',
+  Depart = 'DepartmentField',
+  Select = 'DDSelectField',
+  Money = 'MoneyField',
+  MultiSelect = 'DDMultiSelectField',
+}
+
+export interface IConfig {
+  label?: string;
+  x?: number;
+  y?: number;
+  width?: number;
+  height?: number;
+  count?: number;
+  fontSize?: number;
+  fontFill?: string;
+  fill?: string;
+  stroke?: string;
+  flow_id?: string;
+  flow_node_id?: string;
+  process_code?: string;
+  type: TYPE;
+  formItems: string;
+  priority?: number; //优先级
+}
+
+export interface FormItem {
+  componentName: string;
+  props: {
+    label: string;
+    id: string;
+    options?: string[];
+    required: boolean;
+    placeholder?: string;
+  };
+  judge?: JudgeType;
+}
+
+const Component = (props: any) => {
+  const { config, plugin = {}, formItems } = props;
+  const { updateNode } = plugin;
+
+  const formData: FormItem[] = [
+    {
+      componentName: 'InnerContactField',
+      props: {
+        label: '申请人',
+        id: 'InnerContactField-JEQRQ5VH',
+        required: true,
+      },
+    },
+    {
+      componentName: 'DepartmentField',
+      props: {
+        label: '选择部门',
+        id: 'DepartmentField_1VALX0GTRNVK0',
+        required: true,
+      },
+    },
+    {
+      componentName: 'DDSelectField',
+      props: {
+        id: 'DDSelectField_LWFCJRK508W0',
+        label: '文件类型',
+        options: [
+          '{"value":"新增|FT008","key":"option_1IXTB1VDV9EO0"}',
+          '{"value":"补充|FT009","key":"option_1DVWNV9BNZNK0"}',
+        ],
+        required: true,
+      },
+    },
+    {
+      componentName: 'DDSelectField',
+      props: {
+        id: 'DDSelectField_21WUQ0OWR7R40',
+        label: '是否外带',
+        options: [
+          '{"value":"是","key":"option_DUSP6XANFKO0"}',
+          '{"value":"否","key":"option_CC5VQ63ZLJK0"}',
+        ],
+        required: true,
+      },
+    },
+    {
+      componentName: 'MoneyField',
+      props: {
+        id: 'MoneyField-JSCUC2GG',
+        label: '文件金额(元)',
+        placeholder: '请输入金额',
+        required: true,
+      },
+    },
+  ];
+
+  const [nodeConfig, setNodeConfig] = useState<IConfig>({
+    ...config,
+  });
+  const onNodeConfigChange = (key: string, value: number | string | object) => {
+    console.log(key, value);
+    if (key) {
+      setNodeConfig({
+        ...nodeConfig,
+        [key]: value,
+      });
+      updateNode({
+        [key]: value,
+      });
+    } else if (value instanceof Object) {
+      setNodeConfig({
+        ...nodeConfig,
+        ...value,
+      });
+      updateNode({
+        ...value,
+      });
+    }
+  };
+  console.log(nodeConfig);
+
+  const onSave = () => {
+    UnityAction.emit('NODE_SAVE', nodeConfig);
+  };
+
+  useEffect(() => {
+    setNodeConfig({
+      ...config,
+    });
+  }, [config]);
+
+  return (
+    <div className={`${PREFIX}-panel-body`}>
+      <div className={`${PREFIX}-panel-group`}>
+        <h5>内容</h5>
+        <InputFiled
+          label="标题"
+          value={nodeConfig.label}
+          onChange={value => {
+            onNodeConfigChange('label', value);
+          }}
+        />
+      </div>
+      <div className={`${PREFIX}-panel-group`}>
+        <h5>样式</h5>
+        <Position
+          x={nodeConfig.x}
+          y={nodeConfig.y}
+          onChange={(key, value) => {
+            onNodeConfigChange(key, value);
+          }}
+        />
+        <Size
+          width={nodeConfig.width}
+          height={nodeConfig.height}
+          onChange={(key, value) => {
+            onNodeConfigChange(key, value);
+          }}
+        />
+        <ColorPicker
+          label="填充"
+          value={nodeConfig.fill}
+          onChange={(value: string) => {
+            onNodeConfigChange('fill', value);
+          }}
+        />
+        <ColorPicker
+          label="边框"
+          value={nodeConfig.stroke}
+          onChange={(value: string) => {
+            onNodeConfigChange('stroke', value);
+          }}
+        />
+        <InputNumberFiled
+          label="消息数量"
+          value={nodeConfig.count}
+          onChange={value => {
+            onNodeConfigChange('count', value);
+          }}
+        />
+        <div className={`${PREFIX}-node-text-style`}>
+          <InputNumberFiled
+            label="字号"
+            value={nodeConfig.fontSize}
+            width={68}
+            onChange={value => {
+              onNodeConfigChange('fontSize', value);
+            }}
+          />
+          <ColorPicker
+            value={nodeConfig.fontFill}
+            onChange={(value: string) => {
+              onNodeConfigChange('fontFill', value);
+            }}
+          />
+        </div>
+        <InputNumberFiled
+          label="优先级"
+          value={nodeConfig.priority}
+          width={68}
+          onChange={value => {
+            onNodeConfigChange('priority', value);
+          }}
+        />
+        <AddCondition
+          items={formItems}
+          formItems={nodeConfig.formItems}
+          onOk={(values: FormItem[]) => {
+            onNodeConfigChange('formItems', JSON.stringify(values));
+          }}
+        />
+        <RenderJudge
+          formItems={nodeConfig.formItems}
+          onChange={(values: FormItem[]) => {
+            onNodeConfigChange('formItems', JSON.stringify(values));
+          }}
+        />
+      </div>
+
+      <Button style={{ marginTop: 20 }} type="primary" onClick={onSave}>
+        保存
+      </Button>
+    </div>
+  );
+};
+
+function RecthServe(props: any) {
+  return (
+    <FlowchartFormWrapper {...props}>
+      {(config, plugin) => <Component {...props} plugin={plugin} config={config} />}
+    </FlowchartFormWrapper>
+  );
+}
+
+export default connect(({ xflow }) => ({ auditList: xflow.auditList, formItems: xflow.formData }))(
+  RecthServe
+);

+ 21 - 3
src/components/Flow/node/registerNode.tsx

@@ -1,10 +1,11 @@
-import React from "react"
+import React from 'react';
 import Rect, { RectServe } from './rect';
 import Circle, { CircleServe } from './circle';
+import AuditNode, { AuditServe } from './auditNode';
 
+import judgeNode, { judgeServe } from './judgeNode';
 
 export const registerNode = [
-
   {
     component: Rect,
     popover: () => <div>业务组件</div>,
@@ -23,5 +24,22 @@ export const registerNode = [
     label: '审批节点',
     service: CircleServe,
   },
-
+  {
+    component: AuditNode,
+    popover: () => <div>审批节点</div>,
+    name: 'custom-audit',
+    width: 130,
+    height: 50,
+    label: '审批节点',
+    service: AuditServe,
+  },
+  {
+    component: judgeNode,
+    popover: () => <div>审批节点</div>,
+    name: 'custom-judge',
+    width: 130,
+    height: 50,
+    label: '审批节点',
+    service: judgeServe,
+  },
 ];

+ 1 - 1
src/pages/PurchaseAdmin/PurchaseList/Detail/CommitAuditModal.js

@@ -162,7 +162,7 @@ function CommitAuditModal(props) {
         addAuditList.push(res.data.result);
       }
     }
-    console.log(addAuditList);
+    console.log(JSON.stringify(addAuditList));
     addAuditList.forEach((item, index) => {
       let Components = Form3x.create({
         onValuesChange: (props, changedValues, allValues) => {

+ 9 - 7
src/pages/PurchaseAdmin/PurchaseList/Detail/Index.js

@@ -385,10 +385,11 @@ function Detail(props) {
       }
     };
 
+    let tipText = '是否通过审批。';
     if (!flag) {
-      // setAuditVisible(true);
-      request();
-      return;
+      tipText = '是否拒绝审批。';
+      // request();
+      // return;
     }
 
     let isSingle = false;
@@ -425,13 +426,12 @@ function Detail(props) {
         isSingle = versionList.find(
           item => item.audit_status != 4 && item.template_node_id == serviceNode.Id
         );
+        if (isSingle) tipText = `节点【${serviceNode.label}】只能拥有一个清单,是否覆盖?`;
       }
     }
     Modal.confirm({
       title: '提示',
-      content: isSingle
-        ? `节点【${serviceNode.label}】只能拥有一个清单,是否覆盖?`
-        : `是否通过审批。`,
+      content: tipText,
       okText: '确定',
       cancelText: '取消',
       onOk: () => {
@@ -959,7 +959,9 @@ function Detail(props) {
         />
       </div>
       {/* <TimeNode flow={flow} isAuditor={isAuditor} onApprove={onApprove}></TimeNode> */}
-      {version.flow_id ? <AuditFlow {...auditDetail} canShowAudit={true} onApprove={onApprove} /> : null}
+      {version.flow_id ? (
+        <AuditFlow {...auditDetail} canShowAudit={true} onApprove={onApprove} />
+      ) : null}
 
       {/* {renderAlert()} */}
       {/* 判断是否为比对模式 */}

+ 27 - 214
src/pages/PurchaseAdmin/PurchaseList/Flow/Audit.js

@@ -1,235 +1,48 @@
 import React, { useState, useEffect } from 'react';
-import { Form, Select, Button, Table, Input, Checkbox, Divider } from 'antd';
+import { Form, Select, Button, Table, Input, Checkbox, Divider, Tabs } from 'antd';
 import { connect } from 'dva';
 import AuditNodeModal from './AuditNodeModal';
 import AuditModal from './AuditModal';
 import styles from './Audit.less';
 import router from 'umi/router';
+import Flow, { FLOW_TYPE } from '@/components/Flow';
+import AuditForm from '@/components/AuditForm';
 
 const { Option } = Select;
+const { TabPane } = Tabs;
 
 function Audit(props) {
   const { roleList, currentItem, dispatch } = props;
-  const [visible, setVisible] = useState({
-    audit: false,
-    auditNode: false,
-  });
-  const [current, setCurrent] = useState({ ...currentItem });
-  const [currentNode, setCurrentNode] = useState({});
-  const columns = [
-    {
-      title: '节点名',
-      width: "20%",
-      dataIndex: 'node',
-    },
-    // {
-    //   title: '审批级别',
-    //   dataIndex: 'seq',
-    //   width: "20%",
-    // },
-    {
-      title: '审批角色',
-      dataIndex: 'audit_role',
-      width: "20%",
-      render: audit_role => roleList.find(item => item.ID == audit_role)?.Name,
-    },
-    // {
-    //   title: '审批关系',
-    //   width: "20%",
-    //   dataIndex: 'seq_relate',
-    //   render: relate => {
-    //     switch (relate) {
-    //       case 0:
-    //         return '无';
-    //       case 1:
-    //         return '或';
-    //       case 2:
-    //         return '并';
-    //     }
-    //   },
-    // },
-    {
-      title: '操作',
-      width: "20%",
-      render: item => (
-        <>
-          <a
-            onClick={() => {
-              setCurrentNode(item);
-              changeVisible('auditNode', true);
-            }}
-          >
-            编辑
-          </a>
-          <Divider type="vertical" />
-          <a
-            onClick={() => {
-              handleDelete(item);
-            }}
-          >
-            删除
-          </a>
-        </>
-      ),
-    },
-  ];
-  // const handleAuditOk = values => {
-  //   console.log(values);
-  //   dispatch({
-  //     type: 'flow/addAudit',
-  //     payload: values,
-  //     callback: () => {
-  //       changeVisible('audit', false);
-  //     },
-  //   });
-  // };
-  const handleAuditNodeOk = values => {
-    console.log(values);
-    let FlowNodes = current.FlowNodes;
-
-    changeVisible('auditNode', false);
-    if (currentNode.id) {
-      let index = FlowNodes.findIndex(item => item.id == currentNode.id);
-      let newNodes = [...FlowNodes];
-      newNodes[index] = values;
-      // 将同审批级别的审批关系设置为相同
-      newNodes.forEach(item => {
-        if (item.seq == values.seq) {
-          item.seq_relate = values.seq_relate;
-        }
-      });
-      // 排序
-      newNodes.sort((a, b) => a.seq - b.seq);
-      setCurrent({
-        ...current,
-        FlowNodes: newNodes,
-      });
-    } else {
-      setCurrent({
-        ...current,
-        FlowNodes: [...FlowNodes, values],
-      });
-    }
-  };
-  const handleDelete = item => {
-    let newNodes = [...current.FlowNodes];
-    let index = newNodes.indexOf(item);
-    newNodes.splice(index, 1);
-    setCurrent({
-      ...current,
-      FlowNodes: newNodes,
-    });
+  const [formData, setFormData] = useState([]);
+  const flowDetail = {
+    nodes: [],
+    edgs: [],
   };
-  // const onCancel = () => {
-  //   form.resetFields();
-  //   setCurrent({});
-  // };
-  const onSave = () => {
-    const nodes = current.FlowNodes.map((item,index) => ({
-      flow_id: current.id,
-      node: item.node,
-      desc: item.desc,
-      audit_role: item.audit_role,
-      seq: index + 1,
-      // seq_relate: item.seq_relate,
-    }));
-
+  const onChange = valuse => {
     dispatch({
-      type: 'flow/addAuditNode',
+      type: 'xflow/save',
       payload: {
-        flowId: current.id,
-        nodes: nodes,
+        formData: valuse,
       },
     });
   };
-  // const handleSelect = id => {
-  //   const item = list.find(item => item.list?.id == id);
-  //   console.log(item);
-  //   setCurrent({
-  //     ...item.list,
-  //   });
-  // };
-  const changeVisible = (type, visible) => {
-    setVisible({
-      ...visible,
-      [type]: visible,
-    });
-  };
-
-  // const renderTitle = () => {
-  //   return (
-  //     <div className={styles.box}>
-  //       <span>审批详情</span>
-  //       {current?.id && (
-  //         <div className={styles.btns}>
-  //           {/* <Button onClick={onCancel}>取消</Button> */}
-  //           <Button onClick={onSave} type="primary">
-  //             保存
-  //           </Button>
-  //           <Button
-  //             onClick={() => {
-  //               setCurrentNode({});
-  //               changeVisible('auditNode', true);
-  //             }}
-  //             type="primary"
-  //           >
-  //             添加节点
-  //           </Button>
-  //         </div>
-  //       )}
-  //     </div>
-  //   );
-  // };
-
-  useEffect(() => {
-    if (!current.id) {
-      router.go(-1);
-    } else {
-      dispatch({
-        type: 'user/fetch',
-      });
-      dispatch({
-        type: 'flow/queryAuditList',
-      });
-      dispatch({
-        type: 'flow/getRoleList',
-      });
-    }
-  }, []);
-
   return (
-    <div>
-      <div className={styles.btns}>
-        <Button onClick={() => router.go(-1)}>返回</Button>
-        {/* <Button onClick={onCancel}>取消</Button> */}
-        <Button onClick={onSave} type="primary">
-          保存
-        </Button>
-        <Button
-          onClick={() => {
-            setCurrentNode({});
-            changeVisible('auditNode', true);
-          }}
-          type="primary"
-        >
-          添加节点
-        </Button>
-      </div>
-
-      <Table rowKey="id" dataSource={current?.FlowNodes || []} columns={columns} />
-      {/* <AuditModal
-        visible={visible.audit}
-        onOk={handleAuditOk}
-        onCancel={() => changeVisible('audit', false)}
-      /> */}
-      <AuditNodeModal
-        roleList={roleList}
-        data={currentNode}
-        visible={visible.auditNode}
-        onOk={handleAuditNodeOk}
-        onCancel={() => changeVisible('auditNode', false)}
-      />
-    </div>
+    <Tabs defaultActiveKey="1">
+      <TabPane tab="表单设计" key="1">
+        <AuditForm onChange={values => onChange(values)} />
+      </TabPane>
+      <TabPane tab="流程控制" key="2">
+        <Flow
+          meta={{ type: 'edit', flowId: 2 }}
+          flowDetail={flowDetail}
+          // onUpdate={node => this.onUpdate(node)}
+        />
+      </TabPane>
+    </Tabs>
+    // <div>
+    //
+    //
+    // </div>
   );
 }
 export default connect(({ flow, loading }) => ({

+ 1 - 1
src/pages/PurchaseAdmin/PurchaseList/List/NewList.js

@@ -135,7 +135,7 @@ function List(props) {
 
   return (
     <div>
-      {/* <AuditForm onChange={values => console.log(values)} /> */}
+      <AuditForm onChange={values => console.log(values)} />
       <Table
         loading={loading || loading2}
         rowKey="id"