fix: 修改上传方案

This commit is contained in:
NICE CODE BY DEV 2024-04-06 23:37:12 +08:00
parent ef444ad9e8
commit b65cb471e3
5 changed files with 110 additions and 53 deletions

2
global.d.ts vendored
View File

@ -1,5 +1,5 @@
interface IBaseAPI {
uploadFile: (path: string) => void
uploadFile: (path: File[]) => void
setTitle: (value: string) => void
onUploadProgress: (progress: unknown) => void
}

View File

@ -25,9 +25,9 @@ const createWindow = (): void => {
win.setTitle(title)
})
ipcMain.on('upload', (event, filePath) => {
ipcMain.on('upload', (event, filePaths: string[]) => {
// 在后台线程中处理文件上传
uploadFile(filePath, event.sender);
uploadFile(filePaths, event.sender);
});
// and load the index.html of the app.

View File

@ -1,51 +1,65 @@
import { message, Upload, UploadProps } from 'antd'
import { Button, message, Upload } from 'antd'
import { useEffect, useState } from 'react';
import type { GetProp, UploadFile, UploadProps } from 'antd';
type FileType = Parameters<GetProp<UploadProps, 'beforeUpload'>>[0];
const { Dragger } = Upload;
const props: UploadProps = {
name: 'file',
multiple: true,
capture: 'user',
hasControlInside: false,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
action: false,
onChange(info) {
console.log('info', info)
const { status } = info.file;
if (status !== 'uploading') {
console.log(info.file, info.fileList);
}
if (status === 'done') {
message.success(`${info.file.name} file uploaded successfully.`);
} else if (status === 'error') {
message.error(`${info.file.name} file upload failed.`);
}
},
onDrop(e) {
console.log('Dropped files', e.dataTransfer.files);
},
};
export default () => {
const [progress, setProgress] = useState(0)
useEffect(() => {
window.baseAPI.onUploadProgress((_progress: unknown) => {
console.log('_progress', _progress)
setProgress(_progress)
})
}, [])
const [fileList, setFileList] = useState<UploadFile[]>([]);
const [uploading, setUploading] = useState(false);
const handleUpload = () => {
const formData = new FormData();
fileList.forEach((file) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
formData.append('files[]', file as FileType);
});
setUploading(true);
const filePaths = fileList.map((_file: any) => _file.path)
console.log('filePaths', filePaths)
window.baseAPI.uploadFile(filePaths)
setUploading(false)
};
const uploadProps: UploadProps = {
name: 'file',
multiple: true,
capture: 'user',
hasControlInside: false,
onRemove: (file) => {
const index = fileList.indexOf(file);
const newFileList = fileList.slice();
newFileList.splice(index, 1);
setFileList(newFileList);
},
beforeUpload: (file) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
setFileList([...fileList, file]);
return false;
},
onDrop(e) {
console.log('Dropped files', e.dataTransfer.files);
},
fileList,
};
return (
<div>
<Dragger {...props}>
<Dragger {...uploadProps}>
<p className="ant-upload-drag-icon">
{progress}
</p>
<p className="ant-upload-text"></p>
</Dragger>
<Button block onClick={() => handleUpload()} ></Button>
</div>
)
}

View File

@ -10,7 +10,7 @@ contextBridge.exposeInMainWorld('versions', {
contextBridge.exposeInMainWorld('baseAPI', {
setTitle: (title: string) => ipcRenderer.send('set-title', title),
uploadFile: (filePath: string) => ipcRenderer.send('upload', filePath),
uploadFile: (filePaths: string[]) => ipcRenderer.send('upload', filePaths),
onUploadProgress: (cb: (progress: string) => void) => ipcRenderer.on('upload-progress',
(_event, progress) => {
cb?.(progress)

View File

@ -1,22 +1,65 @@
import { app } from 'electron';
import fs from 'fs';
import path from 'node:path';
export const uploadFile = (filePath: File['path'], sender) => {
const fileSize = fs.statSync(filePath).size;
let uploadedSize = 0;
const readStream = fs.createReadStream(filePath);
readStream.on('data', (chunk) => {
uploadedSize += chunk.length;
const progress = Math.round((uploadedSize / fileSize) * 100);
sender.send('upload-progress', progress);
});
readStream.on('end', () => {
sender.send('upload-success');
});
readStream.on('error', (err) => {
sender.send('upload-error', err.message);
});
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export const uploadFile = (filePaths: string[], _sender: Electron.WebContents) => {
// 获取用户当前文件夹路径
const saveDirectoryPath = app.getPath('userData');
for (let i = 0; i < filePaths.length; i++) {
const fileName = path.basename(filePaths[i]);
const targetFilePath = path.join(saveDirectoryPath, fileName);
const fileStream = fs.createWriteStream(targetFilePath);
fileStream.write(fs.readFileSync(filePaths[i]));
fileStream.end();
console.log('Uploaded file saved at:', targetFilePath);
}
// const fileSize = fs.statSync(filePath).size;
// let uploadedSize = 0;
// const readStream = fs.createReadStream(filePath);
// readStream.on('data', (chunk) => {
// uploadedSize += chunk.length;
// const progress = Math.round((uploadedSize / fileSize) * 100);
// sender.send('upload-progress', progress);
// });
// readStream.on('end', () => {
// sender.send('upload-success');
// });
// readStream.on('error', (err) => {
// sender.send('upload-error', err.message);
// });
}
export const singleUpload = (file: File) => {
let path = file.path; //文件本地路径
let stats = fs.statSync(path); //读取文件信息
let chunkSize = 3 * 1024 * 1024; //每片分块的大小3M
let size = stats.size; //文件大小
let pieces = Math.ceil(size / chunkSize); //总共的分片数
function uploadPiece (i: number) {
//计算每块的结束位置
let enddata = Math.min(size, (i + 1) * chunkSize);
let arr: any[] = [];
//创建一个readStream对象根据文件起始位置和结束位置读取固定的分片
let readStream = fs.createReadStream(path, { start: i * chunkSize, end: enddata - 1 });
//on data读取数据
readStream.on('data', (data)=>{
arr.push(data)
})
//on end在该分片读取完成时触发
readStream.on('end', ()=>{
//这里服务端只接受blob对象需要把原始的数据流转成blob对象这块为了配合后端才转
let blob = new Blob(arr)
//新建formdata数据对象
var formdata = new FormData();
formdata.append("file", blob);
console.log('blob.size',blob.size)
formdata.append("size", size + ''); // 数字30被转换成字符串"30"
formdata.append("chunk", i + '');//第几个分片从0开始
formdata.append("chunks", pieces + '');//分片数
}
}