hejianhao
2026-08-28 16a57a8fc6868cea9171a1119698572407a2fc03
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) {