Merge branch 'fix-812' of https://git.brother7.cn/zoujing/YGChatCS
This commit is contained in:
583
utils/index.js
583
utils/index.js
@@ -3,191 +3,18 @@
|
|||||||
* 包含打字机效果、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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -195,35 +22,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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -231,117 +58,116 @@ 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 {string} type - 消息类型
|
||||||
* @param {any} content - 消息内容
|
* @param {any} content - 消息内容
|
||||||
* @param {Object} options - 额外选项
|
* @param {Object} options - 额外选项
|
||||||
* @returns {Object} 格式化后的消息对象
|
* @returns {Object} 格式化后的消息对象
|
||||||
*/
|
*/
|
||||||
static formatMessage(type, content, options = {}) {
|
static formatMessage(type, content, options = {}) {
|
||||||
return {
|
return {
|
||||||
type,
|
type,
|
||||||
content,
|
content,
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
...options,
|
...options,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查是否为完整消息
|
* 检查是否为完整消息
|
||||||
* @param {any} message - 消息对象
|
* @param {any} message - 消息对象
|
||||||
* @returns {boolean} 是否为完整消息
|
* @returns {boolean} 是否为完整消息
|
||||||
*/
|
*/
|
||||||
static isCompleteMessage(message) {
|
static isCompleteMessage(message) {
|
||||||
return message && message.isComplete === true;
|
return message && message.isComplete === true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查消息是否为心跳响应
|
* 检查消息是否为心跳响应
|
||||||
* @param {any} messageData - 消息数据
|
* @param {any} messageData - 消息数据
|
||||||
* @returns {boolean} 是否为心跳响应
|
* @returns {boolean} 是否为心跳响应
|
||||||
*/
|
*/
|
||||||
static isPongMessage(messageData) {
|
static isPongMessage(messageData) {
|
||||||
if (typeof messageData === "string") {
|
if (typeof messageData === "string") {
|
||||||
return (
|
return (
|
||||||
messageData === "pong" ||
|
messageData === "pong" || messageData.toLowerCase().includes("pong")
|
||||||
messageData.toLowerCase().includes("pong")
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
if (typeof messageData === "object" && messageData !== null) {
|
|
||||||
return messageData.type === "pong";
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
if (typeof messageData === "object" && messageData !== null) {
|
||||||
|
return messageData.type === "pong";
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 安全解析JSON消息
|
* 安全解析JSON消息
|
||||||
* @param {string} messageStr - 消息字符串
|
* @param {string} messageStr - 消息字符串
|
||||||
* @returns {Object|null} 解析后的对象或null
|
* @returns {Object|null} 解析后的对象或null
|
||||||
*/
|
*/
|
||||||
static safeParseJSON(messageStr) {
|
static safeParseJSON(messageStr) {
|
||||||
try {
|
try {
|
||||||
return JSON.parse(messageStr);
|
return JSON.parse(messageStr);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn("JSON解析失败:", messageStr);
|
console.warn("JSON解析失败:", messageStr);
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建打字机消息对象
|
* 创建打字机消息对象
|
||||||
* @param {string} content - 消息内容
|
* @param {string} content - 消息内容
|
||||||
* @param {boolean} isComplete - 是否完成
|
* @param {boolean} isComplete - 是否完成
|
||||||
* @param {string} type - 消息类型
|
* @param {string} type - 消息类型
|
||||||
* @returns {Object} 消息对象
|
* @returns {Object} 消息对象
|
||||||
*/
|
*/
|
||||||
static createTypewriterMessage(
|
static createTypewriterMessage(
|
||||||
content,
|
content,
|
||||||
isComplete = false,
|
isComplete = false,
|
||||||
type = "typewriter"
|
type = "typewriter"
|
||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
type,
|
type,
|
||||||
content,
|
content,
|
||||||
isComplete,
|
isComplete,
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建加载消息对象
|
* 创建加载消息对象
|
||||||
* @param {string} content - 加载内容
|
* @param {string} content - 加载内容
|
||||||
* @returns {Object} 加载消息对象
|
* @returns {Object} 加载消息对象
|
||||||
*/
|
*/
|
||||||
static createLoadingMessage(content = "加载中...") {
|
static createLoadingMessage(content = "加载中...") {
|
||||||
return {
|
return {
|
||||||
type: "loading",
|
type: "loading",
|
||||||
content,
|
content,
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建错误消息对象
|
* 创建错误消息对象
|
||||||
* @param {string} error - 错误信息
|
* @param {string} error - 错误信息
|
||||||
* @returns {Object} 错误消息对象
|
* @returns {Object} 错误消息对象
|
||||||
*/
|
*/
|
||||||
static createErrorMessage(error) {
|
static createErrorMessage(error) {
|
||||||
return {
|
return {
|
||||||
type: "error",
|
type: "error",
|
||||||
content: error.message || error || "未知错误",
|
content: error.message || error || "未知错误",
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -349,81 +175,80 @@ 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 (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) {
|
if (timerId) {
|
||||||
if (type === "interval") {
|
clearTimeout(timerId);
|
||||||
clearInterval(timerId);
|
timerId = null;
|
||||||
} else {
|
|
||||||
clearTimeout(timerId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null;
|
},
|
||||||
}
|
isActive() {
|
||||||
|
return timerId !== null;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 清除定时器(别名方法)
|
* 创建可取消的定时执行
|
||||||
* @param {number|null} timerId - 定时器ID
|
* @param {Function} callback - 回调函数
|
||||||
* @param {string} type - 定时器类型 'timeout' | 'interval'
|
* @param {number} interval - 间隔时间
|
||||||
* @returns {null} 返回null便于重置变量
|
* @returns {Object} 包含cancel方法的对象
|
||||||
*/
|
*/
|
||||||
static clearTimer(timerId, type = "timeout") {
|
static createCancelableInterval(callback, interval) {
|
||||||
return this.safeClear(timerId, type);
|
let timerId = setInterval(callback, interval);
|
||||||
}
|
return {
|
||||||
|
cancel() {
|
||||||
/**
|
if (timerId) {
|
||||||
* 创建可取消的延时执行
|
clearInterval(timerId);
|
||||||
* @param {Function} callback - 回调函数
|
timerId = null;
|
||||||
* @param {number} delay - 延时时间
|
}
|
||||||
* @returns {Object} 包含cancel方法的对象
|
},
|
||||||
*/
|
isActive() {
|
||||||
static createCancelableTimeout(callback, delay) {
|
return timerId !== null;
|
||||||
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 {
|
export default {
|
||||||
TypewriterUtils,
|
IdUtils,
|
||||||
IdUtils,
|
CallbackUtils,
|
||||||
CallbackUtils,
|
MessageUtils,
|
||||||
MessageUtils,
|
TimerUtils,
|
||||||
TimerUtils,
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user