|
@@ -1,18 +1,21 @@
|
|
|
-import { Tabs, Button, Space, Select, Modal, Input } from 'antd'
|
|
|
+import { Tabs, Button, Space, Select, Modal, Input, Form, message } from 'antd'
|
|
|
import DataSourceManage from '../component/DatasourceManage.jsx'
|
|
|
import DatasourceAdd from '../component/DatasourceAdd'
|
|
|
import DatasourceSyncView from '../component/DatasourceSyncView'
|
|
|
import DatasourceLog from '../component/DatasourceLog'
|
|
|
-import React, { useState } from 'react'
|
|
|
+import React, { useState, useEffect } from 'react'
|
|
|
import { Link, useNavigate, useLocation } from 'react-router-dom'
|
|
|
import styled from 'styled-components'
|
|
|
-import { useEffect } from 'react'
|
|
|
+import { importDatalake, craeteAilab } from '../services'
|
|
|
+import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons'
|
|
|
+
|
|
|
const { TabPane } = Tabs
|
|
|
|
|
|
const Datasource = styled.div`
|
|
|
padding: 20px;
|
|
|
`
|
|
|
-// const Main = () {}
|
|
|
+const FormItem = Form.Item
|
|
|
+const FormList = Form.List
|
|
|
|
|
|
export default function DatasourceView() {
|
|
|
const navigate = useNavigate()
|
|
@@ -29,27 +32,9 @@ export default function DatasourceView() {
|
|
|
const [currentLogPageSize, setCurrentLogPageSize] = useState(10)
|
|
|
// 导入数据表
|
|
|
const [importData, setImportData] = useState(false)
|
|
|
- const importTable = async () => {}
|
|
|
- const importModal = (
|
|
|
- <Modal
|
|
|
- title="导入数据表"
|
|
|
- visible="importData"
|
|
|
- onOk={importTable}
|
|
|
- okText="确认导入"
|
|
|
- onCancel={() => {
|
|
|
- setImportData(false)
|
|
|
- }}>
|
|
|
- <Space style={{ padding: '10px 10px 10px ' }}>
|
|
|
- <span>数据库名称:</span>
|
|
|
- <Input></Input>
|
|
|
- </Space>
|
|
|
- <br />
|
|
|
- <Space style={{ padding: '10px 10px 10px ' }}>
|
|
|
- <span>数据表名称:</span>
|
|
|
- <Input></Input>
|
|
|
- </Space>
|
|
|
- </Modal>
|
|
|
- )
|
|
|
+ const [isCreateTable, setIsCreateTable] = useState(false)
|
|
|
+ const [datatableForm] = Form.useForm()
|
|
|
+ const [ailabtableForm] = Form.useForm()
|
|
|
// 数据隔离
|
|
|
const [currentDataType, setCurrentDataType] = useState('ailab')
|
|
|
|
|
@@ -71,6 +56,13 @@ export default function DatasourceView() {
|
|
|
const updateDataSource = () => {
|
|
|
sourceRef.current.updateSourceList()
|
|
|
}
|
|
|
+
|
|
|
+ const updateAilabList = () => {
|
|
|
+ sourceRef.current.updateAilabList()
|
|
|
+ }
|
|
|
+ const updateLakeList = () => {
|
|
|
+ sourceRef.current.updateLakeList()
|
|
|
+ }
|
|
|
const updateLogs = () => {
|
|
|
logRef.current?.updateLogList()
|
|
|
}
|
|
@@ -84,6 +76,230 @@ export default function DatasourceView() {
|
|
|
setCurrentDataType(val)
|
|
|
}
|
|
|
|
|
|
+ const importTable = () => {
|
|
|
+ datatableForm
|
|
|
+ .validateFields()
|
|
|
+ .then(async () => {
|
|
|
+ const { database_name, datatable_name } = datatableForm.getFieldValue()
|
|
|
+ const { data } = await importDatalake({
|
|
|
+ database_name,
|
|
|
+ table_name: datatable_name,
|
|
|
+ })
|
|
|
+ if (data.code === 200) {
|
|
|
+ message.success('导入成功')
|
|
|
+ datatableForm.resetFields()
|
|
|
+ setImportData(false)
|
|
|
+ updateLakeList()
|
|
|
+ } else {
|
|
|
+ message.error(data.msg)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch(err => {
|
|
|
+ message.error('请检查表单数据是否完整')
|
|
|
+ })
|
|
|
+ }
|
|
|
+ const importModal = (
|
|
|
+ <Modal
|
|
|
+ title="导入数据表"
|
|
|
+ visible={importData}
|
|
|
+ onOk={importTable}
|
|
|
+ okText="确认导入"
|
|
|
+ onCancel={() => {
|
|
|
+ datatableForm.resetFields()
|
|
|
+ setImportData(false)
|
|
|
+ }}>
|
|
|
+ <Form form={datatableForm}>
|
|
|
+ <FormItem
|
|
|
+ name="database_name"
|
|
|
+ label="数据库名称"
|
|
|
+ rules={[
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: '请输入数据库名称!',
|
|
|
+ },
|
|
|
+ ]}>
|
|
|
+ <Input placeholder="输入数据库名称" />
|
|
|
+ </FormItem>
|
|
|
+ <FormItem
|
|
|
+ name="datatable_name"
|
|
|
+ label="数据表名称"
|
|
|
+ rules={[
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: '请输入数据表名称!',
|
|
|
+ },
|
|
|
+ ]}>
|
|
|
+ <Input placeholder="输入数据表名称" />
|
|
|
+ </FormItem>
|
|
|
+ </Form>
|
|
|
+ </Modal>
|
|
|
+ )
|
|
|
+
|
|
|
+ const createAilabTable = () => {
|
|
|
+ console.log()
|
|
|
+ ailabtableForm
|
|
|
+ .validateFields()
|
|
|
+ .then(async () => {
|
|
|
+ const { database_field, table_name, partition_column } =
|
|
|
+ ailabtableForm.getFieldsValue()
|
|
|
+ const params = {
|
|
|
+ project_id: sessionStorage.getItem('project_id'),
|
|
|
+ table_name,
|
|
|
+ partition_column,
|
|
|
+ columns: database_field,
|
|
|
+ }
|
|
|
+ const { data } = await craeteAilab(params)
|
|
|
+ if (data.code === 200) {
|
|
|
+ message.success('创建成功')
|
|
|
+ ailabtableForm.resetFields()
|
|
|
+ setIsCreateTable(false)
|
|
|
+ } else {
|
|
|
+ message.error(data.msg)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch(err => {
|
|
|
+ message.error('请检查表单数据是否完整')
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ const formItemLayout = {
|
|
|
+ labelCol: {
|
|
|
+ xs: { span: 24 },
|
|
|
+ sm: { span: 6 },
|
|
|
+ },
|
|
|
+ wrapperCol: {
|
|
|
+ xs: { span: 24 },
|
|
|
+ sm: { span: 18 },
|
|
|
+ },
|
|
|
+ }
|
|
|
+ const formItemLayoutWithOutLabel = {
|
|
|
+ wrapperCol: {
|
|
|
+ xs: { span: 24, offset: 0 },
|
|
|
+ sm: { span: 18, offset: 6 },
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ const createTableModal = (
|
|
|
+ <Modal
|
|
|
+ title="创建数据表"
|
|
|
+ visible={isCreateTable}
|
|
|
+ onOk={createAilabTable}
|
|
|
+ okText="确认创建"
|
|
|
+ onCancel={() => {
|
|
|
+ ailabtableForm.resetFields()
|
|
|
+ setIsCreateTable(false)
|
|
|
+ }}>
|
|
|
+ <Form form={ailabtableForm} {...formItemLayout}>
|
|
|
+ <FormItem
|
|
|
+ name="table_name"
|
|
|
+ label="数据表名称"
|
|
|
+ rules={[
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: '请输入数据表名称!',
|
|
|
+ },
|
|
|
+ ]}>
|
|
|
+ <Input placeholder="输入数据表名称" />
|
|
|
+ </FormItem>
|
|
|
+ <FormList
|
|
|
+ name="database_field"
|
|
|
+ rules={[
|
|
|
+ {
|
|
|
+ validator: async (_, database_field) => {
|
|
|
+ if (!database_field || database_field.length < 1) {
|
|
|
+ return Promise.reject(new Error('最少存在一个字段'))
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ]}>
|
|
|
+ {(fields, { add, remove }, { errors }) => (
|
|
|
+ <div style={{ maxHeight: '400px', overflow: 'auto' }}>
|
|
|
+ {fields.map((field, index) => (
|
|
|
+ <Form.Item
|
|
|
+ {...(index === 0
|
|
|
+ ? formItemLayout
|
|
|
+ : formItemLayoutWithOutLabel)}
|
|
|
+ label={index === 0 ? '表字段设置' : ''}
|
|
|
+ required={true}
|
|
|
+ key={field.key}>
|
|
|
+ <Space>
|
|
|
+ <Form.Item
|
|
|
+ {...field}
|
|
|
+ key={`filed_${field.key}`}
|
|
|
+ name={[field.name, 'column_name']}
|
|
|
+ validateTrigger={['onChange', 'onBlur']}
|
|
|
+ rules={[
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ whitespace: true,
|
|
|
+ message: '请输入表字段',
|
|
|
+ },
|
|
|
+ ]}
|
|
|
+ noStyle>
|
|
|
+ <Input placeholder="输入表字段" />
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item
|
|
|
+ {...field}
|
|
|
+ key={`type_${field.key}`}
|
|
|
+ name={[field.name, 'Column_type']}
|
|
|
+ validateTrigger={['onChange', 'onBlur']}
|
|
|
+ rules={[
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ whitespace: true,
|
|
|
+ message: '请选择表类型',
|
|
|
+ },
|
|
|
+ ]}
|
|
|
+ noStyle>
|
|
|
+ <Select
|
|
|
+ style={{ minWidth: '100px' }}
|
|
|
+ placeholder="选择表类型"
|
|
|
+ options={[
|
|
|
+ { value: 'tinyint', label: 'tinyint' },
|
|
|
+ { value: 'smallint', label: 'smallint' },
|
|
|
+ { value: 'int', label: 'int' },
|
|
|
+ { value: 'bigint', label: 'bigint' },
|
|
|
+ { value: 'boolean', label: 'boolean' },
|
|
|
+ { value: 'float', label: 'float' },
|
|
|
+ { value: 'double', label: 'double' },
|
|
|
+ { value: 'string', label: 'string' },
|
|
|
+ { value: 'binary', label: 'binary' },
|
|
|
+ { value: 'timestamp', label: 'timestamp' },
|
|
|
+ { value: 'decimal', label: 'decimal' },
|
|
|
+ { value: 'char', label: 'char' },
|
|
|
+ { value: 'varchar', label: 'varchar' },
|
|
|
+ { value: 'date', label: 'date' },
|
|
|
+ ]}
|
|
|
+ />
|
|
|
+ </Form.Item>
|
|
|
+ {fields.length > 1 ? (
|
|
|
+ <MinusCircleOutlined
|
|
|
+ className="dynamic-delete-button"
|
|
|
+ onClick={() => remove(field.name)}
|
|
|
+ />
|
|
|
+ ) : null}
|
|
|
+ </Space>
|
|
|
+ </Form.Item>
|
|
|
+ ))}
|
|
|
+ <Form.Item {...formItemLayoutWithOutLabel}>
|
|
|
+ <Button
|
|
|
+ type="dashed"
|
|
|
+ onClick={() => add()}
|
|
|
+ block
|
|
|
+ icon={<PlusOutlined />}>
|
|
|
+ 继续添加
|
|
|
+ </Button>
|
|
|
+ </Form.Item>
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </FormList>
|
|
|
+ <FormItem name="partition_column" label="分区字段">
|
|
|
+ <Input placeholder="输入分区字段" />
|
|
|
+ </FormItem>
|
|
|
+ </Form>
|
|
|
+ </Modal>
|
|
|
+ )
|
|
|
+
|
|
|
// Tab标签右边按钮
|
|
|
const tabExtraBtn = () => {
|
|
|
switch (currentKey) {
|
|
@@ -103,14 +319,18 @@ export default function DatasourceView() {
|
|
|
<DatasourceAdd updateDataSource={updateDataSource} />
|
|
|
)}
|
|
|
{currentDataType === 'ailab' && (
|
|
|
- <Button type="primary" onClick={() => {}}>
|
|
|
+ <Button
|
|
|
+ type="primary"
|
|
|
+ onClick={() => {
|
|
|
+ setIsCreateTable(true)
|
|
|
+ }}>
|
|
|
创建数据表
|
|
|
</Button>
|
|
|
)}
|
|
|
{currentDataType === 'datalake' && (
|
|
|
<Button
|
|
|
type="primary"
|
|
|
- onclick={() => {
|
|
|
+ onClick={() => {
|
|
|
setImportData(true)
|
|
|
}}>
|
|
|
导入数据表
|
|
@@ -163,6 +383,7 @@ export default function DatasourceView() {
|
|
|
</TabPane>
|
|
|
</Tabs>
|
|
|
{importModal}
|
|
|
+ {createTableModal}
|
|
|
</Datasource>
|
|
|
)
|
|
|
}
|