feat: 修复 textNode Label 宽度自适应问题

- 修改 TextNodeModel.ts,动态设置 Label 的 labelWidth 和坐标
- Label 宽度现在跟随节点宽度变化(节点宽度 - 20px)
- 设置 Label 坐标与节点坐标一致,确保 Label 可见
- 限制每个节点只允许一个 Label(isMultiple: false)
- 移除全局 labelWidth 配置,让每个节点自己控制
- 支持文本自动换行(textOverflowMode: wrap)
- 处理数组格式的旧数据兼容性

相关文件:
- src/components/flow/nodes/common/TextNodeModel.ts
- src/components/flow/FlowEditor.vue
- docs/1management/plan.md
This commit is contained in:
2026-02-17 17:19:46 +08:00
parent 777fc2c944
commit 9136f8e84b
3 changed files with 139 additions and 50 deletions

View File

@@ -702,9 +702,8 @@ onMounted(() => {
plugins: [Menu, Label, Snapshot, SelectionSelect, MiniMap, Control],
pluginsOptions: {
label: {
isMultiple: true,
maxCount: 3,
labelWidth: 80,
isMultiple: false, // 每个节点只允许一个 label
// 不设置全局 labelWidth让每个节点自己控制
// textOverflowMode -> 'ellipsis' | 'wrap' | 'clip' | 'nowrap' | 'default'
textOverflowMode: 'wrap',
},

View File

@@ -3,34 +3,128 @@ import { HtmlNodeModel } from '@logicflow/core';
class TextNodeModel extends HtmlNodeModel {
initNodeData(data: any) {
super.initNodeData(data);
// 启用文本编辑功能,支持双击编辑
this.text.editable = true;
this.text.draggable = false;
// 如果有 text 属性,设置为文本内容
if (data.properties?.text) {
this.text.value = data.properties.text;
// 从 data 中读取宽高,支持调整大小后的持久化
if (data.properties?.width) {
this.width = data.properties.width;
} else {
this.width = 200;
}
if (data.properties?.height) {
this.height = data.properties.height;
} else {
this.height = 120;
}
// 计算 Label 宽度
const labelWidth = this.width - 20;
// 初始化或更新 Label 配置
if (data.properties?._label) {
// 如果已有 _label 配置,更新其宽度和坐标
// 处理数组情况(兼容旧数据)
let currentLabel = data.properties._label;
if (Array.isArray(currentLabel)) {
currentLabel = currentLabel[0] || {};
}
this.setProperty('_label', {
value: currentLabel.value || '双击编辑文本',
content: currentLabel.content || currentLabel.value || '双击编辑文本',
x: data.x,
y: data.y,
labelWidth: labelWidth,
textOverflowMode: 'wrap',
editable: true,
draggable: false,
});
} else if (data.properties?.text) {
// 如果有 text 属性但没有 _label创建 _label
this.setProperty('_label', {
value: data.properties.text,
content: data.properties.text,
x: data.x,
y: data.y,
labelWidth: labelWidth,
textOverflowMode: 'wrap',
editable: true,
draggable: false,
});
} else {
// 如果都没有,初始化一个默认的 label
this.setProperty('_label', {
value: '双击编辑文本',
content: '双击编辑文本',
x: data.x,
y: data.y,
labelWidth: labelWidth,
textOverflowMode: 'wrap',
editable: true,
draggable: false,
});
}
}
setAttributes() {
// 设置默认尺寸
this.width = 200;
this.height = 120;
// 设置默认尺寸(如果 initNodeData 中没有设置)
if (!this.width) {
this.width = 200;
}
if (!this.height) {
this.height = 120;
}
}
// 自定义文本样式
getTextStyle() {
const style = super.getTextStyle();
style.fontSize = 14;
style.color = '#333';
return style;
// 监听节点大小变化,更新 Label 宽度
resize(deltaX: number, deltaY: number) {
const result = super.resize?.(deltaX, deltaY);
// 持久化宽高到 properties
this.setProperty('width', this.width);
this.setProperty('height', this.height);
// 更新 Label 宽度和坐标
let currentLabel = this.properties._label || {};
if (Array.isArray(currentLabel)) {
currentLabel = currentLabel[0] || {};
}
this.setProperty('_label', {
value: currentLabel.value || '双击编辑文本',
content: currentLabel.content || currentLabel.value || '双击编辑文本',
x: this.x,
y: this.y,
labelWidth: this.width - 20,
textOverflowMode: 'wrap',
editable: true,
draggable: false,
});
return result;
}
// 当文本被编辑后,同步到 properties
updateText(value: string) {
super.updateText(value);
this.setProperty('text', value);
// 同时更新 _label 中的 value
let currentLabel = this.properties._label || {};
if (Array.isArray(currentLabel)) {
currentLabel = currentLabel[0] || {};
}
this.setProperty('_label', {
value: value,
content: value,
x: this.x,
y: this.y,
labelWidth: this.width - 20,
textOverflowMode: 'wrap',
editable: true,
draggable: false,
});
}
}