<template>
<div class="com-dialog-style">
<el-dialog
class="import-completed-dialog"
:title="isSuccess ? '导入成功' : '导入用户'"
v-model="dialogVisible"
width="60%"
>
<!-- 未导入 -->
<div class="import-completed-cont" v-if="!isSuccess">
<div class="upload-box">
<div class="upload-title">选择文件导入</div>
<div class="upload-content">
<div>
<el-upload
ref="uploadRef"
class="upload"
action="/api/user/import"
drag
:limit="1"
:show-file-list="false"
:before-upload="beforeAvatarUpload"
:on-change="excelChange"
:on-success="excelSuccess"
successExcel
:auto-upload="false"
>
<el-icon class="tips-icon"
><el-icon><UploadFilled /></el-icon
></el-icon>
<div class="el-upload__text">点击或将文件拖拽到这里上传</div>
</el-upload>
</div>
<div class="right-text">
<div>
<a :href="excelUrl" class="download-text">下载导入模板</a>
</div>
<div class="el-upload__tip" slot="tip">
仅支持xls或xlsx格式、行数在1002行以内、大小在10M以内的文档。上传后再次上传可替换。
</div>
<div class="file-name">{{ fileName }}</div>
</div>
</div>
</div>
<div class="import-instructions">
<div class="import-instructions-title">导入说明</div>
<div>
<div class="instructions-item-mgt">
1、一次最多导入<span class="error">1000</span
>条,请确保文件数据不超过1000条。
</div>
<div class="instructions-item-mgt">
2、<span class="error">工资编码</span>是用户的<span class="error"
>唯一标识符</span
>,若系统中已存在相同工资编码的用户,则导入是更新用户信息,而不是新增。
</div>
<div class="instructions-item-mgt">
3、导入功能仅能维护用户基本信息,要新增或修改用户头像请到<span
class="error"
>盒子端</span
>操作。
</div>
<div class="instructions-item-mgt">
4、盒子端批量导入头像时,请用“<span class="error"
>姓名_工资编码</span
>”作为文件名,例如:张三_985326
</div>
<div class="instructions-item-mgt">
5、每天凌晨后台会自动将盒子端的头像同步到用户列表(根据姓名和工资编码匹配),点击列表右侧的“<span
class="error"
>更新头像</span
>”可立即同步。
</div>
<div class="instructions-item-mgt">
6、<span class="error">请勿随意修改模板的表头字段</span
>,否则会导致导入失败。
</div>
<div class="instructions-item-mgt">
7、带 *
字段为必填;手机号如有填写限制11位,性别请勿填男女以外的其他内容。
</div>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="uploadData">开始导入</el-button>
</span>
</div>
<!-- 导入完成 -->
<div class="import-completed-cont-ok" v-else>
<div class="import-completed-item">
本次共导入 <span>{{ excelData.total_num }}</span> 条数据。
</div>
<div class="import-completed-item">
导入成功
<span class="success">{{
excelData.insert_num + excelData.update_num
}}</span>
条,其中新增用户
<span>{{ excelData.insert_num }}</span> 个,修改用户信息
<span class="waring">{{ excelData.update_num }}</span>
个(工资编码已存在的用户,导入是更新用户信息,而不是新增)。
</div>
<div class="import-completed-item">
导入失败
<span class="error">{{ excelData.fail_num }}</span> 条,你可<el-button
class="btn-text"
type="text"
@click="downloadFailureList"
>下载导入失败名单</el-button
>,查看失败原因,然后直接在该表格修正,然后直接上传该文件重新导入(重新导入时,“失败原因”那一列可以不删除)。
</div>
<div class="import-completed-item">
关闭该窗口后,点击列表右上角“下载导入失败名单”可下载最后一次导入失败的名单。
</div>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="closeSuccess">我知道了</el-button>
</span>
</div>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from "vue";
import {
ElDialog,
ElButton,
ElNotification,
ElUpload,
ElLoading,
} from "element-plus";
import { UploadFilled } from "@element-plus/icons";
import { user_fail } from "@/api";
const dialogVisible = ref(false);
const fileName = ref(""); //导入文件名称
const isSuccess = ref(false); //是否导入成功
const loading = ref(false);
const excelUrl =
process.env.NODE_ENV === "development"
? "https://dc-bj-test.familyhealth.tech" + "/export/导入用户模板.xlsx"
: window.location.origin + "/export/导入用户模板.xlsx"; //excel下载地址
const handleOpen = () => {
dialogVisible.value = true;
};
const excelData = ref();
const loadingInstance = ref<ElLoading>();
const beforeAvatarUpload = (files) => {
//获取文件名后缀
const fileType = files.name.endsWith(".xlsx") || files.name.endsWith(".xls");
loadingInstance.value = ElLoading.service({
lock: true,
text: "正在导入,请稍后",
background: "rgba(0, 0, 0, 0.7)",
});
};
const uploadRef = ref(null);
// 文件改变
const excelChange = (file) => {
console.log(file, "file");
fileName.value = file.name;
};
// 文件上传成功
const excelSuccess = ({ data, status, message }) => {
if (status === 200) {
isSuccess.value = true;
excelData.value = data;
} else if (status === 20005) {
const msg = message.replace(/\,/g, "<br />");
ElNotification({
dangerouslyUseHTMLString: true,
message: `你上传的文件里面,以下工资编码出现过两次以上,工资编码是用户唯一标识符,不允许重复,请先修正。<br />${msg}`,
type: "error",
duration: 0, //消息存在时间,0表示一直存在
});
} else {
ElNotification({
message: message || "导入内容有误",
type: "error",
});
}
loadingInstance.value?.close(); //上传成功后关闭loading
uploadRef.value.clearFiles(); //删除文件
};
const uploadData = async () => {
uploadRef.value.submit();
};
// 下载导入失败名单
const downloadFailureList = async () => {
const { status, data } = await user_fail();
if (status === 200) {
window.open(data.url);
ElNotification({
message: "导出成功",
type: "success",
});
}
};
const closeSuccess = () => {
dialogVisible.value = false;
isSuccess.value = false;
};
defineExpose({
handleOpen,
});
</script>
<style lang="scss">
.import-completed-dialog {
.success {
color: #67c23a !important;
}
.error {
color: red !important;
}
.waring {
color: #e6a23c !important;
}
.upload-box {
background: #f7f9fc;
padding: 12px;
}
.upload-content {
display: flex;
align-items: flex-end;
justify-content: flex-start;
margin: 12px 0 0 0;
}
.upload-title {
font-size: var(--el-font-size-large);
}
.tips-icon {
font-size: 28px;
color: #409eff;
}
.download-text {
color: #409eff;
}
.right-text {
margin-left: 0.1rem;
}
.import-instructions {
font-size: var(--el-dialog-content-font-size);
line-height: var(--el-font-size-large);
padding: 0 0 0 14px;
margin: 20px 0;
.import-instructions-title {
font-size: var(--el-font-size-large);
margin-bottom: 10px;
}
.instructions-item-mgt {
margin-bottom: 8px;
}
}
.import-completed-item {
text-align: justify;
font-size: var(--el-dialog-content-font-size);
span {
color: #409eff;
font-weight: bold;
}
.btn-text {
span {
color: red;
}
}
}
.import-completed-item {
margin-bottom: 0.16rem;
}
.dialog-footer {
justify-content: center;
}
.file-name {
margin-top: 0.05rem;
color: #409eff;
font-weight: bold;
}
}
</style>
vue3+ts使用ElUpload上传(包含loading与重新上传)
最新推荐文章于 2024-05-20 17:02:17 发布