<template>
|
<basicContainer>
|
<avue-crud
|
:option="option"
|
:table-loading="pageF.loading"
|
:data="tableData"
|
:page="page"
|
:permission="permissionList"
|
:before-open="beforeOpen"
|
v-model="form"
|
ref="crudRef"
|
@row-update="rowUpdate"
|
@row-save="rowSave"
|
@row-del="rowDel"
|
@refresh-change="refreshChange"
|
@search-change="searchChange"
|
@search-reset="searchReset"
|
@selection-change="selectionChange"
|
@current-change="currentChange"
|
@size-change="sizeChange"
|
@on-load="onLoad"
|
>
|
<template #menu-left>
|
<el-button
|
type="success"
|
icon="Edit"
|
:disabled="pageF.single"
|
v-hasPermi="['system:role:edit']"
|
@click="handleUpdate">修改
|
</el-button>
|
<el-button
|
type="danger"
|
icon="Delete"
|
:disabled="pageF.multiple"
|
@click="handleDelete"
|
v-hasPermi="['system:role:remove']"
|
>删除
|
</el-button>
|
<el-button
|
type="warning"
|
plain
|
icon="Download"
|
@click="handleExport"
|
v-hasPermi="['system:role:export']"
|
>导出
|
</el-button>
|
</template>
|
<template #status="scope">
|
<dict-tag v-if="scope.dic" :options="scope.dic" :value="scope.row.status" />
|
</template>
|
<template #dataScope-form>
|
<el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">展开/折叠</el-checkbox>
|
<el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event, 'menu')">全选/全不选</el-checkbox>
|
<el-checkbox v-model="form.menuCheckStrictly" @change="handleCheckedTreeConnect($event, 'menu')">父子联动</el-checkbox>
|
<el-tree
|
class="tree-border"
|
:data="menuOptions"
|
show-checkbox
|
ref="menuRef"
|
node-key="id"
|
:check-strictly="!form.menuCheckStrictly"
|
empty-text="加载中,请稍候"
|
:props="{ label: 'label', children: 'children' }"
|
></el-tree>
|
</template>
|
<template #menu="{ size, row, index }">
|
<div v-hasPermi="['system:role:edit']" style="display: inline-block;line-height: 1;vertical-align: middle;">
|
<el-dropdown size="small" @command="(command:any) => handleCommand(command, row)" >
|
<el-link size="small" type="primary" :underline="false" icon="el-icon-d-arrow-right">更多</el-link>
|
<template #dropdown>
|
<el-dropdown-menu slot="dropdown">
|
<div v-hasPermi="['system:role:edit']">
|
<el-dropdown-item command="handleDataScope" icon="Check"
|
>数据权限</el-dropdown-item>
|
</div>
|
<div v-hasPermi="['system:role:edit']">
|
<el-dropdown-item command="handleAuthUser" icon="User"
|
>分配用户</el-dropdown-item>
|
</div>
|
</el-dropdown-menu>
|
</template>
|
</el-dropdown>
|
</div>
|
|
</template>
|
</avue-crud>
|
|
<el-dialog title="分配数据权限"
|
:visible.sync="openDataScope"
|
v-model="openDataScope"
|
class="avue-dialog avue-dialog--top"
|
width="55%">
|
<avue-form v-model="dataScopeForm" :option="dataScopeOption">
|
<template #deptCheckStrictly="scope">
|
<el-checkbox v-model="deptExpand" @change="handleCheckedTreeExpand($event, 'dept')">展开/折叠</el-checkbox>
|
<el-checkbox v-model="deptNodeAll" @change="handleCheckedTreeNodeAll($event, 'dept')">全选/全不选</el-checkbox>
|
<el-checkbox v-model="form.deptCheckStrictly" @change="handleCheckedTreeConnect($event, 'dept')">父子联动</el-checkbox>
|
<el-tree
|
class="tree-border"
|
:data="deptOptions"
|
show-checkbox
|
default-expand-all
|
ref="deptRef"
|
node-key="id"
|
:check-strictly="!dataScopeForm.deptCheckStrictly"
|
empty-text="加载中,请稍候"
|
:props="{ children: 'children', label: 'label' }"
|
></el-tree>
|
</template>
|
|
|
</avue-form>
|
|
<div class="avue-dialog__footer">
|
<el-button @click="openDataScope=false">取 消</el-button>
|
<el-button @click="submitDataScope" type="primary">确 定</el-button>
|
</div>
|
</el-dialog>
|
|
</basicContainer>
|
</template>
|
|
<script setup name="role" lang="ts">
|
import {RoleI, addRole, delRole, exportRole, getRole, listRole, updateRole, dataScope} from "@/api/system/role";
|
import useCurrentInstance from "@/utils/useCurrentInstance";
|
import {computed, reactive, ref, toRefs} from "vue";
|
import {PagesInterface, PageQueryInterface} from "@/utils/globalInterface";
|
import {usePagePlus} from "@/hooks/usePagePlus";
|
import {hasPermission} from "@/utils/permissionUtils";
|
import {ElTree} from "element-plus";
|
import {roleDeptTreeSelect} from "@/api/system/dept";
|
import {roleMenuTreeSelect, treeSelect as menuTreeSelect} from "@/api/system/menu";
|
import {useRouter} from "vue-router";
|
import {deptTreeSelect} from "@/api/system/user";
|
|
|
const {proxy} = useCurrentInstance();
|
const crudRef = ref();
|
const router = useRouter();
|
const permissionList = computed(() => {
|
return {
|
addBtn: hasPermission(["system:role:add"]),
|
delBtn: hasPermission(["system:role:remove"]),
|
editBtn: hasPermission(["system:role:edit"]),
|
viewBtn: hasPermission(["system:role:query"]),
|
}
|
})
|
|
const data = reactive({
|
form: <RoleI>{},
|
queryParams: <RoleI & PageQueryInterface>{},
|
page: <PagesInterface>{
|
pageSize: 10,
|
total: 0,
|
currentPage: 1,
|
},
|
selectionList: [],
|
menuOptions:[],
|
deptOptions:[],
|
menuExpand:false,
|
menuNodeAll:false,
|
deptExpand:false,
|
deptNodeAll:false,
|
openDataScope:false,
|
dataScopeForm :<any>{}
|
})
|
const {queryParams, form, page, selectionList,menuOptions,deptOptions,menuNodeAll,menuExpand,deptExpand,deptNodeAll,openDataScope,dataScopeForm} = toRefs(data);
|
const option = ref({
|
pageKey: 'role',
|
rowKey: 'roleId',
|
viewBtn: false,
|
column: {
|
roleId: {
|
label: '角色编号',display:false,width: 100,
|
},
|
roleName: {
|
label: '角色名称',search:true,
|
rules: [
|
{
|
required: true,
|
message: "角色名称不能为空", trigger: "blur"
|
}
|
],
|
},
|
roleKey: {
|
label: '权限字符',search:true,
|
tip:'控制器中定义的权限字符,如:@PreAuthorize(`@ss.hasRole(\'admin\')`)',
|
rules: [
|
{
|
required: true,
|
message: "权限字符不能为空", trigger: "blur"
|
}
|
],
|
},
|
roleSort: {
|
label: '显示顺序',type:'number',min:0,width: 100,
|
rules: [
|
{
|
required: true,
|
message: "显示顺序不能为空", trigger: "blur"
|
}
|
],
|
},
|
status: {
|
label: '角色状态',value:'0',row:true,width: 120,search:true,
|
type: 'radio', dicUrl: '/system/dict/data/type/sys_normal_disable',
|
rules: [
|
{
|
required: true,
|
message: "角色状态不能为空", trigger: "blur"
|
}
|
],
|
},
|
dataScope: {
|
label: '菜单权限',hide:true,row:true,
|
},
|
createTime: {
|
label: '创建时间',addDisplay:false,editDisplay:false,width: 180,
|
},
|
updateBy: {
|
label: '更新者',hide:true,addDisplay:false,editDisplay:false,
|
},
|
updateTime: {
|
label: '更新时间',hide:true,addDisplay:false,editDisplay:false,
|
},
|
remark: {
|
label: '备注',hide:true,span:24,
|
type: 'textarea', minRows: 3, maxRows: 5,
|
},
|
}
|
})
|
|
const {
|
tableData, pageF, rowSave, rowUpdate, rowDel, beforeOpen, searchChange,
|
searchReset, selectionChange, onLoad, currentChange, sizeChange, handleDelete, handleExport, handleUpdate,refreshChange
|
} = usePagePlus({
|
form: form,
|
option:option,
|
queryParams: queryParams,
|
idKey: 'roleId',
|
page: page.value,
|
getListApi: listRole,
|
getDetailApi: getRole,
|
exportApi: exportRole,
|
deleteApi: delRole,
|
addApi: addRole,
|
updateApi: updateRole,
|
handleUpdateFunc: () => {
|
crudRef.value.rowEdit(selectionList.value[0]);
|
},
|
handleSelectionChangeFunc: (selection: any) => {
|
selectionList.value = selection;
|
},
|
handleBeforeOpenFunc:(type:string) => {
|
if (type == "add"){
|
menuTreeSelect().then(response => {
|
menuOptions.value = response.data || [];
|
});
|
}
|
},
|
handleEndOpenFunc:(type:string)=>{
|
getRoleMenuTreeSelect(form.value.roleId).then(res=>{
|
let checkedKeys = res.checkedKeys || [];
|
checkedKeys.forEach((v:any)=>{
|
menuRef.value?.setChecked(v,true,false);
|
})
|
})
|
|
},
|
rowSaveBegin: (row:any)=>{
|
row.menuIds = getMenuAllCheckedKeys();
|
},
|
rowUpdateBegin: (row:any)=>{
|
row.menuIds = getMenuAllCheckedKeys();
|
}
|
})
|
|
|
|
const dataScopeOption = ref({
|
menuBtn:false,
|
column:{
|
roleName:{
|
label: '角色名称',disabled:true
|
},
|
roleKey: {
|
label: '权限字符',disabled:true
|
},
|
dataScope:{
|
label: '权限范围',type:'select',row:true,
|
dicData:[
|
{ value: "1", label: "全部数据权限" },
|
{ value: "2", label: "自定数据权限" },
|
{ value: "3", label: "本部门数据权限" },
|
{ value: "4", label: "本部门及以下数据权限" },
|
{ value: "5", label: "仅本人数据权限" },
|
],
|
change:(e:any)=>{
|
dataScopeOption.value.column.deptCheckStrictly.display =e.value == '2';
|
}
|
},
|
deptCheckStrictly:{
|
label: '数据权限',
|
display: false,
|
}
|
|
}
|
})
|
const deptRef = ref<InstanceType<typeof ElTree>>();
|
const menuRef = ref<InstanceType<typeof ElTree>>();
|
|
|
/** 根据角色ID查询菜单树结构 */
|
function getRoleMenuTreeSelect(roleId?: number | (number | undefined)[]) {
|
return roleMenuTreeSelect(roleId).then(response => {
|
menuOptions.value = response.menus;
|
return response;
|
});
|
}
|
/** 根据角色ID查询部门树结构 */
|
function getRoleDeptTreeSelect(roleId?: number | (number | undefined)[]) {
|
return roleDeptTreeSelect(roleId).then(response => {
|
deptOptions.value = response.depts;
|
return response;
|
});
|
}
|
/** 树权限(展开/折叠)*/
|
function handleCheckedTreeExpand(value:any, type:string) {
|
if (type == "menu") {
|
let treeList = menuOptions.value;
|
for (let i = 0; i < treeList.length; i++) {
|
// @ts-ignore
|
menuRef.value!.store.nodesMap[treeList[i].id].expanded = value;
|
}
|
} else if (type == "dept") {
|
let treeList = deptOptions.value;
|
for (let i = 0; i < treeList.length; i++) {
|
// @ts-ignore
|
deptRef.value!.store.nodesMap[treeList[i].id].expanded = value;
|
}
|
}
|
}
|
/** 树权限(全选/全不选) */
|
function handleCheckedTreeNodeAll(value:any, type:string) {
|
if (type == "menu") {
|
menuRef.value!.setCheckedNodes(value ? menuOptions.value : []);
|
} else if (type == "dept") {
|
deptRef.value!.setCheckedNodes(value ? deptOptions.value : []);
|
}
|
}
|
/** 树权限(父子联动) */
|
function handleCheckedTreeConnect(value:any, type:string) {
|
if (type == "menu") {
|
form.value.menuCheckStrictly = value;
|
} else if (type == "dept") {
|
form.value.deptCheckStrictly = value;
|
}
|
}
|
/** 所有菜单节点数据 */
|
function getMenuAllCheckedKeys() {
|
// 目前被选中的菜单节点
|
let checkedKeys = menuRef.value!.getCheckedKeys();
|
// 半选中的菜单节点
|
let halfCheckedKeys = menuRef.value!.getHalfCheckedKeys();
|
checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
|
return checkedKeys;
|
}
|
const handleCommand = (command:string,row:any) =>{
|
switch (command) {
|
case 'handleDataScope':
|
handleDataScope(row);
|
break;
|
case "handleAuthUser":
|
handleAuthUser(row);
|
break;
|
}
|
}
|
function getDeptTree(roleId:number) {
|
return deptTreeSelect(roleId).then(response => {
|
deptOptions.value = response.data || [];
|
return response;
|
});
|
}
|
const handleDataScope = (row:RoleI) => {
|
const deptTreeSelect = getDeptTree(row.roleId!);
|
getRole(row.roleId).then(res=>{
|
openDataScope.value = true;
|
dataScopeForm.value = res.data;
|
}).then(()=>{
|
deptTreeSelect.then(res=>{
|
deptRef.value?.setCheckedKeys(res.checkedKeys);
|
})
|
|
})
|
}
|
|
const handleAuthUser = (row:RoleI) => {
|
router.push("/system/role-auth/user/" + row.roleId);
|
|
}
|
const getDeptAllCheckedKeys = () => {
|
// 目前被选中的部门节点
|
let checkedKeys = deptRef.value!.getCheckedKeys();
|
// 半选中的部门节点
|
let halfCheckedKeys = deptRef.value!.getHalfCheckedKeys();
|
checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
|
return checkedKeys;
|
}
|
|
const submitDataScope = ()=>{
|
dataScopeForm.value.deptIds = getDeptAllCheckedKeys();
|
dataScope(dataScopeForm.value).then(response => {
|
proxy.$modal.msgSuccess("修改成功");
|
openDataScope.value = false;
|
onLoad(page.value);
|
});
|
}
|
|
|
</script>
|