From e43e196b3cde5ca76c2bca07045c112921963779 Mon Sep 17 00:00:00 2001
From: yyb <995253665@qq.com>
Date: 星期三, 25 三月 2026 17:00:12 +0800
Subject: [PATCH] 其他金额维护弹窗

---
 src/views/salesManagement/salesLedger/index.vue |  282 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 281 insertions(+), 1 deletions(-)

diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index ca7ab04..c6122ed 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -30,6 +30,9 @@
           <el-button type="primary" @click="openForm('add')">
             鏂板鍙拌处
           </el-button>
+          <el-button type="primary" plain @click="openOtherAmountDialog">
+            鍏朵粬閲戦缁存姢
+          </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>
@@ -647,6 +650,115 @@
 				</div>
 			</template>
 		</el-dialog>
+
+		<!-- 鍏朵粬閲戦缁存姢锛堟柊澧�/缂栬緫/鍒犻櫎锛� -->
+		<el-dialog
+			v-model="otherAmountDialogVisible"
+			title="鍏朵粬閲戦缁存姢"
+			width="80%"
+			:close-on-click-modal="false"
+			@close="closeOtherAmountDialog"
+		>
+			<el-row :gutter="20">
+				<el-col :span="14">
+					<el-table
+						:data="otherAmountRecords"
+						border
+						v-loading="otherAmountLoading"
+						height="55vh"
+					>
+						<el-table-column label="缂栫爜" prop="code" min-width="120" show-overflow-tooltip />
+						<el-table-column label="椤圭洰" prop="processName" min-width="180" show-overflow-tooltip />
+						<el-table-column label="鏁伴噺" prop="quantity" min-width="110" :formatter="formattedNumber" />
+						<el-table-column label="鍗曚环(鍏�)" prop="unitPrice" min-width="130" :formatter="formattedNumber" />
+						<el-table-column label="閲戦(鍏�)" prop="amount" min-width="160" :formatter="formattedNumber" />
+						<el-table-column fixed="right" label="鎿嶄綔" width="160" align="center">
+							<template #default="scope">
+								<el-button link type="primary" size="small" @click="handleOtherEdit(scope.row)">缂栬緫</el-button>
+								<el-button link type="danger" size="small" @click="handleOtherDelete(scope.row)">鍒犻櫎</el-button>
+							</template>
+						</el-table-column>
+					</el-table>
+
+					<pagination
+						v-show="otherAmountTotal > 0"
+						:total="otherAmountTotal"
+						layout="total, sizes, prev, pager, next, jumper"
+						:page="otherAmountPage.current"
+						:limit="otherAmountPage.size"
+						@pagination="otherAmountPaginationChange"
+					/>
+				</el-col>
+
+				<el-col :span="10">
+					<div style="padding: 8px 0;">
+						<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom: 10px;">
+							<div style="font-weight:600;">
+								{{ otherAmountOperationType === 'add' ? '鏂板鍏朵粬閲戦' : '缂栬緫鍏朵粬閲戦' }}
+							</div>
+							<el-button
+								type="primary"
+								plain
+								size="small"
+								@click="handleOtherAdd"
+								:disabled="otherAmountOperationType === 'add'"
+							>
+								鏂板
+							</el-button>
+						</div>
+
+						<el-form
+							:model="otherAmountForm"
+							label-width="120px"
+							label-position="top"
+							:rules="otherAmountRules"
+							ref="otherAmountFormRef"
+						>
+							<el-form-item label="缂栫爜code">
+								<el-input v-model="otherAmountForm.code" placeholder="璇疯緭鍏ョ紪鐮侊紙鍙�夛級" clearable />
+							</el-form-item>
+
+							<el-form-item label="椤圭洰processName" prop="processName">
+								<el-input v-model="otherAmountForm.processName" placeholder="璇疯緭鍏ラ」鐩悕绉�" clearable />
+							</el-form-item>
+
+							<el-form-item label="鏁伴噺quantity" prop="quantity">
+								<el-input-number
+									v-model="otherAmountForm.quantity"
+									:min="0"
+									:precision="2"
+									style="width:100%"
+									placeholder="璇疯緭鍏ユ暟閲�"
+									clearable
+									@change="recalcOtherAmount"
+								/>
+							</el-form-item>
+
+							<el-form-item label="鍗曚环unitPrice(鍏�)" prop="unitPrice">
+								<el-input-number
+									v-model="otherAmountForm.unitPrice"
+									:min="0"
+									:precision="2"
+									style="width:100%"
+									placeholder="璇疯緭鍏ュ崟浠�"
+									clearable
+									@change="recalcOtherAmount"
+								/>
+							</el-form-item>
+
+							<el-form-item label="閲戦amount(鍏�)">
+								<el-input v-model="otherAmountForm.amount" disabled />
+							</el-form-item>
+
+							<div style="display:flex; justify-content:flex-end; gap: 10px; margin-top: 8px;">
+								<el-button @click="closeOtherAmountDialog">鍙栨秷</el-button>
+								<el-button type="primary" @click="submitOtherAmountForm">淇濆瓨</el-button>
+							</div>
+						</el-form>
+					</div>
+				</el-col>
+			</el-row>
+		</el-dialog>
 	</div>
 </template>
 
@@ -671,7 +783,12 @@
 	delLedger,
 	addOrUpdateSalesLedgerProduct,
 	delProduct,
-	delLedgerFile, getProductInventory,
+	delLedgerFile,
+	getProductInventory,
+	salesLedgerProductProcessList,
+	salesLedgerProductProcessAdd,
+	salesLedgerProductProcessUpdate,
+	salesLedgerProductProcessDelete,
 } from "@/api/salesManagement/salesLedger.js";
 import { modelList, productTreeList } from "@/api/basicData/product.js";
 import useFormData from "@/hooks/useFormData.js";
@@ -810,6 +927,169 @@
 });
 const { deliveryForm, deliveryRules } = toRefs(deliveryFormData);
 
+// 鍏朵粬閲戦缁存姢锛堝伐搴�/娴佺▼閲戦缁存姢锛�
+const otherAmountDialogVisible = ref(false);
+const otherAmountLoading = ref(false);
+const otherAmountRecords = ref([]);
+const otherAmountTotal = ref(0);
+const otherAmountPage = reactive({
+	current: 1,
+	size: 10,
+});
+
+const otherAmountOperationType = ref("add"); // add/edit
+const otherAmountFormRef = ref(null);
+const otherAmountForm = reactive({
+	id: null,
+	code: "", // 鍓嶇瀛楁鍚嶏細code锛涘悗绔帴鍙e垪琛ㄨ繑鍥� remark锛屾澶勮繘琛屾槧灏�
+	processName: "",
+	quantity: 0,
+	unitPrice: 0,
+	amount: "0.00",
+});
+const otherAmountRules = reactive({
+	processName: [{ required: true, message: "璇疯緭鍏ラ」鐩悕绉�", trigger: "change" }],
+	quantity: [{ required: true, message: "璇疯緭鍏ユ暟閲�", trigger: "blur" }],
+	unitPrice: [{ required: true, message: "璇疯緭鍏ュ崟浠�", trigger: "blur" }],
+});
+
+const recalcOtherAmount = () => {
+	const quantity = Number(otherAmountForm.quantity ?? 0) || 0;
+	const unitPrice = Number(otherAmountForm.unitPrice ?? 0) || 0;
+	otherAmountForm.amount = (quantity * unitPrice).toFixed(2);
+};
+
+const resetOtherAmountForm = (type = "add") => {
+	otherAmountOperationType.value = type;
+	otherAmountForm.id = null;
+	otherAmountForm.code = "";
+	otherAmountForm.processName = "";
+	otherAmountForm.quantity = 0;
+	otherAmountForm.unitPrice = 0;
+	otherAmountForm.amount = "0.00";
+};
+
+const openOtherAmountDialog = () => {
+	otherAmountDialogVisible.value = true;
+	resetOtherAmountForm("add");
+	// 鎵撳紑寮规鏃跺埛鏂版暟鎹紝閬垮厤闀挎椂闂村仠鐣欏鑷存暟鎹繃鏈�
+	otherAmountPage.current = otherAmountPage.current || 1;
+	fetchOtherAmountList();
+};
+
+const closeOtherAmountDialog = () => {
+	otherAmountDialogVisible.value = false;
+	resetOtherAmountForm("add");
+};
+
+const fetchOtherAmountList = async () => {
+	otherAmountLoading.value = true;
+	try {
+		const params = {
+			current: otherAmountPage.current,
+			size: otherAmountPage.size,
+		};
+		const res = await salesLedgerProductProcessList(params);
+
+		// 鍏煎涓嶅悓鎺ュ彛鍝嶅簲缁撴瀯锛氬彲鑳芥槸 res.records / res.total 鎴� res.data.records / res.data.total
+		const records = res?.records ?? res?.data?.records ?? [];
+		const total = res?.total ?? res?.data?.total ?? 0;
+
+		otherAmountRecords.value = records.map((item) => {
+			const quantity = Number(item.quantity ?? 0) || 0;
+			const unitPrice = Number(item.unitPrice ?? 0) || 0;
+			const amount = Number(item.amount ?? quantity * unitPrice) || 0;
+			return {
+				id: item.id,
+				code: item.code ?? item.remark ?? "",
+				processName: item.processName ?? "",
+				quantity,
+				unitPrice,
+				amount: amount.toFixed(2),
+			};
+		});
+
+		otherAmountTotal.value = total;
+	} finally {
+		otherAmountLoading.value = false;
+	}
+};
+
+const otherAmountPaginationChange = (obj) => {
+	otherAmountPage.current = obj.page;
+	otherAmountPage.size = obj.limit;
+	fetchOtherAmountList();
+};
+
+const handleOtherAdd = () => {
+	resetOtherAmountForm("add");
+};
+
+const handleOtherEdit = (row) => {
+	if (!row) return;
+	otherAmountOperationType.value = "edit";
+	otherAmountForm.id = row.id ?? null;
+	otherAmountForm.code = row.code ?? "";
+	otherAmountForm.processName = row.processName ?? "";
+	otherAmountForm.quantity = Number(row.quantity ?? 0) || 0;
+	otherAmountForm.unitPrice = Number(row.unitPrice ?? 0) || 0;
+	recalcOtherAmount();
+};
+
+const submitOtherAmountForm = () => {
+	otherAmountFormRef.value?.validate((valid) => {
+		if (!valid) return;
+
+		const payload = {
+			processName: otherAmountForm.processName,
+			quantity: Number(otherAmountForm.quantity) || 0,
+			unitPrice: Number(otherAmountForm.unitPrice) || 0,
+			amount: Number(otherAmountForm.amount) || 0,
+			// 鍒楄〃杩斿洖瀛楁鏄� remark锛岃繖閲屾寜鈥渃ode=remark鈥濆仛鏄犲皠
+			remark: otherAmountForm.code,
+			// 鍏煎鍚庣鍙兘鐩存帴浣跨敤 code 瀛楁
+			code: otherAmountForm.code,
+		};
+
+		if (otherAmountOperationType.value === "edit") {
+			payload.id = otherAmountForm.id;
+			salesLedgerProductProcessUpdate(payload).then(() => {
+				proxy.$modal.msgSuccess("淇濆瓨鎴愬姛");
+				fetchOtherAmountList();
+				resetOtherAmountForm("add");
+			});
+		} else {
+			salesLedgerProductProcessAdd(payload).then(() => {
+				proxy.$modal.msgSuccess("淇濆瓨鎴愬姛");
+				fetchOtherAmountList();
+				resetOtherAmountForm("add");
+			});
+		}
+	});
+};
+
+const handleOtherDelete = (row) => {
+	if (!row?.id) return;
+	ElMessageBox.confirm("纭鍒犻櫎璇ヨ褰曪紵", "鍒犻櫎", {
+		confirmButtonText: "纭",
+		cancelButtonText: "鍙栨秷",
+		type: "warning",
+	})
+		.then(() => {
+			return salesLedgerProductProcessDelete(row.id).then(() => {
+				proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+				fetchOtherAmountList();
+
+				if (otherAmountOperationType.value === "edit" && otherAmountForm.id === row.id) {
+					resetOtherAmountForm("add");
+				}
+			});
+		})
+		.catch(() => {
+			proxy.$modal.msg("宸插彇娑�");
+		});
+};
+
 // 鍙戣揣瀹℃壒浜鸿妭鐐癸紙浠垮崗鍚屽鎵� infoFormDia.vue锛�
 const approverNodes = ref([{ id: 1, userId: null }]);
 let nextApproverId = 2;

--
Gitblit v1.9.3