Commit 05f9d326 by zhaochengxiang

完成数据源管理的功能

parent 6f815c16
import React, { useEffect, useState } from 'react';
import { Modal, Select, Form, Input, Divider, Space, Button } from 'antd';
import { Modal, Select, Form, Input, Divider, Space, Button, Upload } from 'antd';
import { UploadOutlined } from '@ant-design/icons';
import { dispatch } from '../../../../model';
import { showMessage } from '../../../../util';
......@@ -7,30 +8,69 @@ import { showMessage } from '../../../../util';
const { Option } = Select;
const UpdateDatasourceModal = (props) => {
const { visible, onCancel, databases } = props;
const { visible, onCancel, databases, action, id } = props;
const [ selectedDatabaseKey, setSelectedDatabaseKey ] = useState('');
const [ allSupportedDatasourceTypies, setAllSupportedDatasourceTypies ] = useState([]);
const [ currentSupportedDatasourceTypies, setCurrentSupportedDatasourceTypies ] = useState({});
const [ currentDatasource, setCurrentDatasource ] = useState({});
const [ confirmLoading, setConfirmLoading ] = useState(false);
const [ validateLoading, setValidateLoading ] = useState(false);
const [ fileListBindName, setFileListBindName ] = useState([]);
const [ credentialForm ] = Form.useForm();
const [ datasourceForm ] = Form.useForm();
useEffect(() => {
getAllSupportedDatasourceTypies();
if (visible) {
reset();
getAllSupportedDatasourceTypies();
}
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
}, [visible, action, id])
const getAllSupportedDatasourceTypies = () => {
dispatch({
type: 'datasource.getAllSupportedDatasourceTypies',
callback: data => {
function compare(val1, val2) {
var a = val1.seq;
var b = val2.seq;
return (a - b);
}
(data||[]).forEach(item => {
item.credential && (item.credential.credentialParameters||[]).sort(compare);
(item.targetParameters||[]).sort(compare);
})
setAllSupportedDatasourceTypies(data||[]);
const _defaultKey = (data||[]).length>0?data[0].type:'';
if (action === 'add') {
const _defaultKey = (data||[]).length>0?data[0].type:'';
setSelectedDatabaseKey(_defaultKey);
getCurrentSupportedDatasourceTypies(data||[], _defaultKey);
} else if (action === 'edit') {
getCurrentDatasource(data||[]);
}
}
})
}
const getCurrentDatasource = (typies) => {
dispatch({
type: 'datasource.getDatasource',
payload: {
datasourceId: id
},
callback: data => {
const _defaultKey = (data)?(data.type||''):'';
setSelectedDatabaseKey(_defaultKey);
getCurrentSupportedDatasourceTypies(data||[], _defaultKey);
getCurrentSupportedDatasourceTypies(typies||[], _defaultKey);
setCurrentDatasource(data);
setFormFiledsValue(data);
}
})
}
......@@ -47,7 +87,26 @@ const UpdateDatasourceModal = (props) => {
setCurrentSupportedDatasourceTypies(_currentTypies);
}
const setFormFiledsValue = (data) => {
let _credentialFieldsValue = {}, _datasourceFieldsValue = {};
data && data.credential && (data.credential.credentialParameters||[]).forEach(item => {
_credentialFieldsValue[item.name||''] = item.value||'';
});
credentialForm.setFieldsValue(_credentialFieldsValue);
data && (data.targetParameters||[]).forEach(item => {
_datasourceFieldsValue[item.name||''] = item.value||'';
});
datasourceForm.setFieldsValue(_datasourceFieldsValue);
}
const onDatabaseChange = (value) => {
reset();
setSelectedDatabaseKey(value);
getCurrentSupportedDatasourceTypies(allSupportedDatasourceTypies, value);
}
......@@ -57,13 +116,30 @@ const UpdateDatasourceModal = (props) => {
const datasourceRow = await datasourceForm.validateFields();
const credentialRow = await credentialForm.validateFields();
const newDatasource = {...currentSupportedDatasourceTypies};
//深拷贝
let newDatasource = JSON.parse(JSON.stringify(currentSupportedDatasourceTypies));
if (action === 'edit') {
newDatasource = {...newDatasource, ...currentDatasource};
}
newDatasource && (newDatasource.targetParameters||[]).forEach(item => {
item.value = datasourceRow[item.name]||'';
if (item.selectMode === 'file') {
const index = (fileListBindName||[]).findIndex(_item => _item.name===item.name);
if (index !== -1) {
item.value = fileListBindName[index].data||'';
}
}
});
newDatasource && newDatasource.credential && (newDatasource.credential.credentialParameters||[]).forEach(item => {
item.value = credentialRow[item.name];
item.value = credentialRow[item.name]||'';
if (item.selectMode === 'file') {
const index = (fileListBindName||[]).findIndex(_item => _item.name===item.name);
if (index !== -1) {
item.value = fileListBindName[index].data||'';
}
}
})
setConfirmLoading(true);
......@@ -94,10 +170,22 @@ const UpdateDatasourceModal = (props) => {
const newDatasource = {...currentSupportedDatasourceTypies};
newDatasource && (newDatasource.targetParameters||[]).forEach(item => {
item.value = datasourceRow[item.name];
if (item.selectMode === 'file') {
const index = (fileListBindName||[]).findIndex(_item => _item.name===item.name);
if (index !== -1) {
item.value = fileListBindName[index].data||'';
}
}
});
newDatasource && newDatasource.credential && (newDatasource.credential.credentialParameters||[]).forEach(item => {
item.value = credentialRow[item.name];
if (item.selectMode === 'file') {
const index = (fileListBindName||[]).findIndex(_item => _item.name===item.name);
if (index !== -1) {
item.value = fileListBindName[index].data||'';
}
}
})
setValidateLoading(true);
......@@ -124,6 +212,43 @@ const UpdateDatasourceModal = (props) => {
}
}
const reset =() => {
setFileListBindName([]);
credentialForm.resetFields();
datasourceForm.resetFields();
}
const onRemoveFile = (name, file) => {
const index = (fileListBindName||[]).findIndex(item => item.name===name);
if (index !== -1) {
const fileList = fileListBindName[index].fileList;
const _index = fileList.indexOf(file);
fileList.splice(_index, 1);
setFileListBindName([...fileListBindName]);
}
}
const beforeUpload = (name, file) => {
const index = (fileListBindName||[]).findIndex(item => item.name===name);
var reader = new FileReader();
reader.onload = function (ext) {
if (index !== -1) {
fileListBindName[index].fileList = [file];
fileListBindName[index].data = ext.target.result.substring(ext.target.result.indexOf(',')+1);
} else {
fileListBindName.push({ name, fileList: [file], data: ext.target.result.substring(ext.target.result.indexOf(',')+1) });
}
setFileListBindName([...fileListBindName]);
}
reader.readAsDataURL(file);
}
const formItemLayout = {
labelCol: {
xs: { span: 24 },
......@@ -138,7 +263,7 @@ const UpdateDatasourceModal = (props) => {
return (
<Modal
forceRender
title={'新增数据源'}
title={action==='add'?'新增数据源':'修改数据源'}
visible={visible}
width={600}
onCancel={() => { onCancel && onCancel() }}
......@@ -156,6 +281,7 @@ const UpdateDatasourceModal = (props) => {
value={selectedDatabaseKey}
style={{ width: 150 }}
onChange={onDatabaseChange}
disabled={action==='edit'}
>
{
databases && databases.map((item, index) => {
......@@ -175,6 +301,7 @@ const UpdateDatasourceModal = (props) => {
label={item.cnName||''}
name={item.name||''}
key={index}
rules={[{ required: item.required, message: '必填项'}]}
>
<Input />
</Form.Item>
......@@ -186,13 +313,32 @@ const UpdateDatasourceModal = (props) => {
<Form {...formItemLayout} form={credentialForm}>
{
currentSupportedDatasourceTypies && currentSupportedDatasourceTypies.credential && (currentSupportedDatasourceTypies.credential.credentialParameters||[]).map((item, index) => {
let _fileList = [];
const _index = (fileListBindName||[]).findIndex(_item => _item.name===item.name);
if (_index !== -1) {
_fileList = fileListBindName[_index].fileList || [];
}
return (
<Form.Item
label={item.cnName||''}
name={item.name||''}
key={index}
rules={[{ required: item.required, message: '必填项'}]}
>
<Input />
{ item.selectMode==='file' ? (
<Upload
onRemove={(file) => { onRemoveFile(item.name, file); }}
beforeUpload={(file) => { beforeUpload(item.name, file); }}
fileList={_fileList}
// accept='.txt'
>
<Button icon={<UploadOutlined />}>
选择文件上传
</Button>
</Upload>
) : ( item.show ? <Input /> : <Input.Password /> ) }
</Form.Item>
)
})
......
......@@ -5,32 +5,56 @@ import { dispatch } from '../../../../model';
import './UpdateTaskModal.less';
const UpdateTaskModal = (props) => {
const { visible, onCancel, datasourceId } = props;
const { visible, onCancel, action, id, datasourceId } = props;
const [ schemas, setSchemas ] = useState([]);
const [ filterSchemas, setFilterSchemas ] = useState([]);
const [ selectedSchemas, setSelectedSchemas ] = useState([]);
const [ taskSettings, setTaskSettings ] = useState({});
const [ currentTask, setCurrentTask ] = useState({});
const [ keyword, setKeyword ] = useState('');
const [ confirmLoading, setConfirmLoading ] = useState(false);
const [ form ] = Form.useForm();
useEffect(() => {
if ((datasourceId||'') !== '' ) {
getTaskSettings();
if (visible) {
setSelectedSchemas([]);
form.resetFields();
if (action==='add' && datasourceId) {
getTaskSettings();
} else if (action==='edit' && id) {
getTask();
}
}
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [datasourceId])
}, [visible, action, id, datasourceId])
useEffect(() => {
setFilterSchemas((schemas||[]).filter(schema => (schema||'').indexOf(keyword)!==-1));
}, [keyword, schemas])
const getTaskSettings = () => {
const getTask = () => {
dispatch({
type: 'datasource.getTask',
payload: {
harvestingTaskId: id
},
callback: data => {
setCurrentTask(data);
getTaskSettings(data&&data.target?(data.target.id||''):'', data)
}
})
}
const getTaskSettings = (sourceId = datasourceId, task = null) => {
dispatch({
type: 'datasource.getTaskSettingsByDatasource',
payload: {
datasourceId
datasourceId: sourceId
},
callback: data => {
setTaskSettings(data);
......@@ -39,6 +63,20 @@ const UpdateTaskModal = (props) => {
setSchemas(item.selectItem||[]);
}
})
if (action === 'edit') {
let _fieldsValue = {};
task && (task.targetConfParameters||[]).forEach(item => {
if (item.name === 'schema') {
setSelectedSchemas((item.value||'').split(','));
} else {
_fieldsValue[item.name||''] = item.value||'';
}
})
form.setFieldsValue(_fieldsValue);
}
}
})
}
......@@ -46,7 +84,14 @@ const UpdateTaskModal = (props) => {
const onOk = async() => {
try {
const row = await form.validateFields();
const newTask = {...taskSettings};
//深拷贝
let newTask = JSON.parse(JSON.stringify(taskSettings));
if (action === 'edit') {
newTask = {...newTask, ...currentTask};
}
newTask && (newTask.targetConfParameters||[]).forEach(item => {
if (item.name === 'schema') {
item.value = selectedSchemas.join(',');
......@@ -104,7 +149,7 @@ const UpdateTaskModal = (props) => {
<Modal
className='update-task-modal'
forceRender
title={'新增任务'}
title={action==='add'?'新增任务':'修改任务'}
visible={visible}
width={600}
onCancel={() => { onCancel && onCancel() }}
......
......@@ -6,7 +6,6 @@ import { dispatch } from '../../../model';
import UpdateDatasourceModal from './Component/UpdateDatasourceModal';
import UpdateTaskModal from './Component/UpdateTaskModal';
import { showMessage } from '../../../util';
import { deleteDatasource } from '../../../model/datasource';
const { Option } = Select;
const { Panel } = Collapse;
......@@ -19,8 +18,11 @@ const DatasourceManage = () => {
const [ selectedDatabaseKey, setSelectedDatabaseKey ] = useState('');
const [ loadingDatabases, setLoadingDatabases ] = useState(false);
const [ updateDatasourceModalVisible, setUpdateDatasourceModalVisible ] = useState(false);
const [ updateDatasourceModalAction, setUpdateDatasourceModalAction ] = useState('');
const [ updateTaskModalVisible, setUpdateTaskModalVisible ] = useState(false);
const [ updateTaskModalAction, setUpdateTaskModalAction ] = useState('');
const [ currentDatasourceId, setCurrentDatasourceId ] = useState('');
const [ currentTaskId, setCurrentTaskId ] = useState('');
const [ tasksBindDatasourceId, setTasksBindDatasourceId ] = useState([]);
const [modal, contextHolder] = Modal.useModal();
......@@ -38,7 +40,7 @@ const DatasourceManage = () => {
callback: data => {
setLoadingDatabases(false);
setRawSupportDatabases(data||[]);
setSupportDatabases([{ targetType: 'all', targetName: '全部' }, ...(data||[])]);
setSupportDatabases([{ targetType: 'all', targetName: '全部类型' }, ...(data||[])]);
setSelectedDatabaseKey('all');
getAllDatasources();
},
......@@ -90,6 +92,13 @@ const DatasourceManage = () => {
}
const addDatasource = () => {
setUpdateDatasourceModalAction('add');
setUpdateDatasourceModalVisible(true);
}
const editDatasource = (datasource) => {
setCurrentDatasourceId(datasource.id);
setUpdateDatasourceModalAction('edit');
setUpdateDatasourceModalVisible(true);
}
......@@ -128,8 +137,9 @@ const DatasourceManage = () => {
}
const addTask = (datasource) => {
setUpdateTaskModalVisible(true);
setCurrentDatasourceId(datasource.id||'');
setUpdateTaskModalAction('add');
setUpdateTaskModalVisible(true);
}
const startTask = (task) => {
......@@ -152,6 +162,12 @@ const DatasourceManage = () => {
});
}
const editTask = (task) => {
setCurrentTaskId(task.id);
setUpdateTaskModalAction('edit');
setUpdateTaskModalVisible(true);
}
const deleteTask = (task) => {
modal.confirm({
title: '是否确认删除该任务?',
......@@ -237,7 +253,7 @@ const DatasourceManage = () => {
extra={
<Space>
<Tooltip placement='bottom' title={'修改'}>
<Button icon={<EditOutlined />} size='small' onClick={() => { }} />
<Button icon={<EditOutlined />} size='small' onClick={() => { editDatasource(datasource); }} />
</Tooltip>
<Tooltip placement='bottom' title={'新增任务'}>
<Button icon={<DiffOutlined />} size='small' onClick={() => { addTask(datasource); }} />
......@@ -272,7 +288,7 @@ const DatasourceManage = () => {
<Button icon={<DatabaseOutlined />} size='small' onClick={() => { startTask(task); }} />
</Tooltip>
<Tooltip placement='bottom' title='修改'>
<Button icon={<EditOutlined />} size='small' onClick={() => { }} />
<Button icon={<EditOutlined />} size='small' onClick={() => { editTask(task); }} />
</Tooltip>
<Tooltip placement='bottom' title='删除'>
<Button icon={<DeleteOutlined />} size='small' onClick={() => { deleteTask(task); }} />
......@@ -292,13 +308,17 @@ const DatasourceManage = () => {
<UpdateDatasourceModal
visible={updateDatasourceModalVisible}
id={currentDatasourceId}
databases={rawSupportDatabases}
action={updateDatasourceModalAction}
onCancel={onUpdateDatasourceModalCancel}
/>
<UpdateTaskModal
visible={updateTaskModalVisible}
id={currentTaskId}
datasourceId={currentDatasourceId}
action={updateTaskModalAction}
onCancel={onUpdateTaskModalVisibleCancel}
/>
......
......@@ -34,6 +34,8 @@ class ImportExcel extends React.Component {
onChange && onChange([file]);
this.setState({ fileList: [file] });
console.log('file', file);
return false;
},
accept:".xlsx",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment