<template>
<el-dialog
:title="title"
:visible.sync="dialogFormVisible"
width="800px"
@close="close"
>
<el-form ref="form" label-width="80px" :model="form" :rules="rules">
<el-form-item label="角色码" prop="name">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="菜单">
<div class="vab-tree-border">
<el-cascader
ref="cascader"
v-model="selectedList"
collapse-tags
:disabled="form.id === 1 ? true : false"
:options="list"
:props="{
multiple: true,
value: 'id',
label: 'name',
children: 'children',
emitPath: false,
}"
size="medium"
:style="{ width: '100%' }"
@change="change"
/>
</div>
</el-form-item>
<!-- <el-form-item label="按钮权限">
<el-checkbox-group v-model="form.btnRolesCheckedList">
<el-checkbox v-for="item in btnRoles" :key="item.value" :label="item.value">
{{ item.lable }}
</el-checkbox>
</el-checkbox-group>
</el-form-item> -->
</el-form>
<template #footer>
<el-button @click="close">取 消</el-button>
<el-button type="primary" @click="save">确 定</el-button>
</template>
</el-dialog>
</template>
<script>
import { doEdit, getListMenus, getAllList, doAdd } from '@/api/roleManagement'
// import {
// getList
// } from '@/api/router'
import { translateDataToTree, translateTreeToData } from '@/utils/index'
export default {
name: 'RoleManagementEdit',
data() {
return {
form: {
btnRolesCheckedList: [],
},
rules: {
name: [
{
required: true,
trigger: 'blur',
message: '请输入角色码',
},
],
},
title: '', //添加/编辑
dialogFormVisible: false, //弹窗显示
list: [], //返回数据-shuixngjiegou
allListTest:[],
defaultCheckedKeys: [], //回显选中状态
// 存放选中的数据
selectedList: [],
/* btnRoles demo */
btnRoles: [
{
lable: '读',
value: 'read:system',
},
{
lable: '写',
value: 'write:system',
},
{
lable: '删',
value: 'delete:system',
},
],
}
},
watch: {},
created() {
this.getAll()
},
methods: {
//父组件调用获取数据
showEdit(row) {
if (!row) {
this.title = '添加'
this.form = Object.assign({}, row)
this.fetchData()
} else {
this.title = '编辑'
this.form = Object.assign({}, row)
this.fetchData()
}
this.dialogFormVisible = true
},
close() {
this.selectedList = []
this.$refs['form'].resetFields() //重置表单
this.form = this.$options.data().form
this.dialogFormVisible = false
},
//获取数据
fetchData() {
if (this.form.id == undefined) {
this.form.id = ''
}
const params = 'id=' + this.form.id
getListMenus(params).then((res) => {
// this.list = res
if (this.title == '添加') {
// this.test()
} else {
//编辑-选中数据回显
this.defaultCheckedKeys = []
res.forEach((item) => {
if (item.checked == true) {
this.defaultCheckedKeys.push(item)
}
})
// this.selectedList =[1,6,2,7,8,9,3,10]//级联需要数据结构
console.log('再次打开', this.defaultCheckedKeys)
this.test(this.defaultCheckedKeys)
}
})
},
getAll() {
getAllList().then((res) => {
this.list = translateDataToTree(res) //all菜单转树形结构
this.allListTest=res
console.log('allListTest',this.allListTest) //ok
})
},
test(val) {
//编辑
if (val) {
if (this.form.id === 1) {
//超级管理员默认选中全部菜单
// const uniqueArray = this.getIdsFromTree(this.list) //二维id数组
this.selectedList = uniqueArray.flat()
// console.log('test1',this.selectedList)
} else {
// let aa = translateDataToTree(this.defaultCheckedKeys) //选中部分
// const uniqueArray = this.getIdsFromTree(aa) //二维id数组
// this.selectedList = [...new Set(uniqueArray.flat())]
let obj=this.uniqueIdsAndPids(this.defaultCheckedKeys)
// let idArr =this.defaultCheckedKeys.map(({ id }) => id)//子id-ok
// let parentIDArr =this.defaultCheckedKeys.map(({ parent_id }) => parent_id)//传父id-ok
// const foundObjects = [... new Set([...idArr,...parentIDArr].filter(item => item !== 0))]
// this.selectedList =foundObjects//对父级操作不成功
this.selectedList =obj//ok
console.log('foundObjects',obj); // 输出找到的id
}
}
},
uniqueIdsAndPids(keys) {
const seenPids = new Set(); // 使用Set来存储已经出现过的parent_id
const resultArray = []; // 结果数组
for (const key of keys) {
// 检查parent_id是否为0,如果是,则不处理
if (key.parent_id === 0) continue;
// 检查parent_id是否已经出现过
if (!seenPids.has(key.parent_id)) {
// 如果parent_id是第一次出现,则添加当前对象的parent_id到结果数组
resultArray.push(key.parent_id);
// 将这个parent_id标记为已出现过
seenPids.add(key.parent_id);
// seenIds.add(key.id);
}
resultArray.push(key.id);
}
return resultArray;
},
change(v){
let changeList=this.findMatchingObjects(v, this.allListTest);
this.form.menu_ids =this.uniqueIdsAndPids(changeList)
// console.log(v,changeList,this.uniqueIdsAndPids(changeList));
},
//根据选中节点找到非树形结构总菜单所在对象
findMatchingObjects(numbers, objects) {
// 创建一个新数组来存储匹配的对象
const matchingObjects = [];
// 遍历数字数组
numbers.forEach(number => {
// 遍历对象数组以找到匹配的id
objects.forEach(obj => {
if (number === obj.id) {
// 如果找到匹配的id,将其添加到匹配对象数组中
matchingObjects.push(obj);
}
});
});
return matchingObjects;
},
//修改
save() {
this.$refs['form'].validate(async (valid) => {
if (valid && this.selectedList.length !== 0) {
if (this.title == '编辑') {
const params = this.form.id
// 使用 Set 去除重复的元素,并将结果转换为一维数组
// const uniqueArray = [...new Set(this.selectedList.flat())]
// 使用 Set 去除重复的元素,并且去掉等于0的值
// this.form.menu_ids =[...new Set([...this.selectedList, ...parentIDArrSave].filter(item => item !== 0))]
// console.log('params',params,this.form.menu_ids,this.selectedList); //ok2
doEdit(params, this.form).then((res) => {
this.$baseMessage('编辑成功', 'success')
this.defaultCheckedKeys = translateTreeToData(
this.defaultCheckedKeys
)
this.title = '编辑'
this.$emit('fetch-data')
})
}
if (this.title == '添加') {
this.form.menu_ids = this.selectedList.flat()
doAdd(this.form).then((res) => {
this.$baseMessage(res.message, 'success')
this.title = '添加'
this.$emit('fetch-data')
})
}
this.close()
}
})
},
// 递归函数,用于获取树形结构二维id数组
getIdsFromTree(array) {
function traverse(node) {
// 确保 node 对象存在 id 属性
const ids = node.id !== undefined ? [node.id] : []
// 检查 children 属性是否存在,并且是否为数组
if (node.children && Array.isArray(node.children)) {
// 递归遍历子节点,并将结果与当前节点的 id 合并
node.children.forEach((child) => {
// 递归调用 traverse 并解构返回值
const [childId, ...childIds] = traverse(child)
// 将子节点的 id 添加到当前节点的 ids 数组中
ids.push(childId, ...childIds)
})
}
// 返回当前节点的 ids 数组
console.log('ids',ids)
// return ids
}
// 遍历树的根节点,并对每个节点调用 traverse 函数
return array.map((root) => traverse(root))
},
getCheckedNodes (checkedNodes) {
// 根据 value 来找到对应的节点
// 这里需要根据您的 options 数据结构来实现
const checkedNodesList = this.list.reduce((acc, option) => {
// 这里需要递归地构建 checkedNodesList
// 以下代码仅为示例,您需要根据实际情况进行调整
if (value.includes(option.id)) {
acc.push({ ...option, children: [] }); // 假设 option 是一个对象,并且有 value 属性
if (option.children) {
option.children.forEach(child => {
if (value.includes(child.id)) {
acc.push({ ...child, children: [] });
}
});
}
}
return acc;
}, []);
return checkedNodesList;
},
}
}
</script>
<style lang="scss" scoped>
.vab-tree-border {
// height: 200px;
height: auto;
// padding: $base-padding;
// overflow-y: auto;
// border: 1px solid #dcdfe6;
border-radius: $base-border-radius;
}
</style>
父组件--就是看下调用,和级联没有关系
<template>
<div class="role-management-container">
<vab-query-form>
<vab-query-form-left-panel :span="12">
<el-button icon="el-icon-plus" type="primary" @click="handleEdit($event)">
添加
</el-button>
<el-button icon="el-icon-delete" type="danger" @click="handleDelete($event)">
批量删除
</el-button>
</vab-query-form-left-panel>
<vab-query-form-right-panel :span="12">
<el-form :inline="true" :model="queryForm" @submit.native.prevent>
<el-form-item>
<el-input v-model.trim="queryForm.name" clearable placeholder="请输入角色" />
</el-form-item>
<el-form-item>
<el-button icon="el-icon-search" type="primary" @click="queryData">
查询
</el-button>
</el-form-item>
</el-form>
</vab-query-form-right-panel>
</vab-query-form>
<el-table v-loading="listLoading" border :data="list" @selection-change="setSelectRows">
<el-table-column align="center" show-overflow-tooltip type="selection" />
<el-table-column align="center" label="序号" width="55">
<template #default="{ $index }">
{{ $index + 1 }}
</template>
</el-table-column>
<el-table-column align="center" label="id" prop="id" show-overflow-tooltip width="40px"/>
<el-table-column align="center" label="角色码" prop="name" show-overflow-tooltip />
<!-- <el-table-column align="center" label="按钮权限" show-overflow-tooltip>
<template #default="{ row }">
<el-tag v-for="(item, index) in row.btnRolesCheckedList" :key="index">
{{
{
'read:system': '读',
'write:system': '写',
'delete:system': '删',
}[item]
}}
</el-tag>
</template>
</el-table-column> -->
<el-table-column align="center" label="操作" show-overflow-tooltip width="85">
<template #default="{ row }">
<el-button type="text" @click="handleEdit(row)">编辑</el-button>
<el-button type="text" @click="handleDelete(row)">删除</el-button>
</template>
</el-table-column>
<template #empty>
<el-image class="vab-data-empty" :src="require('@/assets/empty_images/data_empty.png')" />
</template>
</el-table>
<el-pagination background :current-page="queryForm.page" :layout="layout" :page-size="queryForm.perPage"
:total="total" @current-change="handleCurrentChange" @size-change="handleSizeChange" />
<edit ref="edit" @fetch-data="fetchData" />
</div>
</template>
<script>
import {
doDelete,
getList,
getAllList
} from '@/api/roleManagement'
import Edit from './components/RoleManagementEdit'
export default {
name: 'RoleManagement',
components: {
Edit
},
data() {
return {
list: [],
listLoading: true,
layout: 'total, sizes, prev, pager, next, jumper',
total: 0,
selectRows: '',
queryForm: {
page: 1,
perPage: 10,
name: '',
},
}
},
created() {
this.fetchData()
},
methods: {
setSelectRows(val) {
this.selectRows = val
},
handleEdit(row) {
if (row.id) {
this.$refs['edit'].showEdit(row)
} else {
this.$refs['edit'].showEdit()
}
},
handleDelete(row) {
if (row.id) {
this.$baseConfirm('你确定要删除当前项吗', null, async () => {
const {
message
} = await doDelete({
ids: row.id
})
// await doDelete({
// ids: row.id
// }).then(() => {
// this.fetchData()
// })
this.$baseMessage(message, 'success', 'vab-hey-message-success')
await this.fetchData()
})
} else {
if (this.selectRows.length > 0) {
const ids = this.selectRows.map((item) => item.id).join()
// const ids = this.selectRows.map((item) => item.id).toString()
// console.log( {
// ids: ids
// })
// doDelete({
// ids
// }).then(() => {
// this.fetchData()
// })
this.$baseConfirm('你确定要删除选中项吗', null, async() => {
const {
message
} = await doDelete({
ids
})
// doDelete({
// ids: ids
// })
// .then(() => {
// // this.fetchData()
// this.$message.success('删除成功');
// })
this.$baseMessage(message, 'success', 'vab-hey-message-success')
await this.fetchData()
})
} else {
this.$baseMessage('未选中任何行', 'error', 'vab-hey-message-error')
}
}
},
handleSizeChange(val) {
this.queryForm.perPage = val
this.fetchData()
},
handleCurrentChange(val) {
this.queryForm.page = val
this.fetchData()
},
queryData() {
this.queryForm.page = 1
this.fetchData()
},
async fetchData() {
this.listLoading = true
let params = "page=" + this.queryForm.page + "&perPage=" + this.queryForm.perPage
const {
// data: { list, total },
data,
meta
} = await getList(params)
this.list = data
this.total = meta.pagination.total
this.listLoading = false
},
// fetchData(){
// this.listLoading = true
// let params ="page=" + this.queryForm.page+ "&perPage=" + this.queryForm.perPage
// getList(params).then((res)=>{
// this.list = res
// this.total = meta.pagination.total
// this.listLoading = false
// })
// }
},
}
</script>