代码语言:html复制
<template>
<a-modal
width='600px'
:visible='visible'
:confirm-loading='confirmLoading'
@ok='handleSubmit'
@cancel='handleCancel'
>
<template slot='title'>
<span class='modal-title'>{{ title }}</span>
</template>
<div class='modal-card one-card-of-modal'>
<div class='search-panel'>
<span>请选择变量</span>
<a-select
v-model='selectedItems'
mode='multiple'
class='var-select'
:maxTagCount='maxTagCount'
show-search :filter-option="filterOption"
placeholder='请选择需要关联的变量'
@search="handleSearch"
@popupScroll="handlePopupScroll"
@blur="handleBlur"
@focus="handleFocus"
>
<a-select-option
v-for='i in varOption' :value='i.variableId' :key='`${i.variableId}`'
:disabled='optionsDisabled(i)'>
{{ i.displayName }}
</a-select-option>
</a-select>
</div>
<a-table :columns='columns' :data-source='tableData' :pagination='false'>
<span slot='action' slot-scope='text, record'>
<a-icon type='delete' />
<!-- <a-icon type='menu' />-->
</span>
</a-table>
</div>
</a-modal>
</template>
<script>
import Vue from 'vue'
import { ACCESS_TOKEN, TENANT_ID } from '@/store/mutation-types'
import { ListMixin } from '@/mixins/ListMixin'
import { getNoDeviceAssociateVariables } from '@/api/api'
import moment from 'moment'
import { TreeSelect } from 'ant-design-vue'
import { simpleDebounce } from '@/utils/util'
const columns = [
{ title: '变量名称', dataIndex: 'variableName', key: 'variableName', width: 100 },
{ title: '显示名称', dataIndex: 'displayName', key: 'displayName', width: 100 }
]
const SHOW_PARENT = TreeSelect.SHOW_PARENT
export default {
name: 'BatchAssociation', // 批量关联变量面板
components: {},
mixins: [ListMixin],
props: {
varSelectedList: {
type: Array,
default: () => []
},
equipTableList: {
type: Object,
default: () => {
}
}
},
data() {
return {
visible: false,
confirmLoading: false,
labelCol: { span: 6 },
wrapperCol: { span: 20 },
url: {
list: ''
},
columns, // 列表配置
// tableData: [],
treeData: [],
SHOW_PARENT,
varOption: [],
varOptionList: [],
selectedItems: [],
place: '',
title: '批量关联变量',
maxTagCount: 6,
equipId: '',
pageSize: 10,
pageNo: 1,
searchValue: undefined,
pageTotal: 0
}
},
computed: {
tableData({ selectedItems, varOption }) {
return varOption.filter(item => {
return selectedItems.includes(item.variableId)
})
}
},
created() {
const token = Vue.ls.get(ACCESS_TOKEN)
this.headers = { 'X-Access-Token': token }
},
mounted() {
},
methods: {
add(varSelectedList, place) {
this.visible = true
this.place = place
this.varOption = varSelectedList
},
close() {
this.$emit('close')
this.varOption=[].slice(0)
this.pageNo=1
this.searchValue=undefined
this.visible = false
},
addMissingElements(optionArr, resultArr) {
// 创建一个 Set 以存储 optionArr 中的元素,便于快速查找
const setOptionArr = new Set(optionArr.map(item => item.variableId)); // 假设 value 是用来唯一标识元素的属性
// 过滤 resultArr 中不在 setOptionArr 中的元素,并将其转换为与 arr1 相同格式的元素数组
const missingElements = resultArr.filter(item => !setOptionArr.has(item.variableId));
// 将缺失的元素添加到 optionArr 中
return [...optionArr, ...missingElements];
},
// 获取未关联列表数据
getVarSelectOption() {
let obj = {
variableType: '1',
orgId: Vue.ls.get(TENANT_ID),
deviceId: this.equipTableList.id,
placeType: this.place,
factoryId: this.equipTableList.factoryId,
pageNo: this.pageNo,
pageSize: this.pageSize,
searchValue: this.searchValue
}
getNoDeviceAssociateVariables(obj).then(response => {
if (response.success) {
this.pageTotal = Math.ceil(response.total/this.pageSize)
this.varOption = this.addMissingElements(this.varOption, response.result)
}
})
},
handleSearch: simpleDebounce(function (value){
if(value.length) {
this.searchValue=value
}else{
this.searchValue=undefined
}
this.pageNo=1
this.pageTotal=0
this.getVarSelectOption()
}, 500),
handleFocus() {
this.getVarSelectOption()
},
handleBlur() {
this.pageNo=1
this.pageTotal=0
this.searchValue=undefined
},
// 下拉框下滑事件
handlePopupScroll: simpleDebounce(function (e){
if(this.pageNo >= this.pageTotal) return
const { target } = e
const scrollHeight = target.scrollHeight - target.scrollTop
const clientHeight = target.clientHeight
if (scrollHeight === 0 && clientHeight === 0) {
this.pageNo=1
} else {
// 当下拉框滚动条到达底部的时候
if (scrollHeight < clientHeight 5) {
this.pageNo = this.pageNo 1
this.getVarSelectOption()
}
}
}, 500),
optionsDisabled(i) {
const scene1 = this.selectedItems.length >= 6 && this.selectedItems.findIndex(o => o === i.variableId) === -1
const tempArr = this.varSelectedList.filter(item => {
return typeof item.tableId !== 'undefined'
}).map(item => {
return item.variableId
})
const scene2 = tempArr.includes(i.variableId)
return scene1 || scene2
},
moment,
handleSubmit() {
const selectedItems = this.varOption.filter(item => {
return this.selectedItems.includes(item.variableId)
})
// this.$emit('getVarIds', selectedItems, this.place)
this.$emit('getVarIds', this.tableData, this.place)
this.handleCancel()
},
handleCancel() {
this.close()
},
filterOption(input, option) {
return (
option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
);
},
},
watch: {
varSelectedList: {
handler(val) {
this.selectedItems = val.map(item => {
return item.variableId
})
},
immediate: true
}
}
}
</script>
<style scoped lang='less'>
@import '~@assets/less/common.less';
.search-panel {
display: flex;
gap: 20px;
justify-content: left;
align-items: center;
margin-bottom: 20px;
> span {
display: inline-block;
}
.var-select {
flex: 1;
}
}
.one-card-of-modal {
margin-bottom: 0 !important;
}
</style>