From 4c2dd7fdd86ddfad69611a5e825ff4a0cfab3c06 Mon Sep 17 00:00:00 2001
From: “mitao” <“2763622819@qq.com”>
Date: 星期四, 30 四月 2026 22:03:06 +0800
Subject: [PATCH] fix:登录注册修改

---
 tcm-training-admin-backend/src/test/java/com/tcm/training/admin/app/settings/service/AppSettingsServiceTest.java |  156 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 151 insertions(+), 5 deletions(-)

diff --git a/tcm-training-admin-backend/src/test/java/com/tcm/training/admin/app/settings/service/AppSettingsServiceTest.java b/tcm-training-admin-backend/src/test/java/com/tcm/training/admin/app/settings/service/AppSettingsServiceTest.java
index 8300e88..2408f06 100644
--- a/tcm-training-admin-backend/src/test/java/com/tcm/training/admin/app/settings/service/AppSettingsServiceTest.java
+++ b/tcm-training-admin-backend/src/test/java/com/tcm/training/admin/app/settings/service/AppSettingsServiceTest.java
@@ -2,12 +2,13 @@
 
 import com.baomidou.mybatisplus.core.MybatisConfiguration;
 import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
+import cn.dev33.satoken.stp.SaTokenInfo;
 import com.tcm.training.admin.app.auth.service.AppAuthSessionService;
+import com.tcm.training.admin.app.auth.vo.AppLoginResponse;
 import com.tcm.training.admin.app.auth.service.AppSmsCodeService;
 import com.tcm.training.admin.app.auth.service.AppWechatAuthClient;
 import com.tcm.training.admin.app.settings.dto.AppSettingsPhoneBindRequest;
 import com.tcm.training.admin.app.settings.mapper.AppUserNotificationSettingMapper;
-import com.tcm.training.admin.app.settings.vo.AppSettingsProfileVO;
 import com.tcm.training.admin.app.share.service.AppShareService;
 import com.tcm.training.admin.member.entity.AppUser;
 import com.tcm.training.admin.member.mapper.UserMapper;
@@ -28,6 +29,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -103,12 +105,15 @@
         when(userMapper.selectById(1L)).thenReturn(currentUser);
         when(userMapper.selectOne(any())).thenReturn(null);
         doNothing().when(appSmsCodeService).validatePhoneChangeCode("13800138000", "123456");
+        when(appAuthSessionService.getTokenInfo()).thenReturn(buildToken("bind-token"));
 
-        AppSettingsProfileVO response = appSettingsService.bindPhone(request);
+        AppLoginResponse response = appSettingsService.bindPhone(request);
 
         verify(userMapper).updateById(appUserCaptor.capture());
+        verify(appAuthSessionService).login(1L);
         assertEquals("13800138000", appUserCaptor.getValue().getPhone());
-        assertEquals("13800138000", response.getPhone());
+        assertEquals("13800138000", response.getUser().getPhone());
+        assertEquals("bind-token", response.getToken());
     }
 
     /**
@@ -132,10 +137,141 @@
     }
 
     /**
-     * 目标手机号被其他有效用户占用时不允许绑定。
+     * 微信临时账号绑定已注册但未绑定微信的手机号时,应合并到手机号账号。
      */
     @Test
-    void bindPhoneShouldRejectOccupiedPhone() {
+    void bindPhoneShouldMergeWechatUserIntoExistingPhoneUser() {
+        AppSettingsPhoneBindRequest request = new AppSettingsPhoneBindRequest();
+        request.setNewPhone("13800138000");
+        request.setCode("123456");
+        AppUser currentUser = buildEnabledUser(null);
+        currentUser.setWechatOpenid("wx-openid");
+        currentUser.setNickname(null);
+        currentUser.setWechatNickname("微信昵称");
+        AppUser occupiedUser = buildEnabledUser("13800138000");
+        occupiedUser.setId(2L);
+        occupiedUser.setNickname(null);
+
+        when(appAuthSessionService.requireLoginUserId()).thenReturn(1L);
+        when(userMapper.selectById(1L)).thenReturn(currentUser);
+        when(userMapper.selectOne(any())).thenReturn(occupiedUser);
+        doNothing().when(appSmsCodeService).validatePhoneChangeCode("13800138000", "123456");
+        when(appAuthSessionService.getTokenInfo()).thenReturn(buildToken("merged-token"));
+
+        AppLoginResponse response = appSettingsService.bindPhone(request);
+
+        verify(userMapper, times(2)).updateById(appUserCaptor.capture());
+        AppUser mergedUser = appUserCaptor.getAllValues().get(0);
+        AppUser deletedTemporaryUser = appUserCaptor.getAllValues().get(1);
+        verify(appAuthSessionService).login(2L);
+        assertEquals("wx-openid", mergedUser.getWechatOpenid());
+        assertEquals("微信昵称", mergedUser.getNickname());
+        assertEquals(Integer.valueOf(1), deletedTemporaryUser.getDeleted());
+        assertEquals(Long.valueOf(2L), response.getUser().getId());
+        assertEquals("merged-token", response.getToken());
+    }
+
+    /**
+     * 微信临时账号绑定已绑定微信的手机号时,应直接覆盖目标账号微信票据。
+     */
+    @Test
+    void bindPhoneShouldOverwriteWechatBindingWhenPhoneUserAlreadyBoundWechat() {
+        AppSettingsPhoneBindRequest request = new AppSettingsPhoneBindRequest();
+        request.setNewPhone("13800138000");
+        request.setCode("123456");
+        AppUser currentUser = buildEnabledUser(null);
+        currentUser.setWechatOpenid("wx-openid");
+        currentUser.setWechatNickname("新微信昵称");
+        AppUser occupiedUser = buildEnabledUser("13800138000");
+        occupiedUser.setId(2L);
+        occupiedUser.setWechatOpenid("other-wx-openid");
+
+        when(appAuthSessionService.requireLoginUserId()).thenReturn(1L);
+        when(userMapper.selectById(1L)).thenReturn(currentUser);
+        when(userMapper.selectOne(any())).thenReturn(occupiedUser);
+        doNothing().when(appSmsCodeService).validatePhoneChangeCode("13800138000", "123456");
+        when(appAuthSessionService.getTokenInfo()).thenReturn(buildToken("wechat-overwrite-token"));
+
+        AppLoginResponse response = appSettingsService.bindPhone(request);
+
+        verify(userMapper, times(2)).updateById(appUserCaptor.capture());
+        AppUser mergedUser = appUserCaptor.getAllValues().get(0);
+        AppUser deletedTemporaryUser = appUserCaptor.getAllValues().get(1);
+        verify(appAuthSessionService).login(2L);
+        assertEquals("wx-openid", mergedUser.getWechatOpenid());
+        assertEquals("新微信昵称", mergedUser.getWechatNickname());
+        assertEquals(Integer.valueOf(1), deletedTemporaryUser.getDeleted());
+        assertEquals(Long.valueOf(2L), response.getUser().getId());
+    }
+
+    /**
+     * 苹果临时账号绑定已注册但未绑定苹果的手机号时,应合并到手机号账号。
+     */
+    @Test
+    void bindPhoneShouldMergeAppleUserIntoExistingPhoneUser() {
+        AppSettingsPhoneBindRequest request = new AppSettingsPhoneBindRequest();
+        request.setNewPhone("13800138000");
+        request.setCode("123456");
+        AppUser currentUser = buildEnabledUser(null);
+        currentUser.setAppleIdentitySubject("apple-subject");
+        currentUser.setAppleUserIdentifier("apple-user");
+        AppUser occupiedUser = buildEnabledUser("13800138000");
+        occupiedUser.setId(2L);
+
+        when(appAuthSessionService.requireLoginUserId()).thenReturn(1L);
+        when(userMapper.selectById(1L)).thenReturn(currentUser);
+        when(userMapper.selectOne(any())).thenReturn(occupiedUser);
+        doNothing().when(appSmsCodeService).validatePhoneChangeCode("13800138000", "123456");
+        when(appAuthSessionService.getTokenInfo()).thenReturn(buildToken("apple-merged-token"));
+
+        AppLoginResponse response = appSettingsService.bindPhone(request);
+
+        verify(userMapper, times(2)).updateById(appUserCaptor.capture());
+        AppUser mergedUser = appUserCaptor.getAllValues().get(0);
+        verify(appAuthSessionService).login(2L);
+        assertEquals("apple-subject", mergedUser.getAppleIdentitySubject());
+        assertEquals("apple-user", mergedUser.getAppleUserIdentifier());
+        assertEquals(Long.valueOf(2L), response.getUser().getId());
+    }
+
+    /**
+     * 苹果临时账号绑定已绑定苹果的手机号时,应直接覆盖目标账号苹果票据。
+     */
+    @Test
+    void bindPhoneShouldOverwriteAppleBindingWhenPhoneUserAlreadyBoundApple() {
+        AppSettingsPhoneBindRequest request = new AppSettingsPhoneBindRequest();
+        request.setNewPhone("13800138000");
+        request.setCode("123456");
+        AppUser currentUser = buildEnabledUser(null);
+        currentUser.setAppleIdentitySubject("apple-subject");
+        currentUser.setAppleUserIdentifier("apple-user");
+        AppUser occupiedUser = buildEnabledUser("13800138000");
+        occupiedUser.setId(2L);
+        occupiedUser.setAppleIdentitySubject("other-apple-subject");
+
+        when(appAuthSessionService.requireLoginUserId()).thenReturn(1L);
+        when(userMapper.selectById(1L)).thenReturn(currentUser);
+        when(userMapper.selectOne(any())).thenReturn(occupiedUser);
+        doNothing().when(appSmsCodeService).validatePhoneChangeCode("13800138000", "123456");
+        when(appAuthSessionService.getTokenInfo()).thenReturn(buildToken("apple-overwrite-token"));
+
+        AppLoginResponse response = appSettingsService.bindPhone(request);
+
+        verify(userMapper, times(2)).updateById(appUserCaptor.capture());
+        AppUser mergedUser = appUserCaptor.getAllValues().get(0);
+        AppUser deletedTemporaryUser = appUserCaptor.getAllValues().get(1);
+        verify(appAuthSessionService).login(2L);
+        assertEquals("apple-subject", mergedUser.getAppleIdentitySubject());
+        assertEquals("apple-user", mergedUser.getAppleUserIdentifier());
+        assertEquals(Integer.valueOf(1), deletedTemporaryUser.getDeleted());
+        assertEquals(Long.valueOf(2L), response.getUser().getId());
+    }
+
+    /**
+     * 非第三方临时账号绑定已注册手机号时仍按占用处理。
+     */
+    @Test
+    void bindPhoneShouldRejectOccupiedPhoneWithoutThirdPartyBinding() {
         AppSettingsPhoneBindRequest request = new AppSettingsPhoneBindRequest();
         request.setNewPhone("13800138000");
         request.setCode("123456");
@@ -177,6 +313,16 @@
     }
 
     /**
+     * 构造测试登录态。
+     */
+    private SaTokenInfo buildToken(String tokenValue) {
+        SaTokenInfo tokenInfo = new SaTokenInfo();
+        tokenInfo.setTokenValue(tokenValue);
+        tokenInfo.setTokenTimeout(7200L);
+        return tokenInfo;
+    }
+
+    /**
      * 构造启用状态 APP 用户。
      */
     private AppUser buildEnabledUser(String phone) {

--
Gitblit v1.7.1