You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
616 lines
19 KiB
616 lines
19 KiB
<!--
|
|
@ 作者: 秦东
|
|
@ 时间: 2025-12-23 13:29:28
|
|
@ 备注: App应用授权
|
|
-->
|
|
<script lang='ts' setup>
|
|
import { appTableBut, appListBut,appDetailBut,formBaseBut,appGroupBut } from "@/utils/workflow/const";
|
|
import { AppMenuPowerTree, AppPowerTreeMaster, SetupAppMenuPower } from "@/api/system/roleapi/types";
|
|
import { getAppGroupo,getGroupAppList,getAppMenuList,appGroupPowerConfig,appPowerConfig } from "@/api/system/roleapi/postrole";
|
|
import { orgInfo } from "@/api/displayboardapi/types";
|
|
|
|
const props = defineProps({
|
|
appType: {
|
|
type: String,
|
|
default: "app"
|
|
},
|
|
powerType: {
|
|
type: String,
|
|
default: "org"
|
|
},
|
|
roleId: {
|
|
type: String,
|
|
default: "313"
|
|
},
|
|
orgTree: {
|
|
type: Array as PropType<orgInfo[]>,
|
|
default: () => []
|
|
}
|
|
})
|
|
const orgTree = computed(() => props.orgTree);
|
|
const oneGroupActiveTab = ref<string>("first"); //单个分组权限选择
|
|
const oneAppActiveTab = ref<string>("first"); //单个分组权限选择
|
|
const appGroupPower = reactive<SetupAppMenuPower>({
|
|
groupButPower:[],
|
|
appList:[]
|
|
}); //应用分组权限
|
|
const oneGroupAppList = ref<AppPowerTreeMaster[]>([]);
|
|
const oneAppMenuList = ref<AppMenuPowerTree[]>([]);
|
|
const systemMenuTreePropsing = {
|
|
children: "child",
|
|
label: "name",
|
|
value: "id",
|
|
};
|
|
const groupLoading = ref<boolean>(false);
|
|
const appLoading = ref<boolean>(false);
|
|
const menuLoading = ref<boolean>(false);
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2025-12-25 10:36:22
|
|
@ 功能: 初始化获取数据
|
|
*/
|
|
const getAppList = () => {
|
|
groupLoading.value = true;
|
|
let sendData = {
|
|
powerId: props.roleId,
|
|
powerType: props.powerType,
|
|
}
|
|
getAppGroupo(sendData).then((res:any) => {
|
|
console.log("初始化获取数据--->",res)
|
|
if(res.code == 0){
|
|
appGroupPower.groupButPower = res.data.groupButPower;
|
|
appGroupPower.appList = res.data.groupList;
|
|
if(res.data.groupList && Array.isArray(res.data.groupList) && res.data.groupList.length > 0){
|
|
oneGroupActiveTab.value = res.data.groupList[0].id;
|
|
nextTick(() => {
|
|
getGroupAppListOne();
|
|
})
|
|
}
|
|
}
|
|
groupLoading.value = false;
|
|
}).finally(() => {
|
|
groupLoading.value = false;
|
|
})
|
|
}
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2025-12-25 11:07:44
|
|
@ 功能: 获取App列表
|
|
*/
|
|
const getGroupAppListOne = () => {
|
|
appLoading.value = true;
|
|
menuLoading.value = true;
|
|
let sendData = {
|
|
roleId: props.roleId,
|
|
powerType: props.powerType,
|
|
group: oneGroupActiveTab.value,
|
|
}
|
|
getGroupAppList(sendData).then((res:any) => {
|
|
console.log("获取App列表--->",res)
|
|
if(res.code == 0){
|
|
oneGroupAppList.value = res.data;
|
|
if(res.data && Array.isArray(res.data) && res.data.length > 0){
|
|
oneAppActiveTab.value = res.data[0].id;
|
|
nextTick(() => {
|
|
getAppMenuListOne();
|
|
})
|
|
}
|
|
}
|
|
appLoading.value = false;
|
|
}).finally(() => {
|
|
appLoading.value = false;
|
|
})
|
|
}
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2025-12-25 13:36:45
|
|
@ 功能: 获取菜单列表
|
|
*/
|
|
const getAppMenuListOne = () => {
|
|
menuLoading.value = true;
|
|
let sendData = {
|
|
roleId: props.roleId,
|
|
powerType: props.powerType,
|
|
group: oneGroupActiveTab.value,
|
|
appId: oneAppActiveTab.value,
|
|
}
|
|
getAppMenuList(sendData).then((res:any) => {
|
|
console.log("获取菜单列表--->",res)
|
|
if(res.code == 0){
|
|
// oneGroupAppList.value = res.data;
|
|
oneAppMenuList.value = res.data;
|
|
}
|
|
menuLoading.value = false;
|
|
}).finally(() => {
|
|
menuLoading.value = false;
|
|
})
|
|
}
|
|
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2025-12-25 16:21:19
|
|
@ 功能: 监听变化App分组
|
|
*/
|
|
watch(() => oneGroupActiveTab.value, (newVal, oldVal) => {
|
|
if(newVal != oldVal){
|
|
getGroupAppListOne();
|
|
}
|
|
},{
|
|
deep: true
|
|
})
|
|
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2025-12-25 16:30:05
|
|
@ 功能: 监听变化App应用
|
|
*/
|
|
watch(() => oneAppActiveTab.value, (newVal, oldVal) => {
|
|
if(newVal != oldVal){
|
|
getAppMenuListOne();
|
|
}
|
|
},{
|
|
deep: true
|
|
})
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2025-12-25 16:40:07
|
|
@ 功能: app权限全选
|
|
*/
|
|
const pickAppAllPower = (item:AppPowerTreeMaster) => {
|
|
console.log("app权限全选--->",item)
|
|
if(item.isPick){
|
|
item.operationButton = ["bjapp","scapp","xzfg","scfg","yzfg","xz","bj","sc","yz","jczdh","yysz","yyfb"]
|
|
}else{
|
|
item.operationButton = [];
|
|
}
|
|
}
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2025-12-18 13:58:21
|
|
@ 功能: 选择App菜单是选中状态下,关联操作按钮
|
|
*/
|
|
const handleAppMenuChange = (item:any) => {
|
|
console.log("----------------选择App菜单---------->",item)
|
|
if(item.isTrue){
|
|
item.formPower = [ "zc", "tj", "dy", "sc", "fz"]
|
|
item.formPowerIsAll = true
|
|
item.listPower = [ "newAdd", "import", "export", "sc", "dy", "showQrCode","del","bj"]
|
|
item.listPowerIsAll = true
|
|
}else{
|
|
item.formPower = []
|
|
item.listPower = []
|
|
item.listPowerIsAll = false
|
|
item.formPowerIsAll = false
|
|
}
|
|
if(item.children && Array.isArray(item.children)){
|
|
item.children = handleAppChange(item.children,item.isTrue)
|
|
}
|
|
}
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2025-12-18 11:23:40
|
|
@ 功能: 循环递归联动赋值
|
|
*/
|
|
const handleAppChange = (item:any,isTrue:boolean) => {
|
|
// console.log("--------循环递归联动赋值------------------>",item)
|
|
if(item && Array.isArray(item)){
|
|
item.forEach((menu:any) => {
|
|
menu.isTrue = isTrue
|
|
if(isTrue){
|
|
menu.formPower = [ "zc", "tj", "dy", "sc", "fz"]
|
|
menu.listPower = [ "newAdd", "import", "export", "sc", "dy", "showQrCode","del","bj"]
|
|
menu.listPowerIsAll = true
|
|
menu.formPowerIsAll = true
|
|
}else{
|
|
menu.formPower = []
|
|
menu.listPower = []
|
|
menu.listPowerIsAll = false
|
|
menu.formPowerIsAll = false
|
|
}
|
|
if(menu.children && Array.isArray(menu.children)){
|
|
menu.children = handleAppChange(menu.children,isTrue)
|
|
}
|
|
})
|
|
}
|
|
|
|
return item
|
|
}
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2025-12-20 15:33:37
|
|
@ 功能: 全选
|
|
*/
|
|
const pickAllBut = (item:any,types:number) => {
|
|
console.log("--全选------------------------>",item,types)
|
|
// item.isTrue = !item.isTrue
|
|
switch(types){
|
|
case 1:
|
|
// item.pagePowerIsAll = item.isTrue
|
|
item.pagePower = item.pagePowerIsAll ? ["lc","lb","sj","dy","nc"] : []
|
|
|
|
break
|
|
case 2:
|
|
// item.formPowerIsAll = item.isTrue
|
|
item.formPower = item.formPowerIsAll ? ["zc", "tj", "dy", "sc", "fz"] : []
|
|
break
|
|
case 3:
|
|
// item.listPowerIsAll = item.isTrue
|
|
item.listPower = item.listPowerIsAll ? ["newAdd", "import", "export", "sc", "dy", "showQrCode","del","bj"] : []
|
|
break
|
|
case 4:
|
|
// item.isTrue = item.isTrue
|
|
item.operationButton = item.isPick ? ["bjapp","scapp","xzfg","scfg","yzfg","xz","bj","sc","yz","jczdh","yysz","yyfb"] : []
|
|
break
|
|
}
|
|
}
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2025-12-26 15:50:20
|
|
@ 功能: 分组全选全选
|
|
*/
|
|
const pickAllGroupBut = (item:any) => {
|
|
console.log("分组全选全选--->",item)
|
|
if(item){
|
|
appGroupPower.groupButPower = ["xz","dl","bj","xzapp"]
|
|
}else{
|
|
appGroupPower.groupButPower = []
|
|
}
|
|
}
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2025-12-25 16:53:11
|
|
@ 功能: 页面授权联动
|
|
*/
|
|
const changePageButBox = (item:any,types:number) => {
|
|
console.log("页面授权联动--->",item.pagePower.length,item,types)
|
|
if(item.pagePower.length == types){
|
|
item.pagePowerIsAll = true
|
|
}else{
|
|
item.pagePowerIsAll = false
|
|
}
|
|
}
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2025-12-26 15:47:23
|
|
@ 功能: 分组授权
|
|
*/
|
|
const changeGroupPageButBox = () => {
|
|
groupLoading.value = true
|
|
let sendData = {
|
|
powerId: props.roleId,
|
|
powerType: props.powerType,
|
|
groupButPower: appGroupPower.groupButPower,
|
|
}
|
|
appGroupPowerConfig(sendData).then((res:any) => {
|
|
if(res.code == 0){
|
|
ElMessage({
|
|
message: "分组授权成功",
|
|
type: "success",
|
|
});
|
|
}else{
|
|
ElMessage({
|
|
message: res.msg,
|
|
type: "error",
|
|
});
|
|
}
|
|
groupLoading.value = false
|
|
}).finally(() => {
|
|
groupLoading.value = false
|
|
})
|
|
console.log("分组授权--->",sendData)
|
|
}
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2025-12-26 16:31:11
|
|
@ 功能: 提交应用授权
|
|
*/
|
|
const submintAppPower = (appCont:AppPowerTreeMaster) => {
|
|
menuLoading.value = true
|
|
let sendData = {
|
|
powerId: props.roleId,
|
|
powerType: props.powerType,
|
|
appId: appCont.id,
|
|
appIsTrue: appCont.isTrue,
|
|
appPower: appCont.operationButton,
|
|
menuList: oneAppMenuList.value,
|
|
}
|
|
appPowerConfig(sendData).then((res:any) => {
|
|
if(res.code == 0){
|
|
ElMessage({
|
|
message: "应用授权成功",
|
|
type: "success",
|
|
});
|
|
}else{
|
|
ElMessage({
|
|
message: res.msg,
|
|
type: "error",
|
|
});
|
|
}
|
|
menuLoading.value = false
|
|
}).finally(() => {
|
|
menuLoading.value = false
|
|
})
|
|
|
|
console.log("提交应用授权--->",sendData)
|
|
console.log("提交应用授权--appCont->",appCont)
|
|
}
|
|
defineExpose({
|
|
getAppList
|
|
})
|
|
</script>
|
|
<template>
|
|
<div class="app-tabs-content">
|
|
<div class="appGroupPowerBut">
|
|
<div class="appGroupPowerButTitle">应用分组权限</div>
|
|
<div class="appGroupPowerButList">
|
|
<el-checkbox label="全选" @change="pickAllGroupBut" />
|
|
<el-checkbox-group v-model="appGroupPower.groupButPower">
|
|
<el-checkbox
|
|
v-for="city in appGroupBut"
|
|
:key="city.key"
|
|
:label="city.label"
|
|
:value="city.value"
|
|
>
|
|
{{ city.label }}
|
|
</el-checkbox>
|
|
</el-checkbox-group>
|
|
</div>
|
|
<div class="appGroupPowerButAuth">
|
|
<el-button type="primary" v-loading="groupLoading" element-loading-text="Loading..." @click="changeGroupPageButBox">分组授权</el-button>
|
|
</div>
|
|
</div>
|
|
<div class="appGroupTabs">
|
|
<el-tabs v-model="oneGroupActiveTab" class="demo-tabs" v-loading="groupLoading" element-loading-text="Loading...">
|
|
<el-tab-pane v-for="item in appGroupPower.appList " :key="item.id" label="应用权限" :name="item.id">
|
|
<template #label>
|
|
<div class="appTabsCheckbox">
|
|
<el-checkbox v-model="item.isTrue" /><span>{{item.name}}</span>
|
|
</div>
|
|
</template>
|
|
</el-tab-pane>
|
|
</el-tabs>
|
|
<div class="appMenuBox">
|
|
<div class="appInfoBox">
|
|
<el-tabs v-model="oneAppActiveTab" class="demo-tabs left_hight" tab-position="left" v-loading="appLoading" element-loading-text="Loading...">
|
|
<el-tab-pane v-for="item in oneGroupAppList " :key="item.id" label="应用权限" :name="item.id">
|
|
<template #label>
|
|
<div class="apptitle">
|
|
<el-checkbox v-model="item.isTrue" /><span>{{item.name}}</span>
|
|
</div>
|
|
</template>
|
|
<div class="oneAppPower" v-loading="menuLoading" element-loading-text="Loading...">
|
|
|
|
<div class="appGroupPowerButTitle">App应用权限</div>
|
|
<div style="width:100%; padding:0 5px;">
|
|
<el-checkbox label="全选" v-model="item.isPick" @change="pickAppAllPower(item)" />
|
|
</div>
|
|
<div class="app-form-checkbox">
|
|
<el-checkbox-group v-model="item.operationButton">
|
|
<el-checkbox
|
|
v-for="city in appDetailBut"
|
|
:key="city.key"
|
|
:label="city.label"
|
|
:value="city.value"
|
|
>
|
|
{{ city.label }}
|
|
</el-checkbox>
|
|
</el-checkbox-group>
|
|
</div>
|
|
<div class="shouquan">
|
|
<el-button type="primary" v-loading="menuLoading" element-loading-text="Loading..." @click="submintAppPower(item)">提交App权限</el-button>
|
|
</div>
|
|
</div>
|
|
</el-tab-pane>
|
|
</el-tabs>
|
|
</div>
|
|
<div class="appMenuBody">
|
|
|
|
<el-table
|
|
:data="oneAppMenuList"
|
|
style="width: 100%;"
|
|
class="tableScrollbar"
|
|
row-key="id"
|
|
border
|
|
default-expand-all
|
|
v-loading="menuLoading" element-loading-text="Loading..."
|
|
>
|
|
<el-table-column prop="name" label="栏目名称" >
|
|
<template #default="scope">
|
|
<el-checkbox v-model="scope.row.isTrue" :value="scope.row.isTrue" @change="handleAppMenuChange(scope.row)"></el-checkbox>
|
|
{{ scope.row.name }}
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="pagePower" label="页面权力" >
|
|
<template #header>
|
|
<el-text>页面权限</el-text>
|
|
</template>
|
|
<template #default="scope">
|
|
<el-checkbox label="全选" v-model="scope.row.pagePowerIsAll" @change="pickAllBut(scope.row,1)" />
|
|
<el-checkbox-group v-model="scope.row.pagePower">
|
|
<el-checkbox
|
|
v-for="city in formBaseBut"
|
|
:key="city.key"
|
|
:label="city.label"
|
|
:value="city.value"
|
|
@change="changePageButBox(scope.row,formBaseBut.length)"
|
|
>
|
|
{{ city.label }}
|
|
</el-checkbox>
|
|
</el-checkbox-group>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="formPower" label="表单权限" >
|
|
<template #header>
|
|
<el-text>表单权限</el-text>
|
|
</template>
|
|
<template #default="scope">
|
|
<el-checkbox label="全选" v-model="scope.row.formPowerIsAll" @change="pickAllBut(scope.row,2)" />
|
|
<el-checkbox-group v-model="scope.row.formPower">
|
|
<el-checkbox
|
|
v-for="city in appTableBut"
|
|
:key="city.value"
|
|
:label="city.label"
|
|
:value="city.value"
|
|
>
|
|
{{ city.label }}
|
|
</el-checkbox>
|
|
</el-checkbox-group>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="listPower" label="listPower" >
|
|
<template #header>
|
|
<el-text>列表权限</el-text>
|
|
</template>
|
|
<template #default="scope">
|
|
<el-checkbox v-model="scope.row.listPowerIsAll" label="全选" @change="pickAllBut(scope.row,3)" />
|
|
<el-checkbox-group v-model="scope.row.listPower">
|
|
<el-checkbox
|
|
v-for="city in appListBut"
|
|
:key="city.key"
|
|
:label="city.label"
|
|
:value="city.value"
|
|
>
|
|
{{ city.label }}
|
|
</el-checkbox>
|
|
</el-checkbox-group>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="visibleRange" label="数据权限" >
|
|
<template #header>
|
|
<el-text>数据权限</el-text>
|
|
</template>
|
|
<template #default="scope">
|
|
<el-radio-group
|
|
v-model="scope.row.visibleRange.types"
|
|
>
|
|
<el-row>
|
|
<el-col :span="24"><el-radio :value="1">本人</el-radio></el-col>
|
|
<el-col :span="24"><el-radio :value="2">本岗位</el-radio></el-col>
|
|
<el-col :span="24"><el-radio :value="3">本部门</el-radio></el-col>
|
|
<el-col :span="24"><el-radio :value="4">本分部</el-radio></el-col>
|
|
<el-col :span="24">
|
|
<el-radio :value="5">指定行政组织</el-radio>
|
|
<el-tree-select
|
|
v-if="scope.row.visibleRange.types == 5"
|
|
v-model="scope.row.visibleRange.attribute"
|
|
:data="orgTree"
|
|
style="width: 100%"
|
|
node-key="id"
|
|
:props="systemMenuTreePropsing"
|
|
clearable
|
|
multiple
|
|
:render-after-expand="false"
|
|
show-checkbox
|
|
collapse-tags
|
|
collapse-tags-tooltip
|
|
/>
|
|
</el-col>
|
|
<el-col :span="24"><el-radio :value="6">所有</el-radio></el-col>
|
|
</el-row>
|
|
</el-radio-group>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</template>
|
|
<style lang='scss' scoped>
|
|
.app-tabs-content {
|
|
width: 100%;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
.appGroupPowerBut{
|
|
width: 120px;
|
|
border: 1px solid #e4e7ed;
|
|
|
|
.appGroupPowerButList{
|
|
padding: 5px;
|
|
}
|
|
.appGroupPowerButAuth{
|
|
padding: 5px;
|
|
text-align: center;
|
|
button{
|
|
width: 100%;
|
|
}
|
|
}
|
|
}
|
|
.appGroupTabs{
|
|
width: calc(100% - 140px);
|
|
.appTabsCheckbox{
|
|
display: flex;
|
|
align-items: center;
|
|
label{
|
|
padding:0 5px 0 10px;
|
|
}
|
|
span{
|
|
padding:0 10px 0 0;
|
|
}
|
|
}
|
|
:deep .el-tabs__content{
|
|
padding: 0;
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
.left_hight{
|
|
height: calc(100vh - 350px);
|
|
}
|
|
.appGroupPowerButTitle{
|
|
font-size: 16px;
|
|
font-weight: bold;
|
|
background-color: #f5f7fa;
|
|
padding: 5px;
|
|
border-radius: 5px;
|
|
}
|
|
.oneAppPower{
|
|
width: 120px;
|
|
border: 1px solid #e4e7ed;
|
|
.app-form-checkbox{
|
|
padding:0 5px;
|
|
}
|
|
}
|
|
.tableScrollbar{
|
|
width: 100%;
|
|
height: calc(100vh - 365px);
|
|
overflow: hidden;
|
|
overflow-y: auto;
|
|
margin-top: 15px;
|
|
}
|
|
.appMenuBox{
|
|
display: flex;
|
|
justify-content: space-between;
|
|
.appInfoBox{
|
|
width: 410px;
|
|
::deep .el-tabs__content{
|
|
padding: 0;
|
|
}
|
|
}
|
|
.appMenuBody{
|
|
width: calc(100% - 410px);
|
|
}
|
|
}
|
|
.apptitle{
|
|
width: 200px;
|
|
text-align: left;
|
|
padding: 0 10px;
|
|
display: flex;
|
|
align-items: center;
|
|
overflow-x: auto;
|
|
word-wrap: break-word; /* 旧版浏览器兼容 */
|
|
overflow-wrap: break-word; /* 标准属性 */
|
|
word-break: break-all; /* 强制任意字符断行 */
|
|
white-space: pre-wrap; /* 保留空格换行 */
|
|
span{
|
|
margin-left: 5px;
|
|
}
|
|
}
|
|
.shouquan{
|
|
width: 100%;
|
|
text-align: center;
|
|
padding: 5px 0 10px 0;
|
|
}
|
|
</style>
|
|
|