diff --git a/web/client/src/sections/metadataManagement/actions/metadata.js b/web/client/src/sections/metadataManagement/actions/metadata.js index bafacd9..653cc43 100644 --- a/web/client/src/sections/metadataManagement/actions/metadata.js +++ b/web/client/src/sections/metadataManagement/actions/metadata.js @@ -50,4 +50,40 @@ export function delResourceCatalog(id) { option: '删除资源目录', } }); +} + +export function getMetadataDatabases(params) { + return dispatch => basicAction({ + type: 'get', + dispatch: dispatch, + query: params, + actionType: 'GET_METADATA_DATABASES_LIST', + url: ApiTable.getMetadataDatabases, + msg: { error: '获取库表元数据列表失败' }, + reducer: { name: 'metadataDatabases' } + }); +} + +export function getMetadataFiles(params) { + return dispatch => basicAction({ + type: 'get', + dispatch: dispatch, + query: params, + actionType: 'GET_METADATA_FILES_LIST', + url: ApiTable.getMetadataFiles, + msg: { error: '获取文件元数据列表失败' }, + reducer: { name: 'metadataFiles' } + }); +} + +export function getMetadataRestapis(params) { + return dispatch => basicAction({ + type: 'get', + dispatch: dispatch, + query: params, + actionType: 'GET_METADATA_RESTAPIS_LIST', + url: ApiTable.getMetadataRestapis, + msg: { error: '获取接口元数据列表失败' }, + reducer: { name: 'metadataRestapis' } + }); } \ No newline at end of file diff --git a/web/client/src/sections/metadataManagement/containers/databasesTable.js b/web/client/src/sections/metadataManagement/containers/databasesTable.js new file mode 100644 index 0000000..33cec0b --- /dev/null +++ b/web/client/src/sections/metadataManagement/containers/databasesTable.js @@ -0,0 +1,185 @@ +import React, { useEffect, useState } from 'react'; +import { connect } from 'react-redux'; +import { Spin, Table, Popconfirm, Button, Input } from 'antd'; +import moment from 'moment'; + +const DatabaseTable = (props) => { + const { user, dispatch, actions, clientHeight, resourceCatalogId, isRequesting } = props; + const { metadataManagement } = actions; + const SortValues = { 'ascend': 'asc', 'descend': 'desc' }; + const [tableData, setTableData] = useState([]); + const [tableDataCount, setTableDataCount] = useState(0);//Table数据 + const [createAtSort, setCreateAtSort] = useState('descend'); + const [keywords, setKeywords] = useState(''); + const [limit, setLimit] = useState(10); + const [currentPage, setCurrentPage] = useState(1); + const [selectedRowKeys, setSelectedRowKeys] = useState([]); + + useEffect(() => { + setCreateAtSort('descend'); + initData({ limit, offset: currentPage - 1, orderDirection: SortValues[createAtSort] }); + }, [resourceCatalogId]); + + const initData = (query = {}) => { + dispatch(metadataManagement.getMetadataDatabases({ catalog: resourceCatalogId, keywords, orderBy: 'createAt', ...query })).then(res => { + if (res.success) { + setTableData(res.payload.data.rows); + setTableDataCount(res.payload.data.count); + } + }) + } + const onView = (id) => { } + const onEdit = (record) => { } + const confirmDelete = (id) => { } + const marking = (id) => { } + const applyResources = (id) => { } + + 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[createAtSort] }; + if (sorter.columnKey === 'createAt') { + query.orderDirection = SortValues[sorter.order]; + setCreateAtSort(sorter.order); + } + initData(query); + } + const columns = [{ + title: '名称', + dataIndex: 'name', + key: 'name', + width: '15%' + }, { + title: '代码', + dataIndex: 'code', + key: 'code', + width: '15%' + }, { + title: '元数据类型', + dataIndex: 'type', + key: 'type', + width: '10%' + }, { + title: '标签', + dataIndex: 'tags', + key: 'tags', + width: '13%', + render: (text, record, index) => { + let tagName = record.tagDatabases.map(tagSet => tagSet.tag.name); + return tagName.join(','); + } + }, { + title: '创建者', + dataIndex: 'createBy', + key: 'createBy', + width: '10%', + render: (text, record, index) => { + return record.user.username || '' + } + }, { + title: '创建时间', + dataIndex: 'createAt', + key: 'createAt', + width: '17%', + sortOrder: createAtSort, + sorter: (a, b) => moment(a.createAt).valueOf() - moment(b.createAt).valueOf(), + sortDirections: ['descend', 'ascend', 'descend'], + render: (text, record, index) => { + return moment(text).format('YYYY-MM-DD HH:mm:ss') + } + }, { + title: '操作', + dataIndex: 'action', + width: '20%', + render: (text, record) => { + return
+ onView(id)}>查看 +    + onEdit(record)}>编辑 +    + confirmDelete(record.id)} + > 删除 +    + marking(record.id)}>打标 +    + applyResources(record.id)}>申请资源 +
+ } + }]; + + const onSearch = () => { + setCurrentPage(1); + initData({ limit, offset: 0, orderDirection: SortValues[createAtSort] }); + } + const handleExport = (isAll = false) => { + + } + return +
+ + {selectedRowKeys && selectedRowKeys.length ? + + : handleExport(true)} okText="确定" cancelText="取消"> + + + } + + setKeywords(e.target.value || '')} /> +
+ { return {`共${Math.ceil(total / limit)}页,${total}项`} }, + onShowSizeChange: (currentPage, pageSize) => { + setCurrentPage(currentPage); + setLimit(pageSize); + }, + onChange: (page, pageSize) => { + setCurrentPage(page); + setLimit(pageSize); + let queryParams = { + orderDirection: SortValues[createAtSort], + page: page - 1, + size: pageSize + }; + initData(queryParams); + } + }} + rowSelection={{ + onChange: (selectedRowKeys, selectedRows) => { + setSelectedRowKeys(selectedRowKeys) + }, + selectedRowKeys: selectedRowKeys + }} + > +
+
+ +} +function mapStateToProps(state) { + const { global, auth, metadataDatabases } = state; + return { + user: auth.user, + actions: global.actions, + clientHeight: global.clientHeight, + isRequesting: metadataDatabases.isRequesting, + }; +} +export default connect(mapStateToProps)(DatabaseTable) \ No newline at end of file diff --git a/web/client/src/sections/metadataManagement/containers/filesTable.js b/web/client/src/sections/metadataManagement/containers/filesTable.js new file mode 100644 index 0000000..1bbd6e3 --- /dev/null +++ b/web/client/src/sections/metadataManagement/containers/filesTable.js @@ -0,0 +1,105 @@ +import React, { useEffect, useState } from 'react'; +import { connect } from 'react-redux'; +import { Spin, Table, Popconfirm } from 'antd'; +import moment from 'moment'; + +const FilesTable = (props) => { + const { user, dispatch, actions, clientHeight, resourceCatalogId, isRequesting } = props; + const { metadataManagement } = actions; + const [resourceCatalogData, setResourceCatalogData] = useState([]); + const [limit, setLimit] = useState(10) + const [offset, setOffset] = useState(0) + + useEffect(() => { + initData(resourceCatalogId); + }, []); + + const initData = (resourceCatalogId) => { + dispatch(metadataManagement.getMetadataFiles({ catalog: resourceCatalogId, limit, offset })).then(res => { + const { data } = res.payload; + if (res.success) { + + } + }) + } + const onEdit = (record) => { } + const confirmDelete = (id) => { } + const marking = (id) => { } + const applyResources = (id) => { } + const columns = [{ + title: '文件名称', + dataIndex: 'name', + key: 'name', + width: '20%' + }, { + title: '文件描述', + dataIndex: 'description', + key: 'description', + width: '20%' + }, { + title: '文件类型', + dataIndex: 'type', + key: 'type', + width: '20%' + }, { + title: '标签', + dataIndex: 'tags', + key: 'tags', + width: '20%' + }, { + title: '大小', + dataIndex: 'size', + key: 'size', + width: '20%' + }, { + title: '创建者', + dataIndex: 'createBy', + key: 'createBy', + width: '10%', + }, { + title: '修改时间', + dataIndex: 'updateAt', + key: 'updateAt', + width: '20%', + render: (text, record, index) => { + return text ? moment(text).format('YYYY-MM-DD HH:mm') : '' + } + }, { + title: '操作', + dataIndex: 'action', + width: '20%', + render: (text, record) => { + return
+ onEdit(record)}>编辑 +    + confirmDelete(record.id)} + > 删除 +    + marking(record.id)}>打标 +    + applyResources(record.id)}>申请资源 +
+ } + }]; + + return + +
+
+ +} +function mapStateToProps(state) { + const { global, auth, metadataFiles } = state; + return { + user: auth.user, + actions: global.actions, + clientHeight: global.clientHeight, + isRequesting: metadataFiles.isRequesting + }; +} +export default connect(mapStateToProps)(FilesTable) \ No newline at end of file diff --git a/web/client/src/sections/metadataManagement/containers/latestMetadata.js b/web/client/src/sections/metadataManagement/containers/latestMetadata.js index 4f9a791..12f8850 100644 --- a/web/client/src/sections/metadataManagement/containers/latestMetadata.js +++ b/web/client/src/sections/metadataManagement/containers/latestMetadata.js @@ -4,6 +4,7 @@ import { Spin, Row, Col, Tree, Button, Tooltip, Popconfirm } from 'antd'; import { PlusCircleOutlined, EditOutlined, MinusCircleOutlined } from '@ant-design/icons'; import theStyle from './style.css'; import ResourceCatalogModal from '../components/resourceCatalogModal'; +import MetadataTab from './metadataTab'; let expandedKeysData = []; const LatestMetadata = (props) => { @@ -14,6 +15,7 @@ const LatestMetadata = (props) => { const [expandedKeys, setExpandedKeys] = useState([]); const [modalVisible, setModalVisible] = useState(false); const [editData, setEditData] = useState({}); + const [resourceCatalogId, setResourceCatalogId] = useState(''); useEffect(() => { initData(true); @@ -28,6 +30,8 @@ const LatestMetadata = (props) => { if (configRefresh) { setExpandedKeys(expandedKeysData); setSelectedKeys(expandedKeysData); + let id = expandedKeysData[0].split('-').pop(); + setResourceCatalogId(id); } } else { setExpandedKeys([]); @@ -120,11 +124,12 @@ const LatestMetadata = (props) => { selectedKeys={selectedKeys} onSelect={(keys, e) => { if (e.selected) { - // setCurrentPage(1); setSelectedKeys(keys); // let keyArr = allTreeNodeKeys.filter(ak => ak.key.includes(keys[0])); // let ids = keyArr.map(key => key.id); // console.log('all-' + JSON.stringify(ids)) + let id = keys[0].split('-').pop(); + setResourceCatalogId(id); } }} onExpand={(keys) => { @@ -134,7 +139,7 @@ const LatestMetadata = (props) => { /> - + { diff --git a/web/client/src/sections/metadataManagement/containers/metadataTab.js b/web/client/src/sections/metadataManagement/containers/metadataTab.js new file mode 100644 index 0000000..01bd5ad --- /dev/null +++ b/web/client/src/sections/metadataManagement/containers/metadataTab.js @@ -0,0 +1,51 @@ +import React, { useEffect, useState } from 'react'; +import { connect } from 'react-redux'; +import { Tabs } from 'antd'; +import DatabaseTable from './databasesTable'; +import FilesTable from './filesTable'; +import RestapisTable from './restapisTable'; + +const MetadataTab = (props) => { + const { resourceCatalogId, actions, dispatch } = props; + const [activeKey, setActiveKey] = useState('databases'); + useEffect(() => { + setActiveKey('databases'); + }, [resourceCatalogId]); + + const onTabChange = (key) => { + setActiveKey(key) + } + return <> +       库表      , + key: 'databases' + }, + { + label:       文件      , + key: 'files' + }, + { + label:       接口      , + key: 'restapis' + } + ]}> + + { + activeKey === 'databases' && resourceCatalogId ? : + activeKey === 'files' && resourceCatalogId ? : + activeKey === 'restapis' && resourceCatalogId ? < RestapisTable resourceCatalogId={resourceCatalogId} /> : null + } + +} +function mapStateToProps(state) { + const { global, auth } = state; + return { + user: auth.user, + actions: global.actions + }; +} +export default connect(mapStateToProps)(MetadataTab) \ No newline at end of file diff --git a/web/client/src/sections/metadataManagement/containers/restapisTable.js b/web/client/src/sections/metadataManagement/containers/restapisTable.js new file mode 100644 index 0000000..c7904d0 --- /dev/null +++ b/web/client/src/sections/metadataManagement/containers/restapisTable.js @@ -0,0 +1,102 @@ +import React, { useEffect, useState } from 'react'; +import { connect } from 'react-redux'; +import { Spin, Table, Popconfirm } from 'antd'; +import moment from 'moment'; + +const RestapisTable = (props) => { + const { user, dispatch, actions, clientHeight, resourceCatalogId, isRequesting } = props; + const { metadataManagement } = actions; + const [resourceCatalogData, setResourceCatalogData] = useState([]); + const [limit, setLimit] = useState(10) + const [offset, setOffset] = useState(0) + + useEffect(() => { + initData(); + }, []); + + const initData = () => { + dispatch(metadataManagement.getMetadataRestapis({ catalog: resourceCatalogId, limit, offset })).then(res => { + const { data } = res.payload; + if (res.success) { + + } + }) + } + const onEdit = (record) => { } + const confirmDelete = (id) => { } + const marking = (id) => { } + const applyResources = (id) => { } + const columns = [{ + title: '接口名称', + dataIndex: 'name', + key: 'name', + width: '20%' + }, { + title: '接口路由', + dataIndex: 'url', + key: 'url', + width: '20%' + }, { + title: '接口类型', + dataIndex: 'method', + key: 'method', + width: '10%' + }, { + title: '传参', + dataIndex: 'queryParam', + key: 'queryParam', + width: '20%' + }, { + title: '返回值', + dataIndex: 'return', + key: 'return', + width: '20%' + }, { + title: '标签', + dataIndex: 'tags', + key: 'tags', + width: '20%' + }, { + title: '状态', + dataIndex: 'enabled', + key: 'enabled', + width: '10%' + }, { + title: '操作', + dataIndex: 'action', + width: '20%', + render: (text, record) => { + return
+ onEdit(record)}>编辑 +    + confirmDelete(record.id)} + > 删除 +    + marking(record.id)}>打标 +    + applyResources(record.id)}>申请资源 +
+ } + }]; + + return + +
+
+ +} +function mapStateToProps(state) { + const { global, auth, metadataRestapis } = state; + return { + user: auth.user, + actions: global.actions, + clientHeight: global.clientHeight, + isRequesting: metadataRestapis.isRequesting + }; +} +export default connect(mapStateToProps)(RestapisTable) \ No newline at end of file