1. 安裝npm i rc-upload
(官網https://www.npmjs.com/package/rc-upload)
2. 使用
引入import RcUpload from 'rc-upload'
interface FileUploadProps {
name?: string // 上傳的字段文件名
action?: string // 上傳的路徑
className?: string // 樣式類名
style?: object // 行內樣式
multiple?:boolean // 是否多選
accept?:string // 允許上傳的類型
size?:number // 限制的大小
params?: any // 上傳的時候的參數
successChange?: Function // 成功之后
mobxGlobal?: any
}
interface FileUploadState {
accept: string
fileSize: number
filename: string
errmsg: string
errurl: string
visible: boolean
progressPercent: number
}
@inject('mobxGlobal')
export default class FileUpload extends RootComponent<FileUploadProps, FileUploadState> {
basicModel: React.RefObject<BasicModal>
constructor (props:any) {
super(props)
const { accept, size, name } = this.props
this.state = {
accept: accept || '.xlsx,.xls', // '.xlsx,.xls'
fileSize: size || 10,
filename: name || 'file',
errmsg: '',
errurl: '',
visible: false,
progressPercent: 0
}
this.basicModel = React.createRef()
}
/**
* 組件銷毀之前 對 state 的狀態做出處理
*/
componentWillUnmount () {
this.setState = (state, callback) => {}
}
// 開始上傳文件:實際不會進行上傳的
onStart = (file:any) => {
// 文件開始上傳
}
onProgress = (file:any) => {
// console.log(file)
}
/** 導出之后的下載 */
showModel = (url:string, msg:string) => {
this.setState({
errmsg: msg,
errurl: url
})
this.handleModal(1) // 正常導入的錯誤的信息
}
onSuccess = (res: any, file: any) => {
let { successChange } = this.props
if (successChange) {
successChange(res)
} else {
const { errNum, errMessage, excelUrl, successNum } = res.data
if (errNum > 0) {
this.showModel(excelUrl, errMessage)
} else if (errNum < 1 && successNum > 0) {
this.$message.success('導入成功!')
} else {
this.$message.error('導入失?。?)
}
}
}
onError = (err:any, flg:boolean) => {
const { code, msg } = err
this.error(msg || err)
// if (flg) {
// if (code === 401) {
// this.error(msg)
// } else {
// this.error('文件格式不正確!')
// }
// } else {
// this.error(err)
// }
}
/* 文件上傳的 檢查 */
beforeUpload = (file:any, fileList:any) => {
const { accept, fileSize } = this.state
const { size, name } = file
let a = '文件上傳出錯'
return new Promise((resolve, reject) => {
// 對文件的信息進行 類型判斷
let index = name.lastIndexOf('.')
let typeArry = accept.split(',')
let suffer = (name as string).substring(index, name.length)
if (typeArry.indexOf(suffer) < 0) {
a = '請上傳正確的文件'
this.$message.error(a)
reject(a)
}
if ((size / 1024 / 1024) > fileSize) { // 對文件進行 大小判斷
a = `上傳文件的大小不能超過${fileSize}M`
this.$message.warning(a)
reject(a)
}
resolve(file)
})
}
// /* 自定義的文件上傳, 默認的不傳,直接成功 */
// customRequest = (request:any) => {
// const { action, file, filename, fileSize, data, onProgress, onSuccess, onError } = request
// let formData = new FormData()
// let params = this.props.params
// // 創建對象的信息
// formData.append(filename, file, file.name)
// if (params) {
// for (const key in params) {
// formData.append(key, params[key])
// }
// }
// this.setState({ visible: true, progressPercent: 0 })
// let time:any = setInterval(() => {
// let { progressPercent } = this.state
// if (progressPercent >= 80) {
// clearInterval(time)
// } else {
// progressPercent += 8
// }
// this.setState({ progressPercent })
// }, 1000)
// this.axios.upload({
// method: 'post',
// url: action,
// data: formData
// // onUploadProgress: (progressEvent:any) => {
// // if (progressEvent.lengthComputable) {
// // this.onUploadProgressLoading(progressEvent)
// // }
// // }
// }).then((res:any) => {
// const { code, data, msg } = res.data
// if (code === 200) {
// onSuccess(res.data, file)
// } else {
// onError(res.data, true)
// }
// }).catch((err:any) => {
// onError(err, false)
// }).finally(() => {
// this.setState({ visible: false, progressPercent: 100 })
// })
// }
/* 自定義的文件上傳, 默認的不傳,直接成功 */
customRequest = (request:any) => {
const { action, file, filename, fileSize, data, onProgress, onSuccess, onError } = request
const { mobxGlobal: { setTaskNum } } = this.props
let formData = new FormData()
let params = this.props.params
// 創建對象的信息
formData.append(filename, file, file.name)
if (params) {
for (const key in params) {
formData.append(key, params[key])
}
}
this.axios.upload({
method: 'post',
url: action,
data: formData
}).then((res:any) => {
let { data, code, msg } = res.data
if (code === 200) {
this.warning('數據正在導入中,請至任務管理查看報表!')
this.axios.request(this.api.count).then(({ code, data }) => {
if (code === 200) {
let { sun } = data
sun = sun > 99 ? '99+' : sun
this.props.mobxGlobal.setTaskNum(sun)
}
})
} else {
this.warning(`${msg[0]}`)
}
}).finally(() => {
this.setState({ visible: false, progressPercent: 100 })
})
}
/* 打開彈窗: 錯誤的小消息存在 */
handleModal = (num: number = 0) => {
const { handleOk, handleCancel } = this.basicModel.current as BasicModal
num === 0 ? handleCancel() : handleOk()
}
/** 下載數據 */
dowloadFile = (url:string) => {
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
document.body.appendChild(link)
link.click()
this.handleModal(0)
this.$message.success('下載成功!')
}
/** 上傳的進度 */
// onUploadProgressLoading = ({ total, loaded }:any) => {
// let progressPercent:number = (total / loaded) * 100
// let visible:boolean = true
// this.setState({ visible, progressPercent })
// }
render () {
const { multiple, action, name, style } = this.props
const { filename, accept, errmsg, errurl, visible, progressPercent } = this.state
const config = {
action: action,
name: filename,
accept: accept, // 默認上傳的是圖片
multiple: multiple, // 多選
onStart: this.onStart, // 開始上傳文件
onProgress: this.onProgress, // 進度回調,僅適用于現代瀏覽器
onSuccess: this.onSuccess, // 成功回調
onError: this.onError, // 錯誤回調
beforeUpload: this.beforeUpload, // 上傳前的驗證
customRequest: this.customRequest // 提供默認xhr行為的替代以進行其他自定義
}
return (
<div className="upload-file-content" style={style}>
<RcUpload {...config}>
{this.props.children}
</RcUpload>
<Modal title="" closable={false} footer={null} visible={visible}>
<div className="upload-progress">
<p>正在導入,請稍等...</p>
<Progress strokeColor={{
to: '#24C8EA',
from: '#2B8FF9'
}}
status="active" percent={progressPercent} />
</div>
</Modal>
<BasicModal ref={this.basicModel} title="提示">
<Row>
<Col span={7} style={{ textAlign: 'center' }}><img src={js}></img></Col>
<Col span={17} className="error-col">{errmsg}</Col>
</Row>
<Row>
<div className="import-error">
<p>出錯原因可能為:</p>
<p>1.數據不完整(必填項為空);</p>
<p>2.字段格式不正確(如導入數據中的“項目”為系統內沒有的項目名稱等);</p>
<p>3.與原數據沖突(如導入的員工相關記錄在系統中已存在)。</p>
</div>
</Row>
<Row>
<Button type="primary" onClick={() => (this.dowloadFile(errurl))}>下載出錯數據</Button>
</Row>
</BasicModal>
</div>
)
}
}
該文件主要用于后臺管理系統的導入功能