Browse Source

new multipart upload

tags/vopendata0.1.2
yuyuanshifu 5 years ago
parent
commit
fcd2d6245d
24 changed files with 1528 additions and 24 deletions
  1. +60
    -14
      package-lock.json
  2. +4
    -0
      package.json
  3. +4
    -4
      routers/repo/attachment.go
  4. +0
    -1
      templates/repo/datasets/dataset.tmpl
  5. +1
    -5
      templates/repo/datasets/index.tmpl
  6. +206
    -0
      web_src/js/App.vue
  7. BIN
      web_src/js/assets/bg.png
  8. BIN
      web_src/js/assets/body_bg.gif
  9. +65
    -0
      web_src/js/assets/css/iconfont.css
  10. BIN
      web_src/js/assets/css/iconfont.eot
  11. +1
    -0
      web_src/js/assets/css/iconfont.js
  12. +93
    -0
      web_src/js/assets/css/iconfont.json
  13. +62
    -0
      web_src/js/assets/css/iconfont.svg
  14. BIN
      web_src/js/assets/css/iconfont.ttf
  15. BIN
      web_src/js/assets/css/iconfont.woff
  16. BIN
      web_src/js/assets/css/iconfont.woff2
  17. BIN
      web_src/js/assets/logo.png
  18. +230
    -0
      web_src/js/components/Breakpoint.vue
  19. +153
    -0
      web_src/js/components/Chunk.vue
  20. +244
    -0
      web_src/js/components/Md5.vue
  21. +233
    -0
      web_src/js/components/Skip.vue
  22. +112
    -0
      web_src/js/components/Uploader.vue
  23. +21
    -0
      web_src/js/index.js
  24. +39
    -0
      web_src/js/router/index.js

+ 60
- 14
package-lock.json View File

@@ -1797,8 +1797,7 @@
"assert-plus": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
"optional": true
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
},
"assign-symbols": {
"version": "1.0.0",
@@ -1919,6 +1918,14 @@
"integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==",
"optional": true
},
"axios": {
"version": "0.19.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
"integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
"requires": {
"follow-redirects": "1.5.10"
}
},
"babel-loader": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz",
@@ -2847,7 +2854,6 @@
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"optional": true,
"requires": {
"delayed-stream": "~1.0.0"
}
@@ -3584,8 +3590,7 @@
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
"optional": true
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"delegate": {
"version": "3.2.0",
@@ -4801,8 +4806,7 @@
"extsprintf": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
"optional": true
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
},
"fancy-log": {
"version": "1.3.3",
@@ -5172,6 +5176,29 @@
"readable-stream": "^2.3.6"
}
},
"follow-redirects": {
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
"requires": {
"debug": "=3.1.0"
},
"dependencies": {
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"requires": {
"ms": "2.0.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
},
"fomantic-ui": {
"version": "2.8.4",
"resolved": "https://registry.npmjs.org/fomantic-ui/-/fomantic-ui-2.8.4.tgz",
@@ -7594,8 +7621,7 @@
"jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
"optional": true
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
},
"jsesc": {
"version": "2.5.2",
@@ -8651,14 +8677,12 @@
"mime-db": {
"version": "1.44.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
"integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
"optional": true
"integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg=="
},
"mime-types": {
"version": "2.1.27",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
"integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
"optional": true,
"requires": {
"mime-db": "1.44.0"
}
@@ -11996,6 +12020,11 @@
}
}
},
"simple-uploader.js": {
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/simple-uploader.js/-/simple-uploader.js-0.5.4.tgz",
"integrity": "sha512-Dmysgp0wyKqGdnZ9qnxS7QTg/Hfr25GxKM2XlrEnmzSPFmKroFqzW4Qaq/AbJDBvXv4YPGqS3S5YfVI3UxAU0A=="
},
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@@ -12187,6 +12216,11 @@
"resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
"integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM="
},
"spark-md5": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.1.tgz",
"integrity": "sha512-0tF3AGSD1ppQeuffsLDIOWlKUd3lS92tFxcsrh5Pe3ZphhnoK+oXIBTzOAThZCiuINZLvpiLH/1VS1/ANEJVig=="
},
"sparkles": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz",
@@ -13620,8 +13654,7 @@
"tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
"optional": true
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
},
"type": {
"version": "1.2.0",
@@ -14295,6 +14328,19 @@
"resolved": "https://registry.npmjs.org/vue-resize/-/vue-resize-0.4.5.tgz",
"integrity": "sha512-bhP7MlgJQ8TIkZJXAfDf78uJO+mEI3CaLABLjv0WNzr4CcGRGPIAItyWYnP6LsPA4Oq0WE+suidNs6dgpO4RHg=="
},
"vue-router": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.3.4.tgz",
"integrity": "sha512-SdKRBeoXUjaZ9R/8AyxsdTqkOfMcI5tWxPZOUX5Ie1BTL5rPSZ0O++pbiZCeYeythiZIdLEfkDiQPKIaWk5hDg=="
},
"vue-simple-uploader": {
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/vue-simple-uploader/-/vue-simple-uploader-0.7.4.tgz",
"integrity": "sha512-33uv07lkVj7m9gI7IIrQHAUcZkvl70g55lxnfnO/MZ8icwqiemW9Ah4ZexGWNrEfL1p6fV54PlOGICU17aBPFQ==",
"requires": {
"simple-uploader.js": "^0.5.4"
}
},
"vue-style-loader": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz",


+ 4
- 0
package.json View File

@@ -11,6 +11,7 @@
"@babel/preset-env": "7.9.6",
"@babel/runtime": "7.9.6",
"@primer/octicons": "9.6.0",
"axios": "0.19.2",
"babel-loader": "8.1.0",
"clipboard": "2.0.6",
"core-js": "3.6.5",
@@ -34,6 +35,7 @@
"postcss-loader": "3.0.0",
"postcss-preset-env": "6.7.0",
"postcss-safe-parser": "4.0.2",
"spark-md5": "3.0.1",
"svg-sprite-loader": "5.0.0",
"svgo": "1.3.2",
"svgo-loader": "2.2.1",
@@ -43,6 +45,8 @@
"vue-bar-graph": "1.2.0",
"vue-calendar-heatmap": "0.8.4",
"vue-loader": "15.9.2",
"vue-router": "3.3.4",
"vue-simple-uploader": "0.7.4",
"vue-template-compiler": "2.6.11",
"webpack": "4.43.0",
"webpack-cli": "3.3.11",


+ 4
- 4
routers/repo/attachment.go View File

@@ -360,20 +360,20 @@ func NewMultipart(ctx *context.Context) {
return
}

err := upload.VerifyFileType(ctx.Params("file_type"), strings.Split(setting.Attachment.AllowedTypes, ","))
err := upload.VerifyFileType(ctx.Query("fileType"), strings.Split(setting.Attachment.AllowedTypes, ","))
if err != nil {
ctx.Error(400, err.Error())
return
}

if setting.Attachment.StoreType == storage.MinioStorageType {
totalChunkCounts := ctx.ParamsInt("totalChunkCounts")
totalChunkCounts := ctx.QueryInt("totalChunkCounts")
if totalChunkCounts > minio_ext.MaxPartsCount {
ctx.Error(400, fmt.Sprintf("chunk counts(%d) is too much", totalChunkCounts))
return
}

fileSize := ctx.ParamsInt64("size")
fileSize := ctx.QueryInt64("size")
if fileSize > minio_ext.MaxMultipartPutObjectSize {
ctx.Error(400, fmt.Sprintf("file size(%d) is too big", fileSize))
return
@@ -390,7 +390,7 @@ func NewMultipart(ctx *context.Context) {
UUID: uuid,
UserID: ctx.User.ID,
UploadID: uploadID,
Md5: ctx.Params("md5"),
Md5: ctx.Query("md5"),
Size: fileSize,
TotalChunks:totalChunkCounts,
})


+ 0
- 1
templates/repo/datasets/dataset.tmpl View File

@@ -3,6 +3,5 @@
<label>{{.i18n.Tr "dataset.file"}}</label>
<div class="files"></div>
<div class="ui dropzone" id="dataset" data-upload-url="{{.url}}" data-uuid="{{.uuid}}" data-add-url="{{AppSubUrl}}/attachments/add" data-accepts="{{.AttachmentAllowedTypes}}" data-remove-url="{{AppSubUrl}}/attachments/delete" data-csrf="{{.CsrfToken}}" dataset-id={{.dataset.ID}} data-max-file="100" data-dataset-id="{{.dataset.ID}}" data-max-size="{{.AttachmentMaxSize}}" data-default-message="{{.i18n.Tr "dropzone.default_message"}}" data-invalid-input-type="{{.i18n.Tr "dropzone.invalid_input_type"}}" data-file-too-big="{{.i18n.Tr "dropzone.file_too_big"}}" data-remove-file="{{.i18n.Tr "dropzone.remove_file"}}">
</div>
</div>
</div>

+ 1
- 5
templates/repo/datasets/index.tmpl View File

@@ -65,11 +65,7 @@
</div>
<div class="dataset ui middle very relaxed page">
<div class="column">
{{if .Permission.CanWrite $.UnitTypeDatasets}}
<form class="ui form" action="{{.Link}}" method="post">
{{template "repo/datasets/dataset" .}}
</form>
{{end}}
<div id=uploader></div>
</div>
</div>
</div>


+ 206
- 0
web_src/js/App.vue View File

@@ -0,0 +1,206 @@
<template>
<uploader
ref="uploader"
:options="options"
:autoStart="false"
@file-added="onFileAdded"
@file-success="onFileSuccess"
@file-progress="onFileProgress"
@file-error="onFileError"
class="uploader-app">
<uploader-unsupport></uploader-unsupport>
<uploader-drop>
<p>拖动文件</p>
<uploader-btn>选择文件</uploader-btn>
</uploader-drop>
<uploader-list></uploader-list>
</uploader>
</template>

<script>

import SparkMD5 from 'spark-md5';
import axios from 'axios'
import qs from 'qs'

const {AppSubUrl, StaticUrlPrefix, csrf} = window.config;

export default {
data () {
return {
options: {
target: 'http://localhost:9000/upload',
testChunks: false,
chunkSize: 1024*1024*128, //128MB
simultaneousUploads: 1, //并发上传数
headers: {
'access-token': 'abcd1234'
},
maxChunkRetries: 3, //最大自动失败重试上传次数
parseTimeRemaining: function (timeRemaining, parsedTimeRemaining) { //格式化时间
return parsedTimeRemaining
.replace(/\syears?/, '年')
.replace(/\days?/, '天')
.replace(/\shours?/, '小时')
.replace(/\sminutes?/, '分钟')
.replace(/\sseconds?/, '秒')
}
},
attrs: {
accept: '*'
},
panelShow: false, //选择文件后,展示上传panel
collapse: false,
statusTextMap: {
success: '上传成功',
error: '上传出错了',
uploading: '上传中...',
paused: '暂停',
waiting: '等待中...',
cmd5: '计算md5...'
},

fileStatusText: (status, response) => {
return this.statusTextMap[status];
},
}
},
created() {
//const uploaderInstance = this.$refs.uploader.uploader;
},
methods: {
onFileAdded(file) {
// 计算MD5
this.computeMD5(file);
},
newMultiUpload(file) {
axios.get('/attachments/new_multipart', {params :{
totalChunkCounts: file.totalChunkCounts,
md5: file.uniqueIdentifier,
size: file.size,
fileType: file.fileType,
_csrf: csrf
}}).then(function (response) {
console.log(response.data.uploadID, response.data.uuid);
}).catch(function (error) {
console.log(error);
});
},
chkMd5(file) {
let time = new Date().getTime();
let fileReader = new FileReader();
let spark = new SparkMD5(); //创建md5对象(基于SparkMD5)
fileReader.readAsBinaryString(file.file);
console.log('开始计算MD5...')
//文件读取完毕之后的处理
fileReader.onload = (e) => {
spark.appendBinary(e.target.result);
let md5 = spark.end();
console.log(`MD5计算完成:${file.name} \nMD5:${md5} \n用时:${new Date().getTime() - time} ms`);
spark.destroy();
};
},
//计算MD5
computeMD5(file) {
let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice,
chunkSize = 1024*1024*128,
chunks = Math.ceil(file.size / chunkSize),
currentChunk = 0,
spark = new SparkMD5.ArrayBuffer(),
fileReader = new FileReader();

let time = new Date().getTime();

console.log('计算MD5...')
file.cmd5 = true;
file.totalChunkCounts = chunks;
loadNext();

fileReader.onload = (e) => {
spark.append(e.target.result); // Append array buffer
currentChunk++;
if (currentChunk < chunks) {
console.log(`第${currentChunk}分片解析完成, 开始第${currentChunk +1} / ${chunks}分片解析`);
// let percent = Math.floor(currentChunk / chunks * 100);
// console.log(percent);
// file.cmd5progress = percent;
loadNext();
} else {
let md5 = spark.end();
console.log(`MD5计算完成:${file.name} \nMD5:${md5} \n分片:${chunks} 大小:${file.size} 用时:${(new Date().getTime() - time)/1000} s`);
spark.destroy(); //释放缓存
file.uniqueIdentifier = md5; //将文件md5赋值给文件唯一标识
file.cmd5 = false; //取消计算md5状态

this.computeMD5Success(file);
}
};

fileReader.onerror = () => {
console.warn('oops, something went wrong.');
file.cancel();
};
function loadNext() {
let start = currentChunk * chunkSize;
let end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;

fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end));
}
},
computeMD5Success(file) {
this.newMultiUpload(file)
},
// 文件进度的回调
onFileProgress(rootFile, file, chunk) {
console.log(`上传中 ${file.name},chunk:${chunk.startByte / 1024 / 1024} ~ ${chunk.endByte / 1024 / 1024}`)
},
onFileSuccess(rootFile, file, response, chunk) {
let resp = JSON.parse(response);
if (resp.code === 0 && resp.merge === false) {
console.log('上传成功,不需要合并');
} else {
axios.post('http://localhost:9999/up.php?action=merge', {
filename: file.name,
identifier: file.uniqueIdentifier,
totalSize: file.size,
totalChunks: chunk.offset + 1
}).then(function(res){
if (res.code === 0) {
console.log('上传成功')
} else {
console.log(res.message);
}
})
.catch(function(error){
console.log(error);
});
}
},

onFileError(rootFile, file, response, chunk) {
console.log('Error:', response)
},
}
}
</script>

<style>
.uploader-app {
width: 880px;
padding: 15px;
margin: 40px auto 0;
font-size: 12px;
box-shadow: 0 0 10px rgba(0, 0, 0, .4);
}
.uploader-app .uploader-btn {
margin-right: 40px;
}
.uploader-app .uploader-list {
max-height: 440px;
overflow: auto;
overflow-x: hidden;
overflow-y: auto;
}
</style>

BIN
web_src/js/assets/bg.png View File

Before After
Width: 150  |  Height: 150  |  Size: 1.7 kB

BIN
web_src/js/assets/body_bg.gif View File

Before After
Width: 1  |  Height: 100  |  Size: 49 B

+ 65
- 0
web_src/js/assets/css/iconfont.css View File

@@ -0,0 +1,65 @@
@font-face {font-family: "iconfont";
src: url('iconfont.eot?t=1585640036938'); /* IE9 */
src: url('iconfont.eot?t=1585640036938#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'),
url('iconfont.woff?t=1585640036938') format('woff'),
url('iconfont.ttf?t=1585640036938') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('iconfont.svg?t=1585640036938#iconfont') format('svg'); /* iOS 4.1- */
}

.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

.icon-zip:before {
content: "\e626";
}

.icon-unknown:before {
content: "\e613";
}

.icon-audio:before {
content: "\e645";
}

.icon-image:before {
content: "\e656";
}

.icon-video:before {
content: "\e617";
}

.icon-selimage:before {
content: "\e724";
}

.icon-dir:before {
content: "\e761";
}

.icon-tianjia:before {
content: "\e61f";
}

.icon-mkdir:before {
content: "\e607";
}

.icon-upload:before {
content: "\e614";
}

.icon-document:before {
content: "\e760";
}

.icon-folder:before {
content: "\e686";
}


BIN
web_src/js/assets/css/iconfont.eot View File


+ 1
- 0
web_src/js/assets/css/iconfont.js
File diff suppressed because it is too large
View File


+ 93
- 0
web_src/js/assets/css/iconfont.json View File

@@ -0,0 +1,93 @@
{
"id": "1720184",
"name": "upload",
"font_family": "iconfont",
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "6049876",
"name": "压缩包",
"font_class": "zip",
"unicode": "e626",
"unicode_decimal": 58918
},
{
"icon_id": "553902",
"name": "文档",
"font_class": "unknown",
"unicode": "e613",
"unicode_decimal": 58899
},
{
"icon_id": "1004653",
"name": "文件-音频",
"font_class": "audio",
"unicode": "e645",
"unicode_decimal": 58949
},
{
"icon_id": "1071023",
"name": "图像1",
"font_class": "image",
"unicode": "e656",
"unicode_decimal": 58966
},
{
"icon_id": "1638517",
"name": "视频",
"font_class": "video",
"unicode": "e617",
"unicode_decimal": 58903
},
{
"icon_id": "13137449",
"name": "图像_未选择",
"font_class": "selimage",
"unicode": "e724",
"unicode_decimal": 59172
},
{
"icon_id": "4933421",
"name": "文件夹",
"font_class": "dir",
"unicode": "e761",
"unicode_decimal": 59233
},
{
"icon_id": "521050",
"name": "添加",
"font_class": "tianjia",
"unicode": "e61f",
"unicode_decimal": 58911
},
{
"icon_id": "602556",
"name": "网盘-新建文件夹",
"font_class": "mkdir",
"unicode": "e607",
"unicode_decimal": 58887
},
{
"icon_id": "2305613",
"name": "上传文件",
"font_class": "upload",
"unicode": "e614",
"unicode_decimal": 58900
},
{
"icon_id": "4933419",
"name": "文件",
"font_class": "document",
"unicode": "e760",
"unicode_decimal": 59232
},
{
"icon_id": "6583375",
"name": "文件",
"font_class": "folder",
"unicode": "e686",
"unicode_decimal": 59014
}
]
}

+ 62
- 0
web_src/js/assets/css/iconfont.svg View File

@@ -0,0 +1,62 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<!--
2013-9-30: Created.
-->
<svg>
<metadata>
Created by iconfont
</metadata>
<defs>

<font id="iconfont" horiz-adv-x="1024" >
<font-face
font-family="iconfont"
font-weight="500"
font-stretch="normal"
units-per-em="1024"
ascent="896"
descent="-128"
/>
<missing-glyph />
<glyph glyph-name="zip" unicode="&#58918;" d="M937.984 793.6H91.136c-46.08 0-83.456-37.376-83.456-83.456v-650.752c0-46.08 37.376-83.456 83.456-83.456h846.848c46.08 0 83.456 37.376 83.456 83.456V710.144c0 46.08-37.376 83.456-83.456 83.456z m22.016-734.208c0-12.288-9.728-22.016-22.016-22.016H91.136c-12.288 0-22.016 9.728-22.016 22.016V710.144c0 12.288 9.728 22.016 22.016 22.016H332.8v-91.648h96.768V732.16h508.416c12.288 0 22.016-9.728 22.016-22.016v-650.752zM429.568 638.976h96.256V542.72H429.568zM333.312 542.72h96.256v-96.256H333.312zM431.104 444.928H527.36v-96.256H431.104zM333.824 347.648H430.08v-96.256H333.824z" horiz-adv-x="1024" />

<glyph glyph-name="unknown" unicode="&#58899;" d="M678.4 840.533333l-64 0L221.866667 840.533333c-46.933333 0-85.333333-38.4-85.333333-85.333333l0-750.933333c0-46.933333 38.4-85.333333 85.333333-85.333333l584.533333 0c46.933333 0 85.333333 38.4 85.333333 85.333333L891.733333 571.733333l0 42.666667L678.4 840.533333zM844.8 8.53333299999997c0-21.333333-17.066667-42.666667-42.666667-42.666667L221.866667-34.13333299999999c-21.333333 0-42.666667 17.066667-42.666667 42.666667L179.2 759.466667c0 21.333333 17.066667 42.666667 42.666667 42.666667L597.333333 802.133333l0-209.066667c0-21.333333 17.066667-42.666667 42.666667-42.666667l209.066667 0L849.066667 8.53333299999997zM635.733333 593.066667L635.733333 802.133333l21.333333 0 187.733333-209.066667L635.733333 593.066667z" horiz-adv-x="1024" />

<glyph glyph-name="audio" unicode="&#58949;" d="M877.854 626.775l-56.805 56.806-121.726 123.079c-24.345 21.64-41.928 27.05-68.978 27.05h-451.737c-31.108 0-55.453-24.345-55.453-55.453v-789.865c0-29.755 24.345-54.1 55.453-54.1h666.787c31.108 0 55.453 24.345 55.453 54.1v584.284c0 24.345-8.115 35.165-22.993 54.1v0zM830.516 606.4870000000001h-156.891v156.891l156.891-156.891zM856.213-11.609000000000037c0-5.409-4.057-10.821-10.821-10.821h-666.787c-6.762 0-12.172 5.409-12.172 10.821v789.865c0 6.762 5.409 12.172 12.172 12.172 0 0 451.737 0 451.737 0v-205.582c0-12.173 9.468-21.64 21.64-21.64h204.229v-574.816zM723.668 482.057c-117.668 1.353-246.157-22.993-363.825-59.511-9.468-4.058-10.821-5.409-10.821-14.877v-210.991c-12.172 5.409-27.05 6.762-41.927 5.409-45.985-1.353-82.503-29.755-82.503-60.862 0-31.108 36.517-55.453 82.503-52.748 45.985 2.706 82.503 29.755 82.503 60.863v193.409c109.553 25.698 209.638 43.28 312.429 51.395v-150.128c-12.173 5.409-25.698 6.762-40.576 6.762-45.985-2.706-82.503-29.755-82.503-62.215 0-31.108 36.517-55.453 82.503-52.748 44.632 2.706 82.503 29.755 82.503 60.863v267.797c0 13.525-6.762 16.23-20.287 17.583z" horiz-adv-x="1024" />

<glyph glyph-name="image" unicode="&#58966;" d="M871.898 772.915L149.702 772.915c-46.045 0-83.375-37.327-83.375-83.375l0-611.078c0-46.04 37.33-83.37 83.375-83.37l722.186 0c46.05 0 83.38 37.33 83.38 83.37L955.268 689.5409999999999C955.268 735.585 917.938 772.915 871.898 772.915L871.898 772.915 871.898 772.915zM149.682 717.358l722.236 0c15.35 0 27.79-12.45 27.79-27.792l0-327.194c-44.77 36.747-122.38 86.27-215.479 86.27-85.85 0-170.482-66.522-252.319-130.86-62.712-49.28-127.562-100.26-173.06-100.26-63.822 0-118.447 46.92-136.965 64.83L121.885 689.566C121.885 704.908 134.335 717.358 149.682 717.358L149.682 717.358 149.682 717.358zM871.918 50.652000000000044L149.682 50.652000000000044c-15.347 0-27.797 12.44-27.797 27.79l0 131.87c33.315-23.6 81.482-48.37 136.967-48.37 64.727 0 134.032 54.48 207.399 112.14 74.417 58.49 151.357 118.975 217.977 118.975 119.4 0 214.099-105.105 215.039-106.175l0.44 0.39 0-208.829C899.708 63.091999999999985 887.268 50.652000000000044 871.918 50.652000000000044L871.918 50.652000000000044 871.918 50.652000000000044zM343.839 383.701c61.455 0 111.267 49.815 111.267 111.267s-49.812 111.267-111.267 111.267c-61.452 0-111.267-49.815-111.267-111.267S282.387 383.701 343.839 383.701L343.839 383.701 343.839 383.701zM344.257 550.681c30.595 0 55.395-24.8 55.395-55.4s-24.8-55.395-55.395-55.395c-30.6 0-55.402 24.795-55.402 55.395C288.854 525.876 313.662 550.681 344.257 550.681L344.257 550.681 344.257 550.681z" horiz-adv-x="1024" />

<glyph glyph-name="video" unicode="&#58903;" d="M602.224 5h-480.96C54.392 5 0 59.360000000000014 0 126.26400000000001v515.44c0 66.872 54.392 121.304 121.264 121.304h480.96c66.864 0 121.296-54.424 121.296-121.304v-88.312l253.032 146.104a31.76 31.76 0 0 0 31.632 0A31.632 31.632 0 0 0 1024 672.096v-576.232a31.704 31.704 0 0 0-15.816-27.424 31.76 31.76 0 0 0-31.632 0L723.52 214.53599999999994v-88.272c0-66.904-54.424-121.264-121.296-121.264z m-480.96 694.744c-32 0-58.008-26.04-58.008-58.04v-515.44c0-32 26.008-58.008 58.008-58.008h480.96c32 0 58.04 26.008 58.04 58.008V269.336c0 11.304 6.024 21.752 15.816 27.432a31.744 31.744 0 0 0 31.624 0l253.04-146.104V617.312l-253.04-146.104a31.744 31.744 0 0 0-31.624 0 31.632 31.632 0 0 0-15.816 27.4V641.704c0 32-26.04 58.04-58.04 58.04h-480.96z" horiz-adv-x="1024" />

<glyph glyph-name="selimage" unicode="&#59172;" d="M844.75904 750.5510400000001A76.94336 76.94336 0 0 0 921.6 673.4848v-564.77696a76.94336 76.94336 0 0 0-76.84096-77.04576H179.24096A76.94336 76.94336 0 0 0 102.4 108.70784000000003V673.4848a76.94336 76.94336 0 0 0 76.84096 77.06624h665.51808z m-100.5568-337.14176c-22.46656 0-54.90688-19.53792-122.34752-71.8848l-33.15712-25.94816c-110.12096-85.85216-164.10624-115.75296-236.52352-115.75296-68.34176 0-131.76832 24.63744-188.33408 64.1024v-155.21792c0-7.92576 5.81632-14.4384 13.312-15.4624l2.08896-0.14336h665.51808a15.48288 15.48288 0 0 1 15.2576 13.49632l0.14336 2.10944V355.26656a30.59712 30.59712 0 0 0-11.14112 6.92224c-29.92128 28.99968-67.93216 51.22048-104.83712 51.22048z m100.5568 275.70176H179.24096a15.48288 15.48288 0 0 1-15.2576-13.49632L163.84 673.4848l0.02048-334.25408c3.2768-1.16736 6.41024-2.90816 9.25696-5.24288 53.76-44.2368 115.05664-72.72448 179.05664-72.72448 53.4528 0 100.74112 26.37824 199.39328 103.28064l20.6848 16.22016c90.58304 71.12704 127.63136 94.08512 171.9296 94.08512 42.88512 0 82.04288-16.71168 115.99872-41.69728L860.16 673.4848a15.54432 15.54432 0 0 1-13.312 15.48288l-2.08896 0.14336zM348.30336 609.28c56.6272 0 102.54336-46.03904 102.54336-102.83008 0-56.81152-45.91616-102.85056-102.54336-102.85056-56.6272 0-102.54336 46.03904-102.54336 102.85056C245.76 563.24096 291.67616 609.28 348.30336 609.28z m0-61.44A41.24672 41.24672 0 0 1 307.2 506.44992c0-22.91712 18.432-41.41056 41.10336-41.41056a41.24672 41.24672 0 0 1 41.10336 41.41056c0 22.89664-18.432 41.39008-41.10336 41.39008z" horiz-adv-x="1024" />

<glyph glyph-name="dir" unicode="&#59233;" d="M510.4 652.8c8-27.2 33.6-44.8 60.8-44.8h259.2c0 35.2-28.8 64-64 64H504l6.4-19.2zM484.8 736h281.6c70.4 0 128-57.6 128-128v-25.6c30.4-24 51.2-60.8 51.2-102.4v-384c0-70.4-57.6-128-128-128H208c-70.4 0-128 57.6-128 128V672c0 70.4 57.6 128 128 128h164.8c46.4 0 89.6-25.6 112-64z m-112 0H208c-35.2 0-64-28.8-64-64v-576c0-35.2 28.8-64 64-64h608c35.2 0 64 28.8 64 64V480c0 35.2-28.8 64-64 64H574.4c-56 0-105.6 36.8-121.6 89.6l-19.2 57.6c-8 27.2-32 44.8-60.8 44.8zM272 192h256c17.6 0 32-14.4 32-32s-14.4-32-32-32H272c-17.6 0-32 14.4-32 32s14.4 32 32 32z" horiz-adv-x="1024" />

<glyph glyph-name="tianjia" unicode="&#58911;" d="M212.992 369.664 212.992 369.664 212.992 369.664 215.04 369.664 212.992 369.664ZM69.632 816.128l0-866.304 868.352 0L937.984 816.128 69.632 816.128zM720.896 334.848 552.96 334.848l0-167.936c0-28.672-22.528-51.2-49.152-51.2-28.672 0-51.2 22.528-51.2 51.2l0 167.936L286.72 334.848c-28.672 0-51.2 22.528-51.2 51.2 0 28.672 22.528 49.152 51.2 49.152l165.888 0 0 167.936c0 28.672 22.528 51.2 51.2 51.2 26.624 0 49.152-22.528 49.152-51.2l0-167.936 167.936 0c28.672 0 51.2-20.48 51.2-49.152C770.048 355.328 747.52 334.848 720.896 334.848z" horiz-adv-x="1024" />

<glyph glyph-name="mkdir" unicode="&#58887;" d="M1018.23488 13.335893000000056c0 0 0 559.342933 0 621.01504 0 83.749547-76.26752 75.97056-76.26752 75.97056s-363.779413-0.539307-339.69152 0c-26.170027-0.58368-39.03488 13.70112-39.03488 13.70112s-18.10432 31.20128-50.72896 80.530773c-34.194773 51.725653-73.786027 43.277653-73.786027 43.277653L102.85056 847.83104c-93.057707 0-94.08512-89.51808-94.08512-89.51808s0-675.874133 0-740.3008c0-99.853653 75.421013-87.487147 75.421013-87.487147s807.857493 0 864.679253 0C1029.533013-69.47157300000003 1018.23488 13.335893000000056 1018.23488 13.335893000000056zM857.091413 22.312959999999975c-56.825173 0-681.12384 0-681.12384 0s-75.424427-12.36992-75.424427 87.487147c0 64.41984 0 556.73856 0 556.73856s1.030827 89.51808 94.088533 89.51808l175.264427 0c0 0 39.594667 8.448 73.78944-43.281067 32.62464-49.329493 50.72896-80.52736 50.72896-80.52736s12.858027-14.288213 39.031467-13.704533c-24.087893-0.535893 316.740267 0 316.740267 0s76.27776 7.775573 76.27776-75.97056c0-61.672107 0-437.46304 0-437.46304S937.751893 22.312959999999975 857.091413 22.312959999999975zM685.605547 342.920533l-149.138773 0 0 149.138773c0 6.331733-5.13024 11.472213-11.472213 11.472213l-22.944427 0c-6.33856 0-11.472213-5.14048-11.472213-11.472213l0-149.138773-149.138773 0c-6.341973 0-11.472213-5.143893-11.472213-11.472213l0-22.94784c0-6.335147 5.126827-11.461973 11.472213-11.461973l149.138773 0 0-149.1456c0-6.341973 5.133653-11.472213 11.472213-11.472213l22.944427 0c6.341973 0 11.472213 5.13024 11.472213 11.472213l0 149.1456 149.138773 0c6.341973 0 11.475627 5.126827 11.475627 11.461973l0 22.94784C697.084587 337.77664000000004 691.950933 342.920533 685.605547 342.920533z" horiz-adv-x="1024" />

<glyph glyph-name="upload" unicode="&#58900;" d="M532.352 800c-138.688 0-260.992-88-312.32-218.304C111.808 558.656 32 458.752 32 341.312c0-135.168 105.152-245.312 235.648-245.312a32 32 0 1 1 0 64C173.184 160 96 240.832 96 341.312c0 92.608 65.92 169.664 151.68 180.16a32 32 0 0 1 26.496 21.632C312.32 657.92 415.424 736 532.352 736c145.6 0 265.92-120.32 273.152-273.472a32 32 0 0 1 23.68-29.44c57.472-15.296 98.816-70.336 98.816-134.4 0-76.928-58.944-138.688-130.88-138.688a32 32 0 1 1 0-64c107.968 0 194.88 91.072 194.88 202.688 0 84.672-50.432 159.104-124.288 188.928C848.768 663.6800000000001 705.6 800 532.352 800z m11.648-557.248V-32a32 32 0 1 0-64 0v274.752l-73.344-73.408a32 32 0 0 0-45.312 45.312l128 128a32 32 0 0 0 45.312 0l128-128a32 32 0 0 0-45.312-45.312L544 242.75199999999995z" horiz-adv-x="1024" />

<glyph glyph-name="document" unicode="&#59232;" d="M752 816H272c-70.4 0-128-57.6-128-128v-608c0-70.4 57.6-128 128-128h353.6c33.6 0 65.6 12.8 91.2 36.8l126.4 126.4c24 24 36.8 56 36.8 91.2V688c0 70.4-57.6 128-128 128zM208 80V688c0 35.2 28.8 64 64 64h480c35.2 0 64-28.8 64-64v-464h-96c-70.4 0-128-57.6-128-128v-80H272c-35.2 0-64 28.8-64 64z m462.4-44.8c-4.8-4.8-9.6-8-14.4-11.2v72c0 35.2 28.8 64 64 64h75.2L670.4 35.200000000000045zM368 544h288c17.6 0 32 14.4 32 32s-14.4 32-32 32H368c-17.6 0-32-14.4-32-32s14.4-32 32-32z m128-256H368c-17.6 0-32-14.4-32-32s14.4-32 32-32h128c17.6 0 32 14.4 32 32s-14.4 32-32 32z m-128 96h288c17.6 0 32 14.4 32 32s-14.4 32-32 32H368c-17.6 0-32-14.4-32-32s14.4-32 32-32z" horiz-adv-x="1024" />

<glyph glyph-name="folder" unicode="&#59014;" d="M550.4 618.666667h260.266667c56.554667 0 102.4-45.845333 102.4-102.4v-375.466667c0-56.554667-45.845333-102.4-102.4-102.4H213.333333c-56.554667 0-102.4 45.845333-102.4 102.4V661.333333c0 37.704533 30.562133 68.266667 68.266667 68.266667h264.789333a68.266667 68.266667 0 0 0 58.1376-32.4864L550.4 618.666667z m259.84-528.695467c28.279467 0 51.2 22.9248 51.2 51.2v375.466667c0 28.2752-22.920533 51.2-51.2 51.2H162.56v-426.666667c0-28.2752 22.9248-51.2 51.2-51.2h596.48zM465.7152 669.802667A17.066667 17.066667 0 0 1 450.897067 678.4H179.2a17.066667 17.066667 0 0 1-17.066667-17.066667v-41.634133L494.933333 618.666667l-29.218133 51.136z" horiz-adv-x="1024" />



</font>
</defs></svg>

BIN
web_src/js/assets/css/iconfont.ttf View File


BIN
web_src/js/assets/css/iconfont.woff View File


BIN
web_src/js/assets/css/iconfont.woff2 View File


BIN
web_src/js/assets/logo.png View File

Before After
Width: 48  |  Height: 48  |  Size: 2.7 kB

+ 230
- 0
web_src/js/components/Breakpoint.vue View File

@@ -0,0 +1,230 @@
<template>
<div id="page">
<header>
<h1 class="logo"><a href="http://www.helloweba.net" title="返回helloweba首页">helloweba</a></h1>
</header>
<div class="main">
<h2><a href="http://www.helloweba.net/javascript/637.html">文件上传之暂停和断点续传和跨浏览器续传</a></h2>
<uploader
ref="uploader"
:options="options"
:file-status-text="fileStatusText"
:autoStart="false"
@file-added="onFileAdded"
@file-progress="onFileProgress"
@file-success="onFileSuccess"
@file-error="onFileError"
class="uploader">
<uploader-unsupport></uploader-unsupport>
<uploader-drop>
<uploader-btn class="upfile"><i class="iconfont icon-upload"></i> 上传文件</uploader-btn>
<uploader-btn class="updir" :directory="true"><i class="iconfont icon-dir"></i> 上传文件夹</uploader-btn>
</uploader-drop>
<uploader-list></uploader-list>
</uploader>
</div>
<footer>
<p>Powered by helloweba.net 允许转载、修改和使用本站的DEMO,但请注明出处:<a href="http://www.helloweba.net">www.helloweba.net</a></p>
<p class="hidden"></p>
</footer>
</div>
</template>

<script>
import axios from 'axios';
import SparkMD5 from 'spark-md5';

export default {
data () {
return {
options: {
target: 'http://localhost:9999/up.php',
chunkSize: 2097152, //2MB
simultaneousUploads: 1, //并发上传数
headers: {
'X-token': 'abcd123'
},
maxChunkRetries: 2, //最大自动失败重试上传次数
parseTimeRemaining: function (timeRemaining, parsedTimeRemaining) { //格式化时间
return parsedTimeRemaining
.replace(/\syears?/, '年')
.replace(/\days?/, '天')
.replace(/\shours?/, '小时')
.replace(/\sminutes?/, '分钟')
.replace(/\sseconds?/, '秒')
},
testChunks: true, //开启服务端分片校验
// 服务器分片校验函数
checkChunkUploadedByResponse: (chunk, message) => {
let obj = JSON.parse(message);
if (obj.isExist) {
this.statusTextMap.success = '秒传文件';
return true;
}

return (obj.uploaded || []).indexOf(chunk.offset + 1) >= 0
},
},

statusTextMap: {
success: '上传成功',
error: '上传出错了',
uploading: '上传中...',
paused: '暂停',
waiting: '等待中...',
cmd5: '计算md5...'
},

fileStatusText: (status, response) => {
return this.statusTextMap[status];
},
}
},
created() {
//
},
methods: {
onFileAdded(file) {
// 计算MD5
this.computeMD5(file);
},
//计算MD5
computeMD5(file) {
let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice,
chunkSize = 2097152,
chunks = Math.ceil(file.size / chunkSize),
currentChunk = 0,
spark = new SparkMD5.ArrayBuffer(),
fileReader = new FileReader();

let time = new Date().getTime();

file.cmd5 = true;

fileReader.onload = (e) => {
spark.append(e.target.result); // Append array buffer
currentChunk++;
if (currentChunk < chunks) {
//console.log(`第${currentChunk}分片解析完成, 开始第${currentChunk +1} / ${chunks}分片解析`);
let percent = Math.floor(currentChunk / chunks * 100);
file.cmd5progress = percent;
loadNext();
} else {
console.log('finished loading');
let md5 = spark.end();
console.log(`MD5计算完成:${file.name} \nMD5:${md5} \n分片:${chunks} 大小:${file.size} 用时:${new Date().getTime() - time} ms`);
spark.destroy(); //释放缓存
file.uniqueIdentifier = md5; //将文件md5赋值给文件唯一标识
file.cmd5 = false; //取消计算md5状态
file.resume(); //开始上传
}
};

fileReader.onerror = () => {
console.warn('oops, something went wrong.');
file.cancel();
};
let loadNext = () => {
let start = currentChunk * chunkSize,
end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;
fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end));
};
loadNext();
},
// 文件进度的回调
onFileProgress(rootFile, file, chunk) {
console.log(`上传中 ${file.name},chunk:${chunk.startByte / 1024 / 1024} ~ ${chunk.endByte / 1024 / 1024}`)
},
onFileSuccess(rootFile, file, response, chunk) {
let resp = JSON.parse(response);
//合并分片
if (resp.code === 0 && resp.merge === true) {
axios.post('http://localhost:9999/up.php?action=merge', {
filename: file.name,
identifier: file.uniqueIdentifier,
totalSize: file.size,
totalChunks: chunk.offset + 1
}).then(function(res){
if (res.code === 0) {
console.log('上传成功')
} else {
console.log(res.message);
}
})
.catch(function(error){
console.log(error);
});
}
},

onFileError(rootFile, file, response, chunk) {
console.log('Error:', response)
},
}
}
</script>

<style scoped lang="less">
.main{
max-width: 1000px;
margin: 10px auto;
background: #fff;
padding: 10px;
h2{
padding: 30px 0;
text-align: center;
font-size: 20px;
}
}

.uploader {
width: 880px;
padding: 15px;
margin: 20px auto 0;
font-size: 14px;
box-shadow: 0 0 10px rgba(0, 0, 0, .4);
.uploader-btn {
margin-right: 4px;
color: #fff;
padding: 6px 16px;
}
.upfile{
border: 1px solid #409eff;
background: #409eff;
}
.updir{
border: 1px solid #67c23a;
background: #67c23a;
}
.uploader-list {
max-height: 440px;
overflow: auto;
overflow-x: hidden;
overflow-y: auto;
height: 356px;
/deep/.iconfont {
font-size: 18px;
color: #409eff;
}
}
}

//手机等小屏幕手持设备。当设备宽度 在 320px和768px之间时,执行当前的css
@media only screen and (min-width: 320px) and (max-width: 768px) {
.uploader {
width: 98%;
padding: 0;
box-shadow: none;
}
}
</style>

+ 153
- 0
web_src/js/components/Chunk.vue View File

@@ -0,0 +1,153 @@
<template>
<div id="page">
<header>
<h1 class="logo"><a href="http://www.helloweba.net" title="返回helloweba首页">helloweba</a></h1>
</header>
<div class="main">
<h2><a href="http://www.helloweba.net/javascript/633.html">大文件上传之分片上传</a></h2>
<uploader
ref="uploader"
:options="options"
:fileStatusText="fileStatusText"
@file-progress="onFileProgress"
@file-success="onFileSuccess"
@file-error="onFileError"
class="uploader">
<uploader-unsupport></uploader-unsupport>
<uploader-drop>
<uploader-btn class="upfile"><i class="iconfont icon-upload"></i> 上传文件</uploader-btn>
<uploader-btn class="updir" :directory="true"><i class="iconfont icon-dir"></i> 上传文件夹</uploader-btn>
</uploader-drop>
<uploader-list></uploader-list>
</uploader>
</div>
<footer>
<p>Powered by helloweba.net 允许转载、修改和使用本站的DEMO,但请注明出处:<a href="http://www.helloweba.net">www.helloweba.net</a></p>
<p class="hidden"></p>
</footer>
</div>
</template>

<script>
import axios from 'axios';

export default {
data () {
return {
options: {
target: 'up.php',
testChunks: false,
chunkSize: 1024*1024*2, //2MB
simultaneousUploads: 1, //并发上传数
headers: {
'X-token': 'abcd123'
},
maxChunkRetries: 1, //最大自动失败重试上传次数
parseTimeRemaining: function (timeRemaining, parsedTimeRemaining) { //格式化时间
return parsedTimeRemaining
.replace(/\syears?/, '年')
.replace(/\days?/, '天')
.replace(/\shours?/, '小时')
.replace(/\sminutes?/, '分钟')
.replace(/\sseconds?/, '秒')
}
},
fileStatusText: {
success: '上传成功',
error: '上传出错了',
uploading: '上传中...',
paused: '暂停',
waiting: '等待中...'
},
}
},
created() {
},
methods: {
// 文件进度的回调
onFileProgress(rootFile, file, chunk) {
console.log(`上传中 ${file.name},chunk:${chunk.startByte / 1024 / 1024} ~ ${chunk.endByte / 1024 / 1024}`)
if (file.size > 1024 * 1024 * 10) {
alert('文件太大');
file.cancel();
}
},
onFileSuccess(rootFile, file, response, chunk) {
let resp = JSON.parse(response);
if (resp.code === 0 && resp.merge === false) {
console.log('上传成功,不需要合并');
} else {
axios.post('up.php?action=merge', {
filename: file.name,
identifier: file.uniqueIdentifier,
totalSize: file.size,
totalChunks: chunk.offset + 1
}).then(function(res){
if (res.code === 0) {
console.log('上传成功')
} else {
console.log(res.message);
}
})
.catch(function(error){
console.log(error);
});
}
},

onFileError(rootFile, file, response, chunk) {
alert(response);
file.cancel();
console.log('Error:', response)
},
}
}
</script>

<style scoped lang="less">
.main{
max-width: 1000px;
margin: 10px auto;
background: #fff;
padding: 10px;
h2{
padding: 30px 0;
text-align: center;
font-size: 20px;
}
}

.uploader {
width: 880px;
padding: 15px;
margin: 20px auto 0;
font-size: 14px;
box-shadow: 0 0 10px rgba(0, 0, 0, .4);
.uploader-btn {
margin-right: 4px;
color: #fff;
padding: 6px 16px;
}
.upfile{
border: 1px solid #409eff;
background: #409eff;
}
.updir{
border: 1px solid #67c23a;
background: #67c23a;
}
}
//手机等小屏幕手持设备。当设备宽度 在 320px和768px之间时,执行当前的css
@media only screen and (min-width: 320px) and (max-width: 768px) {
.uploader {
width: 98%;
padding: 0;
box-shadow: none;
}
}
</style>

+ 244
- 0
web_src/js/components/Md5.vue View File

@@ -0,0 +1,244 @@
<template>
<div id="page">
<header>
<h1 class="logo"><a href="http://www.helloweba.net" title="返回helloweba首页">helloweba</a></h1>
</header>
<div class="main">
<h2><a href="http://www.helloweba.net/javascript/635.html">超大文件上传和计算文件MD5值</a></h2>
<uploader
ref="uploader"
:options="options"
:file-status-text="fileStatusText"
:autoStart="false"
@file-added="onFileAdded"
@file-progress="onFileProgress"
@file-success="onFileSuccess"
@file-error="onFileError"
class="uploader">
<uploader-unsupport></uploader-unsupport>
<uploader-drop>
<uploader-btn class="upfile"><i class="iconfont icon-upload"></i> 上传文件</uploader-btn>
<uploader-btn class="updir" :directory="true"><i class="iconfont icon-dir"></i> 上传文件夹</uploader-btn>
</uploader-drop>
<uploader-list></uploader-list>
</uploader>
</div>
<footer>
<p>Powered by helloweba.net 允许转载、修改和使用本站的DEMO,但请注明出处:<a href="http://www.helloweba.net">www.helloweba.net</a></p>
<p class="hidden"></p>
</footer>
</div>
</template>

<script>
import axios from 'axios';
import SparkMD5 from 'spark-md5';

export default {
data () {
return {
options: {
target: 'http://localhost:9999/up.php',
testChunks: false,
chunkSize: 2097152, //2MB
simultaneousUploads: 1, //并发上传数
headers: {
'X-token': 'abcd123'
},
maxChunkRetries: 2, //最大自动失败重试上传次数
parseTimeRemaining: function (timeRemaining, parsedTimeRemaining) { //格式化时间
return parsedTimeRemaining
.replace(/\syears?/, '年')
.replace(/\days?/, '天')
.replace(/\shours?/, '小时')
.replace(/\sminutes?/, '分钟')
.replace(/\sseconds?/, '秒')
}
},

statusTextMap: {
success: '上传成功',
error: '上传出错了',
uploading: '上传中...',
paused: '暂停',
waiting: '等待中...',
cmd5: '计算md5...'
},

fileStatusText: (status, response) => {
return this.statusTextMap[status];
},
}
},
created() {
//const uploaderInstance = this.$refs.uploader.uploader;
},
methods: {
onFileAdded(file) {
// 计算MD5
this.computeMD5(file);
},
chkMd5(file) {
let time = new Date().getTime();
let fileReader = new FileReader();
let spark = new SparkMD5(); //创建md5对象(基于SparkMD5)
fileReader.readAsBinaryString(file.file);
console.log('开始计算MD5...')
//文件读取完毕之后的处理
fileReader.onload = (e) => {
spark.appendBinary(e.target.result);
let md5 = spark.end();
console.log(`MD5计算完成:${file.name} \nMD5:${md5} \n用时:${new Date().getTime() - time} ms`);
spark.destroy();
};
},
//计算MD5
computeMD5(file) {
let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice,
chunkSize = 2097152,
chunks = Math.ceil(file.size / chunkSize),
currentChunk = 0,
spark = new SparkMD5.ArrayBuffer(),
fileReader = new FileReader();

let time = new Date().getTime();

// console.log('计算MD5...')
file.cmd5 = true;

fileReader.onload = (e) => {
spark.append(e.target.result); // Append array buffer
currentChunk++;
if (currentChunk < chunks) {
console.log(`第${currentChunk}分片解析完成, 开始第${currentChunk +1} / ${chunks}分片解析`);
// let percent = Math.floor(currentChunk / chunks * 100);
// console.log(percent);
// file.cmd5progress = percent;
loadNext();
} else {
console.log('finished loading');
let md5 = spark.end();
console.log(`MD5计算完成:${file.name} \nMD5:${md5} \n分片:${chunks} 大小:${file.size} 用时:${new Date().getTime() - time} ms`);
spark.destroy(); //释放缓存
file.uniqueIdentifier = md5; //将文件md5赋值给文件唯一标识
file.cmd5 = false; //取消计算md5状态
file.resume(); //开始上传
console.log(file);
}
};

fileReader.onerror = () => {
console.warn('oops, something went wrong.');
file.cancel();
};
let loadNext = () => {
let start = currentChunk * chunkSize,
end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;
fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end));
};
loadNext();
},
// 文件进度的回调
onFileProgress(rootFile, file, chunk) {
console.log(`上传中 ${file.name},chunk:${chunk.startByte / 1024 / 1024} ~ ${chunk.endByte / 1024 / 1024}`)
},
onFileSuccess(rootFile, file, response, chunk) {
let resp = JSON.parse(response);
if (resp.code === 0 && resp.merge === false) {
console.log('上传成功,不需要合并');
} else {
axios.post('http://localhost:9999/up.php?action=merge', {
filename: file.name,
identifier: file.uniqueIdentifier,
totalSize: file.size,
totalChunks: chunk.offset + 1
}).then(function(res){
if (res.code === 0) {
console.log('上传成功')
} else {
console.log(res.message);
}
})
.catch(function(error){
console.log(error);
});
}
},

onFileError(rootFile, file, response, chunk) {
console.log('Error:', response)
},
}
}
</script>

<style scoped lang="less">
.main{
max-width: 1000px;
margin: 10px auto;
background: #fff;
padding: 10px;
h2{
padding: 30px 0;
text-align: center;
font-size: 20px;
}
}

.uploader {
width: 880px;
padding: 15px;
margin: 20px auto 0;
font-size: 14px;
box-shadow: 0 0 10px rgba(0, 0, 0, .4);
.uploader-btn {
margin-right: 4px;
color: #fff;
padding: 6px 16px;
}
.upfile{
border: 1px solid #409eff;
background: #409eff;
}
.updir{
border: 1px solid #67c23a;
background: #67c23a;
}
.uploader-list {
max-height: 440px;
overflow: auto;
overflow-x: hidden;
overflow-y: auto;
height: 356px;
/deep/.iconfont {
font-size: 18px;
color: #409eff;
}
.no-file {
text-align: center;
font-size: 14px;
padding-top: 50px;
color: #ccc;
}
}
}

//手机等小屏幕手持设备。当设备宽度 在 320px和768px之间时,执行当前的css
@media only screen and (min-width: 320px) and (max-width: 768px) {
.uploader {
width: 98%;
padding: 0;
box-shadow: none;
}
}
</style>

+ 233
- 0
web_src/js/components/Skip.vue View File

@@ -0,0 +1,233 @@
<template>
<div id="page">
<header>
<h1 class="logo"><a href="http://www.helloweba.net" title="返回helloweba首页">helloweba</a></h1>
</header>
<div class="main">
<h2><a href="http://www.helloweba.net/javascript/636.html">文件上传之秒传文件</a></h2>
<uploader
ref="uploader"
:options="options"
:file-status-text="fileStatusText"
:autoStart="false"
@file-added="onFileAdded"
@file-progress="onFileProgress"
@file-success="onFileSuccess"
@file-error="onFileError"
class="uploader">
<uploader-unsupport></uploader-unsupport>
<uploader-drop>
<uploader-btn class="upfile"><i class="iconfont icon-upload"></i> 上传文件</uploader-btn>
<uploader-btn class="updir" :directory="true"><i class="iconfont icon-dir"></i> 上传文件夹</uploader-btn>
</uploader-drop>
<uploader-list></uploader-list>
</uploader>
</div>
<footer>
<p>Powered by helloweba.net 允许转载、修改和使用本站的DEMO,但请注明出处:<a href="http://www.helloweba.net">www.helloweba.net</a></p>
<p class="hidden"></p>
</footer>
</div>
</template>

<script>
import axios from 'axios';
import SparkMD5 from 'spark-md5';

export default {
data () {
return {
options: {
target: 'http://localhost:9999/up.php',
chunkSize: 2097152, //2MB
simultaneousUploads: 1, //并发上传数
headers: {
'X-token': 'abcd123'
},
maxChunkRetries: 2, //最大自动失败重试上传次数
parseTimeRemaining: (timeRemaining, parsedTimeRemaining) => { //格式化时间
return parsedTimeRemaining
.replace(/\syears?/, '年')
.replace(/\days?/, '天')
.replace(/\shours?/, '小时')
.replace(/\sminutes?/, '分钟')
.replace(/\sseconds?/, '秒')
},
testChunks: true, //开启服务端分片校验
// 服务器分片校验函数
checkChunkUploadedByResponse: (chunk, message) => {
let obj = JSON.parse(message);
if (obj.isExist) {
this.statusTextMap.success = '秒传文件';
return true;
}

return (obj.uploaded || []).indexOf(chunk.offset + 1) >= 0
},
},

statusTextMap: {
success: '上传成功',
error: '上传出错了',
uploading: '上传中...',
paused: '暂停',
waiting: '等待中...',
cmd5: '计算md5...'
},

fileStatusText: (status, response) => {
return this.statusTextMap[status];
},
}
},
mounted() {

},
created() {
//
},
methods: {
onFileAdded(file) {
// 计算MD5
this.computeMD5(file);
},
//计算MD5
computeMD5(file) {
let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice,
chunkSize = 2097152,
chunks = Math.ceil(file.size / chunkSize),
currentChunk = 0,
spark = new SparkMD5.ArrayBuffer(),
fileReader = new FileReader();

let time = new Date().getTime();

file.cmd5 = true;

fileReader.onload = (e) => {
spark.append(e.target.result); // Append array buffer
currentChunk++;
if (currentChunk < chunks) {
//console.log(`第${currentChunk}分片解析完成, 开始第${currentChunk +1} / ${chunks}分片解析`);
let percent = Math.floor(currentChunk / chunks * 100);
file.cmd5progress = percent;
loadNext();
} else {
console.log('finished loading');
let md5 = spark.end();
console.log(`MD5计算完成:${file.name} \nMD5:${md5} \n分片:${chunks} 大小:${file.size} 用时:${new Date().getTime() - time} ms`);
spark.destroy(); //释放缓存
file.uniqueIdentifier = md5; //将文件md5赋值给文件唯一标识
file.cmd5 = false; //取消计算md5状态
file.resume(); //开始上传
}
};

fileReader.onerror = () => {
console.warn('oops, something went wrong.');
file.cancel();
};
let loadNext = () => {
let start = currentChunk * chunkSize,
end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;
fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end));
};
loadNext();
},
// 文件进度的回调
onFileProgress(rootFile, file, chunk) {
console.log(`上传中 ${file.name},chunk:${chunk.startByte / 1024 / 1024} ~ ${chunk.endByte / 1024 / 1024}`)
},
onFileSuccess(rootFile, file, response, chunk) {
let resp = JSON.parse(response);
//合并分片
if (resp.code === 0 && resp.merge === true) {
axios.post('http://localhost:9999/up.php?action=merge', {
filename: file.name,
identifier: file.uniqueIdentifier,
totalSize: file.size,
totalChunks: chunk.offset + 1
}).then(res => {
if (res.data.code === 0) {
console.log('上传成功')
} else {
console.log(res.data.message);
}
})
.catch(error => {
console.log(error);
});
}
},

onFileError(rootFile, file, response, chunk) {
console.log('Error:', response)
},
}
}
</script>

<style scoped lang="less">
.main{
max-width: 1000px;
margin: 10px auto;
background: #fff;
padding: 10px;
h2{
padding: 30px 0;
text-align: center;
font-size: 20px;
}
}

.uploader {
width: 880px;
padding: 15px;
margin: 20px auto 0;
font-size: 14px;
box-shadow: 0 0 10px rgba(0, 0, 0, .4);
.uploader-btn {
margin-right: 4px;
color: #fff;
padding: 6px 16px;
}
.upfile{
border: 1px solid #409eff;
background: #409eff;
}
.updir{
border: 1px solid #67c23a;
background: #67c23a;
}
.uploader-list {
max-height: 440px;
overflow: auto;
overflow-x: hidden;
overflow-y: auto;
height: 356px;
/deep/.iconfont {
font-size: 18px;
color: #409eff;
}
}
}

//手机等小屏幕手持设备。当设备宽度 在 320px和768px之间时,执行当前的css
@media only screen and (min-width: 320px) and (max-width: 768px) {
.uploader {
width: 98%;
padding: 0;
box-shadow: none;
}
}
</style>

+ 112
- 0
web_src/js/components/Uploader.vue View File

@@ -0,0 +1,112 @@
<template>
<div id="page">
<header>
<h1 class="logo"><a href="http://www.helloweba.net" title="返回helloweba首页">helloweba</a></h1>
</header>
<div class="main">
<h2><a href="http://www.helloweba.net/javascript/632.html">使用vue-simple-uploader上传文件和文件夹</a></h2>
<p style="text-align:center;color: #999">温馨提示:可将文件拖动到灰色区域上传</p>
<uploader :options="options" :fileStatusText="fileStatusText" class="uploader">
<uploader-unsupport></uploader-unsupport>
<uploader-drop>
<uploader-btn class="upfile"><i class="iconfont icon-upload"></i> 上传文件</uploader-btn>
<uploader-btn class="updir" :directory="true"><i class="iconfont icon-dir"></i> 上传文件夹</uploader-btn>
</uploader-drop>
<uploader-list></uploader-list>
</uploader>
</div>
<footer>
<p>Powered by helloweba.net 允许转载、修改和使用本站的DEMO,但请注明出处:<a href="http://www.helloweba.net">www.helloweba.net</a></p>
<p class="hidden"></p>
</footer>
</div>
</template>

<script>
export default {
data () {
return {
options: {
target: 'uploader.php',
testChunks: false,
chunkSize: 1024*1024*128, //128MB
simultaneousUploads: 1, //并发上传数
headers: {
'X-token': 'abcd123'
},
maxChunkRetries: 3, //最大自动失败重试上传次数
},
fileStatusText: {
success: '上传成功',
error: '上传出错了',
uploading: '上传中...',
paused: '暂停',
waiting: '等待中...'
},
attrs: {
accept: 'image/*'
}
}
},
// mounted () {
// this.$nextTick(() => {
// window.uploader = this.$refs.uploader.uploader
// })
// }
}
</script>

<style scoped lang="less">
.main{
max-width: 1000px;
margin: 10px auto;
background: #fff;
padding: 10px;
h2{
padding: 30px 0;
text-align: center;
font-size: 20px;
}
}

.uploader {
width: 880px;
padding: 15px;
margin: 20px auto 0;
font-size: 14px;
box-shadow: 0 0 10px rgba(0, 0, 0, .4);
.uploader-btn {
margin-right: 4px;
color: #fff;
padding: 6px 16px;
}
.upfile{
border: 1px solid #409eff;
background: #409eff;
}
.updir{
border: 1px solid #67c23a;
background: #67c23a;
}
.uploader-list {
max-height: 440px;
overflow: auto;
overflow-x: hidden;
overflow-y: auto;
}
// /deep/.uploader-drop{
// height: 400px;
// }
}
//手机等小屏幕手持设备。当设备宽度 在 320px和768px之间时,执行当前的css
@media only screen and (min-width: 320px) and (max-width: 768px) {
.uploader {
width: 98%;
padding: 0;
box-shadow: none;
}
}
</style>

+ 21
- 0
web_src/js/index.js View File

@@ -21,6 +21,16 @@ import highlight from './features/highlight.js';
import ActivityTopAuthors from './components/ActivityTopAuthors.vue';
import {initNotificationsTable, initNotificationCount} from './features/notification.js';
import {createCodeEditor} from './features/codeeditor.js';
import App from './App.vue'
import router from './router'
import uploader from 'vue-simple-uploader'

Vue.use(uploader);

//import './assets/css/iconfont.css'

//Vue.config.productionTip = false


const {AppSubUrl, StaticUrlPrefix, csrf} = window.config;

@@ -2555,6 +2565,7 @@ $(document).ready(async () => {
initAdmin();
initCodeView();
initVueApp();
initVueUploader();
initTeamSettings();
initCtrlEnterSubmit();
initNavbarContentToggle();
@@ -3165,6 +3176,16 @@ function initVueApp() {
});
}

function initVueUploader() {
/* eslint-disable no-new */
new Vue({
el: '#uploader',
router,
components: { App },
template: '<App/>'
});
}

window.timeAddManual = function () {
$('.mini.modal')
.modal({


+ 39
- 0
web_src/js/router/index.js View File

@@ -0,0 +1,39 @@
import Vue from 'vue'
import Router from 'vue-router'
import Uploader from '../components/Uploader.vue'
import Chunk from '../components/Chunk.vue'
import Md5 from '../components/Md5.vue'
import Skip from '../components/Skip.vue'
import Breakpoint from '../components/Breakpoint.vue'

Vue.use(Router)

export default new Router({
routes: [
{
path: '/',
name: 'uploader',
component: Uploader
},
{
path: '/chunk',
name: 'chunk',
component: Chunk
},
{
path: '/skip',
name: 'skip',
component: Skip
},
{
path: '/md5',
name: 'md5',
component: Md5
},
{
path: '/breakpoint',
name: 'breakpoint',
component: Breakpoint
},
]
})

Loading…
Cancel
Save