60ad9a04cd
竞猜功能:发起竞猜、下注、关闭、开奖、奖池分配 黑名单功能:标记游戏、按原因/严重程度筛选、详情展开 修复:双重结算、TOCTOU竞态、订阅泄漏、选项选择兼容性 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
58 lines
1.6 KiB
TypeScript
58 lines
1.6 KiB
TypeScript
import { pb } from './pocketbase'
|
|
import type { BlacklistEntry } from '@/types'
|
|
|
|
export async function createBlacklistEntry(data: {
|
|
group: string
|
|
game?: string
|
|
gameName: string
|
|
reason: string
|
|
description: string
|
|
severity: string
|
|
}): Promise<BlacklistEntry> {
|
|
const user = pb.authStore.model
|
|
if (!user) throw new Error('未登录')
|
|
|
|
const payload: Record<string, any> = {
|
|
group: data.group,
|
|
reporter: user.id,
|
|
gameName: data.gameName,
|
|
reason: data.reason,
|
|
description: data.description,
|
|
severity: data.severity,
|
|
}
|
|
if (data.game) payload.game = data.game
|
|
|
|
const record = await pb.collection('game_blacklist').create(payload)
|
|
return record as unknown as BlacklistEntry
|
|
}
|
|
|
|
export async function listBlacklist(
|
|
groupId: string,
|
|
options?: { reason?: string; severity?: string }
|
|
): Promise<BlacklistEntry[]> {
|
|
let filter = `group="${groupId}"`
|
|
if (options?.reason) filter += ` && reason="${options.reason}"`
|
|
if (options?.severity) filter += ` && severity="${options.severity}"`
|
|
|
|
const result = await pb.collection('game_blacklist').getFullList({
|
|
filter,
|
|
sort: '-created',
|
|
expand: 'reporter,game',
|
|
$autoCancel: false,
|
|
})
|
|
return result as unknown as BlacklistEntry[]
|
|
}
|
|
|
|
export async function deleteBlacklistEntry(entryId: string): Promise<void> {
|
|
await pb.collection('game_blacklist').delete(entryId)
|
|
}
|
|
|
|
export async function subscribeBlacklist(
|
|
groupId: string,
|
|
callback: (data: any) => void
|
|
): Promise<() => void> {
|
|
return pb.collection('game_blacklist').subscribe('*', (data) => {
|
|
if (data.record?.group === groupId) callback(data)
|
|
})
|
|
}
|