content: package io.github.xxyopen.novel.service.impl;
  
  import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  import io.github.xxyopen.novel.core.common.constant.CommonConsts;
  import io.github.xxyopen.novel.core.common.constant.ErrorCodeEnum;
  import io.github.xxyopen.novel.core.common.exception.BusinessException;
  import io.github.xxyopen.novel.core.common.resp.RestResp;
  import io.github.xxyopen.novel.core.constant.DatabaseConsts;
  import io.github.xxyopen.novel.core.constant.SystemConfigConsts;
  import io.github.xxyopen.novel.core.util.JwtUtils;
  import io.github.xxyopen.novel.dao.entity.UserBookshelf;
  import io.github.xxyopen.novel.dao.entity.UserFeedback;
  import io.github.xxyopen.novel.dao.entity.UserInfo;
  import io.github.xxyopen.novel.dao.mapper.UserBookshelfMapper;
  import io.github.xxyopen.novel.dao.mapper.UserFeedbackMapper;
  import io.github.xxyopen.novel.dao.mapper.UserInfoMapper;
  import io.github.xxyopen.novel.dto.req.UserInfoUptReqDto;
  import io.github.xxyopen.novel.dto.req.UserLoginReqDto;
  import io.github.xxyopen.novel.dto.req.UserRegisterReqDto;
  import io.github.xxyopen.novel.dto.resp.UserInfoRespDto;
  import io.github.xxyopen.novel.dto.resp.UserLoginRespDto;
  import io.github.xxyopen.novel.dto.resp.UserRegisterRespDto;
  import io.github.xxyopen.novel.manager.redis.VerifyCodeManager;
  import io.github.xxyopen.novel.service.UserService;
  import java.nio.charset.StandardCharsets;
  import java.time.LocalDateTime;
  import java.util.Objects;
  import lombok.RequiredArgsConstructor;
  import org.springframework.stereotype.Service;
  import org.springframework.util.DigestUtils;
  
  /**
   * 会员模块 服务实现类
   *
   * @author xiongxiaoyang
   * @date 2022/5/17
   */
  @Service
  @RequiredArgsConstructor
  public class UserServiceImpl implements UserService {
  
      private final UserInfoMapper userInfoMapper;
  
      private final VerifyCodeManager verifyCodeManager;
  
      private final UserFeedbackMapper userFeedbackMapper;
  
      private final UserBookshelfMapper userBookshelfMapper;
  
      private final JwtUtils jwtUtils;
  
      @Override
      public RestResp<UserRegisterRespDto> register(UserRegisterReqDto dto) {
          // 校验图形验证码是否正确
          if (!verifyCodeManager.imgVerifyCodeOk(dto.getSessionId(), dto.getVelCode())) {
              // 图形验证码校验失败
              throw new BusinessException(ErrorCodeEnum.USER_VERIFY_CODE_ERROR);
          }
  
          // 校验手机号是否已注册
          QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
          queryWrapper.eq(DatabaseConsts.UserInfoTable.COLUMN_USERNAME, dto.getUsername())
              .last(DatabaseConsts.SqlEnum.LIMIT_1.getSql());
          if (userInfoMapper.selectCount(queryWrapper) > 0) {
              // 手机号已注册
              throw new BusinessException(ErrorCodeEnum.USER_NAME_EXIST);
          }
  
          // 注册成功，保存用户信息
          UserInfo userInfo = new UserInfo();
          userInfo.setPassword(
              DigestUtils.md5DigestAsHex(dto.getPassword().getBytes(StandardCharsets.UTF_8)));
          userInfo.setUsername(dto.getUsername());
          userInfo.setNickName(dto.getUsername());
          userInfo.setCreateTime(LocalDateTime.now());
          userInfo.setUpdateTime(LocalDateTime.now());
          userInfo.setSalt("0");
          userInfoMapper.insert(userInfo);
  
          // 删除验证码
          verifyCodeManager.removeImgVerifyCode(dto.getSessionId());
  
          // 生成JWT 并返回
          return RestResp.ok(
              UserRegisterRespDto.builder()
                  .token(jwtUtils.generateToken(userInfo.getId(), SystemConfigConsts.NOVEL_FRONT_KEY))
                  .uid(userInfo.getId())
                  .build()
          );
  
      }
  
      @Override
      public RestResp<UserLoginRespDto> login(UserLoginReqDto dto) {
          // 查询用户信息
          QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
          queryWrapper.eq(DatabaseConsts.UserInfoTable.COLUMN_USERNAME, dto.getUsername())
              .last(DatabaseConsts.SqlEnum.LIMIT_1.getSql());
          UserInfo userInfo = userInfoMapper.selectOne(queryWrapper);
          if (Objects.isNull(userInfo)) {
              // 用户不存在
              throw new BusinessException(ErrorCodeEnum.USER_ACCOUNT_NOT_EXIST);
          }
  
          // 判断密码是否正确
          if (!Objects.equals(userInfo.getPassword()
              , DigestUtils.md5DigestAsHex(dto.getPassword().getBytes(StandardCharsets.UTF_8)))) {
              // 密码错误
              throw new BusinessException(ErrorCodeEnum.USER_PASSWORD_ERROR);
          }
  
          // 登录成功，生成JWT并返回
          return RestResp.ok(UserLoginRespDto.builder()
              .token(jwtUtils.generateToken(userInfo.getId(), SystemConfigConsts.NOVEL_FRONT_KEY))
              .uid(userInfo.getId())
              .nickName(userInfo.getNickName()).build());
      }
  
      @Override
      public RestResp<Void> saveFeedback(Long userId, String content) {
          UserFeedback userFeedback = new UserFeedback();
          userFeedback.setUserId(userId);
          userFeedback.setContent(content);
          userFeedback.setCreateTime(LocalDateTime.now());
          userFeedback.setUpdateTime(LocalDateTime.now());
          userFeedbackMapper.insert(userFeedback);
          return RestResp.ok();
      }
  
      @Override
      public RestResp<Void> updateUserInfo(UserInfoUptReqDto dto) {
          UserInfo userInfo = new UserInfo();
          userInfo.setId(dto.getUserId());
          userInfo.setNickName(dto.getNickName());
          userInfo.setUserPhoto(dto.getUserPhoto());
          userInfo.setUserSex(dto.getUserSex());
          userInfoMapper.updateById(userInfo);
          return RestResp.ok();
      }
  
      @Override
      public RestResp<Void> deleteFeedback(Long userId, Long id) {
          QueryWrapper<UserFeedback> queryWrapper = new QueryWrapper<>();
          queryWrapper.eq(DatabaseConsts.CommonColumnEnum.ID.getName(), id)
              .eq(DatabaseConsts.UserFeedBackTable.COLUMN_USER_ID, userId);
          userFeedbackMapper.delete(queryWrapper);
          return RestResp.ok();
      }
  
      @Override
      public RestResp<Integer> getBookshelfStatus(Long userId, String bookId) {
          QueryWrapper<UserBookshelf> queryWrapper = new QueryWrapper<>();
          queryWrapper.eq(DatabaseConsts.UserBookshelfTable.COLUMN_USER_ID, userId)
              .eq(DatabaseConsts.UserBookshelfTable.COLUMN_BOOK_ID, bookId);
          return RestResp.ok(
              userBookshelfMapper.selectCount(queryWrapper) > 0
                  ? CommonConsts.YES
                  : CommonConsts.NO
          );
      }
  
      @Override
      public RestResp<UserInfoRespDto> getUserInfo(Long userId) {
          UserInfo userInfo = userInfoMapper.selectById(userId);
          return RestResp.ok(UserInfoRespDto.builder()
              .nickName(userInfo.getNickName())
              .userSex(userInfo.getUserSex())
              .userPhoto(userInfo.getUserPhoto())
              .build());
      }
  }
  