193 lines
5.6 KiB
TypeScript
193 lines
5.6 KiB
TypeScript
![]() |
import React, { useEffect, useState } from 'react';
|
||
|
import { Upload, Button, message, Modal, Spin } from "antd";
|
||
|
import { UploadOutlined, CloseSquareOutlined, ExclamationCircleOutlined } from '@ant-design/icons';
|
||
|
|
||
|
import { createNewFileBid, removeFileByOid, getFileListByBid } from "./service"
|
||
|
|
||
|
import { getSessionRoleData, getSessionUserData,getUserToken } from '@/utils/session';
|
||
|
|
||
|
import { UploadProps } from 'antd/lib/upload/interface';
|
||
|
|
||
|
interface ExtendUploadProps {
|
||
|
bid?: string;
|
||
|
value?: any;
|
||
|
onChange?: (value: any) => void;
|
||
|
btnName?: string;
|
||
|
maxCount?: number;
|
||
|
maxSize?: number;
|
||
|
uploadProps?: UploadProps;
|
||
|
}
|
||
|
const ExtendUpload: React.FC<ExtendUploadProps> = (props) => {
|
||
|
|
||
|
|
||
|
const { bid, onChange, btnName, maxCount, maxSize, uploadProps } = {
|
||
|
maxCount: 0,
|
||
|
maxSize: 30,
|
||
|
btnName: "上传",
|
||
|
...props
|
||
|
};
|
||
|
|
||
|
const [spin, setSpin] = useState<boolean>(false);//加载
|
||
|
const [returnValue, setReturnValue] = useState<string>("");
|
||
|
const [fileList, setFileList] = useState<any>([]);
|
||
|
|
||
|
const triggerChange = (changedValue: any) => {
|
||
|
if (onChange) {
|
||
|
onChange(changedValue);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
useEffect(() => {
|
||
|
initBidValue(bid)
|
||
|
}, [bid])
|
||
|
|
||
|
//初始化bid方法
|
||
|
const initBidValue = async (bid: any) => {
|
||
|
if (bid !== "" && bid !== null && bid !== undefined) {
|
||
|
fileListById(bid)
|
||
|
setReturnValue(bid);
|
||
|
} else {
|
||
|
await createNewFileBid().then(res => {
|
||
|
setReturnValue(res.id);
|
||
|
triggerChange("");
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const fileBeforeUpload = (curFile: any, curFileList: any) => {
|
||
|
const promise = new Promise<File | void>((resolve, reject) => {
|
||
|
if (maxSize === 0) {
|
||
|
|
||
|
} else {
|
||
|
let curSize = curFile.size / 1024 / 1024;
|
||
|
if (maxSize <= curSize) {
|
||
|
message.error(`当前附件大小为"` + curSize.toFixed(2) + `M",超过允许的最大值"` + maxSize + `M",不可以继续上传!`);
|
||
|
reject(false);
|
||
|
}
|
||
|
}
|
||
|
if (maxCount === 0) {
|
||
|
|
||
|
} else {
|
||
|
let curCount = fileList.length;
|
||
|
if (maxCount <= curCount) {
|
||
|
message.error(`当前附件数量为"` + curCount + `",已经达到允许的最大数量"` + maxCount + `",不可以继续上传!`);
|
||
|
reject(false);
|
||
|
}
|
||
|
}
|
||
|
resolve(curFile);
|
||
|
});
|
||
|
return promise;
|
||
|
}
|
||
|
//fileChange中查询文件列表的方法封装
|
||
|
const fileListById = (fileId: any) => {
|
||
|
getFileListByBid(fileId).then(res => {
|
||
|
setFileList(res);
|
||
|
if (res?.length > 0) {
|
||
|
triggerChange(fileId);
|
||
|
} else {
|
||
|
triggerChange("");
|
||
|
}
|
||
|
}).finally(() => {
|
||
|
setSpin(false);
|
||
|
})
|
||
|
}
|
||
|
|
||
|
const fileChange = async (info: any) => {
|
||
|
const { file, fileList } = info;
|
||
|
setSpin(true);
|
||
|
if (file.status === 'uploading' ||file.status === 'removed' || file.status === 'done' || file.status === 'error') {
|
||
|
if (file.status === 'uploading') {
|
||
|
setFileList(fileList);
|
||
|
}else {
|
||
|
if (file.status === 'removed') {
|
||
|
if (file?.uid !== "") {
|
||
|
await removeFileByOid(file.uid)
|
||
|
}
|
||
|
message.success("删除成功");
|
||
|
} else if (file.status === 'done') {
|
||
|
message.success("上传成功");
|
||
|
} else if (file.status === 'error') {
|
||
|
message.error("上传失败,请重新上传");
|
||
|
}
|
||
|
//重新获取文件列表并确认是否返回文件id
|
||
|
fileListById(returnValue)
|
||
|
}
|
||
|
}else{
|
||
|
fileListById(returnValue)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const fileRemove = (info: any) => {
|
||
|
const promise = new Promise<boolean | void>(function (resolve, reject) {
|
||
|
Modal.confirm({
|
||
|
title: '删除附件',
|
||
|
icon: <ExclamationCircleOutlined />,
|
||
|
content: '确定要删除选中的附件?',
|
||
|
centered: true,
|
||
|
onOk() {
|
||
|
resolve(true);
|
||
|
},
|
||
|
onCancel() {
|
||
|
reject();
|
||
|
},
|
||
|
});
|
||
|
});
|
||
|
return promise;
|
||
|
}
|
||
|
|
||
|
const fileDownLoad = (file: any) => {
|
||
|
window.fetch(file.url, {
|
||
|
method: "GET",
|
||
|
headers: {
|
||
|
// JwtToken: getSessionUserData() == null ? null : getSessionUserData().userId,
|
||
|
Authorization:getUserToken(),
|
||
|
currentRoleCode: getSessionRoleData()?.roleCode,
|
||
|
},
|
||
|
credentials: 'include',
|
||
|
}).then((response) => {
|
||
|
// 这里才是下载附件逻辑处理的地方
|
||
|
response.blob().then(blob => {
|
||
|
const blobUrl = window.URL.createObjectURL(blob);
|
||
|
const aElement = document.createElement("a");
|
||
|
const filename = file.name; // 设置文件名称
|
||
|
aElement.href = blobUrl; // 设置a标签路径
|
||
|
aElement.download = filename;
|
||
|
aElement.click();
|
||
|
window.URL.revokeObjectURL(blobUrl);
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
|
||
|
return (
|
||
|
<>
|
||
|
<Spin spinning={spin}>
|
||
|
<Upload
|
||
|
{...uploadProps}
|
||
|
key={"file" + returnValue}
|
||
|
action="/api/core-service-ebtp-updownload/v1/attachment/upload/"
|
||
|
data={{ businessId: returnValue }}
|
||
|
headers={{
|
||
|
// JwtToken: getSessionUserData() == null ? null : getSessionUserData().userId,
|
||
|
Authorization:getUserToken(),
|
||
|
currentRoleCode: getSessionRoleData()?.roleCode,
|
||
|
}}
|
||
|
name="file"
|
||
|
beforeUpload={fileBeforeUpload}
|
||
|
onChange={fileChange}
|
||
|
onRemove={fileRemove}
|
||
|
showUploadList={{
|
||
|
removeIcon: <CloseSquareOutlined />,
|
||
|
}}
|
||
|
onPreview={fileDownLoad}
|
||
|
fileList={fileList}
|
||
|
>
|
||
|
{!uploadProps?.disabled ?
|
||
|
<Button disabled={uploadProps?.disabled} icon={<UploadOutlined />}>{btnName}</Button>
|
||
|
: null}
|
||
|
</Upload>
|
||
|
</Spin>
|
||
|
</>
|
||
|
)
|
||
|
}
|
||
|
export default ExtendUpload
|