feat: 添加Map和Set的polyfill以增强数据结构支持
This commit is contained in:
parent
be136e8c13
commit
0d315f4bd7
@ -3,6 +3,8 @@ import { LarkEvent } from "@egg/lark-msg-tool"
|
|||||||
import { Lark } from "@egg/net-tool"
|
import { Lark } from "@egg/net-tool"
|
||||||
|
|
||||||
import { Context } from "../../types"
|
import { Context } from "../../types"
|
||||||
|
import MapPolyfill from "../../utils/polyfill/map"
|
||||||
|
import SetPolyfill from "../../utils/polyfill/set"
|
||||||
|
|
||||||
interface Message {
|
interface Message {
|
||||||
user: string
|
user: string
|
||||||
@ -63,7 +65,7 @@ const getChatHistory = async (
|
|||||||
}
|
}
|
||||||
): Promise<{
|
): Promise<{
|
||||||
messages: Message[]
|
messages: Message[]
|
||||||
mentions: Map<string, string>
|
mentions: MapPolyfill<string, string>
|
||||||
}> => {
|
}> => {
|
||||||
// 获取服务器的时区偏移量(以分钟为单位)
|
// 获取服务器的时区偏移量(以分钟为单位)
|
||||||
const serverTimezoneOffset = new Date().getTimezoneOffset()
|
const serverTimezoneOffset = new Date().getTimezoneOffset()
|
||||||
@ -89,10 +91,10 @@ const getChatHistory = async (
|
|||||||
if (!chatHistory?.length)
|
if (!chatHistory?.length)
|
||||||
return {
|
return {
|
||||||
messages: [],
|
messages: [],
|
||||||
mentions: new Map(),
|
mentions: new MapPolyfill(),
|
||||||
}
|
}
|
||||||
|
|
||||||
const targetUsersSet = new Set(
|
const targetUsersSet = new SetPolyfill(
|
||||||
targetUsers
|
targetUsers
|
||||||
?.filter?.((user) => user.id.user_id)
|
?.filter?.((user) => user.id.user_id)
|
||||||
?.map?.((user) => user.id.open_id) ?? []
|
?.map?.((user) => user.id.open_id) ?? []
|
||||||
@ -100,8 +102,8 @@ const getChatHistory = async (
|
|||||||
|
|
||||||
// 清洗数据
|
// 清洗数据
|
||||||
// 取出所有的被AT的人,以及发送者
|
// 取出所有的被AT的人,以及发送者
|
||||||
const mentions: Map<string, string> = new Map()
|
const mentions: MapPolyfill<string, string> = new MapPolyfill()
|
||||||
const senders: Set<string> = new Set()
|
const senders: SetPolyfill<string> = new SetPolyfill()
|
||||||
// 先把提问者加进去
|
// 先把提问者加进去
|
||||||
if (senderOpenId) senders.add(senderOpenId)
|
if (senderOpenId) senders.add(senderOpenId)
|
||||||
// 过滤出文本和post消息
|
// 过滤出文本和post消息
|
||||||
@ -159,7 +161,7 @@ const getChatHistory = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 取出没有被AT的发送者
|
// 取出没有被AT的发送者
|
||||||
const noMentionSenders = new Set(
|
const noMentionSenders = new SetPolyfill(
|
||||||
[...senders].filter((sender) => !mentions.has(sender))
|
[...senders].filter((sender) => !mentions.has(sender))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
74
utils/polyfill/map.ts
Normal file
74
utils/polyfill/map.ts
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
interface MapPolyfillInterface<K, V> {
|
||||||
|
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<K, V>) => void,
|
||||||
|
thisArg?: any
|
||||||
|
): void
|
||||||
|
readonly size: number
|
||||||
|
}
|
||||||
|
|
||||||
|
class MapPolyfill<K, V> implements MapPolyfillInterface<K, V> {
|
||||||
|
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<K, V>) => 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
|
78
utils/polyfill/set.ts
Normal file
78
utils/polyfill/set.ts
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
interface SetPolyfillInterface<T> {
|
||||||
|
add(value: T): void
|
||||||
|
delete(value: T): boolean
|
||||||
|
has(value: T): boolean
|
||||||
|
clear(): void
|
||||||
|
forEach(
|
||||||
|
callback: (value: T, value2: T, set: SetPolyfill<T>) => void,
|
||||||
|
thisArg?: any
|
||||||
|
): void
|
||||||
|
readonly size: number
|
||||||
|
}
|
||||||
|
|
||||||
|
class SetPolyfill<T> implements SetPolyfillInterface<T> {
|
||||||
|
private items: Record<string, T>
|
||||||
|
|
||||||
|
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<T>) => 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<T> {
|
||||||
|
let index = 0
|
||||||
|
const values = Object.values(this.items)
|
||||||
|
return {
|
||||||
|
next: (): IteratorResult<T> => {
|
||||||
|
if (index < values.length) {
|
||||||
|
return { value: values[index++], done: false }
|
||||||
|
} else {
|
||||||
|
return { value: undefined, done: true }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SetPolyfill
|
Loading…
x
Reference in New Issue
Block a user