123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674 |
- import React, {
- useState,
- useEffect,
- useImperativeHandle,
- forwardRef,
- } from 'react'
- import {
- Space,
- Table,
- Modal,
- message,
- Popconfirm,
- Button,
- Select,
- Tabs,
- } from 'antd'
- import DatasourceData from '../component/DatasourceData'
- import DatasourceEdit from '../component/DatasourceEdit'
- import {
- getDataSourceList,
- delDataSource,
- getTableNamesList,
- getDataSourceInfo,
- getAilabList,
- getAllShareProject,
- shareAilab,
- getLakeTable,
- ailabTablePreview,
- ailabSchema,
- lakeTablePreview,
- lakeSchema,
- } from '../services'
- const { Option } = Select
- const { TabPane } = Tabs
- const DatasourceManage = ({ dataType }, ref) => {
- // 查看数据源弹窗是否可可视
- const [dataModalVisible, setDataModalVisible] = useState(false)
- const [dataPreviewVisible, setDataPreviewVisible] = useState(false)
- const [dsModalVisible, setDsModalVisible] = useState(false)
- // 初始化数据源列表数据 constructor
- const [dataSourceList, setDataSourceList] = useState([])
- // 初始化ailab列表数据
- const [ailabDataList, setAilabDataList] = useState([])
- const [lakeDataList, setLakeDataList] = useState([])
- // 表格Loading状态
- const [dataLoading, setDataLoading] = useState(false)
- // 表名
- const [tableNames, setTableNames] = useState([])
- // 选中数据源
- const [datasourceId, setDatasourceId] = useState(null)
- // 查看是否可点击
- const [tableWatcher, setTableWatcher] = useState(false)
- const [currentDsId, setCurrentDsId] = useState(null)
- const [currentDsInfo, setCurrentDsInfo] = useState(null)
- const [isShareData, setIsShareData] = useState(false)
- //选择表格项
- const [selectedRowKeys, setSelectedRowKeys] = useState([])
- // 分享的ailab表
- const [selectedAilabTable, setSelectedAilabTable] = useState([])
- const [projectsList, setProjectsList] = useState([])
- const [selectedProjects, setSelectedProjects] = useState([])
- // 表内容表头
- const [contentCols, setContentCols] = useState([])
- // 表内容表数据
- const [contentData, setContentData] = useState([])
- // 表内容表格Loading状态
- const [contentLoading, setContentLoading] = useState(false)
- // 表结构表头
- const [schemaCols, setScheamCols] = useState([])
- // 表结构表数据
- const [schemaData, setScheamData] = useState([])
- // 表结构表格Loading状态
- const [schemaLoading, setSchemaLoading] = useState(false)
- const onSelectChange = newSelectedRowKeys => {
- setSelectedRowKeys(newSelectedRowKeys)
- }
- // 获取列表数据
- const fetchDataSourceList = async () => {
- setDataLoading(true)
- const { data } = await getDataSourceList()
- if (data.code === 200) {
- const list = data.data.items.map(item => {
- return {
- key: item.id,
- datasource_name: item.datasource_name,
- datasource: item.datasource,
- tag: item.tag,
- comments: item.comments,
- create_time: item.create_time,
- update_time: item.update_time,
- }
- })
- setDataSourceList(list)
- } else {
- message.error(data.msg)
- }
- setDataLoading(false)
- }
- const fetchAilabList = async () => {
- setDataLoading(true)
- const { data } = await getAilabList()
- if (data.code === 200) {
- const list = data.data.map(item => {
- return {
- key: item,
- datatable_name: item,
- }
- })
- setAilabDataList(list)
- } else {
- message.error(data.msg)
- }
- setDataLoading(false)
- }
- const fetchLakeList = async () => {
- setDataLoading(true)
- const { data } = await getLakeTable()
- if (data.code === 200) {
- const list = data.data.map(item => {
- return {
- key: item.id,
- database_name: item.database_name,
- datatable_name: item.table_name,
- }
- })
- setLakeDataList(list)
- } else {
- message.error(data.msg)
- }
- setDataLoading(false)
- }
- // 暴露更新列表方法
- useImperativeHandle(ref, () => {
- return {
- updateSourceList: fetchDataSourceList,
- updateAilabList: fetchAilabList,
- updateLakeList: fetchLakeList,
- }
- })
- // 删除确认
- const DeleteConfirm = async key => {
- const { data } = await delDataSource(key)
- if (data.code === 200) {
- message.success('删除成功')
- fetchDataSourceList()
- } else {
- message.success('删除失败')
- }
- }
- //获取数据源表名
- const fetchTableNames = async key => {
- setTableWatcher(true)
- const { data } = await getTableNamesList(key)
- if (data.code === 200) {
- setDatasourceId(key)
- setTableNames(data.data)
- setDataModalVisible(true)
- } else {
- message.error(data.msg)
- }
- setTableWatcher(false)
- }
- const handleContent = contentData => {
- const colsList = contentData?.header?.map(item => {
- return {
- title: item,
- dataIndex: item,
- key: item,
- }
- })
- const dataList = contentData?.content?.map((item, index) => {
- const row = {}
- row['key'] = index + 1
- item.forEach((val, index) => {
- const title = contentData.header[index]
- row[title] = val
- })
- return row
- })
- setContentCols(colsList)
- setContentData(dataList)
- }
- const handleSchema = schemaData => {
- const colsList = [
- {
- title: '序号',
- dataIndex: 'order',
- key: 'order',
- },
- {
- title: '字段',
- dataIndex: 'field',
- key: 'field',
- },
- {
- title: '属性',
- dataIndex: 'attribute',
- key: 'attribute',
- },
- ]
- const dataList = schemaData?.map((item, index) => {
- const row = {}
- row['key'] = index + 1
- const [order, field, attribute] = item.split(':')
- row['order'] = order
- row['field'] = field
- row['attribute'] = attribute
- return row
- })
- setScheamCols(colsList)
- setScheamData(dataList)
- }
- const fetchAilabDataPreview = async (key, type) => {
- setContentLoading(true)
- const { data } =
- type === 'ailab'
- ? await ailabTablePreview(key)
- : await lakeTablePreview(key)
- if (data.code === 200) {
- handleContent(data.data)
- } else {
- message.error(data.msg)
- }
- setContentLoading(false)
- }
- const fetchAilabSchema = async (key, type) => {
- setSchemaLoading(true)
- const { data } =
- type === 'ailab' ? await ailabSchema(key) : await lakeSchema(key)
- if (data.code === 200) {
- handleSchema(data.data)
- } else {
- message.error(data.msg)
- }
- setSchemaLoading(false)
- }
- const watchAilabData = async table_name => {
- fetchAilabDataPreview(table_name, 'ailab')
- fetchAilabSchema(table_name, 'ailab')
- setDataPreviewVisible(true)
- }
- const watchLakeData = async table_name => {
- fetchAilabDataPreview(table_name, 'lake')
- fetchAilabSchema(table_name, 'lake')
- setDataPreviewVisible(true)
- }
- useEffect(() => {
- if (sessionStorage.getItem('project_id')) {
- switch (dataType) {
- case 'datasource':
- fetchDataSourceList()
- break
- case 'ailab':
- fetchAilabList()
- break
- case 'datalake':
- fetchLakeList()
- break
- default:
- break
- }
- }
- }, [dataType, sessionStorage.getItem('project_id')])
- useEffect(() => {
- if (isShareData) {
- fetchProjects()
- }
- }, [isShareData])
- const fetchProjects = async () => {
- const { data } = await getAllShareProject()
- if (data.code === 200) {
- const list = data.data.map(item => {
- return {
- label: item.name,
- value: item.id,
- }
- })
- setProjectsList(list)
- } else {
- message.error(data.msg)
- }
- }
- // 格式化事件
- const formatTime = time => {
- const date = new Date(Number(time) * 1000)
- const YY = date.getFullYear()
- const MM =
- date.getMonth() + 1 < 10
- ? '0' + (date.getMonth() + 1)
- : date.getMonth() + 1
- const DD = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
- const hh = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
- const mm =
- date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
- const ss =
- date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
- return YY + '-' + MM + '-' + DD + ' ' + hh + ':' + mm + ':' + ss
- }
- // 编辑数据
- const editData = async id => {
- const { data } = await getDataSourceInfo(id)
- if (data.code === 200) {
- setCurrentDsId(id)
- setCurrentDsInfo(data.data)
- setDsModalVisible(true)
- } else {
- message.error(data.msg)
- }
- }
- // 数据源表格项
- const ds_columns = [
- {
- title: '数据源名称',
- dataIndex: 'datasource_name',
- key: 'datasource_name',
- },
- {
- title: '数据源类型',
- dataIndex: 'datasource',
- key: 'datasource',
- },
- {
- title: '标签',
- dataIndex: 'tag',
- key: 'tag',
- render: text => <span style={{ color: '#1890ff' }}>{text}</span>,
- },
- {
- title: '详情',
- key: 'comments',
- dataIndex: 'comments',
- },
- {
- title: '创建时间',
- key: 'create_time',
- dataIndex: 'create_time',
- render: time => formatTime(time),
- },
- {
- title: '更新时间',
- key: 'update_time',
- dataIndex: 'update_time',
- render: time => formatTime(time),
- },
- {
- title: '操作',
- key: 'operation',
- render: (_, record) => (
- <Space size="middle">
- <Button
- onClick={() => {
- fetchTableNames(record.key)
- }}
- type="link"
- disabled={tableWatcher}>
- 查看
- </Button>
- {sessionStorage.getItem('role') === '1' && (
- <Button
- type="link"
- onClick={() => {
- editData(record.key)
- }}>
- 编辑
- </Button>
- )}
- {sessionStorage.getItem('role') === '1' && (
- <Popconfirm
- title="确认删除?"
- okText="确认"
- cancelText="取消"
- onConfirm={() => DeleteConfirm(record.key)}>
- <Button type="link">删除</Button>
- </Popconfirm>
- )}
- </Space>
- ),
- },
- ]
- //AIlab表格项
- const ailab_columns = [
- {
- title: '数据表名称',
- dataIndex: 'datatable_name',
- key: 'datatable_name',
- align: 'center',
- },
- {
- title: '操作',
- key: 'operation',
- align: 'center',
- width: '25%',
- render: (_, record) => (
- <Space size="middle">
- {['1', '2', '3'].includes(sessionStorage.getItem('role')) && (
- <Button
- type="link"
- onClick={() => {
- setIsShareData(true)
- setSelectedAilabTable([record.key])
- }}>
- 分享
- </Button>
- )}
- <Button
- onClick={() => {
- watchAilabData(record.key)
- }}
- type="link">
- 查看
- </Button>
- </Space>
- ),
- },
- ]
- const dl_columns = [
- {
- title: '数据库名称',
- dataIndex: 'database_name',
- key: 'database_name',
- align: 'center',
- },
- {
- title: '数据表名称',
- dataIndex: 'datatable_name',
- key: 'datatable_name',
- align: 'center',
- },
- {
- title: '操作',
- key: 'operation',
- align: 'center',
- width: '25%',
- render: (_, record) => (
- <Space size="middle">
- <Button
- onClick={() => {
- watchLakeData(record.datatable_name)
- }}
- type="link">
- 查看
- </Button>
- </Space>
- ),
- },
- ]
- // 查看数据源弹窗取消
- const handledataModalCancel = () => {
- setDataModalVisible(false)
- }
- const handledsModalCancel = () => {
- setDsModalVisible(false)
- }
- const handledataPreviewCancel = () => {
- setDataPreviewVisible(false)
- }
- // 查看数据源弹窗数据
- const dataModal = (
- <Modal
- title="数据表预览"
- visible={dataModalVisible}
- onCancel={handledataModalCancel}
- footer={null}
- destroyOnClose={true}
- width={'80%'}
- bodyStyle={{ paddingTop: 0 }}>
- <DatasourceData data={tableNames} datasourceId={datasourceId} />
- </Modal>
- )
- const dataPreviewModal = (
- <Modal
- title="数据表预览"
- visible={dataPreviewVisible}
- onCancel={handledataPreviewCancel}
- footer={null}
- destroyOnClose={true}
- width={'80%'}
- bodyStyle={{ paddingTop: 0 }}>
- {
- <Tabs size={'small'}>
- <TabPane
- tab="预览表内容"
- key="content"
- style={{ height: '700px', overflow: 'auto' }}>
- <Table
- columns={contentCols}
- dataSource={contentData}
- bordered
- loading={contentLoading}
- />
- </TabPane>
- <TabPane
- tab="预览表结构"
- key="schema"
- style={{ height: '700px', overflow: 'auto' }}>
- <Table
- columns={schemaCols}
- dataSource={schemaData}
- bordered
- loading={schemaLoading}
- />
- </TabPane>
- </Tabs>
- }
- </Modal>
- )
- const dsEditModal = (
- <Modal
- title="编辑数据源"
- visible={dsModalVisible}
- onCancel={handledsModalCancel}
- footer={null}
- destroyOnClose={true}
- width={'60%'}>
- <DatasourceEdit
- ds_id={currentDsId}
- ds_info={currentDsInfo}
- updateDataSource={fetchDataSourceList}
- setDsModalVisible={val => setDsModalVisible(val)}
- />
- </Modal>
- )
- const rowSelection = {
- selectedRowKeys,
- onChange: onSelectChange,
- columnWidth: '100px',
- selections: [
- Table.SELECTION_ALL,
- Table.SELECTION_INVERT,
- Table.SELECTION_NONE,
- ],
- }
- const shareBtn = () => (
- <Button
- type="link"
- disabled={!selectedRowKeys.length}
- onClick={() => {
- setSelectedAilabTable(selectedRowKeys)
- setIsShareData(true)
- }}>
- 批量分享
- </Button>
- )
- const shareTable = async () => {
- if (selectedProjects.length) {
- const parmas = {
- table_names: selectedAilabTable,
- project_ids: selectedProjects,
- }
- const { data } = await shareAilab(parmas)
- if (data.code === 200) {
- message.success('分享成功')
- setIsShareData(false)
- setSelectedProjects([])
- } else {
- message.error(data.msg)
- }
- } else {
- message.error('请选择项目')
- }
- }
- const shareMadal = (
- <Modal
- title="分享数据表"
- visible={isShareData}
- onOk={shareTable}
- okText="确认分享"
- onCancel={() => {
- setIsShareData(false)
- setSelectedProjects([])
- }}>
- <Space style={{ padding: '10px 20px 30px' }}>
- <span>选择分享至:</span>
- <Select
- mode="multiple"
- value={selectedProjects}
- onChange={val => setSelectedProjects(val)}
- style={{ width: '300px' }}
- showArrow
- showSearch
- optionFilterProp="label"
- placeholder="请选择项目">
- {projectsList.map(item => {
- return (
- <Option key={item.value} value={item.value} label={item.label}>
- {item.label}
- </Option>
- )
- })}
- </Select>
- </Space>
- </Modal>
- )
- // 最终渲染
- return (
- <div>
- {dataType === 'datasource' && (
- <Table
- columns={ds_columns}
- dataSource={dataSourceList}
- bordered
- loading={dataLoading}
- />
- )}
- {dataType === 'ailab' && (
- <Table
- rowSelection={rowSelection}
- columns={ailab_columns}
- dataSource={ailabDataList}
- bordered
- loading={dataLoading}
- footer={
- ['1', '2', '3'].includes(sessionStorage.getItem('role'))
- ? shareBtn
- : null
- }
- />
- )}
- {dataType === 'datalake' && (
- <Table
- columns={dl_columns}
- dataSource={lakeDataList}
- bordered
- loading={dataLoading}
- />
- )}
- {dataModal}
- {dataPreviewModal}
- {dsEditModal}
- {shareMadal}
- </div>
- )
- }
- export default forwardRef(DatasourceManage)
|