- hooks/useDetailModalState: 整合弹窗 17 个状态为单一 Hook - constants: 主题色配置、热度级别常量、日期常量 - utils: 交易时间判断、热度颜色、日期/股票代码格式化 - styles/animations.css: 深色主题覆盖、动画、滚动条样式 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
198 lines
5.8 KiB
JavaScript
198 lines
5.8 KiB
JavaScript
// HeroPanel - DetailModal 状态管理 Hook
|
|
// 整合 DetailModal 组件的所有状态,使主组件更简洁
|
|
|
|
import { useState, useCallback } from "react";
|
|
|
|
/**
|
|
* DetailModal 状态管理 Hook
|
|
* 将 17 个 useState 整合为一个自定义 hook
|
|
*/
|
|
export const useDetailModalState = () => {
|
|
// ========== UI 状态 ==========
|
|
// 视图模式:板块视图 | 个股视图
|
|
const [ztViewMode, setZtViewMode] = useState("sector"); // 'sector' | 'stock'
|
|
// 板块筛选(个股视图时使用)
|
|
const [selectedSectorFilter, setSelectedSectorFilter] = useState(null);
|
|
// 展开的涨停原因
|
|
const [expandedReasons, setExpandedReasons] = useState({});
|
|
|
|
// ========== 弹窗/抽屉状态 ==========
|
|
// 内容详情抽屉
|
|
const [detailDrawerVisible, setDetailDrawerVisible] = useState(false);
|
|
const [selectedContent, setSelectedContent] = useState(null);
|
|
// 板块股票弹窗
|
|
const [sectorStocksModalVisible, setSectorStocksModalVisible] = useState(false);
|
|
const [selectedSectorInfo, setSelectedSectorInfo] = useState(null);
|
|
// 事件关联股票抽屉
|
|
const [stocksDrawerVisible, setStocksDrawerVisible] = useState(false);
|
|
const [selectedEventStocks, setSelectedEventStocks] = useState([]);
|
|
const [selectedEventTime, setSelectedEventTime] = useState(null);
|
|
const [selectedEventTitle, setSelectedEventTitle] = useState("");
|
|
// K线弹窗
|
|
const [klineModalVisible, setKlineModalVisible] = useState(false);
|
|
const [selectedKlineStock, setSelectedKlineStock] = useState(null);
|
|
// 关联事件弹窗
|
|
const [relatedEventsModalVisible, setRelatedEventsModalVisible] = useState(false);
|
|
const [selectedRelatedEvents, setSelectedRelatedEvents] = useState({
|
|
sectorName: "",
|
|
events: [],
|
|
});
|
|
|
|
// ========== 数据加载状态 ==========
|
|
const [stockQuotes, setStockQuotes] = useState({});
|
|
const [stockQuotesLoading, setStockQuotesLoading] = useState(false);
|
|
|
|
// ========== 操作方法 ==========
|
|
|
|
// 打开内容详情
|
|
const openContentDetail = useCallback((content) => {
|
|
setSelectedContent(content);
|
|
setDetailDrawerVisible(true);
|
|
}, []);
|
|
|
|
// 关闭内容详情
|
|
const closeContentDetail = useCallback(() => {
|
|
setDetailDrawerVisible(false);
|
|
setSelectedContent(null);
|
|
}, []);
|
|
|
|
// 打开板块股票弹窗
|
|
const openSectorStocks = useCallback((sectorInfo) => {
|
|
setSelectedSectorInfo(sectorInfo);
|
|
setSectorStocksModalVisible(true);
|
|
}, []);
|
|
|
|
// 关闭板块股票弹窗
|
|
const closeSectorStocks = useCallback(() => {
|
|
setSectorStocksModalVisible(false);
|
|
setSelectedSectorInfo(null);
|
|
}, []);
|
|
|
|
// 打开事件关联股票
|
|
const openEventStocks = useCallback((stocks, time, title) => {
|
|
setSelectedEventStocks(stocks);
|
|
setSelectedEventTime(time);
|
|
setSelectedEventTitle(title);
|
|
setStocksDrawerVisible(true);
|
|
}, []);
|
|
|
|
// 关闭事件关联股票
|
|
const closeEventStocks = useCallback(() => {
|
|
setStocksDrawerVisible(false);
|
|
setSelectedEventStocks([]);
|
|
setSelectedEventTime(null);
|
|
setSelectedEventTitle("");
|
|
}, []);
|
|
|
|
// 打开 K 线弹窗
|
|
const openKlineModal = useCallback((stock) => {
|
|
setSelectedKlineStock(stock);
|
|
setKlineModalVisible(true);
|
|
}, []);
|
|
|
|
// 关闭 K 线弹窗
|
|
const closeKlineModal = useCallback(() => {
|
|
setKlineModalVisible(false);
|
|
setSelectedKlineStock(null);
|
|
}, []);
|
|
|
|
// 打开关联事件弹窗
|
|
const openRelatedEvents = useCallback((sectorName, events) => {
|
|
setSelectedRelatedEvents({ sectorName, events });
|
|
setRelatedEventsModalVisible(true);
|
|
}, []);
|
|
|
|
// 关闭关联事件弹窗
|
|
const closeRelatedEvents = useCallback(() => {
|
|
setRelatedEventsModalVisible(false);
|
|
setSelectedRelatedEvents({ sectorName: "", events: [] });
|
|
}, []);
|
|
|
|
// 切换展开原因
|
|
const toggleExpandedReason = useCallback((stockCode) => {
|
|
setExpandedReasons((prev) => ({
|
|
...prev,
|
|
[stockCode]: !prev[stockCode],
|
|
}));
|
|
}, []);
|
|
|
|
// 重置所有状态(用于关闭弹窗时)
|
|
const resetAllState = useCallback(() => {
|
|
setZtViewMode("sector");
|
|
setSelectedSectorFilter(null);
|
|
setExpandedReasons({});
|
|
setDetailDrawerVisible(false);
|
|
setSelectedContent(null);
|
|
setSectorStocksModalVisible(false);
|
|
setSelectedSectorInfo(null);
|
|
setStocksDrawerVisible(false);
|
|
setSelectedEventStocks([]);
|
|
setSelectedEventTime(null);
|
|
setSelectedEventTitle("");
|
|
setKlineModalVisible(false);
|
|
setSelectedKlineStock(null);
|
|
setRelatedEventsModalVisible(false);
|
|
setSelectedRelatedEvents({ sectorName: "", events: [] });
|
|
setStockQuotes({});
|
|
setStockQuotesLoading(false);
|
|
}, []);
|
|
|
|
return {
|
|
// UI 状态 + setters
|
|
ztViewMode,
|
|
setZtViewMode,
|
|
selectedSectorFilter,
|
|
setSelectedSectorFilter,
|
|
expandedReasons,
|
|
setExpandedReasons,
|
|
|
|
// 弹窗状态 + setters
|
|
detailDrawerVisible,
|
|
setDetailDrawerVisible,
|
|
selectedContent,
|
|
setSelectedContent,
|
|
sectorStocksModalVisible,
|
|
setSectorStocksModalVisible,
|
|
selectedSectorInfo,
|
|
setSelectedSectorInfo,
|
|
stocksDrawerVisible,
|
|
setStocksDrawerVisible,
|
|
selectedEventStocks,
|
|
setSelectedEventStocks,
|
|
selectedEventTime,
|
|
setSelectedEventTime,
|
|
selectedEventTitle,
|
|
setSelectedEventTitle,
|
|
klineModalVisible,
|
|
setKlineModalVisible,
|
|
selectedKlineStock,
|
|
setSelectedKlineStock,
|
|
relatedEventsModalVisible,
|
|
setRelatedEventsModalVisible,
|
|
selectedRelatedEvents,
|
|
setSelectedRelatedEvents,
|
|
|
|
// 数据状态 + setters
|
|
stockQuotes,
|
|
setStockQuotes,
|
|
stockQuotesLoading,
|
|
setStockQuotesLoading,
|
|
|
|
// 操作方法(高级封装)
|
|
openContentDetail,
|
|
closeContentDetail,
|
|
openSectorStocks,
|
|
closeSectorStocks,
|
|
openEventStocks,
|
|
closeEventStocks,
|
|
openKlineModal,
|
|
closeKlineModal,
|
|
openRelatedEvents,
|
|
closeRelatedEvents,
|
|
toggleExpandedReason,
|
|
resetAllState,
|
|
};
|
|
};
|
|
|
|
export default useDetailModalState;
|