This commit is contained in:
2025-12-01 02:19:44 +08:00
parent 84775dd878
commit a51a366f00
21 changed files with 2628 additions and 229 deletions

View File

@@ -1,23 +1,25 @@
import { query } from './query.ts';
import { createMessage } from '../pages/kv-message.ts';
import { WX_MP_APP_ID } from '../pages/kv-login.ts';
import { emit } from './mitt.ts';
export const message = createMessage();
type LoginOpts = {
loginMethod: 'password' | 'phone' | 'wechat' | 'wechat-mp' | 'wechat-mp-ticket',
data: any,
el: HTMLElement
}
/**
* 登录成功后重定向到首页
*/
export const redirectHome = () => {
console.log('重定向到首页')
const href = window.location.href;
const url = new URL(href);
const redirect = url.searchParams.get('redirect');
if (redirect) {
const href = decodeURIComponent(redirect);
window.open(href, '_self');
} else {
window.open('/root/home', '_self');
}
emit({ type: 'login-success', data: {} });
}
export const loginHandle = async (opts: LoginOpts) => {
const { loginMethod, data, el } = opts

View File

@@ -0,0 +1,134 @@
export interface EventData<T = any> {
type: string;
data: T;
}
export type EventHandler<T = any> = (event: EventData<T>) => void;
export class EventEmitter {
private events: Map<string, Set<EventHandler>> = new Map();
/**
* 监听事件
* @param type 事件类型
* @param handler 事件处理函数
*/
on<T = any>(type: string, handler: EventHandler<T>): void {
if (!this.events.has(type)) {
this.events.set(type, new Set());
}
this.events.get(type)!.add(handler);
}
/**
* 移除事件监听器
* @param type 事件类型
* @param handler 事件处理函数 (可选,如果不提供则移除该类型的所有监听器)
*/
off<T = any>(type: string, handler?: EventHandler<T>): void {
if (!this.events.has(type)) {
return;
}
if (handler) {
this.events.get(type)!.delete(handler);
// 如果该类型没有监听器了,删除该类型
if (this.events.get(type)!.size === 0) {
this.events.delete(type);
}
} else {
// 移除该类型的所有监听器
this.events.delete(type);
}
}
/**
* 触发事件
* @param event 事件对象,包含 type 和 data
*/
emit<T = any>(event: EventData<T>): void {
const { type } = event;
if (!this.events.has(type)) {
return;
}
const handlers = this.events.get(type)!;
handlers.forEach(handler => {
try {
handler(event);
} catch (error) {
console.error(`Error in event handler for type "${type}":`, error);
}
});
}
/**
* 触发事件简化版本直接传递type和data
* @param type 事件类型
* @param data 事件数据
*/
emitSimple<T = any>(type: string, data: T): void {
this.emit({ type, data });
}
/**
* 清空所有事件监听器
*/
clear(): void {
this.events.clear();
}
/**
* 获取指定类型的监听器数量
* @param type 事件类型
* @returns 监听器数量
*/
listenerCount(type: string): number {
return this.events.get(type)?.size || 0;
}
/**
* 获取所有事件类型
* @returns 事件类型数组
*/
eventNames(): string[] {
return Array.from(this.events.keys());
}
/**
* 检查是否有指定类型的监听器
* @param type 事件类型
* @returns 是否有监听器
*/
hasListeners(type: string): boolean {
return this.events.has(type) && this.events.get(type)!.size > 0;
}
/**
* 只监听一次事件
* @param type 事件类型
* @param handler 事件处理函数
*/
once<T = any>(type: string, handler: EventHandler<T>): void {
const onceHandler: EventHandler<T> = (event) => {
handler(event);
this.off(type, onceHandler);
};
this.on(type, onceHandler);
}
}
// 创建默认的事件发射器实例
export const eventEmitter = new EventEmitter();
// 导出便捷方法
export const on = <T = any>(type: string, handler: EventHandler<T>) => eventEmitter.on(type, handler);
export const off = <T = any>(type: string, handler?: EventHandler<T>) => eventEmitter.off(type, handler);
export const emit = <T = any>(event: EventData<T>) => eventEmitter.emit(event);
export const emitSimple = <T = any>(type: string, data: T) => eventEmitter.emitSimple(type, data);
export const clear = () => eventEmitter.clear();
export const once = <T = any>(type: string, handler: EventHandler<T>) => eventEmitter.once(type, handler);
// 默认导出
export default eventEmitter;