Python一键打包exe
2026/5/14 6:18:21
作为上海OA软件公司前端工程师,针对公司OA系统50G级大文件传输需求,我进行了深入的技术调研与分析。结合公司现有技术栈和业务需求,现提出以下技术方案。
核心功能:
兼容性要求:
部署要求:
// 文件分片上传核心逻辑示例(Vue3 Composition API)import{ref,onMounted}from'vue'importSparkMD5from'spark-md5'exportfunctionuseFileUploader(options){const{apiUrl,chunkSize=5*1024*1024}=optionsconstprogress=ref(0)constfileInfo=ref(null)// 从本地存储恢复上传状态constrestoreUploadState=(fileId)=>{constsavedState=localStorage.getItem(`upload_${fileId}`)returnsavedState?JSON.parse(savedState):null}// 计算文件MD5(用于唯一标识)constcalculateFileMD5=(file)=>{returnnewPromise((resolve)=>{constchunkSize=5*1024*1024constchunks=Math.ceil(file.size/chunkSize)constspark=newSparkMD5.ArrayBuffer()constfileReader=newFileReader()letcurrentChunk=0fileReader.onload=(e)=>{spark.append(e.target.result)currentChunk++if(currentChunk<chunks){loadNextChunk()}else{resolve(spark.end())}}constloadNextChunk=()=>{conststart=currentChunk*chunkSizeconstend=Math.min(start+chunkSize,file.size)fileReader.readAsArrayBuffer(file.slice(start,end))}loadNextChunk()})}// 分片上传主逻辑constuploadFile=async(file)=>{try{// 恢复或初始化上传状态constfileId=awaitcalculateFileMD5(file)letuploadState=restoreUploadState(fileId)||{fileId,fileName:file.name,fileSize:file.size,uploadedSize:0,chunks:Math.ceil(file.size/chunkSize),uploadedChunks:0}// 如果已上传过部分文件,跳过已上传分片conststartByte=uploadState.uploadedSizeconstendByte=Math.min(startByte+chunkSize,file.size)constchunk=file.slice(startByte,endByte)constformData=newFormData()formData.append('file',chunk)formData.append('fileId',fileId)formData.append('chunkIndex',uploadState.uploadedChunks)formData.append('totalChunks',uploadState.chunks)formData.append('fileName',file.name)formData.append('relativePath',uploadState.relativePath||'')// 用于文件夹结构constresponse=awaitfetch(apiUrl,{method:'POST',body:formData})if(response.ok){uploadState.uploadedSize=endByte uploadState.uploadedChunks++progress.value=Math.min(100,(uploadState.uploadedSize/file.size)*100)// 保存上传状态到本地存储localStorage.setItem(`upload_${fileId}`,JSON.stringify(uploadState))// 如果上传完成,清理状态if(uploadState.uploadedSize>=file.size){localStorage.removeItem(`upload_${fileId}`)fileInfo.value={...uploadState,completed:true}}}}catch(error){console.error('Upload error:',error)throwerror}}return{progress,fileInfo,uploadFile}}核心模块:
数据库设计:
CREATETABLEfile_upload_task(idBIGINTPRIMARYKEYAUTO_INCREMENT,file_idVARCHAR(64)NOTNULLCOMMENT'文件唯一标识',file_nameVARCHAR(255)NOTNULL,relative_pathVARCHAR(512)COMMENT'文件夹相对路径',total_sizeBIGINTNOTNULL,uploaded_sizeBIGINTNOTNULLDEFAULT0,chunk_countINTNOTNULL,uploaded_chunksINTNOTNULLDEFAULT0,statusTINYINTNOTNULLDEFAULT0COMMENT'0:上传中 1:已完成 2:已取消',create_timeDATETIMENOTNULL,update_timeDATETIMENOTNULL,INDEXidx_file_id(file_id));-- 可扩展支持多数据库的JPA实体示例@Entity@Table(name="file_upload_task")@Inheritance(strategy=InheritanceType.SINGLE_TABLE)@DiscriminatorColumn(name="db_type",discriminatorType=DiscriminatorType.STRING)publicabstract class FileUploadTask {@Id@GeneratedValue(strategy=GenerationType.IDENTITY)private Long id;@Column(nullable=false,length=64)private String fileId;// 其他字段...// 数据库类型抽象方法,由子类实现具体逻辑publicabstract DatabaseType getDatabaseType();}// MySQL实现@Entity@DiscriminatorValue("MYSQL")publicclass MySQLFileUploadTask extends FileUploadTask {@OverridepublicDatabaseType getDatabaseType(){returnDatabaseType.MYSQL;} }前端方案:
localStorage持久化上传进度(IE11兼容)后端方案:
前端实现:
// 递归处理文件夹结构constprocessFolder=(entry,relativePath='')=>{returnnewPromise((resolve)=>{if(entry.isFile){entry.file(file=>{resolve([{file,relativePath}])})}elseif(entry.isDirectory){constdirReader=entry.createReader()dirReader.readEntries(entries=>{constpromises=[]entries.forEach(subEntry=>{promises.push(processFolder(subEntry,`${relativePath}${entry.name}/`))})Promise.all(promises).then(results=>{resolve(results.flat())})})}})}// 使用示例(结合HTML5 File System Access API)consthandleDrop=async(event)=>{constitems=event.dataTransfer.itemsfor(leti=0;i<items.length;i++){constentry=items[i].webkitGetAsEntry?items[i].webkitGetAsEntry():nullif(entry){constfiles=awaitprocessFolder(entry)files.forEach(fileItem=>{uploadFile(fileItem.file,fileItem.relativePath)})}}}IE11支持:
FileReaderpolyfillfetchpolyfill或回退到XMLHttpRequest360浏览器处理:
大文件处理优化:
完全可控性:
成本效益:
技术适配性:
第一阶段(2周):
第二阶段(2周):
第三阶段(1周):
IE11兼容性风险:
大文件传输稳定性风险:
性能瓶颈风险:
基于公司现有技术栈和业务需求,自研大文件传输组件是最佳选择。该方案既能满足当前50G级文件传输需求,又能与公司OA系统深度集成,同时通过源代码采购模式实现长期可控的成本效益。建议尽快启动研发工作,优先实现核心功能,再逐步完善兼容性和扩展性。
导入到Eclipse:点南查看教程
导入到IDEA:点击查看教程
springboot统一配置:点击查看教程
NOSQL示例不需要任何配置,可以直接访问测试
选择对应的数据表脚本,这里以SQL为例
up6/upload/年/月/日/guid/filename
支持离线保存文件进度,在关闭浏览器,刷新浏览器后进行不丢失,仍然能够继续上传
支持上传文件夹并保留层级结构,同样支持进度信息离线保存,刷新页面,关闭页面,重启系统不丢失上传进度。
点击下载完整示例