fix(admin): 收紧 isSuper、plan-prices RBAC 与封禁状态机

避免 roles.write 绕过全部 can();定价读写挂 membership.plans 权限;去掉快捷封禁双路径并让 ban/unban 走 lifecycle。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jackyu66git
2026-08-13 01:56:00 +08:00
co-authored by Cursor
parent 62cd8c45dd
commit 0d50c0ee73
10 changed files with 44 additions and 64 deletions
+6 -1
View File
@@ -18,7 +18,7 @@ const router = createRouter({
{ path: 'orders', name: 'orders', component: () => import('@/pages/OrdersPage.vue') },
{ path: 'plans', name: 'plans', component: () => import('@/pages/MembershipPlansPage.vue') },
{ path: 'codes', name: 'codes', component: () => import('@/pages/RedemptionPage.vue') },
{ path: 'pricing', name: 'pricing', component: () => import('@/pages/PricingPage.vue'), meta: { superOnly: true } },
{ path: 'pricing', name: 'pricing', component: () => import('@/pages/PricingPage.vue'), meta: { permission: 'admin.membership.plans.read' } },
{ path: 'ask', name: 'ask', component: () => import('@/pages/AskPage.vue') },
{ path: 'safety', name: 'safety', component: () => import('@/pages/SafetyPage.vue') },
{ path: 'ai', name: 'ai', component: () => import('@/pages/AIConfigPage.vue') },
@@ -41,6 +41,11 @@ router.beforeEach(async (to) => {
if (!auth.username) await auth.hydrate()
if (!auth.isSuper) return { name: 'dashboard' }
}
if (typeof to.meta.permission === 'string') {
const auth = useAuthStore()
if (!auth.username) await auth.hydrate()
if (!auth.can(to.meta.permission)) return { name: 'dashboard' }
}
return true
})