|
|
|
|
@ -1,16 +1,18 @@
|
|
|
|
|
import React, { useState, useEffect, useMemo } from 'react';
|
|
|
|
|
import { Modal, List, Message, Spin, Pagination } from '@arco-design/web-react';
|
|
|
|
|
import { Modal, List, Message, Spin, Pagination, Button, Space } from '@arco-design/web-react';
|
|
|
|
|
import { ReactFlowProvider, ReactFlow, Background, Controls } from '@xyflow/react';
|
|
|
|
|
import '@xyflow/react/dist/style.css';
|
|
|
|
|
import { historyPage } from '@/api/appRes';
|
|
|
|
|
import { convertFlowData } from '@/utils/convertFlowData';
|
|
|
|
|
import { nodeTypes } from '@/components/FlowEditor/node';
|
|
|
|
|
import { useSelector } from 'react-redux';
|
|
|
|
|
import { useSelector, useDispatch } from 'react-redux';
|
|
|
|
|
import { updateFlowData, updateCanvasDataMap } from '@/store/ideContainer';
|
|
|
|
|
import dayjs from 'dayjs';
|
|
|
|
|
|
|
|
|
|
interface HistoryVersionModalProps {
|
|
|
|
|
visible: boolean;
|
|
|
|
|
onCancel: () => void;
|
|
|
|
|
onApply?: (nodes: any[], edges: any[]) => void;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface HistoryItem {
|
|
|
|
|
@ -34,19 +36,19 @@ interface HistoryItem {
|
|
|
|
|
timestamp: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const HistoryVersionModal: React.FC<HistoryVersionModalProps> = ({ visible, onCancel }) => {
|
|
|
|
|
const HistoryVersionModal: React.FC<HistoryVersionModalProps> = ({ visible, onCancel, onApply }) => {
|
|
|
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
|
const [historyList, setHistoryList] = useState<HistoryItem[]>([]);
|
|
|
|
|
const [selectedHistory, setSelectedHistory] = useState<HistoryItem | null>(null);
|
|
|
|
|
const [currPage, setCurrPage] = useState(1);
|
|
|
|
|
const [totalCount, setTotalCount] = useState(0);
|
|
|
|
|
const { currentAppData } = useSelector(state => state.ideContainer);
|
|
|
|
|
const dispatch = useDispatch();
|
|
|
|
|
const pageSize = 10;
|
|
|
|
|
|
|
|
|
|
// 获取历史版本列表
|
|
|
|
|
const fetchHistoryList = async (page = 1) => {
|
|
|
|
|
if (!currentAppData?.id) return;
|
|
|
|
|
console.log('currentAppData:', currentAppData);
|
|
|
|
|
setLoading(true);
|
|
|
|
|
try {
|
|
|
|
|
const response: any = await historyPage({
|
|
|
|
|
@ -90,6 +92,53 @@ const HistoryVersionModal: React.FC<HistoryVersionModalProps> = ({ visible, onCa
|
|
|
|
|
return dayjs(Number(timestamp)).format('YYYY-MM-DD HH:mm:ss');
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 应用历史版本到当前画布
|
|
|
|
|
const handleApplyVersion = () => {
|
|
|
|
|
if (!selectedHistory) {
|
|
|
|
|
Message.warning('请先选择一个历史版本');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Modal.confirm({
|
|
|
|
|
title: '确认应用历史版本',
|
|
|
|
|
content: `确定要将 ${formatTimestamp(selectedHistory.timestamp)} 的版本应用到当前画布吗?当前未保存的修改将会丢失。`,
|
|
|
|
|
onOk: () => {
|
|
|
|
|
try {
|
|
|
|
|
// 转换历史版本数据为 ReactFlow 格式
|
|
|
|
|
const components = selectedHistory.res.main.components;
|
|
|
|
|
const convertedData = convertFlowData(components, false);
|
|
|
|
|
const { nodes, edges } = convertedData;
|
|
|
|
|
|
|
|
|
|
// 如果父组件提供了 onApply 回调,使用回调来更新画布
|
|
|
|
|
if (onApply) {
|
|
|
|
|
onApply(nodes, edges);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 同时更新 Redux store 中的缓存数据
|
|
|
|
|
const canvasKey = currentAppData.key || currentAppData.id;
|
|
|
|
|
|
|
|
|
|
// 更新 flowData(全局流程数据)
|
|
|
|
|
dispatch(updateFlowData(convertedData));
|
|
|
|
|
|
|
|
|
|
// 更新 canvasDataMap(画布缓存)
|
|
|
|
|
dispatch(updateCanvasDataMap({
|
|
|
|
|
[canvasKey]: {
|
|
|
|
|
nodes,
|
|
|
|
|
edges,
|
|
|
|
|
timestamp: Date.now()
|
|
|
|
|
}
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
Message.success('历史版本已应用到当前画布');
|
|
|
|
|
onCancel();
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('应用历史版本失败:', error);
|
|
|
|
|
Message.error('应用历史版本失败');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 使用useMemo缓存转换后的画布数据,避免在渲染时调用convertFlowData导致Redux dispatch
|
|
|
|
|
const canvasData = useMemo(() => {
|
|
|
|
|
if (!selectedHistory) {
|
|
|
|
|
@ -140,7 +189,18 @@ const HistoryVersionModal: React.FC<HistoryVersionModalProps> = ({ visible, onCa
|
|
|
|
|
title="历史版本"
|
|
|
|
|
visible={visible}
|
|
|
|
|
onCancel={onCancel}
|
|
|
|
|
footer={null}
|
|
|
|
|
footer={
|
|
|
|
|
<Space>
|
|
|
|
|
<Button onClick={onCancel}>取消</Button>
|
|
|
|
|
<Button
|
|
|
|
|
type="primary"
|
|
|
|
|
onClick={handleApplyVersion}
|
|
|
|
|
disabled={!selectedHistory}
|
|
|
|
|
>
|
|
|
|
|
应用到当前画布
|
|
|
|
|
</Button>
|
|
|
|
|
</Space>
|
|
|
|
|
}
|
|
|
|
|
style={{ width: '90vw', maxWidth: 1400 }}
|
|
|
|
|
>
|
|
|
|
|
<Spin loading={loading} style={{ width: '100%', height: '100%' }}>
|
|
|
|
|
|