Commit 90128c52 by zhaochengxiang

模型增加分区

parent 9cdf9c4c
...@@ -86,6 +86,10 @@ export function* modelCopy(payload) { ...@@ -86,6 +86,10 @@ export function* modelCopy(payload) {
return yield call(datamodelerService.modelCopy, payload); return yield call(datamodelerService.modelCopy, payload);
} }
export function* getSupportedPartitionTypes() {
return yield call(datamodelerService.getSupportedPartitionTypes);
}
export function* extractExcelContent(payload) { export function* extractExcelContent(payload) {
return yield call(datamodelerService.extractExcelContent, payload); return yield call(datamodelerService.extractExcelContent, payload);
} }
......
...@@ -43,6 +43,10 @@ export function modelCopy(payload) { ...@@ -43,6 +43,10 @@ export function modelCopy(payload) {
return GetJSON("/datamodeler/easyDataModelerCURD/copy", payload); return GetJSON("/datamodeler/easyDataModelerCURD/copy", payload);
} }
export function getSupportedPartitionTypes() {
return GetJSON("/datamodeler/easyDataModelerCURD/getSupportedPartitionTypes");
}
export function extractExcelContent(payload) { export function extractExcelContent(payload) {
return PostFile("/datamodeler/easyDataModelerDesign/kickStart", payload); return PostFile("/datamodeler/easyDataModelerDesign/kickStart", payload);
} }
......
...@@ -4,6 +4,7 @@ import { Spin } from 'antd'; ...@@ -4,6 +4,7 @@ import { Spin } 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';
import ImportActionPartition from './ImportActionPartition';
import { dispatch } from '../../../../model'; import { dispatch } from '../../../../model';
...@@ -16,6 +17,7 @@ const ImportAction = (props) => { ...@@ -16,6 +17,7 @@ const ImportAction = (props) => {
const [ template, setTemplate ] = useState({}); const [ template, setTemplate ] = useState({});
const [ modelerData, setModelerData ] = useState(null); const [ modelerData, setModelerData ] = useState(null);
const [ supportedDatatypes, setSupportedDatatypes ] = useState([]); const [ supportedDatatypes, setSupportedDatatypes ] = useState([]);
const [ supportedPartitionTypes, setSupportedPartitionTypes ] = useState([]);
const [ validateReports, setValidateReports ] = useState([]); const [ validateReports, setValidateReports ] = useState([]);
const [ loading, setLoading ] = useState(false); const [ loading, setLoading ] = useState(false);
...@@ -79,16 +81,7 @@ const ImportAction = (props) => { ...@@ -79,16 +81,7 @@ const ImportAction = (props) => {
}, },
callback: data => { callback: data => {
setLoading(false); setLoading(false);
setModelerData(data||{}); getExtraData(data);
form.setFieldsValue({
cnName: data.cnName||'',
name: data.name||'',
remark: data.remark||'',
easyDataModelerModelingConstraint: data.easyDataModelerModelingConstraint||'',
easyDataModelerModelingTemplate: data.easyDataModelerModelingTemplate||''
});
onChange && onChange(data||{});
getSupportedDatatypes();
}, },
error: () => { error: () => {
setLoading(false); setLoading(false);
...@@ -108,16 +101,7 @@ const ImportAction = (props) => { ...@@ -108,16 +101,7 @@ const ImportAction = (props) => {
}, },
callback: data => { callback: data => {
setLoading(false); setLoading(false);
setModelerData(data||{}); getExtraData(data);
form.setFieldsValue({
cnName: data.cnName||'',
name: data.name||'',
remark: data.remark||'',
easyDataModelerModelingConstraint: data.easyDataModelerModelingConstraint||'',
easyDataModelerModelingTemplate: data.easyDataModelerModelingTemplate||''
});
onChange && onChange(data||{});
getSupportedDatatypes();
} }
}) })
} }
...@@ -163,6 +147,7 @@ const ImportAction = (props) => { ...@@ -163,6 +147,7 @@ const ImportAction = (props) => {
setTemplate(data.easyDataModelerModelingTemplate||{}); setTemplate(data.easyDataModelerModelingTemplate||{});
onChange && onChange(data||{}); onChange && onChange(data||{});
getSupportedDatatypes(); getSupportedDatatypes();
getSupportedPartitionTypes();
if (data) { if (data) {
form.setFieldsValue({ form.setFieldsValue({
...@@ -230,6 +215,15 @@ const ImportAction = (props) => { ...@@ -230,6 +215,15 @@ const ImportAction = (props) => {
}); });
} }
const getSupportedPartitionTypes = () => {
dispatch({
type: 'datamodel.getSupportedPartitionTypes',
callback: data => {
setSupportedPartitionTypes(data||[]);
}
});
}
const onHeaderChange = (changedValues, allValues) => { const onHeaderChange = (changedValues, allValues) => {
if (changedValues.hasOwnProperty('name') || changedValues.hasOwnProperty('cnName')) { if (changedValues.hasOwnProperty('name') || changedValues.hasOwnProperty('cnName')) {
validateDataModel(modelerData); validateDataModel(modelerData);
...@@ -277,6 +271,17 @@ const ImportAction = (props) => { ...@@ -277,6 +271,17 @@ const ImportAction = (props) => {
} }
} }
const onPartitionChange = (data, validate=false) => {
const newModelerData = {...modelerData, partition: data};
setModelerData(newModelerData);
onChange && onChange(newModelerData);
if (validate) {
validateDataModel(newModelerData);
}
}
const getIndicesAfterTableChange = (newModelerData) => { const getIndicesAfterTableChange = (newModelerData) => {
const newEasyDataModelerIndices = [...(newModelerData.easyDataModelerIndices||[])]; const newEasyDataModelerIndices = [...(newModelerData.easyDataModelerIndices||[])];
(newModelerData.easyDataModelerIndices||[]).forEach((easyDataModelerIndex, index) => { (newModelerData.easyDataModelerIndices||[]).forEach((easyDataModelerIndex, index) => {
...@@ -331,6 +336,16 @@ const ImportAction = (props) => { ...@@ -331,6 +336,16 @@ const ImportAction = (props) => {
editable={action!=='detail'} editable={action!=='detail'}
terms={terms} terms={terms}
/> />
<ImportActionPartition
modelerData={modelerData||{}}
constraint={constraint}
template={template}
validateReports={validateReports}
supportedPartitionTypes={supportedPartitionTypes}
onChange={onPartitionChange}
editable={action!=='detail'}
terms={terms}
/>
</React.Fragment>); </React.Fragment>);
return ( return (
......
import React, { useState, useEffect } from 'react';
import { Form, Typography, Divider, Button, Select, Row, Col, Tooltip, Table } from 'antd';
import { DeleteOutlined } from '@ant-design/icons';
import { showMessage, highlightSearchContentByTerms } from '../../../../util';
const { Option } = Select;
const PartitionTypeInput = ({ value = {}, partitionTypes, onChange }) => {
const onNameChange = (value) => {
let currentPartitionType = {};
(partitionTypes||[]).forEach((partitionType, index) => {
if (value === partitionType.name) {
currentPartitionType = partitionType;
}
})
triggerChange(currentPartitionType);
}
const triggerChange = (changedValue) => {
onChange && onChange(changedValue);
};
//value有可能为空
value = value ? value: {};
return (
<>
<Row align='middle'>
<Col span={9}>
<span>名称:</span>
</Col>
<Col span={15}>
<Select
onChange={onNameChange}
value={value.name || ''}
placeholder='请选择类型名称'
>
{
(partitionTypes||[]).map((partitionType, index) => {
return (
<Option key={partitionType.name||''}>{partitionType.name||''}</Option>
);
})
}
</Select>
</Col>
</Row>
</>
)
}
const AttributesInputItem = ({ indexedAttribute = null, attributes, onAttributeChange, onDelete , className }) => {
return (
<Row align='middle' className={className} >
<Col span={4}>
<span>字段名称:</span>
</Col>
<Col span={6}>
<Select
onChange={(value) => { onAttributeChange && onAttributeChange(value) }}
value={indexedAttribute ? (indexedAttribute.name||'') : ''}
placeholder='请选择字段名称'
>
{
(attributes||[]).map((attribute, index) => {
return (
((attribute.name||'')==='') ? null : <Option key={index} value={attribute.iid||''}>{attribute.name||''}</Option>
);
})
}
</Select>
</Col>
<Col span={1}></Col>
<Col span={1}>
<Tooltip title="删除">
<Button type="text" icon={<DeleteOutlined />} onClick={onDelete} />
</Tooltip>
</Col>
</Row>
);
}
const AttributesInput = ({ value = [], attributes, onChange }) => {
const indexedEasyDataModelAttributes = value;
const onAttributeChange = (value, index) => {
if (indexedEasyDataModelAttributes.findIndex(item => item.iid === value) !== -1) {
showMessage('warn', '字段不能重复选择');
return;
}
const newIndexedEasyDataModelAttributes = [...indexedEasyDataModelAttributes];
const _index = attributes.findIndex(item => item.iid === value);
newIndexedEasyDataModelAttributes.splice(index, 1, {...attributes[_index]});
triggerChange(newIndexedEasyDataModelAttributes);
}
const onItemDelete = (index) => {
const newIndexedEasyDataModelAttributes = [...indexedEasyDataModelAttributes];
newIndexedEasyDataModelAttributes.splice(index, 1);
if (newIndexedEasyDataModelAttributes.length === 0) {
newIndexedEasyDataModelAttributes.push({});
}
triggerChange(newIndexedEasyDataModelAttributes);
}
const addAttribute = () => {
triggerChange([...indexedEasyDataModelAttributes, {}])
}
const triggerChange = (changedValue) => {
onChange && onChange(changedValue);
};
return (
<>
{
(indexedEasyDataModelAttributes||[]).map((indexedAttribute, index) => {
return (
<AttributesInputItem
key={index}
className='mb-2'
indexedAttribute={indexedAttribute}
attributes={attributes}
onAttributeChange={(value) => { onAttributeChange(value, index) } }
onDelete={() => { onItemDelete(index) }}
/>
);
})
}
<Button onClick={addAttribute}>新增字段</Button>
</>
)
}
const EditableCell = ({
editing,
dataIndex,
colTitle,
inputType,
record,
index,
attributes,
partitionTypes,
children,
...restProps
}) => {
let editingComponent = null;
if (editing) {
editingComponent = (
<Form.Item
name={dataIndex}
style={{
margin: 0,
}}
valuePropName={'value'}
rules={[
{
required: true,
message: `请输入${colTitle}!`,
},
]}
>
{ (dataIndex==='keys') ? <AttributesInput attributes={attributes} /> : <PartitionTypeInput partitionTypes={partitionTypes} /> }
</Form.Item>
)
}
return (
<td {...restProps}>
{editing ? (
editingComponent
) : (
children
)}
</td>
);
};
const ImportActionPartition = (props) => {
const { modelerData, onChange, editable, constraint, template, terms, supportedPartitionTypes } = props;
const [ attributes, setAttributes ] = useState([]);
const [ data, setData ] = useState(null);
const [ form ] = Form.useForm();
const [ isEditing, setIsEditing ] = useState(false);
//规则改变的时候 数据表为可编辑状态
useEffect(() => {
setIsEditing(false);
}, [constraint, template, modelerData])
useEffect(() => {
setAttributes(modelerData.easyDataModelerDataModelAttributes||[]);
setData(modelerData.partition);
}, [modelerData])
const onAddClick = () => {
if (!data) {
setData({
partitionType: {},
keys: [],
});
form.setFieldsValue({
partitionType: {},
keys: [],
});
setIsEditing(true);
}
}
const edit = (record) => {
form.setFieldsValue({...record});
setIsEditing(true);
}
const remove = (record) => {
onChange && onChange(null);
}
const cancel = () => {
setIsEditing(false);
if (!data?.partitionType?.name) {
setData(null);
}
};
const save = async() => {
try {
const row = await form.validateFields();
if (!row.partitionType?.name) {
form.setFields([{ name: 'partitionType', errors: ['必须选择分区名称'] }]);
return;
}
const _iids = [];
(row.keys||[]).forEach(item => {
if ((item.iid||'')!=='') {
_iids.push(item.iid);
}
})
if ((_iids||[]).length === 0) {
form.setFields([{ name: 'keys', errors: ['必须选择字段'] }]);
return;
}
const newData = {
partitionType: row.partitionType,
keys: row.keys
}
onChange && onChange(newData, true);
setIsEditing(false);
} catch (errInfo) {
console.log('Validate Failed:', errInfo);
}
};
const onValuesChange = (changedValues, allValues) => {
// console.log('changed values', changedValues);
// console.log('all values', allValues);
};
const columns = [
{
title: '序号',
dataIndex: 'key',
editable: false,
width: 50,
render: (_, __, index) => {
return (index+1).toString();
}
},
{
title: '分区名称',
width: 200,
dataIndex: 'partitionType',
editable: true,
ellipsis: true,
render: (text, record, index) => {
return (
<Tooltip title={text||''}>
<span style={{ fontWeight: 'bold' }} >{highlightSearchContentByTerms(record?.partitionType?.name, terms)}</span>
</Tooltip>
)
}
},
{
title: '分区字段列表',
dataIndex: 'keys',
editable: true,
ellipsis: true,
render: (_, record, index) => {
return (
<div>
{
(record.keys||[]).map((item, index) => {
return (
<Row key={index}>
<span>字段: </span>
{ highlightSearchContentByTerms(item.name||'', terms) }
</Row>
)
})
}
</div>
);
}
},
];
const editableColumn = [
...columns,
{
title: '操作',
dataIndex: 'action',
width: 100,
render: (_, record) => {
if (!editable) return null;
return isEditing ? (
<>
<Typography.Link className='mr-3' onClick={() => save()}>
保存
</Typography.Link>
<Typography.Link onClick={() => {cancel()}}>
取消
</Typography.Link>
</>
) : (
<>
<Typography.Link className='mr-3' onClick={() => edit(record)}>
编辑
</Typography.Link>
<Typography.Link className='mr-3' onClick={() => remove(record)}>
删除
</Typography.Link>
</>
);
},
},
]
const mergedColumns = () => {
if (editable) {
return editableColumn.map((col) => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: (record) => ({
record,
dataIndex: col.dataIndex,
inputType: (col.dataIndex==='unique') ? 'check' : 'text',
colTitle: col.title,
editing: isEditing,
attributes,
partitionTypes: supportedPartitionTypes,
}),
};
});
}
return columns;
}
return (
<div className='model-import-action-index mt-7'>
<Divider orientation='left'>
<>
<span>数据表分区</span>
</>
</Divider>
{
editable && <div className='d-flex mb-3' style={{ justifyContent: 'flex-end' }}>
<Button type="primary" onClick={onAddClick} disabled={ data||isEditing } >新增分区</Button>
</div>
}
<div id="containerId">
<Form form={form} component={false} onValuesChange={onValuesChange}>
<Table
components={{
body: {
cell: EditableCell,
row: null,
},
}}
dataSource={data?[data]:[]}
columns={mergedColumns()}
size='small'
rowKey='name'
rowClassName="editable-row"
pagination={false}
sticky
/>
</Form>
</div>
</div>
);
};
export default ImportActionPartition;
\ No newline at end of file
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