From 1c15c3ddecdb0284a47eb763cbfcf6978fcb186b Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期二, 28 四月 2026 10:23:53 +0800
Subject: [PATCH] Merge branch 'dev_NEW_pro' of http://114.132.189.42:9002/r/product-inventory-management into dev_NEW_pro
---
src/views/fileManagement/document/index.vue | 8
src/views/productionManagement/productionOrder/components/MaterialDetailDialog.vue | 338 +++++++-----
src/views/inventoryManagement/stockManagement/New.vue | 350 ++++++------
src/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue | 183 ++++--
src/views/productionManagement/workOrderManagement/components/MaterialDialog.vue | 502 ++++++++++--------
src/views/fileManagement/return/index.vue | 33
src/views/fileManagement/borrow/index.vue | 33
src/views/productionManagement/productionOrder/index.vue | 37
src/api/productionManagement/productionOrder.js | 40 +
9 files changed, 866 insertions(+), 658 deletions(-)
diff --git a/src/api/productionManagement/productionOrder.js b/src/api/productionManagement/productionOrder.js
index 9f7ce58..b87adbb 100644
--- a/src/api/productionManagement/productionOrder.js
+++ b/src/api/productionManagement/productionOrder.js
@@ -72,23 +72,47 @@
}
// 鐢熶骇璁㈠崟-淇濆瓨棰嗘枡鍙拌处
+// export function saveMaterialPickingLedger(data) {
+// return request({
+// url: "/productOrderMaterial/save",
+// method: "post",
+// data,
+// });
+// }
export function saveMaterialPickingLedger(data) {
return request({
- url: "/productOrderMaterial/save",
+ url: "/productionOrderPick/savePick",
method: "post",
data,
});
}
-
-// 鐢熶骇璁㈠崟-棰嗘枡璇︽儏鍒楄〃
-export function listMaterialPickingDetail(query) {
+export function updateMaterialPickingLedger(data) {
return request({
- url: "/productOrderMaterial/detailList",
- method: "get",
- params: query,
+ url: "/productionOrderPick/updatePick",
+ method: "post",
+ data,
});
}
-
+// 鐢熶骇璁㈠崟-棰嗘枡璇︽儏鍒楄〃
+// export function listMaterialPickingDetail(query) {
+// return request({
+// url: "/productOrderMaterial/detailList",
+// method: "get",
+// params: query,
+// });
+// }
+export function listMaterialPickingBom(productionOrderId) {
+ return request({
+ url: "/productionOrder/pick/" + productionOrderId,
+ method: "get",
+ });
+}
+export function listMaterialPickingDetail(productionOrderId) {
+ return request({
+ url: "/productionOrderPick/detail/" + productionOrderId,
+ method: "get",
+ });
+}
// 鐢熶骇璁㈠崟-琛ユ枡璁板綍鍒楄〃
export function listMaterialSupplementRecord(query) {
return request({
diff --git a/src/views/fileManagement/borrow/index.vue b/src/views/fileManagement/borrow/index.vue
index 8983665..c7d8e0d 100644
--- a/src/views/fileManagement/borrow/index.vue
+++ b/src/views/fileManagement/borrow/index.vue
@@ -100,16 +100,14 @@
</el-col>
<el-col :span="12">
<el-form-item label="鍊熼槄涔︾睄锛�" prop="documentationId">
- <!-- <el-select v-model="borrowForm.documentationId" placeholder="璇烽�夋嫨鍊熼槄涔︾睄" style="width: 100%" @change="handleScanContent">
- <el-option
- v-for="item in documentList"
- :key="item.id"
- :label="item.docName || item.name"
- :value="item.id"
- />
- </el-select> -->
<div style="display: flex; gap: 10px;">
- <el-select v-model="borrowForm.documentationId" placeholder="璇烽�夋嫨鍊熼槄涔︾睄" style="flex: 1;width: 100px;" @change="handleSelectChange">
+ <el-select
+ v-if="borrowOperationType !== 'edit'"
+ v-model="borrowForm.documentationId"
+ placeholder="璇烽�夋嫨鍊熼槄涔︾睄"
+ style="flex: 1;width: 100px;"
+ @change="handleSelectChange"
+ >
<el-option
v-for="item in documentList"
:key="item.id"
@@ -118,6 +116,13 @@
/>
</el-select>
<el-input
+ v-else
+ v-model="currentEditDocName"
+ style="flex: 1;width: 100px;"
+ disabled
+ />
+ <el-input
+ v-if="borrowOperationType !== 'edit'"
v-model="scanContent"
placeholder="鎵爜杈撳叆"
style="width: 100px;"
@@ -205,6 +210,7 @@
const selectedRows = ref([]);
const documentList = ref([]); // 鏂囨。鍒楄〃锛岀敤浜庡�熼槄涔︾睄閫夋嫨
const scanContent = ref() // 鎵爜鍐呭
+const currentEditDocName = ref(''); // 缂栬緫鏃跺瓨鍌ㄧ殑鏂囨。鍚嶇О
// 鍒嗛〉鐩稿叧
const pagination = reactive({
currentPage: 1,
@@ -282,6 +288,7 @@
{
name: "缂栬緫",
type: "text",
+ disabled: (row) => row.borrowStatus === '褰掕繕',
clickFun: (row) => {
openBorrowDia('edit', row)
},
@@ -428,13 +435,16 @@
if (type === "edit") {
// 缂栬緫妯″紡锛屽姞杞界幇鏈夋暟鎹�
Object.assign(borrowForm, data);
+ // 瀛樺偍鏂囨。鍚嶇О鐢ㄤ簬鏄剧ず
+ currentEditDocName.value = data.docName || '';
} else {
// 鏂板妯″紡锛屾竻绌鸿〃鍗�
Object.keys(borrowForm).forEach(key => {
borrowForm[key] = "";
});
- // 璁剧疆榛樿鐘舵��
- borrowForm.borrowStatus = "鍊熼槄";
+ currentEditDocName.value = ''; // 娓呯┖缂栬緫鏃剁殑鏂囨。鍚嶇О
+ // 璁剧疆榛樿鐘舵��
+ borrowForm.borrowStatus = "鍊熼槄";
// 璁剧疆褰撳墠鏃ユ湡涓哄�熼槄鏃ユ湡
borrowForm.borrowDate = new Date().toISOString().split('T')[0];
}
@@ -445,6 +455,7 @@
proxy.$refs.borrowFormRef.resetFields();
borrowDia.value = false;
scanContent.value = ''; // 娓呯┖鎵爜鍐呭
+ currentEditDocName.value = ''; // 娓呯┖缂栬緫鏃剁殑鏂囨。鍚嶇О
};
// 鎻愪氦鍊熼槄琛ㄥ崟
diff --git a/src/views/fileManagement/document/index.vue b/src/views/fileManagement/document/index.vue
index c31b044..f4eac2d 100644
--- a/src/views/fileManagement/document/index.vue
+++ b/src/views/fileManagement/document/index.vue
@@ -862,12 +862,14 @@
documentForm[key] = "";
});
documentForm.attachments = []; // 鏂板妯″紡涓嬩篃娓呯┖闄勪欢
- // 璁剧疆榛樿鍊� - 浣跨敤瀛楀吀鏁版嵁鐨勭涓�涓�夐」浣滀负榛樿鍊�
+ // 璁剧疆榛樿鍊� - 鏂囨。鐘舵�侀粯璁よ缃负"姝e父"
if (document_status.value && document_status.value.length > 0) {
- documentForm.docStatus = document_status.value[0].value;
+ const normalStatus = document_status.value.find(item => item.label === '姝e父');
+ documentForm.docStatus = normalStatus ? normalStatus.value : document_status.value[0].value;
}
if (document_urgency.value && document_urgency.value.length > 0) {
- documentForm.urgencyLevel = document_urgency.value[0].value;
+ const normalUrgency = document_urgency.value.find(item => item.label === '鏅��');
+ documentForm.urgencyLevel = normalUrgency ? normalUrgency.value : document_urgency.value[0].value;
}
}
};
diff --git a/src/views/fileManagement/return/index.vue b/src/views/fileManagement/return/index.vue
index bc86c56..097ab29 100644
--- a/src/views/fileManagement/return/index.vue
+++ b/src/views/fileManagement/return/index.vue
@@ -103,16 +103,14 @@
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="鏂囨。锛�" prop="borrowId">
- <!-- <el-select v-model="returnForm.borrowId" placeholder="璇烽�夋嫨鏂囨。" style="flex: 1;" @change="handleDocumentChange">
- <el-option
- v-for="item in documentList"
- :key="item.id"
- :label="item.docName || item.name"
- :value="item.id"
- />
- </el-select> -->
<div style="display: flex; gap: 10px;">
- <el-select v-model="returnForm.borrowId" placeholder="璇烽�夋嫨鏂囨。" style="width: 120px;" @change="handleDocumentChange">
+ <el-select
+ v-if="returnOperationType !== 'edit'"
+ v-model="returnForm.borrowId"
+ placeholder="璇烽�夋嫨鏂囨。"
+ style="width: 120px;"
+ @change="handleDocumentChange"
+ >
<el-option
v-for="item in documentList"
:key="item.id"
@@ -121,6 +119,13 @@
/>
</el-select>
<el-input
+ v-else
+ v-model="currentEditDocName"
+ style="width: 120px;"
+ disabled
+ />
+ <el-input
+ v-if="returnOperationType !== 'edit'"
v-model="scanContent"
placeholder="鎵爜杈撳叆"
style="flex: 1;"
@@ -215,6 +220,7 @@
const documentList = ref([]); // 鏂囨。鍒楄〃
const borrowInfoList = ref([]); // 鍊熼槄淇℃伅鍒楄〃
const scanContent = ref(); // 鎵爜鍐呭
+const currentEditDocName = ref(''); // 缂栬緫鏃跺瓨鍌ㄧ殑鏂囨。鍚嶇О
// 鍒嗛〉鐩稿叧
const pagination = reactive({
@@ -286,6 +292,7 @@
{
name: "缂栬緫",
type: "text",
+ disabled: (row) => row.borrowStatus === '褰掕繕',
clickFun: (row) => {
openReturnDia('edit', row)
},
@@ -396,15 +403,14 @@
if (type === "edit") {
// 缂栬緫妯″紡锛屽姞杞界幇鏈夋暟鎹�
Object.assign(returnForm, data);
- // 缂栬緫妯″紡涓嬶紝鏂囨。閫夋嫨鍚庤嚜鍔ㄥ~鍏呭�熼槄浜哄拰搴斿綊杩樻棩鏈�
- if (returnForm.borrowId) {
- handleDocumentChange(returnForm.borrowId);
- }
+ // 瀛樺偍鏂囨。鍚嶇О鐢ㄤ簬鏄剧ず
+ currentEditDocName.value = data.docName || '';
} else {
// 鏂板妯″紡锛屾竻绌鸿〃鍗�
Object.keys(returnForm).forEach(key => {
returnForm[key] = "";
});
+ currentEditDocName.value = ''; // 娓呯┖缂栬緫鏃剁殑鏂囨。鍚嶇О
// 璁剧疆榛樿鐘舵��
returnForm.borrowStatus = "褰掕繕";
// 璁剧疆褰撳墠鏃ユ湡涓哄綊杩樻棩鏈�
@@ -418,6 +424,7 @@
returnDia.value = false;
scanContent.value = ''; // 娓呯┖鎵爜鍐呭
borrowInfoList.value = []; // 娓呯┖鍊熼槄淇℃伅鍒楄〃
+ currentEditDocName.value = ''; // 娓呯┖缂栬緫鏃剁殑鏂囨。鍚嶇О
};
// 鎻愪氦褰掕繕琛ㄥ崟
diff --git a/src/views/inventoryManagement/stockManagement/New.vue b/src/views/inventoryManagement/stockManagement/New.vue
index eebe313..1c9b333 100644
--- a/src/views/inventoryManagement/stockManagement/New.vue
+++ b/src/views/inventoryManagement/stockManagement/New.vue
@@ -1,96 +1,97 @@
<template>
<div>
- <el-dialog
- v-model="isShow"
- title="鏂板搴撳瓨"
- width="800"
- @close="closeModal"
- >
- <el-form label-width="140px" :model="formState" label-position="top" ref="formRef">
- <el-form-item
- label="浜у搧鍚嶇О"
- prop="productModelId"
- :rules="[
+ <el-dialog v-model="isShow"
+ title="鏂板搴撳瓨"
+ width="800"
+ @close="closeModal">
+ <el-form label-width="140px"
+ :model="formState"
+ label-position="top"
+ ref="formRef">
+ <el-form-item label="浜у搧鍚嶇О"
+ prop="productModelId"
+ :rules="[
{
required: true,
message: '璇烽�夋嫨浜у搧',
trigger: 'change',
}
- ]"
- >
- <el-button type="primary" @click="showProductSelectDialog = true">
+ ]">
+ <el-button type="primary"
+ @click="showProductSelectDialog = true">
{{ formState.productName ? formState.productName : '閫夋嫨浜у搧' }}
</el-button>
</el-form-item>
-
- <el-form-item
- label="瑙勬牸"
- prop="productModelName"
- >
- <el-input v-model="formState.productModelName" disabled />
+ <el-form-item label="瑙勬牸"
+ prop="productModelName">
+ <el-input v-model="formState.productModelName"
+ disabled />
</el-form-item>
-
- <el-form-item
- label="鍗曚綅"
- prop="unit"
- >
- <el-input v-model="formState.unit" disabled />
+ <el-form-item label="鍗曚綅"
+ prop="unit">
+ <el-input v-model="formState.unit"
+ disabled />
</el-form-item>
-
- <el-form-item
- label="搴撳瓨绫诲瀷"
- prop="type"
- :rules="[
+ <el-form-item label="搴撳瓨绫诲瀷"
+ prop="type"
+ :rules="[
{
required: true,
message: '璇烽�夋嫨搴撳瓨绫诲瀷',
trigger: 'change',
}
- ]"
- >
- <el-select v-model="formState.type" placeholder="璇烽�夋嫨搴撳瓨绫诲瀷">
- <el-option label="鍚堟牸搴撳瓨" value="qualified" />
- <el-option label="涓嶅悎鏍煎簱瀛�" value="unqualified" />
+ ]">
+ <el-select v-model="formState.type"
+ placeholder="璇烽�夋嫨搴撳瓨绫诲瀷">
+ <el-option label="鍚堟牸搴撳瓨"
+ value="qualified" />
+ <el-option label="涓嶅悎鏍煎簱瀛�"
+ value="unqualified" />
</el-select>
</el-form-item>
-
- <el-form-item
- label="搴撳瓨鏁伴噺"
- prop="qualitity"
- >
- <el-input-number v-model="formState.qualitity" :step="1" :min="1" style="width: 100%" />
+ <el-form-item label="搴撳瓨鏁伴噺"
+ prop="qualitity">
+ <el-input-number v-model="formState.qualitity"
+ :step="1"
+ :min="1"
+ style="width: 100%" />
</el-form-item>
-
- <el-form-item
- label="鎵瑰彿"
- prop="batchNo"
- >
- <el-input v-model="formState.batchNo" placeholder="璇疯緭鍏ユ壒鍙�" />
+ <el-form-item label="鎵瑰彿"
+ prop="batchNo"
+ :rules="[
+ {
+ required: true,
+ message: '璇疯緭鍏ユ壒鍙�',
+ trigger: 'blur',
+ }
+ ]">
+ <el-input v-model="formState.batchNo"
+ placeholder="璇疯緭鍏ユ壒鍙�" />
</el-form-item>
-
- <el-form-item
- v-if="formState.type === 'qualified'"
- label="搴撳瓨棰勮鏁伴噺"
- prop="warnNum"
- >
- <el-input-number v-model="formState.warnNum" :step="1" :min="0" :max="formState.qualitity" style="width: 100%" />
+ <el-form-item v-if="formState.type === 'qualified'"
+ label="搴撳瓨棰勮鏁伴噺"
+ prop="warnNum">
+ <el-input-number v-model="formState.warnNum"
+ :step="1"
+ :min="0"
+ :max="formState.qualitity"
+ style="width: 100%" />
</el-form-item>
-
- <el-form-item label="澶囨敞" prop="remark">
- <el-input v-model="formState.remark" type="textarea" />
+ <el-form-item label="澶囨敞"
+ prop="remark">
+ <el-input v-model="formState.remark"
+ type="textarea" />
</el-form-item>
</el-form>
-
<!-- 浜у搧閫夋嫨寮圭獥 -->
- <ProductSelectDialog
- v-model="showProductSelectDialog"
- @confirm="handleProductSelect"
- :top-product-parent-id="props.topProductParentId"
- single
- />
+ <ProductSelectDialog v-model="showProductSelectDialog"
+ @confirm="handleProductSelect"
+ :top-product-parent-id="props.topProductParentId"
+ single />
<template #footer>
<div class="dialog-footer">
- <el-button type="primary" @click="handleSubmit">纭</el-button>
+ <el-button type="primary"
+ @click="handleSubmit">纭</el-button>
<el-button @click="closeModal">鍙栨秷</el-button>
</div>
</template>
@@ -99,62 +100,27 @@
</template>
<script setup>
-import {ref, computed, watch, getCurrentInstance} from "vue";
-import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
-import {addStockInRecordOnly} from "@/api/inventoryManagement/stockInventory.js";
-import {createStockUnInventory} from "@/api/inventoryManagement/stockUninventory.js";
+ import { ref, computed, watch, getCurrentInstance } from "vue";
+ import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
+ import { addStockInRecordOnly } from "@/api/inventoryManagement/stockInventory.js";
+ import { createStockUnInventory } from "@/api/inventoryManagement/stockUninventory.js";
-const props = defineProps({
- visible: {
- type: Boolean,
- required: true,
- },
- topProductParentId: {
- type: Number,
- default: undefined,
- required: false,
- }
-});
+ const props = defineProps({
+ visible: {
+ type: Boolean,
+ required: true,
+ },
+ topProductParentId: {
+ type: Number,
+ default: undefined,
+ required: false,
+ },
+ });
-const emit = defineEmits(['update:visible', 'completed']);
+ const emit = defineEmits(["update:visible", "completed"]);
-// 鍝嶅簲寮忔暟鎹紙鏇夸唬閫夐」寮忕殑 data锛�
-const formState = ref({
- productId: undefined,
- productModelId: undefined,
- productName: "",
- productModelName: "",
- unit: "",
- type: undefined,
- qualitity: 0,
- batchNo: null,
- warnNum: 0,
- remark: '',
-});
-
-const isShow = computed({
- get() {
- return props.visible;
- },
- set(val) {
- emit('update:visible', val);
- },
-});
-
-const showProductSelectDialog = ref(false);
-
-// 鎵瑰彿涓虹┖鏃惰浆涓� null
-watch(() => formState.value.batchNo, (val) => {
- if (val === '') {
- formState.value.batchNo = null;
- }
-});
-
-let { proxy } = getCurrentInstance()
-
-const closeModal = () => {
- // 閲嶇疆琛ㄥ崟鏁版嵁
- formState.value = {
+ // 鍝嶅簲寮忔暟鎹紙鏇夸唬閫夐」寮忕殑 data锛�
+ const formState = ref({
productId: undefined,
productModelId: undefined,
productName: "",
@@ -164,65 +130,101 @@
qualitity: 0,
batchNo: null,
warnNum: 0,
- remark: '',
- };
- isShow.value = false;
-};
+ remark: "",
+ });
-// 浜у搧閫夋嫨澶勭悊
-const handleProductSelect = async (products) => {
- if (products && products.length > 0) {
- const product = products[0];
- formState.value.productId = product.productId;
- formState.value.productName = product.productName;
- formState.value.productModelName = product.model;
- formState.value.productModelId = product.id;
- formState.value.unit = product.unit;
- showProductSelectDialog.value = false;
- // 瑙﹀彂琛ㄥ崟楠岃瘉鏇存柊
- proxy.$refs["formRef"]?.validateField('productModelId');
- }
-};
+ const isShow = computed({
+ get() {
+ return props.visible;
+ },
+ set(val) {
+ emit("update:visible", val);
+ },
+ });
-const handleSubmit = () => {
- proxy.$refs["formRef"].validate(valid => {
- if (valid) {
- // 楠岃瘉鏄惁閫夋嫨浜嗕骇鍝佸拰瑙勬牸
- if (!formState.value.productModelId) {
- proxy.$modal.msgError("璇烽�夋嫨浜у搧");
- return;
- }
- if (!formState.value.productModelId) {
- proxy.$modal.msgError("璇烽�夋嫨瑙勬牸");
- return;
- }
- if (formState.value.type === 'qualified') {
- addStockInRecordOnly(formState.value).then(res => {
- // 鍏抽棴妯℃�佹
- isShow.value = false;
- // 鍛婄煡鐖剁粍浠跺凡瀹屾垚
- emit('completed');
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- })
- } else {
- formState.value.warnNum = 0;
- createStockUnInventory(formState.value).then(res => {
- // 鍏抽棴妯℃�佹
- isShow.value = false;
- // 鍛婄煡鐖剁粍浠跺凡瀹屾垚
- emit('completed');
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- })
- }
+ const showProductSelectDialog = ref(false);
+ // 鎵瑰彿涓虹┖鏃惰浆涓� null
+ watch(
+ () => formState.value.batchNo,
+ val => {
+ if (val === "") {
+ formState.value.batchNo = null;
+ }
}
- })
-};
+ );
+ let { proxy } = getCurrentInstance();
-defineExpose({
- closeModal,
- handleSubmit,
- isShow,
-});
+ const closeModal = () => {
+ // 閲嶇疆琛ㄥ崟鏁版嵁
+ formState.value = {
+ productId: undefined,
+ productModelId: undefined,
+ productName: "",
+ productModelName: "",
+ unit: "",
+ type: undefined,
+ qualitity: 0,
+ batchNo: null,
+ warnNum: 0,
+ remark: "",
+ };
+ isShow.value = false;
+ };
+
+ // 浜у搧閫夋嫨澶勭悊
+ const handleProductSelect = async products => {
+ if (products && products.length > 0) {
+ const product = products[0];
+ formState.value.productId = product.productId;
+ formState.value.productName = product.productName;
+ formState.value.productModelName = product.model;
+ formState.value.productModelId = product.id;
+ formState.value.unit = product.unit;
+ showProductSelectDialog.value = false;
+ // 瑙﹀彂琛ㄥ崟楠岃瘉鏇存柊
+ proxy.$refs["formRef"]?.validateField("productModelId");
+ }
+ };
+
+ const handleSubmit = () => {
+ proxy.$refs["formRef"].validate(valid => {
+ if (valid) {
+ // 楠岃瘉鏄惁閫夋嫨浜嗕骇鍝佸拰瑙勬牸
+ if (!formState.value.productModelId) {
+ proxy.$modal.msgError("璇烽�夋嫨浜у搧");
+ return;
+ }
+ if (!formState.value.productModelId) {
+ proxy.$modal.msgError("璇烽�夋嫨瑙勬牸");
+ return;
+ }
+ if (formState.value.type === "qualified") {
+ addStockInRecordOnly(formState.value).then(res => {
+ // 鍏抽棴妯℃�佹
+ isShow.value = false;
+ // 鍛婄煡鐖剁粍浠跺凡瀹屾垚
+ emit("completed");
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ });
+ } else {
+ formState.value.warnNum = 0;
+ createStockUnInventory(formState.value).then(res => {
+ // 鍏抽棴妯℃�佹
+ isShow.value = false;
+ // 鍛婄煡鐖剁粍浠跺凡瀹屾垚
+ emit("completed");
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ });
+ }
+ }
+ });
+ };
+
+ defineExpose({
+ closeModal,
+ handleSubmit,
+ isShow,
+ });
</script>
diff --git a/src/views/productionManagement/productionOrder/components/MaterialDetailDialog.vue b/src/views/productionManagement/productionOrder/components/MaterialDetailDialog.vue
index 9c50fc8..a83ff6a 100644
--- a/src/views/productionManagement/productionOrder/components/MaterialDetailDialog.vue
+++ b/src/views/productionManagement/productionOrder/components/MaterialDetailDialog.vue
@@ -1,44 +1,82 @@
<template>
<div>
- <el-dialog v-model="dialogVisible" title="棰嗘枡璇︽儏" width="1400px" @close="handleClose">
- <el-table v-loading="materialDetailLoading" :data="materialDetailTableData" border row-key="id">
- <el-table-column label="宸ュ簭鍚嶇О" prop="processName" min-width="180" />
- <el-table-column label="鍘熸枡鍚嶇О" prop="materialName" min-width="160" />
- <el-table-column label="鍘熸枡鍨嬪彿" prop="materialModel" min-width="180" />
- <el-table-column label="闇�姹傛暟閲�" prop="requiredQty" min-width="110" />
- <el-table-column label="璁¢噺鍗曚綅" prop="unit" width="100" />
- <el-table-column label="棰嗙敤鏁伴噺" prop="pickQty" min-width="110" />
- <el-table-column label="琛ユ枡鏁伴噺" min-width="120">
+ <el-dialog v-model="dialogVisible"
+ title="棰嗘枡璇︽儏"
+ width="1400px"
+ @close="handleClose">
+ <el-table v-loading="materialDetailLoading"
+ :data="materialDetailTableData"
+ border
+ row-key="id">
+ <el-table-column label="宸ュ簭鍚嶇О"
+ prop="operationName"
+ min-width="180" />
+ <el-table-column label="鍘熸枡鍚嶇О"
+ prop="productName"
+ min-width="160" />
+ <el-table-column label="鍘熸枡鍨嬪彿"
+ prop="model"
+ min-width="180" />
+ <el-table-column label="鎵瑰彿"
+ prop="batchNo"
+ min-width="150" />
+ <el-table-column label="闇�姹傛暟閲�"
+ prop="demandedQuantity"
+ min-width="110" />
+ <el-table-column label="璁¢噺鍗曚綅"
+ prop="unit"
+ width="100" />
+ <el-table-column label="棰嗙敤鏁伴噺"
+ prop="pickQuantity"
+ min-width="110" />
+ <el-table-column label="琛ユ枡鏁伴噺"
+ min-width="120">
<template #default="{ row }">
- <el-button type="primary" link @click="handleViewSupplementRecord(row)">
+ <el-button type="primary"
+ link
+ @click="handleViewSupplementRecord(row)">
{{ row.supplementQty ?? 0 }}
</el-button>
</template>
</el-table-column>
- <el-table-column label="閫�鏂欐暟閲�" prop="returnQty" min-width="110" />
- <el-table-column label="瀹為檯鏁伴噺" prop="actualQty" min-width="110" />
+ <el-table-column label="閫�鏂欐暟閲�"
+ prop="returnQty"
+ min-width="110" />
+ <el-table-column label="瀹為檯鏁伴噺"
+ prop="actualQty"
+ min-width="110" />
</el-table>
<template #footer>
<span class="dialog-footer">
- <el-button
- type="warning"
- :loading="materialReturnConfirming"
- :disabled="!canOpenReturnSummary"
- @click="openReturnSummaryDialog"
- >
+ <el-button type="warning"
+ :loading="materialReturnConfirming"
+ :disabled="!canOpenReturnSummary"
+ @click="openReturnSummaryDialog">
閫�鏂欑‘璁�
</el-button>
<el-button @click="dialogVisible = false">鍙栨秷</el-button>
</span>
</template>
</el-dialog>
-
- <el-dialog v-model="supplementRecordDialogVisible" title="琛ユ枡璁板綍" width="800px">
- <el-table v-loading="supplementRecordLoading" :data="supplementRecordTableData" border row-key="id">
- <el-table-column label="琛ユ枡鏁伴噺" prop="supplementQty" min-width="120" />
- <el-table-column label="琛ユ枡浜�" prop="supplementUserName" min-width="120" />
- <el-table-column label="琛ユ枡鏃ユ湡" prop="supplementTime" min-width="160" />
- <el-table-column label="琛ユ枡鍘熷洜" prop="supplementReason" min-width="200" />
+ <el-dialog v-model="supplementRecordDialogVisible"
+ title="琛ユ枡璁板綍"
+ width="800px">
+ <el-table v-loading="supplementRecordLoading"
+ :data="supplementRecordTableData"
+ border
+ row-key="id">
+ <el-table-column label="琛ユ枡鏁伴噺"
+ prop="supplementQty"
+ min-width="120" />
+ <el-table-column label="琛ユ枡浜�"
+ prop="supplementUserName"
+ min-width="120" />
+ <el-table-column label="琛ユ枡鏃ユ湡"
+ prop="supplementTime"
+ min-width="160" />
+ <el-table-column label="琛ユ枡鍘熷洜"
+ prop="supplementReason"
+ min-width="200" />
</el-table>
<template #footer>
<span class="dialog-footer">
@@ -46,18 +84,30 @@
</span>
</template>
</el-dialog>
-
- <el-dialog v-model="returnSummaryDialogVisible" title="閫�鏂欐眹鎬荤‘璁�" width="900px">
- <el-table :data="returnSummaryList" border row-key="summaryKey">
- <el-table-column label="鍘熸枡鍚嶇О" prop="materialName" min-width="180" />
- <el-table-column label="鍘熸枡鍨嬪彿" prop="materialModel" min-width="180" />
- <el-table-column label="璁¢噺鍗曚綅" prop="unit" min-width="100" />
- <el-table-column label="閫�鏂欐眹鎬绘暟閲�" prop="returnQtyTotal" min-width="140" />
+ <el-dialog v-model="returnSummaryDialogVisible"
+ title="閫�鏂欐眹鎬荤‘璁�"
+ width="900px">
+ <el-table :data="returnSummaryList"
+ border
+ row-key="summaryKey">
+ <el-table-column label="鍘熸枡鍚嶇О"
+ prop="materialName"
+ min-width="180" />
+ <el-table-column label="鍘熸枡鍨嬪彿"
+ prop="materialModel"
+ min-width="180" />
+ <el-table-column label="璁¢噺鍗曚綅"
+ prop="unit"
+ min-width="100" />
+ <el-table-column label="閫�鏂欐眹鎬绘暟閲�"
+ prop="returnQtyTotal"
+ min-width="140" />
</el-table>
-
<template #footer>
<span class="dialog-footer">
- <el-button type="primary" :loading="materialReturnConfirming" @click="handleReturnConfirm">纭鎻愪氦</el-button>
+ <el-button type="primary"
+ :loading="materialReturnConfirming"
+ @click="handleReturnConfirm">纭鎻愪氦</el-button>
<el-button @click="returnSummaryDialogVisible = false">鍙栨秷</el-button>
</span>
</template>
@@ -66,116 +116,126 @@
</template>
<script setup>
-import { computed, ref, watch } from "vue";
-import { ElMessage } from "element-plus";
-import { listMaterialPickingDetail, listMaterialSupplementRecord, confirmMaterialReturn } from "@/api/productionManagement/productionOrder.js";
+ import { computed, ref, watch } from "vue";
+ import { ElMessage } from "element-plus";
+ import {
+ listMaterialPickingDetail,
+ listMaterialSupplementRecord,
+ confirmMaterialReturn,
+ } from "@/api/productionManagement/productionOrder.js";
-const props = defineProps({
- modelValue: { type: Boolean, default: false },
- orderRow: { type: Object, default: null },
-});
-const emit = defineEmits(["update:modelValue", "confirmed"]);
-
-const dialogVisible = computed({
- get: () => props.modelValue,
- set: val => emit("update:modelValue", val),
-});
-
-const materialDetailLoading = ref(false);
-const materialDetailTableData = ref([]);
-const materialReturnConfirming = ref(false);
-const supplementRecordDialogVisible = ref(false);
-const supplementRecordLoading = ref(false);
-const supplementRecordTableData = ref([]);
-const returnSummaryDialogVisible = ref(false);
-const returnSummaryList = ref([]);
-const calcReturnQty = item =>
- Number(item.pickQty || 0) + Number(item.supplementQty || 0) - Number(item.actualQty || 0);
-const canOpenReturnSummary = computed(() =>
- materialDetailTableData.value.some(item => calcReturnQty(item) > 0)
-);
-
-const loadDetailList = async () => {
- if (!props.orderRow?.id) return;
- materialDetailLoading.value = true;
- materialDetailTableData.value = [];
- try {
- const res = await listMaterialPickingDetail({ orderId: props.orderRow.id });
- materialDetailTableData.value = res.data || [];
- } finally {
- materialDetailLoading.value = false;
- }
-};
-
-watch(
- () => dialogVisible.value,
- visible => {
- if (visible) {
- loadDetailList();
- }
- }
-);
-
-const handleClose = () => {
- materialDetailTableData.value = [];
-};
-
-const handleViewSupplementRecord = async row => {
- if (!row?.id) return;
- supplementRecordDialogVisible.value = true;
- supplementRecordLoading.value = true;
- supplementRecordTableData.value = [];
- try {
- const res = await listMaterialSupplementRecord({ materialDetailId: row.id });
- supplementRecordTableData.value = res.data || [];
- } finally {
- supplementRecordLoading.value = false;
- }
-};
-
-const buildReturnSummary = () => {
- const map = new Map();
- materialDetailTableData.value.forEach(item => {
- const returnQty = calcReturnQty(item);
- if (returnQty <= 0) return;
- const key = `${item.materialModelId || ""}_${item.materialName || ""}_${item.materialModel || ""}_${item.unit || ""}`;
- const old = map.get(key) || {
- summaryKey: key,
- materialName: item.materialName || "",
- materialModel: item.materialModel || "",
- unit: item.unit || "",
- returnQtyTotal: 0,
- };
- old.returnQtyTotal += returnQty;
- map.set(key, old);
+ const props = defineProps({
+ modelValue: { type: Boolean, default: false },
+ orderRow: { type: Object, default: null },
});
- return Array.from(map.values());
-};
+ const emit = defineEmits(["update:modelValue", "confirmed"]);
-const openReturnSummaryDialog = async () => {
- if (!canOpenReturnSummary.value) {
- ElMessage.warning("閫�鏂欐暟閲�=棰嗙敤鏁伴噺+琛ユ枡鏁伴噺-瀹為檯鏁伴噺锛屼笖闇�澶т簬0");
- return;
- }
- returnSummaryList.value = buildReturnSummary();
- returnSummaryDialogVisible.value = true;
-};
+ const dialogVisible = computed({
+ get: () => props.modelValue,
+ set: val => emit("update:modelValue", val),
+ });
-const handleReturnConfirm = async () => {
- if (!props.orderRow?.id) return;
- materialReturnConfirming.value = true;
- try {
- await confirmMaterialReturn({
- orderId: props.orderRow.id,
- returnSummaryList: returnSummaryList.value,
+ const materialDetailLoading = ref(false);
+ const materialDetailTableData = ref([]);
+ const materialReturnConfirming = ref(false);
+ const supplementRecordDialogVisible = ref(false);
+ const supplementRecordLoading = ref(false);
+ const supplementRecordTableData = ref([]);
+ const returnSummaryDialogVisible = ref(false);
+ const returnSummaryList = ref([]);
+ const calcReturnQty = item =>
+ Number(item.pickQuantity || 0) +
+ Number(item.supplementQty || 0) -
+ Number(item.actualQty || 0);
+ const canOpenReturnSummary = computed(() =>
+ materialDetailTableData.value.some(item => calcReturnQty(item) > 0)
+ );
+
+ const loadDetailList = async () => {
+ if (!props.orderRow?.id) return;
+ materialDetailLoading.value = true;
+ materialDetailTableData.value = [];
+ try {
+ const res = await listMaterialPickingDetail(props.orderRow.id);
+ materialDetailTableData.value = res.data || [];
+ } finally {
+ materialDetailLoading.value = false;
+ }
+ };
+
+ watch(
+ () => dialogVisible.value,
+ visible => {
+ if (visible) {
+ loadDetailList();
+ }
+ }
+ );
+
+ const handleClose = () => {
+ materialDetailTableData.value = [];
+ };
+
+ const handleViewSupplementRecord = async row => {
+ if (!row?.id) return;
+ supplementRecordDialogVisible.value = true;
+ supplementRecordLoading.value = true;
+ supplementRecordTableData.value = [];
+ try {
+ const res = await listMaterialSupplementRecord({
+ materialDetailId: row.id,
+ });
+ supplementRecordTableData.value = res.data || [];
+ } finally {
+ supplementRecordLoading.value = false;
+ }
+ };
+
+ const buildReturnSummary = () => {
+ const map = new Map();
+ materialDetailTableData.value.forEach(item => {
+ const returnQty = calcReturnQty(item);
+ if (returnQty <= 0) return;
+ const key = `${item.productModelId || ""}_${item.productName || ""}_${
+ item.model || ""
+ }_${item.unit || ""}`;
+ const old = map.get(key) || {
+ summaryKey: key,
+ materialName: item.productName || "",
+ materialModel: item.model || "",
+ unit: item.unit || "",
+ returnQtyTotal: 0,
+ };
+ old.returnQtyTotal += returnQty;
+ map.set(key, old);
});
- returnSummaryDialogVisible.value = false;
- dialogVisible.value = false;
- emit("confirmed");
- } finally {
- materialReturnConfirming.value = false;
- }
-};
+ return Array.from(map.values());
+ };
+
+ const openReturnSummaryDialog = async () => {
+ if (!canOpenReturnSummary.value) {
+ ElMessage.warning("閫�鏂欐暟閲�=棰嗙敤鏁伴噺+琛ユ枡鏁伴噺-瀹為檯鏁伴噺锛屼笖闇�澶т簬0");
+ return;
+ }
+ returnSummaryList.value = buildReturnSummary();
+ returnSummaryDialogVisible.value = true;
+ };
+
+ const handleReturnConfirm = async () => {
+ if (!props.orderRow?.id) return;
+ materialReturnConfirming.value = true;
+ try {
+ await confirmMaterialReturn({
+ orderId: props.orderRow.id,
+ returnSummaryList: returnSummaryList.value,
+ });
+ returnSummaryDialogVisible.value = false;
+ dialogVisible.value = false;
+ emit("confirmed");
+ } finally {
+ materialReturnConfirming.value = false;
+ }
+ };
</script>
<style scoped lang="scss"></style>
diff --git a/src/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue b/src/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue
index 6b040d6..991f2a1 100644
--- a/src/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue
+++ b/src/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue
@@ -13,25 +13,25 @@
border
row-key="tempId">
<el-table-column label="宸ュ簭鍚嶇О"
- min-width="180">
+ min-width="140">
<template #default="{ row }">
- <span v-if="row.bom === true">{{ row.processName || "-" }}</span>
+ <span v-if="row.bom === true">{{ row.operationName || "-" }}</span>
<el-select v-else
- v-model="row.processName"
+ v-model="row.operationName"
placeholder="璇烽�夋嫨宸ュ簭"
clearable
filterable
style="width: 100%;"
@change="val => handleProcessNameChange(row, val)">
<el-option v-for="item in processOptions"
- :key="item.id"
+ :key="item.technologyOperationId"
:label="item.name"
:value="item.name" />
</el-select>
</template>
</el-table-column>
<el-table-column label="鍘熸枡鍚嶇О"
- min-width="160">
+ min-width="140">
<template #default="{ row }">
<span v-if="row.bom === true">{{ row.materialName || "-" }}</span>
<el-button v-else
@@ -43,17 +43,37 @@
</template>
</el-table-column>
<el-table-column label="鍘熸枡鍨嬪彿"
- min-width="180">
+ min-width="140">
<template #default="{ row }">
{{ row.materialModel || "-" }}
+ </template>
+ </el-table-column>
+ <!-- 鎵瑰彿澶氶�� -->
+ <el-table-column min-width="200">
+ <template #header>
+ <span style="color: #f56c6c; margin-right: 4px;">*</span>
+ <span>鎵瑰彿</span>
+ </template>
+ <template #default="{ row }">
+ <el-select v-model="row.batchNo"
+ multiple
+ collapse-tags
+ collapse-tags-indicator
+ placeholder="璇烽�夋嫨鎵瑰彿"
+ style="width: 100%;">
+ <el-option v-for="item in row.batchNoList"
+ :key="item"
+ :label="item"
+ :value="item" />
+ </el-select>
</template>
</el-table-column>
<el-table-column label="闇�姹傛暟閲�"
min-width="120">
<template #default="{ row }">
- <span v-if="row.bom === true">{{ row.requiredQty ?? "-" }}</span>
+ <span v-if="row.bom === true">{{ row.demandedQuantity ?? "-" }}</span>
<el-input-number v-else
- v-model="row.requiredQty"
+ v-model="row.demandedQuantity"
:min="0"
:precision="3"
:step="1"
@@ -63,7 +83,7 @@
</template>
</el-table-column>
<el-table-column label="璁¢噺鍗曚綅"
- width="120">
+ width="100">
<template #default="{ row }">
{{ row.unit || "-" }}
</template>
@@ -110,12 +130,18 @@
import { computed, ref, watch } from "vue";
import { ElMessage } from "element-plus";
import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
- import { findProductProcessRouteItemList } from "@/api/productionManagement/productProcessRoute.js";
+ import {
+ findProductProcessRouteItemList,
+ listMain,
+ } from "@/api/productionManagement/productProcessRoute.js";
import {
listMaterialPickingDetail,
+ listMaterialPickingBom,
listMaterialPickingLedger,
saveMaterialPickingLedger,
+ updateMaterialPickingLedger,
} from "@/api/productionManagement/productionOrder.js";
+ import { queryList2 } from "@/api/productionManagement/productStructure.js";
const props = defineProps({
modelValue: { type: Boolean, default: false },
@@ -139,16 +165,22 @@
const createMaterialRow = (row = {}) => ({
tempId: row.id || `temp_${++materialTempId}`,
id: row.id,
- processId: row.processId,
- productProcessId: row.productProcessId || row.processId,
- processName: row.processName || "",
+ processId: row.processId || row.technologyOperationId,
+ technologyOperationId: row.technologyOperationId || row.processId,
+ operationName: row.operationName || "",
bom: row.bom === true,
- materialModelId: row.materialModelId,
- materialName: row.materialName || "",
- materialModel: row.materialModel || "",
- requiredQty: Number(row.requiredQty ?? 0),
+ materialModelId: row.materialModelId || row.productModelId,
+ materialName: row.materialName || row.productName || "",
+ materialModel: row.materialModel || row.model || "",
+ demandedQuantity: Number(row.requiredQty ?? row.demandedQuantity ?? 0),
unit: row.unit || "",
- pickQty: Number(row.pickQty ?? row.requiredQty ?? 0),
+ pickQty: Number(row.pickQty ?? row.pickQuantity ?? 0),
+ batchNo: row.batchNo
+ ? typeof row.batchNo === "string"
+ ? row.batchNo.split(",")
+ : row.batchNo
+ : [],
+ batchNoList: row.batchNoList || [],
});
const getProcessOptions = async () => {
@@ -161,19 +193,20 @@
: res?.data?.records || [];
const processMap = new Map();
routeList.forEach(item => {
- const processId = item.processId;
- const processName = item.processName;
- if (!processId || !processName) return;
- const key = `${processId}_${processName}`;
+ const processId = item.technologyOperationId;
+ const operationName = item.operationName;
+ if (!processId || !operationName) return;
+ const key = `${processId}_${operationName}`;
if (!processMap.has(key)) {
processMap.set(key, {
id: processId,
- name: processName,
+ name: operationName,
});
}
});
processOptions.value = Array.from(processMap.values());
};
+ const isDetail = ref(true);
const loadMaterialData = async () => {
if (!props.orderRow?.id) return;
@@ -181,23 +214,23 @@
materialTableData.value = [];
await getProcessOptions();
try {
- const detailRes = await listMaterialPickingDetail({
- orderId: props.orderRow.id,
- });
+ const detailRes = await listMaterialPickingDetail(props.orderRow.id);
const detailList = Array.isArray(detailRes?.data)
? detailRes.data
: detailRes?.data?.records || [];
if (detailList.length > 0) {
+ isDetail.value = true;
materialTableData.value = detailList.map(item => createMaterialRow(item));
return;
+ } else {
+ isDetail.value = false;
+ const bomRes = await listMaterialPickingBom(props.orderRow.id);
+ const bomList = Array.isArray(bomRes?.data)
+ ? bomRes.data
+ : bomRes?.data?.records || [];
+ materialTableData.value = bomList.map(item => createMaterialRow(item));
+ return;
}
- const ledgerRes = await listMaterialPickingLedger({
- orderId: props.orderRow.id,
- });
- const ledgerList = Array.isArray(ledgerRes?.data)
- ? ledgerRes.data
- : ledgerRes?.data?.records || [];
- materialTableData.value = ledgerList.map(item => createMaterialRow(item));
} finally {
materialTableLoading.value = false;
}
@@ -225,14 +258,16 @@
materialTableData.value.splice(index, 1);
};
- const handleProcessNameChange = (row, processName) => {
- const process = processOptions.value.find(item => item.name === processName);
- row.productProcessId = process?.id;
+ const handleProcessNameChange = (row, operationName) => {
+ const process = processOptions.value.find(
+ item => item.name === operationName
+ );
+ row.technologyOperationId = process?.technologyOperationId;
};
const handleRequiredQtyChange = (row, val) => {
const required = Number(val ?? 0);
- row.requiredQty = required;
+ row.demandedQuantity = required;
if (!row.pickQty || Number(row.pickQty) === 0) {
row.pickQty = required;
}
@@ -246,6 +281,8 @@
};
const handleMaterialProductConfirm = products => {
+ console.log(products, "products");
+
if (!products || products.length === 0) return;
const index = currentMaterialSelectRowIndex.value;
if (index < 0 || !materialTableData.value[index]) return;
@@ -257,6 +294,7 @@
product.materialName || product.productName || product.name || "";
row.materialModel = product.materialModel || product.model || "";
row.unit = product.unit || product.measureUnit || "";
+ row.batchNoList = product.batchNoList;
currentMaterialSelectRowIndex.value = -1;
materialProductDialogVisible.value = false;
};
@@ -266,22 +304,24 @@
return { valid: false, message: "璇峰厛鏂板棰嗘枡鏁版嵁" };
}
const invalidNewRow = materialTableData.value.find(
- item => item.bom !== true && (!item.processName || !item.materialName)
+ item => item.bom !== true && (!item.operationName || !item.materialName)
);
if (invalidNewRow) {
return { valid: false, message: "鏂板琛岀殑宸ュ簭鍚嶇О鍜屽師鏂欏悕绉颁负蹇呭~椤�" };
}
const invalidRow = materialTableData.value.find(
item =>
- !item.processName ||
+ !item.operationName ||
!item.materialName ||
- item.requiredQty === null ||
- item.requiredQty === undefined ||
+ !item.batchNo ||
+ item.batchNo.length === 0 ||
+ item.demandedQuantity === null ||
+ item.demandedQuantity === undefined ||
item.pickQty === null ||
item.pickQty === undefined
);
if (invalidRow) {
- return { valid: false, message: "璇峰畬鍠勫伐搴忋�佸師鏂欏拰鏁伴噺鍚庡啀淇濆瓨" };
+ return { valid: false, message: "璇峰畬鍠勫伐搴忋�佸師鏂欍�佹壒鍙峰拰鏁伴噺鍚庡啀淇濆瓨" };
}
return { valid: true, message: "" };
};
@@ -295,22 +335,49 @@
}
materialSaving.value = true;
try {
- await saveMaterialPickingLedger({
- orderId: props.orderRow.id,
- items: materialTableData.value.map(item => ({
- id: item.id,
- processId: item.processName,
- productProcessId: item.productProcessId,
- processName: item.processName,
- bom: item.bom === true,
- materialModelId: item.materialModelId,
- materialName: item.materialName,
- materialModel: item.materialModel,
- requiredQty: item.requiredQty,
- unit: item.unit,
- pickQty: item.pickQty,
- })),
- });
+ if (isDetail.value) {
+ await updateMaterialPickingLedger({
+ productionOrderId: props.orderRow.id,
+ productionOrderPickDto: materialTableData.value.map(item => ({
+ id: item.id,
+ // processId: item.operationName,
+ technologyOperationId: item.technologyOperationId,
+ operationName: item.operationName,
+ bom: item.bom === true,
+ productModelId: item.materialModelId,
+ // materialName: item.materialName,
+ // materialModel: item.materialModel,
+ demandedQuantity: item.demandedQuantity,
+ unit: item.unit,
+ pickQuantity: item.pickQty,
+ batchNo: Array.isArray(item.batchNo)
+ ? item.batchNo.join(",")
+ : item.batchNo,
+ })),
+ });
+ } else {
+ await saveMaterialPickingLedger({
+ productionOrderId: props.orderRow.id,
+ productionOrderPickDto: materialTableData.value.map(item => ({
+ id: item.id,
+ // processId: item.operationName,
+ technologyOperationId: item.technologyOperationId,
+ operationName: item.operationName,
+ bom: item.bom === true,
+ productModelId: item.materialModelId,
+ // materialName: item.materialName,
+ // materialModel: item.materialModel,
+ demandedQuantity: item.demandedQuantity,
+ unit: item.unit,
+ pickQuantity: item.pickQty,
+ batchNo: Array.isArray(item.batchNo)
+ ? item.batchNo.join(",")
+ : item.batchNo,
+ })),
+ });
+ }
+
+ ElMessage({ message: "棰嗘枡鎴愬姛", type: "success" });
emit("saved");
dialogVisible.value = false;
} finally {
diff --git a/src/views/productionManagement/productionOrder/index.vue b/src/views/productionManagement/productionOrder/index.vue
index 4ecd0c9..f348aae 100644
--- a/src/views/productionManagement/productionOrder/index.vue
+++ b/src/views/productionManagement/productionOrder/index.vue
@@ -304,7 +304,7 @@
label: "鎿嶄綔",
align: "center",
fixed: "right",
- width: 340,
+ width: 360,
operation: [
{
name: "宸ヨ壓璺嚎",
@@ -337,27 +337,20 @@
showSourceData(row);
},
},
- // {
- // name: "浜у搧缁撴瀯",
- // type: "text",
- // clickFun: row => {
- // showProductStructure(row);
- // },
- // },
- // {
- // name: "棰嗘枡",
- // type: "text",
- // clickFun: row => {
- // openMaterialDialog(row);
- // },
- // },
- // {
- // name: "棰嗘枡璇︽儏",
- // type: "text",
- // clickFun: row => {
- // openMaterialDetailDialog(row);
- // },
- // },
+ {
+ name: "棰嗘枡",
+ type: "text",
+ clickFun: row => {
+ openMaterialDialog(row);
+ },
+ },
+ {
+ name: "棰嗘枡璇︽儏",
+ type: "text",
+ clickFun: row => {
+ openMaterialDetailDialog(row);
+ },
+ },
],
},
]);
diff --git a/src/views/productionManagement/workOrderManagement/components/MaterialDialog.vue b/src/views/productionManagement/workOrderManagement/components/MaterialDialog.vue
index 575d888..45944b5 100644
--- a/src/views/productionManagement/workOrderManagement/components/MaterialDialog.vue
+++ b/src/views/productionManagement/workOrderManagement/components/MaterialDialog.vue
@@ -1,86 +1,119 @@
<template>
<div>
- <el-dialog
- v-model="dialogVisible"
- title="鐗╂枡"
- width="1200px"
- @close="handleCloseMaterialDialog"
- >
- <el-table v-loading="materialTableLoading" :data="materialTableData" border row-key="id">
- <el-table-column label="宸ュ簭鍚嶇О" prop="processName" min-width="140" />
- <el-table-column label="鍘熸枡鍚嶇О" prop="materialName" min-width="140" />
- <el-table-column label="鍘熸枡鍨嬪彿" prop="materialModel" min-width="140" />
- <el-table-column label="璁¢噺鍗曚綅" prop="unit" min-width="100" />
- <el-table-column label="绾胯竟浠撴暟閲�" prop="pickQty" min-width="100" />
- <el-table-column label="琛ユ枡鏁伴噺" prop="supplementQty" min-width="100" />
- <el-table-column label="瀹為檯鏁伴噺" min-width="140">
+ <el-dialog v-model="dialogVisible"
+ title="鐗╂枡"
+ width="1200px"
+ @close="handleCloseMaterialDialog">
+ <el-table v-loading="materialTableLoading"
+ :data="materialTableData"
+ border
+ row-key="id">
+ <el-table-column label="宸ュ簭鍚嶇О"
+ prop="processName"
+ min-width="140" />
+ <el-table-column label="鍘熸枡鍚嶇О"
+ prop="materialName"
+ min-width="140" />
+ <el-table-column label="鍘熸枡鍨嬪彿"
+ prop="materialModel"
+ min-width="140" />
+ <el-table-column label="璁¢噺鍗曚綅"
+ prop="unit"
+ min-width="100" />
+ <el-table-column label="绾胯竟浠撴暟閲�"
+ prop="pickQty"
+ min-width="100" />
+ <el-table-column label="琛ユ枡鏁伴噺"
+ prop="supplementQty"
+ min-width="100" />
+ <el-table-column label="瀹為檯鏁伴噺"
+ min-width="140">
<template #default="{ row }">
- <el-input-number
- v-model="row.actualQty"
- :min="0"
- :precision="3"
- :step="1"
- controls-position="right"
- style="width: 100%;"
- />
+ <el-input-number v-model="row.actualQty"
+ :min="0"
+ :precision="3"
+ :step="1"
+ controls-position="right"
+ style="width: 100%;" />
</template>
</el-table-column>
- <el-table-column label="鎿嶄綔" align="center" fixed="right" width="180">
+ <el-table-column label="鎿嶄綔"
+ align="center"
+ fixed="right"
+ width="180">
<template #default="{ row }">
- <el-button type="primary" link @click="openSupplementDialog(row)">琛ユ枡</el-button>
- <el-button type="info" link @click="openSupplementRecordDialog(row)">琛ユ枡璁板綍</el-button>
+ <el-button type="primary"
+ link
+ @click="openSupplementDialog(row)">琛ユ枡</el-button>
+ <el-button type="info"
+ link
+ @click="openSupplementRecordDialog(row)">琛ユ枡璁板綍</el-button>
</template>
</el-table-column>
</el-table>
<template #footer>
<span class="dialog-footer">
- <el-button type="primary" :loading="pickSubmitting" @click="handleSubmitPick">棰嗙敤</el-button>
+ <el-button type="primary"
+ :loading="pickSubmitting"
+ @click="handleSubmitPick">棰嗙敤</el-button>
<el-button @click="dialogVisible = false">鍙栨秷</el-button>
</span>
</template>
</el-dialog>
-
- <FormDialog
- v-model="supplementDialogVisible"
- title="琛ユ枡"
- width="500px"
- @confirm="handleSubmitSupplement"
- >
- <el-form ref="supplementFormRef" :model="supplementForm" :rules="supplementRules" label-width="100px">
- <el-form-item label="琛ユ枡鏁伴噺" prop="supplementQty">
- <el-input-number
- v-model="supplementForm.supplementQty"
- :min="0.001"
- :precision="3"
- :step="1"
- style="width: 100%;"
- />
+ <FormDialog v-model="supplementDialogVisible"
+ title="琛ユ枡"
+ width="500px"
+ @confirm="handleSubmitSupplement">
+ <el-form ref="supplementFormRef"
+ :model="supplementForm"
+ :rules="supplementRules"
+ label-width="100px">
+ <el-form-item label="琛ユ枡鏁伴噺"
+ prop="supplementQty">
+ <el-input-number v-model="supplementForm.supplementQty"
+ :min="0.001"
+ :precision="3"
+ :step="1"
+ style="width: 100%;" />
</el-form-item>
- <el-form-item label="琛ユ枡鍘熷洜" prop="supplementReason">
- <el-input
- v-model="supplementForm.supplementReason"
- type="textarea"
- :rows="3"
- maxlength="200"
- show-word-limit
- placeholder="璇疯緭鍏ヨˉ鏂欏師鍥�"
- />
+ <el-form-item label="琛ユ枡鍘熷洜"
+ prop="supplementReason">
+ <el-input v-model="supplementForm.supplementReason"
+ type="textarea"
+ :rows="3"
+ maxlength="200"
+ show-word-limit
+ placeholder="璇疯緭鍏ヨˉ鏂欏師鍥�" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
- <el-button type="primary" :loading="supplementSubmitting" @click="handleSubmitSupplement">纭畾</el-button>
+ <el-button type="primary"
+ :loading="supplementSubmitting"
+ @click="handleSubmitSupplement">纭畾</el-button>
<el-button @click="supplementDialogVisible = false">鍙栨秷</el-button>
</span>
</template>
</FormDialog>
-
- <el-dialog v-model="supplementRecordDialogVisible" title="琛ユ枡璁板綍" width="900px">
- <el-table v-loading="supplementRecordLoading" :data="supplementRecordTableData" border row-key="id">
- <el-table-column label="琛ユ枡鏁伴噺" prop="supplementQty" min-width="100" />
- <el-table-column label="琛ユ枡鍘熷洜" prop="supplementReason" min-width="200" />
- <el-table-column label="琛ユ枡浜�" prop="supplementUserName" min-width="120" />
- <el-table-column label="琛ユ枡鏃ユ湡" prop="supplementTime" min-width="160" />
+ <el-dialog v-model="supplementRecordDialogVisible"
+ title="琛ユ枡璁板綍"
+ width="900px">
+ <el-table v-loading="supplementRecordLoading"
+ :data="supplementRecordTableData"
+ border
+ row-key="id">
+ <el-table-column label="琛ユ枡鏁伴噺"
+ prop="supplementQty"
+ min-width="100" />
+ <el-table-column label="琛ユ枡鍘熷洜"
+ prop="supplementReason"
+ min-width="200" />
+ <el-table-column label="琛ユ枡浜�"
+ prop="supplementUserName"
+ min-width="120" />
+ <el-table-column label="琛ユ枡鏃ユ湡"
+ prop="supplementTime"
+ min-width="160" />
</el-table>
<template #footer>
<span class="dialog-footer">
@@ -92,187 +125,196 @@
</template>
<script setup>
-import { computed, nextTick, reactive, ref, watch } from "vue";
-import { ElMessage } from "element-plus";
-import FormDialog from "@/components/Dialog/FormDialog.vue";
-import {
- listWorkOrderMaterialLedger,
- addWorkOrderMaterialSupplement,
- listWorkOrderMaterialSupplementRecord,
- pickWorkOrderMaterial,
-} from "@/api/productionManagement/workOrder.js";
+ import { computed, nextTick, reactive, ref, watch } from "vue";
+ import { ElMessage } from "element-plus";
+ import FormDialog from "@/components/Dialog/FormDialog.vue";
+ import {
+ listWorkOrderMaterialLedger,
+ addWorkOrderMaterialSupplement,
+ listWorkOrderMaterialSupplementRecord,
+ pickWorkOrderMaterial,
+ } from "@/api/productionManagement/workOrder.js";
-const props = defineProps({
- modelValue: {
- type: Boolean,
- default: false,
- },
- rowData: {
- type: Object,
- default: () => null,
- },
-});
-
-const emit = defineEmits(["update:modelValue", "refresh"]);
-
-const dialogVisible = computed({
- get: () => props.modelValue,
- set: val => emit("update:modelValue", val),
-});
-
-const materialTableLoading = ref(false);
-const materialTableData = ref([]);
-const currentMaterialRow = ref(null);
-const currentMaterialOrderRow = ref(null);
-const pickSubmitting = ref(false);
-
-const supplementDialogVisible = ref(false);
-const supplementSubmitting = ref(false);
-const supplementFormRef = ref(null);
-const supplementForm = reactive({
- supplementQty: null,
- supplementReason: "",
-});
-
-const supplementRecordDialogVisible = ref(false);
-const supplementRecordLoading = ref(false);
-const supplementRecordTableData = ref([]);
-
-const supplementRules = {
- supplementQty: [{ required: true, message: "璇疯緭鍏ヨˉ鏂欐暟閲�", trigger: "blur" }],
- supplementReason: [{ required: true, message: "璇疯緭鍏ヨˉ鏂欏師鍥�", trigger: "blur" }],
-};
-const loadMaterialTable = async row => {
- if (!row?.id) return;
- currentMaterialOrderRow.value = row;
- materialTableLoading.value = true;
- materialTableData.value = [];
- try {
- const res = await listWorkOrderMaterialLedger({
- workOrderId: row.id,
- processId: row.processId,
- productProcessRouteItemId: row.productProcessRouteItemId,
- });
- materialTableData.value = res.data || [];
- } catch (e) {
- console.error("鑾峰彇鐗╂枡鍙拌处澶辫触", e);
- ElMessage.error("鑾峰彇鐗╂枡鍙拌处澶辫触");
- } finally {
- materialTableLoading.value = false;
- }
-};
-
-watch(
- () => props.modelValue,
- visible => {
- if (visible && props.rowData) {
- loadMaterialTable(props.rowData);
- }
- }
-);
-
-const handleCloseMaterialDialog = () => {
- materialTableData.value = [];
- currentMaterialRow.value = null;
- currentMaterialOrderRow.value = null;
-};
-
-const openSupplementDialog = row => {
- currentMaterialRow.value = row;
- supplementForm.supplementQty = null;
- supplementForm.supplementReason = "";
- supplementDialogVisible.value = true;
- nextTick(() => {
- supplementFormRef.value?.clearValidate();
+ const props = defineProps({
+ modelValue: {
+ type: Boolean,
+ default: false,
+ },
+ rowData: {
+ type: Object,
+ default: () => null,
+ },
});
-};
-const handleSubmitSupplement = () => {
- supplementFormRef.value?.validate(async valid => {
- if (!valid || !currentMaterialRow.value?.id) {
- ElMessage.warning("缂哄皯鐗╂枡鏄庣粏ID");
+ const emit = defineEmits(["update:modelValue", "refresh"]);
+
+ const dialogVisible = computed({
+ get: () => props.modelValue,
+ set: val => emit("update:modelValue", val),
+ });
+
+ const materialTableLoading = ref(false);
+ const materialTableData = ref([]);
+ const currentMaterialRow = ref(null);
+ const currentMaterialOrderRow = ref(null);
+ const pickSubmitting = ref(false);
+
+ const supplementDialogVisible = ref(false);
+ const supplementSubmitting = ref(false);
+ const supplementFormRef = ref(null);
+ const supplementForm = reactive({
+ supplementQty: null,
+ supplementReason: "",
+ });
+
+ const supplementRecordDialogVisible = ref(false);
+ const supplementRecordLoading = ref(false);
+ const supplementRecordTableData = ref([]);
+
+ const supplementRules = {
+ supplementQty: [
+ { required: true, message: "璇疯緭鍏ヨˉ鏂欐暟閲�", trigger: "blur" },
+ ],
+ supplementReason: [
+ { required: true, message: "璇疯緭鍏ヨˉ鏂欏師鍥�", trigger: "blur" },
+ ],
+ };
+ const loadMaterialTable = async row => {
+ if (!row?.id) return;
+ currentMaterialOrderRow.value = row;
+ materialTableLoading.value = true;
+ materialTableData.value = [];
+ try {
+ const res = await listWorkOrderMaterialLedger({
+ workOrderId: row.id,
+ processId: row.processId,
+ productProcessRouteItemId: row.productProcessRouteItemId,
+ });
+ materialTableData.value = res.data || [];
+ } catch (e) {
+ console.error("鑾峰彇鐗╂枡鍙拌处澶辫触", e);
+ ElMessage.error("鑾峰彇鐗╂枡鍙拌处澶辫触");
+ } finally {
+ materialTableLoading.value = false;
+ }
+ };
+
+ watch(
+ () => props.modelValue,
+ visible => {
+ if (visible && props.rowData) {
+ loadMaterialTable(props.rowData);
+ }
+ }
+ );
+
+ const handleCloseMaterialDialog = () => {
+ materialTableData.value = [];
+ currentMaterialRow.value = null;
+ currentMaterialOrderRow.value = null;
+ };
+
+ const openSupplementDialog = row => {
+ currentMaterialRow.value = row;
+ supplementForm.supplementQty = null;
+ supplementForm.supplementReason = "";
+ supplementDialogVisible.value = true;
+ nextTick(() => {
+ supplementFormRef.value?.clearValidate();
+ });
+ };
+
+ const handleSubmitSupplement = () => {
+ supplementFormRef.value?.validate(async valid => {
+ if (!valid || !currentMaterialRow.value?.id) {
+ ElMessage.warning("缂哄皯鐗╂枡鏄庣粏ID");
+ return;
+ }
+ supplementSubmitting.value = true;
+ try {
+ await addWorkOrderMaterialSupplement({
+ materialLedgerId: currentMaterialRow.value.id,
+ supplementQty: Number(supplementForm.supplementQty),
+ supplementReason: supplementForm.supplementReason,
+ workOrderId: currentMaterialOrderRow.value?.id,
+ });
+ supplementDialogVisible.value = false;
+ await loadMaterialTable(currentMaterialOrderRow.value);
+ ElMessage.success("琛ユ枡鎴愬姛");
+ emit("refresh");
+ } catch (e) {
+ console.error("琛ユ枡澶辫触", e);
+ ElMessage.error("琛ユ枡澶辫触");
+ } finally {
+ supplementSubmitting.value = false;
+ }
+ });
+ };
+
+ const openSupplementRecordDialog = async row => {
+ supplementRecordDialogVisible.value = true;
+ supplementRecordLoading.value = true;
+ supplementRecordTableData.value = [];
+ try {
+ const res = await listWorkOrderMaterialSupplementRecord({
+ materialLedgerId: row.id,
+ });
+ supplementRecordTableData.value = res.data || [];
+ } catch (e) {
+ console.error("鑾峰彇琛ユ枡璁板綍澶辫触", e);
+ ElMessage.error("鑾峰彇琛ユ枡璁板綍澶辫触");
+ } finally {
+ supplementRecordLoading.value = false;
+ }
+ };
+
+ const validatePickRows = () => {
+ if (materialTableData.value.length === 0) {
+ return { valid: false, message: "鏆傛棤鍙鐢ㄧ墿鏂�" };
+ }
+ const invalidRow = materialTableData.value.find(
+ item =>
+ item.actualQty === null ||
+ item.actualQty === undefined ||
+ item.actualQty === ""
+ );
+ if (invalidRow) {
+ return { valid: false, message: "璇峰~鍐欏疄闄呮暟閲忓悗鍐嶉鐢�" };
+ }
+ const exceedRow = materialTableData.value.find(item => {
+ const maxQty = Number(item.pickQty || 0) + Number(item.supplementQty || 0);
+ return Number(item.actualQty || 0) > maxQty;
+ });
+ if (exceedRow) {
+ return { valid: false, message: "瀹為檯鏁伴噺涓嶈兘澶т簬棰嗙敤鏁伴噺+琛ユ枡鏁伴噺" };
+ }
+ return { valid: true, message: "" };
+ };
+
+ const handleSubmitPick = async () => {
+ if (!currentMaterialOrderRow.value?.id) return;
+ const validateResult = validatePickRows();
+ if (!validateResult.valid) {
+ ElMessage.warning(validateResult.message);
return;
}
- supplementSubmitting.value = true;
+ pickSubmitting.value = true;
try {
- await addWorkOrderMaterialSupplement({
- materialLedgerId: currentMaterialRow.value.id,
- supplementQty: Number(supplementForm.supplementQty),
- supplementReason: supplementForm.supplementReason,
- workOrderId: currentMaterialOrderRow.value?.id,
+ await pickWorkOrderMaterial({
+ workOrderId: currentMaterialOrderRow.value.id,
+ items: materialTableData.value.map(item => ({
+ materialLedgerId: item.id,
+ actualQty: Number(item.actualQty || 0),
+ })),
});
- supplementDialogVisible.value = false;
+ ElMessage.success("棰嗙敤鎴愬姛");
await loadMaterialTable(currentMaterialOrderRow.value);
- ElMessage.success("琛ユ枡鎴愬姛");
emit("refresh");
} catch (e) {
- console.error("琛ユ枡澶辫触", e);
- ElMessage.error("琛ユ枡澶辫触");
+ console.error("棰嗙敤澶辫触", e);
+ ElMessage.error("棰嗙敤澶辫触");
} finally {
- supplementSubmitting.value = false;
+ pickSubmitting.value = false;
}
- });
-};
-
-const openSupplementRecordDialog = async row => {
- supplementRecordDialogVisible.value = true;
- supplementRecordLoading.value = true;
- supplementRecordTableData.value = [];
- try {
- const res = await listWorkOrderMaterialSupplementRecord({
- materialLedgerId: row.id,
- });
- supplementRecordTableData.value = res.data || [];
- } catch (e) {
- console.error("鑾峰彇琛ユ枡璁板綍澶辫触", e);
- ElMessage.error("鑾峰彇琛ユ枡璁板綍澶辫触");
- } finally {
- supplementRecordLoading.value = false;
- }
-};
-
-const validatePickRows = () => {
- if (materialTableData.value.length === 0) {
- return { valid: false, message: "鏆傛棤鍙鐢ㄧ墿鏂�" };
- }
- const invalidRow = materialTableData.value.find(item => item.actualQty === null || item.actualQty === undefined || item.actualQty === "");
- if (invalidRow) {
- return { valid: false, message: "璇峰~鍐欏疄闄呮暟閲忓悗鍐嶉鐢�" };
- }
- const exceedRow = materialTableData.value.find(item => {
- const maxQty = Number(item.pickQty || 0) + Number(item.supplementQty || 0);
- return Number(item.actualQty || 0) > maxQty;
- });
- if (exceedRow) {
- return { valid: false, message: "瀹為檯鏁伴噺涓嶈兘澶т簬棰嗙敤鏁伴噺+琛ユ枡鏁伴噺" };
- }
- return { valid: true, message: "" };
-};
-
-const handleSubmitPick = async () => {
- if (!currentMaterialOrderRow.value?.id) return;
- const validateResult = validatePickRows();
- if (!validateResult.valid) {
- ElMessage.warning(validateResult.message);
- return;
- }
- pickSubmitting.value = true;
- try {
- await pickWorkOrderMaterial({
- workOrderId: currentMaterialOrderRow.value.id,
- items: materialTableData.value.map(item => ({
- materialLedgerId: item.id,
- actualQty: Number(item.actualQty || 0),
- })),
- });
- ElMessage.success("棰嗙敤鎴愬姛");
- await loadMaterialTable(currentMaterialOrderRow.value);
- emit("refresh");
- } catch (e) {
- console.error("棰嗙敤澶辫触", e);
- ElMessage.error("棰嗙敤澶辫触");
- } finally {
- pickSubmitting.value = false;
- }
-};
+ };
</script>
--
Gitblit v1.9.3