Initial commit
This commit is contained in:
39
src/utils/debugEventService.js
Normal file
39
src/utils/debugEventService.js
Normal file
@@ -0,0 +1,39 @@
|
||||
// 调试文件 - 检查 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;
|
||||
};
|
||||
25
src/utils/eventBus.js
Normal file
25
src/utils/eventBus.js
Normal file
@@ -0,0 +1,25 @@
|
||||
// 简单的事件总线,用于组件间通信
|
||||
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();
|
||||
75
src/utils/textUtils.js
Normal file
75
src/utils/textUtils.js
Normal file
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* 文本处理工具函数
|
||||
*/
|
||||
|
||||
/**
|
||||
* 处理包含<br>标签的文本,转换为适合在React中显示的格式
|
||||
* @param {string} text - 包含<br>标签的文本
|
||||
* @param {string} mode - 处理模式:'html' 使用dangerouslySetInnerHTML, 'text' 转换为纯文本换行, 'remove' 直接去掉br标签
|
||||
* @returns {string} 处理后的文本
|
||||
*/
|
||||
export const formatTextWithBr = (text, mode = 'text') => {
|
||||
if (!text) return '';
|
||||
|
||||
switch (mode) {
|
||||
case 'html':
|
||||
// 用于dangerouslySetInnerHTML,保持换行效果
|
||||
return text
|
||||
.replace(/<br\s*\/?>(\s*)/g, '\n') // 将br标签转换为换行符
|
||||
.replace(/\n{2,}/g, '\n') // 去掉多余的换行符
|
||||
.replace(/\n/g, '<br/>'); // 重新转换为br标签
|
||||
|
||||
case 'text':
|
||||
// 用于普通Text组件,配合whiteSpace="pre-line"使用
|
||||
return text
|
||||
.replace(/<br\s*\/?>(\s*)/g, '\n') // 将br标签转换为换行符
|
||||
.replace(/\n{2,}/g, '\n') // 去掉多余的换行符
|
||||
.trim();
|
||||
|
||||
case 'remove':
|
||||
// 直接去掉br标签,用空格替代
|
||||
return text
|
||||
.replace(/<br\s*\/?>(\s*)/g, ' ') // 将br标签替换为空格
|
||||
.replace(/\s{2,}/g, ' ') // 去掉多余的空格
|
||||
.trim();
|
||||
|
||||
default:
|
||||
return text;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 为文本添加样式化的换行处理
|
||||
* @param {string} text - 原始文本
|
||||
* @returns {object} 包含处理后文本和样式的对象
|
||||
*/
|
||||
export const getFormattedTextProps = (text) => {
|
||||
if (!text) return { children: '', props: {} };
|
||||
|
||||
const formattedText = formatTextWithBr(text, 'text');
|
||||
|
||||
return {
|
||||
children: formattedText,
|
||||
props: {
|
||||
whiteSpace: 'pre-line',
|
||||
lineHeight: '1.6',
|
||||
wordBreak: 'break-word'
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* 为工具提示(Tooltip)优化的文本格式化
|
||||
* @param {string} text - 原始文本
|
||||
* @param {number} maxLength - 最大长度,超出部分用...省略
|
||||
* @returns {string} 处理后的文本
|
||||
*/
|
||||
export const formatTooltipText = (text, maxLength = 200) => {
|
||||
if (!text) return '';
|
||||
|
||||
const cleaned = formatTextWithBr(text, 'text');
|
||||
|
||||
if (cleaned.length <= maxLength) return cleaned;
|
||||
|
||||
return cleaned.substring(0, maxLength) + '...';
|
||||
};
|
||||
214
src/utils/tradingDayUtils.js
Normal file
214
src/utils/tradingDayUtils.js
Normal file
@@ -0,0 +1,214 @@
|
||||
// src/utils/tradingDayUtils.js
|
||||
// 交易日计算工具函数
|
||||
|
||||
/**
|
||||
* 中国股市交易日工具类
|
||||
* 包含节假日判断和交易日计算
|
||||
*/
|
||||
class TradingDayUtils {
|
||||
constructor() {
|
||||
// 2024-2025年的法定节假日(需要定期更新)
|
||||
this.holidays = new Set([
|
||||
// 2024年节假日
|
||||
'2024-01-01', // 元旦
|
||||
'2024-02-09', '2024-02-10', '2024-02-11', '2024-02-12', '2024-02-13',
|
||||
'2024-02-14', '2024-02-15', '2024-02-16', '2024-02-17', // 春节
|
||||
'2024-04-04', '2024-04-05', '2024-04-06', // 清明节
|
||||
'2024-05-01', '2024-05-02', '2024-05-03', '2024-05-04', '2024-05-05', // 劳动节
|
||||
'2024-06-08', '2024-06-09', '2024-06-10', // 端午节
|
||||
'2024-09-15', '2024-09-16', '2024-09-17', // 中秋节
|
||||
'2024-10-01', '2024-10-02', '2024-10-03', '2024-10-04',
|
||||
'2024-10-05', '2024-10-06', '2024-10-07', // 国庆节
|
||||
|
||||
// 2025年节假日(预估,需要根据官方公告更新)
|
||||
'2025-01-01', // 元旦
|
||||
'2025-01-28', '2025-01-29', '2025-01-30', '2025-01-31',
|
||||
'2025-02-01', '2025-02-02', '2025-02-03', '2025-02-04', // 春节
|
||||
'2025-04-04', '2025-04-05', '2025-04-06', // 清明节
|
||||
'2025-05-01', '2025-05-02', '2025-05-03', // 劳动节
|
||||
'2025-05-31', '2025-06-01', '2025-06-02', // 端午节
|
||||
'2025-10-01', '2025-10-02', '2025-10-03', '2025-10-04',
|
||||
'2025-10-05', '2025-10-06', '2025-10-07', '2025-10-08', // 国庆节+中秋节
|
||||
]);
|
||||
|
||||
// A股交易时间
|
||||
this.marketOpenTime = { hour: 9, minute: 30 };
|
||||
this.marketCloseTime = { hour: 15, minute: 0 };
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为周末
|
||||
* @param {Date} date
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isWeekend(date) {
|
||||
const day = date.getDay();
|
||||
return day === 0 || day === 6; // 0是周日,6是周六
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为节假日
|
||||
* @param {Date} date
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isHoliday(date) {
|
||||
const dateStr = this.formatDate(date);
|
||||
return this.holidays.has(dateStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为交易日
|
||||
* @param {Date} date
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isTradingDay(date) {
|
||||
return !this.isWeekend(date) && !this.isHoliday(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化日期为 YYYY-MM-DD
|
||||
* @param {Date} date
|
||||
* @returns {string}
|
||||
*/
|
||||
formatDate(date) {
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断时间是否在交易时间内
|
||||
* @param {Date} datetime
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isInTradingHours(datetime) {
|
||||
const hours = datetime.getHours();
|
||||
const minutes = datetime.getMinutes();
|
||||
|
||||
// 上午交易时间:9:30-11:30
|
||||
const morningStart = hours > 9 || (hours === 9 && minutes >= 30);
|
||||
const morningEnd = hours < 11 || (hours === 11 && minutes <= 30);
|
||||
|
||||
// 下午交易时间:13:00-15:00
|
||||
const afternoonStart = hours >= 13;
|
||||
const afternoonEnd = hours < 15;
|
||||
|
||||
return (morningStart && morningEnd) || (afternoonStart && afternoonEnd);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断事件是否发生在交易时间后
|
||||
* @param {Date} datetime
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isAfterTradingHours(datetime) {
|
||||
const hours = datetime.getHours();
|
||||
const minutes = datetime.getMinutes();
|
||||
return hours > 15 || (hours === 15 && minutes > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取下一个交易日
|
||||
* @param {Date} date
|
||||
* @returns {Date}
|
||||
*/
|
||||
getNextTradingDay(date) {
|
||||
const nextDay = new Date(date);
|
||||
nextDay.setDate(nextDay.getDate() + 1);
|
||||
|
||||
while (!this.isTradingDay(nextDay)) {
|
||||
nextDay.setDate(nextDay.getDate() + 1);
|
||||
}
|
||||
|
||||
return nextDay;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取上一个交易日
|
||||
* @param {Date} date
|
||||
* @returns {Date}
|
||||
*/
|
||||
getPreviousTradingDay(date) {
|
||||
const prevDay = new Date(date);
|
||||
prevDay.setDate(prevDay.getDate() - 1);
|
||||
|
||||
while (!this.isTradingDay(prevDay)) {
|
||||
prevDay.setDate(prevDay.getDate() - 1);
|
||||
}
|
||||
|
||||
return prevDay;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据事件时间获取对应的交易日
|
||||
* 规则:
|
||||
* 1. 如果是交易日的交易时间内,返回当天
|
||||
* 2. 如果是交易日的15:00后,返回下一个交易日
|
||||
* 3. 如果是非交易日(周末或节假日),返回下一个交易日
|
||||
*
|
||||
* @param {Date|string} eventDateTime 事件时间
|
||||
* @returns {string} 交易日期 YYYY-MM-DD
|
||||
*/
|
||||
getEffectiveTradingDay(eventDateTime) {
|
||||
const datetime = typeof eventDateTime === 'string' ? new Date(eventDateTime) : eventDateTime;
|
||||
|
||||
// 如果是非交易日,直接返回下一个交易日
|
||||
if (!this.isTradingDay(datetime)) {
|
||||
return this.formatDate(this.getNextTradingDay(datetime));
|
||||
}
|
||||
|
||||
// 如果是交易日
|
||||
// 检查是否在15:00之后
|
||||
if (this.isAfterTradingHours(datetime)) {
|
||||
// 15:00后,返回下一个交易日
|
||||
return this.formatDate(this.getNextTradingDay(datetime));
|
||||
}
|
||||
|
||||
// 交易日的15:00前,返回当天
|
||||
return this.formatDate(datetime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量加载交易日数据(如果有CSV文件)
|
||||
* @param {string} csvContent CSV内容
|
||||
*/
|
||||
loadTradingDaysFromCSV(csvContent) {
|
||||
const lines = csvContent.trim().split('\n');
|
||||
const tradingDays = new Set();
|
||||
|
||||
// 跳过标题行
|
||||
for (let i = 1; i < lines.length; i++) {
|
||||
const date = lines[i].trim();
|
||||
if (date) {
|
||||
// 转换日期格式 2010/1/4 -> 2010-01-04
|
||||
const parts = date.split('/');
|
||||
if (parts.length === 3) {
|
||||
const year = parts[0];
|
||||
const month = parts[1].padStart(2, '0');
|
||||
const day = parts[2].padStart(2, '0');
|
||||
tradingDays.add(`${year}-${month}-${day}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.tradingDaysSet = tradingDays;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用CSV数据判断是否为交易日(如果已加载)
|
||||
* @param {Date} date
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isTradingDayByCSV(date) {
|
||||
if (this.tradingDaysSet) {
|
||||
return this.tradingDaysSet.has(this.formatDate(date));
|
||||
}
|
||||
// 如果没有CSV数据,回退到默认判断
|
||||
return this.isTradingDay(date);
|
||||
}
|
||||
}
|
||||
|
||||
// 导出单例
|
||||
export const tradingDayUtils = new TradingDayUtils();
|
||||
export default tradingDayUtils;
|
||||
Reference in New Issue
Block a user