From f661d432b41cd4e0f103e86aa8b573ec0745298a Mon Sep 17 00:00:00 2001 From: Lxq <19852720163@163.com> Date: Tue, 23 Dec 2025 14:02:53 +0800 Subject: [PATCH] =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E7=AE=A1=E7=90=86=E5=AE=8C?= =?UTF-8?q?=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/api/business/islandinfo.ts | 39 ++ .../src/api/{ => system}/department.ts | 0 .../src/api/{ => system}/manage-log.ts | 0 .../src/api/{ => system}/position.ts | 0 rc_autoplc_front/src/api/{ => system}/role.ts | 8 + rc_autoplc_front/src/api/system/user-role.ts | 67 +++ rc_autoplc_front/src/api/{ => system}/user.ts | 0 rc_autoplc_front/src/router/index.ts | 5 + rc_autoplc_front/src/views/Layout.vue | 6 +- .../src/views/department/index.vue | 4 +- .../src/views/manage-log/index.vue | 2 +- rc_autoplc_front/src/views/position/index.vue | 2 +- rc_autoplc_front/src/views/role/index.vue | 2 +- .../src/views/user-role/index.vue | 527 ++++++++++++++++++ rc_autoplc_front/src/views/user/index.vue | 167 +++++- 15 files changed, 819 insertions(+), 10 deletions(-) create mode 100644 rc_autoplc_front/src/api/business/islandinfo.ts rename rc_autoplc_front/src/api/{ => system}/department.ts (100%) rename rc_autoplc_front/src/api/{ => system}/manage-log.ts (100%) rename rc_autoplc_front/src/api/{ => system}/position.ts (100%) rename rc_autoplc_front/src/api/{ => system}/role.ts (83%) create mode 100644 rc_autoplc_front/src/api/system/user-role.ts rename rc_autoplc_front/src/api/{ => system}/user.ts (100%) create mode 100644 rc_autoplc_front/src/views/user-role/index.vue diff --git a/rc_autoplc_front/src/api/business/islandinfo.ts b/rc_autoplc_front/src/api/business/islandinfo.ts new file mode 100644 index 0000000..fbd1bae --- /dev/null +++ b/rc_autoplc_front/src/api/business/islandinfo.ts @@ -0,0 +1,39 @@ +import request from '@/utils/request' + +export function islandInfoadd(data: any) { + return request({ + url: '/islandInfo/add', + method: 'post', + data, + }) +} + +export function islandInfodel(id: string | number) { + return request({ + url: `/islandInfo/del/${id}`, + method: 'delete', + }) +} + +export function islandInfoupd(data: any) { + return request({ + url: '/islandInfo/update', + method: 'put', + data, + }) +} + +export function islandInfolist(data: any) { + return request({ + url: '/islandInfo/listPage', + method: 'get', + params: data, + }) +} + +export function islandInfobyid(id: string | number) { + return request({ + url: `/islandInfo/getById/${id}`, + method: 'get', + }) +} \ No newline at end of file diff --git a/rc_autoplc_front/src/api/department.ts b/rc_autoplc_front/src/api/system/department.ts similarity index 100% rename from rc_autoplc_front/src/api/department.ts rename to rc_autoplc_front/src/api/system/department.ts diff --git a/rc_autoplc_front/src/api/manage-log.ts b/rc_autoplc_front/src/api/system/manage-log.ts similarity index 100% rename from rc_autoplc_front/src/api/manage-log.ts rename to rc_autoplc_front/src/api/system/manage-log.ts diff --git a/rc_autoplc_front/src/api/position.ts b/rc_autoplc_front/src/api/system/position.ts similarity index 100% rename from rc_autoplc_front/src/api/position.ts rename to rc_autoplc_front/src/api/system/position.ts diff --git a/rc_autoplc_front/src/api/role.ts b/rc_autoplc_front/src/api/system/role.ts similarity index 83% rename from rc_autoplc_front/src/api/role.ts rename to rc_autoplc_front/src/api/system/role.ts index 0431cbc..5bbf493 100644 --- a/rc_autoplc_front/src/api/role.ts +++ b/rc_autoplc_front/src/api/system/role.ts @@ -36,4 +36,12 @@ export function rolebyid(id: string | number) { url: `/role/getById/${id}`, method: 'get', }) +} + +export function rleselect(data: any) { + return request({ + url: '/role/list', + method: 'get', + params: data, + }) } \ No newline at end of file diff --git a/rc_autoplc_front/src/api/system/user-role.ts b/rc_autoplc_front/src/api/system/user-role.ts new file mode 100644 index 0000000..9d65c25 --- /dev/null +++ b/rc_autoplc_front/src/api/system/user-role.ts @@ -0,0 +1,67 @@ +import request from '@/utils/request' + +// 新增用户角色关联 +export function userRoleAdd(data: any) { + return request({ + url: '/user-role/add', + method: 'post', + data, + }) +} + +// 根据ID删除用户角色关联 +export function userRoleDel(id: string | number) { + return request({ + url: `/user-role/del/${id}`, + method: 'delete', + }) +} + +// 分页查询用户角色关联列表 +export function userRoleList(data: any) { + return request({ + url: '/user-role/listPage', + method: 'get', + params: data, + }) +} + +// 根据ID查询用户角色关联 +export function userRoleById(id: string | number) { + return request({ + url: `/user-role/getById/${id}`, + method: 'get', + }) +} + +// 根据角色ID查询关联用户(先封装不调用) +export function userRoleByRoleId(roleId: string | number) { + return request({ + url: `/user-role/getByRoleId/${roleId}`, + method: 'get', + }) +} + +// 根据角色ID删除所有关联(先封装不调用) +export function userRoleDelByRoleId(roleId: string | number) { + return request({ + url: `/user-role/delByRoleId/${roleId}`, + method: 'delete', + }) +} + +// 根据用户ID查询关联角色(先封装不调用) +export function userRoleByUserId(userId: string | number) { + return request({ + url: `/user-role/getByUserId/${userId}`, + method: 'get', + }) +} + +// 根据用户ID删除所有关联(先封装不调用) +export function userRoleDelByUserId(userId: string | number) { + return request({ + url: `/user-role/delByUserId/${userId}`, + method: 'delete', + }) +} diff --git a/rc_autoplc_front/src/api/user.ts b/rc_autoplc_front/src/api/system/user.ts similarity index 100% rename from rc_autoplc_front/src/api/user.ts rename to rc_autoplc_front/src/api/system/user.ts diff --git a/rc_autoplc_front/src/router/index.ts b/rc_autoplc_front/src/router/index.ts index ab5d519..b6c6386 100644 --- a/rc_autoplc_front/src/router/index.ts +++ b/rc_autoplc_front/src/router/index.ts @@ -32,6 +32,11 @@ const router = createRouter({ name: 'manage-log', component: () => import('../views/manage-log/index.vue'), }, + { + path: '/user-role', + name: 'user-role', + component: () => import('../views/user-role/index.vue'), + }, ], }, ], diff --git a/rc_autoplc_front/src/views/Layout.vue b/rc_autoplc_front/src/views/Layout.vue index df964a6..2a35ff0 100644 --- a/rc_autoplc_front/src/views/Layout.vue +++ b/rc_autoplc_front/src/views/Layout.vue @@ -56,6 +56,10 @@ 操作日志管理 + + + 用户角色管理 + @@ -72,7 +76,7 @@ import { ref, computed } from 'vue' import { useRouter, useRoute } from 'vue-router' import { ElMessage, ElMessageBox } from 'element-plus' -import { User, Setting, Avatar, OfficeBuilding, Briefcase, Document, CaretBottom } from '@element-plus/icons-vue' +import { User, Setting, Avatar, OfficeBuilding, Briefcase, Document, CaretBottom, UserFilled } from '@element-plus/icons-vue' import { useAuthStore } from '@/stores/auth' const router = useRouter() diff --git a/rc_autoplc_front/src/views/department/index.vue b/rc_autoplc_front/src/views/department/index.vue index a19370f..25c0e66 100644 --- a/rc_autoplc_front/src/views/department/index.vue +++ b/rc_autoplc_front/src/views/department/index.vue @@ -205,8 +205,8 @@ import { departmentadd, departmentdel, departtree, -} from '@/api/department' -import { userselect } from '@/api/user' +} from '@/api/system/department' +import { userselect } from '@/api/system/user' interface DeptItem { id?: number | string diff --git a/rc_autoplc_front/src/views/manage-log/index.vue b/rc_autoplc_front/src/views/manage-log/index.vue index 8451ae8..d0969b4 100644 --- a/rc_autoplc_front/src/views/manage-log/index.vue +++ b/rc_autoplc_front/src/views/manage-log/index.vue @@ -152,7 +152,7 @@ import { managelogdel, manageloglist, managelogupd, -} from '@/api/manage-log' +} from '@/api/system/manage-log' interface LogItem { id?: string | number diff --git a/rc_autoplc_front/src/views/position/index.vue b/rc_autoplc_front/src/views/position/index.vue index 294091b..ab692ac 100644 --- a/rc_autoplc_front/src/views/position/index.vue +++ b/rc_autoplc_front/src/views/position/index.vue @@ -127,7 +127,7 @@ import { onMounted, reactive, ref } from 'vue' import type { FormInstance, FormRules } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus' -import { positionadd, positionbyid, positiondel, positionlist, positionupd } from '@/api/position' +import { positionadd, positionbyid, positiondel, positionlist, positionupd } from '@/api/system/position' interface PositionItem { id?: number | string diff --git a/rc_autoplc_front/src/views/role/index.vue b/rc_autoplc_front/src/views/role/index.vue index 9e38163..5de6a59 100644 --- a/rc_autoplc_front/src/views/role/index.vue +++ b/rc_autoplc_front/src/views/role/index.vue @@ -111,7 +111,7 @@ import { onMounted, reactive, ref } from 'vue' import type { FormInstance, FormRules } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus' -import { roleadd, rolebyid, roledel, rolelist, roleupd } from '@/api/role' +import { roleadd, rolebyid, roledel, rolelist, roleupd } from '@/api/system/role' interface RoleItem { id?: number | string diff --git a/rc_autoplc_front/src/views/user-role/index.vue b/rc_autoplc_front/src/views/user-role/index.vue new file mode 100644 index 0000000..2e939c9 --- /dev/null +++ b/rc_autoplc_front/src/views/user-role/index.vue @@ -0,0 +1,527 @@ + + + + + + diff --git a/rc_autoplc_front/src/views/user/index.vue b/rc_autoplc_front/src/views/user/index.vue index 279a665..300e624 100644 --- a/rc_autoplc_front/src/views/user/index.vue +++ b/rc_autoplc_front/src/views/user/index.vue @@ -100,9 +100,10 @@ min-width="150" :formatter="formatCell" /> - + @@ -213,6 +214,31 @@ + + + + + + {{ role.roleName || role.roleCode }} + + + + @@ -220,9 +246,11 @@ import { onMounted, reactive, ref, computed } from 'vue' import type { FormInstance, FormRules } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus' -import { useradd, userbyid, userdel, userlist, userupd } from '@/api/user' -import { departtree } from '@/api/department' -import { positionselect } from '@/api/position' +import { useradd, userbyid, userdel, userlist, userupd } from '@/api/system/user' +import { departtree } from '@/api/system/department' +import { positionselect } from '@/api/system/position' +import { userRoleAdd, userRoleByUserId, userRoleDel } from '@/api/system/user-role' +import { rleselect } from '@/api/system/role' interface UserItem { id?: number | string @@ -253,6 +281,12 @@ interface PositionItem { posiCode?: string } +interface RoleItem { + id?: number | string + roleName?: string + roleCode?: string +} + const loading = ref(false) const submitLoading = ref(false) const tableData = ref([]) @@ -261,6 +295,12 @@ const deptTreeData = ref([]) const positionOptions = ref([]) const deptMap = ref>(new Map()) const posMap = ref>(new Map()) +const roleDialogVisible = ref(false) +const assignRoleLoading = ref(false) +const roleOptions = ref([]) +const selectedRoleIds = ref<(number | string)[]>([]) +const currentAssignUserId = ref(null) +const originalUserRoles = ref([]) // 保存用户原有的角色关联列表 const queryForm = reactive({ userName: '', @@ -638,9 +678,128 @@ const handleDelete = (row: UserItem) => { .catch(() => {}) } +// 加载角色列表 +const loadRoleList = async () => { + try { + const res: any = await rleselect({}) + const data = Array.isArray(res?.data) ? res.data : Array.isArray(res) ? res : [] + roleOptions.value = data + } catch (error) { + console.error('load role list error', error) + ElMessage.error('加载角色列表失败') + roleOptions.value = [] + } +} + +// 打开角色分配弹框 +const openRoleDialog = async (row: UserItem) => { + if (!row.id) { + ElMessage.warning('缺少用户ID') + return + } + currentAssignUserId.value = row.id + selectedRoleIds.value = [] + roleDialogVisible.value = true + + // 确保角色列表已加载 + if (roleOptions.value.length === 0) { + await loadRoleList() + } + + // 获取用户已有的角色 + try { + const res: any = await userRoleByUserId(row.id) + const data = res?.data ?? res ?? {} + + // 兼容多种返回格式 + const userRoles = Array.isArray(data) + ? data + : Array.isArray(data.data) + ? data.data + : Array.isArray(data.records) + ? data.records + : Array.isArray(data.list) + ? data.list + : [] + + // 保存原有的角色关联列表(包含ID) + originalUserRoles.value = userRoles + + // 提取已有角色的ID列表 + if (Array.isArray(userRoles) && userRoles.length > 0) { + selectedRoleIds.value = userRoles + .map((item: any) => item.roleId) + .filter((id: any) => id !== undefined && id !== null) + } else { + selectedRoleIds.value = [] + originalUserRoles.value = [] + } + } catch (error) { + console.error('load user roles error', error) + // 如果获取失败,不影响弹框打开,只是不预选角色 + originalUserRoles.value = [] + } +} + +// 分配角色 +const handleAssignRole = async () => { + if (!currentAssignUserId.value) { + ElMessage.warning('缺少用户ID') + return + } + + assignRoleLoading.value = true + try { + // 获取原有的角色ID列表 + const originalRoleIds = originalUserRoles.value + .map((item: any) => item.roleId) + .filter((id: any) => id !== undefined && id !== null) + + // 计算需要新增的角色(新选中但原来没有的) + const rolesToAdd = selectedRoleIds.value.filter( + (roleId) => !originalRoleIds.includes(roleId) + ) + + // 计算需要删除的角色(原来有但现在未选中的) + const rolesToDelete = originalUserRoles.value.filter( + (item: any) => !selectedRoleIds.value.includes(item.roleId) + ) + + // 执行新增操作 + const addPromises = rolesToAdd.map((roleId) => { + return userRoleAdd({ + userId: currentAssignUserId.value, + roleId: roleId, + remark: '', + }) + }) + + // 执行删除操作 + const deletePromises = rolesToDelete.map((item: any) => { + if (item.id) { + return userRoleDel(item.id) + } + return Promise.resolve() + }) + + // 等待所有操作完成 + await Promise.all([...addPromises, ...deletePromises]) + + ElMessage.success('分配角色成功') + roleDialogVisible.value = false + } catch (error: any) { + console.error('assign role error', error) + const errorMsg = error?.message || error?.msg || '分配角色失败' + ElMessage.error(errorMsg) + } finally { + assignRoleLoading.value = false + } +} + onMounted(() => { loadDeptTree() loadPositionList() + loadRoleList() loadList() })