Sfoglia il codice sorgente

瀑布流相关接口

zhangxin 1 settimana fa
parent
commit
fc0efc8195
16 ha cambiato i file con 1010 aggiunte e 20 eliminazioni
  1. 99 0
      yami-shop-api/src/main/java/com/yami/shop/api/controller/ShopExposureController.java
  2. 49 0
      yami-shop-bean/src/main/java/com/yami/shop/bean/model/ShopExposure.java
  3. 89 0
      yami-shop-bean/src/main/java/com/yami/shop/bean/model/WaterfallFlow.java
  4. 44 0
      yami-shop-bean/src/main/java/com/yami/shop/bean/prodWatefallFlow/CountConversionRate.java
  5. 44 0
      yami-shop-bean/src/main/java/com/yami/shop/bean/prodWatefallFlow/CountInventoryNum.java
  6. 82 0
      yami-shop-bean/src/main/java/com/yami/shop/bean/prodWatefallFlow/CountSales.java
  7. 17 17
      yami-shop-platform/src/main/java/com/yami/shop/platform/task/ProdWaterfallFlowTask.java
  8. 43 0
      yami-shop-service/src/main/java/com/yami/shop/dao/ProdWaterfallFlowMapper.java
  9. 27 0
      yami-shop-service/src/main/java/com/yami/shop/dao/ShopExposureMapper.java
  10. 0 3
      yami-shop-service/src/main/java/com/yami/shop/service/OrderService.java
  11. 42 0
      yami-shop-service/src/main/java/com/yami/shop/service/ProdWaterfallFlowService.java
  12. 25 0
      yami-shop-service/src/main/java/com/yami/shop/service/ShopExposureService.java
  13. 187 0
      yami-shop-service/src/main/java/com/yami/shop/service/impl/ProdWaterfallFlowServiceImpl.java
  14. 45 0
      yami-shop-service/src/main/java/com/yami/shop/service/impl/ShopExposureServiceImpl.java
  15. 208 0
      yami-shop-service/src/main/resources/mapper/ProdWaterfallFlowMapper.xml
  16. 9 0
      yami-shop-service/src/main/resources/mapper/ShopExposureMapper.xml

+ 99 - 0
yami-shop-api/src/main/java/com/yami/shop/api/controller/ShopExposureController.java

@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
+ *
+ * https://www.gz-yami.com/
+ *
+ * 未经允许,不可做商业用途!
+ *
+ * 版权所有,侵权必究!
+ */
+
+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")
+@Api(tags = "商品曝光接口")
+public class ShopExposureController {
+
+    private Logger logger = LoggerFactory.getLogger(getClass());
+    @Autowired
+    private ShopExposureService shopExposureService;
+
+
+    /**
+     * 商品曝光
+     * @param shopExposure
+     * @return
+     */
+    @PostMapping("/saveShopExposure")
+    public ResponseEntity<String> saveShopExposure(@RequestBody ShopExposure shopExposure) {
+        logger.info("请求参数,{}", JSONUtil.toJsonStr(shopExposure));
+        if (shopExposure == null) {
+            throw new GlobalException("商品曝光请求参数不能为空");
+        }
+        if (shopExposure.getShopId() == null || shopExposure.getProdId() == null) {
+            throw new GlobalException("商品曝光商品id、门店id、渠道id参数不能为空");
+        }
+        if (ObjectUtils.isEmpty(shopExposure.getChannelId())) {
+            shopExposure.setChannelId(3L);
+        }
+        YamiUser user = null;
+        try {
+            user = SecurityUtils.getUser();
+        } catch (Exception e) {
+            System.out.println("商品曝光:" + e.getMessage());
+            logger.error("商品曝光:错误信息", e);
+        }
+        if (user != null) {
+            String userId = user.getUserId();
+            if (StringUtils.isNotEmpty(userId)) {
+                shopExposure.setUserId(userId);
+            }
+            shopExposureService.saveShopExposure(shopExposure);
+        }
+        return ResponseEntity.ok("成功");
+    }
+
+
+
+}

+ 49 - 0
yami-shop-bean/src/main/java/com/yami/shop/bean/model/ShopExposure.java

@@ -0,0 +1,49 @@
+/*
+ * 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.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 用户商品曝光度
+ */
+@Data
+@TableName("tz_shop_exposure")
+public class ShopExposure implements Serializable {
+    private static final long serialVersionUID = 6222259729062826852L;
+    @TableId(type = IdType.UUID)
+    @ApiModelProperty(value = "id",required=true)
+    private String id;
+    @ApiModelProperty(value = "商品id",required=true)
+    private Long prodId;
+    @ApiModelProperty(value = "用户id",required=true)
+    private String userId;
+
+    @ApiModelProperty(value = "店铺id",required=true)
+    private Long shopId;
+
+    @ApiModelProperty(value = "渠道id",required=true)
+    private Long channelId;
+    @ApiModelProperty(value = "创建时间",required=true)
+    private Date createTime;
+
+
+}

+ 89 - 0
yami-shop-bean/src/main/java/com/yami/shop/bean/model/WaterfallFlow.java

@@ -0,0 +1,89 @@
+/*
+ * 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.TableField;
+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.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 瀑布流相关数据信息
+ */
+@Data
+@TableName("tz_waterfall_flow")
+public class WaterfallFlow 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 Long salesNum;
+
+    @ApiModelProperty(value = "每日库存数",required=true)
+    private Long inventoryNum;
+
+    @ApiModelProperty(value = "每日总销售金额",required=true)
+    private BigDecimal salesTotalMoney;
+
+    @ApiModelProperty(value = "每日成本总金额",required=true)
+    private BigDecimal costTotalMoney;
+
+    @ApiModelProperty(value = "统计订单数",required=true)
+    private Long orderNumberTotal;
+
+    @ApiModelProperty(value = "统计评论总评分",required=true)
+    private Long scoreTotal;
+
+    @ApiModelProperty(value = "用户平均评分",required=true)
+    private Double evaluateScore;
+
+    @ApiModelProperty(value = "转化率",required=true)
+    private Double conversionRate;
+
+    @ApiModelProperty(value = "毛利率",required=true)
+    private Double grossProfitMargin;
+
+    @ApiModelProperty(value = "创建时间",required=true)
+    private Date createTime;
+
+    /**
+     * 标识
+     */
+    @ApiModelProperty(value = "标记",required=true)
+    private String concatId;
+
+
+}

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

@@ -0,0 +1,44 @@
+/*
+ * 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;
+}

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

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

+ 82 - 0
yami-shop-bean/src/main/java/com/yami/shop/bean/prodWatefallFlow/CountSales.java

@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
+ *
+ * https://www.gz-yami.com/
+ *
+ * 未经允许,不可做商业用途!
+ *
+ * 版权所有,侵权必究!
+ */
+
+package com.yami.shop.bean.prodWatefallFlow;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.yami.shop.bean.model.OrderItem;
+import com.yami.shop.bean.model.UserAddrOrder;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ *
+ */
+@Data
+public class CountSales  {
+
+    /**
+     * 渠道id
+     */
+    private Long  channelId;
+
+    /**
+     * 店铺Id
+     */
+    private Long shopId;
+
+    /**
+     * 商品id
+     */
+    private Long  prodId;
+
+    /**
+     * 统计销量
+     */
+    private Long countNum;
+
+    /**
+     * 统计商品销售金额
+     */
+    private BigDecimal salesTotalMoney;
+    /**
+     * 统计商品销售成本金额
+     */
+    private BigDecimal costTotalMoney;
+    /**
+     * 毛利率
+     */
+    private Double grossProfitMargin;
+
+    /**
+     * 统计订单数
+     */
+    private Long orderNumberTotal;
+    /**
+     * 统计评论总评分
+     */
+    private Long scoreTotal;
+    /**
+     * 商品评论平均
+     */
+    private Double evaluateScore;
+    /**
+     * 标识
+     */
+    private String concatId;
+}

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

@@ -44,27 +44,27 @@ public class ProdWaterfallFlowTask {
     private Logger logger = LoggerFactory.getLogger(getClass());
 
     @Autowired
-    OrderService orderService;
+    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天前的时间
-//        orderService.countSales(todayStartDate,first7DaysStartDate);
+//        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天前的时间
+        prodWaterfallFlowService.waterfallFlow();
     }
 
 

+ 43 - 0
yami-shop-service/src/main/java/com/yami/shop/dao/ProdWaterfallFlowMapper.java

@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
+ *
+ * https://www.gz-yami.com/
+ *
+ * 未经允许,不可做商业用途!
+ *
+ * 版权所有,侵权必究!
+ */
+
+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 org.apache.ibatis.annotations.Param;
+
+import java.time.LocalDateTime;
+import java.util.Date;
+import java.util.List;
+
+public interface ProdWaterfallFlowMapper extends BaseMapper<WaterfallFlow> {
+
+
+    void saveByConcatId(@Param("waterfallFlows") List<WaterfallFlow> waterfallFlows);
+
+    List<CountSales> countSales(@Param("yesterday") LocalDateTime yesterdayStart, @Param("todayStart")LocalDateTime todayStart);
+
+    List<CountInventoryNum> countInventoryNum();
+
+}

+ 27 - 0
yami-shop-service/src/main/java/com/yami/shop/dao/ShopExposureMapper.java

@@ -0,0 +1,27 @@
+/*
+ * 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.ShopExposure;
+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 java.time.LocalDateTime;
+import java.util.List;
+
+public interface ShopExposureMapper extends BaseMapper<ShopExposure> {
+
+
+    ShopExposure findByUserIdAndShopId(ShopExposure shopExposure);
+}

+ 0 - 3
yami-shop-service/src/main/java/com/yami/shop/service/OrderService.java

@@ -184,7 +184,4 @@ public interface OrderService extends IService<Order> {
 
 
     OrderCountVo orderCount(BackendOrderParam orderParam);
-
-
-//    void countSales(Date todayStartDate, Date first7DaysStartDate);
 }

+ 42 - 0
yami-shop-service/src/main/java/com/yami/shop/service/ProdWaterfallFlowService.java

@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
+ *
+ * https://www.gz-yami.com/
+ *
+ * 未经允许,不可做商业用途!
+ *
+ * 版权所有,侵权必究!
+ */
+
+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.
+ */
+public interface ProdWaterfallFlowService extends IService<WaterfallFlow> {
+
+    void waterfallFlow();
+
+
+}

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

@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
+ *
+ * https://www.gz-yami.com/
+ *
+ * 未经允许,不可做商业用途!
+ *
+ * 版权所有,侵权必究!
+ */
+
+package com.yami.shop.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.yami.shop.bean.model.ShopExposure;
+import com.yami.shop.bean.model.WaterfallFlow;
+
+/**
+ * @author lgh on 2018/09/15.
+ */
+public interface ShopExposureService extends IService<ShopExposure> {
+
+
+    void saveShopExposure(ShopExposure shopExposure);
+
+}

+ 187 - 0
yami-shop-service/src/main/java/com/yami/shop/service/impl/ProdWaterfallFlowServiceImpl.java

@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
+ *
+ * https://www.gz-yami.com/
+ *
+ * 未经允许,不可做商业用途!
+ *
+ * 版权所有,侵权必究!
+ */
+
+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.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.
+ */
+@Slf4j
+@Service
+@AllArgsConstructor
+public class ProdWaterfallFlowServiceImpl extends ServiceImpl<ProdWaterfallFlowMapper, WaterfallFlow> implements ProdWaterfallFlowService {
+
+
+//    /**
+//     * 7天的销量
+//     * 统计销售量并更新销量
+//     * @param todayStartDate
+//     * @param first7DaysStartDate
+//     */
+//    public void countSales(Date todayStartDate, Date first7DaysStartDate) {
+//        List<CountSales> countSales = baseMapper.countSales(todayStartDate, first7DaysStartDate);
+//        List<WaterfallFlow> waterfallFlows = new ArrayList<>();
+//        BeanUtils.copyProperties(countSales,waterfallFlows);
+//        baseMapper.saveByConcatId(waterfallFlows);
+//    }
+
+    /**
+     * 统计每天的销量
+     */
+    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;
+    }
+    /**
+     * 每天统计库存
+     */
+    public List<CountInventoryNum> countInventoryNum() {
+        List<CountInventoryNum> countInventoryNums =baseMapper.countInventoryNum();
+//        List<WaterfallFlow> waterfallFlows = new ArrayList<>();
+//        BeanUtils.copyProperties(countInventoryNums,waterfallFlows);
+//        baseMapper.saveByConcatId(waterfallFlows);
+        return countInventoryNums;
+    }
+
+//    /**
+//     * 每天转化率
+//     * @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() {
+        LocalDateTime todayStart = LocalDate.now().atStartOfDay();  // 今天0点
+        LocalDateTime yesterdayStart = todayStart.minusDays(1);     // 昨天0点
+        ArrayList<WaterfallFlow> waterfallFlows = new ArrayList<>();
+        List<CountInventoryNum> countInventoryNums = countInventoryNum();
+        BeanUtils.copyProperties(waterfallFlows,countInventoryNums);
+        List<CountSales> countSales = countSales(yesterdayStart, todayStart);
+        if (countSales!=null&& !countSales.isEmpty()){
+            Map<String, CountSales> stringCountSalesHashMap = new HashMap<>();
+            for (CountSales countSale : countSales) {
+                stringCountSalesHashMap.put(countSale.getConcatId(),countSale);
+            }
+            for (WaterfallFlow waterfallFlow : waterfallFlows) {
+                CountSales countSalesMap = stringCountSalesHashMap.get(waterfallFlow.getConcatId());
+                if (countSalesMap!=null){
+                    waterfallFlow.setSalesNum(countSalesMap.getCountNum());
+                    waterfallFlow.setSalesTotalMoney(countSalesMap.getSalesTotalMoney());
+                    waterfallFlow.setCostTotalMoney(countSalesMap.getCostTotalMoney());
+                    waterfallFlow.setEvaluateScore(countSalesMap.getEvaluateScore());
+                    waterfallFlow.setGrossProfitMargin(countSalesMap.getGrossProfitMargin());
+                    waterfallFlow.setOrderNumberTotal(countSalesMap.getOrderNumberTotal());
+                    waterfallFlow.setScoreTotal(countSalesMap.getScoreTotal());
+                }
+            }
+        }
+        baseMapper.saveByConcatId(waterfallFlows);
+    }
+}

+ 45 - 0
yami-shop-service/src/main/java/com/yami/shop/service/impl/ShopExposureServiceImpl.java

@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
+ *
+ * https://www.gz-yami.com/
+ *
+ * 未经允许,不可做商业用途!
+ *
+ * 版权所有,侵权必究!
+ */
+
+package com.yami.shop.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yami.shop.bean.model.ShopExposure;
+import com.yami.shop.bean.model.WaterfallFlow;
+import com.yami.shop.bean.prodWatefallFlow.CountInventoryNum;
+import com.yami.shop.bean.prodWatefallFlow.CountSales;
+import com.yami.shop.dao.ProdWaterfallFlowMapper;
+import com.yami.shop.dao.ShopExposureMapper;
+import com.yami.shop.service.ProdWaterfallFlowService;
+import com.yami.shop.service.ShopExposureService;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.*;
+
+/**
+ * @author lgh on 2018/09/15.
+ */
+@Slf4j
+@Service
+@AllArgsConstructor
+public class ShopExposureServiceImpl extends ServiceImpl<ShopExposureMapper, ShopExposure> implements ShopExposureService {
+
+    @Override
+    public void saveShopExposure(ShopExposure shopExposure) {
+        ShopExposure  shopExposureOld  = baseMapper.findByUserIdAndShopId(shopExposure);
+        shopExposure.setId(UUID.randomUUID().toString());
+
+    }
+}

+ 208 - 0
yami-shop-service/src/main/resources/mapper/ProdWaterfallFlowMapper.xml

@@ -0,0 +1,208 @@
+<?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.ProdWaterfallFlowMapper">
+
+    <insert id="saveByConcatId">
+        <!-- 使用rewriteBatchedStatements=true连接参数时,会自动优化批量性能 -->
+        INSERT INTO tz_waterfall_flow (
+        id,
+        calendar_day,
+        shop_id,
+        channel_id,
+        prod_id,
+        <if test="salesNum != null">sales_num,</if>
+        <if test="inventoryNum != null">inventory_num,</if>
+        <if test="salesTotalMoney != null">sales_total_money,</if>
+        <if test="costTotalMoney != null">cost_total_money,</if>
+        <if test="evaluateScore != null">evaluate_score,</if>
+        concat_id,
+        <if test="conversionRate != null">conversion_rate,</if>
+        create_time
+        )
+        VALUES
+        <foreach collection="waterfallFlows" item="item" index="index" separator=",">
+            (
+            <!-- 1. ID 处理:必须为32位UUID -->
+            <choose>
+                <when test="item.id != null and item.id != '' and LENGTH(item.id) = 32">
+                    #{item.id, jdbcType=VARCHAR}
+                </when>
+                <otherwise>
+                    REPLACE(UUID(), '-', '')
+                </otherwise>
+            </choose>,
+            <!-- 2. 日期校验:不能为未来日期,默认为今天 -->
+            <choose>
+                <when test="item.calendarDay != null">
+                    <!-- 防止SQL注入,使用参数绑定 -->
+                    #{item.calendarDay, jdbcType=DATE}
+                </when>
+                <otherwise>
+                    CURDATE()
+                </otherwise>
+            </choose>,
+            <!-- 3. 必填字段校验 -->
+            <choose>
+                <when test="item.shopId != null and item.shopId > 0">
+                    #{item.shopId, jdbcType=BIGINT}
+                </when>
+            </choose>,
+            <choose>
+                <when test="item.channelId != null and item.channelId > 0">
+                    #{item.channelId, jdbcType=BIGINT}
+                </when>
+            </choose>,
+
+            <choose>
+                <when test="item.prodId != null and item.prodId > 0">
+                    #{item.prodId, jdbcType=BIGINT}
+                </when>
+            </choose>,
+
+            <!-- 4. 数值字段校验:非负数,使用默认值 -->
+            <choose>
+                <when test="item.salesNum != null and item.salesNum >= 0">
+                    #{item.salesNum, jdbcType=BIGINT}
+                </when>
+                <otherwise>0</otherwise>
+            </choose>,
+
+            <choose>
+                <when test="item.inventoryNum != null and item.inventoryNum >= 0">
+                    #{item.inventoryNum, jdbcType=BIGINT}
+                </when>
+                <otherwise>0</otherwise>
+            </choose>,
+
+            <!-- 金额字段,四舍五入保留2位小数 -->
+            <choose>
+                <when test="item.salesTotalMoney != null and item.salesTotalMoney >= 0">
+                    ROUND(#{item.salesTotalMoney, jdbcType=DECIMAL}, 2)
+                </when>
+                <otherwise>0.00</otherwise>
+            </choose>,
+
+            <choose>
+                <when test="item.costTotalMoney != null and item.costTotalMoney >= 0">
+                    ROUND(#{item.costTotalMoney, jdbcType=DECIMAL}, 2)
+                </when>
+                <otherwise>0.00</otherwise>
+            </choose>,
+
+            <!-- 5. 评分:范围0-5,保留2位小数 -->
+            <choose>
+                <when test="item.evaluateScore != null">
+                    <!-- 限制范围在0-5之间 -->
+                    ROUND(
+                    CASE
+                    WHEN #{item.evaluateScore}  &lt; 0 THEN 0.00
+                    WHEN #{item.evaluateScore} > 5 THEN 5.00
+                    ELSE #{item.evaluateScore}
+                    END,
+                    2)
+                </when>
+                <otherwise>0.00</otherwise>
+            </choose>,
+
+            <!-- 6. concat_id 处理:自动生成或使用传入值 -->
+            <choose>
+                <when test="item.concatId != null and item.concatId != ''">
+                    #{item.concatId, jdbcType=VARCHAR}
+                </when>
+            </choose>,
+
+            <!-- 7. 转化率:范围0-1,保留2位小数 -->
+            <choose>
+                <when test="item.conversionRate != null">
+                    ROUND(
+                    CASE
+                    WHEN #{item.conversionRate} < 0 THEN 0.00
+                    WHEN #{item.conversionRate} > 1 THEN 1.00
+                    ELSE #{item.conversionRate}
+                    END,
+                    2)
+                </when>
+                <otherwise>0.00</otherwise>
+            </choose>,
+            <!-- 8. 创建时间:不能是未来时间 -->
+            <choose>
+                <when test="item.createTime != null">
+                    <!-- 正式环境应该校验时间有效性 -->
+                    #{item.createTime, jdbcType=TIMESTAMP}
+                </when>
+                <otherwise>
+                    NOW()
+                </otherwise>
+            </choose>
+            )
+        </foreach>
+    </insert>
+
+    <select id="countSales" resultType="com.yami.shop.bean.prodWatefallFlow.CountSales">
+        SELECT
+            m.channel_id,
+            toi.shop_id,
+            toi.prod_id,
+            COUNT( 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,
+            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,
+            CASE
+                WHEN SUM(toi.product_total_amount) = 0 OR SUM(toi.product_total_amount) IS NULL THEN 0
+                ELSE ROUND(
+                            (SUM(toi.product_total_amount) - IFNULL(ROUND(SUM(toi.prod_count) * MAX(tcp.purchase_price), 2), 0))
+                            / NULLIF(SUM(toi.product_total_amount), 0)
+                    , 2)
+                END AS profit_margin,
+            CONCAT_WS('_', m.channel_id, toi.shop_id, toi.prod_id) AS concat_id
+        FROM (
+                 SELECT
+                     a.order_number,
+                     a.channel_id,
+                     a.create_time
+                 FROM tz_order a
+                 WHERE a.create_time >= #{yesterday}
+                   AND a.create_time &lt; #{todayStart}
+                   AND NOT EXISTS (
+                     SELECT 1
+                     FROM tz_order a_ex
+                     WHERE a_ex.order_number = a.order_number
+                       AND a_ex.hb_order_status IN (50, 60, 0)
+                 )
+                   AND (
+                         NOT EXISTS (
+                             SELECT 1
+                             FROM tz_order_refund b2
+                             WHERE b2.order_number = a.order_number
+                         )
+                         OR EXISTS (
+                         SELECT 1
+                         FROM tz_order_refund b3
+                         WHERE b3.order_number = a.order_number
+                           AND b3.return_money_sts IN ('40', '30')
+                     )
+                     )
+             ) m
+                 LEFT JOIN tz_order_item toi ON m.order_number = toi.order_number
+                 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
+        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
+        ORDER BY m.channel_id, toi.shop_id, toi.prod_id;
+    </select>
+
+
+    <select id="countInventoryNum" resultType="com.yami.shop.bean.prodWatefallFlow.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
+        inner JOIN tz_shop_sku tss on ts.prod_id=tss.spu_id and ts.sku_id =tss.sku_id and tcs.shop_id = tss.shop_id  and  tss.is_delete=0
+        where tcs.is_delete=0
+        GROUP BY tcs.channel_id,tcs.shop_id, ts.prod_id
+    </select>
+</mapper>

+ 9 - 0
yami-shop-service/src/main/resources/mapper/ShopExposureMapper.xml

@@ -0,0 +1,9 @@
+<?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.ShopExposureMapper">
+
+
+    <select id="findByUserIdAndShopId" resultType="com.yami.shop.bean.model.ShopExposure">
+        select * from  tz_shop_exposure
+    </select>
+</mapper>