UserService.java
package com.newbit.user.service;
import com.newbit.common.exception.BusinessException;
import com.newbit.common.exception.ErrorCode;
import com.newbit.user.dto.request.FindIdDTO;
import com.newbit.user.dto.response.UserDTO;
import com.newbit.user.dto.response.UserIdDTO;
import com.newbit.user.entity.User;
import com.newbit.user.dto.request.UserRequestDTO;
import com.newbit.user.repository.UserRepository;
import com.newbit.user.support.MailServiceSupport;
import com.newbit.user.support.PasswordValidator;
import lombok.RequiredArgsConstructor;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.security.crypto.password.PasswordEncoder;
import java.util.UUID;
import static com.newbit.common.exception.ErrorCode.FIND_EMAIL_BY_NAME_AND_PHONE_ERROR;
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private final ModelMapper modelMapper;
private final PasswordEncoder passwordEncoder;
private final MailServiceSupport mailServiceSupport;
// 회원 가입
@Transactional
public void registerUser(UserRequestDTO request) {
// 중복 회원 체크 로직 등 추가 가능
if (userRepository.existsByEmail(request.getEmail())) {
throw new BusinessException(ErrorCode.ALREADY_REGISTERED_EMAIL);
}
if (!PasswordValidator.isValid(request.getPassword())) {
throw new BusinessException(ErrorCode.INVALID_PASSWORD_FORMAT);
}
if (userRepository.existsByPhoneNumber(request.getPhoneNumber())) {
throw new BusinessException(ErrorCode.ALREADY_REGISTERED_PHONENUMBER);
}
if (userRepository.existsByNickname(request.getNickname())) {
throw new BusinessException(ErrorCode.ALREADY_REGISTERED_NICKNAME);
}
// 회원 가입
User user = modelMapper.map(request, User.class);
user.setEncodedPassword(passwordEncoder.encode(request.getPassword()));
userRepository.save(user);
}
public UserIdDTO findEmailByNameAndPhone(FindIdDTO findIdDTO) {
return userRepository.findByUserNameAndPhoneNumber(findIdDTO.getUserName(), findIdDTO.getPhoneNumber())
.map(UserIdDTO::from)
.orElseThrow(() -> new BusinessException(FIND_EMAIL_BY_NAME_AND_PHONE_ERROR));
}
@Transactional
public void findPasswordByEmail(String email) {
User user = userRepository.findByEmail(email)
.orElseThrow(() -> new BusinessException(ErrorCode.USER_NOT_FOUND));
String tempPassword = generateTempPassword();
user.findPassword(passwordEncoder.encode(tempPassword));
sendTemporaryPassword(email, tempPassword);
}
private String generateTempPassword() {
return UUID.randomUUID().toString().substring(0, 8);
}
public void sendTemporaryPassword(String toEmail, String tempPassword) {
String subject = "Newbit 임시 비밀번호 안내";
String content = "<p>안녕하세요!,</p>" +
"<p>임시 비밀번호는 다음과 같습니다:</p>" +
"<h3>" + tempPassword + "</h3>" +
"<p>로그인 후 비밀번호를 반드시 변경해주세요.</p>";
mailServiceSupport.sendMailSupport(toEmail, subject, content);
}
@Transactional(readOnly = true)
public Integer getDiamondBalance(Long userId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new BusinessException(ErrorCode.USER_NOT_FOUND));
return user.getDiamond();
}
@Transactional
public Integer useDiamond(Long userId, int amount) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new BusinessException(ErrorCode.USER_NOT_FOUND));
if (user.getDiamond() < amount) {
throw new BusinessException(ErrorCode.INSUFFICIENT_DIAMOND);
}
user.useDiamond(amount);// 도메인 로직에 위임 (Entity 내부에 구현된 로직)
return user.getDiamond();
}
@Transactional
public Integer addDiamond(Long userId, int amount) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new BusinessException(ErrorCode.USER_NOT_FOUND));
user.addDiamond(amount);// 도메인 로직에 위임 (Entity 내부에 구현된 로직)
return user.getDiamond();
}
@Transactional
public Integer usePoint(Long userId, int amount) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new BusinessException(ErrorCode.USER_NOT_FOUND));
if (user.getPoint() < amount) {
throw new BusinessException(ErrorCode.INSUFFICIENT_POINT);
}
user.usePoint(amount);// 도메인 로직에 위임 (Entity 내부에 구현된 로직)
return user.getPoint();
}
@Transactional
public Integer addPoint(Long userId, int amount) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new BusinessException(ErrorCode.USER_NOT_FOUND));
user.addPoint(amount);// 도메인 로직에 위임 (Entity 내부에 구현된 로직)
return user.getPoint();
}
public UserDTO getUserByUserId(Long userId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new BusinessException(ErrorCode.USER_NOT_FOUND));
return UserDTO.builder()
.userId(userId)
.authority(user.getAuthority())
.diamond(user.getDiamond())
.point(user.getPoint())
.build();
}
}