Commit 4cda2acf by zhaochengxiang

新增保存数据模型接口

parent 5c4f848b
import * as userService from '../service/user'; import * as userService from '../service/user';
import * as metadataService from '../service/metadata'; import * as metadataService from '../service/metadata';
import * as datamodelerService from '../service/datamodeler';
import { call } from 'redux-saga/effects'; import { call } from 'redux-saga/effects';
export function* getAllSystemAndDatabase() { export function* getAllSystemAndDatabase() {
...@@ -43,4 +44,57 @@ export function* getAllDataTable(payload) { ...@@ -43,4 +44,57 @@ export function* getAllDataTable(payload) {
export function* getAllFileds(payload) { export function* getAllFileds(payload) {
return yield call(metadataService.queryAllFields, payload); return yield call(metadataService.queryAllFields, payload);
}
export function* loadDataModelCatalog() {
return yield call(datamodelerService.loadDataModelCatalog);
}
export function* saveDataModelCatalog(payload) {
return yield call(datamodelerService.saveDataModelCatalog, payload);
}
export function* deleteDataModelCatalog(payload) {
return yield call(datamodelerService.deleteDataModelCatalog, payload);
}
export function* bindCatalogDataModel(payload) {
return yield call(datamodelerService.bindCatalogDataModel, payload);
}
export function* getCurrentDataModelCatalog(payload) {
return yield call(datamodelerService.getCurrentDataModelCatalog, payload);
}
export function* extractExcelContent(payload) {
return yield call(datamodelerService.extractExcelContent, payload);
}
export function* getAllConstraints() {
return yield call(datamodelerService.constraints);
}
//获取初稿
export function* getDraft(payload) {
return yield call(datamodelerService.draft, payload);
}
export function* getSupportedDatatypes() {
return yield call(datamodelerService.getSupportedDatatypes);
}
export function* suggest(payload) {
return yield call(datamodelerService.suggest, payload);
}
export function* saveDataModel(payload) {
return yield call(datamodelerService.saveDataModel, payload);
}
export function* deleteDataModel(payload) {
return yield call(datamodelerService.deleteDataModel, payload);
}
export function* getDataModel(payload) {
return yield call(datamodelerService.getDataModel, payload);
} }
\ No newline at end of file
import { filePost, GetJSON, PostJSON } from "../util/axios"
export function loadDataModelCatalog() {
return GetJSON("/datamodeler/easyDataModelerCURD/loadDataModelCatalog");
}
export function saveDataModelCatalog(payload) {
return PostJSON("/datamodeler/easyDataModelerCURD/saveDataModelCatalog", payload);
}
export function deleteDataModelCatalog(payload) {
return PostJSON("/datamodeler/easyDataModelerCURD/deleteDataModelCatalog", payload);
}
//绑定模型和模型目录
export function bindCatalogDataModel(payload) {
return PostJSON("/datamodeler/easyDataModelerCURD/catalogDataModel", payload);
}
//读取当前模型目录中的模型
export function getCurrentDataModelCatalog(payload) {
return GetJSON("/datamodeler/easyDataModelerCURD/getCurrentDataModelCatalog", payload);
}
export function extractExcelContent(payload) {
return filePost("/datamodeler/easyDataModelerDesign/kickStart", payload);
}
//规则
export function constraints() {
return GetJSON("/datamodeler/easyDataModelerConstraint/constraints");
}
//创建初稿
export function draft(payload) {
return PostJSON("/datamodeler/easyDataModelerDesign/draft", payload);
}
//获取支持的数据类型
export function getSupportedDatatypes() {
return GetJSON("/datamodeler/easyDataModelerDesign/getSupportedDatatypes");
}
export function suggest(payload) {
return PostJSON("/datamodeler/easyDataModelerDesign/suggest", payload);
}
//保存模型
export function saveDataModel(payload) {
return PostJSON("/datamodeler/easyDataModelerDesign/saveDataModel", payload);
}
export function deleteDataModel(payload) {
return PostJSON("/datamodeler/easyDataModelerCURD/deleteDataModel", payload);
}
export function getDataModel(payload) {
return GetJSON("/datamodeler/easyDataModelerCURD/getDataModel", payload);
}
...@@ -65,19 +65,16 @@ textplain.interceptors.request.use( ...@@ -65,19 +65,16 @@ textplain.interceptors.request.use(
const testA = axios.create({ const fileplain = axios.create({
baseURL, baseURL,
timeout: 5000, timeout: 5000,
headers:{'Content-Type':'multipart/form-data'}, headers:{'Content-Type':'multipart/form-data'},
processData:true, processData:false,
validateStatus: (status) => { validateStatus: (status) => {
return true; return true;
} }
}); });
let __source = null; let __source = null;
export const Cancel = function (msg) { export const Cancel = function (msg) {
return new Promise(res => __source && __source.cancel(msg)); return new Promise(res => __source && __source.cancel(msg));
...@@ -132,11 +129,14 @@ export function Post(url, payload) { ...@@ -132,11 +129,14 @@ export function Post(url, payload) {
) )
} }
export function testPost(url, payload) { export function filePost(url, payload) {
const { fileList = null,} = payload||{}; const { fileList = null,} = payload||{};
let formData = new FormData(); let formData = new FormData();
formData.append('attachment',fileList) (fileList||[]).forEach(file=> {
return testA.post(url, formData, ).then( formData.append('file', file);
});
return fileplain.post(url, formData, ).then(
callback callback
) )
} }
\ No newline at end of file
...@@ -86,3 +86,13 @@ export const paginate = function (items, pageNum = 1, pageSize = 10) { ...@@ -86,3 +86,13 @@ export const paginate = function (items, pageNum = 1, pageSize = 10) {
export const IsArr = function (data) { export const IsArr = function (data) {
return data && Object.prototype.toString.call(data) === '[object Array]'; return data && Object.prototype.toString.call(data) === '[object Array]';
} }
export const generateUUID = function() {
let d = new Date().getTime();
let uuid = 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
let r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16);
});
return uuid;
}
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect, useRef } from 'react';
import { Alert } from 'antd'; import { Alert } from 'antd';
import ImportActionHeader from './ImportActionHeader'; import ImportActionHeader from './ImportActionHeader';
import ImportActionTable from './ImportActionTable'; import ImportActionTable from './ImportActionTable';
import ImportActionIndex from './ImportActionIndex'; // import ImportActionIndex from './ImportActionIndex';
const originData = []; import { dispatchLatest } from '../../../../model';
for (let i = 0; i < 20; i++) {
originData.push({
key: i.toString(),
name: `trade_id${i}`,
cnName: `交易流水${i}`,
type: 'varchar',
length: 32,
desc: '流水单号',
nonnull: true,
primaryKey: false,
distributionKey: false,
zone: false,
});
}
const ImportAction = (props) => { const ImportAction = (props) => {
const { action } = props; const { action, hints } = props;
const [ tableData, setTableData ] = useState([...originData]);
const [indexData, setIndexData] = useState([]);
const [fileds, setFileds] = useState([]);
useEffect(() =>{ const [ constraints, setConstraints ] = useState([]);
const [ modelerData, setModelerData ] = useState({});
const _fileds = []; const mountRef = useRef();
tableData && tableData.forEach(item => { mountRef.current = true;
_fileds.push(item.name||'');
})
setFileds(_fileds);
//数据表结构变化 索引结构也要跟着变化 useEffect(() =>{
const _indexData = (indexData||[]).filter(item => {
let exsit = true; if (mountRef.current) {
mountRef.current = false;
(item.fileds||[]).forEach(filed => { dispatchLatest({
if (_fileds.indexOf(filed) ===-1) { type: 'datamodel.getAllConstraints',
exsit = false; callback: data => {
setConstraints(data||[]);
getDraft((data||[]).length>0?data[0]:{});
} }
}) })
}
return exsit;
})
setIndexData(_indexData);
//eslint-disable-next-line react-hooks/exhaustive-deps //eslint-disable-next-line react-hooks/exhaustive-deps
}, [tableData]); }, []);
const onTableChange = (data) => { const getDraft = (constraint) => {
setTableData(data); dispatchLatest({
type: 'datamodel.getDraft',
payload: {
data: {
hints,
modelerModelingConstraint: constraint
}
},
callback: data => {
setModelerData(data||{});
}
})
} }
const onIndexChange = (data) => { const onTableChange = (data) => {
setIndexData(data); setModelerData({...modelerData, easyDataModelerDataModelAttributes: data});
} }
return ( return (
...@@ -72,8 +63,8 @@ const ImportAction = (props) => { ...@@ -72,8 +63,8 @@ const ImportAction = (props) => {
className='mb-3' className='mb-3'
/> />
} }
<ImportActionTable data={tableData} onChange={onTableChange} editable={action!=='detail'} /> <ImportActionTable modelerData={modelerData||{}} onChange={onTableChange} editable={action!=='detail'} />
<ImportActionIndex data={indexData} fileds={fileds} onChange={onIndexChange} editable={action!=='detail'} /> {/* <ImportActionIndex data={indexData} fileds={fileds} onChange={onIndexChange} editable={action!=='detail'} /> */}
</> </>
); );
}; };
......
...@@ -3,6 +3,8 @@ import { Table, Input, InputNumber, Form, Typography, Radio, Divider, Button, Ch ...@@ -3,6 +3,8 @@ import { Table, Input, InputNumber, Form, Typography, Radio, Divider, Button, Ch
import { DndProvider, useDrag, useDrop } from 'react-dnd'; import { DndProvider, useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend'; import { HTML5Backend } from 'react-dnd-html5-backend';
import update from 'immutability-helper'; import update from 'immutability-helper';
import { generateUUID } from '../../../../util';
import { dispatchLatest } from '../../../../model';
const type = 'DragableTableBodyRow'; const type = 'DragableTableBodyRow';
...@@ -91,17 +93,17 @@ const DragableBodyRow = ({ index, moveRow, className, style, ...restProps }) => ...@@ -91,17 +93,17 @@ const DragableBodyRow = ({ index, moveRow, className, style, ...restProps }) =>
}; };
const ImportActionTable = (props) => { const ImportActionTable = (props) => {
const { data, onChange, editable } = props; const { modelerData, onChange, editable } = props;
const data = modelerData.easyDataModelerDataModelAttributes||[];
const [form] = Form.useForm(); const [form] = Form.useForm();
const [editingKey, setEditingKey] = useState(''); const [editingKey, setEditingKey] = useState('');
const [recommends, setRecommends] = useState([]);
const [suggests, setSuggests] = useState([]); const [suggests, setSuggests] = useState([]);
const isEditing = (record) => record.key === editingKey; const isEditing = (record) => record.iid === editingKey;
const onAddClick = () => { const onAddClick = () => {
//test
const newData = [{key: -1}, ...data]; const newData = [{iid: generateUUID()}, ...data];
onChange && onChange(newData); onChange && onChange(newData);
edit(newData[0]); edit(newData[0]);
...@@ -111,17 +113,16 @@ const ImportActionTable = (props) => { ...@@ -111,17 +113,16 @@ const ImportActionTable = (props) => {
form.setFieldsValue({ form.setFieldsValue({
name: '', name: '',
cnName: '', cnName: '',
type: '', datatype: {},
length: 0, remark: '',
desc: '',
...record, ...record,
}); });
setEditingKey(record.key); setEditingKey(record.iid);
}; };
const remove = (record) => { const remove = (record) => {
const newData = [...data]; const newData = [...data];
const index = newData.findIndex((item) => record.key === item.key); const index = newData.findIndex((item) => record.iid === item.iid);
newData.splice(index, 1); newData.splice(index, 1);
onChange && onChange(newData); onChange && onChange(newData);
} }
...@@ -129,7 +130,7 @@ const ImportActionTable = (props) => { ...@@ -129,7 +130,7 @@ const ImportActionTable = (props) => {
const cancel = () => { const cancel = () => {
const newData = [...data]; const newData = [...data];
const index = newData.findIndex((item) => editingKey === item.key); const index = newData.findIndex((item) => editingKey === item.iid);
const item = newData[index]; const item = newData[index];
if (!item.name || item.name==='') { if (!item.name || item.name==='') {
...@@ -138,82 +139,58 @@ const ImportActionTable = (props) => { ...@@ -138,82 +139,58 @@ const ImportActionTable = (props) => {
} }
setEditingKey(''); setEditingKey('');
setRecommends([]); setSuggests([]);
}; };
const save = () => { const save = async() => {
try { try {
setRecommends([]); const row = await form.validateFields();
const _suggests = [
{
name: '建议1'
},
{
name: '建议2'
}
];
setSuggests(_suggests)
if (_suggests.length === 0) { const newData = [...data];
constraintSave(); const index = newData.findIndex((item) => editingKey === item.iid);
}
const item = newData[index];
newData.splice(index, 1, { ...item, ...row });
onChange && onChange(newData);
setEditingKey('');
setSuggests([]);
} catch (errInfo) { } catch (errInfo) {
console.log('Validate Failed:', errInfo); console.log('Validate Failed:', errInfo);
} }
}; };
const constraintSave = async () => {
const row = await form.validateFields();
//test
row.key = '-1';
const newData = [...data];
const index = newData.findIndex((item) => editingKey === item.key);
if (index > -1) {
const item = newData[index];
newData.splice(index, 1, { ...item, ...row });
} else {
newData.push(row);
}
onChange && onChange(newData);
setEditingKey('');
setSuggests([]);
}
const onValuesChange = (changedValues, allValues) => { const onValuesChange = (changedValues, allValues) => {
// console.log('changed values', changedValues); // console.log('changed values', changedValues);
// console.log('all values', allValues); // console.log('all values', allValues);
setRecommends([ const newData = [...data];
{ const index = newData.findIndex((item) => editingKey === item.iid);
name: 'trade_id', const item = newData[index];
cnName: '流水交易', newData.splice(index, 1, { ...item, ...allValues });
type: 'varchar',
length: 32, dispatchLatest({
desc: '流水交易' type: 'datamodel.suggest',
payload: {
data: { ...modelerData, easyDataModelerDataModelAttributes: newData },
params: {
easyDataModelerDataModelAttributeIid: editingKey
}
}, },
{ callback: data => {
name: 'trade_id', setSuggests(data||[]);
cnName: '流水交易交易',
type: 'varchar',
length: 32,
desc: '流水单号'
} }
]) })
}; };
const onRecommendChange = (e) => { const onSuggestChange = (e) => {
form.setFieldsValue({ form.setFieldsValue({
...recommends[e.target.value] ...suggests[e.target.value]
}); });
setRecommends([]); setSuggests([]);
}; };
const columns = [ const columns = [
...@@ -237,50 +214,16 @@ const ImportActionTable = (props) => { ...@@ -237,50 +214,16 @@ const ImportActionTable = (props) => {
}, },
{ {
title: '类型', title: '类型',
dataIndex: 'type', dataIndex: 'datatype',
editable: true, editable: true,
}, render: (datatype, record, index) => {
{ return datatype.name||'';
title: '长度',
dataIndex: 'length',
editable: true,
},
{
title: '描述',
dataIndex: 'desc',
editable: true,
},
{
title: '非空',
dataIndex: 'nonnull',
editable: true,
render: (text, record, index) => {
return text ? '是': '否';
}
},
{
title: '主键',
dataIndex: 'primaryKey',
editable: true,
render: (text, record, index) => {
return text ? '是': '否';
} }
}, },
{ {
title: '分布键', title: '描述',
dataIndex: 'distributionKey', dataIndex: 'remark',
editable: true,
render: (text, record, index) => {
return text ? '是': '否';
}
},
{
title: '分区',
dataIndex: 'zone',
editable: true, editable: true,
render: (text, record, index) => {
return text ? '是': '否';
}
}, },
{ {
title: '操作', title: '操作',
...@@ -303,7 +246,7 @@ const ImportActionTable = (props) => { ...@@ -303,7 +246,7 @@ const ImportActionTable = (props) => {
编辑 编辑
</Typography.Link> </Typography.Link>
<Popconfirm disabled={editingKey !== ''} title="删除字段会删除相关的索引,您确定删除吗?" onConfirm={() => remove(record)}> <Popconfirm disabled={editingKey !== ''} title="删除字段会删除相关的索引,您确定删除吗?" onConfirm={() => remove(record)}>
<a href="">删除</a> <a disabled={editingKey !== ''} href="">删除</a>
</Popconfirm> </Popconfirm>
</> </>
); );
...@@ -320,7 +263,7 @@ const ImportActionTable = (props) => { ...@@ -320,7 +263,7 @@ const ImportActionTable = (props) => {
...col, ...col,
onCell: (record) => ({ onCell: (record) => ({
record, record,
inputType: (col.dataIndex==='nonnull'||col.dataIndex==='primaryKey'||col.dataIndex==='distributionKey'||col.dataIndex==='zone') ? 'check' : (col.dataIndex==='length'?'number':'text'), inputType: 'text',
dataIndex: col.dataIndex, dataIndex: col.dataIndex,
title: col.title, title: col.title,
editing: isEditing(record), editing: isEditing(record),
...@@ -371,9 +314,10 @@ const ImportActionTable = (props) => { ...@@ -371,9 +314,10 @@ const ImportActionTable = (props) => {
moveRow moveRow
} }
}} }}
dataSource={data} dataSource={data||[]}
columns={mergedColumns} columns={mergedColumns}
size='small' size='small'
rowKey='iid'
rowClassName="editable-row" rowClassName="editable-row"
pagination={false} pagination={false}
expandable={{ expandable={{
...@@ -384,30 +328,13 @@ const ImportActionTable = (props) => { ...@@ -384,30 +328,13 @@ const ImportActionTable = (props) => {
{ {
suggests && suggests.length>0 && ( suggests && suggests.length>0 && (
<> <>
<Divider orientation="left">建议</Divider>
<div className='mb-3 ml-7'>
{
suggests && suggests.map((suggest, index) => {
return (
<div key={index} className='mt-3'>{suggest.name||''}</div>
)
})
}
</div>
<Button className='mb-3 ml-7' type='primary' onClick={constraintSave}>强制保存</Button>
</>
)
}
{
recommends && recommends.length>0 && (
<>
<Divider orientation="left">智能推荐</Divider> <Divider orientation="left">智能推荐</Divider>
<Radio.Group onChange={onRecommendChange} className='mb-3 ml-7'> <Radio.Group onChange={onSuggestChange} className='mb-3 ml-7'>
{ {
recommends && recommends.map((recommend, index) => { suggests && suggests.map((suggest, index) => {
return ( return (
<Radio key={index} value={index} className='mt-3' style={{ display: 'block' }}> <Radio key={index} value={index} className='mt-3' style={{ display: 'block' }}>
{`${recommend.name||''}`} {`${suggest.name||''}`}
</Radio> </Radio>
) )
}) })
...@@ -423,7 +350,7 @@ const ImportActionTable = (props) => { ...@@ -423,7 +350,7 @@ const ImportActionTable = (props) => {
expandIcon: ({ expanded, onExpand, record }) => { expandIcon: ({ expanded, onExpand, record }) => {
return <></>; return <></>;
}, },
rowExpandable: record => (editingKey!==''&&((recommends||[]).length>0||(suggests||[]).length>0)), rowExpandable: record => (editingKey!==''&&(suggests||[]).length>0),
expandedRowKeys: [editingKey] expandedRowKeys: [editingKey]
}} }}
/> />
......
...@@ -13,18 +13,26 @@ class ImportExcel extends React.Component { ...@@ -13,18 +13,26 @@ class ImportExcel extends React.Component {
render() { render() {
const { onChange } = this.props;
const uploadProps = { const uploadProps = {
onRemove: file => { onRemove: file => {
this.setState(state => { this.setState(state => {
const index = state.fileList.indexOf(file) const index = state.fileList.indexOf(file);
const newFileList = state.fileList.slice() const newFileList = state.fileList.slice();
newFileList.splice(index, 1) newFileList.splice(index, 1);
onChange && onChange(newFileList);
return { return {
fileList: newFileList, fileList: newFileList,
} }
}) })
}, },
beforeUpload: file => { beforeUpload: file => {
onChange && onChange([file]);
this.setState(state => ({ this.setState(state => ({
fileList: [file], fileList: [file],
})) }))
......
...@@ -6,6 +6,8 @@ import ImportExcel from './ImportExcel'; ...@@ -6,6 +6,8 @@ import ImportExcel from './ImportExcel';
import ImportMetadata from './ImportMetadata'; import ImportMetadata from './ImportMetadata';
import ImportAction from './ImportAction'; import ImportAction from './ImportAction';
import { dispatchLatest } from '../../../../model';
const modes = [ const modes = [
{ {
title: 'Excel导入', title: 'Excel导入',
...@@ -30,7 +32,10 @@ class ImportModal extends React.Component { ...@@ -30,7 +32,10 @@ class ImportModal extends React.Component {
super(); super();
this.state = { this.state = {
step: 0, step: 0,
radioValue: '' radioValue: '',
excelFiles: [],
hints: [],
confirmLoading: false,
} }
} }
...@@ -47,14 +52,38 @@ class ImportModal extends React.Component { ...@@ -47,14 +52,38 @@ class ImportModal extends React.Component {
} }
next = () => { next = () => {
const { step, radioValue, excelFiles } = this.state;
if (step===1 && radioValue===0) {
if ((excelFiles||[]).length === 0) {
} else {
this.setState({ confirmLoading: true }, () => {
dispatchLatest({
type: 'datamodel.extractExcelContent',
payload: { fileList: excelFiles },
callback: data => {
this.setState({ confirmLoading: false, hints: data||[], step: (step+1) });
}
})
})
}
return;
}
this.setState({ this.setState({
step: (this.state.step+1) step: (step+1)
}) })
} }
onImportExcelChange = (files) => {
this.setState({ excelFiles: files||[] });
}
render() { render() {
const { visible, onCancel } = this.props; const { visible, onCancel } = this.props;
const { radioValue, step } = this.state; const { radioValue, step, confirmLoading, hints } = this.state;
return ( return (
<Modal <Modal
...@@ -82,6 +111,7 @@ class ImportModal extends React.Component { ...@@ -82,6 +111,7 @@ class ImportModal extends React.Component {
<Button <Button
key="1" key="1"
type="primary" type="primary"
loading={confirmLoading}
style={{ display: (step<2)?'':'none' }} style={{ display: (step<2)?'':'none' }}
onClick={this.next} onClick={this.next}
> >
...@@ -90,6 +120,7 @@ class ImportModal extends React.Component { ...@@ -90,6 +120,7 @@ class ImportModal extends React.Component {
<Button <Button
key="2" key="2"
type="primary" type="primary"
loading={confirmLoading}
style={{ display: (step===2)?'':'none' }} style={{ display: (step===2)?'':'none' }}
> >
保存 保存
...@@ -114,7 +145,7 @@ class ImportModal extends React.Component { ...@@ -114,7 +145,7 @@ class ImportModal extends React.Component {
</> </>
} }
{ {
step===1 && radioValue===0 && <ImportExcel /> step===1 && radioValue===0 && <ImportExcel onChange={this.onImportExcelChange} />
} }
{ {
step===1 && radioValue===1 && <></> step===1 && radioValue===1 && <></>
...@@ -129,7 +160,7 @@ class ImportModal extends React.Component { ...@@ -129,7 +160,7 @@ class ImportModal extends React.Component {
step===1 && radioValue===4 && <></> step===1 && radioValue===4 && <></>
} }
{ {
step===2 && <ImportAction /> step===2 && <ImportAction hints={hints} />
} }
</> </>
</Modal> </Modal>
......
...@@ -3,39 +3,7 @@ import { Tooltip, Tree, message, Button } from "antd"; ...@@ -3,39 +3,7 @@ import { Tooltip, Tree, message, Button } from "antd";
import { PlusOutlined, EditOutlined, SyncOutlined, DeleteOutlined } from '@ant-design/icons'; import { PlusOutlined, EditOutlined, SyncOutlined, DeleteOutlined } from '@ant-design/icons';
import UpdateTreeItemModal from './UpdateTreeItemModal'; import UpdateTreeItemModal from './UpdateTreeItemModal';
import { dispatchLatest } from '../../../../model';
const _treeData = [
{
title: 'parent 1',
key: '0-0',
children: [
{
title: 'parent 1-0',
key: '0-0-0',
children: [
{
title: 'leaf',
key: '0-0-0-0',
},
{
title: 'leaf',
key: '0-0-0-1',
},
],
},
{
title: 'parent 1-1',
key: '0-0-1',
children: [
{
title: 'sss',
key: '0-0-1-0',
},
],
},
],
},
];
class ModelTree extends React.Component { class ModelTree extends React.Component {
...@@ -43,7 +11,7 @@ class ModelTree extends React.Component { ...@@ -43,7 +11,7 @@ class ModelTree extends React.Component {
super(); super();
this.state = { this.state = {
loading: false, loading: false,
treeData: _treeData, treeData: null,
item: null, item: null,
visible: false, visible: false,
type: null type: null
...@@ -59,11 +27,35 @@ class ModelTree extends React.Component { ...@@ -59,11 +27,35 @@ class ModelTree extends React.Component {
this.setState({ loading: true }, () => { this.setState({ loading: true }, () => {
this.setState({ loading: false, treeData: _treeData, item: _treeData[0] }, () => { dispatchLatest({
if (onSelect) { type: 'datamodel.loadDataModelCatalog',
onSelect(_treeData[0].key); callback: data => {
data.key = data.id||'';
data.title = data.name||'';
data.children = data.subCatalogs||[];
function recursion(subCatalogs) {
if ((subCatalogs||[]).length===0) return;
(subCatalogs||[]).forEach(catalog=> {
catalog.key = catalog.id||'';
catalog.title = catalog.name||'';
catalog.children = catalog.subCatalogs||[];
recursion(catalog.subCatalogs);
})
}
recursion(data.subCatalogs);
this.setState({ loading: false, treeData: [ data ], item: data }, () => {
if (onSelect) {
onSelect(data.key);
}
});
} }
}); })
}) })
} }
...@@ -105,6 +97,17 @@ class ModelTree extends React.Component { ...@@ -105,6 +97,17 @@ class ModelTree extends React.Component {
return; return;
} }
dispatchLatest({
type: 'datamodel.deleteDataModelCatalog',
payload: {
easyDataModelerCatalogId: item.id
},
callback: () => {
message.success('删除目录成功');
this.getTreeData();
}
});
} }
onUpdateTreeItemModalOk = () => { onUpdateTreeItemModalOk = () => {
......
import React from 'react' import React, { useState } from 'react';
import { Modal, Form, Input, Radio } from 'antd' import { Modal, Form, Input } from 'antd';
class UpdateTreeItemForm extends React.Component { import { dispatchLatest } from '../../../../model';
constructor(props){
super(props);
this.state = {
itemType: 'sub',
radioDisable: false
}
}
componentDidMount() {
const { type, item } = this.props;
if (type === 'add') {
if (item) {
this.setState({ itemType: 'sub', radioDisable: false });
} else {
this.setState({ itemType: 'root', radioDisable: true })
}
} else {
this.setState({ itemType: 'sub', radioDisable: true });
}
}
onRadioChange = (e) => { class UpdateTreeItemForm extends React.Component {
this.setState({ itemType: e.target.value });
}
render() { render() {
const { item, type } = this.props; const { item, type, form } = this.props;
const { itemType, radioDisable } = this.state;
const formItemLayout = { const formItemLayout = {
labelCol: { labelCol: {
...@@ -46,91 +22,90 @@ class UpdateTreeItemForm extends React.Component { ...@@ -46,91 +22,90 @@ class UpdateTreeItemForm extends React.Component {
return ( return (
<Form <Form
{...formItemLayout} {...formItemLayout}
form={form}
name="basic" name="basic"
initialValues={ initialValues={
type!=='add'?{ type!=='add'?{
title: item?item.title:'' name: item?item.name:'',
remark: item?item.remark:'',
}:null }:null
} }
> >
{
type==='add'&&<Form.Item label="目录类型">
<Radio.Group
onChange={this.onRadioChange}
value={itemType}
disabled={radioDisable}
>
<Radio value='root'>根目录</Radio>
<Radio value='sub'>子目录</Radio>
</Radio.Group>
</Form.Item>
}
<Form.Item <Form.Item
label="名称" label="名称"
name="title" name="name"
rules={[{ required: true, message: '请输入名称!' }]} rules={[{ required: true, message: '请输入名称!' }]}
> >
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item
label="描述"
name="remark"
rules={[{ required: true, message: '请输入描述!' }]}
>
<Input />
</Form.Item>
</Form> </Form>
); );
} }
} }
class UpdateTreeItemModal extends React.Component { const UpdateTreeItemModal = (props) => {
constructor() { const { onOk, type, item, onCancel, visible } = props;
super(); const [ confirmLoading, setConfirmLoading ] = useState(false);
this.form = React.createRef(); const [form] = Form.useForm();
this.state= {
confirmLoading: false
}
}
handleOk = () => { const handleOk = async () => {
const { onOk, type } = this.props;
this.setState({ confirmLoading: true }, () => { setConfirmLoading(true);
this.form.current.validateFields((err,values) => {
if (!err) { try {
if (type==='add' && values.itemType==='root') { const values = await form.validateFields();
this.setState({ confirmLoading: false }); let payload = null;
if (onOk) { if (type === 'add') {
onOk(); payload = {
} ...values,
} else if (type==='add' && values.itemType==='sub') { parentId: item.id
this.setState({ confirmLoading: false }); };
if (onOk) { } else {
onOk(); payload = {
} ...item,
} else { ...values,
this.setState({ confirmLoading: false });
if (onOk) {
onOk();
}
}
} }
}) }
})
}
render() { dispatchLatest({
const { visible, type, item, onCancel } = this.props; type: 'datamodel.saveDataModelCatalog',
const { confirmLoading } = this.state; payload: {
data: payload
},
callback: () => {
return ( setConfirmLoading(false);
<Modal
confirmLoading={confirmLoading} if (onOk) {
visible={visible} onOk();
title={type==='add'?"新增目录":"更新目录"} }
destroyOnClose }
onOk={this.handleOk} });
onCancel={onCancel} } catch (errInfo) {
> console.log('Validate Failed:', errInfo);
<UpdateTreeItemForm ref={this.form} item={item} type={type} /> }
</Modal>
);
} }
return (
<Modal
confirmLoading={confirmLoading}
visible={visible}
title={type==='add'?"新增目录":"更新目录"}
destroyOnClose
onOk={handleOk}
onCancel={onCancel}
>
<UpdateTreeItemForm form={form} item={item} type={type} />
</Modal>
);
} }
export default UpdateTreeItemModal; export default UpdateTreeItemModal;
\ No newline at end of file
...@@ -6,6 +6,8 @@ import ModelTable from './Component/ModelTable'; ...@@ -6,6 +6,8 @@ import ModelTable from './Component/ModelTable';
import ImportModal from './Component/ImportModal'; import ImportModal from './Component/ImportModal';
import ExportModal from './Component/ExportModal'; import ExportModal from './Component/ExportModal';
import { dispatchLatest } from '../../../model';
class Model extends React.Component { class Model extends React.Component {
constructor() { constructor() {
...@@ -16,6 +18,18 @@ class Model extends React.Component { ...@@ -16,6 +18,18 @@ class Model extends React.Component {
} }
} }
onTreeSelect = (key) => {
dispatchLatest({
type: 'datamodel.getCurrentDataModelCatalog',
payload: {
easyDataModelerCatalogId: key
},
callback: data => {
console.log('data model', data);
}
})
}
onImportBtnClick = () => { onImportBtnClick = () => {
this.setState({ importModalVisible: true }); this.setState({ importModalVisible: true });
} }
...@@ -39,7 +53,7 @@ class Model extends React.Component { ...@@ -39,7 +53,7 @@ class Model extends React.Component {
<div style={{ backgroundColor: '#fff', height: '100%' }}> <div style={{ backgroundColor: '#fff', height: '100%' }}>
<Row gutter={10} style={{ height: '100%' }}> <Row gutter={10} style={{ height: '100%' }}>
<Col span={6}> <Col span={6}>
<ModelTree /> <ModelTree onSelect={this.onTreeSelect} />
</Col> </Col>
<Col span={18}> <Col span={18}>
<div <div
......
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