mb-tree回显bug,优化搜索,菜单只有第一级的时候出现bug修复

This commit is contained in:
吕金泽 2022-04-10 10:48:49 +08:00
parent e17637c0b8
commit d8e5372054
8 changed files with 142 additions and 161 deletions

View File

@ -5,7 +5,7 @@
"groupId" : "67b2ce258e24491194b74992958c74aa", "groupId" : "67b2ce258e24491194b74992958c74aa",
"name" : "当前用户菜单", "name" : "当前用户菜单",
"createTime" : null, "createTime" : null,
"updateTime" : 1648013721548, "updateTime" : 1649558286068,
"lock" : "0", "lock" : "0",
"createBy" : null, "createBy" : null,
"updateBy" : null, "updateBy" : null,
@ -598,6 +598,14 @@ nodes.each((key, node) => {
var treeNodes = [] var treeNodes = []
nodes.each((key, node) => { nodes.each((key, node) => {
if(node.pid == '0'){ if(node.pid == '0'){
if(node.component != 'Layout'){
node = {
isShow: 1,
component: 'Layout',
redirect: node.path,
children: [node]
}
}
treeNodes.push(node) treeNodes.push(node)
} }
}) })

View File

@ -2,24 +2,24 @@
<div> <div>
<div style="margin-bottom: 5px;" v-if="expand || checked"> <div style="margin-bottom: 5px;" v-if="expand || checked">
<el-button v-if="expand" type="primary" icon="ElSort" plain @click="doExpand">展开/折叠</el-button> <el-button v-if="expand" type="primary" icon="ElSort" plain @click="doExpand">展开/折叠</el-button>
<el-button v-if="checked" type="primary" icon="ElCheck" plain @click="() => { treeAllChecked = !treeAllChecked; checkedAll(searchData, treeAllChecked) }">全选/全不选</el-button> <el-button v-if="checked" type="primary" icon="ElCheck" plain @click="() => { treeAllChecked = !treeAllChecked; checkedAll(treeData, treeAllChecked) }">全选/全不选</el-button>
</div> </div>
<div style="margin-bottom: 5px;" v-if="search"> <div style="margin-bottom: 5px;" v-if="search">
<el-input v-model="searchValue" placeholder="输入关键字进行过滤" @input="searchTree" :style="{ width: searchWidth }" /> <el-input v-model="searchValue" placeholder="输入关键字进行过滤" @input="tree.filter(searchValue)" :style="{ width: searchWidth }" />
</div> </div>
<el-tree <el-tree
v-if="refreshTree" v-if="refreshTree"
ref="tree" ref="tree"
:data="searchData" :data="treeData"
v-bind="el" v-bind="props.props"
node-key="id" node-key="id"
:default-expand-all="defaultExpandAll" :default-expand-all="defaultExpandAll"
:default-checked-keys="checkedIds" :default-checked-keys="checkedIds"
@check-change="checkChange" @check-change="checkChange"
@node-click="nodeClick" @node-click="nodeClick"
:props="defaultProps" :props="defaultProps"
:style="{ 'max-height': maxHeight ? maxHeight : '100%' }" :filter-node-method="searchTree"
style="overflow: auto" :style="style"
/> />
</div> </div>
</template> </template>
@ -45,11 +45,11 @@ const props = defineProps({
type: String, type: String,
default: '' default: ''
}, },
maxHeight: { style: {
type: String, type: String,
default: '' default: ''
}, },
el: { props: {
type: Object, type: Object,
default: () => {} default: () => {}
}, },
@ -68,22 +68,19 @@ const props = defineProps({
searchWidth: { searchWidth: {
type: String, type: String,
default: '230px' default: '230px'
},
checkedIds: {
type: Array,
default: () => []
} }
}) })
const checkedIds = ref(props.selectValues.split(','))
const tree = ref() const tree = ref()
const treeData = ref([]) const treeData = ref([])
const searchData = ref([])
const defaultProps = reactive({ const defaultProps = reactive({
children: 'children', children: 'children',
label: 'name' label: 'name'
}) })
const defaultExpandAll = ref(true) const defaultExpandAll = ref(true)
const refreshTree = ref(true) const refreshTree = ref(false)
const treeAllChecked = ref(false) const treeAllChecked = ref(false)
const searchValue = ref('') const searchValue = ref('')
@ -96,20 +93,12 @@ onMounted(() => {
}) })
watch(() => props.selectValues, async () => { watch(() => props.selectValues, async () => {
await loadTreeData() checkedIds.value = props.selectValues.split(',')
checkedAll(searchData.value, false)
var values = props.selectValues.split(',');
for(var i in values){
tree.value.setChecked(values[i], true, false)
}
}) })
function searchTree() { function searchTree(value, data) {
if(searchValue.value){ if (!value) return true
searchData.value = proxy.$treeTable.recursionSearch(['name'], proxy.$common.copyNew(treeData.value), searchValue.value, false) return data.name.includes(value)
}else{
searchData.value = treeData.value
}
} }
function doExpand() { function doExpand() {
@ -122,8 +111,8 @@ async function loadTreeData() {
if(treeData.value.length == 0){ if(treeData.value.length == 0){
await proxy.$get(props.url, props.params).then((res) => { await proxy.$get(props.url, props.params).then((res) => {
treeData.value = res.data.list treeData.value = res.data.list
searchData.value = treeData.value
}) })
refreshTree.value = true
} }
} }

View File

@ -8,8 +8,9 @@
<div class="avatar"> <div class="avatar">
<el-dropdown> <el-dropdown>
<el-col> <el-col>
<el-avatar :size="40" fit="contain" :src="$global.baseApi + $global.user.info.headPortrait"> <el-avatar v-if="$global.user.info.headPortrait" :size="40" fit="contain" :src="$global.baseApi + $global.user.info.headPortrait"></el-avatar>
{{ !$global.user.info.headPortrait ? $global.user.info.name.substring(0,1) : '' }} <el-avatar v-else :size="40" fit="contain">
{{ $global.user.info.name.substring(0,1) }}
</el-avatar> </el-avatar>
</el-col> </el-col>
<el-col style="line-height: 40px;"> <el-col style="line-height: 40px;">

View File

@ -11,7 +11,7 @@ import { generateRoutes } from '@/scripts/routerPermission'
NProgress.configure({ showSpinner: false }) // NProgress Configuration NProgress.configure({ showSpinner: false }) // NProgress Configuration
const whiteList = ['/login'] // no redirect whitelist const whiteList = ['/login'] // no redirect whitelist
var loadInfo = false
router.beforeEach(async(to, from, next) => { router.beforeEach(async(to, from, next) => {
// start progress bar // start progress bar
NProgress.start() NProgress.start()
@ -26,7 +26,7 @@ router.beforeEach(async(to, from, next) => {
NProgress.done() NProgress.done()
} else { } else {
// determine whether the user has obtained his permission roles through getInfo // determine whether the user has obtained his permission roles through getInfo
if (global.user.authorities.length > 0) { if (loadInfo) {
next() next()
} else { } else {
try { try {
@ -42,6 +42,7 @@ router.beforeEach(async(to, from, next) => {
router.addRoute(it) router.addRoute(it)
}) })
}) })
loadInfo = true
// dynamically add accessible routes // dynamically add accessible routes
// hack method to ensure that addRoutes is complete // hack method to ensure that addRoutes is complete
// set the replace: true, so the navigation will not leave a history record // set the replace: true, so the navigation will not leave a history record

View File

@ -3,7 +3,6 @@
<div class="magic-login-box"> <div class="magic-login-box">
<!-- <div class="magic-login-logo"></div>--> <!-- <div class="magic-login-logo"></div>-->
<div class="magic-login-text">{{ $global.title }}</div> <div class="magic-login-text">{{ $global.title }}</div>
<div class="magic-login-row error" v-if="error"><mb-icon icon="error"/><span>{{ error }}</span></div>
<div class="magic-login-row"> <div class="magic-login-row">
<input ref="username" class="magic-input" v-model="loginForm.username" placeholder="用户名" name="username" type="text" tabindex="1" auto-complete="on" /> <input ref="username" class="magic-input" v-model="loginForm.username" placeholder="用户名" name="username" type="text" tabindex="1" auto-complete="on" />
<mb-icon icon="user"/> <mb-icon icon="user"/>
@ -170,18 +169,6 @@ label {
margin:25px auto; margin:25px auto;
position: relative; position: relative;
} }
.magic-login-row.error{
background-color: #fff1f0;
border: 1px solid #ffa39e;
color: #000;
border-radius: 4px;
padding:10px 0;
padding-left: 40px;
}
.magic-login-row.error span{
font-size: 14px;
word-break: break-all;
}
.magic-login-row svg{ .magic-login-row svg{
position: absolute; position: absolute;
width: 20px; width: 20px;
@ -189,9 +176,6 @@ label {
top: 15px; top: 15px;
left: 15px; left: 15px;
} }
.magic-login-row :deep(.magic-icon-error){
fill: red;
}
.magic-login-box .magic-input{ .magic-login-box .magic-input{
height: 50px; height: 50px;
line-height: 50px; line-height: 50px;

View File

@ -17,7 +17,7 @@
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="上级菜单" prop="pid"> <el-form-item label="上级菜单" prop="pid">
<treeselect v-model="temp.pid" :options="menuTree" :key="temp.pid" /> <treeselect v-model="temp.pid" :options="menuTree" :key="temp.pid" style="position: relative;z-index:999999;" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@ -35,7 +35,7 @@
placeholder="" placeholder=""
:options="componentTree" :options="componentTree"
:key="temp.componentName" :key="temp.componentName"
style="position: fixed;z-index:999999;width: 850px;" style="position: fixed;z-index:999998;width: 850px;"
/> />
</el-form-item> </el-form-item>
<el-form-item label="权限标识" prop="permission" v-if="menuType == 'button'"> <el-form-item label="权限标识" prop="permission" v-if="menuType == 'button'">

View File

@ -1,5 +1,5 @@
<template> <template>
<mb-tree ref="tree" :el="{ 'show-checkbox': true }" url="/system/menu/tree" :search="true" search-width="230px" v-model:select-values="menus" /> <mb-tree ref="tree" :props="{ 'show-checkbox': true }" url="/system/menu/tree" :search="true" search-width="230px" v-model:select-values="menus" />
</template> </template>
<script setup> <script setup>
@ -13,8 +13,6 @@ const props = defineProps({
} }
}) })
console.log(props.id)
const menus = ref('') const menus = ref('')
proxy.$get('/system/menu/by/role',{ roleId: props.id }).then(res => { proxy.$get('/system/menu/by/role',{ roleId: props.id }).then(res => {

View File

@ -30,10 +30,10 @@
<el-col :span="24"> <el-col :span="24">
<el-form-item label="角色描述" prop="descRibe"> <el-form-item label="角色描述" prop="descRibe">
<el-input <el-input
type="textarea" type="textarea"
:rows="4" :rows="4"
placeholder="请输入描述" placeholder="请输入描述"
v-model="temp.descRibe"> v-model="temp.descRibe">
</el-input> </el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -41,13 +41,13 @@
<el-row :gutter="24"> <el-row :gutter="24">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="菜单权限" prop="menus"> <el-form-item label="菜单权限" prop="menus">
<mb-tree ref="tree" :el="{ 'show-checkbox': true }" max-height="270px" url="/system/menu/tree" :search="true" v-model:select-values="temp.menus" /> <mb-tree ref="tree" :props="{ 'show-checkbox': true }" style="height: 270px; overflow: auto" url="/system/menu/tree" :search="true" :select-values="temp.menus" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="数据权限" prop="permission"> <el-form-item label="数据权限" prop="permission">
<mb-select v-model="temp.permission" :options="permissionData" /> <mb-select v-model="temp.permission" :options="permissionData" />
<mb-tree v-if="temp.permission == 1" max-height="270px" :el="{ 'check-strictly': true, 'show-checkbox': true }" ref="office" url="/system/office/tree" v-model:select-values="temp.offices" /> <mb-tree v-if="temp.permission == 1" style="height: 270px; overflow: auto" :props="{ 'check-strictly': true, 'show-checkbox': true }" ref="office" url="/system/office/tree" v-model:select-values="temp.offices" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@ -71,112 +71,112 @@ import RoleAssignPermissions from './role-assign-permissions'
const { proxy } = getCurrentInstance() const { proxy } = getCurrentInstance()
const permissionData = reactive([{ const permissionData = reactive([{
label: '全部', label: '全部',
value: '0' value: '0'
}, { }, {
label: '自定义', label: '自定义',
value: '1' value: '1'
}, { }, {
label: '本级及子级', label: '本级及子级',
value: '2' value: '2'
}, { }, {
label: '本级', label: '本级',
value: '3' value: '3'
}]) }])
const assignPermissions = ref() const assignPermissions = ref()
const assignPermissionsDialog = ref() const assignPermissionsDialog = ref()
const table = ref() const table = ref()
const roleFormDialog = ref() const roleFormDialog = ref()
const dataForm = ref() const dataForm = ref()
const tableOptions = reactive({ const tableOptions = reactive({
url: '/system/role/list', url: '/system/role/list',
where: { where: {
name: { name: {
type: 'input', type: 'input',
label: '角色名称', label: '角色名称',
value: '' value: ''
}
},
cols: [
{
field: 'name',
label: '角色名称'
},
{
field: 'code',
label: '角色编码'
},
{
field: 'descRibe',
label: '角色描述'
},
{
field: 'permission',
label: '数据权限',
templet: (row) => {
return permissionData[row.permission].label
}
},
{
label: '操作',
type: 'btns',
width: 270,
fixed: 'right',
btns: [
{
permission: 'role:save',
label: '修改',
type: 'text',
icon: 'ElEdit',
click: (row) => {
handleUpdate(row)
} }
}, },
cols: [ {
{ permission: 'role:delete',
field: 'name', label: '删除',
label: '角色名称' type: 'text',
}, icon: 'ElDelete',
{ click: (row) => {
field: 'code', proxy.$common.handleDelete({
label: '角色编码' url: '/system/role/delete',
}, id: row.id,
{ done: () => reloadTable()
field: 'descRibe', })
label: '角色描述'
},
{
field: 'permission',
label: '数据权限',
templet: (row) => {
return permissionData[row.permission].label
}
},
{
label: '操作',
type: 'btns',
width: 270,
fixed: 'right',
btns: [
{
permission: 'role:save',
label: '修改',
type: 'text',
icon: 'ElEdit',
click: (row) => {
handleUpdate(row)
}
},
{
permission: 'role:delete',
label: '删除',
type: 'text',
icon: 'ElDelete',
click: (row) => {
proxy.$common.handleDelete({
url: '/system/role/delete',
id: row.id,
done: () => reloadTable()
})
}
},
{
permission: 'role:permission',
label: '权限',
type: 'text',
icon: 'ElPlus',
click: (row) => {
temp.value.id = row.id
assignPermissionsDialog.value.show()
}
},
{
permission: 'role:user:list',
label: '用户列表',
type: 'text',
icon: 'ElUserFilled',
click: (row) => {
proxy.$router.push({
path: '/system/user/user-list',
query: { roleId: row.id }
})
}
}
]
} }
] },
}) {
permission: 'role:permission',
label: '权限',
type: 'text',
icon: 'ElPlus',
click: (row) => {
temp.value.id = row.id
assignPermissionsDialog.value.show()
}
},
{
permission: 'role:user:list',
label: '用户列表',
type: 'text',
icon: 'ElUserFilled',
click: (row) => {
proxy.$router.push({
path: '/system/user/user-list',
query: { roleId: row.id }
})
}
}
]
}
]
})
const dialogTitle = ref('') const dialogTitle = ref('')
const temp = ref(getTemp()) const temp = ref(getTemp())
const rules = reactive({ const rules = reactive({
name: [{ required: true, message: '请输入角色名称', trigger: 'change' }], name: [{ required: true, message: '请输入角色名称', trigger: 'change' }],
code: [{ required: true, message: '请输入角色编码', trigger: 'change' }] code: [{ required: true, message: '请输入角色编码', trigger: 'change' }]
}) })
const downloadLoading = ref(false) const downloadLoading = ref(false)
watch(() => temp.value.permission,() => { watch(() => temp.value.permission,() => {