From 50c5afbbb75c1a04ac7a870ac336bb852c4f3409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=BF=94?= Date: Fri, 20 Mar 2026 08:00:49 +0800 Subject: [PATCH] refactor: UserManagement component with API services and role assignment --- .../src/views/system/UserManagement.vue | 197 ++++++++++++++---- 1 file changed, 162 insertions(+), 35 deletions(-) diff --git a/novalon-manage-web/src/views/system/UserManagement.vue b/novalon-manage-web/src/views/system/UserManagement.vue index 84c26ea..e57047d 100644 --- a/novalon-manage-web/src/views/system/UserManagement.vue +++ b/novalon-manage-web/src/views/system/UserManagement.vue @@ -48,6 +48,11 @@ label="用户名" sortable="custom" /> + @@ -75,7 +80,7 @@ /> + + + + + @@ -157,10 +211,12 @@ import { ref, reactive, onMounted } from 'vue' import { ElMessage, ElMessageBox } from 'element-plus' import { Search } from '@element-plus/icons-vue' -import request from '@/utils/request' +import { userApi, type User, type CreateUserRequest, type UpdateUserRequest } from '@/api/user.api' +import { roleApi, type Role } from '@/api/role.api' +import { handleApiError } from '@/utils/errorHandler' const loading = ref(false) -const dataSource = ref([]) +const dataSource = ref([]) const searchKeyword = ref('') const pagination = reactive({ current: 1, @@ -169,34 +225,41 @@ const pagination = reactive({ }) const sortInfo = reactive({ - sort: 'id', - order: 'asc' + sortBy: 'id', + sortOrder: 'asc' as 'asc' | 'desc' }) const modalVisible = ref(false) const modalTitle = ref('') -const formState = reactive({ - id: null as number | null, +const formState = reactive({ username: '', + password: '', + nickname: '', email: '', phone: '', - status: '0' + roles: [], + status: 'ACTIVE' }) +const roleDialogVisible = ref(false) +const selectedRoles = ref([]) +const allRoles = ref<{ key: number; label: string }[]>([]) +const currentUserId = ref(null) + const fetchData = async () => { loading.value = true try { - const res: any = await request.get('/users/page', { - params: { - page: pagination.current - 1, - size: pagination.pageSize, - sort: sortInfo.sort, - order: sortInfo.order, - keyword: searchKeyword.value || undefined - } + const res = await userApi.getPage({ + page: pagination.current - 1, + size: pagination.pageSize, + sortBy: sortInfo.sortBy, + sortOrder: sortInfo.sortOrder, + username: searchKeyword.value || undefined }) dataSource.value = res.content pagination.total = res.totalElements + } catch (error) { + handleApiError(error) } finally { loading.value = false } @@ -217,51 +280,84 @@ const handleSearch = () => { } const handleSortChange = ({ prop, order }: any) => { - sortInfo.sort = prop - sortInfo.order = order === 'ascending' ? 'asc' : 'desc' + sortInfo.sortBy = prop + sortInfo.sortOrder = order === 'ascending' ? 'asc' : 'desc' fetchData() } const handleAdd = () => { modalTitle.value = '新增用户' - Object.assign(formState, { id: null, username: '', email: '', phone: '', status: '0' }) + Object.assign(formState, { + id: undefined, + username: '', + password: '', + nickname: '', + email: '', + phone: '', + roles: [], + status: 'ACTIVE' + }) modalVisible.value = true } -const handleEdit = (row: any) => { +const handleEdit = (row: User) => { modalTitle.value = '编辑用户' - Object.assign(formState, row) + Object.assign(formState, { + id: row.id, + username: row.username, + nickname: row.nickname, + email: row.email, + phone: row.phone, + status: row.status, + roles: [] + }) modalVisible.value = true } -const handleDelete = async (row: any) => { +const handleDelete = async (row: User) => { try { await ElMessageBox.confirm('确定要删除该用户吗?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }) - await request.delete(`/users/${row.id}`) + await userApi.delete(row.id) ElMessage.success('删除成功') fetchData() - } catch { - // 用户取消或删除失败 + } catch (error) { + if (error !== 'cancel') { + handleApiError(error) + } } } const handleModalOk = async () => { try { if (formState.id) { - await request.put(`/users/${formState.id}`, formState) + const updateData: UpdateUserRequest = { + nickname: formState.nickname, + email: formState.email, + phone: formState.phone, + status: formState.status as 'ACTIVE' | 'INACTIVE' + } + await userApi.update(formState.id, updateData) ElMessage.success('更新成功') } else { - await request.post('/users', formState) + const createData: CreateUserRequest = { + username: formState.username, + password: formState.password, + nickname: formState.nickname, + email: formState.email, + phone: formState.phone, + roles: formState.roles + } + await userApi.create(createData) ElMessage.success('创建成功') } modalVisible.value = false fetchData() - } catch { - ElMessage.error('操作失败') + } catch (error) { + handleApiError(error) } } @@ -269,6 +365,37 @@ const handleModalCancel = () => { modalVisible.value = false } +const handleAssignRoles = async (row: User) => { + currentUserId.value = row.id + try { + const roles = await roleApi.getAll() + allRoles.value = roles.map((role: Role) => ({ + key: role.id, + label: role.name + })) + selectedRoles.value = row.roles.map((roleName: string) => { + const role = roles.find((r: Role) => r.name === roleName) + return role ? role.id : 0 + }).filter((id: number) => id > 0) + roleDialogVisible.value = true + } catch (error) { + handleApiError(error) + } +} + +const handleAssignRolesOk = async () => { + if (!currentUserId.value) return + + try { + await userApi.assignRoles(currentUserId.value, selectedRoles.value) + ElMessage.success('角色分配成功') + roleDialogVisible.value = false + fetchData() + } catch (error) { + handleApiError(error) + } +} + onMounted(() => { fetchData() })