From 93d2a0bd19ffb1d86c6807a4d93d0eff580c14f1 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期六, 25 四月 2026 16:39:26 +0800
Subject: [PATCH] 生产计划和生产订单一些修改
---
src/views/productionManagement/processRoute/processRouteItem/index.vue | 1130 ++++++++++++++++++++++++++++++++---------------------------
1 files changed, 617 insertions(+), 513 deletions(-)
diff --git a/src/views/productionManagement/processRoute/processRouteItem/index.vue b/src/views/productionManagement/processRoute/processRouteItem/index.vue
index be7138d..44fef19 100644
--- a/src/views/productionManagement/processRoute/processRouteItem/index.vue
+++ b/src/views/productionManagement/processRoute/processRouteItem/index.vue
@@ -77,10 +77,10 @@
width="60"
type="index" />
<el-table-column label="宸ュ簭鍚嶇О"
- prop="processId"
+ prop="technologyOperationId"
width="200">
<template #default="scope">
- {{ getProcessName(scope.row.processId) || '-' }}
+ {{ scope.row.technologyOperationName || scope.row.operationName || '-' }}
</template>
</el-table-column>
<el-table-column label="鍙傛暟鍒楄〃"
@@ -106,6 +106,13 @@
width="100">
<template #default="scope">
{{scope.row.isQuality ? "鏄�" : "鍚�"}}
+ </template>
+ </el-table-column>
+ <el-table-column label="鏄惁鐢熶骇"
+ prop="isProduction"
+ width="100">
+ <template #default="scope">
+ {{scope.row.isProduction ? "鏄�" : "鍚�"}}
</template>
</el-table-column>
<el-table-column label="鎿嶄綔"
@@ -151,7 +158,7 @@
<!-- 搴忓彿鍦嗗湀 -->
<div class="card-header">
<div class="card-number">{{ index + 1 }}</div>
- <div class="card-process-name">{{ getProcessName(item.processId) || '-' }}</div>
+ <div class="card-process-name">{{ item.technologyOperationName || item.operationName || '-' }}</div>
</div>
<!-- 浜у搧淇℃伅 -->
<div class="card-content">
@@ -166,6 +173,10 @@
<el-tag type="primary"
class="product-tag"
v-if="item.isQuality">璐ㄦ</el-tag>
+ <el-tag type="primary"
+ class="product-tag"
+ :style="item.isQuality?'margin-left:8px':''"
+ v-if="item.isProduction">鐢熶骇</el-tag>
</div>
<div v-else
class="product-info empty">鏆傛棤浜у搧淇℃伅</div>
@@ -191,168 +202,163 @@
</div>
</div>
</template>
- <div class="section-BOM">
- <div class="section-header">
- <div class="section-title">BOM</div>
- <div class="section-actions">
- <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琛ㄦ牸 -->
- <el-table :data="bomTableData"
- border
- :preserve-expanded-content="false"
- :default-expand-all="true"
- style="width: 100%">
- <el-table-column type="expand">
- <template #default="props">
- <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"
- :rules="[{ required: true, message: '璇烽�夋嫨瑙勬牸', trigger: ['blur','change'] }]"
- style="margin: 0">
- <el-select v-model="row.model"
- placeholder="璇烽�夋嫨瑙勬牸"
- clearable
- :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"
- :rules="[{ required: true, message: '璇烽�夋嫨娑堣�楀伐搴�', trigger: 'change' }]"
- style="margin: 0">
- <el-select v-model="row.processId"
- placeholder="璇烽�夋嫨"
- filterable
- clearable
- :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"
- :rules="[{ required: true, message: '璇疯緭鍏ュ崟浣嶄骇鍑烘墍闇�鏁伴噺', trigger: ['blur','change'] }]"
- style="margin: 0">
- <el-input-number v-model="row.unitQuantity"
- :min="0"
- :precision="2"
- :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 v-if="pageType === 'order'"
- prop="demandedQuantity"
- label="闇�姹傛�婚噺">
- <template #default="{ row }">
- <el-form-item v-if="bomDataValue.isEdit"
- :rules="[{ required: true, message: '璇疯緭鍏ラ渶姹傛�婚噺', trigger: ['blur','change'] }]"
- style="margin: 0">
- <el-input-number v-model="row.demandedQuantity"
- :min="0"
- :precision="2"
- :step="1"
- controls-position="right"
- style="width: 100%"
- :disabled="!bomDataValue.isEdit" />
- </el-form-item>
- <span v-else>{{ row.demandedQuantity }}</span>
- </template>
- </el-table-column>
- <el-table-column prop="unit"
- label="鍗曚綅">
- <template #default="{ row }">
- <el-form-item v-if="bomDataValue.isEdit"
- :rules="[{ required: true, message: '璇疯緭鍏ュ崟浣�', trigger: ['blur','change'] }]"
- 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"
- 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="productName" />
- <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>
+ <!-- bom妯″潡 -->
+ <div class="section-header"
+ style="margin-top: 20px;">
+ <div class="section-title">BOM 缁撴瀯</div>
+ <!-- <div class="section-actions"
+ v-if="pageType === 'order'">
+ <el-button v-if="!bomDataValue.isEdit"
+ type="primary"
+ @click="bomDataValue.isEdit = true">
+ 缂栬緫
+ </el-button>
+ <el-button v-if="bomDataValue.isEdit"
+ @click="cancelEditBom">
+ 鍙栨秷
+ </el-button>
+ <el-button v-if="bomDataValue.isEdit"
+ type="primary"
+ @click="handleSaveBom"
+ :loading="bomDataValue.loading">
+ 淇濆瓨BOM
+ </el-button>
+ </div> -->
</div>
+ <el-table :data="bomTableData"
+ border
+ :preserve-expanded-content="false"
+ :default-expand-all="true"
+ style="width: 100%">
+ <el-table-column type="expand">
+ <template #default>
+ <el-form ref="bomFormRef"
+ :model="bomDataValue">
+ <el-table :data="bomDataValue.dataList"
+ 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="pageType === 'order' && bomDataValue.isEdit"
+ :rules="[{ required: true, message: '璇烽�夋嫨瑙勬牸', trigger: ['blur','change'] }]"
+ style="margin: 0">
+ <el-select v-model="row.model"
+ placeholder="璇烽�夋嫨瑙勬牸"
+ clearable
+ :disabled="!bomDataValue.isEdit || bomDataValue.dataList.some(item => (item).tempId === row.tempId)"
+ style="width: 100%"
+ @visible-change="(v) => { if (v) openBomDialog(row.tempId) }">
+ <el-option v-if="row.model"
+ :label="row.model"
+ :value="row.model" />
+ </el-select>
+ </el-form-item>
+ </template>
+ </el-table-column>
+ <el-table-column prop="processName"
+ label="娑堣�楀伐搴�">
+ <template #default="{ row }">
+ <el-form-item v-if="pageType === 'order' && bomDataValue.isEdit"
+ :rules="bomDataValue.dataList.some(item => (item).tempId === row.tempId) ? [] : [{ required: true, message: '璇烽�夋嫨娑堣�楀伐搴�', trigger: 'change' }]"
+ style="margin: 0">
+ <el-select v-model="row.processId"
+ placeholder="璇烽�夋嫨"
+ filterable
+ clearable
+ style="width: 100%"
+ @change="value => handleBomProcessChange(row, value)"
+ :disabled="!bomDataValue.isEdit || bomDataValue.dataList.some(item => (item).tempId === row.tempId)">
+ <el-option v-for="item in bomDataValue.processOptions"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id" />
+ </el-select>
+ </el-form-item>
+ </template>
+ </el-table-column>
+ <el-table-column prop="unitQuantity"
+ label="鍗曚綅浜у嚭鎵�闇�鏁伴噺">
+ <template #default="{ row }">
+ <el-form-item v-if="pageType === 'order' && bomDataValue.isEdit"
+ :rules="[{ required: true, message: '璇疯緭鍏ュ崟浣嶄骇鍑烘墍闇�鏁伴噺', trigger: ['blur','change'] }]"
+ style="margin: 0">
+ <el-input-number v-model="row.unitQuantity"
+ :min="0"
+ :precision="2"
+ :step="1"
+ controls-position="right"
+ style="width: 100%"
+ :disabled="!bomDataValue.isEdit || bomDataValue.dataList.some(item => (item).tempId === row.tempId)" />
+ </el-form-item>
+ </template>
+ </el-table-column>
+ <el-table-column v-if="pageType === 'order'"
+ prop="demandedQuantity"
+ label="闇�姹傛�婚噺">
+ <template #default="{ row }">
+ <el-form-item v-if="pageType === 'order' && bomDataValue.isEdit"
+ :rules="[{ required: true, message: '璇疯緭鍏ラ渶姹傛�婚噺', trigger: ['blur','change'] }]"
+ style="margin: 0">
+ <el-input-number v-model="row.demandedQuantity"
+ :min="0"
+ :precision="2"
+ :step="1"
+ controls-position="right"
+ style="width: 100%"
+ :disabled="!bomDataValue.isEdit || bomDataValue.dataList.some(item => (item).tempId === row.tempId)" />
+ </el-form-item>
+ </template>
+ </el-table-column>
+ <el-table-column prop="unit"
+ label="鍗曚綅">
+ <template #default="{ row }">
+ <el-form-item v-if="pageType === 'order' && bomDataValue.isEdit"
+ :rules="[{ required: true, message: '璇疯緭鍏ュ崟浣�', trigger: ['blur','change'] }]"
+ style="margin: 0">
+ <el-input v-model="row.unit"
+ placeholder="璇疯緭鍏ュ崟浣�"
+ clearable
+ :disabled="!bomDataValue.isEdit || bomDataValue.dataList.some(item => (item).tempId === row.tempId)" />
+ </el-form-item>
+ </template>
+ </el-table-column>
+ <el-table-column label="鎿嶄綔"
+ fixed="right"
+ width="200"
+ v-if="pageType === 'order' && bomDataValue.isEdit">
+ <template #default="{ row }">
+ <el-button v-if="bomDataValue.isEdit && !bomDataValue.dataList.some(item => (item).tempId === row.tempId)"
+ type="danger"
+ text
+ @click="removeBomItem(row.tempId)">鍒犻櫎
+ </el-button>
+ <el-button v-if="bomDataValue.isEdit"
+ type="primary"
+ text
+ @click="addBomItem(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="productName" />
+ <el-table-column label="瑙勬牸鍨嬪彿"
+ prop="model" />
+ </el-table>
+ <ProductSelectDialog v-if="bomDataValue.showProductDialog"
+ v-model="bomDataValue.showProductDialog"
+ :single="true"
+ @confirm="handleBomProduct" />
<!-- 鏂板/缂栬緫寮圭獥 -->
<el-dialog v-model="dialogVisible"
:title="operationType === 'add' ? '鏂板宸ヨ壓璺嚎椤圭洰' : '缂栬緫宸ヨ壓璺嚎椤圭洰'"
@@ -363,10 +369,12 @@
:rules="rules"
label-width="120px">
<el-form-item label="宸ュ簭"
- prop="processId">
- <el-select v-model="form.processId"
+ v-if="operationType === 'add' || pageType === 'route'"
+ prop="technologyOperationId">
+ <el-select v-model="form.technologyOperationId"
placeholder="璇烽�夋嫨宸ュ簭"
clearable
+ @change="processChange"
style="width: 100%">
<el-option v-for="process in processOptions"
:key="process.id"
@@ -374,27 +382,47 @@
:value="process.id" />
</el-select>
</el-form-item>
+ <el-form-item label="宸ュ簭"
+ v-else>
+ <span>{{ getProcessName(form.technologyOperationId) }}</span>
+ </el-form-item>
<el-form-item label="浜у搧鍚嶇О"
+ v-if="operationType === 'add' || pageType === 'route'"
prop="productModelId">
<el-button type="primary"
@click="showProductSelectDialog = true">
- {{ form.productName && form.model
- ? `${form.productName} - ${form.model}`
+ {{ form.productName
+ ? (form.model ? `${form.productName} - ${form.model}` : form.productName)
: '閫夋嫨浜у搧' }}
</el-button>
</el-form-item>
+ <el-form-item label="浜у搧鍚嶇О"
+ v-else>
+ <span>{{ form.productName }}{{ form.model ? ' - ' + form.model : '' }}</span>
+ </el-form-item>
<el-form-item label="鍗曚綅"
+ v-if="operationType === 'add' || pageType === 'route'"
prop="unit">
<el-input v-model="form.unit"
:placeholder="form.productModelId ? '鏍规嵁閫夋嫨鐨勪骇鍝佽嚜鍔ㄥ甫鍑�' : '璇峰厛閫夋嫨浜у搧'"
clearable
:disabled="true" />
</el-form-item>
+ <el-form-item label="鍗曚綅"
+ v-else>
+ <span>{{ form.unit }}</span>
+ </el-form-item>
<el-form-item label="鏄惁璐ㄦ"
prop="isQuality">
<el-switch v-model="form.isQuality"
:active-value="true"
- inactive-value="false" />
+ :inactive-value="false" />
+ </el-form-item>
+ <el-form-item label="鏄惁鐢熶骇"
+ prop="isProduction">
+ <el-switch v-model="form.isProduction"
+ :active-value="true"
+ :inactive-value="false" />
</el-form-item>
</el-form>
<template #footer>
@@ -408,19 +436,16 @@
<ProductSelectDialog v-model="showProductSelectDialog"
@confirm="handleProductSelect"
single />
- <!-- BOM浜у搧閫夋嫨瀵硅瘽妗� -->
- <ProductSelectDialog v-model="bomDataValue.showProductDialog"
- @confirm="handleBomProductSelect"
- single />
<!-- 鍙傛暟鍒楄〃瀵硅瘽妗� -->
<!-- :editable="!routeInfo.status" -->
<ProcessParamListDialog v-model="showParamListDialog"
- :title="`${currentProcess ? (currentProcess.processName || getProcessName(currentProcess.processId)) : ''} - 鍙傛暟鍒楄〃`"
+ :title="`${currentProcess ? (currentProcess.processName || currentProcess.technologyOperationName || currentProcess.operationName) : ''} - 鍙傛暟鍒楄〃`"
:route-id="routeId"
:order-id="orderId"
:process="currentProcess"
:page-type="pageType"
:param-list="paramList"
+ @getsyncProcessParamItem="getsyncProcessParamItem"
@refresh="refreshParamList" />
</div>
</template>
@@ -439,9 +464,14 @@
import {
findProcessRouteItemList,
addOrUpdateProcessRouteItem,
+ addOrUpdateProcessRouteItem1,
sortProcessRouteItem,
batchDeleteProcessRouteItem,
getProcessParamList,
+ } from "@/api/productionManagement/processRouteItem.js";
+ import {
+ syncProcessParamItem,
+ syncProcessParamItemOrder,
} from "@/api/productionManagement/processRouteItem.js";
import {
findProductProcessRouteItemList,
@@ -452,11 +482,13 @@
sortRouteItem,
} from "@/api/productionManagement/productProcessRoute.js";
import { processList } from "@/api/productionManagement/productionProcess.js";
+ import { listProcessBom } from "@/api/productionManagement/productionOrder.js";
import {
- queryList2,
queryList,
- add2,
+ queryList2,
+ addBomDetail,
} from "@/api/productionManagement/productStructure.js";
+
import { useRoute } from "vue-router";
import { ElMessageBox, ElMessage } from "element-plus";
import Sortable from "sortablejs";
@@ -473,6 +505,7 @@
const dialogVisible = ref(false);
const operationType = ref("add"); // add | edit
const formRef = ref(null);
+ const bomFormRef = ref(null);
const submitLoading = ref(false);
const cardsContainer = ref(null);
const tableRef = ref(null);
@@ -490,15 +523,6 @@
const showParamListDialog = ref(false);
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;
@@ -514,25 +538,66 @@
const form = ref({
id: undefined,
routeId: routeId.value,
- processId: undefined,
+ technologyOperationId: undefined,
productModelId: undefined,
productName: "",
model: "",
unit: "",
isQuality: false,
+ isProduction: false,
});
const rules = {
- processId: [{ required: true, message: "璇烽�夋嫨宸ュ簭", trigger: "change" }],
+ technologyOperationId: [
+ { required: true, message: "璇烽�夋嫨宸ュ簭", trigger: "change" },
+ ],
productModelId: [
{ required: true, message: "璇烽�夋嫨浜у搧", trigger: "change" },
],
};
+ const getsyncProcessParamItem = () => {
+ ElMessageBox.confirm("鏄惁瑕嗙洊褰撳墠宸ュ簭宸插瓨鍦ㄥ弬鏁帮紵", "鎻愮ず", {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ if (pageType.value === "order") {
+ syncProcessParamItemOrder({
+ replaceExisting: true,
+ technologyRoutingOperationId: currentProcess.value.id,
+ }).then(res => {
+ if (res.code === 200) {
+ ElMessage.success("鍚屾鎴愬姛");
+ refreshParamList();
+ } else {
+ ElMessage.error(res.msg || "鍚屾澶辫触");
+ }
+ });
+ } else {
+ syncProcessParamItem({
+ replaceExisting: true,
+ technologyRoutingOperationId: currentProcess.value.id,
+ }).then(res => {
+ if (res.code === 200) {
+ ElMessage.success("鍚屾鎴愬姛");
+ refreshParamList();
+ } else {
+ ElMessage.error(res.msg || "鍚屾澶辫触");
+ }
+ });
+ }
+ })
+ .catch(() => {});
+ };
+
// 鏍规嵁宸ュ簭ID鑾峰彇宸ュ簭鍚嶇О
- const getProcessName = processId => {
- if (!processId) return "";
- const process = processOptions.value.find(p => p.id === processId);
+ const getProcessName = technologyOperationId => {
+ if (!technologyOperationId) return "";
+ const process = processOptions.value.find(
+ p => p.id === technologyOperationId
+ );
return process ? process.name : "";
};
@@ -562,9 +627,10 @@
// 鑾峰彇宸ュ簭鍒楄〃
const getProcessList = () => {
- processList({})
+ processList({ size: -1, current: -1 })
.then(res => {
- processOptions.value = res.data || [];
+ processOptions.value = res.data.records || [];
+ bomDataValue.value.processOptions = processOptions.value;
})
.catch(err => {
console.error("鑾峰彇宸ュ簭澶辫触锛�", err);
@@ -578,76 +644,13 @@
productName: route.query.productName || "",
model: route.query.model || "",
bomNo: route.query.bomNo || "",
+ bomId: route.query.bomId || "",
description: route.query.description || "",
status: !(route.query.status == 1 || route.query.status === "false"),
};
- 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,
- 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);
- });
- } 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);
- });
- }
+ bomTableData.value[0].productName = routeInfo.value.productName;
+ bomTableData.value[0].model = routeInfo.value.model;
+ bomTableData.value[0].bomNo = routeInfo.value.bomNo;
};
// 鏂板
@@ -663,12 +666,13 @@
form.value = {
id: row.id,
routeId: routeId.value,
- processId: row.processId,
+ technologyOperationId: row.technologyOperationId,
productModelId: row.productModelId,
productName: row.productName || "",
model: row.model || "",
unit: row.unit || "",
isQuality: row.isQuality,
+ isProduction: row.isProduction,
};
dialogVisible.value = true;
};
@@ -701,15 +705,20 @@
// 浜у搧閫夋嫨
const handleProductSelect = products => {
+ console.log(products, "===products===");
if (products && products.length > 0) {
const product = products[0];
- form.value.productModelId = product.id;
- form.value.productName = product.productName;
- form.value.model = product.model;
- form.value.unit = product.unit || "";
+ console.log(product, "product");
+ form.value = {
+ ...form.value,
+ productModelId: product.id,
+ productName: product.productName,
+ model: product.model,
+ unit: product.unit || "",
+ };
showProductSelectDialog.value = false;
// 瑙﹀彂琛ㄥ崟楠岃瘉
- formRef.value?.validateField("productModelId");
+ // formRef.value?.validateField("productModelId");
}
};
@@ -727,18 +736,22 @@
const addPromise = isOrderPage
? addRouteItem({
- productOrderId: orderId.value,
- productRouteId: routeId.value,
- processId: form.value.processId,
+ productionOrderId: Number(orderId.value),
+ orderRoutingId: Number(routeId.value),
+ technologyOperationId: form.value.technologyOperationId,
+ technologyRoutingId: Number(routeId.value),
+ operationName: getProcessName(form.value.technologyOperationId),
productModelId: form.value.productModelId,
isQuality: form.value.isQuality,
+ isProduction: form.value.isProduction,
dragSort,
})
: addOrUpdateProcessRouteItem({
- routeId: routeId.value,
- processId: form.value.processId,
+ technologyRoutingId: Number(routeId.value),
+ technologyOperationId: form.value.technologyOperationId,
productModelId: form.value.productModelId,
isQuality: form.value.isQuality,
+ isProduction: form.value.isProduction,
dragSort,
});
@@ -761,16 +774,19 @@
const updatePromise = isOrderPage
? addOrUpdateProductProcessRouteItem({
id: form.value.id,
- processId: form.value.processId,
+ technologyOperationId: form.value.technologyOperationId,
+ operationName: getProcessName(form.value.technologyOperationId),
productModelId: form.value.productModelId,
isQuality: form.value.isQuality,
+ isProduction: form.value.isProduction,
})
- : addOrUpdateProcessRouteItem({
- routeId: routeId.value,
- processId: form.value.processId,
+ : addOrUpdateProcessRouteItem1({
+ technologyRoutingId: Number(routeId.value),
+ technologyOperationId: form.value.technologyOperationId,
productModelId: form.value.productModelId,
id: form.value.id,
isQuality: form.value.isQuality,
+ isProduction: form.value.isProduction,
});
updatePromise
@@ -795,11 +811,13 @@
form.value = {
id: undefined,
routeId: routeId.value,
- processId: undefined,
+ technologyOperationId: undefined,
productModelId: undefined,
productName: "",
model: "",
unit: "",
+ isQuality: false,
+ isProduction: false,
};
formRef.value?.resetFields();
};
@@ -814,8 +832,8 @@
const handleViewParams = row => {
currentProcess.value = row;
const query = {
- routeItemId: row.id,
- orderId: orderId.value,
+ technologyRoutingOperationId: row.id,
+ productionOrderId: orderId.value,
};
const apiPromise =
@@ -839,231 +857,6 @@
if (currentProcess.value) {
handleViewParams(currentProcess.value);
}
- };
-
- // 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,
- demandedQuantity: 0,
- unit: "",
- children: [],
- tempId: new Date().getTime(),
- };
- bomTableData.value[0].bomList.push(newItem);
- }
- };
-
- // 娣诲姞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,
- demandedQuantity: 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);
- }
- };
-
- // 鍒犻櫎BOM椤�
- const removeBomItem = tempId => {
- 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);
- }
- };
-
- // 鎵撳紑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.showProductDialog = false;
- }
- };
-
- // 淇濆瓨BOM鏇存敼
- const saveBomChanges = () => {
- const validateBomData = (items, isTopLevel = false) => {
- for (let i = 0; i < items.length; i++) {
- const item = items[i];
- if (!item.productModelId) {
- ElMessage.error("璇烽�夋嫨浜у搧");
- return false;
- }
- if (!isTopLevel && !item.processId) {
- ElMessage.error("璇烽�夋嫨娑堣�楀伐搴�");
- return false;
- }
- if (
- item.unitQuantity === undefined ||
- item.unitQuantity === null ||
- item.unitQuantity === 0
- ) {
- ElMessage.error("璇峰~鍐欏崟浣嶄骇鍑烘墍闇�鏁伴噺");
- return false;
- }
- if (
- pageType.value === "order" &&
- (item.demandedQuantity === undefined ||
- item.demandedQuantity === null ||
- item.demandedQuantity === 0)
- ) {
- ElMessage.error("璇疯緭鍏ラ渶姹傛�婚噺");
- return false;
- }
- if (item.children && item.children.length > 0) {
- if (!validateBomData(item.children, false)) {
- return false;
- }
- }
- }
- return true;
- };
-
- if (bomTableData.value.length > 0) {
- if (!validateBomData(bomTableData.value[0].bomList, true)) {
- return;
- }
- }
-
- 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 || 0,
- unit: item.unit || "",
- tempId: item.tempId || new Date().getTime(),
- 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)
- );
- }
-
- return cleanItem;
- };
-
- const saveData = {
- orderId: Number(orderId.value),
- bomId: Number(route.query.bomId),
- children: bomTableData.value[0].bomList.map(item => processBomItem(item)),
- };
-
- const savePromise =
- pageType.value === "order" ? add2(saveData) : add(saveData);
-
- savePromise
- .then(() => {
- proxy?.$modal?.msgSuccess("淇濆瓨鎴愬姛");
- bomDataValue.value.isEdit = false;
- getRouteInfo();
- })
- .catch(err => {
- console.error("淇濆瓨BOM澶辫触锛�", err);
- proxy?.$modal?.msgError("淇濆瓨澶辫触");
- });
};
// 鍒濆鍖栨嫋鎷芥帓搴�
@@ -1201,10 +994,332 @@
}
};
+ // BOM鐩稿叧鐘舵�佸拰鏂规硶
+ const bomTableData = ref([
+ {
+ productName: "",
+ model: "",
+ bomNo: "",
+ },
+ ]);
+
+ const bomDataValue = ref({
+ dataList: [],
+ processOptions: [],
+ showProductDialog: false,
+ currentRowName: null,
+ loading: false,
+ isEdit: false,
+ });
+
+ const syncProcessOperationFields = item => {
+ const processId =
+ item.processId ?? item.operationId ?? item.technologyOperationId ?? "";
+ if (!processId) {
+ item.processId = "";
+ return;
+ }
+ const option = bomDataValue.value.processOptions.find(
+ p => p.id === processId
+ );
+ const processName =
+ option?.name || item.processName || item.operationName || "";
+
+ item.processId = processId;
+ if (pageType.value === "order") {
+ item.technologyOperationId = processId;
+ } else {
+ item.operationId = processId;
+ }
+ item.processName = processName;
+ item.operationName = processName;
+ };
+
+ const normalizeTreeData = items => {
+ items.forEach(item => {
+ item.tempId = item.tempId || item.id || `${Date.now()}_${Math.random()}`;
+ syncProcessOperationFields(item);
+ if (Array.isArray(item.children) && item.children.length > 0) {
+ normalizeTreeData(item.children);
+ }
+ });
+ };
+ const processChange = value => {
+ processOptions.value.forEach(item => {
+ if (item.id == value) {
+ form.value.isQuality = item.isQuality;
+ form.value.isProduction = item.isProduction;
+ }
+ });
+ };
+
+ const handleBomProcessChange = (row, value) => {
+ row.processId = value || "";
+ syncProcessOperationFields(row);
+ };
+
+ const openBomDialog = tempId => {
+ bomDataValue.value.currentRowName = tempId;
+ bomDataValue.value.showProductDialog = true;
+ };
+
+ const fetchBomData = async () => {
+ try {
+ const isOrderPage = pageType.value === "order";
+ const { data } = await (isOrderPage ? queryList2 : queryList)(
+ routeInfo.value.bomId
+ );
+ bomDataValue.value.dataList = data || [];
+ normalizeTreeData(bomDataValue.value.dataList);
+ } catch (err) {
+ console.error("鑾峰彇BOM鏁版嵁澶辫触锛�", err);
+ }
+ };
+
+ const childItem = (item, tempId, productData) => {
+ 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) {
+ for (let child of item.children) {
+ if (childItem(child, tempId, productData)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ };
+
+ const handleBomProduct = row => {
+ if (!Array.isArray(row) || row.length === 0) {
+ ElMessage.warning("璇烽�夋嫨涓�涓骇鍝�");
+ return;
+ }
+ const productData = row[row.length - 1];
+
+ const isTopLevel = bomDataValue.value.dataList.some(
+ item => item.tempId === bomDataValue.value.currentRowName
+ );
+ if (isTopLevel) {
+ if (
+ productData.productName === bomTableData.value[0].productName &&
+ productData.model === bomTableData.value[0].model
+ ) {
+ const hasOther = bomDataValue.value.dataList.some(
+ item =>
+ item.tempId !== bomDataValue.value.currentRowName &&
+ item.productName === bomTableData.value[0].productName &&
+ item.model === bomTableData.value[0].model
+ );
+ if (hasOther) {
+ ElMessage.warning("鏈�澶栧眰鍜屽綋鍓嶄骇鍝佷竴鏍风殑涓�绾у彧鑳芥湁涓�涓�");
+ return;
+ }
+ }
+ }
+ bomDataValue.value.dataList.forEach(item => {
+ if (item.tempId === bomDataValue.value.currentRowName) {
+ item.productName = productData.productName;
+ item.model = productData.model;
+ item.productModelId = productData.id;
+ item.unit = productData.unit || "";
+ return;
+ }
+ childItem(item, bomDataValue.value.currentRowName, productData);
+ });
+ bomDataValue.value.showProductDialog = false;
+ };
+
+ const removeBomItem = tempId => {
+ const topIndex = bomDataValue.value.dataList.findIndex(
+ item => item.tempId === tempId
+ );
+ if (topIndex !== -1) {
+ bomDataValue.value.dataList.splice(topIndex, 1);
+ return;
+ }
+
+ const delchildItem = (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 (delchildItem(item.children, tempId)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ };
+
+ bomDataValue.value.dataList.forEach(item => {
+ if (item.children && item.children.length > 0) {
+ delchildItem(item.children, tempId);
+ }
+ });
+ };
+
+ const addchildItem = (item, tempId) => {
+ 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: "",
+ [pageType.value === "order" ? "technologyOperationId" : "operationId"]:
+ "",
+ operationName: "",
+ unitQuantity: 1,
+ demandedQuantity: 0,
+ children: [],
+ unit: "",
+ tempId: new Date().getTime(),
+ });
+ return true;
+ }
+ if (item.children && item.children.length > 0) {
+ for (let child of item.children) {
+ if (addchildItem(child, tempId)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ };
+
+ const addBomItem = tempId => {
+ bomDataValue.value.dataList.forEach(item => {
+ 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: "",
+ [pageType.value === "order" ? "technologyOperationId" : "operationId"]:
+ "",
+ operationName: "",
+ unitQuantity: 1,
+ demandedQuantity: 0,
+ unit: "",
+ children: [],
+ tempId: new Date().getTime(),
+ });
+ return;
+ }
+ addchildItem(item, tempId);
+ });
+ };
+
+ const validateAllBom = () => {
+ let isValid = true;
+ const isOrderPage = pageType.value === "order";
+
+ const validateItem = (item, isTopLevel = false) => {
+ if (!item.model) {
+ ElMessage.error("璇烽�夋嫨瑙勬牸");
+ isValid = false;
+ return;
+ }
+ if (!isTopLevel && !item.processId) {
+ ElMessage.error("璇烽�夋嫨娑堣�楀伐搴�");
+ isValid = false;
+ return;
+ }
+ if (!item.unitQuantity) {
+ ElMessage.error("璇疯緭鍏ュ崟浣嶄骇鍑烘墍闇�鏁伴噺");
+ isValid = false;
+ return;
+ }
+ if (isOrderPage && !item.demandedQuantity) {
+ ElMessage.error("璇疯緭鍏ラ渶姹傛�婚噺");
+ isValid = false;
+ return;
+ }
+
+ if (item.children && item.children.length > 0) {
+ item.children.forEach(child => {
+ validateItem(child, false);
+ });
+ }
+ };
+
+ bomDataValue.value.dataList.forEach(item => {
+ validateItem(item, true);
+ });
+
+ return isValid;
+ };
+
+ const buildSubmitTree = items => {
+ return items.map(item => {
+ const current = { ...item };
+ syncProcessOperationFields(current);
+ current.children = Array.isArray(current.children)
+ ? buildSubmitTree(current.children)
+ : [];
+ return current;
+ });
+ };
+
+ const cancelEditBom = () => {
+ bomDataValue.value.isEdit = false;
+ fetchBomData();
+ };
+
+ const handleSaveBom = () => {
+ bomDataValue.value.loading = true;
+ console.log(bomDataValue.value.dataList, "bomDataValue.value.dataList");
+
+ normalizeTreeData(bomDataValue.value.dataList);
+
+ const valid = validateAllBom();
+ if (valid) {
+ addBomDetail({
+ bomId: Number(routeInfo.value.bomId),
+ children: buildSubmitTree(bomDataValue.value.dataList || []),
+ })
+ .then(() => {
+ ElMessage.success("BOM淇濆瓨鎴愬姛");
+ bomDataValue.value.isEdit = false;
+ fetchBomData();
+ })
+ .catch(() => {
+ ElMessage.error("BOM淇濆瓨澶辫触");
+ })
+ .finally(() => {
+ bomDataValue.value.loading = false;
+ });
+ } else {
+ bomDataValue.value.loading = false;
+ }
+ };
+
onMounted(() => {
getRouteInfo();
getList();
getProcessList();
+ fetchBomData();
});
onUnmounted(() => {
@@ -1470,16 +1585,5 @@
font-weight: 500;
line-height: 1.5;
word-break: break-all;
- }
-
- .section-BOM {
- margin-top: 20px;
- }
-
- .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>
--
Gitblit v1.9.3