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.

290 lines
8.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title class="title">[文件管理器]</title>
<meta name="viewport"
content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<style type="text/css">
.content {
background: transparent;
}
.btn {
position: relative;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
.btn .file {
position: fixed;
z-index: 93;
left: 0;
right: 0;
top: 0;
bottom: 0;
width: 100%;
opacity: 0;
}
</style>
</head>
<body>
<div id="content" class="content">
<div class="btn">
<input @change="onChange" :accept="accept" ref="file" class="file" type="file" />
</div>
</div>
<script type="text/javascript" src="js/vue.min.js"></script>
<script type="text/javascript">
let _this;
var vm = new Vue({
el: '#content',
data: {
accept: '',
},
mounted() {
console.log('加载webview');
_this = this;
this.files = new Map();
document.addEventListener('plusready', (e) => {
let {
debug,
instantly,
prohibited
} = plus.webview.currentWebview();
this.debug = debug;
this.instantly = instantly;
this.prohibited = prohibited;
this.accept = prohibited.accept;
location.href = 'callback?retype=updateOption';
}, false);
},
methods: {
toast(msg) {
plus.nativeUI.toast(msg);
},
clear(name) {
if (!name) {
this.files.clear();
return;
}
this.files.delete(name);
},
setData(option = '{}') {
this.debug && console.log('更新参数:' + option);
try {
_this.option = JSON.parse(option);
} catch (e) {
console.error('参数设置错误')
}
},
async upload(name = '') {
if (name && this.files.has(name)) {
await this.createUpload(this.files.get(name));
} else {
for (let item of this.files.values()) {
if (item.type === 'waiting' || item.type === 'fail') {
await this.createUpload(item);
}
}
}
},
onChange(e) {
const imgType = ['.bmp', '.jpg', '.png', '.tif', '.gif', '.pcx', '.tga', '.exif', '.fpx', '.svg',
'.psd',
'.cdr', '.pcd',
'.dxf',
'.ufo', '.eps', '.ai', '.raw', '.WMF', '.webp', '.avif', '.apng'
]
const videoType = ['.MPEG', '.MPEG-1', '.MPEG-2', '.MPEG-4', '.MPEG-7', '.MPEG-21', '.AVI',
'.nAVI', '.ASF',
'.MOV',
'.WMV',
'.3GP', '.RM', '.RMVB', '.FLV', '.F4V', '.MP4'
]
const audioType = ['.AIFF', '.AU', '.MP3', '.MIDI', '.WMA', '.RealAudio', '.VQF', '.OggVorbis',
'.AAC',
'.APE'
]
let fileDom = this.$refs.file;
let file = fileDom.files[0];
let name = file.name;
fileDom.value = '';
this.debug && console.log('文件名称', name, '大小', file.size);
if (file) {
// 限制文件格式
let suffix = name.substring(name.lastIndexOf("."));
let formats = this.prohibited.formats ? this.prohibited.formats.split(',') : [];
let isAccept = false;
if (!formats.length) isAccept = true;
if (formats && formats.includes(suffix.toUpperCase())) {
isAccept = true;
} else if (formats === '*') {
isAccept = true
} else {
let isImage = false
let isVideo = false
let isAudio = false
if (formats.includes("image/*")) {
isImage = imgType.includes(suffix.toUpperCase())
if (isImage) {
isAccept = true
} else {
if (formats.includes("video/*")) {
isVideo = videoType.includes(suffix.toUpperCase())
if (isVideo) {
isAccept = true
} else {
if (formats.includes("audio/*")) {
isAudio = audioType.includes(suffix.toUpperCase())
if (isAudio) {
isAccept = true
}
}
}
} else {
if (formats.includes("audio/*")) {
isAudio = audioType.includes(suffix.toUpperCase())
if (isAudio) {
isAccept = true
}
}
}
}
} else if (formats.includes("video/*")) {
isVideo = videoType.includes(suffix.toUpperCase())
if (isVideo) {
isAccept = true
} else {
if (formats.includes("audio/*")) {
isAudio = audioType.includes(suffix.toUpperCase())
if (isAudio) {
isAccept = true
}
}
}
} else if (formats.includes("audio/*")) {
isAudio = audioType.includes(suffix.toUpperCase())
if (isAudio) {
isAccept = true
}
}
}
if (!isAccept) {
this.toast(`不支持上传${suffix.toUpperCase()}格式文件`);
return false;
}
// 限制文件大小
if (file.size > 1024 * 1024 * Math.abs(this.prohibited.size)) {
this.toast(`附件大小请勿超过${this.prohibited.size}M`)
return;
}
let path = URL.createObjectURL(file);
this.files.set(file.name, {
file,
path,
name: file.name,
size: file.size,
progress: 0,
type: 'waiting'
});
this.callChange();
this.instantly && this.upload();
}
},
/**
* @returns {Map} 已选择的文件Map集
*/
callChange() {
location.href = 'callback?retype=change&files=' + escape(JSON.stringify([...this.files]));
},
/**
* @returns {object} 正在处理的当前对象
*/
changeFilesItem(item, end = '') {
this.files.set(item.name, item);
location.href = 'callback?retype=progress&end=' + end + '&item=' + escape(JSON.stringify(item));
},
createUpload(item) {
this.debug && console.log('准备上传,option=' + JSON.stringify(this.option));
item.type = 'loading';
delete item.responseText;
return new Promise((resolve, reject) => {
let {
url,
name,
method = 'POST',
header = {},
formData = {},
data = {}
} = this.option;
let form = new FormData();
for (let keys in formData) {
form.append(keys, formData[keys])
}
for (let keys in data) {
form.append(keys, data[keys])
}
form.append(name, item.file);
let xmlRequest = new XMLHttpRequest();
xmlRequest.open(method, url, true);
for (let keys in header) {
xmlRequest.setRequestHeader(keys, header[keys])
}
xmlRequest.upload.addEventListener(
'progress',
event => {
if (event.lengthComputable) {
let progress = Math.ceil((event.loaded * 100) / event.total)
if (progress <= 100) {
item.progress = progress;
this.changeFilesItem(item);
}
}
},
false
);
xmlRequest.ontimeout = () => {
console.error('请求超时')
item.type = 'fail';
this.changeFilesItem(item, true);
return resolve(false);
}
xmlRequest.onreadystatechange = ev => {
if (xmlRequest.readyState == 4) {
if (xmlRequest.status == 200) {
this.debug && console.log('上传完成:' + xmlRequest.responseText)
item['responseText'] = xmlRequest.responseText;
item.type = 'success';
this.changeFilesItem(item, true);
return resolve(true);
} else if (xmlRequest.status == 0) {
console.error(
'status = 0 :请检查请求头Content-Type与服务端是否匹配服务端已正确开启跨域并且nginx未拦截阻止请求'
)
}
console.error('--ERROR--status = ' + xmlRequest.status)
item.type = 'fail';
this.changeFilesItem(item, true);
return resolve(false);
}
}
xmlRequest.send(form)
});
}
}
});
</script>
</body>
</html>