From ca8dfc8a7dd8ba9b84d9a58c3c2a6d52a0c98a74 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期四, 28 五月 2026 09:48:59 +0800
Subject: [PATCH] 中兴实强new 1.生产订单补料时如果库存不足可以提交采购申请单
---
src/views/productionManagement/productionOrder/components/PurchaseRequestDialog.vue | 309 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 309 insertions(+), 0 deletions(-)
diff --git a/src/views/productionManagement/productionOrder/components/PurchaseRequestDialog.vue b/src/views/productionManagement/productionOrder/components/PurchaseRequestDialog.vue
new file mode 100644
index 0000000..88d2a28
--- /dev/null
+++ b/src/views/productionManagement/productionOrder/components/PurchaseRequestDialog.vue
@@ -0,0 +1,309 @@
+<template>
+ <div>
+ <el-dialog v-model="dialogVisible"
+ title="閲囪喘鐢宠锛堝簱瀛樹笉瓒筹級"
+ width="900px"
+ @close="handleClose">
+ <!-- 绠�鏄撻噰璐敵璇疯〃鍗� -->
+ <el-form :model="form" label-width="100px">
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="閿�鍞鍗曞彿" required>
+ <el-input v-model="form.salesContractNo" placeholder="璇疯緭鍏ラ攢鍞鍗曞彿" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鎶勯�佷汉" required>
+ <el-select v-model="form.ccUserId" placeholder="璇烽�夋嫨鎶勯�佷汉" style="width: 100%" filterable>
+ <el-option v-for="user in userOptions" :key="user.userId" :label="user.nickName" :value="user.userId" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
+
+ <!-- 浜у搧琛ㄦ牸 -->
+ <div class="purchase-request-table">
+ <div class="table-toolbar">
+ <span class="table-title">閲囪喘浜у搧鏄庣粏</span>
+ <el-button type="primary" @click="handleAddRow">鏂板浜у搧</el-button>
+ </div>
+ <el-table :data="tableData" border style="width: 100%;" max-height="400">
+ <el-table-column type="index" label="搴忓彿" width="60" align="center" />
+ <el-table-column label="浜у搧鍚嶇О" min-width="150">
+ <template #default="{ row }">
+ <el-button v-if="!row.productName" type="primary" link @click="openProductSelect(row)">
+ 閫夋嫨浜у搧
+ </el-button>
+ <span v-else>{{ row.productName }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="鍨嬪彿/瑙勬牸" min-width="150">
+ <template #default="{ row }">
+ {{ row.model || '-' }}
+ </template>
+ </el-table-column>
+ <el-table-column label="鍗曚綅" width="80" align="center">
+ <template #default="{ row }">
+ {{ row.unit || '-' }}
+ </template>
+ </el-table-column>
+ <el-table-column label="鏁伴噺" width="120">
+ <template #default="{ row }">
+ <el-input-number v-model="row.quantity" :min="1" :precision="0" :step="1" controls-position="right" style="width: 100%;" />
+ </template>
+ </el-table-column>
+ <el-table-column label="鎿嶄綔" width="80" align="center" fixed="right">
+ <template #default="{ $index }">
+ <el-button type="danger" link @click="handleDeleteRow($index)">鍒犻櫎</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
+
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button type="primary" :loading="saving" @click="handleSave">淇濆瓨鑽夌</el-button>
+ <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+ </span>
+ </template>
+ </el-dialog>
+
+ <ProductSelectDialog v-model="productSelectVisible" @confirm="handleProductConfirm" single />
+ </div>
+</template>
+
+<script setup>
+import { computed, ref, watch, onMounted } from "vue";
+import { ElMessage } from "element-plus";
+import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
+import { saveShortagePurchaseDraft } from "@/api/procurementManagement/procurementLedger.js";
+import { listUser } from "@/api/system/user.js";
+import useUserStore from "@/store/modules/user.js";
+
+const userStore = useUserStore();
+
+const props = defineProps({
+ modelValue: { type: Boolean, default: false },
+ insufficientItems: { type: Array, default: () => [] },
+ orderRow: { type: Object, default: null },
+});
+const emit = defineEmits(["update:modelValue", "saved"]);
+
+const dialogVisible = computed({
+ get: () => props.modelValue,
+ set: (val) => emit("update:modelValue", val),
+});
+
+const productSelectVisible = ref(false);
+const saving = ref(false);
+const currentSelectRowIndex = ref(-1);
+const userOptions = ref([]);
+
+// 琛ㄥ崟鏁版嵁
+const form = ref({
+ salesContractNo: "",
+ ccUserId: null,
+ ccUserName: "",
+});
+
+// 琛ㄦ牸鏁版嵁
+const tableData = ref([]);
+
+// 鑾峰彇鐢ㄦ埛鍒楄〃锛堟妱閫佷汉閫夋嫨锛�
+const getUserList = async () => {
+ try {
+ const res = await listUser({ pageSize: 1000 });
+ userOptions.value = res.rows || [];
+ } catch (error) {
+ console.error("鑾峰彇鐢ㄦ埛鍒楄〃澶辫触:", error);
+ }
+};
+
+onMounted(() => {
+ getUserList();
+});
+
+// 鐩戝惉瀵硅瘽妗嗘墦寮�锛屽垵濮嬪寲鏁版嵁
+watch(
+ () => dialogVisible.value,
+ (visible) => {
+ if (visible) {
+ initData();
+ }
+ }
+);
+
+// 鍒濆鍖栨暟鎹�
+const initData = () => {
+ // 浠庣敓浜ц鍗曚腑鑾峰彇閿�鍞鍗曞彿
+ form.value.salesContractNo = props.orderRow?.salesContractNo || "";
+ form.value.applicantId = userStore.id || "";
+ form.value.applicantName = userStore.name || "";
+ form.value.ccUserId = null;
+ form.value.ccUserName = "";
+
+ // 灏嗗簱瀛樹笉瓒崇殑浜у搧濉厖鍒拌〃鏍�
+ // 鍏煎棰嗘枡鍜岃ˉ鏂欑殑鏁版嵁缁撴瀯
+ tableData.value = props.insufficientItems.map((item) => ({
+ tempId: generateTempId(),
+ productModelId: item.materialModelId || item.productModelId,
+ productName: item.materialName || item.productName,
+ model: item.materialModel || item.model,
+ unit: item.unit,
+ quantity: Math.max(1, Math.ceil((item.demandedQuantity || 0) - (item.stockQuantity || 0))),
+ }));
+};
+
+// 鐢熸垚涓存椂ID
+let tempIdCounter = 0;
+const generateTempId = () => {
+ return `temp_${++tempIdCounter}_${Date.now()}`;
+};
+
+// 鍏抽棴瀵硅瘽妗�
+const handleClose = () => {
+ form.value = {
+ salesContractNo: "",
+ applicantId: "",
+ applicantName: "",
+ ccUserId: null,
+ ccUserName: "",
+ };
+ tableData.value = [];
+ currentSelectRowIndex.value = -1;
+};
+
+// 鏂板琛�
+const handleAddRow = () => {
+ tableData.value.push({
+ tempId: generateTempId(),
+ productModelId: null,
+ productName: "",
+ model: "",
+ unit: "",
+ quantity: 1,
+ });
+};
+
+// 鍒犻櫎琛�
+const handleDeleteRow = (index) => {
+ tableData.value.splice(index, 1);
+};
+
+// 鎵撳紑浜у搧閫夋嫨
+const openProductSelect = (row) => {
+ currentSelectRowIndex.value = tableData.value.findIndex(
+ (item) => item.tempId === row.tempId
+ );
+ productSelectVisible.value = true;
+};
+
+// 浜у搧閫夋嫨纭
+const handleProductConfirm = (products) => {
+ if (!products || products.length === 0) return;
+ const index = currentSelectRowIndex.value;
+ if (index < 0 || !tableData.value[index]) return;
+ const product = products[0];
+ const row = tableData.value[index];
+ row.productModelId = product.materialModelId || product.modelId || product.id;
+ row.productName = product.materialName || product.productName || product.name || "";
+ row.model = product.materialModel || product.model || "";
+ row.unit = product.unit || product.measureUnit || "";
+ currentSelectRowIndex.value = -1;
+ productSelectVisible.value = false;
+};
+
+// 楠岃瘉琛ㄥ崟
+const validateForm = () => {
+ if (!form.value.salesContractNo) {
+ ElMessage.warning("璇疯緭鍏ラ攢鍞鍗曞彿");
+ return false;
+ }
+ if (!form.value.ccUserId) {
+ ElMessage.warning("璇烽�夋嫨鎶勯�佷汉");
+ return false;
+ }
+ if (tableData.value.length === 0) {
+ ElMessage.warning("璇疯嚦灏戞坊鍔犱竴涓骇鍝�");
+ return false;
+ }
+ for (let i = 0; i < tableData.value.length; i++) {
+ const row = tableData.value[i];
+ if (!row.productName) {
+ ElMessage.warning(`绗�${i + 1}琛岃閫夋嫨浜у搧`);
+ return false;
+ }
+ if (!row.quantity || row.quantity <= 0) {
+ ElMessage.warning(`绗�${i + 1}琛屾暟閲忓繀椤诲ぇ浜�0`);
+ return false;
+ }
+ }
+ return true;
+};
+
+// 淇濆瓨鑽夌
+const handleSave = async () => {
+ if (!validateForm()) return;
+
+ // 鑾峰彇鎶勯�佷汉濮撳悕
+ const selectedUser = userOptions.value.find(u => u.userId === form.value.ccUserId);
+ form.value.ccUserName = selectedUser?.userName || "";
+
+ saving.value = true;
+ try {
+ // 鏋勫缓閲囪喘鑽夌鏁版嵁锛堟牴鎹仈璋冩枃妗� PurchaseLedgerDto 鏍煎紡锛�
+ const draftData = {
+ salesContractNo: form.value.salesContractNo,
+ ccUserId: form.value.ccUserId,
+ ccUserName: form.value.ccUserName,
+ // 浜у搧鏄庣粏鏁版嵁
+ productData: tableData.value.map((item) => ({
+ productModelId: item.productModelId,
+ productName: item.productName,
+ model: item.model,
+ unit: item.unit,
+ quantity: item.quantity,
+ })),
+ };
+
+ const res = await saveShortagePurchaseDraft(draftData);
+ if (res.code === 200) {
+ ElMessage.success("閲囪喘鑽夌淇濆瓨鎴愬姛锛屽凡閫氱煡鎶勯�佷汉琛ュ叏淇℃伅");
+ emit("saved", res.data); // 杩斿洖鑽夌ID
+ dialogVisible.value = false;
+ } else {
+ ElMessage.error(res.msg || "淇濆瓨澶辫触");
+ }
+ } catch (error) {
+ console.error("淇濆瓨閲囪喘鑽夌澶辫触:", error);
+ ElMessage.error("淇濆瓨澶辫触锛岃閲嶈瘯");
+ } finally {
+ saving.value = false;
+ }
+};
+</script>
+
+<style scoped lang="scss">
+.purchase-request-table {
+ margin-top: 20px;
+
+ .table-toolbar {
+ margin-bottom: 10px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+
+ .table-title {
+ font-weight: bold;
+ font-size: 14px;
+ }
+ }
+}
+
+.dialog-footer {
+ display: flex;
+ justify-content: center;
+ gap: 10px;
+}
+</style>
--
Gitblit v1.9.3