| | |
| | | * 提供案件数据的全局状态管理和localStorage持久化 |
| | | */ |
| | | |
| | | import React, { createContext, useContext, useState, useEffect } from 'react'; |
| | | import React, { createContext, useContext, useState, useEffect, useRef } from 'react'; |
| | | import { message } from 'antd'; |
| | | import ProcessAPIService from '../services/ProcessAPIService'; |
| | | import { getMergedParams } from '../utils/urlParams'; |
| | |
| | | */ |
| | | export const CaseDataProvider = ({ children }) => { |
| | | const [caseData, setCaseData] = useState(null); |
| | | const [processNodes, setProcessNodes] = useState([]); // 流程节点数据 |
| | | const [loading, setLoading] = useState(false); |
| | | const [error, setError] = useState(null); |
| | | const [taskStartTime, setTaskStartTime] = useState(null); // 任务开始时间 |
| | | const [isTaskTimeFallback, setIsTaskTimeFallback] = useState(false); // 是否降级模式 |
| | | const [hasLoaded, setHasLoaded] = useState(false); // 防止重复加载 |
| | | |
| | | /** |
| | | * 从localStorage读取数据 |
| | |
| | | * 加载案件数据 |
| | | */ |
| | | const loadCaseData = async (forceRefresh = false) => { |
| | | // 如果不是强制刷新,先尝试从localStorage读取 |
| | | if (!forceRefresh) { |
| | | const cachedData = loadFromStorage(); |
| | | if (cachedData) { |
| | | setCaseData(cachedData); |
| | | console.log('Loaded case data from localStorage'); |
| | | } |
| | | // 防止重复加载(除非强制刷新) |
| | | if (hasLoaded && !forceRefresh) { |
| | | console.log('Data already loaded, skipping...'); |
| | | return; |
| | | } |
| | | |
| | | setLoading(true); |
| | |
| | | // 提取timeline数据 |
| | | const timelineData = response.timeline || response.data?.timeline || response; |
| | | |
| | | // 提取nodes数据(确保为数组) |
| | | const nodesData = response.nodes || response.data?.nodes || []; |
| | | |
| | | console.log('API Response:', response); |
| | | console.log('Extracted nodesData:', nodesData); |
| | | |
| | | // 更新状态 |
| | | setCaseData(timelineData); |
| | | setProcessNodes(Array.isArray(nodesData) ? nodesData : []); // 确保为数组 |
| | | setHasLoaded(true); // 标记已加载 |
| | | |
| | | // 保存到localStorage |
| | | saveToStorage(timelineData); |
| | |
| | | // 显示错误提示 |
| | | message.error('加载案件数据失败,请稍后重试'); |
| | | |
| | | // 如果localStorage有数据,尝试使用缓存 |
| | | const cachedData = loadFromStorage(); |
| | | if (cachedData && !forceRefresh) { |
| | | message.warning('已加载历史数据'); |
| | | setCaseData(cachedData); |
| | | // 缓存数据也加载任务时间 |
| | | await loadTaskTime(cachedData); |
| | | } else { |
| | | // 使用Mock数据 |
| | | console.log('使用Mock数据'); |
| | | // 使用Mock数据(缓存数据不包含nodes,所以统一使用Mock) |
| | | console.log('===== 使用Mock数据 ====='); |
| | | const mockData = mockTimelineData.data.timeline; |
| | | const mockNodes = mockTimelineData.data.nodes || []; |
| | | console.log('mockData:', mockData); |
| | | console.log('mockNodes:', mockNodes); |
| | | setCaseData(mockData); |
| | | setProcessNodes(mockNodes); |
| | | saveToStorage(mockData); |
| | | setHasLoaded(true); |
| | | |
| | | // Mock数据也加载任务时间 |
| | | await loadTaskTime(mockData); |
| | | } |
| | | } finally { |
| | | setLoading(false); |
| | | } |
| | |
| | | loadCaseData(true); |
| | | }; |
| | | |
| | | // 防止重复加载的引用标识 |
| | | const loadInitRef = useRef(false); |
| | | |
| | | /** |
| | | * 组件挂载时加载数据 |
| | | */ |
| | | useEffect(() => { |
| | | console.log('===== CaseDataContext useEffect triggered ====='); |
| | | console.log('loadInitRef.current:', loadInitRef.current); |
| | | console.log('hasLoaded:', hasLoaded); |
| | | console.log('processNodes:', processNodes); |
| | | |
| | | // StrictMode下防止双重调用 |
| | | if (!loadInitRef.current) { |
| | | loadInitRef.current = true; |
| | | console.log('Calling loadCaseData()...'); |
| | | loadCaseData(); |
| | | } else { |
| | | console.log('loadCaseData() skipped due to loadInitRef.current === true'); |
| | | } |
| | | // eslint-disable-next-line react-hooks/exhaustive-deps |
| | | }, []); // 只在挂载时执行一次 |
| | | |
| | | // 提供的值 |
| | | const value = { |
| | | caseData, |
| | | processNodes, // 流程节点数据 |
| | | loading, |
| | | error, |
| | | refreshData, |