123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698 |
- <template>
- <view class="xfx-image-upload-list">
- <!-- 上传按钮 -->
- <view class="xfx-image-upload-Item xfx-image-upload-Item-add" v-if="uploadLists.length<max && add"
- @click="chooseFile">
- <uni-icons type='camera' style="font-size:60rpx"> </uni-icons>
- <!-- <u-icon name='camera-fill' size='45'></u-icon> -->
- <text class="text-upload">点击上传</text>
- </view>
- <view class="xfx-image-upload-Item" v-for="(item,index) in uploadLists" :key="item.url">
- <view class="xfx-image-upload-Item-video" v-if="(!/.(gif|jpg|jpeg|png|gif|jpg|png)$/i.test(item))">
- <image :disabled="false" :controls="false" :src="item+'?x-oss-process=video/snapshot,t_0,f_jpg'"
- mode="">
- <view class="xfx-image-upload-Item-video-fixed" @click="previewVideo(item)">
- <!-- <uni-icons type='videocam' style="font-size:60rpx"> </uni-icons> -->
- <u-icon size='80' name='play-right-fill' color="#ffffff"></u-icon>
- </view>
- <view class="xfx-image-upload-Item-del-cover" v-if="remove && previewVideoSrc==''"
- @click="imgDel(index)">×</view>
- </image>
- </view>
- <image v-else :src="item" @click="imgPreview(item)"></image>
- <view class="xfx-image-upload-Item-del" v-if="remove" @click="imgDel(index)">×</view>
- </view>
- <!-- flex布局 起占位作用 -->
- <view class="xfx-image-upload-Item" v-if="uploadLists.length<max-1">
- </view>
- <view class="preview-full" v-if="previewVideoSrc!=''">
- <video :autoplay="true" :src="previewVideoSrc" :show-fullscreen-btn="false">
- <cover-view class="preview-full-close" @click="previewVideoClose"> ×
- </cover-view>
- </video>
- </view>
- <!-- -->
- </view>
- </template>
- <style>
- </style>
- <script>
- //请求头token
- import {
- getToken
- } from '@/utils/auth'
- import UniIcons from '@/components/uni-icons/uni-icons.vue'
- export default {
- name: 'xfx-image-upload',
- props: {
- max: { //展示图片最大值
- type: Number,
- default: 6,
- },
- chooseNum: { //选择图片数
- type: Number,
- default: 6,
- },
- name: { //发到后台的文件参数名
- type: String,
- default: 'file',
- },
- remove: { //是否展示删除按钮
- type: Boolean,
- default: true,
- },
- add: { //是否展示添加按钮
- type: Boolean,
- default: true,
- },
- disabled: { //是否禁用
- type: Boolean,
- default: false,
- },
- sourceType: { //选择照片来源 【ps:H5就别费劲了,设置了也没用。不是我说的,官方文档就这样!!!】
- type: Array,
- default: () => ['album', 'camera'],
- },
- action: { //上传地址
- type: String,
- default: '',
- },
- headers: { //上传的请求头部
- type: Object,
- default: () => {
- return {
- Authorization: getToken()
- }
- },
- },
- formData: { //HTTP 请求中其他额外的 form data
- type: Object,
- default: () => {},
- },
- compress: { //是否需要压缩
- type: Boolean,
- default: true,
- },
- quality: { //压缩质量,范围0~100
- type: Number,
- default: 80,
- },
- value: { //受控图片列表
- type: Array,
- default: () => [],
- },
- uploadSuccess: {
- default: (res) => {
- return {
- success: false,
- url: ''
- }
- },
- },
- mediaType: { //文件类型 image/video/all
- type: String,
- default: 'image',
- },
- maxDuration: { //拍摄视频最长拍摄时间,单位秒。最长支持 60 秒。 (只针对拍摄视频有用)
- type: Number,
- default: 60,
- },
- camera: { //'front'、'back',默认'back'(只针对拍摄视频有用)
- type: String,
- default: 'back',
- },
- },
- components: {
- UniIcons
- },
- data() {
- return {
- uploadLists: [],
- mediaTypeData: ['image', 'video', 'all'],
- previewVideoSrc: '',
- // header:{
- // 'Authorization':''
- // }
- }
- },
- mounted: function() {
- console.log(this.action)
- this.headers.Authorization = getToken()
- console.log(this.headers)
- this.$nextTick(function() {
- this.uploadLists = this.value;
- if (this.mediaTypeData.indexOf(this.mediaType) == -1) {
- uni.showModal({
- title: '提示',
- content: 'mediaType参数不正确',
- showCancel: false,
- success: function(res) {
- if (res.confirm) {
- //console.log('用户点击确定');
- } else if (res.cancel) {
- //console.log('用户点击取消');
- }
- }
- });
- }
- });
- },
- watch: {
- value(val, oldVal) {
- console.log('value', val, oldVal)
- this.uploadLists = val;
- },
- },
- methods: {
- previewVideo(src) {
- this.previewVideoSrc = src;
- // this.previewVideoSrc =
- // 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-fbd63a76-dc76-485c-b711-f79f2986daeb/ba804d82-860b-4d1a-a706-5a4c8ce137c3.mp4'
- },
- previewVideoClose() {
- this.previewVideoSrc = ''
- console.log('previewVideoClose', this.previewVideoSrc)
- },
- imgDel(index) {
- uni.showModal({
- title: '提示',
- content: '您确定要删除么?',
- success: (res) => {
- if (res.confirm) {
- // this.uploadLists.splice(index, 1)
- // this.$emit("input", this.uploadLists);
- // this.$emit("imgDelete", this.uploadLists);
- let delUrl = this.uploadLists[index]
- this.uploadLists.splice(index, 1)
- this.$emit("input", this.uploadLists);
- this.$emit("imgDelete", {
- del: delUrl,
- tempFilePaths: this.uploadLists
- });
- } else if (res.cancel) {}
- }
- });
- },
- imgPreview(index) {
- var imgData = this.uploadLists.filter(item => /.(gif|jpg|jpeg|png|gif|jpg|png)$/i.test(item)) //只预览图片的
- uni.previewImage({
- urls: imgData,
- current: index,
- loop: true,
- });
- },
- chooseFile() {
- if (this.disabled) {
- return false;
- }
- switch (this.mediaTypeData.indexOf(this.mediaType)) {
- case 1: //视频
- this.videoAdd();
- break;
- case 2: //全部
- uni.showActionSheet({
- itemList: ['相册', '视频'],
- success: (res) => {
- if (res.tapIndex == 1) {
- this.videoAdd();
- } else if (res.tapIndex == 0) {
- this.imgAdd();
- }
- },
- fail: (res) => {
- console.log(res.errMsg);
- }
- });
- break;
- default: //图片
- this.imgAdd();
- break;
- }
- //if(this.mediaType=='image'){
- },
- videoAdd() {
- console.log('videoAdd')
- let nowNum = Math.abs(this.uploadLists.length - this.max);
- let thisNum = (this.chooseNum > nowNum ? nowNum : this.chooseNum) //可选数量
- uni.chooseVideo({
- compressed: this.compress,
- sourceType: this.sourceType,
- camera: this.camera,
- maxDuration: this.maxDuration,
- success: (res) => {
- console.log('videoAdd', res)
- console.log(res.tempFilePath)
- this.chooseSuccessMethod([res.tempFilePath], 1)
- //this.imgUpload([res.tempFilePath]);
- //console.log('tempFiles', res)
- // if (this.action == '') { //未配置上传路径
- // this.$emit("chooseSuccess", res.tempFilePaths);
- // } else {
- // if (this.compress && (res.tempFiles[0].size / 1024 > 1025)) { //设置了需要压缩 并且 文件大于1M,进行压缩上传
- // this.imgCompress(res.tempFilePaths);
- // } else {
- // this.imgUpload(res.tempFilePaths);
- // }
- // }
- }
- });
- },
- imgAdd() {
- console.log('imgAdd')
- let nowNum = Math.abs(this.uploadLists.length - this.max);
- let thisNum = (this.chooseNum > nowNum ? nowNum : this.chooseNum) //可选数量
- console.log('nowNum', nowNum)
- console.log('thisNum', thisNum)
- // #ifdef APP-PLUS
- if (this.sourceType.length > 1) {
- uni.showActionSheet({
- itemList: ['拍摄', '从手机相册选择'],
- success: (res) => {
- if (res.tapIndex == 1) {
- this.appGallery(thisNum);
- } else if (res.tapIndex == 0) {
- this.appCamera();
- }
- },
- fail: (res) => {
- console.log(res.errMsg);
- }
- });
- }
- if (this.sourceType.length == 1 && this.sourceType.indexOf('album') > -1) {
- this.appGallery(thisNum);
- }
- if (this.sourceType.length == 1 && this.sourceType.indexOf('camera') > -1) {
- this.appCamera();
- }
- // #endif
- //#ifndef APP-PLUS
- uni.chooseImage({
- count: thisNum,
- sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
- sourceType: this.sourceType,
- success: (res) => {
- this.chooseSuccessMethod(res.tempFilePaths, 0)
- //console.log('tempFiles', res)
- // if (this.action == '') { //未配置上传路径
- // this.$emit("chooseSuccess", res.tempFilePaths);
- // } else {
- // if (this.compress && (res.tempFiles[0].size / 1024 > 1025)) { //设置了需要压缩 并且 文件大于1M,进行压缩上传
- // this.imgCompress(res.tempFilePaths);
- // } else {
- // this.imgUpload(res.tempFilePaths);
- // }
- // }
- }
- });
- // #endif
- },
- appCamera() {
- var cmr = plus.camera.getCamera();
- var res = cmr.supportedImageResolutions[0];
- var fmt = cmr.supportedImageFormats[0];
- //console.log("Resolution: " + res + ", Format: " + fmt);
- cmr.captureImage((path) => {
- //alert("Capture image success: " + path);
- this.chooseSuccessMethod([path], 0)
- },
- (error) => {
- //alert("Capture image failed: " + error.message);
- console.log("Capture image failed: " + error.message)
- }, {
- resolution: res,
- format: fmt
- }
- );
- },
- appGallery(maxNum) {
- plus.gallery.pick((res) => {
- this.chooseSuccessMethod(res.files, 0)
- }, function(e) {
- //console.log("取消选择图片");
- }, {
- filter: "image",
- multiple: true,
- maximum: maxNum
- });
- },
- chooseSuccessMethod(filePaths, type) {
- if (this.action == '') { //未配置上传路径
- // this.value.push({url:filePaths[0]})
- // console.log(this.value)
- // this.uploadLists.push({url:filePaths[0]})
- this.$emit("chooseSuccess", filePaths, type); //filePaths 路径 type 0 为图片 1为视频
- } else {
- if (type == 1) {
- this.imgUpload(filePaths);
- } else {
- if (this.compress) { //设置了需要压缩
- this.imgCompress(filePaths);
- } else {
- this.imgUpload(filePaths);
- }
- }
- }
- },
- imgCompress(tempFilePaths) {
- uni.showLoading({
- title: '压缩中...'
- });
- let compressImgs = [];
- let results = [];
- tempFilePaths.forEach((item, index) => {
- compressImgs.push(new Promise((resolve, reject) => {
- // #ifndef H5
- uni.compressImage({
- src: item,
- quality: this.quality,
- success: res => {
- //console.log('compressImage', res.tempFilePath)
- results.push(res.tempFilePath);
- resolve(res.tempFilePath);
- },
- fail: (err) => {
- //console.log(err.errMsg);
- reject(err);
- },
- complete: () => {
- //uni.hideLoading();
- }
- })
- // #endif
- // #ifdef H5
- this.canvasDataURL(item, {
- quality: this.quality / 100
- }, (base64Codes) => {
- //this.imgUpload(base64Codes);
- results.push(base64Codes);
- resolve(base64Codes);
- })
- // #endif
- }))
- })
- Promise.all(compressImgs) //执行所有需请求的接口
- .then((results) => {
- uni.hideLoading();
- console.log('imgUpload', results)
- this.imgUpload(results);
- })
- .catch((res, object) => {
- uni.hideLoading();
- });
- },
- imgUpload(tempFilePaths) {
- // if (this.action == '') {
- // uni.showToast({
- // title: '未配置上传地址',
- // icon: 'none',
- // duration: 2000
- // });
- // return false;
- // }
- uni.showLoading({
- title: '上传中'
- });
- console.log('imgUpload', tempFilePaths)
- let uploadImgs = [];
- tempFilePaths.forEach((item, index) => {
- uploadImgs.push(new Promise((resolve, reject) => {
- // console.log(index, item)
- const uploadTask = uni.uploadFile({
- url: this.action, //仅为示例,非真实的接口地址
- filePath: item,
- name: this.name,
- fileType: 'image',
- formData: this.formData,
- header: this.headers,
- success: (uploadFileRes) => {
- //uni.hideLoading();
- //console.log(typeof this.uploadSuccess)
- //console.log('')
- if (typeof this.uploadSuccess == 'function') {
- if (this.uploadSuccess(uploadFileRes).success) {
- this.value.push(this.uploadSuccess(uploadFileRes)
- .url)
- this.$emit("input", this.uploadLists);
- }
- }
- resolve(uploadFileRes);
- this.$emit("uploadSuccess", uploadFileRes);
- },
- fail: (err) => {
- console.log(err);
- //uni.hideLoading();
- reject(err);
- this.$emit("uploadFail", err);
- },
- complete: () => {
- //uni.hideLoading();
- }
- });
- }))
- })
- Promise.all(uploadImgs) //执行所有需请求的接口
- .then((results) => {
- uni.hideLoading();
- })
- .catch((res, object) => {
- uni.hideLoading();
- this.$emit("uploadFail", res);
- });
- // uploadTask.onProgressUpdate((res) => {
- // //console.log('',)
- // uni.showLoading({
- // title: '上传中' + res.progress + '%'
- // });
- // if (res.progress == 100) {
- // uni.hideLoading();
- // }
- // });
- },
- canvasDataURL(path, obj, callback) {
- var img = new Image();
- img.src = path;
- img.onload = function() {
- var that = this;
- // 默认按比例压缩
- var w = that.width,
- h = that.height,
- scale = w / h;
- w = obj.width || w;
- h = obj.height || (w / scale);
- var quality = 0.8; // 默认图片质量为0.8
- //生成canvas
- var canvas = document.createElement('canvas');
- var ctx = canvas.getContext('2d');
- // 创建属性节点
- var anw = document.createAttribute("width");
- anw.nodeValue = w;
- var anh = document.createAttribute("height");
- anh.nodeValue = h;
- canvas.setAttributeNode(anw);
- canvas.setAttributeNode(anh);
- ctx.drawImage(that, 0, 0, w, h);
- // 图像质量
- if (obj.quality && obj.quality <= 1 && obj.quality > 0) {
- quality = obj.quality;
- }
- // quality值越小,所绘制出的图像越模糊
- var base64 = canvas.toDataURL('image/jpeg', quality);
- // 回调函数返回base64的值
- callback(base64);
- }
- },
- }
- }
- </script>
- <style>
- .preview-full {
- position: fixed;
- top: 0;
- left: 0;
- bottom: 0;
- width: 100%;
- height: 100%;
- z-index: 1002;
- }
- .preview-full video {
- width: 100%;
- height: 100%;
- z-index: 1002;
- }
- .preview-full-close {
- position: fixed;
- right: 32rpx;
- top: 25rpx;
- width: 80rpx;
- height: 80rpx;
- line-height: 60rpx;
- text-align: center;
- z-index: 1003;
- /* background-color: #808080; */
- color: #fff;
- font-size: 65rpx;
- font-weight: bold;
- text-shadow: 1px 2px 5px rgb(0 0 0);
- }
- /* .preview-full-close-before,
- .preview-full-close-after {
- position: absolute;
- top: 50%;
- left: 50%;
- content: '';
- height: 60rpx;
- margin-top: -30rpx;
- width: 6rpx;
- margin-left: -3rpx;
- background-color: #FFFFFF;
- z-index: 20000;
- }
- .preview-full-close-before {
- transform: rotate(45deg);
- }
- .preview-full-close-after {
- transform: rotate(-45deg);
- } */
- .xfx-image-upload-list {
- display: flex;
- flex-wrap: wrap;
- justify-content: space-between;
- }
- .xfx-image-upload-Item {
- width: 190rpx;
- height: 190rpx;
- margin-right: 25rpx;
- /* margin: 13rpx; */
- border-radius: 12rpx;
- position: relative;
- margin-bottom: 30rpx;
- }
- .xfx-image-upload-Item:nth-child(3n) {
- margin-right: 0;
- }
- .xfx-image-upload-Item image {
- width: 100%;
- height: 100%;
- border-radius: 12rpx;
- }
- .xfx-image-upload-Item-video {
- width: 100%;
- height: 100%;
- border-radius: 12rpx;
- position: relative;
- }
- .xfx-image-upload-Item-video-fixed {
- position: absolute;
- top: 0;
- left: 0;
- bottom: 0;
- width: 100%;
- height: 100%;
- border-radius: 12rpx;
- display: flex;
- justify-content: center;
- align-items: center;
- z-index: 50;
- }
- .xfx-image-upload-Item video {
- width: 100%;
- height: 100%;
- border-radius: 10rpx;
- }
- .xfx-image-upload-Item-add {
- /* font-size: 105rpx; */
- /* line-height: 160rpx; */
- padding-top: 56rpx;
- box-sizing: border-box;
- text-align: center;
- background-color: #F6F7F8;
- display: flex;
- flex-direction: column;
- align-items: center;
- }
- .text-upload {
- font-size: 24rpx;
- line-height: 33rpx;
- color: #A4A8AC;
- display: block;
- margin-top: 16rpx;
- }
- .xfx-image-upload-Item-del {
- border-radius: 50%;
- background-color: #F13629;
- font-size: 24rpx;
- position: absolute;
- width: 36rpx;
- height: 36rpx;
- line-height: 35rpx;
- text-align: center;
- top: -18rpx;
- right: -18rpx;
- z-index: 51;
- color: #fff;
- }
- .xfx-image-upload-Item-del-cover {
- border-radius: 50%;
- background-color: #F13629;
- font-size: 24rpx;
- position: absolute;
- width: 36rpx;
- height: 36rpx;
- text-align: center;
- top: -18rpx;
- right: -18rpx;
- color: #fff;
- /* #ifdef APP-PLUS */
- line-height: 25rpx;
- /* #endif */
- /* #ifndef APP-PLUS */
- line-height: 35rpx;
- /* #endif */
- z-index: 51;
- }
- </style>
|