Files
dvcp_v2_webapp/project/xumu/AppRoleRightsManager/AppRoleRightsManager.vue
aixianling 3f26b8b6df refactor(AppRoleRightsManager): BUG 526 优化角色用户展示和编辑功能- 重新设计角色用户列表的展示方式,使用标签替代原有格式
- 调整角色名称列宽,提高可读性- 编辑角色时增加角色类型参数,可能为后续流程使用
2025-01-08 16:00:05 +08:00

408 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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">
<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>
</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"},
{label: "角色名", prop: "name", width: 140},
{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,
name: item.name,
type: item.type,
},
});
},
//删除
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,
type: this.row.type
},
})
.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>