daily-share
daily-share copied to clipboard
对upload-重新封装实现input上传图片(2020-05-13)
对upload-重新封装实现input上传图片
import React, { ClassAttributes } from 'react'
import { Upload } from 'antd'
import { getQiniuUploadToken } from '@/api/common_api'
import { openMessage, MessageType } from '@/utils/system'
import { qiniuUploadUrl } from '@/config/qiniu'
import { RcFile } from 'antd/lib/upload'
import * as qiniu from 'qiniu-js'
import { ClassDeclaration } from '@babel/types'
type FileType = 'audio' | 'video' | 'image'
export class UploadInstance {
public file: File | null = null
public name: string = ""
public sizeUnit: string = ""
public filetype: number = 0
public typename: string = ''
public progress: number = 0
public status: 'pending' | 'uploading' | 'error' | 'complete' = 'pending'
public fileSrc: string = ''
constructor(props: {
file: File
}) {
this.file = props.file
this.status = 'pending'
this.name = this.file.name.split('.')[0] + '.' // 文件名字
this.sizeUnit = this.getFileSizeMin(this.file.size)
this.filetype = this.checkFileType(this.file) // 1 图片, 2 视频
this.typename = this.file.type && this.file.type.split('/')[1]
this.fileSrc = '' // 图片
}
public onUpload(r: any) {
this.status = 'uploading'
// console.log('已上传大小,单位为字节:' + res.total.loaded)
// console.log(
// '本次上传的总量控制信息,单位为字节:' + res.total.size
// )
// console.log(
// '当前上传进度,范围:0~100:' + res.total.percent
// )
// _this.$set(
// _this.materialUploadPercentList,
// file.file.uid,
// res.total.percent.toFixed(0) * 1
// )
this.progress = +(r.total.percent).toFixed(2)
}
public onError(e: any) {
this.status = 'error'
}
public onComplete(res: any) {
this.status = 'complete'
// 判断图片类型
this.fileSrc = res.key
}
// 获取素材的大小
private getFileSizeMin(val: number) {
let sizeType = ''
if (val / (1024 * 1024) > 1) {
sizeType = 'M'
return (val / (1024 * 1024)).toFixed(1) + sizeType
} else {
sizeType = 'Kb'
return (val / 1024).toFixed(1) + sizeType
}
}
// 返回文件类型 1 图片 2 视频
private checkFileType(item: any) {
let type = -1
// 注释的视频类型均为七牛不支持类型
const videoList = [
// 'flv',
// 'avi',
// 'wmv',
// '3gp',
// 'm4v',
// 'ogg',
// 'rmvb',
// 'mov',
// 'x-flv',
// 'mkv',
'mp4',
]
const imageList = ['png', 'jpg', 'jpeg']
const name = item.name
videoList.forEach(node => {
const reg = new RegExp('.' + node + '$', 'i')
if (reg.test(name)) {
type = 2
}
})
imageList.forEach(node => {
const reg = new RegExp('.' + node + '$', 'i')
if (reg.test(name)) {
type = 1
}
})
return type
}
}
// tslint:disable-next-line:no-empty-interface
interface IProps {
className?: ClassDeclaration | any
beforeUpload?: (file: RcFile, FileList: RcFile[]) => boolean
onLoad?: (data: UploadInstance) => void // 文件上传
onChange?: () => void
onSuccess?: () => void
camera?: boolean
}
interface IState {
fileLists: any[]
materialInfo: any
}
export default class SgUpload extends React.Component<IProps, IState> {
private qiniuDomain: string = qiniuUploadUrl
private qiniuToken1: string = ''
private qiniuToken2: string = ''
private materialJson: any = {}
private observer: any = {}
private Uploadprops: any = {
action: qiniuUploadUrl,
multiple: false,
}
private staticProps = {
camera: false
}
constructor(props: any) {
super(props)
this.state = {
fileLists: [],
materialInfo: {}
}
}
public render() {
return(
<Upload
className={ this.props.className }
// beforeUpload={(file: RcFile, FileList: RcFile[]) => { this.beforeUpload(file, FileList)}}
customRequest={(file) => { this.qiniuUpload(file) }}
listType='picture-card'
fileList={ this.state.fileLists }
accept={ this.props.camera ? "image/*" : ''}
capture={this.props.camera ? "camera" : ''}
{...this.Uploadprops}
>
{ this.props.children }
</Upload>
)
}
// 自定义上传方式
private qiniuUpload(file: any) {
console.log('file')
this.beforeUploadCheckout(file.file)
// tslint:disable-next-line:variable-name
const _this = this
const putExtra = {
fname: file.file.name,
params: {},
// mimeType: null,
// 注释的视频类型均为七牛不支持类型
mimeType: [
// 'video/flv',
// 'video/avi',
// 'video/3gpp',
// 'video/wmv',
// 'video/m4v',
// 'video/ogg',
// 'video/rmvb',
// 'video/mov',
// 'video/x-flv',
// 'video/mkv',
// 'video/quicktime',
// 'video/x-ms-wmv',
'video/mp4',
'image/png',
'image/jpg',
'image/jpeg',
],
}
const config: any = {
useCdnDomain: true,
region: null,
checkByMD5: true,
}
if (file.file.type.includes('image')) {
console.log(file, 'fileInfo---------------')
// file, key, token, putExtra, config
this.getQiniuToken(1, () => {
console.log('ok')
const observable = qiniu.upload(
file.file,
file.file.key,
this.qiniuToken1,
putExtra,
config
)
const subscription = observable.subscribe(this.observer)
// this.uploadReq[file.file.uid] = subscription
// this.setState({
// uploadReq: Object.assign({
// 'file.file.uid': subscription
// })
// })
})
} else {
this.getQiniuToken(2, () => {
const observable = qiniu.upload(
file.file,
file.file.key,
this.qiniuToken2,
putExtra,
config
)
const subscription = observable.subscribe(this.observer)
// this.uploadReq[file.file.uid] = subscription
// this.setState({
// uploadReq: Object.assign({
// 'file.file.uid': subscription
// })
// })
})
}
}
// 上传文件之前
private beforeUpload(file: any, fileList: RcFile[]) {
// console.log(file, 'file')
if (this.props.beforeUpload) {
return this.props.beforeUpload(file, fileList)
} else {
const fileType = file.type.includes('image') ? 'img' : 'video'
// 检查大小
const is100M = file.size / 1024 / 1024 < 100
const is5M = file.size / 1024 / 1024 < 5
if (fileType === 'img' && !is5M) {
openMessage(MessageType.error, '图片大小不能超过5M哦')
return false
} else if (fileType === 'video' && !is100M) {
openMessage(MessageType.error, '图片大小不能超过100M哦')
return false
} else if (
file.name
.split('.')
.slice(0, -1)
.join('.').length > 15
) {
openMessage(MessageType.error, '图片大小不能超过5文件名字不能超过15个字M哦')
return false
} else if (!this.isAcceptedFile(file.name)) {
openMessage(MessageType.error, '不支持上传该类型素材')
return false
}
console.log('test')
const uploadInstance = new UploadInstance({
file: file
})
this.observer = {
next: (res: any) => {
uploadInstance.onUpload(res)
this.props.onChange && this.props.onChange()
// _this.props.onChange && _this.props.onChange(res)
// console.log('已上传大小,单位为字节:' + res.total.loaded)
// console.log(
// '本次上传的总量控制信息,单位为字节:' + res.total.size
// )
// console.log(
// '当前上传进度,范围:0~100:' + res.total.percent
// )
// _this.$set(
// _this.materialUploadPercentList,
// file.file.uid,
// res.total.percent.toFixed(0) * 1
// )
},
error: (err: any) => {
// ...
console.log(err.code)
uploadInstance.onError(err)
this.props.onChange && this.props.onChange()
},
complete: (res: any) => {
// ...
console.log(res)
uploadInstance.onComplete(res)
this.props.onChange && this.props.onChange()
// _this.handleSuccess(res, file.file)
},
// this.beforeAvatarUpload(file.file)
}
this.materialJson = {
name: file.name.split('.')[0] + '.', // 文件名字
size: this.getFileSizeMin(file.size),
type: this.checkFileType(file),
typename: file.type && file.type.split('/')[1],
}
console.log('Json', this.materialJson)
this.props.onLoad && this.props.onLoad(uploadInstance)
// return false
return true
}
}
private beforeUploadCheckout(file: any) {
const fileType = file.type.includes('image') ? 'img' : 'video'
// 检查大小
const is100M = file.size / 1024 / 1024 < 100
const is5M = file.size / 1024 / 1024 < 5
if (fileType === 'img' && !is5M) {
return openMessage(MessageType.error, '图片大小不能超过5M哦')
} else if (fileType === 'video' && !is100M) {
openMessage(MessageType.error, '图片大小不能超过100M哦')
return false
} else if (
file.name
.split('.')
.slice(0, -1)
.join('.').length > 15
) {
openMessage(MessageType.error, '图片大小不能超过5文件名字不能超过15个字M哦')
return false
} else if (!this.isAcceptedFile(file.name)) {
openMessage(MessageType.error, '不支持上传该类型素材')
return false
}
const uploadInstance = new UploadInstance({
file: file
})
this.observer = {
next: (res: any) => {
uploadInstance.onUpload(res)
this.props.onChange && this.props.onChange()
// _this.props.onChange && _this.props.onChange(res)
// console.log('已上传大小,单位为字节:' + res.total.loaded)
// console.log(
// '本次上传的总量控制信息,单位为字节:' + res.total.size
// )
// console.log(
// '当前上传进度,范围:0~100:' + res.total.percent
// )
// _this.$set(
// _this.materialUploadPercentList,
// file.file.uid,
// res.total.percent.toFixed(0) * 1
// )
},
error: (err: any) => {
// ...
console.log(err.code)
uploadInstance.onError(err)
this.props.onChange && this.props.onChange()
},
complete: (res: any) => {
// ...
console.log(res)
uploadInstance.onComplete(res)
this.props.onChange && this.props.onChange()
// _this.handleSuccess(res, file.file)
},
// this.beforeAvatarUpload(file.file)
}
// this.materialJson = {
// name: file.name.split('.')[0] + '.', // 文件名字
// size: this.getFileSizeMin(file.size),
// type: this.checkFileType(file),
// typename: file.type && file.type.split('/')[1],
// }
// console.log('Json', this.materialJson)
this.props.onLoad && this.props.onLoad(uploadInstance)
}
// 是否处于接受的文件格式类型内
private isAcceptedFile(fileName: string) {
// 注释的视频类型均为七牛不支持类型
const videoList = [
// 'flv',
// 'avi',
// 'wmv',
// '3gp',
// 'm4v',
// 'ogg',
// 'rmvb',
// 'mov',
// 'x-flv',
// 'mkv',
'mp4',
]
const imageList = ['png', 'jpg', 'jpeg']
let flag = false
videoList.forEach(node => {
const reg = new RegExp('.' + node + '$', 'i')
if (reg.test(fileName)) {
flag = true
}
})
imageList.forEach(node => {
const reg = new RegExp('.' + node + '$', 'i')
if (reg.test(fileName)) {
flag = true
}
})
return flag
}
// 返回文件类型 1 图片 2 视频
private checkFileType(item: any) {
let type = -1
// 注释的视频类型均为七牛不支持类型
const videoList = [
// 'flv',
// 'avi',
// 'wmv',
// '3gp',
// 'm4v',
// 'ogg',
// 'rmvb',
// 'mov',
// 'x-flv',
// 'mkv',
'mp4',
]
const imageList = ['png', 'jpg', 'jpeg']
const name = item.name
videoList.forEach(node => {
const reg = new RegExp('.' + node + '$', 'i')
if (reg.test(name)) {
type = 2
}
})
imageList.forEach(node => {
const reg = new RegExp('.' + node + '$', 'i')
if (reg.test(name)) {
type = 1
}
})
return type
}
// 获取素材的大小
private getFileSizeMin(val: number) {
let sizeType = ''
if (val / (1024 * 1024) > 1) {
sizeType = 'M'
return (val / (1024 * 1024)).toFixed(1) + sizeType
} else {
sizeType = 'Kb'
return (val / 1024).toFixed(1) + sizeType
}
}
// 获取七牛的token
private getQiniuToken(type: number, cb: () => void) {
getQiniuUploadToken(type).then(data => {
if (type === 2) {
// this.qiniuData.token2 = data.token
// this.qiniuToken1 = data.token
this.qiniuToken2 = data.token
} else {
// this.qiniuData.token = data.token
// this.qiniuToken2 = data.token
this.qiniuToken1 = data.token
}
cb && cb()
})
}
}