Commit b0f5c229 by zhaochengxiang

评估方案

parent 12763375
......@@ -24,11 +24,13 @@
"crypto-js": "^4.0.0",
"echarts": "^5.3.1",
"eslint-config-react-app": "^7.0.1",
"immer": "9.0.15",
"immutability-helper": "^3.1.1",
"insert-css": "^2.0.0",
"less": "^4.1.1",
"less-loader": "^8.0.0",
"local-storage": "^2.0.0",
"qiankun": "2.4.0",
"react": "^17.0.1",
"react-contexify": "^5.0.0",
"react-dnd": "^14.0.2",
......@@ -44,7 +46,6 @@
"rxjs": "^7.5.5",
"showdown": "^1.9.1",
"smooth-scroll": "^16.1.3",
"qiankun": "2.4.0",
"typescript": "^4.6.2",
"web-vitals": "^1.0.1"
},
......
import React from 'react'
import { Modal, Spin, Button, Form } from "antd"
import { Modal, Spin, Button, Form, Input, TreeSelect, Row, Col, Checkbox } from "antd"
import produce from "immer"
import { dispatch } from '../../../model'
const FC = (props) => {
const { visible, onCancel } = props
const [waiting, setWaiting] = React.useState(false)
const [loading, setLoading] = React.useState(false)
const [elements, setElements] = React.useState()
const basicRef = React.useRef(null)
React.useEffect(() => {
getElements()
}, [])
const getElements = () => {
setLoading(true)
dispatch({
type: 'assetmanage.listElements',
callback: data => {
setElements(data??[])
setLoading(false)
},
error: () => {
setLoading(false)
}
})
}
const close = (refresh = false) => {
setWaiting(false)
setLoading(false)
......@@ -16,7 +38,20 @@ const FC = (props) => {
const save = async () => {
try {
const row = await basicRef.current?.validate()
setWaiting(true)
dispatch({
type: 'assetmanage.saveEvaluation',
payload: {
data: row
},
callback: data => {
close(true)
},
error: () => {
setWaiting(false)
}
})
} catch (e) {
}
......@@ -45,7 +80,7 @@ const FC = (props) => {
onCancel={() => { close() }}
>
<Spin spinning={loading || waiting}>
<Basic ref={basicRef} />
<Basic ref={basicRef} elements={elements} />
</Spin>
</Modal>
)
......@@ -53,7 +88,7 @@ const FC = (props) => {
export default FC
const Basic = React.forwardRef(function ({ }, ref) {
const Basic = React.forwardRef(function ({ elements }, ref) {
const [form] = Form.useForm()
React.useImperativeHandle(ref, () => ({
......@@ -76,6 +111,112 @@ const Basic = React.forwardRef(function ({ }, ref) {
>
<Input placeholder="请输入方案名称" />
</Form.Item>
<Form.Item
name='dirs'
label='资产目录'
rules={[{ required: true, message: '请选择资产目录!' }]}
>
<AssetCatalogItem />
</Form.Item>
<Form.Item
name='elementIds'
label='评估要素'
rules={[{ required: true, message: '请选择评估要素!' }]}
>
<Checkbox.Group style={{ width: '100%' }}>
<Row>
{
(elements??[]).map((item, index) => {
return (
<Col span={6} key={index}>
<Checkbox
value={item.id}
style={{
lineHeight: '32px',
}}
>
{item.name}
</Checkbox>
</Col>
)
})
}
</Row>
</Checkbox.Group>
</Form.Item>
</Form>
)
})
\ No newline at end of file
})
const AssetCatalogItem = ({ value, onChange }) => {
const [loadingTreeData, setLoadingTreeData] = React.useState(false)
const [treeData, setTreeData] = React.useState()
React.useEffect(() => {
getTreeData()
}, [])
const treeData1 = React.useMemo(() => {
if (treeData) {
const newTreeData = produce(treeData, draft => {
const setNode = (g) => {
g.key = g.nodeId
g.title = g.text
g.value = g.nodeId
g.children?.forEach((child) => {
setNode(child)
})
}
draft.forEach((child) => {
setNode(child)
})
})
return newTreeData
}
return undefined
}, [treeData])
const getTreeData = () => {
setLoadingTreeData(true)
dispatch({
type: 'assetmanage.queryAssetDirectoryAsTree',
callback: data => {
setLoadingTreeData(false)
setTreeData(data)
},
error: () => {
setLoadingTreeData(false)
}
})
}
return (
<TreeSelect
value={(value??[]).map(item => {
return {
label: item.name,
value: item.id
}
})}
loading={loadingTreeData}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={treeData1}
placeholder="请选择资产目录"
treeDefaultExpandAll
treeCheckable={true}
treeCheckStrictly={true}
showCheckedStrategy={TreeSelect.SHOW_ALL}
onChange={(value) => {
onChange?.((value??[]).map(item => {
return {
id: item.value,
name: item.label
}
}))
}}
/>
)
}
\ No newline at end of file
import React from 'react'
import { debounceTime, Subject } from 'rxjs'
import { Space, Input, Table, Button } from 'antd'
import { Space, Input, Table, Button, Tooltip, Modal, Pagination, Typography } from 'antd'
import { ExclamationCircleOutlined } from '@ant-design/icons'
import { defaultPage, usePage } from '../../../util/page'
import { dispatch } from '../../../model'
import AddEvaluate from './add'
import './index.less'
import { showMessage } from '../../../util'
const FC = (props) => {
const [args, setArgs] = React.useState(() => ({
......@@ -21,11 +24,21 @@ const FC = (props) => {
const [loading, setLoading] = React.useState(false)
const [data, setData] = React.useState()
const [total, setTotal] = React.useState()
const [elements, setElements] = React.useState()
const $keyword = React.useMemo(() => new Subject(), [])
const [keyword, setKeyword] = React.useState()
const [addEvaluateParams, setAddEvaluateParams] = React.useState({
visible: false
})
const [selectedRows, setSelectedRows] = React.useState([])
const [page, setPage] = usePage()
const mountRef = React.useRef(false)
const [modal, contextHolder] = Modal.useModal()
React.useEffect(() => {
getElements()
}, [])
const setArgsAndPage = React.useCallback((params) => {
// 设置查询参数时将分页置为1
......@@ -60,41 +73,62 @@ const FC = (props) => {
}, [])
React.useEffect(() => {
getTasks()
getEvaluations()
}, [args])
const cols = [
{
title: '任务编号',
dataIndex: 'taskNO',
title: '方案名称',
dataIndex: 'name',
ellipsis: true,
},
{
title: '数量',
dataIndex: 'resourceNum',
},
{
title: '已分配',
dataIndex: 'distributedNum',
title: '评估范围',
dataIndex: 'dirs',
render: (dirs) => {
const dirStr = (dirs??[]).map(item => item.name).toString()
return (
<Tooltip title={dirStr}>
<Typography.Text ellipsis={true}>
{dirStr}
</Typography.Text>
</Tooltip>
)
}
},
{
title: '已梳理',
dataIndex: 'sortedNum',
title: '评估要素',
dataIndex: 'elementIds',
render: (elementIds) => {
const elementStr = (elements??[]).filter(item => (elementIds??[]).indexOf(item.id) !== -1).map(item => item.name).toString()
return (
<Tooltip title={elementStr}>
<Typography.Text ellipsis={true}>
{elementStr}
</Typography.Text>
</Tooltip>
)
}
},
{
title: '已完成',
dataIndex: 'doneNum',
title: '总得分',
dataIndex: 'score',
ellipsis: true,
},
{
title: '分配人',
dataIndex: 'creator',
title: '资产总数',
dataIndex: 'dataAssetTotalNum',
ellipsis: true,
},
{
title: '分配时间',
dataIndex: 'createTime',
title: '创建时间',
dataIndex: 'createTimestamp',
ellipsis: true,
render: (_, record) => record.createTimestamp ? new Date(record.createTimestamp).toLocaleString() : ''
},
]
const getTasks = () => {
const getEvaluations = () => {
setLoading(true)
dispatch({
type: 'assetmanage.getEvaluations',
......@@ -114,11 +148,75 @@ const FC = (props) => {
})
}
const getElements = () => {
dispatch({
type: 'assetmanage.listElements',
callback: data => {
setElements(data??[])
}
})
}
return (
<div className='asset-evalute'>
<div className='header px-3'>
<Space>
<Button>新增</Button>
<Button onClick={() => {
setAddEvaluateParams({
visible: true
})
}}>新增</Button>
<Tooltip title={((selectedRows??[]).length===0)?'请先选择评估方案':''}>
<Button
disabled={(selectedRows??[]).length===0}
onClick={() => {
modal.confirm({
title: '确认运行选中的评估方案吗?',
icon: <ExclamationCircleOutlined />,
okText: '确认',
cancelText: '取消',
onOk: () => {
dispatch({
type: 'assetmanage.runEvaluations',
payload: {
params: {
evaluationProjectIds: (selectedRows??[]).map(item => item.id).toString()
}
},
callback: data => {
showMessage('warn', '运行成功')
},
})
}
})
}}>运行</Button>
</Tooltip>
<Tooltip title={((selectedRows??[]).length===0)?'请先选择评估方案':''}>
<Button
disabled={(selectedRows??[]).length===0}
onClick={() => {
modal.confirm({
title: '确认删除选中的评估方案吗?',
icon: <ExclamationCircleOutlined />,
okText: '确认',
cancelText: '取消',
onOk: () => {
dispatch({
type: 'assetmanage.deleteEvaluations',
payload: {
params: {
evaluationProjectIds: (selectedRows??[]).map(item => item.id).toString()
}
},
callback: data => {
showMessage('warn', '删除成功')
getEvaluations()
},
})
}
})
}}>删除</Button>
</Tooltip>
</Space>
<Space>
<Input size="middle"
......@@ -138,16 +236,48 @@ const FC = (props) => {
</div>
<div className='px-3 pt-3'>
<Table
maxHeight='calc(100vh - 285px - 46px)'
scroll={{y: 'calc(100vh - 285px)'}}
rowKey='id'
loading={loading}
columns={cols}
dataSource={data||[]}
pageSize={page.pageSize} pageNum={page.pageNum} total={total ?? 0}
onPaginate={(page, pageSize) => {
setPageAndArgs({ pageNum: page, pageSize })
pagination={false}
rowSelection={{
selectedRowKeys: (selectedRows??[]).map(item => item?.id),
onChange: (selectedRowKeys, selectedRows) => {
setSelectedRows(selectedRows)
},
}}
/>
<Pagination
className="text-center mt-3"
showSizeChanger
showQuickJumper
onChange={(_pageNum, _pageSize) => {
setPageAndArgs({ pageNum: _pageNum||1, pageSize: _pageSize || 20 })
}}
onShowSizeChange={(_pageNum, _pageSize) => {
setPageAndArgs({ pageNum: _pageNum||1, pageSize: _pageSize || 20 })
}}
current={page.pageNum}
pageSize={page.pageSize}
defaultCurrent={1}
total={total}
pageSizeOptions={[10,20]}
showTotal={total => `共 ${total} 条`}
/>
</div>
<AddEvaluate
{...addEvaluateParams}
onCancel={(refresh) => {
setAddEvaluateParams({
visible: false
})
refresh && getEvaluations()
}}
/>
{contextHolder}
</div>
)
}
......
......@@ -315,14 +315,6 @@ const ImportActionHeader = (props) => {
const [ maintenanceRecords, setMaintenanceRecords ] = useState(null);
useEffect(() => {
if (modelerData?.dataType) {
getBindingLoadRangeList(modelerData?.dataType);
} else {
setBindingLoadRangeList([]);
}
}, [modelerData?.dataType])
useEffect(() => {
const causes = [];
(validateReports||[]).forEach(report => {
......@@ -447,16 +439,7 @@ const ImportActionHeader = (props) => {
}
})
}
<<<<<<< Updated upstream
=======
} else if (changedValues.hasOwnProperty('dataType')) {
if (changedValues.dataType) {
onChange?.({...changedValues, bindingLoadRange: ''}, {...allValues, bindingLoadRange: ''});
} else {
onChange?.({...changedValues, bindingLoadRange: ''}, {...allValues, bindingLoadRange: ''});
}
>>>>>>> Stashed changes
}
}
}
const onOnlyShowRequireChange = () => {
......
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