<!-- filename: BomSelector.vue author: liubin date: 2023-11-17 16:23:28 description: --> <template> <div class="bom-selector"> <el-row> <el-col :span="8"> <el-input v-model="searchText" placeholder="搜索" clearable style="margin-bottom: 12px; user-select: none"> <i slot="prefix" class="el-input__icon el-icon-search"></i> </el-input> </el-col> </el-row> <el-row style="border: 1px solid #ccc; display: flex"> <el-col :span="8"> <div class="select-list"> <div class="sl__header" style="background: #f3f4fb; padding: 12px"> <span style="">可分配设备</span> <span> {{ selectedEquipments.length }}/{{ filteredBomList.length }} </span> </div> <div class="sl__body"> <el-checkbox v-for="eq in filteredBomList" :key="eq.id + refreshKey" :label="eq.name" :checked="selectedEquipments.includes(eq.id)" @change="(e) => handleEquipmentChange(eq, e)" class="sl__body-item"></el-checkbox> </div> </div> </el-col> <el-col :span="8" style="border-left: 1px solid #ccc"> <div class="select-list"> <div class="sl__header" style="background: #f3f4fb; padding: 12px"> <span style="">物料BOM</span> </div> <BomSelection ref="materialsBomList" key="materialsBomList" :list="materialsBomList" :equipment-id="materialsBomList.equipmentId" @change="handleMaterialBomChange" /> </div> </el-col> <el-col :span="8" style="border-left: 1px solid #ccc"> <div class="select-list"> <div class="sl__header" style="background: #f3f4fb; padding: 12px"> <span style="">参数BOM</span> </div> <BomSelection ref="valuesBomList" key="valuesBomList" :list="valuesBomList" :equipment-id="valuesBomList.equipmentId" @change="handleValueBomChange" /> </div> </el-col> </el-row> </div> </template> ; <script> import BomSelection from './BomSelection.vue'; export default { name: 'BomSelector', components: { BomSelection }, model: { prop: 'value', event: 'update', }, props: { bomList: { type: Array, default: () => [], }, value: { type: Array, default: () => [], }, }, data() { return { searchText: '', selectedEquipments: [], selected: [], materialsBomList: [], valuesBomList: [], refreshKey: Math.random(), }; }, watch: { value: { handler(val) { console.log('value', val); if (val) { this.selectedEquipments = val.map((item) => item.equipmentId); this.selected = val; } }, deep: true, immediate: true, }, }, computed: { filteredBomList() { return this.bomList.filter((item) => { return item.name.includes(this.searchText); }); }, }, methods: { commit() { this.$emit('update', this.selected); }, handleEquipmentChange(eq, selected) { this.currentEquipment = eq.id; this.materialsBomList = eq.materialsBom; this.valuesBomList = eq.valuesBom; if (selected) { this.selectedEquipments.push(eq.id); this.selected.push({ equipmentId: eq.id, equValueBomId: null, equMaterialBomId: null, }); // this.$emit('update', this.selected); } else { // 清空选择状态 this.selectedEquipments = this.selectedEquipments.filter( (id) => id !== eq.id ); this.$refs.materialsBomList.clearSelected(); this.$refs.valuesBomList.clearSelected(); this.selected = this.selected.filter( (item) => item.equipmentId !== eq.id ); // this.$emit('update', this.selected); } }, handleMaterialBomChange(equipmentId, bomId, selected) { const selectedItem = this.selected.find( (item) => item.equipmentId == equipmentId ); if (selected && !selectedItem) { // 如果没找到这个 this.selectedEquipments.push(equipmentId); this.selected.push({ equipmentId, equValueBomId: null, equMaterialBomId: bomId, }); // 强制更新'设备'一栏 this.refreshKey = Math.random(); // this.$emit('update', this.selected); return; } selectedItem && (selectedItem.equMaterialBomId = selected ? bomId : null); // this.$emit('update', this.selected); }, handleValueBomChange(equipmentId, bomId, selected) { const selectedItem = this.selected.find( (item) => item.equipmentId == equipmentId ); if (selected && !selectedItem) { // 如果没找到这个 this.selectedEquipments.push(equipmentId); this.selected.push({ equipmentId, equValueBomId: bomId, equMaterialBomId: null, }); this.refreshKey = Math.random(); // this.$emit('update', this.selected); return; } selectedItem && (selectedItem.equValueBomId = selected ? bomId : null); // this.$emit('update', this.selected); }, }, }; </script> <style scoped lang="scss"> .bom-selector { min-height: 200px; } .select-list { } .sl__body { display: flex; flex-direction: column; gap: 6px; padding: 6px; > .el-checkbox { margin: 0; padding: 3px 6px; border-radius: 4px; transition: background 0.3s ease-in-out; &:hover { background: #0001; } } } .sl__header { border-bottom: 1px solid #ccc; } </style>