chore: 删除未使用的 Hooks/Services/Utils 文件 (第9批)

删除以下未被引用的文件:
- usePostHog.js (已被 usePostHogRedux.js 替代)
- llmService.js
- debugEventService.js / eventBus.js / tradingTimeUtils.js

⚠️ 已恢复误删的 predictionMarketService.js

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
zdl
2025-12-29 17:23:22 +08:00
parent 8c2260cf44
commit 6fed1b40cd
5 changed files with 0 additions and 624 deletions

View File

@@ -1,101 +0,0 @@
// src/hooks/usePostHog.js
import { useCallback } from 'react';
import {
getPostHog,
trackEvent,
trackPageView,
identifyUser,
setUserProperties,
resetUser,
optIn,
optOut,
hasOptedOut,
getFeatureFlag,
isFeatureEnabled,
} from '../lib/posthog';
/**
* Custom hook to access PostHog functionality
* Provides convenient methods for tracking events and managing user sessions
*
* @returns {object} PostHog methods
*/
export const usePostHog = () => {
// Get PostHog instance
const posthog = getPostHog();
// Track custom event
const track = useCallback((eventName, properties = {}) => {
trackEvent(eventName, properties);
}, []);
// Track page view
const trackPage = useCallback((pagePath, properties = {}) => {
trackPageView(pagePath, properties);
}, []);
// Identify user
const identify = useCallback((userId, userProperties = {}) => {
identifyUser(userId, userProperties);
}, []);
// Set user properties
const setProperties = useCallback((properties) => {
setUserProperties(properties);
}, []);
// Reset user session (logout)
const reset = useCallback(() => {
resetUser();
}, []);
// Opt out of tracking
const optOutTracking = useCallback(() => {
optOut();
}, []);
// Opt in to tracking
const optInTracking = useCallback(() => {
optIn();
}, []);
// Check if user has opted out
const isOptedOut = useCallback(() => {
return hasOptedOut();
}, []);
// Get feature flag value
const getFlag = useCallback((flagKey, defaultValue = false) => {
return getFeatureFlag(flagKey, defaultValue);
}, []);
// Check if feature is enabled
const isEnabled = useCallback((flagKey) => {
return isFeatureEnabled(flagKey);
}, []);
return {
// Core PostHog instance
posthog,
// Tracking methods
track,
trackPage,
// User management
identify,
setProperties,
reset,
// Privacy controls
optOut: optOutTracking,
optIn: optInTracking,
isOptedOut,
// Feature flags
getFlag,
isEnabled,
};
};
export default usePostHog;

View File

@@ -1,278 +0,0 @@
// src/services/llmService.js
// LLM服务层 - 集成AI模型进行对话和工具调用
import axios from 'axios';
import { mcpService } from './mcpService';
import { logger } from '../utils/logger';
/**
* LLM服务配置
*/
const LLM_CONFIG = {
// 可以使用 OpenAI、Claude、通义千问等
provider: 'openai', // 或 'claude', 'qwen'
apiKey: process.env.REACT_APP_OPENAI_API_KEY || '',
apiUrl: 'https://api.openai.com/v1/chat/completions',
model: 'gpt-4o-mini', // 更便宜的模型
};
/**
* LLM服务类
*/
class LLMService {
constructor() {
this.conversationHistory = [];
}
/**
* 构建系统提示词
*/
getSystemPrompt(availableTools) {
return `你是一个专业的金融投资助手。你可以使用以下工具来帮助用户查询信息:
${availableTools.map(tool => `
**${tool.name}**
描述:${tool.description}
参数:${JSON.stringify(tool.parameters, null, 2)}
`).join('\n')}
用户提问时,请按照以下步骤:
1. 理解用户的意图
2. 选择合适的工具(可以多个)
3. 提取工具需要的参数
4. 调用工具后,用自然语言总结结果
回复格式:
- 如果需要调用工具返回JSON格式{"tool": "工具名", "arguments": {...}}
- 如果不需要工具,直接回复自然语言
注意:
- 贵州茅台的股票代码是 600519
- 涨停是指股票当日涨幅达到10%
- 概念板块是指相同题材的股票分类`;
}
/**
* 智能对话 - 使用LLM理解意图并调用工具
*/
async chat(userMessage, conversationHistory = []) {
try {
// 1. 获取可用工具列表
const toolsResult = await mcpService.listTools();
if (!toolsResult.success) {
throw new Error('获取工具列表失败');
}
const availableTools = toolsResult.data;
// 2. 构建对话历史
const messages = [
{
role: 'system',
content: this.getSystemPrompt(availableTools),
},
...conversationHistory.map(msg => ({
role: msg.isUser ? 'user' : 'assistant',
content: msg.content,
})),
{
role: 'user',
content: userMessage,
},
];
// 3. 调用LLM
logger.info('LLMService', '调用LLM', { messageCount: messages.length });
// 注意这里需要配置API密钥
if (!LLM_CONFIG.apiKey) {
// 如果没有配置LLM使用简单的关键词匹配
logger.warn('LLMService', '未配置LLM API密钥使用简单匹配');
return await this.fallbackChat(userMessage);
}
const response = await axios.post(
LLM_CONFIG.apiUrl,
{
model: LLM_CONFIG.model,
messages: messages,
temperature: 0.7,
max_tokens: 1000,
},
{
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${LLM_CONFIG.apiKey}`,
},
timeout: 30000,
}
);
const aiResponse = response.data.choices[0].message.content;
logger.info('LLMService', 'LLM响应', { response: aiResponse });
// 4. 解析LLM响应
// 如果LLM返回工具调用指令
try {
const toolCall = JSON.parse(aiResponse);
if (toolCall.tool && toolCall.arguments) {
// 调用MCP工具
const toolResult = await mcpService.callTool(toolCall.tool, toolCall.arguments);
if (!toolResult.success) {
return {
success: false,
error: toolResult.error,
};
}
// 5. 让LLM总结工具结果
const summaryMessages = [
...messages,
{
role: 'assistant',
content: aiResponse,
},
{
role: 'system',
content: `工具 ${toolCall.tool} 返回的数据:\n${JSON.stringify(toolResult.data, null, 2)}\n\n请用自然语言总结这些数据,给用户一个简洁清晰的回复。`,
},
];
const summaryResponse = await axios.post(
LLM_CONFIG.apiUrl,
{
model: LLM_CONFIG.model,
messages: summaryMessages,
temperature: 0.7,
max_tokens: 500,
},
{
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${LLM_CONFIG.apiKey}`,
},
timeout: 30000,
}
);
const summary = summaryResponse.data.choices[0].message.content;
return {
success: true,
data: {
message: summary,
rawData: toolResult.data,
toolUsed: toolCall.tool,
},
};
}
} catch (parseError) {
// 不是JSON格式说明是直接回复
return {
success: true,
data: {
message: aiResponse,
},
};
}
// 默认返回LLM的直接回复
return {
success: true,
data: {
message: aiResponse,
},
};
} catch (error) {
logger.error('LLMService', 'chat error', error);
return {
success: false,
error: error.message || '对话处理失败',
};
}
}
/**
* 降级方案简单的关键词匹配当没有配置LLM时
*/
async fallbackChat(userMessage) {
logger.info('LLMService', '使用降级方案', { message: userMessage });
// 使用原有的简单匹配逻辑
if (userMessage.includes('新闻') || userMessage.includes('资讯')) {
const result = await mcpService.callTool('search_china_news', {
query: userMessage.replace(/新闻|资讯/g, '').trim(),
top_k: 5,
});
return this.formatFallbackResponse(result, '新闻搜索');
} else if (userMessage.includes('概念') || userMessage.includes('板块')) {
const query = userMessage.replace(/概念|板块/g, '').trim();
const result = await mcpService.callTool('search_concepts', {
query,
size: 5,
sort_by: 'change_pct',
});
return this.formatFallbackResponse(result, '概念搜索');
} else if (userMessage.includes('涨停')) {
const query = userMessage.replace(/涨停/g, '').trim();
const result = await mcpService.callTool('search_limit_up_stocks', {
query,
mode: 'hybrid',
page_size: 5,
});
return this.formatFallbackResponse(result, '涨停分析');
} else if (/^[0-9]{6}$/.test(userMessage.trim())) {
// 6位数字 = 股票代码
const result = await mcpService.callTool('get_stock_basic_info', {
seccode: userMessage.trim(),
});
return this.formatFallbackResponse(result, '股票信息');
} else if (userMessage.includes('茅台') || userMessage.includes('贵州茅台')) {
// 特殊处理茅台
const result = await mcpService.callTool('get_stock_basic_info', {
seccode: '600519',
});
return this.formatFallbackResponse(result, '贵州茅台股票信息');
} else {
// 默认:搜索新闻
const result = await mcpService.callTool('search_china_news', {
query: userMessage,
top_k: 5,
});
return this.formatFallbackResponse(result, '新闻搜索');
}
}
/**
* 格式化降级响应
*/
formatFallbackResponse(result, action) {
if (!result.success) {
return {
success: false,
error: result.error,
};
}
return {
success: true,
data: {
message: `已为您完成${action},找到以下结果:`,
rawData: result.data,
},
};
}
/**
* 清除对话历史
*/
clearHistory() {
this.conversationHistory = [];
}
}
// 导出单例
export const llmService = new LLMService();
export default LLMService;

View File

@@ -1,39 +0,0 @@
// 调试文件 - 检查 eventService 的方法
import { eventService } from '../services/eventService';
export const debugEventService = () => {
console.log('=== eventService 调试信息 ===');
console.log('eventService 对象:', eventService);
console.log('eventService 类型:', typeof eventService);
console.log('eventService 的所有键:', Object.keys(eventService));
// 检查特定的方法
const methods = [
'getPosts',
'createPost',
'deletePost',
'likePost',
'getPostComments',
'addPostComment',
'deleteComment',
'likeComment'
];
console.log('\n方法检查:');
methods.forEach(method => {
console.log(`${method}:`,
eventService[method] ? '✓ 存在' : '✗ 不存在',
eventService[method] ? `(类型: ${typeof eventService[method]})` : ''
);
});
// 检查是否有其他相似的方法名
console.log('\n所有方法列表:');
Object.keys(eventService).forEach(key => {
if (typeof eventService[key] === 'function') {
console.log(`- ${key}`);
}
});
return eventService;
};

View File

@@ -1,25 +0,0 @@
// 简单的事件总线,用于组件间通信
class EventBus {
constructor() {
this.events = {};
}
on(event, callback) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(callback);
}
off(event, callback) {
if (!this.events[event]) return;
this.events[event] = this.events[event].filter(cb => cb !== callback);
}
emit(event, data) {
if (!this.events[event]) return;
this.events[event].forEach(callback => callback(data));
}
}
export default new EventBus();

View File

@@ -1,181 +0,0 @@
// src/utils/tradingTimeUtils.js
// 交易时间相关工具函数
import dayjs from 'dayjs';
import isSameOrBefore from 'dayjs/plugin/isSameOrBefore';
import isSameOrAfter from 'dayjs/plugin/isSameOrAfter';
// 扩展 Day.js 插件
dayjs.extend(isSameOrBefore);
dayjs.extend(isSameOrAfter);
/**
* 获取当前时间应该显示的实时要闻时间范围
* 规则:
* - 15:00 之前:显示昨日 15:00 - 今日 15:00
* - 15:30 之后:显示今日 15:00 - 当前时间
*
* @returns {{ startTime: Date, endTime: Date, description: string }}
*/
export const getCurrentTradingTimeRange = () => {
const now = dayjs();
const currentHour = now.hour();
const currentMinute = now.minute();
// 计算当前是第几分钟(方便比较)
const currentTimeInMinutes = currentHour * 60 + currentMinute;
const cutoffTime1500 = 15 * 60; // 15:00 = 900分钟
const cutoffTime1530 = 15 * 60 + 30; // 15:30 = 930分钟
let startTime, endTime, description;
if (currentTimeInMinutes < cutoffTime1500) {
// 15:00 之前:显示昨日 15:00 - 今日 15:00
startTime = dayjs().subtract(1, 'day').hour(15).minute(0).second(0).millisecond(0).toDate();
endTime = dayjs().hour(15).minute(0).second(0).millisecond(0).toDate();
description = '昨日15:00 - 今日15:00';
} else if (currentTimeInMinutes >= cutoffTime1530) {
// 15:30 之后:显示今日 15:00 - 当前时间
startTime = dayjs().hour(15).minute(0).second(0).millisecond(0).toDate();
endTime = now.toDate();
description = '今日15:00 - 当前时间';
} else {
// 15:00 - 15:30 之间:过渡期,保持显示昨日 15:00 - 今日 15:00
startTime = dayjs().subtract(1, 'day').hour(15).minute(0).second(0).millisecond(0).toDate();
endTime = dayjs().hour(15).minute(0).second(0).millisecond(0).toDate();
description = '昨日15:00 - 今日15:00';
}
return {
startTime,
endTime,
description,
rangeType: currentTimeInMinutes >= cutoffTime1530 ? 'current_day' : 'full_day'
};
};
/**
* 获取市场复盘的时间范围
* 规则:显示最近一个完整的交易日(昨日 15:00 - 今日 15:00
*
* @returns {{ startTime: Date, endTime: Date, description: string }}
*/
export const getMarketReviewTimeRange = () => {
const now = dayjs();
const currentHour = now.hour();
const currentMinute = now.minute();
// 计算当前是第几分钟
const currentTimeInMinutes = currentHour * 60 + currentMinute;
const cutoffTime1530 = 15 * 60 + 30; // 15:30 = 930分钟
let startTime, endTime, description;
if (currentTimeInMinutes >= cutoffTime1530) {
// 15:30 之后:显示昨日 15:00 - 今日 15:00刚刚完成的交易日
startTime = dayjs().subtract(1, 'day').hour(15).minute(0).second(0).millisecond(0).toDate();
endTime = dayjs().hour(15).minute(0).second(0).millisecond(0).toDate();
description = '昨日15:00 - 今日15:00';
} else {
// 15:30 之前:显示前日 15:00 - 昨日 15:00上一个完整交易日
startTime = dayjs().subtract(2, 'days').hour(15).minute(0).second(0).millisecond(0).toDate();
endTime = dayjs().subtract(1, 'day').hour(15).minute(0).second(0).millisecond(0).toDate();
description = '前日15:00 - 昨日15:00';
}
return {
startTime,
endTime,
description,
rangeType: 'market_review'
};
};
/**
* 根据时间范围过滤事件列表
*
* @param {Array} events - 事件列表
* @param {Date} startTime - 开始时间
* @param {Date} endTime - 结束时间
* @returns {Array} 过滤后的事件列表
*/
export const filterEventsByTimeRange = (events, startTime, endTime) => {
if (!events || !Array.isArray(events)) {
return [];
}
if (!startTime || !endTime) {
return events;
}
const startMoment = dayjs(startTime);
const endMoment = dayjs(endTime);
return events.filter(event => {
if (!event.created_at) {
return false;
}
const eventTime = dayjs(event.created_at);
return eventTime.isSameOrAfter(startMoment) && eventTime.isSameOrBefore(endMoment);
});
};
/**
* 判断当前是否应该显示市场复盘模块
* 根据需求:市场复盘模块一直显示
*
* @returns {boolean}
*/
export const shouldShowMarketReview = () => {
// 市场复盘模块始终显示
return true;
};
/**
* 获取时间范围的描述文本
*
* @param {Date} startTime - 开始时间
* @param {Date} endTime - 结束时间
* @returns {string}
*/
export const getTimeRangeDescription = (startTime, endTime) => {
if (!startTime || !endTime) {
return '';
}
const startStr = dayjs(startTime).format('MM-DD HH:mm');
const endStr = dayjs(endTime).format('MM-DD HH:mm');
return `${startStr} - ${endStr}`;
};
/**
* 判断是否为交易日(简化版本,只判断周末)
* 注意这里没有考虑节假日如需精确判断需要接入交易日历API
*
* @param {Date} date - 日期
* @returns {boolean}
*/
export const isTradingDay = (date) => {
const day = dayjs(date).day();
// 0 = 周日, 6 = 周六
return day !== 0 && day !== 6;
};
/**
* 获取上一个交易日(简化版本)
*
* @param {Date} date - 日期
* @returns {Date}
*/
export const getPreviousTradingDay = (date) => {
let prevDay = dayjs(date).subtract(1, 'day');
// 如果是周末,继续往前找
while (!isTradingDay(prevDay.toDate())) {
prevDay = prevDay.subtract(1, 'day');
}
return prevDay.toDate();
};