From 656d6f8029f8bf9b2daa9dcc89101a879a70b860 Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期三, 03 十二月 2025 23:10:05 +0800
Subject: [PATCH] feat:优先添加执行人

---
 dryad-payment/src/main/java/com/ruoyi/payment/application/service/PaymentNotifyService.java |  274 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 272 insertions(+), 2 deletions(-)

diff --git a/dryad-payment/src/main/java/com/ruoyi/payment/application/service/PaymentNotifyService.java b/dryad-payment/src/main/java/com/ruoyi/payment/application/service/PaymentNotifyService.java
index c4a8ff4..506f6f5 100644
--- a/dryad-payment/src/main/java/com/ruoyi/payment/application/service/PaymentNotifyService.java
+++ b/dryad-payment/src/main/java/com/ruoyi/payment/application/service/PaymentNotifyService.java
@@ -62,7 +62,7 @@
             // 閫氫俊鎴愬姛涓斾笟鍔℃垚鍔�
             if ("SUCCESS".equals(returnCode) && "SUCCESS".equals(resultCode)) {
                 // 鏌ヨ璁㈠崟鍜屼氦鏄擄紙浣跨敤涓氬姟璁㈠崟鍙锋煡璇級
-                PaymentOrder order = paymentOrderMapper.selectByBizOrderIdAndChannel(outTradeNo, "WECHAT");
+                PaymentOrder order = paymentOrderMapper.selectById(Long.parseLong(outTradeNo));
                 if (order == null) {
                     log.error("璁㈠崟涓嶅瓨鍦�: {}", outTradeNo);
                     updateNotifyLog(notifyLog.getId(), false, "璁㈠崟涓嶅瓨鍦�");
@@ -134,7 +134,7 @@
             // 浜ゆ槗鎴愬姛
             if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {
                 // 鏌ヨ璁㈠崟鍜屼氦鏄擄紙浣跨敤涓氬姟璁㈠崟鍙锋煡璇級
-                PaymentOrder order = paymentOrderMapper.selectByBizOrderIdAndChannel(outTradeNo, "ALIPAY");
+                PaymentOrder order = paymentOrderMapper.selectById(Long.parseLong(outTradeNo));
                 if (order == null) {
                     log.error("璁㈠崟涓嶅瓨鍦�: {}", outTradeNo);
                     updateNotifyLog(notifyLog.getId(), false, "璁㈠崟涓嶅瓨鍦�");
@@ -183,6 +183,276 @@
     }
 
     /**
+     * 澶勭悊绗笁鏂规敮浠樺疂鍥炶皟
+     * 绗笁鏂规敮浠樺疂閫氳繃GET鏂瑰紡鍥炶皟锛屽弬鏁伴�氳繃URL浼犻��
+     * 
+     * 鍙傛暟鏍煎紡锛�
+     * method: 鏂规硶鍚�
+     * APPID: 搴旂敤ID
+     * PaidMoneyType: 鏀粯绫诲瀷
+     * PaidMoney: 鏀粯閲戦锛堝垎锛�
+     * PaidRemarks: 鏀粯澶囨敞锛堝寘鍚玹ransaction_id锛�
+     * UnixTime: 鏃堕棿鎴�
+     * Sign: 绛惧悕
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public void processAlipayThirdPartyNotify(Map<String, String> params) {
+        String method = params.get("method"); // 鏂规硶鍚�
+        String appId = params.get("APPID"); // 搴旂敤ID
+        String paidMoneyType = params.get("PaidMoneyType"); // 鏀粯绫诲瀷
+        String paidMoney = params.get("PaidMoney"); // 鏀粯閲戦锛堝垎锛�
+        String paidRemarks = params.get("PaidRemarks"); // 鏀粯澶囨敞锛堝彲鑳藉寘鍚鍗曞彿鍜屼氦鏄撳彿锛�
+        String unixTime = params.get("UnixTime"); // 鏃堕棿鎴�
+        String sign = params.get("Sign"); // 绛惧悕
+
+        log.info("澶勭悊绗笁鏂规敮浠樺疂鍥炶皟锛宮ethod: {}, APPID: {}, PaidMoneyType: {}, PaidMoney: {}, PaidRemarks: {}, UnixTime: {}, Sign: {}", 
+                method, appId, paidMoneyType, paidMoney, paidRemarks, unixTime, sign);
+        log.info("绗笁鏂规敮浠樺疂鍥炶皟瀹屾暣鍙傛暟: {}", params);
+
+        // 浠嶱aidRemarks涓彁鍙栬鍗曞彿锛坥ut_trade_no锛�
+        // PaidRemarks鏍煎紡鍙兘鏄�: "璁㈠崟鍙�+浜ゆ槗鍙�" 鎴栧叾浠栨牸寮忥紝闇�瑕佽В鏋�
+        String outTradeNo = extractOutTradeNo(paidRemarks);
+        String transactionId = extractTransactionId(paidRemarks);
+        
+        if (outTradeNo == null || outTradeNo.isEmpty()) {
+            log.error("鏃犳硶浠嶱aidRemarks涓彁鍙栬鍗曞彿: {}", paidRemarks);
+            return;
+        }
+
+        log.info("瑙f瀽鍑鸿鍗曞彿: {}, 浜ゆ槗鍙�: {}", outTradeNo, transactionId);
+
+        // 妫�鏌ュ箓绛夋�э紙浣跨敤璁㈠崟鍙锋垨绛惧悕锛�
+        String notifyId = transactionId != null ? transactionId : sign;
+        if (isNotifyProcessed("ALIPAY_THIRD_PARTY", notifyId)) {
+            log.info("绗笁鏂规敮浠樺疂鍥炶皟宸插鐞嗚繃锛屾爣璇�: {}", notifyId);
+            return;
+        }
+
+        // 璁板綍鍥炶皟鏃ュ織
+        NotifyLog notifyLog = saveNotifyLog("ALIPAY_THIRD_PARTY", notifyId, JSON.toJSONString(params), true);
+
+        try {
+            // 绗笁鏂规敮浠樺疂鎴愬姛鐨勫垽鏂潯浠讹紙鏍规嵁瀹為檯鎯呭喌璋冩暣锛�
+            // 閫氬父鍙鑳芥敹鍒板洖璋冨氨琛ㄧず鏀粯鎴愬姛
+            if (paidMoney != null && Integer.parseInt(paidMoney) > 0) {
+                // 鏌ヨ璁㈠崟锛堜娇鐢ㄥ晢鎴疯鍗曞彿锛岃繖閲岀殑outTradeNo瀹為檯鏄垜浠殑璁㈠崟ID锛�
+                PaymentOrder order = paymentOrderMapper.selectById(Long.valueOf(outTradeNo));
+                if (order == null) {
+                    log.error("璁㈠崟涓嶅瓨鍦�: {}", outTradeNo);
+                    updateNotifyLog(notifyLog.getId(), false, "璁㈠崟涓嶅瓨鍦�");
+                    return;
+                }
+
+                // 楠岃瘉閲戦鏄惁鍖归厤
+                if (!order.getAmount().equals(Integer.parseInt(paidMoney))) {
+                    log.error("璁㈠崟閲戦涓嶅尮閰嶏紝璁㈠崟閲戦: {}, 鍥炶皟閲戦: {}", order.getAmount(), paidMoney);
+                    updateNotifyLog(notifyLog.getId(), false, "閲戦涓嶅尮閰�");
+                    return;
+                }
+
+                // 鏌ヨ寰呮敮浠樹氦鏄�
+                PaymentTransaction transaction = paymentTransactionMapper.selectPendingByOrderId(order.getId());
+                if (transaction == null) {
+                    // 濡傛灉娌℃湁寰呮敮浠樹氦鏄擄紝灏濊瘯鏌ヨ鏈�鏂颁氦鏄�
+                    transaction = paymentTransactionMapper.selectLatestByOrderId(order.getId());
+                    if (transaction == null || "SUCCEEDED".equals(transaction.getStatus())) {
+                        log.warn("浜ゆ槗宸插畬鎴愭垨涓嶅瓨鍦紝璁㈠崟ID: {}", order.getId());
+                        updateNotifyLog(notifyLog.getId(), true, "浜ゆ槗宸插畬鎴�");
+                        return;
+                    }
+                }
+
+                // 鏇存柊浜ゆ槗鐘舵��
+                transaction.setStatus("SUCCEEDED");
+                if (transactionId != null) {
+                    transaction.setChannelTradeNo(transactionId);
+                }
+                transaction.setPaidAt(LocalDateTime.now());
+                transaction.setResponseSnapshot(JSON.toJSONString(params));
+                paymentTransactionMapper.update(transaction);
+
+                // 鏇存柊璁㈠崟鐘舵��
+                order.setStatus("SUCCEEDED");
+                if (transactionId != null) {
+                    order.setChannelTradeNo(transactionId);
+                }
+                order.setPaidAt(LocalDateTime.now());
+                order.setLatestTransactionId(transaction.getId());
+                paymentOrderMapper.update(order);
+
+                // 鏇存柊閫氱煡鏃ュ織
+                notifyLog.setOrderId(order.getId());
+                notifyLog.setTransactionId(transaction.getId());
+                updateNotifyLog(notifyLog.getId(), true, "澶勭悊鎴愬姛");
+
+                // 瑙﹀彂涓氬姟鍥炶皟
+                bizCallbackService.triggerCallback(order, transaction);
+
+                log.info("绗笁鏂规敮浠樺疂鍥炶皟澶勭悊鎴愬姛锛岃鍗旾D: {}, 浜ゆ槗ID: {}", order.getId(), transaction.getId());
+            } else {
+                log.warn("绗笁鏂规敮浠樺疂鏀粯閲戦寮傚父: {}", paidMoney);
+                updateNotifyLog(notifyLog.getId(), true, "閲戦寮傚父: " + paidMoney);
+            }
+        } catch (Exception e) {
+            log.error("澶勭悊绗笁鏂规敮浠樺疂鍥炶皟寮傚父", e);
+            updateNotifyLog(notifyLog.getId(), false, "澶勭悊寮傚父: " + e.getMessage());
+            throw e;
+        }
+    }
+
+    /**
+     * 浠嶱aidRemarks涓彁鍙栬鍗曞彿
+     * PaidRemarks鍙兘鍖呭惈璁㈠崟鍙峰拰浜ゆ槗鍙凤紝闇�瑕佽В鏋�
+     */
+    private String extractOutTradeNo(String paidRemarks) {
+        if (paidRemarks == null || paidRemarks.isEmpty()) {
+            return null;
+        }
+        
+        // 鍋囪PaidRemarks鏍煎紡: "璁㈠崟鍙�+浜ゆ槗鍙�" 鎴� "璁㈠崟鍙�"
+        // 鏍规嵁瀹為檯鏍煎紡璋冩暣瑙f瀽閫昏緫
+        // 杩欓噷鍋囪璁㈠崟鍙峰湪鏈�鍓嶉潰锛屽彲鑳界敤鏌愪釜鍒嗛殧绗﹀垎闅�
+        
+        // 灏濊瘯鎻愬彇绾暟瀛椾綔涓鸿鍗旾D
+        String[] parts = paidRemarks.split("[^0-9]+");
+        for (String part : parts) {
+            if (part.length() > 10) { // 璁㈠崟ID閫氬父鏄暱鏁村瀷锛岄暱搴﹁緝闀�
+                return part;
+            }
+        }
+        
+        // 濡傛灉娌℃湁鎵惧埌锛岃繑鍥炴暣涓瓧绗︿覆鐨勬暟瀛楅儴鍒�
+        return paidRemarks.replaceAll("[^0-9]", "");
+    }
+
+    /**
+     * 浠嶱aidRemarks涓彁鍙栦氦鏄撳彿
+     */
+    private String extractTransactionId(String paidRemarks) {
+        if (paidRemarks == null || paidRemarks.isEmpty()) {
+            return null;
+        }
+        
+        // 濡傛灉PaidRemarks鍖呭惈鏀粯瀹濅氦鏄撳彿锛堥�氬父浠�2寮�澶寸殑28浣嶆暟瀛楋級
+        // 杩欓噷绠�鍗曡繑鍥瀗ull锛屽彲浠ユ牴鎹疄闄呮牸寮忚皟鏁�
+        return null;
+    }
+
+    /**
+     * 澶勭悊绗笁鏂瑰井淇″洖璋�
+     * 绗笁鏂瑰井淇¢�氳繃GET鏂瑰紡鍥炶皟锛屽弬鏁伴�氳繃URL浼犻��
+     * 
+     * 鍙傛暟鏍煎紡锛�
+     * method: 鏂规硶鍚�
+     * APPID: 搴旂敤ID
+     * PaidMoneyType: 鏀粯绫诲瀷
+     * PaidMoney: 鏀粯閲戦锛堝垎锛�
+     * PaidRemarks: 鏀粯澶囨敞锛堝寘鍚玹ransaction_id锛�
+     * UnixTime: 鏃堕棿鎴�
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public void processWechatThirdPartyNotify(Map<String, String> params) {
+        String method = params.get("method"); // 鏂规硶鍚�
+        String appId = params.get("APPID"); // 搴旂敤ID
+        String paidMoneyType = params.get("PaidMoneyType"); // 鏀粯绫诲瀷
+        String paidMoney = params.get("PaidMoney"); // 鏀粯閲戦锛堝垎锛�
+        String paidRemarks = params.get("PaidRemarks"); // 鏀粯澶囨敞锛堝彲鑳藉寘鍚鍗曞彿鍜屼氦鏄撳彿锛�
+        String unixTime = params.get("UnixTime"); // 鏃堕棿鎴�
+
+        log.info("澶勭悊绗笁鏂瑰井淇″洖璋冿紝method: {}, APPID: {}, PaidMoneyType: {}, PaidMoney: {}, PaidRemarks: {}, UnixTime: {}", 
+                method, appId, paidMoneyType, paidMoney, paidRemarks, unixTime);
+        log.info("绗笁鏂瑰井淇″洖璋冨畬鏁村弬鏁�: {}", params);
+
+        // 浠嶱aidRemarks涓彁鍙栬鍗曞彿锛坥ut_trade_no锛�
+        String outTradeNo = extractOutTradeNo(paidRemarks);
+        String transactionId = extractTransactionId(paidRemarks);
+        
+        if (outTradeNo == null || outTradeNo.isEmpty()) {
+            log.error("鏃犳硶浠嶱aidRemarks涓彁鍙栬鍗曞彿: {}", paidRemarks);
+            return;
+        }
+
+        log.info("瑙f瀽鍑鸿鍗曞彿: {}, 浜ゆ槗鍙�: {}", outTradeNo, transactionId);
+
+        // 妫�鏌ュ箓绛夋�э紙浣跨敤璁㈠崟鍙锋垨鏃堕棿鎴筹級
+        String notifyId = transactionId != null ? transactionId : (outTradeNo + "_" + unixTime);
+        if (isNotifyProcessed("WECHAT_THIRD_PARTY", notifyId)) {
+            log.info("绗笁鏂瑰井淇″洖璋冨凡澶勭悊杩囷紝鏍囪瘑: {}", notifyId);
+            return;
+        }
+
+        // 璁板綍鍥炶皟鏃ュ織
+        NotifyLog notifyLog = saveNotifyLog("WECHAT_THIRD_PARTY", notifyId, JSON.toJSONString(params), true);
+
+        try {
+            // 绗笁鏂瑰井淇℃垚鍔熺殑鍒ゆ柇鏉′欢锛堥�氬父鍙鑳芥敹鍒板洖璋冨氨琛ㄧず鏀粯鎴愬姛锛�
+            if (paidMoney != null && Integer.parseInt(paidMoney) > 0) {
+                // 鏌ヨ璁㈠崟锛堜娇鐢ㄥ晢鎴疯鍗曞彿锛岃繖閲岀殑outTradeNo瀹為檯鏄垜浠殑璁㈠崟ID锛�
+                PaymentOrder order = paymentOrderMapper.selectById(Long.valueOf(outTradeNo));
+                if (order == null) {
+                    log.error("璁㈠崟涓嶅瓨鍦�: {}", outTradeNo);
+                    updateNotifyLog(notifyLog.getId(), false, "璁㈠崟涓嶅瓨鍦�");
+                    return;
+                }
+
+                // 楠岃瘉閲戦鏄惁鍖归厤
+                if (!order.getAmount().equals(Integer.parseInt(paidMoney))) {
+                    log.error("璁㈠崟閲戦涓嶅尮閰嶏紝璁㈠崟閲戦: {}, 鍥炶皟閲戦: {}", order.getAmount(), paidMoney);
+                    updateNotifyLog(notifyLog.getId(), false, "閲戦涓嶅尮閰�");
+                    return;
+                }
+
+                // 鏌ヨ寰呮敮浠樹氦鏄�
+                PaymentTransaction transaction = paymentTransactionMapper.selectPendingByOrderId(order.getId());
+                if (transaction == null) {
+                    // 濡傛灉娌℃湁寰呮敮浠樹氦鏄擄紝灏濊瘯鏌ヨ鏈�鏂颁氦鏄�
+                    transaction = paymentTransactionMapper.selectLatestByOrderId(order.getId());
+                    if (transaction == null || "SUCCEEDED".equals(transaction.getStatus())) {
+                        log.warn("浜ゆ槗宸插畬鎴愭垨涓嶅瓨鍦紝璁㈠崟ID: {}", order.getId());
+                        updateNotifyLog(notifyLog.getId(), true, "浜ゆ槗宸插畬鎴�");
+                        return;
+                    }
+                }
+
+                // 鏇存柊浜ゆ槗鐘舵��
+                transaction.setStatus("SUCCEEDED");
+                if (transactionId != null) {
+                    transaction.setChannelTradeNo(transactionId);
+                }
+                transaction.setPaidAt(LocalDateTime.now());
+                transaction.setResponseSnapshot(JSON.toJSONString(params));
+                paymentTransactionMapper.update(transaction);
+
+                // 鏇存柊璁㈠崟鐘舵��
+                order.setStatus("SUCCEEDED");
+                if (transactionId != null) {
+                    order.setChannelTradeNo(transactionId);
+                }
+                order.setPaidAt(LocalDateTime.now());
+                order.setLatestTransactionId(transaction.getId());
+                paymentOrderMapper.update(order);
+
+                // 鏇存柊閫氱煡鏃ュ織
+                notifyLog.setOrderId(order.getId());
+                notifyLog.setTransactionId(transaction.getId());
+                updateNotifyLog(notifyLog.getId(), true, "澶勭悊鎴愬姛");
+
+                // 瑙﹀彂涓氬姟鍥炶皟
+                bizCallbackService.triggerCallback(order, transaction);
+
+                log.info("绗笁鏂瑰井淇″洖璋冨鐞嗘垚鍔燂紝璁㈠崟ID: {}, 浜ゆ槗ID: {}", order.getId(), transaction.getId());
+            } else {
+                log.warn("绗笁鏂瑰井淇℃敮浠橀噾棰濆紓甯�: {}", paidMoney);
+                updateNotifyLog(notifyLog.getId(), true, "閲戦寮傚父: " + paidMoney);
+            }
+        } catch (Exception e) {
+            log.error("澶勭悊绗笁鏂瑰井淇″洖璋冨紓甯�", e);
+            updateNotifyLog(notifyLog.getId(), false, "澶勭悊寮傚父: " + e.getMessage());
+            throw e;
+        }
+    }
+
+    /**
      * 妫�鏌ラ�氱煡鏄惁宸插鐞嗭紙骞傜瓑鎬э級
      */
     private boolean isNotifyProcessed(String channel, String notifyId) {

--
Gitblit v1.9.1