feat(flowEditor): 实现自定义边的数据展示与事件选择功能

master
钟良源 3 months ago
parent 018d06a63a
commit ec578f9cde

@ -39,3 +39,8 @@ export function queryEventItemBySceneId(sceneId: string) {
return axios.get(`${urlPrefix}/event/${sceneId}/get`);
}
// 事件管理-获取工程下可用的topic
export function getTopicList(id: string) {
return axios.get(`${urlPrefix}/event/${id}/topic`);
}

@ -1,6 +1,9 @@
import React from 'react';
import React, { useState, useEffect, useRef } from 'react';
import { BaseEdge, EdgeLabelRenderer, EdgeProps, getSmoothStepPath, useReactFlow } from '@xyflow/react';
import EdgeAddNodeButton from '@/pages/flowEditor/components/edgeAddNodeButton';
import { getTopicList } from '@/api/event';
import { useSelector } from 'react-redux';
import { Message } from '@arco-design/web-react';
type DataDisplayEdgeData = {
label?: string;
@ -23,6 +26,10 @@ const DataDisplayEdge: React.FC<EdgeProps> = ({
selected,
data
}) => {
const [options, setOptions] = useState([]);
const [isOpen, setIsOpen] = useState(false);
const [selectedValue, setSelectedValue] = useState('');
const dropdownRef = useRef<HTMLDivElement>(null);
const [edgePath, labelX, labelY] = getSmoothStepPath({
sourceX,
sourceY,
@ -32,6 +39,7 @@ const DataDisplayEdge: React.FC<EdgeProps> = ({
targetPosition,
borderRadius: 8 // 设置圆角半径
});
const { info } = useSelector((state: any) => state.ideContainer);
// 从数据中获取悬停状态
const hovered = data?.hovered || false;
@ -61,8 +69,35 @@ const DataDisplayEdge: React.FC<EdgeProps> = ({
}));
};
const handleDataClick = (e) => {
console.log('click:', e);
const getEventList = async () => {
const res: any = await getTopicList(info.id);
if (res.code === 200) {
setOptions(res.data.map(v => {
return { label: v.eventName, value: v.topic };
}));
}
};
useEffect(() => {
getEventList();
}, [displayData]);
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
setIsOpen(false);
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, []);
const handleSelect = (option) => {
setSelectedValue(option.label);
setIsOpen(false);
};
return (
@ -89,29 +124,60 @@ const DataDisplayEdge: React.FC<EdgeProps> = ({
{/* 数据展示框 */}
{displayData && Object.keys(displayData).length > 0 && (
<div
onClick={(e) => handleDataClick(e)}
ref={dropdownRef}
style={{
background: '#ffffff',
border: '1px solid #ddd',
width: 150,
border: isOpen ? '1px solid #1890ff' : '1px solid #d9d9d9',
borderRadius: 4,
padding: 4,
boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
minWidth: 100,
marginBottom: 4,
fontSize: 12,
textAlign: 'center'
backgroundColor: '#fff',
position: 'relative'
}}
>
{displayData.name && (
<div style={{ fontWeight: 'bold', marginBottom: 2 }}>
{displayData.name}
</div>
)}
{displayData.value !== undefined && (
<div>
{typeof displayData.value === 'object'
? JSON.stringify(displayData.value)
: String(displayData.value)}
<div
onClick={() => setIsOpen(!isOpen)}
style={{
padding: '4px 11px',
cursor: 'pointer',
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center'
}}
>
<span>{selectedValue || displayData.name}</span>
<span>{isOpen ? '▲' : '▼'}</span>
</div>
{isOpen && (
<div
style={{
position: 'absolute',
top: '105%',
left: 0,
right: 0,
border: '1px solid #d9d9d9',
borderTop: 'none',
borderRadius: '0 0 4px 4px',
backgroundColor: '#fff',
zIndex: 1000,
maxHeight: 200,
overflowY: 'auto'
}}
>
{options.map((option: { value: string; label: string }) => (
<div
key={option.value}
onClick={() => handleSelect(option)}
style={{
padding: '5px 12px',
cursor: 'pointer',
borderBottom: '1px solid #f0f0f0'
}}
onMouseEnter={(e) => e.currentTarget.style.backgroundColor = '#f5f5f5'}
onMouseLeave={(e) => e.currentTarget.style.backgroundColor = '#fff'}
>
{option.label}
</div>
))}
</div>
)}
</div>

Loading…
Cancel
Save