From d3840d5971aa6e1272f17acce28a5f96a8e3ab29 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期三, 13 五月 2026 15:06:23 +0800
Subject: [PATCH] 浪潮 1.添加仓库管理页面 2.入库、出库添加新增编辑功能并联调
---
src/views/inventoryManagement/dispatchLog/Record.vue | 362 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 360 insertions(+), 2 deletions(-)
diff --git a/src/views/inventoryManagement/dispatchLog/Record.vue b/src/views/inventoryManagement/dispatchLog/Record.vue
index dd47cb4..724f561 100644
--- a/src/views/inventoryManagement/dispatchLog/Record.vue
+++ b/src/views/inventoryManagement/dispatchLog/Record.vue
@@ -31,6 +31,7 @@
>
</div>
<div>
+ <el-button type="primary" @click="handleAdd">鏂板</el-button>
<el-button type="primary" @click="handleBatchApprove">瀹℃壒</el-button>
<el-button @click="handleOut">瀵煎嚭</el-button>
<el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
@@ -94,6 +95,17 @@
</el-tag>
</template>
</el-table-column>
+ <el-table-column label="鎿嶄綔" width="120" align="center" fixed="right">
+ <template #default="scope">
+ <el-button
+ v-if="scope.row.approvalStatus !== 1 && scope.row.approvalStatus !== '1' && scope.row.approvalStatus !== 'approved' && scope.row.approvalStatus !== 'APPROVED'"
+ link
+ type="primary"
+ size="small"
+ @click="handleEdit(scope.row)">缂栬緫</el-button>
+ <span v-else style="color: #999; font-size: 12px;">宸查�氳繃</span>
+ </template>
+ </el-table-column>
</el-table>
<pagination
v-show="total > 0"
@@ -104,24 +116,160 @@
@pagination="paginationChange"
/>
</div>
+
+ <!-- 鏂板/缂栬緫瀵硅瘽妗� -->
+ <el-dialog v-model="dialogVisible"
+ :title="dialogTitle"
+ width="800"
+ @close="closeDialog">
+ <el-form ref="formRef"
+ :model="formState"
+ label-width="140px"
+ label-position="top">
+ <el-form-item label="浜у搧鍚嶇О"
+ prop="productModelId"
+ :rules="[
+ {
+ required: true,
+ message: '璇烽�夋嫨浜у搧',
+ trigger: 'change',
+ }
+ ]">
+ <el-button type="primary"
+ @click="showProductSelect = 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>
+ <el-form-item label="鍗曚綅"
+ 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"
+ :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"
+ :rules="[
+ {
+ required: true,
+ message: '璇烽�夋嫨鎵瑰彿',
+ trigger: 'change',
+ }
+ ]">
+ <el-select v-model="formState.batchNo"
+ placeholder="璇烽�夋嫨鎵瑰彿"
+ clearable
+ :disabled="isEdit"
+ @change="handleBatchNoChange"
+ style="width: 100%">
+ <el-option v-for="batch in batchNoList"
+ :key="batch"
+ :label="batch + ' (搴撳瓨: ' + (batchNoStockMap[batch] || 0) + ')'"
+ :value="batch" />
+ </el-select>
+ </el-form-item>
+ <el-form-item v-if="formState.batchNo && batchNoStockMap[formState.batchNo]"
+ label="褰撳墠鎵瑰彿搴撳瓨"
+ prop="currentStock">
+ <el-input v-model="batchNoStockMap[formState.batchNo]" disabled />
+ </el-form-item>
+ <el-form-item v-if="isEdit"
+ label="鏉ユ簮"
+ prop="recordType">
+ <el-select v-model="formState.recordType"
+ placeholder="璇烽�夋嫨鏉ユ簮"
+ disabled>
+ <el-option v-for="item in stockRecordTypeOptions"
+ :key="item.value"
+ :label="item.label"
+ :value="item.value" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="澶囨敞"
+ prop="remark">
+ <el-input v-model="formState.remark"
+ type="textarea" />
+ </el-form-item>
+ </el-form>
+ <!-- 浜у搧閫夋嫨寮圭獥 -->
+ <ProductSelectDialog v-model="showProductSelect"
+ @confirm="handleProductSelect"
+ :top-product-parent-id="props.topParentProductId"
+ request-url="/basic/product/pageModelAndQua"
+ single />
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary" @click="handleSubmit">纭</el-button>
+ <el-button @click="closeDialog">鍙栨秷</el-button>
+ </div>
+ </template>
+ </el-dialog>
</div>
</template>
<script setup>
import pagination from "@/components/PIMTable/Pagination.vue";
-import { ref } from "vue";
-import { ElMessageBox } from "element-plus";
+import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
+import { ref, reactive, toRefs, computed, getCurrentInstance, watch, onMounted } from "vue";
+import { ElMessageBox, ElMessage } from "element-plus";
import useUserStore from "@/store/modules/user";
import { getCurrentDate } from "@/utils/index.js";
import {
getStockOutPage,
delPendingStockOut,
batchApproveStockOutRecords,
+ updateStockOutRecord,
} from "@/api/inventoryManagement/stockOut.js";
import {
findAllQualifiedStockOutRecordTypeOptions,
findAllUnQualifiedStockOutRecordTypeOptions,
} from "@/api/basicData/enum.js";
+import { addStockOutRecordOnly } from "@/api/inventoryManagement/stockInventory.js";
+import { addUnqualifiedStockOutRecordOnly } from "@/api/inventoryManagement/stockUninventory.js";
const userStore = useUserStore();
const { proxy } = getCurrentInstance();
@@ -130,6 +278,10 @@
const tableLoading = ref(false);
// 鏉ユ簮绫诲瀷閫夐」
const stockRecordTypeOptions = ref([]);
+// 鎵瑰彿鍒楄〃锛堜粠batchNoMaps鑾峰彇锛�
+const batchNoList = ref([]);
+// 鎵瑰彿搴撳瓨鏄犲皠
+const batchNoStockMap = ref({});
const page = reactive({
current: 1,
size: 100,
@@ -161,6 +313,40 @@
},
});
const { searchForm } = toRefs(data);
+
+// 瀵硅瘽妗嗙浉鍏�
+const dialogVisible = ref(false);
+const dialogType = ref('add'); // 'add' 鎴� 'edit'
+const dialogTitle = computed(() => dialogType.value === 'add' ? '鏂板鍑哄簱璁板綍' : '缂栬緫鍑哄簱璁板綍');
+const isEdit = computed(() => dialogType.value === 'edit');
+const formRef = ref();
+const showProductSelect = ref(false);
+
+// 琛ㄥ崟鏁版嵁
+const formState = ref({
+ id: undefined,
+ productId: undefined,
+ productModelId: undefined,
+ productName: "",
+ productModelName: "",
+ unit: "",
+ type: undefined,
+ qualitity: 0,
+ batchNo: null,
+ recordType: "",
+ remark: "",
+ maxStock: 0, // 褰撳墠閫変腑鎵瑰彿鐨勬渶澶у簱瀛�
+});
+
+// 鎵瑰彿涓虹┖鏃惰浆涓� null
+watch(
+ () => formState.value.batchNo,
+ val => {
+ if (val === "") {
+ formState.value.batchNo = null;
+ }
+ }
+);
// 鏌ヨ鍒楄〃
/** 鎼滅储鎸夐挳鎿嶄綔 */
@@ -239,6 +425,178 @@
return "warning";
};
+// 鏂板
+const handleAdd = () => {
+ dialogType.value = 'add';
+ resetForm();
+ // 鏍规嵁褰撳墠tab璁剧疆榛樿搴撳瓨绫诲瀷
+ formState.value.type = props.type === '0' ? 'qualified' : 'unqualified';
+ dialogVisible.value = true;
+};
+
+// 缂栬緫
+const handleEdit = (row) => {
+ dialogType.value = 'edit';
+ resetForm();
+ // 濉厖琛ㄥ崟鏁版嵁
+ formState.value = {
+ id: row.id,
+ productId: row.productId,
+ productModelId: row.productModelId,
+ productName: row.productName,
+ productModelName: row.model,
+ unit: row.unit,
+ type: props.type === '0' ? 'qualified' : 'unqualified',
+ qualitity: row.stockOutNum,
+ batchNo: row.batchNo,
+ recordType: row.recordType,
+ remark: row.remark || "",
+ maxStock: row.stockOutNum || 0, // 缂栬緫鏃朵娇鐢ㄥ綋鍓嶅嚭搴撴暟閲忎綔涓烘渶澶у簱瀛橈紙鍥犱负鏄慨鏀瑰凡鏈夎褰曪級
+ };
+ // 缂栬緫鏃朵粠batchNoMaps鑾峰彇鎵瑰彿鍒楄〃
+ if (row.batchNoMaps && Object.keys(row.batchNoMaps).length > 0) {
+ batchNoList.value = Object.keys(row.batchNoMaps);
+ batchNoStockMap.value = row.batchNoMaps;
+ } else if (row.batchNo) {
+ batchNoList.value = [row.batchNo];
+ batchNoStockMap.value = { [row.batchNo]: row.stockOutNum || 0 };
+ } else {
+ batchNoList.value = [];
+ batchNoStockMap.value = {};
+ }
+ dialogVisible.value = true;
+};
+
+// 閲嶇疆琛ㄥ崟
+const resetForm = () => {
+ formState.value = {
+ id: undefined,
+ productId: undefined,
+ productModelId: undefined,
+ productName: "",
+ productModelName: "",
+ unit: "",
+ type: undefined,
+ qualitity: 0,
+ batchNo: null,
+ recordType: "",
+ remark: "",
+ maxStock: 0,
+ };
+ batchNoList.value = [];
+ batchNoStockMap.value = {};
+};
+
+// 鍏抽棴瀵硅瘽妗�
+const closeDialog = () => {
+ dialogVisible.value = false;
+ resetForm();
+};
+
+// 浜у搧閫夋嫨澶勭悊
+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;
+ // 浠巄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 = {};
+ }
+ // 娓呯┖宸查�夋嫨鐨勬壒鍙峰拰鏈�澶у簱瀛�
+ formState.value.batchNo = null;
+ formState.value.maxStock = 0;
+ showProductSelect.value = false;
+ // 瑙﹀彂琛ㄥ崟楠岃瘉鏇存柊
+ proxy.$refs["formRef"]?.validateField("productModelId");
+ }
+};
+
+// 鎵瑰彿閫夋嫨鍙樺寲澶勭悊
+const handleBatchNoChange = (batchNo) => {
+ if (batchNo && batchNoStockMap.value[batchNo]) {
+ formState.value.maxStock = batchNoStockMap.value[batchNo];
+ // 濡傛灉褰撳墠鍑哄簱鏁伴噺瓒呰繃鏈�澶у簱瀛橈紝鑷姩璋冩暣涓烘渶澶у簱瀛�
+ if (formState.value.qualitity > formState.value.maxStock) {
+ formState.value.qualitity = formState.value.maxStock;
+ }
+ } else {
+ formState.value.maxStock = 0;
+ }
+};
+
+// 鎻愪氦琛ㄥ崟
+const handleSubmit = () => {
+ proxy.$refs["formRef"].validate(valid => {
+ if (valid) {
+ // 楠岃瘉鏄惁閫夋嫨浜嗕骇鍝�
+ if (!formState.value.productModelId) {
+ ElMessage.error("璇烽�夋嫨浜у搧");
+ return;
+ }
+
+ if (dialogType.value === 'add') {
+ submitAdd();
+ } else {
+ submitEdit();
+ }
+ }
+ });
+};
+
+// 鎻愪氦鏂板
+const submitAdd = () => {
+ const params = { ...formState.value };
+
+ if (formState.value.type === "qualified") {
+ addStockOutRecordOnly(params).then(res => {
+ ElMessage.success("鏂板鎴愬姛");
+ closeDialog();
+ getList();
+ }).catch(() => {
+ ElMessage.error("鏂板澶辫触");
+ });
+ } else {
+ addUnqualifiedStockOutRecordOnly(params).then(res => {
+ ElMessage.success("鏂板鎴愬姛");
+ closeDialog();
+ getList();
+ }).catch(() => {
+ ElMessage.error("鏂板澶辫触");
+ });
+ }
+};
+
+// 鎻愪氦缂栬緫
+const submitEdit = () => {
+ const params = {
+ productId: formState.value.productId,
+ productModelId: formState.value.productModelId,
+ productName: formState.value.productName,
+ model: formState.value.productModelName,
+ unit: formState.value.unit,
+ batchNo: formState.value.batchNo,
+ stockOutNum: formState.value.qualitity,
+ recordType: formState.value.recordType,
+ remark: formState.value.remark,
+ };
+
+ updateStockOutRecord(formState.value.id, params).then(() => {
+ ElMessage.success("缂栬緫鎴愬姛");
+ closeDialog();
+ getList();
+ }).catch(() => {
+ ElMessage.error("缂栬緫澶辫触");
+ });
+};
+
// 鑾峰彇鏉ユ簮绫诲瀷閫夐」
const fetchStockRecordTypeOptions = () => {
if (props.type === "0") {
--
Gitblit v1.9.3