Procházet zdrojové kódy

feat: 首页新增当面付收款统计卡片,汇总统计纳入当面付金额

alphaH před 2 týdny
rodič
revize
5e83aa3dbc

+ 10 - 0
frontend/src/api/module_payment/account.ts

@@ -33,6 +33,16 @@ export const AccountAPI = {
     });
   },
 
+  statF2fTradeAmount(tenantId?: number, enterpriseId?: string) {
+    return request<
+      ApiResponse<{ amount_of_today: string; amount_of_7days: string; amount_of_all: string }>
+    >({
+      url: `${API_PATH}/stat/f2f/amount`,
+      method: "get",
+      params: { tenant_id: tenantId, enterprise_id: enterpriseId },
+    });
+  },
+
   authorizeApply(data: { enterprise_id: string }) {
     return request<ApiResponse<{ sign_url: string }>>({
       url: `${API_PATH}/authorize/apply`,

+ 38 - 1
frontend/src/views/dashboard/tenant.vue

@@ -102,6 +102,24 @@
         </div>
       </div>
 
+      <div class="section-header" style="margin-top: 24px;">
+        <h2>当面付收款统计</h2>
+      </div>
+      <div class="data-cards">
+        <div class="data-card f2f-card">
+          <div class="card-title">今日收款金额(元)</div>
+          <div class="card-value">{{ f2fAmount.amount_of_today || "--" }}</div>
+        </div>
+        <div class="data-card f2f-card">
+          <div class="card-title">近7日收款金额(元)</div>
+          <div class="card-value">{{ f2fAmount.amount_of_7days || "--" }}</div>
+        </div>
+        <div class="data-card f2f-card">
+          <div class="card-title">总收款金额(元)</div>
+          <div class="card-value">{{ f2fAmount.amount_of_all || "--" }}</div>
+        </div>
+      </div>
+
       <div class="section-header" style="margin-top: 24px;">
         <h2>汇总统计</h2>
       </div>
@@ -124,7 +142,7 @@
 </template>
 
 <script setup lang="ts">
-import { ref } from 'vue';
+import { ref, computed, onMounted } from 'vue';
 import { ElButton, ElTabs, ElTabPane } from 'element-plus';
 import { useEnterpriseStore, useUserStore } from '@/store';
 import AccountAPI from '@/api/module_payment/account';
@@ -146,6 +164,7 @@ const selectedEnterpriseId = ref<string | undefined>(
 const selectedPayeeType = ref<string | undefined>(undefined);
 function handlePayeeTypeChange() {
   fetchStatAmount();
+  fetchF2fAmount();
   fetchSummaryAmount();
 }
 
@@ -166,6 +185,12 @@ const consumeAmount = ref<{
   amount_of_all?: string;
 }>({});
 
+const f2fAmount = ref<{
+  amount_of_today?: string;
+  amount_of_7days?: string;
+  amount_of_all?: string;
+}>({});
+
 const summaryAmount = ref<{
   amount_of_today?: string;
   amount_of_7days?: string;
@@ -196,6 +221,15 @@ async function fetchConsumeAmount() {
   }
 }
 
+async function fetchF2fAmount() {
+  try {
+    const res = await AccountAPI.statF2fTradeAmount(currentTenantId.value, selectedEnterpriseId.value);
+    f2fAmount.value = res.data.data || {};
+  } catch (error) {
+    console.error("获取当面付收款统计失败:", error);
+  }
+}
+
 async function fetchSummaryAmount() {
   try {
     const res = await AccountAPI.statSummaryAmount(currentTenantId.value, selectedEnterpriseId.value, selectedPayeeType.value);
@@ -229,6 +263,7 @@ onMounted(async () => {
   }
   fetchStatAmount();
   fetchConsumeAmount();
+  fetchF2fAmount();
   fetchSummaryAmount();
 });
 
@@ -241,12 +276,14 @@ watch(currentTenantId, async (newTenantId) => {
   selectedEnterpriseId.value = undefined;
   fetchStatAmount();
   fetchConsumeAmount();
+  fetchF2fAmount();
   fetchSummaryAmount();
 });
 
 watch(selectedEnterpriseId, () => {
   fetchStatAmount();
   fetchConsumeAmount();
+  fetchF2fAmount();
   fetchSummaryAmount();
 });
 

+ 8 - 0
java/src/main/java/com/payment/platform/module/payment/account/controller/AccountController.java

@@ -46,6 +46,14 @@ public class AccountController {
         return Result.ok(accountService.statConsumeAmount(tenantId, enterpriseId, payeeType));
     }
 
+    @PreAuthorize("@perm.hasAny('module_payment:account:transfer')")
+    @GetMapping("/stat/f2f/amount")
+    public Result<Map<String, String>> statF2fTradeAmount(
+            @RequestParam(name = "tenant_id", required = false) Long tenantId,
+            @RequestParam(name = "enterprise_id", required = false) String enterpriseId) {
+        return Result.ok(accountService.statF2fTradeAmount(tenantId, enterpriseId));
+    }
+
     @PreAuthorize("@perm.hasAny('module_payment:account:transfer')")
     @GetMapping("/stat/summary/amount")
     public Result<Map<String, String>> statSummaryAmount(

+ 47 - 4
java/src/main/java/com/payment/platform/module/payment/account/service/AccountService.java

@@ -18,6 +18,8 @@ import com.payment.platform.module.payment.account.mapper.TransferMapper;
 import com.payment.platform.module.payment.account.mapper.WithdrawMapper;
 import com.payment.platform.module.payment.notification.entity.PayBillEntity;
 import com.payment.platform.module.payment.notification.mapper.PayBillMapper;
+import com.payment.platform.module.payment.facetoface.entity.F2fTradeRecordEntity;
+import com.payment.platform.module.payment.facetoface.mapper.F2fTradeRecordMapper;
 import com.payment.platform.common.exception.BusinessException;
 import com.payment.platform.core.alipay.AlipayClientFactory;
 import com.alipay.api.AlipayApiException;
@@ -63,6 +65,7 @@ public class AccountService {
     private final AlipayClientFactory alipayClientFactory;
     private final RedisTemplate<String, Object> redisTemplate;
     private final PayBillMapper payBillMapper;
+    private final F2fTradeRecordMapper f2fTradeRecordMapper;
     private final AlipayTransferService alipayTransferService;
 
     public List<AccountVO> queryAccounts(String enterpriseId) {
@@ -90,16 +93,56 @@ public class AccountService {
     }
 
     /**
-     * 汇总统计金额 — 转账 + 消费
+     * 统计当面付收款金额 — 仅统计 TRADE_SUCCESS 状态的记录
+     */
+    public Map<String, String> statF2fTradeAmount(Long tenantId, String enterpriseId) {
+        OffsetDateTime today = LocalDate.now().atStartOfDay(ZoneOffset.ofHours(8)).toOffsetDateTime();
+        OffsetDateTime weekAgo = today.minusDays(7);
+
+        LambdaQueryWrapper<F2fTradeRecordEntity> base = new LambdaQueryWrapper<>();
+        base.eq(F2fTradeRecordEntity::getTradeStatus, "TRADE_SUCCESS");
+        if (tenantId != null) base.eq(F2fTradeRecordEntity::getTenantId, tenantId);
+        if (enterpriseId != null && !enterpriseId.isBlank())
+            base.eq(F2fTradeRecordEntity::getEnterpriseId, enterpriseId);
+
+        // 分三次查询简单清晰,当面付收款量不会太大
+        BigDecimal todayAmount = sumF2fTradeAmount(
+                base.clone().ge(F2fTradeRecordEntity::getGmtPayment, today));
+        BigDecimal weekAmount = sumF2fTradeAmount(
+                base.clone().ge(F2fTradeRecordEntity::getGmtPayment, weekAgo));
+        BigDecimal allAmount = sumF2fTradeAmount(base);
+
+        return Map.of(
+                "amount_of_today", todayAmount.toPlainString(),
+                "amount_of_7days", weekAmount.toPlainString(),
+                "amount_of_all", allAmount.toPlainString());
+    }
+
+    private BigDecimal sumF2fTradeAmount(LambdaQueryWrapper<F2fTradeRecordEntity> w) {
+        List<F2fTradeRecordEntity> records = f2fTradeRecordMapper.selectList(w);
+        return records.stream()
+                .map(r -> {
+                    try { return new BigDecimal(r.getTotalAmount()); }
+                    catch (Exception e) { return BigDecimal.ZERO; }
+                })
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+    }
+
+    /**
+     * 汇总统计金额 — 转账 + 消费 + 当面付收款
      */
     public Map<String, String> statSummaryAmount(Long tenantId, String enterpriseId, String payeeType) {
         Map<String, String> transfer = statTransferAmount(tenantId, enterpriseId, payeeType);
         Map<String, String> consume = statConsumeAmount(tenantId, enterpriseId, payeeType);
+        Map<String, String> f2f = statF2fTradeAmount(tenantId, enterpriseId);
 
         return Map.of(
-                "amount_of_today", add(transfer.get("amount_of_today"), consume.get("amount_of_today")),
-                "amount_of_7days", add(transfer.get("amount_of_7days"), consume.get("amount_of_7days")),
-                "amount_of_all", add(transfer.get("amount_of_all"), consume.get("amount_of_all")));
+                "amount_of_today", add(add(transfer.get("amount_of_today"), consume.get("amount_of_today")),
+                        f2f.get("amount_of_today")),
+                "amount_of_7days", add(add(transfer.get("amount_of_7days"), consume.get("amount_of_7days")),
+                        f2f.get("amount_of_7days")),
+                "amount_of_all", add(add(transfer.get("amount_of_all"), consume.get("amount_of_all")),
+                        f2f.get("amount_of_all")));
     }
 
     private String add(String a, String b) {