From 1022826db3084755348fa4169fe0d703ad3bb443 Mon Sep 17 00:00:00 2001
From: yuan <123@>
Date: 星期一, 30 三月 2026 15:20:57 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_长治_健齿齿科器材' into dev_长治_健齿齿科器材
---
src/views/productionManagement/productionOrder/MaterialRequisitionDialog.vue | 245 +++++++++++++++++++++++++++++++++++-------------
1 files changed, 176 insertions(+), 69 deletions(-)
diff --git a/src/views/productionManagement/productionOrder/MaterialRequisitionDialog.vue b/src/views/productionManagement/productionOrder/MaterialRequisitionDialog.vue
index ab3bd63..4aa002b 100644
--- a/src/views/productionManagement/productionOrder/MaterialRequisitionDialog.vue
+++ b/src/views/productionManagement/productionOrder/MaterialRequisitionDialog.vue
@@ -9,49 +9,45 @@
class="material-requisition-dialog"
>
<div class="material-requisition-form">
- <!-- 鍘熸潗鏂欏垪琛� -->
- <el-table :data="materialList" border style="width: 100%" height="65vh">
- <el-table-column type="index" label="搴忓彿" width="60" align="center" />
- <el-table-column prop="productName" label="浜у搧鍚嶇О" min-width="150" />
- <el-table-column prop="model" label="鍨嬪彿" min-width="150" />
- <!-- <el-table-column prop="batchNo" label="鎵瑰彿" min-width="150">
- <template #default="{ row }">
- <el-select
- v-model="row.batchNo"
- placeholder="璇烽�夋嫨鎵瑰彿"
- clearable
- style="width: 100%"
- >
- <el-option
- v-for="item in row.batchOptions || []"
- :key="item.batchNo"
- :label="item.batchNo"
- :value="item.batchNo"
- />
- </el-select>
- </template>
- </el-table-column> -->
- <el-table-column prop="unit" label="鍗曚綅" width="80" align="center" />
- <el-table-column prop="qualitity" label="鏁伴噺" width="100" align="center">
- <template #default="{ row }">
- {{ row.qualitity || 0 }}
- </template>
- </el-table-column>
- <el-table-column prop="requisitionQty" label="棰嗙敤鏁伴噺" width="120" align="center">
- <template #default="{ row }">
- <el-input-number
- v-model="row.requisitionQty"
- :min="0"
- :precision="2"
- :controls="false"
- :disabled="!row.qualitity || hasDrawMaterials"
- style="width: 100%"
- />
- </template>
- </el-table-column>
- <el-table-column prop="remark" label="澶囨敞" min-width="150">
- </el-table-column>
- </el-table>
+ <!-- 鍘熸潗鏂� Tab -->
+
+ <div class="operation-bar">
+ <el-button type="primary" @click="handleAdd">鏂板</el-button>
+ </div>
+ <el-table :data="materialList" border style="width: 100%" height="50vh">
+ <el-table-column type="index" label="搴忓彿" width="60" align="center" />
+ <el-table-column prop="productName" label="浜у搧鍚嶇О" min-width="150" />
+ <el-table-column prop="model" label="鍨嬪彿" min-width="150" />
+ <el-table-column prop="unit" label="鍗曚綅" width="80" align="center" />
+ <!-- <el-table-column prop="qualitity" label="鍙鐢ㄦ暟閲�" width="100" align="center">
+ <template #default="{ row }">
+ {{ row.qualitity || 0 }}
+ </template>
+ </el-table-column> -->
+ <el-table-column prop="requisitionQty" label="棰嗙敤鏁伴噺" width="120" align="center">
+ <template #default="{ row }">
+ <el-input-number
+ v-model="row.requisitionQty"
+ :min="0"
+ :max="row.qualitity || 0"
+ :precision="2"
+ :controls="false"
+ :disabled="!row.qualitity"
+ style="width: 100%"
+ />
+ </template>
+ </el-table-column>
+ <el-table-column prop="remark" label="澶囨敞" min-width="150">
+ <template #default="{ row }">
+ <el-input v-model="row.remark" placeholder="璇疯緭鍏ュ娉�" clearable />
+ </template>
+ </el-table-column>
+ <el-table-column label="鎿嶄綔" width="80" align="center">
+ <template #default="{ $index }">
+ <el-button type="danger" link @click="handleDelete($index)">鍒犻櫎</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
</div>
<template #footer>
@@ -60,13 +56,50 @@
<el-button @click="handleCancel">鍙� 娑�</el-button>
</span>
</template>
+
+ <!-- 鏂板鍘熸潗鏂欏脊绐� -->
+ <el-dialog
+ v-model="addDialogVisible"
+ title="閫夋嫨鍘熸潗鏂�"
+ width="800px"
+ top="5vh"
+ :close-on-click-modal="false"
+ append-to-body
+ >
+ <el-table
+ :data="availableMaterials"
+ border
+ style="width: 100%"
+ height="50vh"
+ @selection-change="handleSelectionChange"
+ >
+ <el-table-column type="selection" width="55" align="center" />
+ <el-table-column type="index" label="搴忓彿" width="60" align="center" />
+ <el-table-column prop="productName" label="浜у搧鍚嶇О" min-width="150" />
+ <el-table-column prop="model" label="鍨嬪彿" min-width="150" />
+ <el-table-column prop="unit" label="鍗曚綅" width="80" align="center" />
+ <!-- <el-table-column prop="qualitity" label="鍙鐢ㄦ暟閲�" width="100" align="center">
+ <template #default="{ row }">
+ {{ row.qualitity || 0 }}
+ </template>
+ </el-table-column> -->
+ </el-table>
+
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button type="primary" @click="handleAddConfirm">纭� 瀹�</el-button>
+ <el-button @click="addDialogVisible = false">鍙� 娑�</el-button>
+ </span>
+ </template>
+ </el-dialog>
</el-dialog>
</template>
<script setup>
-import { ref, reactive, computed, watch } from 'vue';
+import { ref, computed, watch } from 'vue';
import { ElMessage } from 'element-plus';
-import { getByBomId, drawMaterials } from '@/api/productionManagement/productionOrder.js';
+import { drawMaterials } from '@/api/productionManagement/productionOrder.js';
+import { getMaterials } from '@/api/inventoryManagement/stockInventory.js';
const props = defineProps({
modelValue: {
@@ -88,8 +121,13 @@
const loading = ref(false);
const saving = ref(false);
+const activeTab = ref('material');
const materialList = ref([]);
-const hasDrawMaterials = ref(false);
+
+// 鏂板寮圭獥鐩稿叧
+const addDialogVisible = ref(false);
+const availableMaterials = ref([]);
+const selectedMaterials = ref([]);
// 鐩戝惉寮规鎵撳紑锛屽姞杞芥暟鎹�
watch(() => props.modelValue, (val) => {
@@ -101,26 +139,46 @@
const loadMaterialList = async () => {
const order = props.orderData;
const drawMaterialsData = order.drawMaterials;
+ const bomId = order?.bomId;
- // 濡傛灉宸叉湁棰嗘枡鏁版嵁锛岀洿鎺ヤ娇鐢�
+ // 鍏堣幏鍙杇etMaterials鐨勬渶鏂版暟鎹�
+ let materialsFromApi = [];
+ if (bomId) {
+ try {
+ const res = await getMaterials({ bomId });
+ materialsFromApi = res.data || [];
+ } catch (error) {
+ console.error('鏌ヨ鍘熸潗鏂欏垪琛ㄥけ璐�:', error);
+ }
+ }
+
+ // 鍔犺浇宸蹭繚瀛樼殑棰嗘枡鏁版嵁
if (drawMaterialsData) {
- hasDrawMaterials.value = true;
try {
const list = typeof drawMaterialsData === 'string'
? JSON.parse(drawMaterialsData)
: drawMaterialsData;
- materialList.value = list.map(item => ({
- ...item,
- requisitionQty: item.requisitionQty || 0
- }));
- return;
+ // 鍚堝苟鏁版嵁锛氫娇鐢ˋPI鐨剄ualitity锛屼娇鐢ㄤ繚瀛樼殑requisitionQty鍜宺emark
+ materialList.value = list.map(savedItem => {
+ const apiItem = materialsFromApi.find(m => m.id === savedItem.id || m.productModelId === savedItem.productModelId);
+ return {
+ ...savedItem,
+ qualitity: apiItem?.qualitity ?? savedItem.qualitity ?? 0,
+ requisitionQty: savedItem.requisitionQty || 0
+ };
+ });
} catch (e) {
console.error('瑙f瀽棰嗘枡鏁版嵁澶辫触:', e);
+ materialList.value = [];
}
+ } else {
+ materialList.value = [];
}
+};
- // 娌℃湁棰嗘枡鏁版嵁锛岃皟鐢ㄦ帴鍙f煡璇�
- hasDrawMaterials.value = false;
+// 鎵撳紑鏂板寮圭獥
+const handleAdd = async () => {
+ const order = props.orderData;
const bomId = order?.bomId;
if (!bomId) {
ElMessage.warning('褰撳墠璁㈠崟缂哄皯BOM淇℃伅');
@@ -129,30 +187,63 @@
loading.value = true;
try {
- const res = await getByBomId({ bomId });
- const data = res.data || [];
- // 澶勭悊鏁版嵁锛屾坊鍔犻鐢ㄦ暟閲忓瓧娈靛拰鎵瑰彿閫夐」
- materialList.value = data.map(item => ({
- ...item,
- requisitionQty: item.qualitity ? 0 : 0,
- batchNo: item.batchNo || '',
- remark: item.remark || '',
- // 鎵瑰彿閫夐」锛屼粠搴撳瓨鍘熸潗鏂欎俊鎭腑鑾峰彇
- batchOptions: item.inventoryList || []
- }));
+ const res = await getMaterials({ bomId });
+ console.log('getMaterials杩斿洖鏁版嵁:', res.data);
+ // 鐩存帴灞曠ず鎵�鏈夋暟鎹紝涓嶈繃婊�
+ availableMaterials.value = res.data || [];
+ selectedMaterials.value = [];
+ addDialogVisible.value = true;
} catch (error) {
console.error('鏌ヨ鍘熸潗鏂欏垪琛ㄥけ璐�:', error);
ElMessage.error('鏌ヨ鍘熸潗鏂欏垪琛ㄥけ璐�');
- materialList.value = [];
} finally {
loading.value = false;
}
};
+// 閫夋嫨鍙樺寲
+const handleSelectionChange = (selection) => {
+ selectedMaterials.value = selection;
+};
+
+// 纭娣诲姞
+const handleAddConfirm = () => {
+ if (selectedMaterials.value.length === 0) {
+ ElMessage.warning('璇烽�夋嫨鑷冲皯涓�鏉¤褰�');
+ return;
+ }
+
+ // 杩囨护鎺夊凡瀛樺湪鐨勶紙閫氳繃id鍜宲roductModelId鍒ゆ柇锛�
+ const existingIds = materialList.value.map(item => item.id);
+ const existingProductModelIds = materialList.value.map(item => item.productModelId);
+
+ const newItems = selectedMaterials.value
+ .filter(item => !existingIds.includes(item.id) && !existingProductModelIds.includes(item.productModelId))
+ .map(item => ({
+ ...item,
+ requisitionQty: 0,
+ remark: ''
+ }));
+
+ if (newItems.length === 0) {
+ ElMessage.warning('鎵�閫夋暟鎹凡瀛樺湪锛屾棤闇�閲嶅娣诲姞');
+ return;
+ }
+
+ materialList.value = [...materialList.value, ...newItems];
+ addDialogVisible.value = false;
+ ElMessage.success(`鎴愬姛娣诲姞 ${newItems.length} 鏉¤褰昤);
+};
+
+// 鍒犻櫎
+const handleDelete = (index) => {
+ materialList.value.splice(index, 1);
+};
+
const handleCancel = () => {
visible.value = false;
materialList.value = [];
- hasDrawMaterials.value = false;
+ activeTab.value = 'material';
};
const handleConfirm = async () => {
@@ -178,7 +269,7 @@
ElMessage.success('棰嗘枡淇濆瓨鎴愬姛');
visible.value = false;
materialList.value = [];
- hasDrawMaterials.value = false;
+ activeTab.value = 'material';
} catch (error) {
console.error('淇濆瓨棰嗘枡澶辫触:', error);
ElMessage.error('淇濆瓨棰嗘枡澶辫触');
@@ -190,6 +281,14 @@
<style scoped lang="scss">
.material-requisition-form {
+ .operation-bar {
+ margin-bottom: 15px;
+ }
+
+ .el-tabs {
+ height: 100%;
+ }
+
.el-table {
margin-top: 10px;
}
@@ -223,4 +322,12 @@
padding: 15px 20px;
border-top: 1px solid #e4e7ed;
}
+
+:deep(.el-tabs__content) {
+ height: calc(100% - 55px);
+}
+
+:deep(.el-tab-pane) {
+ height: 100%;
+}
</style>
--
Gitblit v1.9.3