Files
foton-laws-system-front/src/components/roleTree/index.vue
T
2022-12-08 14:39:54 +08:00

548 lines
20 KiB
Vue

<template>
<div class="roleTree">
<el-drawer
:title="isTitle"
:visible.sync="visible"
:wrapperClosable="false"
@close="handleTreeDrawerCancel"
size="460px">
<el-form
ref="attributeEO"
class="label-input-form"
:inline="true"
@submit.native.prevent
>
<el-form-item class="form-item-disabled" style="margin: 10px;">
<el-input
v-model="filterText"
placeholder="请输入姓名"
@keyup.enter.native="searchChange"
></el-input>
</el-form-item>
<el-form-item class="form-item-disabled" style="margin-top: 10px;">
<el-button size="medium " type="primary" @click="searchChange">
查询
</el-button>
</el-form-item>
</el-form>
<div class="divTree">
<!-- 当前tree展示全部人员 -->
<el-tree
v-if="open1 && isVisible"
node-key="id"
style="height: 100%; overflow: auto;"
class="filter-tree tree-line"
icon-class="icon-tree"
@check-change="checkChange"
:data="treeData"
:props="defaultProps"
:default-checked-keys="nodeList2"
:default-expanded-keys="defaultKey"
highlight-current
check-strictly
@check="drawerCheck"
:expand-on-click-node="true"
show-checkbox
ref="tree"
:load="loadNode"
:lazy="true">
<span class="custom-tree-node" slot-scope="{ node, data }">
<span :class="node.disabled ? 'is-show' : 'is-leaf-none'"></span>
<span> {{ node.label }} </span>
</span>
</el-tree>
<!-- 当前tree展示搜索出的人员 -->
<el-tree
v-if="!open1 && isVisible"
node-key="id"
style="height: 100%; overflow: auto;"
class="filter-tree tree-line"
icon-class="icon-tree"
:data="treeData1"
:props="defaultProps"
@check-change="checkChange2"
:default-checked-keys="nodeList2"
:default-expanded-keys="defaultKey"
default-expand-all
highlight-current
:check-strictly="true"
@check="drawerCheck"
show-checkbox
ref="tree"
:lazy="false"
:key="treeKey"
>
<span class="custom-tree-node" slot-scope="{ node, data }">
<span :class="node.disabled ? 'is-show' : 'is-leaf-none'"></span>
<span> {{ node.label }} </span>
</span>
</el-tree>
</div>
<div class="divDel">
<div class="divDel_title">已选中人员</div>
<div class="divDel_box">
<el-tag
v-for="tag in delList"
:key="tag.id"
size="mini"
@close="handleClose(tag)"
closable>
{{tag.name}}
</el-tag>
<el-tag v-show="delList.length > 0 && !checkBox" type="danger" closable size="mini" @close="handleCloseAll()">全部删除</el-tag>
</div>
</div>
<div id="roleFormButton" class="demo-drawer-footer">
<el-button class="common-button-primary" size="mini" icon="el-icon-check" type="primary" :loading="subLoading" @click="saveUserInfo">确定</el-button>
<el-button class="common-button-default" size="mini" icon="el-icon-close" :loading="subLoading" @click="handleTreeDrawerCancel">取消</el-button>
</div>
<loading style="z-index: 2099;" :loading="treeLoading">导入中...</loading>
</el-drawer>
</div>
</template>
<script>
function debounce(func, wait = 500){
let timeout;
return function(event){
clearTimeout(timeout)
timeout = setTimeout(()=>{
func.call(this, event)
},wait)
}
}
export default {
name: "roleTree",
props: {
checkBox: { // 单选/多选
type: Boolean,
default: false,//默认false多选
},
isTitle: { // 标题
type: String
},
isVisible: { // drawer开关
type: Boolean,
default: false,
},
nodeList: { // 回显
type: Array,
default: () => {
return []
}
},
type: {
type: Number,
default: 0
}
},
data () {
return {
treeKey:1,
defaultKey: [],//默认展开的节点的 key 的数组
visible: false,
selectList: [],
nodeList2: [],//默认勾选的节点的 key 的数组
delList: [],
roleList: [],
filterText: '',
defaultProps: {//配置选项
children: 'children',//指定子树为节点对象的某个属性值
label: 'name',//指定节点标签为节点对象的某个属性值
},
treeData1: [],
treeData: [],
open1: true,
treeLoading: false,
subLoading: false,
roleRow: {}
}
},
methods: {
nameJoinAccount(treeData1){
treeData1.forEach(item=>{
if(item.account) item.name = `${item.name}(${item.account})`
if(item.children) this.nameJoinAccount(item.children)
})
},
handleClose (tag) {
let arr = []
for (let a = 0; a < this.delList.length; a++) {
if (tag.id === this.delList[a].id) {
this.delList.splice(a, 1)
}
}
this.delList.map(item => {
arr.push(item)
})
this.$refs.tree.setCheckedKeys(arr);
for (let b = 0; b < this.nodeList2.length; b++) {
if (tag.id === this.nodeList2[b]) {
this.nodeList2.splice(b, 1)
}
}
for (let c = 0; c < this.roleList.length; c++) {
if (tag.id === this.roleList[c].id) {
this.roleList.splice(c, 1)
}
}
},
handleCloseAll () {
this.$msgbox({
title: '提示',
message: '是否删除当前选中人员',
showCancelButton: true,
confirmButtonText: '确定',
cancelButtonText: '取消',
}).then(() => {
this.delList = []
this.nodeList2 = []
this.roleList = []
this.$refs.tree.setCheckedKeys([]);
}).catch(() => {
this.$message({
type: 'info',
message: '取消删除'
});
}
)
},
searchChange(){
// 查询
if (this.filterText.length) {
this.open1 = false // 显示第二个tree
this.treeLoading = true
this.defaultKey = []
this.$http.get('SarInstitution/institution/getNextTwo', {
userName: this.filterText
}, {}, res => {
this.treeData1 = res
this.treeData1.forEach(item => {
this.defaultKey.push(item.id)
})
this.nameJoinAccount(this.treeData1)
this.treeLoading = false
})
// this.treeKey++
// this.$http.get('SarInstitution/institution/institutionAndUser', {
// userName: this.filterText
// }, {}, res => {
// this.treeData1 = res.data
// this.treeData1.forEach(item => {
// this.defaultKey.push(item.id)
// })
// console.log(1);
// this.getChildren()
// this.treeLoading = false
// })
} else {
this.open1 = true
}
},
changeInput:debounce(function (val) {
if (val.length) {
this.open1 = false
this.treeLoading = true
this.$http.get('SarInstitution/institution/institutionAndUser', {
userName: val
}, {}, res => {
this.treeData1 = res.data
this.treeLoading = false
})
} else {
this.open1 = true
}
}),
checkChange2 (row, type, c) {
if (this.checkBox) {
} else {
if (type) {
this.nodeList2.push(row.id)
this.delList.push(row)
} else {
for (let a = 0; a < this.nodeList2.length; a ++) {
if (row.id === this.nodeList2[a]) {
this.nodeList2.splice(a, 1)
}
}
for (let b = 0; b < this.delList.length; b++) {
if (row.id === this.delList[b].id) {
this.delList.splice(b, 1)
}
}
}
}
},
checkChange (row, type, c) {
//节点选中状态发生变化时的回调(传递给 data 属性的数组中该节点所对应的对象、节点本身是否被选中、节点的子树中是否有被选中的节点)
if (this.checkBox) {
} else {
if (type) {
this.nodeList2.push(row.id)
this.delList.push(row)
} else {
for (let a = 0; a < this.nodeList2.length; a++) {
if (row.id === this.nodeList2[a]) {
this.nodeList2.splice(a, 1)
}
}
for (let b = 0; b < this.delList.length; b++) {
if (row.id === this.delList[b].id) {
this.delList.splice(b, 1)
}
}
}
}
},
handleTreeDrawerCancel () {
this.filterText = ''
this.open1 = true
this.visible = false
},
saveUserInfo () {
if(this.roleList.length === 0){
this.roleList.push({id:"",name:""});
}
if (this.checkBox) {
this.$emit('checkedRole', this.roleList)
this.nodeList2 = []
this.$emit('update:isVisible', false)
} else {
if (this.nodeList2.length > 0 && this.nodeList2[0].length !== 0) {
let ids = ''
this.nodeList2.forEach(item => {
if (ids.length > 0) {
ids += ','
ids += item
} else {
ids = item
}
})
this.subLoading = true
this.$http.get('SarInstitution/institution/getNextById', {
ids: ids,
topNum: 3,
}, {
_this: this
}, res => {
this.$emit('checkedRole', res)
this.nodeList2 = []
this.$emit('update:isVisible', false)
this.subLoading = false
})
} else {
this.$emit('checkedRole', this.roleList)
this.nodeList2 = []
this.$emit('update:isVisible', false)
}
}
this.open1 = true
},
drawerCheck (data) {
//当复选框被点击的时候触发
//共两个参数,依次为:传递给 data 属性的数组中该节点所对应的对象、树目前的选中状态对象,包含 checkedNodes、checkedKeys、halfCheckedNodes、halfCheckedKeys 四个属性
if (this.checkBox) { // 单选
// 单选判断
let getlist = this.$refs.tree.getCheckedNodes()
if (getlist.length > 1) {
this.$refs.tree.setCheckedKeys([])
this.$refs.tree.setCheckedKeys([data.id])
this.roleList = [data]
this.delList = [data]
} else if (getlist.length === 0) {
this.roleList = [{}]
this.delList = []
} else if (getlist.length === 1) {
this.roleList = [data]
this.delList = [data]
}
} else { // 多选
if (this.roleList.length === 0) {
this.roleList.push(data)
} else {
let delFlag = true
this.roleList.forEach((item, index) => {
if (item.id === data.id) {
this.roleList.splice(index, 1)
delFlag = false
}
})
if (delFlag) {
this.roleList.push(data)
}
}
// this.roleList = this.$refs.tree.getCheckedNodes().concat(this.$refs.tree.getHalfCheckedNodes())
}
},
loadNode(node, resolve) {
//加载子树数据的方法,仅当 lazy 属性为true 时生效
if (node.level === 0) {
return resolve(this.treeData);
}
this.getChildren(node, resolve)
},
getChildren (node, resolve) {
this.$http.get('SarInstitution/institution/getNext', {
institutionId: node.key,
userName: this.filterText
}, {}, res => {
resolve(res)
})
},
getTree () {
this.treeLoading = true
this.$http.get('SarInstitution/institution/getFirstInstitution', {}, {}, res=> {
this.treeData = res
this.treeLoading = false
})
}
},
watch: {
isVisible (val) {
this.visible = val
if (val) {
this.nodeList2 = this.nodeList
if (this.nodeList2.length && this.nodeList2[0].length) {
let ids = ''
this.nodeList2.forEach(item => {
if (ids.length) {
ids += ','
ids += item
} else {
ids = item
}
})
this.$http.get('SarInstitution/institution/getNextById', {
ids: ids
}, {
_this: this
}, res => {
this.delList = res
})
} else {
this.delList = []
}
} else {
this.delList = []
}
},
visible(val) {
this.$emit('update:isVisible', val)
}
},
mounted () {
this.getTree()
}
}
</script>
<style lang="less" scoped>
.divTree {
overflow: auto;
height: calc(~'100% - 300px');
}
.divDel {
border-top: 1px solid #000;
height: 300px;
.divDel_title {
margin: 10px;
}
.divDel_box {
height: 266px;
padding: 0px 0 10px;
display: flex;
flex-wrap: wrap;
overflow: auto;
margin: 10px;
align-content: flex-start;
span {
margin: 0px 5px 5px 0;
}
}
}
/deep/ .icon-tree {
margin: 0 5px 0 10px;
position: relative;
background: url('~@/assets/images/shangqi/img/tree-add.png');
background-size: 100% 100%;
}
/deep/.el-tree-node__content {
padding-left: 0px !important;
}
/deep/ .is-leaf{
background-image:none;
background-size:100% 100%;
}
/deep/ .is-leaf-none{
position: relative;
display: inline-block;
width: 15px;
height: 15px;
background:url('~@/assets/images/shangqi/img/personnel.png');
background-size:100% 100%;
}
/deep/ .is-show{
position: relative;
display: inline-block;
width: 15px;
height: 15px;
background:url('~@/assets/images/shangqi/img/mechanism.png');
background-size:100% 100%;
}
/deep/.tree-line{
.el-tree-node {
position: relative;
padding-left: 0px; // 缩进量
line-height: 30px;
}
.el-tree-node__children {
padding-left: 16px; // 缩进量
}
// 竖线
.el-tree-node::before {
content: "";
height: 100%;
width: 1px;
position: absolute;
left: -3px;
top: -26px;
border-width: 1px;
border-left: 1px dashed #858990e0;
}
// 当前层最后一个节点的竖线高度固定
.el-tree-node:last-child::before {
height: 38px; // 可以自己调节到合适数值
}
// 横线
.el-tree-node::after {
content: "";
width: 11px;
height: 20px;
position: absolute;
left: -3px;
top: 12px;
border-width: 1px;
border-top: 1px dashed #858990e0;
}
// 去掉最顶层的虚线,放最下面样式才不会被上面的覆盖了
& > .el-tree-node::after {
border-top: none;
}
& > .el-tree-node::before {
border-left: none;
}
// 展开关闭的icon
.el-tree-node__expand-icon{
font-size: 16px;
// 叶子节点(无子节点)
&.is-leaf{
color: transparent;
// display: none; // 也可以去掉
}
}
}
</style>