orgManager/src/views/system/user/role/index.vue

1026 lines
34 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<table-search-card :model="queryParams" @getList="getList" @handleQuery="handleQuery" @resetQuery="resetQuery">
<template #left>
<select-input-form ref="selectInputFormRef" :queryParamsList="queryParamsList" :queryParams="queryParams"
@handleQuery="handleQuery">
</select-input-form>
</template>
<template #right>
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:role:add']">新增</el-button>
</template>
</table-search-card>
<el-alert :title="t('提示: 删除权限后台账号数为0时才能删除权限')" style="margin-bottom: 10px;" :closable="false" type="warning"
show-icon />
<!-- 表格数据 -->
<el-table v-loading="loading" :data="roleList" ref="tableRef" class="c-table-main" @select="tableSelect"
@select-all="tableSelect" stripe border>
<el-table-column type="selection" width="55" :selectable="rowSelectable" align="center" />
<el-table-column label="权限名称" prop="roleName" min-width="150" align="center" >
<template #default="{ row }">
<span>{{ row.roleName }} <span v-if="row.defaultStatus == 0">(默认)</span></span>
</template>
</el-table-column>
<!-- <el-table-column label="权限类型" prop="roleName" min-width="110" align="center" /> -->
<el-table-column label="权限适用范围" prop="roleScope" min-width="150" align="center">
<template #default="{ row }">
{{ row.roleScope || '--' }}
</template>
</el-table-column>
<el-table-column label="用户列表" prop="roleSort" min-width="200">
<template #default="{ row }">
<div v-if="row.sysUsers.length > 0">
<span v-for="(item, index) in row.sysUsers.slice(0, 5)" :key="item.userId" @click="handleUserListClick(row)" style="color: rgb(64, 158, 255);cursor: pointer;">
{{ item.userName }}
<span v-if="index < Math.min(5, row.sysUsers.length) - 1">,</span>
</span>
<span v-if="row.sysUsers.length > 5"> ...</span>
</div>
<div v-else>--</div>
</template>
</el-table-column>
<el-table-column label="权限数" prop="menuCount" align="center" min-width="80">
<template #default="{ row }">
{{ row.menuCount || '--' }}
</template>
</el-table-column>
<el-table-column label="备注" prop="remark" min-width="130">
<template #default="{ row }">
{{ row.remark || '--' }}
</template>
</el-table-column>
<el-table-column label="操作" align="center" min-width="200" class-name="small-padding fixed-width">
<template #default="scope">
<el-button link type="primary" @click="handleDetail(scope.row)" v-hasPermi="['system:role:edit']">{{ t('详情')
}}</el-button>
<el-button link type="primary" v-if="scope.row.defaultStatus == 1" @click="handleUpdate(scope.row)"
v-hasPermi="['system:role:edit']">{{ t('修改') }}</el-button>
<el-button link type="primary" @click="handleManage(scope.row)" v-hasPermi="['system:role:edit']">{{ t('管理')
}}</el-button>
<el-button link type="primary" v-if="scope.row.defaultStatus == 1" @click="handleDelete(scope.row)"
v-hasPermi="['system:role:remove']">{{ t('删除') }}</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
@pagination="getList" />
<!-- 批量操作 -->
<table-batch-operate v-if="total > 0" v-model:batchOpType="batchOpType"
v-model:isAllSelection="isAllSelection" @allSelectionChange="allSelectionChange" @opTypeChange="opTypeChange"
:selectionData="selectionData" :opTypeOptions="opTypeOptions"></table-batch-operate>
<!-- 添加或修改角色配置对话框 -->
<el-dialog :title="title" align-center v-model="open" width="860px" append-to-body>
<el-scrollbar max-height="800px">
<el-form ref="roleRef" :model="form" :rules="rules" label-width="100px">
<el-form-item label="角色名称" prop="roleName">
<el-input v-model="form.roleName" :disabled="modifyStatus == 'detail' || modifyStatus == 'Manage'"
placeholder="请输入角色名称" maxlength="20" show-word-limit />
</el-form-item>
<el-form-item label="权限范围">
<el-select disabled v-model="form.dataScope" style="width: 350px;" @change="dataScopeSelectChange">
<el-option v-for="item in dataScopeOptions" :key="item.value" :label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item v-if="modifyStatus == 'add'" label="复制权限">
<el-select v-model="form.copyRoleId" style="width: 350px;" clearable @change="changeMenu">
<el-option v-for="item in roleOptions" :key="item.value" :label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="备注">
<el-input v-model="form.remark" :disabled="modifyStatus == 'detail' || modifyStatus == 'Manage'"
type="textarea" placeholder="请输入内容"></el-input>
</el-form-item>
<el-form-item v-if="modifyStatus == 'Manage'" label="添加账号">
<el-row style="width: 100%;">
<el-col :span="16">
<div style="width: 100%;">
<checkbox-select v-if="showLoding" collapse-tags collapse-tags-tooltip style="width: 100%;" v-model="accountLinking"
:options="accountOptions" :placeholder="t('请选择账号进行权限关联')"></checkbox-select>
</div>
</el-col>
<el-col :span="8" style="display: flex;justify-content: right;">
<div style="margin-left: 10px;">
<el-button type="primary" @click="handleAddAccount">{{ t('添加账户') }}</el-button>
</div>
</el-col>
</el-row>
<el-row v-if="sysUsersArr.length > 0" style="width: 100%;margin-top: 20px;">
<el-col :span="20">
<div style="width: 100%;">
<el-input v-model="userNameText" style="width: 100%" :placeholder="t('输入关键字进行用户列表过滤,支持空格隔开的多关键字匹配')" @input="handleFilter" />
</div>
</el-col>
<el-col :span="4" style="display: flex;justify-content: right;">
<div style="margin-left: 10px;">
<el-button type="primary" @click="handleRemoveAccount">{{ t('移出账户') }}</el-button>
</div>
</el-col>
</el-row>
<div class="accounts-about-scroll-container" v-if="sysUsersArr.length > 0">
<el-tag v-for="(item,index) in form.sysUsers" :key="item.userId" closable type="info" style="margin-right: 10px;" @close="handleClose(item)">
{{ item.userName }}
</el-tag>
</div>
</el-form-item>
<div style="display: flex;">
<div style="font-size: 14px;font-weight: 600;">{{ t('权限设置') }}</div>
<div style="margin-left: 10px;">{{ t('权限数') }}{{ countTree }}</div>
<div @click="handleCheckedTreeExpand($event, 'menu')"
style="cursor: pointer;color: rgb(64, 158, 255);margin-left: 10px;">
<span v-if="!defaultExpandAll">{{ t('全部展开') }}</span>
<span v-if="defaultExpandAll">{{ t('全部收起') }}</span>
</div>
</div>
<div style="width: 100%;margin-top: 10px;">
<el-input v-model="filterText" style="width: 100%" :placeholder="t('输入关键字进行权限过滤,支持空格隔开的多关键字匹配')" />
</div>
<div style="margin-top: 10px;">
<el-checkbox v-model="menuNodeAll" :disabled="modifyStatus == 'Manage' || modifyStatus == 'detail'"
@change="handleCheckedTreeNodeAll($event, 'menu')">全选/全不选</el-checkbox>
<el-checkbox v-model="form.menuCheckStrictly" :disabled="modifyStatus == 'Manage' || modifyStatus == 'detail'"
@change="handleCheckedTreeConnect($event, 'menu')">父子联动</el-checkbox>
<div class="table">
<div class="menu-list">
<el-tree ref="menuRef" :data="menuOptions" v-if="defaultExpandShow" :default-expand-all="defaultExpandAll"
:expand-on-click-node='false' check-on-click-node show-checkbox node-key="id"
:check-strictly="!form.menuCheckStrictly"
:props="{ label: 'label', children: 'children', disabled: (data, node) => modifyStatus == 'Manage' || modifyStatus == 'detail', }"
:filter-node-method="filterNode"></el-tree>
</div>
</div>
</div>
<!-- <el-form-item label="菜单权限">
<el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">展开/折叠</el-checkbox>
<el-tree
class="tree-border"
:data="menuOptions"
show-checkbox
ref="menuRef"
node-key="id"
:check-strictly="!form.menuCheckStrictly"
empty-text="加载中,请稍候"
:render-content="renderContent"
:props="{ label: 'label', children: 'children' }"
></el-tree>
</el-form-item> -->
</el-form>
</el-scrollbar>
<template #footer>
<div class="dialog-footer" style="display: flex;justify-content: center;">
<el-button v-if="modifyStatus == 'detail' || modifyStatus == 'Manage'" @click="cancel">关 闭</el-button>
<el-button v-if="modifyStatus == 'add' || modifyStatus == 'edit'" type="primary" @click="submitForm">确
定</el-button>
<el-button v-if="modifyStatus == 'add' || modifyStatus == 'edit'" @click="cancel">取 消</el-button>
</div>
</template>
</el-dialog>
<el-dialog :title="t('用户列表')" align-center v-model="openUserList" width="1050px" append-to-body>
<el-scrollbar max-height="800px">
<el-form ref="roleRef" label-width="100px">
<el-form-item label="权限名称">
{{ formUserList.roleName }}<span v-if="formUserList.defaultStatus == 0">(默认)</span>
</el-form-item>
<el-form-item label="用户列表">
<el-row v-if="sysUsersArr.length > 0" style="width: 100%;margin-top: 20px;">
<el-col :span="24">
<div style="width: 100%;">
<el-input v-model="userListText" style="width: 100%" :placeholder="t('输入关键字进行用户列表过滤,支持空格隔开的多关键字匹配')" @input="handleUserListFilter" />
</div>
</el-col>
</el-row>
<div class="accounts-about-scroll-container" v-if="sysUsersArr.length > 0">
<el-tag v-for="(item,index) in formUserList.sysUsers" :key="item.userId" type="info" style="margin-right: 10px;" >
{{ item.userName }}
</el-tag>
</div>
</el-form-item>
</el-form>
</el-scrollbar>
<template #footer>
<div class="dialog-footer" style="display: flex;justify-content: center;">
<el-button @click="cancelUserList">关 闭</el-button>
</div>
</template>
</el-dialog>
<!-- 分配角色数据权限对话框 -->
<el-dialog :title="title" align-center v-model="openDataScope" width="500px" append-to-body>
<el-form :model="form" label-width="80px">
<el-form-item label="角色名称">
<el-input v-model="form.roleName" :disabled="true" />
</el-form-item>
<el-form-item label="权限字符">
<el-input v-model="form.roleKey" :disabled="true" />
</el-form-item>
<el-form-item label="权限范围">
<el-select @change="dataScopeSelectChange">
<el-option v-for="item in dataScopeOptions" :key="item.value" :label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="数据权限" v-show="form.dataScope == 2">
<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="!form.deptCheckStrictly" empty-text="加载中,请稍候"
:props="{ label: 'label', children: 'children' }"></el-tree>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitDataScope">确 定</el-button>
<el-button @click="cancelDataScope">取 消</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup name="User">
import { addRole, changeRoleStatus, dataScope, delRole, getRole, listRole, updateRole, deptTreeSelect, optionselect, getMenu, unallocatedUserList,authUserSelectAll,authUserCancelAll,authUserCancel,authRolecancelAll } from "@/api/system/role";
import { roleMenuTreeselect, treeselect as menuTreeselect } from "@/api/system/menu";
import NumberInput from "@/components/NumberInput";
import TableBatchOperate from '@/components/TableBatchOperate'; // 批量操作
import CheckboxSelect from "@/components/CheckboxSelect"; // 下拉框多/全选
import { nextTick, ref } from "vue";
const router = useRouter();
const { proxy } = getCurrentInstance();
const { sys_normal_disable } = proxy.useDict("sys_normal_disable");
import { getLocalStorage } from "@/utils/auth";
const roleList = ref([]);
const open = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const dateRange = ref([]);
const menuOptions = ref([]);
const menuExpand = ref(false);
const menuNodeAll = ref(false);
const deptExpand = ref(true);
const deptNodeAll = ref(false);
const deptOptions = ref([]);
const openDataScope = ref(false);
const menuRef = ref(null);
const deptRef = ref(null);
const filterText = ref('');
const modifyStatus = ref('add');
const accountLinking = ref([]);
const accountOptions = ref([]);
const sysUsersArr = ref([]);
const formUserList = ref({});
const oldForm = shallowRef({ });
const queryParamsList = ref([{
label: proxy.t('角色名称'),
value: 'roleName',
}, {
label: proxy.t('后台账户'),
value: 'account',
}, {
label: proxy.t('后台呢称'),
value: 'nickName',
}])
/** 数据范围选项*/
const dataScopeOptions = ref([
{ value: "1", label: "全部数据权限" },
{ value: "2", label: "自定数据权限" },
{ value: "3", label: "本部门数据权限" },
{ value: "4", label: "本部门及以下数据权限" },
{ value: "5", label: "仅本人数据权限" }
]);
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 20,
searchType: 'roleName',
roleName: undefined,
roleKey: undefined,
status: undefined
},
rules: {
roleName: [{ required: true, message: "角色名称不能为空", trigger: "blur" }],
roleKey: [{ required: true, message: "权限字符不能为空", trigger: "blur" }],
roleSort: [{ required: true, message: "角色顺序不能为空", trigger: "blur" }],
roleLevel: [{ required: true, message: "角色级别不能为空", trigger: "blur" }],
},
});
const { queryParams, form, rules } = toRefs(data);
// 批量操作
const tableRef = ref(),
isAllSelection = ref(false), // 是否全选
selectionData = ref([]), // 选中的表格数据
batchOpType = ref(''); // 选中的批量操作类型
// 批量操作选项
const opTypeOptions = ref([
{ label: proxy.t('批量清除关联账户'), value: 'update' },
{ label: proxy.t('批量删除'), value: 'ignore' },
]);
// 勾选表格
const tableSelect = (val) => {
selectionData.value = val;
// 是否全选中
if (val.length == roleList.value.length) {
isAllSelection.value = true;
} else {
isAllSelection.value = false;
}
}
// 全选表格
const allSelectionChange = () => {
tableRef.value.toggleAllSelection();
}
// 选择批量数据操作类型
const opTypeChange = () => {
if (batchOpType.value === 'ignore') {
const params = selectionData.value.map(i => i.roleId); // 选中的id集合
proxy.$modal.confirm(proxy.t('确认批量删除已选的' + params.length + '条记录吗?')).then(() => {
loading.value = true;
delRole(params).then(res => {
loading.value = false;
batchOpType.value = '';
proxy.$modal.msgSuccess(proxy.t('操作成功!'));
handleQuery();
}).catch(() => {
batchOpType.value = '';
loading.value = false;
});
}).catch(() => {
batchOpType.value = '';
});
}else if (batchOpType.value === 'update') {
const params = selectionData.value.map(i => i.roleId); // 选中的id集合
proxy.$modal.confirm(proxy.t(`确认清除这些权限的关联账号(共${params.length}个)?`)).then(() => {
loading.value = true;
authRolecancelAll({roleIds: params}).then(res => {
loading.value = false;
batchOpType.value = '';
proxy.$modal.msgSuccess(proxy.t('操作成功!'));
handleQuery();
}).catch(() => {
batchOpType.value = '';
loading.value = false;
});
}).catch(() => {
batchOpType.value = '';
});
}
}
/** 查询角色列表 */
function getList() {
loading.value = true;
listRole(proxy.addDateRange(queryParams.value, dateRange.value)).then(response => {
roleList.value = response.rows;
total.value = response.total;
loading.value = false;
});
}
// 监听输入框,调用 el-tree 的 filter
watch(filterText, (val) => {
menuRef.value && menuRef.value.filter(val);
});
const rowSelectable = (row, index) => {
return row.defaultStatus == 0 ? false:true;
}
const openUserList = ref(false);
//打开用户列表
const handleUserListClick = (row) => {
openUserList.value = true;
sysUsersArr.value = row.sysUsers;
formUserList.value = row;
};
const cancelUserList = () => {
openUserList.value = false;
}
// 节点过滤方法
const filterNode = (value, data) => {
if (!value) return true;
// 支持多关键字,用空格分隔
const keywords = value.split(" ");
return keywords.every((kw) => data.label.includes(kw));
};
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
function resetQuery() {
dateRange.value = [];
proxy.resetForm("queryRef");
handleQuery();
}
/** 删除按钮操作 */
function handleDelete(row) {
const roleIds = row.roleId || ids.value;
proxy.$modal.confirm('是否确认删除角色编号为"' + roleIds + '"的数据项?').then(function () {
return delRole(roleIds);
}).then(() => {
getList();
proxy.$modal.msgSuccess("删除成功");
}).catch(() => { });
}
/** 导出按钮操作 */
function handleExport() {
proxy.download("system/role/export", {
...queryParams.value,
}, `role_${new Date().getTime()}.xlsx`);
}
/** 多选框选中数据 */
function handleSelectionChange(selection) {
ids.value = selection.map(item => item.roleId);
single.value = selection.length != 1;
multiple.value = !selection.length;
}
/** 角色状态修改 */
function handleStatusChange(row) {
let text = row.status === "0" ? "启用" : "停用";
proxy.$modal.confirm('确认要"' + text + '""' + row.roleName + '"角色吗?').then(function () {
return changeRoleStatus(row.roleId, row.status);
}).then(() => {
proxy.$modal.msgSuccess(text + "成功");
}).catch(function () {
row.status = row.status === "0" ? "1" : "0";
});
}
/** 更多操作 */
function handleCommand(command, row) {
switch (command) {
case "handleDataScope":
handleDataScope(row);
break;
case "handleAuthUser":
handleAuthUser(row);
break;
default:
break;
}
}
/** 分配用户 */
function handleAuthUser(row) {
router.push("/system/role-auth/user/" + row.roleId);
}
const countTree = ref(0);
/** 查询菜单树结构 */
function getMenuTreeselect() {
menuTreeselect().then(response => {
countTree.value = response.count;
menuOptions.value = response.data;
});
}
const showLoding = ref(true);
/** 获取用户列表 */
const getunallocatedUserList = (roleId) => {
unallocatedUserList({roleId: roleId }).then(response => {
accountOptions.value = response.data.map(item => {
return {
...item,
label: item.userName,
value: item.userId
}
});
showLoding.value = false;
nextTick(() => {
showLoding.value = true;
})
});
}
//添加关联账户
const handleAddAccount = () => {
if (accountLinking.value.length == 0){
proxy.$modal.msgError(proxy.t('请选择要关联的账户'));
return;
}
proxy.$modal.confirm('请确认此操作,是否继续?').then(function () {
let obj = {
roleId:form.value.roleId,
userIds:accountLinking.value
}
return authUserSelectAll(obj);
}).then(() => {
getRole(form.value.roleId).then(response => {
form.value = response.data;
sysUsersArr.value = response.data.sysUsers;
});
accountLinking.value = [];
getunallocatedUserList(form.value.roleId);
handleQuery();
proxy.$modal.msgSuccess("关联成功");
}).catch(() => { });
}
const userNameText = ref('');
//片段2
const handleFilter = () => {
if (!userNameText.value.trim()) return form.value.sysUsers = sysUsersArr.value
const keywords = userNameText.value.trim().split(/\s+/) // 支持空格分隔多个关键词
form.value.sysUsers = sysUsersArr.value.filter(user =>
keywords.every(k => user.userName.includes(k))
)
}
const userListText = ref('');
//
const handleUserListFilter = () => {
if (!userListText.value.trim()) return formUserList.value.sysUsers = sysUsersArr.value;
const keywords = userListText.value.trim().split(/\s+/) // 支持空格分隔多个关键词
formUserList.value.sysUsers = sysUsersArr.value.filter(user =>
keywords.every(k => user.userName.includes(k))
)
}
//移出关联账户
const handleRemoveAccount = () => {
if (form.value.sysUsers.length == 0){
proxy.$modal.msgError("请选择要移出的账户");
return
}
proxy.$modal.confirm('请确认此操作,是否继续?').then(function () {
let userIds = form.value.sysUsers.map(item => item.userId);
let obj = {
roleId:form.value.roleId,
userIds:userIds
}
return authUserCancelAll(obj);
}).then(() => {
getRole(form.value.roleId).then(response => {
form.value = response.data;
sysUsersArr.value = response.data.sysUsers;
});
handleQuery();
getunallocatedUserList(form.value.roleId);
proxy.$modal.msgSuccess("移出成功");
}).catch(() => { });
}
//单个移出关联账户
const handleClose = (row) => {
proxy.$modal.confirm('请确认此操作,是否继续?').then(function () {
let userIds = form.value.sysUsers.map(item => item.userId);
let obj = {
roleId:form.value.roleId,
userId:row.userId
}
return authUserCancel(obj);
}).then(() => {
getRole(form.value.roleId).then(response => {
form.value = response.data;
sysUsersArr.value = response.data.sysUsers;
});
handleQuery();
getunallocatedUserList(form.value.roleId);
proxy.$modal.msgSuccess("移出成功");
}).catch(() => { });
}
/** 所有部门节点数据 */
function getDeptAllCheckedKeys() {
// 目前被选中的部门节点
let checkedKeys = deptRef.value.getCheckedKeys();
// 半选中的部门节点
let halfCheckedKeys = deptRef.value.getHalfCheckedKeys();
checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
return checkedKeys;
}
/** 重置新增的表单以及其他数据 */
function reset() {
if (menuRef.value != undefined) {
menuRef.value.setCheckedKeys([]);
}
menuExpand.value = false;
menuNodeAll.value = false;
deptExpand.value = true;
deptNodeAll.value = false;
form.value = {
roleId: undefined,
roleName: undefined,
roleKey: undefined,
roleSort: 0,
status: "0",
menuIds: [],
deptIds: [],
menuCheckStrictly: true,
deptCheckStrictly: true,
remark: undefined
};
proxy.resetForm("roleRef");
}
const roleOptions = ref([]);
/** 添加角色 */
function handleAdd() {
reset();
getMenuTreeselect();
open.value = true;
title.value = "新增角色";
modifyStatus.value = 'add';
form.value.dataScope = getLocalStorage('userInfo')?.nickName;
optionselect({}).then(response => {
roleOptions.value = response.data.map(item => {
return {
...item,
label: item.roleName,
value: item.roleId
}
});
})
}
//
const handleDetail = (row) => {
reset();
const roleId = row.roleId || ids.value;
const roleMenu = getRoleMenuTreeselect(roleId);
getRole(roleId).then(response => {
form.value = response.data;
form.value.roleSort = Number(form.value.roleSort);
open.value = true;
nextTick(() => {
roleMenu.then((res) => {
let checkedKeys = res.checkedKeys;
checkedKeys.forEach((v) => {
nextTick(() => {
menuRef.value.setChecked(v, true, false);
});
});
});
});
form.value.dataScope = response.data.roleScope;
modifyStatus.value = 'detail';
title.value = "角色详情";
});
}
// 角色管理
const handleManage = (row) => {
reset();
const roleId = row.roleId || ids.value;
const roleMenu = getRoleMenuTreeselect(roleId);
getunallocatedUserList(roleId);
getRole(roleId).then(response => {
form.value = response.data;
sysUsersArr.value = response.data.sysUsers;
form.value.roleSort = Number(form.value.roleSort);
open.value = true;
nextTick(() => {
roleMenu.then((res) => {
let checkedKeys = res.checkedKeys;
checkedKeys.forEach((v) => {
nextTick(() => {
menuRef.value.setChecked(v, true, false);
});
});
});
});
form.value.dataScope = response.data.roleScope;
modifyStatus.value = 'Manage';
title.value = "角色管理";
form.value.roleId = row.roleId;
});
}
//复制权限
const changeMenu = (roleId) => {
if (roleId) {
getMenu(roleId).then(response => {
let checkedKeys = response.data;
checkedKeys.forEach((v) => {
nextTick(() => {
menuRef.value.setChecked(v, true, false);
});
});
});
} else {
menuRef.value.setCheckedKeys([]);
}
}
/** 修改角色 */
function handleUpdate(row) {
reset();
const roleId = row.roleId || ids.value;
const roleMenu = getRoleMenuTreeselect(roleId);
getRole(roleId).then(response => {
form.value = response.data;
form.value.roleSort = Number(form.value.roleSort);
open.value = true;
nextTick(() => {
roleMenu.then((res) => {
let checkedKeys = res.checkedKeys;
checkedKeys.forEach((v) => {
nextTick(() => {
menuRef.value.setChecked(v, true, false);
});
});
});
});
setTimeout(() => {
form.value.menuIds = getMenuAllCheckedKeys();
oldForm.value = JSON.stringify(form.value);
}, 600);
form.value.dataScope = response.data.roleScope;
modifyStatus.value = 'edit';
title.value = "修改角色";
});
}
/** 根据角色ID查询菜单树结构 */
function getRoleMenuTreeselect(roleId) {
return roleMenuTreeselect(roleId).then(response => {
menuOptions.value = response.menus;
return response;
});
}
/** 根据角色ID查询部门树结构 */
function getDeptTree(roleId) {
return deptTreeSelect(roleId).then(response => {
deptOptions.value = response.depts;
return response;
});
}
const defaultExpandAll = ref(false);
const defaultExpandShow = ref(true);
/** 树权限(展开/折叠)*/
function handleCheckedTreeExpand(value, type) {
if (type == "menu") {
// let treeList = menuOptions.value;
// for (let i = 0; i < treeList.length; i++) {
// menuRef.value.store.nodesMap[treeList[i].id].expanded = value;
// }
if (!defaultExpandAll.value) {
defaultExpandAll.value = true;
} else {
defaultExpandAll.value = false;
}
defaultExpandShow.value = false;
nextTick(() => {
defaultExpandShow.value = true;
});
} else if (type == "dept") {
let treeList = deptOptions.value;
for (let i = 0; i < treeList.length; i++) {
deptRef.value.store.nodesMap[treeList[i].id].expanded = value;
}
}
}
/** 树权限(全选/全不选) */
function handleCheckedTreeNodeAll(value, type) {
if (type == "menu") {
menuRef.value.setCheckedNodes(value ? menuOptions.value : []);
} else if (type == "dept") {
deptRef.value.setCheckedNodes(value ? deptOptions.value : []);
}
}
/** 树权限(父子联动) */
function handleCheckedTreeConnect(value, type) {
if (type == "menu") {
form.value.menuCheckStrictly = value ? true : false;
} else if (type == "dept") {
form.value.deptCheckStrictly = value ? true : false;
}
}
/** 所有菜单节点数据 */
function getMenuAllCheckedKeys() {
// 目前被选中的菜单节点
let checkedKeys = menuRef.value.getCheckedKeys();
// 半选中的菜单节点
let halfCheckedKeys = menuRef.value.getHalfCheckedKeys();
checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
return checkedKeys;
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["roleRef"].validate(valid => {
if (valid) {
if (form.value.roleId != undefined) {
form.value.menuIds = getMenuAllCheckedKeys();
if (JSON.stringify(form.value) != oldForm.value) {
let params = {
menuIds: form.value.menuIds,
roleName: form.value.roleName,
remark: form.value.remark,
roleSort: form.value.roleSort,
roleId: form.value.roleId,
};
updateRole(params).then(response => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
}else{
open.value = false;
}
} else {
form.value.menuIds = getMenuAllCheckedKeys();
let params = {
menuIds: form.value.menuIds,
roleName: form.value.roleName,
remark: form.value.remark,
roleSort: form.value.roleSort,
};
addRole(params).then(response => {
proxy.$modal.msgSuccess("新增成功");
open.value = false;
getList();
});
}
}
});
}
/** 取消按钮 */
function cancel() {
open.value = false;
reset();
}
/** 选择角色权限范围触发 */
function dataScopeSelectChange(value) {
if (value !== "2") {
deptRef.value.setCheckedKeys([]);
}
}
/** 分配数据权限操作 */
function handleDataScope(row) {
reset();
const deptTreeSelect = getDeptTree(row.roleId);
getRole(row.roleId).then(response => {
form.value = response.data;
openDataScope.value = true;
nextTick(() => {
deptTreeSelect.then(res => {
nextTick(() => {
if (deptRef.value) {
deptRef.value.setCheckedKeys(res.checkedKeys);
}
});
});
});
title.value = "分配数据权限";
});
}
/** 提交按钮(数据权限) */
function submitDataScope() {
if (form.value.roleId != undefined) {
form.value.deptIds = getDeptAllCheckedKeys();
dataScope(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功");
openDataScope.value = false;
getList();
});
}
}
/** 取消按钮(数据权限)*/
function cancelDataScope() {
openDataScope.value = false;
reset();
}
//初始化
onMounted(() => {
getList();
});
</script>
<style scoped lang="scss">
.custom-node-row {
display: flex;
align-items: center;
}
.col {
display: inline-block;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.col-label {
width: 200px;
font-weight: bold;
}
.col-type {
width: 120px;
color: #888;
}
.col-url {
width: 240px;
color: #aaa;
}
.table {
// padding: 20px;
// min-height: 88vh;
background: #fff;
width: 100%;
// margin: 20px;
}
.menu-list {
::v-deep .el-tree {
border-top: 1px solid #ebeef5;
border-left: 1px solid #ebeef5;
border-right: 1px solid #ebeef5;
.el-tree-node__expand-icon {
// display: none !important;
}
.el-tree-node {
&.is-expanded,
&.is-current,
&.is-focusable {
background-color: transparent !important;
}
.el-tree-node__content {
background-color: transparent !important;
&:hover {
background-color: transparent !important;
}
}
}
>.el-tree-node {
display: flex;
align-items: center;
border-bottom: 1px solid #ebeef5;
position: relative;
padding-top: 10px;
padding-bottom: 10px;
>.el-tree-node__content {
width: 300px;
height: 100%;
padding-left: 20px !important;
}
.el-tree-node__children {
position: relative;
&::after {
content: ' ';
display: block;
width: 1px;
height: 100%;
border-left: 1px solid #ebeef5;
position: absolute;
left: 0px;
top: 0px;
}
.el-tree-node {
// width: 350px;
padding: 10px 0px;
display: flex;
align-items: center;
// border-bottom: 1px solid #ebeef5;
}
}
}
}
}
.accounts-about-scroll-container {
align-items: flex-start;
content-visibility: auto;
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
margin-top: 10px;
max-height: 100px;
overflow: auto;
width: 100%;
}
</style>