From 5af665569d0cc093184f99b70ac38745ef53b911 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期一, 21 九月 2026 20:39:04 +0800
Subject: [PATCH] 新疆-融邦环保 1.油品出库表单改「多台账分摊绑定」:各台账数量之和必须等于出库吨位,产品取各台账明细交集,代储不锁行可自由增删 2.新增到货记录模块:销售台账页入口,车辆随出库单联动,到货上限=该台账分摊量,附件走永久链接 3.发货台账改层级父行:油品出库为父行,children 为到货记录,来源列区分发货单/油品出库/到货 4.开票/收款候选按「出库单×客户」拆行,bindingId 与出库单 id 分两串回传,防重复开票/收款 5.销售台账下拉补产品/规格型号 6.代储入库绑定销售订单:油品入库表单加销售订单下拉,入库台账列表加「销售订单」列 7.采购申请补齐台账字段(油库、采购合同号、提货方式、物流方式、最佳到站日期、采购类别、付款方式、预警数量、附件等) 8.修复采购申请「转订单后跳转无反应」 9.采购台账删掉「销售合同号」的搜索条件、列表列和表单字段 10.公海客户新增「信托基金(元)」,代储金额合计超限标红提示

---
 src/views/procurementManagement/purchaseApplication/index.vue |  494 +++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 407 insertions(+), 87 deletions(-)

diff --git a/src/views/procurementManagement/purchaseApplication/index.vue b/src/views/procurementManagement/purchaseApplication/index.vue
index a9cf71f..f654894 100644
--- a/src/views/procurementManagement/purchaseApplication/index.vue
+++ b/src/views/procurementManagement/purchaseApplication/index.vue
@@ -95,10 +95,6 @@
                          prop="projectName"
                          width="280"
                          show-overflow-tooltip />
-        <el-table-column label="閿�鍞悎鍚屽彿"
-                         prop="salesContractNo"
-                         width="170"
-                         show-overflow-tooltip />
         <el-table-column label="鐢宠浜�"
                          prop="applicantName"
                          width="100"
@@ -202,6 +198,16 @@
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
+            <el-form-item label="閲囪喘鍚堝悓鍙凤細"
+                          prop="purchaseContractNumber">
+              <el-input v-model="form.purchaseContractNumber"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
             <el-form-item label="渚涘簲鍟嗗悕绉帮細"
                           prop="supplierId">
               <el-select v-model="form.supplierId"
@@ -227,22 +233,6 @@
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="閿�鍞悎鍚屽彿锛�"
-                          prop="salesLedgerId">
-              <el-select v-model="form.salesLedgerId"
-                         placeholder="璇烽�夋嫨"
-                         filterable
-                         clearable
-                         style="width: 100%"
-                         @change="salesLedgerChange">
-                <el-option v-for="item in salesContractList"
-                           :key="item.id"
-                           :label="item.salesContractNo"
-                           :value="item.id" />
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
             <el-form-item label="鐢宠浜猴細"
                           prop="applicantId">
               <el-select v-model="form.applicantId"
@@ -257,9 +247,7 @@
               </el-select>
             </el-form-item>
           </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="8">
+          <el-col :span="12">
             <el-form-item label="鏈熸湜鍒拌揣鏃ユ湡锛�"
                           prop="expectedArrivalDate">
               <el-date-picker style="width: 100%"
@@ -271,7 +259,160 @@
                               clearable />
             </el-form-item>
           </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鏈�浣冲埌绔欐棩鏈燂細"
+                          prop="bestArrivalDate">
+              <el-date-picker style="width: 100%"
+                              v-model="form.bestArrivalDate"
+                              value-format="YYYY-MM-DD"
+                              format="YYYY-MM-DD"
+                              type="date"
+                              placeholder="璇烽�夋嫨"
+                              clearable />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="浠樻鏂瑰紡锛�"
+                          prop="paymentMethod">
+              <el-input v-model="form.paymentMethod"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
           <el-col :span="8">
+            <el-form-item label="褰曞叆浜猴細"
+                          prop="recorderId">
+              <el-select v-model="form.recorderId"
+                         placeholder="璇烽�夋嫨"
+                         filterable
+                         clearable
+                         style="width: 100%">
+                <el-option v-for="item in userList"
+                           :key="item.userId"
+                           :label="item.nickName"
+                           :value="item.userId" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="绛捐鏃ユ湡锛�"
+                          prop="executionDate">
+              <el-date-picker style="width: 100%"
+                              v-model="form.executionDate"
+                              value-format="YYYY-MM-DD"
+                              format="YYYY-MM-DD"
+                              type="date"
+                              placeholder="璇烽�夋嫨"
+                              clearable />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="褰曞叆鏃ユ湡锛�"
+                          prop="entryDate">
+              <el-date-picker style="width: 100%"
+                              v-model="form.entryDate"
+                              value-format="YYYY-MM-DD"
+                              format="YYYY-MM-DD"
+                              type="date"
+                              placeholder="璇烽�夋嫨"
+                              clearable />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <div class="form-section-title">閲囪喘鍏ュ簱鎻愪氦</div>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鐢宠鎻愪氦鏃堕棿锛�"
+                          prop="applicationSubmitTime">
+              <el-date-picker style="width: 100%"
+                              v-model="form.applicationSubmitTime"
+                              value-format="YYYY-MM-DD HH:mm:ss"
+                              format="YYYY-MM-DD HH:mm:ss"
+                              type="datetime"
+                              placeholder="璇烽�夋嫨"
+                              clearable />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="閲囪喘绫诲埆锛�"
+                          prop="purchaseCategory">
+              <el-radio-group v-model="form.purchaseCategory"
+                              @change="purchaseCategoryChange">
+                <el-radio value="瀹㈠瓨">瀹㈠瓨</el-radio>
+                <el-radio value="浠e偍">浠e偍</el-radio>
+                <el-radio value="閲囪喘鍏ュ簱">閲囪喘鍏ュ簱</el-radio>
+                <el-radio value="閲囪喘鐩撮攢">閲囪喘鐩撮攢</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鐗╂祦鏂瑰紡锛�"
+                          prop="logisticsMethod">
+              <el-select v-model="form.logisticsMethod"
+                         placeholder="璇烽�夋嫨"
+                         clearable
+                         style="width: 100%">
+                <el-option label="鍘傚閰嶉��"
+                           value="鍘傚閰嶉��" />
+                <el-option label="濮斿鐗╂祦"
+                           value="濮斿鐗╂祦" />
+                <el-option label="瀹㈡埛鑷彁"
+                           value="瀹㈡埛鑷彁" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鎻愯揣鏂瑰紡锛�"
+                          prop="pickupMethod">
+              <el-radio-group v-model="form.pickupMethod">
+                <el-radio value="鏆備笉鎻愯揣">鏆備笉鎻愯揣</el-radio>
+                <el-radio value="鎻愯揣">鎻愯揣</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="閲囪喘娌瑰簱锛�"
+                          prop="oilDepotId">
+              <el-select v-model="form.oilDepotId"
+                         placeholder="璇烽�夋嫨"
+                         clearable
+                         popper-class="oil-depot-select-popper"
+                         style="width: 100%">
+                <el-option v-for="item in oilDepotList"
+                           :key="item.id"
+                           :label="item.depotName"
+                           :value="item.id">
+                  <div class="oil-depot-option">
+                    <div class="oil-depot-option-title">{{ item.depotName }}</div>
+                    <div class="oil-depot-option-line">璐熻矗浜猴細{{ item.chargePerson }}</div>
+                    <div class="oil-depot-option-line">鑱旂郴鐢佃瘽锛歿{ item.phone }}</div>
+                    <div class="oil-depot-option-line">鎵�灞炲叕鍙革細{{ item.company }}</div>
+                    <div class="oil-depot-option-line">鍚敤鏃ユ湡锛歿{ item.enableDate }}</div>
+                  </div>
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="瀹㈡埛鍚嶇О锛�"
+                          prop="customerName">
+              <el-input v-model="form.customerName"
+                        placeholder="浠呴噰璐被鍒负浠e偍/閲囪喘鐩撮攢鏃跺彲濉啓"
+                        clearable
+                        :disabled="!['浠e偍', '閲囪喘鐩撮攢'].includes(form.purchaseCategory)" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
             <el-form-item label="鍚堝悓閲戦(鍏�)锛�"
                           prop="contractAmount">
               <el-input-number v-model="form.contractAmount"
@@ -282,12 +423,34 @@
                                style="width: 100%" />
             </el-form-item>
           </el-col>
-          <el-col :span="8">
-            <el-form-item label="浠樻鏂瑰紡锛�"
-                          prop="paymentMethod">
-              <el-input v-model="form.paymentMethod"
-                        placeholder="璇疯緭鍏�"
-                        clearable />
+          <el-col :span="12">
+            <el-form-item label="閲囪喘鏁伴噺锛堝惃锛夛細"
+                          prop="purchaseQuantity">
+              <el-input-number v-model="form.purchaseQuantity"
+                               :precision="0"
+                               :step="1"
+                               :min="0"
+                               placeholder="璇疯緭鍏�"
+                               style="width: 100%" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <div class="form-section-title">绯荤粺淇℃伅</div>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="閲囪喘鐢宠璁㈠崟鐘舵�侊細"
+                          prop="purchaseOrderStatus">
+              <el-select v-model="form.purchaseOrderStatus"
+                         placeholder="璇烽�夋嫨"
+                         clearable
+                         style="width: 100%">
+                <el-option label="宸茬敵璇凤紝鏈杞�"
+                           value="宸茬敵璇凤紝鏈杞�" />
+                <el-option label="浠ュ嚭鍘傦紝鏈叆搴�"
+                           value="浠ュ嚭鍘傦紝鏈叆搴�" />
+                <el-option label="宸插叆搴�"
+                           value="宸插叆搴�" />
+              </el-select>
             </el-form-item>
           </el-col>
         </el-row>
@@ -327,6 +490,10 @@
           <el-table-column label="鏁伴噺"
                            prop="quantity"
                            width="80" />
+          <el-table-column label="搴撳瓨棰勮鏁伴噺"
+                           prop="warnNum"
+                           width="120"
+                           show-overflow-tooltip />
           <el-table-column label="绋庣巼(%)"
                            prop="taxRate"
                            width="80" />
@@ -381,6 +548,14 @@
                         clearable
                         type="textarea"
                         :rows="2" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="24">
+            <el-form-item label="闄勪欢鏉愭枡锛�"
+                          prop="storageBlobDTOS">
+              <FileUpload v-model:file-list="fileList" />
             </el-form-item>
           </el-col>
         </el-row>
@@ -518,6 +693,19 @@
             </el-form-item>
           </el-col>
           <el-col :span="12">
+            <el-form-item label="搴撳瓨棰勮鏁伴噺锛�"
+                          prop="warnNum">
+              <el-input-number v-model="productForm.warnNum"
+                               :precision="2"
+                               :step="0.1"
+                               :min="0"
+                               clearable
+                               style="width: 100%" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
             <el-form-item label="鏄惁璐ㄦ锛�"
                           prop="isChecked">
               <el-radio-group v-model="productForm.isChecked">
@@ -569,12 +757,11 @@
     delApplication,
     convertToOrder,
   } from "@/api/procurementManagement/purchaseApplication.js";
-  import {
-    getSalesNo,
-    getOptions,
-  } from "@/api/procurementManagement/procurementLedger.js";
+  import { getOptions } from "@/api/procurementManagement/procurementLedger.js";
   import { modelList, productTreeList } from "@/api/basicData/product.js";
+  import { allOilDepot } from "@/api/basicData/oilDepot.js";
   import { userListNoPage } from "@/api/system/user.js";
+  import FileUpload from "@/components/AttachmentUpload/file/index.vue";
 
   const { proxy } = getCurrentInstance();
   const { tax_rate } = proxy.useDict("tax_rate");
@@ -591,8 +778,9 @@
   const productSelectedRows = ref([]);
   const supplierOptions = ref([]);
   const supplierList = ref([]);
-  const salesContractList = ref([]);
   const userList = ref([]);
+  const oilDepotList = ref([]);
+  const fileList = ref([]);
   const productOptions = ref([]);
   const modelOptions = ref([]);
   const tableLoading = ref(false);
@@ -626,19 +814,46 @@
     form: {
       id: "",
       applicationNo: "",
+      // 浠ヤ笅瀛楁涓庛�屾柊澧為噰璐彴璐︺�嶄繚鎸佷竴鑷�
+      purchaseContractNumber: "",
       supplierId: "",
       projectName: "",
-      salesContractNo: "",
-      salesLedgerId: "",
       applicantId: "",
       applyDate: "",
       expectedArrivalDate: "",
-      contractAmount: "",
+      bestArrivalDate: "",
       paymentMethod: "",
+      recorderId: "",
+      executionDate: "",
+      entryDate: "",
+      applicationSubmitTime: "",
+      purchaseCategory: "",
+      logisticsMethod: "",
+      pickupMethod: "",
+      oilDepotId: "",
+      customerName: "",
+      purchaseQuantity: "",
+      purchaseOrderStatus: "",
+      contractAmount: "",
       remarks: "",
     },
     rules: {
       applyDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+      projectName: [
+        { required: true, message: "璇疯緭鍏ラ」鐩悕绉�", trigger: "blur" },
+      ],
+      supplierId: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      entryDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+      executionDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+      purchaseCategory: [
+        { required: true, message: "璇烽�夋嫨閲囪喘绫诲埆", trigger: "change" },
+      ],
+      oilDepotId: [
+        { required: true, message: "璇烽�夋嫨閲囪喘娌瑰簱", trigger: "change" },
+      ],
+      purchaseQuantity: [
+        { required: true, message: "璇疯緭鍏ラ噰璐暟閲�", trigger: "change" },
+      ],
     },
   });
   const { form, rules } = toRefs(data);
@@ -656,6 +871,7 @@
       taxInclusiveTotalPrice: "",
       taxExclusiveTotalPrice: "",
       invoiceType: "",
+      warnNum: "",
       isChecked: false,
       remark: "",
     },
@@ -668,6 +884,7 @@
       taxInclusiveUnitPrice: [
         { required: true, message: "璇疯緭鍏�", trigger: "blur" },
       ],
+      warnNum: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
     },
   });
   const { productForm, productRules } = toRefs(productFormData);
@@ -747,14 +964,14 @@
     supplierList.value = list.filter(item => item.isWhite === 0);
   };
 
-  const getSalesContractList = async () => {
-    const res = await getSalesNo();
-    salesContractList.value = Array.isArray(res) ? res : res?.data || [];
-  };
-
   const getUserList = async () => {
     const res = await userListNoPage();
     userList.value = res.data || [];
+  };
+
+  const getOilDepotList = async () => {
+    const res = await allOilDepot();
+    oilDepotList.value = res?.data || [];
   };
 
   const getProductOptions = async () => {
@@ -905,9 +1122,11 @@
     productFormVisible.value = false;
   };
 
-  const salesLedgerChange = value => {
-    const matched = salesContractList.value.find(item => item.id === value);
-    form.value.salesContractNo = matched ? matched.salesContractNo : "";
+  // 閲囪喘绫诲埆鏀瑰彉锛氫粎浠e偍/閲囪喘鐩撮攢鏃跺鎴峰悕绉板彲鐢紝鍒囨崲鍚庢竻绌�
+  const purchaseCategoryChange = val => {
+    if (!["浠e偍", "閲囪喘鐩撮攢"].includes(val)) {
+      form.value.customerName = "";
+    }
   };
 
   const openForm = async (type, row) => {
@@ -917,26 +1136,38 @@
     form.value = {
       id: "",
       applicationNo: "",
+      purchaseContractNumber: "",
       supplierId: "",
       projectName: "",
-      salesContractNo: "",
-      salesLedgerId: "",
       applicantId: "",
       applyDate: dayjs().format("YYYY-MM-DD"),
       expectedArrivalDate: "",
-      contractAmount: "",
+      bestArrivalDate: "",
       paymentMethod: "",
+      recorderId: "",
+      executionDate: "",
+      entryDate: dayjs().format("YYYY-MM-DD"),
+      applicationSubmitTime: "",
+      purchaseCategory: "",
+      logisticsMethod: "",
+      pickupMethod: "",
+      oilDepotId: "",
+      customerName: "",
+      purchaseQuantity: "",
+      purchaseOrderStatus: "",
+      contractAmount: "",
       remarks: "",
     };
     productData.value = [];
     productSelectedRows.value = [];
+    fileList.value = [];
 
     try {
       await Promise.all([
         getSupplierOptions(),
-        getSalesContractList(),
         getUserList(),
         getProductOptions(),
+        getOilDepotList(),
       ]);
     } catch (error) {
       proxy.$modal.msgError("鍔犺浇鍩虹鏁版嵁澶辫触");
@@ -952,6 +1183,7 @@
       const res = await getApplicationById({ id: row.id });
       form.value = { ...(res.data || {}), id: row.id };
       productData.value = res.data?.productData || [];
+      fileList.value = res.data?.storageBlobVOS || [];
     } catch (error) {
       proxy.$modal.msgError("鍔犺浇閲囪喘鐢宠璇︽儏澶辫触");
       return;
@@ -969,14 +1201,28 @@
     const payload = {
       supplierId: form.value.supplierId || null,
       projectName: form.value.projectName,
-      salesContractNo: form.value.salesContractNo,
-      salesLedgerId: form.value.salesLedgerId || null,
       applyDate: form.value.applyDate,
       expectedArrivalDate: form.value.expectedArrivalDate || null,
       contractAmount:
         form.value.contractAmount === "" ? null : form.value.contractAmount,
       paymentMethod: form.value.paymentMethod,
       remarks: form.value.remarks,
+      // 涓庛�屾柊澧為噰璐彴璐︺�嶅榻愮殑瀛楁
+      purchaseContractNumber: form.value.purchaseContractNumber,
+      bestArrivalDate: form.value.bestArrivalDate || null,
+      recorderId: form.value.recorderId || null,
+      executionDate: form.value.executionDate || null,
+      entryDate: form.value.entryDate || null,
+      applicationSubmitTime: form.value.applicationSubmitTime || null,
+      purchaseCategory: form.value.purchaseCategory,
+      logisticsMethod: form.value.logisticsMethod,
+      pickupMethod: form.value.pickupMethod,
+      oilDepotId: form.value.oilDepotId || null,
+      customerName: form.value.customerName,
+      purchaseQuantity:
+        form.value.purchaseQuantity === "" ? null : form.value.purchaseQuantity,
+      purchaseOrderStatus: form.value.purchaseOrderStatus,
+      storageBlobDTOS: fileList.value,
       productData: productData.value.map(
         ({ id, purchaseApplicationId, ...rest }) => rest
       ),
@@ -1030,49 +1276,69 @@
       .catch(() => {});
   };
 
-  const handleConvert = row => {
-    ElMessageBox.confirm(
-      `纭灏嗙敵璇峰崟銆�${row.applicationNo}銆嶈浆涓洪噰璐鍗曞悧锛熻浆璁㈠崟鍚庡皢鑷姩鎻愪氦閲囪喘瀹℃壒銆俙,
-      "杞鍗�",
-      {
-        confirmButtonText: "纭",
-        cancelButtonText: "鍙栨秷",
-        type: "warning",
-      }
-    )
-      .then(async () => {
-        const res = await convertToOrder(row.id);
-        getList();
-        ElMessageBox.confirm(
-          `杞鍗曟垚鍔燂紝宸茬敓鎴愰噰璐彴璐︼紙id锛�${res.data}锛夈�傛槸鍚﹀墠寰�閲囪喘鍙拌处鏌ョ湅锛焋,
-          "鎻愮ず",
-          {
-            confirmButtonText: "鍓嶅線鏌ョ湅",
-            cancelButtonText: "鐣欏湪鏈〉",
-            type: "success",
-          }
-        )
-          .then(() => {
-            const path = findLedgerPath(permissionStore.sidebarRouters);
-            if (path) {
-              router.push(path);
-            } else {
-              ElMessage.info("璇峰墠寰�銆岄噰璐彴璐︺�嶆煡鐪嬬敓鎴愮殑璁㈠崟");
-            }
-          })
-          .catch(() => {});
-      })
-      .catch(() => {});
+  const handleConvert = async row => {
+    try {
+      await ElMessageBox.confirm(
+        `纭灏嗙敵璇峰崟銆�${row.applicationNo}銆嶈浆涓洪噰璐鍗曞悧锛熻浆璁㈠崟鍚庡皢鑷姩鎻愪氦閲囪喘瀹℃壒銆俙,
+        "杞鍗�",
+        {
+          confirmButtonText: "纭",
+          cancelButtonText: "鍙栨秷",
+          type: "warning",
+        }
+      );
+    } catch {
+      return;
+    }
+
+    try {
+      const res = await convertToOrder(row.id);
+      getList();
+      await ElMessageBox.confirm(
+        `杞鍗曟垚鍔燂紝宸茬敓鎴愰噰璐彴璐︼紙id锛�${res?.data}锛夈�傛槸鍚﹀墠寰�閲囪喘鍙拌处鏌ョ湅锛焋,
+        "鎻愮ず",
+        {
+          confirmButtonText: "鍓嶅線鏌ョ湅",
+          cancelButtonText: "鐣欏湪鏈〉",
+          type: "success",
+        }
+      );
+      await gotoLedger();
+    } catch {
+      // 杞鍗曞け璐ョ敱璇锋眰鎷︽埅鍣ㄦ彁绀猴紱鐐广�岀暀鍦ㄦ湰椤点�嶄篃璧拌繖閲岋紝涓嶉澶栧鐞�
+    }
   };
 
-  // 浠庝晶杈规爮鑿滃崟涓畾浣嶉噰璐彴璐﹁矾鐢憋紝鎵句笉鍒版椂涓嶈烦杞粎鎻愮ず
+  // 璺宠浆閲囪喘鍙拌处銆傝矾鐢卞尮閰嶄笉涓婃垨 push 琚嫤鎴兘缁欏嚭鍙鎻愮ず锛屼笉闈欓粯
+  const gotoLedger = async () => {
+    const path = resolveLedgerPath();
+    try {
+      await router.push(path);
+    } catch {
+      ElMessage.warning(`璺宠浆閲囪喘鍙拌处澶辫触锛�${path}锛夛紝璇蜂粠渚ц竟鏍忚繘鍏ユ煡鐪媊);
+    }
+  };
+
+  // 鑿滃崟鏍囬鍙兘涓庨〉闈㈡爣棰樻湁绌烘牸宸紓锛屽綊涓�鍖栧悗鍐嶆瘮
+  const normalizeMenuTitle = title => String(title ?? "").replace(/\s+/g, "").trim();
+
+  const resolveLedgerPath = () => {
+    const path =
+      findLedgerPath(permissionStore.defaultRoutes) ||
+      findLedgerPath(permissionStore.sidebarRouters);
+    // 鎵句笉鍒拌彍鍗曟椂鍏滃簳鍒颁粨搴撻噷澶氬浣跨敤鐨勫浐瀹氬湴鍧�锛堥噰璐鐞嗛椤靛崱鐗囥�侀椤靛揩鎹峰叆鍙o級
+    return path || "/procurementManagement/procurementLedger";
+  };
+
+  // 浠庝晶杈规爮鑿滃崟涓畾浣嶉噰璐彴璐﹁矾鐢�
   const findLedgerPath = (routes, prefix = "") => {
     for (const route of routes || []) {
+      if (!route) continue;
       const fullPath = String(route.path || "").startsWith("/")
         ? route.path
         : `${prefix}/${route.path || ""}`;
-      if (route.meta?.title === "閲囪喘鍙拌处") {
-        return fullPath;
+      if (normalizeMenuTitle(route.meta?.title ?? route.title) === "閲囪喘鍙拌处") {
+        return fullPath.replace(/\/{2,}/g, "/").replace(/\/$/, "");
       }
       const found = findLedgerPath(route.children, fullPath);
       if (found) return found;
@@ -1085,3 +1351,57 @@
     getSupplierOptions();
   });
 </script>
+
+<style scoped lang="scss">
+  // 琛ㄥ崟鍒嗘爮鏍囬锛氳摑鑹茬珫鏉� + 娴呰摑搴曡壊锛岀獊鍑哄垎鍖�
+  .form-section-title {
+    margin: 18px 0 14px;
+    padding: 8px 14px;
+    font-size: 15px;
+    font-weight: 600;
+    color: #1d6fd8;
+    background: linear-gradient(90deg, rgba(64, 158, 255, 0.14), rgba(64, 158, 255, 0.02));
+    border-left: 4px solid #409eff;
+    border-radius: 3px;
+  }
+
+  // 閲囪喘娌瑰簱涓嬫媺閫夐」锛氬皬鍗$墖鏍峰紡
+  .oil-depot-option {
+    padding: 8px 10px;
+
+    .oil-depot-option-title {
+      font-size: 14px;
+      font-weight: 600;
+      color: #303133;
+      margin-bottom: 4px;
+    }
+
+    .oil-depot-option-line {
+      font-size: 12px;
+      color: #909399;
+      line-height: 1.8;
+    }
+  }
+</style>
+
+<style lang="scss">
+  // 涓嬫媺闈㈡澘娓叉煋鍦� body 涓嬶紝闇�鍏ㄥ眬鏍峰紡
+  .oil-depot-select-popper {
+    .el-select-dropdown__item {
+      height: auto;
+      line-height: normal;
+      padding: 4px 0;
+    }
+
+    .oil-depot-option {
+      border: 1px solid #e4e7ed;
+      border-radius: 6px;
+      background-color: #fafbfc;
+
+      &:hover {
+        border-color: #409eff;
+        background-color: #f0f7ff;
+      }
+    }
+  }
+</style>

--
Gitblit v1.9.3