From 2f426fbcee5f89b904b6685ad34212cc58458963 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Fri, 25 Aug 2023 05:44:15 +0900 Subject: [PATCH 01/60] =?UTF-8?q?=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC,=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 81 +++++---- .../mos/mosback/StudyGroupController.java | 69 -------- .../mosback/controller/IndexController.java | 42 +++++ .../mosback/controller/PostsController.java | 76 ++++++++ .../mosback/domain/posts/BaseTimeEntity.java | 23 +++ .../java/mos/mosback/domain/posts/Posts.java | 95 ++++++++++ .../mosback/domain/posts/PostsRepository.java | 22 +++ .../mos/mosback/dto/StudyGroupRequest.java | 162 ------------------ .../java/mos/mosback/entity/StudyGroup.java | 66 ------- .../repository/StudyGroupRepository.java | 9 - .../java/mos/mosback/service/PostService.java | 89 ++++++++++ .../java/mos/mosback/service/StudyGroup.java | 4 - .../mosback/service/StudyGroupService.java | 11 -- .../service/StudyGroupServiceImpl.java | 29 ---- .../mosback/web/dto/PostSaveRequestDto.java | 78 +++++++++ .../mosback/web/dto/PostsListResponseDto.java | 50 ++++++ .../mos/mosback/web/dto/PostsResponseDto.java | 50 ++++++ .../web/dto/PostsUpdateRequestDto.java | 52 ++++++ src/main/resources/application.properties | 30 +--- 19 files changed, 629 insertions(+), 409 deletions(-) delete mode 100644 src/main/java/mos/mosback/StudyGroupController.java create mode 100644 src/main/java/mos/mosback/controller/IndexController.java create mode 100644 src/main/java/mos/mosback/controller/PostsController.java create mode 100644 src/main/java/mos/mosback/domain/posts/BaseTimeEntity.java create mode 100644 src/main/java/mos/mosback/domain/posts/Posts.java create mode 100644 src/main/java/mos/mosback/domain/posts/PostsRepository.java delete mode 100644 src/main/java/mos/mosback/dto/StudyGroupRequest.java delete mode 100644 src/main/java/mos/mosback/entity/StudyGroup.java delete mode 100644 src/main/java/mos/mosback/repository/StudyGroupRepository.java create mode 100644 src/main/java/mos/mosback/service/PostService.java delete mode 100644 src/main/java/mos/mosback/service/StudyGroup.java delete mode 100644 src/main/java/mos/mosback/service/StudyGroupService.java delete mode 100644 src/main/java/mos/mosback/service/StudyGroupServiceImpl.java create mode 100644 src/main/java/mos/mosback/web/dto/PostSaveRequestDto.java create mode 100644 src/main/java/mos/mosback/web/dto/PostsListResponseDto.java create mode 100644 src/main/java/mos/mosback/web/dto/PostsResponseDto.java create mode 100644 src/main/java/mos/mosback/web/dto/PostsUpdateRequestDto.java diff --git a/build.gradle b/build.gradle index ae40091..2783226 100644 --- a/build.gradle +++ b/build.gradle @@ -1,47 +1,58 @@ -buildscript { - ext { - springBootVersion = "2.1.7.RELEASE" - } - repositories { - mavenCentral() - jcenter() - } - dependencies { - classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") - } +plugins { // (1) + id 'org.springframework.boot' version '2.4.1' + id 'io.spring.dependency-management' version '1.0.10.RELEASE' + id 'java' + id 'maven-publish' } -plugins { - id 'java' +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 } -apply plugin: 'java' -apply plugin: 'eclipse' -apply plugin: 'org.springframework.boot' -apply plugin: 'io.spring.dependency-management' +group = 'jpabook' +version = '0.0.1-SNAPSHOT' -group 'mos.mosback' -version '1.0-SNAPSHOT' -sourceCompatibility = '11' +configurations { + compileOnly { + extendsFrom annotationProcessor + } +} repositories { mavenCentral() + jcenter() } -dependencies { - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - implementation 'org.springframework.boot:spring-boot-starter-validation' - implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' - implementation 'org.springframework.boot:spring-boot-starter-web' - compileOnly 'org.projectlombok:lombok' - runtimeOnly 'com.h2database:h2' - annotationProcessor 'org.projectlombok:lombok' - testImplementation 'org.springframework.boot:spring-boot-starter-test' -//JUnit4 추가 - testImplementation("org.junit.vintage:junit-vintage-engine") { - exclude group: "org.hamcrest", module: "hamcrest-core" - } -} -test { +// for Junit 5 +test { // (2) useJUnitPlatform() +} + +dependencies { + //(3) + implementation('org.springframework.boot:spring-boot-starter-web') + implementation('org.springframework.boot:spring-boot-starter-mustache') + + // lombok + implementation('org.projectlombok:lombok:1.18.20') + testImplementation 'junit:junit:4.13.1' + annotationProcessor('org.projectlombok:lombok:1.18.20') + testImplementation('org.projectlombok:lombok:1.18.20') + testAnnotationProcessor('org.projectlombok:lombok:1.18.20') + + implementation('org.springframework.boot:spring-boot-starter-data-jpa') + implementation("org.mariadb.jdbc:mariadb-java-client") + implementation('com.h2database:h2') + + implementation('org.springframework.boot:spring-boot-starter-oauth2-client') + implementation('org.springframework.session:spring-session-jdbc') + + testImplementation('org.springframework.boot:spring-boot-starter-test') + testImplementation("org.springframework.security:spring-security-test") + + implementation 'org.springframework.security:spring-security-core:5.4.10' + + + } \ No newline at end of file diff --git a/src/main/java/mos/mosback/StudyGroupController.java b/src/main/java/mos/mosback/StudyGroupController.java deleted file mode 100644 index 7ea8931..0000000 --- a/src/main/java/mos/mosback/StudyGroupController.java +++ /dev/null @@ -1,69 +0,0 @@ -package mos.mosback; - -import com.fasterxml.jackson.databind.ObjectMapper; -import mos.mosback.dto.StudyGroupRequest; -import mos.mosback.entity.StudyGroup; -import mos.mosback.service.StudyGroupService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.*; - -import javax.servlet.RequestDispatcher; -import javax.servlet.http.HttpServletRequest; -import java.util.Date; -import java.util.List; - -@ComponentScan -@Controller -@RequestMapping("/study-groups") -public class StudyGroupController { - - private final StudyGroupService studyGroupService; - private final ObjectMapper objectMapper; - - @Autowired - public StudyGroupController(StudyGroupService studyGroupService, ObjectMapper objectMapper) { - this.studyGroupService = studyGroupService; - this.objectMapper = objectMapper; - } - - @GetMapping("/") - public String index(Model model) { - List studyGroups = studyGroupService.getAllStudyGroups(); - model.addAttribute("studyGroups", studyGroups); - return "index"; // 뷰 이름에 확장자 .html 추가 - } - @GetMapping("/create") - public String createForm(Model model) { - List studyGroups = studyGroupService.getAllStudyGroups(); - model.addAttribute("studyGroups", studyGroups); - return "create_form"; // Assuming create_form.html is a Thymeleaf template - } - - @PostMapping("/create") - public ResponseEntity createStudyGroup(@RequestBody StudyGroupRequest studyGroupRequest) { - try { - StudyGroup studyGroup = objectMapper.convertValue(studyGroupRequest, StudyGroup.class); - studyGroupService.createStudyGroup(studyGroup); - return new ResponseEntity<>("Study group created successfully", HttpStatus.CREATED); - } catch (Exception e) { - return new ResponseEntity<>("Failed to create study group", HttpStatus.INTERNAL_SERVER_ERROR); - } - } - - @RequestMapping("/error") - public String handleError(HttpServletRequest request, Model model) { - Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE); - if (status != null) { - int statusCode = Integer.parseInt(status.toString()); - model.addAttribute("errorCode", statusCode); - // 추가적인 오류 처리 로직을 여기에 작성할 수 있습니다. - } - return "error"; // error.html 템플릿을 생성하고 해당 템플릿을 이용하여 오류 정보를 출력 - } - -} \ No newline at end of file diff --git a/src/main/java/mos/mosback/controller/IndexController.java b/src/main/java/mos/mosback/controller/IndexController.java new file mode 100644 index 0000000..60d57e7 --- /dev/null +++ b/src/main/java/mos/mosback/controller/IndexController.java @@ -0,0 +1,42 @@ +package mos.mosback.controller; +import lombok.RequiredArgsConstructor; +import mos.mosback.service.PostService; +import mos.mosback.web.dto.PostsResponseDto; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import javax.servlet.http.HttpSession; + +@RequiredArgsConstructor +@Controller //머스테치에 URL 매핑해주기 +public class IndexController { + private final PostService postService; + private final HttpSession httpSession; +// @GetMapping("/")//머스테치 스타터 덕분에 +// // 컨트롤러에서 문자열을 반환할 때 앞의 경로와 뒤의 파일 확정자는 자동으로 지정된다. +// public String index(Model model, @LoginUser SessionUser user) { +// model.addAttribute("posts", postService.findAllDesc()); +// if (user != null) { +// model.addAttribute("userName", user.getName()); +// } +// return "index"; +// } + + @GetMapping("/posts/save") + public String postsSave() { + return "posts-save"; + } + + @GetMapping("posts/update/{id}") + public String Update(@PathVariable Long id, + Model model){ + + PostsResponseDto dto = postService.findById(id); + model.addAttribute("post",dto); + + return "posts-update"; + + } + +} diff --git a/src/main/java/mos/mosback/controller/PostsController.java b/src/main/java/mos/mosback/controller/PostsController.java new file mode 100644 index 0000000..3a040b4 --- /dev/null +++ b/src/main/java/mos/mosback/controller/PostsController.java @@ -0,0 +1,76 @@ +package mos.mosback.controller; +import mos.mosback.web.dto.PostSaveRequestDto; +import mos.mosback.web.dto.PostsListResponseDto; +import mos.mosback.web.dto.PostsResponseDto; +import mos.mosback.web.dto.PostsUpdateRequestDto; +import mos.mosback.service.PostService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/api/mos") //URL 패턴 +public class PostsController { + + private final PostService postService; // PostService를 주입. + + @Autowired + public PostsController(PostService postService) { + this.postService = postService; + } + + @PostMapping("/create") + public ResponseEntity savePost(@RequestBody PostSaveRequestDto requestDto) { + Long postId = postService.save(requestDto); + String message = "created successfully. ID: " + postId; + return ResponseEntity.status(HttpStatus.CREATED).body(message); + } + + @GetMapping("/{id}") + public ResponseEntity FindByID (@PathVariable Long id) { + PostsResponseDto post = postService.findById(id); + return new ResponseEntity<>(post, HttpStatus.OK); + } + + @GetMapping("/search") + public ResponseEntity> searchPosts(@RequestParam String keyword) { + List posts = postService.findByTitleContaining(keyword); + return new ResponseEntity<>(posts, HttpStatus.OK); + } + + @PutMapping("/{id}") + public ResponseEntity updatePost(@PathVariable Long id, @RequestBody PostsUpdateRequestDto requestDto) { + Long updatedId = postService.update(id, requestDto); + return new ResponseEntity<>(updatedId, HttpStatus.OK); + } + + @DeleteMapping("/{id}") + public ResponseEntity deletePost(@PathVariable Long id) { + postService.delete(id); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @GetMapping("/all") + public ResponseEntity> getAllPosts() { + List posts = postService.findAllDesc(); + return new ResponseEntity<>(posts, HttpStatus.OK); + } + + @GetMapping("/popular") + public ResponseEntity> getPopularPosts() { + List popularPosts = postService.findPopularPosts(); + return new ResponseEntity<>(popularPosts, HttpStatus.OK); + } +} +//핸들러 메서드 : +// +//create: 새 게시물을 생성하는 엔드포인트. +//getPost: 특정 ID에 해당하는 게시물을 조회하는 엔드포인트. +//searchPosts: 제목에 키워드가 포함된 게시물을 검색하는 엔드포인트. +//updatePost: 게시물을 업데이트하는 엔드포인트. +//deletePost: 게시물을 삭제하는 엔드포인트. +//getAllPosts: 모든 게시물을 조회하는 엔드포인트. +//getPopularPosts: 조회순으로 게시물을 조회하는 엔드포인트. (인기순 조회시) diff --git a/src/main/java/mos/mosback/domain/posts/BaseTimeEntity.java b/src/main/java/mos/mosback/domain/posts/BaseTimeEntity.java new file mode 100644 index 0000000..9d0aa1a --- /dev/null +++ b/src/main/java/mos/mosback/domain/posts/BaseTimeEntity.java @@ -0,0 +1,23 @@ +package mos.mosback.domain.posts; +import lombok.Getter; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import javax.persistence.EntityListeners; +import javax.persistence.MappedSuperclass; +import java.time.LocalDateTime; + +@Getter +@MappedSuperclass //JPA Entity 클래스들이 BaseTimeEntity를 상속할 경우 필드들도 칼럼으로 인식하도록 한다 +@EntityListeners(AuditingEntityListener.class) //BaseTimeEntity 클래스에 Auditing 기능을 포함한다 +public abstract class BaseTimeEntity { + + @CreatedDate //Entity가 생성되어 저장될때 시간이 자동저장 + private LocalDateTime createdDate; + + @LastModifiedDate //조회한 Entity의 값을 변경할 때 시간이 자동저장 (이 기능은 굳이 필요 없을지도 ) + private LocalDateTime modifiedDate; + +} +//모든 Entity의 상위 클래스가 되어 엔티티들의 생성시간 변경시간을 자동으로 관리하는 클래스 \ No newline at end of file diff --git a/src/main/java/mos/mosback/domain/posts/Posts.java b/src/main/java/mos/mosback/domain/posts/Posts.java new file mode 100644 index 0000000..4a0e091 --- /dev/null +++ b/src/main/java/mos/mosback/domain/posts/Posts.java @@ -0,0 +1,95 @@ +package mos.mosback.domain.posts; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import mos.mosback.domain.posts.BaseTimeEntity; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import java.util.Date; + +@Getter // 롬복 어노테이션 +@NoArgsConstructor // 롬복 어노테이션 (필수는 아님 그냥 코드 단순화용) +@Entity //JPA 어노테이션 (주요어노테이션) : 테이블과 링크될 클래스임을 나타냄 +public class Posts extends BaseTimeEntity { + //Posts 클래스 - > 실제 DB테이블과 매칭될 클래스 ( Entity 클래스 ) + @Id //해당 테이블 PK 필드 나타냄 + @GeneratedValue(strategy = GenerationType.IDENTITY) //PK 생성규칙 나타냄 스프링 2.0은 + //GenerationType.IDENTITY 옵션을 추가해야만 auto_increment가 된다. + private Long id; + //웬만하면 Entity의 Pk는 long타입의 auto_increment 쓰는게 좋음 + @Column(length = 500, nullable = false) + private String title; + + @Column(columnDefinition = "TEXT", nullable = false) + private String goal; //스터디 목표 + private String rules; //스터디 규칙 + private String quest; //생성 시 질문 + private String tend; //유저 스터디 성향 + private String category; // 스터디 카테고리 + private String date; //스터디 요일 + private String intro; //스터디 소개 + + @Column(columnDefinition = "INT", nullable = false) + + private int num; //멤버수 + private String mod; //스터디 분위기 + private int click;// 클릭횟수 (인기순 조회) + + @Column(columnDefinition = "BOOLEAN", nullable = false) + + private boolean onOff; //진행방식 (온오프) + + @Column(columnDefinition = "DATE", nullable = false) + + private Date startDate; //스터디 시작 날짜 + private Date endDate; //스터디 끝나는 날짜 + private Date createDate; // 스터디룸 생성 날짜 + private Date rcstart; // 모집 시작 날짜 + private Date rcend; //모집 마감 날짜 + @Builder //해당 클래스의 빌더 클래스 생성. 생성자 상단에 선언 시 생성자에 포함된 필드만 빌더에 포함 + public Posts(String title, String goal, String rules, String quest, String tend, + String category, String date, String intro, int num, String mod, + boolean onOff, Date startDate, Date endDate, Date rcstart, Date rcend) { + this.title = title; + this.goal = goal; + this.rules = rules; + this.quest = quest; + this.tend = tend; + this.category = category; + this.date = date; + this.intro = intro; + this.mod = mod; + this.num = num; + this.onOff = onOff; + this.startDate = startDate; + this.endDate = endDate; + this.rcstart = rcstart; + this.rcend = rcend; + } + public void update(String title, String goal, String rules, String quest, String tend, + String category, String date, String intro, int num, String mod, + boolean onOff, Date startDate, Date endDate, Date rcstart, Date rcend) { + this.title = title; + this.goal = goal; + this.rules = rules; + this.quest = quest; + this.tend = tend; + this.category = category; + this.date = date; + this.intro = intro; + this.mod = mod; + this.num = num; + this.onOff = onOff; + this.startDate = startDate; + this.endDate = endDate; + this.rcstart = rcstart; + this.rcend = rcend; + } + + +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/domain/posts/PostsRepository.java b/src/main/java/mos/mosback/domain/posts/PostsRepository.java new file mode 100644 index 0000000..0c34dda --- /dev/null +++ b/src/main/java/mos/mosback/domain/posts/PostsRepository.java @@ -0,0 +1,22 @@ +package mos.mosback.domain.posts; + +//Entity 클래스와 Entity레파지토리 위치 같아야함 +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + + +import java.util.List; + +//인터페이스 생성 후 JpaRepository를 상속하면 기본적인 CRUD 메소드 자동으로 생성됨 +public interface PostsRepository extends JpaRepository { + + @Query("SELECT p FROM Posts p ORDER BY p.id DESC") + List findAllDesc(); + + + List findByTitleContaining(String keyword); //키워드를 통해 스터디그룹을 검색 할 수 있다 + + @Query(value = "SELECT * FROM posts ORDER BY click_count DESC", nativeQuery = true) + List findPopularPosts(); //클릭수로 인기순 나열 +} +//Posts 클래스로 DB를 접근하기 위한 클래스 \ No newline at end of file diff --git a/src/main/java/mos/mosback/dto/StudyGroupRequest.java b/src/main/java/mos/mosback/dto/StudyGroupRequest.java deleted file mode 100644 index 606e06b..0000000 --- a/src/main/java/mos/mosback/dto/StudyGroupRequest.java +++ /dev/null @@ -1,162 +0,0 @@ -package mos.mosback.dto; -import org.springframework.web.bind.annotation.RequestMapping; - -import java.util.Date; - -@RequestMapping("/create") -public class StudyGroupRequest { - - private Long key; - private String title; - private String mode; - private int num; - private Date startDate; - private Date endDate; - private boolean onoff; - private String date; - private String goal; - private String rules; - private Date createDate; - private int click; - private Date rcstart; - private Date rcend; - private String quest; - private String tend; - private Integer category; - - public Long getKey() { - return key; - } - - public void setKey(Long key) { - this.key = key; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getMode() { - return mode; - } - - public void setMode(String mode) { - this.mode = mode; - } - - public int getNum() { - return num; - } - - public void setNum(int num) { - this.num = num; - } - - public Date getStartDate() { - return startDate; - } - - public void setStartDate(Date startDate) { - this.startDate = startDate; - } - - public Date getEndDate() { - return endDate; - } - - public void setEndDate(Date endDate) { - this.endDate = endDate; - } - - public boolean isOnoff() { - return onoff; - } - - public void setOnoff(boolean onoff) { - this.onoff = onoff; - } - - public String getDate() { - return date; - } - - public void setDate(String date) { - this.date = date; - } - - public String getGoal() { - return goal; - } - - public void setGoal(String goal) { - this.goal = goal; - } - - public String getRules() { - return rules; - } - - public void setRules(String rules) { - this.rules = rules; - } - - public Date getCreateDate() { - return createDate; - } - - public void setCreateDate(Date createDate) { - this.createDate = createDate; - } - - public int getClick() { - return click; - } - - public void setClick(int click) { - this.click = click; - } - - public Date getRcstart() { - return rcstart; - } - - public void setRcstart(Date rcstart) { - this.rcstart = rcstart; - } - - public Date getRcend() { - return rcend; - } - - public void setRcend(Date rcend) { - this.rcend = rcend; - } - - public String getQuest() { - return quest; - } - - public void setQuest(String quest) { - this.quest = quest; - } - - public String getTend() { - return tend; - } - - public void setTend(String tend) { - this.tend = tend; - } - - public Integer getCategory() { - return category; - } - - public void setCategory(Integer category) { - this.category = category; - } -} \ No newline at end of file diff --git a/src/main/java/mos/mosback/entity/StudyGroup.java b/src/main/java/mos/mosback/entity/StudyGroup.java deleted file mode 100644 index ad1d014..0000000 --- a/src/main/java/mos/mosback/entity/StudyGroup.java +++ /dev/null @@ -1,66 +0,0 @@ -package mos.mosback.entity; - - -import javax.persistence.*; -import java.util.Date; - -@Entity -@Table(name = "study_group") -public class StudyGroup { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long key; - - @Column(name = "title") - private String title; - - @Column - private String mode; - - @Column(name = "num") - private int num; - - @Column - private Date startDate; - - @Column - private Date endDate; - - @Column - private String date; - - @Column - private String goal; - - @Column - private String rules; - - @Column - private Date createDate; - - @Column - private Integer click; - - @Column - private Date rcstart; - - @Column - private Date rcend; - - @Column - private String quest; - - - @Column - private String tend; - - @Column - private String category; - - @Column - private boolean onoff; - - - -} diff --git a/src/main/java/mos/mosback/repository/StudyGroupRepository.java b/src/main/java/mos/mosback/repository/StudyGroupRepository.java deleted file mode 100644 index c1cf8a5..0000000 --- a/src/main/java/mos/mosback/repository/StudyGroupRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package mos.mosback.repository; - - -import mos.mosback.entity.StudyGroup; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface StudyGroupRepository extends JpaRepository { - // Custom query methods, if needed -} diff --git a/src/main/java/mos/mosback/service/PostService.java b/src/main/java/mos/mosback/service/PostService.java new file mode 100644 index 0000000..2d5aefc --- /dev/null +++ b/src/main/java/mos/mosback/service/PostService.java @@ -0,0 +1,89 @@ +package mos.mosback.service; +import lombok.RequiredArgsConstructor; +import mos.mosback.domain.posts.Posts; +import mos.mosback.domain.posts.PostsRepository; +import mos.mosback.web.dto.PostSaveRequestDto; +import mos.mosback.web.dto.PostsListResponseDto; +import mos.mosback.web.dto.PostsResponseDto; +import mos.mosback.web.dto.PostsUpdateRequestDto; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.List; +import java.util.stream.Collectors; + + +@RequiredArgsConstructor +@Service +public class PostService { + private final PostsRepository postsRepository; + + @Transactional + public Long save(PostSaveRequestDto requestDto){ + return postsRepository.save(requestDto.toEntity()).getId(); + } + + + @Transactional + public Long update(Long id, PostsUpdateRequestDto requestDto) { + Posts posts = postsRepository.findById(id) + .orElseThrow(() -> new IllegalArgumentException("해당 사용자가 없습니다. id=" + id)); + + posts.update(requestDto.getTitle(), requestDto.getGoal(),requestDto.getRules() + ,requestDto.getQuest(),requestDto.getTend(),requestDto.getCategory(), + requestDto.getDate(),requestDto.getIntro(),requestDto.getNum(), + requestDto.getMod(),requestDto.isOnOff(),requestDto.getStartDate(), + requestDto.getEndDate(),requestDto.getRcstart(),requestDto.getRcend()); + + return id; + } //postsRepository를 사용하여 데이터베이스에서 주어진 id에 해당하는 게시물을 찾기 + + + @Transactional(readOnly = true) + public PostsResponseDto findById(Long id) { + Posts entity = postsRepository.findById(id) + .orElseThrow(() -> new IllegalArgumentException("해당 사용자가 없습니다. id=" + id)); + + return new PostsResponseDto(entity); + } + + @Transactional(readOnly = true) + public List findAllDesc() { + return postsRepository.findAllDesc().stream() + .map(PostsListResponseDto::new) //.map(post->new PostResponse(posts))랑 같음 + // postsRepository 결과로 넘어온 Posts의 Stream을 + // map을 통해 PostsListResponseDto변환 ->List로 반환하는 메소드 + + .collect(Collectors.toList()); + } + + @Transactional + public void delete (Long id){ + Posts posts = postsRepository.findById(id) + .orElseThrow(()-> new IllegalArgumentException("해당 게시물이 없습니다. id =" + id)); + + postsRepository.delete(posts); //JpaRepository 에서 이미 delete 메소드를 지원하고 있으므로 활용 + //엔티티를 파라미터로 살제할 수도 있고, deleteById 메서드를 이용하면 id로 삭제할 수 있음 + // 존재하는 Posts인지 확인을 위해 엔티티 조회 후 그대로 삭제함 + // --> 서비스에서 delete 메서드를 만들면 컨트롤러가 사용하도록 컨트롤러에 코드 추가하기. + } + @Transactional(readOnly = true) + public List findByTitleContaining(String keyword) { + List posts = postsRepository.findByTitleContaining(keyword); + if (posts.isEmpty()) { + throw new IllegalArgumentException("해당 스터디가 없습니다."); + } + return posts.stream() + .map(PostsListResponseDto::new) + .collect(Collectors.toList()); + } + + + @Transactional(readOnly = true) + public List findPopularPosts() { + // 클릭된 조회수 순으로 게시물을 조회하는 비즈니스 로직을 호출 + List popularPosts = postsRepository.findPopularPosts(); + return popularPosts.stream() + .map(PostsListResponseDto::new) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/mos/mosback/service/StudyGroup.java b/src/main/java/mos/mosback/service/StudyGroup.java deleted file mode 100644 index 2a854b6..0000000 --- a/src/main/java/mos/mosback/service/StudyGroup.java +++ /dev/null @@ -1,4 +0,0 @@ -package mos.mosback.service; - -public class StudyGroup { -} diff --git a/src/main/java/mos/mosback/service/StudyGroupService.java b/src/main/java/mos/mosback/service/StudyGroupService.java deleted file mode 100644 index 191e94b..0000000 --- a/src/main/java/mos/mosback/service/StudyGroupService.java +++ /dev/null @@ -1,11 +0,0 @@ -package mos.mosback.service; - - -import java.util.List; - -public interface StudyGroupService { - - void createStudyGroup(mos.mosback.entity.StudyGroup studyGroup); - - List getAllStudyGroups(); -} diff --git a/src/main/java/mos/mosback/service/StudyGroupServiceImpl.java b/src/main/java/mos/mosback/service/StudyGroupServiceImpl.java deleted file mode 100644 index a77148a..0000000 --- a/src/main/java/mos/mosback/service/StudyGroupServiceImpl.java +++ /dev/null @@ -1,29 +0,0 @@ -package mos.mosback.service; - - -import mos.mosback.entity.StudyGroup; -import mos.mosback.repository.StudyGroupRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import java.util.List; - -@Service -public class StudyGroupServiceImpl implements StudyGroupService { - - private final StudyGroupRepository studyGroupRepository; - - @Autowired - public StudyGroupServiceImpl(StudyGroupRepository studyGroupRepository) { - this.studyGroupRepository = studyGroupRepository; - } - - @Override - public void createStudyGroup(StudyGroup studyGroup) { - studyGroupRepository.save(studyGroup); - } - - @Override - public List getAllStudyGroups() { - return studyGroupRepository.findAll(); - } -} diff --git a/src/main/java/mos/mosback/web/dto/PostSaveRequestDto.java b/src/main/java/mos/mosback/web/dto/PostSaveRequestDto.java new file mode 100644 index 0000000..41187db --- /dev/null +++ b/src/main/java/mos/mosback/web/dto/PostSaveRequestDto.java @@ -0,0 +1,78 @@ +package mos.mosback.web.dto; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import mos.mosback.domain.posts.Posts; + +import javax.persistence.Column; +import java.util.Date; + +@Getter +@NoArgsConstructor +public class PostSaveRequestDto { + Long id; + private String title; + private String goal; //스터디 목표 + private String rules; //스터디 규칙 + private String quest; //생성 시 질문 + private String tend; //유저 스터디 성향 + private String category; // 스터디 카테고리 + private String date; //스터디 요일 + private String intro; //스터디 소개 + private int num; //멤버수 + private String mod; //스터디 분위기 + private int click;// 클릭횟수 (인기순 조회) + private boolean onOff; //진행방식 (온오프) + private Date startDate; //스터디 시작 날짜 + private Date endDate; //스터디 끝나는 날짜 + private Date createDate; // 스터디룸 생성 날짜 + private Date rcstart; // 모집 시작 날짜 + private Date rcend; //모집 마감 날짜 + + + + @Builder + public PostSaveRequestDto(String title, String goal, String rules, String quest, String tend, + String category, String date, String intro, int num, String mod, + boolean onOff, Date startDate, Date endDate, Date rcstart, Date rcend) { + this.title = title; + this.goal = goal; + this.rules = rules; + this.quest = quest; + this.tend = tend; + this.category = category; + this.date = date; + this.intro = intro; + this.mod = mod; + this.num = num; + this.onOff = onOff; + this.startDate = startDate; + this.endDate = endDate; + this.rcstart = rcstart; + this.rcend = rcend; + } + + public Posts toEntity() { + return Posts.builder() + .title(title) + .goal(goal) + .rules(rules) + .quest(quest) + .tend(tend) + .category(category) + .date(date) + .intro(intro) + .mod(mod) + .num(num) + .date(date) + .intro(intro) + .mod(mod) + .num(num) + .onOff(onOff) + .startDate(startDate) + .endDate(endDate) + .rcstart(rcstart) + .rcend(rcend) + .build(); + } +} diff --git a/src/main/java/mos/mosback/web/dto/PostsListResponseDto.java b/src/main/java/mos/mosback/web/dto/PostsListResponseDto.java new file mode 100644 index 0000000..53a40dc --- /dev/null +++ b/src/main/java/mos/mosback/web/dto/PostsListResponseDto.java @@ -0,0 +1,50 @@ +package mos.mosback.web.dto; +import lombok.Getter; +import mos.mosback.domain.posts.Posts; + +import java.util.Date; + + +@Getter +public class PostsListResponseDto { + Long id; + private String title; + private String goal; //스터디 목표 + private String rules; //스터디 규칙 + private String quest; //생성 시 질문 + private String tend; //유저 스터디 성향 + private String category; // 스터디 카테고리 + private String date; //스터디 요일 + private String intro; //스터디 소개 + private int num; //멤버수 + private String mod; //스터디 분위기 + private int click;// 클릭횟수 (인기순 조회) + private boolean onOff; //진행방식 (온오프) + private Date startDate; //스터디 시작 날짜 + private Date endDate; //스터디 끝나는 날짜 + private Date createDate; // 스터디룸 생성 날짜 + private Date rcstart; // 모집 시작 날짜 + private Date rcend; //모집 마감 날짜 + + + public PostsListResponseDto(Posts entity) { + + this.title = entity.getTitle(); + this.goal = entity.getGoal(); + this.rules = entity.getRules(); + this.quest =entity.getQuest(); + this.tend =entity.getTend(); + this.category =entity.getCategory(); + this.date =entity.getDate(); + this.intro =entity.getIntro(); + this.num = entity.getNum(); + this.mod = entity.getMod(); + this.click = entity.getClick(); + this.onOff = entity.isOnOff(); + this.startDate = entity.getStartDate(); + this.endDate = entity.getEndDate(); + this.rcstart =entity.getRcstart(); + this.rcend =entity.getRcend(); + + } +} diff --git a/src/main/java/mos/mosback/web/dto/PostsResponseDto.java b/src/main/java/mos/mosback/web/dto/PostsResponseDto.java new file mode 100644 index 0000000..9f7f8cd --- /dev/null +++ b/src/main/java/mos/mosback/web/dto/PostsResponseDto.java @@ -0,0 +1,50 @@ +package mos.mosback.web.dto; + +import lombok.Getter; +import mos.mosback.domain.posts.Posts; + +import java.util.Date; + + +@Getter +public class PostsResponseDto { + + private String title; + private String goal; //스터디 목표 + private String rules; //스터디 규칙 + private String quest; //생성 시 질문 + private String tend; //유저 스터디 성향 + private String category; // 스터디 카테고리 + private String date; //스터디 요일 + private String intro; //스터디 소개 + private int num; //멤버수 + private String mod; //스터디 분위기 + private int click;// 클릭횟수 (인기순 조회) + private boolean onOff; //진행방식 (온오프) + private Date startDate; //스터디 시작 날짜 + private Date endDate; //스터디 끝나는 날짜 + private Date createDate; // 스터디룸 생성 날짜 + private Date rcstart; // 모집 시작 날짜 + private Date rcend; //모집 마감 날짜 + public PostsResponseDto(Posts entity) { + + this.title = entity.getTitle(); + this.goal = entity.getGoal(); + this.rules = entity.getRules(); + this.quest =entity.getQuest(); + this.tend =entity.getTend(); + this.category =entity.getCategory(); + this.date =entity.getDate(); + this.intro =entity.getIntro(); + this.num = entity.getNum(); + this.mod = entity.getMod(); + this.click = entity.getClick(); + this.onOff = entity.isOnOff(); + this.startDate = entity.getStartDate(); + this.endDate = entity.getEndDate(); + this.rcstart =entity.getRcstart(); + this.rcend =entity.getRcend();; + + } +} +//Entity의 필드 이루만 사용하므로 생성자로 Entity를 받아 필드에 값을 넣어줌 \ No newline at end of file diff --git a/src/main/java/mos/mosback/web/dto/PostsUpdateRequestDto.java b/src/main/java/mos/mosback/web/dto/PostsUpdateRequestDto.java new file mode 100644 index 0000000..ae8d1aa --- /dev/null +++ b/src/main/java/mos/mosback/web/dto/PostsUpdateRequestDto.java @@ -0,0 +1,52 @@ +package mos.mosback.web.dto; + +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.Date; + +@Getter +@NoArgsConstructor +public class PostsUpdateRequestDto { + + Long id; + private String title; + private String goal; //스터디 목표 + private String rules; //스터디 규칙 + private String quest; //생성 시 질문 + private String tend; //유저 스터디 성향 + private String category; // 스터디 카테고리 + private String date; //스터디 요일 + private String intro; //스터디 소개 + private int num; //멤버수 + private String mod; //스터디 분위기 + private int click;// 클릭횟수 (인기순 조회) + private boolean onOff; //진행방식 (온오프) + private Date startDate; //스터디 시작 날짜 + private Date endDate; //스터디 끝나는 날짜 + private Date createDate; // 스터디룸 생성 날짜 + private Date rcstart; // 모집 시작 날짜 + private Date rcend; //모집 마감 날짜 + + @Builder + public PostsUpdateRequestDto(String title, String goal, String rules, String quest, String tend, + String category, String date, String intro, int num, String mod, + boolean onOff, Date startDate, Date endDate, Date rcstart, Date rcend){ + this.title = title; + this.goal = goal; + this.rules = rules; + this.quest = quest; + this.tend = tend; + this.category = category; + this.date = date; + this.intro = intro; + this.mod = mod; + this.num = num; + this.onOff = onOff; + this.startDate = startDate; + this.endDate = endDate; + this.rcstart = rcstart; + this.rcend = rcend; + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 40edb30..ed45c81 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,26 +1,8 @@ -spring.jpa.show_sql = true - -spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect - +spring.profiles.include=real-oauth +spring.jpa.show_sql=true +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect +spring.jpa.properties.hibernate.dialect.storage_engine=innodb +spring.datasource.hikari.jdbc-url=jdbc:h2:mem:testdb;MODE=MYSQL +spring.datasource.hikari.username=sa spring.h2.console.enabled=true -spring.h2.console.path=/h2-console -spring.datasource.url=jdbc:h2:mem:testdb -spring.jpa.open-in-view=false -spring.mvc.servlet.load-on-startup=1 - -spring.profiles.include=oauth spring.session.store-type=jdbc -logging.level.org.springframework.web=DEBUG - -spring.mvc.view.prefix=/WEB-INF/templates/ -spring.mvc.view.suffix=.html - -#static resource -spring.mvc.static-path-pattern=/static/** -spring.resources.static-locations=classpath:/static/ -spring.mvc.contentnegotiation.media-types.json=application/x-www-form-urlencoded - -#spring.resources.add-mappings=true - -#spring.mvc.throw-exception-if-no-handler-found=true - From 652284290a1c87d5b3ca0d456adc036da62fcf90 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Thu, 31 Aug 2023 00:50:18 +0900 Subject: [PATCH 02/60] =?UTF-8?q?ToDo=EB=A6=AC=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1,=20=EC=A1=B0=ED=9A=8C,=20=EC=88=98=EC=A0=95,?= =?UTF-8?q?=20=EC=82=AD=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mosback/controller/IndexController.java | 4 +- .../mosback/controller/PostsController.java | 14 ++--- .../java/mos/mosback/domain/posts/Posts.java | 5 +- .../mosback/domain/posts/PostsRepository.java | 3 +- .../mos/mosback/domain/posts/ToDoEntity.java | 40 ++++++++++++++ .../mosback/domain/posts/ToDoRepository.java | 12 ++++ .../mos/mosback/domain/posts/TodoEntity.java | 28 ---------- .../java/mos/mosback/repository/UserInfo.java | 2 +- .../java/mos/mosback/service/PostService.java | 25 ++++----- .../java/mos/mosback/service/ToDoService.java | 55 +++++++++++++++++++ .../mosback/web/dto/PostSaveRequestDto.java | 2 +- .../mosback/web/dto/PostsListResponseDto.java | 2 +- .../web/dto/PostsUpdateRequestDto.java | 2 +- .../mos/mosback/web/dto/ToDoRequestDto.java | 29 ++++++++++ .../mos/mosback/web/dto/ToDoResponseDto.java | 16 ++++++ .../java/mos/mosback/web/dto/TodoDto.java | 4 -- 16 files changed, 180 insertions(+), 63 deletions(-) create mode 100644 src/main/java/mos/mosback/domain/posts/ToDoEntity.java create mode 100644 src/main/java/mos/mosback/domain/posts/ToDoRepository.java delete mode 100644 src/main/java/mos/mosback/domain/posts/TodoEntity.java create mode 100644 src/main/java/mos/mosback/service/ToDoService.java create mode 100644 src/main/java/mos/mosback/web/dto/ToDoRequestDto.java create mode 100644 src/main/java/mos/mosback/web/dto/ToDoResponseDto.java delete mode 100644 src/main/java/mos/mosback/web/dto/TodoDto.java diff --git a/src/main/java/mos/mosback/controller/IndexController.java b/src/main/java/mos/mosback/controller/IndexController.java index 60d57e7..92210c0 100644 --- a/src/main/java/mos/mosback/controller/IndexController.java +++ b/src/main/java/mos/mosback/controller/IndexController.java @@ -29,10 +29,10 @@ public String postsSave() { } @GetMapping("posts/update/{id}") - public String Update(@PathVariable Long id, + public String Update(@PathVariable Long groupID, Model model){ - PostsResponseDto dto = postService.findById(id); + PostsResponseDto dto = postService.findById(groupID); model.addAttribute("post",dto); return "posts-update"; diff --git a/src/main/java/mos/mosback/controller/PostsController.java b/src/main/java/mos/mosback/controller/PostsController.java index f424d9a..502e427 100644 --- a/src/main/java/mos/mosback/controller/PostsController.java +++ b/src/main/java/mos/mosback/controller/PostsController.java @@ -29,8 +29,8 @@ public ResponseEntity savePost(@RequestBody PostSaveRequestDto requestDt } @GetMapping("/{id}") - public ResponseEntity FindByID (@PathVariable Long id) { - PostsResponseDto post = postService.findById(id); + public ResponseEntity FindByID (@PathVariable Long groupID) { + PostsResponseDto post = postService.findById(groupID); return new ResponseEntity<>(post, HttpStatus.OK); } @@ -41,20 +41,20 @@ public ResponseEntity> searchPosts(@RequestParam Stri } @PutMapping("/{id}") - public ResponseEntity updatePost(@PathVariable Long id, @RequestBody PostsUpdateRequestDto requestDto) { + public ResponseEntity updatePost(@PathVariable Long groupID, @RequestBody PostsUpdateRequestDto requestDto) { try { - postService.update(id, requestDto); + postService.update(groupID, requestDto); return ResponseEntity.ok("updated."); } catch (IllegalArgumentException e) { return ResponseEntity.status(HttpStatus.NOT_FOUND) - .body("NOT FOUND"+"'"+id+"'"); + .body("NOT FOUND"+"'"+groupID+"'"); } } @DeleteMapping("/{id}") - public ResponseEntity deletePost(@PathVariable Long id) { - postService.delete(id); + public ResponseEntity deletePost(@PathVariable Long groupID) { + postService.delete(groupID); return new ResponseEntity<>(HttpStatus.NO_CONTENT); } diff --git a/src/main/java/mos/mosback/domain/posts/Posts.java b/src/main/java/mos/mosback/domain/posts/Posts.java index 4a0e091..b9dfadc 100644 --- a/src/main/java/mos/mosback/domain/posts/Posts.java +++ b/src/main/java/mos/mosback/domain/posts/Posts.java @@ -1,9 +1,8 @@ package mos.mosback.domain.posts; -import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import mos.mosback.domain.posts.BaseTimeEntity; + import javax.persistence.Column; import javax.persistence.Entity; @@ -20,7 +19,7 @@ public class Posts extends BaseTimeEntity { @Id //해당 테이블 PK 필드 나타냄 @GeneratedValue(strategy = GenerationType.IDENTITY) //PK 생성규칙 나타냄 스프링 2.0은 //GenerationType.IDENTITY 옵션을 추가해야만 auto_increment가 된다. - private Long id; + private Long groupID; //웬만하면 Entity의 Pk는 long타입의 auto_increment 쓰는게 좋음 @Column(length = 500, nullable = false) private String title; diff --git a/src/main/java/mos/mosback/domain/posts/PostsRepository.java b/src/main/java/mos/mosback/domain/posts/PostsRepository.java index 0c34dda..8d85634 100644 --- a/src/main/java/mos/mosback/domain/posts/PostsRepository.java +++ b/src/main/java/mos/mosback/domain/posts/PostsRepository.java @@ -10,10 +10,9 @@ //인터페이스 생성 후 JpaRepository를 상속하면 기본적인 CRUD 메소드 자동으로 생성됨 public interface PostsRepository extends JpaRepository { - @Query("SELECT p FROM Posts p ORDER BY p.id DESC") + @Query("SELECT p FROM Posts p ORDER BY p.groupID DESC") List findAllDesc(); - List findByTitleContaining(String keyword); //키워드를 통해 스터디그룹을 검색 할 수 있다 @Query(value = "SELECT * FROM posts ORDER BY click_count DESC", nativeQuery = true) diff --git a/src/main/java/mos/mosback/domain/posts/ToDoEntity.java b/src/main/java/mos/mosback/domain/posts/ToDoEntity.java new file mode 100644 index 0000000..efe435e --- /dev/null +++ b/src/main/java/mos/mosback/domain/posts/ToDoEntity.java @@ -0,0 +1,40 @@ +package mos.mosback.domain.posts; +import lombok.Builder; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Getter // 롬복 어노테이션 +@NoArgsConstructor +@AllArgsConstructor +@Entity //JPA 어노테이션 (주요어노테이션) : 테이블과 링크될 클래스 +public class ToDoEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long TodoId; + + @Column(nullable = false) + private String todoContent; + + @Column(nullable = false) + private boolean completed; + // TodoLists 상태 ( 완료 - true, 미완료 - false) + + @Builder //해당 클래스의 빌더 클래스 생성. 생성자 상단에 선언 시 생성자에 포함된 필드만 빌더에 포함 + public ToDoEntity(String todoContent, Boolean completed) { + this.todoContent = todoContent; + this.completed = completed; + } + public void updateToDo(String todoContent,boolean completed){ + this.todoContent = todoContent; + this.completed = completed; + } + + +} diff --git a/src/main/java/mos/mosback/domain/posts/ToDoRepository.java b/src/main/java/mos/mosback/domain/posts/ToDoRepository.java new file mode 100644 index 0000000..3ef9dc8 --- /dev/null +++ b/src/main/java/mos/mosback/domain/posts/ToDoRepository.java @@ -0,0 +1,12 @@ +package mos.mosback.domain.posts; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; + +public interface ToDoRepository extends JpaRepository { + @Query("SELECT t FROM ToDoEntity t ORDER BY t.TodoId DESC") + List findAllDesc(); //Todo리스트를 조회시 todoID를 기준으로 내림차순 정렬 + // + +} diff --git a/src/main/java/mos/mosback/domain/posts/TodoEntity.java b/src/main/java/mos/mosback/domain/posts/TodoEntity.java deleted file mode 100644 index 0c7b0d8..0000000 --- a/src/main/java/mos/mosback/domain/posts/TodoEntity.java +++ /dev/null @@ -1,28 +0,0 @@ -package mos.mosback.domain.posts; -import lombok.*; -import lombok.AllArgsConstructor; -import mos.mosback.domain.posts.BaseTimeEntity; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import java.util.Date; - -@Getter // 롬복 어노테이션 -@NoArgsConstructor -@AllArgsConstructor -@Entity //JPA 어노테이션 (주요어노테이션) : 테이블과 링크될 클래스 -public class TodoEntity { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long TodoId; //유저 투두리스트 - - @Column(nullable = false) - private String TodoContent; - - @Column(nullable = false) - private Boolean completed; - -} diff --git a/src/main/java/mos/mosback/repository/UserInfo.java b/src/main/java/mos/mosback/repository/UserInfo.java index 5b5cb64..f8c8b97 100644 --- a/src/main/java/mos/mosback/repository/UserInfo.java +++ b/src/main/java/mos/mosback/repository/UserInfo.java @@ -19,7 +19,7 @@ public Long getId() { return id; } - public void setId(Long id) { + public void setId(Long groupID) { this.id = id; } diff --git a/src/main/java/mos/mosback/service/PostService.java b/src/main/java/mos/mosback/service/PostService.java index 0ec4126..28cf07d 100644 --- a/src/main/java/mos/mosback/service/PostService.java +++ b/src/main/java/mos/mosback/service/PostService.java @@ -21,15 +21,14 @@ public class PostService { @Transactional public Long save(PostSaveRequestDto requestDto){ - return postsRepository.save(requestDto.toEntity()).getId(); + return postsRepository.save(requestDto.toEntity()).getGroupID(); } - - + //스터디를 생성하고 아이디를 반환. @Transactional - public void update(Long id, PostsUpdateRequestDto requestDto) { - Posts posts = postsRepository.findById(id) - .orElseThrow(() -> new IllegalArgumentException(id + " NOT FOUND")); + public void update(Long groupID, PostsUpdateRequestDto requestDto) { + Posts posts = postsRepository.findById(groupID) + .orElseThrow(() -> new IllegalArgumentException(groupID + " NOT FOUND")); posts.update(requestDto.getTitle(), requestDto.getGoal(), requestDto.getRules(), requestDto.getQuest(), requestDto.getTend(), requestDto.getCategory(), @@ -40,9 +39,9 @@ public void update(Long id, PostsUpdateRequestDto requestDto) { @Transactional(readOnly = true) - public PostsResponseDto findById(Long id) { - Posts entity = postsRepository.findById(id) - .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id=" + id)); + public PostsResponseDto findById(Long groupID) { + Posts entity = postsRepository.findById(groupID) + .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id=" + groupID)); return new PostsResponseDto(entity); } @@ -58,9 +57,9 @@ public List findAllDesc() { } @Transactional - public void delete (Long id){ - Posts posts = postsRepository.findById(id) - .orElseThrow(()-> new IllegalArgumentException("해당 게시물이 없습니다. id =" + id)); + public void delete (Long groupID){ + Posts posts = postsRepository.findById(groupID) + .orElseThrow(()-> new IllegalArgumentException("해당 게시물이 없습니다. id =" + groupID)); postsRepository.delete(posts); //JpaRepository 에서 이미 delete 메소드를 지원하고 있으므로 활용 //엔티티를 파라미터로 살제할 수도 있고, deleteById 메서드를 이용하면 id로 삭제할 수 있음 @@ -76,7 +75,7 @@ public List findByTitleContaining(String keyword) { return posts.stream() .map(PostsListResponseDto::new) .collect(Collectors.toList()); - } //스터디 title 로 검색하기 + } //스터디 title 로 검색 @Transactional(readOnly = true) diff --git a/src/main/java/mos/mosback/service/ToDoService.java b/src/main/java/mos/mosback/service/ToDoService.java new file mode 100644 index 0000000..3c70209 --- /dev/null +++ b/src/main/java/mos/mosback/service/ToDoService.java @@ -0,0 +1,55 @@ +package mos.mosback.service; +import lombok.RequiredArgsConstructor; +import mos.mosback.domain.posts.ToDoEntity; +import mos.mosback.domain.posts.ToDoRepository; +import mos.mosback.web.dto.ToDoRequestDto; +import mos.mosback.web.dto.ToDoResponseDto; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.stream.Collectors; + +@RequiredArgsConstructor +@Service +public class ToDoService { + private final ToDoRepository toDoRepository; + + @Transactional + public void addToDo(String todoContent, boolean completed){ + ToDoEntity toDoEntity = ToDoEntity.builder() + .todoContent(todoContent) + .completed(completed) + .build(); + } + //TodoList 추가 + + @Transactional(readOnly = true) + public List findAllDesc() { + return toDoRepository.findAllDesc().stream() + .map(ToDoResponseDto::new) + .collect(Collectors.toList()); + } + //TodoList 조회 + + @Transactional + public void updateToDo(Long TodoId, String todoContent, boolean completed) { + ToDoEntity toDoEntity = toDoRepository.findById(TodoId) + .orElseThrow(() -> new IllegalArgumentException(TodoId + " NOT FOUND")); + + toDoEntity.updateToDo(todoContent, completed); + } + //수정 기능 + + @Transactional + public void delete (Long TodoId){ + ToDoEntity toDoEntity = toDoRepository.findById(TodoId) + .orElseThrow(()-> new IllegalArgumentException("해당 게시물이 없습니다. id =" + TodoId)); + + toDoRepository.delete(toDoEntity); + //엔티티를 파라미터로 삭제할 수도 있고, deleteById 메서드를 이용하면 id로 삭제할 수 있음 + //엔티티 조회 후 그대로 삭제 + //삭제 기능 + } + +} diff --git a/src/main/java/mos/mosback/web/dto/PostSaveRequestDto.java b/src/main/java/mos/mosback/web/dto/PostSaveRequestDto.java index 41187db..167e32c 100644 --- a/src/main/java/mos/mosback/web/dto/PostSaveRequestDto.java +++ b/src/main/java/mos/mosback/web/dto/PostSaveRequestDto.java @@ -10,7 +10,7 @@ @Getter @NoArgsConstructor public class PostSaveRequestDto { - Long id; + Long groupID; private String title; private String goal; //스터디 목표 private String rules; //스터디 규칙 diff --git a/src/main/java/mos/mosback/web/dto/PostsListResponseDto.java b/src/main/java/mos/mosback/web/dto/PostsListResponseDto.java index 53a40dc..e756f53 100644 --- a/src/main/java/mos/mosback/web/dto/PostsListResponseDto.java +++ b/src/main/java/mos/mosback/web/dto/PostsListResponseDto.java @@ -7,7 +7,7 @@ @Getter public class PostsListResponseDto { - Long id; + Long groupID; private String title; private String goal; //스터디 목표 private String rules; //스터디 규칙 diff --git a/src/main/java/mos/mosback/web/dto/PostsUpdateRequestDto.java b/src/main/java/mos/mosback/web/dto/PostsUpdateRequestDto.java index ae8d1aa..8ddcec1 100644 --- a/src/main/java/mos/mosback/web/dto/PostsUpdateRequestDto.java +++ b/src/main/java/mos/mosback/web/dto/PostsUpdateRequestDto.java @@ -10,7 +10,7 @@ @NoArgsConstructor public class PostsUpdateRequestDto { - Long id; + Long groupID; private String title; private String goal; //스터디 목표 private String rules; //스터디 규칙 diff --git a/src/main/java/mos/mosback/web/dto/ToDoRequestDto.java b/src/main/java/mos/mosback/web/dto/ToDoRequestDto.java new file mode 100644 index 0000000..07b9f62 --- /dev/null +++ b/src/main/java/mos/mosback/web/dto/ToDoRequestDto.java @@ -0,0 +1,29 @@ +package mos.mosback.web.dto; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import mos.mosback.domain.posts.ToDoEntity; + + +@Getter +@NoArgsConstructor +public class ToDoRequestDto { + + Long TodoId; + private String todoContent; + private boolean completed; // TodoLists 상태 ( 완료 - true, 미완료 - false) + + @Builder + public ToDoRequestDto(String todoContent, boolean completed) { + this.todoContent = todoContent; + this.completed = completed; + } + + public ToDoEntity toEntity() { + return ToDoEntity.builder() + .todoContent(todoContent) + .completed(completed) + .build(); + } + +} diff --git a/src/main/java/mos/mosback/web/dto/ToDoResponseDto.java b/src/main/java/mos/mosback/web/dto/ToDoResponseDto.java new file mode 100644 index 0000000..6fc5f01 --- /dev/null +++ b/src/main/java/mos/mosback/web/dto/ToDoResponseDto.java @@ -0,0 +1,16 @@ +package mos.mosback.web.dto; +import lombok.Getter; +import mos.mosback.domain.posts.ToDoEntity; + +@Getter +public class ToDoResponseDto { + private Long TodoId; + private String todoContent; + private boolean completed; + + public ToDoResponseDto(ToDoEntity entity) { + + this.todoContent = getTodoContent(); + this.completed = isCompleted(); + } +} diff --git a/src/main/java/mos/mosback/web/dto/TodoDto.java b/src/main/java/mos/mosback/web/dto/TodoDto.java deleted file mode 100644 index 70d1c61..0000000 --- a/src/main/java/mos/mosback/web/dto/TodoDto.java +++ /dev/null @@ -1,4 +0,0 @@ -package mos.mosback.web.dto; - -public class TodoDto { -} From f54e0cbb03abfbe331c8697f7cb0ebc3e060696b Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Tue, 5 Sep 2023 15:32:26 +0900 Subject: [PATCH 03/60] =?UTF-8?q?=EB=AA=A8=EC=A7=91=EA=B8=B0=EA=B0=84?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EC=B6=94=EA=B0=80,=20=EC=8A=A4=ED=84=B0?= =?UTF-8?q?=EB=94=94=EC=A1=B0=ED=9A=8C=20-=20=EC=A7=88=EB=AC=B8=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=20=EC=A0=9C=EC=99=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mosback/controller/PostsController.java | 24 ++++++++++++------- .../java/mos/mosback/domain/posts/Posts.java | 3 --- .../mosback/domain/posts/PostsRepository.java | 8 ++++++- .../java/mos/mosback/service/PostService.java | 8 +++++++ .../mosback/web/dto/PostSaveRequestDto.java | 2 -- .../mosback/web/dto/PostsListResponseDto.java | 3 --- .../mos/mosback/web/dto/PostsResponseDto.java | 8 +++---- .../web/dto/PostsUpdateRequestDto.java | 2 -- 8 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/main/java/mos/mosback/controller/PostsController.java b/src/main/java/mos/mosback/controller/PostsController.java index 502e427..4a28ace 100644 --- a/src/main/java/mos/mosback/controller/PostsController.java +++ b/src/main/java/mos/mosback/controller/PostsController.java @@ -12,7 +12,7 @@ import java.util.List; @RestController -@RequestMapping("/api/mos") //URL 패턴 +@RequestMapping("/api/studyGroup") //URL 패턴 public class PostsController { private final PostService postService; // PostService를 주입. @@ -28,7 +28,7 @@ public ResponseEntity savePost(@RequestBody PostSaveRequestDto requestDt return ResponseEntity.status(HttpStatus.CREATED).body("created successfully. ID: " + postId); } - @GetMapping("/{id}") + @GetMapping("get/{groupID}") public ResponseEntity FindByID (@PathVariable Long groupID) { PostsResponseDto post = postService.findById(groupID); return new ResponseEntity<>(post, HttpStatus.OK); @@ -40,7 +40,7 @@ public ResponseEntity> searchPosts(@RequestParam Stri return new ResponseEntity<>(posts, HttpStatus.OK); } - @PutMapping("/{id}") + @PutMapping("update/{groupID}") public ResponseEntity updatePost(@PathVariable Long groupID, @RequestBody PostsUpdateRequestDto requestDto) { try { postService.update(groupID, requestDto); @@ -52,30 +52,38 @@ public ResponseEntity updatePost(@PathVariable Long groupID, @RequestBod } } - @DeleteMapping("/{id}") + @DeleteMapping("delete/{groupID}") public ResponseEntity deletePost(@PathVariable Long groupID) { postService.delete(groupID); return new ResponseEntity<>(HttpStatus.NO_CONTENT); } - @GetMapping("/all") + @GetMapping("get/all") public ResponseEntity> getAllPosts() { List posts = postService.findAllDesc(); return new ResponseEntity<>(posts, HttpStatus.OK); } - @GetMapping("/popular") + @GetMapping("get/popular") public ResponseEntity> getPopularPosts() { List popularPosts = postService.findPopularPosts(); return new ResponseEntity<>(popularPosts, HttpStatus.OK); } + + @GetMapping("/get/recruitment") + public ResponseEntity> getRecruitment(){ + List RecruitmentPeriod = postService.findGroupRecruitmentPeriod(); + return new ResponseEntity<>(RecruitmentPeriod, HttpStatus.OK); + } + } //핸들러 메서드 : // //create: 새 게시물을 생성하는 엔드포인트. -//getPost: 특정 ID에 해당하는 게시물을 조회하는 엔드포인트. -//searchPosts: 제목에 키워드가 포함된 게시물을 검색하는 엔드포인트. +//getPost: 특정 groupID에 해당하는 게시물을 조회하는 엔드포인트.( 스터디그룹 조회 ) +//searchPosts: 키워드가 포함된 게시물을 검색하는 엔드포인트. //updatePost: 게시물을 업데이트하는 엔드포인트. //deletePost: 게시물을 삭제하는 엔드포인트. //getAllPosts: 모든 게시물을 조회하는 엔드포인트. //getPopularPosts: 조회순으로 게시물을 조회하는 엔드포인트. (인기순 조회시) +//getRecruitment : 모집기간인 게시물을 조회하는 엔드포인트. diff --git a/src/main/java/mos/mosback/domain/posts/Posts.java b/src/main/java/mos/mosback/domain/posts/Posts.java index b9dfadc..f70dbc2 100644 --- a/src/main/java/mos/mosback/domain/posts/Posts.java +++ b/src/main/java/mos/mosback/domain/posts/Posts.java @@ -33,17 +33,14 @@ public class Posts extends BaseTimeEntity { private String date; //스터디 요일 private String intro; //스터디 소개 - @Column(columnDefinition = "INT", nullable = false) private int num; //멤버수 private String mod; //스터디 분위기 private int click;// 클릭횟수 (인기순 조회) - @Column(columnDefinition = "BOOLEAN", nullable = false) private boolean onOff; //진행방식 (온오프) - @Column(columnDefinition = "DATE", nullable = false) private Date startDate; //스터디 시작 날짜 private Date endDate; //스터디 끝나는 날짜 diff --git a/src/main/java/mos/mosback/domain/posts/PostsRepository.java b/src/main/java/mos/mosback/domain/posts/PostsRepository.java index 8d85634..d42956f 100644 --- a/src/main/java/mos/mosback/domain/posts/PostsRepository.java +++ b/src/main/java/mos/mosback/domain/posts/PostsRepository.java @@ -15,7 +15,13 @@ public interface PostsRepository extends JpaRepository { List findByTitleContaining(String keyword); //키워드를 통해 스터디그룹을 검색 할 수 있다 - @Query(value = "SELECT * FROM posts ORDER BY click_count DESC", nativeQuery = true) + @Query(value = "SELECT * FROM posts ORDER BY click DESC", nativeQuery = true) List findPopularPosts(); //클릭수로 인기순 나열 + + + @Query("SELECT p FROM Posts p WHERE p.rcstart <= :currentDate AND p.rcend >= :currentDate") + List findGroupInRecruitmentPeriod(); //모집중인 스터디 조회가능 + + } //Posts 클래스로 DB를 접근하기 위한 클래스 \ No newline at end of file diff --git a/src/main/java/mos/mosback/service/PostService.java b/src/main/java/mos/mosback/service/PostService.java index 28cf07d..e5873ac 100644 --- a/src/main/java/mos/mosback/service/PostService.java +++ b/src/main/java/mos/mosback/service/PostService.java @@ -86,4 +86,12 @@ public List findPopularPosts() { .map(PostsListResponseDto::new) .collect(Collectors.toList()); } + + @Transactional(readOnly = true) + public List findGroupRecruitmentPeriod() { + List RecruitmentPeriod = postsRepository.findGroupInRecruitmentPeriod(); + return RecruitmentPeriod.stream() + .map(PostsListResponseDto::new) + .collect(Collectors.toList()); + } //모집기간인 스터디 조회 } diff --git a/src/main/java/mos/mosback/web/dto/PostSaveRequestDto.java b/src/main/java/mos/mosback/web/dto/PostSaveRequestDto.java index 167e32c..f683b87 100644 --- a/src/main/java/mos/mosback/web/dto/PostSaveRequestDto.java +++ b/src/main/java/mos/mosback/web/dto/PostSaveRequestDto.java @@ -21,11 +21,9 @@ public class PostSaveRequestDto { private String intro; //스터디 소개 private int num; //멤버수 private String mod; //스터디 분위기 - private int click;// 클릭횟수 (인기순 조회) private boolean onOff; //진행방식 (온오프) private Date startDate; //스터디 시작 날짜 private Date endDate; //스터디 끝나는 날짜 - private Date createDate; // 스터디룸 생성 날짜 private Date rcstart; // 모집 시작 날짜 private Date rcend; //모집 마감 날짜 diff --git a/src/main/java/mos/mosback/web/dto/PostsListResponseDto.java b/src/main/java/mos/mosback/web/dto/PostsListResponseDto.java index e756f53..3b94d8b 100644 --- a/src/main/java/mos/mosback/web/dto/PostsListResponseDto.java +++ b/src/main/java/mos/mosback/web/dto/PostsListResponseDto.java @@ -11,7 +11,6 @@ public class PostsListResponseDto { private String title; private String goal; //스터디 목표 private String rules; //스터디 규칙 - private String quest; //생성 시 질문 private String tend; //유저 스터디 성향 private String category; // 스터디 카테고리 private String date; //스터디 요일 @@ -32,14 +31,12 @@ public PostsListResponseDto(Posts entity) { this.title = entity.getTitle(); this.goal = entity.getGoal(); this.rules = entity.getRules(); - this.quest =entity.getQuest(); this.tend =entity.getTend(); this.category =entity.getCategory(); this.date =entity.getDate(); this.intro =entity.getIntro(); this.num = entity.getNum(); this.mod = entity.getMod(); - this.click = entity.getClick(); this.onOff = entity.isOnOff(); this.startDate = entity.getStartDate(); this.endDate = entity.getEndDate(); diff --git a/src/main/java/mos/mosback/web/dto/PostsResponseDto.java b/src/main/java/mos/mosback/web/dto/PostsResponseDto.java index 9f7f8cd..0ec731e 100644 --- a/src/main/java/mos/mosback/web/dto/PostsResponseDto.java +++ b/src/main/java/mos/mosback/web/dto/PostsResponseDto.java @@ -19,11 +19,9 @@ public class PostsResponseDto { private String intro; //스터디 소개 private int num; //멤버수 private String mod; //스터디 분위기 - private int click;// 클릭횟수 (인기순 조회) private boolean onOff; //진행방식 (온오프) private Date startDate; //스터디 시작 날짜 private Date endDate; //스터디 끝나는 날짜 - private Date createDate; // 스터디룸 생성 날짜 private Date rcstart; // 모집 시작 날짜 private Date rcend; //모집 마감 날짜 public PostsResponseDto(Posts entity) { @@ -38,13 +36,13 @@ public PostsResponseDto(Posts entity) { this.intro =entity.getIntro(); this.num = entity.getNum(); this.mod = entity.getMod(); - this.click = entity.getClick(); this.onOff = entity.isOnOff(); this.startDate = entity.getStartDate(); this.endDate = entity.getEndDate(); this.rcstart =entity.getRcstart(); - this.rcend =entity.getRcend();; + this.rcend =entity.getRcend(); } } -//Entity의 필드 이루만 사용하므로 생성자로 Entity를 받아 필드에 값을 넣어줌 \ No newline at end of file +//Entity의 필드 이루만 사용하므로 생성자로 Entity를 받아 필드에 값을 넣어줌 +//상세정보에 노출 될 필드 \ No newline at end of file diff --git a/src/main/java/mos/mosback/web/dto/PostsUpdateRequestDto.java b/src/main/java/mos/mosback/web/dto/PostsUpdateRequestDto.java index 8ddcec1..ace5aab 100644 --- a/src/main/java/mos/mosback/web/dto/PostsUpdateRequestDto.java +++ b/src/main/java/mos/mosback/web/dto/PostsUpdateRequestDto.java @@ -21,11 +21,9 @@ public class PostsUpdateRequestDto { private String intro; //스터디 소개 private int num; //멤버수 private String mod; //스터디 분위기 - private int click;// 클릭횟수 (인기순 조회) private boolean onOff; //진행방식 (온오프) private Date startDate; //스터디 시작 날짜 private Date endDate; //스터디 끝나는 날짜 - private Date createDate; // 스터디룸 생성 날짜 private Date rcstart; // 모집 시작 날짜 private Date rcend; //모집 마감 날짜 From 6908157789805a7f64342be79f6455b87364036f Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Wed, 6 Sep 2023 03:01:54 +0900 Subject: [PATCH 04/60] =?UTF-8?q?=EC=98=A4=EB=A5=98=EC=88=98=EC=A0=95,=20?= =?UTF-8?q?=EC=8A=A4=ED=84=B0=EB=94=94=20=EC=9A=94=EC=9D=BC=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20(=20=EB=8B=A4=EC=A4=91=EC=84=A0=ED=83=9D=20?= =?UTF-8?q?=EA=B0=80=EB=8A=A5=20)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/mos/mosback/domain/posts/Posts.java | 37 +++++++------------ .../mos/mosback/domain/posts/StudyDays.java | 5 +++ .../java/mos/mosback/service/PostService.java | 8 ++-- .../mosback/web/dto/PostSaveRequestDto.java | 16 ++++---- .../mosback/web/dto/PostsListResponseDto.java | 10 ++--- .../mos/mosback/web/dto/PostsResponseDto.java | 10 ++--- .../web/dto/PostsUpdateRequestDto.java | 14 +++---- src/main/resources/application.properties | 2 +- 8 files changed, 46 insertions(+), 56 deletions(-) create mode 100644 src/main/java/mos/mosback/domain/posts/StudyDays.java diff --git a/src/main/java/mos/mosback/domain/posts/Posts.java b/src/main/java/mos/mosback/domain/posts/Posts.java index f70dbc2..ef3e583 100644 --- a/src/main/java/mos/mosback/domain/posts/Posts.java +++ b/src/main/java/mos/mosback/domain/posts/Posts.java @@ -2,14 +2,9 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; - - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import javax.persistence.*; import java.util.Date; +import java.util.Set; @Getter // 롬복 어노테이션 @NoArgsConstructor // 롬복 어노테이션 (필수는 아님 그냥 코드 단순화용) @@ -24,40 +19,35 @@ public class Posts extends BaseTimeEntity { @Column(length = 500, nullable = false) private String title; - @Column(columnDefinition = "TEXT", nullable = false) + @Column(nullable = false) private String goal; //스터디 목표 private String rules; //스터디 규칙 private String quest; //생성 시 질문 - private String tend; //유저 스터디 성향 private String category; // 스터디 카테고리 - private String date; //스터디 요일 private String intro; //스터디 소개 - - private int num; //멤버수 private String mod; //스터디 분위기 private int click;// 클릭횟수 (인기순 조회) - - private boolean onOff; //진행방식 (온오프) - - private Date startDate; //스터디 시작 날짜 private Date endDate; //스터디 끝나는 날짜 - private Date createDate; // 스터디룸 생성 날짜 private Date rcstart; // 모집 시작 날짜 private Date rcend; //모집 마감 날짜 + + @ElementCollection + @Enumerated(EnumType.STRING) // 열거형 값의 매핑 타입을 지정 + private Set studyDays; + @Builder //해당 클래스의 빌더 클래스 생성. 생성자 상단에 선언 시 생성자에 포함된 필드만 빌더에 포함 - public Posts(String title, String goal, String rules, String quest, String tend, + public Posts(String title, String goal, String rules, String quest,Set studyDays, String category, String date, String intro, int num, String mod, boolean onOff, Date startDate, Date endDate, Date rcstart, Date rcend) { this.title = title; this.goal = goal; this.rules = rules; this.quest = quest; - this.tend = tend; + this.studyDays = studyDays; this.category = category; - this.date = date; this.intro = intro; this.mod = mod; this.num = num; @@ -67,16 +57,15 @@ public Posts(String title, String goal, String rules, String quest, String tend, this.rcstart = rcstart; this.rcend = rcend; } - public void update(String title, String goal, String rules, String quest, String tend, - String category, String date, String intro, int num, String mod, + public void update(String title, String goal, String rules, String quest, Set studyDays, + String category, String intro, int num, String mod, boolean onOff, Date startDate, Date endDate, Date rcstart, Date rcend) { this.title = title; this.goal = goal; this.rules = rules; this.quest = quest; - this.tend = tend; + this.studyDays = studyDays; this.category = category; - this.date = date; this.intro = intro; this.mod = mod; this.num = num; diff --git a/src/main/java/mos/mosback/domain/posts/StudyDays.java b/src/main/java/mos/mosback/domain/posts/StudyDays.java new file mode 100644 index 0000000..0070149 --- /dev/null +++ b/src/main/java/mos/mosback/domain/posts/StudyDays.java @@ -0,0 +1,5 @@ +package mos.mosback.domain.posts; + +public enum StudyDays { + MON, TUE, WED, THU, FRI, SAT, SUN +} diff --git a/src/main/java/mos/mosback/service/PostService.java b/src/main/java/mos/mosback/service/PostService.java index e5873ac..996a28e 100644 --- a/src/main/java/mos/mosback/service/PostService.java +++ b/src/main/java/mos/mosback/service/PostService.java @@ -31,10 +31,10 @@ public void update(Long groupID, PostsUpdateRequestDto requestDto) { .orElseThrow(() -> new IllegalArgumentException(groupID + " NOT FOUND")); posts.update(requestDto.getTitle(), requestDto.getGoal(), requestDto.getRules(), - requestDto.getQuest(), requestDto.getTend(), requestDto.getCategory(), - requestDto.getDate(), requestDto.getIntro(), requestDto.getNum(), - requestDto.getMod(), requestDto.isOnOff(), requestDto.getStartDate(), - requestDto.getEndDate(), requestDto.getRcstart(), requestDto.getRcend()); + requestDto.getQuest(),requestDto.getStudyDays(), requestDto.getCategory(), + requestDto.getIntro(), requestDto.getNum(),requestDto.getMod(), + requestDto.isOnOff(),requestDto.getStartDate(),requestDto.getEndDate(), + requestDto.getRcstart(),requestDto.getRcend()); } //postsRepository를 사용하여 데이터베이스에서 주어진 id에 해당하는 게시물을 찾기 diff --git a/src/main/java/mos/mosback/web/dto/PostSaveRequestDto.java b/src/main/java/mos/mosback/web/dto/PostSaveRequestDto.java index f683b87..3a2b3c6 100644 --- a/src/main/java/mos/mosback/web/dto/PostSaveRequestDto.java +++ b/src/main/java/mos/mosback/web/dto/PostSaveRequestDto.java @@ -3,6 +3,8 @@ import lombok.Getter; import lombok.NoArgsConstructor; import mos.mosback.domain.posts.Posts; +import mos.mosback.domain.posts.StudyDays; +import java.util.Set; import javax.persistence.Column; import java.util.Date; @@ -15,9 +17,8 @@ public class PostSaveRequestDto { private String goal; //스터디 목표 private String rules; //스터디 규칙 private String quest; //생성 시 질문 - private String tend; //유저 스터디 성향 + private Set studyDays; private String category; // 스터디 카테고리 - private String date; //스터디 요일 private String intro; //스터디 소개 private int num; //멤버수 private String mod; //스터디 분위기 @@ -30,16 +31,15 @@ public class PostSaveRequestDto { @Builder - public PostSaveRequestDto(String title, String goal, String rules, String quest, String tend, - String category, String date, String intro, int num, String mod, + public PostSaveRequestDto(String title, String goal, String rules, String quest,Set studyDays, + String category, String intro, int num, String mod, boolean onOff, Date startDate, Date endDate, Date rcstart, Date rcend) { this.title = title; this.goal = goal; this.rules = rules; this.quest = quest; - this.tend = tend; + this.studyDays = studyDays; this.category = category; - this.date = date; this.intro = intro; this.mod = mod; this.num = num; @@ -56,13 +56,11 @@ public Posts toEntity() { .goal(goal) .rules(rules) .quest(quest) - .tend(tend) + .studyDays(studyDays) .category(category) - .date(date) .intro(intro) .mod(mod) .num(num) - .date(date) .intro(intro) .mod(mod) .num(num) diff --git a/src/main/java/mos/mosback/web/dto/PostsListResponseDto.java b/src/main/java/mos/mosback/web/dto/PostsListResponseDto.java index 3b94d8b..e2226cf 100644 --- a/src/main/java/mos/mosback/web/dto/PostsListResponseDto.java +++ b/src/main/java/mos/mosback/web/dto/PostsListResponseDto.java @@ -1,8 +1,10 @@ package mos.mosback.web.dto; import lombok.Getter; import mos.mosback.domain.posts.Posts; - import java.util.Date; +import mos.mosback.domain.posts.StudyDays; +import java.util.Set; + @Getter @@ -11,9 +13,8 @@ public class PostsListResponseDto { private String title; private String goal; //스터디 목표 private String rules; //스터디 규칙 - private String tend; //유저 스터디 성향 private String category; // 스터디 카테고리 - private String date; //스터디 요일 + private Set studyDays; //스터디요일 private String intro; //스터디 소개 private int num; //멤버수 private String mod; //스터디 분위기 @@ -31,9 +32,8 @@ public PostsListResponseDto(Posts entity) { this.title = entity.getTitle(); this.goal = entity.getGoal(); this.rules = entity.getRules(); - this.tend =entity.getTend(); this.category =entity.getCategory(); - this.date =entity.getDate(); + this.studyDays =entity.getStudyDays(); this.intro =entity.getIntro(); this.num = entity.getNum(); this.mod = entity.getMod(); diff --git a/src/main/java/mos/mosback/web/dto/PostsResponseDto.java b/src/main/java/mos/mosback/web/dto/PostsResponseDto.java index 0ec731e..7f909e2 100644 --- a/src/main/java/mos/mosback/web/dto/PostsResponseDto.java +++ b/src/main/java/mos/mosback/web/dto/PostsResponseDto.java @@ -1,10 +1,9 @@ package mos.mosback.web.dto; - import lombok.Getter; import mos.mosback.domain.posts.Posts; - +import mos.mosback.domain.posts.StudyDays; import java.util.Date; - +import java.util.Set; @Getter public class PostsResponseDto { @@ -15,7 +14,7 @@ public class PostsResponseDto { private String quest; //생성 시 질문 private String tend; //유저 스터디 성향 private String category; // 스터디 카테고리 - private String date; //스터디 요일 + private Set studyDays; //스터디 요일 private String intro; //스터디 소개 private int num; //멤버수 private String mod; //스터디 분위기 @@ -30,9 +29,8 @@ public PostsResponseDto(Posts entity) { this.goal = entity.getGoal(); this.rules = entity.getRules(); this.quest =entity.getQuest(); - this.tend =entity.getTend(); this.category =entity.getCategory(); - this.date =entity.getDate(); + this.studyDays =entity.getStudyDays(); this.intro =entity.getIntro(); this.num = entity.getNum(); this.mod = entity.getMod(); diff --git a/src/main/java/mos/mosback/web/dto/PostsUpdateRequestDto.java b/src/main/java/mos/mosback/web/dto/PostsUpdateRequestDto.java index ace5aab..436569d 100644 --- a/src/main/java/mos/mosback/web/dto/PostsUpdateRequestDto.java +++ b/src/main/java/mos/mosback/web/dto/PostsUpdateRequestDto.java @@ -3,7 +3,8 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; - +import mos.mosback.domain.posts.StudyDays; +import java.util.Set; import java.util.Date; @Getter @@ -15,9 +16,8 @@ public class PostsUpdateRequestDto { private String goal; //스터디 목표 private String rules; //스터디 규칙 private String quest; //생성 시 질문 - private String tend; //유저 스터디 성향 private String category; // 스터디 카테고리 - private String date; //스터디 요일 + private Set studyDays; //스터디 요일 private String intro; //스터디 소개 private int num; //멤버수 private String mod; //스터디 분위기 @@ -28,16 +28,15 @@ public class PostsUpdateRequestDto { private Date rcend; //모집 마감 날짜 @Builder - public PostsUpdateRequestDto(String title, String goal, String rules, String quest, String tend, - String category, String date, String intro, int num, String mod, + public PostsUpdateRequestDto(String title, String goal, String rules, String quest, + String category,Set studyDays, String intro, int num, String mod, boolean onOff, Date startDate, Date endDate, Date rcstart, Date rcend){ this.title = title; this.goal = goal; this.rules = rules; this.quest = quest; - this.tend = tend; this.category = category; - this.date = date; + this.studyDays = studyDays; this.intro = intro; this.mod = mod; this.num = num; @@ -47,4 +46,5 @@ public PostsUpdateRequestDto(String title, String goal, String rules, String que this.rcstart = rcstart; this.rcend = rcend; } + } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 40edb30..90ea6cf 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -7,7 +7,7 @@ spring.h2.console.path=/h2-console spring.datasource.url=jdbc:h2:mem:testdb spring.jpa.open-in-view=false spring.mvc.servlet.load-on-startup=1 - +spring.datasource.hikari.jdbc-url=jdbc:h2:mem:testdb;MODE=MYSQL spring.profiles.include=oauth spring.session.store-type=jdbc logging.level.org.springframework.web=DEBUG From bd6339f66038dafba4f75bd22fda6fe699f688c3 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Mon, 11 Sep 2023 16:32:29 +0900 Subject: [PATCH 05/60] =?UTF-8?q?=EC=98=A4=EB=A5=98=EC=88=98=EC=A0=95,=20?= =?UTF-8?q?=EC=8A=A4=ED=84=B0=EB=94=94=20=EC=9A=94=EC=9D=BC=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20(=20=EB=8B=A4=EC=A4=91=EC=84=A0=ED=83=9D=20?= =?UTF-8?q?=EA=B0=80=EB=8A=A5=20)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mosback/controller/HomeController.java | 9 ++ .../mosback/controller/IndexController.java | 42 -------- .../mosback/controller/PostsController.java | 89 ----------------- .../mosback/controller/StRoomController.java | 88 +++++++++++++++++ .../mos/mosback/domain/posts/HomeEntity.java | 4 + .../mosback/domain/posts/PostsRepository.java | 27 ------ .../posts/{Posts.java => StRoomEntity.java} | 52 +++++----- .../mos/mosback/domain/posts/StudyDays.java | 5 - .../mosback/domain/posts/StudyDaysEntity.java | 21 ++++ .../mosback/repository/HomeRepository.java | 4 + .../mosback/repository/StRoomRepository.java | 24 +++++ .../posts => repository}/ToDoRepository.java | 5 +- .../java/mos/mosback/repository/UserInfo.java | 2 +- .../java/mos/mosback/service/HomeService.java | 4 + .../java/mos/mosback/service/PostService.java | 97 ------------------- .../mos/mosback/service/StRoomService.java | 90 +++++++++++++++++ .../java/mos/mosback/service/ToDoService.java | 55 ----------- .../mos/mosback/web/dto/HomeResponseDto.java | 4 + .../web/dto/PostsUpdateRequestDto.java | 50 ---------- .../web/dto/StRoomListResponseDto.java | 43 ++++++++ ...esponseDto.java => StRoomResponseDto.java} | 29 +++--- ...uestDto.java => StRoomSaveRequestDto.java} | 39 +++----- ...seDto.java => StRoomUpdateRequestDto.java} | 29 +++--- src/main/resources/application.properties | 23 +++-- .../mosback/domain/posts/PostsRepository.java | 4 - 25 files changed, 381 insertions(+), 458 deletions(-) create mode 100644 src/main/java/mos/mosback/controller/HomeController.java delete mode 100644 src/main/java/mos/mosback/controller/IndexController.java delete mode 100644 src/main/java/mos/mosback/controller/PostsController.java create mode 100644 src/main/java/mos/mosback/controller/StRoomController.java create mode 100644 src/main/java/mos/mosback/domain/posts/HomeEntity.java delete mode 100644 src/main/java/mos/mosback/domain/posts/PostsRepository.java rename src/main/java/mos/mosback/domain/posts/{Posts.java => StRoomEntity.java} (61%) delete mode 100644 src/main/java/mos/mosback/domain/posts/StudyDays.java create mode 100644 src/main/java/mos/mosback/domain/posts/StudyDaysEntity.java create mode 100644 src/main/java/mos/mosback/repository/HomeRepository.java create mode 100644 src/main/java/mos/mosback/repository/StRoomRepository.java rename src/main/java/mos/mosback/{domain/posts => repository}/ToDoRepository.java (58%) create mode 100644 src/main/java/mos/mosback/service/HomeService.java delete mode 100644 src/main/java/mos/mosback/service/PostService.java create mode 100644 src/main/java/mos/mosback/service/StRoomService.java delete mode 100644 src/main/java/mos/mosback/service/ToDoService.java create mode 100644 src/main/java/mos/mosback/web/dto/HomeResponseDto.java delete mode 100644 src/main/java/mos/mosback/web/dto/PostsUpdateRequestDto.java create mode 100644 src/main/java/mos/mosback/web/dto/StRoomListResponseDto.java rename src/main/java/mos/mosback/web/dto/{PostsResponseDto.java => StRoomResponseDto.java} (66%) rename src/main/java/mos/mosback/web/dto/{PostSaveRequestDto.java => StRoomSaveRequestDto.java} (58%) rename src/main/java/mos/mosback/web/dto/{PostsListResponseDto.java => StRoomUpdateRequestDto.java} (68%) diff --git a/src/main/java/mos/mosback/controller/HomeController.java b/src/main/java/mos/mosback/controller/HomeController.java new file mode 100644 index 0000000..74b48cf --- /dev/null +++ b/src/main/java/mos/mosback/controller/HomeController.java @@ -0,0 +1,9 @@ +package mos.mosback.controller; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +public class HomeController { + +} diff --git a/src/main/java/mos/mosback/controller/IndexController.java b/src/main/java/mos/mosback/controller/IndexController.java deleted file mode 100644 index 92210c0..0000000 --- a/src/main/java/mos/mosback/controller/IndexController.java +++ /dev/null @@ -1,42 +0,0 @@ -package mos.mosback.controller; -import lombok.RequiredArgsConstructor; -import mos.mosback.service.PostService; -import mos.mosback.web.dto.PostsResponseDto; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import javax.servlet.http.HttpSession; - -@RequiredArgsConstructor -@Controller //머스테치에 URL 매핑해주기 -public class IndexController { - private final PostService postService; - private final HttpSession httpSession; -// @GetMapping("/")//머스테치 스타터 덕분에 -// // 컨트롤러에서 문자열을 반환할 때 앞의 경로와 뒤의 파일 확정자는 자동으로 지정된다. -// public String index(Model model, @LoginUser SessionUser user) { -// model.addAttribute("posts", postService.findAllDesc()); -// if (user != null) { -// model.addAttribute("userName", user.getName()); -// } -// return "index"; -// } - - @GetMapping("/posts/save") - public String postsSave() { - return "posts-save"; - } - - @GetMapping("posts/update/{id}") - public String Update(@PathVariable Long groupID, - Model model){ - - PostsResponseDto dto = postService.findById(groupID); - model.addAttribute("post",dto); - - return "posts-update"; - - } - -} diff --git a/src/main/java/mos/mosback/controller/PostsController.java b/src/main/java/mos/mosback/controller/PostsController.java deleted file mode 100644 index 4a28ace..0000000 --- a/src/main/java/mos/mosback/controller/PostsController.java +++ /dev/null @@ -1,89 +0,0 @@ -package mos.mosback.controller; -import mos.mosback.web.dto.PostSaveRequestDto; -import mos.mosback.web.dto.PostsListResponseDto; -import mos.mosback.web.dto.PostsResponseDto; -import mos.mosback.web.dto.PostsUpdateRequestDto; -import mos.mosback.service.PostService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - -import java.util.List; - -@RestController -@RequestMapping("/api/studyGroup") //URL 패턴 -public class PostsController { - - private final PostService postService; // PostService를 주입. - - @Autowired - public PostsController(PostService postService) { - this.postService = postService; - } - - @PostMapping("/create") - public ResponseEntity savePost(@RequestBody PostSaveRequestDto requestDto) { - Long postId = postService.save(requestDto); - return ResponseEntity.status(HttpStatus.CREATED).body("created successfully. ID: " + postId); - } - - @GetMapping("get/{groupID}") - public ResponseEntity FindByID (@PathVariable Long groupID) { - PostsResponseDto post = postService.findById(groupID); - return new ResponseEntity<>(post, HttpStatus.OK); - } - - @GetMapping("/search") - public ResponseEntity> searchPosts(@RequestParam String keyword) { - List posts = postService.findByTitleContaining(keyword); - return new ResponseEntity<>(posts, HttpStatus.OK); - } - - @PutMapping("update/{groupID}") - public ResponseEntity updatePost(@PathVariable Long groupID, @RequestBody PostsUpdateRequestDto requestDto) { - try { - postService.update(groupID, requestDto); - return ResponseEntity.ok("updated."); - } catch (IllegalArgumentException e) { - return ResponseEntity.status(HttpStatus.NOT_FOUND) - .body("NOT FOUND"+"'"+groupID+"'"); - - } - } - - @DeleteMapping("delete/{groupID}") - public ResponseEntity deletePost(@PathVariable Long groupID) { - postService.delete(groupID); - return new ResponseEntity<>(HttpStatus.NO_CONTENT); - } - - @GetMapping("get/all") - public ResponseEntity> getAllPosts() { - List posts = postService.findAllDesc(); - return new ResponseEntity<>(posts, HttpStatus.OK); - } - - @GetMapping("get/popular") - public ResponseEntity> getPopularPosts() { - List popularPosts = postService.findPopularPosts(); - return new ResponseEntity<>(popularPosts, HttpStatus.OK); - } - - @GetMapping("/get/recruitment") - public ResponseEntity> getRecruitment(){ - List RecruitmentPeriod = postService.findGroupRecruitmentPeriod(); - return new ResponseEntity<>(RecruitmentPeriod, HttpStatus.OK); - } - -} -//핸들러 메서드 : -// -//create: 새 게시물을 생성하는 엔드포인트. -//getPost: 특정 groupID에 해당하는 게시물을 조회하는 엔드포인트.( 스터디그룹 조회 ) -//searchPosts: 키워드가 포함된 게시물을 검색하는 엔드포인트. -//updatePost: 게시물을 업데이트하는 엔드포인트. -//deletePost: 게시물을 삭제하는 엔드포인트. -//getAllPosts: 모든 게시물을 조회하는 엔드포인트. -//getPopularPosts: 조회순으로 게시물을 조회하는 엔드포인트. (인기순 조회시) -//getRecruitment : 모집기간인 게시물을 조회하는 엔드포인트. diff --git a/src/main/java/mos/mosback/controller/StRoomController.java b/src/main/java/mos/mosback/controller/StRoomController.java new file mode 100644 index 0000000..49b3afd --- /dev/null +++ b/src/main/java/mos/mosback/controller/StRoomController.java @@ -0,0 +1,88 @@ +package mos.mosback.controller; +import mos.mosback.web.dto.StRoomSaveRequestDto; +import mos.mosback.web.dto.StRoomListResponseDto; +import mos.mosback.web.dto.StRoomUpdateRequestDto; +import mos.mosback.service.StRoomService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/api/studyRoom") //URL 패턴 +public class StRoomController { + + private final StRoomService stRoomService; // stRoomService를 주입. + + @Autowired + public StRoomController(StRoomService stRoomService) { + this.stRoomService = stRoomService; + } + + @PostMapping("/create") + public ResponseEntity saveroom(@RequestBody StRoomSaveRequestDto requestDto) { + Long stroomId = stRoomService.save(requestDto); + return ResponseEntity.status(HttpStatus.CREATED).body("created successfully. ID: " + stroomId); + } + + /** + * 스터디 방 정보 가져오기 + * @param roomID + * @return + */ + @GetMapping("/get/{roomID}") + public ResponseEntity getRoom(@PathVariable Long roomID) { + StRoomUpdateRequestDto stroom = stRoomService.findById(roomID); + return new ResponseEntity<>(stroom, HttpStatus.OK); + } + + @GetMapping("/search") + public ResponseEntity> searchrooms(@RequestParam String keyword) { + List strooms = stRoomService.findByTitleContaining(keyword); + return new ResponseEntity<>(strooms, HttpStatus.OK); + } + + @PutMapping("/update/{roomID}") + public ResponseEntity updateroom(@PathVariable Long roomID, @RequestBody StRoomUpdateRequestDto requestDto) { + try { + stRoomService.update(roomID, requestDto); + return ResponseEntity.ok("updated."); + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body("NOT FOUND"+"'"+roomID+"'"); + + } + } + + @DeleteMapping("/delete/{roomID}") + public ResponseEntity deleteroom(@PathVariable Long roomID) { + stRoomService.delete(roomID); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @GetMapping("/all") + public ResponseEntity> getAllrooms() { + List strooms = stRoomService.findAllDesc(); + return new ResponseEntity<>(strooms, HttpStatus.OK); + } + + @GetMapping("/popular") + public ResponseEntity> getPopularrooms() { + List popularrooms = stRoomService.findPopularstrooms(); + return new ResponseEntity<>(popularrooms, HttpStatus.OK); + } + + +} +//핸들러 메서드 : +// +//create: 새 게시물을 생성하는 엔드포인트. +//getstroom: 특정 roomID에 해당하는 게시물을 조회하는 엔드포인트.( 스터디그룹 조회 ) +//searchstrooms: 키워드가 포함된 게시물을 검색하는 엔드포인트. +//updatestroom: 게시물을 업데이트하는 엔드포인트. +//deletestroom: 게시물을 삭제하는 엔드포인트. +//getAllstrooms: 모든 게시물을 조회하는 엔드포인트. +//getPopularstrooms: 조회순으로 게시물을 조회하는 엔드포인트. (인기순 조회시) +//getRecruitment : 모집기간인 게시물을 조회하는 엔드포인트. diff --git a/src/main/java/mos/mosback/domain/posts/HomeEntity.java b/src/main/java/mos/mosback/domain/posts/HomeEntity.java new file mode 100644 index 0000000..1e937c8 --- /dev/null +++ b/src/main/java/mos/mosback/domain/posts/HomeEntity.java @@ -0,0 +1,4 @@ +package mos.mosback.domain.posts; + +public class HomeEntity { +} diff --git a/src/main/java/mos/mosback/domain/posts/PostsRepository.java b/src/main/java/mos/mosback/domain/posts/PostsRepository.java deleted file mode 100644 index d42956f..0000000 --- a/src/main/java/mos/mosback/domain/posts/PostsRepository.java +++ /dev/null @@ -1,27 +0,0 @@ -package mos.mosback.domain.posts; - -//Entity 클래스와 Entity레파지토리 위치 같아야함 -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; - - -import java.util.List; - -//인터페이스 생성 후 JpaRepository를 상속하면 기본적인 CRUD 메소드 자동으로 생성됨 -public interface PostsRepository extends JpaRepository { - - @Query("SELECT p FROM Posts p ORDER BY p.groupID DESC") - List findAllDesc(); - - List findByTitleContaining(String keyword); //키워드를 통해 스터디그룹을 검색 할 수 있다 - - @Query(value = "SELECT * FROM posts ORDER BY click DESC", nativeQuery = true) - List findPopularPosts(); //클릭수로 인기순 나열 - - - @Query("SELECT p FROM Posts p WHERE p.rcstart <= :currentDate AND p.rcend >= :currentDate") - List findGroupInRecruitmentPeriod(); //모집중인 스터디 조회가능 - - -} -//Posts 클래스로 DB를 접근하기 위한 클래스 \ No newline at end of file diff --git a/src/main/java/mos/mosback/domain/posts/Posts.java b/src/main/java/mos/mosback/domain/posts/StRoomEntity.java similarity index 61% rename from src/main/java/mos/mosback/domain/posts/Posts.java rename to src/main/java/mos/mosback/domain/posts/StRoomEntity.java index ef3e583..6320b52 100644 --- a/src/main/java/mos/mosback/domain/posts/Posts.java +++ b/src/main/java/mos/mosback/domain/posts/StRoomEntity.java @@ -3,18 +3,17 @@ import lombok.Getter; import lombok.NoArgsConstructor; import javax.persistence.*; -import java.util.Date; -import java.util.Set; +import java.util.*; @Getter // 롬복 어노테이션 @NoArgsConstructor // 롬복 어노테이션 (필수는 아님 그냥 코드 단순화용) @Entity //JPA 어노테이션 (주요어노테이션) : 테이블과 링크될 클래스임을 나타냄 -public class Posts extends BaseTimeEntity { - //Posts 클래스 - > 실제 DB테이블과 매칭될 클래스 ( Entity 클래스 ) +public class StRoomEntity extends BaseTimeEntity { + //strooms 클래스 - > 실제 DB테이블과 매칭될 클래스 ( Entity 클래스 ) @Id //해당 테이블 PK 필드 나타냄 @GeneratedValue(strategy = GenerationType.IDENTITY) //PK 생성규칙 나타냄 스프링 2.0은 //GenerationType.IDENTITY 옵션을 추가해야만 auto_increment가 된다. - private Long groupID; + private Long roomID; //웬만하면 Entity의 Pk는 long타입의 auto_increment 쓰는게 좋음 @Column(length = 500, nullable = false) private String title; @@ -31,50 +30,51 @@ public class Posts extends BaseTimeEntity { private boolean onOff; //진행방식 (온오프) private Date startDate; //스터디 시작 날짜 private Date endDate; //스터디 끝나는 날짜 - private Date rcstart; // 모집 시작 날짜 - private Date rcend; //모집 마감 날짜 - @ElementCollection - @Enumerated(EnumType.STRING) // 열거형 값의 매핑 타입을 지정 - private Set studyDays; - @Builder //해당 클래스의 빌더 클래스 생성. 생성자 상단에 선언 시 생성자에 포함된 필드만 빌더에 포함 - public Posts(String title, String goal, String rules, String quest,Set studyDays, - String category, String date, String intro, int num, String mod, - boolean onOff, Date startDate, Date endDate, Date rcstart, Date rcend) { + @OneToMany(fetch = FetchType.EAGER) + @JoinColumn(name = "ST_ROOM_ROOMID") + private List studyDayEntities = new ArrayList<>(); + + @Builder + public StRoomEntity(String title, String goal, String rules, String quest, + String category, String intro, int num, String mod, + boolean onOff, Date startDate, Date endDate, List studyDayEntities) { + this.title = title; this.goal = goal; this.rules = rules; this.quest = quest; - this.studyDays = studyDays; this.category = category; this.intro = intro; - this.mod = mod; this.num = num; + this.mod = mod; this.onOff = onOff; this.startDate = startDate; this.endDate = endDate; - this.rcstart = rcstart; - this.rcend = rcend; + this.studyDayEntities = studyDayEntities; } - public void update(String title, String goal, String rules, String quest, Set studyDays, - String category, String intro, int num, String mod, - boolean onOff, Date startDate, Date endDate, Date rcstart, Date rcend) { + + + // 다른 필요한 Getter 및 Setter 메서드 + + public void update(String title, String goal, String rules, String quest, + String category, String intro, + int num, String mod, boolean onOff, Date startDate, + Date endDate,List studyDayEntities) { this.title = title; this.goal = goal; this.rules = rules; this.quest = quest; - this.studyDays = studyDays; this.category = category; this.intro = intro; - this.mod = mod; this.num = num; + this.mod = mod; this.onOff = onOff; this.startDate = startDate; this.endDate = endDate; - this.rcstart = rcstart; - this.rcend = rcend; + this.studyDayEntities = studyDayEntities; } +} -} \ No newline at end of file diff --git a/src/main/java/mos/mosback/domain/posts/StudyDays.java b/src/main/java/mos/mosback/domain/posts/StudyDays.java deleted file mode 100644 index 0070149..0000000 --- a/src/main/java/mos/mosback/domain/posts/StudyDays.java +++ /dev/null @@ -1,5 +0,0 @@ -package mos.mosback.domain.posts; - -public enum StudyDays { - MON, TUE, WED, THU, FRI, SAT, SUN -} diff --git a/src/main/java/mos/mosback/domain/posts/StudyDaysEntity.java b/src/main/java/mos/mosback/domain/posts/StudyDaysEntity.java new file mode 100644 index 0000000..6da06cf --- /dev/null +++ b/src/main/java/mos/mosback/domain/posts/StudyDaysEntity.java @@ -0,0 +1,21 @@ +package mos.mosback.domain.posts; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import java.io.Serializable; + +@Getter // 롬복 어노테이션 +@NoArgsConstructor // 롬복 어노테이션 (필수는 아님 그냥 코드 단순화용) +@Entity //JPA 어노테이션 (주요어노테이션) : 테이블과 링크될 클래스임을 나타냄 +public class StudyDaysEntity implements Serializable { + + @Id //해당 테이블 PK 필드 나타냄 + @Column(name="ST_ROOM_ROOMID") + private Long stroomid; + + @Id + @Column(name="STUDY_DAYS") + private String studyDays; +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/repository/HomeRepository.java b/src/main/java/mos/mosback/repository/HomeRepository.java new file mode 100644 index 0000000..7e8f95c --- /dev/null +++ b/src/main/java/mos/mosback/repository/HomeRepository.java @@ -0,0 +1,4 @@ +package mos.mosback.repository; + +public class HomeRepository { +} diff --git a/src/main/java/mos/mosback/repository/StRoomRepository.java b/src/main/java/mos/mosback/repository/StRoomRepository.java new file mode 100644 index 0000000..3e1552a --- /dev/null +++ b/src/main/java/mos/mosback/repository/StRoomRepository.java @@ -0,0 +1,24 @@ +package mos.mosback.repository; + +//Entity 클래스와 Entity레파지토리 위치 같아야함 +import mos.mosback.domain.posts.StRoomEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + + +import java.util.List; + +//인터페이스 생성 후 JpaRepository를 상속하면 기본적인 CRUD 메소드 자동으로 생성됨 +public interface StRoomRepository extends JpaRepository { + + @Query("SELECT s FROM StRoomEntity s ORDER BY s.roomID DESC") + List findAllDesc(); + + List findByTitleContaining(String keyword); //키워드를 통해 스터디그룹을 검색 할 수 있다 + + @Query(value = "SELECT * FROM stroomEntity ORDER BY click DESC", nativeQuery = true) + List findPopularstrooms(); //클릭수로 인기순 나열 + + +} +//strooms 클래스로 DB를 접근하기 위한 클래스 \ No newline at end of file diff --git a/src/main/java/mos/mosback/domain/posts/ToDoRepository.java b/src/main/java/mos/mosback/repository/ToDoRepository.java similarity index 58% rename from src/main/java/mos/mosback/domain/posts/ToDoRepository.java rename to src/main/java/mos/mosback/repository/ToDoRepository.java index 3ef9dc8..1b6c2c5 100644 --- a/src/main/java/mos/mosback/domain/posts/ToDoRepository.java +++ b/src/main/java/mos/mosback/repository/ToDoRepository.java @@ -1,4 +1,5 @@ -package mos.mosback.domain.posts; +package mos.mosback.repository; +import mos.mosback.domain.posts.ToDoEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; @@ -6,7 +7,7 @@ public interface ToDoRepository extends JpaRepository { @Query("SELECT t FROM ToDoEntity t ORDER BY t.TodoId DESC") - List findAllDesc(); //Todo리스트를 조회시 todoID를 기준으로 내림차순 정렬 + List findAllDesc(); //Todo리스트를 조회시 todoID를 기준으로 내림차순 정렬 // } diff --git a/src/main/java/mos/mosback/repository/UserInfo.java b/src/main/java/mos/mosback/repository/UserInfo.java index f8c8b97..8fbea47 100644 --- a/src/main/java/mos/mosback/repository/UserInfo.java +++ b/src/main/java/mos/mosback/repository/UserInfo.java @@ -19,7 +19,7 @@ public Long getId() { return id; } - public void setId(Long groupID) { + public void setId(Long roomID) { this.id = id; } diff --git a/src/main/java/mos/mosback/service/HomeService.java b/src/main/java/mos/mosback/service/HomeService.java new file mode 100644 index 0000000..8f910a0 --- /dev/null +++ b/src/main/java/mos/mosback/service/HomeService.java @@ -0,0 +1,4 @@ +package mos.mosback.service; + +public class HomeService { +} diff --git a/src/main/java/mos/mosback/service/PostService.java b/src/main/java/mos/mosback/service/PostService.java deleted file mode 100644 index 996a28e..0000000 --- a/src/main/java/mos/mosback/service/PostService.java +++ /dev/null @@ -1,97 +0,0 @@ -package mos.mosback.service; -import lombok.RequiredArgsConstructor; -import mos.mosback.domain.posts.Posts; -import mos.mosback.domain.posts.PostsRepository; -import mos.mosback.web.dto.PostSaveRequestDto; -import mos.mosback.web.dto.PostsListResponseDto; -import mos.mosback.web.dto.PostsResponseDto; -import mos.mosback.web.dto.PostsUpdateRequestDto; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import java.util.List; -import java.util.stream.Collectors; - - -@RequiredArgsConstructor -@Service -public class PostService { - private final PostsRepository postsRepository; - - @Transactional - public Long save(PostSaveRequestDto requestDto){ - return postsRepository.save(requestDto.toEntity()).getGroupID(); - } - //스터디를 생성하고 아이디를 반환. - - @Transactional - public void update(Long groupID, PostsUpdateRequestDto requestDto) { - Posts posts = postsRepository.findById(groupID) - .orElseThrow(() -> new IllegalArgumentException(groupID + " NOT FOUND")); - - posts.update(requestDto.getTitle(), requestDto.getGoal(), requestDto.getRules(), - requestDto.getQuest(),requestDto.getStudyDays(), requestDto.getCategory(), - requestDto.getIntro(), requestDto.getNum(),requestDto.getMod(), - requestDto.isOnOff(),requestDto.getStartDate(),requestDto.getEndDate(), - requestDto.getRcstart(),requestDto.getRcend()); - } //postsRepository를 사용하여 데이터베이스에서 주어진 id에 해당하는 게시물을 찾기 - - - @Transactional(readOnly = true) - public PostsResponseDto findById(Long groupID) { - Posts entity = postsRepository.findById(groupID) - .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id=" + groupID)); - - return new PostsResponseDto(entity); - } - - @Transactional(readOnly = true) - public List findAllDesc() { - return postsRepository.findAllDesc().stream() - .map(PostsListResponseDto::new) //.map(post->new PostResponse(posts))랑 같음 - // postsRepository 결과로 넘어온 Posts의 Stream을 - // map을 통해 PostsListResponseDto변환 ->List로 반환하는 메소드 - - .collect(Collectors.toList()); - } - - @Transactional - public void delete (Long groupID){ - Posts posts = postsRepository.findById(groupID) - .orElseThrow(()-> new IllegalArgumentException("해당 게시물이 없습니다. id =" + groupID)); - - postsRepository.delete(posts); //JpaRepository 에서 이미 delete 메소드를 지원하고 있으므로 활용 - //엔티티를 파라미터로 살제할 수도 있고, deleteById 메서드를 이용하면 id로 삭제할 수 있음 - // 존재하는 Posts인지 확인을 위해 엔티티 조회 후 그대로 삭제함 - // --> 서비스에서 delete 메서드를 만들면 컨트롤러가 사용하도록 컨트롤러에 코드 추가하기. - } - @Transactional(readOnly = true) - public List findByTitleContaining(String keyword) { - List posts = postsRepository.findByTitleContaining(keyword); - if (posts.isEmpty()) { - throw new IllegalArgumentException("해당 스터디가 없습니다."); - } - return posts.stream() - .map(PostsListResponseDto::new) - .collect(Collectors.toList()); - } //스터디 title 로 검색 - - - @Transactional(readOnly = true) - public List findPopularPosts() { - // 클릭된 조회수 순으로 게시물을 조회하는 비즈니스 로직을 호출 - List popularPosts = postsRepository.findPopularPosts(); - return popularPosts.stream() - .map(PostsListResponseDto::new) - .collect(Collectors.toList()); - } - - @Transactional(readOnly = true) - public List findGroupRecruitmentPeriod() { - List RecruitmentPeriod = postsRepository.findGroupInRecruitmentPeriod(); - return RecruitmentPeriod.stream() - .map(PostsListResponseDto::new) - .collect(Collectors.toList()); - } //모집기간인 스터디 조회 -} diff --git a/src/main/java/mos/mosback/service/StRoomService.java b/src/main/java/mos/mosback/service/StRoomService.java new file mode 100644 index 0000000..ce8422f --- /dev/null +++ b/src/main/java/mos/mosback/service/StRoomService.java @@ -0,0 +1,90 @@ +package mos.mosback.service; +import lombok.RequiredArgsConstructor; +import mos.mosback.domain.posts.StRoomEntity; +import mos.mosback.repository.StRoomRepository; +import mos.mosback.web.dto.StRoomSaveRequestDto; +import mos.mosback.web.dto.StRoomListResponseDto; +import mos.mosback.web.dto.StRoomUpdateRequestDto; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.List; +import java.util.stream.Collectors; + + +@RequiredArgsConstructor +@Service +public class StRoomService { + private final StRoomRepository stRoomRepository; + + @Transactional + public Long save(StRoomSaveRequestDto requestDto){ + return stRoomRepository.save(requestDto.toEntity()).getRoomID(); + } + //스터디를 생성하고 아이디를 반환. + + @Transactional + public void update(Long roomID, StRoomUpdateRequestDto requestDto) { + StRoomEntity stroomEntity = stRoomRepository.findById(roomID) + .orElseThrow(() -> new IllegalArgumentException(roomID + " NOT FOUND")); + + // 나머지 필드 업데이트 + stroomEntity.update(requestDto.getTitle(), requestDto.getGoal(), requestDto.getRules(), + requestDto.getQuest(),requestDto.getCategory(), + requestDto.getIntro(), requestDto.getNum(), requestDto.getMod(), + requestDto.isOnOff(), requestDto.getStartDate(), requestDto.getEndDate() + ,requestDto.getStudyDayEntities()); + + } //stroomsRepository를 사용하여 데이터베이스에서 주어진 id에 해당하는 게시물을 찾기 + + + @Transactional(readOnly = true) + public StRoomUpdateRequestDto findById(Long roomID) { + StRoomEntity entity = stRoomRepository.findById(roomID) + .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id=" + roomID)); + + return new StRoomUpdateRequestDto(entity); + } + + @Transactional(readOnly = true) + public List findAllDesc() { + return stRoomRepository.findAllDesc().stream() + .map(StRoomListResponseDto::new) //.map(stroom->new stroomResponse(strooms))랑 같음 + // stroomsRepository 결과로 넘어온 strooms의 Stream을 + // map을 통해 stroomsListResponseDto변환 ->List로 반환하는 메소드 + + .collect(Collectors.toList()); + } + + @Transactional + public void delete (Long roomID){ + StRoomEntity stroomEntity = stRoomRepository.findById(roomID) + .orElseThrow(()-> new IllegalArgumentException("해당 게시물이 없습니다. id =" + roomID)); + + stRoomRepository.delete(stroomEntity); //JpaRepository 에서 이미 delete 메소드를 지원하고 있으므로 활용 + //엔티티를 파라미터로 살제할 수도 있고, deleteById 메서드를 이용하면 id로 삭제할 수 있음 + // 존재하는 strooms인지 확인을 위해 엔티티 조회 후 그대로 삭제함 + // --> 서비스에서 delete 메서드를 만들면 컨트롤러가 사용하도록 컨트롤러에 코드 추가하기. + } + @Transactional(readOnly = true) + public List findByTitleContaining(String keyword) { + List strooms = stRoomRepository.findByTitleContaining(keyword); + if (strooms.isEmpty()) { + throw new IllegalArgumentException("해당 스터디가 없습니다."); + } + return strooms.stream() + .map(StRoomListResponseDto::new) + .collect(Collectors.toList()); + } //스터디 title 로 검색 + + + @Transactional(readOnly = true) + public List findPopularstrooms() { + // 클릭된 조회수 순으로 게시물을 조회하는 비즈니스 로직을 호출 + List popularStrooms = stRoomRepository.findPopularstrooms(); + return popularStrooms.stream() + .map(StRoomListResponseDto::new) + .collect(Collectors.toList()); + } + + +} diff --git a/src/main/java/mos/mosback/service/ToDoService.java b/src/main/java/mos/mosback/service/ToDoService.java deleted file mode 100644 index 3c70209..0000000 --- a/src/main/java/mos/mosback/service/ToDoService.java +++ /dev/null @@ -1,55 +0,0 @@ -package mos.mosback.service; -import lombok.RequiredArgsConstructor; -import mos.mosback.domain.posts.ToDoEntity; -import mos.mosback.domain.posts.ToDoRepository; -import mos.mosback.web.dto.ToDoRequestDto; -import mos.mosback.web.dto.ToDoResponseDto; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.stream.Collectors; - -@RequiredArgsConstructor -@Service -public class ToDoService { - private final ToDoRepository toDoRepository; - - @Transactional - public void addToDo(String todoContent, boolean completed){ - ToDoEntity toDoEntity = ToDoEntity.builder() - .todoContent(todoContent) - .completed(completed) - .build(); - } - //TodoList 추가 - - @Transactional(readOnly = true) - public List findAllDesc() { - return toDoRepository.findAllDesc().stream() - .map(ToDoResponseDto::new) - .collect(Collectors.toList()); - } - //TodoList 조회 - - @Transactional - public void updateToDo(Long TodoId, String todoContent, boolean completed) { - ToDoEntity toDoEntity = toDoRepository.findById(TodoId) - .orElseThrow(() -> new IllegalArgumentException(TodoId + " NOT FOUND")); - - toDoEntity.updateToDo(todoContent, completed); - } - //수정 기능 - - @Transactional - public void delete (Long TodoId){ - ToDoEntity toDoEntity = toDoRepository.findById(TodoId) - .orElseThrow(()-> new IllegalArgumentException("해당 게시물이 없습니다. id =" + TodoId)); - - toDoRepository.delete(toDoEntity); - //엔티티를 파라미터로 삭제할 수도 있고, deleteById 메서드를 이용하면 id로 삭제할 수 있음 - //엔티티 조회 후 그대로 삭제 - //삭제 기능 - } - -} diff --git a/src/main/java/mos/mosback/web/dto/HomeResponseDto.java b/src/main/java/mos/mosback/web/dto/HomeResponseDto.java new file mode 100644 index 0000000..865a857 --- /dev/null +++ b/src/main/java/mos/mosback/web/dto/HomeResponseDto.java @@ -0,0 +1,4 @@ +package mos.mosback.web.dto; + +public class HomeResponseDto { +} diff --git a/src/main/java/mos/mosback/web/dto/PostsUpdateRequestDto.java b/src/main/java/mos/mosback/web/dto/PostsUpdateRequestDto.java deleted file mode 100644 index 436569d..0000000 --- a/src/main/java/mos/mosback/web/dto/PostsUpdateRequestDto.java +++ /dev/null @@ -1,50 +0,0 @@ -package mos.mosback.web.dto; - -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import mos.mosback.domain.posts.StudyDays; -import java.util.Set; -import java.util.Date; - -@Getter -@NoArgsConstructor -public class PostsUpdateRequestDto { - - Long groupID; - private String title; - private String goal; //스터디 목표 - private String rules; //스터디 규칙 - private String quest; //생성 시 질문 - private String category; // 스터디 카테고리 - private Set studyDays; //스터디 요일 - private String intro; //스터디 소개 - private int num; //멤버수 - private String mod; //스터디 분위기 - private boolean onOff; //진행방식 (온오프) - private Date startDate; //스터디 시작 날짜 - private Date endDate; //스터디 끝나는 날짜 - private Date rcstart; // 모집 시작 날짜 - private Date rcend; //모집 마감 날짜 - - @Builder - public PostsUpdateRequestDto(String title, String goal, String rules, String quest, - String category,Set studyDays, String intro, int num, String mod, - boolean onOff, Date startDate, Date endDate, Date rcstart, Date rcend){ - this.title = title; - this.goal = goal; - this.rules = rules; - this.quest = quest; - this.category = category; - this.studyDays = studyDays; - this.intro = intro; - this.mod = mod; - this.num = num; - this.onOff = onOff; - this.startDate = startDate; - this.endDate = endDate; - this.rcstart = rcstart; - this.rcend = rcend; - } - -} diff --git a/src/main/java/mos/mosback/web/dto/StRoomListResponseDto.java b/src/main/java/mos/mosback/web/dto/StRoomListResponseDto.java new file mode 100644 index 0000000..f834ada --- /dev/null +++ b/src/main/java/mos/mosback/web/dto/StRoomListResponseDto.java @@ -0,0 +1,43 @@ +package mos.mosback.web.dto; +import lombok.Getter; +import mos.mosback.domain.posts.StRoomEntity; +import mos.mosback.domain.posts.StudyDaysEntity; + +import java.util.Date; +import java.util.List; + + +@Getter +public class StRoomListResponseDto { + private Long roomID; + private String title; + private String goal; //스터디 목표 + private String rules; //스터디 규칙 + private String quest; + private String category; // 스터디 카테고리 + private String intro; //스터디 소개 + private int num; //멤버수 + private String mod; //스터디 분위기 + private int click;// 클릭횟수 (인기순 조회) + private boolean onOff; //진행방식 (온오프) + private Date startDate; //스터디 시작 날짜 + private Date endDate; //스터디 끝나는 날짜 + private Date createDate; // 스터디룸 생성 날짜 + private List studyDayEntities; + + public StRoomListResponseDto(StRoomEntity entity) { + this.roomID = entity.getRoomID(); + this.title = entity.getTitle(); + this.goal = entity.getGoal(); + this.rules = entity.getRules(); + this.quest =entity.getQuest(); + this.category =entity.getCategory(); + this.intro =entity.getIntro(); + this.num = entity.getNum(); + this.mod = entity.getMod(); + this.onOff = entity.isOnOff(); + this.startDate = entity.getStartDate(); + this.endDate = entity.getEndDate(); + this.studyDayEntities = entity.getStudyDayEntities(); + } +} diff --git a/src/main/java/mos/mosback/web/dto/PostsResponseDto.java b/src/main/java/mos/mosback/web/dto/StRoomResponseDto.java similarity index 66% rename from src/main/java/mos/mosback/web/dto/PostsResponseDto.java rename to src/main/java/mos/mosback/web/dto/StRoomResponseDto.java index 7f909e2..e900730 100644 --- a/src/main/java/mos/mosback/web/dto/PostsResponseDto.java +++ b/src/main/java/mos/mosback/web/dto/StRoomResponseDto.java @@ -1,44 +1,47 @@ package mos.mosback.web.dto; import lombok.Getter; -import mos.mosback.domain.posts.Posts; -import mos.mosback.domain.posts.StudyDays; +import mos.mosback.domain.posts.StRoomEntity; +import mos.mosback.domain.posts.StudyDaysEntity; + import java.util.Date; -import java.util.Set; +import java.util.List; + @Getter -public class PostsResponseDto { +public class StRoomResponseDto { + Long roomID; private String title; private String goal; //스터디 목표 private String rules; //스터디 규칙 - private String quest; //생성 시 질문 - private String tend; //유저 스터디 성향 + private String quest; private String category; // 스터디 카테고리 - private Set studyDays; //스터디 요일 private String intro; //스터디 소개 private int num; //멤버수 private String mod; //스터디 분위기 + private int click;// 클릭횟수 (인기순 조회) private boolean onOff; //진행방식 (온오프) private Date startDate; //스터디 시작 날짜 private Date endDate; //스터디 끝나는 날짜 - private Date rcstart; // 모집 시작 날짜 - private Date rcend; //모집 마감 날짜 - public PostsResponseDto(Posts entity) { + private Date createDate; // 스터디룸 생성 날짜 + private List studyDayEntities; + + + public StRoomResponseDto(StRoomEntity entity) { this.title = entity.getTitle(); this.goal = entity.getGoal(); this.rules = entity.getRules(); this.quest =entity.getQuest(); this.category =entity.getCategory(); - this.studyDays =entity.getStudyDays(); this.intro =entity.getIntro(); this.num = entity.getNum(); this.mod = entity.getMod(); this.onOff = entity.isOnOff(); this.startDate = entity.getStartDate(); this.endDate = entity.getEndDate(); - this.rcstart =entity.getRcstart(); - this.rcend =entity.getRcend(); + this.studyDayEntities =entity.getStudyDayEntities(); + } } diff --git a/src/main/java/mos/mosback/web/dto/PostSaveRequestDto.java b/src/main/java/mos/mosback/web/dto/StRoomSaveRequestDto.java similarity index 58% rename from src/main/java/mos/mosback/web/dto/PostSaveRequestDto.java rename to src/main/java/mos/mosback/web/dto/StRoomSaveRequestDto.java index 3a2b3c6..bf4396e 100644 --- a/src/main/java/mos/mosback/web/dto/PostSaveRequestDto.java +++ b/src/main/java/mos/mosback/web/dto/StRoomSaveRequestDto.java @@ -2,22 +2,19 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import mos.mosback.domain.posts.Posts; -import mos.mosback.domain.posts.StudyDays; -import java.util.Set; - -import javax.persistence.Column; +import mos.mosback.domain.posts.StRoomEntity; +import mos.mosback.domain.posts.StudyDaysEntity; import java.util.Date; +import java.util.List; @Getter @NoArgsConstructor -public class PostSaveRequestDto { - Long groupID; +public class StRoomSaveRequestDto { + Long roomID; private String title; private String goal; //스터디 목표 private String rules; //스터디 규칙 private String quest; //생성 시 질문 - private Set studyDays; private String category; // 스터디 카테고리 private String intro; //스터디 소개 private int num; //멤버수 @@ -25,20 +22,17 @@ public class PostSaveRequestDto { private boolean onOff; //진행방식 (온오프) private Date startDate; //스터디 시작 날짜 private Date endDate; //스터디 끝나는 날짜 - private Date rcstart; // 모집 시작 날짜 - private Date rcend; //모집 마감 날짜 - + private List studyDayEntities; @Builder - public PostSaveRequestDto(String title, String goal, String rules, String quest,Set studyDays, - String category, String intro, int num, String mod, - boolean onOff, Date startDate, Date endDate, Date rcstart, Date rcend) { + public StRoomSaveRequestDto(String title, String goal, String rules, String quest, String category, + String intro, int num, String mod, boolean onOff, Date startDate, + Date endDate,List studyDayEntities) { this.title = title; this.goal = goal; this.rules = rules; this.quest = quest; - this.studyDays = studyDays; this.category = category; this.intro = intro; this.mod = mod; @@ -46,29 +40,24 @@ public PostSaveRequestDto(String title, String goal, String rules, String quest, this.onOff = onOff; this.startDate = startDate; this.endDate = endDate; - this.rcstart = rcstart; - this.rcend = rcend; + this.studyDayEntities = studyDayEntities; + } - public Posts toEntity() { - return Posts.builder() + public StRoomEntity toEntity() { + return StRoomEntity.builder() .title(title) .goal(goal) .rules(rules) .quest(quest) - .studyDays(studyDays) .category(category) .intro(intro) .mod(mod) .num(num) - .intro(intro) - .mod(mod) - .num(num) .onOff(onOff) .startDate(startDate) .endDate(endDate) - .rcstart(rcstart) - .rcend(rcend) + .studyDayEntities(studyDayEntities) .build(); } } diff --git a/src/main/java/mos/mosback/web/dto/PostsListResponseDto.java b/src/main/java/mos/mosback/web/dto/StRoomUpdateRequestDto.java similarity index 68% rename from src/main/java/mos/mosback/web/dto/PostsListResponseDto.java rename to src/main/java/mos/mosback/web/dto/StRoomUpdateRequestDto.java index e2226cf..90c1a49 100644 --- a/src/main/java/mos/mosback/web/dto/PostsListResponseDto.java +++ b/src/main/java/mos/mosback/web/dto/StRoomUpdateRequestDto.java @@ -1,20 +1,22 @@ package mos.mosback.web.dto; + import lombok.Getter; -import mos.mosback.domain.posts.Posts; -import java.util.Date; -import mos.mosback.domain.posts.StudyDays; -import java.util.Set; +import mos.mosback.domain.posts.StRoomEntity; +import mos.mosback.domain.posts.StudyDaysEntity; +import java.util.Date; +import java.util.List; @Getter -public class PostsListResponseDto { - Long groupID; +public class StRoomUpdateRequestDto { + + Long roomID; private String title; private String goal; //스터디 목표 private String rules; //스터디 규칙 + private String quest; private String category; // 스터디 카테고리 - private Set studyDays; //스터디요일 private String intro; //스터디 소개 private int num; //멤버수 private String mod; //스터디 분위기 @@ -23,25 +25,26 @@ public class PostsListResponseDto { private Date startDate; //스터디 시작 날짜 private Date endDate; //스터디 끝나는 날짜 private Date createDate; // 스터디룸 생성 날짜 - private Date rcstart; // 모집 시작 날짜 - private Date rcend; //모집 마감 날짜 + private List studyDayEntities; - public PostsListResponseDto(Posts entity) { + public StRoomUpdateRequestDto(StRoomEntity entity) { this.title = entity.getTitle(); this.goal = entity.getGoal(); this.rules = entity.getRules(); + this.quest =entity.getQuest(); this.category =entity.getCategory(); - this.studyDays =entity.getStudyDays(); this.intro =entity.getIntro(); this.num = entity.getNum(); this.mod = entity.getMod(); this.onOff = entity.isOnOff(); this.startDate = entity.getStartDate(); this.endDate = entity.getEndDate(); - this.rcstart =entity.getRcstart(); - this.rcend =entity.getRcend(); + this.studyDayEntities =entity.getStudyDayEntities(); + } + + } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 90ea6cf..94d217d 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,26 +1,31 @@ -spring.jpa.show_sql = true -spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect +# DB ?? ?? +spring.datasource.url=jdbc:h2:mem:testdb +spring.datasource.hikari.jdbc-url=jdbc:h2:mem:testdb;MODE=MYSQL +# DB (H2) ?? ?? spring.h2.console.enabled=true spring.h2.console.path=/h2-console -spring.datasource.url=jdbc:h2:mem:testdb + +# JPA ?? ?? +spring.jpa.show_sql = true +spring.jpa.hibernate.ddl-auto=update spring.jpa.open-in-view=false +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect + +# Spring ?? ?? spring.mvc.servlet.load-on-startup=1 -spring.datasource.hikari.jdbc-url=jdbc:h2:mem:testdb;MODE=MYSQL spring.profiles.include=oauth spring.session.store-type=jdbc -logging.level.org.springframework.web=DEBUG - spring.mvc.view.prefix=/WEB-INF/templates/ spring.mvc.view.suffix=.html -#static resource +#??? static resource spring.mvc.static-path-pattern=/static/** spring.resources.static-locations=classpath:/static/ spring.mvc.contentnegotiation.media-types.json=application/x-www-form-urlencoded - #spring.resources.add-mappings=true - #spring.mvc.throw-exception-if-no-handler-found=true +# ?? ?? ?? +logging.level.org.springframework.web=DEBUG \ No newline at end of file diff --git a/src/test/java/mos/mosback/domain/posts/PostsRepository.java b/src/test/java/mos/mosback/domain/posts/PostsRepository.java index 1cdc1ac..e69de29 100644 --- a/src/test/java/mos/mosback/domain/posts/PostsRepository.java +++ b/src/test/java/mos/mosback/domain/posts/PostsRepository.java @@ -1,4 +0,0 @@ -package mos.mosback.domain.posts; - -public class PostsRepository { -} From 75941701beb6d6057c3016683fd0eb660319b1ed Mon Sep 17 00:00:00 2001 From: slonue <127409712+slonue@users.noreply.github.com> Date: Mon, 11 Sep 2023 22:46:37 +0900 Subject: [PATCH 06/60] =?UTF-8?q?login=20=EC=9D=B4=EB=9E=91=20=EC=9E=84?= =?UTF-8?q?=EC=8B=9C=EB=B9=84=EB=B0=80=EB=B2=88=ED=98=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mosback/controller/UserController.java | 84 ++++++++++++++++--- 1 file changed, 74 insertions(+), 10 deletions(-) diff --git a/src/main/java/mos/mosback/controller/UserController.java b/src/main/java/mos/mosback/controller/UserController.java index 48e33b0..1d6f277 100644 --- a/src/main/java/mos/mosback/controller/UserController.java +++ b/src/main/java/mos/mosback/controller/UserController.java @@ -1,33 +1,97 @@ package mos.mosback.controller; +import com.zaxxer.hikari.pool.HikariProxyCallableStatement; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import mos.mosback.data.entity.User; +import mos.mosback.repository.UserRepository; import mos.mosback.service.UserService; -import mos.mosback.web.dto.UserInfoDto; +import mos.mosback.web.dto.*; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; +import mos.mosback.Provider.JwtTokenProvider; + +import javax.transaction.Transactional; @Controller @RequestMapping("/api") public class UserController { - private final UserService userService; + private UserService userService; + private UserRepository userRepository; + private String secretKey ="mosback"; - public UserController(UserService userService) { + public UserController(UserService userService, UserRepository userRepository) { this.userService = userService; + this.userRepository = userRepository; } + //회원가입 이메일,닉네임,기간 마이페이지에 있는 erd @PostMapping("/signup") - public ResponseEntity signup(@RequestBody UserInfoDto userInfoDto) { - if (userService.checkEmailDuplicate(userInfoDto.getEmail())) { - return ResponseEntity.badRequest().body("Email already exists"); + public ResponseEntity join(@RequestBody SignUpDTO signUpDTO) { + if(userService.isEmailDuplicate(signUpDTO.getEmail())) { + return ResponseEntity.status(400).body("Email already exists"); + } + userService.join(signUpDTO); + return ResponseEntity.ok("Join Success!"); + } + + //로그인 + @PostMapping("/login") + public ResponseEntity login(@RequestBody LoginDTO loginDTO) { + if(userService.isEmailDuplicate(loginDTO.getEmail())) { + if(userService.comparePassword(loginDTO.getEmail(),loginDTO.getPassword())) { + User user = userRepository.findByEmail(loginDTO.getEmail()); + if(user != null) { + return ResponseEntity.ok(JwtTokenProvider.createToken(user.getEmail(), user.getPassword())); + } + return ResponseEntity.status(400).body("사용자를 찾을 수 없습니다."); + } + return ResponseEntity.status(400).body("비밀번호가 틀렸습니다."); } + return ResponseEntity.status(400).body("사용자를 찾을 수 없습니다."); + } - userService.save(userInfoDto); - return ResponseEntity.ok("Signup successful"); + //회원 정보 수정 + @PutMapping("/update") + public User updateInfo(@RequestBody UserUpdateDTO userUpdateDTO, @RequestHeader("Authorization") String jwtToken) { + Claims claims = Jwts.parser().setSigningKey(secretKey.getBytes()).parseClaimsJws(jwtToken).getBody(); + User user = userRepository.findByEmail(claims.getSubject()); + userService.updateUserInfo(user, userUpdateDTO); + return user; } + + + //이메일 중복확인 @GetMapping("/user-emails/{email}/exists") - public ResponseEntity checkEmailDuplicate(@PathVariable String email){ - return ResponseEntity.ok(userService.checkEmailDuplicate(email)); + public ResponseEntity isEmailDuplicate(@PathVariable String email){ + return ResponseEntity.ok(userService.isEmailDuplicate(email)); + } + + //비밀번호 변경 + @Transactional + @PostMapping("/find") + public ResponseEntity findPw(@RequestBody FindPWDTO findPWDTO){ + if(userService.findPassword(findPWDTO)) { + MailDTO mailDTO = userService.createMailAndChangePassword(findPWDTO.getEmail()); + userService.mailSend(mailDTO); + return ResponseEntity.ok("임시 비밀번호 메일 전송, 변경 완료"); + } + else{ + return ResponseEntity.status(400).body("해당 사용자가 없습니다."); + } + } + + @Transactional + @PostMapping("/send/Email") + public ResponseEntity sendEmail(@RequestParam("userEmail") String userEmail){ + MailDTO mailDTO = userService.createMailAndChangePassword(userEmail); + userService.mailSend(mailDTO); + + return ResponseEntity.ok("임시 비밀번호 메일 전송, 변경 완료"); } + + } From 4f5dc7cbc2953b9fb7823e0376adb8d63db6ad84 Mon Sep 17 00:00:00 2001 From: slonue <127409712+slonue@users.noreply.github.com> Date: Mon, 11 Sep 2023 22:47:58 +0900 Subject: [PATCH 07/60] =?UTF-8?q?user=20=EC=97=94=ED=8B=B0=ED=8B=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/mos/mosback/data/entity/User.java | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 src/main/java/mos/mosback/data/entity/User.java diff --git a/src/main/java/mos/mosback/data/entity/User.java b/src/main/java/mos/mosback/data/entity/User.java new file mode 100644 index 0000000..4458499 --- /dev/null +++ b/src/main/java/mos/mosback/data/entity/User.java @@ -0,0 +1,107 @@ +package mos.mosback.data.entity; + +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import mos.mosback.web.dto.UserUpdateDTO; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; + +import javax.persistence.*; +import java.util.Collection; +import java.util.Date; + +@Entity +@Table(name = "user") +@NoArgsConstructor +@Getter +@Setter +public class User implements UserDetails { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false, unique = true) + private String email; + + @Column(nullable = false) + private String password; + + @Column(nullable = false) + private String name; + + @Column(nullable = false) + private String nickname; + + @Column(nullable = false) + private Date duration; + + @Column(nullable = false) + private String message; + + @Column(nullable = false) + private String company; + + @Builder + public User(String email, String password, String name, String nickname, Date duration, String message, String company){ + this.email = email; + this.password = cryptopassword(password); + this.name = name; + this.nickname = nickname; + this.duration = duration; + this.message = message; + this.company = company; + } + + public void update(UserUpdateDTO userUpdateDTO) { + this.email = userUpdateDTO.getEmail(); + this.password = cryptopassword(userUpdateDTO.getPassword()); + this.name = userUpdateDTO.getName(); + this.nickname = userUpdateDTO.getNickname(); + this.duration = userUpdateDTO.getDuration(); + this.message = userUpdateDTO.getMessage(); + this.company = userUpdateDTO.getCompany(); + } + + public void updatePw(String password) { + this.password = cryptopassword(password); + } + + public String cryptopassword(String password) { + BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + String encodedPassword = passwordEncoder.encode(password); + return encodedPassword; + } + + @Override + public Collection getAuthorities() { + return null; + } + + @Override + public String getUsername() { + return getEmail(); + } + + @Override + public boolean isAccountNonExpired() { + return false; + } + + @Override + public boolean isAccountNonLocked() { + return false; + } + + @Override + public boolean isCredentialsNonExpired() { + return false; + } + + @Override + public boolean isEnabled() { + return false; + } +} From bc67f319048cd5c0975855706d07e5aacd34b069 Mon Sep 17 00:00:00 2001 From: slonue <127409712+slonue@users.noreply.github.com> Date: Mon, 11 Sep 2023 22:48:44 +0900 Subject: [PATCH 08/60] =?UTF-8?q?=EB=A9=94=EC=9D=BC=EC=9D=B4=EB=9E=91=20?= =?UTF-8?q?=ED=86=A0=ED=81=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Filter/JwtAuthenticationFilter.java | 34 ++++++++ .../mosback/Provider/JwtTokenProvider.java | 81 +++++++++++++++++++ .../mos/mosback/config/EncryptionUtils.java | 28 +++++++ .../java/mos/mosback/config/MailConfig.java | 37 +++++++++ 4 files changed, 180 insertions(+) create mode 100644 src/main/java/mos/mosback/Filter/JwtAuthenticationFilter.java create mode 100644 src/main/java/mos/mosback/Provider/JwtTokenProvider.java create mode 100644 src/main/java/mos/mosback/config/EncryptionUtils.java create mode 100644 src/main/java/mos/mosback/config/MailConfig.java diff --git a/src/main/java/mos/mosback/Filter/JwtAuthenticationFilter.java b/src/main/java/mos/mosback/Filter/JwtAuthenticationFilter.java new file mode 100644 index 0000000..7de1310 --- /dev/null +++ b/src/main/java/mos/mosback/Filter/JwtAuthenticationFilter.java @@ -0,0 +1,34 @@ +package mos.mosback.Filter; + +import mos.mosback.Provider.JwtTokenProvider; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.filter.GenericFilterBean; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; + +@RequiredArgsConstructor +public class JwtAuthenticationFilter extends GenericFilterBean { + + private final JwtTokenProvider jwtTokenProvider; + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + // 헤더에서 JWT 를 받아옵니다. + String token = jwtTokenProvider.resolveToken((HttpServletRequest) request); + // 유효한 토큰인지 확인합니다. + if (token != null && jwtTokenProvider.validateToken(token)) { + // 토큰이 유효하면 토큰으로부터 유저 정보를 받아옵니다. + Authentication authentication = jwtTokenProvider.getAuthentication(token); + // SecurityContext 에 Authentication 객체를 저장합니다. + SecurityContextHolder.getContext().setAuthentication(authentication); + } + chain.doFilter(request, response); + } +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/Provider/JwtTokenProvider.java b/src/main/java/mos/mosback/Provider/JwtTokenProvider.java new file mode 100644 index 0000000..ae33c81 --- /dev/null +++ b/src/main/java/mos/mosback/Provider/JwtTokenProvider.java @@ -0,0 +1,81 @@ +package mos.mosback.Provider; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jws; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; +import lombok.RequiredArgsConstructor; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.servlet.http.HttpServletRequest; +import java.security.Key; +import java.util.Base64; +import java.util.Date; + +@RequiredArgsConstructor +@Component +public class JwtTokenProvider { + private static Key secretKey; // Key 타입으로 변경 + + // 토큰 유효시간 30분 + private static long tokenValidTime = 60 * 60 * 1000L; + + private final UserDetailsService userDetailsService; + + // 객체 초기화, secretKey를 Base64로 인코딩한다. + @PostConstruct + protected void init() { + secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256); + } + + // JWT 토큰 생성 + public static String createToken(String userPk, String userPassword) { + Claims claims = Jwts.claims().setSubject(userPk); // JWT payload 에 저장되는 정보단위, 보통 여기서 user를 식별하는 값을 넣는다. + claims.put("password", userPassword); // 정보는 key / value 쌍으로 저장된다. + Date now = new Date(); + return Jwts.builder() + .setClaims(claims) // 정보 저장 + .setIssuedAt(now) // 토큰 발행 시간 정보 + .setExpiration(new Date(now.getTime() + tokenValidTime)) // set Expire Time + .signWith(secretKey, SignatureAlgorithm.HS256) // 사용할 암호화 알고리즘과 + // signature 에 들어갈 secret값 세팅 + .compact(); + } + +// private String token; + //JWT 검증 +// Jws claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token); + + + // JWT 토큰에서 인증 정보 조회 + public Authentication getAuthentication(String token) { + UserDetails userDetails = userDetailsService.loadUserByUsername(this.getUserPk(token)); + return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities()); + } + + // 토큰에서 회원 정보 추출 + public String getUserPk(String token) { + return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getSubject(); + } + + // Request의 Header에서 token 값을 가져옵니다. "Authorization" : "TOKEN값' + public String resolveToken(HttpServletRequest request) { + return request.getHeader("Authorization"); + } + + // 토큰의 유효성 + 만료일자 확인 + public boolean validateToken(String jwtToken) { + try { + Jws claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(jwtToken); + return !claims.getBody().getExpiration().before(new Date()); + } catch (Exception e) { + return false; + } + } +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/config/EncryptionUtils.java b/src/main/java/mos/mosback/config/EncryptionUtils.java new file mode 100644 index 0000000..8c9dcad --- /dev/null +++ b/src/main/java/mos/mosback/config/EncryptionUtils.java @@ -0,0 +1,28 @@ +package mos.mosback.config; + +import java.security.MessageDigest; + +public class EncryptionUtils { + + public static String encryptSHA256(String s) { + return encrypt(s, "SHA-256"); + } + + public static String encryptMD5(String s) { + return encrypt(s, "MD5"); + } + + public static String encrypt(String s, String messageDigest) { + try { + MessageDigest md = MessageDigest.getInstance(messageDigest); + byte[] passBytes = s.getBytes(); + md.reset(); + byte[] digested = md.digest(passBytes); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < digested.length; i++) sb.append(Integer.toString((digested[i]&0xff) + 0x100, 16).substring(1)); + return sb.toString(); + } catch (Exception e) { + return s; + } + } +} diff --git a/src/main/java/mos/mosback/config/MailConfig.java b/src/main/java/mos/mosback/config/MailConfig.java new file mode 100644 index 0000000..2613b5e --- /dev/null +++ b/src/main/java/mos/mosback/config/MailConfig.java @@ -0,0 +1,37 @@ +package mos.mosback.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.JavaMailSenderImpl; + +import java.util.Properties; + +@Configuration +public class MailConfig { + @Bean + public JavaMailSender javaMailService() { + JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl(); + + javaMailSender.setHost("smtp.naver.com"); + javaMailSender.setUsername("dmsthf1225@naver.com"); + javaMailSender.setPassword("dmsthf12fkqb"); + + javaMailSender.setPort(465); + + javaMailSender.setJavaMailProperties(getMailProperties()); + + return javaMailSender; + } + + private Properties getMailProperties() { + Properties properties = new Properties(); + properties.setProperty("mail.transport.protocol", "smtp"); + properties.setProperty("mail.smtp.auth", "true"); + properties.setProperty("mail.smtp.starttls.enable", "true"); + properties.setProperty("mail.debug", "true"); + properties.setProperty("mail.smtp.ssl.trust","smtp.naver.com"); + properties.setProperty("mail.smtp.ssl.enable","true"); + return properties; + } +} \ No newline at end of file From 630e87eca382fafd0d56104bd81a1e586fcba967 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Thu, 14 Sep 2023 14:13:09 +0900 Subject: [PATCH 09/60] 0914 --- .gitignore | 3 + build.gradle | 55 +++++++---- .../mosback/controller/HomeController.java | 9 -- .../mosback/controller/StRoomController.java | 95 +++++++++++++------ .../mosback/controller/TodoController.java | 46 ++++++++- .../mosback/controller/UserController.java | 33 ------- .../mosback/domain/posts/BaseTimeEntity.java | 3 - .../mosback/domain/posts/StRoomEntity.java | 36 ++++--- .../mosback/domain/posts/StudyDaysEntity.java | 10 +- .../mos/mosback/domain/posts/ToDoEntity.java | 10 +- .../mosback/repository/HomeRepository.java | 11 ++- .../mosback/repository/StRoomRepository.java | 21 ++-- .../mosback/repository/ToDoRepository.java | 3 +- .../java/mos/mosback/repository/UserInfo.java | 2 +- .../mosback/repository/UserRepository.java | 2 +- .../java/mos/mosback/service/HomeService.java | 1 + .../mos/mosback/service/StRoomService.java | 59 ++++++------ .../java/mos/mosback/service/ToDoService.java | 37 ++++++++ .../java/mos/mosback/service/UserService.java | 10 -- .../mos/mosback/service/UserServiceImpl.java | 29 ------ .../mos/mosback/web/dto/HomeResponseDto.java | 4 - .../mosback/web/dto/Home_RoomResponseDto.java | 29 ++++++ .../web/dto/StRoomListResponseDto.java | 24 ++++- .../mosback/web/dto/StRoomResponseDto.java | 15 +-- .../mosback/web/dto/StRoomSaveRequestDto.java | 18 ++-- .../web/dto/StRoomUpdateRequestDto.java | 50 +++++----- .../mos/mosback/web/dto/ToDoRequestDto.java | 2 +- .../mos/mosback/web/dto/ToDoResponseDto.java | 2 +- .../java/mos/mosback/web/dto/UserInfoDto.java | 26 ----- 29 files changed, 368 insertions(+), 277 deletions(-) delete mode 100644 src/main/java/mos/mosback/controller/UserController.java create mode 100644 src/main/java/mos/mosback/service/ToDoService.java delete mode 100644 src/main/java/mos/mosback/service/UserService.java delete mode 100644 src/main/java/mos/mosback/service/UserServiceImpl.java delete mode 100644 src/main/java/mos/mosback/web/dto/HomeResponseDto.java create mode 100644 src/main/java/mos/mosback/web/dto/Home_RoomResponseDto.java delete mode 100644 src/main/java/mos/mosback/web/dto/UserInfoDto.java diff --git a/.gitignore b/.gitignore index c2065bc..d611f15 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,6 @@ out/ ### VS Code ### .vscode/ +src/main/java/mos/mosback/web/dto/PostsListResponseDto.java +src/main/java/mos/mosback/web/dto/PostsListResponseDto.java +src/main/java/mos/mosback/web/dto/PostsListResponseDto.java diff --git a/build.gradle b/build.gradle index 2783226..ff2e647 100644 --- a/build.gradle +++ b/build.gradle @@ -10,8 +10,8 @@ java { targetCompatibility = JavaVersion.VERSION_1_8 } -group = 'jpabook' -version = '0.0.1-SNAPSHOT' +group = 'mos' +version '1.0-SNAPSHOT' configurations { compileOnly { @@ -21,7 +21,10 @@ configurations { repositories { mavenCentral() - jcenter() + maven { + url 'https://repo.clojars.org' + name 'Clojars' + } } // for Junit 5 @@ -30,29 +33,39 @@ test { // (2) } dependencies { - //(3) - implementation('org.springframework.boot:spring-boot-starter-web') - implementation('org.springframework.boot:spring-boot-starter-mustache') - - // lombok - implementation('org.projectlombok:lombok:1.18.20') - testImplementation 'junit:junit:4.13.1' - annotationProcessor('org.projectlombok:lombok:1.18.20') - testImplementation('org.projectlombok:lombok:1.18.20') - testAnnotationProcessor('org.projectlombok:lombok:1.18.20') - implementation('org.springframework.boot:spring-boot-starter-data-jpa') - implementation("org.mariadb.jdbc:mariadb-java-client") - implementation('com.h2database:h2') + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-validation' + implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' + implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5' + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-devtools' + implementation 'io:io:0.2.1' + testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1' + compileOnly 'org.projectlombok:lombok' + runtimeOnly 'com.h2database:h2' + annotationProcessor 'org.projectlombok:lombok' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + implementation 'org.springframework.boot:spring-boot-starter-security' + implementation 'org.springframework.boot:spring-boot-starter-mail' //메일 의존성 - implementation('org.springframework.boot:spring-boot-starter-oauth2-client') - implementation('org.springframework.session:spring-session-jdbc') + testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'org.springframework.security:spring-security-test' - testImplementation('org.springframework.boot:spring-boot-starter-test') - testImplementation("org.springframework.security:spring-security-test") +// 로그인 jwt 의존성 + implementation group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.2' + runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.2' + runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.2' + implementation group: 'org.postgresql', name: 'postgresql', version: '42.2.23' - implementation 'org.springframework.security:spring-security-core:5.4.10' + implementation 'org.mariadb.jdbc:mariadb-java-client:3.0.3' + // lombok + implementation('org.projectlombok:lombok:1.18.20') + testImplementation 'junit:junit:4.13.1' + annotationProcessor('org.projectlombok:lombok:1.18.20') + testImplementation('org.projectlombok:lombok:1.18.20') + testAnnotationProcessor('org.projectlombok:lombok:1.18.20') } \ No newline at end of file diff --git a/src/main/java/mos/mosback/controller/HomeController.java b/src/main/java/mos/mosback/controller/HomeController.java index 74b48cf..e69de29 100644 --- a/src/main/java/mos/mosback/controller/HomeController.java +++ b/src/main/java/mos/mosback/controller/HomeController.java @@ -1,9 +0,0 @@ -package mos.mosback.controller; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - -import java.util.List; -public class HomeController { - -} diff --git a/src/main/java/mos/mosback/controller/StRoomController.java b/src/main/java/mos/mosback/controller/StRoomController.java index 49b3afd..04cb362 100644 --- a/src/main/java/mos/mosback/controller/StRoomController.java +++ b/src/main/java/mos/mosback/controller/StRoomController.java @@ -1,14 +1,15 @@ package mos.mosback.controller; -import mos.mosback.web.dto.StRoomSaveRequestDto; -import mos.mosback.web.dto.StRoomListResponseDto; -import mos.mosback.web.dto.StRoomUpdateRequestDto; +import mos.mosback.web.dto.*; import mos.mosback.service.StRoomService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import javax.persistence.EntityNotFoundException; +import java.util.HashMap; import java.util.List; +import java.util.Map; @RestController @RequestMapping("/api/studyRoom") //URL 패턴 @@ -22,59 +23,98 @@ public StRoomController(StRoomService stRoomService) { } @PostMapping("/create") - public ResponseEntity saveroom(@RequestBody StRoomSaveRequestDto requestDto) { + public ResponseEntity saveRoom(@RequestBody StRoomSaveRequestDto requestDto) { Long stroomId = stRoomService.save(requestDto); return ResponseEntity.status(HttpStatus.CREATED).body("created successfully. ID: " + stroomId); } /** * 스터디 방 정보 가져오기 - * @param roomID + * @param //roomId * @return */ - @GetMapping("/get/{roomID}") - public ResponseEntity getRoom(@PathVariable Long roomID) { - StRoomUpdateRequestDto stroom = stRoomService.findById(roomID); + + @GetMapping("get/{roomId}") + public ResponseEntity FindByID (@PathVariable Long roomId) { + StRoomResponseDto stroom = stRoomService.findById(roomId); return new ResponseEntity<>(stroom, HttpStatus.OK); } - @GetMapping("/search") - public ResponseEntity> searchrooms(@RequestParam String keyword) { - List strooms = stRoomService.findByTitleContaining(keyword); - return new ResponseEntity<>(strooms, HttpStatus.OK); + public ResponseEntity searchRoom(@RequestParam String keyword) { + try { + List strooms = stRoomService.findByTitleContaining(keyword); + return new ResponseEntity<>(strooms, HttpStatus.OK); + } catch (IllegalArgumentException e) { + Map response = new HashMap<>(); + response.put("status", "404"); + response.put("message", "NOT FOUND " + keyword); + response.put("success", "false"); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); + } } - - @PutMapping("/update/{roomID}") - public ResponseEntity updateroom(@PathVariable Long roomID, @RequestBody StRoomUpdateRequestDto requestDto) { + @PutMapping("/update/{roomId}") + public ResponseEntity UpdateRoom(@PathVariable Long roomId, @RequestBody StRoomUpdateRequestDto requestDto) { try { - stRoomService.update(roomID, requestDto); + stRoomService.update(roomId, requestDto); return ResponseEntity.ok("updated."); } catch (IllegalArgumentException e) { return ResponseEntity.status(HttpStatus.NOT_FOUND) - .body("NOT FOUND"+"'"+roomID+"'"); - + .body("NOT FOUND "+"'"+roomId+"'"); } } - @DeleteMapping("/delete/{roomID}") - public ResponseEntity deleteroom(@PathVariable Long roomID) { - stRoomService.delete(roomID); - return new ResponseEntity<>(HttpStatus.NO_CONTENT); + @DeleteMapping("/delete/{roomId}") + public ResponseEntity> deleteRoom(@PathVariable Long roomId) { + Map response = new HashMap<>(); + try { + stRoomService.delete(roomId); + response.put("status", 200); + response.put("success", true); + response.put("message", "deleted"+"'"+roomId+"'"); + return ResponseEntity.ok(response); + } catch (EntityNotFoundException ex) { + response.put("status", 404); + response.put("success", false); + response.put("message", "NOTFOUND"+"'"+roomId+"'"); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); + } } @GetMapping("/all") - public ResponseEntity> getAllrooms() { - List strooms = stRoomService.findAllDesc(); - return new ResponseEntity<>(strooms, HttpStatus.OK); + public ResponseEntity> findAllRoomsDesc() { + List rooms = stRoomService.findAllRoomsDesc(); + return ResponseEntity.ok(rooms); } @GetMapping("/popular") - public ResponseEntity> getPopularrooms() { - List popularrooms = stRoomService.findPopularstrooms(); + public ResponseEntity> getPopularRooms() { + List popularrooms = stRoomService.findPopularRoom(); return new ResponseEntity<>(popularrooms, HttpStatus.OK); } + @GetMapping("/home/studyRoom") + public ResponseEntity> findRoomsInHome(){ + List roomsInhome = stRoomService.findRoomsInHome(); + return new ResponseEntity<>(roomsInhome,HttpStatus.OK); + } + + @GetMapping("/byCategory/{category}") + public ResponseEntity> getStudyRoomsByCategory(@PathVariable String category) { + Map response = new HashMap<>(); + List studyRooms = stRoomService.findByCategory(category); + if (studyRooms.isEmpty()) { + response.put("status", HttpStatus.NOT_FOUND.value()); + response.put("success", false); + response.put("message", "NOT FOUND: " + category); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); + } + + response.put("status", HttpStatus.OK.value()); + response.put("success", true); + response.put("studyRooms", studyRooms); // 데이터를 직접 넣음 + return ResponseEntity.ok(response); + } } //핸들러 메서드 : // @@ -85,4 +125,3 @@ public ResponseEntity> getPopularrooms() { //deletestroom: 게시물을 삭제하는 엔드포인트. //getAllstrooms: 모든 게시물을 조회하는 엔드포인트. //getPopularstrooms: 조회순으로 게시물을 조회하는 엔드포인트. (인기순 조회시) -//getRecruitment : 모집기간인 게시물을 조회하는 엔드포인트. diff --git a/src/main/java/mos/mosback/controller/TodoController.java b/src/main/java/mos/mosback/controller/TodoController.java index d0dd724..2254ecf 100644 --- a/src/main/java/mos/mosback/controller/TodoController.java +++ b/src/main/java/mos/mosback/controller/TodoController.java @@ -1,4 +1,48 @@ package mos.mosback.controller; +import mos.mosback.domain.posts.ToDoEntity; +import mos.mosback.service.ToDoService; +import mos.mosback.web.dto.ToDoRequestDto; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +@RestController +@RequestMapping("/api/todo") //URL 패턴 public class TodoController { -} + private final ToDoService toDoService; + + @Autowired + public TodoController(ToDoService toDoService) { + this.toDoService = toDoService; + } + + @PostMapping("/add") + public ResponseEntity addTodo(@RequestBody ToDoRequestDto requestDto){ + ToDoEntity toDoEntity = toDoService.add(requestDto.getTodoContent()); + return ResponseEntity.status(HttpStatus.CREATED).body("TodoList 추가 완료. index : " +toDoEntity.getTodoIdx()); + } + @PutMapping("/update/{TodoIdx}") + public ResponseEntity updateTodo(@PathVariable Long TodoIdx, @RequestBody ToDoRequestDto requestDto) { + try { + ToDoEntity updatedToDo = toDoService.update(TodoIdx, requestDto.getTodoContent(), requestDto.isCompleted()); + return ResponseEntity.ok("ToDo 업데이트 완료. Index: " + TodoIdx); + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body("NOT FOUND TODO"); + } + } + + @DeleteMapping("/delete/{TodoIdx}") + public ResponseEntity deleteTodo(@PathVariable Long TodoIdx) { + try { + toDoService.delete(TodoIdx); + return ResponseEntity.ok("ToDo 삭제 완료. Index: " + TodoIdx); + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body("NOT FOUND TODO"); + } + } + + +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/controller/UserController.java b/src/main/java/mos/mosback/controller/UserController.java deleted file mode 100644 index 48e33b0..0000000 --- a/src/main/java/mos/mosback/controller/UserController.java +++ /dev/null @@ -1,33 +0,0 @@ -package mos.mosback.controller; - -import mos.mosback.service.UserService; -import mos.mosback.web.dto.UserInfoDto; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.*; - -@Controller -@RequestMapping("/api") -public class UserController { - - private final UserService userService; - - public UserController(UserService userService) { - this.userService = userService; - } - - @PostMapping("/signup") - public ResponseEntity signup(@RequestBody UserInfoDto userInfoDto) { - if (userService.checkEmailDuplicate(userInfoDto.getEmail())) { - return ResponseEntity.badRequest().body("Email already exists"); - } - - userService.save(userInfoDto); - return ResponseEntity.ok("Signup successful"); - } - - @GetMapping("/user-emails/{email}/exists") - public ResponseEntity checkEmailDuplicate(@PathVariable String email){ - return ResponseEntity.ok(userService.checkEmailDuplicate(email)); - } -} diff --git a/src/main/java/mos/mosback/domain/posts/BaseTimeEntity.java b/src/main/java/mos/mosback/domain/posts/BaseTimeEntity.java index 9d0aa1a..791b314 100644 --- a/src/main/java/mos/mosback/domain/posts/BaseTimeEntity.java +++ b/src/main/java/mos/mosback/domain/posts/BaseTimeEntity.java @@ -16,8 +16,5 @@ public abstract class BaseTimeEntity { @CreatedDate //Entity가 생성되어 저장될때 시간이 자동저장 private LocalDateTime createdDate; - @LastModifiedDate //조회한 Entity의 값을 변경할 때 시간이 자동저장 (이 기능은 굳이 필요 없을지도 ) - private LocalDateTime modifiedDate; - } //모든 Entity의 상위 클래스가 되어 엔티티들의 생성시간 변경시간을 자동으로 관리하는 클래스 \ No newline at end of file diff --git a/src/main/java/mos/mosback/domain/posts/StRoomEntity.java b/src/main/java/mos/mosback/domain/posts/StRoomEntity.java index 6320b52..d36d3e8 100644 --- a/src/main/java/mos/mosback/domain/posts/StRoomEntity.java +++ b/src/main/java/mos/mosback/domain/posts/StRoomEntity.java @@ -2,10 +2,15 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; + import javax.persistence.*; +import java.time.LocalDate; +import java.time.ZoneId; import java.util.*; @Getter // 롬복 어노테이션 +@Setter @NoArgsConstructor // 롬복 어노테이션 (필수는 아님 그냥 코드 단순화용) @Entity //JPA 어노테이션 (주요어노테이션) : 테이블과 링크될 클래스임을 나타냄 public class StRoomEntity extends BaseTimeEntity { @@ -24,22 +29,26 @@ public class StRoomEntity extends BaseTimeEntity { private String quest; //생성 시 질문 private String category; // 스터디 카테고리 private String intro; //스터디 소개 - private int num; //멤버수 + private int memberNum; //현재 멤버수 + private int maxMember; //모집 멤버수 private String mod; //스터디 분위기 private int click;// 클릭횟수 (인기순 조회) private boolean onOff; //진행방식 (온오프) + private String location; + private int online; //온라인 private Date startDate; //스터디 시작 날짜 private Date endDate; //스터디 끝나는 날짜 + private Date deadline ; //스터디 모집 마감날짜 - @OneToMany(fetch = FetchType.EAGER) - @JoinColumn(name = "ST_ROOM_ROOMID") + @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) private List studyDayEntities = new ArrayList<>(); @Builder public StRoomEntity(String title, String goal, String rules, String quest, - String category, String intro, int num, String mod, - boolean onOff, Date startDate, Date endDate, List studyDayEntities) { + String category, String intro, int memberNum, int maxMember + ,String mod, boolean onOff, String location,int online, + Date startDate, Date endDate, Date deadline ,List studyDayEntities) { this.title = title; this.goal = goal; @@ -47,11 +56,15 @@ public StRoomEntity(String title, String goal, String rules, String quest, this.quest = quest; this.category = category; this.intro = intro; - this.num = num; + this.memberNum = memberNum; + this.maxMember = maxMember; this.mod = mod; this.onOff = onOff; + this.location = location; + this.online = online; this.startDate = startDate; this.endDate = endDate; + this.deadline = deadline; this.studyDayEntities = studyDayEntities; } @@ -59,8 +72,8 @@ public StRoomEntity(String title, String goal, String rules, String quest, // 다른 필요한 Getter 및 Setter 메서드 public void update(String title, String goal, String rules, String quest, - String category, String intro, - int num, String mod, boolean onOff, Date startDate, + String category, String intro, int maxMember, + String mod, boolean onOff,String location,int online, Date startDate, Date endDate,List studyDayEntities) { this.title = title; this.goal = goal; @@ -68,13 +81,14 @@ public void update(String title, String goal, String rules, String quest, this.quest = quest; this.category = category; this.intro = intro; - this.num = num; + this.maxMember = maxMember; this.mod = mod; this.onOff = onOff; + this.location = location; + this.online = online; this.startDate = startDate; this.endDate = endDate; this.studyDayEntities = studyDayEntities; } -} - +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/domain/posts/StudyDaysEntity.java b/src/main/java/mos/mosback/domain/posts/StudyDaysEntity.java index 6da06cf..b350e14 100644 --- a/src/main/java/mos/mosback/domain/posts/StudyDaysEntity.java +++ b/src/main/java/mos/mosback/domain/posts/StudyDaysEntity.java @@ -10,12 +10,10 @@ @NoArgsConstructor // 롬복 어노테이션 (필수는 아님 그냥 코드 단순화용) @Entity //JPA 어노테이션 (주요어노테이션) : 테이블과 링크될 클래스임을 나타냄 public class StudyDaysEntity implements Serializable { - - @Id //해당 테이블 PK 필드 나타냄 - @Column(name="ST_ROOM_ROOMID") - private Long stroomid; - @Id - @Column(name="STUDY_DAYS") + @GeneratedValue(strategy = GenerationType.AUTO) + private Long dayIdx; + @Column(name = "STUDY_DAYS") private String studyDays; + } \ No newline at end of file diff --git a/src/main/java/mos/mosback/domain/posts/ToDoEntity.java b/src/main/java/mos/mosback/domain/posts/ToDoEntity.java index efe435e..222f244 100644 --- a/src/main/java/mos/mosback/domain/posts/ToDoEntity.java +++ b/src/main/java/mos/mosback/domain/posts/ToDoEntity.java @@ -1,6 +1,5 @@ package mos.mosback.domain.posts; import lombok.Builder; -import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; @@ -12,17 +11,16 @@ @Getter // 롬복 어노테이션 @NoArgsConstructor -@AllArgsConstructor @Entity //JPA 어노테이션 (주요어노테이션) : 테이블과 링크될 클래스 public class ToDoEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long TodoId; + private Long TodoIdx; - @Column(nullable = false) + @Column private String todoContent; - @Column(nullable = false) + @Column private boolean completed; // TodoLists 상태 ( 완료 - true, 미완료 - false) @@ -37,4 +35,4 @@ public void updateToDo(String todoContent,boolean completed){ } -} +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/repository/HomeRepository.java b/src/main/java/mos/mosback/repository/HomeRepository.java index 7e8f95c..1d9737e 100644 --- a/src/main/java/mos/mosback/repository/HomeRepository.java +++ b/src/main/java/mos/mosback/repository/HomeRepository.java @@ -1,4 +1,13 @@ package mos.mosback.repository; +import mos.mosback.domain.posts.StRoomEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + + +import java.util.List; + +public class HomeRepository { + + -public class HomeRepository { } diff --git a/src/main/java/mos/mosback/repository/StRoomRepository.java b/src/main/java/mos/mosback/repository/StRoomRepository.java index 3e1552a..14b7951 100644 --- a/src/main/java/mos/mosback/repository/StRoomRepository.java +++ b/src/main/java/mos/mosback/repository/StRoomRepository.java @@ -2,8 +2,10 @@ //Entity 클래스와 Entity레파지토리 위치 같아야함 import mos.mosback.domain.posts.StRoomEntity; +import mos.mosback.web.dto.Home_RoomResponseDto; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import java.util.List; @@ -11,14 +13,19 @@ //인터페이스 생성 후 JpaRepository를 상속하면 기본적인 CRUD 메소드 자동으로 생성됨 public interface StRoomRepository extends JpaRepository { - @Query("SELECT s FROM StRoomEntity s ORDER BY s.roomID DESC") - List findAllDesc(); + @Query("SELECT new mos.mosback.web.dto.Home_RoomResponseDto(s) FROM StRoomEntity s ORDER BY s.roomID DESC") + List findAllDesc(); - List findByTitleContaining(String keyword); //키워드를 통해 스터디그룹을 검색 할 수 있다 + @Query("SELECT new mos.mosback.web.dto.Home_RoomResponseDto(s) FROM StRoomEntity s WHERE s.title LIKE %:keyword%") + List findByTitleContaining(@Param("keyword") String keyword);//키워드를 통해 스터디그룹을 검색 할 수 있다 - @Query(value = "SELECT * FROM stroomEntity ORDER BY click DESC", nativeQuery = true) - List findPopularstrooms(); //클릭수로 인기순 나열 + @Query(value = "SELECT new mos.mosback.web.dto.Home_RoomResponseDto(s) FROM StRoomEntity s ORDER BY s.click DESC") + List findPopularRoom(); + @Query("SELECT new mos.mosback.web.dto.Home_RoomResponseDto(s) FROM StRoomEntity s") + List findHomeStRoomField(); + @Query("SELECT new mos.mosback.web.dto.Home_RoomResponseDto(s) FROM StRoomEntity s WHERE s.category = :category") + List findByCategory(@Param("category") String category); -} -//strooms 클래스로 DB를 접근하기 위한 클래스 \ No newline at end of file + +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/repository/ToDoRepository.java b/src/main/java/mos/mosback/repository/ToDoRepository.java index 1b6c2c5..eb6e8bb 100644 --- a/src/main/java/mos/mosback/repository/ToDoRepository.java +++ b/src/main/java/mos/mosback/repository/ToDoRepository.java @@ -6,8 +6,7 @@ import java.util.List; public interface ToDoRepository extends JpaRepository { - @Query("SELECT t FROM ToDoEntity t ORDER BY t.TodoId DESC") + @Query("SELECT t FROM ToDoEntity t ORDER BY t.TodoIdx DESC") List findAllDesc(); //Todo리스트를 조회시 todoID를 기준으로 내림차순 정렬 - // } diff --git a/src/main/java/mos/mosback/repository/UserInfo.java b/src/main/java/mos/mosback/repository/UserInfo.java index 8fbea47..21c3629 100644 --- a/src/main/java/mos/mosback/repository/UserInfo.java +++ b/src/main/java/mos/mosback/repository/UserInfo.java @@ -39,4 +39,4 @@ public void setPassword(String password) { this.password = password; } // 생성자, 게터/세터 등 생략 -} +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/repository/UserRepository.java b/src/main/java/mos/mosback/repository/UserRepository.java index 4bf7c74..f987924 100644 --- a/src/main/java/mos/mosback/repository/UserRepository.java +++ b/src/main/java/mos/mosback/repository/UserRepository.java @@ -9,4 +9,4 @@ public interface UserRepository extends JpaRepository { boolean existsByEmail(String email); // boolean existsByNickname(String nickname); -} +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/service/HomeService.java b/src/main/java/mos/mosback/service/HomeService.java index 8f910a0..f47fb02 100644 --- a/src/main/java/mos/mosback/service/HomeService.java +++ b/src/main/java/mos/mosback/service/HomeService.java @@ -1,4 +1,5 @@ package mos.mosback.service; public class HomeService { + } diff --git a/src/main/java/mos/mosback/service/StRoomService.java b/src/main/java/mos/mosback/service/StRoomService.java index ce8422f..a879c87 100644 --- a/src/main/java/mos/mosback/service/StRoomService.java +++ b/src/main/java/mos/mosback/service/StRoomService.java @@ -2,9 +2,7 @@ import lombok.RequiredArgsConstructor; import mos.mosback.domain.posts.StRoomEntity; import mos.mosback.repository.StRoomRepository; -import mos.mosback.web.dto.StRoomSaveRequestDto; -import mos.mosback.web.dto.StRoomListResponseDto; -import mos.mosback.web.dto.StRoomUpdateRequestDto; +import mos.mosback.web.dto.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; @@ -28,31 +26,28 @@ public void update(Long roomID, StRoomUpdateRequestDto requestDto) { .orElseThrow(() -> new IllegalArgumentException(roomID + " NOT FOUND")); // 나머지 필드 업데이트 - stroomEntity.update(requestDto.getTitle(), requestDto.getGoal(), requestDto.getRules(), + stroomEntity.update( + requestDto.getTitle(), requestDto.getGoal(), requestDto.getRules(), requestDto.getQuest(),requestDto.getCategory(), - requestDto.getIntro(), requestDto.getNum(), requestDto.getMod(), - requestDto.isOnOff(), requestDto.getStartDate(), requestDto.getEndDate() - ,requestDto.getStudyDayEntities()); + requestDto.getIntro(), requestDto.getMaxMember(), + requestDto.getMod(), requestDto.isOnOff(), requestDto.getLocation(), + requestDto.getOnline(),requestDto.getStartDate(), + requestDto.getEndDate(),requestDto.getStudyDayEntities()); } //stroomsRepository를 사용하여 데이터베이스에서 주어진 id에 해당하는 게시물을 찾기 + @Transactional(readOnly = true) - public StRoomUpdateRequestDto findById(Long roomID) { - StRoomEntity entity = stRoomRepository.findById(roomID) - .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id=" + roomID)); + public StRoomResponseDto findById(Long roomID) { + StRoomEntity stRoomEntity = stRoomRepository.findById(roomID) + .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id="+ roomID)); - return new StRoomUpdateRequestDto(entity); + return new StRoomResponseDto(stRoomEntity); } - @Transactional(readOnly = true) - public List findAllDesc() { - return stRoomRepository.findAllDesc().stream() - .map(StRoomListResponseDto::new) //.map(stroom->new stroomResponse(strooms))랑 같음 - // stroomsRepository 결과로 넘어온 strooms의 Stream을 - // map을 통해 stroomsListResponseDto변환 ->List로 반환하는 메소드 - - .collect(Collectors.toList()); + public List findAllRoomsDesc() { + return stRoomRepository.findAllDesc(); } @Transactional @@ -66,25 +61,25 @@ public void delete (Long roomID){ // --> 서비스에서 delete 메서드를 만들면 컨트롤러가 사용하도록 컨트롤러에 코드 추가하기. } @Transactional(readOnly = true) - public List findByTitleContaining(String keyword) { - List strooms = stRoomRepository.findByTitleContaining(keyword); - if (strooms.isEmpty()) { - throw new IllegalArgumentException("해당 스터디가 없습니다."); - } - return strooms.stream() - .map(StRoomListResponseDto::new) - .collect(Collectors.toList()); - } //스터디 title 로 검색 + public List findByTitleContaining(String keyword) { + return stRoomRepository.findByTitleContaining(keyword); + } @Transactional(readOnly = true) - public List findPopularstrooms() { - // 클릭된 조회수 순으로 게시물을 조회하는 비즈니스 로직을 호출 - List popularStrooms = stRoomRepository.findPopularstrooms(); + public List findPopularRoom() { + List popularStrooms = stRoomRepository.findPopularRoom(); return popularStrooms.stream() .map(StRoomListResponseDto::new) .collect(Collectors.toList()); } + @Transactional(readOnly = true) + public List findRoomsInHome() { + return stRoomRepository.findHomeStRoomField(); + } -} + public List findByCategory(String category) { + return stRoomRepository.findByCategory(category); + } +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/service/ToDoService.java b/src/main/java/mos/mosback/service/ToDoService.java new file mode 100644 index 0000000..f186f4f --- /dev/null +++ b/src/main/java/mos/mosback/service/ToDoService.java @@ -0,0 +1,37 @@ +package mos.mosback.service; +import lombok.RequiredArgsConstructor; +import mos.mosback.domain.posts.ToDoEntity; +import mos.mosback.repository.ToDoRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +@RequiredArgsConstructor +@Service +public class ToDoService { + + private final ToDoRepository toDoRepository; + @Transactional + public ToDoEntity add(String todoContent) { + ToDoEntity toDoEntity = new ToDoEntity(todoContent, false); + return toDoRepository.save(toDoEntity); + } + + + @Transactional + public ToDoEntity update(Long todoId, String todoContent, boolean completed) { + ToDoEntity toDoEntity = toDoRepository.findById(todoId) + .orElseThrow(() -> new IllegalArgumentException("해당 ToDo를 찾을 수 없습니다.")); + + toDoEntity.updateToDo(todoContent, completed); + return toDoEntity; + } + + @Transactional + public void delete(Long todoId) { + ToDoEntity toDoEntity = toDoRepository.findById(todoId) + .orElseThrow(() -> new IllegalArgumentException("해당 ToDo를 찾을 수 없습니다.")); + + toDoRepository.delete(toDoEntity); + } + + +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/service/UserService.java b/src/main/java/mos/mosback/service/UserService.java deleted file mode 100644 index b913b3d..0000000 --- a/src/main/java/mos/mosback/service/UserService.java +++ /dev/null @@ -1,10 +0,0 @@ -package mos.mosback.service; - -import mos.mosback.web.dto.UserInfoDto; - -public interface UserService { - - void save(UserInfoDto userInfoDto); - - boolean checkEmailDuplicate(String email); -} diff --git a/src/main/java/mos/mosback/service/UserServiceImpl.java b/src/main/java/mos/mosback/service/UserServiceImpl.java deleted file mode 100644 index d2e457a..0000000 --- a/src/main/java/mos/mosback/service/UserServiceImpl.java +++ /dev/null @@ -1,29 +0,0 @@ -package mos.mosback.service; - -import mos.mosback.repository.UserInfo; -import mos.mosback.repository.UserRepository; -import mos.mosback.web.dto.UserInfoDto; -import org.springframework.stereotype.Service; - -@Service -public class UserServiceImpl implements UserService { - - private final UserRepository UserRepository; - - public UserServiceImpl(UserRepository UserRepository) { - this.UserRepository = UserRepository; - } - - @Override - public void save(UserInfoDto userInfoDto) { - UserInfo userInfo = new UserInfo(); - userInfo.setEmail(userInfoDto.getEmail()); - userInfo.setPassword(userInfoDto.getPassword()); - UserRepository.save(userInfo); - } - - @Override - public boolean checkEmailDuplicate(String email) { - return UserRepository.existsByEmail(email); - } -} diff --git a/src/main/java/mos/mosback/web/dto/HomeResponseDto.java b/src/main/java/mos/mosback/web/dto/HomeResponseDto.java deleted file mode 100644 index 865a857..0000000 --- a/src/main/java/mos/mosback/web/dto/HomeResponseDto.java +++ /dev/null @@ -1,4 +0,0 @@ -package mos.mosback.web.dto; - -public class HomeResponseDto { -} diff --git a/src/main/java/mos/mosback/web/dto/Home_RoomResponseDto.java b/src/main/java/mos/mosback/web/dto/Home_RoomResponseDto.java new file mode 100644 index 0000000..92b1eac --- /dev/null +++ b/src/main/java/mos/mosback/web/dto/Home_RoomResponseDto.java @@ -0,0 +1,29 @@ +package mos.mosback.web.dto; +import lombok.Getter; +import mos.mosback.domain.posts.StRoomEntity; +import java.util.Date; + + +@Getter +public class Home_RoomResponseDto { + + private String title; + private String category; // 스터디 카테고리 + private int memberNum; //현재 멤버수 + private int maxMember; //모집 멤버수 + private String location; + private int online; //온라인 + private Date deadline ; //스터디 모집 마감날짜 + + //+ 유저프로필사진 + + public Home_RoomResponseDto(StRoomEntity entity) { + this.title = entity.getTitle(); + this.deadline = entity.getDeadline(); + this.location = entity.getLocation(); + this.online = entity.getOnline(); + this.category = entity.getCategory(); + this.memberNum = entity.getMemberNum(); + this.maxMember = entity.getMaxMember(); + } +} diff --git a/src/main/java/mos/mosback/web/dto/StRoomListResponseDto.java b/src/main/java/mos/mosback/web/dto/StRoomListResponseDto.java index f834ada..a861c19 100644 --- a/src/main/java/mos/mosback/web/dto/StRoomListResponseDto.java +++ b/src/main/java/mos/mosback/web/dto/StRoomListResponseDto.java @@ -16,28 +16,42 @@ public class StRoomListResponseDto { private String quest; private String category; // 스터디 카테고리 private String intro; //스터디 소개 - private int num; //멤버수 + private int memberNum; //멤버수 + private int maxMember; private String mod; //스터디 분위기 private int click;// 클릭횟수 (인기순 조회) private boolean onOff; //진행방식 (온오프) private Date startDate; //스터디 시작 날짜 private Date endDate; //스터디 끝나는 날짜 - private Date createDate; // 스터디룸 생성 날짜 + private Date deadline; + private String location; + private int online; //온라인 + private List studyDayEntities; public StRoomListResponseDto(StRoomEntity entity) { - this.roomID = entity.getRoomID(); + this.title = entity.getTitle(); this.goal = entity.getGoal(); this.rules = entity.getRules(); this.quest =entity.getQuest(); this.category =entity.getCategory(); this.intro =entity.getIntro(); - this.num = entity.getNum(); + this.memberNum = entity.getMemberNum(); + this.maxMember = entity.getMaxMember(); this.mod = entity.getMod(); this.onOff = entity.isOnOff(); this.startDate = entity.getStartDate(); this.endDate = entity.getEndDate(); this.studyDayEntities = entity.getStudyDayEntities(); } -} + public StRoomListResponseDto(Home_RoomResponseDto homeRoomResponseDto) { + this.title = homeRoomResponseDto.getTitle(); + this.deadline = homeRoomResponseDto.getDeadline(); + this.location = homeRoomResponseDto.getLocation(); + this.online = homeRoomResponseDto.getOnline(); + this.category = homeRoomResponseDto.getCategory(); + this.memberNum = homeRoomResponseDto.getMemberNum(); + this.maxMember = homeRoomResponseDto.getMaxMember(); + } +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/web/dto/StRoomResponseDto.java b/src/main/java/mos/mosback/web/dto/StRoomResponseDto.java index e900730..6f9e816 100644 --- a/src/main/java/mos/mosback/web/dto/StRoomResponseDto.java +++ b/src/main/java/mos/mosback/web/dto/StRoomResponseDto.java @@ -9,33 +9,28 @@ @Getter public class StRoomResponseDto { - Long roomID; private String title; private String goal; //스터디 목표 private String rules; //스터디 규칙 - private String quest; private String category; // 스터디 카테고리 - private String intro; //스터디 소개 - private int num; //멤버수 + private int memberNum; //현재 멤버수 private String mod; //스터디 분위기 - private int click;// 클릭횟수 (인기순 조회) private boolean onOff; //진행방식 (온오프) private Date startDate; //스터디 시작 날짜 private Date endDate; //스터디 끝나는 날짜 - private Date createDate; // 스터디룸 생성 날짜 private List studyDayEntities; + /*유저프로필 + 사진*/ public StRoomResponseDto(StRoomEntity entity) { + this.roomID = entity.getRoomID(); this.title = entity.getTitle(); this.goal = entity.getGoal(); this.rules = entity.getRules(); - this.quest =entity.getQuest(); this.category =entity.getCategory(); - this.intro =entity.getIntro(); - this.num = entity.getNum(); + this.memberNum = entity.getMemberNum(); this.mod = entity.getMod(); this.onOff = entity.isOnOff(); this.startDate = entity.getStartDate(); @@ -43,7 +38,7 @@ public StRoomResponseDto(StRoomEntity entity) { this.studyDayEntities =entity.getStudyDayEntities(); - } + } //스터디 + 투두 리스트의 스터디룸 상세화면 } //Entity의 필드 이루만 사용하므로 생성자로 Entity를 받아 필드에 값을 넣어줌 //상세정보에 노출 될 필드 \ No newline at end of file diff --git a/src/main/java/mos/mosback/web/dto/StRoomSaveRequestDto.java b/src/main/java/mos/mosback/web/dto/StRoomSaveRequestDto.java index bf4396e..5481a04 100644 --- a/src/main/java/mos/mosback/web/dto/StRoomSaveRequestDto.java +++ b/src/main/java/mos/mosback/web/dto/StRoomSaveRequestDto.java @@ -17,9 +17,11 @@ public class StRoomSaveRequestDto { private String quest; //생성 시 질문 private String category; // 스터디 카테고리 private String intro; //스터디 소개 - private int num; //멤버수 + private int maxMember; private String mod; //스터디 분위기 private boolean onOff; //진행방식 (온오프) + private String location; //스터디 장소 + private int online; // 온라인일 경우 1 : 줌 2 : 디코 3: 구글미트 4: 기타 private Date startDate; //스터디 시작 날짜 private Date endDate; //스터디 끝나는 날짜 private List studyDayEntities; @@ -27,8 +29,8 @@ public class StRoomSaveRequestDto { @Builder public StRoomSaveRequestDto(String title, String goal, String rules, String quest, String category, - String intro, int num, String mod, boolean onOff, Date startDate, - Date endDate,List studyDayEntities) { + String intro, int maxMember, String mod, boolean onOff,String location,int online, + Date startDate, Date endDate,List studyDayEntities) { this.title = title; this.goal = goal; this.rules = rules; @@ -36,8 +38,10 @@ public StRoomSaveRequestDto(String title, String goal, String rules, String ques this.category = category; this.intro = intro; this.mod = mod; - this.num = num; + this.maxMember = maxMember; this.onOff = onOff; + this.location = location; + this.online = online; this.startDate = startDate; this.endDate = endDate; this.studyDayEntities = studyDayEntities; @@ -53,11 +57,13 @@ public StRoomEntity toEntity() { .category(category) .intro(intro) .mod(mod) - .num(num) + .maxMember(maxMember) .onOff(onOff) + .location(location) + .online(online) .startDate(startDate) .endDate(endDate) .studyDayEntities(studyDayEntities) .build(); } -} +} //스터디 수정 시 생성 필드에 들어가는 내용수정 diff --git a/src/main/java/mos/mosback/web/dto/StRoomUpdateRequestDto.java b/src/main/java/mos/mosback/web/dto/StRoomUpdateRequestDto.java index 90c1a49..d4f7ade 100644 --- a/src/main/java/mos/mosback/web/dto/StRoomUpdateRequestDto.java +++ b/src/main/java/mos/mosback/web/dto/StRoomUpdateRequestDto.java @@ -1,7 +1,7 @@ package mos.mosback.web.dto; - +import lombok.Builder; import lombok.Getter; -import mos.mosback.domain.posts.StRoomEntity; +import lombok.NoArgsConstructor; import mos.mosback.domain.posts.StudyDaysEntity; import java.util.Date; @@ -9,42 +9,46 @@ @Getter +@NoArgsConstructor public class StRoomUpdateRequestDto { - + Long roomID; private String title; private String goal; //스터디 목표 private String rules; //스터디 규칙 - private String quest; + private String quest; //생성 시 질문 private String category; // 스터디 카테고리 private String intro; //스터디 소개 - private int num; //멤버수 + private int maxMember; // 모집 멤버수 private String mod; //스터디 분위기 - private int click;// 클릭횟수 (인기순 조회) private boolean onOff; //진행방식 (온오프) + private String location; //스터디 장소 + private int online; // 온라인일 경우 1 : 줌 2 : 디코 3: 구글미트 4: 기타 private Date startDate; //스터디 시작 날짜 private Date endDate; //스터디 끝나는 날짜 - private Date createDate; // 스터디룸 생성 날짜 private List studyDayEntities; - public StRoomUpdateRequestDto(StRoomEntity entity) { - - this.title = entity.getTitle(); - this.goal = entity.getGoal(); - this.rules = entity.getRules(); - this.quest =entity.getQuest(); - this.category =entity.getCategory(); - this.intro =entity.getIntro(); - this.num = entity.getNum(); - this.mod = entity.getMod(); - this.onOff = entity.isOnOff(); - this.startDate = entity.getStartDate(); - this.endDate = entity.getEndDate(); - this.studyDayEntities =entity.getStudyDayEntities(); - + @Builder + public StRoomUpdateRequestDto(String title, String goal, String rules, String quest, String category, + String intro, int maxMember ,String mod, boolean onOff,String location,int online, + Date startDate, Date endDate, List studyDayEntities) { + this.title = title; + this.goal = goal; + this.rules = rules; + this.quest = quest; + this.category = category; + this.intro = intro; + this.mod = mod; + this.maxMember = maxMember; + this.onOff = onOff; + this.location = location; + this.online = online; + this.startDate = startDate; + this.endDate = endDate; + this.studyDayEntities = studyDayEntities; } -} +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/web/dto/ToDoRequestDto.java b/src/main/java/mos/mosback/web/dto/ToDoRequestDto.java index 07b9f62..a2b72b9 100644 --- a/src/main/java/mos/mosback/web/dto/ToDoRequestDto.java +++ b/src/main/java/mos/mosback/web/dto/ToDoRequestDto.java @@ -26,4 +26,4 @@ public ToDoEntity toEntity() { .build(); } -} +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/web/dto/ToDoResponseDto.java b/src/main/java/mos/mosback/web/dto/ToDoResponseDto.java index 6fc5f01..94930f2 100644 --- a/src/main/java/mos/mosback/web/dto/ToDoResponseDto.java +++ b/src/main/java/mos/mosback/web/dto/ToDoResponseDto.java @@ -13,4 +13,4 @@ public ToDoResponseDto(ToDoEntity entity) { this.todoContent = getTodoContent(); this.completed = isCompleted(); } -} +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/web/dto/UserInfoDto.java b/src/main/java/mos/mosback/web/dto/UserInfoDto.java deleted file mode 100644 index d922c5f..0000000 --- a/src/main/java/mos/mosback/web/dto/UserInfoDto.java +++ /dev/null @@ -1,26 +0,0 @@ -package mos.mosback.web.dto; - -public class UserInfoDto { - - private String email; - private String password; - - // 생성자, 게터/세터 등 생략 - - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } -} From 1e478ed7d1bbae1b7000fc20da50f81e8bc9b7f9 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Thu, 14 Sep 2023 14:28:39 +0900 Subject: [PATCH 10/60] 0914 --- .../Filter/JwtAuthenticationFilter.java | 34 ------ .../mosback/Provider/JwtTokenProvider.java | 81 ------------- .../mos/mosback/config/EncryptionUtils.java | 28 ----- .../java/mos/mosback/config/MailConfig.java | 37 ------ .../java/mos/mosback/data/entity/User.java | 107 ------------------ 5 files changed, 287 deletions(-) delete mode 100644 src/main/java/mos/mosback/Filter/JwtAuthenticationFilter.java delete mode 100644 src/main/java/mos/mosback/Provider/JwtTokenProvider.java delete mode 100644 src/main/java/mos/mosback/config/EncryptionUtils.java delete mode 100644 src/main/java/mos/mosback/config/MailConfig.java delete mode 100644 src/main/java/mos/mosback/data/entity/User.java diff --git a/src/main/java/mos/mosback/Filter/JwtAuthenticationFilter.java b/src/main/java/mos/mosback/Filter/JwtAuthenticationFilter.java deleted file mode 100644 index 7de1310..0000000 --- a/src/main/java/mos/mosback/Filter/JwtAuthenticationFilter.java +++ /dev/null @@ -1,34 +0,0 @@ -package mos.mosback.Filter; - -import mos.mosback.Provider.JwtTokenProvider; -import lombok.RequiredArgsConstructor; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.web.filter.GenericFilterBean; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import java.io.IOException; - -@RequiredArgsConstructor -public class JwtAuthenticationFilter extends GenericFilterBean { - - private final JwtTokenProvider jwtTokenProvider; - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - // 헤더에서 JWT 를 받아옵니다. - String token = jwtTokenProvider.resolveToken((HttpServletRequest) request); - // 유효한 토큰인지 확인합니다. - if (token != null && jwtTokenProvider.validateToken(token)) { - // 토큰이 유효하면 토큰으로부터 유저 정보를 받아옵니다. - Authentication authentication = jwtTokenProvider.getAuthentication(token); - // SecurityContext 에 Authentication 객체를 저장합니다. - SecurityContextHolder.getContext().setAuthentication(authentication); - } - chain.doFilter(request, response); - } -} \ No newline at end of file diff --git a/src/main/java/mos/mosback/Provider/JwtTokenProvider.java b/src/main/java/mos/mosback/Provider/JwtTokenProvider.java deleted file mode 100644 index ae33c81..0000000 --- a/src/main/java/mos/mosback/Provider/JwtTokenProvider.java +++ /dev/null @@ -1,81 +0,0 @@ -package mos.mosback.Provider; - -import io.jsonwebtoken.Claims; -import io.jsonwebtoken.Jws; -import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.SignatureAlgorithm; -import io.jsonwebtoken.security.Keys; -import lombok.RequiredArgsConstructor; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.stereotype.Component; - -import javax.annotation.PostConstruct; -import javax.servlet.http.HttpServletRequest; -import java.security.Key; -import java.util.Base64; -import java.util.Date; - -@RequiredArgsConstructor -@Component -public class JwtTokenProvider { - private static Key secretKey; // Key 타입으로 변경 - - // 토큰 유효시간 30분 - private static long tokenValidTime = 60 * 60 * 1000L; - - private final UserDetailsService userDetailsService; - - // 객체 초기화, secretKey를 Base64로 인코딩한다. - @PostConstruct - protected void init() { - secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256); - } - - // JWT 토큰 생성 - public static String createToken(String userPk, String userPassword) { - Claims claims = Jwts.claims().setSubject(userPk); // JWT payload 에 저장되는 정보단위, 보통 여기서 user를 식별하는 값을 넣는다. - claims.put("password", userPassword); // 정보는 key / value 쌍으로 저장된다. - Date now = new Date(); - return Jwts.builder() - .setClaims(claims) // 정보 저장 - .setIssuedAt(now) // 토큰 발행 시간 정보 - .setExpiration(new Date(now.getTime() + tokenValidTime)) // set Expire Time - .signWith(secretKey, SignatureAlgorithm.HS256) // 사용할 암호화 알고리즘과 - // signature 에 들어갈 secret값 세팅 - .compact(); - } - -// private String token; - //JWT 검증 -// Jws claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token); - - - // JWT 토큰에서 인증 정보 조회 - public Authentication getAuthentication(String token) { - UserDetails userDetails = userDetailsService.loadUserByUsername(this.getUserPk(token)); - return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities()); - } - - // 토큰에서 회원 정보 추출 - public String getUserPk(String token) { - return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getSubject(); - } - - // Request의 Header에서 token 값을 가져옵니다. "Authorization" : "TOKEN값' - public String resolveToken(HttpServletRequest request) { - return request.getHeader("Authorization"); - } - - // 토큰의 유효성 + 만료일자 확인 - public boolean validateToken(String jwtToken) { - try { - Jws claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(jwtToken); - return !claims.getBody().getExpiration().before(new Date()); - } catch (Exception e) { - return false; - } - } -} \ No newline at end of file diff --git a/src/main/java/mos/mosback/config/EncryptionUtils.java b/src/main/java/mos/mosback/config/EncryptionUtils.java deleted file mode 100644 index 8c9dcad..0000000 --- a/src/main/java/mos/mosback/config/EncryptionUtils.java +++ /dev/null @@ -1,28 +0,0 @@ -package mos.mosback.config; - -import java.security.MessageDigest; - -public class EncryptionUtils { - - public static String encryptSHA256(String s) { - return encrypt(s, "SHA-256"); - } - - public static String encryptMD5(String s) { - return encrypt(s, "MD5"); - } - - public static String encrypt(String s, String messageDigest) { - try { - MessageDigest md = MessageDigest.getInstance(messageDigest); - byte[] passBytes = s.getBytes(); - md.reset(); - byte[] digested = md.digest(passBytes); - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < digested.length; i++) sb.append(Integer.toString((digested[i]&0xff) + 0x100, 16).substring(1)); - return sb.toString(); - } catch (Exception e) { - return s; - } - } -} diff --git a/src/main/java/mos/mosback/config/MailConfig.java b/src/main/java/mos/mosback/config/MailConfig.java deleted file mode 100644 index 2613b5e..0000000 --- a/src/main/java/mos/mosback/config/MailConfig.java +++ /dev/null @@ -1,37 +0,0 @@ -package mos.mosback.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.mail.javamail.JavaMailSender; -import org.springframework.mail.javamail.JavaMailSenderImpl; - -import java.util.Properties; - -@Configuration -public class MailConfig { - @Bean - public JavaMailSender javaMailService() { - JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl(); - - javaMailSender.setHost("smtp.naver.com"); - javaMailSender.setUsername("dmsthf1225@naver.com"); - javaMailSender.setPassword("dmsthf12fkqb"); - - javaMailSender.setPort(465); - - javaMailSender.setJavaMailProperties(getMailProperties()); - - return javaMailSender; - } - - private Properties getMailProperties() { - Properties properties = new Properties(); - properties.setProperty("mail.transport.protocol", "smtp"); - properties.setProperty("mail.smtp.auth", "true"); - properties.setProperty("mail.smtp.starttls.enable", "true"); - properties.setProperty("mail.debug", "true"); - properties.setProperty("mail.smtp.ssl.trust","smtp.naver.com"); - properties.setProperty("mail.smtp.ssl.enable","true"); - return properties; - } -} \ No newline at end of file diff --git a/src/main/java/mos/mosback/data/entity/User.java b/src/main/java/mos/mosback/data/entity/User.java deleted file mode 100644 index 4458499..0000000 --- a/src/main/java/mos/mosback/data/entity/User.java +++ /dev/null @@ -1,107 +0,0 @@ -package mos.mosback.data.entity; - -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import mos.mosback.web.dto.UserUpdateDTO; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; - -import javax.persistence.*; -import java.util.Collection; -import java.util.Date; - -@Entity -@Table(name = "user") -@NoArgsConstructor -@Getter -@Setter -public class User implements UserDetails { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(nullable = false, unique = true) - private String email; - - @Column(nullable = false) - private String password; - - @Column(nullable = false) - private String name; - - @Column(nullable = false) - private String nickname; - - @Column(nullable = false) - private Date duration; - - @Column(nullable = false) - private String message; - - @Column(nullable = false) - private String company; - - @Builder - public User(String email, String password, String name, String nickname, Date duration, String message, String company){ - this.email = email; - this.password = cryptopassword(password); - this.name = name; - this.nickname = nickname; - this.duration = duration; - this.message = message; - this.company = company; - } - - public void update(UserUpdateDTO userUpdateDTO) { - this.email = userUpdateDTO.getEmail(); - this.password = cryptopassword(userUpdateDTO.getPassword()); - this.name = userUpdateDTO.getName(); - this.nickname = userUpdateDTO.getNickname(); - this.duration = userUpdateDTO.getDuration(); - this.message = userUpdateDTO.getMessage(); - this.company = userUpdateDTO.getCompany(); - } - - public void updatePw(String password) { - this.password = cryptopassword(password); - } - - public String cryptopassword(String password) { - BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); - String encodedPassword = passwordEncoder.encode(password); - return encodedPassword; - } - - @Override - public Collection getAuthorities() { - return null; - } - - @Override - public String getUsername() { - return getEmail(); - } - - @Override - public boolean isAccountNonExpired() { - return false; - } - - @Override - public boolean isAccountNonLocked() { - return false; - } - - @Override - public boolean isCredentialsNonExpired() { - return false; - } - - @Override - public boolean isEnabled() { - return false; - } -} From 2ff337b4ec54b49f4fac789db00fb7b962746121 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Sun, 17 Sep 2023 15:51:26 +0900 Subject: [PATCH 11/60] 0914 --- .../Filter/JwtAuthenticationFilter.java | 34 +++++ .../mosback/Provider/JwtTokenProvider.java | 75 ++++++++++ .../mos/mosback/config/EncryptionUtils.java | 28 ++++ .../java/mos/mosback/config/MailConfig.java | 37 +++++ .../mosback/controller/HomeController.java | 0 .../mosback/controller/StRoomController.java | 10 ++ .../mosback/controller/UserController.java | 86 ++++++++++++ .../java/mos/mosback/data/entity/User.java | 114 +++++++++++++++ .../mos/mosback/domain/posts/HomeEntity.java | 4 - .../mosback/domain/posts/MemberStatus.java | 8 ++ .../mosback/domain/posts/StRoomEntity.java | 14 +- .../domain/posts/StudyMemberEntity.java | 35 +++++ .../mosback/repository/HomeRepository.java | 13 -- .../mosback/repository/StRoomRepository.java | 1 + .../repository/StudyMemberRepository.java | 8 ++ .../java/mos/mosback/repository/UserInfo.java | 42 ------ .../mosback/repository/UserRepository.java | 29 +++- .../java/mos/mosback/service/HomeService.java | 5 - .../mos/mosback/service/StRoomService.java | 14 ++ .../java/mos/mosback/service/UserService.java | 131 ++++++++++++++++++ .../java/mos/mosback/web/dto/FindPWDTO.java | 9 ++ .../mosback/web/dto/Home_RoomResponseDto.java | 1 + .../mosback/web/dto/Home_nickResponseDto.java | 14 ++ .../java/mos/mosback/web/dto/LoginDTO.java | 12 ++ .../java/mos/mosback/web/dto/MailDTO.java | 14 ++ .../java/mos/mosback/web/dto/QuestionDto.java | 12 ++ .../java/mos/mosback/web/dto/SignUpDTO.java | 31 +++++ .../web/dto/StRoomMemberJoinRequestDto.java | 14 ++ .../java/mos/mosback/web/dto/UserInfoDto.java | 26 ++++ .../mos/mosback/web/dto/UserUpdateDTO.java | 18 +++ 30 files changed, 770 insertions(+), 69 deletions(-) create mode 100644 src/main/java/mos/mosback/Filter/JwtAuthenticationFilter.java create mode 100644 src/main/java/mos/mosback/Provider/JwtTokenProvider.java create mode 100644 src/main/java/mos/mosback/config/EncryptionUtils.java create mode 100644 src/main/java/mos/mosback/config/MailConfig.java delete mode 100644 src/main/java/mos/mosback/controller/HomeController.java create mode 100644 src/main/java/mos/mosback/controller/UserController.java create mode 100644 src/main/java/mos/mosback/data/entity/User.java delete mode 100644 src/main/java/mos/mosback/domain/posts/HomeEntity.java create mode 100644 src/main/java/mos/mosback/domain/posts/MemberStatus.java create mode 100644 src/main/java/mos/mosback/domain/posts/StudyMemberEntity.java delete mode 100644 src/main/java/mos/mosback/repository/HomeRepository.java create mode 100644 src/main/java/mos/mosback/repository/StudyMemberRepository.java delete mode 100644 src/main/java/mos/mosback/repository/UserInfo.java delete mode 100644 src/main/java/mos/mosback/service/HomeService.java create mode 100644 src/main/java/mos/mosback/service/UserService.java create mode 100644 src/main/java/mos/mosback/web/dto/FindPWDTO.java create mode 100644 src/main/java/mos/mosback/web/dto/Home_nickResponseDto.java create mode 100644 src/main/java/mos/mosback/web/dto/LoginDTO.java create mode 100644 src/main/java/mos/mosback/web/dto/MailDTO.java create mode 100644 src/main/java/mos/mosback/web/dto/QuestionDto.java create mode 100644 src/main/java/mos/mosback/web/dto/SignUpDTO.java create mode 100644 src/main/java/mos/mosback/web/dto/StRoomMemberJoinRequestDto.java create mode 100644 src/main/java/mos/mosback/web/dto/UserInfoDto.java create mode 100644 src/main/java/mos/mosback/web/dto/UserUpdateDTO.java diff --git a/src/main/java/mos/mosback/Filter/JwtAuthenticationFilter.java b/src/main/java/mos/mosback/Filter/JwtAuthenticationFilter.java new file mode 100644 index 0000000..302aef2 --- /dev/null +++ b/src/main/java/mos/mosback/Filter/JwtAuthenticationFilter.java @@ -0,0 +1,34 @@ +package mos.mosback.Filter; + +import mos.mosback.Provider.JwtTokenProvider; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.filter.GenericFilterBean; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; + +@RequiredArgsConstructor +public class JwtAuthenticationFilter extends GenericFilterBean { + + private final JwtTokenProvider jwtTokenprovider; + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + // 헤더에서 JWT 를 받아옵니다. + String token = jwtTokenprovider.resolveToken((HttpServletRequest) request); + // 유효한 토큰인지 확인합니다. + if (token != null && jwtTokenprovider.validateToken(token)) { + // 토큰이 유효하면 토큰으로부터 유저 정보를 받아옵니다. + Authentication authentication = jwtTokenprovider.getAuthentication(token); + // SecurityContext 에 Authentication 객체를 저장합니다. + SecurityContextHolder.getContext().setAuthentication(authentication); + } + chain.doFilter(request, response); + } +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/Provider/JwtTokenProvider.java b/src/main/java/mos/mosback/Provider/JwtTokenProvider.java new file mode 100644 index 0000000..85bd5ff --- /dev/null +++ b/src/main/java/mos/mosback/Provider/JwtTokenProvider.java @@ -0,0 +1,75 @@ +package mos.mosback.Provider; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jws; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; +import lombok.RequiredArgsConstructor; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.servlet.http.HttpServletRequest; +import java.security.Key; +import java.util.Date; + +@RequiredArgsConstructor +@Component +public class JwtTokenProvider { + private static Key secretKey; // Key 타입으로 변경 + + // 토큰 유효시간 30분 + private static long tokenValidTime = 60 * 60 * 1000L; + + private final UserDetailsService userDetailsService; + + // 객체 초기화, secretKey를 Base64로 인코딩한다. + @PostConstruct + protected void init() { + secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256); + } + + // JWT 토큰 생성 + public static String createToken(String userPk, String userPassword) { + Claims claims = Jwts.claims().setSubject(userPk); // JWT payload 에 저장되는 정보단위, 보통 여기서 user를 식별하는 값을 넣는다. + claims.put("password", userPassword); // 정보는 key / value 쌍으로 저장된다. + Date now = new Date(); + return Jwts.builder() + .setClaims(claims) // 정보 저장 + .setIssuedAt(now) // 토큰 발행 시간 정보 + .setExpiration(new Date(now.getTime() + tokenValidTime)) // set Expire Time + .signWith(secretKey, SignatureAlgorithm.HS256) // 사용할 암호화 알고리즘과 + // signature 에 들어갈 secret값 세팅 + .compact(); + } + + // JWT 토큰에서 인증 정보 조회 + public Authentication getAuthentication(String token) { + UserDetails userDetails = userDetailsService.loadUserByUsername(this.getUserPk(token)); + return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities()); + } + + // 토큰에서 회원 정보 추출 + public String getUserPk(String token) { + return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getSubject(); + } + + // Request의 Header에서 token 값을 가져옵니다. "Authorization" : "TOKEN값' + public String resolveToken(HttpServletRequest request) { + return request.getHeader("Authorization"); + } + + // 토큰의 유효성 + 만료일자 확인 + public boolean validateToken(String jwtToken) { + try { + Jws claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(jwtToken); + return !claims.getBody().getExpiration().before(new Date()); + } catch (Exception e) { + return false; + } + } +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/config/EncryptionUtils.java b/src/main/java/mos/mosback/config/EncryptionUtils.java new file mode 100644 index 0000000..f100125 --- /dev/null +++ b/src/main/java/mos/mosback/config/EncryptionUtils.java @@ -0,0 +1,28 @@ +package mos.mosback.config; + +import java.security.MessageDigest; + +public class EncryptionUtils { + + public static String encryptSHA256(String s) { + return encrypt(s, "SHA-256"); + } + + public static String encryptMD5(String s) { + return encrypt(s, "MD5"); + } + + public static String encrypt(String s, String messageDigest) { + try { + MessageDigest md = MessageDigest.getInstance(messageDigest); + byte[] passBytes = s.getBytes(); + md.reset(); + byte[] digested = md.digest(passBytes); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < digested.length; i++) sb.append(Integer.toString((digested[i]&0xff) + 0x100, 16).substring(1)); + return sb.toString(); + } catch (Exception e) { + return s; + } + } +} diff --git a/src/main/java/mos/mosback/config/MailConfig.java b/src/main/java/mos/mosback/config/MailConfig.java new file mode 100644 index 0000000..86a262a --- /dev/null +++ b/src/main/java/mos/mosback/config/MailConfig.java @@ -0,0 +1,37 @@ +package mos.mosback.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.JavaMailSenderImpl; + +import java.util.Properties; + +@Configuration +public class MailConfig { + @Bean + public JavaMailSender javaMailService() { + JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl(); + + javaMailSender.setHost("smtp.naver.com"); + javaMailSender.setUsername("dmsthf1225@naver.com"); + javaMailSender.setPassword("dmsthf12fkqb"); + + javaMailSender.setPort(465); + + javaMailSender.setJavaMailProperties(getMailProperties()); + + return javaMailSender; + } + + private Properties getMailProperties() { + Properties properties = new Properties(); + properties.setProperty("mail.transport.protocol", "smtp"); + properties.setProperty("mail.smtp.auth", "true"); + properties.setProperty("mail.smtp.starttls.enable", "true"); + properties.setProperty("mail.debug", "true"); + properties.setProperty("mail.smtp.ssl.trust","smtp.naver.com"); + properties.setProperty("mail.smtp.ssl.enable","true"); + return properties; + } +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/controller/HomeController.java b/src/main/java/mos/mosback/controller/HomeController.java deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/mos/mosback/controller/StRoomController.java b/src/main/java/mos/mosback/controller/StRoomController.java index 04cb362..7f4839a 100644 --- a/src/main/java/mos/mosback/controller/StRoomController.java +++ b/src/main/java/mos/mosback/controller/StRoomController.java @@ -115,6 +115,14 @@ public ResponseEntity> getStudyRoomsByCategory(@PathVariable response.put("studyRooms", studyRooms); // 데이터를 직접 넣음 return ResponseEntity.ok(response); } + + @PostMapping("/memberjoin") + public ResponseEntity memberJoin(@RequestBody StRoomMemberJoinRequestDto requestDto) { + Long stroomId = stRoomService.memberJoin(requestDto); + return ResponseEntity.status(HttpStatus.CREATED).body("created successfully. ID: " + stroomId); + } + + } //핸들러 메서드 : // @@ -125,3 +133,5 @@ public ResponseEntity> getStudyRoomsByCategory(@PathVariable //deletestroom: 게시물을 삭제하는 엔드포인트. //getAllstrooms: 모든 게시물을 조회하는 엔드포인트. //getPopularstrooms: 조회순으로 게시물을 조회하는 엔드포인트. (인기순 조회시) +//memberjoin - 스터디 가입 API +//https://blog.pumpkin-raccoon.com/115#:~:text=1%201.%20%EB%B3%B5%EC%88%98%20%3E%20%EB%8B%A8%EC%88%98%20REST%20API%EC%97%90%EC%84%9C%EB%8A%94%20post%2C,%EC%BB%AC%EB%A0%89%EC%85%98%20%ED%95%84%ED%84%B0%EB%A7%81%3A%20URL%20%EC%BF%BC%EB%A6%AC%20%3E%20%EC%83%88%EB%A1%9C%EC%9A%B4%20API%20 \ No newline at end of file diff --git a/src/main/java/mos/mosback/controller/UserController.java b/src/main/java/mos/mosback/controller/UserController.java new file mode 100644 index 0000000..1ccef15 --- /dev/null +++ b/src/main/java/mos/mosback/controller/UserController.java @@ -0,0 +1,86 @@ +package mos.mosback.controller; + +import mos.mosback.data.entity.User; +import mos.mosback.repository.UserRepository; +import mos.mosback.service.UserService; +import mos.mosback.web.dto.*; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +import javax.transaction.Transactional; +import java.util.List; + +@Controller +@RequestMapping("/api") +public class UserController { + + + private UserService userService; + private UserRepository userRepository; + + public UserController(UserService userService, UserRepository userRepository) { + this.userService = userService; + this.userRepository = userRepository; + } + + //회원가입 + @PostMapping("/signup") + public ResponseEntity join(@RequestBody SignUpDTO signUpDTO) { + if(userService.isEmailDuplicate(signUpDTO.getEmail())) { + return ResponseEntity.status(400).body("Email already exists"); + } + userService.join(signUpDTO); + return ResponseEntity.ok("Join Success!"); + } + + //로그인 + @PostMapping("/login") + public ResponseEntity login(@RequestBody LoginDTO loginDTO) { + if(userService.isEmailDuplicate(loginDTO.getEmail())) { + if(userService.comparePassword(loginDTO.getEmail(),loginDTO.getPassword())) { + User user = userRepository.findByEmail(loginDTO.getEmail()); + if(user != null) { + return ResponseEntity.ok("로그인 성공"); + } + return ResponseEntity.status(400).body("사용자를 찾을 수 없습니다."); + } + return ResponseEntity.status(400).body("비밀번호가 틀렸습니다."); + } + return ResponseEntity.status(400).body("사용자를 찾을 수 없습니다."); + } + + //이메일 중복확인 + @GetMapping("/user-emails/{email}/exists") + public ResponseEntity isEmailDuplicate(@PathVariable String email){ + return ResponseEntity.ok(userService.isEmailDuplicate(email)); + } + + //비밀번호 변경 + @Transactional + @PostMapping("/find") + public ResponseEntity findPw(@RequestBody FindPWDTO findPWDTO){ + if(userService.findPassword(findPWDTO)) { + MailDTO mailDTO = userService.createMailAndChangePassword(findPWDTO.getEmail()); + userService.mailSend(mailDTO); + return ResponseEntity.ok("임시 비밀번호 메일 전송, 변경 완료"); + } + else{ + return ResponseEntity.status(400).body("이메일과 이름이 일치하지 않습니다."); + } + } + + @Transactional + @PostMapping("/send/Email") + public ResponseEntity sendEmail(@RequestParam("userEmail") String userEmail){ + MailDTO mailDTO = userService.createMailAndChangePassword(userEmail); + userService.mailSend(mailDTO); + + return ResponseEntity.ok("임시 비밀번호 메일 전송, 변경 완료"); + } + @GetMapping("get/nick") + public ResponseEntity> ReturnNickname() { + List nickname = userRepository.ReturnNickname(); + return ResponseEntity.ok(nickname); + } +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/data/entity/User.java b/src/main/java/mos/mosback/data/entity/User.java new file mode 100644 index 0000000..a087229 --- /dev/null +++ b/src/main/java/mos/mosback/data/entity/User.java @@ -0,0 +1,114 @@ +package mos.mosback.data.entity; + +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import mos.mosback.domain.posts.StRoomEntity; +import mos.mosback.web.dto.UserUpdateDTO; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; + +import javax.persistence.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; + +@Entity +@Table(name = "user") +@NoArgsConstructor +@Getter +@Setter +public class User implements UserDetails { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false, unique = true) + private String email; + + @Column(nullable = false) + private String password; + + @Column(nullable = false) + private String name; + + @Column(nullable = false) + private String nickname; + + @Column(nullable = false) + private Date duration; + + @Column(nullable = false) + private String message; + + @Column(nullable = false) + private String company; + + @ManyToOne + @JoinColumn(name = "roomID") + private StRoomEntity stRoom; + + @Builder + public User(String email, String password, String name, String nickname, Date duration, String message, String company){ + this.email = email; + this.password = cryptopassword(password); + this.name = name; + this.nickname = nickname; + this.duration = duration; + this.message = message; + this.company = company; + } + + public void update(UserUpdateDTO userUpdateDTO) { + this.email = userUpdateDTO.getEmail(); + this.password = cryptopassword(userUpdateDTO.getPassword()); + this.name = userUpdateDTO.getName(); + this.nickname = userUpdateDTO.getNickname(); + this.duration = userUpdateDTO.getDuration(); + this.message = userUpdateDTO.getMessage(); + this.company = userUpdateDTO.getCompany(); + } + + public void updatePw(String password) { + this.password = cryptopassword(password); + } + + public String cryptopassword(String password) { + BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + String encodedPassword = passwordEncoder.encode(password); + return encodedPassword; + } + + @Override + public Collection getAuthorities() { + return null; + } + + @Override + public String getUsername() { + return getEmail(); + } + + @Override + public boolean isAccountNonExpired() { + return false; + } + + @Override + public boolean isAccountNonLocked() { + return false; + } + + @Override + public boolean isCredentialsNonExpired() { + return false; + } + + @Override + public boolean isEnabled() { + return false; + } +} diff --git a/src/main/java/mos/mosback/domain/posts/HomeEntity.java b/src/main/java/mos/mosback/domain/posts/HomeEntity.java deleted file mode 100644 index 1e937c8..0000000 --- a/src/main/java/mos/mosback/domain/posts/HomeEntity.java +++ /dev/null @@ -1,4 +0,0 @@ -package mos.mosback.domain.posts; - -public class HomeEntity { -} diff --git a/src/main/java/mos/mosback/domain/posts/MemberStatus.java b/src/main/java/mos/mosback/domain/posts/MemberStatus.java new file mode 100644 index 0000000..63e708f --- /dev/null +++ b/src/main/java/mos/mosback/domain/posts/MemberStatus.java @@ -0,0 +1,8 @@ +package mos.mosback.domain.posts; + +public enum MemberStatus { + Leader, + Member, + Waiting, + Rejected + } diff --git a/src/main/java/mos/mosback/domain/posts/StRoomEntity.java b/src/main/java/mos/mosback/domain/posts/StRoomEntity.java index d36d3e8..94d673a 100644 --- a/src/main/java/mos/mosback/domain/posts/StRoomEntity.java +++ b/src/main/java/mos/mosback/domain/posts/StRoomEntity.java @@ -3,6 +3,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import mos.mosback.data.entity.User; import javax.persistence.*; import java.time.LocalDate; @@ -40,6 +41,13 @@ public class StRoomEntity extends BaseTimeEntity { private Date endDate; //스터디 끝나는 날짜 private Date deadline ; //스터디 모집 마감날짜 + @ManyToOne + @JoinColumn(name = "leader_id") // 리더와의 관계를 설정할 외래 키 컬럼 + private User leader; + + @ManyToOne + @JoinColumn(name = "User_nick") + private User nickname= new User().getStRoom().getNickname(); @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) private List studyDayEntities = new ArrayList<>(); @@ -48,7 +56,8 @@ public class StRoomEntity extends BaseTimeEntity { public StRoomEntity(String title, String goal, String rules, String quest, String category, String intro, int memberNum, int maxMember ,String mod, boolean onOff, String location,int online, - Date startDate, Date endDate, Date deadline ,List studyDayEntities) { + Date startDate, Date endDate, Date deadline , + List studyDayEntities,User leader,User nickname) { this.title = title; this.goal = goal; @@ -66,6 +75,8 @@ public StRoomEntity(String title, String goal, String rules, String quest, this.endDate = endDate; this.deadline = deadline; this.studyDayEntities = studyDayEntities; + this.leader = leader; + this.nickname= nickname; } @@ -89,6 +100,7 @@ public void update(String title, String goal, String rules, String quest, this.startDate = startDate; this.endDate = endDate; this.studyDayEntities = studyDayEntities; + this.leader = leader; } } \ No newline at end of file diff --git a/src/main/java/mos/mosback/domain/posts/StudyMemberEntity.java b/src/main/java/mos/mosback/domain/posts/StudyMemberEntity.java new file mode 100644 index 0000000..eb26713 --- /dev/null +++ b/src/main/java/mos/mosback/domain/posts/StudyMemberEntity.java @@ -0,0 +1,35 @@ +package mos.mosback.domain.posts; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import javax.persistence.*; + +@Getter // 롬복 어노테이션 +@Setter +@NoArgsConstructor // 롬복 어노테이션 (필수는 아님 그냥 코드 단순화용) +@Entity +public class StudyMemberEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long memberId; + + @Id + private Long roomID; + + // 다른 필드와 매핑 + + @Enumerated(EnumType.STRING) + private MemberStatus status; + + @Column + private String answer; // 스터디 답변 + + + @Builder + public StudyMemberEntity(MemberStatus status){ + this.status = status; + } + +} diff --git a/src/main/java/mos/mosback/repository/HomeRepository.java b/src/main/java/mos/mosback/repository/HomeRepository.java deleted file mode 100644 index 1d9737e..0000000 --- a/src/main/java/mos/mosback/repository/HomeRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package mos.mosback.repository; -import mos.mosback.domain.posts.StRoomEntity; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; - - -import java.util.List; - -public class HomeRepository { - - - -} diff --git a/src/main/java/mos/mosback/repository/StRoomRepository.java b/src/main/java/mos/mosback/repository/StRoomRepository.java index 14b7951..e02b7e5 100644 --- a/src/main/java/mos/mosback/repository/StRoomRepository.java +++ b/src/main/java/mos/mosback/repository/StRoomRepository.java @@ -3,6 +3,7 @@ //Entity 클래스와 Entity레파지토리 위치 같아야함 import mos.mosback.domain.posts.StRoomEntity; import mos.mosback.web.dto.Home_RoomResponseDto; +import mos.mosback.web.dto.Home_nickResponseDto; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; diff --git a/src/main/java/mos/mosback/repository/StudyMemberRepository.java b/src/main/java/mos/mosback/repository/StudyMemberRepository.java new file mode 100644 index 0000000..4673a76 --- /dev/null +++ b/src/main/java/mos/mosback/repository/StudyMemberRepository.java @@ -0,0 +1,8 @@ +package mos.mosback.repository; + +import mos.mosback.domain.posts.StudyMemberEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface StudyMemberRepository extends JpaRepository { + +} diff --git a/src/main/java/mos/mosback/repository/UserInfo.java b/src/main/java/mos/mosback/repository/UserInfo.java deleted file mode 100644 index 21c3629..0000000 --- a/src/main/java/mos/mosback/repository/UserInfo.java +++ /dev/null @@ -1,42 +0,0 @@ -package mos.mosback.repository; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; - -@Entity -public class UserInfo { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - private String email; - private String password; - - public Long getId() { - return id; - } - - public void setId(Long roomID) { - this.id = id; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } -// 생성자, 게터/세터 등 생략 -} \ No newline at end of file diff --git a/src/main/java/mos/mosback/repository/UserRepository.java b/src/main/java/mos/mosback/repository/UserRepository.java index f987924..6bfdd77 100644 --- a/src/main/java/mos/mosback/repository/UserRepository.java +++ b/src/main/java/mos/mosback/repository/UserRepository.java @@ -1,12 +1,33 @@ package mos.mosback.repository; +import mos.mosback.data.entity.User; +import mos.mosback.web.dto.Home_nickResponseDto; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import java.util.List; import java.util.Optional; -public interface UserRepository extends JpaRepository { - Optional findByEmail(String email); // 이메일 통해 회원 조회하기 위함 +public interface UserRepository extends JpaRepository { +// Optional findByEmail(String email); // 이메일 통해 회원 조회하기 위함 - boolean existsByEmail(String email); + + +// boolean existsByEmail(String email); + +// void saveUser(User user); + +// UserInfo findUserByUserId(String userEmail); + +// void updateUserPassword(Long id, String pw); // boolean existsByNickname(String nickname); -} \ No newline at end of file + + User findByEmail(String email); + Optional findById(Long id); + + @Query("SELECT new mos.mosback.web.dto.Home_nickResponseDto(u) FROM User u") + List ReturnNickname(); + @Query("SELECT new mos.mosback.web.dto.Home_nickResponseDto(u) FROM User u") + List ReturnNick(); + +} diff --git a/src/main/java/mos/mosback/service/HomeService.java b/src/main/java/mos/mosback/service/HomeService.java deleted file mode 100644 index f47fb02..0000000 --- a/src/main/java/mos/mosback/service/HomeService.java +++ /dev/null @@ -1,5 +0,0 @@ -package mos.mosback.service; - -public class HomeService { - -} diff --git a/src/main/java/mos/mosback/service/StRoomService.java b/src/main/java/mos/mosback/service/StRoomService.java index a879c87..3da2c0d 100644 --- a/src/main/java/mos/mosback/service/StRoomService.java +++ b/src/main/java/mos/mosback/service/StRoomService.java @@ -1,7 +1,10 @@ package mos.mosback.service; import lombok.RequiredArgsConstructor; +import mos.mosback.domain.posts.MemberStatus; import mos.mosback.domain.posts.StRoomEntity; +import mos.mosback.domain.posts.StudyMemberEntity; import mos.mosback.repository.StRoomRepository; +import mos.mosback.repository.StudyMemberRepository; import mos.mosback.web.dto.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -13,6 +16,7 @@ @Service public class StRoomService { private final StRoomRepository stRoomRepository; + private final StudyMemberRepository studyMemberRepository; @Transactional public Long save(StRoomSaveRequestDto requestDto){ @@ -82,4 +86,14 @@ public List findRoomsInHome() { public List findByCategory(String category) { return stRoomRepository.findByCategory(category); } + + public Long memberJoin(StRoomMemberJoinRequestDto requestDto) { + StudyMemberEntity studyMember = new StudyMemberEntity(); + studyMember.setRoomID(requestDto.getRoomID()); + studyMember.setStatus(MemberStatus.Waiting); + studyMember.setAnswer(requestDto.getAnswer()); + studyMember.setMemberId(); //세션값-멤버아이디 넣어주기 + studyMemberRepository.save(studyMember); + + } } \ No newline at end of file diff --git a/src/main/java/mos/mosback/service/UserService.java b/src/main/java/mos/mosback/service/UserService.java new file mode 100644 index 0000000..21f11d8 --- /dev/null +++ b/src/main/java/mos/mosback/service/UserService.java @@ -0,0 +1,131 @@ +package mos.mosback.service; +import lombok.RequiredArgsConstructor; +import mos.mosback.data.entity.User; +import mos.mosback.repository.UserRepository; +import mos.mosback.web.dto.*; +import org.springframework.mail.SimpleMailMessage; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.stereotype.Service; + +import javax.transaction.Transactional; +import java.util.List; +import java.util.Optional; + +@Service +@Transactional +@RequiredArgsConstructor +public class UserService implements UserDetailsService { + private final UserRepository userRepository; + private final JavaMailSender mailSender; + + public void join(SignUpDTO signUpDTO) { + userRepository.save(signUpDTO.toEntity()); + } + + public boolean isEmailDuplicate(String email) { + User findUser = userRepository.findByEmail(email); + return findUser != null; + } + + public User findByEmail(String email) { + return userRepository.findByEmail(email); + } + + public Optional getById(Long id) { + return userRepository.findById(id); + } + + public boolean comparePassword(String email,String password) { + User findUser = userRepository.findByEmail(email); + + BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + boolean isMatched = passwordEncoder.matches(password, findUser.getPassword()); + + if(isMatched) { + return true; + } + else{ + return false; + } + } + + public User updateUserInfo(User user, UserUpdateDTO userUpdateDTO) { + user.update(userUpdateDTO); + return user; + } + + public boolean findPassword(FindPWDTO findPWDTO) { + User user = userRepository.findByEmail(findPWDTO.getEmail()); + if(user.getName().equals(findPWDTO.getName())) { + return true; + } + else{ + return false; + } + } + + // 메일 내용을 생성하고 임시 비밀번호로 회원 비밀번호를 변경 + public MailDTO createMailAndChangePassword(String userEmail) { + String tempPassword = getTempPassword(); + MailDTO mailDTO = new MailDTO(); + mailDTO.setAddress(userEmail); + mailDTO.setTitle("취업어플리케이션 MOS의 임시비밀번호 안내 이메일 입니다."); + mailDTO.setMessage("안녕하세요. MOS의 임시비밀번호 안내 관련 이메일 입니다." + " 회원님의 임시 비밀번호는 " + + tempPassword + " 입니다." + "로그인 후에 비밀번호를 변경을 해주세요"); + updatePassword(tempPassword,userEmail); + return mailDTO; + } + + //임시 비밀번호로 업데이트 + public void updatePassword(String str, String userEmail){ + User user = userRepository.findByEmail(userEmail); + user.updatePw(str); + } + + //랜덤함수로 임시비밀번호 구문 만들기 + public String getTempPassword(){ + char[] charSet = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', + 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; + + String str = ""; + + // 문자 배열 길이의 값을 랜덤으로 10개를 뽑아 구문을 작성함 + int idx = 0; + for (int i = 0; i < 10; i++) { + idx = (int) (charSet.length * Math.random()); + str += charSet[idx]; + } + return str; + } + + // 메일보내기 + public void mailSend(MailDTO mailDTO) { + SimpleMailMessage message = new SimpleMailMessage(); + message.setTo(mailDTO.getAddress()); + message.setSubject(mailDTO.getTitle()); + message.setText(mailDTO.getMessage()); + message.setFrom("dmsthf1225@naver.com"); + message.setReplyTo("dmsthf1225@naver.com"); + mailSender.send(message); + } + + @Override + public UserDetails loadUserByUsername(String userEmail) throws UsernameNotFoundException { + return userRepository.findByEmail(userEmail); + } + + public void save(UserInfoDto userInfoDto) { + + } + + public List ReturnNickname() { + List nickname = userRepository.ReturnNickname(); + return nickname; + } + + +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/web/dto/FindPWDTO.java b/src/main/java/mos/mosback/web/dto/FindPWDTO.java new file mode 100644 index 0000000..f87a9c4 --- /dev/null +++ b/src/main/java/mos/mosback/web/dto/FindPWDTO.java @@ -0,0 +1,9 @@ +package mos.mosback.web.dto; + +import lombok.Getter; + +@Getter +public class FindPWDTO { + private String email; + private String name; +} diff --git a/src/main/java/mos/mosback/web/dto/Home_RoomResponseDto.java b/src/main/java/mos/mosback/web/dto/Home_RoomResponseDto.java index 92b1eac..aac9b22 100644 --- a/src/main/java/mos/mosback/web/dto/Home_RoomResponseDto.java +++ b/src/main/java/mos/mosback/web/dto/Home_RoomResponseDto.java @@ -25,5 +25,6 @@ public Home_RoomResponseDto(StRoomEntity entity) { this.category = entity.getCategory(); this.memberNum = entity.getMemberNum(); this.maxMember = entity.getMaxMember(); + } } diff --git a/src/main/java/mos/mosback/web/dto/Home_nickResponseDto.java b/src/main/java/mos/mosback/web/dto/Home_nickResponseDto.java new file mode 100644 index 0000000..9ca4efa --- /dev/null +++ b/src/main/java/mos/mosback/web/dto/Home_nickResponseDto.java @@ -0,0 +1,14 @@ +package mos.mosback.web.dto; +import mos.mosback.data.entity.User; +import lombok.Getter; + + +@Getter +public class Home_nickResponseDto { + private String nickname; + + public Home_nickResponseDto(User entity) + { + this.nickname = getNickname(); + } +} diff --git a/src/main/java/mos/mosback/web/dto/LoginDTO.java b/src/main/java/mos/mosback/web/dto/LoginDTO.java new file mode 100644 index 0000000..ea54211 --- /dev/null +++ b/src/main/java/mos/mosback/web/dto/LoginDTO.java @@ -0,0 +1,12 @@ +package mos.mosback.web.dto; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Getter +public class LoginDTO { + private String email; + private String password; + +} diff --git a/src/main/java/mos/mosback/web/dto/MailDTO.java b/src/main/java/mos/mosback/web/dto/MailDTO.java new file mode 100644 index 0000000..3b0ce2d --- /dev/null +++ b/src/main/java/mos/mosback/web/dto/MailDTO.java @@ -0,0 +1,14 @@ +package mos.mosback.web.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class MailDTO { + private String address; + private String title; + private String message; +} diff --git a/src/main/java/mos/mosback/web/dto/QuestionDto.java b/src/main/java/mos/mosback/web/dto/QuestionDto.java new file mode 100644 index 0000000..14cf739 --- /dev/null +++ b/src/main/java/mos/mosback/web/dto/QuestionDto.java @@ -0,0 +1,12 @@ +package mos.mosback.web.dto; +import mos.mosback.domain.posts.StRoomEntity; +import lombok.Getter; + +public class QuestionDto { + private String question; + + public QuestionDto(StRoomEntity entity) { + + this.question = entity.getQuest(); + } +} diff --git a/src/main/java/mos/mosback/web/dto/SignUpDTO.java b/src/main/java/mos/mosback/web/dto/SignUpDTO.java new file mode 100644 index 0000000..f8c6e14 --- /dev/null +++ b/src/main/java/mos/mosback/web/dto/SignUpDTO.java @@ -0,0 +1,31 @@ +package mos.mosback.web.dto; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import mos.mosback.data.entity.User; + +import java.util.Date; + +@Getter +@Setter +public class SignUpDTO { + private String email; + private String password; + private String name; + private String nickname; + private Date duration; + private String message; + private String company; + + public User toEntity() { + return User.builder() + .email(email) + .password(password) + .name(name) + .nickname(nickname) + .duration(duration) + .message(message) + .company(company) + .build(); + } +} diff --git a/src/main/java/mos/mosback/web/dto/StRoomMemberJoinRequestDto.java b/src/main/java/mos/mosback/web/dto/StRoomMemberJoinRequestDto.java new file mode 100644 index 0000000..1b95284 --- /dev/null +++ b/src/main/java/mos/mosback/web/dto/StRoomMemberJoinRequestDto.java @@ -0,0 +1,14 @@ +package mos.mosback.web.dto; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Setter +@Getter +@NoArgsConstructor +public class StRoomMemberJoinRequestDto { + private Long roomID; + private String answer; + + +} //스터디 수정 시 생성 필드에 들어가는 내용수정 diff --git a/src/main/java/mos/mosback/web/dto/UserInfoDto.java b/src/main/java/mos/mosback/web/dto/UserInfoDto.java new file mode 100644 index 0000000..d922c5f --- /dev/null +++ b/src/main/java/mos/mosback/web/dto/UserInfoDto.java @@ -0,0 +1,26 @@ +package mos.mosback.web.dto; + +public class UserInfoDto { + + private String email; + private String password; + + // 생성자, 게터/세터 등 생략 + + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } +} diff --git a/src/main/java/mos/mosback/web/dto/UserUpdateDTO.java b/src/main/java/mos/mosback/web/dto/UserUpdateDTO.java new file mode 100644 index 0000000..1c6d4d7 --- /dev/null +++ b/src/main/java/mos/mosback/web/dto/UserUpdateDTO.java @@ -0,0 +1,18 @@ +package mos.mosback.web.dto; + +import lombok.Getter; +import lombok.Setter; + +import java.util.Date; + +@Getter +@Setter +public class UserUpdateDTO { + private String email; + private String password; + private String name; + private String nickname; + private Date duration; + private String message; + private String company; +} From 05c698b8dc3ccc9604c461e32286e2794f7bd35f Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Sun, 17 Sep 2023 15:57:37 +0900 Subject: [PATCH 12/60] =?UTF-8?q?=EC=8A=A4=ED=84=B0=EB=94=94=EB=A3=B8=20?= =?UTF-8?q?=EA=B0=80=EC=9E=85=ED=95=98=EA=B8=B0=20(=EB=A9=A4=EB=B2=84=20?= =?UTF-8?q?=EC=95=84=EC=9D=B4=EB=94=94=20=EC=84=B8=EC=85=98=20=EB=A7=8C?= =?UTF-8?q?=EB=93=A4=EC=96=B4=EC=A3=BC=EC=84=B8=EC=9A=94)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mosback/controller/StRoomController.java | 4 +- .../mos/mosback/service/StRoomService.java | 38 +++++++++++-------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/main/java/mos/mosback/controller/StRoomController.java b/src/main/java/mos/mosback/controller/StRoomController.java index 7f4839a..ff812bf 100644 --- a/src/main/java/mos/mosback/controller/StRoomController.java +++ b/src/main/java/mos/mosback/controller/StRoomController.java @@ -118,8 +118,8 @@ public ResponseEntity> getStudyRoomsByCategory(@PathVariable @PostMapping("/memberjoin") public ResponseEntity memberJoin(@RequestBody StRoomMemberJoinRequestDto requestDto) { - Long stroomId = stRoomService.memberJoin(requestDto); - return ResponseEntity.status(HttpStatus.CREATED).body("created successfully. ID: " + stroomId); + stRoomService.memberJoin(requestDto); + return ResponseEntity.status(HttpStatus.CREATED).body("created successfully."); } diff --git a/src/main/java/mos/mosback/service/StRoomService.java b/src/main/java/mos/mosback/service/StRoomService.java index 3da2c0d..3294ac3 100644 --- a/src/main/java/mos/mosback/service/StRoomService.java +++ b/src/main/java/mos/mosback/service/StRoomService.java @@ -1,4 +1,5 @@ package mos.mosback.service; + import lombok.RequiredArgsConstructor; import mos.mosback.domain.posts.MemberStatus; import mos.mosback.domain.posts.StRoomEntity; @@ -8,6 +9,7 @@ import mos.mosback.web.dto.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; + import java.util.List; import java.util.stream.Collectors; @@ -19,7 +21,7 @@ public class StRoomService { private final StudyMemberRepository studyMemberRepository; @Transactional - public Long save(StRoomSaveRequestDto requestDto){ + public Long save(StRoomSaveRequestDto requestDto) { return stRoomRepository.save(requestDto.toEntity()).getRoomID(); } //스터디를 생성하고 아이디를 반환. @@ -32,20 +34,19 @@ public void update(Long roomID, StRoomUpdateRequestDto requestDto) { // 나머지 필드 업데이트 stroomEntity.update( requestDto.getTitle(), requestDto.getGoal(), requestDto.getRules(), - requestDto.getQuest(),requestDto.getCategory(), + requestDto.getQuest(), requestDto.getCategory(), requestDto.getIntro(), requestDto.getMaxMember(), requestDto.getMod(), requestDto.isOnOff(), requestDto.getLocation(), - requestDto.getOnline(),requestDto.getStartDate(), - requestDto.getEndDate(),requestDto.getStudyDayEntities()); + requestDto.getOnline(), requestDto.getStartDate(), + requestDto.getEndDate(), requestDto.getStudyDayEntities()); } //stroomsRepository를 사용하여 데이터베이스에서 주어진 id에 해당하는 게시물을 찾기 - @Transactional(readOnly = true) public StRoomResponseDto findById(Long roomID) { StRoomEntity stRoomEntity = stRoomRepository.findById(roomID) - .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id="+ roomID)); + .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id=" + roomID)); return new StRoomResponseDto(stRoomEntity); } @@ -55,15 +56,16 @@ public List findAllRoomsDesc() { } @Transactional - public void delete (Long roomID){ + public void delete(Long roomID) { StRoomEntity stroomEntity = stRoomRepository.findById(roomID) - .orElseThrow(()-> new IllegalArgumentException("해당 게시물이 없습니다. id =" + roomID)); + .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id =" + roomID)); stRoomRepository.delete(stroomEntity); //JpaRepository 에서 이미 delete 메소드를 지원하고 있으므로 활용 //엔티티를 파라미터로 살제할 수도 있고, deleteById 메서드를 이용하면 id로 삭제할 수 있음 // 존재하는 strooms인지 확인을 위해 엔티티 조회 후 그대로 삭제함 // --> 서비스에서 delete 메서드를 만들면 컨트롤러가 사용하도록 컨트롤러에 코드 추가하기. } + @Transactional(readOnly = true) public List findByTitleContaining(String keyword) { return stRoomRepository.findByTitleContaining(keyword); @@ -77,6 +79,7 @@ public List findPopularRoom() { .map(StRoomListResponseDto::new) .collect(Collectors.toList()); } + @Transactional(readOnly = true) public List findRoomsInHome() { @@ -87,13 +90,16 @@ public List findByCategory(String category) { return stRoomRepository.findByCategory(category); } - public Long memberJoin(StRoomMemberJoinRequestDto requestDto) { - StudyMemberEntity studyMember = new StudyMemberEntity(); - studyMember.setRoomID(requestDto.getRoomID()); - studyMember.setStatus(MemberStatus.Waiting); - studyMember.setAnswer(requestDto.getAnswer()); - studyMember.setMemberId(); //세션값-멤버아이디 넣어주기 - studyMemberRepository.save(studyMember); - + public void memberJoin(StRoomMemberJoinRequestDto requestDto) { + try { + StudyMemberEntity studyMember = new StudyMemberEntity(); + studyMember.setRoomID(requestDto.getRoomID()); + studyMember.setStatus(MemberStatus.Waiting); + studyMember.setAnswer(requestDto.getAnswer()); + /*studyMember.setMemberId(); //세션값-멤버아이디 넣어주기*/ + studyMemberRepository.save(studyMember); + } catch (Exception e) { + e.printStackTrace(); + } } } \ No newline at end of file From e85fb303badc9b24ba8f686571b2e58d1bbe64a1 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Sun, 17 Sep 2023 16:32:11 +0900 Subject: [PATCH 13/60] =?UTF-8?q?=EC=8A=A4=ED=84=B0=EB=94=94=EB=A3=B8=20?= =?UTF-8?q?=EA=B0=80=EC=9E=85=ED=95=98=EA=B8=B0=20(=EB=A9=A4=EB=B2=84=20?= =?UTF-8?q?=EC=95=84=EC=9D=B4=EB=94=94=20=EC=84=B8=EC=85=98=20=EB=A7=8C?= =?UTF-8?q?=EB=93=A4=EC=96=B4=EC=A3=BC=EC=84=B8=EC=9A=94)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/mos/mosback/domain/posts/StRoomEntity.java | 13 ++++--------- .../mosback/web/dto/StRoomDetailResponseDto.java | 4 ++++ 2 files changed, 8 insertions(+), 9 deletions(-) create mode 100644 src/main/java/mos/mosback/web/dto/StRoomDetailResponseDto.java diff --git a/src/main/java/mos/mosback/domain/posts/StRoomEntity.java b/src/main/java/mos/mosback/domain/posts/StRoomEntity.java index 94d673a..43742bd 100644 --- a/src/main/java/mos/mosback/domain/posts/StRoomEntity.java +++ b/src/main/java/mos/mosback/domain/posts/StRoomEntity.java @@ -41,13 +41,9 @@ public class StRoomEntity extends BaseTimeEntity { private Date endDate; //스터디 끝나는 날짜 private Date deadline ; //스터디 모집 마감날짜 - @ManyToOne - @JoinColumn(name = "leader_id") // 리더와의 관계를 설정할 외래 키 컬럼 - private User leader; - - @ManyToOne + /* @ManyToOne @JoinColumn(name = "User_nick") - private User nickname= new User().getStRoom().getNickname(); + */ @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) private List studyDayEntities = new ArrayList<>(); @@ -75,8 +71,7 @@ public StRoomEntity(String title, String goal, String rules, String quest, this.endDate = endDate; this.deadline = deadline; this.studyDayEntities = studyDayEntities; - this.leader = leader; - this.nickname= nickname; + } @@ -100,7 +95,7 @@ public void update(String title, String goal, String rules, String quest, this.startDate = startDate; this.endDate = endDate; this.studyDayEntities = studyDayEntities; - this.leader = leader; + } } \ No newline at end of file diff --git a/src/main/java/mos/mosback/web/dto/StRoomDetailResponseDto.java b/src/main/java/mos/mosback/web/dto/StRoomDetailResponseDto.java new file mode 100644 index 0000000..a7c4a43 --- /dev/null +++ b/src/main/java/mos/mosback/web/dto/StRoomDetailResponseDto.java @@ -0,0 +1,4 @@ +package mos.mosback.web.dto; + +public class StRoomDetailResponseDto { +} From 0208c30b01bc1011413a7b8d9a32a048cc7c7c00 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Tue, 19 Sep 2023 18:29:01 +0900 Subject: [PATCH 14/60] =?UTF-8?q?=EB=8B=89=EB=84=A4=EC=9E=84=20=EB=B0=98?= =?UTF-8?q?=ED=99=98=20API=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mosback/controller/StRoomController.java | 4 +-- .../mosback/controller/UserController.java | 14 +++++++--- .../mosback/domain/posts/StRoomEntity.java | 6 ++-- .../domain/posts/StudyMemberEntity.java | 9 ++++-- .../mosback/repository/UserRepository.java | 7 ++--- .../mos/mosback/service/StRoomService.java | 2 +- .../java/mos/mosback/service/UserService.java | 13 +++++---- .../mosback/web/dto/Home_RoomResponseDto.java | 6 ++-- .../mosback/web/dto/Home_nickResponseDto.java | 7 ++--- .../java/mos/mosback/web/dto/QuestionDto.java | 5 ++++ .../web/dto/StRoomDetailResponseDto.java | 28 +++++++++++++++++++ .../web/dto/StRoomListResponseDto.java | 1 - 12 files changed, 72 insertions(+), 30 deletions(-) diff --git a/src/main/java/mos/mosback/controller/StRoomController.java b/src/main/java/mos/mosback/controller/StRoomController.java index ff812bf..90fa47a 100644 --- a/src/main/java/mos/mosback/controller/StRoomController.java +++ b/src/main/java/mos/mosback/controller/StRoomController.java @@ -34,7 +34,7 @@ public ResponseEntity saveRoom(@RequestBody StRoomSaveRequestDto request * @return */ - @GetMapping("get/{roomId}") + @GetMapping("/MyStudy/{roomId}") public ResponseEntity FindByID (@PathVariable Long roomId) { StRoomResponseDto stroom = stRoomService.findById(roomId); return new ResponseEntity<>(stroom, HttpStatus.OK); @@ -63,7 +63,7 @@ public ResponseEntity UpdateRoom(@PathVariable Long roomId, @RequestBody } } - @DeleteMapping("/delete/{roomId}") + @DeleteMapping("/{roomId}") public ResponseEntity> deleteRoom(@PathVariable Long roomId) { Map response = new HashMap<>(); try { diff --git a/src/main/java/mos/mosback/controller/UserController.java b/src/main/java/mos/mosback/controller/UserController.java index 1ccef15..2a1061c 100644 --- a/src/main/java/mos/mosback/controller/UserController.java +++ b/src/main/java/mos/mosback/controller/UserController.java @@ -78,9 +78,15 @@ public ResponseEntity sendEmail(@RequestParam("userEmail") String userEm return ResponseEntity.ok("임시 비밀번호 메일 전송, 변경 완료"); } - @GetMapping("get/nick") - public ResponseEntity> ReturnNickname() { - List nickname = userRepository.ReturnNickname(); - return ResponseEntity.ok(nickname); + + @GetMapping("/nickname") + public ResponseEntity findNicknameO() { + Home_nickResponseDto nicknameDto = userService.getNickname(); + + if (nicknameDto != null) { + return ResponseEntity.ok(nicknameDto.getNickname()); + } else { + return ResponseEntity.notFound().build(); + } } } \ No newline at end of file diff --git a/src/main/java/mos/mosback/domain/posts/StRoomEntity.java b/src/main/java/mos/mosback/domain/posts/StRoomEntity.java index 43742bd..c416da3 100644 --- a/src/main/java/mos/mosback/domain/posts/StRoomEntity.java +++ b/src/main/java/mos/mosback/domain/posts/StRoomEntity.java @@ -41,9 +41,9 @@ public class StRoomEntity extends BaseTimeEntity { private Date endDate; //스터디 끝나는 날짜 private Date deadline ; //스터디 모집 마감날짜 - /* @ManyToOne - @JoinColumn(name = "User_nick") - */ +/* @ManyToOne + @JoinColumn(name = "NICKNAME") + private User nickname ;*/ @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) private List studyDayEntities = new ArrayList<>(); diff --git a/src/main/java/mos/mosback/domain/posts/StudyMemberEntity.java b/src/main/java/mos/mosback/domain/posts/StudyMemberEntity.java index eb26713..ba22711 100644 --- a/src/main/java/mos/mosback/domain/posts/StudyMemberEntity.java +++ b/src/main/java/mos/mosback/domain/posts/StudyMemberEntity.java @@ -5,18 +5,21 @@ import lombok.Setter; import javax.persistence.*; +import java.io.Serializable; @Getter // 롬복 어노테이션 @Setter @NoArgsConstructor // 롬복 어노테이션 (필수는 아님 그냥 코드 단순화용) @Entity -public class StudyMemberEntity { +public class StudyMemberEntity implements Serializable { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "memberID") private Long memberId; - @Id - private Long roomID; + @JoinColumn(name = "roomID") + private Long roomId; // 다른 필드와 매핑 diff --git a/src/main/java/mos/mosback/repository/UserRepository.java b/src/main/java/mos/mosback/repository/UserRepository.java index 6bfdd77..0952965 100644 --- a/src/main/java/mos/mosback/repository/UserRepository.java +++ b/src/main/java/mos/mosback/repository/UserRepository.java @@ -4,6 +4,7 @@ import mos.mosback.web.dto.Home_nickResponseDto; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import java.util.List; import java.util.Optional; @@ -25,9 +26,7 @@ public interface UserRepository extends JpaRepository { User findByEmail(String email); Optional findById(Long id); - @Query("SELECT new mos.mosback.web.dto.Home_nickResponseDto(u) FROM User u") - List ReturnNickname(); - @Query("SELECT new mos.mosback.web.dto.Home_nickResponseDto(u) FROM User u") - List ReturnNick(); + @Query("SELECT new mos.mosback.web.dto.Home_nickResponseDto(u) FROM User u") + Home_nickResponseDto findNickname(); } diff --git a/src/main/java/mos/mosback/service/StRoomService.java b/src/main/java/mos/mosback/service/StRoomService.java index 3294ac3..1458a4c 100644 --- a/src/main/java/mos/mosback/service/StRoomService.java +++ b/src/main/java/mos/mosback/service/StRoomService.java @@ -93,7 +93,7 @@ public List findByCategory(String category) { public void memberJoin(StRoomMemberJoinRequestDto requestDto) { try { StudyMemberEntity studyMember = new StudyMemberEntity(); - studyMember.setRoomID(requestDto.getRoomID()); + studyMember.setRoomId(requestDto.getRoomID()); studyMember.setStatus(MemberStatus.Waiting); studyMember.setAnswer(requestDto.getAnswer()); /*studyMember.setMemberId(); //세션값-멤버아이디 넣어주기*/ diff --git a/src/main/java/mos/mosback/service/UserService.java b/src/main/java/mos/mosback/service/UserService.java index 21f11d8..f4aa4f8 100644 --- a/src/main/java/mos/mosback/service/UserService.java +++ b/src/main/java/mos/mosback/service/UserService.java @@ -122,10 +122,13 @@ public void save(UserInfoDto userInfoDto) { } - public List ReturnNickname() { - List nickname = userRepository.ReturnNickname(); - return nickname; +// @Transactional(readOnly = true) +// public List findRoomsInHome() { +// +// return stRoomRepository.findHomeStRoomField(); +// } + + public Home_nickResponseDto getNickname() { + return userRepository.findNickname(); } - - } \ No newline at end of file diff --git a/src/main/java/mos/mosback/web/dto/Home_RoomResponseDto.java b/src/main/java/mos/mosback/web/dto/Home_RoomResponseDto.java index aac9b22..671065e 100644 --- a/src/main/java/mos/mosback/web/dto/Home_RoomResponseDto.java +++ b/src/main/java/mos/mosback/web/dto/Home_RoomResponseDto.java @@ -11,15 +11,15 @@ public class Home_RoomResponseDto { private String category; // 스터디 카테고리 private int memberNum; //현재 멤버수 private int maxMember; //모집 멤버수 - private String location; + private String location; //스터디장소 private int online; //온라인 - private Date deadline ; //스터디 모집 마감날짜 + private Date startDate; //스터디 시작날짜 //+ 유저프로필사진 public Home_RoomResponseDto(StRoomEntity entity) { this.title = entity.getTitle(); - this.deadline = entity.getDeadline(); + this.startDate = entity.getStartDate(); this.location = entity.getLocation(); this.online = entity.getOnline(); this.category = entity.getCategory(); diff --git a/src/main/java/mos/mosback/web/dto/Home_nickResponseDto.java b/src/main/java/mos/mosback/web/dto/Home_nickResponseDto.java index 9ca4efa..af77d4a 100644 --- a/src/main/java/mos/mosback/web/dto/Home_nickResponseDto.java +++ b/src/main/java/mos/mosback/web/dto/Home_nickResponseDto.java @@ -7,8 +7,7 @@ public class Home_nickResponseDto { private String nickname; - public Home_nickResponseDto(User entity) - { - this.nickname = getNickname(); + public Home_nickResponseDto(User entity) { + this.nickname = entity.getNickname(); } -} +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/web/dto/QuestionDto.java b/src/main/java/mos/mosback/web/dto/QuestionDto.java index 14cf739..bb22110 100644 --- a/src/main/java/mos/mosback/web/dto/QuestionDto.java +++ b/src/main/java/mos/mosback/web/dto/QuestionDto.java @@ -1,7 +1,12 @@ package mos.mosback.web.dto; +import lombok.NoArgsConstructor; +import lombok.Setter; import mos.mosback.domain.posts.StRoomEntity; import lombok.Getter; +@Setter +@Getter +@NoArgsConstructor public class QuestionDto { private String question; diff --git a/src/main/java/mos/mosback/web/dto/StRoomDetailResponseDto.java b/src/main/java/mos/mosback/web/dto/StRoomDetailResponseDto.java index a7c4a43..bf557a0 100644 --- a/src/main/java/mos/mosback/web/dto/StRoomDetailResponseDto.java +++ b/src/main/java/mos/mosback/web/dto/StRoomDetailResponseDto.java @@ -1,4 +1,32 @@ package mos.mosback.web.dto; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.Getter; +import mos.mosback.domain.posts.StudyDaysEntity; + +import java.util.Date; +import java.util.List; public class StRoomDetailResponseDto { + private String title; + private String category; + + //+모집여부 + private String location; + private Date startDate; + private Date endDate; + + private int memberNum; //현재 멤버수 + private int maxMember; //모집 멤버수 + //+ 모집기간 + private String mod; //스터디 분위기 + //+스터디장 닉네임 + + private List studyDayEntities; + private String goal; + private String rules; + private String intro; + //+스터디원 사진..리스트?? + //+웨이팅멤버 사진 + //스터디 투두리스트 } diff --git a/src/main/java/mos/mosback/web/dto/StRoomListResponseDto.java b/src/main/java/mos/mosback/web/dto/StRoomListResponseDto.java index a861c19..c42623c 100644 --- a/src/main/java/mos/mosback/web/dto/StRoomListResponseDto.java +++ b/src/main/java/mos/mosback/web/dto/StRoomListResponseDto.java @@ -47,7 +47,6 @@ public StRoomListResponseDto(StRoomEntity entity) { } public StRoomListResponseDto(Home_RoomResponseDto homeRoomResponseDto) { this.title = homeRoomResponseDto.getTitle(); - this.deadline = homeRoomResponseDto.getDeadline(); this.location = homeRoomResponseDto.getLocation(); this.online = homeRoomResponseDto.getOnline(); this.category = homeRoomResponseDto.getCategory(); From f45ff91ee608b5453de5575cc540aa9458906d62 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Wed, 20 Sep 2023 01:32:40 +0900 Subject: [PATCH 15/60] =?UTF-8?q?=EB=AA=A8=EC=A7=91=EC=A4=91=EC=9D=B8=20?= =?UTF-8?q?=EC=8A=A4=ED=84=B0=EB=94=94=20=EC=A1=B0=ED=9A=8C,=20=EC=8A=A4?= =?UTF-8?q?=ED=84=B0=EB=94=94=EA=B0=80=EC=9E=85,=20=EB=8B=89=EB=84=A4?= =?UTF-8?q?=EC=9E=84=20=EB=B0=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mosback/controller/StRoomController.java | 39 +++++++++++++++---- .../mosback/domain/posts/BaseTimeEntity.java | 2 +- .../mosback/domain/posts/StRoomEntity.java | 11 ++---- .../mosback/repository/StRoomRepository.java | 4 ++ .../mos/mosback/service/StRoomService.java | 9 ++++- .../web/dto/StRoomDetailResponseDto.java | 12 +++--- .../web/dto/StRoomListResponseDto.java | 1 - 7 files changed, 55 insertions(+), 23 deletions(-) diff --git a/src/main/java/mos/mosback/controller/StRoomController.java b/src/main/java/mos/mosback/controller/StRoomController.java index 90fa47a..0a20518 100644 --- a/src/main/java/mos/mosback/controller/StRoomController.java +++ b/src/main/java/mos/mosback/controller/StRoomController.java @@ -1,12 +1,15 @@ package mos.mosback.controller; +import mos.mosback.domain.posts.StRoomEntity; import mos.mosback.web.dto.*; import mos.mosback.service.StRoomService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import javax.persistence.EntityNotFoundException; +import java.time.LocalDateTime; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -123,15 +126,35 @@ public ResponseEntity memberJoin(@RequestBody StRoomMemberJoinRequestDto } + @GetMapping("/recruiting") + public ResponseEntity getRecruitingStudies() { + List recruitingStudies = stRoomService.getRecruitingStudies(); + + if (!recruitingStudies.isEmpty()) { + return ResponseEntity.ok(recruitingStudies); + } else { + Map response = new HashMap<>(); + response.put("status", HttpStatus.NOT_FOUND.value()); + response.put("success", false); + response.put("message", "NOT FOUND: recruiting studyRoom "); + + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); + } + } + + } //핸들러 메서드 : // -//create: 새 게시물을 생성하는 엔드포인트. -//getstroom: 특정 roomID에 해당하는 게시물을 조회하는 엔드포인트.( 스터디그룹 조회 ) -//searchstrooms: 키워드가 포함된 게시물을 검색하는 엔드포인트. -//updatestroom: 게시물을 업데이트하는 엔드포인트. -//deletestroom: 게시물을 삭제하는 엔드포인트. -//getAllstrooms: 모든 게시물을 조회하는 엔드포인트. -//getPopularstrooms: 조회순으로 게시물을 조회하는 엔드포인트. (인기순 조회시) +//create: 새 게시물을 생성 +///MyStudy/{roomId}: 특정 roomID에 해당하는 게시물을 조회( 스터디그룹 -마이스터디화면 조회 ) +//search: 제목에 키워드가 포함된 게시물을 검색하는 엔드포인트. +///update/{roomId}: 게시물 수정 +///(Delete) {roomId}: 게시물을 삭제 +//getPopularstrooms: 조회순으로 게시물을 조회(인기순 조회시) +//all: 전체 스터디 조회 //memberjoin - 스터디 가입 API -//https://blog.pumpkin-raccoon.com/115#:~:text=1%201.%20%EB%B3%B5%EC%88%98%20%3E%20%EB%8B%A8%EC%88%98%20REST%20API%EC%97%90%EC%84%9C%EB%8A%94%20post%2C,%EC%BB%AC%EB%A0%89%EC%85%98%20%ED%95%84%ED%84%B0%EB%A7%81%3A%20URL%20%EC%BF%BC%EB%A6%AC%20%3E%20%EC%83%88%EB%A1%9C%EC%9A%B4%20API%20 \ No newline at end of file +///byCategory/{category} : 카테고리별로 조회하는 엔프포인트 +//https://blog.pumpkin-raccoon.com/115#:~:text=1%201.%20%EB%B3%B5%EC%88%98%20%3E%20%EB%8B%A8%EC%88%98%20REST%20API%EC%97%90%EC%84%9C%EB%8A%94%20post%2C,%EC%BB%AC%EB%A0%89%EC%85%98%20%ED%95%84%ED%84%B0%EB%A7%81%3A%20URL%20%EC%BF%BC%EB%A6%AC%20%3E%20%EC%83%88%EB%A1%9C%EC%9A%B4%20API%20 +///recruiting : 모집중인 게시물을 조회하는 엔드포인트. +// \ No newline at end of file diff --git a/src/main/java/mos/mosback/domain/posts/BaseTimeEntity.java b/src/main/java/mos/mosback/domain/posts/BaseTimeEntity.java index 791b314..4f65553 100644 --- a/src/main/java/mos/mosback/domain/posts/BaseTimeEntity.java +++ b/src/main/java/mos/mosback/domain/posts/BaseTimeEntity.java @@ -17,4 +17,4 @@ public abstract class BaseTimeEntity { private LocalDateTime createdDate; } -//모든 Entity의 상위 클래스가 되어 엔티티들의 생성시간 변경시간을 자동으로 관리하는 클래스 \ No newline at end of file +//모든 Entity의 상위 클래스가 되어 엔티티들의 생성시간을 자동으로 관리하는 클래스 \ No newline at end of file diff --git a/src/main/java/mos/mosback/domain/posts/StRoomEntity.java b/src/main/java/mos/mosback/domain/posts/StRoomEntity.java index c416da3..6b7efa0 100644 --- a/src/main/java/mos/mosback/domain/posts/StRoomEntity.java +++ b/src/main/java/mos/mosback/domain/posts/StRoomEntity.java @@ -39,11 +39,9 @@ public class StRoomEntity extends BaseTimeEntity { private int online; //온라인 private Date startDate; //스터디 시작 날짜 private Date endDate; //스터디 끝나는 날짜 - private Date deadline ; //스터디 모집 마감날짜 + private boolean recruiting; //모집여부 + -/* @ManyToOne - @JoinColumn(name = "NICKNAME") - private User nickname ;*/ @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) private List studyDayEntities = new ArrayList<>(); @@ -52,8 +50,8 @@ public class StRoomEntity extends BaseTimeEntity { public StRoomEntity(String title, String goal, String rules, String quest, String category, String intro, int memberNum, int maxMember ,String mod, boolean onOff, String location,int online, - Date startDate, Date endDate, Date deadline , - List studyDayEntities,User leader,User nickname) { + Date startDate, Date endDate, List studyDayEntities, + User leader,User nickname) { this.title = title; this.goal = goal; @@ -69,7 +67,6 @@ public StRoomEntity(String title, String goal, String rules, String quest, this.online = online; this.startDate = startDate; this.endDate = endDate; - this.deadline = deadline; this.studyDayEntities = studyDayEntities; } diff --git a/src/main/java/mos/mosback/repository/StRoomRepository.java b/src/main/java/mos/mosback/repository/StRoomRepository.java index e02b7e5..dfbefd6 100644 --- a/src/main/java/mos/mosback/repository/StRoomRepository.java +++ b/src/main/java/mos/mosback/repository/StRoomRepository.java @@ -9,6 +9,8 @@ import org.springframework.data.repository.query.Param; +import java.time.LocalDateTime; +import java.util.Date; import java.util.List; //인터페이스 생성 후 JpaRepository를 상속하면 기본적인 CRUD 메소드 자동으로 생성됨 @@ -29,4 +31,6 @@ public interface StRoomRepository extends JpaRepository { List findByCategory(@Param("category") String category); + @Query("SELECT new mos.mosback.web.dto.Home_RoomResponseDto(s) FROM StRoomEntity s WHERE s.startDate > current_timestamp") + List findRecruitingStudies(); } \ No newline at end of file diff --git a/src/main/java/mos/mosback/service/StRoomService.java b/src/main/java/mos/mosback/service/StRoomService.java index 1458a4c..892942e 100644 --- a/src/main/java/mos/mosback/service/StRoomService.java +++ b/src/main/java/mos/mosback/service/StRoomService.java @@ -9,7 +9,7 @@ import mos.mosback.web.dto.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; - +import java.time.LocalDateTime; import java.util.List; import java.util.stream.Collectors; @@ -102,4 +102,11 @@ public void memberJoin(StRoomMemberJoinRequestDto requestDto) { e.printStackTrace(); } } + public List getRecruitingStudies() { + + LocalDateTime now = LocalDateTime.now(); + List recruitingStudies = stRoomRepository.findRecruitingStudies(); + + return recruitingStudies; + } } \ No newline at end of file diff --git a/src/main/java/mos/mosback/web/dto/StRoomDetailResponseDto.java b/src/main/java/mos/mosback/web/dto/StRoomDetailResponseDto.java index bf557a0..1cc9772 100644 --- a/src/main/java/mos/mosback/web/dto/StRoomDetailResponseDto.java +++ b/src/main/java/mos/mosback/web/dto/StRoomDetailResponseDto.java @@ -4,22 +4,24 @@ import lombok.Getter; import mos.mosback.domain.posts.StudyDaysEntity; +import java.time.LocalDateTime; import java.util.Date; import java.util.List; public class StRoomDetailResponseDto { private String title; private String category; - - //+모집여부 + private boolean recruiting; private String location; private Date startDate; private Date endDate; - + private LocalDateTime createdDate; + private Date deadline; private int memberNum; //현재 멤버수 private int maxMember; //모집 멤버수 - //+ 모집기간 + private String mod; //스터디 분위기 + //+스터디장 닉네임 private List studyDayEntities; @@ -28,5 +30,5 @@ public class StRoomDetailResponseDto { private String intro; //+스터디원 사진..리스트?? //+웨이팅멤버 사진 - //스터디 투두리스트 + //+스터디 투두리스트 } diff --git a/src/main/java/mos/mosback/web/dto/StRoomListResponseDto.java b/src/main/java/mos/mosback/web/dto/StRoomListResponseDto.java index c42623c..9c75e1e 100644 --- a/src/main/java/mos/mosback/web/dto/StRoomListResponseDto.java +++ b/src/main/java/mos/mosback/web/dto/StRoomListResponseDto.java @@ -23,7 +23,6 @@ public class StRoomListResponseDto { private boolean onOff; //진행방식 (온오프) private Date startDate; //스터디 시작 날짜 private Date endDate; //스터디 끝나는 날짜 - private Date deadline; private String location; private int online; //온라인 From d70b5d30a243fe6d9347d649e8d9a37e03ebd1bf Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Wed, 20 Sep 2023 19:31:47 +0900 Subject: [PATCH 16/60] =?UTF-8?q?=EC=84=B8=EC=85=98=EC=97=90=20=EC=9C=A0?= =?UTF-8?q?=EC=A0=80=EA=B0=9D=EC=B2=B4=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/mos/mosback/controller/UserController.java | 7 +++++-- .../java/mos/mosback/repository/StRoomRepository.java | 11 ++++++----- .../java/mos/mosback/repository/UserRepository.java | 2 +- src/main/java/mos/mosback/service/StRoomService.java | 2 +- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/main/java/mos/mosback/controller/UserController.java b/src/main/java/mos/mosback/controller/UserController.java index 2a1061c..12aed1f 100644 --- a/src/main/java/mos/mosback/controller/UserController.java +++ b/src/main/java/mos/mosback/controller/UserController.java @@ -8,6 +8,7 @@ import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpSession; import javax.transaction.Transactional; import java.util.List; @@ -36,11 +37,13 @@ public ResponseEntity join(@RequestBody SignUpDTO signUpDTO) { //로그인 @PostMapping("/login") - public ResponseEntity login(@RequestBody LoginDTO loginDTO) { + public ResponseEntity login(@RequestBody LoginDTO loginDTO, HttpSession session) { if(userService.isEmailDuplicate(loginDTO.getEmail())) { - if(userService.comparePassword(loginDTO.getEmail(),loginDTO.getPassword())) { + if(userService.comparePassword(loginDTO.getEmail(), loginDTO.getPassword())) { User user = userRepository.findByEmail(loginDTO.getEmail()); if(user != null) { + // 세션에 유저 객체를 저장 + session.setAttribute("user", user); return ResponseEntity.ok("로그인 성공"); } return ResponseEntity.status(400).body("사용자를 찾을 수 없습니다."); diff --git a/src/main/java/mos/mosback/repository/StRoomRepository.java b/src/main/java/mos/mosback/repository/StRoomRepository.java index dfbefd6..2a0c913 100644 --- a/src/main/java/mos/mosback/repository/StRoomRepository.java +++ b/src/main/java/mos/mosback/repository/StRoomRepository.java @@ -4,6 +4,7 @@ import mos.mosback.domain.posts.StRoomEntity; import mos.mosback.web.dto.Home_RoomResponseDto; import mos.mosback.web.dto.Home_nickResponseDto; +import mos.mosback.web.dto.Home_RoomResponseDto; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -16,18 +17,18 @@ //인터페이스 생성 후 JpaRepository를 상속하면 기본적인 CRUD 메소드 자동으로 생성됨 public interface StRoomRepository extends JpaRepository { - @Query("SELECT new mos.mosback.web.dto.Home_RoomResponseDto(s) FROM StRoomEntity s ORDER BY s.roomID DESC") + @Query("SELECT Home_RoomResponseDto(s) FROM StRoomEntity s ORDER BY s.roomID DESC") List findAllDesc(); - @Query("SELECT new mos.mosback.web.dto.Home_RoomResponseDto(s) FROM StRoomEntity s WHERE s.title LIKE %:keyword%") + @Query("SELECT RoomResponseDto(s) FROM StRoomEntity s WHERE s.title LIKE %:keyword%") List findByTitleContaining(@Param("keyword") String keyword);//키워드를 통해 스터디그룹을 검색 할 수 있다 - @Query(value = "SELECT new mos.mosback.web.dto.Home_RoomResponseDto(s) FROM StRoomEntity s ORDER BY s.click DESC") + @Query(value = "SELECT Home_RoomResponseDto(s) FROM StRoomEntity s ORDER BY s.click DESC") List findPopularRoom(); - @Query("SELECT new mos.mosback.web.dto.Home_RoomResponseDto(s) FROM StRoomEntity s") + @Query("SELECT Home_RoomResponseDto(s) FROM StRoomEntity s") List findHomeStRoomField(); - @Query("SELECT new mos.mosback.web.dto.Home_RoomResponseDto(s) FROM StRoomEntity s WHERE s.category = :category") + @Query("SELECT Home_RoomResponseDto(s) FROM StRoomEntity s WHERE s.category = :category") List findByCategory(@Param("category") String category); diff --git a/src/main/java/mos/mosback/repository/UserRepository.java b/src/main/java/mos/mosback/repository/UserRepository.java index 0952965..f22b4f4 100644 --- a/src/main/java/mos/mosback/repository/UserRepository.java +++ b/src/main/java/mos/mosback/repository/UserRepository.java @@ -27,6 +27,6 @@ public interface UserRepository extends JpaRepository { Optional findById(Long id); - @Query("SELECT new mos.mosback.web.dto.Home_nickResponseDto(u) FROM User u") + @Query("SELECT Home_nickResponseDto(u) FROM User u") Home_nickResponseDto findNickname(); } diff --git a/src/main/java/mos/mosback/service/StRoomService.java b/src/main/java/mos/mosback/service/StRoomService.java index 892942e..7411593 100644 --- a/src/main/java/mos/mosback/service/StRoomService.java +++ b/src/main/java/mos/mosback/service/StRoomService.java @@ -96,7 +96,7 @@ public void memberJoin(StRoomMemberJoinRequestDto requestDto) { studyMember.setRoomId(requestDto.getRoomID()); studyMember.setStatus(MemberStatus.Waiting); studyMember.setAnswer(requestDto.getAnswer()); - /*studyMember.setMemberId(); //세션값-멤버아이디 넣어주기*/ + /*studyMember.setMemberId(requestDto.getID()); //세션값-멤버아이디 넣어주기*/ studyMemberRepository.save(studyMember); } catch (Exception e) { e.printStackTrace(); From 46f8ff5e1965295ff54d88e90f8ab363aaa794d0 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Wed, 20 Sep 2023 22:51:55 +0900 Subject: [PATCH 17/60] =?UTF-8?q?=EC=84=B8=EC=85=98=EC=97=90=20=EC=9C=A0?= =?UTF-8?q?=EC=A0=80=EA=B0=9D=EC=B2=B4=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mosback/controller/StRoomController.java | 27 ++++++++++++------- .../mosback/controller/UserController.java | 1 - .../domain/posts/StudyMemberEntity.java | 2 +- .../mosback/repository/StRoomRepository.java | 16 ++++------- .../mosback/repository/UserRepository.java | 2 +- .../mos/mosback/service/StRoomService.java | 15 ++++++++++- 6 files changed, 39 insertions(+), 24 deletions(-) diff --git a/src/main/java/mos/mosback/controller/StRoomController.java b/src/main/java/mos/mosback/controller/StRoomController.java index 0a20518..78320ef 100644 --- a/src/main/java/mos/mosback/controller/StRoomController.java +++ b/src/main/java/mos/mosback/controller/StRoomController.java @@ -31,12 +31,6 @@ public ResponseEntity saveRoom(@RequestBody StRoomSaveRequestDto request return ResponseEntity.status(HttpStatus.CREATED).body("created successfully. ID: " + stroomId); } - /** - * 스터디 방 정보 가져오기 - * @param //roomId - * @return - */ - @GetMapping("/MyStudy/{roomId}") public ResponseEntity FindByID (@PathVariable Long roomId) { StRoomResponseDto stroom = stRoomService.findById(roomId); @@ -118,11 +112,23 @@ public ResponseEntity> getStudyRoomsByCategory(@PathVariable response.put("studyRooms", studyRooms); // 데이터를 직접 넣음 return ResponseEntity.ok(response); } - + @GetMapping("/question/{roomId}") + public ResponseEntity getQuestionById(@PathVariable Long roomId) { + try { + QuestionDto question = stRoomService.getQuestionById(roomId); + return ResponseEntity.ok(question); + } catch (EntityNotFoundException ex) { + Map response = new HashMap<>(); + response.put("status:", HttpStatus.NOT_FOUND.value()); + response.put("success", false); + response.put("message", "NOT FOUND: Quest with roomID " + roomId); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); + } + } @PostMapping("/memberjoin") public ResponseEntity memberJoin(@RequestBody StRoomMemberJoinRequestDto requestDto) { stRoomService.memberJoin(requestDto); - return ResponseEntity.status(HttpStatus.CREATED).body("created successfully."); + return ResponseEntity.status(HttpStatus.CREATED).body("joined successfully."); } @@ -144,8 +150,10 @@ public ResponseEntity getRecruitingStudies() { } + + //핸들러 메서드 : -// + //create: 새 게시물을 생성 ///MyStudy/{roomId}: 특정 roomID에 해당하는 게시물을 조회( 스터디그룹 -마이스터디화면 조회 ) //search: 제목에 키워드가 포함된 게시물을 검색하는 엔드포인트. @@ -153,6 +161,7 @@ public ResponseEntity getRecruitingStudies() { ///(Delete) {roomId}: 게시물을 삭제 //getPopularstrooms: 조회순으로 게시물을 조회(인기순 조회시) //all: 전체 스터디 조회 +///question/{roomId}: 스터디장이 남긴 질문 조회 //memberjoin - 스터디 가입 API ///byCategory/{category} : 카테고리별로 조회하는 엔프포인트 //https://blog.pumpkin-raccoon.com/115#:~:text=1%201.%20%EB%B3%B5%EC%88%98%20%3E%20%EB%8B%A8%EC%88%98%20REST%20API%EC%97%90%EC%84%9C%EB%8A%94%20post%2C,%EC%BB%AC%EB%A0%89%EC%85%98%20%ED%95%84%ED%84%B0%EB%A7%81%3A%20URL%20%EC%BF%BC%EB%A6%AC%20%3E%20%EC%83%88%EB%A1%9C%EC%9A%B4%20API%20 diff --git a/src/main/java/mos/mosback/controller/UserController.java b/src/main/java/mos/mosback/controller/UserController.java index 12aed1f..ab8dd68 100644 --- a/src/main/java/mos/mosback/controller/UserController.java +++ b/src/main/java/mos/mosback/controller/UserController.java @@ -52,7 +52,6 @@ public ResponseEntity login(@RequestBody LoginDTO loginDTO, HttpSession } return ResponseEntity.status(400).body("사용자를 찾을 수 없습니다."); } - //이메일 중복확인 @GetMapping("/user-emails/{email}/exists") public ResponseEntity isEmailDuplicate(@PathVariable String email){ diff --git a/src/main/java/mos/mosback/domain/posts/StudyMemberEntity.java b/src/main/java/mos/mosback/domain/posts/StudyMemberEntity.java index ba22711..62cad09 100644 --- a/src/main/java/mos/mosback/domain/posts/StudyMemberEntity.java +++ b/src/main/java/mos/mosback/domain/posts/StudyMemberEntity.java @@ -9,7 +9,7 @@ @Getter // 롬복 어노테이션 @Setter -@NoArgsConstructor // 롬복 어노테이션 (필수는 아님 그냥 코드 단순화용) +@NoArgsConstructor @Entity public class StudyMemberEntity implements Serializable { diff --git a/src/main/java/mos/mosback/repository/StRoomRepository.java b/src/main/java/mos/mosback/repository/StRoomRepository.java index 2a0c913..a3b93b0 100644 --- a/src/main/java/mos/mosback/repository/StRoomRepository.java +++ b/src/main/java/mos/mosback/repository/StRoomRepository.java @@ -3,32 +3,26 @@ //Entity 클래스와 Entity레파지토리 위치 같아야함 import mos.mosback.domain.posts.StRoomEntity; import mos.mosback.web.dto.Home_RoomResponseDto; -import mos.mosback.web.dto.Home_nickResponseDto; -import mos.mosback.web.dto.Home_RoomResponseDto; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; - - -import java.time.LocalDateTime; -import java.util.Date; import java.util.List; //인터페이스 생성 후 JpaRepository를 상속하면 기본적인 CRUD 메소드 자동으로 생성됨 public interface StRoomRepository extends JpaRepository { - @Query("SELECT Home_RoomResponseDto(s) FROM StRoomEntity s ORDER BY s.roomID DESC") + @Query("SELECT new mos.mosback.web.dto.Home_RoomResponseDto(s) FROM StRoomEntity s ORDER BY s.roomID DESC") List findAllDesc(); - @Query("SELECT RoomResponseDto(s) FROM StRoomEntity s WHERE s.title LIKE %:keyword%") + @Query("SELECT new mos.mosback.web.dto.Home_RoomResponseDto(s) FROM StRoomEntity s WHERE s.title LIKE %:keyword%") List findByTitleContaining(@Param("keyword") String keyword);//키워드를 통해 스터디그룹을 검색 할 수 있다 - @Query(value = "SELECT Home_RoomResponseDto(s) FROM StRoomEntity s ORDER BY s.click DESC") + @Query(value = "SELECT new mos.mosback.web.dto.Home_RoomResponseDto(s)FROM StRoomEntity s ORDER BY s.click DESC") List findPopularRoom(); - @Query("SELECT Home_RoomResponseDto(s) FROM StRoomEntity s") + @Query("SELECT new mos.mosback.web.dto.Home_RoomResponseDto(s) FROM StRoomEntity s") List findHomeStRoomField(); - @Query("SELECT Home_RoomResponseDto(s) FROM StRoomEntity s WHERE s.category = :category") + @Query("SELECT new mos.mosback.web.dto.Home_RoomResponseDto(s) FROM StRoomEntity s WHERE s.category = :category") List findByCategory(@Param("category") String category); diff --git a/src/main/java/mos/mosback/repository/UserRepository.java b/src/main/java/mos/mosback/repository/UserRepository.java index f22b4f4..9318e72 100644 --- a/src/main/java/mos/mosback/repository/UserRepository.java +++ b/src/main/java/mos/mosback/repository/UserRepository.java @@ -27,6 +27,6 @@ public interface UserRepository extends JpaRepository { Optional findById(Long id); - @Query("SELECT Home_nickResponseDto(u) FROM User u") + @Query("SELECT new mos.mosback.web.dto.Home_nickResponseDto (u) FROM User u") Home_nickResponseDto findNickname(); } diff --git a/src/main/java/mos/mosback/service/StRoomService.java b/src/main/java/mos/mosback/service/StRoomService.java index 7411593..f02c479 100644 --- a/src/main/java/mos/mosback/service/StRoomService.java +++ b/src/main/java/mos/mosback/service/StRoomService.java @@ -9,6 +9,8 @@ import mos.mosback.web.dto.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.EntityNotFoundException; import java.time.LocalDateTime; import java.util.List; import java.util.stream.Collectors; @@ -96,7 +98,7 @@ public void memberJoin(StRoomMemberJoinRequestDto requestDto) { studyMember.setRoomId(requestDto.getRoomID()); studyMember.setStatus(MemberStatus.Waiting); studyMember.setAnswer(requestDto.getAnswer()); - /*studyMember.setMemberId(requestDto.getID()); //세션값-멤버아이디 넣어주기*/ + studyMember.setMemberId(studyMember.getMemberId()); studyMemberRepository.save(studyMember); } catch (Exception e) { e.printStackTrace(); @@ -109,4 +111,15 @@ public List getRecruitingStudies() { return recruitingStudies; } + + public QuestionDto getQuestionById(Long roomId) { + StRoomEntity stRoomEntity = stRoomRepository.findById(roomId) + .orElseThrow(() -> new EntityNotFoundException("Room not found")); + + QuestionDto responseDTO = new QuestionDto(); + responseDTO.setQuestion(stRoomEntity.getQuest()); + + return responseDTO; + + } } \ No newline at end of file From abfbee4c8b288df004f5a0e95e98e79ecd40dba9 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Thu, 21 Sep 2023 01:58:24 +0900 Subject: [PATCH 18/60] =?UTF-8?q?=EB=8B=89=EB=84=A4=EC=9E=84=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 + .../Filter/JwtAuthenticationFilter.java | 34 ----- .../mosback/Provider/JwtTokenProvider.java | 75 ---------- .../mos/mosback/config/EncryptionUtils.java | 28 ---- .../java/mos/mosback/config/MailConfig.java | 37 ----- .../mosback/controller/StRoomController.java | 2 + .../mosback/controller/UserController.java | 94 ------------ .../java/mos/mosback/data/entity/User.java | 114 --------------- .../mosback/domain/posts/StRoomEntity.java | 7 +- .../mosback/repository/StRoomRepository.java | 2 + .../mosback/repository/UserRepository.java | 32 ----- .../mos/mosback/service/StRoomService.java | 2 + .../java/mos/mosback/service/UserService.java | 134 ------------------ .../java/mos/mosback/web/dto/FindPWDTO.java | 9 -- .../mosback/web/dto/Home_nickResponseDto.java | 2 +- .../java/mos/mosback/web/dto/LoginDTO.java | 12 -- .../java/mos/mosback/web/dto/MailDTO.java | 14 -- .../java/mos/mosback/web/dto/SignUpDTO.java | 31 ---- .../java/mos/mosback/web/dto/UserInfoDto.java | 26 ---- .../mos/mosback/web/dto/UserUpdateDTO.java | 18 --- src/main/resources/application-jwt.yml | 10 ++ src/main/resources/application-oauth.yml | 42 ++++++ src/main/resources/application.properties | 8 +- src/main/resources/application.yml | 39 +++++ src/main/resources/templates/index.html | 47 +----- 25 files changed, 109 insertions(+), 712 deletions(-) delete mode 100644 src/main/java/mos/mosback/Filter/JwtAuthenticationFilter.java delete mode 100644 src/main/java/mos/mosback/Provider/JwtTokenProvider.java delete mode 100644 src/main/java/mos/mosback/config/EncryptionUtils.java delete mode 100644 src/main/java/mos/mosback/config/MailConfig.java delete mode 100644 src/main/java/mos/mosback/controller/UserController.java delete mode 100644 src/main/java/mos/mosback/data/entity/User.java delete mode 100644 src/main/java/mos/mosback/repository/UserRepository.java delete mode 100644 src/main/java/mos/mosback/service/UserService.java delete mode 100644 src/main/java/mos/mosback/web/dto/FindPWDTO.java delete mode 100644 src/main/java/mos/mosback/web/dto/LoginDTO.java delete mode 100644 src/main/java/mos/mosback/web/dto/MailDTO.java delete mode 100644 src/main/java/mos/mosback/web/dto/SignUpDTO.java delete mode 100644 src/main/java/mos/mosback/web/dto/UserInfoDto.java delete mode 100644 src/main/java/mos/mosback/web/dto/UserUpdateDTO.java create mode 100644 src/main/resources/application-jwt.yml create mode 100644 src/main/resources/application-oauth.yml create mode 100644 src/main/resources/application.yml diff --git a/build.gradle b/build.gradle index ff2e647..fa840fd 100644 --- a/build.gradle +++ b/build.gradle @@ -60,6 +60,8 @@ dependencies { implementation 'org.mariadb.jdbc:mariadb-java-client:3.0.3' + implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' + implementation 'com.auth0:java-jwt:4.2.1' // lombok diff --git a/src/main/java/mos/mosback/Filter/JwtAuthenticationFilter.java b/src/main/java/mos/mosback/Filter/JwtAuthenticationFilter.java deleted file mode 100644 index 302aef2..0000000 --- a/src/main/java/mos/mosback/Filter/JwtAuthenticationFilter.java +++ /dev/null @@ -1,34 +0,0 @@ -package mos.mosback.Filter; - -import mos.mosback.Provider.JwtTokenProvider; -import lombok.RequiredArgsConstructor; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.web.filter.GenericFilterBean; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import java.io.IOException; - -@RequiredArgsConstructor -public class JwtAuthenticationFilter extends GenericFilterBean { - - private final JwtTokenProvider jwtTokenprovider; - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - // 헤더에서 JWT 를 받아옵니다. - String token = jwtTokenprovider.resolveToken((HttpServletRequest) request); - // 유효한 토큰인지 확인합니다. - if (token != null && jwtTokenprovider.validateToken(token)) { - // 토큰이 유효하면 토큰으로부터 유저 정보를 받아옵니다. - Authentication authentication = jwtTokenprovider.getAuthentication(token); - // SecurityContext 에 Authentication 객체를 저장합니다. - SecurityContextHolder.getContext().setAuthentication(authentication); - } - chain.doFilter(request, response); - } -} \ No newline at end of file diff --git a/src/main/java/mos/mosback/Provider/JwtTokenProvider.java b/src/main/java/mos/mosback/Provider/JwtTokenProvider.java deleted file mode 100644 index 85bd5ff..0000000 --- a/src/main/java/mos/mosback/Provider/JwtTokenProvider.java +++ /dev/null @@ -1,75 +0,0 @@ -package mos.mosback.Provider; - -import io.jsonwebtoken.Claims; -import io.jsonwebtoken.Jws; -import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.SignatureAlgorithm; -import io.jsonwebtoken.security.Keys; -import lombok.RequiredArgsConstructor; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.stereotype.Component; - -import javax.annotation.PostConstruct; -import javax.servlet.http.HttpServletRequest; -import java.security.Key; -import java.util.Date; - -@RequiredArgsConstructor -@Component -public class JwtTokenProvider { - private static Key secretKey; // Key 타입으로 변경 - - // 토큰 유효시간 30분 - private static long tokenValidTime = 60 * 60 * 1000L; - - private final UserDetailsService userDetailsService; - - // 객체 초기화, secretKey를 Base64로 인코딩한다. - @PostConstruct - protected void init() { - secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256); - } - - // JWT 토큰 생성 - public static String createToken(String userPk, String userPassword) { - Claims claims = Jwts.claims().setSubject(userPk); // JWT payload 에 저장되는 정보단위, 보통 여기서 user를 식별하는 값을 넣는다. - claims.put("password", userPassword); // 정보는 key / value 쌍으로 저장된다. - Date now = new Date(); - return Jwts.builder() - .setClaims(claims) // 정보 저장 - .setIssuedAt(now) // 토큰 발행 시간 정보 - .setExpiration(new Date(now.getTime() + tokenValidTime)) // set Expire Time - .signWith(secretKey, SignatureAlgorithm.HS256) // 사용할 암호화 알고리즘과 - // signature 에 들어갈 secret값 세팅 - .compact(); - } - - // JWT 토큰에서 인증 정보 조회 - public Authentication getAuthentication(String token) { - UserDetails userDetails = userDetailsService.loadUserByUsername(this.getUserPk(token)); - return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities()); - } - - // 토큰에서 회원 정보 추출 - public String getUserPk(String token) { - return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getSubject(); - } - - // Request의 Header에서 token 값을 가져옵니다. "Authorization" : "TOKEN값' - public String resolveToken(HttpServletRequest request) { - return request.getHeader("Authorization"); - } - - // 토큰의 유효성 + 만료일자 확인 - public boolean validateToken(String jwtToken) { - try { - Jws claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(jwtToken); - return !claims.getBody().getExpiration().before(new Date()); - } catch (Exception e) { - return false; - } - } -} \ No newline at end of file diff --git a/src/main/java/mos/mosback/config/EncryptionUtils.java b/src/main/java/mos/mosback/config/EncryptionUtils.java deleted file mode 100644 index f100125..0000000 --- a/src/main/java/mos/mosback/config/EncryptionUtils.java +++ /dev/null @@ -1,28 +0,0 @@ -package mos.mosback.config; - -import java.security.MessageDigest; - -public class EncryptionUtils { - - public static String encryptSHA256(String s) { - return encrypt(s, "SHA-256"); - } - - public static String encryptMD5(String s) { - return encrypt(s, "MD5"); - } - - public static String encrypt(String s, String messageDigest) { - try { - MessageDigest md = MessageDigest.getInstance(messageDigest); - byte[] passBytes = s.getBytes(); - md.reset(); - byte[] digested = md.digest(passBytes); - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < digested.length; i++) sb.append(Integer.toString((digested[i]&0xff) + 0x100, 16).substring(1)); - return sb.toString(); - } catch (Exception e) { - return s; - } - } -} diff --git a/src/main/java/mos/mosback/config/MailConfig.java b/src/main/java/mos/mosback/config/MailConfig.java deleted file mode 100644 index 86a262a..0000000 --- a/src/main/java/mos/mosback/config/MailConfig.java +++ /dev/null @@ -1,37 +0,0 @@ -package mos.mosback.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.mail.javamail.JavaMailSender; -import org.springframework.mail.javamail.JavaMailSenderImpl; - -import java.util.Properties; - -@Configuration -public class MailConfig { - @Bean - public JavaMailSender javaMailService() { - JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl(); - - javaMailSender.setHost("smtp.naver.com"); - javaMailSender.setUsername("dmsthf1225@naver.com"); - javaMailSender.setPassword("dmsthf12fkqb"); - - javaMailSender.setPort(465); - - javaMailSender.setJavaMailProperties(getMailProperties()); - - return javaMailSender; - } - - private Properties getMailProperties() { - Properties properties = new Properties(); - properties.setProperty("mail.transport.protocol", "smtp"); - properties.setProperty("mail.smtp.auth", "true"); - properties.setProperty("mail.smtp.starttls.enable", "true"); - properties.setProperty("mail.debug", "true"); - properties.setProperty("mail.smtp.ssl.trust","smtp.naver.com"); - properties.setProperty("mail.smtp.ssl.enable","true"); - return properties; - } -} \ No newline at end of file diff --git a/src/main/java/mos/mosback/controller/StRoomController.java b/src/main/java/mos/mosback/controller/StRoomController.java index 78320ef..aab0b95 100644 --- a/src/main/java/mos/mosback/controller/StRoomController.java +++ b/src/main/java/mos/mosback/controller/StRoomController.java @@ -112,6 +112,8 @@ public ResponseEntity> getStudyRoomsByCategory(@PathVariable response.put("studyRooms", studyRooms); // 데이터를 직접 넣음 return ResponseEntity.ok(response); } + + @GetMapping("/question/{roomId}") public ResponseEntity getQuestionById(@PathVariable Long roomId) { try { diff --git a/src/main/java/mos/mosback/controller/UserController.java b/src/main/java/mos/mosback/controller/UserController.java deleted file mode 100644 index ab8dd68..0000000 --- a/src/main/java/mos/mosback/controller/UserController.java +++ /dev/null @@ -1,94 +0,0 @@ -package mos.mosback.controller; - -import mos.mosback.data.entity.User; -import mos.mosback.repository.UserRepository; -import mos.mosback.service.UserService; -import mos.mosback.web.dto.*; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.*; - -import javax.servlet.http.HttpSession; -import javax.transaction.Transactional; -import java.util.List; - -@Controller -@RequestMapping("/api") -public class UserController { - - - private UserService userService; - private UserRepository userRepository; - - public UserController(UserService userService, UserRepository userRepository) { - this.userService = userService; - this.userRepository = userRepository; - } - - //회원가입 - @PostMapping("/signup") - public ResponseEntity join(@RequestBody SignUpDTO signUpDTO) { - if(userService.isEmailDuplicate(signUpDTO.getEmail())) { - return ResponseEntity.status(400).body("Email already exists"); - } - userService.join(signUpDTO); - return ResponseEntity.ok("Join Success!"); - } - - //로그인 - @PostMapping("/login") - public ResponseEntity login(@RequestBody LoginDTO loginDTO, HttpSession session) { - if(userService.isEmailDuplicate(loginDTO.getEmail())) { - if(userService.comparePassword(loginDTO.getEmail(), loginDTO.getPassword())) { - User user = userRepository.findByEmail(loginDTO.getEmail()); - if(user != null) { - // 세션에 유저 객체를 저장 - session.setAttribute("user", user); - return ResponseEntity.ok("로그인 성공"); - } - return ResponseEntity.status(400).body("사용자를 찾을 수 없습니다."); - } - return ResponseEntity.status(400).body("비밀번호가 틀렸습니다."); - } - return ResponseEntity.status(400).body("사용자를 찾을 수 없습니다."); - } - //이메일 중복확인 - @GetMapping("/user-emails/{email}/exists") - public ResponseEntity isEmailDuplicate(@PathVariable String email){ - return ResponseEntity.ok(userService.isEmailDuplicate(email)); - } - - //비밀번호 변경 - @Transactional - @PostMapping("/find") - public ResponseEntity findPw(@RequestBody FindPWDTO findPWDTO){ - if(userService.findPassword(findPWDTO)) { - MailDTO mailDTO = userService.createMailAndChangePassword(findPWDTO.getEmail()); - userService.mailSend(mailDTO); - return ResponseEntity.ok("임시 비밀번호 메일 전송, 변경 완료"); - } - else{ - return ResponseEntity.status(400).body("이메일과 이름이 일치하지 않습니다."); - } - } - - @Transactional - @PostMapping("/send/Email") - public ResponseEntity sendEmail(@RequestParam("userEmail") String userEmail){ - MailDTO mailDTO = userService.createMailAndChangePassword(userEmail); - userService.mailSend(mailDTO); - - return ResponseEntity.ok("임시 비밀번호 메일 전송, 변경 완료"); - } - - @GetMapping("/nickname") - public ResponseEntity findNicknameO() { - Home_nickResponseDto nicknameDto = userService.getNickname(); - - if (nicknameDto != null) { - return ResponseEntity.ok(nicknameDto.getNickname()); - } else { - return ResponseEntity.notFound().build(); - } - } -} \ No newline at end of file diff --git a/src/main/java/mos/mosback/data/entity/User.java b/src/main/java/mos/mosback/data/entity/User.java deleted file mode 100644 index a087229..0000000 --- a/src/main/java/mos/mosback/data/entity/User.java +++ /dev/null @@ -1,114 +0,0 @@ -package mos.mosback.data.entity; - -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import mos.mosback.domain.posts.StRoomEntity; -import mos.mosback.web.dto.UserUpdateDTO; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; - -import javax.persistence.*; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.List; - -@Entity -@Table(name = "user") -@NoArgsConstructor -@Getter -@Setter -public class User implements UserDetails { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(nullable = false, unique = true) - private String email; - - @Column(nullable = false) - private String password; - - @Column(nullable = false) - private String name; - - @Column(nullable = false) - private String nickname; - - @Column(nullable = false) - private Date duration; - - @Column(nullable = false) - private String message; - - @Column(nullable = false) - private String company; - - @ManyToOne - @JoinColumn(name = "roomID") - private StRoomEntity stRoom; - - @Builder - public User(String email, String password, String name, String nickname, Date duration, String message, String company){ - this.email = email; - this.password = cryptopassword(password); - this.name = name; - this.nickname = nickname; - this.duration = duration; - this.message = message; - this.company = company; - } - - public void update(UserUpdateDTO userUpdateDTO) { - this.email = userUpdateDTO.getEmail(); - this.password = cryptopassword(userUpdateDTO.getPassword()); - this.name = userUpdateDTO.getName(); - this.nickname = userUpdateDTO.getNickname(); - this.duration = userUpdateDTO.getDuration(); - this.message = userUpdateDTO.getMessage(); - this.company = userUpdateDTO.getCompany(); - } - - public void updatePw(String password) { - this.password = cryptopassword(password); - } - - public String cryptopassword(String password) { - BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); - String encodedPassword = passwordEncoder.encode(password); - return encodedPassword; - } - - @Override - public Collection getAuthorities() { - return null; - } - - @Override - public String getUsername() { - return getEmail(); - } - - @Override - public boolean isAccountNonExpired() { - return false; - } - - @Override - public boolean isAccountNonLocked() { - return false; - } - - @Override - public boolean isCredentialsNonExpired() { - return false; - } - - @Override - public boolean isEnabled() { - return false; - } -} diff --git a/src/main/java/mos/mosback/domain/posts/StRoomEntity.java b/src/main/java/mos/mosback/domain/posts/StRoomEntity.java index 6b7efa0..506ead6 100644 --- a/src/main/java/mos/mosback/domain/posts/StRoomEntity.java +++ b/src/main/java/mos/mosback/domain/posts/StRoomEntity.java @@ -3,11 +3,8 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import mos.mosback.data.entity.User; import javax.persistence.*; -import java.time.LocalDate; -import java.time.ZoneId; import java.util.*; @Getter // 롬복 어노테이션 @@ -50,8 +47,8 @@ public class StRoomEntity extends BaseTimeEntity { public StRoomEntity(String title, String goal, String rules, String quest, String category, String intro, int memberNum, int maxMember ,String mod, boolean onOff, String location,int online, - Date startDate, Date endDate, List studyDayEntities, - User leader,User nickname) { + Date startDate, Date endDate, List studyDayEntities + ) { this.title = title; this.goal = goal; diff --git a/src/main/java/mos/mosback/repository/StRoomRepository.java b/src/main/java/mos/mosback/repository/StRoomRepository.java index a3b93b0..11c4a86 100644 --- a/src/main/java/mos/mosback/repository/StRoomRepository.java +++ b/src/main/java/mos/mosback/repository/StRoomRepository.java @@ -3,6 +3,7 @@ //Entity 클래스와 Entity레파지토리 위치 같아야함 import mos.mosback.domain.posts.StRoomEntity; import mos.mosback.web.dto.Home_RoomResponseDto; +import mos.mosback.web.dto.Home_nickResponseDto; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -28,4 +29,5 @@ public interface StRoomRepository extends JpaRepository { @Query("SELECT new mos.mosback.web.dto.Home_RoomResponseDto(s) FROM StRoomEntity s WHERE s.startDate > current_timestamp") List findRecruitingStudies(); + } \ No newline at end of file diff --git a/src/main/java/mos/mosback/repository/UserRepository.java b/src/main/java/mos/mosback/repository/UserRepository.java deleted file mode 100644 index 9318e72..0000000 --- a/src/main/java/mos/mosback/repository/UserRepository.java +++ /dev/null @@ -1,32 +0,0 @@ -package mos.mosback.repository; - -import mos.mosback.data.entity.User; -import mos.mosback.web.dto.Home_nickResponseDto; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -import java.util.List; -import java.util.Optional; - -public interface UserRepository extends JpaRepository { -// Optional findByEmail(String email); // 이메일 통해 회원 조회하기 위함 - - - -// boolean existsByEmail(String email); - -// void saveUser(User user); - -// UserInfo findUserByUserId(String userEmail); - -// void updateUserPassword(Long id, String pw); -// boolean existsByNickname(String nickname); - - User findByEmail(String email); - Optional findById(Long id); - - - @Query("SELECT new mos.mosback.web.dto.Home_nickResponseDto (u) FROM User u") - Home_nickResponseDto findNickname(); -} diff --git a/src/main/java/mos/mosback/service/StRoomService.java b/src/main/java/mos/mosback/service/StRoomService.java index f02c479..abcf4fc 100644 --- a/src/main/java/mos/mosback/service/StRoomService.java +++ b/src/main/java/mos/mosback/service/StRoomService.java @@ -4,6 +4,7 @@ import mos.mosback.domain.posts.MemberStatus; import mos.mosback.domain.posts.StRoomEntity; import mos.mosback.domain.posts.StudyMemberEntity; +import mos.mosback.login.domain.user.repository.UserRepository; import mos.mosback.repository.StRoomRepository; import mos.mosback.repository.StudyMemberRepository; import mos.mosback.web.dto.*; @@ -122,4 +123,5 @@ public QuestionDto getQuestionById(Long roomId) { return responseDTO; } + } \ No newline at end of file diff --git a/src/main/java/mos/mosback/service/UserService.java b/src/main/java/mos/mosback/service/UserService.java deleted file mode 100644 index f4aa4f8..0000000 --- a/src/main/java/mos/mosback/service/UserService.java +++ /dev/null @@ -1,134 +0,0 @@ -package mos.mosback.service; -import lombok.RequiredArgsConstructor; -import mos.mosback.data.entity.User; -import mos.mosback.repository.UserRepository; -import mos.mosback.web.dto.*; -import org.springframework.mail.SimpleMailMessage; -import org.springframework.mail.javamail.JavaMailSender; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.stereotype.Service; - -import javax.transaction.Transactional; -import java.util.List; -import java.util.Optional; - -@Service -@Transactional -@RequiredArgsConstructor -public class UserService implements UserDetailsService { - private final UserRepository userRepository; - private final JavaMailSender mailSender; - - public void join(SignUpDTO signUpDTO) { - userRepository.save(signUpDTO.toEntity()); - } - - public boolean isEmailDuplicate(String email) { - User findUser = userRepository.findByEmail(email); - return findUser != null; - } - - public User findByEmail(String email) { - return userRepository.findByEmail(email); - } - - public Optional getById(Long id) { - return userRepository.findById(id); - } - - public boolean comparePassword(String email,String password) { - User findUser = userRepository.findByEmail(email); - - BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); - boolean isMatched = passwordEncoder.matches(password, findUser.getPassword()); - - if(isMatched) { - return true; - } - else{ - return false; - } - } - - public User updateUserInfo(User user, UserUpdateDTO userUpdateDTO) { - user.update(userUpdateDTO); - return user; - } - - public boolean findPassword(FindPWDTO findPWDTO) { - User user = userRepository.findByEmail(findPWDTO.getEmail()); - if(user.getName().equals(findPWDTO.getName())) { - return true; - } - else{ - return false; - } - } - - // 메일 내용을 생성하고 임시 비밀번호로 회원 비밀번호를 변경 - public MailDTO createMailAndChangePassword(String userEmail) { - String tempPassword = getTempPassword(); - MailDTO mailDTO = new MailDTO(); - mailDTO.setAddress(userEmail); - mailDTO.setTitle("취업어플리케이션 MOS의 임시비밀번호 안내 이메일 입니다."); - mailDTO.setMessage("안녕하세요. MOS의 임시비밀번호 안내 관련 이메일 입니다." + " 회원님의 임시 비밀번호는 " - + tempPassword + " 입니다." + "로그인 후에 비밀번호를 변경을 해주세요"); - updatePassword(tempPassword,userEmail); - return mailDTO; - } - - //임시 비밀번호로 업데이트 - public void updatePassword(String str, String userEmail){ - User user = userRepository.findByEmail(userEmail); - user.updatePw(str); - } - - //랜덤함수로 임시비밀번호 구문 만들기 - public String getTempPassword(){ - char[] charSet = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', - 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; - - String str = ""; - - // 문자 배열 길이의 값을 랜덤으로 10개를 뽑아 구문을 작성함 - int idx = 0; - for (int i = 0; i < 10; i++) { - idx = (int) (charSet.length * Math.random()); - str += charSet[idx]; - } - return str; - } - - // 메일보내기 - public void mailSend(MailDTO mailDTO) { - SimpleMailMessage message = new SimpleMailMessage(); - message.setTo(mailDTO.getAddress()); - message.setSubject(mailDTO.getTitle()); - message.setText(mailDTO.getMessage()); - message.setFrom("dmsthf1225@naver.com"); - message.setReplyTo("dmsthf1225@naver.com"); - mailSender.send(message); - } - - @Override - public UserDetails loadUserByUsername(String userEmail) throws UsernameNotFoundException { - return userRepository.findByEmail(userEmail); - } - - public void save(UserInfoDto userInfoDto) { - - } - -// @Transactional(readOnly = true) -// public List findRoomsInHome() { -// -// return stRoomRepository.findHomeStRoomField(); -// } - - public Home_nickResponseDto getNickname() { - return userRepository.findNickname(); - } -} \ No newline at end of file diff --git a/src/main/java/mos/mosback/web/dto/FindPWDTO.java b/src/main/java/mos/mosback/web/dto/FindPWDTO.java deleted file mode 100644 index f87a9c4..0000000 --- a/src/main/java/mos/mosback/web/dto/FindPWDTO.java +++ /dev/null @@ -1,9 +0,0 @@ -package mos.mosback.web.dto; - -import lombok.Getter; - -@Getter -public class FindPWDTO { - private String email; - private String name; -} diff --git a/src/main/java/mos/mosback/web/dto/Home_nickResponseDto.java b/src/main/java/mos/mosback/web/dto/Home_nickResponseDto.java index af77d4a..f32b900 100644 --- a/src/main/java/mos/mosback/web/dto/Home_nickResponseDto.java +++ b/src/main/java/mos/mosback/web/dto/Home_nickResponseDto.java @@ -1,5 +1,5 @@ package mos.mosback.web.dto; -import mos.mosback.data.entity.User; +import mos.mosback.login.domain.user.User; import lombok.Getter; diff --git a/src/main/java/mos/mosback/web/dto/LoginDTO.java b/src/main/java/mos/mosback/web/dto/LoginDTO.java deleted file mode 100644 index ea54211..0000000 --- a/src/main/java/mos/mosback/web/dto/LoginDTO.java +++ /dev/null @@ -1,12 +0,0 @@ -package mos.mosback.web.dto; - -import lombok.Getter; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -@Getter -public class LoginDTO { - private String email; - private String password; - -} diff --git a/src/main/java/mos/mosback/web/dto/MailDTO.java b/src/main/java/mos/mosback/web/dto/MailDTO.java deleted file mode 100644 index 3b0ce2d..0000000 --- a/src/main/java/mos/mosback/web/dto/MailDTO.java +++ /dev/null @@ -1,14 +0,0 @@ -package mos.mosback.web.dto; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@AllArgsConstructor -@NoArgsConstructor -public class MailDTO { - private String address; - private String title; - private String message; -} diff --git a/src/main/java/mos/mosback/web/dto/SignUpDTO.java b/src/main/java/mos/mosback/web/dto/SignUpDTO.java deleted file mode 100644 index f8c6e14..0000000 --- a/src/main/java/mos/mosback/web/dto/SignUpDTO.java +++ /dev/null @@ -1,31 +0,0 @@ -package mos.mosback.web.dto; -import lombok.Builder; -import lombok.Getter; -import lombok.Setter; -import mos.mosback.data.entity.User; - -import java.util.Date; - -@Getter -@Setter -public class SignUpDTO { - private String email; - private String password; - private String name; - private String nickname; - private Date duration; - private String message; - private String company; - - public User toEntity() { - return User.builder() - .email(email) - .password(password) - .name(name) - .nickname(nickname) - .duration(duration) - .message(message) - .company(company) - .build(); - } -} diff --git a/src/main/java/mos/mosback/web/dto/UserInfoDto.java b/src/main/java/mos/mosback/web/dto/UserInfoDto.java deleted file mode 100644 index d922c5f..0000000 --- a/src/main/java/mos/mosback/web/dto/UserInfoDto.java +++ /dev/null @@ -1,26 +0,0 @@ -package mos.mosback.web.dto; - -public class UserInfoDto { - - private String email; - private String password; - - // 생성자, 게터/세터 등 생략 - - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } -} diff --git a/src/main/java/mos/mosback/web/dto/UserUpdateDTO.java b/src/main/java/mos/mosback/web/dto/UserUpdateDTO.java deleted file mode 100644 index 1c6d4d7..0000000 --- a/src/main/java/mos/mosback/web/dto/UserUpdateDTO.java +++ /dev/null @@ -1,18 +0,0 @@ -package mos.mosback.web.dto; - -import lombok.Getter; -import lombok.Setter; - -import java.util.Date; - -@Getter -@Setter -public class UserUpdateDTO { - private String email; - private String password; - private String name; - private String nickname; - private Date duration; - private String message; - private String company; -} diff --git a/src/main/resources/application-jwt.yml b/src/main/resources/application-jwt.yml new file mode 100644 index 0000000..26d0d11 --- /dev/null +++ b/src/main/resources/application-jwt.yml @@ -0,0 +1,10 @@ +jwt: + secretKey: 'dfadfekndchnsdifqld125654x8sdfnjldsncuelsdfs45x321df' + + access: + expiration: 3600000 # 1??(60?) (1000L(ms -> s) * 60L(s -> m) * 60L(m -> h)) + header: Authorization + + refresh: + expiration: 1209600000 # (1000L(ms -> s) * 60L(s -> m) * 60L(m -> h) * 24L(h -> ??) * 14(2?)) + header: Authorization-refresh \ No newline at end of file diff --git a/src/main/resources/application-oauth.yml b/src/main/resources/application-oauth.yml new file mode 100644 index 0000000..08ca2a4 --- /dev/null +++ b/src/main/resources/application-oauth.yml @@ -0,0 +1,42 @@ +spring: + security: + oauth2: + client: + registration: + google: + client-id: 729954756779-2usa0d48vh0048r4vmmljtlrlstvcjdh.apps.googleusercontent.com + client-secret: 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 + scope: profile, email + + + naver: + client-id: jg5_V_oaR2k60xfasDRa + client-secret: XJ2kRT_oa8 + redirect-uri: http://localhost:8080/login/oauth2/code/naver + authorization-grant-type: authorization_code + scope: name, email, profile_image + client-name: Naver + + + kakao: + client-id: bbe971abb2538851ddabe4ef20d76744 + client-secret: oScTITuccuMT1o8C6X4Vv1arBKJkNzSE + redirect-uri: http://localhost:8080/login/oauth2/code/kakao + client-authentication-method: POST + authorization-grant-type: authorization_code + scope: profile_nickname, profile_image + client-name: Kakao + + + provider: + naver: + authorization_uri: https://nid.naver.com/oauth2.0/authorize + token_uri: https://nid.naver.com/oauth2.0/token + user-info-uri: https://openapi.naver.com/v1/nid/me + user_name_attribute: response + + kakao: + authorization-uri: https://kauth.kakao.com/oauth/authorize + token-uri: https://kauth.kakao.com/oauth/token + user-info-uri: https://kapi.kakao.com/v2/user/me + user-name-attribute: id diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 94d217d..78cca07 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,19 +1,19 @@ -# DB ?? ?? +# DB spring.datasource.url=jdbc:h2:mem:testdb spring.datasource.hikari.jdbc-url=jdbc:h2:mem:testdb;MODE=MYSQL -# DB (H2) ?? ?? +# DB (H2) spring.h2.console.enabled=true spring.h2.console.path=/h2-console -# JPA ?? ?? +# JPA spring.jpa.show_sql = true spring.jpa.hibernate.ddl-auto=update spring.jpa.open-in-view=false spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect -# Spring ?? ?? +# Spring spring.mvc.servlet.load-on-startup=1 spring.profiles.include=oauth spring.session.store-type=jdbc diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..3af23a9 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,39 @@ +spring: + profiles: + group: + "local" : "local, jwt, oauth" + active : local + +--- +spring: + config: + activate: + on-profile: "local" + + h2: + console: + enabled: true + path: /h2-console + + datasource: + driver-class-name: org.h2.Driver + url: jdbc:h2:mem:testdb + username: sa + password: + + server: + port: 8080 + + main: + allow-circular-references: true + + jpa: + show-sql: true + database-platform: org.hibernate.dialect.H2Dialect + properties: + hibernate: + format_sql: true + show_sql: true + + hibernate: + ddl-auto: create diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index a6c4d93..c87dcc5 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -1,44 +1,3 @@ - - - - - - Study Groups - - -

Study Groups

-study groups - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TitleModeNumber of Members
-Create Study Group - - +Kakao Login
+Google Login
+Naver Login
\ No newline at end of file From 06762fa8111ebe631769d87165f921dd57d22c95 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Thu, 21 Sep 2023 03:19:26 +0900 Subject: [PATCH 19/60] =?UTF-8?q?=EC=A0=91=EA=B7=BC=EA=B0=80=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/mos/mosback/controller/StRoomController.java | 2 +- src/test/java/mos/mosback/domain/posts/PostsRepository.java | 0 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 src/test/java/mos/mosback/domain/posts/PostsRepository.java diff --git a/src/main/java/mos/mosback/controller/StRoomController.java b/src/main/java/mos/mosback/controller/StRoomController.java index aab0b95..214b1fb 100644 --- a/src/main/java/mos/mosback/controller/StRoomController.java +++ b/src/main/java/mos/mosback/controller/StRoomController.java @@ -15,7 +15,7 @@ import java.util.Map; @RestController -@RequestMapping("/api/studyRoom") //URL 패턴 +@RequestMapping("/studyRoom") //URL 패턴 public class StRoomController { private final StRoomService stRoomService; // stRoomService를 주입. diff --git a/src/test/java/mos/mosback/domain/posts/PostsRepository.java b/src/test/java/mos/mosback/domain/posts/PostsRepository.java deleted file mode 100644 index e69de29..0000000 From b514843c82b70aa79a8df6fe98f182f41c840fc2 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Fri, 22 Sep 2023 22:13:44 +0900 Subject: [PATCH 20/60] =?UTF-8?q?=EC=B6=A9=EB=8F=8C=20=ED=95=B4=EA=B2=B0?= =?UTF-8?q?=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mosback/controller/TodoController.java | 48 +++++++++++++++++++ .../mos/mosback/login/domain/user/User.java | 20 ++++++++ .../user/conrtoller/UserController.java | 27 +++++++++++ .../login/domain/user/dto/UserSignUpDto.java | 7 +++ .../user/repository/UserRepository.java | 20 ++++++++ .../domain/user/service/UserService.java | 40 ++++++++++++++++ .../login/global/config/CorsConfig.java | 9 +++- .../login/global/config/SecurityConfig.java | 29 ++--------- .../login/handler/LoginSuccessHandler.java | 8 ++++ 9 files changed, 182 insertions(+), 26 deletions(-) create mode 100644 src/main/java/mos/mosback/controller/TodoController.java diff --git a/src/main/java/mos/mosback/controller/TodoController.java b/src/main/java/mos/mosback/controller/TodoController.java new file mode 100644 index 0000000..3f8acd6 --- /dev/null +++ b/src/main/java/mos/mosback/controller/TodoController.java @@ -0,0 +1,48 @@ +package mos.mosback.controller; +import mos.mosback.domain.posts.ToDoEntity; +import mos.mosback.service.ToDoService; +import mos.mosback.web.dto.ToDoRequestDto; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/todo") //URL 패턴 +public class TodoController { + private final ToDoService toDoService; + + @Autowired + public TodoController(ToDoService toDoService) { + this.toDoService = toDoService; + } + + @PostMapping("/add") + public ResponseEntity addTodo(@RequestBody ToDoRequestDto requestDto){ + ToDoEntity toDoEntity = toDoService.add(requestDto.getTodoContent()); + return ResponseEntity.status(HttpStatus.CREATED).body("TodoList 추가 완료. index : " +toDoEntity.getTodoIdx()); + } + @PutMapping("/update/{TodoIdx}") + public ResponseEntity updateTodo(@PathVariable Long TodoIdx, @RequestBody ToDoRequestDto requestDto) { + try { + ToDoEntity updatedToDo = toDoService.update(TodoIdx, requestDto.getTodoContent(), requestDto.isCompleted()); + return ResponseEntity.ok("ToDo 업데이트 완료. Index: " + TodoIdx); + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body("NOT FOUND TODO"); + } + } + + @DeleteMapping("/delete/{TodoIdx}") + public ResponseEntity deleteTodo(@PathVariable Long TodoIdx) { + try { + toDoService.delete(TodoIdx); + return ResponseEntity.ok("ToDo 삭제 완료. Index: " + TodoIdx); + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body("NOT FOUND TODO"); + } + } + + +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/login/domain/user/User.java b/src/main/java/mos/mosback/login/domain/user/User.java index f8b0960..577e4c1 100644 --- a/src/main/java/mos/mosback/login/domain/user/User.java +++ b/src/main/java/mos/mosback/login/domain/user/User.java @@ -2,7 +2,10 @@ import lombok.*; +<<<<<<< Updated upstream import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +======= +>>>>>>> Stashed changes import org.springframework.security.crypto.password.PasswordEncoder; import javax.persistence.*; @@ -23,6 +26,7 @@ public class User { private String email; // 이메일 private String password; // 비밀번호 +<<<<<<< Updated upstream private String name; private String nickname; // 닉네임 @@ -30,6 +34,11 @@ public class User { private Date str_duration; private Date end_duration; +======= + private String nickname; // 닉네임 + private String imageUrl; // 프로필 이미지 + private Date duration; +>>>>>>> Stashed changes private String message; private String company; @Enumerated(EnumType.STRING) @@ -52,6 +61,7 @@ public void passwordEncode(PasswordEncoder passwordEncoder) { this.password = passwordEncoder.encode(this.password); } +<<<<<<< Updated upstream //==setter==// @@ -135,17 +145,24 @@ public void setCompany(String company) { this.company = company; } +======= +>>>>>>> Stashed changes //== 유저 필드 업데이트 ==// public void updateNickname(String updateNickname) { this.nickname = updateNickname; } +<<<<<<< Updated upstream public void updateStr_duration(Date updateStr_Duration) { this.str_duration = updateStr_Duration; } public void updateEnd_duration(Date updateEnd_duration) { this.end_duration = updateEnd_duration; +======= + public void updateDuration(Date updateDuration) { + this.duration = updateDuration; +>>>>>>> Stashed changes } public void updateMessage(String updateMessage) { @@ -161,6 +178,7 @@ public void updatePassword(String updatePassword, PasswordEncoder passwordEncode this.password = passwordEncoder.encode(updatePassword); } +<<<<<<< Updated upstream public void updatePw(String password) { this.password = cryptopassword(password); } @@ -170,6 +188,8 @@ public String cryptopassword(String password) { return encodedPassword; } +======= +>>>>>>> Stashed changes public void updateRefreshToken(String updateRefreshToken) { this.refreshToken = updateRefreshToken; } diff --git a/src/main/java/mos/mosback/login/domain/user/conrtoller/UserController.java b/src/main/java/mos/mosback/login/domain/user/conrtoller/UserController.java index 7d09590..41b6392 100644 --- a/src/main/java/mos/mosback/login/domain/user/conrtoller/UserController.java +++ b/src/main/java/mos/mosback/login/domain/user/conrtoller/UserController.java @@ -2,6 +2,7 @@ import lombok.RequiredArgsConstructor; import mos.mosback.login.domain.user.User; +<<<<<<< Updated upstream import mos.mosback.login.domain.user.dto.*; import mos.mosback.login.domain.user.repository.UserRepository; import mos.mosback.login.domain.user.service.UserService; @@ -25,18 +26,41 @@ public class UserController { private Map userMap = new HashMap<>(); private JwtService jwtService; +======= +import mos.mosback.login.domain.user.dto.UserSignUpDto; +import mos.mosback.login.domain.user.repository.UserRepository; +import mos.mosback.login.domain.user.service.UserService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.web.bind.annotation.*; + +import java.util.Optional; + + +@RestController +@RequiredArgsConstructor +public class UserController { + + private final UserService userService; + private UserRepository userRepository; +>>>>>>> Stashed changes @PostMapping("/sign-up") public String signUp(@RequestBody UserSignUpDto userSignUpDto) throws Exception { userService.signUp(userSignUpDto); return "회원가입 성공"; } +<<<<<<< Updated upstream // @PostMapping("/profile") // public String createUser(@RequestBody UserProfileDto userProfileDto) throws Exception{ // userService.createUser(userProfileDto); // return "회원정보 등록 성공"; // } +======= +>>>>>>> Stashed changes @GetMapping("/jwt-test") public String jwtTest() { @@ -44,6 +68,7 @@ public String jwtTest() { } +<<<<<<< Updated upstream @GetMapping("/user-emails/{email}/exists") public ResponseEntity checkEmailExists(@PathVariable String email) { Optional existingUser = userRepository.findByEmail(email); @@ -68,4 +93,6 @@ public ResponseEntity sendTemporaryPassword(@RequestBody FindPWDto findP return ResponseEntity.status(400).body("이메일이 존재하지 않거나 이름이 일치하지 않습니다."); } } +======= +>>>>>>> Stashed changes } diff --git a/src/main/java/mos/mosback/login/domain/user/dto/UserSignUpDto.java b/src/main/java/mos/mosback/login/domain/user/dto/UserSignUpDto.java index 7ac32b1..2b5cf78 100644 --- a/src/main/java/mos/mosback/login/domain/user/dto/UserSignUpDto.java +++ b/src/main/java/mos/mosback/login/domain/user/dto/UserSignUpDto.java @@ -11,5 +11,12 @@ public class UserSignUpDto { private String email; private String password; +<<<<<<< Updated upstream +======= + private String nickname; + private Date duration; + private String message; + private String company; +>>>>>>> Stashed changes } \ No newline at end of file diff --git a/src/main/java/mos/mosback/login/domain/user/repository/UserRepository.java b/src/main/java/mos/mosback/login/domain/user/repository/UserRepository.java index 783a108..8842914 100644 --- a/src/main/java/mos/mosback/login/domain/user/repository/UserRepository.java +++ b/src/main/java/mos/mosback/login/domain/user/repository/UserRepository.java @@ -3,7 +3,13 @@ import mos.mosback.login.domain.user.SocialType; import mos.mosback.login.domain.user.User; +<<<<<<< Updated upstream import org.springframework.data.jpa.repository.JpaRepository; +======= +import mos.mosback.web.dto.Home_nickResponseDto; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +>>>>>>> Stashed changes import java.util.Optional; @@ -11,12 +17,19 @@ public interface UserRepository extends JpaRepository { Optional findByEmail(String email); +<<<<<<< Updated upstream //Optional findByNickName(String nickname); Optional findByNickname(String nickname); boolean existsByEmail(String email); +======= + Optional findByNickname(String nickname); + + + Optional findById(Long userId); +>>>>>>> Stashed changes Optional findByRefreshToken(String refreshToken); @@ -28,4 +41,11 @@ public interface UserRepository extends JpaRepository { * 따라서 추가 정보를 입력받아 회원 가입을 진행할 때 소셜 타입, 식별자로 해당 회원을 찾기 위한 메소드 */ Optional findBySocialTypeAndSocialId(SocialType socialType, String socialId); +<<<<<<< Updated upstream +======= + + + + +>>>>>>> Stashed changes } diff --git a/src/main/java/mos/mosback/login/domain/user/service/UserService.java b/src/main/java/mos/mosback/login/domain/user/service/UserService.java index 5148f62..1c2ef49 100644 --- a/src/main/java/mos/mosback/login/domain/user/service/UserService.java +++ b/src/main/java/mos/mosback/login/domain/user/service/UserService.java @@ -2,6 +2,7 @@ import mos.mosback.login.domain.user.Role; import mos.mosback.login.domain.user.User; +<<<<<<< Updated upstream import mos.mosback.login.domain.user.dto.FindPWDto; import mos.mosback.login.domain.user.dto.MailDto; @@ -14,6 +15,13 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UsernameNotFoundException; +======= +import mos.mosback.login.domain.user.dto.UserSignUpDto; +import mos.mosback.login.domain.user.repository.UserRepository; +import lombok.RequiredArgsConstructor; +import mos.mosback.web.dto.Home_nickResponseDto; +import org.springframework.data.jpa.repository.Query; +>>>>>>> Stashed changes import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; @@ -28,26 +36,44 @@ public class UserService { private final UserRepository userRepository; private final PasswordEncoder passwordEncoder; +<<<<<<< Updated upstream private final JavaMailSender mailSender; +======= +>>>>>>> Stashed changes public void signUp(UserSignUpDto userSignUpDto) throws Exception { if (userRepository.findByEmail(userSignUpDto.getEmail()).isPresent()) { throw new Exception("이미 존재하는 이메일입니다."); } +<<<<<<< Updated upstream +======= + if (userRepository.findByNickname(userSignUpDto.getNickname()).isPresent()) { + throw new Exception("이미 존재하는 닉네임입니다."); + } +>>>>>>> Stashed changes User user = User.builder() .email(userSignUpDto.getEmail()) .password(userSignUpDto.getPassword()) +<<<<<<< Updated upstream .role(Role.GUEST) +======= + .nickname(userSignUpDto.getNickname()) + .duration(userSignUpDto.getDuration()) + .message(userSignUpDto.getMessage()) + .company(userSignUpDto.getCompany()) + .role(Role.USER) +>>>>>>> Stashed changes .build(); user.passwordEncode(passwordEncoder); userRepository.save(user); } +<<<<<<< Updated upstream private User getUserByEmail(String email) throws Exception { @@ -106,6 +132,17 @@ public void updateUserProfile(String currentEmail, UserProfileDto userProfileDto // // BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); // boolean isMatched = passwordEncoder.matches(password, findUser.getPassword()); +======= +// public boolean isEmailDuplicate(String email) { +// Optional findUser = userRepository.findByEmail(email); +// return findUser != null; +// } +// public boolean comparePassword(String email,String password) { +// Optional findUser = userRepository.findByEmail(email); +// +// BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); +// boolean isMatched = passwordEncoder.matches(password, userRepository.findByPassword()); +>>>>>>> Stashed changes // // if(isMatched) { // return true; @@ -114,6 +151,7 @@ public void updateUserProfile(String currentEmail, UserProfileDto userProfileDto // return false; // } // } +<<<<<<< Updated upstream // // 메일 내용을 생성하고 임시 비밀번호로 회원 비밀번호를 변경 public MailDto createMailAndChangePassword(String userEmail) { @@ -177,6 +215,8 @@ public Optional loadUserByUsername(String userEmail) throws UsernameNotFou return userRepository.findByEmail(userEmail); } +======= +>>>>>>> Stashed changes } diff --git a/src/main/java/mos/mosback/login/global/config/CorsConfig.java b/src/main/java/mos/mosback/login/global/config/CorsConfig.java index 29ca714..47318c7 100644 --- a/src/main/java/mos/mosback/login/global/config/CorsConfig.java +++ b/src/main/java/mos/mosback/login/global/config/CorsConfig.java @@ -10,7 +10,10 @@ public class CorsConfig { @Bean +<<<<<<< Updated upstream +======= +>>>>>>> Stashed changes public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); @@ -21,4 +24,8 @@ public CorsFilter corsFilter() { source.registerCorsConfiguration("/**", config); return new CorsFilter(); } -} \ No newline at end of file +<<<<<<< Updated upstream +} +======= +} +>>>>>>> Stashed changes diff --git a/src/main/java/mos/mosback/login/global/config/SecurityConfig.java b/src/main/java/mos/mosback/login/global/config/SecurityConfig.java index a902246..c8dd4a4 100644 --- a/src/main/java/mos/mosback/login/global/config/SecurityConfig.java +++ b/src/main/java/mos/mosback/login/global/config/SecurityConfig.java @@ -20,16 +20,11 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.http.SessionCreationPolicy; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.factory.PasswordEncoderFactories; -import org.springframework.security.crypto.password.DelegatingPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.logout.LogoutFilter; -import java.util.Map; - /** * 인증은 CustomJsonUsernamePasswordAuthenticationFilter에서 authenticate()로 인증된 사용자로 처리 * JwtAuthenticationProcessingFilter는 AccessToken, RefreshToken 재발급 @@ -67,8 +62,9 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { // 아이콘, css, js 관련 // 기본 페이지, css, image, js 하위 폴더에 있는 자료들은 모두 접근 가능, h2-console에 접근 가능 .antMatchers("/","/css/**","/images/**","/js/**","/favicon.ico","/h2-console/**").permitAll() - .antMatchers("/sign-up").permitAll() // 회원가입 접근 가능 - .antMatchers("/user-emails/{email}/exists").permitAll() // 중복 체크 엔드포인트를 예외로 처리 + .antMatchers("/sign-up","/studyRoom/create","/studyRoom/create","/studyRoom/update/{roomID}","/studyRoom/{roomID}", + "/todo/add","/todo/update{TodoIdx}","/todo/delete/{TodoIdx}","/studyRoom/get/{roomID}", + "/studyRoom/all","/studyRoom/search","/studyRoom/byCategory/{category}","/studyRoom/recruiting").permitAll() // 회원가입 접근 가능 .anyRequest().authenticated() // 위의 경로 이외에는 모두 인증된 사용자만 접근 가능 .and() //== 소셜 로그인 설정 ==// @@ -86,26 +82,9 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { return http.build(); } -// @Bean -// public PasswordEncoder passwordEncoder() { -// return PasswordEncoderFactories.createDelegatingPasswordEncoder(); -// } - -// @Bean -// public PasswordEncoder passwordEncoder() { -// String idForEncode = "bcrypt"; // 기본적으로 BCrypt 알고리즘을 사용합니다. -// PasswordEncoder defaultEncoder = new BCryptPasswordEncoder(); -// PasswordEncoder customEncoder = new Pbkdf2PasswordEncoder(); // 원하는 다른 인코딩 알고리즘을 추가할 수 있습니다. -// -// DelegatingPasswordEncoder delegatingPasswordEncoder = new DelegatingPasswordEncoder(idForEncode, (Map) defaultEncoder); -// delegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(customEncoder); -// -// return delegatingPasswordEncoder; -// } - @Bean public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); + return PasswordEncoderFactories.createDelegatingPasswordEncoder(); } /** diff --git a/src/main/java/mos/mosback/login/global/login/handler/LoginSuccessHandler.java b/src/main/java/mos/mosback/login/global/login/handler/LoginSuccessHandler.java index 0a31bab..a4cbfd4 100644 --- a/src/main/java/mos/mosback/login/global/login/handler/LoginSuccessHandler.java +++ b/src/main/java/mos/mosback/login/global/login/handler/LoginSuccessHandler.java @@ -31,13 +31,21 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo jwtService.sendAccessAndRefreshToken(response, accessToken, refreshToken); // 응답 헤더에 AccessToken, RefreshToken 실어서 응답 +<<<<<<< Updated upstream String currentEmail = email; userRepository.findByEmail(currentEmail) +======= + userRepository.findByEmail(email) +>>>>>>> Stashed changes .ifPresent(user -> { user.updateRefreshToken(refreshToken); userRepository.saveAndFlush(user); }); +<<<<<<< Updated upstream log.info("로그인에 성공하였습니다. 이메일 : {}", currentEmail); +======= + log.info("로그인에 성공하였습니다. 이메일 : {}", email); +>>>>>>> Stashed changes log.info("로그인에 성공하였습니다. AccessToken : {}", accessToken); log.info("발급된 AccessToken 만료 기간 : {}", accessTokenExpiration); } From cf748119999151e31f16bc49c0ed18e58a014ecb Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Sun, 24 Sep 2023 03:28:29 +0900 Subject: [PATCH 21/60] =?UTF-8?q?=EB=A6=AC=EB=8D=94=EA=B6=8C=ED=95=9C=20?= =?UTF-8?q?=EB=B6=80=EC=97=AC=20,=20Todo=20=EC=83=9D=EC=84=B1=20=EC=8B=9C?= =?UTF-8?q?=20=EB=82=A0=EC=A7=9C=20=EA=B8=B0=EB=8A=A5=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mosback/controller/StRoomController.java | 7 +- .../mosback/controller/TodoController.java | 33 +++++-- .../{posts => stRoom}/BaseTimeEntity.java | 3 +- .../{posts => stRoom}/MemberStatus.java | 2 +- .../{posts => stRoom}/StRoomEntity.java | 16 ++-- .../{posts => stRoom}/StudyDaysEntity.java | 2 +- .../{posts => stRoom}/StudyMemberEntity.java | 2 +- .../domain/{posts => stRoom}/ToDoEntity.java | 31 ++++--- .../mos/mosback/login/domain/user/User.java | 26 +----- .../user/conrtoller/UserController.java | 53 +++++------- .../login/domain/user/dto/UserSignUpDto.java | 7 -- .../user/repository/UserRepository.java | 24 +----- .../domain/user/service/UserService.java | 85 +++++-------------- .../login/global/config/CorsConfig.java | 7 -- .../login/handler/LoginSuccessHandler.java | 10 +-- .../mosback/repository/StRoomRepository.java | 17 ++-- .../repository/StudyMemberRepository.java | 2 +- .../mosback/repository/ToDoRepository.java | 7 +- .../mos/mosback/service/StRoomService.java | 28 +++--- .../java/mos/mosback/service/ToDoService.java | 32 +++++-- .../dto/Home_RoomResponseDto.java | 4 +- .../dto/Home_nickResponseDto.java | 2 +- .../user => stRoom}/dto/QuestionDto.java | 4 +- .../dto/StRoomDetailResponseDto.java | 12 ++- .../dto/StRoomListResponseDto.java | 11 +-- .../dto/StRoomMemberJoinRequestDto.java | 2 +- .../dto/StRoomResponseDto.java | 9 +- .../dto/StRoomSaveRequestDto.java | 12 +-- .../dto/StRoomUpdateRequestDto.java | 12 +-- .../user => stRoom}/dto/ToDoRequestDto.java | 13 ++- .../user => stRoom}/dto/ToDoResponseDto.java | 6 +- 31 files changed, 213 insertions(+), 268 deletions(-) rename src/main/java/mos/mosback/domain/{posts => stRoom}/BaseTimeEntity.java (89%) rename src/main/java/mos/mosback/domain/{posts => stRoom}/MemberStatus.java (70%) rename src/main/java/mos/mosback/domain/{posts => stRoom}/StRoomEntity.java (85%) rename src/main/java/mos/mosback/domain/{posts => stRoom}/StudyDaysEntity.java (94%) rename src/main/java/mos/mosback/domain/{posts => stRoom}/StudyMemberEntity.java (95%) rename src/main/java/mos/mosback/domain/{posts => stRoom}/ToDoEntity.java (51%) rename src/main/java/mos/mosback/{login/domain/user => stRoom}/dto/Home_RoomResponseDto.java (90%) rename src/main/java/mos/mosback/{login/domain/user => stRoom}/dto/Home_nickResponseDto.java (84%) rename src/main/java/mos/mosback/{login/domain/user => stRoom}/dto/QuestionDto.java (75%) rename src/main/java/mos/mosback/{login/domain/user => stRoom}/dto/StRoomDetailResponseDto.java (75%) rename src/main/java/mos/mosback/{login/domain/user => stRoom}/dto/StRoomListResponseDto.java (89%) rename src/main/java/mos/mosback/{login/domain/user => stRoom}/dto/StRoomMemberJoinRequestDto.java (89%) rename src/main/java/mos/mosback/{login/domain/user => stRoom}/dto/StRoomResponseDto.java (85%) rename src/main/java/mos/mosback/{login/domain/user => stRoom}/dto/StRoomSaveRequestDto.java (86%) rename src/main/java/mos/mosback/{login/domain/user => stRoom}/dto/StRoomUpdateRequestDto.java (79%) rename src/main/java/mos/mosback/{login/domain/user => stRoom}/dto/ToDoRequestDto.java (56%) rename src/main/java/mos/mosback/{login/domain/user => stRoom}/dto/ToDoResponseDto.java (73%) diff --git a/src/main/java/mos/mosback/controller/StRoomController.java b/src/main/java/mos/mosback/controller/StRoomController.java index 214b1fb..9edd649 100644 --- a/src/main/java/mos/mosback/controller/StRoomController.java +++ b/src/main/java/mos/mosback/controller/StRoomController.java @@ -1,15 +1,13 @@ package mos.mosback.controller; -import mos.mosback.domain.posts.StRoomEntity; -import mos.mosback.web.dto.*; +import mos.mosback.stRoom.dto.*; + import mos.mosback.service.StRoomService; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import javax.persistence.EntityNotFoundException; -import java.time.LocalDateTime; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -30,7 +28,6 @@ public ResponseEntity saveRoom(@RequestBody StRoomSaveRequestDto request Long stroomId = stRoomService.save(requestDto); return ResponseEntity.status(HttpStatus.CREATED).body("created successfully. ID: " + stroomId); } - @GetMapping("/MyStudy/{roomId}") public ResponseEntity FindByID (@PathVariable Long roomId) { StRoomResponseDto stroom = stRoomService.findById(roomId); diff --git a/src/main/java/mos/mosback/controller/TodoController.java b/src/main/java/mos/mosback/controller/TodoController.java index a8d13c1..98ff31b 100644 --- a/src/main/java/mos/mosback/controller/TodoController.java +++ b/src/main/java/mos/mosback/controller/TodoController.java @@ -1,11 +1,12 @@ package mos.mosback.controller; -import mos.mosback.domain.posts.ToDoEntity; +import mos.mosback.domain.stRoom.ToDoEntity; import mos.mosback.service.ToDoService; -import mos.mosback.web.dto.ToDoRequestDto; +import mos.mosback.stRoom.dto.ToDoRequestDto; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import java.util.List; @RestController @RequestMapping("/todo") //URL 패턴 @@ -18,15 +19,31 @@ public TodoController(ToDoService toDoService) { this.toDoService = toDoService; } - @PostMapping("/add") - public ResponseEntity addTodo(@RequestBody ToDoRequestDto requestDto){ - ToDoEntity toDoEntity = toDoService.add(requestDto.getTodoContent()); - return ResponseEntity.status(HttpStatus.CREATED).body("TodoList 추가 완료. index : " +toDoEntity.getTodoIdx()); + public ResponseEntity addTodo(@RequestBody ToDoRequestDto requestDto) { + + ToDoEntity todo = toDoService.addTodo(requestDto.getWeekOfYear(), + requestDto.getDayOfWeek(), requestDto.getTodoContent()); + + return ResponseEntity.status(HttpStatus.CREATED).body("TodoList 추가 완료. index : " +todo.getTodoId()); + } + @GetMapping("/ByWeek-and-Day") + public ResponseEntity> getTodoByWeekAndDay( + @RequestParam("weekOfYear") String weekOfYear, + @RequestParam("dayOfWeek") int dayOfWeek) { + + List todoList = toDoService.findByWeekOfYearAndDayOfWeek(weekOfYear, dayOfWeek); + + if (!todoList.isEmpty()) { + return ResponseEntity.ok(todoList); + } else { + return ResponseEntity.notFound().build(); + } } @PutMapping("/update/{TodoIdx}") public ResponseEntity updateTodo(@PathVariable Long TodoIdx, @RequestBody ToDoRequestDto requestDto) { try { - ToDoEntity updatedToDo = toDoService.update(TodoIdx, requestDto.getTodoContent(), requestDto.isCompleted()); + ToDoEntity updatedToDo = toDoService.updateTodo(TodoIdx, requestDto.getTodoContent(), + requestDto.isCompleted(),requestDto.getDayOfWeek(),requestDto.toEntity().getWeekOfYear()); return ResponseEntity.ok("ToDo 업데이트 완료. Index: " + TodoIdx); } catch (IllegalArgumentException e) { return ResponseEntity.status(HttpStatus.NOT_FOUND) @@ -37,7 +54,7 @@ public ResponseEntity updateTodo(@PathVariable Long TodoIdx, @RequestBod @DeleteMapping("/delete/{TodoIdx}") public ResponseEntity deleteTodo(@PathVariable Long TodoIdx) { try { - toDoService.delete(TodoIdx); + toDoService.deleteTodo(TodoIdx); return ResponseEntity.ok("ToDo 삭제 완료. Index: " + TodoIdx); } catch (IllegalArgumentException e) { return ResponseEntity.status(HttpStatus.NOT_FOUND) diff --git a/src/main/java/mos/mosback/domain/posts/BaseTimeEntity.java b/src/main/java/mos/mosback/domain/stRoom/BaseTimeEntity.java similarity index 89% rename from src/main/java/mos/mosback/domain/posts/BaseTimeEntity.java rename to src/main/java/mos/mosback/domain/stRoom/BaseTimeEntity.java index 4f65553..2d79ac1 100644 --- a/src/main/java/mos/mosback/domain/posts/BaseTimeEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/BaseTimeEntity.java @@ -1,7 +1,6 @@ -package mos.mosback.domain.posts; +package mos.mosback.domain.stRoom; import lombok.Getter; import org.springframework.data.annotation.CreatedDate; -import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; import javax.persistence.EntityListeners; diff --git a/src/main/java/mos/mosback/domain/posts/MemberStatus.java b/src/main/java/mos/mosback/domain/stRoom/MemberStatus.java similarity index 70% rename from src/main/java/mos/mosback/domain/posts/MemberStatus.java rename to src/main/java/mos/mosback/domain/stRoom/MemberStatus.java index 63e708f..bf66868 100644 --- a/src/main/java/mos/mosback/domain/posts/MemberStatus.java +++ b/src/main/java/mos/mosback/domain/stRoom/MemberStatus.java @@ -1,4 +1,4 @@ -package mos.mosback.domain.posts; +package mos.mosback.domain.stRoom; public enum MemberStatus { Leader, diff --git a/src/main/java/mos/mosback/domain/posts/StRoomEntity.java b/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java similarity index 85% rename from src/main/java/mos/mosback/domain/posts/StRoomEntity.java rename to src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java index 506ead6..bd54364 100644 --- a/src/main/java/mos/mosback/domain/posts/StRoomEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java @@ -1,10 +1,11 @@ -package mos.mosback.domain.posts; +package mos.mosback.domain.stRoom; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import javax.persistence.*; +import java.time.LocalDate; import java.util.*; @Getter // 롬복 어노테이션 @@ -35,11 +36,15 @@ public class StRoomEntity extends BaseTimeEntity { private String location; private int online; //온라인 private Date startDate; //스터디 시작 날짜 - private Date endDate; //스터디 끝나는 날짜 + private LocalDate endDate; //스터디 끝나는 날짜 private boolean recruiting; //모집여부 + private String leader; + @OneToMany(mappedBy = "stRoom", fetch = FetchType.LAZY, cascade = CascadeType.ALL) + private List todoEntities = new ArrayList<>(); + @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) private List studyDayEntities = new ArrayList<>(); @@ -47,8 +52,8 @@ public class StRoomEntity extends BaseTimeEntity { public StRoomEntity(String title, String goal, String rules, String quest, String category, String intro, int memberNum, int maxMember ,String mod, boolean onOff, String location,int online, - Date startDate, Date endDate, List studyDayEntities - ) { + Date startDate, LocalDate endDate, List studyDayEntities + ,String leader ) { this.title = title; this.goal = goal; @@ -65,6 +70,7 @@ public StRoomEntity(String title, String goal, String rules, String quest, this.startDate = startDate; this.endDate = endDate; this.studyDayEntities = studyDayEntities; + this.leader = leader; } @@ -74,7 +80,7 @@ public StRoomEntity(String title, String goal, String rules, String quest, public void update(String title, String goal, String rules, String quest, String category, String intro, int maxMember, String mod, boolean onOff,String location,int online, Date startDate, - Date endDate,List studyDayEntities) { + LocalDate endDate,List studyDayEntities) { this.title = title; this.goal = goal; this.rules = rules; diff --git a/src/main/java/mos/mosback/domain/posts/StudyDaysEntity.java b/src/main/java/mos/mosback/domain/stRoom/StudyDaysEntity.java similarity index 94% rename from src/main/java/mos/mosback/domain/posts/StudyDaysEntity.java rename to src/main/java/mos/mosback/domain/stRoom/StudyDaysEntity.java index b350e14..63ae223 100644 --- a/src/main/java/mos/mosback/domain/posts/StudyDaysEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/StudyDaysEntity.java @@ -1,4 +1,4 @@ -package mos.mosback.domain.posts; +package mos.mosback.domain.stRoom; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/src/main/java/mos/mosback/domain/posts/StudyMemberEntity.java b/src/main/java/mos/mosback/domain/stRoom/StudyMemberEntity.java similarity index 95% rename from src/main/java/mos/mosback/domain/posts/StudyMemberEntity.java rename to src/main/java/mos/mosback/domain/stRoom/StudyMemberEntity.java index 62cad09..8791c38 100644 --- a/src/main/java/mos/mosback/domain/posts/StudyMemberEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/StudyMemberEntity.java @@ -1,4 +1,4 @@ -package mos.mosback.domain.posts; +package mos.mosback.domain.stRoom; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/src/main/java/mos/mosback/domain/posts/ToDoEntity.java b/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java similarity index 51% rename from src/main/java/mos/mosback/domain/posts/ToDoEntity.java rename to src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java index 222f244..0b4749f 100644 --- a/src/main/java/mos/mosback/domain/posts/ToDoEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java @@ -1,21 +1,23 @@ -package mos.mosback.domain.posts; +package mos.mosback.domain.stRoom; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; - +import javax.persistence.*; +@Setter @Getter // 롬복 어노테이션 @NoArgsConstructor @Entity //JPA 어노테이션 (주요어노테이션) : 테이블과 링크될 클래스 public class ToDoEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long TodoIdx; + private Long TodoId; + + @ManyToOne + @JoinColumn(name = "roomID") + private StRoomEntity stRoom; + @Column private String todoContent; @@ -24,14 +26,23 @@ public class ToDoEntity { private boolean completed; // TodoLists 상태 ( 완료 - true, 미완료 - false) + @Column + private String dayOfWeek; // 선택한 요일 (월요일, 화요일, ...) + private int weekOfYear; // 몇 주차인지 저장 (1주차, 2주차, ...) + + @Builder //해당 클래스의 빌더 클래스 생성. 생성자 상단에 선언 시 생성자에 포함된 필드만 빌더에 포함 - public ToDoEntity(String todoContent, Boolean completed) { + public ToDoEntity(String todoContent, Boolean completed,String dayOfWeek,int weekOfYear) { this.todoContent = todoContent; this.completed = completed; + this.dayOfWeek = dayOfWeek; + this.weekOfYear = weekOfYear; } - public void updateToDo(String todoContent,boolean completed){ + public void updateToDo(String todoContent,boolean completed,String dayOfWeek,int weekOfYear){ this.todoContent = todoContent; this.completed = completed; + this.dayOfWeek = dayOfWeek; + this.weekOfYear = weekOfYear; } diff --git a/src/main/java/mos/mosback/login/domain/user/User.java b/src/main/java/mos/mosback/login/domain/user/User.java index 577e4c1..21ffb1a 100644 --- a/src/main/java/mos/mosback/login/domain/user/User.java +++ b/src/main/java/mos/mosback/login/domain/user/User.java @@ -2,10 +2,7 @@ import lombok.*; -<<<<<<< Updated upstream import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -======= ->>>>>>> Stashed changes import org.springframework.security.crypto.password.PasswordEncoder; import javax.persistence.*; @@ -26,7 +23,6 @@ public class User { private String email; // 이메일 private String password; // 비밀번호 -<<<<<<< Updated upstream private String name; private String nickname; // 닉네임 @@ -34,11 +30,6 @@ public class User { private Date str_duration; private Date end_duration; -======= - private String nickname; // 닉네임 - private String imageUrl; // 프로필 이미지 - private Date duration; ->>>>>>> Stashed changes private String message; private String company; @Enumerated(EnumType.STRING) @@ -61,7 +52,6 @@ public void passwordEncode(PasswordEncoder passwordEncoder) { this.password = passwordEncoder.encode(this.password); } -<<<<<<< Updated upstream //==setter==// @@ -93,9 +83,7 @@ public String getName() { return name; } - public void setName(String name) { - this.name = name; - } + public void setName(String name) {this.name = name;} public String getNickname() { return nickname; @@ -145,24 +133,17 @@ public void setCompany(String company) { this.company = company; } -======= ->>>>>>> Stashed changes //== 유저 필드 업데이트 ==// public void updateNickname(String updateNickname) { this.nickname = updateNickname; } -<<<<<<< Updated upstream public void updateStr_duration(Date updateStr_Duration) { this.str_duration = updateStr_Duration; } public void updateEnd_duration(Date updateEnd_duration) { this.end_duration = updateEnd_duration; -======= - public void updateDuration(Date updateDuration) { - this.duration = updateDuration; ->>>>>>> Stashed changes } public void updateMessage(String updateMessage) { @@ -178,7 +159,6 @@ public void updatePassword(String updatePassword, PasswordEncoder passwordEncode this.password = passwordEncoder.encode(updatePassword); } -<<<<<<< Updated upstream public void updatePw(String password) { this.password = cryptopassword(password); } @@ -188,9 +168,7 @@ public String cryptopassword(String password) { return encodedPassword; } -======= ->>>>>>> Stashed changes public void updateRefreshToken(String updateRefreshToken) { this.refreshToken = updateRefreshToken; } -} +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/login/domain/user/conrtoller/UserController.java b/src/main/java/mos/mosback/login/domain/user/conrtoller/UserController.java index 41b6392..f04825c 100644 --- a/src/main/java/mos/mosback/login/domain/user/conrtoller/UserController.java +++ b/src/main/java/mos/mosback/login/domain/user/conrtoller/UserController.java @@ -2,12 +2,14 @@ import lombok.RequiredArgsConstructor; import mos.mosback.login.domain.user.User; -<<<<<<< Updated upstream import mos.mosback.login.domain.user.dto.*; import mos.mosback.login.domain.user.repository.UserRepository; import mos.mosback.login.domain.user.service.UserService; import mos.mosback.login.global.jwt.service.JwtService; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; import javax.transaction.Transactional; @@ -26,41 +28,29 @@ public class UserController { private Map userMap = new HashMap<>(); private JwtService jwtService; -======= -import mos.mosback.login.domain.user.dto.UserSignUpDto; -import mos.mosback.login.domain.user.repository.UserRepository; -import mos.mosback.login.domain.user.service.UserService; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.web.bind.annotation.*; - -import java.util.Optional; - - -@RestController -@RequiredArgsConstructor -public class UserController { - - private final UserService userService; - private UserRepository userRepository; ->>>>>>> Stashed changes @PostMapping("/sign-up") public String signUp(@RequestBody UserSignUpDto userSignUpDto) throws Exception { userService.signUp(userSignUpDto); return "회원가입 성공"; } -<<<<<<< Updated upstream -// @PostMapping("/profile") -// public String createUser(@RequestBody UserProfileDto userProfileDto) throws Exception{ -// userService.createUser(userProfileDto); -// return "회원정보 등록 성공"; -// } -======= ->>>>>>> Stashed changes + @PutMapping("/update/password") + public ResponseEntity updateUserPassword(@RequestBody UserSignUpDto userSignUpDto) throws Exception { + // 현재 로그인한 사용자의 정보 가져오기 + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + String currentEmail = authentication.getName(); // 현재 사용자의 이메일 + try{ + // 회원 정보 업데이트 + userService.upadateUserPassword(currentEmail, userSignUpDto); + + return ResponseEntity.ok("비밀번호 수정이 완료되었습니다."); + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("오류가 발생했습니다."); + } + } + @GetMapping("/jwt-test") public String jwtTest() { @@ -68,7 +58,6 @@ public String jwtTest() { } -<<<<<<< Updated upstream @GetMapping("/user-emails/{email}/exists") public ResponseEntity checkEmailExists(@PathVariable String email) { Optional existingUser = userRepository.findByEmail(email); @@ -93,6 +82,4 @@ public ResponseEntity sendTemporaryPassword(@RequestBody FindPWDto findP return ResponseEntity.status(400).body("이메일이 존재하지 않거나 이름이 일치하지 않습니다."); } } -======= ->>>>>>> Stashed changes -} +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/login/domain/user/dto/UserSignUpDto.java b/src/main/java/mos/mosback/login/domain/user/dto/UserSignUpDto.java index 2b5cf78..7ac32b1 100644 --- a/src/main/java/mos/mosback/login/domain/user/dto/UserSignUpDto.java +++ b/src/main/java/mos/mosback/login/domain/user/dto/UserSignUpDto.java @@ -11,12 +11,5 @@ public class UserSignUpDto { private String email; private String password; -<<<<<<< Updated upstream -======= - private String nickname; - private Date duration; - private String message; - private String company; ->>>>>>> Stashed changes } \ No newline at end of file diff --git a/src/main/java/mos/mosback/login/domain/user/repository/UserRepository.java b/src/main/java/mos/mosback/login/domain/user/repository/UserRepository.java index 8842914..1978b65 100644 --- a/src/main/java/mos/mosback/login/domain/user/repository/UserRepository.java +++ b/src/main/java/mos/mosback/login/domain/user/repository/UserRepository.java @@ -3,33 +3,20 @@ import mos.mosback.login.domain.user.SocialType; import mos.mosback.login.domain.user.User; -<<<<<<< Updated upstream import org.springframework.data.jpa.repository.JpaRepository; -======= -import mos.mosback.web.dto.Home_nickResponseDto; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; ->>>>>>> Stashed changes import java.util.Optional; public interface UserRepository extends JpaRepository { - Optional findByEmail(String email); + Optional findByEmail(String email); -<<<<<<< Updated upstream //Optional findByNickName(String nickname); Optional findByNickname(String nickname); boolean existsByEmail(String email); -======= - Optional findByNickname(String nickname); - - - Optional findById(Long userId); ->>>>>>> Stashed changes Optional findByRefreshToken(String refreshToken); @@ -41,11 +28,4 @@ public interface UserRepository extends JpaRepository { * 따라서 추가 정보를 입력받아 회원 가입을 진행할 때 소셜 타입, 식별자로 해당 회원을 찾기 위한 메소드 */ Optional findBySocialTypeAndSocialId(SocialType socialType, String socialId); -<<<<<<< Updated upstream -======= - - - - ->>>>>>> Stashed changes -} +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/login/domain/user/service/UserService.java b/src/main/java/mos/mosback/login/domain/user/service/UserService.java index 1c2ef49..355c9c6 100644 --- a/src/main/java/mos/mosback/login/domain/user/service/UserService.java +++ b/src/main/java/mos/mosback/login/domain/user/service/UserService.java @@ -2,7 +2,6 @@ import mos.mosback.login.domain.user.Role; import mos.mosback.login.domain.user.User; -<<<<<<< Updated upstream import mos.mosback.login.domain.user.dto.FindPWDto; import mos.mosback.login.domain.user.dto.MailDto; @@ -15,13 +14,6 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UsernameNotFoundException; -======= -import mos.mosback.login.domain.user.dto.UserSignUpDto; -import mos.mosback.login.domain.user.repository.UserRepository; -import lombok.RequiredArgsConstructor; -import mos.mosback.web.dto.Home_nickResponseDto; -import org.springframework.data.jpa.repository.Query; ->>>>>>> Stashed changes import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; @@ -36,44 +28,24 @@ public class UserService { private final UserRepository userRepository; private final PasswordEncoder passwordEncoder; -<<<<<<< Updated upstream private final JavaMailSender mailSender; -======= ->>>>>>> Stashed changes public void signUp(UserSignUpDto userSignUpDto) throws Exception { if (userRepository.findByEmail(userSignUpDto.getEmail()).isPresent()) { throw new Exception("이미 존재하는 이메일입니다."); } -<<<<<<< Updated upstream - -======= - if (userRepository.findByNickname(userSignUpDto.getNickname()).isPresent()) { - throw new Exception("이미 존재하는 닉네임입니다."); - } ->>>>>>> Stashed changes - User user = User.builder() .email(userSignUpDto.getEmail()) .password(userSignUpDto.getPassword()) -<<<<<<< Updated upstream .role(Role.GUEST) -======= - .nickname(userSignUpDto.getNickname()) - .duration(userSignUpDto.getDuration()) - .message(userSignUpDto.getMessage()) - .company(userSignUpDto.getCompany()) - .role(Role.USER) ->>>>>>> Stashed changes .build(); user.passwordEncode(passwordEncoder); userRepository.save(user); } -<<<<<<< Updated upstream private User getUserByEmail(String email) throws Exception { @@ -85,6 +57,7 @@ private User getUserByEmail(String email) throws Exception { } } + //마이페이지정보입력 public void createUser(String currentEmail, UserProfileDto userProfileDto) throws Exception { if (userRepository.findByNickname(userProfileDto.getNickname()).isPresent()) { throw new Exception("이미 존재하는 닉네임입니다."); @@ -106,6 +79,7 @@ public void createUser(String currentEmail, UserProfileDto userProfileDto) throw } } + //마이페이지 업데이트 public void updateUserProfile(String currentEmail, UserProfileDto userProfileDto) throws Exception { try { User user = getUserByEmail(currentEmail); @@ -123,37 +97,24 @@ public void updateUserProfile(String currentEmail, UserProfileDto userProfileDto } } -// public boolean checkEmailDuplicate(String email){ -// return userRepository.existsByEmail(email); -// } - -// public boolean comparePassword(String email,String password) { -// User findUser = userRepository.findByEmail(email).get(); -// -// BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); -// boolean isMatched = passwordEncoder.matches(password, findUser.getPassword()); -======= -// public boolean isEmailDuplicate(String email) { -// Optional findUser = userRepository.findByEmail(email); -// return findUser != null; -// } -// public boolean comparePassword(String email,String password) { -// Optional findUser = userRepository.findByEmail(email); -// -// BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); -// boolean isMatched = passwordEncoder.matches(password, userRepository.findByPassword()); ->>>>>>> Stashed changes -// -// if(isMatched) { -// return true; -// } -// else{ -// return false; -// } -// } -<<<<<<< Updated upstream -// -// 메일 내용을 생성하고 임시 비밀번호로 회원 비밀번호를 변경 + public void upadateUserPassword(String currentEmail, UserSignUpDto userSignUpDto) throws Exception{ + try { + User user = getUserByEmail(currentEmail); + // BCryptPasswordEncoder를 사용하여 새로운 비밀번호 해싱 + BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + String hashedPassword = passwordEncoder.encode(userSignUpDto.getPassword()); + + // 회원 정보 업데이트 + user.setPassword(hashedPassword); + + userRepository.save(user); + } catch (Exception e) { + throw new Exception("비밀번호 업데이트 하는 동안 오류가 발생했습니다..", e); + } + } + + + // 메일 내용을 생성하고 임시 비밀번호로 회원 비밀번호를 변경 public MailDto createMailAndChangePassword(String userEmail) { String tempPassword = getTempPassword(); MailDto mailDTO = new MailDto(); @@ -215,10 +176,6 @@ public Optional loadUserByUsername(String userEmail) throws UsernameNotFou return userRepository.findByEmail(userEmail); } -======= ->>>>>>> Stashed changes - - -} +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/login/global/config/CorsConfig.java b/src/main/java/mos/mosback/login/global/config/CorsConfig.java index 47318c7..8d14a6d 100644 --- a/src/main/java/mos/mosback/login/global/config/CorsConfig.java +++ b/src/main/java/mos/mosback/login/global/config/CorsConfig.java @@ -10,10 +10,7 @@ public class CorsConfig { @Bean -<<<<<<< Updated upstream -======= ->>>>>>> Stashed changes public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); @@ -24,8 +21,4 @@ public CorsFilter corsFilter() { source.registerCorsConfiguration("/**", config); return new CorsFilter(); } -<<<<<<< Updated upstream } -======= -} ->>>>>>> Stashed changes diff --git a/src/main/java/mos/mosback/login/global/login/handler/LoginSuccessHandler.java b/src/main/java/mos/mosback/login/global/login/handler/LoginSuccessHandler.java index a4cbfd4..a6e0236 100644 --- a/src/main/java/mos/mosback/login/global/login/handler/LoginSuccessHandler.java +++ b/src/main/java/mos/mosback/login/global/login/handler/LoginSuccessHandler.java @@ -31,21 +31,13 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo jwtService.sendAccessAndRefreshToken(response, accessToken, refreshToken); // 응답 헤더에 AccessToken, RefreshToken 실어서 응답 -<<<<<<< Updated upstream String currentEmail = email; userRepository.findByEmail(currentEmail) -======= - userRepository.findByEmail(email) ->>>>>>> Stashed changes .ifPresent(user -> { user.updateRefreshToken(refreshToken); userRepository.saveAndFlush(user); }); -<<<<<<< Updated upstream log.info("로그인에 성공하였습니다. 이메일 : {}", currentEmail); -======= - log.info("로그인에 성공하였습니다. 이메일 : {}", email); ->>>>>>> Stashed changes log.info("로그인에 성공하였습니다. AccessToken : {}", accessToken); log.info("발급된 AccessToken 만료 기간 : {}", accessTokenExpiration); } @@ -54,4 +46,4 @@ private String extractUsername(Authentication authentication) { UserDetails userDetails = (UserDetails) authentication.getPrincipal(); return userDetails.getUsername(); } -} +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/repository/StRoomRepository.java b/src/main/java/mos/mosback/repository/StRoomRepository.java index 11c4a86..7dcd15d 100644 --- a/src/main/java/mos/mosback/repository/StRoomRepository.java +++ b/src/main/java/mos/mosback/repository/StRoomRepository.java @@ -1,9 +1,8 @@ package mos.mosback.repository; //Entity 클래스와 Entity레파지토리 위치 같아야함 -import mos.mosback.domain.posts.StRoomEntity; -import mos.mosback.web.dto.Home_RoomResponseDto; -import mos.mosback.web.dto.Home_nickResponseDto; +import mos.mosback.domain.stRoom.StRoomEntity; +import mos.mosback.stRoom.dto.Home_RoomResponseDto; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -12,22 +11,22 @@ //인터페이스 생성 후 JpaRepository를 상속하면 기본적인 CRUD 메소드 자동으로 생성됨 public interface StRoomRepository extends JpaRepository { - @Query("SELECT new mos.mosback.web.dto.Home_RoomResponseDto(s) FROM StRoomEntity s ORDER BY s.roomID DESC") + @Query("SELECT new mos.mosback.stRoom.dto.Home_RoomResponseDto(s) FROM StRoomEntity s ORDER BY s.roomID DESC") List findAllDesc(); - @Query("SELECT new mos.mosback.web.dto.Home_RoomResponseDto(s) FROM StRoomEntity s WHERE s.title LIKE %:keyword%") + @Query("SELECT new mos.mosback.stRoom.dto.Home_RoomResponseDto(s) FROM StRoomEntity s WHERE s.title LIKE %:keyword%") List findByTitleContaining(@Param("keyword") String keyword);//키워드를 통해 스터디그룹을 검색 할 수 있다 - @Query(value = "SELECT new mos.mosback.web.dto.Home_RoomResponseDto(s)FROM StRoomEntity s ORDER BY s.click DESC") + @Query(value = "SELECT new mos.mosback.stRoom.dto.Home_RoomResponseDto(s)FROM StRoomEntity s ORDER BY s.click DESC") List findPopularRoom(); - @Query("SELECT new mos.mosback.web.dto.Home_RoomResponseDto(s) FROM StRoomEntity s") + @Query("SELECT new mos.mosback.stRoom.dto.Home_RoomResponseDto(s) FROM StRoomEntity s") List findHomeStRoomField(); - @Query("SELECT new mos.mosback.web.dto.Home_RoomResponseDto(s) FROM StRoomEntity s WHERE s.category = :category") + @Query("SELECT new mos.mosback.stRoom.dto.Home_RoomResponseDto(s) FROM StRoomEntity s WHERE s.category = :category") List findByCategory(@Param("category") String category); - @Query("SELECT new mos.mosback.web.dto.Home_RoomResponseDto(s) FROM StRoomEntity s WHERE s.startDate > current_timestamp") + @Query("SELECT new mos.mosback.stRoom.dto.Home_RoomResponseDto(s) FROM StRoomEntity s WHERE s.startDate > current_timestamp") List findRecruitingStudies(); } \ No newline at end of file diff --git a/src/main/java/mos/mosback/repository/StudyMemberRepository.java b/src/main/java/mos/mosback/repository/StudyMemberRepository.java index 4673a76..ae4637b 100644 --- a/src/main/java/mos/mosback/repository/StudyMemberRepository.java +++ b/src/main/java/mos/mosback/repository/StudyMemberRepository.java @@ -1,6 +1,6 @@ package mos.mosback.repository; -import mos.mosback.domain.posts.StudyMemberEntity; +import mos.mosback.domain.stRoom.StudyMemberEntity; import org.springframework.data.jpa.repository.JpaRepository; public interface StudyMemberRepository extends JpaRepository { diff --git a/src/main/java/mos/mosback/repository/ToDoRepository.java b/src/main/java/mos/mosback/repository/ToDoRepository.java index eb6e8bb..c0556be 100644 --- a/src/main/java/mos/mosback/repository/ToDoRepository.java +++ b/src/main/java/mos/mosback/repository/ToDoRepository.java @@ -1,12 +1,13 @@ package mos.mosback.repository; -import mos.mosback.domain.posts.ToDoEntity; +import mos.mosback.domain.stRoom.ToDoEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import java.util.List; public interface ToDoRepository extends JpaRepository { - @Query("SELECT t FROM ToDoEntity t ORDER BY t.TodoIdx DESC") - List findAllDesc(); //Todo리스트를 조회시 todoID를 기준으로 내림차순 정렬 + @Query("SELECT t FROM ToDoEntity t ORDER BY t.TodoId DESC") + List findAllDesc(); //Todo리스트를 조회시 todoID를 기준으로 내림차순 정렬 + List findByDayOfWeekAndWeekOfYear(String dayOfWeek, int weekOfYear); } diff --git a/src/main/java/mos/mosback/service/StRoomService.java b/src/main/java/mos/mosback/service/StRoomService.java index abcf4fc..6ca2d06 100644 --- a/src/main/java/mos/mosback/service/StRoomService.java +++ b/src/main/java/mos/mosback/service/StRoomService.java @@ -1,13 +1,13 @@ package mos.mosback.service; import lombok.RequiredArgsConstructor; -import mos.mosback.domain.posts.MemberStatus; -import mos.mosback.domain.posts.StRoomEntity; -import mos.mosback.domain.posts.StudyMemberEntity; -import mos.mosback.login.domain.user.repository.UserRepository; +import mos.mosback.domain.stRoom.MemberStatus; +import mos.mosback.domain.stRoom.StRoomEntity; +import mos.mosback.domain.stRoom.StudyMemberEntity; import mos.mosback.repository.StRoomRepository; import mos.mosback.repository.StudyMemberRepository; -import mos.mosback.web.dto.*; +import mos.mosback.stRoom.dto.StRoomSaveRequestDto; +import mos.mosback.stRoom.dto.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -23,12 +23,20 @@ public class StRoomService { private final StRoomRepository stRoomRepository; private final StudyMemberRepository studyMemberRepository; - @Transactional public Long save(StRoomSaveRequestDto requestDto) { - return stRoomRepository.save(requestDto.toEntity()).getRoomID(); - } - //스터디를 생성하고 아이디를 반환. + try { + StudyMemberEntity studyMember = new StudyMemberEntity(); + studyMember.setRoomId(requestDto.getRoomID()); + studyMember.setStatus(MemberStatus.Leader); + studyMember.setMemberId(studyMember.getMemberId()); + studyMemberRepository.save(studyMember); + return stRoomRepository.save(requestDto.toEntity()).getRoomID(); + } catch (Exception e) { + e.printStackTrace(); + return null; + } +} @Transactional public void update(Long roomID, StRoomUpdateRequestDto requestDto) { StRoomEntity stroomEntity = stRoomRepository.findById(roomID) @@ -99,7 +107,7 @@ public void memberJoin(StRoomMemberJoinRequestDto requestDto) { studyMember.setRoomId(requestDto.getRoomID()); studyMember.setStatus(MemberStatus.Waiting); studyMember.setAnswer(requestDto.getAnswer()); - studyMember.setMemberId(studyMember.getMemberId()); + /* studyMember.setMemberId(studyMember.getMemberId());*/ studyMemberRepository.save(studyMember); } catch (Exception e) { e.printStackTrace(); diff --git a/src/main/java/mos/mosback/service/ToDoService.java b/src/main/java/mos/mosback/service/ToDoService.java index f186f4f..c322d13 100644 --- a/src/main/java/mos/mosback/service/ToDoService.java +++ b/src/main/java/mos/mosback/service/ToDoService.java @@ -1,32 +1,47 @@ package mos.mosback.service; import lombok.RequiredArgsConstructor; -import mos.mosback.domain.posts.ToDoEntity; +import mos.mosback.domain.stRoom.ToDoEntity; import mos.mosback.repository.ToDoRepository; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDate; +import java.time.temporal.WeekFields; +import java.util.List; +import java.util.Locale; + @RequiredArgsConstructor @Service public class ToDoService { private final ToDoRepository toDoRepository; @Transactional - public ToDoEntity add(String todoContent) { - ToDoEntity toDoEntity = new ToDoEntity(todoContent, false); - return toDoRepository.save(toDoEntity); + public ToDoEntity addTodo(int weekOfYear,String dayOfWeek,String TodoContent) { + + LocalDate currentDate = LocalDate.now(); + // 주차 계산 + weekOfYear = currentDate.get(WeekFields.of(Locale.KOREA).weekOfWeekBasedYear()); + // 해당 요일 및 주차의 Todo를 조회 + List existingTodos = toDoRepository.findByDayOfWeekAndWeekOfYear(dayOfWeek, weekOfYear); + + ToDoEntity todo = new ToDoEntity("",false,dayOfWeek,weekOfYear); + return toDoRepository.save(todo); + } + @Transactional - public ToDoEntity update(Long todoId, String todoContent, boolean completed) { + public ToDoEntity updateTodo(Long todoId, String todoContent, boolean completed,String dayOfWeek, int weekOfYear) { ToDoEntity toDoEntity = toDoRepository.findById(todoId) .orElseThrow(() -> new IllegalArgumentException("해당 ToDo를 찾을 수 없습니다.")); - toDoEntity.updateToDo(todoContent, completed); + toDoEntity.updateToDo(todoContent, completed,dayOfWeek,weekOfYear); return toDoEntity; } @Transactional - public void delete(Long todoId) { + public void deleteTodo(Long todoId) { ToDoEntity toDoEntity = toDoRepository.findById(todoId) .orElseThrow(() -> new IllegalArgumentException("해당 ToDo를 찾을 수 없습니다.")); @@ -34,4 +49,7 @@ public void delete(Long todoId) { } + public List findByWeekOfYearAndDayOfWeek(String weekOfYear, int dayOfWeek) { + return toDoRepository.findByDayOfWeekAndWeekOfYear(weekOfYear, dayOfWeek); + } } \ No newline at end of file diff --git a/src/main/java/mos/mosback/login/domain/user/dto/Home_RoomResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java similarity index 90% rename from src/main/java/mos/mosback/login/domain/user/dto/Home_RoomResponseDto.java rename to src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java index faaa9ff..fe09f33 100644 --- a/src/main/java/mos/mosback/login/domain/user/dto/Home_RoomResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java @@ -1,6 +1,6 @@ -package mos.mosback.login.domain.user.dto; +package mos.mosback.stRoom.dto; import lombok.Getter; -import mos.mosback.domain.posts.StRoomEntity; +import mos.mosback.domain.stRoom.StRoomEntity; import java.util.Date; diff --git a/src/main/java/mos/mosback/login/domain/user/dto/Home_nickResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/Home_nickResponseDto.java similarity index 84% rename from src/main/java/mos/mosback/login/domain/user/dto/Home_nickResponseDto.java rename to src/main/java/mos/mosback/stRoom/dto/Home_nickResponseDto.java index 3347f4a..ab8e762 100644 --- a/src/main/java/mos/mosback/login/domain/user/dto/Home_nickResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/Home_nickResponseDto.java @@ -1,4 +1,4 @@ -package mos.mosback.login.domain.user.dto; +package mos.mosback.stRoom.dto; import mos.mosback.login.domain.user.User; import lombok.Getter; diff --git a/src/main/java/mos/mosback/login/domain/user/dto/QuestionDto.java b/src/main/java/mos/mosback/stRoom/dto/QuestionDto.java similarity index 75% rename from src/main/java/mos/mosback/login/domain/user/dto/QuestionDto.java rename to src/main/java/mos/mosback/stRoom/dto/QuestionDto.java index 459aed1..ae53937 100644 --- a/src/main/java/mos/mosback/login/domain/user/dto/QuestionDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/QuestionDto.java @@ -1,7 +1,7 @@ -package mos.mosback.login.domain.user.dto; +package mos.mosback.stRoom.dto; import lombok.NoArgsConstructor; import lombok.Setter; -import mos.mosback.domain.posts.StRoomEntity; +import mos.mosback.domain.stRoom.StRoomEntity; import lombok.Getter; @Setter diff --git a/src/main/java/mos/mosback/login/domain/user/dto/StRoomDetailResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java similarity index 75% rename from src/main/java/mos/mosback/login/domain/user/dto/StRoomDetailResponseDto.java rename to src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java index 7c0629e..8d21b16 100644 --- a/src/main/java/mos/mosback/login/domain/user/dto/StRoomDetailResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java @@ -1,9 +1,7 @@ -package mos.mosback.login.domain.user.dto; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.Getter; -import mos.mosback.domain.posts.StudyDaysEntity; +package mos.mosback.stRoom.dto; +import mos.mosback.domain.stRoom.StudyDaysEntity; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.Date; import java.util.List; @@ -14,7 +12,7 @@ public class StRoomDetailResponseDto { private boolean recruiting; private String location; private Date startDate; - private Date endDate; + private LocalDate endDate; private LocalDateTime createdDate; private Date deadline; private int memberNum; //현재 멤버수 @@ -22,7 +20,7 @@ public class StRoomDetailResponseDto { private String mod; //스터디 분위기 - //+스터디장 닉네임 + private String leader; //스터디리더 닉네임 private List studyDayEntities; private String goal; diff --git a/src/main/java/mos/mosback/login/domain/user/dto/StRoomListResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomListResponseDto.java similarity index 89% rename from src/main/java/mos/mosback/login/domain/user/dto/StRoomListResponseDto.java rename to src/main/java/mos/mosback/stRoom/dto/StRoomListResponseDto.java index 9c75e1e..c2ffa89 100644 --- a/src/main/java/mos/mosback/login/domain/user/dto/StRoomListResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomListResponseDto.java @@ -1,15 +1,16 @@ -package mos.mosback.web.dto; +package mos.mosback.stRoom.dto; import lombok.Getter; -import mos.mosback.domain.posts.StRoomEntity; -import mos.mosback.domain.posts.StudyDaysEntity; +import mos.mosback.domain.stRoom.StRoomEntity; +import mos.mosback.domain.stRoom.StudyDaysEntity; +import java.time.LocalDate; import java.util.Date; import java.util.List; @Getter public class StRoomListResponseDto { - private Long roomID; + private String title; private String goal; //스터디 목표 private String rules; //스터디 규칙 @@ -22,7 +23,7 @@ public class StRoomListResponseDto { private int click;// 클릭횟수 (인기순 조회) private boolean onOff; //진행방식 (온오프) private Date startDate; //스터디 시작 날짜 - private Date endDate; //스터디 끝나는 날짜 + private LocalDate endDate; //스터디 끝나는 날짜 private String location; private int online; //온라인 diff --git a/src/main/java/mos/mosback/login/domain/user/dto/StRoomMemberJoinRequestDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomMemberJoinRequestDto.java similarity index 89% rename from src/main/java/mos/mosback/login/domain/user/dto/StRoomMemberJoinRequestDto.java rename to src/main/java/mos/mosback/stRoom/dto/StRoomMemberJoinRequestDto.java index 1b95284..59ab89f 100644 --- a/src/main/java/mos/mosback/login/domain/user/dto/StRoomMemberJoinRequestDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomMemberJoinRequestDto.java @@ -1,4 +1,4 @@ -package mos.mosback.web.dto; +package mos.mosback.stRoom.dto; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; diff --git a/src/main/java/mos/mosback/login/domain/user/dto/StRoomResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java similarity index 85% rename from src/main/java/mos/mosback/login/domain/user/dto/StRoomResponseDto.java rename to src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java index 6f9e816..f5f2276 100644 --- a/src/main/java/mos/mosback/login/domain/user/dto/StRoomResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java @@ -1,8 +1,9 @@ -package mos.mosback.web.dto; +package mos.mosback.stRoom.dto; import lombok.Getter; -import mos.mosback.domain.posts.StRoomEntity; -import mos.mosback.domain.posts.StudyDaysEntity; +import mos.mosback.domain.stRoom.StRoomEntity; +import mos.mosback.domain.stRoom.StudyDaysEntity; +import java.time.LocalDate; import java.util.Date; import java.util.List; @@ -18,7 +19,7 @@ public class StRoomResponseDto { private String mod; //스터디 분위기 private boolean onOff; //진행방식 (온오프) private Date startDate; //스터디 시작 날짜 - private Date endDate; //스터디 끝나는 날짜 + private LocalDate endDate; //스터디 끝나는 날짜 private List studyDayEntities; /*유저프로필 + 사진*/ diff --git a/src/main/java/mos/mosback/login/domain/user/dto/StRoomSaveRequestDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomSaveRequestDto.java similarity index 86% rename from src/main/java/mos/mosback/login/domain/user/dto/StRoomSaveRequestDto.java rename to src/main/java/mos/mosback/stRoom/dto/StRoomSaveRequestDto.java index 5481a04..9c169e6 100644 --- a/src/main/java/mos/mosback/login/domain/user/dto/StRoomSaveRequestDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomSaveRequestDto.java @@ -1,9 +1,11 @@ -package mos.mosback.web.dto; +package mos.mosback.stRoom.dto; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import mos.mosback.domain.posts.StRoomEntity; -import mos.mosback.domain.posts.StudyDaysEntity; +import mos.mosback.domain.stRoom.StRoomEntity; +import mos.mosback.domain.stRoom.StudyDaysEntity; + +import java.time.LocalDate; import java.util.Date; import java.util.List; @@ -23,14 +25,14 @@ public class StRoomSaveRequestDto { private String location; //스터디 장소 private int online; // 온라인일 경우 1 : 줌 2 : 디코 3: 구글미트 4: 기타 private Date startDate; //스터디 시작 날짜 - private Date endDate; //스터디 끝나는 날짜 + private LocalDate endDate; //스터디 끝나는 날짜 private List studyDayEntities; @Builder public StRoomSaveRequestDto(String title, String goal, String rules, String quest, String category, String intro, int maxMember, String mod, boolean onOff,String location,int online, - Date startDate, Date endDate,List studyDayEntities) { + Date startDate, LocalDate endDate,List studyDayEntities) { this.title = title; this.goal = goal; this.rules = rules; diff --git a/src/main/java/mos/mosback/login/domain/user/dto/StRoomUpdateRequestDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomUpdateRequestDto.java similarity index 79% rename from src/main/java/mos/mosback/login/domain/user/dto/StRoomUpdateRequestDto.java rename to src/main/java/mos/mosback/stRoom/dto/StRoomUpdateRequestDto.java index d4f7ade..f52a260 100644 --- a/src/main/java/mos/mosback/login/domain/user/dto/StRoomUpdateRequestDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomUpdateRequestDto.java @@ -1,9 +1,10 @@ -package mos.mosback.web.dto; +package mos.mosback.stRoom.dto; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import mos.mosback.domain.posts.StudyDaysEntity; +import mos.mosback.domain.stRoom.StudyDaysEntity; +import java.time.LocalDate; import java.util.Date; import java.util.List; @@ -23,16 +24,17 @@ public class StRoomUpdateRequestDto { private String mod; //스터디 분위기 private boolean onOff; //진행방식 (온오프) private String location; //스터디 장소 - private int online; // 온라인일 경우 1 : 줌 2 : 디코 3: 구글미트 4: 기타 + private int online; // 온라인일 경우 + // 1 : 줌 2 : 디코 3: 구글미트 4: 기타 private Date startDate; //스터디 시작 날짜 - private Date endDate; //스터디 끝나는 날짜 + private LocalDate endDate; //스터디 끝나는 날짜 private List studyDayEntities; @Builder public StRoomUpdateRequestDto(String title, String goal, String rules, String quest, String category, String intro, int maxMember ,String mod, boolean onOff,String location,int online, - Date startDate, Date endDate, List studyDayEntities) { + Date startDate, LocalDate endDate, List studyDayEntities) { this.title = title; this.goal = goal; this.rules = rules; diff --git a/src/main/java/mos/mosback/login/domain/user/dto/ToDoRequestDto.java b/src/main/java/mos/mosback/stRoom/dto/ToDoRequestDto.java similarity index 56% rename from src/main/java/mos/mosback/login/domain/user/dto/ToDoRequestDto.java rename to src/main/java/mos/mosback/stRoom/dto/ToDoRequestDto.java index a2b72b9..036c9ef 100644 --- a/src/main/java/mos/mosback/login/domain/user/dto/ToDoRequestDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/ToDoRequestDto.java @@ -1,26 +1,31 @@ -package mos.mosback.web.dto; +package mos.mosback.stRoom.dto; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import mos.mosback.domain.posts.ToDoEntity; +import mos.mosback.domain.stRoom.ToDoEntity; @Getter @NoArgsConstructor public class ToDoRequestDto { - Long TodoId; + private int weekOfYear; + private String dayOfWeek; // 사용자가 선택한 요일 private String todoContent; private boolean completed; // TodoLists 상태 ( 완료 - true, 미완료 - false) @Builder - public ToDoRequestDto(String todoContent, boolean completed) { + public ToDoRequestDto(String todoContent, boolean completed,String dayOfWeek,int weekOfYear) { + this.weekOfYear = weekOfYear; + this.dayOfWeek = dayOfWeek; this.todoContent = todoContent; this.completed = completed; } public ToDoEntity toEntity() { return ToDoEntity.builder() + .weekOfYear(weekOfYear) + .dayOfWeek(dayOfWeek) .todoContent(todoContent) .completed(completed) .build(); diff --git a/src/main/java/mos/mosback/login/domain/user/dto/ToDoResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/ToDoResponseDto.java similarity index 73% rename from src/main/java/mos/mosback/login/domain/user/dto/ToDoResponseDto.java rename to src/main/java/mos/mosback/stRoom/dto/ToDoResponseDto.java index 94930f2..4a0f905 100644 --- a/src/main/java/mos/mosback/login/domain/user/dto/ToDoResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/ToDoResponseDto.java @@ -1,10 +1,10 @@ -package mos.mosback.web.dto; +package mos.mosback.stRoom.dto; import lombok.Getter; -import mos.mosback.domain.posts.ToDoEntity; +import mos.mosback.domain.stRoom.ToDoEntity; @Getter public class ToDoResponseDto { - private Long TodoId; + private String todoContent; private boolean completed; From 42a570d6ab3be508d4cd1db707612a2eaf0a7af0 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Sun, 24 Sep 2023 03:31:08 +0900 Subject: [PATCH 22/60] =?UTF-8?q?=EB=A6=AC=EB=8D=94=EA=B6=8C=ED=95=9C=20?= =?UTF-8?q?=EB=B6=80=EC=97=AC=20,=20Todo=20=EC=83=9D=EC=84=B1=20=EC=8B=9C?= =?UTF-8?q?=20=EB=82=A0=EC=A7=9C=20=EA=B8=B0=EB=8A=A5=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/mos/mosback/controller/TodoController.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/mos/mosback/controller/TodoController.java b/src/main/java/mos/mosback/controller/TodoController.java index 98ff31b..b361719 100644 --- a/src/main/java/mos/mosback/controller/TodoController.java +++ b/src/main/java/mos/mosback/controller/TodoController.java @@ -19,6 +19,7 @@ public TodoController(ToDoService toDoService) { this.toDoService = toDoService; } + @GetMapping("/add") public ResponseEntity addTodo(@RequestBody ToDoRequestDto requestDto) { ToDoEntity todo = toDoService.addTodo(requestDto.getWeekOfYear(), From 82ade678da5199d40a549d0f7b5568e0abcb8262 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Sun, 24 Sep 2023 03:41:43 +0900 Subject: [PATCH 23/60] =?UTF-8?q?=EB=A6=AC=EB=8D=94=EA=B6=8C=ED=95=9C=20?= =?UTF-8?q?=EB=B6=80=EC=97=AC=20,=20Todo=20=EC=83=9D=EC=84=B1=20=EC=8B=9C?= =?UTF-8?q?=20=EB=82=A0=EC=A7=9C=20=EA=B8=B0=EB=8A=A5=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/mos/mosback/controller/TodoController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/mos/mosback/controller/TodoController.java b/src/main/java/mos/mosback/controller/TodoController.java index b361719..65f59af 100644 --- a/src/main/java/mos/mosback/controller/TodoController.java +++ b/src/main/java/mos/mosback/controller/TodoController.java @@ -19,7 +19,7 @@ public TodoController(ToDoService toDoService) { this.toDoService = toDoService; } - @GetMapping("/add") + @PostMapping("/add") public ResponseEntity addTodo(@RequestBody ToDoRequestDto requestDto) { ToDoEntity todo = toDoService.addTodo(requestDto.getWeekOfYear(), From e15410ee6659fce06cc888651c99df71bd662830 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Sun, 24 Sep 2023 06:07:47 +0900 Subject: [PATCH 24/60] =?UTF-8?q?=EB=A6=AC=EB=8D=94=EA=B6=8C=ED=95=9C=20?= =?UTF-8?q?=EB=B6=80=EC=97=AC=20,=20Todo=20=EC=83=9D=EC=84=B1=20=EC=8B=9C?= =?UTF-8?q?=20=EB=82=A0=EC=A7=9C=20=EA=B8=B0=EB=8A=A5=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?(=20+yyyy-mm-n=EC=A3=BC=EC=B0=A8=20+=20=EC=9A=94=EC=9D=BC?= =?UTF-8?q?=EC=84=A0=ED=83=9D=20)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mosback/controller/TodoController.java | 5 +- .../mos/mosback/domain/stRoom/ToDoEntity.java | 13 +++- .../java/mos/mosback/service/ToDoService.java | 67 ++++++++++++++----- 3 files changed, 65 insertions(+), 20 deletions(-) diff --git a/src/main/java/mos/mosback/controller/TodoController.java b/src/main/java/mos/mosback/controller/TodoController.java index 65f59af..da40dcb 100644 --- a/src/main/java/mos/mosback/controller/TodoController.java +++ b/src/main/java/mos/mosback/controller/TodoController.java @@ -22,11 +22,12 @@ public TodoController(ToDoService toDoService) { @PostMapping("/add") public ResponseEntity addTodo(@RequestBody ToDoRequestDto requestDto) { - ToDoEntity todo = toDoService.addTodo(requestDto.getWeekOfYear(), + ToDoEntity todo = toDoService.addTodo( requestDto.getDayOfWeek(), requestDto.getTodoContent()); return ResponseEntity.status(HttpStatus.CREATED).body("TodoList 추가 완료. index : " +todo.getTodoId()); } + @GetMapping("/ByWeek-and-Day") public ResponseEntity> getTodoByWeekAndDay( @RequestParam("weekOfYear") String weekOfYear, @@ -44,7 +45,7 @@ public ResponseEntity> getTodoByWeekAndDay( public ResponseEntity updateTodo(@PathVariable Long TodoIdx, @RequestBody ToDoRequestDto requestDto) { try { ToDoEntity updatedToDo = toDoService.updateTodo(TodoIdx, requestDto.getTodoContent(), - requestDto.isCompleted(),requestDto.getDayOfWeek(),requestDto.toEntity().getWeekOfYear()); + requestDto.isCompleted(),requestDto.getDayOfWeek()); return ResponseEntity.ok("ToDo 업데이트 완료. Index: " + TodoIdx); } catch (IllegalArgumentException e) { return ResponseEntity.status(HttpStatus.NOT_FOUND) diff --git a/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java b/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java index 0b4749f..724092f 100644 --- a/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java @@ -5,6 +5,8 @@ import lombok.Setter; import javax.persistence.*; +import java.time.Month; + @Setter @Getter // 롬복 어노테이션 @NoArgsConstructor @@ -29,20 +31,25 @@ public class ToDoEntity { @Column private String dayOfWeek; // 선택한 요일 (월요일, 화요일, ...) private int weekOfYear; // 몇 주차인지 저장 (1주차, 2주차, ...) + private int year; + private int month; @Builder //해당 클래스의 빌더 클래스 생성. 생성자 상단에 선언 시 생성자에 포함된 필드만 빌더에 포함 - public ToDoEntity(String todoContent, Boolean completed,String dayOfWeek,int weekOfYear) { + public ToDoEntity(String todoContent, Boolean completed,String dayOfWeek,int weekOfYear,int year,int month) { this.todoContent = todoContent; this.completed = completed; this.dayOfWeek = dayOfWeek; this.weekOfYear = weekOfYear; + this.year = year; + this.month = month; } - public void updateToDo(String todoContent,boolean completed,String dayOfWeek,int weekOfYear){ + public void updateToDo(String todoContent,boolean completed,String dayOfWeek){ this.todoContent = todoContent; this.completed = completed; this.dayOfWeek = dayOfWeek; - this.weekOfYear = weekOfYear; + + } diff --git a/src/main/java/mos/mosback/service/ToDoService.java b/src/main/java/mos/mosback/service/ToDoService.java index c322d13..30304bd 100644 --- a/src/main/java/mos/mosback/service/ToDoService.java +++ b/src/main/java/mos/mosback/service/ToDoService.java @@ -2,44 +2,74 @@ import lombok.RequiredArgsConstructor; import mos.mosback.domain.stRoom.ToDoEntity; import mos.mosback.repository.ToDoRepository; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.time.DayOfWeek; import java.time.LocalDate; -import java.time.temporal.WeekFields; +import java.time.Month; +import java.time.MonthDay; import java.util.List; -import java.util.Locale; + @RequiredArgsConstructor @Service public class ToDoService { private final ToDoRepository toDoRepository; - @Transactional - public ToDoEntity addTodo(int weekOfYear,String dayOfWeek,String TodoContent) { + @Transactional + public ToDoEntity addTodo(String dayOfWeek, String todoContent) { LocalDate currentDate = LocalDate.now(); + // 주차 계산 - weekOfYear = currentDate.get(WeekFields.of(Locale.KOREA).weekOfWeekBasedYear()); + int weekOfMonth = getCurrentWeekOfMonth(currentDate); + // 해당 요일 및 주차의 Todo를 조회 - List existingTodos = toDoRepository.findByDayOfWeekAndWeekOfYear(dayOfWeek, weekOfYear); + List existingTodos = toDoRepository.findByDayOfWeekAndWeekOfYear(dayOfWeek, weekOfMonth); - ToDoEntity todo = new ToDoEntity("",false,dayOfWeek,weekOfYear); - return toDoRepository.save(todo); + ToDoEntity todo = new ToDoEntity(todoContent, false, dayOfWeek, weekOfMonth, currentDate.getYear(),currentDate.getMonthValue()); + return toDoRepository.save(todo); } + private int getCurrentWeekOfMonth(LocalDate currentDate) { + // 한 주의 시작은 월요일이고, 첫 주에 4일 이상이 포함되어야 첫 주 취급 (목/금/토/일) + DayOfWeek firstDayOfWeek = currentDate.withDayOfMonth(1).getDayOfWeek(); + int daysToAdd = DayOfWeek.MONDAY.getValue() - firstDayOfWeek.getValue(); + if (daysToAdd < 0) { + daysToAdd += 7; // If it's before Monday, move to the next Monday + } - @Transactional - public ToDoEntity updateTodo(Long todoId, String todoContent, boolean completed,String dayOfWeek, int weekOfYear) { - ToDoEntity toDoEntity = toDoRepository.findById(todoId) - .orElseThrow(() -> new IllegalArgumentException("해당 ToDo를 찾을 수 없습니다.")); + LocalDate firstMondayOfMonth = currentDate.withDayOfMonth(1).plusDays(daysToAdd); - toDoEntity.updateToDo(todoContent, completed,dayOfWeek,weekOfYear); - return toDoEntity; - } + int weekOfMonth = (currentDate.getDayOfMonth() - 1) / 7 + 1; + + // 마지막 주차의 경우 + if (weekOfMonth == 5) { + DayOfWeek lastDayOfWeek = currentDate.withDayOfMonth(currentDate.lengthOfMonth()).getDayOfWeek(); + // 마지막 날이 월~수 사이이면 다음달 1주차로 계산 + if (lastDayOfWeek.getValue() <= DayOfWeek.WEDNESDAY.getValue()) { + LocalDate firstDayOfNextMonth = currentDate.withDayOfMonth(1).plusMonths(1); + DayOfWeek firstDayOfNextMonthOfWeek = firstDayOfNextMonth.getDayOfWeek(); + + int daysToAddToNextMonth = DayOfWeek.MONDAY.getValue() - firstDayOfNextMonthOfWeek.getValue(); + + if (daysToAddToNextMonth < 0) { + daysToAddToNextMonth += 7; // If it's before Monday, move to the next Monday + } + + LocalDate firstMondayOfNextMonth = firstDayOfNextMonth.plusDays(daysToAddToNextMonth); + + weekOfMonth = 1; // 다음달의 첫 주로 설정 + } + } + + return weekOfMonth; + } @Transactional public void deleteTodo(Long todoId) { ToDoEntity toDoEntity = toDoRepository.findById(todoId) @@ -48,7 +78,14 @@ public void deleteTodo(Long todoId) { toDoRepository.delete(toDoEntity); } + @Transactional + public ToDoEntity updateTodo(Long todoId, String todoContent, boolean completed,String dayOfWeek) { + ToDoEntity toDoEntity = toDoRepository.findById(todoId) + .orElseThrow(() -> new IllegalArgumentException("해당 ToDo를 찾을 수 없습니다.")); + toDoEntity.updateToDo(todoContent, completed,dayOfWeek); + return toDoEntity; + } public List findByWeekOfYearAndDayOfWeek(String weekOfYear, int dayOfWeek) { return toDoRepository.findByDayOfWeekAndWeekOfYear(weekOfYear, dayOfWeek); } From 94e4b40b3c89f839864eb603c22f9b00cfd2885a Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Sun, 24 Sep 2023 23:04:22 +0900 Subject: [PATCH 25/60] =?UTF-8?q?=EB=A6=AC=EB=8D=94=EA=B6=8C=ED=95=9C=20?= =?UTF-8?q?=EB=B6=80=EC=97=AC=20,=20Todo=20=EC=83=9D=EC=84=B1=20=EC=8B=9C?= =?UTF-8?q?=20=EB=82=A0=EC=A7=9C=20=EA=B8=B0=EB=8A=A5=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?(=20+yyyy-mm-n=EC=A3=BC=EC=B0=A8=20+=20=EC=9A=94=EC=9D=BC?= =?UTF-8?q?=EC=84=A0=ED=83=9D=20)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mosback/controller/TodoController.java | 38 ++-- .../mos/mosback/domain/stRoom/ToDoEntity.java | 9 +- .../login/global/config/SecurityConfig.java | 4 +- .../mosback/repository/ToDoRepository.java | 11 +- .../java/mos/mosback/service/ToDoService.java | 23 ++- .../stRoom/dto/ToDoContentResponseDto.java | 16 ++ .../mos/mosback/stRoom/dto/ToDoDateDto.java | 19 ++ .../mosback/stRoom/dto/ToDoRequestDto.java | 6 +- .../mosback/stRoom/dto/ToDoResponseDto.java | 16 -- src/main/resources/static/MemberTodo.html | 183 ++++++++++++++++++ src/main/resources/static/styles.css | 8 + 11 files changed, 288 insertions(+), 45 deletions(-) create mode 100644 src/main/java/mos/mosback/stRoom/dto/ToDoContentResponseDto.java create mode 100644 src/main/java/mos/mosback/stRoom/dto/ToDoDateDto.java delete mode 100644 src/main/java/mos/mosback/stRoom/dto/ToDoResponseDto.java create mode 100644 src/main/resources/static/MemberTodo.html create mode 100644 src/main/resources/static/styles.css diff --git a/src/main/java/mos/mosback/controller/TodoController.java b/src/main/java/mos/mosback/controller/TodoController.java index da40dcb..2fb0637 100644 --- a/src/main/java/mos/mosback/controller/TodoController.java +++ b/src/main/java/mos/mosback/controller/TodoController.java @@ -1,7 +1,9 @@ package mos.mosback.controller; import mos.mosback.domain.stRoom.ToDoEntity; import mos.mosback.service.ToDoService; +import mos.mosback.stRoom.dto.ToDoDateDto; import mos.mosback.stRoom.dto.ToDoRequestDto; +import mos.mosback.stRoom.dto.ToDoContentResponseDto; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -28,36 +30,42 @@ public ResponseEntity addTodo(@RequestBody ToDoRequestDto requestDto) { return ResponseEntity.status(HttpStatus.CREATED).body("TodoList 추가 완료. index : " +todo.getTodoId()); } - @GetMapping("/ByWeek-and-Day") - public ResponseEntity> getTodoByWeekAndDay( - @RequestParam("weekOfYear") String weekOfYear, - @RequestParam("dayOfWeek") int dayOfWeek) { + @GetMapping("/{year}/{month}/{weekOfYear}/{dayOfWeek}") + public ResponseEntity> FindByDate(@PathVariable int year, @PathVariable int month, @PathVariable int weekOfYear, @PathVariable String dayOfWeek) { - List todoList = toDoService.findByWeekOfYearAndDayOfWeek(weekOfYear, dayOfWeek); + List todos = toDoService.findByDate(year, month, weekOfYear, dayOfWeek); + return new ResponseEntity<>(todos, HttpStatus.OK); - if (!todoList.isEmpty()) { - return ResponseEntity.ok(todoList); + } + @GetMapping("/date") + public ResponseEntity> getTodoDate() { + List todoDates = toDoService.getTodoDate(); + + if (!todoDates.isEmpty()) { + return new ResponseEntity<>(todoDates, HttpStatus.OK); } else { return ResponseEntity.notFound().build(); } } - @PutMapping("/update/{TodoIdx}") - public ResponseEntity updateTodo(@PathVariable Long TodoIdx, @RequestBody ToDoRequestDto requestDto) { + + + @PutMapping("/update/{TodoId}") + public ResponseEntity updateTodo(@PathVariable Long TodoId, @RequestBody ToDoRequestDto requestDto) { try { - ToDoEntity updatedToDo = toDoService.updateTodo(TodoIdx, requestDto.getTodoContent(), + ToDoEntity updatedToDo = toDoService.updateTodo(TodoId, requestDto.getTodoContent(), requestDto.isCompleted(),requestDto.getDayOfWeek()); - return ResponseEntity.ok("ToDo 업데이트 완료. Index: " + TodoIdx); + return ResponseEntity.ok("ToDo 업데이트 완료. Index: " + TodoId); } catch (IllegalArgumentException e) { return ResponseEntity.status(HttpStatus.NOT_FOUND) .body("NOT FOUND TODO"); } } - @DeleteMapping("/delete/{TodoIdx}") - public ResponseEntity deleteTodo(@PathVariable Long TodoIdx) { + @DeleteMapping("/delete/{TodoId}") + public ResponseEntity deleteTodo(@PathVariable Long TodoId) { try { - toDoService.deleteTodo(TodoIdx); - return ResponseEntity.ok("ToDo 삭제 완료. Index: " + TodoIdx); + toDoService.deleteTodo(TodoId); + return ResponseEntity.ok("ToDo 삭제 완료. Index: " + TodoId); } catch (IllegalArgumentException e) { return ResponseEntity.status(HttpStatus.NOT_FOUND) .body("NOT FOUND TODO"); diff --git a/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java b/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java index 724092f..a953a53 100644 --- a/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java @@ -27,12 +27,15 @@ public class ToDoEntity { @Column private boolean completed; // TodoLists 상태 ( 완료 - true, 미완료 - false) - @Column - private String dayOfWeek; // 선택한 요일 (월요일, 화요일, ...) - private int weekOfYear; // 몇 주차인지 저장 (1주차, 2주차, ...) private int year; + @Column private int month; + @Column + private int weekOfYear; // 몇 주차인지 저장 (1주차, 2주차, ...) + @Column + private String dayOfWeek; // 선택한 요일 (월요일, 화요일, ...) + @Builder //해당 클래스의 빌더 클래스 생성. 생성자 상단에 선언 시 생성자에 포함된 필드만 빌더에 포함 diff --git a/src/main/java/mos/mosback/login/global/config/SecurityConfig.java b/src/main/java/mos/mosback/login/global/config/SecurityConfig.java index c8dd4a4..76609b6 100644 --- a/src/main/java/mos/mosback/login/global/config/SecurityConfig.java +++ b/src/main/java/mos/mosback/login/global/config/SecurityConfig.java @@ -63,8 +63,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { // 기본 페이지, css, image, js 하위 폴더에 있는 자료들은 모두 접근 가능, h2-console에 접근 가능 .antMatchers("/","/css/**","/images/**","/js/**","/favicon.ico","/h2-console/**").permitAll() .antMatchers("/sign-up","/studyRoom/create","/studyRoom/create","/studyRoom/update/{roomID}","/studyRoom/{roomID}", - "/todo/add","/todo/update{TodoIdx}","/todo/delete/{TodoIdx}","/studyRoom/get/{roomID}", - "/studyRoom/all","/studyRoom/search","/studyRoom/byCategory/{category}","/studyRoom/recruiting").permitAll() // 회원가입 접근 가능 + "/todo/add","/todo/update{TodoIdx}","/todo/delete/{TodoIdx}","/todo/{TodoId}","/studyRoom/get/{roomID}", + "todo/{year}/{month}/{weekOfYear}/{dayOfWeek}", "/studyRoom/all","/studyRoom/search","/studyRoom/byCategory/{category}","/studyRoom/recruiting").permitAll() // 회원가입 접근 가능 .anyRequest().authenticated() // 위의 경로 이외에는 모두 인증된 사용자만 접근 가능 .and() //== 소셜 로그인 설정 ==// diff --git a/src/main/java/mos/mosback/repository/ToDoRepository.java b/src/main/java/mos/mosback/repository/ToDoRepository.java index c0556be..9af73c0 100644 --- a/src/main/java/mos/mosback/repository/ToDoRepository.java +++ b/src/main/java/mos/mosback/repository/ToDoRepository.java @@ -1,5 +1,7 @@ package mos.mosback.repository; import mos.mosback.domain.stRoom.ToDoEntity; +import mos.mosback.stRoom.dto.ToDoDateDto; +import mos.mosback.stRoom.dto.ToDoContentResponseDto; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; @@ -7,7 +9,14 @@ public interface ToDoRepository extends JpaRepository { @Query("SELECT t FROM ToDoEntity t ORDER BY t.TodoId DESC") - List findAllDesc(); //Todo리스트를 조회시 todoID를 기준으로 내림차순 정렬 + List findAllDesc(); //Todo리스트를 조회시 todoID를 기준으로 내림차순 정렬 List findByDayOfWeekAndWeekOfYear(String dayOfWeek, int weekOfYear); + + + @Query("SELECT new mos.mosback.stRoom.dto.ToDoContentResponseDto(t) FROM ToDoEntity t") + ListfindByDate(int year, int month, int weekOfYear, String dayOfWeek); + + @Query("SELECT new mos.mosback.stRoom.dto.ToDoDateDto(t) FROM ToDoEntity t") + ListgetTodoDate(); } diff --git a/src/main/java/mos/mosback/service/ToDoService.java b/src/main/java/mos/mosback/service/ToDoService.java index 30304bd..11b613c 100644 --- a/src/main/java/mos/mosback/service/ToDoService.java +++ b/src/main/java/mos/mosback/service/ToDoService.java @@ -2,14 +2,13 @@ import lombok.RequiredArgsConstructor; import mos.mosback.domain.stRoom.ToDoEntity; import mos.mosback.repository.ToDoRepository; -import org.springframework.http.ResponseEntity; +import mos.mosback.stRoom.dto.ToDoDateDto; +import mos.mosback.stRoom.dto.ToDoContentResponseDto; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.DayOfWeek; import java.time.LocalDate; -import java.time.Month; -import java.time.MonthDay; import java.util.List; @@ -59,7 +58,7 @@ private int getCurrentWeekOfMonth(LocalDate currentDate) { int daysToAddToNextMonth = DayOfWeek.MONDAY.getValue() - firstDayOfNextMonthOfWeek.getValue(); if (daysToAddToNextMonth < 0) { - daysToAddToNextMonth += 7; // If it's before Monday, move to the next Monday + daysToAddToNextMonth += 7; } LocalDate firstMondayOfNextMonth = firstDayOfNextMonth.plusDays(daysToAddToNextMonth); @@ -70,6 +69,14 @@ private int getCurrentWeekOfMonth(LocalDate currentDate) { return weekOfMonth; } +// @Transactional +// public ToDoResponseDto findById(Long todoId) { +// Optional optionalToDoEntity = toDoRepository.findById(todoId); +// +// // ToDoEntity를 ToDoResponseDto로 변환하여 반환 +// return optionalToDoEntity.map(ToDoResponseDto::new).orElse(null); // 또는 예외 처리를 수행 +// } + @Transactional public void deleteTodo(Long todoId) { ToDoEntity toDoEntity = toDoRepository.findById(todoId) @@ -89,4 +96,12 @@ public ToDoEntity updateTodo(Long todoId, String todoContent, boolean completed, public List findByWeekOfYearAndDayOfWeek(String weekOfYear, int dayOfWeek) { return toDoRepository.findByDayOfWeekAndWeekOfYear(weekOfYear, dayOfWeek); } + + public List findByDate(int year, int month, int weekOfYear, String dayOfWeek) { + return toDoRepository.findByDate(year, month, weekOfYear, dayOfWeek); + } + + public List getTodoDate(){ + return toDoRepository.getTodoDate(); + } } \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/dto/ToDoContentResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/ToDoContentResponseDto.java new file mode 100644 index 0000000..0f7e0ad --- /dev/null +++ b/src/main/java/mos/mosback/stRoom/dto/ToDoContentResponseDto.java @@ -0,0 +1,16 @@ +package mos.mosback.stRoom.dto; +import lombok.Getter; +import mos.mosback.domain.stRoom.ToDoEntity; + +@Getter +public class ToDoContentResponseDto { + + private String todoContent; + private boolean completed; + + public ToDoContentResponseDto(ToDoEntity entity) { + + this.todoContent = entity.getTodoContent(); + this.completed = entity.isCompleted(); + } +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/dto/ToDoDateDto.java b/src/main/java/mos/mosback/stRoom/dto/ToDoDateDto.java new file mode 100644 index 0000000..356cef2 --- /dev/null +++ b/src/main/java/mos/mosback/stRoom/dto/ToDoDateDto.java @@ -0,0 +1,19 @@ +package mos.mosback.stRoom.dto; +import lombok.Getter; +import mos.mosback.domain.stRoom.ToDoEntity; + +@Getter +public class ToDoDateDto { + + private int year; + private int month; + private int weekOfYear; // 몇 주차인지 저장 (1주차, 2주차, ...) + + public ToDoDateDto(ToDoEntity entity) { + + this.year = entity.getYear(); + this.month = entity.getMonth(); + this.weekOfYear = entity.getWeekOfYear(); + + } +} diff --git a/src/main/java/mos/mosback/stRoom/dto/ToDoRequestDto.java b/src/main/java/mos/mosback/stRoom/dto/ToDoRequestDto.java index 036c9ef..2188edf 100644 --- a/src/main/java/mos/mosback/stRoom/dto/ToDoRequestDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/ToDoRequestDto.java @@ -9,14 +9,12 @@ @NoArgsConstructor public class ToDoRequestDto { - private int weekOfYear; private String dayOfWeek; // 사용자가 선택한 요일 private String todoContent; private boolean completed; // TodoLists 상태 ( 완료 - true, 미완료 - false) @Builder - public ToDoRequestDto(String todoContent, boolean completed,String dayOfWeek,int weekOfYear) { - this.weekOfYear = weekOfYear; + public ToDoRequestDto(String todoContent, boolean completed,String dayOfWeek) { this.dayOfWeek = dayOfWeek; this.todoContent = todoContent; this.completed = completed; @@ -24,7 +22,7 @@ public ToDoRequestDto(String todoContent, boolean completed,String dayOfWeek,int public ToDoEntity toEntity() { return ToDoEntity.builder() - .weekOfYear(weekOfYear) + .dayOfWeek(dayOfWeek) .todoContent(todoContent) .completed(completed) diff --git a/src/main/java/mos/mosback/stRoom/dto/ToDoResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/ToDoResponseDto.java deleted file mode 100644 index 4a0f905..0000000 --- a/src/main/java/mos/mosback/stRoom/dto/ToDoResponseDto.java +++ /dev/null @@ -1,16 +0,0 @@ -package mos.mosback.stRoom.dto; -import lombok.Getter; -import mos.mosback.domain.stRoom.ToDoEntity; - -@Getter -public class ToDoResponseDto { - - private String todoContent; - private boolean completed; - - public ToDoResponseDto(ToDoEntity entity) { - - this.todoContent = getTodoContent(); - this.completed = isCompleted(); - } -} \ No newline at end of file diff --git a/src/main/resources/static/MemberTodo.html b/src/main/resources/static/MemberTodo.html new file mode 100644 index 0000000..9359117 --- /dev/null +++ b/src/main/resources/static/MemberTodo.html @@ -0,0 +1,183 @@ + + + + + + Title + + + +
+
+
+
+
+
나의 스터디
+
+
+
+
TODO
+
+
+
2023.05
+ + +
+
+
+
+
모의면접 준비
+
기사 스크랩
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
탐색
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
스터디그룹
+
+
+
+
마이페이지
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
9:41
+
+
+
+
+
+
+
+ + +
+
+
+
+
다른 멤버의 TODO 보러가기
+
75%
+
+
+
+
+ + \ No newline at end of file diff --git a/src/main/resources/static/styles.css b/src/main/resources/static/styles.css new file mode 100644 index 0000000..c336d59 --- /dev/null +++ b/src/main/resources/static/styles.css @@ -0,0 +1,8 @@ + +.custom-box { + width: 20rem; + height: 46.9375rem; + border-radius: 1.5rem; + border: 3px solid #000; + background: #FFF; +} \ No newline at end of file From 5970ae89ae1d845d4251e59643202f6dbf3f4b71 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Mon, 25 Sep 2023 01:05:09 +0900 Subject: [PATCH 26/60] =?UTF-8?q?=EB=A6=AC=EB=8D=94=EA=B6=8C=ED=95=9C=20?= =?UTF-8?q?=EB=B6=80=EC=97=AC=20,=20Todo=20=EC=83=9D=EC=84=B1=20=EC=8B=9C?= =?UTF-8?q?=20=EB=82=A0=EC=A7=9C=20=EA=B8=B0=EB=8A=A5=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?(=20+yyyy-mm-n=EC=A3=BC=EC=B0=A8=20+=20=EC=9A=94=EC=9D=BC?= =?UTF-8?q?=EC=84=A0=ED=83=9D=20)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/mos/mosback/controller/StRoomController.java | 10 ++++++++++ .../java/mos/mosback/domain/stRoom/StRoomEntity.java | 9 +++------ .../mos/mosback/domain/stRoom/StudyMemberEntity.java | 1 + .../java/mos/mosback/domain/stRoom/ToDoEntity.java | 1 - src/main/java/mos/mosback/login/domain/user/User.java | 4 ++++ .../mosback/login/domain/user/service/UserService.java | 2 +- src/main/java/mos/mosback/service/StRoomService.java | 10 ++++++++-- .../mosback/stRoom/dto/StRoomMemberJoinRequestDto.java | 1 + .../mos/mosback/stRoom/dto/StRoomSaveRequestDto.java | 3 +++ 9 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/main/java/mos/mosback/controller/StRoomController.java b/src/main/java/mos/mosback/controller/StRoomController.java index 9edd649..154c680 100644 --- a/src/main/java/mos/mosback/controller/StRoomController.java +++ b/src/main/java/mos/mosback/controller/StRoomController.java @@ -5,6 +5,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; import javax.persistence.EntityNotFoundException; @@ -25,6 +27,10 @@ public StRoomController(StRoomService stRoomService) { @PostMapping("/create") public ResponseEntity saveRoom(@RequestBody StRoomSaveRequestDto requestDto) { + // 현재 로그인한 사용자의 정보 가져오기 + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + String currentEmail = authentication.getName(); // 현재 사용자의 이메일 + requestDto.setEmail(currentEmail); Long stroomId = stRoomService.save(requestDto); return ResponseEntity.status(HttpStatus.CREATED).body("created successfully. ID: " + stroomId); } @@ -126,6 +132,10 @@ public ResponseEntity getQuestionById(@PathVariable Long roomId) { } @PostMapping("/memberjoin") public ResponseEntity memberJoin(@RequestBody StRoomMemberJoinRequestDto requestDto) { + // 현재 로그인한 사용자의 정보 가져오기 + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + String currentEmail = authentication.getName(); // 현재 사용자의 이메일 + requestDto.setEmail(currentEmail); stRoomService.memberJoin(requestDto); return ResponseEntity.status(HttpStatus.CREATED).body("joined successfully."); } diff --git a/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java b/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java index bd54364..310aa87 100644 --- a/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java @@ -3,7 +3,6 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; - import javax.persistence.*; import java.time.LocalDate; import java.util.*; @@ -38,14 +37,12 @@ public class StRoomEntity extends BaseTimeEntity { private Date startDate; //스터디 시작 날짜 private LocalDate endDate; //스터디 끝나는 날짜 private boolean recruiting; //모집여부 - private String leader; - @OneToMany(mappedBy = "stRoom", fetch = FetchType.LAZY, cascade = CascadeType.ALL) private List todoEntities = new ArrayList<>(); - @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) private List studyDayEntities = new ArrayList<>(); @Builder @@ -53,7 +50,7 @@ public StRoomEntity(String title, String goal, String rules, String quest, String category, String intro, int memberNum, int maxMember ,String mod, boolean onOff, String location,int online, Date startDate, LocalDate endDate, List studyDayEntities - ,String leader ) { + ) { this.title = title; this.goal = goal; @@ -70,7 +67,7 @@ public StRoomEntity(String title, String goal, String rules, String quest, this.startDate = startDate; this.endDate = endDate; this.studyDayEntities = studyDayEntities; - this.leader = leader; + } diff --git a/src/main/java/mos/mosback/domain/stRoom/StudyMemberEntity.java b/src/main/java/mos/mosback/domain/stRoom/StudyMemberEntity.java index 8791c38..2326b49 100644 --- a/src/main/java/mos/mosback/domain/stRoom/StudyMemberEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/StudyMemberEntity.java @@ -18,6 +18,7 @@ public class StudyMemberEntity implements Serializable { @Column(name = "memberID") private Long memberId; + @JoinColumn(name = "roomID") private Long roomId; diff --git a/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java b/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java index a953a53..8484f20 100644 --- a/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java @@ -5,7 +5,6 @@ import lombok.Setter; import javax.persistence.*; -import java.time.Month; @Setter @Getter // 롬복 어노테이션 diff --git a/src/main/java/mos/mosback/login/domain/user/User.java b/src/main/java/mos/mosback/login/domain/user/User.java index 21ffb1a..59c15e3 100644 --- a/src/main/java/mos/mosback/login/domain/user/User.java +++ b/src/main/java/mos/mosback/login/domain/user/User.java @@ -2,11 +2,14 @@ import lombok.*; +import mos.mosback.domain.stRoom.StRoomEntity; +import mos.mosback.domain.stRoom.StudyMemberEntity; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import javax.persistence.*; import java.util.Date; +import java.util.List; @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -42,6 +45,7 @@ public class User { private String refreshToken; // 리프레시 토큰 + // 유저 권한 설정 메소드 public void authorizeUser() { this.role = Role.USER; diff --git a/src/main/java/mos/mosback/login/domain/user/service/UserService.java b/src/main/java/mos/mosback/login/domain/user/service/UserService.java index 355c9c6..26e1f45 100644 --- a/src/main/java/mos/mosback/login/domain/user/service/UserService.java +++ b/src/main/java/mos/mosback/login/domain/user/service/UserService.java @@ -48,7 +48,7 @@ public void signUp(UserSignUpDto userSignUpDto) throws Exception { - private User getUserByEmail(String email) throws Exception { + public User getUserByEmail(String email) throws Exception { Optional optionalUser = userRepository.findByEmail(email); if (optionalUser.isPresent()) { return optionalUser.get(); diff --git a/src/main/java/mos/mosback/service/StRoomService.java b/src/main/java/mos/mosback/service/StRoomService.java index 6ca2d06..b2299c3 100644 --- a/src/main/java/mos/mosback/service/StRoomService.java +++ b/src/main/java/mos/mosback/service/StRoomService.java @@ -4,6 +4,9 @@ import mos.mosback.domain.stRoom.MemberStatus; import mos.mosback.domain.stRoom.StRoomEntity; import mos.mosback.domain.stRoom.StudyMemberEntity; +import mos.mosback.login.domain.user.User; +import mos.mosback.login.domain.user.repository.UserRepository; +import mos.mosback.login.domain.user.service.UserService; import mos.mosback.repository.StRoomRepository; import mos.mosback.repository.StudyMemberRepository; import mos.mosback.stRoom.dto.StRoomSaveRequestDto; @@ -22,13 +25,15 @@ public class StRoomService { private final StRoomRepository stRoomRepository; private final StudyMemberRepository studyMemberRepository; + private final UserService userService; public Long save(StRoomSaveRequestDto requestDto) { try { StudyMemberEntity studyMember = new StudyMemberEntity(); studyMember.setRoomId(requestDto.getRoomID()); studyMember.setStatus(MemberStatus.Leader); - studyMember.setMemberId(studyMember.getMemberId()); + User user = userService.getUserByEmail(requestDto.getEmail()); + studyMember.setMemberId(user.getId()); studyMemberRepository.save(studyMember); return stRoomRepository.save(requestDto.toEntity()).getRoomID(); } catch (Exception e) { @@ -107,7 +112,8 @@ public void memberJoin(StRoomMemberJoinRequestDto requestDto) { studyMember.setRoomId(requestDto.getRoomID()); studyMember.setStatus(MemberStatus.Waiting); studyMember.setAnswer(requestDto.getAnswer()); - /* studyMember.setMemberId(studyMember.getMemberId());*/ + User user = userService.getUserByEmail(requestDto.getEmail()); + studyMember.setMemberId(user.getId()); studyMemberRepository.save(studyMember); } catch (Exception e) { e.printStackTrace(); diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomMemberJoinRequestDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomMemberJoinRequestDto.java index 59ab89f..24c1f64 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomMemberJoinRequestDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomMemberJoinRequestDto.java @@ -9,6 +9,7 @@ public class StRoomMemberJoinRequestDto { private Long roomID; private String answer; + private String email; } //스터디 수정 시 생성 필드에 들어가는 내용수정 diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomSaveRequestDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomSaveRequestDto.java index 9c169e6..578ff68 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomSaveRequestDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomSaveRequestDto.java @@ -2,6 +2,7 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; import mos.mosback.domain.stRoom.StRoomEntity; import mos.mosback.domain.stRoom.StudyDaysEntity; @@ -10,6 +11,7 @@ import java.util.List; @Getter +@Setter @NoArgsConstructor public class StRoomSaveRequestDto { Long roomID; @@ -26,6 +28,7 @@ public class StRoomSaveRequestDto { private int online; // 온라인일 경우 1 : 줌 2 : 디코 3: 구글미트 4: 기타 private Date startDate; //스터디 시작 날짜 private LocalDate endDate; //스터디 끝나는 날짜 + private String email; // 사용자 이메일 private List studyDayEntities; From 898b8bf40a1e83cf64e4d8ee9246e4f3eab5bc98 Mon Sep 17 00:00:00 2001 From: slonue <127409712+slonue@users.noreply.github.com> Date: Mon, 25 Sep 2023 01:59:34 +0900 Subject: [PATCH 27/60] =?UTF-8?q?=EB=B9=84=EB=B0=80=EB=B2=88=ED=98=B8?= =?UTF-8?q?=EC=A7=80=EC=9B=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index e2c31a9..78e2600 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -42,7 +42,7 @@ spring: host: smtp.naver.com # 이메일 서버 호스트 (Gmail 사용 예) port: 587 # SMTP 포트 (Gmail의 경우 465 또는 587) username: dmsthf1225@naver.com # 이메일 계정 - password: dmsthf12fkqb # 이메일 계정의 암호 또는 앱 비밀번호 (보안 설정에 따라 다름) + password: 비밀번호 properties: mail: smtp: From 3ca6098743140642c9cbd2ac4cc06971f62ce16c Mon Sep 17 00:00:00 2001 From: slonue <127409712+slonue@users.noreply.github.com> Date: Mon, 25 Sep 2023 02:01:42 +0900 Subject: [PATCH 28/60] =?UTF-8?q?=ED=81=B4=EB=9D=BC=EC=9D=B4=EC=96=B8?= =?UTF-8?q?=ED=8A=B8=EB=B9=84=EB=B0=80=EB=B2=88=ED=98=B8=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application-oauth.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/application-oauth.yml b/src/main/resources/application-oauth.yml index 08ca2a4..7e99bd6 100644 --- a/src/main/resources/application-oauth.yml +++ b/src/main/resources/application-oauth.yml @@ -5,13 +5,13 @@ spring: registration: google: client-id: 729954756779-2usa0d48vh0048r4vmmljtlrlstvcjdh.apps.googleusercontent.com - client-secret: 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 + client-secret: google-client-sercret scope: profile, email naver: client-id: jg5_V_oaR2k60xfasDRa - client-secret: XJ2kRT_oa8 + client-secret: naver-client-secret redirect-uri: http://localhost:8080/login/oauth2/code/naver authorization-grant-type: authorization_code scope: name, email, profile_image @@ -20,7 +20,7 @@ spring: kakao: client-id: bbe971abb2538851ddabe4ef20d76744 - client-secret: oScTITuccuMT1o8C6X4Vv1arBKJkNzSE + client-secret: kakao-client-secret redirect-uri: http://localhost:8080/login/oauth2/code/kakao client-authentication-method: POST authorization-grant-type: authorization_code From dcaded76bd220851d57edd95e50c2c775ce55527 Mon Sep 17 00:00:00 2001 From: slonue <127409712+slonue@users.noreply.github.com> Date: Mon, 25 Sep 2023 10:28:53 +0900 Subject: [PATCH 29/60] Update application.yml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 이메일도 지움 --- src/main/resources/application.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 78e2600..f6e6a7c 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -41,7 +41,7 @@ spring: mail: host: smtp.naver.com # 이메일 서버 호스트 (Gmail 사용 예) port: 587 # SMTP 포트 (Gmail의 경우 465 또는 587) - username: dmsthf1225@naver.com # 이메일 계정 + username: # 이메일 계정 password: 비밀번호 properties: mail: From 3dfcb52a41f225b405ff90aac423c679f29f4c90 Mon Sep 17 00:00:00 2001 From: slonue <127409712+slonue@users.noreply.github.com> Date: Mon, 25 Sep 2023 10:52:35 +0900 Subject: [PATCH 30/60] Delete src/main/resources/application-jwt.yml --- src/main/resources/application-jwt.yml | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 src/main/resources/application-jwt.yml diff --git a/src/main/resources/application-jwt.yml b/src/main/resources/application-jwt.yml deleted file mode 100644 index 76755dc..0000000 --- a/src/main/resources/application-jwt.yml +++ /dev/null @@ -1,10 +0,0 @@ -jwt: - secretKey: 'dfadfekndchnsdifqld125654x8sdfnjldsncuelsdfs45x321df' - - access: - expiration: 360000000 # 1??(60?) (1000L(ms -> s) * 60L(s -> m) * 60L(m -> h)) - header: Authorization - - refresh: - expiration: 1209600000 # (1000L(ms -> s) * 60L(s -> m) * 60L(m -> h) * 24L(h -> ??) * 14(2?)) - header: Authorization-refresh \ No newline at end of file From da71f91834cdc5ff5311c677d3b983c5637505fb Mon Sep 17 00:00:00 2001 From: slonue <127409712+slonue@users.noreply.github.com> Date: Tue, 26 Sep 2023 15:32:06 +0900 Subject: [PATCH 31/60] Update MosbackApplicationTests.java --- src/test/java/mos/mosback/MosbackApplicationTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/mos/mosback/MosbackApplicationTests.java b/src/test/java/mos/mosback/MosbackApplicationTests.java index 4a39173..c8f7838 100644 --- a/src/test/java/mos/mosback/MosbackApplicationTests.java +++ b/src/test/java/mos/mosback/MosbackApplicationTests.java @@ -3,7 +3,7 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -@SpringBootTest +//@SpringBootTest class MosbackApplicationTests { @Test From 16b8e34adc2e7c9c0d545b47b052ae13e38808e5 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Thu, 28 Sep 2023 01:15:09 +0900 Subject: [PATCH 32/60] =?UTF-8?q?=EB=A6=AC=EB=8D=94=EA=B6=8C=ED=95=9C=20?= =?UTF-8?q?=EB=B6=80=EC=97=AC=20,=20Todo=20=EC=83=9D=EC=84=B1=20=EC=8B=9C?= =?UTF-8?q?=20=EB=82=A0=EC=A7=9C=20=EA=B8=B0=EB=8A=A5=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?(=20+yyyy-mm-n=EC=A3=BC=EC=B0=A8=20+=20=EC=9A=94=EC=9D=BC?= =?UTF-8?q?=EC=84=A0=ED=83=9D=20)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mosback/controller/StRoomController.java | 11 +++-- .../mosback/controller/TodoController.java | 22 ++++----- .../mosback/domain/stRoom/StRoomEntity.java | 17 +++---- .../domain/stRoom/StudyMemberEntity.java | 4 +- .../domain/stRoom/StudyMemberTodoEntity.java | 33 ++++++++++++++ .../mos/mosback/domain/stRoom/ToDoEntity.java | 14 ++---- .../mos/mosback/domain/stRoom/TodoStatus.java | 6 +++ .../login/global/config/SecurityConfig.java | 2 +- .../mosback/repository/ToDoRepository.java | 2 +- .../mos/mosback/service/StRoomService.java | 45 +++++++++++++++---- .../java/mos/mosback/service/ToDoService.java | 5 ++- .../stRoom/dto/ToDoContentResponseDto.java | 4 -- .../mosback/stRoom/dto/ToDoRequestDto.java | 23 ++-------- 13 files changed, 111 insertions(+), 77 deletions(-) create mode 100644 src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoEntity.java create mode 100644 src/main/java/mos/mosback/domain/stRoom/TodoStatus.java diff --git a/src/main/java/mos/mosback/controller/StRoomController.java b/src/main/java/mos/mosback/controller/StRoomController.java index 154c680..a4fbc4a 100644 --- a/src/main/java/mos/mosback/controller/StRoomController.java +++ b/src/main/java/mos/mosback/controller/StRoomController.java @@ -10,6 +10,7 @@ import org.springframework.web.bind.annotation.*; import javax.persistence.EntityNotFoundException; +import javax.servlet.http.HttpServletRequest; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -26,13 +27,17 @@ public StRoomController(StRoomService stRoomService) { } @PostMapping("/create") - public ResponseEntity saveRoom(@RequestBody StRoomSaveRequestDto requestDto) { + public ResponseEntity saveRoom(@RequestBody StRoomSaveRequestDto requestDto, HttpServletRequest req) { // 현재 로그인한 사용자의 정보 가져오기 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String currentEmail = authentication.getName(); // 현재 사용자의 이메일 requestDto.setEmail(currentEmail); - Long stroomId = stRoomService.save(requestDto); - return ResponseEntity.status(HttpStatus.CREATED).body("created successfully. ID: " + stroomId); + Long stroomId = stRoomService.save(requestDto, req); + if (stroomId != null) { + return ResponseEntity.status(HttpStatus.CREATED).body("created successfully. ID: " + stroomId); + } else { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Server error!"); + } } @GetMapping("/MyStudy/{roomId}") public ResponseEntity FindByID (@PathVariable Long roomId) { diff --git a/src/main/java/mos/mosback/controller/TodoController.java b/src/main/java/mos/mosback/controller/TodoController.java index 2fb0637..c12c267 100644 --- a/src/main/java/mos/mosback/controller/TodoController.java +++ b/src/main/java/mos/mosback/controller/TodoController.java @@ -30,13 +30,7 @@ public ResponseEntity addTodo(@RequestBody ToDoRequestDto requestDto) { return ResponseEntity.status(HttpStatus.CREATED).body("TodoList 추가 완료. index : " +todo.getTodoId()); } - @GetMapping("/{year}/{month}/{weekOfYear}/{dayOfWeek}") - public ResponseEntity> FindByDate(@PathVariable int year, @PathVariable int month, @PathVariable int weekOfYear, @PathVariable String dayOfWeek) { - List todos = toDoService.findByDate(year, month, weekOfYear, dayOfWeek); - return new ResponseEntity<>(todos, HttpStatus.OK); - - } @GetMapping("/date") public ResponseEntity> getTodoDate() { List todoDates = toDoService.getTodoDate(); @@ -49,23 +43,23 @@ public ResponseEntity> getTodoDate() { } - @PutMapping("/update/{TodoId}") - public ResponseEntity updateTodo(@PathVariable Long TodoId, @RequestBody ToDoRequestDto requestDto) { + @PutMapping("/update/{todoId}") + public ResponseEntity updateTodo(@PathVariable Long todoId, @RequestBody ToDoRequestDto requestDto) { try { - ToDoEntity updatedToDo = toDoService.updateTodo(TodoId, requestDto.getTodoContent(), + ToDoEntity updatedToDo = toDoService.updateTodo(todoId, requestDto.getTodoContent(), requestDto.isCompleted(),requestDto.getDayOfWeek()); - return ResponseEntity.ok("ToDo 업데이트 완료. Index: " + TodoId); + return ResponseEntity.ok("ToDo 업데이트 완료. Index: " + todoId); } catch (IllegalArgumentException e) { return ResponseEntity.status(HttpStatus.NOT_FOUND) .body("NOT FOUND TODO"); } } - @DeleteMapping("/delete/{TodoId}") - public ResponseEntity deleteTodo(@PathVariable Long TodoId) { + @DeleteMapping("/delete/{todoId}") + public ResponseEntity deleteTodo(@PathVariable Long todoId) { try { - toDoService.deleteTodo(TodoId); - return ResponseEntity.ok("ToDo 삭제 완료. Index: " + TodoId); + toDoService.deleteTodo(todoId); + return ResponseEntity.ok("ToDo 삭제 완료. Index: " + todoId); } catch (IllegalArgumentException e) { return ResponseEntity.status(HttpStatus.NOT_FOUND) .body("NOT FOUND TODO"); diff --git a/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java b/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java index 310aa87..8ce832e 100644 --- a/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java @@ -38,20 +38,18 @@ public class StRoomEntity extends BaseTimeEntity { private LocalDate endDate; //스터디 끝나는 날짜 private boolean recruiting; //모집여부 - - @OneToMany(mappedBy = "stRoom", fetch = FetchType.LAZY, cascade = CascadeType.ALL) - private List todoEntities = new ArrayList<>(); - @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) private List studyDayEntities = new ArrayList<>(); + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) + private List studyMemberEntities = new ArrayList<>(); + @Builder public StRoomEntity(String title, String goal, String rules, String quest, String category, String intro, int memberNum, int maxMember - ,String mod, boolean onOff, String location,int online, + ,String mod, boolean onOff, String location,int online, Date startDate, LocalDate endDate, List studyDayEntities - ) { - + ) { this.title = title; this.goal = goal; this.rules = rules; @@ -67,11 +65,8 @@ public StRoomEntity(String title, String goal, String rules, String quest, this.startDate = startDate; this.endDate = endDate; this.studyDayEntities = studyDayEntities; - - } - // 다른 필요한 Getter 및 Setter 메서드 public void update(String title, String goal, String rules, String quest, @@ -92,7 +87,5 @@ public void update(String title, String goal, String rules, String quest, this.startDate = startDate; this.endDate = endDate; this.studyDayEntities = studyDayEntities; - } - } \ No newline at end of file diff --git a/src/main/java/mos/mosback/domain/stRoom/StudyMemberEntity.java b/src/main/java/mos/mosback/domain/stRoom/StudyMemberEntity.java index 2326b49..268bca0 100644 --- a/src/main/java/mos/mosback/domain/stRoom/StudyMemberEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/StudyMemberEntity.java @@ -18,9 +18,9 @@ public class StudyMemberEntity implements Serializable { @Column(name = "memberID") private Long memberId; - + @ManyToOne @JoinColumn(name = "roomID") - private Long roomId; + private StRoomEntity stRoom; // 다른 필드와 매핑 diff --git a/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoEntity.java b/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoEntity.java new file mode 100644 index 0000000..bf1c820 --- /dev/null +++ b/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoEntity.java @@ -0,0 +1,33 @@ +package mos.mosback.domain.stRoom; + +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import javax.persistence.*; +import java.io.Serializable; + +@Getter // 롬복 어노테이션 +@Setter +@NoArgsConstructor +@Entity +public class StudyMemberTodoEntity implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "memberID") + private Long memberId; + + @ManyToOne + @JoinColumn(name = "roomID") + private StRoomEntity stRoom; + + @ManyToOne + @JoinColumn(name = "todoId") + private ToDoEntity toDoEntity; + + // 다른 필드와 매핑 + @Enumerated(EnumType.STRING) + private TodoStatus status; +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java b/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java index 8484f20..e58b2da 100644 --- a/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java @@ -10,22 +10,18 @@ @Getter // 롬복 어노테이션 @NoArgsConstructor @Entity //JPA 어노테이션 (주요어노테이션) : 테이블과 링크될 클래스 -public class ToDoEntity { +public class ToDoEntity extends BaseTimeEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long TodoId; + private Long todoId; @ManyToOne @JoinColumn(name = "roomID") private StRoomEntity stRoom; - @Column private String todoContent; - @Column - private boolean completed; - // TodoLists 상태 ( 완료 - true, 미완료 - false) @Column private int year; @Column @@ -38,17 +34,15 @@ public class ToDoEntity { @Builder //해당 클래스의 빌더 클래스 생성. 생성자 상단에 선언 시 생성자에 포함된 필드만 빌더에 포함 - public ToDoEntity(String todoContent, Boolean completed,String dayOfWeek,int weekOfYear,int year,int month) { + public ToDoEntity(String todoContent, String dayOfWeek,int weekOfYear,int year,int month) { this.todoContent = todoContent; - this.completed = completed; this.dayOfWeek = dayOfWeek; this.weekOfYear = weekOfYear; this.year = year; this.month = month; } - public void updateToDo(String todoContent,boolean completed,String dayOfWeek){ + public void updateToDo(String todoContent,String dayOfWeek){ this.todoContent = todoContent; - this.completed = completed; this.dayOfWeek = dayOfWeek; diff --git a/src/main/java/mos/mosback/domain/stRoom/TodoStatus.java b/src/main/java/mos/mosback/domain/stRoom/TodoStatus.java new file mode 100644 index 0000000..636e2b8 --- /dev/null +++ b/src/main/java/mos/mosback/domain/stRoom/TodoStatus.java @@ -0,0 +1,6 @@ +package mos.mosback.domain.stRoom; + +public enum TodoStatus { + Waiting, + Completed +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/login/global/config/SecurityConfig.java b/src/main/java/mos/mosback/login/global/config/SecurityConfig.java index 76609b6..05818a3 100644 --- a/src/main/java/mos/mosback/login/global/config/SecurityConfig.java +++ b/src/main/java/mos/mosback/login/global/config/SecurityConfig.java @@ -63,7 +63,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { // 기본 페이지, css, image, js 하위 폴더에 있는 자료들은 모두 접근 가능, h2-console에 접근 가능 .antMatchers("/","/css/**","/images/**","/js/**","/favicon.ico","/h2-console/**").permitAll() .antMatchers("/sign-up","/studyRoom/create","/studyRoom/create","/studyRoom/update/{roomID}","/studyRoom/{roomID}", - "/todo/add","/todo/update{TodoIdx}","/todo/delete/{TodoIdx}","/todo/{TodoId}","/studyRoom/get/{roomID}", + "/todo/add","/todo/update{todoId}","/todo/delete/{todoId}","/todo/{todoId}","/studyRoom/get/{roomID}", "todo/{year}/{month}/{weekOfYear}/{dayOfWeek}", "/studyRoom/all","/studyRoom/search","/studyRoom/byCategory/{category}","/studyRoom/recruiting").permitAll() // 회원가입 접근 가능 .anyRequest().authenticated() // 위의 경로 이외에는 모두 인증된 사용자만 접근 가능 .and() diff --git a/src/main/java/mos/mosback/repository/ToDoRepository.java b/src/main/java/mos/mosback/repository/ToDoRepository.java index 9af73c0..4c49928 100644 --- a/src/main/java/mos/mosback/repository/ToDoRepository.java +++ b/src/main/java/mos/mosback/repository/ToDoRepository.java @@ -8,7 +8,7 @@ import java.util.List; public interface ToDoRepository extends JpaRepository { - @Query("SELECT t FROM ToDoEntity t ORDER BY t.TodoId DESC") + @Query("SELECT t FROM ToDoEntity t ORDER BY t.todoId DESC") List findAllDesc(); //Todo리스트를 조회시 todoID를 기준으로 내림차순 정렬 List findByDayOfWeekAndWeekOfYear(String dayOfWeek, int weekOfYear); diff --git a/src/main/java/mos/mosback/service/StRoomService.java b/src/main/java/mos/mosback/service/StRoomService.java index b2299c3..d052878 100644 --- a/src/main/java/mos/mosback/service/StRoomService.java +++ b/src/main/java/mos/mosback/service/StRoomService.java @@ -7,6 +7,7 @@ import mos.mosback.login.domain.user.User; import mos.mosback.login.domain.user.repository.UserRepository; import mos.mosback.login.domain.user.service.UserService; +import mos.mosback.login.global.jwt.service.JwtService; import mos.mosback.repository.StRoomRepository; import mos.mosback.repository.StudyMemberRepository; import mos.mosback.stRoom.dto.StRoomSaveRequestDto; @@ -15,8 +16,11 @@ import org.springframework.transaction.annotation.Transactional; import javax.persistence.EntityNotFoundException; +import javax.servlet.http.HttpServletRequest; +import javax.swing.text.html.Option; import java.time.LocalDateTime; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; @@ -26,16 +30,31 @@ public class StRoomService { private final StRoomRepository stRoomRepository; private final StudyMemberRepository studyMemberRepository; private final UserService userService; + private final JwtService jwtService; - public Long save(StRoomSaveRequestDto requestDto) { + public Long save(StRoomSaveRequestDto requestDto, HttpServletRequest req) { try { + // 1. Study Room 저장 + StRoomEntity stRoom = stRoomRepository.save(requestDto.toEntity()); + + // 2. 스터디 멤버 정보 저장할 변수 선언 StudyMemberEntity studyMember = new StudyMemberEntity(); - studyMember.setRoomId(requestDto.getRoomID()); - studyMember.setStatus(MemberStatus.Leader); - User user = userService.getUserByEmail(requestDto.getEmail()); + + // 3. Access Token 가져오기 + String accessToken = Optional.ofNullable(jwtService.extractAccessToken(req)).get().orElse(""); + + // 4. Access Token으로 스터디 멤버 정보 가져오기 (User Entity를) + String loginUserEmail = Optional.ofNullable(jwtService.extractEmail(accessToken)).get().orElse(""); + User user = userService.getUserByEmail(loginUserEmail); + + // 4. 정보 대입 studyMember.setMemberId(user.getId()); + + // 5. Study Member 저장 + studyMember.setStRoom(stRoom); + studyMember.setStatus(MemberStatus.Leader); studyMemberRepository.save(studyMember); - return stRoomRepository.save(requestDto.toEntity()).getRoomID(); + return stRoom.getRoomID(); } catch (Exception e) { e.printStackTrace(); return null; @@ -56,6 +75,7 @@ public void update(Long roomID, StRoomUpdateRequestDto requestDto) { requestDto.getOnline(), requestDto.getStartDate(), requestDto.getEndDate(), requestDto.getStudyDayEntities()); + stRoomRepository.save(stroomEntity); } //stroomsRepository를 사용하여 데이터베이스에서 주어진 id에 해당하는 게시물을 찾기 @@ -108,12 +128,21 @@ public List findByCategory(String category) { public void memberJoin(StRoomMemberJoinRequestDto requestDto) { try { + // 1. save할 변수 선언 StudyMemberEntity studyMember = new StudyMemberEntity(); - studyMember.setRoomId(requestDto.getRoomID()); - studyMember.setStatus(MemberStatus.Waiting); - studyMember.setAnswer(requestDto.getAnswer()); + + // 2. 가입 시에는 룸ID를 요청 파라미터에서 받아서 StRoom 조회 + StRoomEntity stRoomEntity = stRoomRepository.findById(requestDto.getRoomID()) + .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id =" + requestDto.getRoomID())); + + // 3. 사용자 이메일 조회해서 save 전에 주입 User user = userService.getUserByEmail(requestDto.getEmail()); studyMember.setMemberId(user.getId()); + + // 4. 조회된 정보 토대로 StudyMember save 처리 + studyMember.setStRoom(stRoomEntity); + studyMember.setStatus(MemberStatus.Waiting); + studyMember.setAnswer(requestDto.getAnswer()); studyMemberRepository.save(studyMember); } catch (Exception e) { e.printStackTrace(); diff --git a/src/main/java/mos/mosback/service/ToDoService.java b/src/main/java/mos/mosback/service/ToDoService.java index 11b613c..601ee21 100644 --- a/src/main/java/mos/mosback/service/ToDoService.java +++ b/src/main/java/mos/mosback/service/ToDoService.java @@ -29,7 +29,7 @@ public ToDoEntity addTodo(String dayOfWeek, String todoContent) { List existingTodos = toDoRepository.findByDayOfWeekAndWeekOfYear(dayOfWeek, weekOfMonth); - ToDoEntity todo = new ToDoEntity(todoContent, false, dayOfWeek, weekOfMonth, currentDate.getYear(),currentDate.getMonthValue()); + ToDoEntity todo = new ToDoEntity(todoContent, dayOfWeek, weekOfMonth, currentDate.getYear(),currentDate.getMonthValue()); return toDoRepository.save(todo); } @@ -90,7 +90,8 @@ public ToDoEntity updateTodo(Long todoId, String todoContent, boolean completed, ToDoEntity toDoEntity = toDoRepository.findById(todoId) .orElseThrow(() -> new IllegalArgumentException("해당 ToDo를 찾을 수 없습니다.")); - toDoEntity.updateToDo(todoContent, completed,dayOfWeek); + toDoEntity.updateToDo(todoContent, dayOfWeek); + toDoRepository.save(toDoEntity); return toDoEntity; } public List findByWeekOfYearAndDayOfWeek(String weekOfYear, int dayOfWeek) { diff --git a/src/main/java/mos/mosback/stRoom/dto/ToDoContentResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/ToDoContentResponseDto.java index 0f7e0ad..ab8d194 100644 --- a/src/main/java/mos/mosback/stRoom/dto/ToDoContentResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/ToDoContentResponseDto.java @@ -4,13 +4,9 @@ @Getter public class ToDoContentResponseDto { - private String todoContent; - private boolean completed; public ToDoContentResponseDto(ToDoEntity entity) { - this.todoContent = entity.getTodoContent(); - this.completed = entity.isCompleted(); } } \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/dto/ToDoRequestDto.java b/src/main/java/mos/mosback/stRoom/dto/ToDoRequestDto.java index 2188edf..804274a 100644 --- a/src/main/java/mos/mosback/stRoom/dto/ToDoRequestDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/ToDoRequestDto.java @@ -1,32 +1,15 @@ package mos.mosback.stRoom.dto; -import lombok.Builder; + import lombok.Getter; import lombok.NoArgsConstructor; -import mos.mosback.domain.stRoom.ToDoEntity; +import lombok.Setter; +@Setter @Getter @NoArgsConstructor public class ToDoRequestDto { - private String dayOfWeek; // 사용자가 선택한 요일 private String todoContent; private boolean completed; // TodoLists 상태 ( 완료 - true, 미완료 - false) - - @Builder - public ToDoRequestDto(String todoContent, boolean completed,String dayOfWeek) { - this.dayOfWeek = dayOfWeek; - this.todoContent = todoContent; - this.completed = completed; - } - - public ToDoEntity toEntity() { - return ToDoEntity.builder() - - .dayOfWeek(dayOfWeek) - .todoContent(todoContent) - .completed(completed) - .build(); - } - } \ No newline at end of file From e2a088aaebdcf8d9e56899fb8011c1c69bfeb5b1 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Tue, 17 Oct 2023 15:42:02 +0900 Subject: [PATCH 33/60] Changes --- gradle/wrapper/gradle-wrapper.jar | Bin 60756 -> 0 bytes .../mosback/controller/TodoController.java | 17 +- .../mosback/domain/stRoom/StRoomEntity.java | 3 + .../domain/stRoom/StudyMemberEntity.java | 4 - .../mos/mosback/domain/stRoom/ToDoEntity.java | 24 +-- .../login/domain/user/dto/UserInfo.java | 40 ---- .../mosback/repository/ToDoRepository.java | 8 - .../java/mos/mosback/service/ToDoService.java | 83 +------- .../mos/mosback/stRoom/dto/ToDoDateDto.java | 19 -- src/main/resources/application-jwt.yml | 10 + src/main/resources/application-oauth.yml | 8 +- src/main/resources/application.yml | 2 +- src/main/resources/static/MemberTodo.html | 183 ------------------ src/main/resources/static/styles.css | 8 - src/main/resources/templates/create_form.html | 0 src/main/resources/templates/index.html | 0 .../mos/mosback/MosbackApplicationTests.java | 13 -- src/test/java/mos/mosback/WithMockUser.java | 4 - .../mosback/domain/posts/PostsRepository.java | 0 19 files changed, 32 insertions(+), 394 deletions(-) delete mode 100644 src/main/java/mos/mosback/stRoom/dto/ToDoDateDto.java create mode 100644 src/main/resources/application-jwt.yml delete mode 100644 src/main/resources/static/MemberTodo.html delete mode 100644 src/main/resources/static/styles.css create mode 100644 src/main/resources/templates/create_form.html create mode 100644 src/main/resources/templates/index.html create mode 100644 src/test/java/mos/mosback/domain/posts/PostsRepository.java diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 249e5832f090a2944b7473328c07c9755baa3196..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 GIT binary patch literal 0 HcmV?d00001 literal 60756 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 addTodo(@RequestBody ToDoRequestDto requestDto) { ToDoEntity todo = toDoService.addTodo( - requestDto.getDayOfWeek(), requestDto.getTodoContent()); + requestDto.getTodoContent()); return ResponseEntity.status(HttpStatus.CREATED).body("TodoList 추가 완료. index : " +todo.getTodoId()); } - @GetMapping("/date") - public ResponseEntity> getTodoDate() { - List todoDates = toDoService.getTodoDate(); - - if (!todoDates.isEmpty()) { - return new ResponseEntity<>(todoDates, HttpStatus.OK); - } else { - return ResponseEntity.notFound().build(); - } - } @PutMapping("/update/{todoId}") public ResponseEntity updateTodo(@PathVariable Long todoId, @RequestBody ToDoRequestDto requestDto) { try { - ToDoEntity updatedToDo = toDoService.updateTodo(todoId, requestDto.getTodoContent(), - requestDto.isCompleted(),requestDto.getDayOfWeek()); + ToDoEntity updatedToDo = toDoService.updateTodo(todoId, requestDto.getTodoContent()); return ResponseEntity.ok("ToDo 업데이트 완료. Index: " + todoId); } catch (IllegalArgumentException e) { return ResponseEntity.status(HttpStatus.NOT_FOUND) diff --git a/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java b/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java index 8ce832e..eb58eef 100644 --- a/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java @@ -44,6 +44,9 @@ public class StRoomEntity extends BaseTimeEntity { @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) private List studyMemberEntities = new ArrayList<>(); + @OneToMany (fetch = FetchType.LAZY, cascade = CascadeType.ALL) + private List studyMemberTodoEntities = new ArrayList<>(); + @Builder public StRoomEntity(String title, String goal, String rules, String quest, String category, String intro, int memberNum, int maxMember diff --git a/src/main/java/mos/mosback/domain/stRoom/StudyMemberEntity.java b/src/main/java/mos/mosback/domain/stRoom/StudyMemberEntity.java index 268bca0..4fd9e34 100644 --- a/src/main/java/mos/mosback/domain/stRoom/StudyMemberEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/StudyMemberEntity.java @@ -31,9 +31,5 @@ public class StudyMemberEntity implements Serializable { private String answer; // 스터디 답변 - @Builder - public StudyMemberEntity(MemberStatus status){ - this.status = status; - } } diff --git a/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java b/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java index e58b2da..3acd0a9 100644 --- a/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java @@ -22,31 +22,13 @@ public class ToDoEntity extends BaseTimeEntity { @Column private String todoContent; - @Column - private int year; - @Column - private int month; - @Column - private int weekOfYear; // 몇 주차인지 저장 (1주차, 2주차, ...) - @Column - private String dayOfWeek; // 선택한 요일 (월요일, 화요일, ...) - - - - @Builder //해당 클래스의 빌더 클래스 생성. 생성자 상단에 선언 시 생성자에 포함된 필드만 빌더에 포함 - public ToDoEntity(String todoContent, String dayOfWeek,int weekOfYear,int year,int month) { + public void update(String todoContent) + { this.todoContent = todoContent; - this.dayOfWeek = dayOfWeek; - this.weekOfYear = weekOfYear; - this.year = year; - this.month = month; } - public void updateToDo(String todoContent,String dayOfWeek){ - this.todoContent = todoContent; - this.dayOfWeek = dayOfWeek; - } +// 스터디 방에 대한 Todo 정보를 담는 엔티티 } \ No newline at end of file diff --git a/src/main/java/mos/mosback/login/domain/user/dto/UserInfo.java b/src/main/java/mos/mosback/login/domain/user/dto/UserInfo.java index 02b77e0..e69de29 100644 --- a/src/main/java/mos/mosback/login/domain/user/dto/UserInfo.java +++ b/src/main/java/mos/mosback/login/domain/user/dto/UserInfo.java @@ -1,40 +0,0 @@ -package mos.mosback.login.domain.user.dto; - -public class UserInfo { - - private String email; - private String password; - - // 생성자, 게터/세터 등 생략 - - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - private String nickname; - - public UserInfo(String nickname) { - this.nickname = nickname; - } - - public String getNickname() { - return nickname; - } - - public void setNickname(String nickname) { - this.nickname = nickname; - } -} \ No newline at end of file diff --git a/src/main/java/mos/mosback/repository/ToDoRepository.java b/src/main/java/mos/mosback/repository/ToDoRepository.java index 4c49928..168ba7a 100644 --- a/src/main/java/mos/mosback/repository/ToDoRepository.java +++ b/src/main/java/mos/mosback/repository/ToDoRepository.java @@ -1,6 +1,5 @@ package mos.mosback.repository; import mos.mosback.domain.stRoom.ToDoEntity; -import mos.mosback.stRoom.dto.ToDoDateDto; import mos.mosback.stRoom.dto.ToDoContentResponseDto; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; @@ -11,12 +10,5 @@ public interface ToDoRepository extends JpaRepository { @Query("SELECT t FROM ToDoEntity t ORDER BY t.todoId DESC") List findAllDesc(); //Todo리스트를 조회시 todoID를 기준으로 내림차순 정렬 - List findByDayOfWeekAndWeekOfYear(String dayOfWeek, int weekOfYear); - - @Query("SELECT new mos.mosback.stRoom.dto.ToDoContentResponseDto(t) FROM ToDoEntity t") - ListfindByDate(int year, int month, int weekOfYear, String dayOfWeek); - - @Query("SELECT new mos.mosback.stRoom.dto.ToDoDateDto(t) FROM ToDoEntity t") - ListgetTodoDate(); } diff --git a/src/main/java/mos/mosback/service/ToDoService.java b/src/main/java/mos/mosback/service/ToDoService.java index 601ee21..d931493 100644 --- a/src/main/java/mos/mosback/service/ToDoService.java +++ b/src/main/java/mos/mosback/service/ToDoService.java @@ -2,7 +2,6 @@ import lombok.RequiredArgsConstructor; import mos.mosback.domain.stRoom.ToDoEntity; import mos.mosback.repository.ToDoRepository; -import mos.mosback.stRoom.dto.ToDoDateDto; import mos.mosback.stRoom.dto.ToDoContentResponseDto; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -19,90 +18,26 @@ public class ToDoService { private final ToDoRepository toDoRepository; @Transactional - public ToDoEntity addTodo(String dayOfWeek, String todoContent) { - LocalDate currentDate = LocalDate.now(); - - // 주차 계산 - int weekOfMonth = getCurrentWeekOfMonth(currentDate); - - // 해당 요일 및 주차의 Todo를 조회 - List existingTodos = toDoRepository.findByDayOfWeekAndWeekOfYear(dayOfWeek, weekOfMonth); - - - ToDoEntity todo = new ToDoEntity(todoContent, dayOfWeek, weekOfMonth, currentDate.getYear(),currentDate.getMonthValue()); - return toDoRepository.save(todo); + public ToDoEntity addTodo(String todoContent) { + ToDoEntity toDoEntity = new ToDoEntity(); + return toDoRepository.save(toDoEntity); } - private int getCurrentWeekOfMonth(LocalDate currentDate) { - // 한 주의 시작은 월요일이고, 첫 주에 4일 이상이 포함되어야 첫 주 취급 (목/금/토/일) - DayOfWeek firstDayOfWeek = currentDate.withDayOfMonth(1).getDayOfWeek(); - int daysToAdd = DayOfWeek.MONDAY.getValue() - firstDayOfWeek.getValue(); - - if (daysToAdd < 0) { - daysToAdd += 7; // If it's before Monday, move to the next Monday - } - - LocalDate firstMondayOfMonth = currentDate.withDayOfMonth(1).plusDays(daysToAdd); - - int weekOfMonth = (currentDate.getDayOfMonth() - 1) / 7 + 1; - - // 마지막 주차의 경우 - if (weekOfMonth == 5) { - DayOfWeek lastDayOfWeek = currentDate.withDayOfMonth(currentDate.lengthOfMonth()).getDayOfWeek(); - - // 마지막 날이 월~수 사이이면 다음달 1주차로 계산 - if (lastDayOfWeek.getValue() <= DayOfWeek.WEDNESDAY.getValue()) { - LocalDate firstDayOfNextMonth = currentDate.withDayOfMonth(1).plusMonths(1); - DayOfWeek firstDayOfNextMonthOfWeek = firstDayOfNextMonth.getDayOfWeek(); - - int daysToAddToNextMonth = DayOfWeek.MONDAY.getValue() - firstDayOfNextMonthOfWeek.getValue(); - - if (daysToAddToNextMonth < 0) { - daysToAddToNextMonth += 7; - } - - LocalDate firstMondayOfNextMonth = firstDayOfNextMonth.plusDays(daysToAddToNextMonth); - - weekOfMonth = 1; // 다음달의 첫 주로 설정 - } - } - - return weekOfMonth; - } -// @Transactional -// public ToDoResponseDto findById(Long todoId) { -// Optional optionalToDoEntity = toDoRepository.findById(todoId); -// -// // ToDoEntity를 ToDoResponseDto로 변환하여 반환 -// return optionalToDoEntity.map(ToDoResponseDto::new).orElse(null); // 또는 예외 처리를 수행 -// } @Transactional - public void deleteTodo(Long todoId) { + public ToDoEntity updateTodo(Long todoId, String todoContent) { ToDoEntity toDoEntity = toDoRepository.findById(todoId) .orElseThrow(() -> new IllegalArgumentException("해당 ToDo를 찾을 수 없습니다.")); - toDoRepository.delete(toDoEntity); + toDoEntity.update(todoContent); + return toDoEntity; } @Transactional - public ToDoEntity updateTodo(Long todoId, String todoContent, boolean completed,String dayOfWeek) { + public void deleteTodo(Long todoId) { ToDoEntity toDoEntity = toDoRepository.findById(todoId) .orElseThrow(() -> new IllegalArgumentException("해당 ToDo를 찾을 수 없습니다.")); - toDoEntity.updateToDo(todoContent, dayOfWeek); - toDoRepository.save(toDoEntity); - return toDoEntity; - } - public List findByWeekOfYearAndDayOfWeek(String weekOfYear, int dayOfWeek) { - return toDoRepository.findByDayOfWeekAndWeekOfYear(weekOfYear, dayOfWeek); - } - - public List findByDate(int year, int month, int weekOfYear, String dayOfWeek) { - return toDoRepository.findByDate(year, month, weekOfYear, dayOfWeek); - } - - public List getTodoDate(){ - return toDoRepository.getTodoDate(); + toDoRepository.delete(toDoEntity); } -} \ No newline at end of file +} diff --git a/src/main/java/mos/mosback/stRoom/dto/ToDoDateDto.java b/src/main/java/mos/mosback/stRoom/dto/ToDoDateDto.java deleted file mode 100644 index 356cef2..0000000 --- a/src/main/java/mos/mosback/stRoom/dto/ToDoDateDto.java +++ /dev/null @@ -1,19 +0,0 @@ -package mos.mosback.stRoom.dto; -import lombok.Getter; -import mos.mosback.domain.stRoom.ToDoEntity; - -@Getter -public class ToDoDateDto { - - private int year; - private int month; - private int weekOfYear; // 몇 주차인지 저장 (1주차, 2주차, ...) - - public ToDoDateDto(ToDoEntity entity) { - - this.year = entity.getYear(); - this.month = entity.getMonth(); - this.weekOfYear = entity.getWeekOfYear(); - - } -} diff --git a/src/main/resources/application-jwt.yml b/src/main/resources/application-jwt.yml new file mode 100644 index 0000000..d68b877 --- /dev/null +++ b/src/main/resources/application-jwt.yml @@ -0,0 +1,10 @@ +jwt: + secretKey: secretkey + + access: + expiration: 360000000 # 1??(60?) (1000L(ms -> s) * 60L(s -> m) * 60L(m -> h)) + header: Authorization + + refresh: + expiration: 1209600000 # (1000L(ms -> s) * 60L(s -> m) * 60L(m -> h) * 24L(h -> ??) * 14(2?)) + header: Authorization-refresh diff --git a/src/main/resources/application-oauth.yml b/src/main/resources/application-oauth.yml index 29b3b56..4959327 100644 --- a/src/main/resources/application-oauth.yml +++ b/src/main/resources/application-oauth.yml @@ -5,13 +5,13 @@ spring: registration: google: client-id: 729954756779-2usa0d48vh0048r4vmmljtlrlstvcjdh.apps.googleusercontent.com - client-secret: google-client-sercret + client-secret: 구글시크릿 scope: profile, email naver: client-id: jg5_V_oaR2k60xfasDRa - client-secret: naver-client-secret + client-secret: 네이버시크릿 redirect-uri: http://localhost:8080/login/oauth2/code/naver authorization-grant-type: authorization_code scope: name, email, profile_image @@ -20,7 +20,7 @@ spring: kakao: client-id: bbe971abb2538851ddabe4ef20d76744 - client-secret: kakao-client-secret + client-secret: 카카오시크릿 redirect-uri: http://localhost:8080/login/oauth2/code/kakao client-authentication-method: POST authorization-grant-type: authorization_code @@ -39,4 +39,4 @@ spring: authorization-uri: https://kauth.kakao.com/oauth/authorize token-uri: https://kauth.kakao.com/oauth/token user-info-uri: https://kapi.kakao.com/v2/user/me - user-name-attribute: id + user-name-attribute: id \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 08e8084..eb92159 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -53,4 +53,4 @@ spring: debug: true # 디버그 모드 활성화 logging: level: - root: DEBUG + root: DEBUG \ No newline at end of file diff --git a/src/main/resources/static/MemberTodo.html b/src/main/resources/static/MemberTodo.html deleted file mode 100644 index 9359117..0000000 --- a/src/main/resources/static/MemberTodo.html +++ /dev/null @@ -1,183 +0,0 @@ - - - - - - Title - - - -

-
-
-
-
-
나의 스터디
-
-
-
-
TODO
-
-
-
2023.05
- - -
-
-
-
-
모의면접 준비
-
기사 스크랩
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
탐색
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
스터디그룹
-
-
-
-
마이페이지
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
9:41
-
-
-
-
-
-
-
- - -
-
-
-
-
다른 멤버의 TODO 보러가기
-
75%
-
-
-
-
- - \ No newline at end of file diff --git a/src/main/resources/static/styles.css b/src/main/resources/static/styles.css deleted file mode 100644 index c336d59..0000000 --- a/src/main/resources/static/styles.css +++ /dev/null @@ -1,8 +0,0 @@ - -.custom-box { - width: 20rem; - height: 46.9375rem; - border-radius: 1.5rem; - border: 3px solid #000; - background: #FFF; -} \ No newline at end of file diff --git a/src/main/resources/templates/create_form.html b/src/main/resources/templates/create_form.html new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html new file mode 100644 index 0000000..e69de29 diff --git a/src/test/java/mos/mosback/MosbackApplicationTests.java b/src/test/java/mos/mosback/MosbackApplicationTests.java index c8f7838..e69de29 100644 --- a/src/test/java/mos/mosback/MosbackApplicationTests.java +++ b/src/test/java/mos/mosback/MosbackApplicationTests.java @@ -1,13 +0,0 @@ -package mos.mosback; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -//@SpringBootTest -class MosbackApplicationTests { - - @Test - void contextLoads() { - } - -} diff --git a/src/test/java/mos/mosback/WithMockUser.java b/src/test/java/mos/mosback/WithMockUser.java index 9d0207f..e69de29 100644 --- a/src/test/java/mos/mosback/WithMockUser.java +++ b/src/test/java/mos/mosback/WithMockUser.java @@ -1,4 +0,0 @@ -package mos.mosback; - -public @interface WithMockUser { -} diff --git a/src/test/java/mos/mosback/domain/posts/PostsRepository.java b/src/test/java/mos/mosback/domain/posts/PostsRepository.java new file mode 100644 index 0000000..e69de29 From 68f421ccbeb5b3dae6c488123966c5ddc0bca8b3 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Wed, 18 Oct 2023 22:00:17 +0900 Subject: [PATCH 34/60] =?UTF-8?q?Todo=20=EC=99=84=EC=84=B1,=20=EA=B0=80?= =?UTF-8?q?=EC=9E=85=EC=97=AC=EB=B6=80=20=ED=99=95=EC=9D=B8=20APi=20?= =?UTF-8?q?=EC=99=84=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mosback/controller/StRoomController.java | 24 ++++++++-- .../mosback/controller/TodoController.java | 30 ++++++++---- .../mosback/domain/stRoom/StRoomEntity.java | 2 - .../domain/stRoom/StudyMemberEntity.java | 1 - .../domain/stRoom/StudyMemberTodoEntity.java | 8 ++++ .../mos/mosback/domain/stRoom/ToDoEntity.java | 3 +- .../repository/MemberTodoRepository.java | 10 ++++ .../repository/StudyMemberRepository.java | 4 ++ .../mosback/repository/ToDoRepository.java | 2 - .../mos/mosback/service/StRoomService.java | 23 +++++++--- .../java/mos/mosback/service/ToDoService.java | 46 +++++++++++++++++-- ...uestDto.java => MemberToDoRequestDto.java} | 4 +- .../dto/StRoomMemberJoinRequestDto.java | 3 +- ...nseDto.java => StRoomToDoResponseDto.java} | 4 +- .../stRoom/dto/StudyMemberToDoRequestDto.java | 17 +++++++ 15 files changed, 145 insertions(+), 36 deletions(-) create mode 100644 src/main/java/mos/mosback/repository/MemberTodoRepository.java rename src/main/java/mos/mosback/stRoom/dto/{ToDoRequestDto.java => MemberToDoRequestDto.java} (74%) rename src/main/java/mos/mosback/stRoom/dto/{ToDoContentResponseDto.java => StRoomToDoResponseDto.java} (68%) create mode 100644 src/main/java/mos/mosback/stRoom/dto/StudyMemberToDoRequestDto.java diff --git a/src/main/java/mos/mosback/controller/StRoomController.java b/src/main/java/mos/mosback/controller/StRoomController.java index a4fbc4a..46207c1 100644 --- a/src/main/java/mos/mosback/controller/StRoomController.java +++ b/src/main/java/mos/mosback/controller/StRoomController.java @@ -135,17 +135,18 @@ public ResponseEntity getQuestionById(@PathVariable Long roomId) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); } } - @PostMapping("/memberjoin") - public ResponseEntity memberJoin(@RequestBody StRoomMemberJoinRequestDto requestDto) { + @PostMapping("/memberjoin/{roomId}") + public ResponseEntity memberJoin(@PathVariable Long roomId, + @RequestBody StRoomMemberJoinRequestDto requestDto) { // 현재 로그인한 사용자의 정보 가져오기 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String currentEmail = authentication.getName(); // 현재 사용자의 이메일 requestDto.setEmail(currentEmail); + requestDto.setRoomID(roomId); stRoomService.memberJoin(requestDto); return ResponseEntity.status(HttpStatus.CREATED).body("joined successfully."); } - @GetMapping("/recruiting") public ResponseEntity getRecruitingStudies() { List recruitingStudies = stRoomService.getRecruitingStudies(); @@ -162,6 +163,23 @@ public ResponseEntity getRecruitingStudies() { } } + /** + * 스터디 가입여부를 조회하는 API + * @return + */ + @GetMapping("/my-info") + public ResponseEntity> getMyInfo() throws Exception { + // 현재 로그인한 사용자의 정보 가져오기 + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + String email = authentication.getName(); // 현재 사용자의 이메일 + String joinYn = stRoomService.getMyInfo(email); + Map response = new HashMap<>(); + response.put("joinYn", joinYn); + response.put("success", true); + + return ResponseEntity.status(HttpStatus.CREATED).body(response); + } + } diff --git a/src/main/java/mos/mosback/controller/TodoController.java b/src/main/java/mos/mosback/controller/TodoController.java index 93598b4..22f4b35 100644 --- a/src/main/java/mos/mosback/controller/TodoController.java +++ b/src/main/java/mos/mosback/controller/TodoController.java @@ -1,12 +1,15 @@ package mos.mosback.controller; +import mos.mosback.domain.stRoom.StudyMemberTodoEntity; import mos.mosback.domain.stRoom.ToDoEntity; import mos.mosback.service.ToDoService; -import mos.mosback.stRoom.dto.ToDoRequestDto; +import mos.mosback.stRoom.dto.MemberToDoRequestDto; +import mos.mosback.stRoom.dto.StudyMemberToDoRequestDto; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; -import java.util.List; @RestController @RequestMapping("/todo") //URL 패턴 @@ -20,19 +23,26 @@ public TodoController(ToDoService toDoService) { } @PostMapping("/add") - public ResponseEntity addTodo(@RequestBody ToDoRequestDto requestDto) { - - ToDoEntity todo = toDoService.addTodo( - requestDto.getTodoContent()); - + public ResponseEntity addTodo(@RequestBody MemberToDoRequestDto requestDto) { + ToDoEntity todo = toDoService.addTodo(requestDto); return ResponseEntity.status(HttpStatus.CREATED).body("TodoList 추가 완료. index : " +todo.getTodoId()); } + @PostMapping("/member/add") + public ResponseEntity addMemberTodo(@RequestBody StudyMemberToDoRequestDto requestDto) throws Exception { + // 현재 로그인한 사용자의 정보 가져오기 + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + String currentEmail = authentication.getName(); // 현재 사용자의 이메일 + requestDto.setCurrentEmail(currentEmail); + StudyMemberTodoEntity todo = toDoService.addMemberTodo(requestDto); + return ResponseEntity.status(HttpStatus.CREATED).body("TodoList 추가 완료. index : " +todo.getMemberId()); + } + //todo개수만큼 프론트에서 호출해줘야함 - @PutMapping("/update/{todoId}") - public ResponseEntity updateTodo(@PathVariable Long todoId, @RequestBody ToDoRequestDto requestDto) { + @PutMapping("/{todoId}") + public ResponseEntity updateTodo(@PathVariable Long todoId, @RequestBody MemberToDoRequestDto requestDto) { try { ToDoEntity updatedToDo = toDoService.updateTodo(todoId, requestDto.getTodoContent()); return ResponseEntity.ok("ToDo 업데이트 완료. Index: " + todoId); @@ -42,7 +52,7 @@ public ResponseEntity updateTodo(@PathVariable Long todoId, @RequestBody } } - @DeleteMapping("/delete/{todoId}") + @DeleteMapping("/{todoId}") public ResponseEntity deleteTodo(@PathVariable Long todoId) { try { toDoService.deleteTodo(todoId); diff --git a/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java b/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java index eb58eef..2647530 100644 --- a/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java @@ -44,8 +44,6 @@ public class StRoomEntity extends BaseTimeEntity { @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) private List studyMemberEntities = new ArrayList<>(); - @OneToMany (fetch = FetchType.LAZY, cascade = CascadeType.ALL) - private List studyMemberTodoEntities = new ArrayList<>(); @Builder public StRoomEntity(String title, String goal, String rules, String quest, diff --git a/src/main/java/mos/mosback/domain/stRoom/StudyMemberEntity.java b/src/main/java/mos/mosback/domain/stRoom/StudyMemberEntity.java index 4fd9e34..61fa23d 100644 --- a/src/main/java/mos/mosback/domain/stRoom/StudyMemberEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/StudyMemberEntity.java @@ -1,5 +1,4 @@ package mos.mosback.domain.stRoom; -import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; diff --git a/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoEntity.java b/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoEntity.java index bf1c820..980382b 100644 --- a/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoEntity.java @@ -19,10 +19,15 @@ public class StudyMemberTodoEntity implements Serializable { @Column(name = "memberID") private Long memberId; + @Id + @Column + private String todoContent; + @ManyToOne @JoinColumn(name = "roomID") private StRoomEntity stRoom; + @Id @ManyToOne @JoinColumn(name = "todoId") private ToDoEntity toDoEntity; @@ -30,4 +35,7 @@ public class StudyMemberTodoEntity implements Serializable { // 다른 필드와 매핑 @Enumerated(EnumType.STRING) private TodoStatus status; + + private String day; // 사용자가 선택한 요일 + } \ No newline at end of file diff --git a/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java b/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java index 3acd0a9..ef24f61 100644 --- a/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java @@ -1,5 +1,4 @@ package mos.mosback.domain.stRoom; -import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -29,6 +28,6 @@ public void update(String todoContent) -// 스터디 방에 대한 Todo 정보를 담는 엔티티 +// 스터디 방에 대한 투두 정보를 담는 엔티티 } \ No newline at end of file diff --git a/src/main/java/mos/mosback/repository/MemberTodoRepository.java b/src/main/java/mos/mosback/repository/MemberTodoRepository.java new file mode 100644 index 0000000..8fd85ee --- /dev/null +++ b/src/main/java/mos/mosback/repository/MemberTodoRepository.java @@ -0,0 +1,10 @@ +package mos.mosback.repository; +import mos.mosback.domain.stRoom.StudyMemberTodoEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; + +public interface MemberTodoRepository extends JpaRepository { + +} diff --git a/src/main/java/mos/mosback/repository/StudyMemberRepository.java b/src/main/java/mos/mosback/repository/StudyMemberRepository.java index ae4637b..2e9eb44 100644 --- a/src/main/java/mos/mosback/repository/StudyMemberRepository.java +++ b/src/main/java/mos/mosback/repository/StudyMemberRepository.java @@ -3,6 +3,10 @@ import mos.mosback.domain.stRoom.StudyMemberEntity; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.List; + public interface StudyMemberRepository extends JpaRepository { + List findAllByMemberId(Long memberId); + } diff --git a/src/main/java/mos/mosback/repository/ToDoRepository.java b/src/main/java/mos/mosback/repository/ToDoRepository.java index 168ba7a..9f3132d 100644 --- a/src/main/java/mos/mosback/repository/ToDoRepository.java +++ b/src/main/java/mos/mosback/repository/ToDoRepository.java @@ -1,6 +1,5 @@ package mos.mosback.repository; import mos.mosback.domain.stRoom.ToDoEntity; -import mos.mosback.stRoom.dto.ToDoContentResponseDto; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; @@ -10,5 +9,4 @@ public interface ToDoRepository extends JpaRepository { @Query("SELECT t FROM ToDoEntity t ORDER BY t.todoId DESC") List findAllDesc(); //Todo리스트를 조회시 todoID를 기준으로 내림차순 정렬 - } diff --git a/src/main/java/mos/mosback/service/StRoomService.java b/src/main/java/mos/mosback/service/StRoomService.java index d052878..0c80ee0 100644 --- a/src/main/java/mos/mosback/service/StRoomService.java +++ b/src/main/java/mos/mosback/service/StRoomService.java @@ -60,7 +60,8 @@ public Long save(StRoomSaveRequestDto requestDto, HttpServletRequest req) { return null; } -} + } + @Transactional public void update(Long roomID, StRoomUpdateRequestDto requestDto) { StRoomEntity stroomEntity = stRoomRepository.findById(roomID) @@ -148,6 +149,7 @@ public void memberJoin(StRoomMemberJoinRequestDto requestDto) { e.printStackTrace(); } } + public List getRecruitingStudies() { LocalDateTime now = LocalDateTime.now(); @@ -157,14 +159,23 @@ public List getRecruitingStudies() { } public QuestionDto getQuestionById(Long roomId) { - StRoomEntity stRoomEntity = stRoomRepository.findById(roomId) - .orElseThrow(() -> new EntityNotFoundException("Room not found")); + StRoomEntity stRoomEntity = stRoomRepository.findById(roomId) + .orElseThrow(() -> new EntityNotFoundException("Room not found")); - QuestionDto responseDTO = new QuestionDto(); - responseDTO.setQuestion(stRoomEntity.getQuest()); + QuestionDto responseDTO = new QuestionDto(); + responseDTO.setQuestion(stRoomEntity.getQuest()); - return responseDTO; + return responseDTO; } + public String getMyInfo(String email) throws Exception { + // 3. 사용자 이메일 조회해서 save 전에 주입 + User user = userService.getUserByEmail(email); + + List memberJoinList = studyMemberRepository.findAllByMemberId(user.getId()); + + // study member 가입이력이 있다면 "Y" , 없으면 "N" + return !memberJoinList.isEmpty() ? "Y" : "N"; + } } \ No newline at end of file diff --git a/src/main/java/mos/mosback/service/ToDoService.java b/src/main/java/mos/mosback/service/ToDoService.java index d931493..2f7c2f0 100644 --- a/src/main/java/mos/mosback/service/ToDoService.java +++ b/src/main/java/mos/mosback/service/ToDoService.java @@ -1,13 +1,19 @@ package mos.mosback.service; import lombok.RequiredArgsConstructor; +import mos.mosback.domain.stRoom.StRoomEntity; +import mos.mosback.domain.stRoom.StudyMemberTodoEntity; import mos.mosback.domain.stRoom.ToDoEntity; +import mos.mosback.domain.stRoom.TodoStatus; +import mos.mosback.login.domain.user.User; +import mos.mosback.login.domain.user.service.UserService; +import mos.mosback.repository.MemberTodoRepository; +import mos.mosback.repository.StRoomRepository; import mos.mosback.repository.ToDoRepository; -import mos.mosback.stRoom.dto.ToDoContentResponseDto; +import mos.mosback.stRoom.dto.MemberToDoRequestDto; +import mos.mosback.stRoom.dto.StudyMemberToDoRequestDto; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.time.DayOfWeek; -import java.time.LocalDate; import java.util.List; @@ -16,10 +22,19 @@ public class ToDoService { private final ToDoRepository toDoRepository; + private final StRoomRepository stRoomRepository; + private final MemberTodoRepository studyMemberToDoRepository; + private final UserService userService; @Transactional - public ToDoEntity addTodo(String todoContent) { + public ToDoEntity addTodo(MemberToDoRequestDto requestDto) { ToDoEntity toDoEntity = new ToDoEntity(); + toDoEntity.setTodoContent(requestDto.getTodoContent()); + + StRoomEntity stRoomEntity = stRoomRepository.findById(requestDto.getRoomID()) + .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id =" + requestDto.getRoomID())); + + toDoEntity.setStRoom(stRoomEntity); return toDoRepository.save(toDoEntity); } @@ -40,4 +55,27 @@ public void deleteTodo(Long todoId) { toDoRepository.delete(toDoEntity); } + @Transactional + public void getTodo(Long todoId){ + ToDoEntity toDoEntity = toDoRepository.findById(todoId) + .orElseThrow(() -> new IllegalArgumentException("해당 ToDo를 찾을 수 없습니다.")); + + toDoRepository.findById(todoId); + + } + + public StudyMemberTodoEntity addMemberTodo(StudyMemberToDoRequestDto requestDto) throws Exception { + StudyMemberTodoEntity toDoEntity = new StudyMemberTodoEntity(); + toDoEntity.setTodoContent(requestDto.getTodoContent()); + + StRoomEntity stRoomEntity = stRoomRepository.findById(requestDto.getRoomID()) + .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id =" + requestDto.getRoomID())); + + // 2. 사용자 이메일 조회해서 save 전에 주입 + User user = userService.getUserByEmail(requestDto.getCurrentEmail()); + toDoEntity.setMemberId(user.getId()); + toDoEntity.setStatus(TodoStatus.Waiting); + toDoEntity.setStRoom(stRoomEntity); + return studyMemberToDoRepository.save(toDoEntity); + } } diff --git a/src/main/java/mos/mosback/stRoom/dto/ToDoRequestDto.java b/src/main/java/mos/mosback/stRoom/dto/MemberToDoRequestDto.java similarity index 74% rename from src/main/java/mos/mosback/stRoom/dto/ToDoRequestDto.java rename to src/main/java/mos/mosback/stRoom/dto/MemberToDoRequestDto.java index 804274a..395d2b9 100644 --- a/src/main/java/mos/mosback/stRoom/dto/ToDoRequestDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/MemberToDoRequestDto.java @@ -8,8 +8,8 @@ @Setter @Getter @NoArgsConstructor -public class ToDoRequestDto { - private String dayOfWeek; // 사용자가 선택한 요일 +public class MemberToDoRequestDto { private String todoContent; private boolean completed; // TodoLists 상태 ( 완료 - true, 미완료 - false) + private Long roomID; } \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomMemberJoinRequestDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomMemberJoinRequestDto.java index 24c1f64..67865fa 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomMemberJoinRequestDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomMemberJoinRequestDto.java @@ -11,5 +11,4 @@ public class StRoomMemberJoinRequestDto { private String answer; private String email; - -} //스터디 수정 시 생성 필드에 들어가는 내용수정 +} diff --git a/src/main/java/mos/mosback/stRoom/dto/ToDoContentResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomToDoResponseDto.java similarity index 68% rename from src/main/java/mos/mosback/stRoom/dto/ToDoContentResponseDto.java rename to src/main/java/mos/mosback/stRoom/dto/StRoomToDoResponseDto.java index ab8d194..8ff9e76 100644 --- a/src/main/java/mos/mosback/stRoom/dto/ToDoContentResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomToDoResponseDto.java @@ -3,10 +3,10 @@ import mos.mosback.domain.stRoom.ToDoEntity; @Getter -public class ToDoContentResponseDto { +public class StRoomToDoResponseDto { private String todoContent; - public ToDoContentResponseDto(ToDoEntity entity) { + public StRoomToDoResponseDto(ToDoEntity entity) { this.todoContent = entity.getTodoContent(); } } \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/dto/StudyMemberToDoRequestDto.java b/src/main/java/mos/mosback/stRoom/dto/StudyMemberToDoRequestDto.java new file mode 100644 index 0000000..fd6a097 --- /dev/null +++ b/src/main/java/mos/mosback/stRoom/dto/StudyMemberToDoRequestDto.java @@ -0,0 +1,17 @@ +package mos.mosback.stRoom.dto; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + + +@Setter +@Getter +@NoArgsConstructor +public class StudyMemberToDoRequestDto { + private String todoContent; + private boolean completed; // TodoLists 상태 ( 완료 - true, 미완료 - false) + private Long roomID; + private Long todoId; + private String currentEmail; +} \ No newline at end of file From 5ef3e4017ef362707bc31f556a20f39f0993ef5f Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Wed, 18 Oct 2023 22:43:55 +0900 Subject: [PATCH 35/60] =?UTF-8?q?Todo=20=EC=99=84=EC=84=B1,=20=EA=B0=80?= =?UTF-8?q?=EC=9E=85=EC=97=AC=EB=B6=80=20=ED=99=95=EC=9D=B8=20APi=20?= =?UTF-8?q?=EC=99=84=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/mos/mosback/domain/stRoom/StudyMemberTodoEntity.java | 2 +- .../java/mos/mosback/repository/MemberTodoRepository.java | 4 +--- src/main/java/mos/mosback/service/ToDoService.java | 1 + 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoEntity.java b/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoEntity.java index 980382b..83528d6 100644 --- a/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoEntity.java @@ -1,6 +1,5 @@ package mos.mosback.domain.stRoom; -import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -12,6 +11,7 @@ @Setter @NoArgsConstructor @Entity +@IdClass(StudyMemberTodoEntity.class) public class StudyMemberTodoEntity implements Serializable { @Id diff --git a/src/main/java/mos/mosback/repository/MemberTodoRepository.java b/src/main/java/mos/mosback/repository/MemberTodoRepository.java index 8fd85ee..b501648 100644 --- a/src/main/java/mos/mosback/repository/MemberTodoRepository.java +++ b/src/main/java/mos/mosback/repository/MemberTodoRepository.java @@ -1,10 +1,8 @@ package mos.mosback.repository; import mos.mosback.domain.stRoom.StudyMemberTodoEntity; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import java.util.List; -public interface MemberTodoRepository extends JpaRepository { +public interface MemberTodoRepository extends JpaRepository{ } diff --git a/src/main/java/mos/mosback/service/ToDoService.java b/src/main/java/mos/mosback/service/ToDoService.java index 2f7c2f0..44777dc 100644 --- a/src/main/java/mos/mosback/service/ToDoService.java +++ b/src/main/java/mos/mosback/service/ToDoService.java @@ -64,6 +64,7 @@ public void getTodo(Long todoId){ } + @Transactional public StudyMemberTodoEntity addMemberTodo(StudyMemberToDoRequestDto requestDto) throws Exception { StudyMemberTodoEntity toDoEntity = new StudyMemberTodoEntity(); toDoEntity.setTodoContent(requestDto.getTodoContent()); From da1dfc50bfa17f2f8bc735de21990d46b50d0ae0 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Thu, 19 Oct 2023 23:13:20 +0900 Subject: [PATCH 36/60] =?UTF-8?q?Todo=20=EC=88=98=EC=A0=95=EC=A4=91=20?= =?UTF-8?q?=EA=B0=80=EC=9E=85=EC=97=AC=EB=B6=80=20=ED=99=95=EC=9D=B8=20APi?= =?UTF-8?q?=20=EC=99=84=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/mos/mosback/controller/TodoController.java | 8 ++++---- .../domain/stRoom/StudyMemberTodoEntity.java | 1 - .../java/mos/mosback/domain/stRoom/ToDoEntity.java | 7 ++++++- .../mos/mosback/repository/StRoomRepository.java | 2 ++ .../java/mos/mosback/service/StRoomService.java | 3 +++ src/main/java/mos/mosback/service/ToDoService.java | 12 +++++------- .../mosback/stRoom/dto/Home_nickResponseDto.java | 13 ------------- .../mosback/stRoom/dto/StRoomDetailResponseDto.java | 5 ++--- .../mosback/stRoom/dto/StRoomToDoResponseDto.java | 3 +++ .../stRoom/dto/StudyMemberToDoRequestDto.java | 3 ++- ...oDoRequestDto.java => stRoomToDoRequestDto.java} | 7 ++++--- 11 files changed, 31 insertions(+), 33 deletions(-) delete mode 100644 src/main/java/mos/mosback/stRoom/dto/Home_nickResponseDto.java rename src/main/java/mos/mosback/stRoom/dto/{MemberToDoRequestDto.java => stRoomToDoRequestDto.java} (62%) diff --git a/src/main/java/mos/mosback/controller/TodoController.java b/src/main/java/mos/mosback/controller/TodoController.java index 22f4b35..af7f9b7 100644 --- a/src/main/java/mos/mosback/controller/TodoController.java +++ b/src/main/java/mos/mosback/controller/TodoController.java @@ -2,7 +2,7 @@ import mos.mosback.domain.stRoom.StudyMemberTodoEntity; import mos.mosback.domain.stRoom.ToDoEntity; import mos.mosback.service.ToDoService; -import mos.mosback.stRoom.dto.MemberToDoRequestDto; +import mos.mosback.stRoom.dto.stRoomToDoRequestDto; import mos.mosback.stRoom.dto.StudyMemberToDoRequestDto; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -23,7 +23,7 @@ public TodoController(ToDoService toDoService) { } @PostMapping("/add") - public ResponseEntity addTodo(@RequestBody MemberToDoRequestDto requestDto) { + public ResponseEntity addTodo(@RequestBody stRoomToDoRequestDto requestDto) { ToDoEntity todo = toDoService.addTodo(requestDto); return ResponseEntity.status(HttpStatus.CREATED).body("TodoList 추가 완료. index : " +todo.getTodoId()); } @@ -42,9 +42,9 @@ public ResponseEntity addMemberTodo(@RequestBody StudyMemberToDoRequestD @PutMapping("/{todoId}") - public ResponseEntity updateTodo(@PathVariable Long todoId, @RequestBody MemberToDoRequestDto requestDto) { + public ResponseEntity updateTodo(@PathVariable Long todoId, @RequestBody stRoomToDoRequestDto requestDto) { try { - ToDoEntity updatedToDo = toDoService.updateTodo(todoId, requestDto.getTodoContent()); + ToDoEntity updatedToDo = toDoService.updateTodo(todoId, requestDto.getTodoContent(),requestDto.getStatus()); return ResponseEntity.ok("ToDo 업데이트 완료. Index: " + todoId); } catch (IllegalArgumentException e) { return ResponseEntity.status(HttpStatus.NOT_FOUND) diff --git a/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoEntity.java b/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoEntity.java index 83528d6..21f0b43 100644 --- a/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoEntity.java @@ -36,6 +36,5 @@ public class StudyMemberTodoEntity implements Serializable { @Enumerated(EnumType.STRING) private TodoStatus status; - private String day; // 사용자가 선택한 요일 } \ No newline at end of file diff --git a/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java b/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java index ef24f61..f60fe64 100644 --- a/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java @@ -21,9 +21,14 @@ public class ToDoEntity extends BaseTimeEntity { @Column private String todoContent; - public void update(String todoContent) + @Enumerated(EnumType.STRING) + private TodoStatus status; + + public void update(String todoContent, TodoStatus status) { + this.todoContent = todoContent; + this.status = status; } diff --git a/src/main/java/mos/mosback/repository/StRoomRepository.java b/src/main/java/mos/mosback/repository/StRoomRepository.java index 7dcd15d..37b302f 100644 --- a/src/main/java/mos/mosback/repository/StRoomRepository.java +++ b/src/main/java/mos/mosback/repository/StRoomRepository.java @@ -29,4 +29,6 @@ public interface StRoomRepository extends JpaRepository { @Query("SELECT new mos.mosback.stRoom.dto.Home_RoomResponseDto(s) FROM StRoomEntity s WHERE s.startDate > current_timestamp") List findRecruitingStudies(); + + } \ No newline at end of file diff --git a/src/main/java/mos/mosback/service/StRoomService.java b/src/main/java/mos/mosback/service/StRoomService.java index 0c80ee0..3464361 100644 --- a/src/main/java/mos/mosback/service/StRoomService.java +++ b/src/main/java/mos/mosback/service/StRoomService.java @@ -178,4 +178,7 @@ public String getMyInfo(String email) throws Exception { // study member 가입이력이 있다면 "Y" , 없으면 "N" return !memberJoinList.isEmpty() ? "Y" : "N"; } + + + } \ No newline at end of file diff --git a/src/main/java/mos/mosback/service/ToDoService.java b/src/main/java/mos/mosback/service/ToDoService.java index 44777dc..b68c4f7 100644 --- a/src/main/java/mos/mosback/service/ToDoService.java +++ b/src/main/java/mos/mosback/service/ToDoService.java @@ -9,13 +9,11 @@ import mos.mosback.repository.MemberTodoRepository; import mos.mosback.repository.StRoomRepository; import mos.mosback.repository.ToDoRepository; -import mos.mosback.stRoom.dto.MemberToDoRequestDto; +import mos.mosback.stRoom.dto.stRoomToDoRequestDto; import mos.mosback.stRoom.dto.StudyMemberToDoRequestDto; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.List; - @RequiredArgsConstructor @Service @@ -27,10 +25,10 @@ public class ToDoService { private final UserService userService; @Transactional - public ToDoEntity addTodo(MemberToDoRequestDto requestDto) { + public ToDoEntity addTodo(stRoomToDoRequestDto requestDto) { ToDoEntity toDoEntity = new ToDoEntity(); toDoEntity.setTodoContent(requestDto.getTodoContent()); - + toDoEntity.setStatus(TodoStatus.Waiting); StRoomEntity stRoomEntity = stRoomRepository.findById(requestDto.getRoomID()) .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id =" + requestDto.getRoomID())); @@ -40,11 +38,11 @@ public ToDoEntity addTodo(MemberToDoRequestDto requestDto) { @Transactional - public ToDoEntity updateTodo(Long todoId, String todoContent) { + public ToDoEntity updateTodo(Long todoId, String todoContent,TodoStatus status) { ToDoEntity toDoEntity = toDoRepository.findById(todoId) .orElseThrow(() -> new IllegalArgumentException("해당 ToDo를 찾을 수 없습니다.")); - toDoEntity.update(todoContent); + toDoEntity.update(todoContent, status); return toDoEntity; } diff --git a/src/main/java/mos/mosback/stRoom/dto/Home_nickResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/Home_nickResponseDto.java deleted file mode 100644 index ab8e762..0000000 --- a/src/main/java/mos/mosback/stRoom/dto/Home_nickResponseDto.java +++ /dev/null @@ -1,13 +0,0 @@ -package mos.mosback.stRoom.dto; -import mos.mosback.login.domain.user.User; -import lombok.Getter; - - -@Getter -public class Home_nickResponseDto { - private String nickname; - - public Home_nickResponseDto(User entity) { - this.nickname = entity.getNickname(); - } -} \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java index 8d21b16..011bfb4 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java @@ -26,7 +26,6 @@ public class StRoomDetailResponseDto { private String goal; private String rules; private String intro; - //+스터디원 사진..리스트?? - //+웨이팅멤버 사진 - //+스터디 투두리스트 + //+스터디원 사진 + //+스터디룸 투두리스트 } diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomToDoResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomToDoResponseDto.java index 8ff9e76..da72bb1 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomToDoResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomToDoResponseDto.java @@ -1,12 +1,15 @@ package mos.mosback.stRoom.dto; import lombok.Getter; import mos.mosback.domain.stRoom.ToDoEntity; +import mos.mosback.domain.stRoom.TodoStatus; @Getter public class StRoomToDoResponseDto { private String todoContent; + private TodoStatus status; public StRoomToDoResponseDto(ToDoEntity entity) { this.todoContent = entity.getTodoContent(); + this.status=entity.getStatus(); } } \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/dto/StudyMemberToDoRequestDto.java b/src/main/java/mos/mosback/stRoom/dto/StudyMemberToDoRequestDto.java index fd6a097..4a58ba4 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StudyMemberToDoRequestDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StudyMemberToDoRequestDto.java @@ -3,6 +3,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import mos.mosback.domain.stRoom.TodoStatus; @Setter @@ -10,7 +11,7 @@ @NoArgsConstructor public class StudyMemberToDoRequestDto { private String todoContent; - private boolean completed; // TodoLists 상태 ( 완료 - true, 미완료 - false) + private TodoStatus status; private Long roomID; private Long todoId; private String currentEmail; diff --git a/src/main/java/mos/mosback/stRoom/dto/MemberToDoRequestDto.java b/src/main/java/mos/mosback/stRoom/dto/stRoomToDoRequestDto.java similarity index 62% rename from src/main/java/mos/mosback/stRoom/dto/MemberToDoRequestDto.java rename to src/main/java/mos/mosback/stRoom/dto/stRoomToDoRequestDto.java index 395d2b9..c68736b 100644 --- a/src/main/java/mos/mosback/stRoom/dto/MemberToDoRequestDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/stRoomToDoRequestDto.java @@ -1,15 +1,16 @@ package mos.mosback.stRoom.dto; - import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import mos.mosback.domain.stRoom.TodoStatus; @Setter @Getter @NoArgsConstructor -public class MemberToDoRequestDto { +public class stRoomToDoRequestDto { + private String todoContent; - private boolean completed; // TodoLists 상태 ( 완료 - true, 미완료 - false) + private TodoStatus status; private Long roomID; } \ No newline at end of file From 8dc19ac0f8a5de794deb55deb83d88b5a8ae9aae Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Sat, 21 Oct 2023 05:34:32 +0900 Subject: [PATCH 37/60] =?UTF-8?q?Todo=20=EC=88=98=EC=A0=95=EC=A4=91=20?= =?UTF-8?q?=EA=B0=80=EC=9E=85=EC=97=AC=EB=B6=80=20=ED=99=95=EC=9D=B8=20APi?= =?UTF-8?q?=20=EC=99=84=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mosback/controller/StRoomController.java | 33 +++++++++++-------- .../mosback/controller/TodoController.java | 12 +++---- .../mosback/domain/stRoom/StRoomEntity.java | 7 ++-- .../login/global/config/SecurityConfig.java | 6 ++-- .../mos/mosback/service/StRoomService.java | 2 -- .../java/mos/mosback/service/ToDoService.java | 8 ++--- .../stRoom/dto/Home_RoomResponseDto.java | 6 +++- .../stRoom/dto/StRoomDetailResponseDto.java | 4 +-- .../stRoom/dto/StRoomListResponseDto.java | 2 +- .../mosback/stRoom/dto/StRoomResponseDto.java | 2 +- .../stRoom/dto/StRoomSaveRequestDto.java | 4 +-- .../stRoom/dto/StRoomUpdateRequestDto.java | 4 +-- 12 files changed, 49 insertions(+), 41 deletions(-) diff --git a/src/main/java/mos/mosback/controller/StRoomController.java b/src/main/java/mos/mosback/controller/StRoomController.java index 46207c1..87c09c6 100644 --- a/src/main/java/mos/mosback/controller/StRoomController.java +++ b/src/main/java/mos/mosback/controller/StRoomController.java @@ -34,16 +34,20 @@ public ResponseEntity saveRoom(@RequestBody StRoomSaveRequestDto request requestDto.setEmail(currentEmail); Long stroomId = stRoomService.save(requestDto, req); if (stroomId != null) { - return ResponseEntity.status(HttpStatus.CREATED).body("created successfully. ID: " + stroomId); + return ResponseEntity.status(HttpStatus.CREATED).body + ("message: created successfully. ID:" + stroomId +"\nsuccess:true \nstatus:201"); } else { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Server error!"); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body + ("message: Bad Request \nsuccess:false \nstatus:400"); } } - @GetMapping("/MyStudy/{roomId}") + @GetMapping("/my{roomId}") public ResponseEntity FindByID (@PathVariable Long roomId) { - StRoomResponseDto stroom = stRoomService.findById(roomId); - return new ResponseEntity<>(stroom, HttpStatus.OK); + + StRoomResponseDto stroom = stRoomService.findById(roomId); + return new ResponseEntity<>(stroom, HttpStatus.OK); } + @GetMapping("/search") public ResponseEntity searchRoom(@RequestParam String keyword) { try { @@ -61,10 +65,11 @@ public ResponseEntity searchRoom(@RequestParam String keyword) { public ResponseEntity UpdateRoom(@PathVariable Long roomId, @RequestBody StRoomUpdateRequestDto requestDto) { try { stRoomService.update(roomId, requestDto); - return ResponseEntity.ok("updated."); + return ResponseEntity.ok + ("message: updated successfully. roomId:"+roomId+"\nsuccess:true\nstatus:200"); } catch (IllegalArgumentException e) { return ResponseEntity.status(HttpStatus.NOT_FOUND) - .body("NOT FOUND "+"'"+roomId+"'"); + .body("message: NOT FOUND "+"'"+roomId+"'"+"\nsuccess:false\nstatus:404"); } } @@ -86,9 +91,10 @@ public ResponseEntity> deleteRoom(@PathVariable Long roomId) } @GetMapping("/all") - public ResponseEntity> findAllRoomsDesc() { - List rooms = stRoomService.findAllRoomsDesc(); - return ResponseEntity.ok(rooms); + public ResponseEntity> findAllRoomsDesc(){ + + List rooms = stRoomService.findAllRoomsDesc(); + return ResponseEntity.ok(rooms); } @GetMapping("/popular") @@ -131,7 +137,7 @@ public ResponseEntity getQuestionById(@PathVariable Long roomId) { Map response = new HashMap<>(); response.put("status:", HttpStatus.NOT_FOUND.value()); response.put("success", false); - response.put("message", "NOT FOUND: Quest with roomID " + roomId); + response.put("message", "NOT FOUND"); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); } } @@ -144,7 +150,8 @@ public ResponseEntity memberJoin(@PathVariable Long roomId, requestDto.setEmail(currentEmail); requestDto.setRoomID(roomId); stRoomService.memberJoin(requestDto); - return ResponseEntity.status(HttpStatus.CREATED).body("joined successfully."); + return ResponseEntity.status(HttpStatus.CREATED).body + ("message : joined successfully.\nstatus : 201\n success: true"); } @GetMapping("/recruiting") @@ -157,7 +164,7 @@ public ResponseEntity getRecruitingStudies() { Map response = new HashMap<>(); response.put("status", HttpStatus.NOT_FOUND.value()); response.put("success", false); - response.put("message", "NOT FOUND: recruiting studyRoom "); + response.put("message", "NOT FOUND"); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); } diff --git a/src/main/java/mos/mosback/controller/TodoController.java b/src/main/java/mos/mosback/controller/TodoController.java index af7f9b7..ee6777f 100644 --- a/src/main/java/mos/mosback/controller/TodoController.java +++ b/src/main/java/mos/mosback/controller/TodoController.java @@ -22,12 +22,12 @@ public TodoController(ToDoService toDoService) { this.toDoService = toDoService; } - @PostMapping("/add") - public ResponseEntity addTodo(@RequestBody stRoomToDoRequestDto requestDto) { - ToDoEntity todo = toDoService.addTodo(requestDto); - return ResponseEntity.status(HttpStatus.CREATED).body("TodoList 추가 완료. index : " +todo.getTodoId()); + @PostMapping("/add/{roomID}") + public ResponseEntity addTodo(@RequestBody stRoomToDoRequestDto requestDto, @PathVariable Long roomID) { + ToDoEntity todo = toDoService.addTodo(requestDto, roomID); + return ResponseEntity.status(HttpStatus.CREATED).body + ("TodoList 추가 완료. index : " + todo.getTodoId()+"\nstatus:201\nsuccess:true"); } - @PostMapping("/member/add") public ResponseEntity addMemberTodo(@RequestBody StudyMemberToDoRequestDto requestDto) throws Exception { // 현재 로그인한 사용자의 정보 가져오기 @@ -45,7 +45,7 @@ public ResponseEntity addMemberTodo(@RequestBody StudyMemberToDoRequestD public ResponseEntity updateTodo(@PathVariable Long todoId, @RequestBody stRoomToDoRequestDto requestDto) { try { ToDoEntity updatedToDo = toDoService.updateTodo(todoId, requestDto.getTodoContent(),requestDto.getStatus()); - return ResponseEntity.ok("ToDo 업데이트 완료. Index: " + todoId); + return ResponseEntity.ok("ToDo 업데이트 완료. Index: " + todoId+"\nstatus:200\nsuccess:true"); } catch (IllegalArgumentException e) { return ResponseEntity.status(HttpStatus.NOT_FOUND) .body("NOT FOUND TODO"); diff --git a/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java b/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java index 2647530..d7fa5d5 100644 --- a/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java @@ -23,6 +23,7 @@ public class StRoomEntity extends BaseTimeEntity { @Column(nullable = false) private String goal; //스터디 목표 + @Column(nullable = false) private String rules; //스터디 규칙 private String quest; //생성 시 질문 private String category; // 스터디 카테고리 @@ -34,7 +35,7 @@ public class StRoomEntity extends BaseTimeEntity { private boolean onOff; //진행방식 (온오프) private String location; private int online; //온라인 - private Date startDate; //스터디 시작 날짜 + private LocalDate startDate; //스터디 시작 날짜 private LocalDate endDate; //스터디 끝나는 날짜 private boolean recruiting; //모집여부 @@ -49,7 +50,7 @@ public class StRoomEntity extends BaseTimeEntity { public StRoomEntity(String title, String goal, String rules, String quest, String category, String intro, int memberNum, int maxMember ,String mod, boolean onOff, String location,int online, - Date startDate, LocalDate endDate, List studyDayEntities + LocalDate startDate, LocalDate endDate, List studyDayEntities ) { this.title = title; this.goal = goal; @@ -72,7 +73,7 @@ public StRoomEntity(String title, String goal, String rules, String quest, public void update(String title, String goal, String rules, String quest, String category, String intro, int maxMember, - String mod, boolean onOff,String location,int online, Date startDate, + String mod, boolean onOff,String location,int online,LocalDate startDate, LocalDate endDate,List studyDayEntities) { this.title = title; this.goal = goal; diff --git a/src/main/java/mos/mosback/login/global/config/SecurityConfig.java b/src/main/java/mos/mosback/login/global/config/SecurityConfig.java index 05818a3..f47a815 100644 --- a/src/main/java/mos/mosback/login/global/config/SecurityConfig.java +++ b/src/main/java/mos/mosback/login/global/config/SecurityConfig.java @@ -62,9 +62,9 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { // 아이콘, css, js 관련 // 기본 페이지, css, image, js 하위 폴더에 있는 자료들은 모두 접근 가능, h2-console에 접근 가능 .antMatchers("/","/css/**","/images/**","/js/**","/favicon.ico","/h2-console/**").permitAll() - .antMatchers("/sign-up","/studyRoom/create","/studyRoom/create","/studyRoom/update/{roomID}","/studyRoom/{roomID}", - "/todo/add","/todo/update{todoId}","/todo/delete/{todoId}","/todo/{todoId}","/studyRoom/get/{roomID}", - "todo/{year}/{month}/{weekOfYear}/{dayOfWeek}", "/studyRoom/all","/studyRoom/search","/studyRoom/byCategory/{category}","/studyRoom/recruiting").permitAll() // 회원가입 접근 가능 + .antMatchers("/sign-up","/studyRoom/create","/studyRoom/update/{roomID}","/studyRoom/{roomID}", + "/todo/add","/todo/update{todoId}","/todo/delete/{todoId}","/todo/{todoId}" + , "/studyRoom/all","/studyRoom/search","/studyRoom/byCategory/{category}","/studyRoom/recruiting").permitAll() // 회원가입 접근 가능 .anyRequest().authenticated() // 위의 경로 이외에는 모두 인증된 사용자만 접근 가능 .and() //== 소셜 로그인 설정 ==// diff --git a/src/main/java/mos/mosback/service/StRoomService.java b/src/main/java/mos/mosback/service/StRoomService.java index 3464361..6f88458 100644 --- a/src/main/java/mos/mosback/service/StRoomService.java +++ b/src/main/java/mos/mosback/service/StRoomService.java @@ -5,7 +5,6 @@ import mos.mosback.domain.stRoom.StRoomEntity; import mos.mosback.domain.stRoom.StudyMemberEntity; import mos.mosback.login.domain.user.User; -import mos.mosback.login.domain.user.repository.UserRepository; import mos.mosback.login.domain.user.service.UserService; import mos.mosback.login.global.jwt.service.JwtService; import mos.mosback.repository.StRoomRepository; @@ -17,7 +16,6 @@ import javax.persistence.EntityNotFoundException; import javax.servlet.http.HttpServletRequest; -import javax.swing.text.html.Option; import java.time.LocalDateTime; import java.util.List; import java.util.Optional; diff --git a/src/main/java/mos/mosback/service/ToDoService.java b/src/main/java/mos/mosback/service/ToDoService.java index b68c4f7..b0ee386 100644 --- a/src/main/java/mos/mosback/service/ToDoService.java +++ b/src/main/java/mos/mosback/service/ToDoService.java @@ -25,12 +25,12 @@ public class ToDoService { private final UserService userService; @Transactional - public ToDoEntity addTodo(stRoomToDoRequestDto requestDto) { + public ToDoEntity addTodo(stRoomToDoRequestDto requestDto, Long roomID) { ToDoEntity toDoEntity = new ToDoEntity(); toDoEntity.setTodoContent(requestDto.getTodoContent()); toDoEntity.setStatus(TodoStatus.Waiting); - StRoomEntity stRoomEntity = stRoomRepository.findById(requestDto.getRoomID()) - .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id =" + requestDto.getRoomID())); + StRoomEntity stRoomEntity = stRoomRepository.findById(roomID) + .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id =" + roomID)); toDoEntity.setStRoom(stRoomEntity); return toDoRepository.save(toDoEntity); @@ -70,7 +70,7 @@ public StudyMemberTodoEntity addMemberTodo(StudyMemberToDoRequestDto requestDto) StRoomEntity stRoomEntity = stRoomRepository.findById(requestDto.getRoomID()) .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id =" + requestDto.getRoomID())); - // 2. 사용자 이메일 조회해서 save 전에 주입 + // 사용자 이메일 조회해서 save 전에 주입 User user = userService.getUserByEmail(requestDto.getCurrentEmail()); toDoEntity.setMemberId(user.getId()); toDoEntity.setStatus(TodoStatus.Waiting); diff --git a/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java index fe09f33..d7c9c1b 100644 --- a/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java @@ -1,6 +1,8 @@ package mos.mosback.stRoom.dto; import lombok.Getter; import mos.mosback.domain.stRoom.StRoomEntity; + +import java.time.LocalDate; import java.util.Date; @@ -13,13 +15,15 @@ public class Home_RoomResponseDto { private int maxMember; //모집 멤버수 private String location; //스터디장소 private int online; //온라인 - private Date startDate; //스터디 시작날짜 + private LocalDate startDate; //스터디 시작날짜 + private LocalDate endDate; //+ 유저프로필사진 public Home_RoomResponseDto(StRoomEntity entity) { this.title = entity.getTitle(); this.startDate = entity.getStartDate(); + this.endDate = entity.getEndDate(); this.location = entity.getLocation(); this.online = entity.getOnline(); this.category = entity.getCategory(); diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java index 011bfb4..c626060 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java @@ -11,10 +11,8 @@ public class StRoomDetailResponseDto { private String category; private boolean recruiting; private String location; - private Date startDate; + private LocalDate startDate; private LocalDate endDate; - private LocalDateTime createdDate; - private Date deadline; private int memberNum; //현재 멤버수 private int maxMember; //모집 멤버수 diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomListResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomListResponseDto.java index c2ffa89..4686679 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomListResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomListResponseDto.java @@ -22,7 +22,7 @@ public class StRoomListResponseDto { private String mod; //스터디 분위기 private int click;// 클릭횟수 (인기순 조회) private boolean onOff; //진행방식 (온오프) - private Date startDate; //스터디 시작 날짜 + private LocalDate startDate; //스터디 시작 날짜 private LocalDate endDate; //스터디 끝나는 날짜 private String location; private int online; //온라인 diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java index f5f2276..6aed56f 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java @@ -18,7 +18,7 @@ public class StRoomResponseDto { private int memberNum; //현재 멤버수 private String mod; //스터디 분위기 private boolean onOff; //진행방식 (온오프) - private Date startDate; //스터디 시작 날짜 + private LocalDate startDate; //스터디 시작 날짜 private LocalDate endDate; //스터디 끝나는 날짜 private List studyDayEntities; /*유저프로필 + 사진*/ diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomSaveRequestDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomSaveRequestDto.java index 578ff68..f8440b3 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomSaveRequestDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomSaveRequestDto.java @@ -26,7 +26,7 @@ public class StRoomSaveRequestDto { private boolean onOff; //진행방식 (온오프) private String location; //스터디 장소 private int online; // 온라인일 경우 1 : 줌 2 : 디코 3: 구글미트 4: 기타 - private Date startDate; //스터디 시작 날짜 + private LocalDate startDate; //스터디 시작 날짜 private LocalDate endDate; //스터디 끝나는 날짜 private String email; // 사용자 이메일 private List studyDayEntities; @@ -35,7 +35,7 @@ public class StRoomSaveRequestDto { @Builder public StRoomSaveRequestDto(String title, String goal, String rules, String quest, String category, String intro, int maxMember, String mod, boolean onOff,String location,int online, - Date startDate, LocalDate endDate,List studyDayEntities) { + LocalDate startDate, LocalDate endDate,List studyDayEntities) { this.title = title; this.goal = goal; this.rules = rules; diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomUpdateRequestDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomUpdateRequestDto.java index f52a260..0f16f00 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomUpdateRequestDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomUpdateRequestDto.java @@ -26,7 +26,7 @@ public class StRoomUpdateRequestDto { private String location; //스터디 장소 private int online; // 온라인일 경우 // 1 : 줌 2 : 디코 3: 구글미트 4: 기타 - private Date startDate; //스터디 시작 날짜 + private LocalDate startDate; //스터디 시작 날짜 private LocalDate endDate; //스터디 끝나는 날짜 private List studyDayEntities; @@ -34,7 +34,7 @@ public class StRoomUpdateRequestDto { @Builder public StRoomUpdateRequestDto(String title, String goal, String rules, String quest, String category, String intro, int maxMember ,String mod, boolean onOff,String location,int online, - Date startDate, LocalDate endDate, List studyDayEntities) { + LocalDate startDate, LocalDate endDate, List studyDayEntities) { this.title = title; this.goal = goal; this.rules = rules; From d8ffc4e3c31754c6715ff6b2a214d719da09e4d8 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Sat, 21 Oct 2023 20:23:30 +0900 Subject: [PATCH 38/60] =?UTF-8?q?=EB=82=98=EC=9D=98=20=EC=8A=A4=ED=84=B0?= =?UTF-8?q?=EB=94=94=20>=20Todo=20=EB=82=A0=EC=A7=9C=EC=84=B8=ED=8C=85=20,?= =?UTF-8?q?=20=EB=A9=A4=EB=B2=84=20=ED=88=AC=EB=91=90=20=ED=8F=89=EA=B7=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mosback/controller/TodoController.java | 96 ++++++++++++-- .../mosback/domain/stRoom/StRoomEntity.java | 2 + .../domain/stRoom/StudyMemberTodoEntity.java | 5 + .../domain/stRoom/StudyMemberTodoKey.java | 16 +++ .../repository/MemberTodoRepository.java | 17 ++- .../mosback/repository/ToDoRepository.java | 8 +- .../java/mos/mosback/service/ToDoService.java | 117 +++++++++++++++++- .../dto/StRoomMemberToDoResponseDto.java | 19 +++ .../stRoom/dto/StRoomToDoResponseDto.java | 4 + .../dto/StudyMemberRoomInfoResponseDto.java | 16 +++ .../mosback/stRoom/dto/StudyRoomDayDto.java | 12 ++ .../stRoom/dto/StudyRoomTodoInfoDto.java | 9 ++ 12 files changed, 304 insertions(+), 17 deletions(-) create mode 100644 src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoKey.java create mode 100644 src/main/java/mos/mosback/stRoom/dto/StRoomMemberToDoResponseDto.java create mode 100644 src/main/java/mos/mosback/stRoom/dto/StudyMemberRoomInfoResponseDto.java create mode 100644 src/main/java/mos/mosback/stRoom/dto/StudyRoomDayDto.java create mode 100644 src/main/java/mos/mosback/stRoom/dto/StudyRoomTodoInfoDto.java diff --git a/src/main/java/mos/mosback/controller/TodoController.java b/src/main/java/mos/mosback/controller/TodoController.java index ee6777f..08618e3 100644 --- a/src/main/java/mos/mosback/controller/TodoController.java +++ b/src/main/java/mos/mosback/controller/TodoController.java @@ -1,7 +1,10 @@ package mos.mosback.controller; import mos.mosback.domain.stRoom.StudyMemberTodoEntity; import mos.mosback.domain.stRoom.ToDoEntity; +import mos.mosback.login.domain.user.User; import mos.mosback.service.ToDoService; +import mos.mosback.stRoom.dto.StRoomToDoResponseDto; +import mos.mosback.stRoom.dto.StudyMemberRoomInfoResponseDto; import mos.mosback.stRoom.dto.stRoomToDoRequestDto; import mos.mosback.stRoom.dto.StudyMemberToDoRequestDto; import org.springframework.beans.factory.annotation.Autowired; @@ -10,6 +13,8 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; +import java.util.List; + @RestController @RequestMapping("/todo") //URL 패턴 @@ -24,11 +29,22 @@ public TodoController(ToDoService toDoService) { @PostMapping("/add/{roomID}") public ResponseEntity addTodo(@RequestBody stRoomToDoRequestDto requestDto, @PathVariable Long roomID) { - ToDoEntity todo = toDoService.addTodo(requestDto, roomID); - return ResponseEntity.status(HttpStatus.CREATED).body - ("TodoList 추가 완료. index : " + todo.getTodoId()+"\nstatus:201\nsuccess:true"); + try{ + ToDoEntity todo = toDoService.addTodo(requestDto, roomID); + return ResponseEntity.status(HttpStatus.CREATED).body + ("TodoList 추가 완료." + + "\ntodoIndex : " + todo.getTodoId()+"" + + "\nstatus:201" + + "\nsuccess:true"); + }catch(IllegalArgumentException ex) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body + ("TodoList 추가 실패" + + "\nstatus:404" + + "\nsuccess:false"); + } + } - @PostMapping("/member/add") + @PostMapping("/member/todo/add") public ResponseEntity addMemberTodo(@RequestBody StudyMemberToDoRequestDto requestDto) throws Exception { // 현재 로그인한 사용자의 정보 가져오기 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); @@ -45,10 +61,36 @@ public ResponseEntity addMemberTodo(@RequestBody StudyMemberToDoRequestD public ResponseEntity updateTodo(@PathVariable Long todoId, @RequestBody stRoomToDoRequestDto requestDto) { try { ToDoEntity updatedToDo = toDoService.updateTodo(todoId, requestDto.getTodoContent(),requestDto.getStatus()); - return ResponseEntity.ok("ToDo 업데이트 완료. Index: " + todoId+"\nstatus:200\nsuccess:true"); + return ResponseEntity.ok + ("ToDo 업데이트 완료. \nIndex: " + todoId+ + "\nstatus:200" + + "\nsuccess:true"); + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body("NOT FOUND TODO"+ + "\nstatus:401" + + "\nsuccess:false"); + } + } + + @PutMapping("/member/todo/{todoId}") + public ResponseEntity updateMemberTodo(@PathVariable Long todoId, + @RequestBody stRoomToDoRequestDto requestDto) throws Exception { + // 현재 로그인한 사용자의 정보 가져오기 + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + String currentEmail = authentication.getName(); // 현재 사용자의 이메일 + try { + StudyMemberTodoEntity updatedToDo = toDoService.updateMemberTodo(todoId, requestDto.getTodoContent(), + requestDto.getStatus(), currentEmail); + return ResponseEntity.ok + ("Study Member ToDo 업데이트 완료. \nIndex: " + todoId + + "\nstatus:200" + + "\nsuccess:true"); } catch (IllegalArgumentException e) { return ResponseEntity.status(HttpStatus.NOT_FOUND) - .body("NOT FOUND TODO"); + .body("NOT FOUND TODO"+ + "\nstatus:401" + + "\nsuccess:false"); } } @@ -56,12 +98,50 @@ public ResponseEntity updateTodo(@PathVariable Long todoId, @RequestBody public ResponseEntity deleteTodo(@PathVariable Long todoId) { try { toDoService.deleteTodo(todoId); - return ResponseEntity.ok("ToDo 삭제 완료. Index: " + todoId); + return ResponseEntity.ok + ("ToDo 삭제 완료. Index: " + todoId+ + "\nstatus:200" + + "\nsuccess:true"); } catch (IllegalArgumentException e) { return ResponseEntity.status(HttpStatus.NOT_FOUND) - .body("NOT FOUND TODO"); + .body("NOT FOUND TODO"+ + "\nstatus:401" + + "\nsuccess:false"); } } + @DeleteMapping("/member/todo/{todoId}") + public ResponseEntity deleteMemberTodo(@PathVariable Long todoId) throws Exception{ + // 현재 로그인한 사용자의 정보 가져오기 + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + String currentEmail = authentication.getName(); // 현재 사용자의 이메일 + try { + toDoService.deleteMemberTodo(todoId, currentEmail); + return ResponseEntity.ok + ("Study Member ToDo 삭제 완료. Index: " + todoId+ + "\nstatus:200" + + "\nsuccess:true"); + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body("NOT FOUND TODO"+ + "\nstatus:401" + + "\nsuccess:false"); + } + } + @GetMapping("/{roomId}") + public ResponseEntity> findStRoomTodoByRoomId(@PathVariable Long roomId) { + List todo = toDoService.findStRoomTodoByRoomId(roomId); + return new ResponseEntity<>(todo, HttpStatus.OK); + } + + + @GetMapping("/member/room/{roomId}") + public ResponseEntity getMemberRoomInfo(@PathVariable Long roomId) throws Exception { + // 현재 로그인한 사용자의 정보 가져오기 + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + String currentEmail = authentication.getName(); // 현재 사용자의 이메일 + StudyMemberRoomInfoResponseDto todo = toDoService.getMemberRoomInfo(roomId, currentEmail); + return new ResponseEntity<>(todo, HttpStatus.OK); + } } \ No newline at end of file diff --git a/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java b/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java index d7fa5d5..4cc94f1 100644 --- a/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java @@ -25,7 +25,9 @@ public class StRoomEntity extends BaseTimeEntity { private String goal; //스터디 목표 @Column(nullable = false) private String rules; //스터디 규칙 + @Column(nullable = false) private String quest; //생성 시 질문 + @Column(nullable = false) private String category; // 스터디 카테고리 private String intro; //스터디 소개 private int memberNum; //현재 멤버수 diff --git a/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoEntity.java b/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoEntity.java index 21f0b43..38d58af 100644 --- a/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoEntity.java @@ -37,4 +37,9 @@ public class StudyMemberTodoEntity implements Serializable { private TodoStatus status; + public void update(String todoContent, TodoStatus status) { + this.todoContent = todoContent; + this.status = status; + } + } \ No newline at end of file diff --git a/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoKey.java b/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoKey.java new file mode 100644 index 0000000..7b910ca --- /dev/null +++ b/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoKey.java @@ -0,0 +1,16 @@ +package mos.mosback.domain.stRoom; + +import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import javax.persistence.*; +import java.io.Serializable; + +@Data +public class StudyMemberTodoKey implements Serializable { + + private Long memberId; + private String todoContent; +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/repository/MemberTodoRepository.java b/src/main/java/mos/mosback/repository/MemberTodoRepository.java index b501648..91d13e4 100644 --- a/src/main/java/mos/mosback/repository/MemberTodoRepository.java +++ b/src/main/java/mos/mosback/repository/MemberTodoRepository.java @@ -1,8 +1,23 @@ package mos.mosback.repository; import mos.mosback.domain.stRoom.StudyMemberTodoEntity; +import mos.mosback.domain.stRoom.StudyMemberTodoKey; +import mos.mosback.stRoom.dto.StudyRoomTodoInfoDto; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import java.util.List; -public interface MemberTodoRepository extends JpaRepository{ +public interface MemberTodoRepository extends JpaRepository{ + + @Query(value = "SELECT * FROM STUDY_MEMBER_TODO_ENTITY WHERE roomID = :roomID AND memberId = :memberId", nativeQuery = true) + List findAllByStRoom(@Param("roomId") Long roomID, @Param("memberId") Long memberId); + + @Query(value = "SELECT * FROM (\n" + + "SELECT COUNT(*) AS totalCount FROM STUDY_MEMBER_TODO_ENTITY where roomID = :roomId \n" + + ") A, (\n" + + "SELECT COUNT(*) AS completedCount FROM STUDY_MEMBER_TODO_ENTITY where roomID = :roomId AND status = 'Completed'\n" + + ") B", nativeQuery = true) + StudyRoomTodoInfoDto getStudyRoomTodoAverage(@Param("roomId") Long roomId); } diff --git a/src/main/java/mos/mosback/repository/ToDoRepository.java b/src/main/java/mos/mosback/repository/ToDoRepository.java index 9f3132d..dbcdcd9 100644 --- a/src/main/java/mos/mosback/repository/ToDoRepository.java +++ b/src/main/java/mos/mosback/repository/ToDoRepository.java @@ -1,12 +1,16 @@ package mos.mosback.repository; import mos.mosback.domain.stRoom.ToDoEntity; +import mos.mosback.stRoom.dto.StRoomToDoResponseDto; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import java.util.List; public interface ToDoRepository extends JpaRepository { - @Query("SELECT t FROM ToDoEntity t ORDER BY t.todoId DESC") - List findAllDesc(); //Todo리스트를 조회시 todoID를 기준으로 내림차순 정렬 + @Query("SELECT t FROM ToDoEntity t ORDER BY t.todoId") + List findAllDesc(); + @Query("SELECT NEW mos.mosback.stRoom.dto.StRoomToDoResponseDto(t) FROM ToDoEntity t WHERE t.stRoom.roomID= :roomId ORDER BY t.todoId") + List findByStRoomId(@Param("roomId") Long roomId); } diff --git a/src/main/java/mos/mosback/service/ToDoService.java b/src/main/java/mos/mosback/service/ToDoService.java index b0ee386..8135b04 100644 --- a/src/main/java/mos/mosback/service/ToDoService.java +++ b/src/main/java/mos/mosback/service/ToDoService.java @@ -1,19 +1,20 @@ package mos.mosback.service; import lombok.RequiredArgsConstructor; -import mos.mosback.domain.stRoom.StRoomEntity; -import mos.mosback.domain.stRoom.StudyMemberTodoEntity; -import mos.mosback.domain.stRoom.ToDoEntity; -import mos.mosback.domain.stRoom.TodoStatus; +import mos.mosback.domain.stRoom.*; import mos.mosback.login.domain.user.User; import mos.mosback.login.domain.user.service.UserService; import mos.mosback.repository.MemberTodoRepository; import mos.mosback.repository.StRoomRepository; import mos.mosback.repository.ToDoRepository; -import mos.mosback.stRoom.dto.stRoomToDoRequestDto; -import mos.mosback.stRoom.dto.StudyMemberToDoRequestDto; +import mos.mosback.stRoom.dto.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + @RequiredArgsConstructor @Service @@ -46,6 +47,22 @@ public ToDoEntity updateTodo(Long todoId, String todoContent,TodoStatus status) return toDoEntity; } + + @Transactional + public StudyMemberTodoEntity updateMemberTodo(Long todoId, String todoContent,TodoStatus status, String currentEmail) throws Exception { + ToDoEntity toDoEntity = toDoRepository.findById(todoId) + .orElseThrow(() -> new IllegalArgumentException("해당 ToDo를 찾을 수 없습니다.")); + User user = userService.getUserByEmail(currentEmail); + StudyMemberTodoKey key = new StudyMemberTodoKey(); + key.setMemberId(user.getId()); + key.setTodoContent(toDoEntity.getTodoContent()); + StudyMemberTodoEntity studyMemberTodoEntity = studyMemberToDoRepository.findById(key) + .orElseThrow(() -> new IllegalArgumentException("해당 ToDo를 찾을 수 없습니다.")); + + studyMemberTodoEntity.update(todoContent, status); + return studyMemberTodoEntity; + } + @Transactional public void deleteTodo(Long todoId) { ToDoEntity toDoEntity = toDoRepository.findById(todoId) @@ -53,6 +70,20 @@ public void deleteTodo(Long todoId) { toDoRepository.delete(toDoEntity); } + + @Transactional + public void deleteMemberTodo(Long todoId, String currentEmail) throws Exception { + ToDoEntity toDoEntity = toDoRepository.findById(todoId) + .orElseThrow(() -> new IllegalArgumentException("해당 ToDo를 찾을 수 없습니다.")); + User user = userService.getUserByEmail(currentEmail); + StudyMemberTodoKey key = new StudyMemberTodoKey(); + key.setMemberId(user.getId()); + key.setTodoContent(toDoEntity.getTodoContent()); + StudyMemberTodoEntity studyMemberTodoEntity = studyMemberToDoRepository.findById(key) + .orElseThrow(() -> new IllegalArgumentException("해당 Study Member ToDo를 찾을 수 없습니다.")); + + studyMemberToDoRepository.delete(studyMemberTodoEntity); + } @Transactional public void getTodo(Long todoId){ ToDoEntity toDoEntity = toDoRepository.findById(todoId) @@ -62,6 +93,11 @@ public void getTodo(Long todoId){ } + @Transactional + public List findStRoomTodoByRoomId(Long roomId) { + return toDoRepository.findByStRoomId(roomId); + } + @Transactional public StudyMemberTodoEntity addMemberTodo(StudyMemberToDoRequestDto requestDto) throws Exception { StudyMemberTodoEntity toDoEntity = new StudyMemberTodoEntity(); @@ -77,4 +113,73 @@ public StudyMemberTodoEntity addMemberTodo(StudyMemberToDoRequestDto requestDto) toDoEntity.setStRoom(stRoomEntity); return studyMemberToDoRepository.save(toDoEntity); } + + public StudyMemberRoomInfoResponseDto getMemberRoomInfo(Long roomId, String currentEmail) throws Exception { + StudyMemberRoomInfoResponseDto result = new StudyMemberRoomInfoResponseDto(); + StRoomEntity stRoomEntity = stRoomRepository.findById(roomId) + .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id =" + roomId)); + + User user = userService.getUserByEmail(currentEmail); + + List todoEntityList = studyMemberToDoRepository.findAllByStRoom(roomId, user.getId()); + List todoList = new ArrayList<>(); + for (StudyMemberTodoEntity item : todoEntityList) { + todoList.add(new StRoomMemberToDoResponseDto(item)); + } + // 스터디 룸에 대한 현재 Todo 평균값 + + StudyRoomTodoInfoDto studyRoomTodoAverage = null; + double average = 0; + try { + studyRoomTodoAverage = studyMemberToDoRepository.getStudyRoomTodoAverage(roomId); + } catch (Exception e) { + e.printStackTrace(); + } + if (studyRoomTodoAverage != null) { + // DB에 데이터가 존재할 때에만 해당 로직 수행 + average = (studyRoomTodoAverage.getTotalCount() - studyRoomTodoAverage.getCompletedCount() + / (double) studyRoomTodoAverage.getTotalCount()) * 100; + } + List roomDayList = new ArrayList<>(); + Date now = new Date(); + + Calendar cal1 = Calendar.getInstance(); + + now = new Date(cal1.getTimeInMillis()); + + for (int i=0; i<7; i++) { + StudyRoomDayDto dayDto = new StudyRoomDayDto(); + dayDto.setDate(now); // 날짜 객체 셋팅 + dayDto.setDayVal(cal1.get(Calendar.DATE)); // 날짜 셋팅 + dayDto.setDayOfWeek(getDayOfKoreanWeek(cal1.get(Calendar.DAY_OF_WEEK))); // "월"~"일" 셋팅 + + cal1.add(Calendar.DATE, 1); // 일 계산 하루씩 추가 + } + + result.setTodoList(todoList); + result.setStudyRoomTodoAverage(average); // 평균값 + result.setRoomDayList(roomDayList); + + return result; + } + + private String getDayOfKoreanWeek(int i) { + if (i == 1) { + return "월"; + } else if (i == 2) { + return "화"; + } else if (i == 3) { + return "수"; + } else if (i == 4) { + return "목"; + } else if (i == 5) { + return "금"; + } else if (i == 6) { + return "토"; + } else if (i == 7) { + return "일"; + } else { + return ""; + } + } } diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomMemberToDoResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomMemberToDoResponseDto.java new file mode 100644 index 0000000..c6ea544 --- /dev/null +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomMemberToDoResponseDto.java @@ -0,0 +1,19 @@ +package mos.mosback.stRoom.dto; + +import lombok.Data; +import mos.mosback.domain.stRoom.StudyMemberTodoEntity; +import mos.mosback.domain.stRoom.TodoStatus; + +@Data +public class StRoomMemberToDoResponseDto { + private Long todoId; + private String todoContent; + private TodoStatus status; + + + public StRoomMemberToDoResponseDto (StudyMemberTodoEntity entity) { + this.todoId = entity.getToDoEntity().getTodoId(); + this.status = entity.getStatus(); + this.todoContent = entity.getTodoContent(); + } +} diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomToDoResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomToDoResponseDto.java index da72bb1..82146e8 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomToDoResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomToDoResponseDto.java @@ -1,9 +1,13 @@ package mos.mosback.stRoom.dto; import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; import mos.mosback.domain.stRoom.ToDoEntity; import mos.mosback.domain.stRoom.TodoStatus; +@Setter @Getter +@NoArgsConstructor public class StRoomToDoResponseDto { private String todoContent; private TodoStatus status; diff --git a/src/main/java/mos/mosback/stRoom/dto/StudyMemberRoomInfoResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StudyMemberRoomInfoResponseDto.java new file mode 100644 index 0000000..4b5ca79 --- /dev/null +++ b/src/main/java/mos/mosback/stRoom/dto/StudyMemberRoomInfoResponseDto.java @@ -0,0 +1,16 @@ +package mos.mosback.stRoom.dto; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import mos.mosback.domain.stRoom.StudyMemberTodoEntity; + +import java.util.List; + +@Setter +@Getter +@NoArgsConstructor +public class StudyMemberRoomInfoResponseDto { + private double studyRoomTodoAverage; // 평균값 + private List todoList; // 사용자 TODO 정보 + private List roomDayList; +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/dto/StudyRoomDayDto.java b/src/main/java/mos/mosback/stRoom/dto/StudyRoomDayDto.java new file mode 100644 index 0000000..5880a01 --- /dev/null +++ b/src/main/java/mos/mosback/stRoom/dto/StudyRoomDayDto.java @@ -0,0 +1,12 @@ +package mos.mosback.stRoom.dto; + +import lombok.Data; + +import java.util.Date; + +@Data +public class StudyRoomDayDto { + private Date date; // 날짜 Date 객체 + private String dayOfWeek; // "월" ~ "일" 값 + private int dayVal; // 날짜 값 +} diff --git a/src/main/java/mos/mosback/stRoom/dto/StudyRoomTodoInfoDto.java b/src/main/java/mos/mosback/stRoom/dto/StudyRoomTodoInfoDto.java new file mode 100644 index 0000000..08490a2 --- /dev/null +++ b/src/main/java/mos/mosback/stRoom/dto/StudyRoomTodoInfoDto.java @@ -0,0 +1,9 @@ +package mos.mosback.stRoom.dto; + +import lombok.Data; + +@Data +public class StudyRoomTodoInfoDto { + private int totalCount; + private int completedCount; +} From e9030c6bcb83fd879f48586fecb551032699f69b Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Sun, 22 Oct 2023 03:19:46 +0900 Subject: [PATCH 39/60] =?UTF-8?q?=EB=82=98=EC=9D=98=20=EC=8A=A4=ED=84=B0?= =?UTF-8?q?=EB=94=94=20>=20Todo=20=EB=82=A0=EC=A7=9C=EC=84=B8=ED=8C=85=20,?= =?UTF-8?q?=20=EB=A9=A4=EB=B2=84=20=ED=88=AC=EB=91=90=20crud,=20=ED=8F=89?= =?UTF-8?q?=EA=B7=A0/=20=EB=AA=A8=EC=A7=91=EC=97=AC=EB=B6=80=20/=20?= =?UTF-8?q?=EC=9D=B8=EA=B8=B0=EC=88=9C=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/mos/mosback/Application.java | 2 ++ .../mosback/controller/StRoomController.java | 20 ++++++++++++----- .../mosback/controller/TodoController.java | 17 +++++++------- .../mosback/domain/stRoom/StRoomEntity.java | 4 +++- .../login/global/config/SecurityConfig.java | 5 +++-- .../repository/MemberTodoRepository.java | 7 +++--- .../mosback/repository/StRoomRepository.java | 5 ++--- .../mos/mosback/service/StRoomService.java | 22 ++++++++++++------- .../java/mos/mosback/service/ToDoService.java | 4 +--- .../stRoom/dto/StudyMemberToDoRequestDto.java | 1 + 10 files changed, 52 insertions(+), 35 deletions(-) diff --git a/src/main/java/mos/mosback/Application.java b/src/main/java/mos/mosback/Application.java index 6248da1..08bec20 100644 --- a/src/main/java/mos/mosback/Application.java +++ b/src/main/java/mos/mosback/Application.java @@ -4,10 +4,12 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; @Slf4j @EnableJpaAuditing //JPA Auditing 활성화 @SpringBootApplication(exclude = {SecurityAutoConfiguration.class}) + public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); diff --git a/src/main/java/mos/mosback/controller/StRoomController.java b/src/main/java/mos/mosback/controller/StRoomController.java index 87c09c6..86a5c74 100644 --- a/src/main/java/mos/mosback/controller/StRoomController.java +++ b/src/main/java/mos/mosback/controller/StRoomController.java @@ -92,15 +92,14 @@ public ResponseEntity> deleteRoom(@PathVariable Long roomId) @GetMapping("/all") public ResponseEntity> findAllRoomsDesc(){ - - List rooms = stRoomService.findAllRoomsDesc(); + List rooms = stRoomService.findAllRoomsDesc(); return ResponseEntity.ok(rooms); } @GetMapping("/popular") - public ResponseEntity> getPopularRooms() { - List popularrooms = stRoomService.findPopularRoom(); - return new ResponseEntity<>(popularrooms, HttpStatus.OK); + public ResponseEntity> getPopularRooms() { + List rooms = stRoomService.findPopularRoom(); + return ResponseEntity.ok(rooms); } @GetMapping("/home/studyRoom") @@ -187,7 +186,16 @@ public ResponseEntity> getMyInfo() throws Exception { return ResponseEntity.status(HttpStatus.CREATED).body(response); } + @GetMapping("/recruitInfo/{roomId}") + public ResponseEntity> recruitInfo(@PathVariable Long roomId) { + String recruitInfo = stRoomService.isRecruiting(roomId); + Map response = new HashMap<>(); + response.put("모집", recruitInfo); + response.put("status", HttpStatus.OK.value()); + return ResponseEntity.status(HttpStatus.OK).body(response); + + } } @@ -205,4 +213,4 @@ public ResponseEntity> getMyInfo() throws Exception { ///byCategory/{category} : 카테고리별로 조회하는 엔프포인트 //https://blog.pumpkin-raccoon.com/115#:~:text=1%201.%20%EB%B3%B5%EC%88%98%20%3E%20%EB%8B%A8%EC%88%98%20REST%20API%EC%97%90%EC%84%9C%EB%8A%94%20post%2C,%EC%BB%AC%EB%A0%89%EC%85%98%20%ED%95%84%ED%84%B0%EB%A7%81%3A%20URL%20%EC%BF%BC%EB%A6%AC%20%3E%20%EC%83%88%EB%A1%9C%EC%9A%B4%20API%20 ///recruiting : 모집중인 게시물을 조회하는 엔드포인트. -// \ No newline at end of file +///my-info : 스터디 가입여부 조회 \ No newline at end of file diff --git a/src/main/java/mos/mosback/controller/TodoController.java b/src/main/java/mos/mosback/controller/TodoController.java index 08618e3..a21dbb6 100644 --- a/src/main/java/mos/mosback/controller/TodoController.java +++ b/src/main/java/mos/mosback/controller/TodoController.java @@ -17,7 +17,6 @@ @RestController -@RequestMapping("/todo") //URL 패턴 public class TodoController { private final ToDoService toDoService; @@ -27,13 +26,13 @@ public TodoController(ToDoService toDoService) { this.toDoService = toDoService; } - @PostMapping("/add/{roomID}") + @PostMapping("todo/add/{roomID}") public ResponseEntity addTodo(@RequestBody stRoomToDoRequestDto requestDto, @PathVariable Long roomID) { try{ ToDoEntity todo = toDoService.addTodo(requestDto, roomID); return ResponseEntity.status(HttpStatus.CREATED).body ("TodoList 추가 완료." + - "\ntodoIndex : " + todo.getTodoId()+"" + + "\ntodoIndex : " + todo.getTodoId() + "\nstatus:201" + "\nsuccess:true"); }catch(IllegalArgumentException ex) { @@ -45,7 +44,7 @@ public ResponseEntity addTodo(@RequestBody stRoomToDoRequestDto requestD } @PostMapping("/member/todo/add") - public ResponseEntity addMemberTodo(@RequestBody StudyMemberToDoRequestDto requestDto) throws Exception { + public ResponseEntity addMemberTodo(@RequestBody StudyMemberToDoRequestDto requestDto) throws Exception{ // 현재 로그인한 사용자의 정보 가져오기 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String currentEmail = authentication.getName(); // 현재 사용자의 이메일 @@ -54,10 +53,10 @@ public ResponseEntity addMemberTodo(@RequestBody StudyMemberToDoRequestD return ResponseEntity.status(HttpStatus.CREATED).body("TodoList 추가 완료. index : " +todo.getMemberId()); } //todo개수만큼 프론트에서 호출해줘야함 +// - - @PutMapping("/{todoId}") + @PutMapping("todo/{todoId}") public ResponseEntity updateTodo(@PathVariable Long todoId, @RequestBody stRoomToDoRequestDto requestDto) { try { ToDoEntity updatedToDo = toDoService.updateTodo(todoId, requestDto.getTodoContent(),requestDto.getStatus()); @@ -94,7 +93,7 @@ public ResponseEntity updateMemberTodo(@PathVariable Long todoId, } } - @DeleteMapping("/{todoId}") + @DeleteMapping("todo/{todoId}") public ResponseEntity deleteTodo(@PathVariable Long todoId) { try { toDoService.deleteTodo(todoId); @@ -129,7 +128,7 @@ public ResponseEntity deleteMemberTodo(@PathVariable Long todoId) throws } } - @GetMapping("/{roomId}") + @GetMapping("todo/{roomId}") public ResponseEntity> findStRoomTodoByRoomId(@PathVariable Long roomId) { List todo = toDoService.findStRoomTodoByRoomId(roomId); return new ResponseEntity<>(todo, HttpStatus.OK); @@ -144,4 +143,6 @@ public ResponseEntity getMemberRoomInfo(@PathVar StudyMemberRoomInfoResponseDto todo = toDoService.getMemberRoomInfo(roomId, currentEmail); return new ResponseEntity<>(todo, HttpStatus.OK); } + + } \ No newline at end of file diff --git a/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java b/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java index 4cc94f1..f30aa04 100644 --- a/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java +++ b/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java @@ -71,7 +71,6 @@ public StRoomEntity(String title, String goal, String rules, String quest, this.studyDayEntities = studyDayEntities; } - // 다른 필요한 Getter 및 Setter 메서드 public void update(String title, String goal, String rules, String quest, String category, String intro, int maxMember, @@ -92,4 +91,7 @@ public void update(String title, String goal, String rules, String quest, this.endDate = endDate; this.studyDayEntities = studyDayEntities; } + + + } \ No newline at end of file diff --git a/src/main/java/mos/mosback/login/global/config/SecurityConfig.java b/src/main/java/mos/mosback/login/global/config/SecurityConfig.java index f47a815..075bcc1 100644 --- a/src/main/java/mos/mosback/login/global/config/SecurityConfig.java +++ b/src/main/java/mos/mosback/login/global/config/SecurityConfig.java @@ -63,8 +63,9 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { // 기본 페이지, css, image, js 하위 폴더에 있는 자료들은 모두 접근 가능, h2-console에 접근 가능 .antMatchers("/","/css/**","/images/**","/js/**","/favicon.ico","/h2-console/**").permitAll() .antMatchers("/sign-up","/studyRoom/create","/studyRoom/update/{roomID}","/studyRoom/{roomID}", - "/todo/add","/todo/update{todoId}","/todo/delete/{todoId}","/todo/{todoId}" - , "/studyRoom/all","/studyRoom/search","/studyRoom/byCategory/{category}","/studyRoom/recruiting").permitAll() // 회원가입 접근 가능 + "/todo/add","/todo/update{todoId}","/todo/delete/{todoId}","/todo/{todoId}","/member/todo/add" + , "/studyRoom/all","/studyRoom/search","/studyRoom/byCategory/{category}","/studyRoom/recruiting", + "/recruitInfo/{roomId}").permitAll() // 회원가입 접근 가능 .anyRequest().authenticated() // 위의 경로 이외에는 모두 인증된 사용자만 접근 가능 .and() //== 소셜 로그인 설정 ==// diff --git a/src/main/java/mos/mosback/repository/MemberTodoRepository.java b/src/main/java/mos/mosback/repository/MemberTodoRepository.java index 91d13e4..c68a167 100644 --- a/src/main/java/mos/mosback/repository/MemberTodoRepository.java +++ b/src/main/java/mos/mosback/repository/MemberTodoRepository.java @@ -11,11 +11,10 @@ public interface MemberTodoRepository extends JpaRepository{ - @Query(value = "SELECT * FROM STUDY_MEMBER_TODO_ENTITY WHERE roomID = :roomID AND memberId = :memberId", nativeQuery = true) - List findAllByStRoom(@Param("roomId") Long roomID, @Param("memberId") Long memberId); - + @Query(value = "SELECT * FROM STUDY_MEMBER_TODO_ENTITY WHERE roomID = :roomId AND memberId = :memberId", nativeQuery = true) + List findAllByStRoom(@Param("roomId") Long roomId, @Param("memberId") Long memberId); @Query(value = "SELECT * FROM (\n" + - "SELECT COUNT(*) AS totalCount FROM STUDY_MEMBER_TODO_ENTITY where roomID = :roomId \n" + + "SELECT COUNT(*) AS totalCount FROM STU where roomID = :roomId \n" + ") A, (\n" + "SELECT COUNT(*) AS completedCount FROM STUDY_MEMBER_TODO_ENTITY where roomID = :roomId AND status = 'Completed'\n" + ") B", nativeQuery = true) diff --git a/src/main/java/mos/mosback/repository/StRoomRepository.java b/src/main/java/mos/mosback/repository/StRoomRepository.java index 37b302f..33d7418 100644 --- a/src/main/java/mos/mosback/repository/StRoomRepository.java +++ b/src/main/java/mos/mosback/repository/StRoomRepository.java @@ -14,9 +14,10 @@ public interface StRoomRepository extends JpaRepository { @Query("SELECT new mos.mosback.stRoom.dto.Home_RoomResponseDto(s) FROM StRoomEntity s ORDER BY s.roomID DESC") List findAllDesc(); - @Query("SELECT new mos.mosback.stRoom.dto.Home_RoomResponseDto(s) FROM StRoomEntity s WHERE s.title LIKE %:keyword%") + @Query("SELECT new mos.mosback.stRoom.dto.Home_RoomResponseDto(s) FROM StRoomEntity s WHERE s.title LIKE %:keyword% OR s.intro LIKE %:keyword%") List findByTitleContaining(@Param("keyword") String keyword);//키워드를 통해 스터디그룹을 검색 할 수 있다 + @Query(value = "SELECT new mos.mosback.stRoom.dto.Home_RoomResponseDto(s)FROM StRoomEntity s ORDER BY s.click DESC") List findPopularRoom(); @@ -29,6 +30,4 @@ public interface StRoomRepository extends JpaRepository { @Query("SELECT new mos.mosback.stRoom.dto.Home_RoomResponseDto(s) FROM StRoomEntity s WHERE s.startDate > current_timestamp") List findRecruitingStudies(); - - } \ No newline at end of file diff --git a/src/main/java/mos/mosback/service/StRoomService.java b/src/main/java/mos/mosback/service/StRoomService.java index 6f88458..44e3ab9 100644 --- a/src/main/java/mos/mosback/service/StRoomService.java +++ b/src/main/java/mos/mosback/service/StRoomService.java @@ -1,5 +1,4 @@ package mos.mosback.service; - import lombok.RequiredArgsConstructor; import mos.mosback.domain.stRoom.MemberStatus; import mos.mosback.domain.stRoom.StRoomEntity; @@ -16,10 +15,11 @@ import javax.persistence.EntityNotFoundException; import javax.servlet.http.HttpServletRequest; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.util.Date; import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; @RequiredArgsConstructor @@ -108,11 +108,8 @@ public List findByTitleContaining(String keyword) { @Transactional(readOnly = true) - public List findPopularRoom() { - List popularStrooms = stRoomRepository.findPopularRoom(); - return popularStrooms.stream() - .map(StRoomListResponseDto::new) - .collect(Collectors.toList()); + public List findPopularRoom() { + return stRoomRepository.findPopularRoom(); } @Transactional(readOnly = true) @@ -176,7 +173,16 @@ public String getMyInfo(String email) throws Exception { // study member 가입이력이 있다면 "Y" , 없으면 "N" return !memberJoinList.isEmpty() ? "Y" : "N"; } - + public String isRecruiting(Long roomID) { + Optional optionalRoom = stRoomRepository.findById(roomID); + StRoomEntity stRoom = optionalRoom.get(); + if (stRoom.getStartDate().isAfter(LocalDate.now())) { + stRoom.setRecruiting(true); + } else { + stRoom.setRecruiting(false); + } + return stRoom.isRecruiting() ? "true" : "false"; + } } \ No newline at end of file diff --git a/src/main/java/mos/mosback/service/ToDoService.java b/src/main/java/mos/mosback/service/ToDoService.java index 8135b04..e56c74f 100644 --- a/src/main/java/mos/mosback/service/ToDoService.java +++ b/src/main/java/mos/mosback/service/ToDoService.java @@ -98,19 +98,17 @@ public List findStRoomTodoByRoomId(Long roomId) { return toDoRepository.findByStRoomId(roomId); } - @Transactional public StudyMemberTodoEntity addMemberTodo(StudyMemberToDoRequestDto requestDto) throws Exception { StudyMemberTodoEntity toDoEntity = new StudyMemberTodoEntity(); toDoEntity.setTodoContent(requestDto.getTodoContent()); - StRoomEntity stRoomEntity = stRoomRepository.findById(requestDto.getRoomID()) .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id =" + requestDto.getRoomID())); - // 사용자 이메일 조회해서 save 전에 주입 User user = userService.getUserByEmail(requestDto.getCurrentEmail()); toDoEntity.setMemberId(user.getId()); toDoEntity.setStatus(TodoStatus.Waiting); toDoEntity.setStRoom(stRoomEntity); + return studyMemberToDoRepository.save(toDoEntity); } diff --git a/src/main/java/mos/mosback/stRoom/dto/StudyMemberToDoRequestDto.java b/src/main/java/mos/mosback/stRoom/dto/StudyMemberToDoRequestDto.java index 4a58ba4..8a23758 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StudyMemberToDoRequestDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StudyMemberToDoRequestDto.java @@ -15,4 +15,5 @@ public class StudyMemberToDoRequestDto { private Long roomID; private Long todoId; private String currentEmail; + } \ No newline at end of file From aafac1eeaec72366b9fca821c323bf1dd2671ba5 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Sun, 22 Oct 2023 14:08:17 +0900 Subject: [PATCH 40/60] =?UTF-8?q?=EB=82=98=EC=9D=98=20=EC=8A=A4=ED=84=B0?= =?UTF-8?q?=EB=94=94=20>=20Todo=20=EB=82=A0=EC=A7=9C=EC=84=B8=ED=8C=85=20,?= =?UTF-8?q?=20=EB=A9=A4=EB=B2=84=20=ED=88=AC=EB=91=90=20crud,=20=ED=8F=89?= =?UTF-8?q?=EA=B7=A0/=20=EB=AA=A8=EC=A7=91=EC=97=AC=EB=B6=80=20/=20?= =?UTF-8?q?=EC=9D=B8=EA=B8=B0=EC=88=9C=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mos/mosback/login/domain/user/User.java | 3 -- .../login/global/config/SecurityConfig.java | 2 +- .../controller/StRoomController.java | 8 ++-- .../controller/TodoController.java | 15 ++++---- .../domain/stRoom/BaseTimeEntity.java | 2 +- .../domain/stRoom/MemberStatus.java | 2 +- .../domain/stRoom/StRoomEntity.java | 4 +- .../domain/stRoom/StudyDaysEntity.java | 2 +- .../domain/stRoom/StudyMemberEntity.java | 4 +- .../domain/stRoom/StudyMemberTodoEntity.java | 4 +- .../domain/stRoom/StudyMemberTodoKey.java | 6 +-- .../domain/stRoom/ToDoEntity.java | 4 +- .../domain/stRoom/TodoStatus.java | 2 +- .../stRoom/dto/Home_RoomResponseDto.java | 3 +- .../mos/mosback/stRoom/dto/QuestionDto.java | 2 +- .../stRoom/dto/StRoomDetailResponseDto.java | 4 +- .../stRoom/dto/StRoomListResponseDto.java | 5 +-- .../dto/StRoomMemberJoinRequestDto.java | 2 +- .../dto/StRoomMemberToDoResponseDto.java | 4 +- .../mosback/stRoom/dto/StRoomResponseDto.java | 9 ++--- .../stRoom/dto/StRoomSaveRequestDto.java | 7 ++-- .../stRoom/dto/StRoomToDoResponseDto.java | 4 +- .../stRoom/dto/StRoomUpdateRequestDto.java | 5 +-- .../dto/StudyMemberRoomInfoResponseDto.java | 4 +- .../stRoom/dto/StudyMemberToDoRequestDto.java | 4 +- .../stRoom/dto/stRoomToDoRequestDto.java | 4 +- .../repository/MemberTodoRepository.java | 12 +++--- .../repository/StRoomRepository.java | 6 +-- .../repository/StudyMemberRepository.java | 4 +- .../repository/ToDoRepository.java | 6 +-- .../{ => stRoom}/service/StRoomService.java | 38 +++++++++---------- .../{ => stRoom}/service/ToDoService.java | 22 ++++++----- 32 files changed, 97 insertions(+), 106 deletions(-) rename src/main/java/mos/mosback/{ => stRoom}/controller/StRoomController.java (97%) rename src/main/java/mos/mosback/{ => stRoom}/controller/TodoController.java (95%) rename src/main/java/mos/mosback/{ => stRoom}/domain/stRoom/BaseTimeEntity.java (94%) rename src/main/java/mos/mosback/{ => stRoom}/domain/stRoom/MemberStatus.java (66%) rename src/main/java/mos/mosback/{ => stRoom}/domain/stRoom/StRoomEntity.java (98%) rename src/main/java/mos/mosback/{ => stRoom}/domain/stRoom/StudyDaysEntity.java (92%) rename src/main/java/mos/mosback/{ => stRoom}/domain/stRoom/StudyMemberEntity.java (88%) rename src/main/java/mos/mosback/{ => stRoom}/domain/stRoom/StudyMemberTodoEntity.java (91%) rename src/main/java/mos/mosback/{ => stRoom}/domain/stRoom/StudyMemberTodoKey.java (55%) rename src/main/java/mos/mosback/{ => stRoom}/domain/stRoom/ToDoEntity.java (91%) rename src/main/java/mos/mosback/{ => stRoom}/domain/stRoom/TodoStatus.java (56%) rename src/main/java/mos/mosback/{ => stRoom}/repository/MemberTodoRepository.java (69%) rename src/main/java/mos/mosback/{ => stRoom}/repository/StRoomRepository.java (91%) rename src/main/java/mos/mosback/{ => stRoom}/repository/StudyMemberRepository.java (71%) rename src/main/java/mos/mosback/{ => stRoom}/repository/ToDoRepository.java (78%) rename src/main/java/mos/mosback/{ => stRoom}/service/StRoomService.java (90%) rename src/main/java/mos/mosback/{ => stRoom}/service/ToDoService.java (92%) diff --git a/src/main/java/mos/mosback/login/domain/user/User.java b/src/main/java/mos/mosback/login/domain/user/User.java index 6a809c3..79c26a4 100644 --- a/src/main/java/mos/mosback/login/domain/user/User.java +++ b/src/main/java/mos/mosback/login/domain/user/User.java @@ -2,14 +2,11 @@ import lombok.*; -import mos.mosback.domain.stRoom.StRoomEntity; -import mos.mosback.domain.stRoom.StudyMemberEntity; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import javax.persistence.*; import java.util.Date; -import java.util.List; @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) diff --git a/src/main/java/mos/mosback/login/global/config/SecurityConfig.java b/src/main/java/mos/mosback/login/global/config/SecurityConfig.java index 075bcc1..b8c310c 100644 --- a/src/main/java/mos/mosback/login/global/config/SecurityConfig.java +++ b/src/main/java/mos/mosback/login/global/config/SecurityConfig.java @@ -62,7 +62,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { // 아이콘, css, js 관련 // 기본 페이지, css, image, js 하위 폴더에 있는 자료들은 모두 접근 가능, h2-console에 접근 가능 .antMatchers("/","/css/**","/images/**","/js/**","/favicon.ico","/h2-console/**").permitAll() - .antMatchers("/sign-up","/studyRoom/create","/studyRoom/update/{roomID}","/studyRoom/{roomID}", + .antMatchers("/sign-up","/studyRoom/create","/studyRoom/update/{roomId}","/studyRoom/{roomId}", "/todo/add","/todo/update{todoId}","/todo/delete/{todoId}","/todo/{todoId}","/member/todo/add" , "/studyRoom/all","/studyRoom/search","/studyRoom/byCategory/{category}","/studyRoom/recruiting", "/recruitInfo/{roomId}").permitAll() // 회원가입 접근 가능 diff --git a/src/main/java/mos/mosback/controller/StRoomController.java b/src/main/java/mos/mosback/stRoom/controller/StRoomController.java similarity index 97% rename from src/main/java/mos/mosback/controller/StRoomController.java rename to src/main/java/mos/mosback/stRoom/controller/StRoomController.java index 86a5c74..0807b3c 100644 --- a/src/main/java/mos/mosback/controller/StRoomController.java +++ b/src/main/java/mos/mosback/stRoom/controller/StRoomController.java @@ -1,7 +1,9 @@ -package mos.mosback.controller; +package mos.mosback.stRoom.controller; import mos.mosback.stRoom.dto.*; -import mos.mosback.service.StRoomService; +import mos.mosback.stRoom.service.StRoomService; +import mos.mosback.stduy.dto.*; +import mos.mosback.study.dto.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -202,7 +204,7 @@ public ResponseEntity> recruitInfo(@PathVariable Long roomId //핸들러 메서드 : //create: 새 게시물을 생성 -///MyStudy/{roomId}: 특정 roomID에 해당하는 게시물을 조회( 스터디그룹 -마이스터디화면 조회 ) +///MyStudy/{roomId}: 특정 roomId에 해당하는 게시물을 조회( 스터디그룹 -마이스터디화면 조회 ) //search: 제목에 키워드가 포함된 게시물을 검색하는 엔드포인트. ///update/{roomId}: 게시물 수정 ///(Delete) {roomId}: 게시물을 삭제 diff --git a/src/main/java/mos/mosback/controller/TodoController.java b/src/main/java/mos/mosback/stRoom/controller/TodoController.java similarity index 95% rename from src/main/java/mos/mosback/controller/TodoController.java rename to src/main/java/mos/mosback/stRoom/controller/TodoController.java index a21dbb6..466f101 100644 --- a/src/main/java/mos/mosback/controller/TodoController.java +++ b/src/main/java/mos/mosback/stRoom/controller/TodoController.java @@ -1,8 +1,7 @@ -package mos.mosback.controller; -import mos.mosback.domain.stRoom.StudyMemberTodoEntity; -import mos.mosback.domain.stRoom.ToDoEntity; -import mos.mosback.login.domain.user.User; -import mos.mosback.service.ToDoService; +package mos.mosback.stRoom.controller; +import mos.mosback.stRoom.domain.stRoom.StudyMemberTodoEntity; +import mos.mosback.stRoom.domain.stRoom.ToDoEntity; +import mos.mosback.stRoom.service.ToDoService; import mos.mosback.stRoom.dto.StRoomToDoResponseDto; import mos.mosback.stRoom.dto.StudyMemberRoomInfoResponseDto; import mos.mosback.stRoom.dto.stRoomToDoRequestDto; @@ -26,10 +25,10 @@ public TodoController(ToDoService toDoService) { this.toDoService = toDoService; } - @PostMapping("todo/add/{roomID}") - public ResponseEntity addTodo(@RequestBody stRoomToDoRequestDto requestDto, @PathVariable Long roomID) { + @PostMapping("todo/add/{roomId}") + public ResponseEntity addTodo(@RequestBody stRoomToDoRequestDto requestDto, @PathVariable Long roomId) { try{ - ToDoEntity todo = toDoService.addTodo(requestDto, roomID); + ToDoEntity todo = toDoService.addTodo(requestDto, roomId); return ResponseEntity.status(HttpStatus.CREATED).body ("TodoList 추가 완료." + "\ntodoIndex : " + todo.getTodoId() + diff --git a/src/main/java/mos/mosback/domain/stRoom/BaseTimeEntity.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/BaseTimeEntity.java similarity index 94% rename from src/main/java/mos/mosback/domain/stRoom/BaseTimeEntity.java rename to src/main/java/mos/mosback/stRoom/domain/stRoom/BaseTimeEntity.java index 2d79ac1..69db1d5 100644 --- a/src/main/java/mos/mosback/domain/stRoom/BaseTimeEntity.java +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/BaseTimeEntity.java @@ -1,4 +1,4 @@ -package mos.mosback.domain.stRoom; +package mos.mosback.stRoom.domain.stRoom; import lombok.Getter; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; diff --git a/src/main/java/mos/mosback/domain/stRoom/MemberStatus.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/MemberStatus.java similarity index 66% rename from src/main/java/mos/mosback/domain/stRoom/MemberStatus.java rename to src/main/java/mos/mosback/stRoom/domain/stRoom/MemberStatus.java index bf66868..be50f57 100644 --- a/src/main/java/mos/mosback/domain/stRoom/MemberStatus.java +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/MemberStatus.java @@ -1,4 +1,4 @@ -package mos.mosback.domain.stRoom; +package mos.mosback.stRoom.domain.stRoom; public enum MemberStatus { Leader, diff --git a/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomEntity.java similarity index 98% rename from src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java rename to src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomEntity.java index f30aa04..ea09ee5 100644 --- a/src/main/java/mos/mosback/domain/stRoom/StRoomEntity.java +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomEntity.java @@ -1,4 +1,4 @@ -package mos.mosback.domain.stRoom; +package mos.mosback.stRoom.domain.stRoom; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -16,7 +16,7 @@ public class StRoomEntity extends BaseTimeEntity { @Id //해당 테이블 PK 필드 나타냄 @GeneratedValue(strategy = GenerationType.IDENTITY) //PK 생성규칙 나타냄 스프링 2.0은 //GenerationType.IDENTITY 옵션을 추가해야만 auto_increment가 된다. - private Long roomID; + private Long roomId; //웬만하면 Entity의 Pk는 long타입의 auto_increment 쓰는게 좋음 @Column(length = 500, nullable = false) private String title; diff --git a/src/main/java/mos/mosback/domain/stRoom/StudyDaysEntity.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyDaysEntity.java similarity index 92% rename from src/main/java/mos/mosback/domain/stRoom/StudyDaysEntity.java rename to src/main/java/mos/mosback/stRoom/domain/stRoom/StudyDaysEntity.java index 63ae223..e4be36d 100644 --- a/src/main/java/mos/mosback/domain/stRoom/StudyDaysEntity.java +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyDaysEntity.java @@ -1,4 +1,4 @@ -package mos.mosback.domain.stRoom; +package mos.mosback.stRoom.domain.stRoom; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/src/main/java/mos/mosback/domain/stRoom/StudyMemberEntity.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberEntity.java similarity index 88% rename from src/main/java/mos/mosback/domain/stRoom/StudyMemberEntity.java rename to src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberEntity.java index 61fa23d..438a2a0 100644 --- a/src/main/java/mos/mosback/domain/stRoom/StudyMemberEntity.java +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberEntity.java @@ -1,4 +1,4 @@ -package mos.mosback.domain.stRoom; +package mos.mosback.stRoom.domain.stRoom; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -18,7 +18,7 @@ public class StudyMemberEntity implements Serializable { private Long memberId; @ManyToOne - @JoinColumn(name = "roomID") + @JoinColumn(name = "roomId") private StRoomEntity stRoom; // 다른 필드와 매핑 diff --git a/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoEntity.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberTodoEntity.java similarity index 91% rename from src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoEntity.java rename to src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberTodoEntity.java index 38d58af..ef39a20 100644 --- a/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoEntity.java +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberTodoEntity.java @@ -1,4 +1,4 @@ -package mos.mosback.domain.stRoom; +package mos.mosback.stRoom.domain.stRoom; import lombok.Getter; import lombok.NoArgsConstructor; @@ -24,7 +24,7 @@ public class StudyMemberTodoEntity implements Serializable { private String todoContent; @ManyToOne - @JoinColumn(name = "roomID") + @JoinColumn(name = "roomId") private StRoomEntity stRoom; @Id diff --git a/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoKey.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberTodoKey.java similarity index 55% rename from src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoKey.java rename to src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberTodoKey.java index 7b910ca..39b14dd 100644 --- a/src/main/java/mos/mosback/domain/stRoom/StudyMemberTodoKey.java +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberTodoKey.java @@ -1,11 +1,7 @@ -package mos.mosback.domain.stRoom; +package mos.mosback.stRoom.domain.stRoom; import lombok.Data; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import javax.persistence.*; import java.io.Serializable; @Data diff --git a/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/ToDoEntity.java similarity index 91% rename from src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java rename to src/main/java/mos/mosback/stRoom/domain/stRoom/ToDoEntity.java index f60fe64..9b89e43 100644 --- a/src/main/java/mos/mosback/domain/stRoom/ToDoEntity.java +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/ToDoEntity.java @@ -1,4 +1,4 @@ -package mos.mosback.domain.stRoom; +package mos.mosback.stRoom.domain.stRoom; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -15,7 +15,7 @@ public class ToDoEntity extends BaseTimeEntity { private Long todoId; @ManyToOne - @JoinColumn(name = "roomID") + @JoinColumn(name = "roomId") private StRoomEntity stRoom; @Column diff --git a/src/main/java/mos/mosback/domain/stRoom/TodoStatus.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/TodoStatus.java similarity index 56% rename from src/main/java/mos/mosback/domain/stRoom/TodoStatus.java rename to src/main/java/mos/mosback/stRoom/domain/stRoom/TodoStatus.java index 636e2b8..0e49f2e 100644 --- a/src/main/java/mos/mosback/domain/stRoom/TodoStatus.java +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/TodoStatus.java @@ -1,4 +1,4 @@ -package mos.mosback.domain.stRoom; +package mos.mosback.stRoom.domain.stRoom; public enum TodoStatus { Waiting, diff --git a/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java index d7c9c1b..ee426b8 100644 --- a/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java @@ -1,9 +1,8 @@ package mos.mosback.stRoom.dto; import lombok.Getter; -import mos.mosback.domain.stRoom.StRoomEntity; +import mos.mosback.stRoom.domain.stRoom.StRoomEntity; import java.time.LocalDate; -import java.util.Date; @Getter diff --git a/src/main/java/mos/mosback/stRoom/dto/QuestionDto.java b/src/main/java/mos/mosback/stRoom/dto/QuestionDto.java index ae53937..70a5928 100644 --- a/src/main/java/mos/mosback/stRoom/dto/QuestionDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/QuestionDto.java @@ -1,7 +1,7 @@ package mos.mosback.stRoom.dto; import lombok.NoArgsConstructor; import lombok.Setter; -import mos.mosback.domain.stRoom.StRoomEntity; +import mos.mosback.stRoom.domain.stRoom.StRoomEntity; import lombok.Getter; @Setter diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java index c626060..b665da7 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java @@ -1,9 +1,7 @@ package mos.mosback.stRoom.dto; -import mos.mosback.domain.stRoom.StudyDaysEntity; +import mos.mosback.stRoom.domain.stRoom.StudyDaysEntity; import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.Date; import java.util.List; public class StRoomDetailResponseDto { diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomListResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomListResponseDto.java index 4686679..7138047 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomListResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomListResponseDto.java @@ -1,10 +1,9 @@ package mos.mosback.stRoom.dto; import lombok.Getter; -import mos.mosback.domain.stRoom.StRoomEntity; -import mos.mosback.domain.stRoom.StudyDaysEntity; +import mos.mosback.stRoom.domain.stRoom.StRoomEntity; +import mos.mosback.stRoom.domain.stRoom.StudyDaysEntity; import java.time.LocalDate; -import java.util.Date; import java.util.List; diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomMemberJoinRequestDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomMemberJoinRequestDto.java index 67865fa..c79d16b 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomMemberJoinRequestDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomMemberJoinRequestDto.java @@ -7,7 +7,7 @@ @Getter @NoArgsConstructor public class StRoomMemberJoinRequestDto { - private Long roomID; + private Long roomId; private String answer; private String email; diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomMemberToDoResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomMemberToDoResponseDto.java index c6ea544..8367ab6 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomMemberToDoResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomMemberToDoResponseDto.java @@ -1,8 +1,8 @@ package mos.mosback.stRoom.dto; import lombok.Data; -import mos.mosback.domain.stRoom.StudyMemberTodoEntity; -import mos.mosback.domain.stRoom.TodoStatus; +import mos.mosback.stRoom.domain.stRoom.StudyMemberTodoEntity; +import mos.mosback.stRoom.domain.stRoom.TodoStatus; @Data public class StRoomMemberToDoResponseDto { diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java index 6aed56f..5880cb4 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java @@ -1,16 +1,15 @@ package mos.mosback.stRoom.dto; import lombok.Getter; -import mos.mosback.domain.stRoom.StRoomEntity; -import mos.mosback.domain.stRoom.StudyDaysEntity; +import mos.mosback.stRoom.domain.stRoom.StRoomEntity; +import mos.mosback.stRoom.domain.stRoom.StudyDaysEntity; import java.time.LocalDate; -import java.util.Date; import java.util.List; @Getter public class StRoomResponseDto { - Long roomID; + Long roomId; private String title; private String goal; //스터디 목표 private String rules; //스터디 규칙 @@ -26,7 +25,7 @@ public class StRoomResponseDto { public StRoomResponseDto(StRoomEntity entity) { - this.roomID = entity.getRoomID(); + this.roomId = entity.getRoomID(); this.title = entity.getTitle(); this.goal = entity.getGoal(); this.rules = entity.getRules(); diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomSaveRequestDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomSaveRequestDto.java index f8440b3..f84e7bb 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomSaveRequestDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomSaveRequestDto.java @@ -3,18 +3,17 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import mos.mosback.domain.stRoom.StRoomEntity; -import mos.mosback.domain.stRoom.StudyDaysEntity; +import mos.mosback.stRoom.domain.stRoom.StRoomEntity; +import mos.mosback.stRoom.domain.stRoom.StudyDaysEntity; import java.time.LocalDate; -import java.util.Date; import java.util.List; @Getter @Setter @NoArgsConstructor public class StRoomSaveRequestDto { - Long roomID; + Long roomId; private String title; private String goal; //스터디 목표 private String rules; //스터디 규칙 diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomToDoResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomToDoResponseDto.java index 82146e8..8cd2b17 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomToDoResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomToDoResponseDto.java @@ -2,8 +2,8 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import mos.mosback.domain.stRoom.ToDoEntity; -import mos.mosback.domain.stRoom.TodoStatus; +import mos.mosback.stRoom.domain.stRoom.ToDoEntity; +import mos.mosback.stRoom.domain.stRoom.TodoStatus; @Setter @Getter diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomUpdateRequestDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomUpdateRequestDto.java index 0f16f00..6e78b10 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomUpdateRequestDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomUpdateRequestDto.java @@ -2,10 +2,9 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import mos.mosback.domain.stRoom.StudyDaysEntity; +import mos.mosback.stRoom.domain.stRoom.StudyDaysEntity; import java.time.LocalDate; -import java.util.Date; import java.util.List; @@ -13,7 +12,7 @@ @NoArgsConstructor public class StRoomUpdateRequestDto { - Long roomID; + Long roomId; private String title; private String goal; //스터디 목표 private String rules; //스터디 규칙 diff --git a/src/main/java/mos/mosback/stRoom/dto/StudyMemberRoomInfoResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StudyMemberRoomInfoResponseDto.java index 4b5ca79..1614fc7 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StudyMemberRoomInfoResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StudyMemberRoomInfoResponseDto.java @@ -2,7 +2,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import mos.mosback.domain.stRoom.StudyMemberTodoEntity; + import java.util.List; @@ -11,6 +11,6 @@ @NoArgsConstructor public class StudyMemberRoomInfoResponseDto { private double studyRoomTodoAverage; // 평균값 - private List todoList; // 사용자 TODO 정보 + private List todoList; // 사용자 투두정보 private List roomDayList; } \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/dto/StudyMemberToDoRequestDto.java b/src/main/java/mos/mosback/stRoom/dto/StudyMemberToDoRequestDto.java index 8a23758..afa67bc 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StudyMemberToDoRequestDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StudyMemberToDoRequestDto.java @@ -3,7 +3,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import mos.mosback.domain.stRoom.TodoStatus; +import mos.mosback.stRoom.domain.stRoom.TodoStatus; @Setter @@ -12,7 +12,7 @@ public class StudyMemberToDoRequestDto { private String todoContent; private TodoStatus status; - private Long roomID; + private Long roomId; private Long todoId; private String currentEmail; diff --git a/src/main/java/mos/mosback/stRoom/dto/stRoomToDoRequestDto.java b/src/main/java/mos/mosback/stRoom/dto/stRoomToDoRequestDto.java index c68736b..4d4a6c4 100644 --- a/src/main/java/mos/mosback/stRoom/dto/stRoomToDoRequestDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/stRoomToDoRequestDto.java @@ -2,7 +2,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import mos.mosback.domain.stRoom.TodoStatus; +import mos.mosback.stRoom.domain.stRoom.TodoStatus; @Setter @@ -12,5 +12,5 @@ public class stRoomToDoRequestDto { private String todoContent; private TodoStatus status; - private Long roomID; + private Long roomId; } \ No newline at end of file diff --git a/src/main/java/mos/mosback/repository/MemberTodoRepository.java b/src/main/java/mos/mosback/stRoom/repository/MemberTodoRepository.java similarity index 69% rename from src/main/java/mos/mosback/repository/MemberTodoRepository.java rename to src/main/java/mos/mosback/stRoom/repository/MemberTodoRepository.java index c68a167..38f008d 100644 --- a/src/main/java/mos/mosback/repository/MemberTodoRepository.java +++ b/src/main/java/mos/mosback/stRoom/repository/MemberTodoRepository.java @@ -1,6 +1,6 @@ -package mos.mosback.repository; -import mos.mosback.domain.stRoom.StudyMemberTodoEntity; -import mos.mosback.domain.stRoom.StudyMemberTodoKey; +package mos.mosback.stRoom.repository; +import mos.mosback.stRoom.domain.stRoom.StudyMemberTodoEntity; +import mos.mosback.stRoom.domain.stRoom.StudyMemberTodoKey; import mos.mosback.stRoom.dto.StudyRoomTodoInfoDto; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; @@ -11,12 +11,12 @@ public interface MemberTodoRepository extends JpaRepository{ - @Query(value = "SELECT * FROM STUDY_MEMBER_TODO_ENTITY WHERE roomID = :roomId AND memberId = :memberId", nativeQuery = true) + @Query(value = "SELECT * FROM STUDY_MEMBER_TODO_ENTITY WHERE roomId = :roomId AND memberId = :memberId", nativeQuery = true) List findAllByStRoom(@Param("roomId") Long roomId, @Param("memberId") Long memberId); @Query(value = "SELECT * FROM (\n" + - "SELECT COUNT(*) AS totalCount FROM STU where roomID = :roomId \n" + + "SELECT COUNT(*) AS totalCount FROM STU where roomId = :roomId \n" + ") A, (\n" + - "SELECT COUNT(*) AS completedCount FROM STUDY_MEMBER_TODO_ENTITY where roomID = :roomId AND status = 'Completed'\n" + + "SELECT COUNT(*) AS completedCount FROM STUDY_MEMBER_TODO_ENTITY where roomId = :roomId AND status = 'Completed'\n" + ") B", nativeQuery = true) StudyRoomTodoInfoDto getStudyRoomTodoAverage(@Param("roomId") Long roomId); } diff --git a/src/main/java/mos/mosback/repository/StRoomRepository.java b/src/main/java/mos/mosback/stRoom/repository/StRoomRepository.java similarity index 91% rename from src/main/java/mos/mosback/repository/StRoomRepository.java rename to src/main/java/mos/mosback/stRoom/repository/StRoomRepository.java index 33d7418..4af0708 100644 --- a/src/main/java/mos/mosback/repository/StRoomRepository.java +++ b/src/main/java/mos/mosback/stRoom/repository/StRoomRepository.java @@ -1,7 +1,7 @@ -package mos.mosback.repository; +package mos.mosback.stRoom.repository; //Entity 클래스와 Entity레파지토리 위치 같아야함 -import mos.mosback.domain.stRoom.StRoomEntity; +import mos.mosback.stRoom.domain.stRoom.StRoomEntity; import mos.mosback.stRoom.dto.Home_RoomResponseDto; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; @@ -11,7 +11,7 @@ //인터페이스 생성 후 JpaRepository를 상속하면 기본적인 CRUD 메소드 자동으로 생성됨 public interface StRoomRepository extends JpaRepository { - @Query("SELECT new mos.mosback.stRoom.dto.Home_RoomResponseDto(s) FROM StRoomEntity s ORDER BY s.roomID DESC") + @Query("SELECT new mos.mosback.stRoom.dto.Home_RoomResponseDto(s) FROM StRoomEntity s ORDER BY s.roomId DESC") List findAllDesc(); @Query("SELECT new mos.mosback.stRoom.dto.Home_RoomResponseDto(s) FROM StRoomEntity s WHERE s.title LIKE %:keyword% OR s.intro LIKE %:keyword%") diff --git a/src/main/java/mos/mosback/repository/StudyMemberRepository.java b/src/main/java/mos/mosback/stRoom/repository/StudyMemberRepository.java similarity index 71% rename from src/main/java/mos/mosback/repository/StudyMemberRepository.java rename to src/main/java/mos/mosback/stRoom/repository/StudyMemberRepository.java index 2e9eb44..1e34935 100644 --- a/src/main/java/mos/mosback/repository/StudyMemberRepository.java +++ b/src/main/java/mos/mosback/stRoom/repository/StudyMemberRepository.java @@ -1,6 +1,6 @@ -package mos.mosback.repository; +package mos.mosback.stRoom.repository; -import mos.mosback.domain.stRoom.StudyMemberEntity; +import mos.mosback.stRoom.domain.stRoom.StudyMemberEntity; import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; diff --git a/src/main/java/mos/mosback/repository/ToDoRepository.java b/src/main/java/mos/mosback/stRoom/repository/ToDoRepository.java similarity index 78% rename from src/main/java/mos/mosback/repository/ToDoRepository.java rename to src/main/java/mos/mosback/stRoom/repository/ToDoRepository.java index dbcdcd9..83e1ecf 100644 --- a/src/main/java/mos/mosback/repository/ToDoRepository.java +++ b/src/main/java/mos/mosback/stRoom/repository/ToDoRepository.java @@ -1,5 +1,5 @@ -package mos.mosback.repository; -import mos.mosback.domain.stRoom.ToDoEntity; +package mos.mosback.stRoom.repository; +import mos.mosback.stRoom.domain.stRoom.ToDoEntity; import mos.mosback.stRoom.dto.StRoomToDoResponseDto; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; @@ -11,6 +11,6 @@ public interface ToDoRepository extends JpaRepository { @Query("SELECT t FROM ToDoEntity t ORDER BY t.todoId") List findAllDesc(); - @Query("SELECT NEW mos.mosback.stRoom.dto.StRoomToDoResponseDto(t) FROM ToDoEntity t WHERE t.stRoom.roomID= :roomId ORDER BY t.todoId") + @Query("SELECT NEW mos.mosback.stRoom.dto.StRoomToDoResponseDto(t) FROM ToDoEntity t WHERE t.stRoom.roomId= :roomId ORDER BY t.todoId") List findByStRoomId(@Param("roomId") Long roomId); } diff --git a/src/main/java/mos/mosback/service/StRoomService.java b/src/main/java/mos/mosback/stRoom/service/StRoomService.java similarity index 90% rename from src/main/java/mos/mosback/service/StRoomService.java rename to src/main/java/mos/mosback/stRoom/service/StRoomService.java index 44e3ab9..034343b 100644 --- a/src/main/java/mos/mosback/service/StRoomService.java +++ b/src/main/java/mos/mosback/stRoom/service/StRoomService.java @@ -1,14 +1,15 @@ -package mos.mosback.service; +package mos.mosback.stRoom.service; import lombok.RequiredArgsConstructor; -import mos.mosback.domain.stRoom.MemberStatus; -import mos.mosback.domain.stRoom.StRoomEntity; -import mos.mosback.domain.stRoom.StudyMemberEntity; +import mos.mosback.stRoom.domain.stRoom.MemberStatus; +import mos.mosback.stRoom.domain.stRoom.StRoomEntity; +import mos.mosback.stRoom.domain.stRoom.StudyMemberEntity; import mos.mosback.login.domain.user.User; import mos.mosback.login.domain.user.service.UserService; import mos.mosback.login.global.jwt.service.JwtService; -import mos.mosback.repository.StRoomRepository; -import mos.mosback.repository.StudyMemberRepository; -import mos.mosback.stRoom.dto.StRoomSaveRequestDto; +import mos.mosback.stRoom.repository.StRoomRepository; +import mos.mosback.stRoom.repository.StudyMemberRepository; +import mos.mosback.stduy.dto.*; +import mos.mosback.study.dto.*; import mos.mosback.stRoom.dto.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -17,7 +18,6 @@ import javax.servlet.http.HttpServletRequest; import java.time.LocalDate; import java.time.LocalDateTime; -import java.util.Date; import java.util.List; import java.util.Optional; @@ -61,9 +61,9 @@ public Long save(StRoomSaveRequestDto requestDto, HttpServletRequest req) { } @Transactional - public void update(Long roomID, StRoomUpdateRequestDto requestDto) { - StRoomEntity stroomEntity = stRoomRepository.findById(roomID) - .orElseThrow(() -> new IllegalArgumentException(roomID + " NOT FOUND")); + public void update(Long roomId, StRoomUpdateRequestDto requestDto) { + StRoomEntity stroomEntity = stRoomRepository.findById(roomId) + .orElseThrow(() -> new IllegalArgumentException(roomId + " NOT FOUND")); // 나머지 필드 업데이트 stroomEntity.update( @@ -79,9 +79,9 @@ public void update(Long roomID, StRoomUpdateRequestDto requestDto) { @Transactional(readOnly = true) - public StRoomResponseDto findById(Long roomID) { - StRoomEntity stRoomEntity = stRoomRepository.findById(roomID) - .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id=" + roomID)); + public StRoomResponseDto findById(Long roomId) { + StRoomEntity stRoomEntity = stRoomRepository.findById(roomId) + .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id=" + roomId)); return new StRoomResponseDto(stRoomEntity); } @@ -91,9 +91,9 @@ public List findAllRoomsDesc() { } @Transactional - public void delete(Long roomID) { - StRoomEntity stroomEntity = stRoomRepository.findById(roomID) - .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id =" + roomID)); + public void delete(Long roomId) { + StRoomEntity stroomEntity = stRoomRepository.findById(roomId) + .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id =" + roomId)); stRoomRepository.delete(stroomEntity); //JpaRepository 에서 이미 delete 메소드를 지원하고 있으므로 활용 //엔티티를 파라미터로 살제할 수도 있고, deleteById 메서드를 이용하면 id로 삭제할 수 있음 @@ -173,8 +173,8 @@ public String getMyInfo(String email) throws Exception { // study member 가입이력이 있다면 "Y" , 없으면 "N" return !memberJoinList.isEmpty() ? "Y" : "N"; } - public String isRecruiting(Long roomID) { - Optional optionalRoom = stRoomRepository.findById(roomID); + public String isRecruiting(Long roomId) { + Optional optionalRoom = stRoomRepository.findById(roomId); StRoomEntity stRoom = optionalRoom.get(); if (stRoom.getStartDate().isAfter(LocalDate.now())) { stRoom.setRecruiting(true); diff --git a/src/main/java/mos/mosback/service/ToDoService.java b/src/main/java/mos/mosback/stRoom/service/ToDoService.java similarity index 92% rename from src/main/java/mos/mosback/service/ToDoService.java rename to src/main/java/mos/mosback/stRoom/service/ToDoService.java index e56c74f..f36f208 100644 --- a/src/main/java/mos/mosback/service/ToDoService.java +++ b/src/main/java/mos/mosback/stRoom/service/ToDoService.java @@ -1,12 +1,16 @@ -package mos.mosback.service; +package mos.mosback.stRoom.service; import lombok.RequiredArgsConstructor; import mos.mosback.domain.stRoom.*; import mos.mosback.login.domain.user.User; import mos.mosback.login.domain.user.service.UserService; -import mos.mosback.repository.MemberTodoRepository; -import mos.mosback.repository.StRoomRepository; -import mos.mosback.repository.ToDoRepository; +import mos.mosback.stRoom.domain.stRoom.*; +import mos.mosback.stRoom.repository.MemberTodoRepository; +import mos.mosback.stRoom.repository.StRoomRepository; +import mos.mosback.stRoom.repository.ToDoRepository; import mos.mosback.stRoom.dto.*; +import mos.mosback.stRoom.Entity.*; +import mos.mosback.stduy.dto.*; +import mos.mosback.study.dto.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -26,12 +30,12 @@ public class ToDoService { private final UserService userService; @Transactional - public ToDoEntity addTodo(stRoomToDoRequestDto requestDto, Long roomID) { + public ToDoEntity addTodo(stRoomToDoRequestDto requestDto, Long roomId) { ToDoEntity toDoEntity = new ToDoEntity(); toDoEntity.setTodoContent(requestDto.getTodoContent()); toDoEntity.setStatus(TodoStatus.Waiting); - StRoomEntity stRoomEntity = stRoomRepository.findById(roomID) - .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id =" + roomID)); + StRoomEntity stRoomEntity = stRoomRepository.findById(roomId) + .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id =" + roomId)); toDoEntity.setStRoom(stRoomEntity); return toDoRepository.save(toDoEntity); @@ -49,7 +53,7 @@ public ToDoEntity updateTodo(Long todoId, String todoContent,TodoStatus status) @Transactional - public StudyMemberTodoEntity updateMemberTodo(Long todoId, String todoContent,TodoStatus status, String currentEmail) throws Exception { + public StudyMemberTodoEntity updateMemberTodo(Long todoId, String todoContent, TodoStatus status, String currentEmail) throws Exception { ToDoEntity toDoEntity = toDoRepository.findById(todoId) .orElseThrow(() -> new IllegalArgumentException("해당 ToDo를 찾을 수 없습니다.")); User user = userService.getUserByEmail(currentEmail); @@ -124,7 +128,7 @@ public StudyMemberRoomInfoResponseDto getMemberRoomInfo(Long roomId, String curr for (StudyMemberTodoEntity item : todoEntityList) { todoList.add(new StRoomMemberToDoResponseDto(item)); } - // 스터디 룸에 대한 현재 Todo 평균값 + // 스터디 룸에 대한 현재 투두평균값 StudyRoomTodoInfoDto studyRoomTodoAverage = null; double average = 0; From 8b2d0b5d1288048f8ef87e1c5fb2de3d4d3502d9 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Sun, 22 Oct 2023 14:32:33 +0900 Subject: [PATCH 41/60] =?UTF-8?q?=EB=82=98=EC=9D=98=20=EC=8A=A4=ED=84=B0?= =?UTF-8?q?=EB=94=94=20>=20Todo=20=EB=82=A0=EC=A7=9C=EC=84=B8=ED=8C=85=20,?= =?UTF-8?q?=20=EB=A9=A4=EB=B2=84=20=ED=88=AC=EB=91=90=20crud,=20=ED=8F=89?= =?UTF-8?q?=EA=B7=A0/=20=EB=AA=A8=EC=A7=91=EC=97=AC=EB=B6=80=20/=20?= =?UTF-8?q?=EC=9D=B8=EA=B8=B0=EC=88=9C=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mosback/stRoom/controller/StRoomController.java | 4 +--- .../java/mos/mosback/stRoom/dto/StRoomResponseDto.java | 2 +- .../java/mos/mosback/stRoom/service/StRoomService.java | 8 +++----- .../java/mos/mosback/stRoom/service/ToDoService.java | 10 +++------- 4 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/main/java/mos/mosback/stRoom/controller/StRoomController.java b/src/main/java/mos/mosback/stRoom/controller/StRoomController.java index 0807b3c..f56150e 100644 --- a/src/main/java/mos/mosback/stRoom/controller/StRoomController.java +++ b/src/main/java/mos/mosback/stRoom/controller/StRoomController.java @@ -2,8 +2,6 @@ import mos.mosback.stRoom.dto.*; import mos.mosback.stRoom.service.StRoomService; -import mos.mosback.stduy.dto.*; -import mos.mosback.study.dto.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -149,7 +147,7 @@ public ResponseEntity memberJoin(@PathVariable Long roomId, Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String currentEmail = authentication.getName(); // 현재 사용자의 이메일 requestDto.setEmail(currentEmail); - requestDto.setRoomID(roomId); + requestDto.setRoomId(roomId); stRoomService.memberJoin(requestDto); return ResponseEntity.status(HttpStatus.CREATED).body ("message : joined successfully.\nstatus : 201\n success: true"); diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java index 5880cb4..2bbb6fc 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java @@ -25,7 +25,7 @@ public class StRoomResponseDto { public StRoomResponseDto(StRoomEntity entity) { - this.roomId = entity.getRoomID(); + this.roomId = entity.getRoomId(); this.title = entity.getTitle(); this.goal = entity.getGoal(); this.rules = entity.getRules(); diff --git a/src/main/java/mos/mosback/stRoom/service/StRoomService.java b/src/main/java/mos/mosback/stRoom/service/StRoomService.java index 034343b..7ecfd7e 100644 --- a/src/main/java/mos/mosback/stRoom/service/StRoomService.java +++ b/src/main/java/mos/mosback/stRoom/service/StRoomService.java @@ -8,8 +8,6 @@ import mos.mosback.login.global.jwt.service.JwtService; import mos.mosback.stRoom.repository.StRoomRepository; import mos.mosback.stRoom.repository.StudyMemberRepository; -import mos.mosback.stduy.dto.*; -import mos.mosback.study.dto.*; import mos.mosback.stRoom.dto.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -52,7 +50,7 @@ public Long save(StRoomSaveRequestDto requestDto, HttpServletRequest req) { studyMember.setStRoom(stRoom); studyMember.setStatus(MemberStatus.Leader); studyMemberRepository.save(studyMember); - return stRoom.getRoomID(); + return stRoom.getRoomId(); } catch (Exception e) { e.printStackTrace(); return null; @@ -128,8 +126,8 @@ public void memberJoin(StRoomMemberJoinRequestDto requestDto) { StudyMemberEntity studyMember = new StudyMemberEntity(); // 2. 가입 시에는 룸ID를 요청 파라미터에서 받아서 StRoom 조회 - StRoomEntity stRoomEntity = stRoomRepository.findById(requestDto.getRoomID()) - .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id =" + requestDto.getRoomID())); + StRoomEntity stRoomEntity = stRoomRepository.findById(requestDto.getRoomId()) + .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id =" + requestDto.getRoomId())); // 3. 사용자 이메일 조회해서 save 전에 주입 User user = userService.getUserByEmail(requestDto.getEmail()); diff --git a/src/main/java/mos/mosback/stRoom/service/ToDoService.java b/src/main/java/mos/mosback/stRoom/service/ToDoService.java index f36f208..3c7d757 100644 --- a/src/main/java/mos/mosback/stRoom/service/ToDoService.java +++ b/src/main/java/mos/mosback/stRoom/service/ToDoService.java @@ -1,16 +1,12 @@ package mos.mosback.stRoom.service; import lombok.RequiredArgsConstructor; -import mos.mosback.domain.stRoom.*; import mos.mosback.login.domain.user.User; import mos.mosback.login.domain.user.service.UserService; import mos.mosback.stRoom.domain.stRoom.*; +import mos.mosback.stRoom.dto.*; import mos.mosback.stRoom.repository.MemberTodoRepository; import mos.mosback.stRoom.repository.StRoomRepository; import mos.mosback.stRoom.repository.ToDoRepository; -import mos.mosback.stRoom.dto.*; -import mos.mosback.stRoom.Entity.*; -import mos.mosback.stduy.dto.*; -import mos.mosback.study.dto.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -105,8 +101,8 @@ public List findStRoomTodoByRoomId(Long roomId) { public StudyMemberTodoEntity addMemberTodo(StudyMemberToDoRequestDto requestDto) throws Exception { StudyMemberTodoEntity toDoEntity = new StudyMemberTodoEntity(); toDoEntity.setTodoContent(requestDto.getTodoContent()); - StRoomEntity stRoomEntity = stRoomRepository.findById(requestDto.getRoomID()) - .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id =" + requestDto.getRoomID())); + StRoomEntity stRoomEntity = stRoomRepository.findById(requestDto.getRoomId()) + .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id =" + requestDto.getRoomId())); // 사용자 이메일 조회해서 save 전에 주입 User user = userService.getUserByEmail(requestDto.getCurrentEmail()); toDoEntity.setMemberId(user.getId()); From 6bb5b4756169f05e1cfa1f013f1512fddbb846df Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Sun, 22 Oct 2023 19:34:23 +0900 Subject: [PATCH 42/60] =?UTF-8?q?=EC=9C=A0=EC=A0=80=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=B8=94=20-=20=EC=8A=A4=ED=84=B0=EB=94=94=EB=A3=B8=ED=85=8C?= =?UTF-8?q?=EC=9D=B4=EB=B8=94=20=EB=A7=A4=ED=95=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/mos/mosback/login/domain/user/User.java | 9 ++++++++- .../mosback/login/domain/user/service/UserService.java | 5 ++++- .../java/mos/mosback/stRoom/service/StRoomService.java | 3 +++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main/java/mos/mosback/login/domain/user/User.java b/src/main/java/mos/mosback/login/domain/user/User.java index 79c26a4..73adf76 100644 --- a/src/main/java/mos/mosback/login/domain/user/User.java +++ b/src/main/java/mos/mosback/login/domain/user/User.java @@ -1,13 +1,16 @@ package mos.mosback.login.domain.user; - +import java.util.ArrayList; +import java.util.List; import lombok.*; +import mos.mosback.stRoom.domain.stRoom.StRoomEntity; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import javax.persistence.*; import java.util.Date; +@Setter @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @Entity @@ -21,6 +24,10 @@ public class User { @Column(name = "user_id") private Long id; + @OneToMany + private List stRooms= new ArrayList<>(); + + private String email; // 이메일 private String password; // 비밀번호 diff --git a/src/main/java/mos/mosback/login/domain/user/service/UserService.java b/src/main/java/mos/mosback/login/domain/user/service/UserService.java index 85aef11..5be242d 100644 --- a/src/main/java/mos/mosback/login/domain/user/service/UserService.java +++ b/src/main/java/mos/mosback/login/domain/user/service/UserService.java @@ -9,6 +9,9 @@ import mos.mosback.login.domain.user.dto.UserSignUpDto; import mos.mosback.login.domain.user.repository.UserRepository; import lombok.RequiredArgsConstructor; +import mos.mosback.stRoom.domain.stRoom.StRoomEntity; +import mos.mosback.stRoom.domain.stRoom.StudyMemberEntity; +import mos.mosback.stRoom.dto.StRoomSaveRequestDto; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.security.core.Authentication; @@ -18,6 +21,7 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; +import javax.servlet.http.HttpServletRequest; import javax.transaction.Transactional; import java.util.Optional; @Service @@ -179,5 +183,4 @@ public Optional loadUserByUsername(String userEmail) throws UsernameNotFou } - } \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/service/StRoomService.java b/src/main/java/mos/mosback/stRoom/service/StRoomService.java index 7ecfd7e..6a0caa8 100644 --- a/src/main/java/mos/mosback/stRoom/service/StRoomService.java +++ b/src/main/java/mos/mosback/stRoom/service/StRoomService.java @@ -45,11 +45,14 @@ public Long save(StRoomSaveRequestDto requestDto, HttpServletRequest req) { // 4. 정보 대입 studyMember.setMemberId(user.getId()); + user.getStRooms().add(stRoom); + // 5. Study Member 저장 studyMember.setStRoom(stRoom); studyMember.setStatus(MemberStatus.Leader); studyMemberRepository.save(studyMember); + return stRoom.getRoomId(); } catch (Exception e) { e.printStackTrace(); From 0d32ebbac122279fbac18ddcbcef2a425f99097d Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Fri, 27 Oct 2023 16:39:07 +0900 Subject: [PATCH 43/60] =?UTF-8?q?TodoApi=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mos/mosback/login/domain/user/User.java | 4 ++++ .../stRoom/controller/StRoomController.java | 17 +++++++++------ .../stRoom/controller/TodoController.java | 2 +- .../stRoom/domain/stRoom/StRoomEntity.java | 3 --- .../domain/stRoom/StudyMemberTodoEntity.java | 11 +++------- .../domain/stRoom/StudyMemberTodoKey.java | 5 +++++ .../stRoom/dto/StRoomMemberResponseDto.java | 10 +++++++++ .../dto/StRoomMemberToDoResponseDto.java | 4 ++-- .../repository/MemberTodoRepository.java | 5 ++++- .../repository/StudyMemberRepository.java | 2 ++ .../mosback/stRoom/service/StRoomService.java | 21 ++++++++++++++++--- .../mosback/stRoom/service/ToDoService.java | 20 +++--------------- 12 files changed, 63 insertions(+), 41 deletions(-) create mode 100644 src/main/java/mos/mosback/stRoom/dto/StRoomMemberResponseDto.java diff --git a/src/main/java/mos/mosback/login/domain/user/User.java b/src/main/java/mos/mosback/login/domain/user/User.java index 73adf76..a9ea6c1 100644 --- a/src/main/java/mos/mosback/login/domain/user/User.java +++ b/src/main/java/mos/mosback/login/domain/user/User.java @@ -4,6 +4,7 @@ import java.util.List; import lombok.*; import mos.mosback.stRoom.domain.stRoom.StRoomEntity; +import mos.mosback.stRoom.domain.stRoom.StudyMemberEntity; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @@ -27,6 +28,9 @@ public class User { @OneToMany private List stRooms= new ArrayList<>(); + @OneToMany + private List members = new ArrayList<>(); + private String email; // 이메일 private String password; // 비밀번호 diff --git a/src/main/java/mos/mosback/stRoom/controller/StRoomController.java b/src/main/java/mos/mosback/stRoom/controller/StRoomController.java index f56150e..f00aadd 100644 --- a/src/main/java/mos/mosback/stRoom/controller/StRoomController.java +++ b/src/main/java/mos/mosback/stRoom/controller/StRoomController.java @@ -1,7 +1,9 @@ package mos.mosback.stRoom.controller; +import lombok.RequiredArgsConstructor; import mos.mosback.stRoom.dto.*; import mos.mosback.stRoom.service.StRoomService; +import mos.mosback.stRoom.service.ToDoService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -15,16 +17,13 @@ import java.util.List; import java.util.Map; +@RequiredArgsConstructor @RestController @RequestMapping("/studyRoom") //URL 패턴 public class StRoomController { private final StRoomService stRoomService; // stRoomService를 주입. - - @Autowired - public StRoomController(StRoomService stRoomService) { - this.stRoomService = stRoomService; - } + private final ToDoService toDoService; @PostMapping("/create") public ResponseEntity saveRoom(@RequestBody StRoomSaveRequestDto requestDto, HttpServletRequest req) { @@ -153,6 +152,7 @@ public ResponseEntity memberJoin(@PathVariable Long roomId, ("message : joined successfully.\nstatus : 201\n success: true"); } + @GetMapping("/recruiting") public ResponseEntity getRecruitingStudies() { List recruitingStudies = stRoomService.getRecruitingStudies(); @@ -189,10 +189,15 @@ public ResponseEntity> getMyInfo() throws Exception { @GetMapping("/recruitInfo/{roomId}") public ResponseEntity> recruitInfo(@PathVariable Long roomId) { String recruitInfo = stRoomService.isRecruiting(roomId); + StRoomResponseDto stroom = stRoomService.findById(roomId); + List todoList = toDoService.findStRoomTodoByRoomId(roomId); + List studyRoomMemberList = stRoomService.getStudyRoomMemberList(roomId); Map response = new HashMap<>(); response.put("모집", recruitInfo); - response.put("status", HttpStatus.OK.value()); + response.put("stroom", stroom); + response.put("todoList", todoList); + response.put("studyRoomMemberList", studyRoomMemberList); return ResponseEntity.status(HttpStatus.OK).body(response); } diff --git a/src/main/java/mos/mosback/stRoom/controller/TodoController.java b/src/main/java/mos/mosback/stRoom/controller/TodoController.java index 466f101..90c6c89 100644 --- a/src/main/java/mos/mosback/stRoom/controller/TodoController.java +++ b/src/main/java/mos/mosback/stRoom/controller/TodoController.java @@ -49,7 +49,7 @@ public ResponseEntity addMemberTodo(@RequestBody StudyMemberToDoRequestD String currentEmail = authentication.getName(); // 현재 사용자의 이메일 requestDto.setCurrentEmail(currentEmail); StudyMemberTodoEntity todo = toDoService.addMemberTodo(requestDto); - return ResponseEntity.status(HttpStatus.CREATED).body("TodoList 추가 완료. index : " +todo.getMemberId()); + return ResponseEntity.status(HttpStatus.CREATED).body("TodoList 추가 완료. index : " +todo.getIdx()); } //todo개수만큼 프론트에서 호출해줘야함 // diff --git a/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomEntity.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomEntity.java index ea09ee5..f2cfcc9 100644 --- a/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomEntity.java +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomEntity.java @@ -44,9 +44,6 @@ public class StRoomEntity extends BaseTimeEntity { @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) private List studyDayEntities = new ArrayList<>(); - @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) - private List studyMemberEntities = new ArrayList<>(); - @Builder public StRoomEntity(String title, String goal, String rules, String quest, diff --git a/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberTodoEntity.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberTodoEntity.java index ef39a20..129dd5a 100644 --- a/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberTodoEntity.java +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberTodoEntity.java @@ -11,27 +11,22 @@ @Setter @NoArgsConstructor @Entity -@IdClass(StudyMemberTodoEntity.class) public class StudyMemberTodoEntity implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long idx; + @Column(name = "memberID") private Long memberId; - @Id - @Column + @Column(name = "todoContent") private String todoContent; @ManyToOne @JoinColumn(name = "roomId") private StRoomEntity stRoom; - @Id - @ManyToOne - @JoinColumn(name = "todoId") - private ToDoEntity toDoEntity; - // 다른 필드와 매핑 @Enumerated(EnumType.STRING) private TodoStatus status; diff --git a/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberTodoKey.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberTodoKey.java index 39b14dd..be28fef 100644 --- a/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberTodoKey.java +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberTodoKey.java @@ -2,11 +2,16 @@ import lombok.Data; +import javax.persistence.*; import java.io.Serializable; @Data +@Embeddable public class StudyMemberTodoKey implements Serializable { + @Column(name = "memberID") private Long memberId; + + @Column(name = "todoContent") private String todoContent; } \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomMemberResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomMemberResponseDto.java new file mode 100644 index 0000000..7dce757 --- /dev/null +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomMemberResponseDto.java @@ -0,0 +1,10 @@ +package mos.mosback.stRoom.dto; + +import lombok.Data; +import mos.mosback.stRoom.domain.stRoom.MemberStatus; + +@Data +public class StRoomMemberResponseDto { + private Long memberId; + private MemberStatus status; +} diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomMemberToDoResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomMemberToDoResponseDto.java index 8367ab6..64f448d 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomMemberToDoResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomMemberToDoResponseDto.java @@ -6,13 +6,13 @@ @Data public class StRoomMemberToDoResponseDto { - private Long todoId; + private Long idx; private String todoContent; private TodoStatus status; public StRoomMemberToDoResponseDto (StudyMemberTodoEntity entity) { - this.todoId = entity.getToDoEntity().getTodoId(); + this.idx = entity.getIdx(); this.status = entity.getStatus(); this.todoContent = entity.getTodoContent(); } diff --git a/src/main/java/mos/mosback/stRoom/repository/MemberTodoRepository.java b/src/main/java/mos/mosback/stRoom/repository/MemberTodoRepository.java index 38f008d..bb4a5ca 100644 --- a/src/main/java/mos/mosback/stRoom/repository/MemberTodoRepository.java +++ b/src/main/java/mos/mosback/stRoom/repository/MemberTodoRepository.java @@ -7,9 +7,10 @@ import org.springframework.data.repository.query.Param; import java.util.List; +import java.util.Optional; -public interface MemberTodoRepository extends JpaRepository{ +public interface MemberTodoRepository extends JpaRepository{ @Query(value = "SELECT * FROM STUDY_MEMBER_TODO_ENTITY WHERE roomId = :roomId AND memberId = :memberId", nativeQuery = true) List findAllByStRoom(@Param("roomId") Long roomId, @Param("memberId") Long memberId); @@ -19,4 +20,6 @@ public interface MemberTodoRepository extends JpaRepository findByMemberIdAndTodoContent(Long id, String todoContent); } diff --git a/src/main/java/mos/mosback/stRoom/repository/StudyMemberRepository.java b/src/main/java/mos/mosback/stRoom/repository/StudyMemberRepository.java index 1e34935..3c2e309 100644 --- a/src/main/java/mos/mosback/stRoom/repository/StudyMemberRepository.java +++ b/src/main/java/mos/mosback/stRoom/repository/StudyMemberRepository.java @@ -1,5 +1,6 @@ package mos.mosback.stRoom.repository; +import mos.mosback.stRoom.domain.stRoom.StRoomEntity; import mos.mosback.stRoom.domain.stRoom.StudyMemberEntity; import org.springframework.data.jpa.repository.JpaRepository; @@ -9,4 +10,5 @@ public interface StudyMemberRepository extends JpaRepository findAllByMemberId(Long memberId); + List findAllByStRoom(StRoomEntity stRoom); } diff --git a/src/main/java/mos/mosback/stRoom/service/StRoomService.java b/src/main/java/mos/mosback/stRoom/service/StRoomService.java index 6a0caa8..888f09b 100644 --- a/src/main/java/mos/mosback/stRoom/service/StRoomService.java +++ b/src/main/java/mos/mosback/stRoom/service/StRoomService.java @@ -16,6 +16,7 @@ import javax.servlet.http.HttpServletRequest; import java.time.LocalDate; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -44,11 +45,11 @@ public Long save(StRoomSaveRequestDto requestDto, HttpServletRequest req) { User user = userService.getUserByEmail(loginUserEmail); // 4. 정보 대입 - studyMember.setMemberId(user.getId()); - user.getStRooms().add(stRoom); - +// user.getStRooms().add(stRoom); +// stRoom.setMemberNum(1); // 5. Study Member 저장 + studyMember.setMemberId(user.getId()); studyMember.setStRoom(stRoom); studyMember.setStatus(MemberStatus.Leader); studyMemberRepository.save(studyMember); @@ -146,6 +147,7 @@ public void memberJoin(StRoomMemberJoinRequestDto requestDto) { } } + public List getRecruitingStudies() { LocalDateTime now = LocalDateTime.now(); @@ -186,4 +188,17 @@ public String isRecruiting(Long roomId) { } + public List getStudyRoomMemberList(Long roomId) { + StRoomEntity stRoom = stRoomRepository.findById(roomId) + .orElseThrow(() -> new EntityNotFoundException("Room not found")); + List memberEntityList = studyMemberRepository.findAllByStRoom(stRoom); + List memberList = new ArrayList<>(); + for (StudyMemberEntity item : memberEntityList) { + StRoomMemberResponseDto dto = new StRoomMemberResponseDto(); + dto.setMemberId(item.getMemberId()); + dto.setStatus(item.getStatus()); + memberList.add(dto); + } + return memberList; + } } \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/service/ToDoService.java b/src/main/java/mos/mosback/stRoom/service/ToDoService.java index 3c7d757..0ab20db 100644 --- a/src/main/java/mos/mosback/stRoom/service/ToDoService.java +++ b/src/main/java/mos/mosback/stRoom/service/ToDoService.java @@ -53,10 +53,7 @@ public StudyMemberTodoEntity updateMemberTodo(Long todoId, String todoContent, T ToDoEntity toDoEntity = toDoRepository.findById(todoId) .orElseThrow(() -> new IllegalArgumentException("해당 ToDo를 찾을 수 없습니다.")); User user = userService.getUserByEmail(currentEmail); - StudyMemberTodoKey key = new StudyMemberTodoKey(); - key.setMemberId(user.getId()); - key.setTodoContent(toDoEntity.getTodoContent()); - StudyMemberTodoEntity studyMemberTodoEntity = studyMemberToDoRepository.findById(key) + StudyMemberTodoEntity studyMemberTodoEntity = studyMemberToDoRepository.findByMemberIdAndTodoContent(user.getId(), toDoEntity.getTodoContent()) .orElseThrow(() -> new IllegalArgumentException("해당 ToDo를 찾을 수 없습니다.")); studyMemberTodoEntity.update(todoContent, status); @@ -76,22 +73,11 @@ public void deleteMemberTodo(Long todoId, String currentEmail) throws Exception ToDoEntity toDoEntity = toDoRepository.findById(todoId) .orElseThrow(() -> new IllegalArgumentException("해당 ToDo를 찾을 수 없습니다.")); User user = userService.getUserByEmail(currentEmail); - StudyMemberTodoKey key = new StudyMemberTodoKey(); - key.setMemberId(user.getId()); - key.setTodoContent(toDoEntity.getTodoContent()); - StudyMemberTodoEntity studyMemberTodoEntity = studyMemberToDoRepository.findById(key) + StudyMemberTodoEntity studyMemberTodoEntity = studyMemberToDoRepository.findByMemberIdAndTodoContent(user.getId(), toDoEntity.getTodoContent()) .orElseThrow(() -> new IllegalArgumentException("해당 Study Member ToDo를 찾을 수 없습니다.")); studyMemberToDoRepository.delete(studyMemberTodoEntity); } - @Transactional - public void getTodo(Long todoId){ - ToDoEntity toDoEntity = toDoRepository.findById(todoId) - .orElseThrow(() -> new IllegalArgumentException("해당 ToDo를 찾을 수 없습니다.")); - - toDoRepository.findById(todoId); - - } @Transactional public List findStRoomTodoByRoomId(Long roomId) { @@ -100,7 +86,6 @@ public List findStRoomTodoByRoomId(Long roomId) { public StudyMemberTodoEntity addMemberTodo(StudyMemberToDoRequestDto requestDto) throws Exception { StudyMemberTodoEntity toDoEntity = new StudyMemberTodoEntity(); - toDoEntity.setTodoContent(requestDto.getTodoContent()); StRoomEntity stRoomEntity = stRoomRepository.findById(requestDto.getRoomId()) .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id =" + requestDto.getRoomId())); // 사용자 이메일 조회해서 save 전에 주입 @@ -108,6 +93,7 @@ public StudyMemberTodoEntity addMemberTodo(StudyMemberToDoRequestDto requestDto) toDoEntity.setMemberId(user.getId()); toDoEntity.setStatus(TodoStatus.Waiting); toDoEntity.setStRoom(stRoomEntity); + toDoEntity.setTodoContent(requestDto.getTodoContent()); return studyMemberToDoRepository.save(toDoEntity); } From da36e2aa919c131bffb7528f47568083e48bf7fc Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Sat, 28 Oct 2023 05:22:58 +0900 Subject: [PATCH 44/60] =?UTF-8?q?=EC=8A=A4=ED=84=B0=EB=94=94=EB=A3=B8=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20-=20=EB=A9=A4=EB=B2=84=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EA=B5=AC=ED=98=84=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../stRoom/controller/StRoomController.java | 26 +++++++++--- .../stRoom/controller/TodoController.java | 11 ++--- .../stRoom/domain/stRoom/StRoomEntity.java | 5 +-- .../dto/QuestionAndAnswerResponseDto.java | 14 +++++++ .../stRoom/dto/StRoomDetailResponseDto.java | 41 +++++++++++++++---- .../dto/StudyMemberRoomInfoResponseDto.java | 2 - .../mosback/stRoom/service/StRoomService.java | 24 +++++++++++ 7 files changed, 98 insertions(+), 25 deletions(-) create mode 100644 src/main/java/mos/mosback/stRoom/dto/QuestionAndAnswerResponseDto.java diff --git a/src/main/java/mos/mosback/stRoom/controller/StRoomController.java b/src/main/java/mos/mosback/stRoom/controller/StRoomController.java index f00aadd..8e9f3af 100644 --- a/src/main/java/mos/mosback/stRoom/controller/StRoomController.java +++ b/src/main/java/mos/mosback/stRoom/controller/StRoomController.java @@ -1,16 +1,13 @@ package mos.mosback.stRoom.controller; import lombok.RequiredArgsConstructor; import mos.mosback.stRoom.dto.*; - import mos.mosback.stRoom.service.StRoomService; import mos.mosback.stRoom.service.ToDoService; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; - import javax.persistence.EntityNotFoundException; import javax.servlet.http.HttpServletRequest; import java.util.HashMap; @@ -139,6 +136,23 @@ public ResponseEntity getQuestionById(@PathVariable Long roomId) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); } } + + @GetMapping("/QnA/{memberId}/{roomId}") + public ResponseEntity getQuestionandAnswerById(@PathVariable("memberId") Long memberId, @PathVariable("roomId") Long roomId) { + { + try { + QuestionAndAnswerResponseDto QnA = stRoomService.getQuestionAndAnswerById(memberId,roomId); + return ResponseEntity.ok(QnA); + }catch (EntityNotFoundException ex) { + Map response = new HashMap<>(); + response.put("status:", HttpStatus.NOT_FOUND.value()); + response.put("success", false); + response.put("message", "NOT FOUND"); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); + } + + } + } @PostMapping("/memberjoin/{roomId}") public ResponseEntity memberJoin(@PathVariable Long roomId, @RequestBody StRoomMemberJoinRequestDto requestDto) { @@ -186,16 +200,16 @@ public ResponseEntity> getMyInfo() throws Exception { return ResponseEntity.status(HttpStatus.CREATED).body(response); } - @GetMapping("/recruitInfo/{roomId}") + @GetMapping("/Info/{roomId}") public ResponseEntity> recruitInfo(@PathVariable Long roomId) { String recruitInfo = stRoomService.isRecruiting(roomId); - StRoomResponseDto stroom = stRoomService.findById(roomId); + StRoomDetailResponseDto stroom = stRoomService.findByRoomId(roomId); List todoList = toDoService.findStRoomTodoByRoomId(roomId); List studyRoomMemberList = stRoomService.getStudyRoomMemberList(roomId); Map response = new HashMap<>(); response.put("모집", recruitInfo); - response.put("stroom", stroom); + response.put("StudyRoom", stroom); response.put("todoList", todoList); response.put("studyRoomMemberList", studyRoomMemberList); return ResponseEntity.status(HttpStatus.OK).body(response); diff --git a/src/main/java/mos/mosback/stRoom/controller/TodoController.java b/src/main/java/mos/mosback/stRoom/controller/TodoController.java index 90c6c89..4773704 100644 --- a/src/main/java/mos/mosback/stRoom/controller/TodoController.java +++ b/src/main/java/mos/mosback/stRoom/controller/TodoController.java @@ -71,17 +71,18 @@ public ResponseEntity updateTodo(@PathVariable Long todoId, @RequestBody } } - @PutMapping("/member/todo/{todoId}") - public ResponseEntity updateMemberTodo(@PathVariable Long todoId, - @RequestBody stRoomToDoRequestDto requestDto) throws Exception { + @PutMapping("/member/todo/{idx}") + public ResponseEntity updateMemberTodo(@PathVariable Long idx, + @RequestBody StudyMemberToDoRequestDto requestDto) throws Exception { // 현재 로그인한 사용자의 정보 가져오기 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String currentEmail = authentication.getName(); // 현재 사용자의 이메일 + requestDto.setCurrentEmail(currentEmail); try { - StudyMemberTodoEntity updatedToDo = toDoService.updateMemberTodo(todoId, requestDto.getTodoContent(), + StudyMemberTodoEntity updatedToDo = toDoService.updateMemberTodo(idx, requestDto.getTodoContent(), requestDto.getStatus(), currentEmail); return ResponseEntity.ok - ("Study Member ToDo 업데이트 완료. \nIndex: " + todoId + + ("Study Member ToDo 업데이트 완료. \nIndex: " + idx + "\nstatus:200" + "\nsuccess:true"); } catch (IllegalArgumentException e) { diff --git a/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomEntity.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomEntity.java index f2cfcc9..2cc2a8e 100644 --- a/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomEntity.java +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomEntity.java @@ -40,6 +40,7 @@ public class StRoomEntity extends BaseTimeEntity { private LocalDate startDate; //스터디 시작 날짜 private LocalDate endDate; //스터디 끝나는 날짜 private boolean recruiting; //모집여부 + private LocalDate deadline; // 모집 마감날짜 @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) private List studyDayEntities = new ArrayList<>(); @@ -48,7 +49,7 @@ public class StRoomEntity extends BaseTimeEntity { @Builder public StRoomEntity(String title, String goal, String rules, String quest, String category, String intro, int memberNum, int maxMember - ,String mod, boolean onOff, String location,int online, + ,String mod, boolean onOff, String location,int online, LocalDate startDate, LocalDate endDate, List studyDayEntities ) { this.title = title; @@ -89,6 +90,4 @@ public void update(String title, String goal, String rules, String quest, this.studyDayEntities = studyDayEntities; } - - } \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/dto/QuestionAndAnswerResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/QuestionAndAnswerResponseDto.java new file mode 100644 index 0000000..ffcc9f3 --- /dev/null +++ b/src/main/java/mos/mosback/stRoom/dto/QuestionAndAnswerResponseDto.java @@ -0,0 +1,14 @@ +package mos.mosback.stRoom.dto; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.Getter; + +@Setter +@Getter +@NoArgsConstructor +public class QuestionAndAnswerResponseDto { + private Long memberId; + private String question; + private String answer; + +} diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java index b665da7..3b9dcb4 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java @@ -1,27 +1,50 @@ package mos.mosback.stRoom.dto; +import lombok.Getter; +import mos.mosback.stRoom.domain.stRoom.StRoomEntity; import mos.mosback.stRoom.domain.stRoom.StudyDaysEntity; - import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.List; - +@Getter public class StRoomDetailResponseDto { + private Long roomId; private String title; private String category; - private boolean recruiting; private String location; private LocalDate startDate; private LocalDate endDate; + private boolean onOff; //진행방식 (온오프) private int memberNum; //현재 멤버수 private int maxMember; //모집 멤버수 - private String mod; //스터디 분위기 - - private String leader; //스터디리더 닉네임 - private List studyDayEntities; private String goal; private String rules; private String intro; - //+스터디원 사진 - //+스터디룸 투두리스트 + private LocalDateTime createdDate; + private LocalDate deadline; + + public StRoomDetailResponseDto(StRoomEntity entity) { + + this.roomId = entity.getRoomId(); + this.createdDate = entity.getCreatedDate(); + this.title = entity.getTitle(); + this.location = entity.getLocation(); + this.intro = entity.getIntro(); + this.goal = entity.getGoal(); + this.rules = entity.getRules(); + this.category = entity.getCategory(); + this.memberNum = entity.getMemberNum(); + this.maxMember = entity.getMaxMember(); + this.mod = entity.getMod(); + this.onOff = entity.isOnOff(); + this.startDate = entity.getStartDate(); + this.endDate = entity.getEndDate(); + this.deadline = entity.getStartDate().minusDays(1); + this.studyDayEntities = entity.getStudyDayEntities(); + + + + } //스터디 + 투두 리스트의 스터디룸 상세화면 } + diff --git a/src/main/java/mos/mosback/stRoom/dto/StudyMemberRoomInfoResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StudyMemberRoomInfoResponseDto.java index 1614fc7..fa530ca 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StudyMemberRoomInfoResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StudyMemberRoomInfoResponseDto.java @@ -2,8 +2,6 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; - - import java.util.List; @Setter diff --git a/src/main/java/mos/mosback/stRoom/service/StRoomService.java b/src/main/java/mos/mosback/stRoom/service/StRoomService.java index 888f09b..d4c7ff5 100644 --- a/src/main/java/mos/mosback/stRoom/service/StRoomService.java +++ b/src/main/java/mos/mosback/stRoom/service/StRoomService.java @@ -88,6 +88,13 @@ public StRoomResponseDto findById(Long roomId) { return new StRoomResponseDto(stRoomEntity); } + @Transactional(readOnly = true) + public StRoomDetailResponseDto findByRoomId(Long roomId) { + StRoomEntity stRoomEntity = stRoomRepository.findById(roomId) + .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id=" + roomId)); + + return new StRoomDetailResponseDto(stRoomEntity); + } public List findAllRoomsDesc() { return stRoomRepository.findAllDesc(); } @@ -164,9 +171,26 @@ public QuestionDto getQuestionById(Long roomId) { responseDTO.setQuestion(stRoomEntity.getQuest()); return responseDTO; + } + + public QuestionAndAnswerResponseDto getQuestionAndAnswerById(Long memberId, Long roomId) { + StudyMemberEntity memberEntity = studyMemberRepository.findById(memberId) + .orElseThrow(() -> new EntityNotFoundException("Member not found")); + + StRoomEntity stRoomEntity = stRoomRepository.findById(roomId) + .orElseThrow(() -> new EntityNotFoundException("Room not found")); + + QuestionAndAnswerResponseDto responseDto = new QuestionAndAnswerResponseDto(); + responseDto.setMemberId(memberEntity.getMemberId()); + responseDto.setAnswer(memberEntity.getAnswer()); + responseDto.setQuestion(stRoomEntity.getQuest()); + + + return responseDto; } + public String getMyInfo(String email) throws Exception { // 3. 사용자 이메일 조회해서 save 전에 주입 User user = userService.getUserByEmail(email); From 4203e81a0c011c520091aa3e1e06673219ae750d Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Sat, 28 Oct 2023 16:11:25 +0900 Subject: [PATCH 45/60] =?UTF-8?q?=EC=8A=A4=ED=84=B0=EB=94=94=EB=A3=B8=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20-=20=EB=A9=A4=EB=B2=84=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EA=B5=AC=ED=98=84=EB=81=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../stRoom/controller/StRoomController.java | 27 +++++++++++++++++ .../stRoom/controller/TodoController.java | 8 ++--- .../stRoom/dto/AcceptMemberRequestDto.java | 12 ++++++++ .../mosback/stRoom/service/StRoomService.java | 29 +++++++++++++++++++ 4 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 src/main/java/mos/mosback/stRoom/dto/AcceptMemberRequestDto.java diff --git a/src/main/java/mos/mosback/stRoom/controller/StRoomController.java b/src/main/java/mos/mosback/stRoom/controller/StRoomController.java index 8e9f3af..155f855 100644 --- a/src/main/java/mos/mosback/stRoom/controller/StRoomController.java +++ b/src/main/java/mos/mosback/stRoom/controller/StRoomController.java @@ -165,6 +165,31 @@ public ResponseEntity memberJoin(@PathVariable Long roomId, return ResponseEntity.status(HttpStatus.CREATED).body ("message : joined successfully.\nstatus : 201\n success: true"); } + @PostMapping("/accept/{roomId}") + public ResponseEntity acceptMember(@PathVariable Long roomId, + @RequestBody AcceptMemberRequestDto requestDto) { + try { + requestDto.setRoomId(roomId); + stRoomService.acceptMember(requestDto); + return ResponseEntity.status(HttpStatus.CREATED).body + ("message : Accepted successfully.\nstatus : 201\n success: true"); + }catch (IllegalArgumentException ex){ + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("message : ServerError.ServerError.\nstatus : 500\n success: false"); + } + } + @PostMapping("/reject/{roomId}") + public ResponseEntity rejectMember(@PathVariable Long roomId, + @RequestBody AcceptMemberRequestDto requestDto) { + try { + requestDto.setRoomId(roomId); + stRoomService.rejecttMember(requestDto); + return ResponseEntity.status(HttpStatus.CREATED).body + ("message : Rejected successfully.\nstatus : 201\n success: true"); + }catch (IllegalArgumentException ex){ + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("message : ServerError.ServerError.\nstatus : 500\n success: false"); + } + } + @GetMapping("/recruiting") @@ -215,6 +240,8 @@ public ResponseEntity> recruitInfo(@PathVariable Long roomId return ResponseEntity.status(HttpStatus.OK).body(response); } + + } diff --git a/src/main/java/mos/mosback/stRoom/controller/TodoController.java b/src/main/java/mos/mosback/stRoom/controller/TodoController.java index 4773704..37d9186 100644 --- a/src/main/java/mos/mosback/stRoom/controller/TodoController.java +++ b/src/main/java/mos/mosback/stRoom/controller/TodoController.java @@ -71,18 +71,18 @@ public ResponseEntity updateTodo(@PathVariable Long todoId, @RequestBody } } - @PutMapping("/member/todo/{idx}") - public ResponseEntity updateMemberTodo(@PathVariable Long idx, + @PutMapping("/member/todo/{todoId}") + public ResponseEntity updateMemberTodo(@PathVariable Long todoId, @RequestBody StudyMemberToDoRequestDto requestDto) throws Exception { // 현재 로그인한 사용자의 정보 가져오기 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String currentEmail = authentication.getName(); // 현재 사용자의 이메일 requestDto.setCurrentEmail(currentEmail); try { - StudyMemberTodoEntity updatedToDo = toDoService.updateMemberTodo(idx, requestDto.getTodoContent(), + StudyMemberTodoEntity updatedToDo = toDoService.updateMemberTodo(todoId, requestDto.getTodoContent(), requestDto.getStatus(), currentEmail); return ResponseEntity.ok - ("Study Member ToDo 업데이트 완료. \nIndex: " + idx + + ("Study Member ToDo 업데이트 완료. \nIndex: " + todoId + "\nstatus:200" + "\nsuccess:true"); } catch (IllegalArgumentException e) { diff --git a/src/main/java/mos/mosback/stRoom/dto/AcceptMemberRequestDto.java b/src/main/java/mos/mosback/stRoom/dto/AcceptMemberRequestDto.java new file mode 100644 index 0000000..5dee6fe --- /dev/null +++ b/src/main/java/mos/mosback/stRoom/dto/AcceptMemberRequestDto.java @@ -0,0 +1,12 @@ +package mos.mosback.stRoom.dto; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Setter +@Getter +@NoArgsConstructor +public class AcceptMemberRequestDto { + private Long roomId; + private Long memberId; +} diff --git a/src/main/java/mos/mosback/stRoom/service/StRoomService.java b/src/main/java/mos/mosback/stRoom/service/StRoomService.java index d4c7ff5..2fc25c7 100644 --- a/src/main/java/mos/mosback/stRoom/service/StRoomService.java +++ b/src/main/java/mos/mosback/stRoom/service/StRoomService.java @@ -211,6 +211,34 @@ public String isRecruiting(Long roomId) { return stRoom.isRecruiting() ? "true" : "false"; } + public void acceptMember(AcceptMemberRequestDto requestDto){ + // 1. save할 변수 선언 + StudyMemberEntity studyMember = new StudyMemberEntity(); + + // 2. 가입 시에는 룸ID를 요청 파라미터에서 받아서 StRoom 조회 + StRoomEntity stRoomEntity = stRoomRepository.findById(requestDto.getRoomId()) + .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id =" + requestDto.getRoomId())); + + studyMember.setMemberId(requestDto.getMemberId()); + studyMember.setStRoom(stRoomEntity); + studyMember.setStatus(MemberStatus.Member); + studyMemberRepository.save(studyMember); + + } + public void rejecttMember(AcceptMemberRequestDto requestDto){ + // 1. save할 변수 선언 + StudyMemberEntity studyMember = new StudyMemberEntity(); + + // 2. 가입 시에는 룸ID를 요청 파라미터에서 받아서 StRoom 조회 + StRoomEntity stRoomEntity = stRoomRepository.findById(requestDto.getRoomId()) + .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id =" + requestDto.getRoomId())); + + studyMember.setMemberId(requestDto.getMemberId()); + studyMember.setStRoom(stRoomEntity); + studyMember.setStatus(MemberStatus.Rejected); + studyMemberRepository.save(studyMember); + + } public List getStudyRoomMemberList(Long roomId) { StRoomEntity stRoom = stRoomRepository.findById(roomId) @@ -225,4 +253,5 @@ public List getStudyRoomMemberList(Long roomId) { } return memberList; } + } \ No newline at end of file From 63efce119e35e3de6c894bfc70193bbba7925e68 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Sat, 28 Oct 2023 19:08:04 +0900 Subject: [PATCH 46/60] =?UTF-8?q?=EC=8A=A4=ED=84=B0=EB=94=94=EB=A3=B8=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20-=20=EB=A9=A4=EB=B2=84=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EA=B5=AC=ED=98=84=EB=81=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mos/mosback/login/domain/user/User.java | 63 ++++++++++---- .../conrtoller/UserProfileController.java | 84 ++++++++++++++----- .../login/domain/user/dto/UserProfileDto.java | 37 +++++++- .../domain/user/service/UserService.java | 20 +++++ .../stRoom/controller/StRoomController.java | 29 ++++++- .../mosback/stRoom/service/StRoomService.java | 25 +++++- 6 files changed, 212 insertions(+), 46 deletions(-) diff --git a/src/main/java/mos/mosback/login/domain/user/User.java b/src/main/java/mos/mosback/login/domain/user/User.java index a9ea6c1..3bb37e5 100644 --- a/src/main/java/mos/mosback/login/domain/user/User.java +++ b/src/main/java/mos/mosback/login/domain/user/User.java @@ -1,17 +1,14 @@ package mos.mosback.login.domain.user; -import java.util.ArrayList; -import java.util.List; + import lombok.*; import mos.mosback.stRoom.domain.stRoom.StRoomEntity; -import mos.mosback.stRoom.domain.stRoom.StudyMemberEntity; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import javax.persistence.*; -import java.util.Date; +import java.util.*; -@Setter @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @Entity @@ -23,26 +20,51 @@ public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "user_id") + private Long id; @OneToMany private List stRooms= new ArrayList<>(); - @OneToMany - private List members = new ArrayList<>(); - + @Column(name ="room_id") + private Long roomId; private String email; // 이메일 private String password; // 비밀번호 private String name; + private String nickname; // 닉네임 + + + @Column(name = "image_url") private String imageUrl; // 프로필 이미지 private Date str_duration; private Date end_duration; private String message; + private String company; + + private String tend1; + private String tend2; + + public String getTend1() { + return tend1; + } + + public void setTend1(String tend1) { + this.tend1 = tend1; + } + + public String getTend2() { + return tend2; + } + + public void setTend2(String tend2) { + this.tend2 = tend2; + } + @Enumerated(EnumType.STRING) private Role role; @@ -65,12 +87,16 @@ public void passwordEncode(PasswordEncoder passwordEncoder) { } //==setter==// + public Long getRoomId() { + return roomId; + } - - public Long getId() { - return id; + public void setRoomId(Long roomId) { + this.roomId = roomId; } + + public void setId(Long id) { this.id = id; } @@ -145,6 +171,14 @@ public void setCompany(String company) { this.company = company; } + public Role getRole() { + return role; + } + + public void setRole(Role role) { + this.role = role; + } + //== 유저 필드 업데이트 ==// public void updateNickname(String updateNickname) { this.nickname = updateNickname; @@ -166,13 +200,6 @@ public void updateCompany(String updateCompany) { this.company = updateCompany; } - public Role getRole() { - return role; - } - - public void setRole(Role role) { - this.role = role; - } public void updatePassword(String updatePassword, PasswordEncoder passwordEncoder) { this.password = passwordEncoder.encode(updatePassword); diff --git a/src/main/java/mos/mosback/login/domain/user/conrtoller/UserProfileController.java b/src/main/java/mos/mosback/login/domain/user/conrtoller/UserProfileController.java index 16a88ce..4b403f1 100644 --- a/src/main/java/mos/mosback/login/domain/user/conrtoller/UserProfileController.java +++ b/src/main/java/mos/mosback/login/domain/user/conrtoller/UserProfileController.java @@ -1,5 +1,5 @@ package mos.mosback.login.domain.user.conrtoller; - +import mos.mosback.login.domain.user.User; import mos.mosback.login.domain.user.dto.UserProfileDto; import mos.mosback.login.domain.user.repository.UserRepository; import mos.mosback.login.domain.user.service.UserService; @@ -10,6 +10,10 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; + +import java.util.HashMap; +import java.util.Map; + @RestController @RequestMapping("/profile") public class UserProfileController { @@ -21,7 +25,6 @@ public class UserProfileController { private final UserService userService; private final UserRepository userRepository; - @Autowired public UserProfileController(UserService userService, UserRepository userRepository) { @@ -30,41 +33,76 @@ public UserProfileController(UserService userService, UserRepository userReposit } - @PostMapping - public ResponseEntity createUserProfile(@RequestBody UserProfileDto userProfileDto) throws Exception { - // 현재 로그인한 사용자의 정보 가져오기 - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - String currentEmail = authentication.getName(); // 현재 사용자의 이메일 - try{ - // 회원 정보 생성 - userService.createUser(currentEmail, userProfileDto); - - return ResponseEntity.ok("회원 정보가 생성되었습니다."); - } catch (Exception e){ + public Map createUserProfile(@RequestBody UserProfileDto userProfileDto) { + Map response = new HashMap<>(); + try { + // 현재 로그인한 사용자의 정보 가져오기 + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + String currentEmail = authentication.getName(); // 현재 사용자의 이메일 + + // 회원 정보 생성 + userService.createUser(currentEmail, userProfileDto); + + response.put("status", 200); + response.put("success", true); + response.put("message", "회원 정보가 생성되었습니다."); + } catch (Exception e) { e.printStackTrace(); // 이 코드는 예외의 스택 트레이스를 콘솔에 출력합니다. - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("오류가 발생했습니다."); + response.put("status", 500); + response.put("success", false); + response.put("message", "오류가 발생했습니다."); } - + return response; } + @PutMapping - public ResponseEntity updateUserProfile(@RequestBody UserProfileDto userProfileDto) throws Exception { + public Map updateUserProfile(@RequestBody UserProfileDto userProfileDto) throws Exception { // 현재 로그인한 사용자의 정보 가져오기 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String currentEmail = authentication.getName(); // 현재 사용자의 이메일 + Map response = new HashMap<>(); try{ - // 회원 정보 업데이트 - userService.updateUserProfile(currentEmail, userProfileDto); - - return ResponseEntity.ok("회원 정보가 업데이트되었습니다."); + // 회원 정보 업데이트 + userService.updateUserProfile(currentEmail, userProfileDto); + response.put("status", 200); + response.put("success", true); + response.put("message", "회원 정보가 업데이트되었습니다."); } catch (Exception e) { e.printStackTrace(); - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("오류가 발생했습니다."); - } + response.put("status", 500); + response.put("success", false); + response.put("message", "오류가 발생했습니다."); } + return response; + } + @GetMapping + public ResponseEntity> getUserProfile() { + Map response = new HashMap<>(); + try { + // 현재 로그인한 사용자의 정보 가져오기 + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + String currentEmail = authentication.getName(); // 현재 사용자의 이메일 -} + // 현재 사용자의 이메일을 이용하여 프로필 정보를 가져옵니다. + UserProfileDto userProfileDto = userService.getUserProfileByEmail(currentEmail); + + response.put("status", 200); + response.put("success", true); + response.put("data", userProfileDto); + // 프로필 정보를 클라이언트에 응답으로 반환합니다. + return ResponseEntity.ok(response); + } catch (Exception e) { + // 에러 발생 시 500 Internal Server Error 반환 + response.put("status", 500); + response.put("success", false); + response.put("message", "오류가 발생했습니다."); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); + } + } + +} diff --git a/src/main/java/mos/mosback/login/domain/user/dto/UserProfileDto.java b/src/main/java/mos/mosback/login/domain/user/dto/UserProfileDto.java index fc9f27d..44e53f7 100644 --- a/src/main/java/mos/mosback/login/domain/user/dto/UserProfileDto.java +++ b/src/main/java/mos/mosback/login/domain/user/dto/UserProfileDto.java @@ -1,19 +1,52 @@ package mos.mosback.login.domain.user.dto; import java.util.Date; + + import lombok.Getter; import lombok.NoArgsConstructor; +import org.springframework.stereotype.Component; + +import javax.persistence.Column; -import java.util.Date; @NoArgsConstructor @Getter +@Component public class UserProfileDto { - private String nickname; + @Column(nullable = false) + private String nickname; private String name; private Date str_duration; private Date end_duration; private String message; private String company; + private String tend1; + private String tend2; + private Long roomId; + + + public UserProfileDto(String nickname, String name, Date str_duration, + Date end_duration, String message, String company, String tend1, String tend2, Long roomId) { + this.nickname = nickname; + this.name = name; + this.str_duration = str_duration; + this.end_duration = end_duration; + this.message = message; + this.company = company; + this.roomId = roomId; + this.tend1 = tend1; + this.tend2= tend2; + + + } + public Long getRoomId() { + return roomId; + } + + public void setRoomId(Long roomId) { + this.roomId = roomId; + } + } diff --git a/src/main/java/mos/mosback/login/domain/user/service/UserService.java b/src/main/java/mos/mosback/login/domain/user/service/UserService.java index 5be242d..e1dd1d6 100644 --- a/src/main/java/mos/mosback/login/domain/user/service/UserService.java +++ b/src/main/java/mos/mosback/login/domain/user/service/UserService.java @@ -183,4 +183,24 @@ public Optional loadUserByUsername(String userEmail) throws UsernameNotFou } + public UserProfileDto getUserProfileByEmail(String email) throws Exception { + Optional optionalUser = userRepository.findByEmail(email); + if (optionalUser.isPresent()) { + User user = optionalUser.get(); + // 엔터티 정보를 DTO로 매핑하여 반환 + return new UserProfileDto( + user.getNickname(), + user.getName(), + user.getStr_duration(), + user.getEnd_duration(), + user.getMessage(), + user.getCompany(), + user.getTend1(), + user.getTend2(), + user.getRoomId() + ); + } else { + throw new Exception("해당 이메일의 사용자를 찾을 수 없습니다: " + email); + } + } } \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/controller/StRoomController.java b/src/main/java/mos/mosback/stRoom/controller/StRoomController.java index 155f855..0f73027 100644 --- a/src/main/java/mos/mosback/stRoom/controller/StRoomController.java +++ b/src/main/java/mos/mosback/stRoom/controller/StRoomController.java @@ -1,5 +1,8 @@ package mos.mosback.stRoom.controller; import lombok.RequiredArgsConstructor; +import mos.mosback.login.domain.user.dto.UserProfileDto; +import mos.mosback.login.domain.user.repository.UserRepository; +import mos.mosback.login.domain.user.service.UserService; import mos.mosback.stRoom.dto.*; import mos.mosback.stRoom.service.StRoomService; import mos.mosback.stRoom.service.ToDoService; @@ -21,7 +24,8 @@ public class StRoomController { private final StRoomService stRoomService; // stRoomService를 주입. private final ToDoService toDoService; - + private final UserService userService; + private final UserRepository userRepository; @PostMapping("/create") public ResponseEntity saveRoom(@RequestBody StRoomSaveRequestDto requestDto, HttpServletRequest req) { // 현재 로그인한 사용자의 정보 가져오기 @@ -137,6 +141,26 @@ public ResponseEntity getQuestionById(@PathVariable Long roomId) { } } + @GetMapping("/myPage/{memberId}") + public ResponseEntity> getUserProfile(@PathVariable Long memberId) { + Map response = new HashMap<>(); + try { + UserProfileDto userProfileDto = stRoomService.getMemberProfileById(memberId); + response.put("status", 200); + response.put("success", true); + response.put("data", userProfileDto); + + return ResponseEntity.ok(response); + } catch (Exception e) { + + response.put("status", 500); + response.put("success", false); + response.put("message", "오류가 발생했습니다."); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); + } + } + + @GetMapping("/QnA/{memberId}/{roomId}") public ResponseEntity getQuestionandAnswerById(@PathVariable("memberId") Long memberId, @PathVariable("roomId") Long roomId) { { @@ -174,7 +198,8 @@ public ResponseEntity acceptMember(@PathVariable Long roomId, return ResponseEntity.status(HttpStatus.CREATED).body ("message : Accepted successfully.\nstatus : 201\n success: true"); }catch (IllegalArgumentException ex){ - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("message : ServerError.ServerError.\nstatus : 500\n success: false"); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body("message : ServerError.ServerError.\nstatus : 500\n success: false"); } } @PostMapping("/reject/{roomId}") diff --git a/src/main/java/mos/mosback/stRoom/service/StRoomService.java b/src/main/java/mos/mosback/stRoom/service/StRoomService.java index 2fc25c7..ac97ffc 100644 --- a/src/main/java/mos/mosback/stRoom/service/StRoomService.java +++ b/src/main/java/mos/mosback/stRoom/service/StRoomService.java @@ -1,5 +1,7 @@ package mos.mosback.stRoom.service; import lombok.RequiredArgsConstructor; +import mos.mosback.login.domain.user.dto.UserProfileDto; +import mos.mosback.login.domain.user.repository.UserRepository; import mos.mosback.stRoom.domain.stRoom.MemberStatus; import mos.mosback.stRoom.domain.stRoom.StRoomEntity; import mos.mosback.stRoom.domain.stRoom.StudyMemberEntity; @@ -28,6 +30,7 @@ public class StRoomService { private final StudyMemberRepository studyMemberRepository; private final UserService userService; private final JwtService jwtService; + private final UserRepository userRepository; public Long save(StRoomSaveRequestDto requestDto, HttpServletRequest req) { try { @@ -189,7 +192,27 @@ public QuestionAndAnswerResponseDto getQuestionAndAnswerById(Long memberId, Long return responseDto; } - + public UserProfileDto getMemberProfileById(Long memberId) throws Exception { + + Optional optionalUser = userRepository.findById(memberId); + if (optionalUser.isPresent()) { + User user = optionalUser.get(); + // 엔터티 정보를 DTO로 매핑하여 반환 + return new UserProfileDto( + user.getNickname(), + user.getName(), + user.getStr_duration(), + user.getEnd_duration(), + user.getMessage(), + user.getCompany(), + user.getTend1(), + user.getTend2(), + user.getRoomId() + ); + } else { + throw new Exception("해당 이메일의 사용자를 찾을 수 없습니다: " + memberId); + } + } public String getMyInfo(String email) throws Exception { // 3. 사용자 이메일 조회해서 save 전에 주입 From 0261dc0b601a63136ddc94e28d60b91e9466db17 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Sat, 4 Nov 2023 22:42:50 +0900 Subject: [PATCH 47/60] =?UTF-8?q?=EC=8A=A4=ED=84=B0=EB=94=94=EB=A3=B8=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20-=20=EB=A9=A4=EB=B2=84=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EA=B5=AC=ED=98=84=EB=81=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 4 ++ .../mosback/configuration/SwaggerConfig.java | 36 ++++++++++ .../mos/mosback/login/domain/user/User.java | 1 - .../conrtoller/UserProfileController.java | 1 + .../domain/user/service/UserService.java | 65 +++++++++++++------ .../login/global/config/SecurityConfig.java | 5 +- .../JwtAuthenticationProcessingFilter.java | 10 +++ .../stRoom/controller/StRoomController.java | 54 ++++++++++++--- .../stRoom/controller/TodoController.java | 37 +++++++---- .../stRoom/MemberTodoRankProjection.java | 7 ++ .../stRoom/domain/stRoom/StRoomEntity.java | 3 + .../domain/stRoom/StudyMemberEntity.java | 1 + .../stRoom/dto/Home_RoomResponseDto.java | 5 +- .../stRoom/dto/MemberTodoRankResponseDto.java | 12 ++++ .../stRoom/dto/StRoomDetailResponseDto.java | 3 + .../dto/StRoomMemberJoinRequestDto.java | 1 - .../stRoom/dto/StRoomMemberResponseDto.java | 1 + .../mosback/stRoom/dto/StRoomResponseDto.java | 5 ++ .../stRoom/dto/StudyMemberHistoryDto.java | 10 +++ .../repository/MemberTodoRepository.java | 20 ++++-- .../mosback/stRoom/service/StRoomService.java | 28 ++++++-- .../mosback/stRoom/service/ToDoService.java | 45 +++++++++---- src/main/resources/application.yml | 6 +- 23 files changed, 292 insertions(+), 68 deletions(-) create mode 100644 src/main/java/mos/mosback/configuration/SwaggerConfig.java create mode 100644 src/main/java/mos/mosback/stRoom/domain/stRoom/MemberTodoRankProjection.java create mode 100644 src/main/java/mos/mosback/stRoom/dto/MemberTodoRankResponseDto.java create mode 100644 src/main/java/mos/mosback/stRoom/dto/StudyMemberHistoryDto.java diff --git a/build.gradle b/build.gradle index fa840fd..e67aeb6 100644 --- a/build.gradle +++ b/build.gradle @@ -70,4 +70,8 @@ dependencies { annotationProcessor('org.projectlombok:lombok:1.18.20') testImplementation('org.projectlombok:lombok:1.18.20') testAnnotationProcessor('org.projectlombok:lombok:1.18.20') + + // build.gradle 적용 + implementation 'io.springfox:springfox-swagger2:2.9.2' + implementation 'io.springfox:springfox-swagger-ui:2.9.2' } \ No newline at end of file diff --git a/src/main/java/mos/mosback/configuration/SwaggerConfig.java b/src/main/java/mos/mosback/configuration/SwaggerConfig.java new file mode 100644 index 0000000..632608f --- /dev/null +++ b/src/main/java/mos/mosback/configuration/SwaggerConfig.java @@ -0,0 +1,36 @@ +package mos.mosback.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +@Configuration +@EnableSwagger2 +public class SwaggerConfig implements WebMvcConfigurer { + private ApiInfo apiInfo() { + + return new ApiInfoBuilder() + .title("Demo") + .description("API EXAMPLE") + .build(); + } + + @Bean + public Docket commonApi() { + return new Docket(DocumentationType.SWAGGER_2) + .groupName("example") + .apiInfo(this.apiInfo()) + .select() + .apis(RequestHandlerSelectors + .basePackage("mos.mosback")) + .paths(PathSelectors.ant("/**")) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/login/domain/user/User.java b/src/main/java/mos/mosback/login/domain/user/User.java index 3bb37e5..4988912 100644 --- a/src/main/java/mos/mosback/login/domain/user/User.java +++ b/src/main/java/mos/mosback/login/domain/user/User.java @@ -36,7 +36,6 @@ public class User { private String nickname; // 닉네임 - @Column(name = "image_url") private String imageUrl; // 프로필 이미지 private Date str_duration; diff --git a/src/main/java/mos/mosback/login/domain/user/conrtoller/UserProfileController.java b/src/main/java/mos/mosback/login/domain/user/conrtoller/UserProfileController.java index 4b403f1..9efa878 100644 --- a/src/main/java/mos/mosback/login/domain/user/conrtoller/UserProfileController.java +++ b/src/main/java/mos/mosback/login/domain/user/conrtoller/UserProfileController.java @@ -1,4 +1,5 @@ package mos.mosback.login.domain.user.conrtoller; + import mos.mosback.login.domain.user.User; import mos.mosback.login.domain.user.dto.UserProfileDto; import mos.mosback.login.domain.user.repository.UserRepository; diff --git a/src/main/java/mos/mosback/login/domain/user/service/UserService.java b/src/main/java/mos/mosback/login/domain/user/service/UserService.java index e1dd1d6..7188e63 100644 --- a/src/main/java/mos/mosback/login/domain/user/service/UserService.java +++ b/src/main/java/mos/mosback/login/domain/user/service/UserService.java @@ -62,7 +62,7 @@ public User getUserByEmail(String email) throws Exception { } //마이페이지정보입력 - public void createUser(String currentEmail, UserProfileDto userProfileDto) throws Exception { + public void roomId(String currentEmail, UserProfileDto userProfileDto) throws Exception { if (userRepository.findByNickname(userProfileDto.getNickname()).isPresent()) { throw new Exception("이미 존재하는 닉네임입니다."); } @@ -84,24 +84,6 @@ public void createUser(String currentEmail, UserProfileDto userProfileDto) throw } } - //마이페이지 업데이트 - public void updateUserProfile(String currentEmail, UserProfileDto userProfileDto) throws Exception { - try { - User user = getUserByEmail(currentEmail); - - // 회원 정보 업데이트 - user.setNickname(userProfileDto.getNickname()); - user.setStr_duration(userProfileDto.getStr_duration()); - user.setEnd_duration(userProfileDto.getEnd_duration()); - user.setMessage(userProfileDto.getMessage()); - user.setCompany(userProfileDto.getCompany()); - - userRepository.save(user); - } catch (Exception e) { - throw new Exception("회원 정보를 업데이트하는 동안 오류가 발생했습니다.", e); - } - } - public void upadateUserPassword(String currentEmail, UserSignUpDto userSignUpDto) throws Exception{ try { User user = getUserByEmail(currentEmail); @@ -203,4 +185,49 @@ public UserProfileDto getUserProfileByEmail(String email) throws Exception { throw new Exception("해당 이메일의 사용자를 찾을 수 없습니다: " + email); } } + public void createUser(String currentEmail, UserProfileDto userProfileDto) throws Exception { + if (userRepository.findByNickname(userProfileDto.getNickname()).isPresent()) { + throw new Exception("이미 존재하는 닉네임입니다."); + } + + try { + User user = getUserByEmail(currentEmail); + + // 회원 정보 생성 + user.setNickname(userProfileDto.getNickname()); + user.setName(userProfileDto.getName()); + user.setStr_duration(userProfileDto.getStr_duration()); + user.setEnd_duration(userProfileDto.getEnd_duration()); + user.setMessage(userProfileDto.getMessage()); + user.setCompany(userProfileDto.getCompany()); + user.setTend1(userProfileDto.getTend1()); + user.setTend2(userProfileDto.getTend2()); + user.setRole(Role.USER); + userRepository.save(user); + } catch (Exception e) { + throw new Exception("회원 정보를 생성하는 동안 오류가 발생했습니다.", e); + } + } + + //마이페이지 업데이트 + public void updateUserProfile(String currentEmail, UserProfileDto userProfileDto) throws Exception { + try { + User user = getUserByEmail(currentEmail); + + // 회원 정보 업데이트 + user.setNickname(userProfileDto.getNickname()); + user.setName(userProfileDto.getName()); + user.setStr_duration(userProfileDto.getStr_duration()); + user.setEnd_duration(userProfileDto.getEnd_duration()); + user.setMessage(userProfileDto.getMessage()); + user.setCompany(userProfileDto.getCompany()); + user.setTend1(userProfileDto.getTend1()); + user.setTend2(userProfileDto.getTend2()); + user.setRoomId(userProfileDto.getRoomId()); + userRepository.save(user); + } catch (Exception e) { + throw new Exception("회원 정보를 업데이트하는 동안 오류가 발생했습니다.", e); + } + } + } \ No newline at end of file diff --git a/src/main/java/mos/mosback/login/global/config/SecurityConfig.java b/src/main/java/mos/mosback/login/global/config/SecurityConfig.java index b8c310c..cbcec3c 100644 --- a/src/main/java/mos/mosback/login/global/config/SecurityConfig.java +++ b/src/main/java/mos/mosback/login/global/config/SecurityConfig.java @@ -65,7 +65,10 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .antMatchers("/sign-up","/studyRoom/create","/studyRoom/update/{roomId}","/studyRoom/{roomId}", "/todo/add","/todo/update{todoId}","/todo/delete/{todoId}","/todo/{todoId}","/member/todo/add" , "/studyRoom/all","/studyRoom/search","/studyRoom/byCategory/{category}","/studyRoom/recruiting", - "/recruitInfo/{roomId}").permitAll() // 회원가입 접근 가능 + "/recruitInfo/{roomId}", + "/swagger-ui.html", "/webjars/**", "/v2/**", + "/webjars/springfox-swagger-ui/**", "/swagger-resources/**", + "/swagger-ui/", "/swagger-ui/**", "/csrf").permitAll() // 회원가입 접근 가능 .anyRequest().authenticated() // 위의 경로 이외에는 모두 인증된 사용자만 접근 가능 .and() //== 소셜 로그인 설정 ==// diff --git a/src/main/java/mos/mosback/login/global/jwt/filter/JwtAuthenticationProcessingFilter.java b/src/main/java/mos/mosback/login/global/jwt/filter/JwtAuthenticationProcessingFilter.java index 52fc4da..534dc19 100644 --- a/src/main/java/mos/mosback/login/global/jwt/filter/JwtAuthenticationProcessingFilter.java +++ b/src/main/java/mos/mosback/login/global/jwt/filter/JwtAuthenticationProcessingFilter.java @@ -46,6 +46,11 @@ public class JwtAuthenticationProcessingFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + if (request.getRequestURI().startsWith("/swagger-ui")) { + // Swagger는 필터 적용 X + filterChain.doFilter(request, response); // "/login" 요청이 들어오면, 다음 필터 호출 + return; + } if (request.getRequestURI().equals(NO_CHECK_URL)) { filterChain.doFilter(request, response); // "/login" 요청이 들어오면, 다음 필터 호출 return; // return으로 이후 현재 필터 진행 막기 (안해주면 아래로 내려가서 계속 필터 진행시킴) @@ -114,6 +119,11 @@ private String reIssueRefreshToken(User user) { public void checkAccessTokenAndAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { log.info("checkAccessTokenAndAuthentication() 호출"); + if (request.getRequestURI().startsWith("/swagger-ui")) { + // Swagger는 필터 적용 X + filterChain.doFilter(request, response); // "/login" 요청이 들어오면, 다음 필터 호출 + return; + } jwtService.extractAccessToken(request) .filter(jwtService::isTokenValid) .ifPresent(accessToken -> jwtService.extractEmail(accessToken) diff --git a/src/main/java/mos/mosback/stRoom/controller/StRoomController.java b/src/main/java/mos/mosback/stRoom/controller/StRoomController.java index 0f73027..8faad70 100644 --- a/src/main/java/mos/mosback/stRoom/controller/StRoomController.java +++ b/src/main/java/mos/mosback/stRoom/controller/StRoomController.java @@ -1,8 +1,9 @@ package mos.mosback.stRoom.controller; +import io.swagger.annotations.ApiImplicitParam; import lombok.RequiredArgsConstructor; +import mos.mosback.login.domain.user.User; import mos.mosback.login.domain.user.dto.UserProfileDto; -import mos.mosback.login.domain.user.repository.UserRepository; -import mos.mosback.login.domain.user.service.UserService; +import mos.mosback.stRoom.domain.stRoom.MemberStatus; import mos.mosback.stRoom.dto.*; import mos.mosback.stRoom.service.StRoomService; import mos.mosback.stRoom.service.ToDoService; @@ -16,6 +17,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; @RequiredArgsConstructor @RestController @@ -24,8 +27,7 @@ public class StRoomController { private final StRoomService stRoomService; // stRoomService를 주입. private final ToDoService toDoService; - private final UserService userService; - private final UserRepository userRepository; + @PostMapping("/create") public ResponseEntity saveRoom(@RequestBody StRoomSaveRequestDto requestDto, HttpServletRequest req) { // 현재 로그인한 사용자의 정보 가져오기 @@ -36,16 +38,26 @@ public ResponseEntity saveRoom(@RequestBody StRoomSaveRequestDto request if (stroomId != null) { return ResponseEntity.status(HttpStatus.CREATED).body ("message: created successfully. ID:" + stroomId +"\nsuccess:true \nstatus:201"); + } else { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body ("message: Bad Request \nsuccess:false \nstatus:400"); } } @GetMapping("/my{roomId}") - public ResponseEntity FindByID (@PathVariable Long roomId) { + public ResponseEntity FindByID (@PathVariable Long roomId) { + + StRoomResponseDto stroom = stRoomService.findById(roomId); + List studyRoomMemberList = stRoomService.getStudyRoomMemberList(roomId); + StRoomMemberResponseDto leaderInfo = studyRoomMemberList.stream() + .filter(data -> MemberStatus.Leader.name().equals(data.getStatus().name())) + .findFirst().orElseThrow(() -> new EntityNotFoundException("leader info not found")); + User leaderUser = stRoomService .getUserInfo(leaderInfo.getMemberId()); + stroom.setNickname(leaderUser.getNickname()); + stroom.setMemberNum(studyRoomMemberList.size()); + + return new ResponseEntity<>(stroom,HttpStatus.OK); - StRoomResponseDto stroom = stRoomService.findById(roomId); - return new ResponseEntity<>(stroom, HttpStatus.OK); } @GetMapping("/search") @@ -105,6 +117,7 @@ public ResponseEntity> getPopularRooms() { @GetMapping("/home/studyRoom") public ResponseEntity> findRoomsInHome(){ List roomsInhome = stRoomService.findRoomsInHome(); + return new ResponseEntity<>(roomsInhome,HttpStatus.OK); } @@ -189,6 +202,7 @@ public ResponseEntity memberJoin(@PathVariable Long roomId, return ResponseEntity.status(HttpStatus.CREATED).body ("message : joined successfully.\nstatus : 201\n success: true"); } + @PostMapping("/accept/{roomId}") public ResponseEntity acceptMember(@PathVariable Long roomId, @RequestBody AcceptMemberRequestDto requestDto) { @@ -207,7 +221,7 @@ public ResponseEntity rejectMember(@PathVariable Long roomId, @RequestBody AcceptMemberRequestDto requestDto) { try { requestDto.setRoomId(roomId); - stRoomService.rejecttMember(requestDto); + stRoomService.rejectMember(requestDto); return ResponseEntity.status(HttpStatus.CREATED).body ("message : Rejected successfully.\nstatus : 201\n success: true"); }catch (IllegalArgumentException ex){ @@ -250,12 +264,36 @@ public ResponseEntity> getMyInfo() throws Exception { return ResponseEntity.status(HttpStatus.CREATED).body(response); } + /** + * 스터디 가입여부를 조회하는 API + * @return + */ + @GetMapping("/my-study-member-history") + public ResponseEntity> getMyStudyMemberHistory() throws Exception { + // 현재 로그인한 사용자의 정보 가져오기 + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + String email = authentication.getName(); // 현재 사용자의 이메일 + List memberHistoryList = stRoomService.getMyStudyMemberHistory(email); + Map response = new HashMap<>(); + response.put("memberHistoryList", memberHistoryList); + response.put("success", true); + + return ResponseEntity.status(HttpStatus.CREATED).body(response); + } + @GetMapping("/Info/{roomId}") + @ApiImplicitParam(name = "Authorization", value = "Access Token", required = true, allowEmptyValue = false, paramType = "header", example = "Bearer access_token") public ResponseEntity> recruitInfo(@PathVariable Long roomId) { String recruitInfo = stRoomService.isRecruiting(roomId); StRoomDetailResponseDto stroom = stRoomService.findByRoomId(roomId); List todoList = toDoService.findStRoomTodoByRoomId(roomId); List studyRoomMemberList = stRoomService.getStudyRoomMemberList(roomId); + StRoomMemberResponseDto leaderInfo = studyRoomMemberList.stream() + .filter(data -> MemberStatus.Leader.name().equals(data.getStatus().name())) + .findFirst().orElseThrow(() -> new EntityNotFoundException("leader info not found")); + User leaderUser = stRoomService.getUserInfo(leaderInfo.getMemberId()); + stroom.setNickname(leaderUser.getNickname()); + stroom.setMemberNum(studyRoomMemberList.size()); Map response = new HashMap<>(); response.put("모집", recruitInfo); diff --git a/src/main/java/mos/mosback/stRoom/controller/TodoController.java b/src/main/java/mos/mosback/stRoom/controller/TodoController.java index 37d9186..fea4ce1 100644 --- a/src/main/java/mos/mosback/stRoom/controller/TodoController.java +++ b/src/main/java/mos/mosback/stRoom/controller/TodoController.java @@ -1,11 +1,8 @@ package mos.mosback.stRoom.controller; import mos.mosback.stRoom.domain.stRoom.StudyMemberTodoEntity; import mos.mosback.stRoom.domain.stRoom.ToDoEntity; +import mos.mosback.stRoom.dto.*; import mos.mosback.stRoom.service.ToDoService; -import mos.mosback.stRoom.dto.StRoomToDoResponseDto; -import mos.mosback.stRoom.dto.StudyMemberRoomInfoResponseDto; -import mos.mosback.stRoom.dto.stRoomToDoRequestDto; -import mos.mosback.stRoom.dto.StudyMemberToDoRequestDto; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -44,12 +41,18 @@ public ResponseEntity addTodo(@RequestBody stRoomToDoRequestDto requestD } @PostMapping("/member/todo/add") public ResponseEntity addMemberTodo(@RequestBody StudyMemberToDoRequestDto requestDto) throws Exception{ - // 현재 로그인한 사용자의 정보 가져오기 + try { // 현재 로그인한 사용자의 정보 가져오기 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String currentEmail = authentication.getName(); // 현재 사용자의 이메일 requestDto.setCurrentEmail(currentEmail); StudyMemberTodoEntity todo = toDoService.addMemberTodo(requestDto); return ResponseEntity.status(HttpStatus.CREATED).body("TodoList 추가 완료. index : " +todo.getIdx()); + }catch (IllegalArgumentException ex){ + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body("ServerError"+ + "\nstatus:500" + + "\nsuccess:false"); + } } //todo개수만큼 프론트에서 호출해줘야함 // @@ -71,18 +74,18 @@ public ResponseEntity updateTodo(@PathVariable Long todoId, @RequestBody } } - @PutMapping("/member/todo/{todoId}") - public ResponseEntity updateMemberTodo(@PathVariable Long todoId, + @PutMapping("/member/todo/{todoIdx}") + public ResponseEntity updateMemberTodo(@PathVariable Long todoIdx, @RequestBody StudyMemberToDoRequestDto requestDto) throws Exception { // 현재 로그인한 사용자의 정보 가져오기 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String currentEmail = authentication.getName(); // 현재 사용자의 이메일 requestDto.setCurrentEmail(currentEmail); try { - StudyMemberTodoEntity updatedToDo = toDoService.updateMemberTodo(todoId, requestDto.getTodoContent(), + StudyMemberTodoEntity updatedToDo = toDoService.updateMemberTodo(todoIdx, requestDto.getTodoContent(), requestDto.getStatus(), currentEmail); return ResponseEntity.ok - ("Study Member ToDo 업데이트 완료. \nIndex: " + todoId + + ("Study Member ToDo 업데이트 완료. \nIndex: " + todoIdx + "\nstatus:200" + "\nsuccess:true"); } catch (IllegalArgumentException e) { @@ -109,15 +112,15 @@ public ResponseEntity deleteTodo(@PathVariable Long todoId) { } } - @DeleteMapping("/member/todo/{todoId}") - public ResponseEntity deleteMemberTodo(@PathVariable Long todoId) throws Exception{ + @DeleteMapping("/member/todo/{todoIdx}") + public ResponseEntity deleteMemberTodo(@PathVariable Long todoIdx) throws Exception{ // 현재 로그인한 사용자의 정보 가져오기 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String currentEmail = authentication.getName(); // 현재 사용자의 이메일 try { - toDoService.deleteMemberTodo(todoId, currentEmail); + toDoService.deleteMemberTodo(todoIdx, currentEmail); return ResponseEntity.ok - ("Study Member ToDo 삭제 완료. Index: " + todoId+ + ("Study Member ToDo 삭제 완료. Index: " + todoIdx+ "\nstatus:200" + "\nsuccess:true"); } catch (IllegalArgumentException e) { @@ -144,5 +147,13 @@ public ResponseEntity getMemberRoomInfo(@PathVar return new ResponseEntity<>(todo, HttpStatus.OK); } + @GetMapping("/todoRank/{roomId}") + public ResponseEntity> getMemberTodoRank(@PathVariable Long roomId) throws Exception { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + String currentEmail = authentication.getName(); // 현재 사용자의 이메일 + List todoList = toDoService.getMemberTodoProgress(roomId, currentEmail); + return new ResponseEntity<>(todoList, HttpStatus.OK); + } + } \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/domain/stRoom/MemberTodoRankProjection.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/MemberTodoRankProjection.java new file mode 100644 index 0000000..75e697c --- /dev/null +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/MemberTodoRankProjection.java @@ -0,0 +1,7 @@ +package mos.mosback.stRoom.domain.stRoom; + +public interface MemberTodoRankProjection { + Long getMemberId(); + double getProgress(); + String getNickname(); +} diff --git a/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomEntity.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomEntity.java index 2cc2a8e..d055f33 100644 --- a/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomEntity.java +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomEntity.java @@ -32,12 +32,15 @@ public class StRoomEntity extends BaseTimeEntity { private String intro; //스터디 소개 private int memberNum; //현재 멤버수 private int maxMember; //모집 멤버수 + @Column(nullable = false) private String mod; //스터디 분위기 private int click;// 클릭횟수 (인기순 조회) private boolean onOff; //진행방식 (온오프) private String location; private int online; //온라인 + @Column(nullable = false) private LocalDate startDate; //스터디 시작 날짜 + @Column(nullable = false) private LocalDate endDate; //스터디 끝나는 날짜 private boolean recruiting; //모집여부 private LocalDate deadline; // 모집 마감날짜 diff --git a/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberEntity.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberEntity.java index 438a2a0..8aab433 100644 --- a/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberEntity.java +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberEntity.java @@ -31,4 +31,5 @@ public class StudyMemberEntity implements Serializable { + } diff --git a/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java index ee426b8..cf3273e 100644 --- a/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java @@ -1,10 +1,11 @@ package mos.mosback.stRoom.dto; import lombok.Getter; +import lombok.Setter; import mos.mosback.stRoom.domain.stRoom.StRoomEntity; import java.time.LocalDate; - +@Setter @Getter public class Home_RoomResponseDto { @@ -28,6 +29,6 @@ public Home_RoomResponseDto(StRoomEntity entity) { this.category = entity.getCategory(); this.memberNum = entity.getMemberNum(); this.maxMember = entity.getMaxMember(); - } + } diff --git a/src/main/java/mos/mosback/stRoom/dto/MemberTodoRankResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/MemberTodoRankResponseDto.java new file mode 100644 index 0000000..eb1c0f4 --- /dev/null +++ b/src/main/java/mos/mosback/stRoom/dto/MemberTodoRankResponseDto.java @@ -0,0 +1,12 @@ +package mos.mosback.stRoom.dto; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class MemberTodoRankResponseDto { + private String nickname; + private double progress; + +} diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java index 3b9dcb4..756878b 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java @@ -1,11 +1,13 @@ package mos.mosback.stRoom.dto; import lombok.Getter; +import lombok.Setter; import mos.mosback.stRoom.domain.stRoom.StRoomEntity; import mos.mosback.stRoom.domain.stRoom.StudyDaysEntity; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; @Getter +@Setter public class StRoomDetailResponseDto { private Long roomId; private String title; @@ -23,6 +25,7 @@ public class StRoomDetailResponseDto { private String intro; private LocalDateTime createdDate; private LocalDate deadline; + private String nickname; public StRoomDetailResponseDto(StRoomEntity entity) { diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomMemberJoinRequestDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomMemberJoinRequestDto.java index c79d16b..7f53f6f 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomMemberJoinRequestDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomMemberJoinRequestDto.java @@ -10,5 +10,4 @@ public class StRoomMemberJoinRequestDto { private Long roomId; private String answer; private String email; - } diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomMemberResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomMemberResponseDto.java index 7dce757..3676c44 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomMemberResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomMemberResponseDto.java @@ -7,4 +7,5 @@ public class StRoomMemberResponseDto { private Long memberId; private MemberStatus status; + } diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java index 2bbb6fc..1b47c42 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java @@ -1,5 +1,6 @@ package mos.mosback.stRoom.dto; import lombok.Getter; +import lombok.Setter; import mos.mosback.stRoom.domain.stRoom.StRoomEntity; import mos.mosback.stRoom.domain.stRoom.StudyDaysEntity; @@ -7,6 +8,7 @@ import java.util.List; +@Setter @Getter public class StRoomResponseDto { Long roomId; @@ -20,6 +22,7 @@ public class StRoomResponseDto { private LocalDate startDate; //스터디 시작 날짜 private LocalDate endDate; //스터디 끝나는 날짜 private List studyDayEntities; + private String nickname; /*유저프로필 + 사진*/ @@ -39,6 +42,8 @@ public StRoomResponseDto(StRoomEntity entity) { } //스터디 + 투두 리스트의 스터디룸 상세화면 + + } //Entity의 필드 이루만 사용하므로 생성자로 Entity를 받아 필드에 값을 넣어줌 //상세정보에 노출 될 필드 \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/dto/StudyMemberHistoryDto.java b/src/main/java/mos/mosback/stRoom/dto/StudyMemberHistoryDto.java new file mode 100644 index 0000000..34a6419 --- /dev/null +++ b/src/main/java/mos/mosback/stRoom/dto/StudyMemberHistoryDto.java @@ -0,0 +1,10 @@ +package mos.mosback.stRoom.dto; + +import lombok.Data; +import mos.mosback.stRoom.domain.stRoom.MemberStatus; + +@Data +public class StudyMemberHistoryDto { + private MemberStatus status; // 스터디 상태 + private String title; // 스터디 제목 +} diff --git a/src/main/java/mos/mosback/stRoom/repository/MemberTodoRepository.java b/src/main/java/mos/mosback/stRoom/repository/MemberTodoRepository.java index bb4a5ca..6178761 100644 --- a/src/main/java/mos/mosback/stRoom/repository/MemberTodoRepository.java +++ b/src/main/java/mos/mosback/stRoom/repository/MemberTodoRepository.java @@ -1,6 +1,6 @@ package mos.mosback.stRoom.repository; +import mos.mosback.stRoom.domain.stRoom.MemberTodoRankProjection; import mos.mosback.stRoom.domain.stRoom.StudyMemberTodoEntity; -import mos.mosback.stRoom.domain.stRoom.StudyMemberTodoKey; import mos.mosback.stRoom.dto.StudyRoomTodoInfoDto; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; @@ -12,14 +12,24 @@ public interface MemberTodoRepository extends JpaRepository{ - @Query(value = "SELECT * FROM STUDY_MEMBER_TODO_ENTITY WHERE roomId = :roomId AND memberId = :memberId", nativeQuery = true) - List findAllByStRoom(@Param("roomId") Long roomId, @Param("memberId") Long memberId); + @Query(value = "SELECT * FROM STUDY_MEMBER_TODO_ENTITY WHERE room_id = :roomId AND memberID = :memberID", nativeQuery = true) + List findAllByStRoom(@Param("roomId") Long roomId, @Param("memberID") Long memberID); @Query(value = "SELECT * FROM (\n" + - "SELECT COUNT(*) AS totalCount FROM STU where roomId = :roomId \n" + + "SELECT COUNT(*) AS totalCount FROM STUDY_MEMBER_TODO_ENTITY where room_id = :roomId \n" + ") A, (\n" + - "SELECT COUNT(*) AS completedCount FROM STUDY_MEMBER_TODO_ENTITY where roomId = :roomId AND status = 'Completed'\n" + + "SELECT COUNT(*) AS completedCount FROM STUDY_MEMBER_TODO_ENTITY where room_id = :roomId AND status = 'Completed'\n" + ") B", nativeQuery = true) StudyRoomTodoInfoDto getStudyRoomTodoAverage(@Param("roomId") Long roomId); + @Query(value = "SELECT MEMBERID AS memberId, ROUND((SUM(CASE WHEN STATUS = 'Completed' THEN 1.0 ELSE 0.0 END) / COUNT(*)) * 100) AS progress " + + "FROM STUDY_MEMBER_TODO_ENTITY " + + "WHERE STATUS IN ('Completed', 'Waiting') AND ROOM_ID = :roomId " + + "GROUP BY MEMBERID ORDER BY progress DESC", nativeQuery = true) + + List getRankByStRoom(@Param("roomId") Long roomId); + + + + Optional findByMemberIdAndTodoContent(Long id, String todoContent); } diff --git a/src/main/java/mos/mosback/stRoom/service/StRoomService.java b/src/main/java/mos/mosback/stRoom/service/StRoomService.java index ac97ffc..eaccdc4 100644 --- a/src/main/java/mos/mosback/stRoom/service/StRoomService.java +++ b/src/main/java/mos/mosback/stRoom/service/StRoomService.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; @RequiredArgsConstructor @@ -47,9 +48,6 @@ public Long save(StRoomSaveRequestDto requestDto, HttpServletRequest req) { String loginUserEmail = Optional.ofNullable(jwtService.extractEmail(accessToken)).get().orElse(""); User user = userService.getUserByEmail(loginUserEmail); - // 4. 정보 대입 -// user.getStRooms().add(stRoom); -// stRoom.setMemberNum(1); // 5. Study Member 저장 studyMember.setMemberId(user.getId()); @@ -152,6 +150,7 @@ public void memberJoin(StRoomMemberJoinRequestDto requestDto) { studyMember.setStatus(MemberStatus.Waiting); studyMember.setAnswer(requestDto.getAnswer()); studyMemberRepository.save(studyMember); + } catch (Exception e) { e.printStackTrace(); } @@ -223,6 +222,7 @@ public String getMyInfo(String email) throws Exception { // study member 가입이력이 있다면 "Y" , 없으면 "N" return !memberJoinList.isEmpty() ? "Y" : "N"; } + public String isRecruiting(Long roomId) { Optional optionalRoom = stRoomRepository.findById(roomId); StRoomEntity stRoom = optionalRoom.get(); @@ -248,7 +248,7 @@ public void acceptMember(AcceptMemberRequestDto requestDto){ studyMemberRepository.save(studyMember); } - public void rejecttMember(AcceptMemberRequestDto requestDto){ + public void rejectMember(AcceptMemberRequestDto requestDto){ // 1. save할 변수 선언 StudyMemberEntity studyMember = new StudyMemberEntity(); @@ -277,4 +277,24 @@ public List getStudyRoomMemberList(Long roomId) { return memberList; } + public User getUserInfo(Long memberId) { + return userRepository.findById(memberId).orElseThrow(() -> new EntityNotFoundException("user info not found")); + } + + public List getMyStudyMemberHistory(String email) throws Exception { + // 3. 사용자 이메일 조회해서 save 전에 주입 + User user = userService.getUserByEmail(email); + List memberJoinList = studyMemberRepository.findAllByMemberId(user.getId()); + memberJoinList = memberJoinList.stream() + .filter(data -> !data.getStatus().equals(MemberStatus.Leader)) + .collect(Collectors.toList()); + List result = new ArrayList<>(); + for (StudyMemberEntity item : memberJoinList) { + StudyMemberHistoryDto data = new StudyMemberHistoryDto(); + data.setTitle(item.getStRoom().getTitle()); + data.setStatus(item.getStatus()); + result.add(data); + } + return result; + } } \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/service/ToDoService.java b/src/main/java/mos/mosback/stRoom/service/ToDoService.java index 0ab20db..18a5092 100644 --- a/src/main/java/mos/mosback/stRoom/service/ToDoService.java +++ b/src/main/java/mos/mosback/stRoom/service/ToDoService.java @@ -1,6 +1,7 @@ package mos.mosback.stRoom.service; import lombok.RequiredArgsConstructor; import mos.mosback.login.domain.user.User; +import mos.mosback.login.domain.user.repository.UserRepository; import mos.mosback.login.domain.user.service.UserService; import mos.mosback.stRoom.domain.stRoom.*; import mos.mosback.stRoom.dto.*; @@ -24,6 +25,9 @@ public class ToDoService { private final StRoomRepository stRoomRepository; private final MemberTodoRepository studyMemberToDoRepository; private final UserService userService; + private final StRoomService stRoomService; + private final UserRepository userRepository; + @Transactional public ToDoEntity addTodo(stRoomToDoRequestDto requestDto, Long roomId) { @@ -49,11 +53,9 @@ public ToDoEntity updateTodo(Long todoId, String todoContent,TodoStatus status) @Transactional - public StudyMemberTodoEntity updateMemberTodo(Long todoId, String todoContent, TodoStatus status, String currentEmail) throws Exception { - ToDoEntity toDoEntity = toDoRepository.findById(todoId) - .orElseThrow(() -> new IllegalArgumentException("해당 ToDo를 찾을 수 없습니다.")); + public StudyMemberTodoEntity updateMemberTodo(Long todoIdx, String todoContent, TodoStatus status, String currentEmail) throws Exception { User user = userService.getUserByEmail(currentEmail); - StudyMemberTodoEntity studyMemberTodoEntity = studyMemberToDoRepository.findByMemberIdAndTodoContent(user.getId(), toDoEntity.getTodoContent()) + StudyMemberTodoEntity studyMemberTodoEntity = studyMemberToDoRepository.findById(todoIdx) .orElseThrow(() -> new IllegalArgumentException("해당 ToDo를 찾을 수 없습니다.")); studyMemberTodoEntity.update(todoContent, status); @@ -69,12 +71,10 @@ public void deleteTodo(Long todoId) { } @Transactional - public void deleteMemberTodo(Long todoId, String currentEmail) throws Exception { - ToDoEntity toDoEntity = toDoRepository.findById(todoId) - .orElseThrow(() -> new IllegalArgumentException("해당 ToDo를 찾을 수 없습니다.")); + public void deleteMemberTodo(Long todoIdx, String currentEmail) throws Exception { User user = userService.getUserByEmail(currentEmail); - StudyMemberTodoEntity studyMemberTodoEntity = studyMemberToDoRepository.findByMemberIdAndTodoContent(user.getId(), toDoEntity.getTodoContent()) - .orElseThrow(() -> new IllegalArgumentException("해당 Study Member ToDo를 찾을 수 없습니다.")); + StudyMemberTodoEntity studyMemberTodoEntity = studyMemberToDoRepository.findById(todoIdx) + .orElseThrow(() -> new IllegalArgumentException("해당 ToDo를 찾을 수 없습니다.")); studyMemberToDoRepository.delete(studyMemberTodoEntity); } @@ -125,17 +125,16 @@ public StudyMemberRoomInfoResponseDto getMemberRoomInfo(Long roomId, String curr / (double) studyRoomTodoAverage.getTotalCount()) * 100; } List roomDayList = new ArrayList<>(); - Date now = new Date(); - + Date now; Calendar cal1 = Calendar.getInstance(); - now = new Date(cal1.getTimeInMillis()); - for (int i=0; i<7; i++) { StudyRoomDayDto dayDto = new StudyRoomDayDto(); + now = new Date(cal1.getTimeInMillis()); dayDto.setDate(now); // 날짜 객체 셋팅 dayDto.setDayVal(cal1.get(Calendar.DATE)); // 날짜 셋팅 dayDto.setDayOfWeek(getDayOfKoreanWeek(cal1.get(Calendar.DAY_OF_WEEK))); // "월"~"일" 셋팅 + roomDayList.add(dayDto); cal1.add(Calendar.DATE, 1); // 일 계산 하루씩 추가 } @@ -166,4 +165,24 @@ private String getDayOfKoreanWeek(int i) { return ""; } } + + public List getMemberTodoProgress(Long roomId,String currentEmail) throws Exception { + List progressList = new ArrayList<>(); + List progressProjections = studyMemberToDoRepository.getRankByStRoom(roomId); + List memberList = stRoomService.getStudyRoomMemberList(roomId); + + + for (MemberTodoRankProjection progressProjection : progressProjections) { + User user = stRoomService.getUserInfo(progressProjection.getMemberId()); + + MemberTodoRankResponseDto progress = new MemberTodoRankResponseDto(); + progress.setProgress(progressProjection.getProgress()); + progress.setNickname(user.getNickname()); + progressList.add(progress); + } + + + return progressList; + } + } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index eb92159..2896985 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -9,7 +9,9 @@ spring: config: activate: on-profile: "local" - + mvc: + pathmatch: + matching-strategy: ant_path_matcher h2: console: enabled: true @@ -29,6 +31,7 @@ spring: jpa: show-sql: true + defer-datasource-initialization: true database-platform: org.hibernate.dialect.H2Dialect properties: hibernate: @@ -38,6 +41,7 @@ spring: hibernate: ddl-auto: create + mail: host: smtp.naver.com # 이메일 서버 호스트 (Gmail 사용 예) port: 587 # SMTP 포트 (Gmail의 경우 465 또는 587) From 4d3eb5aa1c18eb97a84242af0c5e1d5e4974d9dc Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Sun, 5 Nov 2023 15:43:49 +0900 Subject: [PATCH 48/60] =?UTF-8?q?=EC=8A=A4=ED=84=B0=EB=94=94=EB=A3=B8=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20-=20=EB=A9=A4=EB=B2=84=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EA=B5=AC=ED=98=84=EB=81=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/mos/mosback/login/domain/user/User.java | 3 ++- .../login/domain/user/conrtoller/UserProfileController.java | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/mos/mosback/login/domain/user/User.java b/src/main/java/mos/mosback/login/domain/user/User.java index 4988912..897b57d 100644 --- a/src/main/java/mos/mosback/login/domain/user/User.java +++ b/src/main/java/mos/mosback/login/domain/user/User.java @@ -36,6 +36,7 @@ public class User { private String nickname; // 닉네임 + @Column(name = "image_url") private String imageUrl; // 프로필 이미지 private Date str_duration; @@ -46,7 +47,6 @@ public class User { private String company; private String tend1; - private String tend2; public String getTend1() { return tend1; @@ -64,6 +64,7 @@ public void setTend2(String tend2) { this.tend2 = tend2; } + private String tend2; @Enumerated(EnumType.STRING) private Role role; diff --git a/src/main/java/mos/mosback/login/domain/user/conrtoller/UserProfileController.java b/src/main/java/mos/mosback/login/domain/user/conrtoller/UserProfileController.java index 9efa878..07a4234 100644 --- a/src/main/java/mos/mosback/login/domain/user/conrtoller/UserProfileController.java +++ b/src/main/java/mos/mosback/login/domain/user/conrtoller/UserProfileController.java @@ -11,12 +11,11 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; - import java.util.HashMap; import java.util.Map; - @RestController @RequestMapping("/profile") + public class UserProfileController { // 현재 로그인한 사용자의 정보 가져오기 From e19064c01d65a87f4a6bdd00d1bf6c35d40fe1cd Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Mon, 6 Nov 2023 19:36:20 +0900 Subject: [PATCH 49/60] =?UTF-8?q?=EC=8A=A4=ED=84=B0=EB=94=94=EB=A3=B8=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20-=20=EB=A9=A4=EB=B2=84=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EA=B5=AC=ED=98=84=EB=81=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 23 +- src/main/java/mos/mosback/Application.java | 10 +- .../mosback/configuration/SwaggerConfig.java | 36 --- .../user/conrtoller/UserController.java | 85 ------ .../user/controller/UserController.java | 149 ++++++++++ .../UserProfileController.java | 94 +++++- .../login/domain/user/dto/UserInfo.java | 17 ++ .../login/domain/user/dto/UserProfileDto.java | 30 +- .../user/repository/UserRepository.java | 8 +- .../domain/user/service/FileService.java | 44 +++ .../domain/user/service/UserService.java | 268 ++++++++++++++---- .../login/global/config/CorsConfig.java | 2 +- .../login/global/config/MailConfig.java | 14 +- .../login/global/config/SecurityConfig.java | 16 +- .../login/global/config/StorageConfig.java | 31 ++ .../JwtAuthenticationProcessingFilter.java | 15 +- .../login/global/jwt/service/JwtService.java | 38 +-- .../login/handler/LoginFailureHandler.java | 12 +- .../login/handler/LoginSuccessHandler.java | 35 ++- .../handler/OAuth2LoginSuccessHandler.java | 23 +- .../stRoom/controller/StRoomController.java | 68 +++-- .../stRoom/controller/TodoController.java | 2 + .../stRoom/MemberTodoRankProjection.java | 2 + .../domain/stRoom/StudyMemberEntity.java | 12 + .../stRoom/dto/Home_RoomResponseDto.java | 6 +- .../stRoom/dto/MemberTodoRankResponseDto.java | 2 +- .../stRoom/dto/StRoomDetailResponseDto.java | 1 + .../stRoom/dto/StRoomMemberResponseDto.java | 3 + .../mosback/stRoom/dto/StRoomResponseDto.java | 2 +- .../dto/StudyMembershipStatusResponseDto.java | 25 ++ .../stRoom/repository/StRoomRepository.java | 6 + .../repository/StudyMemberRepository.java | 1 + .../mosback/stRoom/service/StRoomService.java | 42 ++- .../mosback/stRoom/service/ToDoService.java | 6 +- src/main/resources/application-jwt.yml | 4 +- src/main/resources/application-local.yml | 5 + src/main/resources/application-oauth.yml | 42 --- .../resources/application-real.properties | 5 + src/main/resources/application.yml | 14 +- 39 files changed, 850 insertions(+), 348 deletions(-) delete mode 100644 src/main/java/mos/mosback/configuration/SwaggerConfig.java delete mode 100644 src/main/java/mos/mosback/login/domain/user/conrtoller/UserController.java create mode 100644 src/main/java/mos/mosback/login/domain/user/controller/UserController.java rename src/main/java/mos/mosback/login/domain/user/{conrtoller => controller}/UserProfileController.java (51%) create mode 100644 src/main/java/mos/mosback/login/domain/user/service/FileService.java create mode 100644 src/main/java/mos/mosback/login/global/config/StorageConfig.java create mode 100644 src/main/java/mos/mosback/stRoom/dto/StudyMembershipStatusResponseDto.java create mode 100644 src/main/resources/application-local.yml delete mode 100644 src/main/resources/application-oauth.yml create mode 100644 src/main/resources/application-real.properties diff --git a/build.gradle b/build.gradle index e67aeb6..5b888b9 100644 --- a/build.gradle +++ b/build.gradle @@ -26,7 +26,15 @@ repositories { name 'Clojars' } } +jar { + enabled = false +} +jar { + manifest { + attributes 'Main-Class': 'mos.mosback.Application' + } +} // for Junit 5 test { // (2) useJUnitPlatform() @@ -44,9 +52,11 @@ dependencies { testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' + implementation 'org.mariadb.jdbc:mariadb-java-client' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' implementation 'org.springframework.boot:spring-boot-starter-security' + implementation 'mysql:mysql-connector-java:8.0.34' implementation 'org.springframework.boot:spring-boot-starter-mail' //메일 의존성 testImplementation 'org.springframework.boot:spring-boot-starter-test' @@ -58,11 +68,16 @@ dependencies { runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.2' implementation group: 'org.postgresql', name: 'postgresql', version: '42.2.23' - implementation 'org.mariadb.jdbc:mariadb-java-client:3.0.3' - + implementation 'org.mariadb.jdbc:mariadb-java-client:3.1.2' + implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' + implementation 'com.auth0:java-jwt:4.2.1' + implementation 'mysql:mysql-connector-java:8.0.26' implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' implementation 'com.auth0:java-jwt:4.2.1' + implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE' + implementation "software.amazon.awssdk:s3:2.13.0" + // lombok implementation('org.projectlombok:lombok:1.18.20') @@ -71,7 +86,5 @@ dependencies { testImplementation('org.projectlombok:lombok:1.18.20') testAnnotationProcessor('org.projectlombok:lombok:1.18.20') - // build.gradle 적용 - implementation 'io.springfox:springfox-swagger2:2.9.2' - implementation 'io.springfox:springfox-swagger-ui:2.9.2' + } \ No newline at end of file diff --git a/src/main/java/mos/mosback/Application.java b/src/main/java/mos/mosback/Application.java index 08bec20..1601181 100644 --- a/src/main/java/mos/mosback/Application.java +++ b/src/main/java/mos/mosback/Application.java @@ -4,15 +4,17 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.context.annotation.ComponentScan; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; @Slf4j @EnableJpaAuditing //JPA Auditing 활성화 -@SpringBootApplication(exclude = {SecurityAutoConfiguration.class}) - +@SpringBootApplication(exclude = {SecurityAutoConfiguration.class, + org.springframework.cloud.aws.autoconfigure.context.ContextInstanceDataAutoConfiguration.class, + org.springframework.cloud.aws.autoconfigure.context.ContextStackAutoConfiguration.class, + org.springframework.cloud.aws.autoconfigure.context.ContextRegionProviderAutoConfiguration.class +}) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } -} +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/configuration/SwaggerConfig.java b/src/main/java/mos/mosback/configuration/SwaggerConfig.java deleted file mode 100644 index 632608f..0000000 --- a/src/main/java/mos/mosback/configuration/SwaggerConfig.java +++ /dev/null @@ -1,36 +0,0 @@ -package mos.mosback.configuration; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import springfox.documentation.builders.ApiInfoBuilder; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.service.ApiInfo; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger2.annotations.EnableSwagger2; - -@Configuration -@EnableSwagger2 -public class SwaggerConfig implements WebMvcConfigurer { - private ApiInfo apiInfo() { - - return new ApiInfoBuilder() - .title("Demo") - .description("API EXAMPLE") - .build(); - } - - @Bean - public Docket commonApi() { - return new Docket(DocumentationType.SWAGGER_2) - .groupName("example") - .apiInfo(this.apiInfo()) - .select() - .apis(RequestHandlerSelectors - .basePackage("mos.mosback")) - .paths(PathSelectors.ant("/**")) - .build(); - } -} \ No newline at end of file diff --git a/src/main/java/mos/mosback/login/domain/user/conrtoller/UserController.java b/src/main/java/mos/mosback/login/domain/user/conrtoller/UserController.java deleted file mode 100644 index f04825c..0000000 --- a/src/main/java/mos/mosback/login/domain/user/conrtoller/UserController.java +++ /dev/null @@ -1,85 +0,0 @@ -package mos.mosback.login.domain.user.conrtoller; - -import lombok.RequiredArgsConstructor; -import mos.mosback.login.domain.user.User; -import mos.mosback.login.domain.user.dto.*; -import mos.mosback.login.domain.user.repository.UserRepository; -import mos.mosback.login.domain.user.service.UserService; -import mos.mosback.login.global.jwt.service.JwtService; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.web.bind.annotation.*; - -import javax.transaction.Transactional; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -@RestController -@RequiredArgsConstructor -//@RequestMapping("/api") -public class UserController { - - private final UserService userService; - private final UserRepository userRepository; - - private Map userMap = new HashMap<>(); - - private JwtService jwtService; - @PostMapping("/sign-up") - public String signUp(@RequestBody UserSignUpDto userSignUpDto) throws Exception { - userService.signUp(userSignUpDto); - return "회원가입 성공"; - } - - - @PutMapping("/update/password") - public ResponseEntity updateUserPassword(@RequestBody UserSignUpDto userSignUpDto) throws Exception { - // 현재 로그인한 사용자의 정보 가져오기 - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - String currentEmail = authentication.getName(); // 현재 사용자의 이메일 - try{ - // 회원 정보 업데이트 - userService.upadateUserPassword(currentEmail, userSignUpDto); - - return ResponseEntity.ok("비밀번호 수정이 완료되었습니다."); - } catch (Exception e) { - e.printStackTrace(); - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("오류가 발생했습니다."); - } - } - - - @GetMapping("/jwt-test") - public String jwtTest() { - return "jwtTest 요청 성공"; - } - - - @GetMapping("/user-emails/{email}/exists") - public ResponseEntity checkEmailExists(@PathVariable String email) { - Optional existingUser = userRepository.findByEmail(email); - - if (existingUser.isPresent()) { - User user = existingUser.get(); - return ResponseEntity.ok("이메일이 이미 존재합니다."); - } else { - return ResponseEntity.ok("사용할 수 있는 이메일입니다."); - } - } - - - @Transactional - @PostMapping("/send/email") - public ResponseEntity sendTemporaryPassword(@RequestBody FindPWDto findPWDto) { - if (userService.findPassword(findPWDto)) { - MailDto mailDto = userService.createMailAndChangePassword(findPWDto.getEmail()); - userService.mailSend(mailDto); - return ResponseEntity.ok("임시 비밀번호 메일 전송 및 변경 완료"); - } else { - return ResponseEntity.status(400).body("이메일이 존재하지 않거나 이름이 일치하지 않습니다."); - } - } -} \ No newline at end of file diff --git a/src/main/java/mos/mosback/login/domain/user/controller/UserController.java b/src/main/java/mos/mosback/login/domain/user/controller/UserController.java new file mode 100644 index 0000000..513ec1c --- /dev/null +++ b/src/main/java/mos/mosback/login/domain/user/controller/UserController.java @@ -0,0 +1,149 @@ +package mos.mosback.login.domain.user.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import javassist.NotFoundException; +import lombok.RequiredArgsConstructor; +import mos.mosback.login.domain.user.User; +import mos.mosback.login.domain.user.dto.*; +import mos.mosback.login.domain.user.repository.UserRepository; +import mos.mosback.login.domain.user.service.UserService; +import mos.mosback.login.global.jwt.service.JwtService; +import mos.mosback.stRoom.domain.stRoom.StRoomEntity; +import mos.mosback.stRoom.dto.StRoomResponseDto; +import mos.mosback.stRoom.service.StRoomService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.transaction.Transactional; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +@RestController +@RequiredArgsConstructor +public class UserController { + + private final UserService userService; + private final UserRepository userRepository; + + private final StRoomService stRoomService; + + private Map userMap = new HashMap<>(); + + private final JwtService jwtService; + + @PostMapping("/sign-up") + public ResponseEntity> signUp(@RequestBody UserSignUpDto userSignUpDto) { + Map response = new HashMap<>(); + try { + userService.signUp(userSignUpDto); + response.put("status", 200); + response.put("success", true); + response.put("message", "회원가입 성공"); + return ResponseEntity.ok(response); + } catch (Exception ex) { + response.put("status", 500); + response.put("success", false); + response.put("message", "회원가입 실패: " + ex.getMessage()); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); + } + } + + @PutMapping("/update/password") + public Map updateUserPassword(@RequestBody UserSignUpDto userSignUpDto) throws Exception { + // 현재 로그인한 사용자의 정보 가져오기 + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + String currentEmail = authentication.getName(); // 현재 사용자의 이메일 + Map response = new HashMap<>(); + try{ + // 회원 정보 업데이트 + userService.upadateUserPassword(currentEmail, userSignUpDto); + response.put("status", 200); + response.put("success", true); + response.put("message", "비밀번호 수정이 완료되었습니다."); + } catch (Exception e) { + response.put("status", 500); + response.put("success", false); + response.put("message", "비밀번호 수정 실패: " + e.getMessage()); + } + return response; + } + + + @GetMapping("/jwt-test") + public String jwtTest() { + return "jwtTest 요청 성공"; + } + + + @GetMapping("/user-emails/{email}/exists") + public Map checkEmailExists(@PathVariable String email) { + Map response = new HashMap<>(); + Optional existingUser = userRepository.findByEmail(email); + + if (existingUser.isPresent()) { + response.put("status", 500); + response.put("success", true); + response.put("message", "이메일이 이미 존재합니다."); + } else { + response.put("status", 200); + response.put("success", true); + response.put("message", "사용할 수 있는 이메일입니다."); + } + return response; + } + + + + @Transactional + @PostMapping("/send/email") + public ResponseEntity> sendTemporaryPassword(@RequestBody FindPWDto findPWDto) { + Map response = new HashMap<>(); + if (userService.findPassword(findPWDto)) { + MailDto mailDto = userService.createMailAndChangePassword(findPWDto.getEmail()); + userService.mailSend(mailDto); + response.put("status", 200); + response.put("success", true); + response.put("message", "임시 비밀번호 메일 전송 및 변경 완료"); + return ResponseEntity.ok(response); + } else { + response.put("status", 400); + response.put("success", false); + response.put("message", "이메일이 존재하지 않거나 이름이 일치하지 않습니다."); + return ResponseEntity.status(400).body(response); + } + } + + + /* @GetMapping("/user/list") + public ResponseEntity> getLeaderStudies() { + Map response = new HashMap<>(); + try { + // 현재 로그인한 사용자의 정보 가져오기 + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + String userEmail = authentication.getName(); // 현재 사용자의 이메일 + + List leaderStudies = stRoomService.getLeaderStudies(userEmail); + + response.put("status", HttpStatus.OK.value()); + response.put("success", true); + response.put("data", leaderStudies); + + return new ResponseEntity<>(response, HttpStatus.OK); + } catch (Exception e) { + response.put("status", HttpStatus.INTERNAL_SERVER_ERROR.value()); + response.put("success", false); + response.put("error", "Internal Server Error: " + e.getMessage()); + + return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR); + } + }*/ + +} diff --git a/src/main/java/mos/mosback/login/domain/user/conrtoller/UserProfileController.java b/src/main/java/mos/mosback/login/domain/user/controller/UserProfileController.java similarity index 51% rename from src/main/java/mos/mosback/login/domain/user/conrtoller/UserProfileController.java rename to src/main/java/mos/mosback/login/domain/user/controller/UserProfileController.java index 07a4234..03ebf6a 100644 --- a/src/main/java/mos/mosback/login/domain/user/conrtoller/UserProfileController.java +++ b/src/main/java/mos/mosback/login/domain/user/controller/UserProfileController.java @@ -1,22 +1,29 @@ -package mos.mosback.login.domain.user.conrtoller; +package mos.mosback.login.domain.user.controller; import mos.mosback.login.domain.user.User; import mos.mosback.login.domain.user.dto.UserProfileDto; import mos.mosback.login.domain.user.repository.UserRepository; +import mos.mosback.login.domain.user.service.FileService; import mos.mosback.login.domain.user.service.UserService; +import mos.mosback.stRoom.dto.StudyMembershipStatusResponseDto; +import mos.mosback.stRoom.repository.StRoomRepository; +import mos.mosback.stRoom.repository.StudyMemberRepository; +import mos.mosback.stRoom.service.StRoomService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.util.*; -import java.util.HashMap; -import java.util.Map; @RestController @RequestMapping("/profile") - public class UserProfileController { +// private static final Logger logger = LoggerFactory.getLogger(UserProfileController.class); // 현재 로그인한 사용자의 정보 가져오기 // Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); @@ -25,16 +32,26 @@ public class UserProfileController { private final UserService userService; private final UserRepository userRepository; + private final StRoomService stRoomService; + private final StudyMemberRepository studyMemberRepository; + private final StRoomRepository stRoomRepository; + + private final FileService fileService; + @Autowired - public UserProfileController(UserService userService, UserRepository userRepository) { + public UserProfileController(UserService userService, UserRepository userRepository, StRoomService stRoomService, StudyMemberRepository studyMemberRepository, StRoomRepository stRoomRepository, FileService fileService) { this.userService = userService; this.userRepository = userRepository; - + this.stRoomService = stRoomService; + this.studyMemberRepository = studyMemberRepository; + this.stRoomRepository = stRoomRepository; + this.fileService = fileService; } @PostMapping - public Map createUserProfile(@RequestBody UserProfileDto userProfileDto) { + public Map createUserProfile(@RequestPart(value = "file") MultipartFile file, + @RequestPart(value = "userProfileDto") UserProfileDto userProfileDto) { Map response = new HashMap<>(); try { // 현재 로그인한 사용자의 정보 가져오기 @@ -43,6 +60,12 @@ public Map createUserProfile(@RequestBody UserProfileDto userPro // 회원 정보 생성 userService.createUser(currentEmail, userProfileDto); + // 이미지 업로드 및 URL 저장 + String imageUrl = fileService.uploadFile(file, userProfileDto.getId()); + userProfileDto.setImageUrl(imageUrl); + + // 사용자 정보에 이미지 URL 업데이트 + userService.updateUserProfileImageUrl(userProfileDto.getId(), imageUrl); response.put("status", 200); response.put("success", true); @@ -58,12 +81,12 @@ public Map createUserProfile(@RequestBody UserProfileDto userPro @PutMapping - public Map updateUserProfile(@RequestBody UserProfileDto userProfileDto) throws Exception { + public Map updateUserProfile(UserProfileDto userProfileDto) throws Exception { // 현재 로그인한 사용자의 정보 가져오기 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String currentEmail = authentication.getName(); // 현재 사용자의 이메일 Map response = new HashMap<>(); - try{ + try { // 회원 정보 업데이트 userService.updateUserProfile(currentEmail, userProfileDto); response.put("status", 200); @@ -105,4 +128,57 @@ public ResponseEntity> getUserProfile() { } } + @GetMapping("/status") + public ResponseEntity> getStudyMembershipStatus() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + String userEmail = authentication.getName(); // 현재 사용자의 이메일 + + Map response = new HashMap<>(); + HttpStatus httpStatus; + boolean success = true; + List membershipStatusList; + + try { + // userService에서 스터디 멤버십 상태 정보를 가져옵니다. + membershipStatusList = userService.getStudyMembershipStatus(userEmail); + httpStatus = HttpStatus.OK; + } catch (Exception e) { + membershipStatusList = Collections.emptyList(); + httpStatus = HttpStatus.INTERNAL_SERVER_ERROR; + success = false; + response.put("error", e.getMessage()); + } + + response.put("status", httpStatus.value()); + response.put("success", success); + response.put("data", membershipStatusList); + + return ResponseEntity.status(httpStatus).body(response); + } + + @PostMapping("/{id}/image") + public ResponseEntity uploadUserImage(@PathVariable Long id, + @RequestParam("file") MultipartFile file, + @ModelAttribute UserProfileDto userProfileDto) { + try { + userService.uploadAndSaveImage(id, file); + return new ResponseEntity<>("User image uploaded successfully", HttpStatus.OK); + } catch (IOException e) { + return new ResponseEntity<>("Error occurred while uploading image", HttpStatus.BAD_REQUEST); + } + } + + @GetMapping("/{id}/image") + public ResponseEntity getUserImage(@PathVariable Long id) { + User user = userService.findById(id); + if (user != null) { + String imageUrl = user.getImageUrl(); + return new ResponseEntity<>(imageUrl, HttpStatus.OK); + } else { + return new ResponseEntity<>("User not found", HttpStatus.NOT_FOUND); + } + } + + } + diff --git a/src/main/java/mos/mosback/login/domain/user/dto/UserInfo.java b/src/main/java/mos/mosback/login/domain/user/dto/UserInfo.java index e69de29..e982d00 100644 --- a/src/main/java/mos/mosback/login/domain/user/dto/UserInfo.java +++ b/src/main/java/mos/mosback/login/domain/user/dto/UserInfo.java @@ -0,0 +1,17 @@ +package mos.mosback.login.domain.user.dto; + +public class UserInfo { + + private String email; + private String password; + + // 생성자, 게터/세터 등 생략 + + public String getEmail() { + return email; + } + + public String getPassword() { + return password; + } +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/login/domain/user/dto/UserProfileDto.java b/src/main/java/mos/mosback/login/domain/user/dto/UserProfileDto.java index 44e53f7..2184577 100644 --- a/src/main/java/mos/mosback/login/domain/user/dto/UserProfileDto.java +++ b/src/main/java/mos/mosback/login/domain/user/dto/UserProfileDto.java @@ -8,6 +8,9 @@ import org.springframework.stereotype.Component; import javax.persistence.Column; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; @NoArgsConstructor @@ -15,6 +18,11 @@ @Component public class UserProfileDto { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "user_id") + private Long id; + @Column(nullable = false) private String nickname; private String name; @@ -22,22 +30,30 @@ public class UserProfileDto { private Date end_duration; private String message; private String company; + private String tend1; private String tend2; + private Long roomId; + @Column(name = "image_url") + private String imageUrl; - public UserProfileDto(String nickname, String name, Date str_duration, - Date end_duration, String message, String company, String tend1, String tend2, Long roomId) { + + public UserProfileDto(Long id,String nickname, String name, Date str_duration, + Date end_duration, String message, + String company, String tend1, String tend2, Long roomId, String imageUrl) { + this.id = id; this.nickname = nickname; this.name = name; this.str_duration = str_duration; this.end_duration = end_duration; this.message = message; this.company = company; - this.roomId = roomId; this.tend1 = tend1; this.tend2= tend2; + this.roomId = roomId; + this.imageUrl=imageUrl; } @@ -48,5 +64,13 @@ public Long getRoomId() { public void setRoomId(Long roomId) { this.roomId = roomId; } + public String getImageUrl() { + return imageUrl; + } + + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } } + diff --git a/src/main/java/mos/mosback/login/domain/user/repository/UserRepository.java b/src/main/java/mos/mosback/login/domain/user/repository/UserRepository.java index 1978b65..c04b8e4 100644 --- a/src/main/java/mos/mosback/login/domain/user/repository/UserRepository.java +++ b/src/main/java/mos/mosback/login/domain/user/repository/UserRepository.java @@ -9,10 +9,7 @@ public interface UserRepository extends JpaRepository { - Optional findByEmail(String email); - - - //Optional findByNickName(String nickname); + Optional findByEmail(String email); Optional findByNickname(String nickname); @@ -20,7 +17,6 @@ public interface UserRepository extends JpaRepository { Optional findByRefreshToken(String refreshToken); - //String findByPassword(); /** * 소셜 타입과 소셜의 식별값으로 회원 찾는 메소드 * 정보 제공을 동의한 순간 DB에 저장해야하지만, 아직 추가 정보(사는 도시, 나이 등)를 입력받지 않았으므로 @@ -28,4 +24,4 @@ public interface UserRepository extends JpaRepository { * 따라서 추가 정보를 입력받아 회원 가입을 진행할 때 소셜 타입, 식별자로 해당 회원을 찾기 위한 메소드 */ Optional findBySocialTypeAndSocialId(SocialType socialType, String socialId); -} \ No newline at end of file +} diff --git a/src/main/java/mos/mosback/login/domain/user/service/FileService.java b/src/main/java/mos/mosback/login/domain/user/service/FileService.java new file mode 100644 index 0000000..f67e5f8 --- /dev/null +++ b/src/main/java/mos/mosback/login/domain/user/service/FileService.java @@ -0,0 +1,44 @@ +package mos.mosback.login.domain.user.service; + +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.model.PutObjectRequest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; + +@Service +public class FileService { + + @Value("${application.bucket.name}") + private String bucketName; + + @Value("${cloud.aws.region.static}") + private String region; + @Autowired + private AmazonS3 s3Client; + + + public String uploadFile(MultipartFile file, Long memberId) { + File fileObj = convertMultiPartFileToFile(file); + String fileName = Long.toString(memberId); + s3Client.putObject(new PutObjectRequest(bucketName, fileName, fileObj)); + fileObj.delete(); + + // 업로드된 파일의 S3 URL 반환 + return String.format("https://%s.s3.%s.amazonaws.com/%s", bucketName, region, fileName); + } + + private File convertMultiPartFileToFile(MultipartFile file) { + File convertFile = new File(file.getOriginalFilename()); + try (FileOutputStream fos = new FileOutputStream(convertFile)) { + fos.write(file.getBytes()); + } catch (IOException e) { + e.printStackTrace(); + } + return convertFile; + } +} + diff --git a/src/main/java/mos/mosback/login/domain/user/service/UserService.java b/src/main/java/mos/mosback/login/domain/user/service/UserService.java index 7188e63..5ffab19 100644 --- a/src/main/java/mos/mosback/login/domain/user/service/UserService.java +++ b/src/main/java/mos/mosback/login/domain/user/service/UserService.java @@ -1,5 +1,6 @@ package mos.mosback.login.domain.user.service; +import javassist.NotFoundException; import mos.mosback.login.domain.user.Role; import mos.mosback.login.domain.user.User; import mos.mosback.login.domain.user.dto.FindPWDto; @@ -8,31 +9,58 @@ import mos.mosback.login.domain.user.dto.UserProfileDto; import mos.mosback.login.domain.user.dto.UserSignUpDto; import mos.mosback.login.domain.user.repository.UserRepository; + import lombok.RequiredArgsConstructor; import mos.mosback.stRoom.domain.stRoom.StRoomEntity; import mos.mosback.stRoom.domain.stRoom.StudyMemberEntity; -import mos.mosback.stRoom.dto.StRoomSaveRequestDto; +import mos.mosback.stRoom.dto.StudyMembershipStatusResponseDto; +import mos.mosback.stRoom.repository.StRoomRepository; +import mos.mosback.stRoom.repository.StudyMemberRepository; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; -import javax.servlet.http.HttpServletRequest; import javax.transaction.Transactional; -import java.util.Optional; +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + @Service @Transactional @RequiredArgsConstructor public class UserService { - private final UserRepository userRepository; - private final PasswordEncoder passwordEncoder; - private final JavaMailSender mailSender; + @Autowired + private UserRepository userRepository; + + @Autowired + private PasswordEncoder passwordEncoder; + + @Autowired + private JavaMailSender mailSender; + + @Autowired + private StudyMemberRepository studyMemberRepository; + + private StRoomRepository stRoomRepository; + + @Autowired + private final FileService fileService; + + public User getUserById(Long id) throws Exception { + Optional optionalUser = userRepository.findById(id); + if (optionalUser.isPresent()) { + return optionalUser.get(); + } else { + throw new Exception("현재 로그인한 사용자를 찾을 수 없습니다."); + } + } public void signUp(UserSignUpDto userSignUpDto) throws Exception { @@ -57,12 +85,13 @@ public User getUserByEmail(String email) throws Exception { if (optionalUser.isPresent()) { return optionalUser.get(); } else { - throw new Exception("현재 로그인한 사용자를 찾을 수 없습니다."); + throw new Exception("해당 이메일의 사용자를 찾을 수 없습니다: " + email); } } + //마이페이지정보입력 - public void roomId(String currentEmail, UserProfileDto userProfileDto) throws Exception { + public void createUser(String currentEmail, UserProfileDto userProfileDto) throws Exception { if (userRepository.findByNickname(userProfileDto.getNickname()).isPresent()) { throw new Exception("이미 존재하는 닉네임입니다."); } @@ -72,18 +101,58 @@ public void roomId(String currentEmail, UserProfileDto userProfileDto) throws Ex // 회원 정보 생성 user.setNickname(userProfileDto.getNickname()); + user.setName(userProfileDto.getName()); user.setStr_duration(userProfileDto.getStr_duration()); user.setEnd_duration(userProfileDto.getEnd_duration()); user.setMessage(userProfileDto.getMessage()); user.setCompany(userProfileDto.getCompany()); - + user.setTend1(userProfileDto.getTend1()); + user.setTend2(userProfileDto.getTend2()); user.setRole(Role.USER); + userRepository.save(user); } catch (Exception e) { throw new Exception("회원 정보를 생성하는 동안 오류가 발생했습니다.", e); } } + public void updateUserProfileImageUrl(Long userId, String imageUrl) throws Exception { + Optional optionalUser = userRepository.findById(userId); + if (optionalUser.isPresent()) { + User user = optionalUser.get(); + user.setImageUrl(imageUrl); + userRepository.save(user); + } else { + throw new Exception("해당 ID의 사용자를 찾을 수 없습니다: " + userId); + } + } + + + //마이페이지 업데이트 + public void updateUserProfile(String currentEmail, UserProfileDto userProfileDto ) throws Exception { + try { + User user = getUserByEmail(currentEmail); + + // 회원 정보 업데이트 + user.setNickname(userProfileDto.getNickname()); + user.setName(userProfileDto.getName()); + user.setStr_duration(userProfileDto.getStr_duration()); + user.setEnd_duration(userProfileDto.getEnd_duration()); + user.setMessage(userProfileDto.getMessage()); + user.setCompany(userProfileDto.getCompany()); + user.setTend1(userProfileDto.getTend1()); + user.setTend2(userProfileDto.getTend2()); +/* user.setRoomId(userProfileDto.getRoomId());*/ + + + + + userRepository.save(user); + } catch (Exception e) { + throw new Exception("회원 정보를 업데이트하는 동안 오류가 발생했습니다.", e); + } + } + public void upadateUserPassword(String currentEmail, UserSignUpDto userSignUpDto) throws Exception{ try { User user = getUserByEmail(currentEmail); @@ -101,8 +170,7 @@ public void upadateUserPassword(String currentEmail, UserSignUpDto userSignUpDto } - // 메일 내용을 생성하고 임시 비밀번호로 회원 비밀번호를 변경 - +// 메일 내용을 생성하고 임시 비밀번호로 회원 비밀번호를 변경 public MailDto createMailAndChangePassword(String userEmail) { String tempPassword = getTempPassword(); MailDto mailDTO = new MailDto(); @@ -164,13 +232,35 @@ public Optional loadUserByUsername(String userEmail) throws UsernameNotFou return userRepository.findByEmail(userEmail); } + // 사용자의 이미지 URL 업데이트 메서드 + public void uploadAndSaveImage(Long id, MultipartFile file) throws IOException { + // id를 사용하여 사용자 정보를 데이터베이스에서 조회합니다. + User user = userRepository.findById(id).get(); - public UserProfileDto getUserProfileByEmail(String email) throws Exception { - Optional optionalUser = userRepository.findByEmail(email); + if (user != null) { + // 이미지를 S3에 업로드하고 URL을 받아옵니다. + String imageUrl = fileService.uploadFile(file, user.getId()); + + // 사용자 정보가 존재하면 이미지 URL을 업데이트합니다. + user.setImageUrl(imageUrl); + userRepository.save(user); // 변경된 정보를 저장합니다. + } else { + throw new IllegalArgumentException("해당 ID의 사용자를 찾을 수 없습니다: " + id); + } + } + + public User findById(Long id) { + return userRepository.findById(id).orElse(null); + } + + public UserProfileDto getMemberProfileById(Long memberId) throws Exception { + + Optional optionalUser = userRepository.findById(memberId); if (optionalUser.isPresent()) { User user = optionalUser.get(); // 엔터티 정보를 DTO로 매핑하여 반환 return new UserProfileDto( + user.getId(), user.getNickname(), user.getName(), user.getStr_duration(), @@ -179,55 +269,125 @@ public UserProfileDto getUserProfileByEmail(String email) throws Exception { user.getCompany(), user.getTend1(), user.getTend2(), - user.getRoomId() + user.getRoomId(), + user.getImageUrl() ); } else { - throw new Exception("해당 이메일의 사용자를 찾을 수 없습니다: " + email); + throw new Exception("해당 이메일의 사용자를 찾을 수 없습니다: " + memberId); } } - public void createUser(String currentEmail, UserProfileDto userProfileDto) throws Exception { - if (userRepository.findByNickname(userProfileDto.getNickname()).isPresent()) { - throw new Exception("이미 존재하는 닉네임입니다."); + + public List getStudyGroupsForUserByEmail(String email) throws NotFoundException { + Optional userOptional = userRepository.findByEmail(email); + if (userOptional.isPresent()) { + User user = userOptional.get(); + return user.getStRooms(); + } else { + throw new NotFoundException("사용자를 찾을 수 없습니다."); } + } - try { - User user = getUserByEmail(currentEmail); - // 회원 정보 생성 - user.setNickname(userProfileDto.getNickname()); - user.setName(userProfileDto.getName()); - user.setStr_duration(userProfileDto.getStr_duration()); - user.setEnd_duration(userProfileDto.getEnd_duration()); - user.setMessage(userProfileDto.getMessage()); - user.setCompany(userProfileDto.getCompany()); - user.setTend1(userProfileDto.getTend1()); - user.setTend2(userProfileDto.getTend2()); - user.setRole(Role.USER); - userRepository.save(user); - } catch (Exception e) { - throw new Exception("회원 정보를 생성하는 동안 오류가 발생했습니다.", e); - } + + public List getStudyGroupsForUserByMemberId(Long memberId) { + // 사용자의 memberId를 이용해 사용자가 참여한 스터디 그룹 목록을 조회합니다. + List userStudyMemberships = studyMemberRepository.findAllByMemberId(memberId); + + // 사용자가 참여한 스터디 그룹 목록을 담을 리스트를 생성합니다. + List userStudyGroups = stRoomRepository.findByMembersIn(userStudyMemberships); + + return userStudyGroups; } - //마이페이지 업데이트 - public void updateUserProfile(String currentEmail, UserProfileDto userProfileDto) throws Exception { - try { - User user = getUserByEmail(currentEmail); +// public List getStudyMembershipStatus(String userEmail) throws NotFoundException { +// User user = userRepository.findByEmail(userEmail) +// .orElseThrow(() -> new NotFoundException("사용자를 찾을 수 없습니다.")); +// +// Long memberId = user.getId(); +// List userStudyMemberships = studyMemberRepository.findAllByMemberId(memberId); +// +// Map latestStudyMembershipsMap = userStudyMemberships.stream() +// .collect(Collectors.toMap( +// StudyMemberEntity::getStRoom, +// Function.identity(), +// (m1, m2) -> m1.getJoinedAt().isAfter(m2.getJoinedAt()) ? m1 : m2 +// )); +// +// List membershipStatusList = latestStudyMembershipsMap.entrySet().stream() +// .map(entry -> { +// StRoomEntity stRoom = entry.getKey(); +// StudyMemberEntity studyMembership = entry.getValue(); +// String status = studyMembership.getStatus().name(); +// return new StudyMembershipStatusResponseDto(stRoom.getTitle(), status); +// }) +// .collect(Collectors.toList()); +// +// return membershipStatusList; +// } + +// 내가 가입한 스터디의 상태를 보여줌(하나만 보여주는 문제) + public List getStudyMembershipStatus(String userEmail) throws NotFoundException { + User user = userRepository.findByEmail(userEmail) + .orElseThrow(() -> new NotFoundException("사용자를 찾을 수 없습니다.")); + + Long memberId = user.getId(); + List userStudyMemberships = studyMemberRepository.findAllByMemberId(memberId); + + List membershipStatusList = userStudyMemberships.stream() + .map(member -> { + StRoomEntity stRoom = member.getStRoom(); + String status = member.getStatus().name(); + return new StudyMembershipStatusResponseDto(stRoom.getTitle(), status); + }) + .collect(Collectors.toList()); + + return membershipStatusList; + } - // 회원 정보 업데이트 - user.setNickname(userProfileDto.getNickname()); - user.setName(userProfileDto.getName()); - user.setStr_duration(userProfileDto.getStr_duration()); - user.setEnd_duration(userProfileDto.getEnd_duration()); - user.setMessage(userProfileDto.getMessage()); - user.setCompany(userProfileDto.getCompany()); - user.setTend1(userProfileDto.getTend1()); - user.setTend2(userProfileDto.getTend2()); - user.setRoomId(userProfileDto.getRoomId()); - userRepository.save(user); - } catch (Exception e) { - throw new Exception("회원 정보를 업데이트하는 동안 오류가 발생했습니다.", e); + +// public List getStudyMembershipStatus(String userEmail) throws NotFoundException { +// User user = userRepository.findByEmail(userEmail) +// .orElseThrow(() -> new NotFoundException("사용자를 찾을 수 없습니다.")); +// +// Long memberId = user.getId(); +// List userStudyMemberships = studyMemberRepository.findAllByMemberId(memberId); +// +// List membershipStatusList = userStudyMemberships.stream() +// .map(member -> { +// StRoomEntity stRoom = member.getStRoom(); +// String status = member.getStatus().name(); +// return new StudyMembershipStatusResponseDto(stRoom.getTitle(), status); +// }) +// .collect(Collectors.toList()); +// +// return membershipStatusList; +// } + + + public UserProfileDto getUserProfileByEmail(String email) throws Exception { + Optional optionalUser = userRepository.findByEmail(email); + if (optionalUser.isPresent()) { + User user = optionalUser.get(); + // 엔터티 정보를 DTO로 매핑하여 반환 + return new UserProfileDto( + user.getId(), + user.getNickname(), + user.getName(), + user.getStr_duration(), + user.getEnd_duration(), + user.getMessage(), + user.getCompany(), + user.getTend1(), + user.getTend2(), + user.getRoomId(), + user.getImageUrl() + ); + } else { + throw new Exception("해당 이메일의 사용자를 찾을 수 없습니다: " + email); } } -} \ No newline at end of file + +} + + diff --git a/src/main/java/mos/mosback/login/global/config/CorsConfig.java b/src/main/java/mos/mosback/login/global/config/CorsConfig.java index 8d14a6d..29ca714 100644 --- a/src/main/java/mos/mosback/login/global/config/CorsConfig.java +++ b/src/main/java/mos/mosback/login/global/config/CorsConfig.java @@ -21,4 +21,4 @@ public CorsFilter corsFilter() { source.registerCorsConfiguration("/**", config); return new CorsFilter(); } -} +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/login/global/config/MailConfig.java b/src/main/java/mos/mosback/login/global/config/MailConfig.java index 54eb8e7..db25081 100644 --- a/src/main/java/mos/mosback/login/global/config/MailConfig.java +++ b/src/main/java/mos/mosback/login/global/config/MailConfig.java @@ -1,5 +1,6 @@ package mos.mosback.login.global.config; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.mail.javamail.JavaMailSender; @@ -9,14 +10,21 @@ @Configuration public class MailConfig { + + @Value("${MAIL_USERNAME}") + private String mailUsername; + + @Value("${MAIL_PASSWORD}") + private String mailPassword; @Bean public JavaMailSender javaMailService() { + + JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl(); javaMailSender.setHost("smtp.naver.com"); - javaMailSender.setUsername("이메일"); - javaMailSender.setPassword("비밀번호"); - + javaMailSender.setUsername(mailUsername); + javaMailSender.setPassword(mailPassword); javaMailSender.setPort(465); javaMailSender.setJavaMailProperties(getMailProperties()); diff --git a/src/main/java/mos/mosback/login/global/config/SecurityConfig.java b/src/main/java/mos/mosback/login/global/config/SecurityConfig.java index cbcec3c..c39c990 100644 --- a/src/main/java/mos/mosback/login/global/config/SecurityConfig.java +++ b/src/main/java/mos/mosback/login/global/config/SecurityConfig.java @@ -20,11 +20,16 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.factory.PasswordEncoderFactories; +import org.springframework.security.crypto.password.DelegatingPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.logout.LogoutFilter; +import java.util.Map; + /** * 인증은 CustomJsonUsernamePasswordAuthenticationFilter에서 authenticate()로 인증된 사용자로 처리 * JwtAuthenticationProcessingFilter는 AccessToken, RefreshToken 재발급 @@ -62,13 +67,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { // 아이콘, css, js 관련 // 기본 페이지, css, image, js 하위 폴더에 있는 자료들은 모두 접근 가능, h2-console에 접근 가능 .antMatchers("/","/css/**","/images/**","/js/**","/favicon.ico","/h2-console/**").permitAll() - .antMatchers("/sign-up","/studyRoom/create","/studyRoom/update/{roomId}","/studyRoom/{roomId}", - "/todo/add","/todo/update{todoId}","/todo/delete/{todoId}","/todo/{todoId}","/member/todo/add" - , "/studyRoom/all","/studyRoom/search","/studyRoom/byCategory/{category}","/studyRoom/recruiting", - "/recruitInfo/{roomId}", - "/swagger-ui.html", "/webjars/**", "/v2/**", - "/webjars/springfox-swagger-ui/**", "/swagger-resources/**", - "/swagger-ui/", "/swagger-ui/**", "/csrf").permitAll() // 회원가입 접근 가능 + .antMatchers("/sign-up","/login").permitAll() // 회원가입 접근 가능 + .antMatchers("/user-emails/{email}/exists").permitAll() // 중복 체크 엔드포인트를 예외로 처리 .anyRequest().authenticated() // 위의 경로 이외에는 모두 인증된 사용자만 접근 가능 .and() //== 소셜 로그인 설정 ==// @@ -88,7 +88,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { @Bean public PasswordEncoder passwordEncoder() { - return PasswordEncoderFactories.createDelegatingPasswordEncoder(); + return new BCryptPasswordEncoder(); } /** diff --git a/src/main/java/mos/mosback/login/global/config/StorageConfig.java b/src/main/java/mos/mosback/login/global/config/StorageConfig.java new file mode 100644 index 0000000..4f45414 --- /dev/null +++ b/src/main/java/mos/mosback/login/global/config/StorageConfig.java @@ -0,0 +1,31 @@ +package mos.mosback.login.global.config; + +import com.amazonaws.auth.AWSCredentials; +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3ClientBuilder; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class StorageConfig { + + @Value("${cloud.aws.credentials.access-key}") + private String accessKey; + + @Value("${cloud.aws.credentials.secret-key}") + private String accessSecret; + @Value("${cloud.aws.region.static}") + private String region; + + @Bean + public AmazonS3 s3Client() { + AWSCredentials credentials = new BasicAWSCredentials(accessKey, accessSecret); + return AmazonS3ClientBuilder.standard() + .withCredentials(new AWSStaticCredentialsProvider(credentials)) + .withRegion(region).build(); + } + +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/login/global/jwt/filter/JwtAuthenticationProcessingFilter.java b/src/main/java/mos/mosback/login/global/jwt/filter/JwtAuthenticationProcessingFilter.java index 534dc19..df31628 100644 --- a/src/main/java/mos/mosback/login/global/jwt/filter/JwtAuthenticationProcessingFilter.java +++ b/src/main/java/mos/mosback/login/global/jwt/filter/JwtAuthenticationProcessingFilter.java @@ -46,11 +46,6 @@ public class JwtAuthenticationProcessingFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { - if (request.getRequestURI().startsWith("/swagger-ui")) { - // Swagger는 필터 적용 X - filterChain.doFilter(request, response); // "/login" 요청이 들어오면, 다음 필터 호출 - return; - } if (request.getRequestURI().equals(NO_CHECK_URL)) { filterChain.doFilter(request, response); // "/login" 요청이 들어오면, 다음 필터 호출 return; // return으로 이후 현재 필터 진행 막기 (안해주면 아래로 내려가서 계속 필터 진행시킴) @@ -91,11 +86,12 @@ public void checkRefreshTokenAndReIssueAccessToken(HttpServletResponse response, userRepository.findByRefreshToken(refreshToken) .ifPresent(user -> { String reIssuedRefreshToken = reIssueRefreshToken(user); - jwtService.sendAccessAndRefreshToken(response, jwtService.createAccessToken(user.getEmail()), + jwtService.sendAccessAndRefreshToken(response, jwtService.createJwt(user.getEmail()), reIssuedRefreshToken); }); } + /** * [리프레시 토큰 재발급 & DB에 리프레시 토큰 업데이트 메소드] * jwtService.createRefreshToken()으로 리프레시 토큰 재발급 후 @@ -119,14 +115,9 @@ private String reIssueRefreshToken(User user) { public void checkAccessTokenAndAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { log.info("checkAccessTokenAndAuthentication() 호출"); - if (request.getRequestURI().startsWith("/swagger-ui")) { - // Swagger는 필터 적용 X - filterChain.doFilter(request, response); // "/login" 요청이 들어오면, 다음 필터 호출 - return; - } jwtService.extractAccessToken(request) .filter(jwtService::isTokenValid) - .ifPresent(accessToken -> jwtService.extractEmail(accessToken) + .ifPresent(jwt -> jwtService.extractEmailFromJwt(jwt) .ifPresent(email -> userRepository.findByEmail(email) .ifPresent(this::saveAuthentication))); diff --git a/src/main/java/mos/mosback/login/global/jwt/service/JwtService.java b/src/main/java/mos/mosback/login/global/jwt/service/JwtService.java index 83881cf..c918685 100644 --- a/src/main/java/mos/mosback/login/global/jwt/service/JwtService.java +++ b/src/main/java/mos/mosback/login/global/jwt/service/JwtService.java @@ -8,6 +8,9 @@ import mos.mosback.login.domain.user.User; import mos.mosback.login.domain.user.repository.UserRepository; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; @@ -21,6 +24,7 @@ @RequiredArgsConstructor @Getter @Slf4j + public class JwtService { @Value("${jwt.secretKey}") @@ -42,7 +46,7 @@ public class JwtService { * JWT의 Subject와 Claim으로 email 사용 -> 클레임의 name을 "email"으로 설정 * JWT의 헤더에 들어오는 값 : 'Authorization(Key) = Bearer {토큰} (Value)' 형식 */ - private static final String ACCESS_TOKEN_SUBJECT = "AccessToken"; + private static final String ACCESS_TOKEN_SUBJECT = "accessToken"; private static final String REFRESH_TOKEN_SUBJECT = "RefreshToken"; private static final String EMAIL_CLAIM = "email"; private static final String BEARER = "Bearer "; @@ -52,19 +56,17 @@ public class JwtService { /** * AccessToken 생성 메소드 */ - public String createAccessToken(String email) { + public String createJwt(String email) { Date now = new Date(); - return JWT.create() // JWT 토큰을 생성하는 빌더 반환 - .withSubject(ACCESS_TOKEN_SUBJECT) // JWT의 Subject 지정 -> AccessToken이므로 AccessToken - .withExpiresAt(new Date(now.getTime() + accessTokenExpirationPeriod)) // 토큰 만료 시간 설정 - - //클레임으로는 저희는 email 하나만 사용합니다. - //추가적으로 식별자나, 이름 등의 정보를 더 추가하셔도 됩니다. - //추가하실 경우 .withClaim(클래임 이름, 클래임 값) 으로 설정해주시면 됩니다 + return JWT.create() + .withSubject(ACCESS_TOKEN_SUBJECT) + .withExpiresAt(new Date(now.getTime() + accessTokenExpirationPeriod)) .withClaim(EMAIL_CLAIM, email) - .sign(Algorithm.HMAC512(secretKey)); // HMAC512 알고리즘 사용, application-jwt.yml에서 지정한 secret 키로 암호화 + .sign(Algorithm.HMAC512(secretKey)); } + + /** * RefreshToken 생성 * RefreshToken은 Claim에 email도 넣지 않으므로 withClaim() X @@ -116,8 +118,8 @@ public Optional extractRefreshToken(HttpServletRequest request) { */ public Optional extractAccessToken(HttpServletRequest request) { return Optional.ofNullable(request.getHeader(accessHeader)) - .filter(refreshToken -> refreshToken.startsWith(BEARER)) - .map(refreshToken -> refreshToken.replace(BEARER, "")); + .filter(token -> token.startsWith(BEARER)) + .map(token -> token.replace(BEARER, "")); } /** @@ -127,20 +129,20 @@ public Optional extractAccessToken(HttpServletRequest request) { * 유효하다면 getClaim()으로 이메일 추출 * 유효하지 않다면 빈 Optional 객체 반환 */ - public Optional extractEmail(String accessToken) { + public Optional extractEmailFromJwt(String jwt) { try { - // 토큰 유효성 검사하는 데에 사용할 알고리즘이 있는 JWT verifier builder 반환 return Optional.ofNullable(JWT.require(Algorithm.HMAC512(secretKey)) - .build() // 반환된 빌더로 JWT verifier 생성 - .verify(accessToken) // accessToken을 검증하고 유효하지 않다면 예외 발생 - .getClaim(EMAIL_CLAIM) // claim(Emial) 가져오기 + .build() + .verify(jwt) + .getClaim(EMAIL_CLAIM) .asString()); } catch (Exception e) { - log.error("액세스 토큰이 유효하지 않습니다."); + log.error("유효하지 않은 JWT입니다. {}", e.getMessage()); return Optional.empty(); } } + /** * AccessToken 헤더 설정 */ diff --git a/src/main/java/mos/mosback/login/global/login/handler/LoginFailureHandler.java b/src/main/java/mos/mosback/login/global/login/handler/LoginFailureHandler.java index 5e34917..5718db2 100644 --- a/src/main/java/mos/mosback/login/global/login/handler/LoginFailureHandler.java +++ b/src/main/java/mos/mosback/login/global/login/handler/LoginFailureHandler.java @@ -1,5 +1,6 @@ package mos.mosback.login.global.login.handler; +import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; @@ -7,6 +8,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; /** * JWT 로그인 실패 시 처리하는 핸들러 @@ -21,7 +24,14 @@ public void onAuthenticationFailure(HttpServletRequest request, HttpServletRespo response.setStatus(HttpServletResponse.SC_BAD_REQUEST); response.setCharacterEncoding("UTF-8"); response.setContentType("text/plain;charset=UTF-8"); - response.getWriter().write("로그인 실패! 이메일이나 비밀번호를 확인해주세요."); log.info("로그인에 실패했습니다. 메시지 : {}", exception.getMessage()); + + Map responseData = new HashMap<>(); + responseData.put("status", 500); + responseData.put("success", false); + responseData.put("message" , exception.getMessage()); + response.setContentType("application/json"); + response.setStatus(HttpServletResponse.SC_OK); + response.getWriter().write(new ObjectMapper().writeValueAsString(responseData)); } } diff --git a/src/main/java/mos/mosback/login/global/login/handler/LoginSuccessHandler.java b/src/main/java/mos/mosback/login/global/login/handler/LoginSuccessHandler.java index a6e0236..0669a4a 100644 --- a/src/main/java/mos/mosback/login/global/login/handler/LoginSuccessHandler.java +++ b/src/main/java/mos/mosback/login/global/login/handler/LoginSuccessHandler.java @@ -1,16 +1,22 @@ package mos.mosback.login.global.login.handler; +import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import mos.mosback.login.domain.user.dto.UserInfo; import mos.mosback.login.domain.user.repository.UserRepository; import mos.mosback.login.global.jwt.service.JwtService; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; +import org.springframework.web.bind.annotation.RequestBody; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; @Slf4j @RequiredArgsConstructor @@ -19,17 +25,16 @@ public class LoginSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { private final JwtService jwtService; private final UserRepository userRepository; + @Value("${jwt.access.expiration}") private String accessTokenExpiration; - @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, - Authentication authentication) { + Authentication authentication) throws IOException { String email = extractUsername(authentication); // 인증 정보에서 Username(email) 추출 - String accessToken = jwtService.createAccessToken(email); // JwtService의 createAccessToken을 사용하여 AccessToken 발급 + String jwt = jwtService.createJwt(email); // JwtService의 createJwt를 사용하여 Jwt 토큰 발급 String refreshToken = jwtService.createRefreshToken(); // JwtService의 createRefreshToken을 사용하여 RefreshToken 발급 - - jwtService.sendAccessAndRefreshToken(response, accessToken, refreshToken); // 응답 헤더에 AccessToken, RefreshToken 실어서 응답 + jwtService.sendAccessAndRefreshToken(response, jwt, refreshToken); // 응답 헤더에 Jwt, RefreshToken 실어서 응답 String currentEmail = email; userRepository.findByEmail(currentEmail) @@ -38,12 +43,26 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo userRepository.saveAndFlush(user); }); log.info("로그인에 성공하였습니다. 이메일 : {}", currentEmail); - log.info("로그인에 성공하였습니다. AccessToken : {}", accessToken); - log.info("발급된 AccessToken 만료 기간 : {}", accessTokenExpiration); + log.info("로그인에 성공하였습니다. Jwt : {}", jwt); + log.info("발급된 Jwt 만료 기간 : {}", accessTokenExpiration); + + Map result = new HashMap<>(); + result.put("jwt", jwt); + + Map responseData = new HashMap<>(); + responseData.put("status", 200); + responseData.put("success", true); + responseData.put("result", result); + + response.setContentType("application/json"); + response.setStatus(HttpServletResponse.SC_OK); + response.getWriter().write(new ObjectMapper().writeValueAsString(responseData)); } + + private String extractUsername(Authentication authentication) { UserDetails userDetails = (UserDetails) authentication.getPrincipal(); return userDetails.getUsername(); } -} \ No newline at end of file +} diff --git a/src/main/java/mos/mosback/login/global/oauth2/handler/OAuth2LoginSuccessHandler.java b/src/main/java/mos/mosback/login/global/oauth2/handler/OAuth2LoginSuccessHandler.java index b143a24..ba301e0 100644 --- a/src/main/java/mos/mosback/login/global/oauth2/handler/OAuth2LoginSuccessHandler.java +++ b/src/main/java/mos/mosback/login/global/oauth2/handler/OAuth2LoginSuccessHandler.java @@ -33,37 +33,32 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo CustomOAuth2User oAuth2User = (CustomOAuth2User) authentication.getPrincipal(); // User의 Role이 GUEST일 경우 처음 요청한 회원이므로 회원가입 페이지로 리다이렉트 - if(oAuth2User.getRole() == Role.GUEST) { - - + if (oAuth2User.getRole() == Role.GUEST) { String email = oAuth2User.getAttribute("email"); String name = oAuth2User.getAttribute("name"); - String accessToken = jwtService.createAccessToken(oAuth2User.getEmail()); - response.addHeader(jwtService.getAccessHeader(), "Bearer " + accessToken); - jwtService.sendAccessAndRefreshToken(response, accessToken, null); + String jwt = jwtService.createJwt(oAuth2User.getEmail()); // JwtService의 createJwt를 사용하여 Jwt 토큰 발급 + response.addHeader(jwtService.getAccessHeader(), "Bearer " + jwt); + jwtService.sendAccessAndRefreshToken(response, jwt, null); response.sendRedirect("/profile"); // 프론트의 회원가입 추가 정보 입력 폼으로 리다이렉트 -// User findUser = userRepository.findByEmail(oAuth2User.getEmail()) -// .orElseThrow(() -> new IllegalArgumentException("이메일에 해당하는 유저가 없습니다.")); -// findUser.authorizeUser(); } else { loginSuccess(response, oAuth2User); // 로그인에 성공한 경우 access, refresh 토큰 생성 } } catch (Exception e) { throw e; } - } // TODO : 소셜 로그인 시에도 무조건 토큰 생성하지 말고 JWT 인증 필터처럼 RefreshToken 유/무에 따라 다르게 처리해보기 private void loginSuccess(HttpServletResponse response, CustomOAuth2User oAuth2User) throws IOException { - String accessToken = jwtService.createAccessToken(oAuth2User.getEmail()); - String refreshToken = jwtService.createRefreshToken(); - response.addHeader(jwtService.getAccessHeader(), "Bearer " + accessToken); + String jwt = jwtService.createJwt(oAuth2User.getEmail()); // JwtService의 createJwt를 사용하여 Jwt 토큰 발급 + String refreshToken = jwtService.createRefreshToken(); // JwtService의 createRefreshToken을 사용하여 RefreshToken 발급 + response.addHeader(jwtService.getAccessHeader(), "Bearer " + jwt); response.addHeader(jwtService.getRefreshHeader(), "Bearer " + refreshToken); - jwtService.sendAccessAndRefreshToken(response, accessToken, refreshToken); + jwtService.sendAccessAndRefreshToken(response, jwt, refreshToken); jwtService.updateRefreshToken(oAuth2User.getEmail(), refreshToken); } + } \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/controller/StRoomController.java b/src/main/java/mos/mosback/stRoom/controller/StRoomController.java index 8faad70..0d90f80 100644 --- a/src/main/java/mos/mosback/stRoom/controller/StRoomController.java +++ b/src/main/java/mos/mosback/stRoom/controller/StRoomController.java @@ -1,8 +1,9 @@ package mos.mosback.stRoom.controller; -import io.swagger.annotations.ApiImplicitParam; +/*import io.swagger.annotations.ApiImplicitParam;*/ import lombok.RequiredArgsConstructor; import mos.mosback.login.domain.user.User; import mos.mosback.login.domain.user.dto.UserProfileDto; +import mos.mosback.login.domain.user.service.UserService; import mos.mosback.stRoom.domain.stRoom.MemberStatus; import mos.mosback.stRoom.dto.*; import mos.mosback.stRoom.service.StRoomService; @@ -27,43 +28,60 @@ public class StRoomController { private final StRoomService stRoomService; // stRoomService를 주입. private final ToDoService toDoService; + private final UserService userService; @PostMapping("/create") - public ResponseEntity saveRoom(@RequestBody StRoomSaveRequestDto requestDto, HttpServletRequest req) { + public ResponseEntity> saveRoom(@RequestBody StRoomSaveRequestDto requestDto, HttpServletRequest req) { // 현재 로그인한 사용자의 정보 가져오기 + Map response = new HashMap<>(); Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String currentEmail = authentication.getName(); // 현재 사용자의 이메일 requestDto.setEmail(currentEmail); Long stroomId = stRoomService.save(requestDto, req); - if (stroomId != null) { - return ResponseEntity.status(HttpStatus.CREATED).body - ("message: created successfully. ID:" + stroomId +"\nsuccess:true \nstatus:201"); + try{ + if (stroomId != null) { + response.put("status", 201); + response.put("success", true); + response.put("message", "스터디룸 생성완료."+ "룸아이디:"+stroomId); + return ResponseEntity.ok(response); } else { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body - ("message: Bad Request \nsuccess:false \nstatus:400"); + response.put("status", 501); + response.put("success", false); + response.put("message", "서버내부오류"); + return ResponseEntity.ok(response); + } + } catch (Exception e) { + response.put("status", 501); + response.put("success", false); + response.put("message", "서버내부오류"); + return ResponseEntity.ok(response); } } + @GetMapping("/my{roomId}") public ResponseEntity FindByID (@PathVariable Long roomId) { StRoomResponseDto stroom = stRoomService.findById(roomId); - List studyRoomMemberList = stRoomService.getStudyRoomMemberList(roomId); + List studyRoomMemberList = stRoomService.getStudyRoomMembers(roomId); StRoomMemberResponseDto leaderInfo = studyRoomMemberList.stream() .filter(data -> MemberStatus.Leader.name().equals(data.getStatus().name())) .findFirst().orElseThrow(() -> new EntityNotFoundException("leader info not found")); User leaderUser = stRoomService .getUserInfo(leaderInfo.getMemberId()); stroom.setNickname(leaderUser.getNickname()); + stroom.setUserImg(leaderUser.getImageUrl()); stroom.setMemberNum(studyRoomMemberList.size()); return new ResponseEntity<>(stroom,HttpStatus.OK); } + @GetMapping("/search") public ResponseEntity searchRoom(@RequestParam String keyword) { try { List strooms = stRoomService.findByTitleContaining(keyword); + return new ResponseEntity<>(strooms, HttpStatus.OK); } catch (IllegalArgumentException e) { Map response = new HashMap<>(); @@ -74,14 +92,20 @@ public ResponseEntity searchRoom(@RequestParam String keyword) { } } @PutMapping("/update/{roomId}") - public ResponseEntity UpdateRoom(@PathVariable Long roomId, @RequestBody StRoomUpdateRequestDto requestDto) { + public ResponseEntity> UpdateRoom(@PathVariable Long roomId, @RequestBody StRoomUpdateRequestDto requestDto) { + Map response = new HashMap<>(); try { stRoomService.update(roomId, requestDto); - return ResponseEntity.ok - ("message: updated successfully. roomId:"+roomId+"\nsuccess:true\nstatus:200"); + response.put("status", 200); + response.put("success", true); + response.put("message", "deleted"+"'"+roomId+"'"); + return ResponseEntity.ok(response); + } catch (IllegalArgumentException e) { - return ResponseEntity.status(HttpStatus.NOT_FOUND) - .body("message: NOT FOUND "+"'"+roomId+"'"+"\nsuccess:false\nstatus:404"); + response.put("status", 404); + response.put("success", false); + response.put("message", "해당 스터디룸 없음 :"+"'"+roomId+"'"); + return ResponseEntity.ok(response); } } @@ -97,7 +121,7 @@ public ResponseEntity> deleteRoom(@PathVariable Long roomId) } catch (EntityNotFoundException ex) { response.put("status", 404); response.put("success", false); - response.put("message", "NOTFOUND"+"'"+roomId+"'"); + response.put("message", "해당스터디룸 없음 : "+"'"+roomId+"'"); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); } } @@ -191,7 +215,7 @@ public ResponseEntity getQuestionandAnswerById(@PathVariable("memberId") Long } } @PostMapping("/memberjoin/{roomId}") - public ResponseEntity memberJoin(@PathVariable Long roomId, + public ResponseEntity> memberJoin(@PathVariable Long roomId, @RequestBody StRoomMemberJoinRequestDto requestDto) { // 현재 로그인한 사용자의 정보 가져오기 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); @@ -199,8 +223,12 @@ public ResponseEntity memberJoin(@PathVariable Long roomId, requestDto.setEmail(currentEmail); requestDto.setRoomId(roomId); stRoomService.memberJoin(requestDto); - return ResponseEntity.status(HttpStatus.CREATED).body - ("message : joined successfully.\nstatus : 201\n success: true"); + + Map response = new HashMap<>(); + response.put("status:", HttpStatus.CREATED.value()); + response.put("success", true); + response.put("message", " joined successfully."); + return ResponseEntity.status(HttpStatus.CREATED).body(response); } @PostMapping("/accept/{roomId}") @@ -282,19 +310,19 @@ public ResponseEntity> getMyStudyMemberHistory() throws Exce } @GetMapping("/Info/{roomId}") - @ApiImplicitParam(name = "Authorization", value = "Access Token", required = true, allowEmptyValue = false, paramType = "header", example = "Bearer access_token") + /* @ApiImplicitParam(name = "Authorization", value = "Access Token", required = true, allowEmptyValue = false, paramType = "header", example = "Bearer access_token")*/ public ResponseEntity> recruitInfo(@PathVariable Long roomId) { String recruitInfo = stRoomService.isRecruiting(roomId); StRoomDetailResponseDto stroom = stRoomService.findByRoomId(roomId); List todoList = toDoService.findStRoomTodoByRoomId(roomId); - List studyRoomMemberList = stRoomService.getStudyRoomMemberList(roomId); + List studyRoomMemberList = stRoomService.getStudyRoomMembers(roomId); StRoomMemberResponseDto leaderInfo = studyRoomMemberList.stream() .filter(data -> MemberStatus.Leader.name().equals(data.getStatus().name())) .findFirst().orElseThrow(() -> new EntityNotFoundException("leader info not found")); User leaderUser = stRoomService.getUserInfo(leaderInfo.getMemberId()); stroom.setNickname(leaderUser.getNickname()); stroom.setMemberNum(studyRoomMemberList.size()); - + stroom.setUserImg(leaderUser.getImageUrl()); Map response = new HashMap<>(); response.put("모집", recruitInfo); response.put("StudyRoom", stroom); diff --git a/src/main/java/mos/mosback/stRoom/controller/TodoController.java b/src/main/java/mos/mosback/stRoom/controller/TodoController.java index fea4ce1..fea7f28 100644 --- a/src/main/java/mos/mosback/stRoom/controller/TodoController.java +++ b/src/main/java/mos/mosback/stRoom/controller/TodoController.java @@ -151,6 +151,8 @@ public ResponseEntity getMemberRoomInfo(@PathVar public ResponseEntity> getMemberTodoRank(@PathVariable Long roomId) throws Exception { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String currentEmail = authentication.getName(); // 현재 사용자의 이메일 + + List todoList = toDoService.getMemberTodoProgress(roomId, currentEmail); return new ResponseEntity<>(todoList, HttpStatus.OK); } diff --git a/src/main/java/mos/mosback/stRoom/domain/stRoom/MemberTodoRankProjection.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/MemberTodoRankProjection.java index 75e697c..f4a7879 100644 --- a/src/main/java/mos/mosback/stRoom/domain/stRoom/MemberTodoRankProjection.java +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/MemberTodoRankProjection.java @@ -4,4 +4,6 @@ public interface MemberTodoRankProjection { Long getMemberId(); double getProgress(); String getNickname(); + + String getImage(); } diff --git a/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberEntity.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberEntity.java index 8aab433..391744b 100644 --- a/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberEntity.java +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberEntity.java @@ -2,9 +2,11 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import mos.mosback.login.domain.user.User; import javax.persistence.*; import java.io.Serializable; +import java.time.LocalDateTime; @Getter // 롬복 어노테이션 @Setter @@ -30,6 +32,16 @@ public class StudyMemberEntity implements Serializable { private String answer; // 스터디 답변 + @Column + private String img; + @ManyToOne + @JoinColumn(name = "user_id") + private User user; + public Long getUserId() { + return this.user.getId(); + } + @Column + private LocalDateTime joinedAt; } diff --git a/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java index cf3273e..28b7122 100644 --- a/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java @@ -1,7 +1,9 @@ package mos.mosback.stRoom.dto; import lombok.Getter; import lombok.Setter; +import mos.mosback.login.domain.user.User; import mos.mosback.stRoom.domain.stRoom.StRoomEntity; +import mos.mosback.login.domain.user.service.UserService; import java.time.LocalDate; @@ -17,8 +19,7 @@ public class Home_RoomResponseDto { private int online; //온라인 private LocalDate startDate; //스터디 시작날짜 private LocalDate endDate; - - //+ 유저프로필사진 + private String Img; public Home_RoomResponseDto(StRoomEntity entity) { this.title = entity.getTitle(); @@ -29,6 +30,7 @@ public Home_RoomResponseDto(StRoomEntity entity) { this.category = entity.getCategory(); this.memberNum = entity.getMemberNum(); this.maxMember = entity.getMaxMember(); + } } diff --git a/src/main/java/mos/mosback/stRoom/dto/MemberTodoRankResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/MemberTodoRankResponseDto.java index eb1c0f4..85c729a 100644 --- a/src/main/java/mos/mosback/stRoom/dto/MemberTodoRankResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/MemberTodoRankResponseDto.java @@ -8,5 +8,5 @@ public class MemberTodoRankResponseDto { private String nickname; private double progress; - + private String Image; } diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java index 756878b..5f9057f 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java @@ -26,6 +26,7 @@ public class StRoomDetailResponseDto { private LocalDateTime createdDate; private LocalDate deadline; private String nickname; + private String UserImg; public StRoomDetailResponseDto(StRoomEntity entity) { diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomMemberResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomMemberResponseDto.java index 3676c44..fe5ac28 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomMemberResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomMemberResponseDto.java @@ -3,9 +3,12 @@ import lombok.Data; import mos.mosback.stRoom.domain.stRoom.MemberStatus; + + @Data public class StRoomMemberResponseDto { private Long memberId; private MemberStatus status; + private String image; } diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java index 1b47c42..0a4e011 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java @@ -23,7 +23,7 @@ public class StRoomResponseDto { private LocalDate endDate; //스터디 끝나는 날짜 private List studyDayEntities; private String nickname; - /*유저프로필 + 사진*/ + private String userImg; public StRoomResponseDto(StRoomEntity entity) { diff --git a/src/main/java/mos/mosback/stRoom/dto/StudyMembershipStatusResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StudyMembershipStatusResponseDto.java new file mode 100644 index 0000000..55845a4 --- /dev/null +++ b/src/main/java/mos/mosback/stRoom/dto/StudyMembershipStatusResponseDto.java @@ -0,0 +1,25 @@ +package mos.mosback.stRoom.dto; + +public class StudyMembershipStatusResponseDto { + + + private String title; + private String status; + + public StudyMembershipStatusResponseDto(String title, String status) { + this.title = title; + this.status = status; + } + + public String getTitle() { + return title; + } + + public String getStatus() { + return status; + } + + + + +} diff --git a/src/main/java/mos/mosback/stRoom/repository/StRoomRepository.java b/src/main/java/mos/mosback/stRoom/repository/StRoomRepository.java index 4af0708..fdf0a8e 100644 --- a/src/main/java/mos/mosback/stRoom/repository/StRoomRepository.java +++ b/src/main/java/mos/mosback/stRoom/repository/StRoomRepository.java @@ -2,6 +2,7 @@ //Entity 클래스와 Entity레파지토리 위치 같아야함 import mos.mosback.stRoom.domain.stRoom.StRoomEntity; +import mos.mosback.stRoom.domain.stRoom.StudyMemberEntity; import mos.mosback.stRoom.dto.Home_RoomResponseDto; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; @@ -30,4 +31,9 @@ public interface StRoomRepository extends JpaRepository { @Query("SELECT new mos.mosback.stRoom.dto.Home_RoomResponseDto(s) FROM StRoomEntity s WHERE s.startDate > current_timestamp") List findRecruitingStudies(); + List findByMembersIn(List studyMemberships); + + List findByCreatedByUserEmail(String userEmail); + + } \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/repository/StudyMemberRepository.java b/src/main/java/mos/mosback/stRoom/repository/StudyMemberRepository.java index 3c2e309..08fd669 100644 --- a/src/main/java/mos/mosback/stRoom/repository/StudyMemberRepository.java +++ b/src/main/java/mos/mosback/stRoom/repository/StudyMemberRepository.java @@ -11,4 +11,5 @@ public interface StudyMemberRepository extends JpaRepository findAllByMemberId(Long memberId); List findAllByStRoom(StRoomEntity stRoom); + List findByStRoom(StRoomEntity stRoom); } diff --git a/src/main/java/mos/mosback/stRoom/service/StRoomService.java b/src/main/java/mos/mosback/stRoom/service/StRoomService.java index eaccdc4..1a834ca 100644 --- a/src/main/java/mos/mosback/stRoom/service/StRoomService.java +++ b/src/main/java/mos/mosback/stRoom/service/StRoomService.java @@ -24,6 +24,8 @@ import java.util.stream.Collectors; + + @RequiredArgsConstructor @Service public class StRoomService { @@ -45,7 +47,7 @@ public Long save(StRoomSaveRequestDto requestDto, HttpServletRequest req) { String accessToken = Optional.ofNullable(jwtService.extractAccessToken(req)).get().orElse(""); // 4. Access Token으로 스터디 멤버 정보 가져오기 (User Entity를) - String loginUserEmail = Optional.ofNullable(jwtService.extractEmail(accessToken)).get().orElse(""); + String loginUserEmail = Optional.ofNullable(jwtService.extractEmailFromJwt(accessToken)).get().orElse(""); User user = userService.getUserByEmail(loginUserEmail); @@ -55,6 +57,10 @@ public Long save(StRoomSaveRequestDto requestDto, HttpServletRequest req) { studyMember.setStatus(MemberStatus.Leader); studyMemberRepository.save(studyMember); + //추가 + // 6. 사용자의 스터디 멤버십에 해당 스터디그룹 정보 저장 + /* user.getStudyMemberships().add(studyMember);*/ + return stRoom.getRoomId(); } catch (Exception e) { e.printStackTrace(); @@ -149,6 +155,7 @@ public void memberJoin(StRoomMemberJoinRequestDto requestDto) { studyMember.setStRoom(stRoomEntity); studyMember.setStatus(MemberStatus.Waiting); studyMember.setAnswer(requestDto.getAnswer()); + studyMember.setImg(user.getImageUrl()); studyMemberRepository.save(studyMember); } catch (Exception e) { @@ -198,6 +205,7 @@ public UserProfileDto getMemberProfileById(Long memberId) throws Exception { User user = optionalUser.get(); // 엔터티 정보를 DTO로 매핑하여 반환 return new UserProfileDto( + user.getId(), user.getNickname(), user.getName(), user.getStr_duration(), @@ -206,13 +214,13 @@ public UserProfileDto getMemberProfileById(Long memberId) throws Exception { user.getCompany(), user.getTend1(), user.getTend2(), - user.getRoomId() + user.getRoomId(), + user.getImageUrl() ); } else { throw new Exception("해당 이메일의 사용자를 찾을 수 없습니다: " + memberId); } } - public String getMyInfo(String email) throws Exception { // 3. 사용자 이메일 조회해서 save 전에 주입 User user = userService.getUserByEmail(email); @@ -263,7 +271,7 @@ public void rejectMember(AcceptMemberRequestDto requestDto){ } - public List getStudyRoomMemberList(Long roomId) { + public List getStudyRoomMembers(Long roomId) { StRoomEntity stRoom = stRoomRepository.findById(roomId) .orElseThrow(() -> new EntityNotFoundException("Room not found")); List memberEntityList = studyMemberRepository.findAllByStRoom(stRoom); @@ -272,6 +280,7 @@ public List getStudyRoomMemberList(Long roomId) { StRoomMemberResponseDto dto = new StRoomMemberResponseDto(); dto.setMemberId(item.getMemberId()); dto.setStatus(item.getStatus()); + dto.setImage(item.getImg()); memberList.add(dto); } return memberList; @@ -297,4 +306,29 @@ public List getMyStudyMemberHistory(String email) throws } return result; } + + +/* //-------------은솔 새로 추가된 부분 ----------------- + public List getStudyRoomMemberList(Long roomId) { + StRoomEntity stRoom = stRoomRepository.findById(roomId) + .orElseThrow(() -> new EntityNotFoundException("Room not found")); + + List memberList = studyMemberRepository + .findByStRoom(stRoom) + .stream() + .map(member -> new StRoomMemberResponseDto(member.getMemberId(),member.getStatus()); + .collect(Collectors.toList()); + + return memberList; + + } + public List getLeaderStudies(String userEmail) { + // 사용자의 이메일을 기반으로 Leader로 등록된 스터디룸을 조회하여 StRoomEntity 목록을 얻어옴 + List leaderStudies = stRoomRepository.findByCreatedByUserEmail(userEmail); + + // StRoomEntity 목록을 StRoomResponseDto 목록으로 변환하여 반환 + return leaderStudies.stream() + .map(StRoomResponseDto::new) + .collect(Collectors.toList()); + }*/ } \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/service/ToDoService.java b/src/main/java/mos/mosback/stRoom/service/ToDoService.java index 18a5092..91b037b 100644 --- a/src/main/java/mos/mosback/stRoom/service/ToDoService.java +++ b/src/main/java/mos/mosback/stRoom/service/ToDoService.java @@ -169,8 +169,6 @@ private String getDayOfKoreanWeek(int i) { public List getMemberTodoProgress(Long roomId,String currentEmail) throws Exception { List progressList = new ArrayList<>(); List progressProjections = studyMemberToDoRepository.getRankByStRoom(roomId); - List memberList = stRoomService.getStudyRoomMemberList(roomId); - for (MemberTodoRankProjection progressProjection : progressProjections) { User user = stRoomService.getUserInfo(progressProjection.getMemberId()); @@ -178,6 +176,7 @@ public List getMemberTodoProgress(Long roomId,String MemberTodoRankResponseDto progress = new MemberTodoRankResponseDto(); progress.setProgress(progressProjection.getProgress()); progress.setNickname(user.getNickname()); + progress.setImage(user.getImageUrl()); progressList.add(progress); } @@ -185,4 +184,7 @@ public List getMemberTodoProgress(Long roomId,String return progressList; } + + + } diff --git a/src/main/resources/application-jwt.yml b/src/main/resources/application-jwt.yml index d68b877..1d8febf 100644 --- a/src/main/resources/application-jwt.yml +++ b/src/main/resources/application-jwt.yml @@ -1,5 +1,5 @@ jwt: - secretKey: secretkey + secretKey: 'sdrffdsedrftgyhhgfdse' access: expiration: 360000000 # 1??(60?) (1000L(ms -> s) * 60L(s -> m) * 60L(m -> h)) @@ -7,4 +7,4 @@ jwt: refresh: expiration: 1209600000 # (1000L(ms -> s) * 60L(s -> m) * 60L(m -> h) * 24L(h -> ??) * 14(2?)) - header: Authorization-refresh + header: Authorization-refresh \ No newline at end of file diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml new file mode 100644 index 0000000..d10c6cc --- /dev/null +++ b/src/main/resources/application-local.yml @@ -0,0 +1,5 @@ +cloud: + aws: + credentials: + accessKey: AKIAZ2K7DUYBWM7JVB4I + secretKey: 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 \ No newline at end of file diff --git a/src/main/resources/application-oauth.yml b/src/main/resources/application-oauth.yml deleted file mode 100644 index 4959327..0000000 --- a/src/main/resources/application-oauth.yml +++ /dev/null @@ -1,42 +0,0 @@ -spring: - security: - oauth2: - client: - registration: - google: - client-id: 729954756779-2usa0d48vh0048r4vmmljtlrlstvcjdh.apps.googleusercontent.com - client-secret: 구글시크릿 - scope: profile, email - - - naver: - client-id: jg5_V_oaR2k60xfasDRa - client-secret: 네이버시크릿 - redirect-uri: http://localhost:8080/login/oauth2/code/naver - authorization-grant-type: authorization_code - scope: name, email, profile_image - client-name: Naver - - - kakao: - client-id: bbe971abb2538851ddabe4ef20d76744 - client-secret: 카카오시크릿 - redirect-uri: http://localhost:8080/login/oauth2/code/kakao - client-authentication-method: POST - authorization-grant-type: authorization_code - scope: profile_nickname, profile_image - client-name: Kakao - - - provider: - naver: - authorization_uri: https://nid.naver.com/oauth2.0/authorize - token_uri: https://nid.naver.com/oauth2.0/token - user-info-uri: https://openapi.naver.com/v1/nid/me - user_name_attribute: response - - kakao: - authorization-uri: https://kauth.kakao.com/oauth/authorize - token-uri: https://kauth.kakao.com/oauth/token - user-info-uri: https://kapi.kakao.com/v2/user/me - user-name-attribute: id \ No newline at end of file diff --git a/src/main/resources/application-real.properties b/src/main/resources/application-real.properties new file mode 100644 index 0000000..6f4160c --- /dev/null +++ b/src/main/resources/application-real.properties @@ -0,0 +1,5 @@ +spring.profiles.include=oauth,real-db + +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect + +spring.session.store-type=jdbc diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 2896985..e126b45 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -10,7 +10,7 @@ spring: activate: on-profile: "local" mvc: - pathmatch: + pathmatch: matching-strategy: ant_path_matcher h2: console: @@ -43,18 +43,18 @@ spring: mail: - host: smtp.naver.com # 이메일 서버 호스트 (Gmail 사용 예) - port: 587 # SMTP 포트 (Gmail의 경우 465 또는 587) - username: # 이메일 계정 - password: 비밀번호 + host: smtp.naver.com # ??? ?? ??? (Gmail ?? ?) + port: 587 # SMTP ?? (Gmail? ?? 465 ?? 587) + username: # ??? ?? + password: ???? properties: mail: smtp: auth: true starttls: - enable: true # TLS를 사용하려면 true, SSL을 사용하려면 false - debug: true # 디버그 모드 활성화 + enable: true # TLS? ????? true, SSL? ????? false + debug: true # ??? ?? ??? logging: level: root: DEBUG \ No newline at end of file From d9a9bc61c8c1dbba1fbad275431178e5ee97eb45 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Tue, 7 Nov 2023 13:00:31 +0900 Subject: [PATCH 50/60] =?UTF-8?q?=EC=8A=A4=ED=84=B0=EB=94=94=EB=A3=B8=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20-=20=EB=A9=A4=EB=B2=84=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EA=B5=AC=ED=98=84=EB=81=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/mos/mosback/Application.java | 5 +- .../mos/mosback/login/domain/user/User.java | 23 ++- .../user/controller/UserController.java | 4 +- .../login/domain/user/dto/UserInfo.java | 5 + .../login/domain/user/dto/UserProfileDto.java | 3 +- .../domain/user/service/UserService.java | 39 ++--- .../login/global/jwt/service/JwtService.java | 4 - .../stRoom/controller/StRoomController.java | 147 ++++++++++-------- .../stRoom/controller/TodoController.java | 2 - .../stRoom/MemberTodoRankProjection.java | 2 - .../stRoom/domain/stRoom/StRoomEntity.java | 12 ++ .../domain/stRoom/StudyMemberEntity.java | 23 ++- .../stRoom/dto/Home_RoomResponseDto.java | 6 +- .../stRoom/dto/MemberTodoRankResponseDto.java | 2 +- .../stRoom/dto/StRoomDetailResponseDto.java | 1 - .../stRoom/dto/StRoomMemberResponseDto.java | 4 +- .../mosback/stRoom/dto/StRoomResponseDto.java | 2 +- .../dto/StudyMembershipStatusResponseDto.java | 26 ++-- .../stRoom/repository/StRoomRepository.java | 2 +- .../repository/StudyMemberRepository.java | 4 +- .../mosback/stRoom/service/StRoomService.java | 28 +--- .../mosback/stRoom/service/ToDoService.java | 6 +- src/main/resources/application-jwt.yml | 10 -- src/main/resources/application-oauth.yml | 42 +++++ .../resources/application-real.properties | 5 - src/main/resources/application-real.yml | 9 ++ src/main/resources/application.yml | 73 ++++++--- src/main/resources/static/index.html | 7 +- src/main/resources/templates/create_form.html | 0 src/main/resources/templates/index.html | 0 .../mos/mosback/MosbackApplicationTests.java | 0 .../java/mos/mosback/UserServiceTest.java | 57 +++++++ src/test/java/mos/mosback/WithMockUser.java | 4 + .../mosback/domain/posts/PostsRepository.java | 4 + .../controller/LeaderStudyControllerTest.java | 7 + 35 files changed, 353 insertions(+), 215 deletions(-) delete mode 100644 src/main/resources/application-jwt.yml create mode 100644 src/main/resources/application-oauth.yml delete mode 100644 src/main/resources/application-real.properties create mode 100644 src/main/resources/application-real.yml delete mode 100644 src/main/resources/templates/create_form.html delete mode 100644 src/main/resources/templates/index.html delete mode 100644 src/test/java/mos/mosback/MosbackApplicationTests.java create mode 100644 src/test/java/mos/mosback/UserServiceTest.java create mode 100644 src/test/java/mos/mosback/login/domain/user/controller/LeaderStudyControllerTest.java diff --git a/src/main/java/mos/mosback/Application.java b/src/main/java/mos/mosback/Application.java index 1601181..699a667 100644 --- a/src/main/java/mos/mosback/Application.java +++ b/src/main/java/mos/mosback/Application.java @@ -5,8 +5,9 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; + @Slf4j -@EnableJpaAuditing //JPA Auditing 활성화 +@EnableJpaAuditing @SpringBootApplication(exclude = {SecurityAutoConfiguration.class, org.springframework.cloud.aws.autoconfigure.context.ContextInstanceDataAutoConfiguration.class, org.springframework.cloud.aws.autoconfigure.context.ContextStackAutoConfiguration.class, @@ -17,4 +18,4 @@ public static void main(String[] args) { SpringApplication.run(Application.class, args); } -} \ No newline at end of file +} diff --git a/src/main/java/mos/mosback/login/domain/user/User.java b/src/main/java/mos/mosback/login/domain/user/User.java index 897b57d..6935789 100644 --- a/src/main/java/mos/mosback/login/domain/user/User.java +++ b/src/main/java/mos/mosback/login/domain/user/User.java @@ -3,11 +3,13 @@ import lombok.*; import mos.mosback.stRoom.domain.stRoom.StRoomEntity; +import mos.mosback.stRoom.domain.stRoom.StudyMemberEntity; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import javax.persistence.*; import java.util.*; +import java.util.stream.Collectors; @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -23,11 +25,22 @@ public class User { private Long id; + @Column(name ="room_id") + private Long roomId; + @OneToMany private List stRooms= new ArrayList<>(); - @Column(name ="room_id") - private Long roomId; + @OneToMany(mappedBy = "user", cascade = CascadeType.ALL) + private List studyMemberships = new ArrayList<>(); + + public List getStudyMemberships() { + return studyMemberships; + } + public void addStudyMembership(StudyMemberEntity studyMember) { + this.studyMemberships.add(studyMember); + studyMember.setUser(this); + } private String email; // 이메일 private String password; // 비밀번호 @@ -47,6 +60,8 @@ public class User { private String company; private String tend1; + private String tend2; + public String getTend1() { return tend1; @@ -64,7 +79,7 @@ public void setTend2(String tend2) { this.tend2 = tend2; } - private String tend2; + @Enumerated(EnumType.STRING) private Role role; @@ -97,6 +112,8 @@ public void setRoomId(Long roomId) { + + public void setId(Long id) { this.id = id; } diff --git a/src/main/java/mos/mosback/login/domain/user/controller/UserController.java b/src/main/java/mos/mosback/login/domain/user/controller/UserController.java index 513ec1c..6abd5c9 100644 --- a/src/main/java/mos/mosback/login/domain/user/controller/UserController.java +++ b/src/main/java/mos/mosback/login/domain/user/controller/UserController.java @@ -122,7 +122,7 @@ public ResponseEntity> sendTemporaryPassword(@RequestBody Fi } - /* @GetMapping("/user/list") + @GetMapping("/user/list") public ResponseEntity> getLeaderStudies() { Map response = new HashMap<>(); try { @@ -144,6 +144,6 @@ public ResponseEntity> getLeaderStudies() { return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR); } - }*/ + } } diff --git a/src/main/java/mos/mosback/login/domain/user/dto/UserInfo.java b/src/main/java/mos/mosback/login/domain/user/dto/UserInfo.java index e982d00..73e015d 100644 --- a/src/main/java/mos/mosback/login/domain/user/dto/UserInfo.java +++ b/src/main/java/mos/mosback/login/domain/user/dto/UserInfo.java @@ -4,6 +4,7 @@ public class UserInfo { private String email; private String password; + private String nickname; // 생성자, 게터/세터 등 생략 @@ -14,4 +15,8 @@ public String getEmail() { public String getPassword() { return password; } + + public String getNickname(){ + return nickname; + } } \ No newline at end of file diff --git a/src/main/java/mos/mosback/login/domain/user/dto/UserProfileDto.java b/src/main/java/mos/mosback/login/domain/user/dto/UserProfileDto.java index 2184577..124b030 100644 --- a/src/main/java/mos/mosback/login/domain/user/dto/UserProfileDto.java +++ b/src/main/java/mos/mosback/login/domain/user/dto/UserProfileDto.java @@ -50,9 +50,9 @@ public UserProfileDto(Long id,String nickname, String name, Date str_duration, this.end_duration = end_duration; this.message = message; this.company = company; + this.roomId = roomId; this.tend1 = tend1; this.tend2= tend2; - this.roomId = roomId; this.imageUrl=imageUrl; @@ -74,3 +74,4 @@ public void setImageUrl(String imageUrl) { } + diff --git a/src/main/java/mos/mosback/login/domain/user/service/UserService.java b/src/main/java/mos/mosback/login/domain/user/service/UserService.java index 5ffab19..d8fa5d8 100644 --- a/src/main/java/mos/mosback/login/domain/user/service/UserService.java +++ b/src/main/java/mos/mosback/login/domain/user/service/UserService.java @@ -25,11 +25,17 @@ import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; +import javax.persistence.EntityNotFoundException; import javax.transaction.Transactional; +import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.InputStream; import java.util.*; +import java.util.function.Function; import java.util.stream.Collectors; +import static com.amazonaws.services.ec2.model.Scope.Region; + @Service @Transactional @RequiredArgsConstructor @@ -142,7 +148,7 @@ public void updateUserProfile(String currentEmail, UserProfileDto userProfileDto user.setCompany(userProfileDto.getCompany()); user.setTend1(userProfileDto.getTend1()); user.setTend2(userProfileDto.getTend2()); -/* user.setRoomId(userProfileDto.getRoomId());*/ + user.setRoomId(userProfileDto.getRoomId()); @@ -253,9 +259,8 @@ public User findById(Long id) { return userRepository.findById(id).orElse(null); } - public UserProfileDto getMemberProfileById(Long memberId) throws Exception { - - Optional optionalUser = userRepository.findById(memberId); + public UserProfileDto getUserProfileByEmail(String email) throws Exception { + Optional optionalUser = userRepository.findByEmail(email); if (optionalUser.isPresent()) { User user = optionalUser.get(); // 엔터티 정보를 DTO로 매핑하여 반환 @@ -273,10 +278,11 @@ public UserProfileDto getMemberProfileById(Long memberId) throws Exception { user.getImageUrl() ); } else { - throw new Exception("해당 이메일의 사용자를 찾을 수 없습니다: " + memberId); + throw new Exception("해당 이메일의 사용자를 찾을 수 없습니다: " + email); } } + public List getStudyGroupsForUserByEmail(String email) throws NotFoundException { Optional userOptional = userRepository.findByEmail(email); if (userOptional.isPresent()) { @@ -364,28 +370,7 @@ public List getStudyMembershipStatus(String us // } - public UserProfileDto getUserProfileByEmail(String email) throws Exception { - Optional optionalUser = userRepository.findByEmail(email); - if (optionalUser.isPresent()) { - User user = optionalUser.get(); - // 엔터티 정보를 DTO로 매핑하여 반환 - return new UserProfileDto( - user.getId(), - user.getNickname(), - user.getName(), - user.getStr_duration(), - user.getEnd_duration(), - user.getMessage(), - user.getCompany(), - user.getTend1(), - user.getTend2(), - user.getRoomId(), - user.getImageUrl() - ); - } else { - throw new Exception("해당 이메일의 사용자를 찾을 수 없습니다: " + email); - } - } + } diff --git a/src/main/java/mos/mosback/login/global/jwt/service/JwtService.java b/src/main/java/mos/mosback/login/global/jwt/service/JwtService.java index c918685..e1670b2 100644 --- a/src/main/java/mos/mosback/login/global/jwt/service/JwtService.java +++ b/src/main/java/mos/mosback/login/global/jwt/service/JwtService.java @@ -8,9 +8,6 @@ import mos.mosback.login.domain.user.User; import mos.mosback.login.domain.user.repository.UserRepository; import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; @@ -24,7 +21,6 @@ @RequiredArgsConstructor @Getter @Slf4j - public class JwtService { @Value("${jwt.secretKey}") diff --git a/src/main/java/mos/mosback/stRoom/controller/StRoomController.java b/src/main/java/mos/mosback/stRoom/controller/StRoomController.java index 0d90f80..8455009 100644 --- a/src/main/java/mos/mosback/stRoom/controller/StRoomController.java +++ b/src/main/java/mos/mosback/stRoom/controller/StRoomController.java @@ -1,9 +1,7 @@ package mos.mosback.stRoom.controller; -/*import io.swagger.annotations.ApiImplicitParam;*/ import lombok.RequiredArgsConstructor; import mos.mosback.login.domain.user.User; import mos.mosback.login.domain.user.dto.UserProfileDto; -import mos.mosback.login.domain.user.service.UserService; import mos.mosback.stRoom.domain.stRoom.MemberStatus; import mos.mosback.stRoom.dto.*; import mos.mosback.stRoom.service.StRoomService; @@ -13,13 +11,14 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; +import software.amazon.ion.NullValueException; + import javax.persistence.EntityNotFoundException; import javax.servlet.http.HttpServletRequest; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Optional; -import java.util.stream.Collectors; + @RequiredArgsConstructor @RestController @@ -28,84 +27,73 @@ public class StRoomController { private final StRoomService stRoomService; // stRoomService를 주입. private final ToDoService toDoService; - private final UserService userService; @PostMapping("/create") public ResponseEntity> saveRoom(@RequestBody StRoomSaveRequestDto requestDto, HttpServletRequest req) { // 현재 로그인한 사용자의 정보 가져오기 - Map response = new HashMap<>(); Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String currentEmail = authentication.getName(); // 현재 사용자의 이메일 requestDto.setEmail(currentEmail); Long stroomId = stRoomService.save(requestDto, req); + Map response = new HashMap<>(); + if (stroomId != null) { + + response.put("status", "201"); + response.put("message", "스터디생성완료, roomId: " + stroomId); + response.put("success", "true"); + return ResponseEntity.status(HttpStatus.OK).body(response); - try{ - if (stroomId != null) { - response.put("status", 201); - response.put("success", true); - response.put("message", "스터디룸 생성완료."+ "룸아이디:"+stroomId); - return ResponseEntity.ok(response); } else { - response.put("status", 501); - response.put("success", false); - response.put("message", "서버내부오류"); - return ResponseEntity.ok(response); - } - } catch (Exception e) { - response.put("status", 501); - response.put("success", false); + response.put("status", "500"); response.put("message", "서버내부오류"); - return ResponseEntity.ok(response); + response.put("success", "false"); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); } } - @GetMapping("/my{roomId}") public ResponseEntity FindByID (@PathVariable Long roomId) { StRoomResponseDto stroom = stRoomService.findById(roomId); - List studyRoomMemberList = stRoomService.getStudyRoomMembers(roomId); + List studyRoomMemberList = stRoomService.getStudyRoomMemberList(roomId); StRoomMemberResponseDto leaderInfo = studyRoomMemberList.stream() .filter(data -> MemberStatus.Leader.name().equals(data.getStatus().name())) .findFirst().orElseThrow(() -> new EntityNotFoundException("leader info not found")); User leaderUser = stRoomService .getUserInfo(leaderInfo.getMemberId()); stroom.setNickname(leaderUser.getNickname()); - stroom.setUserImg(leaderUser.getImageUrl()); stroom.setMemberNum(studyRoomMemberList.size()); return new ResponseEntity<>(stroom,HttpStatus.OK); } - @GetMapping("/search") public ResponseEntity searchRoom(@RequestParam String keyword) { try { List strooms = stRoomService.findByTitleContaining(keyword); - return new ResponseEntity<>(strooms, HttpStatus.OK); } catch (IllegalArgumentException e) { Map response = new HashMap<>(); response.put("status", "404"); - response.put("message", "NOT FOUND " + keyword); + response.put("message", "존재하지 않는 키워드: " + keyword); response.put("success", "false"); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); } } @PutMapping("/update/{roomId}") public ResponseEntity> UpdateRoom(@PathVariable Long roomId, @RequestBody StRoomUpdateRequestDto requestDto) { - Map response = new HashMap<>(); try { + Map response = new HashMap<>(); stRoomService.update(roomId, requestDto); - response.put("status", 200); - response.put("success", true); - response.put("message", "deleted"+"'"+roomId+"'"); - return ResponseEntity.ok(response); - + response.put("status", "201"); + response.put("message", "수정완료"); + response.put("success", "true"); + return ResponseEntity.status(HttpStatus.CREATED).body(response); } catch (IllegalArgumentException e) { - response.put("status", 404); - response.put("success", false); - response.put("message", "해당 스터디룸 없음 :"+"'"+roomId+"'"); - return ResponseEntity.ok(response); + Map response = new HashMap<>(); + response.put("status", "404"); + response.put("message", "해당 스터디룸 없음"); + response.put("success", "false"); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); } } @@ -116,12 +104,12 @@ public ResponseEntity> deleteRoom(@PathVariable Long roomId) stRoomService.delete(roomId); response.put("status", 200); response.put("success", true); - response.put("message", "deleted"+"'"+roomId+"'"); + response.put("message", "삭제완료 : "+"'"+roomId+"'"); return ResponseEntity.ok(response); } catch (EntityNotFoundException ex) { response.put("status", 404); response.put("success", false); - response.put("message", "해당스터디룸 없음 : "+"'"+roomId+"'"); + response.put("message", "해당스터디룸 찾을 수 없음"+"'"+roomId+"'"); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); } } @@ -173,7 +161,7 @@ public ResponseEntity getQuestionById(@PathVariable Long roomId) { Map response = new HashMap<>(); response.put("status:", HttpStatus.NOT_FOUND.value()); response.put("success", false); - response.put("message", "NOT FOUND"); + response.put("message", "해당 스터디룸 없음"); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); } } @@ -183,17 +171,25 @@ public ResponseEntity> getUserProfile(@PathVariable Long mem Map response = new HashMap<>(); try { UserProfileDto userProfileDto = stRoomService.getMemberProfileById(memberId); - response.put("status", 200); - response.put("success", true); - response.put("data", userProfileDto); + if(userProfileDto != null) { + response.put("status", 200); + response.put("success", true); + response.put("data", userProfileDto); + return ResponseEntity.ok(response); + } + else{ + response.put("status", 404); + response.put("success", false); + response.put("message", "해당멤버를 찾을 수 없음"); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); + } - return ResponseEntity.ok(response); } catch (Exception e) { response.put("status", 500); response.put("success", false); - response.put("message", "오류가 발생했습니다."); - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); + response.put("message", "서버내부오류"); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); } } @@ -208,7 +204,7 @@ public ResponseEntity getQuestionandAnswerById(@PathVariable("memberId") Long Map response = new HashMap<>(); response.put("status:", HttpStatus.NOT_FOUND.value()); response.put("success", false); - response.put("message", "NOT FOUND"); + response.put("message", "요청을 찾을 수 없음"); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); } @@ -223,37 +219,57 @@ public ResponseEntity> memberJoin(@PathVariable Long roomId, requestDto.setEmail(currentEmail); requestDto.setRoomId(roomId); stRoomService.memberJoin(requestDto); - - Map response = new HashMap<>(); - response.put("status:", HttpStatus.CREATED.value()); - response.put("success", true); - response.put("message", " joined successfully."); - return ResponseEntity.status(HttpStatus.CREATED).body(response); + try{ + Map response = new HashMap<>(); + response.put("status:", HttpStatus.OK.value()); + response.put("success", true); + response.put("message", "가입완료"); + return ResponseEntity.status(HttpStatus.OK).body(response); + }catch (IllegalArgumentException e){ + Map response = new HashMap<>(); + response.put("status:", HttpStatus.NOT_FOUND.value()); + response.put("success", false); + response.put("message", "해당스터디룸 없음"); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); + } } @PostMapping("/accept/{roomId}") - public ResponseEntity acceptMember(@PathVariable Long roomId, + public ResponseEntity> acceptMember(@PathVariable Long roomId, @RequestBody AcceptMemberRequestDto requestDto) { try { requestDto.setRoomId(roomId); stRoomService.acceptMember(requestDto); - return ResponseEntity.status(HttpStatus.CREATED).body - ("message : Accepted successfully.\nstatus : 201\n success: true"); + Map response = new HashMap<>(); + response.put("status:", HttpStatus.OK.value()); + response.put("success", false); + response.put("message", "승인완료"); + return ResponseEntity.status(HttpStatus.OK).body(response); }catch (IllegalArgumentException ex){ - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) - .body("message : ServerError.ServerError.\nstatus : 500\n success: false"); + Map response = new HashMap<>(); + response.put("status:", HttpStatus.BAD_REQUEST.value()); + response.put("success", false); + response.put("message", "잘못된 요청"); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response); } } @PostMapping("/reject/{roomId}") - public ResponseEntity rejectMember(@PathVariable Long roomId, + public ResponseEntity> rejectMember(@PathVariable Long roomId, @RequestBody AcceptMemberRequestDto requestDto) { try { requestDto.setRoomId(roomId); stRoomService.rejectMember(requestDto); - return ResponseEntity.status(HttpStatus.CREATED).body - ("message : Rejected successfully.\nstatus : 201\n success: true"); + Map response = new HashMap<>(); + response.put("status:", HttpStatus.OK.value()); + response.put("success", false); + response.put("message", "승인거절완료"); + return ResponseEntity.status(HttpStatus.OK).body(response); }catch (IllegalArgumentException ex){ - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("message : ServerError.ServerError.\nstatus : 500\n success: false"); + Map response = new HashMap<>(); + response.put("status:", HttpStatus.BAD_REQUEST.value()); + response.put("success", false); + response.put("message", "잘못된 요청"); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response); } } @@ -269,7 +285,7 @@ public ResponseEntity getRecruitingStudies() { Map response = new HashMap<>(); response.put("status", HttpStatus.NOT_FOUND.value()); response.put("success", false); - response.put("message", "NOT FOUND"); + response.put("message", "스터디룸을 찾을 수 없음"); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); } @@ -310,19 +326,18 @@ public ResponseEntity> getMyStudyMemberHistory() throws Exce } @GetMapping("/Info/{roomId}") - /* @ApiImplicitParam(name = "Authorization", value = "Access Token", required = true, allowEmptyValue = false, paramType = "header", example = "Bearer access_token")*/ public ResponseEntity> recruitInfo(@PathVariable Long roomId) { String recruitInfo = stRoomService.isRecruiting(roomId); StRoomDetailResponseDto stroom = stRoomService.findByRoomId(roomId); List todoList = toDoService.findStRoomTodoByRoomId(roomId); - List studyRoomMemberList = stRoomService.getStudyRoomMembers(roomId); + List studyRoomMemberList = stRoomService.getStudyRoomMemberList(roomId); StRoomMemberResponseDto leaderInfo = studyRoomMemberList.stream() .filter(data -> MemberStatus.Leader.name().equals(data.getStatus().name())) .findFirst().orElseThrow(() -> new EntityNotFoundException("leader info not found")); User leaderUser = stRoomService.getUserInfo(leaderInfo.getMemberId()); stroom.setNickname(leaderUser.getNickname()); stroom.setMemberNum(studyRoomMemberList.size()); - stroom.setUserImg(leaderUser.getImageUrl()); + Map response = new HashMap<>(); response.put("모집", recruitInfo); response.put("StudyRoom", stroom); diff --git a/src/main/java/mos/mosback/stRoom/controller/TodoController.java b/src/main/java/mos/mosback/stRoom/controller/TodoController.java index fea7f28..fea4ce1 100644 --- a/src/main/java/mos/mosback/stRoom/controller/TodoController.java +++ b/src/main/java/mos/mosback/stRoom/controller/TodoController.java @@ -151,8 +151,6 @@ public ResponseEntity getMemberRoomInfo(@PathVar public ResponseEntity> getMemberTodoRank(@PathVariable Long roomId) throws Exception { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String currentEmail = authentication.getName(); // 현재 사용자의 이메일 - - List todoList = toDoService.getMemberTodoProgress(roomId, currentEmail); return new ResponseEntity<>(todoList, HttpStatus.OK); } diff --git a/src/main/java/mos/mosback/stRoom/domain/stRoom/MemberTodoRankProjection.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/MemberTodoRankProjection.java index f4a7879..75e697c 100644 --- a/src/main/java/mos/mosback/stRoom/domain/stRoom/MemberTodoRankProjection.java +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/MemberTodoRankProjection.java @@ -4,6 +4,4 @@ public interface MemberTodoRankProjection { Long getMemberId(); double getProgress(); String getNickname(); - - String getImage(); } diff --git a/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomEntity.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomEntity.java index d055f33..f7bfa02 100644 --- a/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomEntity.java +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomEntity.java @@ -1,8 +1,11 @@ package mos.mosback.stRoom.domain.stRoom; +import com.fasterxml.jackson.annotation.JsonManagedReference; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import mos.mosback.login.domain.user.User; + import javax.persistence.*; import java.time.LocalDate; import java.util.*; @@ -49,6 +52,15 @@ public class StRoomEntity extends BaseTimeEntity { private List studyDayEntities = new ArrayList<>(); + @JsonManagedReference + @OneToMany(mappedBy = "stRoom") + private List members = new ArrayList<>(); + + @ManyToOne + @JoinColumn(name = "created_by_user_email") + private User createdByUser; + + @Builder public StRoomEntity(String title, String goal, String rules, String quest, String category, String intro, int memberNum, int maxMember diff --git a/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberEntity.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberEntity.java index 391744b..0a77022 100644 --- a/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberEntity.java +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberEntity.java @@ -1,4 +1,5 @@ package mos.mosback.stRoom.domain.stRoom; +import com.fasterxml.jackson.annotation.JsonBackReference; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -19,6 +20,15 @@ public class StudyMemberEntity implements Serializable { @Column(name = "memberID") private Long memberId; + @ManyToOne + @JoinColumn(name = "user_id") + private User user; + public Long getUserId() { + return this.user.getId(); + } + + + @JsonBackReference @ManyToOne @JoinColumn(name = "roomId") private StRoomEntity stRoom; @@ -31,17 +41,6 @@ public class StudyMemberEntity implements Serializable { @Column private String answer; // 스터디 답변 - - @Column - private String img; - - @ManyToOne - @JoinColumn(name = "user_id") - private User user; - public Long getUserId() { - return this.user.getId(); - } @Column private LocalDateTime joinedAt; - -} +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java index 28b7122..cf3273e 100644 --- a/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java @@ -1,9 +1,7 @@ package mos.mosback.stRoom.dto; import lombok.Getter; import lombok.Setter; -import mos.mosback.login.domain.user.User; import mos.mosback.stRoom.domain.stRoom.StRoomEntity; -import mos.mosback.login.domain.user.service.UserService; import java.time.LocalDate; @@ -19,7 +17,8 @@ public class Home_RoomResponseDto { private int online; //온라인 private LocalDate startDate; //스터디 시작날짜 private LocalDate endDate; - private String Img; + + //+ 유저프로필사진 public Home_RoomResponseDto(StRoomEntity entity) { this.title = entity.getTitle(); @@ -30,7 +29,6 @@ public Home_RoomResponseDto(StRoomEntity entity) { this.category = entity.getCategory(); this.memberNum = entity.getMemberNum(); this.maxMember = entity.getMaxMember(); - } } diff --git a/src/main/java/mos/mosback/stRoom/dto/MemberTodoRankResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/MemberTodoRankResponseDto.java index 85c729a..eb1c0f4 100644 --- a/src/main/java/mos/mosback/stRoom/dto/MemberTodoRankResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/MemberTodoRankResponseDto.java @@ -8,5 +8,5 @@ public class MemberTodoRankResponseDto { private String nickname; private double progress; - private String Image; + } diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java index 5f9057f..756878b 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomDetailResponseDto.java @@ -26,7 +26,6 @@ public class StRoomDetailResponseDto { private LocalDateTime createdDate; private LocalDate deadline; private String nickname; - private String UserImg; public StRoomDetailResponseDto(StRoomEntity entity) { diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomMemberResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomMemberResponseDto.java index fe5ac28..f3495ea 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomMemberResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomMemberResponseDto.java @@ -3,12 +3,10 @@ import lombok.Data; import mos.mosback.stRoom.domain.stRoom.MemberStatus; - - @Data public class StRoomMemberResponseDto { private Long memberId; private MemberStatus status; - private String image; + } diff --git a/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java index 0a4e011..1b47c42 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StRoomResponseDto.java @@ -23,7 +23,7 @@ public class StRoomResponseDto { private LocalDate endDate; //스터디 끝나는 날짜 private List studyDayEntities; private String nickname; - private String userImg; + /*유저프로필 + 사진*/ public StRoomResponseDto(StRoomEntity entity) { diff --git a/src/main/java/mos/mosback/stRoom/dto/StudyMembershipStatusResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StudyMembershipStatusResponseDto.java index 55845a4..c62233f 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StudyMembershipStatusResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StudyMembershipStatusResponseDto.java @@ -3,23 +3,23 @@ public class StudyMembershipStatusResponseDto { - private String title; - private String status; + private String title; + private String status; - public StudyMembershipStatusResponseDto(String title, String status) { - this.title = title; - this.status = status; - } + public StudyMembershipStatusResponseDto(String title, String status) { + this.title = title; + this.status = status; + } - public String getTitle() { - return title; - } + public String getTitle() { + return title; + } - public String getStatus() { - return status; - } + public String getStatus() { + return status; + } -} +} \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/repository/StRoomRepository.java b/src/main/java/mos/mosback/stRoom/repository/StRoomRepository.java index fdf0a8e..57337ae 100644 --- a/src/main/java/mos/mosback/stRoom/repository/StRoomRepository.java +++ b/src/main/java/mos/mosback/stRoom/repository/StRoomRepository.java @@ -31,9 +31,9 @@ public interface StRoomRepository extends JpaRepository { @Query("SELECT new mos.mosback.stRoom.dto.Home_RoomResponseDto(s) FROM StRoomEntity s WHERE s.startDate > current_timestamp") List findRecruitingStudies(); + List findByMembersIn(List studyMemberships); List findByCreatedByUserEmail(String userEmail); - } \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/repository/StudyMemberRepository.java b/src/main/java/mos/mosback/stRoom/repository/StudyMemberRepository.java index 08fd669..824a7f1 100644 --- a/src/main/java/mos/mosback/stRoom/repository/StudyMemberRepository.java +++ b/src/main/java/mos/mosback/stRoom/repository/StudyMemberRepository.java @@ -8,8 +8,10 @@ public interface StudyMemberRepository extends JpaRepository { - List findAllByMemberId(Long memberId); List findAllByStRoom(StRoomEntity stRoom); + List findAllByMemberId(Long memberId); List findByStRoom(StRoomEntity stRoom); + + } diff --git a/src/main/java/mos/mosback/stRoom/service/StRoomService.java b/src/main/java/mos/mosback/stRoom/service/StRoomService.java index 1a834ca..5283907 100644 --- a/src/main/java/mos/mosback/stRoom/service/StRoomService.java +++ b/src/main/java/mos/mosback/stRoom/service/StRoomService.java @@ -24,8 +24,6 @@ import java.util.stream.Collectors; - - @RequiredArgsConstructor @Service public class StRoomService { @@ -57,10 +55,6 @@ public Long save(StRoomSaveRequestDto requestDto, HttpServletRequest req) { studyMember.setStatus(MemberStatus.Leader); studyMemberRepository.save(studyMember); - //추가 - // 6. 사용자의 스터디 멤버십에 해당 스터디그룹 정보 저장 - /* user.getStudyMemberships().add(studyMember);*/ - return stRoom.getRoomId(); } catch (Exception e) { e.printStackTrace(); @@ -155,7 +149,6 @@ public void memberJoin(StRoomMemberJoinRequestDto requestDto) { studyMember.setStRoom(stRoomEntity); studyMember.setStatus(MemberStatus.Waiting); studyMember.setAnswer(requestDto.getAnswer()); - studyMember.setImg(user.getImageUrl()); studyMemberRepository.save(studyMember); } catch (Exception e) { @@ -221,6 +214,7 @@ public UserProfileDto getMemberProfileById(Long memberId) throws Exception { throw new Exception("해당 이메일의 사용자를 찾을 수 없습니다: " + memberId); } } + public String getMyInfo(String email) throws Exception { // 3. 사용자 이메일 조회해서 save 전에 주입 User user = userService.getUserByEmail(email); @@ -271,7 +265,7 @@ public void rejectMember(AcceptMemberRequestDto requestDto){ } - public List getStudyRoomMembers(Long roomId) { + public List getStudyRoomMemberList(Long roomId) { StRoomEntity stRoom = stRoomRepository.findById(roomId) .orElseThrow(() -> new EntityNotFoundException("Room not found")); List memberEntityList = studyMemberRepository.findAllByStRoom(stRoom); @@ -280,7 +274,6 @@ public List getStudyRoomMembers(Long roomId) { StRoomMemberResponseDto dto = new StRoomMemberResponseDto(); dto.setMemberId(item.getMemberId()); dto.setStatus(item.getStatus()); - dto.setImage(item.getImg()); memberList.add(dto); } return memberList; @@ -308,20 +301,6 @@ public List getMyStudyMemberHistory(String email) throws } -/* //-------------은솔 새로 추가된 부분 ----------------- - public List getStudyRoomMemberList(Long roomId) { - StRoomEntity stRoom = stRoomRepository.findById(roomId) - .orElseThrow(() -> new EntityNotFoundException("Room not found")); - - List memberList = studyMemberRepository - .findByStRoom(stRoom) - .stream() - .map(member -> new StRoomMemberResponseDto(member.getMemberId(),member.getStatus()); - .collect(Collectors.toList()); - - return memberList; - - } public List getLeaderStudies(String userEmail) { // 사용자의 이메일을 기반으로 Leader로 등록된 스터디룸을 조회하여 StRoomEntity 목록을 얻어옴 List leaderStudies = stRoomRepository.findByCreatedByUserEmail(userEmail); @@ -330,5 +309,6 @@ public List getLeaderStudies(String userEmail) { return leaderStudies.stream() .map(StRoomResponseDto::new) .collect(Collectors.toList()); - }*/ + } + } \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/service/ToDoService.java b/src/main/java/mos/mosback/stRoom/service/ToDoService.java index 91b037b..18a5092 100644 --- a/src/main/java/mos/mosback/stRoom/service/ToDoService.java +++ b/src/main/java/mos/mosback/stRoom/service/ToDoService.java @@ -169,6 +169,8 @@ private String getDayOfKoreanWeek(int i) { public List getMemberTodoProgress(Long roomId,String currentEmail) throws Exception { List progressList = new ArrayList<>(); List progressProjections = studyMemberToDoRepository.getRankByStRoom(roomId); + List memberList = stRoomService.getStudyRoomMemberList(roomId); + for (MemberTodoRankProjection progressProjection : progressProjections) { User user = stRoomService.getUserInfo(progressProjection.getMemberId()); @@ -176,7 +178,6 @@ public List getMemberTodoProgress(Long roomId,String MemberTodoRankResponseDto progress = new MemberTodoRankResponseDto(); progress.setProgress(progressProjection.getProgress()); progress.setNickname(user.getNickname()); - progress.setImage(user.getImageUrl()); progressList.add(progress); } @@ -184,7 +185,4 @@ public List getMemberTodoProgress(Long roomId,String return progressList; } - - - } diff --git a/src/main/resources/application-jwt.yml b/src/main/resources/application-jwt.yml deleted file mode 100644 index 1d8febf..0000000 --- a/src/main/resources/application-jwt.yml +++ /dev/null @@ -1,10 +0,0 @@ -jwt: - secretKey: 'sdrffdsedrftgyhhgfdse' - - access: - expiration: 360000000 # 1??(60?) (1000L(ms -> s) * 60L(s -> m) * 60L(m -> h)) - header: Authorization - - refresh: - expiration: 1209600000 # (1000L(ms -> s) * 60L(s -> m) * 60L(m -> h) * 24L(h -> ??) * 14(2?)) - header: Authorization-refresh \ No newline at end of file diff --git a/src/main/resources/application-oauth.yml b/src/main/resources/application-oauth.yml new file mode 100644 index 0000000..f0c2b4a --- /dev/null +++ b/src/main/resources/application-oauth.yml @@ -0,0 +1,42 @@ +spring: + security: + oauth2: + client: + registration: + google: + client-id: 729954756779-2usa0d48vh0048r4vmmljtlrlstvcjdh.apps.googleusercontent.com + client-secret: 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 + scope: profile, email + + + naver: + client-id: jg5_V_oaR2k60xfasDRa + client-secret: XJ2kRT_oa8 + redirect-uri: http://localhost:8080/login/oauth2/code/naver + authorization-grant-type: authorization_code + scope: name, email, profile_image + client-name: Naver + + + kakao: + client-id: bbe971abb2538851ddabe4ef20d76744 + client-secret: oScTITuccuMT1o8C6X4Vv1arBKJkNzSE + redirect-uri: http://localhost:8080/login/oauth2/code/kakao + client-authentication-method: POST + authorization-grant-type: authorization_code + scope: profile_nickname, profile_image + client-name: Kakao + + + provider: + naver: + authorization_uri: https://nid.naver.com/oauth2.0/authorize + token_uri: https://nid.naver.com/oauth2.0/token + user-info-uri: https://openapi.naver.com/v1/nid/me + user_name_attribute: response + + kakao: + authorization-uri: https://kauth.kakao.com/oauth/authorize + token-uri: https://kauth.kakao.com/oauth/token + user-info-uri: https://kapi.kakao.com/v2/user/me + user-name-attribute: id \ No newline at end of file diff --git a/src/main/resources/application-real.properties b/src/main/resources/application-real.properties deleted file mode 100644 index 6f4160c..0000000 --- a/src/main/resources/application-real.properties +++ /dev/null @@ -1,5 +0,0 @@ -spring.profiles.include=oauth,real-db - -spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect - -spring.session.store-type=jdbc diff --git a/src/main/resources/application-real.yml b/src/main/resources/application-real.yml new file mode 100644 index 0000000..9a9b169 --- /dev/null +++ b/src/main/resources/application-real.yml @@ -0,0 +1,9 @@ +spring: + profiles: + include: oauth,real-db + jpa: + properties: + hibernate: + dialect: org.hibernate.dialect.MySQL5InnoDBDialect + session: + store-type: jdbc diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index e126b45..e97078d 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,21 +1,18 @@ spring: profiles: - group: - "local" : "local, jwt, oauth" - active : local - + active: local --- spring: config: activate: on-profile: "local" - mvc: - pathmatch: - matching-strategy: ant_path_matcher + h2: console: enabled: true path: /h2-console + settings: + web-allow-others: true datasource: driver-class-name: org.h2.Driver @@ -23,38 +20,64 @@ spring: username: sa password: - server: - port: 8080 - main: allow-circular-references: true jpa: show-sql: true - defer-datasource-initialization: true database-platform: org.hibernate.dialect.H2Dialect properties: hibernate: format_sql: true show_sql: true - - hibernate: - ddl-auto: create - + ddl-auto: create mail: - host: smtp.naver.com # ??? ?? ??? (Gmail ?? ?) - port: 587 # SMTP ?? (Gmail? ?? 465 ?? 587) - username: # ??? ?? - password: ???? - + host: smtp.naver.com + port: 465 + username: ${MAIL_USERNAME} + password: ${MAIL_PASSWORD} properties: mail: smtp: auth: true starttls: - enable: true # TLS? ????? true, SSL? ????? false - debug: true # ??? ?? ??? - logging: - level: - root: DEBUG \ No newline at end of file + enable: true + debug: true + +jwt: + secretKey: 'dfadfekndchnsdifqld125654x8sdfnjldsncuelsdfs45x321df' + + access: + expiration: 360000000 # 1??(60?) (1000L(ms -> s) * 60L(s -> m) * 60L(m -> h)) + header: Authorization + + refresh: + expiration: 1209600000 # (1000L(ms -> s) * 60L(s -> m) * 60L(m -> h) * 24L(h -> ??) * 14(2?)) + header: Authorization-refresh + +logging: + level: + root: DEBUG + +cloud: + aws: + credentials: + accessKey: AKIAZ2K7DUYBW6RY24QH + secretKey: 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 + region: + static: ap-northeast-2 + stack: + auto: false + autoconfigure: + exclude: + - org.springframework.cloud.aws.autoconfigure.context.ContextInstanceDataAutoConfiguration + - org.springframework.cloud.aws.autoconfigure.context.ContextRegionProviderAutoConfiguration + - org.springframework.cloud.aws.autoconfigure.context.ContextStackAutoConfiguration + - org.springframework.cloud.aws.autoconfigure.context.ContextCredentialsAutoConfiguration + +application: + bucket: + name: mos-s3-bucket + + diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html index c87dcc5..201c426 100644 --- a/src/main/resources/static/index.html +++ b/src/main/resources/static/index.html @@ -1,3 +1,8 @@ Kakao Login
Google Login
-Naver Login
\ No newline at end of file +Naver Login
+ +
+ + +
\ No newline at end of file diff --git a/src/main/resources/templates/create_form.html b/src/main/resources/templates/create_form.html deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html deleted file mode 100644 index e69de29..0000000 diff --git a/src/test/java/mos/mosback/MosbackApplicationTests.java b/src/test/java/mos/mosback/MosbackApplicationTests.java deleted file mode 100644 index e69de29..0000000 diff --git a/src/test/java/mos/mosback/UserServiceTest.java b/src/test/java/mos/mosback/UserServiceTest.java new file mode 100644 index 0000000..064de69 --- /dev/null +++ b/src/test/java/mos/mosback/UserServiceTest.java @@ -0,0 +1,57 @@ +package mos.mosback; + +import mos.mosback.stRoom.domain.stRoom.StRoomEntity; +import mos.mosback.stRoom.repository.StRoomRepository; +import mos.mosback.login.domain.user.service.UserService; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@SpringBootTest +public class UserServiceTest { + + @Autowired + private UserService userService; + + @Autowired + private StRoomRepository stRoomRepository; + + @Test + public void testGetStudyGroupsForUserByMemberId() { + // Arrange: 테스트용 memberId와 연관된 스터디 그룹 데이터를 미리 데이터베이스에 저장합니다. + Long memberId = 1L; // 테스트용 memberId + // TODO: 스터디 그룹 데이터베이스에 저장 (예: StRoomEntity 객체 생성 및 stRoomRepository.save()) + + // Act: getStudyGroupsForUserByMemberId 메서드를 호출하여 실제 반환값을 가져옵니다. + List studyGroups = userService.getStudyGroupsForUserByMemberId(memberId); + List expectedStudyGroups = new ArrayList<>(); + +// 예상되는 스터디 그룹을 추가합니다. + StRoomEntity studyGroup1 = new StRoomEntity(); + studyGroup1.setTitle("Study Group 1"); +// TODO: studyGroup1의 다른 필드를 설정 + + StRoomEntity studyGroup2 = new StRoomEntity(); + studyGroup2.setTitle("Study Group 2"); +// TODO: studyGroup2의 다른 필드를 설정 + + expectedStudyGroups.add(studyGroup1); + expectedStudyGroups.add(studyGroup2); + // TODO: expectedStudyGroups를 설정 (실제로 기대하는 스터디 그룹 데이터를 데이터베이스에 저장하고 가져와서 설정) + + // Assert: 반환된 스터디 그룹 목록이 예상한 값과 일치하는지를 검증합니다. + // 예상한 스터디 그룹 개수와 일치하는지 검증 + assertEquals(expectedStudyGroups.size(), studyGroups.size()); + + // 각 스터디 그룹에 대한 추가적인 검증 (예: 제목, 설명 등) + for (int i = 0; i < expectedStudyGroups.size(); i++) { + assertEquals(expectedStudyGroups.get(i).getTitle(), studyGroups.get(i).getTitle()); + // TODO: 다른 필드들을 비교하여 일치하는지 확인 + } + } +} diff --git a/src/test/java/mos/mosback/WithMockUser.java b/src/test/java/mos/mosback/WithMockUser.java index e69de29..9d0207f 100644 --- a/src/test/java/mos/mosback/WithMockUser.java +++ b/src/test/java/mos/mosback/WithMockUser.java @@ -0,0 +1,4 @@ +package mos.mosback; + +public @interface WithMockUser { +} diff --git a/src/test/java/mos/mosback/domain/posts/PostsRepository.java b/src/test/java/mos/mosback/domain/posts/PostsRepository.java index e69de29..1cdc1ac 100644 --- a/src/test/java/mos/mosback/domain/posts/PostsRepository.java +++ b/src/test/java/mos/mosback/domain/posts/PostsRepository.java @@ -0,0 +1,4 @@ +package mos.mosback.domain.posts; + +public class PostsRepository { +} diff --git a/src/test/java/mos/mosback/login/domain/user/controller/LeaderStudyControllerTest.java b/src/test/java/mos/mosback/login/domain/user/controller/LeaderStudyControllerTest.java new file mode 100644 index 0000000..6b5228d --- /dev/null +++ b/src/test/java/mos/mosback/login/domain/user/controller/LeaderStudyControllerTest.java @@ -0,0 +1,7 @@ +package mos.mosback.login.domain.user.controller; + +import static org.junit.jupiter.api.Assertions.*; + +class LeaderStudyControllerTest { + +} \ No newline at end of file From 600d1552baaad3f4977c247a88cad7213976fe2c Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Tue, 7 Nov 2023 23:43:40 +0900 Subject: [PATCH 51/60] =?UTF-8?q?=EC=8A=A4=ED=84=B0=EB=94=94=EB=A3=B8=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20-=20=EB=A9=A4=EB=B2=84=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EA=B5=AC=ED=98=84=EB=81=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../login/global/config/MailConfig.java | 4 +- .../stRoom/controller/StRoomController.java | 60 ++++--- .../stRoom/controller/TodoController.java | 170 ++++++++++++------ .../stRoom/MemberTodoRankProjection.java | 1 + .../dto/MemberTodoProgressResponseDto.java | 11 ++ .../mosback/stRoom/service/StRoomService.java | 15 +- .../mosback/stRoom/service/ToDoService.java | 26 ++- src/main/resources/application-local.yml | 123 ++++++++++++- src/main/resources/application.yml | 4 +- 9 files changed, 319 insertions(+), 95 deletions(-) create mode 100644 src/main/java/mos/mosback/stRoom/dto/MemberTodoProgressResponseDto.java diff --git a/src/main/java/mos/mosback/login/global/config/MailConfig.java b/src/main/java/mos/mosback/login/global/config/MailConfig.java index db25081..a4768ed 100644 --- a/src/main/java/mos/mosback/login/global/config/MailConfig.java +++ b/src/main/java/mos/mosback/login/global/config/MailConfig.java @@ -11,10 +11,10 @@ @Configuration public class MailConfig { - @Value("${MAIL_USERNAME}") + @Value("${spring.mail.username}") private String mailUsername; - @Value("${MAIL_PASSWORD}") + @Value("${spring.mail.password}") private String mailPassword; @Bean public JavaMailSender javaMailService() { diff --git a/src/main/java/mos/mosback/stRoom/controller/StRoomController.java b/src/main/java/mos/mosback/stRoom/controller/StRoomController.java index 8455009..b45f0e4 100644 --- a/src/main/java/mos/mosback/stRoom/controller/StRoomController.java +++ b/src/main/java/mos/mosback/stRoom/controller/StRoomController.java @@ -38,15 +38,16 @@ public ResponseEntity> saveRoom(@RequestBody StRoomSaveReque Map response = new HashMap<>(); if (stroomId != null) { - response.put("status", "201"); - response.put("message", "스터디생성완료, roomId: " + stroomId); - response.put("success", "true"); + response.put("status", 201); + response.put("message", "스터디생성완료"); + response.put("roomId",stroomId); + response.put("success", true); return ResponseEntity.status(HttpStatus.OK).body(response); } else { - response.put("status", "500"); + response.put("status", 500); response.put("message", "서버내부오류"); - response.put("success", "false"); + response.put("success", false); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); } } @@ -54,16 +55,23 @@ public ResponseEntity> saveRoom(@RequestBody StRoomSaveReque public ResponseEntity FindByID (@PathVariable Long roomId) { StRoomResponseDto stroom = stRoomService.findById(roomId); - List studyRoomMemberList = stRoomService.getStudyRoomMemberList(roomId); - StRoomMemberResponseDto leaderInfo = studyRoomMemberList.stream() - .filter(data -> MemberStatus.Leader.name().equals(data.getStatus().name())) - .findFirst().orElseThrow(() -> new EntityNotFoundException("leader info not found")); - User leaderUser = stRoomService .getUserInfo(leaderInfo.getMemberId()); - stroom.setNickname(leaderUser.getNickname()); - stroom.setMemberNum(studyRoomMemberList.size()); - - return new ResponseEntity<>(stroom,HttpStatus.OK); - + try { + List studyRoomMemberList = stRoomService.getStudyRoomMemberList(roomId); + StRoomMemberResponseDto leaderInfo = studyRoomMemberList.stream() + .filter(data -> MemberStatus.Leader.name().equals(data.getStatus().name())) + .findFirst().orElseThrow(() -> new EntityNotFoundException("leader info not found")); + User leaderUser = stRoomService.getUserInfo(leaderInfo.getMemberId()); + stroom.setNickname(leaderUser.getNickname()); + stroom.setMemberNum(studyRoomMemberList.size()); + + return new ResponseEntity<>(stroom, HttpStatus.OK); + }catch (Exception e){ + Map response = new HashMap<>(); + response.put("status", 404); + response.put("message", "해당 스터디룸 없음" ); + response.put("success", false); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); + } } @GetMapping("/search") @@ -72,10 +80,10 @@ public ResponseEntity searchRoom(@RequestParam String keyword) { List strooms = stRoomService.findByTitleContaining(keyword); return new ResponseEntity<>(strooms, HttpStatus.OK); } catch (IllegalArgumentException e) { - Map response = new HashMap<>(); - response.put("status", "404"); + Map response = new HashMap<>(); + response.put("status", 404); response.put("message", "존재하지 않는 키워드: " + keyword); - response.put("success", "false"); + response.put("success", false); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); } } @@ -84,15 +92,15 @@ public ResponseEntity> UpdateRoom(@PathVariable Long roomId, try { Map response = new HashMap<>(); stRoomService.update(roomId, requestDto); - response.put("status", "201"); + response.put("status", 201); response.put("message", "수정완료"); - response.put("success", "true"); + response.put("success", true); return ResponseEntity.status(HttpStatus.CREATED).body(response); } catch (IllegalArgumentException e) { Map response = new HashMap<>(); - response.put("status", "404"); + response.put("status", 404); response.put("message", "해당 스터디룸 없음"); - response.put("success", "false"); + response.put("success", false); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); } } @@ -109,7 +117,7 @@ public ResponseEntity> deleteRoom(@PathVariable Long roomId) } catch (EntityNotFoundException ex) { response.put("status", 404); response.put("success", false); - response.put("message", "해당스터디룸 찾을 수 없음"+"'"+roomId+"'"); + response.put("message", "해당 스터디룸 없음"); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); } } @@ -242,7 +250,7 @@ public ResponseEntity> acceptMember(@PathVariable Long roomI stRoomService.acceptMember(requestDto); Map response = new HashMap<>(); response.put("status:", HttpStatus.OK.value()); - response.put("success", false); + response.put("success", true); response.put("message", "승인완료"); return ResponseEntity.status(HttpStatus.OK).body(response); }catch (IllegalArgumentException ex){ @@ -261,7 +269,7 @@ public ResponseEntity> rejectMember(@PathVariable Long roomI stRoomService.rejectMember(requestDto); Map response = new HashMap<>(); response.put("status:", HttpStatus.OK.value()); - response.put("success", false); + response.put("success", true); response.put("message", "승인거절완료"); return ResponseEntity.status(HttpStatus.OK).body(response); }catch (IllegalArgumentException ex){ @@ -285,7 +293,7 @@ public ResponseEntity getRecruitingStudies() { Map response = new HashMap<>(); response.put("status", HttpStatus.NOT_FOUND.value()); response.put("success", false); - response.put("message", "스터디룸을 찾을 수 없음"); + response.put("message", "모집중인 스터디룸을 찾을 수 없음"); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); } diff --git a/src/main/java/mos/mosback/stRoom/controller/TodoController.java b/src/main/java/mos/mosback/stRoom/controller/TodoController.java index fea4ce1..0991192 100644 --- a/src/main/java/mos/mosback/stRoom/controller/TodoController.java +++ b/src/main/java/mos/mosback/stRoom/controller/TodoController.java @@ -1,4 +1,6 @@ package mos.mosback.stRoom.controller; +import mos.mosback.login.domain.user.dto.NicknameDto; +import mos.mosback.stRoom.domain.stRoom.MemberStatus; import mos.mosback.stRoom.domain.stRoom.StudyMemberTodoEntity; import mos.mosback.stRoom.domain.stRoom.ToDoEntity; import mos.mosback.stRoom.dto.*; @@ -9,7 +11,12 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; +import org.springframework.web.client.HttpClientErrorException; + +import javax.persistence.EntityNotFoundException; +import java.util.HashMap; import java.util.List; +import java.util.Map; @RestController @@ -23,35 +30,44 @@ public TodoController(ToDoService toDoService) { } @PostMapping("todo/add/{roomId}") - public ResponseEntity addTodo(@RequestBody stRoomToDoRequestDto requestDto, @PathVariable Long roomId) { + public ResponseEntity> addTodo(@RequestBody stRoomToDoRequestDto requestDto, @PathVariable Long roomId) { try{ + ToDoEntity todo = toDoService.addTodo(requestDto, roomId); - return ResponseEntity.status(HttpStatus.CREATED).body - ("TodoList 추가 완료." + - "\ntodoIndex : " + todo.getTodoId() + - "\nstatus:201" + - "\nsuccess:true"); + Map response = new HashMap<>(); + response.put("status:", HttpStatus.OK.value()); + response.put("success",true); + response.put("index",todo.getTodoId()); + response.put("message", "todo추가완료"); + return ResponseEntity.ok(response); }catch(IllegalArgumentException ex) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body - ("TodoList 추가 실패" + - "\nstatus:404" + - "\nsuccess:false"); + Map response = new HashMap<>(); + response.put("status:", HttpStatus.INTERNAL_SERVER_ERROR.value()); + response.put("success",false); + response.put("message","서버내부오류"); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); } } @PostMapping("/member/todo/add") - public ResponseEntity addMemberTodo(@RequestBody StudyMemberToDoRequestDto requestDto) throws Exception{ + public ResponseEntity> addMemberTodo(@RequestBody StudyMemberToDoRequestDto requestDto) throws Exception{ try { // 현재 로그인한 사용자의 정보 가져오기 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String currentEmail = authentication.getName(); // 현재 사용자의 이메일 requestDto.setCurrentEmail(currentEmail); StudyMemberTodoEntity todo = toDoService.addMemberTodo(requestDto); - return ResponseEntity.status(HttpStatus.CREATED).body("TodoList 추가 완료. index : " +todo.getIdx()); + Map response = new HashMap<>(); + response.put("status:", HttpStatus.OK.value()); + response.put("success",true); + response.put("index",todo.getIdx()); + response.put("message", "todo추가완료"); + return ResponseEntity.status(HttpStatus.OK).body(response); }catch (IllegalArgumentException ex){ - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) - .body("ServerError"+ - "\nstatus:500" + - "\nsuccess:false"); + Map response = new HashMap<>(); + response.put("status:", HttpStatus.INTERNAL_SERVER_ERROR.value()); + response.put("success",false); + response.put("message","서버내부오류"); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); } } //todo개수만큼 프론트에서 호출해줘야함 @@ -59,23 +75,32 @@ public ResponseEntity addMemberTodo(@RequestBody StudyMemberToDoRequestD @PutMapping("todo/{todoId}") - public ResponseEntity updateTodo(@PathVariable Long todoId, @RequestBody stRoomToDoRequestDto requestDto) { + public ResponseEntity> updateTodo(@PathVariable Long todoId, @RequestBody stRoomToDoRequestDto requestDto) { try { ToDoEntity updatedToDo = toDoService.updateTodo(todoId, requestDto.getTodoContent(),requestDto.getStatus()); - return ResponseEntity.ok - ("ToDo 업데이트 완료. \nIndex: " + todoId+ - "\nstatus:200" + - "\nsuccess:true"); + Map response = new HashMap<>(); + if(updatedToDo != null) { + response.put("status:", HttpStatus.OK.value()); + response.put("success", true); + response.put("message", "Todo수정완료"); + return ResponseEntity.status(HttpStatus.OK).body(response); + }else { + response.put("status:", HttpStatus.NOT_FOUND.value()); + response.put("success", false); + response.put("message", "해당Todo없음"); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); + } } catch (IllegalArgumentException e) { - return ResponseEntity.status(HttpStatus.NOT_FOUND) - .body("NOT FOUND TODO"+ - "\nstatus:401" + - "\nsuccess:false"); + Map response = new HashMap<>(); + response.put("status:", HttpStatus.INTERNAL_SERVER_ERROR.value()); + response.put("success",false); + response.put("message","서버내부오류"); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); } } @PutMapping("/member/todo/{todoIdx}") - public ResponseEntity updateMemberTodo(@PathVariable Long todoIdx, + public ResponseEntity> updateMemberTodo(@PathVariable Long todoIdx, @RequestBody StudyMemberToDoRequestDto requestDto) throws Exception { // 현재 로그인한 사용자의 정보 가져오기 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); @@ -84,60 +109,87 @@ public ResponseEntity updateMemberTodo(@PathVariable Long todoIdx, try { StudyMemberTodoEntity updatedToDo = toDoService.updateMemberTodo(todoIdx, requestDto.getTodoContent(), requestDto.getStatus(), currentEmail); - return ResponseEntity.ok - ("Study Member ToDo 업데이트 완료. \nIndex: " + todoIdx + - "\nstatus:200" + - "\nsuccess:true"); + Map response = new HashMap<>(); + if(updatedToDo != null) { + response.put("status:", HttpStatus.OK.value()); + response.put("success", true); + response.put("message", "Todo수정완료"); + return ResponseEntity.status(HttpStatus.OK).body(response); + }else { + response.put("status:", HttpStatus.NOT_FOUND.value()); + response.put("success", false); + response.put("message", "해당Todo없음"); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); + } } catch (IllegalArgumentException e) { - return ResponseEntity.status(HttpStatus.NOT_FOUND) - .body("NOT FOUND TODO"+ - "\nstatus:401" + - "\nsuccess:false"); + Map response = new HashMap<>(); + response.put("status:", HttpStatus.INTERNAL_SERVER_ERROR.value()); + response.put("success",false); + response.put("message","서버내부오류"); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); } } @DeleteMapping("todo/{todoId}") - public ResponseEntity deleteTodo(@PathVariable Long todoId) { + public ResponseEntity> deleteTodo(@PathVariable Long todoId) { try { toDoService.deleteTodo(todoId); - return ResponseEntity.ok - ("ToDo 삭제 완료. Index: " + todoId+ - "\nstatus:200" + - "\nsuccess:true"); + Map response = new HashMap<>(); + response.put("status:", HttpStatus.OK.value()); + response.put("success", true); + response.put("message", "Todo삭제완료"); + return ResponseEntity.status(HttpStatus.OK).body(response); } catch (IllegalArgumentException e) { - return ResponseEntity.status(HttpStatus.NOT_FOUND) - .body("NOT FOUND TODO"+ - "\nstatus:401" + - "\nsuccess:false"); + Map response = new HashMap<>(); + response.put("status:", HttpStatus.INTERNAL_SERVER_ERROR.value()); + response.put("success",false); + response.put("message","서버내부오류"); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); } } @DeleteMapping("/member/todo/{todoIdx}") - public ResponseEntity deleteMemberTodo(@PathVariable Long todoIdx) throws Exception{ + public ResponseEntity> deleteMemberTodo(@PathVariable Long todoIdx) throws Exception{ // 현재 로그인한 사용자의 정보 가져오기 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String currentEmail = authentication.getName(); // 현재 사용자의 이메일 try { toDoService.deleteMemberTodo(todoIdx, currentEmail); - return ResponseEntity.ok - ("Study Member ToDo 삭제 완료. Index: " + todoIdx+ - "\nstatus:200" + - "\nsuccess:true"); + Map response = new HashMap<>(); + response.put("status:", HttpStatus.OK.value()); + response.put("success", true); + response.put("message", "Todo삭제완료"); + return ResponseEntity.status(HttpStatus.OK).body(response); } catch (IllegalArgumentException e) { - return ResponseEntity.status(HttpStatus.NOT_FOUND) - .body("NOT FOUND TODO"+ - "\nstatus:401" + - "\nsuccess:false"); + Map response = new HashMap<>(); + response.put("status:", HttpStatus.INTERNAL_SERVER_ERROR.value()); + response.put("success",false); + response.put("message","서버내부오류"); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); } + } @GetMapping("todo/{roomId}") - public ResponseEntity> findStRoomTodoByRoomId(@PathVariable Long roomId) { + public ResponseEntity> findStRoomTodoByRoomId(@PathVariable Long roomId) { List todo = toDoService.findStRoomTodoByRoomId(roomId); - return new ResponseEntity<>(todo, HttpStatus.OK); + Map response = new HashMap<>(); + + if (!todo.isEmpty()) { + response.put("status", HttpStatus.OK.value()); + response.put("success", true); + response.put("todo", todo); + return ResponseEntity.status(HttpStatus.OK).body(response); + } else { + response.put("status", HttpStatus.NOT_FOUND.value()); + response.put("success", false); + response.put("message", "Todo를 찾을 수 없음"); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); + } } + @GetMapping("/member/room/{roomId}") public ResponseEntity getMemberRoomInfo(@PathVariable Long roomId) throws Exception { // 현재 로그인한 사용자의 정보 가져오기 @@ -148,11 +200,17 @@ public ResponseEntity getMemberRoomInfo(@PathVar } @GetMapping("/todoRank/{roomId}") - public ResponseEntity> getMemberTodoRank(@PathVariable Long roomId) throws Exception { + public ResponseEntity> getMemberTodoRank(@PathVariable Long roomId) throws Exception { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String currentEmail = authentication.getName(); // 현재 사용자의 이메일 List todoList = toDoService.getMemberTodoProgress(roomId, currentEmail); - return new ResponseEntity<>(todoList, HttpStatus.OK); + MemberTodoProgressResponseDto todoProgress = toDoService.getProgressInfo(roomId,currentEmail); + Map response = new HashMap<>(); + response.put("data", todoProgress); + response.put("TodoRank", todoList); + return ResponseEntity.status(HttpStatus.OK).body(response); + + } diff --git a/src/main/java/mos/mosback/stRoom/domain/stRoom/MemberTodoRankProjection.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/MemberTodoRankProjection.java index 75e697c..c9f445d 100644 --- a/src/main/java/mos/mosback/stRoom/domain/stRoom/MemberTodoRankProjection.java +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/MemberTodoRankProjection.java @@ -4,4 +4,5 @@ public interface MemberTodoRankProjection { Long getMemberId(); double getProgress(); String getNickname(); + } diff --git a/src/main/java/mos/mosback/stRoom/dto/MemberTodoProgressResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/MemberTodoProgressResponseDto.java new file mode 100644 index 0000000..878fe4e --- /dev/null +++ b/src/main/java/mos/mosback/stRoom/dto/MemberTodoProgressResponseDto.java @@ -0,0 +1,11 @@ +package mos.mosback.stRoom.dto; + +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +public class MemberTodoProgressResponseDto { + private double avg; + private String userNick; +} diff --git a/src/main/java/mos/mosback/stRoom/service/StRoomService.java b/src/main/java/mos/mosback/stRoom/service/StRoomService.java index 5283907..eabe178 100644 --- a/src/main/java/mos/mosback/stRoom/service/StRoomService.java +++ b/src/main/java/mos/mosback/stRoom/service/StRoomService.java @@ -82,11 +82,16 @@ public void update(Long roomId, StRoomUpdateRequestDto requestDto) { @Transactional(readOnly = true) - public StRoomResponseDto findById(Long roomId) { - StRoomEntity stRoomEntity = stRoomRepository.findById(roomId) - .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id=" + roomId)); - - return new StRoomResponseDto(stRoomEntity); + public StRoomResponseDto findById(Long roomId) { + try { + StRoomEntity stRoomEntity = stRoomRepository.findById(roomId) + .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id=" + roomId)); + + return new StRoomResponseDto(stRoomEntity); + }catch (Exception e){ + e.printStackTrace(); + return null; + } } @Transactional(readOnly = true) diff --git a/src/main/java/mos/mosback/stRoom/service/ToDoService.java b/src/main/java/mos/mosback/stRoom/service/ToDoService.java index 18a5092..98ae9be 100644 --- a/src/main/java/mos/mosback/stRoom/service/ToDoService.java +++ b/src/main/java/mos/mosback/stRoom/service/ToDoService.java @@ -171,7 +171,6 @@ public List getMemberTodoProgress(Long roomId,String List progressProjections = studyMemberToDoRepository.getRankByStRoom(roomId); List memberList = stRoomService.getStudyRoomMemberList(roomId); - for (MemberTodoRankProjection progressProjection : progressProjections) { User user = stRoomService.getUserInfo(progressProjection.getMemberId()); @@ -181,8 +180,31 @@ public List getMemberTodoProgress(Long roomId,String progressList.add(progress); } - return progressList; } + public MemberTodoProgressResponseDto getProgressInfo(Long roomId, String currentEmail) throws Exception { + MemberTodoProgressResponseDto todoProgress = new MemberTodoProgressResponseDto(); + User user = userService.getUserByEmail(currentEmail); + todoProgress.setUserNick(user.getNickname()); + + StudyRoomTodoInfoDto studyRoomTodoAverage = null; + try { + studyRoomTodoAverage = studyMemberToDoRepository.getStudyRoomTodoAverage(roomId); + } catch (Exception e) { + e.printStackTrace(); + } + + if (studyRoomTodoAverage != null) { + // DB에 데이터가 존재할 때에만 해당 로직 수행 + double totalCount = studyRoomTodoAverage.getTotalCount(); + double completedCount = studyRoomTodoAverage.getCompletedCount(); + double average = (totalCount - completedCount) / totalCount * 100; + todoProgress.setAvg(average); + } else { + todoProgress.setAvg(0.0); + } + + return todoProgress; + } } diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index d10c6cc..4c19177 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -1,5 +1,124 @@ +spring: + profiles: + active: local +--- +spring: + config: + activate: + on-profile: "local" + security: + oauth2: + client: + registration: + google: + client-id: 729954756779-2usa0d48vh0048r4vmmljtlrlstvcjdh.apps.googleusercontent.com + client-secret: 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 + scope: profile, email + + + naver: + client-id: jg5_V_oaR2k60xfasDRa + client-secret: XJ2kRT_oa8 + redirect-uri: http://localhost:8080/login/oauth2/code/naver + authorization-grant-type: authorization_code + scope: name, email, profile_image + client-name: Naver + + + kakao: + client-id: bbe971abb2538851ddabe4ef20d76744 + client-secret: oScTITuccuMT1o8C6X4Vv1arBKJkNzSE + redirect-uri: http://localhost:8080/login/oauth2/code/kakao + client-authentication-method: POST + authorization-grant-type: authorization_code + scope: profile_nickname, profile_image + client-name: Kakao + + + provider: + naver: + authorization_uri: https://nid.naver.com/oauth2.0/authorize + token_uri: https://nid.naver.com/oauth2.0/token + user-info-uri: https://openapi.naver.com/v1/nid/me + user_name_attribute: response + + kakao: + authorization-uri: https://kauth.kakao.com/oauth/authorize + token-uri: https://kauth.kakao.com/oauth/token + user-info-uri: https://kapi.kakao.com/v2/user/me + user-name-attribute: id + + h2: + console: + enabled: true + path: /h2-console + settings: + web-allow-others: true + + datasource: + driver-class-name: org.h2.Driver + url: jdbc:h2:mem:testdb + username: sa + password: + + main: + allow-circular-references: true + + jpa: + show-sql: true + database-platform: org.hibernate.dialect.H2Dialect + properties: + hibernate: + format_sql: true + show_sql: true + ddl-auto: create + + mail: + host: smtp.naver.com + port: 465 + username: dmsthf1225@naver.com + password: dkffkqb77!! + properties: + mail: + smtp: + auth: true + starttls: + enable: true + debug: true + +jwt: + secretKey: 'dfadfekndchnsdifqld125654x8sdfnjldsncuelsdfs45x321df' + + access: + expiration: 360000000 # 1??(60?) (1000L(ms -> s) * 60L(s -> m) * 60L(m -> h)) + header: Authorization + + refresh: + expiration: 1209600000 # (1000L(ms -> s) * 60L(s -> m) * 60L(m -> h) * 24L(h -> ??) * 14(2?)) + header: Authorization-refresh + +logging: + level: + root: DEBUG + cloud: aws: credentials: - accessKey: AKIAZ2K7DUYBWM7JVB4I - secretKey: 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 \ No newline at end of file + accessKey: AKIAZ2K7DUYBW6RY24QH + secretKey: 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 + region: + static: ap-northeast-2 + stack: + auto: false + autoconfigure: + exclude: + - org.springframework.cloud.aws.autoconfigure.context.ContextInstanceDataAutoConfiguration + - org.springframework.cloud.aws.autoconfigure.context.ContextRegionProviderAutoConfiguration + - org.springframework.cloud.aws.autoconfigure.context.ContextStackAutoConfiguration + - org.springframework.cloud.aws.autoconfigure.context.ContextCredentialsAutoConfiguration + +application: + bucket: + name: mos-s3-bucket + + diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index e97078d..cc5eae8 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -35,8 +35,8 @@ spring: mail: host: smtp.naver.com port: 465 - username: ${MAIL_USERNAME} - password: ${MAIL_PASSWORD} + username: dmsthf1225@naver.com + password: dkffkqb77!! properties: mail: smtp: From fed7d5ac1b04a0d9e216ca0e255c26eabfb8b298 Mon Sep 17 00:00:00 2001 From: slonue <127409712+slonue@users.noreply.github.com> Date: Wed, 8 Nov 2023 00:02:17 +0900 Subject: [PATCH 52/60] Update application-local.yml --- src/main/resources/application-local.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index 4c19177..d1ebf60 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -12,13 +12,13 @@ spring: registration: google: client-id: 729954756779-2usa0d48vh0048r4vmmljtlrlstvcjdh.apps.googleusercontent.com - client-secret: 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 + client-secret: GOCSPX- scope: profile, email naver: client-id: jg5_V_oaR2k60xfasDRa - client-secret: XJ2kRT_oa8 + client-secret: redirect-uri: http://localhost:8080/login/oauth2/code/naver authorization-grant-type: authorization_code scope: name, email, profile_image @@ -27,7 +27,7 @@ spring: kakao: client-id: bbe971abb2538851ddabe4ef20d76744 - client-secret: oScTITuccuMT1o8C6X4Vv1arBKJkNzSE + client-secret: redirect-uri: http://localhost:8080/login/oauth2/code/kakao client-authentication-method: POST authorization-grant-type: authorization_code @@ -104,8 +104,8 @@ logging: cloud: aws: credentials: - accessKey: AKIAZ2K7DUYBW6RY24QH - secretKey: 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 + accessKey: + secretKey: region: static: ap-northeast-2 stack: From b0bfd9bf28ca0c993df3f9d08604120bd4a512b1 Mon Sep 17 00:00:00 2001 From: slonue <127409712+slonue@users.noreply.github.com> Date: Wed, 8 Nov 2023 00:03:03 +0900 Subject: [PATCH 53/60] Update application-oauth.yml --- src/main/resources/application-oauth.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/resources/application-oauth.yml b/src/main/resources/application-oauth.yml index f0c2b4a..4300e4c 100644 --- a/src/main/resources/application-oauth.yml +++ b/src/main/resources/application-oauth.yml @@ -5,13 +5,13 @@ spring: registration: google: client-id: 729954756779-2usa0d48vh0048r4vmmljtlrlstvcjdh.apps.googleusercontent.com - client-secret: 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 + client-secret: scope: profile, email naver: client-id: jg5_V_oaR2k60xfasDRa - client-secret: XJ2kRT_oa8 + client-secret: redirect-uri: http://localhost:8080/login/oauth2/code/naver authorization-grant-type: authorization_code scope: name, email, profile_image @@ -20,7 +20,7 @@ spring: kakao: client-id: bbe971abb2538851ddabe4ef20d76744 - client-secret: oScTITuccuMT1o8C6X4Vv1arBKJkNzSE + client-secret: redirect-uri: http://localhost:8080/login/oauth2/code/kakao client-authentication-method: POST authorization-grant-type: authorization_code @@ -39,4 +39,4 @@ spring: authorization-uri: https://kauth.kakao.com/oauth/authorize token-uri: https://kauth.kakao.com/oauth/token user-info-uri: https://kapi.kakao.com/v2/user/me - user-name-attribute: id \ No newline at end of file + user-name-attribute: id From 58d9c9ad038431bdad292902ec0b131a3049a2b5 Mon Sep 17 00:00:00 2001 From: slonue <127409712+slonue@users.noreply.github.com> Date: Wed, 8 Nov 2023 00:03:16 +0900 Subject: [PATCH 54/60] Update application.yml --- src/main/resources/application.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index cc5eae8..4f0048c 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -63,8 +63,8 @@ logging: cloud: aws: credentials: - accessKey: AKIAZ2K7DUYBW6RY24QH - secretKey: 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 + accessKey: + secretKey: region: static: ap-northeast-2 stack: From 91a160c00dec3dd137a64ac039683f08473b5641 Mon Sep 17 00:00:00 2001 From: slonue <127409712+slonue@users.noreply.github.com> Date: Wed, 8 Nov 2023 00:04:34 +0900 Subject: [PATCH 55/60] Update application.yml --- src/main/resources/application.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 4f0048c..bfb36e4 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -35,8 +35,8 @@ spring: mail: host: smtp.naver.com port: 465 - username: dmsthf1225@naver.com - password: dkffkqb77!! + username: + password: properties: mail: smtp: From 983f96ba047f25dbedff55adf74c5e5d5669fc29 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Wed, 8 Nov 2023 22:21:38 +0900 Subject: [PATCH 56/60] =?UTF-8?q?=EA=B5=AC=ED=98=84=EB=81=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/UserProfileController.java | 59 ++++----- .../stRoom/controller/StRoomController.java | 3 + .../stRoom/controller/TodoController.java | 69 ++++++---- .../stRoom/domain/stRoom/StRoomEntity.java | 4 +- .../stRoom/StRoomTodoFindProjection.java | 13 ++ .../stRoom/StRoomTodoInfoProjection.java | 7 + .../domain/stRoom/StudyMemberEntity.java | 1 - .../domain/stRoom/StudyMemberTodoEntity.java | 5 +- .../stRoom/dto/Home_RoomResponseDto.java | 4 +- .../stRoom/dto/MemberTodoResponseDto.java | 13 ++ .../dto/StudyMemberRoomInfoResponseDto.java | 2 + .../stRoom/dto/StudyMemberToDoRequestDto.java | 3 + .../mosback/stRoom/dto/StudyRoomDayDto.java | 6 +- .../stRoom/dto/stRoomToDoRequestDto.java | 3 + .../repository/MemberTodoRepository.java | 16 ++- .../stRoom/repository/ToDoRepository.java | 4 + .../mosback/stRoom/service/StRoomService.java | 3 + .../mosback/stRoom/service/ToDoService.java | 121 ++++++++++++------ 18 files changed, 229 insertions(+), 107 deletions(-) create mode 100644 src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomTodoFindProjection.java create mode 100644 src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomTodoInfoProjection.java create mode 100644 src/main/java/mos/mosback/stRoom/dto/MemberTodoResponseDto.java diff --git a/src/main/java/mos/mosback/login/domain/user/controller/UserProfileController.java b/src/main/java/mos/mosback/login/domain/user/controller/UserProfileController.java index 03ebf6a..f93cd95 100644 --- a/src/main/java/mos/mosback/login/domain/user/controller/UserProfileController.java +++ b/src/main/java/mos/mosback/login/domain/user/controller/UserProfileController.java @@ -49,35 +49,6 @@ public UserProfileController(UserService userService, UserRepository userReposit this.fileService = fileService; } - @PostMapping - public Map createUserProfile(@RequestPart(value = "file") MultipartFile file, - @RequestPart(value = "userProfileDto") UserProfileDto userProfileDto) { - Map response = new HashMap<>(); - try { - // 현재 로그인한 사용자의 정보 가져오기 - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - String currentEmail = authentication.getName(); // 현재 사용자의 이메일 - - // 회원 정보 생성 - userService.createUser(currentEmail, userProfileDto); - // 이미지 업로드 및 URL 저장 - String imageUrl = fileService.uploadFile(file, userProfileDto.getId()); - userProfileDto.setImageUrl(imageUrl); - - // 사용자 정보에 이미지 URL 업데이트 - userService.updateUserProfileImageUrl(userProfileDto.getId(), imageUrl); - - response.put("status", 200); - response.put("success", true); - response.put("message", "회원 정보가 생성되었습니다."); - } catch (Exception e) { - e.printStackTrace(); // 이 코드는 예외의 스택 트레이스를 콘솔에 출력합니다. - response.put("status", 500); - response.put("success", false); - response.put("message", "오류가 발생했습니다."); - } - return response; - } @PutMapping @@ -101,7 +72,37 @@ public Map updateUserProfile(UserProfileDto userProfileDto) thro return response; } + @PostMapping + public Map createUserProfile(@RequestPart(value = "file", required = false) MultipartFile file, + @RequestPart(value = "userProfileDto") UserProfileDto userProfileDto) { + Map response = new HashMap<>(); + try { + // 현재 로그인한 사용자의 정보 가져오기 + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + String currentEmail = authentication.getName(); // 현재 사용자의 이메일 + + // 회원 정보 생성 + userService.createUser(currentEmail, userProfileDto); + //파일이 업로드되었을 때만 이미지 업로드 및 URL 저장 + if (file != null && !file.isEmpty()) { + String imageUrl = fileService.uploadFile(file, userProfileDto.getId()); + userProfileDto.setImageUrl(imageUrl); + // 사용자 정보에 이미지 URL 업데이트 + userService.updateUserProfileImageUrl(userProfileDto.getId(), imageUrl); + } + + response.put("status", 200); + response.put("success", true); + response.put("message", "회원 정보가 생성되었습니다."); + } catch (Exception e) { + e.printStackTrace(); // 이 코드는 예외의 스택 트레이스를 콘솔에 출력합니다. + response.put("status", 500); + response.put("success", false); + response.put("message", "오류가 발생했습니다."); + } + return response; + } @GetMapping public ResponseEntity> getUserProfile() { Map response = new HashMap<>(); diff --git a/src/main/java/mos/mosback/stRoom/controller/StRoomController.java b/src/main/java/mos/mosback/stRoom/controller/StRoomController.java index b45f0e4..10138c5 100644 --- a/src/main/java/mos/mosback/stRoom/controller/StRoomController.java +++ b/src/main/java/mos/mosback/stRoom/controller/StRoomController.java @@ -3,6 +3,7 @@ import mos.mosback.login.domain.user.User; import mos.mosback.login.domain.user.dto.UserProfileDto; import mos.mosback.stRoom.domain.stRoom.MemberStatus; +import mos.mosback.stRoom.domain.stRoom.StRoomEntity; import mos.mosback.stRoom.dto.*; import mos.mosback.stRoom.service.StRoomService; import mos.mosback.stRoom.service.ToDoService; @@ -55,6 +56,7 @@ public ResponseEntity> saveRoom(@RequestBody StRoomSaveReque public ResponseEntity FindByID (@PathVariable Long roomId) { StRoomResponseDto stroom = stRoomService.findById(roomId); + try { List studyRoomMemberList = stRoomService.getStudyRoomMemberList(roomId); StRoomMemberResponseDto leaderInfo = studyRoomMemberList.stream() @@ -70,6 +72,7 @@ public ResponseEntity FindByID (@PathVariable Long roomId) { response.put("status", 404); response.put("message", "해당 스터디룸 없음" ); response.put("success", false); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); } } diff --git a/src/main/java/mos/mosback/stRoom/controller/TodoController.java b/src/main/java/mos/mosback/stRoom/controller/TodoController.java index 0991192..6a715cd 100644 --- a/src/main/java/mos/mosback/stRoom/controller/TodoController.java +++ b/src/main/java/mos/mosback/stRoom/controller/TodoController.java @@ -1,11 +1,15 @@ package mos.mosback.stRoom.controller; +import lombok.RequiredArgsConstructor; +import mos.mosback.login.domain.user.User; import mos.mosback.login.domain.user.dto.NicknameDto; +import mos.mosback.login.domain.user.service.UserService; import mos.mosback.stRoom.domain.stRoom.MemberStatus; import mos.mosback.stRoom.domain.stRoom.StudyMemberTodoEntity; import mos.mosback.stRoom.domain.stRoom.ToDoEntity; import mos.mosback.stRoom.dto.*; import mos.mosback.stRoom.service.ToDoService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.Authentication; @@ -14,25 +18,23 @@ import org.springframework.web.client.HttpClientErrorException; import javax.persistence.EntityNotFoundException; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; import java.util.HashMap; import java.util.List; import java.util.Map; +@RequiredArgsConstructor @RestController - public class TodoController { - private final ToDoService toDoService; - @Autowired - public TodoController(ToDoService toDoService) { - this.toDoService = toDoService; - } + private final ToDoService toDoService; + private final UserService userService; @PostMapping("todo/add/{roomId}") public ResponseEntity> addTodo(@RequestBody stRoomToDoRequestDto requestDto, @PathVariable Long roomId) { try{ - ToDoEntity todo = toDoService.addTodo(requestDto, roomId); Map response = new HashMap<>(); response.put("status:", HttpStatus.OK.value()); @@ -40,7 +42,7 @@ public ResponseEntity> addTodo(@RequestBody stRoomToDoReques response.put("index",todo.getTodoId()); response.put("message", "todo추가완료"); return ResponseEntity.ok(response); - }catch(IllegalArgumentException ex) { + }catch(IllegalArgumentException e) { Map response = new HashMap<>(); response.put("status:", HttpStatus.INTERNAL_SERVER_ERROR.value()); response.put("success",false); @@ -50,26 +52,27 @@ public ResponseEntity> addTodo(@RequestBody stRoomToDoReques } @PostMapping("/member/todo/add") - public ResponseEntity> addMemberTodo(@RequestBody StudyMemberToDoRequestDto requestDto) throws Exception{ - try { // 현재 로그인한 사용자의 정보 가져오기 + public ResponseEntity> addMemberTodo(@RequestBody StudyMemberToDoRequestDto requestDto) throws Exception { +// try { // 현재 로그인한 사용자의 정보 가져오기 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String currentEmail = authentication.getName(); // 현재 사용자의 이메일 requestDto.setCurrentEmail(currentEmail); StudyMemberTodoEntity todo = toDoService.addMemberTodo(requestDto); - Map response = new HashMap<>(); - response.put("status:", HttpStatus.OK.value()); - response.put("success",true); - response.put("index",todo.getIdx()); - response.put("message", "todo추가완료"); - return ResponseEntity.status(HttpStatus.OK).body(response); - }catch (IllegalArgumentException ex){ - Map response = new HashMap<>(); - response.put("status:", HttpStatus.INTERNAL_SERVER_ERROR.value()); - response.put("success",false); - response.put("message","서버내부오류"); - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); - } + Map response = new HashMap<>(); + response.put("status:", HttpStatus.OK.value()); + response.put("success", true); + response.put("index", todo.getIdx()); + response.put("message", "todo추가완료"); + return ResponseEntity.status(HttpStatus.OK).body(response); } +// }catch (IllegalArgumentException ex){ +// Map response = new HashMap<>(); +// response.put("status:", HttpStatus.INTERNAL_SERVER_ERROR.value()); +// response.put("success",false); +// response.put("message","서버내부오류"); +// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); +// } +// } //todo개수만큼 프론트에서 호출해줘야함 // @@ -188,8 +191,6 @@ public ResponseEntity> findStRoomTodoByRoomId(@PathVariable } } - - @GetMapping("/member/room/{roomId}") public ResponseEntity getMemberRoomInfo(@PathVariable Long roomId) throws Exception { // 현재 로그인한 사용자의 정보 가져오기 @@ -199,6 +200,8 @@ public ResponseEntity getMemberRoomInfo(@PathVar return new ResponseEntity<>(todo, HttpStatus.OK); } + + @GetMapping("/todoRank/{roomId}") public ResponseEntity> getMemberTodoRank(@PathVariable Long roomId) throws Exception { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); @@ -212,6 +215,20 @@ public ResponseEntity> getMemberTodoRank(@PathVariable Long } + @GetMapping("/get-todo/{roomId}/{date}") + public ResponseEntity> getTodoByDateAndMemberIdAndRoomId + (@PathVariable Long roomId, @PathVariable @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date) throws Exception { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + String currentEmail = authentication.getName(); + User user = userService.getUserByEmail(currentEmail); + Long memberId = user.getId(); + + List todoList = toDoService.getTodoByDateAndMemberIdAndRoomId(date, memberId, roomId); + Map response = new HashMap<>(); + response.put("todoList", todoList); + + return ResponseEntity.ok(response); + } +} -} \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomEntity.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomEntity.java index f7bfa02..2642be5 100644 --- a/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomEntity.java +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomEntity.java @@ -51,9 +51,7 @@ public class StRoomEntity extends BaseTimeEntity { @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) private List studyDayEntities = new ArrayList<>(); - - @JsonManagedReference - @OneToMany(mappedBy = "stRoom") + @OneToMany private List members = new ArrayList<>(); @ManyToOne diff --git a/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomTodoFindProjection.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomTodoFindProjection.java new file mode 100644 index 0000000..2675163 --- /dev/null +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomTodoFindProjection.java @@ -0,0 +1,13 @@ +package mos.mosback.stRoom.domain.stRoom; + +import java.time.LocalDate; + +public interface StRoomTodoFindProjection { + Long getRoomId(); + Long getMemberId(); + LocalDate getDate(); + String getTodoContent(); + + Long getIdx(); + TodoStatus getStatus(); +} diff --git a/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomTodoInfoProjection.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomTodoInfoProjection.java new file mode 100644 index 0000000..b26c830 --- /dev/null +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomTodoInfoProjection.java @@ -0,0 +1,7 @@ +package mos.mosback.stRoom.domain.stRoom; + +public interface StRoomTodoInfoProjection { + + int getCompletedCount(); + int getTotalCount(); +} diff --git a/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberEntity.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberEntity.java index 0a77022..3f5722b 100644 --- a/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberEntity.java +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberEntity.java @@ -17,7 +17,6 @@ public class StudyMemberEntity implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "memberID") private Long memberId; @ManyToOne diff --git a/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberTodoEntity.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberTodoEntity.java index 129dd5a..f38ebdb 100644 --- a/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberTodoEntity.java +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/StudyMemberTodoEntity.java @@ -6,6 +6,7 @@ import javax.persistence.*; import java.io.Serializable; +import java.time.LocalDate; @Getter // 롬복 어노테이션 @Setter @@ -20,7 +21,7 @@ public class StudyMemberTodoEntity implements Serializable { @Column(name = "memberID") private Long memberId; - @Column(name = "todoContent") + @Column(name = "todo_content") private String todoContent; @ManyToOne @@ -31,6 +32,8 @@ public class StudyMemberTodoEntity implements Serializable { @Enumerated(EnumType.STRING) private TodoStatus status; + private LocalDate date; + public void update(String todoContent, TodoStatus status) { this.todoContent = todoContent; diff --git a/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java index cf3273e..c6c113b 100644 --- a/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/Home_RoomResponseDto.java @@ -2,13 +2,14 @@ import lombok.Getter; import lombok.Setter; import mos.mosback.stRoom.domain.stRoom.StRoomEntity; +import mos.mosback.stRoom.service.ToDoService; import java.time.LocalDate; +import java.util.List; @Setter @Getter public class Home_RoomResponseDto { - private String title; private String category; // 스터디 카테고리 private int memberNum; //현재 멤버수 @@ -17,7 +18,6 @@ public class Home_RoomResponseDto { private int online; //온라인 private LocalDate startDate; //스터디 시작날짜 private LocalDate endDate; - //+ 유저프로필사진 public Home_RoomResponseDto(StRoomEntity entity) { diff --git a/src/main/java/mos/mosback/stRoom/dto/MemberTodoResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/MemberTodoResponseDto.java new file mode 100644 index 0000000..00e5e45 --- /dev/null +++ b/src/main/java/mos/mosback/stRoom/dto/MemberTodoResponseDto.java @@ -0,0 +1,13 @@ +package mos.mosback.stRoom.dto; +import lombok.Getter; +import lombok.Setter; +import mos.mosback.stRoom.domain.stRoom.TodoStatus; + +@Getter +@Setter +public class MemberTodoResponseDto { + private String todoContent; + private Long idx; + private TodoStatus status; + +} diff --git a/src/main/java/mos/mosback/stRoom/dto/StudyMemberRoomInfoResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StudyMemberRoomInfoResponseDto.java index fa530ca..6b1eec1 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StudyMemberRoomInfoResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StudyMemberRoomInfoResponseDto.java @@ -8,7 +8,9 @@ @Getter @NoArgsConstructor public class StudyMemberRoomInfoResponseDto { + private String category; private double studyRoomTodoAverage; // 평균값 private List todoList; // 사용자 투두정보 private List roomDayList; + } \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/dto/StudyMemberToDoRequestDto.java b/src/main/java/mos/mosback/stRoom/dto/StudyMemberToDoRequestDto.java index afa67bc..a0290d7 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StudyMemberToDoRequestDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StudyMemberToDoRequestDto.java @@ -5,6 +5,8 @@ import lombok.Setter; import mos.mosback.stRoom.domain.stRoom.TodoStatus; +import java.time.LocalDate; + @Setter @Getter @@ -15,5 +17,6 @@ public class StudyMemberToDoRequestDto { private Long roomId; private Long todoId; private String currentEmail; + private LocalDate date; } \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/dto/StudyRoomDayDto.java b/src/main/java/mos/mosback/stRoom/dto/StudyRoomDayDto.java index 5880a01..7d6d92e 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StudyRoomDayDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StudyRoomDayDto.java @@ -1,12 +1,14 @@ package mos.mosback.stRoom.dto; - import lombok.Data; +import java.time.LocalDate; import java.util.Date; +; @Data public class StudyRoomDayDto { - private Date date; // 날짜 Date 객체 + private int year; + private int month; private String dayOfWeek; // "월" ~ "일" 값 private int dayVal; // 날짜 값 } diff --git a/src/main/java/mos/mosback/stRoom/dto/stRoomToDoRequestDto.java b/src/main/java/mos/mosback/stRoom/dto/stRoomToDoRequestDto.java index 4d4a6c4..68e92ce 100644 --- a/src/main/java/mos/mosback/stRoom/dto/stRoomToDoRequestDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/stRoomToDoRequestDto.java @@ -4,6 +4,8 @@ import lombok.Setter; import mos.mosback.stRoom.domain.stRoom.TodoStatus; +import java.time.LocalDate; + @Setter @Getter @@ -13,4 +15,5 @@ public class stRoomToDoRequestDto { private String todoContent; private TodoStatus status; private Long roomId; + } \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/repository/MemberTodoRepository.java b/src/main/java/mos/mosback/stRoom/repository/MemberTodoRepository.java index 6178761..e2035b3 100644 --- a/src/main/java/mos/mosback/stRoom/repository/MemberTodoRepository.java +++ b/src/main/java/mos/mosback/stRoom/repository/MemberTodoRepository.java @@ -1,11 +1,14 @@ package mos.mosback.stRoom.repository; import mos.mosback.stRoom.domain.stRoom.MemberTodoRankProjection; +import mos.mosback.stRoom.domain.stRoom.StRoomTodoFindProjection; +import mos.mosback.stRoom.domain.stRoom.StRoomTodoInfoProjection; import mos.mosback.stRoom.domain.stRoom.StudyMemberTodoEntity; import mos.mosback.stRoom.dto.StudyRoomTodoInfoDto; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import java.time.LocalDate; import java.util.List; import java.util.Optional; @@ -19,7 +22,7 @@ public interface MemberTodoRepository extends JpaRepository getStudyRoomTodoAverage(@Param("roomId") Long roomId); @Query(value = "SELECT MEMBERID AS memberId, ROUND((SUM(CASE WHEN STATUS = 'Completed' THEN 1.0 ELSE 0.0 END) / COUNT(*)) * 100) AS progress " + "FROM STUDY_MEMBER_TODO_ENTITY " + @@ -28,8 +31,15 @@ public interface MemberTodoRepository extends JpaRepository getRankByStRoom(@Param("roomId") Long roomId); + @Query(value = "SELECT IDX, STATUS, TODO_CONTENT AS todoContent FROM STUDY_MEMBER_TODO_ENTITY " + + "WHERE DATE = :date " + + "AND MEMBERID = :memberId " + + "AND ROOM_ID = :roomId", + nativeQuery = true) + List findTodoByDateAndMemberIdAndRoomId( + @Param("date") LocalDate date, + @Param("memberId") Long memberId, + @Param("roomId") Long roomId); - - Optional findByMemberIdAndTodoContent(Long id, String todoContent); } diff --git a/src/main/java/mos/mosback/stRoom/repository/ToDoRepository.java b/src/main/java/mos/mosback/stRoom/repository/ToDoRepository.java index 83e1ecf..0b47ab8 100644 --- a/src/main/java/mos/mosback/stRoom/repository/ToDoRepository.java +++ b/src/main/java/mos/mosback/stRoom/repository/ToDoRepository.java @@ -1,10 +1,12 @@ package mos.mosback.stRoom.repository; +import mos.mosback.stRoom.domain.stRoom.StudyMemberTodoEntity; import mos.mosback.stRoom.domain.stRoom.ToDoEntity; import mos.mosback.stRoom.dto.StRoomToDoResponseDto; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import java.time.LocalDate; import java.util.List; public interface ToDoRepository extends JpaRepository { @@ -13,4 +15,6 @@ public interface ToDoRepository extends JpaRepository { @Query("SELECT NEW mos.mosback.stRoom.dto.StRoomToDoResponseDto(t) FROM ToDoEntity t WHERE t.stRoom.roomId= :roomId ORDER BY t.todoId") List findByStRoomId(@Param("roomId") Long roomId); + + } diff --git a/src/main/java/mos/mosback/stRoom/service/StRoomService.java b/src/main/java/mos/mosback/stRoom/service/StRoomService.java index eabe178..474eb99 100644 --- a/src/main/java/mos/mosback/stRoom/service/StRoomService.java +++ b/src/main/java/mos/mosback/stRoom/service/StRoomService.java @@ -84,6 +84,7 @@ public void update(Long roomId, StRoomUpdateRequestDto requestDto) { @Transactional(readOnly = true) public StRoomResponseDto findById(Long roomId) { try { + StRoomEntity stRoomEntity = stRoomRepository.findById(roomId) .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id=" + roomId)); @@ -102,6 +103,8 @@ public StRoomDetailResponseDto findByRoomId(Long roomId) { return new StRoomDetailResponseDto(stRoomEntity); } public List findAllRoomsDesc() { + + return stRoomRepository.findAllDesc(); } diff --git a/src/main/java/mos/mosback/stRoom/service/ToDoService.java b/src/main/java/mos/mosback/stRoom/service/ToDoService.java index 98ae9be..fe36da9 100644 --- a/src/main/java/mos/mosback/stRoom/service/ToDoService.java +++ b/src/main/java/mos/mosback/stRoom/service/ToDoService.java @@ -11,12 +11,16 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; + @RequiredArgsConstructor @Service public class ToDoService { @@ -26,7 +30,7 @@ public class ToDoService { private final MemberTodoRepository studyMemberToDoRepository; private final UserService userService; private final StRoomService stRoomService; - private final UserRepository userRepository; + @Transactional @@ -94,13 +98,14 @@ public StudyMemberTodoEntity addMemberTodo(StudyMemberToDoRequestDto requestDto) toDoEntity.setStatus(TodoStatus.Waiting); toDoEntity.setStRoom(stRoomEntity); toDoEntity.setTodoContent(requestDto.getTodoContent()); - + toDoEntity.setDate(requestDto.getDate()); return studyMemberToDoRepository.save(toDoEntity); } public StudyMemberRoomInfoResponseDto getMemberRoomInfo(Long roomId, String currentEmail) throws Exception { StudyMemberRoomInfoResponseDto result = new StudyMemberRoomInfoResponseDto(); - StRoomEntity stRoomEntity = stRoomRepository.findById(roomId) + + StRoomEntity stRoom = stRoomRepository.findById(roomId) .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 없습니다. id =" + roomId)); User user = userService.getUserByEmail(currentEmail); @@ -110,28 +115,34 @@ public StudyMemberRoomInfoResponseDto getMemberRoomInfo(Long roomId, String curr for (StudyMemberTodoEntity item : todoEntityList) { todoList.add(new StRoomMemberToDoResponseDto(item)); } - // 스터디 룸에 대한 현재 투두평균값 - - StudyRoomTodoInfoDto studyRoomTodoAverage = null; + List studyRoomTodoAverage = null; double average = 0; try { - studyRoomTodoAverage = studyMemberToDoRepository.getStudyRoomTodoAverage(roomId); + studyRoomTodoAverage = studyMemberToDoRepository.getStudyRoomTodoAverage(roomId); // studyRoomTodoAverage를 초기화 } catch (Exception e) { e.printStackTrace(); } - if (studyRoomTodoAverage != null) { + if (studyRoomTodoAverage != null && !studyRoomTodoAverage.isEmpty()) { + StRoomTodoInfoProjection projection = studyRoomTodoAverage.get(0); // DB에 데이터가 존재할 때에만 해당 로직 수행 - average = (studyRoomTodoAverage.getTotalCount() - studyRoomTodoAverage.getCompletedCount() - / (double) studyRoomTodoAverage.getTotalCount()) * 100; + int totalCount = projection.getTotalCount(); + int completedCount = projection.getCompletedCount(); + if (totalCount > 0) { + average = ((double) completedCount / totalCount) * 100; + } } List roomDayList = new ArrayList<>(); - Date now; + + Date now = new Date(); Calendar cal1 = Calendar.getInstance(); + cal1.setTime(now); + LocalDate date = LocalDate.now(); for (int i=0; i<7; i++) { StudyRoomDayDto dayDto = new StudyRoomDayDto(); - now = new Date(cal1.getTimeInMillis()); - dayDto.setDate(now); // 날짜 객체 셋팅 + + dayDto.setYear(date.getYear()); // 날짜 객체 셋팅 + dayDto.setMonth(date.getMonthValue()); dayDto.setDayVal(cal1.get(Calendar.DATE)); // 날짜 셋팅 dayDto.setDayOfWeek(getDayOfKoreanWeek(cal1.get(Calendar.DAY_OF_WEEK))); // "월"~"일" 셋팅 roomDayList.add(dayDto); @@ -139,30 +150,31 @@ public StudyMemberRoomInfoResponseDto getMemberRoomInfo(Long roomId, String curr cal1.add(Calendar.DATE, 1); // 일 계산 하루씩 추가 } + result.setCategory(stRoom.getCategory()); result.setTodoList(todoList); result.setStudyRoomTodoAverage(average); // 평균값 result.setRoomDayList(roomDayList); - return result; } - private String getDayOfKoreanWeek(int i) { - if (i == 1) { - return "월"; - } else if (i == 2) { - return "화"; - } else if (i == 3) { - return "수"; - } else if (i == 4) { - return "목"; - } else if (i == 5) { - return "금"; - } else if (i == 6) { - return "토"; - } else if (i == 7) { - return "일"; - } else { - return ""; + public String getDayOfKoreanWeek(int dayOfWeek) { + switch (dayOfWeek) { + case Calendar.SUNDAY: + return "일"; + case Calendar.MONDAY: + return "월"; + case Calendar.TUESDAY: + return "화"; + case Calendar.WEDNESDAY: + return "수"; + case Calendar.THURSDAY: + return "목"; + case Calendar.FRIDAY: + return "금"; + case Calendar.SATURDAY: + return "토"; + default: + return ""; } } @@ -188,23 +200,52 @@ public MemberTodoProgressResponseDto getProgressInfo(Long roomId, String current User user = userService.getUserByEmail(currentEmail); todoProgress.setUserNick(user.getNickname()); - StudyRoomTodoInfoDto studyRoomTodoAverage = null; + List studyRoomTodoAverage = null; + double average = 0; try { studyRoomTodoAverage = studyMemberToDoRepository.getStudyRoomTodoAverage(roomId); } catch (Exception e) { e.printStackTrace(); } - - if (studyRoomTodoAverage != null) { + if (studyRoomTodoAverage != null && !studyRoomTodoAverage.isEmpty()) { + StRoomTodoInfoProjection projection = studyRoomTodoAverage.get(0); // DB에 데이터가 존재할 때에만 해당 로직 수행 - double totalCount = studyRoomTodoAverage.getTotalCount(); - double completedCount = studyRoomTodoAverage.getCompletedCount(); - double average = (totalCount - completedCount) / totalCount * 100; - todoProgress.setAvg(average); - } else { - todoProgress.setAvg(0.0); + int totalCount = projection.getTotalCount(); + int completedCount = projection.getCompletedCount(); + if (totalCount > 0) { + average = ((double) completedCount / totalCount) * 100; + } } + todoProgress.setAvg(average); return todoProgress; } + + public List getTodoByDateAndMemberIdAndRoomId(LocalDate date, Long memberId, Long roomId){ + List dto = new ArrayList<>(); + List projection = studyMemberToDoRepository.findTodoByDateAndMemberIdAndRoomId(date, memberId, roomId); + + //projection null check + if(projection == null || projection.isEmpty()) + { + System.out.println("**********"); + } + // run 하고 api 도 plea + for (StRoomTodoFindProjection projections : projection) { + MemberTodoResponseDto responseDto = new MemberTodoResponseDto(); + responseDto.setStatus(projections.getStatus()); + responseDto.setTodoContent(projections.getTodoContent()); + responseDto.setIdx(projections.getIdx()); + + //projection select result check + System.out.println("=========[TO DO LIST"+responseDto.getIdx()+"]==========="); + System.out.println(responseDto.getStatus()); + System.out.println(responseDto.getTodoContent()); + + dto.add(responseDto); + } + + return dto; + } + } From 17e390fa496c47c76a5e10ca4f753901f0f1a975 Mon Sep 17 00:00:00 2001 From: leejjeonghui Date: Thu, 9 Nov 2023 01:27:15 +0900 Subject: [PATCH 57/60] =?UTF-8?q?=EA=B5=AC=ED=98=84=EB=81=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../stRoom/controller/TodoController.java | 31 +++---------------- .../stRoom/StRoomTodoFindProjection.java | 1 - .../dto/StudyMemberRoomInfoResponseDto.java | 4 +-- .../mosback/stRoom/service/ToDoService.java | 12 +++---- 4 files changed, 11 insertions(+), 37 deletions(-) diff --git a/src/main/java/mos/mosback/stRoom/controller/TodoController.java b/src/main/java/mos/mosback/stRoom/controller/TodoController.java index 6a715cd..3b85b26 100644 --- a/src/main/java/mos/mosback/stRoom/controller/TodoController.java +++ b/src/main/java/mos/mosback/stRoom/controller/TodoController.java @@ -1,25 +1,16 @@ package mos.mosback.stRoom.controller; import lombok.RequiredArgsConstructor; -import mos.mosback.login.domain.user.User; -import mos.mosback.login.domain.user.dto.NicknameDto; -import mos.mosback.login.domain.user.service.UserService; -import mos.mosback.stRoom.domain.stRoom.MemberStatus; import mos.mosback.stRoom.domain.stRoom.StudyMemberTodoEntity; import mos.mosback.stRoom.domain.stRoom.ToDoEntity; import mos.mosback.stRoom.dto.*; import mos.mosback.stRoom.service.ToDoService; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; -import org.springframework.web.client.HttpClientErrorException; - -import javax.persistence.EntityNotFoundException; import java.time.LocalDate; -import java.time.format.DateTimeFormatter; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -30,7 +21,6 @@ public class TodoController { private final ToDoService toDoService; - private final UserService userService; @PostMapping("todo/add/{roomId}") public ResponseEntity> addTodo(@RequestBody stRoomToDoRequestDto requestDto, @PathVariable Long roomId) { @@ -53,7 +43,7 @@ public ResponseEntity> addTodo(@RequestBody stRoomToDoReques } @PostMapping("/member/todo/add") public ResponseEntity> addMemberTodo(@RequestBody StudyMemberToDoRequestDto requestDto) throws Exception { -// try { // 현재 로그인한 사용자의 정보 가져오기 + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String currentEmail = authentication.getName(); // 현재 사용자의 이메일 requestDto.setCurrentEmail(currentEmail); @@ -65,16 +55,6 @@ public ResponseEntity> addMemberTodo(@RequestBody StudyMembe response.put("message", "todo추가완료"); return ResponseEntity.status(HttpStatus.OK).body(response); } -// }catch (IllegalArgumentException ex){ -// Map response = new HashMap<>(); -// response.put("status:", HttpStatus.INTERNAL_SERVER_ERROR.value()); -// response.put("success",false); -// response.put("message","서버내부오류"); -// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); -// } -// } - //todo개수만큼 프론트에서 호출해줘야함 -// @PutMapping("todo/{todoId}") @@ -215,15 +195,12 @@ public ResponseEntity> getMemberTodoRank(@PathVariable Long } - @GetMapping("/get-todo/{roomId}/{date}") + @GetMapping("/myTodo/{roomId}/{date}") public ResponseEntity> getTodoByDateAndMemberIdAndRoomId (@PathVariable Long roomId, @PathVariable @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date) throws Exception { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - String currentEmail = authentication.getName(); - User user = userService.getUserByEmail(currentEmail); - Long memberId = user.getId(); - - List todoList = toDoService.getTodoByDateAndMemberIdAndRoomId(date, memberId, roomId); + String email = authentication.getName(); // 현재 사용자의 이메일 + List todoList = toDoService.getTodoByDateAndMemberIdAndRoomId(date, roomId,email); Map response = new HashMap<>(); response.put("todoList", todoList); diff --git a/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomTodoFindProjection.java b/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomTodoFindProjection.java index 2675163..4996004 100644 --- a/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomTodoFindProjection.java +++ b/src/main/java/mos/mosback/stRoom/domain/stRoom/StRoomTodoFindProjection.java @@ -4,7 +4,6 @@ public interface StRoomTodoFindProjection { Long getRoomId(); - Long getMemberId(); LocalDate getDate(); String getTodoContent(); diff --git a/src/main/java/mos/mosback/stRoom/dto/StudyMemberRoomInfoResponseDto.java b/src/main/java/mos/mosback/stRoom/dto/StudyMemberRoomInfoResponseDto.java index 6b1eec1..015cbf3 100644 --- a/src/main/java/mos/mosback/stRoom/dto/StudyMemberRoomInfoResponseDto.java +++ b/src/main/java/mos/mosback/stRoom/dto/StudyMemberRoomInfoResponseDto.java @@ -9,8 +9,8 @@ @NoArgsConstructor public class StudyMemberRoomInfoResponseDto { private String category; - private double studyRoomTodoAverage; // 평균값 - private List todoList; // 사용자 투두정보 + private double avg; // 평균값 +/* private List todoList; // 사용자 투두정보*/ private List roomDayList; } \ No newline at end of file diff --git a/src/main/java/mos/mosback/stRoom/service/ToDoService.java b/src/main/java/mos/mosback/stRoom/service/ToDoService.java index fe36da9..282218a 100644 --- a/src/main/java/mos/mosback/stRoom/service/ToDoService.java +++ b/src/main/java/mos/mosback/stRoom/service/ToDoService.java @@ -13,7 +13,6 @@ import java.time.LocalDate; import java.time.ZoneId; -import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; @@ -151,8 +150,8 @@ public StudyMemberRoomInfoResponseDto getMemberRoomInfo(Long roomId, String curr } result.setCategory(stRoom.getCategory()); - result.setTodoList(todoList); - result.setStudyRoomTodoAverage(average); // 평균값 + /* result.setTodoList(todoList);*/ + result.setAvg(average); // 평균값 result.setRoomDayList(roomDayList); return result; } @@ -221,16 +220,15 @@ public MemberTodoProgressResponseDto getProgressInfo(Long roomId, String current return todoProgress; } - public List getTodoByDateAndMemberIdAndRoomId(LocalDate date, Long memberId, Long roomId){ + public List getTodoByDateAndMemberIdAndRoomId(LocalDate date, Long roomId,String email) throws Exception{ List dto = new ArrayList<>(); - List projection = studyMemberToDoRepository.findTodoByDateAndMemberIdAndRoomId(date, memberId, roomId); - + User user= userService.getUserByEmail(email); + List projection = studyMemberToDoRepository.findTodoByDateAndMemberIdAndRoomId(date,user.getId(),roomId); //projection null check if(projection == null || projection.isEmpty()) { System.out.println("**********"); } - // run 하고 api 도 plea for (StRoomTodoFindProjection projections : projection) { MemberTodoResponseDto responseDto = new MemberTodoResponseDto(); responseDto.setStatus(projections.getStatus()); From 5c6807ddfc99cd42b1b054bfa537706d8fad2b3f Mon Sep 17 00:00:00 2001 From: leejjeonghui <109637866+leejjeonghui@users.noreply.github.com> Date: Thu, 9 Nov 2023 01:38:15 +0900 Subject: [PATCH 58/60] Update application-local.yml --- src/main/resources/application-local.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index d1ebf60..2ff7d6a 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -87,7 +87,7 @@ spring: debug: true jwt: - secretKey: 'dfadfekndchnsdifqld125654x8sdfnjldsncuelsdfs45x321df' + secretKey: 'dfadfekndchnsdi access: expiration: 360000000 # 1??(60?) (1000L(ms -> s) * 60L(s -> m) * 60L(m -> h)) From e37a463edf1206227a2efa597d21246ae1299220 Mon Sep 17 00:00:00 2001 From: leejjeonghui <109637866+leejjeonghui@users.noreply.github.com> Date: Thu, 9 Nov 2023 01:38:35 +0900 Subject: [PATCH 59/60] Update application-local.yml --- src/main/resources/application-local.yml | 123 ----------------------- 1 file changed, 123 deletions(-) diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index 2ff7d6a..8b13789 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -1,124 +1 @@ -spring: - profiles: - active: local ---- -spring: - config: - activate: - on-profile: "local" - security: - oauth2: - client: - registration: - google: - client-id: 729954756779-2usa0d48vh0048r4vmmljtlrlstvcjdh.apps.googleusercontent.com - client-secret: GOCSPX- - scope: profile, email - - - naver: - client-id: jg5_V_oaR2k60xfasDRa - client-secret: - redirect-uri: http://localhost:8080/login/oauth2/code/naver - authorization-grant-type: authorization_code - scope: name, email, profile_image - client-name: Naver - - - kakao: - client-id: bbe971abb2538851ddabe4ef20d76744 - client-secret: - redirect-uri: http://localhost:8080/login/oauth2/code/kakao - client-authentication-method: POST - authorization-grant-type: authorization_code - scope: profile_nickname, profile_image - client-name: Kakao - - - provider: - naver: - authorization_uri: https://nid.naver.com/oauth2.0/authorize - token_uri: https://nid.naver.com/oauth2.0/token - user-info-uri: https://openapi.naver.com/v1/nid/me - user_name_attribute: response - - kakao: - authorization-uri: https://kauth.kakao.com/oauth/authorize - token-uri: https://kauth.kakao.com/oauth/token - user-info-uri: https://kapi.kakao.com/v2/user/me - user-name-attribute: id - - h2: - console: - enabled: true - path: /h2-console - settings: - web-allow-others: true - - datasource: - driver-class-name: org.h2.Driver - url: jdbc:h2:mem:testdb - username: sa - password: - - main: - allow-circular-references: true - - jpa: - show-sql: true - database-platform: org.hibernate.dialect.H2Dialect - properties: - hibernate: - format_sql: true - show_sql: true - ddl-auto: create - - mail: - host: smtp.naver.com - port: 465 - username: dmsthf1225@naver.com - password: dkffkqb77!! - properties: - mail: - smtp: - auth: true - starttls: - enable: true - debug: true - -jwt: - secretKey: 'dfadfekndchnsdi - - access: - expiration: 360000000 # 1??(60?) (1000L(ms -> s) * 60L(s -> m) * 60L(m -> h)) - header: Authorization - - refresh: - expiration: 1209600000 # (1000L(ms -> s) * 60L(s -> m) * 60L(m -> h) * 24L(h -> ??) * 14(2?)) - header: Authorization-refresh - -logging: - level: - root: DEBUG - -cloud: - aws: - credentials: - accessKey: - secretKey: - region: - static: ap-northeast-2 - stack: - auto: false - autoconfigure: - exclude: - - org.springframework.cloud.aws.autoconfigure.context.ContextInstanceDataAutoConfiguration - - org.springframework.cloud.aws.autoconfigure.context.ContextRegionProviderAutoConfiguration - - org.springframework.cloud.aws.autoconfigure.context.ContextStackAutoConfiguration - - org.springframework.cloud.aws.autoconfigure.context.ContextCredentialsAutoConfiguration - -application: - bucket: - name: mos-s3-bucket - From 74941c3718b0d16baf294dc07365f2f6d028cb58 Mon Sep 17 00:00:00 2001 From: leejjeonghui <109637866+leejjeonghui@users.noreply.github.com> Date: Thu, 9 Nov 2023 01:39:17 +0900 Subject: [PATCH 60/60] Update application.yml --- src/main/resources/application.yml | 82 ------------------------------ 1 file changed, 82 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index bfb36e4..8b13789 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,83 +1 @@ -spring: - profiles: - active: local ---- -spring: - config: - activate: - on-profile: "local" - - h2: - console: - enabled: true - path: /h2-console - settings: - web-allow-others: true - - datasource: - driver-class-name: org.h2.Driver - url: jdbc:h2:mem:testdb - username: sa - password: - - main: - allow-circular-references: true - - jpa: - show-sql: true - database-platform: org.hibernate.dialect.H2Dialect - properties: - hibernate: - format_sql: true - show_sql: true - ddl-auto: create - - mail: - host: smtp.naver.com - port: 465 - username: - password: - properties: - mail: - smtp: - auth: true - starttls: - enable: true - debug: true - -jwt: - secretKey: 'dfadfekndchnsdifqld125654x8sdfnjldsncuelsdfs45x321df' - - access: - expiration: 360000000 # 1??(60?) (1000L(ms -> s) * 60L(s -> m) * 60L(m -> h)) - header: Authorization - - refresh: - expiration: 1209600000 # (1000L(ms -> s) * 60L(s -> m) * 60L(m -> h) * 24L(h -> ??) * 14(2?)) - header: Authorization-refresh - -logging: - level: - root: DEBUG - -cloud: - aws: - credentials: - accessKey: - secretKey: - region: - static: ap-northeast-2 - stack: - auto: false - autoconfigure: - exclude: - - org.springframework.cloud.aws.autoconfigure.context.ContextInstanceDataAutoConfiguration - - org.springframework.cloud.aws.autoconfigure.context.ContextRegionProviderAutoConfiguration - - org.springframework.cloud.aws.autoconfigure.context.ContextStackAutoConfiguration - - org.springframework.cloud.aws.autoconfigure.context.ContextCredentialsAutoConfiguration - -application: - bucket: - name: mos-s3-bucket -