chore: restructure project and add i18n support
- Reorganize project structure with new electron and shared directories - Add comprehensive i18n support with Chinese, English, and Japanese locales - Update build configurations and TypeScript paths for new structure - Add various UI components including chat interface and task management - Include Windows release binaries and localization files - Update dependencies and fix import paths throughout the codebase
This commit is contained in:
331
src/lib/index.ts
Normal file
331
src/lib/index.ts
Normal file
@@ -0,0 +1,331 @@
|
||||
/**
|
||||
* 工具函数集合
|
||||
* 包含打字机效果、ID生成、回调安全调用等通用工具函数
|
||||
*/
|
||||
|
||||
/* =======================
|
||||
* ID 生成工具
|
||||
* ======================= */
|
||||
export class IdUtils {
|
||||
/**
|
||||
* 生成消息 ID
|
||||
*/
|
||||
static generateMessageId(): string {
|
||||
const timestamp = Date.now()
|
||||
const chars = 'abcdefghijklmnopqrstuvwxyz'
|
||||
const randomStr = Array.from({ length: 4 }, () =>
|
||||
chars.charAt(Math.floor(Math.random() * chars.length))
|
||||
).join('')
|
||||
return `mid${randomStr}${timestamp}`
|
||||
}
|
||||
}
|
||||
|
||||
/* =======================
|
||||
* 回调安全调用工具
|
||||
* ======================= */
|
||||
|
||||
export type CallbackMap = Record<string, (...args: any[]) => any>
|
||||
|
||||
export interface BatchCallbackConfig {
|
||||
name: string
|
||||
args?: any[]
|
||||
}
|
||||
|
||||
export class CallbackUtils {
|
||||
/**
|
||||
* 安全调用回调函数
|
||||
*/
|
||||
static safeCall(
|
||||
callbacks: CallbackMap | null | undefined,
|
||||
callbackName: string,
|
||||
...args: any[]
|
||||
): void {
|
||||
const cb = callbacks?.[callbackName]
|
||||
if (typeof cb === 'function') {
|
||||
try {
|
||||
cb(...args)
|
||||
} catch (error) {
|
||||
console.error(`回调函数 ${callbackName} 执行出错:`, error)
|
||||
}
|
||||
} else {
|
||||
console.warn(`回调函数 ${callbackName} 不可用`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量安全调用回调函数
|
||||
*/
|
||||
static safeBatchCall(
|
||||
callbacks: CallbackMap | null | undefined,
|
||||
callbackConfigs: BatchCallbackConfig[]
|
||||
): void {
|
||||
callbackConfigs.forEach(({ name, args = [] }) => {
|
||||
this.safeCall(callbacks, name, ...args)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/* =======================
|
||||
* 消息处理工具
|
||||
* ======================= */
|
||||
|
||||
export interface BaseMessage {
|
||||
type: string
|
||||
content?: any
|
||||
timestamp: number
|
||||
isComplete?: boolean
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
export class MessageUtils {
|
||||
/**
|
||||
* 验证消息格式
|
||||
*/
|
||||
static validateMessage(message: unknown): message is BaseMessage {
|
||||
return (
|
||||
typeof message === 'object' &&
|
||||
message !== null &&
|
||||
'type' in message
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化消息
|
||||
*/
|
||||
static formatMessage<T = any>(
|
||||
type: string,
|
||||
content: T,
|
||||
options: Partial<BaseMessage> = {}
|
||||
): BaseMessage {
|
||||
return {
|
||||
type,
|
||||
content,
|
||||
timestamp: Date.now(),
|
||||
...options,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为完整消息
|
||||
*/
|
||||
static isCompleteMessage(message: Partial<BaseMessage> | null | undefined): boolean {
|
||||
return message?.isComplete === true
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为心跳 pong
|
||||
*/
|
||||
static isPongMessage(messageData: unknown): boolean {
|
||||
if (typeof messageData === 'string') {
|
||||
return messageData === 'pong' || messageData.toLowerCase().includes('pong')
|
||||
}
|
||||
if (typeof messageData === 'object' && messageData !== null) {
|
||||
return (messageData as any).type === 'pong'
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全解析 JSON
|
||||
*/
|
||||
static safeParseJSON<T = any>(messageStr: string): T | null {
|
||||
try {
|
||||
return JSON.parse(messageStr) as T
|
||||
} catch {
|
||||
console.warn('JSON 解析失败:', messageStr)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建打字机消息
|
||||
*/
|
||||
static createTypewriterMessage(
|
||||
content: string,
|
||||
isComplete = false,
|
||||
type = 'typewriter'
|
||||
): BaseMessage {
|
||||
return {
|
||||
type,
|
||||
content,
|
||||
isComplete,
|
||||
timestamp: Date.now(),
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建加载消息
|
||||
*/
|
||||
static createLoadingMessage(content = '加载中...'): BaseMessage {
|
||||
return {
|
||||
type: 'loading',
|
||||
content,
|
||||
timestamp: Date.now(),
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建错误消息
|
||||
*/
|
||||
static createErrorMessage(error: unknown): BaseMessage {
|
||||
return {
|
||||
type: 'error',
|
||||
content:
|
||||
error instanceof Error ? error.message : String(error ?? '未知错误'),
|
||||
timestamp: Date.now(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* =======================
|
||||
* 定时器工具
|
||||
* ======================= */
|
||||
|
||||
export type TimerType = 'timeout' | 'interval'
|
||||
|
||||
export interface CancelableTimer {
|
||||
cancel(): void
|
||||
isActive(): boolean
|
||||
}
|
||||
|
||||
export class TimerUtils {
|
||||
static safeClear(
|
||||
timerId: number | null,
|
||||
type: TimerType = 'timeout'
|
||||
): null {
|
||||
if (timerId !== null) {
|
||||
type === 'interval' ? clearInterval(timerId) : clearTimeout(timerId)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
static clearTimer(
|
||||
timerId: number | null,
|
||||
type: TimerType = 'timeout'
|
||||
): null {
|
||||
return this.safeClear(timerId, type)
|
||||
}
|
||||
|
||||
static createCancelableTimeout(
|
||||
callback: () => void,
|
||||
delay: number
|
||||
): CancelableTimer {
|
||||
let timerId: number | null = window.setTimeout(callback, delay)
|
||||
return {
|
||||
cancel() {
|
||||
if (timerId !== null) {
|
||||
clearTimeout(timerId)
|
||||
timerId = null
|
||||
}
|
||||
},
|
||||
isActive() {
|
||||
return timerId !== null
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
static createCancelableInterval(
|
||||
callback: () => void,
|
||||
interval: number
|
||||
): CancelableTimer {
|
||||
let timerId: number | null = window.setInterval(callback, interval)
|
||||
return {
|
||||
cancel() {
|
||||
if (timerId !== null) {
|
||||
clearInterval(timerId)
|
||||
timerId = null
|
||||
}
|
||||
},
|
||||
isActive() {
|
||||
return timerId !== null
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* =======================
|
||||
* 防抖工具
|
||||
* ======================= */
|
||||
|
||||
export class DebounceUtils {
|
||||
static createDebounce<T extends (...args: any[]) => void>(
|
||||
func: T,
|
||||
delay: number
|
||||
): (...args: Parameters<T>) => void {
|
||||
let timerId: number | null = null
|
||||
|
||||
return function (this: unknown, ...args: Parameters<T>) {
|
||||
if (timerId !== null) {
|
||||
clearTimeout(timerId)
|
||||
}
|
||||
timerId = window.setTimeout(() => func.apply(this, args), delay)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* =======================
|
||||
* 节流工具
|
||||
* ======================= */
|
||||
|
||||
export class ThrottleUtils {
|
||||
static createThrottle<T extends (...args: any[]) => void>(
|
||||
func: T,
|
||||
delay: number
|
||||
): (...args: Parameters<T>) => void {
|
||||
let prev = Date.now()
|
||||
|
||||
return function (this: unknown, ...args: Parameters<T>) {
|
||||
const now = Date.now()
|
||||
if (now - prev >= delay) {
|
||||
func.apply(this, args)
|
||||
prev = now
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* =======================
|
||||
* 日期工具
|
||||
* ======================= */
|
||||
|
||||
export class DateUtils {
|
||||
static formatDate(
|
||||
date: Date = new Date(),
|
||||
format: string = 'yyyy-MM-dd'
|
||||
): string {
|
||||
const year = date.getFullYear()
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(date.getDate()).padStart(2, '0')
|
||||
|
||||
return format
|
||||
.replace('yyyy', String(year))
|
||||
.replace('MM', month)
|
||||
.replace('dd', day)
|
||||
}
|
||||
}
|
||||
|
||||
/* =======================
|
||||
* 手机号校验
|
||||
* ======================= */
|
||||
|
||||
export class PhoneUtils {
|
||||
static validatePhone(phone: string): boolean {
|
||||
const phoneRegex = /^1[3-9]\d{9}$/
|
||||
return phoneRegex.test(phone)
|
||||
}
|
||||
}
|
||||
|
||||
/* =======================
|
||||
* 默认导出
|
||||
* ======================= */
|
||||
|
||||
export default {
|
||||
IdUtils,
|
||||
CallbackUtils,
|
||||
MessageUtils,
|
||||
TimerUtils,
|
||||
DateUtils,
|
||||
DebounceUtils,
|
||||
ThrottleUtils,
|
||||
PhoneUtils,
|
||||
}
|
||||
Reference in New Issue
Block a user