10 changed files with 280 additions and 15 deletions
Split View
Diff Options
-
2README.md
-
10public/servers.json
-
1src/components/Tabs-KSHLCJD/README.md
-
224src/components/Tabs-KSHLCJD/index.js
-
6src/global.jsx
-
8src/models/doing.js
-
18src/pages/DoingCases/TableList/index.jsx
-
8src/pages/DoingCases/index.jsx
-
10src/pages/ZBSX/TableList/index.jsx
-
8src/services/doing.js
@ -1,7 +1,7 @@ |
|||
{ |
|||
"API_URL": "http://localhost:8080/api/v4", |
|||
"SYS_MAN_URL": "http://localhost:8080/api", |
|||
"LOGIN_URL": "http://localhost:8080", |
|||
"PARENT_URL": "http://localhost:8080", |
|||
"moduleFactory": "http://localhost:8080/api/v4/sys/self" |
|||
"API_URL": "http://172.29.223.62:82/api/v4", |
|||
"SYS_MAN_URL": "http:/172.29.223.62:82/api", |
|||
"LOGIN_URL": "http:/172.29.223.62:82", |
|||
"PARENT_URL": "http://172.29.223.62:82", |
|||
"moduleFactory": "http://172.29.223.62:82/api/v4/sys/self" |
|||
} |
|||
@ -0,0 +1 @@ |
|||
在办事项--查看流程节点--可视化流程节点 |
|||
@ -0,0 +1,224 @@ |
|||
import React, { useState, useEffect } from 'react'; |
|||
import { Modal, Timeline, Steps, Card, Tag, Descriptions, Button } from 'antd'; |
|||
import { connect } from 'umi'; |
|||
import moment from 'moment'; |
|||
|
|||
const { Step } = Steps; |
|||
|
|||
const KSHLCJD = (props) => { |
|||
const { id, sysToken, hideModal, visible } = props; |
|||
const [loading, setLoading] = useState(false); |
|||
const [flowData, setFlowData] = useState(null); |
|||
const [currentStep, setCurrentStep] = useState(0); |
|||
|
|||
// 模拟流程数据 - 实际应该从接口获取
|
|||
const mockFlowData = [ |
|||
{ |
|||
id: 1, |
|||
step: 1, |
|||
name: '预警生成', |
|||
status: 'finish', |
|||
time: '2024-01-01 09:00:00', |
|||
operator: '系统自动', |
|||
remark: '系统自动检测到问题并生成预警' |
|||
}, |
|||
{ |
|||
id: 2, |
|||
step: 2, |
|||
name: '受理派发', |
|||
status: 'finish', |
|||
time: '2024-01-01 10:30:00', |
|||
operator: '张三', |
|||
remark: '受理员接收并派发到处理部门' |
|||
}, |
|||
{ |
|||
id: 3, |
|||
step: 3, |
|||
name: '核查办理', |
|||
status: 'process', |
|||
time: '2024-01-02 14:20:00', |
|||
operator: '李四', |
|||
remark: '正在核查处理中' |
|||
}, |
|||
{ |
|||
id: 4, |
|||
step: 4, |
|||
name: '审批审核', |
|||
status: 'wait', |
|||
time: '', |
|||
operator: '', |
|||
remark: '待审核' |
|||
}, |
|||
{ |
|||
id: 5, |
|||
step: 5, |
|||
name: '办结归档', |
|||
status: 'wait', |
|||
time: '', |
|||
operator: '', |
|||
remark: '待归档' |
|||
} |
|||
]; |
|||
|
|||
useEffect(() => { |
|||
if (id) { |
|||
fetchFlowData(); |
|||
} |
|||
}, [id]); |
|||
|
|||
// 获取流程数据
|
|||
const fetchFlowData = async () => { |
|||
setLoading(true); |
|||
try { |
|||
// 这里应该调用实际的API
|
|||
// const response = await props.dispatch({
|
|||
// type: 'doing/fetchFlowData',
|
|||
// payload: { id, sysToken }
|
|||
// });
|
|||
|
|||
// 暂时使用模拟数据
|
|||
setTimeout(() => { |
|||
setFlowData(mockFlowData); |
|||
|
|||
// 计算当前步骤(根据status)
|
|||
const current = mockFlowData.findIndex(item => item.status === 'process'); |
|||
setCurrentStep(current >= 0 ? current : mockFlowData.length - 1); |
|||
|
|||
setLoading(false); |
|||
}, 500); |
|||
} catch (error) { |
|||
setLoading(false); |
|||
} |
|||
}; |
|||
|
|||
// 渲染步骤状态图标
|
|||
const renderStepStatus = (status) => { |
|||
const statusConfig = { |
|||
finish: { color: 'green', text: '已完成' }, |
|||
process: { color: 'blue', text: '进行中' }, |
|||
wait: { color: 'gray', text: '待处理' }, |
|||
error: { color: 'red', text: '异常' } |
|||
}; |
|||
|
|||
const config = statusConfig[status] || statusConfig.wait; |
|||
return <Tag color={config.color}>{config.text}</Tag>; |
|||
}; |
|||
|
|||
// 渲染Timeline视图
|
|||
const renderTimelineView = () => { |
|||
return ( |
|||
<Timeline mode="left" style={{ marginTop: 20 }}> |
|||
{flowData?.map((item) => ( |
|||
<Timeline.Item |
|||
key={item.id} |
|||
label={item.time || '待处理'} |
|||
color={ |
|||
item.status === 'finish' ? 'green' : |
|||
item.status === 'process' ? 'blue' : |
|||
item.status === 'error' ? 'red' : 'gray' |
|||
} |
|||
> |
|||
<Card size="small"> |
|||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}> |
|||
<div> |
|||
<h4 style={{ margin: 0 }}>步骤{item.step}: {item.name}</h4> |
|||
<p style={{ margin: '5px 0' }}>{item.remark}</p> |
|||
{item.operator && <p style={{ margin: 0, color: '#666' }}>操作人: {item.operator}</p>} |
|||
</div> |
|||
<div> |
|||
{renderStepStatus(item.status)} |
|||
</div> |
|||
</div> |
|||
</Card> |
|||
</Timeline.Item> |
|||
))} |
|||
</Timeline> |
|||
); |
|||
}; |
|||
|
|||
// 渲染Steps视图
|
|||
const renderStepsView = () => { |
|||
return ( |
|||
<Steps current={currentStep} style={{ margin: '40px 0' }}> |
|||
{flowData?.map((item) => ( |
|||
<Step |
|||
key={item.id} |
|||
title={item.name} |
|||
description={ |
|||
<div> |
|||
<div>{item.time || '待处理'}</div> |
|||
<div>{item.operator || ''}</div> |
|||
{item.remark && <div style={{ color: '#666' }}>{item.remark}</div>} |
|||
</div> |
|||
} |
|||
status={item.status} |
|||
/> |
|||
))} |
|||
</Steps> |
|||
); |
|||
}; |
|||
|
|||
// 渲染流程统计信息
|
|||
const renderStatistics = () => { |
|||
if (!flowData) return null; |
|||
|
|||
const finished = flowData.filter(item => item.status === 'finish').length; |
|||
const processing = flowData.filter(item => item.status === 'process').length; |
|||
const waiting = flowData.filter(item => item.status === 'wait').length; |
|||
|
|||
return ( |
|||
<Descriptions bordered size="small" column={3} style={{ marginBottom: 20 }}> |
|||
<Descriptions.Item label="总步骤数">{flowData.length}</Descriptions.Item> |
|||
<Descriptions.Item label="已完成">{finished}</Descriptions.Item> |
|||
<Descriptions.Item label="进行中">{processing}</Descriptions.Item> |
|||
<Descriptions.Item label="待处理">{waiting}</Descriptions.Item> |
|||
<Descriptions.Item label="当前进度">{Math.round((finished / flowData.length) * 100)}%</Descriptions.Item> |
|||
<Descriptions.Item label="预计剩余时间">2天</Descriptions.Item> |
|||
</Descriptions> |
|||
); |
|||
}; |
|||
|
|||
return ( |
|||
<Modal |
|||
title="可视化流程节点" |
|||
visible={visible !== undefined ? visible : true} |
|||
onCancel={() => hideModal(false)} |
|||
footer={[ |
|||
<Button key="close" onClick={() => hideModal(false)}> |
|||
关闭 |
|||
</Button>, |
|||
<Button |
|||
key="refresh" |
|||
type="primary" |
|||
loading={loading} |
|||
onClick={fetchFlowData} |
|||
> |
|||
刷新 |
|||
</Button> |
|||
]} |
|||
width={800} |
|||
maskClosable={false} |
|||
> |
|||
<div style={{ maxHeight: '60vh', overflow: 'auto' }}> |
|||
{renderStatistics()} |
|||
|
|||
<div style={{ margin: '20px 0' }}> |
|||
<h4>流程进度图</h4> |
|||
{renderStepsView()} |
|||
</div> |
|||
|
|||
<div style={{ margin: '20px 0' }}> |
|||
<h4>流程时间线</h4> |
|||
{renderTimelineView()} |
|||
</div> |
|||
|
|||
{/* 如果流程有附件,可以展示在这里 */} |
|||
<Card title="流程附件" size="small" style={{ marginTop: 20 }}> |
|||
<p>暂无附件</p> |
|||
</Card> |
|||
</div> |
|||
</Modal> |
|||
); |
|||
}; |
|||
|
|||
export default connect()(KSHLCJD); |
|||