From e449a5408265e4bd1f6c66f5be28a42efac444ee Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期日, 20 九月 2026 15:22:46 +0800
Subject: [PATCH] 天津豹鸣app 1.需求修改

---
 src/pages/sales/receiptPaymentLedger/detail.vue |  371 +++++++++++++++++++++++++++++++++-------------------
 1 files changed, 232 insertions(+), 139 deletions(-)

diff --git a/src/pages/sales/receiptPaymentLedger/detail.vue b/src/pages/sales/receiptPaymentLedger/detail.vue
index b494332..323c255 100644
--- a/src/pages/sales/receiptPaymentLedger/detail.vue
+++ b/src/pages/sales/receiptPaymentLedger/detail.vue
@@ -1,176 +1,268 @@
 <template>
   <view class="receipt-payment-detail">
-    <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
-    <PageHeader title="瀹㈡埛寰�鏉ヨ鎯�"
+    <PageHeader :title="pageTitle"
                 @back="goBack" />
-    <!-- 缁熻淇℃伅 -->
-    <view class="summary-info"
-          v-if="tableData.length > 0">
-      <view class="summary-item">
-        <text class="summary-label">鎬昏褰曟暟</text>
-        <text class="summary-value">{{ tableData.length }}</text>
+
+    <!-- 绗簩绾э細椤圭洰涓嬬殑瀹㈡埛寰�鏉� -->
+    <template v-if="level === 'customer'">
+      <!-- 椤圭洰搴旀敹鎽樿锛堥渶姹備竷锛氬簲鏀惰处娆剧鐞嗛噸鐐逛俊鎭憳瑕侊級 -->
+      <view class="summary-info">
+        <view class="summary-item">
+          <text class="summary-label">瀹㈡埛鏁�</text>
+          <text class="summary-value">{{ customerTotal }}</text>
+        </view>
+        <view class="summary-item">
+          <text class="summary-label">绛剧害鎬婚</text>
+          <text class="summary-value">{{ fmtMoney(sumOf("contractAmounts")) }}</text>
+        </view>
+        <view class="summary-item">
+          <text class="summary-label">宸插洖娆�</text>
+          <text class="summary-value highlight">{{ fmtMoney(sumOf("receiptPaymentAmount")) }}</text>
+        </view>
+        <view class="summary-item">
+          <text class="summary-label">搴旀敹鎬婚</text>
+          <text class="summary-value danger">{{ fmtMoney(sumOf("receiptableAmount")) }}</text>
+        </view>
+        <view class="summary-item">
+          <text class="summary-label">瓒呮湡鍚堝悓</text>
+          <text class="summary-value danger">{{ overdueCount }} 浠�</text>
+        </view>
       </view>
-      <view class="summary-item">
-        <text class="summary-label">寮�绁ㄦ�婚噾棰�</text>
-        <text class="summary-value">{{ formatAmount(invoiceTotal) }}</text>
-      </view>
-      <view class="summary-item">
-        <text class="summary-label">鍥炴鎬婚噾棰�</text>
-        <text class="summary-value highlight">{{ formatAmount(receiptTotal) }}</text>
-      </view>
-      <view class="summary-item">
-        <text class="summary-label">搴旀敹鎬婚噾棰�</text>
-        <text class="summary-value danger">{{ formatAmount(unReceiptTotal) }}</text>
-      </view>
-    </view>
-    <!-- 鍥炴璁板綍鏄庣粏鍒楄〃 -->
-    <view class="detail-list"
-          v-if="tableData.length > 0">
-      <view v-for="(item, index) in tableData"
-            :key="index"
-            class="detail-item">
-        <view class="item-header">
-          <view class="item-left">
-            <view class="record-icon">
-              <up-icon name="file-text"
-                       size="16"
-                       color="#ffffff"></up-icon>
+
+      <view class="detail-list"
+            v-if="customerList.length > 0">
+        <view v-for="item in customerList"
+              :key="item.customerId"
+              class="detail-item"
+              @click="goContracts(item)">
+          <view class="item-header">
+            <view class="item-left">
+              <view class="record-icon">
+                <up-icon name="account"
+                         size="16"
+                         color="#ffffff" />
+              </view>
+              <text class="item-index">{{ item.customerName || "鏈懡鍚嶅鎴�" }}</text>
             </view>
-            <text class="item-index">{{ index + 1 }}</text>
+            <up-tag :text="item.overdueCount > 0 ? `${item.overdueCount} 浠借秴鏈焋 : '姝e父灞ョ害'"
+                    :type="item.overdueCount > 0 ? 'error' : 'success'"
+                    size="mini"
+                    shape="circle" />
           </view>
-          <view class="item-date">{{ item.happenTime }}</view>
-        </view>
-        <up-divider></up-divider>
-        <view class="item-details">
-          <view class="detail-row">
-            <text class="detail-label">寮�绁ㄩ噾棰�(鍏�)</text>
-            <text class="detail-value">{{ formatAmount(item.invoiceTotal) }}</text>
-          </view>
-          <view class="detail-row">
-            <text class="detail-label">鍥炴閲戦(鍏�)</text>
-            <text class="detail-value highlight">{{ formatAmount(item.receiptPaymentAmount) }}</text>
-          </view>
-          <view class="detail-row">
-            <text class="detail-label">搴旀敹閲戦(鍏�)</text>
-            <text class="detail-value danger">{{ formatAmount(item.unReceiptPaymentAmount) }}</text>
-          </view>
-          <view class="detail-row">
-            <text class="detail-label">鍙戠敓鏃ユ湡</text>
-            <text class="detail-value">{{ item.receiptPaymentDate }}</text>
+          <up-divider></up-divider>
+          <view class="item-details">
+            <view class="detail-row">
+              <text class="detail-label">绛剧害鎬婚</text>
+              <text class="detail-value">{{ fmtMoney(item.contractAmounts) }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">宸插洖娆�</text>
+              <text class="detail-value highlight">{{ fmtMoney(item.receiptPaymentAmount) }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">搴旀敹閲戦</text>
+              <text class="detail-value danger">{{ fmtMoney(item.receiptableAmount) }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">閫�璐ч噾棰�</text>
+              <text class="detail-value">{{ fmtMoney(item.returnAmount) }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">鍥炴杩涘害</text>
+              <text class="detail-value"
+                    :class="{ danger: item.overdueCount > 0 }">
+                {{ calcRate(item.receiptPaymentAmount, item.contractAmounts) }}%
+              </text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">鍚堝悓鏁�</text>
+              <text class="detail-value">{{ item.contractCount || 0 }} 浠�</text>
+            </view>
           </view>
         </view>
       </view>
-    </view>
-    <view v-else
-          class="no-data">
-      <text>鏆傛棤鍥炴璁板綍</text>
-    </view>
+      <view v-else
+            class="no-data">
+        <text>璇ラ」鐩笅鏆傛棤瀹㈡埛寰�鏉ユ暟鎹�</text>
+      </view>
+    </template>
+
+    <!-- 绗笁绾э細瀹㈡埛涓嬬殑鍚堝悓鏄庣粏 -->
+    <template v-else>
+      <view class="detail-list"
+            v-if="contractList.length > 0">
+        <view v-for="(item, index) in contractList"
+              :key="index"
+              class="detail-item">
+          <view class="item-header">
+            <view class="item-left">
+              <view class="record-icon">
+                <up-icon name="file-text"
+                         size="16"
+                         color="#ffffff" />
+              </view>
+              <text class="item-index">{{ item.contractName || item.salesContractNo || "鏈懡鍚嶅悎鍚�" }}</text>
+            </view>
+            <up-tag :text="contractStatusText(item)"
+                    :type="contractStatusType(item)"
+                    size="mini"
+                    shape="circle" />
+          </view>
+          <up-divider></up-divider>
+          <view class="item-details">
+            <view class="detail-row">
+              <text class="detail-label">鍚堝悓缂栧彿</text>
+              <text class="detail-value">{{ item.salesContractNo || "-" }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">鍚堝悓鎬婚</text>
+              <text class="detail-value">{{ fmtMoney(item.contractAmount) }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">宸插洖娆�</text>
+              <text class="detail-value"
+                    :class="{ danger: item.isPaymentTimeout }">
+                {{ fmtMoney(item.receiptPaymentAmount) }}
+                ({{ calcRate(item.receiptPaymentAmount, item.contractAmount) }}%)
+              </text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">搴旀敹閲戦</text>
+              <text class="detail-value danger">{{ fmtMoney(item.receiptableAmount) }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">閫�璐ч噾棰�</text>
+              <text class="detail-value">{{ fmtMoney(item.returnAmount) }}</text>
+            </view>
+          </view>
+        </view>
+      </view>
+      <view v-else
+            class="no-data">
+        <text>璇ュ鎴蜂笅鏆傛棤鍚堝悓鏄庣粏</text>
+      </view>
+    </template>
   </view>
 </template>
 
 <script setup>
-  import { ref, computed, onMounted } from "vue";
-  import { onShow } from "@dcloudio/uni-app";
-  import { customerInteractions } from "@/api/salesManagement/receiptPayment.js";
+  import { computed, ref } from "vue";
+  import { onLoad } from "@dcloudio/uni-app";
+  import PageHeader from "@/components/PageHeader.vue";
+  import {
+    customewTransactions,
+    customewTransactionsDetails,
+  } from "@/api/salesManagement/indicatorStats";
+  import { unwrapList } from "@/utils/list";
 
-  // 瀹㈡埛淇℃伅
+  // level: customer = 椤圭洰涓嬬殑瀹㈡埛姹囨�伙紱contract = 瀹㈡埛涓嬬殑鍚堝悓鏄庣粏
+  const level = ref("customer");
+  const projectId = ref("");
+  const projectName = ref("");
   const customerId = ref("");
+  const customerName = ref("");
 
-  // 琛ㄦ牸鏁版嵁
-  const tableData = ref([]);
+  const customerList = ref([]);
+  const contractList = ref([]);
+  const customerTotal = ref(0);
 
-  const invoiceTotal = computed(() => {
-    return tableData.value.reduce((sum, item) => {
-      return sum + (parseFloat(item.invoiceTotal) || 0);
-    }, 0);
+  const pageTitle = computed(() => {
+    if (level.value === "customer") return projectName.value || "瀹㈡埛寰�鏉�";
+    return customerName.value || "鍚堝悓鏄庣粏";
   });
 
-  const receiptTotal = computed(() => {
-    return tableData.value.reduce((sum, item) => {
-      return sum + (parseFloat(item.receiptPaymentAmount) || 0);
-    }, 0);
-  });
+  const sumOf = field =>
+    customerList.value.reduce((sum, item) => sum + (Number(item[field]) || 0), 0);
 
-  const unReceiptTotal = computed(() => {
-    return tableData.value.reduce((sum, item) => {
-      return sum + (parseFloat(item.unReceiptPaymentAmount) || 0);
-    }, 0);
-  });
+  const overdueCount = computed(() =>
+    customerList.value.reduce((sum, item) => sum + (Number(item.overdueCount) || 0), 0)
+  );
 
-  // 杩斿洖涓婁竴椤�
-  const goBack = () => {
-    uni.removeStorageSync("customerId");
-    uni.navigateBack();
-  };
-
-  // 鑾峰彇椤甸潰鍙傛暟
-  const getPageParams = () => {
-    // 浠庢湰鍦板瓨鍌ㄨ幏鍙栧鎴稩D
-    const storedCustomerId = uni.getStorageSync("customerId");
-    if (storedCustomerId) {
-      customerId.value = storedCustomerId;
-    }
-  };
-
-  // 鏌ヨ鍒楄〃
-  const getList = () => {
-    if (!customerId.value) {
-      uni.showToast({
-        title: "瀹㈡埛淇℃伅缂哄け",
-        icon: "error",
+  const loadCustomers = () => {
+    if (!projectId.value) return;
+    uni.showLoading({ title: "鍔犺浇涓�...", mask: true });
+    customewTransactions({ projectId: projectId.value, current: -1, size: -1 })
+      .then(res => {
+        customerList.value = unwrapList(res);
+        customerTotal.value = Number(res?.data?.total ?? customerList.value.length);
+        uni.hideLoading();
+      })
+      .catch(() => {
+        uni.hideLoading();
+        uni.showToast({ title: "鏌ヨ澶辫触", icon: "none" });
       });
-      return;
-    }
+  };
 
-    showLoadingToast("鍔犺浇涓�...");
-    const param = {
+  const loadContracts = () => {
+    if (!projectId.value || !customerId.value) return;
+    uni.showLoading({ title: "鍔犺浇涓�...", mask: true });
+    customewTransactionsDetails({
+      projectId: projectId.value,
       customerId: customerId.value,
       current: -1,
       size: -1,
-    };
-
-    customerInteractions(param)
+    })
       .then(res => {
-        tableData.value = res.data;
-        closeToast();
+        contractList.value = unwrapList(res);
+        uni.hideLoading();
       })
       .catch(() => {
-        closeToast();
-        uni.showToast({
-          title: "鏌ヨ澶辫触",
-          icon: "error",
-        });
+        uni.hideLoading();
+        uni.showToast({ title: "鏌ヨ澶辫触", icon: "none" });
       });
   };
 
-  // 鏍煎紡鍖栭噾棰�
-  const formatAmount = amount => {
-    return amount ? parseFloat(amount).toFixed(2) : "0.00";
+  const goContracts = item => {
+    customerId.value = item.customerId;
+    customerName.value = item.customerName || "";
+    level.value = "contract";
+    loadContracts();
   };
 
-  // 鏄剧ず鍔犺浇鎻愮ず
-  const showLoadingToast = message => {
-    uni.showLoading({
-      title: message,
-      mask: true,
-    });
+  // 杩斿洖锛氱涓夌骇閫�鍥炵浜岀骇锛岀浜岀骇鎵嶇湡姝i��鍑洪〉闈�
+  const goBack = () => {
+    if (level.value === "contract") {
+      level.value = "customer";
+      contractList.value = [];
+      return;
+    }
+    uni.navigateBack();
   };
 
-  // 鍏抽棴鎻愮ず
-  const closeToast = () => {
-    uni.hideLoading();
+  const contractStatusText = item => {
+    if (item.isPaymentTimeout) return "瓒呮湡鏈洖";
+    const amount = Number(item.contractAmount) || 0;
+    if (amount > 0 && (Number(item.receiptPaymentAmount) || 0) >= amount) return "宸茬粨娓�";
+    return "灞ヨ涓�";
   };
 
-  onShow(() => {
-    // 椤甸潰鏄剧ず鏃惰幏鍙栧弬鏁板苟鍒锋柊鍒楄〃
-    getPageParams();
-    getList();
-  });
+  const contractStatusType = item => {
+    if (item.isPaymentTimeout) return "error";
+    const amount = Number(item.contractAmount) || 0;
+    if (amount > 0 && (Number(item.receiptPaymentAmount) || 0) >= amount) return "success";
+    return "primary";
+  };
 
-  onMounted(() => {
-    // 椤甸潰鍔犺浇鏃惰幏鍙栧弬鏁板苟鍒锋柊鍒楄〃
-    getPageParams();
-    getList();
+  const fmtMoney = value => {
+    const num = Number(value);
+    if (!Number.isFinite(num)) return "楼 0.00";
+    return "楼 " + num.toLocaleString("zh-CN", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
+  };
+
+  const calcRate = (paid, amount) => {
+    const total = Number(amount);
+    if (!Number.isFinite(total) || total === 0) return "0.0";
+    return (((Number(paid) || 0) / total) * 100).toFixed(1);
+  };
+
+  onLoad(options => {
+    projectId.value = options?.projectId || "";
+    projectName.value = options?.projectName ? decodeURIComponent(options.projectName) : "";
+    if (!projectId.value) {
+      uni.showToast({ title: "缂哄皯椤圭洰鍙傛暟", icon: "none" });
+      return;
+    }
+    loadCustomers();
   });
 </script>
 
@@ -249,6 +341,8 @@
     display: flex;
     align-items: center;
     gap: 8px;
+    flex: 1;
+    min-width: 0;
   }
 
   .record-icon {
@@ -259,17 +353,16 @@
     display: flex;
     align-items: center;
     justify-content: center;
+    flex-shrink: 0;
   }
 
   .item-index {
     font-size: 14px;
     color: #333;
     font-weight: 500;
-  }
-
-  .item-date {
-    font-size: 12px;
-    color: #666;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
   }
 
   .item-details {

--
Gitblit v1.9.3