From 7b999f83d195cbfd77a84a6db7c33984edb836a7 Mon Sep 17 00:00:00 2001 From: Jeyong Date: Sun, 13 Apr 2025 18:37:54 +0900 Subject: [PATCH 1/4] =?UTF-8?q?[feat]=20LLM=EC=9A=A9=20DB=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B0=8F=20=ED=95=B4=EB=8B=B9=20DB=EC=97=90=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=A0=20=EB=8F=84=EB=A9=94=EC=9D=B8=20?= =?UTF-8?q?=EC=97=B0=EA=B2=B0=20/=20WebSocket=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MathCaptain/weakness/build.gradle | 12 ++- .../java/MathCaptain/weakness/TestInit.java | 8 +- .../weakness/WeaknessApplication.java | 2 + .../global/config/PrimaryDBConfig.java | 85 +++++++++++++++++++ .../global/config/SecondDBConfig.java | 65 ++++++++++++++ .../global/config/WebSocketConfig.java | 26 ++++++ 6 files changed, 186 insertions(+), 12 deletions(-) create mode 100644 MathCaptain/weakness/src/main/java/MathCaptain/weakness/global/config/PrimaryDBConfig.java create mode 100644 MathCaptain/weakness/src/main/java/MathCaptain/weakness/global/config/SecondDBConfig.java create mode 100644 MathCaptain/weakness/src/main/java/MathCaptain/weakness/global/config/WebSocketConfig.java diff --git a/MathCaptain/weakness/build.gradle b/MathCaptain/weakness/build.gradle index fc69137..49ca9f5 100644 --- a/MathCaptain/weakness/build.gradle +++ b/MathCaptain/weakness/build.gradle @@ -38,10 +38,13 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-websocket' implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect' implementation 'io.jsonwebtoken:jjwt-api:0.12.3' - implementation 'commons-codec:commons-codec:1.5' - implementation 'org.springframework.ai:spring-ai-openai-spring-boot-starter' + implementation 'commons-codec:commons-codec:1.13' + implementation 'org.webjars:webjars-locator-core' + implementation 'org.webjars:sockjs-client:1.5.1' + implementation 'org.webjars:stomp-websocket:2.3.4' implementation 'com.h2database:h2' runtimeOnly 'mysql:mysql-connector-java:8.0.33' + implementation 'org.postgresql:postgresql:42.7.1' implementation 'com.auth0:java-jwt:3.13.0' runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.3' runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.3' @@ -57,11 +60,6 @@ dependencies { testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.10.0' } -dependencyManagement { - imports { - mavenBom "org.springframework.ai:spring-ai-bom:$springAiVersion" - } -} tasks.named('test') { useJUnitPlatform() diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/TestInit.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/TestInit.java index e8195b6..58a8f1c 100644 --- a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/TestInit.java +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/TestInit.java @@ -4,15 +4,13 @@ import MathCaptain.weakness.domain.Group.entity.Group; import MathCaptain.weakness.domain.Group.entity.RelationBetweenUserAndGroup; import MathCaptain.weakness.domain.Group.enums.CategoryStatus; -import MathCaptain.weakness.domain.Group.enums.GroupRole; import MathCaptain.weakness.domain.Group.repository.GroupRepository; import MathCaptain.weakness.domain.Group.repository.RelationRepository; import MathCaptain.weakness.domain.Record.entity.ActivityRecord; -import MathCaptain.weakness.domain.Record.repository.RecordRepository; +import MathCaptain.weakness.domain.Record.repository.record.RecordRepository; import MathCaptain.weakness.domain.Recruitment.dto.request.CreateRecruitmentRequest; import MathCaptain.weakness.domain.Recruitment.entity.Comment; import MathCaptain.weakness.domain.Recruitment.entity.Recruitment; -import MathCaptain.weakness.domain.Recruitment.enums.RecruitmentStatus; import MathCaptain.weakness.domain.Recruitment.repository.CommentRepository; import MathCaptain.weakness.domain.Recruitment.repository.RecruitmentRepository; import MathCaptain.weakness.domain.User.dto.request.SaveUserRequest; @@ -33,7 +31,7 @@ @Component @RequiredArgsConstructor @Transactional -@DependsOn("entityManagerFactory") +@DependsOn("primaryEntityManagerFactory") public class TestInit { private final UserRepository userRepository; @@ -104,7 +102,7 @@ public void init() { CategoryStatus.FITNESS, 2, 3, 0L, null, "test2", 3, 4); GroupCreateRequest groupCreateRequest3 = GroupCreateRequest.of(users1.getUserId(), "testGroup3", - CategoryStatus.READING, 2, 3, 0L, null, "test3", 3, 4); + CategoryStatus.RUNNING, 2, 3, 0L, null, "test3", 3, 4); Group group1 = Group.of(groupCreateRequest1); Group group2 = Group.of(groupCreateRequest2); diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/WeaknessApplication.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/WeaknessApplication.java index fcd8c8a..7093ed3 100644 --- a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/WeaknessApplication.java +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/WeaknessApplication.java @@ -3,10 +3,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; @EnableJpaAuditing @SpringBootApplication(exclude = SecurityAutoConfiguration.class) +@ComponentScan(basePackages = "MathCaptain") public class WeaknessApplication { public static void main(String[] args) { diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/global/config/PrimaryDBConfig.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/global/config/PrimaryDBConfig.java new file mode 100644 index 0000000..37cab1f --- /dev/null +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/global/config/PrimaryDBConfig.java @@ -0,0 +1,85 @@ +package MathCaptain.weakness.global.config; + +import com.zaxxer.hikari.HikariDataSource; +import jakarta.persistence.EntityManagerFactory; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; +import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import javax.sql.DataSource; +import java.util.HashMap; +import java.util.Map; + +@Configuration +@EnableTransactionManagement +@EnableJpaRepositories( + basePackages = { + "MathCaptain.weakness.domain.User.repository", + "MathCaptain.weakness.domain.Record.repository.record", + "MathCaptain.weakness.domain.Group.repository", + "MathCaptain.weakness.domain.Notification.repository", + "MathCaptain.weakness.domain.Recruitment.repository" + }, + entityManagerFactoryRef = "primaryEntityManagerFactory", + transactionManagerRef = "primaryTransactionManager" +) +public class PrimaryDBConfig { + + @Bean(name = "primaryDataSource") + @Primary + @ConfigurationProperties("spring.datasource.hikari") + public HikariDataSource primaryDataSource(@Qualifier("primaryDataSourceProperties") DataSourceProperties properties) { + return properties.initializeDataSourceBuilder().type(HikariDataSource.class).build(); + } + + @Bean(name = "primaryDataSourceProperties") + @Primary + @ConfigurationProperties("spring.datasource") + public DataSourceProperties primaryDataSourceProperties() { + return new DataSourceProperties(); + } + + @Bean + @Primary + @ConfigurationProperties("spring.jpa") + public JpaProperties primaryJpaProperties() { + return new JpaProperties(); + } + + @Primary + @Bean(name = "primaryEntityManagerFactory") + public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory( + EntityManagerFactoryBuilder builder, + @Qualifier("primaryDataSource") DataSource dataSource + ) { + Map jpaProperties = new HashMap<>(); + jpaProperties.put("hibernate.hbm2ddl.auto", "create"); + jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.MySQLDialect"); + jpaProperties.put("hibernate.format_sql", true); + + return builder + .dataSource(dataSource) + .packages("MathCaptain.weakness.domain") + .properties(jpaProperties) // ⬅️ 이 부분이 핵심 + .persistenceUnit("primary") + .build(); + } + + @Primary + @Bean(name = "primaryTransactionManager") + public PlatformTransactionManager primaryTransactionManager( + @Qualifier("primaryEntityManagerFactory") EntityManagerFactory entityManagerFactory) { + + return new JpaTransactionManager(entityManagerFactory); + } +} \ No newline at end of file diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/global/config/SecondDBConfig.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/global/config/SecondDBConfig.java new file mode 100644 index 0000000..3aad619 --- /dev/null +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/global/config/SecondDBConfig.java @@ -0,0 +1,65 @@ +package MathCaptain.weakness.global.config; + +import javax.sql.DataSource; +import jakarta.persistence.EntityManagerFactory; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import java.util.HashMap; +import java.util.Map; + +@Configuration +@EnableTransactionManagement +@EnableJpaRepositories( + basePackages = "MathCaptain.weakness.domain.Record.repository.userLog", // 새 DB를 쓰는 Repository 위치 + entityManagerFactoryRef = "secondEntityManagerFactory", + transactionManagerRef = "secondTransactionManager" +) +public class SecondDBConfig { + + // DataSourceProperties는 application.yml에 설정된 DB 정보를 읽어옴 + @Bean(name = "secondDataSourceProperties") + @ConfigurationProperties(prefix = "second.datasource") + public DataSourceProperties secondDataSourceProperties() { + return new DataSourceProperties(); + } + + // DataSource는 DataSourceProperties를 통해 DB에 연결하는 객체 + @Bean(name = "secondDataSource") + public DataSource secondDataSource() { + return secondDataSourceProperties().initializeDataSourceBuilder().build(); + } + + // EntityManagerFactory는 JPA에서 DB와의 연결을 관리하는 객체 + @Bean(name = "secondEntityManagerFactory") + public LocalContainerEntityManagerFactoryBean secondEntityManagerFactory( + EntityManagerFactoryBuilder builder) { + Map props = new HashMap<>(); + props.put("hibernate.hbm2ddl.auto", "update"); + props.put("hibernate.format_sql", true); + props.put("hibernate.jdbc.lob.non_contextual_creation", true); + + return builder + .dataSource(secondDataSource()) + .packages("MathCaptain.weakness.domain.Record.entity.UserLog") // entity 위치 + .properties(props) + .persistenceUnit("second") + .build(); + } + + // TransactionManager는 DB 트랜잭션을 관리하는 객체 + @Bean(name = "secondTransactionManager") + public PlatformTransactionManager secondTransactionManager( + @Qualifier("secondEntityManagerFactory") EntityManagerFactory factory) { + return new JpaTransactionManager(factory); + } +} diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/global/config/WebSocketConfig.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/global/config/WebSocketConfig.java new file mode 100644 index 0000000..2442bfe --- /dev/null +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/global/config/WebSocketConfig.java @@ -0,0 +1,26 @@ +package MathCaptain.weakness.global.config; + +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.simp.config.MessageBrokerRegistry; +import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; +import org.springframework.web.socket.config.annotation.StompEndpointRegistry; +import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; + +@Configuration +@RequiredArgsConstructor +@EnableWebSocketMessageBroker +public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { + + @Override + public void configureMessageBroker(MessageBrokerRegistry registry) { + registry.setApplicationDestinationPrefixes("/send"); //클라이언트에서 보낸 메세지를 받을 prefix + registry.enableSimpleBroker("/sub"); //해당 주소를 구독하고 있는 클라이언트들에게 메세지 전달 + } + + @Override + public void registerStompEndpoints(StompEndpointRegistry registry) { + registry.addEndpoint("/ws-stomp").setAllowedOriginPatterns("*").withSockJS(); + } + +} From 47ff79d8d2d3b2f8461508c48ac0e6f21039fb20 Mon Sep 17 00:00:00 2001 From: Jeyong Date: Sun, 13 Apr 2025 18:38:57 +0900 Subject: [PATCH 2/4] =?UTF-8?q?[refactor]=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/MathCaptain/weakness/domain/Group/entity/Group.java | 2 +- .../weakness/domain/Group/service/RelationService.java | 2 +- .../weakness/domain/User/repository/UserRepository.java | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Group/entity/Group.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Group/entity/Group.java index 496844f..9eadf67 100644 --- a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Group/entity/Group.java +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Group/entity/Group.java @@ -61,7 +61,7 @@ public class Group { @CollectionTable(name = "group_weekly_goal_achieve", joinColumns = @JoinColumn(name = "group_id")) @MapKeyColumn(name = "day_of_week") // 요일을 키로 사용 @Column(name = "goal_count") // 카운트를 값으로 사용 - private Map weeklyGoalAchieveMap = new EnumMap<>(DayOfWeek.class); + private final Map weeklyGoalAchieveMap = new EnumMap<>(DayOfWeek.class); @OneToMany(mappedBy = "recruitGroup") private List recruitments; diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Group/service/RelationService.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Group/service/RelationService.java index a2fcd85..0a66c06 100644 --- a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Group/service/RelationService.java +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Group/service/RelationService.java @@ -6,7 +6,7 @@ import MathCaptain.weakness.domain.Group.dto.response.GroupResponse; import MathCaptain.weakness.domain.Group.dto.response.RelationResponse; import MathCaptain.weakness.domain.Group.repository.GroupRepository; -import MathCaptain.weakness.domain.Record.repository.RecordRepository; +import MathCaptain.weakness.domain.Record.repository.record.RecordRepository; import MathCaptain.weakness.domain.User.dto.response.UserResponse; import MathCaptain.weakness.domain.Group.enums.GroupRole; import MathCaptain.weakness.domain.Group.repository.RelationRepository; diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/User/repository/UserRepository.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/User/repository/UserRepository.java index 3fb7043..1502006 100644 --- a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/User/repository/UserRepository.java +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/User/repository/UserRepository.java @@ -2,9 +2,11 @@ import MathCaptain.weakness.domain.User.entity.Users; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; import java.util.Optional; +@Repository public interface UserRepository extends JpaRepository { Optional findByUserId(Long userId); From 001b06886ad0762babd41970fbc7ae25f8e85422 Mon Sep 17 00:00:00 2001 From: Jeyong Date: Sun, 13 Apr 2025 18:39:20 +0900 Subject: [PATCH 3/4] =?UTF-8?q?[fix]=20=EC=B9=B4=ED=85=8C=EA=B3=A0?= =?UTF-8?q?=EB=A6=AC=20=EB=B3=80=EA=B2=BD=20READING=20->=20RUNNING?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MathCaptain/weakness/domain/Group/enums/CategoryStatus.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Group/enums/CategoryStatus.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Group/enums/CategoryStatus.java index 462c5a3..0ec8770 100644 --- a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Group/enums/CategoryStatus.java +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Group/enums/CategoryStatus.java @@ -3,5 +3,5 @@ public enum CategoryStatus { FITNESS, STUDY, - READING + RUNNING } From da15ec01e51e0d0bd8e734a545f74308ed0ad32d Mon Sep 17 00:00:00 2001 From: Jeyong Date: Sun, 13 Apr 2025 19:11:41 +0900 Subject: [PATCH 4/4] =?UTF-8?q?[feat]=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20=EB=B0=8F=20=EA=B8=B0=EC=A1=B4=20=EB=AA=A9=ED=91=9C?= =?UTF-8?q?=20=EC=88=98=ED=96=89=20=EB=A1=9C=EC=A7=81=EA=B3=BC=20=EA=B2=B0?= =?UTF-8?q?=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ActivityDetailController.java | 29 +++++ .../Record/controller/RecordController.java | 34 +++++- .../dto/request/ActivityLogEnrollRequest.java | 17 +++ .../dto/request/FitnessLogEnrollRequest.java | 21 ++++ ...dEndRequest.java => RecordEndRequest.java} | 2 +- .../dto/request/RunningLogEnrollRequest.java | 21 ++++ .../dto/request/StudyLogEnrollRequest.java | 21 ++++ .../dto/response/FitnessLogResponse.java | 38 ++++++ .../dto/response/RecordSummaryResponse.java | 51 +++++--- .../dto/response/RunningLogResponse.java | 32 +++++ .../Record/dto/response/StudyLogResponse.java | 29 +++++ .../domain/Record/entity/ActivityRecord.java | 29 +++-- .../Record/entity/UserLog/ExerciseInfo.java | 30 +++++ .../Record/entity/UserLog/FitnessDetail.java | 41 +++++++ .../Record/entity/UserLog/RunningDetail.java | 42 +++++++ .../Record/entity/UserLog/StudyDetail.java | 42 +++++++ .../{ => record}/RecordRepository.java | 2 +- .../userLog/FitnessLogRepository.java | 9 ++ .../userLog/RunningLogRepository.java | 9 ++ .../userLog/StudyLogRepository.java | 9 ++ .../Record/service/ActivityDetailService.java | 97 +++++++++++++++ .../domain/Record/service/RecordService.java | 112 ++++++++++++++++-- 22 files changed, 676 insertions(+), 41 deletions(-) create mode 100644 MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/controller/ActivityDetailController.java create mode 100644 MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/ActivityLogEnrollRequest.java create mode 100644 MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/FitnessLogEnrollRequest.java rename MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/{recordEndRequest.java => RecordEndRequest.java} (90%) create mode 100644 MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/RunningLogEnrollRequest.java create mode 100644 MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/StudyLogEnrollRequest.java create mode 100644 MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/response/FitnessLogResponse.java create mode 100644 MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/response/RunningLogResponse.java create mode 100644 MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/response/StudyLogResponse.java create mode 100644 MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/entity/UserLog/ExerciseInfo.java create mode 100644 MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/entity/UserLog/FitnessDetail.java create mode 100644 MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/entity/UserLog/RunningDetail.java create mode 100644 MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/entity/UserLog/StudyDetail.java rename MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/repository/{ => record}/RecordRepository.java (96%) create mode 100644 MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/repository/userLog/FitnessLogRepository.java create mode 100644 MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/repository/userLog/RunningLogRepository.java create mode 100644 MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/repository/userLog/StudyLogRepository.java create mode 100644 MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/service/ActivityDetailService.java diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/controller/ActivityDetailController.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/controller/ActivityDetailController.java new file mode 100644 index 0000000..e264c43 --- /dev/null +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/controller/ActivityDetailController.java @@ -0,0 +1,29 @@ +package MathCaptain.weakness.domain.Record.controller; + +import MathCaptain.weakness.domain.Record.service.ActivityDetailService; +import MathCaptain.weakness.global.Api.ApiResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/record/detail") +public class ActivityDetailController { + + private final ActivityDetailService activityDetailService; + + @GetMapping("/fitness/{activityId}") + public ApiResponse getFitnessLog(@PathVariable Long activityId) { + return ApiResponse.ok(activityDetailService.getFitnessLog(activityId)); + } + + @GetMapping("/study/{activityId}") + public ApiResponse getStudyLog(@PathVariable Long activityId) { + return ApiResponse.ok(activityDetailService.getStudyLog(activityId)); + } + + @GetMapping("/running/{activityId}") + public ApiResponse getRunningLog(@PathVariable Long activityId) { + return ApiResponse.ok(activityDetailService.getRunningLog(activityId)); + } +} diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/controller/RecordController.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/controller/RecordController.java index 941b85d..b64b2a4 100644 --- a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/controller/RecordController.java +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/controller/RecordController.java @@ -1,6 +1,9 @@ package MathCaptain.weakness.domain.Record.controller; -import MathCaptain.weakness.domain.Record.dto.request.recordEndRequest; +import MathCaptain.weakness.domain.Record.dto.request.FitnessLogEnrollRequest; +import MathCaptain.weakness.domain.Record.dto.request.RecordEndRequest; +import MathCaptain.weakness.domain.Record.dto.request.RunningLogEnrollRequest; +import MathCaptain.weakness.domain.Record.dto.request.StudyLogEnrollRequest; import MathCaptain.weakness.domain.Record.dto.response.RecordSummaryResponse; import MathCaptain.weakness.domain.Record.service.RecordService; import MathCaptain.weakness.domain.User.entity.Users; @@ -10,15 +13,36 @@ import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; +import static MathCaptain.weakness.domain.Group.enums.CategoryStatus.*; + @RestController @RequiredArgsConstructor -@RequestMapping("/record/") +@RequestMapping("/record") public class RecordController { private final RecordService recordService; - @PostMapping("/end/{groupId}") - public ApiResponse endActivity(@Valid @LoginUser Users loginUser, @PathVariable Long groupId, @RequestBody recordEndRequest requestDto) { - return ApiResponse.ok(recordService.endActivity(loginUser, groupId, requestDto)); + @PostMapping("/end/fitness/{groupId}") + public ApiResponse endFitnessActivity( + @Valid @LoginUser Users loginUser, + @PathVariable Long groupId, + @RequestBody FitnessLogEnrollRequest logRequest) { + return ApiResponse.ok(recordService.endActivity(loginUser, groupId, logRequest, FITNESS)); + } + + @PostMapping("/end/running/{groupId}") + public ApiResponse endRunningActivity( + @Valid @LoginUser Users loginUser, + @PathVariable Long groupId, + @RequestBody RunningLogEnrollRequest logRequest) { + return ApiResponse.ok(recordService.endActivity(loginUser, groupId, logRequest, RUNNING)); + } + + @PostMapping("/end/study/{groupId}") + public ApiResponse endStudyActivity( + @Valid @LoginUser Users loginUser, + @PathVariable Long groupId, + @RequestBody StudyLogEnrollRequest logRequest) { + return ApiResponse.ok(recordService.endActivity(loginUser, groupId, logRequest, STUDY)); } } diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/ActivityLogEnrollRequest.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/ActivityLogEnrollRequest.java new file mode 100644 index 0000000..7260a2b --- /dev/null +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/ActivityLogEnrollRequest.java @@ -0,0 +1,17 @@ +package MathCaptain.weakness.domain.Record.dto.request; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Getter +@NoArgsConstructor +public class ActivityLogEnrollRequest { + + private Long activityTime; + + private LocalDateTime startTime; + + private LocalDateTime endTime; +} diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/FitnessLogEnrollRequest.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/FitnessLogEnrollRequest.java new file mode 100644 index 0000000..52fd389 --- /dev/null +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/FitnessLogEnrollRequest.java @@ -0,0 +1,21 @@ +package MathCaptain.weakness.domain.Record.dto.request; + +import MathCaptain.weakness.domain.Record.entity.UserLog.ExerciseInfo; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; +import java.util.List; + +@Getter +@NoArgsConstructor +public class FitnessLogEnrollRequest extends ActivityLogEnrollRequest { + + private Long activityTime; + + private LocalDateTime startTime; + + private LocalDateTime endTime; + + private List exerciseInfoList; +} diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/recordEndRequest.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/RecordEndRequest.java similarity index 90% rename from MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/recordEndRequest.java rename to MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/RecordEndRequest.java index 8f9fb22..7de8664 100644 --- a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/recordEndRequest.java +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/RecordEndRequest.java @@ -6,7 +6,7 @@ @Getter @NoArgsConstructor(access = AccessLevel.PRIVATE) -public class recordEndRequest { +public class RecordEndRequest { // 수행 시간 (분) private Long activityTime; diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/RunningLogEnrollRequest.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/RunningLogEnrollRequest.java new file mode 100644 index 0000000..bf5050a --- /dev/null +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/RunningLogEnrollRequest.java @@ -0,0 +1,21 @@ +package MathCaptain.weakness.domain.Record.dto.request; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Getter +@NoArgsConstructor +public class RunningLogEnrollRequest extends ActivityLogEnrollRequest { + + private Long activityTime; + + private LocalDateTime startTime; + + private LocalDateTime endTime; + + private Long distance; + + private String memo; +} diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/StudyLogEnrollRequest.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/StudyLogEnrollRequest.java new file mode 100644 index 0000000..39f3877 --- /dev/null +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/StudyLogEnrollRequest.java @@ -0,0 +1,21 @@ +package MathCaptain.weakness.domain.Record.dto.request; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Getter +@NoArgsConstructor +public class StudyLogEnrollRequest extends ActivityLogEnrollRequest{ + + private Long activityTime; + + private LocalDateTime startTime; + + private LocalDateTime endTime; + + private String subject; + + private String memo; +} diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/response/FitnessLogResponse.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/response/FitnessLogResponse.java new file mode 100644 index 0000000..5d4b1a5 --- /dev/null +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/response/FitnessLogResponse.java @@ -0,0 +1,38 @@ +package MathCaptain.weakness.domain.Record.dto.response; + +import MathCaptain.weakness.domain.Record.entity.UserLog.ExerciseInfo; +import MathCaptain.weakness.domain.Record.entity.UserLog.FitnessDetail; +import jakarta.persistence.Column; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Getter +@NoArgsConstructor +public class FitnessLogResponse { + + private Long activityId; + + private Long duration; + + private String date; + + private List exerciseInfoList; + + private FitnessLogResponse(Long activityId, Long duration, String date, List exerciseInfoList) { + this.activityId = activityId; + this.duration = duration; + this.date = date; + this.exerciseInfoList = exerciseInfoList; + } + + public static FitnessLogResponse of(FitnessDetail fitnessDetail) { + return new FitnessLogResponse( + fitnessDetail.getActivityId(), + fitnessDetail.getDuration(), + fitnessDetail.getDate().toString(), + fitnessDetail.getExerciseInfoList() + ); + } +} diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/response/RecordSummaryResponse.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/response/RecordSummaryResponse.java index f4bd114..141f72f 100644 --- a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/response/RecordSummaryResponse.java +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/response/RecordSummaryResponse.java @@ -35,11 +35,16 @@ public class RecordSummaryResponse { // 사용자가 설정한 주간 목표 private int personalWeeklyGoal; - @Builder - private RecordSummaryResponse(String userName, String groupName, Long durationInMinutes, - boolean dailyGoalAchieved, boolean weeklyGoalAchieved, - Long remainingDailyGoalMinutes, int remainingWeeklyGoalDays, - Long personalDailyGoal, int personalWeeklyGoal) { + private FitnessLogResponse fitnessLogResponse; + + private RunningLogResponse runningLogResponse; + + private StudyLogResponse studyLogResponse; + + private RecordSummaryResponse(String userName, String groupName, Long durationInMinutes, boolean dailyGoalAchieved, + boolean weeklyGoalAchieved, Long remainingDailyGoalMinutes, int remainingWeeklyGoalDays, + Long personalDailyGoal, int personalWeeklyGoal, FitnessLogResponse fitnessLogResponse, + RunningLogResponse runningLogResponse, StudyLogResponse studyLogResponse) { this.userName = userName; this.groupName = groupName; this.durationInMinutes = durationInMinutes; @@ -49,19 +54,31 @@ private RecordSummaryResponse(String userName, String groupName, Long durationIn this.remainingWeeklyGoalDays = remainingWeeklyGoalDays; this.personalDailyGoal = personalDailyGoal; this.personalWeeklyGoal = personalWeeklyGoal; + this.fitnessLogResponse = fitnessLogResponse; + this.runningLogResponse = runningLogResponse; + this.studyLogResponse = studyLogResponse; } - public static RecordSummaryResponse of(ActivityRecord record, RelationBetweenUserAndGroup relation) { - return RecordSummaryResponse.builder() - .userName(record.getUser().getName()) - .groupName(record.getGroup().getName()) - .durationInMinutes(record.getDurationInMinutes()) - .dailyGoalAchieved(record.isDailyGoalAchieved()) - .weeklyGoalAchieved(record.isWeeklyGoalAchieved()) - .remainingDailyGoalMinutes(relation.remainingDailyGoalMinutes()) - .remainingWeeklyGoalDays(relation.remainingWeeklyGoalDays()) - .personalDailyGoal(relation.getPersonalDailyGoal() * 60L) - .personalWeeklyGoal(relation.getPersonalWeeklyGoal()) - .build(); + public static RecordSummaryResponse of( + ActivityRecord record, + RelationBetweenUserAndGroup relation, + FitnessLogResponse fitnessLog, + RunningLogResponse runningLog, + StudyLogResponse studyLog + ) { + return new RecordSummaryResponse( + record.getUser().getName(), + record.getGroup().getName(), + record.getDurationInMinutes(), + record.isDailyGoalAchieved(), + record.isWeeklyGoalAchieved(), + relation.remainingDailyGoalMinutes(), + relation.remainingWeeklyGoalDays(), + relation.getPersonalDailyGoal() * 60L, + relation.getPersonalWeeklyGoal(), + fitnessLog, + runningLog, + studyLog + ); } } diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/response/RunningLogResponse.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/response/RunningLogResponse.java new file mode 100644 index 0000000..bbb9f45 --- /dev/null +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/response/RunningLogResponse.java @@ -0,0 +1,32 @@ +package MathCaptain.weakness.domain.Record.dto.response; + +import MathCaptain.weakness.domain.Record.entity.UserLog.RunningDetail; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class RunningLogResponse { + + private Long activityId; + + private Long duration; + + private String date; + + private Long distance; + + private String memo; + + private RunningLogResponse(Long activityId, Long duration, String date, Long distance, String memo) { + this.activityId = activityId; + this.duration = duration; + this.date = date; + this.distance = distance; + this.memo = memo; + } + + public static RunningLogResponse of(RunningDetail runningDetail) { + return new RunningLogResponse(runningDetail.getActivityId(), runningDetail.getDuration(), runningDetail.getDate().toString(), runningDetail.getDistance(), runningDetail.getMemo()); + } +} diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/response/StudyLogResponse.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/response/StudyLogResponse.java new file mode 100644 index 0000000..4d6b6f1 --- /dev/null +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/response/StudyLogResponse.java @@ -0,0 +1,29 @@ +package MathCaptain.weakness.domain.Record.dto.response; + +import MathCaptain.weakness.domain.Record.entity.UserLog.StudyDetail; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class StudyLogResponse { + + private Long activityId; + + private String subject; + + private String date; + + private String memo; + + private StudyLogResponse(Long activityId, String subject, String date, String memo) { + this.activityId = activityId; + this.subject = subject; + this.date = date; + this.memo = memo; + } + + public static StudyLogResponse of(StudyDetail studyDetail) { + return new StudyLogResponse(studyDetail.getActivityId(), studyDetail.getSubject(), studyDetail.getDate().toString(), studyDetail.getMemo()); + } +} diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/entity/ActivityRecord.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/entity/ActivityRecord.java index 16f7cdd..cbc1d81 100644 --- a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/entity/ActivityRecord.java +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/entity/ActivityRecord.java @@ -2,7 +2,8 @@ import MathCaptain.weakness.domain.Group.entity.Group; import MathCaptain.weakness.domain.Group.entity.RelationBetweenUserAndGroup; -import MathCaptain.weakness.domain.Record.dto.request.recordEndRequest; +import MathCaptain.weakness.domain.Record.dto.request.ActivityLogEnrollRequest; +import MathCaptain.weakness.domain.Record.dto.request.RecordEndRequest; import MathCaptain.weakness.domain.User.entity.Users; import jakarta.persistence.*; import lombok.*; @@ -23,11 +24,11 @@ public class ActivityRecord { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @ManyToOne(fetch = FetchType.LAZY) + @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REMOVE) @JoinColumn(name = "user_id") private Users user; - @ManyToOne(fetch = FetchType.LAZY) + @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REMOVE) @JoinColumn(name = "group_id") private Group group; @@ -60,17 +61,31 @@ private ActivityRecord(Users user, Group group, LocalDateTime startTime, LocalDa this.dayOfWeek = dayOfWeek; } - public static ActivityRecord of(RelationBetweenUserAndGroup relation, recordEndRequest endRequest, DayOfWeek dayOfWeek) { + public static ActivityRecord of( + RelationBetweenUserAndGroup relation, + DayOfWeek dayOfWeek, LocalDateTime startTime, LocalDateTime endTime, Long duration) { return ActivityRecord.builder() .user(relation.getMember()) .group(relation.getGroup()) - .startTime(endRequest.getStartTime()) - .endTime(endRequest.getEndTime()) - .durationInMinutes(endRequest.getActivityTime()) + .startTime(startTime) + .endTime(endTime) + .durationInMinutes(duration) .dayOfWeek(dayOfWeek) .build(); } + public static ActivityRecord of( + RelationBetweenUserAndGroup relation, ActivityLogEnrollRequest request) { + return ActivityRecord.builder() + .user(relation.getMember()) + .group(relation.getGroup()) + .startTime(request.getStartTime()) + .endTime(request.getEndTime()) + .durationInMinutes(request.getActivityTime()) + .dayOfWeek(request.getStartTime().getDayOfWeek()) + .build(); + } + public static ActivityRecord of(Users user, Group group, LocalDateTime startTime, LocalDateTime endTime, Long activityTime, DayOfWeek dayOfWeek) { return ActivityRecord.builder() diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/entity/UserLog/ExerciseInfo.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/entity/UserLog/ExerciseInfo.java new file mode 100644 index 0000000..56b0181 --- /dev/null +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/entity/UserLog/ExerciseInfo.java @@ -0,0 +1,30 @@ +package MathCaptain.weakness.domain.Record.entity.UserLog; + +import jakarta.persistence.Embeddable; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Embeddable +@NoArgsConstructor +public class ExerciseInfo { + + private String exerciseName; + + private int weight; + + private int reps; + + private int sets; + + private ExerciseInfo(String exerciseName, int weight, int reps, int sets) { + this.exerciseName = exerciseName; + this.weight = weight; + this.reps = reps; + this.sets = sets; + } + + public static ExerciseInfo of(String exerciseName, int weight, int reps, int sets) { + return new ExerciseInfo(exerciseName, weight, reps, sets); + } +} diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/entity/UserLog/FitnessDetail.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/entity/UserLog/FitnessDetail.java new file mode 100644 index 0000000..c9995da --- /dev/null +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/entity/UserLog/FitnessDetail.java @@ -0,0 +1,41 @@ +package MathCaptain.weakness.domain.Record.entity.UserLog; + +import MathCaptain.weakness.domain.Record.dto.request.FitnessLogEnrollRequest; +import MathCaptain.weakness.domain.Record.entity.ActivityRecord; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; +import java.util.List; + +@Entity +@Getter +@NoArgsConstructor +public class FitnessDetail { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false, unique = true) + private Long activityId; + + private Long duration; + + private LocalDate date; + + @ElementCollection + private List exerciseInfoList; + + private FitnessDetail(Long activityId, Long duration, LocalDate date, List exerciseInfoList) { + this.activityId = activityId; + this.duration = duration; + this.date = date; + this.exerciseInfoList = exerciseInfoList; + } + + public static FitnessDetail of(ActivityRecord record, FitnessLogEnrollRequest request) { + return new FitnessDetail(record.getId(), record.getDurationInMinutes(), record.getEndTime().toLocalDate(), request.getExerciseInfoList()); + } +} diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/entity/UserLog/RunningDetail.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/entity/UserLog/RunningDetail.java new file mode 100644 index 0000000..09d9f8c --- /dev/null +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/entity/UserLog/RunningDetail.java @@ -0,0 +1,42 @@ +package MathCaptain.weakness.domain.Record.entity.UserLog; + +import MathCaptain.weakness.domain.Record.dto.request.RunningLogEnrollRequest; +import MathCaptain.weakness.domain.Record.entity.ActivityRecord; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; + +@Entity +@Getter +@NoArgsConstructor +public class RunningDetail { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false, unique = true) + private Long activityId; + + private Long duration; + + private Long distance; + + private LocalDate date; + + private String memo; + + private RunningDetail(Long activityId, Long duration, Long distance, LocalDate date, String memo) { + this.activityId = activityId; + this.duration = duration; + this.distance = distance; + this.date = date; + this.memo = memo; + } + + public static RunningDetail of(ActivityRecord record, RunningLogEnrollRequest request) { + return new RunningDetail(record.getId(), record.getDurationInMinutes(), request.getDistance(), record.getEndTime().toLocalDate() ,request.getMemo()); + } +} diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/entity/UserLog/StudyDetail.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/entity/UserLog/StudyDetail.java new file mode 100644 index 0000000..c35947d --- /dev/null +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/entity/UserLog/StudyDetail.java @@ -0,0 +1,42 @@ +package MathCaptain.weakness.domain.Record.entity.UserLog; + +import MathCaptain.weakness.domain.Record.dto.request.StudyLogEnrollRequest; +import MathCaptain.weakness.domain.Record.entity.ActivityRecord; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; + +@Entity +@Getter +@NoArgsConstructor +public class StudyDetail { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false, unique = true) + private Long activityId; + + private Long duration; + + private LocalDate date; + + private String subject; + + private String memo; + + private StudyDetail(Long activityId, String subject, Long duration, LocalDate date, String memo) { + this.activityId = activityId; + this.subject = subject; + this.duration = duration; + this.date = date; + this.memo = memo; + } + + public static StudyDetail of(ActivityRecord record, StudyLogEnrollRequest request) { + return new StudyDetail(record.getId(), request.getSubject(), record.getDurationInMinutes(), record.getEndTime().toLocalDate(),request.getMemo()); + } +} diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/repository/RecordRepository.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/repository/record/RecordRepository.java similarity index 96% rename from MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/repository/RecordRepository.java rename to MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/repository/record/RecordRepository.java index d4d870d..bfb9194 100644 --- a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/repository/RecordRepository.java +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/repository/record/RecordRepository.java @@ -1,4 +1,4 @@ -package MathCaptain.weakness.domain.Record.repository; +package MathCaptain.weakness.domain.Record.repository.record; import MathCaptain.weakness.domain.Group.entity.Group; import MathCaptain.weakness.domain.Record.entity.ActivityRecord; diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/repository/userLog/FitnessLogRepository.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/repository/userLog/FitnessLogRepository.java new file mode 100644 index 0000000..89f484b --- /dev/null +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/repository/userLog/FitnessLogRepository.java @@ -0,0 +1,9 @@ +package MathCaptain.weakness.domain.Record.repository.userLog; + +import MathCaptain.weakness.domain.Record.entity.UserLog.FitnessDetail; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface FitnessLogRepository extends JpaRepository { +} diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/repository/userLog/RunningLogRepository.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/repository/userLog/RunningLogRepository.java new file mode 100644 index 0000000..819e983 --- /dev/null +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/repository/userLog/RunningLogRepository.java @@ -0,0 +1,9 @@ +package MathCaptain.weakness.domain.Record.repository.userLog; + +import MathCaptain.weakness.domain.Record.entity.UserLog.RunningDetail; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface RunningLogRepository extends JpaRepository { +} diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/repository/userLog/StudyLogRepository.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/repository/userLog/StudyLogRepository.java new file mode 100644 index 0000000..98e82de --- /dev/null +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/repository/userLog/StudyLogRepository.java @@ -0,0 +1,9 @@ +package MathCaptain.weakness.domain.Record.repository.userLog; + +import MathCaptain.weakness.domain.Record.entity.UserLog.StudyDetail; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface StudyLogRepository extends JpaRepository { +} diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/service/ActivityDetailService.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/service/ActivityDetailService.java new file mode 100644 index 0000000..161dc6e --- /dev/null +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/service/ActivityDetailService.java @@ -0,0 +1,97 @@ +package MathCaptain.weakness.domain.Record.service; + +import MathCaptain.weakness.domain.Record.dto.request.FitnessLogEnrollRequest; +import MathCaptain.weakness.domain.Record.dto.request.RunningLogEnrollRequest; +import MathCaptain.weakness.domain.Record.dto.request.StudyLogEnrollRequest; +import MathCaptain.weakness.domain.Record.dto.response.FitnessLogResponse; +import MathCaptain.weakness.domain.Record.dto.response.RunningLogResponse; +import MathCaptain.weakness.domain.Record.dto.response.StudyLogResponse; +import MathCaptain.weakness.domain.Record.entity.ActivityRecord; +import MathCaptain.weakness.domain.Record.entity.UserLog.FitnessDetail; +import MathCaptain.weakness.domain.Record.entity.UserLog.RunningDetail; +import MathCaptain.weakness.domain.Record.entity.UserLog.StudyDetail; +import MathCaptain.weakness.domain.Record.repository.record.RecordRepository; +import MathCaptain.weakness.domain.Record.repository.userLog.FitnessLogRepository; +import MathCaptain.weakness.domain.Record.repository.userLog.RunningLogRepository; +import MathCaptain.weakness.domain.Record.repository.userLog.StudyLogRepository; +import MathCaptain.weakness.global.exception.ResourceNotFoundException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class ActivityDetailService { + + private final FitnessLogRepository fitnessLogRepository; + private final StudyLogRepository studyLogRepository; + private final RunningLogRepository runningLogRepository; + private final RecordRepository recordRepository; + + @Transactional + public FitnessLogResponse enrollFitnessLog(Long activityId, FitnessLogEnrollRequest request) { + ActivityRecord record = findRecordBy(activityId); + FitnessDetail fitnessDetail = FitnessDetail.of(record, request); + fitnessLogRepository.save(fitnessDetail); + return FitnessLogResponse.of(fitnessDetail); + } + + @Transactional + public RunningLogResponse enrollRunningLog(Long activityId, RunningLogEnrollRequest request) { + ActivityRecord record = findRecordBy(activityId); + RunningDetail runningDetail = RunningDetail.of(record, request); + runningLogRepository.save(runningDetail); + return RunningLogResponse.of(runningDetail); + } + + @Transactional + public StudyLogResponse enrollStudyLog(Long activityId, StudyLogEnrollRequest request) { + ActivityRecord record = findRecordBy(activityId); + StudyDetail studyDetail = StudyDetail.of(record, request); + studyLogRepository.save(studyDetail); + return StudyLogResponse.of(studyDetail); + } + + @Transactional + public FitnessLogResponse getFitnessLog(Long activityId) { + FitnessDetail fitnessDetail = findFitnessLogBy(activityId); + return FitnessLogResponse.of(fitnessDetail); + } + + @Transactional + public StudyLogResponse getStudyLog(Long activityId) { + StudyDetail studyDetail = findStudyLogBy(activityId); + return StudyLogResponse.of(studyDetail); + } + + @Transactional + public RunningLogResponse getRunningLog(Long activityId) { + RunningDetail runningDetail = findRunningLogBy(activityId); + return RunningLogResponse.of(runningDetail); + } + + + /// 로직 + + private StudyDetail findStudyLogBy(Long activityId) { + return studyLogRepository.findById(activityId) + .orElseThrow(() -> new ResourceNotFoundException("해당 기록을 찾을 수 없습니다.")); + } + + private RunningDetail findRunningLogBy(Long activityId) { + return runningLogRepository.findById(activityId) + .orElseThrow(() -> new ResourceNotFoundException("해당 기록을 찾을 수 없습니다.")); + } + + private FitnessDetail findFitnessLogBy(Long activityId) { + return fitnessLogRepository.findById(activityId) + .orElseThrow(() -> new ResourceNotFoundException("해당 기록을 찾을 수 없습니다.")); + } + + + private ActivityRecord findRecordBy(Long activityId) { + return recordRepository.findById(activityId) + .orElseThrow(() -> new ResourceNotFoundException("해당 기록을 찾을 수 없습니다.")); + } + +} diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/service/RecordService.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/service/RecordService.java index 967f4a0..4c96ce9 100644 --- a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/service/RecordService.java +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/service/RecordService.java @@ -2,11 +2,18 @@ import MathCaptain.weakness.domain.Group.entity.Group; import MathCaptain.weakness.domain.Group.entity.RelationBetweenUserAndGroup; +import MathCaptain.weakness.domain.Group.enums.CategoryStatus; import MathCaptain.weakness.domain.Group.repository.RelationRepository; +import MathCaptain.weakness.domain.Record.dto.request.*; +import MathCaptain.weakness.domain.Record.dto.response.FitnessLogResponse; +import MathCaptain.weakness.domain.Record.dto.response.RunningLogResponse; +import MathCaptain.weakness.domain.Record.dto.response.StudyLogResponse; import MathCaptain.weakness.domain.Record.entity.ActivityRecord; -import MathCaptain.weakness.domain.Record.dto.request.recordEndRequest; import MathCaptain.weakness.domain.Record.dto.response.RecordSummaryResponse; -import MathCaptain.weakness.domain.Record.repository.RecordRepository; +import MathCaptain.weakness.domain.Record.entity.UserLog.FitnessDetail; +import MathCaptain.weakness.domain.Record.entity.UserLog.RunningDetail; +import MathCaptain.weakness.domain.Record.entity.UserLog.StudyDetail; +import MathCaptain.weakness.domain.Record.repository.record.RecordRepository; import MathCaptain.weakness.domain.User.entity.Users; import MathCaptain.weakness.global.PointSet; import lombok.RequiredArgsConstructor; @@ -21,6 +28,8 @@ import java.util.*; import java.util.stream.Collectors; +import static MathCaptain.weakness.domain.Group.enums.CategoryStatus.*; + @Slf4j @Service @Transactional @@ -32,19 +41,102 @@ public class RecordService { private final RecordRepository recordRepository; private final RelationRepository relationRepository; + private final ActivityDetailService activityDetailService; /// 기록 // 기록 저장 - public RecordSummaryResponse endActivity(Users user, Long groupId, recordEndRequest endRequest) { + public RecordSummaryResponse endActivity(Users user, Long groupId, ActivityLogEnrollRequest logRequest, CategoryStatus activityType) { + // 활동 기록 저장 RelationBetweenUserAndGroup relation = findRelationByMemberAndGroup(user, groupId); - DayOfWeek nowDay = LocalDate.now().getDayOfWeek(); - ActivityRecord record = ActivityRecord.of(relation, endRequest, nowDay); - updateGoalAchieve(relation, record, nowDay); - recordRepository.save(record); - return RecordSummaryResponse.of(record, relation); + ActivityRecord record = ActivityRecord.of(relation, logRequest); + updateGoalAchieve(relation, record); + Long activityId = recordRepository.save(record).getId(); + + // 활동 로그 저장 및 응답 생성 + return createRecordSummaryResponse(activityType, activityId, logRequest, record, relation); + } + + private RecordSummaryResponse createRecordSummaryResponse( + CategoryStatus activityType, + Long activityId, + ActivityLogEnrollRequest logRequest, + ActivityRecord record, + RelationBetweenUserAndGroup relation) { + + FitnessLogResponse fitnessLogResponse = null; + RunningLogResponse runningLogResponse = null; + StudyLogResponse studyLogResponse = null; + + switch (activityType) { + case FITNESS: + fitnessLogResponse = activityDetailService.enrollFitnessLog(activityId, (FitnessLogEnrollRequest) logRequest); + break; + case RUNNING: + runningLogResponse = activityDetailService.enrollRunningLog(activityId, (RunningLogEnrollRequest) logRequest); + break; + case STUDY: + studyLogResponse = activityDetailService.enrollStudyLog(activityId, (StudyLogEnrollRequest) logRequest); + break; + default: + throw new IllegalArgumentException("Unsupported activity type: " + activityType); + } + + return RecordSummaryResponse.of(record, relation, fitnessLogResponse, runningLogResponse, studyLogResponse); } +// +// public RecordSummaryResponse endFitnessActivity(Users user, Long groupId, FitnessLogEnrollRequest logRequest) { +// // 활동 기록 저장 +// RelationBetweenUserAndGroup relation = findRelationByMemberAndGroup(user, groupId); +// DayOfWeek nowDay = LocalDate.now().getDayOfWeek(); +// +// LocalDateTime startTime = logRequest.getStartTime(); +// LocalDateTime endTime = logRequest.getEndTime(); +// Long duration = logRequest.getActivityTime(); +// +// ActivityRecord record = ActivityRecord.of(relation, nowDay, startTime, endTime, duration); +// updateGoalAchieve(relation, record, nowDay); +// Long activityId = recordRepository.save(record).getId(); +// +// // 피트니스 로그 저장 +// FitnessLogResponse fitnessLogResponse = activityDetailService.enrollFitnessLog(activityId, logRequest); +// return RecordSummaryResponse.of(record, relation, fitnessLogResponse, null, null); +// } +// +// public RecordSummaryResponse endRunningActivity(Users user, Long groupId, RunningLogEnrollRequest logRequest) { +// // 활동 기록 저장 +// RelationBetweenUserAndGroup relation = findRelationByMemberAndGroup(user, groupId); +// DayOfWeek nowDay = LocalDate.now().getDayOfWeek(); +// LocalDateTime startTime = logRequest.getStartTime(); +// LocalDateTime endTime = logRequest.getEndTime(); +// Long duration = logRequest.getActivityTime(); +// +// ActivityRecord record = ActivityRecord.of(relation, nowDay, startTime, endTime, duration); +// updateGoalAchieve(relation, record, nowDay); +// Long activityId = recordRepository.save(record).getId(); +// +// // 러닝 로그 저장 +// RunningLogResponse runningLogResponse = activityDetailService.enrollRunningLog(activityId, logRequest); +// return RecordSummaryResponse.of(record, relation, null, runningLogResponse, null); +// } +// +// public RecordSummaryResponse endStudyActivity(Users user, Long groupId, StudyLogEnrollRequest logRequest) { +// // 활동 기록 저장 +// RelationBetweenUserAndGroup relation = findRelationByMemberAndGroup(user, groupId); +// DayOfWeek nowDay = LocalDate.now().getDayOfWeek(); +// LocalDateTime startTime = logRequest.getStartTime(); +// LocalDateTime endTime = logRequest.getEndTime(); +// Long duration = logRequest.getActivityTime(); +// +// ActivityRecord record = ActivityRecord.of(relation, nowDay, startTime, endTime, duration); +// updateGoalAchieve(relation, record, nowDay); +// Long activityId = recordRepository.save(record).getId(); +// +// // 스터디 로그 저장 +// StudyLogResponse studyLogResponse = activityDetailService.enrollStudyLog(activityId, logRequest); +// return RecordSummaryResponse.of(record, relation, null, null, studyLogResponse); +// } // 주간 목표 달성 여부 조회 public Map getWeeklyGoalStatus(Users user, Group group, LocalDateTime weekStart) { @@ -69,7 +161,7 @@ private boolean isWeeklyGoalAchieved(RelationBetweenUserAndGroup relation) { } // 그룹의 요일 목표 수행 카운트 증가 - private void updateGoalAchieve(RelationBetweenUserAndGroup relation, ActivityRecord record, DayOfWeek nowDay) { + private void updateGoalAchieve(RelationBetweenUserAndGroup relation, ActivityRecord record) { // 일간 달성 시간 업데이트 (분) relation.updatePersonalDailyGoalAchieved( @@ -78,7 +170,7 @@ private void updateGoalAchieve(RelationBetweenUserAndGroup relation, ActivityRec // 일간 목표 시간 달성시 if (isDailyGoalAchieved(relation)) { record.updateDailyGoalAchieved(true); - relation.increaseWeeklyGroupCountOf(nowDay); + relation.increaseWeeklyGroupCountOf(record.getDayOfWeek()); addPoint(relation, DAILY_GOAL_ACHIEVE); relation.updatePersonalWeeklyGoalAchieved(); }