13404089107
2026-04-30 1cf6d1e5883cca7793884ca4151c70049cded9f0
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/auth/service/AppAuthService.java
@@ -12,6 +12,7 @@
import com.tcm.training.admin.app.auth.vo.AppLoginUserVO;
import com.tcm.training.admin.app.auth.vo.AppPasswordResetVerifyResponse;
import com.tcm.training.admin.app.auth.vo.AppSmsCodeSendResponse;
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;
import cn.dev33.satoken.stp.SaTokenInfo;
@@ -41,6 +42,7 @@
    private final AppAuthSessionService appAuthSessionService;
    private final AppWechatAuthClient appWechatAuthClient;
    private final AppAppleAuthClient appAppleAuthClient;
    private final AppShareService appShareService;
    private final StringRedisTemplate stringRedisTemplate;
    /**
@@ -52,6 +54,7 @@
                          AppAuthSessionService appAuthSessionService,
                          AppWechatAuthClient appWechatAuthClient,
                          AppAppleAuthClient appAppleAuthClient,
                          AppShareService appShareService,
                          StringRedisTemplate stringRedisTemplate) {
        this.userMapper = userMapper;
        this.appSmsCodeService = appSmsCodeService;
@@ -59,6 +62,7 @@
        this.appAuthSessionService = appAuthSessionService;
        this.appWechatAuthClient = appWechatAuthClient;
        this.appAppleAuthClient = appAppleAuthClient;
        this.appShareService = appShareService;
        this.stringRedisTemplate = stringRedisTemplate;
    }
@@ -111,6 +115,7 @@
        AppUser user = findUserByWechatOpenid(profile.getOpenid());
        if (user == null) {
            user = buildWechatUser(profile);
            bindInviteRelationIfAbsent(user, request.getInviteCode());
            userMapper.insert(user);
            return createLoginResponse(user);
        }
@@ -271,6 +276,22 @@
    }
    /**
     * 用户尚未绑定诊所关系时,根据医生邀请码补齐上下级关系。
     */
    private void bindInviteRelationIfAbsent(AppUser user, String inviteCode) {
        if (user.getClinicId() != null || user.getSuperiorClinicUserId() != null) {
            return;
        }
        String normalizedInviteCode = normalizeInviteCode(inviteCode);
        if (normalizedInviteCode == null) {
            return;
        }
        AppShareService.InviteBindingTarget bindingTarget = appShareService.resolveInviteBindingTarget(normalizedInviteCode);
        user.setClinicId(bindingTarget.getClinicId());
        user.setSuperiorClinicUserId(bindingTarget.getSuperiorClinicUserId());
    }
    /**
     * 基于苹果资料构造首次登录时的本地普通用户。
     */
    private AppUser buildAppleUser(AppAppleUserProfile profile) {
@@ -367,6 +388,18 @@
    }
    /**
     * 归一化医生邀请码,非法时忽略以保持第三方登录主流程可用。
     */
    private String normalizeInviteCode(String inviteCode) {
        String normalized = trimToNull(inviteCode);
        if (normalized == null) {
            return null;
        }
        String upperInviteCode = normalized.toUpperCase();
        return upperInviteCode.matches("^[A-Z0-9]{6}$") ? upperInviteCode : null;
    }
    /**
     * 归一化并校验忘记密码场景下的新密码格式。
     */
    private String normalizeNewPassword(String password) {