| 363 | // 文件上传管理器工厂 |
| 364 | // ===================================================================== |
| 365 | function createUploadManager(type) { |
| 366 | const modeParam = type === 'antigravity' ? 'mode=antigravity' : 'mode=geminicli'; |
| 367 | const endpoint = `./creds/upload?${modeParam}`; |
| 368 | |
| 369 | return { |
| 370 | type: type, |
| 371 | selectedFiles: [], |
| 372 | |
| 373 | getElementId: (suffix) => { |
| 374 | // 普通上传的ID首字母小写,如 fileList |
| 375 | // Antigravity的ID是 antigravity + 首字母大写,如 antigravityFileList |
| 376 | if (type === 'antigravity') { |
| 377 | return 'antigravity' + suffix.charAt(0).toUpperCase() + suffix.slice(1); |
| 378 | } |
| 379 | return suffix.charAt(0).toLowerCase() + suffix.slice(1); |
| 380 | }, |
| 381 | |
| 382 | handleFileSelect(event) { |
| 383 | this.addFiles(Array.from(event.target.files)); |
| 384 | }, |
| 385 | |
| 386 | addFiles(files) { |
| 387 | files.forEach(file => { |
| 388 | const isValid = file.type === 'application/json' || file.name.endsWith('.json') || |
| 389 | file.type === 'application/zip' || file.name.endsWith('.zip'); |
| 390 | |
| 391 | if (isValid) { |
| 392 | if (!this.selectedFiles.find(f => f.name === file.name && f.size === file.size)) { |
| 393 | this.selectedFiles.push(file); |
| 394 | } |
| 395 | } else { |
| 396 | showStatus(`文件 ${file.name} 格式不支持,只支持JSON和ZIP文件`, 'error'); |
| 397 | } |
| 398 | }); |
| 399 | this.updateFileList(); |
| 400 | }, |
| 401 | |
| 402 | updateFileList() { |
| 403 | const list = document.getElementById(this.getElementId('FileList')); |
| 404 | const section = document.getElementById(this.getElementId('FileListSection')); |
| 405 | |
| 406 | if (!list || !section) { |
| 407 | console.warn('File list elements not found:', this.getElementId('FileList')); |
| 408 | return; |
| 409 | } |
| 410 | |
| 411 | if (this.selectedFiles.length === 0) { |
| 412 | section.classList.add('hidden'); |
| 413 | return; |
| 414 | } |
| 415 | |
| 416 | section.classList.remove('hidden'); |
| 417 | list.innerHTML = ''; |
| 418 | |
| 419 | this.selectedFiles.forEach((file, index) => { |
| 420 | const isZip = file.name.endsWith('.zip'); |
| 421 | const fileIcon = isZip ? '📦' : '📄'; |
| 422 | const fileType = isZip ? ' (ZIP压缩包)' : ' (JSON文件)'; |