@@ -9,7 +9,8 @@ | |||
<view class="cu-form-group" style="border-top: none;"> | |||
<view class="grid col-4 grid-square flex-sub"> | |||
<view v-for="(file, index) in value" :key="index" class="bg-img"> | |||
<view v-for="(file, index) in value" :key="index" class="bg-img" style="position: relative;"> | |||
<view v-if="file.noUpdated" class="mask"></view> | |||
<image | |||
v-if="isImgFile(file.type)" | |||
@click="fileClick(index)" | |||
@@ -20,11 +21,14 @@ | |||
<view v-else-if="isDocFile(file.type)" @click="fileClick(index)" class="file-icon solids"> | |||
<l-icon type="text" /> | |||
</view> | |||
<view v-else class="file-icon solids"><l-icon type="text" /></view> | |||
<view v-else class="file-icon solids" @click="fileClick(index)"><l-icon type="text" /></view> | |||
<view v-if="!readonly" @click.stop="delFile(index)" class="cu-tag bg-red" style="height: 24px; width: 24px;"> | |||
<view v-if="!readonly" @click.stop="delFile(index,file.uid)" class="cu-tag bg-red" style="height: 24px; width: 24px;"> | |||
<l-icon type="close" color="white" style="width: 18px; height: 24px; font-size: 24px;" /> | |||
</view> | |||
<view class="fileName"> | |||
<text>{{file.name}}</text> | |||
</view> | |||
</view> | |||
<view v-if="!readonly && value.length < Number(number)" @click="chooseFile" class="solids"> | |||
@@ -54,8 +58,7 @@ export default { | |||
isImgFile(type) { | |||
const typeString = (type || '').toLowerCase() | |||
//return ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'image'].includes(typeString) | |||
return true; | |||
return ['jpg','image/jpg','jpeg','image/jpeg', 'png', 'image/png','gif', 'image/gif','bmp', 'image/bmp','webp', 'image/webp','image'].includes(typeString) | |||
}, | |||
isDocFile(type) { | |||
@@ -63,12 +66,17 @@ export default { | |||
return ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf'].includes(typeString) | |||
}, | |||
delFile(index) { | |||
async delFile(index,fileId) { | |||
if (!(await this.CONFIRM('删除文件', '确定要删除该文件吗?', true))) { | |||
return | |||
} | |||
const newList = JSON.parse(JSON.stringify(this.value)) | |||
newList.splice(index, 1) | |||
this.$emit('input', newList) | |||
this.$emit('change') | |||
this.$emit('del') | |||
//物理删除 | |||
this.DELETE_FILE(fileId); | |||
}, | |||
chooseFile() { | |||
@@ -89,60 +97,84 @@ export default { | |||
// #endif | |||
// #ifndef MP-DINGTALK | |||
uni.chooseImage({ | |||
count: Number(this.number), | |||
sizeType: ['original', 'compressed'], | |||
sourceType: ['album', 'camera'], | |||
success: ({ tempFilePaths }) => { | |||
const newList = JSON.parse(JSON.stringify(this.value || [])).concat( | |||
tempFilePaths//.map(t => ({ path: t, type: this.getFileExt(t) })) | |||
) | |||
this.$emit('input', newList) | |||
this.$emit('change', newList) | |||
this.$emit('add') | |||
} | |||
}) | |||
// uni.chooseFile({ | |||
// count: Number(this.number), | |||
// sizeType: ['original', 'compressed'], | |||
// sourceType: ['album', 'camera'], | |||
// success: ({ tempFilePaths }) => { | |||
// const newList = JSON.parse(JSON.stringify(this.value || [])).concat( | |||
// tempFilePaths//.map(t => ({ path: t, type: this.getFileExt(t) })) | |||
// ) | |||
// this.$emit('input', newList) | |||
// this.$emit('change', newList) | |||
// this.$emit('add') | |||
// } | |||
// }) | |||
uni.chooseFile({ | |||
count: Number(this.number), | |||
sizeType: ['original', 'compressed'], | |||
sourceType: ['album', 'camera'], | |||
success: ({ tempFilePaths,tempFiles }) => { | |||
const newList = JSON.parse(JSON.stringify(this.value || [])).concat( | |||
// tempFilePaths//.map(t => ({ path: t, type: this.getFileExt(t) })) | |||
tempFilePaths.map((t,i) => ({ path: t, type: tempFiles[i].type, size:tempFiles[i].size, name:tempFiles[i].name, noUpdated:true} )) | |||
) | |||
this.$emit('input', newList) | |||
this.$emit('change', newList) | |||
this.$emit('add') | |||
} | |||
}) | |||
// #endif | |||
}, | |||
async fileClick(index) { | |||
// if(typeof this.value[index] == "string"){ | |||
// uni.previewImage({ urls: this.value.filter(item=>typeof this.value[index] == "string"), current: this.value[index] }) | |||
// return | |||
// } | |||
const { path, type, uid, size = 0 } = this.value[index] | |||
if (this.isImgFile(type)) { | |||
uni.previewImage({ urls: [path], current: path }) | |||
} else if (this.isDocFile(type)) { | |||
// #ifndef H5 || MP-DINGTALK | |||
if (size >= 50 * 1024 * 1024) { | |||
this.TOAST('小程序端无法下载超过50MB的文件,此文件大小为${size}KB,超过限制') | |||
return | |||
} | |||
// #endif | |||
// #ifndef MP-DINGTALK | |||
const tempFilePath = await this.HTTP_DOWNLOAD(uid) | |||
uni.openDocument({ filePath: tempFilePath, fileType: type }) | |||
// #endif | |||
// #ifdef MP-DINGTALK | |||
this.TOAST('钉钉小程序只支持查看图片文件') | |||
// #endif | |||
} else { | |||
// #ifndef MP-DINGTALK | |||
this.TOAST('小程序端只支持打开图片和文档(word、pdf等)文件') | |||
// #endif | |||
// #ifdef MP-DINGTALK | |||
this.TOAST('钉钉小程序只支持查看图片文件') | |||
// #endif | |||
// #ifdef APP-VUE | |||
const tempFilePath = await this.HTTP_DOWNLOAD(uid) | |||
uni.openDocument({ filePath: tempFilePath, fileType: type }) | |||
// #endif | |||
// #ifdef H5 | |||
await this.HTTP_DOWNLOAD(uid) | |||
// #endif | |||
} | |||
if (this.isImgFile(type)) { | |||
uni.previewImage({ urls: [path], current: path }) | |||
}else{ | |||
uni.openDocument({ filePath: path, fileType: type }) | |||
} | |||
// if (this.isImgFile(type)) { | |||
// uni.previewImage({ urls: [path], current: path }) | |||
// } else if (this.isDocFile(type)) { | |||
// // #ifndef H5 || MP-DINGTALK | |||
// if (size >= 50 * 1024 * 1024) { | |||
// this.TOAST('小程序端无法下载超过50MB的文件,此文件大小为${size}KB,超过限制') | |||
// return | |||
// } | |||
// // #endif | |||
// // #ifndef MP-DINGTALK | |||
// const tempFilePath = await this.HTTP_DOWNLOAD(uid) | |||
// uni.openDocument({ filePath: tempFilePath, fileType: type }) | |||
// // #endif | |||
// // #ifdef MP-DINGTALK | |||
// this.TOAST('钉钉小程序只支持查看图片文件') | |||
// // #endif | |||
// } else { | |||
// // #ifndef MP-DINGTALK | |||
// this.TOAST('小程序端只支持打开图片和文档(word、pdf等)文件') | |||
// // #endif | |||
// // #ifdef MP-DINGTALK | |||
// this.TOAST('钉钉小程序只支持查看图片文件') | |||
// // #endif | |||
// // #ifdef APP-VUE | |||
// const tempFilePath = await this.HTTP_DOWNLOAD(uid) | |||
// uni.openDocument({ filePath: tempFilePath, fileType: type }) | |||
// // #endif | |||
// // #ifdef H5 | |||
// await this.HTTP_DOWNLOAD(uid) | |||
// // #endif | |||
// } | |||
} | |||
} | |||
} | |||
@@ -153,4 +185,29 @@ export default { | |||
line-height: 100%; | |||
position: static; | |||
} | |||
.fileName{ | |||
padding: 2px 2px; | |||
margin-bottom: 2px; | |||
text-align: center; | |||
position: absolute; | |||
bottom: 0px; | |||
width: 100%; | |||
background: rgba(0,0,0,0.2); | |||
color: #fff; | |||
font-size: 12px; | |||
text-overflow: ellipsis; | |||
overflow: hidden; | |||
white-space: nowrap; | |||
} | |||
.mask{ | |||
position: absolute; | |||
top: 0;left: 0; | |||
width: 100%; | |||
height: 100%; | |||
// background: rgba(255,252,153,0.2); | |||
background: rgba(0,0,0,0.7); | |||
z-index: 100; | |||
pointer-events: none; | |||
} | |||
</style> |
@@ -2,26 +2,27 @@ | |||
<view class="cu-form-group"> | |||
<view class="grid col-4 grid-square flex-sub"> | |||
<view | |||
v-for="(path, index) in value" | |||
@tap="viewImg" | |||
v-for="(item, index) in imgList" | |||
@tap="viewImg(index)" | |||
:key="index" | |||
class="bg-img" | |||
> | |||
<!-- {{item.id?CONFIG('webHost')+item.url:item.url}} --> | |||
<image | |||
v-if="showfile()" | |||
:src="path.path ? path.path : path" | |||
:src="item.id?CONFIG('webHost')+item.url:item.url" | |||
mode="aspectFill" | |||
></image> | |||
<view v-if="!readonly" @tap.stop="delImg(index)" class="cu-tag bg-red"> | |||
<view v-if="!readonly" @tap.stop="delImg(index)" class="cu-tag bg-red" style="width: 18px; height: 18px; font-size: 24px"> | |||
<l-icon | |||
type="close" | |||
style="width: 18px; height: 24px; font-size: 24px" | |||
style="width: 18px; height: 18px; font-size: 12px" | |||
/> | |||
</view> | |||
</view> | |||
<view | |||
v-if="!readonly && value.length < Number(number)" | |||
v-if="!readonly && imgList.length < Number(number)" | |||
@tap="chooseImg" | |||
class="solids" | |||
> | |||
@@ -40,44 +41,190 @@ export default { | |||
readonly: {}, | |||
value: { default: () => [] }, | |||
}, | |||
data(){ | |||
return{ | |||
imgList:[], | |||
} | |||
}, | |||
methods: { | |||
delImg(index) { | |||
const newList = JSON.parse(JSON.stringify(this.value)); | |||
const newList = JSON.parse(JSON.stringify(this.imgList)); | |||
newList.splice(index, 1); | |||
this.imgList = newList | |||
this.$emit("update:value", newList); | |||
this.$emit("input", newList); | |||
this.$emit("change"); | |||
this.$emit("del"); | |||
}, | |||
showfile() { | |||
console.log(this.value); | |||
return true; | |||
}, | |||
chooseImg() { | |||
uni.chooseImage({ | |||
count: Number(this.number), | |||
count: (Number(this.number) - this.imgList.length), | |||
sizeType: ["original", "compressed"], | |||
sourceType: ["album", "camera"], | |||
success: ({ tempFilePaths }) => { | |||
const newList = JSON.parse(JSON.stringify(this.value || [])).concat( | |||
tempFilePaths | |||
success: (res) => { | |||
let {tempFilePaths,tempFiles} = res | |||
if(!this.validate(tempFiles))return | |||
const newList = JSON.parse(JSON.stringify(this.imgList || [])).concat( | |||
tempFilePaths.map(item=>{ | |||
return{ | |||
url:item, | |||
id:'' | |||
} | |||
}) | |||
); | |||
//this.$parent.HTTP_UPLOAD(tempFilePaths[0]); | |||
this.imgList = newList | |||
this.$emit("update:value", newList); | |||
this.$emit("input", newList); | |||
this.$emit("change"); | |||
this.$emit("change",newList); | |||
this.$emit("add"); | |||
}, | |||
}); | |||
}, | |||
uploadImage(){ | |||
// 单图上传 | |||
return new Promise(async (reslove,reject)=>{ | |||
let hasNotUpdatedList = this.imgList.every(item=>item.id) | |||
if(hasNotUpdatedList){ | |||
reslove(this.imgList) | |||
} | |||
if(this.imgList.length){ | |||
var postData = { | |||
Base64Url: await this.imgToBase64(this.imgList[0].url) | |||
} | |||
this.HTTP_POST('StuInfoFresh/savePhoto', postData, '图片上传失败!').then((data) => { | |||
if (data) { | |||
reslove([{ | |||
url:data.Url, | |||
id:data.AnnexesFileId | |||
}]) | |||
}else{ | |||
reject('图片上传失败!') | |||
} | |||
}) | |||
}else{ | |||
reslove("") | |||
} | |||
}) | |||
}, | |||
/** | |||
* @description 控制promise.all并发数量 | |||
* @param limit 并发数 | |||
* @param array 参数列表 | |||
* @param apiFn 执行函数 | |||
* @returns {Promise<Awaited<unknown>[]>} | |||
*/ | |||
async promiseAllLimit(limit, array, apiFn) { | |||
const ret = [] // 用于存放所有的promise实例 | |||
const executing = [] // 用于存放目前正在执行的promise | |||
for (const item of array) { | |||
const p = apiFn(item) | |||
ret.push(p) | |||
if (limit <= array.length) { | |||
// then回调中,当这个promise状态变为fulfilled后,将其从正在执行的promise列表executing中删除 | |||
const e = p.then(() => executing.splice(executing.indexOf(e), 1)) | |||
executing.push(e) | |||
if (executing.length >= limit) { | |||
// 一旦正在执行的promise列表数量等于限制数,就使用Promise.race等待某一个promise状态发生变更, | |||
// 状态变更后,就会执行上面then的回调,将该promise从executing中删除, | |||
// 然后再进入到下一次for循环,生成新的promise进行补充 | |||
await Promise.race(executing) | |||
} | |||
} | |||
} | |||
return Promise.all(ret) | |||
}, | |||
imgToBase64(url){ | |||
return new Promise((resolve,reject)=>{ | |||
if(!url){ | |||
resolve("") | |||
} | |||
var canvas = document.createElement('canvas'), | |||
ctx = canvas.getContext('2d'), | |||
img = new Image; | |||
img.crossOrigin = 'Anonymous'; | |||
img.onload = function () { | |||
canvas.height = img.height; | |||
canvas.width = img.width; | |||
ctx.drawImage(img, 0, 0); | |||
var dataURL = canvas.toDataURL('image/png'); | |||
canvas = null; | |||
resolve(dataURL) | |||
}; | |||
img.src = url; | |||
}) | |||
}, | |||
validate(array){ | |||
// let type = array.every(item=>{ | |||
// return item.type && item.type.substring(0,6) == "image/" | |||
// }) | |||
// if(!type){ | |||
// this.TOAST('文件类型错误'); | |||
// return false | |||
// } | |||
let size = array.every(item=>{ | |||
return item.size && item.size <= 100 * 1024 * 1024 | |||
}) | |||
if(!size){ | |||
this.TOAST('文件大小不得超过100M'); | |||
return false | |||
} | |||
return true | |||
}, | |||
viewImg(index) { | |||
uni.previewImage({ | |||
urls: this.value, | |||
current: this.value[index], | |||
urls: this.imgList.map(item=>item.id?this.CONFIG('webHost')+item.url:item.url), | |||
current: this.imgList[index].id?this.CONFIG('webHost')+this.imgList[index].url:this.imgList[index].url, | |||
}); | |||
}, | |||
// previewFile() { | |||
// var file = document.querySelector('input[type=file]').files[0]; | |||
// var reader = new FileReader(); | |||
// // fileReader.readAsDataURL(blob); | |||
// // fileReader.onerror = () => { | |||
// // reject(new Error('blobToBase64 error')); | |||
// // }; | |||
// // var encodedData = window.btoa("Hello, world"); | |||
// reader.onloadend = function () { | |||
// //$('#PhotoImg').attr('src', reader.result); | |||
// var postData = { | |||
// Base64Url: reader.result | |||
// } | |||
// this.HTTP_POST(config.webapi + "StuInfoFresh/savePhoto", postData, (data) => { | |||
// if (data) { | |||
// $('#Photo').val(data.AnnexesFileId); | |||
// $('#PhotoImg').attr('src', config.web + data.Url); | |||
// } else { | |||
// learun.layer.toast('采集照片信息失败!'); | |||
// } | |||
// }); | |||
// } | |||
// if (file) { | |||
// reader.readAsDataURL(file); | |||
// } | |||
// }, | |||
}, | |||
created() { | |||
console.log(123) | |||
this.imgList = JSON.parse(JSON.stringify(this.value.map(item=>{ | |||
item.isUploaded = true | |||
return item | |||
}))) | |||
// [{url:"",id:""}] | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,217 @@ | |||
<template> | |||
<view> | |||
<view class="cu-form-group" style="border-bottom: none; padding-bottom: 0;"> | |||
<view class="title"> | |||
<text v-if="required" class="lr-required">*</text> | |||
{{ title || '' }} | |||
</view> | |||
</view> | |||
<view class="cu-form-group"> | |||
<view class="grid col-4 grid-square flex-sub"> | |||
<view v-for="(item, index) in imgList" @tap="viewImg(item)" :key="index" class="bg-img"> | |||
<image v-if="showfile()&&item&&(typeof item == 'string'||isImage(item.type))" :src="item.url?CONFIG('webHost') + item.url:item" mode="aspectFill"> | |||
</image> | |||
<l-icon v-if="showfile()&&!isImage(item.type)" type="text" /> | |||
<text class="file-name">{{item.name}}</text> | |||
<view v-if="!readonly" @tap.stop="delImg(index)" class="cu-tag bg-red" | |||
style="width: 18px; height: 18px; font-size: 24px"> | |||
<l-icon type="close" style="width: 18px; height: 18px; font-size: 12px" /> | |||
</view> | |||
</view> | |||
<view v-show="!readonly && imgList.length < Number(number)&&isShow" class="solids"> | |||
<l-icon type="file" /> | |||
<lsj-upload ref="lsjUpload" height="80px" width="100%" :size="20" :option="{}" :count="1" | |||
@change="chooseChange" style="opacity: 0;"></lsj-upload> | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
</template> | |||
<script> | |||
/** | |||
* 附件上传组件 | |||
* 直接选择手机文件 | |||
* | |||
* 注意:可以是图片、文档、等; | |||
*/ | |||
export default { | |||
props: { | |||
number: { | |||
default: 1 | |||
}, | |||
readonly: {}, | |||
value: { | |||
default: () => [] | |||
}, | |||
folderId: {}, | |||
title: {}, | |||
required: {} | |||
}, | |||
data() { | |||
return { | |||
isShow: false, | |||
imgList: [], | |||
} | |||
}, | |||
methods: { | |||
chooseChange(files) { | |||
let array = Array.from(files); | |||
if (array.length) { | |||
this.$refs.lsjUpload.clear() | |||
} | |||
let tempFilePaths = [], | |||
tempFiles = []; | |||
array.forEach(item => { | |||
tempFilePaths.push(item[1].path) | |||
tempFiles.push(item[1].file) | |||
}) | |||
this.chooseChangeback(tempFilePaths, tempFiles) | |||
}, | |||
delImg(index) { | |||
this.CONFIRM("", "是否确认删除?", true).then(res => { | |||
if(!res)return | |||
this.LOADING('正在删除…'); | |||
const newList = JSON.parse(JSON.stringify(this.imgList)); | |||
this.HTTP_POST('/learun/adms/annexes/wxdelete', this.imgList[index].id, "文件删除失败").then((data) => { | |||
this.HIDE_LOADING(); | |||
if (data) { | |||
newList.splice(index, 1); | |||
this.imgList = newList | |||
this.$emit("update:value", newList); | |||
this.$emit("input", newList); | |||
this.$emit("change"); | |||
this.$emit("del"); | |||
} | |||
}) | |||
}) | |||
}, | |||
showfile() { | |||
return true; | |||
}, | |||
async chooseChangeback(tempFilePaths, tempFiles) { | |||
let uploadImageRes = await this.uploadImage(tempFilePaths[0], tempFiles[0] ? tempFiles[0].name : "") | |||
let newList = this.imgList || [] | |||
if (uploadImageRes) { | |||
//请求‘获取附件列表’接口 | |||
let data = await this.FETCH_FILEList(uploadImageRes); | |||
if(data){ | |||
newList = data.map(t=>({ | |||
id: t.F_Id, | |||
name: t.F_FileName, | |||
url: t.F_FilePath.substring(t.F_FilePath.indexOf('Resource')), | |||
type: t.F_FileType, | |||
folderid:t.F_FolderId, | |||
})) | |||
} | |||
} | |||
this.imgList = newList | |||
this.$emit("update:value", newList); | |||
this.$emit("input", newList); | |||
this.$emit("change", newList); | |||
}, | |||
uploadImage(url, name) { | |||
if (!url) return | |||
// 文件上传 | |||
return new Promise(async (reslove, reject) => { | |||
this.LOADING('正在上传…'); | |||
let params = name ? { | |||
folderId: this.folderId, | |||
name | |||
} : { | |||
folderId: this.folderId | |||
} | |||
this.HTTP_UPLOAD2('/learun/adms/annexes/wxuploadinsingle', url, params).then((data) => { | |||
this.HIDE_LOADING(); | |||
this.$refs.lsjUpload.show() | |||
if (data) { | |||
reslove(data) | |||
} else { | |||
reject('上传失败!') | |||
} | |||
}) | |||
}) | |||
}, | |||
validate(array) { | |||
// let type = array.every(item=>{ | |||
// return item.type && item.type.substring(0,6) == "image/" | |||
// }) | |||
// if(!type){ | |||
// this.TOAST('文件类型错误'); | |||
// return false | |||
// } | |||
let size = array.every(item => { | |||
return item.size && item.size <= 200 * 1024 * 1024 | |||
}) | |||
if (!size) { | |||
this.TOAST('文件大小不得超过200M'); | |||
return false | |||
} | |||
return true | |||
}, | |||
isImage(type) { | |||
if (type && type.length) { | |||
return ["png", "jpg"].includes(type.substring(type.length - 3, type.length)) | |||
} else { | |||
return false | |||
} | |||
}, | |||
viewImg(item) { | |||
if (!this.isImage(item.type)) { | |||
window.location.href = this.CONFIG("webHost") + item.url | |||
} else { | |||
uni.previewImage({ | |||
urls: [this.CONFIG('webHost') + item.url], | |||
current: this.CONFIG('webHost') + item.url | |||
}); | |||
} | |||
}, | |||
}, | |||
created() { | |||
// console.log(this.value) | |||
this.imgList = JSON.parse(JSON.stringify(this.value.map(item => { | |||
return { | |||
id: item.F_Id, | |||
name: item.F_FileName, | |||
url: item.F_FilePath.substring(item.F_FilePath.indexOf('Resource')), | |||
type: item.F_FileType, | |||
folderid:item.F_FolderId, | |||
} | |||
}))) | |||
this.$nextTick(() => { | |||
this.isShow = true | |||
}) | |||
} | |||
}; | |||
</script> | |||
<style scoped> | |||
.file-name { | |||
position: absolute; | |||
bottom: 0; | |||
width: 100%; | |||
color: #606266; | |||
font-size: 12px; | |||
text-align: center; | |||
background-color: rgba(255, 255, 255, 0.6); | |||
text-overflow: ellipsis; | |||
overflow: hidden; | |||
white-space: nowrap; | |||
} | |||
</style> |
@@ -0,0 +1,211 @@ | |||
<template> | |||
<view> | |||
<view class="cu-form-group" style="border-bottom: none; padding-bottom: 0;"> | |||
<view class="title"> | |||
<text v-if="required" class="lr-required">*</text> | |||
{{ title || '' }} | |||
</view> | |||
</view> | |||
<view class="cu-form-group"> | |||
<view class="grid col-4 grid-square flex-sub"> | |||
<view v-for="(item, index) in imgList" @tap="viewImg(item)" :key="index" class="bg-img"> | |||
<image v-if="showfile()&&item&&(typeof item == 'string'||isImage(item.type))" :src="item.url?CONFIG('webHost') + item.url:item" mode="aspectFill"> | |||
</image> | |||
<l-icon v-if="showfile()&&!isImage(item.type)" type="text" /> | |||
<text class="file-name">{{item.name}}</text> | |||
<view v-if="!readonly" @tap.stop="delImg(index)" class="cu-tag bg-red" | |||
style="width: 18px; height: 18px; font-size: 24px"> | |||
<l-icon type="close" style="width: 18px; height: 18px; font-size: 12px" /> | |||
</view> | |||
</view> | |||
<view v-if="!readonly && imgList.length < Number(number)" @click="chooseFile" class="solids"> | |||
<l-icon type="file" /> | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
</template> | |||
<script> | |||
/** | |||
* 附件上传组件 | |||
* 使用相机拍摄 和 从相册选图 | |||
* | |||
* 注意:可以选择图片;如果选择文档的话则是从手机的‘文件管理’里面去选择,有可能会找不到文档; | |||
*/ | |||
export default { | |||
props: { | |||
number: { | |||
default: 1 | |||
}, | |||
readonly: {}, | |||
value: { | |||
default: () => [] | |||
}, | |||
folderId: {}, | |||
title: {}, | |||
required: {} | |||
}, | |||
data() { | |||
return { | |||
isShow: false, | |||
imgList: [], | |||
} | |||
}, | |||
methods: { | |||
chooseFile() { | |||
uni.chooseImage({ | |||
count: Number(this.number), | |||
sizeType: ['original', 'compressed'], | |||
sourceType: ['album', 'camera'], | |||
success: ({ tempFilePaths,tempFiles }) => { | |||
this.chooseChangeback(tempFilePaths,tempFiles) | |||
} | |||
}) | |||
}, | |||
delImg(index) { | |||
this.CONFIRM("", "是否确认删除?", true).then(res => { | |||
if(!res)return | |||
this.LOADING('正在删除…'); | |||
const newList = JSON.parse(JSON.stringify(this.imgList)); | |||
this.HTTP_POST('/learun/adms/annexes/wxdelete', this.imgList[index].id, "文件删除失败").then((data) => { | |||
this.HIDE_LOADING(); | |||
if (data) { | |||
newList.splice(index, 1); | |||
this.imgList = newList | |||
this.$emit("update:value", newList); | |||
this.$emit("input", newList); | |||
this.$emit("change"); | |||
this.$emit("del"); | |||
} | |||
}) | |||
}) | |||
}, | |||
showfile() { | |||
return true; | |||
}, | |||
async chooseChangeback(tempFilePaths, tempFiles) { | |||
let uploadImageRes = await this.uploadImage(tempFilePaths[0], tempFiles[0] ? tempFiles[0].name : "") | |||
let newList = this.imgList || [] | |||
if (uploadImageRes) { | |||
//请求‘获取附件列表’接口 | |||
let data = await this.FETCH_FILEList(uploadImageRes); | |||
if(data){ | |||
newList = data.map(t=>({ | |||
id: t.F_Id, | |||
name: t.F_FileName, | |||
url: t.F_FilePath.substring(t.F_FilePath.indexOf('Resource')), | |||
type: t.F_FileType, | |||
folderid:t.F_FolderId, | |||
})) | |||
} | |||
} | |||
this.imgList = newList | |||
this.$emit("update:value", newList); | |||
this.$emit("input", newList); | |||
this.$emit("change", newList); | |||
}, | |||
uploadImage(url, name) { | |||
if (!url) return | |||
// 文件上传 | |||
return new Promise(async (reslove, reject) => { | |||
this.LOADING('正在上传…'); | |||
let params = name ? { | |||
folderId: this.folderId, | |||
name | |||
} : { | |||
folderId: this.folderId | |||
} | |||
this.HTTP_UPLOAD2('/learun/adms/annexes/wxuploadinsingle', url, params).then((data) => { | |||
this.HIDE_LOADING(); | |||
if (data) { | |||
reslove(data) | |||
} else { | |||
reject('上传失败!') | |||
} | |||
}) | |||
}) | |||
}, | |||
validate(array) { | |||
// let type = array.every(item=>{ | |||
// return item.type && item.type.substring(0,6) == "image/" | |||
// }) | |||
// if(!type){ | |||
// this.TOAST('文件类型错误'); | |||
// return false | |||
// } | |||
let size = array.every(item => { | |||
return item.size && item.size <= 200 * 1024 * 1024 | |||
}) | |||
if (!size) { | |||
this.TOAST('文件大小不得超过200M'); | |||
return false | |||
} | |||
return true | |||
}, | |||
isImage(type) { | |||
if (type && type.length) { | |||
return ["png", "jpg"].includes(type.substring(type.length - 3, type.length)) | |||
} else { | |||
return false | |||
} | |||
}, | |||
viewImg(item) { | |||
if (!this.isImage(item.type)) { | |||
window.location.href = this.CONFIG("webHost") + item.url | |||
} else { | |||
uni.previewImage({ | |||
urls: [this.CONFIG('webHost') + item.url], | |||
current: this.CONFIG('webHost') + item.url | |||
}); | |||
} | |||
}, | |||
}, | |||
created() { | |||
// console.log(this.value) | |||
this.imgList = JSON.parse(JSON.stringify(this.value.map(item => { | |||
return { | |||
id: item.F_Id, | |||
name: item.F_FileName, | |||
url: item.F_FilePath.substring(item.F_FilePath.indexOf('Resource')), | |||
type: item.F_FileType, | |||
folderid:item.F_FolderId, | |||
} | |||
}))) | |||
this.$nextTick(() => { | |||
this.isShow = true | |||
}) | |||
} | |||
}; | |||
</script> | |||
<style scoped> | |||
.file-name { | |||
position: absolute; | |||
bottom: 0; | |||
width: 100%; | |||
color: #606266; | |||
font-size: 12px; | |||
text-align: center; | |||
background-color: rgba(255, 255, 255, 0.6); | |||
text-overflow: ellipsis; | |||
overflow: hidden; | |||
white-space: nowrap; | |||
} | |||
</style> |