项目背景
前几天因为项目需要一个上传视频和上传word的文件上传功能,然后这工作就荣幸地安排到我头上了!
不多说,直接整活!
第一步
因为文件上传有两个需求嘛(之前封装过弹窗组件这里就不写了),
//这里呢因为把它拆分了,所属章节保存位置是一个组件,文件上传又是一个组件
<ContentRow label="所属章节">
<Cascader
className="chapter-drop-down-box"
defaultValue={task.chapterList}
fieldNames={{ label: 'value', value: 'value', children: 'children' }}//这里用了antd的组件
options={newStructure}
onChange={value => onValueChange('chapterList', value)}
placeholder="请选择保存位置"
allowClear={false}
/>
</ContentRow>
// 这里呢是根据弹窗之后选择的类型不同而渲染不同的文件上传
const TaskPicker = ({ onChoose }) => {
return (
<>
<div className="video-task" onClick={() => onChoose('Video')}>
<img src={video} alt="" />
<div>视频</div>
</div>
<div className="document-task" onClick={() => onChoose('Pdf')}>
<img src={documentation} alt="" />
<div>文档</div>
</div>
</>
)
}
//这里就是文件上传了
const onFileChange = async e => {
const file = e.target.files[0] || {}//pdf页数
const sizeM = file.size / 1024 / 1024//视频文件大小
if (sizeM > fileConfig.max) {//判断文件多大
toastError(fileConfig.maxErrorMsg, true)
setInputKey(inputKey + 1)
return
}
const startUpload = () => {//这里是文件开始上传
setStatus('process')//状态改变
uploadFile(file)//开始调接口
}
if (type === 'Pdf') {//这里就没什么好说的了,就是判断是pdf和video
const appEle = document.getElementById('app')
let container = appEle.getElementsByClassName('temp-pdf-container')[0]
if (!container) {
container = document.createElement('div')
container.classList.add('temp-pdf-container')
appEle.appendChild(container)
}
const onLoadSuccess = ({ numPages }) => {
const container = document.getElementsByClassName('temp-pdf-container')[0]
container && unmountComponentAtNode(container)
startUpload()
onValueChange('meta', numPages)
}
const { Document } = await import('react-pdf/dist/esm/entry.webpack')
render(<Document file={file} onLoadSuccess={onLoadSuccess} />, container)
} else if (type === 'Video') {
const fileUrl = URL.createObjectURL(new Blob([file], { type: 'application/zip' }))
const audioElement = new Audio(fileUrl)
audioElement.addEventListener('loadedmetadata', function() {
startUpload()
onValueChange('meta', audioElement.duration)
})
}
}
//下一步
const fetchVideoData = (data, noteValue) => {
onValueChange('meta', data.duration)
const videoName = `${noteValue.name}.mp4`//因为获取到上传文件的名字是阿里云处理过的,不带.MP4后缀,所以拼接
const sliceName = videoName.slice(0, 30)
onValueChange('name', sliceName)
if (typeof data === 'boolean') {
setShowPushVideos(true)
setTimeout(() => {
setShowPushVideos(false)
}, 300)
return
}
setStatus('complete')
onValueChange('fileData', { name: videoName, total: 1, loaded: 1, progress: 1, url:data.url })
setInputKey(inputKey + 1)
}
先就写这么多把,不想写了。