diff --git a/api/app/lib/models/data_source.js b/api/app/lib/models/data_source.js index c86538a..37eabf7 100644 --- a/api/app/lib/models/data_source.js +++ b/api/app/lib/models/data_source.js @@ -49,7 +49,7 @@ module.exports = dc => { }, mountPath: { type: DataTypes.INTEGER, - allowNull: false, + allowNull: true, defaultValue: null, comment: "数据源挂载路径", primaryKey: false, @@ -95,7 +95,16 @@ module.exports = dc => { primaryKey: false, field: "catalogKey", autoIncrement: false - } + }, + type: { + type: DataTypes.STRING, + allowNull: false, + defaultValue: null, + comment: "元数据类型", + primaryKey: false, + field: "type", + autoIncrement: false + }, }, { tableName: "t_data_source", comment: "", diff --git a/scripts/0.0.7/02_alter_t_data_source.sql b/scripts/0.0.7/02_alter_t_data_source.sql new file mode 100644 index 0000000..aeea3ce --- /dev/null +++ b/scripts/0.0.7/02_alter_t_data_source.sql @@ -0,0 +1,9 @@ +create type enum_datasource_type as enum ('原数据库', '备份数据库'); + +alter table t_data_source + alter column mount_path drop not null; + +alter table t_data_source + add type enum_datasource_type; + +comment on column t_data_source.type is '数据源类型'; diff --git a/web/client/src/sections/metadataAcquisition/components/steps/postgre/stepOne.js b/web/client/src/sections/metadataAcquisition/components/steps/postgre/stepOne.js index 8a0c4a7..b6704c9 100644 --- a/web/client/src/sections/metadataAcquisition/components/steps/postgre/stepOne.js +++ b/web/client/src/sections/metadataAcquisition/components/steps/postgre/stepOne.js @@ -5,7 +5,8 @@ import { ProFormSelect, ProFormTextArea, ProFormText, - ProFormTreeSelect + ProFormTreeSelect, + ProFormDependency } from '@ant-design/pro-form'; import { push } from 'react-router-redux'; @@ -16,6 +17,7 @@ function StepOne(props) { adapterName: 'PostgreSQL采集适配器', adapterVersion: '9.x', mode: '数据库连接', + type: '原数据库' // mountPath: 1, } @@ -67,7 +69,7 @@ function StepOne(props) { onCancel: () => { }, }} onFinish={async (values) => { - values.mountPath = values.catalogKey.split('-')[values.catalogKey.split('-')?.length - 1] + if (values.catalogKey) values.mountPath = values.catalogKey.split('-')[values.catalogKey.split('-')?.length - 1] next() stepOneValuesFinish(values) return true; @@ -117,54 +119,65 @@ function StepOne(props) { label="采集模式" disabled={readOnly} /> - {/* */} - {treeDataFilter.length > 0 ? { - return treeDataFilter || []; - }} - // tree-select args - fieldProps={{ - showArrow: false, - filterTreeNode: true, - showSearch: true, - dropdownMatchSelectWidth: false, - labelInValue: false, - autoClearSearchValue: true, - multiple: false, - treeNodeFilterProp: 'title', - fieldNames: { - label: 'title', - }, - }} - addonAfter={renderAddonAfter()} - disabled={editData} - /> : } + options={ + [ + { label: '原数据库', value: '原数据库' }, + { label: '备份数据库', value: '备份数据库' } + ] + } + name="type" + label="数据源属性" + disabled={readOnly} + /> + + + {({ type }) => { + return ( + type == '备份数据库' ? null : treeDataFilter.length > 0 ? { + return treeDataFilter || []; + }} + // tree-select args + fieldProps={{ + showArrow: false, + filterTreeNode: true, + showSearch: true, + dropdownMatchSelectWidth: false, + labelInValue: false, + autoClearSearchValue: true, + multiple: false, + treeNodeFilterProp: 'title', + fieldNames: { + label: 'title', + }, + }} + addonAfter={renderAddonAfter()} + disabled={editData} + /> : + ); + + }} + { + options={dataSourceFilter?.filter(x => x?.type != '备份数据库')?.map(s => { return { label: s?.name, value: s?.id, disabled: s?.disabled } })} disabled={editData} diff --git a/web/client/src/sections/metadataAcquisition/containers/adapter.js b/web/client/src/sections/metadataAcquisition/containers/adapter.js index 6601978..174fb1b 100644 --- a/web/client/src/sections/metadataAcquisition/containers/adapter.js +++ b/web/client/src/sections/metadataAcquisition/containers/adapter.js @@ -57,6 +57,7 @@ const Adapter = (props) => { mountPath: stepOneValues?.mountPath, catalogKey: stepOneValues?.catalogKey, description: stepOneValues?.description, + type: stepOneValues?.type, config: stepTwoValues, time: moment() }, '')).then(res => { diff --git a/web/client/src/sections/metadataAcquisition/containers/dataSourceManagement.js b/web/client/src/sections/metadataAcquisition/containers/dataSourceManagement.js index 75ae425..2dd21b1 100644 --- a/web/client/src/sections/metadataAcquisition/containers/dataSourceManagement.js +++ b/web/client/src/sections/metadataAcquisition/containers/dataSourceManagement.js @@ -124,6 +124,7 @@ function DataSourceManagement(props) { mountPath: stepOneValues?.mountPath, catalogKey: stepOneValues?.catalogKey, description: stepOneValues?.description, + type: stepOneValues?.type, config: stepTwoValues, time: moment() } diff --git a/web/client/src/sections/resourceRetrieval/components/keyModal.js b/web/client/src/sections/resourceRetrieval/components/keyModal.js index 30ae3c3..7d1b2f1 100644 --- a/web/client/src/sections/resourceRetrieval/components/keyModal.js +++ b/web/client/src/sections/resourceRetrieval/components/keyModal.js @@ -6,20 +6,22 @@ import { import { Form, message } from 'antd'; export default (props) => { - const { resourceId, onFinish, approveList } = props; + const { resourceId, onFinish, approveList, } = props; const [form] = Form.useForm(); return ( 下载 + } + visible={true} form={form} layout='horizontal' autoFocusFirstInput modalProps={{ destroyOnClose: true, + onCancel: () => { props.onCancel() } }} onFinish={async (values) => { console.log(values.name); diff --git a/web/client/src/sections/resourceRetrieval/containers/retrieval.js b/web/client/src/sections/resourceRetrieval/containers/retrieval.js index 3edb9db..63011ec 100644 --- a/web/client/src/sections/resourceRetrieval/containers/retrieval.js +++ b/web/client/src/sections/resourceRetrieval/containers/retrieval.js @@ -1,9 +1,9 @@ import React, { useEffect, useState } from 'react' -import { Input, Tooltip, Empty, Pagination, Modal, Form } from 'antd' +import { Input, Tooltip, Empty, Pagination, Popover, message } from 'antd' import { InsertRowBelowOutlined, DatabaseOutlined, FileOutlined, PullRequestOutlined, KeyOutlined } from '@ant-design/icons'; import { useFsRequest, ApiTable } from '$utils'; import { connect } from 'react-redux'; -import { downloadImg } from '../utils/index' +import { downloadImg, markRedKeywords } from '../utils/index' import KeyModal from '../components/keyModal'; const METADTA_TYPE = { '库': 'databases', @@ -11,12 +11,21 @@ const METADTA_TYPE = { '文件': 'files', '接口': 'restapis', } + +const METADTA_TYPE_NAMES = { + '库': '库表/库(Schema)', + '表': '库表/表(Table)', + '文件': '文件(File)', + '接口': '接口(Api)', +} + import './style.less'; function Retrieval(props) { const { user, catalogs, dispatch, actions } = props; const [keywords, setKeywords] = useState() const [firstInput, setFirstInput] = useState() const [page, setPage] = useState(1) + const [currentData, setCurrentData] = useState(null) const formRef = React.createRef(); // const { data: catalogs = [] } = useFsRequest({ // url: ApiTable.getResourceCatalog, @@ -77,6 +86,17 @@ function Retrieval(props) { : text } + const renderName = (text) => { + function createMarkup(textFilter) { + return { __html: textFilter.length == text.length ? markRedKeywords(textFilter, keywords) : markRedKeywords(textFilter, keywords) + '...' }; + } + return text?.length > 16 ? + }> + + + : + } + const downloadData = (s) => { if (s?.type == '文件') { const suffix = s?.fileName?.substring(s?.fileName?.length - 3, s?.fileName?.length) @@ -109,21 +129,23 @@ function Retrieval(props) {
{renderIcon(s?.type)} {s?.code && 代码:{renderText(s?.code)}} - 名称:{renderText(s?.name)} - 类型:{s?.type} + 名称:{renderName(s?.name)} + 类型:{METADTA_TYPE_NAMES[s?.type]} 路径:{renderText(catalogText)} 标签:{renderText(tagText)}
@@ -137,6 +159,16 @@ function Retrieval(props) { }} />} {!result?.rows?.length > 0 && } + + {currentData && { + downloadData(currentData) + setCurrentData(null) + }} + onCancel={() => { setCurrentData(null) }} + />} } diff --git a/web/client/src/sections/resourceRetrieval/utils/index.js b/web/client/src/sections/resourceRetrieval/utils/index.js index ae547ef..9fb6f47 100644 --- a/web/client/src/sections/resourceRetrieval/utils/index.js +++ b/web/client/src/sections/resourceRetrieval/utils/index.js @@ -28,3 +28,10 @@ export const downloadImg = (fileName) => { } } + + +export const markRedKeywords = (str, key) => { + var reg = new RegExp((`(${key})`), "gi"); + var replace = '$1'; + return str.replace(reg, replace); +} \ No newline at end of file