Commit 15d6c702 authored by 邓超's avatar 邓超

fix: 重构流程中心交互,改为导航模式

parent aa36af8a
Pipeline #66164 waiting for manual action with stages
import React, { useEffect, useState, useRef } from 'react'; import React, { useEffect, useState, useRef } from 'react';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import classnames from 'classnames'; import classnames from 'classnames';
import { Tabs, Input, message, Modal, Button } from 'antd'; import { Tabs, Input, message, Modal, Button, Anchor } from 'antd';
import { import {
PlusOutlined, PlusOutlined,
EditOutlined, EditOutlined,
...@@ -9,12 +9,15 @@ import { ...@@ -9,12 +9,15 @@ import {
ExclamationCircleOutlined, ExclamationCircleOutlined,
HighlightOutlined, HighlightOutlined,
} from '@ant-design/icons'; } from '@ant-design/icons';
import gsap, { TweenMax, TimelineMax, ScrollToPlugin } from 'gsap/all';
import FlowModal from './workFlowComponents/FlowModal'; import FlowModal from './workFlowComponents/FlowModal';
import FlowGroupModal from './workFlowComponents/FlowGroupModal'; import FlowGroupModal from './workFlowComponents/FlowGroupModal';
import styles from './WorkflowHomePage.less'; import styles from './WorkflowHomePage.less';
import { WFGetAllFlow, GetFlowNode, DeleteFlow } from '@/services/workflow/workflow'; import { WFGetAllFlow, GetFlowNode, DeleteFlow } from '@/services/workflow/workflow';
const plugins = [ScrollToPlugin];
const { Search } = Input; const { Search } = Input;
const { Link } = Anchor;
const { confirm } = Modal; const { confirm } = Modal;
const WorkflowHomePage = () => { const WorkflowHomePage = () => {
...@@ -22,26 +25,70 @@ const WorkflowHomePage = () => { ...@@ -22,26 +25,70 @@ const WorkflowHomePage = () => {
const [flowList, setFlowList] = useState([]); // 流程列表 const [flowList, setFlowList] = useState([]); // 流程列表
const [currentList, setCurrentList] = useState([]); // 当前tab显示列表 const [currentList, setCurrentList] = useState([]); // 当前tab显示列表
const [modalType, setModalType] = useState(''); // 弹窗类型是编辑还是新增 const [modalType, setModalType] = useState(null); // 弹窗类型是编辑还是新增
const [editMsg, setEditMsg] = useState({}); // 弹窗编辑回显 const [editMsg, setEditMsg] = useState({}); // 弹窗编辑回显
const [editIndex, setEditIndex] = useState(); // 编辑流程组得索引 const [editIndex, setEditIndex] = useState(); // 编辑流程组得索引
const [hoverIndex, setHoverIndex] = useState();
const [flowNames, setFlowNames] = useState([]); const [flowNames, setFlowNames] = useState([]);
const [flowTableScroll, setFlowTableScroll] = useState(0);
const [visible, setVisible] = useState({ const [visible, setVisible] = useState({
FlowModal: false, FlowModal: false,
FlowGroupModal: false, FlowGroupModal: false,
}); // 弹窗显示 }); // 弹窗显示
const [flag, setFlag] = useState(0); const [flag, setFlag] = useState(0);
const activeKey = useRef(null); const activeKey = useRef(null);
const isClick = useRef(false);
const scrollTimer = useRef();
useEffect(() => { useEffect(() => {
gsap.registerPlugin(ScrollToPlugin);
getFlowList(); getFlowList();
let flowTable = document.querySelector(`.${styles.flowTable}`);
flowTable.addEventListener('scroll', () => {
setFlowTableScroll(flowTable.scrollTop);
});
}, []); }, []);
useEffect(() => {
clearTimeout(scrollTimer.current);
scrollTimer.current = setTimeout(() => {
// todo something scroll end
isClick.current = false;
}, 50);
console.log(isClick.current, 'isClick.current');
if (isClick.current) {
return;
}
flowList.forEach(item => {
let groupSrolltop = document.getElementById(`${item.name}`)?.offsetTop;
if (groupSrolltop <= flowTableScroll) {
activeKey.current = item.name;
setFlag(flag + 1);
}
});
}, [flowTableScroll]);
useEffect(() => { useEffect(() => {
console.log(history.location.state, 'history.location.state'); console.log(history.location.state, 'history.location.state');
if (modalType) {
if (modalType === 'add') {
console.log('addsaasddfas');
isClick.current = true;
setTimeout(() => {
TweenMax.to(`.${styles.flowTable}`, 0.5, { scrollTo: { y: `#${activeKey.current}` } });
}, 0);
}
setModalType(null);
return;
}
if (history.location.state) { if (history.location.state) {
activeKey.current = history.location.state.activeKey;
console.log(document.querySelector(`.${styles.flowTable}`)); console.log(document.querySelector(`.${styles.flowTable}`));
activeKey.current = history.location.state.activeKey;
isClick.current = true;
setTimeout(() => { setTimeout(() => {
document.querySelector(`.${styles.flowTable}`).scrollTop = history.location.state.scrollTop; TweenMax.to(`.${styles.flowTable}`, 0.5, {
scrollTo: { y: history.location.state.scrollTop },
});
// let flowTable = document.querySelector(`.${styles.flowTable}`);
// document.querySelector(`.${styles.flowTable}`).scrollTop = history.location.state.scrollTop;
}, 0); }, 0);
} }
}, [flowList]); }, [flowList]);
...@@ -60,13 +107,16 @@ const WorkflowHomePage = () => { ...@@ -60,13 +107,16 @@ const WorkflowHomePage = () => {
}); });
setFlowList(list); setFlowList(list);
console.log(activeKey.current, 'activeKey'); console.log(activeKey.current, 'activeKey');
if (activeKey.current) { // if (activeKey.current) {
setCurrentList(list.filter(item => item.name === activeKey.current)); // setCurrentList(list.filter(item => item.name === activeKey.current));
} else { // } else {
setCurrentList(list); // setCurrentList(list);
} // }
setCurrentList(list);
console.log(flowNameList, 'flowNameList'); console.log(flowNameList, 'flowNameList');
setFlowNames(flowNameList); setFlowNames(flowNameList);
} else {
message.error(res.msg);
} }
}); });
}; };
...@@ -83,24 +133,36 @@ const WorkflowHomePage = () => { ...@@ -83,24 +133,36 @@ const WorkflowHomePage = () => {
}; };
// 搜索 // 搜索
const onSearch = val => { const onSearch = val => {
let copyList = JSON.parse(JSON.stringify(flowList)); // let copyList = JSON.parse(JSON.stringify(flowList));
let list = activeKey.current // let list = activeKey.current
? copyList.filter(item => item.name === activeKey.current) // ? copyList.filter(item => item.name === activeKey.current)
: copyList; // : copyList;
let list = JSON.parse(JSON.stringify(flowList));
if (val) { if (val) {
list.forEach(item => { list.forEach(item => {
item.children = item.children.filter(ele => ele.FlowName.includes(val)); item.children = item.children.filter(ele => ele.FlowName.includes(val));
}); });
} }
isClick.current = true;
activeKey.current = list[0].name;
setCurrentList(list); setCurrentList(list);
setFlag(flag + 1); setFlag(flag + 1);
setTimeout(() => {
document.querySelector(`.${styles.flowTable}`).scrollTop = 0;
}, 0);
}; };
// 切换tab // 切换tab
const onChange = val => { const onChange = val => {
isClick.current = true;
console.log(val);
let flowTable = document.querySelector(`.${styles.flowTable}`);
console.log(flowTable.scrollTop, 'flowTable');
TweenMax.to(`.${styles.flowTable}`, 0.5, { scrollTo: { y: `#${val}` } });
let copyList = JSON.parse(JSON.stringify(flowList)); let copyList = JSON.parse(JSON.stringify(flowList));
let list = copyList.filter(item => item.name === val); let list = copyList.filter(item => item.name === val);
activeKey.current = val; activeKey.current = val;
setCurrentList(list); setFlag(flag + 1);
// setCurrentList(list);
// setActiveKey(val); // setActiveKey(val);
}; };
...@@ -138,7 +200,7 @@ const WorkflowHomePage = () => { ...@@ -138,7 +200,7 @@ const WorkflowHomePage = () => {
getFlowList(); getFlowList();
} else if (modalType === 'edit') { } else if (modalType === 'edit') {
let newflowList = [...flowList]; let newflowList = [...flowList];
newflowList[editIndex].name = val; // newflowList[editIndex].name = val;
setFlowList(newflowList); setFlowList(newflowList);
setCurrentList(newflowList.filter(item => item.name === activeKey.current)); setCurrentList(newflowList.filter(item => item.name === activeKey.current));
} else { } else {
...@@ -153,6 +215,7 @@ const WorkflowHomePage = () => { ...@@ -153,6 +215,7 @@ const WorkflowHomePage = () => {
res.data.Nodes.forEach(item => { res.data.Nodes.forEach(item => {
item.nodeDetail = JSON.stringify(item); item.nodeDetail = JSON.stringify(item);
}); });
setModalType(null);
history.push({ history.push({
pathname: '/biz/workflow/flowBoard', pathname: '/biz/workflow/flowBoard',
state: { state: {
...@@ -183,6 +246,7 @@ const WorkflowHomePage = () => { ...@@ -183,6 +246,7 @@ const WorkflowHomePage = () => {
DeleteFlow({ FlowId: val.FlowID }) DeleteFlow({ FlowId: val.FlowID })
.then(res => { .then(res => {
if (res.code === 0) { if (res.code === 0) {
setModalType('del');
getFlowList(); getFlowList();
message.success('删除成功'); message.success('删除成功');
} else { } else {
...@@ -207,20 +271,44 @@ const WorkflowHomePage = () => { ...@@ -207,20 +271,44 @@ const WorkflowHomePage = () => {
)} */} )} */}
</div> </div>
); );
const toFlowGroup = (e, val) => {
e.preventDefault();
let flowTable = document.querySelector(`.${styles.flowTable}`);
console.log(`.${styles.flowTable}`);
TweenMax.to(`.${styles.flowTable}`, 1, { scrollTo: val.href });
};
return ( return (
<div className={styles.pageContent}> <div className={styles.pageContent}>
<div className={styles.headerBox}> <div className={styles.headerBox}>
<div className={styles.left}> <div className={styles.left}>
<div <div
className={classnames(styles.allFlows, { [styles.allFlowsChoose]: !activeKey.current })} className={classnames(styles.allFlows, { [styles.allFlowsChoose]: true })}
onClick={chageAll} // onClick={chageAll}
/> />
<div className={styles.flows}> <div className={styles.flows}>
<Tabs activeKey={activeKey.current} type="card" onChange={onChange} animated={false}> {/* <Anchor affix={false} onClick={toFlowGroup}>
{flowList.map((item, index) => (
<Link href={`#${item.name}`} title={item.name} key={item.name} />
))}
</Anchor> */}
<div className={styles.tabBox}>
{flowList.map((item, index) => (
<div
className={classnames(styles.tab, {
[styles.activeTab]: item.name === activeKey.current,
})}
onClick={() => onChange(item.name)}
key={item.name}
>
{item.name}
</div>
))}
</div>
{/* <Tabs activeKey={activeKey.current} type="card" onChange={onChange} animated={false}>
{flowList.map((item, index) => ( {flowList.map((item, index) => (
<Tabs.TabPane tab={tabRender(item, index)} key={item.name} /> <Tabs.TabPane tab={tabRender(item, index)} key={item.name} />
))} ))}
</Tabs> </Tabs> */}
</div> </div>
</div> </div>
{/* <div className={styles.right} onClick={addFlowGroup}> {/* <div className={styles.right} onClick={addFlowGroup}>
...@@ -249,7 +337,7 @@ const WorkflowHomePage = () => { ...@@ -249,7 +337,7 @@ const WorkflowHomePage = () => {
</div> </div>
<div className={styles.flowTable}> <div className={styles.flowTable}>
{currentList.map((item, index) => ( {currentList.map((item, index) => (
<div className={styles.flowGroup} key={item.name}> <div className={styles.flowGroup} key={item.name} id={item.name}>
<div <div
className={styles.header} className={styles.header}
onClick={() => eiditFlowGroup(item, index)} onClick={() => eiditFlowGroup(item, index)}
...@@ -260,8 +348,14 @@ const WorkflowHomePage = () => { ...@@ -260,8 +348,14 @@ const WorkflowHomePage = () => {
<EditOutlined style={{ marginLeft: '5px' }} /> <EditOutlined style={{ marginLeft: '5px' }} />
</div> </div>
<div className={styles.groupBox}> <div className={styles.groupBox}>
{item.children.map(ele => ( {item.children.map((ele, num) => (
<div className={styles.flowBox} type={item.bgType} key={ele.Code}> <div
className={styles.flowBox}
type={item.bgType}
key={ele.Code}
onMouseEnter={() => setHoverIndex(JSON.stringify([index, num]))}
onMouseLeave={() => setHoverIndex(null)}
>
<div className={styles.header}> <div className={styles.header}>
<div className={styles.title}>{ele.FlowName}</div> <div className={styles.title}>{ele.FlowName}</div>
...@@ -271,9 +365,22 @@ const WorkflowHomePage = () => { ...@@ -271,9 +365,22 @@ const WorkflowHomePage = () => {
</div> </div>
</div> </div>
<div className={styles.imgBox}> <div className={styles.imgBox}>
<div className={styles.mask}> <div
className={classnames(styles.mask, {
[styles.maskHover]: JSON.stringify([index, num]) === hoverIndex,
})}
/>
<div
className={classnames(styles.buttonBox, {
[styles.buttonHover]: JSON.stringify([index, num]) === hoverIndex,
})}
>
<div className={styles.lookDetail}> <div className={styles.lookDetail}>
<Button type="primary" onClick={() => chooseNode(ele)}> <Button
type="primary"
onClick={() => chooseNode(ele)}
style={{ background: '#3D78FF', color: '#fff', opacity: 1 }}
>
设计 设计
</Button> </Button>
...@@ -281,7 +388,12 @@ const WorkflowHomePage = () => { ...@@ -281,7 +388,12 @@ const WorkflowHomePage = () => {
</div> </div>
<div className={styles.delete}> <div className={styles.delete}>
<Button <Button
style={{ background: '#5a5d69', border: '#5a5d69' }} style={{
background: '#fff',
border: '1px solid #FF4D4F',
color: '#FF4D4F',
opacity: 1,
}}
type="primary" type="primary"
onClick={e => delFlow(ele, e)} onClick={e => delFlow(ele, e)}
> >
...@@ -315,7 +427,8 @@ const WorkflowHomePage = () => { ...@@ -315,7 +427,8 @@ const WorkflowHomePage = () => {
handleCancel={() => showModal('FlowModal', false)} handleCancel={() => showModal('FlowModal', false)}
keep={flowNames} keep={flowNames}
treeData={flowList} treeData={flowList}
onSubumit={() => { onSubumit={val => {
activeKey.current = val;
showModal('FlowModal', false); showModal('FlowModal', false);
getFlowList(); getFlowList();
}} }}
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
display: flex; display: flex;
background-color: #e9f0ff; background-color: #e9f0ff;
justify-content: space-between; justify-content: space-between;
margin: -12px 0 0 -12px;
.left { .left {
display: flex; display: flex;
...@@ -36,6 +37,25 @@ ...@@ -36,6 +37,25 @@
flex: 1; flex: 1;
height: 50px; height: 50px;
.tabBox {
display: flex;
.tab {
height: 50px;
line-height: 50px;
text-align: center;
padding: 0 20px;
cursor: pointer;
}
.activeTab {
color: #3D78FF;
}
}
.ant-tabs-tab { .ant-tabs-tab {
height: 50px; height: 50px;
...@@ -43,15 +63,19 @@ ...@@ -43,15 +63,19 @@
border-bottom: none; border-bottom: none;
} }
.ant-tabs-tab:hover {
color: rgba(0, 0, 0, 0.85);
}
.ant-tabs-tab .anticon { .ant-tabs-tab .anticon {
margin-right: 0; margin-right: 0;
} }
.ant-tabs-tab-active { .ant-tabs-tab-active {
border-top: 2px solid #3D78FF; // border-top: 2px solid #3D78FF;
border-bottom: none; // border-bottom: none;
background: linear-gradient(0deg, #BED2F9 0%, #F2F7FF 100%); // background: linear-gradient(0deg, #BED2F9 0%, #F2F7FF 100%);
color: #3D78FF; // color: #3D78FF;
} }
} }
} }
...@@ -81,8 +105,11 @@ ...@@ -81,8 +105,11 @@
.left { .left {
margin-right: 490px; margin-right: 490px;
margin-left: 7px;
span { span {
display: inline-block;
width: 60px;
font-size: 18px; font-size: 18px;
font-weight: 700; font-weight: 700;
color: #3D78FF; color: #3D78FF;
...@@ -135,6 +162,7 @@ ...@@ -135,6 +162,7 @@
.flowTable { .flowTable {
flex: 1; flex: 1;
overflow-y: scroll; overflow-y: scroll;
position: relative;
.flowGroup { .flowGroup {
.header { .header {
...@@ -214,7 +242,28 @@ ...@@ -214,7 +242,28 @@
width: 333px; width: 333px;
height: 141px; height: 141px;
border-radius: 0 20px 20px 20px; border-radius: 0 20px 20px 20px;
z-index: 1;
}
.maskHover {
background: linear-gradient(0deg, #A3C7F9 0%, #FFFFFF 99%);
opacity: 0.65;
}
.buttonBox {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
left: 50%;
transform: translateX(-50%);
width: 333px;
height: 141px;
font-size: 16px; font-size: 16px;
z-index: 2;
.delete { .delete {
display: none; display: none;
...@@ -224,11 +273,9 @@ ...@@ -224,11 +273,9 @@
display: none; display: none;
margin-right: 10px; margin-right: 10px;
} }
} }
.mask:hover { .buttonHover {
background-color: rgba(0, 0, 0, 0.8);
.lookDetail { .lookDetail {
display: block; display: block;
...@@ -239,6 +286,7 @@ ...@@ -239,6 +286,7 @@
display: block; display: block;
cursor: pointer; cursor: pointer;
} }
} }
.imgBox { .imgBox {
......
...@@ -43,7 +43,7 @@ const FlowModal = props => { ...@@ -43,7 +43,7 @@ const FlowModal = props => {
duration: 3, duration: 3,
description: modalType === 'add' ? '新增成功' : '编辑成功', description: modalType === 'add' ? '新增成功' : '编辑成功',
}); });
onSubumit(); onSubumit(validate.Type);
} else { } else {
notification.error({ notification.error({
message: '提示', message: '提示',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment