diff --git a/api/app/lib/controllers/metadataAcquisition/dataSource.js b/api/app/lib/controllers/metadataAcquisition/dataSource.js index 0b1a88f..908bb4b 100644 --- a/api/app/lib/controllers/metadataAcquisition/dataSource.js +++ b/api/app/lib/controllers/metadataAcquisition/dataSource.js @@ -38,6 +38,7 @@ function getDataSource(opts) { let option = { where: searchWhere, order: [["id", "desc"]], + include: [{ model: models.Adapter }] } if (name) { diff --git a/api/app/lib/controllers/metadataAcquisition/task.js b/api/app/lib/controllers/metadataAcquisition/task.js index 282e843..6df3c2f 100644 --- a/api/app/lib/controllers/metadataAcquisition/task.js +++ b/api/app/lib/controllers/metadataAcquisition/task.js @@ -38,6 +38,7 @@ function getAcquisitionTask(opts) { let option = { where: searchWhere, order: [["id", "desc"]], + include: [{ model: models.DataSource }] } if (taskName) { diff --git a/api/app/lib/index.js b/api/app/lib/index.js index 8de169e..493d17a 100644 --- a/api/app/lib/index.js +++ b/api/app/lib/index.js @@ -54,6 +54,15 @@ module.exports.models = function (dc) { require(`./models/${filename}`)(dc) }); - const { } = dc.models; + const { + DataSource, AcquisitionTask, Adapter + } = dc.models; + + AcquisitionTask.belongsTo(DataSource, { foreignKey: 'dataSourceId', targetKey: 'id' }); + DataSource.hasMany(AcquisitionTask, { foreignKey: 'dataSourceId', sourceKey: 'id' }); + + DataSource.belongsTo(Adapter, { foreignKey: 'adapterId', targetKey: 'id' }); + Adapter.hasMany(DataSource, { foreignKey: 'adapterId', sourceKey: 'id' }); + }; diff --git a/api/app/lib/models/acquisition_task.js b/api/app/lib/models/acquisition_task.js index 7e16592..0773a15 100644 --- a/api/app/lib/models/acquisition_task.js +++ b/api/app/lib/models/acquisition_task.js @@ -25,7 +25,7 @@ module.exports = dc => { field: "task_name", autoIncrement: false }, - dataSource: { + dataSourceId: { type: DataTypes.INTEGER, allowNull: false, defaultValue: null, diff --git a/api/app/lib/models/data_source.js b/api/app/lib/models/data_source.js index 17fdab5..d5b7703 100644 --- a/api/app/lib/models/data_source.js +++ b/api/app/lib/models/data_source.js @@ -34,7 +34,7 @@ module.exports = dc => { field: "audited", autoIncrement: false }, - adapter: { + adapterId: { type: DataTypes.INTEGER, allowNull: false, defaultValue: null, diff --git a/web/client/src/sections/metadataAcquisition/components/dataSourceManagementModal.js b/web/client/src/sections/metadataAcquisition/components/dataSourceManagementModal.js index 96d27ac..66f9795 100644 --- a/web/client/src/sections/metadataAcquisition/components/dataSourceManagementModal.js +++ b/web/client/src/sections/metadataAcquisition/components/dataSourceManagementModal.js @@ -4,7 +4,9 @@ import AdapterStep from './adapterStep'; import { BellOutlined } from '@ant-design/icons' function DataSourceModal(props) { - const { visible, editData, onFinish, onCancel, adapterInfo } = props; + const { visible, editData, onFinish, onCancel, adapterInfo, + type = 'postgre',//当前卡片的key (目前只有postgre,支持后续扩展) + } = props; const [current, setCurrent] = useState(0); // const onFinish = () => { } return <> @@ -18,7 +20,7 @@ function DataSourceModal(props) { >
{current == 0 ? '数据源基本信息' : '数据源参数配置'}
{ setCurrent(c) }} diff --git a/web/client/src/sections/metadataAcquisition/components/steps/postgre/stepThree.js b/web/client/src/sections/metadataAcquisition/components/steps/postgre/stepThree.js index 431e750..a3e7d4d 100644 --- a/web/client/src/sections/metadataAcquisition/components/steps/postgre/stepThree.js +++ b/web/client/src/sections/metadataAcquisition/components/steps/postgre/stepThree.js @@ -9,6 +9,7 @@ import { ProFormCheckbox, ProFormDependency } from '@ant-design/pro-form'; +import { BellOutlined } from '@ant-design/icons' import '../../style.less'; function StepThree(props) { @@ -17,8 +18,10 @@ function StepThree(props) { const initialValues = { } - const formItemLayout = { labelCol: { span: 4 }, wrapperCol: { span: 10 } }; + const formItemLayout = { labelCol: { span: 4 }, wrapperCol: { span: 16 } }; return <> +
请输入该计划任务执行时间
+ { next() - return true; + // return true; }} style={{ marginTop: 20 }} submitter={{ @@ -40,73 +43,69 @@ function StepThree(props) { }, }} > - - - - 测试} - /> - + - - {({ retried }) => { + 测试} + /> - return retried ? - <> - + - + + {({ retried }) => { - - : null - }} - + return retried ? + <> + + 分钟} + /> - + + : null + }} +
- + {prev && } diff --git a/web/client/src/sections/metadataAcquisition/components/taskModal.js b/web/client/src/sections/metadataAcquisition/components/taskModal.js new file mode 100644 index 0000000..c126e3d --- /dev/null +++ b/web/client/src/sections/metadataAcquisition/components/taskModal.js @@ -0,0 +1,25 @@ +import React, { useEffect, useState } from 'react' +import { Tabs, Card, Modal } from 'antd' +import AdapterStep from './adapterStep'; +import { STEP_CONFIG } from './steps/index' +function DataSourceModal(props) { + const { visible, editData, onFinish, onCancel, + type = 'postgre',//当前卡片的key (目前只有postgre,支持后续扩展) + } = props; + const { StepThree } = STEP_CONFIG[type]; + // const onFinish = () => { } + return <> + { onCancel() }} + open={visible} + footer={null} + width={1200} + destroyOnClose={true} + > + + + +} + +export default DataSourceModal \ No newline at end of file diff --git a/web/client/src/sections/metadataAcquisition/containers/acquisitionTask.js b/web/client/src/sections/metadataAcquisition/containers/acquisitionTask.js index 8fa053f..24d1384 100644 --- a/web/client/src/sections/metadataAcquisition/containers/acquisitionTask.js +++ b/web/client/src/sections/metadataAcquisition/containers/acquisitionTask.js @@ -1,7 +1,229 @@ import React, { useEffect, useState } from 'react' +import { Spin, Popconfirm, Tree, Row, Col, Button, Input, Table } from 'antd'; +import { connect } from 'react-redux'; +import ProTable from '@ant-design/pro-table'; +import moment from 'moment'; +import TaskModal from '../components/taskModal'; +import { RELATION_DATABASE_TOOL_CONFIG } from '../constants/adapter'; -function AcquisitionTask (props) { - return <>采集任务配置 +import './style.less'; +function AcquisitionTask(props) { + const { loading, clientHeight, actions, dispatch, dataSources, adapters, tasks } = props; + const [pageSize, setPageSize] = useState(10); + const [currentPage, setCurrentPage] = useState(1); + const [searchValue, setSearchValue] = useState('') + const [visible, setVisible] = useState(false);//是否展示新增编辑模态框 + const [editData, setEditData] = useState(null);//模态框编辑数据 + const queryData = (search) => { + const query = { + limit: search ? 10 : pageSize || 10, + page: search ? 1 : currentPage || 1, + taskName: searchValue + } + dispatch(actions.metadataAcquisition.getTasks(query)); + } + + useEffect(() => { + dispatch(actions.metadataAcquisition.getDataSources()); + dispatch(actions.metadataAcquisition.getAdapters()) + queryData(); + }, [pageSize, currentPage]); + + const handleDelete = (id) => { + dispatch(actions.metadataAcquisition.deleteDataSource(id)).then(() => { + queryData(); + }); + }; + + const columns = [ + { + title: '数据源名称', + dataIndex: 'taskName', + }, + { + title: '数据源名称', + dataIndex: 'name', + }, + { + title: '挂载点', + dataIndex: 'mountPath', + }, + { + title: '适配器类型', + dataIndex: 'adapter', + render: (text, record) => { + const adapterInfo = adapters?.find(s => s.id == record?.adapter) + return adapterInfo?.adapterName + } + }, + { + title: '采集方式', + dataIndex: 'control', + render: (text, record) => { + const adapterInfo = adapters?.find(s => s.id == record?.adapter) + return adapterInfo?.mode + } + }, + { + title: '工具版本', + dataIndex: 'length', + render: (text, record) => { + const adapterInfo = adapters?.find(s => s.id == record?.adapter) + return adapterInfo?.adapterVersion + } + }, + { + title: '修改时间', + dataIndex: 'time', + render: (text, record) => moment(record?.time).format('YYYY-MM-DD HH:mm:ss') + }, + { + title: '描述', + dataIndex: 'description', + ellipsis: true, + search: false, + }, + { + title: '操作', + width: 160, + key: 'option', + valueType: 'option', + render: (text, record) => { + const options = []; + options.push( { + const adapterInfo = adapters?.find(x => x.id == record?.adapter) + setVisible(true) + record.adapterInfo = adapterInfo + setEditData(record) + }} style={{ marginRight: 8 }}>编辑) + options.push( + handleDelete(record.id)} + okText="是" + cancelText="否" + > + 删除 + ) + + return options; + + }, + }, + ]; + + const onFinish = (values) => { + const { stepOneValues, stepTwoValues } = values; + const adapterInfo = adapters?.find(x => x.adapterName == stepOneValues?.adapterName) + if (adapterInfo) { + const dataToSave = { + name: stepOneValues?.name, + audited: true, + adapter: adapterInfo?.id, + mountPath: 1, + description: stepOneValues?.description, + config: stepTwoValues, + time: moment() + } + if (editData) { + dispatch(actions.metadataAcquisition.modifyTask(editData?.id, dataToSave)).then(res => { + if (res.success) { + setVisible(false); + setEditData(null); + queryData(); + } + }) + } else { + dispatch(actions.metadataAcquisition.addTask(dataToSave)).then(res => { + if (res.success) { + setVisible(false); + setEditData(null); + queryData(); + } + }) + } + } + } + + return + + + { setSearchValue(e.target.value) }} + style={{ width: 220, marginRight: 15 }} placeholder="数据源或任务名称" /> + + { + return {`共${Math.ceil(total / pageSize)}页,${total}项`} + }, + onShowSizeChange: (currentPage, pageSize) => { + setCurrentPage(currentPage); + setPageSize(pageSize); + + }, + onChange: (page, pageSize) => { + setCurrentPage(page); + setPageSize(pageSize); + + } + }} + dataSource={tasks?.rows || []} + options={false} + /> + + { + visible && { + setVisible(false) + setEditData(null) + } + } + editData={editData} + visible={visible} + onFinish={onFinish} + {...props} + /> + } + + +} + +function mapStateToProps(state) { + const { + auth, global, datasources, adapters, tasks + } = state; + return { + loading: datasources.isRequesting || adapters?.isRequesting, + clientHeight: global.clientHeight, + actions: global.actions, + dataSources: datasources?.data || {}, + adapters: adapters?.data || [], + tasks: tasks?.data || [], + }; } -export default AcquisitionTask \ No newline at end of file +export default connect(mapStateToProps)(AcquisitionTask); + + + + diff --git a/web/client/src/sections/metadataAcquisition/containers/dataSourceManagement.js b/web/client/src/sections/metadataAcquisition/containers/dataSourceManagement.js index 4ffc3d6..44a714c 100644 --- a/web/client/src/sections/metadataAcquisition/containers/dataSourceManagement.js +++ b/web/client/src/sections/metadataAcquisition/containers/dataSourceManagement.js @@ -48,7 +48,7 @@ function DataSourceManagement(props) { title: '适配器类型', dataIndex: 'adapter', render: (text, record) => { - const adapterInfo = adapters?.find(s => s.id == record?.adapter) + const adapterInfo = record?.adapter return adapterInfo?.adapterName } }, @@ -56,7 +56,7 @@ function DataSourceManagement(props) { title: '采集方式', dataIndex: 'control', render: (text, record) => { - const adapterInfo = adapters?.find(s => s.id == record?.adapter) + const adapterInfo = record?.adapter return adapterInfo?.mode } }, @@ -64,7 +64,7 @@ function DataSourceManagement(props) { title: '工具版本', dataIndex: 'length', render: (text, record) => { - const adapterInfo = adapters?.find(s => s.id == record?.adapter) + const adapterInfo = record?.adapter return adapterInfo?.adapterVersion } },