diff --git a/web/client/src/sections/metadataManagement/actions/businessMetadata.js b/web/client/src/sections/metadataManagement/actions/businessMetadata.js index 377d345..e28ec2e 100644 --- a/web/client/src/sections/metadataManagement/actions/businessMetadata.js +++ b/web/client/src/sections/metadataManagement/actions/businessMetadata.js @@ -51,3 +51,53 @@ export function delBusinessMetadataDatabases(id) { } }); } + + +export function getBusinessMetadataFiles(params) { + return dispatch => basicAction({ + type: 'get', + dispatch: dispatch, + query: params, + actionType: 'GET_BUSINESS_METADATA_FILES_LIST', + url: ApiTable.getBusinessMetadataFiles, + msg: { error: '获取业务元数据列表失败' }, + reducer: { name: 'businessMetadataFiles' } + }); +} + +export function postBusinessMetadataFiles(data) { + return dispatch => basicAction({ + type: 'post', + data: data, + dispatch: dispatch, + actionType: 'POST_BUSINESS_METADATA_FILES', + url: ApiTable.postBusinessMetadataFiles, + msg: { option: '新建业务元数据' }, + reducer: {} + }); +} + +export function putBusinessMetadataFiles(id, data) { + return dispatch => basicAction({ + type: 'put', + data: data, + dispatch, + actionType: 'PUT_BUSINESS_METADATA_FILES', + url: ApiTable.putBusinessMetadataFiles.replace('{id}', id), + msg: { + option: '修改业务元数据', + } + }); +} + +export function delBusinessMetadataFiles(id) { + return dispatch => basicAction({ + type: 'del', + dispatch, + actionType: 'DELETE_BUSINESS_METADATA_FILES', + url: ApiTable.delBusinessMetadataFiles.replace('{id}', id), + msg: { + option: '删除业务元数据', + } + }); +} diff --git a/web/client/src/sections/metadataManagement/components/businessDatabaseModal.js b/web/client/src/sections/metadataManagement/components/businessDatabaseModal.js index 6dd8aaa..376f38f 100644 --- a/web/client/src/sections/metadataManagement/components/businessDatabaseModal.js +++ b/web/client/src/sections/metadataManagement/components/businessDatabaseModal.js @@ -1,7 +1,12 @@ import React, { useEffect, useState } from 'react'; import { Modal, Input, Form, Row, Col } from 'antd'; +const basicInfo = [{ name: '元数据名称:', key: 'name' }, +{ name: '元数据代码:', key: 'code' }, +{ name: '元数据类型:', key: 'type' }, +{ name: '上下文路径:', key: 'path' }, +{ name: '元数据详情:', key: 'description' }]; const BusinessDatabaseModal = (props) => { - const { onConfirm, onCancel, editData, metadataModels, resourceCatalogPath } = props; + const { onConfirm, onCancel, editData, metadataModels, resourceCatalogPath, businessType } = props; const [form] = Form.useForm(); useEffect(() => { }, []); @@ -20,19 +25,19 @@ const BusinessDatabaseModal = (props) => { } const renderBasicInfo = (databasesRecord) => { let path = '/' + resourceCatalogPath.join('/'); + let mapData = basicInfo; + if (businessType) + mapData = basicInfo.filter(bi => bi.key != 'code'); return
基本信息
- {[{ name: '元数据名称:', key: 'name' }, - { name: '元数据代码:', key: 'code' }, - { name: '元数据类型:', key: 'type' }, - { name: '上下文路径:', key: 'path' }, - { name: '元数据详情:', key: 'description' }].map(item => { + {mapData.map(item => { if (item.key != 'path') return
{item.name}{ - databasesRecord[item.key] && databasesRecord[item.key].length > (item.key === 'description' ? 40 : 15) ? - databasesRecord[item.key].substring(0, (item.key === 'description' ? 40 : 15)) + '...' : databasesRecord[item.key]}
+ businessType && item.key === 'type' ? businessType : + databasesRecord[item.key] && databasesRecord[item.key].length > (item.key === 'description' ? 40 : 15) ? + databasesRecord[item.key].substring(0, (item.key === 'description' ? 40 : 15)) + '...' : databasesRecord[item.key]}
else return
{item.name}{path && path.length > 15 ? path.substring(0, 15) + '...' : path}
@@ -42,7 +47,7 @@ const BusinessDatabaseModal = (props) => {
属性
- {metadataModels && metadataModels.filter(mm => mm.modelType === '表').map(mm => { + {metadataModels && metadataModels.filter(mm => mm.modelType === businessType ? businessType : '表').map(mm => { let str = '' if (databasesRecord.attributesParam && databasesRecord.attributesParam[mm.attributeCode]) { str = databasesRecord.attributesParam[mm.attributeCode]; @@ -63,11 +68,11 @@ const BusinessDatabaseModal = (props) => { okText='确定' width={800} onOk={() => handleOk(null)} onCancel={onCancel}> - {editData.record && editData.record.businessMetadataDatabases.length ? + {editData.record && editData.record.businessMetadata.length ? renderBasicInfo(editData.record) : null } -
+ {[{ name: '信息资源名称', key: 'resourceName' }, { name: '信息资源摘要', key: 'resourceAbstract' }, { name: '信息资源提供方', key: 'resourceProvider' }, diff --git a/web/client/src/sections/metadataManagement/containers/businessDatabaseTable.js b/web/client/src/sections/metadataManagement/containers/businessDatabaseTable.js index 0f0a267..f9de168 100644 --- a/web/client/src/sections/metadataManagement/containers/businessDatabaseTable.js +++ b/web/client/src/sections/metadataManagement/containers/businessDatabaseTable.js @@ -37,9 +37,9 @@ const BusinessDatabaseTable = (props) => { dispatch(metadataManagement.getMetadataModels({ modelTypes: '表' })).then(res => { if (res.success) { if (!add) - setEditData({ title: '查看业务元数据', record: { path: '/' + resourceCatalogPath.join('/'), ...record, ...record.attributesParam } }); + setEditData({ title: '查看业务元数据', record: { path: '/' + resourceCatalogPath.join('/'), businessMetadata: record.businessMetadataDatabases, ...record, ...record.attributesParam } }); else - setEditData({ add: true, title: '新建业务元数据', record: { ...record } }); + setEditData({ add: true, title: '新建业务元数据', record: { businessMetadata: record.businessMetadataDatabases, ...record } }); setModalVisible(true); } }) diff --git a/web/client/src/sections/metadataManagement/containers/businessFilesTable.js b/web/client/src/sections/metadataManagement/containers/businessFilesTable.js new file mode 100644 index 0000000..49e91bb --- /dev/null +++ b/web/client/src/sections/metadataManagement/containers/businessFilesTable.js @@ -0,0 +1,334 @@ +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 BusinessFilesTable = (props) => { + const { user, dispatch, actions, clientHeight, resourceCatalogId, + 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'); + onSearch('descend'); + }, []); + + const initData = (query = {}) => { + dispatch(metadataManagement.getBusinessMetadataFiles({ 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('/'), businessMetadata: record.businessMetadataFiles, ...record, ...record.attributesParam } }); + else + setEditData({ add: true, title: '新建业务元数据', record: { businessMetadata: record.businessMetadataFiles, ...record } }); + setModalVisible(true); + } + }) + } + const confirmDelete = (id) => { + dispatch(metadataManagement.delBusinessMetadataFiles(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: 'name', + key: 'name', + ellipsis: true, + fixed: 'left', + width: '7%', + }, { + title: '元数据类型', + dataIndex: 'type', + key: 'type', + fixed: 'left', + width: '6%', + render: (text, record, index) => { + return '文件' + } + }, { + title: '信息资源名称', + dataIndex: 'resourceName', + key: 'resourceName', + ellipsis: true, + render: (text, record, index) => { + let data = record.businessMetadataFiles; + if (data && data.length) + return data[0].resourceName; + else + return '' + } + }, { + title: '信息资源摘要', + dataIndex: 'resourceAbstract', + key: 'resourceAbstract', + ellipsis: true, + render: (text, record, index) => { + let data = record.businessMetadataFiles; + if (data && data.length) + return data[0].resourceAbstract; + else + return '' + } + }, { + title: '信息资源提供方', + dataIndex: 'resourceProvider', + key: 'resourceProvider', + ellipsis: true, + render: (text, record, index) => { + let data = record.businessMetadataFiles; + if (data && data.length) + return data[0].resourceProvider; + else + return '' + } + }, { + title: '信息资源分类', + dataIndex: 'resourceCategory', + key: 'resourceCategory', + ellipsis: true, + render: (text, record, index) => { + let data = record.businessMetadataFiles; + if (data && data.length) + return data[0].resourceCategory; + else + return '' + } + }, { + title: '信息资源标识符', + dataIndex: 'resourceId', + key: 'resourceId', + ellipsis: true, + render: (text, record, index) => { + let data = record.businessMetadataFiles; + if (data && data.length) + return data[0].resourceId; + else + return '' + } + }, { + title: '元数据标识符', + dataIndex: 'metadataId', + key: 'metadataId', + ellipsis: true, + render: (text, record, index) => { + let data = record.businessMetadataFiles; + if (data && data.length) + return data[0].metadataId; + else + return '' + } + }, { + title: '创建者', + dataIndex: 'createBy', + key: 'createBy', + ellipsis: true, + render: (text, record, index) => { + let data = record.businessMetadataFiles; + 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.businessMetadataFiles; + 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.businessMetadataFiles.length) { + return
+ onAdd(record, false)}>查看 + confirmDelete(record.businessMetadataFiles[0].id)} + > 删除 +
+ } else + return onAdd(record, true)}>新建 + } + }]; + + const onSearch = (sort) => { + setSelectedRowKeys([]); + setSelectedRows([]); + setCurrentPage(1); + initData({ limit, offset: 0, orderDirection: SortValues[sort || updateAtSort] }); + } + const handleExport = (isAll = false) => { + let tableHeader = ``; + columns.filter(c => c.dataIndex != 'action').map(c => { tableHeader += `
${c.title}
`; }); + tableHeader += ''; + if (isAll) { + dispatch(metadataManagement.getBusinessMetadataFiles({ 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 += ``; + tableContent += `
${cd.name}
`; + tableContent += `
文件
`; + let data = cd.businessMetadataFiles; + tableContent += `
${data && data.length && data[0].resourceName || ''}
`; + tableContent += `
${data && data.length && data[0].resourceAbstract || ''}
`; + tableContent += `
${data && data.length && data[0].resourceProvider || ''}
`; + tableContent += `
${data && data.length && data[0].resourceCategory || ''}
`; + tableContent += `
${data && data.length && data[0].resourceId || ''}
`; + tableContent += `
${data && data.length && data[0].metadataId || ''}
`; + tableContent += `
${data && data.length && data[0].user.username || ''}
`; + tableContent += `
${data && data.length && data[0].updateAt && + moment(data[0].updateAt).format('YYYY-MM-DD HH:mm:ss') || ''}
`; + + tableContent += ``; + }) + let exportTable = `\uFEFF + ${tableHeader} + ${tableContent} +
`; + 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, metadataFileId: editData.record.id, ...values } + dispatch(metadataManagement.postBusinessMetadataFiles(obj)).then(res => { + if (res.success) { + onSearch(); setModalVisible(false); + } + }); + } else { + obj = { ...values } + dispatch(metadataManagement.putBusinessMetadataFiles(editData.record.businessMetadataFiles[0].id, obj)).then(res => { + if (res.success) { + onSearch(); setModalVisible(false); + } + }); + } + } + return +
+ { + tableDataCount == 0 ? : + selectedRowKeys && selectedRowKeys.length ? + + : handleExport(true)} okText="确定" cancelText="取消"> + + + } + + setKeywords(e.target.value || '')} /> +
+ { return {`共${Math.ceil(total / limit)}页,${total}项`} }, + + }} + rowSelection={{ + onChange: (selectedRowKeys, selectedRows) => { + setSelectedRowKeys(selectedRowKeys) + setSelectedRows(selectedRows); + }, + selectedRowKeys: selectedRowKeys + }} + > +
+ { + modalVisible ? + '文件' === m.modelType)} + editData={editData} + onCancel={() => setModalVisible(false)} + onConfirm={onConfirm} + resourceCatalogPath={resourceCatalogPath} + businessType='文件' /> : '' + } +
+} +function mapStateToProps(state) { + const { global, auth, businessMetadataFiles, metadataModels } = state; + return { + user: auth.user, + actions: global.actions, + clientHeight: global.clientHeight, + isRequesting: businessMetadataFiles.isRequesting || metadataModels.isRequesting, + metadataModels: metadataModels.data + }; +} +export default connect(mapStateToProps)(BusinessFilesTable) \ No newline at end of file diff --git a/web/client/src/sections/metadataManagement/containers/businessTab.js b/web/client/src/sections/metadataManagement/containers/businessTab.js index 1963a62..6a7d8af 100644 --- a/web/client/src/sections/metadataManagement/containers/businessTab.js +++ b/web/client/src/sections/metadataManagement/containers/businessTab.js @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'; import { connect } from 'react-redux'; import { Tabs } from 'antd'; import BusinessDatabaseTable from './businessDatabaseTable'; -// import BusinessFilesTable from './businessFilesTable'; +import BusinessFilesTable from './businessFilesTable'; // import BusinessRestapisTable from './businessRestapisTable'; const BusinessTab = (props) => { @@ -37,11 +37,11 @@ const BusinessTab = (props) => { { activeKey === 'databases' && resourceCatalogId ? : - // activeKey === 'files' && resourceCatalogId ? : - // activeKey === 'restapis' && resourceCatalogId ? : - null + activeKey === 'files' && resourceCatalogId ? : + // activeKey === 'restapis' && resourceCatalogId ? : + null }
} diff --git a/web/client/src/utils/webapi.js b/web/client/src/utils/webapi.js index 3f8fc2c..b53c78e 100644 --- a/web/client/src/utils/webapi.js +++ b/web/client/src/utils/webapi.js @@ -50,6 +50,10 @@ export const ApiTable = { postBusinessMetadataDatabases: 'business/metadata/databases', putBusinessMetadataDatabases: 'business/metadata/databases/{id}', delBusinessMetadataDatabases: 'business/metadata/databases/{id}', + getBusinessMetadataFiles: 'business/metadata/files', + postBusinessMetadataFiles: 'business/metadata/files', + putBusinessMetadataFiles: 'business/metadata/files/{id}', + delBusinessMetadataFiles: 'business/metadata/files/{id}', //元数据采集-数据源管理 pgCheckConnect: 'adapter/check/connect',