package com.yau.digitalrmb.security.application; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.yau.digitalrmb.identity.infrastructure.persistence.entity.PlatformUserSnapshotEntity; import com.yau.digitalrmb.identity.infrastructure.persistence.entity.UserEntity; import com.yau.digitalrmb.identity.infrastructure.persistence.mapper.PlatformUserSnapshotMapper; import com.yau.digitalrmb.identity.infrastructure.persistence.mapper.UserMapper; import com.yau.digitalrmb.shared.api.ErrorCode; import com.yau.digitalrmb.shared.exception.BusinessException; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import java.util.Collections; @Service public class LocalAccountAuthenticationService { private final UserMapper userMapper; private final PlatformUserSnapshotMapper snapshotMapper; private final PasswordEncoder passwordEncoder; private final JwtTokenService jwtTokenService; public LocalAccountAuthenticationService(UserMapper userMapper, PlatformUserSnapshotMapper snapshotMapper, PasswordEncoder passwordEncoder, JwtTokenService jwtTokenService) { this.userMapper = userMapper; this.snapshotMapper = snapshotMapper; this.passwordEncoder = passwordEncoder; this.jwtTokenService = jwtTokenService; } public JwtTokenService.Token login(String username, String rawPassword) { UserEntity user = userMapper.selectOne(new LambdaQueryWrapper() .eq(UserEntity::getUsername, username) .eq(UserEntity::getEnabled, true) .last("LIMIT 1")); if (user == null || !passwordEncoder.matches(rawPassword, user.getPasswordHash())) { throw invalidCredentials(); } PlatformUserSnapshotEntity snapshot = snapshotMapper.selectById(user.getId()); if (snapshot == null) { throw invalidCredentials(); } return jwtTokenService.issueFor(user.getId(), snapshot.getAccount(), Collections.singleton(snapshot.getRoleKey())); } private BusinessException invalidCredentials() { return new BusinessException(ErrorCode.UNAUTHORIZED, "用户名或密码错误"); } }