Browse Source

feat: 记录点击的行和展开的行

ZhaoJun 1 year ago
parent
commit
480381cdc1
2 changed files with 279 additions and 342 deletions
  1. 275 342
      src/pages/Detail/FlowModal.js
  2. 4 0
      src/pages/Detail/Index.less

+ 275 - 342
src/pages/Detail/FlowModal.js

@@ -1,4 +1,4 @@
-import React, { useEffect, useState, useRef, useMemo, memo } from 'react';
+import React, {useEffect, useState, useRef, useMemo, memo} from 'react';
 import {
   Modal,
   Input,
@@ -18,24 +18,21 @@ import {
   Tooltip,
 } from 'antd';
 import Flow from '@/components/Flow/index';
-import { connect } from 'dva';
-import { GetTokenFromUrl, getToken } from '@/utils/utils';
-import { MODELS, useXFlowApp, useModelAsync } from '@antv/xflow';
-import { CheckOutlined } from '@ant-design/icons';
+import {connect} from 'dva';
+import {GetTokenFromUrl, getToken} from '@/utils/utils';
+import {MODELS, useXFlowApp, useModelAsync} from '@antv/xflow';
+import {CheckOutlined} from '@ant-design/icons';
 import {
-  queryDelPurchaseExcel,
-  queryDingInstanceDetail,
-  queryRecordSheet,
-  queryTrySeal,
-  queryVserionByNode,
+  queryDelPurchaseExcel, queryDingInstanceDetail, queryRecordSheet, queryTrySeal, queryVserionByNode,
 } from '@/services/boom';
-import { async } from '@antv/x6/lib/registry/marker/async';
+import {async} from '@antv/x6/lib/registry/marker/async';
 import VersionModal from './VersionModal';
+import styles from './Index.less'
 
-const { Option } = Select;
-const { Step } = Steps;
+const {Option} = Select;
+const {Step} = Steps;
 
-const { TextArea } = Input;
+const {TextArea} = Input;
 const localData = JSON.parse(localStorage.ggDetaiData || '{}');
 const PAGE_SIZE = 8;
 let controller = new AbortController();
@@ -44,10 +41,7 @@ let controller = new AbortController();
 function FlowModal(props) {
   let token = getToken();
   const SELECT_TYPE = {
-    NAME: '0',
-    TYPE: '1',
-    CREATOR: '2',
-    STATE: '3',
+    NAME: '0', TYPE: '1', CREATOR: '2', STATE: '3',
   };
   const {
     visible,
@@ -75,6 +69,7 @@ function FlowModal(props) {
   const [versionVisible, setVersionVisible] = useState(false);
   const [selectType, setSelectType] = useState(SELECT_TYPE.NAME);
   const [inputValue, setInputValue] = useState();
+  const [expandedRowKey, setExpandedRowKey] = useState([])
 
   const [sealLoading, setSealLoading] = useState(false);
   // const [currentTempNodeId, setCurrentTempNodeId] = useState();
@@ -83,12 +78,10 @@ function FlowModal(props) {
   const graphData = useMemo(() => {
     if (!flowDetail) return;
     let nodes = flowDetail.nodes?.map(item => ({
-      ...item,
-      isCheck: item.Id == version.template_node_id,
+      ...item, isCheck: item.Id == version.template_node_id,
     }));
     return {
-      nodes,
-      edges: flowDetail.edges,
+      nodes, edges: flowDetail.edges,
     };
   }, [flowDetail, version.template_node_id]);
 
@@ -115,17 +108,12 @@ function FlowModal(props) {
 
   const onDelVersion = data => {
     Modal.confirm({
-      title: '提示',
-      content: `是否确认删除清单?`,
-      okText: '确定',
-      cancelText: '取消',
-      onOk: async () => {
+      title: '提示', content: `是否确认删除清单?`, okText: '确定', cancelText: '取消', onOk: async () => {
         const res = await queryDelPurchaseExcel(data);
         if (res.code == 200) {
           message.success('删除成功');
           dispatch({
-            type: 'xflow/queryBoomFlowDetail',
-            payload: {
+            type: 'xflow/queryBoomFlowDetail', payload: {
               id: templateId,
             },
           });
@@ -142,18 +130,15 @@ function FlowModal(props) {
       }
       setNodeLoading(true);
       controller = new AbortController();
-      const res = await queryVserionByNode(
-        {
-          template_node_id: template_node_id,
-        },
-        controller.signal
-      );
+      const res = await queryVserionByNode({
+        template_node_id: template_node_id,
+      }, controller.signal);
       controller = null;
       let data = [];
       if (!res.data.excel_version_tree) setData([]);
       res.data.excel_version_tree?.map(arr => {
         if (res.data.flow_id) {
-          data = [...data, { ...arr, flow_id: res.data.flow_id }];
+          data = [...data, {...arr, flow_id: res.data.flow_id}];
         } else {
           data = [...data, arr];
         }
@@ -192,14 +177,9 @@ function FlowModal(props) {
         if (item.audit_status == 2) status = 'error';
       });
       let curNode = flowDetail.nodes.find(item => item.Id == itemDataList[0].template_node_id);
-      const seqList = itemDataList[0].FlowInfo.FlowNodes.filter(
-        item => item.template_node_id == template_node_id
-      ).sort((a, b) => a.seq - b.seq);
+      const seqList = itemDataList[0].FlowInfo.FlowNodes.filter(item => item.template_node_id == template_node_id).sort((a, b) => a.seq - b.seq);
       let obj = {
-        status,
-        current: curid,
-        list: seqList,
-        name: curNode?.label || itemDataList[0].FlowInfo.name,
+        status, current: curid, list: seqList, name: curNode?.label || itemDataList[0].FlowInfo.name,
       };
       return obj;
     });
@@ -211,160 +191,117 @@ function FlowModal(props) {
     let type = item.flow_id ? '/queryAuditRecord' : '/queryAuditExcel';
     console.log(`${file}${type}`, item);
     dispatch({
-      type: `${file}${type}`,
-      payload: {
-        excel_id: item.id,
-        pageSize: 100,
-      },
-      callback: res => {
+      type: `${file}${type}`, payload: {
+        excel_id: item.id, pageSize: 100,
+      }, callback: res => {
         updateSteps(res, item.template_node_id);
       },
     });
   };
 
   const columns = useMemo(() => {
-    return [
-      {
-        title: '名称',
-        width: '20%',
-        render: item => (
-          <span style={{ color: item.audit_status != 0 ? '#9b9b9b' : '' }}>
-            {item.id == version.id && !item.isParent && (
-              <CheckOutlined style={{ marginRight: 10 }} />
-            )}
-            {item.version_no && !item.children?.length
-              ? `${item.version_name}.${item.version_no}`
-              : item.version_name}
-          </span>
-        ),
+    return [{
+      title: '名称', width: '20%', render: item => {
+        console.log('***', item, version.id)
+        return (<>
+              <span style={{color: item.audit_status != 0 ? '#9b9b9b' : ''}}>
+                {(item.id == version.id && !item.isParent) && (<CheckOutlined style={{marginRight: 10}}/>)}
+                {item.version_no && !item.children?.length ? `${item.version_name}.${item.version_no}` : `啊?${item.version_name}`}
+              </span>
+        </>)
       },
-      {
-        title: '创建人',
-        width: '15%',
-        render: item => {
-          return (
-            item.isParent && (
-              <span>{userList.find(cur => cur.ID == item.author)?.CName || '-'}</span>
-            )
-          );
-        },
+    }, {
+      title: '创建人', width: '15%', render: item => {
+        return (item.isParent && (<span>{userList.find(cur => cur.ID == item.author)?.CName || '-'}</span>));
       },
-      {
-        title: '分类',
-        width: '15%',
-        render: item => {
-          return (
-            item.isParent && (
-              <span>{typeOptions.find(cur => cur.id == item.classify_id)?.name}</span>
-            )
-          );
-        },
+    }, {
+      title: '分类', width: '15%', render: item => {
+        return (item.isParent && (<span>{typeOptions.find(cur => cur.id == item.classify_id)?.name}</span>));
       },
-      {
-        title: '状态',
-        width: '15%',
-        render: item => {
-          if (!item.flow_id && item.isParent) return;
-          let style = { color: getColor(item) };
-          let txt = '';
-          let dom = '';
-          switch (item.audit_status) {
-            case 0:
-              txt = '未提交';
-              break;
-            case 1:
-              txt = '待审批';
-              break;
-            case 2:
-              txt = '已拒绝';
-              break;
-            case 3:
-              txt = '已通过';
-              break;
-            case 4:
-              txt = '已提交';
-              break;
-          }
-          if (item.status == 1) txt = '已失效';
+    }, {
+      title: '状态', width: '15%', render: item => {
+        if (!item.flow_id && item.isParent) return;
+        let style = {color: getColor(item)};
+        let txt = '';
+        let dom = '';
+        switch (item.audit_status) {
+          case 0:
+            txt = '未提交';
+            break;
+          case 1:
+            txt = '待审批';
+            break;
+          case 2:
+            txt = '已拒绝';
+            break;
+          case 3:
+            txt = '已通过';
+            break;
+          case 4:
+            txt = '已提交';
+            break;
+        }
+        if (item.status == 1) txt = '已失效';
 
-          // 显示拒绝原因
-          // if (item.audit_comment) {
-          //   dom = (
-          //     <Popover content={item.audit_comment} title="原因">
-          //       {txt}
-          //     </Popover>
-          //   );
-          // } else {
-          dom = txt;
-          // }
-          return item.audit_status != 0 ? (
-            <Button onClick={() => handleChangeClick(item)}>{dom}</Button>
-          ) : (
-            <span style={style}>{dom}</span>
-          );
-        },
+        // 显示拒绝原因
+        // if (item.audit_comment) {
+        //   dom = (
+        //     <Popover content={item.audit_comment} title="原因">
+        //       {txt}
+        //     </Popover>
+        //   );
+        // } else {
+        dom = txt;
+        // }
+        return item.audit_status != 0 ? (<Button onClick={() => handleChangeClick(item)}>{dom}</Button>) : (
+          <span style={style}>{dom}</span>);
       },
-      {
-        title: '印章申请',
-        width: '15%',
-        render: item => {
-          if (!item.flow_id && item.isParent) return;
-          let txt = '';
-          //申请印章成功 1  默认0 失败2
-          switch (item.is_seal_succeed) {
-            case 0:
-              txt = '-';
-              break;
-            case 1:
-              txt = '成功';
-              break;
-            case 2:
-              txt = '失败';
-              break;
-          }
-          return (
-            <Space>
-              <span>{txt}</span>
-              {item.is_seal_succeed == 2 && <a onClick={() => handleRetryClick(item.id)}>重试</a>}
-            </Space>
-          );
-        },
-      },
-      {
-        title: '操作',
-        width: '20%',
-        render: item =>
-          (item.flow_id || !item.isParent) &&
-          item.id != version.id && (
-            <Space>
-              <a
-                onClick={() => {
-                  console.log(item);
-                  onChangeVersion(item);
-                  onClose();
-                }}
-              >
-                加载
-              </a>
-              {item.audit_status == 0 &&
-              item.author == currentUser.ID && ( //自己创建的&&未提交的清单自己可以删除
-                  <a
-                    onClick={() => {
-                      onDelVersion({ excel_id: item.id });
-                    }}
-                  >
-                    删除
-                  </a>
-                )}
-            </Space>
-          ),
+    }, {
+      title: '印章申请', width: '15%', render: item => {
+        if (!item.flow_id && item.isParent) return;
+        let txt = '';
+        //申请印章成功 1  默认0 失败2
+        switch (item.is_seal_succeed) {
+          case 0:
+            txt = '-';
+            break;
+          case 1:
+            txt = '成功';
+            break;
+          case 2:
+            txt = '失败';
+            break;
+        }
+        return (<Space>
+          <span>{txt}</span>
+          {item.is_seal_succeed == 2 && <a onClick={() => handleRetryClick(item.id)}>重试</a>}
+        </Space>);
       },
-    ];
+    }, {
+      title: '操作', width: '20%', render: item => (item.flow_id || !item.isParent) && item.id != version.id && (<Space>
+        <a
+          onClick={() => {
+            onChangeVersion(item);
+            onClose();
+          }}
+        >
+          加载
+        </a>
+        {item.audit_status == 0 && item.author == currentUser.ID && ( //自己创建的&&未提交的清单自己可以删除
+          <a
+            onClick={() => {
+              onDelVersion({excel_id: item.id});
+            }}
+          >
+            删除
+          </a>)}
+      </Space>),
+    },];
   }, [version]);
 
   const handleRetryClick = async id => {
     setNodeLoading(true);
-    const res = await queryTrySeal({ excel_id: id });
+    const res = await queryTrySeal({excel_id: id});
     setNodeLoading(false);
     if (res.data?.errcode != 0) {
       message.error(res.data?.errmsg);
@@ -385,16 +322,14 @@ function FlowModal(props) {
 
   const getDescription = node => {
     let str = `审批人:${node.AuditorUser?.CName || '-'}`;
-    return (
+    return (<div>
+      审批人:{node.AuditorUser?.CName || '-'}
       <div>
-        审批人:{node.AuditorUser?.CName || '-'}
-        <div>
-          <span style={{ color: '#1A73E8', textDecoration: 'undeline' }}>
+          <span style={{color: '#1A73E8', textDecoration: 'undeline'}}>
             审批意见:{node.desc || '-'}
           </span>
-        </div>
       </div>
-    );
+    </div>);
   };
 
   const filterState = () => {
@@ -431,6 +366,19 @@ function FlowModal(props) {
     setShowData(resultData);
   }, [inputValue, data]);
 
+  const setRowClassName = (row) => {
+    const rowId = localStorage.excelId
+
+    if (row.id.toString() === rowId) {
+      return styles.selectedROW;
+    }
+    return ''
+  }
+
+  const handleExpandedRowChange = (expandedRows) => {
+    setExpandedRowKey(expandedRows)
+  }
+
   //列表筛选状态
   const STATE = {
     NOSUBMIT: 0, //未提交
@@ -440,159 +388,146 @@ function FlowModal(props) {
     SUBMIT: 4, //已提交
     FAILURE: 5, //已失效
   };
-  return (
-    <>
-      <Modal
-        // confirmLoading={loading}
-        destroyOnClose
-        title="流程图"
-        visible={visible}
-        onCancel={() => {
-          setSelectType(SELECT_TYPE.NAME);
-          setInputValue('');
-          onClose();
-        }}
-        footer={false}
-        width="98%"
-        // bodyStyle={{ maxHeight: '660px', overflow: 'auto' }}
-      >
-        <Row gutter={8}>
-          <Col span={14}>
-            <Flow meta={{ type: 'view' }} flowDetail={graphData} onSelectNode={handleSelectNode} />
-          </Col>
-          <Col span={10}>
-            <div style={{ fontSize: '16px', marginBottom: '10px' }}>清单列表</div>
-            <div style={{ display: 'flex', justifyContent: 'space-between' }}>
-              <div style={{ width: '60%' }}>
-                <Select
-                  value={selectType}
-                  style={{ width: '30%' }}
-                  onChange={value => {
-                    setSelectType(value);
-                    setInputValue('');
-                  }}
-                >
-                  <Option value={SELECT_TYPE.NAME}>名称:</Option>
-                  <Option value={SELECT_TYPE.TYPE}>分类:</Option>
-                  <Option value={SELECT_TYPE.CREATOR}>创建人:</Option>
-                  <Option value={SELECT_TYPE.STATE}>状态:</Option>
-                </Select>
-                {(selectType == SELECT_TYPE.NAME || selectType == SELECT_TYPE.CREATOR) && (
-                  <Input
-                    style={{ width: '70%' }}
-                    placeholder="请输入"
-                    value={inputValue}
-                    onChange={e => setInputValue(e.target.value)}
-                  />
-                )}
-                {selectType == SELECT_TYPE.TYPE && (
-                  <Select
-                    showSearch
-                    allowClear
-                    style={{ width: '70%' }}
-                    placeholder="请选择分类"
-                    options={typeOptions}
-                    onChange={id => setInputValue(id)}
-                    filterOption={(input, option) =>
-                      (option?.label ?? '').toLowerCase().includes(input.toLowerCase())
-                    }
-                  />
-                )}
-                {selectType == SELECT_TYPE.STATE && (
-                  <Select
-                    showSearch
-                    allowClear
-                    style={{ width: '70%' }}
-                    placeholder="请选择状态"
-                    // options={typeOptions}
-                    onChange={id => setInputValue(id)}
-                  >
-                    <Option value={STATE.NOSUBMIT}>未提交</Option>
-                    <Option value={STATE.NOAPPROVE}>待审批</Option>
-                    <Option value={STATE.REJECT}>已拒绝</Option>
-                    <Option value={STATE.PASS}>已通过</Option>
-                    <Option value={STATE.SUBMIT}>已提交</Option>
-                    <Option value={STATE.FAILURE}>已失效</Option>
-                  </Select>
-                )}
-              </div>
-              {isOut && (
-                <Button type="primary" onClick={() => setVersionVisible(true)}>
-                  新建清单
-                </Button>
-              )}
+  return (<>
+    <Modal
+      // confirmLoading={loading}
+      destroyOnClose
+      title="流程图"
+      visible={visible}
+      onCancel={() => {
+        setSelectType(SELECT_TYPE.NAME);
+        setInputValue('');
+        onClose();
+      }}
+      footer={false}
+      width="98%"
+      // bodyStyle={{ maxHeight: '660px', overflow: 'auto' }}
+    >
+      <Row gutter={8}>
+        <Col span={14}>
+          <Flow meta={{type: 'view'}} flowDetail={graphData} onSelectNode={handleSelectNode}/>
+        </Col>
+        <Col span={10}>
+          <div style={{fontSize: '16px', marginBottom: '10px'}}>清单列表</div>
+          <div style={{display: 'flex', justifyContent: 'space-between'}}>
+            <div style={{width: '60%'}}>
+              <Select
+                value={selectType}
+                style={{width: '30%'}}
+                onChange={value => {
+                  setSelectType(value);
+                  setInputValue('');
+                }}
+              >
+                <Option value={SELECT_TYPE.NAME}>名称:</Option>
+                <Option value={SELECT_TYPE.TYPE}>分类:</Option>
+                <Option value={SELECT_TYPE.CREATOR}>创建人:</Option>
+                <Option value={SELECT_TYPE.STATE}>状态:</Option>
+              </Select>
+              {(selectType == SELECT_TYPE.NAME || selectType == SELECT_TYPE.CREATOR) && (<Input
+                style={{width: '70%'}}
+                placeholder="请输入"
+                value={inputValue}
+                onChange={e => setInputValue(e.target.value)}
+              />)}
+              {selectType == SELECT_TYPE.TYPE && (<Select
+                showSearch
+                allowClear
+                style={{width: '70%'}}
+                placeholder="请选择分类"
+                options={typeOptions}
+                onChange={id => setInputValue(id)}
+                filterOption={(input, option) => (option?.label ?? '').toLowerCase().includes(input.toLowerCase())}
+              />)}
+              {selectType == SELECT_TYPE.STATE && (<Select
+                showSearch
+                allowClear
+                style={{width: '70%'}}
+                placeholder="请选择状态"
+                // options={typeOptions}
+                onChange={id => setInputValue(id)}
+              >
+                <Option value={STATE.NOSUBMIT}>未提交</Option>
+                <Option value={STATE.NOAPPROVE}>待审批</Option>
+                <Option value={STATE.REJECT}>已拒绝</Option>
+                <Option value={STATE.PASS}>已通过</Option>
+                <Option value={STATE.SUBMIT}>已提交</Option>
+                <Option value={STATE.FAILURE}>已失效</Option>
+              </Select>)}
             </div>
+            {isOut && (<Button type="primary" onClick={() => setVersionVisible(true)}>
+              新建清单
+            </Button>)}
+          </div>
 
-            <div style={{ width: '100%', marginTop: '10px' }}>
-              <Table
-                columns={columns}
-                dataSource={showData}
-                loading={nodeLoading}
-                bordered={false}
-                pagination={{ position: ['none', 'none'], pageSize: 999, onChange }}
-                scroll={{ y: '460px' }}
-                // childrenColumnName="none"
-                // expandable={{
-                //   expandedRowRender: record => (
-                //     <Table
-                //       columns={columns}
-                //       dataSource={record.children}
-                //       pagination={{ position: ['none', 'none'] }}
-                //     />
-                //   ),
-                //   rowExpandable: record => record.children?.length > 0,
-                // }}
-              />
-            </div>
-            {/* <Spin spinning={loading.global}> */}
-            <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>
-      </Modal>
-      <VersionModal
-        typeOptions={typeOptions}
-        visible={versionVisible}
-        version={version}
-        versionList={versionList}
-        flowDetail={flowDetail}
-        onClose={() => setVersionVisible(false)}
-        onOk={values => {
-          onCommit?.(values, () => {
-            setVersionVisible(false);
-          });
-        }}
-        loading={commitLoading}
-      />
-    </>
-  );
+          <div style={{width: '100%', marginTop: '10px'}}>
+            <Table
+              columns={columns}
+              dataSource={showData}
+              loading={nodeLoading}
+              bordered={false}
+              rowKey='id'
+              pagination={{position: ['none', 'none'], pageSize: 999, onChange}}
+              scroll={{y: '460px'}}
+              rowClassName={setRowClassName}
+              onExpandedRowsChange={handleExpandedRowChange}
+              expandedRowKeys={expandedRowKey}
+              defaultExpandedRowKeys={expandedRowKey}
+              // childrenColumnName="none"
+              // expandable={{
+              //   expandedRowRender: record => (
+              //     <Table
+              //       columns={columns}
+              //       dataSource={record.children}
+              //       pagination={{ position: ['none', 'none'] }}
+              //     />
+              //   ),
+              //   rowExpandable: record => record.children?.length > 0,
+              // }}
+            />
+          </div>
+          {/* <Spin spinning={loading.global}> */}
+          <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>
+    </Modal>
+    <VersionModal
+      typeOptions={typeOptions}
+      visible={versionVisible}
+      version={version}
+      versionList={versionList}
+      flowDetail={flowDetail}
+      onClose={() => setVersionVisible(false)}
+      onOk={values => {
+        onCommit?.(values, () => {
+          setVersionVisible(false);
+        });
+      }}
+      loading={commitLoading}
+    />
+  </>);
 }
 
 const getColor = item => {
@@ -617,9 +552,7 @@ const getColor = item => {
   return color;
 };
 
-export default connect(({ loading, user }) => ({
-  loading,
-  currentUser: user.currentUser,
-  userList: user.list,
+export default connect(({loading, user}) => ({
+  loading, currentUser: user.currentUser, userList: user.list,
 }))(FlowModal);
 // export default FlowModal;

+ 4 - 0
src/pages/Detail/Index.less

@@ -69,3 +69,7 @@
   // justify-content: center;
   // align-items: center;
 }
+
+.selectedROW{
+  background-color: rgba(186, 224, 255, 0.5);
+}