Commit 4ad47ed9 by zhaochengxiang

支持hive

parent 5732470c
......@@ -443,3 +443,13 @@ export function* getSearchProperties() {
export function* searchModelBySearchProperties(payload) {
return yield call(datamodelerService.searchModelBySearchProperties, payload)
}
//zcx hive
export function* getDbTypes() {
return yield call(datamodelerService.getDbTypes)
}
//zcx hive
export function* getHiveStoredTypes() {
return yield call(datamodelerService.getHiveStoredTypes)
}
\ No newline at end of file
......@@ -399,3 +399,13 @@ export function getSearchProperties() {
export function searchModelBySearchProperties(payload) {
return PostJSON("/datamodeler/easyDataModelerCURD/searchEasyDataModelerDataModelsByModelSearchProperties", payload);
}
//zcx hive
export function getDbTypes() {
return GetJSON("/datamodeler/easyDataModelerCURD/getDbTypes")
}
//zcx hive
export function getHiveStoredTypes() {
return GetJSON("/datamodeler/easyDataModelerCURD/getHiveStoredTypes")
}
\ No newline at end of file
......@@ -500,15 +500,9 @@ const ImportAction = React.forwardRef((props, ref) => {
const getConsistentKeys = (newModelerData) => {
//分布键
let newDistribution = [];
let newDistribution = {...newModelerData.distributionKey};
(newModelerData.easyDataModelerDistributionKey||[]).forEach((item, index) => {
const _index = (newModelerData.easyDataModelerDataModelAttributes||[]).findIndex(_item => item.iid === _item.iid);
if (_index !== -1) {
newDistribution.push({...newModelerData.easyDataModelerDataModelAttributes[_index]});
}
})
newDistribution.keys = (newDistribution.keys??[]).filter(item => (newModelerData.easyDataModelerDataModelAttributes??[]).findIndex(_item => item.iid === _item.iid) !== -1)
//主键
let newPrimary = [];
......@@ -573,7 +567,7 @@ const ImportAction = React.forwardRef((props, ref) => {
newEasyDataModelerIndices = newEasyDataModelerIndices.filter(item => (item.indexedEasyDataModelAttributes||[]).length > 0);
return { partition: newPartition, easyDataModelerDistributionKey: newDistribution, easyDataModelerPrimaryKey: newPrimary, easyDataModelerIndices: newEasyDataModelerIndices, easyDataModelerSemiPrimaryKey: newSemiPrimary};
return { partition: newPartition, distributionKey: newDistribution, easyDataModelerPrimaryKey: newPrimary, easyDataModelerIndices: newEasyDataModelerIndices, easyDataModelerSemiPrimaryKey: newSemiPrimary};
}
return (
......
import React, { useState, useEffect, useMemo, useRef } from 'react';
import { Form, Input, Row, Col, Select, AutoComplete, Button, Divider, Tooltip, Checkbox, Space } from 'antd';
import { DownOutlined, UpOutlined, ExclamationCircleFilled, WarningFilled } from '@ant-design/icons';
import { DownOutlined, UpOutlined, ExclamationCircleFilled, WarningFilled, MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
import { Subject } from 'rxjs';
import classnames from 'classnames';
......@@ -53,7 +53,11 @@ const ImportActionHeader = (props) => {
const [ options, setOptions ] = useState([]);
const [ autoTranslate, setAutoTranslate ] = useState(false);
const [loadingDbTypes, setLoadingDbTypes] = useState(false);
const [dbTypes, setDbTypes] = useState();
const [ dataTypeList, setDataTypeList ] = useState(null);
const [loadingHiveStoredTypes, setLoadingHiveStoredTypes] = useState(false);
const [hiveStoredTypes, setHiveStoredTypes] = useState();
const [ bindingLoadRangeList, setBindingLoadRangeList ] = useState(null);
const [isCollapse, setCollapse] = useState(true)
const [ruleParams, setRuleParams] = useState({
......@@ -62,6 +66,8 @@ const ImportActionHeader = (props) => {
useEffect(() => {
getDataTypeList();
getDbTypes();
getHiveStoredTypes();
}, [])
useEffect(() => {
......@@ -82,22 +88,14 @@ const ImportActionHeader = (props) => {
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [modelerData])
//分布
//分布
const distributionDescription = useMemo(() => {
let newDistributionDescription = ''
if (!editable && modelerData) {
if (modelerData?.easyDataModelerDistributionKey) {
(modelerData?.easyDataModelerDistributionKey||[]).forEach((item, index) => {
if (index > 0) {
newDistributionDescription += ',';
if (modelerData && modelerData.distributionKey) {
return (modelerData.distributionKey.keys??[]).map(item => item.name).toString()
}
newDistributionDescription += item.name||'';
});
}
}
return newDistributionDescription;
}, [editable, modelerData])
return '';
}, [modelerData])
//主键
const primaryDescription = useMemo(() => {
......@@ -150,6 +148,15 @@ const ImportActionHeader = (props) => {
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [editable, modelerData])
const hiveTableConfigPropertiesDescription = useMemo(() => {
let tmp = []
for (const item of modelerData?.hiveTableConfigProperties??[]) {
tmp.push({[item.key]: [item.value]})
}
return tmp.join(';')
}, [modelerData])
const marginBottom = useMemo(() => {
return editable ? 15 : 10
}, [editable])
......@@ -174,6 +181,34 @@ const ImportActionHeader = (props) => {
})
}
const getDbTypes = () => {
setLoadingDbTypes(true)
dispatch({
type: 'datamodel.getDbTypes',
callback: data => {
setLoadingDbTypes(false)
setDbTypes(data)
},
error: () => {
setLoadingDbTypes(false)
}
})
}
const getHiveStoredTypes = () => {
setLoadingHiveStoredTypes(true)
dispatch({
type: 'datamodel.getHiveStoredTypes',
callback: data => {
setLoadingHiveStoredTypes(false)
setHiveStoredTypes(data)
},
error: () => {
setLoadingHiveStoredTypes(false)
}
})
}
const getBindingLoadRangeList = (dataTypeName) => {
dispatch({
type: 'datamodel.bindingLoadRangeList',
......@@ -227,6 +262,226 @@ const ImportActionHeader = (props) => {
}
}
const genericTechnicalInfoComponent = () => {
return (
<>
<Col xs={24} sm={24} lg={12} xl={8}>
<Form.Item
label="分布键"
name="distributionKey"
style={{ marginBottom }}
>
{
editable ? <DistributionItem modelerData={modelerData} /> : <span className='word-wrap'>{highlightSearchContentByTerms(distributionDescription, terms)}</span>
}
</Form.Item>
</Col>
<Col xs={24} sm={24} lg={12} xl={8}>
<Form.Item
label="分区键"
name="partition"
style={{ marginBottom }}
>
{
editable ? <PartitionSelect modelerData={modelerData} partitionTypes={supportedPartitionTypes} /> : <span className='word-wrap'>{highlightSearchContentByTerms(partitionsDescription, terms)}</span>
}
</Form.Item>
</Col>
<Col xs={24} sm={24} lg={12} xl={8}>
<Form.Item
label="类主键"
name="easyDataModelerSemiPrimaryKey"
style={{ marginBottom }}
>
{
editable ? <AttributesSelect modelerData={modelerData} mode='tags' /> : <span className='word-wrap'>{highlightSearchContentByTerms(semiPrimaryDescription, terms)}</span>
}
</Form.Item>
</Col>
<Col xs={24} sm={24} lg={12} xl={8}>
<Form.Item
label="数据情况"
name="dataCircumstances"
style={{ marginBottom }}
>
{
editable ? <Input placeholder='描述数据表中数据的更新频率、每日增量情况、数据量级和历史数据' /> : <span className='word-wrap'>{highlightSearchContentByTerms(modelerData?.dataCircumstances, terms)}</span>
}
</Form.Item>
</Col>
<Col xs={24} sm={24} lg={12} xl={8}>
<Form.Item
label="更新时间"
name="dataUpdatingTiming"
style={{ marginBottom }}
>
{
editable ? <UpdateSelect placeholder='描述数据表的更新时间点'/> : <span className='word-wrap'>{highlightSearchContentByTerms(modelerData?.dataUpdatingTiming, terms)}</span>
}
</Form.Item>
</Col>
<Col xs={24} sm={24} lg={12} xl={8}>
<Form.Item
label="数据类型"
name="dataType"
tooltip={dataTypeRemark}
style={{ marginBottom }}
>
{
editable ? <Select allowClear placeholder='请选择数据类型'>
{
dataTypeList?.map((item, index) => <Option key={index} value={item}>
{item}
</Option>)
}
</Select> : <span className='word-wrap'>{highlightSearchContentByTerms(modelerData?.dataType, terms)}</span>
}
</Form.Item>
</Col>
<Col xs={24} sm={24} lg={12} xl={8}>
<Form.Item
label="绑定加载范围"
name="bindingLoadRange"
tooltip={bindingLoadRemark}
style={{ marginBottom }}
>
{
editable ? <Select allowClear placeholder='请选择绑定加载范围'>
{
bindingLoadRangeList?.map((item, index) => <Option key={index} value={item}>
{item}
</Option>)
}
</Select> : <span className='word-wrap'>{highlightSearchContentByTerms(modelerData?.bindingLoadRang, terms)}</span>
}
</Form.Item>
</Col>
</>
)
}
const hiveTechnicalInfoComponent = () => {
return (
<>
<Col xs={24} sm={24} lg={12} xl={8}>
<Form.Item
label="数据表类型"
name="hiveExternalTable"
style={{ marginBottom }}
>
{
editable ? <Select allowClear>
<Select.Option value={false}>内部表</Select.Option>
<Select.Option value={true}>外部表</Select.Option>
</Select> : <span className='word-wrap'>{highlightSearchContentByTerms(modelerData?.hiveExternalTable?'外部表':'内部表', terms)}</span>
}
</Form.Item>
</Col>
<Col xs={24} sm={24} lg={12} xl={8}>
<Form.Item
label="生命周期"
name="hiveLifeCycle"
style={{ marginBottom }}
>
{
editable ? <Input placeholder='默认永久保存' /> : <span className='word-wrap'>{highlightSearchContentByTerms(modelerData?.hiveLifeCycle, terms)}</span>
}
</Form.Item>
</Col>
<Col xs={24} sm={24} lg={12} xl={8}>
<Form.Item
label="存储类型"
name="hiveStoredType"
style={{ marginBottom }}
>
{
editable ? <Select allowClear loading={loadingHiveStoredTypes}>
{ hiveStoredTypes?.map(item => <Select.Option key={item} value={item}>{item}</Select.Option>) }
</Select> : <span className='word-wrap'>{highlightSearchContentByTerms(modelerData?.hiveStoredType, terms)}</span>
}
</Form.Item>
</Col>
<Col xs={24} sm={24} lg={12} xl={8}>
<Form.Item
label="存储地址"
name="hvieStoredLocation"
style={{ marginBottom }}
>
{
editable ? <Input placeholder='请填写存储地址' /> : <span className='word-wrap'>{highlightSearchContentByTerms(modelerData?.hvieStoredLocation, terms)}</span>
}
</Form.Item>
</Col>
<Col xs={24} sm={24} lg={12} xl={8}>
<Form.Item
label="字段分隔符"
name="hiveFieldsTerminated"
style={{ marginBottom }}
>
{
editable ? <Input placeholder='请填写字段分隔符' /> : <span className='word-wrap'>{highlightSearchContentByTerms(modelerData?.hiveFieldsTerminated, terms)}</span>
}
</Form.Item>
</Col>
<Col xs={24} sm={24} lg={12} xl={8}>
<Form.Item label='自定义参数' style={{ marginBottom }}>
{
editable ? <Form.List name="hiveTableConfigProperties">
{(fields, { add, remove }) => (
<>
{fields.map(({ key, name, ...restField }) => (
<Space
key={key}
style={{
display: 'flex',
marginBottom: 0,
}}
align="baseline"
>
<Form.Item
{...restField}
name={[name, 'key']}
style={{ marginBottom }}
rules={[
{
required: true,
message: '请输入key值',
},
]}
>
<Input placeholder="请输入key值" />
</Form.Item>
<Form.Item
{...restField}
name={[name, 'value']}
style={{ marginBottom }}
rules={[
{
required: true,
message: '请输入value值',
},
]}
>
<Input placeholder="请输入value值" />
</Form.Item>
<MinusCircleOutlined onClick={() => remove(name)} />
</Space>
))}
<Form.Item style={{ marginBottom }}>
<Button type="dashed" onClick={() => add()} block icon={<PlusOutlined />}>
新增参数
</Button>
</Form.Item>
</>
)}
</Form.List> : <span className='word-wrap'>{highlightSearchContentByTerms(hiveTableConfigPropertiesDescription, terms)}</span>
}
</Form.Item>
</Col>
</>
)
}
const onValuesChange = (changedValues, allValues) => {
if (changedValues.hasOwnProperty('tableType')) return;
......@@ -272,6 +527,22 @@ const ImportActionHeader = (props) => {
<Row gutter={10}>
<Col xs={24} sm={24} lg={12} xl={8}>
<Form.Item
label='数据库类型'
name="dbType"
rules={[{ required: true, message: '请输入中文名称!' }]}
style={{ marginBottom }}
>
{
!modelerData?.id ? <Select loading={loadingDbTypes}>
{ dbTypes?.map(item => <Select.Option key={item} value={item}>{item}</Select.Option>) }
</Select> : <span className='word-wrap'>
{highlightSearchContentByTerms(modelerData?.dbType, terms)}
</span>
}
</Form.Item>
</Col>
<Col xs={24} sm={24} lg={12} xl={8}>
<Form.Item
label={<ItemTitle name='cnName' cnName='中文名称' validateReports={validateReports} />}
name="cnName"
rules={[{ required: true, message: '请输入中文名称!' }]}
......@@ -359,9 +630,9 @@ const ImportActionHeader = (props) => {
</Col>
<Col xs={24} sm={24} lg={12} xl={8}>
<Form.Item
label="数据表类型"
label="模板类型"
name="tableType"
rules={[{ required: true, message: '请选择数据表类型!' }]}
rules={[{ required: true, message: '请选择模板类型!' }]}
style={{ marginBottom }}
>
{
......@@ -396,97 +667,7 @@ const ImportActionHeader = (props) => {
onValuesChange={onValuesChange}
>
<Row gutter={10}>
<Col xs={24} sm={24} lg={12} xl={8}>
<Form.Item
label="分布键"
name="easyDataModelerDistributionKey"
style={{ marginBottom }}
>
{
editable ? <AttributesSelect modelerData={modelerData} /> : <span className='word-wrap'>{highlightSearchContentByTerms(distributionDescription, terms)}</span>
}
</Form.Item>
</Col>
<Col xs={24} sm={24} lg={12} xl={8}>
<Form.Item
label="分区键"
name="partition"
style={{ marginBottom }}
>
{
editable ? <PartitionSelect modelerData={modelerData} partitionTypes={supportedPartitionTypes} /> : <span className='word-wrap'>{highlightSearchContentByTerms(partitionsDescription, terms)}</span>
}
</Form.Item>
</Col>
<Col xs={24} sm={24} lg={12} xl={8}>
<Form.Item
label="类主键"
name="easyDataModelerSemiPrimaryKey"
style={{ marginBottom }}
>
{
editable ? <AttributesSelect modelerData={modelerData} mode='tags' /> : <span className='word-wrap'>{highlightSearchContentByTerms(semiPrimaryDescription, terms)}</span>
}
</Form.Item>
</Col>
<Col xs={24} sm={24} lg={12} xl={8}>
<Form.Item
label="数据情况"
name="dataCircumstances"
style={{ marginBottom }}
>
{
editable ? <Input placeholder='描述数据表中数据的更新频率、每日增量情况、数据量级和历史数据' /> : <span className='word-wrap'>{highlightSearchContentByTerms(modelerData?.dataCircumstances, terms)}</span>
}
</Form.Item>
</Col>
<Col xs={24} sm={24} lg={12} xl={8}>
<Form.Item
label="更新时间"
name="dataUpdatingTiming"
style={{ marginBottom }}
>
{
editable ? <UpdateSelect placeholder='描述数据表的更新时间点'/> : <span className='word-wrap'>{highlightSearchContentByTerms(modelerData?.dataUpdatingTiming, terms)}</span>
}
</Form.Item>
</Col>
<Col xs={24} sm={24} lg={12} xl={8}>
<Form.Item
label="数据类型"
name="dataType"
tooltip={dataTypeRemark}
style={{ marginBottom }}
>
{
editable ? <Select allowClear placeholder='请选择数据类型'>
{
dataTypeList?.map((item, index) => <Option key={index} value={item}>
{item}
</Option>)
}
</Select> : <span className='word-wrap'>{highlightSearchContentByTerms(modelerData?.dataType, terms)}</span>
}
</Form.Item>
</Col>
<Col xs={24} sm={24} lg={12} xl={8}>
<Form.Item
label="绑定加载范围"
name="bindingLoadRange"
tooltip={bindingLoadRemark}
style={{ marginBottom }}
>
{
editable ? <Select allowClear placeholder='请选择绑定加载范围'>
{
bindingLoadRangeList?.map((item, index) => <Option key={index} value={item}>
{item}
</Option>)
}
</Select> : <span className='word-wrap'>{highlightSearchContentByTerms(modelerData?.bindingLoadRang, terms)}</span>
}
</Form.Item>
</Col>
{ modelerData?.dbType==='Hive' ? hiveTechnicalInfoComponent() : genericTechnicalInfoComponent() }
</Row>
</Form>
}
......@@ -545,7 +726,7 @@ const TemplateSelect = ({ value = '', modelerData = undefined, templates = [], o
<span style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
{
isCustom ? <InputDebounce
placeholder='请输入数据表类型'
placeholder='请输入模板类型'
allowClear
value={modelerData?.tableType}
onChange={(val) => {
......@@ -557,7 +738,7 @@ const TemplateSelect = ({ value = '', modelerData = undefined, templates = [], o
onChange?.(val);
}}
value={value || undefined}
placeholder='请选择数据表类型'
placeholder='请选择模板类型'
allowClear
style={{ flex: 1 }}
{...restProps}
......@@ -646,6 +827,35 @@ const AttributesSelect = ({ value = [], modelerData, onChange, mode = 'multiple'
);
}
const DistributionItem = ({ value, modelerData, onChange, ...restProps }) => {
const onAttributeChange = (value) => {
const newKeys = (modelerData?.easyDataModelerDataModelAttributes||[]).filter(attribute => (value||[]).indexOf(attribute.iid)!==-1);
triggerChange({ keys: newKeys });
}
const triggerChange = (changedValue) => {
onChange?.({...value, ...changedValue});
}
return (
<Select
onChange={(val) => {
onAttributeChange(val)
}}
value={(value?.keys??[]).map(item => item.iid)}
placeholder='请选择字段名称'
mode='multiple'
allowClear={true}
>
{
modelerData?.easyDataModelerDataModelAttributes?.map((attribute, index) => <Option key={index} value={attribute.iid}>{attribute.name}</Option>
)
}
</Select>
);
}
const PartitionSelect = ({ value = {}, modelerData, partitionTypes = [], onChange, ...restProps }) => {
const onPartitionTypeChange = (value) => {
......
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