Commit 346879ec by zhaochengxiang

模型对比

parent 5e42e69d
...@@ -770,13 +770,13 @@ const ModelTable = (props) => { ...@@ -770,13 +770,13 @@ const ModelTable = (props) => {
> >
复制模型 复制模型
</PermissionRcItem> </PermissionRcItem>
{/* <PermissionRcItem <PermissionRcItem
id='model-compare' id='model-compare'
defaultPermission={true} defaultPermission={true}
onClick={handleItemClick} onClick={handleItemClick}
> >
模型对比 模型对比
</PermissionRcItem> */} </PermissionRcItem>
{ {
view !== 'branch' && <PermissionRcItem view !== 'branch' && <PermissionRcItem
id='auth-transfer' id='auth-transfer'
......
...@@ -17,7 +17,7 @@ import produce from "immer"; ...@@ -17,7 +17,7 @@ import produce from "immer";
const { Option } = AutoComplete; const { Option } = AutoComplete;
const viewModes = [ export const viewModes = [
{ {
key: 'dir', key: 'dir',
name: '目录视角' name: '目录视角'
......
import React from 'react' import React from 'react'
import { Modal, Button, Row, Col, Spin, Tree, Input, Pagination, Tooltip, Typography, Space, Select, } from 'antd' import { Modal, Button, Row, Col, Spin, Tree, Input, Pagination, Tooltip, Typography, Space, Select, AutoComplete } from 'antd'
import { useDebounceEffect } from "ahooks" import { useDebounceEffect } from "ahooks"
import { dispatch } from '../../../../model' import { dispatch } from '../../../../model'
import Table from '../../ResizeableTable' import Table from '../../ResizeableTable'
import produce from 'immer' import produce from 'immer'
import { paginate, showMessage } from '../../../../util' import { highlightSearchContentByTerms, paginate, showMessage } from '../../../../util'
import ModelCompare from './model-compare' import ModelCompare from './model-compare'
import { viewModes } from './ModelTree'
import './branch-select-model.less'
const FC = ({ visible, item, onCancel }) => { const FC = ({ visible, item, onCancel }) => {
const [animated, setAnimated] = React.useState(true) const [animated, setAnimated] = React.useState(true)
...@@ -87,6 +86,11 @@ const FC = ({ visible, item, onCancel }) => { ...@@ -87,6 +86,11 @@ const FC = ({ visible, item, onCancel }) => {
export default FC export default FC
const Basic = React.forwardRef(function ({}, ref) { const Basic = React.forwardRef(function ({}, ref) {
const [treeStates, setTreeStates] = React.useState({
type: viewModes.length>0?viewModes[0].key:undefined,
node: undefined,
rootNode: undefined,
})
const [args, setArgs] = React.useState({ const [args, setArgs] = React.useState({
keyword: undefined, keyword: undefined,
}) })
...@@ -94,58 +98,26 @@ const Basic = React.forwardRef(function ({}, ref) { ...@@ -94,58 +98,26 @@ const Basic = React.forwardRef(function ({}, ref) {
page: 1, page: 1,
size: 20, size: 20,
}) })
const [loadingTreeData, setLoadingTreeData] = React.useState(false)
const [treeData, setTreeData] = React.useState()
const [node, setNode] = React.useState()
const [loading, setLoading] = React.useState(false) const [loading, setLoading] = React.useState(false)
const [data, setData] = React.useState() const [data, setData] = React.useState()
const [selectedRows, setSelectedRows] = React.useState() const [selectedRows, setSelectedRows] = React.useState()
const [expandedKeys, setExpandedKeys] = React.useState([])
const [autoExpandParent, setAutoExpandParent] = React.useState(false) const { type, node, rootNode } = treeStates
React.useImperativeHandle(ref, () => ({ React.useImperativeHandle(ref, () => ({
selectedRows selectedRows
}), [selectedRows]) }), [selectedRows])
React.useEffect(() => { React.useEffect(() => {
getTreeData()
}, [])
React.useEffect(() => {
setPagination({...pagination, page: 1}) setPagination({...pagination, page: 1})
}, [node]) }, [node])
useDebounceEffect(() => { useDebounceEffect(() => {
if (node) { if (node && rootNode) {
getDataModels() getDataModels()
} }
}, [node, args], { wait: 300 }) }, [node, rootNode, args], { wait: 300 })
const treeData1 = React.useMemo(() => {
if (treeData) {
const newTreeData = produce(treeData, draft => {
const setNode = (g) => {
g.key = g.id;
g.title = g.name;
g.children = [];
(g.subCatalogs??[]).forEach((child) => {
setNode(child)
g.children.push(child)
});
}
draft.forEach((child) => {
setNode(child)
})
})
return newTreeData
}
return undefined
}, [treeData])
const setArgsByParams = React.useCallback((params) => { const setArgsByParams = React.useCallback((params) => {
setArgs((prev) => { setArgs((prev) => {
...@@ -197,58 +169,70 @@ const Basic = React.forwardRef(function ({}, ref) { ...@@ -197,58 +169,70 @@ const Basic = React.forwardRef(function ({}, ref) {
}, },
] ]
const getTreeData = () => { const getDataModels = () => {
setLoadingTreeData(true) if (args.keyword) {
} else {
if (type === 'dir') {
getDirModelsByCatalog()
} else if (type === 'state') {
getStateModelsByCatalog()
} else if (type === 'branch') {
getBranchModelsByCatalog()
}
}
}
const getDirModelsByCatalog = () => {
setLoading(true)
dispatch({ dispatch({
type: 'datamodel.refreshDataModelCatalog', type: 'datamodel.getCurrentDataModelCatalog',
payload: {
easyDataModelerCatalogId: node?.id,
},
callback: (data) => { callback: (data) => {
setLoadingTreeData(false) setLoading(false)
setData(data?.easyDataModelerDataModels)
const newTreeData = data?.subCatalogs??[]
setTreeData(newTreeData)
if ((newTreeData??[]).length > 0) {
setNode(newTreeData[0])
}
}, },
error: () => { error: () => {
setLoadingTreeData(false) setLoading(false)
} }
}) })
} }
const getDataModels = () => { const getStateModelsByCatalog = () => {
setLoading(true) setLoading(true)
dispatch({
if (args.keyword) { type: 'datamodel.getCurrentDataModelStateCatalog',
payload: {
} else { easyDataModelerStateCatalogId: node?.id,
dispatch({ },
type: 'datamodel.getCurrentDataModelCatalog', callback: (data) => {
payload: { setLoading(false)
easyDataModelerCatalogId: node?.id, setData(data?.easyDataModelerDataModels)
}, },
callback: (data) => { error: () => {
setLoading(false) setLoading(false)
setData(data?.easyDataModelerDataModels) }
}, })
error: () => {
setLoading(false)
}
})
}
}
const onTreeExpand = (expandedKeys) => {
setExpandedKeys(expandedKeys)
setAutoExpandParent(false)
} }
const onTreeSelect = (selectedKeys, { selectedNodes }) => { const getBranchModelsByCatalog = () => {
if (selectedKeys.length === 0 || selectedNodes.length === 0) { setLoading(true)
return dispatch({
} type: 'datamodel.getCurrentDataModelCatalog',
payload: {
setNode(selectedNodes[0]) easyDataModelerCatalogId: rootNode?.id,
branchId: node?.id,
},
callback: (data) => {
setLoading(false)
setData(data?.easyDataModelerDataModels)
},
error: () => {
setLoading(false)
}
})
} }
const onChange = (val) => { const onChange = (val) => {
...@@ -259,19 +243,10 @@ const Basic = React.forwardRef(function ({}, ref) { ...@@ -259,19 +243,10 @@ const Basic = React.forwardRef(function ({}, ref) {
<div className='branch-select-model'> <div className='branch-select-model'>
<Row> <Row>
<Col span={4}> <Col span={4}>
<Spin spinning={loadingTreeData}> <ModelTree
<Tree states={treeStates}
className='tree' setStates={(val) => setTreeStates(val)}
showLine />
showIcon={false}
autoExpandParent={autoExpandParent}
treeData={treeData1}
selectedKeys={node?[node.id]:[]}
expandedKeys={expandedKeys}
onSelect={onTreeSelect}
onExpand={onTreeExpand}
/>
</Spin>
</Col> </Col>
<Col span={20}> <Col span={20}>
<div <div
...@@ -330,4 +305,224 @@ const Basic = React.forwardRef(function ({}, ref) { ...@@ -330,4 +305,224 @@ const Basic = React.forwardRef(function ({}, ref) {
</Row> </Row>
</div> </div>
) )
}) })
\ No newline at end of file
const ModelTree = ({ states, setStates }) => {
const { type, node, rootNode } = states
const [loading, setLoading] = React.useState(false)
const [treeData, setTreeData] = React.useState()
const [keyword, setKeyword] = React.useState()
const [expandedKeys, setExpandedKeys] = React.useState([])
const [autoExpandParent, setAutoExpandParent] = React.useState(false)
const [options, setOptions] = React.useState([])
React.useEffect(() => {
getTreeData()
setKeyword()
}, [type])
const treeData1 = React.useMemo(() => {
if (treeData) {
const newTreeData = produce(treeData, draft => {
const setNode = (g) => {
g.key = g.id;
g.title = g.name;
g.children = [];
(g.subCatalogs??[]).forEach((child) => {
setNode(child)
g.children.push(child)
});
}
draft.forEach((child) => {
setNode(child)
})
})
return newTreeData
}
return undefined
}, [treeData])
const generateList = (data, list, path = null) => {
for (let i = 0; i < (data??[]).length; i++) {
const node = data[i]
const { name } = node
const currentPath = path ? `${path}/${name}` : name
list.push({ ...node, title: currentPath })
if ((node.subCatalogs??[]).length > 0) {
generateList(node.subCatalogs, list, currentPath)
}
}
}
const treeList = React.useMemo(() => {
const newTreeList = []
generateList(treeData, newTreeList)
return newTreeList
}, [treeData])
const getTreeData = () => {
if (type === 'dir') {
getDirTreeData()
} else if (type === 'state') {
getStateTreeData()
} else if (type === 'branch') {
getBranchTreeData()
}
}
const getDirTreeData = () => {
setLoading(true)
dispatch({
type: 'datamodel.refreshDataModelCatalog',
callback: (data) => {
setLoading(false)
const newTreeData = data?.subCatalogs??[]
setTreeData(newTreeData)
if ((newTreeData??[]).length > 0) {
setStates({ ...states, rootNode: data, node: newTreeData[0] })
} else {
setStates({ ...states, rootNode: data, node: undefined })
}
},
error: () => {
setLoading(false)
}
})
}
const getStateTreeData = () => {
setLoading(true)
dispatch({
type: 'datamodel.loadDataModelStateCatalog',
callback: (data) => {
setLoading(false)
const newTreeData = data?.subCatalogs??[]
setTreeData(newTreeData)
if ((newTreeData??[]).length > 0) {
setStates({ ...states, node: newTreeData[0] })
} else {
setStates({ ...states, node: newTreeData[0] })
}
},
error: () => {
setLoading(false)
}
})
}
const getBranchTreeData = () => {
setLoading(true)
dispatch({
type: 'datamodel.getAllBranches',
callback: (data) => {
setLoading(false)
setTreeData(data)
if ((data??[]).length > 0) {
setStates({ ...states, node: data[0] })
} else {
setStates({ ...states, node: undefined })
}
},
error: () => {
setLoading(false)
}
})
}
const onTreeExpand = (expandedKeys) => {
setExpandedKeys(expandedKeys)
setAutoExpandParent(false)
}
const onTreeSelect = (selectedKeys, { selectedNodes }) => {
if (selectedKeys.length === 0 || selectedNodes.length === 0) {
return
}
setStates({ ...states, node: selectedNodes[0] })
}
const onAutoCompleteSearch = (searchText) => {
setKeyword(searchText)
setOptions(
!searchText ? [] : (treeList||[]).filter(item => (item.title??'').indexOf(searchText)!==-1),
)
}
const onAutoCompleteSelect = (value, option) => {
const paths = value.split('/');
setKeyword(paths[paths.length-1]);
const index = (treeList??[]).findIndex(item => item.id === option.key)
if (index !== -1) {
setStates({ ...states, node: treeList[index] })
setExpandedKeys([...expandedKeys, option.key])
setAutoExpandParent(true)
}
}
return (
<Spin spinning={loading}>
<div className='flex' style={{ alignItems: 'center' }}>
<span>模型视角:</span>
<Select
style={{ width: 100 }}
value={type}
onChange={(val) => {
setStates({ ...states, type: val })
}}
>
{
viewModes.map(item => (
<Select.Option key={item.key} value={item.key}>{item.name}</Select.Option>
))
}
</Select>
</div>
{
type !== 'state' && <div style={{ marginTop: 10 }}>
<AutoComplete
allowClear
value={keyword}
placeholder='搜索目录'
onSelect={onAutoCompleteSelect}
onSearch={onAutoCompleteSearch}
onClear={() => { setKeyword() }}
style={{ width: '95%' }}
>
{
(options||[]).map((item, index) => {
return (
<AutoComplete.Option key={item.id} value={item.title}>
<div style={{ whiteSpace: 'normal' }}>
{highlightSearchContentByTerms(item.title, [keyword])}
</div>
</AutoComplete.Option>
);
})
}
</AutoComplete>
</div>
}
<Tree
showLine
showIcon={false}
autoExpandParent={autoExpandParent}
treeData={treeData1}
selectedKeys={node?[node.id]:[]}
expandedKeys={expandedKeys}
onSelect={onTreeSelect}
onExpand={onTreeExpand}
style={{ marginTop: 10, height: 'calc(80vh - 115px)', overflow: 'auto' }}
/>
</Spin>
)
}
\ No newline at end of file
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