diff --git a/pom.xml b/pom.xml index 5182e6e..618d5eb 100644 --- a/pom.xml +++ b/pom.xml @@ -222,6 +222,13 @@ 4.5.13 + + com.jcraft + jsch + 0.1.55 + + + diff --git a/src/main/java/com/mixi/common/tasks/MiTuExportScheduledTask.java b/src/main/java/com/mixi/common/tasks/MiTuExportScheduledTask.java index ba6274a..c8abd93 100644 --- a/src/main/java/com/mixi/common/tasks/MiTuExportScheduledTask.java +++ b/src/main/java/com/mixi/common/tasks/MiTuExportScheduledTask.java @@ -2,6 +2,7 @@ package com.mixi.common.tasks; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.jcraft.jsch.*; import com.mixi.common.tasks.mituExportEntity.*; import com.mixi.common.utils.CopyUtil; import com.mixi.common.utils.MinioUtil; @@ -96,6 +97,7 @@ public class MiTuExportScheduledTask { private TProductStockService tProductStockService; // 更新商品库存 + @Scheduled(cron = "0 * * * * ?") private void updateProductStock() { log.info(String.valueOf(LocalDateTime.now())); @@ -183,7 +185,7 @@ public class MiTuExportScheduledTask { // bestSellIsNotNull.lambda().isNotNull(TProduct::getBestSell); List productListAll = productMapper.selectList(bestSellIsNotNull); LocalDate today = LocalDate.now(); - for (int i = 0; i < 30; i++) { + for (int i = 0; i < 1; i++) { // 将这一天的商品销售数量入库 miTuProductSellNumEntry(today, productListAll); today = today.minusDays(1); @@ -634,7 +636,7 @@ public class MiTuExportScheduledTask { } } - private void exportWeeklySellThrReport(List transactionSummaryList, String filePathName) throws IOException { + private void exportWeeklySellThrReport(List transactionSummaryList, String filePathName) throws IOException, JSchException { String currentPath = Paths.get("").toAbsolutePath().toString(); File file = new File(currentPath + "/" + filePathName); Workbook workbook = new XSSFWorkbook(); @@ -654,56 +656,89 @@ public class MiTuExportScheduledTask { String previousPluCode = ""; String imagePath = ""; - for (TransactionSummary summary : transactionSummaryList) { - if (!summary.getPLU_CODE().equals(previousPluCode)) { - if (startRow < rowNum) { - mergeCells(sheet, startRow, rowNum - 1); - linkImageToCell(workbook, sheet, startRow, rowNum - 1, headers.length - 1, imagePath); + Session session = null; + ChannelSftp channelSftp = null; + + try { + // 配置JSch并连接SFTP服务器 + JSch jsch = new JSch(); + session = jsch.getSession("aiuser", "haymanRCCnas.synology.me", 19322); + session.setPassword("hayNAS-0522"); + java.util.Properties config = new java.util.Properties(); + config.put("StrictHostKeyChecking", "no"); + session.setConfig(config); + session.connect(); + + channelSftp = (ChannelSftp) session.openChannel("sftp"); + channelSftp.connect(); + + for (TransactionSummary summary : transactionSummaryList) { + String currentPluCode = summary.getPLU_CODE(); + if (!currentPluCode.equals(previousPluCode)) { + imagePath = getImagePath(summary.getPLU_CODE()); + + // 判断 imagePath 是否为空 + if (imagePath != null && !imagePath.isEmpty()) { + if (startRow < rowNum) { + mergeCells(sheet, startRow, rowNum - 1); + linkImageToCell(workbook, sheet, startRow, rowNum - 1, headers.length - 1, imagePath, channelSftp); + } + } else { + System.out.println("Image path is empty for PLU_CODE: " + currentPluCode); + // 在这里可以添加其他处理逻辑,例如记录日志或使用默认图片 + } + + startRow = rowNum; + previousPluCode = currentPluCode; } - startRow = rowNum; - previousPluCode = summary.getPLU_CODE(); - imagePath = getImagePath(summary.getPLU_CODE()); + + Row row = sheet.createRow(rowNum); + row.createCell(0).setCellValue(summary.getPLU_CODE()); + // 填充其他列的数据 + row.createCell(1).setCellValue(summary.getToShopDate() != null ? summary.getToShopDate().toString() : ""); + row.createCell(2).setCellValue(summary.getSalesDay()); + row.createCell(3).setCellValue(summary.getCATEGORY()); + row.createCell(4).setCellValue(summary.getSUB_CAT()); + row.createCell(5).setCellValue(summary.getItemName()); + row.createCell(6).setCellValue(summary.getPriceOriginal()); + row.createCell(7).setCellValue(summary.getToRetailQty()); + row.createCell(8).setCellValue(summary.getTotalSaleNum()); + row.createCell(9).setCellValue(summary.getMAS_count()); + row.createCell(10).setCellValue(summary.getMEL_count()); + row.createCell(11).setCellValue(summary.getMPC_count()); + row.createCell(12).setCellValue(summary.getMPS_count()); + row.createCell(13).setCellValue(summary.getMTF_count()); + row.createCell(14).setCellValue(summary.getMWP_count()); + row.createCell(15).setCellValue(summary.getMYO_count()); + row.createCell(16).setCellValue(summary.getLwSalesQty()); + row.createCell(17).setCellValue(summary.getRetailOnHand()); + row.createCell(18).setCellValue(summary.getSalesRate()); + + rowNum++; } - Row row = sheet.createRow(rowNum); - row.createCell(0).setCellValue(summary.getPLU_CODE()); - // 填充其他列的数据 - row.createCell(1).setCellValue(summary.getToShopDate() != null ? summary.getToShopDate().toString() : ""); - row.createCell(2).setCellValue(summary.getSalesDay()); - row.createCell(3).setCellValue(summary.getCATEGORY()); - row.createCell(4).setCellValue(summary.getSUB_CAT()); - row.createCell(5).setCellValue(summary.getItemName()); - row.createCell(6).setCellValue(summary.getPriceOriginal()); - row.createCell(7).setCellValue(summary.getToRetailQty()); - row.createCell(8).setCellValue(summary.getTotalSaleNum()); - row.createCell(9).setCellValue(summary.getMAS_count()); - row.createCell(10).setCellValue(summary.getMEL_count()); - row.createCell(11).setCellValue(summary.getMPC_count()); - row.createCell(12).setCellValue(summary.getMPS_count()); - row.createCell(13).setCellValue(summary.getMTF_count()); - row.createCell(14).setCellValue(summary.getMWP_count()); - row.createCell(15).setCellValue(summary.getMYO_count()); - row.createCell(16).setCellValue(summary.getLwSalesQty()); - row.createCell(17).setCellValue(summary.getRetailOnHand()); - row.createCell(18).setCellValue(summary.getSalesRate()); + // 处理最后一个PLU_CODE的数据 + if (startRow < rowNum) { + mergeCells(sheet, startRow, rowNum - 1); + linkImageToCell(workbook, sheet, startRow, rowNum - 1, headers.length - 1, imagePath, channelSftp); + } - rowNum++; + try (FileOutputStream outputStream = new FileOutputStream(file)) { + workbook.write(outputStream); + } + + FileItem a = getMultipartFile(file, file.getName()); + MultipartFile multipartFile = new CommonsMultipartFile(a); + minioUtil.upload("mi-tu", "export", multipartFile); + + } finally { + if (channelSftp != null && channelSftp.isConnected()) { + channelSftp.disconnect(); + } + if (session != null && session.isConnected()) { + session.disconnect(); + } } - - // 处理最后一个PLU_CODE的数据 - if (startRow < rowNum) { - mergeCells(sheet, startRow, rowNum - 1); - linkImageToCell(workbook, sheet, startRow, rowNum - 1, headers.length - 1, imagePath); - } - - - try (FileOutputStream outputStream = new FileOutputStream(file)) { - workbook.write(outputStream); - } - - FileItem a = getMultipartFile(file, file.getName()); - MultipartFile multipartFile = new CommonsMultipartFile(a); - minioUtil.upload("mi-tu", "export", multipartFile); } @@ -748,46 +783,77 @@ public class MiTuExportScheduledTask { String previousPluCode = ""; String imagePath = ""; - for (WeeklyHeavyStock weeklyHeavyStock : weeklyHeavyStockList) { - if (!weeklyHeavyStock.getPLU_CODE().equals(previousPluCode)) { - if (startRow < rowNum - 1) { - mergeCells(sheet, startRow, rowNum - 1); - linkImageToCell(workbook, sheet, startRow, rowNum - 1, headers.length - 1, imagePath); + // 创建并配置SFTP连接 + Session session = null; + ChannelSftp channelSftp = null; + try { + JSch jsch = new JSch(); + session = jsch.getSession("aiuser", "haymanRCCnas.synology.me", 19322); + session.setPassword("hayNAS-0522"); + java.util.Properties config = new java.util.Properties(); + config.put("StrictHostKeyChecking", "no"); + session.setConfig(config); + session.connect(); + + channelSftp = (ChannelSftp) session.openChannel("sftp"); + channelSftp.connect(); + + for (WeeklyHeavyStock weeklyHeavyStock : weeklyHeavyStockList) { + String currentPluCode = weeklyHeavyStock.getPLU_CODE(); + if (!currentPluCode.equals(previousPluCode)) { + if (startRow < rowNum - 1) { + mergeCells(sheet, startRow, rowNum - 1); + if (imagePath != null && !imagePath.isEmpty()) { + linkImageToCell(workbook, sheet, startRow, rowNum - 1, headers.length - 1, imagePath, channelSftp); + } + } + startRow = rowNum; + previousPluCode = currentPluCode; + imagePath = getImagePath(currentPluCode); } - startRow = rowNum; - previousPluCode = weeklyHeavyStock.getPLU_CODE(); - imagePath = getImagePath(weeklyHeavyStock.getPLU_CODE()); + + Row row = sheet.createRow(rowNum); + row.createCell(0).setCellValue(weeklyHeavyStock.getPLU_CODE()); + // 填充其他列的数据 + row.createCell(1).setCellValue(weeklyHeavyStock.getItem_name()); + row.createCell(2).setCellValue(weeklyHeavyStock.getItem_barcode()); + row.createCell(3).setCellValue(weeklyHeavyStock.getCat()); + row.createCell(4).setCellValue(weeklyHeavyStock.getSub_cat()); + row.createCell(5).setCellValue(weeklyHeavyStock.getCol()); + row.createCell(6).setCellValue(weeklyHeavyStock.getPrice_sales()); + row.createCell(7).setCellValue(weeklyHeavyStock.getMAS()); + row.createCell(8).setCellValue(weeklyHeavyStock.getMEL()); + row.createCell(9).setCellValue(weeklyHeavyStock.getMPC()); + row.createCell(10).setCellValue(weeklyHeavyStock.getMPS()); + row.createCell(11).setCellValue(weeklyHeavyStock.getMTF()); + row.createCell(12).setCellValue(weeklyHeavyStock.getMWP()); + row.createCell(13).setCellValue(weeklyHeavyStock.getMYO()); + row.createCell(14).setCellValue(weeklyHeavyStock.getMHZ()); + row.createCell(15).setCellValue(weeklyHeavyStock.getMRT()); + row.createCell(16).setCellValue(weeklyHeavyStock.getMBZ()); + row.createCell(17).setCellValue(weeklyHeavyStock.getTLT()); + row.createCell(18).setCellValue(weeklyHeavyStock.getSubtotal()); + row.createCell(19).setCellValue(weeklyHeavyStock.getG_TLT()); + + rowNum++; } - Row row = sheet.createRow(rowNum); - row.createCell(0).setCellValue(weeklyHeavyStock.getPLU_CODE()); - // 填充其他列的数据 - row.createCell(1).setCellValue(weeklyHeavyStock.getItem_name()); - row.createCell(2).setCellValue(weeklyHeavyStock.getItem_barcode()); - row.createCell(3).setCellValue(weeklyHeavyStock.getCat()); - row.createCell(4).setCellValue(weeklyHeavyStock.getSub_cat()); - row.createCell(5).setCellValue(weeklyHeavyStock.getCol()); - row.createCell(6).setCellValue(weeklyHeavyStock.getPrice_sales()); - row.createCell(7).setCellValue(weeklyHeavyStock.getMAS()); - row.createCell(8).setCellValue(weeklyHeavyStock.getMEL()); - row.createCell(9).setCellValue(weeklyHeavyStock.getMPC()); - row.createCell(10).setCellValue(weeklyHeavyStock.getMPS()); - row.createCell(11).setCellValue(weeklyHeavyStock.getMTF()); - row.createCell(12).setCellValue(weeklyHeavyStock.getMWP()); - row.createCell(13).setCellValue(weeklyHeavyStock.getMYO()); - row.createCell(14).setCellValue(weeklyHeavyStock.getMHZ()); - row.createCell(15).setCellValue(weeklyHeavyStock.getMRT()); - row.createCell(16).setCellValue(weeklyHeavyStock.getMBZ()); - row.createCell(17).setCellValue(weeklyHeavyStock.getTLT()); - row.createCell(18).setCellValue(weeklyHeavyStock.getSubtotal()); - row.createCell(19).setCellValue(weeklyHeavyStock.getG_TLT()); + if (startRow < rowNum - 1) { + mergeCells(sheet, startRow, rowNum - 1); + if (imagePath != null && !imagePath.isEmpty()) { + linkImageToCell(workbook, sheet, startRow, rowNum - 1, headers.length - 1, imagePath, channelSftp); + } + } - rowNum++; - } - - if (startRow < rowNum - 1 || previousPluCode != null) { - mergeCells(sheet, startRow, rowNum - 1); - linkImageToCell(workbook, sheet, startRow, rowNum - 1, headers.length - 1, imagePath); + } catch (Exception e) { + throw new RuntimeException("Error while processing the report", e); + } finally { + if (channelSftp != null && channelSftp.isConnected()) { + channelSftp.disconnect(); + } + if (session != null && session.isConnected()) { + session.disconnect(); + } } try (FileOutputStream outputStream = new FileOutputStream(file)) { @@ -801,6 +867,7 @@ public class MiTuExportScheduledTask { + /** * Quarterly Product Grouping Report */ @@ -876,80 +943,104 @@ public class MiTuExportScheduledTask { headerRow.createCell(i).setCellValue(headers[i]); } -// // 自动调整除Image列外的其他列宽度 -// for (int i = 1; i < headers.length; i++) { -// sheet.autoSizeColumn(i); -// } - - // 写入数据和插入图片 int rowNum = 3; // 数据从第四行开始 int startRow = rowNum; String previousPluCode = ""; String imagePath = ""; - for (WeeklyHeavyStock weeklyHeavyStock : weeklyHeavyStockList) { - if (!weeklyHeavyStock.getPLU_CODE().equals(previousPluCode)) { - // 新的PLU_CODE,合并之前的单元格,并插入图片 - if (startRow < rowNum - 1) { - mergeCells(sheet, startRow, rowNum - 1); - linkImageToCell(workbook, sheet, startRow, rowNum - 1, 0, imagePath); // 插入图片到合并单元格 + // 创建并配置SFTP连接 + Session session = null; + ChannelSftp channelSftp = null; + try { + JSch jsch = new JSch(); + session = jsch.getSession("aiuser", "haymanRCCnas.synology.me", 19322); + session.setPassword("hayNAS-0522"); + java.util.Properties config = new java.util.Properties(); + config.put("StrictHostKeyChecking", "no"); + session.setConfig(config); + session.connect(); + + channelSftp = (ChannelSftp) session.openChannel("sftp"); + channelSftp.connect(); + + for (WeeklyHeavyStock weeklyHeavyStock : weeklyHeavyStockList) { + if (!weeklyHeavyStock.getPLU_CODE().equals(previousPluCode)) { + imagePath = getImagePath(weeklyHeavyStock.getPLU_CODE()); + // 新的PLU_CODE,合并之前的单元格,并插入图片 + if (startRow < rowNum - 1) { + mergeCells(sheet, startRow, rowNum - 1); + if (imagePath != null && !imagePath.isEmpty()) { + linkImageToCell(workbook, sheet, startRow, rowNum - 1, 0, imagePath, channelSftp); // 插入图片到合并单元格 + } + } + startRow = rowNum; + previousPluCode = weeklyHeavyStock.getPLU_CODE(); } - startRow = rowNum; - previousPluCode = weeklyHeavyStock.getPLU_CODE(); - imagePath = getImagePath(weeklyHeavyStock.getPLU_CODE()); + + // 计算“Shop total Sold” + int shopTotalSold = weeklyHeavyStock.getMASSOLD() + weeklyHeavyStock.getMELSOLD() + + weeklyHeavyStock.getMPCSOLD() + weeklyHeavyStock.getMPSSOLD() + + weeklyHeavyStock.getMTFSOLD() + weeklyHeavyStock.getMWPSOLD() + + weeklyHeavyStock.getMYOSOLD(); + + // 计算“HK Sell-thru” + int stockOnHand = weeklyHeavyStock.getMAS() + weeklyHeavyStock.getMEL() + + weeklyHeavyStock.getMPC() + weeklyHeavyStock.getMPS() + + weeklyHeavyStock.getMTF() + weeklyHeavyStock.getMWP() + + weeklyHeavyStock.getMYO() + weeklyHeavyStock.getMRT() + + weeklyHeavyStock.getMBZ() + weeklyHeavyStock.getMHZ(); + + String hkSellThru = stockOnHand > 0 ? String.format("%.0f%%", (double) shopTotalSold / stockOnHand * 100) : "0%"; + + Row row = sheet.createRow(rowNum); + row.createCell(1).setCellValue(weeklyHeavyStock.getPLU_CODE()); + row.createCell(2).setCellValue(weeklyHeavyStock.getCol()); + row.createCell(3).setCellValue(weeklyHeavyStock.getSize()); + row.createCell(4).setCellValue(weeklyHeavyStock.getItem_barcode()); + row.createCell(5).setCellValue(weeklyHeavyStock.getItem_name()); + row.createCell(6).setCellValue(weeklyHeavyStock.getCat()); + row.createCell(7).setCellValue(weeklyHeavyStock.getSub_cat()); + row.createCell(8).setCellValue(weeklyHeavyStock.getPrice_sales()); + row.createCell(9).setCellValue(hkSellThru); // 填入计算的HK Sell-thru + row.createCell(10).setCellValue(shopTotalSold); // 填入计算的Shop total Sold + row.createCell(11).setCellValue(weeklyHeavyStock.getMASSOLD()); + row.createCell(12).setCellValue(weeklyHeavyStock.getMELSOLD()); + row.createCell(13).setCellValue(weeklyHeavyStock.getMPCSOLD()); + row.createCell(14).setCellValue(weeklyHeavyStock.getMPSSOLD()); + row.createCell(15).setCellValue(weeklyHeavyStock.getMTFSOLD()); + row.createCell(16).setCellValue(weeklyHeavyStock.getMWPSOLD()); + row.createCell(17).setCellValue(weeklyHeavyStock.getMYOSOLD()); + row.createCell(18).setCellValue(weeklyHeavyStock.getMAS()); + row.createCell(19).setCellValue(weeklyHeavyStock.getMEL()); + row.createCell(20).setCellValue(weeklyHeavyStock.getMPC()); + row.createCell(21).setCellValue(weeklyHeavyStock.getMPS()); + row.createCell(22).setCellValue(weeklyHeavyStock.getMTF()); + row.createCell(23).setCellValue(weeklyHeavyStock.getMWP()); + row.createCell(24).setCellValue(weeklyHeavyStock.getMYO()); + row.createCell(25).setCellValue(weeklyHeavyStock.getMRT()); + row.createCell(26).setCellValue(weeklyHeavyStock.getMBZ()); + row.createCell(27).setCellValue(weeklyHeavyStock.getMHZ()); + + rowNum++; } - // 计算“Shop total Sold” - int shopTotalSold = weeklyHeavyStock.getMASSOLD() + weeklyHeavyStock.getMELSOLD() + - weeklyHeavyStock.getMPCSOLD() + weeklyHeavyStock.getMPSSOLD() + - weeklyHeavyStock.getMTFSOLD() + weeklyHeavyStock.getMWPSOLD() + - weeklyHeavyStock.getMYOSOLD(); + // 确保处理最后一个Plu Code + if (startRow < rowNum - 1 || previousPluCode != null) { + mergeCells(sheet, startRow, rowNum - 1); + if (imagePath != null && !imagePath.isEmpty()) { + linkImageToCell(workbook, sheet, startRow, rowNum - 1, 0, imagePath, channelSftp); // 插入图片到合并单元格 + } + } - // 计算“HK Sell-thru” - int stockOnHand = weeklyHeavyStock.getMAS() + weeklyHeavyStock.getMEL() + - weeklyHeavyStock.getMPC() + weeklyHeavyStock.getMPS() + - weeklyHeavyStock.getMTF() + weeklyHeavyStock.getMWP() + - weeklyHeavyStock.getMYO() + weeklyHeavyStock.getMRT() + - weeklyHeavyStock.getMBZ() + weeklyHeavyStock.getMHZ(); - - String hkSellThru = stockOnHand > 0 ? String.format("%.0f%%", (double) shopTotalSold / stockOnHand * 100) : "0%"; - - Row row = sheet.createRow(rowNum); - row.createCell(1).setCellValue(weeklyHeavyStock.getPLU_CODE()); - row.createCell(2).setCellValue(weeklyHeavyStock.getCol()); - row.createCell(3).setCellValue(weeklyHeavyStock.getSize()); - row.createCell(4).setCellValue(weeklyHeavyStock.getItem_barcode()); - row.createCell(5).setCellValue(weeklyHeavyStock.getItem_name()); - row.createCell(6).setCellValue(weeklyHeavyStock.getCat()); - row.createCell(7).setCellValue(weeklyHeavyStock.getSub_cat()); - row.createCell(8).setCellValue(weeklyHeavyStock.getPrice_sales()); - row.createCell(9).setCellValue(hkSellThru); // 填入计算的HK Sell-thru - row.createCell(10).setCellValue(shopTotalSold); // 填入计算的Shop total Sold - row.createCell(11).setCellValue(weeklyHeavyStock.getMASSOLD()); - row.createCell(12).setCellValue(weeklyHeavyStock.getMELSOLD()); - row.createCell(13).setCellValue(weeklyHeavyStock.getMPCSOLD()); - row.createCell(14).setCellValue(weeklyHeavyStock.getMPSSOLD()); - row.createCell(15).setCellValue(weeklyHeavyStock.getMTFSOLD()); - row.createCell(16).setCellValue(weeklyHeavyStock.getMWPSOLD()); - row.createCell(17).setCellValue(weeklyHeavyStock.getMYOSOLD()); - row.createCell(18).setCellValue(weeklyHeavyStock.getMAS()); - row.createCell(19).setCellValue(weeklyHeavyStock.getMEL()); - row.createCell(20).setCellValue(weeklyHeavyStock.getMPC()); - row.createCell(21).setCellValue(weeklyHeavyStock.getMPS()); - row.createCell(22).setCellValue(weeklyHeavyStock.getMTF()); - row.createCell(23).setCellValue(weeklyHeavyStock.getMWP()); - row.createCell(24).setCellValue(weeklyHeavyStock.getMYO()); - row.createCell(25).setCellValue(weeklyHeavyStock.getMRT()); - row.createCell(26).setCellValue(weeklyHeavyStock.getMBZ()); - row.createCell(27).setCellValue(weeklyHeavyStock.getMHZ()); - - rowNum++; - } - - // 确保处理最后一个Plu Code - if (startRow < rowNum - 1 || previousPluCode != null) { - mergeCells(sheet, startRow, rowNum - 1); - linkImageToCell(workbook, sheet, startRow, rowNum - 1, 0, imagePath); + } catch (Exception e) { + throw new RuntimeException("Error while processing the report", e); + } finally { + if (channelSftp != null && channelSftp.isConnected()) { + channelSftp.disconnect(); + } + if (session != null && session.isConnected()) { + session.disconnect(); + } } // 将工作簿写入文件 @@ -967,6 +1058,7 @@ public class MiTuExportScheduledTask { System.out.println("Excel file has been created successfully!"); } + private void mergeCells(Sheet sheet, int startRow, int endRow) { // 合并单元格 if (startRow < endRow) { @@ -976,56 +1068,94 @@ public class MiTuExportScheduledTask { } } - private void linkImageToCell(Workbook workbook, Sheet sheet, int startRow, int endRow, int colNum, String imagePath) throws IOException { - try (InputStream inputStream = minioUtil.download("mi-tu/26/BOTTOM/PANTS/MKTS27000_0CMY_copy.jpg")) { - byte[] bytes = IOUtils.toByteArray(inputStream); - int pictureIdx = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG); + private void linkImageToCell(Workbook workbook, Sheet sheet, int startRow, int endRow, int colNum, String imagePath, ChannelSftp channelSftp) throws IOException { + try { + String[] split = imagePath.split("\\."); + // 拼接完整路径 + String fullPath = "PIC/" + split[0] + ".bmp"; - CreationHelper helper = workbook.getCreationHelper(); - Drawing drawing = sheet.createDrawingPatriarch(); - ClientAnchor anchor = helper.createClientAnchor(); + // 下载图片 + try (InputStream inputStream = channelSftp.get(fullPath)) { + byte[] bytes = IOUtils.toByteArray(inputStream); + int pictureIdx = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG); - // 将图片设置为150x150像素的大小,并转换为EMU单位 - int widthInEMU = 150 * 9525; - int heightInEMU = 150 * 9525; + CreationHelper helper = workbook.getCreationHelper(); + Drawing drawing = sheet.createDrawingPatriarch(); + ClientAnchor anchor = helper.createClientAnchor(); - // 设置图片的插入位置和大小,确保只覆盖Image列 - anchor.setCol1(colNum); // 设置开始列为Image列 - anchor.setRow1(startRow); // 设置开始行 - anchor.setCol2(colNum); // 设置结束列为Image列,不应影响Plu Code列 - anchor.setRow2(endRow + 1); // 设置结束行 + // 将图片设置为150x150像素的大小,并转换为EMU单位 + int widthInEMU = 150 * 9525; + int heightInEMU = 150 * 9525; - // 设置图片的宽度和高度 - anchor.setDx1(0); // 起始点x偏移量 - anchor.setDy1(0); // 起始点y偏移量 - anchor.setDx2(widthInEMU); // 结束点x偏移量,使得图片只占用Image列的空间 - anchor.setDy2(heightInEMU); // 结束点y偏移量 + // 设置图片的插入位置和大小,确保只覆盖Image列 + anchor.setCol1(colNum); // 设置开始列为Image列 + anchor.setRow1(startRow); // 设置开始行 + anchor.setCol2(colNum); // 设置结束列为Image列,不应影响Plu Code列 + anchor.setRow2(endRow + 1); // 设置结束行 - Picture pict = drawing.createPicture(anchor, pictureIdx); + // 设置图片的宽度和高度 + anchor.setDx1(0); // 起始点x偏移量 + anchor.setDy1(0); // 起始点y偏移量 + anchor.setDx2(widthInEMU); // 结束点x偏移量,使得图片只占用Image列的空间 + anchor.setDy2(heightInEMU); // 结束点y偏移量 - // 设置Image列的宽度为150像素 - sheet.setColumnWidth(colNum, 150 * 35); // 设置列宽,Excel列宽的单位为1/256个字符宽度 + Picture pict = drawing.createPicture(anchor, pictureIdx); -// // 自动调整除Image列外的其他列宽度 -// for (int i = 1; i < sheet.getRow(2).getLastCellNum(); i++) { -// sheet.autoSizeColumn(i); -// } + // 设置Image列的宽度为150像素 + sheet.setColumnWidth(colNum, 150 * 35); // 设置列宽,Excel列宽的单位为1/256个字符宽度 - // 计算行数和每行的高度 - int totalRows = endRow - startRow + 1; - int rowHeight = (150 * 15) / totalRows; // 计算每行的高度,单位为1/20点 + // 计算行数和每行的高度 + int totalRows = endRow - startRow + 1; + int rowHeight = (150 * 15) / totalRows; // 计算每行的高度,单位为1/20点 - for (int i = startRow; i <= endRow; i++) { - sheet.getRow(i).setHeight((short) rowHeight); // 设置每一行的行高 + for (int i = startRow; i <= endRow; i++) { + sheet.getRow(i).setHeight((short) rowHeight); // 设置每一行的行高 + } + } catch (SftpException e) { + throw new IOException("Failed to download image from SFTP server", e); } - } catch (MinioException e) { - throw new RuntimeException(e); + } catch (Exception e) { + throw new RuntimeException("Error while downloading image from SFTP server", e); } } private String getImagePath(String pluCode) { - // 假设图片路径与 PLU_CODE 相关,例如:return "path/to/images/" + pluCode + ".jpg"; - return "C:\\Users\\10233\\Desktop\\2024 SS\\MKTS27000_0CMY.jpg"; // 示例路径 + String image = ""; + Connection conn = null; + Statement stmt = null; + try { + Class.forName(JDBC_DRIVER); + conn = DriverManager.getConnection(DB_URL, USER, PASS); + stmt = conn.createStatement(); + + String sql = "SELECT top 1 Image FROM v_item_1A\n" + + "WHERE plu_code = '" + pluCode + "'"; + + ResultSet rs = stmt.executeQuery(sql); + + while (rs.next()) { + image = rs.getString("Image"); + } + rs.close(); + stmt.close(); + conn.close(); + } catch (SQLException | ClassNotFoundException se) { + se.printStackTrace(); + } finally { + try { + if (stmt != null) stmt.close(); + } catch (SQLException ignored) {} + try { + if (conn != null) conn.close(); + } catch (SQLException se) { + se.printStackTrace(); + } + } + System.out.println("Query execution completed!"); + if (image == null) { + return null; + } + return image.split("\\\\")[1]; } private static List getQuarterlyProductGroupingList() { @@ -2483,11 +2613,20 @@ public class MiTuExportScheduledTask { private void runDailySalesIncentiveStatisticsForPast30Days() { LocalDate today = LocalDate.now(); - for (int i = 0; i < 1; i++) { + for (int i = 0; i < 30; i++) { + today = today.minusDays(1); dailySalesIncentiveStatistics(today); - today = today.minusDays(1); // 日期向前移动一天 } } + @Scheduled(cron = "0 0 2 * * ?") + private void runDailySalesIncentiveStatistics() { + LocalDate today = LocalDate.now(); + for (int i = 0; i < 1; i++) { + today = today.minusDays(1); + dailySalesIncentiveStatistics(today); + } + } + public void dailySalesIncentiveStatistics(LocalDate localDate) { // 获取前一日所有商品销售记录 diff --git a/src/main/java/com/mixi/service/PythonService.java b/src/main/java/com/mixi/service/PythonService.java index 745293e..20fabaf 100644 --- a/src/main/java/com/mixi/service/PythonService.java +++ b/src/main/java/com/mixi/service/PythonService.java @@ -569,7 +569,7 @@ public class PythonService { return productList; } - public JSONObject getAIRecommend(QeFilling qeFilling) { + public JSONArray getAIRecommend(QeFilling qeFilling) { //限流校验 // AccessLimitUtils.validate("similarityMatch", 20); OkHttpClient client = new OkHttpClient().newBuilder() @@ -581,20 +581,20 @@ public class PythonService { MediaType mediaType = MediaType.parse("application/json"); Map content = Maps.newHashMap(); content.put("user_id", qeFilling.getPhoneNum()); - content.put("type", qeFilling.getType()); - content.put("q1", qeFilling.getQ1()); - content.put("q2", qeFilling.getQ2()); - content.put("q3", qeFilling.getQ3()); - content.put("q4", qeFilling.getQ4()); - content.put("q5", qeFilling.getQ5()); - content.put("q6", qeFilling.getQ6()); - content.put("q7", qeFilling.getQ7()); - content.put("q8", qeFilling.getQ8()); +// content.put("type", qeFilling.getType()); +// content.put("q1", qeFilling.getQ1()); +// content.put("q2", qeFilling.getQ2()); +// content.put("q3", qeFilling.getQ3()); +// content.put("q4", qeFilling.getQ4()); +// content.put("q5", qeFilling.getQ5()); +// content.put("q6", qeFilling.getQ6()); +// content.put("q7", qeFilling.getQ7()); +// content.put("q8", qeFilling.getQ8()); RequestBody body = RequestBody.create(mediaType, JSON.toJSONString(content)); Request request = new Request.Builder() // .url(accessPythonIp + ":9993/api/similar_matchsimilar_match") - .url("http://18.167.251.121:10001/chat") + .url("http://18.167.251.121:5001/chat") .method("POST", body) // .addHeader("Authorization", "Basic YWlkbGFiOjEyMw==") .addHeader("Content-Type", "application/json") @@ -618,8 +618,8 @@ public class PythonService { JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(response)); Boolean result = jsonObject.getBoolean("successful"); if (result) { - JSONObject parseObject = JSON.parseObject(bodyStr.trim()); - return parseObject; + JSONArray parseArray = JSON.parseArray(bodyStr.trim()); + return parseArray; } log.info("获取python获取AI推荐请求异常###{}", jsonObject); //生成失败 diff --git a/src/main/java/com/mixi/service/TAppProductService.java b/src/main/java/com/mixi/service/TAppProductService.java index d7b276e..dcba439 100644 --- a/src/main/java/com/mixi/service/TAppProductService.java +++ b/src/main/java/com/mixi/service/TAppProductService.java @@ -1,6 +1,7 @@ package com.mixi.service; import cn.hutool.core.collection.CollectionUtil; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; @@ -753,75 +754,83 @@ public class TAppProductService extends ServiceImpl { throw new BusinessException("Phone number not found"); } // 调用ai推荐模型 - JSONObject jsonObject = pythonService.getAIRecommend(qeFillings.get(0)); + JSONArray jsonArray = pythonService.getAIRecommend(qeFillings.get(0)); // 检查jsonObject是否为null - if (jsonObject == null) { + if (jsonArray == null) { throw new NullPointerException("The response from Python service is null"); } // 从JSON对象中获取output字段 - String output = jsonObject.getString("output"); -// String output = "Here are three outfit recommendations for you:\n" + -// "\n" + -// "1. **Garden Party or Brunch Look**:\n" + -// " - **Floral Dress**: A long floral dress with a gathered waist, featuring a wrap-style bodice and three-quarter sleeves. It's crafted from lightweight cotton with a multicolored botanical pattern, suitable for casual or semi-formal wear.\n" + -// " - **Denim Jacket**: A short denim jacket with a classic collar, button closures, and front pockets, crafted from blue denim. It adds a touch of casual chic, ideal for transitioning from day to evening.\n" + -// " - ![Floral Dress](fashion_items/mitu/images/MWSS27211_0LGN.jpg)\n" + -// " - ![Denim Jacket](fashion_items/mitu/images/MLSS27109_0DBL.jpg)\n" + -// "\n" + -// "2. **Casual Summer Day**:\n" + -// " - **Mid-Length Dress**: Featuring short sleeves and a shirt collar, crafted from lightweight blue fabric with white stripes and floral embroidery. It includes a belted waist and tiered skirt for a casual, summery style.\n" + -// " - **Tropical Top**: A sleeveless top with a round neckline and a tropical leaf print in green and beige on a white background, perfect for a sunny outing.\n" + -// " - ![Mid-Length Dress](fashion_items/mitu/images/MLSS27102_0BLU.jpg)\n" + -// " - ![Tropical Top](fashion_items/mitu/images/MLSS27156_0GRN.jpg)\n" + -// "\n" + -// "3. **Everyday Relaxed Look**:\n" + -// " - **White Blouse**: A long-sleeve blouse with a V-neckline and gathered cuffs, made from lightweight cotton. It offers a casual, airy style suitable for everyday wear.\n" + -// " - **Wide-Leg Pants**: Beige wide-leg pants with a striped waistband, crafted from a smooth fabric. They feature side pockets and a sleek, casual design.\n" + -// " - ![White Blouse](fashion_items/mitu/images/MKTS27002_0WHT.jpg)\n" + -// " - ![Wide-Leg Pants](fashion_items/mitu/images/MKTS27004_0BGE.jpg)\n" + -// "\n" + -// "These outfits are designed to provide comfort and style for various occasions. Enjoy your new looks!"; - - String[] parts = output.split("\\n\\n"); - - int length = parts.length; - String start = parts[0]; - String end = parts[length - 1]; - if (length >= 3) { - for (int i = 1; i < (length - 1); i++) { - OutfitRecommendation outfitRecommendation = new OutfitRecommendation(); - String part = parts[i]; - List urls = extractBracketContents(part); - Map map = new HashMap<>(); - for (String url : urls) { - if (url.contains("/")) { - String[] split = url.split("/"); - String s = split[split.length - 1]; - if (s.contains(".")) { - String[] split1 = s.split("\\."); - String pictureName = split1[0]; - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().like(TProduct::getPictureName, pictureName); - List productList = productMapper.selectList(qw); - if (!CollectionUtils.isEmpty(productList)) { - String pictureUrl = productList.get(0).getPictureUrl(); - String presignedUrl = minioUtil.getPresignedUrl(pictureUrl, 24 * 60); - map.put(url, presignedUrl); - outfitRecommendation.addImageUrl(presignedUrl); - } + for (int i = 0; i < jsonArray.size(); i++) { + OutfitRecommendation outfitRecommendation = new OutfitRecommendation(); + JSONObject outfit = jsonArray.getJSONObject(i); + String recommendedReasons = outfit.getString("recommended_reasons"); + JSONArray retrievedUrls = outfit.getJSONArray("retrieved_urls"); + for (int i1 = 0; i1 < retrievedUrls.size(); i1++) { + String url = retrievedUrls.getString(i1); + if (url.contains("/")) { + String[] split = url.split("/"); + String s = split[split.length - 1]; + if (s.contains(".")) { + String[] split1 = s.split("\\."); + String pictureName = split1[0]; + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().like(TProduct::getPictureName, pictureName); + List productList = productMapper.selectList(qw); + if (!CollectionUtils.isEmpty(productList)) { + String pictureUrl = productList.get(0).getPictureUrl(); + String presignedUrl = minioUtil.getPresignedUrl(pictureUrl, 24 * 60); + outfitRecommendation.addImageUrl(presignedUrl); } } } - for (String s : map.keySet()) { - part = part.replace(s, map.get(s)); - } - String recommendOutput = start + "\n\n" + part + "\n\n" + end; - outfitRecommendation.setMarkdownContent(recommendOutput); - result.add(outfitRecommendation); +// String preSignedUrl = minioUtil.getPresignedUrl(url, 24 * 60); +// outfitRecommendation.addImageUrl(preSignedUrl); } + outfitRecommendation.setMarkdownContent("**Recommend reasons:**\n\n" + recommendedReasons); + result.add(outfitRecommendation); } +// String output = jsonObject.getString("output"); +// +// String[] parts = output.split("\\n\\n"); +// +// int length = parts.length; +// String start = parts[0]; +// String end = parts[length - 1]; +// if (length >= 3) { +// for (int i = 1; i < (length - 1); i++) { +// OutfitRecommendation outfitRecommendation = new OutfitRecommendation(); +// String part = parts[i]; +// List urls = extractBracketContents(part); +// Map map = new HashMap<>(); +// for (String url : urls) { +// if (url.contains("/")) { +// String[] split = url.split("/"); +// String s = split[split.length - 1]; +// if (s.contains(".")) { +// String[] split1 = s.split("\\."); +// String pictureName = split1[0]; +// QueryWrapper qw = new QueryWrapper<>(); +// qw.lambda().like(TProduct::getPictureName, pictureName); +// List productList = productMapper.selectList(qw); +// if (!CollectionUtils.isEmpty(productList)) { +// String pictureUrl = productList.get(0).getPictureUrl(); +// String presignedUrl = minioUtil.getPresignedUrl(pictureUrl, 24 * 60); +// map.put(url, presignedUrl); +// outfitRecommendation.addImageUrl(presignedUrl); +// } +// } +// } +// } +// for (String s : map.keySet()) { +// part = part.replace(s, map.get(s)); +// } +// String recommendOutput = start + "\n\n" + part + "\n\n" + end; +// outfitRecommendation.setMarkdownContent(recommendOutput); +// result.add(outfitRecommendation); +// } +// } return result; }