diff --git a/src/api/appRes.ts b/src/api/appRes.ts index 09833f6..2cff31e 100644 --- a/src/api/appRes.ts +++ b/src/api/appRes.ts @@ -1,5 +1,5 @@ import axios from 'axios'; -import { FlowDefinition, appFlowModel, queryParams } from '@/api/interface/index'; +import { FlowDefinition, appFlowModel, historyPageParams } from '@/api/interface/index'; // 公共路径 const urlPrefix = '/api/v1/bpms-workbench'; @@ -66,7 +66,7 @@ export function importComponenets(data: appFlowModel, appId: string) { } // 根据主流程id分页 -export function historyPage(data: queryParams) { +export function historyPage(data: historyPageParams) { return axios.post(`${urlPrefix}/appRes/historyPage`, data); } @@ -78,4 +78,4 @@ export function getHistoryDetail(appId: string, historyId: string) { // 添加已发布流程到子流程 export function addPublishSub(data: FlowDefinition, appId: string) { return axios.post(`${urlPrefix}/appRes/${appId}/addPublishSub`, data); -} +} \ No newline at end of file diff --git a/src/api/interface/index.ts b/src/api/interface/index.ts index 72ab345..28ea901 100644 --- a/src/api/interface/index.ts +++ b/src/api/interface/index.ts @@ -37,6 +37,12 @@ export interface queryParams { total?: number; } +export interface historyPageParams { + "pageSize": number, + "currPage": number, + "appId": string +} + export interface apiResData { list: applicationModel[]; } diff --git a/src/pages/flowEditor/components/handlerBar.tsx b/src/pages/flowEditor/components/handlerBar.tsx index 962a6d6..3502041 100644 --- a/src/pages/flowEditor/components/handlerBar.tsx +++ b/src/pages/flowEditor/components/handlerBar.tsx @@ -1,6 +1,7 @@ -import React from 'react'; +import React, { useState } from 'react'; import { Button } from '@arco-design/web-react'; -import { IconSend } from '@arco-design/web-react/icon'; +import { IconSend, IconOrderedList } from '@arco-design/web-react/icon'; +import HistoryVersionModal from './historyVersionModal'; interface HandlerBarProps { onPublish?: () => void; @@ -8,20 +9,43 @@ interface HandlerBarProps { } const HandlerBar: React.FC = ({ onPublish, isRunning }) => { + const [historyModalVisible, setHistoryModalVisible] = useState(false); + + const handleHistoryClick = () => { + setHistoryModalVisible(true); + }; + return ( -
-
- + <> +
+
+ + +
-
+ + setHistoryModalVisible(false)} + /> + ); }; diff --git a/src/pages/flowEditor/components/historyVersionModal.tsx b/src/pages/flowEditor/components/historyVersionModal.tsx new file mode 100644 index 0000000..4bbbb07 --- /dev/null +++ b/src/pages/flowEditor/components/historyVersionModal.tsx @@ -0,0 +1,210 @@ +import React, { useState, useEffect, useMemo } from 'react'; +import { Modal, List, Message, Spin, Pagination } 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 dayjs from 'dayjs'; + +interface HistoryVersionModalProps { + visible: boolean; + onCancel: () => void; +} + +interface HistoryItem { + appResId: string; + remarks: string; + res: { + appId: string; + compList: any; + events: any[]; + main: { + appEventDefinition: any; + components: any; + flowId: string; + flowName: string; + sceneId: string; + }; + projectId: string; + subMap: any; + subs: any[]; + }; + timestamp: number; +} + +const HistoryVersionModal: React.FC = ({ visible, onCancel }) => { + const [loading, setLoading] = useState(false); + const [historyList, setHistoryList] = useState([]); + const [selectedHistory, setSelectedHistory] = useState(null); + const [currPage, setCurrPage] = useState(1); + const [totalCount, setTotalCount] = useState(0); + const { currentAppData } = useSelector(state => state.ideContainer); + const pageSize = 10; + + // 获取历史版本列表 + const fetchHistoryList = async (page = 1) => { + if (!currentAppData?.id) return; + console.log('currentAppData:', currentAppData); + setLoading(true); + try { + const response: any = await historyPage({ + appId: currentAppData?.id, + currPage: page, + pageSize + }); + + if (response.code === 200) { + const data = response.data; + setHistoryList(data.list); + setCurrPage(data.currPage); + setTotalCount(data.totalCount); + + // 只在第一次打开时默认选择第一个历史版本 + if (data.list.length > 0 && page === 1) { + setSelectedHistory(data.list[0]); + } + } + else { + Message.error('获取历史版本失败'); + } + } catch (error) { + console.error('获取历史版本失败:', error); + Message.error('获取历史版本失败'); + } finally { + setLoading(false); + } + }; + + // 当modal打开时获取历史版本列表 + useEffect(() => { + if (visible && currentAppData?.id) { + setSelectedHistory(null); // 重置选中状态 + fetchHistoryList(1); + } + }, [visible, currentAppData?.id]); + + // 格式化时间戳 + const formatTimestamp = (timestamp: number) => { + return dayjs(Number(timestamp)).format('YYYY-MM-DD HH:mm:ss'); + }; + + // 使用useMemo缓存转换后的画布数据,避免在渲染时调用convertFlowData导致Redux dispatch + const canvasData = useMemo(() => { + if (!selectedHistory) { + return { nodes: [], edges: [] }; + } + + const components = selectedHistory.res.main.components; + try { + return convertFlowData(components, false); + } catch (error) { + console.error('转换流程数据失败:', error); + return { nodes: [], edges: [] }; + } + }, [selectedHistory]); + + // 渲染画布 + const renderCanvas = () => { + if (!selectedHistory) { + return
请选择一个历史版本
; + } + + return ( +
+ + + + + + +
+ ); + }; + + return ( + + +
+ {/* 左侧历史版本列表 */} +
+ ( + setSelectedHistory(item)} + > +
+
+ {currentAppData.name} - {item.res.main.flowName} +
+
+ {formatTimestamp(item.timestamp)} +
+ {item.remarks && ( +
+ {item.remarks} +
+ )} +
+
+ )} + /> +
+ fetchHistoryList(page)} + size="small" + showTotal + /> +
+
+ + {/* 右侧画布区域 */} +
+ {renderCanvas()} +
+
+
+
+ ); +}; + +export default HistoryVersionModal;