xujunjie 2 лет назад
Родитель
Сommit
751f251d10

+ 2 - 1
src/components/DDComponents/InnerContactField/index.js

@@ -5,11 +5,12 @@ import { connect } from 'dva';
 const { Option } = Select;
 
 function InnerContactField(props) {
-  const { userList } = props;
+  const { userList, onChange } = props;
 
   return (
     <Select
       showSearch
+      onChange={onChange}
       filterOption={(input, option) => option.children.toLowerCase().includes(input.toLowerCase())}
     >
       {userList.map(item => (

+ 19 - 0
src/components/DDComponents/PhoneField/index.js

@@ -0,0 +1,19 @@
+import React from 'react';
+import { Input, Row, Col, Select } from 'antd';
+import { connect } from 'dva';
+
+const { Option } = Select;
+
+function PhoneField(props) {
+  const { onChange } = props;
+  return (
+    <Input.Group size="large">
+      <Select defaultValue="+86">
+        <Option value="+86">+86</Option>
+      </Select>
+      <Input style={{ width: '80%' }} {...props} onChange={e => onChange(e.target.value)} />
+    </Input.Group>
+  );
+}
+
+export default PhoneField;

+ 79 - 0
src/components/DDComponents/TableField/index.js

@@ -0,0 +1,79 @@
+import { Button } from 'antd';
+import React, { useMemo } from 'react';
+import DDComponents from '../index';
+import style from './index.less';
+
+function TableField(props) {
+  const { item, value, onChange } = props;
+
+  const getEmptyValue = () => {
+    return item.children.map(children => ({
+      name: children.props.id,
+      value: '',
+    }));
+  };
+  const getChildren = (item, data) => {
+    let cur = data.find(d => d.name == item.props.id);
+    const childrenChange = value => {
+      cur.value = value;
+      onChange(JSON.stringify(localValue));
+    };
+    return DDComponents({ item, onChange: childrenChange, value: cur.value });
+  };
+
+  const localValue = useMemo(() => {
+    let v = [];
+    try {
+      v = JSON.parse(value);
+    } catch (error) {}
+    if (v.length == 0) {
+      let data = getEmptyValue();
+      v.push(data);
+    }
+    return v;
+  }, [value]);
+
+  const addRow = () => {
+    let newValue = [...localValue, getEmptyValue()];
+
+    onChange(JSON.stringify(newValue));
+  };
+
+  const removeRow = index => {
+    let newValue = [...localValue];
+    newValue.splice(index, 1);
+
+    onChange(JSON.stringify(newValue));
+  };
+
+  return (
+    <div>
+      <table className={style.table}>
+        <tr>
+          <th></th>
+          {item.children.map(item => (
+            <th>{item.props.label}</th>
+          ))}
+          <th>操作</th>
+        </tr>
+        {localValue.map((curItem, index) => (
+          <tr>
+            <td>{index + 1}</td>
+            {item.children.map(item => (
+              <td>{getChildren(item, curItem)}</td>
+            ))}
+            <td>
+              {localValue.length > 1 && <a onClick={() => removeRow(index)}>删除</a>}
+              {/* <a>复制</a> */}
+            </td>
+          </tr>
+        ))}
+      </table>
+      <Button style={{ marginTop: 20 }} onClick={addRow}>
+        {item.props.actionName}
+      </Button>
+    </div>
+  );
+}
+
+export default TableField;

+ 16 - 0
src/components/DDComponents/TableField/index.less

@@ -0,0 +1,16 @@
+.table {
+  width: 100%;
+  td {
+    padding: 10px;
+    border-bottom: 1px solid rgba(0, 0, 0, 0.06);
+  }
+  th {
+    padding: 10px;
+    color: #000000d9;
+    font-weight: 500;
+    text-align: left;
+    background: #fafafa;
+    border-bottom: 1px solid rgba(0, 0, 0, 0.06);
+    transition: background 0.3s ease;
+  }
+}

+ 143 - 1
src/components/DDComponents/index.js

@@ -1,3 +1,145 @@
 import InnerContactField from './InnerContactField';
+import { Button, Input, InputNumber, Select, DatePicker, Rate, Upload } from 'antd';
+import { PlusOutlined } from '@ant-design/icons';
+import TableField from './TableField';
+import PhoneField from './PhoneField';
 
-export { InnerContactField };
+const { Option } = Select;
+const { RangePicker } = DatePicker;
+
+export default function DDComponents(props) {
+  const { item, onChange, value } = props;
+  const {
+    id,
+    label,
+    bizAlias,
+    required,
+    placeholder,
+    options,
+    align,
+    statField,
+    hideLabel,
+    objOptions,
+    format,
+    pushToAttendance,
+    labelEditableFreeze,
+    requiredEditableFreeze,
+    unit,
+    extract,
+    link,
+    payEnable,
+    bizType,
+    childFieldVisible,
+    notPrint,
+    verticalPrint,
+    hiddenInApprovalDetail,
+    disabled,
+    notUpper,
+    children, // 子控件
+  } = item.props;
+  let component = null;
+  switch (item.componentName) {
+    case 'TextField': //单行输入
+      component = <Input disabled={disabled} placeholder={placeholder} onChange={onChange} />;
+      break;
+    case 'TextareaField': //多行输入
+      component = (
+        <Input.TextArea disabled={disabled} placeholder={placeholder} onChange={onChange} />
+      );
+      break;
+    case 'NumberField': //数字输入
+      component = (
+        <InputNumber
+          disabled={disabled}
+          formatter={value => `${value}${unit || ''}`}
+          value={value}
+          onChange={e => {
+            console.log(e);
+            onChange?.(e);
+          }}
+        />
+      );
+      break;
+    case 'DDSelectField': //单选框
+      component = (
+        <Select style={{ width: '100%' }} onChange={onChange}>
+          {options?.map(cur => {
+            if (typeof cur == 'string') {
+              cur = JSON.parse(cur);
+            }
+
+            return (
+              <Option key={cur.key} value={cur.key}>
+                {cur.value}
+              </Option>
+            );
+          })}
+        </Select>
+      );
+      break;
+    case 'DDMultiSelectField': //多选框
+      component = (
+        <Select mode="multiple" allowClear style={{ width: '100%' }} onChange={onChange}>
+          {options?.map(cur => {
+            if (typeof cur == 'string') {
+              cur = JSON.parse(cur);
+            }
+
+            return (
+              <Option key={cur.key} value={cur.key}>
+                {cur.value}
+              </Option>
+            );
+          })}
+        </Select>
+      );
+      break;
+    case 'DDDateField': //日期控件
+      component = <DatePicker format={format} onChange={onChange} />;
+      break;
+    case 'DDDateRangeField': //时间区间控件
+      component = <RangePicker format={format} onChange={onChange} />;
+      break;
+    case 'TextNote': //文本说明控件
+      // component = <p style={{textAlign: align}}></p>
+      break;
+    case 'PhoneField': //电话控件
+      component = <PhoneField onChange={onChange} />;
+      break;
+    case 'DDPhotoField': //图片控件
+      component = (
+        <Upload>
+          <Button icon={<PlusOutlined />}>添加图片</Button>
+        </Upload>
+      );
+      break;
+    case 'MoneyField': //金额控件
+      component = <Input placeholder={placeholder} onChange={onChange} />;
+      break;
+    case 'TableField': //明细控件
+      component = <TableField item={item} />;
+      break;
+    case 'DDAttachment': //附件
+      // component = (
+      //   <Upload>
+      //     <Button icon={<PlusOutlined />}>添加附件</Button>
+      //   </Upload>
+      // );
+      break;
+    case 'InnerContactField': //联系人控件
+      component = <InnerContactField onChange={onChange}></InnerContactField>;
+      break;
+    case 'DepartmentField': //部门控件
+      break;
+    case 'RelateField': //关联审批单
+      break;
+    case 'AddressField': //省市区控件
+      break;
+    case 'StarRatingField': //评分控件
+      break;
+    case 'FormRelateField': //关联控件
+      break;
+  }
+
+  return component;
+}

+ 5 - 247
src/pages/PurchaseAdmin/PurchaseList/Detail/AuditDetailed.js

@@ -1,12 +1,8 @@
-import { Button, Input, InputNumber, Select, DatePicker, Rate, Upload } from 'antd';
-import { InnerContactField } from '@/components/DDComponents';
-import { PlusOutlined } from '@ant-design/icons';
+import DDComponents from '@/components/DDComponents';
 import React, { useMemo, useState } from 'react';
 import { Form } from '@ant-design/compatible';
 import '@ant-design/compatible/assets/index.css';
 
-const { Option } = Select;
-const { RangePicker } = DatePicker;
 const layout = {
   labelCol: {
     span: 8,
@@ -43,29 +39,6 @@ const AuditDetailed = props => {
   const onFinish = values => {
     console.log(values);
   };
-  // const selectBefore = (
-  //   <Select defaultValue="是" className="select-before">
-  //     <Option value="是">是</Option>
-  //     <Option value="否">否</Option>
-  //   </Select>
-  // );
-  // const prefixSelector = (
-  //   <Form.Item name="prefix" noStyle>
-  //     <Select style={{ width: 70 }}>
-  //       <Option value="86">+86</Option>
-  //       <Option value="87">+87</Option>
-  //     </Select>
-  //   </Form.Item>
-  // );
-
-  // const children = [];
-  // for (let i = 10; i < 36; i++) {
-  //   children.push(<Option key={i.toString(36) + i}>{i.toString(36) + i}</Option>);
-  // }
-
-  // const handleChange = value => {
-  //   console.log(`selected ${value}`);
-  // };
 
   const GetComponent = item => {
     const {
@@ -107,239 +80,24 @@ const AuditDetailed = props => {
         if (currentValue != value) return null;
       }
     }
-    //{ id: startId, label: startLabel, upper, unit } = statField;是个array
-    //objOptions ={value}
-    // children ={componentName, props ={ id,label,bizAlias,required,}}
-
-    let component;
-    switch (item.componentName) {
-      case 'TextField': //单行输入
-        component = <Input disabled={disabled} placeholder={placeholder} />;
-        break;
-      case 'TextareaField': //多行输入
-        component = <Input.TextArea disabled={disabled} placeholder={placeholder} />;
-        break;
-      case 'NumberField': //数字输入
-        component = <InputNumber disabled={disabled} formatter={value => `${value}${unit}`} />;
-        break;
-      case 'DDSelectField': //单选框
-        component = (
-          <Select style={{ width: '100%' }} onChange={e => console.log(e)}>
-            {options.map(cur => {
-              if (typeof cur == 'string') {
-                cur = JSON.parse(cur);
-              }
-
-              return (
-                <Option key={cur.key} value={cur.key}>
-                  {cur.value}
-                </Option>
-              );
-            })}
-          </Select>
-        );
-        break;
-      case 'DDMultiSelectField': //多选框
-        component = (
-          <Select mode="multiple" allowClear style={{ width: '100%' }}>
-            {options.map(cur => {
-              if (typeof cur == 'string') {
-                cur = JSON.parse(cur);
-              }
 
-              return (
-                <Option key={cur.key} value={cur.key}>
-                  {cur.value}
-                </Option>
-              );
-            })}
-          </Select>
-        );
-        break;
-      case 'DDDateField': //日期控件
-        component = <DatePicker format={format} />;
-        break;
-      case 'DDDateRangeField': //时间区间控件
-        component = <RangePicker format={format} />;
-        break;
-      case 'TextNote': //文本说明控件
-        // component = <p style={{textAlign: align}}></p>
-        break;
-      case 'PhoneField': //电话控件
-        component = <Input type="phone" disabled={disabled} placeholder={placeholder} />;
-        break;
-      case 'DDPhotoField': //图片控件
-        component = (
-          <Upload>
-            <Button icon={<PlusOutlined />}>添加图片</Button>
-          </Upload>
-        );
-        break;
-      case 'MoneyField': //金额控件
-        component = <Input placeholder={placeholder} />;
-        break;
-      case 'TableField': //明细控件
-        break;
-      case 'DDAttachment': //附件
-        component = (
-          <Upload>
-            <Button icon={<PlusOutlined />}>添加附件</Button>
-          </Upload>
-        );
-        break;
-      case 'InnerContactField': //联系人控件
-        component = <InnerContactField></InnerContactField>;
-        break;
-      case 'DepartmentField': //部门控件
-        break;
-      case 'RelateField': //关联审批单
-        break;
-      case 'AddressField': //省市区控件
-        break;
-      case 'StarRatingField': //评分控件
-        break;
-      case 'FormRelateField': //关联控件
-        break;
-    }
+    const component = DDComponents({ item });
     if (!component) return null;
     return (
-      <Form.Item
-        // name={id}
-        label={bizAlias || label}
-        // rules={[
-        //   {
-        //     required,
-        //   },
-        // ]}
-      >
+      <Form.Item label={bizAlias || label}>
         {form.getFieldDecorator(id, {
           rules: [{ required }],
         })(component)}
-        {/* {component} */}
         {notUpper == 1 && <p>大写</p>}
       </Form.Item>
     );
   };
 
   return (
-    <Form
-      style={{ height: '300px', overflowY: 'scroll' }}
-      layout="vertical"
-      autoComplete="off"
-      form={form}
-      onFinish={onFinish}
-    >
-      {/* <Form.Item name={'DDSelectField_4XTULZ7SMI80'} label="单选框">
-        <Select
-          style={{ width: '30%' }}
-          defaultValue="Home"
-          onChange={e => {
-            form.setFieldsValue({
-              DDSelectField_4XTULZ7SMI80: e,
-            });
-          }}
-        >
-          <Option value="option_0">option_0</Option>
-          <Option value="option_1">option_1</Option>
-        </Select>
-      </Form.Item> */}
-      {/* <Form.Item
-        name={['user', 'name']}
-        label="单行输入"
-        rules={[
-          {
-            required: true,
-          },
-        ]}
-      >
-        <Input placeholder="Basic usage" />
-      </Form.Item>
-      <Form.Item
-        name={['user', 'name']}
-        label="金额输入"
-        rules={[
-          {
-            required: true,
-          },
-        ]}
-      >
-        <Input placeholder="Basic usage" />
-        <p>大写</p>
-      </Form.Item>
-      <Form.Item
-        name={['user', 'age']}
-        label="数字输入"
-        rules={[
-          {
-            type: 'number',
-            min: 0,
-            max: 99,
-          },
-        ]}
-      >
-        <InputNumber placeholder="Basic usage" />
-      </Form.Item>
-      <Form.Item
-        name={['user', 'introduction']}
-        tooltip="This is a required field"
-        label="多行输入"
-      >
-        <Input.TextArea placeholder="Basic usage" />
-      </Form.Item>
-      <Form.Item
-        name="phone"
-        label="Phone Number"
-        rules={[{ required: true, message: 'Please input your phone number!' }]}
-      >
-        <Input addonBefore={prefixSelector} style={{ width: '100%' }} />
-      </Form.Item>
-      <Form.Item name={['user', 'introduction']} label="单选框">
-        <Select style={{ width: '30%' }} defaultValue="Home">
-          <Option value="Home">Home</Option>
-          <Option value="Company">Company</Option>
-        </Select>
-      </Form.Item>
-      <Form.Item name={['user', 'introduction']} label="多选框">
-        <Select
-          mode="multiple"
-          allowClear
-          style={{ width: '100%' }}
-          placeholder="Please select"
-          defaultValue={['a10', 'c12']}
-          onChange={handleChange}
-        >
-          {children}
-        </Select>
-      </Form.Item>
-      <Form.Item name={['user', 'introduction']} label="时间组件">
-        <DatePicker onChange={() => {}} />
-      </Form.Item>
-      <Form.Item name={['user', 'introduction']} label="开始时间">
-        <DatePicker onChange={() => {}} />
-        <Select style={{ width: '30%' }} defaultValue="Home">
-          <Option value="Home">上午</Option>
-          <Option value="Company">下午</Option>
-        </Select>
-      </Form.Item>
-      <Form.Item name={['user', 'introduction']} label="结束时间">
-        <DatePicker onChange={() => {}} />
-        <Select style={{ width: '30%' }} defaultValue="Home">
-          <Option value="Home">上午</Option>
-          <Option value="Company">下午</Option>
-        </Select>
-      </Form.Item>
-      <Form.Item name={['user', 'introduction']} label="评分">
-        <Rate />
-      </Form.Item> */}
-      {/* <Form.Item wrapperCol={{ ...layout.wrapperCol, offset: 8 }}>
-        <Button type="primary" htmlType="submit">
-          Submit
-        </Button>
-      </Form.Item> */}
-
+    <Form style={{ height: '300px', overflowY: 'scroll' }} layout="vertical" autoComplete="off">
       {items.map(item => GetComponent(item))}
     </Form>
   );
 };
 
-export default Form.create()(AuditDetailed);
+export default AuditDetailed;

+ 25 - 2
src/pages/PurchaseAdmin/PurchaseList/Detail/CommitAuditModal.js

@@ -6,6 +6,7 @@ import { isArray, result } from 'lodash';
 import { useForm } from 'rc-field-form';
 import { async } from '@antv/x6/lib/registry/marker/async';
 import AuditDetailed from './AuditDetailed';
+import { Form as Form3x } from '@ant-design/compatible';
 
 const { TextArea } = Input;
 const { Option } = Select;
@@ -20,6 +21,7 @@ function CommitAuditModal(props) {
   const [formData, setFromData] = useState({});
   const [auditList, setAuditList] = useState([]); //用于创建Tabs表单
   const [form] = Form.useForm();
+  const formDataRef = useRef([]);
 
   const res = {
     result: {
@@ -56,6 +58,7 @@ function CommitAuditModal(props) {
                 },
               },
               {
+                componentName: 'PhoneField',
                 props: {
                   id: 'PhoneField_SEIS8H2KAQO0',
                   label: '电话',
@@ -244,11 +247,31 @@ function CommitAuditModal(props) {
         return flowDetail.nodes.find?.(item => item.Id == Id);
       })
       .filter(item => item);
-    setAuditList(addAuditList);
+    // .forEach(item => {
+    // });
+    console.log(addAuditList);
+
+    setAuditList(
+      addAuditList.map((item, index) => {
+        let FormComponents = Form3x.create({
+          onValuesChange: (props, changedValues, allValues) => {
+            console.log(allValues);
+            let formData = formDataRef.current;
+            formData[index] = allValues;
+          },
+        })(AuditDetailed);
+
+        return {
+          ...item,
+          FormComponents: <FormComponents items={schemaContent.items} />,
+        };
+      })
+    );
   };
 
   const onFinish = async () => {
     var fieldsValue = await form.validateFields();
+    console.log(formDataRef.current);
     let hasFlowId = true; //是否都绑定审批节点
     const getFlowPath = node => {
       //[134, 135]
@@ -382,7 +405,7 @@ function CommitAuditModal(props) {
           //   <AuditDetailed />
           // </TabPane>
           <TabPane tab={schemaContent.title} key={`${item.Id}_${item.label}`}>
-            <AuditDetailed items={schemaContent.items} />
+            {item.FormComponents}
           </TabPane>
         ))}
       </Tabs>