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>
This commit is contained in:
congsh
2026-04-17 20:23:39 +08:00
parent 0bcf39bb4b
commit 802712c662
17 changed files with 394 additions and 180 deletions
@@ -19,6 +19,14 @@ const memberDetails = computed(() => {
.filter((m): m is NonNullable<typeof m> => Boolean(m))
})
async function startGame() {
try {
await teamStore.updateStatus('playing')
} catch {
// ignore
}
}
async function endGame() {
try {
await ElMessageBox.confirm(
@@ -67,9 +75,15 @@ async function endGame() {
</div>
</div>
<button class="end-game-btn" @click="endGame">
<button v-if="session.status === 'recruiting'" class="start-game-btn" @click="startGame">
开始游戏
</button>
<button v-else-if="session.status === 'playing'" class="end-game-btn" @click="endGame">
游戏结束
</button>
<button v-if="session.status === 'recruiting'" class="dissolve-btn" @click="endGame">
解散小组
</button>
</div>
<div v-else class="no-session">
@@ -177,6 +191,43 @@ async function endGame() {
color: var(--gg-text);
}
.start-game-btn {
width: 100%;
padding: 12px;
margin-bottom: 8px;
border: none;
border-radius: var(--gg-radius-sm);
background: var(--gg-gradient-green);
color: white;
font-size: 14px;
font-weight: 600;
cursor: pointer;
transition: opacity 0.2s, box-shadow 0.2s;
}
.start-game-btn:hover {
opacity: 0.9;
box-shadow: 0 4px 16px rgba(5, 150, 105, 0.3);
}
.dissolve-btn {
width: 100%;
padding: 10px;
border: 1px solid var(--gg-border);
border-radius: var(--gg-radius-sm);
background: transparent;
color: var(--gg-text-secondary);
font-size: 13px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
}
.dissolve-btn:hover {
border-color: var(--gg-danger);
color: var(--gg-danger);
}
.end-game-btn {
width: 100%;
padding: 12px;