diff --git a/.idea/modules.xml b/.idea/modules.xml index 1c0db2d..f1d544a 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,7 @@ + \ No newline at end of file diff --git a/.idea/modules/potato-field.main.iml b/.idea/modules/potato-field.main.iml new file mode 100644 index 0000000..41af0c5 --- /dev/null +++ b/.idea/modules/potato-field.main.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..2b63946 --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/potato-field/build.gradle b/potato-field/build.gradle index 6c3761c..df1867a 100644 --- a/potato-field/build.gradle +++ b/potato-field/build.gradle @@ -1,6 +1,6 @@ plugins { id 'java' - id 'org.springframework.boot' version '3.3.2' + id 'org.springframework.boot' version '3.3.2' // 버전 변경 id 'io.spring.dependency-management' version '1.1.6' } @@ -28,12 +28,19 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-validation' + implementation 'org.springframework.session:spring-session-core' + implementation 'org.springframework.boot:spring-boot-starter-data-redis' + implementation 'org.springframework.session:spring-session-data-redis' + + // JWT 관련 의존성 (중복 제거) implementation 'io.jsonwebtoken:jjwt-api:0.11.5' runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' + runtimeOnly 'com.h2database:h2' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' + testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.security:spring-security-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' @@ -41,4 +48,4 @@ dependencies { tasks.named('test') { useJUnitPlatform() -} +} \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/.DS_Store b/potato-field/src/main/java/com/tools/.DS_Store index 595ce2f..b75214e 100644 Binary files a/potato-field/src/main/java/com/tools/.DS_Store and b/potato-field/src/main/java/com/tools/.DS_Store differ diff --git a/potato-field/src/main/java/com/tools/potato_field/JwtAuthenticationFilter.java b/potato-field/src/main/java/com/tools/potato_field/JwtAuthenticationFilter.java new file mode 100644 index 0000000..17df5fa --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/JwtAuthenticationFilter.java @@ -0,0 +1,59 @@ +package com.tools.potato_field; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.lang.NonNull; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; +import com.tools.potato_field.member.CustomUserDetailsService; + +import java.io.IOException; + +@Component +public class JwtAuthenticationFilter extends OncePerRequestFilter { + + private final JwtUtil jwtUtil; + private final CustomUserDetailsService customUserDetailsService; + + public JwtAuthenticationFilter(JwtUtil jwtUtil, CustomUserDetailsService customUserDetailsService) { + this.jwtUtil = jwtUtil; + this.customUserDetailsService = customUserDetailsService; + } + + @Override + protected void doFilterInternal( + @NonNull HttpServletRequest request, + @NonNull HttpServletResponse response, + @NonNull FilterChain filterChain + ) throws ServletException, IOException { + final String authorizationHeader = request.getHeader("Authorization"); + + String username = null; + String jwt = null; + + if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) { + jwt = authorizationHeader.substring(7); + username = jwtUtil.extractUsername(jwt); + } + + if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { + UserDetails userDetails = this.customUserDetailsService.loadUserByUsername(username); + + if (jwtUtil.validateToken(jwt, userDetails)) { + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken( + userDetails, null, userDetails.getAuthorities()); + authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + SecurityContextHolder.getContext().setAuthentication(authenticationToken); + } + } + filterChain.doFilter(request, response); + } + + +} \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/JwtUtil.java b/potato-field/src/main/java/com/tools/potato_field/JwtUtil.java new file mode 100644 index 0000000..5690efe --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/JwtUtil.java @@ -0,0 +1,60 @@ +package com.tools.potato_field; + +import io.jsonwebtoken.*; +import io.jsonwebtoken.security.Keys; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Component; + +import javax.crypto.SecretKey; +import java.util.Date; +import java.util.function.Function; + +@Component +public class JwtUtil { + + // SecretKey를 더 안전하게 생성 + private final SecretKey secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS512); + + @Value("${jwt.expiration}") + private long expiration; + + public String generateToken(String username) { + return Jwts.builder() + .setSubject(username) + .setIssuedAt(new Date(System.currentTimeMillis())) + .setExpiration(new Date(System.currentTimeMillis() + expiration)) + .signWith(secretKey) // 여기서 안전한 키 사용 + .compact(); + } + + public boolean validateToken(String token, UserDetails userDetails) { + final String username = extractUsername(token); + return (username.equals(userDetails.getUsername()) && !isTokenExpired(token)); + } + + public String extractUsername(String token) { + return extractClaim(token, Claims::getSubject); + } + + public Date extractExpiration(String token) { + return extractClaim(token, Claims::getExpiration); + } + + public T extractClaim(String token, Function claimsResolver) { + final Claims claims = extractAllClaims(token); + return claimsResolver.apply(claims); + } + + private Claims extractAllClaims(String token) { + try { + return Jwts.parserBuilder().setSigningKey(secretKey).build().parseClaimsJws(token).getBody(); + } catch (ExpiredJwtException | UnsupportedJwtException | MalformedJwtException | SignatureException | IllegalArgumentException e) { + throw new JwtException("Invalid JWT token", e); + } + } + + private Boolean isTokenExpired(String token) { + return extractExpiration(token).before(new Date()); + } +} diff --git a/potato-field/src/main/java/com/tools/potato_field/PostCategory.java b/potato-field/src/main/java/com/tools/potato_field/PostCategory.java new file mode 100644 index 0000000..98e4905 --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/PostCategory.java @@ -0,0 +1,4 @@ +package com.tools.potato_field; + +public class PostCategory { +} diff --git a/potato-field/src/main/java/com/tools/potato_field/PotatoFieldApplication.java b/potato-field/src/main/java/com/tools/potato_field/PotatoFieldApplication.java index d295b4a..f0e79f6 100644 --- a/potato-field/src/main/java/com/tools/potato_field/PotatoFieldApplication.java +++ b/potato-field/src/main/java/com/tools/potato_field/PotatoFieldApplication.java @@ -2,12 +2,12 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; - +import org.springframework.context.annotation.ComponentScan; @SpringBootApplication + public class PotatoFieldApplication { public static void main(String[] args) { SpringApplication.run(PotatoFieldApplication.class, args); } - -} +} \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/ResourceNotFoundException.java b/potato-field/src/main/java/com/tools/potato_field/ResourceNotFoundException.java new file mode 100644 index 0000000..17d16ac --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/ResourceNotFoundException.java @@ -0,0 +1,15 @@ +package com.tools.potato_field; + +public class ResourceNotFoundException extends RuntimeException { + public ResourceNotFoundException() { + super(); + } + + public ResourceNotFoundException(String message) { + super(message); + } + + public ResourceNotFoundException(String message, Throwable cause) { + super(message, cause); + } +} \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/SecurityConfig.java b/potato-field/src/main/java/com/tools/potato_field/SecurityConfig.java index 3a9047e..b883e7b 100644 --- a/potato-field/src/main/java/com/tools/potato_field/SecurityConfig.java +++ b/potato-field/src/main/java/com/tools/potato_field/SecurityConfig.java @@ -2,16 +2,42 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +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.password.PasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @Configuration +@EnableWebSecurity public class SecurityConfig { + private final JwtAuthenticationFilter jwtAuthenticationFilter; + + public SecurityConfig(JwtAuthenticationFilter jwtAuthenticationFilter) { + this.jwtAuthenticationFilter = jwtAuthenticationFilter; + } + @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } - // 기타 보안 설정... + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http + .csrf(csrf -> csrf.disable()) + .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .authorizeHttpRequests(authz -> authz + .requestMatchers("/api/members/register", "/api/members/login", "/api/**").permitAll() + .requestMatchers("/h2-console/**").permitAll() + .anyRequest().authenticated() + ) + .headers(headers -> headers.frameOptions(frameOptions -> frameOptions.sameOrigin())) + .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); + + return http.build(); + } } \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/WebConfig.java b/potato-field/src/main/java/com/tools/potato_field/WebConfig.java new file mode 100644 index 0000000..62d67b2 --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/WebConfig.java @@ -0,0 +1,20 @@ +package com.tools.potato_field; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class WebConfig implements WebMvcConfigurer { + + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**") + .allowedOrigins("http://localhost:3000", + "http://10.50.44.159:3000") // 프론트엔드 서버 주소 + .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") + .allowedHeaders("*") + .allowCredentials(true) + .maxAge(3600); // 1시간 + } +} \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/category/Category1Controller.java b/potato-field/src/main/java/com/tools/potato_field/category/Category1Controller.java new file mode 100644 index 0000000..51ed801 --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/category/Category1Controller.java @@ -0,0 +1,69 @@ +package com.tools.potato_field.category; + +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; +import java.util.Optional; + +@RestController +@RequestMapping("/api/category1") +public class Category1Controller { + + @Autowired + private Category1Repository category1Repository; + + // Create + @PostMapping + public ResponseEntity createCategory1(@RequestBody Category_1 category1) { + Category_1 savedCategory = category1Repository.save(category1); + return new ResponseEntity<>(savedCategory, HttpStatus.CREATED); + } + + // Read + @GetMapping("/{id}") + public ResponseEntity getCategory1(@PathVariable Long id) { + Optional category1 = category1Repository.findById(id); + return category1.map(ResponseEntity::ok) + .orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND)); + } + + // Read All + @GetMapping + public ResponseEntity> getAllCategories1() { + List categories = category1Repository.findAll(); + return new ResponseEntity<>(categories, HttpStatus.OK); + } + + // Update + @PutMapping("/{id}") + public ResponseEntity updateCategory1(@PathVariable Long id, @RequestBody Category_1 category1Details) { + Optional category1Optional = category1Repository.findById(id); + + if (category1Optional.isPresent()) { + Category_1 category1 = category1Optional.get(); + + if (category1Details.getGenderName() != null) { + category1.setGenderName(category1Details.getGenderName()); + } + + Category_1 updatedCategory = category1Repository.save(category1); + return new ResponseEntity<>(updatedCategory, HttpStatus.OK); + } else { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + } + + // Delete + @DeleteMapping("/{id}") + public ResponseEntity deleteCategory1(@PathVariable Long id) { + if (category1Repository.existsById(id)) { + category1Repository.deleteById(id); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } else { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + } +} diff --git a/potato-field/src/main/java/com/tools/potato_field/category/Category1Repository.java b/potato-field/src/main/java/com/tools/potato_field/category/Category1Repository.java new file mode 100644 index 0000000..d424456 --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/category/Category1Repository.java @@ -0,0 +1,7 @@ +package com.tools.potato_field.category; + +import com.tools.potato_field.category.Category_1; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface Category1Repository extends JpaRepository { +} diff --git a/potato-field/src/main/java/com/tools/potato_field/category/Category2Controller.java b/potato-field/src/main/java/com/tools/potato_field/category/Category2Controller.java new file mode 100644 index 0000000..0d6924d --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/category/Category2Controller.java @@ -0,0 +1,58 @@ +package com.tools.potato_field.category; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Optional; + +@RestController +@RequestMapping("/api/category2") +public class Category2Controller { + + @Autowired + private Category2Repository category2Repository; + + // Create + @PostMapping + public ResponseEntity createCategory2(@RequestBody Category_2 category2) { + Category_2 savedCategory = category2Repository.save(category2); + return ResponseEntity.ok(savedCategory); + } + + // Read + @GetMapping("/{id}") + public ResponseEntity getCategory2(@PathVariable Long id) { + Optional category2 = category2Repository.findById(id); + return category2.map(ResponseEntity::ok) + .orElseGet(() -> ResponseEntity.notFound().build()); + } + + // Read All + @GetMapping + public ResponseEntity> getAllCategories2() { + List categories = category2Repository.findAll(); + return ResponseEntity.ok(categories); + } + + // Update + @PutMapping("/{id}") + public ResponseEntity updateCategory2(@PathVariable Long id, @RequestBody Category_2 category2Details) { + Category_2 category2 = category2Repository.findById(id).orElseThrow(() -> new RuntimeException("Category not found")); + + if (category2Details.getPlaceName() != null) { + category2.setPlaceName(category2Details.getPlaceName()); + } + + Category_2 updatedCategory = category2Repository.save(category2); + return ResponseEntity.ok(updatedCategory); + } + + // Delete + @DeleteMapping("/{id}") + public ResponseEntity deleteCategory2(@PathVariable Long id) { + category2Repository.deleteById(id); + return ResponseEntity.noContent().build(); + } +} diff --git a/potato-field/src/main/java/com/tools/potato_field/category/Category2Repository.java b/potato-field/src/main/java/com/tools/potato_field/category/Category2Repository.java new file mode 100644 index 0000000..0c92a6f --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/category/Category2Repository.java @@ -0,0 +1,7 @@ +package com.tools.potato_field.category; + +import com.tools.potato_field.category.Category_2; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface Category2Repository extends JpaRepository { +} diff --git a/potato-field/src/main/java/com/tools/potato_field/category/Category_1.java b/potato-field/src/main/java/com/tools/potato_field/category/Category_1.java new file mode 100644 index 0000000..14453a1 --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/category/Category_1.java @@ -0,0 +1,31 @@ +package com.tools.potato_field.category; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; + +@Entity +public class Category_1 { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String genderName; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } +} diff --git a/potato-field/src/main/java/com/tools/potato_field/category/Category_2.java b/potato-field/src/main/java/com/tools/potato_field/category/Category_2.java new file mode 100644 index 0000000..b1c0d29 --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/category/Category_2.java @@ -0,0 +1,31 @@ +package com.tools.potato_field.category; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; + +@Entity +public class Category_2 { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String placeName; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getPlaceName() { + return placeName; + } + + public void setPlaceName(String placeName) { + this.placeName = placeName; + } +} diff --git a/potato-field/src/main/java/com/tools/potato_field/comment/Comment.java b/potato-field/src/main/java/com/tools/potato_field/comment/Comment.java new file mode 100644 index 0000000..a276f1f --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/comment/Comment.java @@ -0,0 +1,39 @@ +package com.tools.potato_field.comment; + + +import com.tools.potato_field.member.Member; +import com.tools.potato_field.post.Post; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalDateTime; + +@Entity +@Getter +@Setter +public class Comment { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private String content; + + @ManyToOne + @JoinColumn(name = "post_id", nullable = false) + private Post post; + + @ManyToOne + @JoinColumn(name = "member_id", nullable = false) + private Member member; + + @Column(nullable = false) + private LocalDateTime createdAt; + + @PrePersist + protected void onCreate() { + createdAt = LocalDateTime.now(); + } +} \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/comment/CommentController.java b/potato-field/src/main/java/com/tools/potato_field/comment/CommentController.java new file mode 100644 index 0000000..3ce1e68 --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/comment/CommentController.java @@ -0,0 +1,29 @@ +package com.tools.potato_field.comment; + +import com.tools.potato_field.dto.CommentDto; +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/comments") +public class CommentController { + + @Autowired + private CommentService commentService; + + @PostMapping + public ResponseEntity createComment(@RequestBody CommentDto commentDto) { + CommentDto createdComment = commentService.createComment(commentDto); + return new ResponseEntity<>(createdComment, HttpStatus.CREATED); + } + + @GetMapping("/post/{postId}") + public ResponseEntity> getCommentsByPostId(@PathVariable Long postId) { + List comments = commentService.getCommentsByPostId(postId); + return new ResponseEntity<>(comments, HttpStatus.OK); + } +} \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/comment/CommentRepository.java b/potato-field/src/main/java/com/tools/potato_field/comment/CommentRepository.java new file mode 100644 index 0000000..e68bf51 --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/comment/CommentRepository.java @@ -0,0 +1,9 @@ +package com.tools.potato_field.comment; + +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface CommentRepository extends JpaRepository { + List findByPostId(Long postId); +} \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/comment/CommentService.java b/potato-field/src/main/java/com/tools/potato_field/comment/CommentService.java new file mode 100644 index 0000000..ea119e6 --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/comment/CommentService.java @@ -0,0 +1,56 @@ +package com.tools.potato_field.comment; + +import com.tools.potato_field.dto.CommentDto; +import com.tools.potato_field.member.Member; +import com.tools.potato_field.member.MemberRepository; +import com.tools.potato_field.post.Post; +import com.tools.potato_field.post.PostRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +public class CommentService { + + @Autowired + private CommentRepository commentRepository; + + @Autowired + private PostRepository postRepository; + + @Autowired + private MemberRepository memberRepository; + + public CommentDto createComment(CommentDto commentDto) { + Comment comment = new Comment(); + comment.setContent(commentDto.getContent()); + + Post post = postRepository.findById(commentDto.getPostId()) + .orElseThrow(() -> new RuntimeException("Post not found")); + comment.setPost(post); + + Member member = memberRepository.findById(commentDto.getMemberId()) + .orElseThrow(() -> new RuntimeException("Member not found")); + comment.setMember(member); + + Comment savedComment = commentRepository.save(comment); + return mapToDto(savedComment); + } + + public List getCommentsByPostId(Long postId) { + List comments = commentRepository.findByPostId(postId); + return comments.stream().map(this::mapToDto).collect(Collectors.toList()); + } + + private CommentDto mapToDto(Comment comment) { + CommentDto dto = new CommentDto(); + dto.setId(comment.getId()); + dto.setContent(comment.getContent()); + dto.setPostId(comment.getPost().getId()); + dto.setMemberId(comment.getMember().getId()); + dto.setCreatedAt(comment.getCreatedAt()); + return dto; + } +} \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/delivery/Delivery.java b/potato-field/src/main/java/com/tools/potato_field/delivery/Delivery.java deleted file mode 100644 index 292b13c..0000000 --- a/potato-field/src/main/java/com/tools/potato_field/delivery/Delivery.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.tools.potato_field.entity; - -import jakarta.persistence.*; -import lombok.Data; - -@Entity -@Data -public class Delivery { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @OneToOne - @JoinColumn(name = "order_id") - private Order order; - - private String status; -} \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/delivery/DeliveryController.java b/potato-field/src/main/java/com/tools/potato_field/delivery/DeliveryController.java deleted file mode 100644 index 14adb67..0000000 --- a/potato-field/src/main/java/com/tools/potato_field/delivery/DeliveryController.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.tools.potato_field.controller; - -import com.tools.potato_field.entity.Delivery; -import com.tools.potato_field.service.DeliveryService; -import org.springframework.web.bind.annotation.*; - -import java.util.List; - -@RestController -@RequestMapping("/deliveries") -public class DeliveryController { - private final DeliveryService deliveryService; - - public DeliveryController(DeliveryService deliveryService) { - this.deliveryService = deliveryService; - } - - @PostMapping - public Delivery createDelivery(@RequestBody Delivery delivery) { - return deliveryService.createDelivery(delivery); - } - - @GetMapping("/{id}") - public Delivery getDelivery(@PathVariable Long id) { - return deliveryService.findDelivery(id); - } - - @GetMapping - public List getAllDeliveries() { - return deliveryService.findAllDeliveries(); - } - - @DeleteMapping("/{id}") - public void deleteDelivery(@PathVariable Long id) { - deliveryService.deleteDelivery(id); - } -} diff --git a/potato-field/src/main/java/com/tools/potato_field/delivery/DeliveryRepository.java b/potato-field/src/main/java/com/tools/potato_field/delivery/DeliveryRepository.java deleted file mode 100644 index 996fe7c..0000000 --- a/potato-field/src/main/java/com/tools/potato_field/delivery/DeliveryRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.tools.potato_field.repository; - -import com.tools.potato_field.entity.Delivery; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface DeliveryRepository extends JpaRepository { -} diff --git a/potato-field/src/main/java/com/tools/potato_field/delivery/DeliveryService.java b/potato-field/src/main/java/com/tools/potato_field/delivery/DeliveryService.java deleted file mode 100644 index b30cc66..0000000 --- a/potato-field/src/main/java/com/tools/potato_field/delivery/DeliveryService.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.tools.potato_field.service; - -import com.tools.potato_field.entity.Delivery; -import com.tools.potato_field.repository.DeliveryRepository; -import org.springframework.stereotype.Service; - -import javax.transaction.Transactional; -import java.util.List; - -@Service -@Transactional -public class DeliveryService { - private final DeliveryRepository deliveryRepository; - - public DeliveryService(DeliveryRepository deliveryRepository) { - this.deliveryRepository = deliveryRepository; - } - - public Delivery createDelivery(Delivery delivery) { - return deliveryRepository.save(delivery); - } - - public Delivery findDelivery(Long id) { - return deliveryRepository.findById(id).orElseThrow(() -> new RuntimeException("Delivery not found")); - } - - public List findAllDeliveries() { - return deliveryRepository.findAll(); - } - - public void deleteDelivery(Long id) { - deliveryRepository.deleteById(id); - } -} \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/dto/AccountInfoDto.java b/potato-field/src/main/java/com/tools/potato_field/dto/AccountInfoDto.java new file mode 100644 index 0000000..8faef96 --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/dto/AccountInfoDto.java @@ -0,0 +1,11 @@ +package com.tools.potato_field.dto; + +import lombok.Getter; +import lombok.Setter; + +@Getter @Setter +public class AccountInfoDto { + private String userID; + private String phoneNumber; + private String email; +} \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/dto/CommentDto.java b/potato-field/src/main/java/com/tools/potato_field/dto/CommentDto.java new file mode 100644 index 0000000..51d254e --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/dto/CommentDto.java @@ -0,0 +1,17 @@ +package com.tools.potato_field.dto; + + +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalDateTime; + +@Getter +@Setter +public class CommentDto { + private Long id; + private String content; + private Long postId; + private Long memberId; + private LocalDateTime createdAt; +} \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/dto/LikesDTO.java b/potato-field/src/main/java/com/tools/potato_field/dto/LikesDTO.java new file mode 100644 index 0000000..2273399 --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/dto/LikesDTO.java @@ -0,0 +1,13 @@ +package com.tools.potato_field.dto; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class LikesDTO { + private Long id; + private Long memberId; + private Long postId; +} + diff --git a/potato-field/src/main/java/com/tools/potato_field/dto/LoginRequest.java b/potato-field/src/main/java/com/tools/potato_field/dto/LoginRequest.java index cf935c5..e27aaef 100644 --- a/potato-field/src/main/java/com/tools/potato_field/dto/LoginRequest.java +++ b/potato-field/src/main/java/com/tools/potato_field/dto/LoginRequest.java @@ -1,9 +1,14 @@ package com.tools.potato_field.dto; import lombok.Data; +import lombok.Getter; +import lombok.Setter; +@Getter +@Setter @Data public class LoginRequest { - private String email; + private String userID; private String password; + } \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/dto/MemberRegistrationDto.java b/potato-field/src/main/java/com/tools/potato_field/dto/MemberRegistrationDto.java new file mode 100644 index 0000000..20f0c9e --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/dto/MemberRegistrationDto.java @@ -0,0 +1,59 @@ +package com.tools.potato_field.dto; +import lombok.Data; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Data +public class MemberRegistrationDto { + private String name; + private String email; + private String userID; + private String password; + private String number; + + +} + // getters and setters + + /*public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getUserID() { + return userID; + } + + public void setUserID(String userID) { + this.userID = userID; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getNumber() { + return number; + } + + public void setNumber(String number) { + this.number = number; + } +}*/ \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/dto/PostLikesDTO.java b/potato-field/src/main/java/com/tools/potato_field/dto/PostLikesDTO.java new file mode 100644 index 0000000..ec8dc04 --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/dto/PostLikesDTO.java @@ -0,0 +1,12 @@ +package com.tools.potato_field.dto; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class PostLikesDTO { + private Long postId; + private String postTitle; // 포스트 제목 또는 관련 정보 + private int likeCount; // 좋아요 개수 +} diff --git a/potato-field/src/main/java/com/tools/potato_field/dto/ProfileDto.java b/potato-field/src/main/java/com/tools/potato_field/dto/ProfileDto.java new file mode 100644 index 0000000..508e073 --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/dto/ProfileDto.java @@ -0,0 +1,16 @@ +package com.tools.potato_field.dto; + +import lombok.Getter; +import lombok.Setter; + +@Getter @Setter +public class ProfileDto { + private String name; + private String description; + private String profileImageUrl; + private Integer height; + private String gender; + private Integer age; + private boolean isProfilePublic; + private String statusMessage; +} \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/dto/ViewInfoModel.java b/potato-field/src/main/java/com/tools/potato_field/dto/ViewInfoModel.java new file mode 100644 index 0000000..1fc5951 --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/dto/ViewInfoModel.java @@ -0,0 +1,15 @@ +package com.tools.potato_field.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ViewInfoModel { + + private String callId; + private String openedAt; + +} diff --git a/potato-field/src/main/java/com/tools/potato_field/entity/Category.java b/potato-field/src/main/java/com/tools/potato_field/entity/Category.java deleted file mode 100644 index 90413ca..0000000 --- a/potato-field/src/main/java/com/tools/potato_field/entity/Category.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.tools.potato_field.entity; - -@Entity -public class Category { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - private String placeName; -} diff --git a/potato-field/src/main/java/com/tools/potato_field/entity/Category_1.java b/potato-field/src/main/java/com/tools/potato_field/entity/Category_1.java deleted file mode 100644 index 551d783..0000000 --- a/potato-field/src/main/java/com/tools/potato_field/entity/Category_1.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.tools.potato_field.entity; - -@Entity -public class Category_1 { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - private String genderName; -} diff --git a/potato-field/src/main/java/com/tools/potato_field/exception/ItemNotFoundException.java b/potato-field/src/main/java/com/tools/potato_field/exception/ItemNotFoundException.java new file mode 100644 index 0000000..adf51fd --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/exception/ItemNotFoundException.java @@ -0,0 +1,7 @@ +package com.tools.potato_field.exception; + +public class ItemNotFoundException extends RuntimeException { + public ItemNotFoundException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/item/Item.java b/potato-field/src/main/java/com/tools/potato_field/item/Item.java index 3ccd091..b8815c1 100644 --- a/potato-field/src/main/java/com/tools/potato_field/item/Item.java +++ b/potato-field/src/main/java/com/tools/potato_field/item/Item.java @@ -1,6 +1,10 @@ -package com.tools.potato_field.entity; +package com.tools.potato_field.item; +import com.tools.potato_field.member.Member; +import com.tools.potato_field.post.Post; import jakarta.persistence.*; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.Data; @Entity @@ -9,14 +13,22 @@ public class Item { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + + @NotBlank(message = "Item name cannot be blank") private String itemName; + + @NotBlank(message = "Item URL cannot be blank") private String itemURL; + private Integer iconNumber; - private Long id2; @ManyToOne - @JoinColumn(name = "member_id") + @JoinColumn(name = "member_id", nullable = false) private Member member; + @ManyToOne + @JoinColumn(name = "post_id", nullable = false) + private Post post; + // Getters and Setters } \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/item/ItemController.java b/potato-field/src/main/java/com/tools/potato_field/item/ItemController.java index 57105d1..6c7f711 100644 --- a/potato-field/src/main/java/com/tools/potato_field/item/ItemController.java +++ b/potato-field/src/main/java/com/tools/potato_field/item/ItemController.java @@ -1,37 +1,65 @@ -package com.tools.potato_field.controller; +package com.tools.potato_field.item; -import com.tools.potato_field.entity.Item; -import com.tools.potato_field.service.ItemService; +import jakarta.validation.Valid; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; - -import java.util.List; +import com.tools.potato_field.member.Member; @RestController -@RequestMapping("/items") +@RequestMapping("/api/items") public class ItemController { - private final ItemService itemService; - public ItemController(ItemService itemService) { - this.itemService = itemService; - } + @Autowired + private ItemService itemService; + // Create @PostMapping - public Item addItem(@RequestBody Item item) { - return itemService.addItem(item); + public ResponseEntity createItem(@Valid @RequestBody Item item, @AuthenticationPrincipal Member member) { + item.setMember(member); // 현재 로그인한 멤버를 아이템의 소유자로 설정 + Item savedItem = itemService.addItem(item); + return ResponseEntity.ok(savedItem); } + // Read @GetMapping("/{id}") - public Item getItem(@PathVariable Long id) { - return itemService.findItem(id); + public ResponseEntity getItem(@PathVariable Long id) { + Item item = itemService.findItem(id); + return ResponseEntity.ok(item); } + // Read All with Pagination @GetMapping - public List getAllItems() { - return itemService.findAllItems(); + public ResponseEntity> getAllItems(Pageable pageable) { + Page items = itemService.findAllItems(pageable); + return ResponseEntity.ok(items); + } + + // Update + @PutMapping("/{id}") + public ResponseEntity updateItem(@PathVariable Long id, @Valid @RequestBody Item itemDetails) { + Item item = itemService.findItem(id); + + if (itemDetails.getItemName() != null) { + item.setItemName(itemDetails.getItemName()); + } + if (itemDetails.getItemURL() != null) { + item.setItemURL(itemDetails.getItemURL()); + } + if (itemDetails.getIconNumber() != null) { + item.setIconNumber(itemDetails.getIconNumber()); + } + Item updatedItem = itemService.addItem(item); + return ResponseEntity.ok(updatedItem); } + // Delete @DeleteMapping("/{id}") - public void deleteItem(@PathVariable Long id) { + public ResponseEntity deleteItem(@PathVariable Long id) { itemService.deleteItem(id); + return ResponseEntity.noContent().build(); } } diff --git a/potato-field/src/main/java/com/tools/potato_field/item/ItemRepository.java b/potato-field/src/main/java/com/tools/potato_field/item/ItemRepository.java index e6f1028..f6e5bc6 100644 --- a/potato-field/src/main/java/com/tools/potato_field/item/ItemRepository.java +++ b/potato-field/src/main/java/com/tools/potato_field/item/ItemRepository.java @@ -1,7 +1,12 @@ -package com.tools.potato_field.repository; +package com.tools.potato_field.item; -import com.tools.potato_field.entity.Item; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.List; public interface ItemRepository extends JpaRepository { + List findByPostId(Long postId); + + Page findAll(Pageable pageable); // 페이징 처리 } diff --git a/potato-field/src/main/java/com/tools/potato_field/item/ItemService.java b/potato-field/src/main/java/com/tools/potato_field/item/ItemService.java index 0d0bd28..cb3e2d6 100644 --- a/potato-field/src/main/java/com/tools/potato_field/item/ItemService.java +++ b/potato-field/src/main/java/com/tools/potato_field/item/ItemService.java @@ -1,10 +1,10 @@ -package com.tools.potato_field.service; +package com.tools.potato_field.item; -import com.tools.potato_field.entity.Item; -import com.tools.potato_field.repository.ItemRepository; +import com.tools.potato_field.exception.ItemNotFoundException; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; - -import javax.transaction.Transactional; +import jakarta.transaction.Transactional; import java.util.List; @Service @@ -21,14 +21,26 @@ public Item addItem(Item item) { } public Item findItem(Long id) { - return itemRepository.findById(id).orElseThrow(() -> new RuntimeException("Item not found")); + return itemRepository.findById(id) + .orElseThrow(() -> new ItemNotFoundException("Item not found with id: " + id)); } public List findAllItems() { return itemRepository.findAll(); } + public Page findAllItems(Pageable pageable) { // 페이징 처리 + return itemRepository.findAll(pageable); + } + public void deleteItem(Long id) { + if (!itemRepository.existsById(id)) { + throw new ItemNotFoundException("Item not found with id: " + id); + } itemRepository.deleteById(id); } -} \ No newline at end of file + + public List findItemsByPostId(Long postId) { + return itemRepository.findByPostId(postId); + } +} diff --git a/potato-field/src/main/java/com/tools/potato_field/like/Likes.java b/potato-field/src/main/java/com/tools/potato_field/like/Likes.java new file mode 100644 index 0000000..13bc7b3 --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/like/Likes.java @@ -0,0 +1,26 @@ +package com.tools.potato_field.like; + +import com.tools.potato_field.member.Member; +import com.tools.potato_field.post.Post; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +@Entity +public class Likes { + + // Getters and Setters + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne + @JoinColumn(name = "member_id", nullable = false)//데이터베이스 테이블에서 Member 엔티티의 id를 참조하는 외래키 + private Member member; + + @ManyToOne + @JoinColumn(name = "post_id", nullable = false) + private Post post; +} diff --git a/potato-field/src/main/java/com/tools/potato_field/like/LikesController.java b/potato-field/src/main/java/com/tools/potato_field/like/LikesController.java new file mode 100644 index 0000000..ccb3ac0 --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/like/LikesController.java @@ -0,0 +1,48 @@ +package com.tools.potato_field.like; + +import com.tools.potato_field.dto.LikesDTO; +import com.tools.potato_field.dto.PostLikesDTO; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/api/likes") +public class LikesController { + + private final LikesService likesService; + + public LikesController(LikesService likesService) { + this.likesService = likesService; + } + + //좋아요 추가 + @PostMapping("/posts/{postId}") + public ResponseEntity addLike(@RequestParam Long memberId, @PathVariable Long postId) { + LikesDTO likesDTO = likesService.addLike(memberId, postId); + return ResponseEntity.ok(likesDTO); + } + + //좋아요 삭제 + @DeleteMapping("/posts/{postId}") + public ResponseEntity removeLike(@RequestParam Long memberId, @PathVariable Long postId) { + likesService.removeLike(memberId, postId); + return ResponseEntity.ok().body("Like removed successfully"); + } + + // 포스트별 좋아요 개수 조회 + @GetMapping("/posts/{postId}/count") + public ResponseEntity getPostLikeCount(@PathVariable Long postId) { + PostLikesDTO postLikesDTO = likesService.getPostLikeCount(postId); + return ResponseEntity.ok(postLikesDTO); + } + + // 사용자가 좋아요한 포스트 목록 조회 + @GetMapping("/members/{memberId}/liked-posts") + public ResponseEntity> getUserLikedPosts(@PathVariable Long memberId) { + List likedPosts = likesService.getUserLikedPosts(memberId); + return ResponseEntity.ok(likedPosts); + } +} + diff --git a/potato-field/src/main/java/com/tools/potato_field/like/LikesRepository.java b/potato-field/src/main/java/com/tools/potato_field/like/LikesRepository.java new file mode 100644 index 0000000..ca550e9 --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/like/LikesRepository.java @@ -0,0 +1,12 @@ +package com.tools.potato_field.like; + +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; +import java.util.Optional; + +public interface LikesRepository extends JpaRepository { + Optional findByMemberIdAndPostId(Long memberId, Long postId); + int countByPostId(Long postId); // 포스트별 좋아요 개수 조회 + List findByMemberId(Long memberId); // 사용자가 좋아요한 포스트 목록 조회 +} diff --git a/potato-field/src/main/java/com/tools/potato_field/like/LikesService.java b/potato-field/src/main/java/com/tools/potato_field/like/LikesService.java new file mode 100644 index 0000000..5d38a5c --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/like/LikesService.java @@ -0,0 +1,93 @@ +package com.tools.potato_field.like; + +import com.tools.potato_field.dto.LikesDTO; +import com.tools.potato_field.dto.PostLikesDTO; +import com.tools.potato_field.member.Member; +import com.tools.potato_field.member.MemberRepository; +import com.tools.potato_field.post.Post; +import com.tools.potato_field.post.PostRepository; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +@Service +public class LikesService { + private final LikesRepository likesRepository; + private final MemberRepository memberRepository; + private final PostRepository postRepository; + + public LikesService(LikesRepository likesRepository, MemberRepository memberRepository, PostRepository postRepository) { + this.likesRepository = likesRepository; + this.memberRepository = memberRepository; + this.postRepository = postRepository; + } + + // 좋아요 추가 + public LikesDTO addLike(Long memberId, Long postId) { + Optional existingLike = likesRepository.findByMemberIdAndPostId(memberId, postId); + if (existingLike.isPresent()) { + throw new IllegalArgumentException("Already liked"); + } + + Member member = memberRepository.findById(memberId) + .orElseThrow(() -> new IllegalArgumentException("Invalid member ID")); + Post post = postRepository.findById(postId) + .orElseThrow(() -> new IllegalArgumentException("Invalid post ID")); + + Likes likes = new Likes(); + likes.setMember(member); + likes.setPost(post); + + Likes savedLike = likesRepository.save(likes); + return mapToDTO(savedLike); + } + + // 좋아요 삭제 + public void removeLike(Long memberId, Long postId) { + Optional existingLike = likesRepository.findByMemberIdAndPostId(memberId, postId); + existingLike.ifPresent(likesRepository::delete); + } + + // 포스트별 좋아요 개수 조회 + public PostLikesDTO getPostLikeCount(Long postId) { + Post post = postRepository.findById(postId) + .orElseThrow(() -> new IllegalArgumentException("Invalid post ID")); + + int likeCount = likesRepository.countByPostId(postId); + + PostLikesDTO postLikesDTO = new PostLikesDTO(); + postLikesDTO.setPostId(postId); + postLikesDTO.setPostTitle(post.getTitle()); // 포스트의 제목을 설정 + postLikesDTO.setLikeCount(likeCount); + + return postLikesDTO; + } + + // 사용자가 좋아요한 포스트 목록 조회 + public List getUserLikedPosts(Long memberId) { + Member member = memberRepository.findById(memberId) + .orElseThrow(() -> new IllegalArgumentException("Invalid member ID")); + + List likedPosts = likesRepository.findByMemberId(memberId); + + return likedPosts.stream() + .map(like -> { + PostLikesDTO dto = new PostLikesDTO(); + dto.setPostId(like.getPost().getId()); + dto.setPostTitle(like.getPost().getTitle()); // 포스트 제목 + dto.setLikeCount(likesRepository.countByPostId(like.getPost().getId())); + return dto; + }) + .collect(Collectors.toList()); + } + + private LikesDTO mapToDTO(Likes likes) { + LikesDTO dto = new LikesDTO(); + dto.setId(likes.getId()); + dto.setMemberId(likes.getMember().getId()); + dto.setPostId(likes.getPost().getId()); + return dto; + } +} diff --git a/potato-field/src/main/java/com/tools/potato_field/member/CustomUserDetailsService.java b/potato-field/src/main/java/com/tools/potato_field/member/CustomUserDetailsService.java new file mode 100644 index 0000000..a3e6424 --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/member/CustomUserDetailsService.java @@ -0,0 +1,27 @@ +package com.tools.potato_field.member; + + + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; + +@Service +public class CustomUserDetailsService implements UserDetailsService { + + @Autowired + private MemberRepository memberRepository; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + Member member = memberRepository.findByUserID(username) + .orElseThrow(() -> new UsernameNotFoundException("User not found with username: " + username)); + return new User(member.getUserID(), member.getPassword(), new ArrayList<>()); + } +} \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/member/GlobalExceptionHandler.java b/potato-field/src/main/java/com/tools/potato_field/member/GlobalExceptionHandler.java new file mode 100644 index 0000000..99ce01f --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/member/GlobalExceptionHandler.java @@ -0,0 +1,17 @@ +package com.tools.potato_field.member; + +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.http.ResponseEntity; +import org.springframework.http.HttpStatus; + + +@ControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(RuntimeException.class) + public ResponseEntity handleRuntimeException(RuntimeException ex) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ex.getMessage()); + } + +} diff --git a/potato-field/src/main/java/com/tools/potato_field/member/Member.java b/potato-field/src/main/java/com/tools/potato_field/member/Member.java index 66e9e0a..b518721 100644 --- a/potato-field/src/main/java/com/tools/potato_field/member/Member.java +++ b/potato-field/src/main/java/com/tools/potato_field/member/Member.java @@ -1,10 +1,8 @@ -package com.tools.potato_field.entity; +package com.tools.potato_field.member; import jakarta.persistence.*; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; +import lombok.*; + @Data @Builder @@ -12,11 +10,12 @@ @AllArgsConstructor @Entity @Table(name = "members") +@Getter@Setter public class Member { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; + private Long id; @Column(nullable = false, unique = true) private String email; @@ -24,9 +23,29 @@ public class Member { @Column(nullable = false) private String password; - private String name; + @Column(nullable = false, unique = true) + private String userID; + + private String number; - private String address; + + @Column(nullable = false) + private String name; + private Integer height; + private String gender; + private Integer age; + private String profileImageUrl; + private String statusMessage; + private String description; + private boolean isProfilePublic; + + public String getUserID() { + return userID; + } + + public void setUserID(String userID) { + this.userID = userID; + } // 추가적인 필드들 (예: 생년월일, 전화번호 등) } \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/member/MemberController.java b/potato-field/src/main/java/com/tools/potato_field/member/MemberController.java index 8a56985..8c3c3c1 100644 --- a/potato-field/src/main/java/com/tools/potato_field/member/MemberController.java +++ b/potato-field/src/main/java/com/tools/potato_field/member/MemberController.java @@ -1,11 +1,13 @@ -package com.tools.potato_field.controller; +package com.tools.potato_field.member; -import com.tools.potato_field.entity.Member; -import com.tools.potato_field.service.MemberService; import com.tools.potato_field.dto.LoginRequest; +import com.tools.potato_field.JwtUtil; 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.web.bind.annotation.*; +import com.tools.potato_field.dto.MemberRegistrationDto; import java.util.List; @@ -14,35 +16,62 @@ public class MemberController { private final MemberService memberService; + private final JwtUtil jwtUtil; @Autowired - public MemberController(MemberService memberService) { + public MemberController(MemberService memberService, JwtUtil jwtUtil) { this.memberService = memberService; + this.jwtUtil = jwtUtil; } @PostMapping("/register") - public ResponseEntity registerMember(@RequestBody Member member) { + public ResponseEntity registerMember(@RequestBody MemberRegistrationDto registrationDto) { + Member member = new Member(); + member.setName(registrationDto.getName()); + member.setEmail(registrationDto.getEmail()); + member.setUserID(registrationDto.getUserID()); + member.setPassword(registrationDto.getPassword()); + member.setNumber(registrationDto.getNumber()); + return ResponseEntity.ok(memberService.registerMember(member)); } + @PostMapping("/login") + public ResponseEntity loginMember(@RequestBody LoginRequest loginRequest) { + Member member = memberService.loginMember(loginRequest.getUserID(), loginRequest.getPassword()); + String token = jwtUtil.generateToken(member.getUserID()); + return ResponseEntity.ok(token); + } + + @PostMapping("/logout") + public ResponseEntity logoutMember() { + // JWT는 서버 측에서 세션을 유지하지 않으므로, 클라이언트에서 토큰을 삭제하도록 안내 + return ResponseEntity.ok("Logout successful. Please remove the token from the client side."); + } + + @GetMapping("/me") + public ResponseEntity getCurrentMember(Authentication authentication) { + String username = authentication.getName(); + Member member = memberService.findByUserID(username); + return ResponseEntity.ok(member); + } + @GetMapping("/{id}") - public ResponseEntity getMember(@PathVariable Long id) { + public ResponseEntity getMember(@PathVariable Long id, Authentication authentication) { + // 인증된 사용자만 접근 가능 return ResponseEntity.ok(memberService.findMember(id)); } @GetMapping - public ResponseEntity> getAllMembers() { + public ResponseEntity> getAllMembers(Authentication authentication) { + // 인증된 사용자만 접근 가능 return ResponseEntity.ok(memberService.findAllMembers()); } @DeleteMapping("/{id}") - public ResponseEntity deleteMember(@PathVariable Long id) { + public ResponseEntity deleteMember(@PathVariable Long id, Authentication authentication) { + // 인증된 사용자만 접근 가능 memberService.deleteMember(id); return ResponseEntity.ok().build(); } - - @PostMapping("/login") - public ResponseEntity loginMember(@RequestBody LoginRequest loginRequest) { - return ResponseEntity.ok(memberService.loginMember(loginRequest.getEmail(), loginRequest.getPassword())); - } } \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/member/MemberRepository.java b/potato-field/src/main/java/com/tools/potato_field/member/MemberRepository.java index ea2a577..90df395 100644 --- a/potato-field/src/main/java/com/tools/potato_field/member/MemberRepository.java +++ b/potato-field/src/main/java/com/tools/potato_field/member/MemberRepository.java @@ -1,6 +1,5 @@ -package com.tools.potato_field.repository; +package com.tools.potato_field.member; -import com.tools.potato_field.entity.Member; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @@ -9,4 +8,5 @@ @Repository public interface MemberRepository extends JpaRepository { Optional findByEmail(String email); + OptionalfindByUserID(String userID); } \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/member/MemberService.java b/potato-field/src/main/java/com/tools/potato_field/member/MemberService.java index 371583f..1fbdeb8 100644 --- a/potato-field/src/main/java/com/tools/potato_field/member/MemberService.java +++ b/potato-field/src/main/java/com/tools/potato_field/member/MemberService.java @@ -1,10 +1,10 @@ -package com.tools.potato_field.service; +package com.tools.potato_field.member; -import com.tools.potato_field.entity.Member; -import com.tools.potato_field.repository.MemberRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; +import com.tools.potato_field.dto.ProfileDto; +import com.tools.potato_field.dto.AccountInfoDto; import java.util.List; @@ -20,9 +20,17 @@ public MemberService(MemberRepository memberRepository, PasswordEncoder password this.passwordEncoder = passwordEncoder; } + public Member findByUserID(String username) { + return memberRepository.findByUserID(username) + .orElseThrow(() -> new RuntimeException("User not found with username: " + username)); + } + public Member registerMember(Member member) { + if (memberRepository.findByUserID(member.getUserID()).isPresent()) { + throw new RuntimeException("User ID already exists"); + } if (memberRepository.findByEmail(member.getEmail()).isPresent()) { - throw new RuntimeException("Email is already in use"); + throw new RuntimeException("Email already exists"); } member.setPassword(passwordEncoder.encode(member.getPassword())); return memberRepository.save(member); @@ -41,12 +49,58 @@ public void deleteMember(Long id) { memberRepository.deleteById(id); } - public Member loginMember(String email, String password) { - Member member = memberRepository.findByEmail(email) + public Member loginMember(String userID, String password) { + Member member = memberRepository.findByUserID(userID) .orElseThrow(() -> new RuntimeException("Member not found")); if (!passwordEncoder.matches(password, member.getPassword())) { throw new RuntimeException("Invalid password"); } return member; } + + // 새로 추가된 메소드: 프로필 정보 조회 + public ProfileDto getProfile(String userID) { + Member member = findByUserID(userID); + ProfileDto profileDTO = new ProfileDto(); + profileDTO.setName(member.getName()); + profileDTO.setDescription(member.getDescription()); + profileDTO.setProfileImageUrl(member.getProfileImageUrl()); + profileDTO.setHeight(member.getHeight()); + profileDTO.setGender(member.getGender()); + profileDTO.setAge(member.getAge()); + profileDTO.setProfilePublic(member.isProfilePublic()); + profileDTO.setStatusMessage(member.getStatusMessage()); + return profileDTO; + } + + // 새로 추가된 메소드: 계정 정보 조회 + public AccountInfoDto getAccountInfo(String userID) { + Member member = findByUserID(userID); + AccountInfoDto accountInfoDTO = new AccountInfoDto(); + accountInfoDTO.setUserID(member.getUserID()); + accountInfoDTO.setPhoneNumber(member.getNumber()); + accountInfoDTO.setEmail(member.getEmail()); + return accountInfoDTO; + } + + // 새로 추가된 메소드: 프로필 정보 업데이트 + public void updateProfile(String userID, ProfileDto profileDTO) { + Member member = findByUserID(userID); + member.setName(profileDTO.getName()); + member.setDescription(profileDTO.getDescription()); + member.setProfileImageUrl(profileDTO.getProfileImageUrl()); + member.setHeight(profileDTO.getHeight()); + member.setGender(profileDTO.getGender()); + member.setAge(profileDTO.getAge()); + member.setProfilePublic(profileDTO.isProfilePublic()); + member.setStatusMessage(profileDTO.getStatusMessage()); + memberRepository.save(member); + } + + // 새로 추가된 메소드: 프로필 공개 설정 업데이트 + public void updatePrivacySettings(String userID, boolean isProfilePublic) { + Member member = findByUserID(userID); + member.setProfilePublic(isProfilePublic); + memberRepository.save(member); + } } \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/order/Order.java b/potato-field/src/main/java/com/tools/potato_field/order/Order.java deleted file mode 100644 index c7dbb06..0000000 --- a/potato-field/src/main/java/com/tools/potato_field/order/Order.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.tools.potato_field.entity; - -import jakarta.persistence.*; -import lombok.Data; -import java.time.LocalDateTime; - -@Entity -@Data -@Table(name = "orders") // 'order'는 예약어이므로 'orders'로 사용 -public class Order { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "member_id") - private Member member; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "item_id") - private Item item; - - private LocalDateTime orderDate; - - private String orderStatus; -} \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/order/OrderController.java b/potato-field/src/main/java/com/tools/potato_field/order/OrderController.java deleted file mode 100644 index 1391510..0000000 --- a/potato-field/src/main/java/com/tools/potato_field/order/OrderController.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.tools.potato_field.controller; - -import com.tools.potato_field.entity.Order; -import com.tools.potato_field.service.OrderService; -import org.springframework.web.bind.annotation.*; - -import java.util.List; - -@RestController -@RequestMapping("/orders") -public class OrderController { - private final OrderService orderService; - - public OrderController(OrderService orderService) { - this.orderService = orderService; - } - - @PostMapping - public Order placeOrder(@RequestBody Order order) { - return orderService.placeOrder(order); - } - - @GetMapping("/{id}") - public Order getOrder(@PathVariable Long id) { - return orderService.findOrder(id); - } - - @GetMapping - public List getAllOrders() { - return orderService.findAllOrders(); - } -} \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/order/OrderRepository.java b/potato-field/src/main/java/com/tools/potato_field/order/OrderRepository.java deleted file mode 100644 index 788e3f8..0000000 --- a/potato-field/src/main/java/com/tools/potato_field/order/OrderRepository.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.tools.potato_field.repository; - -import com.tools.potato_field.entity.Order; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -import java.util.List; - -@Repository -public interface OrderRepository extends JpaRepository { - // 회원 ID로 주문 목록 조회 - List findByMemberId(Long memberId); - - // 주문 상태로 주문 목록 조회 - List findByOrderStatus(String orderStatus); - - // 추가적인 쿼리 메서드들을 필요에 따라 정의할 수 있습니다. -} \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/order/OrderService.java b/potato-field/src/main/java/com/tools/potato_field/order/OrderService.java deleted file mode 100644 index 42ffceb..0000000 --- a/potato-field/src/main/java/com/tools/potato_field/order/OrderService.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.tools.potato_field.service; - -import com.tools.potato_field.entity.Order; -import com.tools.potato_field.repository.OrderRepository; -import org.springframework.stereotype.Service; - -import javax.transaction.Transactional; -import java.util.List; - -@Service -@Transactional -public class OrderService { - private final OrderRepository orderRepository; - - public OrderService(OrderRepository orderRepository) { - this.orderRepository = orderRepository; - } - - public Order placeOrder(Order order) { - return orderRepository.save(order); - } - - public Order findOrder(Long id) { - return orderRepository.findById(id).orElseThrow(() -> new RuntimeException("Order not found")); - } - - public List findAllOrders() { - return orderRepository.findAll(); - } - - public void deleteOrder(Long id) { - orderRepository.deleteById(id); - } -} \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/post/Post.java b/potato-field/src/main/java/com/tools/potato_field/post/Post.java new file mode 100644 index 0000000..c72416f --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/post/Post.java @@ -0,0 +1,43 @@ +package com.tools.potato_field.post; + +import com.tools.potato_field.category.Category_1; +import jakarta.persistence.*; +import com.tools.potato_field.member.Member; +import lombok.Getter; +import lombok.Setter; + +@Entity +@Getter +@Setter + +public class Post { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String title; + private String content; + + @ManyToOne + @JoinColumn(name = "member_id", nullable = false) + private Member member; + + @ManyToOne + @JoinColumn(name = "category_id", nullable = false) + private Category_1 category; + + // 기본 생성자 + public Post() { + } + + // 모든 필드를 받는 생성자 + public Post(String title, String content, Member member, Category_1 category) { + this.title = title; + this.content = content; + this.member = member; + this.category = category; + } + + // Getters and Setters +} diff --git a/potato-field/src/main/java/com/tools/potato_field/post/PostController.java b/potato-field/src/main/java/com/tools/potato_field/post/PostController.java new file mode 100644 index 0000000..4431311 --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/post/PostController.java @@ -0,0 +1,57 @@ +package com.tools.potato_field.post; + +import com.tools.potato_field.ResourceNotFoundException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/api/posts") +public class PostController { + + private final PostService postService; + + // 생성자 주입 방식으로 PostService를 주입합니다. + public PostController(PostService postService) { + this.postService = postService; + } + + // 1. 포스트 생성 API (POST 요청) + @PostMapping + public ResponseEntity createPost(@RequestBody PostDto postDto) { + PostDto createdPost = postService.createPost(postDto); + return new ResponseEntity<>(createdPost, HttpStatus.CREATED); + } + + // 2. 포스트 조회 API (GET 요청) - 특정 ID로 조회 + @GetMapping("/{id}") + public ResponseEntity getPostById(@PathVariable Long id) { + PostDto postDto = postService.getPostById(id) + .orElseThrow(() -> new ResourceNotFoundException("Post not found with id: " + id)); + return new ResponseEntity<>(postDto, HttpStatus.OK); + } + + // 3. 포스트 목록 조회 API (GET 요청) - 전체 조회 + @GetMapping + public ResponseEntity> getAllPosts() { + List posts = postService.getAllPosts(); + return new ResponseEntity<>(posts, HttpStatus.OK); + } + + // 4. 포스트 수정 API (PUT 요청) + @PutMapping("/{id}") + public ResponseEntity updatePost(@PathVariable Long id, @RequestBody PostDto postDto) { + PostDto updatedPost = postService.updatePost(id, postDto); + return new ResponseEntity<>(updatedPost, HttpStatus.OK); + } + + // 5. 포스트 삭제 API (DELETE 요청) + @DeleteMapping("/{id}") + public ResponseEntity deletePost(@PathVariable Long id) { + postService.deletePost(id); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } +} + diff --git a/potato-field/src/main/java/com/tools/potato_field/post/PostDto.java b/potato-field/src/main/java/com/tools/potato_field/post/PostDto.java new file mode 100644 index 0000000..e7d7e42 --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/post/PostDto.java @@ -0,0 +1,29 @@ +package com.tools.potato_field.post; + + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class PostDto { + private Long id; + private String title; + private String content; + private Long memberId; + private Long categoryId; + + // 기본 생성자 (No-Args Constructor) + public PostDto() { + } + + // 모든 필드를 받는 생성자 (All-Args Constructor) + public PostDto(Long id, String title, String content, Long memberId, Long categoryId) { + this.id = id; + this.title = title; + this.content = content; + this.memberId = memberId; + this.categoryId = categoryId; + } + +} \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/post/PostRepository.java b/potato-field/src/main/java/com/tools/potato_field/post/PostRepository.java new file mode 100644 index 0000000..4781e8c --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/post/PostRepository.java @@ -0,0 +1,13 @@ +package com.tools.potato_field.post; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +import java.util.Optional; + +public interface PostRepository extends JpaRepository { + //권준영 + Page findByMemberUserID(String userID, Pageable pageable); + //권준영 +} diff --git a/potato-field/src/main/java/com/tools/potato_field/post/PostService.java b/potato-field/src/main/java/com/tools/potato_field/post/PostService.java new file mode 100644 index 0000000..d19fcda --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/post/PostService.java @@ -0,0 +1,91 @@ +package com.tools.potato_field.post; + +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import java.util.List; +import java.util.Optional; +import com.tools.potato_field.ResourceNotFoundException; +import com.tools.potato_field.postimage.PostImageRepository; +import java.util.stream.Collectors; + +@Service +public class PostService { + + private final PostRepository postRepository; + private final PostImageRepository postImageRepository; + + public PostService(PostRepository postRepository, PostImageRepository postImageRepository) { + this.postRepository = postRepository; + this.postImageRepository = postImageRepository; + } + + // 1. Post 생성 + public PostDto createPost(PostDto postDto) { + // PostDto를 Post 엔티티로 변환 + Post post = mapToEntity(postDto); + // Post 엔티티를 저장 + Post savedPost = postRepository.save(post); + // 저장된 Post 엔티티를 다시 PostDto로 변환하여 반환 + return mapToDto(savedPost); + } + + private Post mapToEntity(PostDto postDto) { + Post post = new Post(); + post.setTitle(postDto.getTitle()); + post.setContent(postDto.getContent()); + return post; + } + + // 2. 특정 ID로 Post 조회 + public Optional getPostById(Long id) { + // ID로 Post 엔티티 조회 + Post post = postRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException("Post not found with id: " + id)); + // 조회된 Post 엔티티를 PostDto로 변환하여 반환 + return Optional.of(mapToDto(post)); + } + + // 3. 모든 Post 조회 + public List getAllPosts() { + // 모든 Post 엔티티 조회 + List posts = postRepository.findAll(); + // 조회된 모든 Post 엔티티를 PostDto 리스트로 변환하여 반환 + return posts.stream().map(this::mapToDto).collect(Collectors.toList()); + } + + // 5. Post 삭제 + public void deletePost(Long id) { + // ID로 Post 엔티티 조회 + Post post = postRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException("Post not found with id: " + id)); + // Post 엔티티 삭제 + postRepository.delete(post); + } + + // Post 엔티티를 PostDto로 변환하는 헬퍼 메서드 + private PostDto mapToDto(Post post) { + PostDto postDto = new PostDto(); + postDto.setId(post.getId()); + postDto.setTitle(post.getTitle()); + postDto.setContent(post.getContent()); + postDto.setMemberId(post.getMember().getId()); + postDto.setCategoryId(post.getCategory().getId()); + return postDto; + } + + public PostDto updatePost(Long id, PostDto postDto) { + Post post = postRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException("Post not found with id: " + id)); + post.setTitle(postDto.getTitle()); + post.setContent(postDto.getContent()); + Post updatedPost = postRepository.save(post); + return mapToDto(updatedPost); + } // 4. Post 수정 + + + public List getPostsByUserID(String userID, int page, int size) { + Pageable pageable = PageRequest.of(page, size); + return postRepository.findByMemberUserID(userID, pageable).getContent(); + }//권준영 +} \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/postimage/PostImage.java b/potato-field/src/main/java/com/tools/potato_field/postimage/PostImage.java new file mode 100644 index 0000000..20105c0 --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/postimage/PostImage.java @@ -0,0 +1,54 @@ +package com.tools.potato_field.postimage; + +import com.tools.potato_field.post.Post; +import jakarta.persistence.*; +import jakarta.persistence.Id; + +@Entity +public class PostImage { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long imageId; + + private String imageUrl; + + @ManyToOne + @JoinColumn(name = "id") + private Post post; // 게시물과의 관계 + + // 기본 생성자 + public PostImage() {} + + // 모든 필드를 포함하는 생성자 + public PostImage(String imageUrl, Post post) { + this.imageUrl = imageUrl; + this.post = post; + } + + // Getter 및 Setter 메서드 + + public Long getImageId() { + return imageId; + } + + public void setImageId(Long imageId) { + this.imageId = imageId; + } + + public String getImageUrl() { + return imageUrl; + } + + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } + + public Post getPost() { + return post; + } + + public void setPost(Post post) { + this.post = post; + } +} diff --git a/potato-field/src/main/java/com/tools/potato_field/postimage/PostImageController.java b/potato-field/src/main/java/com/tools/potato_field/postimage/PostImageController.java new file mode 100644 index 0000000..116ca9b --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/postimage/PostImageController.java @@ -0,0 +1,40 @@ +package com.tools.potato_field.postimage; + +import com.tools.potato_field.ResourceNotFoundException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/api/post-images") +public class PostImageController { + + @Autowired + private PostImageRepository postImageRepository; + + @GetMapping + public List getAllPostImages() { + return postImageRepository.findAll(); + } + + @GetMapping("/{id}") + public PostImage getPostImageById(@PathVariable Long id) { + return postImageRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException("PostImage not found with id " + id)); + } + + @PostMapping + public PostImage createPostImage(@RequestBody PostImage postImage) { + return postImageRepository.save(postImage); + } + + @DeleteMapping("/{id}") + public void deletePostImage(@PathVariable Long id) { + PostImage postImage = postImageRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException("PostImage not found with id " + id)); + + postImageRepository.delete(postImage); + } +} + diff --git a/potato-field/src/main/java/com/tools/potato_field/postimage/PostImageRepository.java b/potato-field/src/main/java/com/tools/potato_field/postimage/PostImageRepository.java new file mode 100644 index 0000000..d55c7bc --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/postimage/PostImageRepository.java @@ -0,0 +1,5 @@ +package com.tools.potato_field.postimage; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PostImageRepository extends JpaRepository { } \ No newline at end of file diff --git a/potato-field/src/main/java/com/tools/potato_field/postimage/PostImageService.java b/potato-field/src/main/java/com/tools/potato_field/postimage/PostImageService.java new file mode 100644 index 0000000..c87d3de --- /dev/null +++ b/potato-field/src/main/java/com/tools/potato_field/postimage/PostImageService.java @@ -0,0 +1,4 @@ +package com.tools.potato_field.postimage; + +public class PostImageService { +} diff --git a/potato-field/src/main/resources/application.yml b/potato-field/src/main/resources/application.yml index 3a9ece4..7cbda4e 100644 --- a/potato-field/src/main/resources/application.yml +++ b/potato-field/src/main/resources/application.yml @@ -2,7 +2,7 @@ spring: application: name: potato-field datasource: - url: jdbc:h2:mem:testdb + url: jdbc:h2:mem:potato_field_db # 'testdb'를 더 명확한 이름으로 변경 driver-class-name: org.h2.Driver username: sa password: @@ -15,9 +15,13 @@ spring: console: enabled: true path: /h2-console - jwt: - secret: yourSecretKey - expiration: 86400000 # 24 hours + + server: - port: 8080 \ No newline at end of file + port: 8080 + +# JWT 설정을 별도의 섹션으로 분리 +jwt: + secret: yourSecretKey + expiration: 360000 \ No newline at end of file