From fb31114feeaf3ae6de7c285b64fcd071c197ba24 Mon Sep 17 00:00:00 2001
From: xyh202131 <246811510+xyh202131@users.noreply.github.com>
Date: Tue, 4 Aug 2026 10:53:24 +0800
Subject: [PATCH 1/2] feat(export-package): add asset packaging plan and export
panel
---
.../export-package/asset-export.test.ts | 181 +++++++++
.../features/export-package/asset-export.ts | 366 ++++++++++++++++++
.../export-package/export-panel.test.tsx | 120 ++++++
.../features/export-package/export-panel.tsx | 122 ++++++
frontend/src/features/export-package/index.ts | 10 +
frontend/src/features/export-package/model.ts | 32 ++
6 files changed, 831 insertions(+)
create mode 100644 frontend/src/features/export-package/asset-export.test.ts
create mode 100644 frontend/src/features/export-package/asset-export.ts
create mode 100644 frontend/src/features/export-package/export-panel.test.tsx
create mode 100644 frontend/src/features/export-package/export-panel.tsx
create mode 100644 frontend/src/features/export-package/index.ts
create mode 100644 frontend/src/features/export-package/model.ts
diff --git a/frontend/src/features/export-package/asset-export.test.ts b/frontend/src/features/export-package/asset-export.test.ts
new file mode 100644
index 0000000..d9cfeb8
--- /dev/null
+++ b/frontend/src/features/export-package/asset-export.test.ts
@@ -0,0 +1,181 @@
+/** @vitest-environment jsdom */
+import { describe, expect, it, vi } from 'vitest'
+
+import type {
+ ExportAction as PreviewAction,
+ ExportFrame as PreviewFrame,
+ ExportPackageModel as PlaytestPreviewModel,
+} from './model'
+import { createAssetExportPlan, exportGameAssets, type AssetExportRuntime } from './asset-export'
+
+function frame(index: number): PreviewFrame {
+ return {
+ imageUrl: `/frames/walk-${index}.png`,
+ durationMs: 100 + index,
+ rootMotion: { dx: index, dy: 0 },
+ keyFrame: index === 0,
+ }
+}
+
+function action(frameCount = 9): PreviewAction {
+ return {
+ id: 'walk-abcdef12',
+ name: 'Walk / Forward',
+ type: 'walk',
+ fps: 10,
+ sequences: [
+ {
+ direction: 'south',
+ frames: Array.from({ length: frameCount }, (_, index) => frame(index)),
+ },
+ ],
+ }
+}
+
+const model: PlaytestPreviewModel = {
+ characterId: 'character-1',
+ characterName: 'Aster',
+ outfitId: 'outfit-1',
+ outfitName: 'Explorer',
+ characterTemplateUrl: null,
+ baseFrameCount: 0,
+ actions: [action(), action(0)],
+}
+
+async function readStoredZip(blob: Blob): Promise
) : state.status === 'failure' ? (
- 导出失败,可重试
+ 导出失败:{state.message}
) : state.status === 'success' ? (
-
-
下载完成
- {state.incomplete ? (
-
- 导出不完整,缺失图片已保留透明占位
-
- ) : null}
-
+ 下载完成
) : null}