From 75bd90c150f2992669f17d3be2f81993ab993def Mon Sep 17 00:00:00 2001 From: dradnats1012 Date: Mon, 18 Nov 2024 03:13:57 +0900 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20=EC=97=91=EC=85=80=20=EB=8B=A4?= =?UTF-8?q?=EC=9A=B4=EB=A1=9C=EB=93=9C=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../koin/domain/coop/service/CoopService.java | 176 +++++++++--------- 1 file changed, 86 insertions(+), 90 deletions(-) diff --git a/src/main/java/in/koreatech/koin/domain/coop/service/CoopService.java b/src/main/java/in/koreatech/koin/domain/coop/service/CoopService.java index ee3daac70..8b1ed794c 100644 --- a/src/main/java/in/koreatech/koin/domain/coop/service/CoopService.java +++ b/src/main/java/in/koreatech/koin/domain/coop/service/CoopService.java @@ -10,6 +10,7 @@ import java.util.List; import java.util.Optional; import java.util.UUID; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import org.apache.poi.ss.usermodel.Cell; @@ -22,8 +23,6 @@ import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.VerticalAlignment; import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.streaming.SXSSFCell; -import org.apache.poi.xssf.streaming.SXSSFRow; import org.apache.poi.xssf.streaming.SXSSFSheet; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.springframework.context.ApplicationEventPublisher; @@ -51,6 +50,7 @@ import in.koreatech.koin.domain.user.model.UserToken; import in.koreatech.koin.domain.user.repository.UserTokenRepository; import in.koreatech.koin.global.auth.JwtProvider; +import in.koreatech.koin.global.concurrent.ConcurrencyGuard; import in.koreatech.koin.global.exception.KoinIllegalArgumentException; import lombok.RequiredArgsConstructor; @@ -119,125 +119,121 @@ public CoopLoginResponse coopLogin(CoopLoginRequest request) { return CoopLoginResponse.of(accessToken, savedToken.getRefreshToken()); } + @ConcurrencyGuard(lockName = "excelDownload", waitTime = 1, leaseTime = 5000, timeUnit = TimeUnit.MILLISECONDS) public ByteArrayInputStream generateDiningExcel(LocalDate startDate, LocalDate endDate, Boolean isCafeteria) { - checkDate(startDate, endDate); - - List dinings; - - if (isCafeteria) { - List placeFilters = Arrays.asList("A코너", "B코너", "C코너"); - dinings = diningRepository.findByDateBetweenAndPlaceIn(startDate, endDate, placeFilters); - } else { - dinings = diningRepository.findByDateBetween(startDate, endDate); - } - + validateDates(startDate, endDate); + List dinings = fetchDiningData(startDate, endDate, isCafeteria); + System.out.println(startDate + " " + endDate); try (SXSSFWorkbook workbook = new SXSSFWorkbook()) { - SXSSFSheet sheet = workbook.createSheet("식단 메뉴"); - sheet.setRandomAccessWindowSize(100); - - CellStyle headerStyle = makeHeaderStyle(workbook); - CellStyle commonStyle = makeCommonStyle(workbook); - createHeaderCell(sheet, headerStyle); - - ByteArrayInputStream result = putDiningData(dinings, sheet, commonStyle, workbook); + SXSSFSheet sheet = createSheet(workbook, "식단 메뉴"); + CellStyle headerStyle = createHeaderStyle(workbook); + CellStyle commonStyle = createCommonStyle(workbook); - return result; + addHeaderRow(sheet, headerStyle); + addDiningDataToSheet(dinings, sheet, commonStyle); + return writeWorkbookToStream(workbook); } catch (IOException e) { throw new RuntimeException("엑셀 파일 생성 중 오류가 발생했습니다.", e); } } - private static void checkDate(LocalDate startDate, LocalDate endDate) { + private void validateDates(LocalDate startDate, LocalDate endDate) { LocalDate limitDate = LocalDate.of(2022, 11, 29); + LocalDate today = LocalDate.now(); + if (startDate.isBefore(limitDate) || endDate.isBefore(limitDate)) { throw new DiningLimitDateException("2022/11/29 식단부터 다운받을 수 있어요."); } - - LocalDate now = LocalDate.now(); - if (startDate.isAfter(now) || endDate.isAfter(now)) { + if (startDate.isAfter(today) || endDate.isAfter(today)) { throw new DiningNowDateException("오늘 날짜 이후 기간은 설정할 수 없어요."); } - if (startDate.isAfter(endDate)) { - throw new StartDateAfterEndDateException("시작일은 종료일 이전으로 설정해주세요."); + throw new StartDateAfterEndDateException("시작일은 종료일 이전으로 설정해주세요"); } } - private ByteArrayInputStream putDiningData(List dinings, SXSSFSheet sheet, CellStyle commonStyle, - SXSSFWorkbook workbook) throws IOException { - AtomicInteger rowIdx = new AtomicInteger(1); + private List fetchDiningData(LocalDate startDate, LocalDate endDate, Boolean isCafeteria) { + if (isCafeteria) { + List cafeteriaPlaces = Arrays.asList("A코너", "B코너", "C코너"); + return diningRepository.findByDateBetweenAndPlaceIn(startDate, endDate, cafeteriaPlaces); + } + return diningRepository.findByDateBetween(startDate, endDate); + } + private SXSSFSheet createSheet(SXSSFWorkbook workbook, String sheetName) { + SXSSFSheet sheet = workbook.createSheet(sheetName); + sheet.setRandomAccessWindowSize(100); + return sheet; + } + + private CellStyle createHeaderStyle(Workbook workbook) { + CellStyle style = workbook.createCellStyle(); + Font font = workbook.createFont(); + font.setBold(true); + font.setColor(IndexedColors.WHITE.getIndex()); + style.setFont(font); + style.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex()); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + style.setAlignment(HorizontalAlignment.CENTER); + return style; + } + + private CellStyle createCommonStyle(Workbook workbook) { + CellStyle style = workbook.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setWrapText(true); + return style; + } + + private void addHeaderRow(Sheet sheet, CellStyle headerStyle) { + String[] headers = {"날짜", "타입", "코너", "칼로", "메뉴", "이미지", "품절 여부", "변경 여부"}; + Row headerRow = sheet.createRow(0); + + for (int i = 0; i < headers.length; i++) { + Cell cell = headerRow.createCell(i); + cell.setCellValue(headers[i]); + cell.setCellStyle(headerStyle); + } + } + + private void addDiningDataToSheet(List dinings, SXSSFSheet sheet, CellStyle commonStyle) { + AtomicInteger rowIndex = new AtomicInteger(1); dinings.forEach(dining -> { - SXSSFRow row = sheet.createRow(rowIdx.getAndIncrement()); - row.createCell(0).setCellValue(dining.getDate().toString()); - row.createCell(1).setCellValue(dining.getType().getDiningName()); - row.createCell(2).setCellValue(dining.getPlace()); - row.createCell(3).setCellValue(dining.getKcal() != null ? dining.getKcal() : 0); - - String formattedMenu = dining.getMenu().toString() - .replaceAll("^\\[|\\]$", "") - .replaceAll(", ", "\n"); - - SXSSFCell menuCell = row.createCell(4); - menuCell.setCellValue(formattedMenu); - - row.createCell(5).setCellValue(dining.getImageUrl()); - row.createCell(6).setCellValue( - Optional.ofNullable(dining.getSoldOut()).map(Object::toString).orElse("") - ); - row.createCell(7).setCellValue(Optional.ofNullable(dining.getIsChanged()).map(Object::toString).orElse("")); - - for (int i = 0; i < EXCEL_COLUMN_COUNT; i++) { - row.getCell(i).setCellStyle(commonStyle); - } + Row row = sheet.createRow(rowIndex.getAndIncrement()); + fillDiningRow(dining, row, commonStyle); }); - for (int i = 0; i < EXCEL_COLUMN_COUNT; i++) { + for (int i = 0; i < 8; i++) { sheet.setColumnWidth(i, 6000); } - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - workbook.write(out); - workbook.close(); - workbook.dispose(); - return new ByteArrayInputStream(out.toByteArray()); } - private void createHeaderCell(Sheet sheet, CellStyle headerStyle) { - Row headerRow = sheet.createRow(0); - headerRow.createCell(0).setCellValue("날짜"); - headerRow.createCell(1).setCellValue("타입"); - headerRow.createCell(2).setCellValue("코너"); - headerRow.createCell(3).setCellValue("칼로리"); - headerRow.createCell(4).setCellValue("메뉴"); - headerRow.createCell(5).setCellValue("이미지"); - headerRow.createCell(6).setCellValue("품절 여부"); - headerRow.createCell(7).setCellValue("변경 여부"); - - for (int i = 0; i < EXCEL_COLUMN_COUNT; i++) { - Cell cell = headerRow.getCell(i); - cell.setCellStyle(headerStyle); + private void fillDiningRow(Dining dining, Row row, CellStyle commonStyle) { + row.createCell(0).setCellValue(dining.getDate().toString()); + row.createCell(1).setCellValue(dining.getType().getDiningName()); + row.createCell(2).setCellValue(dining.getPlace()); + row.createCell(3).setCellValue(Optional.ofNullable(dining.getKcal()).orElse(0)); + row.createCell(4).setCellValue(formatMenu(dining.getMenu())); + row.createCell(5).setCellValue(dining.getImageUrl()); + row.createCell(6).setCellValue(Optional.ofNullable(dining.getSoldOut()).map(Object::toString).orElse("")); + row.createCell(7).setCellValue(Optional.ofNullable(dining.getIsChanged()).map(Object::toString).orElse("")); + + for (int i = 0; i < 8; i++) { + row.getCell(i).setCellStyle(commonStyle); } } - private static CellStyle makeCommonStyle(Workbook workbook) { - CellStyle commonStyle = workbook.createCellStyle(); - commonStyle.setAlignment(HorizontalAlignment.CENTER); - commonStyle.setVerticalAlignment(VerticalAlignment.CENTER); - commonStyle.setWrapText(true); - return commonStyle; + private String formatMenu(List menu) { + return String.join("\n", menu); } - private static CellStyle makeHeaderStyle(Workbook workbook) { - CellStyle headerStyle = workbook.createCellStyle(); - Font font = workbook.createFont(); - font.setBold(true); - font.setColor(IndexedColors.WHITE.getIndex()); - headerStyle.setFont(font); - headerStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex()); - headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); - headerStyle.setAlignment(HorizontalAlignment.CENTER); - return headerStyle; + private ByteArrayInputStream writeWorkbookToStream(SXSSFWorkbook workbook) throws IOException { + try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { + workbook.write(out); + workbook.dispose(); + return new ByteArrayInputStream(out.toByteArray()); + } } } From 1971ecb480f45c731a354162d8c1640a03eda4b2 Mon Sep 17 00:00:00 2001 From: dradnats1012 Date: Mon, 18 Nov 2024 14:32:08 +0900 Subject: [PATCH 2/5] =?UTF-8?q?feat:=20=EC=97=91=EC=85=80=20=EB=8B=A4?= =?UTF-8?q?=EC=9A=B4=EB=A1=9C=EB=93=9C=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../in/koreatech/koin/domain/coop/service/CoopService.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/in/koreatech/koin/domain/coop/service/CoopService.java b/src/main/java/in/koreatech/koin/domain/coop/service/CoopService.java index 8b1ed794c..01775e21d 100644 --- a/src/main/java/in/koreatech/koin/domain/coop/service/CoopService.java +++ b/src/main/java/in/koreatech/koin/domain/coop/service/CoopService.java @@ -69,8 +69,6 @@ public class CoopService { private final PasswordEncoder passwordEncoder; private final JwtProvider jwtProvider; - private final int EXCEL_COLUMN_COUNT = 8; - @Transactional public void changeSoldOut(SoldOutRequest soldOutRequest) { Dining dining = diningRepository.getById(soldOutRequest.menuId()); @@ -123,7 +121,7 @@ public CoopLoginResponse coopLogin(CoopLoginRequest request) { public ByteArrayInputStream generateDiningExcel(LocalDate startDate, LocalDate endDate, Boolean isCafeteria) { validateDates(startDate, endDate); List dinings = fetchDiningData(startDate, endDate, isCafeteria); - System.out.println(startDate + " " + endDate); + try (SXSSFWorkbook workbook = new SXSSFWorkbook()) { SXSSFSheet sheet = createSheet(workbook, "식단 메뉴"); CellStyle headerStyle = createHeaderStyle(workbook); From 16a772ac6822134bfe22b5a37ccfaacdd7cca16f Mon Sep 17 00:00:00 2001 From: dradnats1012 Date: Mon, 18 Nov 2024 15:14:34 +0900 Subject: [PATCH 3/5] =?UTF-8?q?refactor:=20=EB=8F=99=EC=8B=9C=EC=84=B1=20?= =?UTF-8?q?=EC=A0=9C=EC=96=B4=20=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../in/koreatech/koin/domain/coop/service/CoopService.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/in/koreatech/koin/domain/coop/service/CoopService.java b/src/main/java/in/koreatech/koin/domain/coop/service/CoopService.java index 01775e21d..bb27d7b9d 100644 --- a/src/main/java/in/koreatech/koin/domain/coop/service/CoopService.java +++ b/src/main/java/in/koreatech/koin/domain/coop/service/CoopService.java @@ -10,7 +10,6 @@ import java.util.List; import java.util.Optional; import java.util.UUID; -import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import org.apache.poi.ss.usermodel.Cell; @@ -50,7 +49,6 @@ import in.koreatech.koin.domain.user.model.UserToken; import in.koreatech.koin.domain.user.repository.UserTokenRepository; import in.koreatech.koin.global.auth.JwtProvider; -import in.koreatech.koin.global.concurrent.ConcurrencyGuard; import in.koreatech.koin.global.exception.KoinIllegalArgumentException; import lombok.RequiredArgsConstructor; @@ -117,7 +115,6 @@ public CoopLoginResponse coopLogin(CoopLoginRequest request) { return CoopLoginResponse.of(accessToken, savedToken.getRefreshToken()); } - @ConcurrencyGuard(lockName = "excelDownload", waitTime = 1, leaseTime = 5000, timeUnit = TimeUnit.MILLISECONDS) public ByteArrayInputStream generateDiningExcel(LocalDate startDate, LocalDate endDate, Boolean isCafeteria) { validateDates(startDate, endDate); List dinings = fetchDiningData(startDate, endDate, isCafeteria); From da3b8c72f8bb7126d73285c56fad22e3edce291f Mon Sep 17 00:00:00 2001 From: dradnats1012 Date: Wed, 11 Dec 2024 13:58:41 +0900 Subject: [PATCH 4/5] =?UTF-8?q?fix:=20=EB=A6=AC=EB=B7=B0=20=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../koin/domain/coop/service/CoopService.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/in/koreatech/koin/domain/coop/service/CoopService.java b/src/main/java/in/koreatech/koin/domain/coop/service/CoopService.java index bb27d7b9d..9fccc2c51 100644 --- a/src/main/java/in/koreatech/koin/domain/coop/service/CoopService.java +++ b/src/main/java/in/koreatech/koin/domain/coop/service/CoopService.java @@ -67,6 +67,9 @@ public class CoopService { private final PasswordEncoder passwordEncoder; private final JwtProvider jwtProvider; + public static final LocalDate LIMIT_DATE = LocalDate.of(2022, 11, 29); + private final int EXCEL_COLUMN_COUNT = 8; + @Transactional public void changeSoldOut(SoldOutRequest soldOutRequest) { Dining dining = diningRepository.getById(soldOutRequest.menuId()); @@ -134,17 +137,17 @@ public ByteArrayInputStream generateDiningExcel(LocalDate startDate, LocalDate e } private void validateDates(LocalDate startDate, LocalDate endDate) { - LocalDate limitDate = LocalDate.of(2022, 11, 29); + //LocalDate limitDate = LocalDate.of(2022, 11, 29); LocalDate today = LocalDate.now(); - if (startDate.isBefore(limitDate) || endDate.isBefore(limitDate)) { + if (startDate.isBefore(LIMIT_DATE) || endDate.isBefore(LIMIT_DATE)) { throw new DiningLimitDateException("2022/11/29 식단부터 다운받을 수 있어요."); } if (startDate.isAfter(today) || endDate.isAfter(today)) { throw new DiningNowDateException("오늘 날짜 이후 기간은 설정할 수 없어요."); } if (startDate.isAfter(endDate)) { - throw new StartDateAfterEndDateException("시작일은 종료일 이전으로 설정해주세요"); + throw new StartDateAfterEndDateException("시작일은 종료일 이전으로 설정해주세요."); } } @@ -183,7 +186,7 @@ private CellStyle createCommonStyle(Workbook workbook) { } private void addHeaderRow(Sheet sheet, CellStyle headerStyle) { - String[] headers = {"날짜", "타입", "코너", "칼로", "메뉴", "이미지", "품절 여부", "변경 여부"}; + String[] headers = {"날짜", "타입", "코너", "칼로리", "메뉴", "이미지", "품절 여부", "변경 여부"}; Row headerRow = sheet.createRow(0); for (int i = 0; i < headers.length; i++) { @@ -200,7 +203,7 @@ private void addDiningDataToSheet(List dinings, SXSSFSheet sheet, CellSt fillDiningRow(dining, row, commonStyle); }); - for (int i = 0; i < 8; i++) { + for (int i = 0; i < EXCEL_COLUMN_COUNT; i++) { sheet.setColumnWidth(i, 6000); } } From c50813889d69ade7e2628e304808a2fb2434faa9 Mon Sep 17 00:00:00 2001 From: dradnats1012 Date: Wed, 11 Dec 2024 14:11:25 +0900 Subject: [PATCH 5/5] =?UTF-8?q?fix:=20=EC=A3=BC=EC=84=9D=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/in/koreatech/koin/domain/coop/service/CoopService.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/in/koreatech/koin/domain/coop/service/CoopService.java b/src/main/java/in/koreatech/koin/domain/coop/service/CoopService.java index 9fccc2c51..9e72a3b09 100644 --- a/src/main/java/in/koreatech/koin/domain/coop/service/CoopService.java +++ b/src/main/java/in/koreatech/koin/domain/coop/service/CoopService.java @@ -137,7 +137,6 @@ public ByteArrayInputStream generateDiningExcel(LocalDate startDate, LocalDate e } private void validateDates(LocalDate startDate, LocalDate endDate) { - //LocalDate limitDate = LocalDate.of(2022, 11, 29); LocalDate today = LocalDate.now(); if (startDate.isBefore(LIMIT_DATE) || endDate.isBefore(LIMIT_DATE)) {