From 98d1455efaa4cd3d5d3213e047ccc0ac187ba05c Mon Sep 17 00:00:00 2001
From: shinnosuke <tantao@1hoper.com>
Date: 星期一, 03 八月 2026 17:30:53 +0800
Subject: [PATCH] feat(admin): 添加政策文章管理和商户功能增强

---
 talent-card-server/src/main/java/com/talentcard/server/business/admin/MerchantSettlementAdminService.java |   15 +++++++++++----
 1 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/talent-card-server/src/main/java/com/talentcard/server/business/admin/MerchantSettlementAdminService.java b/talent-card-server/src/main/java/com/talentcard/server/business/admin/MerchantSettlementAdminService.java
index 09f8b8e..e425c2f 100644
--- a/talent-card-server/src/main/java/com/talentcard/server/business/admin/MerchantSettlementAdminService.java
+++ b/talent-card-server/src/main/java/com/talentcard/server/business/admin/MerchantSettlementAdminService.java
@@ -11,11 +11,13 @@
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import com.talentcard.server.business.merchant.HuifuMerchantWithdrawalService;
 
 @Service
 public class MerchantSettlementAdminService {
     private final JdbcTemplate jdbc;
-    public MerchantSettlementAdminService(JdbcTemplate jdbc) { this.jdbc = jdbc; }
+    private final HuifuMerchantWithdrawalService withdrawalService;
+    public MerchantSettlementAdminService(JdbcTemplate jdbc, HuifuMerchantWithdrawalService withdrawalService) { this.jdbc = jdbc; this.withdrawalService = withdrawalService; }
 
     @Transactional(readOnly = true)
     public PageResult<Map<String, Object>> onboardings(int page, int size) { return page("select a.*, m.merchant_name, s.store_name from merchant_onboarding_application a join merchant m on m.id = a.merchant_id join merchant_store s on s.id = a.store_id", "select count(*) from merchant_onboarding_application", page, size); }
@@ -24,9 +26,14 @@
     @Transactional(readOnly = true)
     public PageResult<Map<String, Object>> withdrawals(int page, int size) { return page("select w.*, c.bank_name, c.card_masked, m.merchant_name, s.store_name from merchant_withdrawal w join merchant_bank_card c on c.id = w.bank_card_id join merchant m on m.id = w.merchant_id join merchant_store s on s.id = w.store_id", "select count(*) from merchant_withdrawal", page, size); }
 
-    @Transactional public Map<String, Object> reviewOnboarding(Long id, String status, String reason) { return update("merchant_onboarding_application", id, status, reason, "onboarding"); }
-    @Transactional public Map<String, Object> reviewBankCard(Long id, String status, String reason) { return update("merchant_bank_card", id, status, reason, "bank card"); }
-    @Transactional public Map<String, Object> reviewWithdrawal(Long id, String status, String reason) { return update("merchant_withdrawal", id, status, reason, "withdrawal"); }
+    @Transactional public Map<String, Object> reviewOnboarding(Long id, String status, String reason, String huifuId) { return reviewOnboardingInternal(id, status, reason, huifuId); }
+    @Transactional public Map<String, Object> reviewBankCard(Long id, String status, String reason, String tokenNo) { return reviewBankCardInternal(id, status, reason, tokenNo); }
+    public Map<String, Object> reviewWithdrawal(Long id, String status, String reason) { if ("paid".equals(normalizeWithdrawalStatus(status))) return withdrawalService.dispatch(id); return update("merchant_withdrawal", id, "failed", reason, "withdrawal"); }
+
+    private Map<String,Object> reviewOnboardingInternal(Long id,String status,String reason,String huifuId) { String value=reviewStatus(status); if("approved".equals(value) && (huifuId==null || !huifuId.trim().matches("[A-Za-z0-9]{1,32}"))) throw new BusinessException(ErrorCode.BAD_REQUEST,"Huifu merchant ID is required when approving onboarding"); int affected=jdbc.update("update merchant_onboarding_application set status=?, reject_reason=?, provider_huifu_id=?, reviewed_at=now() where id=? and status='pending'",value,reason==null?"":reason.trim(),"approved".equals(value)?huifuId.trim():null,id); if(affected==0)throw new BusinessException(ErrorCode.CONFLICT,"Onboarding is already handled or does not exist");return Map.of("id",id,"status",value); }
+    private Map<String,Object> reviewBankCardInternal(Long id,String status,String reason,String tokenNo) { String value=reviewStatus(status); if("approved".equals(value) && (tokenNo==null || !tokenNo.trim().matches("[A-Za-z0-9]{1,32}"))) throw new BusinessException(ErrorCode.BAD_REQUEST,"Huifu withdrawal card token is required when approving a bank card"); int affected=jdbc.update("update merchant_bank_card set status=?, reject_reason=?, provider_token_no=?, reviewed_at=now() where id=? and status='pending'",value,reason==null?"":reason.trim(),"approved".equals(value)?tokenNo.trim():null,id); if(affected==0)throw new BusinessException(ErrorCode.CONFLICT,"Bank card is already handled or does not exist");return Map.of("id",id,"status",value); }
+    private String reviewStatus(String status) { String value=status==null?"":status.trim().toLowerCase(); if(!List.of("approved","rejected").contains(value))throw new BusinessException(ErrorCode.BAD_REQUEST,"Invalid review status");return value; }
+    private String normalizeWithdrawalStatus(String status) { String value=status==null?"":status.trim().toLowerCase(); if(!List.of("paid","failed").contains(value))throw new BusinessException(ErrorCode.BAD_REQUEST,"Invalid withdrawal status");return value; }
 
     private PageResult<Map<String, Object>> page(String query, String count, int page, int size) { int current = Math.max(1, page); int limit = Math.min(Math.max(1, size), 100); List<Map<String, Object>> values = rows(query + " order by id desc limit ? offset ?", limit, (current - 1) * limit); Long total = jdbc.queryForObject(count, Long.class); return new PageResult<>(values, current, limit, total == null ? 0 : total); }
     private Map<String, Object> update(String table, Long id, String status, String reason, String label) {

--
Gitblit v1.7.1