Commit 65ae3a6c authored by 张伯涛's avatar 张伯涛

角色模块数据权限功能完善

parent 0b1d0535
......@@ -16,7 +16,6 @@ export function getRolePage(
params: queryParams,
});
}
/**
* 获取角色下拉数据
*
......@@ -32,6 +31,15 @@ export function getRoleOptions(
});
}
/** 角色数据权限*/
export function dataScope(data) {
return request({
url: "/system/role/dataScope",
method: "put",
data,
headers: {},
});
}
/**
* 获取角色的菜单ID集合
*
......@@ -114,6 +122,13 @@ export function roleMenuTreeSelectMC(roleId: any) {
method: "get",
});
}
/** 根据角色ID查询部门树结构*/
export function roleDeptTreeSelect(roleId: any, menuId: any) {
return request({
url: "/system/dept/roleDeptTreeSelect/" + roleId + "/" + menuId,
method: "get",
});
}
/**
* 查询角色详细
*
......
......@@ -10,21 +10,24 @@ import {
changeRoleStatus,
treeSelect,
roleMenuTreeSelect,
getRole, roleMenuTreeSelectMC
getRole,
roleMenuTreeSelectMC,
roleDeptTreeSelect,
dataScope,
} from "@/api/role";
import { getMenuOptions } from "@/api/menu";
import {handleTree} from '@/utils/common'
import { RolePageVO, RoleForm, RoleQuery,permForm } from "@/api/role/types";
import { handleTree } from "@/utils/common";
import { RolePageVO, RoleForm, RoleQuery, permForm } from "@/api/role/types";
import { commonField } from "@/utils/commonField";
defineOptions({
name: "Role",
inheritAttrs: false,
});
const hasDelPerm = ref(['sys:role:delete']);
const hasResetPerm = ref(['sys:role:resetPwd']);
const hasUpdatePerm = ref(['sys:role:update']);
const hasAddPerm = ref(['sys:role:add']);
const hasExportPerm = ref(['sys:role:export']);
const hasDelPerm = ref(["sys:role:delete"]);
const hasResetPerm = ref(["sys:role:resetPwd"]);
const hasUpdatePerm = ref(["sys:role:update"]);
const hasAddPerm = ref(["sys:role:add"]);
const hasExportPerm = ref(["sys:role:export"]);
const queryFormRef = ref(ElForm);
const roleFormRef = ref(ElForm);
......@@ -34,54 +37,57 @@ const menuRef = ref(ElTree);
const loading = ref(false);
const ids = ref<number[]>([]);
const total = ref(0);
const menuOptions = ref([])
const updateMenu = ref([])
const menuOptions = ref([]);
let deptOptions = ref([]);
const customSizeTree = ref([]);
const updateMenu = ref([]);
const menu = ref(ElTree);
const dept = ref(ElTree);
const defaultProps = reactive({
children: 'children',
label: 'label'
})
children: "children",
label: "label",
});
const form = reactive<permForm>({
roleName: '',
menuName: '',
dataScope: '',
})
roleName: "",
menuName: "",
dataScope: "",
});
const queryParams = reactive<RoleQuery>({
pageNum: 1,
pageSize: 10,
});
const statusOptions = reactive([
{
dictLabel: '启用',
dictValue: '1'
dictLabel: "启用",
dictValue: "1",
},
{
dictLabel: '停用',
dictValue: '0'
}
])
dictLabel: "停用",
dictValue: "0",
},
]);
const dataScopeOptions = reactive([
{
value: '1',
label: '全部数据权限'
value: "1",
label: "全部数据权限",
},
{
value: '2',
label: '自定数据权限'
value: "2",
label: "自定数据权限",
},
{
value: '3',
label: '本部门数据权限'
value: "3",
label: "本部门数据权限",
},
{
value: '4',
label: '本部门及以下数据权限'
value: "4",
label: "本部门及以下数据权限",
},
{
value: '5',
label: '仅本人数据权限'
}
])
value: "5",
label: "仅本人数据权限",
},
]);
const roleList = ref<RolePageVO[]>();
const dialog = reactive({
......@@ -91,26 +97,28 @@ const dialog = reactive({
const formData = reactive<RoleForm>({
businessId: undefined,
roleName: '',
roleKey: '',
roleName: "",
roleKey: "",
roleSort: 0,
flag: '1',
flag: "1",
menuIds: [],
remarks: '',
remarks: "",
});
const validatePass = (rule, value, callback) => {
const arr = menu.value.getCheckedKeys()
const arr = menu.value.getCheckedKeys();
if (arr.length === 0 || !arr) {
callback(new Error('请选择菜单权限'))
callback(new Error("请选择菜单权限"));
} else {
callback()
callback();
}
}
};
const rules = reactive({
roleName: [{ required: true, message: "请输入角色名称", trigger: "blur" }],
roleKey: [{ required: true, message: "请输入权限字符", trigger: "blur" }],
roleSort: [{ required: true, message: "请输入角色排序", trigger: "blur" }],
menuIds: [{ required: true, validator: validatePass, trigger: ["blur","change"] }]
menuIds: [
{ required: true, validator: validatePass, trigger: ["blur", "change"] },
],
});
const openDataScope = ref(false);
......@@ -127,7 +135,7 @@ let checkedRole: CheckedRole = reactive({});
function handleQuery() {
loading.value = true;
getRolePage(queryParams)
.then(res => {
.then((res) => {
roleList.value = res.rows;
total.value = res.total;
})
......@@ -148,52 +156,55 @@ function handleSelectionChange(selection: any) {
}
/** 菜单权限check事件*/
function handleCheck(data, { checkedKeys }) {
console.log('data',data)
console.log('checkedKeys',checkedKeys)
if (checkedKeys.includes(data.id)) { // 选中
const node = menu.value.getNode(data.id) // getNode(node-key)
console.log('node',node)
selectChildren(data, true) // 选中子节点
parentNodesChange(node) // 选中父节点
console.log("data", data);
console.log("checkedKeys", checkedKeys);
if (checkedKeys.includes(data.id)) {
// 选中
const node = menu.value.getNode(data.id); // getNode(node-key)
console.log("node", node);
selectChildren(data, true); // 选中子节点
parentNodesChange(node); // 选中父节点
} else {
selectChildren(data, false) // 取消子节点
selectChildren(data, false); // 取消子节点
}
}
/** 选中子节点*/
function selectChildren(data, checked) {
data && data.children && data.children.map(item => {
menu.value.setChecked(item.id, checked)
if (data.children) {
selectChildren(item, checked)
}
})
data &&
data.children &&
data.children.map((item) => {
menu.value.setChecked(item.id, checked);
if (data.children) {
selectChildren(item, checked);
}
});
}
/** 父级递归*/
function parentNodesChange(node) {
if (node.parent) {
for (const key in node) {
if (key === 'id') {
menu.value.setChecked(node, true)
if (key === "id") {
menu.value.setChecked(node, true);
}
}
if (node.parent && node.id !== 0) {
parentNodesChange(node.parent)
parentNodesChange(node.parent);
}
}
}
/** 打开角色表单弹窗 */
function openDialog(roleId?: number) {
dialog.visible = true;
getMenuTreeSelect() // 查询菜单树结构
getMenuTreeSelect(); // 查询菜单树结构
if (roleId) {
const roleMenu = getRoleMenuTreeSelect(roleId)
const roleMenu = getRoleMenuTreeSelect(roleId);
dialog.title = "修改角色";
getRoleForm(roleId).then(({ data }) => {
Object.assign(formData, data);
nextTick(() => {
roleMenu.then(res => {
menu.value.setCheckedKeys(res.data.checkedKeys)
})
roleMenu.then((res) => {
menu.value.setCheckedKeys(res.data.checkedKeys);
});
});
});
} else {
......@@ -202,29 +213,29 @@ function openDialog(roleId?: number) {
}
/** 根据角色ID查询菜单树结构 */
function getRoleMenuTreeSelect(roleId) {
return roleMenuTreeSelect(roleId).then(response => {
menuOptions.value = response.data.menus
return response
})
return roleMenuTreeSelect(roleId).then((response) => {
menuOptions.value = response.data.menus;
return response;
});
}
/** 查询菜单树结构*/
function getMenuTreeSelect() {
treeSelect().then(res => {
menuOptions.value = res.data
updateMenu.value.push(menuOptions.value[0].id)
})
treeSelect().then((res) => {
menuOptions.value = res.data;
updateMenu.value.push(menuOptions.value[0].id);
});
}
/** 角色保存提交 */
function handleSubmit() {
updateMenu.value = []
updateMenu.value = [];
roleFormRef.value.validate((valid: any) => {
if (valid) {
loading.value = true;
formData.menuCheckStrictly = 0
formData.menuCheckStrictly = 0;
const roleId = formData.businessId;
if (roleId) {
formData.menuIds = getMenuAllCheckedKeys()
updateRole(roleId,formData)
formData.menuIds = getMenuAllCheckedKeys();
updateRole(roleId, formData)
.then(() => {
ElMessage.success("修改成功");
closeDialog();
......@@ -232,7 +243,7 @@ function handleSubmit() {
})
.finally(() => (loading.value = false));
} else {
formData.menuIds = getMenuAllCheckedKeys()
formData.menuIds = getMenuAllCheckedKeys();
addRole(formData)
.then(() => {
ElMessage.success("新增成功");
......@@ -247,11 +258,11 @@ function handleSubmit() {
/** 所有菜单节点数据 */
function getMenuAllCheckedKeys() {
// 目前被选中的菜单节点
const checkedKeys = menu.value.getHalfCheckedKeys()
const checkedKeys = menu.value.getHalfCheckedKeys();
// 半选中的菜单节点
const halfCheckedKeys = menu.value.getCheckedKeys()
checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys)
return checkedKeys
const halfCheckedKeys = menu.value.getCheckedKeys();
checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
return checkedKeys;
}
/** 关闭表单弹窗 */
function closeDialog() {
......@@ -260,39 +271,40 @@ function closeDialog() {
}
/** 角色状态修改*/
function handleStatusChange(row: any) {
const text = row.flag === '1' ? '启用' : '停用'
const text = row.flag === "1" ? "启用" : "停用";
ElMessageBox.confirm("是否确认操作?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
return changeRoleStatus(row.businessId, row.flag)
}).then(() => {
ElMessage.success(text + '成功');
})
return changeRoleStatus(row.businessId, row.flag);
})
.then(() => {
ElMessage.success(text + "成功");
})
.catch(function () {
row.flag = row.flag === '0' ? '1' : '0'
row.flag = row.flag === "0" ? "1" : "0";
});
}
/** 重置表单 */
function resetForm() {
roleFormRef.value.resetFields();
if (menu.value !== undefined) {
menu.value.setCheckedKeys([])
menu.value.setCheckedKeys([]);
}
formData.businessId = undefined;
formData.roleName = '';
formData.roleKey = '';
formData.roleName = "";
formData.roleKey = "";
formData.roleSort = 0;
formData.flag = '1';
formData.flag = "1";
formData.menuIds = [];
formData.remarks = '';
formData.remarks = "";
}
/** 删除角色 */
function handleDelete(row?: any) {
const roleIds = row.businessId
const roleIds = row.businessId;
ElMessageBox.confirm("是否确认操作?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
......@@ -312,36 +324,112 @@ function handleDelete(row?: any) {
function handleMenu(row: RolePageVO) {
const roleId = row.businessId;
// 查询菜单列表树形显示
roleMenuTreeSelectMC(roleId).then(res => {
menuList.value = handleTree(res.data, 'businessId','','','')
getRole(roleId).then(response => {
roleMenuTreeSelectMC(roleId).then((res) => {
menuList.value = handleTree(res.data, "businessId", "", "", "");
getRole(roleId).then((response) => {
Object.assign(form, response.data);
openDataScope.value = true
})
})
openDataScope.value = true;
});
});
}
/** 分配数据权限操作 */
function handleDataScope(row) {
deptOptions.value = [];
form.dataScope = undefined;
const roleId = form.businessId;
form.menuId = row.businessId;
form.menuName = row.menuName;
const roleDeptTreeSelect = getRoleDeptTreeSelect(roleId, form.menuId);
nextTick(() => {
roleDeptTreeSelect.then((res) => {
dept.value.setCheckedKeys(res.data.checkedKeys);
});
});
}
/** 根据角色ID和菜单ID查询部门树结构 */
function getRoleDeptTreeSelect(roleId, menuId) {
return roleDeptTreeSelect(roleId, menuId).then((response) => {
form.deptCheckStrictly = response.data.deptCheckStrictly;
deptOptions = response.data.depts;
for (let i = 0; i < deptOptions[0].children.length; i++) {
customSizeTree.value.push(deptOptions[0].children[0].id);
}
form.dataScope = dataScopeOptions[response.data.dataScope - 1].value;
return response;
});
}
/** 数据权限的树状菜单*/
function handleDeptCheckChange(data, check) {
// 是否包含子节点
if (data.children !== undefined && data.children !== null) {
checkDeptNode(data.children, check); // 调用checkNode方法
}
}
/** 遍历所有下级节点*/
function checkDeptNode(data, check) {
// 遍历所有下级节点信息
data.forEach((item) => {
// 通过节点信息设置选中状态
dept.value.setChecked(item, check, false);
// 是否包含下级节点,包含下级节点则选中所有下级节点
if (item.children !== undefined) {
checkNode(item.children, check);
}
});
}
/** 选中所有下级节点*/
function checkNode(data, check) {
// 遍历所有下级节点信息
data.forEach((item) => {
// 通过节点信息设置选中状态
menu.value.setChecked(item, check, false);
// 是否包含下级节点,包含下级节点则选中所有下级节点
if (item.children !== undefined) {
checkNode(item.children, check);
}
});
}
/** 取消按钮(数据权限)*/
function cancelDataScope() {
openDataScope.value = false;
handleQuery();
reset();
customSizeTree.value = [];
}
/** 表单重置*/
function reset() {
form.roleId = undefined;
form.businessId = undefined;
form.roleName = undefined;
form.roleKey = undefined;
form.roleSort = 0;
form.flag = "1";
form.menuIds = [];
form.menuName = "";
form.deptIds = [];
form.menuCheckStrictly = 0;
form.deptCheckStrictly = false;
form.remark = undefined;
}
/** 角色分配菜单保存提交 */
function handleRoleMenuSubmit() {
const roleId = checkedRole.id;
if (roleId) {
const checkedMenuIds: number[] = menuRef.value
.getCheckedNodes(false, true)
.map((node: any) => node.value);
loading.value = true;
updateRoleMenus(roleId, checkedMenuIds)
.then(() => {
ElMessage.success("分配权限成功");
openDataScope.value = false;
resetQuery();
})
.finally(() => {
loading.value = false;
});
if (form.businessId !== undefined && form.menuId !== undefined) {
form.deptIds = getDeptAllCheckedKeys();
dataScope(form).then((response) => {
ElMessage.success("修改成功");
customSizeTree.value = [];
});
}
}
/** 所有部门节点数据*/
function getDeptAllCheckedKeys() {
// 目前被选中的部门节点
const checkedKeys = dept.value.getHalfCheckedKeys();
// // 半选中的部门节点
const halfCheckedKeys = dept.value.getCheckedKeys();
checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
return dept.value.getCheckedKeys();
}
onMounted(() => {
handleQuery();
});
......@@ -407,7 +495,8 @@ onMounted(() => {
:icon="commonField.addIcon"
:size="commonField.smallSize"
@click="openDialog()"
>{{ commonField.addName }}</el-button>
>{{ commonField.addName }}</el-button
>
</template>
<el-table
......@@ -418,19 +507,23 @@ onMounted(() => {
border
>
<el-table-column type="index" label="序号" width="90" />
<el-table-column label="名称" prop="roleName" :show-overflow-tooltip="true">
<el-table-column
label="名称"
prop="roleName"
:show-overflow-tooltip="true"
>
<template #default="scope">
{{ scope.row.roleName || '-' }}
{{ scope.row.roleName || "-" }}
</template>
</el-table-column>
<el-table-column label="权限字符" prop="roleKey">
<template #default="scope">
{{ scope.row.roleKey || '-' }}
{{ scope.row.roleKey || "-" }}
</template>
</el-table-column>
<el-table-column label="显示顺序" prop="roleSort">
<template #default="scope">
{{ scope.row.roleSort || '-' }}
{{ scope.row.roleSort || "-" }}
</template>
</el-table-column>
<el-table-column label="状态" align="center" width="100">
......@@ -443,9 +536,14 @@ onMounted(() => {
/>
</template>
</el-table-column>
<el-table-column label="创建时间" :show-overflow-tooltip="true" align="center" prop="createTime">
<el-table-column
label="创建时间"
:show-overflow-tooltip="true"
align="center"
prop="createTime"
>
<template #default="scope">
<span>{{ scope.row.createDate || '-' }}</span>
<span>{{ scope.row.createDate || "-" }}</span>
</template>
</el-table-column>
<el-table-column fixed="right" label="操作" width="220">
......@@ -458,7 +556,8 @@ onMounted(() => {
link
:size="commonField.size"
@click="openDialog(scope.row.businessId)"
>{{ commonField.updateName }}</el-button>
>{{ commonField.updateName }}</el-button
>
<!-- //数据权限-->
<el-button
v-hasPermi="hasDelPerm"
......@@ -467,7 +566,8 @@ onMounted(() => {
link
:size="commonField.size"
@click="handleMenu(scope.row)"
>{{ commonField.dataPower }}</el-button>
>{{ commonField.dataPower }}</el-button
>
<!-- //删除-->
<el-button
v-hasPermi="hasDelPerm"
......@@ -476,7 +576,8 @@ onMounted(() => {
link
:size="commonField.size"
@click="handleDelete(scope.row)"
>{{ commonField.deleteName }}</el-button>
>{{ commonField.deleteName }}</el-button
>
</template>
</el-table-column>
</el-table>
......@@ -507,10 +608,20 @@ onMounted(() => {
<el-input v-model="formData.roleName" placeholder="请输入名称" />
</el-form-item>
<el-form-item label="权限字符" prop="roleKey">
<el-input v-model.trim="formData.roleKey" show-word-limit :maxlength="30" placeholder="请输入权限字符" />
<el-input
v-model.trim="formData.roleKey"
show-word-limit
:maxlength="30"
placeholder="请输入权限字符"
/>
</el-form-item>
<el-form-item label="排序" prop="roleSort">
<el-input-number v-model="formData.roleSort" style="width: 100%" controls-position="right" :min="0" />
<el-input-number
v-model="formData.roleSort"
style="width: 100%"
controls-position="right"
:min="0"
/>
</el-form-item>
<el-form-item label="状态">
<el-radio v-model="formData.flag" label="1">启用</el-radio>
......@@ -530,7 +641,13 @@ onMounted(() => {
/>
</el-form-item>
<el-form-item label="备注">
<el-input v-model.trim="formData.remarks" maxlength="200" show-word-limit type="textarea" placeholder="请输入内容" />
<el-input
v-model.trim="formData.remarks"
maxlength="200"
show-word-limit
type="textarea"
placeholder="请输入内容"
/>
</el-form-item>
</el-form>
......@@ -547,30 +664,46 @@ onMounted(() => {
v-model="openDataScope"
title="数据权限信息"
width="800px"
@close="handleQuery"
@close="cancelDataScope"
>
<el-row>
<el-col :span="12">
<el-form ref="formRef" :model="form" label-width="70px">
<el-form-item label="角色名称">
<el-input v-model.trim="form.roleName" placeholder="请输入角色名称" show-word-limit :maxlength="30" :disabled="true" />
<el-input
v-model.trim="form.roleName"
placeholder="请输入角色名称"
show-word-limit
:maxlength="30"
:disabled="true"
/>
</el-form-item>
<el-table
highlight-current-row
:data="menuList"
row-key="businessId"
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
default-expand-all
max-height="400px"
>
<el-table-column prop="menuName" label="菜单名称" :show-overflow-tooltip="true" width="230px" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<el-table-column
prop="menuName"
label="菜单名称"
:show-overflow-tooltip="true"
width="230px"
/>
<el-table-column
label="操作"
align="center"
class-name="small-padding fixed-width"
>
<template #default="scope">
<el-button
size="mini"
type="text"
@click="handleDataScope(scope.row)"
>修改</el-button>
>修改</el-button
>
</template>
</el-table-column>
</el-table>
......@@ -579,7 +712,12 @@ onMounted(() => {
<el-col :span="12">
<el-form :model="form" label-width="80px">
<el-form-item label="菜单名称" prop="roleName">
<el-input v-model="form.menuName" placeholder="未选择菜单名称" disabled style="width: 300px" />
<el-input
v-model="form.menuName"
placeholder="未选择菜单名称"
disabled
style="width: 300px"
/>
</el-form-item>
<el-form-item label="权限范围" style="width: 300px">
<el-select v-model="form.dataScope" style="width: 300px">
......@@ -610,10 +748,10 @@ onMounted(() => {
</el-row>
<template #footer>
<div class="dialog-footer">
<el-button @click="cancelDataScope">取 消</el-button>
<el-button type="primary" @click="handleRoleMenuSubmit"
>确 定</el-button
>
<el-button @click="openDataScope = false">取 消</el-button>
</div>
</template>
</el-dialog>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment