/** * QR Code 產生器 - Google Drive 上傳模組 */ /** * 上傳圖片到 Google Drive * @param {string} base64Image - Base64 編碼的圖片 * @param {string} filename - 檔案名稱 * @param {string} folderId - 目標資料夾 ID * @returns {Object} 上傳結果 */ function uploadToDrive(base64Image, filename, folderId) { try { // 解碼 Base64 const decoded = Utilities.base64Decode(base64Image); const blob = Utilities.newBlob(decoded, 'image/jpeg', filename); // 取得目標資料夾 const folder = DriveApp.getFolderById(folderId); // 檢查是否已存在同名檔案 const existingFiles = folder.getFilesByName(filename); if (existingFiles.hasNext()) { // 刪除舊檔案 const oldFile = existingFiles.next(); oldFile.setTrashed(true); } // 上傳新檔案 const file = folder.createFile(blob); // 設定分享權限(可選:設為任何人可檢視) // file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW); return { success: true, fileId: file.getId(), fileName: file.getName(), webViewLink: file.getUrl(), downloadUrl: 'https://drive.google.com/uc?export=download&id=' + file.getId() }; } catch (error) { throw new Error('Drive 上傳失敗: ' + error.message); } } /** * 取得資料夾資訊 * @param {string} folderId - 資料夾 ID * @returns {Object} 資料夾資訊 */ function getFolderInfo(folderId) { try { const folder = DriveApp.getFolderById(folderId); // 取得完整路徑 const path = getFolderPath(folder); return { success: true, id: folder.getId(), name: folder.getName(), path: path, url: folder.getUrl() }; } catch (error) { return { success: false, error: '無法存取資料夾: ' + error.message }; } } /** * 取得資料夾完整路徑 * @param {Folder} folder - 資料夾物件 * @returns {string} 完整路徑 */ function getFolderPath(folder) { const pathParts = [folder.getName()]; let parent = folder.getParents(); while (parent.hasNext()) { const parentFolder = parent.next(); pathParts.unshift(parentFolder.getName()); parent = parentFolder.getParents(); } return pathParts.join(' / '); } /** * 列出使用者可存取的資料夾(用於下拉選單) * @param {string} searchQuery - 搜尋關鍵字(可選) * @returns {Array} 資料夾列表 */ function listFolders(searchQuery) { const folders = []; let query = 'mimeType = "application/vnd.google-apps.folder"'; if (searchQuery) { query += ' and name contains "' + searchQuery + '"'; } const iterator = DriveApp.searchFolders(query); let count = 0; const maxResults = 50; while (iterator.hasNext() && count < maxResults) { const folder = iterator.next(); folders.push({ id: folder.getId(), name: folder.getName(), path: getFolderPath(folder) }); count++; } return folders; } /** * 建立新資料夾 * @param {string} folderName - 資料夾名稱 * @param {string} parentFolderId - 父資料夾 ID(可選,預設為根目錄) * @returns {Object} 新資料夾資訊 */ function createFolder(folderName, parentFolderId) { try { let parentFolder; if (parentFolderId) { parentFolder = DriveApp.getFolderById(parentFolderId); } else { parentFolder = DriveApp.getRootFolder(); } // 檢查是否已存在同名資料夾 const existing = parentFolder.getFoldersByName(folderName); if (existing.hasNext()) { const existingFolder = existing.next(); return { success: true, isNew: false, id: existingFolder.getId(), name: existingFolder.getName(), path: getFolderPath(existingFolder), message: '資料夾已存在,使用現有資料夾' }; } // 建立新資料夾 const newFolder = parentFolder.createFolder(folderName); return { success: true, isNew: true, id: newFolder.getId(), name: newFolder.getName(), path: getFolderPath(newFolder), message: '已建立新資料夾' }; } catch (error) { return { success: false, error: '建立資料夾失敗: ' + error.message }; } } /** * 檢查資料夾是否有寫入權限 * @param {string} folderId - 資料夾 ID * @returns {boolean} 是否有權限 */ function checkFolderPermission(folderId) { try { const folder = DriveApp.getFolderById(folderId); // 嘗試取得 editors,如果沒有權限會拋出錯誤 const access = folder.getAccess(Session.getActiveUser()); return access === DriveApp.Permission.EDIT || access === DriveApp.Permission.OWNER; } catch (error) { return false; } } /** * 批次上傳圖片 * @param {Array} images - 圖片陣列 [{base64, filename}, ...] * @param {string} folderId - 目標資料夾 ID * @returns {Array} 上傳結果陣列 */ function uploadToDriveBatch(images, folderId) { const results = []; const folder = DriveApp.getFolderById(folderId); for (const image of images) { try { const decoded = Utilities.base64Decode(image.base64); const blob = Utilities.newBlob(decoded, 'image/jpeg', image.filename); const file = folder.createFile(blob); results.push({ success: true, filename: image.filename, fileId: file.getId(), webViewLink: file.getUrl() }); } catch (error) { results.push({ success: false, filename: image.filename, error: error.message }); } } return results; }