|
|
@@ -12,9 +12,10 @@
|
|
|
<el-table-column prop="roleName" label="角色名称" />
|
|
|
<el-table-column prop="remark" label="备注" />
|
|
|
<el-table-column prop="status" label="状态" />
|
|
|
- <el-table-column label="操作" width="180">
|
|
|
+ <el-table-column label="操作" width="260">
|
|
|
<template #default="{ row }">
|
|
|
<el-button link type="primary" @click="openDialog(row)">编辑</el-button>
|
|
|
+ <el-button link type="primary" @click="openPermissionDialog(row)">分配权限</el-button>
|
|
|
<el-button link type="danger" @click="handleDelete(row.id)">删除</el-button>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
@@ -36,24 +37,83 @@
|
|
|
<el-button type="primary" @click="handleSave">保存</el-button>
|
|
|
</template>
|
|
|
</el-dialog>
|
|
|
+ <el-dialog v-model="permissionVisible" :title="`分配权限 - ${currentRoleName || ''}`" width="560px">
|
|
|
+ <el-tree
|
|
|
+ ref="permissionTreeRef"
|
|
|
+ :data="menuTreeData"
|
|
|
+ node-key="id"
|
|
|
+ show-checkbox
|
|
|
+ check-strictly
|
|
|
+ default-expand-all
|
|
|
+ :props="{ label: 'menuName', children: 'children' }"
|
|
|
+ empty-text="暂无菜单数据"
|
|
|
+ />
|
|
|
+ <template #footer>
|
|
|
+ <el-button @click="permissionVisible = false">取消</el-button>
|
|
|
+ <el-button type="primary" @click="handleSavePermissions">保存权限</el-button>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import { onMounted, reactive, ref } from "vue";
|
|
|
+import { computed, nextTick, onMounted, reactive, ref } from "vue";
|
|
|
import { ElMessageBox } from "element-plus";
|
|
|
-import { deleteRoleApi, listRolesApi, saveRoleApi } from "../../api/modules";
|
|
|
+import { deleteRoleApi, getRoleMenuIdsApi, listMenusApi, listRolesApi, saveRoleApi, saveRoleMenuIdsApi } from "../../api/modules";
|
|
|
|
|
|
const keyword = ref("");
|
|
|
const tableData = ref([]);
|
|
|
const visible = ref(false);
|
|
|
+const permissionVisible = ref(false);
|
|
|
+const permissionTreeRef = ref();
|
|
|
+const menuOptions = ref([]);
|
|
|
+const currentRoleId = ref(null);
|
|
|
+const currentRoleName = ref("");
|
|
|
const form = reactive({ id: null, roleCode: "", roleName: "", remark: "", status: 1 });
|
|
|
|
|
|
+const menuTreeData = computed(() => buildMenuTree(menuOptions.value));
|
|
|
+
|
|
|
const resetForm = () => Object.assign(form, { id: null, roleCode: "", roleName: "", remark: "", status: 1 });
|
|
|
const loadData = async () => { tableData.value = await listRolesApi(keyword.value); };
|
|
|
const openDialog = (row) => { resetForm(); if (row) Object.assign(form, row); visible.value = true; };
|
|
|
const handleSave = async () => { await saveRoleApi({ ...form }); visible.value = false; await loadData(); };
|
|
|
const handleDelete = async (id) => { await ElMessageBox.confirm("确认删除该角色?", "提示"); await deleteRoleApi(id); await loadData(); };
|
|
|
+const loadMenus = async () => { menuOptions.value = await listMenusApi(""); };
|
|
|
+const openPermissionDialog = async (row) => {
|
|
|
+ currentRoleId.value = row.id;
|
|
|
+ currentRoleName.value = row.roleName;
|
|
|
+ if (!menuOptions.value.length) {
|
|
|
+ await loadMenus();
|
|
|
+ }
|
|
|
+ permissionVisible.value = true;
|
|
|
+ await nextTick();
|
|
|
+ permissionTreeRef.value?.setCheckedKeys([]);
|
|
|
+ const checkedKeys = await getRoleMenuIdsApi(row.id);
|
|
|
+ permissionTreeRef.value?.setCheckedKeys(checkedKeys || []);
|
|
|
+};
|
|
|
+const handleSavePermissions = async () => {
|
|
|
+ const checkedKeys = permissionTreeRef.value?.getCheckedKeys(false) || [];
|
|
|
+ await saveRoleMenuIdsApi(currentRoleId.value, { roleId: currentRoleId.value, menuIds: checkedKeys });
|
|
|
+ permissionVisible.value = false;
|
|
|
+};
|
|
|
+
|
|
|
+onMounted(async () => {
|
|
|
+ await Promise.all([loadData(), loadMenus()]);
|
|
|
+});
|
|
|
|
|
|
-onMounted(loadData);
|
|
|
+function buildMenuTree(items) {
|
|
|
+ const nodeMap = new Map();
|
|
|
+ const roots = [];
|
|
|
+ items.forEach((item) => {
|
|
|
+ nodeMap.set(item.id, { ...item, children: [] });
|
|
|
+ });
|
|
|
+ nodeMap.forEach((node) => {
|
|
|
+ if (node.parentId && nodeMap.has(node.parentId)) {
|
|
|
+ nodeMap.get(node.parentId).children.push(node);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ roots.push(node);
|
|
|
+ });
|
|
|
+ return roots;
|
|
|
+}
|
|
|
</script>
|