From ed36047f6ce0b91dad25efc10c8a0e83dd533a68 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期五, 20 三月 2026 17:15:37 +0800
Subject: [PATCH] change
---
src/views/productionManagement/processRoute/processRouteItem/index.vue | 451 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 430 insertions(+), 21 deletions(-)
diff --git a/src/views/productionManagement/processRoute/processRouteItem/index.vue b/src/views/productionManagement/processRoute/processRouteItem/index.vue
index 2a5186c..5d841e8 100644
--- a/src/views/productionManagement/processRoute/processRouteItem/index.vue
+++ b/src/views/productionManagement/processRoute/processRouteItem/index.vue
@@ -169,6 +169,16 @@
<div class="section-BOM">
<div class="section-header">
<div class="section-title">BOM</div>
+ <div class="section-actions"
+ v-if="pageType === 'order'">
+ <el-button type="primary"
+ @click="toggleBomEdit">
+ {{ bomDataValue.isEdit ? '鍙栨秷' : '缂栬緫' }}
+ </el-button>
+ <el-button v-if=" bomDataValue.isEdit"
+ type="success"
+ @click="saveBomChanges">淇濆瓨</el-button>
+ </div>
</div>
<div>
<!-- BOM琛ㄦ牸 -->
@@ -179,28 +189,110 @@
style="width: 100%">
<el-table-column type="expand">
<template #default="props">
- <el-table :data="props.row.bomList"
- row-key="id"
- default-expand-all
- :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
- style="width: 100%">
- <el-table-column prop="productName"
- label="浜у搧" />
- <el-table-column prop="model"
- label="瑙勬牸" />
- <el-table-column prop="processName"
- label="娑堣�楀伐搴�" />
- <el-table-column prop="unitQuantity"
- label="鍗曚綅浜у嚭鎵�闇�鏁伴噺" />
- <el-table-column prop="unit"
- label="鍗曚綅" />
- </el-table>
+ <el-form ref="bomFormRef"
+ :model="bomDataValue">
+ <el-table :data="props.row.bomList"
+ row-key="tempId"
+ default-expand-all
+ :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
+ style="width: 100%">
+ <el-table-column prop="productName"
+ label="浜у搧" />
+ <el-table-column prop="model"
+ label="瑙勬牸">
+ <template #default="{ row }">
+ <el-form-item v-if="bomDataValue.isEdit"
+ style="margin: 0">
+ <el-select v-model="row.model"
+ placeholder="璇烽�夋嫨瑙勬牸"
+ :disabled="!bomDataValue.isEdit"
+ style="width: 100%"
+ @visible-change="(v) => { if (v) openBomProductDialog(row.tempId) }">
+ <el-option v-if="row.model"
+ :label="row.model"
+ :value="row.model" />
+ </el-select>
+ </el-form-item>
+ <span v-else>{{ row.model }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column prop="processName"
+ label="娑堣�楀伐搴�">
+ <template #default="{ row }">
+ <el-form-item v-if="bomDataValue.isEdit"
+ style="margin: 0">
+ <el-select v-model="row.processId"
+ placeholder="璇烽�夋嫨娑堣�楀伐搴�"
+ :disabled="!bomDataValue.isEdit"
+ style="width: 100%">
+ <el-option v-for="process in processOptions"
+ :key="process.id"
+ :label="process.name"
+ :value="process.id" />
+ </el-select>
+ </el-form-item>
+ <span v-else>{{ row.processName }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column prop="unitQuantity"
+ label="鍗曚綅浜у嚭鎵�闇�鏁伴噺">
+ <template #default="{ row }">
+ <el-form-item v-if="bomDataValue.isEdit"
+ style="margin: 0">
+ <el-input-number v-model="row.unitQuantity"
+ :min="0"
+ :step="1"
+ controls-position="right"
+ style="width: 100%"
+ :disabled="!bomDataValue.isEdit" />
+ </el-form-item>
+ <span v-else>{{ row.unitQuantity }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column prop="unit"
+ label="鍗曚綅">
+ <template #default="{ row }">
+ <el-form-item v-if="bomDataValue.isEdit"
+ style="margin: 0">
+ <el-input v-model="row.unit"
+ placeholder="璇疯緭鍏ュ崟浣�"
+ clearable
+ :disabled="!bomDataValue.isEdit" />
+ </el-form-item>
+ <span v-else>{{ row.unit }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="鎿嶄綔"
+ fixed="right"
+ v-if="pageType === 'order'"
+ width="180">
+ <template #default="{ row }">
+ <el-button v-if="bomDataValue.isEdit"
+ type="danger"
+ text
+ size="small"
+ @click="removeBomItem(row.tempId)">鍒犻櫎</el-button>
+ <el-button v-if="bomDataValue.isEdit"
+ type="primary"
+ text
+ size="small"
+ @click="addBomItem2(row.tempId)">娣诲姞瀛愰」</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </el-form>
</template>
</el-table-column>
<el-table-column label="BOM缂栧彿"
prop="bomNo" />
<el-table-column label="浜у搧绫诲瀷"
prop="dictLabel" />
+ <!-- <el-table-column label="鎿嶄綔"
+ width="150">
+ <template #default="{ row }">
+
+ </template>
+ </el-table-column> -->
<!-- <el-table-column label="浜у搧缂栫爜"
prop="productCode" />
<el-table-column label="浜у搧鍚嶇О"
@@ -208,6 +300,18 @@
<el-table-column label="瑙勬牸鍨嬪彿"
prop="model" /> -->
</el-table>
+ <div v-if="bomDataValue.isEdit"
+ style="text-align: center;border: 1px solid #e4e7ed;padding: 10px;transition: all 0.3s ease;cursor: pointer;"
+ :class="{'hover-effect': bomDataValue.isEdit}">
+ <el-button type="primary"
+ text
+ @click="addBomItem">
+ <el-icon style="vertical-align: middle;margin-right: 5px;">
+ <Plus />
+ </el-icon>
+ 娣诲姞
+ </el-button>
+ </div>
</div>
</div>
<!-- 鏂板/缂栬緫寮圭獥 -->
@@ -249,6 +353,10 @@
<ProductSelectDialog v-model="showProductSelectDialog"
@confirm="handleProductSelect"
single />
+ <!-- BOM浜у搧閫夋嫨瀵硅瘽妗� -->
+ <ProductSelectDialog v-model="bomDataValue.showProductDialog"
+ @confirm="handleBomProductSelect"
+ single />
<!-- 鍙傛暟鍒楄〃瀵硅瘽妗� -->
<ProcessParamListDialog v-model="showParamListDialog"
:title="`${currentProcess ? getProcessName(currentProcess.processId) : ''} - 鍙傛暟鍒楄〃`"
@@ -289,7 +397,11 @@
sortRouteItem,
} from "@/api/productionManagement/productProcessRoute.js";
import { processList } from "@/api/productionManagement/productionProcess.js";
- import { queryList } from "@/api/productionManagement/productStructure.js";
+ import {
+ queryList2,
+ queryList,
+ add2,
+ } from "@/api/productionManagement/productStructure.js";
import { useRoute } from "vue-router";
import { ElMessageBox, ElMessage } from "element-plus";
import Sortable from "sortablejs";
@@ -327,6 +439,14 @@
const currentProcess = ref(null);
const paramList = ref([]);
const bomTableData = ref([]);
+ const bomFormRef = ref(null);
+ const bomDataValue = ref({
+ dataList: [],
+ showProductDialog: false,
+ currentRowName: null,
+ loading: false,
+ isEdit: false,
+ });
let tableSortable = null;
let cardSortable = null;
@@ -407,12 +527,21 @@
bomId: route.query.bomId || null,
description: route.query.description || "",
};
-
- // 濡傛灉鏈塨omId锛岃幏鍙朆OM鏁版嵁
- if (routeInfo.value.bomId) {
- queryList(routeInfo.value.bomId)
+ if (pageType.value === "order") {
+ queryList2(route.query.orderId)
.then(res => {
if (res.data) {
+ // 涓築OM鏁版嵁璁剧疆tempId
+ const setTempIdRecursively = items => {
+ items.forEach(item => {
+ item.tempId = item.id || new Date().getTime();
+ if (item.children && item.children.length > 0) {
+ setTempIdRecursively(item.children);
+ }
+ });
+ };
+ setTempIdRecursively(res.data);
+
bomTableData.value = [
{
bomNo: routeInfo.value.bomNo,
@@ -423,12 +552,49 @@
bomList: res.data,
},
];
+
+ // 淇濆瓨鍘熷BOM鏁版嵁
+ bomDataValue.value.dataList = res.data;
+ }
+ })
+ .catch(err => {
+ console.error("鑾峰彇BOM鏁版嵁澶辫触锛�", err);
+ });
+ } else {
+ queryList(Number(route.query.bomId))
+ .then(res => {
+ if (res.data) {
+ // 涓築OM鏁版嵁璁剧疆tempId
+ const setTempIdRecursively = items => {
+ items.forEach(item => {
+ item.tempId = item.id || new Date().getTime();
+ if (item.children && item.children.length > 0) {
+ setTempIdRecursively(item.children);
+ }
+ });
+ };
+ setTempIdRecursively(res.data);
+
+ bomTableData.value = [
+ {
+ bomNo: routeInfo.value.bomNo,
+ dictLabel: routeInfo.value.dictLabel,
+ productCode: "",
+ productName: routeInfo.value.productName,
+ model: routeInfo.value.model,
+ bomList: res.data,
+ },
+ ];
+
+ // 淇濆瓨鍘熷BOM鏁版嵁
+ bomDataValue.value.dataList = res.data;
}
})
.catch(err => {
console.error("鑾峰彇BOM鏁版嵁澶辫触锛�", err);
});
}
+ // 鑾峰彇BOM鏁版嵁锛屼娇鐢ㄦ柊鐨勬帴鍙�
};
// 鏂板
@@ -586,6 +752,241 @@
const closeDialog = () => {
dialogVisible.value = false;
resetForm();
+ };
+
+ // BOM鐩稿叧鏂规硶
+ // 鍒囨崲BOM缂栬緫妯″紡
+ const toggleBomEdit = () => {
+ bomDataValue.value.isEdit = !bomDataValue.value.isEdit;
+ if (!bomDataValue.value.isEdit) {
+ // 鍙栨秷缂栬緫鏃堕噸鏂板姞杞芥暟鎹�
+ getRouteInfo();
+ }
+ };
+
+ // 娣诲姞BOM椤�
+ const addBomItem = () => {
+ if (bomTableData.value.length > 0) {
+ const newItem = {
+ parentId: "",
+ parentTempId: "",
+ productName: "",
+ productId: "",
+ model: undefined,
+ productModelId: undefined,
+ processId: "",
+ processName: "",
+ unitQuantity: 0,
+ unit: "",
+ children: [],
+ tempId: new Date().getTime(),
+ };
+ bomTableData.value[0].bomList.push(newItem);
+ // 鐢变簬bomDataValue.value.dataList鍜宐omTableData.value[0].bomList鎸囧悜鍚屼竴涓暟缁勶紝涓嶉渶瑕侀噸澶嶆坊鍔�
+ }
+ };
+
+ // 娣诲姞BOM瀛愰」
+ const addBomItem2 = tempId => {
+ const addChildItem = (items, tempId) => {
+ for (let i = 0; i < items.length; i++) {
+ const item = items[i];
+ if (item.tempId === tempId) {
+ if (!item.children) {
+ item.children = [];
+ }
+ item.children.push({
+ parentId: item.id || "",
+ parentTempId: item.tempId || "",
+ productName: "",
+ productId: "",
+ model: undefined,
+ productModelId: undefined,
+ processId: "",
+ processName: "",
+ unitQuantity: 0,
+ unit: "",
+ children: [],
+ tempId: new Date().getTime(),
+ });
+ return true;
+ }
+ if (item.children && item.children.length > 0) {
+ if (addChildItem(item.children, tempId)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ };
+
+ if (bomTableData.value.length > 0) {
+ addChildItem(bomTableData.value[0].bomList, tempId);
+ // 鐢变簬bomDataValue.value.dataList鍜宐omTableData.value[0].bomList鎸囧悜鍚屼竴涓暟缁勶紝涓嶉渶瑕侀噸澶嶆坊鍔�
+ }
+ };
+
+ // 鍒犻櫎BOM椤�
+ const removeBomItem = tempId => {
+ // 浠嶣OM琛ㄦ牸鏁版嵁涓垹闄�
+ if (bomTableData.value.length > 0) {
+ const removeFromList = (items, tempId) => {
+ for (let i = 0; i < items.length; i++) {
+ const item = items[i];
+ if (item.tempId === tempId) {
+ items.splice(i, 1);
+ return true;
+ }
+ if (item.children && item.children.length > 0) {
+ if (removeFromList(item.children, tempId)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ };
+ removeFromList(bomTableData.value[0].bomList, tempId);
+ // 鐢变簬bomDataValue.value.dataList鍜宐omTableData.value[0].bomList鎸囧悜鍚屼竴涓暟缁勶紝涓嶉渶瑕侀噸澶嶅垹闄�
+ }
+ };
+
+ // 鎵撳紑BOM浜у搧閫夋嫨瀵硅瘽妗�
+ const openBomProductDialog = tempId => {
+ bomDataValue.value.currentRowName = tempId;
+ bomDataValue.value.showProductDialog = true;
+ };
+
+ // 澶勭悊BOM浜у搧閫夋嫨
+ const handleBomProductSelect = products => {
+ if (products && products.length > 0) {
+ const product = products[0];
+ const updateProductInfo = (items, tempId, productData) => {
+ for (let i = 0; i < items.length; i++) {
+ const item = items[i];
+ if (item.tempId === tempId) {
+ item.productName = productData.productName;
+ item.model = productData.model;
+ item.productModelId = productData.id;
+ item.unit = productData.unit || "";
+ return true;
+ }
+ if (item.children && item.children.length > 0) {
+ if (updateProductInfo(item.children, tempId, productData)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ };
+
+ if (bomTableData.value.length > 0) {
+ updateProductInfo(
+ bomTableData.value[0].bomList,
+ bomDataValue.value.currentRowName,
+ product
+ );
+ // 鐢变簬bomDataValue.value.dataList鍜宐omTableData.value[0].bomList鎸囧悜鍚屼竴涓暟缁勶紝涓嶉渶瑕侀噸澶嶆洿鏂�
+ }
+ bomDataValue.value.showProductDialog = false;
+ }
+ };
+
+ // 淇濆瓨BOM鏇存敼
+ const saveBomChanges = () => {
+ // 鏍¢獙BOM鏁版嵁
+ const validateBomData = items => {
+ for (let i = 0; i < items.length; i++) {
+ const item = items[i];
+ // 鏍¢獙浜у搧鏄惁蹇呭~
+ if (!item.productModelId) {
+ ElMessage.error("璇烽�夋嫨浜у搧");
+ return false;
+ }
+ // 鏍¢獙鍗曚綅浜у嚭鎵�闇�鏁伴噺鏄惁蹇呭~
+ if (
+ item.unitQuantity === undefined ||
+ item.unitQuantity === null ||
+ item.unitQuantity === 0
+ ) {
+ ElMessage.error("璇峰~鍐欏崟浣嶄骇鍑烘墍闇�鏁伴噺");
+ return false;
+ }
+ // 閫掑綊鏍¢獙瀛愰」
+ if (item.children && item.children.length > 0) {
+ if (!validateBomData(item.children)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ };
+
+ // 鎵ц鏍¢獙
+ if (bomTableData.value.length > 0) {
+ if (!validateBomData(bomTableData.value[0].bomList)) {
+ return;
+ }
+ }
+
+ // 璋冪敤鏂扮殑淇濆瓨鎺ュ彛
+ // 鍑嗗淇濆瓨鏁版嵁锛岀‘淇濇牸寮忔纭�
+ // 閫掑綊澶勭悊BOM椤瑰強鍏跺瓙椤�
+ const processBomItem = (item, parentId = null, parentTempId = null) => {
+ const cleanItem = {
+ id: item.id || null,
+ orderId: Number(orderId.value) || null,
+ parentId: parentId,
+ parentTempId: parentTempId || null,
+ productModelId: item.productModelId || null,
+ processId: item.processId || null,
+ unitQuantity: item.unitQuantity || 0,
+ demandedQuantity: item.demandedQuantity || null,
+ unit: item.unit || "",
+ tempId: item.tempId || new Date().getTime(),
+ tenantId: item.tenantId || null,
+ bomId: Number(route.query.bomId) || null,
+ children: [],
+ };
+
+ // 閫掑綊澶勭悊瀛愰」
+ if (item.children && item.children.length > 0) {
+ cleanItem.children = item.children.map(child =>
+ processBomItem(child, item.id, item.tempId || null)
+ );
+ }
+
+ return cleanItem;
+ };
+
+ const saveData = bomTableData.value[0].bomList.map(item =>
+ processBomItem(item, item.parentId, item.parentTempId || null)
+ );
+ const formData = {
+ orderId: Number(orderId.value) || null,
+ children: saveData,
+ };
+
+ add2(formData)
+ .then(res => {
+ if (res.code === 200) {
+ ElMessage.success("BOM淇濆瓨鎴愬姛");
+ bomDataValue.value.isEdit = false;
+ // 閲嶆柊鍔犺浇鏁版嵁浠ヨ幏鍙栨渶鏂扮姸鎬�
+ getRouteInfo();
+ } else {
+ ElMessage.error("BOM淇濆瓨澶辫触锛�" + (res.msg || "鏈煡閿欒"));
+ }
+ })
+ .catch(err => {
+ console.error("淇濆瓨BOM鏁版嵁澶辫触锛�", err);
+ ElMessage.error("BOM淇濆瓨澶辫触锛氱綉缁滈敊璇�");
+ });
+ };
+
+ // 鍙栨秷BOM缂栬緫
+ const cancelBomEdit = () => {
+ bomDataValue.value.isEdit = false;
+ getRouteInfo();
};
// 鍒濆鍖栨嫋鎷芥帓搴�
@@ -1113,3 +1514,11 @@
word-break: break-all;
}
</style>
+<style scoped>
+ .hover-effect:hover {
+ border-color: #409eff;
+ background-color: #ecf5ff;
+ transform: translateY(-2px);
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+ }
+</style>
\ No newline at end of file
--
Gitblit v1.9.3