[api] 회원정보 수정 & 비밀번호 변경

This commit is contained in:
2026-05-18 10:55:16 +09:00
parent 58252a0fda
commit 4cc6078484
7 changed files with 203 additions and 19 deletions
@@ -2,16 +2,9 @@ package com.alist.api.modules.user;
import com.alist.api.common.response.ApiResponse;
import com.alist.api.common.response.ApiResponseCode;
import com.alist.api.modules.user.form.MigrationUserForm;
import com.alist.api.modules.user.form.UserPasswordChangeForm;
import com.alist.api.modules.user.form.UserPasswordCheckForm;
import com.alist.api.modules.user.form.UserSignupForm;
import com.alist.api.modules.user.mapper.UserMapper;
import com.alist.api.modules.user.form.*;
import com.alist.api.modules.user.service.UserService;
import com.alist.api.modules.user.vo.MigrationUserVo;
import com.alist.api.modules.user.vo.UserPasswordChangeVo;
import com.alist.api.modules.user.vo.UserPasswordCheckVo;
import com.alist.api.modules.user.vo.UserVo;
import com.alist.api.modules.user.vo.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
@@ -106,4 +99,25 @@ public class UserController {
return ApiResponse.entity(result, ApiResponseCode.CODE_2005, "비밀번호 변경");
}
@Operation(
summary = "사용자 개인정보 수정",
description = "로그인한 사용자의 현재 비밀번호를 확인한 뒤 이메일과 휴대폰 번호를 수정합니다."
)
@PatchMapping("/profile")
public ResponseEntity<ApiResponse<UserProfileUpdateVo>> updateProfile(
@Valid @RequestBody UserProfileUpdateForm userProfileUpdateForm
) {
UserProfileUpdateVo result = userService.updateProfile(userProfileUpdateForm.toUserProfileUpdateDto());
if (!result.isProfileUpdated()) {
if (result.getResultCode() == 4003 || result.getResultCode() == 4001) {
return ApiResponse.entity(result, ApiResponseCode.CODE_4001);
}
return ApiResponse.entity(result, ApiResponseCode.CODE_2003);
}
return ApiResponse.entity(result, ApiResponseCode.CODE_2005, "개인정보 수정");
}
}
@@ -0,0 +1,13 @@
package com.alist.api.modules.user.dto;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class UserProfileUpdateDto {
private Integer userTokenIdx;
private String currentPassword;
private String email;
private String hp;
}
@@ -0,0 +1,27 @@
package com.alist.api.modules.user.form;
import com.alist.api.modules.user.dto.UserProfileUpdateDto;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class UserProfileUpdateForm {
@NotBlank(message = "현재 비밀번호는 필수입니다.")
private String currentPassword;
@Email(message = "이메일 형식을 확인해주세요.")
private String email;
private String hp;
public UserProfileUpdateDto toUserProfileUpdateDto() {
UserProfileUpdateDto userProfileUpdateDto = new UserProfileUpdateDto();
userProfileUpdateDto.setCurrentPassword(currentPassword);
userProfileUpdateDto.setEmail(email);
userProfileUpdateDto.setHp(hp);
return userProfileUpdateDto;
}
}
@@ -1,6 +1,8 @@
package com.alist.api.modules.user.mapper;
import com.alist.api.modules.user.dto.UserDto;
import com.alist.api.modules.user.dto.UserPasswordChangeDto;
import com.alist.api.modules.user.dto.UserProfileUpdateDto;
import com.alist.api.modules.user.dto.UserTokenDto;
import com.alist.api.modules.user.vo.UserVo;
import org.apache.ibatis.annotations.Mapper;
@@ -14,4 +16,10 @@ public interface UserMapper {
int insertUserTokenSignup(UserTokenDto userTokenDto);
UserVo selectUserByUserIdx(Integer userIdx);
UserVo selectUserByUserTokenIdx(Integer userTokenIdx);
int updateUserPassword(UserPasswordChangeDto userPasswordChangeDto);
int updateUserProfile(UserProfileUpdateDto userProfileUpdateDto);
}
@@ -8,15 +8,9 @@ import com.alist.api.modules.migration.alist.user.vo.AlistUserVo;
import com.alist.api.modules.migration.eltown.user.dto.EltownUserDto;
import com.alist.api.modules.migration.eltown.user.service.EltownUserService;
import com.alist.api.modules.migration.eltown.user.vo.EltownUserVo;
import com.alist.api.modules.user.dto.UserDto;
import com.alist.api.modules.user.dto.UserPasswordChangeDto;
import com.alist.api.modules.user.dto.UserPasswordCheckDto;
import com.alist.api.modules.user.dto.UserTokenDto;
import com.alist.api.modules.user.dto.*;
import com.alist.api.modules.user.mapper.UserMapper;
import com.alist.api.modules.user.vo.MigrationUserVo;
import com.alist.api.modules.user.vo.UserPasswordChangeVo;
import com.alist.api.modules.user.vo.UserPasswordCheckVo;
import com.alist.api.modules.user.vo.UserVo;
import com.alist.api.modules.user.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.security.crypto.password.PasswordEncoder;
@@ -149,7 +143,88 @@ public class UserService {
}
@Transactional
public UserPasswordChangeVo updatePassword(UserPasswordChangeDto toUserPasswordChangeDto) {
return null;
public UserPasswordChangeVo updatePassword(UserPasswordChangeDto userPasswordChangeDto) {
UserPasswordChangeVo result = new UserPasswordChangeVo();
Integer userTokenIdx = SecurityUtil.getLoginUserTokenIdx();
userPasswordChangeDto.setUserTokenIdx(userTokenIdx);
if (userTokenIdx == null
|| userPasswordChangeDto.getCurrentPassword() == null
|| userPasswordChangeDto.getNewPassword() == null) {
result.setPasswordChanged(false);
result.setResultCode(4003);
return result;
}
UserVo userVo = userMapper.selectUserByUserTokenIdx(userTokenIdx);
if (userVo == null || userVo.getPassword() == null) {
result.setPasswordChanged(false);
result.setResultCode(2003);
return result;
}
boolean matched = passwordEncoder.matches(
userPasswordChangeDto.getCurrentPassword(),
userVo.getPassword()
);
if (!matched) {
result.setPasswordChanged(false);
result.setResultCode(4001);
return result;
}
userPasswordChangeDto.setNewPassword(passwordEncoder.encode(userPasswordChangeDto.getNewPassword()));
int updateCount = userMapper.updateUserPassword(userPasswordChangeDto);
result.setPasswordChanged(updateCount > 0);
result.setResultCode(updateCount > 0 ? 2005 : 2003);
return result;
}
@Transactional
public UserProfileUpdateVo updateProfile(UserProfileUpdateDto userProfileUpdateDto) {
UserProfileUpdateVo result = new UserProfileUpdateVo();
Integer userTokenIdx = SecurityUtil.getLoginUserTokenIdx();
userProfileUpdateDto.setUserTokenIdx(userTokenIdx);
if (userTokenIdx == null
|| userProfileUpdateDto.getCurrentPassword() == null
|| (userProfileUpdateDto.getEmail() == null && userProfileUpdateDto.getHp() == null)) {
result.setProfileUpdated(false);
result.setResultCode(4003);
return result;
}
UserVo userVo = userMapper.selectUserByUserTokenIdx(userTokenIdx);
if (userVo == null || userVo.getPassword() == null) {
result.setProfileUpdated(false);
result.setResultCode(2003);
return result;
}
boolean matched = passwordEncoder.matches(
userProfileUpdateDto.getCurrentPassword(),
userVo.getPassword()
);
if (!matched) {
result.setProfileUpdated(false);
result.setResultCode(4001);
return result;
}
int updateCount = userMapper.updateUserProfile(userProfileUpdateDto);
result.setProfileUpdated(updateCount > 0);
result.setResultCode(updateCount > 0 ? 2005 : 2003);
return result;
}
}
@@ -0,0 +1,14 @@
package com.alist.api.modules.user.vo;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class UserProfileUpdateVo {
private boolean profileUpdated;
@JsonIgnore
private Integer resultCode;
}
@@ -12,6 +12,29 @@
insert into ALISTLMS.test_user_token (user_idx, user_api_key, user_role, user_type, created_at, updated_at)
value (#{userIdx}, #{userApiKey}, #{userRole}, #{userType}, now(), now())
</insert>
<update id="updateUserPassword">
/*UserMapper.updateUserPassword*/
UPDATE ALISTLMS.test_user ATU
INNER JOIN ALISTLMS.test_user_token ATUT ON ATUT.user_idx = ATU.user_idx
SET ATU.password = #{newPassword}
, ATU.update_at = now()
WHERE ATUT.user_token_idx = #{userTokenIdx}
AND ATU.del_yn = 1
</update>
<update id="updateUserProfile">
/*UserMapper.updateUserProfile*/
UPDATE ALISTLMS.test_user ATU
INNER JOIN ALISTLMS.test_user_token ATUT ON ATUT.user_idx = ATU.user_idx
SET ATU.update_at = now()
<if test="email != null">
, ATU.email = #{email}
</if>
<if test="hp != null">
, ATU.hp = #{hp}
</if>
WHERE ATUT.user_token_idx = #{userTokenIdx}
AND ATU.del_yn = 1
</update>
<select id="selectDuplicateUserCount" resultType="int">
/*UserMapper.selectDuplicateUserCount*/
@@ -30,4 +53,14 @@
AND ATU.del_yn = 1
</select>
<select id="selectUserByUserTokenIdx" resultType="com.alist.api.modules.user.vo.UserVo">
/*UserMapper.selectUserByUserTokenIdx*/
SELECT ATU.user_idx
, ATU.password
FROM ALISTLMS.test_user ATU
INNER JOIN ALISTLMS.test_user_token ATUT ON ATUT.user_idx = ATU.user_idx
WHERE ATUT.user_token_idx = #{userTokenIdx}
AND ATU.del_yn = 1
</select>
</mapper>