diff --git a/scripts/deploy-oss.js b/scripts/deploy-oss.js index 893f768d..0314596d 100644 --- a/scripts/deploy-oss.js +++ b/scripts/deploy-oss.js @@ -47,31 +47,58 @@ function getAllFiles(dir, fileList = []) { // 上传文件,显示进度,可跳过指定目录 /** - * @param {string[]} files - 要上传的所有文件完整路径 - * @param {string} localBase - 本地基准路径 - * @param {string[]} ignoreDirs - 相对 localBase 的目录名数组,上传时会跳过这些目录 + * 上传文件并清理远端多余文件 + * @param files 本地文件完整路径列表 + * @param localBase 本地基准路径 + * @param ignoreDirs 相对 localBase 的目录名数组,上传时跳过,删除远端时保留 */ -async function uploadFiles(files, localBase = './dist', ignoreDirs = []) { +async function uploadFilesWithClean(files, localBase = './dist', ignoreDirs = []) { + // 1️⃣ 过滤掉忽略的目录 const filteredFiles = files.filter(file => { const relativePath = path.relative(localBase, file) - // 获取文件所在目录的第一级 const topDir = relativePath.split(path.sep)[0] - // 如果在 ignoreDirs 中,就跳过 return !ignoreDirs.includes(topDir) }) + // 2️⃣ 获取远端已有文件列表 + console.log('📄 获取远端文件列表...') + const remoteList = await client.list({prefix: ''}) // 返回 { name, size, ... } 数组 + const remoteFiles = remoteList.map(f => f.name) + + // 3️⃣ 上传文件 const total = filteredFiles.length let count = 0 + const uploadedFiles = [] for (const file of filteredFiles) { const relativePath = path.relative(localBase, file) - const remotePath = relativePath.split(path.sep).join('/') // 转 POSIX 路径 + const remotePath = relativePath.split(path.sep).join('/') // POSIX 路径 await client.put(remotePath, file) + uploadedFiles.push(remotePath) count++ const percent = ((count / total) * 100).toFixed(1) process.stdout.write(`\r📤 上传进度: ${count}/${total} (${percent}%) ${remotePath} `) } - console.log('\n✅ 文件全部上传完成') + console.log('\n✅ 文件上传完成') + + // 4️⃣ 删除远端多余文件(远端存在但本地未上传),同时保留 ignoreDirs + const toDelete = remoteFiles.filter(f => { + const topDir = f.split('/')[0] + return !uploadedFiles.includes(f) && !ignoreDirs.includes(topDir) + }) + + if (toDelete.length) { + console.log('🗑 删除远端多余文件:', toDelete) + // 分批删除,防止数量过多 + const batchSize = 1000 + for (let i = 0; i < toDelete.length; i += batchSize) { + const batch = toDelete.slice(i, i + batchSize) + await client.deleteMulti(batch) + } + console.log('✅ 多余文件删除完成') + } else { + console.log('ℹ️ 无需删除远端文件') + } } @@ -79,8 +106,8 @@ async function uploadFiles(files, localBase = './dist', ignoreDirs = []) { async function refreshCDN() { console.log('🔄 刷新 CDN 缓存...') const params = { - ObjectPath: `https://${CDN_DOMAIN}/*`, - ObjectType: 'File' + ObjectPath: `https://${CDN_DOMAIN}/`, + ObjectType: 'Directory' } const requestOption = {method: 'POST'} const result = await cdnClient.request('RefreshObjectCaches', params, requestOption) @@ -90,7 +117,7 @@ async function refreshCDN() { async function main() { const files = getAllFiles('./dist') console.log(`📁 共找到 ${files.length} 个文件,开始上传...`) - await uploadFiles(files, './dist', ['dicts', 'sound']) + await uploadFilesWithClean(files, './dist', ['dicts', 'sound', 'libs']) await refreshCDN() }