/** * 工具函数集合 * 包含打字机效果、ID生成、回调安全调用等通用工具函数 */ /** * 打字机工具类 * 提供打字机效果相关的工具函数 */ export class TypewriterUtils { /** * 计算动态打字速度 * @param {string} char - 当前字符 * @param {number} baseSpeed - 基础速度(ms) * @returns {number} 动态调整后的速度 */ static calculateDynamicSpeed(char, baseSpeed = 100) { const punctuationMarks = [ "。", "!", "?", ".", "!", "?", ",", ",", ";", ";", ":", ":", ]; const isSpace = char === " "; const hasPunctuation = punctuationMarks.includes(char); if (hasPunctuation) { // 标点符号后停顿更久,模拟思考时间 return baseSpeed * 2.5; } else if (isSpace) { // 空格稍快一些 return baseSpeed * 0.6; } else { // 普通字符添加一些随机性,模拟真实打字的不均匀性 const randomFactor = 0.7 + Math.random() * 0.6; // 0.7-1.3倍速度 return baseSpeed * randomFactor; } } /** * 检查字符是否为标点符号 * @param {string} char - 要检查的字符 * @returns {boolean} 是否为标点符号 */ static isPunctuation(char) { const punctuationMarks = [ "。", "!", "?", ".", "!", "?", ",", ",", ";", ";", ":", ":", ]; return punctuationMarks.includes(char); } /** * 检查字符是否为空格 * @param {string} char - 要检查的字符 * @returns {boolean} 是否为空格 */ static isSpace(char) { return char === " "; } /** * 生成加载动画文本 * @param {number} dotCount - 点的数量(1-3) * @param {string} baseText - 基础文本 * @returns {string} 加载动画文本 */ static generateLoadingText(dotCount = 1, baseText = "加载中") { const normalizedDotCount = ((dotCount - 1) % 3) + 1; return baseText + ".".repeat(normalizedDotCount); } /** * 启动加载动画 */ static startLoadingAnimation( onProgress, options = {}, onTimerCreated = null ) { const { speed = 500, text = "加载中" } = options; let dotCount = 1; const timerId = setInterval(() => { dotCount = (dotCount % 3) + 1; const loadingText = text + ".".repeat(dotCount); onProgress(loadingText); }, speed); if (onTimerCreated) { onTimerCreated(timerId); } return timerId; } /** * 启动打字机效果 * @param {string} text - 要显示的文本 * @param {Element} targetElement - 目标元素(可选) * @param {Object} options - 配置选项 * @param {Function} onTimerCreated - 定时器创建回调(可选) */ static startTypewriter( text, targetElement = null, options = {}, onTimerCreated = null ) { const { speed = 100, onProgress = () => {}, onComplete = () => {}, } = options; let index = 0; const typeNextChar = () => { if (index < text.length) { const char = text[index]; const currentText = text.substring(0, index + 1); // 调用进度回调 onProgress(currentText, index); // 如果有目标元素,更新其内容 if (targetElement) { targetElement.textContent = currentText; } index++; // 计算下一个字符的延时 const delay = TypewriterUtils.calculateDynamicSpeed( char, speed ); const timerId = setTimeout(typeNextChar, delay); if (onTimerCreated && index === 1) { onTimerCreated(timerId); } } else { // 打字完成 onComplete(text); } }; // 开始打字 const initialTimerId = setTimeout(typeNextChar, 0); if (onTimerCreated) { onTimerCreated(initialTimerId); } return initialTimerId; } } /** * ID生成工具类 * 提供各种ID生成功能 */ export class IdUtils { /** * 生成消息ID * @returns {string} 消息ID */ static generateMessageId() { return "mid" + new Date().getTime(); } } /** * 回调函数安全调用工具类 * 提供安全的回调函数调用机制 */ export class CallbackUtils { /** * 安全调用回调函数 * @param {Object} callbacks - 回调函数对象 * @param {string} callbackName - 回调函数名称 * @param {...any} args - 传递给回调函数的参数 */ static safeCall(callbacks, callbackName, ...args) { if (callbacks && typeof callbacks[callbackName] === "function") { try { callbacks[callbackName](...args); } catch (error) { console.error(`回调函数 ${callbackName} 执行出错:`, error); } } else { console.warn(`回调函数 ${callbackName} 不可用`); } } /** * 批量安全调用回调函数 * @param {Object} callbacks - 回调函数对象 * @param {Array} callbackConfigs - 回调配置数组 [{name, args}, ...] */ static safeBatchCall(callbacks, callbackConfigs) { callbackConfigs.forEach((config) => { const { name, args = [] } = config; this.safeCall(callbacks, name, ...args); }); } } /** * 消息处理工具类 * 提供消息相关的工具函数 */ export class MessageUtils { /** * 验证消息格式 * @param {any} message - 消息对象 * @returns {boolean} 是否为有效消息格式 */ static validateMessage(message) { return message && typeof message === "object" && message.type; } /** * 格式化消息 * @param {string} type - 消息类型 * @param {any} content - 消息内容 * @param {Object} options - 额外选项 * @returns {Object} 格式化后的消息对象 */ static formatMessage(type, content, options = {}) { return { type, content, timestamp: Date.now(), ...options, }; } /** * 检查是否为完整消息 * @param {any} message - 消息对象 * @returns {boolean} 是否为完整消息 */ static isCompleteMessage(message) { return message && message.isComplete === true; } /** * 检查消息是否为心跳响应 * @param {any} messageData - 消息数据 * @returns {boolean} 是否为心跳响应 */ static isPongMessage(messageData) { if (typeof messageData === "string") { return ( messageData === "pong" || messageData.toLowerCase().includes("pong") ); } if (typeof messageData === "object" && messageData !== null) { return messageData.type === "pong"; } return false; } /** * 安全解析JSON消息 * @param {string} messageStr - 消息字符串 * @returns {Object|null} 解析后的对象或null */ static safeParseJSON(messageStr) { try { return JSON.parse(messageStr); } catch (error) { console.warn("JSON解析失败:", messageStr); return null; } } /** * 创建打字机消息对象 * @param {string} content - 消息内容 * @param {boolean} isComplete - 是否完成 * @param {string} type - 消息类型 * @returns {Object} 消息对象 */ static createTypewriterMessage( content, isComplete = false, type = "typewriter" ) { return { type, content, isComplete, timestamp: Date.now(), }; } /** * 创建加载消息对象 * @param {string} content - 加载内容 * @returns {Object} 加载消息对象 */ static createLoadingMessage(content = "加载中...") { return { type: "loading", content, timestamp: Date.now(), }; } /** * 创建错误消息对象 * @param {string} error - 错误信息 * @returns {Object} 错误消息对象 */ static createErrorMessage(error) { return { type: "error", content: error.message || error || "未知错误", timestamp: Date.now(), }; } } /** * 定时器管理工具类 * 提供定时器的统一管理 */ export class TimerUtils { /** * 安全清除定时器 * @param {number|null} timerId - 定时器ID * @param {string} type - 定时器类型 'timeout' | 'interval' * @returns {null} 返回null便于重置变量 */ static safeClear(timerId, type = "timeout") { if (timerId) { if (type === "interval") { clearInterval(timerId); } else { clearTimeout(timerId); } } return null; } /** * 清除定时器(别名方法) * @param {number|null} timerId - 定时器ID * @param {string} type - 定时器类型 'timeout' | 'interval' * @returns {null} 返回null便于重置变量 */ static clearTimer(timerId, type = "timeout") { return this.safeClear(timerId, type); } /** * 创建可取消的延时执行 * @param {Function} callback - 回调函数 * @param {number} delay - 延时时间 * @returns {Object} 包含cancel方法的对象 */ static createCancelableTimeout(callback, delay) { let timerId = setTimeout(callback, delay); return { cancel() { if (timerId) { clearTimeout(timerId); timerId = null; } }, isActive() { return timerId !== null; }, }; } /** * 创建可取消的定时执行 * @param {Function} callback - 回调函数 * @param {number} interval - 间隔时间 * @returns {Object} 包含cancel方法的对象 */ static createCancelableInterval(callback, interval) { let timerId = setInterval(callback, interval); return { cancel() { if (timerId) { clearInterval(timerId); timerId = null; } }, isActive() { return timerId !== null; }, }; } } // 默认导出所有工具类 export default { TypewriterUtils, IdUtils, CallbackUtils, MessageUtils, TimerUtils, };