diff --git a/frontend/src/api/datasource.ts b/frontend/src/api/datasource.ts
index 5a66e985b..c349c85e8 100644
--- a/frontend/src/api/datasource.ts
+++ b/frontend/src/api/datasource.ts
@@ -27,4 +27,9 @@ export const datasourceApi = {
cancelRequests: () => request.cancelRequests(),
getSchema: (data: any) => request.post('/datasource/getSchemaByConf', data),
syncFields: (id: number) => request.post(`/datasource/syncFields/${id}`),
+ exportDsSchema: (id: any) =>
+ request.get(`/datasource/exportDsSchema/${id}`, {
+ responseType: 'blob',
+ requestOptions: { customError: true },
+ }),
}
diff --git a/frontend/src/assets/svg/icon_import_outlined.svg b/frontend/src/assets/svg/icon_import_outlined.svg
new file mode 100644
index 000000000..52e5c2645
--- /dev/null
+++ b/frontend/src/assets/svg/icon_import_outlined.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/src/i18n/en.json b/frontend/src/i18n/en.json
index dca1f8359..c0f7bd7b1 100644
--- a/frontend/src/i18n/en.json
+++ b/frontend/src/i18n/en.json
@@ -8,6 +8,7 @@
"Details": "Details"
},
"parameter": {
+ "memo": "Memo update rules: Match table name and field name. If a match is found, update the table memo and field memo; otherwise, leave the memo unchanged.",
"parameter_configuration": "Parameter Config",
"question_count_settings": "Question Count Settings",
"model_thinking_process": "Expand Model Thinking Process",
diff --git a/frontend/src/i18n/ko-KR.json b/frontend/src/i18n/ko-KR.json
index e77a7fe0c..0132d6456 100644
--- a/frontend/src/i18n/ko-KR.json
+++ b/frontend/src/i18n/ko-KR.json
@@ -8,6 +8,7 @@
"Details": "세부"
},
"parameter": {
+ "memo": "메모 업데이트 규칙: 테이블 이름과 필드 이름이 일치하는지 확인합니다. 일치하는 항목이 있으면 테이블 메모와 필드 메모를 업데이트하고, 그렇지 않으면 메모를 변경하지 않고 그대로 둡니다.",
"parameter_configuration": "매개변수 구성",
"question_count_settings": "질문 수 설정",
"model_thinking_process": "모델 사고 프로세스 확장",
@@ -819,4 +820,4 @@
"modelType": {
"llm": "대형 언어 모델"
}
-}
+}
\ No newline at end of file
diff --git a/frontend/src/i18n/zh-CN.json b/frontend/src/i18n/zh-CN.json
index 2ec825a75..47826a2bc 100644
--- a/frontend/src/i18n/zh-CN.json
+++ b/frontend/src/i18n/zh-CN.json
@@ -8,6 +8,7 @@
"Details": "详情"
},
"parameter": {
+ "memo": "备注更新规则:根据表名和字段名匹配,如果匹配则更新表备注和字段备注;如果匹配不上,备注保持不变。",
"parameter_configuration": "参数配置",
"question_count_settings": "问数设置",
"model_thinking_process": "展开模型思考过程",
@@ -140,7 +141,7 @@
"click_to_select_file": "点击选择文件",
"upload_hint_first": "先",
"upload_hint_download_template": "下载模板",
- "upload_hint_end": ",按要求填写后上传",
+ "upload_hint_end": ",按要求填写后上传。",
"continue_to_upload": "继续导入",
"reset_password": "重置密码",
"password_reset_successful": "重置密码成功",
diff --git a/frontend/src/views/ds/DataTable.vue b/frontend/src/views/ds/DataTable.vue
index 4f43f97df..89aed990a 100644
--- a/frontend/src/views/ds/DataTable.vue
+++ b/frontend/src/views/ds/DataTable.vue
@@ -3,14 +3,17 @@ import { ref, computed, onMounted, reactive } from 'vue'
import { datasourceApi } from '@/api/datasource'
import icon_right_outlined from '@/assets/svg/icon_right_outlined.svg'
import icon_form_outlined from '@/assets/svg/icon_form_outlined.svg'
+import icon_import_outlined from '@/assets/svg/icon_import_outlined.svg'
import icon_searchOutline_outlined from '@/assets/svg/icon_search-outline_outlined.svg'
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 UploaderRemark from '@/views/system/excel-upload/UploaderRemark.vue'
import TableRelationship from '@/views/ds/TableRelationship.vue'
import icon_mindnote_outlined from '@/assets/svg/icon_mindnote_outlined.svg'
import { Refresh } from '@element-plus/icons-vue'
+
interface Table {
name: string
host: string
@@ -106,17 +109,29 @@ const fieldListComputed = computed(() => {
return fieldList.value.slice((currentPage - 1) * pageSize, currentPage * pageSize)
})
-const init = () => {
+const init = (reset = false) => {
initLoading.value = true
datasourceApi.getDs(props.info.id).then((res) => {
ds.value = res
fieldList.value = []
pageInfo.total = 0
pageInfo.currentPage = 1
- datasourceApi.tableList(props.info.id).then((res) => {
- tableList.value = res
- initLoading.value = false
- })
+ datasourceApi
+ .tableList(props.info.id)
+ .then((res) => {
+ tableList.value = res
+
+ if (currentTable.value?.id && reset) {
+ tableList.value.forEach((ele) => {
+ if (ele.id === currentTable.value?.id) {
+ clickTable(ele)
+ }
+ })
+ }
+ })
+ .finally(() => {
+ initLoading.value = false
+ })
})
}
onMounted(() => {
@@ -237,6 +252,47 @@ const syncFields = () => {
})
}
+function downloadTemplate() {
+ datasourceApi
+ .exportDsSchema(props.info.id)
+ .then((res) => {
+ const blob = new Blob([res], {
+ type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+ })
+ const link = document.createElement('a')
+ link.href = URL.createObjectURL(blob)
+ link.download = props.info.name + '.xlsx'
+ document.body.appendChild(link)
+ link.click()
+ document.body.removeChild(link)
+ })
+ .catch(async (error) => {
+ if (error.response) {
+ try {
+ let text = await error.response.data.text()
+ try {
+ text = JSON.parse(text)
+ } finally {
+ ElMessage({
+ message: text,
+ type: 'error',
+ showClose: true,
+ })
+ }
+ } catch (e) {
+ console.error('Error processing error response:', e)
+ }
+ } else {
+ console.error('Other error:', error)
+ ElMessage({
+ message: error,
+ type: 'error',
+ showClose: true,
+ })
+ }
+ })
+}
+
const emits = defineEmits(['back', 'refresh'])
const back = () => {
emits('back')
@@ -298,6 +354,16 @@ const btnSelectClick = (val: any) => {