package com.tcm.training.admin.auth.service;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.tcm.training.admin.auth.dto.ChangePasswordRequest;
|
import com.tcm.training.admin.auth.dto.LoginRequest;
|
import com.tcm.training.admin.auth.dto.ProfileUpdateRequest;
|
import com.tcm.training.admin.auth.vo.LoginResponse;
|
import com.tcm.training.admin.auth.vo.UserVO;
|
import com.tcm.training.admin.user.entity.SysUser;
|
import com.tcm.training.admin.user.service.RbacService;
|
import com.tcm.training.admin.user.service.SysUserService;
|
import cn.dev33.satoken.stp.SaTokenInfo;
|
import cn.dev33.satoken.stp.StpUtil;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.time.LocalDateTime;
|
import java.util.List;
|
import java.util.regex.Pattern;
|
|
@Service
|
public class AuthService {
|
|
private static final Pattern PASSWORD_PATTERN = Pattern.compile(
|
"^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[^A-Za-z\\d]).{12,64}$"
|
);
|
|
private final SysUserService sysUserService;
|
private final BCryptPasswordEncoder passwordEncoder;
|
private final CaptchaService captchaService;
|
private final RbacService rbacService;
|
|
public AuthService(
|
SysUserService sysUserService,
|
BCryptPasswordEncoder passwordEncoder,
|
CaptchaService captchaService,
|
RbacService rbacService
|
) {
|
this.sysUserService = sysUserService;
|
this.passwordEncoder = passwordEncoder;
|
this.captchaService = captchaService;
|
this.rbacService = rbacService;
|
}
|
|
public LoginResponse login(LoginRequest req) {
|
captchaService.validate(req.getCaptchaId(), req.getCaptchaCode());
|
|
SysUser user = sysUserService.getOne(new LambdaQueryWrapper<SysUser>()
|
.eq(SysUser::getUsername, req.getUsername())
|
.eq(SysUser::getDeleted, 0)
|
.last("limit 1"));
|
if (user == null) {
|
throw new IllegalArgumentException("账号或密码错误");
|
}
|
if (user.getStatus() != null && user.getStatus() != 1) {
|
throw new IllegalArgumentException("账号已被禁用");
|
}
|
if (!passwordEncoder.matches(req.getPassword(), user.getPassword())) {
|
throw new IllegalArgumentException("账号或密码错误");
|
}
|
|
StpUtil.login(user.getId());
|
SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
|
user.setLastLoginAt(LocalDateTime.now());
|
sysUserService.updateById(user);
|
|
UserVO userVO = buildUserVO(user);
|
return new LoginResponse(tokenInfo.getTokenValue(), "Bearer", tokenInfo.getTokenTimeout(), userVO);
|
}
|
|
public void logout() {
|
StpUtil.logout();
|
}
|
|
public UserVO me() {
|
return buildUserVO(requireCurrentUser());
|
}
|
|
@Transactional
|
public UserVO updateProfile(ProfileUpdateRequest req) {
|
SysUser user = requireCurrentUser();
|
user.setNickname(normalizeRequired(req.getNickname(), "请输入用户名"));
|
user.setAvatar(trimToNull(req.getAvatar()));
|
user.setUpdatedAt(LocalDateTime.now());
|
sysUserService.updateById(user);
|
return buildUserVO(user);
|
}
|
|
@Transactional
|
public void changePassword(ChangePasswordRequest req) {
|
SysUser user = requireCurrentUser();
|
if (!passwordEncoder.matches(req.getOldPassword(), user.getPassword())) {
|
throw new IllegalArgumentException("原密码错误");
|
}
|
if (!req.getNewPassword().equals(req.getConfirmPassword())) {
|
throw new IllegalArgumentException("两次密码输入不一致");
|
}
|
validatePassword(req.getNewPassword());
|
user.setPassword(passwordEncoder.encode(req.getNewPassword()));
|
user.setUpdatedAt(LocalDateTime.now());
|
sysUserService.updateById(user);
|
StpUtil.logout();
|
}
|
|
private UserVO buildUserVO(SysUser user) {
|
List<String> roleCodes = rbacService.getRoleCodesByUserId(user.getId());
|
List<String> permissionKeys = rbacService.getPermissionKeysByUserId(user.getId());
|
return new UserVO(
|
user.getId(),
|
user.getUsername(),
|
user.getNickname(),
|
user.getRealName(),
|
user.getPhone(),
|
user.getAvatar(),
|
roleCodes,
|
permissionKeys
|
);
|
}
|
|
private SysUser requireCurrentUser() {
|
Long userId = StpUtil.getLoginIdAsLong();
|
SysUser user = sysUserService.getById(userId);
|
if (user == null || (user.getDeleted() != null && user.getDeleted() == 1)) {
|
throw new IllegalArgumentException("用户不存在");
|
}
|
return user;
|
}
|
|
private void validatePassword(String password) {
|
if (!PASSWORD_PATTERN.matcher(password).matches()) {
|
throw new IllegalArgumentException("密码需至少12位,且包含大小写字母、数字和特殊字符");
|
}
|
}
|
|
private String normalizeRequired(String value, String message) {
|
String normalized = trimToNull(value);
|
if (normalized == null) {
|
throw new IllegalArgumentException(message);
|
}
|
return normalized;
|
}
|
|
private String trimToNull(String value) {
|
if (value == null) {
|
return null;
|
}
|
String trimmed = value.trim();
|
return trimmed.isEmpty() ? null : trimmed;
|
}
|
}
|