From 5f0513d0955146124c2a8dc37202caf6001f36d2 Mon Sep 17 00:00:00 2001
From: buhuazhen <hua100783@gmail.com>
Date: 星期五, 29 五月 2026 15:19:30 +0800
Subject: [PATCH] feat: 添加一键发货,自动审批通过出库,取消车牌必填项,发货完成后产品状态自己变为不足->变为已发货

---
 src/views/salesManagement/salesLedger/index.vue |  301 +++++++++++++++++++++++++++++++++++++++++++++++---
 src/api/salesManagement/deliveryLedger.js       |   18 +++
 2 files changed, 300 insertions(+), 19 deletions(-)

diff --git a/src/api/salesManagement/deliveryLedger.js b/src/api/salesManagement/deliveryLedger.js
index 4be5829..fc5d21e 100644
--- a/src/api/salesManagement/deliveryLedger.js
+++ b/src/api/salesManagement/deliveryLedger.js
@@ -45,3 +45,21 @@
   });
 }
 
+// 涓�閿彂璐� - 鑷姩瀹℃壒閫氳繃骞跺嚭搴�
+export function oneClickShipping(data) {
+  return request({
+    url: "/shippingInfo/oneClickShipping",
+    method: "post",
+    data,
+  });
+}
+
+// 鎵归噺涓�閿彂璐� - 灏嗛攢鍞彴璐︿笅鎵�鏈夋湭鍙戣揣鐨勪骇鍝佸叏閮ㄥ彂璐�
+export function batchOneClickShipping(data) {
+  return request({
+    url: "/shippingInfo/batchOneClickShipping",
+    method: "post",
+    data,
+  });
+}
+
diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index c9a3b47..b017f5f 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -51,11 +51,11 @@
 															 width="100px"
 															 align="center">
                 <template #default="scope">
-
-									<el-tag v-if="scope.row.approveStatus === 1 && (!scope.row.shippingDate || !scope.row.shippingCarNumber)"
-													type="success">鍏呰冻</el-tag>
-									<el-tag v-else-if="scope.row.approveStatus === 0 && (scope.row.shippingDate || scope.row.shippingCarNumber)"
-													type="success">宸插嚭搴�</el-tag>
+									<!-- 宸插彂璐ф樉绀哄凡鍑哄簱 -->
+									<el-tag v-if="scope.row.shippingDate" type="success">宸插嚭搴�</el-tag>
+									<!-- 鏈彂璐т笖搴撳瓨鍏呰冻 -->
+									<el-tag v-else-if="scope.row.approveStatus === 1" type="success">鍏呰冻</el-tag>
+									<!-- 鏈彂璐т笖搴撳瓨涓嶈冻 -->
 									<el-tag v-else type="danger">涓嶈冻</el-tag>
                 </template>
               </el-table-column>
@@ -93,7 +93,7 @@
               <el-table-column label="鍚◣鎬讳环(鍏�)" prop="taxInclusiveTotalPrice" :formatter="formattedNumber" />
               <el-table-column label="涓嶅惈绋庢�讳环(鍏�)" prop="taxExclusiveTotalPrice" :formatter="formattedNumber" />
             <!--鎿嶄綔-->
-              <el-table-column Width="60px" label="鎿嶄綔" align="center">
+              <el-table-column width="100px" label="鎿嶄綔" align="center">
                 <template #default="scope">
                   <el-button
                     link
@@ -715,8 +715,93 @@
 			</el-form>
 			<template #footer>
 				<div class="dialog-footer">
-					<el-button type="primary" @click="submitDelivery">纭鍙戣揣</el-button>
+					<el-button type="success" @click="submitOneClickDelivery">涓�閿彂璐�</el-button>
+					<el-button type="primary" @click="submitDelivery">鎻愪氦瀹℃壒</el-button>
 					<el-button @click="closeDeliveryDia">鍙栨秷</el-button>
+				</div>
+			</template>
+		</el-dialog>
+
+		<!-- 鎵归噺涓�閿彂璐у脊妗� -->
+		<el-dialog
+			v-model="batchDeliveryFormVisible"
+			title="鎵归噺涓�閿彂璐�"
+			width="40%"
+			@close="closeBatchDeliveryDia"
+		>
+			<el-form :model="batchDeliveryForm" label-width="120px" label-position="top" :rules="batchDeliveryRules" ref="batchDeliveryFormRef">
+				<el-row :gutter="30">
+					<el-col :span="24">
+						<el-form-item label="鍙戣揣绫诲瀷锛�" prop="type">
+							<el-select
+								v-model="batchDeliveryForm.type"
+								placeholder="璇烽�夋嫨鍙戣揣绫诲瀷"
+								style="width: 100%"
+							>
+								<el-option label="璐ц溅" value="璐ц溅" />
+								<el-option label="蹇��" value="蹇��" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row :gutter="30">
+					<el-col :span="24">
+						<el-form-item label="鍙戣揣鏃ユ湡锛�" prop="shippingDate">
+							<el-date-picker
+								style="width: 100%"
+								v-model="batchDeliveryForm.shippingDate"
+								value-format="YYYY-MM-DD"
+								format="YYYY-MM-DD"
+								type="date"
+								placeholder="璇烽�夋嫨鍙戣揣鏃ユ湡"
+								clearable
+							/>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row :gutter="30">
+					<el-col :span="24" v-if="batchDeliveryForm.type === '璐ц溅'">
+						<el-form-item label="鍙戣揣杞︾墝鍙凤細">
+							<el-input
+								v-model="batchDeliveryForm.shippingCarNumber"
+								placeholder="璇疯緭鍏ュ彂璐ц溅鐗屽彿"
+								clearable
+							/>
+						</el-form-item>
+					</el-col>
+					<el-col :span="24" v-else>
+						<el-form-item label="蹇�掑叕鍙革細">
+							<el-input
+								v-model="batchDeliveryForm.expressCompany"
+								placeholder="璇疯緭鍏ュ揩閫掑叕鍙�"
+								clearable
+							/>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row :gutter="30" v-if="batchDeliveryForm.type === '蹇��'">
+					<el-col :span="24">
+						<el-form-item label="蹇�掑崟鍙凤細">
+							<el-input
+								v-model="batchDeliveryForm.expressNumber"
+								placeholder="璇疯緭鍏ュ揩閫掑崟鍙�"
+								clearable
+							/>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-alert
+					title="鎻愮ず锛氬皢瀵硅閿�鍞彴璐︿笅鎵�鏈夋湭鍙戣揣鐨勪骇鍝佽繘琛屼竴閿彂璐э紝鑷姩瀹℃壒閫氳繃骞跺嚭搴�"
+					type="warning"
+					:closable="false"
+					show-icon
+					style="margin-top: 10px;"
+				/>
+			</el-form>
+			<template #footer>
+				<div class="dialog-footer">
+					<el-button type="success" @click="submitBatchDelivery">纭鎵归噺鍙戣揣</el-button>
+					<el-button @click="closeBatchDeliveryDia">鍙栨秷</el-button>
 				</div>
 			</template>
 		</el-dialog>
@@ -726,8 +811,9 @@
 <script setup>
 import { getToken } from "@/utils/auth";
 import pagination from "@/components/PIMTable/Pagination.vue";
-import {onMounted, ref, getCurrentInstance} from "vue";
-import { addShippingInfo } from "@/api/salesManagement/deliveryLedger.js";
+import {onMounted, ref, getCurrentInstance, h} from "vue";
+import { ElButton } from "element-plus";
+import { addShippingInfo, oneClickShipping, batchOneClickShipping } from "@/api/salesManagement/deliveryLedger.js";
 import { ElMessageBox, ElMessage } from "element-plus";
 import { UploadFilled, Download } from "@element-plus/icons-vue";
 import useUserStore from "@/store/modules/user";
@@ -871,6 +957,26 @@
 // 鍙戣揣鐩稿叧
 const deliveryFormVisible = ref(false);
 const currentDeliveryRow = ref(null);
+
+// 鎵归噺涓�閿彂璐х浉鍏�
+const batchDeliveryFormVisible = ref(false);
+const currentBatchDeliveryRow = ref(null);
+const batchDeliveryFormData = reactive({
+  batchDeliveryForm: {
+    type: "璐ц溅",
+    shippingDate: "",
+    shippingCarNumber: "",
+    expressCompany: "",
+    expressNumber: "",
+  },
+  batchDeliveryRules: {
+    type: [
+      { required: true, message: "璇烽�夋嫨鍙戣揣绫诲瀷", trigger: "change" }
+    ],
+    shippingDate: [{ required: true, message: "璇烽�夋嫨鍙戣揣鏃ユ湡", trigger: "change" }],
+  },
+});
+const { batchDeliveryForm, batchDeliveryRules } = toRefs(batchDeliveryFormData);
 const deliveryFileList = ref([]);
 const deliveryFormData = reactive({
   deliveryForm: {
@@ -895,11 +1001,9 @@
 });
 const { deliveryForm, deliveryRules } = toRefs(deliveryFormData);
 
-// 鍙戣揣绫诲瀷鏍¢獙锛氳揣杞︽椂瑕佹眰杞︾墝锛屽揩閫掓椂瑕佹眰蹇�掑叕鍙�
+// 鍙戣揣绫诲瀷鏍¢獙锛氳揣杞︽椂杞︾墝闈炲繀濉紝蹇�掓椂瑕佹眰蹇�掑叕鍙�
 const validateShippingCarNumber = (value, callback) => {
-  if (deliveryForm.value.type === "璐ц溅") {
-    if (!value) return callback(new Error("璇疯緭鍏ュ彂璐ц溅鐗屽彿"));
-  }
+  // 鍙栨秷杞︾墝蹇呭~闄愬埗
   callback();
 };
 const validateExpressCompany = (value, callback) => {
@@ -1098,6 +1202,8 @@
 const expandChange = (row, expandedRows) => {
 	if (expandedRows.length > 0) {
 		expandedRowKeys.value = [];
+		// 璁剧疆褰撳墠灞曞紑琛岋紝鐢ㄤ簬涓�閿彂璐�
+		currentExpandedRow.value = row;
 		try {
 			productList({ salesLedgerId: row.id, type: 1 }).then((res) => {
 				const index = tableData.value.findIndex((item) => item.id === row.id);
@@ -1111,6 +1217,7 @@
 		}
 	} else {
 		expandedRowKeys.value = [];
+		currentExpandedRow.value = null;
 	}
 };
 
@@ -1138,13 +1245,58 @@
 		"taxExclusiveTotalPrice",
 	]);
 };
-// 瀛愯〃鍚堣鏂规硶
+
+// 褰撳墠灞曞紑琛岀殑閿�鍞彴璐︽暟鎹紙鐢ㄤ簬涓�閿彂璐э級
+const currentExpandedRow = ref(null);
+// 褰撳墠灞曞紑琛屾槸鍚︽湁鏈彂璐т骇鍝�
+const hasUnshippedProducts = ref(false);
+
+// 瀛愯〃鍚堣鏂规硶 - 鏈�鍚庝竴鍒楁樉绀轰竴閿彂璐ф寜閽�
 const summarizeChildrenTable = (param) => {
-	return proxy.summarizeTable(param, [
-		"taxInclusiveUnitPrice",
-		"taxInclusiveTotalPrice",
-		"taxExclusiveTotalPrice",
-	]);
+	const { columns, data } = param;
+	const sums = [];
+
+	// 妫�鏌ユ槸鍚︽湁鏈彂璐х殑浜у搧
+	const unshipped = data.filter(item => {
+		const status = item.shippingStatus;
+		return !item.shippingDate && (!status || status === '寰呭彂璐�' || status === '瀹℃牳鎷掔粷');
+	});
+	hasUnshippedProducts.value = unshipped.length > 0;
+
+	columns.forEach((column, index) => {
+		if (index === 0) {
+			sums[index] = "鍚堣";
+			return;
+		}
+
+		const prop = column.property;
+		const summaryProps = ["taxInclusiveUnitPrice", "taxInclusiveTotalPrice", "taxExclusiveTotalPrice"];
+
+		if (summaryProps.includes(prop)) {
+			const values = data.map((item) => Number(item[prop]));
+			if (!values.every(isNaN)) {
+				const sum = values.reduce((acc, val) => (!isNaN(val) ? acc + val : acc), 0);
+				sums[index] = parseFloat(sum).toFixed(2);
+			} else {
+				sums[index] = "";
+			}
+		} else if (index === columns.length - 1 && currentExpandedRow.value && hasUnshippedProducts.value) {
+			// 鏈�鍚庝竴鍒楋紙鎿嶄綔鍒楋級娓叉煋涓�閿彂璐ф寜閽紝浠呭綋鏈夋湭鍙戣揣浜у搧鏃舵樉绀�
+			sums[index] = h(
+				ElButton,
+				{
+					type: 'success',
+					size: 'small',
+					onClick: () => openBatchDeliveryForm(currentExpandedRow.value)
+				},
+				{ default: () => '涓�閿彂璐�' }
+			);
+		} else {
+			sums[index] = "";
+		}
+	});
+
+	return sums;
 };
 // 鎵撳紑寮规
 const openForm = async (type, row) => {
@@ -2299,6 +2451,55 @@
   });
 };
 
+// 涓�閿彂璐� - 鑷姩瀹℃壒閫氳繃骞跺嚭搴�
+const submitOneClickDelivery = () => {
+  proxy.$refs["deliveryFormRef"].validate((valid) => {
+    if (valid) {
+      // 淇濆瓨褰撳墠灞曞紑鐨勮ID锛屼互渚垮彂璐у悗閲嶆柊鍔犺浇瀛愯〃鏍兼暟鎹�
+      const currentExpandedKeys = [...expandedRowKeys.value];
+      const salesLedgerId = currentDeliveryRow.value.salesLedgerId;
+
+      // 鑾峰彇涓婁紶鍥剧墖鐨勪复鏃禝D
+      let tempFileIds = [];
+      if (deliveryFileList.value !== null && deliveryFileList.value.length > 0) {
+        tempFileIds = deliveryFileList.value.map((item) => item.tempId);
+      }
+
+      oneClickShipping({
+        salesLedgerId: salesLedgerId,
+        salesLedgerProductId: currentDeliveryRow.value.id,
+        type: deliveryForm.value.type,
+        shippingDate: deliveryForm.value.shippingDate,
+        shippingCarNumber: deliveryForm.value.type === "璐ц溅" ? deliveryForm.value.shippingCarNumber : "",
+        expressCompany: deliveryForm.value.type === "蹇��" ? deliveryForm.value.expressCompany : "",
+        expressNumber: deliveryForm.value.type === "蹇��" ? deliveryForm.value.expressNumber : "",
+        tempFileIds: tempFileIds,
+      })
+        .then(() => {
+          proxy.$modal.msgSuccess("涓�閿彂璐ф垚鍔�");
+          closeDeliveryDia();
+          // 鍒锋柊涓昏〃鏁版嵁
+          getList().then(() => {
+            // 濡傛灉涔嬪墠鏈夊睍寮�鐨勮锛岄噸鏂板姞杞借繖浜涜鐨勫瓙琛ㄦ牸鏁版嵁
+            if (currentExpandedKeys.length > 0) {
+              const loadPromises = currentExpandedKeys.map(ledgerId => {
+                return productList({ salesLedgerId: ledgerId, type: 1 }).then((res) => {
+                  const index = tableData.value.findIndex((item) => item.id === ledgerId);
+                  if (index > -1) {
+                    tableData.value[index].children = res.data;
+                  }
+                });
+              });
+              Promise.all(loadPromises).then(() => {
+                expandedRowKeys.value = currentExpandedKeys;
+              });
+            }
+          });
+        })
+    }
+  });
+};
+
 // 鍏抽棴鍙戣揣寮规
 const closeDeliveryDia = () => {
   proxy.resetForm("deliveryFormRef");
@@ -2306,6 +2507,68 @@
   deliveryFormVisible.value = false;
   currentDeliveryRow.value = null;
 };
+
+// 鎵撳紑鎵归噺涓�閿彂璐у脊妗�
+const openBatchDeliveryForm = (row) => {
+  currentBatchDeliveryRow.value = row;
+  batchDeliveryForm.value = {
+    type: "璐ц溅",
+    shippingDate: getCurrentDate(),
+    shippingCarNumber: "",
+    expressCompany: "",
+    expressNumber: "",
+  };
+  batchDeliveryFormVisible.value = true;
+};
+
+// 鍏抽棴鎵归噺鍙戣揣寮规
+const closeBatchDeliveryDia = () => {
+  proxy.resetForm("batchDeliveryFormRef");
+  batchDeliveryFormVisible.value = false;
+  currentBatchDeliveryRow.value = null;
+};
+
+// 鎻愪氦鎵归噺涓�閿彂璐�
+const submitBatchDelivery = () => {
+  proxy.$refs["batchDeliveryFormRef"].validate((valid) => {
+    if (valid) {
+      // 淇濆瓨褰撳墠灞曞紑鐨勮ID
+      const currentExpandedKeys = [...expandedRowKeys.value];
+      const salesLedgerId = currentBatchDeliveryRow.value.id;
+
+      batchOneClickShipping({
+        salesLedgerId: salesLedgerId,
+        type: batchDeliveryForm.value.type,
+        shippingDate: batchDeliveryForm.value.shippingDate,
+        shippingCarNumber: batchDeliveryForm.value.type === "璐ц溅" ? batchDeliveryForm.value.shippingCarNumber : "",
+        expressCompany: batchDeliveryForm.value.type === "蹇��" ? batchDeliveryForm.value.expressCompany : "",
+        expressNumber: batchDeliveryForm.value.type === "蹇��" ? batchDeliveryForm.value.expressNumber : "",
+      })
+        .then(() => {
+          proxy.$modal.msgSuccess("鎵归噺鍙戣揣鎴愬姛");
+          closeBatchDeliveryDia();
+          // 鍒锋柊涓昏〃鏁版嵁
+          getList().then(() => {
+            // 濡傛灉涔嬪墠鏈夊睍寮�鐨勮锛岄噸鏂板姞杞借繖浜涜鐨勫瓙琛ㄦ牸鏁版嵁
+            if (currentExpandedKeys.length > 0) {
+              const loadPromises = currentExpandedKeys.map(ledgerId => {
+                return productList({ salesLedgerId: ledgerId, type: 1 }).then((res) => {
+                  const index = tableData.value.findIndex((item) => item.id === ledgerId);
+                  if (index > -1) {
+                    tableData.value[index].children = res.data;
+                  }
+                });
+              });
+              Promise.all(loadPromises).then(() => {
+                expandedRowKeys.value = currentExpandedKeys;
+              });
+            }
+          });
+        })
+    }
+  });
+};
+
 const currentFactoryName = ref("");
 const getCurrentFactoryName = async () => {
 	let res = await userStore.getInfo();

--
Gitblit v1.9.3