Procházet zdrojové kódy

Merge remote-tracking branch 'remotes/origin/developer' into developerA

Aslee před 3 roky
rodič
revize
fdf035eaee
23 změnil soubory, kde provedl 319 přidání a 88 odebrání
  1. 22 0
      backup.sql
  2. 1 1
      src/main/java/com/caimei365/commodity/annotation/Idempotent.java
  3. 2 2
      src/main/java/com/caimei365/commodity/annotation/IdempotentAspect.java
  4. 1 1
      src/main/java/com/caimei365/commodity/annotation/IdempotentException.java
  5. 1 1
      src/main/java/com/caimei365/commodity/annotation/IdempotentExceptionHandler.java
  6. 30 0
      src/main/java/com/caimei365/commodity/annotation/Statistics.java
  7. 106 0
      src/main/java/com/caimei365/commodity/annotation/StatisticsAspect.java
  8. 19 13
      src/main/java/com/caimei365/commodity/components/SearchOpenService.java
  9. 1 1
      src/main/java/com/caimei365/commodity/controller/CouponApi.java
  10. 3 2
      src/main/java/com/caimei365/commodity/controller/ProductPageApi.java
  11. 1 1
      src/main/java/com/caimei365/commodity/controller/SecondHandApi.java
  12. 6 0
      src/main/java/com/caimei365/commodity/mapper/PriceMapper.java
  13. 6 0
      src/main/java/com/caimei365/commodity/mapper/SearchMapper.java
  14. 5 1
      src/main/java/com/caimei365/commodity/model/po/ProductDetailInfoPo.java
  15. 4 0
      src/main/java/com/caimei365/commodity/model/vo/ProductDetailVo.java
  16. 25 9
      src/main/java/com/caimei365/commodity/service/impl/PageServiceImpl.java
  17. 10 3
      src/main/java/com/caimei365/commodity/service/impl/PriceServiceImpl.java
  18. 62 47
      src/main/java/com/caimei365/commodity/service/impl/SearchIndexServiceImpl.java
  19. 1 1
      src/main/java/com/caimei365/commodity/service/impl/SearchProductServiceImpl.java
  20. 1 1
      src/main/resources/mapper/PageMapper.xml
  21. 4 0
      src/main/resources/mapper/PriceMapper.xml
  22. 7 3
      src/main/resources/mapper/SearchMapper.xml
  23. 1 1
      src/main/resources/mapper/ShopMapper.xml

+ 22 - 0
backup.sql

@@ -23,3 +23,25 @@ ALTER TABLE product
     MODIFY COLUMN priceFlag char(2) default '0' null comment '是否公开机构价:0公开价格,1不公开价格,2仅对会员机构公开,3仅对医美机构公开',
     MODIFY COLUMN visibility char(2) default '3' not null comment '商品可见度:3:所有人可见,2:普通机构可见,1:会员机构可见,4:仅医美机构可见' AFTER priceFlag;
 
+-- =================================== 2021年12月 小版本 start =====================================
+
+-- 1. 商品增加销量记录,可按月统计销量,便于搜索排序
+DROP TABLE IF EXISTS `cm_product_sales_record`;
+CREATE TABLE `cm_product_sales_record`(
+     `id` INT NOT NULL AUTO_INCREMENT,
+     `productId` INT(11) NOT NULL COMMENT '商品ID',
+     `sales` INT(11) DEFAULT NULL COMMENT '销量',
+     `saleTime` DATETIME DEFAULT NULL COMMENT '销售时间',
+     PRIMARY KEY (`id`)
+) ENGINE=INNODB CHARSET=utf8mb4 COMMENT='商品销量记录表';
+
+-- 2. 商品详情访问量记录,可按月统计,便于搜索排序
+DROP TABLE IF EXISTS `cm_product_views_record`;
+CREATE TABLE `cm_product_views_record`(
+     `id` INT NOT NULL AUTO_INCREMENT,
+     `productId` INT(11) NOT NULL COMMENT '商品ID',
+     `views` INT(11) DEFAULT NULL COMMENT '访问量',
+     `viewTime` DATETIME DEFAULT NULL COMMENT '访问日期',
+     PRIMARY KEY (`id`)
+) ENGINE=INNODB CHARSET=utf8mb4 COMMENT='商品详情访问量记录表';
+

+ 1 - 1
src/main/java/com/caimei365/commodity/idempotent/Idempotent.java → src/main/java/com/caimei365/commodity/annotation/Idempotent.java

@@ -1,4 +1,4 @@
-package com.caimei365.commodity.idempotent;
+package com.caimei365.commodity.annotation;
 
 import java.lang.annotation.*;
 

+ 2 - 2
src/main/java/com/caimei365/commodity/idempotent/IdempotentAspect.java → src/main/java/com/caimei365/commodity/annotation/IdempotentAspect.java

@@ -1,4 +1,4 @@
-package com.caimei365.commodity.idempotent;
+package com.caimei365.commodity.annotation;
 
 import lombok.extern.slf4j.Slf4j;
 import org.aspectj.lang.ProceedingJoinPoint;
@@ -44,7 +44,7 @@ public class IdempotentAspect {
     /**
      * 切入点,根据自定义Idempotent实际路径进行调整
      */
-    @Pointcut("@annotation(com.caimei365.commodity.idempotent.Idempotent)")
+    @Pointcut("@annotation(com.caimei365.commodity.annotation.Idempotent)")
     public void executeIdempotent() {
     }
 

+ 1 - 1
src/main/java/com/caimei365/commodity/idempotent/IdempotentException.java → src/main/java/com/caimei365/commodity/annotation/IdempotentException.java

@@ -1,4 +1,4 @@
-package com.caimei365.commodity.idempotent;
+package com.caimei365.commodity.annotation;
 
 /**
  * 处理幂等相关异常

+ 1 - 1
src/main/java/com/caimei365/commodity/idempotent/IdempotentExceptionHandler.java → src/main/java/com/caimei365/commodity/annotation/IdempotentExceptionHandler.java

@@ -1,4 +1,4 @@
-package com.caimei365.commodity.idempotent;
+package com.caimei365.commodity.annotation;
 
 
 import com.caimei365.commodity.model.ResponseJson;

+ 30 - 0
src/main/java/com/caimei365/commodity/annotation/Statistics.java

@@ -0,0 +1,30 @@
+package com.caimei365.commodity.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 自定义统计注解
+ *
+ * @author : Charles
+ * @date : 2021/12/29
+ */
+// @Target 指定注解作用的地方:方法,变量,类
+@Target(ElementType.METHOD)
+// @Retention 生命周期
+@Retention(RetentionPolicy.RUNTIME)
+// @Documented 是否能随着被定义的java文件生成到JavaDoc文档当中 (非必填)
+@Documented
+public @interface Statistics {
+    /**
+     * 前缀属性,作为redis缓存Key的一部分。
+     */
+    String prefix() default "statistics_";
+    /**
+     * 需要的参数名
+     */
+    String field();
+    /**
+     * 过期时间(秒),默认两天 60*60*24*2 = 172800
+     */
+    int expire() default 172800;
+}

+ 106 - 0
src/main/java/com/caimei365/commodity/annotation/StatisticsAspect.java

@@ -0,0 +1,106 @@
+package com.caimei365.commodity.annotation;
+
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
+import org.springframework.data.redis.core.RedisCallback;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+import redis.clients.jedis.commands.JedisCommands;
+
+import javax.annotation.Resource;
+import java.lang.reflect.Method;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Date;
+
+/**
+ * 统计切面
+ *
+ * @author : Charles
+ * @date : 2021/12/29
+ */
+@Slf4j
+@Aspect
+@Component
+@ConditionalOnClass(RedisTemplate.class)
+public class StatisticsAspect {
+    @Resource
+    private RedisTemplate<String,String> redisTemplate;
+
+    /**
+     * 切入点,根据自定义Statistics实际路径进行调整
+     */
+    @Pointcut("@annotation(com.caimei365.commodity.annotation.Statistics)")
+    public void executeStatistics() {}
+
+    @Around("executeStatistics()")
+    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
+        // 获取方法
+        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
+        // 获取参数名数组
+        String[] parameters = new LocalVariableTableParameterNameDiscoverer().getParameterNames(method);
+        // 获取参数值列表
+        Object[] args = joinPoint.getArgs();
+        // 获取自定义注解
+        Statistics statistics = method.getAnnotation(Statistics.class);
+        String prefix = statistics.prefix();
+        String field = statistics.field();
+        int expire = statistics.expire();
+        String fieldKey = null;
+        boolean contains = null != parameters && Arrays.asList(parameters).contains(field);
+        if (contains) {
+            for (int i = 0; i < parameters.length; i++) {
+                if (parameters[i] != null && parameters[i].equals(field)) {
+                    fieldKey = args[i].toString();
+                }
+            }
+        }
+        if (null != fieldKey) {
+            // 当前日期串
+            String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date());
+            // 拼接redisKey
+            String redisKey = prefix + ":" + field + ":" + dateStr;
+            // 获取Redis已有的统计值 + 1
+            int count = getHash(redisKey, fieldKey) + 1;
+            // 设置统计数量 + 1, 过期时间默认两天,(后面定时任务每天凌晨把前一天统计量存入数据库(按天存))
+            setHash(redisKey, fieldKey, count, expire);
+        }
+        return joinPoint.proceed();
+    }
+
+    /**
+     * 获取Redis中hash对应的统计值
+     */
+    public Integer getHash(String key, String fieldKey) {
+        String result = redisTemplate.execute(
+                (RedisCallback<String>) connection -> (
+                        (JedisCommands) connection.getNativeConnection()
+                ).hget(key, fieldKey)
+        );
+        return result == null ? 0 : Integer.parseInt(result);
+    }
+
+    /**
+     * 添加/更新Redis中hash的值
+     */
+    public void setHash(String key, String fieldKey, int count, int expire) {
+        String value = Integer.toString(count);
+        redisTemplate.execute(
+                (RedisCallback<Object>) connection -> (
+                        (JedisCommands) connection.getNativeConnection()
+                ).hset(key, fieldKey, value)
+        );
+        // 设置超时时间 (秒)
+        redisTemplate.execute(
+                (RedisCallback<Object>) connection -> (
+                        (JedisCommands) connection.getNativeConnection()
+                ).expire(key, expire)
+        );
+    }
+}

+ 19 - 13
src/main/java/com/caimei365/commodity/components/SearchOpenService.java

@@ -248,7 +248,7 @@ public class SearchOpenService {
             thisFilter += "p_valid=2 AND p_type=1";
         } else if (identity == 2) {
             // 会员机构
-            thisFilter += "(p_visibility=1 OR p_visibility=2 OR p_visibility=3) ANDp_valid=2 AND p_type=1";
+            thisFilter += "(p_visibility=1 OR p_visibility=2 OR p_visibility=3) AND p_valid=2 AND p_type=1";
         } else if (identity == 4) {
             // 普通机构
             thisFilter += "(p_visibility=2 OR p_visibility=3) AND p_valid=2 AND p_type=1";
@@ -284,16 +284,22 @@ public class SearchOpenService {
         }
         // 创建sort对象,并设置二维排序
         Sort sorter = new Sort();
-        // 价格,销量,人气 排序
+        // 价格,销量,人气 排序(按最近30天内)
         String[] sortFields = {"price", "sales", "favorite"};
         if (StringUtils.isNotEmpty(sortField) && Arrays.asList(sortFields).contains(sortField)) {
+            // 设置选定排序字段
             Order order = (1 == sortType) ? Order.DECREASE : Order.INCREASE;
-            // 设置排序字段
             sorter.addToSortFields(new SortField("p_" + sortField, order));
+        } else {
+            // 以RANK相关性算分降序
+            sorter.addToSortFields(new SortField("RANK", Order.DECREASE));
+            // 综合排序:按照品牌权重(p_sort),销量,人气,价格的高低依次降序排列
+            sorter.addToSortFields(new SortField("p_sort", Order.DECREASE));
+            sorter.addToSortFields(new SortField("p_sales", Order.DECREASE));
+            sorter.addToSortFields(new SortField("p_favorite", Order.DECREASE));
+            sorter.addToSortFields(new SortField("p_price", Order.DECREASE));
         }
-        // 以RANK相关性算分降序
-        sorter.addToSortFields(new SortField("RANK", Order.DECREASE));
-        // 默认商品ID倒序
+        // 商品ID倒序
         sorter.addToSortFields(new SortField("p_id", Order.DECREASE));
         //添加Sort对象参数
         searchParams.setSort(sorter);
@@ -360,17 +366,17 @@ public class SearchOpenService {
         }
         searchParams.setFilter(thisFilter);
 
-        // 创建sort对象,并设置二维排序
+        // 创建sort对象,SCROLL查询只能1个排序项
         Sort sorter = new Sort();
-        // 价格,销量,人气 排序
-        String[] sortFields = {"p_price", "p_sales", "p_favorite"};
+        // 价格,销量,人气 排序(按最近30天内)
+        String[] sortFields = {"price", "sales", "favorite"};
         if (StringUtils.isNotEmpty(sortField) && Arrays.asList(sortFields).contains(sortField)) {
+            // 设置选定排序字段
             Order order = (1 == sortType) ? Order.DECREASE : Order.INCREASE;
-            // 设置排序字段
-            sorter.addToSortFields(new SortField(sortField, order));
+            sorter.addToSortFields(new SortField("p_" + sortField, order));
         } else {
-            // 默认商品ID倒序
-            sorter.addToSortFields(new SortField("p_id", Order.DECREASE));
+            // 综合排序:按照品牌权重(p_sort),销量,人气,价格的高低依次降序排列
+            sorter.addToSortFields(new SortField("p_sort", Order.DECREASE));
         }
         //添加Sort对象参数
         searchParams.setSort(sorter);

+ 1 - 1
src/main/java/com/caimei365/commodity/controller/CouponApi.java

@@ -1,6 +1,6 @@
 package com.caimei365.commodity.controller;
 
-import com.caimei365.commodity.idempotent.Idempotent;
+import com.caimei365.commodity.annotation.Idempotent;
 import com.caimei365.commodity.model.ResponseJson;
 import com.caimei365.commodity.model.dto.CollarCouponsDto;
 import com.caimei365.commodity.model.dto.RedeemCouponsDto;

+ 3 - 2
src/main/java/com/caimei365/commodity/controller/ProductPageApi.java

@@ -1,8 +1,8 @@
 package com.caimei365.commodity.controller;
 
+import com.caimei365.commodity.annotation.Statistics;
 import com.caimei365.commodity.model.ResponseJson;
 import com.caimei365.commodity.model.po.ProductParameterPo;
-import com.caimei365.commodity.model.vo.ProductRepairVo;
 import com.caimei365.commodity.model.search.ProductListVo;
 import com.caimei365.commodity.model.vo.*;
 import com.caimei365.commodity.service.PageService;
@@ -13,7 +13,6 @@ import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
 import org.springframework.web.bind.annotation.*;
 
-import javax.ws.rs.GET;
 import java.util.List;
 import java.util.Map;
 
@@ -192,12 +191,14 @@ public class ProductPageApi {
      *
      * @param productId 商品Id
      * @param userId    用户Id
+     * Statistics统计存入Redis的hash => prefix + ":" + field + ":" + date("yyyyMMdd");
      */
     @ApiOperation("商品详情页(旧:/product/details)")
     @ApiImplicitParams({
             @ApiImplicitParam(required = false, name = "userId", value = "用户id"),
             @ApiImplicitParam(required = false, name = "productId", value = "商品Id")
     })
+    @Statistics(prefix = "statistics_details", field = "productId")
     @GetMapping("/product/details")
     public ResponseJson<ProductDetailVo> getProductDetails(Integer productId, Integer userId) {
         return pageService.getProductDetails(productId, userId);

+ 1 - 1
src/main/java/com/caimei365/commodity/controller/SecondHandApi.java

@@ -1,6 +1,6 @@
 package com.caimei365.commodity.controller;
 
-import com.caimei365.commodity.idempotent.Idempotent;
+import com.caimei365.commodity.annotation.Idempotent;
 import com.caimei365.commodity.model.ResponseJson;
 import com.caimei365.commodity.model.dto.SecondDto;
 import com.caimei365.commodity.model.vo.BrandVo;

+ 6 - 0
src/main/java/com/caimei365/commodity/mapper/PriceMapper.java

@@ -69,4 +69,10 @@ public interface PriceMapper {
      * 根据用户Id查询供应商Id
      */
     Integer getShopIdByUserId(Integer userId);
+    /**
+     * 添加销量记录
+     * @param productId 商品Id
+     * @param sales 销量
+     */
+    void insertProductSalesRecord(Integer productId, Integer sales);
 }

+ 6 - 0
src/main/java/com/caimei365/commodity/mapper/SearchMapper.java

@@ -5,6 +5,7 @@ import com.caimei365.commodity.model.search.*;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.Date;
 import java.util.List;
 
 
@@ -248,4 +249,9 @@ public interface SearchMapper {
     List<Integer> findPromotion(List<Integer> productIds);
 
     List<Integer> findPromotionId(Integer p_id);
+    /**
+     * 统计月销量与月访问量
+     */
+    int countViewsByDate(Integer productId, Date date);
+    int countSalesByDate(Integer productId, Date date);
 }

+ 5 - 1
src/main/java/com/caimei365/commodity/model/po/ProductDetailInfoPo.java

@@ -20,9 +20,13 @@ public class ProductDetailInfoPo implements Serializable {
      */
     private Integer productId;
     /**
-     * 商品详情信息
+     * 资质机构商品详情信息
      */
     private String detailInfo;
+    /**
+     * 普通机构商品详情信息
+     */
+    private String commonDetailInfo;
     /**
      * 服务详情
      */

+ 4 - 0
src/main/java/com/caimei365/commodity/model/vo/ProductDetailVo.java

@@ -323,4 +323,8 @@ public class ProductDetailVo implements Serializable {
      * 商品备注
      */
     private String productRemarks;
+    /**
+     * 普通机构商品详情 1同资质机构商品详情,2用普通机构商品详情
+     */
+    private Integer productDetailChose;
 }

+ 25 - 9
src/main/java/com/caimei365/commodity/service/impl/PageServiceImpl.java

@@ -285,8 +285,8 @@ public class PageServiceImpl implements PageService {
         String liveAdvertisingImage = pageMapper.getLiveAdvertisingImage();
         map.put("liveImage", liveAdvertisingImage);
         // 热门百科导航
-        List <BaikeProductVo> baikeList = pageMapper.getSidebarBaike();
-        baikeList.forEach(baikeProduct->{
+        List<BaikeProductVo> baikeList = pageMapper.getSidebarBaike();
+        baikeList.forEach(baikeProduct -> {
             String commodityType = baikeProduct.getCommodityType() == 1 ? "product-" : "instrument-";
             baikeProduct.setLink(domain + "/encyclopedia/" + commodityType + baikeProduct.getProductId() + ".html");
         });
@@ -494,6 +494,8 @@ public class PageServiceImpl implements PageService {
     @Override
     public ResponseJson<ProductDetailVo> getProductDetails(Integer productId, Integer userId) {
         ProductDetailVo product = pageMapper.getProductDetails(productId);
+        // 用户身份:0个人,1协销,2会员机构,3供应商,4普通机构
+        Integer identity = shopMapper.getUserIdentityById(userId);
         if (product == null) {
             //商品不存在
             product = new ProductDetailVo();
@@ -533,6 +535,18 @@ public class PageServiceImpl implements PageService {
         product.setImageList(imageList);
         // 商品详情
         ProductDetailInfoPo productDetail = shopMapper.getProductDetailInfo(productId);
+        //非资质机构商品详情展示普通机构商品详情,游客和普通机构要进判断
+//        if (null == identity || 4 == identity) {
+//            String chose = product.getProductDetailChose();
+//            log.info("身份identity===================>"+identity+"ProductDetail===================》"+chose);
+//            if (StringUtils.isNotEmpty(chose) && "2".equals(chose)) {
+//                //将商品详情展示为普通机构商品详情
+//                String info = null == productDetail.getDetailInfo2() ? "若要查看更多产品信息,请注册机构会员,如有疑问请联系客服。" : productDetail.getDetailInfo2();
+//                log.info("DetailInfo2参数================================》"+info);
+//                productDetail.setDetailInfo(info);
+//            }
+//        }
+//        log.info("-------------------》productDetail参数"+productDetail.toString());
         product.setProductDetail(productDetail);
         // 相关参数
         List<ProductParameterPo> parametersList = shopMapper.getProductParameters(productId);
@@ -570,8 +584,6 @@ public class PageServiceImpl implements PageService {
         // 商品可见度:3:所有人可见,2:普通机构可见,1:会员机构可见,4:仅医美机构可见
         Integer visibility = product.getVisibility();
         if (null != userId && userId > 0) {
-            // 用户身份:0个人,1协销,2会员机构,3供应商,4普通机构
-            Integer identity = shopMapper.getUserIdentityById(userId);
             // 会员机构类型:1医美,2生美
             Integer clubType = 0;
             if (null != identity && identity == 2) {
@@ -677,7 +689,7 @@ public class PageServiceImpl implements PageService {
             identity = shopMapper.getUserIdentityById(userId);
             identity = null == identity ? 0 : identity;
         }
-        boolean flag  = (identity == 1 || identity == 2 || identity == 3);
+        boolean flag = (identity == 1 || identity == 2 || identity == 3);
         if (!flag) {
             return ResponseJson.success(1, "没有权限查看该项目仪器", new PageDetailVo());
         }
@@ -929,12 +941,16 @@ public class PageServiceImpl implements PageService {
             boolean isSuperVip = null != svipUserId;
             // 根据用户Id查询用户身份: 0个人,1协销,2会员机构,3供应商,4普通机构
             Integer identity = priceMapper.getIdentityByUserId(userId);
-            if (null == identity) {identity = 0;}
+            if (null == identity) {
+                identity = 0;
+            }
             // 会员机构类型:1医美,2生美
             Integer clubType = 0;
             if (identity == 2) {
                 clubType = priceMapper.getClubTypeById(userId);
-                if (null == clubType) {clubType = 0;}
+                if (null == clubType) {
+                    clubType = 0;
+                }
             }
             if (image.getProductId() != null) {
                 // 获取商品及价格
@@ -1227,10 +1243,10 @@ public class PageServiceImpl implements PageService {
     public ResponseJson<List<BaikeTypeVo>> getBaikePageData(Integer commodityType) {
         // 分类列表
         List<BaikeTypeVo> baikeTypeList = pageMapper.getBaikeTypeList(commodityType);
-        baikeTypeList.forEach(baikeType->{
+        baikeTypeList.forEach(baikeType -> {
             // 产品/仪器列表
             List<BaikeProductVo> productList = pageMapper.getBaikeProducts(baikeType.getTypeId(), null, 6);
-            productList.forEach(product ->{
+            productList.forEach(product -> {
                 // 问题列表
                 List<String> questionList = pageMapper.getBaikeQuestionList(product.getProductId());
                 product.setQuestionList(questionList);

+ 10 - 3
src/main/java/com/caimei365/commodity/service/impl/PriceServiceImpl.java

@@ -13,6 +13,7 @@ import com.caimei365.commodity.model.vo.ProductSalesVo;
 import com.caimei365.commodity.model.vo.TaxVo;
 import com.caimei365.commodity.service.PageService;
 import com.caimei365.commodity.service.PriceService;
+import com.caimei365.commodity.service.SearchIndexService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
@@ -40,6 +41,8 @@ public class PriceServiceImpl implements PriceService {
     private PriceUtilService priceUtilService;
     @Resource
     private PageService pageService;
+    @Resource
+    private SearchIndexService searchIndexService;
 
     /**
      * 获取商品详情价格
@@ -131,14 +134,14 @@ public class PriceServiceImpl implements PriceService {
         for (Object productObject : infoArr) {
             JSONObject productTemp = (JSONObject) productObject;
             Integer productId = (Integer) productTemp.get("productId");
-            Integer productCount = (Integer) productTemp.get("productCount");
+            Integer sales = (Integer) productTemp.get("productCount");
             // 获取商品销量信息
             ProductSalesVo salesVo = priceMapper.getProductSalesInfo(productId);
             if (null == salesVo || ObjectUtils.isEmpty(salesVo)) {
                 return ResponseJson.error("商品数据异常!", null);
             }
             int dbCount = (null == salesVo.getProductCount()) ? 0 : salesVo.getProductCount();
-            salesVo.setProductCount(dbCount + productCount);
+            salesVo.setProductCount(dbCount + sales);
             // 获取供应商名称
             String shopName = shopMapper.getShopNameByShopId(salesVo.getShopId());
             salesVo.setShopName(shopName);
@@ -156,7 +159,11 @@ public class PriceServiceImpl implements PriceService {
                 // 更新销量
                 priceMapper.updateProductSales(salesVo);
             }
-            log.info("【更新商品销量】:" + salesVo.toString());
+            // 添加销量记录
+            priceMapper.insertProductSalesRecord(productId, sales);
+            // 更新商品索引,销量存入阿里云
+            searchIndexService.updateProductIndexById(productId);
+            log.info("【更新商品销量】:" + salesVo);
         }
         return ResponseJson.success(null);
     }

+ 62 - 47
src/main/java/com/caimei365/commodity/service/impl/SearchIndexServiceImpl.java

@@ -23,9 +23,10 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
+import java.util.*;
 
 /**
  * Description
@@ -109,7 +110,7 @@ public class SearchIndexServiceImpl implements SearchIndexService {
         // 获取最大文档ID
         Integer mainId = searchQueryService.getIdByDocId("", null);
         mainId = mainId == -1 ? 0 : mainId;
-        // 获取推送记录数
+        // 设置商品文档 并返回推送记录数
         Integer productRecord = setAllProductData(mainId, productCount, false);
         if (productCount > productRecord) {
             log.warn("批量添加商品文档异常,部分商品未添加。");
@@ -210,8 +211,8 @@ public class SearchIndexServiceImpl implements SearchIndexService {
             if (promotionIds != null && promotionIds.size() > 0) {
                 product.setP_promotions_id(promotionIds.get(0));
             }
-            // 定义星范商品数据
-            List<DocumentDTO<MallProductDO>> mallProductList = new ArrayList<>();
+//            // 定义星范商品数据
+//            List<DocumentDTO<MallProductDO>> mallProductList = new ArrayList<>();
 //            // 星范商品设值,【必须先于商品文档设值】
 //            Integer mallId = setMallProductDocument(mallProductList, productId);
             // 定义商品文档数据
@@ -238,7 +239,7 @@ public class SearchIndexServiceImpl implements SearchIndexService {
                     return updateProductIndexById(productId);
                 } else {
                     // 推送到阿里云
-                    pushProductDocument(mainList, productList, mallProductList);
+                    pushProductDocument(mainList, productList/*, mallProductList*/);
                     // 返回结果
                     return ResponseJson.success(mainList.size());
                 }
@@ -605,8 +606,8 @@ public class SearchIndexServiceImpl implements SearchIndexService {
             // 获取数据库商品列表的分页数据
             List<ProductDO> dbList = searchMapper.searchProductList();
 
-            // 定义星范商品数据
-            List<DocumentDTO<MallProductDO>> mallProductList = new ArrayList<>();
+//            // 定义星范商品数据
+//            List<DocumentDTO<MallProductDO>> mallProductList = new ArrayList<>();
             // 定义商品文档数据
             List<DocumentDTO<ProductDO>> productList = new ArrayList<>();
             // 定义主文档入口数据
@@ -640,7 +641,7 @@ public class SearchIndexServiceImpl implements SearchIndexService {
             }
             try {
                 // 推送到阿里云
-                pushProductDocument(mainList, productList, mallProductList);
+                pushProductDocument(mainList, productList/*, mallProductList*/);
                 // 添加到返回结果
                 productRecord += mainList.size();
             } catch (OpenSearchClientException | OpenSearchException | JSONException e) {
@@ -656,11 +657,11 @@ public class SearchIndexServiceImpl implements SearchIndexService {
      *
      * @param mainList        list
      * @param productList     list
-     * @param mallProductList list
+     * // @param mallProductList list
      * @throws OpenSearchClientException exp
      * @throws OpenSearchException       exp
      */
-    private void pushProductDocument(List<DocumentDTO<MainDO>> mainList, List<DocumentDTO<ProductDO>> productList, List<DocumentDTO<MallProductDO>> mallProductList) throws OpenSearchClientException, OpenSearchException {
+    private void pushProductDocument(List<DocumentDTO<MainDO>> mainList, List<DocumentDTO<ProductDO>> productList/*, List<DocumentDTO<MallProductDO>> mallProductList*/) throws OpenSearchClientException, OpenSearchException {
         if (mainList.size() > 0) {
             // 将主文档列表转换成Json串,并推送到阿里云
             String mainDocStr = new JSONArray(mainList).toString();
@@ -677,12 +678,12 @@ public class SearchIndexServiceImpl implements SearchIndexService {
             // 更新
             log.info(">>>>>>>>>>>>>>>update document: 【search_product(" + productList.size() + "个):" + productResult + "】");
         }
-        // 将星范商品推送到阿里云
-        if (mallProductList.size() > 0) {
-            String mallProductStr = new JSONArray(mallProductList).toString();
-            String mallProductResult = searchOpenService.pushDocument(mallProductStr, "search_product_mall");
-            log.info(">>>>>>>>>>>>>>>add document: 【search_product_mall(" + mallProductList.size() + "):" + mallProductResult + "】");
-        }
+//        // 将星范商品推送到阿里云
+//        if (mallProductList.size() > 0) {
+//            String mallProductStr = new JSONArray(mallProductList).toString();
+//            String mallProductResult = searchOpenService.pushDocument(mallProductStr, "search_product_mall");
+//            log.info(">>>>>>>>>>>>>>>add document: 【search_product_mall(" + mallProductList.size() + "):" + mallProductResult + "】");
+//        }
     }
 
     /**
@@ -1087,34 +1088,34 @@ public class SearchIndexServiceImpl implements SearchIndexService {
         return docsJsonArr.toString();
     }
 
-    /**
-     * 商品星范商品设值
-     *
-     * @param mallProductList list
-     * @param productId       int
-     */
-    private Integer setMallProductDocument(List<DocumentDTO<MallProductDO>> mallProductList, Integer productId) {
-        // 是否是星范商品
-        int mallCount = searchMapper.countMallProduct(productId);
-        if (mallCount >= 1) {
-            MallProductDO mallProduct = searchMapper.searchMallProductByProductId(productId);
-            // 是否有阶梯价
-            Integer mallLadderFlag = searchMapper.getMallLadderPriceFlag(productId);
-            if (mallLadderFlag == 1) {
-                // 阶梯价
-                Double mallLadderPrice = searchMapper.getMallLowerLadderPrice(productId);
-                mallProduct.setM_price(mallLadderPrice);
-            }
-            mallProduct.setM_all(1);
-            // 搜索星范商品数据
-            DocumentDTO<MallProductDO> mallProductDoc = new DocumentDTO<>();
-            mallProductDoc.setCmd("add");
-            mallProductDoc.setFields(mallProduct);
-            mallProductList.add(mallProductDoc);
-            return mallProduct.getM_id();
-        }
-        return 0;
-    }
+//    /**
+//     * 商品星范商品设值
+//     *
+//     * @param mallProductList list
+//     * @param productId       int
+//     */
+//    private Integer setMallProductDocument(List<DocumentDTO<MallProductDO>> mallProductList, Integer productId) {
+//        // 是否是星范商品
+//        int mallCount = searchMapper.countMallProduct(productId);
+//        if (mallCount >= 1) {
+//            MallProductDO mallProduct = searchMapper.searchMallProductByProductId(productId);
+//            // 是否有阶梯价
+//            Integer mallLadderFlag = searchMapper.getMallLadderPriceFlag(productId);
+//            if (mallLadderFlag == 1) {
+//                // 阶梯价
+//                Double mallLadderPrice = searchMapper.getMallLowerLadderPrice(productId);
+//                mallProduct.setM_price(mallLadderPrice);
+//            }
+//            mallProduct.setM_all(1);
+//            // 搜索星范商品数据
+//            DocumentDTO<MallProductDO> mallProductDoc = new DocumentDTO<>();
+//            mallProductDoc.setCmd("add");
+//            mallProductDoc.setFields(mallProduct);
+//            mallProductList.add(mallProductDoc);
+//            return mallProduct.getM_id();
+//        }
+//        return 0;
+//    }
 
     /**
      * 商品文档设值
@@ -1131,12 +1132,26 @@ public class SearchIndexServiceImpl implements SearchIndexService {
         product.setP_all(1);
         // 价格等级
         product.setP_price_grade(priceUtilService.getPriceGrade(product.getP_price().doubleValue()));
-        DocumentDTO<ProductDO> productDoc = new DocumentDTO<>();
+        // 统计月销量与月访问量
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(new Date());
+        calendar.add(Calendar.DAY_OF_MONTH, -30);
+        calendar.set(Calendar.HOUR_OF_DAY, 0);
+        calendar.set(Calendar.MINUTE, 0);
+        calendar.set(Calendar.SECOND, 0);
+        Date countTime = calendar.getTime();
+        // String dateStr = new SimpleDateFormat("yyyy-MM-dd").format(countTime);
+        int views = searchMapper.countViewsByDate(product.getP_id(), countTime);
+        int sales = searchMapper.countSalesByDate(product.getP_id(), countTime);
+        product.setP_sales(sales);
+        product.setP_favorite(views);
         // 设促销id
         List<Integer> promotionIds = searchMapper.findPromotionId(product.getP_id());
         if (promotionIds != null && promotionIds.size() > 0) {
             product.setP_promotions_id(promotionIds.get(0));
         }
+        // 文档设值
+        DocumentDTO<ProductDO> productDoc = new DocumentDTO<>();
         productDoc.setCmd("add");
         productDoc.setFields(product);
         productList.add(productDoc);

+ 1 - 1
src/main/java/com/caimei365/commodity/service/impl/SearchProductServiceImpl.java

@@ -282,7 +282,7 @@ public class SearchProductServiceImpl implements SearchProductService {
         }
         SearchParams searchParams = searchOpenService.getScrollProductParams(queryStr, identity, requestPageSize, sortField, sortType);
         String thisFilter = searchParams.getFilter();
-        if (StringUtils.isNotEmpty(String.valueOf(filter))) {
+        if (StringUtils.isNotEmpty(filter)) {
             thisFilter = thisFilter + " AND " + filter;
         }
         searchParams.setFilter(thisFilter);

+ 1 - 1
src/main/resources/mapper/PageMapper.xml

@@ -177,7 +177,7 @@
             productCategory, serviceNumber, taxPoint, supplierTaxPoint, priceFlag, actFlag, ladderPriceFlag,
             addTime, hasSkuFlag, sellNumber, sortIndex, featuredFlag, costCheckFlag, recommendType, machineType,
             productCode, updateTime, validFlag, searchKey, allAreaFlag, step, costPrice, provinceIds, qualificationImg,
-            trainingMethod, trainingType ,trainingFee, productRemarks
+            trainingMethod, trainingType ,trainingFee, productRemarks,productDetail as productDetailChose
         from product
         where productID = #{productId}
     </select>

+ 4 - 0
src/main/resources/mapper/PriceMapper.xml

@@ -129,6 +129,10 @@
         INSERT INTO cm_product_sales(productId, product, shop, productCount, property)
         VALUES (#{productId}, #{productName}, #{shopName}, #{productCount}, #{property})
     </insert>
+    <insert id="insertProductSalesRecord">
+        INSERT INTO cm_product_sales_record(productId, sales, saleTime)
+        VALUES (#{productId}, #{sales}, NOW())
+    </insert>
     <update id="updateProductSales" parameterType="com.caimei365.commodity.model.vo.ProductSalesVo">
         UPDATE cm_product_sales
         SET product=#{productName},

+ 7 - 3
src/main/resources/mapper/SearchMapper.xml

@@ -10,10 +10,7 @@
         p.price as p_price,
         p.priceFlag as p_price_flag,
         p.productCode as p_code,
-        p.sortIndex as p_sort,
         p.unit as p_unit,
-        p.sellNumber as p_sales,
-        p.favoriteTimes as p_favorite,
         br.id as p_brand_id,
         br.name as p_brand_name,
         p.shopID as p_supplier_id,
@@ -27,6 +24,7 @@
         p.preferredFlag as p_preferred,
         p.productCategory as p_type,
         p.validFlag as p_valid,
+        br.weights as p_sort,
         DATE_FORMAT(p.ADDTIME,'%Y%m%d') as p_time,
         IFNULL(p.visibility,3) as p_visibility
     </sql>
@@ -545,4 +543,10 @@
         order by pr.type desc
         limit 1
     </select>
+    <select id="countViewsByDate" resultType="java.lang.Integer">
+        select IFNULL(sum(views),0) from cm_product_views_record where productId = #{productId} and viewTime > #{date}
+    </select>
+    <select id="countSalesByDate" resultType="java.lang.Integer">
+        select IFNULL(sum(sales),0) from cm_product_sales_record where productId = #{productId} and saleTime > #{date}
+    </select>
 </mapper>

+ 1 - 1
src/main/resources/mapper/ShopMapper.xml

@@ -489,7 +489,7 @@
         where productID = #{productId} order by mainFlag desc
     </select>
     <select id="getProductDetailInfo" resultType="com.caimei365.commodity.model.po.ProductDetailInfoPo">
-        select productDetailInfoId, productId, detailInfo, serviceInfo, orderInfo, propValueAlias,
+        select productDetailInfoId, productId, detailInfo, commonDetailInfo,serviceInfo, orderInfo, propValueAlias,
                 propValueImages, detailInfoTxt, seoTitle, seoKeyword, seoDes
         from productdetailinfo
         where productId = #{productId}