Files
gamegroup2/frontend/src/api/invitations.ts
T
congsh 802712c662 feat: complete Phase 1 - game library, lifecycle, realtime sync
- Seed 33 popular games across 5 platforms via admin API script
- Add GameDetailDialog with game info and quick-team button
- Update GamesLibrary with game card click to open detail dialog
- Update Home hot games to open detail dialog instead of navigating
- Rewrite invitation accept: frontend auto-joins team + updates status
- Add user status reset on team dissolution (endGame)
- Add start game / dissolve buttons to TeamSessionPanel lifecycle
- Integrate realtime subscriptions in GroupView and Layout
- Add notification store realtime invitation listener
- Add placeholder images for game covers and avatars
- Remove Go hooks, add JS hooks placeholder + Docker mount

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-17 20:23:39 +08:00

117 lines
3.2 KiB
TypeScript

// src/api/invitations.ts
import pb from './pocketbase'
import type { Invitation } from '@/types'
// 发送邀请
export async function sendInvitation(data: {
to: string
teamSession: string
}) {
const user = pb.authStore.model
if (!user) throw new Error('未登录')
// 检查是否已有待处理邀请
const existing = await pb.collection('invitations').getList(1, 1, {
filter: `from="${user.id}" && to="${data.to}" && teamSession="${data.teamSession}" && status="pending"`
})
if (existing.items.length > 0) {
throw new Error('已有待处理的邀请')
}
return pb.collection('invitations').create({
...data,
from: user.id,
status: 'pending'
})
}
// 批量发送邀请
export async function sendBulkInvitations(recipients: string[], teamSessionId: string) {
const promises = recipients.map(to =>
sendInvitation({ to, teamSession: teamSessionId })
)
return Promise.allSettled(promises)
}
// 获取用户的待处理邀请
export async function getPendingInvitations(): Promise<Invitation[]> {
const user = pb.authStore.model
if (!user) return []
const result = await pb.collection('invitations').getList(1, 50, {
filter: `to="${user.id}" && status="pending"`,
sort: '-created',
expand: 'from,teamSession'
})
return result.items as unknown as Invitation[]
}
// 获取我发送的邀请
export async function getMySentInvitations(): Promise<Invitation[]> {
const user = pb.authStore.model
if (!user) return []
const result = await pb.collection('invitations').getList(1, 50, {
filter: `from="${user.id}"`,
sort: '-created',
expand: 'to,teamSession'
})
return result.items as unknown as Invitation[]
}
// 响应邀请
export async function respondInvitation(
invitationId: string,
response: 'accepted' | 'rejected',
rejectReason?: string
) {
const updateData: Record<string, unknown> = {
status: response
}
if (response === 'rejected' && rejectReason) {
updateData.rejectReason = rejectReason
}
// 更新邀请状态
await pb.collection('invitations').update(invitationId, updateData)
// 接受邀请:前端处理加入 team session + 更新用户状态
if (response === 'accepted') {
const user = pb.authStore.model
if (!user) return
// 获取邀请详情以找到 team session
const invitation = await pb.collection('invitations').getOne(invitationId) as any
const teamSessionId = invitation.teamSession
// 加入 team session
const session = await pb.collection('team_sessions').getOne(teamSessionId) as any
const members: string[] = session.members || []
if (!members.includes(user.id)) {
members.push(user.id)
await pb.collection('team_sessions').update(teamSessionId, { members })
}
// 更新用户状态为 in_team
await pb.collection('users').update(user.id, { status: 'in_team' })
}
}
// 订阅邀请变更
export function subscribeInvitations(callback: (invitation: Invitation) => void) {
const user = pb.authStore.model
if (!user) return () => {}
return pb.collection('invitations').subscribe('*', (payload) => {
const invite = payload.record as unknown as Invitation
if (invite.to === user.id || invite.from === user.id) {
callback(invite)
}
})
}