Fix server file browse flow

This commit is contained in:
npc0-hue
2026-08-26 22:00:23 +08:00
parent 861ee752ed
commit 6369a8099a
22 changed files with 627 additions and 132 deletions
+37 -7
View File
@@ -12,19 +12,49 @@ export async function downloadServerFileResult(client: PlatformApiClient, result
if (!result.artifact) {
return "文件内容尚未可用。";
}
const chunks: ArrayBuffer[] = [];
const writer = await createFileWriter(result.filename || result.artifact.filename);
let offset = 0;
const chunkSize = Math.max(1, result.artifact.chunkSizeBytes || 1024 * 1024);
while (offset < result.artifact.sizeBytes) {
const chunk = await client.readArtifactContent(result.artifact.artifactId, offset, Math.min(chunkSize, result.artifact.sizeBytes - offset));
chunks.push(chunk.payload);
offset += chunk.contentLength;
if (chunk.contentLength <= 0) break;
try {
while (offset < result.artifact.sizeBytes) {
const chunk = await client.readArtifactContent(result.artifact.artifactId, offset, Math.min(chunkSize, result.artifact.sizeBytes - offset));
if (chunk.contentLength <= 0) throw new Error("文件下载返回空数据");
await writer.write(chunk.payload);
offset += chunk.contentLength;
}
await writer.close();
} catch (error) {
await writer.abort();
throw error;
}
saveBlob(new Blob(chunks, { type: result.artifact.contentType || "application/octet-stream" }), result.filename || result.artifact.filename);
return `下载已开始:${result.filename || result.artifact.filename}`;
}
interface FileWriter {
write(data: ArrayBuffer): Promise<void>;
close(): Promise<void>;
abort(): Promise<void>;
}
async function createFileWriter(filename: string): Promise<FileWriter> {
const picker = (window as Window & { showSaveFilePicker?: (options?: { suggestedName?: string }) => Promise<{ createWritable(): Promise<FileSystemWritableFileStream> }> }).showSaveFilePicker;
if (picker) {
const handle = await picker({ suggestedName: safeFilename(filename) });
const writable = await handle.createWritable();
return {
write: async (data) => { await writable.write(data); },
close: async () => { await writable.close(); },
abort: async () => { await writable.abort(); }
};
}
const chunks: ArrayBuffer[] = [];
return {
write: async (data) => { chunks.push(data); },
close: async () => { saveBlob(new Blob(chunks, { type: "application/octet-stream" }), safeFilename(filename)); },
abort: async () => { chunks.length = 0; }
};
}
function saveBlob(blob: Blob, filename: string) {
const url = URL.createObjectURL(blob);
const anchor = document.createElement("a");