Skip to content

Commit f75770f

Browse files
committed
feat(Data Source): SQLBot supports custom data types in data sources #768
1 parent 7f543cf commit f75770f

File tree

10 files changed

+613
-78
lines changed

10 files changed

+613
-78
lines changed

frontend/src/api/datasource.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export const datasourceApi = {
66
relationGet: (id: any) => request.post(`/table_relation/get/${id}`),
77
relationSave: (dsId: any, data: any) => request.post(`/table_relation/save/${dsId}`, data),
88
add: (data: any) => request.post('/datasource/add', data),
9+
importToDb: (data: any) => request.post('/datasource/importToDb', data),
910
list: () => request.get('/datasource/list'),
1011
update: (data: any) => request.post('/datasource/update', data),
1112
delete: (id: number, name: string) => request.post(`/datasource/delete/${id}/${name}`),
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 2 additions & 2 deletions
Loading

frontend/src/i18n/en.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@
3333
"enter_variable_value": "Please Enter Variable Value"
3434
},
3535
"sync": {
36+
"records":"Displaying {num} records out of {total}",
37+
"confirm_upload":"Confirm Upload",
38+
"field_details":"Field Details",
3639
"integration": "Platform integration needs to be enabled.",
3740
"the_existing_user": "If the user already exists, overwrite the existing user.",
3841
"sync_users": "Sync Users",
@@ -442,6 +445,9 @@
442445
"get_schema": "Get Schema"
443446
},
444447
"model": {
448+
"int": "Integer",
449+
"float": "Float",
450+
"string": "String",
445451
"default_model": "Default model",
446452
"model_type": "Model type",
447453
"basic_model": "Basic model",

frontend/src/i18n/ko-KR.json

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,6 @@
77
"AI Model Configuration": "모델 구성",
88
"Details": "세부"
99
},
10-
"sync": {
11-
"integration": "플랫폼 통합을 활성화해야 합니다.",
12-
"the_existing_user": "해당 사용자가 이미 존재하는 경우 기존 사용자를 덮어씁니다.",
13-
"sync_users": "사용자 동기화",
14-
"sync_wechat_users": "위챗 사용자 동기화",
15-
"sync_dingtalk_users": "딩톡 사용자 동기화",
16-
"sync_lark_users": "라크 사용자 동기화",
17-
"sync_complete": "동기화 완료",
18-
"synced_10_users": "{num}명 동기화 성공",
19-
"failed_3_users": "{failed}명 동기화 성공, {success}명 동기화 실패",
20-
"download_failure_list": "실패 목록 다운로드",
21-
"sync_failed": "동기화 실패",
22-
"failed_10_users": "{failed}명 동기화 실패",
23-
"continue_syncing": "동기화 계속",
24-
"return_to_view": "화면으로 돌아가기"
25-
},
2610
"variables": {
2711
"please_select_date": "날짜를 선택하십시오",
2812
"number_variable_error": "올바른 숫자 범위를 입력하십시오.",
@@ -48,6 +32,25 @@
4832
"enter_variable_name": "변수 이름을 입력하세요",
4933
"enter_variable_value": "변수 값을 입력하세요"
5034
},
35+
"sync": {
36+
"records": "{total}개 중 {num}개의 레코드 표시",
37+
"confirm_upload": "업로드 확인",
38+
"field_details": "필드 세부 정보",
39+
"integration": "플랫폼 통합을 활성화해야 합니다.",
40+
"the_existing_user": "해당 사용자가 이미 존재하는 경우 기존 사용자를 덮어씁니다.",
41+
"sync_users": "사용자 동기화",
42+
"sync_wechat_users": "위챗 사용자 동기화",
43+
"sync_dingtalk_users": "딩톡 사용자 동기화",
44+
"sync_lark_users": "라크 사용자 동기화",
45+
"sync_complete": "동기화 완료",
46+
"synced_10_users": "{num}명 동기화 성공",
47+
"failed_3_users": "{failed}명 동기화 성공, {success}명 동기화 실패",
48+
"download_failure_list": "실패 목록 다운로드",
49+
"sync_failed": "동기화 실패",
50+
"failed_10_users": "{failed}명 동기화 실패",
51+
"continue_syncing": "동기화 계속",
52+
"return_to_view": "화면으로 돌아가기"
53+
},
5154
"parameter": {
5255
"execution_details": "실행 세부 정보",
5356
"overview": "개요",
@@ -442,6 +445,9 @@
442445
"get_schema": "스키마 가져오기"
443446
},
444447
"model": {
448+
"int": "정수",
449+
"float": "소수",
450+
"string": "문자열",
445451
"default_model": "기본 모델",
446452
"model_type": "모델 유형",
447453
"basic_model": "기본 모델",
@@ -948,4 +954,4 @@
948954
"to_doc": "API 보기",
949955
"trigger_limit": "최대 {0}개의 API 키 생성 지원"
950956
}
951-
}
957+
}

frontend/src/i18n/zh-CN.json

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,6 @@
77
"AI Model Configuration": "模型配置",
88
"Details": "详情"
99
},
10-
"sync": {
11-
"integration": "需开启平台对接",
12-
"the_existing_user": "若用户已存在,覆盖旧用户",
13-
"sync_users": "同步用户",
14-
"sync_wechat_users": "同步企业微信用户",
15-
"sync_dingtalk_users": "同步钉钉用户",
16-
"sync_lark_users": "同步飞书用户",
17-
"sync_complete": "同步完成",
18-
"synced_10_users": "成功同步 {num} 个用户",
19-
"failed_3_users": "成功同步 {success} 个用户,同步失败 {failed} 个用户,",
20-
"download_failure_list": "下载失败列表",
21-
"sync_failed": "同步失败",
22-
"failed_10_users": "同步失败 {num} 个用户,",
23-
"continue_syncing": "继续同步",
24-
"return_to_view": "返回查看"
25-
},
2610
"variables": {
2711
"please_select_date": "请选择日期",
2812
"number_variable_error": "请输入正确的数值范围",
@@ -48,6 +32,25 @@
4832
"enter_variable_name": "请输入变量名称",
4933
"enter_variable_value": "请输入变量值"
5034
},
35+
"sync": {
36+
"records":"显示 {num} 条数据,共 {total} 条",
37+
"confirm_upload":"确定上传",
38+
"field_details":"字段详情",
39+
"integration": "需开启平台对接",
40+
"the_existing_user": "若用户已存在,覆盖旧用户",
41+
"sync_users": "同步用户",
42+
"sync_wechat_users": "同步企业微信用户",
43+
"sync_dingtalk_users": "同步钉钉用户",
44+
"sync_lark_users": "同步飞书用户",
45+
"sync_complete": "同步完成",
46+
"synced_10_users": "成功同步 {num} 个用户",
47+
"failed_3_users": "成功同步 {success} 个用户,同步失败 {failed} 个用户,",
48+
"download_failure_list": "下载失败列表",
49+
"sync_failed": "同步失败",
50+
"failed_10_users": "同步失败 {num} 个用户,",
51+
"continue_syncing": "继续同步",
52+
"return_to_view": "返回查看"
53+
},
5154
"parameter": {
5255
"execution_details": "执行详情",
5356
"overview": "概览",
@@ -442,6 +445,9 @@
442445
"get_schema": "获取Schema"
443446
},
444447
"model": {
448+
"int": "整数",
449+
"float": "小数",
450+
"string": "字符串",
445451
"default_model": "默认模型",
446452
"model_type": "模型类型",
447453
"basic_model": "基础模型",

frontend/src/style.less

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -420,10 +420,13 @@ strong {
420420
}
421421
}
422422

423-
.text-variables.text-variables {
423+
.text-variables.text-variables,
424+
.string-variables.string-variables {
424425
color: #3370ff;
425426
}
426-
.number-variables.number-variables {
427+
.number-variables.number-variables,
428+
.int-variables.int-variables,
429+
.float-variables.float-variables {
427430
color: #04b49c;
428431
}
429432
.datetime-variables.datetime-variables {

frontend/src/views/ds/DatasourceForm.vue

Lines changed: 59 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import EmptyBackground from '@/views/dashboard/common/EmptyBackground.vue'
1717
import icon_fileExcel_colorful from '@/assets/datasource/icon_excel.png'
1818
import IconOpeDelete from '@/assets/svg/icon_delete.svg'
1919
import { useCache } from '@/utils/useCache'
20+
import ExcelDetailDialog from './ExcelDetailDialog.vue'
21+
import icon_visible_outlined from '@/assets/embedded/icon_visible_outlined.svg'
2022
2123
const props = withDefaults(
2224
defineProps<{
@@ -34,6 +36,7 @@ const props = withDefaults(
3436
)
3537
3638
const dsFormRef = ref<FormInstance>()
39+
const excelDetailDialogRef = ref<InstanceType<typeof ExcelDetailDialog>>()
3740
const emit = defineEmits(['refresh', 'changeActiveStep', 'close'])
3841
const isCreate = ref(true)
3942
const isEditTable = ref(false)
@@ -44,7 +47,7 @@ const tableListLoading = ref(false)
4447
const tableListLoadingV1 = ref(false)
4548
const checkLoading = ref(false)
4649
const dialogTitle = ref('')
47-
const getUploadURL = import.meta.env.VITE_API_BASE_URL + '/datasource/uploadExcel'
50+
const getUploadURL = import.meta.env.VITE_API_BASE_URL + '/datasource/parseExcel'
4851
const saveLoading = ref<boolean>(false)
4952
const uploadLoading = ref(false)
5053
const { t } = useI18n()
@@ -54,7 +57,7 @@ const rules = reactive<FormRules>({
5457
name: [
5558
{
5659
required: true,
57-
message: t('datasource.please_enter') + t('common.empty') + t('ds.form.name'),
60+
message: t('datasource.please_enter') + t('common.empty') + t('ds.name'),
5861
trigger: 'blur',
5962
},
6063
{ min: 1, max: 50, message: t('ds.form.validate.name_length'), trigger: 'blur' },
@@ -166,9 +169,7 @@ const initForm = (item: any, editTable: boolean = false) => {
166169
? configuration.lowVersion
167170
: true
168171
form.value.ssl =
169-
configuration.ssl !== null && configuration.ssl !== undefined
170-
? configuration.ssl
171-
: false
172+
configuration.ssl !== null && configuration.ssl !== undefined ? configuration.ssl : false
172173
}
173174
174175
if (editTable) {
@@ -431,15 +432,26 @@ const beforeUpload = (rawFile: any) => {
431432
uploadLoading.value = true
432433
return true
433434
}
434-
435+
let fileDetail: any = null
435436
const onSuccess = (response: any) => {
436-
form.value.filename = response.data.filename
437-
form.value.sheets = response.data.sheets
438-
tableList.value = response.data.sheets
437+
fileDetail = response.data
438+
excelDetailDialogRef.value?.init(response.data)
439439
excelUploadSuccess.value = true
440440
uploadLoading.value = false
441441
}
442442
443+
const openFile = () => {
444+
onSuccess({
445+
data: fileDetail,
446+
})
447+
}
448+
449+
const saveExcel = (excel: any) => {
450+
form.value.filename = excel.filename
451+
form.value.sheets = excel.sheets
452+
tableList.value = excel.sheets
453+
}
454+
443455
const onError = (e: any) => {
444456
ElMessage.error(e.toString())
445457
uploadLoading.value = false
@@ -552,6 +564,26 @@ defineExpose({
552564
:rules="rules"
553565
@submit.prevent
554566
>
567+
<el-form-item :label="t('ds.name')" prop="name">
568+
<el-input
569+
v-model="form.name"
570+
clearable
571+
:placeholder="$t('datasource.please_enter') + $t('common.empty') + t('ds.name')"
572+
/>
573+
</el-form-item>
574+
<el-form-item :label="t('ds.form.description')">
575+
<el-input
576+
v-model="form.description"
577+
:placeholder="
578+
$t('datasource.please_enter') + $t('common.empty') + t('ds.form.description')
579+
"
580+
:rows="2"
581+
show-word-limit
582+
maxlength="200"
583+
clearable
584+
type="textarea"
585+
/>
586+
</el-form-item>
555587
<div v-if="form.type === 'excel'">
556588
<el-form-item prop="sheets" :label="t('ds.form.file')">
557589
<div v-if="form.filename" class="pdf-card">
@@ -560,9 +592,22 @@ defineExpose({
560592
<div class="name">{{ form.filename }}</div>
561593
<div class="size">{{ form.filename.split('.')[1] }} - {{ fileSize }}</div>
562594
</div>
563-
<el-icon v-if="!form.id" class="action-btn" size="16" @click="clearFile">
564-
<IconOpeDelete></IconOpeDelete>
565-
</el-icon>
595+
<div
596+
style="
597+
width: 40px;
598+
margin-left: auto;
599+
display: flex;
600+
align-items: center;
601+
justify-content: space-between;
602+
"
603+
>
604+
<el-icon v-if="!form.id" class="action-btn" size="16" @click="openFile">
605+
<icon_visible_outlined></icon_visible_outlined>
606+
</el-icon>
607+
<el-icon v-if="!form.id" class="action-btn" size="16" @click="clearFile">
608+
<IconOpeDelete></IconOpeDelete>
609+
</el-icon>
610+
</div>
566611
</div>
567612
<el-upload
568613
v-if="form.filename && !form.id"
@@ -602,26 +647,6 @@ defineExpose({
602647
<span v-if="!form.filename" class="not_exceed">{{ $t('common.not_exceed_50mb') }}</span>
603648
</el-form-item>
604649
</div>
605-
<el-form-item :label="t('ds.form.name')" prop="name">
606-
<el-input
607-
v-model="form.name"
608-
clearable
609-
:placeholder="$t('datasource.please_enter') + $t('common.empty') + t('ds.form.name')"
610-
/>
611-
</el-form-item>
612-
<el-form-item :label="t('ds.form.description')">
613-
<el-input
614-
v-model="form.description"
615-
:placeholder="
616-
$t('datasource.please_enter') + $t('common.empty') + t('ds.form.description')
617-
"
618-
:rows="2"
619-
show-word-limit
620-
maxlength="200"
621-
clearable
622-
type="textarea"
623-
/>
624-
</el-form-item>
625650
<div v-if="form.type !== 'excel'" style="margin-top: 16px">
626651
<el-form-item
627652
:label="form.type !== 'es' ? t('ds.form.host') : t('ds.form.address')"
@@ -694,11 +719,7 @@ defineExpose({
694719
>
695720
<el-checkbox v-model="form.lowVersion" :label="t('ds.form.low_version')" />
696721
</el-form-item>
697-
<el-form-item
698-
v-if="form.type === 'mysql'"
699-
:label="t('ds.form.ssl')"
700-
prop="ssl"
701-
>
722+
<el-form-item v-if="form.type === 'mysql'" :label="t('ds.form.ssl')" prop="ssl">
702723
<el-switch v-model="form.ssl" />
703724
</el-form-item>
704725
<el-form-item v-if="form.type !== 'es'" :label="t('ds.form.extra_jdbc')">
@@ -829,6 +850,7 @@ defineExpose({
829850
</el-button>
830851
</div>
831852
</div>
853+
<ExcelDetailDialog ref="excelDetailDialogRef" @finish="saveExcel" />
832854
</template>
833855

834856
<style lang="less" scoped>
@@ -898,10 +920,6 @@ defineExpose({
898920
}
899921
}
900922
901-
.action-btn {
902-
margin-left: auto;
903-
}
904-
905923
.ed-icon {
906924
position: relative;
907925
cursor: pointer;

0 commit comments

Comments
 (0)