king
2021-05-31 ce70be666bcd78a7e16e739040488cf7e7256cc2
src/tabviews/zshare/fileupload/index.jsx
@@ -1,6 +1,6 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { fromJS } from 'immutable'
import { is, fromJS } from 'immutable'
import moment from 'moment'
import { Upload, Button, Icon, Progress, notification } from 'antd'
import SparkMD5 from 'spark-md5'
@@ -16,23 +16,74 @@
class FileUpload extends Component {
  static propTpyes = {
    value: PropTypes.array,    // 文件数组
    accept: PropTypes.any,     // 文件格式
    maxFile: PropTypes.any,    // 最大文件数
    fileType: PropTypes.string // 文件显示类型
    config: PropTypes.object,  // 表单信息
    onChange: PropTypes.func,  // 表单变化
  }
  state = {
    percent: 0,
    accept: '',
    accepts: null,
    maxFile: null,
    rduri: '',
    limit: 2,
    compress: false,
    fileType: 'text',
    showprogress: false,
    filelist: []
  }
  UNSAFE_componentWillMount () {
    const { value } = this.props
    if (!value) return
    const { config } = this.props
    this.setState({filelist: fromJS(value).toJS()})
    let filelist = []
    if (config.initval) {
      try {
        filelist = config.initval.split(',').map((url, index) => {
          return {
            uid: `${index}`,
            name: url.slice(url.lastIndexOf('/') + 1),
            status: 'done',
            url: url,
            origin: true
          }
        })
      } catch {
        filelist = []
      }
    }
    let accept = ''
    let accepts = null
    let compress = false
    if (config.compress === 'true') {
      compress = true
      accepts = ['.jpg', '.png', '.gif', '.jpeg']
      accept = accepts.join(',')
    } else if (config.suffix) {
      accepts = config.suffix.split(',')
      accept = config.suffix
    }
    let rduri = config.rduri || ''
    if (window.GLOB.systemType === 'production') {
      rduri = config.proRduri || ''
    }
    this.setState({
      rduri,
      accept,
      accepts,
      filelist,
      compress,
      limit: config.limit || 2,
      maxFile: config.maxfile && config.maxfile > 0 ? config.maxfile : null,
      fileType: config.fileType || 'text'
    })
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
  onChange = ({ fileList }) => {
@@ -44,14 +95,24 @@
    })
    this.setState({filelist: fileList})
    this.props.onChange(fileList)
  }
  onRemove = file => {
    const files = this.state.filelist.filter(v => v.uid !== file.uid)
    this.setState({filelist: files})
    this.props.onChange(files)
    let vals = []
    files.forEach(item => {
      if (item.origin && item.url) {
        vals.push(item.url)
      } else if (!item.origin && item.status === 'done' && item.response) {
        vals.push(item.response)
      }
    })
    this.props.onChange(vals.join(','))
  }
  onUpdate = (url) => {
@@ -63,19 +124,31 @@
      filelist[filelist.length -1].origin = false
    }
    filelist = filelist.filter(item => !!(item.url || item.response))
    let vals = []
    filelist.forEach(item => {
      if (item.origin && item.url) {
        vals.push(item.url)
      } else if (!item.origin && item.status === 'done' && item.response) {
        vals.push(item.response)
      }
    })
    this.setState({filelist})
    this.props.onChange(filelist)
    this.props.onChange(vals.join(','))
  }
  onDelete = (msg) => {
  onFail = (msg) => {
    let filelist = this.state.filelist.map(item => {
      if (!item.url && !item.response && !item.status) {
        item.status = 'error'
      }
      return item
    })
    this.setState({filelist, showprogress: false})
    this.props.onChange(filelist)
    this.setState({filelist, showprogress: false, percent: 0})
    notification.warning({
      top: 92,
@@ -110,7 +183,7 @@
          if (res.urlPath) {
            this.onUpdate(res.urlPath)
          } else {
            this.onDelete()
            this.onFail()
          }
          this.setState({
            percent: 100
@@ -124,7 +197,7 @@
          })
        }
      } else {
        this.onDelete(res.message)
        this.onFail(res.message)
      }
    })
  }
@@ -140,12 +213,11 @@
  }
  beforeUpload = (file) => {
    const { accept } = this.props
    const { accepts, compress, limit, rduri } = this.state
    if (accept && file.name) {
      let types = accept.split(',')
    if (accepts && file.name) {
      let pass = false
      types.forEach(type => {
      accepts.forEach(type => {
        if (new RegExp(type + '$', 'ig').test(file.name)) {
          pass = true
        }
@@ -165,6 +237,89 @@
      showprogress: true,
      percent: 0
    })
    if (compress) {
      let reader = new FileReader()
      let fileSize = file.size / 1024 / 1024
      let compressRate = 0.9
      if (fileSize / limit > 5) {
        compressRate = 0.4
      } else if (fileSize / limit > 4) {
        compressRate = 0.5
      } else if (fileSize / limit > 3) {
        compressRate = 0.6
      } else if (fileSize / limit > 2) {
        compressRate = 0.7
      } else if (fileSize > limit) {
        compressRate = 0.8
      }
      reader.onload = (e) => {
        let img = new Image()
        let maxW = 640
        img.onload = () => {
          let cvs = document.createElement( 'canvas')
          let ctx = cvs.getContext( '2d')
          if (img.width > maxW) {
            img.height *= maxW / img.width
            img.width = maxW
          }
          cvs.width = img.width
          cvs.height = img.height
          ctx.clearRect(0, 0, cvs.width, cvs.height)
          ctx.drawImage(img, 0, 0, img.width, img.height)
          let param = {Base64Img: cvs.toDataURL('image/jpeg', compressRate)}
          if (rduri) {
            param.rduri = rduri
          }
          Api.fileuploadbase64(param).then(result => {
            if (result.status && result.Images) {
              let url = service + result.Images
              if (rduri) {
                url = rduri.replace(/webapi(.*)$/, '') + result.Images
              }
              this.onUpdate(url)
              this.setState({
                percent: 100
              }, () => {
                setTimeout(() => {
                  this.setState({
                    showprogress: false,
                    percent: 0
                  })
                }, 200)
              })
            } else {
              this.onFail(result.message)
            }
          })
        }
        img.onerror = () => {
          this.onFail('图片读取失败!')
        }
        img.src = e.target.result
      }
      reader.onerror = () => {
        this.onFail('文件读取失败!')
      }
      reader.readAsDataURL(file)
      return false
    }
    // 兼容性的处理
    let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice
@@ -234,11 +389,10 @@
    }
    chunkFileReader.onerror = () => {
      this.onDelete()
      console.warn('File reading failed.')
      this.onFail('文件读取失败!')
    }
    totalFileReader.onerror = () => {
      this.onDelete()
      this.onFail('文件读取失败!')
    }
    let loadNext = () => {
@@ -270,12 +424,11 @@
  }
  render() {
    const { maxFile, fileType, accept } = this.props
    const { showprogress, percent, filelist } = this.state
    const { showprogress, percent, filelist, maxFile, fileType, accept } = this.state
    let uploadable = 'fileupload-form-container '
    if (maxFile && maxFile > 0 && filelist.length >= maxFile) {
    if (maxFile && filelist.length >= maxFile) {
      uploadable += 'limit-fileupload'
    }
@@ -285,7 +438,7 @@
      listType: fileType,
      fileList: filelist,
      action: null,
      accept: accept || '',
      accept: accept,
      method: 'post',
      multiple: false,
      onChange: this.onChange,