Files
gamegroup2/frontend/src/api/invitations.ts
T

149 lines
4.2 KiB
TypeScript
Raw Normal View History

// 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
}
2026-04-18 10:52:48 +08:00
// 接受邀请:先加入 team session,再更新邀请状态
if (response === 'accepted') {
const user = pb.authStore.model
if (!user) return
// 获取邀请详情以找到 team session
2026-04-18 10:52:48 +08:00
const invitation = await pb.collection('invitations').getOne(invitationId, {
$autoCancel: false
}) as any
const teamSessionId = invitation.teamSession
// 加入 team session
2026-04-18 10:52:48 +08:00
const session = await pb.collection('team_sessions').getOne(teamSessionId, {
$autoCancel: false
}) 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' })
// 同步更新本地 userStore
const { useUserStore } = await import('@/stores/user')
const userStore = useUserStore()
if (userStore.user) {
userStore.user.status = 'in_team'
}
}
2026-04-18 10:52:48 +08:00
// 更新邀请状态
await pb.collection('invitations').update(invitationId, updateData)
// 通知邀请发起人
try {
const invitation = await pb.collection('invitations').getOne(invitationId, {
expand: 'teamSession',
$autoCancel: false,
}) as any
const { createNotification } = await import('./notifications')
await createNotification({
user: invitation.from,
type: response === 'rejected' ? 'team_invite' : 'team_invite',
title: response === 'rejected' ? '邀请被拒绝' : '邀请已接受',
content: response === 'rejected'
? (rejectReason || '对方拒绝了组队邀请')
: '对方已接受组队邀请',
relatedId: invitation.teamSession,
relatedType: 'team',
})
} catch {
// 通知失败不影响主流程
}
}
// 订阅邀请变更
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)
}
})
}