diff --git a/src/App.vue b/src/App.vue index ac76cf1..942d425 100644 --- a/src/App.vue +++ b/src/App.vue @@ -17,13 +17,26 @@ > 我的權限 - - 權限管理 - + +
+ + + 管理員 + + + +
登出 @@ -37,6 +50,7 @@ import { computed } from 'vue' import { useRoute, useRouter } from 'vue-router' import { useAuthStore } from '@/stores/auth' +import { ArrowDown } from '@element-plus/icons-vue' const route = useRoute() const router = useRouter() @@ -44,6 +58,19 @@ const authStore = useAuthStore() const isLoginPage = computed(() => route.name === 'login') +function handleAdminNav(command) { + const routes = { + permissions: '/admin/permissions', + systems: '/admin/systems', + modules: '/admin/modules', + companies: '/admin/companies', + sites: '/admin/sites', + members: '/admin/members', + groups: '/admin/permission-groups' + } + router.push(routes[command]) +} + function logout() { authStore.logout() router.push('/login') diff --git a/src/api/companies.js b/src/api/companies.js new file mode 100644 index 0000000..c62607a --- /dev/null +++ b/src/api/companies.js @@ -0,0 +1,4 @@ +import { adminHttp } from './http' + +export const getCompanies = () => adminHttp.get('/admin/companies') +export const createCompany = (data) => adminHttp.post('/admin/companies', data) diff --git a/src/api/members.js b/src/api/members.js new file mode 100644 index 0000000..7a10123 --- /dev/null +++ b/src/api/members.js @@ -0,0 +1,3 @@ +import { adminHttp } from './http' + +export const getMembers = () => adminHttp.get('/admin/members') diff --git a/src/api/modules.js b/src/api/modules.js new file mode 100644 index 0000000..f54f398 --- /dev/null +++ b/src/api/modules.js @@ -0,0 +1,4 @@ +import { adminHttp } from './http' + +export const getModules = () => adminHttp.get('/admin/modules') +export const createModule = (data) => adminHttp.post('/admin/modules', data) diff --git a/src/api/permission-groups.js b/src/api/permission-groups.js new file mode 100644 index 0000000..3ebf8ea --- /dev/null +++ b/src/api/permission-groups.js @@ -0,0 +1,16 @@ +import { adminHttp } from './http' + +export const getPermissionGroups = () => adminHttp.get('/admin/permission-groups') +export const createPermissionGroup = (data) => adminHttp.post('/admin/permission-groups', data) + +export const addMemberToGroup = (groupKey, authentikSub) => + adminHttp.post(`/admin/permission-groups/${groupKey}/members/${authentikSub}`) + +export const removeMemberFromGroup = (groupKey, authentikSub) => + adminHttp.delete(`/admin/permission-groups/${groupKey}/members/${authentikSub}`) + +export const groupGrant = (groupKey, data) => + adminHttp.post(`/admin/permission-groups/${groupKey}/permissions/grant`, data) + +export const groupRevoke = (groupKey, data) => + adminHttp.post(`/admin/permission-groups/${groupKey}/permissions/revoke`, data) diff --git a/src/api/sites.js b/src/api/sites.js new file mode 100644 index 0000000..674bddf --- /dev/null +++ b/src/api/sites.js @@ -0,0 +1,4 @@ +import { adminHttp } from './http' + +export const getSites = () => adminHttp.get('/admin/sites') +export const createSite = (data) => adminHttp.post('/admin/sites', data) diff --git a/src/api/systems.js b/src/api/systems.js new file mode 100644 index 0000000..6d90cd7 --- /dev/null +++ b/src/api/systems.js @@ -0,0 +1,4 @@ +import { adminHttp } from './http' + +export const getSystems = () => adminHttp.get('/admin/systems') +export const createSystem = (data) => adminHttp.post('/admin/systems', data) diff --git a/src/pages/AuthCallbackPage.vue b/src/pages/AuthCallbackPage.vue index d499733..4485362 100644 --- a/src/pages/AuthCallbackPage.vue +++ b/src/pages/AuthCallbackPage.vue @@ -1,55 +1,73 @@ diff --git a/src/pages/admin/CompaniesPage.vue b/src/pages/admin/CompaniesPage.vue new file mode 100644 index 0000000..5744050 --- /dev/null +++ b/src/pages/admin/CompaniesPage.vue @@ -0,0 +1,96 @@ + + + diff --git a/src/pages/admin/MembersPage.vue b/src/pages/admin/MembersPage.vue new file mode 100644 index 0000000..ca06b61 --- /dev/null +++ b/src/pages/admin/MembersPage.vue @@ -0,0 +1,53 @@ + + + diff --git a/src/pages/admin/ModulesPage.vue b/src/pages/admin/ModulesPage.vue new file mode 100644 index 0000000..416db1f --- /dev/null +++ b/src/pages/admin/ModulesPage.vue @@ -0,0 +1,100 @@ + + + diff --git a/src/pages/admin/PermissionGroupsPage.vue b/src/pages/admin/PermissionGroupsPage.vue new file mode 100644 index 0000000..19517f4 --- /dev/null +++ b/src/pages/admin/PermissionGroupsPage.vue @@ -0,0 +1,296 @@ + + + diff --git a/src/pages/admin/SitesPage.vue b/src/pages/admin/SitesPage.vue new file mode 100644 index 0000000..7a87dd1 --- /dev/null +++ b/src/pages/admin/SitesPage.vue @@ -0,0 +1,100 @@ + + + diff --git a/src/pages/admin/SystemsPage.vue b/src/pages/admin/SystemsPage.vue new file mode 100644 index 0000000..305cbc5 --- /dev/null +++ b/src/pages/admin/SystemsPage.vue @@ -0,0 +1,96 @@ + + + diff --git a/src/pages/permissions/PermissionAdminPage.vue b/src/pages/permissions/PermissionAdminPage.vue index 935442a..c1de8bb 100644 --- a/src/pages/permissions/PermissionAdminPage.vue +++ b/src/pages/permissions/PermissionAdminPage.vue @@ -57,13 +57,19 @@ - + + + + - + - - + + + + + @@ -115,13 +121,19 @@ - + + + + - + - - + + + + + @@ -207,6 +219,7 @@ const grantForm = reactive({ display_name: '', scope_type: '', scope_id: '', + system: '', module: '', action: '' }) @@ -218,7 +231,7 @@ const grantRules = { display_name: [required], scope_type: [required], scope_id: [required], - module: [required], + system: [required], action: [required] } @@ -255,6 +268,7 @@ const revokeForm = reactive({ authentik_sub: '', scope_type: '', scope_id: '', + system: '', module: '', action: '' }) @@ -263,7 +277,7 @@ const revokeRules = { authentik_sub: [required], scope_type: [required], scope_id: [required], - module: [required], + system: [required], action: [required] } diff --git a/src/pages/permissions/PermissionSnapshotPage.vue b/src/pages/permissions/PermissionSnapshotPage.vue index 1e735dc..59b5e94 100644 --- a/src/pages/permissions/PermissionSnapshotPage.vue +++ b/src/pages/permissions/PermissionSnapshotPage.vue @@ -33,9 +33,10 @@ border class="w-full shadow-sm" > - - - + + + + diff --git a/src/router/index.js b/src/router/index.js index fe08486..dbb70ee 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -29,6 +29,36 @@ const routes = [ path: '/admin/permissions', name: 'admin-permissions', component: () => import('@/pages/permissions/PermissionAdminPage.vue') + }, + { + path: '/admin/systems', + name: 'admin-systems', + component: () => import('@/pages/admin/SystemsPage.vue') + }, + { + path: '/admin/modules', + name: 'admin-modules', + component: () => import('@/pages/admin/ModulesPage.vue') + }, + { + path: '/admin/companies', + name: 'admin-companies', + component: () => import('@/pages/admin/CompaniesPage.vue') + }, + { + path: '/admin/sites', + name: 'admin-sites', + component: () => import('@/pages/admin/SitesPage.vue') + }, + { + path: '/admin/members', + name: 'admin-members', + component: () => import('@/pages/admin/MembersPage.vue') + }, + { + path: '/admin/permission-groups', + name: 'admin-permission-groups', + component: () => import('@/pages/admin/PermissionGroupsPage.vue') } ] diff --git a/src/stores/admin.js b/src/stores/admin.js new file mode 100644 index 0000000..f802f47 --- /dev/null +++ b/src/stores/admin.js @@ -0,0 +1,39 @@ +import { defineStore } from 'pinia' +import { ref } from 'vue' +import { getSystems } from '@/api/systems' +import { getModules } from '@/api/modules' +import { getCompanies } from '@/api/companies' +import { getSites } from '@/api/sites' + +export const useAdminStore = defineStore('admin', () => { + const systems = ref([]) + const modules = ref([]) + const companies = ref([]) + const sites = ref([]) + + async function loadAllData() { + try { + const [sysRes, modRes, comRes, siteRes] = await Promise.all([ + getSystems(), + getModules(), + getCompanies(), + getSites() + ]) + systems.value = sysRes.data || [] + modules.value = modRes.data || [] + companies.value = comRes.data || [] + sites.value = siteRes.data || [] + } catch (err) { + console.error('Error loading admin data:', err) + throw err + } + } + + return { + systems, + modules, + companies, + sites, + loadAllData + } +})