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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
import jakarta.persistence.Converter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

@Converter
Expand All @@ -16,6 +18,9 @@ public class StringListConverter implements AttributeConverter<List<String>, Str

@Override
public String convertToDatabaseColumn(List<String> attribute) {
if (attribute == null || attribute.isEmpty()) {
return "[]"; // 빈 리스트를 JSON 배열로 변환
}
try {
return objectMapper.writeValueAsString(attribute);
} catch (JsonProcessingException e) {
Expand All @@ -25,10 +30,17 @@ public String convertToDatabaseColumn(List<String> attribute) {

@Override
public List<String> convertToEntityAttribute(String dbData) {
if (dbData == null || dbData.trim().isEmpty()) {
return Collections.emptyList(); // 빈 리스트 반환
}
try {
return Arrays.asList(objectMapper.readValue(dbData, String[].class));
List<String> resultList = objectMapper.readValue(dbData, List.class);
if (resultList == null || resultList.contains(null)) {
return Collections.emptyList(); // null이거나 null이 포함된 경우 빈 리스트 반환
}
return resultList;
} catch (IOException e) {
throw new RuntimeException("Could not convert JSON to list", e);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.mtvs.devlinkbackend.experience.command.controller;

import com.mtvs.devlinkbackend.experience.command.model.dto.request.ExperienceRegistRequestDTO;
import com.mtvs.devlinkbackend.experience.command.model.dto.request.ExperienceUpdateRequestDTO;
import com.mtvs.devlinkbackend.experience.command.service.ExperienceService;
import com.mtvs.devlinkbackend.experience.query.model.dto.response.ExperienceSingleResponseDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/experience")
public class ExperienceCommandController {

private final ExperienceService experienceService;

public ExperienceCommandController(ExperienceService experienceService) {
this.experienceService = experienceService;
}

@Operation(summary = "새 활동 이력 이력 등록", description = "새 활동 이력 이력를 등록합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공적으로 등록됨"),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터"),
@ApiResponse(responseCode = "401", description = "인증되지 않음")
})
@PostMapping
public ResponseEntity<ExperienceSingleResponseDTO> registExperience(
@RequestBody ExperienceRegistRequestDTO experienceRegistRequestDTO) {

ExperienceSingleResponseDTO newExperience = experienceService.registExperience(experienceRegistRequestDTO);
return ResponseEntity.ok(newExperience);
}

@Operation(summary = "Experience 수정", description = "제공된 데이터를 기반으로 특정 Experience를 수정합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공적으로 수정됨"),
@ApiResponse(responseCode = "400", description = "잘못된 수정 데이터"),
@ApiResponse(responseCode = "401", description = "인증되지 않음")
})
@PatchMapping
public ResponseEntity<ExperienceSingleResponseDTO> updateEther(
@RequestBody ExperienceUpdateRequestDTO experienceUpdateRequestDTO) {
try {
ExperienceSingleResponseDTO updatedExperience = experienceService.updateExperience(experienceUpdateRequestDTO);
return ResponseEntity.ok(updatedExperience);
} catch (IllegalArgumentException e) {
return ResponseEntity.badRequest().body(null);
}
}

@Operation(summary = "Experience 삭제", description = "Experience ID를 사용하여 Experience를 삭제합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "204", description = "성공적으로 삭제됨"),
@ApiResponse(responseCode = "401", description = "인증되지 않음"),
@ApiResponse(responseCode = "404", description = "Ether를 찾을 수 없음")
})
@DeleteMapping("/{expId}")
public ResponseEntity<Void> deleteEtherByEtherId(@PathVariable Long expId) {
experienceService.deleteExperienceByExpId(expId);
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.mtvs.devlinkbackend.experience.command.model.dto.request;

import lombok.*;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class ExperienceRegistRequestDTO {
private Long expId;
private Long userId;
private String cause;
private Integer amount;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.mtvs.devlinkbackend.experience.command.model.dto.request;

import lombok.*;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class ExperienceUpdateRequestDTO {
private Long expId;
private Long userId;
private String cause;
private Integer amount;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.mtvs.devlinkbackend.experience.command.model.entity;

import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import java.time.LocalDateTime;

@Table(name = "EXPERIENCE")
@Entity(name = "Experience")
@Getter
@NoArgsConstructor
public class Experience {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "EXP_ID")
private Long expId;

@Column(name = "USER_ID")
private Long userId;

@Column(name = "CAUSE")
private String cause;

@Column(name = "AMOUNT")
private Integer amount;

@CreationTimestamp
@Column(name = "CREATED_AT")
private LocalDateTime createdAt;

@UpdateTimestamp
@Column(name = "MODIFIED_AT")
private LocalDateTime modifiedAt;

public Experience(Long userId, String cause, Integer amount) {
this.userId = userId;
this.cause = cause;
this.amount = amount;
}

public void setCause(String cause) {
this.cause = cause;
}

public void setAmount(Integer amount) {
this.amount = amount;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.mtvs.devlinkbackend.experience.command.repository;

import com.mtvs.devlinkbackend.experience.command.model.entity.Experience;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ExperienceRepository extends JpaRepository<Experience, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.mtvs.devlinkbackend.experience.command.service;

import com.mtvs.devlinkbackend.experience.command.model.dto.request.ExperienceRegistRequestDTO;
import com.mtvs.devlinkbackend.experience.command.model.dto.request.ExperienceUpdateRequestDTO;
import com.mtvs.devlinkbackend.experience.command.model.entity.Experience;
import com.mtvs.devlinkbackend.experience.command.repository.ExperienceRepository;
import com.mtvs.devlinkbackend.experience.query.model.dto.response.ExperienceSingleResponseDTO;
import com.mtvs.devlinkbackend.experience.query.repository.ExperienceViewRepository;
import com.mtvs.devlinkbackend.user.command.model.entity.User;
import com.mtvs.devlinkbackend.user.command.repository.UserRepository;
import com.mtvs.devlinkbackend.user.query.service.UserViewService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

@Service
public class ExperienceService {
private final ExperienceRepository experienceRepository;
private final ExperienceViewRepository experienceViewRepository;
private final UserViewService userViewService;
private final UserRepository userRepository;

public ExperienceService(ExperienceRepository experienceRepository, ExperienceViewRepository experienceViewRepository, UserViewService userViewService, UserRepository userRepository) {
this.experienceRepository = experienceRepository;
this.experienceViewRepository = experienceViewRepository;
this.userViewService = userViewService;
this.userRepository = userRepository;
}

@Transactional
public ExperienceSingleResponseDTO registExperience(ExperienceRegistRequestDTO experienceRegistRequestDTO) {
User user = userViewService.findUserByUserId(experienceRegistRequestDTO.getUserId()).getData();
if (user == null) {
throw new IllegalArgumentException("잘못된 UserId로 접근중");
}

// 경험치 업데이트
user.setExperienceValue(user.getExperienceValue() + experienceRegistRequestDTO.getAmount());

// 경험치 생성 및 저장
Experience experience = experienceRepository.save(new Experience(
experienceRegistRequestDTO.getUserId(),
experienceRegistRequestDTO.getCause(),
experienceRegistRequestDTO.getAmount()
));
return new ExperienceSingleResponseDTO(experience);
}

@Transactional
public ExperienceSingleResponseDTO updateExperience(ExperienceUpdateRequestDTO experienceUpdateRequestDTO) {
Optional<Experience> experience = experienceViewRepository.findById(experienceUpdateRequestDTO.getExpId());
if(experience.isEmpty())
throw new IllegalArgumentException("잘못된 expId로 접근중");
Experience foundExperience = experience.get();


User user = userViewService.findUserByUserId(experienceUpdateRequestDTO.getUserId()).getData();
if(user == null)
throw new IllegalArgumentException("잘못된 UserId로 접근중");

Integer difference = experienceUpdateRequestDTO.getAmount() - foundExperience.getAmount();

user.setExperienceValue(user.getExperienceValue() + difference);

foundExperience.setAmount(experienceUpdateRequestDTO.getAmount());
foundExperience.setCause(experienceUpdateRequestDTO.getCause());

return new ExperienceSingleResponseDTO(foundExperience);
}

@Transactional
public void deleteExperienceByExpId(Long expId) {
experienceRepository.deleteById(expId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.mtvs.devlinkbackend.experience.query.controller;

import com.mtvs.devlinkbackend.experience.query.model.dto.response.ExperienceListResponseDTO;
import com.mtvs.devlinkbackend.experience.query.model.dto.response.ExperienceSingleResponseDTO;
import com.mtvs.devlinkbackend.experience.query.service.ExperienceViewService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/experience")
public class ExperienceQueryController {

private final ExperienceViewService experienceViewService;

public ExperienceQueryController(ExperienceViewService experienceViewService) {
this.experienceViewService = experienceViewService;
}

@Operation(summary = "Experience ID로 Ether 조회", description = "Experience ID를 사용하여 활동내역을 조회합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공적으로 찾음"),
@ApiResponse(responseCode = "401", description = "인증되지 않음"),
@ApiResponse(responseCode = "404", description = "찾을 수 없음")
})
@GetMapping("/{expId}")
public ResponseEntity<ExperienceSingleResponseDTO> findExperienceByExpId(@PathVariable Long expId) {
ExperienceSingleResponseDTO experience = experienceViewService.findExperienceByExpId(expId);
return experience != null ? ResponseEntity.ok(experience) : ResponseEntity.notFound().build();
}

@Operation(summary = "사용자 ID로 활동 내역 목록 조회", description = "사용자 ID를 사용하여 관련된 모든 활동 내역들을 조회합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공적으로 찾음"),
@ApiResponse(responseCode = "401", description = "인증되지 않음")
})
@GetMapping("/{userId}/list/{page}")
public ResponseEntity<ExperienceListResponseDTO> findExperiencesByUserId(
@PathVariable(name = "userId") Long userId, @PathVariable(name = "page") Integer page) {

ExperienceListResponseDTO ethers = experienceViewService.findExperiencesByUserId(userId, page);
return ResponseEntity.ok(ethers);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.mtvs.devlinkbackend.experience.query.model.dto.response;

import com.mtvs.devlinkbackend.experience.command.model.entity.Experience;
import lombok.*;

import java.util.List;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class ExperienceListResponseDTO {
private List<Experience> data;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.mtvs.devlinkbackend.experience.query.model.dto.response;

import com.mtvs.devlinkbackend.experience.command.model.entity.Experience;
import lombok.*;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class ExperienceSingleResponseDTO {
private Experience data;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.mtvs.devlinkbackend.experience.query.repository;

import com.mtvs.devlinkbackend.experience.command.model.entity.Experience;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface ExperienceViewRepository extends JpaRepository<Experience, Long> {
List<Experience> findAllByUserId(Long userId, Pageable pageable);
}
Loading