feat(backend): 添加流程模型与服务支持 feat(frontend): 实现流程编辑器UI与交互 feat(assets): 添加流程节点图标资源 feat(plugins): 实现上下文菜单和运行时插件 feat(components): 新增基础节点和侧边栏组件 feat(routes): 添加流程相关路由配置 feat(models): 创建流程和运行日志数据模型 feat(services): 实现流程服务层逻辑 feat(migration): 添加流程相关数据库迁移 feat(config): 更新前端配置支持流程编辑器 feat(utils): 增强axios错误处理和工具函数
169 lines
4.5 KiB
TypeScript
169 lines
4.5 KiB
TypeScript
/**
|
|
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
import { useCallback, useEffect, useState } from 'react';
|
|
|
|
import {
|
|
FlowNodeFormData,
|
|
FormModelV2,
|
|
FreeOperationType,
|
|
HistoryService,
|
|
TransformData,
|
|
useCurrentEntity,
|
|
usePlayground,
|
|
useService,
|
|
} from '@flowgram.ai/free-layout-editor';
|
|
|
|
import { CommentEditorFormField } from '../constant';
|
|
|
|
export const useSize = () => {
|
|
const node = useCurrentEntity();
|
|
const nodeMeta = node.getNodeMeta();
|
|
const playground = usePlayground();
|
|
const historyService = useService(HistoryService);
|
|
const { size = { width: 240, height: 150 } } = nodeMeta;
|
|
const transform = node.getData(TransformData);
|
|
const formModel = node.getData(FlowNodeFormData).getFormModel<FormModelV2>();
|
|
const formSize = formModel.getValueIn<{ width: number; height: number }>(
|
|
CommentEditorFormField.Size
|
|
);
|
|
|
|
const [width, setWidth] = useState(formSize?.width ?? size.width);
|
|
const [height, setHeight] = useState(formSize?.height ?? size.height);
|
|
|
|
// 初始化表单值
|
|
useEffect(() => {
|
|
const initSize = formModel.getValueIn<{ width: number; height: number }>(
|
|
CommentEditorFormField.Size
|
|
);
|
|
if (!initSize) {
|
|
formModel.setValueIn(CommentEditorFormField.Size, {
|
|
width,
|
|
height,
|
|
});
|
|
}
|
|
}, [formModel, width, height]);
|
|
|
|
// 同步表单外部值变化:初始化/undo/redo/协同
|
|
useEffect(() => {
|
|
const disposer = formModel.onFormValuesChange(({ name }) => {
|
|
if (name !== CommentEditorFormField.Size) {
|
|
return;
|
|
}
|
|
const newSize = formModel.getValueIn<{ width: number; height: number }>(
|
|
CommentEditorFormField.Size
|
|
);
|
|
if (!newSize) {
|
|
return;
|
|
}
|
|
setWidth(newSize.width);
|
|
setHeight(newSize.height);
|
|
});
|
|
return () => disposer.dispose();
|
|
}, [formModel]);
|
|
|
|
const onResize = useCallback(() => {
|
|
const resizeState = {
|
|
width,
|
|
height,
|
|
originalWidth: width,
|
|
originalHeight: height,
|
|
positionX: transform.position.x,
|
|
positionY: transform.position.y,
|
|
offsetX: 0,
|
|
offsetY: 0,
|
|
};
|
|
const resizing = (delta: { top: number; right: number; bottom: number; left: number }) => {
|
|
if (!resizeState) {
|
|
return;
|
|
}
|
|
|
|
const { zoom } = playground.config;
|
|
|
|
const top = delta.top / zoom;
|
|
const right = delta.right / zoom;
|
|
const bottom = delta.bottom / zoom;
|
|
const left = delta.left / zoom;
|
|
|
|
const minWidth = 120;
|
|
const minHeight = 80;
|
|
|
|
const newWidth = Math.max(minWidth, resizeState.originalWidth + right - left);
|
|
const newHeight = Math.max(minHeight, resizeState.originalHeight + bottom - top);
|
|
|
|
// 如果宽度或高度小于最小值,则不更新偏移量
|
|
const newOffsetX =
|
|
(left > 0 || right < 0) && newWidth <= minWidth
|
|
? resizeState.offsetX
|
|
: left / 2 + right / 2;
|
|
const newOffsetY =
|
|
(top > 0 || bottom < 0) && newHeight <= minHeight ? resizeState.offsetY : top;
|
|
|
|
const newPositionX = resizeState.positionX + newOffsetX;
|
|
const newPositionY = resizeState.positionY + newOffsetY;
|
|
|
|
resizeState.width = newWidth;
|
|
resizeState.height = newHeight;
|
|
resizeState.offsetX = newOffsetX;
|
|
resizeState.offsetY = newOffsetY;
|
|
|
|
// 更新状态
|
|
setWidth(newWidth);
|
|
setHeight(newHeight);
|
|
|
|
// 更新偏移量
|
|
transform.update({
|
|
position: {
|
|
x: newPositionX,
|
|
y: newPositionY,
|
|
},
|
|
});
|
|
};
|
|
|
|
const resizeEnd = () => {
|
|
historyService.transact(() => {
|
|
historyService.pushOperation(
|
|
{
|
|
type: FreeOperationType.dragNodes,
|
|
value: {
|
|
ids: [node.id],
|
|
value: [
|
|
{
|
|
x: resizeState.positionX + resizeState.offsetX,
|
|
y: resizeState.positionY + resizeState.offsetY,
|
|
},
|
|
],
|
|
oldValue: [
|
|
{
|
|
x: resizeState.positionX,
|
|
y: resizeState.positionY,
|
|
},
|
|
],
|
|
},
|
|
},
|
|
{
|
|
noApply: true,
|
|
}
|
|
);
|
|
formModel.setValueIn(CommentEditorFormField.Size, {
|
|
width: resizeState.width,
|
|
height: resizeState.height,
|
|
});
|
|
});
|
|
};
|
|
|
|
return {
|
|
resizing,
|
|
resizeEnd,
|
|
};
|
|
}, [node, width, height, transform, playground, formModel, historyService]);
|
|
|
|
return {
|
|
width,
|
|
height,
|
|
onResize,
|
|
};
|
|
};
|