Commit 426fd43d by zhaochengxiang

数据对比

parent ee577f52
......@@ -794,4 +794,8 @@ export function* getModelMetadataCompareResult(payload) {
export function* getModelBranchNotice(payload) {
return yield call(datamodelerService.getModelBranchNotice, payload)
}
export function* getMetadataTable(payload) {
return yield call(datamodelerService.getMetadataTable, payload)
}
\ No newline at end of file
......@@ -750,4 +750,8 @@ export function getModelMetadataCompareResult(payload) {
export function getModelBranchNotice(payload) {
return GetJSON("/shandatamodeler/easyDataModelerNotice/getModelBranchNotice", payload)
}
export function getMetadataTable(payload) {
return PostJSON("/baseservice/dataSecurityGrade/getTablePage", payload)
}
\ No newline at end of file
......@@ -494,7 +494,7 @@ const EditModel = (props) => {
复制模型
</PermissionButton>
{/* <Button type='primary' ghost onClick={onMetadataCompare}>
数据对比
数据对比
</Button> */}
<PermissionButton
type='primary'
......
......@@ -13,7 +13,7 @@ import PermissionRcItem from '../../../../util/Component/PermissionRcItem';
import TagCell from './tag-help';
import BranchModelSync from './branch-model-sync';
import ModelCompareSelectModel from './model-compare-select-model';
import MetadataCompare from './metadata-compare';
import MetadataCompareSelectMetadata from './metadata-compare-select-metadata';
import ModelForkDetail from './model-fork-detail';
import './ModelTable.less';
......@@ -164,7 +164,7 @@ const ModelTable = (props) => {
visible: false,
item: undefined,
})
const [metadataCompareParams, setMetadataCompareParams] = useState({
const [metadataCompareSelectMetadataParams, setMetadataCompareSelectMetadataParams] = useState({
visible: false,
item: undefined,
})
......@@ -688,7 +688,7 @@ const ModelTable = (props) => {
item: currentItem,
})
} else if (key === 'metadata-compare') {
setMetadataCompareParams({
setMetadataCompareSelectMetadataParams({
visible: true,
item: currentItem,
})
......@@ -802,7 +802,7 @@ const ModelTable = (props) => {
defaultPermission={true}
onClick={handleItemClick}
>
数据对比
数据对比
</PermissionRcItem>
<PermissionRcItem
id='fork-model'
......@@ -898,10 +898,10 @@ const ModelTable = (props) => {
})
}}
/>
<MetadataCompare
{...metadataCompareParams}
<MetadataCompareSelectMetadata
{...metadataCompareSelectMetadataParams}
onCancel={() => {
setMetadataCompareParams({
setMetadataCompareSelectMetadataParams({
visible: false,
item: undefined,
})
......
import React from 'react'
import { Modal, Button, Row, Col, Spin, Tree, Input, Pagination, Tooltip, Typography, Space, Select, AutoComplete } from 'antd'
import { useDebounceEffect } from "ahooks"
import { dispatch } from '../../../../model'
import Table from '../../ResizeableTable'
import produce from 'immer'
import { highlightSearchContentByTerms, paginate, showMessage } from '../../../../util'
import MetadataCompare from './metadata-compare'
import { viewModes } from './ModelTree'
import { AppContext } from '../../../../App'
const FC = ({ visible, item, onCancel }) => {
const [animated, setAnimated] = React.useState(true)
const [metadataCompareParams, setMetadataCompareParams] = React.useState({
visible: false,
leftItem: undefined,
rightItem: undefined
})
const basicRef = React.useRef()
React.useEffect(() => {
if (visible) {
setTimeout(() => {
setAnimated(false)
}, 300)
}
}, [visible])
const close = () => {
setAnimated(true)
onCancel?.()
}
const save = () => {
const selectedRows = basicRef.current.selectedRows??[]
if ((selectedRows??[]).length === 0) {
showMessage('warn', '请选择元数据')
return
}
setMetadataCompareParams({
visible: true,
leftItem: selectedRows[0],
rightItem: item,
})
}
const footer = React.useMemo(() => {
return [
<Button key='cancel'
onClick={() => close()}
>取消</Button>,
<Button key='save' type='primary'
onClick={() => save()}
>确定</Button>
]
}, [close, save])
return (
<>
<Modal
title='数据对比设置'
visible={visible}
footer={footer}
width='80%'
bodyStyle={{ padding: '15px', overflowX: 'auto', height: '80vh' }}
centered destroyOnClose
onCancel={() => { close() }}
>
{ !animated && <Basic ref={basicRef} /> }
</Modal>
<MetadataCompare
{...metadataCompareParams}
onCancel={() => {
setMetadataCompareParams({
visible: false,
leftItem: undefined,
rightItem: undefined,
})
}}
/>
</>
)
}
export default FC
const Basic = React.forwardRef(function ({}, ref) {
const [args, setArgs] = React.useState({
node: undefined,
keyword: undefined,
})
const [pagination, setPagination] = React.useState({
page: 1,
size: 20,
})
const [loading, setLoading] = React.useState(false)
const [data, setData] = React.useState()
const [total, setTotal] = React.useState()
const [selectedRows, setSelectedRows] = React.useState()
const app = React.useContext(AppContext)
React.useImperativeHandle(ref, () => ({
selectedRows
}), [selectedRows])
useDebounceEffect(() => {
if (args.node) {
getMetadatas()
}
}, [args, pagination], { wait: 300 })
const setArgsByParams = React.useCallback((params) => {
setPagination((prev => {
return { ...pagination, page: 1 }
}))
setArgs((prev) => {
return {...prev, ...params}
})
}, [])
const columns = [
{
title: '表英文名称',
dataIndex: 'tableName',
render: (text, record) => {
return <Tooltip title={text}>
<Typography.Text ellipsis={true}>{text}</Typography.Text>
</Tooltip>
}
},
{
title: '表中文名称',
dataIndex: 'tableCnName',
render: (text, record) => {
return <Tooltip title={text}>
<Typography.Text ellipsis={true}>{text}</Typography.Text>
</Tooltip>
}
},
{
title: '数据库',
dataIndex: 'databaseName',
render: (text, record) => {
return <Tooltip title={text}>
<Typography.Text ellipsis={true}>{text}</Typography.Text>
</Tooltip>
}
},
{
title: 'Schema',
dataIndex: 'schemaName',
render: (text, record) => {
return <Tooltip title={text}>
<Typography.Text ellipsis={true}>{text}</Typography.Text>
</Tooltip>
}
},
]
const getMetadatas = () => {
setLoading(true)
console.log('args.node', args.node)
let params = {
modelPath: 'Catalog,Database,Schema,Table',
sysId: args.node?.scopeId,
reload: 0,
catalog: app?.env?.domainId,
pageNum: pagination.page,
pageSize: pagination.size,
}
if (args.keyword) {
params.keyword = args.keyword
}
dispatch({
type: 'datamodel.getMetadataTable',
payload: {
params
},
callback: (data) => {
setLoading(false)
setData(data?.content)
setTotal(data?.totalElements)
},
error: () => {
setLoading(false)
}
})
}
return (
<Row gutter={10}>
<Col span={4}>
<MetadataTree
node={args.node}
setNode={(val) => setArgsByParams({ node: val })}
/>
</Col>
<Col span={20}>
<div
style={{
display: 'flex',
padding: '0px 0px 15px',
alignItems: 'center',
justifyContent: 'flex-end',
}}>
<Input size="middle"
placeholder="请输入关键字搜索"
value={args.keyword}
bordered={true} allowClear
onChange={(e) => {
setArgsByParams({ keyword: e.target.value })
}}
style={{ width: 200 }}
/>
</div>
<Table
size='small'
extraColWidth={32}
rowKey='tableId'
loading={loading}
columns={columns}
dataSource={data??[]}
pagination={false}
rowSelection={{
type: 'radio',
selectedRowKeys: (selectedRows??[]).map(item => item.tableId),
onChange: (selectedRowKeys, selectedRows) => {
for (const item of selectedRows??[]) {
item.path = args.node?.path
}
setSelectedRows(selectedRows)
},
}}
scroll={{ y: 'calc(80vh - 170px)' }}
/>
{
total!==0 && <Pagination
style={{
textAlign: 'center',
marginTop: 15,
}}
showSizeChanger
onChange={(page,size) => {
setPagination({page, size})
}}
current={pagination.page}
pageSize={pagination.size}
defaultCurrent={1}
total={total}
showTotal={(total) => `共${total??0}项`}
/>
}
</Col>
</Row>
)
})
export const MetadataTree = ({ node, setNode }) => {
const [loading, setLoading] = React.useState(false)
const [treeData, setTreeData] = React.useState()
const [expandedKeys, setExpandedKeys] = React.useState([])
const [autoExpandParent, setAutoExpandParent] = React.useState(false)
const app = React.useContext(AppContext)
React.useEffect(() => {
getTreeData()
}, [])
const getTreeData = () => {
setLoading(true)
dispatch({
type: 'assetmanage.getDatasources',
payload: {
catalog: app?.env?.domainId,
},
callback: (data) => {
setLoading(false)
let defaultNode = null
for (let item of data??[]) {
item.key = `${item.catalogId}`
item.title = item.catalogName
item.value = `${item.catalogId}`
item.idStr = `${item.catalogId}`
item.disabled = true
item.children = []
for (let child of item.scopes??[]) {
child.key = `${item.catalogId}-${child.scopeId}`
child.title = child.scopeName
child.value = `${item.catalogId}-${child.scopeId}`
child.idStr = `${child.scopeId}`
child.path = `/${item.catalogName}/${child.scopeName}`
item.children.push(child)
if (!defaultNode) {
console.log('child', child)
defaultNode = child
}
}
}
setTreeData(data)
if (defaultNode) {
setNode(defaultNode)
setExpandedKeys(defaultNode?.key?[defaultNode?.key]:[])
setAutoExpandParent(true)
}
},
error: () => {
setLoading(false)
}
})
}
const onTreeExpand = (expandedKeys) => {
setExpandedKeys(expandedKeys)
setAutoExpandParent(false)
}
const onTreeSelect = (selectedKeys, { selectedNodes }) => {
if (selectedKeys.length === 0 || selectedNodes.length === 0) {
return
}
setNode(selectedNodes[0])
}
return (
<Spin spinning={loading}>
<Tree
showLine
showIcon={false}
autoExpandParent={autoExpandParent}
treeData={treeData}
selectedKeys={node?.key?[node.key]:[]}
expandedKeys={expandedKeys}
onSelect={onTreeSelect}
onExpand={onTreeExpand}
style={{ height: 'calc(80vh - 30px)', overflow: 'auto' }}
/>
</Spin>
)
}
\ No newline at end of file
......@@ -5,14 +5,14 @@ import { CompareDetail } from './VersionCompare'
import { dispatch } from '../../../../model'
import { AppContext } from '../../../../App'
const FC = ({ visible, item, onCancel }) => {
const FC = ({ visible, leftItem, rightItem, onCancel }) => {
const close = () => {
onCancel?.()
}
return (
<Modal
title='数据对比'
title='数据对比'
visible={visible}
footer={null}
width='80%'
......@@ -20,64 +20,36 @@ const FC = ({ visible, item, onCancel }) => {
centered destroyOnClose
onCancel={() => { close() }}
>
<Basic item={item} />
<Basic leftItem={leftItem} rightItem={rightItem} />
</Modal>
)
}
export default FC
const Basic = ({ item }) => {
const [loadingMetadata, setLoadingMetadata] = React.useState(false)
const [metadata, setMetadata] = React.useState()
const Basic = ({ leftItem, rightItem }) => {
const [loadingResult, setLoadingResult] = React.useState(false)
const [result, setResult] = React.useState()
const [onlyShowChange, setOnlyShowChange] = React.useState(true)
const app = React.useContext(AppContext)
React.useEffect(() => {
if (item) {
getMetadata()
}
}, [item])
React.useEffect(() => {
if (metadata && item) {
if (leftItem && rightItem) {
compare()
}
}, [metadata, item, onlyShowChange])
}, [leftItem, rightItem, onlyShowChange])
const onOnlyShowChange = (e) => {
setOnlyShowChange(e.target.checked)
}
const getMetadata = () => {
setLoadingMetadata(true)
dispatch({
type: 'datamodel.getMatchMetadataTableById',
payload: {
params: {
envId: app?.env?.domainId,
easyDataModelerDataModelId: item?.id,
}
},
callback: data => {
setLoadingMetadata(false)
setMetadata(data)
},
error: () => {
setLoadingMetadata(false)
}
})
}
const compare = () => {
setLoadingResult(true)
dispatch({
type: 'datamodel.getModelMetadataCompareResult',
payload: {
easyDataModelerDataModelId: item?.id,
metadataId: metadata?.metadataId,
easyDataModelerDataModelId: rightItem?.id,
metadataId: leftItem?.tableId,
leftModel: false,
},
callback: data => {
......@@ -91,31 +63,29 @@ const Basic = ({ item }) => {
}
return (
<Spin spinning={loadingMetadata}>
<div className='model-version-compare'>
<div className='flex'>
<div style={{ flex: 1, paddingRight: 10, overflow: 'hidden'}}>
<span>{`元数据:${metadata?.metadataFullPath??'暂无数据'}`}</span>
</div>
<div style={{ flex: 1, paddingLeft: 10, overflow: 'hidden'}}>
<Row gutter={10}>
<Col flex='1 1 0' style={{ overflow: 'hidden' }}>
<span>{`模型:${item?.path}/${item?.name}`}</span>
</Col>
{/* <Col flex={0}>
<Checkbox onChange={onOnlyShowChange} checked={onlyShowChange}>
仅显示差异
</Checkbox>
</Col> */}
</Row>
</div>
<div className='model-version-compare'>
<div className='flex'>
<div style={{ flex: 1, paddingRight: 10, overflow: 'hidden'}}>
<span>{`元数据:${leftItem?.path}/${leftItem?.tableName}`}</span>
</div>
<div className='py-5'>
<Spin spinning={loadingResult} >
<CompareDetail data={result} showIndex={false} />
</Spin>
<div style={{ flex: 1, paddingLeft: 10, overflow: 'hidden'}}>
<Row gutter={10}>
<Col flex='1 1 0' style={{ overflow: 'hidden' }}>
<span>{`模型:${rightItem?.path}/${rightItem?.name}`}</span>
</Col>
{/* <Col flex={0}>
<Checkbox onChange={onOnlyShowChange} checked={onlyShowChange}>
仅显示差异
</Checkbox>
</Col> */}
</Row>
</div>
</div>
</Spin>
<div className='py-5'>
<Spin spinning={loadingResult} >
<CompareDetail data={result} showIndex={false} />
</Spin>
</div>
</div>
)
}
\ No newline at end of file
......@@ -34,7 +34,7 @@ const FC = ({ visible, item, onCancel }) => {
const save = () => {
const selectedRows = basicRef.current.selectedRows??[]
if ((selectedRows??[]).length === 0) {
showMessage('warn', '请选择模型')
showMessage('warn', '请选择模型')
return
}
......
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