实测对比后!千笔·专业学术智能体,行业天花板级的AI论文平台

核心内容摘要

LFM2.5-1.2B-Thinking模型性能优化:从理论到实践
Goby 漏洞安全通告|Moltbot(Clawdbot)Gateways 未授权访问漏洞

Ollama金融应用实战:打造私有化AI股票分析工具

一个大三学生的文件管理系统血泪史前端篇各位看官我是浙江某高校网络工程专业的大三学生最近在搞一个史诗级项目——文件管理系统。

为啥说是史诗级因为光是需求就快把我整秃噜皮了项目背景我们导师说“小张啊现在找工作得有作品你做个文件管理系统吧要支持10G大文件上传、加密传输、断点续传、文件夹层级保留还要兼容IE8”我“老师您这是要让我重写百度网盘吗”导师“不我要你超越百度网盘”我“…”技术选型经过一番挣扎我选择了前端Vue3 原生JS因为导师说不能用jQuery上传组件WebUploader兼容性好 H5现代浏览器用开发工具VSCode因为Sublime Text要钱数据库MySQL因为导师说这个最简单服务器本地Windows 7 IE9学校老机器的配置前端实现血泪版

兼容性处理首先得解决IE8兼容问题我写了这么个神器// 检测浏览器并给出友好提示functiondetectBrowser(){constuserAgentnavigator.userAgent;if(userAgent.indexOf(MSIE)-1||userAgent.indexOf(Trident)-

{constversionuserAgent.match(/(MSIE |rv:)(\d)/)[2];if(version

{alert(检测到您使用的是IEversion本系统需要IE9或其他现代浏览器);// 偷偷给IE用户显示个可爱图片document.body.innerHTML亲爱的IE用户 请使用Chrome/Firefox/Edge/Safari等现代浏览器;}}}detectBrowser();

文件上传组件封装classFileUploader{constructor(options){this.chunkSizeoptions.chunkSize||5*1024*1024;// 默认5MB分片this.fileInputdocument.getElementById(options.inputId);this.uploadBtndocument.getElementById(options.uploadBtnId);this.progressBardocument.getElementById(options.progressId);this.fileList[];this.initEvents();}initEvents(){this.fileInput.addEventListener(change,(e)this.handleFileSelect(e));this.uploadBtn.addEventListener(click,()this.startUpload());}handleFileSelect(e){constfilesArray.from(e.target.files);this.fileListfiles.map(file({file,chunks:[],uploadedChunks:0,totalChunks:Math.ceil(file.size/this.chunkSize),fileId:this.generateFileId()}));// 显示文件列表简化版console.log(已选择文件:,this.fileList.map(ff.file.name));}generateFileId(){returnxxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx.replace(/[xy]/g,function(c){constrMath.random()*16|0;return(cx?r:(r0x3|0x

).toString(

;});}// 加密函数简化版encryptData(data){// 实际项目中应该用AES等加密算法// 这里只是演示返回Base64编码returnbtoa(unescape(encodeURIComponent(data)));}// 分片上传asyncuploadChunk(fileObj,chunkIndex){constfilefileObj.file;conststartchunkIndex*this.chunkSize;constendMath.min(file.size,startthis.chunkSize);constchunkfile.slice(start,end);// 加密分片数据constencryptedChunkthis.encryptData(chunk);// 这里应该用XMLHttpRequest或Fetch API发送到后端// 但导师说后端要我自己写所以我只能...console.log(模拟上传分片${chunkIndex1}/${fileObj.totalChunks}:${file.name});// 模拟网络延迟awaitnewPromise(resolvesetTimeout(resolve,

);return{success:true,chunkIndex};}asyncstartUpload(){if(this.fileList.length

{alert(请先选择文件);return;}for(constfileObjofthis.fileList){try{for(leti0;ifileObj.totalChunks;i){constresultawaitthis.uploadChunk(fileObj,i);if(result.success){fileObj.uploadedChunks;this.updateProgress(fileObj);// 保存上传进度到localStorage断点续传this.saveProgressToStorage(fileObj);}}console.log(文件${fileObj.file.name}上传完成);}catch(error){console.error(上传文件${fileObj.file.name}时出错:,error);}}}updateProgress(fileObj){constpercent(fileObj.uploadedChunks/fileObj.totalChunks*

.toFixed(

;this.progressBar.style.widthpercent%;this.progressBar.textContentpercent%;}saveProgressToStorage(fileObj){constprogressData{fileId:fileObj.fileId,fileName:fileObj.file.name,uploadedChunks:fileObj.uploadedChunks,totalChunks:fileObj.totalChunks,fileSize:fileObj.file.size,lastModified:fileObj.file.lastModified};localStorage.setItem(uploadProgress_${fileObj.fileId},JSON.stringify(progressData));}// 从localStorage恢复上传进度staticrestoreProgress(){constprogressItems{};for(leti0;ilocalStorage.length;i){constkeylocalStorage.key(i);if(key.startsWith(uploadProgress_)){constdataJSON.parse(localStorage.getItem(key));progressItems[key]data;}}returnprogressItems;}}// 使用示例document.addEventListener(DOMContentLoaded,(){constuploadernewFileUploader({inputId:fileInput,uploadBtnId:uploadBtn,progressId:progressBar});// 恢复上传进度constprogressFileUploader.restoreProgress();console.log(恢复的上传进度:,progress);});

Vue3组件封装export default { name: FileUploader, data() { return { files: [], chunkSize: 5 * 1024 * 1024, // 5MB uploadProgress: {} }; }, methods: { handleFileChange(e) { const files Array.from(e.target.files); // 处理文件夹上传WebKit browsers if (files.length 0 e.target.webkitEntries) { const entries Array.from(e.target.webkitEntries); this.processDirectoryEntries(entries); return; } this.files files.map(file ({ file, name: file.name, size: file.size, uploaded: false, uploadedSize: 0 })); }, processDirectoryEntries(entries) { // 实际项目中需要递归处理文件夹结构 // 这里简化处理只取文件 const files []; const processEntry (entry) { if (entry.isFile) { entry.file(file { files.push(file); if (files.length entries.length) { this.files files.map(file ({ file, name: file.name, size: file.size, uploaded: false, uploadedSize: 0 })); } }); } }; entries.forEach(processEntry); }, async startUpload() { if (this.files.length

{ alert(请先选择文件或文件夹); return; } for (const fileObj of this.files) { try { await this.uploadFile(fileObj); fileObj.uploaded true; } catch (error) { console.error(上传文件 ${fileObj.name} 时出错:, error); } } }, async uploadFile(fileObj) { const file fileObj.file; const totalChunks Math.ceil(file.size / this.chunkSize); for (let i 0; i totalChunks; i) { const start i * this.chunkSize; const end Math.min(file.size, start this.chunkSize); const chunk file.slice(start, end); // 加密分片实际项目中应该用更安全的加密方式 const encryptedChunk this.simpleEncrypt(chunk); // 这里应该调用后端API上传分片 // 但导师说后端要我自己写所以我只能... console.log(上传分片 ${i 1}/${totalChunks}: ${file.name}); // 模拟网络延迟 await new Promise(resolve setTimeout(resolve,

); fileObj.uploadedSize end; this.updateProgress(); } }, simpleEncrypt(data) { // 超级简单的加密实际项目不能用 return data; // 这里应该返回加密后的数据 }, updateProgress() { const totalUploaded this.files.reduce((sum, file) sum file.uploadedSize,

; const totalSize this.files.reduce((sum, file) sum file.size,

; const percent Math.round((totalUploaded / totalSize) *

; this.$refs.progressBar.style.width percent %; this.$refs.progressBar.nextElementSibling.textContent percent %; }, restoreUpload() { // 从localStorage恢复上传进度 const progressItems {}; for (let i 0; i localStorage.length; i) { const key localStorage.key(i); if (key.startsWith(uploadProgress_)) { const data JSON.parse(localStorage.getItem(key)); progressItems[key] data; } } console.log(恢复的上传进度:, progressItems); alert(上传进度已恢复控制台查看详情); }, formatFileSize(bytes) { if (bytes

return 0 Bytes; const k 1024; const sizes [Bytes, KB, MB, GB]; const i Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(

) sizes[i]; } }, mounted() { // 检测浏览器兼容性 this.detectBrowser(); }, methods: { detectBrowser() { const userAgent navigator.userAgent; if (userAgent.indexOf(MSIE) -1 || userAgent.indexOf(Trident) -

{ const version userAgent.match(/(MSIE |rv:)(\d)/)[2]; if (version

{ alert(检测到您使用的是IE${version}本系统需要IE9或其他现代浏览器); document.body.innerHTML div styletext-align:center; padding:50px; h1亲爱的IE用户/h1 img srchttps://http.cat/

jpg altIE已淘汰 p请使用Chrome/Firefox/Edge/Safari等现代浏览器/p /div ; } } } } }; .file-uploader { max-width: 800px; margin: 0 auto; padding: 20px; font-family: Arial, sans-serif; } .upload-area { margin: 20px 0; padding: 20px; border: 2px dashed #ccc; text-align: center; } .progress-container { margin: 20px 0; height: 30px; background: #f0f0f0; border-radius: 15px; position: relative; } .progress-bar { height: 100%; background: #4CAF50; border-radius: 15px; width: 0%; transition: width

3s; } .progress-text { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #333; } .file-list { margin-top: 30px; } .file-list ul { list-style: none; padding: 0; } .file-list li { padding: 8px; border-bottom: 1px solid #eee; }项目趣事IE8兼容大战为了兼容IE8我尝试了各种polyfill最后发现还是直接显示请升级浏览器更实际文件夹上传WebUploader对文件夹上传支持不好我研究了半天发现原来要用webkitdirectory属性断点续传本来想用IndexedDB存储上传进度发现IE不支持最后改用localStorage虽然有大小限制加密传输研究了AES加密发现实现起来太复杂最后用了简单的Base64编码导师说这不算真正的加密求助与展望现在前端部分勉强能跑但后端完全没头绪。

群里的小伙伴们也都在喊后端大佬救命在此我郑重声明不提供后端代码因为我也不会欢迎大佬加入QQ群374992201指导加群送

元红包老板说这是营销策略推荐工作成功者送20%项目提成虽然现在还没项目最后如果哪位师哥师姐愿意收我为徒教我后端开发我愿意每天给您请安帮您写前端代码毕业设计可以挂您名字未来第一年工资分您10%联系方式QQ群374992201群里找我求带的小张将组件复制到项目中示例中已经包含此目录引入组件配置接口地址接口地址分别对应文件初始化文件数据上传文件进度文件上传完毕文件删除文件夹初始化文件夹删除文件列表参考http://www.ncmem.com/doc/view.aspx?ide1f49f3e1d4742e19135e00bd41fa3de处理事件启动测试启动成功效果数据库效果预览文件上传文件刷新续传支持离线保存文件进度在关闭浏览器刷新浏览器后进行不丢失仍然能够继续上传文件夹上传支持上传文件夹并保留层级结构同样支持进度信息离线保存刷新页面关闭页面重启系统不丢失上传进度。

下载示例点击下载完整示例

虫虫漫画页面免费漫画在线阅读窗-虫虫漫画页面免费漫画在线阅读窗应用

百度百家号客服电话人工服务

123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123