支持拖放上传
支持鼠标右键和Ctrl+v方式上传
就是有点丑,样式慢慢优化。。。。。。。。。
<template>
<div
class="pre_upload"
@drop="okdrop($event)"
@dragover="allowDrop($event)"
v-on:paste="fun_paste($event)"
>
<div class="pre_leve_one"></div>
<div class="pre_leve_two">
<h4>请把文件拖放到这里来上传</h4>
<div id="files_data" class="pre_files_data" v-show="show_tab">
<table class="pre_dataintable">
<thead>
<tr>
<th>序号</th>
<th>单号</th>
<th>名称</th>
<th>类型</th>
<th>Y/N</th>
<th>大小</th>
<th>进度</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in pre_flies" :key="index">
<td>{{ item.id }}</td>
<td>{{ item.sheet_no }}</td>
<td class="pre_tab_name">
{{ item.name }}
</td>
<td>{{ item.type }}</td>
<td>{{ item.flag }}</td>
<td>{{ item.size }} KB</td>
<td>{{ item.up }}</td>
<td>
<button class="pre_btn_canle" @click="del_files(item.id)">
取消上传
</button>
<button class="pre_btn_ok" @click="lookImage(item)">
预览图片
</button>
</td>
</tr>
</tbody>
</table>
<div>
<button class="pre_btn_del_all" @click="canle_all">全部取消</button
>
<button class="pre_btn_up" @click="submit_files">上传</button>
</div>
</div>
<!-- 使用画布验证上传图片转换是否正确 -->
<!-- <p>画布:</p>
<canvas
id="myCanvas"
width="500"
height="300"
style="border:1px solid #d3d3d3;background:#ffffff;"
>
Your browser does not support the HTML5 canvas tag.
</canvas>-->
<!-- 画布验证过程有异步 还是img直接 -->
</div>
<div>
<p>
注意:复制黏贴实现方式为,使用鼠标右键里的复制,然后使用Ctrl+v到指定区域,才可以上传文件。
</p>
<p>Ctrl+c然后Ctrl+v方式无法上传文件。</p>
</div>
<!-- 弹出向导层 start-->
<div id="pop" class="pop_img" v-show="show_img">
<div class="pop_head">
<a class="close" href="javascript:void(0);" @click="hide()"></a>
</div>
<div id="pop_bodyup" class="pre_show_img">
<img :src="imgsrc" />
</div>
</div>
<!-- 弹出向导层 end-->
<per-message :message_data="msg_obj" />
</div>
</template>
<script>
/*
名称:拖放上传组件
日期:2019-03-14
作者:hj
目标:
1、将拖放的文件名称展示出来:拖放过来的有可能是一堆文件和文件夹混合 当放置被拖数据时,会发生 drop 事件。
2、显示上传文件的进度
3、最好可以支持预览
4、2019-05-16 增加对复制黏贴上传方式的支持
*/
import '@/assets/css/pop.css';
import { base_encode } from "@/utils/base64.js";
import { GetShort,DeleteSpecialWord } from "@/utils/localstore.js";
import { BrowserGet } from "@/utils/systemSelect.js";
export default {
name: "pre_upfile",
components: {
'per-message':()=>import("./pre_message.vue")
},
data() {
return {
pre_flies: [],
exist_data: [],
show_tab: false,
show_img:false,
imgsrc: "",
msg_obj:{},
ok_name:''
};
},
props: {
post_action:String,
sheet_no:String
},
methods: {
okdrop: async function(ev) {
// 调用 preventDefault() 来避免浏览器对数据的默认处理(drop 事件的默认行为是以链接形式打开)
ev.preventDefault();
//绑定单号校验
if(this.sheet_no===undefined || this.sheet_no==null || this.sheet_no==''){
this.msg_obj={'showtype':'warning','note':'请您先选择要上传的文件的对应业务单据'};
return;
}
// 通过 dataTransfer.getData("Text") 方法获得被拖的数据。该方法将返回在 setData() 方法中设置为相同类型的任何数据。
// var data=ev.dataTransfer.getData("Text");
var back_data = [],
ok_data = [];
back_data = ev.dataTransfer.files; //获取文件
for (var i = 0; i < back_data.length; i++) {
var td = {};
td.id = i + 1;
this.check_file_name(back_data[i].name);
td.name = this.ok_name;
td.type = back_data[i].type;
// td.size=Math.round(Number(back_data[i].size)/1024);
td.size = (Number(back_data[i].size) / 1024).toFixed(0);
if (
String(td.type)
.toLowerCase()
.indexOf(".exe") > 0
) {
td.flag = "NO";
} else {
td.flag = "YES";
}
td.up = 0 + "%";
td.sheet_no=this.sheet_no; //当前点击选择 的单号
td.filedata = await this.convertFileToString(back_data[i]);
ok_data[i] = td;
}
var j = 0;
j = this.exist_data.length;
if (j > 0) {
for (var i = 0; i < ok_data.length; i++) {
this.exist_data[j] = ok_data[i];
j += 1;
}
// 如果是多次拖放,需要进行二次整理
var temp_d=[];
for(var i=0;i<this.exist_data.length;i++){
var temp_o={};
temp_o.id = i + 1;
temp_o.name = this.exist_data[i].name;
temp_o.type = this.exist_data[i].type;
temp_o.size = this.exist_data[i].size;
temp_o.flag = this.exist_data[i].flag;
temp_o.up = this.exist_data[i].up;
temp_o.filedata= this.exist_data[i].filedata;
temp_o.sheet_no= this.exist_data[i].sheet_no;
temp_d[i]=temp_o;
}
this.pre_flies=temp_d;
} else {
this.exist_data = ok_data;
this.pre_flies = this.exist_data;
}
this.show_tab = true;
// var tf=document.getElementById("files_data");
// tf.target.appendChild(files);
},
allowDrop: function(ev) {
ev.preventDefault();
},
convertFileToString: function(tempfile) {
return new Promise(resolve => {
var tf = new FileReader();
tf.readAsDataURL(tempfile);
tf.onload = function() {
resolve(this.result);
};
});
},
submit_files: async function() {
this.exist_data = [];
for (var i = 0; i < this.pre_flies.length; i++) {
/*这块应该还可以用vuex 封装*/
var postdata = "";
postdata =
'{"action":"'+this.post_action+'","user_no":"' +
GetShort("userno") +
'","upfile_name":"' +
DeleteSpecialWord(this.pre_flies[i].name) +
'","upfile_type":"' +
this.pre_flies[i].type +
'","upfile_size":"' +
this.pre_flies[i].size +
'","upfile_data":"' +
this.pre_flies[i].filedata +
'","sheet_no":"' +
this.pre_flies[i].sheet_no +
'"}';
postdata =
'{"method":"File_load","data":"' + base_encode(postdata) + '"}';
var tp = this.pre_flies[i];
await this.updatabyquere(postdata, tp);
}
},
updatabyquere: function(postdata, tp) {
// try {
this.$postfile(
"/Data_Back",
postdata,
res => {
var loaded = 0,
total = 0;
loaded = res.loaded;
total = res.total;
this.$nextTick(() => {
// console.log(tp);
tp.up = ((loaded / total) * 100).toFixed(2) + " %";
});
}
).then(res => {
res = JSON.parse(res);
console.log(res);
res = res.data;
if (res.status == 1) {
tp.up = "上传成功";
this.msg_obj={'showtype':'ok','note':'上传成功'};
} else {
tp.up = "上传失败";
this.msg_obj={'showtype':'ok','note':'上传失败\n\r'+res.msg};
}
});
// }
// catch (ex) {
// tp.up = "上传失败\r\n"+ex;
// }
},
del_files: function(id) {
var data = [];
var j=0;
for (var i = 0; i < this.pre_flies.length; i++) {
if (this.pre_flies[i].id != id) {
data[j] = this.pre_flies[i];
j+=1;
}
}
this.pre_flies = data;
if (this.pre_flies.length == 0) {
this.show_tab = false;
}
},
canle_all: function() {
this.pre_flies = [];
this.exist_data = [];
this.show_tab = false;
},
lookImage:function(parm){
console.log('进来'+parm.name);
if (/\.(gif|jpg|jpeg|png|GIF|JPG|PNG|ico|pdf)$/.test(parm.name)) {
this.imgsrc=parm.filedata;
this.show_img=true;
}
},
closeImage:function(parm){
console.log('出去');
this.show_img=false;
},
hide:function(){
this.show_img=false;
},
fun_paste:async function(e){
var browserType=BrowserGet();
console.log('浏览器类型 '+browserType);
//绑定单号校验
if(this.sheet_no===undefined || this.sheet_no==null || this.sheet_no==''){
this.msg_obj={'showtype':'warning','note':'请您先选择要上传的文件的对应业务单据'};
return;
}
var back_data = [],ok_data = [];
if(browserType=='chrome' || browserType=='firefox' ){
// console.log(e.clipboardData);
// console.log(e.clipboardData.files);
back_data = e.clipboardData.files; //获取文件
for (var i = 0; i < back_data.length; i++) {
var td = {};
td.id = i + 1;
this.check_file_name(back_data[i].name);
td.name = this.ok_name;
td.type = back_data[i].type;
// td.size=Math.round(Number(back_data[i].size)/1024);
td.size = (Number(back_data[i].size) / 1024).toFixed(0);
if (
String(td.type)
.toLowerCase()
.indexOf(".exe") > 0
) {
td.flag = "NO";
} else {
td.flag = "YES";
}
td.up = 0 + "%";
td.sheet_no=this.sheet_no; //当前点击选择 的单号
td.filedata = await this.convertFileToString(back_data[i]);
ok_data[i] = td;
}
}
var j = 0;
j = this.exist_data.length;
if (j > 0) {
for (var i = 0; i < ok_data.length; i++) {
this.exist_data[j] = ok_data[i];
j += 1;
}
// 如果是多次拖放,需要进行二次整理
var temp_d=[];
for(var i=0;i<this.exist_data.length;i++){
var temp_o={};
temp_o.id = i + 1;
temp_o.name = this.exist_data[i].name;
temp_o.type = this.exist_data[i].type;
temp_o.size = this.exist_data[i].size;
temp_o.flag = this.exist_data[i].flag;
temp_o.up = this.exist_data[i].up;
temp_o.filedata= this.exist_data[i].filedata;
temp_o.sheet_no= this.exist_data[i].sheet_no;
temp_d[i]=temp_o;
}
this.pre_flies=temp_d;
} else {
this.exist_data = ok_data;
this.pre_flies = this.exist_data;
}
if(this.pre_flies.length>0){
this.show_tab = true;
}
},
check_file_name:function(name){
this.ok_name='';
var chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
var maxLength = 6;
var paramsAccount = '';
for (var i = 0; i < maxLength; i++) {
var id = Math.ceil(Math.random() * 35);
paramsAccount += chars[id];
}
this.ok_name=paramsAccount+'_'+name;
}
}
};
</script>
<style scoped>
.pre_upload {
width: 100%;
min-height: 200px;
height: 100%;
background-color: azure;
text-align: center;
/* padding: 10px 20px 10px 20px; */
}
.pre_leve_one {
height: 5px;
}
.pre_leve_two {
/* padding: 5px; */
margin: 15px;
margin-top: 15px;
border: 1px solid #191970;
min-height: 200px;
height: auto;
}
.pre_files_data {
width: 100%;
min-height: 200px;
height: auto;
/* padding: 10px 20px 10px 20px; */
}
.pre_files_data > ul {
list-style: none;
}
.pre_files_data > ul > li {
border: 1px solid black;
}
.pre_files_data > ul > li > span {
margin-left: 5px;
}
.pre_dataintable {
margin-top: 15px;
border-collapse: collapse;
border: 1px solid #aaa;
width: 95%;
/* padding 没有作用 */
/* padding: 0px 5px 10px 5px; */
position: relative;
left: 2%;
}
.pre_dataintable th {
vertical-align: baseline;
padding: 5px 15px 5px 6px;
background-color: rgb(87, 201, 230);
border: 1px solid #3f3f3f;
text-align: left;
color: #000000;
font-size: 16px;
font-weight: bolder;
}
.pre_dataintable td {
vertical-align: text-top;
padding: 6px 15px 6px 6px;
border: 1px solid #aaa;
}
.pre_dataintable tr:nth-child(odd) {
background-color: #f5f5f5;
}
.pre_dataintable tr:nth-child(even) {
background-color: #fff;
}
.pre_tab_name {
cursor: pointer;
word-break: break-all;
}
.pre_tab_name:hover {
cursor: pointer;
background-color: #aaa;
}
/* 全部取消按钮 */
.pre_btn_del_all {
color: black;
font-size: 16px;
width: 100px;
height: 30px;
background-color: rgba(236, 26, 26, 0.986);
}
/* 上传按钮 */
.pre_btn_up {
color: black;
font-size: 16px;
width: 100px;
height: 30px;
background-color: rgba(44, 247, 61, 0.986);
}
/* 删除按钮 */
.pre_btn_canle {
color: black;
font-size: 16px;
width: 80px;
height: 25px;
background-color: rgba(236, 26, 26, 0.986);
}
.pre_show_img {
width: 400px;
height: 400px;
text-align: center;
margin-top: -40px;
/* background-color: #000000; */
}
.pre_show_img > img {
width: auto;
height: 100%;
}
</style>