Compare commits

..

No commits in common. "48f915a54956ca162e99ef2816c9d1b1080905ea" and "b28625906b8788cbde2a91cd64cccfa644cf7ed6" have entirely different histories.

View File

@ -3,18 +3,191 @@
* 包含打字机效果ID生成回调安全调用等通用工具函数 * 包含打字机效果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生成工具类
* 提供各种ID生成功能 * 提供各种ID生成功能
*/ */
export class IdUtils { export class IdUtils {
/** /**
* 生成消息ID * 生成消息ID
* @returns {string} 消息ID * @returns {string} 消息ID
*/ */
static generateMessageId() { static generateMessageId() {
return "mid" + new Date().getTime(); return "mid" + new Date().getTime();
} }
} }
/** /**
@ -22,35 +195,35 @@ export class IdUtils {
* 提供安全的回调函数调用机制 * 提供安全的回调函数调用机制
*/ */
export class CallbackUtils { export class CallbackUtils {
/** /**
* 安全调用回调函数 * 安全调用回调函数
* @param {Object} callbacks - 回调函数对象 * @param {Object} callbacks - 回调函数对象
* @param {string} callbackName - 回调函数名称 * @param {string} callbackName - 回调函数名称
* @param {...any} args - 传递给回调函数的参数 * @param {...any} args - 传递给回调函数的参数
*/ */
static safeCall(callbacks, callbackName, ...args) { static safeCall(callbacks, callbackName, ...args) {
if (callbacks && typeof callbacks[callbackName] === "function") { if (callbacks && typeof callbacks[callbackName] === "function") {
try { try {
callbacks[callbackName](...args); callbacks[callbackName](...args);
} catch (error) { } catch (error) {
console.error(`回调函数 ${callbackName} 执行出错:`, error); console.error(`回调函数 ${callbackName} 执行出错:`, error);
} }
} else { } else {
console.warn(`回调函数 ${callbackName} 不可用`); console.warn(`回调函数 ${callbackName} 不可用`);
}
} }
}
/** /**
* 批量安全调用回调函数 * 批量安全调用回调函数
* @param {Object} callbacks - 回调函数对象 * @param {Object} callbacks - 回调函数对象
* @param {Array} callbackConfigs - 回调配置数组 [{name, args}, ...] * @param {Array} callbackConfigs - 回调配置数组 [{name, args}, ...]
*/ */
static safeBatchCall(callbacks, callbackConfigs) { static safeBatchCall(callbacks, callbackConfigs) {
callbackConfigs.forEach((config) => { callbackConfigs.forEach((config) => {
const { name, args = [] } = config; const { name, args = [] } = config;
this.safeCall(callbacks, name, ...args); this.safeCall(callbacks, name, ...args);
}); });
} }
} }
/** /**
@ -58,116 +231,117 @@ export class CallbackUtils {
* 提供消息相关的工具函数 * 提供消息相关的工具函数
*/ */
export class MessageUtils { export class MessageUtils {
/** /**
* 验证消息格式 * 验证消息格式
* @param {any} message - 消息对象 * @param {any} message - 消息对象
* @returns {boolean} 是否为有效消息格式 * @returns {boolean} 是否为有效消息格式
*/ */
static validateMessage(message) { static validateMessage(message) {
return message && typeof message === "object" && message.type; 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"; /**
* 格式化消息
* @param {string} type - 消息类型
* @param {any} content - 消息内容
* @param {Object} options - 额外选项
* @returns {Object} 格式化后的消息对象
*/
static formatMessage(type, content, options = {}) {
return {
type,
content,
timestamp: Date.now(),
...options,
};
} }
return false;
}
/** /**
* 安全解析JSON消息 * 检查是否为完整消息
* @param {string} messageStr - 消息字符串 * @param {any} message - 消息对象
* @returns {Object|null} 解析后的对象或null * @returns {boolean} 是否为完整消息
*/ */
static safeParseJSON(messageStr) { static isCompleteMessage(message) {
try { return message && message.isComplete === true;
return JSON.parse(messageStr);
} catch (error) {
console.warn("JSON解析失败:", messageStr);
return null;
} }
}
/** /**
* 创建打字机消息对象 * 检查消息是否为心跳响应
* @param {string} content - 消息内容 * @param {any} messageData - 消息数据
* @param {boolean} isComplete - 是否完成 * @returns {boolean} 是否为心跳响应
* @param {string} type - 消息类型 */
* @returns {Object} 消息对象 static isPongMessage(messageData) {
*/ if (typeof messageData === "string") {
static createTypewriterMessage( return (
content, messageData === "pong" ||
isComplete = false, messageData.toLowerCase().includes("pong")
type = "typewriter" );
) { }
return { if (typeof messageData === "object" && messageData !== null) {
type, return messageData.type === "pong";
content, }
isComplete, return false;
timestamp: Date.now(), }
};
}
/** /**
* 创建加载消息对象 * 安全解析JSON消息
* @param {string} content - 加载内容 * @param {string} messageStr - 消息字符串
* @returns {Object} 加载消息对象 * @returns {Object|null} 解析后的对象或null
*/ */
static createLoadingMessage(content = "加载中...") { static safeParseJSON(messageStr) {
return { try {
type: "loading", return JSON.parse(messageStr);
content, } catch (error) {
timestamp: Date.now(), console.warn("JSON解析失败:", messageStr);
}; return null;
} }
}
/** /**
* 创建错误消息对象 * 创建打字机消息对象
* @param {string} error - 错误信息 * @param {string} content - 消息内容
* @returns {Object} 错误消息对象 * @param {boolean} isComplete - 是否完成
*/ * @param {string} type - 消息类型
static createErrorMessage(error) { * @returns {Object} 消息对象
return { */
type: "error", static createTypewriterMessage(
content: error.message || error || "未知错误", content,
timestamp: Date.now(), 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(),
};
}
} }
/** /**
@ -175,80 +349,81 @@ export class MessageUtils {
* 提供定时器的统一管理 * 提供定时器的统一管理
*/ */
export class TimerUtils { export class TimerUtils {
/** /**
* 安全清除定时器 * 安全清除定时器
* @param {number|null} timerId - 定时器ID * @param {number|null} timerId - 定时器ID
* @param {string} type - 定时器类型 'timeout' | 'interval' * @param {string} type - 定时器类型 'timeout' | 'interval'
* @returns {null} 返回null便于重置变量 * @returns {null} 返回null便于重置变量
*/ */
static safeClear(timerId, type = "timeout") { static safeClear(timerId, type = "timeout") {
if (timerId) { if (timerId) {
if (type === "interval") { if (type === "interval") {
clearInterval(timerId); clearInterval(timerId);
} else { } else {
clearTimeout(timerId); clearTimeout(timerId);
} }
}
return null;
} }
return null;
}
/** /**
* 清除定时器别名方法 * 清除定时器别名方法
* @param {number|null} timerId - 定时器ID * @param {number|null} timerId - 定时器ID
* @param {string} type - 定时器类型 'timeout' | 'interval' * @param {string} type - 定时器类型 'timeout' | 'interval'
* @returns {null} 返回null便于重置变量 * @returns {null} 返回null便于重置变量
*/ */
static clearTimer(timerId, type = "timeout") { static clearTimer(timerId, type = "timeout") {
return this.safeClear(timerId, type); return this.safeClear(timerId, type);
} }
/** /**
* 创建可取消的延时执行 * 创建可取消的延时执行
* @param {Function} callback - 回调函数 * @param {Function} callback - 回调函数
* @param {number} delay - 延时时间 * @param {number} delay - 延时时间
* @returns {Object} 包含cancel方法的对象 * @returns {Object} 包含cancel方法的对象
*/ */
static createCancelableTimeout(callback, delay) { static createCancelableTimeout(callback, delay) {
let timerId = setTimeout(callback, delay); let timerId = setTimeout(callback, delay);
return { return {
cancel() { cancel() {
if (timerId) { if (timerId) {
clearTimeout(timerId); clearTimeout(timerId);
timerId = null; timerId = null;
} }
}, },
isActive() { isActive() {
return timerId !== null; return timerId !== null;
}, },
}; };
} }
/** /**
* 创建可取消的定时执行 * 创建可取消的定时执行
* @param {Function} callback - 回调函数 * @param {Function} callback - 回调函数
* @param {number} interval - 间隔时间 * @param {number} interval - 间隔时间
* @returns {Object} 包含cancel方法的对象 * @returns {Object} 包含cancel方法的对象
*/ */
static createCancelableInterval(callback, interval) { static createCancelableInterval(callback, interval) {
let timerId = setInterval(callback, interval); let timerId = setInterval(callback, interval);
return { return {
cancel() { cancel() {
if (timerId) { if (timerId) {
clearInterval(timerId); clearInterval(timerId);
timerId = null; timerId = null;
} }
}, },
isActive() { isActive() {
return timerId !== null; return timerId !== null;
}, },
}; };
} }
} }
// 默认导出所有工具类 // 默认导出所有工具类
export default { export default {
IdUtils, TypewriterUtils,
CallbackUtils, IdUtils,
MessageUtils, CallbackUtils,
TimerUtils, MessageUtils,
TimerUtils,
}; };