You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
6.2 KiB
170 lines
6.2 KiB
import { VantComponent } from '../common/component'; |
|
import { isBoolean, isPromise } from '../common/validator'; |
|
import { imageProps, mediaProps, messageFileProps, videoProps } from './shared'; |
|
import { chooseFile, isImageFile, isVideoFile } from './utils'; |
|
VantComponent({ |
|
props: Object.assign(Object.assign(Object.assign(Object.assign({ disabled: Boolean, multiple: Boolean, uploadText: String, useBeforeRead: Boolean, afterRead: null, beforeRead: null, previewSize: { |
|
type: null, |
|
value: 80, |
|
}, name: { |
|
type: null, |
|
value: '', |
|
}, accept: { |
|
type: String, |
|
value: 'image', |
|
}, fileList: { |
|
type: Array, |
|
value: [], |
|
observer: 'formatFileList', |
|
}, maxSize: { |
|
type: Number, |
|
value: Number.MAX_VALUE, |
|
}, maxCount: { |
|
type: Number, |
|
value: 100, |
|
}, deletable: { |
|
type: Boolean, |
|
value: true, |
|
}, showUpload: { |
|
type: Boolean, |
|
value: true, |
|
}, previewImage: { |
|
type: Boolean, |
|
value: true, |
|
}, previewFullImage: { |
|
type: Boolean, |
|
value: true, |
|
}, videoFit: { |
|
type: String, |
|
value: 'contain', |
|
}, imageFit: { |
|
type: String, |
|
value: 'scaleToFill', |
|
}, uploadIcon: { |
|
type: String, |
|
value: 'photograph', |
|
} }, imageProps), videoProps), mediaProps), messageFileProps), |
|
data: { |
|
lists: [], |
|
isInCount: true, |
|
}, |
|
methods: { |
|
formatFileList() { |
|
const { fileList = [], maxCount } = this.data; |
|
const lists = fileList.map((item) => (Object.assign(Object.assign({}, item), { isImage: isImageFile(item), isVideo: isVideoFile(item), deletable: isBoolean(item.deletable) ? item.deletable : true }))); |
|
this.setData({ lists, isInCount: lists.length < maxCount }); |
|
}, |
|
getDetail(index) { |
|
return { |
|
name: this.data.name, |
|
index: index == null ? this.data.fileList.length : index, |
|
}; |
|
}, |
|
startUpload() { |
|
const { maxCount, multiple, lists, disabled } = this.data; |
|
if (disabled) |
|
return; |
|
chooseFile(Object.assign(Object.assign({}, this.data), { maxCount: maxCount - lists.length })) |
|
.then((res) => { |
|
this.onBeforeRead(multiple ? res : res[0]); |
|
}) |
|
.catch((error) => { |
|
this.$emit('error', error); |
|
}); |
|
}, |
|
onBeforeRead(file) { |
|
const { beforeRead, useBeforeRead } = this.data; |
|
let res = true; |
|
if (typeof beforeRead === 'function') { |
|
res = beforeRead(file, this.getDetail()); |
|
} |
|
if (useBeforeRead) { |
|
res = new Promise((resolve, reject) => { |
|
this.$emit('before-read', Object.assign(Object.assign({ file }, this.getDetail()), { callback: (ok) => { |
|
ok ? resolve() : reject(); |
|
} })); |
|
}); |
|
} |
|
if (!res) { |
|
return; |
|
} |
|
if (isPromise(res)) { |
|
res.then((data) => this.onAfterRead(data || file)); |
|
} |
|
else { |
|
this.onAfterRead(file); |
|
} |
|
}, |
|
onAfterRead(file) { |
|
const { maxSize, afterRead } = this.data; |
|
const oversize = Array.isArray(file) |
|
? file.some((item) => item.size > maxSize) |
|
: file.size > maxSize; |
|
if (oversize) { |
|
this.$emit('oversize', Object.assign({ file }, this.getDetail())); |
|
return; |
|
} |
|
if (typeof afterRead === 'function') { |
|
afterRead(file, this.getDetail()); |
|
} |
|
this.$emit('after-read', Object.assign({ file }, this.getDetail())); |
|
}, |
|
deleteItem(event) { |
|
const { index } = event.currentTarget.dataset; |
|
this.$emit('delete', Object.assign(Object.assign({}, this.getDetail(index)), { file: this.data.fileList[index] })); |
|
}, |
|
onPreviewImage(event) { |
|
if (!this.data.previewFullImage) |
|
return; |
|
const { index } = event.currentTarget.dataset; |
|
const { lists, showmenu } = this.data; |
|
const item = lists[index]; |
|
wx.previewImage({ |
|
urls: lists.filter((item) => isImageFile(item)).map((item) => item.url), |
|
current: item.url, |
|
showmenu, |
|
fail() { |
|
wx.showToast({ title: '预览图片失败', icon: 'none' }); |
|
}, |
|
}); |
|
}, |
|
onPreviewVideo(event) { |
|
if (!this.data.previewFullImage) |
|
return; |
|
const { index } = event.currentTarget.dataset; |
|
const { lists } = this.data; |
|
const sources = []; |
|
const current = lists.reduce((sum, cur, curIndex) => { |
|
if (!isVideoFile(cur)) { |
|
return sum; |
|
} |
|
sources.push(Object.assign(Object.assign({}, cur), { type: 'video' })); |
|
if (curIndex < index) { |
|
sum++; |
|
} |
|
return sum; |
|
}, 0); |
|
wx.previewMedia({ |
|
sources, |
|
current, |
|
fail() { |
|
wx.showToast({ title: '预览视频失败', icon: 'none' }); |
|
}, |
|
}); |
|
}, |
|
onPreviewFile(event) { |
|
if (!this.data.previewFile) |
|
return; |
|
const { index } = event.currentTarget.dataset; |
|
wx.openDocument({ |
|
filePath: this.data.lists[index].url, |
|
showMenu: true, |
|
}); |
|
}, |
|
onClickPreview(event) { |
|
const { index } = event.currentTarget.dataset; |
|
const item = this.data.lists[index]; |
|
this.$emit('click-preview', Object.assign(Object.assign({}, item), this.getDetail(index))); |
|
}, |
|
}, |
|
});
|
|
|