Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat] createPlant, updatePlant, getPlantList 추가 #31

Merged
merged 3 commits into from
Aug 21, 2023
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
@@ -0,0 +1,88 @@
package com.umc.commonplant.domain.plant.controller;

import com.umc.commonplant.domain.Jwt.JwtService;
import com.umc.commonplant.domain.place.entity.Place;
import com.umc.commonplant.domain.place.service.PlaceService;
import com.umc.commonplant.domain.plant.dto.PlantDto;
import com.umc.commonplant.domain.plant.entity.Plant;
import com.umc.commonplant.domain.plant.service.PlantService;
import com.umc.commonplant.domain.user.entity.User;
import com.umc.commonplant.domain.user.service.UserService;
import com.umc.commonplant.global.dto.JsonResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

@Slf4j
@RequiredArgsConstructor
@RestController
public class PlantController {

private final UserService userService;
private final JwtService jwtService;
private final PlaceService placeService;
private final PlantService plantService;

/**
* [POST] 식물 추가
* [POST] /plant/add
* @return 추가한 식물의 애칭
*/
@PostMapping("/plant/add")
public ResponseEntity<JsonResponse> createPlant(@RequestPart("plant") PlantDto.createPlantReq createPlantReq,
@RequestPart("image") MultipartFile file) {

log.info("=============CREATE PLANT===============");

String uuid = jwtService.resolveToken();
User user = userService.getUser(uuid);

String nickname = plantService.createPlant(user, createPlantReq, file);

return ResponseEntity.ok(new JsonResponse(true, 200, "createPlant", nickname));
}

/**
* [GET] 같은 장소에 있는 식물 리스트 조회
* @param placeCode: 장소 코드
* @return 같은 장소에 있는 식물 리스트
*/
@GetMapping("/plant/plantList/{placeCode}")
public ResponseEntity<JsonResponse> getPlantList(@PathVariable String placeCode) {

log.info("=============GET PLANT LIST===============");

String uuid = jwtService.resolveToken();
User user = userService.getUser(uuid);

// Place place = placeService.getPlace(user, placeCode);
String place = placeService.getPlace(user, placeCode).getCode();

List<Plant> plantList = plantService.getPlantList(place);

return ResponseEntity.ok(new JsonResponse(true, 200, "getPlantList", plantList));
}

/**
* [PATCH] /plant/update
* @return 수정한 식물의 애칭
*/
@PatchMapping("/plant/update/{plantIdx}")
public ResponseEntity<JsonResponse> updatePlant(@PathVariable Long plantIdx,
@RequestPart("nickname") String nickname,
@RequestPart("image") MultipartFile file){

log.info("=============UPDATE PLANT===============");

String uuid = jwtService.resolveToken();
User user = userService.getUser(uuid);

String updatedPlant = plantService.updatePlant(plantIdx, nickname, file);

return ResponseEntity.ok(new JsonResponse(true, 200, "updatePlant", updatedPlant));
}
}
56 changes: 56 additions & 0 deletions src/main/java/com/umc/commonplant/domain/plant/dto/PlantDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.umc.commonplant.domain.plant.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.*;

import java.time.LocalDateTime;

public class PlantDto {

@AllArgsConstructor
@NoArgsConstructor
@Data
public static class createPlantReq{
// private String plantImage;
// TODO: 종 이름을 추가할 때 나중에 Information 에서 불러오기 때문에 추후 수정/삭제
// private String scientificName;
private String nickname;
// TODO: 장소를 추가할 때 장소 리스트에서 선택하는 것이기 때문에 추후 수정/삭제
private String place;
// TODO: (default)식물 도감에 있는 값(info.getWaterDay()), 사용자가 물주기 기간 설정 가능
private int waterCycle;
private String strWateredDate;
// TODO: 물주는 날짜가 적게 남은 순서로 정렬
}

@AllArgsConstructor
@NoArgsConstructor
@Getter
// @Builder
public static class getPlantRes{
private String name;
private String nickname;

private String place;

private String imgUrl;

private Long countDate;
private Long remainderDate;

// Info
private String scientificName;
private Long waterDay;
private String sunlight;
private Long tempMin;
private Long tempMax;
private String humidity;

@JsonFormat(pattern = "yyyy.MM.dd")
private LocalDateTime createdAt;

@JsonFormat(pattern = "yyyy.MM.dd")
private LocalDateTime wateredDate;
}

}
19 changes: 18 additions & 1 deletion src/main/java/com/umc/commonplant/domain/plant/entity/Plant.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.umc.commonplant.domain.plant.entity;

import com.umc.commonplant.domain.BaseTime;
import com.umc.commonplant.domain2.info.entity.Info;
import com.umc.commonplant.domain.place.entity.Place;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.OnDelete;
Expand Down Expand Up @@ -30,4 +30,21 @@ public class Plant extends BaseTime {
private String imgUrl;
private LocalDateTime wateredDate;

@Builder
public Plant(Place place, String name, String imgUrl, LocalDateTime wateredDate){
this.place = place;
// this.info = info;
this.name = name;
this.imgUrl = imgUrl;
this.wateredDate = wateredDate;
}

/**
* 식물 수정 API 관련 메소드
*/
public void updatePlant(String imgUrl, String name) {
this.imgUrl = imgUrl;
this.name = name;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.umc.commonplant.domain.plant.entity;

import com.umc.commonplant.domain.place.entity.Place;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;


@Repository
public interface PlantRepository extends JpaRepository<Plant, Long> {

@Query("select p from Plant p where p.plantIdx=?1")
Optional<Plant> findByPlantIdx(Long plantIdx);

@Query(value = "SELECT p FROM Plant p WHERE p.place= ?1 ")
List<Plant> findAllByPlace(Place place);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package com.umc.commonplant.domain.plant.service;

import com.umc.commonplant.domain.image.service.ImageService;
import com.umc.commonplant.domain.place.entity.Place;
import com.umc.commonplant.domain.place.entity.PlaceRepository;
import com.umc.commonplant.domain.place.service.PlaceService;
import com.umc.commonplant.domain.plant.dto.PlantDto;
import com.umc.commonplant.domain.plant.entity.Plant;
import com.umc.commonplant.domain.plant.entity.PlantRepository;
import com.umc.commonplant.domain.user.entity.User;
import com.umc.commonplant.global.exception.BadRequestException;
import com.umc.commonplant.global.exception.ErrorResponseStatus;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

@Slf4j
@RequiredArgsConstructor
@Service
public class PlantService {

private final PlaceRepository placeRepository;
private final PlantRepository plantRepository;

private final PlaceService placeService;
private final ImageService imageService;

/**
* createPlant: 식물 추가
* @param req
* @param plantImage
* @return
*/
@Transactional
public String createPlant(User user, PlantDto.createPlantReq req, MultipartFile plantImage) {

// 식물 이미지
String imgUrl = null;

if (plantImage.getSize() > 0) {
imgUrl = imageService.saveImage(plantImage);
} else {
throw new BadRequestException(ErrorResponseStatus.NO_SELECTED_PLANT_IMAGE);
}

// 식물 장소
// TODO: 식물이 있는 장소 -> 장소의 코드로 검색(추후 장소의 이름으로 바뀔 수 있음)
Place plantPlace = placeRepository.getPlaceByCode(req.getPlace())
.orElseThrow(() -> new BadRequestException(ErrorResponseStatus.NOT_FOUND_PLACE_NAME));

// 최근에 물 준 날짜
// TODO: WateredDate -> String에서 LocalDateTime으로 변환
String strWateredDate = req.getStrWateredDate();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy.MM.dd");

LocalDateTime parsedWateredDate = null;
parsedWateredDate = LocalDate.parse(strWateredDate, dateTimeFormatter).atStartOfDay();

// TODO: 식물 종 이름 -> 장소 처럼 검색(현재는 임시로 Info 객체 생성)
Plant plant = Plant.builder()
.place(plantPlace)
//.info(new Info())
.name(req.getNickname())
.imgUrl(imgUrl)
.wateredDate(parsedWateredDate)
.build();

plantRepository.save(plant);

return req.getNickname();
}

/**
* getPlantList: 같은 장소에 있는 식물 리스트 조회
* @param placeCode: 장소 코드
* @return List<Plant>
*/
@Transactional
public List<Plant> getPlantList(String placeCode) {

// TODO: 식물이 있는 장소 -> 장소의 코드로 검색(추후 장소의 이름으로 바뀔 수 있음)
Place plantPlace = placeRepository.getPlaceByCode(placeCode)
.orElseThrow(() -> new BadRequestException(ErrorResponseStatus.NOT_FOUND_PLACE_NAME));

return plantRepository.findAllByPlace(plantPlace);
}

/**
* updatePlant: 식물 수정
* @param plantIdx
* @param nickname
* @param plantImage
* @return
*/
@Transactional
public String updatePlant(Long plantIdx, String nickname, MultipartFile plantImage) {

Plant plant = plantRepository.findByPlantIdx(plantIdx)
.orElseThrow(() -> new BadRequestException(ErrorResponseStatus.NOT_FOUND_PLANT));

// TODO: 식물의 애칭
String plantNickname = null;

if (nickname.isEmpty()) {
throw new BadRequestException(ErrorResponseStatus.NO_PLANT_NICKNAME);
} else if (nickname.length() <= 10) {
plantNickname = nickname;
} else {
throw new BadRequestException(ErrorResponseStatus.LONG_PLANT_NICKNAME);
}

// TODO: imgUrl
String imgUrl = null;

if (plantImage.getSize() > 0) {
imgUrl = plant.getImgUrl();
} else {
throw new BadRequestException(ErrorResponseStatus.NO_SELECTED_PLANT_IMAGE);
}

plant.updatePlant(imgUrl, plantNickname);

return plantRepository.save(plant).getName();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ public enum ErrorResponseStatus {
EXPIRED_JWT(false, 4007, "만료된 토큰입니다."),

NOT_FOUND_PLACE_CODE(false, 4100, "등록된 code가 없습니다."),
NOT_FOUND_PLACE_NAME(false, 4101, "등록된 장소 이름이 없습니다."),

NOT_FOUND_PLANT(false, 4200, "등록된 식물이 없습니다."),
NO_PLANT_NICKNAME(false, 4201, "식물의 애칭을 입력해 주세요!"),
LONG_PLANT_NICKNAME(false, 4202, "식물의 애칭은 10자 이하로 설정해주세요!"),
NO_SELECTED_PLANT_IMAGE(false,4203, "식물의 이미지를 선택해주세요!"),

//5000 : Server connection 오류
SERVER_ERROR(false, 5000, "서버와의 연결에 실패하였습니다."),
Expand Down