Compare commits

..

3 Commits

Author SHA1 Message Date
lb
ac041c2f4a update bom-selector v1 2023-11-20 15:53:23 +08:00
lb
dd23c49ba0 update 设备选择 2023-11-20 14:21:14 +08:00
lb
44452f2e89 update 2023-11-20 11:26:27 +08:00
8 changed files with 283 additions and 494 deletions

View File

@ -12,8 +12,8 @@ ENV = 'development'
VUE_APP_TITLE = MES系统 VUE_APP_TITLE = MES系统
# 芋道管理系统/开发环境 # 芋道管理系统/开发环境
VUE_APP_BASE_API = 'http://100.64.0.26:48082' # VUE_APP_BASE_API = 'http://100.64.0.26:48082'
# VUE_APP_BASE_API = 'http://192.168.0.33:48082' VUE_APP_BASE_API = 'http://192.168.0.33:48082'
# VUE_APP_BASE_API = 'http://192.168.4.173:48080' # VUE_APP_BASE_API = 'http://192.168.4.173:48080'
# VUE_APP_BASE_API = 'http://192.168.2.173:48080' # VUE_APP_BASE_API = 'http://192.168.2.173:48080'
# VUE_APP_BASE_API = 'http://192.168.1.49:48080' # VUE_APP_BASE_API = 'http://192.168.1.49:48080'

View File

@ -0,0 +1,107 @@
<!--
filename: BomSelection.vue
author: liubin
date: 2023-11-20 13:23:36
description:
-->
<template>
<div class="bom-selection">
<el-checkbox
v-for="item in list__inner"
:key="item.id + randomKey"
:label="item.name"
:disabled="item.disabled"
:checked="item.id === selected"
@change="(e) => handleChange(item, e)"
class="sl__body-item"></el-checkbox>
</div>
</template>
<script>
export default {
name: 'BomSelection',
components: {},
// model: {
// prop: 'selected',
// event: 'update',
// },
props: {
// selected: {
// type: String,
// default: '',
// },
list: {
type: Array,
default: () => [],
},
equipmentId: {
type: String,
default: '',
},
},
data() {
return {
list__inner: [],
selected: null,
randomKey: Math.random()
};
},
watch: {
list: {
handler(val) {
if (val) {
this.list__inner = val.map((item) => ({ ...item, disabled: false }));
}
},
deep: true,
immediate: true,
},
},
methods: {
handleChange(bomItem, selected) {
this.list__inner = this.list__inner.map((item) => ({
...item,
disabled: selected ? item.id !== bomItem.id : false,
}));
if (selected) this.selected = null;
else this.clearSelected();
this.$emit('change', this.equipmentId, bomItem.id, selected);
this.$nextTick(() => {
this.$forceUpdate();
});
},
clearSelected() {
console.log('clearSelected');
this.selected = null;
this.randomKey = Math.random()
// this.$emit('update', null);
// this.$nextTick(() => {
// this.$forceUpdate();
// });
},
},
};
</script>
<style scoped lang="scss">
.bom-selection {
display: flex;
flex-direction: column;
gap: 6px;
padding: 6px;
}
.sl__body-item {
margin: 0;
padding: 3px 6px;
border-radius: 4px;
transition: background 0.3s ease-in-out;
&:hover {
background: #0001;
}
}
</style>

View File

@ -12,40 +12,45 @@
<el-input <el-input
v-model="searchText" v-model="searchText"
placeholder="搜索" placeholder="搜索"
clearable
style="margin-bottom: 12px; user-select: none"> style="margin-bottom: 12px; user-select: none">
<i slot="prefix" class="el-input__icon el-icon-search"></i> <i slot="prefix" class="el-input__icon el-icon-search"></i>
</el-input> </el-input>
</el-col> </el-col>
</el-row> </el-row>
<el-row style="border: 1px solid #ccc; display: flex;"> <el-row style="border: 1px solid #ccc; display: flex">
<el-col :span="8"> <el-col :span="8">
<div class="select-list"> <div class="select-list">
<div class="sl__header" style="background: #f3f4fb; padding: 12px"> <div class="sl__header" style="background: #f3f4fb; padding: 12px">
<span style="">可分配设备</span> <span style="">可分配设备</span>
<span>1/24</span> <span>
{{ selectedEquipments.length }}/{{ filteredBomList.length }}
</span>
</div> </div>
<el-checkbox-group v-model="selectedEquipments" class="sl__body"> <div class="sl__body">
<el-checkbox <el-checkbox
v-for="n in 10" v-for="eq in filteredBomList"
:key="n" :key="eq.id + refreshKey"
:label="'设备' + n" :label="eq.name"
@change="() => handleChange(n)" :checked="selectedEquipments.includes(eq.id)"
@change="(e) => handleEquipmentChange(eq, e)"
class="sl__body-item"></el-checkbox> class="sl__body-item"></el-checkbox>
</el-checkbox-group> </div>
</div> </div>
</el-col> </el-col>
<el-col :span="8" style="border-left: 1px solid #ccc;"> <el-col :span="8" style="border-left: 1px solid #ccc">
<div class="select-list"> <div class="select-list">
<div class="sl__header" style="background: #f3f4fb; padding: 12px"> <div class="sl__header" style="background: #f3f4fb; padding: 12px">
<span style="">物料BOM</span> <span style="">物料BOM</span>
</div> </div>
<el-checkbox-group v-model="selectedMBom" class="sl__body">
<el-checkbox <BomSelection
v-for="n in materialBomList" ref="materialsBomList"
:key="n" key="materialsBomList"
class="sl__body-item"></el-checkbox> :list="materialsBomList"
</el-checkbox-group> :equipment-id="materialsBomList.equipmentId"
@change="handleMaterialBomChange" />
</div> </div>
</el-col> </el-col>
<el-col :span="8" style="border-left: 1px solid #ccc"> <el-col :span="8" style="border-left: 1px solid #ccc">
@ -53,12 +58,13 @@
<div class="sl__header" style="background: #f3f4fb; padding: 12px"> <div class="sl__header" style="background: #f3f4fb; padding: 12px">
<span style="">参数BOM</span> <span style="">参数BOM</span>
</div> </div>
<el-checkbox-group v-model="selectedPBom" class="sl__body">
<el-checkbox <BomSelection
v-for="n in paramBomList" ref="valuesBomList"
:key="n" key="valuesBomList"
class="sl__body-item"></el-checkbox> :list="valuesBomList"
</el-checkbox-group> :equipment-id="valuesBomList.equipmentId"
@change="handleValueBomChange" />
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
@ -66,49 +72,122 @@
</template> </template>
; ;
<script> <script>
import BomSelection from './BomSelection.vue';
export default { export default {
name: 'BomSelector', name: 'BomSelector',
components: {}, components: { BomSelection },
props: {}, model: {
prop: 'value',
event: 'update',
},
props: {
bomList: {
type: Array,
default: () => [],
},
value: {
type: Array,
default: () => [],
},
},
data() { data() {
return { return {
searchText: '', searchText: '',
selectedEquipments: [], selectedEquipments: [],
selectedMBom: [],
selectedPBom: [],
selected: [], selected: [],
materialBomList: [], materialsBomList: [],
paramBomList: [], valuesBomList: [],
refreshKey: Math.random(),
}; };
}, },
watch: { watch: {
selected: { value: {
handler(val) { handler(val) {
console.log(val); console.log('value', val);
if (val) {
this.selectedEquipments = val.map((item) => item.equipmentId);
this.selected = val;
}
}, },
deep: true, deep: true,
immediate: true,
}, },
}, },
computed: {}, computed: {
methods: { filteredBomList() {
handleChange(id) { return this.bomList.filter((item) => {
this.materialBomList = []; return item.name.includes(this.searchText);
this.paramBomList = [];
this.selected.push({
id: id,
}); });
}, },
handleBomChange(eqId, id, type) { },
const record = this.selected.find((item) => item.id === eqId); methods: {
if (record) { handleEquipmentChange(eq, selected) {
record[type == 'param' ? 'paramBomId' : 'materialBomId'] = id; this.currentEquipment = eq.id;
} else { this.materialsBomList = eq.materialsBom;
this.valuesBomList = eq.valuesBom;
if (selected) {
this.selectedEquipments.push(eq.id);
this.selected.push({ this.selected.push({
id: eqId, equipmentId: eq.id,
[type == 'param' ? 'paramBomId' : 'materialBomId']: 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> </script>

View File

@ -1,111 +0,0 @@
<!--
filename: CustomBomList.vue
author: liubin
date: 2023-11-17 14:06:04
description:
-->
<template>
<div class="custom-bom-list—wrapper">
<div
class="ct__equipment-name"
@click.prevent="
() => {
$emit('open', equipment.id);
}
">
{{ equipment.name }}
</div>
<div
class="ct__bom-list"
:class="{
hidden: active && bomListLength > 0 ? false : true,
}">
<ul class="param-bom">
<li v-for="bom in equipment.paramBomList" :key="bom.name">
{{ bom.name }}
</li>
</ul>
<ul class="material-bom">
<li v-for="bom in equipment.materialBomList" :key="bom.name">
{{ bom.name }}
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
name: 'CustomBomList',
components: {},
props: {
equipment: {
type: Object,
default: () => ({}),
},
active: {
type: Boolean,
default: false,
},
},
computed: {
bomListLength() {
return (
(this.equipment.paramBomList?.length || 0) +
(this.equipment.materialBomList?.length || 0)
);
},
},
data() {
return {
showList: false,
};
},
methods: {},
};
</script>
<style scoped lang="scss">
// .custom-bom-listwrapper {
// height: auto;
// transition: height .2s ease-in-out;
// }
.ct__equipment-name {
background: #0001;
padding: 8px;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s;
&:hover {
background: #0002;
}
}
.hidden {
display: none;
}
ul,
li {
margin: 0;
padding: 0;
list-style: none;
}
ul {
display: flex;
flex-direction: column;
gap: 4px;
margin-top: 4px;
}
.material-bom > li,
.param-bom > li {
padding: 4px 24px;
background: #0001;
border-radius: 4px;
}
</style>

View File

@ -1,127 +0,0 @@
<!--
filename: CustomTransfer.vue
author: liubin
date: 2023-11-17 10:22:28
description:
-->
<template>
<div class="custom-transfer">
<CustomTransferBox
key="left"
class="left-ctb"
title="设备列表"
:candidate-list="candidateList"
:selected-list="selectedList"
@selected-list-change="handleChange" />
<div
class="btns"
style="
display: flex;
flex-direction: column;
gap: 12px;
justify-content: center;
align-items: center;
">
<el-button style="margin: 0">&gt;</el-button>
<el-button style="margin: 0" disabled>&lt;</el-button>
</div>
<CustomTransferBox
key="right"
class="right-ctb"
title="已选BOM"
:candidate-list="[]"
:selected-list="[]"
@selected-list-change="handleChange" />
</div>
</template>
<script>
import CustomTransferBox from './CustomTransferBox.vue';
export default {
name: 'CustomTransfer',
components: { CustomTransferBox },
props: ['sectionId', 'selectedBoms'],
data() {
return {
pageUrl: '',
list: [],
bomLoading: false,
queryParams: {
pageNo: 1,
pageSize: 100,
},
candidate: [],
selectedList: [],
};
},
computed: {},
methods: {
http(url, method, payload) {
return this.$axios({
url,
method,
params: method === 'get' ? payload : null,
data: method !== 'get' ? payload : null,
});
},
//
async getList() {
const res = await this.http.get(this.pageUrl, {
workshopSectionId: this.sectionId,
...this.queryParams,
});
if (res.code === 200) {
// this.list = res.data;
this.list = [
{ equipmentId: 1, equipmentName: '设备1' },
{ equipmentId: 2, equipmentName: '设备2' },
{ equipmentId: 3, equipmentName: '设备3' },
];
}
},
// bombom
async getMaterialBom(eqId) {},
async getParamBom(eqId) {},
async handleEquipmentClick(eqItem) {
this.bomLoading = true;
eqItem.children = [];
const { code: materialCode, data: materialData } =
await this.getMaterialBom(eqItem.equipmentId);
const { code: paramCode, data: paramData } = await this.getParamBom(
eqItem.equipmentId
);
if (materialCode == 0) {
eqItem.children.push(...materialData);
}
if (paramCode == 0) {
eqItem.children.push(...paramData);
}
this.bomLoading = false;
},
//
handleChange() {},
},
};
</script>
<style scoped lang="scss">
.custom-transfer {
background: '#cfc2';
display: flex;
}
.btns {
padding: 10px;
}
.left-ctb {
flex: 1;
}
.right-ctb {
flex: 1;
}
</style>

View File

@ -1,110 +0,0 @@
<!--
filename: CustomTrasferBox.vue
author: liubin
date: 2023-11-17 10:49:08
description:
-->
<template>
<div class="custom-transfer-box">
<div class="ctb-header">
<span>
{{ title }}
</span>
<span>
<b>{{ selectedList.length }}</b>
/
<b>{{ candidateList.length }}</b>
</span>
</div>
<div class="ctb-main">
<el-input
v-model="searchText"
placeholder="搜索"
style="margin-bottom: 12px; user-select: none">
<i slot="prefix" class="el-input__icon el-icon-search"></i>
</el-input>
<custom-tree :raw-data="candidateList" />
</div>
<div class="ctb-footer">
<pagination
v-show="1"
style="padding: 0"
:total="total"
:page.sync="queryParams.pageNo"
:limit.sync="queryParams.pageSize"
@pagination="getList" />
</div>
</div>
</template>
<script>
import CustomTree from './CustomTree.vue';
export default {
name: 'CustomTransferBox',
components: { CustomTree },
props: {
title: {
type: String,
default: '',
},
candidateList: {
type: Array,
default: () => [],
},
selectedList: {
type: Array,
default: () => [],
},
},
data() {
return {
queryParams: {
pageNo: 1,
pageSize: 10,
},
total: 0,
searchText: '',
};
},
computed: {},
methods: {
getList() {
this.$emit('get-list', this.queryParams);
},
},
};
</script>
<style scoped lang="scss">
.custom-transfer-box {
margin: 0 8px;
flex: 1;
border: 1px solid #ccc;
border-radius: 8px;
min-height: 240px;
display: flex;
flex-direction: column;
}
.ctb-header {
min-height: 12px;
padding: 12px;
border-bottom: 1px solid #ccc;
display: flex;
justify-content: space-between;
}
.ctb-main {
flex: 1;
padding: 12px;
}
.ctb-footer {
user-select: none;
min-height: 12px;
padding: 12px;
border-top: 1px solid #ccc;
}
</style>

View File

@ -1,53 +0,0 @@
<!--
filename: CustomTree.vue
author: liubin
date: 2023-11-17 13:53:16
description:
-->
<template>
<div class="custom-tree">
<div v-for="equipment in rawData" :key="eq.id">
<CustomBomList
@open="closeOthers"
:active="activeId == eq.id"
:equipment="equipment" />
</div>
</div>
</template>
<script>
import CustomBomList from './CustomBomList.vue';
export default {
name: 'CustomTree',
components: { CustomBomList },
props: {
rawData: {
type: Array,
default: () => [],
},
},
data() {
return {
showList: false,
activeId: null,
};
},
computed: {},
methods: {
closeOthers(id) {
this.activeId = id;
},
},
};
</script>
<style scoped lang="scss">
.custom-tree {
// background: #0001;
display: flex;
flex-direction: column;
gap: 8px;
}
</style>

View File

@ -68,13 +68,12 @@
@cancel="cancel" @cancel="cancel"
@confirm="submitForm"> @confirm="submitForm">
<!-- <CustomTransfer /> --> <!-- <CustomTransfer /> -->
<BomSelector /> <BomSelector :bom-list="bomList" v-model="selectedBoms" />
</base-dialog> </base-dialog>
</section> </section>
</template> </template>
<script> <script>
import CustomTransfer from './CustomTransfer.vue';
import BomSelector from './BomSelector.vue'; import BomSelector from './BomSelector.vue';
export default { export default {
@ -90,6 +89,7 @@ export default {
return { return {
open: false, open: false,
eqList: [], eqList: [],
bomList: [],
finalList: [], finalList: [],
choosedEquipments: [], choosedEquipments: [],
searchBarFormConfig: [{ label: '工序下设备' }], searchBarFormConfig: [{ label: '工序下设备' }],
@ -106,11 +106,13 @@ export default {
pageSize: 10, pageSize: 10,
}, },
searchText: '', searchText: '',
selectedBoms: [],
}; };
}, },
watch: { watch: {
currentDet: { currentDet: {
handler(val) { handler(val) {
console.log('currentDet', val);
if (val != null) { if (val != null) {
this.getList(val); this.getList(val);
} else { } else {
@ -122,49 +124,6 @@ export default {
}, },
}, },
methods: { methods: {
renderFn(h, option) {
console.log(option);
return <span>1</span>;
},
async getEqList() {
console.log('currentDet', this.currentDet);
const { sectionId } = this.currentDet;
const { code, data } = await this.http(
'base/core-equipment-bind-section/page',
'get',
{ workshopSectionId: sectionId, pageNo: 1, pageSize: 100 }
);
if (code == 0) {
console.log('workshopSectionId', data);
//
this.eqList = [
{ equipmentId: 1, equipmentName: '设备1' },
{ equipmentId: 2, equipmentName: '设备2' },
{ equipmentId: 3, equipmentName: '设备3' },
{ equipmentId: 4, equipmentName: '设备4' },
{ equipmentId: 5, equipmentName: '设备5' },
{ equipmentId: 6, equipmentName: '设备6' },
]; // ].map((item) => ({ label: item.equipmentName, key: item.equipmentId }));
// bombom
// bom bom
this.finalList = this.eqList.map((item) => {
item.sub = [];
// key: equipmentId-bomId
item.sub.push({
key: item.equipmentId + '-' + '101',
label: '参数bom1',
});
item.sub.push({
key: item.equipmentId + '-' + '201',
label: '物料bom1',
});
return item;
});
}
},
handleEmitFun() {}, handleEmitFun() {},
handleTableBtnClick() {}, handleTableBtnClick() {},
put(payload) { put(payload) {
@ -187,8 +146,36 @@ export default {
data: method !== 'get' ? payload : null, data: method !== 'get' ? payload : null,
}); });
}, },
submitForm() {}, async submitForm() {
async getList({ detId, detName, detDesc, flowId, sectionName } = {}) { console.log('selectedBoms', this.selectedBoms);
if (this.selectedBoms.length) {
const { code, data } = await this.http(
'/extend/process-flow-det-equipment/createList',
'post',
this.selectedBoms.map((item) => ({
...item,
flowDetId: this.currentDet.detId,
}))
);
if (code == 0) {
this.$message.success('操作成功');
this.getList(this.currentDet);
this.cancel();
} else {
this.$message.error('操作失败');
}
} else {
this.$message.info('请选择设备');
}
},
async getList({
detId,
detName,
detDesc,
flowId,
sectionName,
sectionId,
} = {}) {
console.log('get list', detId, detName, flowId); console.log('get list', detId, detName, flowId);
const { data, code } = await this.http( const { data, code } = await this.http(
'/extend/process-flow-det-equipment/page', '/extend/process-flow-det-equipment/page',
@ -202,10 +189,27 @@ export default {
this.list.splice(0); this.list.splice(0);
this.total = 0; this.total = 0;
} }
// bom
this.http(
'/extend/process-flow-det/getEquipmentDetBySectionId?id=' + sectionId,
'post'
).then(({ code, data }) => {
if (code == 0) {
this.bomList = data.map((eq) => {
eq.materialsBom = eq.materialsBom || [];
eq.valuesBom = eq.valuesBom || [];
eq.materialsBom.equipmentId = eq.id;
eq.valuesBom.equipmentId = eq.id;
return eq;
});
} else {
this.bomList.splice(0);
}
});
}, },
async handleAddEquipment() { async handleAddEquipment() {
this.open = true; this.open = true;
await this.getEqList();
}, },
cancel() { cancel() {
this.open = false; this.open = false;