1
This commit is contained in:
296
Design/frontend_Design/PersonnelManagementPage_Design.md
Normal file
296
Design/frontend_Design/PersonnelManagementPage_Design.md
Normal file
@@ -0,0 +1,296 @@
|
||||
# 人员管理页面设计文档
|
||||
|
||||
## 1. 页面概述
|
||||
|
||||
人员管理页面是提供给系统管理员(ADMIN)用于管理所有用户账户的界面。其核心功能包括展示用户列表、添加新用户、编辑现有用户信息、更改用户角色与状态,以及搜索和筛选用户。
|
||||
|
||||
## 2. 页面布局
|
||||
|
||||

|
||||
|
||||
### 2.1 布局结构
|
||||
|
||||
页面采用经典的后台管理布局,与任务管理、反馈管理页面保持一致:
|
||||
- **顶部**: 操作区域,包含"添加用户"按钮。
|
||||
- **中部**: 筛选和搜索区域,支持按用户名、角色或状态进行搜索。
|
||||
- **下部**: 用户数据表格,展示所有用户及其关键信息,并提供行内操作。
|
||||
- **底部**: 分页组件。
|
||||
|
||||
## 3. 组件结构
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div class="personnel-management-page">
|
||||
<el-page-header title="人员管理" content="系统用户列表" />
|
||||
|
||||
<el-card class="page-container">
|
||||
<!-- 搜索与操作区域 -->
|
||||
<div class="table-toolbar">
|
||||
<el-form :model="filters" inline class="filter-form">
|
||||
<el-form-item>
|
||||
<el-input v-model="filters.name" placeholder="按姓名或用户名搜索" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-select v-model="filters.role" placeholder="按角色筛选" clearable>
|
||||
<el-option label="管理员" value="ADMIN" />
|
||||
<el-option label="主管" value="SUPERVISOR" />
|
||||
<el-option label="网格员" value="GRID_WORKER" />
|
||||
<el-option label="决策者" value="DECISION_MAKER" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="action-buttons">
|
||||
<el-button type="primary" icon="Plus" @click="handleCreateUser">添加用户</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 用户表格 -->
|
||||
<el-table :data="users" v-loading="loading" stripe>
|
||||
<el-table-column prop="username" label="用户名" />
|
||||
<el-table-column prop="name" label="姓名" />
|
||||
<el-table-column prop="role" label="角色">
|
||||
<template #default="{ row }">
|
||||
<span>{{ formatRole(row.role) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="email" label="邮箱" />
|
||||
<el-table-column prop="status" label="状态">
|
||||
<template #default="{ row }">
|
||||
<el-switch
|
||||
v-model="row.isActive"
|
||||
@change="handleStatusChange(row)"
|
||||
:loading="row.statusChanging"
|
||||
active-text="启用"
|
||||
inactive-text="禁用"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="handleEdit(row)">编辑</el-button>
|
||||
<el-popconfirm title="确定要删除该用户吗?" @confirm="handleDelete(row)">
|
||||
<template #reference>
|
||||
<el-button link type="danger">删除</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<el-pagination
|
||||
v-if="total > 0"
|
||||
class="pagination-container"
|
||||
:current-page="pagination.page"
|
||||
:page-size="pagination.pageSize"
|
||||
:total="total"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</el-card>
|
||||
|
||||
<!-- 用户表单对话框 -->
|
||||
<UserFormDialog
|
||||
v-model="dialogVisible"
|
||||
:user-id="selectedUserId"
|
||||
@success="onFormSuccess"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
## 4. 数据结构
|
||||
|
||||
```typescript
|
||||
// 用户筛选条件
|
||||
interface UserFilters {
|
||||
name?: string;
|
||||
role?: 'ADMIN' | 'SUPERVISOR' | 'GRID_WORKER' | 'DECISION_MAKER';
|
||||
}
|
||||
|
||||
// 用户列表项
|
||||
interface UserListItem {
|
||||
id: number;
|
||||
username: string;
|
||||
name: string;
|
||||
email: string;
|
||||
role: string;
|
||||
isActive: boolean;
|
||||
statusChanging?: boolean; // 用于控制 Switch 的 loading 状态
|
||||
}
|
||||
|
||||
// 用户表单数据 (用于对话框)
|
||||
interface UserFormData {
|
||||
id?: number;
|
||||
username: string;
|
||||
name: string;
|
||||
email: string;
|
||||
role: string;
|
||||
password?: string; // 创建时需要,编辑时可选
|
||||
}
|
||||
```
|
||||
|
||||
## 5. 状态管理
|
||||
|
||||
```typescript
|
||||
// 组件内状态
|
||||
const filters = ref<UserFilters>({});
|
||||
const pagination = ref({ page: 1, pageSize: 10 });
|
||||
const dialogVisible = ref(false);
|
||||
const selectedUserId = ref<number | null>(null);
|
||||
|
||||
// 全局状态 (Pinia Store)
|
||||
const personnelStore = usePersonnelStore();
|
||||
const { users, total, loading } = storeToRefs(personnelStore);
|
||||
```
|
||||
|
||||
## 6. 交互逻辑
|
||||
|
||||
### 6.1 CRUD 操作
|
||||
|
||||
```typescript
|
||||
const fetchUsers = () => {
|
||||
personnelStore.fetchUsers({ ...filters.value, ...pagination.value });
|
||||
};
|
||||
|
||||
onMounted(fetchUsers);
|
||||
|
||||
const handleSearch = () => {
|
||||
pagination.value.page = 1;
|
||||
fetchUsers();
|
||||
};
|
||||
|
||||
const handleCreateUser = () => {
|
||||
selectedUserId.value = null;
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
const handleEdit = (user: UserListItem) => {
|
||||
selectedUserId.value = user.id;
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
const handleDelete = async (user: UserListItem) => {
|
||||
await personnelStore.deleteUser(user.id);
|
||||
ElMessage.success('用户删除成功');
|
||||
fetchUsers(); // 刷新列表
|
||||
};
|
||||
|
||||
const handleStatusChange = async (user: UserListItem) => {
|
||||
user.statusChanging = true;
|
||||
try {
|
||||
await personnelStore.updateUserStatus(user.id, user.isActive);
|
||||
ElMessage.success('状态更新成功');
|
||||
} catch {
|
||||
// 失败时将开关拨回原位
|
||||
user.isActive = !user.isActive;
|
||||
} finally {
|
||||
user.statusChanging = false;
|
||||
}
|
||||
};
|
||||
|
||||
const onFormSuccess = () => {
|
||||
dialogVisible.value = false;
|
||||
fetchUsers();
|
||||
};
|
||||
```
|
||||
|
||||
### 6.2 辅助函数
|
||||
|
||||
```typescript
|
||||
const formatRole = (role: string) => {
|
||||
const roleMap = {
|
||||
ADMIN: '管理员',
|
||||
SUPERVISOR: '主管',
|
||||
GRID_WORKER: '网格员',
|
||||
DECISION_MAKER: '决策者'
|
||||
};
|
||||
return roleMap[role] || '未知角色';
|
||||
};
|
||||
```
|
||||
|
||||
## 7. API 调用
|
||||
|
||||
```typescript
|
||||
// api/personnel.ts
|
||||
export const personnelApi = {
|
||||
getUsers: (params) => apiClient.get('/personnel', { params }),
|
||||
getUserById: (id: number) => apiClient.get(`/personnel/${id}`),
|
||||
createUser: (data: UserFormData) => apiClient.post('/personnel', data),
|
||||
updateUser: (id: number, data: UserFormData) => apiClient.put(`/personnel/${id}`, data),
|
||||
deleteUser: (id: number) => apiClient.delete(`/personnel/${id}`),
|
||||
};
|
||||
|
||||
// stores/personnel.ts
|
||||
export const usePersonnelStore = defineStore('personnel', {
|
||||
state: () => ({
|
||||
users: [] as UserListItem[],
|
||||
total: 0,
|
||||
loading: false,
|
||||
}),
|
||||
actions: {
|
||||
async fetchUsers(params) {
|
||||
this.loading = true;
|
||||
try {
|
||||
const { data } = await personnelApi.getUsers(params);
|
||||
this.users = data.items.map(u => ({ ...u, statusChanging: false }));
|
||||
this.total = data.total;
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
// ...其他 createUser, updateUser, deleteUser 等 actions
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## 8. 样式设计
|
||||
|
||||
```scss
|
||||
.personnel-management-page {
|
||||
padding: 24px;
|
||||
|
||||
.page-container {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.table-toolbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
margin-top: 24px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 9. 关联组件
|
||||
|
||||
### `UserFormDialog.vue`
|
||||
|
||||
用于创建和编辑用户的对话框组件。
|
||||
- **Props**: `modelValue`, `userId`
|
||||
- **功能**:
|
||||
- 如果 `userId` 存在,则为编辑模式,对话框打开时会根据 ID 加载用户信息。
|
||||
- 如果 `userId` 为空,则为创建模式。
|
||||
- 包含用户名、姓名、邮箱、角色和密码的表单字段。
|
||||
- 密码字段在编辑模式下为可选,并提示"留空则不修改密码"。
|
||||
- 表单提交时进行验证,并调用 store 中对应的 `createUser` 或 `updateUser` action。
|
||||
- 操作成功后,发出 `success` 事件。
|
||||
|
||||
## 10. 测试用例
|
||||
|
||||
- **集成测试**:
|
||||
- 测试能否成功添加一个新用户。
|
||||
- 测试能否成功编辑一个现有用户的信息(包括修改密码和不修改密码两种情况)。
|
||||
- 测试能否成功删除一个用户。
|
||||
- 测试启用/禁用开关是否能正确更新用户状态。
|
||||
- 测试搜索和筛选功能是否能正确过滤用户列表。
|
||||
Reference in New Issue
Block a user