Browse Source

(*)适配器管理UI提交

master
peng.peng 2 years ago
parent
commit
1cbdc0a76f
  1. 33
      api/app/lib/controllers/adapter/index.js
  2. 0
      api/app/lib/controllers/modelManagement/index.js
  3. 12
      api/app/lib/routes/adapter/index.js
  4. 2
      api/app/lib/routes/modelManagement/index.js
  5. 45
      web/client/src/sections/metadataAcquisition/components/adapterStep.js
  6. 3
      web/client/src/sections/metadataAcquisition/components/details/index.js
  7. 93
      web/client/src/sections/metadataAcquisition/components/details/postgreDetail.js
  8. 9
      web/client/src/sections/metadataAcquisition/components/steps/index.js
  9. 5
      web/client/src/sections/metadataAcquisition/components/steps/postgre/index.js
  10. 15
      web/client/src/sections/metadataAcquisition/components/steps/postgre/stepOne.js
  11. 17
      web/client/src/sections/metadataAcquisition/components/steps/postgre/stepThree.js
  12. 39
      web/client/src/sections/metadataAcquisition/components/steps/postgre/stepTwo.js
  13. 5
      web/client/src/sections/metadataAcquisition/components/style.less
  14. 47
      web/client/src/sections/metadataAcquisition/containers/adapter.js
  15. 26
      web/client/src/sections/metadataAcquisition/containers/adapterDetail.js

33
api/app/lib/controllers/adapter/index.js

@ -0,0 +1,33 @@
'use strict';
const { Pool } = require('pg');
// 新增模型
function checkConnect(opts) {
return async function (ctx, next) {
const models = ctx.fs.dc.models;
try {
let { user, host, database, password, port } = ctx.request.body;
const pool = new Pool({
user: user,
host: host,
database: database,
password: password,
port: port,
})
const client = await pool.connect()
ctx.status = 200;
ctx.body = { message: client._connected ? '连接成功' : '连接失败' }
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = { message: '连接失败' }
}
}
}
module.exports = {
checkConnect,
}

0
api/app/lib/controllers/model-management/index.js → api/app/lib/controllers/modelManagement/index.js

12
api/app/lib/routes/adapter/index.js

@ -0,0 +1,12 @@
'use strict';
const model = require('../../controllers/adapter/index');
module.exports = function (app, router, opts, AuthCode) {
app.fs.api.logAttr['POST/adapter/check/connect'] = { content: '增加模型信息', visible: true };
router.post('/adapter/check/connect', model.checkConnect(opts))
};

2
api/app/lib/routes/model-management/index.js → api/app/lib/routes/modelManagement/index.js

@ -1,6 +1,6 @@
'use strict';
const model = require('../../controllers/model-management/index');
const model = require('../../controllers/modelManagement/index');
module.exports = function (app, router, opts, AuthCode) {

45
web/client/src/sections/metadataAcquisition/components/adapterStep.js

@ -0,0 +1,45 @@
import React, { useEffect, useState } from 'react';
import { connect } from 'react-redux';
import { Steps, Row, Col, Table, Button } from 'antd'
import { STEP_CONFIG } from './steps/index';
const AdapterStep = (props) => {
const { type } = props;
const [current, setCurrent] = useState(0);
const { StepOne, StepTwo, StepThree } = STEP_CONFIG[type];
const next = () => {
current < 2 && setCurrent(current + 1);
};
const prev = () => {
setCurrent(current - 1);
};
const steps = [
{
title: '配置数据源基本信息',
content: <StepOne next={next} />,
},
{
title: '数据源参数配置',
content: <StepTwo prev={prev} next={next} />,
},
{
title: '配置计划任务',
content: <StepThree prev={prev} next={next} />,
},
];
const items = steps.map((item) => ({
key: item.title,
title: item.title,
}));
return <>
<Steps current={current} items={items} />
<div className="steps-content">{steps[current].content}</div>
</>
}
export default AdapterStep;

3
web/client/src/sections/metadataAcquisition/components/details/index.js

@ -0,0 +1,3 @@
import PostGreDetail from './postgreDetail';
export { PostGreDetail }

93
web/client/src/sections/metadataAcquisition/components/details/postgreDetail.js

@ -0,0 +1,93 @@
import React, { useEffect, useState } from 'react';
import { connect } from 'react-redux';
import { Tabs, Tree, Row, Col, Table, Button } from 'antd'
const TreeNode = Tree.TreeNode;
const PostGreDetail = (props) => {
const { history } = props;
const renderBasicInfo = () => {
return <div style={{ lineHeight: '40px' }}>
<div> 适配器名称PostgreSQL 采集适配器</div>
<div> 适配器版本1.0</div>
<div> 工具名称PostgreSQL数据库</div>
<div> 工具版本9.x</div>
<div> 描述采集数据库结构及相关对象</div>
</div>
}
const renderManageInfo = () => {
const dataSource = [
{
param: 'url',
title: '数据库访问URL',
isRequired: 'true',
description: '数据库访问所需的URL',
},
{
param: 'username',
title: '用户名',
isRequired: 'true',
description: '数据库用户名',
},
{
param: 'password',
title: '密码',
isRequired: 'true',
description: '数据库密码',
}
];
const columns = [
{
title: '参数名',
dataIndex: 'param',
key: 'param',
},
{
title: '标题',
dataIndex: 'title',
key: 'title',
},
{
title: '是否必填',
dataIndex: 'isRequired',
key: 'isRequired',
},
{
title: '描述',
dataIndex: 'description',
key: 'description',
},
];
return <Row>
<Col style={{ width: 240 }}>
<Tree
defaultExpandAll={true}
>
<TreeNode title={'PostgreSQL数据库'} key={'PostgreSQL数据库'} selectable={false}>
<TreeNode selectable={false} title={'9.x'} key={'9x'}>
<TreeNode selectable={false} title={'数据库连接'} key={'数据库连接'}>
</TreeNode>
</TreeNode>
</TreeNode>
</Tree>
</Col>
<Col style={{ width: 'calc(100% - 240px)' }}>
<Table dataSource={dataSource} columns={columns} pagination={{ position: ['none', 'none'] }} />
</Col>
</Row>
}
const items = [
{ label: '基本信息', key: '基本信息', children: renderBasicInfo() },
{ label: '配置信息', key: '配置信息', children: renderManageInfo() },
];
const renderExtra = <Button onClick={() => { history.push(`/metadataAcquisition/adapter`) }} type='primary'>返回</Button>
return <>
<Tabs tabBarExtraContent={renderExtra} items={items} />
</>
}
export default PostGreDetail;

9
web/client/src/sections/metadataAcquisition/components/steps/index.js

@ -0,0 +1,9 @@
import * as postgre from './postgre/index';
export const STEP_CONFIG = {
'postgre': {
StepOne: postgre.stepOne,
StepTwo: postgre.stepTwo,
StepThree: postgre.stepThree
}
}

5
web/client/src/sections/metadataAcquisition/components/steps/postgre/index.js

@ -0,0 +1,5 @@
import stepOne from './stepOne';
import stepTwo from './stepTwo';
import stepThree from './stepThree';
export { stepOne, stepTwo, stepThree }

15
web/client/src/sections/metadataAcquisition/components/steps/postgre/stepOne.js

@ -0,0 +1,15 @@
import React, { useEffect, useState } from 'react'
import { Button } from 'antd';
import '../../style.less';
function StepOne(props) {
const { next } = props;
return <>
<div className='step-footer'>
<Button type="primary" onClick={() => next()}>
下一步
</Button>
</div>
</>
}
export default StepOne

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

@ -0,0 +1,17 @@
import React, { useEffect, useState } from 'react'
import { Button } from 'antd';
import '../../style.less';
function StepThree(props) {
const { prev, next } = props;
return <>
<div className='step-footer'>
<Button style={{ margin: '0 8px', }} onClick={() => prev()}>上一步</Button>
<Button type="primary" onClick={() => {next()}}>
完成
</Button>
</div>
</>
}
export default StepThree;

39
web/client/src/sections/metadataAcquisition/components/steps/postgre/stepTwo.js

@ -0,0 +1,39 @@
import React, { useEffect, useState } from 'react'
import { Button } from 'antd';
import '../../style.less';
import { Func, useMockRequest, useFsRequest, ApiTable } from '$utils';
function StepTwo(props) {
const { prev, next } = props;
const { data: connect = {} } = useFsRequest({
url: ApiTable.robotRequest,
method: 'post',
data: {
"user": "FashionAdmin",
"host": "10.8.30.156",
"database": "dayawan",
"password": "123456",
"port": "5432"
},
// ready: !!(struct?.id && actiAlarm?.hasRobot),
});
const checkConnect = () => {
}
return <>
<div>connect:{connect?.message}</div>
<Button onClick={checkConnect}>测试连接</Button>
<div className='step-footer'>
<Button style={{ margin: '0 8px', }} onClick={() => prev()}>上一步</Button>
<Button type="primary" onClick={() => next()}>
下一步
</Button>
</div>
</>
}
export default StepTwo;

5
web/client/src/sections/metadataAcquisition/components/style.less

@ -0,0 +1,5 @@
.step-footer {
display: flex;
justify-content: flex-end;
margin-top: 20px;
}

47
web/client/src/sections/metadataAcquisition/containers/adapter.js

@ -1,15 +1,52 @@
import React, { useEffect, useState } from 'react';
import { connect } from 'react-redux';
import { Button, } from 'antd'
import { Tabs, Card, Modal } from 'antd'
import { DatabaseOutlined } from '@ant-design/icons'
import AdapterStep from '../components/adapterStep';
//关系型数据库卡片配置
const RELATION_DATABASE_TOOL_CONFIG = [{
key: 'postgre', // key与详情配置(adapterDetail)中的key需一直否则无法查看详情页
name: 'PostgreSQL数据库',
version: '9.X',
desc: '采集数据数据库结构及相关对象',
title: 'PostgreSQL采集适配器'
}]
const LatestMetadata = (props) => {
const { user, dispatch, actions, history } = props;
const { history } = props;
const [isModalOpen, setIsModalOpen] = useState(false);
const renderRelationalDatabase = () => {
return RELATION_DATABASE_TOOL_CONFIG.map(s => <Card
title={<a onClick={() => { history.push(`/metadataAcquisition/adapter/detail/${s.key}`) }}>{s.title}</a>}
extra={<a onClick={() => { setIsModalOpen(s.key) }}><DatabaseOutlined style={{ fontSize: 18 }} /></a>}
style={{ width: '30%', lineHeight: '30px' }}
>
<p>工具名称{s.name}</p>
<p>工具版本{s.version}</p>
<p>描述{s.desc}</p>
</Card>)
}
useEffect(() => {
}, [])
const items = [
{ label: '关系型数据库', key: '关系型数据库', children: renderRelationalDatabase() },
];
return <>
<Button type="primary" onClick={() => { history.push(`/metadataAcquisition/adapter/detail/1`) }} >查看详情</Button>
<Tabs items={items} />
<Modal
title="新建采集导向"
onCancel={() => { setIsModalOpen(false) }}
open={isModalOpen}
footer={null}
width={1200}
destroyOnClose={true}
>
<AdapterStep
type={isModalOpen} //当前卡片的key (目前只有postgre,支持后续扩展)
/>
</Modal>
</>
}

26
web/client/src/sections/metadataAcquisition/containers/adapterDetail.js

@ -1,7 +1,25 @@
import React, { useEffect, useState } from 'react'
import React, { useEffect, useState } from 'react';
import { connect } from 'react-redux';
import { PostGreDetail } from '../components/details/index';
function AdapterDetail(props) {
return <>适配器详情</>
const AdapterDetail = (props) => {
const { match, history } = props;
//配置详情展示 可扩展 details的key值需要跳转过来的详情参数匹配
const details = {
'postgre': PostGreDetail, //postgre详情
}
const Component = details[match?.params?.id] ? details[match?.params?.id] : null
return <>
{Component && <Component history={history} />}
</>
}
export default AdapterDetail
function mapStateToProps(state) {
const { global, auth } = state;
return {
clientHeight: global.clientHeight,
user: auth.user,
actions: global.actions,
};
}
export default connect(mapStateToProps)(AdapterDetail)
Loading…
Cancel
Save