From c0d6fe2638379e6fb23f1af5eff27355cb565e9d Mon Sep 17 00:00:00 2001
From: ZN <zhang_12370@163.com>
Date: 星期六, 28 三月 2026 15:34:06 +0800
Subject: [PATCH] feat(采购管理): 优化高级价格管理与采购台账功能

---
 src/views/procurementManagement/procurementLedger/index.vue |  208 ++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 168 insertions(+), 40 deletions(-)

diff --git a/src/views/procurementManagement/procurementLedger/index.vue b/src/views/procurementManagement/procurementLedger/index.vue
index 400f061..b8fd556 100644
--- a/src/views/procurementManagement/procurementLedger/index.vue
+++ b/src/views/procurementManagement/procurementLedger/index.vue
@@ -250,6 +250,7 @@
                 v-model="form.supplierId"
                 placeholder="璇烽�夋嫨"
                 clearable
+                @change="handleSupplierChange"
               >
                 <el-option
                   v-for="item in supplierList"
@@ -647,39 +648,60 @@
     <!-- 鍘嗗彶閲囪喘浠锋牸鍙傝�冨脊绐� -->
     <el-dialog
       v-model="priceReferenceVisible"
-      title="鍘嗗彶閲囪喘浠锋牸鍙傝��"
+      :title="`鍘嗗彶閲囪喘浠锋牸鍙傝�� ${productForm.supplierName}-${productForm.productName}-${productForm.productModel}`"
       width="1000px"
       append-to-body
     >
       <el-table 
-        v-loading="priceReferenceLoading"
         :data="priceReferenceData" 
         border 
-        style="width: 100%"
+        v-loading="priceReferenceLoading" 
+        :default-sort="{ prop: 'updateTime', order: 'descending' }"
       >
-        <el-table-column label="鍟嗗搧鍚嶇О" prop="productName" min-width="150" show-overflow-tooltip />
-        <el-table-column label="瑙勬牸鍨嬪彿" prop="specification" width="150" show-overflow-tooltip />
-        <el-table-column label="渚涘簲鍟�" prop="supplierName" width="200" show-overflow-tooltip />
-        <el-table-column label="鍩虹浠锋牸" width="120" align="right">
+        <!-- <el-table-column label="鍟嗗搧淇℃伅" min-width="200">
           <template #default="{ row }">
-            <span style="color: #f56c6c; font-weight: bold;">楼{{ row.basePrice }}</span>
+            <div class="product-info">
+              <div class="product-name">{{ row.productName }}</div>
+              <div class="product-spec">{{ row.specification }}</div>
+              <div class="product-code">缂栫爜: {{ row.productCode }}</div>
+            </div>
+          </template>
+        </el-table-column> -->
+        <!-- <el-table-column label="渚涘簲鍟�" prop="supplierName" width="200" /> -->
+        <el-table-column label="鍩虹浠锋牸(涓嶅惈绋�)" width="150" align="right">
+          <template #default="{ row }">
+            <span class="price-text">楼{{ row.basePrice }}</span>
           </template>
         </el-table-column>
+        <el-table-column label="瀹為檯浠锋牸(涓嶅惈绋�)" prop="actuallyPrice" width="150" align="right"/>
         <el-table-column label="鎶樻墸淇℃伅" width="120" align="center">
           <template #default="{ row }">
-            <el-tag v-if="row.discountType === 'percentage'" type="success">
-              {{ row.discountValue }}%
-            </el-tag>
-            <el-tag v-else-if="row.discountType === 'fixed'" type="warning">
-              -楼{{ row.discountValue }}
-            </el-tag>
-            <span v-else>鏃犳姌鎵�</span>
+            <div v-if="row.discountType">
+              <el-tag :type="getDiscountTagType(row.discountType)" size="small">
+                {{ getDiscountText(row.discountType) }}
+              </el-tag>
+              <div class="discount-value">{{ row.discountValue }}{{ row.discountType === 'percentage' ? '%' : '鍏�' }}</div>
+            </div>
+            <span v-else class="no-discount">鏃犳姌鎵�</span>
           </template>
         </el-table-column>
-        <el-table-column label="鐢熸晥鏃堕棿" prop="effectiveTime" width="180" align="center" />
+        <el-table-column label="鐘舵��" width="100" align="center">
+          <template #default="{ row }">
+            <el-tag :type="getStatusType(row.status)">{{ getStatusText(row.status) }}</el-tag>
+            <!-- <div v-if="isPriceWarning(row)" class="warning-indicator">
+              <el-icon color="#F56C6C"><Warning /></el-icon>
+            </div> -->
+          </template>
+        </el-table-column>
+        <el-table-column label="鐢熸晥鏃堕棿" prop="effectiveTime" width="100" align="center" />
+        <el-table-column label="鏇存柊鏃堕棿" prop="updateTime" width="160" sortable align="center" />
+        <el-table-column label="澶囨敞" width="200" prop="remark" align="center" show-overflow-tooltip />
         <el-table-column label="鎿嶄綔" width="100" align="center" fixed="right">
           <template #default="{ row }">
-            <el-button type="primary" link @click="selectPriceReference(row)">閫夋嫨</el-button>
+            <el-button type="success" link @click="selectPriceReference(row)">
+              <el-icon><Check /></el-icon>
+              寮曠敤
+            </el-button>
           </template>
         </el-table-column>
       </el-table>
@@ -921,7 +943,7 @@
 import { getToken } from "@/utils/auth";
 import pagination from "@/components/PIMTable/Pagination.vue";
 import { ref, onMounted, reactive, toRefs, getCurrentInstance, nextTick } from "vue";
-import { Search } from "@element-plus/icons-vue";
+import { Search, Check } from "@element-plus/icons-vue";
 import { ElMessageBox } from "element-plus";
 import { userListNoPage } from "@/api/system/user.js";
 import {
@@ -1037,6 +1059,9 @@
     taxExclusiveTotalPrice: "",
     invoiceType: "",
 		warnNum: "",
+    supplierName: "",
+    productName: "",
+    productModel: "",
   },
   productRules: {
     productId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
@@ -1069,7 +1094,59 @@
   size: 10
 });
 
+const calculateFinalPrice = (row) => {
+  let finalPrice = row.basePrice;
+  if (row.discountType === "percentage") {
+    finalPrice = row.basePrice * (1 - row.discountValue / 100);
+  } else if (row.discountType === "fixed") {
+    finalPrice = row.basePrice - row.discountValue;
+  }
+  let man = Math.max(finalPrice, 0);
+  return man.toFixed(2);
+};
+
+const getDiscountTagType = (discountType) => {
+  const typeMap = {
+    percentage: "success",
+    fixed: "warning",
+    tiered: "info",
+  };
+  return typeMap[discountType] || "info";
+};
+
+const getDiscountText = (discountType) => {
+  const textMap = {
+    percentage: "鐧惧垎姣�",
+    fixed: "鍥哄畾閲戦",
+  };
+  return textMap[discountType] || "鏈煡";
+};
+
+const getStatusType = (status) => {
+  const statusMap = {
+    active: "success",
+    pending: "warning",
+    expired: "info",
+  };
+  return statusMap[status] || "info";
+};
+
+const getStatusText = (status) => {
+  const statusMap = {
+    active: "鏈夋晥",
+    pending: "寰呯敓鏁�",
+    expired: "宸茶繃鏈�",
+  };
+  return statusMap[status] || "鏈煡";
+};
+
 const showPriceReference = () => {
+  if (form.value.supplierId) {
+    const supplier = supplierList.value.find((item) => item.id === form.value.supplierId);
+    if (supplier) {
+      productForm.value.supplierName = supplier.supplierName;
+    }
+  }
   priceReferenceVisible.value = true;
   handlePriceReferenceSearch();
 };
@@ -1080,11 +1157,12 @@
   // 鍋囪楂樼骇浠锋牸绠$悊鐨� listPage 鎺ユ敹 productId
   const query = {
     productId: productForm.value.productId,
-    specificationId: productForm.value.productModelId,
+    supplierId: form.value.supplierId,
     current: priceReferencePagination.current,
     size: priceReferencePagination.size
   };
   listAdvancedPrice(query).then(res => {
+    console.log(res);
     priceReferenceData.value = res.data.records;
     priceReferenceTotal.value = res.data.total;
     priceReferenceLoading.value = false;
@@ -1104,25 +1182,39 @@
 };
 
 const selectPriceReference = (row) => {
-   // 璁$畻瀹為檯浠锋牸锛氬熀纭�浠锋牸 - 鎶樻墸
-   let actualPrice = row.basePrice;
-   if (row.discountType === 'percentage') {
-     actualPrice = row.basePrice * (1 - row.discountValue / 100);
-   } else if (row.discountType === 'fixed') {
-     actualPrice = row.basePrice - row.discountValue;
-   }
-   
-   // 濉厖鍚◣鍗曚环锛屼繚鐣欎袱浣嶅皬鏁�
-   productForm.value.taxInclusiveUnitPrice = Number(Math.max(actualPrice, 0)).toFixed(2);
-   
-   // 濡傛灉宸茬粡杈撳叆浜嗘暟閲忥紝鍒欒嚜鍔ㄨ绠楁�讳环
-   if (productForm.value.quantity) {
-     mathNum();
-   }
-   
-   priceReferenceVisible.value = false;
-   proxy.$modal.msgSuccess("宸插紩鐢ㄥ巻鍙蹭环鏍�");
- };
+  // 璁$畻鍘嗗彶浠锋牸锛堜綔涓轰笉鍚◣鍗曚环锛夛細鍩虹浠锋牸 - 鎶樻墸
+  let taxExclusivePrice = row.basePrice;
+  if (row.discountType === "percentage") {
+    taxExclusivePrice = row.basePrice * (1 - row.discountValue / 100);
+  } else if (row.discountType === "fixed") {
+    taxExclusivePrice = row.basePrice - row.discountValue;
+  }
+  taxExclusivePrice = Number(Math.max(taxExclusivePrice, 0));
+
+  // 璁剧疆鏁伴噺涓� 1
+  if (!productForm.value.quantity) {
+    productForm.value.quantity = 1;
+  }
+
+  // 濡傛灉宸叉湁绋庣巼锛屽垯璁$畻鍚◣鍗曚环
+  if (productForm.value.taxRate) {
+    const taxRate = Number(productForm.value.taxRate);
+    productForm.value.taxInclusiveUnitPrice = (
+      taxExclusivePrice *
+      (1 + taxRate / 100)
+    ).toFixed(2);
+  } else {
+    // 濡傛灉娌℃湁绋庣巼锛屾殏鏃跺皢鍚◣鍗曚环璁句负涓嶅惈绋庝环鏍硷紝鎻愮ず鐢ㄦ埛閫夋嫨绋庣巼
+    productForm.value.taxInclusiveUnitPrice = taxExclusivePrice.toFixed(2);
+    proxy.$modal.msgWarning("璇烽�夋嫨绋庣巼浠ュ噯纭绠楀惈绋庝环鏍�");
+  }
+
+  // 鑷姩瑙﹀彂璁$畻閫昏緫锛堣绠楁�讳环绛夛級
+  mathNum();
+
+  priceReferenceVisible.value = false;
+  proxy.$modal.msgSuccess("宸插紩鐢ㄥ巻鍙蹭环鏍硷紙涓嶅惈绋庯級");
+};
 
 const upload = reactive({
   // 涓婁紶鐨勫湴鍧�
@@ -1364,11 +1456,32 @@
   }
   productOperationType.value = type;
   productOperationIndex.value = index;
-  productForm.value = {};
+  productForm.value = {
+    supplierName: "",
+    productName: "",
+    productModel: "",
+  };
   proxy.resetForm("productFormRef");
   if (type === "edit") {
-    productForm.value = { ...row };
+    productForm.value = { 
+      ...row,
+      productName: row.productCategory || "",
+      productModel: row.specificationModel || ""
+    };
+    // 缂栬緫鏃讹紝鏍规嵁 productId 棰勫姞杞借鏍煎瀷鍙峰垪琛紝纭繚涓嬫媺妗嗘樉绀哄悕绉拌�岄潪 ID
+    if (productForm.value.productId) {
+      modelList({ id: productForm.value.productId }).then((res) => {
+        modelOptions.value = res;
+      });
+    }
   }
+  
+  // 纭繚渚涘簲鍟嗗悕绉板缁堝悓姝�
+  const supplier = supplierList.value.find((item) => item.id === form.value.supplierId);
+  if (supplier) {
+    productForm.value.supplierName = supplier.supplierName;
+  }
+  
   productFormVisible.value = true;
   getProductOptions();
 };
@@ -1380,11 +1493,14 @@
 const getModels = (value) => {
   if (value) {
     productForm.value.productCategory = findNodeById(productOptions.value, value) || "";
+    productForm.value.productName = productForm.value.productCategory;
+    productForm.value.productModelId = "";
     modelList({ id: value }).then((res) => {
       modelOptions.value = res;
     });
   } else {
     productForm.value.productCategory = "";
+    productForm.value.productName = "";
     modelOptions.value = [];
   }
 };
@@ -1392,12 +1508,24 @@
   const index = modelOptions.value.findIndex((item) => item.id === value);
   if (index !== -1) {
     productForm.value.specificationModel = modelOptions.value[index].model;
+    productForm.value.productModel = modelOptions.value[index].model;
     productForm.value.unit = modelOptions.value[index].unit;
   } else {
     productForm.value.specificationModel = null;
+    productForm.value.productModel = null;
     productForm.value.unit = null;
   }
 };
+const handleSupplierChange = (value) => {
+  const supplier = supplierList.value.find((item) => item.id === value);
+  if (supplier) {
+    form.value.supplierName = supplier.supplierName;
+    productForm.value.supplierName = supplier.supplierName;
+  } else {
+    form.value.supplierName = "";
+    productForm.value.supplierName = "";
+  }
+};
 const findNodeById = (nodes, productId) => {
   for (let i = 0; i < nodes.length; i++) {
     if (nodes[i].value === productId) {

--
Gitblit v1.9.3