From 4b97c99e567569ff38bad05c16a83f3a551d22bb Mon Sep 17 00:00:00 2001 From: congsh Date: Fri, 17 Apr 2026 21:03:20 +0800 Subject: [PATCH] feat: add game library CRUD/import/export/favorites/comments, fix team creation - Game library: add/delete games per group, JSON/CSV import/export, favorites, star ratings & comments - Fix team session creation: add creator to members array, handle null currentGroup - Fix image loading: rename SVG files from .png to .svg extensions - Add PocketBase migrations for game_comments and game_favorites collections - Remove seed data script Co-Authored-By: Claude Opus 4.7 --- .../1776429444_created_game_comments.js | 87 ++++++ .../1776429455_created_game_favorites.js | 59 ++++ .../pb_migrations/1776429475_updated_games.js | 66 ++++ backend/scripts/seed-games.sh | 67 ----- ...{default-avatar.png => default-avatar.svg} | 0 ...e-placeholder.png => game-placeholder.svg} | 0 frontend/src/api/games.ts | 187 ++++++++---- .../src/components/game/AddGameDialog.vue | 92 ++++++ frontend/src/components/game/GameComments.vue | 108 +++++++ .../src/components/game/GameDetailDialog.vue | 132 ++++---- .../src/components/game/ImportGamesDialog.vue | 145 +++++++++ .../components/group/GroupMembersPanel.vue | 2 +- .../src/components/team/GameSelectDialog.vue | 2 +- .../src/components/team/IdleMembersList.vue | 2 +- .../src/components/team/InvitationCard.vue | 2 +- .../src/components/team/TeamSessionPanel.vue | 69 ++++- frontend/src/stores/team.ts | 9 +- frontend/src/types/index.ts | 25 ++ frontend/src/views/GamesLibrary.vue | 282 ++++++++++-------- frontend/src/views/GroupView.vue | 2 +- frontend/src/views/Home.vue | 2 +- frontend/src/views/Layout.vue | 2 +- frontend/src/views/Profile.vue | 2 +- 23 files changed, 996 insertions(+), 348 deletions(-) create mode 100644 backend/pb_migrations/1776429444_created_game_comments.js create mode 100644 backend/pb_migrations/1776429455_created_game_favorites.js create mode 100644 backend/pb_migrations/1776429475_updated_games.js delete mode 100644 backend/scripts/seed-games.sh rename frontend/public/{default-avatar.png => default-avatar.svg} (100%) rename frontend/public/{game-placeholder.png => game-placeholder.svg} (100%) create mode 100644 frontend/src/components/game/AddGameDialog.vue create mode 100644 frontend/src/components/game/GameComments.vue create mode 100644 frontend/src/components/game/ImportGamesDialog.vue diff --git a/backend/pb_migrations/1776429444_created_game_comments.js b/backend/pb_migrations/1776429444_created_game_comments.js new file mode 100644 index 0000000..1fa4bdb --- /dev/null +++ b/backend/pb_migrations/1776429444_created_game_comments.js @@ -0,0 +1,87 @@ +/// +migrate((db) => { + const collection = new Collection({ + "id": "4f73q31qelxycnu", + "created": "2026-04-17 12:37:24.610Z", + "updated": "2026-04-17 12:37:24.610Z", + "name": "game_comments", + "type": "base", + "system": false, + "schema": [ + { + "system": false, + "id": "gc_game", + "name": "game", + "type": "relation", + "required": true, + "presentable": false, + "unique": false, + "options": { + "collectionId": "x5adjlc0txf16r8", + "cascadeDelete": false, + "minSelect": null, + "maxSelect": 1, + "displayFields": null + } + }, + { + "system": false, + "id": "gc_author", + "name": "author", + "type": "relation", + "required": true, + "presentable": false, + "unique": false, + "options": { + "collectionId": "_pb_users_auth_", + "cascadeDelete": false, + "minSelect": null, + "maxSelect": 1, + "displayFields": null + } + }, + { + "system": false, + "id": "gc_content", + "name": "content", + "type": "text", + "required": true, + "presentable": false, + "unique": false, + "options": { + "min": null, + "max": 1000, + "pattern": "" + } + }, + { + "system": false, + "id": "gc_rating", + "name": "rating", + "type": "number", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": 1, + "max": 5, + "noDecimal": true + } + } + ], + "indexes": [], + "listRule": "@request.auth.id != \"\"", + "viewRule": "@request.auth.id != \"\"", + "createRule": "@request.auth.id != \"\"", + "updateRule": null, + "deleteRule": "author = @request.auth.id", + "options": {} + }); + + return Dao(db).saveCollection(collection); +}, (db) => { + const dao = new Dao(db); + const collection = dao.findCollectionByNameOrId("4f73q31qelxycnu"); + + return dao.deleteCollection(collection); +}) diff --git a/backend/pb_migrations/1776429455_created_game_favorites.js b/backend/pb_migrations/1776429455_created_game_favorites.js new file mode 100644 index 0000000..88d2c07 --- /dev/null +++ b/backend/pb_migrations/1776429455_created_game_favorites.js @@ -0,0 +1,59 @@ +/// +migrate((db) => { + const collection = new Collection({ + "id": "b7dbz8i2snrgw9g", + "created": "2026-04-17 12:37:35.573Z", + "updated": "2026-04-17 12:37:35.573Z", + "name": "game_favorites", + "type": "base", + "system": false, + "schema": [ + { + "system": false, + "id": "gf_game", + "name": "game", + "type": "relation", + "required": true, + "presentable": false, + "unique": false, + "options": { + "collectionId": "x5adjlc0txf16r8", + "cascadeDelete": false, + "minSelect": null, + "maxSelect": 1, + "displayFields": null + } + }, + { + "system": false, + "id": "gf_user", + "name": "user", + "type": "relation", + "required": true, + "presentable": false, + "unique": false, + "options": { + "collectionId": "_pb_users_auth_", + "cascadeDelete": false, + "minSelect": null, + "maxSelect": 1, + "displayFields": null + } + } + ], + "indexes": [], + "listRule": "@request.auth.id != \"\"", + "viewRule": "@request.auth.id != \"\"", + "createRule": "@request.auth.id != \"\"", + "updateRule": null, + "deleteRule": "user = @request.auth.id", + "options": {} + }); + + return Dao(db).saveCollection(collection); +}, (db) => { + const dao = new Dao(db); + const collection = dao.findCollectionByNameOrId("b7dbz8i2snrgw9g"); + + return dao.deleteCollection(collection); +}) diff --git a/backend/pb_migrations/1776429475_updated_games.js b/backend/pb_migrations/1776429475_updated_games.js new file mode 100644 index 0000000..8e9302a --- /dev/null +++ b/backend/pb_migrations/1776429475_updated_games.js @@ -0,0 +1,66 @@ +/// +migrate((db) => { + const dao = new Dao(db) + const collection = dao.findCollectionByNameOrId("x5adjlc0txf16r8") + + collection.listRule = "group.owner = @request.auth.id || group.members.id = @request.auth.id" + collection.viewRule = "group.owner = @request.auth.id || group.members.id = @request.auth.id" + collection.createRule = "@request.auth.id != \"\"" + collection.updateRule = "group.owner = @request.auth.id || addedBy = @request.auth.id" + collection.deleteRule = "group.owner = @request.auth.id || addedBy = @request.auth.id" + + // add + collection.schema.addField(new SchemaField({ + "system": false, + "id": "sf_group", + "name": "group", + "type": "relation", + "required": true, + "presentable": false, + "unique": false, + "options": { + "collectionId": "es63bkyiblpnxdf", + "cascadeDelete": false, + "minSelect": null, + "maxSelect": 1, + "displayFields": null + } + })) + + // add + collection.schema.addField(new SchemaField({ + "system": false, + "id": "sf_addedBy", + "name": "addedBy", + "type": "relation", + "required": false, + "presentable": false, + "unique": false, + "options": { + "collectionId": "_pb_users_auth_", + "cascadeDelete": false, + "minSelect": null, + "maxSelect": 1, + "displayFields": null + } + })) + + return dao.saveCollection(collection) +}, (db) => { + const dao = new Dao(db) + const collection = dao.findCollectionByNameOrId("x5adjlc0txf16r8") + + collection.listRule = "@request.auth.id != \"\"" + collection.viewRule = "@request.auth.id != \"\"" + collection.createRule = null + collection.updateRule = null + collection.deleteRule = null + + // remove + collection.schema.removeField("sf_group") + + // remove + collection.schema.removeField("sf_addedBy") + + return dao.saveCollection(collection) +}) diff --git a/backend/scripts/seed-games.sh b/backend/scripts/seed-games.sh deleted file mode 100644 index 524a5b1..0000000 --- a/backend/scripts/seed-games.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/bin/bash -# seed-games.sh - 批量导入热门游戏数据到 PocketBase -set -e - -PB_URL="${PB_URL:-http://192.168.1.14:8090}" -ADMIN_EMAIL="${ADMIN_EMAIL:-admin@example.com}" -ADMIN_PASS="${ADMIN_PASS:-admin123456}" - -echo "获取管理员 Token..." -TOKEN=$(curl -s -X POST "$PB_URL/api/admins/auth-with-password" \ - -H "Content-Type: application/json" \ - -d "{\"identity\":\"$ADMIN_EMAIL\",\"password\":\"$ADMIN_PASS\"}" | python3 -c "import sys,json; print(json.load(sys.stdin)['token'])") - -echo "Token 获取成功,开始导入游戏..." - -create_game() { - local name="$1" platform="$2" tags="$3" count="$4" - curl -s -X POST "$PB_URL/api/collections/games/records" \ - -H "Authorization: Bearer $TOKEN" \ - -H "Content-Type: application/json" \ - -d "{\"name\":\"$name\",\"platform\":\"$platform\",\"tags\":$tags,\"popularCount\":$count}" | python3 -c "import sys,json; d=json.load(sys.stdin); print(f' ✓ {d.get(\"name\",\"ERROR\")}')" -} - -# PC 游戏 -create_game "League of Legends" "PC" '["MOBA","竞技","5v5"]' 10000 -create_game "Counter-Strike 2" "PC" '["FPS","射击","竞技"]' 9500 -create_game "Valorant" "PC" '["FPS","射击","战术"]' 9000 -create_game "Dota 2" "PC" '["MOBA","竞技","策略"]' 8500 -create_game "Apex Legends" "PC" '["FPS","大逃杀","吃鸡"]' 8000 -create_game "PUBG" "PC" '["大逃杀","吃鸡","射击"]' 7500 -create_game "Overwatch 2" "PC" '["FPS","英雄射击","团队"]' 7000 -create_game "Minecraft" "PC" '["沙盒","生存","建造"]' 6500 -create_game "Genshin Impact" "PC" '["RPG","开放世界","二次元"]' 6000 -create_game "Elden Ring" "PC" '["RPG","魂系","开放世界"]' 5500 -create_game "Teamfight Tactics" "PC" '["自走棋","策略","休闲"]' 5000 -create_game "Call of Duty: Warzone" "PC" '["FPS","大逃杀","射击"]' 4500 -create_game "Fortnite" "PC" '["大逃杀","建造","射击"]' 4000 -create_game "Dead by Daylight" "PC" '["恐怖","非对称","多人"]' 3500 -create_game "Among Us" "PC" '["社交","推理","休闲"]' 3000 -create_game "It Takes Two" "PC" '["合作","双人","冒险"]' 2500 -create_game "Baldurs Gate 3" "PC" '["RPG","回合制","合作"]' 2000 - -# PS5 -create_game "Helldivers 2" "PS5" '["射击","合作","PvE"]' 1800 -create_game "Final Fantasy XIV" "PS5" '["MMORPG","RPG","多人"]' 1500 -create_game "Spider-Man 2" "PS5" '["动作","冒险","开放世界"]' 1200 -create_game "God of War Ragnarok" "PS5" '["动作","冒险","单人"]' 1000 - -# Switch -create_game "Mario Kart 8" "Switch" '["竞速","休闲","派对"]' 2000 -create_game "Zelda: TOTK" "Switch" '["冒险","开放世界","解谜"]' 1800 -create_game "Super Smash Bros" "Switch" '["格斗","派对","竞技"]' 1500 -create_game "Pokemon Scarlet" "Switch" '["RPG","收集","冒险"]' 1200 - -# Mobile -create_game "Honor of Kings" "Mobile" '["MOBA","竞技","5v5"]' 9000 -create_game "PUBG Mobile" "Mobile" '["大逃杀","吃鸡","射击"]' 7000 -create_game "Genshin Impact" "Mobile" '["RPG","开放世界","二次元"]' 5500 -create_game "Call of Duty Mobile" "Mobile" '["FPS","射击","多人"]' 4000 -create_game "Arena of Valor" "Mobile" '["MOBA","竞技","5v5"]' 3000 - -# Xbox -create_game "Halo Infinite" "Xbox" '["FPS","射击","竞技"]' 3000 -create_game "Forza Horizon 5" "Xbox" '["竞速","开放世界","休闲"]' 2500 -create_game "Starfield" "Xbox" '["RPG","开放世界","太空"]' 2000 - -echo "导入完成!" diff --git a/frontend/public/default-avatar.png b/frontend/public/default-avatar.svg similarity index 100% rename from frontend/public/default-avatar.png rename to frontend/public/default-avatar.svg diff --git a/frontend/public/game-placeholder.png b/frontend/public/game-placeholder.svg similarity index 100% rename from frontend/public/game-placeholder.png rename to frontend/public/game-placeholder.svg diff --git a/frontend/src/api/games.ts b/frontend/src/api/games.ts index e71dc9a..b857a50 100644 --- a/frontend/src/api/games.ts +++ b/frontend/src/api/games.ts @@ -1,88 +1,127 @@ -// src/api/games.ts import pb from './pocketbase' -import type { Game, GamePlatform } from '@/types' +import type { Game, GamePlatform, GameComment } from '@/types' -// 获取游戏列表 -export async function getGames(options?: { +// 获取群组的游戏列表 +export async function getGroupGames(groupId: string, options?: { page?: number limit?: number platform?: GamePlatform search?: string }): Promise<{ items: Game[], total: number }> { - const { page = 1, limit = 20, platform, search } = options || {} - - let filter = '' - if (platform) { - filter = `platform="${platform}"` - } - if (search) { - const searchFilter = `name ~ "${search}"` - filter = filter ? `${filter} && ${searchFilter}` : searchFilter - } + const { page = 1, limit = 50, platform, search } = options || {} + let filter = `group="${groupId}"` + if (platform) filter += ` && platform="${platform}"` + if (search) filter += ` && name ~ "${search}"` const result = await pb.collection('games').getList(page, limit, { filter, - sort: '-popularCount' + sort: '-created' }) - - return { - items: result.items as unknown as Game[], - total: result.totalItems - } + return { items: result.items as unknown as Game[], total: result.totalItems } } -// 获取热门游戏 -export async function getPopularGames(limit = 10): Promise { - const result = await pb.collection('games').getList(1, limit, { - sort: '-popularCount' - }) - - return result.items as unknown as Game[] -} - -// 搜索游戏 -export async function searchGames(query: string, limit = 20): Promise { - if (!query.trim()) return [] - - const result = await pb.collection('games').getList(1, limit, { - filter: `name ~ "${query}"`, - sort: '-popularCount' - }) - - return result.items as unknown as Game[] -} - -// 添加游戏(需要管理员权限) -export async function addGame(data: { +// 添加游戏到群组 +export async function addGame(groupId: string, data: { name: string - platform: GamePlatform + platform?: GamePlatform tags?: string[] cover?: string }) { - return pb.collection('games').create(data) -} - -// 更新游戏热度 -export async function incrementGamePopularity(gameId: string) { - const game = await pb.collection('games').getOne(gameId) - return pb.collection('games').update(gameId, { - popularCount: (game.popularCount || 0) + 1 + const user = pb.authStore.model + return pb.collection('games').create({ + ...data, + group: groupId, + addedBy: user?.id, + popularCount: 0 }) } -// 获取游戏详情 -export async function getGame(gameId: string): Promise { - return pb.collection('games').getOne(gameId) as unknown as Game +// 删除游戏 +export async function deleteGame(gameId: string) { + return pb.collection('games').delete(gameId) } -// 按平台获取游戏 -export async function getGamesByPlatform(platform: GamePlatform): Promise { - const result = await pb.collection('games').getList(1, 50, { - filter: `platform="${platform}"`, - sort: '-popularCount' +// 导入游戏(批量添加) +export async function importGames(groupId: string, games: Array<{ + name: string + platform?: GamePlatform + tags?: string[] + cover?: string +}>) { + const results = [] + for (const game of games) { + try { + const result = await addGame(groupId, game) + results.push({ success: true, data: result }) + } catch (error: any) { + results.push({ success: false, error: error.message, data: game }) + } + } + return results +} + +// 导出游戏(获取全部数据) +export async function exportGames(groupId: string): Promise { + const result = await pb.collection('games').getFullList({ + filter: `group="${groupId}"`, + sort: '-created' + }) + return result as unknown as Game[] +} + +// 收藏/取消收藏 +export async function toggleFavorite(gameId: string): Promise { + const user = pb.authStore.model + if (!user) throw new Error('未登录') + + const existing = await pb.collection('game_favorites').getList(1, 1, { + filter: `game="${gameId}" && user="${user.id}"` }) - return result.items as unknown as Game[] + if (existing.items.length > 0) { + await pb.collection('game_favorites').delete(existing.items[0].id) + return false + } else { + await pb.collection('game_favorites').create({ + game: gameId, + user: user.id + }) + return true + } +} + +// 检查是否已收藏 +export async function isFavorite(gameId: string): Promise { + const user = pb.authStore.model + if (!user) return false + + const result = await pb.collection('game_favorites').getList(1, 1, { + filter: `game="${gameId}" && user="${user.id}"` + }) + return result.items.length > 0 +} + +// 添加评论 +export async function addComment(gameId: string, content: string, rating?: number) { + const user = pb.authStore.model + if (!user) throw new Error('未登录') + + return pb.collection('game_comments').create({ + game: gameId, + author: user.id, + content, + rating + }) +} + +// 获取游戏评论 +export async function getGameComments(gameId: string): Promise { + const result = await pb.collection('game_comments').getList(1, 50, { + filter: `game="${gameId}"`, + sort: '-created', + expand: 'author' + }) + return result.items as unknown as GameComment[] } // 获取所有平台 @@ -90,9 +129,27 @@ export function getAllPlatforms(): GamePlatform[] { return ['PC', 'PS5', 'Xbox', 'Switch', 'Mobile'] } -// 订阅游戏变更 -export function subscribeGames(callback: (game: Game) => void) { - return pb.collection('games').subscribe('*', (payload) => { - callback(payload.record as unknown as Game) +// 搜索游戏(用于 GameSelectDialog,全局搜索或群组内搜索) +export async function searchGames(query: string, groupId?: string, limit = 20): Promise { + if (!query.trim()) return [] + let filter = `name ~ "${query}"` + if (groupId) filter += ` && group="${groupId}"` + + const result = await pb.collection('games').getList(1, limit, { + filter, + sort: '-popularCount' }) + return result.items as unknown as Game[] +} + +// 获取热门游戏(全局,按 popularCount 排序) +export async function getPopularGames(limit = 10): Promise { + const user = pb.authStore.model + if (!user) return [] + + // 获取用户所在群组的游戏 + const result = await pb.collection('games').getList(1, limit, { + sort: '-popularCount' + }) + return result.items as unknown as Game[] } diff --git a/frontend/src/components/game/AddGameDialog.vue b/frontend/src/components/game/AddGameDialog.vue new file mode 100644 index 0000000..de98e91 --- /dev/null +++ b/frontend/src/components/game/AddGameDialog.vue @@ -0,0 +1,92 @@ + + + + + diff --git a/frontend/src/components/game/GameComments.vue b/frontend/src/components/game/GameComments.vue new file mode 100644 index 0000000..7684f39 --- /dev/null +++ b/frontend/src/components/game/GameComments.vue @@ -0,0 +1,108 @@ + + + + + diff --git a/frontend/src/components/game/GameDetailDialog.vue b/frontend/src/components/game/GameDetailDialog.vue index 4a53896..dc402b3 100644 --- a/frontend/src/components/game/GameDetailDialog.vue +++ b/frontend/src/components/game/GameDetailDialog.vue @@ -1,15 +1,20 @@ diff --git a/frontend/src/components/game/ImportGamesDialog.vue b/frontend/src/components/game/ImportGamesDialog.vue new file mode 100644 index 0000000..7b0a25e --- /dev/null +++ b/frontend/src/components/game/ImportGamesDialog.vue @@ -0,0 +1,145 @@ + + + + + diff --git a/frontend/src/components/group/GroupMembersPanel.vue b/frontend/src/components/group/GroupMembersPanel.vue index c3579dc..a69c8f1 100644 --- a/frontend/src/components/group/GroupMembersPanel.vue +++ b/frontend/src/components/group/GroupMembersPanel.vue @@ -58,7 +58,7 @@ async function removeMember(userId: string, username: string) {
- +
{{ member.username }} 群主 diff --git a/frontend/src/components/team/GameSelectDialog.vue b/frontend/src/components/team/GameSelectDialog.vue index 9bf8b02..d1fe2e8 100644 --- a/frontend/src/components/team/GameSelectDialog.vue +++ b/frontend/src/components/team/GameSelectDialog.vue @@ -82,7 +82,7 @@ function confirmCustomGame() { @click="selectGame(game)" > diff --git a/frontend/src/components/team/IdleMembersList.vue b/frontend/src/components/team/IdleMembersList.vue index 6297c71..a0bcbe0 100644 --- a/frontend/src/components/team/IdleMembersList.vue +++ b/frontend/src/components/team/IdleMembersList.vue @@ -59,7 +59,7 @@ async function inviteMember(userId: string, username: string) { class="member-item" > diff --git a/frontend/src/components/team/InvitationCard.vue b/frontend/src/components/team/InvitationCard.vue index b3c4bd2..1361076 100644 --- a/frontend/src/components/team/InvitationCard.vue +++ b/frontend/src/components/team/InvitationCard.vue @@ -49,7 +49,7 @@ async function rejectInvitation() {
diff --git a/frontend/src/components/team/TeamSessionPanel.vue b/frontend/src/components/team/TeamSessionPanel.vue index 4d6401d..3016eb3 100644 --- a/frontend/src/components/team/TeamSessionPanel.vue +++ b/frontend/src/components/team/TeamSessionPanel.vue @@ -1,16 +1,20 @@ diff --git a/frontend/src/stores/team.ts b/frontend/src/stores/team.ts index ea8c4fb..b5c114c 100644 --- a/frontend/src/stores/team.ts +++ b/frontend/src/stores/team.ts @@ -3,6 +3,7 @@ import { defineStore } from 'pinia' import { ref, computed } from 'vue' import type { TeamSession, TeamStatus } from '@/types' import { getActiveTeamSession, createTeamSession, updateTeamStatus, endGame } from '@/api/sessions' +import { pb } from '@/api/pocketbase' import { getPendingInvitations, sendBulkInvitations } from '@/api/invitations' export const useTeamStore = defineStore('team', () => { @@ -43,8 +44,12 @@ export const useTeamStore = defineStore('team', () => { const session = await createTeamSession(data) currentSession.value = session - // 发送邀请 - await sendBulkInvitations(data.members, session.id) + // 发送邀请(排除创建者自己) + const currentUserId = pb.authStore.model?.id + const others = data.members.filter(id => id !== currentUserId) + if (others.length > 0) { + await sendBulkInvitations(others, session.id) + } return session } catch (error: any) { diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts index 803d2f2..3294233 100644 --- a/frontend/src/types/index.ts +++ b/frontend/src/types/index.ts @@ -117,6 +117,8 @@ export interface Game { tags?: string[] cover?: string popularCount: number + group: string + addedBy?: string created: string updated: string } @@ -126,3 +128,26 @@ export interface WorkSchedule { workdays: number[] workStartTime: string } + +// 游戏评论 +export interface GameComment { + id: string + game: string + author: string + content: string + rating?: number + created: string + updated: string + expand?: { + author?: User + } +} + +// 游戏收藏 +export interface GameFavorite { + id: string + game: string + user: string + created: string + updated: string +} diff --git a/frontend/src/views/GamesLibrary.vue b/frontend/src/views/GamesLibrary.vue index 27753e8..4e1bc2b 100644 --- a/frontend/src/views/GamesLibrary.vue +++ b/frontend/src/views/GamesLibrary.vue @@ -1,9 +1,15 @@ diff --git a/frontend/src/views/GroupView.vue b/frontend/src/views/GroupView.vue index 3f3ce87..56b24ae 100644 --- a/frontend/src/views/GroupView.vue +++ b/frontend/src/views/GroupView.vue @@ -153,7 +153,7 @@ async function refreshMembers() {
暂无
- + {{ m.username }} {{ m.statusNote }}
diff --git a/frontend/src/views/Home.vue b/frontend/src/views/Home.vue index 48127de..ed2ae80 100644 --- a/frontend/src/views/Home.vue +++ b/frontend/src/views/Home.vue @@ -137,7 +137,7 @@ function openGameDetail(game: Game) { >
diff --git a/frontend/src/views/Layout.vue b/frontend/src/views/Layout.vue index f14b617..693ce89 100644 --- a/frontend/src/views/Layout.vue +++ b/frontend/src/views/Layout.vue @@ -106,7 +106,7 @@ function goHome() {