refactor: 前端重构为项目+任务双核心模型
- 新增 HomePage 项目画廊页,支持新建/删除工程 - 新增 ProjectDetailPage 三栏工作台(配置+生成+任务列表) - 新增 CustomTagsEditor 支持自定义风格标签(custom: 前缀存入 kvPairs) - 重构 project store 为 draft/commit 模式,支持手动保存/取消 - 新增 projectList store 管理工程列表 - 扩展 mock.ts 为多工程数据结构 - 扩展 api/project.ts 新增项目 CRUD API(mock-gated) - 简化 ResultPage,仅展示素材预览 - 删除 GeneratePage、ProjectPage 及未使用的 hooks - 更新 docs/ 文档(frontend.md、api.md、style-keys.md、_index.md)
This commit is contained in:
+196
-175
@@ -10,7 +10,7 @@ Vite 6 + React 18 + TypeScript + zustand + react-router-dom
|
||||
| UI 框架 | React 18 | 函数组件 + Hooks |
|
||||
| 状态管理 | zustand | 轻量,支持 devtools 中间件 |
|
||||
| 路由 | react-router-dom v6 | SPA 模式 |
|
||||
| 实时通信 | 原生 WebSocket | 连接后端 `/api/v1/tasks/:taskId/ws`(Cookie 认证) |
|
||||
| 实时通信 | HTTP 轮询 | 每 1.5s 轮询任务状态(WebSocket 待后端实现) |
|
||||
| HTTP 请求 | fetch + 封装层 | 统一错误处理、响应解包 |
|
||||
|
||||
## 目录结构
|
||||
@@ -18,40 +18,51 @@ Vite 6 + React 18 + TypeScript + zustand + react-router-dom
|
||||
```
|
||||
frontend/src/
|
||||
├── main.tsx # 入口
|
||||
├── App.tsx # 根组件 + 路由配置
|
||||
├── App.tsx # 根组件
|
||||
├── api/ # API 封装层
|
||||
│ ├── client.ts # fetch 封装:baseURL、统一错误处理、响应解包
|
||||
│ ├── client.ts # fetch 封装:统一错误处理、响应解包(get/post/put/del)
|
||||
│ ├── auth.ts # 注册/登录(真实后端调用)
|
||||
│ ├── project.ts # 工程 CRUD + 风格 GET/PUT(mock 切换)
|
||||
│ ├── generate.ts # POST /generate、GET /tasks/:taskId、GET /tasks/:taskId/assets(mock 切换)
|
||||
│ ├── mock.ts # Mock 数据 + 模拟 WebSocket 管线进度
|
||||
│ └── types.ts # API 请求/响应类型定义(Task、Asset、Style、PipelineProgress 等)
|
||||
│ ├── project.ts # 工程 CRUD + 风格 + 任务列表(mock 切换)
|
||||
│ ├── generate.ts # POST /generate、GET /tasks/:taskId、GET /tasks/:taskId/assets
|
||||
│ ├── prompt.ts # 提示词优化 + extractTags
|
||||
│ ├── mock.ts # 多工程 Mock 数据 + 模拟 WebSocket 管线进度
|
||||
│ └── types.ts # API 类型定义
|
||||
├── stores/ # zustand stores
|
||||
│ ├── auth.ts # 用户认证状态(login/register/logout/loadFromStorage)
|
||||
│ ├── project.ts # 当前工程(id、风格、任务列表)
|
||||
│ ├── task.ts # 当前任务草稿(用户文本、素材类型、任务风格覆盖、技术参数)
|
||||
│ └── generation.ts # 生成状态(taskId、进度、阶段、结果、错误)
|
||||
│ ├── auth.ts # 用户认证状态
|
||||
│ ├── project.ts # 当前工程详情(含 draft/commit 风格编辑)
|
||||
│ ├── projectList.ts # 工程列表(画廊页)
|
||||
│ ├── task.ts # 任务草稿(生成表单状态)
|
||||
│ ├── generation.ts # 生成状态(提交、轮询、结果)
|
||||
│ ├── theme.ts # 主题切换(light/dark)
|
||||
│ └── toast.ts # Toast 通知
|
||||
├── pages/ # 页面级组件
|
||||
│ ├── LoginPage.tsx # 登录页
|
||||
│ ├── RegisterPage.tsx # 注册页
|
||||
│ ├── ProjectPage.tsx # 工程首页:工程风格配置 + 任务列表
|
||||
│ ├── GeneratePage.tsx # 生成页:提示词构建 + 提交
|
||||
│ └── ResultPage.tsx # 结果页:素材预览 + 下载 + 元数据
|
||||
│ ├── HomePage.tsx # 项目画廊(工程列表 + 新建弹窗)
|
||||
│ ├── ProjectDetailPage.tsx # 三栏工作台(配置 + 生成 + 任务列表)
|
||||
│ └── ResultPage.tsx # 结果页(素材预览 + 下载)
|
||||
├── components/ # 可复用组件
|
||||
│ ├── StyleSelector.tsx # 风格选择器(CSS Modules)
|
||||
│ ├── Layout.tsx # 导航栏 + Outlet + ToastContainer
|
||||
│ ├── StyleSelector.tsx # 预设风格选择器(pill 按钮)
|
||||
│ ├── CustomTagsEditor.tsx # 自定义标签编辑器(可添加/删除)
|
||||
│ ├── PromptEditor.tsx # 三段式提示词编辑器
|
||||
│ ├── GenerateForm.tsx # 生成表单
|
||||
│ ├── ProgressBar.tsx # 管线进度条(显示当前阶段 + 重试状态)
|
||||
│ └── AssetPreview.tsx # 素材预览(spritesheet 预览、单帧预览)
|
||||
├── hooks/ # 自定义 Hooks
|
||||
│ ├── useGenerate.ts # 提交生成任务 + WebSocket 订阅进度
|
||||
│ └── useProjectStyle.ts # 工程风格加载/保存
|
||||
│ ├── GenerateForm.tsx # 生成表单(素材类型 + 风格覆盖 + 提示词 + 参数)
|
||||
│ ├── ProgressBar.tsx # 管线进度条
|
||||
│ ├── AssetPreview.tsx # 素材预览
|
||||
│ ├── ProjectCard.tsx # 画廊卡片
|
||||
│ ├── CreateProjectModal.tsx # 新建工程弹窗
|
||||
│ ├── ProjectConfigPanel.tsx # 左栏:工程配置编辑面板
|
||||
│ ├── TaskListPanel.tsx # 右栏:任务列表面板
|
||||
│ ├── StatusBadge.tsx # 状态徽标组件
|
||||
│ ├── EmptyState.tsx # 空状态占位
|
||||
│ ├── Skeleton.tsx # 加载骨架屏
|
||||
│ └── Toast.tsx # Toast 通知容器
|
||||
├── router/ # 路由定义
|
||||
│ └── index.tsx
|
||||
├── styles/ # 全局样式
|
||||
│ └── global.css # 暗色主题 CSS 变量 + reset
|
||||
│ └── global.css # 暗色/亮色主题 CSS 变量 + reset
|
||||
└── utils/ # 工具函数
|
||||
└── style.ts # 风格合并逻辑 + 风格键分类定义
|
||||
└── style.ts # 风格合并、预设分类、自定义标签工具
|
||||
```
|
||||
|
||||
## 实现状态
|
||||
@@ -59,167 +70,219 @@ frontend/src/
|
||||
| 模块 | 状态 | 说明 |
|
||||
|------|------|------|
|
||||
| API 封装层 | [x] | client.ts 统一 fetch 封装,auth.ts 真实调用,project/generate 使用 mock |
|
||||
| Mock 层 | [x] | mock.ts 提供 mock 数据 + 模拟 WebSocket 管线进度 |
|
||||
| Mock 层 | [x] | mock.ts 提供多工程 mock 数据 + 模拟 WebSocket 管线进度 |
|
||||
| 认证流程 | [x] | 注册/登录/退出/token 持久化,真实后端对接 |
|
||||
| zustand stores | [x] | auth/project/task/generation 四个 store |
|
||||
| 页面 | [x] | 5 个页面全部实现(Login/Register/Project/Generate/Result) |
|
||||
| 组件 | [x] | StyleSelector/PromptEditor/GenerateForm/ProgressBar/AssetPreview |
|
||||
| zustand stores | [x] | auth/project/projectList/task/generation/theme/toast 七个 store |
|
||||
| 页面 | [x] | 5 个页面(Login/Register/Home/ProjectDetail/Result) |
|
||||
| 组件 | [x] | StyleSelector/CustomTagsEditor/PromptEditor/GenerateForm/ProgressBar/AssetPreview/ProjectCard/CreateProjectModal/ProjectConfigPanel/TaskListPanel/StatusBadge 等 |
|
||||
| 路由 | [x] | 含 ProtectedRoute 守卫 |
|
||||
| WebSocket | [ ] | 当前使用 mock 模拟,待后端实现后切换为真实 WS |
|
||||
| 自定义标签 | [x] | `custom:` 前缀存入 kvPairs,零后端改动 |
|
||||
|
||||
## 路由规划
|
||||
|
||||
| 路径 | 页面 | 说明 |
|
||||
|------|------|------|
|
||||
| `/` | — | 重定向到默认工程 |
|
||||
| `/projects/:projectId` | ProjectPage | 工程首页,配置工程风格,查看历史任务 |
|
||||
| `/projects/:projectId/generate` | GeneratePage | 提示词构建 + 提交生成 |
|
||||
| `/projects/:projectId/tasks/:taskId` | ResultPage | 任务结果页,预览素材、下载 |
|
||||
| `/` | HomePage | 项目画廊,展示所有工程 |
|
||||
| `/projects/:projectId` | ProjectDetailPage | 三栏工作台(配置 + 生成 + 任务列表) |
|
||||
| `/projects/:projectId/tasks/:taskId` | ResultPage | 素材预览 + 下载 |
|
||||
|
||||
## 组件树
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
App --> Router
|
||||
Router --> ProjectPage
|
||||
Router --> GeneratePage
|
||||
Router --> HomePage
|
||||
Router --> ProjectDetailPage
|
||||
Router --> ResultPage
|
||||
|
||||
ProjectPage --> StyleSelector["StyleSelector(工程风格编辑)"]
|
||||
ProjectPage --> TaskList["TaskList(历史任务列表)"]
|
||||
HomePage --> ProjectCard["ProjectCard(工程卡片)"]
|
||||
HomePage --> CreateProjectModal["CreateProjectModal(新建弹窗)"]
|
||||
CreateProjectModal --> StyleSelector
|
||||
CreateProjectModal --> CustomTagsEditor
|
||||
|
||||
GeneratePage --> GenerateForm
|
||||
GenerateForm --> AssetTypePicker["AssetTypePicker"]
|
||||
GenerateForm --> StyleSelector2["StyleSelector(任务风格覆盖)"]
|
||||
GenerateForm --> PromptEditor["PromptEditor(三段式预览)"]
|
||||
GenerateForm --> ParamsForm["ParamsForm(分辨率、帧数)"]
|
||||
GeneratePage --> ProgressBar["ProgressBar(管线进度)"]
|
||||
ProjectDetailPage --> ProjectConfigPanel["ProjectConfigPanel(左栏配置)"]
|
||||
ProjectDetailPage --> GenerateForm["GenerateForm(中间上半)"]
|
||||
ProjectDetailPage --> ProgressBar["ProgressBar(中间下半)"]
|
||||
ProjectDetailPage --> TaskListPanel["TaskListPanel(右栏任务)"]
|
||||
|
||||
ResultPage --> AssetPreview["AssetPreview(素材预览)"]
|
||||
ResultPage --> MetadataPanel["MetadataPanel(元数据)"]
|
||||
ResultPage --> DownloadButton["DownloadButton"]
|
||||
ProjectConfigPanel --> StyleSelector2["StyleSelector"]
|
||||
ProjectConfigPanel --> CustomTagsEditor2["CustomTagsEditor"]
|
||||
TaskListPanel --> StatusBadge["StatusBadge"]
|
||||
|
||||
GenerateForm --> PromptEditor["PromptEditor"]
|
||||
GenerateForm --> StyleSelector3["StyleSelector(任务覆盖)"]
|
||||
|
||||
ResultPage --> AssetPreview["AssetPreview"]
|
||||
```
|
||||
|
||||
## 三栏工作台布局
|
||||
|
||||
ProjectDetailPage 采用 CSS Grid 三栏布局:
|
||||
|
||||
```
|
||||
grid-template-columns: 260px 1fr 320px
|
||||
```
|
||||
|
||||
| 区域 | 宽度 | 内容 |
|
||||
|------|------|------|
|
||||
| 左栏 | 260px | 工程名(可编辑)、预设风格选择器、自定义标签编辑器、保存/取消按钮 |
|
||||
| 中间 | flex-1 | 上半:生成表单;下半:当前任务进度条(提交后显示) |
|
||||
| 右栏 | 320px | 任务列表(所有状态),15 秒自动刷新 |
|
||||
|
||||
## 核心交互流程
|
||||
|
||||
### 项目管理流程
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
actor User
|
||||
participant HP as HomePage
|
||||
participant API as 后端 API
|
||||
|
||||
User->>HP: 进入首页
|
||||
HP->>API: GET /api/v1/projects
|
||||
API-->>HP: 工程列表
|
||||
HP->>HP: 画廊展示 ProjectCard
|
||||
|
||||
User->>HP: 点击「新建工程」
|
||||
HP->>HP: 弹出 CreateProjectModal
|
||||
User->>HP: 输入名称、选择风格、添加自定义标签
|
||||
HP->>API: POST /api/v1/projects
|
||||
API-->>HP: 新工程
|
||||
HP->>HP: 跳转到 ProjectDetailPage
|
||||
```
|
||||
|
||||
### 生成流程
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
actor User
|
||||
participant GP as GeneratePage
|
||||
participant PDP as ProjectDetailPage
|
||||
participant API as 后端 API
|
||||
participant WS as WebSocket
|
||||
|
||||
User->>GP: 填写 prompt、选择素材类型
|
||||
User->>GP: StyleSelector 点选任务风格覆盖
|
||||
GP->>GP: PromptEditor 实时预览三段式提示词
|
||||
User->>GP: 点击提交
|
||||
GP->>API: POST /api/v1/generate
|
||||
API-->>GP: 返回 taskId
|
||||
GP->>WS: ws://host/api/v1/tasks/:taskId/ws(Cookie 自动携带)
|
||||
loop 管线执行中
|
||||
WS-->>GP: PipelineProgress(stage + progress)
|
||||
GP->>GP: ProgressBar 更新阶段和进度
|
||||
User->>PDP: 填写 prompt、选择素材类型
|
||||
User->>PDP: 点击提交
|
||||
PDP->>API: POST /api/v1/generate
|
||||
API-->>PDP: 返回 taskId
|
||||
PDP->>PDP: ProgressBar 显示进度
|
||||
|
||||
loop 轮询任务状态(1.5s)
|
||||
PDP->>API: GET /api/v1/tasks/:taskId
|
||||
API-->>PDP: 任务状态 + 进度
|
||||
PDP->>PDP: 更新 ProgressBar
|
||||
end
|
||||
WS-->>GP: format_adapter completed + assets
|
||||
GP->>GP: 跳转 ResultPage
|
||||
|
||||
API-->>PDP: status = completed
|
||||
PDP->>API: GET /api/v1/tasks/:taskId/assets
|
||||
API-->>PDP: 素材列表
|
||||
PDP->>PDP: 显示「查看结果」按钮
|
||||
```
|
||||
|
||||
管线阶段对应 Eino Graph 节点,ProgressBar 展示:
|
||||
|
||||
| 阶段 | 说明 | ProgressBar 展示 |
|
||||
|------|------|-----------------|
|
||||
| `prompt_optimizer` | 调用 PromptAgent/LLM 优化提示词,合并风格 | 第 1 步 |
|
||||
| `asset_generator` | 调用 AI 推理 API 出图 | 第 2 步 |
|
||||
| `quality_supervisor` | 视觉模型质检 | 第 3 步(可能回退到第 1 步) |
|
||||
| `format_adapter` | 格式转换、spritesheet 打包 | 第 4 步 |
|
||||
|
||||
质检重试时,ProgressBar 显示回退动画和重试次数。
|
||||
|
||||
### 风格编辑流程
|
||||
### 风格编辑流程(手动保存)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
actor User
|
||||
participant SP as StyleSelector
|
||||
participant PCP as ProjectConfigPanel
|
||||
participant Store as project store
|
||||
participant API as 后端 API
|
||||
|
||||
User->>SP: 进入 ProjectPage
|
||||
SP->>API: GET /api/v1/projects/:id/style
|
||||
API-->>SP: 返回 kvPairs
|
||||
SP->>SP: 按分类展示风格键值对
|
||||
User->>SP: 点选/修改风格
|
||||
SP->>SP: 实时展示当前配置
|
||||
User->>SP: 点击保存
|
||||
SP->>API: PUT /api/v1/projects/:id/style
|
||||
API-->>SP: 保存成功
|
||||
User->>PCP: 进入工程页
|
||||
PCP->>Store: startEditing() — 复制 style 到 draftStyle
|
||||
User->>PCP: 修改预设风格 / 添加自定义标签
|
||||
PCP->>Store: updateDraft(key, value) — 更新 draftStyle
|
||||
Store->>Store: hasUnsavedChanges = true
|
||||
|
||||
alt 点击保存
|
||||
User->>PCP: 点击「保存」
|
||||
PCP->>Store: commitDraft()
|
||||
Store->>API: PUT /api/v1/projects/:id/style
|
||||
Store->>API: PUT /api/v1/projects/:id(如名称变更)
|
||||
Store->>Store: style = draftStyle, hasUnsavedChanges = false
|
||||
else 点击取消
|
||||
User->>PCP: 点击「取消」
|
||||
PCP->>Store: discardDraft()
|
||||
Store->>Store: draftStyle = style, hasUnsavedChanges = false
|
||||
end
|
||||
```
|
||||
|
||||
## 错误处理
|
||||
## 自定义标签
|
||||
|
||||
### API 请求错误
|
||||
在预设风格分类之外,用户可添加自定义标签。标签存储在工程风格的 `kvPairs` 中,使用 `custom:` 前缀区分:
|
||||
|
||||
- `api/client.ts` 统一拦截 `code !== 0` 的响应,抛出业务异常
|
||||
- 401:跳转到登录页(Token 已过期或无效,Cookie 会被服务端清除)
|
||||
- 403:提示无权访问,不自动跳转
|
||||
- 429:提示请求过于频繁,稍后重试
|
||||
- 500:展示通用错误提示
|
||||
```json
|
||||
{
|
||||
"artStyle": "pixel",
|
||||
"palette": "warm",
|
||||
"custom:cel-shading": "true",
|
||||
"custom:glow-effects": "true"
|
||||
}
|
||||
```
|
||||
|
||||
### WebSocket 断连
|
||||
工具函数(`utils/style.ts`):
|
||||
- `isCustomKey(key)` — 判断是否为自定义标签
|
||||
- `getCustomTags(style)` — 提取自定义标签列表
|
||||
- `addCustomTag(style, tag)` — 添加标签
|
||||
- `removeCustomTag(style, tag)` — 删除标签
|
||||
|
||||
- 连接断开后自动重连(指数退避,最大间隔 10 秒)
|
||||
- 重连失败超过 3 次后,降级为轮询模式(`GET /api/v1/tasks/:taskId`,间隔 2-3 秒)
|
||||
- 连接恢复后自动切回 WebSocket
|
||||
|
||||
### 加载状态
|
||||
|
||||
- 页面级加载(如 ProjectPage 进入时):展示骨架屏或 Loading 指示器
|
||||
- 操作级提交(如保存风格、提交生成):按钮置为 loading 态,防止重复提交
|
||||
`extractTags()` 函数在提取标签时自动包含自定义标签值。
|
||||
|
||||
## 状态管理
|
||||
|
||||
### zustand stores
|
||||
|
||||
**project store** — 当前工程
|
||||
**projectList store** — 工程列表(HomePage)
|
||||
|
||||
```typescript
|
||||
interface ProjectStore {
|
||||
projectId: string;
|
||||
name: string;
|
||||
style: Record<string, string>; // kvPairs
|
||||
interface ProjectListState {
|
||||
projects: Project[];
|
||||
loading: boolean;
|
||||
loadProject: (projectId: string) => Promise<void>;
|
||||
loadStyle: (projectId: string) => Promise<void>;
|
||||
updateStyle: (kvPairs: Record<string, string>) => void;
|
||||
saveStyle: () => Promise<void>;
|
||||
loadProjects: () => Promise<void>;
|
||||
createProject: (name: string, style?: Record<string, string>) => Promise<Project>;
|
||||
deleteProject: (projectId: string) => Promise<void>;
|
||||
}
|
||||
```
|
||||
|
||||
**task store** — 任务草稿(对应后端 `PipelineInput`)
|
||||
**project store** — 当前工程详情(ProjectDetailPage)
|
||||
|
||||
```typescript
|
||||
interface TaskStore {
|
||||
interface ProjectState {
|
||||
projectId: string;
|
||||
name: string;
|
||||
style: Record<string, string>;
|
||||
draftStyle: Record<string, string>;
|
||||
draftName: string;
|
||||
hasUnsavedChanges: boolean;
|
||||
loading: boolean;
|
||||
loadProject: (projectId: string) => Promise<void>;
|
||||
loadStyle: (projectId: string) => Promise<void>;
|
||||
startEditing: () => void;
|
||||
updateDraft: (key: string, value: string) => void;
|
||||
setDraftStyle: (style: Record<string, string>) => void;
|
||||
setDraftName: (name: string) => void;
|
||||
discardDraft: () => void;
|
||||
commitDraft: () => Promise<void>;
|
||||
}
|
||||
```
|
||||
|
||||
**task store** — 任务草稿
|
||||
|
||||
```typescript
|
||||
interface TaskState {
|
||||
prompt: string;
|
||||
assetType: 'sprite' | 'background' | 'ui' | 'animation';
|
||||
taskStyle: Record<string, string>; // 仅覆盖的键
|
||||
params: {
|
||||
resolution: number;
|
||||
frames?: { directions: number; framesPerDirection: number };
|
||||
format: 'spritesheet' | 'individual';
|
||||
};
|
||||
setPrompt: (text: string) => void;
|
||||
setAssetType: (type: TaskStore['assetType']) => void;
|
||||
toggleTaskStyle: (key: string, value: string) => void;
|
||||
setParams: (params: Partial<TaskStore['params']>) => void;
|
||||
reset: () => void;
|
||||
taskStyle: Record<string, string>;
|
||||
params: TaskParams;
|
||||
enableAI: boolean;
|
||||
optimizedPrompt: string | null;
|
||||
// ... setters, runOptimize, reset
|
||||
}
|
||||
```
|
||||
|
||||
**generation store** — 生成状态
|
||||
|
||||
```typescript
|
||||
interface GenerationStore {
|
||||
interface GenerationState {
|
||||
taskId: string | null;
|
||||
stage: PipelineStage | null;
|
||||
progress: number;
|
||||
@@ -228,57 +291,26 @@ interface GenerationStore {
|
||||
rejectReason: string | null;
|
||||
assets: Asset[];
|
||||
error: string | null;
|
||||
submit: (projectId: string, task: TaskStore) => Promise<void>;
|
||||
submit: (req: GenerateRequest) => Promise<void>;
|
||||
reset: () => void;
|
||||
}
|
||||
|
||||
type PipelineStage =
|
||||
| 'prompt_optimizer'
|
||||
| 'asset_generator'
|
||||
| 'quality_supervisor'
|
||||
| 'format_adapter';
|
||||
```
|
||||
|
||||
## API 封装
|
||||
|
||||
`api/client.ts` 统一封装:
|
||||
|
||||
- baseURL 从环境变量读取,开发模式默认 `/api/v1`
|
||||
- 所有 fetch 请求设置 `credentials: 'include'`,自动携带 Cookie
|
||||
- 所有响应按 `{ code, message, data }` 解包,`code !== 0` 时抛错
|
||||
- 统一 401/403/500 错误处理
|
||||
- WebSocket 连接封装为 `createTaskSocket(taskId)` 返回可订阅对象(浏览器自动携带 Cookie)
|
||||
|
||||
### API 类型定义(api/types.ts)
|
||||
## API 类型定义(api/types.ts)
|
||||
|
||||
```typescript
|
||||
// 请求
|
||||
interface CreateProjectRequest {
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface GenerateRequest {
|
||||
projectId: string;
|
||||
prompt: string;
|
||||
assetType: 'sprite' | 'background' | 'ui' | 'animation';
|
||||
taskStyle?: Record<string, string>;
|
||||
params?: {
|
||||
resolution?: number;
|
||||
frames?: { directions?: number; framesPerDirection?: number };
|
||||
format?: 'spritesheet' | 'individual';
|
||||
};
|
||||
}
|
||||
|
||||
interface UpdateStyleRequest {
|
||||
kvPairs: Record<string, string>;
|
||||
}
|
||||
|
||||
// 响应
|
||||
interface Project {
|
||||
id: string;
|
||||
name: string;
|
||||
style: { kvPairs: Record<string, string> };
|
||||
createdAt: string;
|
||||
taskCount?: number;
|
||||
lastActivityAt?: string;
|
||||
}
|
||||
|
||||
interface CreateProjectRequest {
|
||||
name: string;
|
||||
style?: Record<string, string>;
|
||||
}
|
||||
|
||||
interface Task {
|
||||
@@ -286,7 +318,7 @@ interface Task {
|
||||
projectId: string;
|
||||
prompt: string;
|
||||
assetType: string;
|
||||
status: 'pending' | 'running' | 'completed' | 'failed';
|
||||
status: 'pending' | 'submitted' | 'running' | 'completed' | 'failed';
|
||||
stage?: PipelineStage;
|
||||
progress?: number;
|
||||
retryCount?: number;
|
||||
@@ -297,6 +329,7 @@ interface Task {
|
||||
|
||||
interface Asset {
|
||||
id: string;
|
||||
key: string;
|
||||
url: string;
|
||||
format: string;
|
||||
width: number;
|
||||
@@ -308,18 +341,6 @@ interface Asset {
|
||||
directions?: number;
|
||||
};
|
||||
}
|
||||
|
||||
// WebSocket 消息
|
||||
interface PipelineProgress {
|
||||
stage: PipelineStage;
|
||||
status: 'running' | 'completed' | 'failed';
|
||||
progress: number;
|
||||
message?: string;
|
||||
retryCount?: number;
|
||||
rejectReason?: string;
|
||||
result?: { assets: Asset[] };
|
||||
error?: string;
|
||||
}
|
||||
```
|
||||
|
||||
## 预设风格键分类
|
||||
@@ -327,5 +348,5 @@ interface PipelineProgress {
|
||||
前端 StyleSelector 以分类标签组织,完整键值表见 [预设风格键](style-keys.md)。
|
||||
|
||||
StyleSelector 两种使用场景:
|
||||
1. **工程风格**(ProjectPage):全量编辑,保存到后端
|
||||
2. **任务覆盖**(GeneratePage):基于工程风格展示,高亮已覆盖的键,仅记录差异
|
||||
1. **工程风格**(ProjectConfigPanel / CreateProjectModal):全量编辑,保存到后端
|
||||
2. **任务覆盖**(GenerateForm):基于工程风格展示,仅记录差异
|
||||
|
||||
Reference in New Issue
Block a user