Procházet zdrojové kódy

Merge branch 'develop' of http://120.55.44.4:10080/xujunjie/BomWeb into develop

Renxy před 1 rokem
rodič
revize
540139dc66

+ 140 - 55
src/components/AuditForm/ItemAttribute.js

@@ -7,17 +7,19 @@ function ItemAttribute(props) {
   const renderForm = () => {
     let FormContent;
     const formProps = {
-      btns: <Form.Item>
-        <Button type="primary" htmlType="submit" style={{ marginRight: 20 }}>
-          保存
-        </Button>
-      </Form.Item>,
+      btns: (
+        <Form.Item>
+          <Button type="primary" htmlType="submit" style={{ marginRight: 20 }}>
+            保存
+          </Button>
+        </Form.Item>
+      ),
       item,
       onFinish: values => {
         console.log(values);
         onChange?.(values);
-      }
-    }
+      },
+    };
     switch (item.componentName) {
       case 'InnerContactField':
         FormContent = <InnerContactField {...formProps} />;
@@ -40,6 +42,9 @@ function ItemAttribute(props) {
       case 'NumberField':
         FormContent = <NumberField {...formProps} />;
         break;
+      case 'DDDateField':
+        FormContent = <DDDateField {...formProps} />;
+        break;
     }
 
     return FormContent;
@@ -69,10 +74,17 @@ function InnerContactField(props) {
   const { item, btns, onFinish } = props;
   const [form] = Form.useForm();
   const onSwitchChange = checked => {
-    form.setFieldValue("choice", checked ? 1 : 0);
-  }
+    form.setFieldValue('choice', checked ? 1 : 0);
+  };
   return (
-    <Form form={form} labelCol={{ span: 8 }} wrapperCol={{ span: 16 }} autoComplete="off" initialValues={item.props} onFinish={onFinish}>
+    <Form
+      form={form}
+      labelCol={{ span: 8 }}
+      wrapperCol={{ span: 16 }}
+      autoComplete="off"
+      initialValues={item.props}
+      onFinish={onFinish}
+    >
       <Form.Item label="标题" name="label">
         <Input />
       </Form.Item>
@@ -98,7 +110,14 @@ function DepartmentField(props) {
   const { item, btns, onFinish } = props;
   const [form] = Form.useForm();
   return (
-    <Form form={form} labelCol={{ span: 8 }} wrapperCol={{ span: 16 }} autoComplete="off" initialValues={item.props} onFinish={onFinish}>
+    <Form
+      form={form}
+      labelCol={{ span: 8 }}
+      wrapperCol={{ span: 16 }}
+      autoComplete="off"
+      initialValues={item.props}
+      onFinish={onFinish}
+    >
       <Form.Item label="标题" name="label">
         <Input />
       </Form.Item>
@@ -153,7 +172,14 @@ function TextareaField(props) {
   const { item, btns, onFinish } = props;
   const [form] = Form.useForm();
   return (
-    <Form form={form} labelCol={{ span: 8 }} wrapperCol={{ span: 16 }} autoComplete="off" initialValues={item.props} onFinish={onFinish}>
+    <Form
+      form={form}
+      labelCol={{ span: 8 }}
+      wrapperCol={{ span: 16 }}
+      autoComplete="off"
+      initialValues={item.props}
+      onFinish={onFinish}
+    >
       <Form.Item label="标题" name="label">
         <Input />
       </Form.Item>
@@ -175,17 +201,24 @@ function DDSelectField(props) {
     let arr = [];
     tempValue.options.map(item => {
       arr.push(item.value);
-    })
+    });
     if (arr) {
-      arr = arr.filter(item => item)
+      arr = arr.filter(item => item);
       arr = [...new Set(arr)];
-      tempValue.options = arr
+      tempValue.options = arr;
     }
     onFinish?.(tempValue);
-  }
+  };
 
   return (
-    <Form form={form} labelCol={{ span: 8 }} wrapperCol={{ span: 16 }} autoComplete="off" initialValues={item.props} onFinish={handleFinish}>
+    <Form
+      form={form}
+      labelCol={{ span: 8 }}
+      wrapperCol={{ span: 16 }}
+      autoComplete="off"
+      initialValues={item.props}
+      onFinish={handleFinish}
+    >
       <Form.Item label="标题" name="label">
         <Input />
       </Form.Item>
@@ -210,16 +243,23 @@ function DDMultiSelectField(props) {
     let arr = [];
     tempValue.options.map(item => {
       arr.push(item.value);
-    })
+    });
     if (arr) {
-      arr = arr.filter(item => item)
+      arr = arr.filter(item => item);
       arr = [...new Set(arr)];
-      tempValue.options = arr
+      tempValue.options = arr;
     }
     onFinish?.(tempValue);
-  }
+  };
   return (
-    <Form form={form} labelCol={{ span: 8 }} wrapperCol={{ span: 16 }} autoComplete="off" initialValues={item.props} onFinish={handleFinish}>
+    <Form
+      form={form}
+      labelCol={{ span: 8 }}
+      wrapperCol={{ span: 16 }}
+      autoComplete="off"
+      initialValues={item.props}
+      onFinish={handleFinish}
+    >
       <Form.Item label="标题" name="label">
         <Input />
       </Form.Item>
@@ -237,30 +277,57 @@ function DDMultiSelectField(props) {
   );
 }
 
+function DDDateField(props) {
+  const { item, btns, onFinish } = props;
+  const [form] = Form.useForm();
+
+  return (
+    <Form
+      form={form}
+      labelCol={{ span: 8 }}
+      wrapperCol={{ span: 16 }}
+      onFinish={onFinish}
+      autoComplete="off"
+      initialValues={item.props}
+    >
+      <Form.Item label="标题" name="label">
+        <Input />
+      </Form.Item>
+      <Form.Item label="提示文字" name="placeholder">
+        <Input />
+      </Form.Item>
+      {btns}
+    </Form>
+  );
+}
+
 function SelectItem(props) {
   const { value, onChange } = props;
   const [localValue, setLocalValue] = useState([]);
   const pushItem = item => {
-    let tempValue = [...localValue, {
-      id: +new Date(),
-      value: item
-    }];
+    let tempValue = [
+      ...localValue,
+      {
+        id: +new Date(),
+        value: item,
+      },
+    ];
     setLocalValue(tempValue);
     onChange(tempValue);
-  }
+  };
 
   const handleDelete = index => {
     let tempValue = [...localValue];
     tempValue.splice(index, 1);
     setLocalValue(tempValue);
     onChange(tempValue);
-  }
+  };
   const handleInputOnChange = (targetValue, index) => {
     let tempValue = [...localValue];
     tempValue[index].value = targetValue;
     setLocalValue(tempValue);
     onChange(tempValue);
-  }
+  };
   useEffect(() => {
     let tempValue = value.map(item => ({ id: +new Date(), value: item }));
     setLocalValue(tempValue);
@@ -268,46 +335,64 @@ function SelectItem(props) {
   }, []);
 
   return (
-    <div style={{
-      minHeight: 40,
-      display: 'flex',
-      flexDirection: 'column'
-    }}>
+    <div
+      style={{
+        minHeight: 40,
+        display: 'flex',
+        flexDirection: 'column',
+      }}
+    >
       <div>
-        <div style={{
-          fontSize: 4,
-          color: '#40a9ff',
-          cursor: 'pointer',
-          lineHeight: '32px'
-        }} onClick={() => { pushItem('') }}>添加选项</div>
+        <div
+          style={{
+            fontSize: 4,
+            color: '#40a9ff',
+            cursor: 'pointer',
+            lineHeight: '32px',
+          }}
+          onClick={() => {
+            pushItem('');
+          }}
+        >
+          添加选项
+        </div>
       </div>
       <div style={{ minHeight: 20 }}>
-        {
-          localValue.map((item, index) =>
-            <div style={{
+        {localValue.map((item, index) => (
+          <div
+            style={{
               display: 'flex',
               justifyContent: 'center',
               alignItems: 'center',
-              marginBottom: 5
+              marginBottom: 5,
             }}
-              key={item.id}
-            >
-              <Input style={{ marginRight: 10 }} value={item.value} onChange={e => handleInputOnChange(e.target.value, index)} />
-              <DeleteOutlined
-                onClick={() => handleDelete(index)}
-              />
-            </div>)
-        }
+            key={item.id}
+          >
+            <Input
+              style={{ marginRight: 10 }}
+              value={item.value}
+              onChange={e => handleInputOnChange(e.target.value, index)}
+            />
+            <DeleteOutlined onClick={() => handleDelete(index)} />
+          </div>
+        ))}
       </div>
-    </div >
-  )
+    </div>
+  );
 }
 
 function NumberField(props) {
   const { item, btns, onFinish } = props;
   const [form] = Form.useForm();
   return (
-    <Form form={form} labelCol={{ span: 8 }} wrapperCol={{ span: 16 }} autoComplete="off" initialValues={item.props} onFinish={onFinish}>
+    <Form
+      form={form}
+      labelCol={{ span: 8 }}
+      wrapperCol={{ span: 16 }}
+      autoComplete="off"
+      initialValues={item.props}
+      onFinish={onFinish}
+    >
       <Form.Item label="标题" name="label">
         <Input />
       </Form.Item>

+ 14 - 3
src/components/AuditForm/constant.js

@@ -6,6 +6,7 @@ import {
   BorderOutlined,
   BlockOutlined,
   FieldNumberOutlined,
+  InsertRowAboveOutlined,
 } from '@ant-design/icons';
 
 export const COMPONENT_LIST = [
@@ -16,7 +17,7 @@ export const COMPONENT_LIST = [
       label: '联系人',
       placeholder: '请选择联系人',
       required: false,
-      choice: '0'
+      choice: '0',
     },
   },
   {
@@ -26,7 +27,7 @@ export const COMPONENT_LIST = [
       label: '选择部门',
       placeholder: '请选择部门',
       required: false,
-      choice: '0'
+      choice: '0',
     },
   },
   {
@@ -74,7 +75,17 @@ export const COMPONENT_LIST = [
       label: '数字输入框',
       placeholder: '请输入',
       required: false,
-      unit: ''
+      unit: '',
+    },
+  },
+  {
+    componentName: 'DDDateField',
+    icon: <InsertRowAboveOutlined />,
+    props: {
+      label: '日历控件',
+      placeholder: '请选择日期',
+      required: false,
+      unit: '',
     },
   },
 ];

+ 8 - 2
src/components/DDComponents/DDDateField/index.js

@@ -2,12 +2,18 @@ import React from 'react';
 import { DatePicker } from 'antd';
 
 function DDDateField(props) {
-  const { format, disabled, onChange } = props;
+  const { format = '', disabled, onChange } = props;
 
   const handleChange = date => {
     onChange?.(date.format('YYYY-MM-DD'));
   };
-  return <DatePicker disabled={disabled} format={format.replace("yyyy","YYYY").replace("dd","DD")} onChange={handleChange} />;
+  return (
+    <DatePicker
+      disabled={disabled}
+      format={format.replace('yyyy', 'YYYY').replace('dd', 'DD')}
+      onChange={handleChange}
+    />
+  );
 }
 
 export default DDDateField;

+ 36 - 25
src/pages/Detail/FlowModal.js

@@ -385,19 +385,16 @@ function FlowModal(props) {
 
   const getDescription = node => {
     let str = `审批人:${node.AuditorUser?.CName || '-'}`;
-    if (node.desc) {
-      return (
+    return (
+      <div>
+        审批人:{node.AuditorUser?.CName || '-'}
         <div>
-          {str}
-          <div>
-            <Tooltip title={node.desc}>
-              <span style={{ color: '#1A73E8', textDecoration: 'undeline' }}>审批意见</span>
-            </Tooltip>
-          </div>
+          <span style={{ color: '#1A73E8', textDecoration: 'undeline' }}>
+            审批意见:{node.desc || '-'}
+          </span>
         </div>
-      );
-    }
-    return str;
+      </div>
+    );
   };
 
   const filterState = () => {
@@ -548,20 +545,34 @@ function FlowModal(props) {
               />
             </div>
             {/* <Spin spinning={loading.global}> */}
-            {stepsData.map((item, idx) => (
-              <div key={`${item.name}_${idx}`} style={{ marginBottom: '20px' }}>
-                <div style={{ marginBottom: '4px' }}>{item.name}</div>
-                <Steps size="small" current={item.current} status={item.status}>
-                  {item.list.map(node => (
-                    <Step
-                      key={`${node.id}_${node.node}`}
-                      title={node.node}
-                      description={getDescription(node)}
-                    />
-                  ))}
-                </Steps>
-              </div>
-            ))}
+            <div
+              style={{
+                display: 'flex',
+                justifyContent: 'space-around',
+                maxHeight: '300px',
+                overflow: 'auto',
+              }}
+            >
+              {stepsData.map((item, idx) => (
+                <div key={`${item.name}_${idx}`} style={{ marginTop: '20px', display: 'inline' }}>
+                  <div style={{ marginBottom: '4px' }}>{item.name}</div>
+                  <Steps
+                    direction="vertical"
+                    size="small"
+                    current={item.current}
+                    status={item.status}
+                  >
+                    {item.list.map(node => (
+                      <Step
+                        key={`${node.id}_${node.node}`}
+                        title={node.node}
+                        description={getDescription(node)}
+                      />
+                    ))}
+                  </Steps>
+                </div>
+              ))}
+            </div>
             {/* </Spin> */}
           </Col>
         </Row>

+ 57 - 47
src/pages/Detail/Index.js

@@ -1,5 +1,5 @@
 import React, { useEffect, useState, useRef, useMemo } from 'react';
-import { UnorderedListOutlined, PlusOutlined } from '@ant-design/icons';
+import { UnorderedListOutlined, PlusOutlined, InfoOutlined } from '@ant-design/icons';
 import { Button, Modal, message, Alert, Avatar } from 'antd';
 import { connect } from 'dva';
 import styles from './Index.less';
@@ -512,7 +512,7 @@ function Detail(props) {
   }, [versionList]);
 
   return (
-    <div>
+    <>
       <div className={styles.top}>
         <div>
           <Button type="primary" style={{ marginRight: 20 }} onClick={() => setFlowVisible(true)}>
@@ -573,54 +573,64 @@ function Detail(props) {
           onChange={e => exportExcl(e.target.files)}
         />
       </div>
-      <TimeNode
-        flow={flow}
-        flowDetail={flowDetail}
-        isAuditor={isAuditor}
-        version={version}
-        templateId={templateId}
-        projectId={projectId}
-        setAuditVisible={setAuditVisible}
-      ></TimeNode>
-      <div
-        className={styles.content}
-        style={{
-          // 合同清单先显示附件再显示清单详情
-          flexDirection: version?.TemplateNodeInfo?.flow_id == 9 ? 'column-reverse' : 'column',
-        }}
-      >
-        {/* 判断是否为比对模式 */}
-        {compareList.length == 2 ? (
-          <>
-            <Alert
-              message={`比对结果:${updateCount.diff}项差异。${updateCount.add}项新增`}
-              type="info"
-            />
-            <div className={styles.sheetBox}>{compareList.map(renderSheetDom)}</div>
-          </>
-        ) : (
-          <div className={styles.sheetBox}>
-            {version.id && (
-              <LuckySheet
-                className={styles.sheet}
-                ref={sheetRef}
-                onClickCell={onClickCell}
-                version={version}
-                templateId={templateId}
-                getUser={getUser}
-                onUpdate={onUpdate}
-                onDelSheet={onDelSheet}
+      <div style={{ display: 'flex' }}>
+        <div
+          className={styles.content}
+          style={{
+            width: '100%',
+            // 合同清单先显示附件再显示清单详情
+            flexDirection: version?.TemplateNodeInfo?.flow_id == 9 ? 'column-reverse' : 'column',
+          }}
+        >
+          {/* 判断是否为比对模式 */}
+          {compareList.length == 2 ? (
+            <>
+              <Alert
+                message={`比对结果:${updateCount.diff}项差异。${updateCount.add}项新增`}
+                type="info"
               />
-            )}
-          </div>
-        )}
+              <div className={styles.sheetBox}>{compareList.map(renderSheetDom)}</div>
+            </>
+          ) : (
+            <div className={styles.sheetBox}>
+              {version.id && (
+                <LuckySheet
+                  className={styles.sheet}
+                  ref={sheetRef}
+                  onClickCell={onClickCell}
+                  version={version}
+                  templateId={templateId}
+                  getUser={getUser}
+                  onUpdate={onUpdate}
+                  onDelSheet={onDelSheet}
+                />
+              )}
+            </div>
+          )}
 
-        <FormAndFilesNode
-          formData={version?.ding_schema}
-          excelFileList={excelFileList}
+          <FormAndFilesNode
+            formData={version?.ding_schema}
+            excelFileList={excelFileList}
+            version={version}
+          />
+        </div>
+        <TimeNode
+          flow={flow}
+          flowDetail={flowDetail}
+          isAuditor={isAuditor}
           version={version}
-        />
+          templateId={templateId}
+          projectId={projectId}
+          setAuditVisible={setAuditVisible}
+          stepDirection="vertical"
+          style={{
+            maxWidth: '20%',
+            display: 'inline',
+            marginLeft: '20px',
+          }}
+        ></TimeNode>
       </div>
+
       <CommentContent
         title="单元格沟通记录"
         comment={comment}
@@ -695,7 +705,7 @@ function Detail(props) {
         luckysheet={sheetRef}
         templateId={templateId}
       />
-    </div>
+    </>
   );
 }
 

+ 20 - 16
src/pages/Detail/TimeNode.js

@@ -12,7 +12,7 @@ function TimeNode(props) {
   const {
     isAuditor,
     flowDetail,
-
+    style,
     flow,
     versionList,
     version,
@@ -20,7 +20,7 @@ function TimeNode(props) {
     setAuditVisible,
     projectId,
     dispatch,
-
+    stepDirection,
     currentUser,
   } = props;
   const { current, list, active } = flow;
@@ -29,25 +29,29 @@ function TimeNode(props) {
     let str = node?.AuditRoleInfo
       ? `审批人:${node?.AuditRoleInfo.Name || '-'}`
       : `审批人:${node?.AuditorUser.CName || '-'}`;
-    if (node.desc) {
-      return (
+
+    return (
+      <div>
+        {str}
         <div>
-          {str}
-          <div>
-            <Tooltip title={node.desc}>
-              <span style={{ color: '#1A73E8', textDecoration: 'undeline' }}>审批意见</span>
-            </Tooltip>
-          </div>
+          <span style={{ color: '#1A73E8', textDecoration: 'undeline' }}>
+            审批意见:{node.desc || '-'}
+          </span>
         </div>
-      );
-    }
-    return str;
+      </div>
+    );
+
+    // return str;
   };
 
   if (!list || list.FlowNodes?.length != 0) {
     return (
-      <>
-        <Steps current={current} status={active == 0 ? 'error' : 'process'}>
+      <div style={style}>
+        <Steps
+          direction={stepDirection || 'horizontal'}
+          current={current}
+          status={active == 0 ? 'error' : 'process'}
+        >
           {list.FlowNodes.map(item => (
             <Step key={item.id} title={item.node} description={getDescription(item)} />
           ))}
@@ -62,7 +66,7 @@ function TimeNode(props) {
             </Button>
           </div>
         )}
-      </>
+      </div>
     );
   }
   // else {