vue中,el-table树形数据与懒加载【实例】(二)——封装拖拽上传el-upload & 本地下载模板-public下的file文件夹 & JSON.parse转对象 & 表单禁止输入特殊字符
4、封装拖拽下载模板和上传
src\components\customPlanImport.vue
<template>
<div class="item-content">
<el-dialog
v-model="isShow"
:close-on-click-modal="true"
:destroy-on-close="true"
:show-close="true"
title="导入规划计划"
width="35%"
@close="handleCancel"
>
<el-upload
ref="uploadRef"
action="#"
class="upload-demo"
drag
:file-list="fileList"
:http-request="handlePeopleUpload"
:limit="1"
:multiple="false"
:show-file-list="true"
>
<!-- :on-change="handleChange"
:on-remove="handleRemove" -->
<i class="el-icon-upload"></i>
<div class="el-upload__text">
<em>选择文件</em>
或将文件拖拽至此区域
</div>
<div class="el-upload__tip">支持格式:xls、xlsx</div>
</el-upload>
<el-button type="text" @click="handleDownLoadTemplate(source)">
下载导入模板
</el-button>
<div class="upload-footer">
<el-button type="primary" @click="handleSubmit">确 定</el-button>
<el-button plain type="primary" @click="handleCancel">取 消</el-button>
</div>
</el-dialog>
<!-- 导入失败 -->
<el-dialog
v-model="isShowFail"
class="fail-dialog"
:close-on-click-modal="true"
:destroy-on-close="true"
:show-close="true"
title="导入失败"
width="35%"
@close="handleClose"
>
<template v-if="errorList[0].row">
<h4 class="fail-title">
导入失败,请求改后重新上传,错误数据{
{ errNumber }}条,失败原因如下:
</h4>
<el-table border :data="errorList">
<el-table-column label="行数" prop="index" />
<el-table-column label="错误原因" prop="msg" />
</el-table>
</template>
<template v-else>
<h4 class="fail-title">
导入失败,请求改后重新上传,失败原因:
<span style="font-weight: 200; color: red">
{
{ errorList[0].msg }}
</span>
</h4>
</template>
</el-dialog>
</div>
</template>
<script>
// import { downloadFileCom } from '@src/hooks/useFolesUtils.js' // 走接口下载
// import { getFeasDownload } from '@/api/research/index' // 走接口下载
import { downFile } from '@src/utils/util' // 本地下载
import { ElMessage } from 'element-plus'
import { uploadPlanFileApi } from '@/api/organization/project'
export default defineComponent({
name: 'CustomTaskImport',
components: {},
props: {
source: {
require: true,
type: String,
default: '',
},
showDialog: {
require: true,
type: Boolean,
default: false,
},
},
emits: ['closeDialog', 'submitDialog', 'downLoadTemplate'],
setup(props, { emit }) {
const { showDialog, source } = toRefs(props)
const state = reactive({
isShow: showDialog,
uploadRef: null,
isShowFail: false,
source: source,
fileList: [],
formData: {
name: '',
},
fileData: [],
errNumber: 0,
errorList: [],
})
//下载导入模板
const handleDownLoadTemplate = (type) => {
if (type === 'approval') {
// 接口下载模板
// getFeasDownload().then((res) => {
// downloadFileCom(res, '规划计划导入模板')
// })
downFile('Plan-Import.xlsx')
}
}
//提交
const handlePeopleUpload = (options) => {
const formData = new FormData()
formData.append('file', options.file)
switch (state.source) {
case 'research':
case 'task':
case 'approval':
uploadPlanFileApi(formData).then((res) => {
if (res.code === '00000') {
// state.fileData = res.data
ElMessage({
type: 'success',
message: '上传成功',
})
} else {
// state.errNumber = 0
ElMessage.error(res.message)
}
})
}
}
const handleSubmit = () => {
state.uploadRef.clearFiles()
// if (state.errNumber > 0) {
// state.isShowFail = true
// } else {
// state.isShowFail = false
// if (state.fileData.length && state.errorList.length) {
// ElMessage.success('导入成功')
// } else {
// ElMessage.error({
// type: 'error',
// message: '请先上传文件',
// })
// }
// }
handleClose()
// emit('submitDialog', state.fileData)
emit('submitDialog', state.handleClose)
}
// 文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用
const handleChange = (file) => {
const fileName = file.raw.name
//限制文件类型
const fileExt = fileName.replace(/.+\./, '')
if (['xlsx', 'xls'].indexOf(fileExt.toLowerCase()) === -1) {
ElMessage({
showClose: true,
message: '请上传后缀名为xlsx、xls',
type: 'error',
})
return
}
}
//移除
const handleRemove = () => {}
// 取消
const handleCancel = () => {
emit('closeDialog')
}
// 关闭
const handleClose = () => {
state.handleClose = false
}
return {
...toRefs(state),
handleClose,
handleSubmit,
handleRemove,
handleChange,
handleCancel,
handlePeopleUpload,
handleDownLoadTemplate,
}
},
})
</script>
<style lang="scss" scoped>
.fail-dialog {
.fail-title {
margin: 0px 0 10px;
}
:deep() {
.ym-dialog__body {
padding: 10px 20px 20px;
}
}
}
:deep() {
.ym-dialog {
.ym-dialog__title {
float: left;
}
}
}
.upload-footer {
display: flex;
justify-content: center;
padding-bottom: 20px;
}
</style>
src\app\plan\api\organization\project.js
//上传文件-规划计划模板
export const uploadPlanFileApi = (data) => {
return request({
url: `${
plan}/prog/importProg`,
method: 'post',
data,
headers: {
'Content-Type': 'multipart/from-data',
},
})
}
5、本地下载-public下的file文件夹
src\utils\util.js
//文件流导出数据处理
export const downLoadxls = (res, fileName) => {
let name = fileName
if (res.headers['content-disposition']) {
const contentDisposition = res.headers['content-disposition'].split('=')
name = (contentDisposition && decodeURI(contentDisposition[1])) || ''
}
const file = new File([res.data], name, res.data)
const href = URL.createObjectURL(file)
const aTag = document.createElement('a')
aTag.download = file.name
aTag.target = '_blank'
aTag