From 48a18736c461ad730bd264b0ac7b40b68a0e33a1 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期日, 28 六月 2020 20:30:20 +0800
Subject: [PATCH] 2020-06-28

---
 src/tabviews/zshare/fileupload/index.jsx |  237 ++++++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 162 insertions(+), 75 deletions(-)

diff --git a/src/tabviews/zshare/fileupload/index.jsx b/src/tabviews/zshare/fileupload/index.jsx
index 479a886..df7e480 100644
--- a/src/tabviews/zshare/fileupload/index.jsx
+++ b/src/tabviews/zshare/fileupload/index.jsx
@@ -1,13 +1,21 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import { Upload, message, Button, Icon, Progress, notification } from 'antd'
-import md5 from 'md5'
+import { fromJS } from 'immutable'
+import { Upload, Button, Icon, Progress, notification } from 'antd'
+import SparkMD5 from 'spark-md5'
 import Api from '@/api'
 import './index.scss'
 
 let Url = '/Upload'
 if (process.env.NODE_ENV === 'production') {
   Url = document.location.origin + '/' + window.GLOB.service + 'zh-CN/Home/Upload'
+}
+
+let service = ''
+if (process.env.NODE_ENV === 'production') {
+  service = document.location.origin + '/' + window.GLOB.service
+} else {
+  service = window.GLOB.location + window.GLOB.service
 }
 
 class FileUpload extends Component {
@@ -21,18 +29,6 @@
     baseUrl: Url,
     percent: 0,
     showprogress: false
-  }
-
-  init = async () => {
-    try {
-      const OSSData = await this.mockGetOSSData()
-
-      this.setState({
-        OSSData
-      })
-    } catch (error) {
-      message.error(error)
-    }
   }
 
   onChange = ({ fileList }) => {
@@ -53,89 +49,180 @@
     }
   }
 
+  onUpdate = (url) => {
+    const { value, onChange } = this.props
+
+    let filelist = fromJS(value).toJS()
+    filelist[filelist.length -1].status = 'done'
+    filelist[filelist.length -1].response = url
+    filelist[filelist.length -1].origin = false
+
+    if (onChange) {
+      onChange([...filelist])
+    }
+  }
+
+  onDelete = (msg) => {
+    const { value, onChange } = this.props
+    let filelist = value.filter(v => !v.url && !v.response)
+
+    if (onChange) {
+      onChange([...filelist])
+    }
+
+    this.setState({
+      showprogress: false
+    })
+
+    notification.warning({
+      top: 92,
+      message: msg || '鏂囦欢涓婁紶澶辫触锛�',
+      duration: 5
+    })
+  }
+
   getExtraData = () => {
     return {
       RootPath: 'Content/images/upload/'
     }
   }
 
-  shardupload = (file, shardSize, shardCount, i, fileList) => {
-    let start = i * shardSize
-    let end = Math.min(file.size, start + shardSize)
-    // let param = {
-    //   file: file.slice(start, end),
-    //   fileMd5: md5(''),
-    //   shardingMd5: md5(''),
-    //   baseDomain: '',
-    //   rootPath: 'Content/images/upload/',
-    //   fileName: file.name,
-    //   fileExt: file.type.replace('image/', ''),
-    //   shardingCnt: shardCount,
-    //   shardingNo: i + 1
-    // }
-
+  shardupload = (params) => {
+    let param = params.chunks.shift()
     let form = new FormData()
-    let pice = file.slice(start, end)
 
-    form.append('file', pice) //slice鏂规硶鐢ㄤ簬鍒囧嚭鏂囦欢鐨勪竴閮ㄥ垎
-    form.append('fileMd5', md5(file))
-    form.append('shardingMd5', md5(pice))
-    form.append('baseDomain', '')
+    form.append('file', param.binary)
+    form.append('fileMd5', params.file.fileMd5)
+    form.append('shardingMd5', param.chunkMd5)
+    form.append('baseDomain', service)
     form.append('rootPath', 'Content/images/upload/')
-    form.append('fileName', file.name)
-    form.append('fileExt', file.type.replace('image/', ''))
-    form.append('shardingCnt', shardCount)
-    form.append('shardingNo', i + 1)
+    form.append('fileName', params.file.fileName)
+    form.append('fileExt', params.file.fileType)
+    form.append('shardingCnt', param.chunks)
+    form.append('shardingNo', param.chunk)
 
     Api.getLargeFileUpload(form).then(res => {
       if (res.status) {
-        if (i < shardCount) {
-          i++
-
+        if (params.chunks.length > 0) {
           this.setState({
-            percent: Math.floor(100 * (i / shardCount))
+            percent: Math.floor(100 * (param.chunk / param.chunks))
           })
-          this.shardupload(file, shardSize, shardCount, i, fileList)
+          this.shardupload(params)
+        } else {
+          if (res.urlPath) {
+            this.onUpdate(res.urlPath)
+          } else {
+            this.onDelete()
+          }
+          this.setState({
+            percent: 100
+          }, () => {
+            setTimeout(() => {
+              this.setState({
+                showprogress: false,
+                percent: 0
+              })
+            }, 200)
+          })
         }
       } else {
-        fileList = fileList.filter(item => !!item.url)
-        notification.warning({
-          top: 92,
-          message: res.message,
-          duration: 5
-        })
+        this.onDelete(res.message)
       }
     })
-    // } else {
-    //   this.setState({
-    //     percent: 100
-    //   }, () => {
-    //     setTimeout(() => {
-    //       this.setState({
-    //         showprogress: false,
-    //         percent: 0
-    //       })
-    //     }, 200)
-    //   })
-    // }
   }
 
-  beforeUpload = (file, fileList) => {
-    let shardSize = 2 * 1024 * 1024
+  beforeUpload = (file) => {
+    this.setState({
+      showprogress: true,
+      percent: 0
+    })
 
-    if (file.size > shardSize) {
-      // this.setState({
-      //   showprogress: true,
-      //   percent: 0
-      // })
-      // let shardCount = Math.ceil(file.size / shardSize)
+    // 鍏煎鎬х殑澶勭悊
+    let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice
+    let chunkSize = 1024 * 1024 * 2                // 鍒囩墖姣忔2M
+    let chunks = Math.ceil(file.size / chunkSize)  // 鍒囩墖鎬绘暟
+    let currentChunk = 0                           // 褰撳墠涓婁紶鐨刢hunk
+    let spark = new SparkMD5.ArrayBuffer()         // 瀵筧rrayBuffer鏁版嵁杩涜md5鍔犲瘑锛屼骇鐢熶竴涓猰d5瀛楃涓�
+    let chunkFileReader = new FileReader()         // 鐢ㄤ簬璁$畻鍑烘瘡涓猚hunkMd5
+    let totalFileReader = new FileReader()         // 鐢ㄤ簬璁$畻鍑烘�绘枃浠剁殑fileMd5
+    let params = {chunks: [], file: {}}            // 鐢ㄤ簬涓婁紶鎵�鏈夊垎鐗囩殑md5淇℃伅
 
-      // this.shardupload(file, shardSize, shardCount, 0, fileList)
-      // return false
-      return true
-    } else {
-      return true
+    params.file.fileName = file.name.replace(/\.{1}[^.]*$/ig, '')  // 鏂囦欢鍚嶏紙鍘婚櫎鍚庣紑鍚嶏級
+    params.file.fileType = file.name.replace(/^.*\.{1}/ig, '')     // 鏂囦欢绫诲瀷
+    params.file.fileSize = file.size                               // 鏂囦欢澶у皬
+    params.file.fileChunks = chunks                                // 璁板綍鎵�鏈塩hunks鐨勯暱搴�
+
+    totalFileReader.readAsArrayBuffer(file)
+    totalFileReader.onload = (e) => {   // 瀵规暣涓猼otalFile鐢熸垚md5
+      spark.append(e.target.result)
+      params.file.fileMd5 = spark.end() // 璁$畻鏁翠釜鏂囦欢鐨刦ileMd5
+
+      Api.getFilePreUpload({fileMd5: params.file.fileMd5}).then(res => {
+        if (res.status && res.urlPath) {
+          this.onUpdate(res.urlPath)
+          this.setState({
+            percent: 100
+          }, () => {
+            setTimeout(() => {
+              this.setState({
+                showprogress: false,
+                percent: 0
+              })
+            }, 200)
+          })
+        } else if (res.shardings && res.shardings.length > 0) {
+          res.shardings.forEach(shard => {
+            if (shard.shardingNo && parseInt(shard.shardingNo) > currentChunk) {
+              currentChunk = parseInt(shard.shardingNo)
+            }
+          })
+          loadNext()
+        } else {
+          loadNext()
+        }
+      })
     }
+
+    chunkFileReader.onload = (e) => {
+      spark.append(e.target.result)      // 瀵规瘡涓�鐗囧垎鐗囪繘琛宮d5鍔犲瘑
+      
+      params.chunks[params.chunks.length - 1].chunkMd5 = spark.end() // 娣诲姞鍒囩墖md5
+      
+      currentChunk++  // 姣忎竴娆″垎鐗噊nload,currentChunk閮介渶瑕佸鍔狅紝浠ヤ究鏉ヨ绠楀垎鐗囩殑娆℃暟
+
+      if (currentChunk < chunks) { // 褰撳墠鍒囩墖鎬绘暟娌℃湁杈惧埌鎬绘暟鏃�
+        loadNext()
+      } else {
+        this.shardupload(params)
+      }
+    }
+
+    chunkFileReader.onerror = () => {
+      this.onDelete()
+      console.warn('File reading failed.')
+    }
+    totalFileReader.onerror = () => {
+      this.onDelete()
+    }
+
+    let loadNext = () => {
+      let start = currentChunk * chunkSize              // 璁$畻鍒嗙墖鐨勮捣濮嬩綅缃�
+      let end = Math.min(file.size, start + chunkSize)  // 璁$畻鍒嗙墖鐨勭粨鏉熶綅缃�
+
+      let obj = {                                       // 姣忎竴涓垎鐗囬渶瑕佸寘鍚殑淇℃伅
+        chunk: currentChunk + 1,
+        binary: file.slice(start, end),
+        start: start,
+        end: end,
+        chunks
+      }
+
+      params.chunks.push(obj)
+      chunkFileReader.readAsArrayBuffer(blobSlice.call(file, start, end))
+    }
+
+    // loadNext()
+    return false
   }
 
   /**
@@ -164,7 +251,7 @@
       fileList: value,
       action: baseUrl,
       method: 'post',
-      multiple: true,
+      multiple: false,
       onChange: this.onChange,
       onRemove: this.onRemove,
       data: this.getExtraData,

--
Gitblit v1.8.0