Skip to content

Commit

Permalink
Merge pull request #411 from beyond-sw-camp/feat/aws_s3/#322
Browse files Browse the repository at this point in the history
feat: 이미지 s3 구현
  • Loading branch information
hcbak authored Jan 2, 2025
2 parents 12f76ef + 1d42ee0 commit cdeae13
Show file tree
Hide file tree
Showing 12 changed files with 285 additions and 273 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package error.pirate.backend.common;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter;
import org.springframework.stereotype.Component;

import java.lang.reflect.Type;

@Component
public class OctetStreamReadMsgConverter extends AbstractJackson2HttpMessageConverter {
@Autowired
public OctetStreamReadMsgConverter(ObjectMapper objectMapper) {
super(objectMapper, MediaType.APPLICATION_OCTET_STREAM);
}

// 기존 application/octet-stream 타입을 쓰기로 다루는 메시지 컨버터가 이미 존재 (ByteArrayHttpMessageConverter)
// 따라서 해당 컨버터는 쓰기 작업에는 이용하면 안됨
@Override
public boolean canWrite(Class<?> clazz, MediaType mediaType) {
return false;
}

@Override
public boolean canWrite(Type type, Class<?> clazz, MediaType mediaType) {
return false;
}

@Override
protected boolean canWrite(MediaType mediaType) {
return false;
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
package error.pirate.backend.config;

import error.pirate.backend.common.OctetStreamReadMsgConverter;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@Configuration
@RequiredArgsConstructor
public class WebConfig implements WebMvcConfigurer {

private final Environment env;
private final OctetStreamReadMsgConverter octetStreamReadMsgConverter;

@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 모든 경로에 대해
.allowedOrigins(env.getProperty("frontend")) // 허용할 출처
.allowedMethods("GET", "POST", "PUT", "PATCH", "DELETE") // 허용할 HTTP 메서드
.allowedHeaders("*") // 모든 헤더 허용
.exposedHeaders("Content-Disposition")
.allowCredentials(true); // 자격 증명(쿠키 등) 허용
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(octetStreamReadMsgConverter);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package error.pirate.backend.item.command.application.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import error.pirate.backend.item.command.application.dto.ItemCreateRequest;
import error.pirate.backend.item.command.application.dto.ItemUpdateRequest;
import error.pirate.backend.item.command.application.service.ItemService;
import error.pirate.backend.common.FileUploadUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -21,38 +18,24 @@
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/item")
@Tag(name = "Item", description = "품목 관리")
@Tag(name = "품목 관리", description = "품목 관리 API")
@Slf4j
public class ItemController {

private final ItemService itemService;
private final FileUploadUtil fileUploadUtil;

@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "품목 등록", description = "파일과 함께 품목을 등록합니다.", requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "multipart/form-data 형식의 요청 본문", content = @io.swagger.v3.oas.annotations.media.Content(mediaType = MediaType.MULTIPART_FORM_DATA_VALUE)
)
)
public ResponseEntity<String> createItem(
@Parameter(description = "업로드할 파일", required = true)
@RequestPart("file") MultipartFile file,
@Parameter(description = "품목 생성 요청 JSON ", required = true)
@RequestPart("request") ItemCreateRequest request
) throws IOException {
@Operation(summary = "품목 등록", description = "파일과 함께 품목을 등록합니다.")
public ResponseEntity<String> createItem(@RequestPart("file") MultipartFile file, @RequestPart("itemCreateRequest") ItemCreateRequest request) throws IOException {
itemService.createItem(request, file);
return ResponseEntity.status(HttpStatus.CREATED).build();
}

@PutMapping("/{itemSeq}")
@PutMapping(value = "/{itemSeq}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "품목 수정", description = "품목 정보를 수정합니다.")
public ResponseEntity<Void> updateItem(
@PathVariable Long itemSeq,
@RequestPart(value = "file", required = false) MultipartFile file,
@RequestPart(value = "request") ItemUpdateRequest request) throws IOException {
if (file != null && !file.isEmpty()) {
String imageUrl = fileUploadUtil.uploadFile(file);
request.setItemImageUrl(imageUrl);
}
itemService.updateItem(itemSeq, request);
public ResponseEntity<Void> updateItem(@PathVariable Long itemSeq, @RequestPart("file") MultipartFile file, @RequestPart("itemUpdateRequest") ItemUpdateRequest request) throws IOException {

itemService.updateItem(itemSeq, request, file);
return ResponseEntity.status(HttpStatus.OK).build();
}

Expand All @@ -62,4 +45,5 @@ public ResponseEntity<Void> deleteItem(@PathVariable Long itemSeq) {
itemService.deleteItem(itemSeq);
return ResponseEntity.noContent().build();
}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
package error.pirate.backend.item.command.application.dto;
package error.pirate.backend.item.command.application.dto;

import error.pirate.backend.item.command.domain.aggregate.entity.ItemDivision;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import error.pirate.backend.item.command.domain.aggregate.entity.ItemDivision;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.List;
import java.util.ArrayList;
import java.util.List;

@Data
public class ItemUpdateRequest {
@Data
public class ItemUpdateRequest {

private Long itemUnitSeq; // 품목 단위 ID
private String itemName; // 품목 이름
private ItemDivision itemDivision; // 품목 구분
private Integer itemExpirationHour; // 유통 기한 (시간)
private String itemImageUrl; // 이미지 URL
private Integer itemPrice; // 품목 가격
private String itemNote; // 품목 비고
private Long warehouseSeq;
private Long itemUnitSeq; // 품목 단위 ID
private Long warehouseSeq;
private String itemName; // 품목 이름
private ItemDivision itemDivision; // 품목 구분
private Integer itemExpirationHour; // 유통 기한 (시간)
private String itemImageUrl; // 이미지 URL
private Integer itemPrice; // 품목 가격
private String itemNote; // 품목 비고

private List<BomItemDTO> bomItemList = new ArrayList<>(); // bom 품목
}
private List<BomItemDTO> bomItemList = new ArrayList<>(); // bom 품목
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import error.pirate.backend.exception.CustomException;
import error.pirate.backend.exception.ErrorCodeType;
import error.pirate.backend.item.command.application.dto.BomItemDTO;
import error.pirate.backend.item.command.application.dto.ItemDTO;
import error.pirate.backend.item.command.application.dto.ItemCreateRequest;
import error.pirate.backend.item.command.application.dto.ItemUpdateRequest;
import error.pirate.backend.item.command.domain.aggregate.entity.BomItem;
Expand All @@ -21,6 +20,7 @@
import error.pirate.backend.warehouse.command.domain.repository.WarehouseRepository;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
Expand All @@ -30,6 +30,7 @@

@Service
@RequiredArgsConstructor
@Slf4j
public class ItemService {

private final ItemRepository itemRepository;
Expand All @@ -51,12 +52,9 @@ public void createItem(ItemCreateRequest request, MultipartFile file) throws IOE
Warehouse warehouse = warehouseRepository.findById(request.getWarehouseSeq())
.orElseThrow(() -> new CustomException(ErrorCodeType.WAREHOUSE_NOT_FOUND));

ItemDTO itemDTO = modelMapper.map(request, ItemDTO.class);
itemDTO.setUser(user);
itemDTO.setItemUnit(itemUnit);
itemDTO.setWarehouse(warehouse);
itemDTO.setItemImageUrl(fileUploadUtil.uploadFile(file));
Item item = modelMapper.map(itemDTO, Item.class);
request.setItemImageUrl(fileUploadUtil.uploadFile(file));

Item item = Item.createItem(user, itemUnit, warehouse, request);

// bom 등록
if(NullCheck.nullCheck(request.getBomItemList())) {
Expand All @@ -72,17 +70,11 @@ public void createItem(ItemCreateRequest request, MultipartFile file) throws IOE
}

@Transactional
public void updateItem(Long itemSeq, ItemUpdateRequest request) {

// userSeq는 나중에 토큰에서 빼올 것
// Long loginUserSeq = CustomUtil.getUserSeq();

Long loginUserSeq = 1L;

public void updateItem(Long itemSeq, ItemUpdateRequest request, MultipartFile file) throws IOException {
// 기존 품목 조회
Item item = itemRepository.findById(itemSeq)
.orElseThrow(() -> new CustomException(ErrorCodeType.ITEM_NOT_FOUND));
if(!ItemStatus.ACTIVE.equals(item.getItemStatus())) {
if (!ItemStatus.ACTIVE.equals(item.getItemStatus())) {
throw new CustomException(ErrorCodeType.ITEM_STATUS_ERROR);
}

Expand All @@ -92,13 +84,15 @@ public void updateItem(Long itemSeq, ItemUpdateRequest request) {
Warehouse warehouse = warehouseRepository.findById(request.getWarehouseSeq())
.orElseThrow(() -> new CustomException(ErrorCodeType.WAREHOUSE_NOT_FOUND));

item.updateItem(itemUnit, warehouse, request);
// 파일 업로드 처리
request.setItemImageUrl(fileUploadUtil.uploadFile(file));

item.updateItem(itemUnit, warehouse, request);

/* bom 수정 로직
* 1. 해당 부모 item의 bom 전체 삭제
* 2. bom 재등록
* */
* 1. 해당 부모 item의 bom 전체 삭제
* 2. bom 재등록
* */
bomItemRepository.deleteAllByParentItem(item);

if(NullCheck.nullCheck(request.getBomItemList())) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package error.pirate.backend.item.command.domain.aggregate.entity;

import error.pirate.backend.item.command.application.dto.ItemCreateRequest;
import error.pirate.backend.item.command.application.dto.ItemUpdateRequest;
import error.pirate.backend.user.command.domain.aggregate.entity.User;
import error.pirate.backend.warehouse.command.domain.aggregate.entity.Warehouse;
Expand Down Expand Up @@ -55,15 +56,43 @@ public class Item {
private String itemNote;

@Enumerated(EnumType.STRING)
private ItemStatus itemStatus = ItemStatus.ACTIVE;
private ItemStatus itemStatus;

public static Item createItem(User user, ItemUnit itemUnit, Warehouse warehouse, ItemCreateRequest request) {
Item item = new Item(request);
item.specifyUser(user);
item.specifyItemUnit(itemUnit);
item.specifyWarehouse(warehouse);

return item;
}

public Item(ItemCreateRequest request) {
this.itemName = request.getItemName();
this.itemDivision = request.getItemDivision();
this.itemExpirationHour = request.getItemExpirationHour();
this.itemImageUrl = request.getItemImageUrl();
this.itemPrice = request.getItemPrice();
this.itemNote = request.getItemNote();
this.itemStatus = ItemStatus.ACTIVE;
}

private void specifyUser(User user) {
this.user = user;
}

private void specifyItemUnit(ItemUnit itemUnit) {
this.itemUnit = itemUnit;
}

private void specifyWarehouse(Warehouse warehouse) {
this.warehouse = warehouse;
}

public void updateItem(ItemUnit itemUnit, Warehouse warehouse, ItemUpdateRequest request) {
if(itemUnit != null) {
this.itemUnit = itemUnit;
}
if(warehouse != null) {
this.warehouse = warehouse;
}
specifyItemUnit(itemUnit);
specifyWarehouse(warehouse);

if(request.getItemName() != null) {
this.itemName = request.getItemName();
}
Expand All @@ -83,6 +112,7 @@ public void updateItem(ItemUnit itemUnit, Warehouse warehouse, ItemUpdateRequest
this.itemNote = request.getItemNote();
}
}

// 품목 삭제 메서드
public void delete() {
this.itemStatus = ItemStatus.DELETED;
Expand Down
Loading

0 comments on commit cdeae13

Please sign in to comment.