feat(members): split username/display_name, sync updates to authentik, add password reset API and refresh docs
This commit is contained in:
@@ -3,6 +3,7 @@ import { adminHttp } from './http'
|
||||
export const getMembers = () => adminHttp.get('/admin/members')
|
||||
export const upsertMember = (data) => adminHttp.post('/admin/members/upsert', data)
|
||||
export const updateMember = (authentikSub, data) => adminHttp.patch(`/admin/members/${authentikSub}`, data)
|
||||
export const resetMemberPassword = (authentikSub) => adminHttp.post(`/admin/members/${authentikSub}/password/reset`)
|
||||
export const getMemberPermissionGroups = (authentikSub) => adminHttp.get(`/admin/members/${authentikSub}/permission-groups`)
|
||||
export const setMemberPermissionGroups = (authentikSub, groupKeys) =>
|
||||
adminHttp.put(`/admin/members/${authentikSub}/permission-groups`, { group_keys: groupKeys })
|
||||
|
||||
@@ -14,20 +14,23 @@
|
||||
<el-table v-else :data="members" stripe border class="w-full shadow-sm">
|
||||
<template #empty><el-empty description="目前無會員" /></template>
|
||||
<el-table-column prop="authentik_sub" label="Authentik Sub" min-width="260" />
|
||||
<el-table-column prop="username" label="Username" min-width="160" />
|
||||
<el-table-column prop="email" label="Email" min-width="220" />
|
||||
<el-table-column prop="display_name" label="顯示名稱" min-width="180" />
|
||||
<el-table-column prop="is_active" label="啟用" width="100">
|
||||
<template #default="{ row }">{{ row.is_active ? '是' : '否' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="120">
|
||||
<el-table-column label="操作" width="220">
|
||||
<template #default="{ row }">
|
||||
<el-button size="small" @click="openEdit(row)">編輯</el-button>
|
||||
<el-button size="small" type="warning" @click="handleResetPassword(row)">重設密碼</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-dialog v-model="showCreateDialog" title="新增會員" @close="resetCreateForm">
|
||||
<el-form ref="createFormRef" :model="createForm" :rules="createRules" label-width="120px">
|
||||
<el-form-item label="Username" prop="username"><el-input v-model="createForm.username" /></el-form-item>
|
||||
<el-form-item label="Email" prop="email"><el-input v-model="createForm.email" /></el-form-item>
|
||||
<el-form-item label="顯示名稱" prop="display_name"><el-input v-model="createForm.display_name" /></el-form-item>
|
||||
<el-form-item label="權限群組">
|
||||
@@ -47,6 +50,7 @@
|
||||
<el-dialog v-model="showEditDialog" title="編輯會員" @close="resetEditForm">
|
||||
<el-form :model="editForm" label-width="120px">
|
||||
<el-form-item label="Authentik Sub"><el-input :model-value="editForm.authentik_sub" disabled /></el-form-item>
|
||||
<el-form-item label="Username"><el-input v-model="editForm.username" /></el-form-item>
|
||||
<el-form-item label="Email"><el-input v-model="editForm.email" /></el-form-item>
|
||||
<el-form-item label="顯示名稱"><el-input v-model="editForm.display_name" /></el-form-item>
|
||||
<el-form-item label="權限群組">
|
||||
@@ -73,6 +77,7 @@ import {
|
||||
getMembers,
|
||||
upsertMember,
|
||||
updateMember,
|
||||
resetMemberPassword,
|
||||
getMemberPermissionGroups,
|
||||
setMemberPermissionGroups
|
||||
} from '@/api/members'
|
||||
@@ -88,6 +93,7 @@ const showCreateDialog = ref(false)
|
||||
const createFormRef = ref()
|
||||
const creating = ref(false)
|
||||
const createForm = ref({
|
||||
username: '',
|
||||
email: '',
|
||||
display_name: '',
|
||||
group_keys: [],
|
||||
@@ -95,6 +101,7 @@ const createForm = ref({
|
||||
sync_to_authentik: true
|
||||
})
|
||||
const createRules = {
|
||||
username: [{ required: true, message: '請輸入 Username', trigger: 'blur' }],
|
||||
email: [{ required: true, message: '請輸入 Email', trigger: 'blur' }]
|
||||
}
|
||||
|
||||
@@ -102,6 +109,7 @@ const showEditDialog = ref(false)
|
||||
const saving = ref(false)
|
||||
const editForm = ref({
|
||||
authentik_sub: '',
|
||||
username: '',
|
||||
email: '',
|
||||
display_name: '',
|
||||
group_keys: [],
|
||||
@@ -126,6 +134,7 @@ async function load() {
|
||||
|
||||
function resetCreateForm() {
|
||||
createForm.value = {
|
||||
username: '',
|
||||
email: '',
|
||||
display_name: '',
|
||||
group_keys: [],
|
||||
@@ -137,6 +146,7 @@ function resetCreateForm() {
|
||||
async function openEdit(row) {
|
||||
editForm.value = {
|
||||
authentik_sub: row.authentik_sub,
|
||||
username: row.username || '',
|
||||
email: row.email || '',
|
||||
display_name: row.display_name || '',
|
||||
group_keys: [],
|
||||
@@ -155,6 +165,7 @@ async function openEdit(row) {
|
||||
function resetEditForm() {
|
||||
editForm.value = {
|
||||
authentik_sub: '',
|
||||
username: '',
|
||||
email: '',
|
||||
display_name: '',
|
||||
group_keys: [],
|
||||
@@ -189,6 +200,7 @@ async function handleEdit() {
|
||||
saving.value = true
|
||||
try {
|
||||
await updateMember(editForm.value.authentik_sub, {
|
||||
username: editForm.value.username || null,
|
||||
email: editForm.value.email || null,
|
||||
display_name: editForm.value.display_name || null,
|
||||
is_active: editForm.value.is_active,
|
||||
@@ -206,5 +218,21 @@ async function handleEdit() {
|
||||
}
|
||||
}
|
||||
|
||||
async function handleResetPassword(row) {
|
||||
try {
|
||||
const res = await resetMemberPassword(row.authentik_sub)
|
||||
const pwd = res.data?.temporary_password || ''
|
||||
if (!pwd) {
|
||||
ElMessage.success('密碼已重設')
|
||||
return
|
||||
}
|
||||
await navigator.clipboard.writeText(pwd)
|
||||
ElMessage.success(`已重設密碼,臨時密碼已複製:${pwd}`)
|
||||
} catch (err) {
|
||||
const detail = err.response?.data?.detail
|
||||
ElMessage.error(detail || '重設密碼失敗')
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(load)
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user