diff --git a/backend/apps/data_training/api/data_training.py b/backend/apps/data_training/api/data_training.py index e019465a..2b07a8f0 100644 --- a/backend/apps/data_training/api/data_training.py +++ b/backend/apps/data_training/api/data_training.py @@ -17,6 +17,7 @@ from common.core.config import settings from common.core.deps import SessionDep, CurrentUser, Trans from common.utils.data_format import DataFormat +from common.utils.excel import get_excel_column_count router = APIRouter(tags=["DataTraining"], prefix="/system/data-training") @@ -136,6 +137,9 @@ def inner(): for sheet_name in sheet_names: + if get_excel_column_count(save_path, sheet_name) < len(use_cols): + raise Exception(trans("i18n_excel_import.col_num_not_match")) + df = pd.read_excel( save_path, sheet_name=sheet_name, diff --git a/backend/apps/terminology/api/terminology.py b/backend/apps/terminology/api/terminology.py index e437d457..fe2af92c 100644 --- a/backend/apps/terminology/api/terminology.py +++ b/backend/apps/terminology/api/terminology.py @@ -17,6 +17,7 @@ from common.core.config import settings from common.core.deps import SessionDep, CurrentUser, Trans from common.utils.data_format import DataFormat +from common.utils.excel import get_excel_column_count router = APIRouter(tags=["Terminology"], prefix="/system/terminology") @@ -133,6 +134,9 @@ def inner(): for sheet_name in sheet_names: + if get_excel_column_count(save_path, sheet_name) < len(use_cols): + raise Exception(trans("i18n_excel_import.col_num_not_match")) + df = pd.read_excel( save_path, sheet_name=sheet_name, diff --git a/backend/common/utils/excel.py b/backend/common/utils/excel.py new file mode 100644 index 00000000..659428ab --- /dev/null +++ b/backend/common/utils/excel.py @@ -0,0 +1,12 @@ +import pandas as pd + +def get_excel_column_count(file_path, sheet_name): + """获取Excel文件的列数""" + df_temp = pd.read_excel( + file_path, + sheet_name=sheet_name, + engine='calamine', + header=0, + nrows=0 + ) + return len(df_temp.columns) \ No newline at end of file diff --git a/backend/locales/en.json b/backend/locales/en.json index f6402bbc..bf64bb07 100644 --- a/backend/locales/en.json +++ b/backend/locales/en.json @@ -83,5 +83,8 @@ }, "i18n_excel_export": { "data_is_empty": "Form data is empty, unable to export data" + }, + "i18n_excel_import": { + "col_num_not_match": "Number of columns in Excel does not match" } } \ No newline at end of file diff --git a/backend/locales/ko-KR.json b/backend/locales/ko-KR.json index 3c7621c8..ca72a448 100644 --- a/backend/locales/ko-KR.json +++ b/backend/locales/ko-KR.json @@ -83,5 +83,8 @@ }, "i18n_excel_export": { "data_is_empty": "폼 데이터가 비어 있어 데이터를 내보낼 수 없습니다" + }, + "i18n_excel_import": { + "col_num_not_match": "Excel 열 개수가 일치하지 않습니다" } } \ No newline at end of file diff --git a/backend/locales/zh-CN.json b/backend/locales/zh-CN.json index de454ba8..242253a8 100644 --- a/backend/locales/zh-CN.json +++ b/backend/locales/zh-CN.json @@ -83,5 +83,8 @@ }, "i18n_excel_export": { "data_is_empty": "表单数据为空,无法导出数据" + }, + "i18n_excel_import": { + "col_num_not_match": "EXCEL列数量不匹配" } } \ No newline at end of file diff --git a/frontend/src/views/system/professional/index.vue b/frontend/src/views/system/professional/index.vue index d898006b..9658a4eb 100644 --- a/frontend/src/views/system/professional/index.vue +++ b/frontend/src/views/system/professional/index.vue @@ -11,7 +11,7 @@ import IconOpeDelete from '@/assets/svg/icon_delete.svg' import icon_searchOutline_outlined from '@/assets/svg/icon_search-outline_outlined.svg' import EmptyBackground from '@/views/dashboard/common/EmptyBackground.vue' import { useI18n } from 'vue-i18n' -import { cloneDeep } from 'lodash-es' +import { cloneDeep, endsWith, startsWith } from 'lodash-es' import { genFileId, type UploadInstance, type UploadProps, type UploadRawFile } from 'element-plus' import { useCache } from '@/utils/useCache.ts' import { settingsApi } from '@/api/setting.ts' @@ -164,9 +164,18 @@ const onSuccess = (response: any) => { } } -const onError = () => { +const onError = (err: Error) => { uploadLoading.value = false uploadRef.value!.clearFiles() + let msg = err.message + if (startsWith(msg, '"') && endsWith(msg, '"')) { + msg = msg.slice(1, msg.length - 1) + } + ElMessage({ + message: msg, + type: 'error', + showClose: true, + }) } const exportExcel = () => { diff --git a/frontend/src/views/system/prompt/index.vue b/frontend/src/views/system/prompt/index.vue index 2ecec06b..c3cb6f2b 100644 --- a/frontend/src/views/system/prompt/index.vue +++ b/frontend/src/views/system/prompt/index.vue @@ -13,7 +13,7 @@ import icon_searchOutline_outlined from '@/assets/svg/icon_search-outline_outlin import EmptyBackground from '@/views/dashboard/common/EmptyBackground.vue' import { useClipboard } from '@vueuse/core' import { useI18n } from 'vue-i18n' -import { cloneDeep } from 'lodash-es' +import { cloneDeep, endsWith, startsWith } from 'lodash-es' import { genFileId, type UploadInstance, type UploadProps, type UploadRawFile } from 'element-plus' import { settingsApi } from '@/api/setting.ts' import { useCache } from '@/utils/useCache.ts' @@ -167,9 +167,18 @@ const onSuccess = (response: any) => { } } -const onError = () => { +const onError = (err: Error) => { uploadLoading.value = false uploadRef.value!.clearFiles() + let msg = err.message + if (startsWith(msg, '"') && endsWith(msg, '"')) { + msg = msg.slice(1, msg.length - 1) + } + ElMessage({ + message: msg, + type: 'error', + showClose: true, + }) } const exportExcel = () => { diff --git a/frontend/src/views/system/training/index.vue b/frontend/src/views/system/training/index.vue index 2c9f2a84..0e771505 100644 --- a/frontend/src/views/system/training/index.vue +++ b/frontend/src/views/system/training/index.vue @@ -15,7 +15,7 @@ import EmptyBackground from '@/views/dashboard/common/EmptyBackground.vue' import { useClipboard } from '@vueuse/core' import { useUserStore } from '@/stores/user' import { useI18n } from 'vue-i18n' -import { cloneDeep } from 'lodash-es' +import { cloneDeep, endsWith, startsWith } from 'lodash-es' import { getAdvancedApplicationList } from '@/api/embedded.ts' import { genFileId } from 'element-plus' @@ -172,9 +172,18 @@ const onSuccess = (response: any) => { } } -const onError = () => { +const onError = (err: Error) => { uploadLoading.value = false uploadRef.value!.clearFiles() + let msg = err.message + if (startsWith(msg, '"') && endsWith(msg, '"')) { + msg = msg.slice(1, msg.length - 1) + } + ElMessage({ + message: msg, + type: 'error', + showClose: true, + }) } const exportExcel = () => {