From 6ed28fe4e3536519ed5c59dcdb06264eb5c9866e Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期一, 13 四月 2026 14:10:59 +0800
Subject: [PATCH] fix: 销售订单状态修改、发货审批修改

---
 src/views/salesManagement/salesLedger/index.vue |  433 +++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 333 insertions(+), 100 deletions(-)

diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index 6254645..3790894 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -18,6 +18,14 @@
           <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
             placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
         </el-form-item>
+        <el-form-item label="鍙戣揣鐘舵�侊細">
+          <el-select v-model="searchForm.deliveryStatus" placeholder="璇烽�夋嫨" clearable style="width: 140px">
+            <el-option label="鏈彂璐�" :value="1" />
+            <el-option label="瀹℃壒涓�" :value="2" />
+            <el-option label="瀹℃壒澶辫触" :value="3" />
+            <el-option label="宸插彂璐�" :value="4" />
+          </el-select>
+        </el-form-item>
         <el-form-item>
           <el-button type="primary" @click="handleQuery"> 鎼滅储 </el-button>
         </el-form-item>
@@ -35,28 +43,30 @@
           :bound-route-name="processFlowSelectBoundRouteName"
           @confirm="handleProcessFlowSelectConfirm"
         />
-        <div>
-          <el-button type="primary" @click="openForm('add')">
-            鏂板鍙拌处
-          </el-button>
-		  <el-button type="primary"  @click="handleBulkDelivery">
-            鍙戣揣
-          </el-button>
-          <el-button type="primary" plain @click="handleImport">瀵煎叆</el-button>
-          <el-button @click="handleOut">瀵煎嚭</el-button>
-          <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
-          <el-dropdown @command="handlePrintCommand">
-            <el-button type="primary" plain>
-              鎵撳嵃鍗曟嵁<el-icon class="el-icon--right"><ArrowDown /></el-icon>
-            </el-button>
-            <template #dropdown>
-              <el-dropdown-menu>
-                <el-dropdown-item command="finishedProcessCard">鐢熶骇娴佺▼鍗★紙鎴愬搧锛�</el-dropdown-item>
-                <el-dropdown-item command="salesOrder">閿�鍞鍗�</el-dropdown-item>
-              </el-dropdown-menu>
-            </template>
-          </el-dropdown>
-        </div>
+			<el-space wrap>
+					<el-button type="primary" @click="openForm('add')">鏂板鍙拌处</el-button>
+					<el-button type="primary" @click="handleBulkDelivery">鍙戣揣</el-button>
+					<el-button type="primary" plain @click="handleImport">瀵煎叆</el-button>
+					<el-button @click="handleOut">瀵煎嚭</el-button>
+
+					<el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
+
+					<el-dropdown @command="handlePrintCommand">
+						<el-button type="primary" plain>
+							鎵撳嵃鍗曟嵁<el-icon class="el-icon--right">
+								<ArrowDown />
+							</el-icon>
+						</el-button>
+						<template #dropdown>
+							<el-dropdown-menu>
+								<el-dropdown-item command="finishedProcessCard">鐢熶骇娴佺▼鍗★紙鎴愬搧锛�</el-dropdown-item>
+								<el-dropdown-item command="salesOrder">閿�鍞鍗�</el-dropdown-item>
+								<el-dropdown-item command="salesDeliveryNote">閿�鍞彂璐у崟</el-dropdown-item>
+							</el-dropdown-menu>
+						</template>
+					</el-dropdown>
+					<el-button type="primary" plain @click="handlePrintLabel">鎵撳嵃鏍囩</el-button>
+				</el-space>
       </div>
       <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange"
         :expand-row-keys="expandedRowKeys" :row-key="(row) => row.id" :row-class-name="tableRowClassName" show-summary style="width: 100%"
@@ -66,6 +76,7 @@
           <template #default="props">
             <el-table :data="props.row.children" border show-summary :summary-method="summarizeChildrenTable">
               <el-table-column align="center" label="搴忓彿" type="index"/>
+			<el-table-column label="妤煎眰缂栧彿" prop="floorCode" min-width="100" show-overflow-tooltip />
               <el-table-column label="浜у搧澶х被" prop="productCategory" />
               <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
               <el-table-column label="鍘氬害" prop="thickness" min-width="90">
@@ -73,6 +84,34 @@
                   {{ scope.row.thickness ?? "" }}
                 </template>
               </el-table-column>
+							<el-table-column label="瀹�(mm)" prop="width" min-width="80">
+								<template #default="scope">
+									{{ scope.row.width ?? "" }}
+								</template>
+							</el-table-column>
+							<el-table-column label="楂�(mm)" prop="height" min-width="80">
+								<template #default="scope">
+									{{ scope.row.height ?? "" }}
+								</template>
+							</el-table-column>
+							<el-table-column label="鍛ㄩ暱(cm)" prop="perimeter" min-width="90">
+								<template #default="scope">
+									{{ scope.row.perimeter ?? "" }}
+								</template>
+							</el-table-column>
+							<el-table-column label="鎬婚潰绉�(cm虏)" prop="actualTotalArea" min-width="100">
+								<template #default="scope">
+									{{ scope.row.actualTotalArea ?? "" }}
+								</template>
+							</el-table-column>
+							<el-table-column label="鍔犲伐瑕佹眰" prop="processRequirement" min-width="120"
+								show-overflow-tooltip />
+							<el-table-column label="澶囨敞" prop="remark" min-width="120" show-overflow-tooltip />
+							<el-table-column label="閲嶇" prop="heavyBox" min-width="80">
+								<template #default="scope">
+									{{ scope.row.heavyBox ?? "" }}
+								</template>
+							</el-table-column>
 							<el-table-column label="浜у搧鐘舵��"
 															 width="100px"
 															 align="center">
@@ -85,13 +124,13 @@
 									<el-tag v-else type="danger">涓嶈冻</el-tag>
                 </template>
               </el-table-column>
-							<el-table-column label="鍙戣揣鐘舵��" width="140" align="center">
+							<!-- <el-table-column label="鍙戣揣鐘舵��" width="140" align="center">
 								<template #default="scope">
 									<el-tag :type="getShippingStatusType(scope.row)" size="small">
 										{{ getShippingStatusText(scope.row) }}
 									</el-tag>
 								</template>
-							</el-table-column>
+							</el-table-column> -->
 							<el-table-column label="蹇�掑叕鍙�" prop="expressCompany" show-overflow-tooltip />
 							<el-table-column label="蹇�掑崟鍙�" prop="expressNumber" show-overflow-tooltip />
               <el-table-column label="鍙戣揣杞︾墝" minWidth="100px" align="center">
@@ -141,6 +180,16 @@
         <el-table-column label="浠樻鏂瑰紡" prop="paymentMethod" show-overflow-tooltip />
         <el-table-column label="鍚堝悓閲戦(鍏�)" prop="contractAmount" width="220" show-overflow-tooltip
           :formatter="formattedNumber" />
+		  <el-table-column label="鍙戣揣鐘舵��" width="140" align="center">
+				<template #default="scope">
+						<el-tag v-if="Number(scope.row.deliveryStatus) === 1" type="info">鏈彂璐�</el-tag>
+						<el-tag v-else-if="Number(scope.row.deliveryStatus) === 2" type="warning">瀹℃壒涓�</el-tag>
+						<el-tag v-else-if="Number(scope.row.deliveryStatus) === 3" type="danger">瀹℃壒涓嶉�氳繃</el-tag>
+						<el-tag v-else-if="Number(scope.row.deliveryStatus) === 4" type="primary">瀹℃壒閫氳繃</el-tag>
+						<el-tag v-else-if="Number(scope.row.deliveryStatus) === 5" type="success">宸插彂璐�</el-tag>
+						<el-tag v-else type="info">-</el-tag>
+					</template>
+		  </el-table-column>
         <el-table-column label="褰曞叆浜�" prop="entryPersonName" width="100" show-overflow-tooltip />
         <el-table-column label="褰曞叆鏃ユ湡" prop="entryDate" width="120" show-overflow-tooltip />
         <el-table-column label="绛捐鏃ユ湡" prop="executionDate" width="120" show-overflow-tooltip />
@@ -256,6 +305,21 @@
 					<el-table-column label="鍘氬害" prop="thickness" min-width="90">
 						<template #default="scope">
 							{{ scope.row.thickness ?? "" }}
+						</template>
+					</el-table-column>
+					<el-table-column label="瀹�(mm)" prop="width" min-width="80">
+						<template #default="scope">
+							{{ scope.row.width ?? "" }}
+						</template>
+					</el-table-column>
+					<el-table-column label="楂�(mm)" prop="height" min-width="80">
+						<template #default="scope">
+							{{ scope.row.height ?? "" }}
+						</template>
+					</el-table-column>
+					<el-table-column label="闈㈢Н(m虏)" prop="actualTotalArea" min-width="100">
+						<template #default="scope">
+							{{ scope.row.actualTotalArea ?? "" }}
 						</template>
 					</el-table-column>
 					<el-table-column label="鏁伴噺" prop="quantity" />
@@ -578,7 +642,7 @@
 								style="width: 100%"
 								placeholder="璇疯緭鍏�"
 								clearable
-								@change="recalcAreaTotals"
+								@change="() => { recalcAreaTotals(); calculateFromUnitPrice(true); }"
 							/>
 						</el-form-item>
 					</el-col>
@@ -675,11 +739,12 @@
 											<el-input-number
 												v-model="item.quantity"
 												:min="0"
-												:step="0.1"
-												:precision="2"
+												:step="1"
+												:precision="0"
 												style="width: 100%;"
 												placeholder="璇疯緭鍏ユ暟閲�"
 												:disabled="operationType === 'view'"
+												@change="calculateFromUnitPrice(true)"
 											/>
 										</div>
 										<el-button
@@ -891,6 +956,9 @@
 	saleProcessBind,
 	getSaleProcessBindInfo,
 	getProcessCard,
+	getSalesOrder,
+	getSalesInvoices,
+	getSalesLabel,
 } from "@/api/salesManagement/salesLedger.js";
 import { modelList, productTreeList } from "@/api/basicData/product.js";
 import useFormData from "@/hooks/useFormData.js";
@@ -898,6 +966,8 @@
 import { getCurrentDate } from "@/utils/index.js";
 import { printFinishedProcessCard } from "./components/processCardPrint.js";
 import { printSalesOrder } from "./components/salesOrderPrint.js";
+import { printSalesDeliveryNote } from "./components/salesDeliveryPrint.js";
+import { printSalesLabel } from "./components/salesLabelPrint.js";
 // import { salesLedgerProductSetProcessFlowConfig } from "@/api/salesManagement/salesProcessFlowConfig.js";
 
 const userStore = useUserStore();
@@ -935,6 +1005,7 @@
 		entryDate: null, // 褰曞叆鏃ユ湡
 		entryDateStart: undefined,
 		entryDateEnd: undefined,
+		deliveryStatus: undefined, // 鍙戣揣鐘舵�侊細1鏈彂璐� 2瀹℃壒涓� 3瀹℃壒澶辫触 4宸插彂璐�
 	},
 	form: {
 		salesContractNo: "",
@@ -1042,7 +1113,7 @@
     type: "璐ц溅", // 璐ц溅, 蹇��
   },
   deliveryRules: {
-    type: [
+    type: [	
       { required: true, message: "璇烽�夋嫨鍙戣揣绫诲瀷", trigger: "change" }
     ]
   },
@@ -1068,6 +1139,7 @@
 		otherAmountSelectOptions.value = records.map((item) => ({
 			id: item.id,
 			processName: item.processName ?? "",
+			unitPrice: item.unitPrice ?? 0,
 		}));
 	} finally {
 		otherAmountSelectOptionsLoading.value = false;
@@ -1139,6 +1211,7 @@
 		return {
 			id: s.id,
 			processName: opt?.processName ?? s.processName ?? "",
+			unitPrice: opt?.unitPrice ?? s.unitPrice ?? 0,
 			quantity: Number(s.quantity ?? 0) || 0,
 		};
 	});
@@ -1194,8 +1267,10 @@
 	productForm.value.salesProductProcessList.push({
 		id: opt.id,
 		processName: opt.processName,
+		unitPrice: opt.unitPrice ?? 0,
 		quantity: 0,
 	});
+	calculateFromUnitPrice(true);
 
 	// 閫夋嫨瀹屾垚鍚庡叧闂脊绐楋紝涓嬩竴娆″彲鍐嶆鐐瑰嚮鈥滄柊澧炩�濈户缁坊鍔�
 	otherAmountAddDialogVisible.value = false;
@@ -1210,6 +1285,7 @@
 	if (operationType.value === "view") return;
 	if (!Array.isArray(productForm.value?.salesProductProcessList)) return;
 	productForm.value.salesProductProcessList.splice(index, 1);
+	calculateFromUnitPrice(true);
 };
 
 // 鍙戣揣瀹℃壒浜鸿妭鐐癸紙浠垮崗鍚屽鎵� infoFormDia.vue锛�
@@ -1642,8 +1718,9 @@
 	productData.value = products.map((p) => {
 		const quantity = Number(p.quantity ?? 0) || 0;
 		const unitPrice = Number(p.unitPrice ?? 0) || 0;
+		const settlePieceArea = Number(p.settlePieceArea ?? 0) || 1;
 		const taxRate = "13"; // 榛樿 13%锛屼究浜庣洿鎺ユ彁浜わ紙濡傞渶鍙湪浜у搧涓嚜琛屼慨鏀癸級
-		const taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
+		const taxInclusiveTotalPrice = (unitPrice * settlePieceArea * quantity).toFixed(2);
 		const taxExclusiveTotalPrice = proxy.calculateTaxExclusiveTotalPrice(taxInclusiveTotalPrice, taxRate);
 		return {
 			// 鍙拌处瀛楁
@@ -1835,15 +1912,16 @@
 			recalcAreaTotals();
 			// 鍏朵粬閲戦鍙彁浜� {id, processName, quantity}锛堝悗绔瓧娈碉細salesProductProcessList锛�
 			productForm.value.salesProductProcessList = (Array.isArray(productForm.value.salesProductProcessList)
-				? productForm.value.salesProductProcessList
-				: []
-			)
-				.map((it) => ({
-					id: it?.id,
-					processName: it?.processName ?? "",
-					quantity: Number(it?.quantity ?? 0) || 0,
-				}))
-				.filter((it) => it.id !== null && it.id !== undefined && it.id !== "");
+			? productForm.value.salesProductProcessList
+			: []
+		)
+			.map((it) => ({
+				id: it?.id,
+				processName: it?.processName ?? "",
+				unitPrice: Number(it?.unitPrice ?? 0) || 0,
+				quantity: Number(it?.quantity ?? 0) || 0,
+			}))
+			.filter((it) => it.id !== null && it.id !== undefined && it.id !== "");
 
 			if (operationType.value === "edit") {
 				submitProductEdit();
@@ -2025,14 +2103,53 @@
 };
 
 const handlePrintCommand = async (command) => {
-	if (command !== "finishedProcessCard" && command !== "salesOrder") return;
-	if (selectedRows.value.length !== 1) {
+	if (command !== "finishedProcessCard" && command !== "salesOrder" && command !== "salesDeliveryNote") return;
+	if (command === "salesDeliveryNote") {
+		if (selectedRows.value.length === 0) {
+			proxy.$modal.msgWarning("璇疯嚦灏戦�夋嫨涓�鏉¢攢鍞彴璐︽暟鎹繘琛屾墦鍗�");
+			return;
+		}
+		const customerNames = Array.from(
+			new Set(selectedRows.value.map((item) => String(item?.customerName ?? "").trim()))
+		);
+		if (customerNames.length > 1) {
+			proxy.$modal.msgWarning("浠呮敮鎸佺浉鍚屽鎴峰悕绉扮殑閿�鍞彴璐﹀悎骞跺彂璐ф墦鍗�");
+			return;
+		}
+	} else if (selectedRows.value.length !== 1) {
 		proxy.$modal.msgWarning("璇烽�夋嫨涓�鏉¢攢鍞彴璐︽暟鎹繘琛屾墦鍗�");
 		return;
 	}
 
 	const selectedRow = selectedRows.value[0];
 	const selectedId = selectedRow?.id;
+	if (command === "salesDeliveryNote") {
+		const selectedIds = selectedRows.value
+			.map((item) => item?.id)
+			.filter((id) => id !== null && id !== undefined && id !== "");
+		if (selectedIds.length !== selectedRows.value.length) {
+			proxy.$modal.msgWarning("褰撳墠閫夋嫨鏁版嵁瀛樺湪缂哄皯ID鐨勮褰曪紝鏃犳硶鎵撳嵃");
+			return;
+		}
+		const loadingText =
+			command === "salesOrder"
+				? "姝e湪鑾峰彇閿�鍞鍗曟暟鎹紝璇风◢鍊�..."
+				: command === "salesDeliveryNote"
+					? "姝e湪鑾峰彇閿�鍞彂璐у崟鏁版嵁锛岃绋嶅��..."
+					: "姝e湪鑾峰彇鐢熶骇娴佺▼鍗℃暟鎹紝璇风◢鍊�...";
+		proxy.$modal.loading(loadingText);
+		try {
+			const res = await getSalesInvoices(selectedIds);
+			const salesInvoiceData = res?.data ?? {};
+			printSalesDeliveryNote(salesInvoiceData, selectedRow);
+		} catch (error) {
+			console.error("鎵撳嵃閿�鍞彂璐у崟澶辫触:", error);
+			proxy.$modal.msgError("鎵撳嵃澶辫触锛岃绋嶅悗閲嶈瘯");
+		} finally {
+			proxy.$modal.closeLoading();
+		}
+		return;
+	}
 	if (!selectedId) {
 		proxy.$modal.msgWarning("褰撳墠閫夋嫨鏁版嵁缂哄皯ID锛屾棤娉曟墦鍗�");
 		return;
@@ -2041,19 +2158,59 @@
 	const loadingText =
 		command === "salesOrder"
 			? "姝e湪鑾峰彇閿�鍞鍗曟暟鎹紝璇风◢鍊�..."
-			: "姝e湪鑾峰彇鐢熶骇娴佺▼鍗℃暟鎹紝璇风◢鍊�...";
+			: command === "salesDeliveryNote"
+				? "姝e湪鑾峰彇閿�鍞彂璐у崟鏁版嵁锛岃绋嶅��..."
+				: "姝e湪鑾峰彇鐢熶骇娴佺▼鍗℃暟鎹紝璇风◢鍊�...";
 	proxy.$modal.loading(loadingText);
 	try {
-		const res = await getProcessCard(selectedId);
-		const processCardData = res?.data ?? {};
 		if (command === "salesOrder") {
-			printSalesOrder(processCardData);
+			const res = await getSalesOrder(selectedId);
+			const salesOrderData = res?.data ?? {};
+			printSalesOrder(salesOrderData);
 		} else {
+			const res = await getProcessCard(selectedId);
+			const processCardData = res?.data ?? {};
 			printFinishedProcessCard(processCardData);
 		}
 	} catch (error) {
-		console.error(command === "salesOrder" ? "鎵撳嵃閿�鍞鍗曞け璐�:" : "鎵撳嵃鐢熶骇娴佺▼鍗″け璐�:", error);
+		console.error(
+			command === "salesOrder"
+				? "鎵撳嵃閿�鍞鍗曞け璐�:"
+				: command === "salesDeliveryNote"
+					? "鎵撳嵃閿�鍞彂璐у崟澶辫触:"
+					: "鎵撳嵃鐢熶骇娴佺▼鍗″け璐�:",
+			error
+		);
 		proxy.$modal.msgError("鎵撳嵃澶辫触锛岃绋嶅悗閲嶈瘯");
+	} finally {
+		proxy.$modal.closeLoading();
+	}
+};
+
+const handlePrintLabel = async () => {
+	if (selectedRows.value.length !== 1) {
+		proxy.$modal.msgWarning("璇烽�夋嫨涓�鏉¢攢鍞彴璐︽暟鎹繘琛屾爣绛炬墦鍗�");
+		return;
+	}
+
+	const selectedId = selectedRows.value[0]?.id;
+	if (!selectedId) {
+		proxy.$modal.msgWarning("褰撳墠閫夋嫨鏁版嵁缂哄皯ID锛屾棤娉曟墦鍗版爣绛�");
+		return;
+	}
+
+	proxy.$modal.loading("姝e湪鑾峰彇鏍囩鏁版嵁锛岃绋嶅��...");
+	try {
+		const res = await getSalesLabel(selectedId);
+		const labelList = res?.data ?? [];
+		if (!Array.isArray(labelList) || labelList.length === 0) {
+			proxy.$modal.msgWarning("鏆傛棤鍙墦鍗版爣绛炬暟鎹�");
+			return;
+		}
+		printSalesLabel(labelList);
+	} catch (error) {
+		console.error("鎵撳嵃鏍囩澶辫触:", error);
+		proxy.$modal.msgError("鎵撳嵃鏍囩澶辫触锛岃绋嶅悗閲嶈瘯");
 	} finally {
 		proxy.$modal.closeLoading();
 	}
@@ -2067,12 +2224,16 @@
 	if (!productForm.value.quantity) {
 		return;
 	}
-	// 鍚◣鎬讳环璁$畻
-	productForm.value.taxInclusiveTotalPrice =
-		proxy.calculateTaxIncludeTotalPrice(
-			productForm.value.taxInclusiveUnitPrice,
-			productForm.value.quantity
-		);
+	const settlePieceArea = parseFloat(productForm.value.settlePieceArea) || 1;
+	// 鍚◣鎬讳环璁$畻 = 鍗曚环 * 缁撶畻闈㈢Н * 鏁伴噺 + 鍏朵粬閲戦鎬诲拰
+	const basePrice = proxy.calculateTaxIncludeTotalPrice(
+		productForm.value.taxInclusiveUnitPrice * settlePieceArea,
+		productForm.value.quantity
+	);
+	const otherAmountTotal = (productForm.value.salesProductProcessList || []).reduce((total, item) => {
+		return total + (Number(item.unitPrice) || 0) * (Number(item.quantity) || 0);
+	}, 0);
+	productForm.value.taxInclusiveTotalPrice = (parseFloat(basePrice) + otherAmountTotal).toFixed(2);
 	if (productForm.value.taxRate) {
 		// 涓嶅惈绋庢�讳环璁$畻
 		productForm.value.taxExclusiveTotalPrice =
@@ -2133,15 +2294,12 @@
 	const computed = Number(computedPieceArea.toFixed(5));
 
 	productForm.value.actualPieceArea = computed;
-
-	// settlePieceArea锛氳嫢鐢ㄦ埛鏈~鍐�/涓�0锛屽垯榛樿浣跨敤瀹介珮璁$畻鍊�
-	const settlePieceRaw = Number(productForm.value.settlePieceArea ?? 0) || 0;
-	if (!settlePieceRaw) {
-		productForm.value.settlePieceArea = computed;
-	}
+	productForm.value.settlePieceArea = computed;
 
 	recalcPerimeterFromWidthHeight();
 	recalcAreaTotals();
+	// 闈㈢Н鏇存柊鍚庯紝閲嶆柊璁$畻鍚◣鎬讳环 = 鍗曚环 * 缁撶畻闈㈢Н * 鏁伴噺
+	calculateFromUnitPrice(true);
 };
 
 // 鏍规嵁鍚◣鎬讳环璁$畻鍚◣鍗曚环鍜屾暟閲�
@@ -2157,8 +2315,12 @@
 	
 	isCalculating.value = true;
 	
-	// 璁$畻鍚◣鍗曚环 = 鍚◣鎬讳环 / 鏁伴噺
-	productForm.value.taxInclusiveUnitPrice = (totalPrice / quantity).toFixed(2);
+	// 璁$畻鍚◣鍗曚环 = (鍚◣鎬讳环 - 鍏朵粬閲戦鎬诲拰) / 鏁伴噺
+	const otherAmountTotal = (productForm.value.salesProductProcessList || []).reduce((total, item) => {
+		return total + (Number(item.unitPrice) || 0) * (Number(item.quantity) || 0);
+	}, 0);
+	const basePrice = totalPrice - otherAmountTotal;
+	productForm.value.taxInclusiveUnitPrice = (basePrice / quantity).toFixed(2);
 	
 	// 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
 	if (productForm.value.taxRate) {
@@ -2195,8 +2357,12 @@
 	const inclusiveTotalPrice = exclusiveTotalPrice / (1 - taxRateDecimal);
 	productForm.value.taxInclusiveTotalPrice = inclusiveTotalPrice.toFixed(2);
 	
-	// 璁$畻鍚◣鍗曚环 = 鍚◣鎬讳环 / 鏁伴噺
-	productForm.value.taxInclusiveUnitPrice = (inclusiveTotalPrice / quantity).toFixed(2);
+	// 璁$畻鍚◣鍗曚环 = (鍚◣鎬讳环 - 鍏朵粬閲戦鎬诲拰) / 鏁伴噺
+	const otherAmountTotal = (productForm.value.salesProductProcessList || []).reduce((total, item) => {
+		return total + (Number(item.unitPrice) || 0) * (Number(item.quantity) || 0);
+	}, 0);
+	const basePrice = inclusiveTotalPrice - otherAmountTotal;
+	productForm.value.taxInclusiveUnitPrice = (basePrice / quantity).toFixed(2);
 	
 	isCalculating.value = false;
 };
@@ -2208,19 +2374,24 @@
 		return;
 	}
 	if (isCalculating.value) return;
-	
+
 	const quantity = parseFloat(productForm.value.quantity);
 	const unitPrice = parseFloat(productForm.value.taxInclusiveUnitPrice);
-	
+	const settlePieceArea = parseFloat(productForm.value.settlePieceArea) || 1;
+
 	if (!quantity || quantity <= 0 || !unitPrice) {
 		return;
 	}
-	
+
 	isCalculating.value = true;
-	
-	// 璁$畻鍚◣鎬讳环
-	productForm.value.taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
-	
+
+	// 璁$畻鍚◣鎬讳环 = 鍗曚环 * 缁撶畻闈㈢Н * 鏁伴噺 + 鍏朵粬閲戦鎬诲拰
+	const basePrice = unitPrice * settlePieceArea * quantity;
+	const otherAmountTotal = (productForm.value.salesProductProcessList || []).reduce((total, item) => {
+		return total + (Number(item.unitPrice) || 0) * (Number(item.quantity) || 0);
+	}, 0);
+	productForm.value.taxInclusiveTotalPrice = (basePrice + otherAmountTotal).toFixed(2);
+
 	// 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
 	if (productForm.value.taxRate) {
 		productForm.value.taxExclusiveTotalPrice =
@@ -2229,30 +2400,35 @@
 				productForm.value.taxRate
 			);
 	}
-	
+
 	isCalculating.value = false;
 };
 
 // 鏍规嵁鍚◣鍗曚环鍙樺寲璁$畻鎬讳环
-const calculateFromUnitPrice = () => {
+const calculateFromUnitPrice = (silent = false) => {
 	if (!productForm.value.taxRate) {
-		proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
+		if (!silent) proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
 		return;
 	}
 	if (isCalculating.value) return;
-	
+
 	const quantity = parseFloat(productForm.value.quantity);
 	const unitPrice = parseFloat(productForm.value.taxInclusiveUnitPrice);
-	
+	const settlePieceArea = parseFloat(productForm.value.settlePieceArea) || 1;
+
 	if (!quantity || quantity <= 0 || !unitPrice) {
 		return;
 	}
-	
+
 	isCalculating.value = true;
-	
-	// 璁$畻鍚◣鎬讳环
-	productForm.value.taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
-	
+
+	// 璁$畻鍚◣鎬讳环 = 鍗曚环 * 缁撶畻闈㈢Н * 鏁伴噺 + 鍏朵粬閲戦鎬诲拰
+	const basePrice = unitPrice * settlePieceArea * quantity;
+	const otherAmountTotal = (productForm.value.salesProductProcessList || []).reduce((total, item) => {
+		return total + (Number(item.unitPrice) || 0) * (Number(item.quantity) || 0);
+	}, 0);
+	productForm.value.taxInclusiveTotalPrice = (basePrice + otherAmountTotal).toFixed(2);
+
 	// 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
 	if (productForm.value.taxRate) {
 		productForm.value.taxExclusiveTotalPrice =
@@ -2261,7 +2437,7 @@
 				productForm.value.taxRate
 			);
 	}
-	
+
 	isCalculating.value = false;
 };
 
@@ -2359,11 +2535,23 @@
  * @param row 琛屾暟鎹�
  */
 const canShip = (row) => {
+
 	// 浜у搧鐘舵�佸繀椤绘槸鍏呰冻锛坅pproveStatus === 1锛�
 	if (row.approveStatus !== 1) {
 		return false;
 	}
 	
+	// 濡傛灉鍚庣杩斿洖浜嗗彴璐︾骇鍙戣揣鐘舵�侊紙deliveryStatus锛�
+	// 1=宸插彂璐э紝鍒欑姝㈠啀娆″彂璐�
+	const deliveryStatus = row.deliveryStatus;
+	if (
+		deliveryStatus !== null &&
+		deliveryStatus !== undefined &&
+		String(deliveryStatus).trim() !== ""
+	) {
+		if (Number(deliveryStatus) === 1) return false;
+	}
+
 	// 鑾峰彇鍙戣揣鐘舵��
 	const shippingStatus = row.shippingStatus;
 	
@@ -2381,6 +2569,44 @@
 	if (selectedRows.value.length === 0) {
 		proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
 		return;
+	}
+
+	// 鍙厑璁搞�愭湭鍙戣揣/瀹℃壒澶辫触銆戣繘鍏ュ彂璐ф祦绋�
+	const canDeliveryLedgers = selectedRows.value.filter((r) => {
+		const status = Number(r.deliveryStatus);
+		return status === 1 || status === 3;
+	});
+	if (canDeliveryLedgers.length === 0) {
+		proxy.$modal.msgWarning("浠呮湭鍙戣揣鎴栧鎵瑰け璐ョ殑鍙拌处鍙互鍙戣揣");
+		return;
+	}
+
+	// 宸插彂璐у彴璐︼細寮圭獥鎻愰啋锛屼笉鑳藉啀娆″彂璐э紙4 瑙嗕负宸插彂璐э級
+	const shippedLedgers = selectedRows.value.filter((r) => Number(r.deliveryStatus) === 4);
+	if (shippedLedgers.length === selectedRows.value.length) {
+		try {
+			await ElMessageBox.alert("鎵�閫夐攢鍞彴璐﹀潎宸插彂璐э紝涓嶈兘鍐嶆鍙戣揣銆�", "鎻愮ず", {
+				type: "warning",
+				confirmButtonText: "鐭ラ亾浜�",
+			});
+		} catch {
+			/* 鍏抽棴寮圭獥 */
+		}
+		return;
+	}
+	if (shippedLedgers.length > 0) {
+		try {
+			await ElMessageBox.alert(
+				"閫変腑鐨勯攢鍞彴璐︿腑鍖呭惈宸插彂璐ц褰曪紝宸插彂璐х殑涓嶈兘鍐嶆鍙戣揣锛岀郴缁熷皢浠呬负鏈彂璐у彴璐﹀鐞嗐��",
+				"鎻愮ず",
+				{
+					type: "warning",
+					confirmButtonText: "鐭ラ亾浜�",
+				}
+			);
+		} catch {
+			return;
+		}
 	}
 
 	const customerNames = selectedRows.value.map((r) => String(r.customerName || "").trim());
@@ -2410,14 +2636,22 @@
 	try {
 		const targets = [];
 		for (const ledger of selectedRows.value) {
+
+			//濡傛灉宸茬粡鏄�滃鎵逛腑(2)鈥濇垨鈥滃凡鍙戣揣(4)鈥濓紝鍒欒烦杩囷紝涓嶅厑璁搁噸澶嶆搷浣�
+			const status = Number(ledger.deliveryStatus);
+			if (status === 2 || status === 4) {
+				console.warn(`鍙拌处缂栧彿 ${ledger.salesContractNo} 鐘舵�佷负 ${status}锛岃烦杩囧彂璐);
+				continue;
+			}
+
 			let products = [];
 			try {
 				const res = await productList({ salesLedgerId: ledger.id, type: 1 });
 				products = res?.data || [];
-			} catch {
+			} catch (error) {
 				products = [];
+				console.error('璇锋眰鍙戠敓寮傚父', error);
 			}
-
 			for (const product of products) {
 				if (!canShip(product)) continue;
 				targets.push({
@@ -2426,7 +2660,6 @@
 				});
 			}
 		}
-
 		if (targets.length === 0) {
 			proxy.$modal.msgWarning("娌℃湁鍙彂璐х殑鏁版嵁");
 			return;
@@ -2458,14 +2691,15 @@
 	});
 }
 
-// 鎵撳紑鍙戣揣寮规
+// 鎵撳紑鍙戣揣寮规锛堝崟鏉★級
 const openDeliveryForm = (row) => {
-	// 妫�鏌ユ槸鍚﹀彲浠ュ彂璐�
-	if (!canShip(row)) {
-		proxy.$modal.msgWarning("鍙湁鍦ㄤ骇鍝佺姸鎬佹槸鍏呰冻锛屽彂璐х姸鎬佹槸寰呭彂璐ф垨瀹℃牳鎷掔粷鐨勬椂鍊欐墠鍙互鍙戣揣");
+	// 鍙厑璁搞�愭湭鍙戣揣/瀹℃壒澶辫触銆戝彂璐э紱宸插彂璐�/瀹℃壒涓笉鍏佽
+	const status = Number(row.deliveryStatus);
+	if (status !== 1 && status !== 3) {
+		proxy.$modal.msgWarning("鍙湁鍙戣揣鐘舵�佷负鏈彂璐ф垨瀹℃壒澶辫触鐨勮褰曟墠鍙互鍙戣揣");
 		return;
 	}
-	
+
 	currentDeliveryRows.value = [row];
   deliveryForm.value = {
     type: "璐ц溅",
@@ -2496,19 +2730,18 @@
         return;
       }
 
-      // 渚濇鍙戣揣锛堥伩鍏嶅苟鍙戜笅搴撳瓨鎵e噺/鐘舵�佹洿鏂颁簰鐩稿奖鍝嶏級
-      const run = async () => {
-        for (const item of targets) {
-          const salesLedgerId = item.salesLedgerId;
-          if (!salesLedgerId) continue;
-          await addShippingInfo({
-            salesLedgerId,
-            salesLedgerProductId: item.id,
-            type: deliveryForm.value.type,
-            approveUserIds,
-          });
-        }
-      };
+      // 鎸夊彴璐︾淮搴﹀幓閲嶏紝姣忎釜 salesLedgerId 鍙皟鐢ㄤ竴娆″彂璐ф帴鍙�
+      const uniqueLedgerIds = [...new Set(targets.map((item) => item.salesLedgerId).filter(Boolean))];
+
+		const run = async () => {
+			for (const salesLedgerId of uniqueLedgerIds) {
+				await addShippingInfo({
+					salesLedgerId,
+					type: deliveryForm.value.type,
+					approveUserIds,
+				});
+			}
+		};
 
       run()
         .then(() => {

--
Gitblit v1.9.3