Parcourir la source

feat: 数据源管理接口对接

leo il y a 2 ans
Parent
commit
3c2c92c86a

+ 21 - 0
package-lock.json

@@ -3806,6 +3806,27 @@
       "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.3.tgz",
       "integrity": "sha512-32+ub6kkdhhWick/UjvEwRchgoetXqTK14INLqbGm5U2TzBkBNF3nQtLYm8ovxSkQWArjEQvftCKryjZaATu3w=="
     },
+    "axios": {
+      "version": "0.27.2",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
+      "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
+      "requires": {
+        "follow-redirects": "^1.14.9",
+        "form-data": "^4.0.0"
+      },
+      "dependencies": {
+        "form-data": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+          "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+          "requires": {
+            "asynckit": "^0.4.0",
+            "combined-stream": "^1.0.8",
+            "mime-types": "^2.1.12"
+          }
+        }
+      }
+    },
     "axobject-query": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz",

+ 118 - 33
src/module/datasource/component/DatasourceData.jsx

@@ -1,6 +1,8 @@
-import React, { useState } from 'react'
+import React, { useMemo, useState } from 'react'
 import styled from 'styled-components'
-import { Tree, Tabs } from 'antd'
+import { Tree, Tabs, Table } from 'antd'
+import { getTableData, getTableSchema } from '../services'
+
 const { DirectoryTree } = Tree
 const { TabPane } = Tabs
 
@@ -23,36 +25,109 @@ const DatasourceWrapper = styled.div`
   }
 `
 
-const treeData = [
-  {
-    title: 'node1',
-    key: '1',
-    isLeaf: true,
-  },
-  {
-    title: 'node2',
-    key: '2',
-    isLeaf: true,
-  },
-  {
-    title: 'node3',
-    key: '3',
-    isLeaf: true,
-  },
-  {
-    title: 'node4',
-    key: '4',
-    isLeaf: true,
-  },
-]
+const DatasourceData = props => {
+  const { data, datasourceId } = props
+
+  // 表内容表头
+  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 treeData = useMemo(() => {
+    return data.map(item => {
+      return {
+        key: item,
+        title: item,
+        isLeaf: true,
+      }
+    })
+  }, [data])
 
-const DatasourceData = () => {
   const onSelect = selectedKeys => {
-    console.log('selected', selectedKeys)
+    const params = {
+      id: datasourceId,
+      table_name: selectedKeys,
+    }
+    fetchTableData(params)
+    fetchTableSchema(params)
+  }
+
+  const fetchTableData = async params => {
+    setContentLoading(true)
+    const { data } = await getTableData(params)
+    if (data.code) {
+      handleContent(data.data)
+    }
+    setContentLoading(false)
+  }
+
+  const fetchTableSchema = async params => {
+    setSchemaLoading(true)
+    const { data } = await getTableSchema(params)
+    if (data.code) {
+      handleSchema(data.data)
+    }
+    setSchemaLoading(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 onChange = key => {
-    console.log('key', key)
+  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 tree = (
@@ -66,12 +141,22 @@ const DatasourceData = () => {
   return (
     <DatasourceWrapper>
       {tree}
-      <Tabs onChange={onChange} className="datasource__table" size={'small'}>
-        <TabPane tab="预览表内容" key="1">
-          Content of Tab Pane 1
+      <Tabs className="datasource__table" size={'small'}>
+        <TabPane tab="预览表内容" key="content">
+          <Table
+            columns={contentCols}
+            dataSource={contentData}
+            bordered
+            loading={contentLoading}
+          />
         </TabPane>
-        <TabPane tab="预览表结构" key="2">
-          Content of Tab Pane 2
+        <TabPane tab="预览表结构" key="schema">
+          <Table
+            columns={schemaCols}
+            dataSource={schemaData}
+            bordered
+            loading={schemaLoading}
+          />
         </TabPane>
       </Tabs>
     </DatasourceWrapper>

+ 52 - 23
src/module/datasource/component/DatasourceManage.jsx

@@ -1,12 +1,16 @@
 import React, { useState, useEffect, useImperativeHandle } from 'react'
 import { Space, Table, Modal, message } from 'antd'
 import DatasourceData from '../component/DatasourceData'
-import {getDataSourceList, delDataSource} from '../services'
+import {
+  getDataSourceList,
+  delDataSource,
+  getTableNamesList,
+} from '../services'
 import { ExclamationCircleOutlined } from '@ant-design/icons'
 
 const { confirm } = Modal
 
-export default function DatasourceManage({onRef}) {
+export default function DatasourceManage({ onRef }) {
   // 查看数据源弹窗是否可可视
   const [dataModalVisible, setDataModalVisible] = useState(false)
 
@@ -16,6 +20,12 @@ export default function DatasourceManage({onRef}) {
   // 表格Loading状态
   const [dataLoading, setDataLoading] = useState(false)
 
+  // 表名
+  const [tableNames, setTableNames] = useState([])
+
+  // 选中数据源
+  const [datasourceId, setDatasourceId] = useState(null)
+
   // 获取列表数据
   const fetchDataSourceList = async () => {
     setDataLoading(true)
@@ -40,12 +50,12 @@ export default function DatasourceManage({onRef}) {
   // 暴露更新列表方法
   useImperativeHandle(onRef, () => {
     return {
-      updateSourceList: fetchDataSourceList
+      updateSourceList: fetchDataSourceList,
     }
   })
 
   // 删除确认
-  const DeleteConfirm = (key) => {
+  const DeleteConfirm = key => {
     confirm({
       title: '是否要删除该数据源?',
       icon: <ExclamationCircleOutlined />,
@@ -63,14 +73,24 @@ export default function DatasourceManage({onRef}) {
       },
       onCancel() {
         message.info('取消删除')
-      }
+      },
     })
   }
 
+  //获取数据源表名
+  const fetchTableNames = async key => {
+    const { data } = await getTableNamesList(key)
+    if (data.code === 200) {
+      setDatasourceId(key)
+      setTableNames(data.data)
+      setDataModalVisible(true)
+    }
+  }
+
   // componentDidMount
   useEffect(() => {
     fetchDataSourceList()
-  }, []);
+  }, [])
 
   // 格式化事件
   const formatTime = time => {
@@ -88,15 +108,10 @@ export default function DatasourceManage({onRef}) {
       date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
     return YY + '-' + MM + '-' + DD + ' ' + hh + ':' + mm + ':' + ss
   }
-  // 查看数据
-  const checkData = () => {
-    setDataModalVisible(true)
-    console.log('查看数据源')
-  }
-  // 编辑数据
-  const editData = () => {
-    console.log('编辑数据源')
-  }
+  // // 编辑数据
+  // const editData = () => {
+  //   console.log('编辑数据源')
+  // }
   // 表格项
   const columns = [
     {
@@ -137,15 +152,23 @@ export default function DatasourceManage({onRef}) {
       key: 'operation',
       render: (_, record) => (
         <Space size="middle">
-          <a href="/#" onClick={checkData} style={{ color: '#1881DA' }}>
+          <a
+            href="/#"
+            onClick={() => {
+              fetchTableNames(record.key)
+            }}
+            style={{ color: '#1881DA' }}>
             查看
           </a>
-          <a href="/#" onClick={editData} style={{ color: '#1881DA' }}>
+          {/* <a href="/#" onClick={editData} style={{ color: '#1881DA' }}>
             编辑
-          </a>
-          <a href="/#" onClick={() => {
-            DeleteConfirm(record.key)
-          }} style={{ color: '#1881DA' }}>
+          </a> */}
+          <a
+            href="/#"
+            onClick={() => {
+              DeleteConfirm(record.key)
+            }}
+            style={{ color: '#1881DA' }}>
             删除
           </a>
         </Space>
@@ -166,14 +189,20 @@ export default function DatasourceManage({onRef}) {
       footer={null}
       width={800}
       bodyStyle={{ paddingTop: 0 }}>
-      <DatasourceData />
+      <DatasourceData data={tableNames} datasourceId={datasourceId} />
     </Modal>
   )
 
   // 最终渲染
   return (
     <>
-      <Table columns={columns} dataSource={dataSourceList} bordered loading={dataLoading} /> {dataModal}
+      <Table
+        columns={columns}
+        dataSource={dataSourceList}
+        bordered
+        loading={dataLoading}
+      />
+      {dataModal}
     </>
   )
 }

+ 21 - 12
src/module/datasource/component/DatasourceSyncView.jsx

@@ -1,5 +1,5 @@
-import { Table, Space, Switch, message } from "antd"
-import { useEffect, useState } from "react"
+import { Table, Space, Switch, message } from 'antd'
+import React, { useEffect, useState } from 'react'
 import { getJobList, updateJobList } from '../services'
 
 export default function DatasourceSyncView() {
@@ -15,7 +15,7 @@ export default function DatasourceSyncView() {
   const [dataLoading, setDataLoading] = useState(false)
 
   // 请求任务列表数据
-  const fetchJobList= async () => {
+  const fetchJobList = async () => {
     setDataLoading(true)
     const { data } = await getJobList()
     if (data.code === 200) {
@@ -37,12 +37,12 @@ export default function DatasourceSyncView() {
   useEffect(() => {
     fetchJobList()
   }, [])
-  
+
   const columns = [
     {
       title: '任务ID',
       dataIndex: 'id',
-      key: 'id'
+      key: 'id',
     },
     {
       title: '任务描述',
@@ -75,28 +75,37 @@ export default function DatasourceSyncView() {
                 executor_param: switch_data.executor_param,
                 executor_block_strategy: switch_data.executor_block_strategy,
                 executor_timeout: switch_data.executor_timeout,
-                executor_fail_retry_count: switch_data.executor_fail_retry_count,
+                executor_fail_retry_count:
+                  switch_data.executor_fail_retry_count,
                 inc_start_time: switch_data.inc_start_time,
                 job_json: switch_data.job_json,
-                trigger_status: switch_data.trigger_status === 1 ? 0 : 1
+                trigger_status: switch_data.trigger_status === 1 ? 0 : 1,
               }
               const { data } = await updateJobList(record.key, request_body)
               if (data.code === 200) {
-                message.success(record.trigger_status === 1 ? '关闭成功' : '开启成功')
+                message.success(
+                  record.trigger_status === 1 ? '关闭成功' : '开启成功'
+                )
                 fetchJobList()
               } else {
-                message.error(record.trigger_status === 1 ? '关闭失败' : '开启失败')
+                message.error(
+                  record.trigger_status === 1 ? '关闭失败' : '开启失败'
+                )
               }
               setSwitchLoading(false)
             }}
           />
         </Space>
-      )
+      ),
     },
   ]
   return (
     <>
-    <Table columns={columns} dataSource={jobList} bordered loading={dataLoading}></Table>
+      <Table
+        columns={columns}
+        dataSource={jobList}
+        bordered
+        loading={dataLoading}></Table>
     </>
   )
-}
+}

+ 22 - 7
src/module/datasource/services/index.js

@@ -1,15 +1,15 @@
 import request from '../../../utils/request'
 
 // 获取数据源列表
-export const getDataSourceList  = params => request({
+export const getDataSourceList = params => request({
   url: `/jpt/datasource/`,
   method: 'get',
   params
 })
 
 // 删除指定数据源
-export const delDataSource  = id => request({
-  url: `/jpt/datasource/`+id,
+export const delDataSource = id => request({
+  url: `/jpt/datasource/` + id,
   method: 'delete',
 })
 
@@ -17,14 +17,14 @@ export const delDataSource  = id => request({
 export const testDataSourceConnection = params => request({
   url: '/jpt/datasource/test',
   method: 'post',
-  data: {...params}
+  data: { ...params }
 })
 
 // 创建数据源
-export const createDataSource  = params => request({
+export const createDataSource = params => request({
   url: `/jpt/datasource/`,
   method: 'post',
-  data: {...params}
+  data: { ...params }
 })
 
 export const getJobList = params => request({
@@ -36,5 +36,20 @@ export const getJobList = params => request({
 export const updateJobList = (id, params) => request({
   url: 'jpt/jobinfo/' + id,
   method: 'put',
-  data: {...params}
+  data: { ...params }
+})
+
+export const getTableNamesList = params => request({
+  url: `/jpt/datasource/table_names?ds_id=${params}`,
+  method: 'post',
+})
+
+export const getTableData = params => request({
+  url: `/jpt/datasource/preview?ds_id=${params.id}&table_name=${params.table_name}`,
+  method: 'post',
+})
+
+export const getTableSchema = params => request({
+  url: `/jpt/datasource/table_schema?ds_id=${params.id}&table_name=${params.table_name}`,
+  method: 'post',
 })