|
|
@@ -1,40 +1,31 @@
|
|
|
<template>
|
|
|
- <div class="role">
|
|
|
- <ElRow :gutter="20" style="background: white; height: 840px">
|
|
|
- <ElCol :md="6">
|
|
|
- <ElCol :md="20" style="margin: 10px 0">
|
|
|
- <ElInput
|
|
|
- v-model="roleName"
|
|
|
- placeholder="角色名称查找"
|
|
|
- type="text"
|
|
|
- tabindex="1"
|
|
|
- >
|
|
|
- <template #prefix>
|
|
|
- <SvgIcon name="i-ri:user-3-fill" />
|
|
|
- </template>
|
|
|
- </ElInput>
|
|
|
- </ElCol>
|
|
|
- <ElCol :md="20" style="margin: 10px 0">
|
|
|
+ <PageMain class="vh100">
|
|
|
+ <div class="flex ">
|
|
|
+ <div class="flex f-c" style="width: 300px;">
|
|
|
+ <ElInput v-model="roleName" placeholder="角色名称查找" type="text" tabindex="1">
|
|
|
+ <template #prefix>
|
|
|
+ <SvgIcon name="i-ri:user-3-fill" />
|
|
|
+ </template>
|
|
|
+ </ElInput>
|
|
|
+ <div class="flex a-c mt-2">
|
|
|
<ElButton type="primary" @click="addRole">
|
|
|
- <el-icon><Plus /></el-icon>添加
|
|
|
+ <el-icon>
|
|
|
+ <Plus />
|
|
|
+ </el-icon>添加
|
|
|
</ElButton>
|
|
|
<ElButton type="primary" @click="handleSearch">查找</ElButton>
|
|
|
- </ElCol>
|
|
|
- <ElCol :md="24" style="height: 720px; overflow-y: auto;">
|
|
|
- <div
|
|
|
- v-for="item in searchList"
|
|
|
- :key="item.id"
|
|
|
- :class="roleId == item.id ? 'on' : 'role-item'"
|
|
|
- @click="chooseRole(item)"
|
|
|
- >
|
|
|
+ </div>
|
|
|
+ <div style="height: calc(100vh - 300px); overflow: auto;">
|
|
|
+ <div v-for="item in searchList" :key="item.id" :class="roleId == item.id ? 'on' : 'role-item'"
|
|
|
+ @click="chooseRole(item)">
|
|
|
<p>{{ item.name }}</p>
|
|
|
<p>
|
|
|
<span>{{ item.remark || "--" }}</span>
|
|
|
</p>
|
|
|
</div>
|
|
|
- </ElCol>
|
|
|
- </ElCol>
|
|
|
- <ElCol :md="18">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="flex f-c flex-1 ml-12">
|
|
|
<div class="flex j-s a-c" style="margin-top: 20px;">
|
|
|
<span class="strong">角色管理</span>
|
|
|
<div>
|
|
|
@@ -43,103 +34,61 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
<h5>基本信息</h5>
|
|
|
- <!-- <ElCol :md="6"></ElCol> -->
|
|
|
- <ElForm
|
|
|
- :model="roleInfo"
|
|
|
- :rules="roleRules"
|
|
|
- ref="roleRef"
|
|
|
- label-width="auto"
|
|
|
- size=""
|
|
|
- style="max-width: 500px;"
|
|
|
- >
|
|
|
+ <ElForm :model="roleInfo" :rules="roleRules" ref="roleRef" label-width="auto" size="" style="max-width: 500px;">
|
|
|
<ElFormItem prop="name" label="角色名称">
|
|
|
- <ElInput
|
|
|
- v-model="roleInfo.name"
|
|
|
- placeholder="输入20个字以内的角色名称"
|
|
|
- type="text"
|
|
|
- tabindex="1"
|
|
|
- >
|
|
|
+ <ElInput v-model="roleInfo.name" placeholder="输入20个字以内的角色名称" type="text" tabindex="1">
|
|
|
</ElInput>
|
|
|
</ElFormItem>
|
|
|
<ElFormItem prop="deptId" label="所属机构">
|
|
|
- <el-cascader
|
|
|
- clearable
|
|
|
- style="width: 100%;"
|
|
|
- v-model="roleInfo.deptId"
|
|
|
- :options="tableData"
|
|
|
- :props="tableProps"
|
|
|
- @change="deptChange"
|
|
|
- />
|
|
|
+ <el-cascader clearable style="width: 100%;" v-model="roleInfo.deptId" :options="tableData"
|
|
|
+ :props="tableProps" @change="deptChange" />
|
|
|
</ElFormItem>
|
|
|
<ElFormItem prop="remark" label="角色描述">
|
|
|
- <ElInput
|
|
|
- v-model="roleInfo.remark"
|
|
|
- placeholder="请输入"
|
|
|
- type="textarea"
|
|
|
- tabindex="2"
|
|
|
- >
|
|
|
+ <ElInput v-model="roleInfo.remark" placeholder="请输入" type="textarea" tabindex="2">
|
|
|
</ElInput>
|
|
|
</ElFormItem>
|
|
|
</ElForm>
|
|
|
<ElDivider></ElDivider>
|
|
|
- <div style="min-height: 500px;">
|
|
|
+ <div>
|
|
|
<h5>角色权限
|
|
|
<span style=" font-size: 12px; font-weight: 400;color: #ccc;">
|
|
|
(该角色享有的后台模块功能权限剩余数据权限)
|
|
|
</span>
|
|
|
</h5>
|
|
|
- <el-tabs
|
|
|
- :tab-position="'left'"
|
|
|
- style="height: 460px;"
|
|
|
- class="demo-tabs"
|
|
|
- >
|
|
|
- <el-tab-pane label="菜单/操作权限">
|
|
|
- <ElTree
|
|
|
- style="height: 490px; overflow-y: auto;"
|
|
|
- :data="treeData"
|
|
|
- ref="permsRef"
|
|
|
- :props="defaultProps"
|
|
|
- show-checkbox
|
|
|
- node-key="id"
|
|
|
- :default-expand-all="true"
|
|
|
- :default-checked-keys="checkedKeys"
|
|
|
- @check="handleCheckChange"
|
|
|
- />
|
|
|
+ <el-tabs :tab-position="'left'" class="demo-tabs">
|
|
|
+ <el-tab-pane label="菜单/操作权限" style="height: 340px;overflow-y: auto;">
|
|
|
+ <ElTree :data="treeData" ref="permsRef" :props="defaultProps" show-checkbox node-key="id"
|
|
|
+ :default-expand-all="true" check-strictly :default-checked-keys="checkedKeys"
|
|
|
+ @check="handleCheckChange">
|
|
|
+ <template #default="{ node, data }">
|
|
|
+ <div class="flex a-c ">
|
|
|
+ <span>{{ node.label }}</span>
|
|
|
+ <div v-if="data.type == 2">
|
|
|
+ (权限)
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </ElTree>
|
|
|
</el-tab-pane>
|
|
|
<el-tab-pane label="组织架构权限">
|
|
|
- <el-radio-group
|
|
|
- v-model="roleInfo.dataMark"
|
|
|
- @change="dataMarkChange"
|
|
|
- >
|
|
|
+ <el-radio-group v-model="roleInfo.dataMark" @change="dataMarkChange">
|
|
|
<el-radio value="1" size="large">可见本机构下的数据</el-radio>
|
|
|
- <el-radio value="2" size="large"
|
|
|
- >可见本机构及下级机构数据</el-radio
|
|
|
- >
|
|
|
+ <el-radio value="2" size="large">可见本机构及下级机构数据</el-radio>
|
|
|
<el-radio value="3" size="large">指定机构</el-radio>
|
|
|
</el-radio-group>
|
|
|
- <ElTree
|
|
|
- style="max-height: 440px; overflow-y: auto;"
|
|
|
- :data="deptTreeData"
|
|
|
- :props="deptProps"
|
|
|
- show-checkbox
|
|
|
- node-key="id"
|
|
|
- :check-strictly="true"
|
|
|
- :default-expand-all="true"
|
|
|
- :default-checked-keys="roleInfo.deptIds"
|
|
|
- @check="handleDeptCheckChange"
|
|
|
- ref="deptTree"
|
|
|
- />
|
|
|
+ <ElTree style="max-height: 440px; overflow-y: auto;" :data="deptTreeData" :props="deptProps" show-checkbox
|
|
|
+ node-key="id" :check-strictly="true" :default-expand-all="true" :default-checked-keys="roleInfo.deptIds"
|
|
|
+ @check="handleDeptCheckChange" ref="deptTree" />
|
|
|
</el-tab-pane>
|
|
|
</el-tabs>
|
|
|
</div>
|
|
|
- </ElCol>
|
|
|
- </ElRow>
|
|
|
- </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </PageMain>
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
-import { asyncRoutes } from "@/router/routes"; // 请根据实际路径调整
|
|
|
-import { ref, reactive, onMounted, onBeforeMount, } from "vue";
|
|
|
+import { ref, reactive, onMounted } from "vue";
|
|
|
import {
|
|
|
type FormRules,
|
|
|
type ElTree,
|
|
|
@@ -148,10 +97,7 @@ import {
|
|
|
ElMessageBox
|
|
|
} from "element-plus";
|
|
|
import {
|
|
|
- preprocessRoutes,
|
|
|
- convertToTreeData,
|
|
|
TreeNode,
|
|
|
- clearId
|
|
|
} from "@/utils/composables/routeUtils"; // 导入工具方法
|
|
|
import api from "@/api";
|
|
|
const roleName = ref<string>("");
|
|
|
@@ -185,7 +131,7 @@ const roleRules = ref<FormRules>({
|
|
|
],
|
|
|
deptId: [{ required: true, message: "请选择机构", trigger: "change" }],
|
|
|
});
|
|
|
-const treeData = ref<TreeNode[]>([]);
|
|
|
+const treeData = ref();
|
|
|
const defaultProps = {
|
|
|
children: "children",
|
|
|
label: "title",
|
|
|
@@ -195,20 +141,22 @@ const deptProps = {
|
|
|
children: "children",
|
|
|
label: "name",
|
|
|
};
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
const handleCheckChange = (
|
|
|
- _checkedNodes: TreeNode[],
|
|
|
+ _checkedNodes: any,
|
|
|
checkedInfo: {
|
|
|
checkedKeys: number[];
|
|
|
- checkedNodes: TreeNode[];
|
|
|
+ checkedNodes: any[];
|
|
|
halfCheckedKeys: number[];
|
|
|
- halfCheckedNodes: TreeNode[];
|
|
|
+ halfCheckedNodes: any[];
|
|
|
}
|
|
|
) => {
|
|
|
- // console.log('Checked keys:', checkedInfo.checkedKeys);
|
|
|
- // console.log(checkedInfo.checkedNodes);
|
|
|
- roleInfo.permsId = checkedInfo.checkedKeys;
|
|
|
+ roleInfo.permsId = [...checkedInfo.checkedKeys, ...checkedInfo.halfCheckedKeys];
|
|
|
roleInfo.perms = [];
|
|
|
- roleInfo.perms = checkedInfo.checkedNodes;
|
|
|
+ roleInfo.perms = [...checkedInfo.checkedNodes, ...checkedInfo.halfCheckedNodes];
|
|
|
};
|
|
|
|
|
|
const handleDeptCheckChange = (
|
|
|
@@ -287,16 +235,16 @@ function chooseRole(item: any) {
|
|
|
.then((res) => {
|
|
|
// console.log(res);
|
|
|
roleInfo.name = res.data.name;
|
|
|
-
|
|
|
roleInfo.remark = res.data.remark;
|
|
|
roleInfo.deptId = res.data.deptId;
|
|
|
roleInfo.permsId = res.data.perms.map((val: Perm) => val.id);
|
|
|
roleInfo.perms = res.data.perms;
|
|
|
checkedKeys.value = res.data.perms.map((val: Perm) => val.id);
|
|
|
- if(res.data.dataScope?.deptIds){
|
|
|
+ console.log(checkedKeys.value)
|
|
|
+ if (res.data.dataScope?.deptIds) {
|
|
|
deptTree.value!.setCheckedKeys(res.data.dataScope?.deptIds, true);
|
|
|
roleInfo.dataMark = res.data.dataScope?.dataMark;
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
deptTree.value!.setCheckedKeys([], false);
|
|
|
roleInfo.dataMark = '1';
|
|
|
}
|
|
|
@@ -328,18 +276,18 @@ function addRole() {
|
|
|
permsRef.value!.setCheckedKeys([], true)
|
|
|
}
|
|
|
// 搜索
|
|
|
-let searchList = ref([])
|
|
|
+let searchList = ref()
|
|
|
const handleSearch = () => {
|
|
|
- searchList.value = roleList.value.filter(a => a.name.includes(roleName.value))
|
|
|
+ searchList.value = roleList.value.filter((item: any) => item.name.includes(roleName.value))
|
|
|
}
|
|
|
//提交角色信息
|
|
|
async function roleSubmit(roleRef: FormInstance | undefined) {
|
|
|
- if(!roleRef) {
|
|
|
+ if (!roleRef) {
|
|
|
roleRef.resetFields()
|
|
|
return
|
|
|
}
|
|
|
await roleRef.validate((vaild) => {
|
|
|
- if(vaild) {
|
|
|
+ if (vaild) {
|
|
|
if (operationType.value == "add") {
|
|
|
api.roleApi
|
|
|
.roleAdd({
|
|
|
@@ -354,9 +302,9 @@ async function roleSubmit(roleRef: FormInstance | undefined) {
|
|
|
dataMark: roleInfo.dataMark,
|
|
|
},
|
|
|
})
|
|
|
- .then((res) => {
|
|
|
+ .then((res: any) => {
|
|
|
// console.log(res);
|
|
|
- if(res.code == 200) {
|
|
|
+ if (res.code == 200) {
|
|
|
ElMessage.success("操作成功");
|
|
|
getRoleList();
|
|
|
} else {
|
|
|
@@ -379,9 +327,9 @@ async function roleSubmit(roleRef: FormInstance | undefined) {
|
|
|
dataMark: roleInfo.dataMark,
|
|
|
},
|
|
|
})
|
|
|
- .then((res) => {
|
|
|
+ .then((res: any) => {
|
|
|
// console.log(res);
|
|
|
- if(res.code == 200) {
|
|
|
+ if (res.code == 200) {
|
|
|
ElMessage.success("操作成功");
|
|
|
getRoleList();
|
|
|
} else {
|
|
|
@@ -400,7 +348,7 @@ function deleteRole() {
|
|
|
.roleDeleteValid({
|
|
|
id: roleId.value,
|
|
|
})
|
|
|
- .then((res:any) => {
|
|
|
+ .then((res: any) => {
|
|
|
if (res.code == 200) {
|
|
|
ElMessageBox({
|
|
|
title: '提示',
|
|
|
@@ -410,13 +358,13 @@ function deleteRole() {
|
|
|
confirmButtonText: "确认",
|
|
|
cancelButtonText: "取消",
|
|
|
}).then(() => {
|
|
|
- api.roleApi.roleDelete({
|
|
|
- id: roleId.value,
|
|
|
- }).then((res) => {
|
|
|
- ElMessage.success("操作成功");
|
|
|
- getRoleList();
|
|
|
- });
|
|
|
- })
|
|
|
+ api.roleApi.roleDelete({
|
|
|
+ id: roleId.value,
|
|
|
+ }).then((res) => {
|
|
|
+ ElMessage.success("操作成功");
|
|
|
+ getRoleList();
|
|
|
+ });
|
|
|
+ })
|
|
|
.catch(() => {
|
|
|
ElMessage.warning("用户取消操作");
|
|
|
});
|
|
|
@@ -437,19 +385,19 @@ const dataMarkChange = () => {
|
|
|
};
|
|
|
|
|
|
//根据所属id 判断组织架构权限是否可选
|
|
|
-function deptChange(e:any) {
|
|
|
+function deptChange(e: any) {
|
|
|
// console.log(e)
|
|
|
if (e != undefined) {
|
|
|
let deptId = e[e?.length - 1];
|
|
|
roleInfo.deptId = deptId;
|
|
|
// if(roleInfo.dataMark=='1'){
|
|
|
// let arr=[...deptTreeData.value]
|
|
|
- deptIds.value=[]
|
|
|
+ deptIds.value = []
|
|
|
disabledTree(deptTreeData.value, deptId);
|
|
|
deptTree.value!.setCheckedKeys(deptIds.value, true);
|
|
|
roleInfo.deptIds = deptIds.value;
|
|
|
- }else{
|
|
|
- roleInfo.deptId=''
|
|
|
+ } else {
|
|
|
+ roleInfo.deptId = ''
|
|
|
}
|
|
|
|
|
|
// deptTree.value.defaultCheckedKeys=roleInfo.deptIds
|
|
|
@@ -489,7 +437,7 @@ function disabledTree(list: any[], id: string) {
|
|
|
|
|
|
//
|
|
|
} else {
|
|
|
- if(id && list[i].id === id) {
|
|
|
+ if (id && list[i].id === id) {
|
|
|
deptIds.value.push(list[i].id);
|
|
|
}
|
|
|
list[i].disabled = false;
|
|
|
@@ -512,9 +460,6 @@ function getRoleList() {
|
|
|
api.roleApi
|
|
|
.roleList({
|
|
|
system: localStorage.getItem("login_system") || "",
|
|
|
- name: "",
|
|
|
- remark: "",
|
|
|
- permsId: [],
|
|
|
perms: [],
|
|
|
})
|
|
|
.then((res) => {
|
|
|
@@ -523,34 +468,20 @@ function getRoleList() {
|
|
|
// roleId.value = res.data[0].id;
|
|
|
});
|
|
|
}
|
|
|
-onBeforeMount(() => {
|
|
|
- // 对 asyncRoutes 进行预处理并转换为树形结构
|
|
|
- clearId()
|
|
|
- const processedRoutes = preprocessRoutes(asyncRoutes);
|
|
|
- // treeData.value = convertToTreeData(0, processedRoutes);
|
|
|
- treeData.value = processedRoutes;
|
|
|
- console.log(222222, treeData.value)
|
|
|
- api.roleApi.updateConfig({
|
|
|
- sysConfig:JSON.stringify(processedRoutes),
|
|
|
- sysPerms:JSON.stringify(treeData.value)
|
|
|
- }).then(res=>{
|
|
|
-
|
|
|
+const MenuTree = () => {
|
|
|
+ api.menuApi.findMenuTree().then((res) => {
|
|
|
+ treeData.value = JSON.parse(JSON.stringify(res.data))
|
|
|
})
|
|
|
-
|
|
|
-});
|
|
|
+}
|
|
|
onMounted(() => {
|
|
|
// 对 asyncRoutes 进行预处理并转换为树形结构
|
|
|
-
|
|
|
+ MenuTree();
|
|
|
getRoleList();
|
|
|
getInstitutionList();
|
|
|
});
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
-.role{
|
|
|
- height: 100%;
|
|
|
- overflow: hidden;
|
|
|
-}
|
|
|
.roleitem {
|
|
|
padding: 20px;
|
|
|
cursor: pointer;
|
|
|
@@ -576,12 +507,13 @@ p {
|
|
|
margin-top: 10px;
|
|
|
cursor: pointer;
|
|
|
|
|
|
- > p {
|
|
|
+ >p {
|
|
|
span {
|
|
|
font-size: 10px;
|
|
|
color: #b4b2b2;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
// >p:last-child{
|
|
|
// // margin: 5px 0;
|
|
|
|
|
|
@@ -595,15 +527,11 @@ p {
|
|
|
cursor: pointer;
|
|
|
background: rgb(242 242 242);
|
|
|
|
|
|
- > p {
|
|
|
+ >p {
|
|
|
span {
|
|
|
font-size: 10px;
|
|
|
color: #b4b2b2;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-:deep(.p-5) {
|
|
|
- padding: 0.2rem !important;
|
|
|
-}
|
|
|
</style>
|