TASK:mixi;

This commit is contained in:
shahaibo
2024-08-01 13:21:09 +08:00
parent ed578f5ace
commit cde9bbbb00
28 changed files with 1216 additions and 107 deletions

View File

@@ -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<String, String> mostFrequentColorMap = new HashMap<>();
public Map<String, String> mostFrequentSizeMap = new HashMap<>();
public Map<String, String> mostFrequentSubCatMap = new HashMap<>();
public Map<String, String> mostFrequentCategoryMap = new HashMap<>();
public Map<String, Double> avePriceMap = new HashMap<>();
private List<MiTuMember> getMemberType(List<String> 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<MiTuMember> qw = new QueryWrapper<>();
qw.lambda().eq(MiTuMember::getMbrCode, miTuMember.getMbrCode());
List<MiTuMember> 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<String, Integer> colorCountMap = new HashMap<>();
Map<String, Integer> sizeCountMap = new HashMap<>();
Map<String, Integer> subCatCountMap = new HashMap<>();
Map<String, Integer> 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<String, Integer> entry : sizeCountMap.entrySet()) {
for (Map.Entry<String, Integer> 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<String, Integer> 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<String> mostFrequentColors = colorCountMap.entrySet().stream()
@@ -2129,13 +2160,21 @@ public class MiTuExportScheduledTask {
String size = String.join(",", mostFrequentSizes);
// 获取出现次数最多的SubCat
int finalMaxSubCatCount = maxSizeCount;
List<String> mostFrequentSubCats = sizeCountMap.entrySet().stream()
int finalMaxSubCatCount = maxSubCatCount;
List<String> 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<String> 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<TProduct> qw = new QueryWrapper<>();
List<TProduct> productList = productMapper.selectList(qw);
Map<String, Object> map = new HashMap<>();
for (TProduct tProduct : productList) {
Map<String, Object> aaa = new HashMap<>();
QueryWrapper<TProductAttribute> tProductAttributeQueryWrapper = new QueryWrapper<>();
tProductAttributeQueryWrapper.eq("product_id", tProduct.getId());
tProductAttributeQueryWrapper.eq("attribute_type", "Length");
List<TProductAttribute> 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<Transaction> 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<Transaction> 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<Transaction> 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<Transaction> 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<Transaction> 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<Transaction> 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<Transaction> 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<Transaction> 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<Transaction> 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<Transaction> 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<Transaction> 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<Transaction> 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<Transaction> 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<Transaction> 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<Transaction> 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;
}
}

View File

@@ -84,4 +84,5 @@ public class Transaction {
private String refNo;
private String remark;
private String mbrGroup;
private Integer totalNum;
}

View File

@@ -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<PageBaseResponse<TaskRuleVO>> queryPage(@Valid @RequestBody TaskRuleQuery taskRuleQuery) {
return Response.success(salesIncentivesService.queryPage(taskRuleQuery));
}
@ApiOperation(value = "销售激励排名查询")
@PostMapping("/salesRanking")
public Response<List<SalesRankingVO>> salesRanking(@Valid @RequestBody TaskRuleQuery taskRuleQuery) {
return Response.success(salesIncentivesService.salesRanking(taskRuleQuery));
}
@ApiOperation(value = "AI推荐")
@PostMapping("/aiRecommend")
public Response<OutfitRecommendation> aiRecommend(@Valid @RequestBody AIRecommendDTO aiRecommendDTO) {
return Response.success(tAppProductService.aiRecommend(aiRecommendDTO));
}
@ApiOperation(value = "问卷填写")
@PostMapping("/QEfilling")
public Response<OutfitRecommendation> QEfilling(@Valid @RequestBody AIRecommendDTO aiRecommendDTO) {
return Response.success(tAppProductService.aiRecommend(aiRecommendDTO));
}
}

View File

@@ -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<Boolean> addTask(@Valid @RequestBody TaskRuleDTO taskRuleDTO) {
return Response.success(salesIncentivesService.addTask(taskRuleDTO));
}
@ApiOperation(value = "激励任务规则分页查询")
@PostMapping("/queryPage")
public Response<PageBaseResponse<TaskRuleVO>> queryPage(@Valid @RequestBody TaskRuleQuery taskRuleQuery) {
return Response.success(salesIncentivesService.queryPage(taskRuleQuery));
}
@ApiOperation(value = "销售激励排名查询")
@PostMapping("/salesRanking")
public Response<List<SalesRankingVO>> salesRanking(@Valid @RequestBody TaskRuleQuery taskRuleQuery) {
return Response.success(salesIncentivesService.salesRanking(taskRuleQuery));
}
}

View File

@@ -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<MiTuProduct> {
List<MiTuProduct> getTop30ScoreByMemberCode(String memberCode);
}

View File

@@ -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<SalesRecord> {
}

View File

@@ -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<TaskCondition> {
}

View File

@@ -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<TaskRule> {
}

View File

@@ -30,5 +30,6 @@ public class MiTuMember implements Serializable {
private String mostFrequentColor;
private String mostFrequentSize;
private String mostFrequentSubCat;
private String mostFrequentCategory;
private double avePrice;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -0,0 +1,9 @@
package com.mixi.model.dto;
import lombok.Data;
@Data
public class AIRecommendDTO {
private String userId;
private String inputMessage;
}

View File

@@ -26,4 +26,8 @@ public class SearchProductPageDTO extends PageQueryBaseVo implements Serializabl
private String memberCode;
private String pluCode;
private String color;
}

View File

@@ -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<TaskCondition> taskConditionList;
}

View File

@@ -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;
}

View File

@@ -0,0 +1,12 @@
package com.mixi.model.vo;
import lombok.Data;
import java.util.List;
@Data
public class OutfitRecommendation {
private List<String> items;
private String reasons;
private List<String> imageUrls;
}

View File

@@ -0,0 +1,11 @@
package com.mixi.model.vo;
import lombok.Data;
@Data
public class SalesRankingVO {
private String salesmanName;
private Integer incentiveNum;
}

View File

@@ -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<TaskCondition> taskConditionList;
}

View File

@@ -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("定时任务-商品重新搭配开始---------");

View File

@@ -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<String, Object> 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.");
}
}

View File

@@ -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<TaskRuleVO> queryPage(TaskRuleQuery taskRuleQuery);
List<SalesRankingVO> salesRanking(TaskRuleQuery taskRuleQuery);
}

View File

@@ -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<TProductMapper, TProduct> {
if (CollectionUtils.isEmpty(page.getRecords())) {
return PageBaseResponse.success(new Page<>());
}
List<Long> collect = page.getRecords().stream().map(TProduct::getId).collect(Collectors.toList());
Map<Long,List<TProductLabel>> productToLabelMap = productLabelService.findByProductIds(collect);
List<Long> labelIds = productToLabelMap.values()
@@ -574,6 +579,9 @@ public class TAppProductService extends ServiceImpl<TProductMapper, TProduct> {
* @param query
* @returnN
*/
@Resource
private MiTuProductMapper miTuProductMapper;
public PageBaseResponse<AppNewProductVO> searchProductPage(SearchProductPageDTO query) {
// // 根据顾客获取对应商品推荐
// if (!StringUtils.isEmpty(query.getMemberCode())) {
@@ -606,6 +614,28 @@ public class TAppProductService extends ServiceImpl<TProductMapper, TProduct> {
}
queryWrapper.in("id", productIds);
}
if (!StringUtils.isEmpty(query.getPluCode())) {
QueryWrapper<MiTuProduct> miTuProductQueryWrapper = new QueryWrapper<>();
miTuProductQueryWrapper.lambda().like(MiTuProduct::getPluCode, query.getPluCode());
List<MiTuProduct> miTuProductList = miTuProductMapper.selectList(miTuProductQueryWrapper);
if (!CollectionUtils.isEmpty(miTuProductList)) {
List<Long> 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<MiTuProduct> miTuProductQueryWrapper = new QueryWrapper<>();
miTuProductQueryWrapper.lambda().like(MiTuProduct::getColor, query.getColor());
List<MiTuProduct> miTuProductList = miTuProductMapper.selectList(miTuProductQueryWrapper);
if (!CollectionUtils.isEmpty(miTuProductList)) {
List<Long> 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<TProductMapper, TProduct> {
+ 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;
}
}

View File

@@ -127,15 +127,23 @@ public class TProductService extends ServiceImpl<TProductMapper, TProduct> {
QueryWrapper<MiTuProduct> miTuProductQueryWrapper = new QueryWrapper<>();
miTuProductQueryWrapper.lambda().like(MiTuProduct::getPluCode, query.getPluCode());
List<MiTuProduct> miTuProductList = miTuProductMapper.selectList(miTuProductQueryWrapper);
List<Long> collect = miTuProductList.stream().map(MiTuProduct::getProductId).collect(Collectors.toList());
queryWrapper.in("id", collect);
if (!CollectionUtils.isEmpty(miTuProductList)) {
List<Long> 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<MiTuProduct> miTuProductQueryWrapper = new QueryWrapper<>();
miTuProductQueryWrapper.lambda().like(MiTuProduct::getColor, query.getColor());
List<MiTuProduct> miTuProductList = miTuProductMapper.selectList(miTuProductQueryWrapper);
List<Long> collect = miTuProductList.stream().map(MiTuProduct::getProductId).collect(Collectors.toList());
queryWrapper.in("id", collect);
if (!CollectionUtils.isEmpty(miTuProductList)) {
List<Long> 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<TProductMapper, TProduct> {
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" +

View File

@@ -145,91 +145,102 @@ public class MiTuExportServiceImpl implements MiTuExportService {
@Override
public List<Long> getProductIdsByMiTuMemberCode(String memberCode) {
QueryWrapper<MiTuMember> qw = new QueryWrapper<>();
qw.lambda().eq(MiTuMember::getMbrCode, memberCode);
List<MiTuMember> miTuMembers = miTuMemberMapper.selectList(qw);
if (CollectionUtils.isEmpty(miTuMembers)) {
List<MiTuProduct> 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<String> colorList = new ArrayList<>();
if (mostFrequentColor.contains(",")) {
colorList = Arrays.asList(mostFrequentColor.split(","));
}else {
colorList.add(mostFrequentColor);
}
List<String> sizeList = new ArrayList<>();
if (mostFrequentSize.contains(",")) {
sizeList = Arrays.asList(mostFrequentSize.split(","));
}else {
sizeList.add(mostFrequentSize);
}
List<String> 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<MiTuProduct> miTuProductQueryWrapper = new QueryWrapper<>();
miTuProductQueryWrapper.lambda().in(MiTuProduct::getColor, colorList);
List<MiTuProduct> miTuProductList = miTuProductMapper.selectList(miTuProductQueryWrapper);
if (CollectionUtils.isEmpty(miTuProductList)) {
return new ArrayList<>();
}
Set<Long> collect = miTuProductList.stream().map(MiTuProduct::getProductId).collect(Collectors.toSet());
if (CollectionUtils.isEmpty(collect)) {
return new ArrayList<>();
}
return new ArrayList<>(collect);
}
case "Type i" : {
QueryWrapper<MiTuProduct> miTuProductQueryWrapper = new QueryWrapper<>();
miTuProductQueryWrapper.lambda().eq(MiTuProduct::getYear, "TE");
miTuProductQueryWrapper.lambda().eq(MiTuProduct::getSeason, "A");
List<MiTuProduct> miTuProductList = miTuProductMapper.selectList(miTuProductQueryWrapper);
if (CollectionUtils.isEmpty(miTuProductList)) {
return new ArrayList<>();
}
Set<Long> collect = miTuProductList.stream().map(MiTuProduct::getProductId).collect(Collectors.toSet());
if (CollectionUtils.isEmpty(collect)) {
return new ArrayList<>();
}
return new ArrayList<>(collect);
}
case "Type C" : {
QueryWrapper<MiTuProduct> miTuProductQueryWrapper = new QueryWrapper<>();
miTuProductQueryWrapper.lambda().eq(MiTuProduct::getSubGroup, "TWIN SET");
List<MiTuProduct> miTuProductList = miTuProductMapper.selectList(miTuProductQueryWrapper);
if (CollectionUtils.isEmpty(miTuProductList)) {
return new ArrayList<>();
}
Set<Long> 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<Long, Integer> productIdNumMap = appProductService.getProductIdListByQueryType(3, null);
List<Long> collect = productIdNumMap.keySet().stream().collect(Collectors.toList());
if (CollectionUtils.isEmpty(collect)) {
return new ArrayList<>();
}
return collect;
}
default :
throw new BusinessException("Unknown memberType.");
// List<Long> result = new ArrayList<>();
// int i = 0;
// while (result.size() <= 30) {
//
// }
return miTuProductList.stream().map(MiTuProduct::getProductId).collect(Collectors.toList());
}
// QueryWrapper<MiTuMember> qw = new QueryWrapper<>();
// qw.lambda().eq(MiTuMember::getMbrCode, memberCode);
// List<MiTuMember> 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<String> colorList = new ArrayList<>();
// if (mostFrequentColor.contains(",")) {
// colorList = Arrays.asList(mostFrequentColor.split(","));
// }else {
// colorList.add(mostFrequentColor);
// }
//
// List<String> sizeList = new ArrayList<>();
// if (mostFrequentSize.contains(",")) {
// sizeList = Arrays.asList(mostFrequentSize.split(","));
// }else {
// sizeList.add(mostFrequentSize);
// }
//
// List<String> 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<MiTuProduct> miTuProductQueryWrapper = new QueryWrapper<>();
// miTuProductQueryWrapper.lambda().in(MiTuProduct::getColor, colorList);
// List<MiTuProduct> miTuProductList = miTuProductMapper.selectList(miTuProductQueryWrapper);
// if (CollectionUtils.isEmpty(miTuProductList)) {
// return new ArrayList<>();
// }
// Set<Long> collect = miTuProductList.stream().map(MiTuProduct::getProductId).collect(Collectors.toSet());
// if (CollectionUtils.isEmpty(collect)) {
// return new ArrayList<>();
// }
// return new ArrayList<>(collect);
// }
// case "Type i" : {
// QueryWrapper<MiTuProduct> miTuProductQueryWrapper = new QueryWrapper<>();
// miTuProductQueryWrapper.lambda().eq(MiTuProduct::getYear, "TE");
// miTuProductQueryWrapper.lambda().eq(MiTuProduct::getSeason, "A");
// List<MiTuProduct> miTuProductList = miTuProductMapper.selectList(miTuProductQueryWrapper);
// if (CollectionUtils.isEmpty(miTuProductList)) {
// return new ArrayList<>();
// }
// Set<Long> collect = miTuProductList.stream().map(MiTuProduct::getProductId).collect(Collectors.toSet());
// if (CollectionUtils.isEmpty(collect)) {
// return new ArrayList<>();
// }
// return new ArrayList<>(collect);
// }
// case "Type C" : {
//
// QueryWrapper<MiTuProduct> miTuProductQueryWrapper = new QueryWrapper<>();
// miTuProductQueryWrapper.lambda().eq(MiTuProduct::getSubGroup, "TWIN SET");
// List<MiTuProduct> miTuProductList = miTuProductMapper.selectList(miTuProductQueryWrapper);
// if (CollectionUtils.isEmpty(miTuProductList)) {
// return new ArrayList<>();
// }
// Set<Long> 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<Long, Integer> productIdNumMap = appProductService.getProductIdListByQueryType(3, null);
// List<Long> collect = productIdNumMap.keySet().stream().collect(Collectors.toList());
// if (CollectionUtils.isEmpty(collect)) {
// return new ArrayList<>();
// }
// return collect;
// }
// default :
// throw new BusinessException("Unknown memberType.");
// }
}
}

View File

@@ -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<TaskRuleMapper, TaskRule> 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<TaskCondition> taskConditionList = CopyUtil.copyList(taskRuleDTO.getTaskConditionList(), TaskCondition.class);
for (TaskCondition taskCondition : taskConditionList) {
taskConditionMapper.insert(taskCondition);
}
}else {
taskRuleMapper.updateById(taskRule);
deleteBatchByTaskId(taskRule.getId());
List<TaskCondition> taskConditionList = CopyUtil.copyList(taskRuleDTO.getTaskConditionList(), TaskCondition.class);
for (TaskCondition taskCondition : taskConditionList) {
taskConditionMapper.insert(taskCondition);
}
}
return Boolean.TRUE;
}
@Override
public PageBaseResponse<TaskRuleVO> queryPage(TaskRuleQuery taskRuleQuery) {
// 分页数据
QueryWrapper<TaskRule> queryWrapper = new QueryWrapper<>();
IPage<TaskRule> page = getBaseMapper().selectPage(
new Page<>(taskRuleQuery.getPage(), taskRuleQuery.getSize()), queryWrapper);
if(CollectionUtils.isEmpty(page.getRecords())){
return PageBaseResponse.success(new Page<>());
}
IPage<TaskRuleVO> convert = page.convert((Function<TaskRule, TaskRuleVO>) taskRule -> {
TaskRuleVO taskRuleVO = CopyUtil.copyObject(taskRule, TaskRuleVO.class);
List<TaskCondition> taskConditionList = getTaskConditionListByTaskId(taskRuleVO.getId());
taskRuleVO.setTaskConditionList(taskConditionList);
return taskRuleVO;
});
return PageBaseResponse.success(convert);
}
@Override
public List<SalesRankingVO> salesRanking(TaskRuleQuery taskRuleQuery) {
QueryWrapper<SalesRecord> 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<SalesRecord> salesRecords = salesRecordMapper.selectList(queryWrapper);
return CopyUtil.copyList(salesRecords, SalesRankingVO.class);
}
private List<TaskCondition> getTaskConditionListByTaskId(Long id) {
QueryWrapper<TaskCondition> qw = new QueryWrapper<>();
qw.lambda().eq(TaskCondition::getTaskId, id);
return taskConditionMapper.selectList(qw);
}
private void deleteBatchByTaskId(Long id) {
QueryWrapper<TaskCondition> qw = new QueryWrapper<>();
qw.lambda().eq(TaskCondition::getTaskId, id);
taskConditionMapper.delete(qw);
}
private void checkTaskName(TaskRuleDTO taskRuleDTO) {
QueryWrapper<TaskRule> qw = new QueryWrapper<>();
if (null != taskRuleDTO.getId()) {
qw.lambda().ne(TaskRule::getId, taskRuleDTO.getId());
}
qw.lambda().eq(TaskRule::getTaskName, taskRuleDTO.getTaskName());
List<TaskRule> taskRuleList = taskRuleMapper.selectList(qw);
if (!CollectionUtils.isEmpty(taskRuleList)) {
throw new BusinessException("The sales incentive rule name already exists.");
}
}
}

View File

@@ -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

View File

@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mixi.mapper.MiTuProductMapper">
<!-- &lt;!&ndash; 通用查询映射结果 &ndash;&gt;-->
<!-- <resultMap id="BaseResultMap" type="com.mixi.mapper.entity.Account">-->
<!-- <id column="id" property="id" />-->
<!-- <result column="user_email" property="userEmail" />-->
<!-- <result column="user_phone" property="userPhone" />-->
<!-- <result column="user_password" property="userPassword" />-->
<!-- <result column="create_date" property="createDate" />-->
<!-- </resultMap>-->
<!-- <select id="findByPhoneList" resultType="com.mixi.mapper.entity.Account">-->
<!-- select id , user_email AS userEmail, user_phone AS userPhone,-->
<!-- user_password AS userPassword from t_account-->
<!-- where user_phone in-->
<!-- <foreach collection="phoneList" item="phone" open="(" separator="," close=")">-->
<!-- #{phone}-->
<!-- </foreach>-->
<!-- </select>-->
<!-- <select id="findById" resultType="com.mixi.mapper.entity.Account">-->
<!-- select id ,user_email AS userEmail, user_phone AS userPhone,-->
<!-- user_password AS userPassword from t_account-->
<!-- where id = #{id}-->
<!-- </select>-->
<select id="getTop30ScoreByMemberCode" resultType="com.mixi.mapper.entity.MiTuProduct">
WITH CustomerPreferences AS (
SELECT
mbr_code,
most_frequent_size,
most_frequent_color,
most_frequent_sub_cat,
most_frequent_category,
ave_price
FROM mi_tu_member
WHERE mbr_code = #{memberCode} -- 请替换为具体的顾客编号
), ProductScores AS (
SELECT
p.id,
p.plu_code,
p.item_code,
p.item_name,
p.item_barcode,
p.unit,
p.item_type,
p.qty_on_hand,
p.qty_on_ord,
p.price_sales,
p.brand,
p.gender,
p.year,
p.season,
p.sample_non,
p.item_group,
p.sub_group,
p.country,
p.supplier,
p.size,
p.color,
p.image,
p.product_id,
cp.most_frequent_size,
cp.most_frequent_color,
cp.most_frequent_sub_cat,
cp.most_frequent_category,
cp.ave_price,
(0.30 * (cp.most_frequent_size like CONCAT('%', p.size, '%')) +
0.25 * (cp.most_frequent_color like CONCAT('%', p.color, '%')) +
0.20 * (1 - LEAST(ABS(p.price_sales - cp.ave_price) / cp.ave_price, 1)) +
0.15 * (cp.most_frequent_sub_cat like CONCAT('%', p.sub_group, '%')) +
0.10 * (cp.most_frequent_category like CONCAT('%', p.item_group, '%'))) AS score
FROM mi_tu_product p
CROSS JOIN CustomerPreferences cp
)
SELECT
product_id,
sum(score) as score
FROM ProductScores
GROUP BY product_id
ORDER BY score DESC
LIMIT 30
</select>
</mapper>