fix(canvas): 局部重绘 - 同步默认显示模型与生成模型
This commit is contained in:
@@ -5,6 +5,13 @@ description: 当前项目已实现功能的手工验证清单与未确认边界
|
||||
|
||||
# 待测试
|
||||
|
||||
## 局部重绘默认模型同步
|
||||
|
||||
- 已修复:局部重绘弹窗打开时,将默认显示的图片模型同步到实际请求模型;下拉框显示与提交使用同一字段,无需手动重新选择模型。
|
||||
- 已修复:局部重绘任务优先使用提交的图片模型,并将 `model` 与 `imageModel` 统一为本次选中的模型。
|
||||
- [ ] 上传图片,在全局当前模型与默认图片模型不同的情况下打开局部重绘,直接涂抹、填写修改要求并生成,确认不再出现「所选模型与任务能力不匹配」。
|
||||
- [ ] 在弹窗中切换图片模型,以及从已有生成图片打开局部重绘,确认提交模型与显示模型一致。
|
||||
|
||||
## 系统模型「拉取模型」弹窗搜索
|
||||
|
||||
- 已实现:后台「模型与资源 → 系统模型」点「拉取模型」后的选择弹窗新增搜索框(按模型标识做大小写不敏感的子串匹配,自动聚焦、可一键清空),因为部分上游端点会返回几百个模型。
|
||||
|
||||
@@ -30,7 +30,10 @@ function MaskEditor({ dataUrl, config, onClose, onConfirm }: MaskEditorProps) {
|
||||
const [diameter, setDiameter] = useState(100);
|
||||
const [mode, setMode] = useState("paint");
|
||||
const [prompt, setPrompt] = useState("");
|
||||
const [settings, setSettings] = useState(config);
|
||||
const [settings, setSettings] = useState(() => {
|
||||
const model = config.imageModel || config.model;
|
||||
return { ...config, model, imageModel: model };
|
||||
});
|
||||
const [error, setError] = useState("");
|
||||
const [strokeCount, setStrokeCount] = useState(0);
|
||||
const theme = canvasThemes[useActiveTheme()];
|
||||
@@ -61,8 +64,8 @@ function MaskEditor({ dataUrl, config, onClose, onConfirm }: MaskEditorProps) {
|
||||
let maskDataUrl: string;
|
||||
try { maskDataUrl = exportEditMask(size.width, size.height, strokes.current); }
|
||||
catch (failure) { setError(failure instanceof Error ? failure.message : "遮罩生成失败"); return; }
|
||||
const { model, imageModel, quality, count, transparentBackground } = settings;
|
||||
onConfirm({ prompt: prompt.trim(), maskDataUrl, generationConfig: { model, imageModel, size: settings.size, quality, count, transparentBackground } });
|
||||
const { model, quality, count, transparentBackground } = settings;
|
||||
onConfirm({ prompt: prompt.trim(), maskDataUrl, generationConfig: { model, imageModel: model, size: settings.size, quality, count, transparentBackground } });
|
||||
};
|
||||
return (
|
||||
<AppModal open centered title="局部重绘" className="workspace-modal workspace-modal-wide" onCancel={onClose} onOk={submit} okText="AI 修改" okButtonProps={{ disabled: !size }}>
|
||||
@@ -96,7 +99,7 @@ function MaskEditor({ dataUrl, config, onClose, onConfirm }: MaskEditorProps) {
|
||||
</div>
|
||||
<label className="flex flex-col gap-2 text-sm">修改要求<Input.TextArea rows={4} value={prompt} placeholder="描述选中区域需要发生的变化" onChange={(event) => { setPrompt(event.target.value); setError(""); }} /></label>
|
||||
<Collapse defaultActiveKey={["settings"]} items={[{ key: "settings", label: "生成设置", children: <div className="space-y-4">
|
||||
<ModelPicker config={settings} value={settings.imageModel || settings.model} capability="image" fullWidth showSelectedPrice={false} onChange={(model) => setSettings((previous) => ({ ...previous, ...defaultImageParamsForModel(previous, model), imageModel: model, model }))} />
|
||||
<ModelPicker config={settings} value={settings.model} capability="image" fullWidth showSelectedPrice={false} onChange={(model) => setSettings((previous) => ({ ...previous, ...defaultImageParamsForModel(previous, model), imageModel: model, model }))} />
|
||||
<ImageSettingsPanel config={settings} theme={theme} showTitle={false} showCount={false} bypassPriceGuard onConfigChange={(key, value) => setSettings((previous) => ({ ...previous, [key]: value }))} />
|
||||
</div> }]} />
|
||||
{error || loadError ? <p role="alert" className="text-sm text-destructive">{error || loadError}</p> : null}
|
||||
|
||||
@@ -681,7 +681,7 @@ export function useCanvasMediaTools({
|
||||
const maskEditImageNode = useCallback(async (node: CanvasNodeData, payload: CanvasImageMaskEditPayload) => {
|
||||
if (!node.metadata?.content) return;
|
||||
const baseGenerationConfig = buildGenerationConfig(effectiveConfig, node, "image");
|
||||
const selectedModel = payload.generationConfig?.model || payload.generationConfig?.imageModel || baseGenerationConfig.model;
|
||||
const selectedModel = payload.generationConfig?.imageModel || payload.generationConfig?.model || baseGenerationConfig.model;
|
||||
const modelDefaults = defaultImageParamsForModel(baseGenerationConfig, selectedModel);
|
||||
const selectedImageProfile = modelCapabilityConfigFor(baseGenerationConfig, selectedModel).image;
|
||||
if (!selectedImageProfile?.references.maskSupported) {
|
||||
@@ -692,7 +692,7 @@ export function useCanvasMediaTools({
|
||||
...baseGenerationConfig,
|
||||
...payload.generationConfig,
|
||||
model: selectedModel,
|
||||
imageModel: payload.generationConfig?.imageModel || payload.generationConfig?.model || effectiveConfig.imageModel,
|
||||
imageModel: selectedModel,
|
||||
quality: normalizeMaskEditQuality(payload.generationConfig?.quality || node.metadata?.quality || baseGenerationConfig.quality || modelDefaults.quality, payload.generationConfig?.size || node.metadata?.size || baseGenerationConfig.size || modelDefaults.size),
|
||||
count: String(payload.generationConfig?.count || 1),
|
||||
// 原图像素尺寸不是模型的输出尺寸合同;非高级设置时使用模型默认尺寸,避免把节点尺寸误发给上游。
|
||||
|
||||
Reference in New Issue
Block a user