From e566c01cff091ded4bad20377641681239883838 Mon Sep 17 00:00:00 2001 From: shahaibo <1023316923@qq.com> Date: Sun, 11 Aug 2024 17:36:56 +0800 Subject: [PATCH] TASK:mixi; --- .../common/tasks/MiTuExportScheduledTask.java | 417 +++++++++++------- .../com/mixi/mapper/MiTuProductMapper.java | 2 + .../com/mixi/mapper/entity/MiTuMember.java | 1 + .../mixi/model/dto/QueryRecommendPageDTO.java | 2 +- .../com/mixi/service/TAppProductService.java | 73 ++- .../com/mixi/service/TProductService.java | 14 + .../service/impl/MiTuExportServiceImpl.java | 342 ++++++++++---- .../resources/mapper/MiTuProductMapper.xml | 62 +++ 8 files changed, 624 insertions(+), 289 deletions(-) diff --git a/src/main/java/com/mixi/common/tasks/MiTuExportScheduledTask.java b/src/main/java/com/mixi/common/tasks/MiTuExportScheduledTask.java index 7380cc5..e367601 100644 --- a/src/main/java/com/mixi/common/tasks/MiTuExportScheduledTask.java +++ b/src/main/java/com/mixi/common/tasks/MiTuExportScheduledTask.java @@ -7,8 +7,10 @@ import com.mixi.common.utils.CopyUtil; import com.mixi.common.utils.MinioUtil; import com.mixi.mapper.*; import com.mixi.mapper.entity.*; +import io.minio.errors.MinioException; import org.apache.commons.compress.utils.IOUtils; import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItemFactory; @@ -24,6 +26,8 @@ import org.springframework.web.multipart.commons.CommonsMultipartFile; import javax.annotation.PostConstruct; import javax.annotation.Resource; +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; import java.io.*; import java.nio.file.Files; import java.nio.file.Paths; @@ -68,7 +72,7 @@ public class MiTuExportScheduledTask { // getBestSell(); // getData(); // dailySalesIncentiveStatistics(); - updateProductStock(); +// updateProductStock(); } private void updateProductStock() { @@ -549,51 +553,38 @@ public class MiTuExportScheduledTask { private void exportWeeklySellThrReport(List transactionSummaryList, String filePathName) throws IOException { String currentPath = Paths.get("").toAbsolutePath().toString(); File file = new File(currentPath + "/" + filePathName); - // 如果文件不存在或者为空,则创建一个新的 Workbook Workbook workbook = new XSSFWorkbook(); + Sheet sheet = workbook.createSheet("Weekly Sell Through Report"); - // 创建一个新的 Sheet 或获取现有的 Sheet - Sheet sheet = workbook.getSheet("Weekly Sell Through Report"); - if (sheet == null) { - sheet = workbook.createSheet("Weekly Sell Through Report"); + Row headerRow = sheet.createRow(0); + String[] headers = {"PLU_CODE", "ToShopDate", "SalesDay", "CATEGORY", "SUB_CAT", "ItemName", + "PriceOriginal", "ToRetailQty", "TotalSaleNum", "MAS_count", "MEL_count", + "MPC_count", "MPS_count", "MTF_count", "MWP_count", "MYO_count", + "LwSalesQty", "RetailOnHand", "SalesRate", "Product Image"}; + for (int i = 0; i < headers.length; i++) { + headerRow.createCell(i).setCellValue(headers[i]); } - // 写入标题行 - Row headerRow = sheet.getRow(0); - if (headerRow == null) { - headerRow = sheet.createRow(0); - } - headerRow.createCell(0).setCellValue("PLU_CODE"); - headerRow.createCell(1).setCellValue("ToShopDate"); - headerRow.createCell(2).setCellValue("SalesDay"); - headerRow.createCell(3).setCellValue("CATEGORY"); - headerRow.createCell(4).setCellValue("SUB_CAT"); - headerRow.createCell(5).setCellValue("ItemName"); - headerRow.createCell(6).setCellValue("PriceOriginal"); - headerRow.createCell(7).setCellValue("ToRetailQty"); - headerRow.createCell(8).setCellValue("TotalSaleNum"); - headerRow.createCell(9).setCellValue("MAS_count"); - headerRow.createCell(10).setCellValue("MEL_count"); - headerRow.createCell(11).setCellValue("MPC_count"); - headerRow.createCell(12).setCellValue("MPS_count"); - headerRow.createCell(13).setCellValue("MTF_count"); - headerRow.createCell(14).setCellValue("MWP_count"); - headerRow.createCell(15).setCellValue("MYO_count"); - headerRow.createCell(16).setCellValue("LwSalesQty"); - headerRow.createCell(17).setCellValue("RetailOnHand"); - headerRow.createCell(18).setCellValue("SalesRate"); + int rowNum = 1; + int startRow = rowNum; + String previousPluCode = ""; + String imagePath = ""; - // 写入数据 - int rowNum = sheet.getLastRowNum() + 1; for (TransactionSummary summary : transactionSummaryList) { - Row row = sheet.createRow(rowNum++); - - row.createCell(0).setCellValue(summary.getPLU_CODE()); - if (summary.getToShopDate() != null) { - row.createCell(1).setCellValue(summary.getToShopDate().toString()); - }else { - row.createCell(1).setCellValue(""); + if (!summary.getPLU_CODE().equals(previousPluCode)) { + if (startRow < rowNum) { + mergeCells(sheet, startRow, rowNum - 1); + linkImageToCell(workbook, sheet, startRow, rowNum - 1, headers.length - 1, imagePath); + } + 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()); @@ -611,17 +602,24 @@ public class MiTuExportScheduledTask { row.createCell(16).setCellValue(summary.getLwSalesQty()); row.createCell(17).setCellValue(summary.getRetailOnHand()); row.createCell(18).setCellValue(summary.getSalesRate()); + + rowNum++; } - // 将Workbook写入文件 + // 处理最后一个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); - - System.out.println("Excel file has been created successfully!"); } @@ -647,41 +645,39 @@ public class MiTuExportScheduledTask { } } - private void exportWeeklyHeavyStock(List weeklyHeavyStockList, String weeklyHeavyStockReportName) { + private void exportWeeklyHeavyStock(List weeklyHeavyStockList, String weeklyHeavyStockReportName) throws IOException { String currentPath = Paths.get("").toAbsolutePath().toString(); File file = new File(currentPath + "/" + weeklyHeavyStockReportName); - // 创建工作簿 Workbook workbook = new XSSFWorkbook(); - // 创建工作表 Sheet sheet = workbook.createSheet("Weekly Heavy Stock Report"); - // 创建标题行 - Row headerRow = sheet.createRow(0); - headerRow.createCell(0).setCellValue("PLU_CODE"); - headerRow.createCell(1).setCellValue("item_name"); - headerRow.createCell(2).setCellValue("item_barcode"); - headerRow.createCell(3).setCellValue("cat"); - headerRow.createCell(4).setCellValue("sub_cat"); - headerRow.createCell(5).setCellValue("Col"); - headerRow.createCell(6).setCellValue("price_sales"); - headerRow.createCell(7).setCellValue("MAS"); - headerRow.createCell(8).setCellValue("MEL"); - headerRow.createCell(9).setCellValue("MPC"); - headerRow.createCell(10).setCellValue("MPS"); - headerRow.createCell(11).setCellValue("MTF"); - headerRow.createCell(12).setCellValue("MWP"); - headerRow.createCell(13).setCellValue("MYO"); - headerRow.createCell(14).setCellValue("MHZ"); - headerRow.createCell(15).setCellValue("MRT"); - headerRow.createCell(16).setCellValue("MBZ"); - headerRow.createCell(17).setCellValue("TLT"); - headerRow.createCell(18).setCellValue("subtotal"); - headerRow.createCell(19).setCellValue("G.TLT"); - // 写入数据 + Row headerRow = sheet.createRow(0); + String[] headers = {"PLU_CODE", "item_name", "item_barcode", "cat", "sub_cat", "Col", "price_sales", + "MAS", "MEL", "MPC", "MPS", "MTF", "MWP", "MYO", "MHZ", "MRT", "MBZ", "TLT", + "subtotal", "G.TLT", "Product Image"}; + for (int i = 0; i < headers.length; i++) { + headerRow.createCell(i).setCellValue(headers[i]); + } + int rowNum = 1; + int startRow = rowNum; + String previousPluCode = ""; + String imagePath = ""; + for (WeeklyHeavyStock weeklyHeavyStock : weeklyHeavyStockList) { - Row row = sheet.createRow(rowNum++); + 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); + } + 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()); @@ -701,22 +697,26 @@ public class MiTuExportScheduledTask { row.createCell(17).setCellValue(weeklyHeavyStock.getTLT()); row.createCell(18).setCellValue(weeklyHeavyStock.getSubtotal()); row.createCell(19).setCellValue(weeklyHeavyStock.getG_TLT()); + + rowNum++; + } + + if (startRow < rowNum - 1 || previousPluCode != null) { + mergeCells(sheet, startRow, rowNum - 1); + linkImageToCell(workbook, sheet, startRow, rowNum - 1, headers.length - 1, imagePath); } - // 将工作簿写入文件 try (FileOutputStream outputStream = new FileOutputStream(file)) { workbook.write(outputStream); - } catch (IOException e) { - e.printStackTrace(); } + FileItem a = getMultipartFile(file, file.getName()); MultipartFile multipartFile = new CommonsMultipartFile(a); minioUtil.upload("mi-tu", "export", multipartFile); - - System.out.println("Excel file has been created successfully!"); } + /** * Quarterly Product Grouping Report */ @@ -756,70 +756,116 @@ public class MiTuExportScheduledTask { return String.format("0 0 22 %d %d ?", dayOfMonth, month); } - private void exportQuarterlyProductGrouping(List weeklyHeavyStockList, String weeklyHeavyStockReportName) { + public void exportQuarterlyProductGrouping(List weeklyHeavyStockList, String weeklyHeavyStockReportName) throws IOException { String currentPath = Paths.get("").toAbsolutePath().toString(); File file = new File(currentPath + "/" + weeklyHeavyStockReportName); - // 创建工作簿 - Workbook workbook = new XSSFWorkbook(); - // 创建工作表 - Sheet sheet = workbook.createSheet("Quarterly Product Grouping Report"); - // 创建标题行 - Row headerRow = sheet.createRow(0); - headerRow.createCell(0).setCellValue("PLU_CODE"); - headerRow.createCell(1).setCellValue("Col"); - headerRow.createCell(2).setCellValue("Size"); - headerRow.createCell(3).setCellValue("item_barcode"); - headerRow.createCell(4).setCellValue("item_name"); - headerRow.createCell(5).setCellValue("cat"); - headerRow.createCell(6).setCellValue("sub_cat"); - headerRow.createCell(7).setCellValue("price_sales"); - headerRow.createCell(8).setCellValue("MASSOLD"); - headerRow.createCell(9).setCellValue("MELSOLD"); - headerRow.createCell(10).setCellValue("MPCSOLD"); - headerRow.createCell(11).setCellValue("MPSSOLD"); - headerRow.createCell(12).setCellValue("MTFSOLD"); - headerRow.createCell(13).setCellValue("MWPSOLD"); - headerRow.createCell(14).setCellValue("MYOSOLD"); - headerRow.createCell(15).setCellValue("MAS"); - headerRow.createCell(16).setCellValue("MEL"); - headerRow.createCell(17).setCellValue("MPC"); - headerRow.createCell(18).setCellValue("MPS"); - headerRow.createCell(19).setCellValue("MTF"); - headerRow.createCell(20).setCellValue("MWP"); - headerRow.createCell(21).setCellValue("MYO"); - headerRow.createCell(22).setCellValue("MHZ"); - headerRow.createCell(23).setCellValue("MRT"); - headerRow.createCell(24).setCellValue("MBZ"); - // 写入数据 - int rowNum = 1; + // 创建工作簿和工作表 + Workbook workbook = new XSSFWorkbook(); + Sheet sheet = workbook.createSheet("Quarterly Product Grouping Report"); + + // 添加报表头 + Row titleRow = sheet.createRow(0); + Cell titleCell = titleRow.createCell(0); + titleCell.setCellValue("FW24 STOCK LIST"); + sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 26)); // 合并标题单元格 + + // 添加“Stock on hand - shop”和“Stock on hand - back office” + Row stockHeaderRow = sheet.createRow(1); + + Cell stockShopCell = stockHeaderRow.createCell(10); + stockShopCell.setCellValue("Stock on hand - shop"); + sheet.addMergedRegion(new CellRangeAddress(1, 1, 10, 16)); // 适当调整列的范围 + + Cell stockOfficeCell = stockHeaderRow.createCell(17); + stockOfficeCell.setCellValue("Stock on hand - back office"); + sheet.addMergedRegion(new CellRangeAddress(1, 1, 17, 19)); // 适当调整列的范围 + + // 创建标题行 + Row headerRow = sheet.createRow(2); + String[] headers = {"Image", "Plu Code", "Col", "Size", "Item Code", "Item Name", "Cat", "Sub_Cat", "RSP", + "HK Sell-thru", "Shop total Sold", // 新增字段 + "MAS Sold", "MEL Sold", "MPC Sold", "MPS Sold", "MTF Sold", "MWP Sold", "MYO Sold", + "MAS", "MEL", "MPC", "MPS", "MTF", "MWP", "MYO", "MRT", "MBZ", "MHZ"}; + + for (int i = 0; i < headers.length; i++) { + 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) { - Row row = sheet.createRow(rowNum++); - row.createCell(0).setCellValue(weeklyHeavyStock.getPLU_CODE()); - row.createCell(1).setCellValue(weeklyHeavyStock.getCol()); - row.createCell(2).setCellValue(weeklyHeavyStock.getSize()); - row.createCell(3).setCellValue(weeklyHeavyStock.getItem_barcode()); - row.createCell(4).setCellValue(weeklyHeavyStock.getItem_name()); - row.createCell(5).setCellValue(weeklyHeavyStock.getCat()); - row.createCell(6).setCellValue(weeklyHeavyStock.getSub_cat()); - row.createCell(7).setCellValue(weeklyHeavyStock.getPrice_sales()); - row.createCell(8).setCellValue(weeklyHeavyStock.getMASSOLD()); - row.createCell(9).setCellValue(weeklyHeavyStock.getMELSOLD()); - row.createCell(10).setCellValue(weeklyHeavyStock.getMPCSOLD()); - row.createCell(11).setCellValue(weeklyHeavyStock.getMPSSOLD()); - row.createCell(12).setCellValue(weeklyHeavyStock.getMTFSOLD()); - row.createCell(13).setCellValue(weeklyHeavyStock.getMWPSOLD()); - row.createCell(14).setCellValue(weeklyHeavyStock.getMYOSOLD()); - row.createCell(15).setCellValue(weeklyHeavyStock.getMAS()); - row.createCell(16).setCellValue(weeklyHeavyStock.getMEL()); - row.createCell(17).setCellValue(weeklyHeavyStock.getMPC()); - row.createCell(18).setCellValue(weeklyHeavyStock.getMPS()); - row.createCell(19).setCellValue(weeklyHeavyStock.getMTF()); - row.createCell(20).setCellValue(weeklyHeavyStock.getMWP()); - row.createCell(21).setCellValue(weeklyHeavyStock.getMYO()); - row.createCell(22).setCellValue(weeklyHeavyStock.getMHZ()); - row.createCell(23).setCellValue(weeklyHeavyStock.getMRT()); - row.createCell(24).setCellValue(weeklyHeavyStock.getMBZ()); + 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); // 插入图片到合并单元格 + } + 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++; + } + + // 确保处理最后一个Plu Code + if (startRow < rowNum - 1 || previousPluCode != null) { + mergeCells(sheet, startRow, rowNum - 1); + linkImageToCell(workbook, sheet, startRow, rowNum - 1, 0, imagePath); } // 将工作簿写入文件 @@ -828,6 +874,8 @@ public class MiTuExportScheduledTask { } catch (IOException e) { e.printStackTrace(); } + + // 上传文件 FileItem a = getMultipartFile(file, file.getName()); MultipartFile multipartFile = new CommonsMultipartFile(a); minioUtil.upload("mi-tu", "export", multipartFile); @@ -835,7 +883,66 @@ public class MiTuExportScheduledTask { System.out.println("Excel file has been created successfully!"); } + private void mergeCells(Sheet sheet, int startRow, int endRow) { + // 合并单元格 + if (startRow < endRow) { + for (int i = 1; i <= 1; i++) { // 只合并Plu Code列 + sheet.addMergedRegion(new CellRangeAddress(startRow, endRow, i, i)); + } + } + } + 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_0BLK.jpg")) { + byte[] bytes = IOUtils.toByteArray(inputStream); + int pictureIdx = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG); + + CreationHelper helper = workbook.getCreationHelper(); + Drawing drawing = sheet.createDrawingPatriarch(); + ClientAnchor anchor = helper.createClientAnchor(); + + // 将图片设置为150x150像素的大小,并转换为EMU单位 + int widthInEMU = 150 * 9525; + int heightInEMU = 150 * 9525; + + // 设置图片的插入位置和大小,确保只覆盖Image列 + anchor.setCol1(colNum); // 设置开始列为Image列 + anchor.setRow1(startRow); // 设置开始行 + anchor.setCol2(colNum); // 设置结束列为Image列,不应影响Plu Code列 + anchor.setRow2(endRow + 1); // 设置结束行 + + // 设置图片的宽度和高度 + anchor.setDx1(0); // 起始点x偏移量 + anchor.setDy1(0); // 起始点y偏移量 + anchor.setDx2(widthInEMU); // 结束点x偏移量,使得图片只占用Image列的空间 + anchor.setDy2(heightInEMU); // 结束点y偏移量 + + Picture pict = drawing.createPicture(anchor, pictureIdx); + + // 设置Image列的宽度为150像素 + sheet.setColumnWidth(colNum, 150 * 35); // 设置列宽,Excel列宽的单位为1/256个字符宽度 + +// // 自动调整除Image列外的其他列宽度 +// for (int i = 1; i < sheet.getRow(2).getLastCellNum(); i++) { +// sheet.autoSizeColumn(i); +// } + + // 计算行数和每行的高度 + 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); // 设置每一行的行高 + } + } catch (MinioException e) { + throw new RuntimeException(e); + } + } + + private String getImagePath(String pluCode) { + // 假设图片路径与 PLU_CODE 相关,例如:return "path/to/images/" + pluCode + ".jpg"; + return "C:\\Users\\10233\\Desktop\\2024 SS\\MKTS27000_0CMY.jpg"; // 示例路径 + } private static List getQuarterlyProductGroupingList() { List QuarterlyProductGroupingList = new ArrayList<>(); @@ -1538,8 +1645,6 @@ public class MiTuExportScheduledTask { public final static String MITU = "mi-tu"; public void exportToExcelCustomerPurchaseReport(List customerDataList, String fileName) throws IOException { - File productFile = getProductFile(fileName); - String currentPath = Paths.get("").toAbsolutePath().toString(); File file = new File(currentPath + "/" + fileName); // 如果文件不存在或者为空,则创建一个新的 Workbook @@ -1560,7 +1665,7 @@ public class MiTuExportScheduledTask { // 获取当前年月 YearMonth currentYearMonth = YearMonth.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM"); - String[] headers = new String[26]; // 增加一个额外的标题列 + String[] headers = new String[25]; headers[0] = "mbrCode"; headers[1] = "mbrName"; headers[2] = "mbrMobile"; @@ -1579,7 +1684,6 @@ public class MiTuExportScheduledTask { for (int i = 0; i < 11; i++) { headers[13 + i] = currentYearMonth.minusMonths(i + 1).format(formatter); } - headers[24] = "productFile"; // 新增的标题列 for (int i = 0; i < headers.length; i++) { Cell cell = headerRow.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK); cell.setCellValue(headers[i]); @@ -1616,26 +1720,7 @@ public class MiTuExportScheduledTask { row.createCell(21).setCellValue(customer.getMonth9()); row.createCell(22).setCellValue(customer.getMonth10()); row.createCell(23).setCellValue(customer.getMonth11()); - row.createCell(24).setCellValue(""); // 占位符,用于后续插入图片 - } - - // 插入图片 - InputStream inputStream = new FileInputStream(productFile); - byte[] bytes = IOUtils.toByteArray(inputStream); - int pictureIdx = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG); - inputStream.close(); - - CreationHelper helper = workbook.getCreationHelper(); - Drawing drawing = sheet.createDrawingPatriarch(); - - for (int i = 1; i <= customerDataList.size(); i++) { // 跳过标题行,从第一行开始 - ClientAnchor anchor = helper.createClientAnchor(); - anchor.setCol1(24); // 图片插入的列 - anchor.setRow1(i); // 图片插入的行 - anchor.setCol2(25); // 图片所占的列数 - anchor.setRow2(i + 1); // 图片所占的行数 - - drawing.createPicture(anchor, pictureIdx); + row.createCell(24).setCellValue(customer.getMonth12()); } // 将Workbook写入文件 @@ -1880,6 +1965,7 @@ public class MiTuExportScheduledTask { public Map mostFrequentSubCatMap = new HashMap<>(); public Map mostFrequentCategoryMap = new HashMap<>(); public Map avePriceMap = new HashMap<>(); + public Map priceVarianceMap = new HashMap<>(); private List getMemberType(List memberCodeList) { List miTuMemberList = new ArrayList<>(); @@ -1897,6 +1983,7 @@ public class MiTuExportScheduledTask { miTuMember.setMostFrequentSubCat(mostFrequentSubCatMap.get(miTuMember.getMbrCode())); miTuMember.setMostFrequentCategory(mostFrequentCategoryMap.get(miTuMember.getMbrCode())); miTuMember.setAvePrice(avePriceMap.get(miTuMember.getMbrCode())); + miTuMember.setPriceVariance(priceVarianceMap.get(miTuMember.getMbrCode())); miTuMemberList.add(miTuMember); } // 计算顾客颜色方差的方差 @@ -2096,6 +2183,20 @@ public class MiTuExportScheduledTask { avePriceMap.put(memberCode, avePrice); } + // Step 1: 提取每笔交易的实际付款金额 + List paymentList = transactionList.stream() + .map(Transaction::getNetAmt) + .collect(Collectors.toList()); + + // Step 2: 计算均值 + double mean = paymentList.stream().mapToDouble(Double::doubleValue).average().orElse(0.0); + + // Step 3: 计算标准差 + double priceVariance = paymentList.stream() + .mapToDouble(payment -> Math.pow(payment - mean, 2)) + .average().orElse(0.0); + priceVarianceMap.put(memberCode, priceVariance); + // 计算颜色的方差 double colorMean = (double) totalCount / colorCountMap.size(); double colorVarianceSum = 0; diff --git a/src/main/java/com/mixi/mapper/MiTuProductMapper.java b/src/main/java/com/mixi/mapper/MiTuProductMapper.java index da1decc..32c8673 100644 --- a/src/main/java/com/mixi/mapper/MiTuProductMapper.java +++ b/src/main/java/com/mixi/mapper/MiTuProductMapper.java @@ -15,4 +15,6 @@ import java.util.List; public interface MiTuProductMapper extends CommonMapper { List getTop30ScoreByMemberCode(String memberCode); + + List getTopScoreByMemberCode(String memberCode, List productIdList); } diff --git a/src/main/java/com/mixi/mapper/entity/MiTuMember.java b/src/main/java/com/mixi/mapper/entity/MiTuMember.java index 758ef69..8a1c8e8 100644 --- a/src/main/java/com/mixi/mapper/entity/MiTuMember.java +++ b/src/main/java/com/mixi/mapper/entity/MiTuMember.java @@ -32,4 +32,5 @@ public class MiTuMember implements Serializable { private String mostFrequentSubCat; private String mostFrequentCategory; private double avePrice; + private double priceVariance; } diff --git a/src/main/java/com/mixi/model/dto/QueryRecommendPageDTO.java b/src/main/java/com/mixi/model/dto/QueryRecommendPageDTO.java index 68c12d5..cabd72b 100644 --- a/src/main/java/com/mixi/model/dto/QueryRecommendPageDTO.java +++ b/src/main/java/com/mixi/model/dto/QueryRecommendPageDTO.java @@ -14,7 +14,7 @@ public class QueryRecommendPageDTO extends PageQueryBaseVo implements Serializab @ApiModelProperty("商品一级标签类型 top dress 等等") private String labelItem; - + private String storeId; private String memberCode; } diff --git a/src/main/java/com/mixi/service/TAppProductService.java b/src/main/java/com/mixi/service/TAppProductService.java index 558e033..173b7ae 100644 --- a/src/main/java/com/mixi/service/TAppProductService.java +++ b/src/main/java/com/mixi/service/TAppProductService.java @@ -157,71 +157,67 @@ public class TAppProductService extends ServiceImpl { if (StringUtils.isEmpty(query.getMemberCode())) { query.setMemberCode("100002"); } + // 分页数据 QueryWrapper queryWrapper = new QueryWrapper<>(); List productIds = new ArrayList<>(); + List productIdsByMemberCode = new ArrayList<>(); // 初始化 productIdsByMemberCode + if (!StringUtils.isEmpty(query.getMemberCode())) { - List productIdsByMemberCode = miTuExportService.getProductIdsByMiTuMemberCode(query.getMemberCode()); + // 获取三页商品ID列表 + productIdsByMemberCode = miTuExportService.getProductIdsByMiTuMemberCode(query.getMemberCode()); productIds.addAll(productIdsByMemberCode); if (CollectionUtils.isEmpty(productIds)) { return PageBaseResponse.success(new Page<>()); } } - if (!StringUtils.isEmpty(query.getLabelItem())) { - List byItemAndType = tProductAttributeService.findByItemAndType(query.getLabelItem(), null); - if (CollectionUtils.isEmpty(byItemAndType)) { - return PageBaseResponse.success(new Page<>()); - } - if (!StringUtils.isEmpty(query.getMemberCode())) { - productIds.retainAll(byItemAndType); - }else { - productIds.addAll(byItemAndType); - } - } + if (CollectionUtils.isEmpty(productIds)) { return PageBaseResponse.success(new Page<>()); } - queryWrapper.in("id", productIds); - //个性化商品筛选 - List customBuriedPointRecords = tCustomBuriedPointRecordService.getRecommendProduct("BROWSE"); -// if(CollectionUtils.isEmpty(customBuriedPointRecords)){ -// return PageBaseResponse.success(new Page<>()); -// } -// List selectProductIds = customBuriedPointRecords.stream().map(v->v.getProductId().toString()).collect(Collectors.toList()); -// queryWrapper.in("id", selectProductIds); - //上架 + // 将商品ID列表作为过滤条件 + queryWrapper.in("id", productIds); + + // 使用 ORDER BY FIELD 语句按照 productIds 列表顺序排序 + queryWrapper.last("ORDER BY FIELD(id, " + productIdsByMemberCode.stream().map(String::valueOf).collect(Collectors.joining(",")) + ")"); + + // 其他筛选条件(如上架状态) queryWrapper.eq("on_sale_state", 1); queryWrapper.eq("upload_state", 1); -// queryWrapper.eq("account_id", UserContext.getUserHolder().getId()); - queryWrapper.orderByDesc("id"); + + // 执行分页查询 IPage page = getBaseMapper().selectPage( new Page<>(query.getPage(), query.getSize()), queryWrapper); + if (CollectionUtils.isEmpty(page.getRecords())) { return PageBaseResponse.success(new Page<>()); } List collect = page.getRecords().stream().map(TProduct::getId).collect(Collectors.toList()); - Map> productToLabelMap = productLabelService.findByProductIds(collect); + Map> productToLabelMap = productLabelService.findByProductIds(collect); List labelIds = productToLabelMap.values() .stream() - .map(list->list.stream().map(TProductLabel::getLabelId).collect(Collectors.toList())) + .map(list -> list.stream().map(TProductLabel::getLabelId).collect(Collectors.toList())) .flatMap(List::stream).collect(Collectors.toList()); - //标签map - Map labelMap = labelService.queryMapByIds(labelIds); + + // 标签映射 + Map labelMap = labelService.queryMapByIds(labelIds); + + // 将查询结果转换为 VO 对象 IPage convert = page.convert((Function) - product -> - { + product -> { AppNewProductVO result = CopyUtil.copyObject(product, AppNewProductVO.class); result.setId(product.getId().toString()); result.setPictureUrl(minioUtil.getPresignedUrl(result.getPictureUrl(), 24 * 60)); - result.setProductLabelInfo(CopyUtil.copyList(productToLabelMap.get(product.getId()),ProductLabelVO.class,(o,d) ->{ + result.setProductLabelInfo(CopyUtil.copyList(productToLabelMap.get(product.getId()), ProductLabelVO.class, (o, d) -> { d.setId(o.getLabelId().toString()); d.setName(labelMap.get(o.getLabelId()).getName()); d.setType(labelMap.get(o.getLabelId()).getType()); })); return result; }); + return PageBaseResponse.success(convert); } /** @@ -726,16 +722,17 @@ public class TAppProductService extends ServiceImpl { // 创建推荐对象 OutfitRecommendation recommendation = new OutfitRecommendation(); - // 调用ai推荐模型 - JSONObject jsonObject = pythonService.getAIRecommend(aiRecommendDTO); - - // 检查jsonObject是否为null - if (jsonObject == null) { - throw new NullPointerException("The response from Python service is null"); - } +// // 调用ai推荐模型 +// JSONObject jsonObject = pythonService.getAIRecommend(aiRecommendDTO); +// +// // 检查jsonObject是否为null +// if (jsonObject == null) { +// throw new NullPointerException("The response from Python service is null"); +// } // 从JSON对象中获取output字段 - String output = jsonObject.getString("output"); +// String output = jsonObject.getString("output"); + String output = "I have a great outfit recommendation for you! Here are the details:\n\n### Recommended Outfit:\n1. **Tailored Navy Blue Blazer**\n - **Description**: A single-breasted design with notched lapels and a slim fit. Features two front flap pockets and a single button closure. Made from a wool blend for a structured yet comfortable feel.\n - ![Navy Blue Blazer](fashion_items/mitu/MKTS27015_0CMY.jpg)\n\n2. **White Silk Blouse**\n - **Description**: A classic collar, button-down front, and long sleeves with buttoned cuffs. Slightly loose fit for a sophisticated and airy look.\n - ![White Silk Blouse](fashion_items/mitu/MKTS27018_0WHT.jpg)\n\n3. **High-Waisted Beige Trousers**\n - **Description**: Straight-leg trousers in a light beige color. Clean front with a concealed hook-and-bar closure, side pockets, and a slightly cropped length to show off the ankles.\n - ![Beige Trousers](fashion_items/mitu/MLSS27160_0BGE.jpg)\n\n### Reasons for Recommendation:\n- **Parisian Chic Theme**: Classic and versatile pieces that embody sophistication and elegance.\n- **Navy Blue Blazer**: Adds a touch of structure, perfect for various occasions.\n- **White Silk Blouse**: A timeless staple that pairs well with the blazer.\n- **High-Waisted Beige Trousers**: Neutral base that complements the navy and white, creating a balanced and polished ensemble.\n\nThis combination is ideal for general use and can be dressed up or down depending on the occasion. Enjoy your new look!"; List urls = extractBracketContents(output); Map map = new HashMap<>(); diff --git a/src/main/java/com/mixi/service/TProductService.java b/src/main/java/com/mixi/service/TProductService.java index 7bbe388..cc0b5a6 100644 --- a/src/main/java/com/mixi/service/TProductService.java +++ b/src/main/java/com/mixi/service/TProductService.java @@ -470,6 +470,20 @@ public class TProductService extends ServiceImpl { * @returnN */ public ProductVO detail(String id) { + if (id.contains("http:")) { + String[] split = id.split("\\.jpg\\?"); + String s = split[0]; + String[] split1 = s.split("/"); + String s1 = split1[split1.length - 1]; + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(TProduct::getPictureName, s1); + List productList = tProductMapper.selectList(qw); + if (!CollectionUtils.isEmpty(productList)) { + id = String.valueOf(productList.get(0).getId()); + }else { + throw new BusinessException("Unknown Product."); + } + } TProduct tProduct = tProductMapper.selectById(id); Assert.notNull(tProduct, "Unknown Product!"); diff --git a/src/main/java/com/mixi/service/impl/MiTuExportServiceImpl.java b/src/main/java/com/mixi/service/impl/MiTuExportServiceImpl.java index d1cf1d8..68996c9 100644 --- a/src/main/java/com/mixi/service/impl/MiTuExportServiceImpl.java +++ b/src/main/java/com/mixi/service/impl/MiTuExportServiceImpl.java @@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.mixi.common.config.exception.BusinessException; import com.mixi.common.response.PageBaseResponse; +import com.mixi.common.tasks.mituExportEntity.WeeklyHeavyStock; import com.mixi.common.utils.CopyUtil; import com.mixi.common.utils.MinioUtil; import com.mixi.mapper.MiTuExportMapper; @@ -28,10 +29,12 @@ import org.springframework.util.StringUtils; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.io.*; +import java.sql.*; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; +import java.util.stream.IntStream; //import com.ai.da.common.utils.SendSmsUtil; @@ -145,102 +148,257 @@ public class MiTuExportServiceImpl implements MiTuExportService { @Override public List getProductIdsByMiTuMemberCode(String memberCode) { - List miTuProductList = miTuProductMapper.getTop30ScoreByMemberCode(memberCode); - if (CollectionUtils.isEmpty(miTuProductList)) { + // 顾客类型筛选 + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(MiTuMember::getMbrCode, memberCode); + List miTuMembers = miTuMemberMapper.selectList(qw); + if (CollectionUtils.isEmpty(miTuMembers)) { return new ArrayList<>(); - }else { -// List result = new ArrayList<>(); -// int i = 0; -// while (result.size() <= 30) { -// -// } - return miTuProductList.stream().map(MiTuProduct::getProductId).collect(Collectors.toList()); } -// QueryWrapper qw = new QueryWrapper<>(); -// qw.lambda().eq(MiTuMember::getMbrCode, memberCode); -// List miTuMembers = miTuMemberMapper.selectList(qw); -// if (CollectionUtils.isEmpty(miTuMembers)) { -// return new ArrayList<>(); -// } -// String mostFrequentColor = miTuMembers.get(0).getMostFrequentColor(); -// String mostFrequentSize = miTuMembers.get(0).getMostFrequentSize(); -// String mostFrequentSubCat = miTuMembers.get(0).getMostFrequentSubCat(); -// List colorList = new ArrayList<>(); -// if (mostFrequentColor.contains(",")) { -// colorList = Arrays.asList(mostFrequentColor.split(",")); -// }else { -// colorList.add(mostFrequentColor); -// } + + MiTuMember member = miTuMembers.get(0); + // 根据顾客代码获取筛选后的商品ID列表 + List productIdList = getProductIdListByMemberType(member); + if (CollectionUtils.isEmpty(productIdList)) { + return new ArrayList<>(); + } + + // 获取经过打分后的商品列表 + List scoredProducts = miTuProductMapper.getTopScoreByMemberCode(memberCode, productIdList); + if (CollectionUtils.isEmpty(scoredProducts)) { + return new ArrayList<>(); + } + + // 获取顾客的平均购买价格 + double avgPrice = member.getAvePrice(); + + double priceVariance = member.getPriceVariance(); + + double priceStdDev = Math.sqrt(priceVariance); + + double lowerBound = avgPrice - 2 * priceStdDev; + double upperBound = avgPrice + 2 * priceStdDev; + + +// // 按照商品价格与平均价格的接近程度进行排序 +// List sortedProducts = scoredProducts.stream() +// .sorted(Comparator.comparingDouble(p -> Math.abs(p.getPriceSales() - avgPrice))) +// .collect(Collectors.toList()); // -// List sizeList = new ArrayList<>(); -// if (mostFrequentSize.contains(",")) { -// sizeList = Arrays.asList(mostFrequentSize.split(",")); -// }else { -// sizeList.add(mostFrequentSize); -// } +// // 计算总商品数量和6:2的比例 +// int totalProducts = sortedProducts.size(); +// int closeToAverageCount = (int) Math.round(totalProducts * 0.75); // 6/8 = 0.75 +// int notCloseToAverageCount = totalProducts - closeToAverageCount; // -// List subCatList = new ArrayList<>(); -// if (mostFrequentSubCat.contains(",")) { -// subCatList = Arrays.asList(mostFrequentSubCat.split(",")); -// }else { -// subCatList.add(mostFrequentSubCat); -// } +// // 选择最接近均价的75%商品 +// List closeToAverage = sortedProducts.stream() +// .limit(closeToAverageCount) +// .collect(Collectors.toList()); // -// String memberType = miTuMembers.get(0).getMemberType(); -// switch (memberType) { -// case "Type D" : { -// // 根据牌子、款式、颜色推荐 -// QueryWrapper miTuProductQueryWrapper = new QueryWrapper<>(); -// miTuProductQueryWrapper.lambda().in(MiTuProduct::getColor, colorList); -// List miTuProductList = miTuProductMapper.selectList(miTuProductQueryWrapper); -// if (CollectionUtils.isEmpty(miTuProductList)) { -// return new ArrayList<>(); -// } -// Set collect = miTuProductList.stream().map(MiTuProduct::getProductId).collect(Collectors.toSet()); -// if (CollectionUtils.isEmpty(collect)) { -// return new ArrayList<>(); -// } -// return new ArrayList<>(collect); -// } -// case "Type i" : { -// QueryWrapper miTuProductQueryWrapper = new QueryWrapper<>(); -// miTuProductQueryWrapper.lambda().eq(MiTuProduct::getYear, "TE"); -// miTuProductQueryWrapper.lambda().eq(MiTuProduct::getSeason, "A"); -// List miTuProductList = miTuProductMapper.selectList(miTuProductQueryWrapper); -// if (CollectionUtils.isEmpty(miTuProductList)) { -// return new ArrayList<>(); -// } -// Set collect = miTuProductList.stream().map(MiTuProduct::getProductId).collect(Collectors.toSet()); -// if (CollectionUtils.isEmpty(collect)) { -// return new ArrayList<>(); -// } -// return new ArrayList<>(collect); -// } -// case "Type C" : { -// -// QueryWrapper miTuProductQueryWrapper = new QueryWrapper<>(); -// miTuProductQueryWrapper.lambda().eq(MiTuProduct::getSubGroup, "TWIN SET"); -// List miTuProductList = miTuProductMapper.selectList(miTuProductQueryWrapper); -// if (CollectionUtils.isEmpty(miTuProductList)) { -// return new ArrayList<>(); -// } -// Set collect = miTuProductList.stream().map(MiTuProduct::getProductId).collect(Collectors.toSet()); -// if (CollectionUtils.isEmpty(collect)) { -// return new ArrayList<>(); -// } -// return new ArrayList<>(collect); -// } -// case "Type S" : { -// // Sell through 前20 -// Map productIdNumMap = appProductService.getProductIdListByQueryType(3, null); -// List collect = productIdNumMap.keySet().stream().collect(Collectors.toList()); -// if (CollectionUtils.isEmpty(collect)) { -// return new ArrayList<>(); -// } -// return collect; -// } -// default : -// throw new BusinessException("Unknown memberType."); -// } +// // 选择不太接近均价的25%商品 +// List notCloseToAverage = sortedProducts.stream() +// .skip(closeToAverageCount) +// .collect(Collectors.toList()); + + // 选择靠近均价的商品 + List closeToAverage = scoredProducts.stream() + .filter(p -> p.getPriceSales() >= lowerBound && p.getPriceSales() <= upperBound) + .collect(Collectors.toList()); + + // 选择不太靠近均价的商品 + List notCloseToAverage = scoredProducts.stream() + .filter(p -> p.getPriceSales() < lowerBound || p.getPriceSales() > upperBound) + .collect(Collectors.toList()); + + + // 获取重仓商品列表 + List heavyStockPluCodes = getHeavyStockProduct(); + QueryWrapper heavyStockQw = new QueryWrapper<>(); + heavyStockQw.lambda().in(MiTuProduct::getPluCode, heavyStockPluCodes); + List heavyStockProducts = miTuProductMapper.selectList(heavyStockQw); + + // 最终推荐的商品列表 + List recommendedProducts = new ArrayList<>(); + Set usedProductIds = new HashSet<>(); // 用来记录已经使用过的商品 + + for (int i = 0; i < 3; i++) { // 循环处理3页数据 + List pageProducts = new ArrayList<>(); + + // 1. 按照打分顺序填充,先从靠近均价的商品列表中填充6件商品 + for (MiTuProduct product : scoredProducts) { + if (closeToAverage.contains(product) && pageProducts.size() < 6) { + if (!usedProductIds.contains(product.getProductId())) { + pageProducts.add(product); + usedProductIds.add(product.getProductId()); + } + } + // 每页最多6个产品 + if (pageProducts.size() >= 6) break; + } + + for (MiTuProduct product : scoredProducts) { + // 2. 从不靠近均价的商品列表中填充2件商品 + if (notCloseToAverage.contains(product) && pageProducts.size() < 8) { + if (!usedProductIds.contains(product.getProductId())) { + pageProducts.add(product); + usedProductIds.add(product.getProductId()); + } + } + + // 每页最多10个产品 + if (pageProducts.size() >= 8) break; + } + + // 3. 从重仓商品列表中填充2件商品,并确保不重复 + int heavyStockCount = 0; + for (MiTuProduct product : heavyStockProducts) { + if (heavyStockCount >= 2) break; + if (!usedProductIds.contains(product.getProductId()) && !pageProducts.contains(product)) { + pageProducts.add(product); + usedProductIds.add(product.getProductId()); + heavyStockCount++; + } + } + + // 4. 如果重仓商品不够2件,从靠近均价的商品中补充 + if (heavyStockCount < 2) { + for (MiTuProduct product : closeToAverage) { + if (heavyStockCount >= 2) break; + if (!usedProductIds.contains(product.getProductId())) { + pageProducts.add(product); + usedProductIds.add(product.getProductId()); + heavyStockCount++; + } + } + } + + // 将这一页的商品加入最终推荐列表 + recommendedProducts.addAll(pageProducts); + + // 从已使用列表中移除本页使用的商品 + closeToAverage.removeAll(pageProducts); + notCloseToAverage.removeAll(pageProducts); + heavyStockProducts.removeAll(pageProducts); + } + + // 确保推荐商品的数量足够,并返回最终的商品ID列表 + return recommendedProducts.stream() + .limit(30) // 确保不超过3页(30件)商品 + .map(MiTuProduct::getProductId) + .collect(Collectors.toList()); + } + +// private List pickProducts(List products, int count) { +// return products.stream().limit(count).collect(Collectors.toList()); +// } + + private List getProductIdListByMemberType(MiTuMember member) { + String memberType = member.getMemberType(); + switch (memberType) { + case "Type D" : { + // 根据颜色、尺寸、sub_cat、category筛选 + QueryWrapper miTuProductQueryWrapper = new QueryWrapper<>(); + miTuProductQueryWrapper.lambda() + .like(MiTuProduct::getColor, member.getMostFrequentColor()) + .or() + .like(MiTuProduct::getSize, member.getMostFrequentSize()) + .or() + .like(MiTuProduct::getSubGroup, member.getMostFrequentSubCat()) + .or() + .like(MiTuProduct::getItemGroup, member.getMostFrequentCategory()); + List miTuProductList = miTuProductMapper.selectList(miTuProductQueryWrapper); + if (CollectionUtils.isEmpty(miTuProductList)) { + return new ArrayList<>(); + } + Set collect = miTuProductList.stream().map(MiTuProduct::getProductId).collect(Collectors.toSet()); + if (CollectionUtils.isEmpty(collect)) { + return new ArrayList<>(); + } + return new ArrayList<>(collect); + } + case "Type i" : { + QueryWrapper miTuProductQueryWrapper = new QueryWrapper<>(); + miTuProductQueryWrapper.lambda().eq(MiTuProduct::getYear, "TE"); + miTuProductQueryWrapper.lambda().eq(MiTuProduct::getSeason, "A"); + List miTuProductList = miTuProductMapper.selectList(miTuProductQueryWrapper); + if (CollectionUtils.isEmpty(miTuProductList)) { + return new ArrayList<>(); + } + Set collect = miTuProductList.stream().map(MiTuProduct::getProductId).collect(Collectors.toSet()); + if (CollectionUtils.isEmpty(collect)) { + return new ArrayList<>(); + } + return new ArrayList<>(collect); + } + case "Type C" : { + + QueryWrapper miTuProductQueryWrapper = new QueryWrapper<>(); + miTuProductQueryWrapper.lambda().eq(MiTuProduct::getSubGroup, "TWIN SET"); + List miTuProductList = miTuProductMapper.selectList(miTuProductQueryWrapper); + if (CollectionUtils.isEmpty(miTuProductList)) { + return new ArrayList<>(); + } + Set collect = miTuProductList.stream().map(MiTuProduct::getProductId).collect(Collectors.toSet()); + if (CollectionUtils.isEmpty(collect)) { + return new ArrayList<>(); + } + return new ArrayList<>(collect); + } + case "Type S" : { + // 卖的最好 前24 + Map productIdNumMap = appProductService.getProductIdListByQueryType(3, null); + List collect = productIdNumMap.keySet().stream().collect(Collectors.toList()); + if (CollectionUtils.isEmpty(collect)) { + return new ArrayList<>(); + } + return collect; + } + default : + throw new BusinessException("Unknown memberType."); + } + } + + static final String JDBC_DRIVER = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; + static final String DB_URL = "jdbc:sqlserver://118.142.0.178:1550;databaseName=Hayman_prod"; + + // 数据库凭据 + static final String USER = "user01"; + static final String PASS = "haySIS-0522"; + private List getHeavyStockProduct() { + List result = new ArrayList<>(); + Connection conn = null; + Statement stmt = null; + try { + Class.forName(JDBC_DRIVER); + conn = DriverManager.getConnection(DB_URL, USER, PASS); + stmt = conn.createStatement(); + + String sql = "SELECT plu_code\n" + + "FROM v_MZG003A\n" + + "WHERE TTL_QTY >= 30"; + + ResultSet rs = stmt.executeQuery(sql); + + while (rs.next()) { + String pluCode = rs.getString("plu_code"); + result.add(pluCode); + } + 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!"); + return result; } } diff --git a/src/main/resources/mapper/MiTuProductMapper.xml b/src/main/resources/mapper/MiTuProductMapper.xml index 6a71696..bbffb62 100644 --- a/src/main/resources/mapper/MiTuProductMapper.xml +++ b/src/main/resources/mapper/MiTuProductMapper.xml @@ -82,4 +82,66 @@ ORDER BY score DESC LIMIT 30 + +