mirror of https://gitee.com/xiaonuobase/snowy
【更新】完善前端给角色授权移动端菜单功能
parent
a2ac82a1e8
commit
fed5dc8bbf
|
@ -46,6 +46,14 @@ export default {
|
|||
roleGrantResource(data) {
|
||||
return request('grantResource', data)
|
||||
},
|
||||
// 获取角色拥有移动端菜单
|
||||
roleOwnMobileMenu(data) {
|
||||
return request('ownMobileMenu', data, 'get')
|
||||
},
|
||||
// 给角色授权移动端菜单
|
||||
roleGrantMobileMenu(data) {
|
||||
return request('grantMobileMenu', data)
|
||||
},
|
||||
// 获取角色拥有权限
|
||||
roleOwnPermission(data) {
|
||||
return request('ownPermission', data, 'get')
|
||||
|
@ -70,6 +78,10 @@ export default {
|
|||
roleResourceTreeSelector(data) {
|
||||
return request('resourceTreeSelector', data, 'get')
|
||||
},
|
||||
// 获取移动端菜单授权树
|
||||
roleMobileMenuTreeSelector(data) {
|
||||
return request('mobileMenuTreeSelector', data, 'get')
|
||||
},
|
||||
// 获取权限授权树
|
||||
rolePermissionTreeSelector(data) {
|
||||
return request('permissionTreeSelector', data, 'get')
|
||||
|
|
|
@ -0,0 +1,246 @@
|
|||
<template>
|
||||
<a-drawer
|
||||
title="授权移动端资源"
|
||||
:width="drawerWidth"
|
||||
:visible="visible"
|
||||
:destroy-on-close="true"
|
||||
:show-pagination="false"
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
:footer-style="{ textAlign: 'right' }"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-spin :spinning="spinningLoading">
|
||||
<a-radio-group v-model:value="moduleId" button-style="solid" style="padding-bottom: 10px">
|
||||
<a-radio-button
|
||||
:key="module.id"
|
||||
v-for="module in echoDatalist"
|
||||
:value="module.id"
|
||||
@click="moduleClock(module.id)"
|
||||
>
|
||||
<component :is="module.icon" />
|
||||
{{ module.title }}</a-radio-button
|
||||
>
|
||||
</a-radio-group>
|
||||
|
||||
<a-table size="middle" :columns="columns" :data-source="loadDatas" :pagination="false" bordered>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex === 'parentName'">
|
||||
<a-checkbox :checked="record.parentCheck" @update:checked="(val) => changeParent(record, val)">
|
||||
{{ record.parentName }}
|
||||
</a-checkbox>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'title'">
|
||||
<a-checkbox :checked="record.nameCheck" @update:checked="(val) => changeSub(record, val)">{{
|
||||
record.title
|
||||
}}</a-checkbox>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-spin>
|
||||
<template #footer>
|
||||
<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
|
||||
<a-button type="primary" :loading="submitLoading" @click="onSubmit">保存</a-button>
|
||||
</template>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script setup name="grantMobileResourceForm">
|
||||
import tool from '@/utils/tool'
|
||||
import roleApi from '@/api/sys/roleApi'
|
||||
const spinningLoading = ref(false)
|
||||
let firstShowMap = $ref({})
|
||||
const emit = defineEmits({ successful: null })
|
||||
const submitLoading = ref(false)
|
||||
// 抽屉的宽度
|
||||
const drawerWidth = 600
|
||||
// 自动获取宽度,默认获取浏览器的宽度的90%
|
||||
//(window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) * 0.9
|
||||
|
||||
const columns = [
|
||||
{
|
||||
key: 'parentName',
|
||||
title: '一级目录',
|
||||
dataIndex: 'parentName',
|
||||
customCell: (row, index) => {
|
||||
const parentName = row.parentName
|
||||
const indexArr = firstShowMap[parentName]
|
||||
if (index === indexArr[0]) {
|
||||
return { rowSpan: indexArr.length }
|
||||
}
|
||||
return { rowSpan: 0 }
|
||||
},
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
key: 'title',
|
||||
title: '菜单',
|
||||
dataIndex: 'title',
|
||||
width: 200
|
||||
}
|
||||
]
|
||||
const echoDatalist = ref([])
|
||||
const moduleId = ref('')
|
||||
const loadDatas = ref([])
|
||||
|
||||
// 获取数据
|
||||
const loadData = async () => {
|
||||
// firstShowMap = {} // 重置单元格合并映射
|
||||
// 如果有数据,我们再不去反复的查询
|
||||
if (echoDatalist.value.length > 0) {
|
||||
let data = echoDatalist.value.find((f) => f.id === moduleId.value).menu
|
||||
loadDatas.value = data
|
||||
} else {
|
||||
// 获取表格数据
|
||||
spinningLoading.value = true
|
||||
const res = await roleApi.roleMobileMenuTreeSelector()
|
||||
const param = {
|
||||
id: resultDataModel.id
|
||||
}
|
||||
// 获取回显数据
|
||||
const resEcho = await roleApi.roleOwnMobileMenu(param)
|
||||
spinningLoading.value = false
|
||||
echoDatalist.value = echoModuleData(res, resEcho)
|
||||
moduleId.value = res[0].id
|
||||
loadDatas.value = echoDatalist.value[0].menu
|
||||
}
|
||||
}
|
||||
let visible = $ref(false)
|
||||
// 返回的数据模型,最终需要转换成这样
|
||||
let resultDataModel = {
|
||||
id: '',
|
||||
grantInfoList: []
|
||||
}
|
||||
// 打开抽屉
|
||||
const onOpen = (record) => {
|
||||
resultDataModel.id = record.id
|
||||
visible = true
|
||||
firstShowMap = {}
|
||||
loadData()
|
||||
}
|
||||
// 数据转换
|
||||
const echoModuleData = (data, resEcho) => {
|
||||
// 通过应用循环
|
||||
data.forEach((module) => {
|
||||
if (module.menu) {
|
||||
// 加入回显内容
|
||||
module.menu.forEach((item) => {
|
||||
const menueCheck = ref(0)
|
||||
if (resEcho.grantInfoList.length > 0) {
|
||||
resEcho.grantInfoList.forEach((grant) => {
|
||||
if (item.id === grant.menuId) {
|
||||
menueCheck.value++
|
||||
}
|
||||
})
|
||||
}
|
||||
// 回显前面的2个
|
||||
if (menueCheck.value > 0) {
|
||||
item.parentCheck = true
|
||||
item.nameCheck = true
|
||||
}
|
||||
})
|
||||
|
||||
// 排序
|
||||
module.menu = module.menu.sort((a, b) => {
|
||||
return a.parentId - b.parentId
|
||||
})
|
||||
// 缓存加入索引
|
||||
module.menu.forEach((item, index) => {
|
||||
// 下面就是用来知道不同的一级菜单里面有几个二级菜单,以及他们所在的索引
|
||||
if (firstShowMap[item.parentName]) {
|
||||
firstShowMap[item.parentName].push(index)
|
||||
} else {
|
||||
firstShowMap[item.parentName] = [index]
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
return data
|
||||
}
|
||||
|
||||
// 通过应用分菜单
|
||||
const moduleClock = (value) => {
|
||||
moduleId.value = value
|
||||
loadData()
|
||||
}
|
||||
// 遍历字段
|
||||
const handleOnlySelf = (record, key, val) => {
|
||||
record[key].forEach((item) => {
|
||||
// 处理'button'选中状态
|
||||
item.check = val
|
||||
})
|
||||
}
|
||||
// 二级菜单的勾选
|
||||
const changeSub = (record, val) => {
|
||||
// 选中二级菜单
|
||||
record.nameCheck = val
|
||||
}
|
||||
// 当点击首列的勾选
|
||||
const changeParent = (record, val) => {
|
||||
record.parentCheck = val
|
||||
// 通过这个应用id,找到应用下的所有菜单
|
||||
const moduleMenu = echoDatalist.value.find((f) => record.module === f.id)
|
||||
const parentName = record.parentName
|
||||
// 获取同一级菜单的所有索引
|
||||
const indexArr = firstShowMap[parentName]
|
||||
indexArr.forEach((indexItem) => {
|
||||
// 获取同一级菜单的所有行
|
||||
const row = moduleMenu.menu[indexItem]
|
||||
// 给这些菜单的索引去勾选
|
||||
changeSub(row, val)
|
||||
})
|
||||
}
|
||||
// 关闭抽屉
|
||||
const onClose = () => {
|
||||
// 将这些缓存的给清空
|
||||
echoDatalist.value = []
|
||||
moduleId.value = ''
|
||||
loadDatas.value = []
|
||||
firstShowMap = {}
|
||||
visible = false
|
||||
}
|
||||
// 提交之前转换数据
|
||||
const convertData = () => {
|
||||
resultDataModel.grantInfoList = []
|
||||
echoDatalist.value.forEach((table) => {
|
||||
if (table.menu) {
|
||||
table.menu.forEach((item) => {
|
||||
const grantInfo = {
|
||||
menuId: ''
|
||||
}
|
||||
if (item.nameCheck) {
|
||||
grantInfo.menuId = item.id
|
||||
resultDataModel.grantInfoList.push(grantInfo)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
return resultDataModel
|
||||
}
|
||||
// 验证并提交数据
|
||||
const onSubmit = () => {
|
||||
const param = convertData()
|
||||
submitLoading.value = true
|
||||
roleApi
|
||||
.roleGrantMobileMenu(param)
|
||||
.then(() => {
|
||||
onClose()
|
||||
emit('successful')
|
||||
})
|
||||
.finally(() => {
|
||||
submitLoading.value = false
|
||||
})
|
||||
}
|
||||
// 调用这个函数将子组件的一些数据和方法暴露出去
|
||||
defineExpose({
|
||||
onOpen
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 重写复选框的样式 */
|
||||
.ant-checkbox-wrapper {
|
||||
margin-left: 0px !important;
|
||||
padding-top: 2px !important;
|
||||
padding-bottom: 2px !important;
|
||||
}
|
||||
</style>
|
|
@ -77,6 +77,9 @@
|
|||
<a-menu-item>
|
||||
<a @click="GrantResourceForm.onOpen(record)">授权资源</a>
|
||||
</a-menu-item>
|
||||
<a-menu-item>
|
||||
<a @click="GrantMobileResourceForm.onOpen(record)">授权移动端资源</a>
|
||||
</a-menu-item>
|
||||
<a-menu-item>
|
||||
<a @click="GrantPermissionForm.onOpen(record)">授权权限</a>
|
||||
</a-menu-item>
|
||||
|
@ -93,6 +96,7 @@
|
|||
</a-col>
|
||||
</a-row>
|
||||
<grantResourceForm ref="GrantResourceForm" @successful="table.refresh(true)" />
|
||||
<grantMobileResourceForm ref="GrantMobileResourceForm" @successful="table.refresh(true)" />
|
||||
<grantPermissionForm ref="GrantPermissionForm" @successful="table.refresh(true)" />
|
||||
<Form ref="form" @successful="table.refresh(true)" />
|
||||
<user-selector-plus
|
||||
|
@ -108,6 +112,7 @@
|
|||
import roleApi from '@/api/sys/roleApi'
|
||||
import orgApi from '@/api/sys/orgApi'
|
||||
import grantResourceForm from './grantResourceForm.vue'
|
||||
import grantMobileResourceForm from './grantMobileResourceForm.vue'
|
||||
import grantPermissionForm from './grantPermissionForm.vue'
|
||||
import userSelectorPlus from '@/components/Selector/userSelectorPlus.vue'
|
||||
import Form from './form.vue'
|
||||
|
@ -153,6 +158,7 @@
|
|||
const table = ref()
|
||||
const form = ref()
|
||||
const GrantResourceForm = ref()
|
||||
const GrantMobileResourceForm = ref()
|
||||
const GrantPermissionForm = ref()
|
||||
const userselectorPlusRef = ref()
|
||||
const searchFormRef = ref()
|
||||
|
|
Loading…
Reference in New Issue