feat(flow): unify member-group-permission admin workflow and docs
This commit is contained in:
@@ -154,6 +154,40 @@
|
||||
</el-form>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<el-card class="mt-6 shadow-sm">
|
||||
<template #header>
|
||||
<div class="flex items-center justify-between gap-3">
|
||||
<span class="font-medium text-gray-700">已授權列表(直接授權)</span>
|
||||
<div class="flex items-center gap-2">
|
||||
<el-input v-model="listFilters.keyword" placeholder="搜尋 email/sub/module/action" clearable style="width: 280px" @keyup.enter="loadDirectPermissionList" />
|
||||
<el-select v-model="listFilters.scope_type" clearable placeholder="Scope" style="width: 140px">
|
||||
<el-option label="Company" value="company" />
|
||||
<el-option label="Site" value="site" />
|
||||
</el-select>
|
||||
<el-button :loading="listLoading" @click="loadDirectPermissionList">查詢</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<el-table :data="directPermissions" stripe border class="w-full" v-loading="listLoading">
|
||||
<template #empty><el-empty description="目前沒有直接授權資料" /></template>
|
||||
<el-table-column prop="display_name" label="名稱" min-width="140" />
|
||||
<el-table-column prop="email" label="Email" min-width="200" />
|
||||
<el-table-column prop="authentik_sub" label="Sub" min-width="200" />
|
||||
<el-table-column prop="scope_type" label="Scope" width="90" />
|
||||
<el-table-column prop="scope_id" label="Scope ID" min-width="120" />
|
||||
<el-table-column prop="system" label="系統" width="100" />
|
||||
<el-table-column prop="module" label="模組" width="130" />
|
||||
<el-table-column prop="action" label="操作" width="100" />
|
||||
<el-table-column prop="created_at" label="建立時間" min-width="180" />
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button type="danger" size="small" @click="handleRevokeByRow(row)" :loading="revokeRowLoadingId === row.permission_id">撤銷</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -166,6 +200,7 @@ import { getModules } from '@/api/modules'
|
||||
import { getCompanies } from '@/api/companies'
|
||||
import { getSites } from '@/api/sites'
|
||||
import { getMembers } from '@/api/members'
|
||||
import { listDirectPermissions, revokeDirectPermissionById } from '@/api/permission-admin'
|
||||
|
||||
const permissionStore = usePermissionStore()
|
||||
|
||||
@@ -176,6 +211,10 @@ const companies = ref([])
|
||||
const sites = ref([])
|
||||
const members = ref([])
|
||||
const actionOptions = ['view', 'edit', 'manage', 'admin']
|
||||
const listFilters = reactive({ keyword: '', scope_type: '' })
|
||||
const listLoading = ref(false)
|
||||
const directPermissions = ref([])
|
||||
const revokeRowLoadingId = ref('')
|
||||
|
||||
// Grant
|
||||
const grantFormRef = ref()
|
||||
@@ -237,6 +276,7 @@ async function handleGrant() {
|
||||
const result = await permissionStore.grant({ ...grantForm })
|
||||
grantSuccess.value = `授權成功(ID: ${result.permission_id})`
|
||||
ElMessage.success('Grant 成功')
|
||||
await loadDirectPermissionList()
|
||||
} catch (err) {
|
||||
grantError.value = formatAdminError(err)
|
||||
} finally {
|
||||
@@ -305,6 +345,7 @@ async function handleRevoke() {
|
||||
const result = await permissionStore.revoke({ ...revokeForm })
|
||||
revokeSuccess.value = `撤銷成功(共刪除 ${result.deleted} 筆)`
|
||||
ElMessage.success('Revoke 成功')
|
||||
await loadDirectPermissionList()
|
||||
} catch (err) {
|
||||
revokeError.value = formatAdminError(err)
|
||||
} finally {
|
||||
@@ -356,6 +397,39 @@ async function loadCatalogs() {
|
||||
members.value = membersRes.data?.items || []
|
||||
}
|
||||
|
||||
async function loadDirectPermissionList() {
|
||||
listLoading.value = true
|
||||
try {
|
||||
const res = await listDirectPermissions({
|
||||
keyword: listFilters.keyword || undefined,
|
||||
scope_type: listFilters.scope_type || undefined,
|
||||
limit: 200,
|
||||
offset: 0
|
||||
})
|
||||
directPermissions.value = (res.data?.items || []).map(row => ({
|
||||
...row,
|
||||
created_at: row.created_at ? new Date(row.created_at).toLocaleString() : ''
|
||||
}))
|
||||
} catch (err) {
|
||||
ElMessage.error('載入權限列表失敗')
|
||||
} finally {
|
||||
listLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function handleRevokeByRow(row) {
|
||||
revokeRowLoadingId.value = row.permission_id
|
||||
try {
|
||||
await revokeDirectPermissionById(row.permission_id)
|
||||
ElMessage.success('已撤銷該筆授權')
|
||||
await loadDirectPermissionList()
|
||||
} catch (err) {
|
||||
ElMessage.error('撤銷失敗')
|
||||
} finally {
|
||||
revokeRowLoadingId.value = ''
|
||||
}
|
||||
}
|
||||
|
||||
watch(() => grantForm.scope_type, () => { grantForm.scope_id = '' })
|
||||
watch(() => grantForm.system, () => { grantForm.module = '' })
|
||||
watch(() => revokeForm.scope_type, () => { revokeForm.scope_id = '' })
|
||||
@@ -368,5 +442,7 @@ watch(() => grantForm.authentik_sub, (sub) => {
|
||||
grantForm.display_name = user.display_name || ''
|
||||
})
|
||||
|
||||
onMounted(loadCatalogs)
|
||||
onMounted(async () => {
|
||||
await Promise.all([loadCatalogs(), loadDirectPermissionList()])
|
||||
})
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user