Commit cf51034b authored by 吴永生#A02208's avatar 吴永生#A02208

fix: 文件上传进度条修改

parent b54c89e1
......@@ -2,19 +2,17 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-13 17:00:19
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-15 15:24:44
* @LastEditTime: 2022-06-16 02:15:55
* @FilePath: /bkunyun/src/store/modules/upload.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import { makeAutoObservable, observable, action } from "mobx";
import { makeAutoObservable } from "mobx";
interface IUploadInfo {
export interface IUploadInfo {
id: string,
open: boolean,
file: File,
list: any,
isPermanence: boolean,
info: any,
}
/** 存储地图派单websocket推送数据状态的store */
......@@ -43,7 +41,6 @@ class FileList {
/** 设置文件上传信息 */
setUploadInfo = (id: string, val: IUploadInfo) => {
console.log(id, val,'2222')
const newFileList = this.fileList?.map((item)=>{
if(item.id === id){
return val
......@@ -52,29 +49,10 @@ class FileList {
this.fileList = newFileList
}
setUploadInfoOpen = (id: string, val: boolean) => {
const newFileList = this.fileList?.map((item)=>{
if(item.id === id){
return {...item,open: val};
}
return item;
})
this.fileList = newFileList
}
setUploadInfoList = (id: string, val: any) => {
const newFileList = this.fileList?.map((item)=>{
if(item.id === id){
return {...item, list: val}
} return item
})
this.fileList = newFileList
}
setUploadInfoIsPermanence = (id: string, val: boolean) => {
const newFileList = this.fileList?.map((item)=>{
if(item.id === id){
return {...item, isPermanence: val}
return {...item, info: {...item.info, ...val}}
} return item
})
this.fileList = newFileList
......
import React, { useEffect, useState } from "react";
import useGlobalStore from "@/hooks/useGlobalStore";
import { toJS } from "mobx";
import * as tus from "tus-js-client";
import {
verifyLettersNumbersCertainChars4,
verifyLettersNumbersCertainChars5,
} from "../helper";
import { getDataFileToken } from "@/api/project_api";
import useMyRequest from "@/hooks/useMyRequest";
import { getTokenInfo } from "@/utils/util";
import { getTokenInfo } from "../util";
const UseTusUpload = (props) => {
const { fileListStore: uploadInfoStore, currentProjectStore } = props;
/** 文件token */
const [fileToken, setFileToken] = useState("");
/** token信息 */
let tokenInfo = getTokenInfo();
/** 获取文件token请求 */
const { run: getDataFileTokenRun } = useMyRequest(getDataFileToken, {
onSuccess: (res) => {
setFileToken(res.data);
},
});
useEffect(() => {
getDataFileTokenRun({
id: currentProjectStore?.currentProjectInfo.id,
});
}, []);
const { fileList } = uploadInfoStore;
const uploadFile = (item, file, url, filepath, callBack) => {
uploadInfoStore?.setUploadInfoIsPermanence(item.id, false);
console.log(fileList);
const UseTusUpload = (uploadInfoStore: any) => {
/** token信息 */
let tokenInfo = getTokenInfo();
const currentProjectStore = toJS(useGlobalStore("currentProjectStore"));
const uploadFile = (
item: any,
file: any,
url: string,
fileToken: string,
filepath: any,
callBack: any
) => {
if (!verifyLettersNumbersCertainChars4(file.name)) {
console.log(222);
let json1 = item?.list.concat({
let json = {
name: file.name,
bytesUploaded: 0,
bytesTotal: 0,
......@@ -46,18 +30,16 @@ const UseTusUpload = (props) => {
startTime: new Date().getTime(),
endTime: new Date().getTime() + 1000,
bytesUploaded2: 0,
fileIsCn: true,
isSuspend: false,
statusMsg: "上传失败",
upload: null,
id: new Date().getTime(),
statusMsgDetail:
"上传失败,文件或文件夹的命名长度不超过127字节,不支持特殊符号、空格。",
});
};
uploadInfoStore?.setUploadInfo(item.id, {
...item,
open: true,
list: json1,
isPermanence: false,
info: json,
});
return;
}
......@@ -72,60 +54,46 @@ const UseTusUpload = (props) => {
let upload = new tus.Upload(file, {
endpoint: url,
parallelUploads: 1,
chunkSize: 5242880,
chunkSize: 5 * 1024 * 1024,
metadata: {
filepath: filepath,
},
retryDelays: [0, 3000, 5000, 10000, 20000],
headers: headers,
onError: function (error) {
onError: function (error: string) {
console.log("Failed because: " + error);
},
onProgress: function (bytesUploaded, bytesTotal, a) {
var percentage = ((bytesUploaded / bytesTotal) * 100).toFixed(2);
const json = item.list.concat({
onProgress: function (bytesUploaded: number, bytesTotal: number) {
var percentage = (bytesUploaded / bytesTotal) * 100;
const json = {
name: upload.file.name,
bytesUploaded: bytesUploaded,
bytesTotal: bytesTotal,
percentage: percentage,
startTime: new Date().getTime(),
endTime: new Date().getTime() + 1000,
startTime: timeId,
isSuspend: false,
endTime: new Date().getTime(),
bytesUploaded2: bytesUploaded,
id: timeId,
statusMsg: "正在上传",
upload,
dir: "/home/cloudam/",
});
console.log(item, "0111111");
};
uploadInfoStore?.setUploadInfo(item.id, {
...item,
open: true,
list: json || [],
isPermanence: item.isPermanence,
info: json,
});
},
onSuccess: function () {
let json = [];
json = item.list.concat({
name: upload.file.name,
bytesUploaded: 0,
bytesTotal: 0,
const json = {
id: timeId,
percentage: 100,
startTime: new Date().getTime(),
startTime: timeId,
endTime: new Date().getTime() + 1000,
bytesUploaded2: 0,
statusMsg: "上传成功",
upload,
});
console.log(json, item.list, "0222222");
uploadInfoStore?.setUploadInfo(item.id, {
...item,
open: true,
list: json,
isPermanence: item.isPermanence,
});
};
uploadInfoStore?.setUploadInfoList(item.id, json);
callBack && callBack(upload, filepath);
},
......
......@@ -6,7 +6,20 @@
align-items: center;
border-bottom: 1px solid #f0f2f5;
}
.fileNameBox {
white-space: nowrap;
display: inline-block;
vertical-align: middle;
color: #1e2633;
max-width: 260px;
overflow: hidden;
text-overflow: ellipsis;
font-size: 14px;
}
.rightBox {
cursor: pointer;
font-size: 12px;
color: #1370ff;
}
......
......@@ -5,44 +5,75 @@ import { LinearProgress } from "@mui/material";
import styles from "./index.module.css";
import { useMemo } from "react";
import { formatTime, storageUnitFromB } from "@/utils/util";
import useGlobalStore from "@/hooks/useGlobalStore";
import { observer } from "mobx-react-lite";
import { IUploadInfo } from "@/store/modules/fileList";
import { useMessage } from "@/components/MySnackbar";
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-11 15:46:42
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-15 18:03:31
* @LastEditTime: 2022-06-16 02:07:56
* @FilePath: /bkunyun/src/views/ConsoleLayout/components/FileItem/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
interface IProps {
fileItemInfo: any;
fileItemInfo: IUploadInfo;
}
const FileItem = (props: IProps) => {
const FileItem = observer((props: IProps) => {
const { fileItemInfo } = props;
const itemInfo = toJS(fileItemInfo);
const lastInfo = itemInfo?.list[itemInfo.list?.length - 1];
const firstInfo = itemInfo?.list[0];
const lastMsg = lastInfo?.statusMsg;
const itemInfo = toJS(fileItemInfo)?.info;
const { statusMsg = "" } = itemInfo || {};
const uploadInfoStore = toJS(useGlobalStore("fileListStore"));
const Message = useMessage();
console.log(toJS(fileItemInfo), "11111");
/** 时间 */
const TimeText = useMemo(() => {
const val = lastInfo.endTime - firstInfo.startTime;
return formatTime(val);
}, [firstInfo.startTime, lastInfo.endTime]);
const val = itemInfo?.endTime - itemInfo?.startTime;
return formatTime(val) || "";
}, [itemInfo?.endTime, itemInfo?.startTime]);
const text = useMemo(() => {
let result = "";
if (lastMsg === "上传失败") {
if (statusMsg === "上传失败") {
result = "重新上传";
}
if (lastMsg === "正在上传") {
result = "暂停";
if (statusMsg === "正在上传") {
if (itemInfo?.isSuspend) {
result = "重新上传";
} else {
result = "暂停";
}
}
if (lastMsg === "上传成功") {
if (statusMsg === "上传成功") {
result = "查看文件";
}
return result;
}, [itemInfo?.list, lastMsg]);
}, [itemInfo?.isSuspend, statusMsg]);
/** 操作合集 */
const onOperation = () => {
if (text === "暂停") {
itemInfo?.upload?.abort(true).then(() => {
Message.info("暂停成功!");
uploadInfoStore.setUploadInfoList(fileItemInfo?.id, {
isSuspend: true,
});
});
}
if (text === "重新上传") {
itemInfo?.upload?.start();
uploadInfoStore.setUploadInfoList(fileItemInfo?.id, {
isSuspend: false,
});
}
if (text === "查看文件") {
console.log("跳转");
}
};
return (
<div className={styles.itemBox}>
......@@ -50,12 +81,14 @@ const FileItem = (props: IProps) => {
<img />
<div>
<div>
<b style={{ fontSize: 14 }}>{firstInfo?.name || ""}</b>
{lastMsg === "上传失败" ? (
<b className={styles.fileNameBox} title={itemInfo?.name || ""}>
{itemInfo?.name || ""}
</b>
{statusMsg === "上传失败" ? (
<span
className={styles.span}
style={{ marginLeft: 16, color: "#FF4E4E" }}
>{`(${lastMsg})`}</span>
>{`(${statusMsg})`}</span>
) : (
<span className={styles.span} style={{ marginLeft: 16 }}>
{TimeText}
......@@ -63,20 +96,31 @@ const FileItem = (props: IProps) => {
)}
</div>
<LinearProgress
sx={{ width: 300, borderRadius: 2, margin: "2px 0", color: "red" }}
sx={{ width: 300, borderRadius: 2, margin: "6px 0", color: "red" }}
variant="determinate"
value={50}
value={itemInfo?.percentage}
/>
<div>
<span className={styles.span}>{`700MB/${storageUnitFromB(
500000
)}`}</span>
<div style={{ fontSize: 12 }}>
{statusMsg === "上传成功" ? (
<>
<span style={{ color: "#8A9099" }}>已上传至</span>
<span style={{ color: "#565C66", marginLeft: 12 }}>
{itemInfo?.dir}
</span>
</>
) : (
<span className={styles.span}>{`${storageUnitFromB(
itemInfo?.bytesUploaded || 0
)}/${storageUnitFromB(itemInfo?.bytesTotal || 0)}`}</span>
)}
</div>
</div>
</div>
<div className={styles.rightBox}>{text}</div>
<div className={styles.rightBox} onClick={onOperation}>
{text}
</div>
</div>
);
};
});
export default FileItem;
......@@ -2,11 +2,11 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-10 18:05:21
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-14 21:00:46
* @LastEditTime: 2022-06-16 03:05:08
* @FilePath: /bkunyun/src/views/ConsoleLayout/components/TransferList/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import { Box, InputLabel, MenuItem, Select } from "@mui/material";
import { Box } from "@mui/material";
import { memo } from "react";
import MySelect from "@/components/mui/MySelect";
......@@ -14,9 +14,11 @@ import MyTitle from "@/components/mui/MyTitle";
import FileItem from "../FileItem";
import useGlobalStore from "@/hooks/useGlobalStore";
import { observer } from "mobx-react-lite";
import { toJS } from "mobx";
const TranSferList = observer(() => {
const fileList = useGlobalStore("fileListStore");
const uploadInfoStore = toJS(useGlobalStore("fileListStore"));
return (
<Box style={{ width: 520, padding: 20 }}>
<MyTitle title="传输列表" />
......@@ -45,8 +47,8 @@ const TranSferList = observer(() => {
/>
</Box>
<Box>
{fileList?.fileList.map((item) => {
return <FileItem fileItemInfo={item} />;
{uploadInfoStore?.fileList.map((item) => {
return <FileItem fileItemInfo={item} key={item.id} />;
})}
</Box>
</Box>
......
......@@ -3,7 +3,6 @@ import { Outlet, useLocation, useNavigate } from "react-router-dom";
import cx from "classnames";
import { observer } from "mobx-react-lite";
import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
import Add from "@mui/icons-material/Add";
import Avatar from "@mui/material/Avatar";
import { Box, Menu, MenuItem } from "@mui/material";
......@@ -17,13 +16,6 @@ import MyPopover from "@/components/mui/MyPopover";
import TranSferList from "./components/TransferList";
import style from "./index.module.css";
import useGlobalStore from "@/hooks/useGlobalStore";
import { toJS } from "mobx";
import { APIOPTION, urlToken } from "@/api/fileserver/raysyncApi";
import UseTusUpload from "@/utils/Upload/tusUpload";
import useMyRequest from "@/hooks/useMyRequest";
import { getDataFileToken } from "@/api/project_api";
import useDeepEffect from "@/hooks/useDeepEffect";
const ConsoleLayout = observer(() => {
const {
......@@ -44,44 +36,6 @@ const ConsoleLayout = observer(() => {
permissionStore.setSidebarRouters(location.pathname);
}, [location, permissionStore]);
const fileList = toJS(useGlobalStore("fileListStore"));
const currentProjectStore = toJS(useGlobalStore("currentProjectStore"));
const { uploadFile } = UseTusUpload({
fileListStore: fileList,
currentProjectStore,
});
/** 获取文件token请求 */
const { run: getDataFileTokenRun } = useMyRequest(getDataFileToken, {
onSuccess: (res: any) => {
let url =
APIOPTION() +
"/parallelupload/" +
urlToken(
res?.data || "",
currentProjectStore?.currentProjectInfo?.id as string
);
fileList?.newFileList?.forEach((item: any) => {
uploadFile(
item,
item?.file,
url,
"/",
(upload: any, filepath: string) => console.log(upload, filepath, 1111)
);
});
},
});
useDeepEffect(() => {
if (fileList?.newFileList?.length) {
console.log(111, 222);
getDataFileTokenRun({
id: currentProjectStore?.currentProjectInfo.id || "",
});
}
}, [fileList?.newFileList]);
return (
<Box>
<Box className={style.topApp}>
......
......@@ -8,7 +8,7 @@ import React, {
import style from "./index.module.css";
import MyDialog from "@/components/mui/MyDialog";
import { Button } from "@mui/material";
import { uuid } from "@/utils/util";
import { getTokenInfo, uuid } from "@/utils/util";
import { useMessage } from "@/components/MySnackbar";
import { useDropzone } from "react-dropzone";
import Table from "@/components/Material.Ui/Table";
......@@ -20,10 +20,16 @@ import { storageUnitFromB } from "@/utils/util";
import { observer } from "mobx-react";
import { useStores } from "@/store";
import { toJS } from "mobx";
import { IResponse, useHttp } from "@/api/http";
import useGlobalStore from "@/hooks/useGlobalStore";
import { APIOPTION, urlToken } from "@/api/fileserver/raysyncApi";
import UseTusUpload from "@/utils/Upload/tusUpload";
const UpLoaderFile = observer((props: any) => {
const { fileListStore } = useStores();
const message = useMessage();
const http = useHttp();
const [fileList, setFileList] = useState<any>([]);
// list 是项目数据table的数据
const { path, list } = props;
......@@ -33,6 +39,10 @@ const UpLoaderFile = observer((props: any) => {
return [...list, ...fileList];
}, [list, fileList]);
const currentProjectStore = toJS(useGlobalStore("currentProjectStore"));
const uploadInfoStore = toJS(useGlobalStore("fileListStore"));
const { uploadFile } = UseTusUpload(uploadInfoStore);
const onDrop = useCallback(
(acceptedFiles: any) => {
// 获取重复的项目文件列表和要上传(名称不重复就上传)的文件
......@@ -97,6 +107,38 @@ const UpLoaderFile = observer((props: any) => {
let dialogRef: any = React.createRef();
const getFileToken = useCallback(
(newFileList: any) => {
http
.get<IResponse<any>>(
`/cpp/data/filetoken?id=${
currentProjectStore?.currentProjectInfo.id || ""
}`
)
.then((res: any) => {
let url =
APIOPTION() +
"/parallelupload/" +
urlToken(
res?.data || "",
currentProjectStore?.currentProjectInfo?.id as string
);
newFileList?.forEach((item: any) => {
uploadFile(
item,
item?.file,
url,
res.data,
"/",
(upload: any, filepath: string) =>
console.log(upload, filepath, 1111)
);
});
});
},
[currentProjectStore?.currentProjectInfo.id, http, uploadFile]
);
const handleSubmit = () => {
const newFileList =
fileList?.map((item: any) => {
......@@ -109,6 +151,10 @@ const UpLoaderFile = observer((props: any) => {
};
}) || [];
toJS(fileListStore?.setNewFileList)(newFileList);
if (newFileList?.length) {
getFileToken(newFileList);
}
dialogRef.current.handleClose();
};
const showDialog = () => {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment