This commit is contained in:
吴红兵
2026-03-07 01:34:48 +08:00
parent adc511cfdc
commit 94c3473958
1211 changed files with 599405 additions and 322105 deletions

View File

@@ -1,135 +1,134 @@
<!-- excel 导入组件 -->
<template>
<el-dialog :title="prop.title" v-model="state.upload.open" :close-on-click-modal="false" draggable>
<el-upload
ref="uploadRef"
:limit="1"
accept=".xlsx, .xls"
:headers="headers"
:action="baseURL + other.adaptationUrl(url)"
:disabled="state.upload.isUploading"
:on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess"
:on-error="handleFileError"
:auto-upload="false"
drag
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">
{{ $t('excel.operationNotice') }}
<em>{{ $t('excel.clickUpload') }}</em>
</div>
<template #tip>
<div class="el-upload__tip text-center">
<span>{{ $t('excel.fileFormat') }}</span>
<el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline"
@click="downExcelTemp" v-if="tempUrl"
>{{ $t('excel.downloadTemplate') }}
</el-link>
</div>
</template>
</el-upload>
<template #footer>
<el-button type="primary" @click="submitFileForm">{{ $t('common.confirmButtonText') }}</el-button>
<el-button @click="state.upload.open = false">{{ $t('common.cancelButtonText') }}</el-button>
</template>
</el-dialog>
<el-dialog :title="prop.title" v-model="state.upload.open" :close-on-click-modal="false" draggable>
<el-upload
ref="uploadRef"
:limit="1"
accept=".xlsx, .xls"
:headers="headers"
:action="baseURL + other.adaptationUrl(url)"
:disabled="state.upload.isUploading"
:on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess"
:on-error="handleFileError"
:auto-upload="false"
drag
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">
{{ $t('excel.operationNotice') }}
<em>{{ $t('excel.clickUpload') }}</em>
</div>
<template #tip>
<div class="el-upload__tip text-center">
<span>{{ $t('excel.fileFormat') }}</span>
<el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="downExcelTemp" v-if="tempUrl"
>{{ $t('excel.downloadTemplate') }}
</el-link>
</div>
</template>
</el-upload>
<template #footer>
<el-button type="primary" @click="submitFileForm">{{ $t('common.confirmButtonText') }}</el-button>
<el-button @click="state.upload.open = false">{{ $t('common.cancelButtonText') }}</el-button>
</template>
</el-dialog>
<!--校验失败错误数据-->
<el-dialog :title="$t('excel.validationFailureData')" v-model="state.errorVisible">
<el-table :data="state.errorData">
<el-table-column property="lineNum" :label="$t('excel.lineNumbers')" width="100"></el-table-column>
<el-table-column property="errors" :label="$t('excel.misDescription')" show-overflow-tooltip>
<template v-slot="scope">
<el-tag type="danger" v-for="error in scope.row.errors" :key="error">{{ error }}</el-tag>
</template>
</el-table-column>
</el-table>
</el-dialog>
<!--校验失败错误数据-->
<el-dialog :title="$t('excel.validationFailureData')" v-model="state.errorVisible">
<el-table :data="state.errorData">
<el-table-column property="lineNum" :label="$t('excel.lineNumbers')" width="100"></el-table-column>
<el-table-column property="errors" :label="$t('excel.misDescription')" show-overflow-tooltip>
<template v-slot="scope">
<el-tag type="danger" v-for="error in scope.row.errors" :key="error">{{ error }}</el-tag>
</template>
</el-table-column>
</el-table>
</el-dialog>
</template>
<script setup lang="ts" name="upload-excel">
import {useMessage} from '/@/hooks/message';
import { useMessage } from '/@/hooks/message';
import other from '/@/utils/other';
import {Session} from '/@/utils/storage';
import { Session } from '/@/utils/storage';
const emit = defineEmits(['sizeChange', 'refreshDataList']);
const prop = defineProps({
url: {
type: String,
},
title: {
type: String,
},
tempUrl: {
type: String,
},
url: {
type: String,
},
title: {
type: String,
},
tempUrl: {
type: String,
},
});
const uploadRef = ref();
const state = reactive({
errorVisible: false,
errorData: [],
dialog: {
title: '',
isShowDialog: false,
},
upload: {
open: false,
isUploading: false,
},
errorVisible: false,
errorData: [],
dialog: {
title: '',
isShowDialog: false,
},
upload: {
open: false,
isUploading: false,
},
});
/**
* 下载模板文件
*/
const downExcelTemp = async () => {
try {
// 如果是 assets 文件夹下的文件,使用 import.meta.url 获取文件
if (prop.tempUrl && prop.tempUrl.includes('assets/file')) {
// 从路径中提取文件名
const fileName = prop.tempUrl.split('/').pop() || 'template.xlsx';
// 使用动态导入获取文件URL从 components/Upload 到 assets/file 的相对路径
const fileUrl = new URL(`../../assets/file/${fileName}`, import.meta.url).href;
const response = await fetch(fileUrl);
if (!response.ok) {
throw new Error('文件下载失败');
}
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = fileName;
document.body.appendChild(link);
link.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(link);
} else {
// 使用后端接口下载,文件名使用导入功能名称
const title = prop.title?.replace('导入', '') || '导入模板';
const fileName = `${title}模板.xlsx`;
await other.downBlobFile(other.adaptationUrl(prop.tempUrl), {}, fileName);
}
} catch (error) {
console.error('模板下载失败:', error);
useMessage().error('模板下载失败,请先维护模板文件');
}
try {
// 如果是 assets 文件夹下的文件,使用 import.meta.url 获取文件
if (prop.tempUrl && prop.tempUrl.includes('assets/file')) {
// 从路径中提取文件名
const fileName = prop.tempUrl.split('/').pop() || 'template.xlsx';
// 使用动态导入获取文件URL从 components/Upload 到 assets/file 的相对路径
const fileUrl = new URL(`../../assets/file/${fileName}`, import.meta.url).href;
const response = await fetch(fileUrl);
if (!response.ok) {
throw new Error('文件下载失败');
}
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = fileName;
document.body.appendChild(link);
link.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(link);
} else {
// 使用后端接口下载,文件名使用导入功能名称
const title = prop.title?.replace('导入', '') || '导入模板';
const fileName = `${title}模板.xlsx`;
await other.downBlobFile(other.adaptationUrl(prop.tempUrl), {}, fileName);
}
} catch (error) {
console.error('模板下载失败:', error);
useMessage().error('模板下载失败,请先维护模板文件');
}
};
/**
* 上传进度条变化事件
*/
const handleFileUploadProgress = () => {
state.upload.isUploading = true;
state.upload.isUploading = true;
};
/**
* 上传失败事件处理
*/
const handleFileError = () => {
useMessage().error('上传失败,数据格式不合法!');
state.upload.open = false;
useMessage().error('上传失败,数据格式不合法!');
state.upload.open = false;
};
/**
@@ -137,53 +136,53 @@ const handleFileError = () => {
* @param {any} response - 上传成功的响应结果
*/
const handleFileSuccess = (response: any) => {
state.upload.isUploading = false;
state.upload.open = false;
uploadRef.value.clearFiles();
state.upload.isUploading = false;
state.upload.open = false;
uploadRef.value.clearFiles();
// 校验失败
if (response.code === 1) {
useMessage().error('导入失败,以下数据不合法');
state.errorVisible = true;
state.errorData = response.data;
uploadRef.value.clearFiles();
// 刷新表格
emit?.('refreshDataList');
} else {
useMessage().success(response.msg ? response.msg : '导入成功');
// 刷新表格
emit?.('refreshDataList');
}
// 校验失败
if (response.code === 1) {
useMessage().error('导入失败,以下数据不合法');
state.errorVisible = true;
state.errorData = response.data;
uploadRef.value.clearFiles();
// 刷新表格
emit?.('refreshDataList');
} else {
useMessage().success(response.msg ? response.msg : '导入成功');
// 刷新表格
emit?.('refreshDataList');
}
};
/**
* 提交表单,触发上传
*/
const submitFileForm = () => {
uploadRef.value.submit();
uploadRef.value.submit();
};
/**
* 显示上传文件对话框,并清除上传信息
*/
const show = () => {
state.upload.isUploading = false;
state.upload.open = true;
state.upload.isUploading = false;
state.upload.open = true;
};
/**
* 计算请求头部信息
*/
const headers = computed(() => {
return {
Authorization: 'Bearer ' + Session.getToken(),
'TENANT-ID': Session.getTenant(),
};
return {
Authorization: 'Bearer ' + Session.getToken(),
'TENANT-ID': Session.getTenant(),
};
});
// 暴露变量
defineExpose({
show,
show,
});
</script>