This commit is contained in:
2026-08-10 15:36:53 +08:00
parent 5d97c7517a
commit f6556c57b5
54 changed files with 4107 additions and 170 deletions
+36 -28
View File
@@ -17,6 +17,12 @@ import ApiErrorMeta from '@/shared/components/ApiErrorMeta.vue'
import StatusBadge from '@/shared/components/StatusBadge.vue'
import DataTable, { type DataTableColumn } from '@/shared/components/DataTable.vue'
import QueryToolbar, { type QueryField, type QueryModel } from '@/shared/components/QueryToolbar.vue'
import AdminPage from '@/shared/components/AdminPage.vue'
import AppDialog from '@/shared/components/AppDialog.vue'
import FormSection from '@/shared/components/FormSection.vue'
import ListPageLayout from '@/shared/components/ListPageLayout.vue'
import LoadErrorState from '@/shared/components/LoadErrorState.vue'
import PageToolbar from '@/shared/components/PageToolbar.vue'
import { useUnsavedWorkRegistration } from '@/core/unsaved-work/useUnsavedWorkRegistration'
import { useAccessPreviewStore } from '@/core/access/accessPreview'
import { useAuthStore } from '@/core/auth/auth'
@@ -295,24 +301,27 @@ onMounted(loadInitialData)
</script>
<template>
<div class="business-page">
<el-alert v-if="loadError" type="error" :closable="false" show-icon role="alert">
<template #title>
<div class="api-error-alert-title"><span>{{ loadError.message }}</span><ApiErrorMeta :details="loadError" /></div>
<el-button link type="danger" @click="loadInitialData">重新加载</el-button>
<AdminPage as="div">
<PageToolbar title="内部用户" description="维护平台内部员工账号、平台角色和使用状态。" />
<ListPageLayout aria-label="内部用户管理">
<template #toolbar>
<QueryToolbar
v-model="filters"
class="surface-panel"
ariaLabel="用户筛选"
:fields="queryFields"
preference-key="internal-users-query"
@search="applyFilters"
/>
</template>
<template v-if="loadError" #state>
<LoadErrorState title="内部用户列表暂时无法加载" :message="loadError.message" :loading="loading" @retry="loadInitialData">
<template #details><ApiErrorMeta :details="loadError" /></template>
</LoadErrorState>
</template>
</el-alert>
<QueryToolbar
v-model="filters"
class="surface-panel"
ariaLabel="用户筛选"
:fields="queryFields"
preference-key="internal-users-query"
@search="applyFilters"
/>
<section class="surface-panel table-panel" :aria-busy="loading">
<section class="surface-panel table-panel" :aria-busy="loading">
<DataTable v-model:page="page" v-model:page-size="pageSize" :data="users" :columns="userColumns" preference-key="internal-users-table"
:loading="loading" :total="total" aria-label="内部用户列表" row-key="membershipId" empty-text="没有符合筛选条件的内部用户">
<template #toolbar-start><div><h2>内部用户列表 <span class="secondary-text">共 {{ total }} 条</span></h2><p>维护平台内部员工账号、平台角色和使用状态。</p></div></template>
@@ -340,11 +349,13 @@ onMounted(loadInitialData)
<template #status="{ row }"><StatusBadge :status="(row as PlatformManagedUser).status === 'ACTIVE' ? '正常' : '禁用'" /></template>
<template #lastLoginAt="{ row }">{{ formatLogin((row as PlatformManagedUser).lastLoginAt) }}</template>
</DataTable>
</section>
</section>
</ListPageLayout>
<el-dialog v-model="editorOpen" :title="editorLabel" width="min(760px, calc(100vw - 32px))" :close-on-click-modal="false" destroy-on-close>
<AppDialog v-model="editorOpen" :title="editorLabel" width="min(760px, calc(100vw - 32px))" destroy-on-close :confirm-loading="saving" :confirm-text="editingUser ? '保存修改' : '确认添加'" @confirm="saveUser">
<el-form ref="formRef" :model="form" :rules="formRules" label-position="top">
<div class="form-grid two-cols">
<FormSection title="用户资料" description="维护登录身份、联系方式与平台角色。">
<div class="form-grid two-cols">
<el-form-item label="用户名" prop="username" required>
<el-input v-model="form.username" :disabled="Boolean(editingUser)" placeholder="登录用户名" maxlength="64" />
</el-form-item>
@@ -372,9 +383,10 @@ onMounted(loadInitialData)
<el-form-item v-if="editingUser" label="最后登录">
<el-input :model-value="formatLogin(editingUser.lastLoginAt)" disabled />
</el-form-item>
</div>
</div>
</FormSection>
<template v-if="!editingUser || canResetPassword">
<FormSection v-if="!editingUser || canResetPassword" title="登录密码" description="密码为 8-64 位,并同时包含字母和数字。">
<el-checkbox v-if="editingUser" v-model="form.resetPassword">同时重置密码</el-checkbox>
<div v-if="!editingUser || form.resetPassword" class="form-grid two-cols password-fields">
<el-form-item :label="editingUser ? '新密码' : '初始密码'" prop="password" required>
@@ -384,14 +396,10 @@ onMounted(loadInitialData)
<el-input v-model="form.confirmPassword" type="password" show-password autocomplete="new-password" placeholder="再次输入密码" />
</el-form-item>
</div>
</template>
</FormSection>
</el-form>
<template #footer>
<el-button :disabled="saving" @click="editorOpen = false">取消</el-button>
<el-button type="primary" :loading="saving" @click="saveUser">{{ editingUser ? '保存修改' : '确认添加' }}</el-button>
</template>
</el-dialog>
</div>
</AppDialog>
</AdminPage>
</template>
<style scoped>