feat(prompt): AI 提示词优化双栏交互

新增 prompt API 模块调用后端 /api/v1/prompt/optimize,PromptEditor
重构为左右双栏布局支持原始/优化提示词对比编辑,默认开启 AI 优化,
用户可关闭开关或手动编辑优化结果后再提交生成。
This commit is contained in:
2026-05-24 21:16:15 +08:00
parent eac64105de
commit c177cbaf82
6 changed files with 304 additions and 22 deletions
+46 -4
View File
@@ -1,5 +1,7 @@
import { create } from 'zustand'
import type { AssetType } from '../api/types'
import { optimizePrompt, extractTags } from '../api/prompt'
import { mergeStyles } from '../utils/style'
interface TaskParams {
resolution: number
@@ -12,10 +14,16 @@ interface TaskState {
assetType: AssetType
taskStyle: Record<string, string>
params: TaskParams
enableAI: boolean
optimizedPrompt: string | null
isOptimizing: boolean
setPrompt: (text: string) => void
setAssetType: (type: AssetType) => void
toggleTaskStyle: (key: string, value: string) => void
setParams: (params: Partial<TaskParams>) => void
setEnableAI: (enable: boolean) => void
setOptimizedPrompt: (text: string | null) => void
runOptimize: (projectStyle: Record<string, string>) => Promise<void>
reset: () => void
}
@@ -24,15 +32,18 @@ const DEFAULT_PARAMS: TaskParams = {
format: 'spritesheet',
}
export const useTaskStore = create<TaskState>((set) => ({
export const useTaskStore = create<TaskState>((set, get) => ({
prompt: '',
assetType: 'sprite',
taskStyle: {},
params: { ...DEFAULT_PARAMS },
enableAI: true,
optimizedPrompt: null,
isOptimizing: false,
setPrompt: (text) => set({ prompt: text }),
setPrompt: (text) => set({ prompt: text, optimizedPrompt: null }),
setAssetType: (type) => set({ assetType: type }),
setAssetType: (type) => set({ assetType: type, optimizedPrompt: null }),
toggleTaskStyle: (key, value) =>
set(state => {
@@ -42,17 +53,48 @@ export const useTaskStore = create<TaskState>((set) => ({
} else {
next[key] = value
}
return { taskStyle: next }
return { taskStyle: next, optimizedPrompt: null }
}),
setParams: (params) =>
set(state => ({ params: { ...state.params, ...params } })),
setEnableAI: (enable) => set({ enableAI: enable, optimizedPrompt: null }),
setOptimizedPrompt: (text) => set({ optimizedPrompt: text }),
runOptimize: async (projectStyle) => {
const { prompt, assetType, taskStyle } = get()
if (!prompt.trim()) return
const mergedStyle = mergeStyles(projectStyle, taskStyle)
const tags = extractTags(mergedStyle)
if (tags.length === 0) return
set({ isOptimizing: true })
try {
const result = await optimizePrompt({
tags,
assetType,
prompt,
})
set({ optimizedPrompt: result.prompt })
} catch (err) {
console.error('提示词优化失败:', err)
throw err
} finally {
set({ isOptimizing: false })
}
},
reset: () =>
set({
prompt: '',
assetType: 'sprite',
taskStyle: {},
params: { ...DEFAULT_PARAMS },
enableAI: true,
optimizedPrompt: null,
isOptimizing: false,
}),
}))