From 2225a5d9243e7f8ece8b57e781534b21acd1ab00 Mon Sep 17 00:00:00 2001
From: “mitao” <“2763622819@qq.com”>
Date: 星期三, 06 五月 2026 16:37:42 +0800
Subject: [PATCH] fix:token续期

---
 tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/settings/service/AppSettingsService.java |   33 +++++++++++++++++++++++++++++++++
 1 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/settings/service/AppSettingsService.java b/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/settings/service/AppSettingsService.java
index 5cd0c21..3dd08a8 100644
--- a/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/settings/service/AppSettingsService.java
+++ b/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/settings/service/AppSettingsService.java
@@ -10,6 +10,7 @@
 import com.tcm.training.admin.app.auth.service.AppSmsCodeService;
 import com.tcm.training.admin.app.auth.service.AppWechatAuthClient;
 import com.tcm.training.admin.app.auth.service.AppWechatUserProfile;
+import com.tcm.training.admin.app.auth.exception.InviteCodeRequiredException;
 import com.tcm.training.admin.app.settings.dto.AppSettingsNotificationUpdateRequest;
 import com.tcm.training.admin.app.settings.dto.AppSettingsPasswordUpdateRequest;
 import com.tcm.training.admin.app.settings.dto.AppSettingsPhoneBindRequest;
@@ -168,6 +169,7 @@
         }
         AppUser occupiedUser = findUserByPhone(newPhone);
         validatePhoneBindTarget(user, occupiedUser);
+        requireInviteCodeWhenDoctorRelationMissing(user, occupiedUser, request.getInviteCode());
         appSmsCodeService.validatePhoneChangeCode(newPhone, code);
         AppUser loginUser = occupiedUser == null
                 ? bindPhoneToCurrentUser(user, newPhone, request.getInviteCode())
@@ -208,10 +210,34 @@
         requireEnabledUser(targetUser);
         copyThirdPartyBinding(currentUser, targetUser);
         fillMissingProfile(targetUser, currentUser);
+        inheritDoctorRelationIfAbsent(targetUser, currentUser);
         bindInviteRelationIfAbsent(targetUser, inviteCode);
         userMapper.updateById(targetUser);
         disableMergedTemporaryUser(currentUser);
         return targetUser;
+    }
+
+    /**
+     * 当临时账号和目标手机号账号都没有医生关系时,绑定手机号阶段必须携带邀请码。
+     */
+    private void requireInviteCodeWhenDoctorRelationMissing(AppUser currentUser, AppUser targetUser, String inviteCode) {
+        if (hasDoctorRelation(currentUser) || hasDoctorRelation(targetUser)) {
+            return;
+        }
+        if (normalizeInviteCode(inviteCode) == null) {
+            throw new InviteCodeRequiredException();
+        }
+    }
+
+    /**
+     * 合并到已有手机号账号时,优先继承临时账号上已存在的医生关系。
+     */
+    private void inheritDoctorRelationIfAbsent(AppUser targetUser, AppUser sourceUser) {
+        if (hasDoctorRelation(targetUser) || !hasDoctorRelation(sourceUser)) {
+            return;
+        }
+        targetUser.setClinicId(sourceUser.getClinicId());
+        targetUser.setSuperiorClinicUserId(sourceUser.getSuperiorClinicUserId());
     }
 
     /**
@@ -487,6 +513,13 @@
     }
 
     /**
+     * 判断账号是否已绑定医生上下级关系。
+     */
+    private boolean hasDoctorRelation(AppUser user) {
+        return user != null && (user.getClinicId() != null || user.getSuperiorClinicUserId() != null);
+    }
+
+    /**
      * 为绑定后的用户签发新的 APP 登录态。
      */
     private AppLoginResponse createLoginResponse(AppUser user) {

--
Gitblit v1.7.1