“mitao”
2026-04-27 69c2c400e6e3393424d704742cd9de0e6da07e2f
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/auth/service/AppAuthService.java
@@ -4,6 +4,7 @@
import com.tcm.training.admin.app.auth.dto.AppPasswordLoginRequest;
import com.tcm.training.admin.app.auth.dto.AppPasswordResetRequest;
import com.tcm.training.admin.app.auth.dto.AppPasswordResetVerifyRequest;
import com.tcm.training.admin.app.auth.dto.AppAppleLoginRequest;
import com.tcm.training.admin.app.auth.dto.AppSmsCodeSendRequest;
import com.tcm.training.admin.app.auth.dto.AppSmsLoginRequest;
import com.tcm.training.admin.app.auth.dto.AppWechatLoginRequest;
@@ -39,6 +40,7 @@
    private final BCryptPasswordEncoder passwordEncoder;
    private final AppAuthSessionService appAuthSessionService;
    private final AppWechatAuthClient appWechatAuthClient;
    private final AppAppleAuthClient appAppleAuthClient;
    private final StringRedisTemplate stringRedisTemplate;
    /**
@@ -49,12 +51,14 @@
                          BCryptPasswordEncoder passwordEncoder,
                          AppAuthSessionService appAuthSessionService,
                          AppWechatAuthClient appWechatAuthClient,
                          AppAppleAuthClient appAppleAuthClient,
                          StringRedisTemplate stringRedisTemplate) {
        this.userMapper = userMapper;
        this.appSmsCodeService = appSmsCodeService;
        this.passwordEncoder = passwordEncoder;
        this.appAuthSessionService = appAuthSessionService;
        this.appWechatAuthClient = appWechatAuthClient;
        this.appAppleAuthClient = appAppleAuthClient;
        this.stringRedisTemplate = stringRedisTemplate;
    }
@@ -114,6 +118,25 @@
        requireEnabledUser(user);
        // 登录时同步微信专用资料,并仅在本地昵称头像为空时补齐展示字段。
        applyWechatProfile(user, profile, false);
        userMapper.updateById(user);
        return createLoginResponse(user);
    }
    /**
     * 使用苹果授权结果完成 APP 登录,首次登录自动创建普通用户。
     */
    public AppLoginResponse appleLogin(AppAppleLoginRequest request) {
        AppAppleUserProfile profile = appAppleAuthClient.resolveUserProfile(request);
        AppUser user = findUserByAppleSubject(profile.getSubject());
        if (user == null) {
            user = buildAppleUser(profile);
            userMapper.insert(user);
            return createLoginResponse(user);
        }
        requireEnabledUser(user);
        // 登录时同步苹果绑定标识,避免历史账号缺少最新 subject 或绑定时间。
        applyAppleProfile(user, profile, false);
        userMapper.updateById(user);
        return createLoginResponse(user);
    }
@@ -227,6 +250,16 @@
    }
    /**
     * 按苹果 subject 查询本地 APP 用户。
     */
    private AppUser findUserByAppleSubject(String subject) {
        return userMapper.selectOne(new LambdaQueryWrapper<AppUser>()
                .eq(AppUser::getAppleIdentitySubject, subject)
                .eq(AppUser::getDeleted, 0)
                .last("limit 1"));
    }
    /**
     * 基于微信资料构造首次登录时的本地普通用户。
     */
    private AppUser buildWechatUser(AppWechatUserProfile profile) {
@@ -234,6 +267,17 @@
        user.setType(0);
        user.setStatus(1);
        applyWechatProfile(user, profile, true);
        return user;
    }
    /**
     * 基于苹果资料构造首次登录时的本地普通用户。
     */
    private AppUser buildAppleUser(AppAppleUserProfile profile) {
        AppUser user = new AppUser();
        user.setType(0);
        user.setStatus(1);
        applyAppleProfile(user, profile, true);
        return user;
    }
@@ -261,6 +305,19 @@
    }
    /**
     * 将苹果资料回填到本地用户,并在首次自动建号时补齐基础展示昵称。
     */
    private void applyAppleProfile(AppUser user, AppAppleUserProfile profile, boolean syncLocalProfile) {
        user.setAppleUserIdentifier(trimToNull(profile.getUserIdentifier()));
        user.setAppleIdentitySubject(trimToNull(profile.getSubject()));
        user.setAppleBoundAt(LocalDateTime.now());
        if (syncLocalProfile || trimToNull(user.getNickname()) == null) {
            user.setNickname("苹果用户");
        }
    }
    /**
     * 将微信性别值转换为本地用户性别枚举。
     */
    private Integer resolveWechatGender(Integer sex) {