diff --git a/controller/groupAgent/chatHistory.ts b/controller/groupAgent/chatHistory.ts index a1c3e9b..d32a284 100644 --- a/controller/groupAgent/chatHistory.ts +++ b/controller/groupAgent/chatHistory.ts @@ -3,6 +3,8 @@ import { LarkEvent } from "@egg/lark-msg-tool" import { Lark } from "@egg/net-tool" import { Context } from "../../types" +import MapPolyfill from "../../utils/polyfill/map" +import SetPolyfill from "../../utils/polyfill/set" interface Message { user: string @@ -63,7 +65,7 @@ const getChatHistory = async ( } ): Promise<{ messages: Message[] - mentions: Map + mentions: MapPolyfill }> => { // 获取服务器的时区偏移量(以分钟为单位) const serverTimezoneOffset = new Date().getTimezoneOffset() @@ -89,10 +91,10 @@ const getChatHistory = async ( if (!chatHistory?.length) return { messages: [], - mentions: new Map(), + mentions: new MapPolyfill(), } - const targetUsersSet = new Set( + const targetUsersSet = new SetPolyfill( targetUsers ?.filter?.((user) => user.id.user_id) ?.map?.((user) => user.id.open_id) ?? [] @@ -100,8 +102,8 @@ const getChatHistory = async ( // 清洗数据 // 取出所有的被AT的人,以及发送者 - const mentions: Map = new Map() - const senders: Set = new Set() + const mentions: MapPolyfill = new MapPolyfill() + const senders: SetPolyfill = new SetPolyfill() // 先把提问者加进去 if (senderOpenId) senders.add(senderOpenId) // 过滤出文本和post消息 @@ -159,7 +161,7 @@ const getChatHistory = async ( } // 取出没有被AT的发送者 - const noMentionSenders = new Set( + const noMentionSenders = new SetPolyfill( [...senders].filter((sender) => !mentions.has(sender)) ) diff --git a/utils/polyfill/map.ts b/utils/polyfill/map.ts new file mode 100644 index 0000000..01c4d2d --- /dev/null +++ b/utils/polyfill/map.ts @@ -0,0 +1,74 @@ +interface MapPolyfillInterface { + set(key: K, value: V): void + get(key: K): V | undefined + delete(key: K): boolean + has(key: K): boolean + clear(): void + forEach( + callback: (value: V, key: K, map: MapPolyfill) => void, + thisArg?: any + ): void + readonly size: number +} + +class MapPolyfill implements MapPolyfillInterface { + private keys: K[] + private values: V[] + + constructor() { + this.keys = [] + this.values = [] + } + + set(key: K, value: V): void { + const index = this.keys.indexOf(key) + if (index === -1) { + this.keys.push(key) + this.values.push(value) + } else { + this.values[index] = value + } + } + + get(key: K): V | undefined { + const index = this.keys.indexOf(key) + if (index === -1) { + return undefined + } + return this.values[index] + } + + delete(key: K): boolean { + const index = this.keys.indexOf(key) + if (index === -1) { + return false + } + this.keys.splice(index, 1) + this.values.splice(index, 1) + return true + } + + has(key: K): boolean { + return this.keys.indexOf(key) !== -1 + } + + clear(): void { + this.keys = [] + this.values = [] + } + + forEach( + callback: (value: V, key: K, map: MapPolyfill) => void, + thisArg?: any + ): void { + for (let i = 0; i < this.keys.length; i++) { + callback.call(thisArg, this.values[i], this.keys[i], this) + } + } + + get size(): number { + return this.keys.length + } +} + +export default MapPolyfill diff --git a/utils/polyfill/set.ts b/utils/polyfill/set.ts new file mode 100644 index 0000000..dc113cf --- /dev/null +++ b/utils/polyfill/set.ts @@ -0,0 +1,78 @@ +interface SetPolyfillInterface { + add(value: T): void + delete(value: T): boolean + has(value: T): boolean + clear(): void + forEach( + callback: (value: T, value2: T, set: SetPolyfill) => void, + thisArg?: any + ): void + readonly size: number +} + +class SetPolyfill implements SetPolyfillInterface { + private items: Record + + constructor(initialValues?: T[]) { + this.items = {} + if (initialValues) { + for (const value of initialValues) { + this.add(value) + } + } + } + + add(value: T): void { + const key = JSON.stringify(value) + this.items[key] = value + } + + delete(value: T): boolean { + const key = JSON.stringify(value) + if (this.has(value)) { + delete this.items[key] + return true + } + return false + } + + has(value: T): boolean { + const key = JSON.stringify(value) + return Object.prototype.hasOwnProperty.call(this.items, key) + } + + clear(): void { + this.items = {} + } + + forEach( + callback: (value: T, value2: T, set: SetPolyfill) => void, + thisArg?: any + ): void { + for (const key in this.items) { + if (Object.prototype.hasOwnProperty.call(this.items, key)) { + callback.call(thisArg, this.items[key], this.items[key], this) + } + } + } + + get size(): number { + return Object.keys(this.items).length + } + + [Symbol.iterator](): Iterator { + let index = 0 + const values = Object.values(this.items) + return { + next: (): IteratorResult => { + if (index < values.length) { + return { value: values[index++], done: false } + } else { + return { value: undefined, done: true } + } + }, + } + } +} + +export default SetPolyfill