refactor(admin): 合并管理后台并移除 apps/agent

- 平台与代理共用 apps/admin,统一登录 manage/auth/login
- 按 userType 展示菜单,修复 token 循环跳转
- 删除独立 apps/agent 前端工程

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-02 17:50:58 +08:00
parent b5dca1bfb1
commit 31737286b9
34 changed files with 363 additions and 255 deletions

View File

@@ -1,23 +1,95 @@
import { createRouter, createWebHistory } from 'vue-router';
import { useAuthStore } from '../stores/auth';
export default createRouter({
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/login', component: () => import('../views/Login.vue') },
{ path: '/login', component: () => import('../views/Login.vue'), meta: { public: true } },
{
path: '/',
component: () => import('../layouts/AdminLayout.vue'),
component: () => import('../layouts/ManageLayout.vue'),
meta: { auth: true },
children: [
{ path: '', component: () => import('../views/Dashboard.vue') },
{ path: 'users', component: () => import('../views/Users.vue') },
{ path: 'agents', component: () => import('../views/Agents.vue') },
{ path: 'matches', component: () => import('../views/Matches.vue') },
{ path: 'bets', component: () => import('../views/Bets.vue') },
{ path: 'settlement/:id', component: () => import('../views/Settlement.vue') },
{ path: 'cashback', component: () => import('../views/Cashback.vue') },
{ path: 'audit', component: () => import('../views/Audit.vue') },
{ path: '', component: () => import('../views/HomeEntry.vue') },
{
path: 'users',
component: () => import('../views/Users.vue'),
meta: { adminOnly: true },
},
{
path: 'agents',
component: () => import('../views/Agents.vue'),
meta: { adminOnly: true },
},
{
path: 'matches',
component: () => import('../views/Matches.vue'),
meta: { adminOnly: true },
},
{
path: 'bets',
component: () => import('../views/Bets.vue'),
meta: { adminOnly: true },
},
{
path: 'settlement/:id',
component: () => import('../views/Settlement.vue'),
meta: { adminOnly: true },
},
{
path: 'cashback',
component: () => import('../views/Cashback.vue'),
meta: { adminOnly: true },
},
{
path: 'audit',
component: () => import('../views/Audit.vue'),
meta: { adminOnly: true },
},
{
path: 'my-players',
component: () => import('../views/agent/Players.vue'),
meta: { agentOnly: true },
},
{
path: 'sub-agents',
component: () => import('../views/agent/SubAgents.vue'),
meta: { agentOnly: true },
},
{
path: 'my-bets',
component: () => import('../views/agent/Bets.vue'),
meta: { agentOnly: true },
},
],
},
],
});
router.beforeEach((to) => {
const auth = useAuthStore();
const hasToken = !!auth.token.value;
const hasUser = !!auth.user.value?.userType;
if (to.meta.public) {
if (hasToken && hasUser) return '/';
return true;
}
if (!hasToken || !hasUser) {
auth.clearStaffSession();
return { path: '/login', query: { redirect: to.fullPath } };
}
if (to.meta.adminOnly && !auth.isAdmin.value) {
return '/';
}
if (to.meta.agentOnly && !auth.isAgent.value) {
return '/';
}
return true;
});
export default router;