fix(canvas): 解决画布节点拖拽操作被控件拦截问题
- 在 CanvasConfigNodePanel 组件中为 Segmented 控件添加事件阻止传播 - 为输入框和按钮组件添加 onMouseDown 事件阻止传播 - 为 ModelPicker 和 CanvasSizePicker 的下拉菜单添加事件阻止传播 - 更新 API 基础 URL 默认端口从 8080 改为 3000 - 更新开发服务器端口配置为 3001 - 在 CHANGELOG 中更新修复说明
This commit is contained in:
+2
-1
@@ -5,7 +5,8 @@
|
||||
1. [新增] 增加生图工作台功能,支持文生图、图生图、查看历史记录,并增加移动端适配。
|
||||
2. [修复] Docker 镜像启动时 Next.js 监听地址改为 `0.0.0.0`,便于容器环境访问。
|
||||
3. [修复] 画布生成尺寸控件支持选择更多常用比例,并可直接输入自定义比例。
|
||||
4. [文档] 增加 Render 部署说明。
|
||||
4. [修复] 生成配置节点恢复拖拽操作,避免面板控件拦截整块节点拖动。
|
||||
5. [文档] 增加 Render 部署说明。
|
||||
|
||||
## v0.0.1 - 2026-05-19
|
||||
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ import { readFileSync } from "node:fs";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { dirname, resolve } from "node:path";
|
||||
|
||||
const apiBaseUrl = process.env.API_BASE_URL || "http://127.0.0.1:8080";
|
||||
const apiBaseUrl = process.env.API_BASE_URL || "http://127.0.0.1:3000";
|
||||
const webDir = dirname(fileURLToPath(import.meta.url));
|
||||
const version = readFileSync(resolve(webDir, "../VERSION"), "utf8").trim() || "dev";
|
||||
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "next dev --webpack -H 0.0.0.0",
|
||||
"dev": "next dev --webpack -H 0.0.0.0 -p 3001",
|
||||
"build": "next build",
|
||||
"start": "next start"
|
||||
},
|
||||
|
||||
@@ -65,27 +65,29 @@ export function CanvasConfigNodePanel({ node, isRunning, inputSummary, inputs, o
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex h-full w-full flex-col px-3 pb-3 pt-7 text-sm" style={{ color: theme.node.text }} onMouseDown={(event) => event.stopPropagation()} onPointerDown={(event) => event.stopPropagation()} onWheel={(event) => event.stopPropagation()}>
|
||||
<div className="flex h-full w-full cursor-move flex-col px-3 pb-3 pt-7 text-sm" style={{ color: theme.node.text }} onWheel={(event) => event.stopPropagation()}>
|
||||
<div className="mb-2 flex items-center justify-between gap-3">
|
||||
<div className="shrink-0 text-sm font-semibold">生成配置</div>
|
||||
<Segmented
|
||||
size="small"
|
||||
className="canvas-config-mode !rounded-md !p-0.5"
|
||||
value={mode}
|
||||
onChange={(value) => onConfigChange(node.id, { generationMode: value as CanvasGenerationMode })}
|
||||
options={[
|
||||
{ value: "image", label: <span className="inline-flex items-center gap-1"><ImageIcon className="size-3.5" />生图</span> },
|
||||
{ value: "text", label: <span className="inline-flex items-center gap-1"><MessageSquare className="size-3.5" />文本</span> },
|
||||
]}
|
||||
/>
|
||||
<div className="cursor-default" onMouseDown={(event) => event.stopPropagation()}>
|
||||
<Segmented
|
||||
size="small"
|
||||
className="canvas-config-mode !rounded-md !p-0.5"
|
||||
value={mode}
|
||||
onChange={(value) => onConfigChange(node.id, { generationMode: value as CanvasGenerationMode })}
|
||||
options={[
|
||||
{ value: "image", label: <span className="inline-flex items-center gap-1"><ImageIcon className="size-3.5" />生图</span> },
|
||||
{ value: "text", label: <span className="inline-flex items-center gap-1"><MessageSquare className="size-3.5" />文本</span> },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mb-2 flex flex-wrap gap-1.5">
|
||||
<div className="mb-2 flex flex-wrap gap-1.5" onMouseDown={(event) => event.stopPropagation()}>
|
||||
<InputChip label="提示词" value={`${inputSummary.textCount} 个`} style={chipStyle} />
|
||||
<InputChip label="参考图" value={`${inputSummary.imageCount} 张`} style={chipStyle} />
|
||||
<button
|
||||
type="button"
|
||||
className="inline-flex h-7 items-center gap-1 rounded-md border px-2 text-[11px]"
|
||||
className="inline-flex h-7 cursor-pointer items-center gap-1 rounded-md border px-2 text-[11px]"
|
||||
style={chipStyle}
|
||||
onClick={() => setPreviewOpen(true)}
|
||||
>
|
||||
@@ -94,7 +96,7 @@ export function CanvasConfigNodePanel({ node, isRunning, inputSummary, inputs, o
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="mb-2 grid min-w-0 grid-cols-[minmax(0,1fr)_92px_64px] items-center gap-2">
|
||||
<div className="mb-2 grid min-w-0 cursor-default grid-cols-[minmax(0,1fr)_92px_64px] items-center gap-2" onMouseDown={(event) => event.stopPropagation()}>
|
||||
<ModelPicker className="canvas-compact-control h-10" config={config} value={config.model} onChange={(model) => onConfigChange(node.id, { model })} onMissingConfig={() => openConfigDialog(true)} fullWidth />
|
||||
{mode === "image" ? <CanvasSizePicker className="h-10 min-w-0" value={node.metadata?.size || globalConfig.size || defaultConfig.size} onChange={(value) => onConfigChange(node.id, { size: value })} /> : null}
|
||||
<InputNumber min={1} max={15} className="canvas-compact-control canvas-control-number h-10 !w-full" value={count} onChange={(value) => onConfigChange(node.id, { count: Number(value) || 1 })} />
|
||||
@@ -102,8 +104,9 @@ export function CanvasConfigNodePanel({ node, isRunning, inputSummary, inputs, o
|
||||
|
||||
<Button
|
||||
type="primary"
|
||||
className="mt-auto !h-9 !w-full !rounded-lg"
|
||||
className="mt-auto !h-9 !w-full !cursor-pointer !rounded-lg"
|
||||
disabled={isRunning || (!inputSummary.textCount && !inputSummary.imageCount)}
|
||||
onMouseDown={(event) => event.stopPropagation()}
|
||||
onClick={() => onGenerate(node.id)}
|
||||
icon={isRunning ? <LoaderCircle className="size-4 animate-spin" /> : <Play className="size-4" />}
|
||||
>
|
||||
|
||||
@@ -47,6 +47,7 @@ export function CanvasSizePicker({ value, className, onChange }: CanvasSizePicke
|
||||
placeholder="比例"
|
||||
options={options}
|
||||
popupMatchSelectWidth={false}
|
||||
popupRender={(menu) => <div onMouseDown={(event) => event.stopPropagation()} onPointerDown={(event) => event.stopPropagation()}>{menu}</div>}
|
||||
onOpenChange={setOpen}
|
||||
onSearch={setSearch}
|
||||
onChange={selectSize}
|
||||
|
||||
@@ -23,6 +23,7 @@ export function ModelPicker({ config, value, onChange, className, fullWidth = fa
|
||||
showSearch
|
||||
className={`canvas-control-select ${className || ""}`}
|
||||
popupMatchSelectWidth={false}
|
||||
popupRender={(menu) => <div onMouseDown={(event) => event.stopPropagation()} onPointerDown={(event) => event.stopPropagation()}>{menu}</div>}
|
||||
style={{ width, maxWidth: "100%", minWidth: 0, flexShrink: 1 }}
|
||||
value={value || undefined}
|
||||
placeholder={placeholder}
|
||||
@@ -30,6 +31,7 @@ export function ModelPicker({ config, value, onChange, className, fullWidth = fa
|
||||
notFoundContent="请先到配置里拉取模型列表"
|
||||
onChange={onChange}
|
||||
onMouseDown={(event) => event.stopPropagation()}
|
||||
onPointerDown={(event) => event.stopPropagation()}
|
||||
onClick={() => {
|
||||
if (!options.length) onMissingConfig?.();
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user