Browse Source

(*) 数据源增加备份数据源 资源检索展示优化

master
peng.peng 2 years ago
parent
commit
de03a0681c
  1. 13
      api/app/lib/models/data_source.js
  2. 9
      scripts/0.0.7/02_alter_t_data_source.sql
  3. 111
      web/client/src/sections/metadataAcquisition/components/steps/postgre/stepOne.js
  4. 2
      web/client/src/sections/metadataAcquisition/components/steps/postgre/stepThree.js
  5. 1
      web/client/src/sections/metadataAcquisition/containers/adapter.js
  6. 1
      web/client/src/sections/metadataAcquisition/containers/dataSourceManagement.js
  7. 6
      web/client/src/sections/resourceRetrieval/components/keyModal.js
  8. 54
      web/client/src/sections/resourceRetrieval/containers/retrieval.js
  9. 7
      web/client/src/sections/resourceRetrieval/utils/index.js

13
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: "",

9
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 '数据源类型';

111
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}
/>
{/* <ProFormSelect
rules={[{ required: true, message: '请选择输入控件' }]}
options={[
{ label: '库表/目录1', value: 1 },
]}
name="mountPath"
label="数据源挂载路径"
// disabled={true}
/> */}
{treeDataFilter.length > 0 ? <ProFormTreeSelect
key={JSON.stringify(treeDataFilter)}
// width={'md'}
name="catalogKey"
label="数据源挂载路径"
placeholder="请选择数据源挂载路径"
rules={[{ required: true, message: '请选择数据源挂载路径' }]}
allowClear
width={480}
secondary
request={async () => {
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}
/> : <ProFormSelect
width={480}
<ProFormSelect
rules={[{ required: true, message: '请选择' }]}
options={[]}
name="catalogKey"
label="数据源挂载路径"
addonAfter={renderAddonAfter()}
placeholder="请选择数据源挂载路径"
disabled={editData}
/>}
options={
[
{ label: '原数据库', value: '原数据库' },
{ label: '备份数据库', value: '备份数据库' }
]
}
name="type"
label="数据源属性"
disabled={readOnly}
/>
<ProFormDependency name={['type']}>
{({ type }) => {
return (
type == '备份数据库' ? null : treeDataFilter.length > 0 ? <ProFormTreeSelect
key={JSON.stringify(treeDataFilter)}
// width={'md'}
name="catalogKey"
label="数据源挂载路径"
placeholder="请选择数据源挂载路径"
rules={[{ required: true, message: '请选择数据源挂载路径' }]}
allowClear
width={480}
secondary
request={async () => {
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}
/> : <ProFormSelect
width={480}
rules={[{ required: true, message: '请选择' }]}
options={[]}
name="catalogKey"
label="数据源挂载路径"
addonAfter={renderAddonAfter()}
placeholder="请选择数据源挂载路径"
disabled={editData}
/>
);
}}
</ProFormDependency>
<ProFormTextArea
name="description"

2
web/client/src/sections/metadataAcquisition/components/steps/postgre/stepThree.js

@ -67,7 +67,7 @@ function StepThree(props) {
{dataSourceFilter && <ProFormSelect
width={'md'}
rules={[{ required: true, message: '请选择数据源' }]}
options={dataSourceFilter?.map(s => {
options={dataSourceFilter?.filter(x => x?.type != '备份数据库')?.map(s => {
return { label: s?.name, value: s?.id, disabled: s?.disabled }
})}
disabled={editData}

1
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 => {

1
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()
}

6
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 (
<ModalForm
title="输入令牌"
trigger={
<a>下载</a>
<a></a>
}
visible={true}
form={form}
layout='horizontal'
autoFocusFirstInput
modalProps={{
destroyOnClose: true,
onCancel: () => { props.onCancel() }
}}
onFinish={async (values) => {
console.log(values.name);

54
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) {
</Tooltip> : text
}
const renderName = (text) => {
function createMarkup(textFilter) {
return { __html: textFilter.length == text.length ? markRedKeywords(textFilter, keywords) : markRedKeywords(textFilter, keywords) + '...' };
}
return text?.length > 16 ?
<Popover placement="topRight" title={null} content={<span dangerouslySetInnerHTML={createMarkup(text)} />}>
<span dangerouslySetInnerHTML={createMarkup(text.substring(0, 16))} />
</Popover>
: <span dangerouslySetInnerHTML={createMarkup(text)} />
}
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) {
<div className='column1'>
{renderIcon(s?.type)}
{s?.code && <span> 代码{renderText(s?.code)}</span>}
<span> 名称{renderText(s?.name)}</span>
<span> 类型{s?.type}</span>
<span> 名称{renderName(s?.name)}</span>
<span> 类型{METADTA_TYPE_NAMES[s?.type]}</span>
<span> 路径{renderText(catalogText)}</span>
<span> 标签{renderText(tagText)}</span>
</div>
<div className='column2'>相关操作<a onClick={() => { window.open(`/metadataManagement/latestMetadata?type=${METADTA_TYPE[s.type]}&treeId=${s?.catalog}&resourceId=${s.id}&catalogKey=${s.catalogKey}`) }}>定位</a>
{s?.type == '表' || s?.type == '文件' ?
user?.role == '数据消费者' ?
<KeyModal
resourceId={s.id}
approveList={approveList}
onFinish={() => {
downloadData(s)
}}
/> :
<a onClick={() => {
const token = approveList?.rows?.find(x => x.resourceId == s.id)?.token
if (!token) {
message.warning('您暂未申请该数据资源,请先申请该数据资源')
} else {
setCurrentData(s)
}
}}>下载</a> :
<a onClick={() => { downloadData(s) }}>下载</a> : ''}
</div>
</div>
@ -137,6 +159,16 @@ function Retrieval(props) {
}}
/>}
{!result?.rows?.length > 0 && <Empty />}
{currentData && <KeyModal
resourceId={currentData?.id}
approveList={approveList}
onFinish={() => {
downloadData(currentData)
setCurrentData(null)
}}
onCancel={() => { setCurrentData(null) }}
/>}
</>
}

7
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 = '<span style="color:#FD463E;font-weight:bold;margin-right:0px;">$1</span>';
return str.replace(reg, replace);
}
Loading…
Cancel
Save