From 9f8395fab13ca4b230a0f7d62636e209745c91d4 Mon Sep 17 00:00:00 2001
From: lrj <owen.stl@gmail.com>
Date: 星期日, 28 九月 2025 14:16:18 +0800
Subject: [PATCH] feat: 完善注册流程的文件上传功能

---
 backend/src/main/java/com/rongyichuang/auth/service/AuthService.java |  546 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 540 insertions(+), 6 deletions(-)

diff --git a/backend/src/main/java/com/rongyichuang/auth/service/AuthService.java b/backend/src/main/java/com/rongyichuang/auth/service/AuthService.java
index e691bb4..bd2fa0f 100644
--- a/backend/src/main/java/com/rongyichuang/auth/service/AuthService.java
+++ b/backend/src/main/java/com/rongyichuang/auth/service/AuthService.java
@@ -2,7 +2,15 @@
 
 import com.rongyichuang.auth.dto.LoginRequest;
 import com.rongyichuang.auth.dto.LoginResponse;
+import com.rongyichuang.auth.dto.PhoneDecryptResponse;
+import com.rongyichuang.auth.dto.WxLoginRequest;
+import com.rongyichuang.auth.dto.WxLoginResponse;
+import com.rongyichuang.auth.entity.WxLoginRecord;
 import com.rongyichuang.auth.util.JwtUtil;
+import com.rongyichuang.service.WechatApiService;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonMappingException;
 import com.rongyichuang.employee.entity.Employee;
 import com.rongyichuang.employee.repository.EmployeeRepository;
 import com.rongyichuang.judge.entity.Judge;
@@ -19,6 +27,11 @@
 import org.springframework.stereotype.Service;
 
 import java.util.Optional;
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.util.Base64;
+import com.fasterxml.jackson.databind.ObjectMapper;
 
 /**
  * 璁よ瘉鏈嶅姟绫�
@@ -45,6 +58,12 @@
 
     @Autowired
     private JwtUtil jwtUtil;
+
+    @Autowired
+    private WxLoginRecordService wxLoginRecordService;
+
+    @Autowired
+    private WechatApiService wechatApiService;
 
     /**
      * 鐢ㄦ埛鐧诲綍
@@ -85,10 +104,10 @@
             throw new BadCredentialsException("娌℃湁鏉冮檺");
         }
 
-        // 6. 鐢熸垚JWT token
+        // 7. 鐢熸垚JWT token
         String token = jwtUtil.generateToken(user.getId(), user.getPhone());
 
-        // 7. 纭畾涓昏瑙掕壊绫诲瀷锛堜紭鍏堢骇锛歟mployee > judge > player锛�
+        // 8. 纭畾涓昏瑙掕壊绫诲瀷锛堜紭鍏堢骇锛歟mployee > judge > player锛�
         String userType;
         if (employeeOpt.isPresent()) {
             userType = "employee";
@@ -98,7 +117,7 @@
             userType = "player";
         }
 
-        // 8. 鏋勫缓鐢ㄦ埛淇℃伅
+        // 9. 鏋勫缓鐢ㄦ埛淇℃伅
         LoginResponse.UserInfo userInfo = new LoginResponse.UserInfo(
                 user.getId(),
                 user.getName(),
@@ -106,7 +125,7 @@
                 userType
         );
 
-        // 9. 璁剧疆鎵�鏈夊叧鑱旂殑瑙掕壊淇℃伅
+        // 10. 璁剧疆鎵�鏈夊叧鑱旂殑瑙掕壊淇℃伅
         if (employeeOpt.isPresent()) {
             Employee employee = employeeOpt.get();
             userInfo.setEmployee(new LoginResponse.EmployeeInfo(
@@ -138,8 +157,7 @@
                     player.getId(),
                     player.getName(),
                     player.getPhone(),
-                    player.getDescription(),
-                    player.getAuditState()
+                    player.getDescription()
             ));
             if (employeeOpt.isEmpty() && judgeOpt.isEmpty()) {
                 logger.info("瀛﹀憳鐧诲綍鎴愬姛锛孖D: {}, 濮撳悕: {}", player.getId(), player.getName());
@@ -148,4 +166,520 @@
 
         return new LoginResponse(token, userInfo);
     }
+
+    /**
+     * 寰俊鐧诲綍
+     */
+    public WxLoginResponse wxLogin(WxLoginRequest wxLoginRequest) throws JsonProcessingException, JsonMappingException {
+        logger.info("=== 寮�濮嬪井淇$櫥褰曟祦绋� ===");
+        logger.info("鐧诲綍鏃堕棿: {}", java.time.LocalDateTime.now());
+        logger.info("璇锋眰鍙傛暟璇︽儏:");
+        logger.info("- code: {}", wxLoginRequest.getCode());
+        logger.info("- code闀垮害: {}", wxLoginRequest.getCode() != null ? wxLoginRequest.getCode().length() : 0);
+        logger.info("- wxOpenid: {}", wxLoginRequest.getWxOpenid());
+        logger.info("- wxUnionid: {}", wxLoginRequest.getWxUnionid());
+        logger.info("- phone: {}", wxLoginRequest.getPhone());
+        logger.info("- loginIp: {}", wxLoginRequest.getLoginIp());
+        logger.info("- deviceInfo: {}", wxLoginRequest.getDeviceInfo());
+        logger.info("- phoneAuthorized: {}", wxLoginRequest.getPhoneAuthorized());
+
+        // 1. 閫氳繃code璋冪敤寰俊API鑾峰彇openid鍜寀nionid
+        WechatApiService.WechatUserInfo wechatUserInfo = null;
+        if (wxLoginRequest.getCode() != null && !wxLoginRequest.getCode().trim().isEmpty()) {
+            logger.info("姝ラ1: 璋冪敤寰俊API鑾峰彇鐢ㄦ埛淇℃伅");
+            logger.info("浣跨敤code: {}", wxLoginRequest.getCode());
+            
+            try {
+                wechatUserInfo = wechatApiService.getWechatUserInfo(wxLoginRequest.getCode());
+                
+                // 灏嗕粠寰俊API鑾峰彇鐨勪俊鎭缃埌璇锋眰瀵硅薄涓�
+                wxLoginRequest.setWxOpenid(wechatUserInfo.getOpenid());
+                wxLoginRequest.setWxUnionid(wechatUserInfo.getUnionid());
+                wxLoginRequest.setSessionKey(wechatUserInfo.getSessionKey());
+                
+                logger.info("鉁� 浠庡井淇PI鑾峰彇鐢ㄦ埛淇℃伅鎴愬姛");
+                logger.info("- openid: {}", wechatUserInfo.getOpenid());
+                logger.info("- unionid: {}", wechatUserInfo.getUnionid());
+                logger.info("- sessionKey闀垮害: {}", wechatUserInfo.getSessionKey() != null ? wechatUserInfo.getSessionKey().length() : 0);
+                
+            } catch (Exception e) {
+                logger.error("鉂� 璋冪敤寰俊API澶辫触");
+                logger.error("寮傚父淇℃伅: {}", e.getMessage());
+                logger.error("寮傚父鍫嗘爤:", e);
+                throw e;
+            }
+        } else {
+            logger.warn("鈿狅笍 寰俊鐧诲綍code涓虹┖锛屽皢浣跨敤璇锋眰涓殑openid鍜寀nionid");
+            logger.info("璇锋眰涓殑openid: {}", wxLoginRequest.getWxOpenid());
+            logger.info("璇锋眰涓殑unionid: {}", wxLoginRequest.getWxUnionid());
+        }
+
+        User user = null;
+        boolean isNewUser = false;
+
+        logger.info("姝ラ2: 鏌ユ壘鎴栧垱寤虹敤鎴�");
+        
+        // 2. 棣栧厛灏濊瘯閫氳繃openid鏌ユ壘鐢ㄦ埛
+        if (wxLoginRequest.getWxOpenid() != null && !wxLoginRequest.getWxOpenid().trim().isEmpty()) {
+            logger.info("灏濊瘯閫氳繃openid鏌ユ壘鐢ㄦ埛: {}", wxLoginRequest.getWxOpenid());
+            
+            try {
+                Optional<User> userOpt = userRepository.findByWxOpenid(wxLoginRequest.getWxOpenid());
+                if (userOpt.isPresent()) {
+                    user = userOpt.get();
+                    logger.info("鉁� 閫氳繃openid鎵惧埌鐢ㄦ埛");
+                    logger.info("- 鐢ㄦ埛ID: {}", user.getId());
+                    logger.info("- 鐢ㄦ埛濮撳悕: {}", user.getName());
+                    logger.info("- 鐢ㄦ埛鎵嬫満鍙�: {}", user.getPhone());
+                    logger.info("- 鐢ㄦ埛unionid: {}", user.getWxUnionid());
+                } else {
+                    logger.info("鉂� 閫氳繃openid鏈壘鍒扮敤鎴�");
+                }
+            } catch (Exception e) {
+                logger.error("鉂� 閫氳繃openid鏌ユ壘鐢ㄦ埛鏃跺彂鐢熷紓甯�: {}", e.getMessage());
+                logger.error("寮傚父鍫嗘爤:", e);
+            }
+        } else {
+            logger.warn("鈿狅笍 openid涓虹┖锛岃烦杩噊penid鏌ユ壘");
+        }
+
+        // 3. 濡傛灉閫氳繃openid娌℃壘鍒帮紝灏濊瘯閫氳繃unionid鏌ユ壘
+        if (user == null && wxLoginRequest.getWxUnionid() != null && !wxLoginRequest.getWxUnionid().trim().isEmpty()) {
+            logger.info("灏濊瘯閫氳繃unionid鏌ユ壘鐢ㄦ埛: {}", wxLoginRequest.getWxUnionid());
+            
+            try {
+                Optional<User> userOpt = userRepository.findByWxUnionid(wxLoginRequest.getWxUnionid());
+                if (userOpt.isPresent()) {
+                    user = userOpt.get();
+                    logger.info("鉁� 閫氳繃unionid鎵惧埌鐢ㄦ埛");
+                    logger.info("- 鐢ㄦ埛ID: {}", user.getId());
+                    logger.info("- 鐢ㄦ埛濮撳悕: {}", user.getName());
+                    logger.info("- 鐢ㄦ埛鎵嬫満鍙�: {}", user.getPhone());
+                    logger.info("- 鐢ㄦ埛openid: {}", user.getWxOpenid());
+                    
+                    // 鏇存柊鐢ㄦ埛鐨刼penid锛堝鏋滀箣鍓嶆病鏈夛級
+                    if (user.getWxOpenid() == null || user.getWxOpenid().trim().isEmpty()) {
+                        logger.info("鐢ㄦ埛openid涓虹┖锛岄渶瑕佹洿鏂�");
+                        user.setWxOpenid(wxLoginRequest.getWxOpenid());
+                        try {
+                            userRepository.save(user);
+                            logger.info("鉁� 鎴愬姛鏇存柊鐢ㄦ埛openid锛岀敤鎴稩D: {}", user.getId());
+                        } catch (Exception e) {
+                            logger.error("鉂� 鏇存柊鐢ㄦ埛openid澶辫触: {}", e.getMessage());
+                            logger.error("寮傚父鍫嗘爤:", e);
+                        }
+                    } else {
+                        logger.info("鐢ㄦ埛openid宸插瓨鍦紝鏃犻渶鏇存柊");
+                    }
+                } else {
+                    logger.info("鉂� 閫氳繃unionid鏈壘鍒扮敤鎴�");
+                }
+            } catch (Exception e) {
+                logger.error("鉂� 閫氳繃unionid鏌ユ壘鐢ㄦ埛鏃跺彂鐢熷紓甯�: {}", e.getMessage());
+                logger.error("寮傚父鍫嗘爤:", e);
+            }
+        } else {
+            logger.warn("鈿狅笍 unionid涓虹┖鎴栫敤鎴峰凡鎵惧埌锛岃烦杩噓nionid鏌ユ壘");
+        }
+
+        // 4. 濡傛灉閮芥病鎵惧埌锛屽垱寤烘柊鐢ㄦ埛
+        if (user == null) {
+            logger.info("鏈壘鍒扮幇鏈夌敤鎴凤紝寮�濮嬪垱寤烘柊鐢ㄦ埛");
+            logger.info("鏂扮敤鎴蜂俊鎭�:");
+            logger.info("- openid: {}", wxLoginRequest.getWxOpenid());
+            logger.info("- unionid: {}", wxLoginRequest.getWxUnionid());
+            logger.info("- phone: {}", wxLoginRequest.getPhone());
+            
+            try {
+                user = new User();
+                user.setWxOpenid(wxLoginRequest.getWxOpenid());
+                user.setWxUnionid(wxLoginRequest.getWxUnionid());
+                user.setName("寰俊鐢ㄦ埛"); // 榛樿鍚嶇О锛屽悗缁彲浠ユ洿鏂�
+                user.setPhone(wxLoginRequest.getPhone()); // 濡傛灉鏈夋巿鏉冩墜鏈哄彿
+                
+                user = userRepository.save(user);
+                isNewUser = true;
+                
+                logger.info("鉁� 鎴愬姛鍒涘缓鏂扮殑寰俊鐢ㄦ埛");
+                logger.info("- 鏂扮敤鎴稩D: {}", user.getId());
+                logger.info("- 鏂扮敤鎴峰鍚�: {}", user.getName());
+                logger.info("- 鏂扮敤鎴锋墜鏈哄彿: {}", user.getPhone());
+                
+            } catch (Exception e) {
+                logger.error("鉂� 鍒涘缓鏂扮敤鎴峰け璐�");
+                logger.error("寮傚父淇℃伅: {}", e.getMessage());
+                logger.error("寮傚父鍫嗘爤:", e);
+                throw new RuntimeException("鍒涘缓鏂扮敤鎴峰け璐�: " + e.getMessage(), e);
+            }
+        }
+
+        // 5. 璁板綍鐧诲綍淇℃伅鍒版柊琛�
+        logger.info("姝ラ3: 璁板綍鐧诲綍淇℃伅");
+        WxLoginRecord loginRecord = null;
+        try {
+            loginRecord = wxLoginRecordService.createLoginRecord(
+                    wxLoginRequest.getWxOpenid(),
+                    wxLoginRequest.getWxUnionid(),
+                    user.getId(),
+                    wxLoginRequest.getLoginIp(),
+                    wxLoginRequest.getDeviceInfo(),
+                    wxLoginRequest.getSessionKey(),
+                    wxLoginRequest.getPhoneAuthorized()
+            );
+            logger.info("鉁� 鎴愬姛鍒涘缓鐧诲綍璁板綍锛岃褰旾D: {}", loginRecord.getId());
+        } catch (Exception e) {
+            logger.error("鉂� 鍒涘缓鐧诲綍璁板綍澶辫触: {}", e.getMessage());
+            logger.error("寮傚父鍫嗘爤:", e);
+            throw new RuntimeException("鍒涘缓鐧诲綍璁板綍澶辫触: " + e.getMessage(), e);
+        }
+
+        // 6. 鏌ユ壘鍏宠仈鐨勫憳宸ャ�佽瘎濮斿拰瀛﹀憳淇℃伅
+        logger.info("姝ラ4: 鏌ユ壘鐢ㄦ埛鍏宠仈鐨勮鑹蹭俊鎭�");
+        logger.info("鏌ユ壘鐢ㄦ埛ID: {}", user.getId());
+        
+        Optional<Employee> employeeOpt = Optional.empty();
+        Optional<Judge> judgeOpt = Optional.empty();
+        Optional<Player> playerOpt = Optional.empty();
+        
+        try {
+            employeeOpt = employeeRepository.findByUserId(user.getId());
+            logger.info("鍛樺伐瑙掕壊鏌ユ壘缁撴灉: {}", employeeOpt.isPresent() ? "鎵惧埌" : "鏈壘鍒�");
+            if (employeeOpt.isPresent()) {
+                Employee employee = employeeOpt.get();
+                logger.info("- 鍛樺伐ID: {}", employee.getId());
+                logger.info("- 鍛樺伐濮撳悕: {}", employee.getName());
+                logger.info("- 鍛樺伐瑙掕壊ID: {}", employee.getRoleId());
+            }
+        } catch (Exception e) {
+            logger.error("鉂� 鏌ユ壘鍛樺伐瑙掕壊鏃跺彂鐢熷紓甯�: {}", e.getMessage());
+            logger.error("寮傚父鍫嗘爤:", e);
+        }
+        
+        try {
+            judgeOpt = judgeRepository.findByUserId(user.getId());
+            logger.info("璇勫瑙掕壊鏌ユ壘缁撴灉: {}", judgeOpt.isPresent() ? "鎵惧埌" : "鏈壘鍒�");
+            if (judgeOpt.isPresent()) {
+                Judge judge = judgeOpt.get();
+                logger.info("- 璇勫ID: {}", judge.getId());
+                logger.info("- 璇勫濮撳悕: {}", judge.getName());
+                logger.info("- 璇勫鑱岀О: {}", judge.getTitle());
+                logger.info("- 璇勫鍏徃: {}", judge.getCompany());
+            }
+        } catch (Exception e) {
+            logger.error("鉂� 鏌ユ壘璇勫瑙掕壊鏃跺彂鐢熷紓甯�: {}", e.getMessage());
+            logger.error("寮傚父鍫嗘爤:", e);
+        }
+        
+        try {
+            playerOpt = playerRepository.findByUserId(user.getId());
+            logger.info("瀛﹀憳瑙掕壊鏌ユ壘缁撴灉: {}", playerOpt.isPresent() ? "鎵惧埌" : "鏈壘鍒�");
+            if (playerOpt.isPresent()) {
+                Player player = playerOpt.get();
+                logger.info("- 瀛﹀憳ID: {}", player.getId());
+                logger.info("- 瀛﹀憳濮撳悕: {}", player.getName());
+                logger.info("- 瀛﹀憳鎵嬫満鍙�: {}", player.getPhone());
+            }
+        } catch (Exception e) {
+            logger.error("鉂� 鏌ユ壘瀛﹀憳瑙掕壊鏃跺彂鐢熷紓甯�: {}", e.getMessage());
+            logger.error("寮傚父鍫嗘爤:", e);
+        }
+
+        // 6. 鐢熸垚JWT token
+        logger.info("姝ラ5: 鐢熸垚JWT token");
+        String tokenIdentifier = user.getPhone() != null ? user.getPhone() : user.getWxOpenid();
+        logger.info("Token鏍囪瘑绗�: {}", tokenIdentifier);
+        
+        String token = null;
+        try {
+            token = jwtUtil.generateToken(user.getId(), tokenIdentifier);
+            logger.info("鉁� 鎴愬姛鐢熸垚JWT token锛岄暱搴�: {}", token != null ? token.length() : 0);
+        } catch (Exception e) {
+            logger.error("鉂� 鐢熸垚JWT token澶辫触: {}", e.getMessage());
+            logger.error("寮傚父鍫嗘爤:", e);
+            throw new RuntimeException("鐢熸垚JWT token澶辫触: " + e.getMessage(), e);
+        }
+
+        // 7. 纭畾涓昏瑙掕壊绫诲瀷锛堜紭鍏堢骇锛歟mployee > judge > player锛�
+        logger.info("姝ラ6: 纭畾鐢ㄦ埛涓昏瑙掕壊绫诲瀷");
+        String userType;
+        if (employeeOpt.isPresent()) {
+            userType = "employee";
+            logger.info("鐢ㄦ埛涓昏瑙掕壊: 鍛樺伐");
+        } else if (judgeOpt.isPresent()) {
+            userType = "judge";
+            logger.info("鐢ㄦ埛涓昏瑙掕壊: 璇勫");
+        } else if (playerOpt.isPresent()) {
+            userType = "player";
+            logger.info("鐢ㄦ埛涓昏瑙掕壊: 瀛﹀憳");
+        } else {
+            userType = "user"; // 鏅�氬井淇$敤鎴�
+            logger.info("鐢ㄦ埛涓昏瑙掕壊: 鏅�氬井淇$敤鎴�");
+        }
+
+        // 8. 鏋勫缓鐢ㄦ埛淇℃伅
+        logger.info("姝ラ7: 鏋勫缓鐢ㄦ埛淇℃伅鍝嶅簲");
+        LoginResponse.UserInfo userInfo = null;
+        try {
+            userInfo = new LoginResponse.UserInfo(
+                    user.getId(),
+                    user.getName(),
+                    user.getPhone(),
+                    userType
+            );
+            logger.info("鉁� 鎴愬姛鏋勫缓鍩虹鐢ㄦ埛淇℃伅");
+            logger.info("- 鐢ㄦ埛ID: {}", user.getId());
+            logger.info("- 鐢ㄦ埛濮撳悕: {}", user.getName());
+            logger.info("- 鐢ㄦ埛鎵嬫満鍙�: {}", user.getPhone());
+            logger.info("- 鐢ㄦ埛绫诲瀷: {}", userType);
+        } catch (Exception e) {
+            logger.error("鉂� 鏋勫缓鍩虹鐢ㄦ埛淇℃伅澶辫触: {}", e.getMessage());
+            logger.error("寮傚父鍫嗘爤:", e);
+            throw new RuntimeException("鏋勫缓鍩虹鐢ㄦ埛淇℃伅澶辫触: " + e.getMessage(), e);
+        }
+
+        // 9. 璁剧疆鎵�鏈夊叧鑱旂殑瑙掕壊淇℃伅
+        logger.info("姝ラ8: 璁剧疆瑙掕壊璇︾粏淇℃伅");
+        
+        if (employeeOpt.isPresent()) {
+            try {
+                Employee employee = employeeOpt.get();
+                userInfo.setEmployee(new LoginResponse.EmployeeInfo(
+                        employee.getId(),
+                        employee.getName(),
+                        employee.getRoleId(),
+                        employee.getDescription()
+                ));
+                logger.info("鉁� 璁剧疆鍛樺伐淇℃伅鎴愬姛");
+                logger.info("- 鍛樺伐ID: {}", employee.getId());
+                logger.info("- 鍛樺伐濮撳悕: {}", employee.getName());
+                logger.info("- 鍛樺伐瑙掕壊ID: {}", employee.getRoleId());
+                logger.info("鍛樺伐寰俊鐧诲綍鎴愬姛锛孖D: {}, 濮撳悕: {}", employee.getId(), employee.getName());
+            } catch (Exception e) {
+                logger.error("鉂� 璁剧疆鍛樺伐淇℃伅澶辫触: {}", e.getMessage());
+                logger.error("寮傚父鍫嗘爤:", e);
+            }
+        }
+
+        if (judgeOpt.isPresent()) {
+            try {
+                Judge judge = judgeOpt.get();
+                userInfo.setJudge(new LoginResponse.JudgeInfo(
+                        judge.getId(),
+                        judge.getName(),
+                        judge.getTitle(),
+                        judge.getCompany(),
+                        judge.getDescription()
+                ));
+                logger.info("鉁� 璁剧疆璇勫淇℃伅鎴愬姛");
+                logger.info("- 璇勫ID: {}", judge.getId());
+                logger.info("- 璇勫濮撳悕: {}", judge.getName());
+                logger.info("- 璇勫鑱岀О: {}", judge.getTitle());
+                logger.info("- 璇勫鍏徃: {}", judge.getCompany());
+                
+                if (employeeOpt.isEmpty()) {
+                    logger.info("璇勫寰俊鐧诲綍鎴愬姛锛孖D: {}, 濮撳悕: {}", judge.getId(), judge.getName());
+                }
+            } catch (Exception e) {
+                logger.error("鉂� 璁剧疆璇勫淇℃伅澶辫触: {}", e.getMessage());
+                logger.error("寮傚父鍫嗘爤:", e);
+            }
+        }
+
+        if (playerOpt.isPresent()) {
+            try {
+                Player player = playerOpt.get();
+                userInfo.setPlayer(new LoginResponse.PlayerInfo(
+                        player.getId(),
+                        player.getName(),
+                        player.getPhone(),
+                        player.getDescription()
+                ));
+                logger.info("鉁� 璁剧疆瀛﹀憳淇℃伅鎴愬姛");
+                logger.info("- 瀛﹀憳ID: {}", player.getId());
+                logger.info("- 瀛﹀憳濮撳悕: {}", player.getName());
+                logger.info("- 瀛﹀憳鎵嬫満鍙�: {}", player.getPhone());
+                
+                if (employeeOpt.isEmpty() && judgeOpt.isEmpty()) {
+                    logger.info("瀛﹀憳寰俊鐧诲綍鎴愬姛锛孖D: {}, 濮撳悕: {}", player.getId(), player.getName());
+                }
+            } catch (Exception e) {
+                logger.error("鉂� 璁剧疆瀛﹀憳淇℃伅澶辫触: {}", e.getMessage());
+                logger.error("寮傚父鍫嗘爤:", e);
+            }
+        }
+
+        logger.info("=== 寰俊鐧诲綍娴佺▼瀹屾垚 ===");
+        logger.info("鐧诲綍缁撴灉:");
+        logger.info("- 鏄惁鏂扮敤鎴�: {}", isNewUser);
+        logger.info("- 鐧诲綍璁板綍ID: {}", loginRecord != null ? loginRecord.getId() : "null");
+        logger.info("- Token闀垮害: {}", token != null ? token.length() : 0);
+        logger.info("- 鐢ㄦ埛绫诲瀷: {}", userType);
+        logger.info("瀹屾垚鏃堕棿: {}", java.time.LocalDateTime.now());
+
+        return new WxLoginResponse(token, userInfo, isNewUser, loginRecord.getId(), wxLoginRequest.getSessionKey());
+    }
+
+    /**
+     * 瑙e瘑寰俊鎵嬫満鍙�
+     */
+    public PhoneDecryptResponse decryptPhoneNumber(String encryptedData, String iv, String sessionKey) {
+        logger.info("=== 寮�濮嬭В瀵嗗井淇℃墜鏈哄彿 ===");
+        logger.info("瑙e瘑鏃堕棿: {}", java.time.LocalDateTime.now());
+        logger.info("encryptedData闀垮害: {}", encryptedData != null ? encryptedData.length() : 0);
+        logger.info("iv闀垮害: {}", iv != null ? iv.length() : 0);
+        logger.info("sessionKey闀垮害: {}", sessionKey != null ? sessionKey.length() : 0);
+
+        try {
+            // 1. Base64瑙g爜
+            byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData);
+            byte[] ivBytes = Base64.getDecoder().decode(iv);
+            byte[] sessionKeyBytes = Base64.getDecoder().decode(sessionKey);
+
+            logger.info("Base64瑙g爜鎴愬姛");
+            logger.info("encryptedBytes闀垮害: {}", encryptedBytes.length);
+            logger.info("ivBytes闀垮害: {}", ivBytes.length);
+            logger.info("sessionKeyBytes闀垮害: {}", sessionKeyBytes.length);
+
+            // 2. AES瑙e瘑
+            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+            SecretKeySpec secretKeySpec = new SecretKeySpec(sessionKeyBytes, "AES");
+            IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
+            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
+
+            byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
+            String decryptedData = new String(decryptedBytes, "UTF-8");
+
+            logger.info("AES瑙e瘑鎴愬姛");
+            logger.info("瑙e瘑鍚庢暟鎹暱搴�: {}", decryptedData.length());
+            logger.info("瑙e瘑鍚庢暟鎹�: {}", decryptedData);
+
+            // 3. 瑙f瀽JSON
+            ObjectMapper objectMapper = new ObjectMapper();
+            WechatPhoneInfo phoneInfo = objectMapper.readValue(decryptedData, WechatPhoneInfo.class);
+
+            logger.info("JSON瑙f瀽鎴愬姛");
+            logger.info("鎵嬫満鍙�: {}", phoneInfo.getPhoneNumber());
+            logger.info("绾墜鏈哄彿: {}", phoneInfo.getPurePhoneNumber());
+            logger.info("鍥藉浠g爜: {}", phoneInfo.getCountryCode());
+
+            PhoneDecryptResponse response = new PhoneDecryptResponse(
+                phoneInfo.getPhoneNumber(),
+                phoneInfo.getPurePhoneNumber(),
+                phoneInfo.getCountryCode()
+            );
+
+            logger.info("鉁� 寰俊鎵嬫満鍙疯В瀵嗘垚鍔�");
+            return response;
+
+        } catch (Exception e) {
+            logger.error("鉂� 寰俊鎵嬫満鍙疯В瀵嗗け璐�", e);
+            String friendlyMessage = getDecryptFriendlyErrorMessage(e);
+            throw new RuntimeException(friendlyMessage, e);
+        }
+    }
+
+    /**
+     * 浣跨敤鏂扮増API閫氳繃code鐩存帴鑾峰彇鎵嬫満鍙�
+     */
+    public PhoneDecryptResponse getPhoneNumberByCode(String code) {
+        logger.info("=== 寮�濮嬩娇鐢ㄦ柊鐗圓PI鑾峰彇鎵嬫満鍙� ===");
+        logger.info("鑾峰彇鏃堕棿: {}", java.time.LocalDateTime.now());
+        logger.info("杈撳叆code: {}", code);
+
+        try {
+            // 璋冪敤寰俊API鏈嶅姟鑾峰彇鎵嬫満鍙�
+            WechatApiService.WechatPhoneInfo phoneInfo = wechatApiService.getPhoneNumberByCode(code);
+
+            logger.info("鉁� 鏂扮増API鑾峰彇鎵嬫満鍙锋垚鍔�");
+            logger.info("鎵嬫満鍙�: {}", phoneInfo.getPhoneNumber());
+            logger.info("绾墜鏈哄彿: {}", phoneInfo.getPurePhoneNumber());
+            logger.info("鍥藉浠g爜: {}", phoneInfo.getCountryCode());
+
+            PhoneDecryptResponse response = new PhoneDecryptResponse(
+                phoneInfo.getPhoneNumber(),
+                phoneInfo.getPurePhoneNumber(),
+                phoneInfo.getCountryCode()
+            );
+
+            return response;
+
+        } catch (Exception e) {
+            logger.error("鉂� 鏂扮増API鑾峰彇鎵嬫満鍙峰け璐�", e);
+            // 鐩存帴浼犻�扺echatApiService鐨勫弸濂介敊璇俊鎭�
+            throw new RuntimeException(e.getMessage(), e);
+        }
+    }
+
+    /**
+     * 寰俊鎵嬫満鍙蜂俊鎭�
+     */
+    @JsonIgnoreProperties(ignoreUnknown = true)
+    public static class WechatPhoneInfo {
+        private String phoneNumber;
+        private String purePhoneNumber;
+        private String countryCode;
+
+        public String getPhoneNumber() {
+            return phoneNumber;
+        }
+
+        public void setPhoneNumber(String phoneNumber) {
+            this.phoneNumber = phoneNumber;
+        }
+
+        public String getPurePhoneNumber() {
+            return purePhoneNumber;
+        }
+
+        public void setPurePhoneNumber(String purePhoneNumber) {
+            this.purePhoneNumber = purePhoneNumber;
+        }
+
+        public String getCountryCode() {
+            return countryCode;
+        }
+
+        public void setCountryCode(String countryCode) {
+            this.countryCode = countryCode;
+        }
+    }
+    
+    /**
+     * 鏍规嵁瑙e瘑寮傚父鎻愪緵鍙嬪ソ鐨勯敊璇俊鎭�
+     */
+    private String getDecryptFriendlyErrorMessage(Exception e) {
+        String errorMessage = e.getMessage();
+        
+        if (e instanceof IllegalArgumentException) {
+            if (errorMessage.contains("Illegal base64 character")) {
+                return "鎺堟潈鏁版嵁鏍煎紡閿欒锛岃閲嶆柊鑾峰彇鎵嬫満鍙锋巿鏉�";
+            }
+        }
+        
+        if (e instanceof javax.crypto.BadPaddingException) {
+            return "鎺堟潈鏁版嵁宸茶繃鏈熸垨鏃犳晥锛岃閲嶆柊鑾峰彇鎵嬫満鍙锋巿鏉�";
+        }
+        
+        if (e instanceof javax.crypto.IllegalBlockSizeException) {
+            return "鎺堟潈鏁版嵁闀垮害閿欒锛岃閲嶆柊鑾峰彇鎵嬫満鍙锋巿鏉�";
+        }
+        
+        if (e instanceof java.security.InvalidKeyException) {
+            return "浼氳瘽瀵嗛挜鏃犳晥锛岃閲嶆柊鐧诲綍鍚庡啀璇�";
+        }
+        
+        if (e instanceof com.fasterxml.jackson.core.JsonParseException) {
+            return "鎺堟潈鏁版嵁瑙f瀽澶辫触锛岃閲嶆柊鑾峰彇鎵嬫満鍙锋巿鏉�";
+        }
+        
+        if (errorMessage.contains("sessionKey")) {
+            return "浼氳瘽宸茶繃鏈燂紝璇烽噸鏂扮櫥褰曞悗鍐嶈瘯";
+        }
+        
+        if (errorMessage.contains("encryptedData")) {
+            return "鎺堟潈鏁版嵁鏃犳晥锛岃閲嶆柊鑾峰彇鎵嬫満鍙锋巿鏉�";
+        }
+        
+        return "鎵嬫満鍙疯В瀵嗗け璐ワ紝璇烽噸鏂拌幏鍙栨墜鏈哄彿鎺堟潈";
+    }
 }
\ No newline at end of file

--
Gitblit v1.8.0