mirror of
https://gh-proxy.org/https://github.com/klinsmaya/SQLBot.git
synced 2026-11-11 02:36:54 +08:00
feat: import Sample SQL
This commit is contained in:
@@ -15,4 +15,9 @@ export const trainingApi = {
|
||||
responseType: 'blob',
|
||||
requestOptions: { customError: true },
|
||||
}),
|
||||
downloadError: (path: any) =>
|
||||
request.get(`/system/data-training/download-fail-info/${path}`, {
|
||||
responseType: 'blob',
|
||||
requestOptions: { customError: true },
|
||||
}),
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"sql_statement": "SQL Statement",
|
||||
"edit_training_data": "Edit SQL Sample",
|
||||
"all_236_terms": "Export all {msg} sample SQL records?",
|
||||
"sales_this_year": "Do you want to delete the SQL Sample: {msg}?"
|
||||
"sales_this_year": "Do you want to delete the SQL Sample: {msg}?",
|
||||
"upload_success": "Import Successful",
|
||||
"upload_failed": "Import successful: {success} records. Failed: {fail} records. For details, see: {fail_info}"
|
||||
},
|
||||
"professional": {
|
||||
"cannot_be_repeated": "Term name, synonyms cannot be repeated",
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"sql_statement": "SQL 문",
|
||||
"edit_training_data": "예제 SQL 편집",
|
||||
"all_236_terms": "모든 {msg}개의 예시 SQL 기록을 내보내시겠습니까?",
|
||||
"sales_this_year": "예제 SQL을 삭제하시겠습니까: {msg}?"
|
||||
"sales_this_year": "예제 SQL을 삭제하시겠습니까: {msg}?",
|
||||
"upload_success": "가져오기 성공",
|
||||
"upload_failed": "성공: {success}건, 실패: {fail}건. 자세한 내용은 다음을 참조하세요: {fail_info}"
|
||||
},
|
||||
"professional": {
|
||||
"cannot_be_repeated": "용어 이름과 동의어는 중복될 수 없습니다",
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"sql_statement": "SQL 语句",
|
||||
"edit_training_data": "编辑示例 SQL",
|
||||
"all_236_terms": "是否导出全部 {msg} 条示例 SQL?",
|
||||
"sales_this_year": "是否删除示例 SQL:{msg}?"
|
||||
"sales_this_year": "是否删除示例 SQL:{msg}?",
|
||||
"upload_success": "导入成功",
|
||||
"upload_failed": "导入成功 {success} 条,失败 {fail} 条,失败信息详见:{fail_info}"
|
||||
},
|
||||
"professional": {
|
||||
"cannot_be_repeated": "术语名称,同义词不能重复",
|
||||
|
||||
@@ -16,6 +16,10 @@ import { useUserStore } from '@/stores/user'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import { getAdvancedApplicationList } from '@/api/embedded.ts'
|
||||
import { genFileId } from 'element-plus'
|
||||
|
||||
import type { UploadInstance, UploadProps, UploadRawFile } from 'element-plus'
|
||||
import { useCache } from '@/utils/useCache.ts'
|
||||
|
||||
interface Form {
|
||||
id?: string | null
|
||||
@@ -33,7 +37,7 @@ const keywords = ref('')
|
||||
const oldKeywords = ref('')
|
||||
const searchLoading = ref(false)
|
||||
const { copy } = useClipboard({ legacy: true })
|
||||
|
||||
const { wsCache } = useCache()
|
||||
const options = ref<any[]>([])
|
||||
const adv_options = ref<any[]>([])
|
||||
const selectable = () => {
|
||||
@@ -86,6 +90,94 @@ const cancelDelete = () => {
|
||||
isIndeterminate.value = false
|
||||
}
|
||||
|
||||
const upload = () => {}
|
||||
|
||||
const uploadRef = ref<UploadInstance>()
|
||||
const uploadLoading = ref(false)
|
||||
|
||||
const token = wsCache.get('user.token')
|
||||
const headers = ref<any>({ 'X-SQLBOT-TOKEN': `Bearer ${token}` })
|
||||
const getUploadURL = import.meta.env.VITE_API_BASE_URL + '/system/data-training/uploadExcel'
|
||||
|
||||
const handleExceed: UploadProps['onExceed'] = (files) => {
|
||||
uploadRef.value!.clearFiles()
|
||||
const file = files[0] as UploadRawFile
|
||||
file.uid = genFileId()
|
||||
uploadRef.value!.handleStart(file)
|
||||
}
|
||||
|
||||
const beforeUpload = (rawFile: any) => {
|
||||
if (rawFile.size / 1024 / 1024 > 50) {
|
||||
ElMessage.error(t('common.not_exceed_50mb'))
|
||||
return false
|
||||
}
|
||||
uploadLoading.value = true
|
||||
return true
|
||||
}
|
||||
const onSuccess = (response: any) => {
|
||||
uploadRef.value!.clearFiles()
|
||||
search()
|
||||
|
||||
if (response?.data?.failed_count > 0 && response?.data?.error_excel_filename) {
|
||||
ElMessage.error(
|
||||
t('training.upload_failed', {
|
||||
success: response.data.success_count,
|
||||
fail: response.data.failed_count,
|
||||
fail_info: response.data.error_excel_filename,
|
||||
})
|
||||
)
|
||||
trainingApi
|
||||
.downloadError(response.data.error_excel_filename)
|
||||
.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 = `${t('training.data_training')}_error.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,
|
||||
})
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
uploadLoading.value = false
|
||||
})
|
||||
} else {
|
||||
ElMessage.success(t('training.upload_success'))
|
||||
uploadLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const onError = () => {
|
||||
uploadLoading.value = false
|
||||
uploadRef.value!.clearFiles()
|
||||
}
|
||||
|
||||
const exportExcel = () => {
|
||||
ElMessageBox.confirm(t('training.all_236_terms', { msg: pageInfo.total }), {
|
||||
confirmButtonType: 'primary',
|
||||
@@ -360,13 +452,13 @@ const onRowFormClose = () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-loading="searchLoading" class="training">
|
||||
<div v-loading="searchLoading || uploadLoading" class="training">
|
||||
<div class="tool-left">
|
||||
<span class="page-title">{{ $t('training.data_training') }}</span>
|
||||
<div>
|
||||
<div class="tool-row">
|
||||
<el-input
|
||||
v-model="keywords"
|
||||
style="width: 240px; margin-right: 12px"
|
||||
style="width: 240px"
|
||||
:placeholder="$t('training.search_problem')"
|
||||
clearable
|
||||
@blur="search"
|
||||
@@ -383,12 +475,26 @@ const onRowFormClose = () => {
|
||||
</template>
|
||||
{{ $t('professional.export_all') }}
|
||||
</el-button>
|
||||
<el-button v-if="false" secondary @click="editHandler(null)">
|
||||
<template #icon>
|
||||
<ccmUpload></ccmUpload>
|
||||
</template>
|
||||
{{ $t('user.batch_import') }}
|
||||
</el-button>
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
:multiple="false"
|
||||
accept=".xlsx,.xls"
|
||||
:action="getUploadURL"
|
||||
:before-upload="beforeUpload"
|
||||
:headers="headers"
|
||||
:on-success="onSuccess"
|
||||
:on-error="onError"
|
||||
:show-file-list="false"
|
||||
:limit="1"
|
||||
:on-exceed="handleExceed"
|
||||
>
|
||||
<el-button secondary @click="upload()">
|
||||
<template #icon>
|
||||
<ccmUpload></ccmUpload>
|
||||
</template>
|
||||
{{ $t('user.batch_import') }}
|
||||
</el-button>
|
||||
</el-upload>
|
||||
<el-button type="primary" @click="editHandler(null)">
|
||||
<template #icon>
|
||||
<icon_add_outlined></icon_add_outlined>
|
||||
@@ -688,6 +794,13 @@ const onRowFormClose = () => {
|
||||
}
|
||||
}
|
||||
|
||||
.tool-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
@@ -861,4 +974,10 @@ const onRowFormClose = () => {
|
||||
line-height: 22px;
|
||||
}
|
||||
}
|
||||
.upload-user {
|
||||
height: 32px;
|
||||
.ed-upload {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user