zmh
2 years ago
10 changed files with 671 additions and 8 deletions
@ -0,0 +1,53 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
import { basicAction } from '@peace/utils' |
||||
|
import { ApiTable } from '$utils' |
||||
|
|
||||
|
export function getBusinessMetadata(params) { |
||||
|
return dispatch => basicAction({ |
||||
|
type: 'get', |
||||
|
dispatch: dispatch, |
||||
|
query: params, |
||||
|
actionType: 'GET_BUSINESS_METADATA_LIST', |
||||
|
url: ApiTable.getBusinessMetadata, |
||||
|
msg: { error: '获取业务元数据列表失败' }, |
||||
|
reducer: { name: 'metadataDatabases' } |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
export function postBusinessMetadata(data) { |
||||
|
return dispatch => basicAction({ |
||||
|
type: 'post', |
||||
|
data: data, |
||||
|
dispatch: dispatch, |
||||
|
actionType: 'POST_BUSINESS_METADATA', |
||||
|
url: ApiTable.postBusinessMetadata, |
||||
|
msg: { option: '新建业务元数据' }, |
||||
|
reducer: {} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
export function putBusinessMetadata(id, data) { |
||||
|
return dispatch => basicAction({ |
||||
|
type: 'put', |
||||
|
data: data, |
||||
|
dispatch, |
||||
|
actionType: 'PUT_BUSINESS_METADATA', |
||||
|
url: ApiTable.putBusinessMetadata.replace('{id}', id), |
||||
|
msg: { |
||||
|
option: '修改业务元数据', |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
export function delBusinessMetadata(id) { |
||||
|
return dispatch => basicAction({ |
||||
|
type: 'del', |
||||
|
dispatch, |
||||
|
actionType: 'DELETE_BUSINESS_METADATA', |
||||
|
url: ApiTable.delBusinessMetadata.replace('{id}', id), |
||||
|
msg: { |
||||
|
option: '删除业务元数据', |
||||
|
} |
||||
|
}); |
||||
|
} |
@ -0,0 +1,76 @@ |
|||||
|
import React, { useEffect, useState } from 'react'; |
||||
|
import { Modal, Input, Form, Row, Col } from 'antd'; |
||||
|
const BusinessDatabaseModal = (props) => { |
||||
|
const { onConfirm, onCancel, editData, metadataModels, resourceCatalogPath } = props; |
||||
|
const [form] = Form.useForm(); |
||||
|
useEffect(() => { |
||||
|
}, []); |
||||
|
const handleOk = () => { |
||||
|
form.validateFields().then(values => { |
||||
|
if (onConfirm) { |
||||
|
onConfirm(values); |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
const validatorNull = (rule, value, getFieldValue, validateFields, label) => { |
||||
|
if (!value || !value.trim().length) { |
||||
|
return Promise.reject(new Error(`${label}不可空字符串`)); |
||||
|
} |
||||
|
return Promise.resolve(); |
||||
|
} |
||||
|
const renderBasicInfo = (databasesRecord) => { |
||||
|
return <div> |
||||
|
<Row><Col span={12}> |
||||
|
<div style={{ color: '#3BB19C', fontSize: 18 }}>基本信息</div> |
||||
|
<div style={{ lineHeight: '35px', marginLeft: 32 }}> |
||||
|
<div> 元数据名称:<span style={{ color: '#7F7F7F' }}>{databasesRecord.name}</span></div> |
||||
|
<div> 元数据代码:<span style={{ color: '#7F7F7F' }}>{databasesRecord.code}</span></div> |
||||
|
<div> 元数据类型:<span style={{ color: '#7F7F7F' }}>{databasesRecord.type}</span></div> |
||||
|
<div> 上下文路径:<span style={{ color: '#7F7F7F' }}>{'/' + resourceCatalogPath.join('/')}</span></div> |
||||
|
<div> 元数据详情:<span style={{ color: '#7F7F7F' }}>{databasesRecord.description}</span></div> |
||||
|
</div> |
||||
|
</Col> |
||||
|
<Col span={12}> |
||||
|
<div style={{ color: '#3BB19C', fontSize: 18 }}>属性</div> |
||||
|
<div style={{ lineHeight: '35px', marginLeft: 32 }}> |
||||
|
{metadataModels && metadataModels.filter(mm => mm.modelType === '表').map(mm => |
||||
|
<div title={mm.attributeName}> {mm.attributeName.length > 10 ? mm.attributeName.substring(0, 10) + '...' : |
||||
|
mm.attributeName}: |
||||
|
<span style={{ color: '#7F7F7F' }}>{databasesRecord.attributesParam && databasesRecord.attributesParam[mm.attributeCode] || ""}</span></div>)} |
||||
|
</div> |
||||
|
</Col> |
||||
|
</Row> |
||||
|
<div style={{ color: '#3BB19C', fontSize: 18, margin: '16px 0px' }}>业务信息</div> |
||||
|
</div> |
||||
|
} |
||||
|
return ( |
||||
|
<Modal title={editData.title} open={true} destroyOnClose |
||||
|
okText='确定' width={800} |
||||
|
onOk={() => handleOk(null)} |
||||
|
onCancel={onCancel}> |
||||
|
{editData.record.businessMetadataDatabases.length ? |
||||
|
renderBasicInfo(editData.record) : null |
||||
|
} |
||||
|
<Form form={form} labelCol={{ span: 6 }} wrapperCol={{ span: 18 }} initialValues={editData.record.businessMetadataDatabases || {}}> |
||||
|
{[{ name: '信息资源名称', key: 'resourceName' }, |
||||
|
{ name: '信息资源摘要', key: 'resourceAbstract' }, |
||||
|
{ name: '信息资源提供方', key: 'resourceProvider' }, |
||||
|
{ name: '信息资源分类', key: 'resourceCategory' }, |
||||
|
{ name: '信息资源标识符', key: 'resourceId' }, |
||||
|
{ name: '元数据标识符', key: 'metadataId' }].map(item => |
||||
|
<Form.Item |
||||
|
label={item.name} |
||||
|
name={item.key} |
||||
|
key={item.key} |
||||
|
rules={[{ required: true, message: '' }, { max: 50, message: `${item.name}不超过50个字符` }, |
||||
|
({ getFieldValue, validateFields }) => ({ |
||||
|
validator(_, value) { return validatorNull(_, value, getFieldValue, validateFields, item.name) } |
||||
|
})]}> |
||||
|
<Input style={{ width: '90%' }} placeholder={`请输入${item.name}`} /> |
||||
|
</Form.Item> |
||||
|
)} |
||||
|
</Form> |
||||
|
</Modal > |
||||
|
) |
||||
|
} |
||||
|
export default BusinessDatabaseModal; |
@ -0,0 +1,344 @@ |
|||||
|
import React, { useEffect, useState } from 'react'; |
||||
|
import { connect } from 'react-redux'; |
||||
|
import { Spin, Table, Popconfirm, Button, Input } from 'antd'; |
||||
|
import moment from 'moment'; |
||||
|
import FileSaver from 'file-saver'; |
||||
|
import BusinessDatabaseModal from '../components/businessDatabaseModal'; |
||||
|
const BusinessDatabaseTable = (props) => { |
||||
|
const { user, dispatch, actions, clientHeight, resourceCatalogId, resourceCatalogKey, |
||||
|
resourceCatalogPath, isRequesting, metadataModels } = props; |
||||
|
const { metadataManagement } = actions; |
||||
|
const SortValues = { 'ascend': 'asc', 'descend': 'desc' }; |
||||
|
const [tableData, setTableData] = useState([]); |
||||
|
const [tableDataCount, setTableDataCount] = useState(0);//Table数据
|
||||
|
const [updateAtSort, setUpdateAtSort] = useState('descend'); |
||||
|
const [keywords, setKeywords] = useState(''); |
||||
|
const [limit, setLimit] = useState(10); |
||||
|
const [currentPage, setCurrentPage] = useState(1); |
||||
|
const [selectedRowKeys, setSelectedRowKeys] = useState([]); |
||||
|
const [selectedRows, setSelectedRows] = useState([]); |
||||
|
const [modalVisible, setModalVisible] = useState(false); |
||||
|
const [editData, setEditData] = useState({}); |
||||
|
|
||||
|
useEffect(() => { |
||||
|
setUpdateAtSort('descend'); |
||||
|
initData({ limit, offset: currentPage - 1, orderDirection: SortValues[updateAtSort] }); |
||||
|
}, [resourceCatalogId]); |
||||
|
|
||||
|
const initData = (query = {}) => { |
||||
|
dispatch(metadataManagement.getBusinessMetadata({ catalog: resourceCatalogId, keywords, orderBy: 'updateAt', ...query })).then(res => { |
||||
|
if (res.success) { |
||||
|
setTableData(res.payload.data.rows); |
||||
|
setTableDataCount(res.payload.data.count); |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
const onAdd = (record, add) => { |
||||
|
dispatch(metadataManagement.getMetadataModels({ modelTypes: '表' })).then(res => { |
||||
|
if (res.success) { |
||||
|
if (!add) |
||||
|
setEditData({ title: '查看业务元数据', record: { path: '/' + resourceCatalogPath.join('/'), ...record, ...record.attributesParam } }); |
||||
|
else |
||||
|
setEditData({ add: true, title: '新建业务元数据', record: { path: '/' + resourceCatalogPath.join('/'), ...record, ...record.attributesParam } }); |
||||
|
setModalVisible(true); |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
const confirmDelete = (id) => { |
||||
|
dispatch(metadataManagement.delBusinessMetadata(id)).then(res => { |
||||
|
if (res.success) { |
||||
|
onSearch(); setModalVisible(false); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
const onTableChange = (pagination, filters, sorter) => { |
||||
|
let limit = Number.parseInt(pagination.pageSize); |
||||
|
let offset = Number.parseInt(pagination.current) - 1; |
||||
|
setCurrentPage(pagination.current); |
||||
|
setLimit(limit); |
||||
|
let query = { offset, limit, orderDirection: SortValues[updateAtSort] }; |
||||
|
if (sorter.columnKey === 'updateAt') { |
||||
|
query.orderDirection = SortValues[sorter.order]; |
||||
|
setUpdateAtSort(sorter.order); |
||||
|
} |
||||
|
setSelectedRowKeys([]); |
||||
|
setSelectedRows([]); |
||||
|
initData(query); |
||||
|
} |
||||
|
const columns = [ |
||||
|
{ |
||||
|
title: '所属库元数据', |
||||
|
dataIndex: 'parentDataName', |
||||
|
key: 'parentDataName', |
||||
|
ellipsis: true, |
||||
|
fixed: 'left', |
||||
|
width: '7%', |
||||
|
}, { |
||||
|
title: '元数据名称', |
||||
|
dataIndex: 'name', |
||||
|
key: 'name', |
||||
|
ellipsis: true, |
||||
|
fixed: 'left', |
||||
|
width: '7%', |
||||
|
}, { |
||||
|
title: '代码', |
||||
|
dataIndex: 'code', |
||||
|
key: 'code', |
||||
|
ellipsis: true, |
||||
|
fixed: 'left', |
||||
|
width: '6%', |
||||
|
}, { |
||||
|
title: '元数据类型', |
||||
|
dataIndex: 'type', |
||||
|
key: 'type', |
||||
|
fixed: 'left', |
||||
|
width: '6%', |
||||
|
}, { |
||||
|
title: '信息资源名称', |
||||
|
dataIndex: 'resourceName', |
||||
|
key: 'resourceName', |
||||
|
ellipsis: true, |
||||
|
render: (text, record, index) => { |
||||
|
let data = record.businessMetadataDatabases; |
||||
|
if (data && data.length) |
||||
|
return data[0].resourceName; |
||||
|
else |
||||
|
return '' |
||||
|
} |
||||
|
}, { |
||||
|
title: '信息资源摘要', |
||||
|
dataIndex: 'resourceAbstract', |
||||
|
key: 'resourceAbstract', |
||||
|
ellipsis: true, |
||||
|
render: (text, record, index) => { |
||||
|
let data = record.businessMetadataDatabases; |
||||
|
if (data && data.length) |
||||
|
return data[0].resourceAbstract; |
||||
|
else |
||||
|
return '' |
||||
|
} |
||||
|
}, { |
||||
|
title: '信息资源提供方', |
||||
|
dataIndex: 'resourceProvider', |
||||
|
key: 'resourceProvider', |
||||
|
ellipsis: true, |
||||
|
render: (text, record, index) => { |
||||
|
let data = record.businessMetadataDatabases; |
||||
|
if (data && data.length) |
||||
|
return data[0].resourceProvider; |
||||
|
else |
||||
|
return '' |
||||
|
} |
||||
|
}, { |
||||
|
title: '信息资源分类', |
||||
|
dataIndex: 'resourceCategory', |
||||
|
key: 'resourceCategory', |
||||
|
ellipsis: true, |
||||
|
render: (text, record, index) => { |
||||
|
let data = record.businessMetadataDatabases; |
||||
|
if (data && data.length) |
||||
|
return data[0].resourceCategory; |
||||
|
else |
||||
|
return '' |
||||
|
} |
||||
|
}, { |
||||
|
title: '信息资源标识符', |
||||
|
dataIndex: 'resourceId', |
||||
|
key: 'resourceId', |
||||
|
ellipsis: true, |
||||
|
render: (text, record, index) => { |
||||
|
let data = record.businessMetadataDatabases; |
||||
|
if (data && data.length) |
||||
|
return data[0].resourceId; |
||||
|
else |
||||
|
return '' |
||||
|
} |
||||
|
}, { |
||||
|
title: '元数据标识符', |
||||
|
dataIndex: 'metadataId', |
||||
|
key: 'metadataId', |
||||
|
ellipsis: true, |
||||
|
render: (text, record, index) => { |
||||
|
let data = record.businessMetadataDatabases; |
||||
|
if (data && data.length) |
||||
|
return data[0].metadataId; |
||||
|
else |
||||
|
return '' |
||||
|
} |
||||
|
}, { |
||||
|
title: '创建者', |
||||
|
dataIndex: 'createBy', |
||||
|
key: 'createBy', |
||||
|
ellipsis: true, |
||||
|
render: (text, record, index) => { |
||||
|
let data = record.businessMetadataDatabases; |
||||
|
if (data && data.length) |
||||
|
return data[0].user.username; |
||||
|
else |
||||
|
return '' |
||||
|
} |
||||
|
}, { |
||||
|
title: '最后执行时间', |
||||
|
dataIndex: 'updateAt', |
||||
|
key: 'updateAt', |
||||
|
width: '8%', |
||||
|
sortOrder: updateAtSort, |
||||
|
sorter: (a, b) => moment(a.updateAt).valueOf() - moment(b.updateAt).valueOf(), |
||||
|
sortDirections: ['descend', 'ascend', 'descend'], |
||||
|
render: (text, record, index) => { |
||||
|
let data = record.businessMetadataDatabases; |
||||
|
if (data && data.length) |
||||
|
return data[0].updateAt && moment(data[0].updateAt).format('YYYY-MM-DD HH:mm:ss') |
||||
|
else |
||||
|
return '' |
||||
|
} |
||||
|
}, { |
||||
|
title: '操作', |
||||
|
dataIndex: 'action', |
||||
|
width: '5%', |
||||
|
fixed: 'right', |
||||
|
render: (text, record) => { |
||||
|
if (record.businessMetadataDatabases.length) { |
||||
|
return <div> |
||||
|
<a style={{ marginLeft: 10 }} onClick={() => onAdd(record, false)}>查看</a> |
||||
|
<Popconfirm |
||||
|
title="是否确认删除该业务元数据?" |
||||
|
onConfirm={() => confirmDelete(record.businessMetadataDatabases[0].id)} |
||||
|
> <a style={{ marginLeft: 10 }}>删除</a></Popconfirm> |
||||
|
</div> |
||||
|
} else |
||||
|
return <a style={{ marginLeft: 10 }} onClick={() => onAdd(record, true)}>新建</a> |
||||
|
} |
||||
|
}]; |
||||
|
|
||||
|
const onSearch = () => { |
||||
|
setSelectedRowKeys([]); |
||||
|
setSelectedRows([]); |
||||
|
setCurrentPage(1); |
||||
|
initData({ limit, offset: 0, orderDirection: SortValues[updateAtSort] }); |
||||
|
} |
||||
|
const handleExport = (isAll = false) => { |
||||
|
let tableHeader = `<tr>`; |
||||
|
columns.filter(c => c.dataIndex != 'action').map(c => { tableHeader += `<th><div>${c.title}</div></th>`; }); |
||||
|
tableHeader += '</tr>'; |
||||
|
if (isAll) { |
||||
|
dispatch(metadataManagement.getBusinessMetadata({ catalog: resourceCatalogId })).then(res => { |
||||
|
if (res.success) { |
||||
|
handleExportTable(tableHeader, res.payload.data.rows); |
||||
|
} |
||||
|
}) |
||||
|
} else { |
||||
|
let data = [] |
||||
|
if (updateAtSort === 'descend') { |
||||
|
data = selectedRows.sort((a, b) => moment(b.updateAt).valueOf() - moment(a.updateAt).valueOf()); |
||||
|
} else { |
||||
|
data = selectedRows.sort((a, b) => moment(a.updateAt).valueOf() - moment(b.updateAt).valueOf()); |
||||
|
} |
||||
|
handleExportTable(tableHeader, data); |
||||
|
} |
||||
|
} |
||||
|
const handleExportTable = (tableHeader, contentData) => { |
||||
|
let tableContent = ''; |
||||
|
contentData.map(cd => { |
||||
|
tableContent += `<tr>`; |
||||
|
tableContent += `<th style="font-weight:600"><div>${cd.parentDataName}</div></th>`; |
||||
|
tableContent += `<th style="font-weight:600"><div>${cd.name}</div></th>`; |
||||
|
tableContent += `<th style="font-weight:600"><div>${cd.code}</div></th>`; |
||||
|
tableContent += `<th style="font-weight:600"><div>${cd.type}</div></th>`; |
||||
|
let data = cd.businessMetadataDatabases; |
||||
|
tableContent += `<th style="font-weight:600"><div>${data && data.length && data[0].resourceName || ''}</div></th>`; |
||||
|
tableContent += `<th style="font-weight:600"><div>${data && data.length && data[0].resourceAbstract || ''}</div></th>`; |
||||
|
tableContent += `<th style="font-weight:600"><div>${data && data.length && data[0].resourceProvider || ''}</div></th>`; |
||||
|
tableContent += `<th style="font-weight:600"><div>${data && data.length && data[0].resourceCategory || ''}</div></th>`; |
||||
|
tableContent += `<th style="font-weight:600"><div>${data && data.length && data[0].resourceId || ''}</div></th>`; |
||||
|
tableContent += `<th style="font-weight:600"><div>${data && data.length && data[0].metadataId || ''}</div></th>`; |
||||
|
tableContent += `<th style="font-weight:600"><div>${data && data.length && data[0].user.username || ''}</div></th>`; |
||||
|
tableContent += `<th style="font-weight:600"><div>${data && data.length && data[0].updateAt && |
||||
|
moment(data[0].updateAt).format('YYYY-MM-DD HH:mm:ss') || ''}</div></th>`; |
||||
|
|
||||
|
tableContent += `</tr>`; |
||||
|
}) |
||||
|
let exportTable = `\uFEFF<table border="1">
|
||||
|
${tableHeader} |
||||
|
${tableContent} |
||||
|
</table>`; |
||||
|
let tempStr = new Blob([exportTable], { type: 'text/plain;charset=utf-8' }); |
||||
|
FileSaver.saveAs(tempStr, `表业务元数据导出.xls`); |
||||
|
} |
||||
|
//新建、修改
|
||||
|
const onConfirm = (values) => { |
||||
|
let obj = {} |
||||
|
if (editData.add) { |
||||
|
obj = { createBy: user.id, metadataDatabaseId: editData.record.id, ...values } |
||||
|
dispatch(metadataManagement.postBusinessMetadata(obj)).then(() => { |
||||
|
onSearch(); setModalVisible(false); |
||||
|
}); |
||||
|
} else { |
||||
|
obj = { ...values } |
||||
|
dispatch(metadataManagement.putBusinessMetadata(editData.record.businessMetadataDatabases[0].id, obj)).then(res => { |
||||
|
if (res.success) { |
||||
|
onSearch(); setModalVisible(false); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
return <Spin spinning={isRequesting}> |
||||
|
<div style={{ marginBottom: 16 }}> |
||||
|
{ |
||||
|
tableDataCount == 0 ? <Button disabled={tableDataCount == 0} onClick={() => handleExport()}>导出</Button> : |
||||
|
selectedRowKeys && selectedRowKeys.length ? |
||||
|
<Button disabled={tableDataCount == 0} onClick={() => handleExport()}>导出</Button> |
||||
|
: <Popconfirm title={'是否导出全部?'} onConfirm={() => handleExport(true)} okText="确定" cancelText="取消"> |
||||
|
<Button disabled={tableDataCount == 0} > 导出</Button> |
||||
|
</Popconfirm> |
||||
|
} |
||||
|
<Button type='primary' style={{ marginLeft: 16, float: 'right' }} onClick={onSearch}>查询</Button> |
||||
|
<Input style={{ width: 220, float: 'right' }} placeholder="元数据名称/代码" |
||||
|
allowClear onPressEnter={onSearch} onChange={e => setKeywords(e.target.value || '')} /> |
||||
|
</div > |
||||
|
<Table |
||||
|
scroll={{ y: clientHeight - 320, x: 1800 }} |
||||
|
rowKey='id' |
||||
|
columns={columns} |
||||
|
dataSource={tableData} |
||||
|
onChange={onTableChange} |
||||
|
pagination={{ |
||||
|
current: currentPage, |
||||
|
pageSize: limit, |
||||
|
total: tableDataCount, |
||||
|
showSizeChanger: true, |
||||
|
// showQuickJumper: true,
|
||||
|
showTotal: (total) => { return <span style={{ fontSize: 15 }}>{`共${Math.ceil(total / limit)}页,${total}项`}</span> }, |
||||
|
|
||||
|
}} |
||||
|
rowSelection={{ |
||||
|
onChange: (selectedRowKeys, selectedRows) => { |
||||
|
setSelectedRowKeys(selectedRowKeys) |
||||
|
setSelectedRows(selectedRows); |
||||
|
}, |
||||
|
selectedRowKeys: selectedRowKeys |
||||
|
}} |
||||
|
> |
||||
|
</Table> |
||||
|
{ |
||||
|
modalVisible ? |
||||
|
<BusinessDatabaseModal |
||||
|
metadataModels={metadataModels.filter(m => '表' === m.modelType)} |
||||
|
editData={editData} |
||||
|
onCancel={() => setModalVisible(false)} |
||||
|
onConfirm={onConfirm} |
||||
|
resourceCatalogPath={resourceCatalogPath} /> : '' |
||||
|
} |
||||
|
</Spin > |
||||
|
} |
||||
|
function mapStateToProps(state) { |
||||
|
const { global, auth, metadataDatabases, metadataModels } = state; |
||||
|
return { |
||||
|
user: auth.user, |
||||
|
actions: global.actions, |
||||
|
clientHeight: global.clientHeight, |
||||
|
isRequesting: metadataDatabases.isRequesting || metadataModels.isRequesting, |
||||
|
metadataModels: metadataModels.data |
||||
|
}; |
||||
|
} |
||||
|
export default connect(mapStateToProps)(BusinessDatabaseTable) |
@ -1,7 +1,131 @@ |
|||||
import React, { useEffect, useState } from 'react' |
import React, { useEffect, useState } from 'react'; |
||||
|
import { connect } from 'react-redux'; |
||||
|
import { Spin, Row, Col, Tree, Tooltip } from 'antd'; |
||||
|
import theStyle from './style.css'; |
||||
|
import BusinessTab from './businessTab'; |
||||
|
let expandedKeysData = []; |
||||
|
let allTreeNodeKeys = []; |
||||
|
|
||||
function BusinessMetadata (props) { |
const BusinessMetadata = (props) => { |
||||
return <>业务元数据管理</> |
const { user, dispatch, actions, clientHeight, isRequesting } = props; |
||||
|
const { metadataManagement } = actions; |
||||
|
const [resourceCatalogData, setResourceCatalogData] = useState([]); |
||||
|
const [selectedKeys, setSelectedKeys] = useState([]); |
||||
|
const [expandedKeys, setExpandedKeys] = useState([]); |
||||
|
const [modalVisible, setModalVisible] = useState(false); |
||||
|
const [resourceCatalogId, setResourceCatalogId] = useState(''); |
||||
|
const [resourceCatalogKey, setResourceCatalogKey] = useState(''); |
||||
|
const [resourceCatalogPath, setResourceCatalogPath] = useState([]); |
||||
|
|
||||
|
useEffect(() => { |
||||
|
const jumpBusinessSelectedKey = sessionStorage.getItem('jumpBusinessSelectedKey') || null; |
||||
|
initData(jumpBusinessSelectedKey); |
||||
|
}, []) |
||||
|
const initData = (jumpBusinessSelectedKey) => { |
||||
|
dispatch(metadataManagement.getResourceCatalog()).then(res => { |
||||
|
const { data } = res.payload; |
||||
|
if (res.success) { |
||||
|
allTreeNodeKeys = [] |
||||
|
const resourceCatalogData = getTreeNodeData(data, null, 'rc'); |
||||
|
setResourceCatalogData(resourceCatalogData); |
||||
|
if (data.length) { |
||||
|
if (jumpBusinessSelectedKey || selectedKeys.length) |
||||
|
expandedKeysData = jumpBusinessSelectedKey ? [jumpBusinessSelectedKey] : selectedKeys; |
||||
|
let expandedKeys = getExpandKeys(expandedKeysData); |
||||
|
setSelectedKeys(expandedKeysData); |
||||
|
setExpandedKeys(expandedKeys); |
||||
|
expandedKeysData = []; |
||||
|
} else { |
||||
|
setExpandedKeys([]); |
||||
|
setSelectedKeys([]); |
||||
|
}; |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
const getExpandKeys = (selectedData) => { |
||||
|
const keyArr = selectedData[0].split('-'); |
||||
|
keyArr.shift();//['rc-2-5']->返回'rc';keyArr:['2','5']
|
||||
|
const allExpandedKeys = allTreeNodeKeys.filter(k => keyArr.includes(k.id.toString())); |
||||
|
setResourceCatalogId(keyArr.pop()); |
||||
|
setResourceCatalogKey(selectedData[0]); |
||||
|
const resourceCatalogPath = allExpandedKeys.map(a => a.name); |
||||
|
setResourceCatalogPath(resourceCatalogPath); |
||||
|
return allExpandedKeys.map(a => a.key); |
||||
|
} |
||||
|
const getTreeNodeData = (dataSource, parent, key) => { |
||||
|
let treeData = []; |
||||
|
let data = []; |
||||
|
if (!parent) { |
||||
|
data = dataSource.filter(ds => !ds.parent); |
||||
|
if (!expandedKeysData.length && data.length) { |
||||
|
expandedKeysData.push(`rc-${data[0].id}`); |
||||
|
} |
||||
|
} else { |
||||
|
data = dataSource.filter(ds => ds.parent == parent); |
||||
|
} |
||||
|
treeData = data.map(ds => { |
||||
|
allTreeNodeKeys.push({ name: ds.name, key: `${key}-${ds.id}`, id: ds.id }) |
||||
|
return { title: renderTreeNode(ds), key: `${key}-${ds.id}`, id: ds.id } |
||||
|
}); |
||||
|
for (let d of treeData) { |
||||
|
d.children = getTreeNodeData(dataSource, d.id, d.key); |
||||
|
} |
||||
|
return treeData |
||||
} |
} |
||||
|
|
||||
export default BusinessMetadata |
const setTreeNodeTitle = (name) => { |
||||
|
let content = <span>{name}</span> |
||||
|
if (name.length > 6) { |
||||
|
content = <Tooltip title={name}> |
||||
|
{name.substring(0, 6) + '...'} |
||||
|
</Tooltip> |
||||
|
} |
||||
|
return content; |
||||
|
} |
||||
|
|
||||
|
const renderTreeNode = (ds) => { |
||||
|
return <div className={theStyle.icon} style={{ width: 180 }}> |
||||
|
{setTreeNodeTitle(ds.name)} |
||||
|
</div > |
||||
|
}; |
||||
|
return <Spin spinning={isRequesting}> |
||||
|
<Row> |
||||
|
<Col style={{ width: 240 }}> |
||||
|
<Tree |
||||
|
// showLine
|
||||
|
height={clientHeight - 180} |
||||
|
expandedKeys={expandedKeys} |
||||
|
selectedKeys={selectedKeys} |
||||
|
onSelect={(keys, e) => { |
||||
|
if (e.selected) { |
||||
|
setSelectedKeys(keys); |
||||
|
getExpandKeys(keys); |
||||
|
} |
||||
|
sessionStorage.setItem('jumpBusinessSelectedKey', keys.length ? keys[0] : selectedKeys && selectedKeys[0]); |
||||
|
}} |
||||
|
onExpand={(keys) => { |
||||
|
setExpandedKeys(keys); |
||||
|
}} |
||||
|
treeData={resourceCatalogData} |
||||
|
/> |
||||
|
</Col> |
||||
|
<Col style={{ width: 'calc(100% - 240px)' }}> |
||||
|
<BusinessTab resourceCatalogId={resourceCatalogId} |
||||
|
resourceCatalogKey={resourceCatalogKey} |
||||
|
resourceCatalogPath={resourceCatalogPath} /> |
||||
|
</Col> |
||||
|
</Row> |
||||
|
</Spin> |
||||
|
} |
||||
|
|
||||
|
function mapStateToProps(state) { |
||||
|
const { global, auth, resourceCatalog } = state; |
||||
|
return { |
||||
|
user: auth.user, |
||||
|
actions: global.actions, |
||||
|
clientHeight: global.clientHeight, |
||||
|
resourceCatalog: resourceCatalog?.data || [], |
||||
|
isRequesting: resourceCatalog.isRequesting |
||||
|
}; |
||||
|
} |
||||
|
export default connect(mapStateToProps)(BusinessMetadata) |
@ -0,0 +1,55 @@ |
|||||
|
import React, { useEffect, useState } from 'react'; |
||||
|
import { connect } from 'react-redux'; |
||||
|
import { Tabs } from 'antd'; |
||||
|
import BusinessDatabaseTable from './businessDatabaseTable'; |
||||
|
// import BusinessFilesTable from './businessFilesTable';
|
||||
|
// import BusinessRestapisTable from './businessRestapisTable';
|
||||
|
|
||||
|
const BusinessTab = (props) => { |
||||
|
const { resourceCatalogId, resourceCatalogKey, resourceCatalogPath, actions, dispatch } = props; |
||||
|
const [activeKey, setActiveKey] = useState('databases'); |
||||
|
useEffect(() => { |
||||
|
setActiveKey('databases'); |
||||
|
}, [resourceCatalogId]); |
||||
|
|
||||
|
const onTabChange = (key) => { |
||||
|
setActiveKey(key) |
||||
|
} |
||||
|
return <div> |
||||
|
<Tabs defaultActiveKey="databases" |
||||
|
onChange={onTabChange} |
||||
|
activeKey={activeKey} |
||||
|
items={[ |
||||
|
{ |
||||
|
label: <span> 表 </span>, |
||||
|
key: 'databases' |
||||
|
}, |
||||
|
{ |
||||
|
label: <span> 文件 </span>, |
||||
|
key: 'files' |
||||
|
}, |
||||
|
{ |
||||
|
label: <span> 接口 </span>, |
||||
|
key: 'restapis' |
||||
|
} |
||||
|
]}> |
||||
|
</Tabs> |
||||
|
{ |
||||
|
activeKey === 'databases' && resourceCatalogId ? <BusinessDatabaseTable resourceCatalogId={resourceCatalogId} |
||||
|
resourceCatalogKey={resourceCatalogKey} resourceCatalogPath={resourceCatalogPath} /> : |
||||
|
// activeKey === 'files' && resourceCatalogId ? <BusinessFilesTable resourceCatalogId={resourceCatalogId}
|
||||
|
// resourceCatalogKey={resourceCatalogKey} resourceCatalogPath={resourceCatalogPath} /> :
|
||||
|
// activeKey === 'restapis' && resourceCatalogId ? <BusinessRestapisTable resourceCatalogId={resourceCatalogId}
|
||||
|
// resourceCatalogKey={resourceCatalogKey} resourceCatalogPath={resourceCatalogPath} /> :
|
||||
|
null |
||||
|
} |
||||
|
</div> |
||||
|
} |
||||
|
function mapStateToProps(state) { |
||||
|
const { global, auth } = state; |
||||
|
return { |
||||
|
user: auth.user, |
||||
|
actions: global.actions |
||||
|
}; |
||||
|
} |
||||
|
export default connect(mapStateToProps)(BusinessTab) |
Loading…
Reference in new issue