diff --git a/frontend/src/components-mobile/bet/BetListMobile.vue b/frontend/src/components-mobile/bet/BetListMobile.vue new file mode 100644 index 0000000..347ea80 --- /dev/null +++ b/frontend/src/components-mobile/bet/BetListMobile.vue @@ -0,0 +1,410 @@ + + + + + + + + + + + + 加载中... + + + + + + {{ currentBet.status === 'open' ? '下注中' : currentBet.status === 'closed' ? '待结算' : '已结算' }} + + 范围 {{ currentBet.minStake }}-{{ currentBet.maxStake }} 积分 + + + {{ currentBet.description }} + + + + + {{ opt.content }} + 🏆 胜出 + + + {{ optionEntryCount(opt.id) }} 注 + {{ optionTotalStake(opt.id) }} 积分 + + + + + + + + {{ myEntry()?.won ? `🎉 你赢了!` : '本次未中奖' }} + + + + + + + 关闭下注 + + + 结算 + + + + + + + + + + 发起竞猜 + + + + + + + + + + + + + {{ bet.status === 'open' ? '下注中' : bet.status === 'closed' ? '待结算' : '已结算' }} + + {{ bet.minStake }}-{{ bet.maxStake }} 积分 + + {{ bet.title }} + + + + + + + + + + + {{ stakeAmount }} + 积分 + + + + + 确认下注 + + + + + + + + + 发起竞猜 + + + + + + + + + + + + + + + 创建 + + + + + + + + + + {{ opt.content }} + + + 确认结算 + + + + + + + diff --git a/frontend/src/components-mobile/group/ActivityFeedMobile.vue b/frontend/src/components-mobile/group/ActivityFeedMobile.vue new file mode 100644 index 0000000..8ad9bfc --- /dev/null +++ b/frontend/src/components-mobile/group/ActivityFeedMobile.vue @@ -0,0 +1,400 @@ + + + + + + + + + + + 进行中 + + {{ teamStore.currentSession?.gameName }} + + {{ teamStore.currentSession?.name }} · {{ teamStore.currentSession?.members?.length || 0 }} 人 + + 进入语音房 → + + + + + 发起组队 + + + + + + + + {{ statusLabels[status] }} + {{ list.length }} + + + + + + {{ m.name || m.username }} + {{ m.statusNote }} + + + + + + + + + + 发起组队 + + + + + + 邀请成员(空闲:{{ idleMembers.length }}) + + + + {{ m.name || m.username }} + + + 暂无其他空闲成员 + + + + + 开始组队 + + + + + + + + diff --git a/frontend/src/components-mobile/group/MemberListMobile.vue b/frontend/src/components-mobile/group/MemberListMobile.vue new file mode 100644 index 0000000..79b48b0 --- /dev/null +++ b/frontend/src/components-mobile/group/MemberListMobile.vue @@ -0,0 +1,315 @@ + + + + + + + + + + + 入群申请({{ joinRequests.length }}) + + + + {{ req.expand?.user?.name || req.expand?.user?.username }} + + + 通过 + 拒绝 + + + + + + + + + + + + + + + + + + + {{ statusLabels[status] }} + {{ list.length }} + + + + + + + {{ m.name || m.username }} + 群主 + + {{ m.statusNote }} + + 移除 + + + + + + + diff --git a/frontend/src/components-mobile/memory/MemoryGridMobile.vue b/frontend/src/components-mobile/memory/MemoryGridMobile.vue new file mode 100644 index 0000000..5f2bff8 --- /dev/null +++ b/frontend/src/components-mobile/memory/MemoryGridMobile.vue @@ -0,0 +1,211 @@ + + + + + + + + {{ memories.length }} 个回忆 + + 上传 + + + + + 加载中... + + + + + + + + + + + + + + + {{ m.fileType }} + + + + {{ m.title }} + {{ timeAgo(m.created) }} + + + + + + + + + 上传回忆 + + + + + + + + + 上传 {{ uploadFiles.length > 0 ? `(${uploadFiles.length})` : '' }} + + + + + + + + diff --git a/frontend/src/components-mobile/poll/PollListMobile.vue b/frontend/src/components-mobile/poll/PollListMobile.vue new file mode 100644 index 0000000..377bab9 --- /dev/null +++ b/frontend/src/components-mobile/poll/PollListMobile.vue @@ -0,0 +1,463 @@ + + + + + + + + + + + + 加载中... + + + + + + {{ currentPoll.status === 'settled' ? '已结算' : '进行中' }} + + {{ votes.length }} 人参与 · {{ timeAgo(currentPoll.created) }} + + + + + + + + + {{ opt.content }} + {{ optionVoteCount(opt.id) }} 票 + + + + + + + 结算投票 + + + + + + + + + + 发起投票 + + + + + + + + + + + + + {{ poll.status === 'settled' ? '已结算' : '进行中' }} + + {{ timeAgo(poll.created) }} + + {{ poll.title }} + + + + + + + + + + 发起投票 + + + + + + 选项投票 + 点名 + + + + + + + + + + + + + + 创建 + + + + + + + + diff --git a/frontend/src/components-mobile/stats/StatsPanelMobile.vue b/frontend/src/components-mobile/stats/StatsPanelMobile.vue new file mode 100644 index 0000000..28a1e12 --- /dev/null +++ b/frontend/src/components-mobile/stats/StatsPanelMobile.vue @@ -0,0 +1,109 @@ + + + + + + + + 加载中... + + + + + + + {{ members.length }} + 成员 + + + {{ gameCount }} + 游戏 + + + {{ group?.maxMembers || '-' }} + 上限 + + + + + + 积分排行 + 暂无数据 + + + {{ idx + 1 }} + + {{ item.name || '玩家' }} + + {{ item.points }} + + + + + + + + diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts index 4bd0a4e..0cb2285 100644 --- a/frontend/src/router/index.ts +++ b/frontend/src/router/index.ts @@ -22,7 +22,7 @@ const routes: RouteRecordRaw[] = [ name: 'Login', component: view( () => import('@/views/Login.vue'), - () => import('@/views-mobile/Placeholder.vue') // 阶段 2 替换为 LoginMobile + () => import('@/views-mobile/LoginMobile.vue') ), meta: { requiresGuest: true } }, @@ -31,7 +31,7 @@ const routes: RouteRecordRaw[] = [ name: 'Register', component: view( () => import('@/views/Register.vue'), - () => import('@/views-mobile/Placeholder.vue') // 阶段 2 替换为 RegisterMobile + () => import('@/views-mobile/RegisterMobile.vue') ), meta: { requiresGuest: true } }, @@ -45,7 +45,7 @@ const routes: RouteRecordRaw[] = [ name: 'Home', component: view( () => import('@/views/Home.vue'), - () => import('@/views-mobile/Placeholder.vue') // 阶段 3 替换为 HomeMobile + () => import('@/views-mobile/HomeMobile.vue') ) }, { @@ -53,7 +53,7 @@ const routes: RouteRecordRaw[] = [ name: 'MobileGroups', component: view( () => import('@/views/Home.vue'), // 桌面端无此路由,回退首页 - () => import('@/views-mobile/Placeholder.vue') // 阶段 3 替换为 GroupsMobile + () => import('@/views-mobile/GroupsMobile.vue') ) }, { @@ -61,7 +61,7 @@ const routes: RouteRecordRaw[] = [ name: 'MobileNotifications', component: view( () => import('@/views/Home.vue'), - () => import('@/views-mobile/Placeholder.vue') // 阶段 3 替换为 NotificationsMobile + () => import('@/views-mobile/NotificationsMobile.vue') ) }, { @@ -69,7 +69,7 @@ const routes: RouteRecordRaw[] = [ name: 'GroupView', component: view( () => import('@/views/GroupView.vue'), - () => import('@/views-mobile/Placeholder.vue') // 阶段 4 替换为 GroupViewMobile + () => import('@/views-mobile/GroupViewMobile.vue') ), props: true }, @@ -78,7 +78,7 @@ const routes: RouteRecordRaw[] = [ name: 'LedgerView', component: view( () => import('@/views/LedgerView.vue'), - () => import('@/views-mobile/Placeholder.vue') // 阶段 8 替换为 LedgerMobile + () => import('@/views-mobile/LedgerMobile.vue') ), props: true }, @@ -87,7 +87,7 @@ const routes: RouteRecordRaw[] = [ name: 'AssetView', component: view( () => import('@/views/AssetView.vue'), - () => import('@/views-mobile/Placeholder.vue') // 阶段 8 替换为 AssetMobile + () => import('@/views-mobile/AssetMobile.vue') ), props: true }, @@ -96,7 +96,7 @@ const routes: RouteRecordRaw[] = [ name: 'BlacklistView', component: view( () => import('@/views/BlacklistView.vue'), - () => import('@/views-mobile/Placeholder.vue') // 阶段 8 替换为 BlacklistMobile + () => import('@/views-mobile/BlacklistMobile.vue') ), props: true }, @@ -105,7 +105,7 @@ const routes: RouteRecordRaw[] = [ name: 'VoiceRoom', component: view( () => import('@/views/VoiceRoom.vue'), - () => import('@/views-mobile/Placeholder.vue') // 阶段 5 替换为 VoiceRoomMobile + () => import('@/views-mobile/VoiceRoomMobile.vue') ), props: true }, @@ -114,7 +114,7 @@ const routes: RouteRecordRaw[] = [ name: 'GamesLibrary', component: view( () => import('@/views/GamesLibrary.vue'), - () => import('@/views-mobile/Placeholder.vue') // 阶段 7 替换为 GamesLibraryMobile + () => import('@/views-mobile/GamesLibraryMobile.vue') ) }, { @@ -122,7 +122,7 @@ const routes: RouteRecordRaw[] = [ name: 'Profile', component: view( () => import('@/views/Profile.vue'), - () => import('@/views-mobile/Placeholder.vue') // 阶段 9 替换为 ProfileMobile + () => import('@/views-mobile/ProfileMobile.vue') ) }, { @@ -130,7 +130,7 @@ const routes: RouteRecordRaw[] = [ name: 'Settings', component: view( () => import('@/views/Settings.vue'), - () => import('@/views-mobile/Placeholder.vue') // 阶段 9 替换为 SettingsMobile + () => import('@/views-mobile/SettingsMobile.vue') ) }, { @@ -138,7 +138,7 @@ const routes: RouteRecordRaw[] = [ name: 'Changelog', component: view( () => import('@/views/Changelog.vue'), - () => import('@/views-mobile/Placeholder.vue') // 阶段 9 替换为 ChangelogMobile + () => import('@/views-mobile/ChangelogMobile.vue') ) } ] diff --git a/frontend/src/views-mobile/AssetMobile.vue b/frontend/src/views-mobile/AssetMobile.vue new file mode 100644 index 0000000..fe52a33 --- /dev/null +++ b/frontend/src/views-mobile/AssetMobile.vue @@ -0,0 +1,230 @@ + + + + + + + + + + + + + + + + + + + {{ a.name }} + + {{ AssetTypeMap[a.type] }} + + + 持有: {{ displayName(a.expand.currentHolder) }} + + + + + 转移 + 删除 + + + + + + + + + + + + + 添加资产 + + + + + + {{ AssetTypeMap[t] }} + + + + + + + + + + 添加 + + + + + + + + + + {{ displayName(m) }} + + + + 确认转移 + + + + + + + diff --git a/frontend/src/views-mobile/BlacklistMobile.vue b/frontend/src/views-mobile/BlacklistMobile.vue new file mode 100644 index 0000000..5449f0b --- /dev/null +++ b/frontend/src/views-mobile/BlacklistMobile.vue @@ -0,0 +1,278 @@ + + + + + + + + + + 添加 + + + + + + + + + {{ g.gameName }} + {{ BlacklistSeverityMap[g.severity] }} + + {{ BlacklistReasonMap[g.reason] }} + {{ g.description }} + + + + + + + + + + 添加 + + + + + + + + + {{ p.playerId }} + {{ BlacklistSeverityMap[p.severity] }} + + + {{ PlayerTagMap[t] }} + {{ p.customTag }} + + {{ p.description }} + 平台: {{ p.platform }} + + + + + + + + + + + + 添加游戏黑名单 + + + + + + {{ BlacklistReasonMap[r] }} + + + + + + + {{ BlacklistSeverityMap[s] }} + + + + + + + 添加 + + + + + + + 添加玩家黑名单 + + + + + + + {{ BlacklistSeverityMap[s] }} + + + + + 标签(多选) + + {{ PlayerTagMap[t] }} + + + + + + 添加 + + + + + + + diff --git a/frontend/src/views-mobile/ChangelogMobile.vue b/frontend/src/views-mobile/ChangelogMobile.vue new file mode 100644 index 0000000..f8506bf --- /dev/null +++ b/frontend/src/views-mobile/ChangelogMobile.vue @@ -0,0 +1,101 @@ + + + + + + + + + {{ log.version }} + {{ log.date }} + + {{ log.title }} + + + {{ typeLabel[item.type] }} + {{ item.text }} + + + + + + + diff --git a/frontend/src/views-mobile/GamesLibraryMobile.vue b/frontend/src/views-mobile/GamesLibraryMobile.vue new file mode 100644 index 0000000..8a2142f --- /dev/null +++ b/frontend/src/views-mobile/GamesLibraryMobile.vue @@ -0,0 +1,170 @@ + + + + + + + + + 取消 + + + + + + {{ p || '全部' }} + + + + + 加载中... + + + + + + + + + + {{ game.name }} + + {{ game.platform }} + 热门{{ game.popularCount }} + + + + + + + + + {{ currentGame.name }} + + {{ currentGame.platform }} + {{ t }} + + + 暂无详细信息 + + + + + + + + diff --git a/frontend/src/views-mobile/GroupViewMobile.vue b/frontend/src/views-mobile/GroupViewMobile.vue new file mode 100644 index 0000000..f42f948 --- /dev/null +++ b/frontend/src/views-mobile/GroupViewMobile.vue @@ -0,0 +1,231 @@ + + + + + + + + + + {{ group?.name || '加载中...' }} + {{ members.length }} 人 + + {{ group?.description || '暂无群组简介' }} + + 群主: {{ ownerName }} + · + {{ members.length }}/{{ group?.maxMembers || '-' }} + + + + + + 账本 + + + + 资产 + + + + 黑名单 + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/src/views-mobile/GroupsMobile.vue b/frontend/src/views-mobile/GroupsMobile.vue new file mode 100644 index 0000000..e02b82d --- /dev/null +++ b/frontend/src/views-mobile/GroupsMobile.vue @@ -0,0 +1,381 @@ + + + + + + + + + + 创建 + + + 加入 + + + + + + + + 创建第一个群组 + + + + + + + + {{ group.name }} + {{ group.description || '暂无简介' }} + + + + + + + + + + + 创建群组 + + + + + + + + + + + + 创建 + + + + + + + + + 加入群组 + + + 搜索中... + + + + + + + + {{ group.name }} + {{ group.description || '暂无简介' }} + {{ group.members?.length || 0 }}/{{ group.maxMembers }} 人 + + + 加入 + + + + + + + + + diff --git a/frontend/src/views-mobile/HomeMobile.vue b/frontend/src/views-mobile/HomeMobile.vue new file mode 100644 index 0000000..d2e71ce --- /dev/null +++ b/frontend/src/views-mobile/HomeMobile.vue @@ -0,0 +1,463 @@ + + + + + + + + + + + + {{ userStore.user?.name || userStore.user?.username }} + + + {{ statusText }} + + · {{ userStore.user.statusNote }} + + + + + + + + {{ userStore.user?.points ?? 0 }} + 积分 + + + {{ groupStore.groups.length }} + 群组 + + + + + + + + + 当前组队 + {{ teamStore.teamStatus }} + + + {{ teamStore.currentSession?.gameName }} + + {{ teamStore.currentSession?.name }} + · {{ teamStore.currentSession?.members?.length || 0 }} 人 + + + + 进入语音房 + + + + + + + 我的群组 + 全部 + + + + + + 创建或加入群组 + + + + + + + {{ group.name }} + {{ group.members?.length || 0 }} 人 + + + + + + + + 热门游戏 + + + + 加载中... + + + + 暂无热门游戏 + + + + + + {{ game.name }} + {{ game.platform }} + + + + + + + + + + diff --git a/frontend/src/views-mobile/LedgerMobile.vue b/frontend/src/views-mobile/LedgerMobile.vue new file mode 100644 index 0000000..c11ab2a --- /dev/null +++ b/frontend/src/views-mobile/LedgerMobile.vue @@ -0,0 +1,260 @@ + + + + + + + + + + {{ months.find(m => m.value === currentMonth)?.label || currentMonth }} + + + + + 收入 + {{ summary.totalIncome.toFixed(2) }} + + + + 支出 + {{ summary.totalExpense.toFixed(2) }} + + + + 结余 + + {{ summary.balance.toFixed(2) }} + + + + + + + + + + + + + + + {{ LedgerTypeMap[l.type] }} + + {{ l.description || LedgerCategoryMap[l.category] }} + + {{ LedgerCategoryMap[l.category] }} · {{ formatDate(l.occurredAt) }} + + + + + {{ l.type === 'income' ? '+' : '-' }}{{ l.amount.toFixed(2) }} + + + + + + + + + + + + + + + + + + {{ m.label }} + + + + + + + + 添加账目 + + + + + 支出 + 收入 + + + + + + + + + + + + {{ label }} + + + + + + + + 添加 + + + + + + + diff --git a/frontend/src/views-mobile/LoginMobile.vue b/frontend/src/views-mobile/LoginMobile.vue new file mode 100644 index 0000000..311a7e0 --- /dev/null +++ b/frontend/src/views-mobile/LoginMobile.vue @@ -0,0 +1,158 @@ + + + + + + + + 🎮 + Game Group + 组队开黑,一起嗨 + + + + + + + + + + + 登录 + + + + + + + + + diff --git a/frontend/src/views-mobile/NotificationsMobile.vue b/frontend/src/views-mobile/NotificationsMobile.vue new file mode 100644 index 0000000..5919b42 --- /dev/null +++ b/frontend/src/views-mobile/NotificationsMobile.vue @@ -0,0 +1,393 @@ + + + + + + + + + + + + + + + 组队邀请 + + + + + {{ inv.expand?.from?.name || inv.expand?.from?.username || '未知' }} + + 邀请你组队:{{ inv.expand?.teamSession?.gameName || '游戏' }} + + + + + + 接受 + + + 拒绝 + + + + + + + + 入群申请 + + + + + {{ req.expand?.user?.name || req.expand?.user?.username || '未知' }} + + 申请加入:{{ req.expand?.group?.name || '群组' }} + + + + + + 通过 + + + 拒绝 + + + + + + + + + + 全部标为已读 + + + + + + + + + + + + + {{ n.title }} + {{ n.content }} + {{ timeAgo(n.created) }} + + + + + + + + + + + + + + diff --git a/frontend/src/views-mobile/ProfileMobile.vue b/frontend/src/views-mobile/ProfileMobile.vue new file mode 100644 index 0000000..124b091 --- /dev/null +++ b/frontend/src/views-mobile/ProfileMobile.vue @@ -0,0 +1,137 @@ + + + + + + + + + + + {{ user?.name || user?.username }} + @{{ user?.username }} + + + + + + + {{ user?.points ?? 0 }} + 积分 + + + {{ groupStore.groups.length }} + 群组 + + + + + + + + + + + + + + + + + + + + + + + 退出登录 + + + + + + + + diff --git a/frontend/src/views-mobile/RegisterMobile.vue b/frontend/src/views-mobile/RegisterMobile.vue new file mode 100644 index 0000000..6400d85 --- /dev/null +++ b/frontend/src/views-mobile/RegisterMobile.vue @@ -0,0 +1,166 @@ + + + + + + + + + + + 🎮 + 创建账号 + 输入昵称开始你的组队之旅 + + + + + + + + + + + 注册 + + + + + + + + + diff --git a/frontend/src/views-mobile/SettingsMobile.vue b/frontend/src/views-mobile/SettingsMobile.vue new file mode 100644 index 0000000..fa2a7e8 --- /dev/null +++ b/frontend/src/views-mobile/SettingsMobile.vue @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/src/views-mobile/VoiceRoomMobile.vue b/frontend/src/views-mobile/VoiceRoomMobile.vue new file mode 100644 index 0000000..8b95979 --- /dev/null +++ b/frontend/src/views-mobile/VoiceRoomMobile.vue @@ -0,0 +1,255 @@ + + + + + + + + + + + {{ gameName }} + + + {{ members.length }} 人在线 + + + + + + + + + + 加载中... + + + + + + + + + + + + {{ displayName(m) }} + 我 + + + + + + + + + + + + + {{ micEnabled ? '麦克风' : '已静音' }} + + + + {{ speakerEnabled ? '扬声器' : '已关闭' }} + + + + 退出 + + + + + + diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 4a66df3..475eb4a 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -9,6 +9,25 @@ export default defineConfig({ '@': path.resolve(__dirname, 'src') } }, + build: { + rollupOptions: { + output: { + // 代码分割:vendor 按依赖分组,避免单个超大 chunk + manualChunks: { + // Vue 核心运行时(vue + vue-router + pinia) + 'vue-vendor': ['vue', 'vue-router', 'pinia'], + // 桌面端 UI 库 + 'element-plus': ['element-plus', '@element-plus/icons-vue'], + // 手机端 UI 库 + 'vant': ['vant'], + // 后端 SDK + 'pocketbase': ['pocketbase'], + // 语音房依赖(仅 VoiceRoom 用到,体积大,单独拆分) + 'livekit': ['livekit-client'], + } + } + } + }, server: { port: Number(process.env.VITE_PORT) || 5173, proxy: {
{{ currentBet.description }}
{{ g.description }}
{{ p.description }}
{{ group?.description || '暂无群组简介' }}
组队开黑,一起嗨
输入昵称开始你的组队之旅