修复Google Drive同请求ID附件文件夹重复创建问题
问题修复:多附件上传时重复创建请求ID文件夹
问题根源
- 重复生成请求ID:每次调用
saveFile都会执行generateId(),前端同时上传两个文件时,两次后端调用几乎同步,导致生成相同ID或因generateId的bug生成异常ID。 - 文件夹检测时机问题:异步上传时,第一个文件正在创建文件夹,第二个文件的
folderExists检测还未查到新文件夹,因此重复创建同名目录。 generateId函数bug:代码中id = lastId + 1;的lastId未定义,未正确获取上一次请求的序号。
修复步骤
1. 修改前端JavaScript:统一生成请求ID并传给后端
在前端一次性生成请求ID,所有附件上传共享该ID,避免后端重复生成:
function getFiles(){ // 先统一获取请求ID google.script.run.withSuccessHandler(requestId => { const f = document.getElementById('photoPres'); if (f.files.length > 0){ [...f.files].forEach((file, i) => { const fr = new FileReader(); fr.onload = (e) => { const data = e.target.result.split(","); const obj = { fileName: f.files[i].name, mimeType: data[0].match(/:(\w.+);/)[1], data: data[1], requestId: requestId }; google.script.run.withSuccessHandler(info => { document.getElementById("idPhotoPres").innerHTML = info.id; }).saveFile(obj); } fr.readAsDataURL(file); }); } const f2 = document.getElementById('photoLoin'); if (f2.files.length > 0){ [...f2.files].forEach((file2, i) => { const fr2 = new FileReader(); fr2.onload = (e) => { const data = e.target.result.split(","); const obj = { fileName: f2.files[i].name, mimeType: data[0].match(/:(\w.+);/)[1], data: data[1], requestId: requestId }; google.script.run.withSuccessHandler(info => { document.getElementById("idPhotoLoin").innerHTML = info.id; }).saveFile(obj); } fr2.readAsDataURL(file2); }); } }).generateId(); }
2. 修复后端saveFile函数:使用前端传入的请求ID
不再在saveFile中生成ID,改用前端传入的统一ID,确保所有附件存入同一目录:
function saveFile(obj){ var pieceJointe = Utilities.newBlob(Utilities.base64Decode(obj.data), obj.mimeType, obj.fileName); const dossierDrive = DriveApp.getFolderById('1KRwd79dc8k8EArwHU_1RnkDHd-Sdv0DJ'); // 使用前端传入的requestId const idDemande = obj.requestId; var dossierPieceJointe; var idDosssier = folderExists(idDemande); if (idDosssier !== false) { dossierPieceJointe = DriveApp.getFolderById(idDosssier); } else { dossierPieceJointe = dossierDrive.createFolder(idDemande); } // 统一返回附件的ID和URL const pieceJointeAjoutee = dossierPieceJointe.createFile(pieceJointe); const informationsPJ = { 'url' : pieceJointeAjoutee.getUrl(), 'id' : pieceJointeAjoutee.getId() }; return informationsPJ; }
3. 修复generateId函数的bug
修正未定义变量的问题,正确生成递增的请求ID:
function generateId(){ const classeur = SpreadsheetApp.getActiveSpreadsheet(); const webAppSheet = classeur.getSheetByName("Demandes"); var lastRow = webAppSheet.getLastRow(); var splitId = []; var id; var lastDemande = ""; if(lastRow == 1){ const newId = (new Date().getFullYear()) + "_1"; const feuilleBDD = classeur.getSheetByName("BDD"); feuilleBDD.getRange("I2").setValue(1); return newId; }else{ lastDemande = webAppSheet.getRange(lastRow, 1).getValue(); splitId = lastDemande.split('_'); if (splitId[0] == new Date().getFullYear()){ // 将上一次ID的序号转为数字后加1 id = parseInt(splitId[1]) + 1; const feuilleBDD = classeur.getSheetByName("BDD"); feuilleBDD.getRange("I2").setValue(id); return (new Date().getFullYear()) + "_" + id; } else { const feuilleBDD = classeur.getSheetByName("BDD"); feuilleBDD.getRange("I2").setValue(1); return (new Date().getFullYear()) + "_1"; } } }
4. 优化folderExists函数:提升查找效率
替换遍历逻辑为搜索查询,减少资源消耗:
function folderExists(nomDossierPJ) { const dossierDrive = DriveApp.getFolderById('1KRwd79dc8k8EArwHU_1RnkDHd-Sdv0DJ'); // 使用Drive搜索直接定位同名文件夹 const folders = dossierDrive.searchFolders(`title='${nomDossierPJ}'`); return folders.hasNext() ? folders.next().getId() : false; }
修复说明
- 前端统一获取请求ID,确保所有附件上传共享同一ID,从根源避免重复目录。
- 后端不再重复生成ID,消除异步调用导致的检测延迟问题。
- 修正
generateId的变量错误,保证ID生成逻辑稳定。 - 优化文件夹检测逻辑,提升查找速度。
内容的提问来源于stack exchange,提问作者devMethodes
相关产品推荐
相关产品推荐

