2024-12-18 10:16:27 +08:00
|
|
|
<template>
|
|
|
|
|
<section class="AppRoleRightsManager">
|
|
|
|
|
<ai-list v-if="!showDetail">
|
|
|
|
|
<ai-title slot="title" title="角色管理" isShowBottomBorder/>
|
|
|
|
|
<template #content>
|
|
|
|
|
<ai-search-bar>
|
|
|
|
|
<template #left>
|
|
|
|
|
<el-button size="small" type="primary" icon="iconfont iconAdd"
|
|
|
|
|
@click="$router.push({hash:'#add'})"
|
|
|
|
|
v-if="$permissions('admin_sysapprole_add')">
|
|
|
|
|
添加
|
|
|
|
|
</el-button>
|
|
|
|
|
<el-button
|
|
|
|
|
size="small"
|
|
|
|
|
icon="iconfont iconDelete"
|
|
|
|
|
:disabled="!multipleSelection.length"
|
|
|
|
|
class="del-btn-list"
|
|
|
|
|
@click="deleteApp('all')"
|
|
|
|
|
v-if="$permissions('admin_sysapprole_del')"
|
|
|
|
|
>删除
|
|
|
|
|
</el-button>
|
|
|
|
|
</template>
|
|
|
|
|
<template #right>
|
|
|
|
|
<el-input
|
|
|
|
|
size="small"
|
|
|
|
|
v-model="search.roleName"
|
|
|
|
|
placeholder="角色名称"
|
|
|
|
|
clearable
|
|
|
|
|
@change="searchList()"
|
|
|
|
|
suffix-icon="iconfont iconSearch"/>
|
|
|
|
|
</template>
|
|
|
|
|
</ai-search-bar>
|
|
|
|
|
<ai-table :tableData="adminList" :colConfigs="colConfigs" :total="total" :current.sync="page.pageNum"
|
|
|
|
|
:size.sync="page.pageSize"
|
|
|
|
|
@getList="getTableData" :col-configs="colConfigs" :dict="dict"
|
|
|
|
|
@selection-change="v=>multipleSelection=v">
|
|
|
|
|
<el-table-column label="角色用户" slot="users" align="center">
|
2025-01-08 16:00:05 +08:00
|
|
|
<template slot-scope="{row}">
|
|
|
|
|
<div class="font-12 flex wrap gap-6">
|
|
|
|
|
<el-tag size="mini" v-for="(item, i) in row.users" :key="i">{{ item.name }}
|
|
|
|
|
<template v-if="item.phone">({{ item.phone }})</template>
|
|
|
|
|
</el-tag>
|
|
|
|
|
</div>
|
2024-12-18 10:16:27 +08:00
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column slot="options" label="操作" fixed="right" align="center">
|
|
|
|
|
<template slot-scope="{row}">
|
|
|
|
|
<el-button type="text" @click="beforeCopy(row)" v-if="$permissions('admin_sysapprole_edit')">复制
|
|
|
|
|
</el-button>
|
|
|
|
|
<el-button type="text" @click="viewApp(row)" v-if="$permissions('admin_sysapprole_detail')">详情
|
|
|
|
|
</el-button>
|
|
|
|
|
<el-button type="text" @click="openRightsGraph(row)" v-if="$permissions('admin_sysapprole_detail')">关系图
|
|
|
|
|
</el-button>
|
|
|
|
|
<el-button type="text" @click="toAddAppRole(row)" v-if="$permissions('admin_sysapprole_edit')">编辑
|
|
|
|
|
</el-button>
|
|
|
|
|
<el-button type="text" @click="deleteApp(row)" v-if="$permissions('admin_sysapprole_del')">删除</el-button>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
</ai-table>
|
|
|
|
|
<ai-dialog
|
|
|
|
|
title="应用角色详情"
|
|
|
|
|
:visible.sync="viewShow"
|
|
|
|
|
width="600px"
|
|
|
|
|
customFooter>
|
|
|
|
|
<ai-card title="基本信息">
|
|
|
|
|
<template #content>
|
|
|
|
|
<ai-wrapper>
|
|
|
|
|
<ai-info-item label="应用角色名称" :value="viewInfo.name" isLine/>
|
|
|
|
|
</ai-wrapper>
|
|
|
|
|
</template>
|
|
|
|
|
</ai-card>
|
|
|
|
|
<ai-card title="权限信息">
|
|
|
|
|
<template #content>
|
|
|
|
|
<div style="margin-bottom: 16px" v-text="roleList.map(e => e.name).join('、')"/>
|
|
|
|
|
</template>
|
|
|
|
|
</ai-card>
|
|
|
|
|
<ai-card title="角色账号">
|
|
|
|
|
<template #right>
|
|
|
|
|
<span style="text-align: right; color: #999">
|
|
|
|
|
共<span style="color: #26f" v-text="userList.length"/>个账号
|
|
|
|
|
</span>
|
|
|
|
|
</template>
|
|
|
|
|
<template #content>
|
|
|
|
|
<div class="datail-table-body" v-if="userList.length">
|
|
|
|
|
<div class="datail-item" v-for="(item, index) in userList" :key="index">
|
|
|
|
|
<span class="item-name">{{ item.name }}</span>
|
|
|
|
|
<span style="color: #999">{{ item.phone }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
</ai-card>
|
|
|
|
|
<template #footer>
|
|
|
|
|
<el-button
|
|
|
|
|
type="primary"
|
|
|
|
|
@click="toAddAppRole(viewInfo)"
|
|
|
|
|
v-if="$permissions('admin_sysapprole_edit')"
|
|
|
|
|
>编辑角色
|
|
|
|
|
</el-button>
|
|
|
|
|
</template>
|
|
|
|
|
</ai-dialog>
|
|
|
|
|
<ai-dialog title="权限关系图" :visible.sync="rightsGraph" class="rightsGraphDialog" customFooter>
|
|
|
|
|
<rights-graph :instance="instance" :dict="dict" :app="selectApp"/>
|
|
|
|
|
<el-button slot="footer" @click="rightsGraph=false">关闭</el-button>
|
|
|
|
|
</ai-dialog>
|
|
|
|
|
<!--复制角色-->
|
|
|
|
|
<el-dialog
|
|
|
|
|
class="editStyle"
|
|
|
|
|
:visible.sync="copyDialog"
|
|
|
|
|
width="520px"
|
|
|
|
|
@close="dataInit()"
|
|
|
|
|
title="复制角色">
|
|
|
|
|
<el-form :model="form" label-width="80px">
|
|
|
|
|
<el-form-item label="角色名" :rules="[{ required: true, message: '', trigger: 'blur' }]">
|
|
|
|
|
<el-input
|
|
|
|
|
v-model="editName"
|
|
|
|
|
placeholder="请输入..."
|
|
|
|
|
size="small"
|
|
|
|
|
clearable
|
|
|
|
|
/>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-form>
|
|
|
|
|
<div slot="footer" style="text-align: center">
|
|
|
|
|
<el-button
|
|
|
|
|
style="width: 92px"
|
|
|
|
|
size="small"
|
|
|
|
|
@click="copyDialog = false"
|
|
|
|
|
>取消
|
|
|
|
|
</el-button
|
|
|
|
|
>
|
|
|
|
|
<el-button
|
|
|
|
|
style="width: 92px"
|
|
|
|
|
size="small"
|
|
|
|
|
type="primary"
|
|
|
|
|
@click="copyFn()"
|
|
|
|
|
:disabled="!editName"
|
|
|
|
|
>
|
|
|
|
|
确认
|
|
|
|
|
</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
</template>
|
|
|
|
|
</ai-list>
|
|
|
|
|
<rights-add v-else :instance="instance" :dict="dict" :permissions="permissions"/>
|
|
|
|
|
</section>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import RightsAdd from "./rightsAdd";
|
|
|
|
|
import RightsGraph from "./rightsGraph";
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
name: "AppRoleRightsManager",
|
|
|
|
|
components: {RightsGraph, RightsAdd},
|
|
|
|
|
label: "角色管理",
|
|
|
|
|
provide() {
|
|
|
|
|
return {
|
|
|
|
|
top: this
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
props: {
|
|
|
|
|
instance: Function,
|
|
|
|
|
dict: Object,
|
|
|
|
|
permissions: Function,
|
|
|
|
|
actions: {
|
|
|
|
|
default: () => ({
|
|
|
|
|
list: '/admin/role/page',
|
|
|
|
|
apps: '/admin/role/list-all',
|
|
|
|
|
delete: '/admin/role/del',
|
|
|
|
|
detail: '/admin/role/queryById-checked',
|
|
|
|
|
modify: '/admin/role/modify',
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
computed: {
|
|
|
|
|
colConfigs() {
|
|
|
|
|
return [
|
|
|
|
|
{type: "selection"},
|
2025-01-08 16:00:05 +08:00
|
|
|
{label: "角色名", prop: "name", width: 140},
|
2024-12-18 10:16:27 +08:00
|
|
|
{label: "所属端", prop: "type", width: '100px', dict: "roleType"},
|
|
|
|
|
{label: "用户数量", prop: "roleCount", align: 'center', width: '80px'},
|
|
|
|
|
{slot: "users"},
|
|
|
|
|
{slot: "options"}
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
showDetail() {
|
|
|
|
|
return this.$route.hash == "#add"
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
page: {pageNum: 1, pageSize: 10},
|
|
|
|
|
search: {roleName: ''},
|
|
|
|
|
adminList: [], //列表数据
|
|
|
|
|
total: 0,
|
|
|
|
|
multipleSelection: [],
|
|
|
|
|
delShow: false,
|
|
|
|
|
delParams: "",
|
|
|
|
|
delIds: [],
|
|
|
|
|
viewShow: false,
|
|
|
|
|
viewInfo: {},
|
|
|
|
|
roleList: [], //详情权限列表
|
|
|
|
|
row: {},
|
|
|
|
|
copyDialog: false,
|
|
|
|
|
titleDel: "",
|
|
|
|
|
form: {},
|
|
|
|
|
editName: "",
|
|
|
|
|
userList: [],
|
|
|
|
|
rightsGraph: false,
|
|
|
|
|
selectApp: {}
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
created() {
|
|
|
|
|
this.getTableData();
|
|
|
|
|
this.dict.load('roleType')
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
//查询table列表
|
|
|
|
|
getTableData() {
|
|
|
|
|
this.adminList = [];
|
|
|
|
|
this.instance.post(this.actions.list, null, {
|
|
|
|
|
params: {...this.page, ...this.search}
|
|
|
|
|
}).then(res => {
|
|
|
|
|
if (res?.data) {
|
|
|
|
|
this.total = res.data.total;
|
|
|
|
|
this.adminList = res.data.records;
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
//查询
|
|
|
|
|
searchList() {
|
|
|
|
|
this.page.pageNum = 1;
|
|
|
|
|
this.getTableData();
|
|
|
|
|
},
|
|
|
|
|
//添加按钮
|
|
|
|
|
toAddAppRole(item) {
|
|
|
|
|
this.$router.push({
|
|
|
|
|
hash: "#add",
|
|
|
|
|
query: {
|
|
|
|
|
id: item.id,
|
2025-01-08 16:00:05 +08:00
|
|
|
name: item.name,
|
|
|
|
|
type: item.type,
|
2024-12-18 10:16:27 +08:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
//删除
|
|
|
|
|
deleteApp(e) {
|
|
|
|
|
if (e == "all") {
|
|
|
|
|
this.multipleSelection.map((item) => {
|
|
|
|
|
this.delIds.push(item.id);
|
|
|
|
|
});
|
|
|
|
|
this.delParams = `ids=${this.delIds}`;
|
|
|
|
|
this.titleDel = "确定要执行删除操作吗?";
|
|
|
|
|
} else {
|
|
|
|
|
this.delParams = `ids=${e.id}`;
|
|
|
|
|
this.titleDel = "确定需要删除该角色吗?";
|
|
|
|
|
}
|
|
|
|
|
this.$confirm(this.titleDel, {
|
|
|
|
|
type: "error",
|
|
|
|
|
}).then(() => {
|
|
|
|
|
this.instance.post(`${this.actions.delete}?${this.delParams}`).then(res => {
|
|
|
|
|
if (res?.msg == "success") {
|
|
|
|
|
this.getTableData();
|
|
|
|
|
} else {
|
|
|
|
|
this.$message.error(res.msg);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}).catch(() => 0);
|
|
|
|
|
},
|
|
|
|
|
//查看信息
|
|
|
|
|
viewApp(e) {
|
|
|
|
|
this.userList = e.users;
|
|
|
|
|
this.viewInfo = e;
|
|
|
|
|
this.viewShow = true;
|
|
|
|
|
this.getRowInfo(this.viewInfo.appId, this.viewInfo.id);
|
|
|
|
|
},
|
|
|
|
|
//查询 row 信息
|
|
|
|
|
getRowInfo(appId, id) {
|
|
|
|
|
this.roleList = [];
|
|
|
|
|
this.instance.post(`${this.actions.detail}?id=${appId}&roleId=${id}`)
|
|
|
|
|
.then(res => {
|
|
|
|
|
if (res?.data) {
|
|
|
|
|
this.roleList = res.data.filter(e => e.checked)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
//复制
|
|
|
|
|
beforeCopy(row) {
|
|
|
|
|
this.row = row;
|
|
|
|
|
this.copyDialog = true;
|
|
|
|
|
this.getRowInfo(this.row.appId, this.row.id);
|
|
|
|
|
},
|
|
|
|
|
//确认复制
|
|
|
|
|
copyFn() {
|
|
|
|
|
let crr = [];
|
|
|
|
|
let appRoleList = this.roleList;
|
|
|
|
|
for (let i = 0; i < appRoleList.length; i++) {
|
|
|
|
|
if (appRoleList[i].checked) {
|
|
|
|
|
crr.push(appRoleList[i].id);
|
|
|
|
|
if (appRoleList[i].list.length) {
|
|
|
|
|
for (let j = 0; j < appRoleList[i].list.length; j++) {
|
|
|
|
|
if (appRoleList[i].list[j].checked) {
|
|
|
|
|
crr.push(appRoleList[i].list[j].id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this.instance.post(`${this.actions.modify}?menus=${crr}`, null, {
|
|
|
|
|
params: {
|
|
|
|
|
roleName: this.editName,
|
|
|
|
|
appId: this.row.appId,
|
2025-01-07 09:20:48 +08:00
|
|
|
type: this.row.type
|
2024-12-18 10:16:27 +08:00
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
.then((res) => {
|
|
|
|
|
if (res.code == 0) {
|
|
|
|
|
this.$message({message: "复制成功", type: "success"});
|
|
|
|
|
this.copyDialog = false;
|
|
|
|
|
this.searchList()
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
dataInit() {
|
|
|
|
|
this.multipleSelection = [];
|
|
|
|
|
this.row = {};
|
|
|
|
|
},
|
|
|
|
|
openRightsGraph(row) {
|
|
|
|
|
this.rightsGraph = true
|
|
|
|
|
this.selectApp = row
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
.AppRoleRightsManager {
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
:deep( .ai-dialog ) {
|
|
|
|
|
.ai-card {
|
|
|
|
|
box-shadow: none;
|
|
|
|
|
border: 1px solid #eee;
|
|
|
|
|
|
|
|
|
|
.aibar {
|
|
|
|
|
height: 40px;
|
|
|
|
|
background: #f3f6f9;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.ai-card__body {
|
|
|
|
|
padding: 0 16px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
:deep( .rightsGraphDialog ) {
|
|
|
|
|
.el-dialog__body {
|
|
|
|
|
padding: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.ai-dialog__content {
|
|
|
|
|
padding-bottom: 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
:deep( .datail-table-body ) {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: auto;
|
|
|
|
|
margin-bottom: 16px;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
|
|
|
|
|
.datail-item {
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
width: 50%;
|
|
|
|
|
height: 24px;
|
|
|
|
|
line-height: 24px;
|
|
|
|
|
|
|
|
|
|
span {
|
|
|
|
|
display: inline-block;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.item-name {
|
|
|
|
|
width: 102px;
|
|
|
|
|
padding-left: 16px;
|
|
|
|
|
color: #333;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.datail-item:nth-of-type(2n - 1) {
|
|
|
|
|
border-right: 1px solid rgba(208, 212, 220, 1);
|
|
|
|
|
width: calc(50% - 1px);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.padd-l0 {
|
|
|
|
|
padding-left: 0 !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pad-l16 {
|
|
|
|
|
padding-left: 16px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
</style>
|