Przeglądaj źródła

瀑布流相关功能开发 待完成

zhangxin 1 tydzień temu
rodzic
commit
0b833d8d7d
17 zmienionych plików z 428 dodań i 227 usunięć
  1. 2 24
      yami-shop-api/src/main/java/com/yami/shop/api/controller/ShopExposureController.java
  2. 11 1
      yami-shop-bean/src/main/java/com/yami/shop/bean/model/WaterfallFlow.java
  3. 77 0
      yami-shop-bean/src/main/java/com/yami/shop/bean/model/WaterfallFlowNormalization.java
  4. 0 44
      yami-shop-bean/src/main/java/com/yami/shop/bean/prodWatefallFlow/CountConversionRate.java
  5. 1 1
      yami-shop-bean/src/main/java/com/yami/shop/bean/prodWaterfallFlow/CountInventoryNum.java
  6. 13 1
      yami-shop-bean/src/main/java/com/yami/shop/bean/prodWaterfallFlow/CountSales.java
  7. 90 0
      yami-shop-platform/src/main/java/com/yami/shop/platform/controller/TaskException.java
  8. 10 15
      yami-shop-platform/src/main/java/com/yami/shop/platform/task/ProdWaterfallFlowTask.java
  9. 8 14
      yami-shop-service/src/main/java/com/yami/shop/dao/ProdWaterfallFlowMapper.java
  10. 25 0
      yami-shop-service/src/main/java/com/yami/shop/dao/ProdWaterfallFlowNormalizationMapper.java
  11. 2 1
      yami-shop-service/src/main/java/com/yami/shop/dao/ShopExposureMapper.java
  12. 3 18
      yami-shop-service/src/main/java/com/yami/shop/service/ProdWaterfallFlowService.java
  13. 52 98
      yami-shop-service/src/main/java/com/yami/shop/service/impl/ProdWaterfallFlowServiceImpl.java
  14. 7 3
      yami-shop-service/src/main/java/com/yami/shop/service/impl/ShopExposureServiceImpl.java
  15. 55 6
      yami-shop-service/src/main/resources/mapper/ProdWaterfallFlowMapper.xml
  16. 66 0
      yami-shop-service/src/main/resources/mapper/ProdWaterfallFlowNormalizationMapper.xml
  17. 6 1
      yami-shop-service/src/main/resources/mapper/ShopExposureMapper.xml

+ 2 - 24
yami-shop-api/src/main/java/com/yami/shop/api/controller/ShopExposureController.java

@@ -11,44 +11,22 @@
 package com.yami.shop.api.controller;
 
 import cn.hutool.json.JSONUtil;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.google.gson.JsonObject;
-import com.yami.shop.bean.app.dto.ProdCommDataDto;
-import com.yami.shop.bean.app.dto.ProdCommDto;
-import com.yami.shop.bean.app.dto.ProductDto;
-import com.yami.shop.bean.dto.ProdByCategoryIdAndShopIdDTO;
-import com.yami.shop.bean.dto.SearchProdDto;
+
 import com.yami.shop.bean.model.*;
-import com.yami.shop.bean.param.CategoryProductParam;
-import com.yami.shop.bean.vo.SimilarProdListVo;
 import com.yami.shop.common.exception.GlobalException;
-import com.yami.shop.common.util.PageParam;
-import com.yami.shop.common.util.R;
+
 import com.yami.shop.security.api.model.YamiUser;
 import com.yami.shop.security.api.util.SecurityUtils;
 import com.yami.shop.service.*;
 import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiImplicitParam;
-import io.swagger.annotations.ApiImplicitParams;
-import io.swagger.annotations.ApiOperation;
-import ma.glasnost.orika.MapperFacade;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.List;
-import java.util.stream.Collectors;
-
 
 @RestController
 @RequestMapping("/p/shopExposure")

+ 11 - 1
yami-shop-bean/src/main/java/com/yami/shop/bean/model/WaterfallFlow.java

@@ -69,7 +69,16 @@ public class WaterfallFlow implements Serializable {
 
     @ApiModelProperty(value = "用户平均评分",required=true)
     private Double evaluateScore;
-
+    /**
+     * 商品曝光数
+     */
+    @ApiModelProperty(value = "商品曝光数",required=true)
+    private Long exposureProdNum;
+    /**
+     * 商品曝光订单数
+     */
+    @ApiModelProperty(value = "商品曝光订单数",required=true)
+    private Long exposureOrderNum;
     @ApiModelProperty(value = "转化率",required=true)
     private Double conversionRate;
 
@@ -79,6 +88,7 @@ public class WaterfallFlow implements Serializable {
     @ApiModelProperty(value = "创建时间",required=true)
     private Date createTime;
 
+
     /**
      * 标识
      */

+ 77 - 0
yami-shop-bean/src/main/java/com/yami/shop/bean/model/WaterfallFlowNormalization.java

@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
+ *
+ * https://www.gz-yami.com/
+ *
+ * 未经允许,不可做商业用途!
+ *
+ * 版权所有,侵权必究!
+ */
+
+package com.yami.shop.bean.model;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 瀑布流归一化相关数据信息
+ */
+@Data
+@TableName("tz_waterfall_flow_normalization")
+public class WaterfallFlowNormalization implements Serializable {
+    private static final long serialVersionUID = 6222259729062826852L;
+    @TableId(type = IdType.UUID)
+    @ApiModelProperty(value = "id",required=true)
+    private String id;
+
+    @ApiModelProperty(value = "自然日日期",required=true)
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private Date calendarDay;
+
+    @ApiModelProperty(value = "商品id",required=true)
+    private Long prodId;
+
+    @ApiModelProperty(value = "店铺id",required=true)
+    private Long shopId;
+
+    @ApiModelProperty(value = "渠道id",required=true)
+    private Long channelId;
+
+    @ApiModelProperty(value = "用户平均评分",required=true)
+    private Double evaluateScore;
+    @ApiModelProperty(value = "转化率",required=true)
+    private Double conversionRate;
+
+    @ApiModelProperty(value = "毛利率",required=true)
+    private Double grossProfitMargin;
+
+
+    @ApiModelProperty(value = "7日的销售量",required=true)
+    private Long sevenSalesNum;
+
+    @ApiModelProperty(value = "上月总销量",required=true)
+    private Long salesNumTotal;
+    @ApiModelProperty(value = "上月总库存",required=true)
+    private Long inventoryNumTotal;
+    @ApiModelProperty(value = "上月总天数",required=true)
+    private Long dayNum;
+    @ApiModelProperty(value = "库存周转率",required=true)
+    private Double inventoryTurnoverRate;
+
+    @ApiModelProperty(value = "创建时间",required=true)
+    private Date createTime;
+    /**
+     * 标识
+     */
+    @ApiModelProperty(value = "标记",required=true)
+    private String concatId;
+}

+ 0 - 44
yami-shop-bean/src/main/java/com/yami/shop/bean/prodWatefallFlow/CountConversionRate.java

@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
- *
- * https://www.gz-yami.com/
- *
- * 未经允许,不可做商业用途!
- *
- * 版权所有,侵权必究!
- */
-
-package com.yami.shop.bean.prodWatefallFlow;
-
-import lombok.Data;
-
-/**
- * 转化率
- */
-@Data
-public class CountConversionRate {
-
-    /**
-     * 渠道id
-     */
-    private Long  channelId;
-
-    /**
-     * 店铺Id
-     */
-    private Long shopId;
-
-    /**
-     * 商品id
-     */
-    private Long  prodId;
-
-    /**
-     * 统计销量
-     */
-    private Long countNum;
-    /**
-     * 标识
-     */
-    private String concatId;
-}

+ 1 - 1
yami-shop-bean/src/main/java/com/yami/shop/bean/prodWatefallFlow/CountInventoryNum.java → yami-shop-bean/src/main/java/com/yami/shop/bean/prodWaterfallFlow/CountInventoryNum.java

@@ -8,7 +8,7 @@
  * 版权所有,侵权必究!
  */
 
-package com.yami.shop.bean.prodWatefallFlow;
+package com.yami.shop.bean.prodWaterfallFlow;
 
 import lombok.Data;
 

+ 13 - 1
yami-shop-bean/src/main/java/com/yami/shop/bean/prodWatefallFlow/CountSales.java → yami-shop-bean/src/main/java/com/yami/shop/bean/prodWaterfallFlow/CountSales.java

@@ -8,7 +8,7 @@
  * 版权所有,侵权必究!
  */
 
-package com.yami.shop.bean.prodWatefallFlow;
+package com.yami.shop.bean.prodWaterfallFlow;
 
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
@@ -75,6 +75,18 @@ public class CountSales  {
      * 商品评论平均
      */
     private Double evaluateScore;
+    /**
+     * 商品曝光数
+     */
+    private Long exposureProdNum;
+    /**
+     * 商品曝光订单数
+     */
+    private Long exposureOrderNum;
+    /**
+     * 转化率
+     */
+    private Double conversionRate;
     /**
      * 标识
      */

+ 90 - 0
yami-shop-platform/src/main/java/com/yami/shop/platform/controller/TaskException.java

@@ -0,0 +1,90 @@
+package com.yami.shop.platform.controller;
+
+
+import com.yami.shop.common.util.R;
+import com.yami.shop.service.PointsRecordService;
+import com.yami.shop.service.ProdWaterfallFlowService;
+import lombok.AllArgsConstructor;
+import lombok.extern.log4j.Log4j2;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.concurrent.CompletableFuture;
+
+
+/**
+ *定时任务异常处理controller
+ * 当定时任务异常时需手动调用
+ */
+@RestController
+@RequestMapping("/platform/order")
+@AllArgsConstructor
+@Log4j2
+public class TaskException {
+
+    @Autowired
+    private PointsRecordService pointsRecordService;
+
+    @Autowired
+    private ProdWaterfallFlowService prodWaterfallFlowService;
+
+    @GetMapping("/expiredPointsException")
+    public R<String> expiredPointsException(@Param("todayStr")String todayStr, @Param("yesterdayStr")String yesterdayStr){
+        log.info("积分过期定时任务执行开始,开始时间:"+todayStr+",结束时间:"+yesterdayStr);
+        // 使用 CompletableFuture 异步执行
+        CompletableFuture.runAsync(() -> {
+            try {
+                pointsRecordService.expiredPoints(todayStr,yesterdayStr);
+                log.info("积分过期定时任务执行完成");
+            } catch (Exception e) {
+                log.error("积分过期任务执行异常", e);
+            }
+        });
+        return R.SUCCESS("定时任务运行中");
+    }
+
+
+    /**
+     * 只能调用当然的 库存上可能会存在差异
+     * 每日处理
+     * 处理瀑布流相关数据
+     */
+    @GetMapping("/waterfallFlowException")
+    public void waterfallFlow() {
+        log.info("处理瀑布流相关数据定时任务执行开始");
+        CompletableFuture.runAsync(() -> {
+            try {
+                prodWaterfallFlowService.waterfallFlow();
+                log.info("处理瀑布流相关数据定时任务执行完成");
+            } catch (Exception e) {
+                log.error("处理瀑布流相关数据任务执行异常", e);
+            }
+        });
+    }
+
+    /**
+     *
+     * 每月二号需要更新的数据
+     * 处理瀑布流归一化数据
+     */
+    @GetMapping("/inventoryTurnoverRateException")
+    public void inventoryTurnoverRate(){
+        log.info("处理瀑布流归一化数据定时任务执行开始");
+        CompletableFuture.runAsync(() -> {
+            try {
+                prodWaterfallFlowService.inventoryTurnoverRate();
+                log.info("处理瀑布流归一化数据定时任务执行完成");
+            } catch (Exception e) {
+                log.error("处理瀑布流归一化数据任务执行异常", e);
+            }
+        });
+
+    }
+
+}

+ 10 - 15
yami-shop-platform/src/main/java/com/yami/shop/platform/task/ProdWaterfallFlowTask.java

@@ -47,25 +47,20 @@ public class ProdWaterfallFlowTask {
     private ProdWaterfallFlowService prodWaterfallFlowService;
 
     /**
+     * 每日处理
      * 处理瀑布流相关数据
      */
-    public void countSales() {
-//        LocalDate localDate = LocalDate.now();
-//        LocalDateTime todayDateTime = localDate.atStartOfDay();
-//        LocalDateTime first7DaysDateTime = localDate.minusDays(7).atStartOfDay();
-//        // 获取当前时间
-//        Date todayStartDate = Date.from(
-//                todayDateTime
-//                        .atZone(ZoneId.systemDefault())
-//                        .toInstant()
-//        );//获取当前时间
-//        Date first7DaysStartDate = Date.from(
-//                first7DaysDateTime
-//                        .atZone(ZoneId.systemDefault())
-//                        .toInstant()
-//        );//获取7天前的时间
+    public void waterfallFlow() {
         prodWaterfallFlowService.waterfallFlow();
     }
 
+    /**
+     * 每月二号需要更新的数据
+     * 处理瀑布流归一化数据
+     */
+    public void inventoryTurnoverRate(){
+        prodWaterfallFlowService.inventoryTurnoverRate();
+    }
+
 
 }

+ 8 - 14
yami-shop-service/src/main/java/com/yami/shop/dao/ProdWaterfallFlowMapper.java

@@ -10,25 +10,15 @@
 
 package com.yami.shop.dao;
 
-import cn.hutool.core.date.DateTime;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.yami.shop.bean.app.dto.MyOrderDto;
-import com.yami.shop.bean.app.dto.MyOrderItemDto;
-import com.yami.shop.bean.app.dto.OrderCountData;
-import com.yami.shop.bean.distribution.UserShoppingDataDto;
-import com.yami.shop.bean.model.Order;
 import com.yami.shop.bean.model.WaterfallFlow;
-import com.yami.shop.bean.param.*;
-import com.yami.shop.bean.prodWatefallFlow.CountInventoryNum;
-import com.yami.shop.bean.prodWatefallFlow.CountSales;
-import com.yami.shop.bean.vo.OrderCountVo;
-import com.yami.shop.common.util.PageAdapter;
-import com.yami.shop.common.util.PageParam;
+import com.yami.shop.bean.model.WaterfallFlowNormalization;
+import com.yami.shop.bean.prodWaterfallFlow.CountInventoryNum;
+import com.yami.shop.bean.prodWaterfallFlow.CountSales;
 import org.apache.ibatis.annotations.Param;
 
+import java.time.LocalDate;
 import java.time.LocalDateTime;
-import java.util.Date;
 import java.util.List;
 
 public interface ProdWaterfallFlowMapper extends BaseMapper<WaterfallFlow> {
@@ -40,4 +30,8 @@ public interface ProdWaterfallFlowMapper extends BaseMapper<WaterfallFlow> {
 
     List<CountInventoryNum> countInventoryNum();
 
+
+    List<WaterfallFlowNormalization> findWaterfallFlowNormalization(@Param("yesterdayStart")LocalDate yesterdayStart,@Param("sevenDayStart") LocalDate sevenDayStart);
+
+    List<WaterfallFlowNormalization> inventoryTurnoverRate(@Param("firstDayOfLastMonth")LocalDate firstDayOfLastMonth,@Param("lastDayOfLastMonth") LocalDate lastDayOfLastMonth);
 }

+ 25 - 0
yami-shop-service/src/main/java/com/yami/shop/dao/ProdWaterfallFlowNormalizationMapper.java

@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
+ *
+ * https://www.gz-yami.com/
+ *
+ * 未经允许,不可做商业用途!
+ *
+ * 版权所有,侵权必究!
+ */
+
+package com.yami.shop.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.yami.shop.bean.model.WaterfallFlowNormalization;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface ProdWaterfallFlowNormalizationMapper extends BaseMapper<WaterfallFlowNormalization> {
+
+    void saveList(@Param("waterfallFlowNormalizations") List<WaterfallFlowNormalization> waterfallFlowNormalizations);
+
+    void updateList(@Param("waterfallFlowNormalizations")List<WaterfallFlowNormalization> waterfallFlowNormalizations);
+
+}

+ 2 - 1
yami-shop-service/src/main/java/com/yami/shop/dao/ShopExposureMapper.java

@@ -16,6 +16,7 @@ import com.yami.shop.bean.model.WaterfallFlow;
 import com.yami.shop.bean.prodWatefallFlow.CountInventoryNum;
 import com.yami.shop.bean.prodWatefallFlow.CountSales;
 import org.apache.ibatis.annotations.Param;
+import org.springframework.security.core.parameters.P;
 
 import java.time.LocalDateTime;
 import java.util.List;
@@ -23,5 +24,5 @@ import java.util.List;
 public interface ShopExposureMapper extends BaseMapper<ShopExposure> {
 
 
-    ShopExposure findByUserIdAndShopId(ShopExposure shopExposure);
+    ShopExposure findByUserIdAndShopId(@Param("shopExposure") ShopExposure shopExposure,@Param("todayStart") LocalDateTime todayStart,@Param("tomorrowDay") LocalDateTime tomorrowDay);
 }

+ 3 - 18
yami-shop-service/src/main/java/com/yami/shop/service/ProdWaterfallFlowService.java

@@ -10,26 +10,9 @@
 
 package com.yami.shop.service;
 
-import cn.hutool.core.date.DateTime;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
 import com.baomidou.mybatisplus.extension.service.IService;
-import com.yami.shop.bean.app.dto.OrderCountData;
-import com.yami.shop.bean.app.dto.ShopCartOrderMergerDto;
-import com.yami.shop.bean.model.Order;
-import com.yami.shop.bean.model.OrderItem;
-import com.yami.shop.bean.model.OrderRefund;
 import com.yami.shop.bean.model.WaterfallFlow;
-import com.yami.shop.bean.param.*;
-import com.yami.shop.bean.prodWatefallFlow.CountSales;
-import com.yami.shop.bean.vo.OrderCountVo;
-import com.yami.shop.common.util.PageParam;
-import com.yami.shop.common.util.R;
-
-import javax.servlet.http.HttpServletResponse;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
 
 /**
  * @author lgh on 2018/09/15.
@@ -39,4 +22,6 @@ public interface ProdWaterfallFlowService extends IService<WaterfallFlow> {
     void waterfallFlow();
 
 
+    void inventoryTurnoverRate();
+
 }

+ 52 - 98
yami-shop-service/src/main/java/com/yami/shop/service/impl/ProdWaterfallFlowServiceImpl.java

@@ -10,93 +10,21 @@
 
 package com.yami.shop.service.impl;
 
-import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.core.date.DateTime;
-import cn.hutool.core.date.DateUtil;
-import cn.hutool.core.io.IORuntimeException;
-import cn.hutool.core.lang.Snowflake;
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.RandomUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.poi.excel.ExcelUtil;
-import cn.hutool.poi.excel.ExcelWriter;
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-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.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
-import com.google.gson.internal.LinkedTreeMap;
-import com.yami.shop.bean.app.dto.OrderCountData;
-import com.yami.shop.bean.app.dto.ShopCartOrderMergerDto;
-import com.yami.shop.bean.dto.hb.HBBaseReq;
-import com.yami.shop.bean.enums.*;
-import com.yami.shop.bean.event.CancelOrderEvent;
-import com.yami.shop.bean.event.ReceiptOrderEvent;
-import com.yami.shop.bean.event.SubmitOrderEvent;
-import com.yami.shop.bean.event.SubmitScoreOrderEvent;
 import com.yami.shop.bean.model.*;
-import com.yami.shop.bean.param.*;
-import com.yami.shop.bean.prodWatefallFlow.CountInventoryNum;
-import com.yami.shop.bean.prodWatefallFlow.CountSales;
-import com.yami.shop.bean.vo.ExportContext;
-import com.yami.shop.bean.vo.OrderCountVo;
-import com.yami.shop.common.config.Constant;
-import com.yami.shop.common.exception.GlobalException;
-import com.yami.shop.common.util.Arith;
-import com.yami.shop.common.util.PageAdapter;
-import com.yami.shop.common.util.PageParam;
-import com.yami.shop.common.util.R;
+import com.yami.shop.bean.prodWaterfallFlow.CountInventoryNum;
+import com.yami.shop.bean.prodWaterfallFlow.CountSales;
 import com.yami.shop.dao.*;
 import com.yami.shop.service.*;
-import com.yami.shop.utils.CullenUtils;
-import com.yami.shop.utils.ExportUtils;
-import com.yami.shop.utils.HBSignUtil;
-import com.yami.shop.wx.po.RefundInfoPo;
-import com.yami.shop.wx.service.WxProviderService;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.ObjectUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.poi.ss.usermodel.CellStyle;
-import org.apache.poi.ss.usermodel.Row;
-import org.apache.poi.ss.usermodel.Sheet;
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.xssf.streaming.SXSSFSheet;
-import org.apache.poi.xssf.streaming.SXSSFWorkbook;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.cache.annotation.CacheEvict;
-import org.springframework.cache.annotation.CachePut;
-import org.springframework.cache.annotation.Cacheable;
-import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServletResponse;
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-import java.rmi.server.ExportException;
-import java.text.SimpleDateFormat;
-import java.time.Instant;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.util.*;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.stream.Collectors;
-
-import static com.yami.shop.common.util.HttpUtil.post;
 
 /**
  * @author lgh on 2018/09/15.
@@ -107,6 +35,8 @@ import static com.yami.shop.common.util.HttpUtil.post;
 public class ProdWaterfallFlowServiceImpl extends ServiceImpl<ProdWaterfallFlowMapper, WaterfallFlow> implements ProdWaterfallFlowService {
 
 
+    @Autowired
+    private ProdWaterfallFlowNormalizationMapper prodWaterfallFlowNormalizationMapper;
 //    /**
 //     * 7天的销量
 //     * 统计销售量并更新销量
@@ -124,40 +54,21 @@ public class ProdWaterfallFlowServiceImpl extends ServiceImpl<ProdWaterfallFlowM
      * 统计每天的销量
      */
     public List<CountSales> countSales(LocalDateTime yesterdayStart, LocalDateTime todayStart) {
-//        LocalDateTime todayStart = LocalDate.now().atStartOfDay();  // 今天0点
-//        LocalDateTime yesterdayStart = todayStart.minusDays(1);     // 昨天0点
-        List<CountSales> countSales = baseMapper.countSales(yesterdayStart,todayStart);
-//        List<WaterfallFlow> waterfallFlows = new ArrayList<>();
-//        BeanUtils.copyProperties(countSales,waterfallFlows);
-//        baseMapper.saveByConcatId(waterfallFlows);
-        return  countSales;
+        return baseMapper.countSales(yesterdayStart,todayStart);
     }
     /**
      * 每天统计库存
      */
     public List<CountInventoryNum> countInventoryNum() {
-        List<CountInventoryNum> countInventoryNums =baseMapper.countInventoryNum();
-//        List<WaterfallFlow> waterfallFlows = new ArrayList<>();
-//        BeanUtils.copyProperties(countInventoryNums,waterfallFlows);
-//        baseMapper.saveByConcatId(waterfallFlows);
-        return countInventoryNums;
+        return baseMapper.countInventoryNum();
     }
 
-//    /**
-//     * 每天转化率
-//     * @param yesterday
-//     */
-//    public void countConversionRate(LocalDateTime yesterdayStart, LocalDateTime todayStart) {
-//        List<CountInventoryNum> countInventoryNums =baseMapper.countConversionRate(yesterday);
-//        List<WaterfallFlow> waterfallFlows = new ArrayList<>();
-//        BeanUtils.copyProperties(countInventoryNums,waterfallFlows);
-//        baseMapper.saveByConcatId(waterfallFlows);
-//    }
     /**
      * 每天更新瀑布流相关数据
      */
     @Override
     public void waterfallFlow() {
+        log.info("瀑布流相关数据处理开始");
         LocalDateTime todayStart = LocalDate.now().atStartOfDay();  // 今天0点
         LocalDateTime yesterdayStart = todayStart.minusDays(1);     // 昨天0点
         ArrayList<WaterfallFlow> waterfallFlows = new ArrayList<>();
@@ -179,9 +90,52 @@ public class ProdWaterfallFlowServiceImpl extends ServiceImpl<ProdWaterfallFlowM
                     waterfallFlow.setGrossProfitMargin(countSalesMap.getGrossProfitMargin());
                     waterfallFlow.setOrderNumberTotal(countSalesMap.getOrderNumberTotal());
                     waterfallFlow.setScoreTotal(countSalesMap.getScoreTotal());
+                    waterfallFlow.setExposureOrderNum(countSalesMap.getExposureOrderNum());
+                    waterfallFlow.setExposureProdNum(countSalesMap.getExposureProdNum());
+                    waterfallFlow.setConversionRate(countSalesMap.getConversionRate());
                 }
             }
         }
-        baseMapper.saveByConcatId(waterfallFlows);
+        if (!waterfallFlows.isEmpty()){
+            try {
+                baseMapper.saveByConcatId(waterfallFlows);
+            } catch (Exception e) {
+                throw new RuntimeException(e.getMessage());
+            }
+            waterfallFlowNormalization();
+        }
+
+        log.info("瀑布流相关数据处理完成");
     }
-}
+    /**
+     * 每日需要更新的数据
+     * 处理瀑布流归一化数据
+     */
+    public void waterfallFlowNormalization() {
+        LocalDate todayStart = LocalDate.now();//获取今天年月日
+        LocalDate yesterdayStart = todayStart.minusDays(1);//获取昨天年月日
+        LocalDate sevenDayStart = todayStart.minusDays(7);//获取七天前年月日
+        List<WaterfallFlowNormalization> waterfallFlowNormalizations = baseMapper.findWaterfallFlowNormalization(yesterdayStart,sevenDayStart);
+        if (waterfallFlowNormalizations!=null&&!waterfallFlowNormalizations.isEmpty()){
+            prodWaterfallFlowNormalizationMapper.saveList(waterfallFlowNormalizations);
+        }
+    }
+
+    /**
+     * 每月一号需要更新的数据
+     * 处理瀑布流归一化数据
+     */
+    @Override
+    public void inventoryTurnoverRate() {
+        log.info("瀑布流每月库存周转率数据处理开始");
+        LocalDate todayStart = LocalDate.now();//获取今天年月日
+        LocalDate firstDayOfLastMonth = todayStart.minusMonths(1).withDayOfMonth(1);//获取上月第一天年月日
+        LocalDate lastDayOfLastMonth = todayStart.withDayOfMonth(1).minusDays(1);//获取上月最后一天年月日
+        List<WaterfallFlowNormalization> waterfallFlowNormalizations = baseMapper.inventoryTurnoverRate(firstDayOfLastMonth,lastDayOfLastMonth);
+        if (waterfallFlowNormalizations!=null&&!waterfallFlowNormalizations.isEmpty()){
+            prodWaterfallFlowNormalizationMapper.updateList(waterfallFlowNormalizations);
+        }
+        log.info("瀑布流每月库存周转率数据处理完成");
+    }
+
+}

+ 7 - 3
yami-shop-service/src/main/java/com/yami/shop/service/impl/ShopExposureServiceImpl.java

@@ -38,8 +38,12 @@ public class ShopExposureServiceImpl extends ServiceImpl<ShopExposureMapper, Sho
 
     @Override
     public void saveShopExposure(ShopExposure shopExposure) {
-        ShopExposure  shopExposureOld  = baseMapper.findByUserIdAndShopId(shopExposure);
-        shopExposure.setId(UUID.randomUUID().toString());
-
+        LocalDateTime todayStart = LocalDate.now().atStartOfDay();  // 今天0点
+        LocalDateTime tomorrowDay = todayStart.plusDays(1);     // 明天0点
+        ShopExposure  shopExposureOld  = baseMapper.findByUserIdAndShopId(shopExposure,todayStart,tomorrowDay);
+        if (shopExposureOld==null){
+            shopExposure.setId(UUID.randomUUID().toString());
+            baseMapper.insert(shopExposure);
+        }
     }
 }

+ 55 - 6
yami-shop-service/src/main/resources/mapper/ProdWaterfallFlowMapper.xml

@@ -38,7 +38,7 @@
                     #{item.calendarDay, jdbcType=DATE}
                 </when>
                 <otherwise>
-                    CURDATE()
+                    DATE_SUB(CURDATE(), INTERVAL 1 DAY)
                 </otherwise>
             </choose>,
             <!-- 3. 必填字段校验 -->
@@ -138,14 +138,17 @@
         </foreach>
     </insert>
 
-    <select id="countSales" resultType="com.yami.shop.bean.prodWatefallFlow.CountSales">
+    <select id="countSales" resultType="com.yami.shop.bean.prodWaterfallFlow.CountSales">
         SELECT
             m.channel_id,
             toi.shop_id,
             toi.prod_id,
-            COUNT( m.order_number) as orderNumberTotal,
+            count( DISTINCT tse.id) as exposureOrderNum,
+            IFNULL(tse1.countp,0) as exposureProdNum,
+            ROUND(IFNULL(count(DISTINCT tse.id)/tse1.countp,0),2) as conversionRate,
+            COUNT(DISTINCT m.order_number) as orderNumberTotal,
             IFNULL(sum(tpc.score),0) as scoreTotal,
-            ROUND(IFNULL(sum(tpc.score),0) / COUNT(m.order_number) ,2) as evaluateScore,
+            ROUND(IFNULL(sum(tpc.score),0) / COUNT(DISTINCT m.order_number) ,2) as evaluateScore,
             SUM(toi.prod_count) AS countNum,
             SUM(toi.product_total_amount) AS total_amount,
             IFNULL(ROUND(SUM(toi.prod_count) * MAX(tcp.purchase_price), 2), 0) AS total_price,
@@ -161,6 +164,7 @@
                  SELECT
                      a.order_number,
                      a.channel_id,
+                     a.user_id,
                      a.create_time
                  FROM tz_order a
                  WHERE a.create_time >= #{yesterday}
@@ -189,7 +193,15 @@
                  LEFT JOIN tz_channel_prod tcp ON m.channel_id = tcp.channel_id
             AND toi.shop_id = tcp.shop_id
             AND toi.sku_id = tcp.sku_id
-                 LEFT JOIN tz_prod_comm tpc on m.order_number = tpc.order_number
+        LEFT JOIN tz_prod_comm tpc on m.order_number = tpc.order_number
+        LEFT JOIN
+        (SELECT shop_id,channel_id,prod_id,COUNT(1) as countp from  tz_shop_exposure where create_time >=  #{yesterday}  and  create_time &lt; #{todayStart}  GROUP BY shop_id,channel_id,prod_id) tse1 on tse1.channel_id = m.channel_id and  toi.shop_id = tse1.shop_id
+        and  toi.prod_id=tse1.prod_id
+        LEFT JOIN tz_shop_exposure tse on tse.channel_id = m.channel_id and  toi.shop_id = tse.shop_id
+        and  toi.prod_id=tse.prod_id and m.user_id = tse.user_id
+        and  tse.create_time >=  #{yesterday}
+        AND m.create_time > tse.create_time
+        and  tse.create_time &lt; #{todayStart}
         WHERE toi.shop_id IS NOT NULL
           AND toi.prod_id IS NOT NULL
         GROUP BY m.channel_id, toi.shop_id, toi.prod_id
@@ -197,7 +209,7 @@
     </select>
 
 
-    <select id="countInventoryNum" resultType="com.yami.shop.bean.prodWatefallFlow.CountInventoryNum">
+    <select id="countInventoryNum" resultType="com.yami.shop.bean.prodWaterfallFlow.CountInventoryNum">
         select tcs.channel_id,tcs.shop_id, ts.prod_id,sum(tss.shop_sku_stocks) from  tz_channel_shop tcs
         inner JOIN tz_channel_prod tcp on  tcs.channel_id =tcp.channel_id and  tcs.shop_id =tcp.shop_id  and tcp.is_delete=0
         inner JOIN tz_sku ts on  tcp.sku_id = ts.sku_id and ts.is_delete =0
@@ -205,4 +217,41 @@
         where tcs.is_delete=0
         GROUP BY tcs.channel_id,tcs.shop_id, ts.prod_id
     </select>
+    <select id="findWaterfallFlowNormalization"
+            resultType="com.yami.shop.bean.model.WaterfallFlowNormalization">
+        -- 获取今天的
+        select a.*,b.seven_sales_num from (
+        select id ,calendar_day,shop_id,channel_id,prod_id,
+        gross_profit_margin,evaluate_score,conversion_rate
+        from tz_waterfall_flow WHERE calendar_day = #{yesterdayStart}
+        ) a
+        LEFT JOIN
+        -- 获取7天内的销售量
+        (
+        select shop_id,channel_id,prod_id,SUM(sales_num) as seven_sales_num
+        from tz_waterfall_flow WHERE calendar_day &lt;= #{yesterdayStart} and calendar_day >= #{sevenDayStart}
+        GROUP BY channel_id,shop_id,prod_id
+        ) b on a.channel_id = b.channel_id and a.shop_id =  b.shop_id and  a.prod_id = b.prod_id
+    </select>
+    <select id="inventoryTurnoverRate" resultType="com.yami.shop.bean.model.WaterfallFlowNormalization">
+        -- 统计上个月的库存周转率
+        SELECT a.*,c.salesNumTotal,c.inventoryNumTotal,c.dayNum,ifnull(c.inventory_turnover_rate,0.00) from (
+        SELECT id ,calendar_day,shop_id,channel_id,prod_id,
+        gross_profit_margin,evaluate_score,conversion_rate from  tz_waterfall_flow WHERE calendar_day &lt;=  #{lastDayOfLastMonth}  and calendar_day >= #{firstDayOfLastMonth}
+        ) a
+        LEFT JOIN
+        (
+        select shop_id,channel_id,prod_id,SUM(sales_num) as salesNumTotal,SUM(inventory_num) as inventoryNumTotal,
+        -- 只统计 inventory_num 不为 null 且不为 0 的
+        COUNT(CASE WHEN inventory_num IS NOT NULL AND inventory_num > 0 THEN 1 ELSE 0 END) AS dayNum,
+        -- 计算库存周转率,防止除零错误
+        CASE
+        WHEN SUM(inventory_num) > 0
+        THEN SUM(sales_num) / (SUM(inventory_num) / COUNT(CASE WHEN inventory_num IS NOT NULL AND inventory_num > 0 THEN 1 ELSE 0 END))
+        ELSE 0
+        END AS inventory_turnover_rate
+        from tz_waterfall_flow WHERE  calendar_day >= #{firstDayOfLastMonth} and calendar_day &lt;= #{lastDayOfLastMonth}
+        GROUP BY channel_id,shop_id,prod_id
+        ) c on a.channel_id = c.channel_id and a.shop_id =  c.shop_id and  a.prod_id =  c.prod_id
+    </select>
 </mapper>

+ 66 - 0
yami-shop-service/src/main/resources/mapper/ProdWaterfallFlowNormalizationMapper.xml

@@ -0,0 +1,66 @@
+<?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.yami.shop.dao.ProdWaterfallFlowNormalizationMapper">
+
+
+    <insert id="saveList">
+        INSERT INTO tz_waterfall_flow_normalization (
+        id,
+        calendar_day,
+        shop_id,
+        channel_id,
+        prod_id,
+        gross_profit_margin,
+        evaluate_score,
+        conversion_rate,
+        seven_sales_num,
+        inventory_turnover_rate,
+        concat_id,
+        create_time
+        ) VALUES
+        <foreach collection="waterfallFlowNormalizations" item="item" separator=",">
+        (
+        #{item.id},
+        #{item.calendarDay},
+        #{item.shopId},
+        #{item.channelId},
+        #{item.prodId},
+        #{item.grossProfitMargin},
+        #{item.evaluateScore},
+        #{item.conversionRate},
+        #{item.sevenSalesNum},
+        #{item.inventoryTurnoverRate},
+        #{item.concatId},
+        #{item.createTime}
+        )
+        </foreach>
+    </insert>
+    <update id="updateList">
+        UPDATE tz_waterfall_flow_normalization
+        SET
+        sales_num_total = CASE concat_id
+        <foreach collection="list" item="item">
+            WHEN #{item.concatId} THEN #{item.salesNumTotal}
+        </foreach>
+        END,
+        inventory_num_total = CASE concat_id
+        <foreach collection="list" item="item">
+            WHEN #{item.concatId} THEN #{item.inventoryNumTotal}
+        </foreach>
+        END,
+        day_num = CASE concat_id
+        <foreach collection="list" item="item">
+            WHEN #{item.concatId} THEN #{item.dayNum}
+        </foreach>
+        END,
+        inventory_turnover_rate = CASE concat_id
+        <foreach collection="list" item="item">
+            WHEN #{item.concatId} THEN #{item.inventoryTurnoverRate}
+        </foreach>
+        END
+        WHERE id IN
+        <foreach collection="list" item="item" open="(" close=")" separator=",">
+            #{item.id}
+        </foreach>
+    </update>
+</mapper>

+ 6 - 1
yami-shop-service/src/main/resources/mapper/ShopExposureMapper.xml

@@ -4,6 +4,11 @@
 
 
     <select id="findByUserIdAndShopId" resultType="com.yami.shop.bean.model.ShopExposure">
-        select * from  tz_shop_exposure
+        select * from  tz_shop_exposure where  user_id = #{shopExposure.userId}
+                                          and  shop_id = #{shopExposure.shopId}
+                                          and  channel_id  = #{shopExposure.channelId}
+                                          and  prod_id = #{shopExposure.prodId}
+                                          and create_time >= #{todayStart}
+                                          and create_time &lt;  #{tomorrowDay}
     </select>
 </mapper>