refactor: DynamicNewsDetailPanel 组件优化
- 使用 useReducer 整合 7 个折叠状态为统一的 sectionState - 提取自选股逻辑到 useWatchlist Hook,移除 70 行重复代码 - 扩展 useWatchlist 添加 handleAddToWatchlist、isInWatchlist 方法 - 清理未使用的导入(HStack、useColorModeValue) - 移除调试 console.log 日志 - RelatedStocksSection 改用 isInWatchlist 函数替代 watchlistSet 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -10,7 +10,7 @@ const WATCHLIST_PAGE_SIZE = 10;
|
||||
|
||||
/**
|
||||
* 自选股管理 Hook
|
||||
* 提供自选股加载、分页、移除等功能
|
||||
* 提供自选股加载、分页、添加、移除等功能
|
||||
*
|
||||
* @returns {{
|
||||
* watchlistQuotes: Array,
|
||||
@@ -19,7 +19,9 @@ const WATCHLIST_PAGE_SIZE = 10;
|
||||
* setWatchlistPage: Function,
|
||||
* WATCHLIST_PAGE_SIZE: number,
|
||||
* loadWatchlistQuotes: Function,
|
||||
* handleRemoveFromWatchlist: Function
|
||||
* handleAddToWatchlist: Function,
|
||||
* handleRemoveFromWatchlist: Function,
|
||||
* isInWatchlist: Function
|
||||
* }}
|
||||
*/
|
||||
export const useWatchlist = () => {
|
||||
@@ -58,6 +60,32 @@ export const useWatchlist = () => {
|
||||
}
|
||||
}, []);
|
||||
|
||||
// 添加到自选股
|
||||
const handleAddToWatchlist = useCallback(async (stockCode, stockName) => {
|
||||
try {
|
||||
const base = getApiBase();
|
||||
const resp = await fetch(base + '/api/account/watchlist/add', {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ stock_code: stockCode, stock_name: stockName })
|
||||
});
|
||||
const data = await resp.json().catch(() => ({}));
|
||||
if (resp.ok && data.success) {
|
||||
// 刷新自选股列表
|
||||
loadWatchlistQuotes();
|
||||
toast({ title: '已添加至自选股', status: 'success', duration: 1500 });
|
||||
return true;
|
||||
} else {
|
||||
toast({ title: '添加失败', status: 'error', duration: 2000 });
|
||||
return false;
|
||||
}
|
||||
} catch (e) {
|
||||
toast({ title: '网络错误,添加失败', status: 'error', duration: 2000 });
|
||||
return false;
|
||||
}
|
||||
}, [toast, loadWatchlistQuotes]);
|
||||
|
||||
// 从自选股移除
|
||||
const handleRemoveFromWatchlist = useCallback(async (stockCode) => {
|
||||
try {
|
||||
@@ -85,9 +113,20 @@ export const useWatchlist = () => {
|
||||
}
|
||||
} catch (e) {
|
||||
toast({ title: '网络错误,移除失败', status: 'error', duration: 2000 });
|
||||
return false;
|
||||
}
|
||||
}, [toast]);
|
||||
|
||||
// 判断股票是否在自选股中
|
||||
const isInWatchlist = useCallback((stockCode) => {
|
||||
const normalize6 = (code) => {
|
||||
const m = String(code || '').match(/(\d{6})/);
|
||||
return m ? m[1] : String(code || '');
|
||||
};
|
||||
const target = normalize6(stockCode);
|
||||
return watchlistQuotes.some(item => normalize6(item.stock_code) === target);
|
||||
}, [watchlistQuotes]);
|
||||
|
||||
return {
|
||||
watchlistQuotes,
|
||||
watchlistLoading,
|
||||
@@ -95,6 +134,8 @@ export const useWatchlist = () => {
|
||||
setWatchlistPage,
|
||||
WATCHLIST_PAGE_SIZE,
|
||||
loadWatchlistQuotes,
|
||||
handleRemoveFromWatchlist
|
||||
handleAddToWatchlist,
|
||||
handleRemoveFromWatchlist,
|
||||
isInWatchlist
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user