From a8d694d5d987892afee5a1bb8f6c01d612e6b2a3 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期四, 14 五月 2026 11:23:23 +0800
Subject: [PATCH] 浪潮 1.入库管理、出库管理添加库位相关字段和逻辑
---
src/views/inventoryManagement/dispatchLog/Record.vue | 169 ++++++++++++++++++++-------
src/views/inventoryManagement/stockManagement/New.vue | 65 ++++++++--
src/components/PIMTable/PIMTable.vue | 59 +++++++++
src/views/inventoryManagement/stockManagement/Record.vue | 1
src/views/inventoryManagement/receiptManagement/Record.vue | 65 +++++-----
5 files changed, 271 insertions(+), 88 deletions(-)
diff --git a/src/components/PIMTable/PIMTable.vue b/src/components/PIMTable/PIMTable.vue
index f99b1eb..e256832 100644
--- a/src/components/PIMTable/PIMTable.vue
+++ b/src/components/PIMTable/PIMTable.vue
@@ -14,6 +14,10 @@
:expand-row-keys="expandRowKeys"
:show-summary="isShowSummary"
:summary-method="summaryMethod"
+ :default-expand-all="defaultExpandAll"
+ :tree-props="treeProps"
+ :lazy="lazy"
+ :load="load"
@row-click="rowClick"
@current-change="currentChange"
@selection-change="handleSelectionChange"
@@ -316,6 +320,22 @@
type: [String, Object],
default: () => ({ width: "100%" }),
},
+ defaultExpandAll: {
+ type: Boolean,
+ default: false,
+ },
+ treeProps: {
+ type: Object,
+ default: () => ({ children: "children", hasChildren: "hasChildren" }),
+ },
+ lazy: {
+ type: Boolean,
+ default: false,
+ },
+ load: {
+ type: Function,
+ default: null,
+ },
});
const mergedHeaderCellStyle = computed(() => ({
@@ -326,6 +346,7 @@
}));
// Data
+ const multipleTable = ref(null);
const uploadRefs = ref([]);
const currentFiles = ref({});
const uploadKeys = ref({});
@@ -499,6 +520,44 @@
const handleSelectionChange = newSelection => {
emit("selection-change", newSelection);
};
+
+ // 灞曞紑/鎶樺彔鏍戝舰鑺傜偣
+ const toggleRowExpansion = (row, expanded) => {
+ multipleTable.value?.toggleRowExpansion(row, expanded);
+ };
+
+ // 灞曞紑鎵�鏈夋爲褰㈣妭鐐�
+ const expandAll = () => {
+ const expandRows = (rows) => {
+ rows?.forEach(row => {
+ if (row[props.treeProps.children]?.length > 0) {
+ multipleTable.value?.toggleRowExpansion(row, true);
+ expandRows(row[props.treeProps.children]);
+ }
+ });
+ };
+ expandRows(props.tableData);
+ };
+
+ // 鎶樺彔鎵�鏈夋爲褰㈣妭鐐�
+ const collapseAll = () => {
+ const collapseRows = (rows) => {
+ rows?.forEach(row => {
+ if (row[props.treeProps.children]?.length > 0) {
+ collapseRows(row[props.treeProps.children]);
+ multipleTable.value?.toggleRowExpansion(row, false);
+ }
+ });
+ };
+ collapseRows(props.tableData);
+ };
+
+ defineExpose({
+ toggleRowExpansion,
+ expandAll,
+ collapseAll,
+ multipleTable
+ });
</script>
<style scoped lang="scss">
diff --git a/src/views/inventoryManagement/dispatchLog/Record.vue b/src/views/inventoryManagement/dispatchLog/Record.vue
index 724f561..7ba8dfd 100644
--- a/src/views/inventoryManagement/dispatchLog/Record.vue
+++ b/src/views/inventoryManagement/dispatchLog/Record.vue
@@ -68,6 +68,7 @@
show-overflow-tooltip
/>
<el-table-column label="瑙勬牸鍨嬪彿" prop="model" show-overflow-tooltip />
+ <el-table-column label="搴撲綅" prop="warehouseName" show-overflow-tooltip />
<el-table-column label="鎵瑰彿" prop="batchNo" show-overflow-tooltip />
<el-table-column label="鍗曚綅" prop="unit" show-overflow-tooltip />
<el-table-column
@@ -148,48 +149,26 @@
prop="unit">
<el-input v-model="formState.unit" disabled />
</el-form-item>
- <el-form-item label="搴撳瓨绫诲瀷"
- prop="type"
+ <el-form-item label="浠撳簱"
+ prop="warehouseId"
:rules="[
{
required: true,
- message: '璇烽�夋嫨搴撳瓨绫诲瀷',
+ message: '璇烽�夋嫨浠撳簱',
trigger: 'change',
}
]">
- <el-select v-model="formState.type"
- placeholder="璇烽�夋嫨搴撳瓨绫诲瀷"
- :disabled="isEdit">
- <el-option label="鍚堟牸搴撳瓨"
- value="qualified" />
- <el-option label="涓嶅悎鏍煎簱瀛�"
- value="unqualified" />
+ <el-select v-model="formState.warehouseId"
+ placeholder="璇烽�夋嫨浠撳簱"
+ clearable
+ :disabled="isEdit || !formState.productId"
+ @change="handleWarehouseChange"
+ style="width: 100%">
+ <el-option v-for="warehouse in warehouseList"
+ :key="warehouse.id"
+ :label="warehouse.name"
+ :value="warehouse.id" />
</el-select>
- </el-form-item>
- <el-form-item label="鍑哄簱鏁伴噺"
- prop="qualitity"
- :rules="[
- {
- required: true,
- message: '璇疯緭鍏ュ嚭搴撴暟閲�',
- trigger: 'blur',
- },
- {
- validator: (rule, value, callback) => {
- if (formState.maxStock > 0 && value > formState.maxStock) {
- callback('鍑哄簱鏁伴噺涓嶈兘瓒呰繃褰撳墠鎵瑰彿搴撳瓨 ' + formState.maxStock);
- } else {
- callback();
- }
- },
- trigger: 'blur',
- }
- ]">
- <el-input-number v-model="formState.qualitity"
- :step="1"
- :min="1"
- :max="formState.maxStock > 0 ? formState.maxStock : undefined"
- style="width: 100%" />
</el-form-item>
<el-form-item label="鎵瑰彿"
prop="batchNo"
@@ -217,6 +196,31 @@
prop="currentStock">
<el-input v-model="batchNoStockMap[formState.batchNo]" disabled />
</el-form-item>
+ <el-form-item label="鍑哄簱鏁伴噺"
+ prop="qualitity"
+ :rules="[
+ {
+ required: true,
+ message: '璇疯緭鍏ュ嚭搴撴暟閲�',
+ trigger: 'blur',
+ },
+ {
+ validator: (rule, value, callback) => {
+ if (formState.maxStock > 0 && value > formState.maxStock) {
+ callback('鍑哄簱鏁伴噺涓嶈兘瓒呰繃褰撳墠鎵瑰彿搴撳瓨 ' + formState.maxStock);
+ } else {
+ callback();
+ }
+ },
+ trigger: 'blur',
+ }
+ ]">
+ <el-input-number v-model="formState.qualitity"
+ :step="1"
+ :min="1"
+ :max="formState.maxStock > 0 ? formState.maxStock : undefined"
+ style="width: 100%" />
+ </el-form-item>
<el-form-item v-if="isEdit"
label="鏉ユ簮"
prop="recordType">
@@ -227,6 +231,24 @@
:key="item.value"
:label="item.label"
:value="item.value" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="搴撳瓨绫诲瀷"
+ prop="type"
+ :rules="[
+ {
+ required: true,
+ message: '璇烽�夋嫨搴撳瓨绫诲瀷',
+ trigger: 'change',
+ }
+ ]">
+ <el-select v-model="formState.type"
+ placeholder="璇烽�夋嫨搴撳瓨绫诲瀷"
+ :disabled="isEdit">
+ <el-option label="鍚堟牸搴撳瓨"
+ value="qualified" />
+ <el-option label="涓嶅悎鏍煎簱瀛�"
+ value="unqualified" />
</el-select>
</el-form-item>
<el-form-item label="澶囨敞"
@@ -270,6 +292,7 @@
} from "@/api/basicData/enum.js";
import { addStockOutRecordOnly } from "@/api/inventoryManagement/stockInventory.js";
import { addUnqualifiedStockOutRecordOnly } from "@/api/inventoryManagement/stockUninventory.js";
+import { getWarehouseList } from "@/api/inventoryManagement/warehouse.js";
const userStore = useUserStore();
const { proxy } = getCurrentInstance();
@@ -282,6 +305,10 @@
const batchNoList = ref([]);
// 鎵瑰彿搴撳瓨鏄犲皠
const batchNoStockMap = ref({});
+// 浠撳簱鍒楄〃
+const warehouseList = ref([]);
+// 鍘熷batchNoMaps鏁版嵁
+const rawBatchNoMaps = ref({});
const page = reactive({
current: 1,
size: 100,
@@ -330,6 +357,7 @@
productName: "",
productModelName: "",
unit: "",
+ warehouseId: null, // 浠撳簱ID
type: undefined,
qualitity: 0,
batchNo: null,
@@ -476,6 +504,7 @@
productName: "",
productModelName: "",
unit: "",
+ warehouseId: null,
type: undefined,
qualitity: 0,
batchNo: null,
@@ -483,14 +512,29 @@
remark: "",
maxStock: 0,
};
+ warehouseList.value = [];
batchNoList.value = [];
batchNoStockMap.value = {};
+ rawBatchNoMaps.value = {};
};
// 鍏抽棴瀵硅瘽妗�
const closeDialog = () => {
dialogVisible.value = false;
resetForm();
+};
+
+// 鍔犺浇浠撳簱鍒楄〃
+const loadWarehouseList = async () => {
+ try {
+ const res = await getWarehouseList();
+ if (res.code === 200) {
+ return res.data || [];
+ }
+ } catch (error) {
+ console.error('鍔犺浇浠撳簱鍒楄〃澶辫触', error);
+ }
+ return [];
};
// 浜у搧閫夋嫨澶勭悊
@@ -502,23 +546,60 @@
formState.value.productModelName = product.model;
formState.value.productModelId = product.id;
formState.value.unit = product.unit;
- // 浠巄atchNoMaps鑾峰彇鎵瑰彿鍒楄〃鍜屽簱瀛�
- if (product.batchNoMaps && Object.keys(product.batchNoMaps).length > 0) {
- batchNoList.value = Object.keys(product.batchNoMaps);
- batchNoStockMap.value = product.batchNoMaps;
- } else {
- batchNoList.value = [];
- batchNoStockMap.value = {};
- }
- // 娓呯┖宸查�夋嫨鐨勬壒鍙峰拰鏈�澶у簱瀛�
+ // 瑙f瀽batchNoMaps鏁版嵁锛屾牸寮忎负锛歿 浠撳簱ID: [{鎵瑰彿: 搴撳瓨}, {鎵瑰彿: 搴撳瓨}] }
+ warehouseList.value = [];
+ batchNoList.value = [];
+ batchNoStockMap.value = {};
+ rawBatchNoMaps.value = {};
+ formState.value.warehouseId = null;
formState.value.batchNo = null;
formState.value.maxStock = 0;
+
+ if (product.batchNoMaps && Object.keys(product.batchNoMaps).length > 0) {
+ rawBatchNoMaps.value = product.batchNoMaps;
+ // 鑾峰彇鎵�鏈変粨搴撲俊鎭敤浜庡弽鏄惧悕绉�
+ const allWarehouses = await loadWarehouseList();
+ const warehouseMap = {};
+ allWarehouses.forEach(w => {
+ warehouseMap[w.id] = w.warehouseName || w.name || w.warehouseCode || `浠撳簱${w.id}`;
+ });
+ // 鏋勫缓浠撳簱鍒楄〃
+ warehouseList.value = Object.keys(product.batchNoMaps).map(warehouseId => ({
+ id: warehouseId,
+ name: warehouseMap[warehouseId] || `浠撳簱${warehouseId}`
+ }));
+ }
showProductSelect.value = false;
// 瑙﹀彂琛ㄥ崟楠岃瘉鏇存柊
proxy.$refs["formRef"]?.validateField("productModelId");
}
};
+// 浠撳簱閫夋嫨鍙樺寲澶勭悊
+const handleWarehouseChange = (warehouseId) => {
+ batchNoList.value = [];
+ batchNoStockMap.value = {};
+ formState.value.batchNo = null;
+ formState.value.maxStock = 0;
+
+ if (warehouseId && rawBatchNoMaps.value[warehouseId]) {
+ // 瑙f瀽璇ヤ粨搴撲笅鐨勬壒鍙锋暟鎹紝鏍煎紡涓猴細[{鎵瑰彿: 搴撳瓨}, {鎵瑰彿: 搴撳瓨}]
+ const batchArray = rawBatchNoMaps.value[warehouseId];
+ const batchMap = {};
+ const batches = [];
+
+ batchArray.forEach(item => {
+ const batchNo = Object.keys(item)[0];
+ const stock = item[batchNo];
+ batches.push(batchNo);
+ batchMap[batchNo] = stock;
+ });
+
+ batchNoList.value = batches;
+ batchNoStockMap.value = batchMap;
+ }
+};
+
// 鎵瑰彿閫夋嫨鍙樺寲澶勭悊
const handleBatchNoChange = (batchNo) => {
if (batchNo && batchNoStockMap.value[batchNo]) {
diff --git a/src/views/inventoryManagement/receiptManagement/Record.vue b/src/views/inventoryManagement/receiptManagement/Record.vue
index 8e51b13..929b2a0 100644
--- a/src/views/inventoryManagement/receiptManagement/Record.vue
+++ b/src/views/inventoryManagement/receiptManagement/Record.vue
@@ -70,6 +70,9 @@
<el-table-column label="瑙勬牸鍨嬪彿"
prop="model"
show-overflow-tooltip/>
+ <el-table-column label="搴撲綅"
+ prop="warehouseName"
+ show-overflow-tooltip/>
<el-table-column label="鎵瑰彿"
prop="batchNo"
show-overflow-tooltip/>
@@ -149,37 +152,6 @@
prop="unit">
<el-input v-model="formState.unit" disabled />
</el-form-item>
- <el-form-item label="搴撳瓨绫诲瀷"
- prop="type"
- :rules="[
- {
- required: true,
- message: '璇烽�夋嫨搴撳瓨绫诲瀷',
- trigger: 'change',
- }
- ]">
- <el-select v-model="formState.type"
- placeholder="璇烽�夋嫨搴撳瓨绫诲瀷"
- :disabled="isEdit">
- <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>
- <el-form-item label="鎵瑰彿"
- prop="batchNo">
- <el-input v-model="formState.batchNo"
- placeholder="璇疯緭鍏ユ壒鍙�"
- :disabled="isEdit" />
- </el-form-item>
<el-form-item label="搴撲綅"
prop="warehouseId"
:rules="[
@@ -198,6 +170,19 @@
:label="warehouse.warehouseName + ' - ' + warehouse.location"
:value="warehouse.id" />
</el-select>
+ </el-form-item>
+ <el-form-item label="鎵瑰彿"
+ prop="batchNo">
+ <el-input v-model="formState.batchNo"
+ placeholder="璇疯緭鍏ユ壒鍙�"
+ :disabled="isEdit" />
+ </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>
<el-form-item v-if="isEdit"
label="鏉ユ簮"
@@ -220,6 +205,24 @@
:max="formState.qualitity"
style="width: 100%" />
</el-form-item>
+ <el-form-item label="搴撳瓨绫诲瀷"
+ prop="type"
+ :rules="[
+ {
+ required: true,
+ message: '璇烽�夋嫨搴撳瓨绫诲瀷',
+ trigger: 'change',
+ }
+ ]">
+ <el-select v-model="formState.type"
+ placeholder="璇烽�夋嫨搴撳瓨绫诲瀷"
+ :disabled="isEdit">
+ <el-option label="鍚堟牸搴撳瓨"
+ value="qualified" />
+ <el-option label="涓嶅悎鏍煎簱瀛�"
+ value="unqualified" />
+ </el-select>
+ </el-form-item>
<el-form-item label="澶囨敞"
prop="remark">
<el-input v-model="formState.remark"
diff --git a/src/views/inventoryManagement/stockManagement/New.vue b/src/views/inventoryManagement/stockManagement/New.vue
index 2addb95..5a22acd 100644
--- a/src/views/inventoryManagement/stockManagement/New.vue
+++ b/src/views/inventoryManagement/stockManagement/New.vue
@@ -32,6 +32,37 @@
<el-input v-model="formState.unit"
disabled />
</el-form-item>
+ <el-form-item label="搴撲綅"
+ prop="warehouseId"
+ :rules="[
+ {
+ required: true,
+ message: '璇烽�夋嫨搴撲綅',
+ trigger: 'change',
+ }
+ ]">
+ <el-select v-model="formState.warehouseId"
+ placeholder="璇烽�夋嫨搴撲綅"
+ clearable
+ style="width: 100%">
+ <el-option v-for="warehouse in warehouseList"
+ :key="warehouse.id"
+ :label="warehouse.warehouseName + ' - ' + warehouse.location"
+ :value="warehouse.id" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="鎵瑰彿"
+ prop="batchNo">
+ <el-input v-model="formState.batchNo"
+ placeholder="璇疯緭鍏ユ壒鍙�" />
+ </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>
<el-form-item label="搴撳瓨绫诲瀷"
prop="type"
:rules="[
@@ -48,18 +79,6 @@
<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>
- <el-form-item label="鎵瑰彿"
- prop="batchNo">
- <el-input v-model="formState.batchNo"
- placeholder="璇疯緭鍏ユ壒鍙�" />
</el-form-item>
<el-form-item v-if="formState.type === 'qualified'"
label="搴撳瓨棰勮鏁伴噺"
@@ -93,10 +112,11 @@
</template>
<script setup>
- import { ref, computed, watch, getCurrentInstance } from "vue";
+ import { ref, computed, watch, getCurrentInstance, onMounted } 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 { getWarehouseList } from "@/api/inventoryManagement/warehouse.js";
const props = defineProps({
visible: {
@@ -119,12 +139,16 @@
productName: "",
productModelName: "",
unit: "",
+ warehouseId: undefined,
type: undefined,
qualitity: 0,
batchNo: null,
warnNum: 0,
remark: "",
});
+
+ // 浠撳簱鍒楄〃
+ const warehouseList = ref([]);
const isShow = computed({
get() {
@@ -136,6 +160,15 @@
});
const showProductSelectDialog = ref(false);
+
+ // 鑾峰彇浠撳簱鍒楄〃
+ const fetchWarehouseList = () => {
+ getWarehouseList({ status: true }).then(res => {
+ warehouseList.value = res.data || [];
+ }).catch(() => {
+ proxy.$modal.msgError("鑾峰彇浠撳簱鍒楄〃澶辫触");
+ });
+ };
// 鎵瑰彿涓虹┖鏃惰浆涓� null
watch(
@@ -157,6 +190,7 @@
productName: "",
productModelName: "",
unit: "",
+ warehouseId: undefined,
type: undefined,
qualitity: 0,
batchNo: null,
@@ -215,6 +249,11 @@
});
};
+ // 缁勪欢鎸傝浇鏃跺姞杞戒粨搴撳垪琛�
+ onMounted(() => {
+ fetchWarehouseList();
+ });
+
defineExpose({
closeModal,
handleSubmit,
diff --git a/src/views/inventoryManagement/stockManagement/Record.vue b/src/views/inventoryManagement/stockManagement/Record.vue
index 0e16cca..cfa19ea 100644
--- a/src/views/inventoryManagement/stockManagement/Record.vue
+++ b/src/views/inventoryManagement/stockManagement/Record.vue
@@ -26,6 +26,7 @@
<el-table-column label="浜у搧澶х被" prop="productName" show-overflow-tooltip />
<el-table-column label="瑙勬牸鍨嬪彿" prop="model" show-overflow-tooltip />
<el-table-column label="鍗曚綅" prop="unit" show-overflow-tooltip />
+ <el-table-column label="搴撲綅" prop="warehouseName" show-overflow-tooltip />
<el-table-column label="鎵瑰彿" prop="batchNo" show-overflow-tooltip />
<el-table-column label="鍚堟牸搴撳瓨鏁伴噺" prop="qualifiedQuantity" show-overflow-tooltip />
<el-table-column label="涓嶅悎鏍煎簱瀛樻暟閲�" prop="unQualifiedQuantity" show-overflow-tooltip />
--
Gitblit v1.9.3