自定义上传oss,待后端返回上传地址,利用axios.put上传 ,uploa组件内置请求是formdata 无法满足
//import UploadOss,{transUrlsToFileList} from '../../../components/UploadOss'
import React, { useState, } from 'react';
import { Upload, Button, message, Form } from 'antd';
import { UploadOutlined } from '@ant-design/icons';
import request, { ResponseDataType } from '@/utils/request';
import axios from 'axios'
/* eg:
<UploadOss
formItem={{
name:'page_background',
label:'权益背景图',
}}
imgUrl={bgUrl}
setImgUrl={setBgUrl}
/>
*/
let cdnUrl = ''
let uuid = ''
const REG_IMG_TYPE = /\/\w+\.(jfif|png|jpg|gif|pdf|jpeg)/i;
//[urls],初始化url
export function transUrlsToFileList(urls) {
if (!Array.isArray(urls)) return [];
const fileObjs: any[] = [];
for (let i = 0; i < urls.length; i += 1) {
const url_i = urls[i];
if (url_i) {
const fileNameMatch = url_i.match(REG_IMG_TYPE) || [url_i];
if (fileNameMatch) {
// let arr=fileNameMatch[0].split("_")
// console.log(fileNameMatch[0],fileNameMatch[0].split("_"))
fileObjs.push({
uid: Date.now(),
name: fileNameMatch[0],
status: 'done',
url: url_i,
});
}
}
}
return fileObjs;
}
//上传图片地址修改
export function changeFile(field: any) {
if (!field || field.length === 0) {
return undefined
}
const fileObj = field[0]
if (field && typeof field == 'string') {
return field
} else if (field.length && field[0].response) {
return fileObj.response.url
} else {
throw new Error('获取不到上传文件')
}
}
//获取上传oss地址
async function uploadFile(
item: { objectName: string, dir: string },
) {
const res: ResponseDataType = await request.post(`/api/op/file/oss/path`, {
...item,
});
return res;
}
//uuid,前端独立文件名
function generateUUID() {
var d = new Date().getTime();
if (window.performance && typeof window.performance.now === "function") {
d += performance.now(); //use high-precision timer if available
}
var uuid = 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
return uuid;
}
interface FormItem {
name: string
label: string
[index: string]: string | {}
}
type Props = {
imgUrl: any[]
formItem: FormItem
setImgUrl: (value) => void;
dir: string // eg:xxx/xxx/xxx/
beforeUpload?: (file) => any
};
const UploadOss: React.FC<Props> = (props) => {
const { imgUrl, formItem, setImgUrl, dir, beforeUpload = () => { } } = props
const normFile = (e) => {
if (Array.isArray(e)) {
return e;
}
if (e.file && e.file.status === 'done') {
const resp = e.file.response
if (resp && !resp.result_status) {
message.error(resp.error_desc || '抱歉,上传服务发送未知错误.')
setImgUrl([])
return []
}
}
let fileList = (e && e.fileList) || []
if (fileList && e.fileList.length > 1) {
fileList = fileList.filter(file => !file.error)
}
// 同步
if (e.fileList && e.fileList.length === 0) {
setImgUrl([]) // 删除
} else if (e.file.status === 'done' && e.file.response) {
e.file.thumbUrl = e.file.response.url
setImgUrl([e.file])
} else if (e.file.status === 'uploading') {
setImgUrl([e.file])
}
return fileList;
};
return (
<Form.Item
{...formItem}
getValueFromEvent={(e) => normFile(e)}
>
<Upload
fileList={imgUrl}
action={
(file) => new Promise(async (resolve) => {
uuid = generateUUID() + '_' + file.name
const res: ResponseDataType = await uploadFile({
objectName: uuid,
dir,
})
if (res && res.result_status) {
resolve(res.data.url)
cdnUrl = res.data.cdnUrl
} else {
message.error('获取上传oss地址失败')
}
})
}
customRequest={
(e) => {
const { action, file, onError, onProgress, onSuccess } = e
// var file = new File([e.file],uuid, {
// type: e.file.type
// });
axios.put(action, file, {// 显示进度
headers: { 'Content-Type': 'application/octet-stream' },
onUploadProgress: (ev) => {
const percent = ((ev.loaded / ev.total) * 100) | 0;
onProgress({ percent, }, file,);
},
}).then(() => {
// const url=`${cdnUrl}/${dir}${uuid}`
const url =cdnUrl+'/'+dir+uuid
onSuccess({ result_status: true, url, }, file,);
},
(res) => {
onError(res);
},
);
}
}
listType="picture"
accept="image/*"
method='PUT'
beforeUpload={(file, fileList) => beforeUpload(file)}
>
{imgUrl.length > 0 ? null : (
<Button>
<UploadOutlined /> 上传图片
</Button>
)}
</Upload>
</Form.Item>
)
}
export default UploadOss