240 lines
7.1 KiB
JavaScript
240 lines
7.1 KiB
JavaScript
/**
|
||
* 事件服务层
|
||
* 复用 Web 端的 eventService 逻辑
|
||
*/
|
||
|
||
import { apiRequest } from './api';
|
||
|
||
/**
|
||
* 股票服务
|
||
* 获取股票实时报价等
|
||
*/
|
||
export const stockService = {
|
||
/**
|
||
* 批量获取股票报价
|
||
* @param {string[]} codes - 股票代码数组
|
||
* @param {string} eventTime - 可选的事件时间
|
||
* @returns {Promise<object>} 报价数据 {code: {name, price, change}}
|
||
*/
|
||
getQuotes: async (codes, eventTime = null) => {
|
||
try {
|
||
const requestBody = { codes };
|
||
if (eventTime) {
|
||
requestBody.event_time = eventTime;
|
||
}
|
||
|
||
console.log('[StockService] 获取股票报价:', { codes: codes.slice(0, 5), eventTime });
|
||
|
||
const response = await apiRequest('/api/stock/quotes', {
|
||
method: 'POST',
|
||
body: JSON.stringify(requestBody),
|
||
});
|
||
|
||
if (response.success && response.data) {
|
||
console.log('[StockService] 报价响应成功:', Object.keys(response.data).length, '只股票');
|
||
return response.data;
|
||
} else {
|
||
console.warn('[StockService] 报价响应格式异常:', response);
|
||
return {};
|
||
}
|
||
} catch (error) {
|
||
console.error('[StockService] getQuotes 错误:', error);
|
||
throw error;
|
||
}
|
||
},
|
||
};
|
||
|
||
export const eventService = {
|
||
/**
|
||
* 获取事件列表
|
||
* @param {object} params - 查询参数
|
||
* @param {number} params.page - 页码
|
||
* @param {number} params.per_page - 每页数量
|
||
* @param {string} params.sort - 排序方式 (new/hot/importance)
|
||
* @param {string} params.importance - 重要性筛选 (S/A/B/C)
|
||
* @param {string} params.q - 搜索关键词
|
||
* @returns {Promise<object>} 事件列表和分页信息
|
||
*/
|
||
getEvents: (params = {}) => {
|
||
// 过滤空值和内部字段
|
||
const cleanParams = Object.fromEntries(
|
||
Object.entries(params).filter(
|
||
([key, v]) => v !== null && v !== undefined && v !== '' && !key.startsWith('_')
|
||
)
|
||
);
|
||
const query = new URLSearchParams(cleanParams).toString();
|
||
return apiRequest(`/api/events?${query}`);
|
||
},
|
||
|
||
/**
|
||
* 获取热点事件
|
||
* @param {object} params - 查询参数
|
||
* @returns {Promise<object>} 热点事件列表
|
||
*/
|
||
getHotEvents: (params = {}) => {
|
||
const query = new URLSearchParams(params).toString();
|
||
return apiRequest(`/api/events/hot?${query}`);
|
||
},
|
||
|
||
/**
|
||
* 获取热门关键词
|
||
* @param {number} limit - 返回数量限制
|
||
* @returns {Promise<object>} 热门关键词列表
|
||
*/
|
||
getPopularKeywords: (limit = 20) => {
|
||
return apiRequest(`/api/events/keywords/popular?limit=${limit}`);
|
||
},
|
||
|
||
/**
|
||
* 获取事件详情
|
||
* @param {number} eventId - 事件ID
|
||
* @returns {Promise<object>} 事件详情
|
||
*/
|
||
getEventDetail: async (eventId) => {
|
||
return await apiRequest(`/api/events/${eventId}`);
|
||
},
|
||
|
||
/**
|
||
* 获取事件相关股票
|
||
* @param {number} eventId - 事件ID
|
||
* @returns {Promise<object>} 相关股票列表
|
||
*/
|
||
getRelatedStocks: async (eventId) => {
|
||
return await apiRequest(`/api/events/${eventId}/stocks`);
|
||
},
|
||
|
||
/**
|
||
* 获取事件相关概念
|
||
* @param {number} eventId - 事件ID
|
||
* @returns {Promise<object>} 相关概念列表
|
||
*/
|
||
getRelatedConcepts: async (eventId) => {
|
||
return await apiRequest(`/api/events/${eventId}/concepts`);
|
||
},
|
||
|
||
/**
|
||
* 切换事件关注状态
|
||
* @param {number} eventId - 事件ID
|
||
* @param {boolean} isFollowing - 是否关注
|
||
* @returns {Promise<object>} 关注状态
|
||
*/
|
||
toggleFollow: async (eventId, isFollowing) => {
|
||
return await apiRequest(`/api/events/${eventId}/follow`, {
|
||
method: 'POST',
|
||
body: JSON.stringify({ is_following: isFollowing }),
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 情绪投票(看多/看空)
|
||
* @param {number} eventId - 事件ID
|
||
* @param {string} voteType - 投票类型 'bullish' | 'bearish' | null
|
||
* @returns {Promise<object>} 投票结果
|
||
*/
|
||
sentimentVote: async (eventId, voteType) => {
|
||
return await apiRequest(`/api/events/${eventId}/sentiment-vote`, {
|
||
method: 'POST',
|
||
body: JSON.stringify({ vote_type: voteType }),
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 获取历史事件
|
||
* @param {number} eventId - 事件ID
|
||
* @returns {Promise<object>} 历史事件列表
|
||
*/
|
||
getHistoricalEvents: async (eventId) => {
|
||
return await apiRequest(`/api/events/${eventId}/historical`);
|
||
},
|
||
|
||
/**
|
||
* 获取事件帖子
|
||
* @param {number} eventId - 事件ID
|
||
* @param {object} params - 查询参数
|
||
* @returns {Promise<object>} 帖子列表
|
||
*/
|
||
getEventPosts: async (eventId, params = {}) => {
|
||
const query = new URLSearchParams(params).toString();
|
||
return await apiRequest(`/api/events/${eventId}/posts?${query}`);
|
||
},
|
||
|
||
/**
|
||
* 创建帖子
|
||
* @param {number} eventId - 事件ID
|
||
* @param {object} data - 帖子数据
|
||
* @returns {Promise<object>} 创建结果
|
||
*/
|
||
createPost: async (eventId, data) => {
|
||
return await apiRequest(`/api/events/${eventId}/posts`, {
|
||
method: 'POST',
|
||
body: JSON.stringify(data),
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 获取传导链数据
|
||
* @param {number} eventId - 事件ID
|
||
* @returns {Promise<object>} 传导链数据
|
||
*/
|
||
getTransmissionChain: async (eventId) => {
|
||
return await apiRequest(`/api/events/${eventId}/transmission`);
|
||
},
|
||
|
||
/**
|
||
* 获取桑基图数据
|
||
* @param {number} eventId - 事件ID
|
||
* @returns {Promise<object>} 桑基图数据
|
||
*/
|
||
getSankeyData: async (eventId) => {
|
||
return await apiRequest(`/api/events/${eventId}/sankey-data`);
|
||
},
|
||
|
||
/**
|
||
* 获取事件有效性统计(今日统计面板数据)
|
||
* @param {number} days - 天数
|
||
* @param {string} date - 可选日期
|
||
* @returns {Promise<object>} 统计数据
|
||
*/
|
||
getEffectivenessStats: async (days = 1, date = '') => {
|
||
const dateParam = date ? `&date=${date}` : '';
|
||
return await apiRequest(`/api/v1/events/effectiveness-stats?days=${days}${dateParam}`);
|
||
},
|
||
|
||
/**
|
||
* 获取市场实时统计
|
||
* @returns {Promise<object>} 市场统计数据
|
||
*/
|
||
getMarketStats: async () => {
|
||
return await apiRequest('/api/v1/market/realtime-stats');
|
||
},
|
||
|
||
/**
|
||
* 获取主线/题材事件数据
|
||
* @param {object} params - 查询参数
|
||
* @param {string} params.group_by - 分组级别 (lv1/lv2/lv3 或具体概念ID)
|
||
* @param {number} params.recent_days - 最近天数(与 start_date/end_date 二选一)
|
||
* @param {string} params.start_date - 开始时间 (YYYY-MM-DD HH:mm:ss)
|
||
* @param {string} params.end_date - 结束时间 (YYYY-MM-DD HH:mm:ss)
|
||
* @returns {Promise<object>} 主线事件分组数据
|
||
*/
|
||
getMainlineEvents: async (params = {}) => {
|
||
const { group_by = 'lv1', recent_days, start_date, end_date } = params;
|
||
|
||
// 构建查询参数
|
||
const queryParams = new URLSearchParams();
|
||
queryParams.append('group_by', group_by);
|
||
|
||
// 优先使用 start_date/end_date,否则使用 recent_days
|
||
if (start_date && end_date) {
|
||
queryParams.append('start_date', start_date);
|
||
queryParams.append('end_date', end_date);
|
||
} else if (recent_days) {
|
||
queryParams.append('recent_days', recent_days);
|
||
}
|
||
|
||
return await apiRequest(`/api/events/mainline?${queryParams.toString()}`);
|
||
},
|
||
};
|
||
|
||
export default eventService;
|