From cde9bbbb004bb909dda6c6a0e88e78c67d5acf2a Mon Sep 17 00:00:00 2001 From: shahaibo <1023316923@qq.com> Date: Thu, 1 Aug 2024 13:21:09 +0800 Subject: [PATCH] TASK:mixi; --- .../common/tasks/MiTuExportScheduledTask.java | 477 +++++++++++++++++- .../tasks/mituExportEntity/Transaction.java | 1 + .../mixi/controller/AppProductController.java | 24 + .../controller/SalesIncentivesController.java | 48 ++ .../com/mixi/mapper/MiTuProductMapper.java | 3 + .../com/mixi/mapper/SalesRecordMapper.java | 7 + .../com/mixi/mapper/TaskConditionMapper.java | 7 + .../java/com/mixi/mapper/TaskRuleMapper.java | 7 + .../com/mixi/mapper/entity/MiTuMember.java | 1 + .../com/mixi/mapper/entity/SalesRecord.java | 48 ++ .../com/mixi/mapper/entity/TaskCondition.java | 33 ++ .../java/com/mixi/mapper/entity/TaskRule.java | 29 ++ .../com/mixi/model/dto/AIRecommendDTO.java | 9 + .../mixi/model/dto/SearchProductPageDTO.java | 4 + .../java/com/mixi/model/dto/TaskRuleDTO.java | 12 + .../com/mixi/model/dto/TaskRuleQuery.java | 13 + .../mixi/model/vo/OutfitRecommendation.java | 12 + .../com/mixi/model/vo/SalesRankingVO.java | 11 + .../java/com/mixi/model/vo/TaskRuleVO.java | 13 + .../mixi/schedule/ReCollocationSchedule.java | 2 +- .../java/com/mixi/service/PythonService.java | 51 ++ .../mixi/service/SalesIncentivesService.java | 17 + .../com/mixi/service/TAppProductService.java | 74 +++ .../com/mixi/service/TProductService.java | 18 +- .../service/impl/MiTuExportServiceImpl.java | 177 ++++--- .../impl/SalesIncentivesServiceImpl.java | 138 +++++ src/main/resources/application.properties | 2 +- .../resources/mapper/MiTuProductMapper.xml | 85 ++++ 28 files changed, 1216 insertions(+), 107 deletions(-) create mode 100644 src/main/java/com/mixi/controller/SalesIncentivesController.java create mode 100644 src/main/java/com/mixi/mapper/SalesRecordMapper.java create mode 100644 src/main/java/com/mixi/mapper/TaskConditionMapper.java create mode 100644 src/main/java/com/mixi/mapper/TaskRuleMapper.java create mode 100644 src/main/java/com/mixi/mapper/entity/SalesRecord.java create mode 100644 src/main/java/com/mixi/mapper/entity/TaskCondition.java create mode 100644 src/main/java/com/mixi/mapper/entity/TaskRule.java create mode 100644 src/main/java/com/mixi/model/dto/AIRecommendDTO.java create mode 100644 src/main/java/com/mixi/model/dto/TaskRuleDTO.java create mode 100644 src/main/java/com/mixi/model/dto/TaskRuleQuery.java create mode 100644 src/main/java/com/mixi/model/vo/OutfitRecommendation.java create mode 100644 src/main/java/com/mixi/model/vo/SalesRankingVO.java create mode 100644 src/main/java/com/mixi/model/vo/TaskRuleVO.java create mode 100644 src/main/java/com/mixi/service/SalesIncentivesService.java create mode 100644 src/main/java/com/mixi/service/impl/SalesIncentivesServiceImpl.java create mode 100644 src/main/resources/mapper/MiTuProductMapper.xml diff --git a/src/main/java/com/mixi/common/tasks/MiTuExportScheduledTask.java b/src/main/java/com/mixi/common/tasks/MiTuExportScheduledTask.java index 5712d7b..bd3900a 100644 --- a/src/main/java/com/mixi/common/tasks/MiTuExportScheduledTask.java +++ b/src/main/java/com/mixi/common/tasks/MiTuExportScheduledTask.java @@ -1,5 +1,6 @@ package com.mixi.common.tasks; +import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.mixi.common.tasks.mituExportEntity.*; import com.mixi.common.utils.CopyUtil; @@ -17,6 +18,7 @@ import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.commons.CommonsMultipartFile; @@ -57,13 +59,15 @@ public class MiTuExportScheduledTask { private MiTuProductSellNumMapper miTuProductSellNumMapper; @PostConstruct public void executeWeeklyHeavyStockReport() { - customerPurchaseReport(); +// customerPurchaseReport(); // NewJoinVIPReport(); // weeklySellThrReport(); // WeeklyHeavyStockReport(); // QuarterlyProductGroupingReport(); // customerTypeAnalysis(); // getBestSell(); +// getData(); +// dailySalesIncentiveStatistics(); } // public static void main(String[] args) { @@ -1869,6 +1873,7 @@ public class MiTuExportScheduledTask { public Map mostFrequentColorMap = new HashMap<>(); public Map mostFrequentSizeMap = new HashMap<>(); public Map mostFrequentSubCatMap = new HashMap<>(); + public Map mostFrequentCategoryMap = new HashMap<>(); public Map avePriceMap = new HashMap<>(); private List getMemberType(List memberCodeList) { @@ -1885,6 +1890,7 @@ public class MiTuExportScheduledTask { miTuMember.setMostFrequentColor(mostFrequentColorMap.get(miTuMember.getMbrCode())); miTuMember.setMostFrequentSize(mostFrequentSizeMap.get(miTuMember.getMbrCode())); miTuMember.setMostFrequentSubCat(mostFrequentSubCatMap.get(miTuMember.getMbrCode())); + miTuMember.setMostFrequentCategory(mostFrequentCategoryMap.get(miTuMember.getMbrCode())); miTuMember.setAvePrice(avePriceMap.get(miTuMember.getMbrCode())); miTuMemberList.add(miTuMember); } @@ -1899,7 +1905,14 @@ public class MiTuExportScheduledTask { miTuMember.setMemberType("Type S"); } } - miTuMemberMapper.insert(miTuMember); + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(MiTuMember::getMbrCode, miTuMember.getMbrCode()); + List miTuMembers = miTuMemberMapper.selectList(qw); + if (CollectionUtils.isEmpty(miTuMembers)) { + miTuMemberMapper.insert(miTuMember); + }else { + miTuMemberMapper.update(miTuMember, qw); + } } return miTuMemberList; } @@ -2023,11 +2036,12 @@ public class MiTuExportScheduledTask { } transaction.setYear(rs.getString("YEAR")); transaction.setSeason(rs.getString("SEASON")); - transaction.setColor(rs.getString("COLOR")); - transaction.setSubCat(rs.getString("SUB_CAT")); -// transaction.setCategory(rs.getString("CATEGORY")); + transaction.setSize(rs.getString("SIZE")); + transaction.setColor(rs.getString("COLOR")); transaction.setNetAmt(rs.getDouble("net_amt")); + transaction.setSubCat(rs.getString("SUB_CAT")); + transaction.setCategory(rs.getString("CATEGORY")); transactionList.add(transaction); } @@ -2051,6 +2065,7 @@ public class MiTuExportScheduledTask { Map colorCountMap = new HashMap<>(); Map sizeCountMap = new HashMap<>(); Map subCatCountMap = new HashMap<>(); + Map categoryCountMap = new HashMap<>(); int totalCount = transactionList.size(); double totalPrice = 0; @@ -2066,6 +2081,9 @@ public class MiTuExportScheduledTask { String subCat = transaction.getSubCat(); subCatCountMap.put(subCat, subCatCountMap.getOrDefault(size, 0) + 1); + + String category = transaction.getCategory(); + categoryCountMap.put(category, categoryCountMap.getOrDefault(size, 0) + 1); } if (totalCount > 0) { @@ -2100,10 +2118,10 @@ public class MiTuExportScheduledTask { double sizeVariance = sizeVarianceSum / sizeCountMap.size(); // 计算SUBCAT的方差 - double subCatMean = (double) totalCount / sizeCountMap.size(); + double subCatMean = (double) totalCount / subCatCountMap.size(); double subCatVarianceSum = 0; int maxSubCatCount = 0; - for (Map.Entry entry : sizeCountMap.entrySet()) { + for (Map.Entry entry : subCatCountMap.entrySet()) { int count = entry.getValue(); subCatVarianceSum += Math.pow(count - subCatMean, 2); if (count > maxSubCatCount) { @@ -2112,6 +2130,19 @@ public class MiTuExportScheduledTask { } double subCatVariance = subCatVarianceSum / subCatCountMap.size(); + // 计算category的方差 + double categoryMean = (double) totalCount / categoryCountMap.size(); + double categoryVarianceSum = 0; + int maxCategoryCount = 0; + for (Map.Entry entry : categoryCountMap.entrySet()) { + int count = entry.getValue(); + categoryVarianceSum += Math.pow(count - categoryMean, 2); + if (count > maxCategoryCount) { + maxCategoryCount = count; + } + } + double categoryVariance = categoryVarianceSum / categoryCountMap.size(); + // 获取出现次数最多的颜色 int finalMaxColorCount = maxColorCount; List mostFrequentColors = colorCountMap.entrySet().stream() @@ -2129,13 +2160,21 @@ public class MiTuExportScheduledTask { String size = String.join(",", mostFrequentSizes); // 获取出现次数最多的SubCat - int finalMaxSubCatCount = maxSizeCount; - List mostFrequentSubCats = sizeCountMap.entrySet().stream() + int finalMaxSubCatCount = maxSubCatCount; + List mostFrequentSubCats = subCatCountMap.entrySet().stream() .filter(entry -> entry.getValue() == finalMaxSubCatCount) .map(Map.Entry::getKey) .collect(Collectors.toList()); String subCat = String.join(",", mostFrequentSubCats); + // 获取出现次数最多的category + int finalMaxCategoryCount = maxCategoryCount; + List mostFrequentCategory = categoryCountMap.entrySet().stream() + .filter(entry -> entry.getValue() == finalMaxCategoryCount) + .map(Map.Entry::getKey) + .collect(Collectors.toList()); + String category = String.join(",", mostFrequentCategory); + // 统计折扣和当季商品数量 for (Transaction transaction : transactionList) { if ((transaction.getDiscountPer() != null && transaction.getDiscountPer() >= 20.0) || transaction.getSubCat().equals("TWIN SET")) { @@ -2146,20 +2185,20 @@ public class MiTuExportScheduledTask { } } + double variance = (colorVariance + sizeVariance + subCatVariance + categoryVariance) / 4; + varianceMap.put(memberCode, variance); +// varianceMap.put(memberCode, sizeVariance); + mostFrequentColorMap.put(memberCode, mostFrequentColor); + mostFrequentSizeMap.put(memberCode, size); + mostFrequentSubCatMap.put(memberCode, subCat); + mostFrequentCategoryMap.put(memberCode, category); + if (discountNum >= transactionList.size() * 0.5) { return "Type C"; } if (currentSeasonNum >= transactionList.size() * 0.7) { return "Type i"; } - - double variance = (colorVariance + sizeVariance + subCatVariance) / 3; - varianceMap.put(memberCode, variance); -// varianceMap.put(memberCode, sizeVariance); - mostFrequentColorMap.put(memberCode, mostFrequentColor); - mostFrequentSizeMap.put(memberCode, size); - mostFrequentSubCatMap.put(memberCode, subCat); - return null; } @@ -2217,4 +2256,408 @@ public class MiTuExportScheduledTask { return threeMonthsAgoDateTimeAsString; } + + @Resource + private TProductAttributeMapper productAttributeMapper; + + public void getData() { + QueryWrapper qw = new QueryWrapper<>(); + List productList = productMapper.selectList(qw); + Map map = new HashMap<>(); + for (TProduct tProduct : productList) { + Map aaa = new HashMap<>(); + QueryWrapper tProductAttributeQueryWrapper = new QueryWrapper<>(); + tProductAttributeQueryWrapper.eq("product_id", tProduct.getId()); + tProductAttributeQueryWrapper.eq("attribute_type", "Length"); + List tProductAttributes = productAttributeMapper.selectList(tProductAttributeQueryWrapper); + if (!CollectionUtils.isEmpty(tProductAttributes)) { + TProductAttribute tProductAttribute = tProductAttributes.get(0); + aaa.put("category", tProductAttribute.getAttributeItem()); + aaa.put("Length", tProductAttribute.getAttributeValue()); + } + map.put(tProduct.getPictureName(), aaa); + } + System.out.println(JSON.toJSONString(map)); + } + + @Resource + private SalesRecordMapper salesRecordMapper; + + public void dailySalesIncentiveStatistics() { + // 获取前一日所有商品销售记录 + + // 全日最高個人生意額 (每日計) + List saleRecordList = getSales(); + if (!CollectionUtils.isEmpty(saleRecordList)) { + Transaction transaction = saleRecordList.get(0); + SalesRecord salesRecord = new SalesRecord(); + salesRecord.setSalesmanName(transaction.getSalesmanName()); + salesRecord.setIncentiveNum(3); + salesRecord.setTaskId(1); + salesRecordMapper.insert(salesRecord); + } + + // 全日最高個人銷售件數 (每日計) + List saleRecordList1 = getSalesNumTop(); + if (!CollectionUtils.isEmpty(saleRecordList1)) { + int i = 0; + Transaction transaction = saleRecordList1.get(0); + Integer totalNum = transaction.getTotalNum(); + + for (int i1 = 1; i1 < saleRecordList1.size(); i1++) { + if (Objects.equals(saleRecordList1.get(i1).getTotalNum(), totalNum)) { + i ++; + } + } + + for (int i1 = 0; i1 < i; i1++) { + Transaction transaction1 = saleRecordList1.get(i1); + + SalesRecord salesRecord = new SalesRecord(); + salesRecord.setSalesmanName(transaction1.getSalesmanName()); + salesRecord.setIncentiveNum(3); + salesRecord.setTaskId(2); + salesRecordMapper.insert(salesRecord); + } + } + + List saleRecordList2 = getSalesByCategory(); + if (!CollectionUtils.isEmpty(saleRecordList2)) { + for (Transaction transaction : saleRecordList2) { + SalesRecord salesRecord = new SalesRecord(); + salesRecord.setSalesmanName(transaction.getSalesmanName()); + salesRecord.setIncentiveNum(transaction.getTotalNum()); + salesRecord.setTaskId(3); + salesRecordMapper.insert(salesRecord); + } + } + + List saleRecordList3 = getSalesByMultiSelling(); + if (!CollectionUtils.isEmpty(saleRecordList3)) { + for (Transaction transaction : saleRecordList3) { + SalesRecord salesRecord = new SalesRecord(); + salesRecord.setSalesmanName(transaction.getSalesmanName()); + salesRecord.setIncentiveNum(2); + salesRecord.setTaskId(4); + salesRecordMapper.insert(salesRecord); + } + } + + List saleRecordList4 = getSalesByPluCode(); + if (!CollectionUtils.isEmpty(saleRecordList4)) { + for (Transaction transaction : saleRecordList4) { + SalesRecord salesRecord = new SalesRecord(); + salesRecord.setSalesmanName(transaction.getSalesmanName()); + salesRecord.setIncentiveNum(2); + salesRecord.setTaskId(5); + salesRecordMapper.insert(salesRecord); + } + } + + + + + + } + + private List getSalesByPluCode() { + // 获取今日日期 + LocalDate today = LocalDate.now(); + + // 获取昨日日期 + LocalDate yesterday = today.minusDays(1); + + // 格式化日期 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + String todayStr = today.format(formatter); + String yesterdayStr = yesterday.format(formatter); + List result = new ArrayList<>(); + Connection conn = null; + Statement stmt = null; + try { + // 注册 JDBC 驱动器 + Class.forName(JDBC_DRIVER); + + // 打开一个连接 + System.out.println("连接数据库..."); + conn = DriverManager.getConnection(DB_URL, USER, PASS); + + // 执行查询 + System.out.println("创建声明..."); + stmt = conn.createStatement(); + String sql; + sql = "SELECT\n" + + "saleman_name\n" + + "FROM v_MZG016A\n" + + "WHERE trx_no IN \n" + + "(SELECT trx_no\n" + + " FROM V_MZG013\n" + + "WHERE trx_date >= '" + yesterdayStr + "'\n" + + "AND trx_date < '" + todayStr + "')\n" + + "AND plu_code in ('MTDTEAN29367','MTDTEAN29350')"; + + ResultSet rs = stmt.executeQuery(sql); + // 处理结果集 + while (rs.next()) { + Transaction transaction = new Transaction(); + transaction.setSalesmanName(rs.getString("saleman_name")); +// transaction.setTrxNo(rs.getString("trx_no")); + result.add(transaction); + } + + // 清理环境 + rs.close(); + stmt.close(); + conn.close(); + } catch (SQLException | ClassNotFoundException e) { + // 处理异常 + e.printStackTrace(); + } + System.out.println("查询执行完成!"); + return result; + } + + private List getSalesByMultiSelling() { + // 获取今日日期 + LocalDate today = LocalDate.now(); + + // 获取昨日日期 + LocalDate yesterday = today.minusDays(1); + + // 格式化日期 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + String todayStr = today.format(formatter); + String yesterdayStr = yesterday.format(formatter); + List result = new ArrayList<>(); + Connection conn = null; + Statement stmt = null; + try { + // 注册 JDBC 驱动器 + Class.forName(JDBC_DRIVER); + + // 打开一个连接 + System.out.println("连接数据库..."); + conn = DriverManager.getConnection(DB_URL, USER, PASS); + + // 执行查询 + System.out.println("创建声明..."); + stmt = conn.createStatement(); + String sql; + sql = "SELECT\n" + + "trx_no,\n" + + "saleman_name\n" + + "FROM v_MZG016A\n" + + "WHERE trx_no IN \n" + + "(SELECT\n" + + " trx_no\n" + + "FROM v_MZG016A\n" + + "WHERE trx_no IN \n" + + "(SELECT trx_no\n" + + " FROM V_MZG013\n" + + "WHERE trx_date >= '" + yesterdayStr + "'\n" + + "AND trx_date < '" + todayStr + "')\n" + + "GROUP BY trx_no\n" + + "HAVING COUNT(*) >= 4)\n" + + "GROUP BY trx_no, saleman_name"; + + ResultSet rs = stmt.executeQuery(sql); + // 处理结果集 + while (rs.next()) { + Transaction transaction = new Transaction(); + transaction.setSalesmanName(rs.getString("saleman_name")); + transaction.setTrxNo(rs.getString("trx_no")); + result.add(transaction); + } + + // 清理环境 + rs.close(); + stmt.close(); + conn.close(); + } catch (SQLException | ClassNotFoundException e) { + // 处理异常 + e.printStackTrace(); + } + System.out.println("查询执行完成!"); + return result; + } + + private List getSales() { + // 获取今日日期 + LocalDate today = LocalDate.now(); + + // 获取昨日日期 + LocalDate yesterday = today.minusDays(1); + + // 格式化日期 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + String todayStr = today.format(formatter); + String yesterdayStr = yesterday.format(formatter); + List result = new ArrayList<>(); + Connection conn = null; + Statement stmt = null; + try { + // 注册 JDBC 驱动器 + Class.forName(JDBC_DRIVER); + + // 打开一个连接 + System.out.println("连接数据库..."); + conn = DriverManager.getConnection(DB_URL, USER, PASS); + + // 执行查询 + System.out.println("创建声明..."); + stmt = conn.createStatement(); + String sql; + sql = "SELECT\n" + + "saleman_name,\n" + + "SUM(net_amt) AS total_net_amt\n" + + "FROM v_MZG016A\n" + + "WHERE trx_no in (SELECT trx_no FROM V_MZG013\n" + + "WHERE trx_date >= '" + yesterdayStr + "'\n" + + "AND trx_date < '" + todayStr + "'\n" + + "and pay_desc != 'Bonus'\n" + + "AND pay_desc != 'mi-tu Cash Coupon')\n" + + "GROUP BY saleman_name\n" + + "ORDER BY total_net_amt desc"; + + ResultSet rs = stmt.executeQuery(sql); + // 处理结果集 + while (rs.next()) { + Transaction transaction = new Transaction(); + transaction.setSalesmanName(rs.getString("saleman_name")); + transaction.setNetAmt(rs.getDouble("total_net_amt")); + result.add(transaction); + } + + // 清理环境 + rs.close(); + stmt.close(); + conn.close(); + } catch (SQLException | ClassNotFoundException e) { + // 处理异常 + e.printStackTrace(); + } + System.out.println("查询执行完成!"); + return result; + + } + + private List getSalesNumTop() { + // 获取今日日期 + LocalDate today = LocalDate.now(); + + // 获取昨日日期 + LocalDate yesterday = today.minusDays(1); + + // 格式化日期 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + String todayStr = today.format(formatter); + String yesterdayStr = yesterday.format(formatter); + List result = new ArrayList<>(); + Connection conn = null; + Statement stmt = null; + try { + // 注册 JDBC 驱动器 + Class.forName(JDBC_DRIVER); + + // 打开一个连接 + System.out.println("连接数据库..."); + conn = DriverManager.getConnection(DB_URL, USER, PASS); + + // 执行查询 + System.out.println("创建声明..."); + stmt = conn.createStatement(); + String sql; + sql = "SELECT\n" + + "saleman_name,\n" + + "COUNT(*) AS total_count\n" + + "FROM v_MZG016A\n" + + "WHERE trx_no in (SELECT trx_no FROM V_MZG013\n" + + "WHERE trx_date >= '" + yesterdayStr + "'\n" + + "AND trx_date < '" + todayStr + "')\n" + + "AND CAT_DESC != 'GIFT'\n" + + "GROUP BY saleman_name\n" + + "ORDER BY total_count desc"; + + ResultSet rs = stmt.executeQuery(sql); + // 处理结果集 + while (rs.next()) { + Transaction transaction = new Transaction(); + transaction.setSalesmanName(rs.getString("saleman_name")); + transaction.setTotalNum(rs.getInt("total_count")); + result.add(transaction); + } + + // 清理环境 + rs.close(); + stmt.close(); + conn.close(); + } catch (SQLException | ClassNotFoundException e) { + // 处理异常 + e.printStackTrace(); + } + System.out.println("查询执行完成!"); + return result; + + } + + private List getSalesByCategory() { + // 获取今日日期 + LocalDate today = LocalDate.now(); + + // 获取昨日日期 + LocalDate yesterday = today.minusDays(1); + + // 格式化日期 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + String todayStr = today.format(formatter); + String yesterdayStr = yesterday.format(formatter); + List result = new ArrayList<>(); + Connection conn = null; + Statement stmt = null; + try { + // 注册 JDBC 驱动器 + Class.forName(JDBC_DRIVER); + + // 打开一个连接 + System.out.println("连接数据库..."); + conn = DriverManager.getConnection(DB_URL, USER, PASS); + + // 执行查询 + System.out.println("创建声明..."); + stmt = conn.createStatement(); + String sql; + sql = "SELECT\n" + + "saleman_name,\n" + + "COUNT(*) AS total_count\n" + + "FROM v_MZG016A\n" + + "WHERE trx_no in (SELECT trx_no FROM V_MZG013\n" + + "WHERE trx_date >= '" + yesterdayStr + "'\n" + + "AND trx_date < '" + todayStr + "')\n" + + "AND YEAR = 'TE'\n" + + "AND SEASON = 'A'\n" + + "AND CATEGORY = 'ONE PIECE'\n" + + "GROUP BY saleman_name\n" + + "ORDER BY total_count desc"; + + ResultSet rs = stmt.executeQuery(sql); + // 处理结果集 + while (rs.next()) { + Transaction transaction = new Transaction(); + transaction.setSalesmanName(rs.getString("saleman_name")); + transaction.setTotalNum(rs.getInt("total_count")); + result.add(transaction); + } + + // 清理环境 + rs.close(); + stmt.close(); + conn.close(); + } catch (SQLException | ClassNotFoundException e) { + // 处理异常 + e.printStackTrace(); + } + System.out.println("查询执行完成!"); + return result; + + } } diff --git a/src/main/java/com/mixi/common/tasks/mituExportEntity/Transaction.java b/src/main/java/com/mixi/common/tasks/mituExportEntity/Transaction.java index 4b97a7b..4b8e9a3 100644 --- a/src/main/java/com/mixi/common/tasks/mituExportEntity/Transaction.java +++ b/src/main/java/com/mixi/common/tasks/mituExportEntity/Transaction.java @@ -84,4 +84,5 @@ public class Transaction { private String refNo; private String remark; private String mbrGroup; + private Integer totalNum; } diff --git a/src/main/java/com/mixi/controller/AppProductController.java b/src/main/java/com/mixi/controller/AppProductController.java index 0e21777..9d8b838 100644 --- a/src/main/java/com/mixi/controller/AppProductController.java +++ b/src/main/java/com/mixi/controller/AppProductController.java @@ -37,6 +37,8 @@ public class AppProductController { @Resource private MiTuExportService miTuExportService; + @Resource + private SalesIncentivesService salesIncentivesService; @ApiOperation(value = "新品推荐列表") @PostMapping("/queryNewProductPage") @@ -104,5 +106,27 @@ public class AppProductController { return Response.success(miTuExportService.queryMiTuMemberList(query.getPhone())); } + @ApiOperation(value = "激励任务规则分页查询") + @PostMapping("/queryPage") + public Response> queryPage(@Valid @RequestBody TaskRuleQuery taskRuleQuery) { + return Response.success(salesIncentivesService.queryPage(taskRuleQuery)); + } + @ApiOperation(value = "销售激励排名查询") + @PostMapping("/salesRanking") + public Response> salesRanking(@Valid @RequestBody TaskRuleQuery taskRuleQuery) { + return Response.success(salesIncentivesService.salesRanking(taskRuleQuery)); + } + + @ApiOperation(value = "AI推荐") + @PostMapping("/aiRecommend") + public Response aiRecommend(@Valid @RequestBody AIRecommendDTO aiRecommendDTO) { + return Response.success(tAppProductService.aiRecommend(aiRecommendDTO)); + } + + @ApiOperation(value = "问卷填写") + @PostMapping("/QEfilling") + public Response QEfilling(@Valid @RequestBody AIRecommendDTO aiRecommendDTO) { + return Response.success(tAppProductService.aiRecommend(aiRecommendDTO)); + } } diff --git a/src/main/java/com/mixi/controller/SalesIncentivesController.java b/src/main/java/com/mixi/controller/SalesIncentivesController.java new file mode 100644 index 0000000..cd1c8cf --- /dev/null +++ b/src/main/java/com/mixi/controller/SalesIncentivesController.java @@ -0,0 +1,48 @@ +package com.mixi.controller; + +import com.mixi.common.response.PageBaseResponse; +import com.mixi.common.response.Response; +import com.mixi.model.dto.TaskRuleDTO; +import com.mixi.model.dto.TaskRuleQuery; +import com.mixi.model.vo.SalesRankingVO; +import com.mixi.model.vo.TaskRuleVO; +import com.mixi.service.SalesIncentivesService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +@Api(tags = "销售激励") +@Slf4j +@RestController +@RequestMapping("/api/salesIncentives") +public class SalesIncentivesController { + + @Resource + private SalesIncentivesService salesIncentivesService; + + @ApiOperation(value = "新建激励任务规则") + @PostMapping("/addTask") + public Response addTask(@Valid @RequestBody TaskRuleDTO taskRuleDTO) { + return Response.success(salesIncentivesService.addTask(taskRuleDTO)); + } + + @ApiOperation(value = "激励任务规则分页查询") + @PostMapping("/queryPage") + public Response> queryPage(@Valid @RequestBody TaskRuleQuery taskRuleQuery) { + return Response.success(salesIncentivesService.queryPage(taskRuleQuery)); + } + + @ApiOperation(value = "销售激励排名查询") + @PostMapping("/salesRanking") + public Response> salesRanking(@Valid @RequestBody TaskRuleQuery taskRuleQuery) { + return Response.success(salesIncentivesService.salesRanking(taskRuleQuery)); + } +} diff --git a/src/main/java/com/mixi/mapper/MiTuProductMapper.java b/src/main/java/com/mixi/mapper/MiTuProductMapper.java index 27d5794..da1decc 100644 --- a/src/main/java/com/mixi/mapper/MiTuProductMapper.java +++ b/src/main/java/com/mixi/mapper/MiTuProductMapper.java @@ -4,6 +4,8 @@ package com.mixi.mapper; import com.mixi.common.config.mybatis.plus.CommonMapper; import com.mixi.mapper.entity.MiTuProduct; +import java.util.List; + /** * Mapper 接口 * @@ -12,4 +14,5 @@ import com.mixi.mapper.entity.MiTuProduct; */ public interface MiTuProductMapper extends CommonMapper { + List getTop30ScoreByMemberCode(String memberCode); } diff --git a/src/main/java/com/mixi/mapper/SalesRecordMapper.java b/src/main/java/com/mixi/mapper/SalesRecordMapper.java new file mode 100644 index 0000000..a222838 --- /dev/null +++ b/src/main/java/com/mixi/mapper/SalesRecordMapper.java @@ -0,0 +1,7 @@ +package com.mixi.mapper; + +import com.mixi.common.config.mybatis.plus.CommonMapper; +import com.mixi.mapper.entity.SalesRecord; + +public interface SalesRecordMapper extends CommonMapper { +} diff --git a/src/main/java/com/mixi/mapper/TaskConditionMapper.java b/src/main/java/com/mixi/mapper/TaskConditionMapper.java new file mode 100644 index 0000000..a366658 --- /dev/null +++ b/src/main/java/com/mixi/mapper/TaskConditionMapper.java @@ -0,0 +1,7 @@ +package com.mixi.mapper; + +import com.mixi.common.config.mybatis.plus.CommonMapper; +import com.mixi.mapper.entity.TaskCondition; + +public interface TaskConditionMapper extends CommonMapper { +} diff --git a/src/main/java/com/mixi/mapper/TaskRuleMapper.java b/src/main/java/com/mixi/mapper/TaskRuleMapper.java new file mode 100644 index 0000000..7a7593d --- /dev/null +++ b/src/main/java/com/mixi/mapper/TaskRuleMapper.java @@ -0,0 +1,7 @@ +package com.mixi.mapper; + +import com.mixi.common.config.mybatis.plus.CommonMapper; +import com.mixi.mapper.entity.TaskRule; + +public interface TaskRuleMapper extends CommonMapper { +} diff --git a/src/main/java/com/mixi/mapper/entity/MiTuMember.java b/src/main/java/com/mixi/mapper/entity/MiTuMember.java index c095d75..758ef69 100644 --- a/src/main/java/com/mixi/mapper/entity/MiTuMember.java +++ b/src/main/java/com/mixi/mapper/entity/MiTuMember.java @@ -30,5 +30,6 @@ public class MiTuMember implements Serializable { private String mostFrequentColor; private String mostFrequentSize; private String mostFrequentSubCat; + private String mostFrequentCategory; private double avePrice; } diff --git a/src/main/java/com/mixi/mapper/entity/SalesRecord.java b/src/main/java/com/mixi/mapper/entity/SalesRecord.java new file mode 100644 index 0000000..a5f26ba --- /dev/null +++ b/src/main/java/com/mixi/mapper/entity/SalesRecord.java @@ -0,0 +1,48 @@ +package com.mixi.mapper.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +@Data +@TableName("sales_incentive_result") +public class SalesRecord implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * ID + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * Task ID + */ + private Integer taskId; + + /** + * Salesman Name + */ + private String salesmanName; + + /** + * Incentive Number + */ + private Integer incentiveNum; + + /** + * Create Time + */ + private LocalDateTime createTime; + + /** + * Update Time + */ + private LocalDateTime updateTime; + + private Integer isDeleted; +} diff --git a/src/main/java/com/mixi/mapper/entity/TaskCondition.java b/src/main/java/com/mixi/mapper/entity/TaskCondition.java new file mode 100644 index 0000000..54b5416 --- /dev/null +++ b/src/main/java/com/mixi/mapper/entity/TaskCondition.java @@ -0,0 +1,33 @@ +package com.mixi.mapper.entity; + + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +@Data +public class TaskCondition implements Serializable { + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + private Long taskId; + + private String viewName; + + private String conditionField; + + private String conditionOperator; + + private String conditionValue; + + private Integer isDeleted = 0; + + private LocalDateTime createTime; + + private LocalDateTime updateTime; +} diff --git a/src/main/java/com/mixi/mapper/entity/TaskRule.java b/src/main/java/com/mixi/mapper/entity/TaskRule.java new file mode 100644 index 0000000..8d32643 --- /dev/null +++ b/src/main/java/com/mixi/mapper/entity/TaskRule.java @@ -0,0 +1,29 @@ +package com.mixi.mapper.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +@Data +public class TaskRule implements Serializable { + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + private String taskName; + + private String description; + + private Integer targetValue; + + private Integer isDeleted = 0; + + private LocalDateTime createTime; + + private LocalDateTime updateTime; + +} diff --git a/src/main/java/com/mixi/model/dto/AIRecommendDTO.java b/src/main/java/com/mixi/model/dto/AIRecommendDTO.java new file mode 100644 index 0000000..a1d947a --- /dev/null +++ b/src/main/java/com/mixi/model/dto/AIRecommendDTO.java @@ -0,0 +1,9 @@ +package com.mixi.model.dto; + +import lombok.Data; + +@Data +public class AIRecommendDTO { + private String userId; + private String inputMessage; +} diff --git a/src/main/java/com/mixi/model/dto/SearchProductPageDTO.java b/src/main/java/com/mixi/model/dto/SearchProductPageDTO.java index fbbafa3..0d5f769 100644 --- a/src/main/java/com/mixi/model/dto/SearchProductPageDTO.java +++ b/src/main/java/com/mixi/model/dto/SearchProductPageDTO.java @@ -26,4 +26,8 @@ public class SearchProductPageDTO extends PageQueryBaseVo implements Serializabl private String memberCode; + private String pluCode; + + private String color; + } diff --git a/src/main/java/com/mixi/model/dto/TaskRuleDTO.java b/src/main/java/com/mixi/model/dto/TaskRuleDTO.java new file mode 100644 index 0000000..ee9abe7 --- /dev/null +++ b/src/main/java/com/mixi/model/dto/TaskRuleDTO.java @@ -0,0 +1,12 @@ +package com.mixi.model.dto; + +import com.mixi.mapper.entity.TaskCondition; +import com.mixi.mapper.entity.TaskRule; +import lombok.Data; + +import java.util.List; + +@Data +public class TaskRuleDTO extends TaskRule { + private List taskConditionList; +} diff --git a/src/main/java/com/mixi/model/dto/TaskRuleQuery.java b/src/main/java/com/mixi/model/dto/TaskRuleQuery.java new file mode 100644 index 0000000..3e977d4 --- /dev/null +++ b/src/main/java/com/mixi/model/dto/TaskRuleQuery.java @@ -0,0 +1,13 @@ +package com.mixi.model.dto; + +import com.mixi.model.vo.PageQueryBaseVo; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class TaskRuleQuery extends PageQueryBaseVo { + private String startTime; + + private String endTime; +} diff --git a/src/main/java/com/mixi/model/vo/OutfitRecommendation.java b/src/main/java/com/mixi/model/vo/OutfitRecommendation.java new file mode 100644 index 0000000..af8cf85 --- /dev/null +++ b/src/main/java/com/mixi/model/vo/OutfitRecommendation.java @@ -0,0 +1,12 @@ +package com.mixi.model.vo; + +import lombok.Data; + +import java.util.List; + +@Data +public class OutfitRecommendation { + private List items; + private String reasons; + private List imageUrls; +} diff --git a/src/main/java/com/mixi/model/vo/SalesRankingVO.java b/src/main/java/com/mixi/model/vo/SalesRankingVO.java new file mode 100644 index 0000000..0446ce2 --- /dev/null +++ b/src/main/java/com/mixi/model/vo/SalesRankingVO.java @@ -0,0 +1,11 @@ +package com.mixi.model.vo; + +import lombok.Data; + +@Data +public class SalesRankingVO { + private String salesmanName; + + private Integer incentiveNum; + +} diff --git a/src/main/java/com/mixi/model/vo/TaskRuleVO.java b/src/main/java/com/mixi/model/vo/TaskRuleVO.java new file mode 100644 index 0000000..6fd53bf --- /dev/null +++ b/src/main/java/com/mixi/model/vo/TaskRuleVO.java @@ -0,0 +1,13 @@ +package com.mixi.model.vo; + +import com.mixi.mapper.TaskConditionMapper; +import com.mixi.mapper.entity.TaskCondition; +import com.mixi.mapper.entity.TaskRule; +import lombok.Data; + +import java.util.List; + +@Data +public class TaskRuleVO extends TaskRule { + public List taskConditionList; +} diff --git a/src/main/java/com/mixi/schedule/ReCollocationSchedule.java b/src/main/java/com/mixi/schedule/ReCollocationSchedule.java index edefe7a..7d621a1 100644 --- a/src/main/java/com/mixi/schedule/ReCollocationSchedule.java +++ b/src/main/java/com/mixi/schedule/ReCollocationSchedule.java @@ -21,7 +21,7 @@ public class ReCollocationSchedule { * @author yl * @since 2023-04-13 */ - @Scheduled(cron = "0 0 1 * * ?") +// @Scheduled(cron = "0 0 1 * * ?") // @Scheduled(cron = "0 0/2 * * * ?") public void websocketHeartBeatTask() { log.info("定时任务-商品重新搭配开始---------"); diff --git a/src/main/java/com/mixi/service/PythonService.java b/src/main/java/com/mixi/service/PythonService.java index 73f059c..f63c52f 100644 --- a/src/main/java/com/mixi/service/PythonService.java +++ b/src/main/java/com/mixi/service/PythonService.java @@ -13,6 +13,7 @@ import com.mixi.common.config.exception.BusinessException; import com.mixi.common.utils.AccessLimitUtils; import com.mixi.mapper.TProductMapper; import com.mixi.mapper.entity.TProduct; +import com.mixi.model.dto.AIRecommendDTO; import com.mixi.model.dto.GenerateCollocationDataBaseDTO; import com.mixi.model.dto.GenerateCollocationQueryDTO; import com.mixi.model.dto.GenerateCollocationQueryNewDTO; @@ -566,4 +567,54 @@ public class PythonService { } return productList; } + + public JSONObject getAIRecommend(AIRecommendDTO aiRecommendDTO) { + //限流校验 + AccessLimitUtils.validate("similarityMatch", 20); + OkHttpClient client = new OkHttpClient().newBuilder() + .connectTimeout(30, TimeUnit.SECONDS) + .pingInterval(5, TimeUnit.SECONDS)//websocket轮训间隔(单位:秒) + .readTimeout(300, TimeUnit.SECONDS)//读取超时(单位:秒) + .writeTimeout(300, TimeUnit.SECONDS)//写入超时(单位:秒) + .build(); + MediaType mediaType = MediaType.parse("application/json"); + Map content = Maps.newHashMap(); + content.put("input_message", "recommend an outfit"); + content.put("user_id", "user123"); + content.put("image_urls", "http://localhost:5001/chat"); + + RequestBody body = RequestBody.create(mediaType, JSON.toJSONString(content)); + Request request = new Request.Builder() +// .url(accessPythonIp + ":9993/api/similar_matchsimilar_match") + .url("http://192.168.1.3:5001/chat") + .method("POST", body) +// .addHeader("Authorization", "Basic YWlkbGFiOjEyMw==") + .addHeader("Content-Type", "application/json") + .build(); + Response response = null; + String bodyStr = null; + try { + log.info("获取python获取相似商品请求入参content###{}", JSON.toJSONString(content)); + response = client.newCall(request).execute(); + bodyStr = response.body().string(); + } catch (IOException ioException) { + log.error("PythonService##similarityMatch异常###{}", ExceptionUtil.getThrowableList(ioException)); + } + log.info("识获取python获取相似商品请求结果###{}", bodyStr.trim()); + //去除限流 + AccessLimitUtils.validateOut("similarityMatch"); + if (Objects.isNull(response)) { + log.error("PythonService##similarityMatch异常###{}", "response or body is empty!"); + throw new BusinessException("SimilarityMatch exception."); + } + JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(response)); + Boolean result = jsonObject.getBoolean("successful"); + if (result) { + JSONObject parseObject = JSON.parseObject(bodyStr.trim()); + return parseObject; + } + log.info("获取python获取相似商品请求异常###{}", jsonObject); + //生成失败 + throw new BusinessException("SimilarityMatch exception."); + } } diff --git a/src/main/java/com/mixi/service/SalesIncentivesService.java b/src/main/java/com/mixi/service/SalesIncentivesService.java new file mode 100644 index 0000000..912ac77 --- /dev/null +++ b/src/main/java/com/mixi/service/SalesIncentivesService.java @@ -0,0 +1,17 @@ +package com.mixi.service; + +import com.mixi.common.response.PageBaseResponse; +import com.mixi.model.dto.TaskRuleDTO; +import com.mixi.model.dto.TaskRuleQuery; +import com.mixi.model.vo.SalesRankingVO; +import com.mixi.model.vo.TaskRuleVO; + +import java.util.List; + +public interface SalesIncentivesService { + Boolean addTask(TaskRuleDTO taskConditionDTO); + + PageBaseResponse queryPage(TaskRuleQuery taskRuleQuery); + + List salesRanking(TaskRuleQuery taskRuleQuery); +} diff --git a/src/main/java/com/mixi/service/TAppProductService.java b/src/main/java/com/mixi/service/TAppProductService.java index c7493aa..8be5c39 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.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -12,6 +13,7 @@ import com.mixi.common.context.UserContext; import com.mixi.common.response.PageBaseResponse; import com.mixi.common.utils.*; import com.mixi.mapper.MiTuMemberMapper; +import com.mixi.mapper.MiTuProductMapper; import com.mixi.mapper.MiTuProductSellNumMapper; import com.mixi.mapper.TProductMapper; import com.mixi.mapper.entity.*; @@ -30,6 +32,8 @@ import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.function.Function; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -199,6 +203,7 @@ public class TAppProductService extends ServiceImpl { 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); List labelIds = productToLabelMap.values() @@ -574,6 +579,9 @@ public class TAppProductService extends ServiceImpl { * @param query * @returnN */ + + @Resource + private MiTuProductMapper miTuProductMapper; public PageBaseResponse searchProductPage(SearchProductPageDTO query) { // // 根据顾客获取对应商品推荐 // if (!StringUtils.isEmpty(query.getMemberCode())) { @@ -606,6 +614,28 @@ public class TAppProductService extends ServiceImpl { } queryWrapper.in("id", productIds); } + if (!StringUtils.isEmpty(query.getPluCode())) { + QueryWrapper miTuProductQueryWrapper = new QueryWrapper<>(); + miTuProductQueryWrapper.lambda().like(MiTuProduct::getPluCode, query.getPluCode()); + List miTuProductList = miTuProductMapper.selectList(miTuProductQueryWrapper); + if (!CollectionUtils.isEmpty(miTuProductList)) { + List collect = miTuProductList.stream().map(MiTuProduct::getProductId).collect(Collectors.toList()); + queryWrapper.in("id", collect); + }else { + return PageBaseResponse.success(new Page<>()); + } + } + if (!StringUtils.isEmpty(query.getColor())) { + QueryWrapper miTuProductQueryWrapper = new QueryWrapper<>(); + miTuProductQueryWrapper.lambda().like(MiTuProduct::getColor, query.getColor()); + List miTuProductList = miTuProductMapper.selectList(miTuProductQueryWrapper); + if (!CollectionUtils.isEmpty(miTuProductList)) { + List collect = miTuProductList.stream().map(MiTuProduct::getProductId).collect(Collectors.toList()); + queryWrapper.in("id", collect); + }else { + return PageBaseResponse.success(new Page<>()); + } + } //上架 queryWrapper.eq("on_sale_state", 1); @@ -677,4 +707,48 @@ public class TAppProductService extends ServiceImpl { + File.separator + userId + File.separator + UUID.randomUUID().toString(); } + public OutfitRecommendation aiRecommend(AIRecommendDTO aiRecommendDTO) { + + // 调用ai推荐模型 + JSONObject jsonObject = pythonService.getAIRecommend(aiRecommendDTO); + OutfitRecommendation recommendation = new OutfitRecommendation(); + + // 从 JSON 对象中提取 output 字符串 + String output = jsonObject.getString("output"); + + // 提取服装描述 + Pattern descriptionPattern = Pattern.compile("### Outfit Description:[\\s\\S]*?### Reasons for Recommendation:"); + Matcher descriptionMatcher = descriptionPattern.matcher(output); + if (descriptionMatcher.find()) { + String description = descriptionMatcher.group(); + String[] lines = description.split("\\n"); + for (String line : lines) { + if (line.startsWith("1.") || line.startsWith("2.") || line.startsWith("3.") || line.startsWith("4.") || line.startsWith("5.")) { + recommendation.getItems().add(line.trim()); + } + } + } + + // 提取理由 + Pattern reasonsPattern = Pattern.compile("### Reasons for Recommendation:[\\s\\S]*?### Reference Images:"); + Matcher reasonsMatcher = reasonsPattern.matcher(output); + if (reasonsMatcher.find()) { + String reasons = reasonsMatcher.group(); + recommendation.setReasons(reasons.trim()); + } + + // 提取参考图片 + Pattern imagesPattern = Pattern.compile("### Reference Images:[\\s\\S]*"); + Matcher imagesMatcher = imagesPattern.matcher(output); + if (imagesMatcher.find()) { + String images = imagesMatcher.group(); + Pattern imagePattern = Pattern.compile("\\!\\[.*?\\]\\((.*?)\\)"); + Matcher imageMatcher = imagePattern.matcher(images); + while (imageMatcher.find()) { + recommendation.getImageUrls().add(imageMatcher.group(1)); + } + } + + return recommendation; + } } diff --git a/src/main/java/com/mixi/service/TProductService.java b/src/main/java/com/mixi/service/TProductService.java index 9247b51..7bbe388 100644 --- a/src/main/java/com/mixi/service/TProductService.java +++ b/src/main/java/com/mixi/service/TProductService.java @@ -127,15 +127,23 @@ public class TProductService extends ServiceImpl { QueryWrapper miTuProductQueryWrapper = new QueryWrapper<>(); miTuProductQueryWrapper.lambda().like(MiTuProduct::getPluCode, query.getPluCode()); List miTuProductList = miTuProductMapper.selectList(miTuProductQueryWrapper); - List collect = miTuProductList.stream().map(MiTuProduct::getProductId).collect(Collectors.toList()); - queryWrapper.in("id", collect); + if (!CollectionUtils.isEmpty(miTuProductList)) { + List collect = miTuProductList.stream().map(MiTuProduct::getProductId).collect(Collectors.toList()); + queryWrapper.in("id", collect); + }else { + return PageBaseResponse.success(new Page<>()); + } } if (!StringUtils.isEmpty(query.getColor())) { QueryWrapper miTuProductQueryWrapper = new QueryWrapper<>(); miTuProductQueryWrapper.lambda().like(MiTuProduct::getColor, query.getColor()); List miTuProductList = miTuProductMapper.selectList(miTuProductQueryWrapper); - List collect = miTuProductList.stream().map(MiTuProduct::getProductId).collect(Collectors.toList()); - queryWrapper.in("id", collect); + if (!CollectionUtils.isEmpty(miTuProductList)) { + List collect = miTuProductList.stream().map(MiTuProduct::getProductId).collect(Collectors.toList()); + queryWrapper.in("id", collect); + }else { + return PageBaseResponse.success(new Page<>()); + } } if (Objects.nonNull(query.getCreateDateStart())) { queryWrapper.ge("create_date", new Date(query.getCreateDateStart())); @@ -851,7 +859,7 @@ public class TProductService extends ServiceImpl { sql = "SELECT\n" + "WHCODE,\n" + "SIZE,\n" + - "count(1) as num\n" + + "SUM(ONLINE_QTY) as num\n" + "FROM v_MZG003A\n" + "WHERE plu_code = '" + pluCode + "'\n" + "AND COLOR = '" + color + "'\n" + diff --git a/src/main/java/com/mixi/service/impl/MiTuExportServiceImpl.java b/src/main/java/com/mixi/service/impl/MiTuExportServiceImpl.java index 8242814..d1cf1d8 100644 --- a/src/main/java/com/mixi/service/impl/MiTuExportServiceImpl.java +++ b/src/main/java/com/mixi/service/impl/MiTuExportServiceImpl.java @@ -145,91 +145,102 @@ public class MiTuExportServiceImpl implements MiTuExportService { @Override public List getProductIdsByMiTuMemberCode(String memberCode) { - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(MiTuMember::getMbrCode, memberCode); - List miTuMembers = miTuMemberMapper.selectList(qw); - if (CollectionUtils.isEmpty(miTuMembers)) { + List miTuProductList = miTuProductMapper.getTop30ScoreByMemberCode(memberCode); + if (CollectionUtils.isEmpty(miTuProductList)) { 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); - } - - List sizeList = new ArrayList<>(); - if (mostFrequentSize.contains(",")) { - sizeList = Arrays.asList(mostFrequentSize.split(",")); - }else { - sizeList.add(mostFrequentSize); - } - - List subCatList = new ArrayList<>(); - if (mostFrequentSubCat.contains(",")) { - subCatList = Arrays.asList(mostFrequentSubCat.split(",")); - }else { - subCatList.add(mostFrequentSubCat); - } - - 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."); +// 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); +// } +// +// List sizeList = new ArrayList<>(); +// if (mostFrequentSize.contains(",")) { +// sizeList = Arrays.asList(mostFrequentSize.split(",")); +// }else { +// sizeList.add(mostFrequentSize); +// } +// +// List subCatList = new ArrayList<>(); +// if (mostFrequentSubCat.contains(",")) { +// subCatList = Arrays.asList(mostFrequentSubCat.split(",")); +// }else { +// subCatList.add(mostFrequentSubCat); +// } +// +// 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."); +// } } } diff --git a/src/main/java/com/mixi/service/impl/SalesIncentivesServiceImpl.java b/src/main/java/com/mixi/service/impl/SalesIncentivesServiceImpl.java new file mode 100644 index 0000000..986899f --- /dev/null +++ b/src/main/java/com/mixi/service/impl/SalesIncentivesServiceImpl.java @@ -0,0 +1,138 @@ +package com.mixi.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.google.common.base.Function; +import com.mixi.common.config.exception.BusinessException; +import com.mixi.common.response.PageBaseResponse; +import com.mixi.common.utils.CopyUtil; +import com.mixi.mapper.SalesRecordMapper; +import com.mixi.mapper.TaskConditionMapper; +import com.mixi.mapper.TaskRuleMapper; +import com.mixi.mapper.entity.SalesRecord; +import com.mixi.mapper.entity.TAccount; +import com.mixi.mapper.entity.TaskCondition; +import com.mixi.mapper.entity.TaskRule; +import com.mixi.model.dto.TaskRuleDTO; +import com.mixi.model.dto.TaskRuleQuery; +import com.mixi.model.vo.SalesRankingVO; +import com.mixi.model.vo.TaskRuleVO; +import com.mixi.service.SalesIncentivesService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + +import javax.annotation.Resource; +import java.util.Date; +import java.util.List; +import java.util.Objects; + +@Slf4j +@Service +public class SalesIncentivesServiceImpl extends ServiceImpl implements SalesIncentivesService { + + @Resource + private TaskConditionMapper taskConditionMapper; + + @Resource + private TaskRuleMapper taskRuleMapper; + + @Resource + private SalesRecordMapper salesRecordMapper; + + @Override + public Boolean addTask(TaskRuleDTO taskRuleDTO) { + checkTaskName(taskRuleDTO); + + TaskRule taskRule = CopyUtil.copyObject(taskRuleDTO, TaskRule.class); + if (null == taskRule.getId()) { + taskRuleMapper.insert(taskRule); + + List taskConditionList = CopyUtil.copyList(taskRuleDTO.getTaskConditionList(), TaskCondition.class); + for (TaskCondition taskCondition : taskConditionList) { + taskConditionMapper.insert(taskCondition); + } + }else { + taskRuleMapper.updateById(taskRule); + + deleteBatchByTaskId(taskRule.getId()); + + List taskConditionList = CopyUtil.copyList(taskRuleDTO.getTaskConditionList(), TaskCondition.class); + for (TaskCondition taskCondition : taskConditionList) { + taskConditionMapper.insert(taskCondition); + } + } + return Boolean.TRUE; + } + + @Override + public PageBaseResponse queryPage(TaskRuleQuery taskRuleQuery) { + + // 分页数据 + QueryWrapper queryWrapper = new QueryWrapper<>(); + IPage page = getBaseMapper().selectPage( + new Page<>(taskRuleQuery.getPage(), taskRuleQuery.getSize()), queryWrapper); + if(CollectionUtils.isEmpty(page.getRecords())){ + return PageBaseResponse.success(new Page<>()); + } + + IPage convert = page.convert((Function) taskRule -> { + TaskRuleVO taskRuleVO = CopyUtil.copyObject(taskRule, TaskRuleVO.class); + + List taskConditionList = getTaskConditionListByTaskId(taskRuleVO.getId()); + taskRuleVO.setTaskConditionList(taskConditionList); + + return taskRuleVO; + }); + + return PageBaseResponse.success(convert); + } + + @Override + public List salesRanking(TaskRuleQuery taskRuleQuery) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + + // 根据查询参数中的起止时间条件构建查询 + if (taskRuleQuery.getStartTime() != null) { + queryWrapper.ge("create_time", taskRuleQuery.getStartTime()); + } + if (taskRuleQuery.getEndTime() != null) { + queryWrapper.le("create_time", taskRuleQuery.getEndTime()); + } + + queryWrapper.select("salesman_name, SUM(incentive_num) as incentiveNum") + .groupBy("salesman_name") + .orderByDesc("SUM(incentive_num)"); + + List salesRecords = salesRecordMapper.selectList(queryWrapper); + return CopyUtil.copyList(salesRecords, SalesRankingVO.class); + } + + private List getTaskConditionListByTaskId(Long id) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(TaskCondition::getTaskId, id); + return taskConditionMapper.selectList(qw); + } + + private void deleteBatchByTaskId(Long id) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(TaskCondition::getTaskId, id); + taskConditionMapper.delete(qw); + } + + private void checkTaskName(TaskRuleDTO taskRuleDTO) { + QueryWrapper qw = new QueryWrapper<>(); + if (null != taskRuleDTO.getId()) { + qw.lambda().ne(TaskRule::getId, taskRuleDTO.getId()); + } + qw.lambda().eq(TaskRule::getTaskName, taskRuleDTO.getTaskName()); + List taskRuleList = taskRuleMapper.selectList(qw); + if (!CollectionUtils.isEmpty(taskRuleList)) { + throw new BusinessException("The sales incentive rule name already exists."); + } + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 638dd7b..ce226a2 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -15,7 +15,7 @@ spring.security.jwtExpiration=8640000000 #spring security Full authentication is required to access this resource spring.security.ignorePaths=/,/favicon.ico,/doc.html,/webjars/**,/swagger-resources,/v2/api-docs,\ /api/account/**,/api/label/**,/api/python/**,/api/role/**,/api/product/**,/api/store/**,/api/attribute/**,\ - /api/app/account/**,/api/app/product/**,/api/app/custom/**,/api/miTuExport/** + /api/app/account/**,/api/app/product/**,/api/app/custom/**,/api/miTuExport/**,/api/salesIncentives/* spring.security.authApi=/auth/login #请求超级 6000秒 spring.mvc.async.request-timeout=6000000 diff --git a/src/main/resources/mapper/MiTuProductMapper.xml b/src/main/resources/mapper/MiTuProductMapper.xml new file mode 100644 index 0000000..6a71696 --- /dev/null +++ b/src/main/resources/mapper/MiTuProductMapper.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +