Skip to content

Commit

Permalink
Merge pull request #34 from MarketPlace-O2O-Platform/feat/#32
Browse files Browse the repository at this point in the history
[Feat/#32] 매장 이미지 수정 기능 추가, 매장 응답 DTO 및 조회 로직 변경, 매장 삭제 시 이미지 삭제 로직 추가
  • Loading branch information
kangwook1 authored Nov 2, 2024
2 parents b713947 + d95c319 commit 447b5e6
Show file tree
Hide file tree
Showing 20 changed files with 303 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public class QImage extends EntityPathBase<Image> {

public final StringPath name = createString("name");

public final NumberPath<Integer> order = createNumber("order", Integer.class);

public QImage(String variable) {
this(Image.class, forVariable(variable), INITS);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.appcenter.marketplace.domain.image.dto.res;

import com.querydsl.core.types.dsl.*;

import com.querydsl.core.types.ConstructorExpression;
import javax.annotation.processing.Generated;

/**
* com.appcenter.marketplace.domain.image.dto.res.QImageResDto is a Querydsl Projection type for ImageResDto
*/
@Generated("com.querydsl.codegen.DefaultProjectionSerializer")
public class QImageResDto extends ConstructorExpression<ImageResDto> {

private static final long serialVersionUID = 796700072L;

public QImageResDto(com.querydsl.core.types.Expression<Long> id, com.querydsl.core.types.Expression<Integer> order, com.querydsl.core.types.Expression<String> name) {
super(ImageResDto.class, new Class<?>[]{long.class, int.class, String.class}, id, order, name);
}

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.appcenter.marketplace.domain.market.dto.res;

import com.querydsl.core.types.dsl.*;

import com.querydsl.core.types.ConstructorExpression;
import javax.annotation.processing.Generated;

/**
* com.appcenter.marketplace.domain.market.dto.res.QMarketResDto is a Querydsl Projection type for MarketResDto
*/
@Generated("com.querydsl.codegen.DefaultProjectionSerializer")
public class QMarketResDto extends ConstructorExpression<MarketResDto> {

private static final long serialVersionUID = -832137944L;

public QMarketResDto(com.querydsl.core.types.Expression<Long> marketId, com.querydsl.core.types.Expression<String> name, com.querydsl.core.types.Expression<String> description, com.querydsl.core.types.Expression<String> operationHours, com.querydsl.core.types.Expression<String> closedDays, com.querydsl.core.types.Expression<String> phoneNumber, com.querydsl.core.types.Expression<String> address, com.querydsl.core.types.Expression<? extends java.util.List<com.appcenter.marketplace.domain.image.dto.res.ImageResDto>> imageResDtoList) {
super(MarketResDto.class, new Class<?>[]{long.class, String.class, String.class, String.class, String.class, String.class, String.class, java.util.List.class}, marketId, name, description, operationHours, closedDays, phoneNumber, address, imageResDtoList);
}

}

Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.appcenter.marketplace.domain.coupon.service.impl;

import com.appcenter.marketplace.domain.coupon.Coupon;
import com.appcenter.marketplace.domain.coupon.CouponRepository;
import com.appcenter.marketplace.domain.coupon.dto.req.CouponReqDto;
import com.appcenter.marketplace.domain.coupon.dto.req.CouponUpdateReqDto;
import com.appcenter.marketplace.domain.coupon.dto.res.CouponHiddenResDto;
import com.appcenter.marketplace.domain.coupon.dto.res.CouponResDto;
import com.appcenter.marketplace.domain.coupon.CouponRepository;
import com.appcenter.marketplace.domain.coupon.service.CouponService;
import com.appcenter.marketplace.domain.market.Market;
import com.appcenter.marketplace.domain.market.MarketRepository;
import com.appcenter.marketplace.domain.market.repository.MarketRepository;
import com.appcenter.marketplace.global.exception.CustomException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
Expand Down
10 changes: 8 additions & 2 deletions src/main/java/com/appcenter/marketplace/domain/image/Image.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ public class Image extends BaseEntity {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(nullable = false)
private Integer order;

@Column(nullable = false)
private String name;

Expand All @@ -25,8 +28,11 @@ public class Image extends BaseEntity {
private Market market;

@Builder
public Image(String name, Market market) {
this.name=name;
public Image(Integer order, String name, Market market) {
this.order = order;
this.name = name;
this.market = market;
}

public void updateOrder(Integer order){ this.order= order;}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,9 @@

import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface ImageRepository extends JpaRepository<Image,Long> {

List<Image> findAllByMarket_Id(Long marketId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.appcenter.marketplace.domain.image.dto.res;

import com.querydsl.core.annotations.QueryProjection;
import lombok.Getter;

@Getter
public class ImageResDto {
private final Long id;
private final Integer order;
private final String name;


@QueryProjection
public ImageResDto(Long id, Integer order, String name) {
this.id = id;
this.order = order;
this.name = name;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.appcenter.marketplace.domain.image.service;

import com.appcenter.marketplace.domain.market.Market;
import com.appcenter.marketplace.domain.market.dto.req.MarketImageUpdateReqDto;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
Expand All @@ -9,4 +10,9 @@
public interface ImageService {

void createImage(Market market, List<MultipartFile> multipartFileList) throws IOException;

void UpdateImage(Market market, MarketImageUpdateReqDto marketImageUpdateReqDto,
List<MultipartFile> multipartFileList) throws IOException;

void deleteAllImages(Long marketId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import com.appcenter.marketplace.domain.image.ImageRepository;
import com.appcenter.marketplace.domain.image.service.ImageService;
import com.appcenter.marketplace.domain.market.Market;
import com.appcenter.marketplace.domain.market.dto.req.MarketImageUpdateReqDto;
import com.appcenter.marketplace.global.exception.CustomException;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
Expand All @@ -13,8 +15,12 @@
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import static com.appcenter.marketplace.global.common.StatusCode.FILE_DELETE_INVALID;
import static com.appcenter.marketplace.global.common.StatusCode.IMAGE_NOT_EXIST;

@Transactional(readOnly = true)
@Service
@RequiredArgsConstructor
Expand All @@ -29,23 +35,99 @@ public class ImageServiceImpl implements ImageService {
@Transactional
public void createImage(Market market, List<MultipartFile> multipartFileList) throws IOException {

for (int i = 0; i < multipartFileList.size(); i++){
// 이미지 리스트를 순회하며 저장하고 순서를 1부터 매겨 이미지 엔티티를 생성한다.
for (int i = 0; i < multipartFileList.size(); i++) {
MultipartFile file = multipartFileList.get(i);
String imageFileName = UUID.randomUUID() + "_" + file.getOriginalFilename();
File uploadFile = new File(uploadFolder + imageFileName);

file.transferTo(uploadFile);

Image image= Image.builder()
Image image = Image.builder()
.order(i + 1)
.name(imageFileName)
.market(market)
.build();
imageRepository.save(image);

if(i==0){
// 첫번 째 요소는 썸네일로 지정
if (i == 0) {
market.updateThumbnailPath(image.getName());
}

}
}

@Override
@Transactional
public void UpdateImage(Market market, MarketImageUpdateReqDto marketImageUpdateReqDto, List<MultipartFile> multipartFileList) throws IOException {

// 삭제할 이미지 id 리스트를 순회하며 파일을 삭제하고 이미지 엔티티를 삭제한다.
for (Long id : marketImageUpdateReqDto.getDeletedImageIds()) {
Image image = findById(id);

File file = new File(uploadFolder + image.getName());
if (!file.delete())
throw new CustomException(FILE_DELETE_INVALID);

imageRepository.deleteById(id);
}

// 순서가 변경될 Map 객체를 순회하며 이미지 엔티티의 순서를 변경한다.
for (Map.Entry<Long, Integer> entry : marketImageUpdateReqDto.getChangedOrders().entrySet()) {
Long id = entry.getKey();
Integer order = entry.getValue();

Image image = findById(id);
image.updateOrder(order);

// 순서가 1인 엔티티는 마켓의 썸네일로 선정한다.
if(order==1) market.updateThumbnailPath(image.getName());
}

// 추가될 이미지 리스트와 추가될 이미지의 순서 리스트의 길이가 맞지 않으면 안된다.
if(multipartFileList.size()==marketImageUpdateReqDto.getAddedImageOrders().size()){
// 리스트를 순회하며 이미지를 저장하고 순서를 매겨 엔티티를 생성한다.
for (int i = 0; i < multipartFileList.size(); i++) {
Integer order= marketImageUpdateReqDto.getAddedImageOrders().get(i);
MultipartFile file = multipartFileList.get(i);
String imageFileName = UUID.randomUUID() + "_" + file.getOriginalFilename();
File uploadFile = new File(uploadFolder + imageFileName);

file.transferTo(uploadFile);

Image image = Image.builder()
.order(order)
.name(imageFileName)
.market(market)
.build();
imageRepository.save(image);

// 순서가 1인 엔티티는 마켓의 썸네일로 선정한다.
if(order==1) market.updateThumbnailPath(image.getName());
}
}

}

@Override
@Transactional
public void deleteAllImages(Long marketId) {
List<Image> images= imageRepository.findAllByMarket_Id(marketId);

for (Image image: images){
File file = new File(uploadFolder + image.getName());
if (!file.delete())
throw new CustomException(FILE_DELETE_INVALID);
}

// delete 쿼리 한꺼번에 실행
imageRepository.deleteAllInBatch(images);

}

private Image findById(Long id){
return imageRepository.findById(id).orElseThrow(() -> new CustomException(IMAGE_NOT_EXIST));
}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.appcenter.marketplace.domain.market.controller;

import com.appcenter.marketplace.domain.market.dto.req.MarketCreateReqDto;
import com.appcenter.marketplace.domain.market.dto.req.MarketImageUpdateReqDto;
import com.appcenter.marketplace.domain.market.dto.req.MarketUpdateReqDto;
import com.appcenter.marketplace.domain.market.dto.res.MarketResDto;
import com.appcenter.marketplace.domain.market.service.MarketOwnerService;
Expand Down Expand Up @@ -29,30 +30,48 @@ public class MarketOwnerController {
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<CommonResponse<MarketResDto>> createMarket(
@RequestPart(value = "jsonData") @Valid MarketCreateReqDto marketCreateReqDto,
@RequestPart(value = "files") List<MultipartFile> multipartFileList) throws IOException {
@RequestPart(value = "images") List<MultipartFile> multipartFileList) throws IOException {
return ResponseEntity
.status(MARKET_CREATE.getStatus())
.body(CommonResponse.from(MARKET_CREATE.getMessage(),marketOwnerService.createMarket(marketCreateReqDto,multipartFileList)));
.body(CommonResponse.from(MARKET_CREATE.getMessage()
,marketOwnerService.createMarket(marketCreateReqDto,multipartFileList)));
}

@Operation(summary = "사장님 매장 정보 수정", description = "사장님이 생성한 매장 정보를 수정합니다.")
@PutMapping("/{marketId}")
public ResponseEntity<CommonResponse<MarketResDto>> updateMarket(@RequestBody @Valid MarketUpdateReqDto marketUpdateReqDto,
@PathVariable Long marketId) {
return ResponseEntity.ok(CommonResponse.from(MARKET_UPDATE.getMessage(),marketOwnerService.updateMarket(marketUpdateReqDto,marketId)));
public ResponseEntity<CommonResponse<MarketResDto>> updateMarket(
@RequestBody @Valid MarketUpdateReqDto marketUpdateReqDto, @PathVariable Long marketId) {
return ResponseEntity
.ok(CommonResponse.from(MARKET_UPDATE.getMessage()
,marketOwnerService.updateMarket(marketId, marketUpdateReqDto)));
}

@Operation(summary = "사장님 매장 이미지 수정", description = "매장의 이미지를 추가,삭제 및 순서 변경을 합니다. <br>" +
"jsonData는 삭제할 이미지 id 리스트, 순서 변경할 Map<이미지id,순서order>, 추가할 이미지의 순서 리스트입니다. <br>" +
"images는 추가할 이미지 리스트입니다. 기존 이미지는 안주셔도 됩니다.")
@PutMapping("/images")
public ResponseEntity<CommonResponse<MarketResDto>> updateMarket(
@RequestPart(value = "jsonData") MarketImageUpdateReqDto marketImageUpdateReqDto,
@RequestPart(value = "images") List<MultipartFile> multipartFileList,
@RequestParam(name = "marketId") Long marketId) throws IOException {
return ResponseEntity
.ok(CommonResponse.from(MARKET_IMAGE_UPDATE.getMessage()
,marketOwnerService.updateMarketImage(marketId, marketImageUpdateReqDto,multipartFileList)));
}

@Operation(summary = "사장님 매장 조회", description = "사장님이 생성한 매장 정보를 조회합니다.")
@GetMapping("/{marketId}")
public ResponseEntity<CommonResponse<MarketResDto>> getMarket(@PathVariable Long marketId){
return ResponseEntity.ok(CommonResponse.from(MARKET_FOUND.getMessage(),marketOwnerService.getMarket(marketId)));
return ResponseEntity
.ok(CommonResponse.from(MARKET_FOUND.getMessage(),marketOwnerService.getMarket(marketId)));
}

@Operation(summary = "사장님 매장 삭제", description = "사장님이 생성한 매장을 삭제합니다. ")
@DeleteMapping("/{marketId}")
public ResponseEntity<CommonResponse<Object>> deleteMarket(@PathVariable Long marketId){
marketOwnerService.deleteMarket(marketId);
return ResponseEntity.ok(CommonResponse.from(MARKET_DELETE.getMessage()));
return ResponseEntity
.ok(CommonResponse.from(MARKET_DELETE.getMessage()));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.appcenter.marketplace.domain.market.dto.req;

import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.Map;

@Getter
@NoArgsConstructor
public class MarketImageUpdateReqDto {
private List<Long> deletedImageIds; // 삭제할 이미지 ID 리스트
private Map<Long, Integer> changedOrders; // 변경된 순서 (id와 Order를 Map으로 처리)
private List<Integer> addedImageOrders; // 추가된 이미지의 순서 리스트 (순서 번호)

}
Loading

0 comments on commit 447b5e6

Please sign in to comment.