fix: 修改上传方案
This commit is contained in:
parent
ef444ad9e8
commit
b65cb471e3
2
global.d.ts
vendored
2
global.d.ts
vendored
@ -1,5 +1,5 @@
|
|||||||
interface IBaseAPI {
|
interface IBaseAPI {
|
||||||
uploadFile: (path: string) => void
|
uploadFile: (path: File[]) => void
|
||||||
setTitle: (value: string) => void
|
setTitle: (value: string) => void
|
||||||
onUploadProgress: (progress: unknown) => void
|
onUploadProgress: (progress: unknown) => void
|
||||||
}
|
}
|
||||||
|
@ -25,9 +25,9 @@ const createWindow = (): void => {
|
|||||||
win.setTitle(title)
|
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.
|
// and load the index.html of the app.
|
||||||
|
@ -1,51 +1,65 @@
|
|||||||
import { message, Upload, UploadProps } from 'antd'
|
import { Button, message, Upload } from 'antd'
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
import type { GetProp, UploadFile, UploadProps } from 'antd';
|
||||||
|
|
||||||
|
type FileType = Parameters<GetProp<UploadProps, 'beforeUpload'>>[0];
|
||||||
|
|
||||||
const { Dragger } = Upload;
|
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 () => {
|
export default () => {
|
||||||
const [progress, setProgress] = useState(0)
|
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 (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Dragger {...props}>
|
<Dragger {...uploadProps}>
|
||||||
<p className="ant-upload-drag-icon">
|
<p className="ant-upload-drag-icon">
|
||||||
✋{progress}
|
✋{progress}
|
||||||
</p>
|
</p>
|
||||||
<p className="ant-upload-text">文件拖拽到这上传</p>
|
<p className="ant-upload-text">文件拖拽到这上传</p>
|
||||||
</Dragger>
|
</Dragger>
|
||||||
|
<Button block onClick={() => handleUpload()} >上传</Button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -10,7 +10,7 @@ contextBridge.exposeInMainWorld('versions', {
|
|||||||
|
|
||||||
contextBridge.exposeInMainWorld('baseAPI', {
|
contextBridge.exposeInMainWorld('baseAPI', {
|
||||||
setTitle: (title: string) => ipcRenderer.send('set-title', title),
|
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',
|
onUploadProgress: (cb: (progress: string) => void) => ipcRenderer.on('upload-progress',
|
||||||
(_event, progress) => {
|
(_event, progress) => {
|
||||||
cb?.(progress)
|
cb?.(progress)
|
||||||
|
@ -1,22 +1,65 @@
|
|||||||
|
import { app } from 'electron';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
|
import path from 'node:path';
|
||||||
|
|
||||||
export const uploadFile = (filePath: File['path'], sender) => {
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
const fileSize = fs.statSync(filePath).size;
|
export const uploadFile = (filePaths: string[], _sender: Electron.WebContents) => {
|
||||||
let uploadedSize = 0;
|
// 获取用户当前文件夹路径
|
||||||
|
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);
|
// const readStream = fs.createReadStream(filePath);
|
||||||
|
|
||||||
readStream.on('data', (chunk) => {
|
// readStream.on('data', (chunk) => {
|
||||||
uploadedSize += chunk.length;
|
// uploadedSize += chunk.length;
|
||||||
const progress = Math.round((uploadedSize / fileSize) * 100);
|
// const progress = Math.round((uploadedSize / fileSize) * 100);
|
||||||
sender.send('upload-progress', progress);
|
// sender.send('upload-progress', progress);
|
||||||
});
|
// });
|
||||||
|
|
||||||
readStream.on('end', () => {
|
// readStream.on('end', () => {
|
||||||
sender.send('upload-success');
|
// sender.send('upload-success');
|
||||||
});
|
// });
|
||||||
|
|
||||||
readStream.on('error', (err) => {
|
// readStream.on('error', (err) => {
|
||||||
sender.send('upload-error', err.message);
|
// 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 + '');//分片数
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user