一:pc端,基于element-ui的文件上传功能
<el-upload class="upload-demo" :before-upload="beforeUpload" drag action multiple>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
</el-upload>
async beforeUpload(file) {
let postParams = new FormData();
postParams.append("fileField", file); // 上传参数{ fileField: file}
const res = await this.$store.dispatch('doc-management/saveImport', postParams);
console.log("res",res);
}
二:移动端,使用uploader直传图片到oss的功能 ,上传成功后获取到图片,接着合成一整新的海报图片(适用于合成动态二维码海报的需求)
- pages/showCertificate/index.vue (需要先安装依赖 cnpm i plupload)
<section class="pageStatus1" v-if="pageStatus === 1">
<img class="uploader_btn" v-if="teacherCert === ''" ref="uploaderInput" @click="uploaderInput" src="../../assets/showCertificate/upload_btn.png" alt="">
<img class="uploader_btn" v-else ref="uploaderInput" @click="uploaderInput" src="../../assets/showCertificate/upload_btn_again.png" alt="">
<div class="content_box">
<div class="imageWrapper" v-if="posterBase64 === ''"></div>
<div class="imageWrapper_box" v-else>
<img class="imageWrapper_kuang" src="../../assets/showCertificate/wrapper_kuang.png" alt="">
<div class="imageWrapper_cont">
<img class="real_pic" :src="posterBase64" />
</div>
</div>
<ul class="miniUl">
<li v-for="(item,itemI) in defaultSetting.miniImg" :key="itemI" :class="itemI+1 === teacherCertBg ? 'active' :''" @click="chooseComponent(itemI + 1)">
<img :src="item" alt="">
<p>相框 {{ (itemI+1) | numFilter }}</p>
</li>
</ul>
</div>
<img class="sz_btn" @click="uploadBase64" src="../../assets/showCertificate/sz_btn.png" alt="">
</section>
init() {
this.uploadOss();
},
uploadOss() {
this.uploaderType = 'cert'; // 上传的是证件照
let uploaderInput = this.$refs.uploaderInput;
let that = this;
// 一:接口请求
axios.post('****').then(({data}) => {
multipart_params = data.data;
baseKey = data.data.key;
that.uploader = new plupload.Uploader({
runtimes : 'html5,flash,silverlight,html4',
browse_button: uploaderInput, //触发文件选择对话框的按钮,为那个元素id
url: data.data.host, //服务器端的上传页面地址
resize: {
width: 4200,//指定压缩后图片的宽度,如果没有设置该属性则默认为原始图片的宽度
height: 4200,//指定压缩后图片的高度,如果没有设置该属性则默认为原始图片的高度
preserve_headers: false//压缩后是否保留图片的元数据,true为保留,false为不保留,默认为true。删除图片的元数据能使图片的体积减小一点点
}
})
that.uploader.init();
// 三:点击事件 文件上传 // 获得的图片上传的地址:<https://****.aliyuncs.com/> + key
that.uploader.bind('FilesAdded', function (uploader, files) { // 限制提交的最多的张数是多少
that.defaultSetting.chooseFile = files[0];
that.set_upload_param(uploader,files[0].name, false);
});
// 四:beforeUpload 提前上传
that.uploader.bind('BeforeUpload', function (up, file) {
});
//五:上传成功
that.uploader.bind('FileUploaded', function (up, file, info) {
if(info.status === 200) {
if(that.uploaderType === 'certposter') { // 上传的是证件照合成后的海报
that.teacherCertPoster = that.uploadConfig;
that.pageStatus = 2; //打开第二个弹框
that.saveTipPopup = true;
console.log("teacherCertPoster",that.teacherCertPoster);
}else {
// 上传成功 添加为海报的内容
axios.post('***', qs.stringify({imgUrl: that.uploadConfig})
).then(res => {
that.teacherCert = 'data:image/jpg;base64,'+ res.data;
that.toImageHandled();
})
}
}else {
console.log("上传失败",info.response);
}
});
})
},
// 三:点击事件 文件上传
set_upload_param(up, filename, ret, base64tofile){
let g_object_name = baseKey + common.timestamp() + filename;
multipart_params.key = g_object_name;
multipart_params.success_action_status = '200';
up.setOption({
'url': multipart_params.host,
'multipart_params': multipart_params
});
this.uploadConfig = multipart_params.host +'/'+ g_object_name;
if(base64tofile) { // 若是上传的是本地
// 上传的base64位的图片的话 那么需要再这里单独上传
up.addFile(base64tofile);
}
up.start();
},
// 生成晒证照 需要先把base64 上传到oss 获得url地址
toImageHandled(isUpload) { // 需要在页面渲染出来之后 才可以运行 不然渲染出来 so 需要点击就它了
let that = this;
this.uploaderType = 'certposter';
setTimeout(() => { // 加缓存处理资源未加载完的坑
let el = document.getElementById('Wrapperbox');
// 解决生成的canvas在滚动的情况下 的坑
window.pageYOffset = 0;
document.documentElement.scrollTop = 0
document.body.scrollTop = 0;
html2canvas( el, {
useCORS: true,
backgroundColor: null
}).then((canvas) => {
let dataURL = canvas.toDataURL("image/png");
that.posterBase64 = dataURL;
});
},500 );
},
uploadBase64() {
if(this.posterBase64) {
let dataurl = this.posterBase64;
let _blob = dataURLtoBlob(dataurl);
let suffix = dataurl.split(';')[0].split(':')[1].split('/')[1];//文件扩展名
let filename = String(new Date().getTime())+'.'+suffix;
let _file = blobToFile(_blob, filename)
this.set_upload_param(this.uploader, '证书.png',false, _file);
}else {
this.$toast.fail({message: '您还未上传照片哦!', icon: 'close' });
}
},
三:移动端,封装成了组件的图片直传oss功能
<template>
<section class="section_box">
<Upload-oss :src.sync="imagePath" @srcChangeFun="(data)=>{ imagePath = data}"/>
或
<Upload-oss :objConfig="{name: pic.name,project: pic.project, dir: pic.dir}" :isMult="true" @srcChangeFun="srcChangeFun"/
</section>
</template>
<script>
import UploadOss from "@/components/UploadOss";
export default {
components: { UploadOss },
data() {
return {
imagePath: ''
}
},
}
</script>
- components/UploadOss/index.vue
<template>
<div>
<img ref="uploaderInput" v-if="!src" class="img180" src="<https://***.png>" alt="">
<img ref="uploaderInput" v-else-if='src.indexOf("https://") === -1' class="img180" :src="iceConfig.baseUrl +'/'+ src" />
<img ref="uploaderInput" v-else class="img180" :src="src" />
</div>
</template>
<script>
import { uploadOss } from "./uploadOss"
export default {
props: {
src: String,
isMult: {
type: Boolean,
default: false
},
objConfig: {
type: Object,
default: ()=>{}
}
},
data() {
return {
}
},
mounted() {
this.getAliyunOssConfig();
},
methods: {
async getAliyunOssConfig() {
let src = await uploadOss(this.$refs.uploaderInput, this.isMult, this.objConfig)
console.log("上传后得到的数据",src);
this.$emit('srcChangeFun',src)
},
}
}
</script>
<style>
.img180 {
width: 120px;
height: 120px;
}
</style>
- components/UploadOss/uploadOss.js
let multipart_params = {
key: '',
success_action_status: ''
};
let baseKey = '';
let defaultSetting= {
chooseFile: '',
};
let uploader={};
let uploadConfig='';
let options = {
files: [],
index: 0,
urlList: ''
};
import axios from "./node_modules/axios"
import qs from "./node_modules/qs"
import plupload from "plupload";
export function uploadOss(uploaderInput, isMult, objConfig = {}) {
return new Promise((resolve, reject)=>{
// thePath 代表处理后台上传
let thePath = objConfig.dir ;
axios.post('*****', qs.stringify({path: thePath})).then(({data}) => {
multipart_params = data.data;
baseKey = data.data.key;
uploader = new plupload.Uploader({
runtimes : 'html5,flash,silverlight,html4',
browse_button: uploaderInput, //触发文件选择对话框的按钮,为那个元素id
url: data.data.host, //服务器端的上传页面地址
filters: {
mime_types : [ //只允许上传图片和zip文件
{ title : "Image", extensions : "jpg,gif,png,jpeg" },
],
},
})
uploader.init();
// 三:点击事件 文件上传
uploader.bind('FilesAdded', function (uploader, files) { // 限制提交的最多的张数是多少
// console.log("点击事件 文件上传",files);
options.files = files;
defaultSetting.chooseFile = files[0];
if(Object.keys(objConfig).length > 0) {
// console.log("objConfig",objConfig);
if(objConfig.name) {
set_upload_param(uploader, objConfig.dir +"/"+ objConfig.project+ objConfig.name, false);
return;
}else {
set_upload_param(uploader, objConfig.dir +"/"+ objConfig.project +files[0].name, false);
return;
}
}
// 这次处理 修改了图片上传的名称为随机的32为字符 解决了图片是中文的问题
set_upload_param(uploader,baseKey + randomString()+"."+files[0].name.split(".")[1], false);
});
//五:上传成功
uploader.bind('FileUploaded', function (up, file, info) {
if(info.status === 200) {
if(!isMult) {
// 非多选的情况下 可以不要reload
// console.log("isMult",isMult );
resolve(uploadConfig);
}else{
// 这一整块的内容 是为了图片管理模块 内部批量上传网页的图片处理的 基本不改动
options.urlList = options.urlList + uploadConfig + ',';
options.index++;
if(options.index < options.files.length) { // 已经全部上传完毕
if(Object.keys(objConfig).length > 0) {
set_upload_param(uploader, objConfig.dir +"/"+ objConfig.project +options.files[options.index].name, false);
return;
}
set_upload_param(uploader, baseKey + timestamp()+ options.files[options.index].name, false);
}else {
resolve(options.urlList);
reloadData();
}
}
}else {
console.log("上传失败",info.response);
resolve('error');
reloadData();
}
});
})
})
}
// 三:点击事件 文件上传
function set_upload_param(up, filename, ret, base64tofile){
// console.log('filename',filename,"------",multipart_params);
multipart_params.key = filename;
multipart_params.success_action_status = '200';
// console.log('multipart_params',multipart_params);
up.setOption({
'url': multipart_params.host,
'multipart_params': multipart_params
});
// uploadConfig = multipart_params.host +'/'+ filename;
//上面这个是默认的https://***.aliyuncs.com 这个域名,建议不用用下面这个我们的域名
uploadConfig = '<https://****.com/'+> filename;
// console.log("需要上传图片",multipart_params,"uploadConfig",uploadConfig);
if(base64tofile) { // 若是上传的是本地
// 上传的base64位的图片的话 那么需要再这里单独上传
up.addFile(base64tofile);
}
up.start();
}
function reloadData() {
multipart_params = {};
baseKey = '';
defaultSetting= {
chooseFile: '',
};
uploader={};
uploadConfig='';
options = {
files: [],
index: 0,
urlList: ''
};
// console.log("reloadData",options);
}
function timestamp() {
var time = new Date();
var y = time.getFullYear();
var m = time.getMonth() + 1;
var d = time.getDate();
var h = time.getHours();
var mm = time.getMinutes();
var s = time.getSeconds();
return "" + y + add0(m) + add0(d) + add0(h) + add0(mm) + add0(s);
}
// 生成32位的随机数
function randomString(e) { // e表示长度 默认32位
e = e || 32;
var t = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678",a = t.length,n = "";
for(let i=0; i< e; i++) {
n += t.charAt(Math.floor(Math.random() * a));
}
return n;
}
function add0(m) {
return m < 10 ? '0' + m : m;
}