package top.peng.answerbi.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import top.peng.answerbi.common.ErrorCode; import top.peng.answerbi.constant.CommonConstant; import top.peng.answerbi.exception.BusinessException; import top.peng.answerbi.mapper.UserMapper; import top.peng.answerbi.model.dto.user.UserQueryRequest; import top.peng.answerbi.model.entity.User; import top.peng.answerbi.model.enums.UserRoleEnum; import top.peng.answerbi.model.vo.LoginUserVO; import top.peng.answerbi.model.vo.UserVO; import top.peng.answerbi.service.UserService; import top.peng.answerbi.utils.SqlUtils; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import javax.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.util.DigestUtils; import top.peng.answerbi.constant.UserConstant; /** * 用户服务实现 * * @author yunpeng * @version 1.0 2023/5/16 */ @Service @Slf4j public class UserServiceImpl extends ServiceImpl implements UserService { /** * 盐值,混淆密码 */ private static final String SALT = "answer"; @Override public long userRegister(String userAccount, String userPassword, String checkPassword) { // 1. 校验 if (StringUtils.isAnyBlank(userAccount, userPassword, checkPassword)) { throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空"); } if (userAccount.length() < 4) { throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户账号过短"); } if (userPassword.length() < 8 || checkPassword.length() < 8) { throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户密码过短"); } // 密码和校验密码相同 if (!userPassword.equals(checkPassword)) { throw new BusinessException(ErrorCode.PARAMS_ERROR, "两次输入的密码不一致"); } synchronized (userAccount.intern()) { // 账户不能重复 QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("user_account", userAccount); long count = this.baseMapper.selectCount(queryWrapper); if (count > 0) { throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号重复"); } // 2. 加密 String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes()); // 3. 插入数据 User user = new User(); user.setUserAccount(userAccount); user.setUserPassword(encryptPassword); boolean saveResult = this.save(user); if (!saveResult) { throw new BusinessException(ErrorCode.SYSTEM_ERROR, "注册失败,数据库错误"); } return user.getId(); } } @Override public LoginUserVO userLogin(String userAccount, String userPassword, HttpServletRequest request) { // 1. 校验 if (StringUtils.isAnyBlank(userAccount, userPassword)) { throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空"); } if (userAccount.length() < 4) { throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号错误"); } if (userPassword.length() < 8) { throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码错误"); } // 2. 加密 String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes()); // 查询用户是否存在 QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("user_account", userAccount); queryWrapper.eq("user_password", encryptPassword); User user = this.baseMapper.selectOne(queryWrapper); // 用户不存在 if (user == null) { log.info("user login failed, userAccount cannot match userPassword"); throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在或密码错误"); } // 3. 记录用户的登录态 request.getSession().setAttribute(UserConstant.USER_LOGIN_STATE, user); return this.getLoginUserVO(user); } /** * 获取当前登录用户 * * @param request * @return */ @Override public User getLoginUser(HttpServletRequest request) { // 先判断是否已登录 Object userObj = request.getSession().getAttribute(UserConstant.USER_LOGIN_STATE); User currentUser = (User) userObj; if (currentUser == null || currentUser.getId() == null) { throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR); } // 从数据库查询(追求性能的话可以注释,直接走缓存) long userId = currentUser.getId(); currentUser = this.getById(userId); if (currentUser == null) { throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR); } return currentUser; } /** * 获取当前登录用户(允许未登录) * * @param request * @return */ @Override public User getLoginUserPermitNull(HttpServletRequest request) { // 先判断是否已登录 Object userObj = request.getSession().getAttribute(UserConstant.USER_LOGIN_STATE); User currentUser = (User) userObj; if (currentUser == null || currentUser.getId() == null) { return null; } // 从数据库查询(追求性能的话可以注释,直接走缓存) long userId = currentUser.getId(); return this.getById(userId); } /** * 是否为管理员 * * @param request * @return */ @Override public boolean isAdmin(HttpServletRequest request) { // 仅管理员可查询 Object userObj = request.getSession().getAttribute(UserConstant.USER_LOGIN_STATE); User user = (User) userObj; return isAdmin(user); } @Override public boolean isAdmin(User user) { return user != null && UserRoleEnum.ADMIN.getValue().equals(user.getUserRole()); } /** * 用户注销 * * @param request */ @Override public boolean userLogout(HttpServletRequest request) { if (request.getSession().getAttribute(UserConstant.USER_LOGIN_STATE) == null) { throw new BusinessException(ErrorCode.OPERATION_ERROR, "未登录"); } // 移除登录态 request.getSession().removeAttribute(UserConstant.USER_LOGIN_STATE); return true; } @Override public LoginUserVO getLoginUserVO(User user) { if (user == null) { return null; } LoginUserVO loginUserVO = new LoginUserVO(); BeanUtils.copyProperties(user, loginUserVO); return loginUserVO; } @Override public UserVO getUserVO(User user) { if (user == null) { return null; } UserVO userVO = new UserVO(); BeanUtils.copyProperties(user, userVO); return userVO; } @Override public List getUserVO(List userList) { if (CollectionUtils.isEmpty(userList)) { return new ArrayList<>(); } return userList.stream().map(this::getUserVO).collect(Collectors.toList()); } @Override public QueryWrapper getQueryWrapper(UserQueryRequest userQueryRequest) { if (userQueryRequest == null) { throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空"); } Long id = userQueryRequest.getId(); String userName = userQueryRequest.getUserName(); String userAccount = userQueryRequest.getUserAccount(); String userProfile = userQueryRequest.getUserProfile(); String userRole = userQueryRequest.getUserRole(); String sortField = userQueryRequest.getSortField(); String sortOrder = userQueryRequest.getSortOrder(); QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq(id != null, "id", id); queryWrapper.eq(StringUtils.isNotBlank(userAccount), "user_account", userAccount); queryWrapper.eq(StringUtils.isNotBlank(userRole), "user_role", userRole); queryWrapper.like(StringUtils.isNotBlank(userProfile), "user_profile", userProfile); queryWrapper.like(StringUtils.isNotBlank(userName), "user_name", userName); queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC), sortField); return queryWrapper; } }