diff --git a/frontend/package.json b/frontend/package.json index c06d20086..50e4dbced 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -18,6 +18,7 @@ "dependencies": { "@antv/g2": "^5.3.3", "@antv/s2": "^2.4.3", + "@antv/x6": "^2.18.1", "@eslint/js": "^9.28.0", "@highlightjs/vue-plugin": "^2.1.0", "@npkg/tinymce-plugins": "^0.0.7", diff --git a/frontend/src/api/datasource.ts b/frontend/src/api/datasource.ts index 3274b3f4b..4a733185f 100644 --- a/frontend/src/api/datasource.ts +++ b/frontend/src/api/datasource.ts @@ -3,6 +3,8 @@ import { request } from '@/utils/request' export const datasourceApi = { check: (data: any) => request.post('/datasource/check', data), check_by_id: (id: any) => request.get(`/datasource/check/${id}`), + relationGet: (id: any) => request.post(`/table_relation/get/${id}`), + relationSave: (dsId: any, data: any) => request.post(`/table_relation/save/${dsId}`, data), add: (data: any) => request.post('/datasource/add', data), list: () => request.get('/datasource/list'), update: (data: any) => request.post('/datasource/update', data), diff --git a/frontend/src/assets/svg/icon_mindnote_outlined.svg b/frontend/src/assets/svg/icon_mindnote_outlined.svg new file mode 100644 index 000000000..d3456f2bd --- /dev/null +++ b/frontend/src/assets/svg/icon_mindnote_outlined.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/frontend/src/i18n/en.json b/frontend/src/i18n/en.json index 7112845b5..5c69a0ba8 100644 --- a/frontend/src/i18n/en.json +++ b/frontend/src/i18n/en.json @@ -7,6 +7,8 @@ "AI Model Configuration": "AI Model Configuration" }, "training": { + "add_it_here": "Drag the table name on the left to add it here", + "table_relationship_management": "Table relationship management", "system_anagement": "System Management", "data_training": "SQL Sample Lib", "problem_description": "Problem Description", @@ -669,4 +671,4 @@ "setting_successfully": "Setting Successfully", "customize_theme_color": "Customize theme color" } -} +} \ No newline at end of file diff --git a/frontend/src/i18n/zh-CN.json b/frontend/src/i18n/zh-CN.json index 3e5375a7f..27ce2e3c5 100644 --- a/frontend/src/i18n/zh-CN.json +++ b/frontend/src/i18n/zh-CN.json @@ -7,6 +7,8 @@ "AI Model Configuration": "模型配置" }, "training": { + "add_it_here": "拖拽左侧表名,添加到这里", + "table_relationship_management": "表关系管理", "system_anagement": "系统管理", "data_training": "SQL 示例库", "problem_description": "问题描述", @@ -669,4 +671,4 @@ "setting_successfully": "设置成功", "customize_theme_color": "自定义主题色" } -} +} \ No newline at end of file diff --git a/frontend/src/views/chat/index.vue b/frontend/src/views/chat/index.vue index 702373bec..e1620f1a2 100644 --- a/frontend/src/views/chat/index.vue +++ b/frontend/src/views/chat/index.vue @@ -514,6 +514,10 @@ const scrollBottom = () => { if (!isTyping.value && !getRecommendQuestionsLoading.value) { clearInterval(scrollTime) } + if (!chatListRef.value) { + clearInterval(scrollTime) + return + } chatListRef.value!.setScrollTop(innerRef.value!.clientHeight) } diff --git a/frontend/src/views/ds/DataTable.vue b/frontend/src/views/ds/DataTable.vue index 320835159..5963f0b76 100644 --- a/frontend/src/views/ds/DataTable.vue +++ b/frontend/src/views/ds/DataTable.vue @@ -8,7 +8,8 @@ import EmptyBackground from '@/views/dashboard/common/EmptyBackground.vue' import edit from '@/assets/svg/icon_edit_outlined.svg' import { useI18n } from 'vue-i18n' import ParamsForm from './ParamsForm.vue' - +import TableRelationship from '@/views/ds/TableRelationship.vue' +import icon_mindnote_outlined from '@/assets/svg/icon_mindnote_outlined.svg' interface Table { name: string host: string @@ -54,6 +55,7 @@ const paramsFormRef = ref() const tableList = ref([] as any[]) const loading = ref(false) const initLoading = ref(false) +const activeRelationship = ref(false) const keywords = ref('') const tableListWithSearch = computed(() => { if (!keywords.value) return tableList.value @@ -66,13 +68,29 @@ const showNum = ref(100) const currentTable = ref({}) const ds = ref({}) const btnSelect = ref('d') - +const isDrag = ref(false) +const tableName = ref([]) const pageInfo = reactive({ currentPage: 1, pageSize: 10, total: 0, }) +const handleRelationship = () => { + activeRelationship.value = !activeRelationship.value + currentTable.value = {} +} +const singleDragStartD = (e: DragEvent, ele: any) => { + isDrag.value = true + e.dataTransfer!.setData('table', JSON.stringify(ele)) +} +const getTableName = (val: any) => { + tableName.value = val +} + +const singleDragEnd = () => { + isDrag.value = false +} const handleSizeChange = (val: number) => { pageInfo.currentPage = 1 pageInfo.pageSize = val @@ -119,6 +137,7 @@ const handleSelectTableList = () => { } const clickTable = (table: any) => { + if (activeRelationship.value) return loading.value = true currentTable.value = table fieldList.value = [] @@ -290,8 +309,14 @@ const btnSelectClick = (val: any) => {
@@ -318,9 +343,32 @@ const btnSelectClick = (val: any) => {
+
+
+ + + + {{ t('training.table_relationship_management') }} +
+
+ + +
+
{{ t('training.table_relationship_management') }}
+
+ +
-
+
{{ currentTable.table_name }}
@@ -336,6 +384,7 @@ const btnSelectClick = (val: any) => {
+
{ padding: 8px 16px; height: 100%; border-right: 1px solid #1f232926; + .table-relationship { + height: 56px; + width: 100%; + display: flex; + align-items: center; + margin-top: 20px; + position: relative; + + &::after { + content: ''; + width: calc(100% + 32px); + position: absolute; + left: -16px; + background-color: #1f232926; + top: 0; + height: 1px; + } + + .btn { + width: 248px; + height: 32px; + cursor: pointer; + border-radius: 6px; + display: flex; + align-items: center; + padding-left: 8px; + .ed-icon { + color: #646a73; + margin-right: 8px; + } + + &.active { + color: var(--ed-color-primary); + .ed-icon { + color: var(--ed-color-primary); + } + background-color: var(--ed-color-primary-1a); + } + } + } .select-table_top { height: 40px; display: flex; @@ -551,7 +640,7 @@ const btnSelectClick = (val: any) => { } .list-content { - height: calc(100% - 100px); + height: calc(100% - 156px); .no-result { margin-top: 72px; font-weight: 400; @@ -569,6 +658,12 @@ const btnSelectClick = (val: any) => { border-radius: 4px; cursor: pointer; + &.disabled-table { + background: #dee0e3 !important; + color: #646a73; + cursor: not-allowed; + } + .name { margin-left: 8px; font-weight: 500; @@ -604,6 +699,27 @@ const btnSelectClick = (val: any) => { } } } + .relationship-content { + position: absolute; + right: 0; + top: 0; + width: calc(100% - 280px); + height: 100%; + + .content { + height: calc(100% - 56px); + width: 100%; + } + + .title { + height: 56px; + padding-left: 24px; + line-height: 56px; + font-weight: 500; + font-size: 16px; + border-bottom: 1px solid #1f232926; + } + } .info-table { position: absolute; right: 0; diff --git a/frontend/src/views/ds/TableRelationship.vue b/frontend/src/views/ds/TableRelationship.vue new file mode 100644 index 000000000..a3a8485d7 --- /dev/null +++ b/frontend/src/views/ds/TableRelationship.vue @@ -0,0 +1,403 @@ + + + + +