Files
fe-manage/src/components/project/ImportWork.vue
2024-11-01 11:01:07 +08:00

637 lines
22 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div>
<a-modal
:visible="showWork"
:footer="null"
:closable="closableQR"
wrapClassName="codeModal"
style="margin-top: 400px"
:zIndex="9"
@cancel="qr_exit"
>
<div class="QR">
<div class="qr_header"></div>
<div class="qr_main">
<div class="qrm_header">
<span style="title">{{ title }}</span>
<div class="close_exit" @click="closeCodeModal"></div>
</div>
<div class="line"></div>
<div class="contents">
<div class="drawerMain">
<div class="main">
<div class="minatitl">
<div class="up1">请下载</div>
<div class="up2" @click="downTemplate" style="cursor: pointer">
模板
</div>
<div class="up1">按要求填写数据并导入</div>
</div>
<div class="upload">
<div class="text">上传</div>
<div class="right">
<div style="height: 176px; margin-bottom: 20px">
<a-upload-dragger v-model:fileList="fileList" :action="importHomeWork" :name="fileName" :multiple="true"
:headers="headers"
@change="handleChange" :showUploadList="false">
<p class="ant-upload-drag-icon">
<inbox-outlined></inbox-outlined>
</p>
<p class="ant-upload-text">点击或将文件拖拽到此处上传</p>
<p class="ant-upload-hint">支持扩展名.xls/.xlsx</p>
</a-upload-dragger>
</div>
<div class="loadstate">
<div class="loadborder" v-if="uploadpercent < 100 && uploadpercent !== -1">
<div class="content">
<div class="img"></div>
<div class="timebox">
<div class="timetop">
<div class="tit">{{ fileName }}</div>
<div class="stateloading">正在上传</div>
</div>
<a-progress :percent="uploadpercent" />
</div>
<div class="curloading">
</div>
</div>
</div>
<div class="loadborder" v-if="uploadErr">
<div class="content">
<div class="img"></div>
<div class="timebox">
<div class="timetop">
<div class="tit">{{ fileName }}</div>
<div class="statedefeat">上传失败</div>
</div>
<a-progress :percent="uploadpercent" />
</div>
<div class="curloading">
<div style="color: #387df7; margin-left: 20px; cursor: pointer">
下载失败数据
</div>
</div>
<div class="defeat" style="display: flex; align-items: center">
<div style="color: #ff7474">
{{ succNum }}条数据导入成功{{ errNum }}条数据导入失败
</div>
</div>
</div>
</div>
<div class="loadborder" v-if="uploadpercent === 100">
<div class="content">
<div class="img"></div>
<div class="timebox">
<div class="timetop">
<div class="tit">{{ fileName }}</div>
<div class="statesucce">上传成功</div>
</div>
<a-progress :percent="uploadpercent" />
</div>
<div class="curloading">
<div class="cancel" style="margin-left: 20px; cursor: pointer" @click="removeUpload">
删除
</div>
</div>
</div>
<div v-if="errNum">
<div class="downloadErr" @click="downloadEeeorData">
下载失败数据
</div>
</div>
</div>
<div v-if="uploadpercent === 100" class="defeat" style="
display: flex;
align-items: center;
width: 500px;
height: 40px;" :style="{
background: errNum
? 'rgba(255, 116, 116, 0.1)'
: 'rgba(53, 174, 105, 0.1)',
border: errNum ? '1px solid #ff7474' : '1px solid #35AE69',
}">
<img style="width: 14px; height: 14px; margin-left: 16px" :src="
errNum
? require('../../assets/images/err.png')
: require('../../assets/images/success.png')
" />
<div style="margin-left: 8px" :style="{ color: errNum ? '#ff7474' : 'rgba(0,0,0,0.65)' }">
{{ succNum }}条数据导入成功{{ errNum }}条数据导入失败
</div>
</div>
</div>
</div>
</div>
</div>
<div class="btnn">
<button class="btn1" @click="closeCodeModal">取消</button>
<button class="btn2" @click="closeCodeModal">确定</button>
</div>
</div>
</div>
</div>
</div>
</a-modal>
</div>
</template>
<script>
import { reactive, toRefs, watch,ref,computed } from "vue";
import { message } from "ant-design-vue";
import { useStore } from "vuex";
import * as api from "../../api/index1";
import {getCookieForName} from "@/api/method";
export default {
name: "importWork",
components: {
},
props: {
showWork: {
type: Boolean,
default: false,
},
url: {
type: String,
default: null,
},
title:{
type: String,
default: null,
},
fileName:{
type: String,
default: 'file',
},
},
setup(props, ctx) {
const state = reactive({
fileType: ["xls", "xlsx"],
importHomeWork:
process.env.VUE_APP_BASE_API + props.url,
uploadpercent: -1,
uploadErr: false, //上传失败
addLoading: false,
fileList: [],
succNum: 0, //成功数据数
errNum: 0, //失败数据数
downloadErrUrl: null, //下载失败数据
fileName: "",
});
const headers = { token: getCookieForName("token") };
const closeCodeModal = () => {
ctx.emit("update:showWork", false);
state.fileList = [];
state.uploadpercent = -1;
state.uploadErr = false; //上传失败
};
//上传文件
const handleChange = (info) => {
if (info) {
var FileExt = info.file.name.replace(/.+\./, "");
if (["xls", "xlsx"].indexOf(FileExt.toLowerCase()) === -1) {
state.fileList = [];
state.uploadpercent = -1;
message.destroy();
message.error("请上传正确的文件格式");
return;
}
}
state.addLoading = true;
state.uploadpercent = parseInt(info.file.percent);
console.log("我是文件上传的进度---------->", info.file.percent);
const status = info.file.status;
console.log(info.file,'status')
if (status !== "uploading") {
// console.log(info.file, info.fileList);
}
if (status === "done") {
state.fileName = info.file.name;
if(!info.file.response.data){
message.error(`${info.file.name}上传失败`);
}
let i = 0;
let timeouts = setTimeout(() => {
// clearInterval(timer)
state.addLoading = false;
message.destroy();
message.error(`文件导入超时`);
}, 30000);
// let timer = setInterval(() => {
// let uid = info.file.response.data;
// api
// .getImportStatus(uid)
// .then((res) => {
// console.log("查询导入状态", res);
// if (res.data.code === 200) {
// if (res.data.data.status !== "START") {
// i++;
// if (i === 1) {
// message.destroy();
// message.success(`${info.file.name}上传成功`);
// state.addLoading = false;
// props.searchTaskList && props.searchTaskList();
// }
// state.succNum = res.data.data.successNum;
// state.errNum = res.data.data.failedNum;
// state.downloadErrUrl = res.data.data.url;
// console.log("props.getStudent", props.getStudent);
// clearInterval(timer);
// clearTimeout(timeouts);
// }
// } else {
// state.addLoading = false;
// message.destroy();
// clearTimeout(timeouts);
// }
// })
// .catch((err) => {
// state.addLoading = false;
// clearInterval(timer);
// clearTimeout(timeouts);
// console.log("查询导入状态失败", err);
// });
// }, 500);
} else if (status === "error") {
state.uploadErr = true;
message.error(`${info.file.name}上传失败`);
}
};
//删除
const removeUpload = () => {
state.fileList = [];
state.uploadpercent = -1;
state.uploadErr = false; //上传失败
state.succNum = 0;
state.errNum = 0;
state.downloadErrUrl = null;
state.addLoading = false;
};
// 下载失败数据
const downloadEeeorData = () => {
if (state.downloadErrUrl !== "") {
window.open(process.env.VUE_APP_FILE_PATH + state.downloadErrUrl);
}
};
function downTemplate() {
window.open(`${process.env.VUE_APP_BASE_API}/admin/student/exportHomeWorkTemplate?taskId=${props.id || ''}&type=${props.type || ''}&pid=${props.pid || ''}&thirdType=3`);
}
return {
...toRefs(state),
closeCodeModal,
handleChange,
downTemplate,
headers,
removeUpload,
downloadEeeorData,
};
},
}
</script>
<style lang="scss" scoped>
.codeModal {
.ant-modal {
.ant-modal-content {
width: 479px !important;
.ant-modal-body {
.QR {
z-index: 11;
width: 700px;
background: #ffffff;
box-shadow: 0px 1px 35px 0px rgba(118, 136, 166, 0.21);
position: absolute;
left: 50%;
top: 10%;
transform: translate(-50%, -50%);
.qr_header {
position: absolute;
width: calc(100%);
height: 40px;
// background: linear-gradient(
// rgba(78, 166, 255, 0.2) 0%,
// rgba(78, 166, 255, 0) 100%
// );
}
.qr_main {
width: 100%;
position: relative;
.qrm_header {
display: flex;
align-items: center;
padding-top: 20px;
padding-left: 26px;
font-size: 16px;
.title {
font-size: 16px;
font-weight: 600;
color: #333333;
line-height: 22px;
}
.close_exit {
position: absolute;
right: 42px;
cursor: pointer;
width: 20px;
height: 20px;
background-image: url(@/assets/images/coursewareManage/close.png);
background-size: 100% 100%;
}
}
.line{
height: 1px;
margin-top: 16px;
background-color: #666666;
}
.contents{
display: flex;
min-height: 500px;
.drawerMain {
min-width: 600px;
margin: 0px 32px 0px 32px;
overflow-x: auto;
display: flex;
flex-direction: column;
.header {
height: 73px;
border-bottom: 1px solid #e8e8e8;
display: flex;
justify-content: space-between;
align-items: center;
// background-color: red;
margin-bottom: 20px;
flex-shrink: 0;
.headerTitle {
font-size: 18px;
font-weight: 600;
color: #333333;
line-height: 25px;
// margin-left: 24px;
}
}
.main {
overflow-y: auto;
.minatitl {
display: flex;
margin-top: 20px;
.up1 {
font-size: 16px;
font-weight: 400;
color: #333333;
}
.up2 {
font-size: 16px;
font-weight: 400;
color: #4ea6ff;
margin-left: 4px;
}
}
.upload {
margin-top: 32px;
display: flex;
.text {
font-size: 14px;
font-weight: 400;
color: #333333;
}
.right {
margin-left: 6px;
.load {
width: 500px;
height: 176px;
background: #f5f9fd;
border-radius: 4px;
// opacity: 0.3;
border: 1px dashed #caddfd;
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 20px;
.cloud {
margin-top: 52px;
width: 28px;
height: 28px;
background-image: url(../../assets/images/basicinfo/cloud.png);
}
.tip {
font-size: 14px;
font-weight: 400;
color: #4ea6ff;
margin-top: 15px;
cursor: pointer;
}
.tipz {
font-size: 14px;
font-weight: 400;
color: #999999;
margin-top: 10px;
}
}
.loadstate {
width: 500px;
margin-bottom: 100px;
.loadborder {
width: 500px;
height: 173px;
border-radius: 4px;
border: 1px dashed #eaeaea;
margin-bottom: 30px;
display: flex;
flex-direction: column;
justify-content: center;
position: relative;
.content {
display: flex;
margin-left: 20px;
position: relative;
.defeat {
width: 400px;
position: absolute;
left: 46px;
top: 38px;
font-size: 14px;
font-weight: 500;
justify-content: space-between;
}
.img {
width: 30px;
height: 34px;
background-image: url(../../assets/images/basicinfo/exl.png);
}
.timebox {
margin-left: 15px;
margin-top: -5px;
.timetop {
display: flex;
width: 262px;
justify-content: space-between;
// margin-bottom: 8px;
.tit {
font-size: 14px;
font-weight: 400;
color: #333333;
}
.stateloading {
font-size: 14px;
font-weight: 400;
color: #4ea6ff;
}
.statedefeat {
font-size: 14px;
font-weight: 400;
color: #ff7474;
}
.statesucce {
font-size: 14px;
font-weight: 400;
color: #35ae69;
}
}
.prog {
width: 262px;
height: 5px;
background: #eaf1fe;
border-radius: 4px;
.inprogloading {
width: 55%;
height: 5px;
border-radius: 4px;
background: #4ea6ff;
}
//下载失败条
.inprogdefeat {
width: 55%;
height: 5px;
border-radius: 4px;
background: #ff7474;
}
//下载成功条
.inprogsucce {
width: 100%;
height: 5px;
border-radius: 4px;
background: #57c887;
}
}
}
.curloading {
margin-left: 15px;
margin-top: 15px;
display: flex;
.cur {
font-size: 14px;
font-weight: 400;
color: #333333;
}
.cancel {
font-size: 14px;
font-weight: 400;
color: #387df7;
}
}
}
.downloadErr {
width: 120px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 2px;
border: 1px solid #387df7;
font-size: 14px;
font-weight: 400;
color: #387df7;
line-height: 20px;
cursor: pointer;
margin-left: 66px;
margin-top: 16px;
position: absolute;
bottom: 28;
}
}
}
}
}
}
.btnn {
height: 72px;
width: 100%;
position: absolute;
background-color: #fff;
bottom: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0px 1px 35px 0px rgba(118, 136, 166, 0.16);
.btn1 {
width: 100px;
height: 40px;
border: 1px solid #4ea6ff;
border-radius: 8px;
color: #4ea6ff;
background-color: #fff;
cursor: pointer;
}
.btn2 {
cursor: pointer;
width: 100px;
height: 40px;
background: #4ea6ff;
border-radius: 8px;
border: 0;
margin-left: 15px;
color: #fff;
}
}
}
}
}
}
}
}
}
}
</style>