Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ dependencies {
// Swagger
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.13'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-api:2.8.13'

// Security
implementation 'org.springframework.boot:spring-boot-starter-security'
testImplementation 'org.springframework.security:spring-security-test'

// Jwt
implementation 'io.jsonwebtoken:jjwt-api:0.12.3'
implementation 'io.jsonwebtoken:jjwt-impl:0.12.3'
implementation 'io.jsonwebtoken:jjwt-jackson:0.12.3'
implementation 'org.springframework.boot:spring-boot-configuration-processor'
}

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.umc9th.domain.category.repository;

import com.umc9th.domain.category.entity.Category;
import org.springframework.data.jpa.repository.JpaRepository;

public interface CategoryRepository extends JpaRepository<Category, Long> {
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.example.umc9th.domain.mission.converter;
package com.umc9th.domain.mission.converter;

import com.example.umc9th.domain.mission.dto.res.GetUserMissionResponse;
import com.example.umc9th.domain.user.entity.UserMission;
import com.umc9th.domain.mission.dto.res.GetUserMissionResponse;
import com.umc9th.domain.user.entity.UserMission;

public class UserMissionConverter {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.example.umc9th.domain.mission.repository;
package com.umc9th.domain.mission.repository;

import com.example.umc9th.domain.mission.dto.UserMissionDto;
import com.example.umc9th.domain.mission.entity.Mission;
import com.umc9th.domain.mission.dto.UserMissionDto;
import com.umc9th.domain.mission.entity.Mission;
import org.springframework.data.domain.Page; // 💡 페이징 처리를 위해 Page 클래스 사용
import org.springframework.data.domain.Pageable; // 💡 페이징 정보를 받기 위해 Pageable 사용
import org.springframework.data.jpa.repository.JpaRepository;
Expand All @@ -13,7 +13,7 @@
public interface MissionRepository extends JpaRepository<Mission, Long> {

//내가 진행중/완료한 미션 모아보기 쿼리 (페이징 포함)
@Query("SELECT new com.example.umc9th.domain.mission.dto.UserMissionDto(" +
@Query("SELECT new com.umc9th.domain.mission.dto.UserMissionDto(" +
"um.id, " +
"m.id, " +
"s.storeName, " +
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.example.umc9th.domain.mission.repository;
package com.umc9th.domain.mission.repository;

import com.example.umc9th.domain.user.entity.UserMission;
import com.umc9th.domain.user.entity.UserMission;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package com.example.umc9th.domain.mission.service;

import com.example.umc9th.domain.mission.converter.MissionConverter;
import com.example.umc9th.domain.mission.dto.req.MissionRequestDto;
import com.example.umc9th.domain.mission.dto.res.MissionResponseDto;
import com.example.umc9th.domain.mission.entity.Mission;
import com.example.umc9th.domain.mission.repository.MissionRepository;
import com.example.umc9th.domain.mission.repository.UserMissionRepository;
import com.example.umc9th.domain.user.entity.User;
import com.example.umc9th.domain.user.entity.UserMission;
import com.example.umc9th.domain.user.repository.MyPageRepository; // 혹은 UserRepository
import com.example.umc9th.global.apiPayload.code.GeneralErrorCode;
import com.example.umc9th.global.apiPayload.exception.GeneralException;
package com.umc9th.domain.mission.service;

import com.umc9th.domain.mission.converter.MissionConverter;
import com.umc9th.domain.mission.dto.req.MissionRequestDto;
import com.umc9th.domain.mission.dto.res.MissionResponseDto;
import com.umc9th.domain.mission.entity.Mission;
import com.umc9th.domain.mission.repository.MissionRepository;
import com.umc9th.domain.mission.repository.UserMissionRepository;
import com.umc9th.domain.user.entity.User;
import com.umc9th.domain.user.entity.UserMission;
import com.umc9th.domain.user.repository.MyPageRepository; // 혹은 UserRepository
import com.umc9th.global.apiPayload.code.GeneralErrorCode;
import com.umc9th.global.apiPayload.exception.GeneralException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.example.umc9th.domain.mission.service;
package com.umc9th.domain.mission.service;

import com.example.umc9th.domain.mission.converter.MissionConverter;
import com.example.umc9th.domain.mission.dto.res.StoreMissionDto;
import com.example.umc9th.domain.mission.entity.Mission;
import com.example.umc9th.domain.mission.repository.MissionRepository;
import com.example.umc9th.global.apiPayload.code.GeneralErrorCode;
import com.example.umc9th.global.apiPayload.exception.GeneralException;
import com.umc9th.domain.mission.converter.MissionConverter;
import com.umc9th.domain.mission.dto.res.StoreMissionDto;
import com.umc9th.domain.mission.entity.Mission;
import com.umc9th.domain.mission.repository.MissionRepository;
import com.umc9th.global.apiPayload.code.GeneralErrorCode;
import com.umc9th.global.apiPayload.exception.GeneralException;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.example.umc9th.domain.review.dto.res;
package com.umc9th.domain.review.dto.res;

import lombok.AllArgsConstructor;
import lombok.Builder;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.example.umc9th.domain.store.controller;
package com.umc9th.domain.store.controller;

import com.example.umc9th.domain.review.dto.req.ReviewCreateRequest;
import com.example.umc9th.domain.review.dto.res.ReviewResDTO;
import com.example.umc9th.domain.review.service.ReviewService;
import com.example.umc9th.global.annotation.ExistStore;
import com.example.umc9th.global.apiPayload.ApiResponse;
import com.example.umc9th.global.apiPayload.code.GeneralSuccessCode;
import com.umc9th.domain.review.dto.req.ReviewCreateRequest;
import com.umc9th.domain.review.dto.res.ReviewResDTO;
import com.umc9th.domain.review.service.ReviewService;
import com.umc9th.global.annotation.ExistStore;
import com.umc9th.global.apiPayload.ApiResponse;
import com.umc9th.global.apiPayload.code.GeneralSuccessCode;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.example.umc9th.domain.store.controller;
package com.umc9th.domain.store.controller;

import com.example.umc9th.domain.mission.dto.res.StoreMissionDto;
import com.example.umc9th.domain.mission.service.MissionQueryService;
import com.example.umc9th.global.annotation.ExistStore;
import com.example.umc9th.global.annotation.PageCheck;
import com.example.umc9th.global.apiPayload.ApiResponse;
import com.example.umc9th.global.apiPayload.code.GeneralSuccessCode;
import com.example.umc9th.global.apiPayload.response.PageResponse;
import com.umc9th.domain.mission.dto.res.StoreMissionDto;
import com.umc9th.domain.mission.service.MissionQueryService;
import com.umc9th.global.annotation.ExistStore;
import com.umc9th.global.annotation.PageCheck;
import com.umc9th.global.apiPayload.ApiResponse;
import com.umc9th.global.apiPayload.code.GeneralSuccessCode;
import com.umc9th.global.apiPayload.response.PageResponse;
import lombok.RequiredArgsConstructor;

import org.springframework.data.domain.Page;
Expand Down
42 changes: 31 additions & 11 deletions src/main/java/com/umc9th/domain/user/controller/UserController.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package com.example.umc9th.domain.user.controller;


import com.example.umc9th.domain.mission.dto.res.GetUserMissionResponse;
import com.example.umc9th.domain.review.dto.UserReviewDto;
import com.example.umc9th.domain.user.service.UserQueryService;
import com.example.umc9th.global.apiPayload.ApiResponse;
import com.example.umc9th.global.apiPayload.code.GeneralSuccessCode;
import com.example.umc9th.global.annotation.PageCheck;
import com.example.umc9th.global.apiPayload.response.PageResponse;
package com.umc9th.domain.user.controller;


import com.umc9th.domain.mission.dto.res.GetUserMissionResponse;
import com.umc9th.domain.review.dto.UserReviewDto;
import com.umc9th.domain.user.dto.UserReqDTO;
import com.umc9th.domain.user.dto.UserResDTO;
import com.umc9th.domain.user.service.UserCommandService;
import com.umc9th.domain.user.service.UserQueryService;
import com.umc9th.global.apiPayload.ApiResponse;
import com.umc9th.global.apiPayload.code.GeneralSuccessCode;
import com.umc9th.global.annotation.PageCheck;
import com.umc9th.global.apiPayload.response.PageResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
Expand All @@ -28,9 +32,10 @@
@RequiredArgsConstructor
@RequestMapping("/users")// 유저 관련 API 경로
@Tag(name="유저")
public class UserController { // 클래스 이름 변경
public class UserController { // 💡 클래스 이름 변경

private final UserQueryService userQueryService;
private final UserCommandService userCommandService;

// [API 1] 내가 작성한 리뷰 목록 조회 (GET /users/{userId}/review-list)
@Operation(summary = "내가 작성한 리뷰 목록 조회", description = "사용자가 작성한 리뷰 목록을 페이지네이션으로 조회합니다. page는 1부터 시작합니다.")
Expand Down Expand Up @@ -93,5 +98,20 @@ public ApiResponse<PageResponse<GetUserMissionResponse>> getUserMissionList(
PageResponse.from(pageResponse)
);
}
// 회원가입
@PostMapping("/signup")
@Operation(summary = "회원가입api")
public ApiResponse<String> join(@RequestBody @Valid UserReqDTO.JoinDTO request) {
userCommandService.joinUser(request);
return ApiResponse.onSuccess(GeneralSuccessCode.CREATED, "회원가입 성공!");
}

// 로그인
@PostMapping("/login")
@Operation(summary = "로그인api")
public ApiResponse<UserResDTO.LoginDTO> login(
@RequestBody @Valid UserReqDTO.LoginDTO dto
){
return ApiResponse.onSuccess(GeneralSuccessCode.OK, userQueryService.login(dto));
}
}
35 changes: 35 additions & 0 deletions src/main/java/com/umc9th/domain/user/converter/UserConverter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.umc9th.domain.user.converter;

import com.umc9th.domain.user.dto.UserReqDTO;
import com.umc9th.domain.user.dto.UserResDTO;
import com.umc9th.domain.user.entity.User;
import com.umc9th.global.enums.Role;
import com.umc9th.domain.user.enums.SocialType;
public class UserConverter {

//DTO, Salted Passwd, Role -> Entity
public static User toUser(
UserReqDTO.JoinDTO dto,
String password,
Role role
){
return User.builder()
.name(dto.name())
.email(dto.email()) // 추가된 코드
.password(password) // 추가된 코드
.role(role) // 추가된 코드
.birthday(dto.birthday())
.address(dto.address())
.gender(dto.gender())
.socialType(SocialType.naver)
.userPoint(0L)
.build();
}
//login
public static UserResDTO.LoginDTO toLoginDTO(User user, String accessToken) {
return UserResDTO.LoginDTO.builder()
.userId(user.getId())
.accessToken(accessToken)
.build();
}
}
38 changes: 38 additions & 0 deletions src/main/java/com/umc9th/domain/user/dto/UserReqDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.umc9th.domain.user.dto;

import com.umc9th.domain.user.enums.Address;
import com.umc9th.domain.user.enums.Gender;
import com.umc9th.global.annotation.ExistCategories;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;

import java.time.LocalDate;
import java.util.List;

public class UserReqDTO {
public record JoinDTO(
@NotBlank
String name,
@Email
String email, // 추가된 속성
@NotBlank
String password, // 추가된 속성
@NotNull
Gender gender,
@NotNull
LocalDate birthday,
@NotNull
Address address,
@ExistCategories
List<Long> preferCategory
){}

//로그인dto
public record LoginDTO(
@NotBlank
String email,
@NotBlank
String password
){}
}
13 changes: 13 additions & 0 deletions src/main/java/com/umc9th/domain/user/dto/UserResDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.umc9th.domain.user.dto;

import lombok.Builder;

public class UserResDTO {

// 로그인
@Builder
public record LoginDTO(
Long userId,
String accessToken
){}
}
11 changes: 10 additions & 1 deletion src/main/java/com/umc9th/domain/user/entity/User.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.umc9th.domain.user.entity;

import com.umc9th.global.enums.Role;
import com.umc9th.domain.user.enums.Address;
import com.umc9th.domain.user.enums.Gender;
import com.umc9th.domain.user.enums.SocialType;
Expand Down Expand Up @@ -45,6 +46,14 @@ public class User extends BaseEntity {
@Column(name ="userpoint", nullable = false)
private Long userPoint;

@Column(nullable = false, unique = true)
private String email;

@Column(nullable = false)
private String password;

}
@Enumerated(EnumType.STRING)
private Role role;


}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.example.umc9th.domain.user.repository;
package com.umc9th.domain.user.repository;

import com.example.umc9th.domain.review.dto.UserReviewDto; // 💡 사용자 리뷰 목록 DTO
import com.example.umc9th.domain.user.dto.MyPageUserDto; // 💡 마이 페이지 상단 DTO
import com.example.umc9th.domain.user.entity.User; // User 엔티티 import
import com.umc9th.domain.review.dto.UserReviewDto; // 💡 사용자 리뷰 목록 DTO
import com.umc9th.domain.user.dto.MyPageUserDto; // 💡 마이 페이지 상단 DTO
import com.umc9th.domain.user.entity.User; // User 엔티티 import
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
Expand All @@ -19,7 +19,7 @@ public interface MyPageRepository extends JpaRepository<User, Long> {

// [1. 마이 페이지 상단 정보 조회 쿼리]
// 마이 페이지 화면 (닉네임, 포인트, 리뷰 개수 등)에 필요한 데이터를 조회
@Query("SELECT new com.example.umc9th.domain.user.dto.MyPageUserDto(" +
@Query("SELECT new com.umc9th.domain.user.dto.MyPageUserDto(" +
"u.name, " +
"u.address, " +
"u.userPoint, " +
Expand All @@ -33,7 +33,7 @@ public interface MyPageRepository extends JpaRepository<User, Long> {

//2. 사용자가 작성한 리뷰 목록 조회 쿼리
// '작성한 리뷰' 버튼 클릭 시 호출되어, page로 반환
@Query("SELECT new com.example.umc9th.domain.review.dto.UserReviewDto(" +
@Query("SELECT new com.umc9th.domain.review.dto.UserReviewDto(" +
"r.id, " +
"s.storeName, " + // Store 정보를 가져옴
"r.star, " +
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.umc9th.domain.user.repository;

import com.umc9th.domain.user.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface UserRepository extends JpaRepository<User, Long> {

//이메일로 유저찾기
Optional<User> findByEmail(String email);
}
Loading