部门级别-部门多选 处理
子组件
<template>
<div style="display: flex;justify-items: center;align-items: center;justify-content:flex-start;white-space: nowrap;">
<div style="width: 50%">
<span class="width_t">部门级别:</span>
<el-select
ref="optionRef"
v-model="divLevel"
placeholder="选择级别"
style="width: 170px;"
@change="handleClassLevel">
<el-option
v-for="item in levelList"
:key="item.value"
:label="item.lable"
:value="item.value"/>
</el-select>
</div>
<div style="width: 50%">
<span class="width_t">部门:</span>
<el-cascader
ref="cascader"
v-model="divisionIds"
:options="ddivisions"
:props="{multiple: true,value: 'level', label: 'className'}"
:collapse-tags="true"
filterable
placeholder="请选择"
style="width:170px"
@change="selectHandle">
<template slot-scope="{ node, data }">
<span>{{ data.className }}</span>
<span v-if="skuShow">
<span v-if="data.className !== '全部'"> ({{ data.sku }}) </span>
</span>
</template>
</el-cascader>
</div>
</div>
</template>
<script>
import { getClassByRoles } from '../../../../api/division'
import { getDivisionCount } from '../../../../api/dept'
import { getDivisionByRoles } from '../../../../api/dept'
import errorLog from '../../../monitor/log/errorLog'
export default {
name: 'DepartmentLevel',
props: {
subdivFlag: {
type: Boolean,
default: () => false
},
skuShow: {
type: Boolean,
default: () => false
},
selectedLevel: {
type: Number,
default: () => 2
},
selectedNo: {
type: Array,
default: () => []
}
},
data() {
return {
divLevel: 2, levelList: [], levelName: '',
preSelected: [], // 上次选中的数据
originData: [], // 源数据平铺成一级节点
ddivisions: [],
divisionIds: [],
test: []
}
},
watch: {
subdivFlag: {
immediate: true,
handler(value) {
if (value == true) {
this.divLevel = 2
this.handleClassLevel()
}
}
},
selectedLevel: {
handler(n, o) {
this.divLevel = this.selectedLevel
this.handleClassLevel()
}
},
selectedNo: {
handler(n, o) {
this.divisionIds = this.selectedNo
}
}
},
mounted() {
this.getMaxClass()
this.getTagDivisions()
},
methods: {
handleClassLevel() {
this.$nextTick(() => {
// 清空级联选择器选中状态
// this.$refs.cascader.$refs.panel.clearCheckedNodes()
// // 清除⾼亮
this.$refs.cascader.$refs.panel.activePath = []
})
this.ddivisions = []
const classArr = JSON.parse(localStorage.getItem('classByRoles'))
this.ddivisions = this.getTreeData(classArr, this.divLevel)
this.originData = []
this.getTreeInitialData(JSON.parse(localStorage.getItem('classByRoles')), this.divLevel)
this.selectHandle([['全部']], 1)
},
// 递归判断列表,把最后层级的children设为undefined
// num 显示的层级
getTreeData(data, num) {
for (let i = 0; i < data.length; i++) {
if (data[i].levelFlag <= num && data[i].children) {
if (data[i].levelFlag === num) {
// children若为空数组,则将children设为undefined
data[i].children = undefined
} else {
// children若不为空数组,则继续 递归调用 本方法
this.getTreeData(data[i].children, num)
}
}
}
return data
},
getTreeInitialData(data, num) {
const that = this
for (var da of data) {
if (Number(da.levelFlag) === Number(num)) {
that.originData.push(da.level)
}
if (da.level !== '全部' && da.levelFlag && Number(da.levelFlag) !== Number(num)) {
that.getTreeInitialData(da.children, num)
}
}
},
// 最大品类级别
getMaxClass() {
const user = JSON.parse(localStorage.getItem('user'))
const par = { userName: user.username }
getDivisionCount(par).then(res => {
if (res != null) {
const maxClass = localStorage.getItem('maxClass')
const arr = []
const chinese = ['一', '二', '三', '四', '五', '六', '七']
for (let i = 0; i < maxClass; i++) {
const it = {
value: i + 1,
lable: chinese[i] + '级部门'
}
arr.push(it)
}
if (res === 0) {
arr.shift()
}
this.levelList = arr
this.divLevel = this.selectedLevel
}
})
},
getTagDivisions() {
const that = this
var par = { num: 5, selectRole: localStorage.getItem('selectRole') }
getDivisionByRoles(par).then(res => {
if (res.content != null) {
res.content[0].children.unshift({ level: '全部', className: '全部' })
localStorage.setItem('classByRoles', JSON.stringify(res.content[0].children))
that.ddivisions = that.getTreeData(res.content[0].children, that.divLevel)
that.getTreeInitialData(JSON.parse(localStorage.getItem('classByRoles')), that.divLevel)
this.selectHandle([['全部']])
}
})
},
judgetAllSelected(node) {
// 判断是否是全部,也就是看已选择的选中中包不包含"全部"
let isAllSelected = false
console.log(node)
for (let i = 0; i < node.length; i++) {
if (node[i][0] === '全部') {
isAllSelected = true
break
}
}
return isAllSelected
},
loopSelectData(list, parentNode = []) {
list.length > 0 && list.forEach(e => {
const pNode = [...parentNode] // 注意这里必须是深拷贝,否则会由于引用类型赋值的是地址(指针),导致parentNode在pNode更新时,同时被更新
if (e.children && e.children.length > 0) {
pNode.push(e.level)// 1 11
this.loopSelectData(e.children, pNode)
} else {
if (parentNode.length > 0) {
this.divisionIds.push([...parentNode, e.level])
} else {
this.divisionIds.push([e.level])
}
}
})
},
checkIsAddAllSelected() {
const origin = this.originData
const now = [...this.divisionIds].filter(item => item[0] !== '全部')
if (origin.length > now.length) {
// 非全部时, 如果有之前选过全部,要把全部过滤掉
this.divisionIds = this.divisionIds.filter(item => item[0] !== '全部')
} else {
// 当所有的数据都选择时, 要自动把全部勾选上
if (this.divisionIds[0] && this.divisionIds[0][0] !== '全部') {
this.divisionIds = [['全部'], ...this.divisionIds]
}
}
},
async selectHandle(node = [], type) {
this.divisionIds = []
// 选中的数据格式: [['全部'], ['0'], ['1', '11', '111'], ['2', '21'],...]
const list = this.ddivisions
let current = [] // 获取当前选中的option, 因为element文档中没有获取当前选中的option的方法,所以我通过上一次和本地的选中数据进行对比来获取
if (type === 1) {
current = node.filter(item => JSON.stringify(item))
} else {
if (node.length >= this.preSelected.length) {
const keys = this.preSelected.map(item => JSON.stringify(item))
current = node.filter(item => !keys.includes(JSON.stringify(item)))
console.log('选中某项', current)
} else {
// 取消选中
const keys = node.map(item => JSON.stringify(item))
current = this.preSelected.filter(item => !keys.includes(JSON.stringify(item)))
console.log('取消选中', current)
}
}
// 根据element的选中数据格式, 每一个选项都是一个列表, 列表第一项为父级value, 第二项为选中的子级value, ...以此类推
const currentValue = current.length > 0 ? current[0][0] || '' : ''
if (currentValue === '全部') {
if (this.judgetAllSelected(node)) {
this.loopSelectData(list)
} else {
this.divisionIds = []
}
} else {
this.divisionIds = node
}
this.checkIsAddAllSelected() // 主要是勾选或取消非“全部”项时,对于全部的逻辑处理
this.preSelected = this.divisionIds // 保存上一次的选择结果
this.changeHandle()
},
changeHandle() {
// 这里是处理成自己需要的数据格式, 需要把全部的这一选项过滤掉
// 原始选择的数据格式[['全部'], ['1', '11'], ['2', '21'],...]
const arr = []
this.divisionIds.forEach((item) => {
if (item[this.divLevel - 1] !== '全部' && typeof (item[this.divLevel - 1]) !== 'undefined') {
arr.push(item[this.divLevel - 1])
}
})
this.$emit('passfunction', arr.toString(), this.divLevel, this.divisionIds)
console.log('changeHandle: ', arr)
}
}
}
</script>
<style scoped>
.organization{
display: flex;
align-items: center;
font-size: 0.9rem;
}
/deep/.el-cascader__tags {
flex-wrap: nowrap !important;
width: 56%;
}
/deep/ .el-cascader__search-input{
display: none;
}
.width_t{
display: inline-block;
width: 6.25rem;
text-align: right
}
</style>
父组件
<department-level :size="'small'" :subdiv-flag="subdivFlag" @passfunction="meetfunction"/>
meetfunction(param1, param2) {
const that = this
that.class_no = param1
that.class_level = param2
that.subdivFlag = false
if (that.selectFlag) {
that.selectFlag = false
that.queryTableData()
}
},