zdl
e22a39c5cd
feat: 提交历史事件对比组件
2025-11-02 16:37:46 +08:00
zdl
c518fa76e3
feat: 添加相关股票模块
2025-11-01 12:19:47 +08:00
zdl
3b8b749eb1
feat: 添加相关股票模块
2025-11-01 12:19:47 +08:00
zdl
1c12fafc99
feat:删除不必要组件
2025-10-31 20:12:05 +08:00
zdl
571d5e68bc
feat:删除不必要组件
2025-10-31 20:12:05 +08:00
zdl
873fcb0adb
feat:添加mock数据
2025-10-31 20:11:50 +08:00
zdl
933932b86d
feat:添加mock数据
2025-10-31 20:11:50 +08:00
zdl
15f5ae92b3
feat: 添加相关概念组件
2025-10-31 20:08:53 +08:00
zdl
fc251ede05
feat: 添加相关概念组件
2025-10-31 20:08:53 +08:00
zdl
b1abe8a831
feat: 添加可折叠模块标题组件
2025-10-31 18:15:39 +08:00
zdl
57c4c3c959
feat: 添加可折叠模块标题组件
2025-10-31 18:15:39 +08:00
zdl
a72baf6805
feat: 事件滑动面板添加 详情面板
2025-10-31 18:14:05 +08:00
zdl
e1e82555bf
feat: 事件滑动面板添加 详情面板
2025-10-31 18:14:05 +08:00
zdl
2e1cdba8d3
feat: 添加事件描述组件
2025-10-31 17:50:23 +08:00
zdl
b44a0ccd39
feat: 添加事件描述组件
2025-10-31 17:50:23 +08:00
zdl
45ee80b5eb
feat: UI调整
2025-10-31 16:29:11 +08:00
zdl
2d936ca1c7
feat: UI调整
2025-10-31 16:29:11 +08:00
zdl
320795b705
style: 优化事件详情和涨跌幅指标的视觉效果
...
EventHeaderInfo 组件优化:
- "重要性:高"背景色改为浅杏黄色(yellow.100 → orange.50)
- 文字颜色改为深杏色(yellow.700 → orange.800)
- 视觉效果更柔和优雅,不刺眼
StockChangeIndicators 组件优化:
- 改用多颜色梯度(5级分级)
- 上涨:红色系(red.900/700/500)→ 橙色系(orange.600/400)
- 下跌:绿色系(green.900/700/500)→ 青色系(teal.600/400)
- 背景色和边框色跟随数字颜色
- 移除调试 console.log
视觉改进:
- 颜色分级更细腻,从3级增加到5级
- 引入橙色和青色让小幅和大幅波动有明显色系区别
- 5.7% 显示为深红色,1.7% 显示为橙色,视觉区分明显
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-10-31 16:00:37 +08:00
zdl
14db374820
style: 优化事件详情和涨跌幅指标的视觉效果
...
EventHeaderInfo 组件优化:
- "重要性:高"背景色改为浅杏黄色(yellow.100 → orange.50)
- 文字颜色改为深杏色(yellow.700 → orange.800)
- 视觉效果更柔和优雅,不刺眼
StockChangeIndicators 组件优化:
- 改用多颜色梯度(5级分级)
- 上涨:红色系(red.900/700/500)→ 橙色系(orange.600/400)
- 下跌:绿色系(green.900/700/500)→ 青色系(teal.600/400)
- 背景色和边框色跟随数字颜色
- 移除调试 console.log
视觉改进:
- 颜色分级更细腻,从3级增加到5级
- 引入橙色和青色让小幅和大幅波动有明显色系区别
- 5.7% 显示为深红色,1.7% 显示为橙色,视觉区分明显
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-10-31 16:00:37 +08:00
zdl
6c8dce49ae
feat: 添加事件详情头部
2025-10-31 15:33:22 +08:00
zdl
db472620f3
feat: 添加事件详情头部
2025-10-31 15:33:22 +08:00
zdl
b29e90f7d0
fix: 优化概念中心时间轴弹窗关闭行为,使用条件渲染
...
问题描述:
- 点击关闭按钮后,弹窗未完全关闭
- 可能存在 DOM 残留或状态问题
优化方案:
- 使用条件渲染替代 isOpen 属性控制
- 当状态为 false 时,Modal 组件完全从 DOM 中卸载
- 确保每次打开都是全新的状态
修改内容:
1. 主时间轴 Modal:添加 {isOpen && <Modal>...</Modal>} 条件渲染
2. 研报详情 Modal:添加 {isReportModalOpen && <Modal>...</Modal>} 条件渲染
3. 新闻详情 Modal:添加 {isNewsModalOpen && <Modal>...</Modal>} 条件渲染
优化效果:
- 弹窗关闭后组件完全卸载,避免残留
- 减少不必要的 DOM 节点,提升性能
- 每次打开都是全新的组件实例
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-10-31 15:05:15 +08:00
zdl
37d98203a3
fix: 优化概念中心时间轴弹窗关闭行为,使用条件渲染
...
问题描述:
- 点击关闭按钮后,弹窗未完全关闭
- 可能存在 DOM 残留或状态问题
优化方案:
- 使用条件渲染替代 isOpen 属性控制
- 当状态为 false 时,Modal 组件完全从 DOM 中卸载
- 确保每次打开都是全新的状态
修改内容:
1. 主时间轴 Modal:添加 {isOpen && <Modal>...</Modal>} 条件渲染
2. 研报详情 Modal:添加 {isReportModalOpen && <Modal>...</Modal>} 条件渲染
3. 新闻详情 Modal:添加 {isNewsModalOpen && <Modal>...</Modal>} 条件渲染
优化效果:
- 弹窗关闭后组件完全卸载,避免残留
- 减少不必要的 DOM 节点,提升性能
- 每次打开都是全新的组件实例
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-10-31 15:05:15 +08:00
zdl
d4c577e197
feat:暂时注释掉市场复盘
2025-10-31 15:01:53 +08:00
zdl
2420ff45a4
feat:暂时注释掉市场复盘
2025-10-31 15:01:53 +08:00
zdl
5ca8d91f34
fix: 修复概念中心历史时间轴"查看详情"按钮无响应问题
...
问题描述:
- 在历史时间轴弹窗中,点击新闻或研报的"查看详情"按钮无响应
- 导致用户无法查看新闻/研报的详细内容
问题根因:
- 在 onClick 事件处理函数中使用了未定义的变量 `date`
- 应该使用循环中的 `item.date` 变量
- 未定义的变量导致追踪函数报错,阻止了后续代码执行
- Modal 无法正常打开
修复内容:
- 第750行:trackNewsClicked(event, date) → trackNewsClicked(event, item.date)
- 第763行:trackReportClicked(event, date) → trackReportClicked(event, item.date)
影响范围:
- 概念中心历史时间轴功能
- 新闻和研报详情查看功能
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-10-31 14:51:53 +08:00
zdl
adaebbf800
fix: 修复概念中心历史时间轴"查看详情"按钮无响应问题
...
问题描述:
- 在历史时间轴弹窗中,点击新闻或研报的"查看详情"按钮无响应
- 导致用户无法查看新闻/研报的详细内容
问题根因:
- 在 onClick 事件处理函数中使用了未定义的变量 `date`
- 应该使用循环中的 `item.date` 变量
- 未定义的变量导致追踪函数报错,阻止了后续代码执行
- Modal 无法正常打开
修复内容:
- 第750行:trackNewsClicked(event, date) → trackNewsClicked(event, item.date)
- 第763行:trackReportClicked(event, date) → trackReportClicked(event, item.date)
影响范围:
- 概念中心历史时间轴功能
- 新闻和研报详情查看功能
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-10-31 14:51:53 +08:00
zdl
46e99938e8
feat: 添加事件详情面板
2025-10-31 14:38:43 +08:00
zdl
9fd9fcb731
feat: 添加事件详情面板
2025-10-31 14:38:43 +08:00
zdl
f5ade90d0f
feat: 新增实时要闻·动态追踪与市场复盘功能,优化导航体验
...
新增功能:
- 实时要闻·动态追踪横向滚动卡片(DynamicNewsCard)
- 动态新闻事件卡片组件(DynamicNewsEventCard)
- 市场复盘卡片组件(MarketReviewCard)
- 股票涨跌幅指标组件(StockChangeIndicators)
- 交易时间工具函数(tradingTimeUtils)
- Mock API 支持动态新闻数据生成
UI 优化:
- EventFollowButton 改用 react-icons 星星图标,实现真正的空心/实心效果
- 关注按钮添加半透明白色背景(whiteAlpha.500),悬停效果更明显
- 事件卡片标题添加右侧留白,防止关注按钮遮挡文字
性能优化:
- 禁用 Router v7_startTransition 特性,解决路由切换延迟 2 秒问题
- 调整导航菜单点击顺序(先跳转后关闭),提升响应速度
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-10-31 14:11:03 +08:00
zdl
c372832f1f
feat: 新增实时要闻·动态追踪与市场复盘功能,优化导航体验
...
新增功能:
- 实时要闻·动态追踪横向滚动卡片(DynamicNewsCard)
- 动态新闻事件卡片组件(DynamicNewsEventCard)
- 市场复盘卡片组件(MarketReviewCard)
- 股票涨跌幅指标组件(StockChangeIndicators)
- 交易时间工具函数(tradingTimeUtils)
- Mock API 支持动态新闻数据生成
UI 优化:
- EventFollowButton 改用 react-icons 星星图标,实现真正的空心/实心效果
- 关注按钮添加半透明白色背景(whiteAlpha.500),悬停效果更明显
- 事件卡片标题添加右侧留白,防止关注按钮遮挡文字
性能优化:
- 禁用 Router v7_startTransition 特性,解决路由切换延迟 2 秒问题
- 调整导航菜单点击顺序(先跳转后关闭),提升响应速度
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-10-31 14:11:03 +08:00
zdl
80f9376cc6
feat: bugfix
2025-10-31 10:33:53 +08:00
zdl
5d8ad5e442
feat: bugfix
2025-10-31 10:33:53 +08:00
zdl
2ca58cdff7
fix(TradingSimulation): 修复 React Hooks 调用顺序错误
...
提取 JSX 中直接调用的 useColorModeValue 到组件顶部,避免 Hooks 顺序不一致。
修改内容:
- 在第 95 行添加 contentTextColor 常量
- 替换第 350 行 Heading 中的内联 Hook 调用
- 替换第 361 行 Text 中的内联 Hook 调用
修复警告:React has detected a change in the order of Hooks called by TradingSimulation
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-10-30 19:08:24 +08:00
zdl
f05daa3a78
fix(TradingSimulation): 修复 React Hooks 调用顺序错误
...
提取 JSX 中直接调用的 useColorModeValue 到组件顶部,避免 Hooks 顺序不一致。
修改内容:
- 在第 95 行添加 contentTextColor 常量
- 替换第 350 行 Heading 中的内联 Hook 调用
- 替换第 361 行 Text 中的内联 Hook 调用
修复警告:React has detected a change in the order of Hooks called by TradingSimulation
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-10-30 19:08:24 +08:00
zdl
2eb260edd7
fix: 修复导航菜单 hover 触发实现方式
...
修复之前提交(47f84c5 )中使用的无效 trigger="hover" 属性。
Chakra UI Menu 组件不支持 trigger 属性,改用正确的实现方式:
**实现方式:**
- 使用 useDisclosure Hook 管理菜单开关状态
- 为 MenuButton 和 MenuList 添加 onMouseEnter/onMouseLeave 事件
- 这样可以确保鼠标从按钮移到菜单列表时保持打开状态
**修改的组件:**
- DesktopNav.js: 为4个菜单添加独立的 useDisclosure Hook
- MoreMenu.js: 平板版"更多"菜单
- PersonalCenterMenu.js: 个人中心菜单
**技术要点:**
- MenuButton 和 MenuList 都需要 hover 事件处理
- 每个菜单使用独立的 useDisclosure 实例
- 符合 Chakra UI 官方推荐的 hover 菜单实现方式
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-10-30 19:06:21 +08:00
zdl
2461ce81c9
fix: 修复导航菜单 hover 触发实现方式
...
修复之前提交(47f84c5 )中使用的无效 trigger="hover" 属性。
Chakra UI Menu 组件不支持 trigger 属性,改用正确的实现方式:
**实现方式:**
- 使用 useDisclosure Hook 管理菜单开关状态
- 为 MenuButton 和 MenuList 添加 onMouseEnter/onMouseLeave 事件
- 这样可以确保鼠标从按钮移到菜单列表时保持打开状态
**修改的组件:**
- DesktopNav.js: 为4个菜单添加独立的 useDisclosure Hook
- MoreMenu.js: 平板版"更多"菜单
- PersonalCenterMenu.js: 个人中心菜单
**技术要点:**
- MenuButton 和 MenuList 都需要 hover 事件处理
- 每个菜单使用独立的 useDisclosure 实例
- 符合 Chakra UI 官方推荐的 hover 菜单实现方式
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-10-30 19:06:21 +08:00
zdl
42a3b0c6ad
fix: 修复 InvestmentCalendar Ant Design 5.x API 废弃警告
...
## 问题
控制台出现 4 个 Ant Design API 废弃警告:
```
[antd: Calendar] `dateCellRender` is deprecated. Please use `cellRender` instead.
[antd: Modal] `visible` is deprecated. Please use `open` instead.
[antd: Modal] `bodyStyle` is deprecated. Please use `styles.body` instead.
[antd: Drawer] `visible` is deprecated. Please use `open` instead.
```
## 修复内容
### 1. Calendar API (Line 137, 687)
**旧 API**:
```javascript
const dateCellRender = (value) => {
const dateStr = value.format('YYYY-MM-DD');
// ...
};
<Calendar dateCellRender={dateCellRender} />
```
**新 API (Ant Design 5.x)**:
```javascript
const cellRender = (current, info) => {
// 只处理日期单元格,月份单元格返回默认
if (info.type !== 'date') return info.originNode;
const dateStr = current.format('YYYY-MM-DD');
// ...
};
<Calendar cellRender={cellRender} />
```
### 2. Modal API (Line 701, 766)
`visible` → `open`
```javascript
// 旧 API
<Modal visible={modalVisible} />
// 新 API
<Modal open={modalVisible} />
```
### 3. Modal Styles API (Line 705)
`bodyStyle` → `styles.body`
```javascript
// 旧 API
<Modal bodyStyle={{ padding: '24px' }} />
// 新 API
<Modal styles={{ body: { padding: '24px' } }} />
```
### 4. Drawer API (Line 740)
`visible` → `open`
```javascript
// 旧 API
<Drawer visible={detailDrawerVisible} />
// 新 API
<Drawer open={detailDrawerVisible} />
```
## 影响
- ✅ 消除 4 个 Ant Design API 废弃警告
- ✅ 兼容 Ant Design 5.x
- ✅ 功能不受影响
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-10-30 19:04:30 +08:00
zdl
85d505cd53
fix: 修复 InvestmentCalendar Ant Design 5.x API 废弃警告
...
## 问题
控制台出现 4 个 Ant Design API 废弃警告:
```
[antd: Calendar] `dateCellRender` is deprecated. Please use `cellRender` instead.
[antd: Modal] `visible` is deprecated. Please use `open` instead.
[antd: Modal] `bodyStyle` is deprecated. Please use `styles.body` instead.
[antd: Drawer] `visible` is deprecated. Please use `open` instead.
```
## 修复内容
### 1. Calendar API (Line 137, 687)
**旧 API**:
```javascript
const dateCellRender = (value) => {
const dateStr = value.format('YYYY-MM-DD');
// ...
};
<Calendar dateCellRender={dateCellRender} />
```
**新 API (Ant Design 5.x)**:
```javascript
const cellRender = (current, info) => {
// 只处理日期单元格,月份单元格返回默认
if (info.type !== 'date') return info.originNode;
const dateStr = current.format('YYYY-MM-DD');
// ...
};
<Calendar cellRender={cellRender} />
```
### 2. Modal API (Line 701, 766)
`visible` → `open`
```javascript
// 旧 API
<Modal visible={modalVisible} />
// 新 API
<Modal open={modalVisible} />
```
### 3. Modal Styles API (Line 705)
`bodyStyle` → `styles.body`
```javascript
// 旧 API
<Modal bodyStyle={{ padding: '24px' }} />
// 新 API
<Modal styles={{ body: { padding: '24px' } }} />
```
### 4. Drawer API (Line 740)
`visible` → `open`
```javascript
// 旧 API
<Drawer visible={detailDrawerVisible} />
// 新 API
<Drawer open={detailDrawerVisible} />
```
## 影响
- ✅ 消除 4 个 Ant Design API 废弃警告
- ✅ 兼容 Ant Design 5.x
- ✅ 功能不受影响
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-10-30 19:04:30 +08:00
zdl
b3a9c832a0
fix: 修复 StockOverview prevStats 未定义错误
...
## 问题
控制台报错:
```
ReferenceError: prevStats is not defined
at fetchMarketStats (index.js:247:1)
```
## 根本原因
`fetchMarketStats` 函数中引用了不存在的变量 `prevStats`:
```javascript
// ❌ 错误代码
const newStats = {
...data.summary,
rising_count: prevStats?.rising_count,
falling_count: prevStats?.falling_count,
date: data.trade_date
};
```
这里的 `prevStats` 变量从未定义或声明。
## 解决方案
使用状态变量 `marketStats` 来获取之前的值:
```javascript
// ✅ 正确代码
const newStats = {
...data.summary,
rising_count: marketStats?.rising_count,
falling_count: marketStats?.falling_count,
date: data.trade_date
};
```
## 影响
- ✅ 修复市场统计数据加载错误
- ✅ 正确保留上涨/下跌家数
- ✅ 消除控制台 ReferenceError
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-10-30 18:59:49 +08:00
zdl
1886c54e0f
fix: 修复 StockOverview prevStats 未定义错误
...
## 问题
控制台报错:
```
ReferenceError: prevStats is not defined
at fetchMarketStats (index.js:247:1)
```
## 根本原因
`fetchMarketStats` 函数中引用了不存在的变量 `prevStats`:
```javascript
// ❌ 错误代码
const newStats = {
...data.summary,
rising_count: prevStats?.rising_count,
falling_count: prevStats?.falling_count,
date: data.trade_date
};
```
这里的 `prevStats` 变量从未定义或声明。
## 解决方案
使用状态变量 `marketStats` 来获取之前的值:
```javascript
// ✅ 正确代码
const newStats = {
...data.summary,
rising_count: marketStats?.rising_count,
falling_count: marketStats?.falling_count,
date: data.trade_date
};
```
## 影响
- ✅ 修复市场统计数据加载错误
- ✅ 正确保留上涨/下跌家数
- ✅ 消除控制台 ReferenceError
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-10-30 18:59:49 +08:00
zdl
602547eb22
fix: 修复 MSW EventEmitter 内存泄漏警告
...
## 问题
控制台警告:
```
MaxListenersExceededWarning: Possible EventEmitter memory leak detected.
11 response:mocked listeners added. Use emitter.setMaxListeners() to increase limit
```
## 根本原因
类似 PostHog 的问题:
1. **React StrictMode 双重渲染** - 开发环境组件渲染两次
2. **热重载** - 代码更改时频繁重新加载模块
3. **缺少启动锁** - `startMockServiceWorker()` 被多次调用
4. **事件监听器累积** - 每次启动添加新 listener,旧的未清理
## 解决方案
### 方案A: 防止重复启动
添加启动状态锁:
```javascript
let isStarting = false;
let isStarted = false;
export async function startMockServiceWorker() {
// 防止重复启动
if (isStarting || isStarted) {
console.log('[MSW] 已启动,跳过重复调用');
return;
}
isStarting = true;
try {
await worker.start({...});
isStarted = true; // 成功后标记
} finally {
isStarting = false; // 无论成功失败都重置
}
}
```
### 方案B: 完善 stop 逻辑
确保正确清理:
```javascript
export function stopMockServiceWorker() {
if (!isStarted) return; // 避免重复停止
worker.stop();
isStarted = false; // 重置状态
console.log('[MSW] Mock Service Worker 已停止');
}
```
## 影响
- ✅ 修复 EventEmitter 内存泄漏警告
- ✅ 防止热重载时重复启动 MSW
- ✅ 正确清理事件监听器
- ✅ 提升开发体验
## 验证
重启开发服务器后:
- ✅ 不再有 MaxListenersExceededWarning
- ✅ MSW 只启动一次
- ✅ 热重载正常工作
- ✅ Mock 功能正常
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-10-30 18:56:12 +08:00
zdl
6829f687ee
fix: 修复 MSW EventEmitter 内存泄漏警告
...
## 问题
控制台警告:
```
MaxListenersExceededWarning: Possible EventEmitter memory leak detected.
11 response:mocked listeners added. Use emitter.setMaxListeners() to increase limit
```
## 根本原因
类似 PostHog 的问题:
1. **React StrictMode 双重渲染** - 开发环境组件渲染两次
2. **热重载** - 代码更改时频繁重新加载模块
3. **缺少启动锁** - `startMockServiceWorker()` 被多次调用
4. **事件监听器累积** - 每次启动添加新 listener,旧的未清理
## 解决方案
### 方案A: 防止重复启动
添加启动状态锁:
```javascript
let isStarting = false;
let isStarted = false;
export async function startMockServiceWorker() {
// 防止重复启动
if (isStarting || isStarted) {
console.log('[MSW] 已启动,跳过重复调用');
return;
}
isStarting = true;
try {
await worker.start({...});
isStarted = true; // 成功后标记
} finally {
isStarting = false; // 无论成功失败都重置
}
}
```
### 方案B: 完善 stop 逻辑
确保正确清理:
```javascript
export function stopMockServiceWorker() {
if (!isStarted) return; // 避免重复停止
worker.stop();
isStarted = false; // 重置状态
console.log('[MSW] Mock Service Worker 已停止');
}
```
## 影响
- ✅ 修复 EventEmitter 内存泄漏警告
- ✅ 防止热重载时重复启动 MSW
- ✅ 正确清理事件监听器
- ✅ 提升开发体验
## 验证
重启开发服务器后:
- ✅ 不再有 MaxListenersExceededWarning
- ✅ MSW 只启动一次
- ✅ 热重载正常工作
- ✅ Mock 功能正常
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-10-30 18:56:12 +08:00
zdl
63e26db44e
feat: 导航菜单改为 hover 触发
...
为所有导航菜单组件添加 trigger="hover" 属性,使菜单在鼠标悬停时自动展开,提升用户体验。
修改的组件:
- DesktopNav.js: 4 个主导航菜单(高频跟踪、行情复盘、AGENT社群、联系我们)
- MoreMenu.js: 平板版"更多"下拉菜单
- PersonalCenterMenu.js: 个人中心下拉菜单
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-10-30 18:49:14 +08:00
zdl
47f84c5eff
feat: 导航菜单改为 hover 触发
...
为所有导航菜单组件添加 trigger="hover" 属性,使菜单在鼠标悬停时自动展开,提升用户体验。
修改的组件:
- DesktopNav.js: 4 个主导航菜单(高频跟踪、行情复盘、AGENT社群、联系我们)
- MoreMenu.js: 平板版"更多"下拉菜单
- PersonalCenterMenu.js: 个人中心下拉菜单
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-10-30 18:49:14 +08:00
zdl
10e417516e
fix: 修复 PostHog AbortError 和重复初始化问题
...
## 问题
控制台报错:
```
[PostHog.js] AbortError: The user aborted a request.
```
## 根本原因
### 1. 热重载导致重复初始化
- 开发环境频繁热重载
- App.js 每次重载都调用 initPostHog()
- 之前的网络请求被新请求中断 → AbortError
### 2. 缺少初始化状态管理
- 没有防止重复初始化的锁
- 每次组件更新都可能触发新的初始化
## 解决方案
### 方案A: 防止重复初始化
添加初始化状态锁:
```javascript
let isInitializing = false;
let isInitialized = false;
export const initPostHog = () => {
// 防止重复初始化
if (isInitializing || isInitialized) {
console.log('📊 PostHog 已初始化,跳过重复调用');
return;
}
isInitializing = true;
try {
posthog.init(apiKey, {...});
isInitialized = true; // 成功后标记为已初始化
} finally {
isInitializing = false; // 无论成功失败都重置标志
}
};
```
### 方案B: 捕获并忽略 AbortError
在 catch 块中特殊处理:
```javascript
} catch (error) {
// 忽略 AbortError(通常由热重载引起)
if (error.name === 'AbortError') {
console.log('⚠️ PostHog 初始化请求被中断(热重载)');
return; // 静默处理,不报错
}
console.error('❌ PostHog initialization failed:', error);
}
```
## 影响
- ✅ 修复 AbortError 警告
- ✅ 防止热重载时重复初始化
- ✅ 提升开发体验
- ✅ 不影响生产环境
## 验证
重启开发服务器后:
- ✅ 不再有 AbortError
- ✅ PostHog 只初始化一次
- ✅ 热重载正常工作
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-10-30 18:49:03 +08:00
zdl
a0d1790469
fix: 修复 PostHog AbortError 和重复初始化问题
...
## 问题
控制台报错:
```
[PostHog.js] AbortError: The user aborted a request.
```
## 根本原因
### 1. 热重载导致重复初始化
- 开发环境频繁热重载
- App.js 每次重载都调用 initPostHog()
- 之前的网络请求被新请求中断 → AbortError
### 2. 缺少初始化状态管理
- 没有防止重复初始化的锁
- 每次组件更新都可能触发新的初始化
## 解决方案
### 方案A: 防止重复初始化
添加初始化状态锁:
```javascript
let isInitializing = false;
let isInitialized = false;
export const initPostHog = () => {
// 防止重复初始化
if (isInitializing || isInitialized) {
console.log('📊 PostHog 已初始化,跳过重复调用');
return;
}
isInitializing = true;
try {
posthog.init(apiKey, {...});
isInitialized = true; // 成功后标记为已初始化
} finally {
isInitializing = false; // 无论成功失败都重置标志
}
};
```
### 方案B: 捕获并忽略 AbortError
在 catch 块中特殊处理:
```javascript
} catch (error) {
// 忽略 AbortError(通常由热重载引起)
if (error.name === 'AbortError') {
console.log('⚠️ PostHog 初始化请求被中断(热重载)');
return; // 静默处理,不报错
}
console.error('❌ PostHog initialization failed:', error);
}
```
## 影响
- ✅ 修复 AbortError 警告
- ✅ 防止热重载时重复初始化
- ✅ 提升开发体验
- ✅ 不影响生产环境
## 验证
重启开发服务器后:
- ✅ 不再有 AbortError
- ✅ PostHog 只初始化一次
- ✅ 热重载正常工作
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-10-30 18:49:03 +08:00
zdl
b83eab28e3
fix(NotificationContainer): 修复 React Hooks 调用顺序错误
...
**问题描述**
React 检测到 NotificationItem 组件中 Hooks 调用顺序不一致:
```
Warning: React has detected a change in the order of Hooks called by null.
Previous render: 24. useCallback
Next render: 25. useContext
```
**根本原因**
在第 433 行,`useColorModeValue` Hook 在条件对象展开中被调用:
```javascript
{...(isNewest && {
borderTopColor: useColorModeValue(...), // ❌ 违反 Hooks 规则
})}
```
当 `isNewest` 值变化时:
- `isNewest = false` → Hook 不调用
- `isNewest = true` → Hook 调用
- 导致不同渲染的 Hooks 数量不一致
**React Hooks 规则**
> Hooks 必须在组件顶层调用,不能在条件语句、循环或嵌套函数中调用
**修复内容**
1. **将 Hook 移到组件顶层** (第 349-353 行)
```javascript
// 最新通知的 borderTopColor(避免在条件语句中调用 Hook)
const newestBorderTopColor = useColorModeValue(
`${typeConfig.colorScheme}.100`,
`${typeConfig.colorScheme}.700`
);
```
2. **添加到 colors 对象** (第 365 行)
```javascript
const colors = useMemo(() => ({
// ... 其他颜色
newestBorderTop: newestBorderTopColor,
}), [/* dependencies */]);
```
3. **在 JSX 中使用预计算的值** (第 439 行)
```diff
{...(isNewest && {
- borderTopColor: useColorModeValue(...),
+ borderTopColor: colors.newestBorderTop,
})}
```
**修复验证**
- ✅ 所有 Hooks 在每次渲染都以相同顺序调用
- ✅ 消除 React Hooks 警告
- ✅ 功能保持不变(视觉效果一致)
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-10-30 18:43:19 +08:00
zdl
0364b3a927
fix(NotificationContainer): 修复 React Hooks 调用顺序错误
...
**问题描述**
React 检测到 NotificationItem 组件中 Hooks 调用顺序不一致:
```
Warning: React has detected a change in the order of Hooks called by null.
Previous render: 24. useCallback
Next render: 25. useContext
```
**根本原因**
在第 433 行,`useColorModeValue` Hook 在条件对象展开中被调用:
```javascript
{...(isNewest && {
borderTopColor: useColorModeValue(...), // ❌ 违反 Hooks 规则
})}
```
当 `isNewest` 值变化时:
- `isNewest = false` → Hook 不调用
- `isNewest = true` → Hook 调用
- 导致不同渲染的 Hooks 数量不一致
**React Hooks 规则**
> Hooks 必须在组件顶层调用,不能在条件语句、循环或嵌套函数中调用
**修复内容**
1. **将 Hook 移到组件顶层** (第 349-353 行)
```javascript
// 最新通知的 borderTopColor(避免在条件语句中调用 Hook)
const newestBorderTopColor = useColorModeValue(
`${typeConfig.colorScheme}.100`,
`${typeConfig.colorScheme}.700`
);
```
2. **添加到 colors 对象** (第 365 行)
```javascript
const colors = useMemo(() => ({
// ... 其他颜色
newestBorderTop: newestBorderTopColor,
}), [/* dependencies */]);
```
3. **在 JSX 中使用预计算的值** (第 439 行)
```diff
{...(isNewest && {
- borderTopColor: useColorModeValue(...),
+ borderTopColor: colors.newestBorderTop,
})}
```
**修复验证**
- ✅ 所有 Hooks 在每次渲染都以相同顺序调用
- ✅ 消除 React Hooks 警告
- ✅ 功能保持不变(视觉效果一致)
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-10-30 18:43:19 +08:00
zdl
0c9f130f2a
fix(EventList): 删除重复的 Toast 通知,统一使用右下角通知卡片
...
**问题描述**
新事件推送时显示两种通知:
1. ❌ 左侧顶部绿色 Toast(重复多次)
2. ✅ 右下角通知卡片(NotificationContainer)
用户反馈:只需要右下角通知卡片,不需要 Toast 提示
**修复内容**
删除 EventList.js 中的 Chakra UI Toast 通知代码(13 行):
```diff
- console.log('[EventList DEBUG] 准备显示 Toast 通知');
- // 显示 Toast 通知 - 更明显的配置
- const toastId = toast({
- title: '🔔 新事件发布',
- description: event.title,
- status: 'success',
- duration: 8000,
- isClosable: true,
- position: 'top',
- variant: 'solid',
- });
- console.log('[EventList DEBUG] ✓ Toast 通知已调用,ID:', toastId);
```
**保留的通知能力**
- ✅ 右下角通知卡片(NotificationContainer)
- ✅ 浏览器原生通知(需用户授权)
- ✅ 事件列表实时更新
- ✅ PostHog 埋点追踪
**验证**
刷新页面后,新事件推送时:
- ❌ 不再显示左侧 Toast
- ✅ 只显示右下角通知卡片
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-10-30 18:39:47 +08:00